Loading commands/text/textutils.cpp +28 −12 Changes for commands/text/textutils.cpp: 28 added lines, 12 removed lines. Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ namespace fresh { namespace cmd { } if(ty.size!=4 && ty.size!=8){ std::cerr << "od: invalid float size" << std::endl; return false; } } else{ std::cerr << "od: invalid type string '" << t << "'" << std::endl; return false; } else{ std::cerr << "od: invalid character '" << k << "' in type string '" << t << "'" << std::endl; return false; } if(i<t.size() && t[i]=='z'){ ty.z=true; ++i; } types.push_back(ty); } Loading Loading @@ -209,7 +209,7 @@ namespace fresh { namespace cmd { prevLine=chunk; bool firstType=true; for(auto &t: types){ std::string line=firstType ? addr(off) : std::string(radix=='n' ? 0 : addr(off).size(),' '); std::string line=firstType ? addr((unsigned long long)skip+off) : std::string(radix=='n' ? 0 : addr((unsigned long long)skip+off).size(),' '); firstType=false; int fieldW; switch(t.kind){ Loading @@ -220,7 +220,7 @@ namespace fresh { namespace cmd { case 'd': fieldW=t.size==1 ? 4 : t.size==2 ? 6 : t.size==4 ? 11 : 20; break; default: fieldW=t.size==4 ? 14 : 24; break; } for(size_t k=0;k+t.size<=n || (k<n && t.size==1);k+=(size_t)t.size){ for(size_t k=0;k<n;k+=(size_t)t.size){ unsigned long long v=0; for(int b=t.size-1;b>=0;--b) v=(v<<8)|(unsigned char)(k+b<n ? chunk[k+b] : 0); std::string s; Loading Loading @@ -253,6 +253,9 @@ namespace fresh { namespace cmd { line+=std::string(1+(fieldW>(int)s.size() ? fieldW-(int)s.size() : 0),' ')+s; } if(t.z){ size_t full=((size_t)width+(size_t)t.size-1)/(size_t)t.size; size_t have=(n+(size_t)t.size-1)/(size_t)t.size; line+=std::string((full-have)*(size_t)(fieldW+1),' '); line+=" >"; for(unsigned char c: chunk) line+=isprint(c) ? (char)c : '.'; line+="<"; Loading @@ -260,7 +263,7 @@ namespace fresh { namespace cmd { out << line << "\n"; } } if(radix!='n') out << addr(data.size()) << "\n"; if(radix!='n') out << addr((unsigned long long)skip+data.size()) << "\n"; return 0; } }; Loading Loading @@ -302,6 +305,7 @@ namespace fresh { namespace cmd { b=skip2<(long long)b.size() ? b.substr((size_t)skip2) : ""; if(limit>=0){ if((long long)a.size()>limit) a.resize((size_t)limit); if((long long)b.size()>limit) b.resize((size_t)limit); } size_t n=std::min(a.size(),b.size()); int offW=(int)std::to_string(n).size(); unsigned long long line=1; int status=0; text::Out out; Loading @@ -311,11 +315,11 @@ namespace fresh { namespace cmd { if(silent) return 1; if(list){ char buf[64]; snprintf(buf,sizeof buf,"%zu %3o %3o\n",i+1,(unsigned char)a[i],(unsigned char)b[i]); snprintf(buf,sizeof buf,"%*zu %3o %3o\n",offW,i+1,(unsigned char)a[i],(unsigned char)b[i]); out << buf; continue; } out << f1 << " " << f2 << " differ: byte " << (unsigned long long)(i+1) << ", line " << line; out << f1 << " " << f2 << " differ: char " << (unsigned long long)(i+1) << ", line " << line; if(printBytes){ char buf[64]; snprintf(buf,sizeof buf," is %3o %c %3o %c",(unsigned char)a[i],isprint((unsigned char)a[i]) ? a[i] : '?',(unsigned char)b[i],isprint((unsigned char)b[i]) ? b[i] : '?'); Loading @@ -327,8 +331,11 @@ namespace fresh { namespace cmd { if(a[i]=='\n') ++line; } if(a.size()!=b.size()){ out.flush(); if(!silent) std::cerr << "cmp: EOF on " << (a.size()<b.size() ? f1 : f2) << " after byte " << n << ", line " << line << std::endl; if(!silent){ std::cerr << "cmp: EOF on '" << (a.size()<b.size() ? f1 : f2) << "' after byte " << n; if(!list) std::cerr << ", in line " << line; std::cerr << std::endl; } return 1; } return status; Loading Loading @@ -508,13 +515,22 @@ namespace fresh { namespace cmd { for(auto *v: {&la,&lb}) for(auto &l: *v) if(!l.empty() && l.back()=='\n') l.pop_back(); text::Out out; size_t i=0,j=0; bool warned[2]={false,false},unsorted=false; auto check=[&](const std::vector<std::string> &v,size_t k,int which){ if(!warned[which] && k>0 && v[k-1].compare(v[k])>0){ out.flush(); std::cerr << "comm: file " << which+1 << " is not in sorted order" << std::endl; warned[which]=true; unsorted=true; } }; std::string p2=s1 ? "" : delim,p3=(s1 ? "" : delim)+(s2 ? "" : delim); while(i<la.size() || j<lb.size()){ int c=i>=la.size() ? 1 : j>=lb.size() ? -1 : la[i].compare(lb[j]); if(c<0){ if(!s1) out << la[i] << "\n"; ++i; } else if(c>0){ if(!s2) out << p2 << lb[j] << "\n"; ++j; } else{ if(!s3) out << p3 << la[i] << "\n"; ++i; ++j; } if(c<0){ check(la,i,0); if(!s1) out << la[i] << "\n"; ++i; } else if(c>0){ check(lb,j,1); if(!s2) out << p2 << lb[j] << "\n"; ++j; } else{ check(la,i,0); check(lb,j,1); if(!s3) out << p3 << la[i] << "\n"; ++i; ++j; } } if(unsorted){ out.flush(); std::cerr << "comm: input is not in sorted order" << std::endl; return 1; } return 0; } }; Loading Loading @@ -673,7 +689,7 @@ namespace fresh { namespace cmd { out << buf << sep << l; n+=incr; }else{ out << std::string((size_t)width+sep.size(),' ').substr(0,body.empty() ? 0 : (size_t)width+sep.size()) << l; out << std::string((size_t)width+sep.size(),' ') << l; } } return 0; Loading Loading
commands/text/textutils.cpp +28 −12 Changes for commands/text/textutils.cpp: 28 added lines, 12 removed lines. Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ namespace fresh { namespace cmd { } if(ty.size!=4 && ty.size!=8){ std::cerr << "od: invalid float size" << std::endl; return false; } } else{ std::cerr << "od: invalid type string '" << t << "'" << std::endl; return false; } else{ std::cerr << "od: invalid character '" << k << "' in type string '" << t << "'" << std::endl; return false; } if(i<t.size() && t[i]=='z'){ ty.z=true; ++i; } types.push_back(ty); } Loading Loading @@ -209,7 +209,7 @@ namespace fresh { namespace cmd { prevLine=chunk; bool firstType=true; for(auto &t: types){ std::string line=firstType ? addr(off) : std::string(radix=='n' ? 0 : addr(off).size(),' '); std::string line=firstType ? addr((unsigned long long)skip+off) : std::string(radix=='n' ? 0 : addr((unsigned long long)skip+off).size(),' '); firstType=false; int fieldW; switch(t.kind){ Loading @@ -220,7 +220,7 @@ namespace fresh { namespace cmd { case 'd': fieldW=t.size==1 ? 4 : t.size==2 ? 6 : t.size==4 ? 11 : 20; break; default: fieldW=t.size==4 ? 14 : 24; break; } for(size_t k=0;k+t.size<=n || (k<n && t.size==1);k+=(size_t)t.size){ for(size_t k=0;k<n;k+=(size_t)t.size){ unsigned long long v=0; for(int b=t.size-1;b>=0;--b) v=(v<<8)|(unsigned char)(k+b<n ? chunk[k+b] : 0); std::string s; Loading Loading @@ -253,6 +253,9 @@ namespace fresh { namespace cmd { line+=std::string(1+(fieldW>(int)s.size() ? fieldW-(int)s.size() : 0),' ')+s; } if(t.z){ size_t full=((size_t)width+(size_t)t.size-1)/(size_t)t.size; size_t have=(n+(size_t)t.size-1)/(size_t)t.size; line+=std::string((full-have)*(size_t)(fieldW+1),' '); line+=" >"; for(unsigned char c: chunk) line+=isprint(c) ? (char)c : '.'; line+="<"; Loading @@ -260,7 +263,7 @@ namespace fresh { namespace cmd { out << line << "\n"; } } if(radix!='n') out << addr(data.size()) << "\n"; if(radix!='n') out << addr((unsigned long long)skip+data.size()) << "\n"; return 0; } }; Loading Loading @@ -302,6 +305,7 @@ namespace fresh { namespace cmd { b=skip2<(long long)b.size() ? b.substr((size_t)skip2) : ""; if(limit>=0){ if((long long)a.size()>limit) a.resize((size_t)limit); if((long long)b.size()>limit) b.resize((size_t)limit); } size_t n=std::min(a.size(),b.size()); int offW=(int)std::to_string(n).size(); unsigned long long line=1; int status=0; text::Out out; Loading @@ -311,11 +315,11 @@ namespace fresh { namespace cmd { if(silent) return 1; if(list){ char buf[64]; snprintf(buf,sizeof buf,"%zu %3o %3o\n",i+1,(unsigned char)a[i],(unsigned char)b[i]); snprintf(buf,sizeof buf,"%*zu %3o %3o\n",offW,i+1,(unsigned char)a[i],(unsigned char)b[i]); out << buf; continue; } out << f1 << " " << f2 << " differ: byte " << (unsigned long long)(i+1) << ", line " << line; out << f1 << " " << f2 << " differ: char " << (unsigned long long)(i+1) << ", line " << line; if(printBytes){ char buf[64]; snprintf(buf,sizeof buf," is %3o %c %3o %c",(unsigned char)a[i],isprint((unsigned char)a[i]) ? a[i] : '?',(unsigned char)b[i],isprint((unsigned char)b[i]) ? b[i] : '?'); Loading @@ -327,8 +331,11 @@ namespace fresh { namespace cmd { if(a[i]=='\n') ++line; } if(a.size()!=b.size()){ out.flush(); if(!silent) std::cerr << "cmp: EOF on " << (a.size()<b.size() ? f1 : f2) << " after byte " << n << ", line " << line << std::endl; if(!silent){ std::cerr << "cmp: EOF on '" << (a.size()<b.size() ? f1 : f2) << "' after byte " << n; if(!list) std::cerr << ", in line " << line; std::cerr << std::endl; } return 1; } return status; Loading Loading @@ -508,13 +515,22 @@ namespace fresh { namespace cmd { for(auto *v: {&la,&lb}) for(auto &l: *v) if(!l.empty() && l.back()=='\n') l.pop_back(); text::Out out; size_t i=0,j=0; bool warned[2]={false,false},unsorted=false; auto check=[&](const std::vector<std::string> &v,size_t k,int which){ if(!warned[which] && k>0 && v[k-1].compare(v[k])>0){ out.flush(); std::cerr << "comm: file " << which+1 << " is not in sorted order" << std::endl; warned[which]=true; unsorted=true; } }; std::string p2=s1 ? "" : delim,p3=(s1 ? "" : delim)+(s2 ? "" : delim); while(i<la.size() || j<lb.size()){ int c=i>=la.size() ? 1 : j>=lb.size() ? -1 : la[i].compare(lb[j]); if(c<0){ if(!s1) out << la[i] << "\n"; ++i; } else if(c>0){ if(!s2) out << p2 << lb[j] << "\n"; ++j; } else{ if(!s3) out << p3 << la[i] << "\n"; ++i; ++j; } if(c<0){ check(la,i,0); if(!s1) out << la[i] << "\n"; ++i; } else if(c>0){ check(lb,j,1); if(!s2) out << p2 << lb[j] << "\n"; ++j; } else{ check(la,i,0); check(lb,j,1); if(!s3) out << p3 << la[i] << "\n"; ++i; ++j; } } if(unsorted){ out.flush(); std::cerr << "comm: input is not in sorted order" << std::endl; return 1; } return 0; } }; Loading Loading @@ -673,7 +689,7 @@ namespace fresh { namespace cmd { out << buf << sep << l; n+=incr; }else{ out << std::string((size_t)width+sep.size(),' ').substr(0,body.empty() ? 0 : (size_t)width+sep.size()) << l; out << std::string((size_t)width+sep.size(),' ') << l; } } return 0; Loading