Line data Source code
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 Option.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Mon, 17 Dec 2001
19 : ///
20 : // A class representing a single program option
21 : /****************************************************************************/
22 : #include <config.h>
23 :
24 : #include <string>
25 : #include <exception>
26 : #include <sstream>
27 : #include "Option.h"
28 : #include <utils/common/StringUtils.h>
29 : #include <utils/common/UtilExceptions.h>
30 : #include <utils/common/StringTokenizer.h>
31 : #include <utils/common/StringUtils.h>
32 : #include <utils/common/MsgHandler.h>
33 : #include <utils/common/ToString.h>
34 :
35 :
36 : // ===========================================================================
37 : // method definitions
38 : // ===========================================================================
39 :
40 : // -------------------------------------------------------------------------
41 : // Option - methods
42 : // -------------------------------------------------------------------------
43 :
44 20419043 : Option::Option(bool set) :
45 20419043 : myAmSet(set) {
46 20419043 : }
47 :
48 :
49 20481135 : Option::~Option() {}
50 :
51 :
52 : bool
53 997002498 : Option::isSet() const {
54 997002498 : return myAmSet;
55 : }
56 :
57 :
58 : double
59 0 : Option::getFloat() const {
60 0 : throw InvalidArgument("This is not a double-option");
61 : }
62 :
63 :
64 : int
65 0 : Option::getInt() const {
66 0 : throw InvalidArgument("This is not an int-option");
67 : }
68 :
69 :
70 : std::string
71 0 : Option::getString() const {
72 0 : throw InvalidArgument("This is not a string-option");
73 : }
74 :
75 :
76 : bool
77 0 : Option::getBool() const {
78 0 : throw InvalidArgument("This is not a bool-option");
79 : }
80 :
81 :
82 : const IntVector&
83 0 : Option::getIntVector() const {
84 0 : throw InvalidArgument("This is not an int vector-option");
85 : }
86 :
87 :
88 : const StringVector&
89 0 : Option::getStringVector() const {
90 0 : throw InvalidArgument("This is not a string vector-option");
91 : }
92 :
93 :
94 : bool
95 1024354 : Option::markSet(const std::string& orig) {
96 1024354 : bool ret = myAmWritable;
97 1024354 : myHaveTheDefaultValue = false;
98 1024354 : myAmSet = true;
99 1024354 : myAmWritable = false;
100 1024354 : myValueString = orig;
101 1024354 : return ret;
102 : }
103 :
104 :
105 : const std::string&
106 15766489 : Option::getValueString() const {
107 15766489 : return myValueString;
108 : }
109 :
110 :
111 : bool
112 40053634 : Option::isDefault() const {
113 40053634 : return myHaveTheDefaultValue;
114 : }
115 :
116 :
117 : bool
118 0 : Option::isInteger() const {
119 0 : return false;
120 : }
121 :
122 :
123 : bool
124 0 : Option::isFloat() const {
125 0 : return false;
126 : }
127 :
128 :
129 : bool
130 465381 : Option::isBool() const {
131 465381 : return false;
132 : }
133 :
134 :
135 : bool
136 5401172 : Option::isFileName() const {
137 5401172 : return false;
138 : }
139 :
140 :
141 : bool
142 0 : Option::isNetwork() const {
143 0 : return false;
144 : }
145 :
146 :
147 : bool
148 0 : Option::isAdditional() const {
149 0 : return false;
150 : }
151 :
152 :
153 : bool
154 0 : Option::isRoute() const {
155 0 : return false;
156 : }
157 :
158 :
159 : bool
160 0 : Option::isData() const {
161 0 : return false;
162 : }
163 :
164 :
165 : bool
166 0 : Option::isSumoConfig() const {
167 0 : return false;
168 : }
169 :
170 :
171 : bool
172 0 : Option::isEdge() const {
173 0 : return false;
174 : }
175 :
176 :
177 : bool
178 0 : Option::isEdgeVector() const {
179 0 : return false;
180 : }
181 :
182 :
183 : bool
184 1248395 : Option::isWriteable() const {
185 1248395 : return myAmWritable;
186 : }
187 :
188 :
189 : void
190 25931406 : Option::resetWritable() {
191 25931406 : myAmWritable = true;
192 25931406 : }
193 :
194 :
195 : void
196 135858 : Option::resetDefault() {
197 135858 : myHaveTheDefaultValue = true;
198 135858 : }
199 :
200 :
201 : const std::string&
202 20163301 : Option::getDescription() const {
203 20163301 : return myDescription;
204 : }
205 :
206 :
207 : void
208 40516155 : Option::setDescription(const std::string& desc) {
209 40516155 : myDescription = desc;
210 40516155 : }
211 :
212 :
213 : bool
214 0 : Option::isRequired() const {
215 0 : return myRequired;
216 : }
217 :
218 :
219 : void
220 0 : Option::setRequired() {
221 0 : myRequired = true;
222 0 : }
223 :
224 : bool
225 0 : Option::isPositional() const {
226 0 : return myPositional;
227 : }
228 :
229 : void
230 0 : Option::setPositional() {
231 0 : myPositional = true;
232 0 : }
233 :
234 :
235 : bool
236 0 : Option::isEditable() const {
237 0 : return myEditable;
238 : }
239 :
240 :
241 0 : void Option::setEditable(const bool value) {
242 0 : myEditable = value;
243 0 : }
244 :
245 :
246 : const std::string&
247 0 : Option::getListSeparator() const {
248 0 : return myListSeparator;
249 : }
250 :
251 : void
252 0 : Option::setListSeparator(const std::string& listSep) {
253 0 : myListSeparator = listSep;
254 0 : }
255 :
256 : const std::string&
257 0 : Option::getSubTopic() const {
258 0 : return mySubTopic;
259 : }
260 :
261 :
262 : void
263 20378330 : Option::setSubtopic(const std::string& subtopic) {
264 20378330 : mySubTopic = subtopic;
265 20378330 : }
266 :
267 :
268 : const std::string&
269 47813 : Option::getTypeName() const {
270 47813 : return myTypeName;
271 : }
272 :
273 : // -------------------------------------------------------------------------
274 : // Option_Integer - methods
275 : // -------------------------------------------------------------------------
276 :
277 1067205 : Option_Integer::Option_Integer(int value) :
278 : Option(true),
279 1067205 : myValue(value) {
280 1067205 : myTypeName = "INT";
281 1067205 : myValueString = toString(value);
282 1067205 : }
283 :
284 :
285 : int
286 2123182 : Option_Integer::getInt() const {
287 2123182 : return myValue;
288 : }
289 :
290 :
291 : bool
292 30898 : Option_Integer::set(const std::string& v, const std::string& orig, const bool /* append */) {
293 : try {
294 30898 : myValue = StringUtils::toInt(v);
295 30898 : return markSet(orig);
296 0 : } catch (...) {
297 0 : std::string s = "'" + v + "' is not a valid integer.";
298 0 : throw ProcessError(s);
299 0 : }
300 : }
301 :
302 :
303 : bool
304 0 : Option_Integer::isInteger() const {
305 0 : return true;
306 : }
307 :
308 : // -------------------------------------------------------------------------
309 : // Option_String - methods
310 : // -------------------------------------------------------------------------
311 :
312 419564 : Option_String::Option_String() :
313 419564 : Option() {
314 419564 : myTypeName = "STR";
315 419564 : }
316 :
317 :
318 3698542 : Option_String::Option_String(const std::string& value, std::string typeName) :
319 : Option(true),
320 3698542 : myValue(value) {
321 3698542 : myTypeName = typeName;
322 3698542 : myValueString = value;
323 3698542 : }
324 :
325 :
326 : std::string
327 7992947 : Option_String::getString() const {
328 7992947 : return myValue;
329 : }
330 :
331 :
332 : bool
333 265597 : Option_String::set(const std::string& v, const std::string& orig, const bool /* append */) {
334 265597 : myValue = v;
335 265597 : return markSet(orig);
336 : }
337 :
338 : // -------------------------------------------------------------------------
339 : // Option_Float - methods
340 : // -------------------------------------------------------------------------
341 :
342 4929374 : Option_Float::Option_Float(double value) :
343 : Option(true),
344 4929374 : myValue(value) {
345 4929374 : myTypeName = "FLOAT";
346 4929374 : std::ostringstream oss;
347 : oss << value;
348 4929374 : myValueString = oss.str();
349 4929374 : }
350 :
351 :
352 : double
353 112522736 : Option_Float::getFloat() const {
354 112522736 : return myValue;
355 : }
356 :
357 :
358 : bool
359 84113 : Option_Float::set(const std::string& v, const std::string& orig, const bool /* append */) {
360 : try {
361 84113 : myValue = StringUtils::toDouble(v);
362 84101 : return markSet(orig);
363 12 : } catch (...) {
364 36 : throw ProcessError(TLF("'%' is not a valid float.", v));
365 12 : }
366 : }
367 :
368 :
369 : bool
370 0 : Option_Float::isFloat() const {
371 0 : return true;
372 : }
373 :
374 : // -------------------------------------------------------------------------
375 : // Option_Bool - methods
376 : // -------------------------------------------------------------------------
377 :
378 6064636 : Option_Bool::Option_Bool(bool value) :
379 : Option(true),
380 6064636 : myValue(value) {
381 6064636 : myTypeName = "BOOL";
382 11814742 : myValueString = value ? "true" : "false";
383 6064636 : }
384 :
385 :
386 : bool
387 125514353 : Option_Bool::getBool() const {
388 125514353 : return myValue;
389 : }
390 :
391 :
392 : bool
393 309256 : Option_Bool::set(const std::string& v, const std::string& orig, const bool /* append */) {
394 : try {
395 309256 : myValue = StringUtils::toBool(v);
396 309250 : return markSet(orig);
397 6 : } catch (...) {
398 18 : throw ProcessError(TLF("'%' is not a valid bool.", v));
399 6 : }
400 : }
401 :
402 :
403 : bool
404 261265 : Option_Bool::isBool() const {
405 261265 : return true;
406 : }
407 :
408 : // -------------------------------------------------------------------------
409 : // Option_BoolExtended - methods
410 : // -------------------------------------------------------------------------
411 :
412 50525 : Option_BoolExtended::Option_BoolExtended(bool value) :
413 50525 : Option_Bool(value) {
414 50525 : }
415 :
416 :
417 : bool
418 85 : Option_BoolExtended::set(const std::string& v, const std::string& orig, const bool /* append */) {
419 : try {
420 85 : myValue = StringUtils::toBool(v);
421 170 : return markSet("");
422 0 : } catch (...) {
423 0 : myValue = true;
424 0 : }
425 0 : return markSet(orig);
426 : }
427 :
428 : // -------------------------------------------------------------------------
429 : // Option_IntVector - methods
430 : // -------------------------------------------------------------------------
431 :
432 0 : Option_IntVector::Option_IntVector() :
433 0 : Option() {
434 0 : myTypeName = "INT[]";
435 0 : }
436 :
437 :
438 0 : Option_IntVector::Option_IntVector(const IntVector& value)
439 0 : : Option(true), myValue(value) {
440 0 : myTypeName = "INT[]";
441 0 : myValueString = joinToString(value, ",");
442 0 : }
443 :
444 :
445 : const IntVector&
446 0 : Option_IntVector::getIntVector() const {
447 0 : return myValue;
448 : }
449 :
450 :
451 : bool
452 0 : Option_IntVector::set(const std::string& v, const std::string& orig, const bool append) {
453 0 : if (!append) {
454 : myValue.clear();
455 : }
456 : try {
457 0 : if (v.find(';') != std::string::npos) {
458 0 : WRITE_WARNING(TL("Please note that using ';' as list separator is deprecated and not accepted anymore."));
459 : }
460 0 : StringTokenizer st(v, ",", true);
461 0 : while (st.hasNext()) {
462 0 : myValue.push_back(StringUtils::toInt(st.next()));
463 : }
464 0 : return markSet(orig);
465 0 : } catch (EmptyData&) {
466 0 : throw ProcessError("Empty element occurred in " + v);
467 0 : } catch (...) {
468 0 : throw ProcessError(TLF("'%' is not a valid integer vector.", v));
469 0 : }
470 : }
471 :
472 : // -------------------------------------------------------------------------
473 : // Option_StringVector - methods
474 : // -------------------------------------------------------------------------
475 :
476 3970811 : Option_StringVector::Option_StringVector() :
477 3970811 : Option() {
478 3970811 : myTypeName = "STR[]";
479 3970811 : }
480 :
481 :
482 268911 : Option_StringVector::Option_StringVector(const StringVector& value) :
483 268911 : Option(true), myValue(value) {
484 268911 : myTypeName = "STR[]";
485 268911 : myValueString = joinToString(value, ",");
486 268911 : }
487 :
488 :
489 : const StringVector&
490 22182139 : Option_StringVector::getStringVector() const {
491 22182139 : return myValue;
492 : }
493 :
494 :
495 : bool
496 334423 : Option_StringVector::set(const std::string& v, const std::string& orig, const bool append) {
497 334423 : if (!append) {
498 : myValue.clear();
499 : }
500 1003269 : StringTokenizer st(v, ",");
501 698683 : while (st.hasNext()) {
502 728520 : myValue.push_back(StringUtils::prune(st.next()));
503 : }
504 1337692 : return markSet(append && getValueString() != "" ? getValueString() + "," + orig : orig);
505 334423 : }
506 :
507 : // -------------------------------------------------------------------------
508 : // Option_FileName - methods
509 : // -------------------------------------------------------------------------
510 :
511 2538517 : Option_FileName::Option_FileName() :
512 2538517 : Option_StringVector() {
513 2538517 : myTypeName = "FILE";
514 2538517 : }
515 :
516 :
517 89738 : Option_FileName::Option_FileName(const StringVector& value) :
518 89738 : Option_StringVector(value) {
519 89738 : myTypeName = "FILE";
520 89738 : }
521 :
522 :
523 : bool
524 1032307 : Option_FileName::isFileName() const {
525 1032307 : return true;
526 : }
527 :
528 :
529 : std::string
530 21506310 : Option_FileName::getString() const {
531 21506310 : return joinToString(getStringVector(), ",");
532 : }
533 :
534 : // -------------------------------------------------------------------------
535 : // Option_Network - methods
536 : // -------------------------------------------------------------------------
537 :
538 0 : Option_Network::Option_Network(const std::string& value) :
539 0 : Option_String(value, "NETWORK") {
540 0 : }
541 :
542 :
543 0 : bool Option_Network::isNetwork() const {
544 0 : return true;
545 : }
546 :
547 : // -------------------------------------------------------------------------
548 : // Option_Additional - methods
549 : // -------------------------------------------------------------------------
550 :
551 0 : Option_Additional::Option_Additional(const std::string& value) :
552 0 : Option_String(value, "ADDITIONAL") {
553 0 : }
554 :
555 :
556 : bool
557 0 : Option_Additional::isAdditional() const {
558 0 : return true;
559 : }
560 :
561 : // -------------------------------------------------------------------------
562 : // Option_Route - methods
563 : // -------------------------------------------------------------------------
564 :
565 0 : Option_Route::Option_Route(const std::string& value) :
566 0 : Option_String(value, "ROUTE") {
567 0 : }
568 :
569 :
570 : bool
571 0 : Option_Route::isRoute() const {
572 0 : return true;
573 : }
574 :
575 : // -------------------------------------------------------------------------
576 : // Option_Data - methods
577 : // -------------------------------------------------------------------------
578 :
579 0 : Option_Data::Option_Data(const std::string& value) :
580 0 : Option_String(value, "DATA") {
581 0 : }
582 :
583 :
584 : bool
585 0 : Option_Data::isData() const {
586 0 : return true;
587 : }
588 :
589 : // -------------------------------------------------------------------------
590 : // Option_Data - methods
591 : // -------------------------------------------------------------------------
592 :
593 0 : Option_SumoConfig::Option_SumoConfig(const std::string& value) :
594 0 : Option_String(value, "SUMOCONFIG") {
595 0 : }
596 :
597 :
598 : bool
599 0 : Option_SumoConfig::isSumoConfig() const {
600 0 : return true;
601 : }
602 :
603 : // -------------------------------------------------------------------------
604 : // Option_Data - methods
605 : // -------------------------------------------------------------------------
606 :
607 0 : Option_Edge::Option_Edge(const std::string& value) :
608 0 : Option_String(value, "EDGE") {
609 0 : }
610 :
611 :
612 : bool
613 0 : Option_Edge::isEdge() const {
614 0 : return true;
615 : }
616 :
617 : // -------------------------------------------------------------------------
618 : // Option_Data - methods
619 : // -------------------------------------------------------------------------
620 :
621 0 : Option_EdgeVector::Option_EdgeVector(const std::string& value) :
622 0 : Option_String(value, "EDGE[]") {
623 0 : }
624 :
625 :
626 : bool
627 0 : Option_EdgeVector::isEdgeVector() const {
628 0 : return true;
629 : }
630 :
631 : /****************************************************************************/
|