https://mooseframework.inl.gov
Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
CommandLine Class Reference

This class wraps provides and tracks access to command line parameters. More...

#include <CommandLine.h>

Classes

struct  CommandLineParam
 Stores information pertaining to a command line InputParameter. More...
 
struct  Entry
 Stores name/value pairs for each command line argument. More...
 

Public Types

using ArgumentType = InputParameters::CommandLineMetadata::ArgumentType
 

Public Member Functions

 CommandLine ()
 
 CommandLine (int argc, char *argv[])
 
 CommandLine (const std::vector< std::string > &args)
 
virtual ~CommandLine ()
 
void addArguments (int argc, char *argv[])
 Adds arguments from raw argc and argv. More...
 
void addArgument (const std::string &arg)
 Adds a single argument. More...
 
void addArguments (const std::vector< std::string > &args)
 Adds arguments from a vector. More...
 
bool hasArgument (const std::string &arg) const
 
void removeArgument (const std::string &arg)
 Removes an argument that must exist. More...
 
void parse ()
 Performs the parsing, which is the combining of arguments into [name, value] pairs. More...
 
bool hasParsed () const
 
std::unique_ptr< CommandLineinitSubAppCommandLine (const std::string &multiapp_name, const std::string &subapp_name, const std::vector< std::string > &input_cli_args)
 Initializes a new CommandLine for a subapp with a MultiApp named multiapp_name and a subapp named subapp_name. More...
 
std::string buildHitParams ()
 
const std::vector< std::string > & getArguments ()
 
void populateCommandLineParams (InputParameters &params)
 Populates the command line input parameters from params. More...
 
auto begin () const
 
auto end () const
 
const std::list< Entry > & getEntries () const
 
std::string getExecutableName () const
 
std::string getExecutableNameBase () const
 
void printUsage () const
 Print the usage info for this command line. More...
 
std::vector< std::string > unusedHitParams (const Parallel::Communicator &comm) const
 Returns the HIT command line arguments that are not used. More...
 
std::list< Entry >::const_iterator findCommandLineParam (const std::string &name) const
 
std::string formatEntry (const Entry &entry) const
 
template<typename T >
void setCommandLineParam (std::list< CommandLine::Entry >::iterator entry_it, const CommandLineParam &param, const std::string &cli_switch, T &value)
 

Private Member Functions

std::list< Entry > & getEntries ()
 
template<typename T >
void setCommandLineParam (std::list< Entry >::iterator entry_it, const CommandLineParam &param, const std::string &cli_switch, T &value)
 Sets an InputParameters command line option at value. More...
 
std::list< Entry >::iterator findCommandLineParam (const std::string &name)
 

Private Attributes

std::vector< std::string > _argv
 Storage for the raw argv. More...
 
std::list< Entry_entries
 The parsed command line entries (arguments split into name value pairs) This is a list because it is necessary to combine Entry objects later on. More...
 
std::map< std::string, CommandLineParam_command_line_params
 The command line parameters, added by populateCommandLineParams() More...
 
bool _has_parsed = false
 Whether or not the Parser has parsed yet. More...
 
bool _command_line_params_populated = false
 Whether or not command line parameters have been populated. More...
 

Detailed Description

This class wraps provides and tracks access to command line parameters.

Definition at line 29 of file CommandLine.h.

Member Typedef Documentation

◆ ArgumentType

Definition at line 32 of file CommandLine.h.

Constructor & Destructor Documentation

◆ CommandLine() [1/3]

CommandLine::CommandLine ( )

Definition at line 27 of file CommandLine.C.

27 {}

◆ CommandLine() [2/3]

CommandLine::CommandLine ( int  argc,
char *  argv[] 
)

Definition at line 28 of file CommandLine.C.

28 { addArguments(argc, argv); }
void addArguments(int argc, char *argv[])
Adds arguments from raw argc and argv.
Definition: CommandLine.C:32

◆ CommandLine() [3/3]

CommandLine::CommandLine ( const std::vector< std::string > &  args)

Definition at line 29 of file CommandLine.C.

29 { addArguments(args); }
void addArguments(int argc, char *argv[])
Adds arguments from raw argc and argv.
Definition: CommandLine.C:32

◆ ~CommandLine()

CommandLine::~CommandLine ( )
virtual

Definition at line 199 of file CommandLine.C.

199 {}

Member Function Documentation

◆ addArgument()

void CommandLine::addArgument ( const std::string &  arg)

Adds a single argument.

Definition at line 39 of file CommandLine.C.

Referenced by addArguments().

