"Fossies" - the Fresh Open Source Software Archive

Member "dateutils-0.4.6/src/dconv.c" (19 Mar 2019, 6509 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. For more information about "dconv.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.4.5_vs_0.4.6.

    1 /*** dconv.c -- convert calendrical and time stamp systems
    2  *
    3  * Copyright (C) 2011-2019 Sebastian Freundt
    4  *
    5  * Author:  Sebastian Freundt <freundt@ga-group.nl>
    6  *
    7  * This file is part of dateutils.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  *
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  *
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * 3. Neither the name of the author nor the names of any contributors
   21  *    may be used to endorse or promote products derived from this
   22  *    software without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
   25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   27  * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
   31  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   32  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
   33  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   34  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35  *
   36  **/
   37 #if defined HAVE_CONFIG_H
   38 # include "config.h"
   39 #endif  /* HAVE_CONFIG_H */
   40 #include <stdio.h>
   41 #include <stdlib.h>
   42 #include <stdint.h>
   43 #include <sys/time.h>
   44 #include <time.h>
   45 
   46 #include "dt-core.h"
   47 #include "dt-io.h"
   48 #include "dt-locale.h"
   49 #include "prchunk.h"
   50 
   51 
   52 const char *prog = "dconv";
   53 
   54 struct prln_ctx_s {
   55     struct grep_atom_soa_s *ndl;
   56     const char *ofmt;
   57     zif_t fromz;
   58     zif_t outz;
   59     int sed_mode_p;
   60     int quietp;
   61 };
   62 
   63 static int
   64 proc_line(struct prln_ctx_s ctx, char *line, size_t llen)
   65 {
   66     struct dt_dt_s d;
   67     char *sp = NULL;
   68     char *ep = NULL;
   69     int rc = 0;
   70 
   71     do {
   72         d = dt_io_find_strpdt2(
   73             line, llen, ctx.ndl, &sp, &ep, ctx.fromz);
   74 
   75         /* check if line matches */
   76         if (!dt_unk_p(d) && ctx.sed_mode_p) {
   77             __io_write(line, sp - line, stdout);
   78             dt_io_write(d, ctx.ofmt, ctx.outz, '\0');
   79             llen -= (ep - line);
   80             line = ep;
   81         } else if (!dt_unk_p(d)) {
   82             if (UNLIKELY(d.fix) && !ctx.quietp) {
   83                 rc = 2;
   84             }
   85             dt_io_write(d, ctx.ofmt, ctx.outz, '\n');
   86             break;
   87         } else if (ctx.sed_mode_p) {
   88             line[llen] = '\n';
   89             __io_write(line, llen + 1, stdout);
   90             break;
   91         } else {
   92             /* obviously unmatched, warn about it in non -q mode */
   93             if (!ctx.quietp) {
   94                 dt_io_warn_strpdt(line);
   95                 rc = 2;
   96             }
   97             break;
   98         }
   99     } while (1);
  100     return rc;
  101 }
  102 
  103 
  104 #include "dconv.yucc"
  105 
  106 int
  107 main(int argc, char *argv[])
  108 {
  109     yuck_t argi[1U];
  110     const char *ofmt;
  111     char **fmt;
  112     size_t nfmt;
  113     int rc = 0;
  114     zif_t fromz = NULL;
  115     zif_t z = NULL;
  116 
  117     if (yuck_parse(argi, argc, argv)) {
  118         rc = 1;
  119         goto out;
  120     }
  121     /* init and unescape sequences, maybe */
  122     ofmt = argi->format_arg;
  123     fmt = argi->input_format_args;
  124     nfmt = argi->input_format_nargs;
  125     if (argi->backslash_escapes_flag) {
  126         dt_io_unescape(argi->format_arg);
  127         for (size_t i = 0; i < nfmt; i++) {
  128             dt_io_unescape(fmt[i]);
  129         }
  130     }
  131 
  132     if (argi->locale_arg) {
  133         setflocale(argi->locale_arg);
  134     }
  135     if (argi->from_locale_arg) {
  136         setilocale(argi->from_locale_arg);
  137     }
  138 
  139     /* try and read the from and to time zones */
  140     if (argi->from_zone_arg) {
  141         fromz = dt_io_zone(argi->from_zone_arg);
  142     }
  143     if (argi->zone_arg) {
  144         z = dt_io_zone(argi->zone_arg);
  145     }
  146     if (argi->base_arg) {
  147         struct dt_dt_s base = dt_strpdt(argi->base_arg, NULL, NULL);
  148         dt_set_base(base);
  149     }
  150 
  151     if (argi->nargs) {
  152         for (size_t i = 0; i < argi->nargs; i++) {
  153             const char *inp = argi->args[i];
  154             struct dt_dt_s d = dt_io_strpdt(inp, fmt, nfmt, fromz);
  155 
  156             if (!dt_unk_p(d)) {
  157                 if (UNLIKELY(d.fix) && !argi->quiet_flag) {
  158                     rc = 2;
  159                 }
  160                 dt_io_write(d, ofmt, z, '\n');
  161             } else if (!argi->quiet_flag) {
  162                 rc = 2;
  163                 dt_io_warn_strpdt(inp);
  164             }
  165         }
  166     } else if (argi->empty_mode_flag) {
  167         /* read from stdin */
  168         size_t lno = 0;
  169         void *pctx;
  170 
  171         /* no threads reading this stream */
  172         __io_setlocking_bycaller(stdout);
  173 
  174         /* using the prchunk reader now */
  175         if ((pctx = init_prchunk(STDIN_FILENO)) == NULL) {
  176             serror("Error: could not open stdin");
  177             goto clear;
  178         }
  179         while (prchunk_fill(pctx) >= 0) {
  180             for (char *line; prchunk_haslinep(pctx); lno++) {
  181                 size_t llen = prchunk_getline(pctx, &line);
  182                 struct dt_dt_s d;
  183                 char *ep = NULL;
  184 
  185                 if (UNLIKELY(!llen)) {
  186                     goto empty;
  187                 }
  188                 /* try and parse the line */
  189                 d = dt_io_strpdt_ep(line, fmt, nfmt, &ep, fromz);
  190                 if (UNLIKELY(dt_unk_p(d))) {
  191                     goto empty;
  192                 } else if (ep && (unsigned)*ep >= ' ') {
  193                     goto empty;
  194                 }
  195                 dt_io_write(d, ofmt, z, '\n');
  196                 continue;
  197             empty:
  198                 __io_write("\n", 1U, stdout);
  199             }
  200         }
  201         /* get rid of resources */
  202         free_prchunk(pctx);
  203     } else {
  204         /* read from stdin */
  205         size_t lno = 0;
  206         struct grep_atom_s __nstk[16], *needle = __nstk;
  207         size_t nneedle = countof(__nstk);
  208         struct grep_atom_soa_s ndlsoa;
  209         void *pctx;
  210         struct prln_ctx_s prln = {
  211             .ndl = &ndlsoa,
  212             .ofmt = ofmt,
  213             .fromz = fromz,
  214             .outz = z,
  215             .sed_mode_p = argi->sed_mode_flag,
  216             .quietp = argi->quiet_flag,
  217         };
  218 
  219         /* no threads reading this stream */
  220         __io_setlocking_bycaller(stdout);
  221 
  222         /* lest we overflow the stack */
  223         if (nfmt >= nneedle) {
  224             /* round to the nearest 8-multiple */
  225             nneedle = (nfmt | 7) + 1;
  226             needle = calloc(nneedle, sizeof(*needle));
  227         }
  228         /* and now build the needles */
  229         ndlsoa = build_needle(needle, nneedle, fmt, nfmt);
  230 
  231         /* using the prchunk reader now */
  232         if ((pctx = init_prchunk(STDIN_FILENO)) == NULL) {
  233             serror("Error: could not open stdin");
  234             goto ndl_free;
  235         }
  236         while (prchunk_fill(pctx) >= 0) {
  237             for (char *line; prchunk_haslinep(pctx); lno++) {
  238                 size_t llen = prchunk_getline(pctx, &line);
  239 
  240                 rc |= proc_line(prln, line, llen);
  241             }
  242         }
  243         /* get rid of resources */
  244         free_prchunk(pctx);
  245     ndl_free:
  246         if (needle != __nstk) {
  247             free(needle);
  248         }
  249     }
  250 
  251 clear:
  252     dt_io_clear_zones();
  253     if (argi->from_locale_arg) {
  254         setilocale(NULL);
  255     }
  256     if (argi->locale_arg) {
  257         setflocale(NULL);
  258     }
  259 
  260 out:
  261     yuck_free(argi);
  262     return rc;
  263 }
  264 
  265 /* dconv.c ends here */