LCOV - code coverage report
Current view: top level - src/utils/options - OptionsParser.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 96.8 % 62 60
Test Date: 2025-11-13 15:38:19 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    OptionsParser.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @author  Mirko Barthauer
      19              : /// @date    Mon, 17 Dec 2001
      20              : ///
      21              : // Parses the command line arguments
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <iostream>
      26              : #include <cstring>
      27              : #include "Option.h"
      28              : #include "OptionsCont.h"
      29              : #include "OptionsParser.h"
      30              : #include <utils/common/UtilExceptions.h>
      31              : #include <utils/common/MsgHandler.h>
      32              : 
      33              : 
      34              : // ===========================================================================
      35              : // method definitions
      36              : // ===========================================================================
      37              : bool
      38        97079 : OptionsParser::parse(const std::vector<std::string>& args, const bool ignoreAppenders) {
      39        97079 :     bool ok = true;
      40        97079 :     const int argc = (int)args.size();
      41       901591 :     for (int i = 1; i < argc;) {
      42              :         try {
      43              :             int add;
      44              :             // try to set the current option
      45       804512 :             if (i < argc - 1) {
      46       757040 :                 add = check(args[i], &args[i + 1], ok, ignoreAppenders);
      47              :             } else {
      48        47472 :                 add = check(args[i], nullptr, ok, ignoreAppenders);
      49              :             }
      50       804464 :             i += add;
      51           48 :         } catch (ProcessError& e) {
      52           96 :             WRITE_ERROR("On processing option '" + args[i] + "':\n " + e.what());
      53           48 :             i++;
      54           48 :             ok = false;
      55           48 :         }
      56              :     }
      57        97079 :     return ok;
      58              : }
      59              : 
      60              : 
      61              : int
      62       804512 : OptionsParser::check(const std::string& arg1, const std::string* const arg2, bool& ok, const bool ignoreAppenders) {
      63              :     // the first argument should be an option
      64              :     // (only the second may be a free string)
      65       804512 :     if (!checkParameter(arg1)) {
      66           33 :         ok = false;
      67           33 :         return 1;
      68              :     }
      69              : 
      70              : #ifdef _DEBUG
      71              :     // allow to set FOX FXApp switches tracelevel (messages) and maxcolors
      72              :     if ((arg1 == "-tracelevel" || arg1 == "-maxcolors") && arg2 != nullptr) {
      73              :         ok = true;
      74              :         return 2;
      75              :     }
      76              : #endif
      77              : 
      78       804479 :     OptionsCont& oc = OptionsCont::getOptions();
      79       804479 :     const bool append = arg1[0] == '+';
      80              :     // process not abbreviated switches
      81       804479 :     if (append || arg1[1] == '-') {
      82      1268968 :         const std::string tmp(arg1.substr(append ? 1 : 2));
      83       634503 :         const std::string::size_type idx1 = tmp.find('=');
      84       634503 :         if (append && ignoreAppenders) {
      85           23 :             return idx1 == std::string::npos ? 2 : 1;
      86              :         }
      87              :         // check whether a parameter was submitted
      88       634484 :         if (idx1 != std::string::npos) {
      89        92481 :             ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1), append);
      90              :         } else {
      91       542015 :             if (arg2 == nullptr || (oc.isBool(tmp) && (*arg2)[0] == '-')) {
      92       237629 :                 ok &= oc.set(tmp, "true");
      93              :             } else {
      94       304404 :                 ok &= oc.set(tmp, *arg2, append);
      95       304404 :                 return 2;
      96              :             }
      97              :         }
      98       330032 :         return 1;
      99              :     }
     100              :     // go through the abbreviated switches
     101       169976 :     const int len = (int)arg1.size();
     102       206330 :     for (int i = 1; i < len; i++) {
     103              :         // set boolean switches
     104       169976 :         const std::string abbr = arg1.substr(i, 1);
     105       169976 :         if (oc.isBool(abbr)) {
     106        36368 :             if (arg2 == nullptr || (*arg2)[0] == '-' || i != len - 1) {
     107        36354 :                 ok &= oc.set(abbr, "true");
     108              :             } else {
     109           14 :                 ok &= oc.set(abbr, *arg2);
     110           14 :                 return 2;
     111              :             }
     112              :             // set non-boolean switches
     113              :         } else {
     114              :             // check whether the parameter comes directly after the switch
     115              :             //  and process if so
     116       133608 :             if (arg2 == nullptr || i != len - 1) {
     117         9604 :                 ok &= processNonBooleanSingleSwitch(oc, arg1.substr(i), append);
     118         9604 :                 return 1;
     119              :                 // process parameter following after a space
     120              :             } else {
     121       124004 :                 ok &= oc.set(abbr, *arg2, append);
     122              :                 // option name and attribute were in two arguments
     123       124004 :                 return 2;
     124              :             }
     125              :         }
     126              :     }
     127              :     // all switches within the current argument were boolean switches
     128              :     return 1;
     129              : }
     130              : 
     131              : 
     132              : bool
     133         9604 : OptionsParser::processNonBooleanSingleSwitch(OptionsCont& oc, const std::string& arg, const bool append) {
     134         9604 :     if (arg[1] == '=') {
     135         9598 :         if (arg.size() < 3) {
     136            0 :             WRITE_ERRORF(TL("Missing value for parameter '%'."), arg.substr(0, 1));
     137            0 :             return false;
     138              :         } else {
     139        19196 :             return oc.set(arg.substr(0, 1), arg.substr(2), append);
     140              :         }
     141              :     } else {
     142            6 :         if (arg.size() < 2) {
     143            3 :             WRITE_ERRORF(TL("Missing value for parameter '%'."), arg);
     144            1 :             return false;
     145              :         } else {
     146           10 :             return oc.set(arg.substr(0, 1), arg.substr(1), append);
     147              :         }
     148              :     }
     149              : }
     150              : 
     151              : 
     152              : bool
     153       804512 : OptionsParser::checkParameter(const std::string& arg1) {
     154       804512 :     if (arg1[0] != '-' && arg1[0] != '+') {
     155           75 :         WRITE_ERRORF(TL("The parameter '%' is not allowed in this context.\n Switch or parameter name expected."), arg1);
     156           25 :         return false;
     157              :     }
     158       804487 :     if ((arg1[0] == '-' && arg1[1] == '+') || (arg1[0] == '+' && arg1[1] == '-')) {
     159           24 :         WRITE_ERRORF(TL("Mixed parameter syntax in '%'."), arg1);
     160            8 :         return false;
     161              :     }
     162              :     return true;
     163              : }
     164              : 
     165              : 
     166              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1