00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00021
00022 #include <iostream>
00023 #include <stdlib.h>
00024 #include <boost/regex.hpp>
00025 #include <boost/foreach.hpp>
00026
00027 #include "icl_core/List.h"
00028 #include "icl_core_config/GetoptParser.h"
00029
00030 namespace icl_core {
00031 namespace config {
00032
00033 Getopt& Getopt::instance()
00034 {
00035 static Getopt instance;
00036 return instance;
00037 }
00038
00039 void Getopt::activateExtraCmdParams(const icl_core::String& delimiter)
00040 {
00041 m_extra_cmd_param_activated = true;
00042 m_extra_cmd_param_delimiter = delimiter;
00043 }
00044
00045 void Getopt::addParameter(const GetoptParameter& parameter)
00046 {
00047 if (parameter.isPrefixOption())
00048 {
00049 m_prefix_parameters.insert(std::make_pair(parameter.option(), parameter));
00050 if (parameter.shortOption() != "")
00051 {
00052 m_short_prefix_parameters.insert(std::make_pair(parameter.shortOption(), parameter));
00053 }
00054 }
00055 else
00056 {
00057 m_parameters.insert(std::make_pair(parameter.option(), parameter));
00058 if (parameter.shortOption() != "")
00059 {
00060 m_short_parameters.insert(std::make_pair(parameter.shortOption(), parameter));
00061 }
00062 }
00063 }
00064
00065 void Getopt::addParameter(const GetoptParameterList& parameters)
00066 {
00067 for (GetoptParameterList::const_iterator opt_it = parameters.begin();
00068 opt_it != parameters.end(); ++opt_it)
00069 {
00070 addParameter(*opt_it);
00071 }
00072 }
00073
00074 void Getopt::addParameter(const GetoptPositionalParameter ¶meter)
00075 {
00076 if (parameter.isOptional())
00077 {
00078 m_optional_positional_parameters.push_back(parameter);
00079 }
00080 else
00081 {
00082 m_required_positional_parameters.push_back(parameter);
00083 }
00084 }
00085
00086 void Getopt::addParameter(const GetoptPositionalParameterList ¶meters)
00087 {
00088 for (GetoptPositionalParameterList::const_iterator opt_it = parameters.begin();
00089 opt_it != parameters.end(); ++opt_it)
00090 {
00091 addParameter(*opt_it);
00092 }
00093 }
00094
00095 bool Getopt::initialize(int& argc, char *argv[], bool remove_read_arguments)
00096 {
00097 return initialize(argc, argv, remove_read_arguments ? eCLC_Cleanup : eCLC_None, ePRC_Strict);
00098 }
00099
00100 bool Getopt::initialize(int& argc, char *argv[], CommandLineCleaning cleanup,
00101 ParameterRegistrationCheck registration_check)
00102 {
00103 if (argc == 0)
00104 {
00105 return false;
00106 }
00107
00108 if (isInitialized())
00109 {
00110 std::cerr << "GETOPT WARNING: The commandline option framework is already initialized!" << std::endl;
00111 return true;
00112 }
00113
00114
00115 m_argc = argc;
00116 m_argv = argv;
00117
00118
00119
00120 m_program_name = argv[0];
00121
00122
00123 icl_core::List<icl_core::String> arguments;
00124 for (int index = 1; index < argc; ++index)
00125 {
00126 arguments.push_back(argv[index]);
00127 }
00128
00129
00130
00131 size_t positional_parameters_counter = 0;
00132 bool extra_cmd_params_reached = false;
00133 boost::regex long_opt_regex("--([^-][^=]*)(=(.*))?");
00134 boost::regex short_opt_regex("-([^-].*)");
00135 boost::smatch mres;
00136 for (icl_core::List<icl_core::String>::const_iterator arg_it = arguments.begin();
00137 arg_it != arguments.end(); ++arg_it)
00138 {
00139 if (extra_cmd_params_reached)
00140 {
00141 m_extra_cmd_param.push_back(*arg_it);
00142 }
00143 else if (boost::regex_match(*arg_it, mres, long_opt_regex))
00144 {
00145
00146 icl_core::String name = mres[1];
00147 ParameterMap::const_iterator find_it = m_parameters.find(name);
00148 if (find_it != m_parameters.end())
00149 {
00150 if (find_it->second.hasValue())
00151 {
00152
00153
00154 if (mres.size() == 4)
00155 {
00156 m_param_opt[name] = mres[3];
00157 }
00158 else
00159 {
00160 std::cerr << "Found option " << *arg_it << " but the value is missing." << std::endl;
00161 printHelp();
00162 return false;
00163 }
00164 }
00165 else
00166 {
00167 m_param_opt[name] = "yes";
00168 }
00169 }
00170 else
00171 {
00172
00173
00174 bool found = false;
00175 boost::smatch prefix_res;
00176 for (ParameterMap::const_iterator prefix_it = m_prefix_parameters.begin();
00177 !found && prefix_it != m_prefix_parameters.end(); ++prefix_it)
00178 {
00179 if (boost::regex_match(name, prefix_res, boost::regex(prefix_it->first + "(.*)")))
00180 {
00181 found = true;
00182
00183 if (prefix_it->second.hasValue())
00184 {
00185 if (mres.size() == 4)
00186 {
00187 m_prefix_param_opt[prefix_it->first].push_back(KeyValue(prefix_res[1], mres[3]));
00188 }
00189 else
00190 {
00191 std::cerr << "Found prefix option " << name << " but the value is missing." << std::endl;
00192 printHelp();
00193 return false;
00194 }
00195 }
00196 else
00197 {
00198 m_prefix_param_opt[prefix_it->first].push_back(KeyValue(prefix_res[1], "yes"));
00199 }
00200 }
00201 }
00202
00203
00204 if (!found)
00205 {
00206 if (registration_check == ePRC_Strict)
00207 {
00208 std::cerr << "Found unknown option " << *arg_it << "." << std::endl;
00209 printHelp();
00210 return false;
00211 }
00212 else
00213 {
00214 m_param_non_opt.push_back(*arg_it);
00215 }
00216 }
00217 }
00218 }
00219 else if (boost::regex_match(*arg_it, mres, short_opt_regex))
00220 {
00221
00222 icl_core::String name = mres[1];
00223 ParameterMap::const_iterator find_it = m_short_parameters.find(name);
00224 if (find_it != m_short_parameters.end())
00225 {
00226 if (find_it->second.hasValue())
00227 {
00228
00229 ++arg_it;
00230 if (arg_it == arguments.end())
00231 {
00232 std::cerr << "Found option -" << name << " but the value is missing." << std::endl;
00233 printHelp();
00234 return false;
00235 }
00236 else
00237 {
00238 m_param_opt[find_it->second.option()] = *arg_it;
00239 }
00240 }
00241 else
00242 {
00243 m_param_opt[find_it->second.option()] = "yes";
00244 }
00245 }
00246 else
00247 {
00248
00249
00250 bool found = false;
00251 boost::smatch prefix_res;
00252 for (ParameterMap::const_iterator prefix_it = m_short_prefix_parameters.begin();
00253 !found && prefix_it != m_short_prefix_parameters.end(); ++prefix_it)
00254 {
00255 if (boost::regex_match(name, prefix_res, boost::regex(prefix_it->first + "(.*)")))
00256 {
00257 found = true;
00258
00259 if (prefix_it->second.hasValue())
00260 {
00261
00262 ++arg_it;
00263 if (arg_it == arguments.end())
00264 {
00265 std::cerr << "Found prefix option " << name << " but the value is missing." << std::endl;
00266 printHelp();
00267 return false;
00268 }
00269 else
00270 {
00271 m_prefix_param_opt[prefix_it->second.option()].push_back(KeyValue(prefix_res[1], *arg_it));
00272 }
00273 }
00274 else
00275 {
00276 m_prefix_param_opt[prefix_it->second.option()].push_back(KeyValue(prefix_res[1], "yes"));
00277 }
00278 }
00279 }
00280
00281
00282 if (!found)
00283 {
00284 if (registration_check == ePRC_Strict)
00285 {
00286 std::cerr << "Found unknown option " << *arg_it << "." << std::endl;
00287 printHelp();
00288 return false;
00289 }
00290 else
00291 {
00292 m_param_non_opt.push_back(*arg_it);
00293 }
00294 }
00295 }
00296 }
00297 else if (m_extra_cmd_param_activated && *arg_it == m_extra_cmd_param_delimiter)
00298 {
00299 extra_cmd_params_reached = true;
00300 }
00301 else if (positional_parameters_counter < m_required_positional_parameters.size())
00302 {
00303
00304 const GetoptPositionalParameter& param = m_required_positional_parameters[positional_parameters_counter];
00305 m_param_opt[param.name()] = *arg_it;
00306 positional_parameters_counter++;
00307 }
00308 else if (positional_parameters_counter < m_required_positional_parameters.size() + m_optional_positional_parameters.size())
00309 {
00310
00311 const GetoptPositionalParameter& param = m_optional_positional_parameters[positional_parameters_counter - m_required_positional_parameters.size()];
00312 m_param_opt[param.name()] = *arg_it;
00313 positional_parameters_counter++;
00314 }
00315 else if (positional_parameters_counter >= m_required_positional_parameters.size() + m_optional_positional_parameters.size())
00316 {
00321
00322
00323
00324
00325
00326
00327
00328 {
00329 m_param_non_opt.push_back(*arg_it);
00330 }
00331 }
00332 }
00333
00334
00335 if (positional_parameters_counter < m_required_positional_parameters.size())
00336 {
00337 std::cerr << "Not all required parameters are given. Aborting." << std::endl;
00338 printHelp();
00339 exit(0);
00340 }
00341
00342
00343 if (m_param_opt.find("help") != m_param_opt.end())
00344 {
00345 printHelp();
00346 exit(0);
00347 }
00348
00349
00350 if (cleanup == eCLC_Cleanup)
00351 {
00352 int check = 1;
00353 while (check < argc)
00354 {
00355 icl_core::Vector<icl_core::String>::const_iterator find_it =
00356 std::find(m_param_non_opt.begin(), m_param_non_opt.end(), icl_core::String(argv[check]));
00357 if (find_it == m_param_non_opt.end())
00358 {
00359 for (int move = check + 1; move < argc; ++move)
00360 {
00361 argv[move - 1] = argv[move];
00362 }
00363 --argc;
00364 }
00365 else
00366 {
00367 ++check;
00368 }
00369 }
00370 }
00371
00372 return true;
00373 }
00374
00375 int& Getopt::argc()
00376 {
00377 return m_argc;
00378 }
00379
00380 char **Getopt::argv() const
00381 {
00382 return m_argv;
00383 }
00384
00385 icl_core::String Getopt::extraCmdParam(size_t index) const
00386 {
00387 return m_extra_cmd_param[index];
00388 }
00389
00390 size_t Getopt::extraCmdParamCount() const
00391 {
00392 return m_extra_cmd_param.size();
00393 }
00394
00395 icl_core::String Getopt::paramOpt(const icl_core::String& name) const
00396 {
00397 icl_core::Map<icl_core::String, icl_core::String>::const_iterator find_it = m_param_opt.find(name);
00398 if (find_it == m_param_opt.end())
00399 {
00400 return "";
00401 }
00402 else
00403 {
00404 return find_it->second;
00405 }
00406 }
00407
00408 bool Getopt::paramOptPresent(const icl_core::String& name) const
00409 {
00410 return m_param_opt.find(name) != m_param_opt.end();
00411 }
00412
00413 Getopt::KeyValueList Getopt::paramPrefixOpt(const icl_core::String& prefix) const
00414 {
00415 icl_core::Map<icl_core::String, KeyValueList>::const_iterator find_it = m_prefix_param_opt.find(prefix);
00416 if (find_it == m_prefix_param_opt.end())
00417 {
00418 return KeyValueList();
00419 }
00420 else
00421 {
00422 return find_it->second;
00423 }
00424 }
00425
00426 bool Getopt::paramPrefixOptPresent(const icl_core::String& prefix) const
00427 {
00428 return m_prefix_param_opt.find(prefix) != m_prefix_param_opt.end();
00429 }
00430
00431 icl_core::String Getopt::paramNonOpt(size_t index) const
00432 {
00433 if (index < m_param_non_opt.size())
00434 {
00435 return m_param_non_opt.at(index);
00436 }
00437 else
00438 {
00439 return "";
00440 }
00441 }
00442
00443 size_t Getopt::paramNonOptCount() const
00444 {
00445 return m_param_non_opt.size();
00446 }
00447
00448 icl_core::String Getopt::programName() const
00449 {
00450 return m_program_name;
00451 }
00452
00453 icl_core::String Getopt::programVersion() const
00454 {
00455 return m_program_version;
00456 }
00457
00458 void Getopt::setProgramVersion(icl_core::String const & version)
00459 {
00460 m_program_version = version;
00461 }
00462
00463 icl_core::String Getopt::programDescription() const
00464 {
00465 return m_program_description;
00466 }
00467
00468 void Getopt::setProgramDescription(icl_core::String const & description)
00469 {
00470 m_program_description = description;
00471 }
00472
00473 void Getopt::printHelp() const
00474 {
00475
00476 GetoptPositionalParameterList positional_parameters = m_required_positional_parameters;
00477 std::copy(m_optional_positional_parameters.begin(), m_optional_positional_parameters.end(), std::back_inserter(positional_parameters));
00478
00479 std::cerr << programName();
00480 if (programVersion() != "")
00481 {
00482 std::cerr << " (version " << programVersion() << ")";
00483 }
00484 std::cerr << std::endl << std::endl;
00485
00486 std::cerr << "Usage: ";
00487 std::cerr << programName();
00488
00489 std::cerr << " [OPTIONS...]";
00490
00491 BOOST_FOREACH(const GetoptPositionalParameter param, positional_parameters)
00492 {
00493 if (param.isOptional())
00494 {
00495 std::cerr << " [<" << param.name() << ">]";
00496 }
00497 else
00498 {
00499 std::cerr << " <" << param.name() << ">";
00500 }
00501 }
00502
00503 std::cerr << std::endl << std::endl << programDescription() << std::endl << std::endl;
00504
00505 if (positional_parameters.size() > 0 )
00506 {
00507 std::cerr << "Positional Parameters:" << std::endl;
00508
00509 BOOST_FOREACH(const GetoptPositionalParameter param, positional_parameters)
00510 {
00511 std::cerr << " <" << param.name() << ">" << ":" << std::endl << "\t"
00512 << boost::regex_replace(param.help(), boost::regex("\\n"), "\n\t")
00513 << std::endl;
00514 }
00515 std::cerr << std::endl;
00516 }
00517
00518 for (int i=0; i<2; ++i)
00519 {
00520 std::cerr << (i == 0 ? "Generic options:" : "Options:") << std::endl;
00521 for (ParameterMap::const_iterator it = m_parameters.begin(); it != m_parameters.end(); ++it)
00522 {
00523 bool const is_generic =
00524 it->second.option() == "configfile" ||
00525 it->second.option() == "dump-config" ||
00526 it->second.option() == "help" ||
00527 it->second.option() == "log-level" ||
00528 it->second.option() == "quick-debug";
00529 if (!i==is_generic)
00530 {
00531 std::cerr << " ";
00532
00533 if (it->second.shortOption() != "")
00534 {
00535 std::cerr << "-" << it->second.shortOption();
00536 if (it->second.hasValue())
00537 {
00538 std::cerr << " <value>";
00539 }
00540 std::cerr << ", ";
00541 }
00542
00543
00544 std::cerr << "--" << it->second.option();
00545 if (it->second.hasValue())
00546 {
00547 std::cerr << "=<value>";
00548 }
00549
00550
00551 std::cerr << ":" << std::endl << "\t"
00552 << boost::regex_replace(it->second.help(), boost::regex("\\n"), "\n\t")
00553 << std::endl;
00554 }
00555 }
00556 std::cerr << std::endl;
00557 }
00558 }
00559
00561 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
00562
00566 Getopt& Getopt::Instance()
00567 {
00568 return instance();
00569 }
00570
00574 void Getopt::ActivateExtraCmdParams(const icl_core::String& delimiter)
00575 {
00576 activateExtraCmdParams(delimiter);
00577 }
00578
00582 void Getopt::AddParameter(const GetoptParameter& parameter)
00583 {
00584 addParameter(parameter);
00585 }
00586
00590 void Getopt::AddParameter(const GetoptParameterList& parameters)
00591 {
00592 addParameter(parameters);
00593 }
00594
00598 bool Getopt::Initialize(int& argc, char *argv[], bool remove_read_arguments)
00599 {
00600 return initialize(argc, argv, remove_read_arguments);
00601 }
00602
00606 bool Getopt::Initialize(int& argc, char *argv[],
00607 CommandLineCleaning cleanup,
00608 ParameterRegistrationCheck registration_check)
00609 {
00610 return initialize(argc, argv, cleanup, registration_check);
00611 }
00612
00616 bool Getopt::IsInitialized() const
00617 {
00618 return isInitialized();
00619 }
00620
00624 icl_core::String Getopt::ExtraCmdParam(size_t index) const
00625 {
00626 return extraCmdParam(index);
00627 }
00628
00632 size_t Getopt::ExtraCmdParamCount() const
00633 {
00634 return extraCmdParamCount();
00635 }
00636
00640 icl_core::String Getopt::ParamOpt(const icl_core::String& name) const
00641 {
00642 return paramOpt(name);
00643 }
00644
00648 bool Getopt::ParamOptPresent(const icl_core::String& name) const
00649 {
00650 return paramOptPresent(name);
00651 }
00652
00656 Getopt::KeyValueList Getopt::ParamPrefixOpt(const icl_core::String& prefix) const
00657 {
00658 return paramPrefixOpt(prefix);
00659 }
00660
00664 bool Getopt::ParamPrefixOptPresent(const icl_core::String& prefix) const
00665 {
00666 return paramPrefixOptPresent(prefix);
00667 }
00668
00672 icl_core::String Getopt::ParamNonOpt(size_t index) const
00673 {
00674 return paramNonOpt(index);
00675 }
00676
00680 size_t Getopt::ParamNonOptCount() const
00681 {
00682 return paramNonOptCount();
00683 }
00684
00688 icl_core::String Getopt::ProgramName() const
00689 {
00690 return programName();
00691 }
00692
00696 void Getopt::PrintHelp() const
00697 {
00698 printHelp();
00699 }
00700
00701 #endif
00702
00703
00704 Getopt::Getopt()
00705 : m_extra_cmd_param_activated(false),
00706 m_initialized(false)
00707 {
00708 addParameter(GetoptParameter("help", "h", "Print commandline help."));
00709 }
00710
00711 }
00712 }