irefactor the code to avoid copying the whole ical file to memory - 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 917f5b056d0b1241f0816bfd41276a36b5727fb1 /scm/ics2txt/commit/917f5b056d0b1241f0816bfd41276a36b5727fb1.gph bitreich.org 70 1parent b81a0df00fa8f12b03fa371762b6bd4ee3db8422 /scm/ics2txt/commit/b81a0df00fa8f12b03fa371762b6bd4ee3db8422.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:me@josuah.net bitreich.org 70 iDate: Sat, 12 Jun 2021 22:50:29 +0200 Err bitreich.org 70 i Err bitreich.org 70 irefactor the code to avoid copying the whole ical file to memory Err bitreich.org 70 i Err bitreich.org 70 iThis is how Evil_Bob does it with xml.c, a sane and tiny XML parser. Err bitreich.org 70 i Err bitreich.org 70 iThe document structure gets parsed, and a struct parser passed to the Err bitreich.org 70 iparser contains function pointers. As parsed objects get encountered, Err bitreich.org 70 ithe matching function pointers gets called with the parsed text as Err bitreich.org 70 iparameter. Then the content can be processed as it is read, instead of Err bitreich.org 70 iparsed first and processed after. Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 4 ++-- Err bitreich.org 70 i M ical.c | 351 ++++++++++--------------------- Err bitreich.org 70 i M ical.h | 79 ++++++++----------------------- Err bitreich.org 70 i M ics2tree.c | 81 +++++++++++++------------------ Err bitreich.org 70 i D log.c | 89 ------------------------------- Err bitreich.org 70 i D log.h | 15 --------------- Err bitreich.org 70 i D map.c | 106 ------------------------------ Err bitreich.org 70 i D map.h | 24 ------------------------ Err bitreich.org 70 i M util.c | 88 +++++++++++++++++++++++++------ Err bitreich.org 70 i M util.h | 21 +++++++++++++++------ Err bitreich.org 70 i Err bitreich.org 70 i10 files changed, 253 insertions(+), 605 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/ics2txt/file/Makefile.gph bitreich.org 70 i@@ -7,8 +7,8 @@ CFLAGS = $D $W -g Err bitreich.org 70 i PREFIX = /usr/local Err bitreich.org 70 i MANPREFIX = ${PREFIX}/man Err bitreich.org 70 i Err bitreich.org 70 i-SRC = ical.c map.c util.c log.c Err bitreich.org 70 i-HDR = ical.h map.h util.h log.h Err bitreich.org 70 i+SRC = ical.c util.c Err bitreich.org 70 i+HDR = ical.h util.h Err bitreich.org 70 i OBJ = ${SRC:.c=.o} Err bitreich.org 70 i BIN = ics2tree Err bitreich.org 70 i MAN1 = ics2txt.1 Err bitreich.org 70 1diff --git a/ical.c b/ical.c /scm/ics2txt/file/ical.c.gph bitreich.org 70 i@@ -1,288 +1,157 @@ 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 Err bitreich.org 70 i-#include /* strcase* */ Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i #include "util.h" Err bitreich.org 70 i Err bitreich.org 70 i-enum ical_err ical_errno; Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-ical_getline(char **line, char **ln, size_t *sz, FILE *fp) Err bitreich.org 70 i+static int Err bitreich.org 70 i+ical_error(IcalParser *p, char const *msg) Err bitreich.org 70 i { Err bitreich.org 70 i- int c; Err bitreich.org 70 i- void *v; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((v = realloc(*line, 1)) == NULL) Err bitreich.org 70 i- return -ICAL_ERR_SYSTEM; Err bitreich.org 70 i- *line = v; Err bitreich.org 70 i- (*line)[0] = '\0'; Err bitreich.org 70 i- Err bitreich.org 70 i- do { top: Err bitreich.org 70 i- if (getline(ln, sz, fp) <= 0) Err bitreich.org 70 i- return ferror(fp) ? -ICAL_ERR_SYSTEM : 0; Err bitreich.org 70 i- strchomp(*ln); Err bitreich.org 70 i- if (**ln == '\0') Err bitreich.org 70 i- goto top; Err bitreich.org 70 i- if (strappend(line, *ln) < 0) Err bitreich.org 70 i- return -ICAL_ERR_SYSTEM; Err bitreich.org 70 i- if ((c = fgetc(fp)) == EOF) Err bitreich.org 70 i- return ferror(fp) ? -ICAL_ERR_SYSTEM : 1; 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+ p->errmsg = msg; Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-char * Err bitreich.org 70 i-ical_strerror(int i) Err bitreich.org 70 i-{ Err bitreich.org 70 i- enum ical_err err = (i > 0) ? i : -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- switch (err) { Err bitreich.org 70 i- case ICAL_ERR_OK: Err bitreich.org 70 i- return "no error"; Err bitreich.org 70 i- case ICAL_ERR_SYSTEM: Err bitreich.org 70 i- return "system error"; Err bitreich.org 70 i- case ICAL_ERR_END_MISMATCH: Err bitreich.org 70 i- return "END: does not match its corresponding BEGIN:"; Err bitreich.org 70 i- case ICAL_ERR_MISSING_BEGIN: Err bitreich.org 70 i- return "unexpected content line before any BEGIN:"; Err bitreich.org 70 i- case ICAL_ERR_MISSING_COLUMN: Err bitreich.org 70 i- return "missing ':' character from line"; Err bitreich.org 70 i- case ICAL_ERR_MISSING_SEMICOLUMN: Err bitreich.org 70 i- return "missing ';' character before ':'"; Err bitreich.org 70 i- case ICAL_ERR_MISSING_EQUAL: Err bitreich.org 70 i- return "missing '=' character in parameter before ':'"; Err bitreich.org 70 i- case ICAL_ERR_MIN_NESTED: Err bitreich.org 70 i- return "too many END: for the number of BEGIN:"; Err bitreich.org 70 i- case ICAL_ERR_MAX_NESTED: Err bitreich.org 70 i- return "maximum nesting level reached"; Err bitreich.org 70 i- case ICAL_ERR_LENGTH: Err bitreich.org 70 i- assert(!"used internally, should not happen"); Err bitreich.org 70 i- } Err bitreich.org 70 i- assert(!"unknown error code"); Err bitreich.org 70 i- return "not a valid ical error code"; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-struct ical_value * Err bitreich.org 70 i-ical_new_value(char const *line) Err bitreich.org 70 i+static int Err bitreich.org 70 i+ical_parse_value(IcalParser *p, char **sp, char *name) Err bitreich.org 70 i { Err bitreich.org 70 i- struct ical_value *new; Err bitreich.org 70 i- size_t len; Err bitreich.org 70 i+ int err; Err bitreich.org 70 i+ char *s, c, *val; Err bitreich.org 70 i Err bitreich.org 70 i- len = strlen(line); Err bitreich.org 70 i- if ((new = calloc(1, sizeof *new + len + 1)) == NULL) Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i- memcpy(new->buf, line, len + 1); Err bitreich.org 70 i- return new; Err bitreich.org 70 i-} Err bitreich.org 70 i+ s = *sp; 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- map_free(&value->param, NULL); Err bitreich.org 70 i- free(value); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-ical_parse_value(struct ical_value *value) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *column, *equal, *param, *cp; Err bitreich.org 70 i- int e = errno; Err bitreich.org 70 i- Err bitreich.org 70 i- value->name = value->buf; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((column = strchr(value->buf, ':')) == NULL) Err bitreich.org 70 i- return -ICAL_ERR_MISSING_COLUMN; Err bitreich.org 70 i- *column = '\0'; Err bitreich.org 70 i- value->value = column + 1; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((cp = strchr(value->buf, ';')) != NULL) Err bitreich.org 70 i- *cp++ = '\0'; Err bitreich.org 70 i- while ((param = strsep(&cp, ";")) != NULL) { Err bitreich.org 70 i- if ((equal = strchr(param, '=')) == NULL) Err bitreich.org 70 i- return -ICAL_ERR_MISSING_EQUAL; Err bitreich.org 70 i- *equal = '\0'; Err bitreich.org 70 i- if (map_set(&value->param, param, equal + 1) < 0) Err bitreich.org 70 i- return -ICAL_ERR_SYSTEM; 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+ 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 } 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-struct ical_vnode * Err bitreich.org 70 i-ical_new_vnode(char const *name) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct ical_vnode *new; Err bitreich.org 70 i- size_t sz; 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+ return err; Err bitreich.org 70 i+ *s = c; Err bitreich.org 70 i Err bitreich.org 70 i- if ((new = calloc(1, sizeof *new)) == NULL) Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i- sz = sizeof new->name; Err bitreich.org 70 i- if (strlcpy(new->name, name, sz) >= sz) { Err bitreich.org 70 i- errno = EMSGSIZE; Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- } Err bitreich.org 70 i- return new; Err bitreich.org 70 i-err: Err bitreich.org 70 i- ical_free_vnode(new); Err bitreich.org 70 i- return NULL; 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 void Err bitreich.org 70 i-ical_free_value_void(void *v) Err bitreich.org 70 i+static int Err bitreich.org 70 i+ical_parse_param(IcalParser *p, char **sp) Err bitreich.org 70 i { Err bitreich.org 70 i- ical_free_value(v); Err bitreich.org 70 i-} Err bitreich.org 70 i+ int err; Err bitreich.org 70 i+ char *s, *name; Err bitreich.org 70 i Err bitreich.org 70 i-static void Err bitreich.org 70 i-ical_free_vnode_void(void *v) Err bitreich.org 70 i-{ Err bitreich.org 70 i- ical_free_vnode(v); Err bitreich.org 70 i-} Err bitreich.org 70 i+ s = *sp; Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-ical_free_vnode(struct ical_vnode *node) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (node == NULL) Err bitreich.org 70 i- return; Err bitreich.org 70 i- map_free(&node->values, ical_free_value_void); Err bitreich.org 70 i- map_free(&node->childs, ical_free_vnode_void); Err bitreich.org 70 i- ical_free_vnode(node->next); Err bitreich.org 70 i- free(node); 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+ return err; Err bitreich.org 70 i Err bitreich.org 70 i-int Err bitreich.org 70 i-ical_push_nested(struct ical_vcalendar *vcal, struct ical_vnode *new) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct ical_vnode **node; 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- node = vcal->nested; Err bitreich.org 70 i- for (int i = 0; *node != NULL; node++, i++) { Err bitreich.org 70 i- if (i >= ICAL_NESTED_MAX) Err bitreich.org 70 i- return -ICAL_ERR_MAX_NESTED; Err bitreich.org 70 i- } Err bitreich.org 70 i- node[0] = new; Err bitreich.org 70 i- node[1] = NULL; 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-struct ical_vnode * Err bitreich.org 70 i-ical_pop_nested(struct ical_vcalendar *vcal) Err bitreich.org 70 i+static int Err bitreich.org 70 i+ical_parse_contentline(IcalParser *p, char *line) Err bitreich.org 70 i { Err bitreich.org 70 i- struct ical_vnode **node, **prev = vcal->nested, *old; 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- for (prev = node = vcal->nested; *node != NULL; node++) { Err bitreich.org 70 i- vcal->current = *prev; Err bitreich.org 70 i- prev = node; Err bitreich.org 70 i- old = *node; Err bitreich.org 70 i- } Err bitreich.org 70 i- *prev = NULL; Err bitreich.org 70 i- if (vcal->nested[0] == NULL) Err bitreich.org 70 i- vcal->current = NULL; Err bitreich.org 70 i- return old; Err bitreich.org 70 i-} Err bitreich.org 70 i+ s = line; 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- struct ical_vnode *new; Err bitreich.org 70 i- int e; 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+ return err; Err bitreich.org 70 i+ *s = c; Err bitreich.org 70 i+ end = s; Err bitreich.org 70 i Err bitreich.org 70 i- if ((new = ical_new_vnode(name)) == NULL) Err bitreich.org 70 i- return -ICAL_ERR_SYSTEM; Err bitreich.org 70 i- if ((e = ical_push_nested(vcal, new)) < 0) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- if (vcal->root == NULL) { Err bitreich.org 70 i- vcal->root = new; Err bitreich.org 70 i- } else { Err bitreich.org 70 i- new->next = map_get(&vcal->current->childs, new->name); Err bitreich.org 70 i- if (map_set(&vcal->current->childs, new->name, new) < 0) { Err bitreich.org 70 i- e = -ICAL_ERR_SYSTEM; Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- } Err bitreich.org 70 i+ while (*s == ';') { Err bitreich.org 70 i+ s++; Err bitreich.org 70 i+ if ((err = ical_parse_param(p, &s)) != 0) Err bitreich.org 70 i+ return err; Err bitreich.org 70 i } Err bitreich.org 70 i- vcal->current = new; Err bitreich.org 70 i- return 0; Err bitreich.org 70 i-err: Err bitreich.org 70 i- ical_free_vnode(new); Err bitreich.org 70 i- return e; 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- struct ical_vnode *old; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((old = ical_pop_nested(vcal)) == NULL) Err bitreich.org 70 i- return -ICAL_ERR_MIN_NESTED; Err bitreich.org 70 i- if (strcasecmp(name, old->name) != 0) Err bitreich.org 70 i- return -ICAL_ERR_END_MISMATCH; 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_push_value(struct ical_vcalendar *vcal, struct ical_value *new) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (strcasecmp(new->name, "BEGIN") == 0) { Err bitreich.org 70 i- int e = ical_begin_vnode(vcal, new->value); Err bitreich.org 70 i- ical_free_value(new); Err bitreich.org 70 i- return e; Err bitreich.org 70 i- } Err bitreich.org 70 i- if (strcasecmp(new->name, "END") == 0) { Err bitreich.org 70 i- int e = ical_end_vnode(vcal, new->value); Err bitreich.org 70 i- ical_free_value(new); Err bitreich.org 70 i- return e; Err bitreich.org 70 i+ if (*s != ':') 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+ if (strcasecmp(name, "BEGIN") == 0) { Err bitreich.org 70 i+ if ((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+ 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+ return err; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- if (vcal->current == NULL) Err bitreich.org 70 i- return -ICAL_ERR_MISSING_BEGIN; Err bitreich.org 70 i- Err bitreich.org 70 i- new->next = map_get(&vcal->current->values, new->name); Err bitreich.org 70 i- if (map_set(&vcal->current->values, new->name, new) < 0) Err bitreich.org 70 i- return -ICAL_ERR_SYSTEM; 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_read_vcalendar(struct ical_vcalendar *vcal, FILE *fp) Err bitreich.org 70 i+ical_parse(IcalParser *p, FILE *fp) Err bitreich.org 70 i { Err bitreich.org 70 i- char *line = NULL, *ln = NULL; Err bitreich.org 70 i+ char *ln = NULL, *contentline = NULL; Err bitreich.org 70 i size_t sz = 0; Err bitreich.org 70 i- ssize_t r; Err bitreich.org 70 i- int e; Err bitreich.org 70 i- Err bitreich.org 70 i- memset(vcal, 0, sizeof *vcal); Err bitreich.org 70 i- Err bitreich.org 70 i- while ((r = ical_getline(&line, &ln, &sz, fp)) > 0) { Err bitreich.org 70 i- struct ical_value *new; Err bitreich.org 70 i- Err bitreich.org 70 i- if ((new = ical_new_value(line)) == NULL) { Err bitreich.org 70 i- e = -ICAL_ERR_SYSTEM; Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- } Err bitreich.org 70 i- if ((e = ical_parse_value(new)) < 0) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i- if ((e = ical_push_value(vcal, new)) < 0) Err bitreich.org 70 i- goto err; Err bitreich.org 70 i+ int err, c; 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+ *contentline = '\0'; 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+ if (getline(&ln, &sz, fp) <= 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ strchomp(ln); Err bitreich.org 70 i+ } while (*ln == '\0'); Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (strappend(&contentline, ln) < 0) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ if ((c = fgetc(fp)) == EOF) { Err bitreich.org 70 i+ if (ferror(fp)) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ goto done; Err bitreich.org 70 i+ } Err bitreich.org 70 i+ } while (c == ' '); Err bitreich.org 70 i+ ungetc(c, fp); Err bitreich.org 70 i+done: Err bitreich.org 70 i+ assert(!ferror(fp)); Err bitreich.org 70 i+ if ((err = ical_parse_contentline(p, contentline)) != 0) Err bitreich.org 70 i+ break; Err bitreich.org 70 i } Err bitreich.org 70 i- e = (r == 0) ? 0 : -ICAL_ERR_SYSTEM; Err bitreich.org 70 i-err: Err bitreich.org 70 i- free(line); Err bitreich.org 70 i+ free(contentline); Err bitreich.org 70 i free(ln); Err bitreich.org 70 i- return e; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-ical_free_vcalendar(struct ical_vcalendar *vcal) Err bitreich.org 70 i-{ Err bitreich.org 70 i- ical_free_vnode(vcal->root); Err bitreich.org 70 i+ return err; Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/ical.h b/ical.h /scm/ics2txt/file/ical.h.gph bitreich.org 70 i@@ -4,65 +4,28 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i-#include "map.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#define ICAL_NESTED_MAX 4 Err bitreich.org 70 i- Err bitreich.org 70 i-enum ical_err { Err bitreich.org 70 i- ICAL_ERR_OK, Err bitreich.org 70 i- ICAL_ERR_SYSTEM, Err bitreich.org 70 i- ICAL_ERR_END_MISMATCH, Err bitreich.org 70 i- ICAL_ERR_MISSING_BEGIN, Err bitreich.org 70 i- ICAL_ERR_MISSING_COLUMN, Err bitreich.org 70 i- ICAL_ERR_MISSING_SEMICOLUMN, Err bitreich.org 70 i- ICAL_ERR_MISSING_EQUAL, Err bitreich.org 70 i- ICAL_ERR_MIN_NESTED, Err bitreich.org 70 i- ICAL_ERR_MAX_NESTED, Err bitreich.org 70 i- Err bitreich.org 70 i- ICAL_ERR_LENGTH, 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- struct ical_vnode *root; Err bitreich.org 70 i- struct ical_vnode *nested[ICAL_NESTED_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- struct map values; /*(struct ical_value *)*/ Err bitreich.org 70 i- struct map childs; /*(struct ical_vnode *)*/ Err bitreich.org 70 i- struct ical_vnode *next; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-/* one line whith the whole content unfolded */ Err bitreich.org 70 i- Err bitreich.org 70 i-struct ical_value { Err bitreich.org 70 i- char *name, *value; Err bitreich.org 70 i- struct map param; Err bitreich.org 70 i- struct ical_value *next; Err bitreich.org 70 i- char buf[]; Err bitreich.org 70 i+typedef struct IcalParser IcalParser; Err bitreich.org 70 i+struct IcalParser { Err bitreich.org 70 i+ /* function called on content */ 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+ int (*fn_entry_value)(IcalParser *, char *, char *); Err bitreich.org 70 i+ int (*fn_block_begin)(IcalParser *, char *); Err bitreich.org 70 i+ int (*fn_block_end)(IcalParser *, char *); Err bitreich.org 70 i+ /* if returning non-zero then halt the parser */ Err bitreich.org 70 i+ Err bitreich.org 70 i+ int base64encoded; Err bitreich.org 70 i+ char const *errmsg; Err bitreich.org 70 i+ size_t line; 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 }; Err bitreich.org 70 i Err bitreich.org 70 i-/** src/ical.c **/ Err bitreich.org 70 i-int ical_getline(char **line, char **ln, size_t *sz, FILE *fp); Err bitreich.org 70 i-char * ical_strerror(int i); Err bitreich.org 70 i-struct ical_value * ical_new_value(char const *line); Err bitreich.org 70 i-void ical_free_value(struct ical_value *value); Err bitreich.org 70 i-int ical_parse_value(struct ical_value *value); Err bitreich.org 70 i-struct ical_vnode * ical_new_vnode(char const *name); Err bitreich.org 70 i-void ical_free_vnode(struct ical_vnode *node); Err bitreich.org 70 i-int ical_push_nested(struct ical_vcalendar *vcal, struct ical_vnode *new); Err bitreich.org 70 i-struct ical_vnode * ical_pop_nested(struct ical_vcalendar *vcal); Err bitreich.org 70 i-int ical_begin_vnode(struct ical_vcalendar *vcal, char const *name); Err bitreich.org 70 i-int ical_end_vnode(struct ical_vcalendar *vcal, char const *name); Err bitreich.org 70 i-int ical_push_value(struct ical_vcalendar *vcal, struct ical_value *new); Err bitreich.org 70 i-void ical_free_vcalendar(struct ical_vcalendar *vcal); Err bitreich.org 70 i-int ical_read_vcalendar(struct ical_vcalendar *vcal, FILE *fp); Err bitreich.org 70 i+int ical_parse(IcalParser *, FILE *); Err bitreich.org 70 i+//TODO: char *ical_get_time(char *); Err bitreich.org 70 i+//TODO: char *ical_get_value(IcalCtx *, char *); Err bitreich.org 70 i Err bitreich.org 70 i #endif Err bitreich.org 70 1diff --git a/ics2tree.c b/ics2tree.c /scm/ics2txt/file/ics2tree.c.gph bitreich.org 70 i@@ -3,76 +3,63 @@ 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 #include "util.h" Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i print_ruler(int level) Err bitreich.org 70 i { Err bitreich.org 70 i- for (int i = 0; i < level; i++) Err bitreich.org 70 i+ while (level-- > 0) Err bitreich.org 70 i fprintf(stdout, ": "); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-print_ical_tree_param(struct map_entry *entry, 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- if (entry == NULL) Err bitreich.org 70 i- return; Err bitreich.org 70 i- print_ruler(level); Err bitreich.org 70 i- fprintf(stdout, "param %s=%s\n", entry->key, (char *)entry->value); Err bitreich.org 70 i+ print_ruler(p->level); 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 Err bitreich.org 70 i-void Err bitreich.org 70 i-print_ical_tree_value(struct ical_value *value, int level) 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- if (value == NULL) Err bitreich.org 70 i- return; Err bitreich.org 70 i- print_ruler(level); Err bitreich.org 70 i- fprintf(stdout, "value %s:%s\n", value->name, value->value); Err bitreich.org 70 i- for (size_t i = 0; i < value->param.len; i++) Err bitreich.org 70 i- print_ical_tree_param(value->param.entry + i, level + 1); Err bitreich.org 70 i- print_ical_tree_value(value->next, level); Err bitreich.org 70 i+ print_ruler(p->level); 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 Err bitreich.org 70 i-void Err bitreich.org 70 i-print_ical_tree_vnode(struct ical_vnode *node, int level) 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- if (node == NULL) Err bitreich.org 70 i- return; Err bitreich.org 70 i- print_ruler(level); Err bitreich.org 70 i- fprintf(stdout, "node %s\n", node->name); Err bitreich.org 70 i- for (size_t i = 0; i < node->values.len; i++) Err bitreich.org 70 i- print_ical_tree_value(node->values.entry[i].value, level + 1); Err bitreich.org 70 i- for (size_t i = 0; i < node->childs.len; i++) Err bitreich.org 70 i- print_ical_tree_vnode(node->childs.entry[i].value, level + 1); Err bitreich.org 70 i- print_ical_tree_vnode(node->next, level); Err bitreich.org 70 i+ print_ruler(p->level + 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 Err bitreich.org 70 i-int Err bitreich.org 70 i-print_ical_tree(FILE *fp) Err bitreich.org 70 i+static int Err bitreich.org 70 i+fn_entry_value(IcalParser *p, char *name, char *value) Err bitreich.org 70 i { Err bitreich.org 70 i- struct ical_vcalendar vcal; Err bitreich.org 70 i- int e; Err bitreich.org 70 i+ (void)name; Err bitreich.org 70 i Err bitreich.org 70 i- if ((e = ical_read_vcalendar(&vcal, fp)) < 0) Err bitreich.org 70 i- die("reading ical file: %s", ical_strerror(e)); Err bitreich.org 70 i- Err bitreich.org 70 i- print_ical_tree_vnode(vcal.root, 0); Err bitreich.org 70 i- fprintf(stdout, "end\n"); Err bitreich.org 70 i- fflush(stdout); Err bitreich.org 70 i- Err bitreich.org 70 i- ical_free_vcalendar(&vcal); 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 return 0; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i main(int argc, char **argv) Err bitreich.org 70 i { Err bitreich.org 70 i- log_arg0 = *argv++; Err bitreich.org 70 i+ IcalParser p = {0}; Err bitreich.org 70 i+ arg0 = *argv++; Err bitreich.org 70 i+ Err bitreich.org 70 i+ p.fn_entry_name = fn_entry_name; Err bitreich.org 70 i+ p.fn_block_begin = fn_block_begin; Err bitreich.org 70 i+ p.fn_param_value = fn_param_value; Err bitreich.org 70 i+ p.fn_entry_value = fn_entry_value; Err bitreich.org 70 i Err bitreich.org 70 i if (*argv == NULL) { Err bitreich.org 70 i- if (print_ical_tree(stdin) < 0) Err bitreich.org 70 i- die("converting stdin"); 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 bitreich.org 70 i Err bitreich.org 70 i for (; *argv != NULL; argv++, argc--) { Err bitreich.org 70 i@@ -80,9 +67,9 @@ main(int argc, char **argv) Err bitreich.org 70 i Err bitreich.org 70 i debug("converting \"%s\"", *argv); Err bitreich.org 70 i if ((fp = fopen(*argv, "r")) == NULL) Err bitreich.org 70 i- die("opening %s", *argv); Err bitreich.org 70 i- if (print_ical_tree(fp) < 0) Err bitreich.org 70 i- die("converting %s", *argv); 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 fclose(fp); Err bitreich.org 70 i } Err bitreich.org 70 i return 0; Err bitreich.org 70 1diff --git a/log.c b/log.c /scm/ics2txt/file/log.c.gph bitreich.org 70 i@@ -1,89 +0,0 @@ Err bitreich.org 70 i-#include "log.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-/* Err bitreich.org 70 i- * log.c - log to standard error according to the log level Err bitreich.org 70 i- * Err bitreich.org 70 i- * Instead of logging to syslog, delegate logging to a separate Err bitreich.org 70 i- * tool, such as FreeBSD's daemon(8), POSIX's logger(1). Err bitreich.org 70 i- */ 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- Err bitreich.org 70 i-#define LOG_DEFAULT 3 /* info */ Err bitreich.org 70 i- Err bitreich.org 70 i-int log_level = -1; Err bitreich.org 70 i-char *log_arg0 = NULL; Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-vlogf(int level, char const *flag, char const *fmt, va_list va) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *env; Err bitreich.org 70 i- int e = errno; Err bitreich.org 70 i- Err bitreich.org 70 i- if (log_level < 0) { Err bitreich.org 70 i- env = getenv("LOG"); Err bitreich.org 70 i- log_level = (env == NULL ? 0 : atoi(env)); Err bitreich.org 70 i- log_level = (log_level > 0 ? log_level : LOG_DEFAULT); Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- if (log_level < level) Err bitreich.org 70 i- return; Err bitreich.org 70 i- Err bitreich.org 70 i- if (log_arg0 != NULL) Err bitreich.org 70 i- fprintf(stderr, "%s: ", log_arg0); Err bitreich.org 70 i- Err bitreich.org 70 i- fprintf(stderr, "%s: ", flag); Err bitreich.org 70 i- vfprintf(stderr, fmt, va); Err bitreich.org 70 i- Err bitreich.org 70 i- if (e != 0) Err bitreich.org 70 i- fprintf(stderr, ": %s", strerror(e)); Err bitreich.org 70 i- 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- Err bitreich.org 70 i-void Err bitreich.org 70 i-die(char const *fmt, ...) Err bitreich.org 70 i-{ 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- vlogf(1, "error", fmt, va); Err bitreich.org 70 i- va_end(va); Err bitreich.org 70 i- exit(1); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-warn(char const *fmt, ...) Err bitreich.org 70 i-{ 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- vlogf(2, "warn", fmt, va); Err bitreich.org 70 i- va_end(va); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-info(char const *fmt, ...) Err bitreich.org 70 i-{ 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- vlogf(3, "info", fmt, va); Err bitreich.org 70 i- va_end(va); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-debug(char const *fmt, ...) Err bitreich.org 70 i-{ 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- vlogf(4, "debug", fmt, va); Err bitreich.org 70 i- va_end(va); Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/log.h b/log.h /scm/ics2txt/file/log.h.gph bitreich.org 70 i@@ -1,15 +0,0 @@ Err bitreich.org 70 i-#ifndef LOG_H Err bitreich.org 70 i-#define LOG_H Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-/** src/log.c **/ Err bitreich.org 70 i-extern int log_level; Err bitreich.org 70 i-extern char *log_arg0; Err bitreich.org 70 i-void vlogf(int level, char const *flag, char const *fmt, va_list va); Err bitreich.org 70 i-void die(char const *fmt, ...); Err bitreich.org 70 i-void warn(char const *fmt, ...); Err bitreich.org 70 i-void info(char const *fmt, ...); Err bitreich.org 70 i-void debug(char const *fmt, ...); Err bitreich.org 70 i- Err bitreich.org 70 i-#endif Err bitreich.org 70 1diff --git a/map.c b/map.c /scm/ics2txt/file/map.c.gph bitreich.org 70 i@@ -1,106 +0,0 @@ Err bitreich.org 70 i-#include "map.h" Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-#include "util.h" Err bitreich.org 70 i- Err bitreich.org 70 i-static int Err bitreich.org 70 i-map_cmp(void const *v1, void const *v2) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct map_entry const *e1 = v1, *e2 = v2; Err bitreich.org 70 i- Err bitreich.org 70 i- return strcmp(e1->key, e2->key); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void * Err bitreich.org 70 i-map_get(struct map *map, char *key) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct map_entry *entry, k = { .key = key }; Err bitreich.org 70 i- size_t sz; Err bitreich.org 70 i- Err bitreich.org 70 i- sz = sizeof(*map->entry); Err bitreich.org 70 i- if ((entry = bsearch(&k, map->entry, map->len, sz, map_cmp)) == NULL) Err bitreich.org 70 i- return NULL; Err bitreich.org 70 i- return entry->value; Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-int Err bitreich.org 70 i-map_set(struct map *map, char *key, void *value) Err bitreich.org 70 i-{ Err bitreich.org 70 i- struct map_entry *insert, *e; 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- 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- Err bitreich.org 70 i- if (cmp == 0) { Err bitreich.org 70 i- map->entry[i].value = value; Err bitreich.org 70 i- return 0; Err bitreich.org 70 i- } Err bitreich.org 70 i- if (cmp < 0) Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- sz = sizeof(*map->entry); Err bitreich.org 70 i- if ((v = reallocarray(map->entry, map->len + 1, sz)) == NULL) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- map->entry = v; Err bitreich.org 70 i- map->len++; Err bitreich.org 70 i- Err bitreich.org 70 i- insert = map->entry + i; Err bitreich.org 70 i- for (e = map->entry + map->len - 2; e >= insert; e--) Err bitreich.org 70 i- e[1] = e[0]; Err bitreich.org 70 i- Err bitreich.org 70 i- insert->key = key; Err bitreich.org 70 i- insert->value = 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-map_del(struct map *map, char *key) Err bitreich.org 70 i-{ Err bitreich.org 70 i- size_t i; 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- Err bitreich.org 70 i- if (cmp == 0) Err bitreich.org 70 i- break; Err bitreich.org 70 i- if (cmp < 0) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- } Err bitreich.org 70 i- if (i == map->len) Err bitreich.org 70 i- return -1; Err bitreich.org 70 i- Err bitreich.org 70 i- map->len--; Err bitreich.org 70 i- for (; i < map->len; i++) Err bitreich.org 70 i- map->entry[i] = map->entry[i + 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-map_init(struct map *map) Err bitreich.org 70 i-{ Err bitreich.org 70 i- memset(map, 0, sizeof(*map)); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-map_free_keys(struct map *map) Err bitreich.org 70 i-{ Err bitreich.org 70 i- for (size_t i = 0; i < map->len; i++) Err bitreich.org 70 i- free(map->entry[i].key); Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-void Err bitreich.org 70 i-map_free(struct map *map, void (*fn)(void *)) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (fn != NULL) { Err bitreich.org 70 i- for (size_t i = 0; i < map->len; i++) Err bitreich.org 70 i- fn(map->entry[i].value); Err bitreich.org 70 i- } Err bitreich.org 70 i- free(map->entry); Err bitreich.org 70 i- map->len = 0; Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/map.h b/map.h /scm/ics2txt/file/map.h.gph bitreich.org 70 i@@ -1,24 +0,0 @@ Err bitreich.org 70 i-#ifndef MAP_H Err bitreich.org 70 i-#define MAP_H Err bitreich.org 70 i- Err bitreich.org 70 i-#include Err bitreich.org 70 i- Err bitreich.org 70 i-struct map_entry { Err bitreich.org 70 i- char *key; Err bitreich.org 70 i- void *value; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-struct map { Err bitreich.org 70 i- struct map_entry *entry; Err bitreich.org 70 i- size_t len; Err bitreich.org 70 i-}; Err bitreich.org 70 i- Err bitreich.org 70 i-/** src/map.c **/ Err bitreich.org 70 i-void * map_get(struct map *map, char *key); Err bitreich.org 70 i-int map_set(struct map *map, char *key, void *value); Err bitreich.org 70 i-int map_del(struct map *map, char *key); Err bitreich.org 70 i-void map_init(struct map *map); Err bitreich.org 70 i-void map_free_keys(struct map *map); Err bitreich.org 70 i-void map_free(struct map *map, void (*fn)(void *)); Err bitreich.org 70 i- Err bitreich.org 70 i-#endif Err bitreich.org 70 1diff --git a/util.c b/util.c /scm/ics2txt/file/util.c.gph bitreich.org 70 i@@ -4,6 +4,59 @@ 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+ Err bitreich.org 70 i+char *arg0; Err bitreich.org 70 i+ 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+{ 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+ Err bitreich.org 70 i+void Err bitreich.org 70 i+err(char const *fmt, ...) Err bitreich.org 70 i+{ 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+ exit(1); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+warn(char const *fmt, ...) Err bitreich.org 70 i+{ 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+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+debug(char const *fmt, ...) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ static int verbose = -1; Err bitreich.org 70 i+ va_list va; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (verbose < 0) Err bitreich.org 70 i+ verbose = (getenv("DEBUG") == NULL); 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+} Err bitreich.org 70 i+ 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@@ -18,21 +71,20 @@ strlcpy(char *buf, char const *str, size_t sz) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i char * Err bitreich.org 70 i-strsep(char **str_p, char const *sep) Err bitreich.org 70 i+strsep(char **sp, char const *sep) Err bitreich.org 70 i { Err bitreich.org 70 i char *s, *prev; Err bitreich.org 70 i Err bitreich.org 70 i- if (*str_p == NULL) Err bitreich.org 70 i+ if (*sp == NULL) Err bitreich.org 70 i return NULL; Err bitreich.org 70 i- Err bitreich.org 70 i- for (s = prev = *str_p; strchr(sep, *s) == NULL; s++) Err bitreich.org 70 i+ prev = *sp; Err bitreich.org 70 i+ for (s = *sp; strchr(sep, *s) == NULL; s++) Err bitreich.org 70 i continue; Err bitreich.org 70 i- Err bitreich.org 70 i if (*s == '\0') { Err bitreich.org 70 i- *str_p = NULL; Err bitreich.org 70 i+ *sp = NULL; Err bitreich.org 70 i } else { Err bitreich.org 70 i+ *sp = s + 1; Err bitreich.org 70 i *s = '\0'; Err bitreich.org 70 i- *str_p = s + 1; Err bitreich.org 70 i } Err bitreich.org 70 i return prev; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -44,28 +96,30 @@ strchomp(char *line) Err bitreich.org 70 i Err bitreich.org 70 i len = strlen(line); Err bitreich.org 70 i if (len > 0 && line[len - 1] == '\n') Err bitreich.org 70 i- line[len-- - 1] = '\0'; Err bitreich.org 70 i+ line[--len] = '\0'; Err bitreich.org 70 i if (len > 0 && line[len - 1] == '\r') Err bitreich.org 70 i- line[len-- - 1] = '\0'; Err bitreich.org 70 i+ line[--len] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-strappend(char **base_p, char const *s) Err bitreich.org 70 i+strappend(char **dstp, char const *src) Err bitreich.org 70 i { Err bitreich.org 70 i- size_t base_len, s_len; Err bitreich.org 70 i- void *v; Err bitreich.org 70 i+ size_t dstlen, srclen; Err bitreich.org 70 i+ void *mem; Err bitreich.org 70 i Err bitreich.org 70 i- base_len = (*base_p == NULL) ? (0) : (strlen(*base_p)); Err bitreich.org 70 i- s_len = strlen(s); Err bitreich.org 70 i+ dstlen = (*dstp == NULL) ? 0 : strlen(*dstp); Err bitreich.org 70 i+ srclen = strlen(src); Err bitreich.org 70 i Err bitreich.org 70 i- if ((v = realloc(*base_p, base_len + s_len + 1)) == NULL) Err bitreich.org 70 i+ if ((mem = realloc(*dstp, dstlen + srclen + 1)) == NULL) Err bitreich.org 70 i return -1; Err bitreich.org 70 i+ *dstp = mem; Err bitreich.org 70 i Err bitreich.org 70 i- *base_p = v; Err bitreich.org 70 i- memcpy(*base_p + base_len, s, s_len + 1); Err bitreich.org 70 i+ memcpy(*dstp + dstlen, src, srclen + 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+ 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 { Err bitreich.org 70 1diff --git a/util.h b/util.h /scm/ics2txt/file/util.h.gph bitreich.org 70 i@@ -2,12 +2,21 @@ Err bitreich.org 70 i #define UTIL_H Err bitreich.org 70 i Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i Err bitreich.org 70 i-/** src/util.c **/ 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-void * reallocarray(void *buf, size_t len, size_t sz); 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+ 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 Err bitreich.org 70 i #endif Err bitreich.org 70 .