40 {
41  mooseAssert(!hasParsed(), "Has already parsed");
42  _argv.push_back(arg);
43 }
std::vector< std::string > _argv
Storage for the raw argv.
Definition: CommandLine.h:223
bool hasParsed() const
Definition: CommandLine.h:105

◆ addArguments() [1/2]

void CommandLine::addArguments ( int  argc,
char *  argv[] 
)

Adds arguments from raw argc and argv.

Definition at line 32 of file CommandLine.C.

Referenced by CommandLine().

33 {
34  for (int i = 0; i < argc; i++)
35  addArgument(argv[i]);
36 }
void addArgument(const std::string &arg)
Adds a single argument.
Definition: CommandLine.C:39

◆ addArguments() [2/2]

void CommandLine::addArguments ( const std::vector< std::string > &  args)

Adds arguments from a vector.

Definition at line 46 of file CommandLine.C.

47 {
48  for (const auto & arg : args)
49  addArgument(arg);
50 }
void addArgument(const std::string &arg)
Adds a single argument.
Definition: CommandLine.C:39

◆ begin()

auto CommandLine::begin ( ) const
inline
Returns
An iterator to the beginning of the options

Definition at line 145 of file CommandLine.h.

Referenced by initSubAppCommandLine(), and parse().

145 { return _entries.begin(); }
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227

◆ buildHitParams()

std::string CommandLine::buildHitParams ( )
Returns
The parsed HIT command line parameters per the command line arguments.

This will also mark all found HIT parameters as used.

Definition at line 240 of file CommandLine.C.

241 {
242  mooseAssert(_command_line_params_populated, "Must populate command line params first");
243 
244  std::vector<std::string> params;
245 
246  // Collect all hit parameters that aren't for subapps
247  for (auto & entry : getEntries())
248  if (entry.hit_param && !entry.subapp_name)
249  {
250  mooseAssert(entry.value, "Should have a value");
251  mooseAssert(entry.value_separator, "Should have value separator");
252  mooseAssert(*entry.value_separator == "=", "Should be an equals");
253 
254  const std::string name_and_equals = entry.name + *entry.value_separator;
255  std::string arg = name_and_equals;
256  // In the case of empty values, we want them to be empty to hit
257  if (entry.value->empty())
258  arg += "''";
259  else
260  arg += *entry.value;
261 
262  // We could have issues with bash eating strings, so the first try
263  // gives us a chance to wrap the value in quotes
264  try
265  {
266  hit::check("CLI_ARG", arg);
267  }
268  catch (hit::ParseError & err)
269  {
270  // bash might have eaten quotes around a hit string value or vector
271  // so try quoting after the "=" and reparse
272  arg = name_and_equals + "'" + *entry.value + "'";
273  try
274  {
275  hit::check("CLI_ARG", arg);
276  }
277  // At this point, we've failed to fix it
278  catch (hit::ParseError & err)
279  {
280  mooseError("Failed to parse HIT in command line argument '", arg, "'\n\n", err.what());
281  }
282  }
283 
284  // Append to the total output
285  params.push_back(arg);
286  // Consider this parameter used
287  entry.used = true;
288  }
289 
290  return MooseUtils::stringJoin(params, " ");
291 }
OStreamProxy err
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
bool _command_line_params_populated
Whether or not command line parameters have been populated.
Definition: CommandLine.h:235
const std::list< Entry > & getEntries() const
Definition: CommandLine.C:186
std::string stringJoin(const std::vector< std::string > &values, const std::string &separator=" ")
Concatenates value into a single string separated by separator.
Definition: MooseUtils.C:1050
Result check(std::string requirements, const Registry &capabilities)
Checks if a set of requirements is satisified by the given capability registry.

◆ end()

auto CommandLine::end ( ) const
inline
Returns
An iterator to the end of the options

Definition at line 149 of file CommandLine.h.

Referenced by initSubAppCommandLine(), and parse().

149 { return _entries.end(); }
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227

◆ findCommandLineParam() [1/2]

std::list< CommandLine::Entry >::const_iterator CommandLine::findCommandLineParam ( const std::string &  name) const
Returns
The entry iterator for the command line arguments for the command line input parameter with name name, if any.

Definition at line 463 of file CommandLine.C.

Referenced by populateCommandLineParams().

