334 #include <boost/filesystem.hpp> 342 namespace style = boost::program_options::command_line_style;
389 po::basic_parsed_options<char>
394 cerr <<
"Connected to '" << db.uri() <<
"' for " << prgname << endl;
396 const mysqlpp::StoreQueryResult res =
397 db.query(
"SELECT CONCAT(fKey1,fKey2), fValue " 398 "FROM ProgramOption " 399 "WHERE fCounter=(SELECT MAX(fCounter) FROM History) " 400 "AND NOT ISNULL(fValue) " 401 "AND (fProgram='"+prgname+
"' OR fProgram='*')").store();
403 set<string> allowed_options;
405 const vector<boost::shared_ptr<po::option_description>> &options = desc.options();
406 for (
unsigned i=0;
i<options.size(); ++
i)
408 const po::option_description &d = *options[
i];
409 if (d.long_name().empty())
410 boost::throw_exception(po::error(
"long name required for database"));
412 allowed_options.insert(d.long_name());
415 po::parsed_options result(&desc);
417 for (vector<mysqlpp::Row>::const_iterator v=res.begin(); v<res.end(); v++)
419 const string key = (*v)[0].c_str();
425 const bool unregistered = allowed_options.find(key)==allowed_options.end();
426 if (unregistered && allow_unregistered)
427 boost::throw_exception(po::unknown_option(key));
436 n.value.push_back((*v)[1].c_str());
444 result.options.push_back(n);
450 po::basic_parsed_options<char>
453 return po::parsed_options(&desc);
462 fNameMapper(bind1st(mem_fun(&
Configuration::DefaultMapper), this)),
465 po::options_description
generic(
"Generic options");
466 generic.add_options()
467 (
"version,V",
"Print version information.")
468 (
"help",
"Print available commandline options.")
469 (
"help-environment",
"Print available environment variables.")
470 (
"help-database",
"Print available options retreived from the database.")
471 (
"help-config",
"Print available configuration file options.")
472 (
"print-all",
"Print all options as parsed from all the different sources.")
473 (
"print",
"Print options as parsed from the commandline.")
474 (
"print-default",
"Print options as parsed from default configuration file.")
475 (
"print-database",
"Print options as retrieved from the database.")
476 (
"print-config",
"Print options as parsed from the high priority configuration file.")
477 (
"print-environment",
"Print options as parsed from the environment.")
478 (
"print-unknown",
"Print unrecognized options.")
479 (
"print-options",
"Print options as passed to program.")
480 (
"print-wildcards",
"Print all options registered with wildcards.")
481 (
"dont-check",
"Do not check validity of options from files and database.")
482 (
"dont-check-files",
"Do not check validity of options from files.")
483 (
"dont-check-database",
"Do not check validity of options from database.")
486 po::options_description def_config;
487 def_config.add_options()
488 (
"default", var<string>(
fName+string(
".rc")),
"Default configuration file.")
491 po::options_description config(
"Configuration options");
493 (
"config,C", var<string>(),
"Configuration file overwriting options retrieved from the database.")
494 (
"database", var<string>(),
"Database link as in\n\t[user[:password]@]server.com[:port]/database\nOverwrites options from the default configuration file.")
495 (
"no-database",
"Suppress any access to the database even if a database URL was set.")
510 const vector< po::basic_option<char> >& options = parsed.options;
521 for (
unsigned i=0;
i<options.size(); ++
i)
523 const po::basic_option<char> &opt = options[
i];
525 if (opt.value.size()>0 && opt.string_key[0]!=
'-')
526 Max(maxlen, opt.string_key.length());
529 cout.setf(ios_base::left);
532 for(
unsigned i=0;
i<options.size(); ++
i)
534 const po::basic_option<char> &opt = options[
i];
536 if (opt.value.size()==0 && opt.string_key[0]!=
'-')
538 cout << setw(maxlen) << opt.string_key;
539 if (opt.value.size()>0)
540 cout <<
" = " << opt.value[0];
548 if (opt.position_key>=0)
549 com <<
" [position=" << opt.position_key <<
"]";
550 if (opt.unregistered)
551 com <<
" [unregistered]";
553 if (!com.str().empty())
554 cout <<
" # " << com.str();
565 const vector<T> vec = v.as<vector<T>>();
566 for (
typename std::vector<T>::const_iterator s=vec.begin(); s<vec.end(); s++)
569 return str.str().substr(1);
574 if (v.value().type()==
typeid(bool))
575 return v.as<
bool>() ?
"yes ":
"no";
577 if (v.value().type()==
typeid(string))
578 return v.as<
string>();
580 if (v.value().type()==
typeid(int16_t))
581 return to_string((
long long int)v.as<int16_t>());
583 if (v.value().type()==
typeid(int32_t))
584 return to_string((
long long int)v.as<int32_t>());
586 if (v.value().type()==
typeid(int64_t))
587 return to_string((
long long int)v.as<int64_t>());
589 if (v.value().type()==
typeid(uint16_t))
590 return to_string((
long long unsigned int)v.as<uint16_t>());
592 if (v.value().type()==
typeid(uint32_t))
593 return to_string((
long long unsigned int)v.as<uint32_t>());
595 if (v.value().type()==
typeid(uint64_t))
596 return to_string((
long long unsigned int)v.as<uint64_t>());
598 if (v.value().type()==
typeid(float))
599 return to_string((
long double)v.as<
float>());
601 if (v.value().type()==
typeid(double))
602 return to_string((
long double)v.as<
double>());
604 if (v.value().type()==
typeid(vector<string>))
605 return VecAsStr<string>(v);
607 if (v.value().type()==
typeid(vector<int16_t>))
608 return VecAsStr<int16_t>(v);
610 if (v.value().type()==
typeid(vector<int32_t>))
611 return VecAsStr<int32_t>(v);
613 if (v.value().type()==
typeid(vector<int64_t>))
614 return VecAsStr<int64_t>(v);
616 if (v.value().type()==
typeid(vector<uint16_t>))
617 return VecAsStr<uint16_t>(v);
619 if (v.value().type()==
typeid(vector<uint32_t>))
620 return VecAsStr<uint32_t>(v);
622 if (v.value().type()==
typeid(vector<uint64_t>))
623 return VecAsStr<uint64_t>(v);
625 if (v.value().type()==
typeid(vector<float>))
626 return VecAsStr<float>(v);
628 if (v.value().type()==
typeid(vector<double>))
629 return VecAsStr<double>(v);
632 str << hex << setfill(
'0') <<
"0x";
651 cout <<
"Options propagated to program:" << endl;
654 for (map<string,po::variable_value>::const_iterator m=
fVariables.begin();
656 Max(maxlen, m->first.length());
658 cout.setf(ios_base::left);
661 for (map<string,po::variable_value>::const_iterator m=
fVariables.begin();
664 const po::variable_value &v = m->second;
668 if (v.value().type()==
typeid(bool))
670 if (v.value().type()==
typeid(string))
672 if (v.value().type()==
typeid(int16_t))
674 if (v.value().type()==
typeid(int32_t))
676 if (v.value().type()==
typeid(int64_t))
678 if (v.value().type()==
typeid(uint16_t))
680 if (v.value().type()==
typeid(uint32_t))
682 if (v.value().type()==
typeid(uint64_t))
684 if (v.value().type()==
typeid(float))
686 if (v.value().type()==
typeid(double))
689 str <<
" Hex<uint16_t>";
691 str <<
" Hex<uint32_t>";
693 str <<
" Hex<uint64_t>";
694 if (v.value().type()==
typeid(vector<string>))
695 str <<
" vector<string>";
696 if (v.value().type()==
typeid(vector<int16_t>))
697 str <<
" vector<int16_t>";
698 if (v.value().type()==
typeid(vector<int32_t>))
699 str <<
" vector<int32_t>";
700 if (v.value().type()==
typeid(vector<int64_t>))
701 str <<
" vector<int64_t>";
702 if (v.value().type()==
typeid(vector<uint16_t>))
703 str <<
" vector<uint16_t>";
704 if (v.value().type()==
typeid(vector<uint32_t>))
705 str <<
" vector<uint32_t>";
706 if (v.value().type()==
typeid(vector<uint64_t>))
707 str <<
" vector<uint64_t>";
708 if (v.value().type()==
typeid(vector<float>))
709 str <<
" vector<float>";
710 if (v.value().type()==
typeid(vector<double>))
711 str <<
" vector<double>";
713 if (str.str().empty())
714 str <<
" unknown[" << v.value().type().name() <<
"]";
717 cout << setw(maxlen) << m->first;
720 cout << var <<
" #" << str.str();
723 cout <<
" [default]";
739 for (vector<string>::const_iterator v=vec.begin(); v<vec.end(); v+=steps)
740 cout <<
" " << *v << endl;
746 multimap<string,string> rc;
748 for (map<string,po::variable_value>::const_iterator m=
fVariables.begin();
750 rc.insert(make_pair(m->first,
VarAsStr(m->second)));
763 cout <<
"Unknown commandline options:" << endl;
769 cout <<
"Unknown options in configfile:" << endl;
775 cout <<
"Unknown environment variables:" << endl;
781 cout <<
"Unknown database entry:" << endl;
953 cout <<
"--0--" << endl;
956 po::options_description opt_commandline;
957 po::options_description opt_configfile;
958 po::options_description opt_environment;
959 po::options_description opt_database;
961 for (
int i=0;
i<2;
i++)
971 cout <<
"--1--" << endl;
980 cout <<
"--2--" << endl;
983 po::command_line_parser parser(argc, const_cast<char**>(argv));
984 parser.options(opt_commandline);
985 parser.positional(opt_positional);
986 parser.style(style::unix_style&~style::allow_guessing);
989 const po::parsed_options parsed_commandline = parser.run();
993 cout <<
"--3--" << endl;
996 po::variables_map getfiles;
997 po::store(parsed_commandline, getfiles);
999 if (getfiles.count(
"version"))
1001 if (getfiles.count(
"help"))
1006 "The following describes the available commandline options. " 1007 "For further details on how command line option are parsed " 1008 "and in which order which configuration sources are accessed " 1009 "please refer to the class reference of the Configuration class." << endl;
1012 if (getfiles.count(
"help-config"))
1014 if (getfiles.count(
"help-env"))
1016 if (getfiles.count(
"help-database"))
1023 cout <<
"--4--" << endl;
1026 if (getfiles.count(
"print") || getfiles.count(
"print-all"))
1028 cout << endl <<
"Parsed commandline options:" << endl;
1033 if (getfiles.count(
"help") || getfiles.count(
"help-config") ||
1034 getfiles.count(
"help-env") || getfiles.count(
"help-database"))
1042 cout <<
"--5--" << endl;
1045 const boost::filesystem::path path(
GetName());
1046 const string globalfile = (path.parent_path()/boost::filesystem::path(
"fact++.rc")).
string();
1048 cerr <<
"Reading global options from '" << globalfile <<
"'." << endl;
1050 ifstream gfile(globalfile.c_str());
1052 const po::parsed_options parsed_globalfile =
1054 po::parsed_options(&opt_configfile) :
1055 po::parse_config_file<char>(gfile, opt_configfile,
true);
1059 cout <<
"--6--" << endl;
1063 if (getfiles.count(
"default"))
1066 cerr <<
"Reading default options from '" <<
fDefaultFile <<
"'." << endl;
1069 const bool checkf = !getfiles.count(
"dont-check-files") && !getfiles.count(
"dont-check");
1070 const bool defaulted = getfiles.count(
"default") && getfiles[
"default"].defaulted();
1075 const po::parsed_options parsed_defaultfile =
1076 !indef && defaulted ?
1077 po::parsed_options(&opt_configfile) :
1078 po::parse_config_file<char>(indef, opt_configfile, !checkf);
1082 cout <<
"--7--" << endl;
1085 if (getfiles.count(
"print-default") || getfiles.count(
"print-all"))
1087 if (!indef.is_open() && defaulted)
1088 cout <<
"No configuration file by --default option specified." << endl;
1091 cout << endl <<
"Parsed options from '" <<
fDefaultFile <<
"':" << endl;
1097 po::store(parsed_defaultfile, getfiles);
1101 cout <<
"--8--" << endl;
1105 if (getfiles.count(
"config"))
1108 cerr <<
"Reading config options from '" <<
fPriorityFile <<
"'." << endl;
1113 const po::parsed_options parsed_priorityfile =
1114 fPriorityFile.empty() ? po::parsed_options(&opt_configfile) :
1115 po::parse_config_file<char>(inpri, opt_configfile, !checkf);
1119 cout <<
"--9--" << endl;
1122 if (getfiles.count(
"print-config") || getfiles.count(
"print-all"))
1125 cout <<
"No configuration file by --config option specified." << endl;
1128 cout << endl <<
"Parsed options from '" <<
fPriorityFile <<
"':" << endl;
1136 cout <<
"--10--" << endl;
1139 po::variables_map getdatabase;
1140 po::store(parsed_commandline, getdatabase);
1141 po::store(parsed_priorityfile, getdatabase);
1142 po::store(parsed_defaultfile, getdatabase);
1143 po::store(parsed_globalfile, getdatabase);
1145 if (getdatabase.count(
"database") && !getdatabase.count(
"no-database"))
1147 fDatabase = getdatabase[
"database"].as<
string>();
1148 cerr <<
"Requesting options from database for '" <<
fName <<
"'" << endl;
1151 const bool checkdb = !getdatabase.count(
"dont-check-database") && !getdatabase.count(
"dont-check");
1153 const po::parsed_options parsed_database =
1154 fDatabase.empty() ? po::parsed_options(&opt_database) :
1155 #if BOOST_VERSION < 104600 1162 cout <<
"--11--" << endl;
1165 if (getfiles.count(
"print-database") || getfiles.count(
"print-all"))
1168 cout <<
"No database access requested." << endl;
1171 cout << endl <<
"Options received from '" <<
fDatabase <<
"':" << endl;
1179 cout <<
"--12--" << endl;
1182 const po::parsed_options parsed_environment = po::parse_environment(opt_environment,
fNameMapper);
1186 cout <<
"--13--" << endl;
1189 if (getfiles.count(
"print-environment"))
1191 cout <<
"Parsed options from environment:" << endl;
1198 cout <<
"--14--" << endl;
1201 po::variables_map result;
1202 po::store(parsed_commandline, result);
1203 po::store(parsed_priorityfile, result);
1204 po::store(parsed_database, result);
1205 po::store(parsed_defaultfile, result);
1206 po::store(parsed_globalfile, result);
1207 po::store(parsed_environment, result);
1214 cout <<
"--15--" << endl;
1217 const vector<string> unknown0 = collect_unrecognized(parsed_globalfile.options, po::exclude_positional);
1218 const vector<string> unknown1 = collect_unrecognized(parsed_defaultfile.options, po::exclude_positional);
1219 const vector<string> unknown2 = collect_unrecognized(parsed_priorityfile.options, po::exclude_positional);
1226 fUnknownCommandline = collect_unrecognized(parsed_commandline.options, po::exclude_positional);
1227 fUnknownEnvironment = collect_unrecognized(parsed_environment.options, po::exclude_positional);
1228 fUnknownDatabase = collect_unrecognized(parsed_database.options, po::exclude_positional);
1232 cout <<
"--16--" << endl;
1239 cout <<
"--17--" << endl;
1242 if (result.count(
"print-options"))
1245 if (result.count(
"print-wildcards"))
1248 if (result.count(
"print-unknown"))
1252 cout <<
"------" << endl;
1264 #if BOOST_VERSION > 104000 1265 catch (po::multiple_occurrences &e)
1267 cerr <<
"Program options invalid due to: " << e.what() <<
" of '" << e.get_option_name() <<
"'." << endl;
1271 catch (exception& e)
1273 cerr <<
"Program options invalid due to: " << e.what() << endl;
1286 po::options_description opts;
1288 for (
int i=0;
i<2;
i++)
1298 typedef map<string,po::variable_value> Vars;
1299 typedef vector<boost::shared_ptr<po::option_description>> Descs;
1301 const Descs &desc = opts.options();
1305 for (Descs::const_iterator
id=desc.begin();
id!=desc.end();
id++)
1306 #
if BOOST_VERSION > 104000
1307 if ((*id)->match(io->first,
false,
false,
false)==po::option_description::approximate_match)
1309 if ((*id)->match(io->first,
false)==po::option_description::approximate_match)
1322 cout <<
"Options registered with wildcards and not yet accessed:" << endl;
1326 if (it->second.length()>max)
1327 max = it->second.length();
1329 cout.setf(ios_base::left);
1331 cout << setw(max+1) << it->second <<
" : " << it->first <<endl;
1340 if (it->second == opt)
1341 rc.push_back(it->first);
1358 const boost::filesystem::path path(src);
1360 string pname = path.parent_path().string();
1361 #if BOOST_VERSION < 104600 1362 string fname = path.filename();
1364 string fname = path.filename().string();
1368 if (fname.substr(0, 3)==
"lt-")
1369 fname = fname.substr(3);
1374 pname = boost::filesystem::current_path().string();
1382 if (pname.length()>=6)
1385 const size_t pos = pname.length()-6;
1386 if (pname.substr(pos)==
"/.libs")
1387 pname = pname.substr(0, pos);
1391 if (pname==boost::filesystem::current_path().
string())
1394 return pname+
'/'+fname;
1437 #ifndef PACKAGE_STRING 1438 #define PACKAGE_STRING "" 1442 #define PACKAGE_URL "" 1445 #ifndef PACKAGE_BUGREPORT 1446 #define PACKAGE_BUGREPORT "" 1455 #if BOOST_VERSION < 104600 1456 const std::string n = boost::filesystem::path(
fName).filename();
1458 const std::string n = boost::filesystem::path(
fName).filename().string();
1467 cout <<
" - " << name;
1470 "Written by Thomas Bretz et al.\n" 1473 cout <<
"Report bugs to <" << bugs <<
">\n";
1475 cout <<
"Home page: " << url <<
"\n";
1478 "Copyright (C) 2011 by the FACT Collaboration.\n" 1479 "This is free software; see the source for copying conditions.\n" #define PACKAGE_BUGREPORT
void PrintWildcardOptions() const
void AddOptionsEnvironment(const po::options_description &env, bool visible=true)
std::string fDatabase
File name of the default configuration file (usually {program}.rc)
std::string fPriorityFile
Options which were registered using wildcards.
Configuration(const std::string &prgname="")
std::string VecAsStr(const po::variable_value &v) const
std::vector< std::string > fUnknownDatabase
Storage container for unrecognized options from the environment.
void AddOptionsConfigfile(const po::options_description &cf, bool visible=true)
po::options_description fOptionsEnvironment[2]
Description of options from the database.
po::typed_value< T > * var(T *ptr=0)
void CreateWildcardOptions()
Helper for Parse to create list of used wildcard options.
void SetArgumentPositions(const po::positional_options_description &desc)
std::function< std::string(std::string)> fNameMapper
Pointer to the mapper function for environment variables.
Index for options visible in PrintParsed.
po::positional_options_description fArgumentPositions
Description of options from the environment.
std::multimap< std::string, std::string > GetOptions() const
po::options_description fOptionsDatabase[2]
Description of the options in the configuration file.
void PrintParsed(const po::parsed_options &parsed) const
Print all options from a list of already parsed options.
void AddOptionsDatabase(const po::options_description &db, bool visible=true)
std::function< void(const std::string &)> fPrintVersion
void PrintUnknown() const
void PrintOptions() const
std::string fDefaultFile
File name of the priority configuration file (overwrites option from the databse) ...
void AddOptionsCommandline(const po::options_description &cl, bool visible=true)
po::options_description fOptionsCommandline[2]
Commandline parsing, resource file parsing and database access.
std::map< std::string, std::string > fWildcardOptions
Storage container for unrecognized options retrieved from the database.
po::options_description fOptionsConfigfile[2]
Description of the command-line options.
std::vector< std::string > fUnknownCommandline
Description of positional command-line options (arguments)
std::function< void()> fPrintUsage
std::string VarAsStr(const po::variable_value &v) const
static po::basic_parsed_options< char > parse_database(const std::string &prgname, const std::string &database, const po::options_description &desc, bool allow_unregistered=false)
Retrieve data from a database and return them as options.
static void Max(int &val, const int &comp)
Helper function which return the max of the two arguments in the first argument.
const std::map< std::string, std::string > & GetWildcardOptions() const
po::variables_map fVariables
URL for database connection (see Configuration::parse_database)
std::string DefaultMapper(const std::string env)
Variables as compiled by the Parse-function, which will be passed to the program. ...
virtual void PrintVersion() const
std::string UnLibToolize(const std::string &src) const
const po::variables_map & Parse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
virtual void PrintUsage() const
std::vector< std::string > fUnknownConfigfile
Storage container for unrecognized commandline options.
std::vector< std::string > fUnknownEnvironment
Storage container for unrecognized options from configuration files.
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
const std::string & GetName() const