64 : myAddresses(), myValues(), myDeprecatedSynonymes() {
65 myCopyrightNotices.push_back(
"Copyright (C) 2001-2022 German Aerospace Center (DLR) and others; https://sumo.dlr.de");
82 throw ProcessError(name +
" is an already used option name.");
97 KnownContType::iterator i1 =
myValues.find(name1);
98 KnownContType::iterator i2 =
myValues.find(name2);
100 throw ProcessError(
"Neither the option '" + name1 +
"' nor the option '" + name2 +
"' is known yet");
103 if ((*i1).second == (*i2).second) {
106 throw ProcessError(
"Both options '" + name1 +
"' and '" + name2 +
"' do exist and differ.");
137 KnownContType::const_iterator i =
myValues.find(name);
139 if (failOnNonExistant) {
140 throw ProcessError(
"Internal request for unknown option '" + name +
"'!");
145 return (*i).second->isSet();
151 KnownContType::const_iterator i =
myValues.find(name);
153 if (failOnNonExistant) {
154 throw ProcessError(
"Internal request for unknown option '" + name +
"'!");
159 (*i).second->unSet();
165 KnownContType::const_iterator i =
myValues.find(name);
169 return (*i).second->isDefault();
175 KnownContType::const_iterator k =
myValues.find(name);
177 throw ProcessError(
"No option with the name '" + name +
"' exists.");
181 std::string defaultName;
183 for (std::vector<std::string>::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
184 KnownContType::const_iterator l =
myValues.find(*j);
185 if (l !=
myValues.end() && l->second == k->second) {
190 if (defaultName !=
"") {
194 WRITE_WARNING(
"Please note that '" + name +
"' is deprecated.\n Use '" + defaultName +
"' instead.");
256 if (!o->
set(value)) {
260 WRITE_ERROR(
"While processing option '" + name +
"':\n " + e.what());
269 if (
set(name, value)) {
289 std::vector<std::string>
292 std::vector<std::string> v(0);
293 for (KnownContType::const_iterator i =
myValues.begin(); i !=
myValues.end(); i++) {
294 if ((*i).second == o && name != (*i).first) {
295 v.push_back((*i).first);
310 std::vector<std::string> done;
311 os <<
"Options set:" << std::endl;
312 for (OptionsCont::KnownContType::const_iterator i = oc.
myValues.begin();
314 std::vector<std::string>::iterator j = std::find(done.begin(), done.end(), (*i).first);
315 if (j == done.end()) {
316 std::vector<std::string> synonymes = oc.
getSynonymes((*i).first);
317 if (synonymes.size() != 0) {
318 os << (*i).first <<
" (";
319 for (j = synonymes.begin(); j != synonymes.end(); j++) {
320 if (j != synonymes.begin()) {
329 if ((*i).second->isSet()) {
330 os <<
": " << (*i).second->getValueString() << std::endl;
332 os <<
": <INVALID>" << std::endl;
334 done.push_back((*i).first);
335 copy(synonymes.begin(), synonymes.end(), back_inserter(done));
345 if (option->isFileName() && option->isSet()) {
347 for (std::string& f : fileList) {
356 if (conv !=
joinToString(option->getStringVector(),
',')) {
357 const bool hadDefault = option->isDefault();
360 option->resetDefault();
379 if (files.size() == 0) {
380 WRITE_ERROR(
"The file list for '" + name +
"' is empty.");
383 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
404 std::vector<std::string> seenSynonymes;
405 for (KnownContType::const_iterator i =
myValues.begin(); i !=
myValues.end(); i++) {
406 if (std::find(seenSynonymes.begin(), seenSynonymes.end(), (*i).first) != seenSynonymes.end()) {
409 if ((*i).second->isSet() && !(*i).second->isDefault() && (*i).first.find(prefix) == 0) {
410 WRITE_ERROR(
"Option '" + (*i).first +
"' needs option '" + name +
"'.");
411 std::vector<std::string> synonymes =
getSynonymes((*i).first);
412 std::copy(synonymes.begin(), synonymes.end(), std::back_inserter(seenSynonymes));
423 std::ostringstream s;
424 s <<
"A value for the option '" + arg +
"' was already set.\n Possible synonymes: ";
425 for (std::vector<std::string>::iterator i = synonymes.begin(); i != synonymes.end();) {
428 if (i != synonymes.end()) {
456 (*i)->resetWritable();
470 ItemAddressContType::iterator i;
483 const std::string& subtopic,
484 const std::string& description) {
495 const std::string& fullName) {
540 int offset,
int nextOffset) {
541 while (what.length() > 0) {
542 if ((
int)what.length() > 79 - offset) {
543 std::string::size_type splitPos = what.rfind(
';', 79 - offset);
544 if (splitPos == std::string::npos) {
545 splitPos = what.rfind(
' ', 79 - offset);
549 if (splitPos != std::string::npos) {
550 os << what.substr(0, splitPos) << std::endl;
551 what = what.substr(splitPos + 1);
552 for (
int r = 0; r < nextOffset + 1; ++r) {
571 if (missingOptions) {
574 std::cout <<
" Build features: " << HAVE_ENABLED << std::endl;
575 for (std::vector<std::string>::const_iterator it =
577 std::cout <<
" " << *it << std::endl;
579 std::cout <<
" License EPL-2.0: Eclipse Public License Version 2 <https://eclipse.org/legal/epl-v20.html>\n";
580 std::cout <<
" Use --help to get the list of options." << std::endl;
588 for (std::vector<std::string>::const_iterator it =
590 std::cout <<
" " << *it << std::endl;
598 std::cout <<
" Build features: " << HAVE_ENABLED << std::endl;
599 for (std::vector<std::string>::const_iterator it =
601 std::cout <<
" " << *it << std::endl;
603 std::cout <<
"\n" <<
myFullName <<
" is part of SUMO.\n";
604 std::cout <<
"This program and the accompanying materials\n";
605 std::cout <<
"are made available under the terms of the Eclipse Public License v2.0\n";
606 std::cout <<
"which accompanies this distribution, and is available at\n";
607 std::cout <<
"http://www.eclipse.org/legal/epl-v20.html\n";
608 std::cout <<
"This program may also be made available under the following Secondary\n";
609 std::cout <<
"Licenses when the conditions for such availability set forth in the Eclipse\n";
610 std::cout <<
"Public License 2.0 are satisfied: GNU General Public License, version 2\n";
611 std::cout <<
"or later which is available at\n";
612 std::cout <<
"https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html\n";
613 std::cout <<
"SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later" << std::endl;
618 std::cout << (*this);
622 if (
isSet(
"save-configuration",
false)) {
623 if (
getString(
"save-configuration") ==
"-" ||
getString(
"save-configuration") ==
"stdout") {
639 if (
isSet(
"save-template",
false)) {
655 if (
isSet(
"save-schema",
false)) {
676 std::vector<std::string>::const_iterator i, j;
687 for (j = entries.begin(); j != entries.end(); ++j) {
690 int csize = (int)j->length() + 2 + 4;
692 const std::vector<std::string> synonymes =
getSynonymes(*j);
693 for (std::vector<std::string>::const_iterator s = synonymes.begin(); s != synonymes.end(); ++s) {
705 if (csize < tooLarge && maxSize < csize) {
712 if (helpTopic !=
"") {
713 bool foundTopic =
false;
722 os <<
"Help Topics:" << std::endl;
724 os <<
" " << t << std::endl;
730 os <<
"Usage: " <<
myAppName <<
" [OPTION]*" << std::endl;
742 os <<
"Examples:" << std::endl;
744 os <<
" " <<
myAppName <<
' ' << e->first << std::endl;
745 os <<
" " << e->second << std::endl;
749 os <<
"Report bugs at <https://github.com/eclipse/sumo/issues>." << std::endl;
750 os <<
"Get in contact via <sumo@dlr.de>." << std::endl;
755 os << topic <<
" Options:" << std::endl;
758 int csize = (int)entry.length() + 2;
762 std::vector<std::string> synonymes =
getSynonymes(entry);
763 for (std::vector<std::string>::const_iterator s = synonymes.begin(); s != synonymes.end(); ++s) {
765 os <<
'-' << *s <<
", ";
783 for (
int r = maxSize; r > csize; --r) {
786 int offset = csize > tooLarge ? csize : maxSize;
794 const bool complete,
const bool addComments,
795 const bool inComment)
const {
799 os <<
"<configuration xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/";
807 os <<
"Configuration.xsd\">" << std::endl << std::endl;
809 std::string subtopic = *i;
810 if (subtopic ==
"Configuration" && !complete) {
813 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
817 for (
const std::string& name : entries) {
819 bool write = complete || (filled && !o->
isDefault());
823 if (name ==
"registry-viewport" && !complete) {
827 os <<
" <" << subtopic <<
">" << std::endl;
834 os <<
" <" << name <<
" value=\"";
839 std::vector<std::string> synonymes =
getSynonymes(name);
840 if (!synonymes.empty()) {
841 os <<
"\" synonymes=\"";
842 for (std::vector<std::string>::const_iterator s = synonymes.begin(); s != synonymes.end(); ++s) {
843 if (s != synonymes.begin()) {
854 os <<
"\"/>" << std::endl;
862 os <<
" </" << subtopic <<
">" << std::endl << std::endl;
865 os <<
"</configuration>" << std::endl;
872 os <<
"<xsd:schema elementFormDefault=\"qualified\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n";
873 os <<
" <xsd:include schemaLocation=\"baseTypes.xsd\"/>\n";
874 os <<
" <xsd:element name=\"configuration\" type=\"configurationType\"/>\n\n";
875 os <<
" <xsd:complexType name=\"configurationType\">\n";
876 os <<
" <xsd:all>\n";
878 std::string subtopic = *i;
879 if (subtopic ==
"Configuration") {
882 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
884 os <<
" <xsd:element name=\"" << subtopic <<
"\" type=\"" << subtopic <<
"TopicType\" minOccurs=\"0\"/>\n";
886 os <<
" </xsd:all>\n";
887 os <<
" </xsd:complexType>\n\n";
889 std::string subtopic = *i;
890 if (subtopic ==
"Configuration") {
893 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
895 os <<
" <xsd:complexType name=\"" << subtopic <<
"TopicType\">\n";
896 os <<
" <xsd:all>\n";
898 for (std::vector<std::string>::const_iterator j = entries.begin(); j != entries.end(); ++j) {
902 if (type ==
"int[]") {
905 if (type ==
"str[]") {
908 os <<
" <xsd:element name=\"" << *j <<
"\" type=\"" << type <<
"OptionType\" minOccurs=\"0\"/>\n";
910 os <<
" </xsd:all>\n";
911 os <<
" </xsd:complexType>\n\n";
913 os <<
"</xsd:schema>\n";
924 strftime(buffer, 80,
"<!-- generated on %F %T by ", localtime(&rawtime));
927 os <<
"This data file and the accompanying materials\n";
928 os <<
"are made available under the terms of the Eclipse Public License v2.0\n";
929 os <<
"which accompanies this distribution, and is available at\n";
930 os <<
"http://www.eclipse.org/legal/epl-v20.html\n";
931 os <<
"SPDX-License-Identifier: EPL-2.0\n";
942 const std::string& itemName)
const {
943 if (
isSet(optionName)) {
945 return std::find(values.begin(), values.end(), itemName) != values.end();
#define WRITE_MESSAGE(msg)
#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 checkForRelativity(const std::string &filename, const std::string &basePath)
Returns the path from a configuration so that it is accessable from the current working directory.
static bool isReadable(std::string path)
Checks whether the given file is readable.
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.
virtual std::string getString() const
Returns the stored string value.
virtual const IntVector & getIntVector() const
Returns the stored integer vector.
const std::string & getDescription() const
Returns the description of what this option does.
virtual bool set(const std::string &v)=0
Stores the given value.
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 resetDefault()
Resets the option to be on its default value.
virtual bool isBool() const
Returns the information whether the option is a bool option.
virtual std::string getValueString() const =0
Returns the string-representation of the value.
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 unSet(const std::string &name, bool failOnNonExistant=true) const
Marks the option as unset.
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
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)
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
void writeConfiguration(std::ostream &os, const bool filled, const bool complete, const bool addComments, const bool inComment=false) const
Writes the configuration.
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.
void printHelpOnTopic(const std::string &topic, int tooLarge, int maxSize, std::ostream &os)
Prints help on the given topic.
std::string myAdditionalMessage
std::vector< std::string > myCopyrightNotices
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)
bool myWriteLicense
Information whether we should always include license information in file headers.
ItemAddressContType myAddresses
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.
bool exists(const std::string &name) const
Returns the information whether the named option is known.
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.
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.
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::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.
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::string ENCODING
The encoding of parsed strings.
static std::string urlDecode(const std::string &encoded)
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static std::string to_lower_case(std::string str)
Transfers the content to lower case.
static std::string transcodeToLocal(const std::string &utf8String)
convert a string from UTF-8 to the local codepage
static std::string strerror()