#include #include "xml.h" /* parse a string into a document */ struct kai_tag_t * kai_parse_string(const char *str) { yyscan_t scanner; struct kai_tag_t *document; kalmialex_init(&scanner); YY_BUFFER_STATE buf = kalmia_scan_string(str, scanner); int result = kalmiaparse(scanner, &document); kalmia_delete_buffer(buf, scanner); kalmialex_destroy(scanner); if (result != 0) { return NULL; } return document; } char * kai_tag_get_attr(struct kai_tag_t *t, const char *attr) { struct kai_attr_t *a = t->attrs; while (a != NULL) { if (strcmp(a->key, attr) == 0) { return a->value; } a = a->next; } return NULL; } long kai_tag_attr_to_long( struct kai_tag_t *t, const char *attr, long base) { char *val = kai_tag_get_attr(t, attr); if (val == NULL) { /* attribute not present, fall back to base */ return base; } else { return strtol(val, NULL, 10); } } char *kai_tag_attr_to_dup(struct kai_tag_t *t, const char *attr) { char *val = kai_tag_get_attr(t, attr); if (val == NULL) { return NULL; } else { return strdup(val); } } int kai_tag_num_children(struct kai_tag_t *t) { int count = 0; struct kai_tag_t *child = t->children; while (child != NULL) { count += 1; child = child->next; } return count; } struct kai_tag_t * kai_tag_get_first_child_with_type(struct kai_tag_t *t, char *type) { struct kai_tag_t *child = t->children; for (; child != NULL; child = child->next) { if (strcmp(child->type, type) == 0) { return child; } } return NULL; } struct kai_tag_t * kai_tag_get_next_sibling_with_type(struct kai_tag_t *t, char *type) { for (t = t->next; t != NULL; t = t->next) { if (strcmp(t->type, type) == 0) { return t; } } return NULL; }