SMOLNET PORTAL home about changes
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
Original URLgopher://bitreich.org/0/scm/ics2txt/commit/58a1a9df90b575...
Content-Typetext/plain; charset=utf-8