52 #ifdef CHECK_MEMORY_LEAKS
54 #endif // CHECK_MEMORY_LEAKS
73 : myAddresses(), myValues(), myDeprecatedSynonymes(), myHaveInformedAboutDeprecatedDivider(false) {
74 myCopyrightNotices.push_back(
"Copyright (C) 2001-2015 DLR and contributors; http://sumo.dlr.de");
91 throw ProcessError(name +
" is an already used option name.");
106 KnownContType::iterator i1 =
myValues.find(name1);
107 KnownContType::iterator i2 =
myValues.find(name2);
109 throw ProcessError(
"Neither the option '" + name1 +
"' nor the option '" + name2 +
"' is known yet");
112 if ((*i1).second == (*i2).second) {
115 throw ProcessError(
"Both options '" + name1 +
"' and '" + name2 +
"' do exist and differ.");
140 KnownContType::const_iterator i =
myValues.find(name);
142 if (failOnNonExistant) {
143 throw ProcessError(
"Internal request for unknown option '" + name +
"'!");
148 return (*i).second->isSet();
154 KnownContType::const_iterator i =
myValues.find(name);
156 if (failOnNonExistant) {
157 throw ProcessError(
"Internal request for unknown option '" + name +
"'!");
162 (*i).second->unSet();
168 KnownContType::const_iterator i =
myValues.find(name);
172 return (*i).second->isDefault();
178 KnownContType::const_iterator k =
myValues.find(name);
180 throw ProcessError(
"No option with the name '" + name +
"' exists.");
184 std::string defaultName;
186 for (std::vector<std::string>::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
187 KnownContType::const_iterator l =
myValues.find(*j);
188 if (l !=
myValues.end() && l->second == k->second) {
193 if (defaultName !=
"") {
197 WRITE_WARNING(
"Please note that '" + name +
"' is deprecated.\n Use '" + defaultName +
"' instead.");
247 if (!o->
set(value)) {
251 WRITE_ERROR(
"While processing option '" + name +
"':\n " + e.what());
258 std::vector<std::string>
261 std::vector<std::string> v(0);
262 for (KnownContType::const_iterator i =
myValues.begin(); i !=
myValues.end(); i++) {
263 if ((*i).second == o && name != (*i).first) {
264 v.push_back((*i).first);
273 std::vector<std::string> done;
274 os <<
"Options set:" << std::endl;
275 for (OptionsCont::KnownContType::const_iterator i = oc.
myValues.begin();
277 std::vector<std::string>::iterator j = find(done.begin(), done.end(), (*i).first);
278 if (j == done.end()) {
279 std::vector<std::string> synonymes = oc.
getSynonymes((*i).first);
280 if (synonymes.size() != 0) {
281 os << (*i).first <<
" (";
282 for (j = synonymes.begin(); j != synonymes.end(); j++) {
283 if (j != synonymes.begin()) {
292 if ((*i).second->isSet()) {
293 os <<
": " << (*i).second->getValueString() << std::endl;
295 os <<
": <INVALID>" << std::endl;
297 done.push_back((*i).first);
298 copy(synonymes.begin(), synonymes.end(), back_inserter(done));
308 if ((*i)->isFileName() && (*i)->isSet()) {
311 while (st.hasNext()) {
312 if (conv.length() != 0) {
315 std::string tmp = st.
next();
321 if (conv != (*i)->getString()) {
340 if (files.size() == 0) {
341 WRITE_ERROR(
"The file list for '" + name +
"' is empty.");
344 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
347 WRITE_ERROR(
"File '" + *fileIt +
"' is not accessible.");
365 std::vector<std::string> seenSynonymes;
366 for (KnownContType::const_iterator i =
myValues.begin(); i !=
myValues.end(); i++) {
367 if (std::find(seenSynonymes.begin(), seenSynonymes.end(), (*i).first) != seenSynonymes.end()) {
370 if ((*i).second->isSet() && !(*i).second->isDefault() && (*i).first.find(prefix) == 0) {
371 WRITE_ERROR(
"Option '" + (*i).first +
"' needs option '" + name +
"'.");
372 std::vector<std::string> synonymes =
getSynonymes((*i).first);
373 std::copy(synonymes.begin(), synonymes.end(), std::back_inserter(seenSynonymes));
384 std::ostringstream s;
385 s <<
"A value for the option '" + arg +
"' was already set.\n Possible synonymes: ";
386 for (std::vector<std::string>::iterator i = synonymes.begin(); i != synonymes.end();) {
389 if (i != synonymes.end()) {
417 (*i)->resetWritable();
431 ItemAddressContType::iterator i;
444 const std::string& subtopic,
445 const std::string& description) {
456 const std::string& fullName) {
501 size_t offset,
size_t nextOffset) {
502 while (what.length() > 0) {
503 if (what.length() > 79 - offset) {
504 size_t splitPos = what.rfind(
';', 79 - offset);
505 if (splitPos == std::string::npos) {
506 splitPos = what.rfind(
' ', 79 - offset);
510 if (splitPos != std::string::npos) {
511 os << what.substr(0, splitPos) << std::endl;
512 what = what.substr(splitPos);
513 for (
size_t r = 0; r < nextOffset + 1; ++r) {
532 if (missingOptions) {
535 for (std::vector<std::string>::const_iterator it =
537 std::cout <<
" " << *it << std::endl;
539 std::cout <<
" License GPLv3+: GNU GPL Version 3 or later <http://gnu.org/licenses/gpl.html>\n";
540 std::cout <<
" Use --help to get the list of options." << std::endl;
547 for (std::vector<std::string>::const_iterator it =
549 std::cout <<
" " << *it << std::endl;
557 for (std::vector<std::string>::const_iterator it =
559 std::cout <<
" " << *it << std::endl;
561 std::cout <<
"\n" <<
myFullName <<
" is part of SUMO.\n";
562 std::cout <<
"SUMO is free software: you can redistribute it and/or modify\n";
563 std::cout <<
"it under the terms of the GNU General Public License as published by\n";
564 std::cout <<
"the Free Software Foundation, either version 3 of the License, or\n";
565 std::cout <<
"(at your option) any later version.\n\n";
566 std::cout <<
"This program is distributed in the hope that it will be useful,\n";
567 std::cout <<
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
568 std::cout <<
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n";
569 std::cout <<
"GNU General Public License for more details.\n\n";
570 std::cout <<
"You should have received a copy of the GNU General Public License\n";
571 std::cout <<
"along with this program. If not, see http://www.gnu.org/licenses/gpl.html" << std::endl;
576 std::cout << (*this);
580 if (
isSet(
"save-configuration",
false)) {
581 if (
getString(
"save-configuration") ==
"-" ||
getString(
"save-configuration") ==
"stdout") {
585 std::ofstream out(
getString(
"save-configuration").c_str());
597 if (
isSet(
"save-template",
false)) {
602 std::ofstream out(
getString(
"save-template").c_str());
613 if (
isSet(
"save-schema",
false)) {
618 std::ofstream out(
getString(
"save-schema").c_str());
634 std::vector<std::string>::const_iterator i, j;
639 os <<
"Usage: " <<
myAppName <<
" [OPTION]*" << std::endl;
647 size_t tooLarge = 40;
651 for (j = entries.begin(); j != entries.end(); ++j) {
654 size_t csize = (*j).length() + 2 + 4;
657 if (find_if(synonymes.begin(), synonymes.end(),
abbreviation_finder()) != synonymes.end()) {
666 if (csize < tooLarge && maxSize < csize) {
673 os << *i <<
" Options:" << std::endl;
675 for (j = entries.begin(); j != entries.end(); ++j) {
677 size_t csize = (*j).length() + 2;
682 std::vector<std::string>::iterator a = find_if(synonymes.begin(), synonymes.end(),
abbreviation_finder());
683 if (a != synonymes.end()) {
684 os <<
'-' << (*a) <<
", ";
700 for (
size_t r = maxSize; r > csize; --r) {
703 size_t offset = csize > tooLarge ? csize : maxSize;
711 os <<
"Examples:" << std::endl;
713 os <<
" " <<
myAppName <<
' ' << e->first << std::endl;
714 os <<
" " << e->second << std::endl;
718 os <<
"Report bugs at <http://sumo.dlr.de/trac/>." << std::endl;
719 os <<
"Get in contact via <sumo@dlr.de>." << std::endl;
725 bool complete,
bool addComments)
const {
727 os <<
"<configuration xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo.dlr.de/xsd/" <<
myAppName <<
"Configuration.xsd\">" << std::endl << std::endl;
729 std::string subtopic = *i;
730 if (subtopic ==
"Configuration" && !complete) {
733 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
734 std::transform(subtopic.begin(), subtopic.end(), subtopic.begin(), tolower);
737 for (std::vector<std::string>::const_iterator j = entries.begin(); j != entries.end(); ++j) {
739 bool write = complete || (filled && !o->
isDefault());
744 os <<
" <" << subtopic <<
">" << std::endl;
751 os <<
" <" << *j <<
" value=\"";
757 if (!synonymes.empty()) {
758 os <<
"\" synonymes=\"";
759 for (std::vector<std::string>::const_iterator s = synonymes.begin(); s != synonymes.end(); ++s) {
760 if (s != synonymes.begin()) {
771 os <<
"\"/>" << std::endl;
779 os <<
" </" << subtopic <<
">" << std::endl << std::endl;
782 os <<
"</configuration>" << std::endl;
789 os <<
"<xsd:schema elementFormDefault=\"qualified\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n";
790 os <<
" <xsd:include schemaLocation=\"baseTypes.xsd\"/>\n";
791 os <<
" <xsd:element name=\"configuration\" type=\"configurationType\"/>\n\n";
792 os <<
" <xsd:complexType name=\"configurationType\">\n";
793 os <<
" <xsd:all>\n";
795 std::string subtopic = *i;
796 if (subtopic ==
"Configuration") {
799 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
800 std::transform(subtopic.begin(), subtopic.end(), subtopic.begin(), tolower);
801 os <<
" <xsd:element name=\"" << subtopic <<
"\" type=\"" << subtopic <<
"Type\" minOccurs=\"0\"/>\n";
803 os <<
" </xsd:all>\n";
804 os <<
" </xsd:complexType>\n\n";
806 std::string subtopic = *i;
807 if (subtopic ==
"Configuration") {
810 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
811 std::transform(subtopic.begin(), subtopic.end(), subtopic.begin(), tolower);
812 os <<
" <xsd:complexType name=\"" << subtopic <<
"Type\">\n";
813 os <<
" <xsd:all>\n";
815 for (std::vector<std::string>::const_iterator j = entries.begin(); j != entries.end(); ++j) {
818 std::transform(type.begin(), type.end(), type.begin(), tolower);
819 if (type ==
"int[]") {
822 os <<
" <xsd:element name=\"" << *j <<
"\" type=\"" << type <<
"OptionType\" minOccurs=\"0\"/>\n";
824 os <<
" </xsd:all>\n";
825 os <<
" </xsd:complexType>\n\n";
827 os <<
"</xsd:schema>\n";
838 strftime(buffer, 80,
"<!-- generated on %c by ", localtime(&rawtime));
845 std::vector<std::string>
850 WRITE_WARNING(
"Please note that using ';' as list separator is deprecated.\n From 1.0 onwards, only ',' will be accepted.");
854 std::vector<std::string> ret = st.
getVector();
855 for (std::vector<std::string>::iterator i = ret.begin(); i != ret.end(); ++i) {
864 const std::string& itemName) {
865 if (
isSet(optionName)) {
867 return find(values.begin(), values.end(), itemName) != values.end();
std::string myAppName
some information on the application
void doRegister(const std::string &name, Option *v)
Adds an option under the given name.
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
std::vector< std::string > getSynonymes(const std::string &name) const
Returns the synonymes of an option name.
std::vector< std::string > mySubTopics
lists of option subtopics and copyright notices
static std::string getConfigurationRelative(const std::string &configPath, const std::string &path)
Returns the second path as a relative path to the first file.
void resetWritable()
Resets all options to be writeable.
bool isSet() const
returns the information whether this options holds a valid value
void addCopyrightNotice(const std::string ©rightLine)
Adds a copyright notice to the help output.
bool isInStringVector(const std::string &optionName, const std::string &itemName)
Returns the named option is a list of string values containing the specified item.
static bool isReadable(std::string path)
Checks whether the given file is readable.
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. ...
virtual bool isBool() const
Returns the information whether the option is a bool option.
void addCallExample(const std::string &example, const std::string &desc)
Add a call example.
void unSet(const std::string &name, bool failOnNonExistant=true) const
Marks the option as unset.
void reportDoubleSetting(const std::string &arg) const
Reports an error that the option has already been set.
void setApplicationDescription(const std::string &appDesc)
Sets the application description.
void clearCopyrightNotices()
Removes all copyright information.
void printHelp(std::ostream &os)
Prints the help.
const IntVector & getIntVector(const std::string &name) const
Returns the list of integer-value of the named option (only for Option_IntVector) ...
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
static std::string escapeXML(const std::string &orig)
Replaces the standard escapes by their XML entities.
bool myHaveInformedAboutDeprecatedDivider
Information whether a warning a deprecated divider.
virtual bool getBool() const
Returns the stored boolean value.
std::string convertChar(char abbr) const
Converts an abbreviation into a name.
virtual const IntVector & getIntVector() const
Returns the stored integer 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.
static OptionsCont myOptions
The static options container used.
virtual std::string getString() const
Returns the stored string value.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
#define WRITE_WARNING(msg)
static OptionsCont & getOptions()
Retrieves the options.
void addSynonyme(const std::string &name1, const std::string &name2, bool isDeprecated=false)
Adds a synonyme for an options name (any order)
std::string myAppDescription
ItemAddressContType myAddresses
std::string getString(const std::string &name) const
Returns the string-value of the named option (only for Option_String)
std::map< std::string, bool > myDeprecatedSynonymes
A map from deprecated options to a bool indicating whether we warned about deprecation.
void clear()
Removes all information from the container.
void writeXMLHeader(std::ostream &os)
Writes a standard XML header, including the configuration.
bool isBool(const std::string &name) const
Returns the information whether the option is a boolean option.
std::string myAdditionalMessage
std::vector< int > IntVector
Definition of a vector of unsigned ints.
const std::string & getDescription() const
Returns the description of what this option does.
static bool isAbsolute(const std::string &path)
Returns the information whether the given path is absolute.
void setAdditionalHelpMessage(const std::string &add)
Sets an additional message to be printed at the begin of the help screen.
bool isUsableFileList(const std::string &name) const
Checks whether the named option is usable as a file list (with at least a single file) ...
static const std::string ENCODING
The encoding of parsed strings.
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
~OptionsCont()
Destructor.
bool isWriteable(const std::string &name)
Returns the information whether the named option may be set.
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
bool isWriteable() const
Returns the information whether the option may be set a further time.
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
void splitLines(std::ostream &os, std::string what, size_t offset, size_t nextOffset)
Writes the given string 'formatted'.
std::ostream & operator<<(std::ostream &os, const OptionsCont &oc)
virtual bool set(const std::string &v)=0
Stores the given value (used for non-bool options)
void writeSchema(std::ostream &os, bool addComments)
Writes the xml schema for the configuration.
std::vector< std::string > getVector()
A class to find abbreviated option names (length=1)
A class representing a single program option.
void relocateFiles(const std::string &configuration) const
Modifies file name options according to the configuration path.
virtual bool isDefault() const
Returns the information whether the option holds the default value.
virtual int getInt() const
Returns the stored integer value.
virtual SUMOReal getFloat() const
Returns the stored SUMOReal value.
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
bool set(const std::string &name, const std::string &value)
Sets the given value for the named option.
virtual std::string getValueString() const =0
Returns the string-representation of the value.
std::map< std::string, std::vector< std::string > > mySubTopicEntries
A map from subtopic to option.
A storage for options typed value containers)
Option * getSecure(const std::string &name) const
Returns the named option.
std::vector< std::string > myCopyrightNotices
void writeConfiguration(std::ostream &os, bool filled, bool complete, bool addComments) const
Writes the configuration.
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
int getInt(const std::string &name) const
Returns the int-value of the named option (only for Option_Integer)
#define WRITE_MESSAGE(msg)
OptionsCont()
Constructor.
std::vector< std::pair< std::string, std::string > > myCallExamples
list of call examples
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void setApplicationName(const std::string &appName, const std::string &fullName)
Sets the application name.