LCOV - code coverage report
Current view: top level - metalib_isl - isl_arg.c (source / functions) Hit Total Coverage
Test: 2018-10-31_point_maint_greina16.lcov Lines: 39 719 5.4 %
Date: 2018-11-01 11:27:00 Functions: 7 62 11.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2008-2009 Katholieke Universiteit Leuven
       3             :  *
       4             :  * Use of this software is governed by the MIT license
       5             :  *
       6             :  * Written by Sven Verdoolaege, K.U.Leuven, Departement
       7             :  * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
       8             :  */
       9             : 
      10             : #include <stdio.h>
      11             : #include <stdlib.h>
      12             : #include <string.h>
      13             : 
      14             : #include <isl/arg.h>
      15             : #include <isl/ctx.h>
      16             : #include <isl_config.h>
      17             : 
      18             : static struct isl_arg help_arg[] = {
      19             : ISL_ARG_PHANTOM_BOOL('h', "help", NULL, "print this help, then exit")
      20             : };
      21             : 
      22      338796 : static void set_default_choice(struct isl_arg *arg, void *opt)
      23             : {
      24      338796 :         if (arg->offset == (size_t) -1)
      25       37644 :                 return;
      26      301152 :         *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value;
      27             : }
      28             : 
      29       37644 : static void set_default_flags(struct isl_arg *arg, void *opt)
      30             : {
      31       37644 :         *(unsigned *)(((char *)opt) + arg->offset) = arg->u.flags.default_value;
      32       37644 : }
      33             : 
      34     1054032 : static void set_default_bool(struct isl_arg *arg, void *opt)
      35             : {
      36     1054032 :         if (arg->offset == (size_t) -1)
      37           0 :                 return;
      38     1054032 :         *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value;
      39             : }
      40             : 
      41           0 : static void set_default_child(struct isl_arg *arg, void *opt)
      42             : {
      43             :         void *child;
      44             : 
      45           0 :         if (arg->offset == (size_t) -1)
      46           0 :                 child = opt;
      47             :         else {
      48           0 :                 child = calloc(1, arg->u.child.child->options_size);
      49           0 :                 *(void **)(((char *)opt) + arg->offset) = child;
      50             :         }
      51             : 
      52           0 :         if (child)
      53           0 :                 isl_args_set_defaults(arg->u.child.child, child);
      54           0 : }
      55             : 
      56           0 : static void set_default_user(struct isl_arg *arg, void *opt)
      57             : {
      58           0 :         arg->u.user.init(((char *)opt) + arg->offset);
      59           0 : }
      60             : 
      61       75288 : static void set_default_int(struct isl_arg *arg, void *opt)
      62             : {
      63       75288 :         *(int *)(((char *)opt) + arg->offset) = arg->u.i.default_value;
      64       75288 : }
      65             : 
      66           0 : static void set_default_long(struct isl_arg *arg, void *opt)
      67             : {
      68           0 :         *(long *)(((char *)opt) + arg->offset) = arg->u.l.default_value;
      69           0 : }
      70             : 
      71       37644 : static void set_default_ulong(struct isl_arg *arg, void *opt)
      72             : {
      73       37644 :         *(unsigned long *)(((char *)opt) + arg->offset) = arg->u.ul.default_value;
      74       37644 : }
      75             : 
      76       37644 : static void set_default_str(struct isl_arg *arg, void *opt)
      77             : {
      78       37644 :         const char *str = NULL;
      79       37644 :         if (arg->u.str.default_value)
      80       37644 :                 str = strdup(arg->u.str.default_value);
      81       37644 :         *(const char **)(((char *)opt) + arg->offset) = str;
      82       37644 : }
      83             : 
      84           0 : static void set_default_str_list(struct isl_arg *arg, void *opt)
      85             : {
      86           0 :         *(const char ***)(((char *) opt) + arg->offset) = NULL;
      87           0 :         *(int *)(((char *) opt) + arg->u.str_list.offset_n) = 0;
      88           0 : }
      89             : 
      90       37644 : void isl_args_set_defaults(struct isl_args *args, void *opt)
      91             : {
      92             :         int i;
      93             : 
      94     1656336 :         for (i = 0; args->args[i].type != isl_arg_end; ++i) {
      95     1618692 :                 switch (args->args[i].type) {
      96             :                 case isl_arg_choice:
      97      338796 :                         set_default_choice(&args->args[i], opt);
      98      338796 :                         break;
      99             :                 case isl_arg_flags:
     100       37644 :                         set_default_flags(&args->args[i], opt);
     101       37644 :                         break;
     102             :                 case isl_arg_bool:
     103     1054032 :                         set_default_bool(&args->args[i], opt);
     104     1054032 :                         break;
     105             :                 case isl_arg_child:
     106           0 :                         set_default_child(&args->args[i], opt);
     107           0 :                         break;
     108             :                 case isl_arg_user:
     109           0 :                         set_default_user(&args->args[i], opt);
     110           0 :                         break;
     111             :                 case isl_arg_int:
     112       75288 :                         set_default_int(&args->args[i], opt);
     113       75288 :                         break;
     114             :                 case isl_arg_long:
     115           0 :                         set_default_long(&args->args[i], opt);
     116           0 :                         break;
     117             :                 case isl_arg_ulong:
     118       37644 :                         set_default_ulong(&args->args[i], opt);
     119       37644 :                         break;
     120             :                 case isl_arg_arg:
     121             :                 case isl_arg_str:
     122       37644 :                         set_default_str(&args->args[i], opt);
     123       37644 :                         break;
     124             :                 case isl_arg_str_list:
     125           0 :                         set_default_str_list(&args->args[i], opt);
     126           0 :                         break;
     127             :                 case isl_arg_alias:
     128             :                 case isl_arg_footer:
     129             :                 case isl_arg_version:
     130             :                 case isl_arg_end:
     131       37644 :                         break;
     132             :                 }
     133             :         }
     134       37644 : }
     135             : 
     136             : static void free_args(struct isl_arg *arg, void *opt);
     137             : 
     138           0 : static void free_child(struct isl_arg *arg, void *opt)
     139             : {
     140           0 :         if (arg->offset == (size_t) -1)
     141           0 :                 free_args(arg->u.child.child->args, opt);
     142             :         else
     143           0 :                 isl_args_free(arg->u.child.child,
     144           0 :                             *(void **)(((char *)opt) + arg->offset));
     145           0 : }
     146             : 
     147           0 : static void free_str_list(struct isl_arg *arg, void *opt)
     148             : {
     149             :         int i;
     150           0 :         int n = *(int *)(((char *) opt) + arg->u.str_list.offset_n);
     151           0 :         char **list = *(char ***)(((char *) opt) + arg->offset);
     152             : 
     153           0 :         for (i = 0; i < n; ++i)
     154           0 :                 free(list[i]);
     155           0 :         free(list);
     156           0 : }
     157             : 
     158           0 : static void free_user(struct isl_arg *arg, void *opt)
     159             : {
     160           0 :         if (arg->u.user.clear)
     161           0 :                 arg->u.user.clear(((char *)opt) + arg->offset);
     162           0 : }
     163             : 
     164           0 : static void free_args(struct isl_arg *arg, void *opt)
     165             : {
     166             :         int i;
     167             : 
     168           0 :         for (i = 0; arg[i].type != isl_arg_end; ++i) {
     169           0 :                 switch (arg[i].type) {
     170             :                 case isl_arg_child:
     171           0 :                         free_child(&arg[i], opt);
     172           0 :                         break;
     173             :                 case isl_arg_arg:
     174             :                 case isl_arg_str:
     175           0 :                         free(*(char **)(((char *)opt) + arg[i].offset));
     176           0 :                         break;
     177             :                 case isl_arg_str_list:
     178           0 :                         free_str_list(&arg[i], opt);
     179           0 :                         break;
     180             :                 case isl_arg_user:
     181           0 :                         free_user(&arg[i], opt);
     182           0 :                         break;
     183             :                 case isl_arg_alias:
     184             :                 case isl_arg_bool:
     185             :                 case isl_arg_choice:
     186             :                 case isl_arg_flags:
     187             :                 case isl_arg_int:
     188             :                 case isl_arg_long:
     189             :                 case isl_arg_ulong:
     190             :                 case isl_arg_version:
     191             :                 case isl_arg_footer:
     192             :                 case isl_arg_end:
     193           0 :                         break;
     194             :                 }
     195             :         }
     196           0 : }
     197             : 
     198           0 : void isl_args_free(struct isl_args *args, void *opt)
     199             : {
     200           0 :         if (!opt)
     201           0 :                 return;
     202             : 
     203           0 :         free_args(args->args, opt);
     204             : 
     205           0 :         free(opt);
     206             : }
     207             : 
     208             : /* Data structure for collecting the prefixes of ancestor nodes.
     209             :  *
     210             :  * n is the number of prefixes.
     211             :  * prefix[i] for i < n is a prefix of an ancestor.
     212             :  * len[i] for i < n is the length of prefix[i].
     213             :  */
     214             : struct isl_prefixes {
     215             :         int n;
     216             :         const char *prefix[10];
     217             :         size_t len[10];
     218             : };
     219             : 
     220             : /* Add "prefix" to the list of prefixes and return the updated
     221             :  * number of prefixes.
     222             :  */
     223           0 : static int add_prefix(struct isl_prefixes *prefixes, const char *prefix)
     224             : {
     225           0 :         int n = prefixes->n;
     226             : 
     227           0 :         if (!prefix)
     228           0 :                 return n;
     229             : 
     230           0 :         if (prefixes->n >= 10) {
     231           0 :                 fprintf(stderr, "too many prefixes\n");
     232           0 :                 exit(EXIT_FAILURE);
     233             :         }
     234           0 :         prefixes->len[prefixes->n] = strlen(prefix);
     235           0 :         prefixes->prefix[prefixes->n] = prefix;
     236           0 :         prefixes->n++;
     237             : 
     238           0 :         return n;
     239             : }
     240             : 
     241             : /* Drop all prefixes starting at "first".
     242             :  */
     243           0 : static void drop_prefix(struct isl_prefixes *prefixes, int first)
     244             : {
     245           0 :         prefixes->n = first;
     246           0 : }
     247             : 
     248             : /* Print the prefixes in "prefixes".
     249             :  */
     250           0 : static int print_prefixes(struct isl_prefixes *prefixes)
     251             : {
     252             :         int i;
     253           0 :         int len = 0;
     254             : 
     255           0 :         if (!prefixes)
     256           0 :                 return 0;
     257             : 
     258           0 :         for (i = 0; i < prefixes->n; ++i) {
     259           0 :                 printf("%s-", prefixes->prefix[i]);
     260           0 :                 len += strlen(prefixes->prefix[i]) + 1;
     261             :         }
     262             : 
     263           0 :         return len;
     264             : }
     265             : 
     266             : /* Check if "name" starts with one or more of the prefixes in "prefixes",
     267             :  * starting at *first.  If so, advance the pointer beyond the prefixes
     268             :  * and return the updated pointer.  Additionally, update *first to
     269             :  * the index after the last prefix found.
     270             :  */
     271           0 : static const char *skip_prefixes(const char *name,
     272             :         struct isl_prefixes *prefixes, int *first)
     273             : {
     274             :         int i;
     275             : 
     276           0 :         for (i = first ? *first : 0; i < prefixes->n; ++i) {
     277           0 :                 size_t len = prefixes->len[i];
     278           0 :                 const char *prefix = prefixes->prefix[i];
     279           0 :                 if (strncmp(name, prefix, len) == 0 && name[len] == '-') {
     280           0 :                         name += len + 1;
     281           0 :                         if (first)
     282           0 :                                 *first = i + 1;
     283             :                 }
     284             :         }
     285             : 
     286           0 :         return name;
     287             : }
     288             : 
     289           0 : static int print_arg_help(struct isl_arg *decl, struct isl_prefixes *prefixes,
     290             :         int no)
     291             : {
     292           0 :         int len = 0;
     293             : 
     294           0 :         if (!decl->long_name) {
     295           0 :                 printf("  -%c", decl->short_name);
     296           0 :                 return 4;
     297             :         }
     298             : 
     299           0 :         if (decl->short_name) {
     300           0 :                 printf("  -%c, --", decl->short_name);
     301           0 :                 len += 8;
     302           0 :         } else if (decl->flags & ISL_ARG_SINGLE_DASH) {
     303           0 :                 printf("  -");
     304           0 :                 len += 3;
     305             :         } else {
     306           0 :                 printf("      --");
     307           0 :                 len += 8;
     308             :         }
     309             : 
     310           0 :         if (no) {
     311           0 :                 printf("no-");
     312           0 :                 len += 3;
     313             :         }
     314           0 :         len += print_prefixes(prefixes);
     315           0 :         printf("%s", decl->long_name);
     316           0 :         len += strlen(decl->long_name);
     317             : 
     318           0 :         while ((++decl)->type == isl_arg_alias) {
     319           0 :                 printf(", --");
     320           0 :                 len += 4;
     321           0 :                 if (no) {
     322           0 :                         printf("no-");
     323           0 :                         len += 3;
     324             :                 }
     325           0 :                 printf("%s", decl->long_name);
     326           0 :                 len += strlen(decl->long_name);
     327             :         }
     328             : 
     329           0 :         return len;
     330             : }
     331             : 
     332           0 : const void *isl_memrchr(const void *s, int c, size_t n)
     333             : {
     334           0 :         const char *p = s;
     335           0 :         while (n-- > 0)
     336           0 :                 if (p[n] == c)
     337           0 :                         return p + n;
     338           0 :         return NULL;
     339             : }
     340             : 
     341           0 : static int wrap_msg(const char *s, int indent, int pos)
     342             : {
     343             :         int len;
     344           0 :         int wrap_len = 75 - indent;
     345             : 
     346           0 :         if (pos + 1 >= indent)
     347           0 :                 printf("\n%*s", indent, "");
     348             :         else
     349           0 :                 printf("%*s", indent - pos, "");
     350             : 
     351           0 :         len = strlen(s);
     352           0 :         while (len > wrap_len) {
     353           0 :                 const char *space = isl_memrchr(s, ' ', wrap_len);
     354             :                 int l;
     355             : 
     356           0 :                 if (!space)
     357           0 :                         space = strchr(s + wrap_len, ' ');
     358           0 :                 if (!space)
     359           0 :                         break;
     360           0 :                 l = space - s;
     361           0 :                 printf("%.*s", l, s);
     362           0 :                 s = space + 1;
     363           0 :                 len -= l + 1;
     364           0 :                 printf("\n%*s", indent, "");
     365             :         }
     366             : 
     367           0 :         printf("%s", s);
     368           0 :         return len;
     369             : }
     370             : 
     371           0 : static int print_help_msg(struct isl_arg *decl, int pos)
     372             : {
     373           0 :         if (!decl->help_msg)
     374           0 :                 return pos;
     375             : 
     376           0 :         return wrap_msg(decl->help_msg, 30, pos);
     377             : }
     378             : 
     379           0 : static void print_default(struct isl_arg *decl, const char *def, int pos)
     380             : {
     381           0 :         const char *default_prefix = "[default: ";
     382           0 :         const char *default_suffix = "]";
     383             :         int len;
     384             : 
     385           0 :         len = strlen(default_prefix) + strlen(def) + strlen(default_suffix);
     386             : 
     387           0 :         if (!decl->help_msg) {
     388           0 :                 if (pos >= 29)
     389           0 :                         printf("\n%30s", "");
     390             :                 else
     391           0 :                         printf("%*s", 30 - pos, "");
     392             :         } else {
     393           0 :                 if (pos + len >= 48)
     394           0 :                         printf("\n%30s", "");
     395             :                 else
     396           0 :                         printf(" ");
     397             :         }
     398           0 :         printf("%s%s%s", default_prefix, def, default_suffix);
     399           0 : }
     400             : 
     401           0 : static void print_default_choice(struct isl_arg *decl, void *opt, int pos)
     402             : {
     403             :         int i;
     404           0 :         const char *s = "none";
     405             :         unsigned *p;
     406             : 
     407           0 :         p = (unsigned *)(((char *) opt) + decl->offset);
     408           0 :         for (i = 0; decl->u.choice.choice[i].name; ++i)
     409           0 :                 if (decl->u.choice.choice[i].value == *p) {
     410           0 :                         s = decl->u.choice.choice[i].name;
     411           0 :                         break;
     412             :                 }
     413             : 
     414           0 :         print_default(decl, s, pos);
     415           0 : }
     416             : 
     417           0 : static void print_choice_help(struct isl_arg *decl,
     418             :         struct isl_prefixes *prefixes, void *opt)
     419             : {
     420             :         int i;
     421             :         int pos;
     422             : 
     423           0 :         pos = print_arg_help(decl, prefixes, 0);
     424           0 :         printf("=");
     425           0 :         pos++;
     426             : 
     427           0 :         for (i = 0; decl->u.choice.choice[i].name; ++i) {
     428           0 :                 if (i) {
     429           0 :                         printf("|");
     430           0 :                         pos++;
     431             :                 }
     432           0 :                 printf("%s", decl->u.choice.choice[i].name);
     433           0 :                 pos += strlen(decl->u.choice.choice[i].name);
     434             :         }
     435             : 
     436           0 :         pos = print_help_msg(decl, pos);
     437           0 :         print_default_choice(decl, opt, pos);
     438             : 
     439           0 :         printf("\n");
     440           0 : }
     441             : 
     442           0 : static void print_default_flags(struct isl_arg *decl, void *opt, int pos)
     443             : {
     444             :         int i, first;
     445           0 :         const char *default_prefix = "[default: ";
     446           0 :         const char *default_suffix = "]";
     447           0 :         int len = strlen(default_prefix) + strlen(default_suffix);
     448             :         unsigned *p;
     449             : 
     450           0 :         p = (unsigned *)(((char *) opt) + decl->offset);
     451           0 :         for (i = 0; decl->u.flags.flags[i].name; ++i)
     452           0 :                 if ((*p & decl->u.flags.flags[i].mask) ==
     453           0 :                      decl->u.flags.flags[i].value)
     454           0 :                         len += strlen(decl->u.flags.flags[i].name);
     455             : 
     456           0 :         if (!decl->help_msg) {
     457           0 :                 if (pos >= 29)
     458           0 :                         printf("\n%30s", "");
     459             :                 else
     460           0 :                         printf("%*s", 30 - pos, "");
     461             :         } else {
     462           0 :                 if (pos + len >= 48)
     463           0 :                         printf("\n%30s", "");
     464             :                 else
     465           0 :                         printf(" ");
     466             :         }
     467           0 :         printf("%s", default_prefix);
     468             : 
     469           0 :         for (first = 1, i = 0; decl->u.flags.flags[i].name; ++i)
     470           0 :                 if ((*p & decl->u.flags.flags[i].mask) ==
     471           0 :                      decl->u.flags.flags[i].value) {
     472           0 :                         if (!first)
     473           0 :                                 printf(",");
     474           0 :                         printf("%s", decl->u.flags.flags[i].name);
     475           0 :                         first = 0;
     476             :                 }
     477             : 
     478           0 :         printf("%s", default_suffix);
     479           0 : }
     480             : 
     481           0 : static void print_flags_help(struct isl_arg *decl,
     482             :         struct isl_prefixes *prefixes, void *opt)
     483             : {
     484             :         int i, j;
     485             :         int pos;
     486             : 
     487           0 :         pos = print_arg_help(decl, prefixes, 0);
     488           0 :         printf("=");
     489           0 :         pos++;
     490             : 
     491           0 :         for (i = 0; decl->u.flags.flags[i].name; ++i) {
     492           0 :                 if (i) {
     493           0 :                         printf(",");
     494           0 :                         pos++;
     495             :                 }
     496           0 :                 for (j = i;
     497           0 :                      decl->u.flags.flags[j].mask == decl->u.flags.flags[i].mask;
     498           0 :                      ++j) {
     499           0 :                         if (j != i) {
     500           0 :                                 printf("|");
     501           0 :                                 pos++;
     502             :                         }
     503           0 :                         printf("%s", decl->u.flags.flags[j].name);
     504           0 :                         pos += strlen(decl->u.flags.flags[j].name);
     505             :                 }
     506           0 :                 i = j - 1;
     507             :         }
     508             : 
     509           0 :         pos = print_help_msg(decl, pos);
     510           0 :         print_default_flags(decl, opt, pos);
     511             : 
     512           0 :         printf("\n");
     513           0 : }
     514             : 
     515           0 : static void print_bool_help(struct isl_arg *decl,
     516             :         struct isl_prefixes *prefixes, void *opt)
     517             : {
     518             :         int pos;
     519           0 :         unsigned *p = opt ? (unsigned *)(((char *) opt) + decl->offset) : NULL;
     520           0 :         int no = p ? *p == 1 : 0;
     521           0 :         pos = print_arg_help(decl, prefixes, no);
     522           0 :         pos = print_help_msg(decl, pos);
     523           0 :         if (decl->offset != (size_t) -1)
     524           0 :                 print_default(decl, no ? "yes" : "no", pos);
     525           0 :         printf("\n");
     526           0 : }
     527             : 
     528           0 : static int print_argument_name(struct isl_arg *decl, const char *name, int pos)
     529             : {
     530           0 :         printf("%c<%s>", decl->long_name ? '=' : ' ', name);
     531           0 :         return pos + 3 + strlen(name);
     532             : }
     533             : 
     534           0 : static void print_int_help(struct isl_arg *decl,
     535             :         struct isl_prefixes *prefixes, void *opt)
     536             : {
     537             :         int pos;
     538             :         char val[20];
     539           0 :         int *p = (int *)(((char *) opt) + decl->offset);
     540           0 :         pos = print_arg_help(decl, prefixes, 0);
     541           0 :         pos = print_argument_name(decl, decl->argument_name, pos);
     542           0 :         pos = print_help_msg(decl, pos);
     543           0 :         snprintf(val, sizeof(val), "%d", *p);
     544           0 :         print_default(decl, val, pos);
     545           0 :         printf("\n");
     546           0 : }
     547             : 
     548           0 : static void print_long_help(struct isl_arg *decl,
     549             :         struct isl_prefixes *prefixes, void *opt)
     550             : {
     551             :         int pos;
     552           0 :         long *p = (long *)(((char *) opt) + decl->offset);
     553           0 :         pos = print_arg_help(decl, prefixes, 0);
     554           0 :         if (*p != decl->u.l.default_selected) {
     555           0 :                 printf("[");
     556           0 :                 pos++;
     557             :         }
     558           0 :         printf("=long");
     559           0 :         pos += 5;
     560           0 :         if (*p != decl->u.l.default_selected) {
     561           0 :                 printf("]");
     562           0 :                 pos++;
     563             :         }
     564           0 :         print_help_msg(decl, pos);
     565           0 :         printf("\n");
     566           0 : }
     567             : 
     568           0 : static void print_ulong_help(struct isl_arg *decl,
     569             :         struct isl_prefixes *prefixes)
     570             : {
     571             :         int pos;
     572           0 :         pos = print_arg_help(decl, prefixes, 0);
     573           0 :         printf("=ulong");
     574           0 :         pos += 6;
     575           0 :         print_help_msg(decl, pos);
     576           0 :         printf("\n");
     577           0 : }
     578             : 
     579           0 : static void print_str_help(struct isl_arg *decl,
     580             :         struct isl_prefixes *prefixes, void *opt)
     581             : {
     582             :         int pos;
     583           0 :         const char *a = decl->argument_name ? decl->argument_name : "string";
     584           0 :         const char **p = (const char **)(((char *) opt) + decl->offset);
     585           0 :         pos = print_arg_help(decl, prefixes, 0);
     586           0 :         pos = print_argument_name(decl, a, pos);
     587           0 :         pos = print_help_msg(decl, pos);
     588           0 :         if (*p)
     589           0 :                 print_default(decl, *p, pos);
     590           0 :         printf("\n");
     591           0 : }
     592             : 
     593           0 : static void print_str_list_help(struct isl_arg *decl,
     594             :         struct isl_prefixes *prefixes)
     595             : {
     596             :         int pos;
     597           0 :         const char *a = decl->argument_name ? decl->argument_name : "string";
     598           0 :         pos = print_arg_help(decl, prefixes, 0);
     599           0 :         pos = print_argument_name(decl, a, pos);
     600           0 :         pos = print_help_msg(decl, pos);
     601           0 :         printf("\n");
     602           0 : }
     603             : 
     604           0 : static void print_help(struct isl_arg *arg,
     605             :         struct isl_prefixes *prefixes, void *opt)
     606             : {
     607             :         int i;
     608           0 :         int any = 0;
     609             : 
     610           0 :         for (i = 0; arg[i].type != isl_arg_end; ++i) {
     611           0 :                 if (arg[i].flags & ISL_ARG_HIDDEN)
     612           0 :                         continue;
     613           0 :                 switch (arg[i].type) {
     614             :                 case isl_arg_flags:
     615           0 :                         print_flags_help(&arg[i], prefixes, opt);
     616           0 :                         any = 1;
     617           0 :                         break;
     618             :                 case isl_arg_choice:
     619           0 :                         print_choice_help(&arg[i], prefixes, opt);
     620           0 :                         any = 1;
     621           0 :                         break;
     622             :                 case isl_arg_bool:
     623           0 :                         print_bool_help(&arg[i], prefixes, opt);
     624           0 :                         any = 1;
     625           0 :                         break;
     626             :                 case isl_arg_int:
     627           0 :                         print_int_help(&arg[i], prefixes, opt);
     628           0 :                         any = 1;
     629           0 :                         break;
     630             :                 case isl_arg_long:
     631           0 :                         print_long_help(&arg[i], prefixes, opt);
     632           0 :                         any = 1;
     633           0 :                         break;
     634             :                 case isl_arg_ulong:
     635           0 :                         print_ulong_help(&arg[i], prefixes);
     636           0 :                         any = 1;
     637           0 :                         break;
     638             :                 case isl_arg_str:
     639           0 :                         print_str_help(&arg[i], prefixes, opt);
     640           0 :                         any = 1;
     641           0 :                         break;
     642             :                 case isl_arg_str_list:
     643           0 :                         print_str_list_help(&arg[i], prefixes);
     644           0 :                         any = 1;
     645           0 :                         break;
     646             :                 case isl_arg_alias:
     647             :                 case isl_arg_version:
     648             :                 case isl_arg_arg:
     649             :                 case isl_arg_footer:
     650             :                 case isl_arg_child:
     651             :                 case isl_arg_user:
     652             :                 case isl_arg_end:
     653           0 :                         break;
     654             :                 }
     655             :         }
     656             : 
     657           0 :         for (i = 0; arg[i].type != isl_arg_end; ++i) {
     658             :                 void *child;
     659             :                 int first;
     660             : 
     661           0 :                 if (arg[i].type != isl_arg_child)
     662           0 :                         continue;
     663           0 :                 if (arg[i].flags & ISL_ARG_HIDDEN)
     664           0 :                         continue;
     665             : 
     666           0 :                 if (any)
     667           0 :                         printf("\n");
     668           0 :                 if (arg[i].help_msg)
     669           0 :                         printf(" %s\n", arg[i].help_msg);
     670           0 :                 if (arg[i].offset == (size_t) -1)
     671           0 :                         child = opt;
     672             :                 else
     673           0 :                         child = *(void **)(((char *) opt) + arg[i].offset);
     674           0 :                 first = add_prefix(prefixes, arg[i].long_name);
     675           0 :                 print_help(arg[i].u.child.child->args, prefixes, child);
     676           0 :                 drop_prefix(prefixes, first);
     677           0 :                 any = 1;
     678             :         }
     679           0 : }
     680             : 
     681           0 : static const char *prog_name(const char *prog)
     682             : {
     683             :         const char *slash;
     684             : 
     685           0 :         slash = strrchr(prog, '/');
     686           0 :         if (slash)
     687           0 :                 prog = slash + 1;
     688           0 :         if (strncmp(prog, "lt-", 3) == 0)
     689           0 :                 prog += 3;
     690             : 
     691           0 :         return prog;
     692             : }
     693             : 
     694           0 : static int any_version(struct isl_arg *decl)
     695             : {
     696             :         int i;
     697             : 
     698           0 :         for (i = 0; decl[i].type != isl_arg_end; ++i) {
     699           0 :                 switch (decl[i].type) {
     700             :                 case isl_arg_version:
     701           0 :                         return 1;
     702             :                 case isl_arg_child:
     703           0 :                         if (any_version(decl[i].u.child.child->args))
     704           0 :                                 return 1;
     705           0 :                         break;
     706             :                 default:
     707           0 :                         break;
     708             :                 }
     709             :         }
     710             : 
     711           0 :         return 0;
     712             : }
     713             : 
     714           0 : static void print_help_and_exit(struct isl_arg *arg, const char *prog,
     715             :         void *opt)
     716             : {
     717             :         int i;
     718           0 :         struct isl_prefixes prefixes = { 0 };
     719             : 
     720           0 :         printf("Usage: %s [OPTION...]", prog_name(prog));
     721             : 
     722           0 :         for (i = 0; arg[i].type != isl_arg_end; ++i)
     723           0 :                 if (arg[i].type == isl_arg_arg)
     724           0 :                         printf(" %s", arg[i].argument_name);
     725             : 
     726           0 :         printf("\n\n");
     727             : 
     728           0 :         print_help(arg, &prefixes, opt);
     729           0 :         printf("\n");
     730           0 :         if (any_version(arg))
     731           0 :                 printf("  -V, --version\n");
     732           0 :         print_bool_help(help_arg, NULL, NULL);
     733             : 
     734           0 :         for (i = 0; arg[i].type != isl_arg_end; ++i) {
     735           0 :                 if (arg[i].type != isl_arg_footer)
     736           0 :                         continue;
     737           0 :                 wrap_msg(arg[i].help_msg, 0, 0);
     738           0 :                 printf("\n");
     739             :         }
     740             : 
     741           0 :         exit(0);
     742             : }
     743             : 
     744           0 : static int match_long_name(struct isl_arg *decl,
     745             :         const char *start, const char *end)
     746             : {
     747             :         do {
     748           0 :                 if (end - start == strlen(decl->long_name) &&
     749           0 :                     !strncmp(start, decl->long_name, end - start))
     750           0 :                         return 1;
     751           0 :         } while ((++decl)->type == isl_arg_alias);
     752             : 
     753           0 :         return 0;
     754             : }
     755             : 
     756           0 : static const char *skip_dash_dash(struct isl_arg *decl, const char *arg)
     757             : {
     758           0 :         if (!strncmp(arg, "--", 2))
     759           0 :                 return arg + 2;
     760           0 :         if ((decl->flags & ISL_ARG_SINGLE_DASH) && arg[0] == '-')
     761           0 :                 return arg + 1;
     762           0 :         return NULL;
     763             : }
     764             : 
     765           0 : static const char *skip_name(struct isl_arg *decl, const char *arg,
     766             :         struct isl_prefixes *prefixes, int need_argument, int *has_argument)
     767             : {
     768             :         const char *equal;
     769             :         const char *name;
     770             :         const char *end;
     771             : 
     772           0 :         if (arg[0] == '-' && arg[1] && arg[1] == decl->short_name) {
     773           0 :                 if (need_argument && !arg[2])
     774           0 :                         return NULL;
     775           0 :                 if (has_argument)
     776           0 :                         *has_argument = arg[2] != '\0';
     777           0 :                 return arg + 2;
     778             :         }
     779           0 :         if (!decl->long_name)
     780           0 :                 return NULL;
     781             : 
     782           0 :         name = skip_dash_dash(decl, arg);
     783           0 :         if (!name)
     784           0 :                 return NULL;
     785             : 
     786           0 :         equal = strchr(name, '=');
     787           0 :         if (need_argument && !equal)
     788           0 :                 return NULL;
     789             : 
     790           0 :         if (has_argument)
     791           0 :                 *has_argument = !!equal;
     792           0 :         end = equal ? equal : name + strlen(name);
     793             : 
     794           0 :         name = skip_prefixes(name, prefixes, NULL);
     795             : 
     796           0 :         if (!match_long_name(decl, name, end))
     797           0 :                 return NULL;
     798             : 
     799           0 :         return equal ? equal + 1 : end;
     800             : }
     801             : 
     802           0 : static int parse_choice_option(struct isl_arg *decl, char **arg,
     803             :         struct isl_prefixes *prefixes, void *opt)
     804             : {
     805             :         int i;
     806             :         int has_argument;
     807             :         const char *choice;
     808             : 
     809           0 :         choice = skip_name(decl, arg[0], prefixes, 0, &has_argument);
     810           0 :         if (!choice)
     811           0 :                 return 0;
     812             : 
     813           0 :         if (!has_argument && (!arg[1] || arg[1][0] == '-')) {
     814           0 :                 unsigned u = decl->u.choice.default_selected;
     815           0 :                 if (decl->offset != (size_t) -1)
     816           0 :                         *(unsigned *)(((char *)opt) + decl->offset) = u;
     817           0 :                 if (decl->u.choice.set)
     818           0 :                         decl->u.choice.set(opt, u);
     819             : 
     820           0 :                 return 1;
     821             :         }
     822             : 
     823           0 :         if (!has_argument)
     824           0 :                 choice = arg[1];
     825             : 
     826           0 :         for (i = 0; decl->u.choice.choice[i].name; ++i) {
     827             :                 unsigned u;
     828             : 
     829           0 :                 if (strcmp(choice, decl->u.choice.choice[i].name))
     830           0 :                         continue;
     831             : 
     832           0 :                 u = decl->u.choice.choice[i].value;
     833           0 :                 if (decl->offset != (size_t) -1)
     834           0 :                         *(unsigned *)(((char *)opt) + decl->offset) = u;
     835           0 :                 if (decl->u.choice.set)
     836           0 :                         decl->u.choice.set(opt, u);
     837             : 
     838           0 :                 return has_argument ? 1 : 2;
     839             :         }
     840             : 
     841           0 :         return 0;
     842             : }
     843             : 
     844           0 : static int set_flag(struct isl_arg *decl, unsigned *val, const char *flag,
     845             :         size_t len)
     846             : {
     847             :         int i;
     848             : 
     849           0 :         for (i = 0; decl->u.flags.flags[i].name; ++i) {
     850           0 :                 if (strncmp(flag, decl->u.flags.flags[i].name, len))
     851           0 :                         continue;
     852             : 
     853           0 :                 *val &= ~decl->u.flags.flags[i].mask;
     854           0 :                 *val |= decl->u.flags.flags[i].value;
     855             : 
     856           0 :                 return 1;
     857             :         }
     858             : 
     859           0 :         return 0;
     860             : }
     861             : 
     862           0 : static int parse_flags_option(struct isl_arg *decl, char **arg,
     863             :         struct isl_prefixes *prefixes, void *opt)
     864             : {
     865             :         int has_argument;
     866             :         const char *flags;
     867             :         const char *comma;
     868             :         unsigned val;
     869             : 
     870           0 :         flags = skip_name(decl, arg[0], prefixes, 0, &has_argument);
     871           0 :         if (!flags)
     872           0 :                 return 0;
     873             : 
     874           0 :         if (!has_argument && !arg[1])
     875           0 :                 return 0;
     876             : 
     877           0 :         if (!has_argument)
     878           0 :                 flags = arg[1];
     879             : 
     880           0 :         val = 0;
     881             : 
     882           0 :         while ((comma = strchr(flags, ',')) != NULL) {
     883           0 :                 if (!set_flag(decl, &val, flags, comma - flags))
     884           0 :                         return 0;
     885           0 :                 flags = comma + 1;
     886             :         }
     887           0 :         if (!set_flag(decl, &val, flags, strlen(flags)))
     888           0 :                 return 0;
     889             : 
     890           0 :         *(unsigned *)(((char *)opt) + decl->offset) = val;
     891             : 
     892           0 :         return has_argument ? 1 : 2;
     893             : }
     894             : 
     895           0 : static int parse_bool_option(struct isl_arg *decl, char **arg,
     896             :         struct isl_prefixes *prefixes, void *opt)
     897             : {
     898             :         const char *name;
     899           0 :         unsigned *p = (unsigned *)(((char *)opt) + decl->offset);
     900             :         int next_prefix;
     901             : 
     902           0 :         if (skip_name(decl, arg[0], prefixes, 0, NULL)) {
     903           0 :                 if ((decl->flags & ISL_ARG_BOOL_ARG) && arg[1]) {
     904             :                         char *endptr;
     905           0 :                         int val = strtol(arg[1], &endptr, 0);
     906           0 :                         if (*endptr == '\0' && (val == 0 || val == 1)) {
     907           0 :                                 if (decl->offset != (size_t) -1)
     908           0 :                                         *p = val;
     909           0 :                                 if (decl->u.b.set)
     910           0 :                                         decl->u.b.set(opt, val);
     911           0 :                                 return 2;
     912             :                         }
     913             :                 }
     914           0 :                 if (decl->offset != (size_t) -1)
     915           0 :                         *p = 1;
     916           0 :                 if (decl->u.b.set)
     917           0 :                         decl->u.b.set(opt, 1);
     918             : 
     919           0 :                 return 1;
     920             :         }
     921             : 
     922           0 :         if (!decl->long_name)
     923           0 :                 return 0;
     924             : 
     925           0 :         name = skip_dash_dash(decl, arg[0]);
     926           0 :         if (!name)
     927           0 :                 return 0;
     928             : 
     929           0 :         next_prefix = 0;
     930           0 :         name = skip_prefixes(name, prefixes, &next_prefix);
     931             : 
     932           0 :         if (strncmp(name, "no-", 3))
     933           0 :                 return 0;
     934           0 :         name += 3;
     935             : 
     936           0 :         name = skip_prefixes(name, prefixes, &next_prefix);
     937             : 
     938           0 :         if (match_long_name(decl, name, name + strlen(name))) {
     939           0 :                 if (decl->offset != (size_t) -1)
     940           0 :                         *p = 0;
     941           0 :                 if (decl->u.b.set)
     942           0 :                         decl->u.b.set(opt, 0);
     943             : 
     944           0 :                 return 1;
     945             :         }
     946             : 
     947           0 :         return 0;
     948             : }
     949             : 
     950           0 : static int parse_str_option(struct isl_arg *decl, char **arg,
     951             :         struct isl_prefixes *prefixes, void *opt)
     952             : {
     953             :         int has_argument;
     954             :         const char *s;
     955           0 :         char **p = (char **)(((char *)opt) + decl->offset);
     956             : 
     957           0 :         s = skip_name(decl, arg[0], prefixes, 0, &has_argument);
     958           0 :         if (!s)
     959           0 :                 return 0;
     960             : 
     961           0 :         if (has_argument) {
     962           0 :                 free(*p);
     963           0 :                 *p = strdup(s);
     964           0 :                 return 1;
     965             :         }
     966             : 
     967           0 :         if (arg[1]) {
     968           0 :                 free(*p);
     969           0 :                 *p = strdup(arg[1]);
     970           0 :                 return 2;
     971             :         }
     972             : 
     973           0 :         return 0;
     974             : }
     975             : 
     976           0 : static int isl_arg_str_list_append(struct isl_arg *decl, void *opt,
     977             :         const char *s)
     978             : {
     979           0 :         int *n = (int *)(((char *) opt) + decl->u.str_list.offset_n);
     980           0 :         char **list = *(char ***)(((char *) opt) + decl->offset);
     981             : 
     982           0 :         list = realloc(list, (*n + 1) * sizeof(char *));
     983           0 :         if (!list)
     984           0 :                 return -1;
     985           0 :         *(char ***)(((char *) opt) + decl->offset) = list;
     986           0 :         list[*n] = strdup(s);
     987           0 :         (*n)++;
     988           0 :         return 0;
     989             : }
     990             : 
     991           0 : static int parse_str_list_option(struct isl_arg *decl, char **arg,
     992             :         struct isl_prefixes *prefixes, void *opt)
     993             : {
     994             :         int has_argument;
     995             :         const char *s;
     996             : 
     997           0 :         s = skip_name(decl, arg[0], prefixes, 0, &has_argument);
     998           0 :         if (!s)
     999           0 :                 return 0;
    1000             : 
    1001           0 :         if (has_argument) {
    1002           0 :                 isl_arg_str_list_append(decl, opt, s);
    1003           0 :                 return 1;
    1004             :         }
    1005             : 
    1006           0 :         if (arg[1]) {
    1007           0 :                 isl_arg_str_list_append(decl, opt, arg[1]);
    1008           0 :                 return 2;
    1009             :         }
    1010             : 
    1011           0 :         return 0;
    1012             : }
    1013             : 
    1014           0 : static int parse_int_option(struct isl_arg *decl, char **arg,
    1015             :         struct isl_prefixes *prefixes, void *opt)
    1016             : {
    1017             :         int has_argument;
    1018             :         const char *val;
    1019             :         char *endptr;
    1020           0 :         int *p = (int *)(((char *)opt) + decl->offset);
    1021             : 
    1022           0 :         val = skip_name(decl, arg[0], prefixes, 0, &has_argument);
    1023           0 :         if (!val)
    1024           0 :                 return 0;
    1025             : 
    1026           0 :         if (has_argument) {
    1027           0 :                 *p = atoi(val);
    1028           0 :                 return 1;
    1029             :         }
    1030             : 
    1031           0 :         if (arg[1]) {
    1032           0 :                 int i = strtol(arg[1], &endptr, 0);
    1033           0 :                 if (*endptr == '\0') {
    1034           0 :                         *p = i;
    1035           0 :                         return 2;
    1036             :                 }
    1037             :         }
    1038             : 
    1039           0 :         return 0;
    1040             : }
    1041             : 
    1042           0 : static int parse_long_option(struct isl_arg *decl, char **arg,
    1043             :         struct isl_prefixes *prefixes, void *opt)
    1044             : {
    1045             :         int has_argument;
    1046             :         const char *val;
    1047             :         char *endptr;
    1048           0 :         long *p = (long *)(((char *)opt) + decl->offset);
    1049             : 
    1050           0 :         val = skip_name(decl, arg[0], prefixes, 0, &has_argument);
    1051           0 :         if (!val)
    1052           0 :                 return 0;
    1053             : 
    1054           0 :         if (has_argument) {
    1055           0 :                 long l = strtol(val, NULL, 0);
    1056           0 :                 *p = l;
    1057           0 :                 if (decl->u.l.set)
    1058           0 :                         decl->u.l.set(opt, l);
    1059           0 :                 return 1;
    1060             :         }
    1061             : 
    1062           0 :         if (arg[1]) {
    1063           0 :                 long l = strtol(arg[1], &endptr, 0);
    1064           0 :                 if (*endptr == '\0') {
    1065           0 :                         *p = l;
    1066           0 :                         if (decl->u.l.set)
    1067           0 :                                 decl->u.l.set(opt, l);
    1068           0 :                         return 2;
    1069             :                 }
    1070             :         }
    1071             : 
    1072           0 :         if (decl->u.l.default_value != decl->u.l.default_selected) {
    1073           0 :                 *p = decl->u.l.default_selected;
    1074           0 :                 if (decl->u.l.set)
    1075           0 :                         decl->u.l.set(opt, decl->u.l.default_selected);
    1076           0 :                 return 1;
    1077             :         }
    1078             : 
    1079           0 :         return 0;
    1080             : }
    1081             : 
    1082           0 : static int parse_ulong_option(struct isl_arg *decl, char **arg,
    1083             :         struct isl_prefixes *prefixes, void *opt)
    1084             : {
    1085             :         int has_argument;
    1086             :         const char *val;
    1087             :         char *endptr;
    1088           0 :         unsigned long *p = (unsigned long *)(((char *)opt) + decl->offset);
    1089             : 
    1090           0 :         val = skip_name(decl, arg[0], prefixes, 0, &has_argument);
    1091           0 :         if (!val)
    1092           0 :                 return 0;
    1093             : 
    1094           0 :         if (has_argument) {
    1095           0 :                 *p = strtoul(val, NULL, 0);
    1096           0 :                 return 1;
    1097             :         }
    1098             : 
    1099           0 :         if (arg[1]) {
    1100           0 :                 unsigned long ul = strtoul(arg[1], &endptr, 0);
    1101           0 :                 if (*endptr == '\0') {
    1102           0 :                         *p = ul;
    1103           0 :                         return 2;
    1104             :                 }
    1105             :         }
    1106             : 
    1107           0 :         return 0;
    1108             : }
    1109             : 
    1110             : static int parse_option(struct isl_arg *decl, char **arg,
    1111             :         struct isl_prefixes *prefixes, void *opt);
    1112             : 
    1113           0 : static int parse_child_option(struct isl_arg *decl, char **arg,
    1114             :         struct isl_prefixes *prefixes, void *opt)
    1115             : {
    1116             :         void *child;
    1117             :         int first, parsed;
    1118             : 
    1119           0 :         if (decl->offset == (size_t) -1)
    1120           0 :                 child = opt;
    1121             :         else
    1122           0 :                 child = *(void **)(((char *)opt) + decl->offset);
    1123             : 
    1124           0 :         first = add_prefix(prefixes, decl->long_name);
    1125           0 :         parsed = parse_option(decl->u.child.child->args, arg, prefixes, child);
    1126           0 :         drop_prefix(prefixes, first);
    1127             : 
    1128           0 :         return parsed;
    1129             : }
    1130             : 
    1131           0 : static int parse_option(struct isl_arg *decl, char **arg,
    1132             :         struct isl_prefixes *prefixes, void *opt)
    1133             : {
    1134             :         int i;
    1135             : 
    1136           0 :         for (i = 0; decl[i].type != isl_arg_end; ++i) {
    1137           0 :                 int parsed = 0;
    1138           0 :                 switch (decl[i].type) {
    1139             :                 case isl_arg_choice:
    1140           0 :                         parsed = parse_choice_option(&decl[i], arg,
    1141             :                                                         prefixes, opt);
    1142           0 :                         break;
    1143             :                 case isl_arg_flags:
    1144           0 :                         parsed = parse_flags_option(&decl[i], arg,
    1145             :                                                         prefixes, opt);
    1146           0 :                         break;
    1147             :                 case isl_arg_int:
    1148           0 :                         parsed = parse_int_option(&decl[i], arg, prefixes, opt);
    1149           0 :                         break;
    1150             :                 case isl_arg_long:
    1151           0 :                         parsed = parse_long_option(&decl[i], arg,
    1152             :                                                         prefixes, opt);
    1153           0 :                         break;
    1154             :                 case isl_arg_ulong:
    1155           0 :                         parsed = parse_ulong_option(&decl[i], arg,
    1156             :                                                         prefixes, opt);
    1157           0 :                         break;
    1158             :                 case isl_arg_bool:
    1159           0 :                         parsed = parse_bool_option(&decl[i], arg,
    1160             :                                                         prefixes, opt);
    1161           0 :                         break;
    1162             :                 case isl_arg_str:
    1163           0 :                         parsed = parse_str_option(&decl[i], arg, prefixes, opt);
    1164           0 :                         break;
    1165             :                 case isl_arg_str_list:
    1166           0 :                         parsed = parse_str_list_option(&decl[i], arg, prefixes,
    1167             :                                                         opt);
    1168           0 :                         break;
    1169             :                 case isl_arg_child:
    1170           0 :                         parsed = parse_child_option(&decl[i], arg,
    1171             :                                                         prefixes, opt);
    1172           0 :                         break;
    1173             :                 case isl_arg_alias:
    1174             :                 case isl_arg_arg:
    1175             :                 case isl_arg_footer:
    1176             :                 case isl_arg_user:
    1177             :                 case isl_arg_version:
    1178             :                 case isl_arg_end:
    1179           0 :                         break;
    1180             :                 }
    1181           0 :                 if (parsed)
    1182           0 :                         return parsed;
    1183             :         }
    1184             : 
    1185           0 :         return 0;
    1186             : }
    1187             : 
    1188           0 : static void print_version(struct isl_arg *decl)
    1189             : {
    1190             :         int i;
    1191             : 
    1192           0 :         for (i = 0; decl[i].type != isl_arg_end; ++i) {
    1193           0 :                 switch (decl[i].type) {
    1194             :                 case isl_arg_version:
    1195           0 :                         decl[i].u.version.print_version();
    1196           0 :                         break;
    1197             :                 case isl_arg_child:
    1198           0 :                         print_version(decl[i].u.child.child->args);
    1199           0 :                         break;
    1200             :                 default:
    1201           0 :                         break;
    1202             :                 }
    1203             :         }
    1204           0 : }
    1205             : 
    1206           0 : static void print_version_and_exit(struct isl_arg *decl)
    1207             : {
    1208           0 :         print_version(decl);
    1209             : 
    1210           0 :         exit(0);
    1211             : }
    1212             : 
    1213           0 : static int drop_argument(int argc, char **argv, int drop, int n)
    1214             : {
    1215           0 :         for (; drop + n < argc; ++drop)
    1216           0 :                 argv[drop] = argv[drop + n];
    1217             : 
    1218           0 :         return argc - n;
    1219             : }
    1220             : 
    1221           0 : static int n_arg(struct isl_arg *arg)
    1222             : {
    1223             :         int i;
    1224           0 :         int n_arg = 0;
    1225             : 
    1226           0 :         for (i = 0; arg[i].type != isl_arg_end; ++i)
    1227           0 :                 if (arg[i].type == isl_arg_arg)
    1228           0 :                         n_arg++;
    1229             : 
    1230           0 :         return n_arg;
    1231             : }
    1232             : 
    1233           0 : static int next_arg(struct isl_arg *arg, int a)
    1234             : {
    1235           0 :         for (++a; arg[a].type != isl_arg_end; ++a)
    1236           0 :                 if (arg[a].type == isl_arg_arg)
    1237           0 :                         return a;
    1238             : 
    1239           0 :         return -1;
    1240             : }
    1241             : 
    1242             : /* Unless ISL_ARG_SKIP_HELP is set, check if "arg" is
    1243             :  * equal to "--help" and if so call print_help_and_exit.
    1244             :  */
    1245           0 : static void check_help(struct isl_args *args, char *arg, char *prog, void *opt,
    1246             :         unsigned flags)
    1247             : {
    1248           0 :         if (ISL_FL_ISSET(flags, ISL_ARG_SKIP_HELP))
    1249           0 :                 return;
    1250             : 
    1251           0 :         if (strcmp(arg, "--help") == 0)
    1252           0 :                 print_help_and_exit(args->args, prog, opt);
    1253             : }
    1254             : 
    1255           0 : int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt,
    1256             :         unsigned flags)
    1257             : {
    1258           0 :         int a = -1;
    1259           0 :         int skip = 0;
    1260             :         int i;
    1261             :         int n;
    1262           0 :         struct isl_prefixes prefixes = { 0 };
    1263             : 
    1264           0 :         n = n_arg(args->args);
    1265             : 
    1266           0 :         for (i = 1; i < argc; ++i) {
    1267           0 :                 if ((strcmp(argv[i], "--version") == 0 ||
    1268           0 :                      strcmp(argv[i], "-V") == 0) && any_version(args->args))
    1269           0 :                         print_version_and_exit(args->args);
    1270             :         }
    1271             : 
    1272           0 :         while (argc > 1 + skip) {
    1273             :                 int parsed;
    1274           0 :                 if (argv[1 + skip][0] != '-') {
    1275           0 :                         a = next_arg(args->args, a);
    1276           0 :                         if (a >= 0) {
    1277             :                                 char **p;
    1278           0 :                                 p = (char **)(((char *)opt)+args->args[a].offset);
    1279           0 :                                 free(*p);
    1280           0 :                                 *p = strdup(argv[1 + skip]);
    1281           0 :                                 argc = drop_argument(argc, argv, 1 + skip, 1);
    1282           0 :                                 --n;
    1283           0 :                         } else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) {
    1284           0 :                                 fprintf(stderr, "%s: extra argument: %s\n",
    1285           0 :                                             prog_name(argv[0]), argv[1 + skip]);
    1286           0 :                                 exit(-1);
    1287             :                         } else
    1288           0 :                                 ++skip;
    1289           0 :                         continue;
    1290             :                 }
    1291           0 :                 check_help(args, argv[1 + skip], argv[0], opt, flags);
    1292           0 :                 parsed = parse_option(args->args, &argv[1 + skip],
    1293             :                                         &prefixes, opt);
    1294           0 :                 if (parsed)
    1295           0 :                         argc = drop_argument(argc, argv, 1 + skip, parsed);
    1296           0 :                 else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) {
    1297           0 :                         fprintf(stderr, "%s: unrecognized option: %s\n",
    1298           0 :                                         prog_name(argv[0]), argv[1 + skip]);
    1299           0 :                         exit(-1);
    1300             :                 } else
    1301           0 :                         ++skip;
    1302             :         }
    1303             : 
    1304           0 :         if (n > 0) {
    1305           0 :                 fprintf(stderr, "%s: expecting %d more argument(s)\n",
    1306             :                                 prog_name(argv[0]), n);
    1307           0 :                 exit(-1);
    1308             :         }
    1309             : 
    1310           0 :         return argc;
    1311             : }

Generated by: LCOV version 1.12