aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2019-02-08 21:13:08 +0100
committerHugo Hörnquist <hugo@lysator.liu.se>2019-02-08 21:23:31 +0100
commit8e2d4025fc02e07866869a33ccc686f87389cb36 (patch)
tree2af14e4713d88024597add14106d565055317cb4
parentMade root of graphviz output gray. (diff)
downloadcalp-8e2d4025fc02e07866869a33ccc686f87389cb36.tar.gz
calp-8e2d4025fc02e07866869a33ccc686f87389cb36.tar.xz
V{calendar,event} merged into vcomponent, making it symmetic.
-rw-r--r--Makefile3
-rw-r--r--calendar.c9
-rw-r--r--calendar.h2
-rwxr-xr-xcode.scm29
-rw-r--r--graphs.c2
-rw-r--r--graphs.h2
-rw-r--r--main.c23
-rw-r--r--parse.c24
-rw-r--r--parse.h6
-rw-r--r--scheme.scm.c14
-rw-r--r--strbuf.c3
-rw-r--r--vcal.c69
-rw-r--r--vcal.h37
-rw-r--r--vector.h27
-rw-r--r--vector.inc.h51
15 files changed, 200 insertions, 101 deletions
diff --git a/Makefile b/Makefile
index 4d87fab2..8ce4608f 100644
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,6 @@ CFLAGS = $(CPPFLAGS) \
LDFLAGS = -fPIC $(shell guile-config link)
H_FILES = $(wildcard *.h)
-
C_FILES = $(wildcard *.c)
SCM_C_FILES = $(wildcard *.scm.c)
@@ -41,7 +40,7 @@ $(OBJDIR):
libguile-calendar.so: $(O_FILES)
$(CC) -shared -o $@ $^ $(LDFLAGS)
-CALDIR = cal
+CALDIR = test-cal/cal2/0c0f4d7090bacd99abe9ccca2d5baadf2afac709f7cb66454ef913c52a5ef096.ics
.SECONDARY += %.dot
%.dot: parse
./parse $(CALDIR) -g $@
diff --git a/calendar.c b/calendar.c
index 8fc4199b..477de492 100644
--- a/calendar.c
+++ b/calendar.c
@@ -17,6 +17,9 @@
/*
* Returns 0 if file has no extersion
+ *
+ * TODO this looks from the first point, it should look from the last
+ * point.
*/
int get_extension(const char* filename, char* ext, ssize_t max_len) {
int ext_idx = -1;
@@ -41,7 +44,7 @@ int get_extension(const char* filename, char* ext, ssize_t max_len) {
* TODO merge the code for files and dirs.
*/
-int parse_dir(vcalendar* cal, char* path) {
+int parse_dir(vcomponent* cal, char* path) {
DIR* dir = opendir(path);
struct dirent* d;
while ((d = readdir(dir)) != NULL) {
@@ -81,7 +84,7 @@ int parse_dir(vcalendar* cal, char* path) {
return 0;
}
-int read_vcalendar(vcalendar* cal, char* path) {
+int read_vcalendar(vcomponent* cal, char* path) {
struct stat statbuf;
if (stat (path, &statbuf) != 0) {
@@ -101,7 +104,7 @@ int read_vcalendar(vcalendar* cal, char* path) {
char ext[10];
int has_ext = get_extension(path, ext, 9);
if (! has_ext || strcmp(ext, "ics") != 0) {
- fprintf(stderr, "File doesn't have .ics extension.\n");
+ fprintf(stderr, "File doesn't have .ics extension. [%s]\n", ext);
exit(1);
}
diff --git a/calendar.h b/calendar.h
index e17d9281..c7484d05 100644
--- a/calendar.h
+++ b/calendar.h
@@ -3,6 +3,6 @@
#include "vcal.h"
-int read_vcalendar(vcalendar* cal, char* path);
+int read_vcalendar(vcomponent* cal, char* path);
#endif /* CALENDAR_H */
diff --git a/code.scm b/code.scm
index 6787f2f4..aef2772b 100755
--- a/code.scm
+++ b/code.scm
@@ -14,4 +14,31 @@
(do ((i 0 (1+ i)))
((>= i (calendar-size v)))
(format #t "~3d | ~a~%"
- i (calendar-get-attr v i "summary")))
+ (1+ i) (car (calendar-get-attr v i "summary"))))
+
+
+;;; ----------------------------------------
+
+;; (use-modules (srfi srfi-19))
+
+#|
+- Z at end means that it's in UTC time.
+- No mark at end means that it's in "local time".
+- `TZID` can be given as an parameter, specifiying the timezone by name
+
+See p. 46-47 of the RFC
+|#
+
+;; (string->date (calendar-get-attr v 0 "dtstart")
+;; "~Y~m~eT~k~M~S~z")
+;; => #<date nanosecond: 0 second: 0 minute: 15 hour: 12 day: 29 month: 1 year: 2019 zone-offset: 0>
+
+;; (string->date (calendar-get-attr v 0 "dtstart")
+;; "~Y~m~eT~k~M~S")
+;; => #<date nanosecond: 0 second: 0 minute: 15 hour: 12 day: 29 month: 1 year: 2019 zone-offset: 3600>
+
+;; (string-take-right (calendar-get-attr v 0 "dtstart") 1) ; => "Z"
+
+;; (string->date "20180311T133700"
+;; "~Y~m~eT~k~M~S") ; <-- Note missing ~z
+;; => #<date nanosecond: 0 second: 0 minute: 37 hour: 13 day: 11 month: 3 year: 2018 zone-offset: 3600>
diff --git a/graphs.c b/graphs.c
index 931b181b..ab49f4f1 100644
--- a/graphs.c
+++ b/graphs.c
@@ -2,7 +2,7 @@
#include <stdio.h>
-int create_graph (vevent* ev, char* filename) {
+int create_graph (vcomponent* ev, char* filename) {
FILE* f = fopen(filename, "w");
fputs("digraph {\n rankdir=LR;", f);
diff --git a/graphs.h b/graphs.h
index 399079b6..45c461af 100644
--- a/graphs.h
+++ b/graphs.h
@@ -3,6 +3,6 @@
#include "vcal.h"
-int create_graph (vevent* ev, char* filename);
+int create_graph (vcomponent* ev, char* filename);
#endif /* GRAPHS_H */
diff --git a/main.c b/main.c
index 2a3eb98d..c52b0554 100644
--- a/main.c
+++ b/main.c
@@ -28,35 +28,36 @@ int main (int argc, char* argv[argc]) {
exit (1);
}
- SNEW(vcalendar, cal);
+ SNEW(vcomponent, cal);
read_vcalendar(&cal, args.argv[0]);
arg_shift(&args);
if (args.argc == 0 || strcmp(args.argv[0], "-p") == 0) {
- printf("\nParsed calendar file containing [%lu] events\n",
- cal.n_events);
- for (size_t i = 0; i < cal.n_events; i++) {
- char* filename = cal.events[i]->filename;
+ printf("\nParsed calendar file containing [%u] events\n",
+ cal.components.length
+ );
+ for (size_t i = 0; i < cal.components.length; i++) {
+ char* filename = cal.components.items[i]->filename;
printf("%3lu | %s | %s\n",
i + 1,
filename,
- get_property(cal.events[i], "SUMMARY")->vals.cur->value->mem);
+ get_property(cal.components.items[i], "SUMMARY")->vals.cur->value->mem);
}
} else if (strcmp(args.argv[0], "-g") == 0) {
if (arg_shift(&args) == 0) {
- for (size_t i = 0; i < cal.n_events; i++) {
+ for (size_t i = 0; i < cal.components.length; i++) {
char target[0xFF];
target[0] = '\0';
strcat(target, "/tmp/dot/");
- strcat(target, cal.events[i]->filename);
+ strcat(target, cal.components.items[i]->filename);
strcat(target, ".dot");
- create_graph(cal.events[i], target);
+ create_graph(cal.components.items[i], target);
}
} else {
- create_graph(cal.events[0], args.argv[0]);
+ create_graph(cal.components.items[0], args.argv[0]);
}
}
- free_vcalendar(&cal);
+ FREE(vcomponent)(&cal);
}
diff --git a/parse.c b/parse.c
index ed113d47..651572bb 100644
--- a/parse.c
+++ b/parse.c
@@ -8,7 +8,7 @@
#include "err.h"
-int parse_file(char* fname, FILE* f, vcalendar* cal) {
+int parse_file(char* fname, FILE* f, vcomponent* cal) {
int segments = 1;
SNEW(strbuf, str, segments * SEGSIZE);
@@ -24,7 +24,7 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
int line = 0;
- vevent* ev = NULL;
+ vcomponent* ev = NULL;
SNEW(content_line, cline, keylen, vallen);
@@ -87,7 +87,7 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
switch (handle_kv(cal, ev, &cline, line, &ctx)) {
case s_event:
- RENEW(vevent, ev, fname);
+ RENEW(vcomponent, ev, fname);
break;
}
strbuf_soft_reset(&str);
@@ -151,10 +151,10 @@ int parse_file(char* fname, FILE* f, vcalendar* cal) {
* TODO Extend this to handle properties
*/
int handle_kv(
- vcalendar* cal,
- vevent* ev,
- content_line* cline,
- int line,
+ vcomponent* cal,
+ vcomponent* ev,
+ content_line* cline,
+ int line,
parse_ctx* ctx
) {
switch (ctx->scope) {
@@ -174,6 +174,11 @@ int handle_kv(
break;
case s_calendar:
+ /*
+ * TODO
+ * BEGIN's can be nested, extend this with a stack
+ * Apparently only VALARM can be nested.
+ */
if (strbuf_c(&cline->key, "BEGIN")) {
if (strbuf_c(cline->vals.cur->value, "VEVENT")) {
ctx->scope = s_event;
@@ -205,11 +210,12 @@ int handle_kv(
}
if (strbuf_c(&cline->key, "END")) {
if (strbuf_c(cline->vals.cur->value, "VEVENT")) {
- push_event(cal, ev);
+ PUSH(vcomponent)(cal, ev);
ctx->scope = s_calendar;
return ctx->scope;
} else {
- ERR_F("%s, %i", "Trying to end something, expected VEVENT", line);
+ ERR_F("Trying to end something, expected VEVENT, Got [%s]\n%s : %i",
+ cline->vals.cur->value->mem, ev->filename, line);
return -3;
}
} else {
diff --git a/parse.h b/parse.h
index 9d95bb22..ea60461f 100644
--- a/parse.h
+++ b/parse.h
@@ -33,13 +33,13 @@ typedef struct {
} parse_ctx;
int handle_kv(
- vcalendar* cal,
- vevent* ev,
+ vcomponent* cal,
+ vcomponent* ev,
content_line* cline,
int line,
parse_ctx* ctx
);
-int parse_file(char* fname, FILE* f, vcalendar* cal);
+int parse_file(char* fname, FILE* f, vcomponent* cal);
#endif /* PARSE_H */
diff --git a/scheme.scm.c b/scheme.scm.c
index a7ddc27d..2c06dd3d 100644
--- a/scheme.scm.c
+++ b/scheme.scm.c
@@ -17,10 +17,10 @@ SCM_DEFINE (make_calendar, "make-calendar", 1, 0, 0,
(SCM path),
"Loads a vdir iCalendar from the given path.")
{
- vcalendar* cal =
- (vcalendar*) scm_gc_malloc (
+ vcomponent* cal =
+ (vcomponent*) scm_gc_malloc (
sizeof(*cal), "calendar");
- INIT(vcalendar, cal);
+ INIT(vcomponent, cal);
char* p = scm_to_utf8_stringn(path, NULL);
read_vcalendar(cal, p);
@@ -40,9 +40,9 @@ SCM_DEFINE (calendar_get_attr, "calendar-get-attr", 3, 0, 0,
"Retuns the given attribute from the vevent object at index in calendar.")
{
scm_assert_foreign_object_type (calendar_type, calendar);
- vcalendar* cal = scm_foreign_object_ref (calendar, 0);
+ vcomponent* cal = scm_foreign_object_ref (calendar, 0);
- vevent* v = cal->events[scm_to_int(id)];
+ vcomponent* v = cal->components.items[scm_to_int(id)];
char* key = scm_to_utf8_stringn(scm_string_upcase(attr), NULL);
content_line* c = get_property (v, key);
free(key);
@@ -67,8 +67,8 @@ SCM_DEFINE (calendar_size, "calendar-size", 1, 0, 0,
"Returns number of events in a vcalendar.")
{
scm_assert_foreign_object_type (calendar_type, calendar);
- vcalendar* cal = scm_foreign_object_ref (calendar, 0);
- return scm_from_size_t (cal->n_events);
+ vcomponent* cal = scm_foreign_object_ref (calendar, 0);
+ return scm_from_size_t (cal->components.length);
}
void init_calendar () {
diff --git a/strbuf.c b/strbuf.c
index bf40d7fe..38aca4f4 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -51,7 +51,8 @@ FREE_F(strbuf) {
int strbuf_append(strbuf* s, char c) {
#ifdef SAFE_STR
if (s->len > s->alloc) {
- ERR("Not enough memmory allocated");
+ // printf("s->len = %i, s->alloc = %i\n", s->len, s->alloc);
+ // ERR("Not enough memmory allocated");
return 1;
}
#endif
diff --git a/vcal.c b/vcal.c
index c837c189..575d808d 100644
--- a/vcal.c
+++ b/vcal.c
@@ -11,14 +11,25 @@
#include "linked_list.inc.h"
#undef TYPE
-INIT_F(vevent, char* filename) {
+#define TYPE vcomponent
+#include "vector.inc.h"
+#undef TYPE
+
+INIT_F(vcomponent) {
+ return INIT(vcomponent, this, NULL);
+}
+
+INIT_F(vcomponent, char* filename) {
INIT(TRIE(content_line), &this->clines);
+ INIT(VECT(vcomponent), &this->components);
- this->filename = calloc(sizeof(*filename), strlen(filename) + 1);
- strcpy(this->filename, filename);
+ if (filename != NULL) {
+ this->filename = calloc(sizeof(*filename), strlen(filename) + 1);
+ strcpy(this->filename, filename);
+ }
- this->calendar = NULL;
+ this->parent = NULL;
return 0;
}
@@ -41,7 +52,7 @@ content_line* RESOLVE(content_line)
return dest;
}
-content_line* get_property (vevent* ev, char* key) {
+content_line* get_property (vcomponent* ev, char* key) {
return GET(TRIE(content_line))(&ev->clines, key);
}
@@ -65,63 +76,39 @@ INIT_F(content_line, int keylen, int vallen) {
return 0;
}
-
-int content_line_copy (content_line* dest, content_line* src) {
- DEEP_COPY(strbuf)(&dest->key, &src->key);
- DEEP_COPY(LLIST(strbuf))(&dest->vals, &src->vals);
+FREE_F(content_line) {
+ FREE(strbuf)(&this->key);
+ FREE(LLIST(strbuf))(&this->vals);
// TODO remaining fields
return 0;
}
-FREE_F(content_line) {
- FREE(strbuf)(&this->key);
- FREE(LLIST(strbuf))(&this->vals);
+int content_line_copy (content_line* dest, content_line* src) {
+ DEEP_COPY(strbuf)(&dest->key, &src->key);
+ DEEP_COPY(LLIST(strbuf))(&dest->vals, &src->vals);
// TODO remaining fields
return 0;
}
-FREE_F(vevent) {
+FREE_F(vcomponent) {
if (this->filename != NULL) free(this->filename);
if (FREE(TRIE(content_line))(&this->clines) != 0) {
- fprintf(stderr, "Error freeing vevent belonging to file \n %s \n",
+ fprintf(stderr, "Error freeing vcomponent belonging to file \n %s \n",
this->filename);
}
- return 0;
-}
-
-int push_event(vcalendar* cal, vevent* ev) {
+ FREE(VECT(vcomponent))(&this->components);
- ev->calendar = cal;
-
- /* Make sure that cal->eents is large enough */
- if (cal->n_events + 1 > cal->alloc) {
- cal->alloc <<= 1;
- cal->events = realloc(cal->events, sizeof(*cal->events) * cal->alloc);
- }
-
- cal->events[cal->n_events] = ev;
-
- cal->n_events++;
return 0;
}
-INIT_F(vcalendar) {
- this->alloc = 1;
- this->events = calloc(sizeof(*this->events), this->alloc);
- this->n_events = 0;
- return 0;
+int PUSH(vcomponent)(vcomponent* parent, vcomponent* child) {
+ return PUSH(VECT(vcomponent))(&parent->components, child);
}
-int free_vcalendar (vcalendar* cal) {
- for (size_t i = 0; i < cal->n_events; i++) {
- FFREE(vevent, cal->events[i]);
- }
- free (cal->events);
- return 0;
-}
+
diff --git a/vcal.h b/vcal.h
index b4b2c017..6b3667bf 100644
--- a/vcal.h
+++ b/vcal.h
@@ -27,6 +27,7 @@ typedef struct {
INIT_F(content_line);
INIT_F(content_line, int keylen, int vallen);
+FREE_F(content_line);
/*
* Resolves a collision in some form of structure (probably a hash-map
@@ -41,37 +42,33 @@ content_line* RESOLVE(content_line)
#include "trie.h"
#undef TYPE
-typedef struct s_vevent {
+typedef struct s_vcomponent vcomponent;
+
+#define TYPE vcomponent
+#include "vector.h"
+#undef TYPE
+
+struct s_vcomponent {
char* filename;
- struct s_vcalendar* calendar;
+ vcomponent* parent;
TRIE(content_line) clines;
-} vevent;
+ VECT(vcomponent) components;
+};
-INIT_F(vevent, char* filename);
+INIT_F(vcomponent);
+INIT_F(vcomponent, char* filename);
+FREE_F(vcomponent);
-FREE_F(content_line);
int content_line_copy (content_line* dest, content_line* src);
-content_line* get_property (vevent* ev, char* key);
-
-int add_content_line (vevent* ev, content_line* c);
-
-FREE_F(vevent);
-
-typedef struct s_vcalendar {
- size_t n_events;
- size_t alloc;
- vevent** events;
-} vcalendar;
+content_line* get_property (vcomponent* ev, char* key);
-INIT_F(vcalendar);
-int free_vcalendar (vcalendar* cal);
+int add_content_line (vcomponent* ev, content_line* c);
/*
* Appends ev to cal. Doesn't copy ev. So make sure that it wont go
* out of scope.
- * TODO change this into PUSH(VCALENDAR) (vevent*) ?
*/
-int push_event(vcalendar* cal, vevent* ev);
+int PUSH(vcomponent)(vcomponent*, vcomponent*);
#endif /* VCAL_H */
diff --git a/vector.h b/vector.h
new file mode 100644
index 00000000..f6acd66a
--- /dev/null
+++ b/vector.h
@@ -0,0 +1,27 @@
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include <stdlib.h>
+#include "macro.h"
+
+#define VECT(T) TEMPL(vect, T)
+
+#endif /* VECTOR_H */
+
+#ifdef TYPE
+
+typedef struct {
+ unsigned int length;
+ unsigned int alloc;
+ TYPE** items;
+} VECT(TYPE);
+
+INIT_F(VECT(TYPE));
+FREE_F(VECT(TYPE));
+
+int PUSH(VECT(TYPE))(VECT(TYPE)*, TYPE*);
+TYPE* GET(VECT(TYPE))(VECT(TYPE)*, unsigned int idx);
+int EMPTY(VECT(TYPE))(VECT(TYPE)*);
+unsigned int SIZE(VECT(TYPE))(VECT(TYPE)*);
+
+#endif /* TYPE */
diff --git a/vector.inc.h b/vector.inc.h
new file mode 100644
index 00000000..68f302cd
--- /dev/null
+++ b/vector.inc.h
@@ -0,0 +1,51 @@
+#ifndef TYPE
+#error "Set TYPE before including this file"
+#else
+
+#include "macro.h"
+#include "err.h"
+
+INIT_F(VECT(TYPE)) {
+ this->length = 0;
+ this->alloc = 0x10;
+ this->items = calloc(sizeof(*this->items), this->alloc);
+ return 0;
+}
+
+FREE_F(VECT(TYPE)) {
+ for (unsigned int i = 0; i < this->length; i++) {
+ FFREE(TYPE, this->items[i]);
+ }
+ free(this->items);
+ return 0;
+}
+
+int PUSH(VECT(TYPE))(VECT(TYPE)* this, TYPE* t) {
+ if (this->length + 1 > this->alloc) {
+ this->alloc <<= 1;
+ this->items = realloc(this->items, sizeof(*this->items) * this->alloc);
+ }
+
+ this->items[this->length] = t;
+ ++this->length;
+ return 0;
+}
+
+TYPE* GET(VECT(TYPE))(VECT(TYPE)* this, unsigned int idx) {
+ if (idx >= this->length) {
+ ERR("Index out of range");
+ return NULL;
+ }
+
+ return this->items[idx];
+}
+
+int EMPTY(VECT(TYPE))(VECT(TYPE)* this) {
+ return this->length == 0;
+}
+
+unsigned int SIZE(VECT(TYPE))(VECT(TYPE)* this) {
+ return this->length;
+}
+
+#endif /* TYPE */