Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 21197595 : Option::Option(bool set) :
45 21197595 : myAmSet(set) {
46 21197595 : }
47 :
48 :
49 21254339 : Option::~Option() {}
50 :
51 :
52 : bool
53 1653697617 : Option::isSet() const {
54 1653697617 : 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 1132504 : Option::markSet(const std::string& orig) {
96 1132504 : bool ret = myAmWritable;
97 1132504 : myHaveTheDefaultValue = false;
98 1132504 : myAmSet = true;
99 1132504 : myAmWritable = false;
100 1132504 : myValueString = orig;
101 1132504 : return ret;
102 : }
103 :
104 :
105 : const std::string&
106 12420355 : Option::getValueString() const {
107 12420355 : return myValueString;
108 : }
109 :
110 :
111 : bool
112 35368182 : Option::isDefault() const {
113 35368182 : 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 518301 : Option::isBool() const {
131 518301 : return false;
132 : }
133 :
134 :
135 : bool
136 4675266 : Option::isFileName() const {
137 4675266 : 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 1391973 : Option::isWriteable() const {
185 1391973 : return myAmWritable;
186 : }
187 :
188 :
189 : void
190 25967244 : Option::resetWritable() {
191 25967244 : myAmWritable = true;
192 25967244 : }
193 :
194 :
195 : void
196 146556 : Option::resetDefault() {
197 146556 : myHaveTheDefaultValue = true;
198 146556 : }
199 :
200 :
201 : const std::string&
202 22577 : Option::getDescription() const {
203 22577 : return myDescription;
204 : }
205 :
206 :
207 : void
208 21154024 : Option::setDescription(const std::string& desc) {
209 21154024 : myDescription = desc;
210 21154024 : }
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 : const std::string&
235 0 : Option::getListSeparator() const {
236 0 : return myListSeparator;
237 : }
238 :
239 : void
240 0 : Option::setListSeparator(const std::string& listSep) {
241 0 : myListSeparator = listSep;
242 0 : }
243 :
244 : const std::string&
245 0 : Option::getSubTopic() const {
246 0 : return mySubTopic;
247 : }
248 :
249 :
250 : void
251 21154024 : Option::setSubtopic(const std::string& subtopic) {
252 21154024 : mySubTopic = subtopic;
253 21154024 : }
254 :
255 :
256 : const std::string&
257 43041 : Option::getTypeName() const {
258 43041 : return myTypeName;
259 : }
260 :
261 : // -------------------------------------------------------------------------
262 : // Option_Integer - methods
263 : // -------------------------------------------------------------------------
264 :
265 1162862 : Option_Integer::Option_Integer(int value) :
266 : Option(true),
267 1162862 : myValue(value) {
268 1162862 : myTypeName = "INT";
269 1162862 : myValueString = toString(value);
270 1162862 : }
271 :
272 :
273 : int
274 2133137 : Option_Integer::getInt() const {
275 2133137 : return myValue;
276 : }
277 :
278 :
279 : bool
280 19466 : Option_Integer::set(const std::string& v, const std::string& orig, const bool /* append */) {
281 : try {
282 19466 : myValue = StringUtils::toInt(v);
283 19466 : return markSet(orig);
284 0 : } catch (...) {
285 0 : std::string s = "'" + v + "' is not a valid integer.";
286 0 : throw ProcessError(s);
287 0 : }
288 : }
289 :
290 :
291 : bool
292 0 : Option_Integer::isInteger() const {
293 0 : return true;
294 : }
295 :
296 : // -------------------------------------------------------------------------
297 : // Option_String - methods
298 : // -------------------------------------------------------------------------
299 :
300 371013 : Option_String::Option_String() :
301 371013 : Option() {
302 371013 : myTypeName = "STR";
303 371013 : }
304 :
305 :
306 3629270 : Option_String::Option_String(const std::string& value, std::string typeName) :
307 : Option(true),
308 3629270 : myValue(value) {
309 3629270 : myTypeName = typeName;
310 3629270 : myValueString = value;
311 3629270 : }
312 :
313 :
314 : std::string
315 9013813 : Option_String::getString() const {
316 9013813 : return myValue;
317 : }
318 :
319 :
320 : bool
321 289007 : Option_String::set(const std::string& v, const std::string& orig, const bool /* append */) {
322 289007 : myValue = v;
323 289007 : return markSet(orig);
324 : }
325 :
326 : // -------------------------------------------------------------------------
327 : // Option_Float - methods
328 : // -------------------------------------------------------------------------
329 :
330 5174065 : Option_Float::Option_Float(double value) :
331 : Option(true),
332 5174065 : myValue(value) {
333 5174065 : myTypeName = "FLOAT";
334 5174065 : std::ostringstream oss;
335 : oss << value;
336 5174065 : myValueString = oss.str();
337 5174065 : }
338 :
339 :
340 : double
341 109692132 : Option_Float::getFloat() const {
342 109692132 : return myValue;
343 : }
344 :
345 :
346 : bool
347 79958 : Option_Float::set(const std::string& v, const std::string& orig, const bool /* append */) {
348 : try {
349 79958 : myValue = StringUtils::toDouble(v);
350 79946 : return markSet(orig);
351 12 : } catch (...) {
352 36 : throw ProcessError(TLF("'%' is not a valid float.", v));
353 12 : }
354 : }
355 :
356 :
357 : bool
358 0 : Option_Float::isFloat() const {
359 0 : return true;
360 : }
361 :
362 : // -------------------------------------------------------------------------
363 : // Option_Bool - methods
364 : // -------------------------------------------------------------------------
365 :
366 6357749 : Option_Bool::Option_Bool(bool value) :
367 : Option(true),
368 6357749 : myValue(value) {
369 6357749 : myTypeName = "BOOL";
370 12473862 : myValueString = value ? "true" : "false";
371 6357749 : }
372 :
373 :
374 : bool
375 121850286 : Option_Bool::getBool() const {
376 121850286 : return myValue;
377 : }
378 :
379 :
380 : bool
381 346775 : Option_Bool::set(const std::string& v, const std::string& orig, const bool /* append */) {
382 : try {
383 346775 : myValue = StringUtils::toBool(v);
384 346769 : return markSet(orig);
385 6 : } catch (...) {
386 18 : throw ProcessError(TLF("'%' is not a valid bool.", v));
387 6 : }
388 : }
389 :
390 :
391 : bool
392 277736 : Option_Bool::isBool() const {
393 277736 : return true;
394 : }
395 :
396 : // -------------------------------------------------------------------------
397 : // Option_BoolExtended - methods
398 : // -------------------------------------------------------------------------
399 :
400 58465 : Option_BoolExtended::Option_BoolExtended(bool value) :
401 58465 : Option_Bool(value) {
402 58465 : }
403 :
404 :
405 : bool
406 83 : Option_BoolExtended::set(const std::string& v, const std::string& orig, const bool /* append */) {
407 : try {
408 83 : myValue = StringUtils::toBool(v);
409 166 : return markSet("");
410 0 : } catch (...) {
411 0 : myValue = true;
412 0 : }
413 0 : return markSet(orig);
414 : }
415 :
416 : // -------------------------------------------------------------------------
417 : // Option_IntVector - methods
418 : // -------------------------------------------------------------------------
419 :
420 0 : Option_IntVector::Option_IntVector() :
421 0 : Option() {
422 0 : myTypeName = "INT[]";
423 0 : }
424 :
425 :
426 0 : Option_IntVector::Option_IntVector(const IntVector& value)
427 0 : : Option(true), myValue(value) {
428 0 : myTypeName = "INT[]";
429 0 : myValueString = joinToString(value, ",");
430 0 : }
431 :
432 :
433 : const IntVector&
434 0 : Option_IntVector::getIntVector() const {
435 0 : return myValue;
436 : }
437 :
438 :
439 : bool
440 0 : Option_IntVector::set(const std::string& v, const std::string& orig, const bool append) {
441 0 : if (!append) {
442 : myValue.clear();
443 : }
444 : try {
445 0 : if (v.find(';') != std::string::npos) {
446 0 : WRITE_WARNING(TL("Please note that using ';' as list separator is deprecated and not accepted anymore."));
447 : }
448 0 : StringTokenizer st(v, ",", true);
449 0 : while (st.hasNext()) {
450 0 : myValue.push_back(StringUtils::toInt(st.next()));
451 : }
452 0 : return markSet(orig);
453 0 : } catch (EmptyData&) {
454 0 : throw ProcessError("Empty element occurred in " + v);
455 0 : } catch (...) {
456 0 : throw ProcessError(TLF("'%' is not a valid integer vector.", v));
457 0 : }
458 : }
459 :
460 : // -------------------------------------------------------------------------
461 : // Option_StringVector - methods
462 : // -------------------------------------------------------------------------
463 :
464 4254759 : Option_StringVector::Option_StringVector() :
465 4254759 : Option() {
466 4254759 : myTypeName = "STR[]";
467 4254759 : }
468 :
469 :
470 247877 : Option_StringVector::Option_StringVector(const StringVector& value) :
471 247877 : Option(true), myValue(value) {
472 247877 : myTypeName = "STR[]";
473 247877 : myValueString = joinToString(value, ",");
474 247877 : }
475 :
476 :
477 : const StringVector&
478 19290654 : Option_StringVector::getStringVector() const {
479 19290654 : return myValue;
480 : }
481 :
482 :
483 : bool
484 397233 : Option_StringVector::set(const std::string& v, const std::string& orig, const bool append) {
485 397233 : if (!append) {
486 : myValue.clear();
487 : }
488 1191699 : StringTokenizer st(v, ",");
489 820858 : while (st.hasNext()) {
490 847250 : myValue.push_back(StringUtils::prune(st.next()));
491 : }
492 1588932 : return markSet(append && getValueString() != "" ? getValueString() + "," + orig : orig);
493 397233 : }
494 :
495 : // -------------------------------------------------------------------------
496 : // Option_FileName - methods
497 : // -------------------------------------------------------------------------
498 :
499 2731477 : Option_FileName::Option_FileName() :
500 2731477 : Option_StringVector() {
501 2731477 : myTypeName = "FILE";
502 2731477 : }
503 :
504 :
505 100107 : Option_FileName::Option_FileName(const StringVector& value) :
506 100107 : Option_StringVector(value) {
507 100107 : myTypeName = "FILE";
508 100107 : }
509 :
510 :
511 : bool
512 924678 : Option_FileName::isFileName() const {
513 924678 : return true;
514 : }
515 :
516 :
517 : std::string
518 17889770 : Option_FileName::getString() const {
519 17889770 : return joinToString(getStringVector(), ",");
520 : }
521 :
522 : // -------------------------------------------------------------------------
523 : // Option_Network - methods
524 : // -------------------------------------------------------------------------
525 :
526 0 : Option_Network::Option_Network(const std::string& value) :
527 0 : Option_String(value, "NETWORK") {
528 0 : }
529 :
530 :
531 0 : bool Option_Network::isNetwork() const {
532 0 : return true;
533 : }
534 :
535 : // -------------------------------------------------------------------------
536 : // Option_Additional - methods
537 : // -------------------------------------------------------------------------
538 :
539 0 : Option_Additional::Option_Additional(const std::string& value) :
540 0 : Option_String(value, "ADDITIONAL") {
541 0 : }
542 :
543 :
544 : bool
545 0 : Option_Additional::isAdditional() const {
546 0 : return true;
547 : }
548 :
549 : // -------------------------------------------------------------------------
550 : // Option_Route - methods
551 : // -------------------------------------------------------------------------
552 :
553 0 : Option_Route::Option_Route(const std::string& value) :
554 0 : Option_String(value, "ROUTE") {
555 0 : }
556 :
557 :
558 : bool
559 0 : Option_Route::isRoute() const {
560 0 : return true;
561 : }
562 :
563 : // -------------------------------------------------------------------------
564 : // Option_Data - methods
565 : // -------------------------------------------------------------------------
566 :
567 0 : Option_Data::Option_Data(const std::string& value) :
568 0 : Option_String(value, "DATA") {
569 0 : }
570 :
571 :
572 : bool
573 0 : Option_Data::isData() const {
574 0 : return true;
575 : }
576 :
577 : // -------------------------------------------------------------------------
578 : // Option_Data - methods
579 : // -------------------------------------------------------------------------
580 :
581 0 : Option_SumoConfig::Option_SumoConfig(const std::string& value) :
582 0 : Option_String(value, "SUMOCONFIG") {
583 0 : }
584 :
585 :
586 : bool
587 0 : Option_SumoConfig::isSumoConfig() const {
588 0 : return true;
589 : }
590 :
591 : // -------------------------------------------------------------------------
592 : // Option_Data - methods
593 : // -------------------------------------------------------------------------
594 :
595 0 : Option_Edge::Option_Edge(const std::string& value) :
596 0 : Option_String(value, "EDGE") {
597 0 : }
598 :
599 :
600 : bool
601 0 : Option_Edge::isEdge() const {
602 0 : return true;
603 : }
604 :
605 : // -------------------------------------------------------------------------
606 : // Option_Data - methods
607 : // -------------------------------------------------------------------------
608 :
609 0 : Option_EdgeVector::Option_EdgeVector(const std::string& value) :
610 0 : Option_String(value, "EDGE[]") {
611 0 : }
612 :
613 :
614 : bool
615 0 : Option_EdgeVector::isEdgeVector() const {
616 0 : return true;
617 : }
618 :
619 : /****************************************************************************/
|