|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Parses the command line arguments 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 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) { 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 (ProcessError& e) { 00060 WRITE_ERROR("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) { 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) { 00123 if (arg[1]=='=') { 00124 if (strlen(arg)<3) { 00125 WRITE_ERROR("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 WRITE_ERROR("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) { 00143 if (arg1[0]!='-') { 00144 WRITE_ERROR("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) { 00153 return arg1[1]!='-'; 00154 } 00155 00156 00157 std::string 00158 OptionsParser::convert(char* arg) { 00159 std::string s(arg); 00160 return s; 00161 } 00162 00163 00164 std::string 00165 OptionsParser::convert(char abbr) { 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