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-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
17 // Parses the command line arguments
18 /****************************************************************************/
19 
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <iostream>
27 #include <cstring>
28 #include "Option.h"
29 #include "OptionsCont.h"
30 #include "OptionsParser.h"
33 
34 
35 // ===========================================================================
36 // method definitions
37 // ===========================================================================
38 bool
39 OptionsParser::parse(int argc, char** argv) {
40  bool ok = true;
41  for (int i = 1; i < argc;) {
42  try {
43  int add;
44  // try to set the current option
45  if (i < argc - 1) {
46  add = check(argv[i], argv[i + 1], ok);
47  } else {
48  add = check(argv[i], nullptr, ok);
49  }
50  i += add;
51  } catch (ProcessError& e) {
52  WRITE_ERROR("On processing option '" + std::string(argv[i]) + "':\n " + e.what());
53  i++;
54  ok = false;
55  }
56  }
57  return ok;
58 }
59 
60 
61 int
62 OptionsParser::check(const char* arg1, const char* arg2, bool& ok) {
63  // the first argument should be an option
64  // (only the second may be a free string)
65  if (!checkParameter(arg1)) {
66  ok = false;
67  return 1;
68  }
69 
71  // process not abbreviated switches
72  if (!isAbbreviation(arg1)) {
73  std::string tmp(arg1 + 2);
74  const std::string::size_type idx1 = tmp.find('=');
75  // check whether a parameter was submitted
76  if (idx1 != std::string::npos) {
77  ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1));
78  } else {
79  if (arg2 == nullptr || (oc.isBool(convert(arg1 + 2)) && arg2[0] == '-')) {
80  ok &= oc.set(convert(arg1 + 2), "true");
81  } else {
82  ok &= oc.set(convert(arg1 + 2), convert(arg2));
83  return 2;
84  }
85  }
86  return 1;
87  }
88  // go through the abbreviated switches
89  for (int i = 1; arg1[i] != 0; i++) {
90  // set boolean switches
91  if (oc.isBool(convert(arg1[i]))) {
92  if (arg2 == nullptr || arg2[0] == '-' || arg1[i + 1] != 0) {
93  ok &= oc.set(convert(arg1[i]), "true");
94  } else {
95  ok &= oc.set(convert(arg1[i]), convert(arg2));
96  return 2;
97  }
98  // set non-boolean switches
99  } else {
100  // check whether the parameter comes directly after the switch
101  // and process if so
102  if (arg2 == nullptr || arg1[i + 1] != 0) {
103  ok &= processNonBooleanSingleSwitch(oc, arg1 + i);
104  return 1;
105  // process parameter following after a space
106  } else {
107  ok &= oc.set(convert(arg1[i]), convert(arg2));
108  // option name and attribute were in two arguments
109  return 2;
110  }
111  }
112  }
113  // all switches within the current argument were boolean switches
114  return 1;
115 }
116 
117 
118 bool
120  if (arg[1] == '=') {
121  if (strlen(arg) < 3) {
122  WRITE_ERROR("Missing value for parameter '" + std::string(arg).substr(0, 1) + "'.");
123  return false;
124  } else {
125  return oc.set(convert(arg[0]), std::string(arg + 2));
126  }
127  } else {
128  if (strlen(arg) < 2) {
129  WRITE_ERROR("Missing value for parameter '" + std::string(arg) + "'.");
130  return false;
131  } else {
132  return oc.set(convert(arg[0]), std::string(arg + 1));
133  }
134  }
135 }
136 
137 
138 bool
139 OptionsParser::checkParameter(const char* arg1) {
140  if (arg1[0] != '-') {
141  WRITE_ERROR("The parameter '" + std::string(arg1) + "' is not allowed in this context.\n Switch or parameter name expected.");
142  return false;
143  }
144  return true;
145 }
146 
147 
148 bool
149 OptionsParser::isAbbreviation(const char* arg1) {
150  return arg1[1] != '-';
151 }
152 
153 
154 std::string
155 OptionsParser::convert(const char* arg) {
156  std::string s(arg);
157  return s;
158 }
159 
160 
161 std::string
163  char buf[2];
164  buf[0] = abbr;
165  buf[1] = 0;
166  std::string s(buf);
167  return buf;
168 }
169 
170 
171 
172 /****************************************************************************/
173 
static int check(const char *arg1, const char *arg2, bool &ok)
parses the previous arguments
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 OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
static bool parse(int argc, char **argv)
Parses the given command line arguments.
bool isBool(const std::string &name) const
Returns the information whether the option is a boolean option.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
static bool isAbbreviation(const char *arg1)
returns the whether the given token is an abbreviation
A storage for options typed value containers)
Definition: OptionsCont.h:92
static std::string convert(const char *arg)
Converts char* to string.