"Fossies" - the Fresh Open Source Software Archive

Member "dateutils-0.4.6/lib/tzmap.yucc" (19 Mar 2019, 15060 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 "tzmap.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     TZMAP_CMD_NONE = 0U,
   12 
   13     /* actual commands */
   14     TZMAP_CMD_CC,
   15     TZMAP_CMD_SHOW,
   16     TZMAP_CMD_CHECK,
   17     
   18     /* convenience identifiers */
   19     YUCK_NOCMD = TZMAP_CMD_NONE,
   20     YUCK_NCMDS = TZMAP_CMD_CHECK
   21 };
   22 
   23 
   24 
   25 typedef union yuck_u yuck_t;
   26 
   27 
   28 /* convenience structure for `cc' */
   29 struct yuck_cmd_cc_s {
   30     enum yuck_cmds_e cmd;
   31 
   32     /* left-over arguments, the command string is never a part of this */
   33     size_t nargs;
   34     char **args;
   35 
   36     /* help is handled automatically */
   37     /* version is handled automatically */
   38 
   39     char *output_arg;
   40     unsigned int existing_only_flag;
   41 };
   42 
   43 /* convenience structure for `show' */
   44 struct yuck_cmd_show_s {
   45     enum yuck_cmds_e cmd;
   46 
   47     /* left-over arguments, the command string is never a part of this */
   48     size_t nargs;
   49     char **args;
   50 
   51     /* help is handled automatically */
   52     /* version is handled automatically */
   53 
   54     char *tzmap_arg;
   55 };
   56 
   57 /* convenience structure for `check' */
   58 struct yuck_cmd_check_s {
   59     enum yuck_cmds_e cmd;
   60 
   61     /* left-over arguments, the command string is never a part of this */
   62     size_t nargs;
   63     char **args;
   64 
   65     /* help is handled automatically */
   66     /* version is handled automatically */
   67 
   68 };
   69 
   70 
   71 union yuck_u {
   72     /* generic struct */
   73     struct {
   74         enum yuck_cmds_e cmd;
   75 
   76         /* left-over arguments,
   77          * the command string is never a part of this */
   78         size_t nargs;
   79         char **args;
   80 
   81         /* slots common to all commands */
   82         /* help is handled automatically */
   83         /* version is handled automatically */
   84     };
   85 
   86     /* depending on CMD at most one of the following structs is filled in
   87      * if CMD is YUCK_NONE no slots of this union must be accessed */
   88     struct yuck_cmd_cc_s cc;
   89     struct yuck_cmd_show_s show;
   90     struct yuck_cmd_check_s check;
   91 };
   92 
   93 
   94 static __attribute__((nonnull(1))) int
   95 yuck_parse(yuck_t*, int argc, char *argv[]);
   96 static __attribute__((nonnull(1))) void yuck_free(yuck_t*);
   97 
   98 static __attribute__((nonnull(1))) void yuck_auto_help(const yuck_t*);
   99 static __attribute__((nonnull(1))) void yuck_auto_usage(const yuck_t*);
  100 static __attribute__((nonnull(1))) void yuck_auto_version(const yuck_t*);
  101 
  102 /* some hooks */
  103 #if defined yuck_post_help
  104 static __attribute__((nonnull(1))) void yuck_post_help(const yuck_t*);
  105 #endif  /* yuck_post_help */
  106 
  107 #if defined yuck_post_usage
  108 static __attribute__((nonnull(1))) void yuck_post_usage(const yuck_t*);
  109 #endif  /* yuck_post_usage */
  110 
  111 #if defined yuck_post_version
  112 static __attribute__((nonnull(1))) void yuck_post_version(const yuck_t*);
  113 #endif  /* yuck_post_version */
  114 
  115 #endif  /* INCLUDED_yuck_h_ */
  116 /* -*- c -*- */
  117 #if defined HAVE_CONFIG_H
  118 # include "config.h"
  119 #endif  /* HAVE_CONFIG_H */
  120 #if defined HAVE_VERSION_H
  121 # include "version.h"
  122 #endif  /* HAVE_VERSION_H */
  123 #include <stdlib.h>
  124 #include <stdbool.h>
  125 #include <string.h>
  126 #include <stdio.h>
  127 #include <limits.h>
  128 
  129 #if defined __INTEL_COMPILER
  130 # pragma warning (push)
  131 # pragma warning (disable:177)
  132 # pragma warning (disable:111)
  133 # pragma warning (disable:3280)
  134 #elif defined __GNUC__
  135 # if __GNUC__ > 4 || __GNUC__ == 4 &&  __GNUC_MINOR__ >= 6
  136 #  pragma GCC diagnostic push
  137 # endif  /* GCC version */
  138 # pragma GCC diagnostic ignored "-Wunused-label"
  139 # pragma GCC diagnostic ignored "-Wunused-variable"
  140 # pragma GCC diagnostic ignored "-Wunused-function"
  141 # pragma GCC diagnostic ignored "-Wshadow"
  142 #endif  /* __INTEL_COMPILER */
  143 
  144 
  145 static inline bool
  146 yuck_streqp(const char *s1, const char *s2)
  147 {
  148     return !strcmp(s1, s2);
  149 }
  150 
  151 /* for multi-args */
  152 static inline char**
  153 yuck_append(char **array, size_t n, char *val)
  154 {
  155     if (!(n % 16U)) {
  156         /* resize */
  157         void *tmp = realloc(array, (n + 16U) * sizeof(*array));
  158         if (tmp == NULL) {
  159             free(array);
  160             return NULL;
  161         }
  162         /* otherwise make it persistent */
  163         array = tmp;
  164     }
  165     array[n] = val;
  166     return array;
  167 }
  168 
  169 static enum yuck_cmds_e yuck_parse_cmd(const char *cmd)
  170 {
  171     if (0) {
  172         ;
  173     } else if (yuck_streqp(cmd, "cc")) {
  174         return TZMAP_CMD_CC;
  175     } else if (yuck_streqp(cmd, "show")) {
  176         return TZMAP_CMD_SHOW;
  177     } else if (yuck_streqp(cmd, "check")) {
  178         return TZMAP_CMD_CHECK;
  179     } else {
  180         /* error here? */
  181         fprintf(stderr, "tzmap: invalid command `%s'\n\
  182 Try `--help' for a list of commands.\n", cmd);
  183     }
  184     return (enum yuck_cmds_e)-1;
  185 }
  186 
  187 
  188 static int yuck_parse(yuck_t tgt[static 1U], int argc, char *argv[])
  189 {
  190     char *op;
  191     int i;
  192 
  193     /* we'll have at most this many args */
  194     memset(tgt, 0, sizeof(*tgt));
  195     if ((tgt->args = calloc(argc, sizeof(*tgt->args))) == NULL) {
  196         return -1;
  197     }
  198     for (i = 1; i < argc && tgt->nargs < (size_t)-1; i++) {
  199         op = argv[i];
  200 
  201         switch (*op) {
  202         case '-':
  203             /* could be an option */
  204             switch (*++op) {
  205             default:
  206                 /* could be glued into one */
  207                 for (; *op; op++) {
  208                     goto shortopt; back_from_shortopt:;
  209                 }
  210                 break;
  211             case '-':
  212                 if (*++op == '\0') {
  213                     i++;
  214                     goto dashdash; back_from_dashdash:;
  215                     break;
  216                 }
  217                 goto longopt; back_from_longopt:;
  218                 break;
  219             case '\0':
  220                 goto plain_dash;
  221             }
  222             break;
  223         default:
  224         plain_dash:
  225             goto arg; back_from_arg:;
  226             break;
  227         }
  228     }
  229     if (i < argc) {
  230         op = argv[i];
  231 
  232         if (*op++ == '-' && *op++ == '-' && !*op) {
  233             /* another dashdash, filter out */
  234             i++;
  235         }
  236     }
  237     /* has to be here as the max_pargs condition might drive us here */
  238     dashdash:
  239     {
  240         /* dashdash loop, pile everything on tgt->args
  241          * don't check for subcommands either, this is in accordance to
  242          * the git tool which won't accept commands after -- */
  243         for (; i < argc; i++) {
  244             tgt->args[tgt->nargs++] = argv[i];
  245         }
  246     }
  247     return 0;
  248 
  249     longopt:
  250     {
  251         /* split into option and arg part */
  252         char *arg;
  253 
  254         if ((arg = strchr(op, '=')) != NULL) {
  255             /* \nul this one out */
  256             *arg++ = '\0';
  257         }
  258 
  259         switch (tgt->cmd) {
  260         default:
  261             goto TZMAP_CMD_NONE_longopt; back_from_TZMAP_CMD_NONE_longopt:;
  262             break;
  263         case TZMAP_CMD_CC:
  264             goto TZMAP_CMD_CC_longopt; back_from_TZMAP_CMD_CC_longopt:;
  265             break;
  266         case TZMAP_CMD_SHOW:
  267             goto TZMAP_CMD_SHOW_longopt; back_from_TZMAP_CMD_SHOW_longopt:;
  268             break;
  269         case TZMAP_CMD_CHECK:
  270             goto TZMAP_CMD_CHECK_longopt; back_from_TZMAP_CMD_CHECK_longopt:;
  271             break;
  272         }
  273         goto back_from_longopt;
  274 
  275 
  276         TZMAP_CMD_NONE_longopt:
  277         {
  278             if (0) {
  279                 ;
  280             } else if (yuck_streqp(op, "help")) {
  281                 /* invoke auto action and exit */
  282                 yuck_auto_help(tgt);
  283                 goto success;
  284             } else if (yuck_streqp(op, "version")) {
  285                 /* invoke auto action and exit */
  286                 yuck_auto_version(tgt);
  287                 goto success;
  288             } else {
  289                 /* grml */
  290                 fprintf(stderr, "tzmap: unrecognized option `--%s'\n", op);
  291                 goto failure;
  292             xtra_chk:
  293                 if (arg != NULL) {
  294                     fprintf(stderr, "tzmap: option `--%s' doesn't allow an argument\n", op);
  295                     goto failure;
  296                 }
  297             }
  298             if (i >= argc) {
  299                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  300                 goto failure;
  301             }
  302             goto back_from_TZMAP_CMD_NONE_longopt;
  303         }
  304         TZMAP_CMD_CC_longopt:
  305         {
  306             if (0) {
  307                 ;
  308             } else if (yuck_streqp(op, "output")) {
  309                 tgt->cc.output_arg = arg ?: argv[++i];
  310             } else if (yuck_streqp(op, "existing-only")) {
  311                 tgt->cc.existing_only_flag++; goto xtra_chk;
  312             } else {
  313                 goto TZMAP_CMD_NONE_longopt;
  314             }
  315             if (i >= argc) {
  316                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  317                 goto failure;
  318             }
  319             goto back_from_TZMAP_CMD_CC_longopt;
  320         }
  321         TZMAP_CMD_SHOW_longopt:
  322         {
  323             if (0) {
  324                 ;
  325             } else if (yuck_streqp(op, "tzmap")) {
  326                 tgt->show.tzmap_arg = arg ?: argv[++i];
  327             } else {
  328                 goto TZMAP_CMD_NONE_longopt;
  329             }
  330             if (i >= argc) {
  331                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  332                 goto failure;
  333             }
  334             goto back_from_TZMAP_CMD_SHOW_longopt;
  335         }
  336         TZMAP_CMD_CHECK_longopt:
  337         {
  338             if (0) {
  339                 ;
  340             } else {
  341                 goto TZMAP_CMD_NONE_longopt;
  342             }
  343             if (i >= argc) {
  344                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  345                 goto failure;
  346             }
  347             goto back_from_TZMAP_CMD_CHECK_longopt;
  348         }
  349         
  350     }
  351 
  352     shortopt:
  353     {
  354         char *arg = op + 1U;
  355 
  356         switch (tgt->cmd) {
  357         default:
  358             goto TZMAP_CMD_NONE_shortopt; back_from_TZMAP_CMD_NONE_shortopt:;
  359             break;
  360         case TZMAP_CMD_CC:
  361             goto TZMAP_CMD_CC_shortopt; back_from_TZMAP_CMD_CC_shortopt:;
  362             break;
  363         case TZMAP_CMD_SHOW:
  364             goto TZMAP_CMD_SHOW_shortopt; back_from_TZMAP_CMD_SHOW_shortopt:;
  365             break;
  366         case TZMAP_CMD_CHECK:
  367             goto TZMAP_CMD_CHECK_shortopt; back_from_TZMAP_CMD_CHECK_shortopt:;
  368             break;
  369         }
  370         goto back_from_shortopt;
  371 
  372 
  373         TZMAP_CMD_NONE_shortopt:
  374         {
  375             switch (*op) {
  376             default:
  377                 /* again for clarity */
  378                 switch (*op) {
  379                 case '0':
  380                 case '1':
  381                 case '2':
  382                 case '3':
  383                 case '4':
  384                 case '5':
  385                 case '6':
  386                 case '7':
  387                 case '8':
  388                 case '9':
  389                     if (op[-1] == '-') {
  390                         /* literal treatment of numeral */
  391                         goto arg;
  392                     }
  393                     /* fallthrough */
  394                 default:
  395                     break;
  396                 }
  397                 ;
  398                 ;
  399                 fprintf(stderr, "tzmap: unrecognized option -%c\n", *op);
  400                 goto failure;
  401 
  402 
  403 
  404                 
  405             case 'h':
  406                 /* invoke auto action and exit */
  407                 yuck_auto_help(tgt);
  408                 goto success;
  409                 break;
  410             case 'V':
  411                 /* invoke auto action and exit */
  412                 yuck_auto_version(tgt);
  413                 goto success;
  414                 break;
  415             }
  416             if (i >= argc) {
  417                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  418                 goto failure;
  419             }
  420             goto back_from_TZMAP_CMD_NONE_shortopt;
  421         }
  422         TZMAP_CMD_CC_shortopt:
  423         {
  424             switch (*op) {
  425             default:
  426                 /* again for clarity */
  427                 switch (*op) {
  428                 case '0':
  429                 case '1':
  430                 case '2':
  431                 case '3':
  432                 case '4':
  433                 case '5':
  434                 case '6':
  435                 case '7':
  436                 case '8':
  437                 case '9':
  438                     if (op[-1] == '-') {
  439                         /* literal treatment of numeral */
  440                         goto arg;
  441                     }
  442                     /* fallthrough */
  443                 default:
  444                     break;
  445                 }
  446                 ;
  447                 ;
  448                 goto TZMAP_CMD_NONE_shortopt;
  449 
  450                 
  451             case 'o':
  452                 tgt->cc.output_arg = *arg
  453                     ? (op += strlen(arg), arg)
  454                     : argv[++i];
  455                 break;
  456             case 'e':
  457                 tgt->cc.existing_only_flag++;
  458                 break;
  459             }
  460             if (i >= argc) {
  461                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  462                 goto failure;
  463             }
  464             goto back_from_TZMAP_CMD_CC_shortopt;
  465         }
  466         TZMAP_CMD_SHOW_shortopt:
  467         {
  468             switch (*op) {
  469             default:
  470                 /* again for clarity */
  471                 switch (*op) {
  472                 case '0':
  473                 case '1':
  474                 case '2':
  475                 case '3':
  476                 case '4':
  477                 case '5':
  478                 case '6':
  479                 case '7':
  480                 case '8':
  481                 case '9':
  482                     if (op[-1] == '-') {
  483                         /* literal treatment of numeral */
  484                         goto arg;
  485                     }
  486                     /* fallthrough */
  487                 default:
  488                     break;
  489                 }
  490                 ;
  491                 ;
  492                 goto TZMAP_CMD_NONE_shortopt;
  493 
  494                 
  495             case 'f':
  496                 tgt->show.tzmap_arg = *arg
  497                     ? (op += strlen(arg), arg)
  498                     : argv[++i];
  499                 break;
  500             }
  501             if (i >= argc) {
  502                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  503                 goto failure;
  504             }
  505             goto back_from_TZMAP_CMD_SHOW_shortopt;
  506         }
  507         TZMAP_CMD_CHECK_shortopt:
  508         {
  509             switch (*op) {
  510             default:
  511                 /* again for clarity */
  512                 switch (*op) {
  513                 case '0':
  514                 case '1':
  515                 case '2':
  516                 case '3':
  517                 case '4':
  518                 case '5':
  519                 case '6':
  520                 case '7':
  521                 case '8':
  522                 case '9':
  523                     if (op[-1] == '-') {
  524                         /* literal treatment of numeral */
  525                         goto arg;
  526                     }
  527                     /* fallthrough */
  528                 default:
  529                     break;
  530                 }
  531                 ;
  532                 ;
  533                 goto TZMAP_CMD_NONE_shortopt;
  534 
  535                 
  536             }
  537             if (i >= argc) {
  538                 fprintf(stderr, "tzmap: option `--%s' requires an argument\n", op);
  539                 goto failure;
  540             }
  541             goto back_from_TZMAP_CMD_CHECK_shortopt;
  542         }
  543         
  544     }
  545 
  546     arg:
  547     {
  548         if (tgt->cmd || YUCK_NCMDS == 0U) {
  549             tgt->args[tgt->nargs++] = argv[i];
  550         } else {
  551             /* ah, might be an arg then */
  552             if ((tgt->cmd = yuck_parse_cmd(op)) > YUCK_NCMDS) {
  553                 return -1;
  554             }
  555         }
  556         goto back_from_arg;
  557     }
  558 
  559     failure:
  560     {
  561         exit(EXIT_FAILURE);
  562     }
  563 
  564     success:
  565     {
  566         exit(EXIT_SUCCESS);
  567     }
  568 }
  569 
  570 static void yuck_free(yuck_t tgt[static 1U])
  571 {
  572     if (tgt->args != NULL) {
  573         /* free despite const qualifier */
  574         free(tgt->args);
  575     }
  576     /* free mulargs */
  577     switch (tgt->cmd) {
  578         void *ptr;
  579     default:
  580         break;
  581     case TZMAP_CMD_NONE:
  582 ;
  583 ;
  584         break;
  585     case TZMAP_CMD_CC:
  586 ;
  587 ;
  588         break;
  589     case TZMAP_CMD_SHOW:
  590 ;
  591         break;
  592     case TZMAP_CMD_CHECK:
  593         break;
  594     }
  595     return;
  596 }
  597 
  598 static void yuck_auto_usage(const yuck_t src[static 1U])
  599 {
  600     switch (src->cmd) {
  601     default:
  602     YUCK_NOCMD:
  603         puts("Usage: tzmap [OPTION]... COMMAND [ARG]...\n\
  604 \n\
  605 Generate or inspect zoneinfo name map files.\n\
  606 ");
  607         break;
  608 
  609     case TZMAP_CMD_CC:
  610         puts("Usage: tzmap cc [OPTION]... [FILE]...\n\
  611 \n\
  612 Generate a map to zoneinfo names suitable for dateutils.\n\
  613 ");
  614         break;
  615 
  616     case TZMAP_CMD_SHOW:
  617         puts("Usage: tzmap show [OPTION]... [MNAME]...\n\
  618 \n\
  619 Show mapped zonename for MNAMEs, if omitted show all entries\n\
  620 from the specified tzmap file.\n\
  621 ");
  622         break;
  623 
  624     case TZMAP_CMD_CHECK:
  625         puts("Usage: tzmap check [FILE]...\n\
  626 \n\
  627 Check IANA zonenames in FILEs.\n\
  628 ");
  629         break;
  630 
  631     }
  632 
  633 #if defined yuck_post_usage
  634     yuck_post_usage(src);
  635 #endif  /* yuck_post_usage */
  636     return;
  637 }
  638 
  639 static void yuck_auto_help(const yuck_t src[static 1U])
  640 {
  641     yuck_auto_usage(src);
  642 
  643     if (src->cmd == YUCK_NOCMD) {
  644         /* also output a list of commands */
  645         puts("COMMAND may be one of:\n\
  646   cc          Generate a map to zoneinfo names suitable for dateutils.\n\
  647   show        Show mapped zonename for MNAMEs, if omitted show all entries\n\
  648   check       Check IANA zonenames in FILEs.\n\
  649 ");
  650     }
  651 
  652     /* leave a not about common options */
  653     if (src->cmd == YUCK_NOCMD) {
  654         puts("\
  655 Options accepted by all commands:");
  656     } else {
  657         puts("\
  658 Common options:\n\
  659   -h, --help            display this help and exit\n\
  660   -V, --version         output version information and exit\n\
  661 ");
  662     }
  663 
  664     switch (src->cmd) {
  665     default:
  666     case TZMAP_CMD_NONE:
  667         puts("\
  668   -h, --help            display this help and exit\n\
  669   -V, --version         output version information and exit\n\
  670 ");
  671         break;
  672 
  673     case TZMAP_CMD_CC:
  674         puts("\
  675 Command-specific options:\n\
  676   -o, --output=FILE     Output compiled map into FILE.\n\
  677   -e, --existing-only   Only map currently existing zones.\n\
  678 ");
  679         break;
  680 
  681     case TZMAP_CMD_SHOW:
  682         puts("\
  683 Command-specific options:\n\
  684   -f, --tzmap=FILE      Use FILE.\n\
  685 ");
  686         break;
  687 
  688     case TZMAP_CMD_CHECK:
  689         puts("\
  690 ");
  691         break;
  692 
  693     }
  694 
  695 #if defined yuck_post_help
  696     yuck_post_help(src);
  697 #endif  /* yuck_post_help */
  698 
  699 #if defined PACKAGE_BUGREPORT
  700     puts("\n\
  701 Report bugs to " PACKAGE_BUGREPORT);
  702 #endif  /* PACKAGE_BUGREPORT */
  703     return;
  704 }
  705 
  706 static void yuck_auto_version(const yuck_t src[static 1U])
  707 {
  708     switch (src->cmd) {
  709     default:
  710 #if 0
  711 
  712 #elif defined package_string
  713         puts(package_string);
  714 #elif defined package_version
  715         printf("tzmap %s\n", package_version);
  716 #elif defined PACKAGE_STRING
  717         puts(PACKAGE_STRING);
  718 #elif defined PACKAGE_VERSION
  719         puts("tzmap " PACKAGE_VERSION);
  720 #elif defined VERSION
  721         puts("tzmap " VERSION);
  722 #else  /* !PACKAGE_VERSION, !VERSION */
  723         puts("tzmap unknown version");
  724 #endif  /* PACKAGE_VERSION */
  725         break;
  726     }
  727 
  728 #if defined yuck_post_version
  729     yuck_post_version(src);
  730 #endif  /* yuck_post_version */
  731     return;
  732 }
  733 
  734 #if defined __INTEL_COMPILER
  735 # pragma warning (pop)
  736 #elif defined __GNUC__
  737 # if __GNUC__ > 4 || __GNUC__ == 4 &&  __GNUC_MINOR__ >= 6
  738 #  pragma GCC diagnostic pop
  739 # endif  /* GCC version */
  740 #endif  /* __INTEL_COMPILER */