From 5ad76492af8931added1ae9600309d915d1427a5 Mon Sep 17 00:00:00 2001 From: dana Date: Tue, 13 Nov 2018 13:01:01 -0600 Subject: 43800: Add nanosecond support to strftime built-in --- Src/Modules/datetime.c | 64 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'Src') diff --git a/Src/Modules/datetime.c b/Src/Modules/datetime.c index be378b347..18c7fb58e 100644 --- a/Src/Modules/datetime.c +++ b/Src/Modules/datetime.c @@ -100,8 +100,8 @@ output_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) { int bufsize, x, len; char *endptr = NULL, *scalar = NULL, *buffer; - time_t secs; - struct tm *t; + struct tm *tm; + struct timespec ts; if (OPT_ISSET(ops,'s')) { scalar = OPT_ARG(ops, 's'); @@ -110,30 +110,58 @@ output_strftime(char *nam, char **argv, Options ops, UNUSED(int func)) return 1; } } - if (OPT_ISSET(ops, 'r')) + if (OPT_ISSET(ops, 'r')) { + if (!argv[1]) { + zwarnnam(nam, "timestring expected"); + return 1; + } return reverse_strftime(nam, argv, scalar, OPT_ISSET(ops, 'q')); - - errno = 0; - secs = (time_t)strtoul(argv[1], &endptr, 10); - if (errno != 0) { - zwarnnam(nam, "%s: %e", argv[1], errno); - return 1; - } else if (*endptr != '\0') { - zwarnnam(nam, "%s: invalid decimal number", argv[1]); - return 1; } - t = localtime(&secs); - if (!t) { - zwarnnam(nam, "%s: unable to convert to time", argv[1]); - return 1; + if (!argv[1]) { + zgettime(&ts); + tm = localtime(&ts.tv_sec); + } else { + errno = 0; + + ts.tv_sec = (time_t)strtoul(argv[1], &endptr, 10); + if (errno != 0) { + zwarnnam(nam, "%s: %e", argv[1], errno); + return 1; + } else if (*argv[1] == '\0' || *endptr != '\0') { + zwarnnam(nam, "%s: invalid decimal number", argv[1]); + return 1; + } + + tm = localtime(&ts.tv_sec); + if (!tm) { + zwarnnam(nam, "%s: unable to convert to time", argv[1]); + return 1; + } + + ts.tv_nsec = 0L; + if (argv[2]) { + ts.tv_nsec = (long)zstrtol(argv[2], &endptr, 10); + if (errno != 0) { + zwarnnam(nam, "%s: %e", argv[2], errno); + return 1; + } else if (*argv[2] == '\0' || *endptr != '\0') { + zwarnnam(nam, "%s: invalid decimal number", argv[2]); + return 1; + } else if (ts.tv_nsec < 0) { + zwarnnam(nam, "%s: invalid nanosecond value", argv[2]); + return 1; + } + } } + bufsize = strlen(argv[0]) * 8; buffer = zalloc(bufsize); len = 0; for (x=0; x < 4; x++) { - if ((len = ztrftime(buffer, bufsize, argv[0], t, 0L)) >= 0 || x==3) + if ((len = ztrftime(buffer, bufsize, argv[0], tm, ts.tv_nsec)) >= 0 || + x==3) break; buffer = zrealloc(buffer, bufsize *= 2); } @@ -207,7 +235,7 @@ getcurrenttime(UNUSED(Param pm)) } static struct builtin bintab[] = { - BUILTIN("strftime", 0, bin_strftime, 2, 2, 0, "qrs:", NULL), + BUILTIN("strftime", 0, bin_strftime, 1, 3, 0, "qrs:", NULL), }; static const struct gsu_integer epochseconds_gsu = -- cgit 1.4.1