SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // Parses the command line arguments 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #include <iostream> 00034 #include <cstring> 00035 #include "Option.h" 00036 #include "OptionsCont.h" 00037 #include "OptionsParser.h" 00038 #include <utils/common/UtilExceptions.h> 00039 #include <utils/common/MsgHandler.h> 00040 00041 #ifdef CHECK_MEMORY_LEAKS 00042 #include <foreign/nvwa/debug_new.h> 00043 #endif // CHECK_MEMORY_LEAKS 00044 00045 00046 // =========================================================================== 00047 // method definitions 00048 // =========================================================================== 00049 bool 00050 OptionsParser::parse(int argc, char** argv) { 00051 bool ok = true; 00052 if (argc == 2 && argv[1][0] != '-') { 00053 // special case only one parameter is handled like config 00054 check("-c", argv[1], ok); 00055 return ok; 00056 } 00057 for (int i = 1; i < argc;) { 00058 try { 00059 int add; 00060 // try to set the current option 00061 if (i < argc - 1) { 00062 add = check(argv[i], argv[i + 1], ok); 00063 } else { 00064 add = check(argv[i], 0, ok); 00065 } 00066 i += add; 00067 } catch (ProcessError& e) { 00068 WRITE_ERROR("On processing option '" + std::string(argv[i]) + "':\n " + e.what()); 00069 i++; 00070 ok = false; 00071 } 00072 } 00073 return ok; 00074 } 00075 00076 00077 int 00078 OptionsParser::check(const char* arg1, const char* arg2, bool& ok) { 00079 // the first argument should be an option 00080 // (only the second may be a free string) 00081 if (!checkParameter(arg1)) { 00082 ok = false; 00083 return 1; 00084 } 00085 00086 OptionsCont& oc = OptionsCont::getOptions(); 00087 // process not abbreviated switches 00088 if (!isAbbreviation(arg1)) { 00089 std::string tmp(arg1 + 2); 00090 size_t idx1 = tmp.find('='); 00091 // check whether a parameter was submitted 00092 if (idx1 != std::string::npos) { 00093 ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1)); 00094 } else { 00095 if (arg2 == 0 || (oc.isBool(convert(arg1 + 2)) && arg2[0] == '-')) { 00096 ok &= oc.set(convert(arg1 + 2), "true"); 00097 } else { 00098 ok &= oc.set(convert(arg1 + 2), convert(arg2)); 00099 return 2; 00100 } 00101 } 00102 return 1; 00103 } 00104 // go through the abbreviated switches 00105 for (int i = 1; arg1[i] != 0; i++) { 00106 // set boolean switches 00107 if (oc.isBool(convert(arg1[i]))) { 00108 if (arg2 == 0 || arg2[0] == '-' || arg1[i + 1] != 0) { 00109 ok &= oc.set(convert(arg1[i]), "true"); 00110 } else { 00111 ok &= oc.set(convert(arg1[i]), convert(arg2)); 00112 return 2; 00113 } 00114 // set non-boolean switches 00115 } else { 00116 // check whether the parameter comes directly after the switch 00117 // and process if so 00118 if (arg2 == 0 || arg1[i + 1] != 0) { 00119 ok &= processNonBooleanSingleSwitch(oc, arg1 + i); 00120 return 1; 00121 // process parameter following after a space 00122 } else { 00123 ok &= oc.set(convert(arg1[i]), convert(arg2)); 00124 // option name and attribute were in two arguments 00125 return 2; 00126 } 00127 } 00128 } 00129 // all switches within the current argument were boolean switches 00130 return 1; 00131 } 00132 00133 00134 bool 00135 OptionsParser::processNonBooleanSingleSwitch(OptionsCont& oc, const char* arg) { 00136 if (arg[1] == '=') { 00137 if (strlen(arg) < 3) { 00138 WRITE_ERROR("Missing value for parameter '" + std::string(arg).substr(0, 1) + "'."); 00139 return false; 00140 } else { 00141 return oc.set(convert(arg[0]), std::string(arg + 2)); 00142 } 00143 } else { 00144 if (strlen(arg) < 2) { 00145 WRITE_ERROR("Missing value for parameter '" + std::string(arg) + "'."); 00146 return false; 00147 } else { 00148 return oc.set(convert(arg[0]), std::string(arg + 1)); 00149 } 00150 } 00151 } 00152 00153 00154 bool 00155 OptionsParser::checkParameter(const char* arg1) { 00156 if (arg1[0] != '-') { 00157 WRITE_ERROR("The parameter '" + std::string(arg1) + "' is not allowed in this context.\n Switch or parameter name expected."); 00158 return false; 00159 } 00160 return true; 00161 } 00162 00163 00164 bool 00165 OptionsParser::isAbbreviation(const char* arg1) { 00166 return arg1[1] != '-'; 00167 } 00168 00169 00170 std::string 00171 OptionsParser::convert(const char* arg) { 00172 std::string s(arg); 00173 return s; 00174 } 00175 00176 00177 std::string 00178 OptionsParser::convert(char abbr) { 00179 char buf[2]; 00180 buf[0] = abbr; 00181 buf[1] = 0; 00182 std::string s(buf); 00183 return buf; 00184 } 00185 00186 00187 00188 /****************************************************************************/ 00189