Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
OptionsIO.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-2026 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/****************************************************************************/
19// Helper for parsing command line arguments and reading configuration files
20/****************************************************************************/
21#include <config.h>
22
23#include <string>
24#include <iostream>
25#include <cstdlib>
26#include <cstring>
27#include <xercesc/framework/XMLPScanToken.hpp>
28#include <xercesc/parsers/SAXParser.hpp>
29#include <xercesc/sax/HandlerBase.hpp>
30#include <xercesc/sax/AttributeList.hpp>
31#include <xercesc/sax/SAXParseException.hpp>
32#include <xercesc/sax/SAXException.hpp>
33#include <xercesc/util/PlatformUtils.hpp>
34#include "OptionsIO.h"
35#include "OptionsCont.h"
36#include "OptionsLoader.h"
37#include "OptionsParser.h"
41#include <utils/xml/XMLSubSys.h>
42#ifdef HAVE_ZLIB
43#include <foreign/zstr/zstr.hpp>
44#endif
46
47
48// ===========================================================================
49// static member definitions
50// ===========================================================================
51std::vector<std::string> OptionsIO::myArgs;
52std::chrono::time_point<std::chrono::system_clock> OptionsIO::myLoadTime;
53
54
55// ===========================================================================
56// method definitions
57// ===========================================================================
58void
59OptionsIO::setArgs(int argc, char** argv) {
60 myArgs.clear();
61 for (int i = 0; i < argc; i++) {
62 myArgs.push_back(XMLSubSys::transcodeFromLocal(argv[i]));
63 }
64}
65
66
67void
68OptionsIO::setArgs(const std::vector<std::string>& args) {
69 myArgs.resize(1); // will insert an empty string if no first element is there
70 myArgs.insert(myArgs.end(), args.begin(), args.end());
71}
72
73
74void
75OptionsIO::getOptions(const bool commandLineOnly) {
76 myLoadTime = std::chrono::system_clock::now();
77 if (myArgs.size() == 2 && myArgs[1][0] != '-') {
78 // special case only one parameter, check who can handle it
79 if (OptionsCont::getOptions().setByRootElement(getRoot(myArgs[1]), myArgs[1])) {
80 if (!commandLineOnly) {
82 }
83 return;
84 }
85 }
86 // preparse the options
87 // (maybe another configuration file was chosen)
88 if (!OptionsParser::parse(myArgs, true)) {
89 throw ProcessError(TL("Could not parse commandline options."));
90 }
91 if (!commandLineOnly || OptionsCont::getOptions().isSet("save-configuration", false)) {
92 // read the configuration when everything's ok
94 }
95}
96
97
98void
101 if (oc.exists("configuration-file") && oc.isSet("configuration-file")) {
102 const std::string path = oc.getString("configuration-file");
103 if (!FileHelpers::isReadable(path)) {
104 throw ProcessError(TLF("Could not access configuration '%'.", oc.getString("configuration-file")));
105 }
106 const bool verbose = !oc.exists("verbose") || oc.getBool("verbose");
107 if (verbose) {
108 PROGRESS_BEGIN_MESSAGE(TL("Loading configuration"));
109 }
110 oc.resetWritable();
111 // build parser
112 XERCES_CPP_NAMESPACE::SAXParser parser;
113 parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
114 parser.setDisableDefaultEntityResolution(true);
115 // start the parsing
117 try {
118 parser.setDocumentHandler(&handler);
119 parser.setErrorHandler(&handler);
120 parser.parse(XMLSubSys::transcodeToLocal(path).c_str());
121 if (handler.errorOccurred()) {
122 throw ProcessError(TLF("Could not load configuration '%'.", path));
123 }
124 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
125 throw ProcessError("Could not load configuration '" + path + "':\n " + XMLSubSys::transcode(e.getMessage()));
126 }
127 oc.relocateFiles(path);
128 if (verbose) {
130 }
131 }
132 if (myArgs.size() > 2) {
133 // reparse the options (overwrite the settings from the configuration file)
134 oc.resetWritable();
136 throw ProcessError(TL("Could not parse commandline options."));
137 }
138 }
139}
140
141
142std::string
143OptionsIO::getRoot(const std::string& filename) {
144 // build parser
145 XERCES_CPP_NAMESPACE::SAXParser parser;
146 parser.setValidationScheme(XERCES_CPP_NAMESPACE::SAXParser::Val_Never);
147 parser.setDisableDefaultEntityResolution(true);
148 // start the parsing
150 try {
151 parser.setDocumentHandler(&handler);
152 parser.setErrorHandler(&handler);
153 XERCES_CPP_NAMESPACE::XMLPScanToken token;
154 if (!FileHelpers::isReadable(filename) || FileHelpers::isDirectory(filename)) {
155 throw ProcessError(TLF("Could not open '%'.", filename));
156 }
157#ifdef HAVE_ZLIB
158 zstr::ifstream istream(XMLSubSys::transcodeToLocal(filename).c_str(), std::fstream::in | std::fstream::binary);
159 IStreamInputSource inputStream(istream);
160 const bool result = parser.parseFirst(inputStream, token);
161#else
162 const bool result = parser.parseFirst(XMLSubSys::transcodeToLocal(filename).c_str(), token);
163#endif
164 if (!result) {
165 throw ProcessError(TLF("Can not read XML-file '%'.", filename));
166 }
167 while (parser.parseNext(token) && handler.getItem() == "");
168 if (handler.errorOccurred()) {
169 throw ProcessError(TLF("Could not load '%'.", filename));
170 }
171 } catch (const XERCES_CPP_NAMESPACE::XMLException& e) {
172 throw ProcessError("Could not load '" + filename + "':\n " + XMLSubSys::transcode(e.getMessage()));
173 }
174 return handler.getItem();
175}
176
177
178/****************************************************************************/
#define TL(string)
Definition MsgHandler.h:304
#define PROGRESS_DONE_MESSAGE()
Definition MsgHandler.h:291
#define TLF(string,...)
Definition MsgHandler.h:306
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition MsgHandler.h:290
static bool isReadable(std::string path)
Checks whether the given file is readable.
static bool isDirectory(std::string path)
Checks whether the given file is a directory.
Xerces InputSource reading from arbitrary std::istream.
A storage for options typed value containers)
Definition OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void resetWritable()
Resets all options to be writeable.
static OptionsCont & getOptions()
Retrieves the options.
void relocateFiles(const std::string &configuration) const
Modifies file name options according to the configuration path.
static void loadConfiguration()
Loads and parses the configuration.
Definition OptionsIO.cpp:99
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition OptionsIO.cpp:59
static void getOptions(const bool commandLineOnly=false)
Parses the command line arguments and loads the configuration.
Definition OptionsIO.cpp:75
static std::vector< std::string > myArgs
Definition OptionsIO.h:107
static std::string getRoot(const std::string &filename)
Retrieves the XML root element of a supposed configuration or net.
static std::chrono::time_point< std::chrono::system_clock > myLoadTime
Definition OptionsIO.h:108
A SAX-Handler for loading options.
const std::string & getItem() const
Returns the last item read.
bool errorOccurred() const
Returns the information whether an error occurred.
static bool parse(const std::vector< std::string > &args, const bool ignoreAppenders=false)
Parses the given command line arguments.
static std::string transcode(const XMLCh *const data, int length=-1)
converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8
static std::string transcodeToLocal(const std::string &utf8String)
convert a string from UTF-8 to the local codepage
static std::string transcodeFromLocal(const std::string &localString)
convert a string from the local codepage to UTF-8