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