LCOV - code coverage report
Current view: top level - lib/roken - getarg.c (source / functions) Hit Total Coverage
Test: samba_4_0_test.lcov.info Lines: 54 336 16.1 %
Date: 2014-04-02 Functions: 3 11 27.3 %
Branches: 29 230 12.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan
       3                 :            :  * (Royal Institute of Technology, Stockholm, Sweden).
       4                 :            :  * All rights reserved.
       5                 :            :  *
       6                 :            :  * Redistribution and use in source and binary forms, with or without
       7                 :            :  * modification, are permitted provided that the following conditions
       8                 :            :  * are met:
       9                 :            :  *
      10                 :            :  * 1. Redistributions of source code must retain the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer.
      12                 :            :  *
      13                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :            :  *    notice, this list of conditions and the following disclaimer in the
      15                 :            :  *    documentation and/or other materials provided with the distribution.
      16                 :            :  *
      17                 :            :  * 3. Neither the name of the Institute nor the names of its contributors
      18                 :            :  *    may be used to endorse or promote products derived from this software
      19                 :            :  *    without specific prior written permission.
      20                 :            :  *
      21                 :            :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31                 :            :  * SUCH DAMAGE.
      32                 :            :  */
      33                 :            : 
      34                 :            : #include <config.h>
      35                 :            : 
      36                 :            : #include <stdio.h>
      37                 :            : #include <stdlib.h>
      38                 :            : #include <string.h>
      39                 :            : #include "roken.h"
      40                 :            : #include "getarg.h"
      41                 :            : 
      42                 :            : #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
      43                 :            : 
      44                 :            : static size_t
      45                 :          0 : print_arg (char *string,
      46                 :            :            size_t len,
      47                 :            :            int mdoc,
      48                 :            :            int longp,
      49                 :            :            struct getargs *arg,
      50                 :            :            char *(i18n)(const char *))
      51                 :            : {
      52                 :            :     const char *s;
      53                 :            : 
      54                 :          0 :     *string = '\0';
      55                 :            : 
      56 [ #  # ][ #  # ]:          0 :     if (ISFLAG(*arg) || (!longp && arg->type == arg_counter))
         [ #  # ][ #  # ]
      57                 :          0 :         return 0;
      58                 :            : 
      59         [ #  # ]:          0 :     if(mdoc){
      60         [ #  # ]:          0 :         if(longp)
      61                 :          0 :             strlcat(string, "= Ns", len);
      62                 :          0 :         strlcat(string, " Ar ", len);
      63                 :            :     } else {
      64         [ #  # ]:          0 :         if (longp)
      65                 :          0 :             strlcat (string, "=", len);
      66                 :            :         else
      67                 :          0 :             strlcat (string, " ", len);
      68                 :            :     }
      69                 :            : 
      70         [ #  # ]:          0 :     if (arg->arg_help)
      71                 :          0 :         s = (*i18n)(arg->arg_help);
      72 [ #  # ][ #  # ]:          0 :     else if (arg->type == arg_integer || arg->type == arg_counter)
      73                 :          0 :         s = "integer";
      74         [ #  # ]:          0 :     else if (arg->type == arg_string)
      75                 :          0 :         s = "string";
      76         [ #  # ]:          0 :     else if (arg->type == arg_strings)
      77                 :          0 :         s = "strings";
      78         [ #  # ]:          0 :     else if (arg->type == arg_double)
      79                 :          0 :         s = "float";
      80                 :            :     else
      81                 :          0 :         s = "<undefined>";
      82                 :            : 
      83                 :          0 :     strlcat(string, s, len);
      84                 :          0 :     return 1 + strlen(s);
      85                 :            : }
      86                 :            : 
      87                 :            : static void
      88                 :          0 : mandoc_template(struct getargs *args,
      89                 :            :                 size_t num_args,
      90                 :            :                 const char *progname,
      91                 :            :                 const char *extra_string,
      92                 :            :                 char *(i18n)(const char *))
      93                 :            : {
      94                 :            :     size_t i;
      95                 :            :     char timestr[64], cmd[64];
      96                 :            :     char buf[128];
      97                 :            :     const char *p;
      98                 :            :     time_t t;
      99                 :            : 
     100                 :          0 :     printf(".\\\" Things to fix:\n");
     101                 :          0 :     printf(".\\\"   * correct section, and operating system\n");
     102                 :          0 :     printf(".\\\"   * remove Op from mandatory flags\n");
     103                 :          0 :     printf(".\\\"   * use better macros for arguments (like .Pa for files)\n");
     104                 :          0 :     printf(".\\\"\n");
     105                 :          0 :     t = time(NULL);
     106                 :          0 :     strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t));
     107                 :          0 :     printf(".Dd %s\n", timestr);
     108                 :          0 :     p = strrchr(progname, '/');
     109         [ #  # ]:          0 :     if(p) p++; else p = progname;
     110                 :          0 :     strlcpy(cmd, p, sizeof(cmd));
     111                 :          0 :     strupr(cmd);
     112                 :            : 
     113                 :          0 :     printf(".Dt %s SECTION\n", cmd);
     114                 :          0 :     printf(".Os OPERATING_SYSTEM\n");
     115                 :          0 :     printf(".Sh NAME\n");
     116                 :          0 :     printf(".Nm %s\n", p);
     117                 :          0 :     printf(".Nd in search of a description\n");
     118                 :          0 :     printf(".Sh SYNOPSIS\n");
     119                 :          0 :     printf(".Nm\n");
     120         [ #  # ]:          0 :     for(i = 0; i < num_args; i++){
     121                 :            :         /* we seem to hit a limit on number of arguments if doing
     122                 :            :            short and long flags with arguments -- split on two lines */
     123 [ #  # ][ #  # ]:          0 :         if(ISFLAG(args[i]) ||
         [ #  # ][ #  # ]
     124                 :          0 :            args[i].short_name == 0 || args[i].long_name == NULL) {
     125                 :          0 :             printf(".Op ");
     126                 :            : 
     127         [ #  # ]:          0 :             if(args[i].short_name) {
     128                 :          0 :                 print_arg(buf, sizeof(buf), 1, 0, args + i, i18n);
     129                 :          0 :                 printf("Fl %c%s", args[i].short_name, buf);
     130         [ #  # ]:          0 :                 if(args[i].long_name)
     131                 :          0 :                     printf(" | ");
     132                 :            :             }
     133         [ #  # ]:          0 :             if(args[i].long_name) {
     134                 :          0 :                 print_arg(buf, sizeof(buf), 1, 1, args + i, i18n);
     135         [ #  # ]:          0 :                 printf("Fl Fl %s%s%s",
     136                 :          0 :                        args[i].type == arg_negative_flag ? "no-" : "",
     137                 :          0 :                        args[i].long_name, buf);
     138                 :            :             }
     139                 :          0 :             printf("\n");
     140                 :            :         } else {
     141                 :          0 :             print_arg(buf, sizeof(buf), 1, 0, args + i, i18n);
     142                 :          0 :             printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf);
     143                 :          0 :             print_arg(buf, sizeof(buf), 1, 1, args + i, i18n);
     144                 :          0 :             printf(".Fl Fl %s%s\n.Xc\n.Oc\n", args[i].long_name, buf);
     145                 :            :         }
     146                 :            :     /*
     147                 :            :             if(args[i].type == arg_strings)
     148                 :            :                 fprintf (stderr, "...");
     149                 :            :                 */
     150                 :            :     }
     151 [ #  # ][ #  # ]:          0 :     if (extra_string && *extra_string)
     152                 :          0 :         printf (".Ar %s\n", extra_string);
     153                 :          0 :     printf(".Sh DESCRIPTION\n");
     154                 :          0 :     printf("Supported options:\n");
     155                 :          0 :     printf(".Bl -tag -width Ds\n");
     156         [ #  # ]:          0 :     for(i = 0; i < num_args; i++){
     157                 :          0 :         printf(".It Xo\n");
     158         [ #  # ]:          0 :         if(args[i].short_name){
     159                 :          0 :             printf(".Fl %c", args[i].short_name);
     160                 :          0 :             print_arg(buf, sizeof(buf), 1, 0, args + i, i18n);
     161                 :          0 :             printf("%s", buf);
     162         [ #  # ]:          0 :             if(args[i].long_name)
     163                 :          0 :                 printf(" ,");
     164                 :          0 :             printf("\n");
     165                 :            :         }
     166         [ #  # ]:          0 :         if(args[i].long_name){
     167         [ #  # ]:          0 :             printf(".Fl Fl %s%s",
     168                 :          0 :                    args[i].type == arg_negative_flag ? "no-" : "",
     169                 :          0 :                    args[i].long_name);
     170                 :          0 :             print_arg(buf, sizeof(buf), 1, 1, args + i, i18n);
     171                 :          0 :             printf("%s\n", buf);
     172                 :            :         }
     173                 :          0 :         printf(".Xc\n");
     174         [ #  # ]:          0 :         if(args[i].help)
     175                 :          0 :             printf("%s\n", args[i].help);
     176                 :            :     /*
     177                 :            :             if(args[i].type == arg_strings)
     178                 :            :                 fprintf (stderr, "...");
     179                 :            :                 */
     180                 :            :     }
     181                 :          0 :     printf(".El\n");
     182                 :          0 :     printf(".\\\".Sh ENVIRONMENT\n");
     183                 :          0 :     printf(".\\\".Sh FILES\n");
     184                 :          0 :     printf(".\\\".Sh EXAMPLES\n");
     185                 :          0 :     printf(".\\\".Sh DIAGNOSTICS\n");
     186                 :          0 :     printf(".\\\".Sh SEE ALSO\n");
     187                 :          0 :     printf(".\\\".Sh STANDARDS\n");
     188                 :          0 :     printf(".\\\".Sh HISTORY\n");
     189                 :          0 :     printf(".\\\".Sh AUTHORS\n");
     190                 :          0 :     printf(".\\\".Sh BUGS\n");
     191                 :          0 : }
     192                 :            : 
     193                 :            : static int
     194                 :          0 : check_column(FILE *f, int col, int len, int columns)
     195                 :            : {
     196         [ #  # ]:          0 :     if(col + len > columns) {
     197                 :          0 :         fprintf(f, "\n");
     198                 :          0 :         col = fprintf(f, "  ");
     199                 :            :     }
     200                 :          0 :     return col;
     201                 :            : }
     202                 :            : 
     203                 :            : static char *
     204                 :          0 : builtin_i18n(const char *str)
     205                 :            : {
     206                 :          0 :     return rk_UNCONST(str);
     207                 :            : }
     208                 :            : 
     209                 :            : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     210                 :          0 : arg_printusage (struct getargs *args,
     211                 :            :                 size_t num_args,
     212                 :            :                 const char *progname,
     213                 :            :                 const char *extra_string)
     214                 :            : {
     215                 :          0 :     arg_printusage_i18n(args, num_args, "Usage",
     216                 :            :                         progname, extra_string, builtin_i18n);
     217                 :          0 : }
     218                 :            : 
     219                 :            : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     220                 :          0 : arg_printusage_i18n (struct getargs *args,
     221                 :            :                      size_t num_args,
     222                 :            :                      const char *usage,
     223                 :            :                      const char *progname,
     224                 :            :                      const char *extra_string,
     225                 :            :                      char *(*i18n)(const char *))
     226                 :            : {
     227                 :          0 :     size_t i, max_len = 0;
     228                 :            :     char buf[128];
     229                 :          0 :     int col = 0, columns;
     230                 :            : 
     231         [ #  # ]:          0 :     if (progname == NULL)
     232                 :          0 :         progname = getprogname();
     233                 :            : 
     234         [ #  # ]:          0 :     if (i18n == NULL)
     235                 :          0 :         i18n = builtin_i18n;
     236                 :            : 
     237         [ #  # ]:          0 :     if(getenv("GETARGMANDOC")){
     238                 :          0 :         mandoc_template(args, num_args, progname, extra_string, i18n);
     239                 :          0 :         return;
     240                 :            :     }
     241         [ #  # ]:          0 :     if(get_window_size(2, NULL, &columns) == -1)
     242                 :          0 :         columns = 80;
     243                 :          0 :     col = 0;
     244                 :          0 :     col += fprintf (stderr, "%s: %s", usage, progname);
     245                 :          0 :     buf[0] = '\0';
     246         [ #  # ]:          0 :     for (i = 0; i < num_args; ++i) {
     247 [ #  # ][ #  # ]:          0 :         if(args[i].short_name && ISFLAG(args[i])) {
                 [ #  # ]
     248                 :            :             char s[2];
     249         [ #  # ]:          0 :             if(buf[0] == '\0')
     250                 :          0 :                 strlcpy(buf, "[-", sizeof(buf));
     251                 :          0 :             s[0] = args[i].short_name;
     252                 :          0 :             s[1] = '\0';
     253                 :          0 :             strlcat(buf, s, sizeof(buf));
     254                 :            :         }
     255                 :            :     }
     256         [ #  # ]:          0 :     if(buf[0] != '\0') {
     257                 :          0 :         strlcat(buf, "]", sizeof(buf));
     258                 :          0 :         col = check_column(stderr, col, strlen(buf) + 1, columns);
     259                 :          0 :         col += fprintf(stderr, " %s", buf);
     260                 :            :     }
     261                 :            : 
     262         [ #  # ]:          0 :     for (i = 0; i < num_args; ++i) {
     263                 :          0 :         size_t len = 0;
     264                 :            : 
     265         [ #  # ]:          0 :         if (args[i].long_name) {
     266                 :          0 :             buf[0] = '\0';
     267                 :          0 :             strlcat(buf, "[--", sizeof(buf));
     268                 :          0 :             len += 2;
     269         [ #  # ]:          0 :             if(args[i].type == arg_negative_flag) {
     270                 :          0 :                 strlcat(buf, "no-", sizeof(buf));
     271                 :          0 :                 len += 3;
     272                 :            :             }
     273                 :          0 :             strlcat(buf, args[i].long_name, sizeof(buf));
     274                 :          0 :             len += strlen(args[i].long_name);
     275                 :          0 :             len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
     276                 :          0 :                              0, 1, &args[i], i18n);
     277                 :          0 :             strlcat(buf, "]", sizeof(buf));
     278         [ #  # ]:          0 :             if(args[i].type == arg_strings)
     279                 :          0 :                 strlcat(buf, "...", sizeof(buf));
     280                 :          0 :             col = check_column(stderr, col, strlen(buf) + 1, columns);
     281                 :          0 :             col += fprintf(stderr, " %s", buf);
     282                 :            :         }
     283 [ #  # ][ #  # ]:          0 :         if (args[i].short_name && !ISFLAG(args[i])) {
                 [ #  # ]
     284                 :          0 :             snprintf(buf, sizeof(buf), "[-%c", args[i].short_name);
     285                 :          0 :             len += 2;
     286                 :          0 :             len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf),
     287                 :          0 :                              0, 0, &args[i], i18n);
     288                 :          0 :             strlcat(buf, "]", sizeof(buf));
     289         [ #  # ]:          0 :             if(args[i].type == arg_strings)
     290                 :          0 :                 strlcat(buf, "...", sizeof(buf));
     291                 :          0 :             col = check_column(stderr, col, strlen(buf) + 1, columns);
     292                 :          0 :             col += fprintf(stderr, " %s", buf);
     293                 :            :         }
     294 [ #  # ][ #  # ]:          0 :         if (args[i].long_name && args[i].short_name)
     295                 :          0 :             len += 2; /* ", " */
     296                 :          0 :         max_len = max(max_len, len);
     297                 :            :     }
     298         [ #  # ]:          0 :     if (extra_string) {
     299                 :          0 :         check_column(stderr, col, strlen(extra_string) + 1, columns);
     300                 :          0 :         fprintf (stderr, " %s\n", extra_string);
     301                 :            :     } else
     302                 :          0 :         fprintf (stderr, "\n");
     303         [ #  # ]:          0 :     for (i = 0; i < num_args; ++i) {
     304         [ #  # ]:          0 :         if (args[i].help) {
     305                 :          0 :             size_t count = 0;
     306                 :            : 
     307         [ #  # ]:          0 :             if (args[i].short_name) {
     308                 :          0 :                 count += fprintf (stderr, "-%c", args[i].short_name);
     309                 :          0 :                 print_arg (buf, sizeof(buf), 0, 0, &args[i], i18n);
     310                 :          0 :                 count += fprintf(stderr, "%s", buf);
     311                 :            :             }
     312 [ #  # ][ #  # ]:          0 :             if (args[i].short_name && args[i].long_name)
     313                 :          0 :                 count += fprintf (stderr, ", ");
     314         [ #  # ]:          0 :             if (args[i].long_name) {
     315                 :          0 :                 count += fprintf (stderr, "--");
     316         [ #  # ]:          0 :                 if (args[i].type == arg_negative_flag)
     317                 :          0 :                     count += fprintf (stderr, "no-");
     318                 :          0 :                 count += fprintf (stderr, "%s", args[i].long_name);
     319                 :          0 :                 print_arg (buf, sizeof(buf), 0, 1, &args[i], i18n);
     320                 :          0 :                 count += fprintf(stderr, "%s", buf);
     321                 :            :             }
     322         [ #  # ]:          0 :             while(count++ <= max_len)
     323                 :          0 :                 putc (' ', stderr);
     324                 :          0 :             fprintf (stderr, "%s\n", (*i18n)(args[i].help));
     325                 :            :         }
     326                 :            :     }
     327                 :            : }
     328                 :            : 
     329                 :            : static int
     330                 :         18 : add_string(getarg_strings *s, char *value)
     331                 :            : {
     332                 :            :     char **strings;
     333                 :            : 
     334                 :         18 :     strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings));
     335         [ -  + ]:         18 :     if (strings == NULL) {
     336                 :          0 :         free(s->strings);
     337                 :          0 :         s->strings = NULL;
     338                 :          0 :         s->num_strings = 0;
     339                 :          0 :         return ENOMEM;
     340                 :            :     }
     341                 :         18 :     s->strings = strings;
     342                 :         18 :     s->strings[s->num_strings] = value;
     343                 :         18 :     s->num_strings++;
     344                 :         18 :     return 0;
     345                 :            : }
     346                 :            : 
     347                 :            : static int
     348                 :         36 : arg_match_long(struct getargs *args, size_t num_args,
     349                 :            :                char *argv, int argc, char **rargv, int *goptind)
     350                 :            : {
     351                 :            :     size_t i;
     352                 :         36 :     char *goptarg = NULL;
     353                 :         36 :     int negate = 0;
     354                 :         36 :     int partial_match = 0;
     355                 :         36 :     struct getargs *partial = NULL;
     356                 :         36 :     struct getargs *current = NULL;
     357                 :            :     int argv_len;
     358                 :            :     char *p;
     359                 :            :     int p_len;
     360                 :            : 
     361                 :         36 :     argv_len = strlen(argv);
     362                 :         36 :     p = strchr (argv, '=');
     363         [ +  + ]:         36 :     if (p != NULL)
     364                 :         20 :         argv_len = p - argv;
     365                 :            : 
     366         [ +  - ]:        221 :     for (i = 0; i < num_args; ++i) {
     367         [ +  - ]:        221 :         if(args[i].long_name) {
     368                 :        221 :             int len = strlen(args[i].long_name);
     369                 :        221 :             p = argv;
     370                 :        221 :             p_len = argv_len;
     371                 :        221 :             negate = 0;
     372                 :            : 
     373                 :            :             for (;;) {
     374         [ +  + ]:        221 :                 if (strncmp (args[i].long_name, p, p_len) == 0) {
     375         [ +  - ]:         36 :                     if(p_len == len)
     376                 :         36 :                         current = &args[i];
     377                 :            :                     else {
     378                 :          0 :                         ++partial_match;
     379                 :          0 :                         partial = &args[i];
     380                 :            :                     }
     381                 :         36 :                     goptarg  = p + p_len;
     382 [ +  + ][ -  + ]:        185 :                 } else if (ISFLAG(args[i]) && strncmp (p, "no-", 3) == 0) {
                 [ -  + ]
     383                 :          0 :                     negate = !negate;
     384                 :          0 :                     p += 3;
     385                 :          0 :                     p_len -= 3;
     386                 :          0 :                     continue;
     387                 :            :                 }
     388                 :            :                 break;
     389                 :          0 :             }
     390         [ +  + ]:        221 :             if (current)
     391                 :         36 :                 break;
     392                 :            :         }
     393                 :            :     }
     394         [ -  + ]:         36 :     if (current == NULL) {
     395         [ #  # ]:          0 :         if (partial_match == 1)
     396                 :          0 :             current = partial;
     397                 :            :         else
     398                 :          0 :             return ARG_ERR_NO_MATCH;
     399                 :            :     }
     400                 :            : 
     401 [ +  + ][ -  + ]:         36 :     if(*goptarg == '\0'
         [ #  # ][ #  # ]
                 [ #  # ]
     402                 :            :        && !ISFLAG(*current)
     403                 :            :        && current->type != arg_collect
     404                 :          0 :        && current->type != arg_counter)
     405                 :          0 :         return ARG_ERR_NO_MATCH;
     406   [ -  +  +  +  :         36 :     switch(current->type){
             -  -  -  - ]
     407                 :            :     case arg_integer:
     408                 :            :     {
     409                 :            :         int tmp;
     410         [ #  # ]:          0 :         if(sscanf(goptarg + 1, "%d", &tmp) != 1)
     411                 :          0 :             return ARG_ERR_BAD_ARG;
     412                 :          0 :         *(int*)current->value = tmp;
     413                 :          0 :         return 0;
     414                 :            :     }
     415                 :            :     case arg_string:
     416                 :            :     {
     417                 :          2 :         *(char**)current->value = goptarg + 1;
     418                 :          2 :         return 0;
     419                 :            :     }
     420                 :            :     case arg_strings:
     421                 :            :     {
     422                 :         18 :         return add_string((getarg_strings*)current->value, goptarg + 1);
     423                 :            :     }
     424                 :            :     case arg_flag:
     425                 :            :     case arg_negative_flag:
     426                 :            :     {
     427                 :         16 :         int *flag = current->value;
     428 [ -  + ][ #  # ]:         16 :         if(*goptarg == '\0' ||
                 [ #  # ]
     429                 :          0 :            strcmp(goptarg + 1, "yes") == 0 ||
     430                 :          0 :            strcmp(goptarg + 1, "true") == 0){
     431                 :         16 :             *flag = !negate;
     432                 :         16 :             return 0;
     433 [ #  # ][ #  # ]:          0 :         } else if (*goptarg && strcmp(goptarg + 1, "maybe") == 0) {
     434                 :          0 :             *flag = rk_random() & 1;
     435                 :            :         } else {
     436                 :          0 :             *flag = negate;
     437                 :          0 :             return 0;
     438                 :            :         }
     439                 :          0 :         return ARG_ERR_BAD_ARG;
     440                 :            :     }
     441                 :            :     case arg_counter :
     442                 :            :     {
     443                 :            :         int val;
     444                 :            : 
     445         [ #  # ]:          0 :         if (*goptarg == '\0')
     446                 :          0 :             val = 1;
     447         [ #  # ]:          0 :         else if(sscanf(goptarg + 1, "%d", &val) != 1)
     448                 :          0 :             return ARG_ERR_BAD_ARG;
     449                 :          0 :         *(int *)current->value += val;
     450                 :          0 :         return 0;
     451                 :            :     }
     452                 :            :     case arg_double:
     453                 :            :     {
     454                 :            :         double tmp;
     455         [ #  # ]:          0 :         if(sscanf(goptarg + 1, "%lf", &tmp) != 1)
     456                 :          0 :             return ARG_ERR_BAD_ARG;
     457                 :          0 :         *(double*)current->value = tmp;
     458                 :          0 :         return 0;
     459                 :            :     }
     460                 :            :     case arg_collect:{
     461                 :          0 :         struct getarg_collect_info *c = current->value;
     462                 :          0 :         int o = argv - rargv[*goptind];
     463                 :          0 :         return (*c->func)(FALSE, argc, rargv, goptind, &o, c->data);
     464                 :            :     }
     465                 :            : 
     466                 :            :     default:
     467                 :         36 :         abort ();
     468                 :            :         UNREACHABLE(return 0);
     469                 :            :     }
     470                 :            : }
     471                 :            : 
     472                 :            : static int
     473                 :          0 : arg_match_short (struct getargs *args, size_t num_args,
     474                 :            :                  char *argv, int argc, char **rargv, int *goptind)
     475                 :            : {
     476                 :            :     size_t j, k;
     477                 :            : 
     478 [ #  # ][ #  # ]:          0 :     for(j = 1; j > 0 && j < strlen(rargv[*goptind]); j++) {
     479         [ #  # ]:          0 :         for(k = 0; k < num_args; k++) {
     480                 :            :             char *goptarg;
     481                 :            : 
     482         [ #  # ]:          0 :             if(args[k].short_name == 0)
     483                 :          0 :                 continue;
     484         [ #  # ]:          0 :             if(argv[j] == args[k].short_name) {
     485         [ #  # ]:          0 :                 if(args[k].type == arg_flag) {
     486                 :          0 :                     *(int*)args[k].value = 1;
     487                 :          0 :                     break;
     488                 :            :                 }
     489         [ #  # ]:          0 :                 if(args[k].type == arg_negative_flag) {
     490                 :          0 :                     *(int*)args[k].value = 0;
     491                 :          0 :                     break;
     492                 :            :                 }
     493         [ #  # ]:          0 :                 if(args[k].type == arg_counter) {
     494                 :          0 :                     ++*(int *)args[k].value;
     495                 :          0 :                     break;
     496                 :            :                 }
     497         [ #  # ]:          0 :                 if(args[k].type == arg_collect) {
     498                 :          0 :                     struct getarg_collect_info *c = args[k].value;
     499                 :          0 :                     int a = (int)j;
     500                 :            : 
     501         [ #  # ]:          0 :                     if((*c->func)(TRUE, argc, rargv, goptind, &a, c->data))
     502                 :          0 :                         return ARG_ERR_BAD_ARG;
     503                 :          0 :                     j = a;
     504                 :          0 :                     break;
     505                 :            :                 }
     506                 :            : 
     507         [ #  # ]:          0 :                 if(argv[j + 1])
     508                 :          0 :                     goptarg = &argv[j + 1];
     509                 :            :                 else {
     510                 :          0 :                     ++*goptind;
     511                 :          0 :                     goptarg = rargv[*goptind];
     512                 :            :                 }
     513         [ #  # ]:          0 :                 if(goptarg == NULL) {
     514                 :          0 :                     --*goptind;
     515                 :          0 :                     return ARG_ERR_NO_ARG;
     516                 :            :                 }
     517         [ #  # ]:          0 :                 if(args[k].type == arg_integer) {
     518                 :            :                     int tmp;
     519         [ #  # ]:          0 :                     if(sscanf(goptarg, "%d", &tmp) != 1)
     520                 :          0 :                         return ARG_ERR_BAD_ARG;
     521                 :          0 :                     *(int*)args[k].value = tmp;
     522                 :          0 :                     return 0;
     523         [ #  # ]:          0 :                 } else if(args[k].type == arg_string) {
     524                 :          0 :                     *(char**)args[k].value = goptarg;
     525                 :          0 :                     return 0;
     526         [ #  # ]:          0 :                 } else if(args[k].type == arg_strings) {
     527                 :          0 :                     return add_string((getarg_strings*)args[k].value, goptarg);
     528         [ #  # ]:          0 :                 } else if(args[k].type == arg_double) {
     529                 :            :                     double tmp;
     530         [ #  # ]:          0 :                     if(sscanf(goptarg, "%lf", &tmp) != 1)
     531                 :          0 :                         return ARG_ERR_BAD_ARG;
     532                 :          0 :                     *(double*)args[k].value = tmp;
     533                 :          0 :                     return 0;
     534                 :            :                 }
     535                 :          0 :                 return ARG_ERR_BAD_ARG;
     536                 :            :             }
     537                 :            :         }
     538         [ #  # ]:          0 :         if (k == num_args)
     539                 :          0 :             return ARG_ERR_NO_MATCH;
     540                 :            :     }
     541                 :          0 :     return 0;
     542                 :            : }
     543                 :            : 
     544                 :            : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
     545                 :         26 : getarg(struct getargs *args, size_t num_args,
     546                 :            :        int argc, char **argv, int *goptind)
     547                 :            : {
     548                 :            :     int i;
     549                 :         26 :     int ret = 0;
     550                 :            : 
     551                 :         26 :     rk_random_init();
     552                 :         26 :     (*goptind)++;
     553         [ +  + ]:         62 :     for(i = *goptind; i < argc; i++) {
     554         [ +  + ]:         60 :         if(argv[i][0] != '-')
     555                 :         24 :             break;
     556         [ +  - ]:         36 :         if(argv[i][1] == '-'){
     557         [ -  + ]:         36 :             if(argv[i][2] == 0){
     558                 :          0 :                 i++;
     559                 :          0 :                 break;
     560                 :            :             }
     561                 :         36 :             ret = arg_match_long (args, num_args, argv[i] + 2,
     562                 :            :                                   argc, argv, &i);
     563                 :            :         } else {
     564                 :          0 :             ret = arg_match_short (args, num_args, argv[i],
     565                 :            :                                    argc, argv, &i);
     566                 :            :         }
     567         [ -  + ]:         36 :         if(ret)
     568                 :          0 :             break;
     569                 :            :     }
     570                 :         26 :     *goptind = i;
     571                 :         26 :     return ret;
     572                 :            : }
     573                 :            : 
     574                 :            : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     575                 :          0 : free_getarg_strings (getarg_strings *s)
     576                 :            : {
     577                 :          0 :     free (s->strings);
     578                 :          0 : }
     579                 :            : 
     580                 :            : #if TEST
     581                 :            : int foo_flag = 2;
     582                 :            : int flag1 = 0;
     583                 :            : int flag2 = 0;
     584                 :            : int bar_int;
     585                 :            : char *baz_string;
     586                 :            : 
     587                 :            : struct getargs args[] = {
     588                 :            :     { NULL, '1', arg_flag, &flag1, "one", NULL },
     589                 :            :     { NULL, '2', arg_flag, &flag2, "two", NULL },
     590                 :            :     { "foo", 'f', arg_negative_flag, &foo_flag, "foo", NULL },
     591                 :            :     { "bar", 'b', arg_integer, &bar_int, "bar", "seconds"},
     592                 :            :     { "baz", 'x', arg_string, &baz_string, "baz", "name" },
     593                 :            : };
     594                 :            : 
     595                 :            : int main(int argc, char **argv)
     596                 :            : {
     597                 :            :     int goptind = 0;
     598                 :            :     while(getarg(args, 5, argc, argv, &goptind))
     599                 :            :         printf("Bad arg: %s\n", argv[goptind]);
     600                 :            :     printf("flag1 = %d\n", flag1);
     601                 :            :     printf("flag2 = %d\n", flag2);
     602                 :            :     printf("foo_flag = %d\n", foo_flag);
     603                 :            :     printf("bar_int = %d\n", bar_int);
     604                 :            :     printf("baz_flag = %s\n", baz_string);
     605                 :            :     arg_printusage (args, 5, argv[0], "nothing here");
     606                 :            : }
     607                 :            : #endif

Generated by: LCOV version 1.9