lemon/arg_parser.h
author alpar
Sat, 03 Mar 2007 12:05:05 +0000
changeset 2389 df6a32249b46
child 2391 14a343be7a5a
permissions -rw-r--r--
arg_parser.h: A command line argument parser.
dist_log.h: A tool for measuring one and two dimensional distributions.
     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