"Fossies" - the Fresh Open Source Software Archive

Member "dateutils-0.4.6/build-aux/yuck-coru.c.m4" (19 Mar 2019, 13075 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-coru.c.m4": 0.4.5_vs_0.4.6.

    1 /* -*- c -*- */
    2 changequote`'changequote([,])dnl
    3 changecom([#])dnl
    4 #if defined HAVE_CONFIG_H
    5 # include "config.h"
    6 #endif  /* HAVE_CONFIG_H */
    7 #if defined HAVE_VERSION_H
    8 # include "version.h"
    9 #endif  /* HAVE_VERSION_H */
   10 #include <stdlib.h>
   11 #include <stdbool.h>
   12 #include <string.h>
   13 #include <stdio.h>
   14 #include <limits.h>
   15 changecom([])dnl
   16 ifdef([YUCK_HEADER], [dnl
   17 #include "YUCK_HEADER"
   18 ])dnl
   19 changecom([#])dnl
   20 
   21 #if defined __INTEL_COMPILER
   22 # pragma warning (push)
   23 # pragma warning (disable:177)
   24 # pragma warning (disable:111)
   25 # pragma warning (disable:3280)
   26 #elif defined __GNUC__
   27 # if __GNUC__ > 4 || __GNUC__ == 4 &&  __GNUC_MINOR__ >= 6
   28 #  pragma GCC diagnostic push
   29 # endif  /* GCC version */
   30 # pragma GCC diagnostic ignored "-Wunused-label"
   31 # pragma GCC diagnostic ignored "-Wunused-variable"
   32 # pragma GCC diagnostic ignored "-Wunused-function"
   33 # pragma GCC diagnostic ignored "-Wshadow"
   34 #endif  /* __INTEL_COMPILER */
   35 pushdef([DEFUN], ifdef([YUCK_HEADER], [], [static]))[]dnl
   36 
   37 
   38 static inline bool
   39 yuck_streqp(const char *s1, const char *s2)
   40 {
   41     return !strcmp(s1, s2);
   42 }
   43 
   44 /* for multi-args */
   45 static inline char**
   46 yuck_append(char **array, size_t n, char *val)
   47 {
   48     if (!(n % 16U)) {
   49         /* resize */
   50         void *tmp = realloc(array, (n + 16U) * sizeof(*array));
   51         if (tmp == NULL) {
   52             free(array);
   53             return NULL;
   54         }
   55         /* otherwise make it persistent */
   56         array = tmp;
   57     }
   58     array[[n]] = val;
   59     return array;
   60 }
   61 
   62 static enum yuck_cmds_e yuck_parse_cmd(const char *cmd)
   63 {
   64     if (0) {
   65         ;
   66     }foreachq([__CMD], yuck_cmds(), [ else if (yuck_streqp(cmd, "yuck_cmd_string(defn([__CMD]))")) {
   67         return yuck_cmd(defn([__CMD]));
   68     }]) else {
   69         /* error here? */
   70         fprintf(stderr, "YUCK_UMB_STR: invalid command `%s'\n\
   71 Try `--help' for a list of commands.\n", cmd);
   72     }
   73     return (enum yuck_cmds_e)-1;
   74 }
   75 
   76 
   77 DEFUN int yuck_parse(yuck_t tgt[[static 1U]], int argc, char *argv[[]])
   78 {
   79     char *op;
   80     int i;
   81 
   82     /* we'll have at most this many args */
   83     memset(tgt, 0, sizeof(*tgt));
   84     if ((tgt->args = calloc(argc, sizeof(*tgt->args))) == NULL) {
   85         return -1;
   86     }
   87 ifdef([YUCK_MAX_POSARGS], [], [define([YUCK_MAX_POSARGS], [(size_t)-1])])dnl
   88     for (i = 1; i < argc && tgt->nargs < YUCK_MAX_POSARGS; i++) {
   89         op = argv[[i]];
   90 
   91         switch (*op) {
   92         case '-':
   93             /* could be an option */
   94             switch (*++op) {
   95             default:
   96                 /* could be glued into one */
   97                 for (; *op; op++) {
   98                     yield(shortopt, *op);
   99                 }
  100                 break;
  101             case '-':
  102                 if (*++op == '\0') {
  103                     i++;
  104                     yield(dashdash);
  105                     break;
  106                 }
  107                 yield(longopt, op);
  108                 break;
  109             case '\0':
  110                 goto plain_dash;
  111             }
  112             break;
  113         default:
  114         plain_dash:
  115             yield(arg, op);
  116             break;
  117         }
  118     }
  119     if (i < argc) {
  120         op = argv[[i]];
  121 
  122         if (*op++ == '-' && *op++ == '-' && !*op) {
  123             /* another dashdash, filter out */
  124             i++;
  125         }
  126     }
  127     /* has to be here as the max_pargs condition might drive us here */
  128     coroutine(dashdash)
  129     {
  130         /* dashdash loop, pile everything on tgt->args
  131          * don't check for subcommands either, this is in accordance to
  132          * the git tool which won't accept commands after -- */
  133         for (; i < argc; i++) {
  134             tgt->args[[tgt->nargs++]] = argv[[i]];
  135         }
  136     }
  137     return 0;
  138 
  139     coroutine(longopt)
  140     {
  141         /* split into option and arg part */
  142         char *arg;
  143 
  144         if ((arg = strchr(op, '=')) != NULL) {
  145             /* \nul this one out */
  146             *arg++ = '\0';
  147         }
  148 
  149         switch (tgt->cmd) {
  150         default:
  151             yield(yuck_cmd()[_longopt]);
  152             break;
  153         foreachq([__CMD], yuck_cmds(), [case yuck_cmd(defn([__CMD])):
  154             yield(yuck_cmd(defn([__CMD]))[_longopt]);
  155             break;
  156         ])}
  157         resume;
  158 
  159 dnl TYPE actions
  160 pushdef([yuck_flag_action], [tgt->yuck_slot([$1], [$2])++; ifdef([YOPT_ALLOW_UNKNOWN_DASHDASH], [], [goto xtra_chk])])dnl
  161 pushdef([yuck_arg_action], [tgt->yuck_slot([$1], [$2]) = arg ?: argv[[++i]]])dnl
  162 pushdef([yuck_arg_opt_action], [tgt->yuck_slot([$1], [$2]) = arg ?: YUCK_OPTARG_NONE])dnl
  163 pushdef([yuck_arg_mul_action], [tgt->yuck_slot([$1], [$2]) =
  164                     yuck_append(
  165                         tgt->yuck_slot([$1], [$2]), tgt->yuck_cnt_slot([$1], [$2])++,
  166                         arg ?: argv[[++i]]);
  167                 if (tgt->yuck_slot([$1], [$2]) == NULL) {
  168                     return -1;
  169                 }])dnl
  170 pushdef([yuck_arg_mul_opt_action], [tgt->yuck_slot([$1], [$2]) =
  171                     yuck_append(
  172                         tgt->yuck_slot([$1], [$2]), tgt->yuck_cnt_slot([$1], [$2])++,
  173                         arg ?: YUCK_OPTARG_NONE);
  174                 if (tgt->yuck_slot([$1], [$2]) == NULL) {
  175                     return -1;
  176                 }])dnl
  177 pushdef([yuck_auto_action], [/* invoke auto action and exit */
  178                 yuck_auto_[]yuck_canon([$1], [$2])(tgt);
  179                 resume_at(success)])dnl
  180 
  181         foreachq([__CMD], yuck_umbcmds(), [coroutine(yuck_cmd(defn([__CMD]))[_longopt])
  182         {
  183             if (0) {
  184                 ;
  185             }dnl
  186 foreachq([__IDN], yuck_idents(defn([__CMD])), [ dnl
  187 pushdef([long], yuck_long(defn([__IDN]), defn([__CMD])))[]dnl
  188 ifelse(defn([long]), [], [divert(-1)])dnl
  189 else if (yuck_streqp(op, "defn([long])")) {
  190 popdef([long])[]dnl
  191 dnl now simply expand yuck_foo_action:
  192                 yuck_option_action(defn([__IDN]), defn([__CMD]));
  193             }dnl
  194 divert[]dnl
  195 ]) else {
  196 ifelse(defn([__CMD]), [], [dnl
  197 ifdef([YOPT_ALLOW_UNKNOWN_DASHDASH], [dnl
  198                 /* just treat it as argument then */
  199                 resume_at(arg);
  200 ], [dnl
  201                 /* grml */
  202                 fprintf(stderr, "YUCK_UMB_STR: unrecognized option `--%s'\n", op);
  203                 resume_at(failure);
  204             xtra_chk:
  205                 if (arg != NULL) {
  206                     fprintf(stderr, "YUCK_UMB_STR: option `--%s' doesn't allow an argument\n", op);
  207                     resume_at(failure);
  208                 }
  209 ])dnl
  210 ], [dnl
  211                 resume_at(yuck_cmd()[_longopt]);
  212 ])dnl
  213             }
  214             if (i >= argc) {
  215                 fprintf(stderr, "YUCK_UMB_STR: option `--%s' requires an argument\n", op);
  216                 resume_at(failure);
  217             }
  218             resume;
  219         }
  220         ])
  221 popdef([yuck_flag_action])dnl
  222 popdef([yuck_arg_action])dnl
  223 popdef([yuck_arg_mul_action])dnl
  224 popdef([yuck_arg_opt_action])dnl
  225 popdef([yuck_arg_mul_opt_action])dnl
  226 popdef([yuck_auto_action])dnl
  227     }
  228 
  229     coroutine(shortopt)
  230     {
  231         char *arg = op + 1U;
  232 
  233         switch (tgt->cmd) {
  234         default:
  235             yield(yuck_cmd()[_shortopt]);
  236             break;
  237         foreachq([__CMD], yuck_cmds(), [case yuck_cmd(defn([__CMD])):
  238             yield(yuck_cmd(defn([__CMD]))[_shortopt]);
  239             break;
  240         ])}
  241         resume;
  242 
  243 dnl TYPE actions
  244 pushdef([yuck_flag_action], [tgt->yuck_slot([$1], [$2])++])dnl
  245 pushdef([yuck_arg_action], [tgt->yuck_slot([$1], [$2]) = *arg
  246                     ? (op += strlen(arg), arg)
  247                     : argv[[++i]]])dnl
  248 pushdef([yuck_arg_opt_action], [tgt->yuck_slot([$1], [$2]) = *arg
  249                     ? (op += strlen(arg), arg)
  250                     : YUCK_OPTARG_NONE])dnl
  251 pushdef([yuck_arg_mul_action], [tgt->yuck_slot([$1], [$2]) =
  252                     yuck_append(
  253                         tgt->yuck_slot([$1], [$2]),
  254                         tgt->yuck_cnt_slot([$1], [$2])++,
  255                         *arg ? (op += strlen(arg), arg) : argv[[++i]]);
  256                 if (tgt->yuck_slot([$1], [$2]) == NULL) {
  257                     return -1;
  258                 }])dnl
  259 pushdef([yuck_arg_mul_opt_action], [tgt->yuck_slot([$1], [$2]) =
  260                     yuck_append(
  261                         tgt->yuck_slot([$1], [$2]),
  262                         tgt->yuck_cnt_slot([$1], [$2])++,
  263                         *arg ? (op += strlen(arg), arg) : YUCK_OPTARG_NONE);
  264                 if (tgt->yuck_slot([$1], [$2]) == NULL) {
  265                     return -1;
  266                 }])dnl
  267 pushdef([yuck_auto_action], [/* invoke auto action and exit */
  268                 yuck_auto_[]yuck_canon([$1], [$2])(tgt);
  269                 resume_at(success)])dnl
  270 
  271         foreachq([__CMD], yuck_umbcmds(), [coroutine(yuck_cmd(defn([__CMD]))[_shortopt])
  272         {
  273             switch (*op) {
  274             default:
  275                 /* again for clarity */
  276                 switch (*op) {
  277                 case '0':
  278                 case '1':
  279                 case '2':
  280                 case '3':
  281                 case '4':
  282                 case '5':
  283                 case '6':
  284                 case '7':
  285                 case '8':
  286                 case '9':
  287                     if (op[[-1]] == '-') {
  288                         /* literal treatment of numeral */
  289                         resume_at(arg);
  290                     }
  291                     /* fallthrough */
  292                 default:
  293                     break;
  294                 }
  295                 divert(1);
  296 ifdef([YOPT_ALLOW_UNKNOWN_DASH], [dnl
  297                 resume_at(arg);
  298 ], [dnl
  299                 fprintf(stderr, "YUCK_UMB_STR: unrecognized option -%c\n", *op);
  300                 resume_at(failure);
  301 ])dnl
  302 
  303 ifdef([YUCK_SHORTS_HAVE_NUMERALS], [
  304                 /* [yuck_shorts()] (= yuck_shorts())
  305                  * has numerals as shortopts
  306                  * don't allow literal treatment of numerals */divert(-1)])
  307 
  308                 divert(2);
  309                 resume_at(yuck_cmd()[_shortopt]);
  310 
  311                 divert(0);
  312                 ifelse(defn([__CMD]), [], [select_divert(1)], [select_divert(2)])dnl
  313 divert[]dnl
  314 
  315 foreachq([__IDN], yuck_idents(defn([__CMD])), [dnl
  316 pushdef([short], yuck_short(defn([__IDN]), defn([__CMD])))dnl
  317 ifelse(defn([short]), [], [divert(-1)])dnl
  318             case 'defn([short])':
  319 popdef([short])dnl
  320 dnl
  321 dnl now simply expand yuck_foo_action:
  322                 yuck_option_action(defn([__IDN]), defn([__CMD]));
  323                 break;
  324 divert[]dnl
  325 ])dnl
  326             }
  327             if (i >= argc) {
  328                 fprintf(stderr, "YUCK_UMB_STR: option `--%s' requires an argument\n", op);
  329                 resume_at(failure);
  330             }
  331             resume;
  332         }
  333         ])
  334 popdef([yuck_flag_action])dnl
  335 popdef([yuck_arg_action])dnl
  336 popdef([yuck_arg_opt_action])dnl
  337 popdef([yuck_arg_mul_action])dnl
  338 popdef([yuck_arg_mul_opt_action])dnl
  339 popdef([yuck_auto_action])dnl
  340     }
  341 
  342     coroutine(arg)
  343     {
  344         if (tgt->cmd || YUCK_NCMDS == 0U) {
  345             tgt->args[[tgt->nargs++]] = argv[[i]];
  346         } else {
  347             /* ah, might be an arg then */
  348             if ((tgt->cmd = yuck_parse_cmd(op)) > YUCK_NCMDS) {
  349                 return -1;
  350             }
  351         }
  352         resume;
  353     }
  354 
  355     coroutine(failure)
  356     {
  357         exit(EXIT_FAILURE);
  358     }
  359 
  360     coroutine(success)
  361     {
  362         exit(EXIT_SUCCESS);
  363     }
  364 }
  365 
  366 DEFUN void yuck_free(yuck_t tgt[[static 1U]])
  367 {
  368     if (tgt->args != NULL) {
  369         /* free despite const qualifier */
  370         free(tgt->args);
  371     }
  372     /* free mulargs */
  373     switch (tgt->cmd) {
  374         void *ptr;
  375     default:
  376         break;
  377 pushdef([action], [dnl
  378         ptr = tgt->yuck_slot([$1], [$2]);
  379         if (ptr != NULL) {
  380             free(ptr);
  381         }
  382 ])dnl
  383 dnl TYPE actions
  384 pushdef([yuck_flag_action], [])dnl
  385 pushdef([yuck_arg_action], [])dnl
  386 pushdef([yuck_arg_opt_action], [])dnl
  387 pushdef([yuck_arg_mul_action], defn([action]))dnl
  388 pushdef([yuck_arg_mul_opt_action], defn([action]))dnl
  389 pushdef([yuck_auto_action], [])dnl
  390 foreachq([__CMD], yuck_umbcmds(), [dnl
  391     case yuck_cmd(defn([__CMD])):
  392 foreachq([__IDN], yuck_idents(defn([__CMD])), [dnl
  393 yuck_option_action(defn([__IDN]), defn([__CMD]));
  394 ])[]dnl
  395         break;
  396 ])[]dnl
  397 popdef([action])dnl
  398 popdef([yuck_flag_action])dnl
  399 popdef([yuck_arg_action])dnl
  400 popdef([yuck_arg_opt_action])dnl
  401 popdef([yuck_arg_mul_action])dnl
  402 popdef([yuck_arg_mul_opt_action])dnl
  403 popdef([yuck_auto_opt_action])dnl
  404     }
  405     return;
  406 }
  407 
  408 DEFUN void yuck_auto_usage(const yuck_t src[[static 1U]])
  409 {
  410     switch (src->cmd) {
  411     default:
  412     YUCK_NOCMD:
  413         puts("Usage: YUCK_UMB_STR [[OPTION]]...dnl
  414 ifelse(yuck_cmds(), [], [], [ COMMAND])[]dnl
  415 ifelse(defn([YUCK_UMB_POSARG]), [], [], [ defn([YUCK_UMB_POSARG])])\n\
  416 ifelse(yuck_umb_desc(), [], [], [dnl
  417 \n\
  418 yuck_C_literal(yuck_umb_desc())\n\
  419 ])dnl
  420 ");
  421         break;
  422 foreachq([__CMD], yuck_cmds(), [
  423     case yuck_cmd(defn([__CMD])):
  424         puts("Usage: YUCK_UMB_STR dnl
  425 yuck_cmd_string(defn([__CMD]))[]dnl
  426 ifelse(yuck_idents(defn([__CMD])), [], [], [ [[OPTION]]...])[]dnl
  427 ifelse(yuck_cmd_posarg(defn([__CMD])), [], [], [ yuck_cmd_posarg(defn([__CMD]))])\n\
  428 ifelse(yuck_cmd_desc(defn([__CMD])), [], [], [dnl
  429 \n\
  430 yuck_C_literal(yuck_cmd_desc(defn([__CMD])))\n\
  431 ])dnl
  432 ");
  433         break;
  434 ])
  435     }
  436 
  437 #if defined yuck_post_usage
  438     yuck_post_usage(src);
  439 #endif  /* yuck_post_usage */
  440     return;
  441 }
  442 
  443 DEFUN void yuck_auto_help(const yuck_t src[[static 1U]])
  444 {
  445     yuck_auto_usage(src);
  446 
  447 ifelse(yuck_cmds(), [], [], [dnl
  448     if (src->cmd == YUCK_NOCMD) {
  449         /* also output a list of commands */
  450         puts("COMMAND may be one of:\n\
  451 foreachq([__CMD], yuck_cmds(), [yuck_C_literal(yuck_cmd_line(defn([__CMD])))\n\
  452 ])");
  453     }
  454 ])dnl
  455 
  456     /* leave a not about common options */
  457     if (src->cmd == YUCK_NOCMD) {
  458 ifelse(yuck_cmds(), [], [dnl
  459         ;
  460 ], [dnl
  461         puts("\
  462 Options accepted by all commands:");
  463 ])dnl
  464 ifelse(yuck_cmds(), [], [], [dnl
  465     } else {
  466         puts("\
  467 Common options:\n\
  468 foreachq([__IDN], yuck_idents([]), [dnl
  469 yuck_C_literal(backquote([yuck_option_help_line(defn([__IDN]), [])]))[]dnl
  470 ])dnl
  471 ");
  472 ])dnl
  473     }
  474 
  475     switch (src->cmd) {
  476     default:foreachq([__CMD], yuck_umbcmds(), [
  477     case yuck_cmd(defn([__CMD])):
  478         puts("\
  479 ifelse(defn([__CMD]), [], [], [dnl
  480 ifelse(yuck_idents(defn([__CMD])), [], [], [dnl
  481 Command-specific options:\n\
  482 ])dnl
  483 ])dnl
  484 foreachq([__IDN], yuck_idents(defn([__CMD])), [dnl
  485 yuck_C_literal(backquote([yuck_option_help_line(defn([__IDN]), defn([__CMD]))]))[]dnl
  486 ])dnl
  487 ");
  488         break;
  489 ])
  490     }
  491 
  492 #if defined yuck_post_help
  493     yuck_post_help(src);
  494 #endif  /* yuck_post_help */
  495 
  496 #if defined PACKAGE_BUGREPORT
  497     puts("\n\
  498 Report bugs to " PACKAGE_BUGREPORT);
  499 #endif  /* PACKAGE_BUGREPORT */
  500     return;
  501 }
  502 
  503 DEFUN void yuck_auto_version(const yuck_t src[[static 1U]])
  504 {
  505     switch (src->cmd) {
  506     default:
  507 ifdef([YUCK_VERSION], [dnl
  508         puts("YUCK_UMB_STR YUCK_VERSION");
  509 ], [dnl
  510 #if 0
  511 
  512 #elif defined package_string
  513         puts(package_string);
  514 #elif defined package_version
  515         printf("YUCK_UMB_STR %s\n", package_version);
  516 #elif defined PACKAGE_STRING
  517         puts(PACKAGE_STRING);
  518 #elif defined PACKAGE_VERSION
  519         puts("YUCK_UMB_STR " PACKAGE_VERSION);
  520 #elif defined VERSION
  521         puts("YUCK_UMB_STR " VERSION);
  522 #else  /* !PACKAGE_VERSION, !VERSION */
  523         puts("YUCK_UMB_STR unknown version");
  524 #endif  /* PACKAGE_VERSION */
  525 ])dnl
  526         break;
  527     }
  528 
  529 #if defined yuck_post_version
  530     yuck_post_version(src);
  531 #endif  /* yuck_post_version */
  532     return;
  533 }
  534 popdef([DEFUN])dnl
  535 
  536 #if defined __INTEL_COMPILER
  537 # pragma warning (pop)
  538 #elif defined __GNUC__
  539 # if __GNUC__ > 4 || __GNUC__ == 4 &&  __GNUC_MINOR__ >= 6
  540 #  pragma GCC diagnostic pop
  541 # endif  /* GCC version */
  542 #endif  /* __INTEL_COMPILER */
  543 changequote`'dnl