https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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.
 
void addArgument (const std::string &arg)
 Adds a single argument.
 
void addArguments (const std::vector< std::string > &args)
 Adds arguments from a vector.
 
bool hasArgument (const std::string &arg) const
 
void removeArgument (const std::string &arg)
 Removes an argument that must exist.
 
void parse ()
 Performs the parsing, which is the combining of arguments into [name, value] pairs.
 
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, const std::set< std::string > &exclude_params={})
 Initializes a new CommandLine for a subapp with a MultiApp named multiapp_name and a subapp named subapp_name.
 
std::vector< std::string > buildHitParams ()
 
const std::vector< std::string > & getArguments ()
 
void populateCommandLineParams (InputParameters &params)
 Populates the command line input parameters from params.
 
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.
 
std::vector< std::string > unusedHitParams (const Parallel::Communicator &comm) const
 Returns the HIT command line arguments that are not used.
 
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.
 
std::list< Entry >::iterator findCommandLineParam (const std::string &name)
 

Private Attributes

std::vector< std::string > _argv
 Storage for the raw argv.
 
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.
 
std::map< std::string, CommandLineParam_command_line_params
 The command line parameters, added by populateCommandLineParams()
 
bool _has_parsed = false
 Whether or not the Parser has parsed yet.
 
bool _command_line_params_populated = false
 Whether or not command line parameters have been populated.
 
bool _hit_params_built = false
 Whether or not the HIT parameters have been built (set as used)
 

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); }

◆ ~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.

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

Referenced by addArguments(), and addArguments().

