iadd initial parsing functions - 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 8248ba97aa609be30e0ecf481d93e59a9876afcd /scm/ics2txt/commit/8248ba97aa609be30e0ecf481d93e59a9876afcd.gph bitreich.org 70 1parent a7b4ceeaf4a57476c0952e0da2def5f92bdfdb9f /scm/ics2txt/commit/a7b4ceeaf4a57476c0952e0da2def5f92bdfdb9f.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:me@josuah.net bitreich.org 70 iDate: Sun, 28 Jun 2020 14:33:48 +0200 Err bitreich.org 70 i Err bitreich.org 70 iadd initial parsing functions Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M ics2tsv.c | 7 ++++--- Err bitreich.org 70 i M src/ical.c | 93 +++++++++++++++++++++++++++---- Err bitreich.org 70 i M src/ical.h | 40 ++++++++++++++++++++++++++++---- Err bitreich.org 70 i M src/map.c | 3 --- Err bitreich.org 70 i Err bitreich.org 70 i4 files changed, 122 insertions(+), 21 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/ics2tsv.c b/ics2tsv.c /scm/ics2txt/file/ics2tsv.c.gph bitreich.org 70 i@@ -1,5 +1,6 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #include "ical.h" Err bitreich.org 70 i #include "log.h" Err bitreich.org 70 i@@ -8,16 +9,16 @@ Err bitreich.org 70 i int Err bitreich.org 70 i print_ical_to_tsv(FILE *fp) Err bitreich.org 70 i { Err bitreich.org 70 i- struct ical_contentline contentline; Err bitreich.org 70 i+ struct ical_contentline cl; Err bitreich.org 70 i char *line = NULL, *ln = NULL; Err bitreich.org 70 i size_t sz = 0; Err bitreich.org 70 i ssize_t r; Err bitreich.org 70 i Err bitreich.org 70 i- ical_init_contentline(&contentline); Err bitreich.org 70 i+ memset(&cl, 0, sizeof cl); Err bitreich.org 70 i Err bitreich.org 70 i while ((r = ical_read_line(&line, &ln, &sz, fp)) > 0) { Err bitreich.org 70 i debug("readling line \"%s\"", line); Err bitreich.org 70 i- if (ical_parse_contentline(&contentline, line) < 0) Err bitreich.org 70 i+ if (ical_parse_contentline(&cl, line) < 0) Err bitreich.org 70 i die("parsing line \"%s\"", line); Err bitreich.org 70 i } Err bitreich.org 70 i free(line); Err bitreich.org 70 1diff --git a/src/ical.c b/src/ical.c /scm/ics2txt/file/src/ical.c.gph bitreich.org 70 i@@ -1,9 +1,11 @@ Err bitreich.org 70 i #include "ical.h" Err bitreich.org 70 i Err bitreich.org 70 i+#include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i+#include /* strcase* */ Err bitreich.org 70 i Err bitreich.org 70 i #include "util.h" Err bitreich.org 70 i Err bitreich.org 70 i@@ -29,19 +31,21 @@ ical_read_line(char **line, char **ln, size_t *sz, FILE *fp) Err bitreich.org 70 i } while (c == ' '); Err bitreich.org 70 i Err bitreich.org 70 i ungetc(c, fp); Err bitreich.org 70 i+ assert(!ferror(fp)); Err bitreich.org 70 i return 1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-ical_parse_contentline(struct ical_contentline *contentline, char *line) Err bitreich.org 70 i+ical_parse_contentline(struct ical_contentline *cl, char *line) Err bitreich.org 70 i { Err bitreich.org 70 i char *column, *equal, *param, *cp; Err bitreich.org 70 i size_t sz; Err bitreich.org 70 i+ int e = errno; Err bitreich.org 70 i Err bitreich.org 70 i if ((column = strchr(line, ':')) == NULL) Err bitreich.org 70 i return -1; Err bitreich.org 70 i *column = '\0'; Err bitreich.org 70 i- if ((contentline->value = strdup(column + 1)) == NULL) Err bitreich.org 70 i+ if ((cl->value = strdup(column + 1)) == NULL) Err bitreich.org 70 i return -1; Err bitreich.org 70 i Err bitreich.org 70 i if ((cp = strchr(line, ';')) != NULL) Err bitreich.org 70 i@@ -50,27 +54,94 @@ ical_parse_contentline(struct ical_contentline *contentline, char *line) Err bitreich.org 70 i if ((equal = strchr(param, '=')) == NULL) Err bitreich.org 70 i return -1; Err bitreich.org 70 i *equal = '\0'; Err bitreich.org 70 i- if (map_set(&contentline->param, param, equal + 1) < 0) Err bitreich.org 70 i+ if (map_set(&cl->param, param, equal + 1) < 0) Err bitreich.org 70 i return -1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- sz = sizeof(contentline->name); Err bitreich.org 70 i- if (strlcpy(contentline->name, line, sz) >= sz) Err bitreich.org 70 i+ sz = sizeof cl->name; Err bitreich.org 70 i+ if (strlcpy(cl->name, line, sz) >= sz) Err bitreich.org 70 i return errno=EMSGSIZE, -1; Err bitreich.org 70 i Err bitreich.org 70 i+ assert(errno == e); Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-ical_init_contentline(struct ical_contentline *contentline) Err bitreich.org 70 i+int Err bitreich.org 70 i+ical_parse_tzid(struct ical_value *value, struct ical_contentline *cl) 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+ical_parse_date(struct ical_value *value, struct ical_contentline *cl) 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+ical_parse_attribute(struct ical_value *value, struct ical_contentline *cl) 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+ical_begin_vnode(struct ical_vcalendar *vcal, char const *name) Err bitreich.org 70 i { Err bitreich.org 70 i- memset(contentline, 0, sizeof(*contentline)); Err bitreich.org 70 i+ if (strcasecmp(name, "VCALENDAR")) Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+int Err bitreich.org 70 i+ical_end_vnode(struct ical_vcalendar *vcal, char const *name) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ if (strcasecmp(name, "VCALENDAR")) Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+ical_add_contentline(struct ical_vcalendar *vcal, struct ical_contentline *cl) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct ical_value value_buf, *value = &value_buf; Err bitreich.org 70 i+ int i; Err bitreich.org 70 i+ struct { Err bitreich.org 70 i+ char *name; Err bitreich.org 70 i+ enum ical_value_type type; Err bitreich.org 70 i+ int (*fn)(struct ical_value *, struct ical_contentline *); Err bitreich.org 70 i+ } map[] = { Err bitreich.org 70 i+ { "DTSTART", ICAL_VALUE_TIME, ical_parse_date }, Err bitreich.org 70 i+ { "DTEND", ICAL_VALUE_TIME, ical_parse_date }, Err bitreich.org 70 i+ { "TZID", ICAL_VALUE_TIME, ical_parse_tzid }, Err bitreich.org 70 i+ { NULL, ICAL_VALUE_ATTRIBUTE, ical_parse_attribute }, Err bitreich.org 70 i+ }; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (strcasecmp(cl->name, "BEGIN") == 0) Err bitreich.org 70 i+ return ical_begin_vnode(vcal, cl->value); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (strcasecmp(cl->name, "END") == 0) Err bitreich.org 70 i+ return ical_end_vnode(vcal, cl->value); Err bitreich.org 70 i+ Err bitreich.org 70 i+ memset(value, 0, sizeof *value); Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = 0; map[i].name == NULL; i++) Err bitreich.org 70 i+ if (strcasecmp(cl->name, map[i].name) == 0) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ value->type = map[i].type; Err bitreich.org 70 i+ if (map[i].fn(value, cl) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ return 0; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+ical_free_value(struct ical_value *value) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ ; Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-ical_free_contentline(struct ical_contentline *contentline) Err bitreich.org 70 i+ical_free_contentline(struct ical_contentline *cl) Err bitreich.org 70 i { Err bitreich.org 70 i- map_free(&contentline->param); Err bitreich.org 70 i- free(contentline->value); Err bitreich.org 70 i+ map_free(&cl->param); Err bitreich.org 70 i+ free(cl->value); Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/src/ical.h b/src/ical.h /scm/ics2txt/file/src/ical.h.gph bitreich.org 70 i@@ -6,16 +6,48 @@ Err bitreich.org 70 i Err bitreich.org 70 i #include "map.h" Err bitreich.org 70 i Err bitreich.org 70 i-struct ical_vevent { Err bitreich.org 70 i- time_t beg, end; Err bitreich.org 70 i- struct map map; Err bitreich.org 70 i-}; Err bitreich.org 70 i+#define ICAL_NEST_MAX 4 Err bitreich.org 70 i+ Err bitreich.org 70 i+/* */ Err bitreich.org 70 i Err bitreich.org 70 i struct ical_contentline { Err bitreich.org 70 i char name[32], *value; Err bitreich.org 70 i struct map param; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i+/* single value for an iCalendar element attribute */ Err bitreich.org 70 i+ Err bitreich.org 70 i+enum ical_value_type { Err bitreich.org 70 i+ ICAL_VALUE_TIME, ICAL_VALUE_ATTRIBUTE, Err bitreich.org 70 i+} type; Err bitreich.org 70 i+ Err bitreich.org 70 i+union ical_value_union { Err bitreich.org 70 i+ time_t *time; Err bitreich.org 70 i+ char *str; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+struct ical_value { Err bitreich.org 70 i+ enum ical_value_type type; Err bitreich.org 70 i+ union ical_value_union value; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+/* global propoerties for an iCalendar document as well as parsing state */ Err bitreich.org 70 i+ Err bitreich.org 70 i+struct ical_vcalendar { Err bitreich.org 70 i+ time_t tzid; Err bitreich.org 70 i+ char *stack[ICAL_NEST_MAX + 1]; Err bitreich.org 70 i+ struct ical_vnode *current; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+/* element part of an iCalendar document with eventual nested childs */ Err bitreich.org 70 i+ Err bitreich.org 70 i+struct ical_vnode { Err bitreich.org 70 i+ char name[32]; Err bitreich.org 70 i+ time_t beg, end; Err bitreich.org 70 i+ struct map properties; /* struct ical_value */ Err bitreich.org 70 i+ struct ical_vnode *child, *next; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i /** src/ical.c **/ Err bitreich.org 70 i int ical_read_line(char **line, char **ln, size_t *sz, FILE *fp); Err bitreich.org 70 i int ical_parse_contentline(struct ical_contentline *contentline, char *line); Err bitreich.org 70 1diff --git a/src/map.c b/src/map.c /scm/ics2txt/file/src/map.c.gph bitreich.org 70 i@@ -32,11 +32,8 @@ map_set(struct map *map, char *key, void *value) Err bitreich.org 70 i size_t i, sz; Err bitreich.org 70 i void *v; Err bitreich.org 70 i Err bitreich.org 70 i- debug("%s: key=%s len=%zd", __func__, key, map->len); Err bitreich.org 70 i- Err bitreich.org 70 i for (i = 0; i < map->len; i++) { Err bitreich.org 70 i int cmp = strcmp(key, map->entry[i].key); Err bitreich.org 70 i- debug("cmp(%s,%s)=%d", key, map->entry[i].key, cmp); Err bitreich.org 70 i Err bitreich.org 70 i if (cmp == 0) { Err bitreich.org 70 i map->entry[i].value = value; Err bitreich.org 70 .