lemon/arg_parser.h
changeset 2389 df6a32249b46
child 2391 14a343be7a5a
equal deleted inserted replaced
-1:000000000000 0:eb5a76f069ff
       
     1 /* -*- C++ -*-
       
     2  * lemon/main_params.h - Part of LEMON, a generic C++ optimization library
       
     3  *
       
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     6  *
       
     7  * Permission to use, modify and distribute this software is granted
       
     8  * provided that this copyright notice appears in all copies. For
       
     9  * precise terms see the accompanying LICENSE file.
       
    10  *
       
    11  * This software is provided "AS IS" with no warranty of any kind,
       
    12  * express or implied, and with no claim as to its suitability for any
       
    13  * purpose.
       
    14  *
       
    15  */
       
    16 
       
    17 #ifndef LEMON_ARG_PARSER
       
    18 #define LEMON_ARG_PARSER
       
    19 
       
    20 #include <vector>
       
    21 #include <map>
       
    22 #include <list>
       
    23 #include <string>
       
    24 #include <iostream>
       
    25 #include <sstream>
       
    26 #include <algorithm>
       
    27 
       
    28 ///\ingroup misc
       
    29 ///\file
       
    30 ///\brief A tools to parse command line arguments.
       
    31 ///
       
    32 ///\author Alpar Juttner
       
    33 
       
    34 namespace lemon {
       
    35 
       
    36   ///Command line arguments parser
       
    37 
       
    38   ///\ingroup misc
       
    39   ///Command line arguments parser
       
    40   ///
       
    41   class ArgParser {
       
    42     
       
    43     static void _showHelp(void *p);
       
    44   protected:
       
    45     
       
    46     int _argc;
       
    47     char **_argv;
       
    48     
       
    49     enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
       
    50     
       
    51     class ParData {
       
    52     public:
       
    53       union {
       
    54 	bool *bool_p;
       
    55 	int *int_p;
       
    56 	double *double_p;
       
    57 	std::string *string_p;
       
    58 	struct {
       
    59 	  void (*p)(void *);
       
    60 	  void *data;
       
    61 	} func_p;
       
    62 	  
       
    63       };
       
    64       std::string help;
       
    65       bool mandatory;
       
    66       OptType type;
       
    67       bool set;
       
    68       bool ingroup;
       
    69       bool has_syn;
       
    70       bool syn;
       
    71 	     
       
    72       ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
       
    73 		  has_syn(false), syn(false) {}
       
    74     };
       
    75 
       
    76     typedef std::map<std::string,ParData> Opts;
       
    77     Opts _opts;
       
    78 
       
    79     class GroupData 
       
    80     {
       
    81     public:
       
    82       typedef std::list<std::string> Opts;
       
    83       Opts opts;
       
    84       bool only_one;
       
    85       bool mandatory;
       
    86       GroupData() :only_one(false), mandatory(false) {}
       
    87     };
       
    88       
       
    89     typedef std::map<std::string,GroupData> Groups;
       
    90     Groups _groups;
       
    91 
       
    92     struct OtherArg
       
    93     {
       
    94       std::string name;
       
    95       std::string help;
       
    96       OtherArg(std::string n, std::string h) :name(n), help(h) {}
       
    97 
       
    98     };
       
    99       
       
   100     std::vector<OtherArg> _others_help;
       
   101     std::vector<std::string> _file_args;
       
   102     std::string _command_name;
       
   103     
       
   104   public:
       
   105 
       
   106     ///\e
       
   107     ArgParser(int argc, char **argv);
       
   108 
       
   109     ///Add a new integer type option
       
   110 
       
   111     ///\param name The name of the option. The leading '-' must be omitted.
       
   112     ///\param help A help string.
       
   113     ///\retval value The value of the argument will be written to this variable.
       
   114     ///\param obl Indicate if the option is mandatory.
       
   115     ArgParser &option(const std::string &name,
       
   116 		    const std::string &help,
       
   117 		    int &value, bool obl=false);
       
   118 
       
   119     ///Add a new floating type option
       
   120 
       
   121     ///\param name The name of the option. The leading '-' must be omitted.
       
   122     ///\param help A help string.
       
   123     ///\retval value The value of the argument will be written to this variable.
       
   124     ///\param obl Indicate if the option is mandatory.
       
   125     ArgParser &option(const std::string &name,
       
   126 		      const std::string &help,
       
   127 		      double &value, bool obl=false);
       
   128 
       
   129     ///Add a new bool type option
       
   130 
       
   131     ///\param name The name of the option. The leading '-' must be omitted.
       
   132     ///\param help A help string.
       
   133     ///\retval value The value of the argument will be written to this variable.
       
   134     ///\param obl Indicate if the option is mandatory.
       
   135     ////\note A mandatory bool obtion is of very little use.)
       
   136     ArgParser &option(const std::string &name,
       
   137 		      const std::string &help,
       
   138 		      bool &value, bool obl=false);
       
   139 
       
   140     ///Add a new string type option
       
   141 
       
   142     ///\param name The name of the option. The leading '-' must be omitted.
       
   143     ///\param help A help string.
       
   144     ///\retval value The value of the argument will be written to this variable.
       
   145     ///\param obl Indicate if the option is mandatory.
       
   146     ArgParser &option(const std::string &name,
       
   147 		      const std::string &help,
       
   148 		      std::string &value, bool obl=false);
       
   149     
       
   150     ///Bind a function to an option.
       
   151 
       
   152     ///\param name The name of the option. The leading '-' must be omitted.
       
   153     ///\param help A help string.
       
   154     ///\retval func The function to be called when the option is given. It
       
   155     ///  must be of type "void f(void *)"
       
   156     ///\param data Data to be passed to \c func
       
   157     ArgParser &option(const std::string &name,
       
   158 		    const std::string &help,
       
   159 		    void (*func)(void *),void *data);
       
   160 
       
   161     ///Boundle some options into a group
       
   162 
       
   163     /// You can group some option by calling this function repeatedly for each
       
   164     /// option to be grupped with the same groupname.
       
   165     ///\param group The group name
       
   166     ///\param opt The option name
       
   167     ArgParser &optionGroup(const std::string &group,
       
   168 			   const std::string &opt);
       
   169 
       
   170     ///Make the members of a group exclusive
       
   171 
       
   172     ///If you call this function for a group, than at most one of them can be
       
   173     ///given at the same time
       
   174     ArgParser &onlyOneGroup(const std::string &group);
       
   175   
       
   176     ///Create synonym to an option
       
   177 
       
   178     ///With this function you can create a sysnonym called \c sys of the
       
   179     ///option \c opt.
       
   180     ArgParser &synonym(const std::string &syn,
       
   181 			   const std::string &opt);
       
   182     
       
   183     ///Make a group mandatory
       
   184 
       
   185     ///Using this function, at least one of the members of \c group
       
   186     ///must be given.
       
   187     ArgParser &mandatoryGroup(const std::string &group);
       
   188     
       
   189     ///Give help string for non-parsed arguments.
       
   190 
       
   191     ///With this function you can give help string for non-parsed arguments.
       
   192     ///the parameter \c name will be printed in the short usage line, while
       
   193     ///\c help gives a more detailed description.
       
   194     ArgParser &other(const std::string &name,
       
   195 		     const std::string &help="");
       
   196     
       
   197     ///Non option type arguments.
       
   198 
       
   199     ///Gives back a reference to a vector consisting of the program arguments
       
   200     ///not starting with a '-' character.
       
   201     std::vector<std::string> &files() { return _file_args; }
       
   202 
       
   203     ///Give back the command name (the 0th argument)
       
   204     const std::string &commandName() { return _command_name; }
       
   205 
       
   206     void show(std::ostream &os,Opts::iterator i);
       
   207     void show(std::ostream &os,Groups::iterator i);
       
   208     void showHelp(Opts::iterator i);
       
   209     void showHelp(std::vector<OtherArg>::iterator i);
       
   210     void shortHelp();
       
   211     void showHelp();
       
   212 
       
   213     void unknownOpt(std::string arg);
       
   214 
       
   215     void requiresValue(std::string arg, OptType t);
       
   216     void checkMandatories();
       
   217     
       
   218     ///\e
       
   219     ArgParser &parse();
       
   220 
       
   221     /// Synonym for parse()
       
   222     ArgParser &run() 
       
   223     {
       
   224       return parse();
       
   225     }
       
   226     
       
   227     ///Check if an opion has been given to the command.
       
   228     bool given(std::string op) 
       
   229     {
       
   230       Opts::iterator i = _opts.find(op);
       
   231       return i!=_opts.end()?i->second.set:false;
       
   232     }
       
   233     
       
   234   };
       
   235 }
       
   236 
       
   237     
       
   238 
       
   239 #endif // LEMON_MAIN_PARAMS