◆ addArguments() [1/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

◆ addArguments() [2/2]

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

Adds arguments from raw argc and argv.

Definition at line 32 of file CommandLine.C.

33{
34 for (int i = 0; i < argc; i++)
35 addArgument(argv[i]);
36}

Referenced by CommandLine(), and CommandLine().

◆ begin()

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

Definition at line 151 of file CommandLine.h.

151{ 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 ...

Referenced by initSubAppCommandLine(), and parse().

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

257{
258 mooseAssert(!_hit_params_built, "Already built");
259 _hit_params_built = true;
260
261 std::vector<std::string> params;
262
263 // Collect all hit parameters that aren't for subapps
264 for (auto & entry : getEntries())
265 if (entry.hit_param && !entry.subapp_name)
266 {
267 mooseAssert(entry.value, "Should have a value");
268 mooseAssert(entry.value_separator, "Should have value separator");
269 mooseAssert(*entry.value_separator == "=", "Should be an equals");
270
271 const std::string name_and_equals = entry.name + *entry.value_separator;
272 std::string arg = name_and_equals;
273 // In the case of empty values, we want them to be empty to hit
274 if (entry.value->empty())
275 arg += "''";
276 else
277 arg += *entry.value;
278
279 // We could have issues with bash eating strings, so the first try
280 // gives us a chance to wrap the value in quotes
281 try
282 {
283 hit::check("CLI_ARG", arg);
284 }
285 catch (hit::Error & err)
286 {
287 // bash might have eaten quotes around a hit string value or vector
288 // so try quoting after the "=" and reparse
289 arg = name_and_equals + "'" + *entry.value + "'";
290 try
291 {
292 hit::check("CLI_ARG", arg);
293 }
294 // At this point, we've failed to fix it
295 catch (hit::Error & err)
296 {
297 mooseError("Failed to parse HIT in command line argument '", arg, "'\n\n", err.what());
298 }
299 }
300
301 // Append to the total output
302 params.push_back(arg);
303 // Consider this parameter used
304 entry.used = true;
305 }
306
307 return params;
308}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
if(!dmm->_nl) SETERRQ(PETSC_COMM_WORLD
bool _hit_params_built
Whether or not the HIT parameters have been built (set as used)
const std::list< Entry > & getEntries() const
OStreamProxy err(std::cerr)

◆ end()

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

Definition at line 155 of file CommandLine.h.

155{ return _entries.end(); }

Referenced by initSubAppCommandLine(), and parse().

◆ findCommandLineParam() [1/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 499 of file CommandLine.C.

500{
501 const auto it = std::as_const(*this).findCommandLineParam(name);
502 // Easy way to go from a const iterator -> non-const iterator
503 return _entries.erase(it, it);
504}

◆ findCommandLineParam() [2/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 480 of file CommandLine.C.

481{
482 const auto find_param = _command_line_params.find(name);
483 if (find_param == _command_line_params.end())
484 mooseError("CommandLine::findCommandLineParam(): The parameter '",
485 name,
486 "' is not a command line parameter");
487
488 // Search for the last thing that matches a switch from this param
489 const auto & param = find_param->second;
490 for (auto rit = _entries.rbegin(); rit != _entries.rend(); ++rit)
491 for (const auto & search_switch : param.metadata.switches)
492 if (rit->name == search_switch)
493 return --(rit.base());
494
495 return getEntries().end();
496}
std::map< std::string, CommandLineParam > _command_line_params
The command line parameters, added by populateCommandLineParams()
std::string name(const ElemQuality q)

Referenced by initSubAppCommandLine(), and populateCommandLineParams().

◆ formatEntry()

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

Definition at line 507 of file CommandLine.C.

508{
509 std::stringstream oss;
510 oss << entry.name;
511 if (entry.value)
512 {
513 const auto q = (*entry.value).find(" ") != std::string::npos ? "'" : "";
514 oss << *entry.value_separator << q << *entry.value << q;
515 }
516 return oss.str();
517}
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition KokkosUtils.h:40

◆ getArguments()

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

Definition at line 138 of file CommandLine.h.

138{ return _argv; }

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

◆ getEntries() [1/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}

◆ getEntries() [2/2]

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

Definition at line 186 of file CommandLine.C.

187{
188 mooseAssert(hasParsed(), "Has not parsed");
189 return _entries;
190}

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

◆ getExecutableName()

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

Definition at line 401 of file CommandLine.C.

402{
403 mooseAssert(_entries.size() > 0, "Does not have any entries");
404
405 // Grab the first item out of argv
406 const auto & command = _entries.begin()->name;
407 return command.substr(command.find_last_of("/\\") + 1);
408}

Referenced by getExecutableNameBase(), and printUsage().

◆ getExecutableNameBase()

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

Definition at line 411 of file CommandLine.C.

412{
413 auto name = getExecutableName();
414 name = name.substr(0, name.find_last_of("-"));
415 if (name.find_first_of("/") != std::string::npos)
416 name = name.substr(name.find_first_of("/") + 1, std::string::npos);
417 return name;
418}
std::string getExecutableName() const

◆ 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}

◆ hasParsed()

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

Definition at line 105 of file CommandLine.h.

105{ return _has_parsed; }
bool _has_parsed
Whether or not the Parser has parsed yet.

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

◆ 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,
const std::set< std::string > &  exclude_params = {} 
)

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.

The optional exclude_params is a set of InputParameters names (e.g. "recover", "test_checkpoint_half_transient") whose corresponding command-line entries will NOT be propagated to the sub-app, even if they are marked global. Entries are matched by the parameter name as registered in MooseApp::validParams().

Definition at line 202 of file CommandLine.C.

206{
207 mooseAssert(MooseUtils::beginsWith(subapp_name, multiapp_name),
208 "Name for the subapp should begin with the multiapp");
209
210 std::vector<std::string> subapp_args;
211
212 // Start with the arguments from the input file; we want these to take the
213 // lowest priority so we put them first. Also trim extra whitespace
214 for (const auto & arg : input_cli_args)
215 subapp_args.push_back(MooseUtils::removeExtraWhitespace(arg));
216
217 // Resolve the excluded parameter names to their Entry pointers so we can
218 // efficiently skip them in the propagation loop below. We skip entries for
219 // which findCommandLineParam returns end() (param registered but not present).
220 std::set<const Entry *> skip_entries;
221 for (const auto & param_name : exclude_params)
222 {
223 auto it = findCommandLineParam(param_name);
224 if (it != getEntries().end())
225 skip_entries.insert(&*it);
226 }
227
228 // Pull out all of the arguments that are relevant to this multiapp from the parent
229 // Note that the 0th argument of the main app, i.e., the name used to invoke the program,
230 // is neither a global entry nor a subapp entry and, as such, won't be passed on
231 for (auto & entry : as_range(getEntries().begin(), getEntries().end()))
232 if (entry.global || (entry.subapp_name && (*entry.subapp_name == multiapp_name ||
233 *entry.subapp_name == subapp_name)))
234 {
235 // Skip entries that the caller has asked to suppress from propagation
236 if (skip_entries.count(&entry))
237 continue;
238
239 if (entry.hit_param)
240 {
241 // Append : to the beginning if this is global and should be passed to all
242 const std::string prefix = entry.global ? ":" : "";
243 // Apply the param, but without the subapp name
244 subapp_args.push_back(prefix + entry.name + *entry.value_separator + *entry.value);
245 // Mark this entry as used as a child has consumed it
246 entry.used = true;
247 }
248 else
249 subapp_args.insert(subapp_args.end(), entry.raw_args.begin(), entry.raw_args.end());
250 }
251
252 return std::make_unique<CommandLine>(subapp_args);
253}
std::list< Entry >::const_iterator findCommandLineParam(const std::string &name) const
auto begin() const
auto end() const
std::string removeExtraWhitespace(const std::string &input)
Definition MooseUtils.C:236
bool beginsWith(const std::string &value, const std::string &begin_value)
Definition MooseUtils.C:966
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)

◆ 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.

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);
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}
auto index_range(const T &sizable)

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

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

