summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/kit/dynamic_array.c1
-rw-r--r--source/kit/dynamic_array.h15
-rw-r--r--source/kit/string_ref.h9
-rw-r--r--source/kit/xml.c324
4 files changed, 170 insertions, 179 deletions
diff --git a/source/kit/dynamic_array.c b/source/kit/dynamic_array.c
index 2b17d07..ede817b 100644
--- a/source/kit/dynamic_array.c
+++ b/source/kit/dynamic_array.c
@@ -1,7 +1,6 @@
#include "dynamic_array.h"
#include <assert.h>
-#include <string.h>
void kit_da_init(kit_da_void_t *array, i64 element_size, i64 size,
kit_allocator_t *alloc) {
diff --git a/source/kit/dynamic_array.h b/source/kit/dynamic_array.h
index df7b933..e868917 100644
--- a/source/kit/dynamic_array.h
+++ b/source/kit/dynamic_array.h
@@ -3,6 +3,8 @@
#include "allocator.h"
+#include <string.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -46,11 +48,14 @@ void kit_da_resize_exact(kit_da_void_t *array, i64 element_size,
/* Destroy dynamic array.
*/
-#define KIT_DA_DESTROY(array_) \
- do { \
- if ((array_).values != NULL) \
- kit_alloc_dispatch((array_).alloc, KIT_DEALLOCATE, 0, 0, \
- (array_).values); \
+#define KIT_DA_DESTROY(array_) \
+ do { \
+ if ((array_).values != NULL) \
+ kit_alloc_dispatch((array_).alloc, KIT_DEALLOCATE, 0, \
+ (array_).capacity * \
+ sizeof((array_).values[0]), \
+ (array_).values); \
+ memset(&(array_), 0, sizeof(array_)); \
} while (0)
/* Resize dynamic array.
diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h
index 89c319b..38ade80 100644
--- a/source/kit/string_ref.h
+++ b/source/kit/string_ref.h
@@ -34,7 +34,8 @@ static char *kit_make_bs(kit_str_t s) {
i64 n = s.size;
if (n > 4095)
n = 4095;
- memcpy(buf[index], s.values, n);
+ if (n > 0)
+ memcpy(buf[index], s.values, n);
buf[index][n] = '\0';
char *result = buf[index];
index = (index + 1) % 8;
@@ -51,11 +52,11 @@ static char *kit_make_bs(kit_str_t s) {
#define KIT_WRAP_BS(string_) kit_str(strlen(string_), (string_))
-#define KIT_WRAP_STR(string_) \
- kit_str((string_).size, (string_).values)
+#define KIT_WRAP_STR(...) \
+ kit_str((__VA_ARGS__).size, (__VA_ARGS__).values)
#ifndef KIT_DISABLE_SHORT_NAMES
-# define BS(string_) kit_make_bs(KIT_WRAP_STR(string_))
+# define BS(...) kit_make_bs(KIT_WRAP_STR(__VA_ARGS__))
# define str_t kit_str_t
diff --git a/source/kit/xml.c b/source/kit/xml.c
index 2bef6d5..ed11b18 100644
--- a/source/kit/xml.c
+++ b/source/kit/xml.c
@@ -4,8 +4,9 @@
#include <assert.h>
typedef struct {
- ib_t last;
- kit_xml_t xml;
+ ib_t last;
+ kit_str_builder_t text;
+ kit_da_xml_t tags;
} kit_xml_intermediate_t;
static kit_xml_intermediate_t kit_xml_parse_buf_(
@@ -17,210 +18,195 @@ static kit_xml_intermediate_t kit_xml_parse_buf_(
memset(&last, 0, sizeof last);
memset(&spaces, 0, sizeof spaces);
- ib_t tag_open = ib_exact(begin, SZ("<"));
- ib_t tag_name = ib_none(tag_open, SZ(" \t\r\n/>"));
- last = ib_copy(tag_name);
+ ib_t tag_text = ib_until(begin, SZ("<"));
+ last = ib_copy(tag_text);
- DA_INIT(res.xml.properties, 0, alloc);
+ DA_INIT(res.tags, 0, alloc);
for (;;) {
- spaces = ib_any(last, SZ(" \t\r\n"));
- ib_t property = ib_none(spaces, SZ(" \t\r\n=/>"));
- ib_destroy(spaces);
-
- if (property.status != KIT_OK || property.data.size == 0) {
- ib_destroy(property);
+ ib_t tagend_open = ib_exact(last, SZ("</"));
+ ib_destroy(tagend_open);
+ if (tagend_open.status == KIT_OK)
break;
- }
-
- spaces = ib_any(property, SZ(" \t\r\n"));
- ib_t equals = ib_exact(spaces, SZ("="));
- ib_destroy(spaces);
- spaces = ib_any(equals, SZ(" \t\r\n"));
- ib_t value_open = ib_exact(spaces, SZ("\""));
- ib_t value_text = ib_until(value_open, SZ("\""));
- ib_t value_close = ib_exact(value_text, SZ("\""));
-
- if (value_close.status == KIT_OK) {
- i64 n = res.xml.properties.size;
- DA_RESIZE(res.xml.properties, n + 1);
-
- if (res.xml.properties.size != n + 1) {
- res.last = value_close;
- res.last.status = KIT_ERROR_BAD_ALLOC;
-
- ib_destroy(begin);
- ib_destroy(tag_open);
- ib_destroy(tag_name);
- ib_destroy(last);
- ib_destroy(spaces);
- ib_destroy(property);
- ib_destroy(equals);
- ib_destroy(value_open);
- ib_destroy(value_text);
-
- DA_DESTROY(res.xml.properties);
- return res;
- }
- // move
- res.xml.properties.values[n].name = property.data;
- memset(&property.data, 0, sizeof property.data);
+ ib_t tag_open = ib_exact(last, SZ("<"));
- // move
- res.xml.properties.values[n].value = value_text.data;
- memset(&value_text.data, 0, sizeof value_text.data);
+ if (tag_open.status != KIT_OK) {
+ ib_destroy(tag_open);
+ break;
}
- ib_destroy(last);
- last = ib_copy(value_close);
+ xml_t tag;
+ memset(&tag, 0, sizeof tag);
+ spaces = ib_any(tag_open, SZ(" \t\r\n"));
+ ib_t tag_name = ib_none(spaces, SZ(" \t\r\n/>"));
ib_destroy(spaces);
- ib_destroy(property);
- ib_destroy(equals);
- ib_destroy(value_open);
- ib_destroy(value_text);
- ib_destroy(value_close);
- if (value_close.status != KIT_OK)
- break;
- }
-
- spaces = ib_any(last, SZ(" \t\r\n"));
- ib_t tag_close = ib_exact(spaces, SZ(">"));
- ib_t tag_close_empty = ib_exact(spaces, SZ("/>"));
+ DA_INIT(tag.properties, 0, alloc);
- ib_destroy(last);
- ib_destroy(spaces);
+ ib_destroy(last);
+ last = ib_copy(tag_name);
-#define return_ \
- ib_destroy(begin); \
- ib_destroy(tag_open); \
- ib_destroy(tag_name); \
- ib_destroy(tag_close); \
- ib_destroy(tag_close_empty); \
- return
+ for (;;) {
+ spaces = ib_any(last, SZ(" \t\r\n"));
+ ib_t property = ib_none(spaces, SZ(" \t\r\n=/>"));
+ ib_destroy(spaces);
- if (tag_close_empty.status == KIT_OK) {
- ib_t tag_tail = ib_until(tag_close_empty, SZ("<"));
+ if (property.status != KIT_OK || property.data.size == 0) {
+ ib_destroy(property);
+ break;
+ }
- if (tag_tail.status != KIT_OK) {
- res.last = tag_tail;
+ spaces = ib_any(property, SZ(" \t\r\n"));
+ ib_t equals = ib_exact(spaces, SZ("="));
+ ib_destroy(spaces);
+ spaces = ib_any(equals, SZ(" \t\r\n"));
+ ib_t value_open = ib_exact(spaces, SZ("\""));
+ ib_destroy(spaces);
+ ib_t value_text = ib_until(value_open, SZ("\""));
+ ib_t value_close = ib_exact(value_text, SZ("\""));
+
+ ib_destroy(last);
+ last = value_close;
+
+ if (last.status == KIT_OK) {
+ i64 n = tag.properties.size;
+ DA_RESIZE(tag.properties, n + 1);
+
+ if (tag.properties.size != n + 1) {
+ last.status = KIT_ERROR_BAD_ALLOC;
+ DA_DESTROY(tag.properties);
+ } else {
+ // move
+ tag.properties.values[n].name = property.data;
+ memset(&property.data, 0, sizeof property.data);
+
+ // move
+ tag.properties.values[n].value = value_text.data;
+ memset(&value_text.data, 0, sizeof value_text.data);
+ }
+ }
- DA_DESTROY(res.xml.properties);
- return_ res;
+ ib_destroy(property);
+ ib_destroy(equals);
+ ib_destroy(value_open);
+ ib_destroy(value_text);
}
- // move
- res.xml.tag = tag_name.data;
- memset(&tag_name.data, 0, sizeof tag_name.data);
-
- // move
- res.xml.tail = tag_tail.data;
- memset(&tag_tail.data, 0, sizeof tag_tail.data);
-
- DA_INIT(res.xml.text, 0, alloc);
- DA_INIT(res.xml.children, 0, alloc);
+ spaces = ib_any(last, SZ(" \t\r\n"));
+ ib_t tag_close = ib_exact(spaces, SZ(">"));
+ ib_t tag_close_empty = ib_exact(spaces, SZ("/>"));
+ ib_destroy(spaces);
- res.last = tag_tail;
- return_ res;
- }
+ if (tag_close.status == KIT_OK) {
+ kit_xml_intermediate_t im = kit_xml_parse_buf_(tag_close,
+ alloc);
+ tag.text = im.text;
+ tag.children = im.tags;
+
+ tagend_open = ib_exact(im.last, SZ("</"));
+ ib_destroy(im.last);
+ spaces = ib_any(tagend_open, SZ(" \t\r\n"));
+ ib_t tagend_name = ib_exact(spaces, WRAP_STR(tag_name.data));
+ ib_destroy(spaces);
+ spaces = ib_any(tagend_name, SZ(" \t\r\n"));
+ ib_t tagend_close = ib_exact(spaces, SZ(">"));
+ ib_destroy(spaces);
+ ib_destroy(tagend_open);
+ ib_destroy(tagend_name);
+
+ ib_destroy(last);
+ last = tagend_close;
+
+ } else if (tag_close_empty.status == KIT_OK) {
+ ib_destroy(last);
+ last = ib_copy(tag_close_empty);
+
+ DA_INIT(tag.text, 0, alloc);
+ DA_INIT(tag.children, 0, alloc);
+ } else
+ last.status = KIT_ERROR_INTERNAL;
+
+ ib_t tag_tail = ib_until(last, SZ("<"));
- ib_t tag_text = ib_until(tag_close, SZ("<"));
- last = ib_copy(tag_text);
+ ib_destroy(last);
+ last = ib_copy(tag_tail);
- DA_INIT(res.xml.children, 0, alloc);
+ if (last.status == KIT_OK) {
+ i64 n = res.tags.size;
+ DA_RESIZE(res.tags, n + 1);
- if (last.status == KIT_OK)
- for (;;) {
- // TODO
- // Refactor: make this outer loop.
- //
+ if (res.tags.size != n + 1) {
+ last.status = KIT_ERROR_BAD_ALLOC;
+ xml_destroy(&tag);
+ } else {
+ // move
+ tag.tag = tag_name.data;
+ memset(&tag_name.data, 0, sizeof tag_name.data);
- ib_t next = ib_exact(last, SZ("</"));
+ // move
+ tag.tail = tag_tail.data;
+ memset(&tag_tail.data, 0, sizeof tag_tail.data);
- if (next.status == KIT_OK) {
- ib_destroy(last);
- last = next;
- break;
+ res.tags.values[n] = tag;
}
+ } else
+ xml_destroy(&tag);
+
+ ib_destroy(tag_open);
+ ib_destroy(tag_name);
+ ib_destroy(tag_close);
+ ib_destroy(tag_close_empty);
+ ib_destroy(tag_tail);
+ }
- ib_destroy(next);
-
- kit_xml_intermediate_t im = kit_xml_parse_buf_(last, alloc);
+ if (last.status != KIT_OK) {
+ for (i64 i = 0; i < res.tags.size; i++)
+ xml_destroy(res.tags.values + i);
+ DA_DESTROY(res.text);
+ DA_DESTROY(res.tags);
+ } else {
+ // move
+ res.text = tag_text.data;
+ memset(&tag_text.data, 0, sizeof tag_text.data);
+ }
- last = im.last;
+ ib_destroy(tag_text);
- if (last.status != KIT_OK)
- break;
-
- i64 n = res.xml.children.size;
- DA_RESIZE(res.xml.children, n + 1);
+ res.last = last;
+ return res;
+}
- if (res.xml.children.size != n + 1) {
- res.last = last;
- res.last.status = KIT_ERROR_BAD_ALLOC;
+kit_xml_parse_result_t kit_xml_parse(kit_is_handle_t is,
+ kit_allocator_t *alloc) {
+ ib_t ib = ib_wrap(is, alloc);
+ kit_xml_intermediate_t im = kit_xml_parse_buf_(ib, alloc);
+ ib_destroy(ib);
- ib_destroy(tag_text);
+ kit_xml_parse_result_t res;
+ memset(&res, 0, sizeof res);
- DA_DESTROY(res.xml.properties);
- DA_DESTROY(res.xml.children);
- return_ res;
- }
+ res.status = im.last.status;
+ ib_destroy(im.last);
- res.xml.children.values[n] = im.xml;
- }
+ if (res.status != KIT_OK)
+ return res;
- ib_t tagend_open = last;
- ib_t tagend_name = ib_exact(tagend_open, WRAP_STR(tag_name.data));
- ib_t tagend_close = ib_exact(tagend_name, SZ(">"));
- ib_t tag_tail = ib_until(tagend_close, SZ("<"));
-
-#undef return_
-#define return_ \
- ib_destroy(begin); \
- ib_destroy(tag_open); \
- ib_destroy(tag_name); \
- ib_destroy(tag_close); \
- ib_destroy(tag_close_empty); \
- ib_destroy(tag_text); \
- ib_destroy(tagend_open); \
- ib_destroy(tagend_name); \
- ib_destroy(tagend_close); \
- return
-
- if (tag_tail.status != KIT_OK) {
- res.last = tag_tail;
-
- DA_DESTROY(res.xml.properties);
- DA_DESTROY(res.xml.children);
- return_ res;
+ if (im.text.size == 0 && im.tags.size == 1) {
+ res.xml = im.tags.values[0];
+ DA_DESTROY(im.text);
+ DA_DESTROY(im.tags);
+ return res;
}
- // move
- res.xml.tag = tag_name.data;
- memset(&tag_name.data, 0, sizeof tag_name.data);
-
- // move
- res.xml.text = tag_text.data;
- memset(&tag_text.data, 0, sizeof tag_text.data);
-
- // move
- res.xml.tail = tag_tail.data;
- memset(&tag_tail.data, 0, sizeof tag_tail.data);
+ DA_INIT(res.xml.tag, 0, alloc);
+ DA_INIT(res.xml.tail, 0, alloc);
+ DA_INIT(res.xml.properties, 0, alloc);
- res.last = tag_tail;
- return_ res;
-#undef return_
-}
+ res.xml.text = im.text;
+ res.xml.children = im.tags;
-kit_xml_parse_result_t kit_xml_parse(kit_is_handle_t is,
- kit_allocator_t *alloc) {
- kit_xml_intermediate_t im = kit_xml_parse_buf_(ib_wrap(is, alloc),
- alloc);
- kit_xml_parse_result_t res = { .status = im.last.status,
- .xml = im.xml };
- ib_destroy(im.last);
return res;
}