LCOV - code coverage report
Current view: top level - src/utils/options - OptionsParser.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 58 62 93.5 %
Date: 2024-05-01 15:34:42 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2001-2024 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             : /// @date    Mon, 17 Dec 2001
      19             : ///
      20             : // Parses the command line arguments
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : #include <iostream>
      25             : #include <cstring>
      26             : #include "Option.h"
      27             : #include "OptionsCont.h"
      28             : #include "OptionsParser.h"
      29             : #include <utils/common/UtilExceptions.h>
      30             : #include <utils/common/MsgHandler.h>
      31             : 
      32             : 
      33             : // ===========================================================================
      34             : // method definitions
      35             : // ===========================================================================
      36             : bool
      37       96399 : OptionsParser::parse(const std::vector<std::string>& args, const bool ignoreAppenders) {
      38       96399 :     bool ok = true;
      39       96399 :     const int argc = (int)args.size();
      40      858002 :     for (int i = 1; i < argc;) {
      41             :         try {
      42             :             int add;
      43             :             // try to set the current option
      44      761603 :             if (i < argc - 1) {
      45      721834 :                 add = check(args[i], &args[i + 1], ok, ignoreAppenders);
      46             :             } else {
      47       39769 :                 add = check(args[i], nullptr, ok, ignoreAppenders);
      48             :             }
      49      761555 :             i += add;
      50          48 :         } catch (ProcessError& e) {
      51          96 :             WRITE_ERROR("On processing option '" + args[i] + "':\n " + e.what());
      52          48 :             i++;
      53          48 :             ok = false;
      54          48 :         }
      55             :     }
      56       96399 :     return ok;
      57             : }
      58             : 
      59             : 
      60             : int
      61      761603 : OptionsParser::check(const std::string& arg1, const std::string* const arg2, bool& ok, const bool ignoreAppenders) {
      62             :     // the first argument should be an option
      63             :     // (only the second may be a free string)
      64      761603 :     if (!checkParameter(arg1)) {
      65          44 :         ok = false;
      66          44 :         return 1;
      67             :     }
      68             : 
      69      761559 :     OptionsCont& oc = OptionsCont::getOptions();
      70      761559 :     const bool append = arg1[0] == '+';
      71             :     // process not abbreviated switches
      72      761559 :     if (append || arg1[1] == '-') {
      73     1176754 :         const std::string tmp(arg1.substr(append ? 1 : 2));
      74      588401 :         const std::string::size_type idx1 = tmp.find('=');
      75      588401 :         if (append && ignoreAppenders) {
      76          32 :             return idx1 == std::string::npos ? 2 : 1;
      77             :         }
      78             :         // check whether a parameter was submitted
      79      588377 :         if (idx1 != std::string::npos) {
      80      124775 :             ok &= oc.set(tmp.substr(0, idx1), tmp.substr(idx1 + 1), append);
      81             :         } else {
      82      503550 :             if (arg2 == nullptr || (oc.isBool(tmp) && (*arg2)[0] == '-')) {
      83      211428 :                 ok &= oc.set(tmp, "true");
      84             :             } else {
      85      292142 :                 ok &= oc.set(tmp, *arg2, append);
      86      292142 :                 return 2;
      87             :             }
      88             :         }
      89      296187 :         return 1;
      90             :     }
      91             :     // go through the abbreviated switches
      92      173158 :     const int len = (int)arg1.size();
      93      206550 :     for (int i = 1; i < len; i++) {
      94             :         // set boolean switches
      95      173158 :         const std::string abbr = arg1.substr(i, 1);
      96      173158 :         if (oc.isBool(abbr)) {
      97       33392 :             if (arg2 == nullptr || (*arg2)[0] == '-' || i != len - 1) {
      98       33392 :                 ok &= oc.set(abbr, "true");
      99             :             } else {
     100           0 :                 ok &= oc.set(abbr, *arg2);
     101           0 :                 return 2;
     102             :             }
     103             :             // set non-boolean switches
     104             :         } else {
     105             :             // check whether the parameter comes directly after the switch
     106             :             //  and process if so
     107      139766 :             if (arg2 == nullptr || i != len - 1) {
     108        8195 :                 ok &= processNonBooleanSingleSwitch(oc, arg1.substr(i), append);
     109        8195 :                 return 1;
     110             :                 // process parameter following after a space
     111             :             } else {
     112      131571 :                 ok &= oc.set(abbr, *arg2, append);
     113             :                 // option name and attribute were in two arguments
     114      131571 :                 return 2;
     115             :             }
     116             :         }
     117             :     }
     118             :     // all switches within the current argument were boolean switches
     119             :     return 1;
     120             : }
     121             : 
     122             : 
     123             : bool
     124        8195 : OptionsParser::processNonBooleanSingleSwitch(OptionsCont& oc, const std::string& arg, const bool append) {
     125        8195 :     if (arg[1] == '=') {
     126        8184 :         if (arg.size() < 3) {
     127           0 :             WRITE_ERRORF(TL("Missing value for parameter '%'."), arg.substr(0, 1));
     128           0 :             return false;
     129             :         } else {
     130       24548 :             return oc.set(arg.substr(0, 1), arg.substr(2), append);
     131             :         }
     132             :     } else {
     133          11 :         if (arg.size() < 2) {
     134           3 :             WRITE_ERRORF(TL("Missing value for parameter '%'."), arg);
     135           1 :             return false;
     136             :         } else {
     137          24 :             return oc.set(arg.substr(0, 1), arg.substr(1), append);
     138             :         }
     139             :     }
     140             : }
     141             : 
     142             : 
     143             : bool
     144      761603 : OptionsParser::checkParameter(const std::string& arg1) {
     145      761603 :     if (arg1[0] != '-' && arg1[0] != '+') {
     146          84 :         WRITE_ERRORF(TL("The parameter '%' is not allowed in this context.\n Switch or parameter name expected."), arg1);
     147          28 :         return false;
     148             :     }
     149      761575 :     if ((arg1[0] == '-' && arg1[1] == '+') || (arg1[0] == '+' && arg1[1] == '-')) {
     150          48 :         WRITE_ERRORF(TL("Mixed parameter syntax in '%'."), arg1);
     151          16 :         return false;
     152             :     }
     153             :     return true;
     154             : }
     155             : 
     156             : 
     157             : /****************************************************************************/

Generated by: LCOV version 1.14