SUMO - Simulation of Urban MObility
OptionsParser.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines