alpar@2389: /* -*- C++ -*- alpar@2389: * alpar@2391: * This file is a part of LEMON, a generic C++ optimization library alpar@2391: * alpar@2391: * Copyright (C) 2003-2007 alpar@2391: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@2389: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@2389: * alpar@2389: * Permission to use, modify and distribute this software is granted alpar@2389: * provided that this copyright notice appears in all copies. For alpar@2389: * precise terms see the accompanying LICENSE file. alpar@2389: * alpar@2389: * This software is provided "AS IS" with no warranty of any kind, alpar@2389: * express or implied, and with no claim as to its suitability for any alpar@2389: * purpose. alpar@2389: * alpar@2389: */ alpar@2389: alpar@2389: #ifndef LEMON_ARG_PARSER alpar@2389: #define LEMON_ARG_PARSER alpar@2389: alpar@2389: #include alpar@2389: #include alpar@2389: #include alpar@2389: #include alpar@2389: #include alpar@2389: #include alpar@2389: #include alpar@2389: alpar@2389: ///\ingroup misc alpar@2389: ///\file alpar@2389: ///\brief A tools to parse command line arguments. alpar@2389: /// alpar@2389: ///\author Alpar Juttner alpar@2389: alpar@2389: namespace lemon { alpar@2389: alpar@2389: ///Command line arguments parser alpar@2389: alpar@2389: ///\ingroup misc alpar@2389: ///Command line arguments parser alpar@2389: /// alpar@2389: class ArgParser { alpar@2389: alpar@2389: static void _showHelp(void *p); alpar@2389: protected: alpar@2389: alpar@2389: int _argc; alpar@2389: char **_argv; alpar@2389: alpar@2389: enum OptType { UNKNOWN=0, BOOL=1, STRING=2, DOUBLE=3, INTEGER=4, FUNC=5 }; alpar@2389: alpar@2389: class ParData { alpar@2389: public: alpar@2389: union { alpar@2389: bool *bool_p; alpar@2389: int *int_p; alpar@2389: double *double_p; alpar@2389: std::string *string_p; alpar@2389: struct { alpar@2389: void (*p)(void *); alpar@2389: void *data; alpar@2389: } func_p; alpar@2389: alpar@2389: }; alpar@2389: std::string help; alpar@2389: bool mandatory; alpar@2389: OptType type; alpar@2389: bool set; alpar@2389: bool ingroup; alpar@2389: bool has_syn; alpar@2389: bool syn; alpar@2389: alpar@2389: ParData() : mandatory(false), type(UNKNOWN), set(false), ingroup(false), alpar@2389: has_syn(false), syn(false) {} alpar@2389: }; alpar@2389: alpar@2389: typedef std::map Opts; alpar@2389: Opts _opts; alpar@2389: alpar@2389: class GroupData alpar@2389: { alpar@2389: public: alpar@2389: typedef std::list Opts; alpar@2389: Opts opts; alpar@2389: bool only_one; alpar@2389: bool mandatory; alpar@2389: GroupData() :only_one(false), mandatory(false) {} alpar@2389: }; alpar@2389: alpar@2389: typedef std::map Groups; alpar@2389: Groups _groups; alpar@2389: alpar@2389: struct OtherArg alpar@2389: { alpar@2389: std::string name; alpar@2389: std::string help; alpar@2389: OtherArg(std::string n, std::string h) :name(n), help(h) {} alpar@2389: alpar@2389: }; alpar@2389: alpar@2389: std::vector _others_help; alpar@2389: std::vector _file_args; alpar@2389: std::string _command_name; alpar@2389: alpar@2389: public: alpar@2389: alpar@2389: ///\e alpar@2389: ArgParser(int argc, char **argv); alpar@2389: alpar@2389: ///Add a new integer type option alpar@2389: alpar@2389: ///\param name The name of the option. The leading '-' must be omitted. alpar@2389: ///\param help A help string. alpar@2389: ///\retval value The value of the argument will be written to this variable. alpar@2389: ///\param obl Indicate if the option is mandatory. alpar@2389: ArgParser &option(const std::string &name, alpar@2389: const std::string &help, alpar@2389: int &value, bool obl=false); alpar@2389: alpar@2389: ///Add a new floating type option alpar@2389: alpar@2389: ///\param name The name of the option. The leading '-' must be omitted. alpar@2389: ///\param help A help string. alpar@2389: ///\retval value The value of the argument will be written to this variable. alpar@2389: ///\param obl Indicate if the option is mandatory. alpar@2389: ArgParser &option(const std::string &name, alpar@2389: const std::string &help, alpar@2389: double &value, bool obl=false); alpar@2389: alpar@2389: ///Add a new bool type option alpar@2389: alpar@2389: ///\param name The name of the option. The leading '-' must be omitted. alpar@2389: ///\param help A help string. alpar@2389: ///\retval value The value of the argument will be written to this variable. alpar@2389: ///\param obl Indicate if the option is mandatory. alpar@2389: ////\note A mandatory bool obtion is of very little use.) alpar@2389: ArgParser &option(const std::string &name, alpar@2389: const std::string &help, alpar@2389: bool &value, bool obl=false); alpar@2389: alpar@2389: ///Add a new string type option alpar@2389: alpar@2389: ///\param name The name of the option. The leading '-' must be omitted. alpar@2389: ///\param help A help string. alpar@2389: ///\retval value The value of the argument will be written to this variable. alpar@2389: ///\param obl Indicate if the option is mandatory. alpar@2389: ArgParser &option(const std::string &name, alpar@2389: const std::string &help, alpar@2389: std::string &value, bool obl=false); alpar@2389: alpar@2389: ///Bind a function to an option. alpar@2389: alpar@2389: ///\param name The name of the option. The leading '-' must be omitted. alpar@2389: ///\param help A help string. alpar@2389: ///\retval func The function to be called when the option is given. It alpar@2389: /// must be of type "void f(void *)" alpar@2389: ///\param data Data to be passed to \c func alpar@2389: ArgParser &option(const std::string &name, alpar@2389: const std::string &help, alpar@2389: void (*func)(void *),void *data); alpar@2389: alpar@2389: ///Boundle some options into a group alpar@2389: alpar@2389: /// You can group some option by calling this function repeatedly for each alpar@2389: /// option to be grupped with the same groupname. alpar@2389: ///\param group The group name alpar@2389: ///\param opt The option name alpar@2389: ArgParser &optionGroup(const std::string &group, alpar@2389: const std::string &opt); alpar@2389: alpar@2389: ///Make the members of a group exclusive alpar@2389: alpar@2389: ///If you call this function for a group, than at most one of them can be alpar@2389: ///given at the same time alpar@2389: ArgParser &onlyOneGroup(const std::string &group); alpar@2389: alpar@2389: ///Create synonym to an option alpar@2389: alpar@2389: ///With this function you can create a sysnonym called \c sys of the alpar@2389: ///option \c opt. alpar@2389: ArgParser &synonym(const std::string &syn, alpar@2389: const std::string &opt); alpar@2389: alpar@2389: ///Make a group mandatory alpar@2389: alpar@2389: ///Using this function, at least one of the members of \c group alpar@2389: ///must be given. alpar@2389: ArgParser &mandatoryGroup(const std::string &group); alpar@2389: alpar@2389: ///Give help string for non-parsed arguments. alpar@2389: alpar@2389: ///With this function you can give help string for non-parsed arguments. alpar@2389: ///the parameter \c name will be printed in the short usage line, while alpar@2389: ///\c help gives a more detailed description. alpar@2389: ArgParser &other(const std::string &name, alpar@2389: const std::string &help=""); alpar@2389: alpar@2389: ///Non option type arguments. alpar@2389: alpar@2389: ///Gives back a reference to a vector consisting of the program arguments alpar@2389: ///not starting with a '-' character. alpar@2389: std::vector &files() { return _file_args; } alpar@2389: alpar@2389: ///Give back the command name (the 0th argument) alpar@2389: const std::string &commandName() { return _command_name; } alpar@2389: alpar@2389: void show(std::ostream &os,Opts::iterator i); alpar@2389: void show(std::ostream &os,Groups::iterator i); alpar@2389: void showHelp(Opts::iterator i); alpar@2389: void showHelp(std::vector::iterator i); alpar@2389: void shortHelp(); alpar@2389: void showHelp(); alpar@2389: alpar@2389: void unknownOpt(std::string arg); alpar@2389: alpar@2389: void requiresValue(std::string arg, OptType t); alpar@2389: void checkMandatories(); alpar@2389: alpar@2389: ///\e alpar@2389: ArgParser &parse(); alpar@2389: alpar@2389: /// Synonym for parse() alpar@2389: ArgParser &run() alpar@2389: { alpar@2389: return parse(); alpar@2389: } alpar@2389: alpar@2389: ///Check if an opion has been given to the command. alpar@2389: bool given(std::string op) alpar@2389: { alpar@2389: Opts::iterator i = _opts.find(op); alpar@2389: return i!=_opts.end()?i->second.set:false; alpar@2389: } alpar@2389: alpar@2389: }; alpar@2389: } alpar@2389: alpar@2389: alpar@2389: alpar@2389: #endif // LEMON_MAIN_PARAMS