52 #ifdef CHECK_MEMORY_LEAKS
54 #endif // CHECK_MEMORY_LEAKS
73 : myAddresses(), myValues(), myDeprecatedSynonymes(), myHaveInformedAboutDeprecatedDivider(false) {
74 myCopyrightNotices.push_back(
"Copyright (C) 2001-2014 DLR and contributors; http://sumo-sim.org");
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();
338 if (files.size() == 0) {
339 WRITE_ERROR(
"The file list for '" + name +
"' is empty.");
342 for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
345 WRITE_ERROR(
"File '" + *fileIt +
"' is not accessible.");
363 std::vector<std::string> seenSynonymes;
364 for (KnownContType::const_iterator i =
myValues.begin(); i !=
myValues.end(); i++) {
365 if (std::find(seenSynonymes.begin(), seenSynonymes.end(), (*i).first) != seenSynonymes.end()) {
368 if ((*i).second->isSet() && !(*i).second->isDefault() && (*i).first.find(prefix) == 0) {
369 WRITE_ERROR(
"Option '" + (*i).first +
"' needs option '" + name +
"'.");
370 std::vector<std::string> synonymes =
getSynonymes((*i).first);
371 std::copy(synonymes.begin(), synonymes.end(), std::back_inserter(seenSynonymes));
382 std::ostringstream s;
383 s <<
"A value for the option '" + arg +
"' was already set.\n Possible synonymes: ";
384 for (std::vector<std::string>::iterator i = synonymes.begin(); i != synonymes.end();) {
387 if (i != synonymes.end()) {
415 (*i)->resetWritable();
429 ItemAddressContType::iterator i;
442 const std::string& subtopic,
443 const std::string& description) {
454 const std::string& fullName) {
499 size_t offset,
size_t nextOffset) {
500 while (what.length() > 0) {
501 if (what.length() > 79 - offset) {
502 size_t splitPos = what.rfind(
';', 79 - offset);
503 if (splitPos == std::string::npos) {
504 splitPos = what.rfind(
' ', 79 - offset);
508 if (splitPos != std::string::npos) {
509 os << what.substr(0, splitPos) << std::endl;
510 what = what.substr(splitPos);
511 for (
size_t r = 0; r < nextOffset + 1; ++r) {
530 if (missingOptions) {
533 for (std::vector<std::string>::const_iterator it =
535 std::cout <<
" " << *it << std::endl;
537 std::cout <<
" License GPLv3+: GNU GPL Version 3 or later <http://gnu.org/licenses/gpl.html>\n";
538 std::cout <<
" Use --help to get the list of options." << std::endl;
545 for (std::vector<std::string>::const_iterator it =
547 std::cout <<
" " << *it << std::endl;
555 for (std::vector<std::string>::const_iterator it =
557 std::cout <<
" " << *it << std::endl;
559 std::cout <<
"\n" <<
myFullName <<
" is part of SUMO.\n";
560 std::cout <<
"SUMO is free software: you can redistribute it and/or modify\n";
561 std::cout <<
"it under the terms of the GNU General Public License as published by\n";
562 std::cout <<
"the Free Software Foundation, either version 3 of the License, or\n";
563 std::cout <<
"(at your option) any later version.\n\n";
564 std::cout <<
"This program is distributed in the hope that it will be useful,\n";
565 std::cout <<
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
566 std::cout <<
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n";
567 std::cout <<
"GNU General Public License for more details.\n\n";
568 std::cout <<
"You should have received a copy of the GNU General Public License\n";
569 std::cout <<
"along with this program. If not, see http://www.gnu.org/licenses/gpl.html" << std::endl;
574 std::cout << (*this);
578 if (
isSet(
"save-configuration",
false)) {
579 if (
getString(
"save-configuration") ==
"-" ||
getString(
"save-configuration") ==
"stdout") {
583 std::ofstream out(
getString(
"save-configuration").c_str());
595 if (
isSet(
"save-template",
false)) {
600 std::ofstream out(
getString(
"save-template").c_str());
611 if (
isSet(
"save-schema",
false)) {
616 std::ofstream out(
getString(
"save-schema").c_str());
632 std::vector<std::string>::const_iterator i, j;
637 os <<
"Usage: " <<
myAppName <<
" [OPTION]*" << std::endl;
645 size_t tooLarge = 40;
649 for (j = entries.begin(); j != entries.end(); ++j) {
652 size_t csize = (*j).length() + 2 + 4;
655 if (find_if(synonymes.begin(), synonymes.end(),
abbreviation_finder()) != synonymes.end()) {
664 if (csize < tooLarge && maxSize < csize) {
671 os << *i <<
" Options:" << std::endl;
673 for (j = entries.begin(); j != entries.end(); ++j) {
675 size_t csize = (*j).length() + 2;
680 std::vector<std::string>::iterator a = find_if(synonymes.begin(), synonymes.end(),
abbreviation_finder());
681 if (a != synonymes.end()) {
682 os <<
'-' << (*a) <<
", ";
698 for (
size_t r = maxSize; r > csize; --r) {
701 size_t offset = csize > tooLarge ? csize : maxSize;
709 os <<
"Examples:" << std::endl;
711 os <<
" " <<
myAppName <<
' ' << e->first << std::endl;
712 os <<
" " << e->second << std::endl;
716 os <<
"Report bugs at <http://sumo-sim.org/trac/>." << std::endl;
717 os <<
"Get in contact via <sumo-user@lists.sourceforge.net>." << std::endl;
723 bool complete,
bool addComments)
const {
725 os <<
"<configuration xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://sumo-sim.org/xsd/" <<
myAppName <<
"Configuration.xsd\">" << std::endl << std::endl;
727 std::string subtopic = *i;
728 if (subtopic ==
"Configuration" && !complete) {
731 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
732 std::transform(subtopic.begin(), subtopic.end(), subtopic.begin(), tolower);
735 for (std::vector<std::string>::const_iterator j = entries.begin(); j != entries.end(); ++j) {
737 bool write = complete || (filled && !o->
isDefault());
742 os <<
" <" << subtopic <<
">" << std::endl;
749 os <<
" <" << *j <<
" value=\"";
755 if (!synonymes.empty()) {
756 os <<
"\" synonymes=\"";
757 for (std::vector<std::string>::const_iterator s = synonymes.begin(); s != synonymes.end(); ++s) {
758 if (s != synonymes.begin()) {
769 os <<
"\"/>" << std::endl;
777 os <<
" </" << subtopic <<
">" << std::endl << std::endl;
780 os <<
"</configuration>" << std::endl;
787 os <<
"<xsd:schema elementFormDefault=\"qualified\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n\n";
788 os <<
" <xsd:include schemaLocation=\"baseTypes.xsd\"/>\n";
789 os <<
" <xsd:element name=\"configuration\" type=\"configurationType\"/>\n\n";
790 os <<
" <xsd:complexType name=\"configurationType\">\n";
791 os <<
" <xsd:all>\n";
793 std::string subtopic = *i;
794 if (subtopic ==
"Configuration") {
797 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
798 std::transform(subtopic.begin(), subtopic.end(), subtopic.begin(), tolower);
799 os <<
" <xsd:element name=\"" << subtopic <<
"\" type=\"" << subtopic <<
"Type\" minOccurs=\"0\"/>\n";
801 os <<
" </xsd:all>\n";
802 os <<
" </xsd:complexType>\n\n";
804 std::string subtopic = *i;
805 if (subtopic ==
"Configuration") {
808 std::replace(subtopic.begin(), subtopic.end(),
' ',
'_');
809 std::transform(subtopic.begin(), subtopic.end(), subtopic.begin(), tolower);
810 os <<
" <xsd:complexType name=\"" << subtopic <<
"Type\">\n";
811 os <<
" <xsd:all>\n";
813 for (std::vector<std::string>::const_iterator j = entries.begin(); j != entries.end(); ++j) {
816 std::transform(type.begin(), type.end(), type.begin(), tolower);
817 if (type ==
"int[]") {
820 os <<
" <xsd:element name=\"" << *j <<
"\" type=\"" << type <<
"OptionType\" minOccurs=\"0\"/>\n";
822 os <<
" </xsd:all>\n";
823 os <<
" </xsd:complexType>\n\n";
825 os <<
"</xsd:schema>\n";
836 strftime(buffer, 80,
"<!-- generated on %c by ", localtime(&rawtime));
843 std::vector<std::string>
848 WRITE_WARNING(
"Please note that using ';' as list separator is deprecated.\n From 1.0 onwards, only ',' will be accepted.");
852 std::vector<std::string> ret = st.
getVector();
853 for (std::vector<std::string>::iterator i = ret.begin(); i != ret.end(); ++i) {
862 const std::string& itemName) {
863 if (
isSet(optionName)) {
865 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.