312{
313 mooseAssert(!_command_line_params_populated, "Already populated");
314
315 // Set the metadata for each command line parameter
316 // We set this separately so that it can be used later to print usage
317 std::map<std::string, std::string> switch_param_map;
318 for (const auto & name_value_pair : params)
319 {
320 const auto & name = name_value_pair.first;
321 if (const auto metadata = params.queryCommandLineMetadata(name))
322 {
323 auto it_inserted_pair = _command_line_params.emplace(name, CommandLineParam());
324 auto & option = it_inserted_pair.first->second;
325
326 option.description = params.getDocString(name);
327 option.metadata = *metadata;
328
329 // Make sure that one switch isn't specified for multiple parameters
330 for (const auto & cli_switch : option.metadata.switches)
331 if (const auto it_inserted_pair = switch_param_map.emplace(cli_switch, name);
332 !it_inserted_pair.second)
333 mooseError("The command line options '",
334 it_inserted_pair.first->second,
335 "' and '",
336 name,
337 "' both declare the command line switch '",
338 cli_switch,
339 "'");
340 }
341 }
342
343 // Set each paramter that we have a value for
344 for (const auto & [name, param] : _command_line_params)
345 {
346 auto entry_it = findCommandLineParam(name);
347 if (entry_it != _entries.end())
348 {
349 auto & entry = *entry_it;
350 mooseAssert(!entry.subapp_name, "Should not be for a subapp");
351
352 bool found = false;
353#define trySetParameter(type) \
354 if (!found && params.have_parameter<type>(name)) \
355 { \
356 static_assert(InputParameters::isValidCommandLineType<type>::value, "Not a supported value"); \
357 auto & value = params.set<type>(name); \
358 setCommandLineParam(entry_it, param, entry.name, value); \
359 found = true; \
360 }
361
362 trySetParameter(std::string);
363 trySetParameter(std::vector<std::string>);
364 trySetParameter(Real);
365 trySetParameter(unsigned int);
366 trySetParameter(int);
367 trySetParameter(bool);
368 trySetParameter(MooseEnum);
369#undef trySetParameter
370
371 mooseAssert(found, "Should have been found");
372
373 // If we found this parameter, that means we set it and we should mark in the
374 // InputParameters that it is set so that isParamSetByUser() returns true for this param
375 params.commandLineParamSet(name, {});
376
377 // If this parameter is global, mark its entry as global
378 if (param.metadata.global)
379 entry.global = true;
380
381 // If the arg is of the form "--key=value", PETSc will recognize it as an unused
382 // argument. That is, setting "--key" as a known command line argument is not
383 // sufficient for PETSc to consider "--key=value" as known. Thus, we explicitly
384 // add "--key=value" args as known when we come across them.
385 if (entry.value_separator && *entry.value_separator == "=")
386 {
387 mooseAssert(entry.raw_args.size() == 1, "Should have one value");
388 libMesh::add_command_line_name(entry.raw_args[0]);
389 }
390 }
391 // If we didn't find it and it is required, we need to error
392 else if (param.metadata.required)
394 "Missing required command-line parameter: ", name, "\nDoc string: ", param.description);
395 }
396
398}
bool _command_line_params_populated
Whether or not command line parameters have been populated.
void commandLineParamSet(const std::string &name, const CommandLineParamSetKey)
Marks the command line parameter name as set by the CommandLine.
std::optional< InputParameters::CommandLineMetadata > queryCommandLineMetadata(const std::string &name) const
std::string getDocString(const std::string &name) const
Returns the documentation string for the specified parameter name.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
void add_command_line_name(const std::string &name)

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

