LCOV - code coverage report
Current view: top level - AP_HAL/utility - getopt_cpp.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 80 84 95.2 %
Date: 2026-09-09 11:02:08 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * getopt_long() -- long options parser
       3             :  *
       4             :  * Portions Copyright (c) 1987, 1993, 1994
       5             :  * The Regents of the University of California.  All rights reserved.
       6             :  *
       7             :  * Portions Copyright (c) 2003
       8             :  * PostgreSQL Global Development Group
       9             :  *
      10             :  * Simple conversion to C++ by Andrew Tridgell for ArduPilot. Based on
      11             :  * getopt_long.cpp from ccache
      12             :  *
      13             :  * Redistribution and use in source and binary forms, with or without
      14             :  * modification, are permitted provided that the following conditions
      15             :  * are met:
      16             :  * 1. Redistributions of source code must retain the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer.
      18             :  * 2. Redistributions in binary form must reproduce the above copyright
      19             :  *    notice, this list of conditions and the following disclaimer in the
      20             :  *    documentation and/or other materials provided with the distribution.
      21             :  * 3. Neither the name of the University nor the names of its contributors
      22             :  *    may be used to endorse or promote products derived from this software
      23             :  *    without specific prior written permission.
      24             :  *
      25             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      26             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      27             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      28             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      29             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      30             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      31             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      32             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      33             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      34             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      35             :  * SUCH DAMAGE.
      36             :  */
      37             : 
      38             : #include <AP_HAL/AP_HAL.h>
      39             : 
      40             : #include "getopt_cpp.h"
      41             : #include <stdio.h>
      42             : #include <string.h>
      43             : 
      44             : #define GETOPT_ERROR(...) ::printf(__VA_ARGS__)
      45             : 
      46             : 
      47             : /*
      48             :   constructor
      49             :  */
      50        2128 : GetOptLong::GetOptLong(int _argc, char *const _argv[], const char *_optstring, const GetOptLong::option * _longopts) :
      51        2128 :     opterr(0),
      52        2128 :     optind(1),
      53        2128 :     optopt(0),
      54        2128 :     longindex(-1),
      55        2128 :     optarg(nullptr),
      56        2128 :     argc(_argc),
      57        2128 :     argv(_argv),
      58        2128 :     optstring(_optstring),
      59        2128 :     longopts(_longopts),
      60        2128 :     place("")
      61        2128 : {}
      62             : 
      63             : /*
      64             :   main parse code
      65             :  */
      66       11200 : int GetOptLong::getoption(void)
      67             : {
      68             :     const char        *oli;          /* option letter list index */
      69             : 
      70       11200 :     if (!*place)
      71             :     { /* update scanning pointer */
      72       11198 :         if (optind >= argc)
      73             :         {
      74        2108 :             place = "";
      75        2108 :             return -1;
      76             :         }
      77             : 
      78        9090 :         place = argv[optind];
      79             : 
      80        9090 :         if (place[0] != '-')
      81             :         {
      82           4 :             place = "";
      83           4 :             return -1;
      84             :         }
      85             :         
      86        9086 :         place++;
      87             :         
      88        9086 :         if (place[0] && place[0] == '-' && place[1] == '\0')
      89             :         { /* found "--" */
      90           2 :             ++optind;
      91           2 :             place = "";
      92           2 :             return -1;
      93             :         }
      94             : 
      95        9084 :         if (place[0] && place[0] == '-' && place[1])
      96             :         {
      97             :             /* long option */
      98             :             size_t namelen;
      99             :             int    i;
     100             :             
     101        8761 :             place++;
     102             :             
     103        8761 :             namelen = strcspn(place, "=");
     104      142696 :             for (i = 0; longopts[i].name != nullptr; i++)
     105             :             {
     106      142694 :                 if (strlen(longopts[i].name) == namelen
     107       25497 :                     && strncmp(place, longopts[i].name, namelen) == 0)
     108             :                 {
     109        8759 :                     if (longopts[i].has_arg)
     110             :                     {
     111        8741 :                         if (place[namelen] == '=')
     112        2398 :                             optarg = place + namelen + 1;
     113        6343 :                         else if (optind < argc - 1)
     114             :                         {
     115        6339 :                             optind++;
     116        6339 :                             optarg = argv[optind];
     117             :                         }
     118             :                         else
     119             :                         {
     120           4 :                             if (optstring[0] == ':')
     121           2 :                                 return BADARG;
     122           2 :                             if (opterr) {
     123           0 :                                 GETOPT_ERROR("%s: option requires an argument -- %s\n",
     124             :                                              argv[0], place);
     125             :                             }
     126           2 :                             place = "";
     127           2 :                             optind++;
     128           2 :                             return BADCH;
     129             :                         }
     130             :                     }
     131             :                     else
     132             :                     {
     133          18 :                         optarg = nullptr;
     134          18 :                         if (place[namelen] != 0)
     135             :                         {
     136             :                             /* XXX error? */
     137             :                         }
     138             :                     }
     139             :                     
     140        8755 :                     optind++;
     141             :                     
     142        8755 :                     longindex = i;
     143             :                     
     144        8755 :                     place = "";
     145             :                     
     146        8755 :                     if (longopts[i].flag == nullptr)
     147        8753 :                         return longopts[i].val;
     148             :                     else
     149             :                     {
     150           2 :                         *longopts[i].flag = longopts[i].val;
     151           2 :                         return 0;
     152             :                     }
     153             :                 }
     154             :             }
     155             :             
     156           2 :             if (opterr && optstring[0] != ':') {
     157           0 :                 GETOPT_ERROR("%s: illegal option -- %s\n", argv[0], place);
     158             :             }
     159           2 :             place = "";
     160           2 :             optind++;
     161           2 :             return BADCH;
     162             :         }
     163             :     }
     164             : 
     165             :     /* short option */
     166         325 :     optopt = (int) *place++;
     167             : 
     168         325 :     oli = strchr(optstring, optopt);
     169         325 :     if (!oli)
     170             :     {
     171           2 :         if (!*place)
     172           2 :             ++optind;
     173           2 :         if (opterr && *optstring != ':') {
     174           0 :             GETOPT_ERROR("%s: illegal option -- %c\n", argv[0], optopt);
     175             :         }
     176           2 :         return BADCH;
     177             :     }
     178             :     
     179         323 :     if (oli[1] != ':')
     180             :     { /* don't need argument */
     181         302 :         optarg = nullptr;
     182         302 :         if (!*place)
     183         300 :             ++optind;
     184             :     }
     185             :     else
     186             :     { /* need an argument */
     187          21 :         if (*place) /* no white space */
     188           2 :             optarg = place;
     189          19 :         else if (argc <= ++optind)
     190             :         { /* no arg */
     191           4 :             place = "";
     192           4 :             if (*optstring == ':')
     193           2 :                 return BADARG;
     194           2 :             if (opterr) {
     195           0 :                 GETOPT_ERROR("%s: option requires an argument -- %c\n",
     196             :                              argv[0], optopt);
     197             :             }
     198           2 :             return BADCH;
     199             :         }
     200             :         else
     201             :             /* white space */
     202          15 :             optarg = argv[optind];
     203          17 :         place = "";
     204          17 :         ++optind;
     205             :     }
     206         319 :     return optopt;
     207             : }
     208             : 

Generated by: LCOV version 1.14