isupport time zone conversion and date-time parsing - ics2txt - convert icalendar .ics file to plain text Err bitreich.org 70
hgit clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt URL:git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt bitreich.org 70
1Log /scm/ics2txt/log.gph bitreich.org 70
1Files /scm/ics2txt/files.gph bitreich.org 70
1Refs /scm/ics2txt/refs.gph bitreich.org 70
1Tags /scm/ics2txt/tag bitreich.org 70
1README /scm/ics2txt/file/README.md.gph bitreich.org 70
i--- Err bitreich.org 70
1commit 58a1a9df90b5751ae05fba076cd9e664e3d9f3c1 /scm/ics2txt/commit/58a1a9df90b5751ae05fba076cd9e664e3d9f3c1.gph bitreich.org 70
1parent b72092250747c7443e20fee06bee232b236f441e /scm/ics2txt/commit/b72092250747c7443e20fee06bee232b236f441e.gph bitreich.org 70
hAuthor: Josuah Demangeon <me@josuah.net> URL:mailto:me@josuah.net bitreich.org 70
iDate: Mon, 14 Jun 2021 00:08:10 +0200 Err bitreich.org 70
i Err bitreich.org 70
isupport time zone conversion and date-time parsing Err bitreich.org 70
i Err bitreich.org 70
iConvert dates from DT* fields to epoch on sample program. Err bitreich.org 70
i Err bitreich.org 70
iDiffstat: Err bitreich.org 70
i M ical.c | 168 ++++++++++++++++++++++++++------ Err bitreich.org 70
i M ical.h | 19 ++++++++++++++----- Err bitreich.org 70
i M ics2tree.c | 28 +++++++++++++++++++++------- Err bitreich.org 70
i M util.c | 81 ++++++++++++++++++++++--------- Err bitreich.org 70
i M util.h | 21 +++++++++++++-------- Err bitreich.org 70
i Err bitreich.org 70
i5 files changed, 245 insertions(+), 72 deletions(-) Err bitreich.org 70
i--- Err bitreich.org 70
1diff --git a/ical.c b/ical.c /scm/ics2txt/file/ical.c.gph bitreich.org 70
i@@ -11,6 +11,12 @@ Err bitreich.org 70
i #include "util.h" Err bitreich.org 70
i #include "base64.h" Err bitreich.org 70
i Err bitreich.org 70
i+#define Xstrlcpy(d, s) (strlcpy((d), (s), sizeof(d)) < sizeof(d)) Err bitreich.org 70
i+#define Xstrlcat(d, s) (strlcat((d), (s), sizeof(d)) < sizeof(d)) Err bitreich.org 70
i+ Err bitreich.org 70
i+/* helpers: common utilities to call within the p->fn() callbacks as Err bitreich.org 70
i+ * well as in the code below */ Err bitreich.org 70
i+ Err bitreich.org 70
i int Err bitreich.org 70
i ical_error(IcalParser *p, char const *msg) Err bitreich.org 70
i { Err bitreich.org 70
i@@ -19,6 +25,12 @@ ical_error(IcalParser *p, char const *msg) Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i int Err bitreich.org 70
i+ical_get_level(IcalParser *p) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ return p->current - p->stack; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i ical_get_value(IcalParser *p, char *s, size_t *len) Err bitreich.org 70
i { Err bitreich.org 70
i *len = strlen(s); Err bitreich.org 70
i@@ -31,9 +43,111 @@ ical_get_value(IcalParser *p, char *s, size_t *len) Err bitreich.org 70
i int Err bitreich.org 70
i ical_get_time(IcalParser *p, char *s, time_t *t) Err bitreich.org 70
i { Err bitreich.org 70
i- return -1; Err bitreich.org 70
i+ struct tm tm = {0}; Err bitreich.org 70
i+ char const *tzid; Err bitreich.org 70
i+ Err bitreich.org 70
i+ tzid = (p->tzid) ? p->tzid : Err bitreich.org 70
i+ (p->current && p->current->tzid[0] != '\0') ? p->current->tzid : Err bitreich.org 70
i+ ""; Err bitreich.org 70
i+ Err bitreich.org 70
i+ /* date */ Err bitreich.org 70
i+ for (int i = 0; i < 8; i++) Err bitreich.org 70
i+ if (!isdigit(s[i])) Err bitreich.org 70
i+ return ical_error(p, "invalid date format"); Err bitreich.org 70
i+ tm.tm_year = s[0] * 1000 + s[1] * 100 + s[2] * 10 + s[3]; Err bitreich.org 70
i+ tm.tm_mon = s[4] * 10 + s[5] - 1; Err bitreich.org 70
i+ tm.tm_mday = s[6] * 10 + s[7]; Err bitreich.org 70
i+ s += 8; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (*s == 'T') { Err bitreich.org 70
i+ /* time */ Err bitreich.org 70
i+ s++; Err bitreich.org 70
i+ for (int i = 0; i < 6; i++) Err bitreich.org 70
i+ if (!isdigit(s[i])) Err bitreich.org 70
i+ return ical_error(p, "invalid time format"); Err bitreich.org 70
i+ tm.tm_hour = s[0] * 10 + s[1]; Err bitreich.org 70
i+ tm.tm_min = s[2] * 10 + s[3]; Err bitreich.org 70
i+ tm.tm_sec = s[4] * 10 + s[5]; Err bitreich.org 70
i+ if (s[6] == 'Z') Err bitreich.org 70
i+ tzid = "UTC"; Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i+ if ((*t = tztime(&tm, tzid)) == (time_t)-1) Err bitreich.org 70
i+ return ical_error(p, "could not convert time"); Err bitreich.org 70
i+ Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+/* hooks: called just before user functions to do extra work such as Err bitreich.org 70
i+ * processing time zones definition or prepare base64 decoding, and Err bitreich.org 70
i+ * permit to only have parsing code left to parsing functions */ Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+hook_entry_name(IcalParser *p, char *name) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ (void)p; (void)name; Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+hook_param_name(IcalParser *p, char *name) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ (void)p; (void)name; Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+hook_param_value(IcalParser *p, char *name, char *value) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (strcasecmp(name, "ENCODING") == 0) Err bitreich.org 70
i+ p->base64 = (strcasecmp(value, "BASE64") == 0); Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (strcasecmp(name, "TZID") == 0) Err bitreich.org 70
i+ p->tzid = value; Err bitreich.org 70
i+ Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+hook_entry_value(IcalParser *p, char *name, char *value) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (strcasecmp(name, "TZID") == 0) Err bitreich.org 70
i+ if (!Xstrlcpy(p->current->tzid, value)) Err bitreich.org 70
i+ return ical_error(p, "TZID: name too large"); Err bitreich.org 70
i+ Err bitreich.org 70
i+ p->tzid = NULL; Err bitreich.org 70
i+ Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+hook_block_begin(IcalParser *p, char *name) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ p->current++; Err bitreich.org 70
i+ memset(p->current, 0, sizeof(*p->current)); Err bitreich.org 70
i+ if (ical_get_level(p) >= ICAL_STACK_SIZE) Err bitreich.org 70
i+ return ical_error(p, "max recurion reached"); Err bitreich.org 70
i+ if (!Xstrlcpy(p->current->name, name)) Err bitreich.org 70
i+ return ical_error(p, "value too large"); Err bitreich.org 70
i+ Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+int Err bitreich.org 70
i+hook_block_end(IcalParser *p, char *name) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ if (strcasecmp(p->current->name, name) != 0) Err bitreich.org 70
i+ return ical_error(p, "mismatching BEGIN: and END:"); Err bitreich.org 70
i+ p->current--; Err bitreich.org 70
i+ if (p->current < p->stack) Err bitreich.org 70
i+ return ical_error(p, "more END: than BEGIN:"); Err bitreich.org 70
i+ Err bitreich.org 70
i+ return 0; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i+/* parsers: in charge of reading from `fp`, splitting text into Err bitreich.org 70
i+ * fields, and call hooks and user functions. */ Err bitreich.org 70
i+ Err bitreich.org 70
i #define CALL(p, fn, ...) ((p)->fn ? (p)->fn((p), __VA_ARGS__) : 0) Err bitreich.org 70
i Err bitreich.org 70
i static int Err bitreich.org 70
i@@ -43,24 +157,23 @@ ical_parse_value(IcalParser *p, char **sp, char *name) Err bitreich.org 70
i char *s, c, *val; Err bitreich.org 70
i Err bitreich.org 70
i s = *sp; Err bitreich.org 70
i- Err bitreich.org 70
i if (*s == '"') { Err bitreich.org 70
i- ++s; Err bitreich.org 70
i- for (val = s; !iscntrl(*s) && !strchr(",;:\"", *s); s++); Err bitreich.org 70
i+ val = ++s; Err bitreich.org 70
i+ while (!iscntrl(*s) && *s != '"') Err bitreich.org 70
i+ s++; Err bitreich.org 70
i if (*s != '"') Err bitreich.org 70
i return ical_error(p, "missing '\"'"); Err bitreich.org 70
i *s++ = '\0'; Err bitreich.org 70
i } else { Err bitreich.org 70
i- for (val = s; !iscntrl(*s) && !strchr(",;:'\"", *s); s++); Err bitreich.org 70
i+ val = s; Err bitreich.org 70
i+ while (!iscntrl(*s) && !strchr(",;:'\"", *s)) Err bitreich.org 70
i+ s++; Err bitreich.org 70
i } Err bitreich.org 70
i- Err bitreich.org 70
i c = *s, *s = '\0'; Err bitreich.org 70
i- if ((err = CALL(p, fn_param_value, name, val)) != 0) Err bitreich.org 70
i+ if ((err = hook_param_value(p, name, val)) != 0 || Err bitreich.org 70
i+ (err = CALL(p, fn_param_value, name, val)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i- if (strcasecmp(name, "ENCODING") == 0) Err bitreich.org 70
i- p->base64 = (strcasecmp(val, "BASE64") == 0); Err bitreich.org 70
i *s = c; Err bitreich.org 70
i- Err bitreich.org 70
i *sp = s; Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i@@ -72,42 +185,39 @@ ical_parse_param(IcalParser *p, char **sp) Err bitreich.org 70
i char *s, *name; Err bitreich.org 70
i Err bitreich.org 70
i s = *sp; Err bitreich.org 70
i- Err bitreich.org 70
i do { Err bitreich.org 70
i for (name = s; isalnum(*s) || *s == '-'; s++); Err bitreich.org 70
i if (s == name || (*s != '=')) Err bitreich.org 70
i return ical_error(p, "invalid parameter name"); Err bitreich.org 70
i *s++ = '\0'; Err bitreich.org 70
i- if ((err = CALL(p, fn_param_name, name)) != 0) Err bitreich.org 70
i+ if ((err = hook_param_name(p, name)) != 0 || Err bitreich.org 70
i+ (err = CALL(p, fn_param_name, name)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i- Err bitreich.org 70
i do { Err bitreich.org 70
i if ((err = ical_parse_value(p, &s, name)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i } while (*s == ',' && s++); Err bitreich.org 70
i } while (*s == ';' && s++); Err bitreich.org 70
i- Err bitreich.org 70
i *sp = s; Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i static int Err bitreich.org 70
i-ical_parse_contentline(IcalParser *p, char *line) Err bitreich.org 70
i+ical_parse_contentline(IcalParser *p, char *s) Err bitreich.org 70
i { Err bitreich.org 70
i int err; Err bitreich.org 70
i- char *s, c, *name, *end; Err bitreich.org 70
i- Err bitreich.org 70
i- s = line; Err bitreich.org 70
i+ char c, *name, *sep; Err bitreich.org 70
i Err bitreich.org 70
i for (name = s; isalnum(*s) || *s == '-'; s++); Err bitreich.org 70
i if (s == name || (*s != ';' && *s != ':')) Err bitreich.org 70
i return ical_error(p, "invalid entry name"); Err bitreich.org 70
i c = *s, *s = '\0'; Err bitreich.org 70
i if (strcasecmp(name, "BEGIN") != 0 && strcasecmp(name, "END") != 0) Err bitreich.org 70
i- if ((err = CALL(p, fn_entry_name, name)) != 0) Err bitreich.org 70
i+ if ((err = hook_entry_name(p, name)) != 0 || Err bitreich.org 70
i+ (err = CALL(p, fn_entry_name, name)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i *s = c; Err bitreich.org 70
i- end = s; Err bitreich.org 70
i+ sep = s; Err bitreich.org 70
i Err bitreich.org 70
i p->base64 = 0; Err bitreich.org 70
i while (*s == ';') { Err bitreich.org 70
i@@ -120,20 +230,20 @@ ical_parse_contentline(IcalParser *p, char *line) Err bitreich.org 70
i return ical_error(p, "expected ':' delimiter"); Err bitreich.org 70
i s++; Err bitreich.org 70
i Err bitreich.org 70
i- *end = '\0'; Err bitreich.org 70
i+ *sep = '\0'; Err bitreich.org 70
i if (strcasecmp(name, "BEGIN") == 0) { Err bitreich.org 70
i- if ((err = CALL(p, fn_block_begin, s)) != 0) Err bitreich.org 70
i+ if ((err = hook_block_begin(p, s)) != 0 || Err bitreich.org 70
i+ (err = CALL(p, fn_block_begin, s)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i- p->level++; Err bitreich.org 70
i } else if (strcasecmp(name, "END") == 0) { Err bitreich.org 70
i- if ((err = CALL(p, fn_block_end, s)) != 0) Err bitreich.org 70
i+ if ((err = hook_block_end(p, s)) != 0 || Err bitreich.org 70
i+ (err = CALL(p, fn_block_end, s)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i- p->level--; Err bitreich.org 70
i } else { Err bitreich.org 70
i- if ((err = CALL(p, fn_entry_value, name, s)) != 0) Err bitreich.org 70
i+ if ((err = hook_entry_value(p, name, s)) != 0 || Err bitreich.org 70
i+ (err = CALL(p, fn_entry_value, name, s)) != 0) Err bitreich.org 70
i return err; Err bitreich.org 70
i } Err bitreich.org 70
i- Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i@@ -144,6 +254,8 @@ ical_parse(IcalParser *p, FILE *fp) Err bitreich.org 70
i size_t sz = 0; Err bitreich.org 70
i int err, c; Err bitreich.org 70
i Err bitreich.org 70
i+ p->current = p->stack; Err bitreich.org 70
i+ Err bitreich.org 70
i while (!feof(fp)) { Err bitreich.org 70
i if ((contentline = realloc(contentline, 1)) == NULL) Err bitreich.org 70
i return -1; Err bitreich.org 70
i@@ -151,7 +263,7 @@ ical_parse(IcalParser *p, FILE *fp) Err bitreich.org 70
i Err bitreich.org 70
i do { Err bitreich.org 70
i do { Err bitreich.org 70
i- p->line++; Err bitreich.org 70
i+ p->linenum++; Err bitreich.org 70
i if (getline(&ln, &sz, fp) <= 0) Err bitreich.org 70
i return -1; Err bitreich.org 70
i strchomp(ln); Err bitreich.org 70
1diff --git a/ical.h b/ical.h /scm/ics2txt/file/ical.h.gph bitreich.org 70
i@@ -4,9 +4,18 @@ Err bitreich.org 70
i #include <stdio.h> Err bitreich.org 70
i #include <time.h> Err bitreich.org 70
i Err bitreich.org 70
i+#define ICAL_STACK_SIZE 10 Err bitreich.org 70
i+ Err bitreich.org 70
i typedef struct IcalParser IcalParser; Err bitreich.org 70
i+typedef struct IcalStack IcalStack; Err bitreich.org 70
i+ Err bitreich.org 70
i+struct IcalStack { Err bitreich.org 70
i+ char name[32]; Err bitreich.org 70
i+ char tzid[32]; Err bitreich.org 70
i+}; Err bitreich.org 70
i+ Err bitreich.org 70
i struct IcalParser { Err bitreich.org 70
i- /* function called on content */ Err bitreich.org 70
i+ /* function called while parsing in this order */ Err bitreich.org 70
i int (*fn_entry_name)(IcalParser *, char *); Err bitreich.org 70
i int (*fn_param_name)(IcalParser *, char *); Err bitreich.org 70
i int (*fn_param_value)(IcalParser *, char *, char *); Err bitreich.org 70
i@@ -17,14 +26,14 @@ struct IcalParser { Err bitreich.org 70
i Err bitreich.org 70
i int base64; Err bitreich.org 70
i char const *errmsg; Err bitreich.org 70
i- size_t line; Err bitreich.org 70
i+ size_t linenum; Err bitreich.org 70
i+ char *tzid; Err bitreich.org 70
i Err bitreich.org 70
i- /* stack of blocks names: "name1\0name2\0...nameN\0\0" */ Err bitreich.org 70
i- int level; Err bitreich.org 70
i- char stack[1024]; Err bitreich.org 70
i+ IcalStack stack[ICAL_STACK_SIZE], *current; Err bitreich.org 70
i }; Err bitreich.org 70
i Err bitreich.org 70
i int ical_parse(IcalParser *, FILE *); Err bitreich.org 70
i+int ical_get_level(IcalParser *); Err bitreich.org 70
i int ical_get_time(IcalParser *, char *, time_t *); Err bitreich.org 70
i int ical_get_value(IcalParser *, char *, size_t *); Err bitreich.org 70
i int ical_error(IcalParser *, char const *); Err bitreich.org 70
1diff --git a/ics2tree.c b/ics2tree.c /scm/ics2txt/file/ics2tree.c.gph bitreich.org 70
i@@ -1,6 +1,7 @@ Err bitreich.org 70
i #include <stdio.h> Err bitreich.org 70
i #include <stdlib.h> Err bitreich.org 70
i #include <string.h> Err bitreich.org 70
i+#include <strings.h> Err bitreich.org 70
i Err bitreich.org 70
i #include "ical.h" Err bitreich.org 70
i #include "util.h" Err bitreich.org 70
i@@ -15,7 +16,7 @@ print_ruler(int level) Err bitreich.org 70
i static int Err bitreich.org 70
i fn_entry_name(IcalParser *p, char *name) Err bitreich.org 70
i { Err bitreich.org 70
i- print_ruler(p->level); Err bitreich.org 70
i+ print_ruler(ical_get_level(p)); Err bitreich.org 70
i printf("name %s\n", name); Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i@@ -23,7 +24,7 @@ fn_entry_name(IcalParser *p, char *name) Err bitreich.org 70
i static int Err bitreich.org 70
i fn_block_begin(IcalParser *p, char *name) Err bitreich.org 70
i { Err bitreich.org 70
i- print_ruler(p->level); Err bitreich.org 70
i+ print_ruler(ical_get_level(p) - 1); Err bitreich.org 70
i printf("begin %s\n", name); Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i@@ -31,7 +32,7 @@ fn_block_begin(IcalParser *p, char *name) Err bitreich.org 70
i static int Err bitreich.org 70
i fn_param_value(IcalParser *p, char *name, char *value) Err bitreich.org 70
i { Err bitreich.org 70
i- print_ruler(p->level + 1); Err bitreich.org 70
i+ print_ruler(ical_get_level(p) + 1); Err bitreich.org 70
i printf("param %s=%s\n", name, value); Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i@@ -44,8 +45,21 @@ fn_entry_value(IcalParser *p, char *name, char *value) Err bitreich.org 70
i Err bitreich.org 70
i if (ical_get_value(p, value, &len) < 0) Err bitreich.org 70
i return -1; Err bitreich.org 70
i- print_ruler(p->level + 1); Err bitreich.org 70
i- printf("value %s\n", value); Err bitreich.org 70
i+ Err bitreich.org 70
i+ print_ruler(ical_get_level(p) + 1); Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (strcasecmp(name, "DTSTART") == 0 || Err bitreich.org 70
i+ strcasecmp(name, "DTSTAMP") == 0 || Err bitreich.org 70
i+ strcasecmp(name, "DTEND") == 0) { Err bitreich.org 70
i+ time_t t; Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (ical_get_time(p, value, &t) != 0) Err bitreich.org 70
i+ warn("%s: %s", p->errmsg, value); Err bitreich.org 70
i+ printf("epoch %ld\n", t); Err bitreich.org 70
i+ } else { Err bitreich.org 70
i+ printf("value %s\n", value); Err bitreich.org 70
i+ } Err bitreich.org 70
i+ Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i@@ -62,7 +76,7 @@ main(int argc, char **argv) Err bitreich.org 70
i Err bitreich.org 70
i if (*argv == NULL) { Err bitreich.org 70
i if (ical_parse(&p, stdin) < 0) Err bitreich.org 70
i- err("parsing stdin:%d: %s", p.line, p.errmsg); Err bitreich.org 70
i+ err("parsing stdin:%d: %s", p.linenum, p.errmsg); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i for (; *argv != NULL; argv++, argc--) { Err bitreich.org 70
i@@ -72,7 +86,7 @@ main(int argc, char **argv) Err bitreich.org 70
i if ((fp = fopen(*argv, "r")) == NULL) Err bitreich.org 70
i err("opening %s", *argv); Err bitreich.org 70
i if (ical_parse(&p, fp) < 0) Err bitreich.org 70
i- err("parsing %s:%d: %s", *argv, p.line, p.errmsg); Err bitreich.org 70
i+ err("parsing %s:%d: %s", *argv, p.linenum, p.errmsg); Err bitreich.org 70
i fclose(fp); Err bitreich.org 70
i } Err bitreich.org 70
i return 0; Err bitreich.org 70
1diff --git a/util.c b/util.c /scm/ics2txt/file/util.c.gph bitreich.org 70
i@@ -5,20 +5,18 @@ Err bitreich.org 70
i #include <stdlib.h> Err bitreich.org 70
i #include <string.h> Err bitreich.org 70
i #include <stdio.h> Err bitreich.org 70
i+#include <time.h> Err bitreich.org 70
i Err bitreich.org 70
i char *arg0; Err bitreich.org 70
i Err bitreich.org 70
i-/* logging */ Err bitreich.org 70
i+/** logging **/ Err bitreich.org 70
i Err bitreich.org 70
i static void Err bitreich.org 70
i-_log(char const *tag, char const *fmt, va_list va) Err bitreich.org 70
i+_log(char const *fmt, va_list va) Err bitreich.org 70
i { Err bitreich.org 70
i if (arg0 != NULL) Err bitreich.org 70
i fprintf(stderr, "%s: ", arg0); Err bitreich.org 70
i- fprintf(stderr, "%s: ", tag); Err bitreich.org 70
i vfprintf(stderr, fmt, va); Err bitreich.org 70
i- if (errno != 0) Err bitreich.org 70
i- fprintf(stderr, ": %s", strerror(errno)); Err bitreich.org 70
i fprintf(stderr, "\n"); Err bitreich.org 70
i fflush(stderr); Err bitreich.org 70
i } Err bitreich.org 70
i@@ -29,7 +27,7 @@ err(char const *fmt, ...) Err bitreich.org 70
i va_list va; Err bitreich.org 70
i Err bitreich.org 70
i va_start(va, fmt); Err bitreich.org 70
i- _log("error", fmt, va); Err bitreich.org 70
i+ _log( fmt, va); Err bitreich.org 70
i exit(1); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i@@ -39,7 +37,7 @@ warn(char const *fmt, ...) Err bitreich.org 70
i va_list va; Err bitreich.org 70
i Err bitreich.org 70
i va_start(va, fmt); Err bitreich.org 70
i- _log("warning", fmt, va); Err bitreich.org 70
i+ _log(fmt, va); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i void Err bitreich.org 70
i@@ -53,23 +51,34 @@ debug(char const *fmt, ...) Err bitreich.org 70
i if (!verbose) Err bitreich.org 70
i return; Err bitreich.org 70
i va_start(va, fmt); Err bitreich.org 70
i- _log("debug", fmt, va); Err bitreich.org 70
i+ _log(fmt, va); Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i-/* strings */ Err bitreich.org 70
i+/** strings **/ Err bitreich.org 70
i Err bitreich.org 70
i size_t Err bitreich.org 70
i-strlcpy(char *buf, char const *str, size_t sz) Err bitreich.org 70
i+strlcpy(char *d, char const *s, size_t sz) Err bitreich.org 70
i { Err bitreich.org 70
i size_t len, cpy; Err bitreich.org 70
i Err bitreich.org 70
i- len = strlen(str); Err bitreich.org 70
i+ len = strlen(s); Err bitreich.org 70
i cpy = (len > sz) ? (sz) : (len); Err bitreich.org 70
i- memcpy(buf, str, cpy + 1); Err bitreich.org 70
i- buf[sz - 1] = '\0'; Err bitreich.org 70
i+ memcpy(d, s, cpy + 1); Err bitreich.org 70
i+ d[sz - 1] = '\0'; Err bitreich.org 70
i return len; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i+size_t Err bitreich.org 70
i+strlcat(char *d, char const *s, size_t dsz) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ size_t dlen; Err bitreich.org 70
i+ Err bitreich.org 70
i+ dlen = strlen(d); Err bitreich.org 70
i+ if (dlen >= dsz) Err bitreich.org 70
i+ return dlen + strlen(s); Err bitreich.org 70
i+ return dlen + strlcpy(d + dlen, s, dsz - dlen); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i char * Err bitreich.org 70
i strsep(char **sp, char const *sep) Err bitreich.org 70
i { Err bitreich.org 70
i@@ -102,28 +111,52 @@ strchomp(char *line) Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i int Err bitreich.org 70
i-strappend(char **dstp, char const *src) Err bitreich.org 70
i+strappend(char **dp, char const *s) Err bitreich.org 70
i { Err bitreich.org 70
i- size_t dstlen, srclen; Err bitreich.org 70
i+ size_t dlen, slen; Err bitreich.org 70
i void *mem; Err bitreich.org 70
i Err bitreich.org 70
i- dstlen = (*dstp == NULL) ? 0 : strlen(*dstp); Err bitreich.org 70
i- srclen = strlen(src); Err bitreich.org 70
i+ dlen = (*dp == NULL) ? 0 : strlen(*dp); Err bitreich.org 70
i+ slen = strlen(s); Err bitreich.org 70
i Err bitreich.org 70
i- if ((mem = realloc(*dstp, dstlen + srclen + 1)) == NULL) Err bitreich.org 70
i+ if ((mem = realloc(*dp, dlen + slen + 1)) == NULL) Err bitreich.org 70
i return -1; Err bitreich.org 70
i- *dstp = mem; Err bitreich.org 70
i+ *dp = mem; Err bitreich.org 70
i Err bitreich.org 70
i- memcpy(*dstp + dstlen, src, srclen + 1); Err bitreich.org 70
i+ memcpy(*dp + dlen, s, slen + 1); Err bitreich.org 70
i return 0; Err bitreich.org 70
i } Err bitreich.org 70
i Err bitreich.org 70
i-/* memory */ Err bitreich.org 70
i+/** memory **/ Err bitreich.org 70
i Err bitreich.org 70
i void * Err bitreich.org 70
i-reallocarray(void *buf, size_t len, size_t sz) Err bitreich.org 70
i+reallocarray(void *mem, size_t n, size_t sz) Err bitreich.org 70
i { Err bitreich.org 70
i- if (SIZE_MAX / len < sz) Err bitreich.org 70
i+ if (SIZE_MAX / n < sz) Err bitreich.org 70
i return errno=ERANGE, NULL; Err bitreich.org 70
i- return realloc(buf, len * sz); Err bitreich.org 70
i+ return realloc(mem, n * sz); Err bitreich.org 70
i+} Err bitreich.org 70
i+ Err bitreich.org 70
i+/** time **/ Err bitreich.org 70
i+ Err bitreich.org 70
i+time_t Err bitreich.org 70
i+tztime(struct tm *tm, char const *tz) Err bitreich.org 70
i+{ Err bitreich.org 70
i+ char *env, old[32]; Err bitreich.org 70
i+ time_t t; Err bitreich.org 70
i+ Err bitreich.org 70
i+ env = getenv("TZ"); Err bitreich.org 70
i+ if (strlcpy(old, env ? env : "", sizeof old) >= sizeof old) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ if (setenv("TZ", tz, 1) < 0) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ Err bitreich.org 70
i+ tzset(); Err bitreich.org 70
i+ t = mktime(tm); Err bitreich.org 70
i+ Err bitreich.org 70
i+ if (env == NULL) Err bitreich.org 70
i+ unsetenv("TZ"); Err bitreich.org 70
i+ else if (setenv("TZ", old, 1) < 0) Err bitreich.org 70
i+ return -1; Err bitreich.org 70
i+ return t; Err bitreich.org 70
i } Err bitreich.org 70
1diff --git a/util.h b/util.h /scm/ics2txt/file/util.h.gph bitreich.org 70
i@@ -3,20 +3,25 @@ Err bitreich.org 70
i Err bitreich.org 70
i #include <stddef.h> Err bitreich.org 70
i #include <stdarg.h> Err bitreich.org 70
i+#include <time.h> Err bitreich.org 70
i Err bitreich.org 70
i-/* logging */ Err bitreich.org 70
i+/** logging **/ Err bitreich.org 70
i extern char *arg0; Err bitreich.org 70
i void err(char const *fmt, ...); Err bitreich.org 70
i void warn(char const *fmt, ...); Err bitreich.org 70
i void debug(char const *fmt, ...); Err bitreich.org 70
i Err bitreich.org 70
i-/* strings */ Err bitreich.org 70
i-size_t strlcpy(char *buf, char const *str, size_t sz); Err bitreich.org 70
i-char *strsep(char **str_p, char const *sep); Err bitreich.org 70
i-void strchomp(char *line); Err bitreich.org 70
i-int strappend(char **base_p, char const *s); Err bitreich.org 70
i+/** strings **/ Err bitreich.org 70
i+size_t strlcpy(char *, char const *, size_t); Err bitreich.org 70
i+char *strsep(char **, char const *); Err bitreich.org 70
i+void strchomp(char *); Err bitreich.org 70
i+int strappend(char **, char const *); Err bitreich.org 70
i+size_t strlcat(char *, char const *, size_t); Err bitreich.org 70
i Err bitreich.org 70
i-/* memory */ Err bitreich.org 70
i-void *reallocarray(void *buf, size_t len, size_t sz); Err bitreich.org 70
i+/** memory **/ Err bitreich.org 70
i+void *reallocarray(void *, size_t, size_t); Err bitreich.org 70
i+ Err bitreich.org 70
i+/** time **/ Err bitreich.org 70
i+time_t tztime(struct tm *, char const *); Err bitreich.org 70
i Err bitreich.org 70
i #endif Err bitreich.org 70
.
Response:
text/plain