From 6d320b0386aa4d7c6bfe2d6fce3d68e227752bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Tue, 19 Feb 2019 22:27:43 +0100 Subject: Further C++ improvements, maybe doesn't segfault now. --- parse.cpp | 43 ++++++++------------ strbuf.h | 4 ++ trie.cpp | 124 --------------------------------------------------------- trie.h | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- vcal.h | 49 ++++++++++++++--------- 5 files changed, 184 insertions(+), 171 deletions(-) delete mode 100644 trie.cpp diff --git a/parse.cpp b/parse.cpp index 1b186d4c..d6da0bb4 100644 --- a/parse.cpp +++ b/parse.cpp @@ -30,12 +30,7 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { if (fold(f, &ctx, c) > 0) { /* Actuall end of line, handle value */ - // std::string& target = CLINE_CUR_VAL(&cline); - // TODO solve current; - // std::string& target = cline - - cline.value() = ctx.str; - cline.value().cap(); + cline.push_value(ctx.str); ctx.str.soft_reset(); handle_kv(&cline, &ctx); @@ -86,10 +81,12 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { /* Border between param {key, value} */ } else if (p_ctx == p_param_name && c == '=') { - strbuf cpy = ctx.str; - cpy.cap(); + + // ctx.str holds param_key; + // cline.values.back()->params.push_back(new __param_set(ctx.str)); + cline.values.back()->push_param_key(ctx.str); + ctx.str.soft_reset(); - cline.push_param_key (cpy); p_ctx = p_param_value; @@ -105,21 +102,17 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { if (p_ctx == p_param_value) { /* push kv pair */ - auto s = new strbuf(ctx.str); - s->cap(); + cline.values.back()->push_param_value(ctx.str); ctx.str.soft_reset(); - - cline.push_param_value (s); } if (p_ctx == p_key) { + /* set key for content line */ cline.key = ctx.str; cline.key.cap(); ctx.str.soft_reset(); - // TODO? - // content_set* p = new content_set; - // cline.second.push(p); + } if (c == ':') p_ctx = p_value; @@ -144,14 +137,13 @@ int parse_file(char* filename, FILE* f, vcomponent* root) { * the end here. */ - //strbuf* target = CLINE_CUR_VAL(&cline); - cline.value() = ctx.str; - cline.value().cap(); - ctx.str.soft_reset(); - ++ctx.line; ctx.column = 0; + cline.values.back()->value = ctx.str; + cline.values.back()->value.cap(); + ctx.str.soft_reset(); + handle_kv(&cline, &ctx); } @@ -174,21 +166,20 @@ int handle_kv ( * and possibly some others I forget. */ - strbuf* s = new strbuf(cline->value()); - ctx->key_stack.push(s); + ctx->key_stack.push(new strbuf(ctx->str)); - cline->values.reset(); + // cline->values.reset(); // TODO ompty cline->second here; // RESET(LLIST(content_set))(&cline->val); - auto e = new vcomponent(s->to_string(), ctx->filename); + auto e = new vcomponent(ctx->str.to_string(), ctx->filename); e->parent = ctx->comp_stack.top(); ctx->comp_stack.push(e); } else if (cline->key == "END") { // strbuf* s = POP(LLIST(strbuf))(&ctx->key_stack); strbuf* s = ctx->key_stack.top(); ctx->key_stack.pop(); - if (*s == cline->value()) { + if (*s == ctx->str) { #if 0 ERR_P(ctx, "Expected END:%s, got END:%s.\n%s line", s->mem, diff --git a/strbuf.h b/strbuf.h index 04457c0d..38a45b09 100644 --- a/strbuf.h +++ b/strbuf.h @@ -75,6 +75,10 @@ struct strbuf { std::string to_string() { return std::string (this->mem); } + + char* c_str() { + return this->mem; + } }; /* diff --git a/trie.cpp b/trie.cpp deleted file mode 100644 index e3158a2b..00000000 --- a/trie.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "trie.h" - -template -trie_node::trie_node (char c, trie_node* next, trie_node* child) { - this->c = c; - this->next = next; - this->child = child; -} - -template -int trie::push_back (const char* key, const T& item) { - trie_node *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(*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(*subkey); - cur->next = t; - last = cur; - cur = t; - } - } -} - -template -T& trie::operator[] (const char* key) { - trie_node* 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 -std::ostream& operator<<(std::ostream& o, trie_node* 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* 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 -std::ostream& operator<<(std::ostream& o, trie* trie) { - o << "Trie: " << trie << " {\n"; - o << trie->root->child; - o << "}"; - return o; -} diff --git a/trie.h b/trie.h index 4613694e..4e01e837 100644 --- a/trie.h +++ b/trie.h @@ -3,6 +3,9 @@ #include +#include +#include + template struct trie_node { char c; @@ -23,9 +26,9 @@ struct trie { trie () : root (new trie_node ('\0')) { } - int push_back (const char* key, const T&); + int push (const char* key, T* item); - T& operator[] ( const char* key ); + T* operator[] ( const char* key ); bool empty () { return this->root->child == NULL; } }; @@ -33,4 +36,132 @@ struct trie { template std::ostream& operator<<(std::ostream&, trie* trie); +template +trie_node::trie_node (char c, trie_node* next, trie_node* child) { + this->c = c; + this->next = next; + this->child = child; +} + +template +int trie::push (const char* key, T* item) { + trie_node *cur, *last; + + last = this->root; + cur = last->child; + + // TODO subkey is never collected + char* subkey = static_cast(malloc(strlen(key))); + strcpy (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(*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(*subkey); + cur->next = t; + last = cur; + cur = t; + } + } +} + +template +T* trie::operator[] (const char* key) { + trie_node* n = this->root->child; + + // TODO subkey is never collected + char* subkey = static_cast(malloc(strlen(key))); + strcpy (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 +std::ostream& operator<<(std::ostream& o, trie_node* 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* 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 +std::ostream& operator<<(std::ostream& o, trie* trie) { + o << "Trie: " << trie << " {\n"; + o << trie->root->child; + o << "}"; + return o; +} + #endif /* TRIE_H */ diff --git a/vcal.h b/vcal.h index ea76e593..21f66063 100644 --- a/vcal.h +++ b/vcal.h @@ -13,9 +13,14 @@ struct __param_set { strbuf key; - llist values; + std::list values; - __param_set (strbuf key) : key (key) { } + __param_set (strbuf key) : key (key) { this->key.cap(); } + + void push_value (strbuf val) { + this->values.push_back(val); + this->values.back().cap(); + } }; /* @@ -24,7 +29,17 @@ struct __param_set { */ struct __content_set { strbuf value; - llist<__param_set> params; + std::list<__param_set*> params; + + __content_set (strbuf value) : value(value) { this->value.cap(); } + + void push_param_key (strbuf key) { + this->params.push_back (new __param_set(key)); + } + + void push_param_value (strbuf val) { + this->params.back()->push_value(val); + } }; /* @@ -33,18 +48,12 @@ struct __content_set { */ struct content_line { strbuf key; - llist<__content_set> values; - - inline void push_param_key (strbuf key) { - auto p = new __param_set(key); - this->values.cur()->params.push(p); - } - - inline void push_param_value (strbuf* value) - { this->values.cur()->params.cur()->values.push(value); } - - inline strbuf& value() { return this->values.cur()->value; } + // llist<__content_set> values; + std::list<__content_set*> values; + void push_value (strbuf str) { + this->values.push_back(new __content_set(str)); + } }; struct vcomponent { @@ -58,6 +67,9 @@ struct vcomponent { vcomponent(const std::string& type, const std::string& filename); + void add_content_line (content_line* c) { + clines.push(c->key.c_str(), c); + } /* * Resolves a collision in some form of structure (probably a hash-map @@ -67,18 +79,17 @@ struct vcomponent { */ vcomponent* operator= (vcomponent* other); - content_line& operator[] (const char* key) { - return this->clines[key]; - } + content_line* operator[] (const char* key) + { return this->clines[key]; } void push_back(const vcomponent& child) - { this->components.push_back(child); } + { this->components.push_back(child); } }; std::ostream& operator<<(std::ostream&, vcomponent*); -#if 1 +#if 0 /* * Helper macros for accessing fields in * content_line, content_set, and param_set -- cgit v1.2.3