Browse Source

New easy xml interface

Squashed commit of the following:

commit 7300b93a1f
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:51:19 2012 +0100

    Easy development...

commit 66b764840d
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:50:11 2012 +0100

    Easy development...

commit 62e4801612
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:47:26 2012 +0100

    Easy development...

commit d3b67262ff
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:47:08 2012 +0100

    Easy development...

commit 65661e2ac0
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:45:05 2012 +0100

    Easy development...

commit 3ae765fd82
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:44:58 2012 +0100

    Easy development...

commit c6d1a3bb2c
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:44:36 2012 +0100

    Easy development...

commit deb9846236
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:44:13 2012 +0100

    Easy development...

commit 53cb08c3fc
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:43:41 2012 +0100

    Easy development...

commit ce3766de25
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:40:47 2012 +0100

    Easy development...

commit 9df056a6a0
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:37:59 2012 +0100

    Easy interface...

commit c6b1797f0a
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:37:49 2012 +0100

    Easy interface...

commit b72f20c42d
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:37:32 2012 +0100

    Easy interface...

commit 9d9e3994a3
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:36:52 2012 +0100

    Easy interface...

commit fe43225e7d
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:36:18 2012 +0100

    Easy interface...

commit 9881f5516d
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:35:55 2012 +0100

    Easy interface...

commit 5a0b4197be
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:35:23 2012 +0100

    Easy interface...

commit e4bce00912
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:34:47 2012 +0100

    Easy interface...

commit 0872374b18
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:33:56 2012 +0100

    Easy interface...

commit fa075c61c6
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:31:58 2012 +0100

    Easy interface...

commit 221f9cd044
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:30:12 2012 +0100

    Easy interface...

commit ec2b858a82
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:29:32 2012 +0100

    Easy interface...

commit 4159c73181
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:29:17 2012 +0100

    Easy interface...

commit e040c00436
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:28:35 2012 +0100

    Easy interface...

commit a34b05154c
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:27:39 2012 +0100

    Easy interface...

commit f9b46f112b
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:26:37 2012 +0100

    Easy interface...

commit d049b2f822
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:26:24 2012 +0100

    Easy interface...

commit 8ff31ce1f3
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:25:39 2012 +0100

    Easy interface...

commit 004a580c6b
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:25:12 2012 +0100

    Easy interface...

commit 29d1070b98
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:23:57 2012 +0100

    Easy interface...

commit 158f5db904
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:23:40 2012 +0100

    Easy interface...

commit 9f761ff51b
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:21:27 2012 +0100

    Easy interface...

commit 795c6464ca
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:19:08 2012 +0100

    Easy interface...

commit 64f60cddad
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:18:32 2012 +0100

    Easy interface...

commit d0c595ea84
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:18:23 2012 +0100

    Easy interface...

commit 4a593ce313
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:17:59 2012 +0100

    Easy interface...

commit a1552478a0
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:15:54 2012 +0100

    Easy interface...

commit ac2184dee3
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:14:57 2012 +0100

    Easy interface...

commit 393cbe4bf0
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:14:31 2012 +0100

    Easy interface...

commit a56995ac8a
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:13:55 2012 +0100

    Easy interface...

commit 921d7d6740
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:07:57 2012 +0100

    Easy interface...

commit fe7de39d75
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 14:04:36 2012 +0100

    Easy interface...

commit e6e158dd43
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 13:59:29 2012 +0100

    Easy interface...

commit 9bb88f95d4
Author: ooxi <85fcd0ef4ec8@f977375cdcd6.anonbox.net>
Date:   Thu Nov 1 13:59:01 2012 +0100

    Easy interface...
master
ooxi 12 years ago
parent
commit
4ec6006b64
4 changed files with 190 additions and 3 deletions
  1. +1
    -1
      CMakeLists.txt
  2. +111
    -2
      src/xml.c
  3. +25
    -0
      src/xml.h
  4. +53
    -0
      test/test-xml.c

+ 1
- 1
CMakeLists.txt View File

@@ -2,7 +2,7 @@
PROJECT(xml)
SET(VERSION_MAJOR "0")
SET(VERSION_MINOR "1")
SET(VERSION_PATCH "2")
SET(VERSION_PATCH "3")
CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)


+ 111
- 2
src/xml.c View File

@@ -22,6 +22,7 @@
*/
#include <ctype.h>
#include <malloc.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -37,7 +38,7 @@
* UTF-8 text
*/
struct xml_string {
uint8_t* buffer;
uint8_t const* buffer;
size_t length;
};

