SPH
ArgsParser.cpp
Go to the documentation of this file.
1 #include "system/ArgsParser.h"
3 
5 
7  descs.pushAll(args.begin(), args.end());
8  descs.push(ArgDesc{ "h", "help", ArgEnum::NONE, "Prints this help", [this] {
9  StringLogger logger;
10  logger.write("List of parameters:");
11  printHelp(logger);
12  throw HelpException(logger.toString());
13  } });
14 }
15 
16 void ArgParser::parse(const int argc, char** argv) {
17  params.clear();
18  for (int i = 1; i < argc; ++i) {
19  const std::string name = argv[i];
20  auto iter =
21  std::find_if(descs.begin(), descs.end(), [&name](ArgDesc& desc) { return desc.matches(name); });
22  if (iter != descs.end()) {
23  if (iter->type == ArgEnum::NONE) {
24  parseValuelessArg(*iter);
25  } else {
26  if (i + 1 == argc) {
27  throw ArgError("Missing parameter value: " + name);
28  }
29  parseValueArg(*iter, argv[i + 1]);
30  ++i;
31  }
32  } else {
33  throw ArgError("Unknown parameter: " + name);
34  }
35  }
36 }
37 
38 INLINE std::string toString(const ArgEnum type) {
39  switch (type) {
40  case ArgEnum::INT:
41  return "INT";
42  case ArgEnum::FLOAT:
43  return "FLOAT";
44  case ArgEnum::STRING:
45  return "STRING";
46  default:
48  }
49 }
50 
52  for (ArgDesc& arg : descs) {
53  std::string line = "-" + arg.shortName + ", --" + arg.longName + " ";
54  if (arg.type != ArgEnum::NONE) {
55  line += toString(arg.type);
56  }
58  line += std::string(max(1, 35 - int(line.size())), ' ');
59 
60  const std::string desc = setLineBreak(arg.desc, 40);
61  line += replaceAll(desc, "\n", "\n" + std::string(35, ' '));
62  logger.write(line);
63  }
64 }
65 
66 void ArgParser::parseValuelessArg(const ArgDesc& desc) {
67  if (params.contains(desc.shortName)) {
68  throw ArgError("Duplicate parameter: " + desc.shortName);
69  }
70  params.insert(desc.shortName, true);
71 
72  if (desc.callback) {
73  desc.callback();
74  }
75 }
76 
77 void ArgParser::parseValueArg(const ArgDesc& desc, const std::string& value) {
78  if (params.contains(desc.shortName)) {
79  throw ArgError("Duplicate parameter: " + desc.shortName);
80  }
81 
82  switch (desc.type) {
83  case ArgEnum::INT:
84  insertArg<int>(desc.shortName, value);
85  break;
86  case ArgEnum::FLOAT:
87  insertArg<Float>(desc.shortName, value);
88  break;
89  case ArgEnum::STRING:
90  insertArg<std::string>(desc.shortName, value);
91  break;
92  default:
93  STOP;
94  }
95 
96  if (desc.callback) {
97  desc.callback();
98  }
99 }
100 
101 template <typename TValue>
102 void ArgParser::insertArg(const std::string& name, const std::string& textValue) {
103  const Optional<TValue> value = fromString<TValue>(textValue);
104  if (!value) {
105  throw ArgError("Cannot parse value of parameter " + name);
106  }
107  params.insert(name, value.value());
108 }
109 
110 void ArgParser::throwIfUnknownArg(const std::string& name) const {
111  auto iter = std::find_if(descs.begin(), descs.end(), [&name](const ArgDesc& desc) { //
112  return desc.shortName == name;
113  });
114  if (iter == descs.end()) {
115  throw ArgError("Unknown argument " + name);
116  }
117 }
118 
INLINE std::string toString(const ArgEnum type)
Definition: ArgsParser.cpp:38
ArgEnum
Definition: ArgsParser.h:13
@ NONE
No value after the argument.
#define STOP
Definition: Assert.h:106
#define NOT_IMPLEMENTED
Helper macro marking missing implementation.
Definition: Assert.h:100
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
constexpr INLINE T max(const T &f1, const T &f2)
Definition: MathBasic.h:20
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
std::string setLineBreak(const std::string &s, const Size lineWidth)
Inserts to string so that no line is longer than given limit.
std::string replaceAll(const std::string &source, const std::string &old, const std::string &s)
Replaces all occurences of string with a new string.
Exception thrown if the arguments are invalid.
Definition: ArgsParser.h:23
void parse(const int argc, char **argv)
Parses the input arguments and stored the parsed values.
Definition: ArgsParser.cpp:16
void printHelp(ILogger &logger)
Prints the help information into given logger.
Definition: ArgsParser.cpp:51
ArgParser(ArrayView< const ArgDesc > args)
Creates a parser, given a set of parameter descriptors.
Definition: ArgsParser.cpp:6
Object providing safe access to continuous memory of data.
Definition: ArrayView.h:17
INLINE Iterator< StorageType > begin()
Definition: ArrayView.h:55
INLINE Iterator< StorageType > end()
Definition: ArrayView.h:63
INLINE Iterator< StorageType > end() noexcept
Definition: Array.h:462
INLINE void push(U &&u)
Adds new element to the end of the array, resizing the array if necessary.
Definition: Array.h:306
INLINE Iterator< StorageType > begin() noexcept
Definition: Array.h:450
void pushAll(const TIter first, const TIter last)
Definition: Array.h:312
Exception thrown when used passes -h or –help parameter.
Definition: ArgsParser.h:32
Interface providing generic (text, human readable) output of the program.
Definition: Logger.h:22
void write(TArgs &&... args)
Creates and logs a message by concatenating arguments.
Definition: Logger.h:37
Wrapper of type value of which may or may not be present.
Definition: Optional.h:23
INLINE Type & value()
Returns the reference to the stored value.
Definition: Optional.h:172
Logger writing messages to string stream.
Definition: Logger.h:145
std::string toString() const
Returns all written messages as a string. Messages are not erased from the logger by this.
Definition: Logger.cpp:35
Descriptor of a command-line argument.
Definition: ArgsParser.h:39
std::string shortName
Short name, prefixed by single dash (e.g. -h)
Definition: ArgsParser.h:41
Function< void()> callback
Generic callback executed when the parameter is parsed.
Definition: ArgsParser.h:53
ArgEnum type
Type of the parameter.
Definition: ArgsParser.h:47