CMS 3D CMS Logo

CmsRunParser.cc
Go to the documentation of this file.
4 
5 #include <vector>
6 #include <string>
7 #include <iostream>
8 
9 namespace {
10  //additional_parser is documented at https://www.boost.org/doc/libs/1_83_0/doc/html/program_options/howto.html#id-1.3.30.6.3
11  //extra_style_parser was added in https://www.boost.org/users/history/version_1_33_0.html
12  //it allows performing a fully custom processing on whatever arguments have not yet been processed
13  //the function is responsible for removing processed arguments from the input vector
14  //and assembling the return value, which is a vector of boost's option type
15  //some usage examples: https://stackoverflow.com/a/5481228, https://stackoverflow.com/a/37993517
16  //internally, when cmdline::run() is called, the function given to extra_style_parser is added to the beginning of list of parsers
17  //all parsers are called in order until args is empty (validity of non-empty output is checked after each parser)
18  std::vector<boost::program_options::option> final_opts_parser(std::vector<std::string>& args) {
19  std::vector<boost::program_options::option> result;
20  std::string configName;
21  if (!args.empty() and !args[0].empty()) {
22  if (args[0][0] != '-') { // name is first positional arg -> doesn't start with '-'
23  configName = args[0];
24  args.erase(args.begin());
25  } else if (args[0] == "--" and args.size() > 1) { // name can start with '-' if separator comes first
26  configName = args[1];
27  args.erase(args.begin(), args.begin() + 2);
28  }
29  }
30  if (!configName.empty()) {
31  result.emplace_back(edm::CmsRunParser::kParameterSetOpt, std::vector<std::string>(1, configName));
32  result.emplace_back();
33  auto& pythonOpts = result.back();
34  pythonOpts.string_key = edm::CmsRunParser::kPythonOpt;
35  pythonOpts.value.reserve(args.size());
36  pythonOpts.original_tokens.reserve(args.size());
37  for (const auto& arg : args) {
38  pythonOpts.value.push_back(arg);
39  pythonOpts.original_tokens.push_back(arg);
40  }
41  //default value to avoid "is missing" error
42  if (pythonOpts.value.empty()) {
43  pythonOpts.value.push_back(edm::CmsRunParser::kPythonOptDefault);
44  pythonOpts.original_tokens.push_back("");
45  }
46  args.clear();
47  }
48  return result;
49  }
50 } // namespace
51 
52 namespace edm {
54  : desc_(std::string(name) + " [options] [--] config_file [python options]\nAllowed options"),
55  all_options_("All Options") {
56  // clang-format off
57  desc_.add_options()(kHelpCommandOpt, "produce help message")(
59  boost::program_options::value<std::string>(),
60  "file name to use for a job report file: default extension is .xml")(
61  kEnableJobreportCommandOpt, "enable job report files (if any) specified in configuration file")(
63  boost::program_options::value<std::string>(),
64  "Job Mode for MessageLogger defaults - default mode is grid")(
66  boost::program_options::value<unsigned int>(),
67  "Number of threads to use in job (0 is use all CPUs)")(
69  boost::program_options::value<unsigned int>(),
70  "Size of stack in KB to use for extra threads (0 is use system default size)")(kStrictOpt, "strict parsing")(
71  kCmdCommandOpt, boost::program_options::value<std::string>(), "config passed in as string (cannot be used with config_file)");
72  // clang-format on
73 
74  // anything at the end will be ignored, and sent to python
75  pos_options_.add(kParameterSetOpt, 1).add(kPythonOpt, -1);
76 
77  // This --fwk option is not used anymore, but I'm leaving it around as
78  // it might be useful again in the future for code development
79  // purposes. We originally used it when implementing the boost
80  // state machine code.
81  boost::program_options::options_description hidden("hidden options");
82  hidden.add_options()("fwk", "For use only by Framework Developers")(
83  kParameterSetOpt, boost::program_options::value<std::string>(), "configuration file")(
84  kPythonOpt,
85  boost::program_options::value<std::vector<std::string>>(),
86  "options at the end to be passed to python");
87 
88  all_options_.add(desc_).add(hidden);
89  }
91  boost::program_options::variables_map vm;
92  try {
93  store(boost::program_options::command_line_parser(argc, argv)
94  .extra_style_parser(final_opts_parser)
96  .positional(pos_options_)
97  .run(),
98  vm);
99  notify(vm);
100  } catch (boost::program_options::error const& iException) {
101  edm::LogAbsolute("CommandLineProcessing")
102  << "cmsRun: Error while trying to process command line arguments:\n"
103  << iException.what() << "\nFor usage and an options list, please do 'cmsRun --help'.";
105  }
106 
107  if (vm.count(kHelpOpt)) {
108  std::cout << desc_ << std::endl;
110  return MapOrExit(0);
111  }
112 
113  //special handling of python options
114  if (vm.count(kPythonOpt)) {
115  const auto& pythonOptValues = vm[kPythonOpt].as<std::vector<std::string>>();
116  //omit default arg
117  if (pythonOptValues.size() == 1 and pythonOptValues[0] == kPythonOptDefault)
118  vm.erase(kPythonOpt);
119  }
120 
121  return MapOrExit(vm);
122  }
123 } // namespace edm
static const char *const kEnableJobreportCommandOpt
Definition: CmsRunParser.h:38
boost::program_options::options_description desc_
Definition: CmsRunParser.h:25
static const char *const kJobModeCommandOpt
Definition: CmsRunParser.h:40
static const char *const kStrictOpt
Definition: CmsRunParser.h:48
void HaltMessageLogging()
A arg
Definition: Factorize.h:31
boost::program_options::positional_options_description pos_options_
Definition: CmsRunParser.h:27
static const char *const kHelpOpt
Definition: CmsRunParser.h:46
static const char *const kParameterSetOpt
Definition: CmsRunParser.h:31
static const char *const kHelpCommandOpt
Definition: CmsRunParser.h:47
std::variant< boost::program_options::variables_map, int > MapOrExit
Definition: CmsRunParser.h:11
static const char *const kCmdCommandOpt
Definition: CmsRunParser.h:34
static const char *const kSizeOfStackForThreadCommandOpt
Definition: CmsRunParser.h:44
CmsRunParser(const char *name)
Definition: CmsRunParser.cc:53
boost::program_options::options_description all_options_
Definition: CmsRunParser.h:26
static const char *const kPythonOpt
Definition: CmsRunParser.h:32
HLT enums.
static const char *const kJobreportCommandOpt
Definition: CmsRunParser.h:36
Log< level::System, true > LogAbsolute
static const char *const kPythonOptDefault
Definition: CmsRunParser.h:33
static const char *const kNumberOfThreadsCommandOpt
Definition: CmsRunParser.h:42
MapOrExit parse(int argc, const char *argv[]) const
Definition: CmsRunParser.cc:90