convert some fields to time_t - ics2txt - convert icalendar .ics file to plain text
(HTM) 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
(HTM) 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)