aboutsummaryrefslogtreecommitdiff
path: root/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c157
1 files changed, 68 insertions, 89 deletions
diff --git a/parse.c b/parse.c
index 651572bb..77c3f8db 100644
--- a/parse.c
+++ b/parse.c
@@ -2,30 +2,31 @@
#include <errno.h>
#include <string.h>
+#include <assert.h>
#include "macro.h"
#include "vcal.h"
#include "err.h"
-int parse_file(char* fname, FILE* f, vcomponent* cal) {
+#define TYPE vcomponent
+#include "linked_list.inc.h"
+#undef TYPE
+
+int parse_file(char* filename, FILE* f, vcomponent* root) {
int segments = 1;
SNEW(strbuf, str, segments * SEGSIZE);
part_context p_ctx = p_key;
- SNEW(strbuf, skip, SEGSIZE);
- parse_ctx ctx = {
- .scope = s_none,
- .skip_to = &skip
- };
+
+ SNEW(parse_ctx, ctx, filename);
+ PUSH(LLIST(vcomponent))(&ctx.comp_stack, root);
int keylen = 100;
int vallen = 100;
int line = 0;
- vcomponent* ev = NULL;
-
SNEW(content_line, cline, keylen, vallen);
char c;
@@ -84,12 +85,7 @@ int parse_file(char* fname, FILE* f, vcomponent* cal) {
// strbuf_cap(cline.vals.cur->value);
++line;
-
- switch (handle_kv(cal, ev, &cline, line, &ctx)) {
- case s_event:
- RENEW(vcomponent, ev, fname);
- break;
- }
+ handle_kv(&cline, line, &ctx);
strbuf_soft_reset(&str);
p_ctx = p_key;
@@ -138,11 +134,17 @@ int parse_file(char* fname, FILE* f, vcomponent* cal) {
}
strbuf_copy(cline.vals.cur->value, &str);
strbuf_cap(cline.vals.cur->value);
- handle_kv(cal, ev, &cline, line, &ctx);
+ handle_kv(&cline, line, &ctx);
}
FREE(strbuf)(&str);
FREE(content_line)(&cline);
- FREE(strbuf)(ctx.skip_to);
+ // FREE(strbuf)(ctx.skip_to);
+ assert(POP(LLIST(vcomponent))(&ctx.comp_stack) == root);
+ assert(EMPTY(LLIST(strbuf))(&ctx.key_stack));
+ assert(EMPTY(LLIST(vcomponent))(&ctx.comp_stack));
+ FREE(LLIST(strbuf))(&ctx.key_stack);
+ FREE(LLIST(vcomponent))(&ctx.comp_stack);
+ free(ctx.filename);
return 0;
}
@@ -150,80 +152,57 @@ int parse_file(char* fname, FILE* f, vcomponent* cal) {
/*
* TODO Extend this to handle properties
*/
-int handle_kv(
- vcomponent* cal,
- vcomponent* ev,
- content_line* cline,
- int line,
- parse_ctx* ctx
- ) {
- switch (ctx->scope) {
-
- case s_skip:
- if (strbuf_c(&cline->key, "END") && strbuf_cmp(cline->vals.cur->value, ctx->skip_to)) {
- ctx->scope = s_calendar;
- }
- break;
-
- case s_none:
- if (! (strbuf_c(&cline->key, "BEGIN") && strbuf_c(cline->vals.cur->value, "VCALENDAR"))) {
- ERR_F("%s, %i\n%s", "Invalid start of calendar", line, ev->filename);
- return -1;
- }
- ctx->scope = s_calendar;
- 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;
- return ctx->scope;
- break;
- } else {
-
- /*
- * Here we found the start of some form of block
- * we don't understand. Just skip everything until
- * we find the matching END
- */
- ctx->scope = s_skip;
- strbuf_copy(ctx->skip_to, cline->vals.cur->value);
+int handle_kv (
+ content_line* cline,
+ int line,
+ parse_ctx* ctx
+ ) {
+
+ if (strbuf_c(&cline->key, "BEGIN")) {
+ /* should be one of:
+ * VCALENDAR, VEVENT, VALARM, VTODO, VTIMEZONE,
+ * and possibly some others I forget.
+ */
+ NEW(strbuf, s);
+ strbuf_init_copy(s, cline->vals.cur->value);
+ PUSH(LLIST(strbuf))(&ctx->key_stack, s);
+
+ NEW(vcomponent, e,
+ s->mem,
+ ctx->filename);
+ e->parent = PEEK(LLIST(vcomponent))(&ctx->comp_stack);
+ PUSH(LLIST(vcomponent))(&ctx->comp_stack, e);
+
+ } else if (strbuf_c(&cline->key, "END")) {
+ strbuf* s = POP(LLIST(strbuf))(&ctx->key_stack);
+ if (strbuf_cmp(s, cline->vals.cur->value) != 0) {
+ ERR_F("Expected END:%s, got END:%s.\n%s line %i",
+ s->mem, cline->vals.cur->value->mem, PEEK(LLIST(vcomponent))(&ctx->comp_stack)->filename, line);
+ PUSH(LLIST(strbuf))(&ctx->key_stack, s);
+ return -1;
+
+ } else {
+ FFREE(strbuf, s);
+ /* Received propper end, push cur into parent */
+ vcomponent* cur = POP(LLIST(vcomponent))(&ctx->comp_stack);
+ // TODO should this instead be done at creation time?
+ PUSH(vcomponent)(PEEK(LLIST(vcomponent))(&ctx->comp_stack), cur);
+ }
+ } else {
+ NEW(content_line, c);
+ content_line_copy(c, cline);
+ PUSH(TRIE(content_line))(
+ &PEEK(LLIST(vcomponent))(&ctx->comp_stack)->clines,
+ c->key.mem, c);
+ }
- }
- } else if (strbuf_c(&cline->key, "END")) {
- if (strbuf_c(cline->vals.cur->value, "VCALENDAR")) {
- ctx->scope = s_none;
- break;
- }
- }
- break;
+ return 0;
+}
- case s_event:
- if (ev == NULL) {
- ERR_F("%s, %i", "Something has gone terribly wrong", line);
- return -5;
- }
- if (strbuf_c(&cline->key, "END")) {
- if (strbuf_c(cline->vals.cur->value, "VEVENT")) {
- PUSH(vcomponent)(cal, ev);
- ctx->scope = s_calendar;
- return ctx->scope;
- } else {
- ERR_F("Trying to end something, expected VEVENT, Got [%s]\n%s : %i",
- cline->vals.cur->value->mem, ev->filename, line);
- return -3;
- }
- } else {
- NEW(content_line, c);
- content_line_copy(c, cline);
- PUSH(TRIE(content_line))(&ev->clines, c->key.mem, c);
- }
- break;
- }
+INIT_F(parse_ctx, char* filename) {
+ INIT(LLIST(strbuf), &this->key_stack);
+ INIT(LLIST(vcomponent), &this->comp_stack);
+ this->filename = calloc(sizeof(*filename), strlen(filename) + 1);
+ strcpy(this->filename, filename);
return 0;
}