"Fossies" - the Fresh Open Source Software Archive

Member "dateutils-0.4.6/build-aux/yuck.yucc" (19 Mar 2019, 24977 Bytes) of package /linux/privat/dateutils-0.4.6.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "yuck.yucc": 0.4.5_vs_0.4.6.

    1 /* -*- c -*- */
    2 #if !defined INCLUDED_yuck_h_
    3 #define INCLUDED_yuck_h_
    4 
    5 #include <stddef.h>
    6 
    7 #define YUCK_OPTARG_NONE    ((void*)0x1U)
    8 
    9 enum yuck_cmds_e {
   10     /* value used when no command was specified */
   11     YUCK_CMD_NONE = 0U,
   12 
   13     /* actual commands */
   14     YUCK_CMD_GEN,
   15     YUCK_CMD_GENMAN,
   16     YUCK_CMD_GENDSL,
   17     YUCK_CMD_SCMVER,
   18     YUCK_CMD_CONFIG,
   19     
   20     /* convenience identifiers */
   21     YUCK_NOCMD = YUCK_CMD_NONE,
   22     YUCK_NCMDS = YUCK_CMD_CONFIG
   23 };
   24 
   25 
   26 
   27 typedef union yuck_u yuck_t;
   28 
   29 
   30 /* convenience structure for `gen' */
   31 struct yuck_cmd_gen_s {
   32     enum yuck_cmds_e cmd;
   33 
   34     /* left-over arguments, the command string is never a part of this */
   35     size_t nargs;
   36     char **args;
   37 
   38     /* help is handled automatically */
   39     /* version is handled automatically */
   40     unsigned int keep_flag;
   41     char *output_arg;
   42 
   43     char *header_arg;
   44     unsigned int no_auto_flags_flag;
   45     unsigned int no_auto_help_flag;
   46     unsigned int no_auto_version_flag;
   47     unsigned int no_auto_actions_flag;
   48     char *version_arg;
   49     char *custom_arg;
   50 };
   51 
   52 /* convenience structure for `genman' */
   53 struct yuck_cmd_genman_s {
   54     enum yuck_cmds_e cmd;
   55 
   56     /* left-over arguments, the command string is never a part of this */
   57     size_t nargs;
   58     char **args;
   59 
   60     /* help is handled automatically */
   61     /* version is handled automatically */
   62     unsigned int keep_flag;
   63     char *output_arg;
   64 
   65     char *version_string_arg;
   66     char *version_file_arg;
   67     char *package_arg;
   68     size_t include_nargs; char **include_args;
   69     char *info_page_arg;
   70 };
   71 
   72 /* convenience structure for `gendsl' */
   73 struct yuck_cmd_gendsl_s {
   74     enum yuck_cmds_e cmd;
   75 
   76     /* left-over arguments, the command string is never a part of this */
   77     size_t nargs;
   78     char **args;
   79 
   80     /* help is handled automatically */
   81     /* version is handled automatically */
   82     unsigned int keep_flag;
   83     char *output_arg;
   84 
   85     unsigned int no_auto_flags_flag;
   86     unsigned int no_auto_help_flag;
   87     unsigned int no_auto_version_flag;
   88     unsigned int no_auto_actions_flag;
   89     char *version_arg;
   90 };
   91 
   92 /* convenience structure for `scmver' */
   93 struct yuck_cmd_scmver_s {
   94     enum yuck_cmds_e cmd;
   95 
   96     /* left-over arguments, the command string is never a part of this */
   97     size_t nargs;
   98     char **args;
   99 
  100     /* help is handled automatically */
  101     /* version is handled automatically */
  102     unsigned int keep_flag;
  103     char *output_arg;
  104 
  105     unsigned int verbose_flag;
  106     char *reference_arg;
  107     unsigned int force_flag;
  108     unsigned int use_reference_flag;
  109     unsigned int ignore_noscm_flag;
  110 };
  111 
  112 /* convenience structure for `config' */
  113 struct yuck_cmd_config_s {
  114     enum yuck_cmds_e cmd;
  115 
  116     /* left-over arguments, the command string is never a part of this */
  117     size_t nargs;
  118     char **args;
  119 
  120     /* help is handled automatically */
  121     /* version is handled automatically */
  122     unsigned int keep_flag;
  123     char *output_arg;
  124 
  125     unsigned int m4_flag;
  126 };
  127 
  128 
  129 union yuck_u {
  130     /* generic struct */
  131     struct {
  132         enum yuck_cmds_e cmd;
  133 
  134         /* left-over arguments,
  135          * the command string is never a part of this */
  136         size_t nargs;
  137         char **args;
  138 
  139         /* slots common to all commands */
  140         /* help is handled automatically */
  141         /* version is handled automatically */
  142         unsigned int keep_flag;
  143         char *output_arg;
  144     };
  145 
  146     /* depending on CMD at most one of the following structs is filled in
  147      * if CMD is YUCK_NONE no slots of this union must be accessed */
  148     struct yuck_cmd_gen_s gen;
  149     struct yuck_cmd_genman_s genman;
  150     struct yuck_cmd_gendsl_s gendsl;
  151     struct yuck_cmd_scmver_s scmver;
  152     struct yuck_cmd_config_s config;
  153 };
  154 
  155 
  156 static __attribute__((nonnull(1))) int
  157 yuck_parse(yuck_t*, int argc, char *argv[]);
  158 static __attribute__((nonnull(1))) void yuck_free(yuck_t*);
  159 
  160 static __attribute__((nonnull(1))) void yuck_auto_help(const yuck_t*);
  161 static __attribute__((nonnull(1))) void yuck_auto_usage(const yuck_t*);
  162 static __attribute__((nonnull(1))) void yuck_auto_version(const yuck_t*);
  163 
  164 /* some hooks */
  165 #if defined yuck_post_help
  166 static __attribute__((nonnull(1))) void yuck_post_help(const yuck_t*);
  167 #endif  /* yuck_post_help */
  168 
  169 #if defined yuck_post_usage
  170 static __attribute__((nonnull(1))) void yuck_post_usage(const yuck_t*);
  171 #endif  /* yuck_post_usage */
  172 
  173 #if defined yuck_post_version
  174 static __attribute__((nonnull(1))) void yuck_post_version(const yuck_t*);
  175 #endif  /* yuck_post_version */
  176 
  177 #endif  /* INCLUDED_yuck_h_ */
  178 /* -*- c -*- */
  179 #if defined HAVE_CONFIG_H
  180 # include "config.h"
  181 #endif  /* HAVE_CONFIG_H */
  182 #if defined HAVE_VERSION_H
  183 # include "version.h"
  184 #endif  /* HAVE_VERSION_H */
  185 #include <stdlib.h>
  186 #include <stdbool.h>
  187 #include <string.h>
  188 #include <stdio.h>
  189 #include <limits.h>
  190 
  191 #if defined __INTEL_COMPILER
  192 # pragma warning (push)
  193 # pragma warning (disable:177)
  194 # pragma warning (disable:111)
  195 # pragma warning (disable:3280)
  196 #elif defined __GNUC__
  197 # if __GNUC__ > 4 || __GNUC__ == 4 &&  __GNUC_MINOR__ >= 6
  198 #  pragma GCC diagnostic push
  199 # endif  /* GCC version */
  200 # pragma GCC diagnostic ignored "-Wunused-label"
  201 # pragma GCC diagnostic ignored "-Wunused-variable"
  202 # pragma GCC diagnostic ignored "-Wunused-function"
  203 # pragma GCC diagnostic ignored "-Wshadow"
  204 #endif  /* __INTEL_COMPILER */
  205 
  206 
  207 static inline bool
  208 yuck_streqp(const char *s1, const char *s2)
  209 {
  210     return !strcmp(s1, s2);
  211 }
  212 
  213 /* for multi-args */
  214 static inline char**
  215 yuck_append(char **array, size_t n, char *val)
  216 {
  217     if (!(n % 16U)) {
  218         /* resize */
  219         void *tmp = realloc(array, (n + 16U) * sizeof(*array));
  220         if (tmp == NULL) {
  221             free(array);
  222             return NULL;
  223         }
  224         /* otherwise make it persistent */
  225         array = tmp;
  226     }
  227     array[n] = val;
  228     return array;
  229 }
  230 
  231 static enum yuck_cmds_e yuck_parse_cmd(const char *cmd)
  232 {
  233     if (0) {
  234         ;
  235     } else if (yuck_streqp(cmd, "gen")) {
  236         return YUCK_CMD_GEN;
  237     } else if (yuck_streqp(cmd, "genman")) {
  238         return YUCK_CMD_GENMAN;
  239     } else if (yuck_streqp(cmd, "gendsl")) {
  240         return YUCK_CMD_GENDSL;
  241     } else if (yuck_streqp(cmd, "scmver")) {
  242         return YUCK_CMD_SCMVER;
  243     } else if (yuck_streqp(cmd, "config")) {
  244         return YUCK_CMD_CONFIG;
  245     } else {
  246         /* error here? */
  247         fprintf(stderr, "yuck: invalid command `%s'\n\
  248 Try `--help' for a list of commands.\n", cmd);
  249     }
  250     return (enum yuck_cmds_e)-1;
  251 }
  252 
  253 
  254 static int yuck_parse(yuck_t tgt[static 1U], int argc, char *argv[])
  255 {
  256     char *op;
  257     int i;
  258 
  259     /* we'll have at most this many args */
  260     memset(tgt, 0, sizeof(*tgt));
  261     if ((tgt->args = calloc(argc, sizeof(*tgt->args))) == NULL) {
  262         return -1;
  263     }
  264     for (i = 1; i < argc && tgt->nargs < (size_t)-1; i++) {
  265         op = argv[i];
  266 
  267         switch (*op) {
  268         case '-':
  269             /* could be an option */
  270             switch (*++op) {
  271             default:
  272                 /* could be glued into one */
  273                 for (; *op; op++) {
  274                     goto shortopt; back_from_shortopt:;
  275                 }
  276                 break;
  277             case '-':
  278                 if (*++op == '\0') {
  279                     i++;
  280                     goto dashdash; back_from_dashdash:;
  281                     break;
  282                 }
  283                 goto longopt; back_from_longopt:;
  284                 break;
  285             case '\0':
  286                 goto plain_dash;
  287             }
  288             break;
  289         default:
  290         plain_dash:
  291             goto arg; back_from_arg:;
  292             break;
  293         }
  294     }
  295     if (i < argc) {
  296         op = argv[i];
  297 
  298         if (*op++ == '-' && *op++ == '-' && !*op) {
  299             /* another dashdash, filter out */
  300             i++;
  301         }
  302     }
  303     /* has to be here as the max_pargs condition might drive us here */
  304     dashdash:
  305     {
  306         /* dashdash loop, pile everything on tgt->args
  307          * don't check for subcommands either, this is in accordance to
  308          * the git tool which won't accept commands after -- */
  309         for (; i < argc; i++) {
  310             tgt->args[tgt->nargs++] = argv[i];
  311         }
  312     }
  313     return 0;
  314 
  315     longopt:
  316     {
  317         /* split into option and arg part */
  318         char *arg;
  319 
  320         if ((arg = strchr(op, '=')) != NULL) {
  321             /* \nul this one out */
  322             *arg++ = '\0';
  323         }
  324 
  325         switch (tgt->cmd) {
  326         default:
  327             goto YUCK_CMD_NONE_longopt; back_from_YUCK_CMD_NONE_longopt:;
  328             break;
  329         case YUCK_CMD_GEN:
  330             goto YUCK_CMD_GEN_longopt; back_from_YUCK_CMD_GEN_longopt:;
  331             break;
  332         case YUCK_CMD_GENMAN:
  333             goto YUCK_CMD_GENMAN_longopt; back_from_YUCK_CMD_GENMAN_longopt:;
  334             break;
  335         case YUCK_CMD_GENDSL:
  336             goto YUCK_CMD_GENDSL_longopt; back_from_YUCK_CMD_GENDSL_longopt:;
  337             break;
  338         case YUCK_CMD_SCMVER:
  339             goto YUCK_CMD_SCMVER_longopt; back_from_YUCK_CMD_SCMVER_longopt:;
  340             break;
  341         case YUCK_CMD_CONFIG:
  342             goto YUCK_CMD_CONFIG_longopt; back_from_YUCK_CMD_CONFIG_longopt:;
  343             break;
  344         }
  345         goto back_from_longopt;
  346 
  347 
  348         YUCK_CMD_NONE_longopt:
  349         {
  350             if (0) {
  351                 ;
  352             } else if (yuck_streqp(op, "help")) {
  353                 /* invoke auto action and exit */
  354                 yuck_auto_help(tgt);
  355                 goto success;
  356             } else if (yuck_streqp(op, "version")) {
  357                 /* invoke auto action and exit */
  358                 yuck_auto_version(tgt);
  359                 goto success;
  360             } else if (yuck_streqp(op, "keep")) {
  361                 tgt->keep_flag++; goto xtra_chk;
  362             } else if (yuck_streqp(op, "output")) {
  363                 tgt->output_arg = arg ?: argv[++i];
  364             } else {
  365                 /* grml */
  366                 fprintf(stderr, "yuck: unrecognized option `--%s'\n", op);
  367                 goto failure;
  368             xtra_chk:
  369                 if (arg != NULL) {
  370                     fprintf(stderr, "yuck: option `--%s' doesn't allow an argument\n", op);
  371                     goto failure;
  372                 }
  373             }
  374             if (i >= argc) {
  375                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  376                 goto failure;
  377             }
  378             goto back_from_YUCK_CMD_NONE_longopt;
  379         }
  380         YUCK_CMD_GEN_longopt:
  381         {
  382             if (0) {
  383                 ;
  384             } else if (yuck_streqp(op, "header")) {
  385                 tgt->gen.header_arg = arg ?: argv[++i];
  386             } else if (yuck_streqp(op, "no-auto-flags")) {
  387                 tgt->gen.no_auto_flags_flag++; goto xtra_chk;
  388             } else if (yuck_streqp(op, "no-auto-help")) {
  389                 tgt->gen.no_auto_help_flag++; goto xtra_chk;
  390             } else if (yuck_streqp(op, "no-auto-version")) {
  391                 tgt->gen.no_auto_version_flag++; goto xtra_chk;
  392             } else if (yuck_streqp(op, "no-auto-actions")) {
  393                 tgt->gen.no_auto_actions_flag++; goto xtra_chk;
  394             } else if (yuck_streqp(op, "version")) {
  395                 tgt->gen.version_arg = arg ?: argv[++i];
  396             } else if (yuck_streqp(op, "custom")) {
  397                 tgt->gen.custom_arg = arg ?: argv[++i];
  398             } else {
  399                 goto YUCK_CMD_NONE_longopt;
  400             }
  401             if (i >= argc) {
  402                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  403                 goto failure;
  404             }
  405             goto back_from_YUCK_CMD_GEN_longopt;
  406         }
  407         YUCK_CMD_GENMAN_longopt:
  408         {
  409             if (0) {
  410                 ;
  411             } else if (yuck_streqp(op, "version-string")) {
  412                 tgt->genman.version_string_arg = arg ?: argv[++i];
  413             } else if (yuck_streqp(op, "version-file")) {
  414                 tgt->genman.version_file_arg = arg ?: argv[++i];
  415             } else if (yuck_streqp(op, "package")) {
  416                 tgt->genman.package_arg = arg ?: argv[++i];
  417             } else if (yuck_streqp(op, "include")) {
  418                 tgt->genman.include_args =
  419                     yuck_append(
  420                         tgt->genman.include_args, tgt->genman.include_nargs++,
  421                         arg ?: argv[++i]);
  422                 if (tgt->genman.include_args == NULL) {
  423                     return -1;
  424                 };
  425             } else if (yuck_streqp(op, "info-page")) {
  426                 tgt->genman.info_page_arg = arg ?: YUCK_OPTARG_NONE;
  427             } else {
  428                 goto YUCK_CMD_NONE_longopt;
  429             }
  430             if (i >= argc) {
  431                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  432                 goto failure;
  433             }
  434             goto back_from_YUCK_CMD_GENMAN_longopt;
  435         }
  436         YUCK_CMD_GENDSL_longopt:
  437         {
  438             if (0) {
  439                 ;
  440             } else if (yuck_streqp(op, "no-auto-flags")) {
  441                 tgt->gendsl.no_auto_flags_flag++; goto xtra_chk;
  442             } else if (yuck_streqp(op, "no-auto-help")) {
  443                 tgt->gendsl.no_auto_help_flag++; goto xtra_chk;
  444             } else if (yuck_streqp(op, "no-auto-version")) {
  445                 tgt->gendsl.no_auto_version_flag++; goto xtra_chk;
  446             } else if (yuck_streqp(op, "no-auto-actions")) {
  447                 tgt->gendsl.no_auto_actions_flag++; goto xtra_chk;
  448             } else if (yuck_streqp(op, "version")) {
  449                 tgt->gendsl.version_arg = arg ?: argv[++i];
  450             } else {
  451                 goto YUCK_CMD_NONE_longopt;
  452             }
  453             if (i >= argc) {
  454                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  455                 goto failure;
  456             }
  457             goto back_from_YUCK_CMD_GENDSL_longopt;
  458         }
  459         YUCK_CMD_SCMVER_longopt:
  460         {
  461             if (0) {
  462                 ;
  463             } else if (yuck_streqp(op, "verbose")) {
  464                 tgt->scmver.verbose_flag++; goto xtra_chk;
  465             } else if (yuck_streqp(op, "reference")) {
  466                 tgt->scmver.reference_arg = arg ?: argv[++i];
  467             } else if (yuck_streqp(op, "force")) {
  468                 tgt->scmver.force_flag++; goto xtra_chk;
  469             } else if (yuck_streqp(op, "use-reference")) {
  470                 tgt->scmver.use_reference_flag++; goto xtra_chk;
  471             } else if (yuck_streqp(op, "ignore-noscm")) {
  472                 tgt->scmver.ignore_noscm_flag++; goto xtra_chk;
  473             } else {
  474                 goto YUCK_CMD_NONE_longopt;
  475             }
  476             if (i >= argc) {
  477                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  478                 goto failure;
  479             }
  480             goto back_from_YUCK_CMD_SCMVER_longopt;
  481         }
  482         YUCK_CMD_CONFIG_longopt:
  483         {
  484             if (0) {
  485                 ;
  486             } else if (yuck_streqp(op, "m4")) {
  487                 tgt->config.m4_flag++; goto xtra_chk;
  488             } else {
  489                 goto YUCK_CMD_NONE_longopt;
  490             }
  491             if (i >= argc) {
  492                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  493                 goto failure;
  494             }
  495             goto back_from_YUCK_CMD_CONFIG_longopt;
  496         }
  497         
  498     }
  499 
  500     shortopt:
  501     {
  502         char *arg = op + 1U;
  503 
  504         switch (tgt->cmd) {
  505         default:
  506             goto YUCK_CMD_NONE_shortopt; back_from_YUCK_CMD_NONE_shortopt:;
  507             break;
  508         case YUCK_CMD_GEN:
  509             goto YUCK_CMD_GEN_shortopt; back_from_YUCK_CMD_GEN_shortopt:;
  510             break;
  511         case YUCK_CMD_GENMAN:
  512             goto YUCK_CMD_GENMAN_shortopt; back_from_YUCK_CMD_GENMAN_shortopt:;
  513             break;
  514         case YUCK_CMD_GENDSL:
  515             goto YUCK_CMD_GENDSL_shortopt; back_from_YUCK_CMD_GENDSL_shortopt:;
  516             break;
  517         case YUCK_CMD_SCMVER:
  518             goto YUCK_CMD_SCMVER_shortopt; back_from_YUCK_CMD_SCMVER_shortopt:;
  519             break;
  520         case YUCK_CMD_CONFIG:
  521             goto YUCK_CMD_CONFIG_shortopt; back_from_YUCK_CMD_CONFIG_shortopt:;
  522             break;
  523         }
  524         goto back_from_shortopt;
  525 
  526 
  527         YUCK_CMD_NONE_shortopt:
  528         {
  529             switch (*op) {
  530             default:
  531                 /* again for clarity */
  532                 switch (*op) {
  533                 case '0':
  534                 case '1':
  535                 case '2':
  536                 case '3':
  537                 case '4':
  538                 case '5':
  539                 case '6':
  540                 case '7':
  541                 case '8':
  542                 case '9':
  543                     if (op[-1] == '-') {
  544                         /* literal treatment of numeral */
  545                         goto arg;
  546                     }
  547                     /* fallthrough */
  548                 default:
  549                     break;
  550                 }
  551                 ;
  552                 ;
  553                 fprintf(stderr, "yuck: unrecognized option -%c\n", *op);
  554                 goto failure;
  555 
  556 
  557 
  558                 
  559             case 'h':
  560                 /* invoke auto action and exit */
  561                 yuck_auto_help(tgt);
  562                 goto success;
  563                 break;
  564             case 'V':
  565                 /* invoke auto action and exit */
  566                 yuck_auto_version(tgt);
  567                 goto success;
  568                 break;
  569             case 'k':
  570                 tgt->keep_flag++;
  571                 break;
  572             case 'o':
  573                 tgt->output_arg = *arg
  574                     ? (op += strlen(arg), arg)
  575                     : argv[++i];
  576                 break;
  577             }
  578             if (i >= argc) {
  579                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  580                 goto failure;
  581             }
  582             goto back_from_YUCK_CMD_NONE_shortopt;
  583         }
  584         YUCK_CMD_GEN_shortopt:
  585         {
  586             switch (*op) {
  587             default:
  588                 /* again for clarity */
  589                 switch (*op) {
  590                 case '0':
  591                 case '1':
  592                 case '2':
  593                 case '3':
  594                 case '4':
  595                 case '5':
  596                 case '6':
  597                 case '7':
  598                 case '8':
  599                 case '9':
  600                     if (op[-1] == '-') {
  601                         /* literal treatment of numeral */
  602                         goto arg;
  603                     }
  604                     /* fallthrough */
  605                 default:
  606                     break;
  607                 }
  608                 ;
  609                 ;
  610                 goto YUCK_CMD_NONE_shortopt;
  611 
  612                 
  613             case 'H':
  614                 tgt->gen.header_arg = *arg
  615                     ? (op += strlen(arg), arg)
  616                     : argv[++i];
  617                 break;
  618             }
  619             if (i >= argc) {
  620                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  621                 goto failure;
  622             }
  623             goto back_from_YUCK_CMD_GEN_shortopt;
  624         }
  625         YUCK_CMD_GENMAN_shortopt:
  626         {
  627             switch (*op) {
  628             default:
  629                 /* again for clarity */
  630                 switch (*op) {
  631                 case '0':
  632                 case '1':
  633                 case '2':
  634                 case '3':
  635                 case '4':
  636                 case '5':
  637                 case '6':
  638                 case '7':
  639                 case '8':
  640                 case '9':
  641                     if (op[-1] == '-') {
  642                         /* literal treatment of numeral */
  643                         goto arg;
  644                     }
  645                     /* fallthrough */
  646                 default:
  647                     break;
  648                 }
  649                 ;
  650                 ;
  651                 goto YUCK_CMD_NONE_shortopt;
  652 
  653                 
  654             case 'i':
  655                 tgt->genman.include_args =
  656                     yuck_append(
  657                         tgt->genman.include_args,
  658                         tgt->genman.include_nargs++,
  659                         *arg ? (op += strlen(arg), arg) : argv[++i]);
  660                 if (tgt->genman.include_args == NULL) {
  661                     return -1;
  662                 };
  663                 break;
  664             }
  665             if (i >= argc) {
  666                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  667                 goto failure;
  668             }
  669             goto back_from_YUCK_CMD_GENMAN_shortopt;
  670         }
  671         YUCK_CMD_GENDSL_shortopt:
  672         {
  673             switch (*op) {
  674             default:
  675                 /* again for clarity */
  676                 switch (*op) {
  677                 case '0':
  678                 case '1':
  679                 case '2':
  680                 case '3':
  681                 case '4':
  682                 case '5':
  683                 case '6':
  684                 case '7':
  685                 case '8':
  686                 case '9':
  687                     if (op[-1] == '-') {
  688                         /* literal treatment of numeral */
  689                         goto arg;
  690                     }
  691                     /* fallthrough */
  692                 default:
  693                     break;
  694                 }
  695                 ;
  696                 ;
  697                 goto YUCK_CMD_NONE_shortopt;
  698 
  699                 
  700             }
  701             if (i >= argc) {
  702                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  703                 goto failure;
  704             }
  705             goto back_from_YUCK_CMD_GENDSL_shortopt;
  706         }
  707         YUCK_CMD_SCMVER_shortopt:
  708         {
  709             switch (*op) {
  710             default:
  711                 /* again for clarity */
  712                 switch (*op) {
  713                 case '0':
  714                 case '1':
  715                 case '2':
  716                 case '3':
  717                 case '4':
  718                 case '5':
  719                 case '6':
  720                 case '7':
  721                 case '8':
  722                 case '9':
  723                     if (op[-1] == '-') {
  724                         /* literal treatment of numeral */
  725                         goto arg;
  726                     }
  727                     /* fallthrough */
  728                 default:
  729                     break;
  730                 }
  731                 ;
  732                 ;
  733                 goto YUCK_CMD_NONE_shortopt;
  734 
  735                 
  736             case 'v':
  737                 tgt->scmver.verbose_flag++;
  738                 break;
  739             case 'f':
  740                 tgt->scmver.force_flag++;
  741                 break;
  742             case 'n':
  743                 tgt->scmver.use_reference_flag++;
  744                 break;
  745             }
  746             if (i >= argc) {
  747                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  748                 goto failure;
  749             }
  750             goto back_from_YUCK_CMD_SCMVER_shortopt;
  751         }
  752         YUCK_CMD_CONFIG_shortopt:
  753         {
  754             switch (*op) {
  755             default:
  756                 /* again for clarity */
  757                 switch (*op) {
  758                 case '0':
  759                 case '1':
  760                 case '2':
  761                 case '3':
  762                 case '4':
  763                 case '5':
  764                 case '6':
  765                 case '7':
  766                 case '8':
  767                 case '9':
  768                     if (op[-1] == '-') {
  769                         /* literal treatment of numeral */
  770                         goto arg;
  771                     }
  772                     /* fallthrough */
  773                 default:
  774                     break;
  775                 }
  776                 ;
  777                 ;
  778                 goto YUCK_CMD_NONE_shortopt;
  779 
  780                 
  781             }
  782             if (i >= argc) {
  783                 fprintf(stderr, "yuck: option `--%s' requires an argument\n", op);
  784                 goto failure;
  785             }
  786             goto back_from_YUCK_CMD_CONFIG_shortopt;
  787         }
  788         
  789     }
  790 
  791     arg:
  792     {
  793         if (tgt->cmd || YUCK_NCMDS == 0U) {
  794             tgt->args[tgt->nargs++] = argv[i];
  795         } else {
  796             /* ah, might be an arg then */
  797             if ((tgt->cmd = yuck_parse_cmd(op)) > YUCK_NCMDS) {
  798                 return -1;
  799             }
  800         }
  801         goto back_from_arg;
  802     }
  803 
  804     failure:
  805     {
  806         exit(EXIT_FAILURE);
  807     }
  808 
  809     success:
  810     {
  811         exit(EXIT_SUCCESS);
  812     }
  813 }
  814 
  815 static void yuck_free(yuck_t tgt[static 1U])
  816 {
  817     if (tgt->args != NULL) {
  818         /* free despite const qualifier */
  819         free(tgt->args);
  820     }
  821     /* free mulargs */
  822     switch (tgt->cmd) {
  823         void *ptr;
  824     default:
  825         break;
  826     case YUCK_CMD_NONE:
  827 ;
  828 ;
  829 ;
  830 ;
  831         break;
  832     case YUCK_CMD_GEN:
  833 ;
  834 ;
  835 ;
  836 ;
  837 ;
  838 ;
  839 ;
  840         break;
  841     case YUCK_CMD_GENMAN:
  842 ;
  843 ;
  844 ;
  845         ptr = tgt->genman.include_args;
  846         if (ptr != NULL) {
  847             free(ptr);
  848         }
  849 ;
  850 ;
  851         break;
  852     case YUCK_CMD_GENDSL:
  853 ;
  854 ;
  855 ;
  856 ;
  857 ;
  858         break;
  859     case YUCK_CMD_SCMVER:
  860 ;
  861 ;
  862 ;
  863 ;
  864 ;
  865         break;
  866     case YUCK_CMD_CONFIG:
  867 ;
  868         break;
  869     }
  870     return;
  871 }
  872 
  873 static void yuck_auto_usage(const yuck_t src[static 1U])
  874 {
  875     switch (src->cmd) {
  876     default:
  877     YUCK_NOCMD:
  878         puts("Usage: yuck [OPTION]... COMMAND [ARG]...\n\
  879 \n\
  880 Generate command line option parsers for umbrella commands.\n\
  881 ");
  882         break;
  883 
  884     case YUCK_CMD_GEN:
  885         puts("Usage: yuck gen [OPTION]... [FILE]...\n\
  886 \n\
  887 Generate a parser from definitions in FILE, or stdin if omitted.\n\
  888 ");
  889         break;
  890 
  891     case YUCK_CMD_GENMAN:
  892         puts("Usage: yuck genman [OPTION]... [FILE]...\n\
  893 \n\
  894 Generate a man page from definitions in FILE, or stdin if omitted.\n\
  895 ");
  896         break;
  897 
  898     case YUCK_CMD_GENDSL:
  899         puts("Usage: yuck gendsl [OPTION]... [FILE]...\n\
  900 \n\
  901 Generate the intermediary description of definitions from FILE, or stdin\n\
  902 if omitted.\n\
  903 ");
  904         break;
  905 
  906     case YUCK_CMD_SCMVER:
  907         puts("Usage: yuck scmver [OPTION]... [PATH]\n\
  908 \n\
  909 Guess version number for SCM controlled PATH.\n\
  910 If PATH is a file run a transformation.\n\
  911 If PATH is a directory just output the version number.\n\
  912 \n\
  913 Transformations are done through the m4 processor:\n\
  914 YUCK_SCMVER_VTAG     will expand to the tag name.\n\
  915 YUCK_SCMVER_SCM      will expand to the name of the SCM used.\n\
  916 YUCK_SCMVER_DIST     will expand to the distance, that is the number of\n\
  917                      commits since the last tag.\n\
  918 YUCK_SCMVER_RVSN     will expand to the current commit number.\n\
  919 YUCK_SCMVER_FLAG_DIRTY  is set for changes in the source tree that have\n\
  920                      not yet been committed.\n\
  921 \n\
  922 Definitions in the template yuck-scmver.m4 are prepended, and by\n\
  923 default this defines the YUCK_SCMVER_VERSION macro that expands to the\n\
  924 full version number.\n\
  925 ");
  926         break;
  927 
  928     case YUCK_CMD_CONFIG:
  929         puts("Usage: yuck config [OPTION]...\n\
  930 \n\
  931 Output config values for yuck.\n\
  932 ");
  933         break;
  934 
  935     }
  936 
  937 #if defined yuck_post_usage
  938     yuck_post_usage(src);
  939 #endif  /* yuck_post_usage */
  940     return;
  941 }
  942 
  943 static void yuck_auto_help(const yuck_t src[static 1U])
  944 {
  945     yuck_auto_usage(src);
  946 
  947     if (src->cmd == YUCK_NOCMD) {
  948         /* also output a list of commands */
  949         puts("COMMAND may be one of:\n\
  950   gen         Generate a parser from definitions in FILE, or stdin if omitted.\n\
  951   genman      Generate a man page from definitions in FILE, or stdin if omitted.\n\
  952   gendsl      Generate the intermediary description of definitions from FILE, or stdin\n\
  953   scmver      Guess version number for SCM controlled PATH.\n\
  954   config      Output config values for yuck.\n\
  955 ");
  956     }
  957 
  958     /* leave a not about common options */
  959     if (src->cmd == YUCK_NOCMD) {
  960         puts("\
  961 Options accepted by all commands:");
  962     } else {
  963         puts("\
  964 Common options:\n\
  965   -h, --help            display this help and exit\n\
  966   -V, --version         output version information and exit\n\
  967   -k, --keep            Keep intermediary files.\n\
  968   -o, --output=FILE     Output goes into FILE instead of stdout.\n\
  969 ");
  970     }
  971 
  972     switch (src->cmd) {
  973     default:
  974     case YUCK_CMD_NONE:
  975         puts("\
  976   -h, --help            display this help and exit\n\
  977   -V, --version         output version information and exit\n\
  978   -k, --keep            Keep intermediary files.\n\
  979   -o, --output=FILE     Output goes into FILE instead of stdout.\n\
  980 ");
  981         break;
  982 
  983     case YUCK_CMD_GEN:
  984         puts("\
  985 Command-specific options:\n\
  986   -H, --header=FILE     Also generate a header file.\n\
  987       --no-auto-flags   Do not add auto flags (--help, --version).\n\
  988       --no-auto-help    Do not add auto --help flag\n\
  989       --no-auto-version  Do not add auto --version flag\n\
  990       --no-auto-actions  Do not automatically handle auto flags.\n\
  991       --version=VERSION  Hardwire version number.\n\
  992       --custom=FILE     Include custom macros from FILE.\n\
  993 ");
  994         break;
  995 
  996     case YUCK_CMD_GENMAN:
  997         puts("\
  998 Command-specific options:\n\
  999       --version-string=STRING\n\
 1000                         Hardwire version number as STRING.\n\
 1001       --version-file=FILE\n\
 1002                         Hardwire version number from FILE.\n\
 1003       --package=STRING  Use package STRING instead of umbrella.\n\
 1004   -i, --include=FILE...  Include sections from FILE\n\
 1005       --info-page[=NAME]\n\
 1006                         Include reference to Texinfo manual.\n\
 1007 ");
 1008         break;
 1009 
 1010     case YUCK_CMD_GENDSL:
 1011         puts("\
 1012 Command-specific options:\n\
 1013       --no-auto-flags   Do not add auto flags (--help, --version).\n\
 1014       --no-auto-help    Do not add auto --help flag\n\
 1015       --no-auto-version  Do not add auto --version flag\n\
 1016       --no-auto-actions  Do not automatically handle auto flags.\n\
 1017       --version=VERSION  Hardwire version number.\n\
 1018 ");
 1019         break;
 1020 
 1021     case YUCK_CMD_SCMVER:
 1022         puts("\
 1023 Command-specific options:\n\
 1024   -v, --verbose         Print additional information on stderr.\n\
 1025       --reference=FILE  Store version reference in FILE and don't touch\n\
 1026                         the output file if nothing has changed.\n\
 1027   -f, --force           Force operation even if the current scm version\n\
 1028                         coincides with the reference version.\n\
 1029   -n, --use-reference   Use version number provided in the reference\n\
 1030                         file instead of determining it.\n\
 1031       --ignore-noscm    Don't treat no scm as error.\n\
 1032 ");
 1033         break;
 1034 
 1035     case YUCK_CMD_CONFIG:
 1036         puts("\
 1037 Command-specific options:\n\
 1038       --m4              Print m4 value used during yuck build.\n\
 1039 ");
 1040         break;
 1041 
 1042     }
 1043 
 1044 #if defined yuck_post_help
 1045     yuck_post_help(src);
 1046 #endif  /* yuck_post_help */
 1047 
 1048 #if defined PACKAGE_BUGREPORT
 1049     puts("\n\
 1050 Report bugs to " PACKAGE_BUGREPORT);
 1051 #endif  /* PACKAGE_BUGREPORT */
 1052     return;
 1053 }
 1054 
 1055 static void yuck_auto_version(const yuck_t src[static 1U])
 1056 {
 1057     switch (src->cmd) {
 1058     default:
 1059 #if 0
 1060 
 1061 #elif defined package_string
 1062         puts(package_string);
 1063 #elif defined package_version
 1064         printf("yuck %s\n", package_version);
 1065 #elif defined PACKAGE_STRING
 1066         puts(PACKAGE_STRING);
 1067 #elif defined PACKAGE_VERSION
 1068         puts("yuck " PACKAGE_VERSION);
 1069 #elif defined VERSION
 1070         puts("yuck " VERSION);
 1071 #else  /* !PACKAGE_VERSION, !VERSION */
 1072         puts("yuck unknown version");
 1073 #endif  /* PACKAGE_VERSION */
 1074         break;
 1075     }
 1076 
 1077 #if defined yuck_post_version
 1078     yuck_post_version(src);
 1079 #endif  /* yuck_post_version */
 1080     return;
 1081 }
 1082 
 1083 #if defined __INTEL_COMPILER
 1084 # pragma warning (pop)
 1085 #elif defined __GNUC__
 1086 # if __GNUC__ > 4 || __GNUC__ == 4 &&  __GNUC_MINOR__ >= 6
 1087 #  pragma GCC diagnostic pop
 1088 # endif  /* GCC version */
 1089 #endif  /* __INTEL_COMPILER */