SMOLNET PORTAL home about changes
iinitial C implementation - 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 94bccd0b9ea7049ebeec4fcf2416f6f0b7d221b5	/scm/ics2txt/commit/94bccd0b9ea7049ebeec4fcf2416f6f0b7d221b5.gph	bitreich.org	70
1parent 78e0184b4deb29669bfde9a66fc945968845ced8	/scm/ics2txt/commit/78e0184b4deb29669bfde9a66fc945968845ced8.gph	bitreich.org	70
hAuthor: Josuah Demangeon <me@josuah.net>	URL:mailto:me@josuah.net	bitreich.org	70
iDate:   Sat, 27 Jun 2020 20:31:09 +0200	Err	bitreich.org	70
i	Err	bitreich.org	70
iinitial C implementation	Err	bitreich.org	70
i	Err	bitreich.org	70
iDiffstat:	Err	bitreich.org	70
i  A .gitignore                          |       2 ++	Err	bitreich.org	70
i  M Makefile                            |      24 +++++++++++++++++++-----	Err	bitreich.org	70
i  A bin/ics2tsv                         |     141 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  R ics2txt -> bin/ics2txt              |       0 	Err	bitreich.org	70
i  R tcal2tsv -> bin/tcal2tsv            |       0 	Err	bitreich.org	70
i  R tsv2ics -> bin/tsv2ics              |       0 	Err	bitreich.org	70
i  A bin/tsv2tcal                        |      91 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A doc/index.md                        |      11 +++++++++++	Err	bitreich.org	70
i  D ics2tsv                             |     138 ------------------------------	Err	bitreich.org	70
i  A ics2tsv.c                           |      62 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/ical.c                          |     108 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/ical.h                          |      25 +++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/log.c                           |      89 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/log.h                           |      15 +++++++++++++++	Err	bitreich.org	70
i  A src/map.c                           |     102 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/map.h                           |      23 +++++++++++++++++++++++	Err	bitreich.org	70
i  A src/util.c                          |      74 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/util.h                          |      13 +++++++++++++	Err	bitreich.org	70
i  D tsv2tcal                            |      91 -------------------------------	Err	bitreich.org	70
i	Err	bitreich.org	70
i19 files changed, 775 insertions(+), 234 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@@ -0,0 +1,2 @@	Err	bitreich.org	70
i+*.o	Err	bitreich.org	70
i+ics2tsv	Err	bitreich.org	70
1diff --git a/Makefile b/Makefile	/scm/ics2txt/file/Makefile.gph	bitreich.org	70
i@@ -1,23 +1,37 @@	Err	bitreich.org	70
i NAME = ics2txt	Err	bitreich.org	70
i VERSION = 0.1	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-BIN = ics2tsv tsv2tcal tcal2tsv tsv2ics ics2txt	Err	bitreich.org	70
i-	Err	bitreich.org	70
i+W = -Wall -Wextra -std=c99 --pedantic	Err	bitreich.org	70
i+I = -Isrc	Err	bitreich.org	70
i+D = -D_POSIX_C_SOURCE=200811L -DVERSION='"${VERSION}"'	Err	bitreich.org	70
i+CFLAGS = $I $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 = src/ical.c src/map.c src/util.c src/log.c	Err	bitreich.org	70
i+HDR = src/ical.h src/map.h src/util.h src/log.h	Err	bitreich.org	70
i+OBJ = ${SRC:.c=.o}	Err	bitreich.org	70
i+BIN = ics2tsv	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+${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 ${NAME}-${VERSION} *.gz	Err	bitreich.org	70
i+        rm -rf *.o */*.o ${BIN} ${NAME}-${VERSION} *.gz	Err	bitreich.org	70
i 	Err	bitreich.org	70
i install:	Err	bitreich.org	70
i         mkdir -p ${DESTDIR}$(PREFIX)/bin	Err	bitreich.org	70
i-        cp $(BIN) ${DESTDIR}$(PREFIX)/bin	Err	bitreich.org	70
i+        cp bin/* $(BIN) ${DESTDIR}$(PREFIX)/bin	Err	bitreich.org	70
i         mkdir -p ${DESTDIR}$(MANPREFIX)/man1	Err	bitreich.org	70
i         cp doc/*.1 ${DESTDIR}$(MANPREFIX)/man1	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 doc ${BIN} ${NAME}-${VERSION}	Err	bitreich.org	70
i+        cp -r README Makefile doc bin ${SRC} ${NAME}-${VERSION}	Err	bitreich.org	70
i         tar -cf - ${NAME}-${VERSION} | gzip -c >${NAME}-${VERSION}.tar.gz	Err	bitreich.org	70
1diff --git a/bin/ics2tsv b/bin/ics2tsv	/scm/ics2txt/file/bin/ics2tsv.gph	bitreich.org	70
i@@ -0,0 +1,141 @@	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_tzid(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/ics2txt b/bin/ics2txt	/scm/ics2txt/file/bin/ics2txt.gph	bitreich.org	70
1diff --git a/tcal2tsv b/bin/tcal2tsv	/scm/ics2txt/file/bin/tcal2tsv.gph	bitreich.org	70
1diff --git a/tsv2ics b/bin/tsv2ics	/scm/ics2txt/file/bin/tsv2ics.gph	bitreich.org	70
1diff --git a/bin/tsv2tcal b/bin/tsv2tcal	/scm/ics2txt/file/bin/tsv2tcal.gph	bitreich.org	70
i@@ -0,0 +1,91 @@	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 gmtime(sec, tm)	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+function localtime(sec, tm,	Err	bitreich.org	70
i+        tz, h, m)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        return gmtime(sec + TZ, tm)	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+BEGIN {	Err	bitreich.org	70
i+        "exec date +%z" | getline tz	Err	bitreich.org	70
i+        close("exec date +%z")	Err	bitreich.org	70
i+        TZ = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        print("TZ" tz)	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        FS = "\t"	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+	Err	bitreich.org	70
i+        localtime(ev["beg"] + offset, tm)	Err	bitreich.org	70
i+        printf("%04d-%02d-%02d %02d:%02d\n",	Err	bitreich.org	70
i+          tm["year"], tm["mon"], tm["mday"], tm["hour"], tm["min"])	Err	bitreich.org	70
i+        delete ev["beg"]	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        localtime(ev["end"] + offset, tm)	Err	bitreich.org	70
i+        printf("%04d-%02d-%02d %02d:%02d\n",	Err	bitreich.org	70
i+          tm["year"], tm["mon"], tm["mday"], tm["hour"], tm["min"])	Err	bitreich.org	70
i+        delete ev["end"]	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (i = 1; i <= NF; i++) {	Err	bitreich.org	70
i+                if (name[i] in ev && ev[name[i]])	Err	bitreich.org	70
i+                        printf(" %s: %s\n", name[i], ev[name[i]])	Err	bitreich.org	70
i+        }	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+}	Err	bitreich.org	70
1diff --git a/doc/index.md b/doc/index.md	/scm/ics2txt/file/doc/index.md.gph	bitreich.org	70
i@@ -0,0 +1,11 @@	Err	bitreich.org	70
i+ics2txt	Err	bitreich.org	70
i+=======	Err	bitreich.org	70
i+Set of tools to work with the popular iCalendar format and converting to even	Err	bitreich.org	70
i+simpler TSV and text forms.	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+Parsing have been tested with the following input formats (sample account	Err	bitreich.org	70
i+created for testing):	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+* Zoom meetings generated events	Err	bitreich.org	70
i+* FOSDEM events, like <https://fosdem.org/2020/schedule/ical>;	Err	bitreich.org	70
i+* Google Calendar	Err	bitreich.org	70
1diff --git a/ics2tsv b/ics2tsv	/scm/ics2txt/file/ics2tsv.gph	bitreich.org	70
i@@ -1,138 +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_to_epoch(content, param,	Err	bitreich.org	70
i-        tz, cmd)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        tz = (param["TZID"] ? param["TZID"] : vcalendar["TZID"])	Err	bitreich.org	70
i-        gsub("'", "", tz)	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        cmd = "TZ='"tz"' date +%z" 	Err	bitreich.org	70
i-        cmd | getline tz	Err	bitreich.org	70
i-        close(cmd)	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        tz = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60	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"], 8, 2)	Err	bitreich.org	70
i-        tm["hour"] = substr(content["value"], 12, 2)	Err	bitreich.org	70
i-        tm["min"] = substr(content["value"], 15, 2)	Err	bitreich.org	70
i-        tm["sec"] = substr(content["value"], 18, 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",	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-                vcalendar[content["name"]] = 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/ics2tsv.c b/ics2tsv.c	/scm/ics2txt/file/ics2tsv.c.gph	bitreich.org	70
i@@ -0,0 +1,62 @@	Err	bitreich.org	70
i+#include <stdio.h>	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+int	Err	bitreich.org	70
i+print_ical_to_tsv(FILE *fp)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        struct ical_contentline contentline;	Err	bitreich.org	70
i+        char *line = NULL;	Err	bitreich.org	70
i+        size_t sz = 0;	Err	bitreich.org	70
i+        ssize_t r;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        ical_init_contentline(&contentline);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        while ((r = ical_read_line(&line, &sz, fp)) > 0) {	Err	bitreich.org	70
i+                debug("readling line \"%s\"", line);	Err	bitreich.org	70
i+                if (ical_parse_contentline(&contentline, line) < 0)	Err	bitreich.org	70
i+                        die("parsing line \"%s\"", line);	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+        return r;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+print_header(void)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        char *fields[] = { "", NULL };	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        printf("%s\t%s", "beg", "end");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (char **f = fields; *f != NULL; f++) {	Err	bitreich.org	70
i+                fprintf(stdout, "\t%s", *f);	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+        fprintf(stdout, "\n");	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+        print_header();	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        log_arg0 = *argv++;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if (*argv == NULL) {	Err	bitreich.org	70
i+                if (print_ical_to_tsv(stdin) < 0)	Err	bitreich.org	70
i+                        die("converting stdin");	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+                FILE *fp;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                info("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_to_tsv(fp) < 0)	Err	bitreich.org	70
i+                        die("converting %s", *argv);	Err	bitreich.org	70
i+                fclose(fp);	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/src/ical.c b/src/ical.c	/scm/ics2txt/file/src/ical.c.gph	bitreich.org	70
i@@ -0,0 +1,108 @@	Err	bitreich.org	70
i+#include "ical.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <errno.h>	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include "util.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+ical_read_line(char **line, size_t *sz, FILE *fp)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        ssize_t r;	Err	bitreich.org	70
i+        char *tail = NULL;	Err	bitreich.org	70
i+        size_t tail_sz = 0;	Err	bitreich.org	70
i+        int c, ret = -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if ((r = getline(line, sz, fp)) <= 0)	Err	bitreich.org	70
i+                return r;	Err	bitreich.org	70
i+        strchomp(*line);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (;;) {	Err	bitreich.org	70
i+                if ((c = fgetc(fp)) == EOF) {	Err	bitreich.org	70
i+                        ret = ferror(fp) ? -1 : 0;	Err	bitreich.org	70
i+                        goto end;	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+                if (c != ' ')	Err	bitreich.org	70
i+                        break;	Err	bitreich.org	70
i+                if ((r = getline(&tail, &tail_sz, fp)) <= 0) {	Err	bitreich.org	70
i+                        ret = r;	Err	bitreich.org	70
i+                        goto end;	Err	bitreich.org	70
i+                }	Err	bitreich.org	70
i+                strchomp(tail);	Err	bitreich.org	70
i+                if (strappend(line, tail) < 0)	Err	bitreich.org	70
i+                        goto end;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        ret = 1;	Err	bitreich.org	70
i+end:	Err	bitreich.org	70
i+        free(tail);	Err	bitreich.org	70
i+        ungetc(c, fp);	Err	bitreich.org	70
i+        return ret;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int	Err	bitreich.org	70
i+ical_parse_contentline(struct ical_contentline *contentline, char *line)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        char *column, *equal, *param, *cp;	Err	bitreich.org	70
i+        size_t sz;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        debug("0");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if ((column = strchr(line, ':')) == NULL)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+        *column = '\0';	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        {	Err	bitreich.org	70
i+                size_t len;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                debug("1.1");	Err	bitreich.org	70
i+                len = strlen(column + 1);	Err	bitreich.org	70
i+                debug("1.2");	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+        	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if ((contentline->value = strdup(column + 1)) == NULL)	Err	bitreich.org	70
i+                return -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        debug("2");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        cp = strchr(line, ';');	Err	bitreich.org	70
i+        cp = (cp == NULL) ? (NULL) : (cp + 1);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        debug("3");	Err	bitreich.org	70
i+	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 -1;	Err	bitreich.org	70
i+                *equal = '\0';	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                if (map_set(&contentline->param, param, equal + 1) < 0)	Err	bitreich.org	70
i+                        return -1;	Err	bitreich.org	70
i+        }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        debug("4");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        sz = sizeof(contentline->name);	Err	bitreich.org	70
i+        if (strlcpy(contentline->name, line, sz) >= sz)	Err	bitreich.org	70
i+                return errno=EMSGSIZE, -1;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        debug("5");	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+void	Err	bitreich.org	70
i+ical_init_contentline(struct ical_contentline *contentline)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        memset(contentline, 0, sizeof(*contentline));	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+ical_free_contentline(struct ical_contentline *contentline)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        map_free(&contentline->param);	Err	bitreich.org	70
i+        free(contentline->value);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/src/ical.h b/src/ical.h	/scm/ics2txt/file/src/ical.h.gph	bitreich.org	70
i@@ -0,0 +1,25 @@	Err	bitreich.org	70
i+#ifndef ICAL_H	Err	bitreich.org	70
i+#define ICAL_H	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <time.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include "map.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+struct ical_vevent {	Err	bitreich.org	70
i+        time_t beg, end;	Err	bitreich.org	70
i+        struct map map;	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+struct ical_contentline {	Err	bitreich.org	70
i+        char name[32], *value;	Err	bitreich.org	70
i+        struct map param;	Err	bitreich.org	70
i+};	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+/** src/ical.c **/	Err	bitreich.org	70
i+int ical_read_line(char **line, size_t *sz, FILE *fp);	Err	bitreich.org	70
i+int ical_parse_contentline(struct ical_contentline *contentline, char *line);	Err	bitreich.org	70
i+void ical_init_contentline(struct ical_contentline *contentline);	Err	bitreich.org	70
i+void ical_free_contentline(struct ical_contentline *contentline);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#endif	Err	bitreich.org	70
1diff --git a/src/log.c b/src/log.c	/scm/ics2txt/file/src/log.c.gph	bitreich.org	70
i@@ -0,0 +1,89 @@	Err	bitreich.org	70
i+#include "log.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <assert.h>	Err	bitreich.org	70
i+#include <string.h>	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 <errno.h>	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <stdlib.h>	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/src/log.h b/src/log.h	/scm/ics2txt/file/src/log.h.gph	bitreich.org	70
i@@ -0,0 +1,15 @@	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 <stdarg.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+/** src/log.c **/	Err	bitreich.org	70
i+int log_level;	Err	bitreich.org	70
i+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/src/map.c b/src/map.c	/scm/ics2txt/file/src/map.c.gph	bitreich.org	70
i@@ -0,0 +1,102 @@	Err	bitreich.org	70
i+#include "map.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	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+        debug("%s: key=%s len=%zd", __func__, key, map->len);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        for (i = 0; i < map->len; i++) {	Err	bitreich.org	70
i+                int cmp = strcmp(key, map->entry[i].key);	Err	bitreich.org	70
i+                debug("cmp(%s,%s)=%d", key, map->entry[i].key, cmp);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+                if (cmp == 0) {	Err	bitreich.org	70
i+                        map->entry[i].value = value;	Err	bitreich.org	70
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+        e = map->entry + map->len - 1 - 1;	Err	bitreich.org	70
i+        for (; e >= insert; e--)	Err	bitreich.org	70
i+                e[1].key = e[0].key;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        if ((insert->key = strdup(key)) == NULL)	Err	bitreich.org	70
i+                return -1;	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_free_values(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[map->len - 1].value);	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)	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[map->len - 1].key);	Err	bitreich.org	70
i+        free(map->entry);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/src/map.h b/src/map.h	/scm/ics2txt/file/src/map.h.gph	bitreich.org	70
i@@ -0,0 +1,23 @@	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 <stddef.h>	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_free_values(struct map *map);	Err	bitreich.org	70
i+void map_free(struct map *map);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#endif	Err	bitreich.org	70
1diff --git a/src/util.c b/src/util.c	/scm/ics2txt/file/src/util.c.gph	bitreich.org	70
i@@ -0,0 +1,74 @@	Err	bitreich.org	70
i+#include "util.h"	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <errno.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+#include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	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+{	Err	bitreich.org	70
i+        size_t len, cpy;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        cpy = ((len = strlen(str)) > sz) ? (sz) : (len);	Err	bitreich.org	70
i+        memcpy(buf, str, cpy + 1);	Err	bitreich.org	70
i+        buf[sz - 1] = '\0';	Err	bitreich.org	70
i+        return len;	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+{	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+                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+                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+        } else {	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+	Err	bitreich.org	70
i+void	Err	bitreich.org	70
i+strchomp(char *line)	Err	bitreich.org	70
i+{	Err	bitreich.org	70
i+        size_t len;	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+        if (len > 0 && line[len - 1] == '\r')	Err	bitreich.org	70
i+                line[len-- - 1] = '\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+{	Err	bitreich.org	70
i+        size_t base_len, s_len;	Err	bitreich.org	70
i+        void *v;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+        base_len = strlen(*base_p);	Err	bitreich.org	70
i+        s_len = strlen(s);	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+                return -1;	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+        return 0;	Err	bitreich.org	70
i+}	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
i+        if (SIZE_MAX / len < sz)	Err	bitreich.org	70
i+                return errno=ERANGE, NULL;	Err	bitreich.org	70
i+        return realloc(buf, len * sz);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
1diff --git a/src/util.h b/src/util.h	/scm/ics2txt/file/src/util.h.gph	bitreich.org	70
i@@ -0,0 +1,13 @@	Err	bitreich.org	70
i+#ifndef UTIL_H	Err	bitreich.org	70
i+#define UTIL_H	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+#include <stddef.h>	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+	Err	bitreich.org	70
i+#endif	Err	bitreich.org	70
1diff --git a/tsv2tcal b/tsv2tcal	/scm/ics2txt/file/tsv2tcal.gph	bitreich.org	70
i@@ -1,91 +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 gmtime(sec, tm)	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-function localtime(sec, tm,	Err	bitreich.org	70
i-        tz, h, m)	Err	bitreich.org	70
i-{	Err	bitreich.org	70
i-        return gmtime(sec + TZ, tm)	Err	bitreich.org	70
i-}	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-BEGIN {	Err	bitreich.org	70
i-        "date +%z" | getline tz	Err	bitreich.org	70
i-        close("date +%z")	Err	bitreich.org	70
i-        TZ = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        print("TZ" tz)	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        FS = "\t"	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-	Err	bitreich.org	70
i-        localtime(ev["beg"] + offset, tm)	Err	bitreich.org	70
i-        printf("%04d-%02d-%02d %02d:%02d\n",	Err	bitreich.org	70
i-          tm["year"], tm["mon"], tm["mday"], tm["hour"], tm["min"])	Err	bitreich.org	70
i-        delete ev["beg"]	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        localtime(ev["end"] + offset, tm)	Err	bitreich.org	70
i-        printf("%04d-%02d-%02d %02d:%02d\n",	Err	bitreich.org	70
i-          tm["year"], tm["mon"], tm["mday"], tm["hour"], tm["min"])	Err	bitreich.org	70
i-        delete ev["end"]	Err	bitreich.org	70
i-	Err	bitreich.org	70
i-        for (i = 1; i <= NF; i++) {	Err	bitreich.org	70
i-                if (name[i] in ev && ev[name[i]])	Err	bitreich.org	70
i-                        printf(" %s: %s\n", name[i], ev[name[i]])	Err	bitreich.org	70
i-        }	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-}	Err	bitreich.org	70
.
Response: text/plain
Original URLgopher://bitreich.org/0/scm/ics2txt/commit/94bccd0b9ea704...
Content-Typetext/plain; charset=utf-8