FACT++  1.0
const po::variables_map & Configuration::Parse ( int  argc,
const char **  argv,
const std::function< void()> &  PrintHelp = std::function<void()>() 
)

The idea of the Parse() memeber-function is to parse the command-line, the configuration files, the databse and the environment and return a proper combined result.

In details the following actions are performed in the given order:

  • (0) Init local variables with the list of options described by the data members.
  • (1) Reset the data members fPriorityFile, fDefaultFile, fDatabase
  • (2) Parse the command line
  • (3) Check for –help* command-line options and performe corresponding action
  • (4) Check for –print and –print-all and perform corresponding action
  • (5) Read and parse the global configuration file, which is compiled from the path corresponding to the argument given in the constructor + "/fact++.rc", unrecognized options are always allowed. Note that in contradiction to all other options the options in this file are not checked at all. Hence, typos might stay unnoticed.
  • (6) Read and parse the default configuration file, which is either given by the default name or the –default command-line option. The default name is compiled from the argument given to the constructor and ".rc". If the file-name is identical to the default (no command-line option given) a missing configuration file is no error. Depending on the –dont-check and –dont-check-files options, unrecognized options in the file throw an exception or not.
  • (7) Check for –print-default and –print-all and perform corresponding action
  • (8) Read and parse the priority configuration file, which must be given by the –config or -C command-line option or a corresponding entry in the default-configuration file. If an option on the command-line and the in the configuration file exists, the command-line option has priority. If none is given, no priority file is read. Depending on the –dont-check and –dont-check-files options, unrecognized options in the file throw an exception or not.
  • (9) Check for –print-config and –print-all and perform corresponding action
  • (10) Retrieve options from the database according to the options –database and –no-database. Note that options given on the command-line have highest priority. The second priority is the priority-configuration file. The options from the default configuration-file have lowest priority.
  • (11) Check for –print-database and –print-all and perform corresponding action
  • (12) Parse the environment options.
  • (13) Check for –print-environment and –print-all and perform corresponding action
  • (14) Compile the final result. The priority of the options is (in decreasing order): command-line options, options from the priority configuration file, options from the database, options from the default configuration-file and options from the environment.
  • (15) Find all options which were found and flagged as unrecognized, because they are not in the user-defined list of described options, are collected and stored in the corresponding data-members.
  • (16) Find all options which where registered with wildcards and store the list in fWildcardOptions.
  • (17) Before the function returns it check for –print-options and –print-unknown and performs the corresponding actions.
Parameters
argc,argvarguments passed to main(int argc, char **argv)
Returns
A reference to the list with the resulting options with their values.
Todo:
  • describe the exceptions
  • describe what happens in a more general way
  • print a waring when no default coonfig file is read
  • proper handling and error messages if files not available
Examples:
argv.cc.

Definition at line 947 of file Configuration.cc.

References CreateWildcardOptions(), fArgumentPositions, fDatabase, fDefaultFile, fName, fNameMapper, fOptionsCommandline, fOptionsConfigfile, fOptionsDatabase, fOptionsEnvironment, fPrintUsage, fPriorityFile, fUnknownCommandline, fUnknownConfigfile, fUnknownDatabase, fUnknownEnvironment, fVariables, GetName(), i, kVisible, parse_database(), PrintHelp(), PrintOptions(), PrintParsed(), PrintUnknown(), PrintVersion(), and PrintWildcardOptions().

Referenced by DoParse(), GetOptions(), and main().