464 {
465  const auto find_param = _command_line_params.find(name);
466  if (find_param == _command_line_params.end())
467  mooseError("CommandLine::findCommandLineParam(): The parameter '",
468  name,
469  "' is not a command line parameter");
470 
471  // Search for the last thing that matches a switch from this param
472  const auto & param = find_param->second;
473  for (auto rit = _entries.rbegin(); rit != _entries.rend(); ++rit)
474  for (const auto & search_switch : param.metadata.switches)
475  if (rit->name == search_switch)
476  return --(rit.base());
477 
478  return getEntries().end();
479 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227
std::map< std::string, CommandLineParam > _command_line_params
The command line parameters, added by populateCommandLineParams()
Definition: CommandLine.h:230
const std::list< Entry > & getEntries() const
Definition: CommandLine.C:186

◆ findCommandLineParam() [2/2]

std::list< CommandLine::Entry >::iterator CommandLine::findCommandLineParam ( const std::string &  name)
private
Returns
The entry iterator for the command line arguments for the command line input parameter with name name, if any.

Definition at line 482 of file CommandLine.C.

483 {
484  const auto it = std::as_const(*this).findCommandLineParam(name);
485  // Easy way to go from a const iterator -> non-const iterator
486  return _entries.erase(it, it);
487 }
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227

◆ formatEntry()

std::string CommandLine::formatEntry ( const Entry entry) const
Returns
A formatted representation of the given command line entry

Definition at line 490 of file CommandLine.C.

491 {
492  std::stringstream oss;
493  oss << entry.name;
494  if (entry.value)
495  {
496  const auto q = (*entry.value).find(" ") != std::string::npos ? "'" : "";
497  oss << *entry.value_separator << q << *entry.value << q;
498  }
499  return oss.str();
500 }

◆ getArguments()

const std::vector<std::string>& CommandLine::getArguments ( )
inline
Returns
The raw argv arguments as a vector

Definition at line 132 of file CommandLine.h.

Referenced by Moose::createMooseApp(), and Moose::PetscSupport::petscSetupOutput().

132 { return _argv; }
std::vector< std::string > _argv
Storage for the raw argv.
Definition: CommandLine.h:223

◆ getEntries() [1/2]

const std::list< CommandLine::Entry > & CommandLine::getEntries ( ) const
Returns
The combined argument entries

Definition at line 186 of file CommandLine.C.

Referenced by buildHitParams(), findCommandLineParam(), initSubAppCommandLine(), and unusedHitParams().

187 {
188  mooseAssert(hasParsed(), "Has not parsed");
189  return _entries;
190 }
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227
bool hasParsed() const
Definition: CommandLine.h:105

◆ getEntries() [2/2]

std::list< CommandLine::Entry > & CommandLine::getEntries ( )
private
Returns
The combined argument entries

Definition at line 193 of file CommandLine.C.

194 {
195  mooseAssert(hasParsed(), "Has not parsed");
196  return _entries;
197 }
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227
bool hasParsed() const
Definition: CommandLine.h:105

◆ getExecutableName()

std::string CommandLine::getExecutableName ( ) const
Returns
The executable name.

Definition at line 384 of file CommandLine.C.

Referenced by getExecutableNameBase(), and printUsage().

385 {
386  mooseAssert(_entries.size() > 0, "Does not have any entries");
387 
388  // Grab the first item out of argv
389  const auto & command = _entries.begin()->name;
390  return command.substr(command.find_last_of("/\\") + 1);
391 }
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227

◆ getExecutableNameBase()

std::string CommandLine::getExecutableNameBase ( ) const
Returns
The exectuable name base (the name without the -[opt,oprof,devel,dbg])

Definition at line 394 of file CommandLine.C.

395 {
396  auto name = getExecutableName();
397  name = name.substr(0, name.find_last_of("-"));
398  if (name.find_first_of("/") != std::string::npos)
399  name = name.substr(name.find_first_of("/") + 1, std::string::npos);
400  return name;
401 }
std::string name(const ElemQuality q)
std::string getExecutableName() const
Definition: CommandLine.C:384

◆ hasArgument()

bool CommandLine::hasArgument ( const std::string &  arg) const
Returns
Whether or not the raw argument arg is contained

Definition at line 53 of file CommandLine.C.

54 {
55  return std::find(_argv.begin(), _argv.end(), arg) != _argv.end();
56 }
std::vector< std::string > _argv
Storage for the raw argv.
Definition: CommandLine.h:223

◆ hasParsed()

bool CommandLine::hasParsed ( ) const
inline
Returns
Whether or not the arguments have been parsed

Definition at line 105 of file CommandLine.h.

Referenced by addArgument(), getEntries(), parse(), and removeArgument().

105 { return _has_parsed; }
bool _has_parsed
Whether or not the Parser has parsed yet.
Definition: CommandLine.h:233

◆ initSubAppCommandLine()

std::unique_ptr< CommandLine > CommandLine::initSubAppCommandLine ( const std::string &  multiapp_name,
const std::string &  subapp_name,
const std::vector< std::string > &  input_cli_args 
)

Initializes a new CommandLine for a subapp with a MultiApp named multiapp_name and a subapp named subapp_name.

The arguments input_cli_args are the additional arguments to apply to the subapp, such as those that have been specified in the MultiApp params (cli_args param).

This will apply all global parameters from this parent application and all HIT CLI parameters that have the same.

Definition at line 202 of file CommandLine.C.

205 {
206  mooseAssert(MooseUtils::beginsWith(subapp_name, multiapp_name),
207  "Name for the subapp should begin with the multiapp");
208 
209  std::vector<std::string> subapp_args;
210 
211  // Start with the arguments from the input file; we want these to take the
212  // lowest priority so we put them first. Also trim extra whitespace
213  for (const auto & arg : input_cli_args)
214  subapp_args.push_back(MooseUtils::removeExtraWhitespace(arg));
215 
216  // Pull out all of the arguments that are relevant to this multiapp from the parent
217  // Note that the 0th argument of the main app, i.e., the name used to invoke the program,
218  // is neither a global entry nor a subapp entry and, as such, won't be passed on
219  for (auto & entry : as_range(getEntries().begin(), getEntries().end()))
220  if (entry.global || (entry.subapp_name && (*entry.subapp_name == multiapp_name ||
221  *entry.subapp_name == subapp_name)))
222  {
223  if (entry.hit_param)
224  {
225  // Append : to the beginning if this is global and should be passed to all
226  const std::string prefix = entry.global ? ":" : "";
227  // Apply the param, but without the subapp name
228  subapp_args.push_back(prefix + entry.name + *entry.value_separator + *entry.value);
229  // Mark this entry as used as a child has consumed it
230  entry.used = true;
231  }
232  else
233  subapp_args.insert(subapp_args.end(), entry.raw_args.begin(), entry.raw_args.end());
234  }
235 
236  return std::make_unique<CommandLine>(subapp_args);
237 }
bool beginsWith(const std::string &value, const std::string &begin_value)
Definition: MooseUtils.C:1061
auto end() const
Definition: CommandLine.h:149
auto begin() const
Definition: CommandLine.h:145
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
const std::list< Entry > & getEntries() const
Definition: CommandLine.C:186
std::string removeExtraWhitespace(const std::string &str)
Removes additional whitespace from a string.
Definition: MooseUtils.C:221

◆ parse()

void CommandLine::parse ( )

Performs the parsing, which is the combining of arguments into [name, value] pairs.

Must be called before extracing anything from the CommandLine.

Definition at line 69 of file CommandLine.C.

Referenced by AppFactory::createAppShared(), and Moose::createMooseApp().

70 {
71  mooseAssert(!hasParsed(), "Has already parsed");
72  mooseAssert(_entries.empty(), "Should be empty");
73 
74  // Whether or not we have a entry that accepts values
75  bool has_value_accepting_entry = false;
76 
77  // Helper for adding an entry
78  auto add_entry = [this](const auto & name) -> Entry &
79  {
80  auto & entry = _entries.emplace_back();
81  entry.name = name;
82  return entry;
83  };
84 
85  // Work through each argument
86  for (const auto i : index_range(_argv))
87  {
88  const auto & arg = _argv[i];
89  const auto begins_with_dash = MooseUtils::beginsWith(arg, "-");
90  std::string subapp_prefix, subapp_name, hit_path, hit_value;
91 
92  // MultiApp syntax with a non-hit option
93  if (!begins_with_dash && std::regex_search(arg, std::regex("^(([^\\s\n\t[\\]\\/=#&:]+):)[-]")))
94  {
95  mooseError("The MultiApp command line argument '",
96  arg,
97  "' sets a command line option.\nMultiApp command line arguments can only be "
98  "used for setting HIT parameters.");
99  }
100  // Match HIT CLI syntax (including for multiapps with the prefix)
101  // For subapp hit cli syntax (i.e, <subname>:<value)), we will store the
102  // subapp names to be stripped away in initSubAppCommandLine() as they
103  // are passed down
104  else if (!begins_with_dash &&
105  pcrecpp::RE("(([^\\s\n\t[\\]\\/=#&:]+)?:)?((?:[^\\s\n\t[\\]=#&]+\\/"
106  ")?(?:[^\\s\n\t=#$'\"]+))=([^#]+)?")
107  .FullMatch(arg, &subapp_prefix, &subapp_name, &hit_path, &hit_value))
108  {
109  auto & entry = add_entry(hit_path);
110  if (subapp_prefix.size())
111  {
112  if (subapp_name.empty()) // :param=value; means apply to all
113  entry.global = true;
114  else
115  entry.subapp_name = subapp_name;
116  }
117  entry.value = MooseUtils::removeExtraWhitespace(hit_value);
118  entry.value_separator = "=";
119  entry.raw_args.push_back(arg);
120  entry.hit_param = true;
121  has_value_accepting_entry = false;
122  }
123  // Has an = sign in it, so we have a name=value (non-HIT)
124  else if (const auto find_equals = arg.find("="); find_equals != std::string::npos)
125  {
126  const auto begin = arg.substr(0, find_equals);
127  const auto end = arg.substr(find_equals + 1);
128  auto & entry = add_entry(begin);
129  entry.value = MooseUtils::removeExtraWhitespace(end);
130  entry.value_separator = "=";
131  entry.raw_args.push_back(arg);
132  has_value_accepting_entry = false;
133  }
134  // Begins with dash(es) and a character, so a new argument. We pass on
135  // everything else that starts with a dash as a value, so the error
136  // will be associated with the value before it
137  else if (std::regex_search(arg, std::regex("^\\-+[a-zA-Z]")))
138  {
139  auto & entry = add_entry(arg);
140  entry.raw_args.push_back(arg);
141  has_value_accepting_entry = true;
142  }
143  // Should be tagging on a value to the previous argument
144  else
145  {
146  // First one is the executable
147  if (i == 0)
148  {
149  auto & entry = add_entry(arg);
150  entry.raw_args.push_back(arg);
151  continue;
152  }
153 
154  // Throw an error if this a value and we don't have anything to apply it to
155  if (!has_value_accepting_entry)
156  {
157  std::stringstream err;
158  err << "The command line argument '" << arg
159  << "' is not applied to an option and is not a HIT parameter.";
160  // Maybe they meant to apply it to the previous thing
161  // Example: "-i foo.i bar.i" would suggest "-i 'foo.i bar.i'"
162  if (i > 0 && _entries.back().value)
163  {
164  err << "\n\nDid you mean to combine this argument with the previous argument, such "
165  "as:\n\n "
166  << _entries.back().name << *_entries.back().value_separator << "'"
167  << *_entries.back().value << " " << arg << "'\n";
168  }
169  mooseError(err.str());
170  }
171 
172  auto & entry = _entries.back();
173  if (entry.value)
174  *entry.value += " " + MooseUtils::removeExtraWhitespace(arg);
175  else
176  entry.value = MooseUtils::removeExtraWhitespace(arg);
177  entry.value_separator = " ";
178  entry.raw_args.push_back(arg);
179  }
180  }
181 
182  _has_parsed = true;
183 }
bool _has_parsed
Whether or not the Parser has parsed yet.
Definition: CommandLine.h:233
std::string name(const ElemQuality q)
OStreamProxy err
bool beginsWith(const std::string &value, const std::string &begin_value)
Definition: MooseUtils.C:1061
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
auto end() const
Definition: CommandLine.h:149
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227
auto begin() const
Definition: CommandLine.h:145
std::vector< std::string > _argv
Storage for the raw argv.
Definition: CommandLine.h:223
bool hasParsed() const
Definition: CommandLine.h:105
std::string removeExtraWhitespace(const std::string &str)
Removes additional whitespace from a string.
Definition: MooseUtils.C:221
auto index_range(const T &sizable)

◆ populateCommandLineParams()

void CommandLine::populateCommandLineParams ( InputParameters params)

Populates the command line input parameters from params.

Will throw errors when conversions fail and may combine entires in _entries if some are found that can be combined.

Definition at line 294 of file CommandLine.C.

Referenced by AppFactory::createAppShared(), and Moose::createMooseApp().

295 {
296  mooseAssert(!_command_line_params_populated, "Already populated");
297 
298  // Set the metadata for each command line parameter
299  // We set this separately so that it can be used later to print usage
300  std::map<std::string, std::string> switch_param_map;
301  for (const auto & name_value_pair : params)
302  {
303  const auto & name = name_value_pair.first;
304  if (const auto metadata = params.queryCommandLineMetadata(name))
305  {
306  auto it_inserted_pair = _command_line_params.emplace(name, CommandLineParam());
307  auto & option = it_inserted_pair.first->second;
308 
309  option.description = params.getDocString(name);
310  option.metadata = *metadata;
311 
312  // Make sure that one switch isn't specified for multiple parameters
313  for (const auto & cli_switch : option.metadata.switches)
314  if (const auto it_inserted_pair = switch_param_map.emplace(cli_switch, name);
315  !it_inserted_pair.second)
316  mooseError("The command line options '",
317  it_inserted_pair.first->second,
318  "' and '",
319  name,
320  "' both declare the command line switch '",
321  cli_switch,
322  "'");
323  }
324  }
325 
326  // Set each paramter that we have a value for
327  for (const auto & [name, param] : _command_line_params)
328  {
329  auto entry_it = findCommandLineParam(name);
330  if (entry_it != _entries.end())
331  {
332  auto & entry = *entry_it;
333  mooseAssert(!entry.subapp_name, "Should not be for a subapp");
334 
335  bool found = false;
336 #define trySetParameter(type) \
337  if (!found && params.have_parameter<type>(name)) \
338  { \
339  static_assert(InputParameters::isValidCommandLineType<type>::value, "Not a supported value"); \
340  auto & value = params.set<type>(name); \
341  setCommandLineParam(entry_it, param, entry.name, value); \
342  found = true; \
343  }
344 
345  trySetParameter(std::string);
346  trySetParameter(std::vector<std::string>);
347  trySetParameter(Real);
348  trySetParameter(unsigned int);
349  trySetParameter(int);
350  trySetParameter(bool);
351  trySetParameter(MooseEnum);
352 #undef trySetParameter
353 
354  mooseAssert(found, "Should have been found");
355 
356  // If we found this parameter, that means we set it and we should mark in the
357  // InputParameters that it is set so that isParamSetByUser() returns true for this param
358  params.commandLineParamSet(name, {});
359 
360  // If this parameter is global, mark its entry as global
361  if (param.metadata.global)
362  entry.global = true;
363 
364  // If the arg is of the form "--key=value", PETSc will recognize it as an unused
365  // argument. That is, setting "--key" as a known command line argument is not
366  // sufficient for PETSc to consider "--key=value" as known. Thus, we explicitly
367  // add "--key=value" args as known when we come across them.
368  if (entry.value_separator && *entry.value_separator == "=")
369  {
370  mooseAssert(entry.raw_args.size() == 1, "Should have one value");
371  libMesh::add_command_line_name(entry.raw_args[0]);
372  }
373  }
374  // If we didn't find it and it is required, we need to error
375  else if (param.metadata.required)
376  mooseError(
377  "Missing required command-line parameter: ", name, "\nDoc string: ", param.description);
378  }
379 
381 }
std::string name(const ElemQuality q)
std::list< Entry >::const_iterator findCommandLineParam(const std::string &name) const
Definition: CommandLine.C:463
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227
bool _command_line_params_populated
Whether or not command line parameters have been populated.
Definition: CommandLine.h:235
std::map< std::string, CommandLineParam > _command_line_params
The command line parameters, added by populateCommandLineParams()
Definition: CommandLine.h:230
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:33
void add_command_line_name(const std::string &name)

◆ printUsage()

void CommandLine::printUsage ( ) const

Print the usage info for this command line.

Definition at line 404 of file CommandLine.C.

405 {
406  Moose::out << "Usage: " << getExecutableName() << " [<options>]\n\n";
407 
408  std::size_t max_len = 0;
409  for (const auto & name_option_pair : _command_line_params)
410  max_len = std::max(max_len, name_option_pair.second.metadata.syntax.size());
411 
412  const auto output_options = [this, &max_len](const bool global)
413  {
414  Moose::out << (global ? "Global " : "") << "Options:\n" << std::left;
415  for (const auto & name_option_pair : _command_line_params)
416  {
417  const auto & option = name_option_pair.second;
418  if (option.metadata.syntax.empty() || option.metadata.global != global)
419  continue;
420 
421  Moose::out << " " << std::setw(max_len + 2) << option.metadata.syntax << option.description
422  << "\n";
423  }
424  Moose::out << "\n";
425  };
426 
427  output_options(false);
428  output_options(true);
429 
430  Moose::out << "Solver Options:\n"
431  << " See PETSc manual for details" << std::endl;
432 
433  // If we get here, we are not running a simulation and should silence petsc's unused options
434  // warning
435  Moose::PetscSupport::setSinglePetscOption("-options_left", "0");
436 }
std::string getExecutableName() const
Definition: CommandLine.C:384
auto max(const L &left, const R &right)
std::map< std::string, CommandLineParam > _command_line_params
The command line parameters, added by populateCommandLineParams()
Definition: CommandLine.h:230
void setSinglePetscOption(const std::string &name, const std::string &value="", FEProblemBase *const problem=nullptr)
A wrapper function for dealing with different versions of PetscOptionsSetValue.

◆ removeArgument()

void CommandLine::removeArgument ( const std::string &  arg)

Removes an argument that must exist.

Definition at line 59 of file CommandLine.C.

60 {
61  mooseAssert(!hasParsed(), "Has already parsed");
62  auto it = std::find(_argv.begin(), _argv.end(), arg);
63  if (it == _argv.end())
64  mooseError("CommandLine::removeArgument(): The argument '", arg, "' does not exist");
65  _argv.erase(it);
66 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::vector< std::string > _argv
Storage for the raw argv.
Definition: CommandLine.h:223
bool hasParsed() const
Definition: CommandLine.h:105

◆ setCommandLineParam() [1/2]

template<typename T >
void CommandLine::setCommandLineParam ( std::list< Entry >::iterator  entry_it,
const CommandLineParam param,
const std::string &  cli_switch,
T &  value 
)
private

Sets an InputParameters command line option at value.

Will report an error if string -> value conversions fail or if the parameter requires a value and one was not found.

Parameters
entry_itIterator to the Entry object that we're extracting from
paramThe internal metadata for the command line parameter
cli_switchThe command line switch for the parameter (-t, –timing, etc)
valueThe value that we want to fill into

◆ setCommandLineParam() [2/2]

template<typename T >
void CommandLine::setCommandLineParam ( std::list< CommandLine::Entry >::iterator  entry_it,
const CommandLineParam param,
const std::string &  cli_switch,
T &  value 
)

Definition at line 240 of file CommandLine.h.

244 {
245  auto & entry = *entry_it;
246  const auto required = param.metadata.argument_type == ArgumentType::REQUIRED;
247 
248  // Mark this entry as used
249  entry.used = true;
250 
251  // Option doesn't have any arguments (boolean)
252  if constexpr (std::is_same_v<bool, T>)
253  {
254  mooseAssert(param.metadata.argument_type == ArgumentType::NONE, "Incorrect argument type");
255 
256  if (entry.value)
257  mooseError("The command line option '",
258  cli_switch,
259  "' is a boolean and does not support a value but the value '",
260  *entry.value,
261  "' was provided.\nDoc string: ",
262  param.description);
263  value = true;
264  }
265  // Option has arguments
266  else
267  {
268  mooseAssert(param.metadata.argument_type != ArgumentType::NONE, "Incorrect argument type");
269 
270  // Helper for setting a value depending on its type and also throwing a useful
271  // error when the conversion fails
272  const auto set_value = [&cli_switch](const std::string & from, auto & value)
273  {
274  using type = typename std::remove_reference<decltype(value)>::type;
275 
276  // Keep track of and change the throw on error characteristics so that
277  // we can catch parsing errors for the argument
278  const auto throw_on_error_orig = Moose::_throw_on_error;
279  Moose::_throw_on_error = true;
280 
281  try
282  {
283  if constexpr (std::is_same_v<type, std::string> || std::is_same_v<type, MooseEnum>)
284  value = from;
285  else
286  value = MooseUtils::convert<type>(from, true);
287  }
288  catch (std::exception & e)
289  {
290  Moose::_throw_on_error = throw_on_error_orig;
291  mooseError("While parsing command line option '",
292  cli_switch,
293  "' with value '",
294  from,
295  "':\n\n",
296  e.what());
297  }
298 
299  Moose::_throw_on_error = throw_on_error_orig;
300  };
301 
302  // If a value doesn't exist, check the next argument to see if it
303  // would work. This is needed for when we have argument values that
304  // have = signs that get split. For example:
305  // "--required-capabilities 'petsc>=3.11'" would get split into:
306  // - "--required-capabilities" with no value
307  // - "petsc>" with value "3.11"
308  // which we want to re-combine into
309  // - "--required-capabilities" with value "petsc>=3.11"
310  if (!entry.value)
311  {
312  auto next_entry_it = std::next(entry_it);
313  if (next_entry_it != _entries.end())
314  {
315  const auto & next_entry = *next_entry_it;
316  if (!next_entry.used && // isn't already used
317  (required || !next_entry.hit_param) && // if required, get the last value. if not, get
318  // it if it's not a hit param
319  !MooseUtils::beginsWith(next_entry.name, "-") && // doesn't start with a -
320  next_entry.value_separator && // has a separator
321  *next_entry.value_separator == "=" && // that separator is =
322  next_entry.value) // and has a value after the =
323  {
324  const auto & next_entry = *next_entry_it;
325  // Merge with the next Entry object and remove said next object
326  entry.value = next_entry.name + *next_entry.value_separator + *next_entry.value;
327  entry.raw_args.insert(
328  entry.raw_args.end(), next_entry.raw_args.begin(), next_entry.raw_args.end());
329  _entries.erase(next_entry_it);
330  }
331  }
332  }
333 
334  // If we have a value, set the parameter to it
335  if (entry.value)
336  {
337  // For vector<string>, we need to unpack the values
338  if constexpr (std::is_same_v<T, std::vector<std::string>>)
339  {
340  std::vector<std::string> split_values;
341  MooseUtils::tokenize(*entry.value, split_values, 1, " ");
342  value.resize(split_values.size());
343  for (const auto i : index_range(split_values))
344  set_value(split_values[i], value[i]);
345  }
346  // For everything else, we can set them directly
347  else
348  set_value(*entry.value, value);
349  }
350  // No value, but one is required
351  else if (param.metadata.argument_type == ArgumentType::REQUIRED)
352  mooseError("The command line option '",
353  cli_switch,
354  "' requires a value and one was not provided.\nDoc string: ",
355  param.description);
356  }
357 }
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
This function will split the passed in string on a set of delimiters appending the substrings to the ...
bool beginsWith(const std::string &value, const std::string &begin_value)
Definition: MooseUtils.C:1061
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
std::list< Entry > _entries
The parsed command line entries (arguments split into name value pairs) This is a list because it is ...
Definition: CommandLine.h:227
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
bool _throw_on_error
Variable to turn on exceptions during mooseError(), should only be used within MOOSE unit tests or wh...
Definition: Moose.C:758
auto index_range(const T &sizable)

◆ unusedHitParams()

std::vector< std::string > CommandLine::unusedHitParams ( const Parallel::Communicator comm) const

Returns the HIT command line arguments that are not used.

The HIT command line arguments are considered used when they are accumulated in buildHitParams().

The commmunicator is needed because we need to sync this in parallel due to the fact that sub apps could only be created on a subset of processors.

Definition at line 439 of file CommandLine.C.

440 {
441  libmesh_parallel_only(comm);
442 
443  std::vector<const Entry *> hit_params;
444  std::vector<std::size_t> use_count;
445  for (const auto & entry : getEntries())
446  if (entry.hit_param)
447  {
448  hit_params.push_back(&entry);
449  use_count.push_back(entry.used ? 1 : 0);
450  }
451 
452  mooseAssert(comm.verify(use_count.size()), "Inconsistent HIT params across procs");
453  comm.sum(use_count);
454 
455  std::vector<std::string> unused;
456  for (const auto i : index_range(use_count))
457  if (use_count[i] == 0)
458  unused.push_back(hit_params[i]->raw_args[0]);
459  return unused;
460 }
const std::list< Entry > & getEntries() const
Definition: CommandLine.C:186
timpi_pure bool verify(const T &r) const
auto index_range(const T &sizable)

Member Data Documentation

◆ _argv

std::vector<std::string> CommandLine::_argv
private

Storage for the raw argv.

Definition at line 223 of file CommandLine.h.

Referenced by addArgument(), getArguments(), hasArgument(), parse(), and removeArgument().

◆ _command_line_params

std::map<std::string, CommandLineParam> CommandLine::_command_line_params
private

The command line parameters, added by populateCommandLineParams()

Definition at line 230 of file CommandLine.h.

Referenced by findCommandLineParam(), populateCommandLineParams(), and printUsage().

◆ _command_line_params_populated

bool CommandLine::_command_line_params_populated = false
private

Whether or not command line parameters have been populated.

Definition at line 235 of file CommandLine.h.

Referenced by buildHitParams(), and populateCommandLineParams().

◆ _entries

std::list<Entry> CommandLine::_entries
private

The parsed command line entries (arguments split into name value pairs) This is a list because it is necessary to combine Entry objects later on.

Definition at line 227 of file CommandLine.h.

Referenced by begin(), end(), findCommandLineParam(), getEntries(), getExecutableName(), parse(), populateCommandLineParams(), and setCommandLineParam().

◆ _has_parsed

bool CommandLine::_has_parsed = false
private

Whether or not the Parser has parsed yet.

Definition at line 233 of file CommandLine.h.

Referenced by hasParsed(), and parse().


The documentation for this class was generated from the following files: