19 #ifndef INCLUDE_UTIL_COMMANDLINE_HPP
20 #define INCLUDE_UTIL_COMMANDLINE_HPP
34 class I_CommandLineOption {
36 virtual ~I_CommandLineOption() {}
37 virtual void notify_begin() = 0;
38 virtual void notify( std::string) = 0;
39 virtual void notify_end() = 0;
40 virtual std::string getName() = 0;
41 virtual std::string getDefaultValue() = 0;
42 virtual std::string getHelpString() = 0;
52 static CommandLine &getSingleton()
54 static CommandLine commandLine;
58 void parse(
int argc,
char **argv,
bool exitOnHelp =
true)
60 parse(argc, const_cast<const char **>(argv), exitOnHelp);
63 void parse(
int argc,
const char **argv,
bool exitOnHelp =
true)
65 mOptionValues.clear();
71 if (argc == 2 && isKey(argv[1]) && toKey(argv[1]) ==
"help")
73 if (mOptions.find(
"help" ) == mOptions.end())
75 std::cout <<
"Available command line switches:\n";
76 for (OptionIterator it = mOptions.begin(); it != mOptions.end(); it++)
80 I_CommandLineOption *option = (*it).second;
81 std::cout <<
"-" << option->getName() <<
"\n";
82 std::cout <<
"\tDescription: " << option->getHelpString() <<
"\n";
83 std::cout <<
"\tDefault: " << option->getDefaultValue() <<
"\n";
96 std::string arg1 = argv[i];
98 std::string arg2 = (i<argc) ? argv[i] :
"";
104 mOptionValues[ toKey(arg1) ].push_back( arg2 );
108 mOptionValues[ toKey(arg1) ].push_back(
"" );
111 if (mOptions.find( toKey(arg1) ) == mOptions.end())
119 mArgs.push_back( arg1 );
125 for (OptionIterator iter = mOptions.begin(); iter != mOptions.end(); iter++)
129 (*iter).second->notify_begin();
133 for (OptionValueIterator iter = mOptionValues.begin(); iter != mOptionValues.end(); iter++)
135 OptionIterator jter = mOptions.find((*iter).first);
136 if (jter != mOptions.end())
138 for (ValueIterator kter = (*iter).second.begin(); kter != (*iter).second.end(); kter++)
140 jter->second->notify( *kter );
145 for (OptionIterator iter = mOptions.begin(); iter != mOptions.end(); iter++)
149 (*iter).second->notify_end();
154 void registerOption(I_CommandLineOption *option)
156 mOptions[ option->getName() ] = option;
159 void unregisterOption(I_CommandLineOption *option)
161 OptionIterator it = mOptions.find( option->getName() );
162 if (it != mOptions.end() && (*it).second == option)
164 mOptions.erase( it );
171 mOptionValues.clear();
176 T
get(std::string name)
179 lexical_cast( mOptionValues[name][0], t );
183 const std::vector<std::string> &getArguments()
188 const std::vector<std::string> &getValues(std::string name)
190 return mOptionValues[name];
194 T lexical_cast(std::string strValue, T* = NULL)
198 lexical_cast(strValue, t);
204 std::map< std::string, I_CommandLineOption *> mOptions;
205 std::map<std::string, std::vector<std::string> > mOptionValues;
206 std::vector<std::string> mArgs;
208 typedef std::map< std::string, I_CommandLineOption *>::iterator OptionIterator;
209 typedef std::map<std::string, std::vector<std::string> >::iterator OptionValueIterator;
210 typedef std::vector<std::string>::iterator ValueIterator;
212 bool isKey(
const std::string &arg)
214 bool startsWithDash = (arg.size() > 1 && arg[0] ==
'-' );
215 bool startsWithDoubleDash = (arg.size() > 2 && arg[0] ==
'-' && arg[1] ==
'-');
216 return startsWithDash || startsWithDoubleDash;
219 std::string toKey(
const std::string &arg)
221 assert( isKey(arg) );
223 bool startsWithDash = (arg.size() > 1 && arg[0] ==
'-' );
224 bool startsWithDoubleDash = (arg.size() > 2 && arg[0] ==
'-' && arg[1] ==
'-');
226 if (startsWithDoubleDash)
228 return arg.substr(2);
230 else if (startsWithDash)
232 return arg.substr(1);
236 assert(0 &&
"invalid command line option syntax");
241 void lexical_cast(
const std::string &strValue,
bool &value )
243 if (strValue ==
"1" || strValue ==
"true" || strValue ==
"")
249 void lexical_cast(
const std::string &strValue,
int &value )
251 value = atoi(strValue.c_str());
254 void lexical_cast(
const std::string &strValue,
unsigned int &value )
256 value =
static_cast<unsigned int>(atoi(strValue.c_str()));
259 void lexical_cast(
const std::string &strValue, std::string &value )
267 class CommandLineOption :
public I_CommandLineOption {
270 CommandLineOption(std::string name, T default_value, std::string helpString) :
271 name(name), default_value(default_value), helpString(helpString)
273 CommandLine::getSingleton().registerOption(
this);
278 CommandLine::getSingleton().unregisterOption(
this);
287 const std::vector<T> &getValues()
const
294 return (values.empty()) ? default_value : values[0];
300 values.push_back( t );
303 virtual void on_notify_end()
318 void notify( std::string value )
321 values.push_back( CommandLine::getSingleton().lexical_cast(value, (T *) 0));
324 std::string getName()
329 std::string getHelpString()
334 std::string getDefaultValue()
336 std::ostringstream ostr;
337 ostr << default_value ;
344 std::vector<T> values;
345 std::string helpString;
349 inline std::istream &operator>>(std::istream &is, CommandLineOption<T> &option)
358 inline RCF::MemOstream &operator<<(RCF::MemOstream &os, CommandLineOption<T> &option)
366 #endif // ! INCLUDE_UTIL_COMMANDLINE_HPP