LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/roken - getarg.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 94 369 25.5 %
Date: 2024-04-21 15:09:00 Functions: 5 11 45.5 %

          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           0 :     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           0 :     size_t i;
      95           0 :     char timestr[64], cmd[64];
      96           0 :     char buf[128];
      97           0 :     const char *p;
      98           0 :     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           0 :     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           0 :             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         591 : add_string(getarg_strings *s, char *value)
     331             : {
     332          31 :     char **strings;
     333             : 
     334         591 :     strings = realloc(s->strings, (s->num_strings + 1) * sizeof(*s->strings));
     335         591 :     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         591 :     s->strings = strings;
     342         591 :     s->strings[s->num_strings] = value;
     343         591 :     s->num_strings++;
     344         591 :     return 0;
     345             : }
     346             : 
     347             : static int
     348        1524 : arg_match_long(struct getargs *args, size_t num_args,
     349             :                char *argv, int argc, char **rargv, int *goptind)
     350             : {
     351          66 :     size_t i;
     352        1524 :     char *goptarg = NULL;
     353        1524 :     int negate = 0;
     354        1524 :     int partial_match = 0;
     355        1524 :     struct getargs *partial = NULL;
     356        1524 :     struct getargs *current = NULL;
     357          66 :     int argv_len;
     358          66 :     char *p;
     359          66 :     int p_len;
     360             : 
     361        1524 :     argv_len = strlen(argv);
     362        1524 :     p = strchr (argv, '=');
     363        1524 :     if (p != NULL)
     364         818 :         argv_len = p - argv;
     365             : 
     366       15189 :     for (i = 0; i < num_args; ++i) {
     367       15189 :         if(args[i].long_name) {
     368       14943 :             int len = strlen(args[i].long_name);
     369       14943 :             p = argv;
     370       14943 :             p_len = argv_len;
     371       14943 :             negate = 0;
     372             : 
     373         552 :             for (;;) {
     374       14943 :                 if (strncmp (args[i].long_name, p, p_len) == 0) {
     375        1524 :                     if(p_len == len)
     376        1458 :                         current = &args[i];
     377             :                     else {
     378           0 :                         ++partial_match;
     379           0 :                         partial = &args[i];
     380             :                     }
     381        1524 :                     goptarg  = p + p_len;
     382       13419 :                 } 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       14943 :                 break;
     389             :             }
     390       14943 :             if (current)
     391        1458 :                 break;
     392             :         }
     393             :     }
     394        1524 :     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        1524 :     if(*goptarg == '\0'
     402         706 :        && !ISFLAG(*current)
     403           0 :        && current->type != arg_collect
     404           0 :        && current->type != arg_counter)
     405           0 :         return ARG_ERR_NO_MATCH;
     406        1524 :     switch(current->type){
     407           0 :     case arg_integer:
     408             :     {
     409           0 :         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         229 :     case arg_string:
     416             :     {
     417         229 :         *(char**)current->value = goptarg + 1;
     418         229 :         return 0;
     419             :     }
     420         589 :     case arg_strings:
     421             :     {
     422         589 :         return add_string((getarg_strings*)current->value, goptarg + 1);
     423             :     }
     424         706 :     case arg_flag:
     425             :     case arg_negative_flag:
     426             :     {
     427         706 :         int *flag = current->value;
     428         706 :         if(*goptarg == '\0' ||
     429           0 :            strcmp(goptarg + 1, "yes") == 0 ||
     430           0 :            strcmp(goptarg + 1, "true") == 0){
     431         706 :             *flag = !negate;
     432         706 :             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           0 :     case arg_counter :
     442             :     {
     443           0 :         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           0 :     case arg_double:
     453             :     {
     454           0 :         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           0 :     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           0 :     default:
     467           0 :         abort ();
     468          66 :         UNREACHABLE(return 0);
     469             :     }
     470             : }
     471             : 
     472             : static int
     473         125 : arg_match_short (struct getargs *args, size_t num_args,
     474             :                  char *argv, int argc, char **rargv, int *goptind)
     475             : {
     476           0 :     size_t j, k;
     477             : 
     478         133 :     for(j = 1; j > 0 && j < strlen(rargv[*goptind]); j++) {
     479         400 :         for(k = 0; k < num_args; k++) {
     480           0 :             char *goptarg;
     481             : 
     482         400 :             if(args[k].short_name == 0)
     483         134 :                 continue;
     484         266 :             if(argv[j] == args[k].short_name) {
     485         125 :                 if(args[k].type == arg_flag) {
     486           8 :                     *(int*)args[k].value = 1;
     487           8 :                     break;
     488             :                 }
     489         117 :                 if(args[k].type == arg_negative_flag) {
     490           0 :                     *(int*)args[k].value = 0;
     491           0 :                     break;
     492             :                 }
     493         117 :                 if(args[k].type == arg_counter) {
     494           0 :                     ++*(int *)args[k].value;
     495           0 :                     break;
     496             :                 }
     497         117 :                 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         117 :                 if(argv[j + 1])
     508           0 :                     goptarg = &argv[j + 1];
     509             :                 else {
     510         117 :                     ++*goptind;
     511         117 :                     goptarg = rargv[*goptind];
     512             :                 }
     513         117 :                 if(goptarg == NULL) {
     514           0 :                     --*goptind;
     515           0 :                     return ARG_ERR_NO_ARG;
     516             :                 }
     517         117 :                 if(args[k].type == arg_integer) {
     518           0 :                     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         117 :                 } else if(args[k].type == arg_string) {
     524         115 :                     *(char**)args[k].value = goptarg;
     525         115 :                     return 0;
     526           2 :                 } else if(args[k].type == arg_strings) {
     527           2 :                     return add_string((getarg_strings*)args[k].value, goptarg);
     528           0 :                 } else if(args[k].type == arg_double) {
     529           0 :                     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           8 :         if (k == num_args)
     539           0 :             return ARG_ERR_NO_MATCH;
     540             :     }
     541           8 :     return 0;
     542             : }
     543             : 
     544             : ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
     545         812 : getarg(struct getargs *args, size_t num_args,
     546             :        int argc, char **argv, int *goptind)
     547             : {
     548          34 :     int i;
     549         812 :     int ret = 0;
     550             : 
     551         812 :     rk_random_init();
     552         812 :     (*goptind)++;
     553        2461 :     for(i = *goptind; i < argc; i++) {
     554        2337 :         if(argv[i][0] != '-')
     555         659 :             break;
     556        1649 :         if(argv[i][1] == '-'){
     557        1524 :             if(argv[i][2] == 0){
     558           0 :                 i++;
     559           0 :                 break;
     560             :             }
     561        1524 :             ret = arg_match_long (args, num_args, argv[i] + 2,
     562             :                                   argc, argv, &i);
     563             :         } else {
     564         125 :             ret = arg_match_short (args, num_args, argv[i],
     565             :                                    argc, argv, &i);
     566             :         }
     567        1649 :         if(ret)
     568           0 :             break;
     569             :     }
     570         812 :     *goptind = i;
     571         812 :     return ret;
     572             : }
     573             : 
     574             : ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
     575         148 : free_getarg_strings (getarg_strings *s)
     576             : {
     577         148 :     free (s->strings);
     578         148 : }
     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.14