From 2082d56c2546c76de5b1411c5d7ff86a76487469 Mon Sep 17 00:00:00 2001 From: Timerix Date: Wed, 26 Nov 2025 16:42:28 +0500 Subject: [PATCH] added tlibc error handling everywhere --- README.md | 29 +++++++-- include/{tlibtoml/toml.h => tlibtoml.h} | 8 ++- project.config | 2 +- src/TomlTable.c | 2 +- src/TomlValue.c | 11 +++- src/tlibtoml.c | 15 +++++ src/toml_internal.h | 42 ++++++------ src/toml_load.c | 65 ++++++++++--------- src/toml_parse/toml_parse.c | 14 ++-- src/toml_parse/toml_parse_array.c | 17 ++--- src/toml_parse/toml_parse_bare_key.c | 26 ++++++++ src/toml_parse/toml_parse_basic_string.c | 16 +++-- .../toml_parse_basic_string_value.c | 16 ++--- src/toml_parse/toml_parse_bool.c | 54 ++++++++++----- src/toml_parse/toml_parse_datetime.c | 8 ++- src/toml_parse/toml_parse_inline_table.c | 50 ++++++-------- .../toml_parse_int_or_float_or_time.c | 58 +++++++---------- src/toml_parse/toml_parse_key_value.c | 40 ++++++------ src/toml_parse/toml_parse_literal_string.c | 10 +-- .../toml_parse_literal_string_value.c | 14 ++-- .../toml_parse_multi_line_basic_string.c | 10 +-- .../toml_parse_multi_line_literal_string.c | 17 ++--- src/toml_parse/toml_parse_table.c | 42 +++++------- src/toml_parse/toml_parse_value.c | 28 ++++---- src/toml_parse/toml_walk_table_path.c | 39 +++++------ src/toml_parser.c | 35 +++------- tests/main.c | 14 ++-- 27 files changed, 374 insertions(+), 308 deletions(-) rename include/{tlibtoml/toml.h => tlibtoml.h} (96%) create mode 100644 src/tlibtoml.c create mode 100644 src/toml_parse/toml_parse_bare_key.c diff --git a/README.md b/README.md index e481cc3..70516aa 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,42 @@ # tlibtoml A fork of [libtoml](https://github.com/brglng/libtoml) rewritten to use [tlibc](https://timerix.ddns.net/git/Timerix/tlibtoml) instead of its own (worse) implementation of collections and strings. For example, Table from libtoml is just an array of key-value pairs, where search happens by calling `strcmp()` on each element. Such inefficient code hurts my mind, so i have no other choise than to rewrite this library. + ## Build -1. Clone the repository. +1. Clone this repository. ``` git clone https://timerix.ddns.net/git/Timerix/tlibtoml.git ``` -2. Install [cbuild](https://timerix.ddns.net/git/Timerix/cbuild). -3. Clone [tlibc](https://timerix.ddns.net/git/Timerix/tlibc). By default - `dependencies/tlibc.config` expects that `tlibc/` is present in the same directory as `tlibtoml/`. + +2. Install [cbuild](https://timerix.ddns.net/git/Timerix/cbuild) version specified in `project.config`. + +3. Clone [tlibc](https://timerix.ddns.net/git/Timerix/tlibc). + By default `dependencies/tlibc.config` expects that `tlibc/` is present in the same directory as `tlibtoml/`. If you cloned it to another directory, change `DEPENDENCIES_DIR` in `tlibtoml/project.user.config`. ``` git clone https://timerix.ddns.net/git/Timerix/tlibc.git ``` + 4. Build and run tests ``` cd tlibtoml cbuild build_exec exec ``` + 5. To build library use tasks `build_static_lib[_dbg]` or `build_shared_lib[_dbg]` + + +## Usage +```c +#include "tlibtoml.h" + +int main(){ + Deferral(32); // reserve memory for 32 defers + try_fatal_void(tlibc_init()); + try_fatal_void(tlibtoml_init()); + Defer(tlibc_deinit()); + Defer(tlibtoml_deinit()); + + Return 0; // call defers +} +``` diff --git a/include/tlibtoml/toml.h b/include/tlibtoml.h similarity index 96% rename from include/tlibtoml/toml.h rename to include/tlibtoml.h index 867c558..507e81c 100644 --- a/include/tlibtoml/toml.h +++ b/include/tlibtoml.h @@ -15,6 +15,10 @@ extern "C" { #include "tlibc/string/str.h" #include "tlibc/collections/HashMap.h" + +Result(void) tlibtoml_init(); +void tlibtoml_deinit(); + typedef DateTime TomlDateTime; typedef HashMap(TomlValue) TomlTable; @@ -123,7 +127,9 @@ TomlValue TomlValue_new_float(f64 flt); TomlValue TomlValue_new_datetime(void); TomlValue TomlValue_new_bool(bool b); /// copies the string -TomlValue TomlValue_new_string(str s); +TomlValue TomlValue_copy_str(str s); +/// doesnt copy the string +TomlValue TomlValue_move_str(str s); void TomlValue_destroy(TomlValue* self); #ifdef __cplusplus diff --git a/project.config b/project.config index da42b01..a950c2f 100644 --- a/project.config +++ b/project.config @@ -1,5 +1,5 @@ #!/usr/bin/env bash -CBUILD_VERSION=2.3.0 +CBUILD_VERSION=2.3.2 PROJECT="tlibtoml" CMP_C="gcc" diff --git a/src/TomlTable.c b/src/TomlTable.c index 9351ab5..ba4efba 100644 --- a/src/TomlTable.c +++ b/src/TomlTable.c @@ -7,7 +7,7 @@ TomlTable* TomlTable_new(void) { TomlTable* table = malloc(sizeof(TomlTable)); - HashMap_construct(table, TomlValue, (FreeFunction)TomlValue_destroy); + HashMap_construct(table, TomlValue, (Destructor_t)TomlValue_destroy); return table; } diff --git a/src/TomlValue.c b/src/TomlValue.c index 583c04a..6a42b1b 100644 --- a/src/TomlValue.c +++ b/src/TomlValue.c @@ -38,10 +38,15 @@ TomlValue TomlValue_new(TomlType type) return value; } -TomlValue TomlValue_from_str(str s) +TomlValue TomlValue_copy_str(str s) { + return TomlValue_move_str(str_copy(s)); +} + +TomlValue TomlValue_move_str(str s){ TomlValue value = {0}; - value.value.s = str_copy(s); + value.value.s = (str*)malloc(sizeof(str)); + *value.value.s = s; value.type = TLIBTOML_STRING; return value; } @@ -98,7 +103,7 @@ void TomlValue_destroy(TomlValue* self) switch (self->type) { case TLIBTOML_STRING: - str_destroy(self->value.s); + str_free(self->value.s); break; case TLIBTOML_TABLE: TomlTable_free(self->value.table); diff --git a/src/tlibtoml.c b/src/tlibtoml.c new file mode 100644 index 0000000..7fae139 --- /dev/null +++ b/src/tlibtoml.c @@ -0,0 +1,15 @@ +#include "tlibtoml.h" + +ErrorCodePage_define(TLIBTOML); + +Result(void) tlibtoml_init(){ + Deferral(8); + + ErrorCodePage_register(TLIBTOML); + + Return RESULT_VOID; +} + +void tlibtoml_deinit(){ + +} diff --git a/src/toml_internal.h b/src/toml_internal.h index a6344c2..2483928 100644 --- a/src/toml_internal.h +++ b/src/toml_internal.h @@ -2,17 +2,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#pragma onces +#pragma once #ifdef __cplusplus extern "C" { #endif -#include "tlibtoml/toml.h" +#include "tlibtoml.h" #include "tlibc/string/StringBuilder.h" #include "tlibc/collections/HashMap.h" #include "tlibc/collections/List.h" -// TODO: get rid of libc assert #include #include @@ -30,26 +29,27 @@ void toml_parser_free(TomlParser* self); void toml_move_next(TomlParser* self); void toml_next_n(TomlParser* self, i32 n); -str toml_parse_bare_key(TomlParser* self); -char toml_hex_char_to_int(char ch); +u32 toml_hex_char_to_int(char ch); Result(void) toml_encode_unicode_scalar(StringBuilder* sb_ptr, TomlParser* parser, i32 n); -Result(str*) toml_parse_basic_string(TomlParser* self); -Result(str*) toml_parse_literal_string(TomlParser* self); -TomlValue toml_parse_basic_string_value(TomlParser* self); -TomlValue toml_parse_literal_string_value(TomlParser* self); -TomlValue toml_parse_multi_line_basic_string(TomlParser* self); -TomlValue toml_parse_multi_line_literal_string(TomlParser* self); -TomlValue toml_parse_datetime(str s); -TomlValue toml_parse_int_or_float_or_time(TomlParser* self); -TomlValue toml_parse_bool(TomlParser* self); -TomlValue toml_parse_value(TomlParser* self); -TomlValue toml_parse_array(TomlParser* self); -TomlValue toml_parse_inline_table(TomlParser* self); -Result(void) toml_parse_table(TomlParser* self, TomlTable* table); -Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table); -Result(TomlTable*) toml_walk_table_path(TomlParser* parser, TomlTable* table, - TomlArray* key_path, i32 is_array, i32 create_if_not_exist); +Result(void) toml_parse_bare_key(TomlParser* self, str* out_str); +Result(void) toml_parse_basic_string(TomlParser* self, str* out_str); +Result(void) toml_parse_literal_string(TomlParser* self, str* out_str); +Result(void) toml_parse_basic_string_value(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_literal_string_value(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_multi_line_basic_string(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_multi_line_literal_string(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_datetime(str s, TomlValue* out_value); +Result(void) toml_parse_int_or_float_or_time(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_bool(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_value(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_array(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_inline_table(TomlParser* self, TomlValue* out_value); +Result(void) toml_parse_table(TomlParser* self, TomlTable* target_table); +Result(void) toml_parse_key_value(TomlParser* self, TomlTable* target_table); +Result(TomlTable*) toml_walk_table_path(TomlParser* parser, TomlTable* target_table, + TomlArray* key_path, bool is_array, bool create_if_not_exist); +Result(TomlTable*) toml_parse(TomlParser* self); #ifdef __cplusplus diff --git a/src/toml_load.c b/src/toml_load.c index a9ce1ae..e561bbd 100644 --- a/src/toml_load.c +++ b/src/toml_load.c @@ -11,7 +11,38 @@ Result(TomlTable*) toml_load_str_filename(str s, cstr filename) TomlParser* parser = toml_parser_new(s, filename); Defer(toml_parser_free(parser)); - try(TomlTable* table, p, = toml_parse(parser)); + try(TomlTable* table, p, toml_parse(parser)); + + Return RESULT_VALUE(p, table); +} + + +Result(TomlTable*) toml_load_file_filename(FILE* file, cstr filename) +{ + Deferral(4); + + const u32 file_chunk_size = 8*1024; + StringBuilder sb = StringBuilder_alloc(file_chunk_size); + Defer(StringBuilder_destroy(&sb)); + u64 count = 0; + u64 remaining_capacity = 0; + do { + remaining_capacity = sb.buffer.capacity - sb.buffer.len; + count = fread((char*)sb.buffer.data + sb.buffer.len, 1, remaining_capacity, file); + if (ferror(file)) { + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_OS, + "Error when reading %s [errno %d: %s]", + filename, errno, strerror(errno)); + } + + sb.buffer.len += count; + + if (sb.buffer.len + 1 >= sb.buffer.capacity) { + StringBuilder_increaseCapacity(&sb, file_chunk_size); + } + } while (count == remaining_capacity); + + try(TomlTable* table, p, toml_load_str_filename(StringBuilder_getStr(&sb), filename)); Return RESULT_VALUE(p, table); } @@ -28,40 +59,10 @@ Result(TomlTable*) toml_load_file(FILE* file) Result(TomlTable*) toml_load_filename(cstr filename) { - Deferral(4); + Deferral(1); try(FILE* f, p, file_open(filename, FO_ReadExisting)); try(TomlTable* table, p, toml_load_file_filename(f, filename)); Return RESULT_VALUE(p, table); } - -Result(TomlTable*) toml_load_file_filename(FILE* file, cstr filename) -{ - Deferral(8); - - const u32 file_chunk_size = 8*1024; - StringBuilder sb = StringBuilder_alloc(file_chunk_size); - Defer(StringBuilder_destroy(&sb)); - u64 count = 0; - u64 remaining_capacity = 0; - do { - remaining_capacity = sb.buffer.allocated_size - sb.buffer.size; - count = fread((char*)sb.buffer.data + sb.buffer.size, 1, remaining_capacity, file); - if (ferror(file)) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_OS, - "Error when reading %s [errno %d: %s]", - filename, errno, strerror(errno)); - } - - sb.buffer.size += count; - - if (sb.buffer.size + 1 >= sb.buffer.allocated_size) { - StringBuilder_increaseCapacity(&sb, file_chunk_size); - } - } while (count == remaining_capacity); - - try(TomlTable* table, p, toml_load_str_filename(StringBuilder_getStr(&sb), filename)); - - Return RESULT_VALUE(p, table); -} diff --git a/src/toml_parse/toml_parse.c b/src/toml_parse/toml_parse.c index 09e56ea..70ff5a0 100644 --- a/src/toml_parse/toml_parse.c +++ b/src/toml_parse/toml_parse.c @@ -6,9 +6,10 @@ Result(TomlTable*) toml_parse(TomlParser* self) { - Deferral(8); + Deferral(1); TomlTable* table = TomlTable_new(); - Defer(TomlTable_free(table)); + bool success = false; + Defer(if(!success) TomlTable_free(table)); while (self->ptr < self->end) { char ch = *self->ptr; @@ -26,11 +27,9 @@ Result(TomlTable*) toml_parse(TomlParser* self) toml_move_next(self); } else if (ch == '[') { toml_move_next(self); - if (toml_parse_table(self, table) != 0) - return NULL; + try_void(toml_parse_table(self, table)); } else if (isalnum(ch) || ch == '_' || ch == '-') { - if (toml_parse_key_value(self, table) != 0) - return NULL; + try_void(toml_parse_key_value(self, table)); } else if (ch == ' ' || ch == '\t' || ch == '\r') { do { toml_move_next(self); @@ -41,5 +40,6 @@ Result(TomlTable*) toml_parse(TomlParser* self) } } - return table; + success = true; + Return RESULT_VALUE(p, table); } diff --git a/src/toml_parse/toml_parse_array.c b/src/toml_parse/toml_parse_array.c index 08558bd..96b7b39 100644 --- a/src/toml_parse/toml_parse_array.c +++ b/src/toml_parse/toml_parse_array.c @@ -4,9 +4,12 @@ #include "toml_internal.h" -TomlValue toml_parse_array(TomlParser* self) +Result(void) toml_parse_array(TomlParser* self, TomlValue* out_value) { + Deferral(1); TomlValue array_value = TomlValue_new_array(); + bool success = false; + Defer(if(!success) TomlValue_destroy(&array_value)); while (self->ptr < self->end) { if (isspace(*self->ptr)) { @@ -24,12 +27,8 @@ TomlValue toml_parse_array(TomlParser* self) toml_move_next(self); break; } else { - TomlValue value = toml_parse_value(self); - if (value.type == TLIBTOML_INVALID_TYPE) { - TomlValue_destroy(&array_value); - //TODO: error handling - assert(false && "TODO error handling"); - } + TomlValue value; + try_void(toml_parse_value(self, &value)); TomlArray_append(array_value.value.array, value); @@ -53,5 +52,7 @@ TomlValue toml_parse_array(TomlParser* self) } } - return array_value; + success = true; + *out_value = array_value; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_bare_key.c b/src/toml_parse/toml_parse_bare_key.c new file mode 100644 index 0000000..d1481ce --- /dev/null +++ b/src/toml_parse/toml_parse_bare_key.c @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "toml_internal.h" + +Result(void) toml_parse_bare_key(TomlParser* self, str* s_out) +{ + Deferral(1); + + cstr s = self->ptr; + u64 len = 0; + + while (self->ptr < self->end) { + char ch = *self->ptr; + + if (!(isalnum(ch) || ch == '_' || ch == '-')) + break; + + len++; + toml_move_next(self); + } + + *s_out = str_copy(str_construct((void*)s, len, false)); + Return RESULT_VOID; +} diff --git a/src/toml_parse/toml_parse_basic_string.c b/src/toml_parse/toml_parse_basic_string.c index 0b7d06b..28eb29d 100644 --- a/src/toml_parse/toml_parse_basic_string.c +++ b/src/toml_parse/toml_parse_basic_string.c @@ -4,10 +4,12 @@ #include "toml_internal.h" -Result(str*) toml_parse_basic_string(TomlParser* self) +Result(void) toml_parse_basic_string(TomlParser* self, str* out_str) { - Deferral(16); + Deferral(1); StringBuilder sb = StringBuilder_alloc(32); + bool success = false; + Defer(if(!success) StringBuilder_destroy(&sb)); while (self->ptr < self->end &&* self->ptr != '\"' &&* self->ptr != '\n') { char ch1 = *self->ptr; @@ -45,7 +47,8 @@ Result(str*) toml_parse_basic_string(TomlParser* self) toml_move_next(self); try_void(toml_encode_unicode_scalar(&sb, self, 8)); } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid escape character", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid escape character", self->filename, self->lineno, self->colno); } } else { @@ -55,9 +58,14 @@ Result(str*) toml_parse_basic_string(TomlParser* self) } if (self->ptr >= self->end ||* self->ptr != '\"' ||* self->ptr == '\n') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated basic string", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated basic string", self->filename, self->lineno, self->colno); } toml_move_next(self); + + *out_str = StringBuilder_getStr(&sb); + success = true; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_basic_string_value.c b/src/toml_parse/toml_parse_basic_string_value.c index 0499b74..35a8866 100644 --- a/src/toml_parse/toml_parse_basic_string_value.c +++ b/src/toml_parse/toml_parse_basic_string_value.c @@ -4,13 +4,13 @@ #include "toml_internal.h" -TomlValue toml_parse_basic_string_value(TomlParser* self) +Result(void) toml_parse_basic_string_value(TomlParser* self, TomlValue* out_value) { - str s = toml_parse_basic_string(self); - //TODO: error handling - assert(s.data != NULL); - - TomlValue value = TomlValue_new(TLIBTOML_STRING); - value.value.s = s; - return value; + Deferral(1); + + str s; + try_void(toml_parse_basic_string(self, &s)); + *out_value = TomlValue_move_str(s); + + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_bool.c b/src/toml_parse/toml_parse_bool.c index 0fe486e..cd2203e 100644 --- a/src/toml_parse/toml_parse_bool.c +++ b/src/toml_parse/toml_parse_bool.c @@ -4,21 +4,41 @@ #include "toml_internal.h" -TomlValue toml_parse_bool(TomlParser* self) -{ - if (self->ptr + 4 <= self->end && strncmp(self->ptr, "true", 4) == 0 && - (self->ptr + 4 == self->end || isspace(*(self->ptr + 4)) || *(self->ptr + 4) == ',' || *(self->ptr + 4) == ']' || *(self->ptr + 4) == '}')) { - toml_next_n(self, 4); - return TomlValue_new_bool(true); - } - - if (self->ptr + 5 <= self->end && strncmp(self->ptr, "false", 5) == 0 && - (self->ptr + 5 == self->end || isspace(*(self->ptr + 5)) || *(self->ptr + 5) == ',' || *(self->ptr + 5) == ']' || *(self->ptr + 5) == '}')) { - toml_next_n(self, 5); - return TomlValue_new_bool(false); - } - - //TODO: error handling - assert(false && "TODO error handling"); - return TomlValue_new(TLIBTOML_INVALID_TYPE); +static bool is_value_end(cstr expected_value_end, cstr input_end){ + if(expected_value_end == input_end) + return true; + + char next_ch = *expected_value_end; + return isspace(next_ch) || next_ch == ',' || next_ch == ']' || next_ch == '}'; +} + +Result(void) toml_parse_bool(TomlParser* self, TomlValue* out_value) +{ + Deferral(1); + + cstr val_end = self->ptr + 4; + if(val_end <= self->end && strncmp(self->ptr, "true", 4) == 0) + { + if(is_value_end(val_end, self->end)) + { + toml_next_n(self, 4); + *out_value = TomlValue_new_bool(true); + Return RESULT_VOID; + } + } + + val_end = self->ptr + 5; + if(val_end <= self->end && strncmp(self->ptr, "false", 5) == 0) + { + if(is_value_end(val_end, self->end)) + { + toml_next_n(self, 5); + *out_value = TomlValue_new_bool(false); + Return RESULT_VOID; + } + } + + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: value of unknown type", + self->filename, self->lineno, self->colno); } diff --git a/src/toml_parse/toml_parse_datetime.c b/src/toml_parse/toml_parse_datetime.c index da28771..dd13e92 100644 --- a/src/toml_parse/toml_parse_datetime.c +++ b/src/toml_parse/toml_parse_datetime.c @@ -4,9 +4,13 @@ #include "toml_internal.h" -TomlValue toml_parse_datetime(str s) +Result(void) toml_parse_datetime(str s, TomlValue* out_value) { + Deferral(1); (void)s; //TODO: parse datetime - return TomlValue_new(TLIBTOML_DATETIME); + try_assert(false && "DateTime parsing is not implemented"); + TomlValue value = TomlValue_new(TLIBTOML_DATETIME); + *out_value = value; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_inline_table.c b/src/toml_parse/toml_parse_inline_table.c index 2295573..5120243 100644 --- a/src/toml_parse/toml_parse_inline_table.c +++ b/src/toml_parse/toml_parse_inline_table.c @@ -4,9 +4,13 @@ #include "toml_internal.h" -TomlValue toml_parse_inline_table(TomlParser* self) +Result(void) toml_parse_inline_table(TomlParser* self, TomlValue* out_value) { + Deferral(1); + TomlValue table_value = TomlValue_new_table(); + bool success = false; + Defer(if(!success) TomlValue_destroy(&table_value)); while (self->ptr < self->end) { char ch = *self->ptr; @@ -17,25 +21,19 @@ TomlValue toml_parse_inline_table(TomlParser* self) str key; if (isalnum(ch) || ch == '_') { - key = toml_parse_bare_key(self); - if (key.data == NULL) - goto error; + try_void(toml_parse_bare_key(self, &key)); } else if (ch == '\"') { toml_move_next(self); - key = toml_parse_basic_string(self); - if (key.data == NULL) - goto error; + try_void(toml_parse_basic_string(self, &key)); } else if (ch == '\'') { toml_move_next(self); - key = toml_parse_literal_string(self); - if (key.data == NULL) - goto error; + try_void(toml_parse_literal_string(self, &key)); } else if (ch == '}') { break; } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unexpected token", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unexpected token", self->filename, self->lineno, self->colno); - goto error; } ch = *self->ptr; @@ -45,15 +43,15 @@ TomlValue toml_parse_inline_table(TomlParser* self) } if (self->ptr == self->end) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated key value pair", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated key value pair", self->filename, self->lineno, self->colno); - goto error; } if (ch != '=') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unexpected token", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unexpected token", self->filename, self->lineno, self->colno); - goto error; } toml_move_next(self); @@ -65,14 +63,13 @@ TomlValue toml_parse_inline_table(TomlParser* self) } if (self->ptr == self->end) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated key value pair", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated key value pair", self->filename, self->lineno, self->colno); - goto error; } - TomlValue value = toml_parse_value(self); - if (value.type == TLIBTOML_INVALID_TYPE) - goto error; + TomlValue value; + try_void(toml_parse_value(self, &value)); TomlTable_set(table_value.value.table, key, value); str_destroy(key); @@ -89,12 +86,7 @@ TomlValue toml_parse_inline_table(TomlParser* self) } } - goto end; - -error: - TomlValue_destroy(&table_value); - //TODO: error handling - assert(false && "TODO error handling"); -end: - return table_value; + success = true; + *out_value = table_value; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_int_or_float_or_time.c b/src/toml_parse/toml_parse_int_or_float_or_time.c index c23fb1c..79db5b2 100644 --- a/src/toml_parse/toml_parse_int_or_float_or_time.c +++ b/src/toml_parse/toml_parse_int_or_float_or_time.c @@ -4,15 +4,17 @@ #include "toml_internal.h" -TomlValue toml_parse_int_or_float_or_time(TomlParser* self) +Result(void) toml_parse_int_or_float_or_time(TomlParser* self, TomlValue* out_value) { - TomlValue value = {0}; + Deferral(1); + + StringBuilder sb = StringBuilder_alloc(32); + Defer(StringBuilder_destroy(&sb)); + TomlValue value = {0}; char type = 'i'; i32 base = 10; - StringBuilder sb = StringBuilder_alloc(32); - // Determine nan and inf type as float, as we cannot determine by dot. // But do not strip it because we will append it to the string later if (self->ptr + 3 <= self->end && @@ -24,7 +26,8 @@ TomlValue toml_parse_int_or_float_or_time(TomlParser* self) (strncmp(self->ptr, "+nan", 4) == 0 || strncmp(self->ptr, "-nan", 4) == 0 || strncmp(self->ptr, "+inf", 4) == 0 || - strncmp(self->ptr, "-inf", 4) == 0)) { + strncmp(self->ptr, "-inf", 4) == 0)) + { type = 'f'; } @@ -67,27 +70,21 @@ TomlValue toml_parse_int_or_float_or_time(TomlParser* self) type = 'f'; StringBuilder_append_char(&sb,* self->ptr); } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid float", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid float", self->filename, self->lineno, self->colno); - StringBuilder_destroy(&sb); - //TODO: error handling - assert(false && "TODO error handling"); } } else if (*self->ptr == '_') { if (type == 't') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid datetime", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid datetime", self->filename, self->lineno, self->colno); - StringBuilder_destroy(&sb); - //TODO: error handling - assert(false && "TODO error handling"); } if (!isalnum(last_char)) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid integer or float", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid integer or float", self->filename, self->lineno, self->colno); - StringBuilder_destroy(&sb); - //TODO: error handling - assert(false && "TODO error handling"); } } else if (*self->ptr == '-') { type = 't'; @@ -101,40 +98,35 @@ TomlValue toml_parse_int_or_float_or_time(TomlParser* self) } if (last_char == '_') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid integer or float or datetime", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid integer or float or datetime", self->filename, self->lineno, self->colno); - StringBuilder_destroy(&sb); - //TODO: error handling - assert(false && "TODO error handling"); } if (type == 'i') { char* end = NULL; char* start = StringBuilder_getStr(&sb).data; i64 n = strtoll(start, &end, base); - if (end < start + sb.buffer.size) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid integer", + if (end < start + sb.buffer.len) { + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid integer", self->filename, self->lineno, self->colno); - StringBuilder_destroy(&sb); - //TODO: error handling - assert(false && "TODO error handling"); } value = TomlValue_new_integer(n); } else if (type == 'f') { char* end = NULL; char* start = StringBuilder_getStr(&sb).data; f64 n = strtod(start, &end); - if (end < start + sb.buffer.size) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: invalid float", + if (end < start + sb.buffer.len) { + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: invalid float", self->filename, self->lineno, self->colno); - goto cleanup; } value = TomlValue_new_float(n); } else if (type == 't') { - value = toml_parse_datetime(StringBuilder_getStr(&sb)); + try_void(toml_parse_datetime(StringBuilder_getStr(&sb), &value)); } -cleanup: - StringBuilder_destroy(&sb); - return value; + *out_value = value; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_key_value.c b/src/toml_parse/toml_parse_key_value.c index b6bec7a..d9b4237 100644 --- a/src/toml_parse/toml_parse_key_value.c +++ b/src/toml_parse/toml_parse_key_value.c @@ -4,8 +4,10 @@ #include "toml_internal.h" -Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table) +Result(void) toml_parse_key_value(TomlParser* self, TomlTable* target_table) { + Deferral(1); + while (self->ptr < self->end) { char ch; @@ -19,19 +21,13 @@ Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table) str key; if (isalnum(ch) || ch == '_') { - key = toml_parse_bare_key(self); - if (key.data == NULL) - return toml_err()->code; + try_void(toml_parse_bare_key(self, &key)); } else if (ch == '\"') { toml_move_next(self); - key = toml_parse_basic_string(self); - if (key.data == NULL) - return toml_err()->code; + try_void(toml_parse_basic_string(self, &key)); } else if (ch == '\'') { toml_move_next(self); - key = toml_parse_literal_string(self); - if (key.data == NULL) - return toml_err()->code; + try_void(toml_parse_literal_string(self, &key)); } else if (ch == '[') { break; } else if (ch == '#') { @@ -42,7 +38,8 @@ Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table) toml_move_next(self); continue; } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unexpected token", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unexpected token", self->filename, self->lineno, self->colno); } @@ -53,12 +50,14 @@ Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table) } if (self->ptr == self->end) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated key value pair", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated key value pair", self->filename, self->lineno, self->colno); } if (ch != '=') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unexpected token", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unexpected token", self->filename, self->lineno, self->colno); } @@ -71,15 +70,15 @@ Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table) } if (self->ptr == self->end) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated key value pair", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated key value pair", self->filename, self->lineno, self->colno); } - TomlValue value = toml_parse_value(self); - if (value.type == TLIBTOML_INVALID_TYPE) - return toml_err()->code; + TomlValue value; + try_void(toml_parse_value(self, &value)); - TomlTable_set(table, key, value); + TomlTable_set(target_table, key, value); str_destroy(key); while (self->ptr < self->end && (*self->ptr == ' ' ||* self->ptr == '\t')) { @@ -102,10 +101,11 @@ Result(void) toml_parse_key_value(TomlParser* self, TomlTable* table) if (*self->ptr == '\n') { toml_move_next(self); } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: new line expected", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: new line expected", self->filename, self->lineno, self->colno); } } - return TLIBTOML_OK; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_literal_string.c b/src/toml_parse/toml_parse_literal_string.c index de7cd0b..bf1f940 100644 --- a/src/toml_parse/toml_parse_literal_string.c +++ b/src/toml_parse/toml_parse_literal_string.c @@ -4,9 +4,9 @@ #include "toml_internal.h" -Result(str*) toml_parse_literal_string(TomlParser* self) +Result(void) toml_parse_literal_string(TomlParser* self, str* out_str) { - Deferral(4); + Deferral(1); StringBuilder sb = StringBuilder_alloc(32); bool success = false; Defer(if(!success) StringBuilder_destroy(&sb)); @@ -17,12 +17,14 @@ Result(str*) toml_parse_literal_string(TomlParser* self) } if (self->ptr >= self->end ||* self->ptr != '\'' ||* self->ptr == '\n') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated literal string", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated literal string", self->filename, self->lineno, self->colno); } toml_move_next(self); + *out_str = StringBuilder_getStr(&sb); success = true; - return StringBuilder_getStr(&sb); + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_literal_string_value.c b/src/toml_parse/toml_parse_literal_string_value.c index 5ba9d77..34b31cb 100644 --- a/src/toml_parse/toml_parse_literal_string_value.c +++ b/src/toml_parse/toml_parse_literal_string_value.c @@ -4,13 +4,13 @@ #include "toml_internal.h" -TomlValue toml_parse_literal_string_value(TomlParser* self) +Result(void) toml_parse_literal_string_value(TomlParser* self, TomlValue* out_value) { - str s = toml_parse_literal_string(self); - //TODO: error handling - assert(s.data != NULL); + Deferral(1); + + str s; + try_void(toml_parse_literal_string(self, &s)); + *out_value = TomlValue_move_str(s); - TomlValue value = TomlValue_new(TLIBTOML_STRING); - value.value.s = s; - return value; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_multi_line_basic_string.c b/src/toml_parse/toml_parse_multi_line_basic_string.c index ca1b972..8f98b69 100644 --- a/src/toml_parse/toml_parse_multi_line_basic_string.c +++ b/src/toml_parse/toml_parse_multi_line_basic_string.c @@ -4,9 +4,9 @@ #include "toml_internal.h" -TomlValue toml_parse_multi_line_basic_string(TomlParser* self) +Result(void) toml_parse_multi_line_basic_string(TomlParser* self, TomlValue* out_value) { - Deferral(4); + Deferral(1); StringBuilder sb = StringBuilder_alloc(32); bool success = false; Defer(if(!success) StringBuilder_destroy(&sb)); @@ -75,7 +75,7 @@ TomlValue toml_parse_multi_line_basic_string(TomlParser* self) toml_next_n(self, 3); - TomlValue value = TomlValue_new(TLIBTOML_STRING); - value.value.s = StringBuilder_getStr(&sb); - return value; + *out_value = TomlValue_move_str(StringBuilder_getStr(&sb)); + success = true; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_multi_line_literal_string.c b/src/toml_parse/toml_parse_multi_line_literal_string.c index aef4be0..47702f0 100644 --- a/src/toml_parse/toml_parse_multi_line_literal_string.c +++ b/src/toml_parse/toml_parse_multi_line_literal_string.c @@ -4,9 +4,12 @@ #include "toml_internal.h" -TomlValue toml_parse_multi_line_literal_string(TomlParser* self) +Result(void) toml_parse_multi_line_literal_string(TomlParser* self, TomlValue* out_value) { + Deferral(1); StringBuilder sb = StringBuilder_alloc(32); + bool success = false; + Defer(if(!success) StringBuilder_destroy(&sb)); if (*self->ptr == '\n') { toml_move_next(self); @@ -18,16 +21,14 @@ TomlValue toml_parse_multi_line_literal_string(TomlParser* self) } if (self->ptr + 3 > self->end || strncmp(self->ptr, "\'\'\'", 3) != 0) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unterminated multi-line literal string", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unterminated multi-line literal string", self->filename, self->lineno, self->colno); - StringBuilder_destroy(&sb); - //TODO: error handling - assert(false && "TODO error handling"); } toml_next_n(self, 3); - TomlValue value = TomlValue_new(TLIBTOML_STRING); - value.value.s = StringBuilder_getStr(&sb); - return value; + *out_value = TomlValue_move_str(StringBuilder_getStr(&sb)); + success = true; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_table.c b/src/toml_parse/toml_parse_table.c index 5ba33d5..edae4fe 100644 --- a/src/toml_parse/toml_parse_table.c +++ b/src/toml_parse/toml_parse_table.c @@ -4,12 +4,12 @@ #include "toml_internal.h" -Result(void) toml_parse_table(TomlParser* self, TomlTable* table) +Result(void) toml_parse_table(TomlParser* self, TomlTable* target_table) { - Deferral(16); + Deferral(1); i32 is_array = false; - TomlTable* real_table = table; + TomlTable* real_table = target_table; TomlArray* key_path = TomlArray_new(); Defer(TomlArray_free(key_path)); @@ -36,28 +36,20 @@ Result(void) toml_parse_table(TomlParser* self, TomlTable* table) } else { str key_part; if (isalnum(*self->ptr) ||* self->ptr == '_') { - key_part = toml_parse_bare_key(self); - if (key_part.data == NULL) - goto cleanup; + try_void(toml_parse_bare_key(self, &key_part)); } else if (*self->ptr == '\"') { toml_move_next(self); - key_part = toml_parse_basic_string(self); - if (key_part.data == NULL) - goto cleanup; + try_void(toml_parse_basic_string(self, &key_part)); } else if (*self->ptr == '\'') { toml_move_next(self); - key_part = toml_parse_literal_string(self); - if (key_part.data == NULL) - goto cleanup; + try_void(toml_parse_literal_string(self, &key_part)); } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unexpected token", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unexpected token", self->filename, self->lineno, self->colno); - goto cleanup; } - TomlValue key_part_value = TomlValue_new(TLIBTOML_STRING); - key_part_value.value.s = key_part; - + TomlValue key_part_value = TomlValue_move_str(key_part); TomlArray_append(key_path, key_part_value); while (self->ptr < self->end && @@ -72,9 +64,9 @@ Result(void) toml_parse_table(TomlParser* self, TomlTable* table) } if (key_path->len == 0) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: empty table name", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: empty table name", self->filename, self->lineno, self->colno); - goto cleanup; } while (self->ptr < self->end && @@ -83,17 +75,13 @@ Result(void) toml_parse_table(TomlParser* self, TomlTable* table) } if (self->ptr < self->end &&* self->ptr != '\n') { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: new line expected", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: new line expected", self->filename, self->lineno, self->colno); - goto cleanup; } - real_table = toml_walk_table_path(self, table, key_path, is_array, true); - if (real_table == NULL) - goto error; - - if(toml_parse_key_value(self, real_table) != TLIBTOML_OK) - goto error; + try(real_table, p, toml_walk_table_path(self, target_table, key_path, is_array, true)); + try_void(toml_parse_key_value(self, real_table)); Return RESULT_VOID; } diff --git a/src/toml_parse/toml_parse_value.c b/src/toml_parse/toml_parse_value.c index 96df99a..24f5925 100644 --- a/src/toml_parse/toml_parse_value.c +++ b/src/toml_parse/toml_parse_value.c @@ -4,39 +4,41 @@ #include "toml_internal.h" -TomlValue toml_parse_value(TomlParser* self) +Result(void) toml_parse_value(TomlParser* self, TomlValue* out_value) { + Deferral(1); + char ch = *self->ptr; TomlValue value; if (strncmp(self->ptr, "\"\"\"", 3) == 0) { toml_next_n(self, 3); - value = toml_parse_multi_line_basic_string(self); + try_void(toml_parse_multi_line_basic_string(self, &value)); } else if (strncmp(self->ptr, "\'\'\'", 3) == 0) { toml_next_n(self, 3); - value = toml_parse_multi_line_literal_string(self); + try_void(toml_parse_multi_line_literal_string(self, &value)); } else if (ch == '\"') { toml_move_next(self); - value = toml_parse_basic_string_value(self); + try_void(toml_parse_basic_string_value(self, &value)); } else if (ch == '\'') { toml_move_next(self); - value = toml_parse_literal_string_value(self); + try_void(toml_parse_literal_string_value(self, &value)); } else if (isdigit(ch) || ch == '+' || ch == '-' || ch == '.' || ch == 'n' || ch == 'i') { - value = toml_parse_int_or_float_or_time(self); + try_void(toml_parse_int_or_float_or_time(self, &value)); } else if (ch == 't' || ch == 'f') { - value = toml_parse_bool(self); + try_void(toml_parse_bool(self, &value)); } else if (ch == '[') { toml_move_next(self); - value = toml_parse_array(self); + try_void(toml_parse_array(self, &value)); } else if (ch == '{') { toml_move_next(self); - value = toml_parse_inline_table(self); + try_void(toml_parse_inline_table(self, &value)); } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: unexpected token", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: unexpected token", self->filename, self->lineno, self->colno); - //TODO: error handling - assert(false && "TODO error handling"); } - return value; + *out_value = value; + Return RESULT_VOID; } diff --git a/src/toml_parse/toml_walk_table_path.c b/src/toml_parse/toml_walk_table_path.c index 525dadb..1904457 100644 --- a/src/toml_parse/toml_walk_table_path.c +++ b/src/toml_parse/toml_walk_table_path.c @@ -5,15 +5,16 @@ #include "toml_internal.h" -TomlTable* toml_walk_table_path(TomlParser* parser, TomlTable* table, - TomlArray* key_path, i32 is_array, i32 create_if_not_exist) +Result(Table*) toml_walk_table_path(TomlParser* parser, TomlTable* table, + TomlArray* key_path, bool is_array, bool create_if_not_exist) { + Deferral(1); TomlTable* real_table = table; if (is_array) { u64 i = 0; for (; i < key_path->len - 1; i++) { - str part = key_path->elements[i].value.s; + str part = *key_path->elements[i].value.s; TomlValue* t = TomlTable_get(real_table, part); if (t == NULL) { if (create_if_not_exist) { @@ -21,15 +22,16 @@ TomlTable* toml_walk_table_path(TomlParser* parser, TomlTable* table, TomlTable_set(real_table, part, new_table_value); real_table = new_table_value.value.table; } else { - real_table = NULL; - break; + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: not found key '" FMT_str "'", + parser->filename, parser->lineno, parser->colno, part.len, part.data); } } else { real_table = t->value.table; } } - str part = key_path->elements[i].value.s; + str part = *key_path->elements[i].value.s; TomlValue* t = TomlTable_get(real_table, part); if (t == NULL) { if (create_if_not_exist) { @@ -39,13 +41,15 @@ TomlTable* toml_walk_table_path(TomlParser* parser, TomlTable* table, TomlTable_set(real_table, part, array_value); real_table = new_table_value.value.table; } else { - real_table = NULL; + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: not found key '" FMT_str "'", + parser->filename, parser->lineno, parser->colno, part.len, part.data); } } else { if (t->type != TLIBTOML_ARRAY) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, "%s:%d:%d: this key was not an array", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: this key was not an array", parser->filename, parser->lineno, parser->colno); - goto error; } TomlValue new_table_value = TomlValue_new_table(); @@ -54,7 +58,7 @@ TomlTable* toml_walk_table_path(TomlParser* parser, TomlTable* table, } } else { for (u64 i = 0; i < key_path->len; i++) { - str part = key_path->elements[i].value.s; + str part = *key_path->elements[i].value.s; TomlValue* t = TomlTable_get(real_table, part); if (t == NULL) { if (create_if_not_exist) { @@ -62,8 +66,9 @@ TomlTable* toml_walk_table_path(TomlParser* parser, TomlTable* table, TomlTable_set(real_table, part, new_table_value); real_table = new_table_value.value.table; } else { - real_table = NULL; - break; + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, + "%s:%d:%d: not found key '" FMT_str "'", + parser->filename, parser->lineno, parser->colno, part.len, part.data); } } else { if (t->type == TLIBTOML_ARRAY) { @@ -75,13 +80,5 @@ TomlTable* toml_walk_table_path(TomlParser* parser, TomlTable* table, } } - goto end; - -error: - real_table = NULL; - //TODO: error handling - assert(false && "TODO error handling"); - -end: - return real_table; + Return RESULT_VALUE(p, real_table); } diff --git a/src/toml_parser.c b/src/toml_parser.c index cd44d18..e3f991a 100644 --- a/src/toml_parser.c +++ b/src/toml_parser.c @@ -8,7 +8,7 @@ TomlParser* toml_parser_new(str s, cstr filename) { TomlParser* parser = malloc(sizeof(TomlParser)); parser->begin = s.data; - parser->end = s.data + s.size; + parser->end = s.data + s.len; parser->ptr = s.data; parser->lineno = 1; parser->colno = 1; @@ -45,25 +45,7 @@ void toml_next_n(TomlParser* self, i32 n) } } -str toml_parse_bare_key(TomlParser* self) -{ - cstr s = self->ptr; - u64 len = 0; - - while (self->ptr < self->end) { - char ch = *self->ptr; - - if (!(isalnum(ch) || ch == '_' || ch == '-')) - break; - - len++; - toml_move_next(self); - } - - return str_copy(str_construct((void*)s, len, false)); -} - -char toml_hex_char_to_int(char ch) +u32 toml_hex_char_to_int(char ch) { assert(isxdigit(ch)); if (isdigit(ch)) { @@ -78,7 +60,7 @@ char toml_hex_char_to_int(char ch) Result(void) toml_encode_unicode_scalar(StringBuilder* sb_ptr, TomlParser* parser, i32 n) { - Deferral(16); + Deferral(1); u32 scalar = 0; if (parser->ptr + n > parser->end) { @@ -90,10 +72,11 @@ Result(void) toml_encode_unicode_scalar(StringBuilder* sb_ptr, TomlParser* parse for (i32 i = 0; i < n; i++) { char ch = *parser->ptr; if (isxdigit(ch)) { - scalar = scalar * 16 + (u32)toml_hex_char_to_int(ch); + scalar = scalar * 16 + toml_hex_char_to_int(ch); toml_move_next(parser); } else { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_UNICODE, "%s:%d:%d: invalid unicode scalar", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_UNICODE, + "%s:%d:%d: invalid unicode scalar", parser->filename, parser->lineno, parser->colno); } } @@ -101,7 +84,8 @@ Result(void) toml_encode_unicode_scalar(StringBuilder* sb_ptr, TomlParser* parse if ((scalar >= 0xd800 && scalar <= 0xdfff) || (scalar >= 0xfffe && scalar <= 0xffff)) { - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_UNICODE, "%s:%d:%d: invalid unicode scalar", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_UNICODE, + "%s:%d:%d: invalid unicode scalar", parser->filename, parser->lineno, parser->colno); } @@ -150,6 +134,7 @@ Result(void) toml_encode_unicode_scalar(StringBuilder* sb_ptr, TomlParser* parse Return RESULT_VOID; } - Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_UNICODE, "%s:%d:%d: invalid unicode scalar", + Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_UNICODE, + "%s:%d:%d: invalid unicode scalar", parser->filename, parser->lineno, parser->colno); } diff --git a/tests/main.c b/tests/main.c index ade4c94..05bb58b 100644 --- a/tests/main.c +++ b/tests/main.c @@ -4,7 +4,7 @@ #include #include -#include "tlibtoml/toml.h" +#include "tlibtoml.h" #ifndef PROJECT_SOURCE_DIR #define PROJECT_SOURCE_DIR ".." @@ -38,7 +38,7 @@ void print_value(const TomlValue* value) print_array(value->value.array); break; case TLIBTOML_STRING: - printf("\"%s\"", value->value.s.data); + printf("'" FMT_str "'", value->value.s->len, value->value.s->data); break; case TLIBTOML_INTEGER: printf("%" PRId64, value->value.i); @@ -80,14 +80,12 @@ void print_table(const TomlTable* table) Result(void) test_run(cstr filename) { - Deferral(4); + Deferral(1); try(TomlTable* table, p, toml_load_filename(filename)); Defer(TomlTable_free(table)); print_table(table); printf("\n"); - -cleanup: - ; + Return RESULT_VOID; } i32 main(void) @@ -95,6 +93,8 @@ i32 main(void) Deferral(32); try_fatal_void(tlibc_init()); Defer(tlibc_deinit()); + try_fatal_void(tlibtoml_init()); + Defer(tlibtoml_deinit()); static cstr const filenames[] = { /* should parse */ @@ -131,5 +131,5 @@ i32 main(void) printf("total %d tests, %d passed, %d failed\n", total_tests, num_passed, num_failed); - return num_failed; + Return num_failed; }