diff options
Diffstat (limited to '')
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | calendar.cpp (renamed from calendar.c) | 0 | ||||
-rw-r--r-- | err.h | 4 | ||||
-rw-r--r-- | linked_list.cpp | 38 | ||||
-rw-r--r-- | linked_list.h | 58 | ||||
-rw-r--r-- | linked_list.inc.h | 23 | ||||
-rw-r--r-- | macro.h | 131 | ||||
-rw-r--r-- | parse.cpp (renamed from parse.c) | 83 | ||||
-rw-r--r-- | parse.h | 31 | ||||
-rw-r--r-- | strbuf.c | 138 | ||||
-rw-r--r-- | strbuf.cpp | 26 | ||||
-rw-r--r-- | strbuf.h | 106 | ||||
-rw-r--r-- | trie.cpp | 134 | ||||
-rw-r--r-- | trie.h | 68 | ||||
-rw-r--r-- | trie.inc.h | 166 | ||||
-rw-r--r-- | vcal.c | 130 | ||||
-rw-r--r-- | vcal.cpp | 14 | ||||
-rw-r--r-- | vcal.h | 132 |
18 files changed, 420 insertions, 870 deletions
@@ -10,14 +10,14 @@ CFLAGS = -std=gnu++11 -Wall -Wextra \ LDFLAGS = -fPIC $(shell guile-config link) H_FILES = $(wildcard *.h) -C_FILES = $(wildcard *.c) +C_FILES = $(wildcard *.cpp) SCM_C_FILES = $(wildcard *.scm.c) -X_FILES = $(SCM_C_FILES:.scm.c=.x) +X_FILES = $(SCM_C_FILES:.scm.cpp=.x) .SECONDARY: $(X_FILES) -O_FILES = $(addprefix obj/,$(C_FILES:.c=.o)) +O_FILES = $(addprefix obj/,$(C_FILES:.cpp=.o)) all: parse libguile-calendar.so @@ -32,7 +32,7 @@ $(O_FILES): | $(OBJDIR) $(OBJDIR)/%.scm.o : %.scm.c %.x $(CC) -c $(CFLAGS) -o $@ $< -$(OBJDIR)/%.o : %.c # $(H_FILES) $(X_FILES) +$(OBJDIR)/%.o : %.cpp # $(H_FILES) $(X_FILES) $(CC) -c $(CFLAGS) -o $@ $< $(OBJDIR): diff --git a/calendar.c b/calendar.cpp index d0476583..d0476583 100644 --- a/calendar.c +++ b/calendar.cpp @@ -3,8 +3,6 @@ #include <stdio.h> -#include "macro.h" - #define _RESET "\x1b[m" #define _BLACK "\x1B[0;30m" #define _RED "\x1B[0;31m" @@ -27,6 +25,7 @@ #define INFO_F(fmt, ...) fprintf(stderr, _BLUE "INFO" _RESET " (%s:%i) " fmt "\n", \ __FILE__, __LINE__, ##__VA_ARGS__) +#if 0 #define LINE(len) do { \ printf(_GREEN); \ FOR(int, i, len) printf("_"); \ @@ -38,5 +37,6 @@ FMT(T)(v, buf); \ INFO_F("%s", buf); \ } while (0) +#endif #endif /* ERR_H */ diff --git a/linked_list.cpp b/linked_list.cpp new file mode 100644 index 00000000..bd49510e --- /dev/null +++ b/linked_list.cpp @@ -0,0 +1,38 @@ +#include "linked_list.h" + +template <typename T> +llist<T>::llist () { + this->length = 0; + this->cur = this->head = new link<T>; + this->tail = new link<T>; + + head->after = tail; + tail->before = head; +} + +template <typename T> +link<T>::~link () { + this.unlink(); +} + +template <typename T> +void link<T>::unlink () { + if (this->before != nullptr) this->before->after = this->after; + if (this->after != nullptr) this->after->before = this->before; +} + +template <typename T> +void llist<T>::push(T& val) { + auto l = new link<T>(val); + + l->after = FIRST(this); + FIRST(this) = l; + + l->after->before = l; + l->before = this->head; + + ++this->length; + + // TODO do I want to change that? + this->cur = l; +} diff --git a/linked_list.h b/linked_list.h index a17bd797..7d11ca81 100644 --- a/linked_list.h +++ b/linked_list.h @@ -1,54 +1,48 @@ #ifndef LINKED_LIST_H #define LINKED_LIST_H -#include "macro.h" -#define LLIST(T) TEMPL(llist, T) -#define LINK(T) TEMPL(llist_link, T) +template <typename T> +struct link { + link<T>* before = nullptr; + link<T>* after = nullptr; + T* value; -#define UNLINK(T) TEMPL(unlink, T) + link (); + link (T* val) : value(val) { } + ~link (); -#endif /* LINKED_LIST_H */ -#ifdef TYPE - -typedef struct LINK(TYPE) { - struct LINK(TYPE)* before; - struct LINK(TYPE)* after; - TYPE* value; -} LINK(TYPE); + void unlink (); +}; -#define L(link) (link)->value +// #define L(link) (link)->value -typedef struct { - LINK(TYPE)* head; - LINK(TYPE)* tail; - LINK(TYPE)* cur; +template <typename T> +struct llist { + link<T>* head; + link<T>* tail; + link<T>* cur; int length; -} LLIST(TYPE); + + llist (); + + void push ( T& ); + T& peek (); + T& pop (); + + llist& operator += (llist& other); +}; #define FIRST(lst) (lst)->head->after #define FIRST_V(lst) (lst)->head->after->value #define LAST(lst) (lst)->tail->before #define LAST_V(lst) (lst)->tail->before->value -INIT_F ( LLIST(TYPE) ); - /* * NOTE freeing a linked list alsa FFREE's all its contents. * TODO some form of shared pointer to ensure nothing is free'd twice * would be a good idea. */ -FREE_F ( LLIST(TYPE) ); - -INIT_F ( LINK(TYPE) ); -INIT_F ( LINK(TYPE), TYPE* val ); -FREE_F ( LINK(TYPE) ); - -int UNLINK(LINK(TYPE)) ( LINK(TYPE)* ); - -int PUSH(LLIST(TYPE)) ( LLIST(TYPE)*, TYPE* ); -TYPE* PEEK(LLIST(TYPE)) ( LLIST(TYPE)* ); -TYPE* POP(LLIST(TYPE)) ( LLIST(TYPE)* ); int DEEP_COPY(LLIST(TYPE)) ( LLIST(TYPE)* dest, LLIST(TYPE)* src ); @@ -85,4 +79,4 @@ FMT_F(LLIST(TYPE)); // #define __NXT_LLIST(T, l, set) l = L(__INTER(l) = __INTER(l)->after) #define NXT_LLIST(T) __NXT_LLIST -#endif /* TYPE */ +#endif /* LINKED_LIST_H */ diff --git a/linked_list.inc.h b/linked_list.inc.h index 8ae720ba..410fddba 100644 --- a/linked_list.inc.h +++ b/linked_list.inc.h @@ -1,26 +1,3 @@ -#ifndef TYPE -#error "Set TYPE before including self file" -#else - -INIT_F ( LLIST(TYPE) ) { - self->length = 0; - NEW(LINK(TYPE), head); - NEW(LINK(TYPE), tail); - self->head = head; - self->tail = tail; - head->after = tail; - tail->before = head; - self->cur = head; - return 0; -} - -FREE_F (LINK(TYPE)) { - UNLINK(LINK(TYPE))(self); - - if (self->value != NULL) FFREE(TYPE, self->value); - return 0; -} - FREE_F( LLIST(TYPE) ) { LINK(TYPE) *n, *next; n = self->head; diff --git a/macro.h b/macro.h deleted file mode 100644 index 6421b2fd..00000000 --- a/macro.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef MACRO_H -#define MACRO_H - -/* - * Token paste - */ -#define TP(a, b) a ## b -#define TP3(a, b, c) a ## b ## c -#define TP4(a, b, c, d) a ## b ## c ## d -#define TP5(a, b, c, d, e) a ## b ## c ## d ## e -#define TP6(a, b, c, d, e, f) a ## b ## c ## d ## e ## f - -/* - * Get length of __VA_ARGS__ - * Borrowed fram: - * https://stackoverflow.com/a/35986932 - */ -#define VA_ARGS_NUM_PRIV(P1, P2, P3, P4, P5, P6, Pn, ...) Pn -#define VA_ARGS_NUM(...) VA_ARGS_NUM_PRIV(-1, ## __VA_ARGS__, 5, 4, 3, 2, 1, 0) - -/* - * Templatization macros. Forms symbols on the from name<T>, which - * looks really good in debuggers and the like. Unicode characters - * written in \U notation since C apparently doesn't support unicode - * literals. - * - * Can be nested (useful for container types). - * - * Doesn't use ASCII <>, but rather some other ᐸᐳ, meaning that it's - * not a reserved character. - * - * nameᐸTᐳ - */ -#define TEMPL(name, T) TP4(name, \U00001438 , T, \U00001433 ) -#define TEMPL2(name, T, V) TP6(name, \U00001438\U00001438 , T , \U00001433_\U00001438 , V, \U00001433\U00001433) -#define TEMPL_N(name, T, argcount) TP6(name, \U00001438 , T, _, argcount, \U00001433 ) - -/* Constructor type name */ -#define __INIT_T(T, C) TEMPL_N(init, T, C) - -/* Returns full type of constructor */ -#define INIT_F(T, ...) \ - int __INIT_T(T, VA_ARGS_NUM(__VA_ARGS__)) (T* self, ## __VA_ARGS__) - -/* - * Call the constructor of an object - * `int` part of the macro, to ensure that any attempt to call self - * function results in an error. - */ -#define INIT(T, N, ...) \ - __INIT_T(T, VA_ARGS_NUM(__VA_ARGS__)) (N, ## __VA_ARGS__) - -/* Allocate a new_ object on the HEAP */ -#define NEW(T, N, ...) \ - T* N = (T*) malloc(sizeof(*N)); \ - INIT(T, N, ## __VA_ARGS__); - -/* - * Reconstructs a object. Use with caution. - */ -#define RENEW(T, N, ...) do { \ - N = (T*) malloc(sizeof(*N)); \ - INIT(T, N, ## __VA_ARGS__); \ -} while (0) - - -/* Allocate a new_ object on the STACK */ -#define SNEW(T, N, ...) \ - T N; \ - INIT(T, & N, ## __VA_ARGS__); - -/* Destructor for type */ -#define FREE(T) TEMPL(free, T) - -/* Call destructor for type, and free object */ -#define FFREE(T, N) do { FREE(T)(N); free(N); } while (0) - -/* Declare destructor */ -#define FREE_F(T) int FREE(T) (T* self) - -/* generate reusable internal symbol */ -#define __INTER(s) TP3(__, s, __internal) - -/* Iterator macros. */ -#define FOR(CONT_T, T, var, set) \ - PRE_FOR_ ## CONT_T (T) (T, var, set); \ - for( BEG_ ## CONT_T (T) (T, var, set); \ - END_ ## CONT_T (T) (T, var, set); \ - NXT_ ## CONT_T (T) (T, var, set)) - -/* Example int implementation - * FOR(int, i, 10) { } */ - -#define PRE_FOR_int(i, set) -#define BEG_int(i, set) int i = 0 -#define NXT_int(i, set) i++ -#define END_int(i, set) i < set - -/* - * General functions that different container types may implement. - * Actuall implementation and type signature is mostly left to - * individual implementations. - */ -#define DEEP_COPY(T) TEMPL(copy , T) -#define RESOLVE(T) TEMPL(resolve , T) -#define APPEND(T) TEMPL(append , T) -#define SIZE(T) TEMPL(size , T) -#define EMPTY(T) TEMPL(empty , T) -#define PUSH(T) TEMPL(push , T) -#define PEEK(T) TEMPL(peek , T) -#define POP(T) TEMPL(pop , T) -#define GET(T) TEMPL(get , T) -#define RESET(T) TEMPL(reset , T) - -/* - * Formatting macros. - * Transform objects into string representation of themselves. - * buf should be a suffisiently large memmory location, if it's to - * small then bad stuff might happen. - * - * Should return the number of bytes written (like sprintf). - */ - -#define FMT_T(T) TEMPL(format , T) -#define FMT_F(T) int FMT_T(T)(T* self, char* buf, ...) -// TODO change order of buf and item -#define __FMT_HELP(item, buf, ...) ((item), (buf), VA_ARGS_NUM(__VA_ARGS__), ## __VA_ARGS__) -#define FMT(T) FMT_T(T) __FMT_HELP -#define fmtf(...) seek += sprintf(buf + seek, __VA_ARGS__) - -#endif /* MACRO_H */ @@ -4,32 +4,21 @@ #include <string.h> #include <assert.h> -#include "macro.h" #include "vcal.h" +#include "strbuf.h" #include "err.h" -#define TYPE vcomponent -#include "linked_list.inc.h" -#undef TYPE - -#define T strbuf -#define V strbuf -#include "pair.h" -#include "pair.inc.h" -#undef T -#undef V - /* * name *(";" param) ":" value CRLF */ -int parse_file(char* filename, FILE* f, vcomponent* root) { +int parse_file(char* filename, FILE* f, vcomponent& root) { part_context p_ctx = p_key; - SNEW(parse_ctx, ctx, filename); - PUSH(LLIST(vcomponent))(&ctx.comp_stack, root); + parse_ctx ctx(filename); + ctx.comp_stack.push(root); - SNEW(content_line, cline); + content_line cline; char c; while ( (c = fgetc(f)) != EOF) { @@ -40,11 +29,16 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { if (fold(f, &ctx, c) > 0) { /* Actuall end of line, handle value */ - strbuf* target = CLINE_CUR_VAL(&cline); + // std::string& target = CLINE_CUR_VAL(&cline); + // TODO solve current; + // std::string& target = cline - DEEP_COPY(strbuf)(target, &ctx.str); - strbuf_cap(target); - strbuf_soft_reset(&ctx.str); + strbuf target = ctx.str; + // DEEP_COPY(strbuf)(target, &ctx.str); + target.cap(); + // strbuf_cap(target); + ctx.str.soft_reset(); + // strbuf_soft_reset(&ctx.str); handle_kv(&cline, &ctx); @@ -86,7 +80,8 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { } /* save escapade character as a normal character */ - strbuf_append(&ctx.str, target); + // strbuf_append(&ctx.str, target); + ctx.str += target; ++ctx.column; ++ctx.pcolumn; @@ -94,12 +89,15 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { /* Border between param {key, value} */ } else if (p_ctx == p_param_name && c == '=') { - LLIST(param_set)* params = CLINE_CUR_PARAMS(&cline); - - NEW(param_set, ps); - DEEP_COPY(strbuf)(&ps->key, &ctx.str); - strbuf_cap(&ps->key); - strbuf_soft_reset(&ctx.str); + // LLIST(param_set)* params = CLINE_CUR_PARAMS(&cline); + std::list<param_set>* params = cline.second.second; + + // NEW(param_set, ps); + auto ps = new param_set; + // TODO make sure this is a deep copy + ps->first = ctx.str; + ps->first.cap(); + ctx.str.soft_reset(); PUSH(LLIST(param_set))(params, ps); p_ctx = p_param_value; @@ -269,34 +267,3 @@ int fold(FILE* f, parse_ctx* ctx, char c) { return retval; } - - -INIT_F(parse_ctx, char* filename) { - INIT(LLIST(strbuf), &self->key_stack); - INIT(LLIST(vcomponent), &self->comp_stack); - self->filename = (char*) calloc(sizeof(*filename), strlen(filename) + 1); - strcpy(self->filename, filename); - - self->line = 0; - self->column = 0; - - self->pline = 1; - self->pcolumn = 1; - - INIT(strbuf, &self->str); - - return 0; -} - -FREE_F(parse_ctx) { - - FREE(LLIST(strbuf))(&self->key_stack); - FREE(LLIST(vcomponent))(&self->comp_stack); - free(self->filename); - - self->line = 0; - self->column = 0; - FREE(strbuf)(&self->str); - - return 0; -} @@ -4,12 +4,17 @@ #include <stdio.h> #include <stdlib.h> +#include <string> +#include <stack> + #include "strbuf.h" #include "vcal.h" +#if 0 #define TYPE vcomponent #include "linked_list.h" #undef TYPE +#endif /* * The standard says that no line should be longer than 75 octets. @@ -18,32 +23,32 @@ */ #define SEGSIZE 75 -typedef enum { +enum part_context { p_key, p_value, p_param_name, p_param_value, p_escape -} part_context; +}; /* * Struct holding most state information needed while parsing. * Kept together for simplicity. */ -typedef struct { - char* filename; - LLIST(strbuf) key_stack; - LLIST(vcomponent) comp_stack; +struct parse_ctx { + std::string filename; + std::stack<std::string> key_stack; + std::stack<vcomponent> comp_stack; /* Number for unfolded lines */ - int line; - int column; + int line = 0; + int column = 0; /* Actuall lines and columns from file */ - int pline; - int pcolumn; + int pline = 1; + int pcolumn = 1; strbuf str; -} parse_ctx; -INIT_F(parse_ctx, char* filename); -FREE_F(parse_ctx); + parse_ctx (const std::string& filename) + : filename(filename) { } +}; int handle_kv( content_line* cline, diff --git a/strbuf.c b/strbuf.c deleted file mode 100644 index f17de211..00000000 --- a/strbuf.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "strbuf.h" - -#include <string.h> -#include <stdio.h> - -#include "err.h" - -INIT_F(strbuf) { - INIT(strbuf, self, 1); - return 0; -} - -/* - * Giving len < 1 is an error. - */ -INIT_F(strbuf, size_t len) { - self->mem = (char*) calloc(sizeof(*self->mem), len); - self->alloc = len; - self->ptr = 0; - self->len = 0; - return 0; -} - -int strbuf_realloc(strbuf* str, size_t len) { - str->mem = (char*) realloc(str->mem, len); - str->alloc = len; - return 0; -} - -FREE_F(strbuf) { - /* has already been freed */ - if (self->mem == NULL) return 1; - - free (self->mem); - self->mem = NULL; - self->alloc = 0; - self->len = 0; - return 0; -} - -/* - * Reallocates memmory for you. Returns 1 if memory was reallocated. - */ -int strbuf_append(strbuf* s, char c) { - int retval = 0; - - if (s->len + 1 > s->alloc) { - s->alloc <<= 1; - s->mem = (char*) realloc(s->mem, s->alloc); - retval = 1; - } - - s->mem[s->len] = c; - s->ptr = ++s->len; - return retval; -} - -int strbuf_cap(strbuf* s) { - /* - * TODO check memmory usage - */ - return strbuf_append(s, 0); -} - -int DEEP_COPY(strbuf)(strbuf* dest, strbuf* src) { - int retval = 0; - - if (dest->alloc < src->len) { - /* +1 in length is to have room for '\0'. */ - strbuf_realloc(dest, src->len + 1); - retval = 1; - } - - dest->len = src->len; - memcpy(dest->mem, src->mem, src->len); - return retval; -} - -int strbuf_cmp(strbuf* a, strbuf* b) { - if (a == NULL || a->alloc == 0 || - b == NULL || b->alloc == 0) - { - ERR("a or b not alloced"); - // return -1; - } - - return strncmp(a->mem, b->mem, a->len); -} - -int strbuf_c(strbuf* a, char* b) { - if (a == NULL || a->alloc == 0) { - ERR("a not allocated"); - return -1; - } - - return strcmp(a->mem, b) == 0; -} - -char* charat(strbuf* s, unsigned int idx) { - if (idx > s->len) { - ERR("Index out of bounds"); - return (char*) -1; - } - - return &s->mem[idx]; -} - -char* strbuf_cur(strbuf* s) { - return &s->mem[s->ptr]; -} - -char* strbuf_end(strbuf* s) { - return &s->mem[s->len]; -} - -int strbuf_reset(strbuf* s) { - s->ptr = 0; - return 0; -} - - -int strbuf_soft_reset(strbuf* s) { - s->ptr = s->len = 0; - return 0; -} - -strbuf* RESOLVE(strbuf)(strbuf* dest, strbuf* new_) { - if (dest == NULL) return new_; - else return dest; -} - -FMT_F(strbuf) { - return sprintf(buf, "%s", self->mem); -} - -int SIZE(strbuf)(strbuf* self) { - return self->len; -} diff --git a/strbuf.cpp b/strbuf.cpp new file mode 100644 index 00000000..3864b271 --- /dev/null +++ b/strbuf.cpp @@ -0,0 +1,26 @@ +#include "strbuf.h" + +#include <cstdlib> + +void strbuf::realloc (size_t len) { + this->mem = static_cast<char*>(std::realloc(this->mem, len)); + this->alloc = len; +} + +strbuf::~strbuf() { + free (this->mem); + this->mem = NULL; + this->alloc = 0; + this->len = 0; +} + +strbuf& strbuf::operator+=(char c) { + if (this->len + 1 > this->alloc) { + this->alloc <<= 1; + this->mem = static_cast<char*> (std::realloc(this->mem, this->alloc)); + } + + this->mem[this->len] = c; + this->ptr = ++this->len; + return *this; +} @@ -1,8 +1,9 @@ #ifndef STRBUF_H #define STRBUF_H -#include <stdlib.h> -#include "macro.h" +#include <unistd.h> +#include <cstdlib> +#include <cstring> /* * A high level string type which holds it's own length, how much @@ -12,88 +13,74 @@ * Also comes with a number of functions which allow for safe(er) * access to the memmory. */ -typedef struct { +struct strbuf { char* mem; /* TODO add support for negative ptr */ - int ptr; - unsigned int alloc; - unsigned int len; -} strbuf; + int ptr = 0; + size_t alloc; + size_t len = 0; -/* - * Init strbuf to size of 0 - * Doesnt't call malloc. - */ -INIT_F(strbuf); + strbuf () : strbuf (1) { }; + strbuf (size_t alloc) + : alloc(alloc) + , mem(static_cast<char*>(malloc(alloc))) { }; -/* Constructor */ -INIT_F(strbuf, size_t len); + ~strbuf(); -/* - * Like realloc, but for strbuf - */ -int strbuf_realloc(strbuf* str, size_t len); + /* + * Like realloc, but for strbuf + */ + void realloc (size_t len); -/* - * Free's contents of str, but keeps str. - */ -FREE_F(strbuf); + bool operator==(strbuf& other) { + return strncmp(this->mem, other.mem, this->len) == 0; + } + bool operator==(char* other) + { strncmp(this->mem, other, this->len) == 0 ; } -int strbuf_cmp(strbuf* a, strbuf* b); -int strbuf_c(strbuf* a, char* b); + strbuf& operator=(strbuf* other); -/* - * Copy contents from src to dest. - * Assumes that dest is already initialized. - */ -int DEEP_COPY(strbuf)(strbuf*, strbuf*); + strbuf& operator+=(char c); -/* - * Append char to end of strbuf, determined by s->len. - */ -int strbuf_append(strbuf* s, char c); + void cap() { this->mem += '\0'; } -/* - * Calls strbuf_append with NULL. - */ -int strbuf_cap(strbuf* s); + /* + * Returns a pointer to character at index. Allows mutation of the + * value pointed to by the return address. + */ + char& operator[](int idx) + { return this->mem[idx]; } -/* - * Returns a pointer to character at index. Allows mutation of the - * value pointed to by the return address. - */ -char* charat(strbuf* s, unsigned int idx); + /* Same as `charat`, But returns the current character. */ + char& strbuf_cur() + { return this->mem[this->ptr]; } -/* - * Same as `charat`, But returns the current character. - */ -char* strbuf_cur(strbuf* s); + /* Returns the character after the last, so where null hopefully is. */ + char& back() + { return this->mem[this->len]; } -/* - * Resets the seek for strbuf to 0. - */ -int strbuf_reset(strbuf* s); + /* Resets the seek for strbuf to 0. */ + void reset(); -/* - * Sets the length and seek ptr to 0, but doesn't touch the memmory. - */ -int strbuf_soft_reset(strbuf* s); + /* Sets the length and seek ptr to 0, but doesn't touch the memmory. */ + void soft_reset(); -/* - * Returns the character after the last, so where null hopefully is. - */ -char* strbuf_end(strbuf* s); + std::string to_string() { + return std::string (this->mem); + } +}; /* * Reallocs dest to be the same size as src, and copies the contents * of src into dest. */ -int strbuf_realloc_copy(strbuf* dest, strbuf* src); +// int strbuf_realloc_copy(strbuf* dest, strbuf* src); /* * Copies contents from src to dest, also allocating dest in the * process. dest should not be initialized before self call. */ +#if 0 int strbuf_init_copy(strbuf* dest, strbuf* src); strbuf* RESOLVE(strbuf)(strbuf*, strbuf*); @@ -101,5 +88,6 @@ strbuf* RESOLVE(strbuf)(strbuf*, strbuf*); FMT_F(strbuf); int SIZE(strbuf)(strbuf*); +#endif #endif /* STRBUF_H */ diff --git a/trie.cpp b/trie.cpp new file mode 100644 index 00000000..729277bd --- /dev/null +++ b/trie.cpp @@ -0,0 +1,134 @@ +#include "trie.h" + +template <class T> +trie<T>::trie () { + this->root = new trie_node<T> ('\0'); +} + +template <class T> +trie_node<T>::trie_node (char c) { + this->c = c; +} + +template <class T> +trie_node<T>::trie_node (char c, trie_node<T>* next, trie_node<T>* child) { + this->c = c; + this->next = next; + this->child = child; +} + +template <class T> +int trie<T>::push_back (const char* key, const T& item) { + trie_node<T> *cur, *last; + + last = this->root; + cur = last->child; + + char* subkey = key; + + while (true) { + if (cur == NULL) { + /* Build direct LL for remaining subkey */ + for (char* c = subkey; c[0] != '\0'; c++) { + // NEW(TRIE_NODE(TYPE), t, *c); + auto t = new trie_node<T>(*c); + last->child = t; + last = t; + } + // TODO fix resolve + // last->value = RESOLVE(TYPE)(last->value, val); + last->value = item; + return 0; + } else if (cur->c == subkey[0]) { + /* This node belongs to the key, + * Decend further */ + last = cur; + cur = cur->child; + subkey++; + } else if (subkey[0] == '\0') { + /* Key finished */ + // TODO fix resolve + // last->value = RESOLVE(TYPE)(last->value, val); + last->value = item; + return 0; + } else if (cur->next != NULL) { + /* This node was not part of the set, but it's sibling might */ + cur = cur->next; + /* `last` not set since we aren't moving down */ + } else { + /* No node on self level was part of the set, create a new__ + * sibling and follow down that parse */ + // NEW(TRIE_NODE(TYPE), t, *subkey); + auto t = new trie_node<T>(*subkey); + cur->next = t; + last = cur; + cur = t; + } + } +} + +template <class T> +T& trie<T>::operator[] (char* key) { + trie_node<T>* n = this->root->child; + char* subkey = key; + + while (n != NULL) { + if (subkey[1] == '\0') { + return n->value; + } else if (subkey[0] == n->c) { + n = n->child; + subkey++; + } else { + n = n->next; + } + } + + // ERR("Position not found"); + // return 0; + return nullptr; +} + +template <class T> +std::ostream& operator<<(std::ostream& o, trie_node<T>* node) { +#if 0 + va_list ap; + va_start(ap, buf); + int argc = va_arg(ap, int); + int depth = argc >= 1 + ? va_arg(ap, int) + : 0; + va_end(ap); + + int seek = 0; +#endif + // TODO figure out depth + int depth = 1; + + trie_node<T>* n = node; + + + if (n == NULL) { o << std::endl; } + while (n != NULL) { + o << '|'; + for (int i = 0; i < depth; i++) o << ' '; + o << (n->c == '\0' ? '0' : n->c); + if (n->value != NULL) { + o << n->value << std::endl; + } + + if (n->child != NULL) { + o << std::endl; + o << n->child; // depth + 1 + } + n = n->next; + } + return o; +} + +template <class T> +std::ostream& operator<<(std::ostream& o, trie<T>* trie) { + o << "Trie: " << trie << " {\n"; + o << trie->root->child; + o << "}"; + return o; +} @@ -1,46 +1,60 @@ #ifndef TRIE_H #define TRIE_H -#include <stdio.h> +#include <iostream> -#include "macro.h" +template <typename T> +struct trie_node { + char c; + T* value = NULL; + trie_node<T>* next = NULL; + trie_node<T>* child = NULL; -#define TRIE(T) TEMPL(trie, T) -#define TRIE_NODE(T) TEMPL(trie_node, T) + trie_node (char c); + trie_node (char c, trie_node<T>* next, trie_node<T>* child); -#endif /* TRIE_H */ -#ifdef TYPE + // ~trie_node (); +}; -typedef struct TRIE_NODE(TYPE) { - char c; - TYPE* value; - struct TRIE_NODE(TYPE)* next; - struct TRIE_NODE(TYPE)* child; -} TRIE_NODE(TYPE); +template <class T> +std::ostream& operator<<(std::ostream&, trie_node<T>* node); + +template <typename T> +struct trie { + trie_node<T>* root; + + trie (); + // ~trie (); -typedef struct { - TRIE_NODE(TYPE)* root; -} TRIE(TYPE); + int push_back (const char* key, const T&); + T& operator[] ( char* key ); -INIT_F ( TRIE(TYPE) ); + bool empty () { return this->root->child == NULL; } +}; -INIT_F (TRIE_NODE(TYPE), char c); +template <class T> +std::ostream& operator<<(std::ostream&, trie<T>* trie); -INIT_F (TRIE_NODE(TYPE), - char c, TRIE_NODE(TYPE)* next, TRIE_NODE(TYPE)* child ); -int PUSH(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key, TYPE* val ); +// INIT_F ( TRIE(TYPE) ); -TYPE* GET(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key ); +// INIT_F (TRIE_NODE(TYPE), char c); -FREE_F(TRIE_NODE(TYPE)); +// INIT_F (TRIE_NODE(TYPE), +// char c, TRIE_NODE(TYPE)* next, TRIE_NODE(TYPE)* child ); -FREE_F(TRIE(TYPE)); +// int PUSH(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key, TYPE* val ); -int EMPTY(TRIE(TYPE))(TRIE(TYPE)*); +// TYPE* GET(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key ); -FMT_F(TRIE_NODE(TYPE)); -FMT_F(TRIE(TYPE)); +// FREE_F(TRIE_NODE(TYPE)); -#endif /* TYPE */ +// FREE_F(TRIE(TYPE)); + +// int EMPTY(TRIE(TYPE))(TRIE(TYPE)*); + +// FMT_F(TRIE_NODE(TYPE)); +// FMT_F(TRIE(TYPE)); + +#endif /* TRIE_H */ diff --git a/trie.inc.h b/trie.inc.h deleted file mode 100644 index 5517939e..00000000 --- a/trie.inc.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef TYPE -#error "Set TYPE before including self file" -#else - -#include <stdarg.h> - -#include "err.h" -#include "macro.h" - -INIT_F ( TRIE(TYPE) ) { - NEW(TRIE_NODE(TYPE), t, '\0'); - self->root = t; - return 0; -} - -INIT_F (TRIE_NODE(TYPE), char c) { - self->c = c; - self->value = NULL; - self->next = NULL; - self->child = NULL; - return 0; -} - -INIT_F (TRIE_NODE(TYPE), - char c, - TRIE_NODE(TYPE)* next, - TRIE_NODE(TYPE)* child ) -{ - self->c = c; - self->next = next; - self->child = child; - return 0; -} - -int PUSH(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key, TYPE* val ) { - TRIE_NODE(TYPE) *cur, *last; - - last = trie->root; - cur = last->child; - - char* subkey = key; - - while (1) { - if (cur == NULL) { - /* Build direct LL for remaining subkey */ - for (char* c = subkey; c[0] != '\0'; c++) { - NEW(TRIE_NODE(TYPE), t, *c); - last->child = t; - last = t; - } - last->value = RESOLVE(TYPE)(last->value, val); - return 0; - } else if (cur->c == subkey[0]) { - /* This node belongs to the key, - * Decend further */ - last = cur; - cur = cur->child; - subkey++; - } else if (subkey[0] == '\0') { - /* Key finished */ - last->value = RESOLVE(TYPE)(last->value, val); - return 0; - } else if (cur->next != NULL) { - /* This node was not part of the set, but it's sibling might */ - cur = cur->next; - /* `last` not set since we aren't moving down */ - } else { - /* No node on self level was part of the set, create a new__ - * sibling and follow down that parse */ - NEW(TRIE_NODE(TYPE), t, *subkey); - cur->next = t; - last = cur; - cur = t; - } - } - - return 0; -} - -/* - * TODO what happens when I give an invalid key? - */ -TYPE* GET(TRIE(TYPE)) ( TRIE(TYPE)* trie, char* key ) { - TRIE_NODE(TYPE)* n = trie->root->child; - char* subkey = key; - - while (n != NULL) { - if (subkey[1] == '\0') { - return n->value; - } else if (subkey[0] == n->c) { - n = n->child; - subkey++; - } else { - n = n->next; - } - } - - ERR("Position not found"); - return 0; -} - -FREE_F(TRIE_NODE(TYPE)) { - if (self == NULL) return 0; - if (self->value != NULL) FFREE(TYPE, self->value); - if (self->next != NULL) FREE(TRIE_NODE(TYPE))(self->next); - if (self->child != NULL) FREE(TRIE_NODE(TYPE))(self->child); - free (self); - return 0; -} - -FREE_F(TRIE(TYPE)) { - if (self->root->c != '\0') { - // ERR("Invalid trie"); - return 1; - } - return FREE(TRIE_NODE(TYPE))(self->root); -} - -int EMPTY(TRIE(TYPE))(TRIE(TYPE)* self) { - return self->root->child == NULL; -} - -FMT_F(TRIE_NODE(TYPE)) { - - va_list ap; - va_start(ap, buf); - int argc = va_arg(ap, int); - int depth = argc >= 1 - ? va_arg(ap, int) - : 0; - va_end(ap); - - int seek = 0; - - TRIE_NODE(TYPE)* n = self; - - if (n == NULL) { fmtf("\n"); } - while (n != NULL) { - fmtf("|"); - // FOR(int, i, depth) fmtf(" "); - for (int i = 0; i < depth; i++) fmtf(" "); - fmtf("%c ", n->c == '\0' ? '0' : n->c); - if (n->value != NULL) { - seek += FMT(TYPE)(n->value, buf + seek); - fmtf("\n"); - } - - if (n->child != NULL) { - fmtf("\n"); - seek += FMT(TRIE_NODE(TYPE))(n->child, buf + seek, depth + 1); - } - n = n->next; - } - return seek; - -} - -FMT_F(TRIE(TYPE)) { - int seek = 0; - fmtf("Trie: %p: {\n", self); - seek += FMT(TRIE_NODE(TYPE))(self->root->child, buf + seek); - fmtf("}"); - return seek; -} - -#endif /* TYPE */ diff --git a/vcal.c b/vcal.c deleted file mode 100644 index 7f674dac..00000000 --- a/vcal.c +++ /dev/null @@ -1,130 +0,0 @@ -#include "vcal.h" - -#include <string.h> - -#define TYPE strbuf -#include "linked_list.inc.h" -#undef TYPE - -#define TYPE param_set -#include "linked_list.inc.h" -#undef TYPE - -#define TYPE content_set -#include "linked_list.inc.h" -#undef TYPE - -#define T strbuf - #define V LLIST(strbuf) - #include "pair.inc.h" - #undef V - #define V LLIST(param_set) - #include "pair.inc.h" - #undef V - #define V LLIST(content_set) - #include "pair.inc.h" - #undef V -#undef T - -#define TYPE content_line -// #include "hash.inc" -#include "trie.inc.h" -#undef TYPE - -#define TYPE vcomponent -#include "vector.inc.h" -#undef TYPE - -INIT_F(vcomponent) { - (void) self; - ERR("Do not use"); - return 0; -} - -INIT_F(vcomponent, char* type) { - return INIT(vcomponent, self, type, NULL); -} - -INIT_F(vcomponent, char* type, char* filename) { - - INIT(TRIE(content_line), &self->clines); - INIT(VECT(vcomponent), &self->components); - - self->filename = NULL; - if (filename != NULL) { - self->filename = (char*) calloc(sizeof(*filename), strlen(filename) + 1); - strcpy(self->filename, filename); - } - - self->type = (char*) calloc(sizeof(*type), strlen(type) + 1); - strcpy(self->type, type); - - self->parent = NULL; - - return 0; -} - -content_line* RESOLVE(content_line) - (content_line* dest, content_line* new_) -{ - if (dest == NULL) return new_; - - if (strbuf_cmp(&dest->key, &new_->key) != 0) { - ERR("Can't resolve between these two types"); - return NULL; - } - - /* This destroys new_->val. */ - APPEND(LLIST(content_set)) (&dest->val, &new_->val); - - FREE(strbuf)(&new_->key); - free(new_); - - return dest; -} - -content_line* get_property (vcomponent* ev, char* key) { - return GET(TRIE(content_line))(&ev->clines, key); -} - -FREE_F(vcomponent) { - if (self->filename != NULL) free(self->filename); - free(self->type); - - if (FREE(TRIE(content_line))(&self->clines) != 0) { - fprintf(stderr, "Error freeing vcomponent belonging to file \n %s \n", - self->filename); - } - - FREE(VECT(vcomponent))(&self->components); - - return 0; -} - -int PUSH(vcomponent)(vcomponent* parent, vcomponent* child) { - return PUSH(VECT(vcomponent))(&parent->components, child); -} - -int DEEP_COPY(vcomponent)(vcomponent* a, vcomponent* b) { - (void) a; - (void) b; - ERR("Deep copy not implemented for vcomponent"); - return -1; -} - -FMT_F(vcomponent) { - int seek = 0; - - for (int i = 0; i < 40; i++) fmtf("_"); - - seek += sprintf(buf + seek, _YELLOW); - seek += sprintf(buf + seek, "\nVComponet (Type := %s)\n", self->type); - seek += sprintf(buf + seek, _RESET); - seek += FMT(TRIE(content_line))(&self->clines, buf + seek); - seek += sprintf(buf + seek, "\nComponents:\n"); - FOR(VECT, vcomponent, comp, &self->components) { - seek += FMT(vcomponent)(comp, buf + seek); - } - - return seek; -} diff --git a/vcal.cpp b/vcal.cpp new file mode 100644 index 00000000..a104664d --- /dev/null +++ b/vcal.cpp @@ -0,0 +1,14 @@ +#include "vcal.h" +#include "err.h" + +std::ostream& operator<<(std::ostream& o, vcomponent* self) { + for (int i = 0; i < 40; i++) o << '_'; + + o << _YELLOW << std::endl + << "VComponet (Type := " << self->type << _RESET + << self->clines + << std::endl << "Components:" << std::endl + << self->components; + + return o; +} @@ -1,47 +1,20 @@ #ifndef VCAL_H #define VCAL_H -#include <stdlib.h> - -#include "strbuf.h" - -#define TYPE strbuf -#include "linked_list.h" -// #include "trie.h" -#undef TYPE - -#define T strbuf - #define V LLIST(strbuf) - #include "pair.h" - /* left := param_name | right := param_values */ - #define param_set PAIR(strbuf, LLIST(strbuf)) - #undef V -#undef T - -#define TYPE param_set -#include "linked_list.h" -#undef TYPE - -#define T strbuf - #define V LLIST(param_set) - #include "pair.h" - /* left := content | right := params */ - #define content_set PAIR(strbuf, LLIST(param_set)) - #undef V -#undef T - -#define TYPE content_set -#include "linked_list.h" -#undef TYPE - -#define T strbuf - #define V LLIST(content_set) - #include "pair.h" - /* left := content | right := params */ - #define content_line PAIR(strbuf, LLIST(content_set)) - #undef V -#undef T +#include <string> +#include <utility> +#include <vector> +#include <list> +#include <iostream> +#include "trie.h" + + +typedef std::pair<strbuf, std::list<strbuf> > param_set; +typedef std::pair<strbuf, std::list<param_set> > content_set; +typedef std::pair<strbuf, std::list<content_set> > content_line; + +#if 0 /* * Helper macros for accessing fields in * content_line, content_set, and param_set @@ -50,21 +23,36 @@ */ /* ptr -> ptr */ -#define CLINE_KEY(c) (&(c)->key) -#define CLINE_CUR_CSET(c) (&((c)->val.cur->value)) +#define CLINE_KEY(c) (&(c)->first) +#define CLINE_CUR_CSET(c) (&((c)->second.cur->value)) /* content_set */ -#define CLINE_CUR(c) ((c)->val.cur->value) +#define CLINE_CUR(c) ((c)->second.cur->value) /* strbuf */ -#define CLINE_CUR_VAL(c) (& CLINE_CUR(c)->key) +#define CLINE_CUR_VAL(c) (& CLINE_CUR(c)->first) -/* LLIST(param_set) */ -#define CLINE_CUR_PARAMS(c) (& CLINE_CUR(c)->val) + /* LLIST(param_set) */ +#define CLINE_CUR_PARAMS(c) (& CLINE_CUR(c)->second) + + /* strbuf */ +#define CLINE_CUR_PARAM_KEY(c) (CLINE_CUR_PARAMS(c)->cur->value->first) + /* strbuf */ +#define CLINE_CUR_PARAM_VAL(c) (CLINE_CUR_PARAMS(c)->cur->value->second.cur->value) +#endif + + struct vcomponent { + std::string filename; + std::string type; + vcomponent* parent = nullptr; + trie<content_line> clines; + std::vector<vcomponent> components; + + vcomponent(const std::string& type) : vcomponent(type, nullptr) { }; + vcomponent(const std::string& type, const std::string& filename) + : type(type) , filename(filename) { }; + + ~vcomponent(); -/* strbuf */ -#define CLINE_CUR_PARAM_KEY(c) (CLINE_CUR_PARAMS(c)->cur->value->key) -/* strbuf */ -#define CLINE_CUR_PARAM_VAL(c) (CLINE_CUR_PARAMS(c)->cur->value->val.cur->value) /* * Resolves a collision in some form of structure (probably a hash-map @@ -72,46 +60,16 @@ * to have the correct form, and returns it. Destroying new_ in the * process. */ -content_line* RESOLVE(content_line) - (content_line* dest, content_line* new_); + vcomponent* operator= (vcomponent* other); -#define TYPE content_line -#include "trie.h" -#undef TYPE + content_line& operator[] (char* key) { + return this->clines[key]; + } -typedef struct s_vcomponent vcomponent; - -#define TYPE vcomponent -#include "vector.h" -#undef TYPE - -struct s_vcomponent { - char* filename; - char* type; - vcomponent* parent; - TRIE(content_line) clines; - VECT(vcomponent) components; + void push_back(const vcomponent& child) + { this->components.push_back(child); } }; -#define FCHILD(v) GET(VECT(vcomponent))(&(v)->components, 0) - -INIT_F(vcomponent); -INIT_F(vcomponent, char* type); -INIT_F(vcomponent, char* type, char* filename); -FREE_F(vcomponent); - -content_line* get_property (vcomponent* ev, char* key); - -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. - */ -int PUSH(vcomponent)(vcomponent*, vcomponent*); - -int DEEP_COPY(vcomponent)(vcomponent*, vcomponent*); - -FMT_F(vcomponent); +std::ostream& operator<<(std::ostream&, vcomponent*); #endif /* VCAL_H */ |