◆ printUsage()

void CommandLine::printUsage ( ) const

Print the usage info for this command line.

Definition at line 421 of file CommandLine.C.

422{
423 Moose::out << "Usage: " << getExecutableName() << " [<options>]\n\n";
424
425 std::size_t max_len = 0;
426 for (const auto & name_option_pair : _command_line_params)
427 max_len = std::max(max_len, name_option_pair.second.metadata.syntax.size());
428
429 const auto output_options = [this, &max_len](const bool global)
430 {
431 Moose::out << (global ? "Global " : "") << "Options:\n" << std::left;
432 for (const auto & name_option_pair : _command_line_params)
433 {
434 const auto & option = name_option_pair.second;
435 if (option.metadata.syntax.empty() || option.metadata.global != global)
436 continue;
437
438 Moose::out << " " << std::setw(max_len + 2) << option.metadata.syntax << option.description
439 << "\n";
440 }
441 Moose::out << "\n";
442 };
443
444 output_options(false);
445 output_options(true);
446
447 Moose::out << "Solver Options:\n"
448 << " See PETSc manual for details" << std::endl;
449
450 // If we get here, we are not running a simulation and should silence petsc's unused options
451 // warning
452 Moose::PetscSupport::setSinglePetscOption("-options_left", "0");
453}
auto max(const L &left, const R &right)
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}

◆ setCommandLineParam() [1/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 248 of file CommandLine.h.

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

◆ setCommandLineParam() [2/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

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

457{
458 libmesh_parallel_only(comm);
459
460 std::vector<const Entry *> hit_params;
461 std::vector<std::size_t> use_count;
462 for (const auto & entry : getEntries())
463 if (entry.hit_param)
464 {
465 hit_params.push_back(&entry);
466 use_count.push_back(entry.used ? 1 : 0);
467 }
468
469 mooseAssert(comm.verify(use_count.size()), "Inconsistent HIT params across procs");
470 comm.sum(use_count);
471
472 std::vector<std::string> unused;
473 for (const auto i : index_range(use_count))
474 if (use_count[i] == 0)
475 unused.push_back(hit_params[i]->raw_args[0]);
476 return unused;
477}
timpi_pure bool verify(const T &r) const

Member Data Documentation

◆ _argv

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

Storage for the raw argv.

Definition at line 229 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 236 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 241 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 233 of file CommandLine.h.

Referenced by begin(), end(), findCommandLineParam(), findCommandLineParam(), getEntries(), 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 239 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 243 of file CommandLine.h.

Referenced by buildHitParams().


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