iremove unused utilities and flatten the source some more - 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 24ae7d2759496b7907cce29f0c26697950453ff5 /scm/ics2txt/commit/24ae7d2759496b7907cce29f0c26697950453ff5.gph bitreich.org 70 1parent 742516775b1d9b12e4c8893114b7cc5a363884ad /scm/ics2txt/commit/742516775b1d9b12e4c8893114b7cc5a363884ad.gph bitreich.org 70 hAuthor: Josuah Demangeon URL:mailto:me@josuah.net bitreich.org 70 iDate: Sun, 20 Jun 2021 18:37:15 +0200 Err bitreich.org 70 i Err bitreich.org 70 iremove unused utilities and flatten the source some more Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M .gitignore | 1 + Err bitreich.org 70 i M Makefile | 19 ++++++++++++------- Err bitreich.org 70 i D bin/ics2tsv | 141 ------------------------------- Err bitreich.org 70 i D bin/ics2txt | 2 -- Err bitreich.org 70 i D bin/tsv2ics | 104 ------------------------------- Err bitreich.org 70 i M ics2tsv.c | 57 ++++++++++++++++--------------- Err bitreich.org 70 i M tsv2agenda.c | 249 ++++++++++++++++++------------- Err bitreich.org 70 i A tsv2ics.awk | 106 ++++++++++++++++++++++++++++++ Err bitreich.org 70 i M util.c | 14 ++++++++++++++ Err bitreich.org 70 i M util.h | 4 ++++ Err bitreich.org 70 i Err bitreich.org 70 i10 files changed, 310 insertions(+), 387 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/.gitignore b/.gitignore /scm/ics2txt/file/.gitignore.gph bitreich.org 70 i@@ -1,5 +1,6 @@ Err bitreich.org 70 i *.o Err bitreich.org 70 i /ics2tsv Err bitreich.org 70 i /ics2tree Err bitreich.org 70 i+/tsv2ics Err bitreich.org 70 i /tsv2agenda Err bitreich.org 70 i /ics2txt-[0-9]* Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/ics2txt/file/Makefile.gph bitreich.org 70 i@@ -10,31 +10,36 @@ MANPREFIX = ${PREFIX}/man Err bitreich.org 70 i SRC = ical.c base64.c util.c Err bitreich.org 70 i HDR = ical.h base64.h util.h Err bitreich.org 70 i OBJ = ${SRC:.c=.o} Err bitreich.org 70 i+AWK = tsv2ics.awk Err bitreich.org 70 i BIN = ics2tree ics2tsv tsv2agenda Err bitreich.org 70 i MAN1 = ics2txt.1 ics2tsv.1 Err bitreich.org 70 i-MAN5 = tcal.5 Err bitreich.org 70 i Err bitreich.org 70 i all: ${BIN} Err bitreich.org 70 i Err bitreich.org 70 i .c.o: Err bitreich.org 70 i ${CC} -c ${CFLAGS} -o $@ $< Err bitreich.org 70 i Err bitreich.org 70 i+${AWK:.awk=}: Err bitreich.org 70 i+ cp $@.awk $@ Err bitreich.org 70 i+ chmod +x $@ Err bitreich.org 70 i+ Err bitreich.org 70 i ${OBJ}: ${HDR} Err bitreich.org 70 i ${BIN}: ${OBJ} ${BIN:=.o} Err bitreich.org 70 i ${CC} ${LDFLAGS} -o $@ $@.o ${OBJ} Err bitreich.org 70 i Err bitreich.org 70 i clean: Err bitreich.org 70 i- rm -rf *.o ${BIN} ${NAME}-${VERSION} *.gz Err bitreich.org 70 i+ rm -rf *.o ${BIN} ${AWK:.awk} ${NAME}-${VERSION} *.gz Err bitreich.org 70 i Err bitreich.org 70 i-install: Err bitreich.org 70 i+install: ${BIN} ${AWK:.awk=} Err bitreich.org 70 i mkdir -p ${DESTDIR}$(PREFIX)/bin Err bitreich.org 70 i- cp bin/* $(BIN) ${DESTDIR}$(PREFIX)/bin Err bitreich.org 70 i+ cp $(BIN) ${AWK:.awk=} ${DESTDIR}$(PREFIX)/bin Err bitreich.org 70 i mkdir -p ${DESTDIR}$(MANPREFIX)/man1 Err bitreich.org 70 i cp ${MAN1} ${DESTDIR}$(MANPREFIX)/man1 Err bitreich.org 70 i- mkdir -p ${DESTDIR}$(MANPREFIX)/man5 Err bitreich.org 70 i- cp ${MAN5} ${DESTDIR}$(MANPREFIX)/man5 Err bitreich.org 70 i Err bitreich.org 70 i dist: clean Err bitreich.org 70 i mkdir -p ${NAME}-${VERSION} Err bitreich.org 70 i- cp -r README Makefile bin ${MAN1} ${MAN5} ${SRC} ${NAME}-${VERSION} Err bitreich.org 70 i+ cp -r README Makefile ${AWK} ${MAN1} ${SRC} ${NAME}-${VERSION} Err bitreich.org 70 i tar -cf - ${NAME}-${VERSION} | gzip -c >${NAME}-${VERSION}.tar.gz Err bitreich.org 70 i+ Err bitreich.org 70 i+.SUFFIXES: .awk Err bitreich.org 70 i+.PHONY: ${AWK} Err bitreich.org 70 1diff --git a/bin/ics2tsv b/bin/ics2tsv /scm/ics2txt/file/bin/ics2tsv.gph bitreich.org 70 i@@ -1,141 +0,0 @@ Err bitreich.org 70 i-#!/usr/bin/awk -f Err bitreich.org 70 i- Err bitreich.org 70 i-function isleap(year) Err bitreich.org 70 i-{ Err bitreich.org 70 i- return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function mdays(mon, year) Err bitreich.org 70 i-{ Err bitreich.org 70 i- return (mon == 2) ? (28 + isleap(year)) : (30 + (mon + (mon > 7)) % 2) Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function timegm(tm, Err bitreich.org 70 i- sec, mon, day) Err bitreich.org 70 i-{ Err bitreich.org 70 i- sec = tm["sec"] + tm["min"] * 60 + tm["hour"] * 3600 Err bitreich.org 70 i- Err bitreich.org 70 i- day = tm["mday"] - 1 Err bitreich.org 70 i- Err bitreich.org 70 i- for (mon = tm["mon"] - 1; mon > 0; mon--) Err bitreich.org 70 i- day = day + mdays(mon, tm["year"]) Err bitreich.org 70 i- Err bitreich.org 70 i- # constants: x * 365 + x / 400 - x / 100 + x / 4 Err bitreich.org 70 i- day = day + int(tm["year"] / 400) * 146097 Err bitreich.org 70 i- day = day + int(tm["year"] % 400 / 100) * 36524 Err bitreich.org 70 i- day = day + int(tm["year"] % 100 / 4) * 1461 Err bitreich.org 70 i- day = day + int(tm["year"] % 4 / 1) * 365 Err bitreich.org 70 i- Err bitreich.org 70 i- return sec + (day - 719527) * 86400 Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function print_vevent(ev, fields, Err bitreich.org 70 i- i) Err bitreich.org 70 i-{ Err bitreich.org 70 i- for (i = 1; i in fields; i++) Err bitreich.org 70 i- printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]]) Err bitreich.org 70 i- printf("\n") Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function ical_parse_line(str, content, params, Err bitreich.org 70 i- i, eq) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if ((i = index(str, ":")) == 0) Err bitreich.org 70 i- return -1 Err bitreich.org 70 i- content["value"] = substr(str, i + 1) Err bitreich.org 70 i- str = substr(str, 1, i - 1) Err bitreich.org 70 i- Err bitreich.org 70 i- if ((i = index(str, ";")) == 0) { Err bitreich.org 70 i- content["name"] = str Err bitreich.org 70 i- return 0 Err bitreich.org 70 i- } Err bitreich.org 70 i- content["name"] = substr(str, 1, i - 1) Err bitreich.org 70 i- str = substr(str, i + 1) Err bitreich.org 70 i- Err bitreich.org 70 i- while ((i = index(str, ";")) > 0) { Err bitreich.org 70 i- if ((eq = index(str, "=")) == 0) Err bitreich.org 70 i- return -1 Err bitreich.org 70 i- param[substr(str, 1, eq - 1)] = substr(str, eq + 1, i - 1) Err bitreich.org 70 i- str = substr(str, eq + 1) Err bitreich.org 70 i- } Err bitreich.org 70 i- if ((eq = index(str, "=")) == 0) Err bitreich.org 70 i- return -1 Err bitreich.org 70 i- params[substr(str, 1, eq - 1)] = substr(str, eq + 1) Err bitreich.org 70 i- return 0 Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function ical_set_tz(tzid) Err bitreich.org 70 i-{ Err bitreich.org 70 i- gsub("'", "", tzid) Err bitreich.org 70 i- cmd = "TZ='" tzid "' exec date +%z" Err bitreich.org 70 i- cmd | getline tzid Err bitreich.org 70 i- close(cmd) Err bitreich.org 70 i- TZ = substr(tzid, 1, 1) substr(tzid, 2, 2)*3600 + substr(tzid, 4, 2)*60 Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function ical_to_epoch(content, param, Err bitreich.org 70 i- tz, cmd) Err bitreich.org 70 i-{ Err bitreich.org 70 i- if (param["TZID"]) Err bitreich.org 70 i- ical_set_tz(param["TZID"]) Err bitreich.org 70 i- Err bitreich.org 70 i- tm["year"] = substr(content["value"], 1, 4) Err bitreich.org 70 i- tm["mon"] = substr(content["value"], 5, 2) Err bitreich.org 70 i- tm["mday"] = substr(content["value"], 7, 2) Err bitreich.org 70 i- tm["hour"] = substr(content["value"], 10, 2) Err bitreich.org 70 i- tm["min"] = substr(content["value"], 12, 2) Err bitreich.org 70 i- tm["sec"] = substr(content["value"], 14, 2) Err bitreich.org 70 i- Err bitreich.org 70 i- return timegm(tm) + TZ Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-BEGIN { Err bitreich.org 70 i- split("DTSTART DTEND CATEGORIES LOCATION SUMMARY DESCRIPTION URL", Err bitreich.org 70 i- FIELDS, " ") Err bitreich.org 70 i- DT["DTSTART"] = DT["DTEND"] = DT["DUE"] = 1 Err bitreich.org 70 i- Err bitreich.org 70 i- # by default: "CATEGORIES" -> "cat", "LOCATION" -> "loc"... Err bitreich.org 70 i- translate["DTSTART"] = "beg" Err bitreich.org 70 i- translate["DTEND"] = "end" Err bitreich.org 70 i- Err bitreich.org 70 i- for (i = 1; i in FIELDS; i++) { Err bitreich.org 70 i- if (!(s = translate[FIELDS[i]])) Err bitreich.org 70 i- s = tolower(substr(FIELDS[i], 1, 3)) Err bitreich.org 70 i- printf("%s%s", (i > 1 ? "\t" : ""), s) Err bitreich.org 70 i- } Err bitreich.org 70 i- printf("\n") Err bitreich.org 70 i- Err bitreich.org 70 i- FS = "[:;]" Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-{ Err bitreich.org 70 i- gsub("\r", "") Err bitreich.org 70 i- gsub("\t", "\\\\t") Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-sub("^ ", "") { Err bitreich.org 70 i- content["value"] = content["value"] $0 Err bitreich.org 70 i- next Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-{ Err bitreich.org 70 i- delete content Err bitreich.org 70 i- delete param Err bitreich.org 70 i- Err bitreich.org 70 i- if (ical_parse_line($0, content, params) < 0) Err bitreich.org 70 i- next Err bitreich.org 70 i- Err bitreich.org 70 i- if (content["name"] == "TZID") { Err bitreich.org 70 i- ical_set_tz(content["value"]) Err bitreich.org 70 i- } else if (DT[content["name"]]) { Err bitreich.org 70 i- vevent[content["name"]] = ical_to_epoch(content, params) Err bitreich.org 70 i- } else { Err bitreich.org 70 i- vevent[content["name"]] = content["value"] Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-/^END:VEVENT/ { Err bitreich.org 70 i- print_vevent(vevent, FIELDS) Err bitreich.org 70 i- delete vevent Err bitreich.org 70 i- next Err bitreich.org 70 i-} Err bitreich.org 70 1diff --git a/bin/ics2txt b/bin/ics2txt /scm/ics2txt/file/bin/ics2txt.gph bitreich.org 70 i@@ -1,2 +0,0 @@ Err bitreich.org 70 i-#!/bin/sh -e Err bitreich.org 70 i-exec ics2tsv "$@" | exec tsv2tcal Err bitreich.org 70 1diff --git a/bin/tsv2ics b/bin/tsv2ics /scm/ics2txt/file/bin/tsv2ics.gph bitreich.org 70 i@@ -1,104 +0,0 @@ Err bitreich.org 70 i-#!/usr/bin/awk -f Err bitreich.org 70 i- Err bitreich.org 70 i-function isleap(year) Err bitreich.org 70 i-{ Err bitreich.org 70 i- return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function mdays(mon, year) Err bitreich.org 70 i-{ Err bitreich.org 70 i- return (mon == 2) ? (28 + isleap(year)) : (30 + (mon + (mon > 7)) % 2) Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-# Split the time in seconds since epoch into a table, with fields Err bitreich.org 70 i-# named as with gmtime(3): tm["year"], tm["mon"], tm["mday"], Err bitreich.org 70 i-# tm["hour"], tm["min"], tm["sec"] Err bitreich.org 70 i-function gmtime(sec, tm, Err bitreich.org 70 i- s) Err bitreich.org 70 i-{ Err bitreich.org 70 i- tm["year"] = 1970 Err bitreich.org 70 i- while (sec >= (s = 86400 * (365 + isleap(tm["year"])))) { Err bitreich.org 70 i- tm["year"]++ Err bitreich.org 70 i- sec -= s Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- tm["mon"] = 1 Err bitreich.org 70 i- while (sec >= (s = 86400 * mdays(tm["mon"], tm["year"]))) { Err bitreich.org 70 i- tm["mon"]++ Err bitreich.org 70 i- sec -= s Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- tm["mday"] = 1 Err bitreich.org 70 i- while (sec >= (s = 86400)) { Err bitreich.org 70 i- tm["mday"]++ Err bitreich.org 70 i- sec -= s Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- tm["hour"] = 0 Err bitreich.org 70 i- while (sec >= 3600) { Err bitreich.org 70 i- tm["hour"]++ Err bitreich.org 70 i- sec -= 3600 Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- tm["min"] = 0 Err bitreich.org 70 i- while (sec >= 60) { Err bitreich.org 70 i- tm["min"]++ Err bitreich.org 70 i- sec -= 60 Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- tm["sec"] = sec Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-function print_fold(prefix, s, n) Err bitreich.org 70 i-{ Err bitreich.org 70 i- while (s != "") { Err bitreich.org 70 i- line = substr(s, 1, n) Err bitreich.org 70 i- if (length(s) > n) sub(" +[^ \t\r\n]*$", "", line) Err bitreich.org 70 i- print prefix line Err bitreich.org 70 i- s = substr(s, length(line) + 2) Err bitreich.org 70 i- } Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-BEGIN { Err bitreich.org 70 i- FS = "\t" Err bitreich.org 70 i- Err bitreich.org 70 i- print "BEGIN:VCALENDAR" Err bitreich.org 70 i- print "VERSION:2.0" Err bitreich.org 70 i- print "CALSCALE:GREGORIAN" Err bitreich.org 70 i- print "METHOD:PUBLISH" Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-NR == 1 { Err bitreich.org 70 i- for (i = 1; i <= NF; i++) Err bitreich.org 70 i- name[i] = $i Err bitreich.org 70 i- next Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-{ Err bitreich.org 70 i- for (i = 1; i <= NF; i++) Err bitreich.org 70 i- ev[name[i]] = $i Err bitreich.org 70 i- Err bitreich.org 70 i- print "" Err bitreich.org 70 i- print "BEGIN:VEVENT" Err bitreich.org 70 i- Err bitreich.org 70 i- gmtime(ev["beg"] + offset, ev) Err bitreich.org 70 i- printf "DTSTART:%04d%02d%02dT%02d%02d00Z\n", Err bitreich.org 70 i- ev["year"], ev["mon"], ev["mday"], ev["hour"], ev["min"] Err bitreich.org 70 i- Err bitreich.org 70 i- gmtime(ev["end"] + offset, ev) Err bitreich.org 70 i- printf "DTEND:%04d%02d%02dT%02d%02d00Z\n", Err bitreich.org 70 i- ev["year"], ev["mon"], ev["mday"], ev["hour"], ev["min"] Err bitreich.org 70 i- Err bitreich.org 70 i- print "SUMMARY:" ev["sum"] Err bitreich.org 70 i- print "DESCRIPTION:" ev["des"] Err bitreich.org 70 i- print "CATEGORIES:" ev["cat"] Err bitreich.org 70 i- print "LOCATION:" ev["loc"] Err bitreich.org 70 i- print "END:VEVENT" Err bitreich.org 70 i- Err bitreich.org 70 i- delete ev Err bitreich.org 70 i-} Err bitreich.org 70 i- Err bitreich.org 70 i-END { Err bitreich.org 70 i- print "" Err bitreich.org 70 i- print "END:VCALENDAR" 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@@ -27,11 +27,11 @@ struct Block { Err bitreich.org 70 i char *fields[FIELDS_MAX]; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i-static int flag_1 = 0; Err bitreich.org 70 i-static char default_fields[] = "CATEGORIES,LOCATION,SUMMARY,DESCRIPTION"; Err bitreich.org 70 i-static char *flag_s = ","; Err bitreich.org 70 i-static char *flag_t = NULL; Err bitreich.org 70 i-static char *flag_f = default_fields; Err bitreich.org 70 i+static int flag_header = 1; Err bitreich.org 70 i+static char default_fields[] = "SUMMARY,DESCRIPTION,CATEGORIES,LOCATION"; Err bitreich.org 70 i+static char *flag_sep = ","; Err bitreich.org 70 i+static char *flag_timefmt = NULL; Err bitreich.org 70 i+static char *flag_fields = default_fields; Err bitreich.org 70 i static char *fields[FIELDS_MAX]; Err bitreich.org 70 i static Block block; Err bitreich.org 70 i Err bitreich.org 70 i@@ -60,9 +60,6 @@ fn_block_begin(IcalParser *p, char *name) Err bitreich.org 70 i static int Err bitreich.org 70 i fn_block_end(IcalParser *p, char *name) Err bitreich.org 70 i { Err bitreich.org 70 i- char buf[128]; Err bitreich.org 70 i- struct tm tm = {0}; Err bitreich.org 70 i- Err bitreich.org 70 i (void)name; Err bitreich.org 70 i Err bitreich.org 70 i if (p->blocktype == ICAL_BLOCK_OTHER) Err bitreich.org 70 i@@ -70,12 +67,18 @@ fn_block_end(IcalParser *p, char *name) Err bitreich.org 70 i fputs(p->current->name, stdout); Err bitreich.org 70 i Err bitreich.org 70 i /* printing dates with %s is much much slower than %lld */ Err bitreich.org 70 i- if (flag_t == NULL) { Err bitreich.org 70 i+ if (flag_timefmt == NULL) { Err bitreich.org 70 i printf("\t%lld\t%lld", block.beg, block.end); Err bitreich.org 70 i } else { Err bitreich.org 70 i- strftime(buf, sizeof buf, flag_t, localtime_r(&block.beg, &tm)); Err bitreich.org 70 i+ char buf[128]; Err bitreich.org 70 i+ struct tm tm = {0}; Err bitreich.org 70 i+ Err bitreich.org 70 i+ localtime_r(&block.beg, &tm); Err bitreich.org 70 i+ strftime(buf, sizeof buf, flag_timefmt, &tm); Err bitreich.org 70 i printf("\t%s", buf); Err bitreich.org 70 i- strftime(buf, sizeof buf, flag_t, localtime_r(&block.end, &tm)); Err bitreich.org 70 i+ Err bitreich.org 70 i+ localtime_r(&block.end, &tm); Err bitreich.org 70 i+ strftime(buf, sizeof buf, flag_timefmt, &tm); Err bitreich.org 70 i printf("\t%s", buf); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -131,7 +134,7 @@ fn_field_value(IcalParser *p, char *name, char *value) Err bitreich.org 70 i if ((block.fields[i] = strdup(value)) == NULL) Err bitreich.org 70 i return ical_err(p, strerror(errno)); Err bitreich.org 70 i } else { Err bitreich.org 70 i- if (strappend(&block.fields[i], flag_s) == NULL || Err bitreich.org 70 i+ if (strappend(&block.fields[i], flag_sep) == NULL || Err bitreich.org 70 i strappend(&block.fields[i], value) == NULL) Err bitreich.org 70 i return ical_err(p, strerror(errno)); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -144,7 +147,7 @@ fn_field_value(IcalParser *p, char *name, char *value) Err bitreich.org 70 i static void Err bitreich.org 70 i usage(void) Err bitreich.org 70 i { Err bitreich.org 70 i- fprintf(stderr,"usage: %s [-1] [-f fields] [-s subsep] [-t timefmt]" Err bitreich.org 70 i+ fprintf(stderr,"usage: %s [-1] [-f fields] [-s separator] [-t timefmt]" Err bitreich.org 70 i " [file...]\n", arg0); Err bitreich.org 70 i exit(1); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -153,7 +156,6 @@ int Err bitreich.org 70 i main(int argc, char **argv) Err bitreich.org 70 i { Err bitreich.org 70 i IcalParser p = {0}; Err bitreich.org 70 i- size_t i; Err bitreich.org 70 i int c; Err bitreich.org 70 i Err bitreich.org 70 i arg0 = *argv; Err bitreich.org 70 i@@ -167,19 +169,22 @@ main(int argc, char **argv) Err bitreich.org 70 i p.fn_param_value = fn_param_value; Err bitreich.org 70 i p.fn_field_value = fn_field_value; Err bitreich.org 70 i Err bitreich.org 70 i- while ((c = getopt(argc, argv, "1f:s:t:")) != -1) { Err bitreich.org 70 i+ while ((c = getopt(argc, argv, "01f:s:t:")) != -1) { Err bitreich.org 70 i switch (c) { Err bitreich.org 70 i+ case '0': Err bitreich.org 70 i+ flag_header = 0; Err bitreich.org 70 i+ break; Err bitreich.org 70 i case '1': Err bitreich.org 70 i- flag_1 = 1; Err bitreich.org 70 i+ flag_header = 1; Err bitreich.org 70 i break; Err bitreich.org 70 i case 'f': Err bitreich.org 70 i- flag_f = optarg; Err bitreich.org 70 i+ flag_fields = optarg; Err bitreich.org 70 i break; Err bitreich.org 70 i case 's': Err bitreich.org 70 i- flag_s = optarg; Err bitreich.org 70 i+ flag_sep = optarg; Err bitreich.org 70 i break; Err bitreich.org 70 i case 't': Err bitreich.org 70 i- flag_t = optarg; Err bitreich.org 70 i+ flag_timefmt = optarg; Err bitreich.org 70 i break; Err bitreich.org 70 i case '?': Err bitreich.org 70 i usage(); Err bitreich.org 70 i@@ -189,16 +194,12 @@ main(int argc, char **argv) Err bitreich.org 70 i argv += optind; Err bitreich.org 70 i argc -= optind; Err bitreich.org 70 i Err bitreich.org 70 i- i = 0; Err bitreich.org 70 i- do { Err bitreich.org 70 i- if (i >= sizeof fields / sizeof *fields - 1) Err bitreich.org 70 i- err(1, "too many fields specified with -o flag"); Err bitreich.org 70 i- } while ((fields[i++] = strsep(&flag_f, ",")) != NULL); Err bitreich.org 70 i- fields[i] = NULL; Err bitreich.org 70 i+ if (strsplit(flag_fields, fields, LEN(fields), ",") < 0) Err bitreich.org 70 i+ err(1, "too many fields specified with -f flag"); Err bitreich.org 70 i Err bitreich.org 70 i- if (flag_1) { Err bitreich.org 70 i- printf("%s\t%s\t%s\t%s", "TYPE", "BEG", "END", "RECUR"); Err bitreich.org 70 i- for (i = 0; fields[i] != NULL; i++) Err bitreich.org 70 i+ if (flag_header) { Err bitreich.org 70 i+ printf("%s\t%s\t%s\t%s", "TYPE", "START", "END", "RECUR"); Err bitreich.org 70 i+ for (size_t i = 0; fields[i] != NULL; i++) Err bitreich.org 70 i printf("\t%s", fields[i]); Err bitreich.org 70 i fputc('\n', stdout); Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/tsv2agenda.c b/tsv2agenda.c /scm/ics2txt/file/tsv2agenda.c.gph bitreich.org 70 i@@ -1,35 +1,38 @@ 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 Err bitreich.org 70 i #include Err bitreich.org 70 i+#include Err bitreich.org 70 i #include "util.h" Err bitreich.org 70 i Err bitreich.org 70 i #ifndef __OpenBSD__ Err bitreich.org 70 i #define pledge(...) 0 Err bitreich.org 70 i #endif Err bitreich.org 70 i Err bitreich.org 70 i-#define FIELDS_MAX 128 Err bitreich.org 70 i- Err bitreich.org 70 i enum { Err bitreich.org 70 i FIELD_TYPE, Err bitreich.org 70 i FIELD_BEG, Err bitreich.org 70 i FIELD_END, Err bitreich.org 70 i FIELD_RECUR, Err bitreich.org 70 i FIELD_OTHER, Err bitreich.org 70 i+ FIELD_MAX = 128, Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i typedef struct { Err bitreich.org 70 i struct tm beg, end; Err bitreich.org 70 i+ char *fieldnames[FIELD_MAX]; Err bitreich.org 70 i+ size_t fieldnum; Err bitreich.org 70 i+ size_t linenum; Err bitreich.org 70 i } AgendaCtx; Err bitreich.org 70 i Err bitreich.org 70 i-static size_t field_categories = 0; Err bitreich.org 70 i-static size_t field_location = 0; Err bitreich.org 70 i-static size_t field_summary = 0; Err bitreich.org 70 i+static time_t flag_from = INT64_MIN; Err bitreich.org 70 i+static time_t flag_to = INT64_MAX; Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i+static void Err bitreich.org 70 i print_date(struct tm *tm) Err bitreich.org 70 i { Err bitreich.org 70 i if (tm == NULL) { Err bitreich.org 70 i@@ -42,7 +45,7 @@ print_date(struct tm *tm) 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+static void Err bitreich.org 70 i print_time(struct tm *tm) Err bitreich.org 70 i { Err bitreich.org 70 i if (tm == NULL) { Err bitreich.org 70 i@@ -55,139 +58,175 @@ print_time(struct tm *tm) 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-print(AgendaCtx *ctx, char **fields, size_t n) Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_header1(struct tm *old, struct tm *new) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int same; Err bitreich.org 70 i+ Err bitreich.org 70 i+ same = (old->tm_year == new->tm_year && old->tm_mon == new->tm_mon && Err bitreich.org 70 i+ old->tm_mday == new->tm_mday); Err bitreich.org 70 i+ print_date(same ? NULL : new); Err bitreich.org 70 i+ print_time(new); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_header2(struct tm *beg, struct tm *end) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ int same; Err bitreich.org 70 i+ Err bitreich.org 70 i+ same = (beg->tm_year == end->tm_year && beg->tm_mon == end->tm_mon && Err bitreich.org 70 i+ beg->tm_mday == end->tm_mday); Err bitreich.org 70 i+ print_date(same ? NULL : end); Err bitreich.org 70 i+ Err bitreich.org 70 i+ same = (beg->tm_hour == end->tm_hour && beg->tm_min == end->tm_min); Err bitreich.org 70 i+ print_time(same ? NULL : end); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_header3(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ print_date(NULL); Err bitreich.org 70 i+ print_time(NULL); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+print_row(AgendaCtx *ctx, char **fields, size_t i) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ if (i > ctx->fieldnum || *fields[i] == '\0') Err bitreich.org 70 i+ return; Err bitreich.org 70 i+ fprintf(stdout, "%s\n", fields[i]); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static void Err bitreich.org 70 i+print(AgendaCtx *ctx, char **fields) Err bitreich.org 70 i { Err bitreich.org 70 i struct tm beg = {0}, end = {0}; Err bitreich.org 70 i time_t t; Err bitreich.org 70 i+ size_t i = FIELD_OTHER; Err bitreich.org 70 i char const *e; Err bitreich.org 70 i- int rows, samedate; Err bitreich.org 70 i Err bitreich.org 70 i- t = strtonum(fields[FIELD_BEG], 0, UINT32_MAX, &e); Err bitreich.org 70 i+ t = strtonum(fields[FIELD_BEG], INT64_MIN, INT64_MAX, &e); Err bitreich.org 70 i if (e != NULL) Err bitreich.org 70 i err(1, "start time %s is %s", fields[FIELD_BEG], e); Err bitreich.org 70 i+ if (t > flag_to) Err bitreich.org 70 i+ return; Err bitreich.org 70 i localtime_r(&t, &beg); Err bitreich.org 70 i Err bitreich.org 70 i- t = strtonum(fields[FIELD_END], 0, UINT32_MAX, &e); Err bitreich.org 70 i+ t = strtonum(fields[FIELD_END], INT64_MIN, INT64_MAX, &e); Err bitreich.org 70 i if (e != NULL) Err bitreich.org 70 i err(1, "end time %s is %s", fields[FIELD_END], e); Err bitreich.org 70 i+ if (t < flag_from) Err bitreich.org 70 i+ return; Err bitreich.org 70 i localtime_r(&t, &end); Err bitreich.org 70 i Err bitreich.org 70 i- fputc('\n', stdout); Err bitreich.org 70 i- Err bitreich.org 70 i- samedate = (ctx->beg.tm_year != beg.tm_year || ctx->beg.tm_mon != beg.tm_mon || Err bitreich.org 70 i- ctx->beg.tm_mday != beg.tm_mday); Err bitreich.org 70 i- print_date(samedate ? &beg : NULL); Err bitreich.org 70 i- print_time(&beg); Err bitreich.org 70 i- Err bitreich.org 70 i- assert(field_summary < n); Err bitreich.org 70 i- assert(field_summary > FIELD_OTHER); Err bitreich.org 70 i- fprintf(stdout, "%s\n", fields[field_summary]); Err bitreich.org 70 i- Err bitreich.org 70 i- samedate = (beg.tm_year != end.tm_year || beg.tm_mon != end.tm_mon || Err bitreich.org 70 i- beg.tm_mday != end.tm_mday); Err bitreich.org 70 i- print_date(samedate ? &end : NULL); Err bitreich.org 70 i- print_time(&end); Err bitreich.org 70 i- Err bitreich.org 70 i- rows = 0; Err bitreich.org 70 i- Err bitreich.org 70 i- assert(field_location < n); Err bitreich.org 70 i- if (field_location > 0 && fields[field_location][0] != '\0') { Err bitreich.org 70 i- assert(field_summary > FIELD_OTHER); Err bitreich.org 70 i- fprintf(stdout, "%s\n", fields[field_location]); Err bitreich.org 70 i- rows++; Err bitreich.org 70 i- } Err bitreich.org 70 i- Err bitreich.org 70 i- assert(field_categories < n); Err bitreich.org 70 i- if (field_categories > 0 && fields[field_categories][0] != '\0') { Err bitreich.org 70 i- assert(field_summary > FIELD_OTHER); Err bitreich.org 70 i- if (rows > 0) { Err bitreich.org 70 i- print_date(NULL); Err bitreich.org 70 i- print_time(NULL); Err bitreich.org 70 i- } Err bitreich.org 70 i- fprintf(stdout, "%s\n", fields[field_categories]); Err bitreich.org 70 i+ print_header1(&ctx->beg, &beg); Err bitreich.org 70 i+ print_row(ctx, fields, i++); Err bitreich.org 70 i+ print_header2(&beg, &end); Err bitreich.org 70 i+ print_row(ctx, fields, i++); Err bitreich.org 70 i+ while (i < ctx->fieldnum) { Err bitreich.org 70 i+ print_header3(); Err bitreich.org 70 i+ print_row(ctx, fields, i++); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i ctx->beg = beg; Err bitreich.org 70 i ctx->end = end; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i-void Err bitreich.org 70 i-set_fields_num(char **fields, size_t n) Err bitreich.org 70 i+static void Err bitreich.org 70 i+tsv_to_agenda(AgendaCtx *ctx, FILE *fp) Err bitreich.org 70 i { Err bitreich.org 70 i- struct { char *name; size_t *var; } map[] = { Err bitreich.org 70 i- { "CATEGORIES", &field_categories }, Err bitreich.org 70 i- { "LOCATION", &field_location }, Err bitreich.org 70 i- { "SUMMARY", &field_summary }, Err bitreich.org 70 i- { NULL, NULL } Err bitreich.org 70 i- }; Err bitreich.org 70 i- Err bitreich.org 70 i- debug("n=%zd", n); Err bitreich.org 70 i- for (size_t i1 = FIELD_OTHER; i1 < n; i1++) Err bitreich.org 70 i- for (size_t i2 = 0; map[i2].name != NULL; i2++) Err bitreich.org 70 i- if (strcasecmp(fields[i1], map[i2].name) == 0) Err bitreich.org 70 i- *map[i2].var = i1; Err bitreich.org 70 i- if (field_summary < FIELD_OTHER) Err bitreich.org 70 i- err(1, "missing column SUMMARY"); Err bitreich.org 70 i-} Err bitreich.org 70 i+ char *ln1 = NULL, *ln2 = NULL; Err bitreich.org 70 i+ size_t sz1 = 0, sz2 = 0; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (ctx->linenum == 0) { Err bitreich.org 70 i+ char *fields[FIELD_MAX]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ctx->linenum++; Err bitreich.org 70 i+ if (getline(&ln1, &sz1, fp) < 0) Err bitreich.org 70 i+ err(1, "reading stdin: %s", strerror(errno)); Err bitreich.org 70 i+ if (feof(fp)) Err bitreich.org 70 i+ err(1, "empty input"); Err bitreich.org 70 i+ Err bitreich.org 70 i+ strchomp(ln1); Err bitreich.org 70 i+ ctx->fieldnum = strsplit(ln1, fields, FIELD_MAX, "\t"); Err bitreich.org 70 i+ if (ctx->fieldnum == FIELD_MAX) Err bitreich.org 70 i+ err(1, "line 1: too many fields"); Err bitreich.org 70 i+ if (ctx->fieldnum < FIELD_OTHER) Err bitreich.org 70 i+ err(1, "line 1: not enough input columns"); Err bitreich.org 70 i+ if (strcasecmp(fields[0], "TYPE") != 0) Err bitreich.org 70 i+ err(1, "line 1: 1st column is not \"TYPE\""); Err bitreich.org 70 i+ if (strcasecmp(fields[1], "START") != 0) Err bitreich.org 70 i+ err(1, "line 1: 2nd column is not \"START\""); Err bitreich.org 70 i+ if (strcasecmp(fields[2], "END") != 0) Err bitreich.org 70 i+ err(1, "line 1: 3rd column is not \"END\""); Err bitreich.org 70 i+ if (strcasecmp(fields[3], "RECUR") != 0) Err bitreich.org 70 i+ err(1, "line 1: 4th column is not \"RECUR\""); Err bitreich.org 70 i+ } Err bitreich.org 70 i Err bitreich.org 70 i-ssize_t Err bitreich.org 70 i-tsv_getline(char **fields, size_t max, char **line, size_t *sz, FILE *fp) Err bitreich.org 70 i-{ Err bitreich.org 70 i- char *s; Err bitreich.org 70 i- size_t n = 0; Err bitreich.org 70 i+ for (;;) { Err bitreich.org 70 i+ char *fields[FIELD_MAX]; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ctx->linenum++; Err bitreich.org 70 i+ if (getline(&ln2, &sz2, fp) < 0) Err bitreich.org 70 i+ err(1, "reading stdin: %s", strerror(errno)); Err bitreich.org 70 i+ if (feof(fp)) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ Err bitreich.org 70 i+ strchomp(ln2); Err bitreich.org 70 i+ if (strsplit(ln2, fields, FIELD_MAX, "\t") != ctx->fieldnum) Err bitreich.org 70 i+ err(1, "line %zd: bad number of columns", Err bitreich.org 70 i+ ctx->linenum, strerror(errno)); Err bitreich.org 70 i Err bitreich.org 70 i- if (getline(line, sz, fp) <= 0) Err bitreich.org 70 i- return ferror(fp) ? -1 : 0; Err bitreich.org 70 i- s = *line; Err bitreich.org 70 i- strchomp(s); Err bitreich.org 70 i+ fputc('\n', stdout); Err bitreich.org 70 i+ print(ctx, fields); Err bitreich.org 70 i+ } Err bitreich.org 70 i+ fputc('\n', stdout); Err bitreich.org 70 i Err bitreich.org 70 i- do { Err bitreich.org 70 i- if (n >= max) Err bitreich.org 70 i- return errno=E2BIG, -1; Err bitreich.org 70 i- } while ((fields[n++] = strsep(&s, "\t")) != NULL); Err bitreich.org 70 i+ free(ln1); Err bitreich.org 70 i+ free(ln2); Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i- return n - 1; Err bitreich.org 70 i+static void Err bitreich.org 70 i+usage(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ fprintf(stderr, "usage: %s [-f fromdate] [-t todate]\n", arg0); Err bitreich.org 70 i+ exit(1); 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 AgendaCtx ctx = {0}; Err bitreich.org 70 i- ssize_t nfield, n; Err bitreich.org 70 i- size_t sz = 0; Err bitreich.org 70 i- char *line = NULL, *fields[FIELDS_MAX]; Err bitreich.org 70 i+ char c; Err bitreich.org 70 i Err bitreich.org 70 i- arg0 = *argv; Err bitreich.org 70 i- Err bitreich.org 70 i- if (pledge("stdio", "") < 0) Err bitreich.org 70 i- err(1, "pledge: %s", strerror(errno)); Err bitreich.org 70 i+ if ((flag_from = time(NULL)) == (time_t)-1) Err bitreich.org 70 i+ err(1, "time: %s", strerror(errno)); Err bitreich.org 70 i Err bitreich.org 70 i- nfield = tsv_getline(fields, FIELDS_MAX, &line, &sz, stdin); Err bitreich.org 70 i- if (nfield == -1) Err bitreich.org 70 i- err(1, "reading stdin: %s", strerror(errno)); Err bitreich.org 70 i- if (nfield == 0) Err bitreich.org 70 i- err(1, "empty input"); Err bitreich.org 70 i- if (nfield < FIELD_OTHER) Err bitreich.org 70 i- err(1, "not enough input columns"); Err bitreich.org 70 i- Err bitreich.org 70 i- set_fields_num(fields, nfield); Err bitreich.org 70 i- Err bitreich.org 70 i- for (size_t num = 1;; num++) { Err bitreich.org 70 i- n = tsv_getline(fields, FIELDS_MAX, &line, &sz, stdin); Err bitreich.org 70 i- if (n < 0) Err bitreich.org 70 i- err(1, "line %zd: reading stdin: %s", num, strerror(errno)); Err bitreich.org 70 i- if (n == 0) Err bitreich.org 70 i+ arg0 = *argv; Err bitreich.org 70 i+ while ((c = getopt(argc, argv, "f:t:")) > 0) { Err bitreich.org 70 i+ char const *e; Err bitreich.org 70 i+ Err bitreich.org 70 i+ switch (c) { Err bitreich.org 70 i+ case 'f': Err bitreich.org 70 i+ flag_from = strtonum(optarg, INT64_MIN, INT64_MAX, &e); Err bitreich.org 70 i+ if (e != NULL) Err bitreich.org 70 i+ err(1, "fromdate value %s is %s", optarg, e); Err bitreich.org 70 i break; Err bitreich.org 70 i- if (n != nfield) Err bitreich.org 70 i- err(1, "line %zd: had %lld columns, wanted %lld", Err bitreich.org 70 i- num, n, nfield); Err bitreich.org 70 i- Err bitreich.org 70 i- print(&ctx, fields, n); Err bitreich.org 70 i+ case 't': Err bitreich.org 70 i+ flag_to = strtonum(optarg, INT64_MIN, INT64_MAX, &e); Err bitreich.org 70 i+ if (e != NULL) Err bitreich.org 70 i+ err(1, "todate value %s is %s", optarg, e); Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ default: Err bitreich.org 70 i+ usage(); Err bitreich.org 70 i+ } Err bitreich.org 70 i } Err bitreich.org 70 i- fputc('\n', stdout); Err bitreich.org 70 i+ argc -= optind; Err bitreich.org 70 i+ argv += optind; Err bitreich.org 70 i Err bitreich.org 70 i- free(line); Err bitreich.org 70 i+ if (pledge("stdio", "") < 0) Err bitreich.org 70 i+ err(1, "pledge: %s", strerror(errno)); Err bitreich.org 70 i Err bitreich.org 70 i+ tsv_to_agenda(&ctx, stdin); Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 1diff --git a/tsv2ics.awk b/tsv2ics.awk /scm/ics2txt/file/tsv2ics.awk.gph bitreich.org 70 i@@ -0,0 +1,106 @@ Err bitreich.org 70 i+#!/usr/bin/awk -f Err bitreich.org 70 i+ Err bitreich.org 70 i+function isleap(year) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return (year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0) Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+function mdays(mon, year) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return (mon == 2) ? (28 + isleap(year)) : (30 + (mon + (mon > 7)) % 2) Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+# Split the time in seconds since epoch into a table, with fields Err bitreich.org 70 i+# named as with gmtime(3): tm["year"], tm["mon"], tm["mday"], Err bitreich.org 70 i+# tm["hour"], tm["min"], tm["sec"] Err bitreich.org 70 i+function gmtime(sec, tm, Err bitreich.org 70 i+ s) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ tm["year"] = 1970 Err bitreich.org 70 i+ while (sec >= (s = 86400 * (365 + isleap(tm["year"])))) { Err bitreich.org 70 i+ tm["year"]++ Err bitreich.org 70 i+ sec -= s Err bitreich.org 70 i+ } Err bitreich.org 70 i+ tm["mon"] = 1 Err bitreich.org 70 i+ while (sec >= (s = 86400 * mdays(tm["mon"], tm["year"]))) { Err bitreich.org 70 i+ tm["mon"]++ Err bitreich.org 70 i+ sec -= s Err bitreich.org 70 i+ } Err bitreich.org 70 i+ tm["mday"] = 1 Err bitreich.org 70 i+ while (sec >= (s = 86400)) { Err bitreich.org 70 i+ tm["mday"]++ Err bitreich.org 70 i+ sec -= s Err bitreich.org 70 i+ } Err bitreich.org 70 i+ tm["hour"] = 0 Err bitreich.org 70 i+ while (sec >= 3600) { Err bitreich.org 70 i+ tm["hour"]++ Err bitreich.org 70 i+ sec -= 3600 Err bitreich.org 70 i+ } Err bitreich.org 70 i+ tm["min"] = 0 Err bitreich.org 70 i+ while (sec >= 60) { Err bitreich.org 70 i+ tm["min"]++ Err bitreich.org 70 i+ sec -= 60 Err bitreich.org 70 i+ } Err bitreich.org 70 i+ tm["sec"] = sec Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+BEGIN { Err bitreich.org 70 i+ FS = "\t" Err bitreich.org 70 i+ Err bitreich.org 70 i+ DTSTART["VEVENT"] = "DTSTART" Err bitreich.org 70 i+ DTEND["VEVENT"] = "DTEND" Err bitreich.org 70 i+ Err bitreich.org 70 i+ DTEND["VTODO"] = "DUE" Err bitreich.org 70 i+ Err bitreich.org 70 i+ DTSTART["VJOURNAL"] = "DTSTAMP" Err bitreich.org 70 i+ Err bitreich.org 70 i+ DTSTART["VFREEBUSY"] = "DTSTART" Err bitreich.org 70 i+ DTEND["VFREEBUSY"] = "DTEND" Err bitreich.org 70 i+ Err bitreich.org 70 i+ DTSTART["VALARM"] = "DTSTART" Err bitreich.org 70 i+ Err bitreich.org 70 i+ print "BEGIN:VCALENDAR" Err bitreich.org 70 i+ print "VERSION:2.0" Err bitreich.org 70 i+ print "CALSCALE:GREGORIAN" Err bitreich.org 70 i+ print "METHOD:PUBLISH" Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+NR == 1 { Err bitreich.org 70 i+ if ($1 != "TYPE" || $2 != "START" || $3 != "END" || $4 != "RECUR") { Err bitreich.org 70 i+ print "tsv2ics: invalid column names on first line" >/dev/stderr Err bitreich.org 70 i+ exit(EXIT = 1) Err bitreich.org 70 i+ } Err bitreich.org 70 i+ for (i = 1; i <= NF; i++) { Err bitreich.org 70 i+ FIELD[$i] = i Err bitreich.org 70 i+ NAME[i] = $i Err bitreich.org 70 i+ } Err bitreich.org 70 i+ next Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+{ Err bitreich.org 70 i+ type = $FIELD["TYPE"] Err bitreich.org 70 i+ print "BEGIN:"type Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (type in DTSTART) { Err bitreich.org 70 i+ gmtime($FIELD["START"] + offset, tm) Err bitreich.org 70 i+ printf "%s:%04d%02d%02dT%02d%02d00Z\n", DTSTART[type], Err bitreich.org 70 i+ tm["year"], tm["mon"], tm["mday"], tm["hour"], tm["min"] Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (type in DTEND) { Err bitreich.org 70 i+ gmtime($FIELD["END"] + offset, tm) Err bitreich.org 70 i+ printf "%s:%04d%02d%02dT%02d%02d00Z\n", DTEND[type], Err bitreich.org 70 i+ tm["year"], tm["mon"], tm["mday"], tm["hour"], tm["min"] Err bitreich.org 70 i+ } Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (i = 5; i in NAME; i++) Err bitreich.org 70 i+ print$NAME[i]":"$i Err bitreich.org 70 i+ Err bitreich.org 70 i+ print "END:"type Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+END { Err bitreich.org 70 i+ if (EXIT) exit(EXIT) Err bitreich.org 70 i+ print "" Err bitreich.org 70 i+ print "END:VCALENDAR" Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/util.c b/util.c /scm/ics2txt/file/util.c.gph bitreich.org 70 i@@ -1,4 +1,5 @@ Err bitreich.org 70 i #include "util.h" 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@@ -123,6 +124,19 @@ strappend(char **dp, char const *s) Err bitreich.org 70 i return *dp; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+size_t Err bitreich.org 70 i+strsplit(char *s, char **array, size_t len, char const *sep) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ size_t i; Err bitreich.org 70 i+ Err bitreich.org 70 i+ assert(len > 0); Err bitreich.org 70 i+ for (i = 0; i < len; i++) Err bitreich.org 70 i+ if ((array[i] = strsep(&s, sep)) == NULL) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ array[len - 1] = NULL; Err bitreich.org 70 i+ return i; 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 1diff --git a/util.h b/util.h /scm/ics2txt/file/util.h.gph bitreich.org 70 i@@ -2,9 +2,12 @@ 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 #include Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i+#define LEN(x) (sizeof (x) / sizeof *(x)) Err bitreich.org 70 i+ Err bitreich.org 70 i /** logging **/ Err bitreich.org 70 i extern char *arg0; Err bitreich.org 70 i void err(int, char const *fmt, ...); Err bitreich.org 70 i@@ -18,6 +21,7 @@ void strchomp(char *); Err bitreich.org 70 i char *strappend(char **, char const *); Err bitreich.org 70 i size_t strlcat(char *, char const *, size_t); Err bitreich.org 70 i long long strtonum(const char *, long long, long long, const char **); Err bitreich.org 70 i+size_t strsplit(char *, char **, size_t, char const *); Err bitreich.org 70 i Err bitreich.org 70 i /** memory **/ Err bitreich.org 70 i void *reallocarray(void *, size_t, size_t); Err bitreich.org 70 .