#include #include #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; }