Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/options/OptionsParser.cpp
169678 views
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
/****************************************************************************/
14
/// @file OptionsParser.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @author Mirko Barthauer
19
/// @date Mon, 17 Dec 2001
20
///
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"
30
#include <utils/common/UtilExceptions.h>
31
#include <utils/common/MsgHandler.h>
32
33
34
// ===========================================================================
35
// method definitions
36
// ===========================================================================
37
bool
38
OptionsParser::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
61
int
62
OptionsParser::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
78
OptionsCont& oc = OptionsCont::getOptions();
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
132
bool
133
OptionsParser::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
152
bool
153
OptionsParser::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
/****************************************************************************/
167
168