Eclipse SUMO - Simulation of Urban MObility
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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-2025 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/****************************************************************************/
21// Parses the command line arguments
22/****************************************************************************/
23#include <config.h>
24
25#include <iostream>
26#include <cstring>
27#include "Option.h"
28#include "OptionsCont.h"
29#include "OptionsParser.h"
32
33
34// ===========================================================================
35// method definitions
36// ===========================================================================
37bool
38OptionsParser::parse(const std::vector<std::string>& args, const bool ignoreAppenders) {
39 bool ok = true;
40 const int argc = (int)args.size();
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(args[i], &args[i + 1], ok, ignoreAppenders);
47 } else {
48 add = check(args[i], nullptr, ok, ignoreAppenders);
49 }
50 i += add;
51 } catch (ProcessError& e) {
52 WRITE_ERROR("On processing option '" + args[i] + "':\n " + e.what());
53 i++;
54 ok = false;
55 }
56 }
57 return ok;
58}
59
60
61int
62OptionsParser::check(const std::string& arg1, const std::string* const arg2, bool& ok, const bool ignoreAppenders) {
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
70#ifdef _DEBUG
71 // allow to set FOX FXApp switches tracelevel (messages) and maxcolors
72 if ((arg1 == "-tracelevel" || arg1 == "-maxcolors") && arg2 != nullptr) {
73 ok = true;
74 return 2;
75 }
76#endif
77
79 const bool append = arg1[0] == '+';
80 // process not abbreviated switches
81 if (append || arg1[1] == '-') {
82 const std::string tmp(arg1.substr(append ? 1 : 2));
83 const std::string::size_type idx1 = tmp.find('=');
84 if (append && ignoreAppenders) {
85 return idx1 == std::string::npos ? 2 : 1;
86 }
87 // check whether a parameter was submitted
88 if (idx1 != std::string::npos) {
89 ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1), append);
90 } else {
91 if (arg2 == nullptr || (oc.isBool(tmp) && (*arg2)[0] == '-')) {
92 ok &= oc.set(tmp, "true");
93 } else {
94 ok &= oc.set(tmp, *arg2, append);
95 return 2;
96 }
97 }
98 return 1;
99 }
100 // go through the abbreviated switches
101 const int len = (int)arg1.size();
102 for (int i = 1; i < len; i++) {
103 // set boolean switches
104 const std::string abbr = arg1.substr(i, 1);
105 if (oc.isBool(abbr)) {
106 if (arg2 == nullptr || (*arg2)[0] == '-' || i != len - 1) {
107 ok &= oc.set(abbr, "true");
108 } else {
109 ok &= oc.set(abbr, *arg2);
110 return 2;
111 }
112 // set non-boolean switches
113 } else {
114 // check whether the parameter comes directly after the switch
115 // and process if so
116 if (arg2 == nullptr || i != len - 1) {
117 ok &= processNonBooleanSingleSwitch(oc, arg1.substr(i), append);
118 return 1;
119 // process parameter following after a space
120 } else {
121 ok &= oc.set(abbr, *arg2, append);
122 // option name and attribute were in two arguments
123 return 2;
124 }
125 }
126 }
127 // all switches within the current argument were boolean switches
128 return 1;
129}
130
131
132bool
133OptionsParser::processNonBooleanSingleSwitch(OptionsCont& oc, const std::string& arg, const bool append) {
134 if (arg[1] == '=') {
135 if (arg.size() < 3) {
136 WRITE_ERRORF(TL("Missing value for parameter '%'."), arg.substr(0, 1));
137 return false;
138 } else {
139 return oc.set(arg.substr(0, 1), arg.substr(2), append);
140 }
141 } else {
142 if (arg.size() < 2) {
143 WRITE_ERRORF(TL("Missing value for parameter '%'."), arg);
144 return false;
145 } else {
146 return oc.set(arg.substr(0, 1), arg.substr(1), append);
147 }
148 }
149}
150
151
152bool
153OptionsParser::checkParameter(const std::string& arg1) {
154 if (arg1[0] != '-' && arg1[0] != '+') {
155 WRITE_ERRORF(TL("The parameter '%' is not allowed in this context.\n Switch or parameter name expected."), arg1);
156 return false;
157 }
158 if ((arg1[0] == '-' && arg1[1] == '+') || (arg1[0] == '+' && arg1[1] == '-')) {
159 WRITE_ERRORF(TL("Mixed parameter syntax in '%'."), arg1);
160 return false;
161 }
162 return true;
163}
164
165
166/****************************************************************************/
#define WRITE_ERRORF(...)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:296
#define TL(string)
Definition MsgHandler.h:305
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.
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.