[server] / trunk / lib / getoption.h Repository:
ViewVC logotype

View of /trunk/lib/getoption.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 256 - (download) (annotate)
Fri Jun 12 13:48:11 2009 UTC (4 years ago) by jtarlton
File size: 8751 byte(s)
abort if conf file is specified but  does not exist
    1 /*
    2  * Copyright (C) 2009 Dialogic Corp.
    3  *
    4  * This program is free software; you can redistribute it and/or
    5  * modify it under the terms of the GNU General Public License
    6  * as published by the Free Software Foundation; either version 2
    7  * of the License, or (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
   17  * 02110-1301, USA.
   18  * Alternatively see <http://www.gnu.org/licenses/>.
   19  * Or see the LICENSE file included within the source tree.
   20  *
   21  */
   22 
   23 /*!
   24  * \file    getoption.h
   25  * \brief   Get command line options, C++ wrapper for getopt_long().
   26  * \author  John Tarlton
   27  * \version 0.1
   28  */
   29 
   30 #ifndef _GETOPTION_H
   31 #define _GETOPTION_H
   32 
   33 /*----------------------------- Dependencies -------------------------------*/
   34 
   35 #include <getopt.h>
   36 
   37 #include <vector>
   38 #include <map>
   39 #include <ostream>
   40 
   41 /*--------------------------------------------------------------------------*/
   42 
   43 
   44 /*!
   45  * \class GetOptions
   46  * Get program options from the command line argv array.
   47  */
   48 class GetOptions
   49 {
   50 private:
   51 
   52   /*!
   53    * \struct Option
   54    * Stores the definition of a single option flag.
   55    */
   56   struct Option
   57   {
   58     Option( char sname,
   59             const std::string& lname,
   60             const std::string& description,
   61             int hasarg)
   62       : short_name (sname),
   63         long_name (lname),
   64         desc (description),
   65         has_arg (hasarg),
   66         found (false)
   67     {}
   68 
   69     char         short_name; /*!< e.g. -v */
   70     std::string  long_name;  /*!< e.g. --foo */
   71     std::string  desc;       /*!< description, useful for help messages */
   72     int          has_arg;    /*!< no_argument | required_argument | optional_argument */
   73     bool         found;      /*!< true, if this option was present */
   74     std::string  value;      /*!< receives the argument's value */
   75   };
   76 
   77 public:
   78 
   79   /*!
   80    * ctor.
   81    */
   82   GetOptions() {}
   83 
   84   /*!
   85    * dtor, remove the Option objects.
   86    */
   87   ~GetOptions()
   88   {
   89     std::vector<Option*>::iterator i;
   90     for ( i = options_.begin();  i != options_.end(); ++i )
   91     {
   92       delete *i;
   93     }
   94   }
   95 
   96   /*!
   97    * Add an option that does not have an explicit value. This is used for
   98    * boolean options. E.g. --foo
   99    *
  100    * \param sname - single character name, use '\0' if not required.
  101    * \param lname - long name
  102    * \param description a short description of the option
  103    */
  104   void addOptionNoArg( char sname,
  105                        const std::string& lname,
  106                        const std::string& description )
  107   {
  108     Option* op = new Option(sname, lname, description, no_argument);
  109     options_.push_back(op);
  110   }
  111 
  112   /*!
  113    * Add an option that requires an explicit argument.
  114    * e.g. --foo=bar or --foo bar
  115    *
  116    * \param sname - single character name, use '\0' if not required.
  117    * \param lname - long name
  118    * \param description - a short description of the option
  119    */
  120   void addOptionRequiredArg( char sname,
  121                              const std::string& lname,
  122                              const std::string& description )
  123   {
  124     Option* op = new Option(sname, lname, description, required_argument);
  125     options_.push_back(op);
  126   }
  127 
  128   /*!
  129    * Add an option that has an optional argument.
  130    * e.g. --foo=bar or --foo
  131    *
  132    * \param sname - single character name, use '\0' if not required.
  133    * \param lname - long name
  134    * \param description - a short description of the option
  135    */
  136   void addOptionOptionalArg( char sname,
  137                              const std::string& lname,
  138                              const std::string& description )
  139   {
  140     Option* op = new Option(sname, lname, description, optional_argument);
  141     options_.push_back(op);
  142   }
  143 
  144   /*!
  145    * Lookup an option using is short name and return its arg value.
  146    * \param sname - single character name,
  147    * \return the value or an empty string if the option is not found.
  148    */
  149   const std::string getValue( char sname ) const
  150   {
  151     Option* op = find(sname);
  152     return op ? op->value : std::string();
  153   }
  154 
  155   /*!
  156    * Lookup an option using its long name and return its arg value.
  157    * \param lname - long name
  158    * \return the value or an empty string if the option is not found.
  159    */
  160   const std::string getValue( const std::string& lname ) const
  161   {
  162     Option* op = find(lname);
  163     return op ? op->value : std::string();
  164   }
  165 
  166   /*!
  167    * Lookup an option using its short name and test if it was found.
  168    * \param sname - single character name.
  169    * \return true if the option was found; otherwise, false.
  170    */
  171   bool isFound( char sname ) const
  172   {
  173     Option* op = find(sname);
  174     return op ? op->found : false;
  175   }
  176 
  177   /*!
  178    * Lookup an option using its long name and test if it was found.
  179    * \param lname - long name.
  180    * \return true if the option was found; otherwise, false.
  181    */
  182   bool isFound( const std::string& lname ) const
  183   {
  184     Option* op = find(lname);
  185     return op ? op->found : false;
  186   }
  187 
  188   /*!
  189    * Get all options that were found.
  190    * \param opts - receives name/value pairs for each option
  191    */
  192   void getAllValues( std::map<std::string, std::string>& opts ) const
  193   {
  194     opts.clear();
  195     std::vector<Option*>::const_iterator i;
  196     for ( i = options_.begin();  i != options_.end(); ++i )
  197     {
  198       if ( (*i)->found )
  199       {
  200         opts.insert(std::pair<std::string, std::string>((*i)->long_name, (*i)->value));
  201       }
  202     }
  203   }
  204 
  205   /*!
  206    * Parse command-line options.
  207    * \param argc - as passed into main()
  208    * \param argv - as passed into main()
  209    * \return the index of the first non-option in argv
  210    */
  211   int parseOptions( int argc, char** argv )
  212   {
  213     /* build an array of option structS using data from Options and
  214      * terminate it with a zeroed-out element.
  215      */
  216     ::option* opt_array = new ::option[options_.size() + 1];
  217     ::option* opt = opt_array;
  218 
  219     std::string optstring;
  220     std::vector<Option*>::const_iterator i;
  221     for ( i = options_.begin(); i != options_.end(); ++i )
  222     {
  223       opt->name = (*i)->long_name.c_str();
  224       opt->has_arg = (*i)->has_arg;
  225       opt->flag = 0;
  226       opt->val = (*i)->short_name;
  227 
  228       if ( (*i)->short_name )
  229       {
  230         optstring += (*i)->short_name;
  231         if ( opt->has_arg == required_argument )
  232         {
  233           optstring += ':';
  234         }
  235         if ( opt->has_arg == optional_argument )
  236         {
  237           optstring += "::";
  238         }
  239       }
  240       ++opt;
  241     }
  242     /* mark the end of the opt_array */
  243     opt->name = 0;
  244     opt->has_arg = 0;
  245     opt->flag = 0;
  246     opt->val = 0;
  247 
  248     /* stops getopt_long() from writing to stderr. */
  249     ::opterr = 0;
  250 
  251     for (;;)
  252     {
  253       int opt_index = -1;
  254 
  255       int val = ::getopt_long(argc,
  256                               argv,
  257                               optstring.c_str(),
  258                               opt_array,
  259                               &opt_index);
  260       if ( val == -1 )
  261       {
  262         /* completed */
  263         break;
  264       }
  265 
  266       Option* op = find(val);
  267       if ( !op && (opt_index != -1) )
  268       {
  269         op = find(opt_array[opt_index].name);
  270       }
  271       if ( op )
  272       {
  273         op->found = true;
  274         if ( op->has_arg != no_argument )
  275         {
  276           op->value = optarg ? optarg : "";
  277         }
  278       }
  279     }
  280     delete[] opt_array;
  281     return ::optind;
  282   }
  283 
  284     /*!
  285    * Build a text string describing all options.
  286      */
  287   std::ostream& print( std::ostream& s ) const
  288   {
  289     std::vector<Option*>::const_iterator i;
  290     for ( i = options_.begin();  i != options_.end(); ++i )
  291     {
  292       if ( (*i)->short_name )
  293       {
  294         s << "-" << (*i)->short_name << ", ";
  295       }
  296       s << "--" << (*i)->long_name;
  297       s << "\t" << (*i)->desc;
  298       s << std::endl;
  299     }
  300     return s;
  301   }
  302 
  303    friend std::ostream& operator << (std::ostream& s, const GetOptions& go);
  304 
  305 private:
  306 
  307   /*!
  308    * Lookup an Option object by its short name.
  309    * \param sname - single character name.
  310    * \return a pointer to an Option object or 0 if not found.
  311    */
  312   Option* find( char sname ) const
  313   {
  314     if ( sname != '\0' )
  315     {
  316       std::vector<Option*>::const_iterator i;
  317       for ( i = options_.begin(); i != options_.end(); ++i )
  318       {
  319         if ( (*i)->short_name == sname )
  320         {
  321           return *i;
  322         }
  323       }
  324     }
  325     return 0;
  326   }
  327 
  328   /*!
  329    * Lookup an Option object by its long name.
  330    * \param lname - long name.
  331    * \return a pointer to an Option object or 0 if not found.
  332    */
  333   Option* find( const std::string& lname ) const
  334   {
  335     std::vector<Option*>::const_iterator i;
  336     for ( i = options_.begin();  i != options_.end(); ++i )
  337     {
  338       if ( (*i)->long_name == lname )
  339       {
  340         return *i;
  341       }
  342     }
  343     return 0;
  344   }
  345 
  346 private:
  347 
  348   std::vector<Option*> options_;
  349 };
  350 
  351 /*!
  352  * Overload << for printing options.
  353  */
  354 inline std::ostream& operator << (std::ostream &s, const GetOptions& go)
  355 {
  356   return go.print(s);
  357 }
  358 
  359 
  360 #endif // _GETOPTION_H
  361 
  362 /*
  363  * vim:ts=4:set nu:
  364  */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.8