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();