diff options
Diffstat (limited to 'libs/xml.c/test/test-huitre39.c')
| -rw-r--r-- | libs/xml.c/test/test-huitre39.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/libs/xml.c/test/test-huitre39.c b/libs/xml.c/test/test-huitre39.c new file mode 100644 index 0000000..43b9ae7 --- /dev/null +++ b/libs/xml.c/test/test-huitre39.c @@ -0,0 +1,181 @@ +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "./xml.h" + + + + + +/** + * Will halt the program iff assertion fails + */ +static void _assert_that(_Bool condition, char const* message, char const* func, char const* file, int line) { + if (!condition) { + fprintf(stderr, "Assertion failed: %s, in %s (%s:%i)\n", message, func, file, line); + exit(EXIT_FAILURE); + } +} + +#define assert_that(condition, message) \ + _assert_that(condition, message, __func__, __FILE__, __LINE__) + + + + + +/** + * Behaves similar to `getElementsByTagName`, however returns just the first and + * not all elements with a given tag name + * + * @param base Node in tree which should be the start of te recursive search + * @param 0-terminated tag name, case sensitive + * + * @return First node below `base` iff found, otherwise 0 + * @warning Depth-First search! + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName + */ +static struct xml_node* get_node_by_name(struct xml_node* base, uint8_t* name) { + + + /* Check whether `base` already has the tag name we are searching for + */ + size_t const name_length = strlen(name); + + uint8_t* base_name = xml_easy_name(base); + size_t const base_name_length = strlen(base_name); + + + /* Length of `name` and `base_name` do match, we should now do a real + * comparison + */ + if (name_length == base_name_length) { + int const rs = memcmp(name, base_name, name_length); + + /* Names match! We have found an element which fullfills our + * search criteria + */ + if (!rs) { + free(base_name); + return base; + } + } + + + /* Unfortunately, `base` is not the element we are looking for :-( + */ + free(base_name); + + + /* Let's take a look at the children of `base` + */ + size_t const number_of_children = xml_node_children(base); + + + /* No children → No luck with base + */ + if (!number_of_children) { + return 0; + } + + + /* Recursivly look through all children + */ + size_t child = 0; for (; child < number_of_children; ++child) { + struct xml_node* child_node = xml_node_child(base, child); + + /* Maybe this child does contain the element we are looking for? + */ + struct xml_node* search_result = get_node_by_name( + child_node, name + ); + + /* We are lucky! + */ + if (search_result) { + return search_result; + } + } + + + /* No luck :-( + */ + return 0; +} + + + + + +int main(int argc, char** argv) { + + /* XML source, could be read from disk + */ + uint8_t* source = "" + "<Root>" + "<Hello>World</Hello>" + + "<Functions>" + "<Function>" + "<as>testas one</as>" + "<os>testos</os>" + "</Function>" + + "<Function>" + "<is>testis</is>" + "<us>testus</us>" + "<ls>testls</ls>" + "</Function>" + + "<Function>" + "<mn>testmn</mn>" + "<as>testas two</as>" + "</Function>" + "</Functions>" + "</Root>" + ; + + struct xml_document* document = xml_parse_document(source, strlen(source)); + + if (!document) { + printf("Could parse document\n"); + exit(EXIT_FAILURE); + } + struct xml_node* root = xml_document_root(document); + + + + /* We expect to find Root / Functions / Function#1 / us + */ + struct xml_node* us = get_node_by_name(root, "us"); + assert_that(us, "Did not find element by tag name `us'"); + + uint8_t* us_content = xml_easy_content(us); + assert_that(us_content, "`us' should have content"); + assert_that(!strcmp(us_content, "testus"), "Unexpected content for node `us'"); + free(us_content); + + + /* We expect to find Root / Functions / Function#0 / as + */ + struct xml_node* as = get_node_by_name(root, "as"); + assert_that(as, "Did not find element by tag name `as'"); + + uint8_t* as_content = xml_easy_content(as); + assert_that(as_content, "`as' should have content"); + assert_that(!strcmp(as_content, "testas one"), "Unexpected content for first `as' node"); + free(as_content); + + + /* We do not expect do find a node with tag name `does_not_exist' + */ + struct xml_node* does_not_exist = get_node_by_name(root, "does_not_exist"); + assert_that(!does_not_exist, "Found node that should not exist"); + + + + xml_document_free(document, false); +} + |
