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.org/sumo
3 // Copyright (C) 2001-2020 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(int argc, char** argv) {
38  bool ok = true;
39  for (int i = 1; i < argc;) {
40  try {
41  int add;
42  // try to set the current option
43  if (i < argc - 1) {
44  add = check(argv[i], argv[i + 1], ok);
45  } else {
46  add = check(argv[i], nullptr, ok);
47  }
48  i += add;
49  } catch (ProcessError& e) {
50  WRITE_ERROR("On processing option '" + std::string(argv[i]) + "':\n " + e.what());
51  i++;
52  ok = false;
53  }
54  }
55  return ok;
56 }
57 
58 
59 int
60 OptionsParser::check(const char* arg1, const char* arg2, bool& ok) {
61  // the first argument should be an option
62  // (only the second may be a free string)
63  if (!checkParameter(arg1)) {
64  ok = false;
65  return 1;
66  }
67 
69  // process not abbreviated switches
70  if (!isAbbreviation(arg1)) {
71  std::string tmp(arg1 + 2);
72  const std::string::size_type idx1 = tmp.find('=');
73  // check whether a parameter was submitted
74  if (idx1 != std::string::npos) {
75  ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1));
76  } else {
77  if (arg2 == nullptr || (oc.isBool(convert(arg1 + 2)) && arg2[0] == '-')) {
78  ok &= oc.set(convert(arg1 + 2), "true");
79  } else {
80  ok &= oc.set(convert(arg1 + 2), convert(arg2));
81  return 2;
82  }
83  }
84  return 1;
85  }
86  // go through the abbreviated switches
87  for (int i = 1; arg1[i] != 0; i++) {
88  // set boolean switches
89  if (oc.isBool(convert(arg1[i]))) {
90  if (arg2 == nullptr || arg2[0] == '-' || arg1[i + 1] != 0) {
91  ok &= oc.set(convert(arg1[i]), "true");
92  } else {
93  ok &= oc.set(convert(arg1[i]), convert(arg2));
94  return 2;
95  }
96  // set non-boolean switches
97  } else {
98  // check whether the parameter comes directly after the switch
99  // and process if so
100  if (arg2 == nullptr || arg1[i + 1] != 0) {
101  ok &= processNonBooleanSingleSwitch(oc, arg1 + i);
102  return 1;
103  // process parameter following after a space
104  } else {
105  ok &= oc.set(convert(arg1[i]), convert(arg2));
106  // option name and attribute were in two arguments
107  return 2;
108  }
109  }
110  }
111  // all switches within the current argument were boolean switches
112  return 1;
113 }
114 
115 
116 bool
118  if (arg[1] == '=') {
119  if (strlen(arg) < 3) {
120  WRITE_ERROR("Missing value for parameter '" + std::string(arg).substr(0, 1) + "'.");
121  return false;
122  } else {
123  return oc.set(convert(arg[0]), std::string(arg + 2));
124  }
125  } else {
126  if (strlen(arg) < 2) {
127  WRITE_ERROR("Missing value for parameter '" + std::string(arg) + "'.");
128  return false;
129  } else {
130  return oc.set(convert(arg[0]), std::string(arg + 1));
131  }
132  }
133 }
134 
135 
136 bool
137 OptionsParser::checkParameter(const char* arg1) {
138  if (arg1[0] != '-') {
139  WRITE_ERROR("The parameter '" + std::string(arg1) + "' is not allowed in this context.\n Switch or parameter name expected.");
140  return false;
141  }
142  return true;
143 }
144 
145 
146 bool
147 OptionsParser::isAbbreviation(const char* arg1) {
148  return arg1[1] != '-';
149 }
150 
151 
152 std::string
153 OptionsParser::convert(const char* arg) {
154  std::string s(arg);
155  return s;
156 }
157 
158 
159 std::string
161  char buf[2];
162  buf[0] = abbr;
163  buf[1] = 0;
164  std::string s(buf);
165  return buf;
166 }
167 
168 
169 /****************************************************************************/
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
bool isBool(const std::string &name) const
Returns the information whether the option is a boolean option.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
static std::string convert(const char *arg)
Converts char* to string.
static int check(const char *arg1, const char *arg2, bool &ok)
parses the previous arguments
static bool isAbbreviation(const char *arg1)
returns the whether the given token is an abbreviation
static bool checkParameter(const char *arg1)
Returns the whether the given token is an option.
static bool processNonBooleanSingleSwitch(OptionsCont &oc, const char *arg)
Extracts the parameter directly attached to an option.
static bool parse(int argc, char **argv)
Parses the given command line arguments.