summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild_and_test.sh8
-rw-r--r--source/kit/file.c29
-rw-r--r--source/kit/file.h25
-rw-r--r--source/kit/input_buffer.c447
-rw-r--r--source/kit/input_buffer.h60
-rw-r--r--source/kit/math.h2
-rw-r--r--source/kit/secure_random.c2
-rw-r--r--source/kit/secure_random.h2
-rw-r--r--source/kit/shared_memory.h10
-rw-r--r--source/kit/shared_memory.posix.c6
-rw-r--r--source/kit/shared_memory.win32.c4
-rw-r--r--source/kit/sockets.h8
-rw-r--r--source/kit/status.h7
-rw-r--r--source/kit/string_builder.h3
-rw-r--r--source/kit/types.h15
-rw-r--r--source/kit/unival.h6
-rw-r--r--source/kit/xml.c335
-rw-r--r--source/kit/xml.h6
-rw-r--r--source/tests/input_buffer.test.c204
-rw-r--r--source/tests/xml.test.c4
20 files changed, 616 insertions, 567 deletions
diff --git a/build_and_test.sh b/build_and_test.sh
index 66ba8d8..46ed36a 100755
--- a/build_and_test.sh
+++ b/build_and_test.sh
@@ -226,10 +226,6 @@ if [ $? -ne 0 ]; then
exit 1
fi
-if [ $SKIP_TESTS -ne 0 ] || [ "$COMPILE" = "emcc" ]; then
- exit 0
-fi
-
echo "Build test suite"
$COMPILE $FLAGS \
$FLAG_EXE"$FOLDER/test_suite$EXE_POSTFIX" \
@@ -285,6 +281,10 @@ if [ $? -ne 0 ]; then
exit 1
fi
+if [ $SKIP_TESTS -ne 0 ] || [ "$COMPILE" = "emcc" ]; then
+ exit 0
+fi
+
echo "Run tests"
echo ""
diff --git a/source/kit/file.c b/source/kit/file.c
index e5b834f..76d3249 100644
--- a/source/kit/file.c
+++ b/source/kit/file.c
@@ -276,7 +276,7 @@ static void kit_prepare_path_(char *buf, kit_str_t path) {
char buf[PATH_BUF_SIZE]; \
kit_prepare_path_(buf, path)
-kit_status_t kit_folder_create(kit_str_t path) {
+s32 kit_folder_create(kit_str_t path) {
PREPARE_PATH_BUF_;
#if defined(_WIN32) && !defined(__CYGWIN__)
return CreateDirectoryA(buf, NULL) ? KIT_OK
@@ -286,14 +286,14 @@ kit_status_t kit_folder_create(kit_str_t path) {
#endif
}
-kit_status_t kit_folder_create_recursive(kit_str_t path) {
+s32 kit_folder_create_recursive(kit_str_t path) {
for (i32 i = 0;; i++) {
str_t part = kit_path_take(path, i);
i32 type = kit_path_type(part);
if (type == KIT_PATH_FILE)
return KIT_ERROR_FILE_ALREADY_EXISTS;
if (type == KIT_PATH_NONE) {
- kit_status_t s = kit_folder_create(part);
+ s32 s = kit_folder_create(part);
if (s != KIT_OK)
return s;
}
@@ -304,7 +304,7 @@ kit_status_t kit_folder_create_recursive(kit_str_t path) {
return KIT_OK;
}
-kit_status_t kit_file_remove(kit_str_t path) {
+s32 kit_file_remove(kit_str_t path) {
PREPARE_PATH_BUF_;
#if defined(_WIN32) && !defined(__CYGWIN__)
return DeleteFileA(buf) ? KIT_OK : KIT_ERROR_UNLINK_FAILED;
@@ -313,7 +313,7 @@ kit_status_t kit_file_remove(kit_str_t path) {
#endif
}
-kit_status_t kit_folder_remove(kit_str_t path) {
+s32 kit_folder_remove(kit_str_t path) {
PREPARE_PATH_BUF_;
#if defined(_WIN32) && !defined(__CYGWIN__)
return RemoveDirectoryA(buf) ? KIT_OK : KIT_ERROR_RMDIR_FAILED;
@@ -322,14 +322,14 @@ kit_status_t kit_folder_remove(kit_str_t path) {
#endif
}
-kit_status_t kit_file_remove_recursive(kit_str_t path,
- kit_allocator_t *alloc) {
+s32 kit_file_remove_recursive(kit_str_t path,
+ kit_allocator_t *alloc) {
i32 type = kit_path_type(path);
i64 i;
switch (type) {
case KIT_PATH_FILE: {
- kit_status_t s = kit_file_remove(path);
+ s32 s = kit_file_remove(path);
assert(s == KIT_OK);
return s;
}
@@ -346,15 +346,14 @@ kit_status_t kit_file_remove_recursive(kit_str_t path,
for (i = 0; i < list.files.size; i++) {
str_builder_t full_path = kit_path_join(
path, WRAP_STR(list.files.values[i]), alloc);
- kit_status_t s = kit_file_remove_recursive(
- WRAP_STR(full_path), alloc);
+ s32 s = kit_file_remove_recursive(WRAP_STR(full_path), alloc);
DA_DESTROY(full_path);
assert(s == KIT_OK);
}
kit_path_list_destroy(list);
- kit_status_t s = kit_folder_remove(path);
+ s32 s = kit_folder_remove(path);
assert(s == KIT_OK);
return s;
}
@@ -652,13 +651,13 @@ kit_mapped_file_t kit_file_map(kit_str_t path, i64 size, i32 mode) {
return mf;
}
-kit_status_t kit_file_sync(kit_mapped_file_t *mf) {
+s32 kit_file_sync(kit_mapped_file_t *mf) {
assert(mf != NULL);
if (mf == NULL)
return KIT_ERROR_INVALID_ARGUMENT;
- kit_status_t status = KIT_OK;
+ s32 status = KIT_OK;
#if !defined(_WIN32) || defined(__CYGWIN__)
if (msync(mf->bytes, mf->size, MS_SYNC) != 0)
@@ -668,13 +667,13 @@ kit_status_t kit_file_sync(kit_mapped_file_t *mf) {
return status;
}
-kit_status_t kit_file_unmap(kit_mapped_file_t *mf) {
+s32 kit_file_unmap(kit_mapped_file_t *mf) {
assert(mf != NULL);
if (mf == NULL)
return KIT_ERROR_INVALID_ARGUMENT;
- kit_status_t status = KIT_OK;
+ s32 status = KIT_OK;
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!UnmapViewOfFile(mf->bytes))
diff --git a/source/kit/file.h b/source/kit/file.h
index b9988f1..79bc574 100644
--- a/source/kit/file.h
+++ b/source/kit/file.h
@@ -28,7 +28,7 @@ typedef enum {
} kit_path_type_t;
typedef struct {
- kit_status_t status;
+ s32 status;
i64 time_modified_sec;
i32 time_modified_nsec;
@@ -36,16 +36,16 @@ typedef struct {
} kit_file_info_t;
typedef struct {
- kit_status_t status;
+ s32 status;
KIT_DA(kit_str_builder_t) files;
} kit_path_list_t;
enum { KIT_FILE_MAP_PRIVATE, KIT_FILE_MAP_SHARED };
typedef struct {
- kit_status_t status;
- i64 size;
- u8 *bytes;
+ s32 status;
+ i64 size;
+ u8 *bytes;
#if defined(_WIN32) && !defined(__CYGWIN__)
void *_file;
void *_map;
@@ -72,16 +72,15 @@ kit_str_t kit_path_index(kit_str_t path, i64 index);
kit_str_t kit_path_take(kit_str_t path, i64 count);
-kit_status_t kit_folder_create(kit_str_t path);
+s32 kit_folder_create(kit_str_t path);
-kit_status_t kit_folder_create_recursive(kit_str_t path);
+s32 kit_folder_create_recursive(kit_str_t path);
-kit_status_t kit_file_remove(kit_str_t path);
+s32 kit_file_remove(kit_str_t path);
-kit_status_t kit_folder_remove(kit_str_t path);
+s32 kit_folder_remove(kit_str_t path);
-kit_status_t kit_file_remove_recursive(kit_str_t path,
- kit_allocator_t *alloc);
+s32 kit_file_remove_recursive(kit_str_t path, kit_allocator_t *alloc);
kit_path_type_t kit_path_type(kit_str_t path);
@@ -93,8 +92,8 @@ kit_path_list_t kit_folder_enum(kit_str_t path,
void kit_path_list_destroy(kit_path_list_t list);
kit_mapped_file_t kit_file_map(kit_str_t path, i64 size, i32 mode);
-kit_status_t kit_file_sync(kit_mapped_file_t *mf);
-kit_status_t kit_file_unmap(kit_mapped_file_t *mf);
+s32 kit_file_sync(kit_mapped_file_t *mf);
+s32 kit_file_unmap(kit_mapped_file_t *mf);
#ifdef __cplusplus
}
diff --git a/source/kit/input_buffer.c b/source/kit/input_buffer.c
index 3ee4959..db7e156 100644
--- a/source/kit/input_buffer.c
+++ b/source/kit/input_buffer.c
@@ -3,174 +3,178 @@
#include <assert.h>
#include <string.h>
-typedef struct {
- i64 ref_count;
- kit_is_handle_t upstream;
- kit_allocator_t *alloc;
- kit_str_builder_t data;
-} internal_buffer_t;
-
-static internal_buffer_t *kit_buf_init_(kit_is_handle_t upstream,
- kit_allocator_t *alloc) {
- internal_buffer_t *buf = kit_alloc_dispatch(alloc, KIT_ALLOCATE,
- sizeof *buf, 0, NULL);
-
- if (buf != NULL) {
- memset(buf, 0, sizeof *buf);
- buf->ref_count = 1;
- buf->upstream = upstream;
- buf->alloc = alloc;
- DA_INIT(buf->data, 0, alloc);
- }
+enum { KIT_IB_CACHE_SIZE = 256 };
- return buf;
-}
+static s32 kit_buf_adjust_(kit_input_buffer_t *buf, i64 size) {
+ assert(buf != NULL);
+ assert(size >= 0);
-static kit_allocator_t *kit_buf_alloc_(void *p) {
- assert(p != NULL);
+ if (buf == NULL)
+ return KIT_ERROR_INTERNAL;
- return ((internal_buffer_t *) p)->alloc;
-}
+ i64 offset = buf->data.size;
-static void kit_buf_acquire_(void *p) {
- assert(p != NULL);
+ if (offset >= size)
+ return KIT_OK;
- ((internal_buffer_t *) p)->ref_count++;
-}
+ DA_RESIZE(buf->data, size);
+ if (buf->data.size != size)
+ return KIT_ERROR_BAD_ALLOC;
-static void kit_buf_release_(void *p) {
- if (p == NULL)
- return;
+ str_t destination = { .size = size - offset,
+ .values = buf->data.values + offset };
+ i64 n = IS_READ(buf->upstream, destination);
- internal_buffer_t *buf = (internal_buffer_t *) p;
+ DA_RESIZE(buf->data, offset + n);
+ if (buf->data.size != offset + n)
+ return KIT_ERROR_BAD_ALLOC;
- if (--buf->ref_count == 0) {
- DA_DESTROY(buf->data);
- kit_alloc_dispatch(buf->alloc, KIT_DEALLOCATE, 0, 0, buf);
- }
+ return KIT_OK;
}
-static void kit_buf_adjust_(void *p, i64 size) {
- assert(p != NULL);
- assert(size >= 0);
+kit_input_buffer_t kit_ib_wrap(is_handle_t upstream,
+ kit_allocator_t *alloc) {
+ kit_input_buffer_t buf;
+ memset(&buf, 0, sizeof buf);
- internal_buffer_t *buf = (internal_buffer_t *) p;
- i64 offset = buf->data.size;
+ buf.upstream = upstream;
+ DA_INIT(buf.data, 0, alloc);
- if (offset < size) {
- DA_RESIZE(buf->data, size);
- kit_str_t destination = { .size = size - offset,
- .values = buf->data.values + offset };
- i64 n = KIT_IS_READ(buf->upstream, destination);
- DA_RESIZE(buf->data, offset + n);
- }
+ return buf;
}
-static i64 kit_buf_read_(void *p, i64 offset, kit_str_t destination) {
- internal_buffer_t *buf = (internal_buffer_t *) p;
- i64 n = destination.size < buf->data.size - offset
- ? destination.size
- : buf->data.size - offset;
- memcpy(destination.values, buf->data.values + offset, n);
- return n;
+void kit_ib_destroy(kit_input_buffer_t *buf) {
+ assert(buf != NULL);
+ if (buf == NULL)
+ return;
+
+ DA_DESTROY(buf->data);
+ memset(buf, 0, sizeof *buf);
}
-kit_ib_t kit_ib_wrap(kit_is_handle_t upstream,
- kit_allocator_t *alloc) {
- kit_ib_t buf;
- memset(&buf, 0, sizeof buf);
- buf.status = KIT_OK;
- DA_INIT(buf.data, 0, alloc);
- buf.internal = kit_buf_init_(upstream, alloc);
- if (buf.internal == NULL)
- buf.status = KIT_ERROR_BAD_ALLOC;
- return buf;
+kit_ib_token_t kit_ib_token(kit_input_buffer_t *buf) {
+ return (kit_ib_token_t) {
+ .status = KIT_OK, .offset = 0, .size = 0, .buffer = buf
+ };
}
-kit_ib_t kit_ib_copy(kit_ib_t buf) {
- kit_ib_t next;
- memset(&next, 0, sizeof next);
+kit_str_t kit_ib_str(kit_ib_token_t tok) {
+ assert(tok.buffer != NULL);
- if (buf.status != KIT_OK) {
- next.status = buf.status;
- return next;
- }
+ if (tok.buffer == NULL || tok.buffer->data.values == NULL)
+ return (str_t) { .size = 0, .values = NULL };
- kit_buf_acquire_(buf.internal);
+ return (str_t) { .size = tok.size,
+ .values = tok.buffer->data.values + tok.offset };
+}
- next.offset = buf.offset;
- next.internal = buf.internal;
+kit_ib_token_t kit_ib_read(kit_ib_token_t tok, i64 size) {
+ assert(tok.buffer != NULL);
- return next;
-}
+ kit_ib_token_t next = tok;
-kit_ib_t kit_ib_read(kit_ib_t buf, i64 size) {
- kit_ib_t next;
- memset(&next, 0, sizeof next);
+ next.offset = tok.offset + tok.size;
+ next.size = 0;
- if (buf.status != KIT_OK) {
- next.status = buf.status;
+ if (tok.status != KIT_OK)
+ return next;
+
+ if (tok.buffer == NULL) {
+ next.status = KIT_ERROR_INVALID_ARGUMENT;
return next;
}
- kit_buf_acquire_(buf.internal);
- kit_buf_adjust_(buf.internal, buf.offset + size);
+ s32 s = kit_buf_adjust_(tok.buffer, tok.offset + tok.size + size);
+
+ if (s != KIT_OK) {
+ next.status = s;
+ return next;
+ }
- DA_INIT(next.data, size, kit_buf_alloc_(buf.internal));
- if (next.data.size != size)
- next.status = KIT_ERROR_BAD_ALLOC;
+ assert(tok.buffer->data.values != NULL);
- kit_str_t destination = { .size = next.data.size,
- .values = next.data.values };
- i64 n = kit_buf_read_(buf.internal, buf.offset, destination);
- next.offset = buf.offset + n;
- next.internal = buf.internal;
+ if (tok.buffer->data.values == NULL) {
+ next.status = KIT_ERROR_INTERNAL;
+ return next;
+ }
- DA_RESIZE(next.data, n);
- if (next.data.size != n)
- next.status = KIT_ERROR_BAD_ALLOC;
+ next.size = size < tok.buffer->data.size - tok.offset - tok.size
+ ? size
+ : tok.buffer->data.size - tok.offset - tok.size;
return next;
}
-kit_ib_t kit_ib_any(kit_ib_t buf, kit_str_t data) {
- kit_ib_t next;
- memset(&next, 0, sizeof next);
+#define IB_CACHE_INIT_(res_) \
+ str_builder_t cache_dynamic; \
+ memset(&cache_dynamic, 0, sizeof cache_dynamic); \
+ char cache_static[KIT_IB_CACHE_SIZE]; \
+ \
+ do { \
+ if (data.size > 0) { \
+ if (data.size < KIT_IB_CACHE_SIZE) { \
+ memcpy(cache_static, data.values, data.size); \
+ data.values = cache_static; \
+ } else { \
+ DA_INIT(cache_dynamic, data.size, tok.buffer->data.alloc); \
+ if (cache_dynamic.size != data.size) { \
+ (res_).status |= KIT_ERROR_BAD_ALLOC; \
+ return (res_); \
+ } \
+ memcpy(cache_dynamic.values, data.values, data.size); \
+ data.values = cache_dynamic.values; \
+ } \
+ } \
+ } while (0)
+
+#define IB_CACHE_CLEANUP_() \
+ do { \
+ if (cache_dynamic.values != NULL) \
+ DA_DESTROY(cache_dynamic); \
+ } while (0)
+
+kit_ib_token_t kit_ib_any(kit_ib_token_t tok, str_t data) {
+ assert(tok.buffer != NULL);
+
+ kit_ib_token_t next = tok;
+
+ next.offset = tok.offset + tok.size;
+ next.size = 0;
+
+ if (tok.status != KIT_OK)
+ return next;
- if (buf.status != KIT_OK) {
- next.status = buf.status;
+ if (tok.buffer == NULL) {
+ next.status = KIT_ERROR_INVALID_ARGUMENT;
return next;
}
- kit_buf_acquire_(buf.internal);
-
- DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal));
+ IB_CACHE_INIT_(next);
- i64 size = 0;
+ for (;; ++next.size) {
+ s32 s = kit_buf_adjust_(tok.buffer,
+ tok.offset + tok.size + next.size + 1);
- for (;; ++size) {
- kit_buf_adjust_(buf.internal, buf.offset + size + 1);
+ if (s != KIT_OK) {
+ next.status = s;
+ return next;
+ }
- DA_RESIZE(next.data, size + 1);
+ assert(tok.buffer->data.values != NULL);
- assert(next.data.size == size + 1);
- if (next.data.size != size + 1) {
- next.status = KIT_ERROR_BAD_ALLOC;
+ if (tok.buffer->data.values == NULL) {
+ next.status = KIT_ERROR_INTERNAL;
return next;
}
- kit_str_t destination = { .size = 1,
- .values = next.data.values + size };
- i64 n = kit_buf_read_(buf.internal, buf.offset + size,
- destination);
-
- if (n != 1)
+ if (tok.offset + tok.size + next.size >= tok.buffer->data.size)
break;
i8 found = 0;
for (i64 i = 0; i < data.size; i++)
- if (data.values[i] == destination.values[0]) {
+ if (data.values[i] ==
+ tok.buffer->data.values[next.offset + next.size]) {
found = 1;
break;
}
@@ -179,54 +183,53 @@ kit_ib_t kit_ib_any(kit_ib_t buf, kit_str_t data) {
break;
}
- next.offset = buf.offset + size;
- next.internal = buf.internal;
-
- DA_RESIZE(next.data, size);
- if (next.data.size != size)
- next.status = KIT_ERROR_BAD_ALLOC;
+ IB_CACHE_CLEANUP_();
return next;
}
-kit_ib_t kit_ib_none(kit_ib_t buf, kit_str_t data) {
- kit_ib_t next;
- memset(&next, 0, sizeof next);
+kit_ib_token_t kit_ib_none(kit_ib_token_t tok, str_t data) {
+ assert(tok.buffer != NULL);
- if (buf.status != KIT_OK) {
- next.status = buf.status;
- return next;
- }
+ kit_ib_token_t next = tok;
- kit_buf_acquire_(buf.internal);
+ next.offset = tok.offset + tok.size;
+ next.size = 0;
- DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal));
+ if (tok.status != KIT_OK)
+ return next;
- i64 size = 0;
+ if (tok.buffer == NULL) {
+ next.status = KIT_ERROR_INVALID_ARGUMENT;
+ return next;
+ }
- for (;; ++size) {
- kit_buf_adjust_(buf.internal, buf.offset + size + 1);
+ IB_CACHE_INIT_(next);
- DA_RESIZE(next.data, size + 1);
+ for (;; ++next.size) {
+ s32 s = kit_buf_adjust_(tok.buffer,
+ tok.offset + tok.size + next.size + 1);
- assert(next.data.size == size + 1);
- if (next.data.size != size + 1) {
- next.status = KIT_ERROR_BAD_ALLOC;
+ if (s != KIT_OK) {
+ next.status = s;
return next;
}
- kit_str_t destination = { .size = 1,
- .values = next.data.values + size };
- i64 n = kit_buf_read_(buf.internal, buf.offset + size,
- destination);
+ assert(tok.buffer->data.values != NULL);
- if (n != 1)
+ if (tok.buffer->data.values == NULL) {
+ next.status = KIT_ERROR_INTERNAL;
+ return next;
+ }
+
+ if (tok.offset + tok.size + next.size >= tok.buffer->data.size)
break;
i8 found = 0;
for (i64 i = 0; i < data.size; i++)
- if (data.values[i] == destination.values[0]) {
+ if (data.values[i] ==
+ tok.buffer->data.values[next.offset + next.size]) {
found = 1;
break;
}
@@ -235,125 +238,123 @@ kit_ib_t kit_ib_none(kit_ib_t buf, kit_str_t data) {
break;
}
- next.offset = buf.offset + size;
- next.internal = buf.internal;
-
- DA_RESIZE(next.data, size);
- if (next.data.size != size)
- next.status = KIT_ERROR_BAD_ALLOC;
+ IB_CACHE_CLEANUP_();
return next;
}
-kit_ib_t kit_ib_exact(kit_ib_t buf, kit_str_t data) {
- kit_ib_t res = kit_ib_read(buf, data.size);
- if (!AR_EQUAL(res.data, data))
- res.status = KIT_ERROR_INTERNAL;
+kit_ib_token_t kit_ib_exact(kit_ib_token_t tok, str_t data) {
+ kit_ib_token_t res = tok;
+
+ res.offset = tok.offset + tok.size;
+ res.size = 0;
+
+ IB_CACHE_INIT_(res);
+
+ res = kit_ib_read(tok, data.size);
+ if (!AR_EQUAL(kit_ib_str(res), data))
+ res.status = KIT_PARSING_FAILED;
+
+ IB_CACHE_CLEANUP_();
+
return res;
}
-kit_ib_t kit_ib_until(kit_ib_t buf, kit_str_t data) {
- kit_ib_t next;
- memset(&next, 0, sizeof next);
+kit_ib_token_t kit_ib_until(kit_ib_token_t tok, str_t data) {
+ assert(tok.buffer != NULL);
- if (buf.status != KIT_OK) {
- next.status = buf.status;
- return next;
- }
+ kit_ib_token_t next = tok;
- kit_buf_acquire_(buf.internal);
+ next.offset = tok.offset + tok.size;
+ next.size = 0;
- DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal));
+ if (tok.status != KIT_OK)
+ return next;
- i64 size = 0;
+ if (tok.buffer == NULL) {
+ next.status = KIT_ERROR_INVALID_ARGUMENT;
+ return next;
+ }
- for (;; ++size) {
- kit_buf_adjust_(buf.internal, buf.offset + size + 1);
+ IB_CACHE_INIT_(next);
- DA_RESIZE(next.data, size + 1);
+ for (;; ++next.size) {
+ s32 s = kit_buf_adjust_(tok.buffer,
+ tok.offset + tok.size + next.size + 1);
- assert(next.data.size == size + 1);
- if (next.data.size != size + 1) {
- next.status = KIT_ERROR_BAD_ALLOC;
+ if (s != KIT_OK) {
+ next.status = s;
return next;
}
- kit_str_t destination = { .size = 1,
- .values = next.data.values + size };
- i64 n = kit_buf_read_(buf.internal, buf.offset + size,
- destination);
+ assert(tok.buffer->data.values != NULL);
- if (n != 1)
+ if (tok.buffer->data.values == NULL) {
+ next.status = KIT_ERROR_INTERNAL;
+ return next;
+ }
+
+ if (tok.offset + tok.size + next.size >= tok.buffer->data.size)
break;
- if (size + 1 >= data.size &&
- AR_EQUAL(kit_str(data.size,
- next.data.values + (size + 1 - data.size)),
+ if (next.size + 1 >= data.size &&
+ AR_EQUAL(kit_str(data.size, tok.buffer->data.values +
+ (next.offset + next.size + 1 -
+ data.size)),
data)) {
- size -= data.size - 1;
+ next.size -= data.size - 1;
break;
}
}
- next.offset = buf.offset + size;
- next.internal = buf.internal;
-
- DA_RESIZE(next.data, size);
- if (next.data.size != size)
- next.status = KIT_ERROR_BAD_ALLOC;
+ IB_CACHE_CLEANUP_();
return next;
}
-kit_ib_t kit_ib_while(kit_ib_t buf,
- kit_ib_read_condition_fn condition,
- void *context) {
- kit_ib_t next;
- memset(&next, 0, sizeof next);
+kit_ib_token_t kit_ib_while(kit_ib_token_t tok,
+ kit_ib_read_condition_fn condition,
+ void *context) {
+ assert(tok.buffer != NULL);
- if (buf.status != KIT_OK) {
- next.status = buf.status;
- return next;
- }
+ kit_ib_token_t next = tok;
- kit_buf_acquire_(buf.internal);
+ next.offset = tok.offset + tok.size;
+ next.size = 0;
+
+ if (tok.status != KIT_OK)
+ return next;
- DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal));
+ if (tok.buffer == NULL) {
+ next.status = KIT_ERROR_INVALID_ARGUMENT;
+ return next;
+ }
- i64 size = 0;
+ for (;; ++next.size) {
+ s32 s = kit_buf_adjust_(tok.buffer,
+ tok.offset + tok.size + next.size + 1);
- for (;; ++size) {
- kit_buf_adjust_(buf.internal, buf.offset + size + 1);
+ if (s != KIT_OK) {
+ next.status = s;
+ return next;
+ }
- DA_RESIZE(next.data, size + 1);
+ assert(tok.buffer->data.values != NULL);
- assert(next.data.size == size + 1);
- if (next.data.size != size + 1) {
- next.status = KIT_ERROR_BAD_ALLOC;
+ if (tok.buffer->data.values == NULL) {
+ next.status = KIT_ERROR_INTERNAL;
return next;
}
- kit_str_t destination = { .size = 1,
- .values = next.data.values + size };
- i64 n = kit_buf_read_(buf.internal, buf.offset + size,
- destination);
+ if (tok.offset + tok.size + next.size >= tok.buffer->data.size)
+ break;
- kit_str_t data = { .size = size + 1, .values = next.data.values };
- if (n != 1 || condition == NULL || condition(data, context) == 0)
+ if (condition == NULL ||
+ !condition(kit_str(next.size + 1,
+ tok.buffer->data.values + next.offset),
+ context))
break;
}
- next.offset = buf.offset + size;
- next.internal = buf.internal;
-
- DA_RESIZE(next.data, size);
- if (next.data.size != size)
- next.status = KIT_ERROR_BAD_ALLOC;
-
return next;
}
-
-void kit_ib_destroy(kit_ib_t buf) {
- kit_buf_release_(buf.internal);
- DA_DESTROY(buf.data);
-}
diff --git a/source/kit/input_buffer.h b/source/kit/input_buffer.h
index a40ec99..2a7c8a7 100644
--- a/source/kit/input_buffer.h
+++ b/source/kit/input_buffer.h
@@ -10,42 +10,46 @@ extern "C" {
#endif
typedef struct {
- kit_status_t status;
- i64 offset;
- void *internal;
+ kit_is_handle_t upstream;
kit_str_builder_t data;
-} kit_ib_t;
+} kit_input_buffer_t;
-typedef i8 (*kit_ib_read_condition_fn)(kit_str_t data, void *context);
+typedef struct {
+ s32 status;
+ i64 offset;
+ i64 size;
+ kit_input_buffer_t *buffer;
+} kit_ib_token_t;
+
+typedef b8 (*kit_ib_read_condition_fn)(kit_str_t data, void *context);
-kit_ib_t kit_ib_wrap(kit_is_handle_t upstream,
- kit_allocator_t *alloc);
+kit_input_buffer_t kit_ib_wrap(kit_is_handle_t upstream,
+ kit_allocator_t *alloc);
-kit_ib_t kit_ib_copy(kit_ib_t buf);
+void kit_ib_destroy(kit_input_buffer_t *buf);
-kit_ib_t kit_ib_read(kit_ib_t buf, i64 size);
+kit_ib_token_t kit_ib_token(kit_input_buffer_t *buf);
-kit_ib_t kit_ib_any(kit_ib_t buf, kit_str_t data);
+kit_str_t kit_ib_str(kit_ib_token_t tok);
-kit_ib_t kit_ib_none(kit_ib_t buf, kit_str_t data);
+kit_ib_token_t kit_ib_read(kit_ib_token_t tok, i64 size);
-kit_ib_t kit_ib_exact(kit_ib_t buf, kit_str_t data);
+kit_ib_token_t kit_ib_any(kit_ib_token_t tok, kit_str_t data);
-kit_ib_t kit_ib_until(kit_ib_t buf, kit_str_t data);
+kit_ib_token_t kit_ib_none(kit_ib_token_t tok, kit_str_t data);
-kit_ib_t kit_ib_while(kit_ib_t buf,
- kit_ib_read_condition_fn condition,
- void *context);
+kit_ib_token_t kit_ib_exact(kit_ib_token_t tok, kit_str_t data);
-void kit_ib_destroy(kit_ib_t buf);
+kit_ib_token_t kit_ib_until(kit_ib_token_t tok, kit_str_t data);
-#define KIT_IB_WRAP(upstream) kit_ib_wrap(upstream, NULL)
+kit_ib_token_t kit_ib_while(kit_ib_token_t buf,
+ kit_ib_read_condition_fn condition,
+ void *context);
-#define KIT_IB_SKIP(buf_, proc_, ...) \
- do { \
- kit_ib_t temp_buf_ = (buf_); \
- (buf_) = proc_((buf_), __VA_ARGS__); \
- kit_ib_destroy((temp_buf_)); \
+#define KIT_IB_SKIP(buf_, proc_, ...) \
+ do { \
+ kit_ib_token_t temp_buf_ = (buf_); \
+ (buf_) = proc_((buf_), __VA_ARGS__); \
} while (0)
#ifdef __cplusplus
@@ -53,19 +57,19 @@ void kit_ib_destroy(kit_ib_t buf);
#endif
#ifndef KIT_DISABLE_SHORT_NAMES
-# define ib_t kit_ib_t
+# define input_buffer_t kit_input_buffer_t
+# define ib_token_t kit_ib_token_t
# define ib_read_condition_fn kit_ib_read_condition_fn
# define ib_wrap kit_ib_wrap
-# define ib_copy kit_ib_copy
+# define ib_destroy kit_ib_destroy
+# define ib_token kit_ib_token
+# define ib_str kit_ib_str
# define ib_read kit_ib_read
# define ib_any kit_ib_any
# define ib_none kit_ib_none
# define ib_exact kit_ib_exact
# define ib_until kit_ib_until
# define ib_while kit_ib_while
-# define ib_destroy kit_ib_destroy
-
-# define IB_WRAP KIT_IB_WRAP
# define IB_SKIP KIT_IB_SKIP
#endif
diff --git a/source/kit/math.h b/source/kit/math.h
index f4ab33a..3a55276 100644
--- a/source/kit/math.h
+++ b/source/kit/math.h
@@ -13,7 +13,7 @@
// TODO
// - Gamma correction.
-//
+// - Custom prefixes
#ifdef __cplusplus
extern "C" {
diff --git a/source/kit/secure_random.c b/source/kit/secure_random.c
index 02b168b..2565f6f 100644
--- a/source/kit/secure_random.c
+++ b/source/kit/secure_random.c
@@ -14,7 +14,7 @@
# include <unistd.h>
#endif
-kit_status_t kit_secure_random(i64 size, void *data) {
+s32 kit_secure_random(i64 size, void *data) {
assert(size >= 0);
assert(data != NULL);
diff --git a/source/kit/secure_random.h b/source/kit/secure_random.h
index 54a40e0..fbee23d 100644
--- a/source/kit/secure_random.h
+++ b/source/kit/secure_random.h
@@ -7,7 +7,7 @@
extern "C" {
#endif
-kit_status_t kit_secure_random(i64 size, void *data);
+s32 kit_secure_random(i64 size, void *data);
#ifdef __cplusplus
}
diff --git a/source/kit/shared_memory.h b/source/kit/shared_memory.h
index bd910cb..0c0c1ce 100644
--- a/source/kit/shared_memory.h
+++ b/source/kit/shared_memory.h
@@ -13,9 +13,9 @@ extern "C" {
#endif
typedef struct {
- kit_status_t status;
- i64 size;
- u8 *bytes;
+ s32 status;
+ i64 size;
+ u8 *bytes;
#if defined(_WIN32) && !defined(__CYGWIN__)
void *_handle;
#else
@@ -31,8 +31,8 @@ enum {
kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
i32 mode);
-kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem);
-kit_status_t kit_shared_memory_clean(kit_str_t name);
+s32 kit_shared_memory_close(kit_shared_memory_t *mem);
+s32 kit_shared_memory_clean(kit_str_t name);
#ifdef __cplusplus
}
diff --git a/source/kit/shared_memory.posix.c b/source/kit/shared_memory.posix.c
index e109e2a..fa0db98 100644
--- a/source/kit/shared_memory.posix.c
+++ b/source/kit/shared_memory.posix.c
@@ -81,13 +81,13 @@ kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
return mem;
}
-kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) {
+s32 kit_shared_memory_close(kit_shared_memory_t *mem) {
assert(mem != NULL);
if (mem == NULL)
return KIT_ERROR_INVALID_ARGUMENT;
- kit_status_t status = KIT_OK;
+ s32 status = KIT_OK;
if (munmap(mem->bytes, mem->size) != 0)
status |= KIT_ERROR_UNMAP_FAILED;
@@ -97,7 +97,7 @@ kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) {
return status;
}
-kit_status_t kit_shared_memory_clean(kit_str_t name) {
+s32 kit_shared_memory_clean(kit_str_t name) {
assert(name.size > 0);
assert(name.size + 1 <= NAME_MAX);
assert(name.values != NULL);
diff --git a/source/kit/shared_memory.win32.c b/source/kit/shared_memory.win32.c
index 34bb276..61b7317 100644
--- a/source/kit/shared_memory.win32.c
+++ b/source/kit/shared_memory.win32.c
@@ -67,7 +67,7 @@ kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size,
return mem;
}
-kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) {
+s32 kit_shared_memory_close(kit_shared_memory_t *mem) {
assert(mem != NULL);
i32 status = KIT_OK;
@@ -80,7 +80,7 @@ kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) {
return status;
}
-kit_status_t kit_shared_memory_clean(kit_str_t name) {
+s32 kit_shared_memory_clean(kit_str_t name) {
// Do nothing.
//
diff --git a/source/kit/sockets.h b/source/kit/sockets.h
index a9e2754..1fe2a3d 100644
--- a/source/kit/sockets.h
+++ b/source/kit/sockets.h
@@ -23,7 +23,7 @@ extern "C" {
# define socket_t SOCKET
# define socklen_t i32
-static kit_status_t kit_sockets_init(void) {
+static s32 kit_sockets_init(void) {
WSADATA data;
memset(&data, 0, sizeof data);
WORD version = MAKEWORD(2, 2);
@@ -32,7 +32,7 @@ static kit_status_t kit_sockets_init(void) {
: KIT_ERROR_SOCKETS_STARTUP_FAILED;
}
-static kit_status_t kit_sockets_cleanup(void) {
+static s32 kit_sockets_cleanup(void) {
WSACleanup();
return KIT_OK;
}
@@ -69,12 +69,12 @@ static i32 kit_socket_set_nonblocking(socket_t s) {
# define closesocket close
# define INVALID_SOCKET -1
-static kit_status_t kit_sockets_init(void) {
+static s32 kit_sockets_init(void) {
signal(SIGPIPE, SIG_IGN);
return KIT_OK;
}
-static kit_status_t kit_sockets_cleanup(void) {
+static s32 kit_sockets_cleanup(void) {
return KIT_OK;
}
diff --git a/source/kit/status.h b/source/kit/status.h
index be54aad..6316704 100644
--- a/source/kit/status.h
+++ b/source/kit/status.h
@@ -5,7 +5,7 @@
enum {
KIT_OK = 0,
- KIT_ERROR_INTERNAL = 1,
+ KIT_PARSING_FAILED = 1,
KIT_ERROR_BAD_ALLOC = (1 << 1),
KIT_ERROR_INVALID_ARGUMENT = (1 << 2),
KIT_ERROR_MKDIR_FAILED = (1 << 3),
@@ -27,9 +27,8 @@ enum {
KIT_ERROR_SYNC_FAILED = (1 << 19),
KIT_ERROR_CLOSE_FAILED = (1 << 20),
KIT_ERROR_RESOURCE_UNAVAILABLE = (1 << 21),
- KIT_ERROR_NOT_IMPLEMENTED = (1 << 30),
+ KIT_ERROR_INTERNAL = (1 << 30),
+ KIT_ERROR_NOT_IMPLEMENTED = -1,
};
-typedef i32 kit_status_t;
-
#endif
diff --git a/source/kit/string_builder.h b/source/kit/string_builder.h
index 322f6e2..3f244e8 100644
--- a/source/kit/string_builder.h
+++ b/source/kit/string_builder.h
@@ -31,8 +31,7 @@ static kit_str_builder_t kit_str_build(kit_str_t s,
return builder;
}
-static kit_status_t kit_str_append(kit_str_builder_t *a,
- kit_str_t b) {
+static s32 kit_str_append(kit_str_builder_t *a, kit_str_t b) {
assert(a != NULL);
if (a == NULL)
return KIT_ERROR_INVALID_ARGUMENT;
diff --git a/source/kit/types.h b/source/kit/types.h
index b83ba39..cbb9a71 100644
--- a/source/kit/types.h
+++ b/source/kit/types.h
@@ -5,17 +5,32 @@
# define _GNU_SOURCE
#endif
+// signed integers
+//
typedef signed char i8;
typedef signed short i16;
typedef signed int i32;
typedef signed long long i64;
+// unsigned integers
+//
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
+// floats
+//
typedef float f32;
typedef double f64;
+// chars
+//
+typedef signed char c8;
+typedef signed int c32;
+
+typedef signed char b8; // 8-bit boolean
+typedef signed int b32; // 32-bit boolean
+typedef signed int s32; // 32-bit status
+
#endif
diff --git a/source/kit/unival.h b/source/kit/unival.h
index a87a763..905430b 100644
--- a/source/kit/unival.h
+++ b/source/kit/unival.h
@@ -45,17 +45,17 @@ struct kit_uv_data {
};
typedef struct {
- kit_status_t status;
+ s32 status;
kit_unival_t *value;
} kit_uv_decode_result_t;
typedef struct {
- kit_status_t status;
+ s32 status;
kit_uv_bytes_t value;
} kit_uv_encode_result_t;
typedef struct {
- kit_status_t status;
+ s32 status;
kit_str_builder_t value;
} kit_uv_print_result_t;
diff --git a/source/kit/xml.c b/source/kit/xml.c
index c62ee82..399cc5f 100644
--- a/source/kit/xml.c
+++ b/source/kit/xml.c
@@ -4,198 +4,178 @@
#include <assert.h>
typedef struct {
- ib_t last;
+ ib_token_t last;
kit_str_builder_t text;
kit_da_xml_t tags;
} kit_xml_intermediate_t;
-static kit_status_t kit_xml_unescape_(str_builder_t *str) {
- assert(str != NULL);
+static s32 kit_xml_alloc_and_unescape_(str_builder_t *dst, str_t str,
+ kit_allocator_t *alloc) {
+ assert(dst != NULL);
+ assert(str.size == 0 || str.values != NULL);
- str_builder_t buf;
- DA_INIT(buf, str->size, str->alloc);
- buf.size = 0;
+ if (dst == NULL)
+ return KIT_ERROR_INTERNAL;
+ if (str.size != 0 && str.values == NULL)
+ return KIT_ERROR_INTERNAL;
- for (i64 i = 0; i < str->size; i++)
- if (str->values[i] != '&')
- buf.values[buf.size++] = str->values[i];
+ DA_INIT(*dst, str.size, alloc);
+
+ if (dst->size != str.size)
+ return KIT_ERROR_BAD_ALLOC;
+
+ dst->size = 0;
+
+ for (i64 i = 0; i < str.size; i++)
+ if (str.values[i] != '&')
+ dst->values[dst->size++] = str.values[i];
else {
i64 n = 1;
- while (i + n < str->size && str->values[i + n] != ';') n++;
- if (i + n >= str->size) {
- DA_DESTROY(buf);
- return KIT_ERROR_INTERNAL;
+ while (i + n < str.size && str.values[i + n] != ';') n++;
+ if (i + n >= str.size) {
+ DA_DESTROY(*dst);
+ return KIT_PARSING_FAILED;
}
- if (n == 3 && memcmp(str->values + i, "&lt;", 4) == 0)
- buf.values[buf.size++] = '<';
- else if (n == 3 && memcmp(str->values + i, "&gt;", 4) == 0)
- buf.values[buf.size++] = '>';
- else if (n == 4 && memcmp(str->values + i, "&amp;", 5) == 0)
- buf.values[buf.size++] = '&';
- else if (n == 5 && memcmp(str->values + i, "&quot;", 6) == 0)
- buf.values[buf.size++] = '"';
- else if (n == 5 && memcmp(str->values + i, "&apos;", 6) == 0)
- buf.values[buf.size++] = '\'';
+ if (n == 3 && memcmp(str.values + i, "&lt;", 4) == 0)
+ dst->values[dst->size++] = '<';
+ else if (n == 3 && memcmp(str.values + i, "&gt;", 4) == 0)
+ dst->values[dst->size++] = '>';
+ else if (n == 4 && memcmp(str.values + i, "&amp;", 5) == 0)
+ dst->values[dst->size++] = '&';
+ else if (n == 5 && memcmp(str.values + i, "&quot;", 6) == 0)
+ dst->values[dst->size++] = '"';
+ else if (n == 5 && memcmp(str.values + i, "&apos;", 6) == 0)
+ dst->values[dst->size++] = '\'';
else {
- DA_DESTROY(buf);
- return KIT_ERROR_INTERNAL;
+ DA_DESTROY(*dst);
+ return KIT_PARSING_FAILED;
}
i += n;
}
- DA_DESTROY(*str);
- *str = buf;
-
return KIT_OK;
}
-static ib_t kit_xml_parse_text_(ib_t begin) {
- ib_t text = ib_until(begin, SZ("<"));
- ib_t last = ib_copy(text);
+static ib_token_t kit_xml_parse_text_(ib_token_t begin,
+ str_builder_t *dst) {
+ ib_token_t last = ib_until(begin, SZ("<"));
+
+ DA_RESIZE(*dst, last.size);
+
+ assert(dst->size == last.size);
+ if (dst->size != last.size)
+ last.status |= KIT_ERROR_BAD_ALLOC;
+ else if (last.size > 0)
+ memcpy(dst->values, ib_str(last).values, last.size);
for (;;) {
- ib_t comment_open = ib_exact(last, SZ("<!--"));
+ ib_token_t comment_open = ib_exact(last, SZ("<!--"));
- if (comment_open.status != KIT_OK) {
- ib_destroy(comment_open);
+ if (comment_open.status != KIT_OK)
break;
- }
- ib_t comment_text = ib_until(comment_open, SZ("-->"));
- ib_t comment_close = ib_exact(comment_text, SZ("-->"));
- ib_t next_text = ib_until(comment_close, SZ("<"));
+ ib_token_t comment_text = ib_until(comment_open, SZ("-->"));
+ ib_token_t comment_close = ib_exact(comment_text, SZ("-->"));
+ ib_token_t next_text = ib_until(comment_close, SZ("<"));
- if (next_text.status == KIT_OK && next_text.data.size > 0) {
- i64 n = text.data.size;
- DA_RESIZE(text.data, n + next_text.data.size);
+ if (next_text.status == KIT_OK && next_text.size > 0) {
+ i64 n = dst->size;
+ DA_RESIZE(*dst, n + next_text.size);
- assert(text.data.size == n + next_text.data.size);
- if (text.data.size != n + next_text.data.size)
- next_text.status = KIT_ERROR_BAD_ALLOC;
+ assert(dst->size == n + next_text.size);
+ if (dst->size != n + next_text.size)
+ next_text.status |= KIT_ERROR_BAD_ALLOC;
else
- memcpy(text.data.values + n, next_text.data.values,
- next_text.data.size);
+ memcpy(dst->values + n, ib_str(next_text).values,
+ ib_str(next_text).size);
}
- ib_destroy(last);
- last = ib_copy(next_text);
-
- ib_destroy(comment_open);
- ib_destroy(comment_text);
- ib_destroy(comment_close);
- ib_destroy(next_text);
+ last = next_text;
}
- // move
- DA_DESTROY(last.data);
- last.data = text.data;
- memset(&text.data, 0, sizeof text.data);
-
- kit_status_t s = kit_xml_unescape_(&last.data);
- if (s != KIT_OK)
- last.status = s;
-
- ib_destroy(text);
-
return last;
}
-static ib_t kit_xml_parse_string_(ib_t begin) {
- ib_t quotes_open = ib_exact(begin, SZ("\""));
- ib_t apostr_open = ib_exact(begin, SZ("'"));
-
- ib_t open = quotes_open.status == KIT_OK ? quotes_open
- : apostr_open;
-
- ib_t text = ib_until(open, WRAP_STR(open.data));
- ib_t close = ib_exact(text, WRAP_STR(open.data));
+static ib_token_t kit_xml_parse_string_(ib_token_t begin,
+ ib_token_t *value) {
+ assert(value != NULL);
+ if (value == NULL) {
+ begin.status |= KIT_ERROR_INTERNAL;
+ return begin;
+ }
- // move
- DA_DESTROY(close.data);
- close.data = text.data;
- memset(&text.data, 0, sizeof text.data);
+ ib_token_t quotes_open = ib_exact(begin, SZ("\""));
+ ib_token_t apostr_open = ib_exact(begin, SZ("'"));
- kit_status_t s = kit_xml_unescape_(&close.data);
- if (s == KIT_OK)
- close.status = s;
+ ib_token_t open = quotes_open.status == KIT_OK ? quotes_open
+ : apostr_open;
- ib_destroy(quotes_open);
- ib_destroy(apostr_open);
- ib_destroy(text);
+ *value = ib_until(open, ib_str(open));
+ ib_token_t close = ib_exact(*value, ib_str(open));
return close;
}
static kit_xml_intermediate_t kit_xml_parse_buf_(
- ib_t begin, kit_allocator_t *alloc) {
+ ib_token_t begin, kit_allocator_t *alloc) {
kit_xml_intermediate_t res;
memset(&res, 0, sizeof res);
- ib_t last, spaces;
+ ib_token_t last, spaces;
memset(&last, 0, sizeof last);
memset(&spaces, 0, sizeof spaces);
- ib_t tag_text = kit_xml_parse_text_(begin);
- last = ib_copy(tag_text);
+ str_builder_t tag_text_string;
+ str_builder_t tag_tail_string;
+ DA_INIT(tag_text_string, 0, alloc);
+ DA_INIT(tag_tail_string, 0, alloc);
+
+ ib_token_t tag_text = kit_xml_parse_text_(begin, &tag_text_string);
+ last = tag_text;
DA_INIT(res.tags, 0, alloc);
for (;;) {
- ib_t tagend_open = ib_exact(last, SZ("</"));
- ib_destroy(tagend_open);
+ ib_token_t tagend_open = ib_exact(last, SZ("</"));
if (tagend_open.status == KIT_OK)
break;
- ib_t tag_open = ib_exact(last, SZ("<"));
+ ib_token_t tag_open = ib_exact(last, SZ("<"));
- if (tag_open.status != KIT_OK) {
- ib_destroy(tag_open);
+ if (tag_open.status != KIT_OK)
break;
- }
xml_t tag;
memset(&tag, 0, sizeof tag);
- ib_t decl_open = ib_exact(tag_open, SZ("?"));
-
- ib_destroy(last);
+ ib_token_t decl_open = ib_exact(tag_open, SZ("?"));
if (decl_open.status == KIT_OK) {
tag.is_declaration = 1;
- last = ib_copy(decl_open);
+ last = decl_open;
} else
- last = ib_copy(tag_open);
+ last = tag_open;
- ib_destroy(decl_open);
-
- spaces = ib_any(last, SZ(" \t\r\n"));
- ib_t tag_name = ib_none(spaces, SZ(" \t\r\n/>"));
- ib_destroy(spaces);
+ spaces = ib_any(last, SZ(" \t\r\n"));
+ ib_token_t tag_name = ib_none(spaces, SZ(" \t\r\n/>"));
DA_INIT(tag.properties, 0, alloc);
- ib_destroy(last);
- last = ib_copy(tag_name);
+ last = tag_name;
for (;;) {
- spaces = ib_any(last, SZ(" \t\r\n"));
- ib_t property = ib_none(spaces, SZ(" \t\r\n=?/>"));
- ib_destroy(spaces);
+ spaces = ib_any(last, SZ(" \t\r\n"));
+ ib_token_t property = ib_none(spaces, SZ(" \t\r\n=?/>"));
- if (property.status != KIT_OK || property.data.size == 0) {
- ib_destroy(property);
+ if (property.status != KIT_OK || property.size == 0)
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 = kit_xml_parse_string_(spaces);
- ib_destroy(spaces);
+ spaces = ib_any(property, SZ(" \t\r\n"));
+ ib_token_t equals = ib_exact(spaces, SZ("="));
+ spaces = ib_any(equals, SZ(" \t\r\n"));
- ib_destroy(last);
- last = ib_copy(value);
+ ib_token_t value;
+ last = kit_xml_parse_string_(spaces, &value);
if (last.status == KIT_OK) {
i64 n = tag.properties.size;
@@ -203,77 +183,56 @@ static kit_xml_intermediate_t kit_xml_parse_buf_(
assert(tag.properties.size == n + 1);
if (tag.properties.size != n + 1) {
- last.status = KIT_ERROR_BAD_ALLOC;
+ 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.data;
- memset(&value.data, 0, sizeof value.data);
+ last.status |= kit_xml_alloc_and_unescape_(
+ &tag.properties.values[n].name, ib_str(property),
+ alloc);
+ last.status |= kit_xml_alloc_and_unescape_(
+ &tag.properties.values[n].value, ib_str(value), alloc);
}
}
-
- ib_destroy(property);
- ib_destroy(equals);
- ib_destroy(value);
}
- spaces = ib_any(last, SZ(" \t\r\n"));
-
if (tag.is_declaration) {
- ib_t tag_decl_close = ib_exact(spaces, SZ("?>"));
- ib_destroy(spaces);
+ ib_token_t tag_decl_close = ib_exact(spaces, SZ("?>"));
- ib_destroy(last);
last = tag_decl_close;
DA_INIT(tag.text, 0, alloc);
DA_INIT(tag.children, 0, alloc);
} else {
- ib_t tag_close = ib_exact(spaces, SZ(">"));
- ib_t tag_close_empty = ib_exact(spaces, SZ("/>"));
- ib_destroy(spaces);
+ ib_token_t tag_close = ib_exact(spaces, SZ(">"));
+ ib_token_t tag_close_empty = ib_exact(spaces, SZ("/>"));
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);
+
+ tag.text = im.text;
+ tag.children = im.tags;
+
+ tagend_open = ib_exact(im.last, SZ("</"));
+ spaces = ib_any(tagend_open, SZ(" \t\r\n"));
+ ib_token_t tagend_name = ib_exact(spaces, ib_str(tag_name));
+ spaces = ib_any(tagend_name, SZ(" \t\r\n"));
+ ib_token_t tagend_close = ib_exact(spaces, SZ(">"));
+
last = tagend_close;
} else if (tag_close_empty.status == KIT_OK) {
- ib_destroy(last);
- last = ib_copy(tag_close_empty);
+ last = tag_close_empty;
DA_INIT(tag.text, 0, alloc);
DA_INIT(tag.children, 0, alloc);
} else
- last.status = KIT_ERROR_INTERNAL;
-
- ib_destroy(tag_close);
- ib_destroy(tag_close_empty);
+ last.status |= KIT_PARSING_FAILED;
}
- ib_t tag_tail = kit_xml_parse_text_(last);
+ ib_token_t tag_tail = kit_xml_parse_text_(last, &tag_tail_string);
- ib_destroy(last);
- last = ib_copy(tag_tail);
+ last = tag_tail;
if (last.status == KIT_OK) {
i64 n = res.tags.size;
@@ -281,25 +240,18 @@ static kit_xml_intermediate_t kit_xml_parse_buf_(
assert(res.tags.size == n + 1);
if (res.tags.size != n + 1) {
- last.status = KIT_ERROR_BAD_ALLOC;
+ 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);
-
- // move
- tag.tail = tag_tail.data;
- memset(&tag_tail.data, 0, sizeof tag_tail.data);
+ last.status |= kit_xml_alloc_and_unescape_(
+ &tag.tag, ib_str(tag_name), alloc);
+ last.status |= kit_xml_alloc_and_unescape_(
+ &tag.tail, WRAP_STR(tag_tail_string), alloc);
res.tags.values[n] = tag;
}
} else
xml_destroy(&tag);
-
- ib_destroy(tag_open);
- ib_destroy(tag_name);
- ib_destroy(tag_tail);
}
if (last.status != KIT_OK) {
@@ -307,13 +259,12 @@ static kit_xml_intermediate_t kit_xml_parse_buf_(
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);
- }
+ } else
+ last.status |= kit_xml_alloc_and_unescape_(
+ &res.text, WRAP_STR(tag_text_string), alloc);
- ib_destroy(tag_text);
+ DA_DESTROY(tag_text_string);
+ DA_DESTROY(tag_tail_string);
res.last = last;
return res;
@@ -321,23 +272,25 @@ static kit_xml_intermediate_t kit_xml_parse_buf_(
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);
+ input_buffer_t ib = ib_wrap(is, alloc);
+ kit_xml_intermediate_t im = kit_xml_parse_buf_(ib_token(&ib),
+ alloc);
kit_xml_parse_result_t res;
memset(&res, 0, sizeof res);
res.status = im.last.status;
- ib_destroy(im.last);
- if (res.status != KIT_OK)
+ if (res.status != KIT_OK) {
+ ib_destroy(&ib);
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);
+ ib_destroy(&ib);
return res;
}
@@ -348,10 +301,14 @@ kit_xml_parse_result_t kit_xml_parse(kit_is_handle_t is,
res.xml.text = im.text;
res.xml.children = im.tags;
+ ib_destroy(&ib);
return res;
}
kit_xml_text_t kit_xml_print(kit_xml_t *xml, kit_allocator_t *alloc) {
+ // TODO
+ //
+
assert(xml != NULL);
xml_text_t result;
@@ -361,8 +318,7 @@ kit_xml_text_t kit_xml_print(kit_xml_t *xml, kit_allocator_t *alloc) {
return result;
}
-static kit_status_t kit_xml_append_text_(str_builder_t *buf,
- xml_t *xml) {
+static s32 kit_xml_append_text_(str_builder_t *buf, xml_t *xml) {
assert(buf != NULL);
assert(xml != NULL);
@@ -377,8 +333,7 @@ static kit_status_t kit_xml_append_text_(str_builder_t *buf,
memcpy(buf->values + n, xml->text.values, xml->text.size);
for (i64 i = 0; i < xml->children.size; i++) {
- kit_status_t s = kit_xml_append_text_(buf,
- xml->children.values + i);
+ s32 s = kit_xml_append_text_(buf, xml->children.values + i);
if (s != KIT_OK)
return s;
diff --git a/source/kit/xml.h b/source/kit/xml.h
index 0bd5744..755a918 100644
--- a/source/kit/xml.h
+++ b/source/kit/xml.h
@@ -29,12 +29,12 @@ struct kit_xml_ {
};
typedef struct {
- kit_status_t status;
- kit_xml_t xml;
+ s32 status;
+ kit_xml_t xml;
} kit_xml_parse_result_t;
typedef struct {
- kit_status_t status;
+ s32 status;
kit_str_builder_t text;
} kit_xml_text_t;
diff --git a/source/tests/input_buffer.test.c b/source/tests/input_buffer.test.c
index b8dc19b..1ec1ad4 100644
--- a/source/tests/input_buffer.test.c
+++ b/source/tests/input_buffer.test.c
@@ -4,59 +4,54 @@
#include "../kit/test.h"
TEST("input buffer read once") {
- str_t text = { .size = 3, .values = "foo" };
- is_handle_t in = IS_WRAP_STRING(text);
- ib_t first = IB_WRAP(in);
+ str_t text = { .size = 3, .values = "foo" };
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
- ib_t second = ib_read(first, 3);
+ ib_token_t tok = ib_read(ib_token(&buf), 3);
- REQUIRE(second.status == KIT_OK);
- REQUIRE(second.data.size == 3);
- REQUIRE(AR_EQUAL(text, second.data));
+ REQUIRE_EQ(tok.status, KIT_OK);
+ REQUIRE_EQ(tok.size, 3);
+ REQUIRE(AR_EQUAL(text, ib_str(tok)));
- ib_destroy(second);
- ib_destroy(first);
+ ib_destroy(&buf);
is_destroy(in);
}
TEST("input buffer read again") {
- str_t text = { .size = 6, .values = "foobar" };
- str_t foo = { .size = 3, .values = "foo" };
- is_handle_t in = IS_WRAP_STRING(text);
- ib_t first = IB_WRAP(in);
+ str_t text = { .size = 6, .values = "foobar" };
+ str_t foo = { .size = 3, .values = "foo" };
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
- ib_t second = ib_read(first, 3);
- ib_t third = ib_read(first, 3);
+ ib_token_t first = ib_read(ib_token(&buf), 3);
+ ib_token_t second = ib_read(ib_token(&buf), 3);
- REQUIRE(AR_EQUAL(foo, second.data));
- REQUIRE(AR_EQUAL(foo, third.data));
+ REQUIRE(AR_EQUAL(foo, ib_str(first)));
+ REQUIRE(AR_EQUAL(foo, ib_str(second)));
- ib_destroy(third);
- ib_destroy(second);
- ib_destroy(first);
+ ib_destroy(&buf);
is_destroy(in);
}
TEST("input buffer read twice") {
- str_t text = { .size = 6, .values = "foobar" };
- str_t foo = { .size = 3, .values = "foo" };
- str_t bar = { .size = 3, .values = "bar" };
- is_handle_t in = IS_WRAP_STRING(text);
- ib_t first = IB_WRAP(in);
+ str_t text = { .size = 6, .values = "foobar" };
+ str_t foo = { .size = 3, .values = "foo" };
+ str_t bar = { .size = 3, .values = "bar" };
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
- ib_t second = ib_read(first, 3);
- ib_t third = ib_read(second, 3);
+ ib_token_t first = ib_read(ib_token(&buf), 3);
+ ib_token_t second = ib_read(first, 3);
- REQUIRE(AR_EQUAL(foo, second.data));
- REQUIRE(AR_EQUAL(bar, third.data));
+ REQUIRE(AR_EQUAL(foo, ib_str(first)));
+ REQUIRE(AR_EQUAL(bar, ib_str(second)));
- ib_destroy(third);
- ib_destroy(second);
- ib_destroy(first);
+ ib_destroy(&buf);
is_destroy(in);
}
-static i8 is_integer_(str_t const data, void *_) {
+static b8 is_integer_(str_t const data, void *_) {
for (ptrdiff_t i = 0; i < data.size; i++)
if (data.values[i] < '0' || data.values[i] > '9')
return 0;
@@ -64,43 +59,126 @@ static i8 is_integer_(str_t const data, void *_) {
}
TEST("input buffer read integer once") {
- str_t text = { .size = 9, .values = "31415 foo" };
- str_t num = { .size = 5, .values = "31415" };
- is_handle_t in = IS_WRAP_STRING(text);
- ib_t first = IB_WRAP(in);
+ str_t text = { .size = 9, .values = "31415 foo" };
+ str_t num = { .size = 5, .values = "31415" };
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
- ib_t second = ib_while(first, is_integer_, NULL);
+ ib_token_t tok = ib_while(ib_token(&buf), is_integer_, NULL);
- REQUIRE(second.status == KIT_OK);
- REQUIRE(second.data.size == 5);
- REQUIRE(AR_EQUAL(num, second.data));
+ REQUIRE_EQ(tok.status, KIT_OK);
+ REQUIRE_EQ(tok.size, 5);
+ REQUIRE(AR_EQUAL(num, ib_str(tok)));
- ib_destroy(second);
- ib_destroy(first);
+ ib_destroy(&buf);
is_destroy(in);
}
TEST("input buffer read integer twice") {
- str_t text = { .size = 6, .values = "314 15" };
- str_t num_0 = { .size = 3, .values = "314" };
- str_t num_1 = { .size = 2, .values = "15" };
- is_handle_t in = IS_WRAP_STRING(text);
- ib_t first = IB_WRAP(in);
-
- ib_t second = ib_while(first, is_integer_, NULL);
- ib_t third = ib_read(second, 1);
- ib_t fourth = ib_while(third, is_integer_, NULL);
-
- REQUIRE(fourth.status == KIT_OK);
- REQUIRE(second.data.size == 3);
- REQUIRE(fourth.data.size == 2);
- REQUIRE(AR_EQUAL(num_0, second.data));
- REQUIRE(AR_EQUAL(num_1, fourth.data));
-
- ib_destroy(first);
- ib_destroy(second);
- ib_destroy(third);
- ib_destroy(fourth);
+ str_t text = { .size = 6, .values = "314 15" };
+ str_t num_0 = { .size = 3, .values = "314" };
+ str_t num_1 = { .size = 2, .values = "15" };
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t first = ib_while(ib_token(&buf), is_integer_, NULL);
+ ib_token_t second = ib_read(first, 1);
+ ib_token_t third = ib_while(second, is_integer_, NULL);
+
+ REQUIRE_EQ(third.status, KIT_OK);
+ REQUIRE_EQ(first.size, 3);
+ REQUIRE_EQ(third.size, 2);
+ REQUIRE(AR_EQUAL(num_0, ib_str(first)));
+ REQUIRE(AR_EQUAL(num_1, ib_str(third)));
+
+ ib_destroy(&buf);
+ is_destroy(in);
+}
+
+TEST("input buffer any") {
+ str_t text = SZ("01234bbdac");
+ str_t expect = SZ("01234");
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t tok = ib_any(ib_token(&buf), SZ("01234"));
+
+ REQUIRE_EQ(tok.status, KIT_OK);
+ REQUIRE(AR_EQUAL(expect, ib_str(tok)));
+
+ ib_destroy(&buf);
+ is_destroy(in);
+}
+
+TEST("input buffer none") {
+ str_t text = SZ("01234bbdac");
+ str_t expect = SZ("01234");
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t tok = ib_none(ib_token(&buf), SZ("abcd"));
+
+ REQUIRE_EQ(tok.status, KIT_OK);
+ REQUIRE(AR_EQUAL(expect, ib_str(tok)));
+
+ ib_destroy(&buf);
+ is_destroy(in);
+}
+
+TEST("input buffer until") {
+ str_t text = SZ("01234bbdac");
+ str_t expect = SZ("01234");
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t tok = ib_none(ib_token(&buf), SZ("bbdac"));
+
+ REQUIRE_EQ(tok.status, KIT_OK);
+ REQUIRE(AR_EQUAL(expect, ib_str(tok)));
+
+ ib_destroy(&buf);
+ is_destroy(in);
+}
+
+TEST("input buffer exact success") {
+ str_t text = SZ("01234bbdac");
+ str_t expect = SZ("01234");
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t tok = ib_exact(ib_token(&buf), SZ("01234"));
+
+ REQUIRE_EQ(tok.status, KIT_OK);
+ REQUIRE(AR_EQUAL(expect, ib_str(tok)));
+
+ ib_destroy(&buf);
+ is_destroy(in);
+}
+
+TEST("input buffer exact fail") {
+ str_t text = SZ("01234bbdac");
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t tok = ib_exact(ib_token(&buf), SZ("bbdac"));
+
+ REQUIRE_EQ(tok.status, KIT_PARSING_FAILED);
+
+ ib_destroy(&buf);
+ is_destroy(in);
+}
+
+TEST("input buffer use after free") {
+ str_t text = SZ("foobarfoobar");
+ is_handle_t in = IS_WRAP_STRING(text);
+ input_buffer_t buf = ib_wrap(in, NULL);
+
+ ib_token_t first = ib_exact(ib_token(&buf), SZ("foobar"));
+ ib_token_t second = ib_exact(first, ib_str(first));
+
+ REQUIRE_EQ(second.status, KIT_OK);
+
+ ib_destroy(&buf);
is_destroy(in);
}
diff --git a/source/tests/xml.test.c b/source/tests/xml.test.c
index a3e931d..4c72d28 100644
--- a/source/tests/xml.test.c
+++ b/source/tests/xml.test.c
@@ -37,7 +37,7 @@ TEST("xml parse tag not closed") {
is_handle_t is = IS_WRAP_STRING(SZ("<foo>"));
xml_parse_result_t res = xml_parse(is, NULL);
- REQUIRE_EQ(res.status, KIT_ERROR_INTERNAL);
+ REQUIRE_EQ(res.status, KIT_PARSING_FAILED);
if (res.status == KIT_OK)
xml_destroy(&res.xml);
@@ -380,7 +380,7 @@ TEST("xml parse invalid escape") {
is_handle_t is = IS_WRAP_STRING(SZ("&foobar;"));
xml_parse_result_t res = xml_parse(is, NULL);
- REQUIRE_EQ(res.status, KIT_ERROR_INTERNAL);
+ REQUIRE_EQ(res.status, KIT_PARSING_FAILED);
if (res.status == KIT_OK)
xml_destroy(&res.xml);