XdkWrl: argstream.h Source File

Home | Hierarchy | Members | Alphabetical | Related Pages

# argstream.h

Go to the documentation of this file.

    00001 /* Copyright (C) 2004 Xavier Décoret <Xavier.Decoret@imag.fr>
    00002  *
    00003  * argsteam is free software; you can redistribute it and/or modify
    00004  * it under the terms of the GNU General Public License as published by
    00005  * the Free Software Foundation; either version 2 of the License, or
    00006  * (at your option) any later version.
    00007  *
    00008  * Foobar is distributed in the hope that it will be useful,
    00009  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00011  * GNU General Public License for more details.
    00012  *
    00013  * You should have received a copy of the GNU General Public License
    00014  * along with Foobar; if not, write to the Free Software
    00015  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    00016  */
    00017
    00018 #ifndef ARGSTREAM_H
    00019 #define ARGSTREAM_H
    00020
    00021
    00022 #include <string>
    00023 #include <list>
    00024 #include <deque>
    00025 #include <map>
    00026 #include <stdexcept>
    00027 #include <sstream>
    00028 #include <iostream>
    00029
    00030 namespace
    00031 {
    00032   class argstream;
    00033
    00034   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00035   // Interface of ValueHolder<T>
    00036   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00037   template<class T>
    00038   class ValueHolder;
    00039
    00040   template <class T>
    00041   argstream& operator>> (argstream&, const ValueHolder<T>&);
    00042
    00043   template<class T>
    00044   class ValueHolder
    00045   {
    00046   public:
    00047     ValueHolder(char s,
    00048                                                                 const char* l,
    00049                                                                 T& b,
    00050                                                                 const char* desc,
    00051                                                                 bool mandatory);
    00052     ValueHolder(const char* l,
    00053                                                                 T& b,
    00054                                                                 const char* desc,
    00055                                                                 bool mandatory);
    00056     ValueHolder(char s,
    00057                                                                 T& b,
    00058                                                                 const char* desc,
    00059                                                                 bool mandatory);
    00060     friend argstream& operator>><>(argstream& s,const ValueHolder<T>& v);
    00061     std::string name() const;
    00062     std::string description() const;
    00063   private:
    00064     std::string shortName_;
    00065     std::string longName_;
    00066     T*          value_;
    00067     T           initialValue_;
    00068     std::string description_;
    00069     bool        mandatory_;
    00070   };
    00071   template <class T>
    00072   inline ValueHolder<T>
    00073   parameter(char s,
    00074                                                 const char* l,
    00075                                                 T& b,
    00076                                                 const char* desc="",
    00077                                                 bool mandatory = true)
    00078   {
    00079     return ValueHolder<T>(s,l,b,desc,mandatory);
    00080   }
    00081   template <class T>
    00082   inline ValueHolder<T>
    00083   parameter(char s,
    00084                                                 T& b,
    00085                                                 const char* desc="",
    00086                                                 bool mandatory = true)
    00087   {
    00088     return ValueHolder<T>(s,b,desc,mandatory);
    00089   }
    00090   template <class T>
    00091   inline ValueHolder<T>
    00092   parameter(const char* l,
    00093                                                 T& b,
    00094                                                 const char* desc="",
    00095                                                 bool mandatory = true)
    00096   {
    00097     return ValueHolder<T>(l,b,desc,mandatory);
    00098   }
    00099   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00100   // Interface of OptionHolder
    00101   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00102   class OptionHolder
    00103   {
    00104   public:
    00105     inline OptionHolder(char s,
    00106                                                                                                 const char* l,
    00107                                                                                                 bool& b,
    00108                                                                                                 const char* desc);
    00109     inline OptionHolder(const char* l,
    00110                                                                                                 bool& b,
    00111                                                                                                 const char* desc);
    00112     inline OptionHolder(char s,
    00113                                                                                                 bool& b,
    00114                                                                                                 const char* desc);
    00115     friend argstream& operator>>(argstream& s,const OptionHolder& v);
    00116     inline std::string name() const;
    00117     inline std::string description() const;
    00118   protected:
    00119     inline OptionHolder(char s,
    00120                                                                                                 const char* l,
    00121                                                                                                 const char* desc);
    00122     friend OptionHolder help(char s='h',
    00123                                                                                                                  const char* l="help",
    00124                                                                                                                  const char* desc="Display this help");
    00125   private:
    00126     std::string shortName_;
    00127     std::string longName_;
    00128     bool*       value_;
    00129     std::string description_;
    00130   };
    00131   inline OptionHolder
    00132   option(char s,
    00133                                  const char* l,
    00134                                  bool& b,
    00135                                  const char* desc="")
    00136   {
    00137     return OptionHolder(s,l,b,desc);
    00138   }
    00139   inline OptionHolder
    00140   option(char s,
    00141                                  bool& b,
    00142                                  const char* desc="")
    00143   {
    00144     return OptionHolder(s,b,desc);
    00145   }
    00146   inline OptionHolder
    00147   option(const char* l,
    00148                                  bool& b,
    00149                                  const char* desc="")
    00150   {
    00151     return OptionHolder(l,b,desc);
    00152   }
    00153   inline OptionHolder
    00154   help(char s,
    00155        const char* l,
    00156        const char* desc)
    00157   {
    00158     return OptionHolder(s,l,desc);
    00159   }
    00160   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00161   // Interface of ValuesHolder
    00162   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00163   template<class T,class O>
    00164   class ValuesHolder;
    00165
    00166   template <class T,class O>
    00167   argstream& operator>>(argstream&, const ValuesHolder<T,O>&);
    00168
    00169   template<class T,class O>
    00170   class ValuesHolder
    00171   {
    00172   public:
    00173     ValuesHolder(const O& o,
    00174                                                                  const char* desc,
    00175                                                                  int len);
    00176     friend argstream& operator>><>(argstream& s,const ValuesHolder<T,O>& v);
    00177     std::string name() const;
    00178     std::string description() const;
    00179     typedef T value_type;
    00180   private:
    00181     mutable O   value_;
    00182     std::string description_;
    00183     int         len_;
    00184     char        letter_;
    00185   };
    00186   template<class T,class O>
    00187   inline ValuesHolder<T,O>
    00188   values(const O& o,
    00189                                  const char* desc="",
    00190                                  int len=-1)
    00191   {
    00192     return ValuesHolder<T,O>(o,desc,len);
    00193   }
    00194   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00195   // Interface of ValueParser
    00196   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00197   template <class T>
    00198   class ValueParser
    00199   {
    00200   public:
    00201     inline T operator()(const std::string& s) const
    00202       {
    00203                                 std::istringstream is(s);
    00204                                 T t;
    00205                                 is>>t;
    00206                                 return t;
    00207       }
    00208   };
    00209   // We need to specialize for string otherwise parsing of a value that
    00210   // contains space (for example a string with space passed in quotes on the
    00211   // command line) would parse only the first element of the value!!!
    00212   template <>
    00213   class ValueParser<std::string>
    00214   {
    00215   public:
    00216     inline std::string operator()(const std::string& s) const
    00217       {
    00218                                 return s;
    00219       }
    00220   };
    00221   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00222   // Interface of argstream
    00223   //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    00224   class argstream
    00225   {
    00226   public:
    00227     inline argstream(int argc,char** argv);
    00228     inline argstream(const char* c);
    00229     template<class T>
    00230     friend argstream& operator>>(argstream& s,const ValueHolder<T>& v);
    00231     friend inline argstream& operator>>(argstream& s,const OptionHolder& v);
    00232     template<class T,class O>
    00233     friend argstream& operator>>(argstream& s,const ValuesHolder<T,O>& v);
    00234
    00235     inline bool helpRequested() const;
    00236     inline bool isOk() const;
    00237     inline std::string errorLog() const;
    00238     inline std::string usage() const;
    00239     inline void defaultErrorHandling(bool ignoreUnused=false) const;
    00240     static inline char uniqueLetter();
    00241   protected:
    00242     void parse(int argc,char** argv);
    00243   private:
    00244     typedef std::list<std::string>::iterator value_iterator;
    00245     typedef std::pair<std::string,std::string> help_entry;
    00246     std::string                          progName_;
    00247     std::map<std::string,value_iterator> options_;
    00248     std::list<std::string>               values_;
    00249     bool                                 minusActive_;
    00250     bool                                 isOk_;
    00251     std::deque<help_entry>               argHelps_;
    00252     std::string                          cmdLine_;
    00253     std::deque<std::string>              errors_;
    00254     bool                                 helpRequested_;
    00255   };
    00256   //************************************************************
    00257   // Implementation of ValueHolder<T>
    00258   //************************************************************
    00259   template<class T>
    00260   ValueHolder<T>::ValueHolder(char s,
    00261                                                                                                                         const char* l,
    00262                                                                                                                         T& v,
    00263                                                                                                                         const char* desc,
    00264                                                                                                                         bool mandatory)
    00265     :  shortName_(1,s),
    00266        longName_(l),
    00267        value_(&v),
    00268        initialValue_(v),
    00269        description_(desc),
    00270        mandatory_(mandatory)
    00271   {
    00272   }
    00273   template<class T>
    00274   ValueHolder<T>::ValueHolder(const char* l,
    00275                                                                                                                         T& v,
    00276                                                                                                                         const char* desc,
    00277                                                                                                                         bool mandatory)
    00278     :  longName_(l),
    00279        value_(&v),
    00280        initialValue_(v),
    00281        description_(desc),
    00282        mandatory_(mandatory)
    00283   {
    00284   }
    00285   template<class T>
    00286   ValueHolder<T>::ValueHolder(char s,
    00287                                                                                                                         T& v,
    00288                                                                                                                         const char* desc,
    00289                                                                                                                         bool mandatory)
    00290     :  shortName_(1,s),
    00291        value_(&v),
    00292        initialValue_(v),
    00293        description_(desc),
    00294        mandatory_(mandatory)
    00295   {
    00296   }
    00297   template<class T>
    00298   std::string
    00299   ValueHolder<T>::name() const
    00300   {
    00301     std::ostringstream  os;
    00302     if (!shortName_.empty()) os<<'-'<<shortName_;
    00303     if (!longName_.empty()) {
    00304       if (!shortName_.empty()) os<<'/';
    00305       os<<"--"<<longName_;
    00306     }
    00307     return os.str();
    00308   }
    00309   template<class T>
    00310   std::string
    00311   ValueHolder<T>::description() const
    00312   {
    00313     std::ostringstream  os;
    00314     os<<description_;
    00315     if (mandatory_)
    00316     {
    00317       os<<"(mandatory)";
    00318     }
    00319     else
    00320     {
    00321       os<<"(default="<<initialValue_<<")";
    00322     }
    00323     return os.str();
    00324   }
    00325   //************************************************************
    00326   // Implementation of OptionHolder
    00327   //************************************************************
    00328   inline OptionHolder::OptionHolder(char s,
    00329                                                                                                                                                 const char* l,
    00330                                                                                                                                                 bool& b,
    00331                                                                                                                                                 const char* desc)
    00332     : shortName_(1,s),
    00333       longName_(l),
    00334       value_(&b),
    00335       description_(desc)
    00336   {
    00337   }
    00338   inline OptionHolder::OptionHolder(const char* l,
    00339                                                                                                                                                 bool& b,
    00340                                                                                                                                                 const char* desc)
    00341     : longName_(l),
    00342       value_(&b),
    00343       description_(desc)
    00344   {
    00345   }
    00346   inline OptionHolder::OptionHolder(char s,
    00347                                                                                                                                                 bool& b,
    00348                                                                                                                                                 const char* desc)
    00349     : shortName_(1,s),
    00350       value_(&b),
    00351       description_(desc)
    00352   {
    00353   }
    00354   inline OptionHolder::OptionHolder(char s,
    00355                                                                                                                                                 const char* l,
    00356                                                                                                                                                 const char* desc)
    00357     : shortName_(1,s),
    00358       longName_(l),
    00359       value_(NULL),
    00360       description_(desc)
    00361   {
    00362   }
    00363   inline std::string
    00364   OptionHolder::name() const
    00365   {
    00366     std::ostringstream  os;
    00367     if (!shortName_.empty()) os<<'-'<<shortName_;
    00368     if (!longName_.empty())
    00369     {
    00370       if (!shortName_.empty()) os<<'/';
    00371       os<<"--"<<longName_;
    00372     }
    00373     return os.str();
    00374   }
    00375   inline std::string
    00376   OptionHolder::description() const
    00377   {
    00378     return description_;
    00379   }
    00380   //************************************************************
    00381   // Implementation of ValuesHolder<T,O>
    00382   //************************************************************
    00383   template<class T,class O>
    00384   ValuesHolder<T,O>::ValuesHolder(const O& o,
    00385                                                                                                                                         const char* desc,
    00386                                                                                                                                         int len)
    00387     : value_(o),
    00388       description_(desc),
    00389       len_(len)
    00390   {
    00391     letter_ = argstream::uniqueLetter();
    00392   }
    00393   template <class T,class O>
    00394   std::string
    00395   ValuesHolder<T,O>::name() const
    00396   {
    00397     std::ostringstream  os;
    00398     os<<letter_<<"i";
    00399     return os.str();
    00400   }
    00401   template <class T,class O>
    00402   std::string
    00403   ValuesHolder<T,O>::description() const
    00404   {
    00405     return description_;
    00406   }
    00407   //************************************************************
    00408   // Implementation of argstream
    00409   //************************************************************
    00410   inline
    00411   argstream::argstream(int argc,char** argv)
    00412     : progName_(argv[0]),
    00413       minusActive_(true),
    00414       isOk_(true)
    00415   {
    00416     parse(argc,argv);
    00417   }
    00418   inline
    00419   argstream::argstream(const char* c)
    00420     : progName_(""),
    00421       minusActive_(true),
    00422       isOk_(true)
    00423   {
    00424     std::string s(c);
    00425     // Build argc, argv from s. We must add a dummy first element for
    00426     // progName because parse() expects it!!
    00427     std::deque<std::string> args;
    00428     args.push_back("");
    00429     std::istringstream is(s);
    00430     while (is.good())
    00431     {
    00432       std::string t;
    00433       is>>t;
    00434       args.push_back(t);
    00435     }
    00436     char* pargs[args.size()];
    00437     char** p = pargs;
    00438     for (std::deque<std::string>::const_iterator
    00439                                          iter = args.begin();
    00440                                  iter != args.end();++iter)
    00441     {
    00442       *p++ = const_cast<char*>(iter->c_str());
    00443     }
    00444     parse(args.size(),pargs);
    00445   }
    00446   inline void
    00447   argstream::parse(int argc,char** argv)
    00448   {
    00449     // Run thru all arguments.
    00450     // * it has -- in front : it is a long name option, if remainder is empty,
    00451     //                        it is an error
    00452     // * it has - in front  : it is a sequence of short name options, if
    00453     //                        remainder is empty, deactivates option (- will
    00454     //                        now be considered a char).
    00455     // * if any other char, or if option was deactivated
    00456     //                      : it is a value. Values are split in parameters
    00457     //                      (immediately follow an option) and pure values.
    00458     // Each time a value is parsed, if the previously parsed argument was an
    00459     // option, then the option is linked to the value in case of it is a
    00460     // option with parameter.  The subtle point is that when several options
    00461     // are given with short names (ex: -abc equivalent to -a -b -c), the last
    00462     // parsed option is -c).
    00463     // Since we use map for option, any successive call overides the previous
    00464     // one: foo -a -b -a hello is equivalent to foo -b -a hello
    00465     // For values it is not true since we might have several times the same
    00466     // value.
    00467     value_iterator* lastOption = NULL;
    00468     for (char** a = argv,**astop=a+argc;++a!=astop;)
    00469     {
    00470       std::string s(*a);
    00471       if (minusActive_ && s[0] == '-')
    00472       {
    00473                                 if (s.size() > 1 && s[1] == '-')
    00474                                 {
    00475                                         if (s.size() == 2)
    00476                                         {
    00477                                                 minusActive_ = false;
    00478                                                 continue;
    00479                                         }
    00480                                         lastOption = &(options_[s.substr(2)] = values_.end());
    00481                                 }
    00482                                 else
    00483                                 {
    00484                                         if (s.size() > 1)
    00485                                         {
    00486                                                 // Parse all chars, if it is a minus we have an error
    00487                                                 for (std::string::const_iterator cter = s.begin();
    00488                                                                  ++cter != s.end();)
    00489                                                 {
    00490                                                         if (*cter == '-')
    00491                                                         {
    00492                                                                 isOk_ = false;
    00493                                                                 std::ostringstream os;
    00494                                                                 os<<"- in the middle of a switch "<<a;
    00495                                                                 errors_.push_back(os.str());
    00496                                                                 break;
    00497                                                         }
    00498                                                         lastOption = &(options_[std::string(1,*cter)] = values_.end());
    00499                                                 }
    00500                                         }
    00501                                         else
    00502                                         {
    00503                                                 isOk_ = false;
    00504                                                 errors_.push_back("Invalid argument -");
    00505                                                 break;
    00506                                         }
    00507                                 }
    00508       }
    00509       else
    00510       {
    00511                                 values_.push_back(s);
    00512                                 if (lastOption != NULL)
    00513                                 {
    00514                                         *lastOption = --values_.end();
    00515                                 }
    00516                                 lastOption = NULL;
    00517       }
    00518     }
    00519 #ifdef ARGSTREAM_DEBUG
    00520     for (std::map<std::string,value_iterator>::const_iterator
    00521                                          iter = options_.begin();iter != options_.end();++iter)
    00522     {
    00523       std::cout<<"DEBUG: option "<<iter->first;
    00524       if (iter->second != values_.end())
    00525       {
    00526                                 std::cout<<" -> "<<*(iter->second);
    00527       }
    00528       std::cout<<std::endl;
    00529     }
    00530     for (std::list<std::string>::const_iterator
    00531                                          iter = values_.begin();iter != values_.end();++iter)
    00532     {
    00533       std::cout<<"DEBUG: value  "<<*iter<<std::endl;
    00534     }
    00535 #endif // ARGSTREAM_DEBUG
    00536   }
    00537   inline bool
    00538   argstream::isOk() const
    00539   {
    00540     return isOk_;
    00541   }
    00542   inline bool
    00543   argstream::helpRequested() const
    00544   {
    00545     return helpRequested_;
    00546   }
    00547   inline std::string
    00548   argstream::usage() const
    00549   {
    00550     std::ostringstream os;
    00551     os<<"usage: "<<progName_<<cmdLine_<<'\n';
    00552     unsigned int lmax = 0;
    00553     for (std::deque<help_entry>::const_iterator
    00554                                          iter = argHelps_.begin();iter != argHelps_.end();++iter)
    00555     {
    00556       if (lmax<iter->first.size()) lmax = iter->first.size();
    00557     }
    00558     for (std::deque<help_entry>::const_iterator
    00559                                          iter = argHelps_.begin();iter != argHelps_.end();++iter)
    00560     {
    00561       os<<'\t'<<iter->first<<std::string(lmax-iter->first.size(),' ')
    00562                                 <<" : "<<iter->second<<'\n';
    00563     }
    00564     return os.str();
    00565   }
    00566   inline std::string
    00567   argstream::errorLog() const
    00568   {
    00569     std::string s;
    00570     for(std::deque<std::string>::const_iterator iter = errors_.begin();
    00571                                 iter != errors_.end();++iter)
    00572     {
    00573       s += *iter;
    00574       s += '\n';
    00575     }
    00576     return s;
    00577   }
    00578   inline char
    00579   argstream::uniqueLetter()
    00580   {
    00581     static unsigned int c = 'a';
    00582     return c++;
    00583   }
    00584   template<class T>
    00585   argstream&
    00586   operator>>(argstream& s,const ValueHolder<T>& v)
    00587   {
    00588     // Search in the options if there is any such option defined either with a
    00589     // short name or a long name. If both are found, only the last one is
    00590     // used.
    00591 #ifdef ARGSTREAM_DEBUG
    00592     std::cout<<"DEBUG: searching "<<v.shortName_<<" "<<v.longName_<<std::endl;
    00593 #endif
    00594     s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
    00595     if (v.mandatory_)
    00596     {
    00597       if (!v.shortName_.empty())
    00598       {
    00599                                 s.cmdLine_ += " -";
    00600                                 s.cmdLine_ += v.shortName_;
    00601       }
    00602       else
    00603       {
    00604                                 s.cmdLine_ += " --";
    00605                                 s.cmdLine_ += v.longName_;
    00606       }
    00607       s.cmdLine_ += " value";
    00608     }
    00609     else
    00610     {
    00611       if (!v.shortName_.empty())
    00612       {
    00613                                 s.cmdLine_ += " [-";
    00614                                 s.cmdLine_ += v.shortName_;
    00615       }
    00616       else
    00617       {
    00618                                 s.cmdLine_ += " [--";
    00619                                 s.cmdLine_ += v.longName_;
    00620       }
    00621       s.cmdLine_ += " value]";
    00622
    00623     }
    00624     std::map<std::string,argstream::value_iterator>::iterator iter =
    00625       s.options_.find(v.shortName_);
    00626     if (iter == s.options_.end())
    00627     {
    00628       iter = s.options_.find(v.longName_);
    00629     }
    00630     if (iter != s.options_.end())
    00631     {
    00632       // If we find counterpart for value holder on command line, either it
    00633       // has an associated value in which case we assign it, or it has not, in
    00634       // which case we have an error.
    00635       if (iter->second != s.values_.end())
    00636       {
    00637 #ifdef ARGSTREAM_DEBUG
    00638                                 std::cout<<"DEBUG: found value "<<*(iter->second)<<std::endl;
    00639 #endif
    00640                                 ValueParser<T> p;
    00641                                 *(v.value_) = p(*(iter->second));
    00642                                 // The option and its associated value are removed, the subtle thing
    00643                                 // is that someother options might have this associated value too,
    00644                                 // which we must invalidate.
    00645                                 s.values_.erase(iter->second);
    00646                                 for (std::map<std::string,argstream::value_iterator>::iterator
    00647                                                          jter = s.options_.begin();jter != s.options_.end();++jter)
    00648                                 {
    00649                                         if (jter->second == iter->second)
    00650                                         {
    00651                                                 jter->second = s.values_.end();
    00652                                         }
    00653                                 }
    00654                                 s.options_.erase(iter);
    00655       }
    00656       else
    00657       {
    00658                                 s.isOk_ = false;
    00659                                 std::ostringstream  os;
    00660                                 os<<"No value following switch "<<iter->first
    00661                                         <<" on command line";
    00662                                 s.errors_.push_back(os.str());
    00663       }
    00664     }
    00665     else
    00666     {
    00667       if (v.mandatory_)
    00668       {
    00669                                 s.isOk_ = false;
    00670                                 std::ostringstream  os;
    00671                                 os<<"Mandatory parameter ";
    00672                                 if (!v.shortName_.empty()) os<<'-'<<v.shortName_;
    00673                                 if (!v.longName_.empty())
    00674                                 {
    00675                                         if (!v.shortName_.empty()) os<<'/';
    00676                                         os<<"--"<<v.longName_;
    00677                                 }
    00678                                 os<<" missing";
    00679                                 s.errors_.push_back(os.str());
    00680       }
    00681     }
    00682     return s;
    00683   }
    00684   inline argstream&
    00685   operator>>(argstream& s,const OptionHolder& v)
    00686   {
    00687     // Search in the options if there is any such option defined either with a
    00688     // short name or a long name. If both are found, only the last one is
    00689     // used.
    00690 #ifdef ARGSTREAM_DEBUG
    00691     std::cout<<"DEBUG: searching "<<v.shortName_<<" "<<v.longName_<<std::endl;
    00692 #endif
    00693     s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
    00694     {
    00695       std::string c;
    00696       if (!v.shortName_.empty())
    00697       {
    00698                                 c += " [-";
    00699                                 c += v.shortName_;
    00700       }
    00701       else
    00702       {
    00703                                 c += " [--";
    00704                                 c += v.longName_;
    00705       }
    00706       c += "]";
    00707       s.cmdLine_ = c+s.cmdLine_;
    00708     }
    00709     std::map<std::string,argstream::value_iterator>::iterator iter =
    00710       s.options_.find(v.shortName_);
    00711     if (iter == s.options_.end())
    00712     {
    00713       iter = s.options_.find(v.longName_);
    00714     }
    00715     if (iter != s.options_.end())
    00716     {
    00717       // If we find counterpart for value holder on command line then the
    00718       // option is true and if an associated value was found, it is ignored
    00719       if (v.value_ != NULL)
    00720       {
    00721                                 *(v.value_) = true;
    00722       }
    00723       else
    00724       {
    00725                                 s.helpRequested_ = true;
    00726       }
    00727       // The option only is removed
    00728       s.options_.erase(iter);
    00729     }
    00730     else
    00731     {
    00732       if (v.value_ != NULL)
    00733       {
    00734                                 *(v.value_) = false;
    00735       }
    00736       else
    00737       {
    00738                                 s.helpRequested_ = false;
    00739       }
    00740     }
    00741     return s;
    00742   }
    00743   template<class T,class O>
    00744   argstream&
    00745   operator>>(argstream& s,const ValuesHolder<T,O>& v)
    00746   {
    00747     s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
    00748     {
    00749       std::ostringstream os;
    00750       os<<' '<<v.letter_<<'1';
    00751       switch (v.len_)
    00752       {
    00753       case -1:
    00754                                 os<<"...";
    00755                                 break;
    00756       case 1:
    00757                                 break;
    00758       default:
    00759                                 os<<"..."<<v.letter_<<v.len_;
    00760                                 break;
    00761       }
    00762       s.cmdLine_ += os.str();
    00763     }
    00764     std::list<std::string>::iterator first = s.values_.begin();
    00765     // We add to the iterator as much values as we can, limited to the length
    00766     // specified (if different of -1)
    00767     int n = v.len_ != -1?v.len_:s.values_.size();
    00768     while (first != s.values_.end() && n-->0)
    00769     {
    00770       // Read the value from the string *first
    00771       ValueParser<T> p;
    00772       *(v.value_++) = p(*first );
    00773       s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
    00774       // The value we just removed was maybe "remembered" by an option so we
    00775       // remove it now.
    00776       for (std::map<std::string,argstream::value_iterator>::iterator
    00777                                                  jter = s.options_.begin();jter != s.options_.end();++jter)
    00778       {
    00779                                 if (jter->second == first)
    00780                                 {
    00781                                         jter->second = s.values_.end();
    00782                                 }
    00783       }
    00784       ++first;
    00785     }
    00786     // Check if we have enough values
    00787     if (n != 0)
    00788     {
    00789       s.isOk_ = false;
    00790       std::ostringstream  os;
    00791       os<<"Expecting "<<v.len_<<" values";
    00792       s.errors_.push_back(os.str());
    00793     }
    00794     // Erase the values parsed
    00795     s.values_.erase(s.values_.begin(),first);
    00796     return s;
    00797   }
    00798   inline void
    00799   argstream::defaultErrorHandling(bool ignoreUnused) const
    00800   {
    00801     if (helpRequested_)
    00802     {
    00803       std::cout<<usage();
    00804       exit(1);
    00805     }
    00806     if (!isOk_)
    00807     {
    00808       std::cerr<<errorLog();
    00809       exit(1);
    00810     }
    00811     if (!ignoreUnused &&
    00812                                 (!values_.empty() || !options_.empty()))
    00813     {
    00814       std::cerr<<"Unused arguments"<<std::endl;
    00815       exit(1);
    00816     }
    00817   }
    00818 };
    00819 #endif // ARGSTREAM_H
    00820
    00821 // Local variables section.
    00822 // This is only used by emacs!
    00823 // Local Variables:
    00824 // ff-search-directories: ("." "../../../src/xdkwrl/tools/")
    00825 // End:

Generated on 28 Jun 2006 with version 1.4.4. |