summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine <sanine.not@pm.me>2023-02-06 01:01:22 -0600
committersanine <sanine.not@pm.me>2023-02-06 01:01:22 -0600
commit3d1afa579c9ce045c87e4b68a6d6068a389251a0 (patch)
treee4e569dcd1b6ae798ff59fb640dfb1ab2ff76eed
parentc5936b5e28c8f81e974bd8d9eb901832921c2b78 (diff)
add kai_tag_get_first_child_with_type() and kai_tag_get_next_sibling_with_type()
-rw-r--r--src/xml/xml.c19
-rw-r--r--src/xml/xml.h6
-rw-r--r--src/xml/xml.test.c93
3 files changed, 118 insertions, 0 deletions
diff --git a/src/xml/xml.c b/src/xml/xml.c
index 7f101ee..1b369c1 100644
--- a/src/xml/xml.c
+++ b/src/xml/xml.c
@@ -70,3 +70,22 @@ int kai_tag_num_children(struct kai_tag_t *t)
}
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;
+}
diff --git a/src/xml/xml.h b/src/xml/xml.h
index 41d4006..4849ced 100644
--- a/src/xml/xml.h
+++ b/src/xml/xml.h
@@ -29,4 +29,10 @@ char *kai_tag_attr_to_dup(struct kai_tag_t *t, const char *attr);
/* return the number of immediate children of a node */
int kai_tag_num_children(struct kai_tag_t *t);
+/* get the first child of type "type", or NULL if no such child exists */
+struct kai_tag_t * kai_tag_get_first_child_with_type(struct kai_tag_t *t, char *type);
+
+/* get the next sibling of type "type", or NULL if no such sibling exists */
+struct kai_tag_t * kai_tag_get_next_sibling_with_type(struct kai_tag_t *t, char *type);
+
#endif
diff --git a/src/xml/xml.test.c b/src/xml/xml.test.c
index 58784be..78a806c 100644
--- a/src/xml/xml.test.c
+++ b/src/xml/xml.test.c
@@ -106,5 +106,98 @@ LILY_TEST("count xml tag children")
#include LILY_PUSH_TEST()
+LILY_TEST("find first child with specified type")
+{
+ struct kai_tag_t *t, *child;
+
+ t = kai_parse_string("<no_children />");
+ child = kai_tag_get_first_child_with_type(t, "xxx");
+ CHECK_EQ(child, NULL, "%p");
+ kai_tag_destroy(t);
+
+ t = kai_parse_string(
+ "<tag>"
+ " <xxx />"
+ "</tag>"
+ );
+ child = kai_tag_get_first_child_with_type(t, "xxx");
+ REQUIRE_NEQ(child, NULL, "%p");
+ CHECK_EQS(child->type, "xxx");
+ kai_tag_destroy(t);
+ child = NULL;
+
+ t = kai_parse_string(
+ "<tag>"
+ " <qqq />"
+ " <xxx />"
+ " <yyy />"
+ "</tag>"
+ );
+ child = kai_tag_get_first_child_with_type(t, "xxx");
+ REQUIRE_NEQ(child, NULL, "%p");
+ CHECK_EQS(child->type, "xxx");
+ kai_tag_destroy(t);
+ child = NULL;
+
+ t = kai_parse_string(
+ "<tag>"
+ " <qqq />"
+ " <yyy />"
+ "</tag>"
+ );
+ child = kai_tag_get_first_child_with_type(t, "xxx");
+ CHECK_EQ(child, NULL, "%p");
+ kai_tag_destroy(t);
+}
+#include LILY_PUSH_TEST()
+
+
+LILY_TEST("find next sibling with specified type")
+{
+ struct kai_tag_t *t, *child;
+
+ t = kai_parse_string(
+ "<tag>"
+ " <qqq />"
+ " <xxx />"
+ "</tag>"
+ );
+ child = t->children;
+ child = kai_tag_get_next_sibling_with_type(child, "xxx");
+ REQUIRE_NEQ(child, NULL, "%p");
+ CHECK_EQS(child->type, "xxx");
+ kai_tag_destroy(t);
+ child = NULL;
+
+ t = kai_parse_string(
+ "<tag>"
+ " <qqq />"
+ " <xxx />"
+ " <yyy />"
+ "</tag>"
+ );
+ child = t->children;
+ child = kai_tag_get_next_sibling_with_type(child, "xxx");
+ REQUIRE_NEQ(child, NULL, "%p");
+ CHECK_EQS(child->type, "xxx");
+ kai_tag_destroy(t);
+ child = NULL;
+
+ t = kai_parse_string(
+ "<tag>"
+ " <qqq />"
+ " <yyy />"
+ "</tag>"
+ );
+ child = t->children;
+ child = kai_tag_get_next_sibling_with_type(child, "xxx");
+ CHECK_EQ(child, NULL, "%p");
+ kai_tag_destroy(t);
+}
+#include LILY_PUSH_TEST()
+
+
+
+
#define LILY_FILE_END
#include LILY_REGISTER_TESTS()