OptionsParser.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Parses the command line arguments
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 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include <iostream>
00031 #include <cstring>
00032 #include "Option.h"
00033 #include "OptionsCont.h"
00034 #include "OptionsParser.h"
00035 #include <utils/common/UtilExceptions.h>
00036 #include <utils/common/MsgHandler.h>
00037 
00038 #ifdef CHECK_MEMORY_LEAKS
00039 #include <foreign/nvwa/debug_new.h>
00040 #endif // CHECK_MEMORY_LEAKS
00041 
00042 
00043 // ===========================================================================
00044 // method definitions
00045 // ===========================================================================
00046 bool
00047 OptionsParser::parse(int argc, char **argv) throw(InvalidArgument) {
00048     bool ok = true;
00049     for (int i=1; i<argc;) {
00050         try {
00051             int add;
00052             // try to set the current option
00053             if (i<argc-1) {
00054                 add = check(argv[i], argv[i+1], ok);
00055             } else {
00056                 add = check(argv[i], 0, ok);
00057             }
00058             i += add;
00059         } catch (InvalidArgument &e) {
00060             MsgHandler::getErrorInstance()->inform("On processing option '" + std::string(argv[i]) + "':\n " + e.what());
00061             i++;
00062             ok = false;
00063         }
00064     }
00065     return ok;
00066 }
00067 
00068 
00069 int
00070 OptionsParser::check(char *arg1, char *arg2, bool &ok) throw(InvalidArgument) {
00071     // the first argument should be an option
00072     // (only the second may be a free string)
00073     if (!checkParameter(arg1)) {
00074         ok = false;
00075         return 1;
00076     }
00077 
00078     OptionsCont &oc = OptionsCont::getOptions();
00079     // process not abbreviated switches
00080     if (!isAbbreviation(arg1)) {
00081         std::string tmp(arg1+2);
00082         size_t idx1 = tmp.find('=');
00083         // check whether a parameter was submitted
00084         if (idx1!=std::string::npos) {
00085             ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1+1));
00086         } else {
00087             if (arg2==0||oc.isBool(convert(arg1+2))) {
00088                 ok &= oc.set(convert(arg1+2), true);
00089             } else {
00090                 ok &= oc.set(convert(arg1+2), convert(arg2));
00091                 return 2;
00092             }
00093         }
00094         return 1;
00095     }
00096     // go through the abbreviated switches
00097     for (int i=1; arg1[i]!=0; i++) {
00098         // set boolean switches
00099         if (oc.isBool(convert(arg1[i]))) {
00100             ok &= oc.set(convert(arg1[i]), true);
00101             // set non-boolean switches
00102         } else {
00103             // check whether the parameter comes directly after the switch
00104             //  and process if so
00105             if (arg2==0||arg1[i+1]!=0) {
00106                 ok &= processNonBooleanSingleSwitch(oc, arg1+i);
00107                 return 1;
00108                 // process parameter following after a space
00109             } else {
00110                 ok &= oc.set(convert(arg1[i]), convert(arg2));
00111                 // option name and attribute were in two arguments
00112                 return 2;
00113             }
00114         }
00115     }
00116     // all switches within the current argument were boolean switches
00117     return 1;
00118 }
00119 
00120 
00121 bool
00122 OptionsParser::processNonBooleanSingleSwitch(OptionsCont &oc, char *arg) throw(InvalidArgument) {
00123     if (arg[1]=='=') {
00124         if (strlen(arg)<3) {
00125             MsgHandler::getErrorInstance()->inform("Missing value for parameter '" + std::string(arg).substr(0, 1) + "'.");
00126             return false;
00127         } else {
00128             return oc.set(convert(arg[0]), std::string(arg+2));
00129         }
00130     } else {
00131         if (strlen(arg)<2) {
00132             MsgHandler::getErrorInstance()->inform("Missing value for parameter '" + std::string(arg) + "'.");
00133             return false;
00134         } else {
00135             return oc.set(convert(arg[0]), std::string(arg+1));
00136         }
00137     }
00138 }
00139 
00140 
00141 bool
00142 OptionsParser::checkParameter(char *arg1) throw() {
00143     if (arg1[0]!='-') {
00144         MsgHandler::getErrorInstance()->inform("The parameter '" + std::string(arg1) + "' is not allowed in this context.\n Switch or parameter name expected.");
00145         return false;
00146     }
00147     return true;
00148 }
00149 
00150 
00151 bool
00152 OptionsParser::isAbbreviation(char *arg1) throw() {
00153     return arg1[1]!='-';
00154 }
00155 
00156 
00157 std::string
00158 OptionsParser::convert(char *arg) throw() {
00159     std::string s(arg);
00160     return s;
00161 }
00162 
00163 
00164 std::string
00165 OptionsParser::convert(char abbr) throw() {
00166     char buf[2];
00167     buf[0] = abbr;
00168     buf[1] = 0;
00169     std::string s(buf);
00170     return buf;
00171 }
00172 
00173 
00174 
00175 /****************************************************************************/
00176 

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