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

Referenced by populateCommandLineParams().

465 {
466  const auto find_param = _command_line_params.find(name);
467  if (find_param == _command_line_params.end())
468  mooseError("CommandLine::findCommandLineParam(): The parameter '",
469  name,
470  "' is not a command line parameter");
471 
472  // Search for the last thing that matches a switch from this param
473  const auto & param = find_param->second;
474  for (auto rit = _entries.rbegin(); rit != _entries.rend(); ++rit)
475  for (const auto & search_switch : param.metadata.switches)
476  if (rit->name == search_switch)
477  return --(rit.base());
478 
479  return getEntries().end();
480 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:333
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 483 of file CommandLine.C.

484 {
485  const auto it = std::as_const(*this).findCommandLineParam(name);
486  // Easy way to go from a const iterator -> non-const iterator
487  return _entries.erase(it, it);
488 }
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 491 of file CommandLine.C.

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

◆ 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 385 of file CommandLine.C.

Referenced by getExecutableNameBase(), and printUsage().

386 {
387  mooseAssert(_entries.size() > 0, "Does not have any entries");
388 
389  // Grab the first item out of argv
390  const auto & command = _entries.begin()->name;
391  return command.substr(command.find_last_of("/\\") + 1);
392 }
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 395 of file CommandLine.C.

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

◆ 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:333
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 295 of file CommandLine.C.

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

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

406 {
407  Moose::out << "Usage: " << getExecutableName() << " [<options>]\n\n";
408 
409  std::size_t max_len = 0;
410  for (const auto & name_option_pair : _command_line_params)
411  max_len = std::max(max_len, name_option_pair.second.metadata.syntax.size());
412 
413  const auto output_options = [this, &max_len](const bool global)
414  {
415  Moose::out << (global ? "Global " : "") << "Options:\n" << std::left;
416  for (const auto & name_option_pair : _command_line_params)
417  {
418  const auto & option = name_option_pair.second;
419  if (option.metadata.syntax.empty() || option.metadata.global != global)
420  continue;
421 
422  Moose::out << " " << std::setw(max_len + 2) << option.metadata.syntax << option.description
423  << "\n";
424  }
425  Moose::out << "\n";
426  };
427 
428  output_options(false);
429  output_options(true);
430 
431  Moose::out << "Solver Options:\n"
432  << " See PETSc manual for details" << std::endl;
433 
434  // If we get here, we are not running a simulation and should silence petsc's unused options
435  // warning
436  Moose::PetscSupport::setSinglePetscOption("-options_left", "0");
437 }
std::string getExecutableName() const
Definition: CommandLine.C:385
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:333
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 242 of file CommandLine.h.

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

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

◆ _hit_params_built

bool CommandLine::_hit_params_built = false
private

Whether or not the HIT parameters have been built (set as used)

Definition at line 237 of file CommandLine.h.

Referenced by buildHitParams().


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