948 {
949  const po::positional_options_description &opt_positional = fArgumentPositions;
950 
951  // ------------------------ (0) --------------------------
952 #ifdef DEBUG
953  cout << "--0--" << endl;
954 #endif
955 
956  po::options_description opt_commandline;
957  po::options_description opt_configfile;
958  po::options_description opt_environment;
959  po::options_description opt_database;
960 
961  for (int i=0; i<2; i++)
962  {
963  opt_commandline.add(fOptionsCommandline[i]);
964  opt_configfile.add(fOptionsConfigfile[i]);
965  opt_environment.add(fOptionsEnvironment[i]);
966  opt_database.add(fOptionsDatabase[i]);
967  }
968 
969  // ------------------------ (1) --------------------------
970 #ifdef DEBUG
971  cout << "--1--" << endl;
972 #endif
973 
974  fPriorityFile = "";
975  fDefaultFile = "";
976  fDatabase = "";
977 
978  // ------------------------ (2) --------------------------
979 #ifdef DEBUG
980  cout << "--2--" << endl;
981 #endif
982 
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);
987  //parser.allow_unregistered();
988 
989  const po::parsed_options parsed_commandline = parser.run();
990 
991  // ------------------------ (3) --------------------------
992 #ifdef DEBUG
993  cout << "--3--" << endl;
994 #endif
995 
996  po::variables_map getfiles;
997  po::store(parsed_commandline, getfiles);
998 
999  if (getfiles.count("version"))
1000  PrintVersion();
1001  if (getfiles.count("help"))
1002  {
1003  fPrintUsage();
1004  cout <<
1005  "Options:\n"
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;
1010  cout << fOptionsCommandline[kVisible] << endl;
1011  }
1012  if (getfiles.count("help-config"))
1013  cout << fOptionsConfigfile[kVisible] << endl;
1014  if (getfiles.count("help-env"))
1015  cout << fOptionsEnvironment[kVisible] << endl;
1016  if (getfiles.count("help-database"))
1017  cout << fOptionsDatabase[kVisible] << endl;
1018 
1019 
1020 
1021  // ------------------------ (4) --------------------------
1022 #ifdef DEBUG
1023  cout << "--4--" << endl;
1024 #endif
1025 
1026  if (getfiles.count("print") || getfiles.count("print-all"))
1027  {
1028  cout << endl << "Parsed commandline options:" << endl;
1029  PrintParsed(parsed_commandline);
1030  cout << endl;
1031  }
1032 
1033  if (getfiles.count("help") || getfiles.count("help-config") ||
1034  getfiles.count("help-env") || getfiles.count("help-database"))
1035  {
1036  if (PrintHelp)
1037  PrintHelp();
1038  }
1039 
1040  // ------------------------ (5) --------------------------
1041 #ifdef DEBUG
1042  cout << "--5--" << endl;
1043 #endif
1044 
1045  const boost::filesystem::path path(GetName());
1046  const string globalfile = (path.parent_path()/boost::filesystem::path("fact++.rc")).string();
1047 
1048  cerr << "Reading global options from '" << globalfile << "'." << endl;
1049 
1050  ifstream gfile(globalfile.c_str());
1051  // ===> FIXME: Proper handling of missing file or wrong file name
1052  const po::parsed_options parsed_globalfile =
1053  !gfile ?
1054  po::parsed_options(&opt_configfile) :
1055  po::parse_config_file<char>(gfile, opt_configfile, true);
1056 
1057  // ------------------------ (6) --------------------------
1058 #ifdef DEBUG
1059  cout << "--6--" << endl;
1060 #endif
1061 
1062  // Get default file from command line
1063  if (getfiles.count("default"))
1064  {
1065  fDefaultFile = getfiles["default"].as<string>();
1066  cerr << "Reading default options from '" << fDefaultFile << "'." << endl;
1067  }
1068 
1069  const bool checkf = !getfiles.count("dont-check-files") && !getfiles.count("dont-check");
1070  const bool defaulted = getfiles.count("default") && getfiles["default"].defaulted();
1071  //const bool exists = boost::filesystem::exists(fDefaultFile);
1072 
1073  ifstream indef(fDefaultFile.c_str());
1074  // ===> FIXME: Proper handling of missing file or wrong file name
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);
1079 
1080  // ------------------------ (7) --------------------------
1081 #ifdef DEBUG
1082  cout << "--7--" << endl;
1083 #endif
1084 
1085  if (getfiles.count("print-default") || getfiles.count("print-all"))
1086  {
1087  if (!indef.is_open() && defaulted)
1088  cout << "No configuration file by --default option specified." << endl;
1089  else
1090  {
1091  cout << endl << "Parsed options from '" << fDefaultFile << "':" << endl;
1092  PrintParsed(parsed_defaultfile);
1093  cout << endl;
1094  }
1095  }
1096 
1097  po::store(parsed_defaultfile, getfiles);
1098 
1099  // ------------------------ (8) --------------------------
1100 #ifdef DEBUG
1101  cout << "--8--" << endl;
1102 #endif
1103 
1104  // Get priority from commandline(1), defaultfile(2)
1105  if (getfiles.count("config"))
1106  {
1107  fPriorityFile = getfiles["config"].as<string>();
1108  cerr << "Reading config options from '" << fPriorityFile << "'." << endl;
1109  }
1110 
1111  ifstream inpri(fPriorityFile.c_str());
1112  // ===> FIXME: Proper handling of missing file or wrong file name
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);
1116 
1117  // ------------------------ (9) --------------------------
1118 #ifdef DEBUG
1119  cout << "--9--" << endl;
1120 #endif
1121 
1122  if (getfiles.count("print-config") || getfiles.count("print-all"))
1123  {
1124  if (fPriorityFile.empty())
1125  cout << "No configuration file by --config option specified." << endl;
1126  else
1127  {
1128  cout << endl << "Parsed options from '" << fPriorityFile << "':" << endl;
1129  PrintParsed(parsed_priorityfile);
1130  cout << endl;
1131  }
1132  }
1133 
1134  // ------------------------ (10) -------------------------
1135 #ifdef DEBUG
1136  cout << "--10--" << endl;
1137 #endif
1138 
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);
1144 
1145  if (getdatabase.count("database") && !getdatabase.count("no-database"))
1146  {
1147  fDatabase = getdatabase["database"].as<string>();
1148  cerr << "Requesting options from database for '" << fName << "'" << endl;
1149  }
1150 
1151  const bool checkdb = !getdatabase.count("dont-check-database") && !getdatabase.count("dont-check");
1152 
1153  const po::parsed_options parsed_database =
1154  fDatabase.empty() ? po::parsed_options(&opt_database) :
1155 #if BOOST_VERSION < 104600
1156  parse_database(path.filename(), fDatabase, opt_database, !checkdb);
1157 #else
1158  parse_database(path.filename().string(), fDatabase, opt_database, !checkdb);
1159 #endif
1160  // ------------------------ (11) -------------------------
1161 #ifdef DEBUG
1162  cout << "--11--" << endl;
1163 #endif
1164 
1165  if (getfiles.count("print-database") || getfiles.count("print-all"))
1166  {
1167  if (fDatabase.empty())
1168  cout << "No database access requested." << endl;
1169  else
1170  {
1171  cout << endl << "Options received from '" << fDatabase << "':" << endl;
1172  PrintParsed(parsed_database);
1173  cout << endl;
1174  }
1175  }
1176 
1177  // ------------------------ (12) -------------------------
1178 #ifdef DEBUG
1179  cout << "--12--" << endl;
1180 #endif
1181 
1182  const po::parsed_options parsed_environment = po::parse_environment(opt_environment, fNameMapper);
1183 
1184  // ------------------------ (13) -------------------------
1185 #ifdef DEBUG
1186  cout << "--13--" << endl;
1187 #endif
1188 
1189  if (getfiles.count("print-environment"))
1190  {
1191  cout << "Parsed options from environment:" << endl;
1192  PrintParsed(parsed_environment);
1193  cout << endl;
1194  }
1195 
1196  // ------------------------ (14) -------------------------
1197 #ifdef DEBUG
1198  cout << "--14--" << endl;
1199 #endif
1200 
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);
1208  po::notify(result);
1209 
1210  fVariables = result;
1211 
1212  // ------------------------ (15) -------------------------
1213 #ifdef DEBUG
1214  cout << "--15--" << endl;
1215 #endif
1216 
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);
1220 
1221  fUnknownConfigfile.clear();
1222  fUnknownConfigfile.insert(fUnknownConfigfile.end(), unknown0.begin(), unknown0.end());
1223  fUnknownConfigfile.insert(fUnknownConfigfile.end(), unknown1.begin(), unknown1.end());
1224  fUnknownConfigfile.insert(fUnknownConfigfile.end(), unknown2.begin(), unknown2.end());
1225 
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);
1229 
1230  // ------------------------ (16) -------------------------
1231 #ifdef DEBUG
1232  cout << "--16--" << endl;
1233 #endif
1234 
1236 
1237  // ------------------------ (17) -------------------------
1238 #ifdef DEBUG
1239  cout << "--17--" << endl;
1240 #endif
1241 
1242  if (result.count("print-options"))
1243  PrintOptions();
1244 
1245  if (result.count("print-wildcards"))
1247 
1248  if (result.count("print-unknown"))
1249  PrintUnknown();
1250 
1251 #ifdef DEBUG
1252  cout << "------" << endl;
1253 #endif
1254 
1255  return fVariables;
1256 }
void PrintWildcardOptions() const
std::string fDatabase
File name of the default configuration file (usually {program}.rc)
Definition: Configuration.h:39
std::string fPriorityFile
Options which were registered using wildcards.
Definition: Configuration.h:37
int i
Definition: db_dim_client.c:21
std::vector< std::string > fUnknownDatabase
Storage container for unrecognized options from the environment.
Definition: Configuration.h:33
po::options_description fOptionsEnvironment[2]
Description of options from the database.
Definition: Configuration.h:26
void CreateWildcardOptions()
Helper for Parse to create list of used wildcard options.
void PrintHelp()
Definition: fact.cc:30
std::function< std::string(std::string)> fNameMapper
Pointer to the mapper function for environment variables.
Definition: Configuration.h:50
Index for options visible in PrintParsed.
Definition: Configuration.h:16
po::positional_options_description fArgumentPositions
Description of options from the environment.
Definition: Configuration.h:28
po::options_description fOptionsDatabase[2]
Description of the options in the configuration file.
Definition: Configuration.h:25
void PrintParsed(const po::parsed_options &parsed) const
Print all options from a list of already parsed options.
void PrintUnknown() const
void PrintOptions() const
std::string fDefaultFile
File name of the priority configuration file (overwrites option from the databse) ...
Definition: Configuration.h:38
po::options_description fOptionsCommandline[2]
Definition: Configuration.h:23
const std::string fName
Definition: Configuration.h:19
po::options_description fOptionsConfigfile[2]
Description of the command-line options.
Definition: Configuration.h:24
std::vector< std::string > fUnknownCommandline
Description of positional command-line options (arguments)
Definition: Configuration.h:30
std::function< void()> fPrintUsage
Definition: Configuration.h:51
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.
if(extraDns) new Dns
po::variables_map fVariables
URL for database connection (see Configuration::parse_database)
Definition: Configuration.h:41
virtual void PrintVersion() const
std::vector< std::string > fUnknownConfigfile
Storage container for unrecognized commandline options.
Definition: Configuration.h:31
std::vector< std::string > fUnknownEnvironment
Storage container for unrecognized options from configuration files.
Definition: Configuration.h:32
const std::string & GetName() const

+ Here is the call graph for this function:

+ Here is the caller graph for this function: