From 8e2d4025fc02e07866869a33ccc686f87389cb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Fri, 8 Feb 2019 21:13:08 +0100 Subject: V{calendar,event} merged into vcomponent, making it symmetic. --- Makefile | 3 +-- calendar.c | 9 +++++--- calendar.h | 2 +- code.scm | 29 ++++++++++++++++++++++++- graphs.c | 2 +- graphs.h | 2 +- main.c | 23 ++++++++++---------- parse.c | 24 +++++++++++++-------- parse.h | 6 +++--- scheme.scm.c | 14 ++++++------ strbuf.c | 3 ++- vcal.c | 69 ++++++++++++++++++++++++------------------------------------ vcal.h | 37 +++++++++++++++----------------- vector.h | 27 ++++++++++++++++++++++++ vector.inc.h | 51 ++++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 200 insertions(+), 101 deletions(-) create mode 100644 vector.h create mode 100644 vector.inc.h 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") +;; => # + +;; (string->date (calendar-get-attr v 0 "dtstart") +;; "~Y~m~eT~k~M~S") +;; => # + +;; (string-take-right (calendar-get-attr v 0 "dtstart") 1) ; => "Z" + +;; (string->date "20180311T133700" +;; "~Y~m~eT~k~M~S") ; <-- Note missing ~z +;; => # diff --git a/graphs.c b/graphs.c index 931b181b..ab49f4f1 100644 --- a/graphs.c +++ b/graphs.c @@ -2,7 +2,7 @@ #include -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 +#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 */ -- cgit v1.2.3