@@ -59,7 +60,11 @@ struct xml_node {
* An xml_document simply contains the root node and the underlying buffer
*/
struct xml_document {
struct xml_string buffer;
struct {
uint8_t* buffer;
size_t length;
} buffer;

struct xml_node* root;
};

@@ -134,6 +139,20 @@ static _Bool xml_string_equals(struct xml_string* a, struct xml_string* b) {



/**
* [PRIVATE]
*/
static uint8_t* xml_string_clone(struct xml_string* s) {
uint8_t* clone = calloc(s->length + 1, sizeof(uint8_t));

xml_string_copy(s, clone, s->length);
clone[s->length] = 0;

return clone;
}



/**
* [PRIVATE]
*
@@ -715,6 +734,96 @@ struct xml_node* xml_node_child(struct xml_node* node, size_t child) {



/**
* [PUBLIC API]
*/
struct xml_node* xml_easy_child(struct xml_node* node, uint8_t const* child_name, ...) {

/* Find childrens, one by one
*/
struct xml_node* current = node;

va_list arguments;
va_start(arguments, child_name);


/* Descent to current.child
*/
while (child_name) {

/* Convert child_name to xml_string for easy comparison
*/
struct xml_string cn = {
.buffer = child_name,
.length = strlen(child_name)
};

/* Interate through all children
*/
struct xml_node* next = 0;

size_t i = 0; for (; i < xml_node_children(current); ++i) {
struct xml_node* child = xml_node_child(current, i);

if (xml_string_equals(xml_node_name(child), &cn)) {
if (!next) {
next = child;

/* Two children with the same name
*/
} else {
return 0;
}
}
}

/* No child with that name found
*/
if (!next) {
return 0;
}
current = next;
/* Find name of next child
*/
child_name = va_arg(arguments, uint8_t const*);
}
va_end(arguments);


/* Return current element
*/
return current;
}



/**
* [PUBLIC API]
*/
uint8_t* xml_easy_name(struct xml_node* node) {
if (!node) {
return 0;
}

return xml_string_clone(xml_node_name(node));
}



/**
* [PUBLIC API]
*/
uint8_t* xml_easy_content(struct xml_node* node) {
if (!node) {
return 0;
}

return xml_string_clone(xml_node_content(node));
}



/**
* [PUBLIC API]
*/


+ 25
- 0
src/xml.h View File

@@ -107,6 +107,31 @@ struct xml_node* xml_node_child(struct xml_node* node, size_t child);



/**
* @return The node described by the path or 0 if child cannot be found
* @warning Each element on the way must be unique
* @warning Last argument must be 0
*/
struct xml_node* xml_easy_child(struct xml_node* node, uint8_t const* child, ...);



/**
* @return 0-terminated copy of node name
* @warning User must free the result
*/
uint8_t* xml_easy_name(struct xml_node* node);



/**
* @return 0-terminated copy of node content
* @warning User must free the result
*/
uint8_t* xml_easy_content(struct xml_node* node);



/**
* @return Length of the string
*/


+ 53
- 0
test/test-xml.c View File

@@ -141,6 +141,58 @@ static void test_xml_parse_document_1() {



/**
* Tests the eas functionality
*/
static void test_xml_parse_document_2() {
SOURCE(source, ""
"<Parent>\n"
"\t<Child>\n"
"\t\tFirst content\n"
"\t</Child>\n"
"\t<This><Is>\n"
"<A><Test>Content A</Test></A>\n"
"<B><Test>Content B</Test></B>\n"
"\t</Is></This>\n"
"\t<Child>\n"
"\t\tSecond content\n"
"\t</Child>\n"
"</Parent>\n"
);
struct xml_document* document = xml_parse_document(source, strlen(source));
assert_that(document, "Could not parse document");

struct xml_node* root = xml_document_root(document);
assert_that(string_equals(xml_node_name(root), "Parent"), "root node name must be `Parent'");
assert_that(3 == xml_node_children(root), "root must have two children");

struct xml_node* test_a = xml_easy_child(root, "This", "Is", "A", "Test", 0);
assert_that(test_a, "Cannot find Parent/This/Is/A/Test");
assert_that(string_equals(xml_node_content(test_a), "Content A"), "Content of Parent/This/Is/A/Test must be `Content A'");

struct xml_node* test_b = xml_easy_child(root, "This", "Is", "B", "Test", 0);
assert_that(test_b, "Cannot find Parent/This/Is/B/Test");
assert_that(string_equals(xml_node_content(test_b), "Content B"), "Content of Parent/This/Is/B/Test must be `Content B'");

struct xml_node* test_c = xml_easy_child(root, "This", "Is", "C", "Test", 0);
assert_that(!test_c, "Must not find Parent/This/Is/C/Test because no such path exists");

struct xml_node* must_be_null = xml_easy_child(root, "Child");
assert_that(!must_be_null, "Parent/Child cannot be a valid expression, because there are two children named `Child' in `Parent'");

uint8_t* name_is = xml_easy_name(xml_easy_child(root, "This", "Is", 0));
assert_that(!strcmp(name_is, "Is"), "Name of Parent/This/Is must be `Is'");
free(name_is);

uint8_t* content_a = xml_easy_content(test_a);
assert_that(!strcmp(content_a, "Content A"), "Content of Parent/This/Is/A/Test must be `Content A'");
free(content_a);

xml_document_free(document, true);
}





/**
@@ -149,6 +201,7 @@ static void test_xml_parse_document_1() {
int main(int argc, char** argv) {
test_xml_parse_document_0();
test_xml_parse_document_1();
test_xml_parse_document_2();

fprintf(stdout, "All tests passed :-)\n");
exit(EXIT_SUCCESS);


Loading…
Cancel
Save