1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/arg_parser.h Sat Mar 03 12:05:05 2007 +0000
1.3 @@ -0,0 +1,239 @@
1.4 +/* -*- C++ -*-
1.5 + * lemon/main_params.h - Part of LEMON, a generic C++ optimization library
1.6 + *
1.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.9 + *
1.10 + * Permission to use, modify and distribute this software is granted
1.11 + * provided that this copyright notice appears in all copies. For
1.12 + * precise terms see the accompanying LICENSE file.
1.13 + *
1.14 + * This software is provided "AS IS" with no warranty of any kind,
1.15 + * express or implied, and with no claim as to its suitability for any
1.16 + * purpose.
1.17 + *
1.18 + */
1.19 +
1.20 +#ifndef LEMON_ARG_PARSER
1.21 +#define LEMON_ARG_PARSER
1.22 +
1.23 +#include <vector>
1.24 +#include <map>
1.25 +#include <list>
1.26 +#include <string>
1.27 +#include <iostream>
1.28 +#include <sstream>
1.29 +#include <algorithm>
1.30 +
1.31 +///\ingroup misc
1.32 +///\file
1.33 +///\brief A tools to parse command line arguments.
1.34 +///
1.35 +///\author Alpar Juttner
1.36 +
1.37 +namespace lemon {
1.38 +
1.39 + ///Command line arguments parser
1.40 +
1.41 + ///\ingroup misc
1.42 + ///Command line arguments parser
1.43 + ///
1.44 + class ArgParser {
1.45 +
1.46 + static void _showHelp(void *p);
1.47 + protected:
1.48 +
1.49 + int _argc;
1.50 + char **_argv;
1.51 +
1.52 + enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 };
1.53 +
1.54 + class ParData {
1.55 + public:
1.56 + union {
1.57 + bool *bool_p;
1.58 + int *int_p;
1.59 + double *double_p;
1.60 + std::string *string_p;
1.61 + struct {
1.62 + void (*p)(void *);
1.63 + void *data;
1.64 + } func_p;
1.65 +
1.66 + };
1.67 + std::string help;
1.68 + bool mandatory;
1.69 + OptType type;
1.70 + bool set;
1.71 + bool ingroup;
1.72 + bool has_syn;
1.73 + bool syn;
1.74 +
1.75 + ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false),
1.76 + has_syn(false), syn(false) {}
1.77 + };
1.78 +
1.79 + typedef std::map<std::string,ParData> Opts;
1.80 + Opts _opts;
1.81 +
1.82 + class GroupData
1.83 + {
1.84 + public:
1.85 + typedef std::list<std::string> Opts;
1.86 + Opts opts;
1.87 + bool only_one;
1.88 + bool mandatory;
1.89 + GroupData() :only_one(false), mandatory(false) {}
1.90 + };
1.91 +
1.92 + typedef std::map<std::string,GroupData> Groups;
1.93 + Groups _groups;
1.94 +
1.95 + struct OtherArg
1.96 + {
1.97 + std::string name;
1.98 + std::string help;
1.99 + OtherArg(std::string n, std::string h) :name(n), help(h) {}
1.100 +
1.101 + };
1.102 +
1.103 + std::vector<OtherArg> _others_help;
1.104 + std::vector<std::string> _file_args;
1.105 + std::string _command_name;
1.106 +
1.107 + public:
1.108 +
1.109 + ///\e
1.110 + ArgParser(int argc, char **argv);
1.111 +
1.112 + ///Add a new integer type option
1.113 +
1.114 + ///\param name The name of the option. The leading '-' must be omitted.
1.115 + ///\param help A help string.
1.116 + ///\retval value The value of the argument will be written to this variable.
1.117 + ///\param obl Indicate if the option is mandatory.
1.118 + ArgParser &option(const std::string &name,
1.119 + const std::string &help,
1.120 + int &value, bool obl=false);
1.121 +
1.122 + ///Add a new floating type option
1.123 +
1.124 + ///\param name The name of the option. The leading '-' must be omitted.
1.125 + ///\param help A help string.
1.126 + ///\retval value The value of the argument will be written to this variable.
1.127 + ///\param obl Indicate if the option is mandatory.
1.128 + ArgParser &option(const std::string &name,
1.129 + const std::string &help,
1.130 + double &value, bool obl=false);
1.131 +
1.132 + ///Add a new bool type option
1.133 +
1.134 + ///\param name The name of the option. The leading '-' must be omitted.
1.135 + ///\param help A help string.
1.136 + ///\retval value The value of the argument will be written to this variable.
1.137 + ///\param obl Indicate if the option is mandatory.
1.138 + ////\note A mandatory bool obtion is of very little use.)
1.139 + ArgParser &option(const std::string &name,
1.140 + const std::string &help,
1.141 + bool &value, bool obl=false);
1.142 +
1.143 + ///Add a new string type option
1.144 +
1.145 + ///\param name The name of the option. The leading '-' must be omitted.
1.146 + ///\param help A help string.
1.147 + ///\retval value The value of the argument will be written to this variable.
1.148 + ///\param obl Indicate if the option is mandatory.
1.149 + ArgParser &option(const std::string &name,
1.150 + const std::string &help,
1.151 + std::string &value, bool obl=false);
1.152 +
1.153 + ///Bind a function to an option.
1.154 +
1.155 + ///\param name The name of the option. The leading '-' must be omitted.
1.156 + ///\param help A help string.
1.157 + ///\retval func The function to be called when the option is given. It
1.158 + /// must be of type "void f(void *)"
1.159 + ///\param data Data to be passed to \c func
1.160 + ArgParser &option(const std::string &name,
1.161 + const std::string &help,
1.162 + void (*func)(void *),void *data);
1.163 +
1.164 + ///Boundle some options into a group
1.165 +
1.166 + /// You can group some option by calling this function repeatedly for each
1.167 + /// option to be grupped with the same groupname.
1.168 + ///\param group The group name
1.169 + ///\param opt The option name
1.170 + ArgParser &optionGroup(const std::string &group,
1.171 + const std::string &opt);
1.172 +
1.173 + ///Make the members of a group exclusive
1.174 +
1.175 + ///If you call this function for a group, than at most one of them can be
1.176 + ///given at the same time
1.177 + ArgParser &onlyOneGroup(const std::string &group);
1.178 +
1.179 + ///Create synonym to an option
1.180 +
1.181 + ///With this function you can create a sysnonym called \c sys of the
1.182 + ///option \c opt.
1.183 + ArgParser &synonym(const std::string &syn,
1.184 + const std::string &opt);
1.185 +
1.186 + ///Make a group mandatory
1.187 +
1.188 + ///Using this function, at least one of the members of \c group
1.189 + ///must be given.
1.190 + ArgParser &mandatoryGroup(const std::string &group);
1.191 +
1.192 + ///Give help string for non-parsed arguments.
1.193 +
1.194 + ///With this function you can give help string for non-parsed arguments.
1.195 + ///the parameter \c name will be printed in the short usage line, while
1.196 + ///\c help gives a more detailed description.
1.197 + ArgParser &other(const std::string &name,
1.198 + const std::string &help="");
1.199 +
1.200 + ///Non option type arguments.
1.201 +
1.202 + ///Gives back a reference to a vector consisting of the program arguments
1.203 + ///not starting with a '-' character.
1.204 + std::vector<std::string> &files() { return _file_args; }
1.205 +
1.206 + ///Give back the command name (the 0th argument)
1.207 + const std::string &commandName() { return _command_name; }
1.208 +
1.209 + void show(std::ostream &os,Opts::iterator i);
1.210 + void show(std::ostream &os,Groups::iterator i);
1.211 + void showHelp(Opts::iterator i);
1.212 + void showHelp(std::vector<OtherArg>::iterator i);
1.213 + void shortHelp();
1.214 + void showHelp();
1.215 +
1.216 + void unknownOpt(std::string arg);
1.217 +
1.218 + void requiresValue(std::string arg, OptType t);
1.219 + void checkMandatories();
1.220 +
1.221 + ///\e
1.222 + ArgParser &parse();
1.223 +
1.224 + /// Synonym for parse()
1.225 + ArgParser &run()
1.226 + {
1.227 + return parse();
1.228 + }
1.229 +
1.230 + ///Check if an opion has been given to the command.
1.231 + bool given(std::string op)
1.232 + {
1.233 + Opts::iterator i = _opts.find(op);
1.234 + return i!=_opts.end()?i->second.set:false;
1.235 + }
1.236 +
1.237 + };
1.238 +}
1.239 +
1.240 +
1.241 +
1.242 +#endif // LEMON_MAIN_PARAMS