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