"Fossies" - the Fresh Open Source Software Archive

Member "htmlrecode-1.3.1/argh/argh.cc" (21 Jul 2009, 10869 Bytes) of package /linux/www/htmlrecode-1.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "argh.cc" see the Fossies "Dox" file reference documentation.

    1 #include <map>
    2 #include <cstdio>
    3 #include <cstring>
    4 #include <cstdlib>
    5 
    6 using std::strchr;
    7 using std::sprintf;
    8 using std::strtod;
    9 
   10 #define ARGH_VERSION_2
   11 #include "argh.hh"
   12 
   13 using std::map;
   14 using std::pair;
   15 using std::string;
   16 
   17 class argh_aliasmap : public map<string, ParamHandler::keytype>
   18 {
   19 };
   20 class argh_descsmap : public map<ParamHandler::keytype, pair<string,string> >
   21 {
   22 };
   23 class argh_atypemap : public map<ParamHandler::keytype, ParamHandler::ArgInfo>
   24 {
   25 };
   26 
   27 ParamHandler::ParamHandler()
   28 {
   29     aliases  = new argh_aliasmap();
   30     descs    = new argh_descsmap();
   31     argtypes = new argh_atypemap();
   32 }
   33 ParamHandler::~ParamHandler()
   34 {
   35     delete aliases;
   36     delete descs;
   37     delete argtypes;
   38 }
   39 
   40 int ParamHandler::ShortOpt(ParamHandler::keytype key, const char *s)
   41 {
   42     argh_atypemap::const_iterator i = argtypes->find(key);
   43     if(i == argtypes->end())
   44     {
   45         if(key=='=' && longo.size())
   46             ErrorNeedNoArg(longo);
   47         else
   48             ErrorIllegalOption(key);
   49         return ParseError();
   50     }
   51     switch(i->second.type)
   52     {
   53         case 0: /* bool */
   54             shortpointer = s;
   55             return key;
   56         case 1: /* int */
   57         {
   58             int value = 0; bool nega = false;
   59             if(*s=='=')++s;
   60             if(!*s && (argpos+1) < argc)s = argv[++argpos];
   61             if(i->second.min < 0 && *s=='-') { nega = true; ++s; }
   62             if(s[0] < '0' || s[0] > '9')goto ArgMissing;
   63             while(s[0] >= '0' && s[0] <= '9')
   64                 value = value*10 + (*s++ - '0');
   65             if(value < i->second.min || value > i->second.max)
   66             {
   67                 char Buf[128]; sprintf(Buf, "%d", value); param = Buf;
   68                 goto RangeFailure;
   69             }
   70             shortpointer = s;
   71             intparm = value;
   72             return key;
   73         }
   74         case 2: /* float */
   75         {
   76             if(*s=='=')++s;
   77             if(!*s && (argpos+1) < argc)s = argv[++argpos];
   78             char *newend;
   79             doubleparm = strtod(s, &newend);
   80             if(newend == s)goto ArgMissing;
   81             if(doubleparm < i->second.fmin || doubleparm > i->second.fmax)
   82             {
   83                 char Buf[256]; sprintf(Buf, "%g", doubleparm); param = Buf;
   84                 goto RangeFailure;
   85             }
   86             shortpointer = newend;
   87             return key;
   88         }
   89         case 3: /* string */
   90         {
   91             param = s;
   92             if(param.size() && param[0]=='=' && longobuf.size())param=s+1;
   93             else if(!param.size() && (argpos+1) < argc && (argv[argpos+1][0] != '-' || !argv[argpos+1][1]))
   94                 param = argv[++argpos];
   95             else if(!param.size() && i->second.min > 0)
   96             {
   97 ArgMissing:     if(longo.size())
   98                     ErrorNeedsArg(longo);
   99                 else
  100                     ErrorNeedsArg(key);
  101                 return ParseError();
  102             }
  103             if((int)param.size() < i->second.min || param.size() > i->second.maxl)
  104             {
  105 RangeFailure:   ErrorOutOfRange(param);
  106                 return ParseError();
  107             }
  108             shortpointer = "";
  109             return key;
  110         }
  111     }
  112     InternalError(key, s);
  113     return key;
  114 }
  115 
  116 ParamHandler::keytype ParamHandler::GetParam()
  117 {
  118     if(error)return -1;
  119     
  120 Retry:
  121     polarity = true;
  122     
  123     if(shortpointer && *shortpointer)
  124         return ShortOpt(*shortpointer, shortpointer+1);
  125 
  126     if(++argpos >= argc)return -1;
  127     
  128     /* new arg */
  129     const char *s = argv[argpos];
  130     if(!opts || *s!='-' || !s[1])
  131     {
  132         param = s;
  133         return 0;
  134     }
  135     
  136     longo = "";
  137     longobuf = "";
  138     
  139     if(s[1] != '-')
  140         return ShortOpt(s[1], s+2);
  141 
  142     if(!s[2]) /* -- */
  143     {
  144         opts = false;
  145         goto Retry;
  146     }
  147     
  148     /* --something */
  149     longo = s+2;
  150     bool nega = false, negafail = false;
  151     if(longo.substr(0, 4) == "not-")          { nega=true; longo.erase(0, 4); }
  152     else if(longo.substr(0, 3) == "no-")      { nega=true; longo.erase(0, 3); }
  153     else if(longo.substr(0, 8) == "without-") { nega=true; longo.erase(0, 8); }
  154     else if(longo.substr(0, 5) == "with-")   { nega=false; longo.erase(0, 5); }
  155     
  156 NegaDone:
  157     size_t p = longo.find('=');
  158     if(p == longo.npos)p = longo.find(':');
  159     string option;
  160     if(p != longo.npos) {option=longo.substr(p+1);longo.erase(p);}
  161     argh_aliasmap::const_iterator i = aliases->find(longo);
  162     if(i == aliases->end())
  163     {
  164         if(nega) { nega=false; longo=s+2; goto NegaDone; }
  165         
  166         ErrorUnknownOption(s, negafail);
  167         return ParseError();
  168     }
  169     if(nega)
  170     {
  171         argh_atypemap::const_iterator j = argtypes->find(i->second);
  172         if(j != argtypes->end() && j->second.type != 0)
  173         {
  174             negafail = true;
  175             nega = false;
  176             longo = s+2;
  177             goto NegaDone;
  178         }
  179         polarity = false;
  180     }
  181     longobuf = "";
  182     if(option.size()) { longobuf += '='; longobuf += option; }
  183     return ShortOpt(i->second, longobuf.c_str());
  184 }
  185 
  186 #include <vector>
  187 using std::vector;
  188 
  189 void ParamHandler::ListOptions()
  190 {
  191     argh_atypemap::const_iterator i;
  192     argh_aliasmap::const_iterator j;
  193     argh_descsmap::const_iterator k;
  194     
  195     vector<pair<string,string> > hdrs;
  196     size_t widest=0;
  197 
  198     for(j=aliases->begin(); j!=aliases->end(); ++j)
  199         if(argtypes->find(j->second) == argtypes->end())
  200         {
  201             k = descs->find(j->second);
  202             if(k == descs->end())continue;
  203 
  204             string s = "    --";
  205             s += j->first;
  206             if(k->second.second.size())
  207             {
  208                 s += ' ';
  209                 s += k->second.second;
  210             }
  211             if(s.size() > widest)widest = s.size();
  212             hdrs.push_back(pair<string,string> (s, k->second.first));
  213         }
  214     
  215     for(i=argtypes->begin(); i!=argtypes->end(); ++i)
  216     {
  217         k = descs->find(i->first);
  218         if(k == descs->end())continue;
  219         
  220         string s;
  221         
  222         bool did = false;
  223         
  224         if(i->first < 256)
  225         {
  226             s += "-";
  227             s += i->first;
  228             did = true;
  229         }
  230 
  231         for(j=aliases->begin(); j!=aliases->end(); ++j)
  232             if(j->second == i->first)
  233             {
  234                 if(did) s += ", ";
  235                 s += "--";
  236                 s += j->first;
  237                 did = true;
  238             }
  239         if(k->second.second.size())
  240         {
  241             s += ' ';
  242             s += k->second.second;
  243         }
  244         if(s.size() > widest)widest = s.size();
  245         hdrs.push_back(pair<string,string> (s, k->second.first));
  246     }
  247     
  248     for(size_t a=0; a<hdrs.size(); ++a)
  249         PrintOpt(widest, hdrs[a].first, hdrs[a].second);
  250 }
  251 
  252 ParamHandler::Reference ParamHandler::AddLong(const string &longname, ParamHandler::keytype alias)
  253 {
  254     (*aliases)[longname]=alias;
  255     return MakeRef(alias);
  256 }
  257 
  258 ParamHandler::Reference ParamHandler::AddDesc(ParamHandler::keytype c, const string &s, const string &param)
  259 {
  260     (*descs)[c] = pair<string,string>(s,param);
  261     return MakeRef(c);
  262 }
  263 
  264 ParamHandler::Reference ParamHandler::AddBool(ParamHandler::keytype c)
  265 {
  266     (*argtypes)[c].type=0;
  267     return MakeRef(c);
  268 }
  269 
  270 ParamHandler::Reference ParamHandler::AddInt(ParamHandler::keytype c, int min, int max)
  271 {
  272     ArgInfo&a=(*argtypes)[c];a.type=1;a.min=min;a.max=max;
  273     return MakeRef(c);
  274 }
  275 
  276 ParamHandler::Reference ParamHandler::AddFloat(ParamHandler::keytype c, double min, double max)
  277 {
  278     ArgInfo&a=(*argtypes)[c];a.type=2;a.fmin=min;a.fmax=max;
  279     return MakeRef(c);
  280 }
  281 
  282 ParamHandler::Reference ParamHandler::AddString(ParamHandler::keytype c, unsigned min, unsigned max)
  283 {
  284     ArgInfo&a=(*argtypes)[c];a.type=3;a.min=min;a.maxl=max;
  285     return MakeRef(c);
  286 }
  287 
  288 void ParamHandler::StartParse(int ac, const char *const *av, int firstarg)
  289 {
  290     argc=ac;argv=av;
  291     argpos=firstarg-1;opts=true;
  292     longo="";shortpointer="";
  293     polarity=true;
  294     error=false;
  295 
  296     A0 = argv[0];
  297     for(const char *q; (q = strchr(A0, '/')); )A0 = q+1;
  298 }
  299 void ParamHandler::StartParse(int ac, const char **av, int firstarg)
  300 {
  301     StartParse(ac, const_cast<const char*const *> (av), firstarg);
  302 }
  303 void ParamHandler::StartParse(int ac, char **av, int firstarg)
  304 {
  305     StartParse(ac, const_cast<const char*const *> (av), firstarg);
  306 }
  307 void ParamHandler::StartParse(int ac, char *const *av, int firstarg)
  308 {
  309     StartParse(ac, const_cast<const char*const *> (av), firstarg);
  310 }
  311 
  312 #define reffunc(fun, args, fun2, args2) \
  313   ParamHandler::Reference &ParamHandler::Reference::fun args \
  314   { \
  315       par.fun2 args2; \
  316       return *this; \
  317   }
  318 
  319 reffunc(SetBool, (), AddBool, (key))
  320 reffunc(SetInt, (int min, int max), AddInt, (key, min, max))
  321 reffunc(SetFloat, (double min, double max), AddFloat, (key, min, max))
  322 reffunc(SetString, (unsigned min, unsigned max), AddString, (key, min, max))
  323 reffunc(SetDesc, (const string &s, const string &param), AddDesc, (key, s, param))
  324 
  325 #undef reffunc
  326 
  327 int ParamHandler::ParseError()
  328 {
  329     error=true;
  330     return -1;
  331 }
  332 
  333 ParamHandler::Reference ParamHandler::MakeRef(ParamHandler::keytype key)
  334 {
  335     return Reference(*this, key);
  336 }
  337 
  338 using std::printf;
  339 using std::fprintf;
  340 using std::fflush;
  341 
  342 void ParamHandler::ErrorIllegalOption(ParamHandler::keytype key)
  343 {
  344     fprintf(stderr, "%s: illegal option -- %c\n", A0, (int)key);
  345 }
  346 
  347 void ParamHandler::ErrorNeedsArg(const string &longo)
  348 {
  349     fprintf(stderr, "%s: Switch `--%s' requires an argument.\n", A0, longo.c_str());
  350 }
  351 
  352 void ParamHandler::ErrorNeedsArg(ParamHandler::keytype key)
  353 {
  354     fprintf(stderr, "%s: Option `-%c' requires an argument.\n", A0, (int)key);
  355 }
  356 
  357 void ParamHandler::InternalError(ParamHandler::keytype key, const char *s)
  358 {
  359     fprintf(stderr, "%s: Internal error when parsing key '%ld' (%c), s='%s'\n", A0, key, (int)key, s);
  360 }
  361 
  362 void ParamHandler::ErrorOutOfRange(const string &param)
  363 {
  364     fprintf(stderr, "%s: parameter length/value out of range `%s'\n", A0, param.c_str());
  365 }
  366 
  367 void ParamHandler::ErrorUnknownOption(const char *s, bool negafail)
  368 {
  369     fprintf(stderr, "%s: unrecognized option: `%s'", A0, s);
  370     if(negafail)fprintf(stderr, " (can only negate boolean switches)");
  371     fprintf(stderr, "\n");
  372 }
  373 
  374 void ParamHandler::ErrorNeedNoArg(const string &longo)
  375 {
  376     fprintf(stderr, "%s: Parameter error: `--%s' does not take a value.\n", A0, longo.c_str());
  377 }
  378 
  379 void ParamHandler::PrintOpt(unsigned space, const string &opt, const string &desc)
  380 {
  381     printf("    %-*s  ", space, opt.c_str());
  382     
  383     bool needeol = true;
  384     for(size_t a=0; a < desc.size(); )
  385     {
  386         size_t b = desc.find('\n', a);
  387         if(!needeol){printf("%*s", space+6, "");needeol=true;}
  388         if(b == desc.npos) { printf("%s", desc.c_str()+a); break; }
  389         printf("%s", desc.substr(a, b-a).c_str());
  390         printf("\n"); needeol = false;
  391         a = b+1;
  392     }
  393     if(needeol)printf("\n");
  394     fflush(stdout);
  395 }
  396 
  397 #ifdef NEED_ARGH_H
  398 #include "argh-c.inc"
  399 #endif