Eclipse SUMO - Simulation of Urban MObility
OptionsParser.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Parses the command line arguments
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <iostream>
25 #include <cstring>
26 #include "Option.h"
27 #include "OptionsCont.h"
28 #include "OptionsParser.h"
31 
32 
33 // ===========================================================================
34 // method definitions
35 // ===========================================================================
36 bool
37 OptionsParser::parse(const std::vector<std::string>& args, const bool ignoreAppenders) {
38  bool ok = true;
39  const int argc = (int)args.size();
40  for (int i = 1; i < argc;) {
41  try {
42  int add;
43  // try to set the current option
44  if (i < argc - 1) {
45  add = check(args[i], &args[i + 1], ok, ignoreAppenders);
46  } else {
47  add = check(args[i], nullptr, ok, ignoreAppenders);
48  }
49  i += add;
50  } catch (ProcessError& e) {
51  WRITE_ERROR("On processing option '" + args[i] + "':\n " + e.what());
52  i++;
53  ok = false;
54  }
55  }
56  return ok;
57 }
58 
59 
60 int
61 OptionsParser::check(const std::string& arg1, const std::string* const arg2, bool& ok, const bool ignoreAppenders) {
62  // the first argument should be an option
63  // (only the second may be a free string)
64  if (!checkParameter(arg1)) {
65  ok = false;
66  return 1;
67  }
68 
70  const bool append = arg1[0] == '+';
71  // process not abbreviated switches
72  if (append || arg1[1] == '-') {
73  const std::string tmp(arg1.substr(append ? 1 : 2));
74  const std::string::size_type idx1 = tmp.find('=');
75  if (append && ignoreAppenders) {
76  return idx1 == std::string::npos ? 2 : 1;
77  }
78  // check whether a parameter was submitted
79  if (idx1 != std::string::npos) {
80  ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1), append);
81  } else {
82  if (arg2 == nullptr || (oc.isBool(tmp) && (*arg2)[0] == '-')) {
83  ok &= oc.set(tmp, "true");
84  } else {
85  ok &= oc.set(tmp, *arg2, append);
86  return 2;
87  }
88  }
89  return 1;
90  }
91  // go through the abbreviated switches
92  const int len = (int)arg1.size();
93  for (int i = 1; i < len; i++) {
94  // set boolean switches
95  const std::string abbr = arg1.substr(i, 1);
96  if (oc.isBool(abbr)) {
97  if (arg2 == nullptr || (*arg2)[0] == '-' || i != len - 1) {
98  ok &= oc.set(abbr, "true");
99  } else {
100  ok &= oc.set(abbr, *arg2);
101  return 2;
102  }
103  // set non-boolean switches
104  } else {
105  // check whether the parameter comes directly after the switch
106  // and process if so
107  if (arg2 == nullptr || i != len - 1) {
108  ok &= processNonBooleanSingleSwitch(oc, arg1.substr(i), append);
109  return 1;
110  // process parameter following after a space
111  } else {
112  ok &= oc.set(abbr, *arg2, append);
113  // option name and attribute were in two arguments
114  return 2;
115  }
116  }
117  }
118  // all switches within the current argument were boolean switches
119  return 1;
120 }
121 
122 
123 bool
124 OptionsParser::processNonBooleanSingleSwitch(OptionsCont& oc, const std::string& arg, const bool append) {
125  if (arg[1] == '=') {
126  if (arg.size() < 3) {
127  WRITE_ERRORF(TL("Missing value for parameter '%'."), arg.substr(0, 1));
128  return false;
129  } else {
130  return oc.set(arg.substr(0, 1), arg.substr(2), append);
131  }
132  } else {
133  if (arg.size() < 2) {
134  WRITE_ERRORF(TL("Missing value for parameter '%'."), arg);
135  return false;
136  } else {
137  return oc.set(arg.substr(0, 1), arg.substr(1), append);
138  }
139  }
140 }
141 
142 
143 bool
144 OptionsParser::checkParameter(const std::string& arg1) {
145  if (arg1[0] != '-' && arg1[0] != '+') {
146  WRITE_ERRORF(TL("The parameter '%' is not allowed in this context.\n Switch or parameter name expected."), arg1);
147  return false;
148  }
149  if ((arg1[0] == '-' && arg1[1] == '+') || (arg1[0] == '+' && arg1[1] == '-')) {
150  WRITE_ERRORF(TL("Mixed parameter syntax in '%'."), arg1);
151  return false;
152  }
153  return true;
154 }
155 
156 
157 /****************************************************************************/
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isBool(const std::string &name) const
Returns the information whether the option is a boolean option.
bool set(const std::string &name, const std::string &value, const bool append=false)
Sets the given value for the named option.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
static bool parse(const std::vector< std::string > &args, const bool ignoreAppenders=false)
Parses the given command line arguments.
static int check(const std::string &arg1, const std::string *const arg2, bool &ok, const bool ignoreAppenders)
parses the previous arguments
static bool checkParameter(const std::string &arg1)
Returns the whether the given token is an option.
static bool processNonBooleanSingleSwitch(OptionsCont &oc, const std::string &arg, const bool append)
Extracts the parameter directly attached to an option.