OptionsCont.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // A storage for options (typed value containers)
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 // ===========================================================================
00020 // included modules
00021 // ===========================================================================
00022 #ifdef _MSC_VER
00023 #include <windows_config.h>
00024 #else
00025 #include <config.h>
00026 #endif
00027 
00028 #include <map>
00029 #include <string>
00030 #include <exception>
00031 #include <algorithm>
00032 #include <vector>
00033 #include <iostream>
00034 #include <cstdlib>
00035 #include <cassert>
00036 #include <ctime>
00037 #include "Option.h"
00038 #include "OptionsCont.h"
00039 #include <utils/common/UtilExceptions.h>
00040 #include <utils/common/FileHelpers.h>
00041 #include <utils/common/MsgHandler.h>
00042 #include <utils/common/StringTokenizer.h>
00043 #include <utils/common/StringUtils.h>
00044 #include <sstream>
00045 
00046 #ifdef CHECK_MEMORY_LEAKS
00047 #include <foreign/nvwa/debug_new.h>
00048 #endif // CHECK_MEMORY_LEAKS
00049 
00050 
00051 // ===========================================================================
00052 // static member definitions
00053 // ===========================================================================
00054 OptionsCont OptionsCont::myOptions;
00055 
00056 
00057 // ===========================================================================
00058 // method definitions
00059 // ===========================================================================
00060 OptionsCont &
00061 OptionsCont::getOptions() throw() {
00062     return myOptions;
00063 }
00064 
00065 
00066 OptionsCont::OptionsCont() throw()
00067         : myAddresses(), myValues(), myHaveInformedAboutDeprecatedDivider(false) {}
00068 
00069 
00070 OptionsCont::~OptionsCont() throw() {
00071     clear();
00072 }
00073 
00074 
00075 void
00076 OptionsCont::doRegister(const std::string &name, Option *v) throw(InvalidArgument) {
00077     assert(v!=0);
00078     ItemAddressContType::iterator i = find(myAddresses.begin(), myAddresses.end(), v);
00079     if (i==myAddresses.end()) {
00080         myAddresses.push_back(v);
00081     }
00082     if (myValues.find(name)!=myValues.end()) {
00083         throw InvalidArgument(name + " is an already used option name.");
00084     }
00085     myValues[name] = v;
00086 }
00087 
00088 
00089 void
00090 OptionsCont::doRegister(const std::string &name1, char abbr, Option *v) throw(InvalidArgument) {
00091     doRegister(name1, v);
00092     doRegister(convertChar(abbr), v);
00093 }
00094 
00095 
00096 void
00097 OptionsCont::addSynonyme(const std::string &name1, const std::string &name2) throw(InvalidArgument) {
00098     KnownContType::iterator i1 = myValues.find(name1);
00099     KnownContType::iterator i2 = myValues.find(name2);
00100     if (i1==myValues.end()&&i2==myValues.end()) {
00101         throw InvalidArgument("Neither the option '" + name1 + "' nor the option '" + name2 + "' is known yet");
00102     }
00103     if (i1!=myValues.end()&&i2!=myValues.end()) {
00104         if ((*i1).second==(*i2).second) {
00105             return;
00106         }
00107         throw InvalidArgument("Both options '" + name1 + "' and '" + name2 + "' do exist and differ.");
00108     }
00109     if (i1==myValues.end()&&i2!=myValues.end()) {
00110         doRegister(name1, (*i2).second);
00111     }
00112     if (i1!=myValues.end()&&i2==myValues.end()) {
00113         doRegister(name2, (*i1).second);
00114     }
00115 }
00116 
00117 
00118 bool
00119 OptionsCont::exists(const std::string &name) const throw() {
00120     KnownContType::const_iterator i = myValues.find(name);
00121     return i!=myValues.end();
00122 }
00123 
00124 
00125 bool
00126 OptionsCont::isSet(const std::string &name) const throw(InvalidArgument) {
00127     KnownContType::const_iterator i = myValues.find(name);
00128     if (i==myValues.end()) {
00129         return false;
00130     }
00131     return (*i).second->isSet();
00132 }
00133 
00134 
00135 bool
00136 OptionsCont::isDefault(const std::string &name) const throw(InvalidArgument) {
00137     KnownContType::const_iterator i = myValues.find(name);
00138     if (i==myValues.end()) {
00139         return false;
00140     }
00141     return (*i).second->isDefault();
00142 }
00143 
00144 
00145 Option *
00146 OptionsCont::getSecure(const std::string &name) const throw(InvalidArgument) {
00147     KnownContType::const_iterator i = myValues.find(name);
00148     if (i==myValues.end()) {
00149         throw InvalidArgument("No option with the name '" + name + "' exists.");
00150     }
00151     return (*i).second;
00152 }
00153 
00154 
00155 std::string
00156 OptionsCont::getString(const std::string &name) const throw(InvalidArgument) {
00157     Option *o = getSecure(name);
00158     return o->getString();
00159 }
00160 
00161 
00162 SUMOReal
00163 OptionsCont::getFloat(const std::string &name) const throw(InvalidArgument) {
00164     Option *o = getSecure(name);
00165     return o->getFloat();
00166 }
00167 
00168 
00169 int
00170 OptionsCont::getInt(const std::string &name) const throw(InvalidArgument) {
00171     Option *o = getSecure(name);
00172     return o->getInt();
00173 }
00174 
00175 
00176 bool
00177 OptionsCont::getBool(const std::string &name) const throw(InvalidArgument) {
00178     Option *o = getSecure(name);
00179     return o->getBool();
00180 }
00181 
00182 
00183 const IntVector &
00184 OptionsCont::getIntVector(const std::string &name) const throw(InvalidArgument) {
00185     Option *o = getSecure(name);
00186     return o->getIntVector();
00187 }
00188 
00189 
00190 bool
00191 OptionsCont::set(const std::string &name, const std::string &value) throw(InvalidArgument) {
00192     Option *o = getSecure(name);
00193     if (!o->isWriteable()) {
00194         reportDoubleSetting(name);
00195         return false;
00196     }
00197     try {
00198         if (!o->set(value)) {
00199             return false;
00200         }
00201     } catch (InvalidArgument &e) {
00202         MsgHandler::getErrorInstance()->inform("While processing option '" + name + "':\n " + e.what());
00203         return false;
00204     }
00205     return true;
00206 }
00207 
00208 
00209 bool
00210 OptionsCont::set(const std::string &name, bool value) throw(InvalidArgument) {
00211     Option *o = getSecure(name);
00212     if (!o->isBool()) {
00213         throw InvalidArgument("The option '" + name + "' is not a boolean attribute and requires an argument.");
00214     }
00215     if (!o->isWriteable()) {
00216         reportDoubleSetting(name);
00217         return false;
00218     }
00219     try {
00220         if (!o->set(value)) {
00221             return false;
00222         }
00223     } catch (InvalidArgument &e) {
00224         MsgHandler::getErrorInstance()->inform("While processing option '" + name + "':\n " + e.what());
00225         return false;
00226     }
00227     return true;
00228 }
00229 
00230 
00231 std::vector<std::string>
00232 OptionsCont::getSynonymes(const std::string &name) const throw(InvalidArgument) {
00233     Option *o = getSecure(name);
00234     std::vector<std::string> v(0);
00235     for (KnownContType::const_iterator i=myValues.begin(); i!=myValues.end(); i++) {
00236         if ((*i).second==o&&name!=(*i).first) {
00237             v.push_back((*i).first);
00238         }
00239     }
00240     return v;
00241 }
00242 
00243 
00244 std::ostream&
00245 operator<<(std::ostream& os, const OptionsCont& oc) {
00246     std::vector<std::string> done;
00247     os << "Options set:" << std::endl;
00248     for (OptionsCont::KnownContType::const_iterator i=oc.myValues.begin();
00249             i!=oc.myValues.end(); i++) {
00250         std::vector<std::string>::iterator j = find(done.begin(), done.end(), (*i).first);
00251         if (j==done.end()) {
00252             std::vector<std::string> synonymes = oc.getSynonymes((*i).first);
00253             if (synonymes.size()!=0) {
00254                 os << (*i).first << " (";
00255                 for (j=synonymes.begin(); j!=synonymes.end(); j++) {
00256                     if (j!=synonymes.begin()) {
00257                         os << ", ";
00258                     }
00259                     os << (*j);
00260                 }
00261                 os << ")";
00262             } else {
00263                 os << (*i).first;
00264             }
00265             if ((*i).second->isSet()) {
00266                 os << ": " << (*i).second->getValueString() << std::endl;
00267             } else {
00268                 os << ": <INVALID>" << std::endl;
00269             }
00270             done.push_back((*i).first);
00271             copy(synonymes.begin(), synonymes.end(), back_inserter(done));
00272         }
00273     }
00274     return os;
00275 }
00276 
00277 
00278 void
00279 OptionsCont::relocateFiles(const std::string &configuration) const throw() {
00280     for (ItemAddressContType::const_iterator i=myAddresses.begin(); i!=myAddresses.end(); i++) {
00281         if ((*i)->isFileName() && (*i)->isSet()) {
00282             StringTokenizer st((*i)->getString(), ";, ", true);
00283             std::string conv;
00284             while (st.hasNext()) {
00285                 if (conv.length()!=0) {
00286                     conv += ',';
00287                 }
00288                 std::string tmp = st.next();
00289                 if (!FileHelpers::isAbsolute(tmp)) {
00290                     tmp = FileHelpers::getConfigurationRelative(configuration, tmp);
00291                 }
00292                 conv += tmp;
00293             }
00294             (*i)->set(conv);
00295         }
00296     }
00297 }
00298 
00299 
00300 bool
00301 OptionsCont::isUsableFileList(const std::string &name) const throw(InvalidArgument) {
00302     Option *o = getSecure(name);
00303     // check whether the option is set
00304     //  return false i not
00305     if (!o->isSet()) {
00306         return false;
00307     }
00308     // check whether the list of files is valid
00309     bool ok = true;
00310     std::vector<std::string> files = getStringVector(name);
00311     if (files.size()==0) {
00312         MsgHandler::getErrorInstance()->inform("The file list for '" + name + "' is empty.");
00313         ok = false;
00314     }
00315     for (std::vector<std::string>::const_iterator fileIt=files.begin(); fileIt!=files.end(); ++fileIt) {
00316         if (!FileHelpers::exists(*fileIt)) {
00317             if (*fileIt!="") {
00318                 MsgHandler::getErrorInstance()->inform("File '" + *fileIt + "' does not exist.");
00319                 ok = false;
00320             } else {
00321                 MsgHandler::getWarningInstance()->inform("Empty file name given; ignoring.");
00322             }
00323         }
00324     }
00325     return ok;
00326 }
00327 
00328 
00329 bool
00330 OptionsCont::checkDependingSuboptions(const std::string &name, const std::string &prefix) const throw(InvalidArgument) {
00331     Option *o = getSecure(name);
00332     if (o->isSet()) {
00333         return true;
00334     }
00335     bool ok = true;
00336     for (KnownContType::const_iterator i=myValues.begin(); i!=myValues.end(); i++) {
00337         if ((*i).second->isSet() && !(*i).second->isDefault() && (*i).first.find(prefix) == 0) {
00338             MsgHandler::getErrorInstance()->inform("Option '" + (*i).first + "' needs option '" + name + "'.");
00339             ok = false;
00340         }
00341     }
00342     return ok;
00343 }
00344 
00345 
00346 void
00347 OptionsCont::reportDoubleSetting(const std::string &arg) const throw() {
00348     std::vector<std::string> synonymes = getSynonymes(arg);
00349     std::ostringstream s;
00350     s << "A value for the option '" + arg + "' was already set.\n Possible synonymes: ";
00351     for (std::vector<std::string>::iterator i=synonymes.begin(); i!=synonymes.end();) {
00352         s << (*i);
00353         i++;
00354         if (i!=synonymes.end()) {
00355             s << ", ";
00356         }
00357     }
00358     MsgHandler::getErrorInstance()->inform(s.str());
00359 }
00360 
00361 
00362 std::string
00363 OptionsCont::convertChar(char abbr) const throw() {
00364     char buf[2];
00365     buf[0] = abbr;
00366     buf[1] = 0;
00367     std::string s(buf);
00368     return s;
00369 }
00370 
00371 
00372 bool
00373 OptionsCont::isBool(const std::string &name) const throw(InvalidArgument) {
00374     Option *o = getSecure(name);
00375     return o->isBool();
00376 }
00377 
00378 
00379 void
00380 OptionsCont::resetWritable() throw() {
00381     for (ItemAddressContType::iterator i=myAddresses.begin(); i!=myAddresses.end(); i++) {
00382         (*i)->myAmWritable = true;
00383     }
00384 }
00385 
00386 
00387 bool
00388 OptionsCont::isWriteable(const std::string &name) throw(InvalidArgument) {
00389     Option *o = getSecure(name);
00390     return o->isWriteable();
00391 }
00392 
00393 
00394 void
00395 OptionsCont::clear() throw() {
00396     ItemAddressContType::iterator i;
00397     for (i=myAddresses.begin(); i!=myAddresses.end(); i++) {
00398         delete(*i);
00399     }
00400     myAddresses.clear();
00401     myValues.clear();
00402     mySubTopics.clear();
00403     mySubTopicEntries.clear();
00404 }
00405 
00406 
00407 void
00408 OptionsCont::addDescription(const std::string &name,
00409                             const std::string &subtopic,
00410                             const std::string &description) throw(InvalidArgument) {
00411     Option *o = getSecure(name);
00412     assert(o!=0);
00413     assert(o->myDescription=="");
00414     assert(find(mySubTopics.begin(), mySubTopics.end(), subtopic)!=mySubTopics.end());
00415     o->myDescription = description;
00416     mySubTopicEntries[subtopic].push_back(name);
00417 }
00418 
00419 
00420 void
00421 OptionsCont::setApplicationName(const std::string &appName,
00422                                 const std::string &fullName) throw() {
00423     myAppName = appName;
00424     myFullName = fullName;
00425 }
00426 
00427 
00428 void
00429 OptionsCont::setApplicationDescription(const std::string &appDesc) throw() {
00430     myAppDescription = appDesc;
00431 }
00432 
00433 
00434 void
00435 OptionsCont::addCallExample(const std::string &example) throw() {
00436     myCallExamples.push_back(example);
00437 }
00438 
00439 
00440 void
00441 OptionsCont::setAdditionalHelpMessage(const std::string &add) throw() {
00442     myAdditionalMessage = add;
00443 }
00444 
00445 
00446 void
00447 OptionsCont::addOptionSubTopic(const std::string &topic) throw() {
00448     mySubTopics.push_back(topic);
00449     mySubTopicEntries[topic] = std::vector<std::string>();
00450 }
00451 
00452 
00453 void
00454 OptionsCont::splitLines(std::ostream &os, std::string what,
00455                         size_t offset, size_t nextOffset) throw() {
00456     while (what.length()>0) {
00457         if (what.length()>79-offset) {
00458             size_t splitPos = what.rfind(';', 79-offset);
00459             if (splitPos==std::string::npos) {
00460                 splitPos = what.rfind(' ', 79-offset);
00461             } else {
00462                 splitPos++;
00463             }
00464             if (splitPos!=std::string::npos) {
00465                 os << what.substr(0, splitPos) << std::endl;
00466                 what = what.substr(splitPos);
00467                 for (size_t r=0; r<nextOffset+1; ++r) {
00468                     os << ' ';
00469                 }
00470             } else {
00471                 os << what;
00472                 what = "";
00473             }
00474             offset = nextOffset;
00475         } else {
00476             os << what;
00477             what = "";
00478         }
00479     }
00480     os << std::endl;
00481 }
00482 
00483 
00484 bool
00485 OptionsCont::processMetaOptions(bool missingOptions) throw(ProcessError) {
00486     if (missingOptions) {
00487         // no options are given
00488         std::cout << myFullName << std::endl;
00489         std::cout << " (c) DLR 2001-2009; http://sumo.sourceforge.net" << std::endl;
00490         std::cout << " Use --help to get the list of options." << std::endl;
00491         return true;
00492     }
00493 
00494     OptionsCont &oc = OptionsCont::getOptions();
00495     // check whether the help shall be printed
00496     if (oc.getBool("help")) {
00497         std::cout << myFullName << std::endl;
00498         std::cout << " (c) DLR 2001-2009; http://sumo.sourceforge.net" << std::endl;
00499         oc.printHelp(std::cout);
00500         return true;
00501     }
00502     // check whether the settings shall be printed
00503     if (oc.getBool("print-options")) {
00504         std::cout << oc;
00505     }
00506     // check whether something has to be done with options
00507     // whether the current options shall be saved
00508     if (oc.isSet("save-configuration")) {
00509         std::ofstream out(oc.getString("save-configuration").c_str());
00510         if (!out.good()) {
00511             throw ProcessError("Could not save configuration to '" + oc.getString("save-configuration") + "'");
00512         } else {
00513             oc.writeConfiguration(out, true, false, false);
00514             if (oc.getBool("verbose")) {
00515                 MsgHandler::getMessageInstance()->inform("Written configuration to '" + oc.getString("save-configuration") + "'");
00516             }
00517             return true;
00518         }
00519     }
00520     // whether the template shall be saved
00521     if (oc.isSet("save-template")) {
00522         std::ofstream out(oc.getString("save-template").c_str());
00523         if (!out.good()) {
00524             throw ProcessError("Could not save template to '" + oc.getString("save-template") + "'");
00525         } else {
00526             oc.writeConfiguration(out, false, true, oc.getBool("save-template.commented"));
00527             if (oc.getBool("verbose")) {
00528                 MsgHandler::getMessageInstance()->inform("Written template to '" + oc.getString("save-template") + "'");
00529             }
00530             return true;
00531         }
00532     }
00533     return false;
00534 }
00535 
00536 void
00537 OptionsCont::printHelp(std::ostream &os) throw() {
00538     std::vector<std::string>::const_iterator i, j;
00539     // print application description
00540     os << ' ' << std::endl;
00541     splitLines(os, myAppDescription , 0, 0);
00542     os << std::endl;
00543     // print usage BNF
00544     os << "Usage: " << myAppName << " [OPTION]*" << std::endl;
00545     os << ' ' << std::endl;
00546     // print usage examples
00547     if (myCallExamples.size()>1) {
00548         os << " Examples:" << std::endl;
00549     } else if (myCallExamples.size()!=0) {
00550         os << " Example:" << std::endl;
00551     }
00552     if (myCallExamples.size()!=0) {
00553         for (i=myCallExamples.begin(); i!=myCallExamples.end(); ++i) {
00554             os << "  " << myAppName << ' ' << (*i) << std::endl;
00555         }
00556     }
00557     os << ' ' << std::endl;
00558     // print additional text if any
00559     if (myAdditionalMessage.length()>0) {
00560         os << myAdditionalMessage << std::endl << ' ' << std::endl;
00561     }
00562     // print the options
00563     // check their sizes first
00564     //  we want to know how large the largest not-too-large-entry will be
00565     size_t tooLarge = 40;
00566     size_t maxSize = 0;
00567     for (i=mySubTopics.begin(); i!=mySubTopics.end(); ++i) {
00568         const std::vector<std::string> &entries = mySubTopicEntries[*i];
00569         for (j=entries.begin(); j!=entries.end(); ++j) {
00570             Option *o = getSecure(*j);
00571             // name, two leading spaces and "--"
00572             size_t csize = (*j).length() + 2 + 4;
00573             // abbreviation length ("-X, "->4chars) if any
00574             std::vector<std::string> synonymes = getSynonymes(*j);
00575             if (find_if(synonymes.begin(), synonymes.end(), abbreviation_finder())!=synonymes.end()) {
00576                 csize += 4;
00577             }
00578             // the type name
00579             if (!o->isBool()) {
00580                 csize += 1 + o->getTypeName().length();
00581             }
00582             // divider
00583             csize += 2;
00584             if (csize<tooLarge&&maxSize<csize) {
00585                 maxSize = csize;
00586             }
00587         }
00588     }
00589 
00590     for (i=mySubTopics.begin(); i!=mySubTopics.end(); ++i) {
00591         os << ' ' << *i << " Options:" << std::endl;
00592         const std::vector<std::string> &entries = mySubTopicEntries[*i];
00593         for (j=entries.begin(); j!=entries.end(); ++j) {
00594             // start length computation
00595             size_t csize = (*j).length() + 2;
00596             Option *o = getSecure(*j);
00597             os << "  ";
00598             // write abbreviation if given
00599             std::vector<std::string> synonymes = getSynonymes(*j);
00600             std::vector<std::string>::iterator a = find_if(synonymes.begin(), synonymes.end(), abbreviation_finder());
00601             if (a!=synonymes.end()) {
00602                 os << '-' << (*a) << ", ";
00603                 csize += 4;
00604             }
00605             // write leading '-'/"--"
00606             os << "--";
00607             csize += 2;
00608             // write the name
00609             os << *j;
00610             // write the type if not a bool option
00611             if (!o->isBool()) {
00612                 os << ' ' << o->getTypeName();
00613                 csize += 1 + o->getTypeName().length();
00614             }
00615             csize += 2;
00616             // write the description formatting it
00617             os << "  ";
00618             size_t r;
00619             for (r=maxSize; r>csize; --r) {
00620                 os << ' ';
00621             }
00622             std::string desc = o->getDescription();
00623             size_t offset = csize > tooLarge ? csize : maxSize;
00624             splitLines(os, desc, offset, maxSize);
00625         }
00626         os << std::endl;
00627     }
00628 }
00629 
00630 
00631 void
00632 OptionsCont::writeConfiguration(std::ostream &os, bool filled,
00633                                 bool complete, bool addComments) throw() {
00634     std::vector<std::string>::const_iterator i, j;
00635     os << "<configuration>" << std::endl << std::endl;
00636     for (i=mySubTopics.begin(); i!=mySubTopics.end(); ++i) {
00637         std::string subtopic = *i;
00638         if (subtopic=="Configuration") {
00639             continue;
00640         }
00641         for (size_t k=0; k<subtopic.length(); ++k) {
00642             if (subtopic[k]==' ') {
00643                 subtopic[k] = '_';
00644             }
00645             if (subtopic[k]>='A'&&subtopic[k]<='Z') {
00646                 subtopic[k] = subtopic[k] - 'A' + 'a';
00647             }
00648         }
00649         const std::vector<std::string> &entries = mySubTopicEntries[*i];
00650         bool hadOne = false;
00651         for (j=entries.begin(); j!=entries.end(); ++j) {
00652             Option *o = getSecure(*j);
00653             bool write = complete || (filled&&!o->isDefault());
00654             if (!write) {
00655                 continue;
00656             }
00657             if (!hadOne) {
00658                 os << "    <" << subtopic << ">" << std::endl;
00659             }
00660             // add the comment if wished
00661             if (addComments) {
00662                 os << "        <!-- " << o->getDescription() << " -->" << std::endl;
00663             }
00664             // write the option and the value (if given)
00665             os << "        <" << *j << " value=\"";
00666             if (o->isSet()) {
00667                 os << o->getValueString();
00668             }
00669             os << "\"/>" << std::endl;
00670             // append an endline if a comment was printed
00671             if (addComments) {
00672                 os << std::endl;
00673             }
00674             hadOne = true;
00675         }
00676         if (hadOne) {
00677             os << "    </" << subtopic << ">" << std::endl << std::endl;
00678         }
00679     }
00680     os << "</configuration>" << std::endl;
00681 }
00682 
00683 
00684 void
00685 OptionsCont::writeXMLHeader(std::ostream &os, const bool writeConfig) throw() {
00686     time_t rawtime;
00687     char buffer [80];
00688 
00689     os << "<?xml version=\"1.0\"?>\n\n";
00690     time(&rawtime);
00691     strftime(buffer, 80, "<!-- generated on %c by ", localtime(&rawtime));
00692     os << buffer << myFullName << "\n";
00693     if (writeConfig) {
00694         writeConfiguration(os, true, false, false);
00695     }
00696     os << "-->\n\n";
00697 }
00698 
00699 
00700 std::vector<std::string>
00701 OptionsCont::getStringVector(const std::string &name) const throw(InvalidArgument) {
00702     Option *o = getSecure(name);
00703     std::string def = o->getString();
00704     if (def.find(';')!=std::string::npos&&!myHaveInformedAboutDeprecatedDivider) {
00705         MsgHandler::getWarningInstance()->inform("Please note that using ';' as list separator is deprecated.\n From 1.0 onwards, only ',' will be accepted.");
00706         myHaveInformedAboutDeprecatedDivider = true;
00707     }
00708     StringTokenizer st(def, ";,", true);
00709     std::vector<std::string> ret = st.getVector();
00710     for (std::vector<std::string>::iterator i=ret.begin(); i!=ret.end(); ++i) {
00711         (*i) = StringUtils::prune(*i);
00712     }
00713     return ret;
00714 }
00715 
00716 
00717 bool
00718 OptionsCont::isInStringVector(const std::string &optionName,
00719                               const std::string &itemName) throw(InvalidArgument) {
00720     if (isSet(optionName)) {
00721         std::vector<std::string> values = getStringVector(optionName);
00722         return find(values.begin(), values.end(), itemName)!=values.end();
00723     }
00724     return false;
00725 }
00726 
00727 
00728 /****************************************************************************/

Generated on Wed May 5 00:06:35 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6