1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2008
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     9  * Permission to use, modify and distribute this software is granted
 
    10  * provided that this copyright notice appears in all copies. For
 
    11  * precise terms see the accompanying LICENSE file.
 
    13  * This software is provided "AS IS" with no warranty of any kind,
 
    14  * express or implied, and with no claim as to its suitability for any
 
    19 #ifndef LEMON_ARG_PARSER_H
 
    20 #define LEMON_ARG_PARSER_H
 
    29 #include <lemon/assert.h>
 
    33 ///\brief A tool to parse command line arguments.
 
    37   ///Command line arguments parser
 
    40   ///Command line arguments parser.
 
    42   ///For a complete example see the \ref arg_parser_demo.cc demo file.
 
    45     static void _showHelp(void *p);
 
    49     const char * const *_argv;
 
    51     enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
 
    59         std::string *string_p;
 
    74       ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
 
    75                   has_syn(false), syn(false), self_delete(false) {}
 
    78     typedef std::map<std::string,ParData> Opts;
 
    84       typedef std::list<std::string> Opts;
 
    88       GroupData() :only_one(false), mandatory(false) {}
 
    91     typedef std::map<std::string,GroupData> Groups;
 
    98       OtherArg(std::string n, std::string h) :name(n), help(h) {}
 
   102     std::vector<OtherArg> _others_help;
 
   103     std::vector<std::string> _file_args;
 
   104     std::string _command_name;
 
   108     //Bind a function to an option.
 
   110     //\param name The name of the option. The leading '-' must be omitted.
 
   111     //\param help A help string.
 
   112     //\retval func The function to be called when the option is given. It
 
   113     //  must be of type "void f(void *)"
 
   114     //\param data Data to be passed to \c func
 
   115     ArgParser &funcOption(const std::string &name,
 
   116                     const std::string &help,
 
   117                     void (*func)(void *),void *data);
 
   122     ArgParser(int argc, const char * const *argv);
 
   131     ///Add a new integer type option
 
   133     ///Add a new integer type option.
 
   134     ///\param name The name of the option. The leading '-' must be omitted.
 
   135     ///\param help A help string.
 
   136     ///\param value A default value for the option.
 
   137     ///\param obl Indicate if the option is mandatory.
 
   138     ArgParser &intOption(const std::string &name,
 
   139                     const std::string &help,
 
   140                     int value=0, bool obl=false);
 
   142     ///Add a new floating point type option
 
   144     ///Add a new floating point type option.
 
   145     ///\param name The name of the option. The leading '-' must be omitted.
 
   146     ///\param help A help string.
 
   147     ///\param value A default value for the option.
 
   148     ///\param obl Indicate if the option is mandatory.
 
   149     ArgParser &doubleOption(const std::string &name,
 
   150                       const std::string &help,
 
   151                       double value=0, bool obl=false);
 
   153     ///Add a new bool type option
 
   155     ///Add a new bool type option.
 
   156     ///\param name The name of the option. The leading '-' must be omitted.
 
   157     ///\param help A help string.
 
   158     ///\param value A default value for the option.
 
   159     ///\param obl Indicate if the option is mandatory.
 
   160     ///\note A mandatory bool obtion is of very little use.
 
   161     ArgParser &boolOption(const std::string &name,
 
   162                       const std::string &help,
 
   163                       bool value=false, bool obl=false);
 
   165     ///Add a new string type option
 
   167     ///Add a new string type option.
 
   168     ///\param name The name of the option. The leading '-' must be omitted.
 
   169     ///\param help A help string.
 
   170     ///\param value A default value for the option.
 
   171     ///\param obl Indicate if the option is mandatory.
 
   172     ArgParser &stringOption(const std::string &name,
 
   173                       const std::string &help,
 
   174                       std::string value="", bool obl=false);
 
   176     ///Give help string for non-parsed arguments.
 
   178     ///With this function you can give help string for non-parsed arguments.
 
   179     ///The parameter \c name will be printed in the short usage line, while
 
   180     ///\c help gives a more detailed description.
 
   181     ArgParser &other(const std::string &name,
 
   182                      const std::string &help="");
 
   186     ///\name Options with External Storage
 
   187     ///Using this functions, the value of the option will be directly written
 
   188     ///into a variable once the option appears in the command line.
 
   192     ///Add a new integer type option with a storage reference
 
   194     ///Add a new integer type option with a storage reference.
 
   195     ///\param name The name of the option. The leading '-' must be omitted.
 
   196     ///\param help A help string.
 
   197     ///\param obl Indicate if the option is mandatory.
 
   198     ///\retval ref The value of the argument will be written to this variable.
 
   199     ArgParser &refOption(const std::string &name,
 
   200                     const std::string &help,
 
   201                     int &ref, bool obl=false);
 
   203     ///Add a new floating type option with a storage reference
 
   205     ///Add a new floating type option with a storage reference.
 
   206     ///\param name The name of the option. The leading '-' must be omitted.
 
   207     ///\param help A help string.
 
   208     ///\param obl Indicate if the option is mandatory.
 
   209     ///\retval ref The value of the argument will be written to this variable.
 
   210     ArgParser &refOption(const std::string &name,
 
   211                       const std::string &help,
 
   212                       double &ref, bool obl=false);
 
   214     ///Add a new bool type option with a storage reference
 
   216     ///Add a new bool type option with a storage reference.
 
   217     ///\param name The name of the option. The leading '-' must be omitted.
 
   218     ///\param help A help string.
 
   219     ///\param obl Indicate if the option is mandatory.
 
   220     ///\retval ref The value of the argument will be written to this variable.
 
   221     ///\note A mandatory bool obtion is of very little use.
 
   222     ArgParser &refOption(const std::string &name,
 
   223                       const std::string &help,
 
   224                       bool &ref, bool obl=false);
 
   226     ///Add a new string type option with a storage reference
 
   228     ///Add a new string type option with a storage reference.
 
   229     ///\param name The name of the option. The leading '-' must be omitted.
 
   230     ///\param help A help string.
 
   231     ///\param obl Indicate if the option is mandatory.
 
   232     ///\retval ref The value of the argument will be written to this variable.
 
   233     ArgParser &refOption(const std::string &name,
 
   234                       const std::string &help,
 
   235                       std::string &ref, bool obl=false);
 
   239     ///\name Option Groups and Synonyms
 
   244     ///Bundle some options into a group
 
   246     /// You can group some option by calling this function repeatedly for each
 
   247     /// option to be grouped with the same groupname.
 
   248     ///\param group The group name.
 
   249     ///\param opt The option name.
 
   250     ArgParser &optionGroup(const std::string &group,
 
   251                            const std::string &opt);
 
   253     ///Make the members of a group exclusive
 
   255     ///If you call this function for a group, than at most one of them can be
 
   256     ///given at the same time.
 
   257     ArgParser &onlyOneGroup(const std::string &group);
 
   259     ///Make a group mandatory
 
   261     ///Using this function, at least one of the members of \c group
 
   263     ArgParser &mandatoryGroup(const std::string &group);
 
   265     ///Create synonym to an option
 
   267     ///With this function you can create a synonym \c syn of the
 
   269     ArgParser &synonym(const std::string &syn,
 
   270                            const std::string &opt);
 
   275     void show(std::ostream &os,Opts::const_iterator i) const;
 
   276     void show(std::ostream &os,Groups::const_iterator i) const;
 
   277     void showHelp(Opts::const_iterator i) const;
 
   278     void showHelp(std::vector<OtherArg>::const_iterator i) const;
 
   280     void unknownOpt(std::string arg) const;
 
   282     void requiresValue(std::string arg, OptType t) const;
 
   283     void checkMandatories() const;
 
   285     void shortHelp() const;
 
   286     void showHelp() const;
 
   289     ///Start the parsing process
 
   292     /// Synonym for parse()
 
   298     ///Give back the command name (the 0th argument)
 
   299     const std::string &commandName() const { return _command_name; }
 
   301     ///Check if an opion has been given to the command.
 
   302     bool given(std::string op) const
 
   304       Opts::const_iterator i = _opts.find(op);
 
   305       return i!=_opts.end()?i->second.set:false;
 
   309     ///Magic type for operator[]
 
   311     ///This is the type of the return value of ArgParser::operator[]().
 
   312     ///It automatically converts to \c int, \c double, \c bool or
 
   313     ///\c std::string if the type of the option matches, which is checked
 
   314     ///with an \ref LEMON_ASSERT "assertion" (i.e. it performs runtime
 
   318       const ArgParser &_parser;
 
   322       RefType(const ArgParser &p,const std::string &n) :_parser(p),_name(n) {}
 
   326         Opts::const_iterator i = _parser._opts.find(_name);
 
   327         LEMON_ASSERT(i!=_parser._opts.end(),
 
   328                      std::string()+"Unkown option: '"+_name+"'");
 
   329         LEMON_ASSERT(i->second.type==ArgParser::BOOL,
 
   330                      std::string()+"'"+_name+"' is a bool option");
 
   331         return *(i->second.bool_p);
 
   334       operator std::string()
 
   336         Opts::const_iterator i = _parser._opts.find(_name);
 
   337         LEMON_ASSERT(i!=_parser._opts.end(),
 
   338                      std::string()+"Unkown option: '"+_name+"'");
 
   339         LEMON_ASSERT(i->second.type==ArgParser::STRING,
 
   340                      std::string()+"'"+_name+"' is a string option");
 
   341         return *(i->second.string_p);
 
   346         Opts::const_iterator i = _parser._opts.find(_name);
 
   347         LEMON_ASSERT(i!=_parser._opts.end(),
 
   348                      std::string()+"Unkown option: '"+_name+"'");
 
   349         LEMON_ASSERT(i->second.type==ArgParser::DOUBLE ||
 
   350                      i->second.type==ArgParser::INTEGER,
 
   351                      std::string()+"'"+_name+"' is a floating point option");
 
   352         return i->second.type==ArgParser::DOUBLE ?
 
   353           *(i->second.double_p) : *(i->second.int_p);
 
   358         Opts::const_iterator i = _parser._opts.find(_name);
 
   359         LEMON_ASSERT(i!=_parser._opts.end(),
 
   360                      std::string()+"Unkown option: '"+_name+"'");
 
   361         LEMON_ASSERT(i->second.type==ArgParser::INTEGER,
 
   362                      std::string()+"'"+_name+"' is an integer option");
 
   363         return *(i->second.int_p);
 
   368     ///Give back the value of an option
 
   370     ///Give back the value of an option.
 
   372     RefType operator[](const std::string &n) const
 
   374       return RefType(*this, n);
 
   377     ///Give back the non-option type arguments.
 
   379     ///Give back a reference to a vector consisting of the program arguments
 
   380     ///not starting with a '-' character.
 
   381     const std::vector<std::string> &files() const { return _file_args; }
 
   386 #endif // LEMON_ARG_PARSER_H