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 20784660 : Option::Option(bool set) :
45 20784660 : myAmSet(set) {
46 20784660 : }
47 :
48 :
49 20784660 : Option::~Option() {}
50 :
51 :
52 : bool
53 1668693295 : Option::isSet() const {
54 1668693295 : 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 1121263 : Option::markSet(const std::string& orig) {
96 1121263 : bool ret = myAmWritable;
97 1121263 : myHaveTheDefaultValue = false;
98 1121263 : myAmSet = true;
99 1121263 : myAmWritable = false;
100 1121263 : myValueString = orig;
101 1121263 : return ret;
102 : }
103 :
104 :
105 : const std::string&
106 61849060 : Option::getValueString() const {
107 61849060 : return myValueString;
108 : }
109 :
110 :
111 : bool
112 28086272 : Option::isDefault() const {
113 28086272 : 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 512869 : Option::isBool() const {
131 512869 : return false;
132 : }
133 :
134 :
135 : bool
136 4513042 : Option::isFileName() const {
137 4513042 : 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 1378276 : Option::isWriteable() const {
185 1378276 : return myAmWritable;
186 : }
187 :
188 :
189 : void
190 25473671 : Option::resetWritable() {
191 25473671 : myAmWritable = true;
192 25473671 : }
193 :
194 :
195 : void
196 144954 : Option::resetDefault() {
197 144954 : myHaveTheDefaultValue = true;
198 144954 : }
199 :
200 :
201 : const std::string&
202 21846 : Option::getDescription() const {
203 21846 : return myDescription;
204 : }
205 :
206 :
207 : void
208 20784660 : Option::setDescription(const std::string& desc) {
209 20784660 : myDescription = desc;
210 20784660 : }
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 20784660 : Option::setSubtopic(const std::string& subtopic) {
252 20784660 : mySubTopic = subtopic;
253 20784660 : }
254 :
255 :
256 : const std::string&
257 41397 : Option::getTypeName() const {
258 41397 : return myTypeName;
259 : }
260 :
261 : // -------------------------------------------------------------------------
262 : // Option_Integer - methods
263 : // -------------------------------------------------------------------------
264 :
265 1151246 : Option_Integer::Option_Integer(int value) :
266 : Option(true),
267 1151246 : myValue(value) {
268 1151246 : myTypeName = "INT";
269 1151246 : myValueString = toString(value);
270 1151246 : }
271 :
272 :
273 : int
274 2082125 : Option_Integer::getInt() const {
275 2082125 : return myValue;
276 : }
277 :
278 :
279 : bool
280 19296 : Option_Integer::set(const std::string& v, const std::string& orig, const bool /* append */) {
281 : try {
282 19296 : myValue = StringUtils::toInt(v);
283 19296 : 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 366698 : Option_String::Option_String() :
301 366698 : Option() {
302 366698 : myTypeName = "STR";
303 366698 : }
304 :
305 :
306 3495212 : Option_String::Option_String(const std::string& value, std::string typeName) :
307 : Option(true),
308 3495212 : myValue(value) {
309 3495212 : myTypeName = typeName;
310 3495212 : myValueString = value;
311 3495212 : }
312 :
313 :
314 : std::string
315 8787515 : Option_String::getString() const {
316 8787515 : return myValue;
317 : }
318 :
319 :
320 : bool
321 286770 : Option_String::set(const std::string& v, const std::string& orig, const bool /* append */) {
322 286770 : myValue = v;
323 286770 : return markSet(orig);
324 : }
325 :
326 : // -------------------------------------------------------------------------
327 : // Option_Float - methods
328 : // -------------------------------------------------------------------------
329 :
330 5024161 : Option_Float::Option_Float(double value) :
331 : Option(true),
332 5024161 : myValue(value) {
333 5024161 : myTypeName = "FLOAT";
334 5024161 : std::ostringstream oss;
335 : oss << value;
336 5024161 : myValueString = oss.str();
337 5024161 : }
338 :
339 :
340 : double
341 108989990 : Option_Float::getFloat() const {
342 108989990 : return myValue;
343 : }
344 :
345 :
346 : bool
347 79307 : Option_Float::set(const std::string& v, const std::string& orig, const bool /* append */) {
348 : try {
349 79307 : myValue = StringUtils::toDouble(v);
350 79295 : 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 6291642 : Option_Bool::Option_Bool(bool value) :
367 : Option(true),
368 6291642 : myValue(value) {
369 6291642 : myTypeName = "BOOL";
370 12346134 : myValueString = value ? "true" : "false";
371 6291642 : }
372 :
373 :
374 : bool
375 121356165 : Option_Bool::getBool() const {
376 121356165 : return myValue;
377 : }
378 :
379 :
380 : bool
381 343349 : Option_Bool::set(const std::string& v, const std::string& orig, const bool /* append */) {
382 : try {
383 343349 : myValue = StringUtils::toBool(v);
384 343343 : 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 274716 : Option_Bool::isBool() const {
393 274716 : return true;
394 : }
395 :
396 : // -------------------------------------------------------------------------
397 : // Option_BoolExtended - methods
398 : // -------------------------------------------------------------------------
399 :
400 57923 : Option_BoolExtended::Option_BoolExtended(bool value) :
401 57923 : Option_Bool(value) {
402 57923 : }
403 :
404 :
405 : bool
406 81 : Option_BoolExtended::set(const std::string& v, const std::string& orig, const bool /* append */) {
407 : try {
408 81 : myValue = StringUtils::toBool(v);
409 162 : 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 4210326 : Option_StringVector::Option_StringVector() :
465 4210326 : Option() {
466 4210326 : myTypeName = "STR[]";
467 4210326 : }
468 :
469 :
470 245375 : Option_StringVector::Option_StringVector(const StringVector& value) :
471 245375 : Option(true), myValue(value) {
472 245375 : myTypeName = "STR[]";
473 245375 : myValueString = joinToString(value, ",");
474 245375 : }
475 :
476 :
477 : const StringVector&
478 18646683 : Option_StringVector::getStringVector() const {
479 18646683 : return myValue;
480 : }
481 :
482 :
483 : bool
484 392478 : Option_StringVector::set(const std::string& v, const std::string& orig, const bool append) {
485 392478 : if (!append) {
486 : myValue.clear();
487 : }
488 1177434 : StringTokenizer st(v, ",");
489 803743 : while (st.hasNext()) {
490 822530 : myValue.push_back(StringUtils::prune(st.next()));
491 : }
492 1569912 : return markSet(append && getValueString() != "" ? getValueString() + "," + orig : orig);
493 392478 : }
494 :
495 : // -------------------------------------------------------------------------
496 : // Option_FileName - methods
497 : // -------------------------------------------------------------------------
498 :
499 2702986 : Option_FileName::Option_FileName() :
500 2702986 : Option_StringVector() {
501 2702986 : myTypeName = "FILE";
502 2702986 : }
503 :
504 :
505 99102 : Option_FileName::Option_FileName(const StringVector& value) :
506 99102 : Option_StringVector(value) {
507 99102 : myTypeName = "FILE";
508 99102 : }
509 :
510 :
511 : bool
512 869745 : Option_FileName::isFileName() const {
513 869745 : return true;
514 : }
515 :
516 :
517 : std::string
518 17291092 : Option_FileName::getString() const {
519 17291092 : 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 : /****************************************************************************/
|