diff options
Diffstat (limited to 'wv_dom.c')
| -rw-r--r-- | wv_dom.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/wv_dom.c b/wv_dom.c new file mode 100644 index 0000000..ee24e98 --- /dev/null +++ b/wv_dom.c @@ -0,0 +1,88 @@ +#include <string.h> +#include <stdio.h> + +#include "wv_dom.h" + +wv_ref wv_node_new(struct wv_arena *arena, wv_node_type type) +{ + wv_ref ref; + struct wv_node *node; + + ref = wv_alloc(arena, sizeof(struct wv_node)); + node = (struct wv_node *)WV_ADDR(arena, ref); + memset(node, 0, sizeof(struct wv_node)); + node->type = type; + + return ref; +} + +void wv_node_append(struct wv_arena *arena, wv_ref parent_ref, + wv_ref child_ref) +{ + struct wv_node *p, *c, *last; + + if (!parent_ref || !child_ref) + return; + + p = (struct wv_node *)WV_ADDR(arena, parent_ref); + c = (struct wv_node *)WV_ADDR(arena, child_ref); + + c->parent = parent_ref; + + if (!p->first_child) { + /* This is the parent's only child */ + p->first_child = child_ref; + } else { + /* Link to the current tail of the child list */ + last = (struct wv_node *)WV_ADDR(arena, p->last_child); + last->next_sibling = child_ref; + c->prev_sibling = p->last_child; + } + + p->last_child = child_ref; +} + +void wv_attr_set(struct wv_arena *arena, wv_ref node_ref, + wv_ref key_str, wv_ref val_str) +{ + wv_ref attr_ref; + struct wv_node *n; + struct wv_attr *a; + + n = (struct wv_node *)WV_ADDR(arena, node_ref); + if (n->type != WV_NODE_ELEMENT) return; + + attr_ref = wv_alloc(arena, sizeof(struct wv_attr)); + a = (struct wv_attr *)WV_ADDR(arena, attr_ref); + + a->key = key_str; + a->val = val_str; + + // Link attribute to the head of the list (prepend) + a->next = n->u.element.attr_head; + n->u.element.attr_head = attr_ref; +} + +wv_ref wv_attr_get(struct wv_arena *arena, wv_ref node_ref, + const char *key_name) +{ + wv_ref curr; + struct wv_node *n; + struct wv_attr *a; + + n = (struct wv_node *)WV_ADDR(arena, node_ref); + if (n->type != WV_NODE_ELEMENT) + return 0; + + curr = n->u.element.attr_head; + while (curr != 0) { + a = (struct wv_attr *)WV_ADDR(arena, curr); + const char *attr_key = (const char *)WV_ADDR(arena, a->key); + if (strcmp(attr_key, key_name) == 0) + return a->val; + curr = a->next; + } + + return 0; +} + |
