68 myCopyrightNotices.push_back(
TL(
"Copyright (C) 2001-2026 German Aerospace Center (DLR) and others; https://sumo.dlr.de"));
85 throw ProcessError(name +
" is an already used option name.");
88 bool isSynonym =
false;
90 if (addresse.second == o) {
114 throw ProcessError(
"Neither the option '" + name1 +
"' nor the option '" + name2 +
"' is known yet");
117 if ((*i1).second == (*i2).second) {
120 throw ProcessError(
"Both options '" + name1 +
"' and '" + name2 +
"' do exist and differ.");
153 if (failOnNonExistant) {
154 throw ProcessError(
TLF(
"Internal request for unknown option '%'!", name));
159 return (*i).second->isSet();
169 return (*i).second->isDefault();
175 const auto& valuesFinder =
myValues.find(name);
176 if (valuesFinder ==
myValues.end()) {
181 std::string defaultName;
183 for (
const auto& value : subtopicEntry.second) {
184 const auto l =
myValues.find(value);
185 if ((l !=
myValues.end()) && (l->second == valuesFinder->second)) {
190 if (defaultName !=
"") {
194 WRITE_WARNINGF(
TL(
"Please note that '%' is deprecated.\n Use '%' instead."), name, defaultName);
195 synonymFinder->second =
true;
197 return valuesFinder->second;
262 WRITE_ERROR(
"While processing option '" + name +
"':\n " + e.what());
292std::vector<std::string>
295 std::vector<std::string> synonymes;
296 for (
const auto& value :
myValues) {
297 if ((value.second == o) && (name != value.first)) {
298 synonymes.push_back(value.first);
319 std::vector<std::string> done;
320 os <<
"Options set:" << std::endl;
321 for (
const auto& value : oc.
myValues) {
322 const auto& finder = std::find(done.begin(), done.end(), value.first);
323 if (finder == done.end()) {
324 std::vector<std::string> synonymes = oc.
getSynonymes(value.first);
325 if (synonymes.size() != 0) {
326 os << value.first <<
" (";
327 for (
auto synonym = synonymes.begin(); synonym != synonymes.end(); synonym++) {
328 if (synonym != synonymes.begin()) {
337 if (value.second->isSet()) {
338 os <<
": " << value.second->getValueString() << std::endl;
340 os <<
": <INVALID>" << std::endl;
342 done.push_back(value.first);
343 copy(synonymes.begin(), synonymes.end(), back_inserter(done));
353 if (addresse.second->isFileName() && addresse.second->isSet()) {
355 for (
auto& file : fileList) {
356 if (addresse.first !=
"configuration-file") {
366 for (
auto& file : rawList) {
370 if (conv !=
joinToString(addresse.second->getStringVector(),
',')) {
371 const bool hadDefault = addresse.second->isDefault();
372 addresse.second->set(conv,
joinToString(rawList,
','),
false);
374 addresse.second->resetDefault();
391 if (files.size() == 0) {
395 for (
const auto& file : files) {
398 WRITE_ERRORF(
TL(
"File '%' is not accessible (%)."), file, std::strerror(errno));
416 std::vector<std::string> seenSynonymes;
417 for (
const auto& value :
myValues) {
418 if (std::find(seenSynonymes.begin(), seenSynonymes.end(), value.first) != seenSynonymes.end()) {
421 if (value.second->isSet() && !value.second->isDefault() && value.first.find(prefix) == 0) {
422 WRITE_ERRORF(
TL(
"Option '%' needs option '%'."), value.first, name);
423 std::vector<std::string> synonymes =
getSynonymes(value.first);
424 std::copy(synonymes.begin(), synonymes.end(), std::back_inserter(seenSynonymes));
435 std::ostringstream s;
436 s <<
TLF(
"A value for the option '%' was already set.\n Possible synonymes: ", arg);
437 auto synonym = synonymes.begin();
438 while (synonym != synonymes.end()) {
441 if (synonym != synonymes.end()) {
469 addresse.second->resetWritable();
483 addresse.second->resetDefault();
511 delete addresse.second;
522 const std::string& description) {
528 throw ProcessError(
"SubTopic '" + subtopic +
"' doesn't exist");
543 throw ProcessError(
"SubTopic '" + subtopic +
"' doesn't exist");
618 auto it = std::find(entry.second.begin(), entry.second.end(), name);
619 if (it != entry.second.end()) {
620 entry.second.erase(it);
628 int offset,
int nextOffset) {
629 while (what.length() > 0) {
630 if ((
int)what.length() > 79 - offset) {
631 std::string::size_type splitPos = what.rfind(
';', 79 - offset);
632 if (splitPos == std::string::npos) {
633 splitPos = what.rfind(
' ', 79 - offset);
637 if (splitPos != std::string::npos) {
638 os << what.substr(0, splitPos) << std::endl;
639 what = what.substr(splitPos + 1);
640 for (
int r = 0; r < (nextOffset + 1); ++r) {
661 if (missingOptions) {
664 std::cout <<
TL(
" Build features: ") << HAVE_ENABLED << std::endl;
666 std::cout <<
" " << copyrightNotice.data() << std::endl;
668 std::cout <<
TL(
" License EPL-2.0: Eclipse Public License Version 2 <https://eclipse.org/legal/epl-v20.html>") << std::endl;
669 std::cout <<
TL(
" Use --help to get the list of options.") << std::endl;
677 std::cout <<
" " << copyrightNotice.data() << std::endl;
685 std::cout <<
TL(
" Build features: ") << HAVE_ENABLED << std::endl;
687 std::cout <<
" " << copyrightNotice.data() << std::endl;
689 std::cout <<
"\n" <<
myFullName <<
" is part of SUMO.\n";
690 std::cout <<
"This program and the accompanying materials\n";
691 std::cout <<
"are made available under the terms of the Eclipse Public License v2.0\n";
692 std::cout <<
"which accompanies this distribution, and is available at\n";
693 std::cout <<
"http://www.eclipse.org/legal/epl-v20.html\n";
694 std::cout <<
"This program may also be made available under the following Secondary\n";
695 std::cout <<
"Licenses when the conditions for such availability set forth in the Eclipse\n";
696 std::cout <<
"Public License 2.0 are satisfied: GNU General Public License, version 2\n";
697 std::cout <<
"or later which is available at\n";
698 std::cout <<
"https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html\n";
699 std::cout <<
"SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later" << std::endl;
703 if (
getBool(
"print-options")) {
704 std::cout << (*this);
708 if (
isSet(
"save-configuration")) {
709 const std::string& configPath =
getString(
"save-configuration");
710 if (configPath ==
"-" || configPath ==
"stdout") {
716 throw ProcessError(
TLF(
"Could not save configuration to '%'", configPath));
726 if (
isSet(
"save-template")) {
742 if (
isSet(
"save-schema")) {
767 option.second->setDescription(
TL(option.second->getDescription().c_str()));
771 example.second =
TL(example.second.c_str());
780const std::vector<std::string>&
786std::vector<std::string>
791 return std::vector<std::string>();
814std::vector<std::pair<std::string, Option*> >::const_iterator
820std::vector<std::pair<std::string, Option*> >::const_iterator
840 int csize = (int)entry.length() + 2 + 4;
843 for (
const auto& synonym : synonymes) {
855 if (csize < tooLarge && maxSize < csize) {
862 if (helpTopic !=
"") {
863 bool foundTopic =
false;
872 os <<
TL(
"Help Topics:") << std::endl;
874 os <<
" " << t << std::endl;
880 os <<
TL(
"Usage: ") <<
myAppName <<
TL(
" [OPTION]*") << std::endl;
892 os <<
TL(
"Examples:") << std::endl;
894 os <<
" " <<
myAppName <<
' ' << callExample.first << std::endl;
895 os <<
" " << callExample.second << std::endl;
899 os <<
TLF(
"Report bugs at %.",
"<https://github.com/eclipse-sumo/sumo/issues>") << std::endl;
900 os <<
TLF(
"Get in contact via %.",
"<sumo@dlr.de>") << std::endl;
906 os <<
TLF(
"% Options:", topic) << std::endl;
909 int csize = (int)entry.length() + 2;
914 for (
const auto& synonym : synonymes) {
916 os <<
'-' << synonym <<
", ";
934 for (
int r = maxSize; r > csize; --r) {
937 int offset = csize > tooLarge ? csize : maxSize;
946 const bool complete,
const bool addComments,
const std::string& relativeTo,
947 const bool forceRelative,
const bool inComment,
const std::string& indent)
const {
952 os << indent <<
"<" << app <<
"Configuration xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
953 <<
"xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/" << app <<
"Configuration.xsd\">\n\n";
955 if (subtopic ==
"Configuration" && !complete) {
958 const std::vector<std::string>& entries =
mySubTopicEntries.find(subtopic)->second;
959 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
962 for (
const std::string& name : entries) {
964 bool write = complete || (filled && !o->
isDefault());
968 if (name ==
"registry-viewport" && !complete) {
972 os << indent <<
" <" << subtopic <<
">\n";
979 os << indent <<
" <" << name <<
" value=\"";
983 for (
auto& file : fileList) {
992 forceRelative ||
getBool(
"save-configuration.relative"));
1001 const std::vector<std::string> synonymes =
getSynonymes(name);
1002 if (!synonymes.empty()) {
1003 os <<
"\" synonymes=\"" <<
toString(synonymes);
1005 std::string deprecated;
1006 for (
const auto& synonym : synonymes) {
1008 deprecated +=
" " + synonym;
1011 if (deprecated !=
"") {
1012 os <<
"\" deprecated=\"" << deprecated.substr(1);
1027 os << indent <<
" </" << subtopic <<
">\n\n";
1030 os << indent <<
"</" << app <<
"Configuration>" << std::endl;
1038 os <<
"<xsd:schema elementFormDefault=\"qualified\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n";
1039 os <<
" <xsd:complexType name=\"" << app <<
"ConfigurationType\">\n";
1040 os <<
" <xsd:all>\n";
1042 if (subtopic ==
"Configuration") {
1045 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
1047 os <<
" <xsd:element name=\"" << subtopic <<
"\" type=\"" << app << subtopic <<
"TopicType\" minOccurs=\"0\"/>\n";
1049 os <<
" </xsd:all>\n";
1050 os <<
" </xsd:complexType>\n\n";
1052 if (subtopic ==
"Configuration") {
1055 const std::vector<std::string>& entries =
mySubTopicEntries.find(subtopic)->second;
1056 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
1058 os <<
" <xsd:complexType name=\"" << app << subtopic <<
"TopicType\">\n";
1059 os <<
" <xsd:all>\n";
1060 for (
const auto& entry : entries) {
1064 if (type ==
"int[]") {
1067 if (type ==
"str[]") {
1070 os <<
" <xsd:element name=\"" << entry <<
"\" type=\"" << type <<
"OptionType\" minOccurs=\"0\"/>\n";
1072 os <<
" </xsd:all>\n";
1073 os <<
" </xsd:complexType>\n\n";
1075 os <<
"</xsd:schema>\n";
1083 if (!
getBool(
"write-metadata")) {
1086 if (
getBool(
"write-license")) {
1087 os <<
"This data file and the accompanying materials\n"
1088 "are made available under the terms of the Eclipse Public License v2.0\n"
1089 "which accompanies this distribution, and is available at\n"
1090 "http://www.eclipse.org/legal/epl-v20.html\n"
1091 "This file may also be made available under the following Secondary\n"
1092 "Licenses when the conditions for such availability set forth in the Eclipse\n"
1093 "Public License 2.0 are satisfied: GNU General Public License, version 2\n"
1094 "or later which is available at\n"
1095 "https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html\n"
1096 "SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later\n";
1098 if (includeConfig && !
getBool(
"write-metadata")) {
1107 const std::string& itemName)
const {
1108 if (
isSet(optionName)) {
1110 return std::find(values.begin(), values.end(), itemName) != values.end();
1123 addr.second = addr.second->clone();
#define WRITE_WARNINGF(...)
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
#define WRITE_WARNING(msg)
std::vector< std::string > StringVector
Definition of a vector of strings.
std::vector< int > IntVector
Definition of a vector of ints.
std::ostream & operator<<(std::ostream &os, const OptionsCont &oc)
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static std::string fixRelative(const std::string &filename, const std::string &basePath, const bool force, std::string curDir="")
Fixes the relative path for the given filename in relation to the basePath (usually a config file).
static std::string checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessible from the current working directory.
static bool isReadable(std::string path)
Checks whether the given file is readable.
static void setupI18n(const std::string &locale="")
set up gettext stuff
A class representing a single program option.
bool isWriteable() const
Returns the information whether the option may be set a further time.
bool isSet() const
returns the information whether this options holds a valid value
virtual bool isDefault() const
Returns the information whether the option holds the default value.
void setRequired()
mark option as required
virtual std::string getString() const
Returns the stored string value.
virtual const IntVector & getIntVector() const
Returns the stored integer vector.
void resetWritable()
Resets the option to be writeable.
const std::string & getDescription() const
Returns the description of what this option does.
void setListSeparator(const std::string &listSep)
set list separator
virtual bool isFileName() const
Returns the information whether this option is a file name.
virtual const StringVector & getStringVector() const
Returns the stored string vector.
void setDescription(const std::string &desc)
Sets the description of what this option does.
virtual const std::string & getTypeName() const
Returns the mml-type name of this option.
virtual int getInt() const
Returns the stored integer value.
virtual double getFloat() const
Returns the stored double value.
virtual bool getBool() const
Returns the stored boolean value.
void setPositional()
mark option as positional
void resetDefault()
Resets the option to be on its default value.
const std::string & getSubTopic() const
Returns the subtopic to which this option belongs.
virtual bool set(const std::string &v, const std::string &orig, const bool append)=0
Stores the given value.
bool isEditable() const
check if this option is editable
virtual bool isBool() const
Returns the information whether the option is a bool option.
void setEditable(const bool value)
set editable
const std::string & getValueString() const
Returns the string-representation of the value.
void setSubtopic(const std::string &subtopic)
Sets the subtopic to which this option belongs.
A storage for options typed value containers)
void setAdditionalHelpMessage(const std::string &add)
Sets an additional message to be printed at the begin of the help screen.
~OptionsCont()
Destructor.
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void writeConfiguration(std::ostream &os, const bool filled, const bool complete, const bool addComments, const std::string &relativeTo="", const bool forceRelative=false, const bool inComment=false, const std::string &indent="") const
Writes the configuration.
void resetDefault()
Resets all options to default.
void setFurtherAttributes(const std::string &name, const std::string &subtopic, bool required, bool positional, const std::string &listSep)
mark option as required
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
std::vector< std::pair< std::string, std::string > > myCallExamples
list of call examples
bool isWriteable(const std::string &name)
Returns the information whether the named option may be set.
std::map< std::string, std::vector< std::string > > mySubTopicEntries
A map from subtopic to option.
void writeXMLHeader(std::ostream &os, const bool includeConfig=true) const
Writes a standard XML header, including the configuration.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
void splitLines(std::ostream &os, std::string what, int offset, int nextOffset)
Writes the given string 'formatted'.
void setApplicationName(const std::string &appName, const std::string &fullName)
Sets the application name.
OptionsCont * clone() const
make a copy of this OptionsCont instance
void printHelpOnTopic(const std::string &topic, int tooLarge, int maxSize, std::ostream &os)
Prints help on the given topic.
void removeSubTopic(const std::string &topic)
Removes the given sub-topic.
const std::string & getSubTopic(const std::string &name) const
Returns the option category.
std::map< std::string, Option * > myValues
option maps sorted by name (for addresses AND their synonyms)
bool isEmpty() const
check if options container is empty
std::string myAdditionalMessage
std::vector< std::string > myCopyrightNotices
const std::vector< std::string > & getSubTopics() const
return the list of subtopics
void setOptionEditable(const std::string &name, const bool value)
set option editable
bool myAmLocalized
Whether the descriptino has already been translated to the locale language.
std::vector< std::pair< std::string, Option * > > myAddresses
option-addresses
const IntVector & getIntVector(const std::string &name) const
Returns the list of integer-value of the named option (only for Option_IntVector)
std::vector< std::string > getSynonymes(const std::string &name) const
Returns the synonymes of an option name.
void reportDoubleSetting(const std::string &arg) const
Reports an error that the option has already been set.
std::vector< std::string > mySubTopics
lists of option subtopics and copyright notices
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
static OptionsCont EMPTY_OPTIONS
empty option container
void localizeDescriptions()
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
bool setDefault(const std::string &name, const std::string &value)
Sets the given value for the named option as new default value.
void removeOption(const std::string &name)
Removes an option from its subtopic.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
bool exists(const std::string &name) const
Returns the information whether the named option is known.
const std::string & getFullName() const
get options full name
bool isBool(const std::string &name) const
Returns the information whether the option is a boolean option.
void addCopyrightNotice(const std::string ©rightLine)
Adds a copyright notice to the help output.
std::string getTypeName(const std::string name)
return the type name for the given option
void writeSchema(std::ostream &os)
Writes the xml schema for the configuration.
void clear()
Removes all information from the container.
void setApplicationDescription(const std::string &appDesc)
Sets the application description.
std::vector< std::pair< std::string, Option * > >::const_iterator begin() const
get begin addresses iterator
bool set(const std::string &name, const std::string &value, const bool append=false)
Sets the given value for the named option.
bool isEditable(const std::string &name)
Returns the information whether the named option is editable.
void clearCopyrightNotices()
Removes all copyright information.
std::string convertChar(char abbr) const
Converts an abbreviation into a name.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
OptionsCont()
Constructor.
void printHelp(std::ostream &os)
Prints the help.
std::vector< std::pair< std::string, Option * > >::const_iterator end() const
get begin addresses iterator
std::string getValueString(const std::string &name) const
Returns the string-value of the named option (all options)
std::string myAppDescription
const std::string & getDescription(const std::string &name) const
Returns the option description.
bool setByRootElement(const std::string &name, const std::string &value)
Sets the given value for the option which can handle the given XML root.
std::map< std::string, bool > myDeprecatedSynonymes
A map from deprecated options to a bool indicating whether we warned about deprecation.
static OptionsCont myOptions
The static options container used.
bool checkDependingSuboptions(const std::string &name, const std::string &prefix) const
Checks whether an option is set, which has options with a prefix depending on it.
std::map< std::string, std::string > myXMLDefaults
A map from XML root element to option.
std::string myAppName
some information on the application
void resetWritable()
Resets all options to be writeable.
void addXMLDefault(const std::string &name, const std::string &xmlRoot="")
Adds an XML root element to handle by default. The special root "" denotes the default handler.
static OptionsCont & getOptions()
Retrieves the options.
std::vector< std::string > getSubTopicsEntries(const std::string &subtopic) const
return the list of entries for the given subtopic
Option * getSecure(const std::string &name) const
Returns the named option.
void relocateFiles(const std::string &configuration) const
Modifies file name options according to the configuration path.
bool isInStringVector(const std::string &optionName, const std::string &itemName) const
Returns the named option is a list of string values containing the specified item.
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file)
void addCallExample(const std::string &example, const std::string &desc)
Add a call example.
static const std::chrono::time_point< std::chrono::system_clock > & getLoadTime()
Return the time stamp of the last init.
static const std::string ENCODING
The encoding of parsed strings.
std::vector< std::string > getVector()
return vector of strings
static std::string urlEncode(const std::string &url, const std::string encodeWhich="")
encode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
static std::string urlDecode(const std::string &encoded)
decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static std::string substituteEnvironment(const std::string &str, const std::chrono::time_point< std::chrono::system_clock > *const timeRef=nullptr)
Replaces an environment variable with its value (similar to bash); syntax for a variable is ${NAME}.
static std::string isoTimeString(const std::chrono::time_point< std::chrono::system_clock > *const timeRef=nullptr)
Returns an ISO8601 formatted time string with microsecond precision.
static std::string transcodeToLocal(const std::string &utf8String)
convert a string from UTF-8 to the local codepage