Commit 8fa3c245 authored by jan.koester's avatar jan.koester
Browse files

test

parent 75667a28
Loading
Loading
Loading
Loading
+48 −0
Changes for commands/text/textutil.h: 48 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstring>
#include <cerrno>
#include <cstdlib>
#include <iostream>

#include <unistd.h>
#include <fcntl.h>
@@ -128,4 +129,51 @@ namespace fresh { namespace text {
        return v;
    }

        // GNU-style option walk: calls opt(c, value) for each short option
        // (value only for letters in `withValue`), long options go to lopt;
        // returns the operands, or sets ok=false
        struct Opts {
            std::vector<std::string> operands;
            bool ok=true;
        };
        template<class F,class G>
        Opts parseOpts(int argc,const char **argv,const char *withValue,F opt,G lopt,bool numberIsOperand=false){
            Opts o;
            bool end=false;
            for(int i=1;i<argc;++i){
                std::string a=argv[i];
                if(end || a.size()<2 || a[0]!='-' || (numberIsOperand && (isdigit((unsigned char)a[1]) || a[1]=='.'))){ o.operands.push_back(a); continue; }
                if(a=="--"){ end=true; continue; }
                if(a.compare(0,2,"--")==0){
                    std::string n=a.substr(2),v;
                    size_t eq=n.find('=');
                    bool hasV=eq!=std::string::npos;
                    if(hasV){ v=n.substr(eq+1); n=n.substr(0,eq); }
                    int r=lopt(n,v,hasV);
                    if(r<0){ o.ok=false; return o; }
                    if(r==1 && !hasV){
                        if(i+1>=argc){ std::cerr << argv[0] << ": option '--" << n << "' requires an argument" << std::endl; o.ok=false; return o; }
                        lopt(n,std::string(argv[++i]),true);
                    }
                    continue;
                }
                for(size_t k=1;k<a.size();++k){
                    char c=a[k];
                    if(strchr(withValue,c)){
                        std::string v=a.substr(k+1);
                        if(v.empty()){
                            if(i+1>=argc){ std::cerr << argv[0] << ": option requires an argument -- '" << c << "'" << std::endl; o.ok=false; return o; }
                            v=argv[++i];
                        }
                        if(!opt(c,v)){ o.ok=false; return o; }
                        break;
                    }
                    if(!opt(c,std::string())){ o.ok=false; return o; }
                }
            }
            return o;
        }
        inline bool badOpt(const char *prog,char c){ std::cerr << prog << ": invalid option -- '" << c << "'" << std::endl; return false; }
        inline int badLong(const char *prog,const std::string &n){ std::cerr << prog << ": unrecognized option '--" << n << "'" << std::endl; return -1; }

}}
+4 −48
Changes for commands/text/textutils.cpp: 4 added lines, 48 removed lines.
Original line number Diff line number Diff line
@@ -52,54 +52,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

namespace fresh { namespace cmd {

    namespace {
        // GNU-style option walk: calls opt(c, value) for each short option
        // (value only for letters in `withValue`), long options go to lopt;
        // returns the operands, or sets ok=false
        struct Opts {
            std::vector<std::string> operands;
            bool ok=true;
        };
        template<class F,class G>
        Opts parseOpts(int argc,const char **argv,const char *withValue,F opt,G lopt,bool numberIsOperand=false){
            Opts o;
            bool end=false;
            for(int i=1;i<argc;++i){
                std::string a=argv[i];
                if(end || a.size()<2 || a[0]!='-' || (numberIsOperand && (isdigit((unsigned char)a[1]) || a[1]=='.'))){ o.operands.push_back(a); continue; }
                if(a=="--"){ end=true; continue; }
                if(a.compare(0,2,"--")==0){
                    std::string n=a.substr(2),v;
                    size_t eq=n.find('=');
                    bool hasV=eq!=std::string::npos;
                    if(hasV){ v=n.substr(eq+1); n=n.substr(0,eq); }
                    int r=lopt(n,v,hasV);
                    if(r<0){ o.ok=false; return o; }
                    if(r==1 && !hasV){
                        if(i+1>=argc){ std::cerr << argv[0] << ": option '--" << n << "' requires an argument" << std::endl; o.ok=false; return o; }
                        lopt(n,std::string(argv[++i]),true);
                    }
                    continue;
                }
                for(size_t k=1;k<a.size();++k){
                    char c=a[k];
                    if(strchr(withValue,c)){
                        std::string v=a.substr(k+1);
                        if(v.empty()){
                            if(i+1>=argc){ std::cerr << argv[0] << ": option requires an argument -- '" << c << "'" << std::endl; o.ok=false; return o; }
                            v=argv[++i];
                        }
                        if(!opt(c,v)){ o.ok=false; return o; }
                        break;
                    }
                    if(!opt(c,std::string())){ o.ok=false; return o; }
                }
            }
            return o;
        }
        bool badOpt(const char *prog,char c){ std::cerr << prog << ": invalid option -- '" << c << "'" << std::endl; return false; }
        int badLong(const char *prog,const std::string &n){ std::cerr << prog << ": unrecognized option '--" << n << "'" << std::endl; return -1; }
    }
    using text::Opts;
    using text::parseOpts;
    using text::badOpt;
    using text::badLong;

    // od [-A d|o|x|n] [-t TYPE]... [-j SKIP] [-N LEN] [-w WIDTH] [-v] [-bcdox] [FILE...]
    class OdCommand : public ShellCommand {