convert some fields to time_t - ics2txt - convert icalendar .ics file to plain text HTML git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ics2txt DIR Log DIR Files DIR Refs DIR Tags DIR README --- DIR commit 54ba66bb7b1b7eed7e3aaf60ef00c9ccc9cc65d6 DIR parent 58d91e5e80aea1ab98f675ccc4530f26a9659162 HTML Author: Josuah Demangeon <me@josuah.net> Date: Thu, 17 Jun 2021 01:35:05 +0200 convert some fields to time_t Diffstat: M ical.c | 24 ++++++++++++------------ M ical.h | 6 +++--- M ics2tree.c | 8 ++++---- M ics2tsv.c | 69 ++++++++++++++++--------------- 4 files changed, 55 insertions(+), 52 deletions(-) --- DIR diff --git a/ical.c b/ical.c @@ -93,7 +93,7 @@ ical_get_time(IcalParser *p, char *s, time_t *t) * permit to only have parsing code left to parsing functions */ static int -hook_entry_name(IcalParser *p, char *name) +hook_field_name(IcalParser *p, char *name) { (void)p; (void)name; return 0; @@ -119,7 +119,7 @@ hook_param_value(IcalParser *p, char *name, char *value) } static int -hook_entry_value(IcalParser *p, char *name, char *value) +hook_field_value(IcalParser *p, char *name, char *value) { if (strcasecmp(name, "TZID") == 0) if (strlcpy(p->current->tzid, value, sizeof p->current->tzid) >= @@ -144,9 +144,9 @@ hook_block_begin(IcalParser *p, char *name) for (int i = 0; ical_block_name[i] != NULL; i++) { if (strcasecmp(ical_block_name[i], name) == 0) { - if (p->block != ICAL_BLOCK_OTHER) + if (p->blocktype != ICAL_BLOCK_OTHER) return ical_err(p, "BEGIN:V* in BEGIN:V*"); - p->block = i; + p->blocktype = i; } } @@ -164,9 +164,9 @@ hook_block_end(IcalParser *p, char *name) if (p->current < p->stack) return ical_err(p, "more END: than BEGIN:"); - if (ical_block_name[p->block] != NULL && - strcasecmp(ical_block_name[p->block], name) == 0) - p->block = ICAL_BLOCK_OTHER; + if (ical_block_name[p->blocktype] != NULL && + strcasecmp(ical_block_name[p->blocktype], name) == 0) + p->blocktype = ICAL_BLOCK_OTHER; return 0; } @@ -241,8 +241,8 @@ ical_parse_contentline(IcalParser *p, char *s) return ical_err(p, "invalid property name"); c = *s, *s = '\0'; if (strcasecmp(name, "BEGIN") != 0 && strcasecmp(name, "END") != 0) - if ((err = hook_entry_name(p, name)) != 0 || - (err = CALL(p, fn_entry_name, name)) != 0) + if ((err = hook_field_name(p, name)) != 0 || + (err = CALL(p, fn_field_name, name)) != 0) return err; *s = c; sep = s; @@ -268,8 +268,8 @@ ical_parse_contentline(IcalParser *p, char *s) (err = CALL(p, fn_block_end, s)) != 0) return err; } else { - if ((err = hook_entry_value(p, name, s)) != 0 || - (err = CALL(p, fn_entry_value, name, s)) != 0) + if ((err = hook_field_value(p, name, s)) != 0 || + (err = CALL(p, fn_field_value, name, s)) != 0) return err; } return 0; @@ -312,7 +312,7 @@ ical_parse(IcalParser *p, FILE *fp) p->current = p->stack; p->linenum = 0; - p->block = ICAL_BLOCK_OTHER; + p->blocktype = ICAL_BLOCK_OTHER; do { if ((l = ical_getline(&contentline, &line, &sz, fp)) < 0) { DIR diff --git a/ical.h b/ical.h @@ -25,10 +25,10 @@ struct IcalStack { struct IcalParser { /* function called while parsing in this order */ - int (*fn_entry_name)(IcalParser *, char *); + int (*fn_field_name)(IcalParser *, char *); int (*fn_param_name)(IcalParser *, char *); int (*fn_param_value)(IcalParser *, char *, char *); - int (*fn_entry_value)(IcalParser *, char *, char *); + int (*fn_field_value)(IcalParser *, char *, char *); int (*fn_block_begin)(IcalParser *, char *); int (*fn_block_end)(IcalParser *, char *); /* if returning non-zero then halt the parser */ @@ -37,7 +37,7 @@ struct IcalParser { char *errmsg; size_t linenum; char *tzid; - IcalBlock block; + IcalBlock blocktype; IcalStack stack[ICAL_STACK_SIZE], *current; }; DIR diff --git a/ics2tree.c b/ics2tree.c @@ -14,7 +14,7 @@ print_ruler(int level) } static int -fn_entry_name(IcalParser *p, char *name) +fn_field_name(IcalParser *p, char *name) { print_ruler(ical_get_level(p)); printf("name %s\n", name); @@ -41,7 +41,7 @@ fn_param_value(IcalParser *p, char *name, char *value) } static int -fn_entry_value(IcalParser *p, char *name, char *value) +fn_field_value(IcalParser *p, char *name, char *value) { size_t len; (void)name; @@ -69,10 +69,10 @@ main(int argc, char **argv) IcalParser p = {0}; arg0 = *argv++; - p.fn_entry_name = fn_entry_name; + p.fn_field_name = fn_field_name; p.fn_block_begin = fn_block_begin; p.fn_param_value = fn_param_value; - p.fn_entry_value = fn_entry_value; + p.fn_field_value = fn_field_value; if (*argv == NULL) { if (ical_parse(&p, stdin) < 0) DIR diff --git a/ics2tsv.c b/ics2tsv.c @@ -1,3 +1,4 @@ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -8,25 +9,18 @@ #define FIELDS_MAX 64 -typedef struct Event Event; +typedef struct Field Field; +typedef struct Block Block; -struct Event { +struct Block { time_t beg, end; char *fields[FIELDS_MAX]; }; -static char *fields_time[] = { - "DTSTART", "DTEND", "DTSTAMP", "DUE", "EXDATE", "RDATE" -}; - -static char *fields_default[] = { - "ATTENDEE", "CATEGORY", "DESCRIPTION", "LOCATION", "SUMMARY", "URL" -}; - -static char **fields = fields_default; +Block block; static int -fn_entry_name(IcalParser *p, char *name) +fn_field_name(IcalParser *p, char *name) { printf("name %s\n", name); return 0; @@ -35,7 +29,14 @@ fn_entry_name(IcalParser *p, char *name) static int fn_block_begin(IcalParser *p, char *name) { - printf("begin %s\n", name); + debug("begin %s\n", name); + return 0; +} + +static int +fn_block_end(IcalParser *p, char *name) +{ + debug("end %s\n", name); return 0; } @@ -47,25 +48,26 @@ fn_param_value(IcalParser *p, char *name, char *value) } static int -fn_entry_value(IcalParser *p, char *name, char *value) +fn_field_value(IcalParser *p, char *name, char *value) { - size_t len; - (void)name; - - if (ical_get_value(p, value, &len) < 0) - return -1; - - if (strcasecmp(name, "DTSTART") == 0 || - strcasecmp(name, "DTSTAMP") == 0 || - strcasecmp(name, "DTEND") == 0) { - time_t t = 0; - if (ical_get_time(p, value, &t) != 0) - warn("%s: %s", p->errmsg, value); - printf("epoch %lld\n", t); - } else { - printf("value %s\n", value); - } - + static char *fieldmap[][2] = { + [ICAL_BLOCK_VEVENT] = { "DTSTART", "DTEND" }, + [ICAL_BLOCK_VTODO] = { NULL, "DUE" }, + [ICAL_BLOCK_VJOURNAL] = { "DTSTAMP", NULL }, + [ICAL_BLOCK_VFREEBUSY] = { "DTSTART", "DTEND" }, + [ICAL_BLOCK_VALARM] = { "DTSTART", NULL }, + [ICAL_BLOCK_OTHER] = { NULL, NULL }, + }; + char *beg, *end; + + beg = fieldmap[p->blocktype][0]; + if (beg != NULL && strcasecmp(name, beg) == 0) + if (ical_get_time(p, value, &block.beg) != 0) + return -1; + end = fieldmap[p->blocktype][1]; + if (end != NULL && strcasecmp(name, end) == 0) + if (ical_get_time(p, value, &block.end) != 0) + return -1; return 0; } @@ -75,10 +77,11 @@ main(int argc, char **argv) IcalParser p = {0}; arg0 = *argv++; - p.fn_entry_name = fn_entry_name; + p.fn_field_name = fn_field_name; p.fn_block_begin = fn_block_begin; + p.fn_block_end = fn_block_end; p.fn_param_value = fn_param_value; - p.fn_entry_value = fn_entry_value; + p.fn_field_value = fn_field_value; if (*argv == NULL) { if (ical_parse(&p, stdin) < 0)