Compare commits

..

11 Commits

12 changed files with 152 additions and 109 deletions

View File

@@ -1,5 +1,5 @@
# tlibtoml # 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. A fork of [libtoml](https://github.com/brglng/libtoml) rewritten to use [tlibc](https://timerix.ddns.net/git/Timerix/tlibc) 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 ## Build
@@ -8,7 +8,9 @@ A fork of [libtoml](https://github.com/brglng/libtoml) rewritten to use [tlibc](
git clone https://timerix.ddns.net/git/Timerix/tlibtoml.git git clone https://timerix.ddns.net/git/Timerix/tlibtoml.git
``` ```
2. Install [cbuild](https://timerix.ddns.net/git/Timerix/cbuild) version specified in `project.config`. 2. Install [cbuild](https://timerix.ddns.net/git/Timerix/cbuild/releases).
Select latest version compatible with the one in `project.config`.
Example: For `2.3.0` download latest `2.3.x`.
3. Clone [tlibc](https://timerix.ddns.net/git/Timerix/tlibc). 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/`. By default `dependencies/tlibc.config` expects that `tlibc/` is present in the same directory as `tlibtoml/`.
@@ -25,6 +27,8 @@ A fork of [libtoml](https://github.com/brglng/libtoml) rewritten to use [tlibc](
5. To build library use tasks `build_static_lib[_dbg]` or `build_shared_lib[_dbg]` 5. To build library use tasks `build_static_lib[_dbg]` or `build_shared_lib[_dbg]`
6. If you use tlibtoml as static library, add `LINKER_LIBS` from tlibtoml `project.config` to your project.
## Usage ## Usage
```c ```c
@@ -32,11 +36,20 @@ A fork of [libtoml](https://github.com/brglng/libtoml) rewritten to use [tlibc](
int main(){ int main(){
Deferral(32); // reserve memory for 32 defers Deferral(32); // reserve memory for 32 defers
// init tlibc global variables
try_fatal_void(tlibc_init()); try_fatal_void(tlibc_init());
// init tlibtoml global variables
try_fatal_void(tlibtoml_init()); try_fatal_void(tlibtoml_init());
Defer(tlibc_deinit()); Defer(tlibc_deinit());
Defer(tlibtoml_deinit()); Defer(tlibtoml_deinit());
// load whole file to memory and parse it as toml
try_fatal(TomlTable* t, p, toml_load_filename("example.toml"));
// get value by key and ensure it's a string
try_fatal(str* s, p, TomlTable_get_str(t, STR("some_key")));
// print this string value
printf("some_key = '"FMT_str"'\n", str_unwrap(*s));
Return 0; // call defers Return 0; // call defers
} }
``` ```

View File

@@ -27,11 +27,10 @@ void tlibtoml_deinit();
typedef enum TlibtomlError { typedef enum TlibtomlError {
TLIBTOML_OK, TLIBTOML_OK,
TLIBTOML_ERR,
TLIBTOML_ERR_OS,
TLIBTOML_ERR_NOMEM,
TLIBTOML_ERR_SYNTAX, TLIBTOML_ERR_SYNTAX,
TLIBTOML_ERR_UNICODE TLIBTOML_ERR_UNICODE,
TLIBTOML_ERR_NOT_FOUND,
TLIBTOML_ERR_UNEXPECTED_TYPE,
} TlibtomlError; } TlibtomlError;
ErrorCodePage_declare(TLIBTOML); ErrorCodePage_declare(TLIBTOML);
@@ -49,10 +48,25 @@ typedef List(TomlValue) TomlArray;
// // // //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
Result(TomlTable*) toml_load_str(str s); /// opens file
Result(TomlTable*) toml_load_file(FILE* file);
Result(TomlTable*) toml_load_filename(cstr filename); Result(TomlTable*) toml_load_filename(cstr filename);
/// @param filename to use in error messages
Result(TomlTable*) toml_load_str_filename(str s, cstr filename);
/// loads whole file in memory
/// @param filename to use in error messages
Result(TomlTable*) toml_load_file_filename(FILE* file, cstr filename);
static inline Result(TomlTable*) toml_load_str(str s){
return toml_load_str_filename(s, "<string>");
}
static inline Result(TomlTable*) toml_load_file(FILE* file){
return toml_load_file_filename(file, "<stream>");
}
/* TODO: implement dump functions /* TODO: implement dump functions
str toml_dump_str(const TomlTable* self, TomlErr *err); str toml_dump_str(const TomlTable* self, TomlErr *err);
void toml_dump_file(const TomlTable* self, FILE* file, TomlErr *err); void toml_dump_file(const TomlTable* self, FILE* file, TomlErr *err);
@@ -76,6 +90,8 @@ typedef enum TomlType {
TLIBTOML_BOOLEAN, TLIBTOML_BOOLEAN,
} TomlType; } TomlType;
str TomlType_toStr(TomlType t);
typedef struct TomlValue { typedef struct TomlValue {
TomlType type; TomlType type;
union { union {
@@ -86,7 +102,7 @@ typedef struct TomlValue {
TomlArray* array; TomlArray* array;
TomlTable* table; TomlTable* table;
TomlDateTime* dt; TomlDateTime* dt;
} value; };
} TomlValue; } TomlValue;
List_declare(TomlValue); List_declare(TomlValue);

View File

@@ -45,8 +45,7 @@ case "$OS" in
EXEC_FILE="test.exe" EXEC_FILE="test.exe"
SHARED_LIB_FILE="$PROJECT.dll" SHARED_LIB_FILE="$PROJECT.dll"
INCLUDE="$INCLUDE " INCLUDE="$INCLUDE "
# example: "-lSDL2 -lSDL2_image" LINKER_LIBS="-luuid"
LINKER_LIBS=""
;; ;;
LINUX) LINUX)
EXEC_FILE="test" EXEC_FILE="test"

View File

@@ -15,6 +15,6 @@ void TomlArray_free(TomlArray* self)
{ {
if(!self) if(!self)
return; return;
List_TomlValue_destroy(self); List_TomlValue_destroyWithElements(self, TomlValue_destroy);
free(self); free(self);
} }

View File

@@ -19,65 +19,84 @@ void TomlTable_free(TomlTable* self)
free(self); free(self);
} }
#define try_assert_value_found(VAL, KEY) \
if(VAL == NULL){ \
Return RESULT_ERROR_CODE_FMT( \
TLIBTOML, TLIBTOML_ERR_NOT_FOUND, \
"can't find '"FMT_str"'", \
str_unwrap(KEY)); \
} \
#define try_assert_value_type(VAL, KEY, TYPE) \
if((VAL)->type != TYPE){ \
str t_expected_s = TomlType_toStr(TYPE); \
str t_got_s = TomlType_toStr((VAL)->type); \
Return RESULT_ERROR_CODE_FMT( \
TLIBTOML, TLIBTOML_ERR_UNEXPECTED_TYPE, \
"expected '"FMT_str"' of type '"FMT_str"', but got '"FMT_str"'", \
str_unwrap(KEY), str_unwrap(t_expected_s), str_unwrap(t_got_s)); \
} \
Result(TomlTable*) TomlTable_get_table(const TomlTable* self, str key) Result(TomlTable*) TomlTable_get_table(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_TABLE); try_assert_value_type(v, key, TLIBTOML_TABLE);
Return RESULT_VALUE(p, v->value.table); Return RESULT_VALUE(p, v->table);
} }
Result(TomlArray*) TomlTable_get_array(const TomlTable* self, str key) Result(TomlArray*) TomlTable_get_array(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_ARRAY); try_assert_value_type(v, key, TLIBTOML_ARRAY);
Return RESULT_VALUE(p, v->value.array); Return RESULT_VALUE(p, v->array);
} }
Result(str*) TomlTable_get_str(const TomlTable* self, str key) Result(str*) TomlTable_get_str(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_STRING); try_assert_value_type(v, key, TLIBTOML_STRING);
Return RESULT_VALUE(p, v->value.s); Return RESULT_VALUE(p, v->s);
} }
Result(i64) TomlTable_get_integer(const TomlTable* self, str key) Result(i64) TomlTable_get_integer(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_INTEGER); try_assert_value_type(v, key, TLIBTOML_INTEGER);
Return RESULT_VALUE(i, v->value.i); Return RESULT_VALUE(i, v->i);
} }
Result(f64) TomlTable_get_float(const TomlTable* self, str key) Result(f64) TomlTable_get_float(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_FLOAT); try_assert_value_type(v, key, TLIBTOML_FLOAT);
Return RESULT_VALUE(f, v->value.f); Return RESULT_VALUE(f, v->f);
} }
Result(TomlDateTime*) TomlTable_get_datetime(const TomlTable* self, str key) Result(TomlDateTime*) TomlTable_get_datetime(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_DATETIME); try_assert_value_type(v, key, TLIBTOML_DATETIME);
Return RESULT_VALUE(p, v->value.dt); Return RESULT_VALUE(p, v->dt);
} }
Result(bool) TomlTable_get_bool(const TomlTable* self, str key) Result(bool) TomlTable_get_bool(const TomlTable* self, str key)
{ {
Deferral(1); Deferral(1);
TomlValue* v = TomlTable_get(self, key); TomlValue* v = TomlTable_get(self, key);
try_assert(v != NULL); try_assert_value_found(v, key);
try_assert(v->type == TLIBTOML_BOOLEAN); try_assert_value_type(v, key, TLIBTOML_BOOLEAN);
Return RESULT_VALUE(i, v->value.b); Return RESULT_VALUE(i, v->b);
} }

View File

@@ -4,6 +4,25 @@
#include "toml_internal.h" #include "toml_internal.h"
Array_declare(str);
static Array(str) _TomlType_str_array = ARRAY(str, {
STR("INVALID_TYPE"),
STR("TABLE"),
STR("ARRAY"),
STR("STRING"),
STR("INTEGER"),
STR("FLOAT"),
STR("DATETIME"),
STR("BOOLEAN"),
});
str TomlType_toStr(TomlType t){
if((u32)t >= _TomlType_str_array.len)
return STR("!! ERROR: INVALID TomlType !!");
return _TomlType_str_array.data[t];
}
TomlValue TomlValue_new(TomlType type) TomlValue TomlValue_new(TomlType type)
{ {
TomlValue value = {0}; TomlValue value = {0};
@@ -13,26 +32,26 @@ TomlValue TomlValue_new(TomlType type)
assert(false && "invalid type"); assert(false && "invalid type");
break; break;
case TLIBTOML_TABLE: case TLIBTOML_TABLE:
value.value.table = NULL; value.table = NULL;
break; break;
case TLIBTOML_ARRAY: case TLIBTOML_ARRAY:
value.value.array = NULL; value.array = NULL;
break; break;
case TLIBTOML_STRING: case TLIBTOML_STRING:
value.value.s = NULL; value.s = NULL;
break; break;
case TLIBTOML_INTEGER: case TLIBTOML_INTEGER:
value.value.i = 0; value.i = 0;
break; break;
case TLIBTOML_FLOAT: case TLIBTOML_FLOAT:
value.value.f = 0.0; value.f = 0.0;
break; break;
case TLIBTOML_BOOLEAN: case TLIBTOML_BOOLEAN:
value.value.b = false; value.b = false;
break; break;
case TLIBTOML_DATETIME: case TLIBTOML_DATETIME:
value.value.dt = (TomlDateTime*)malloc(sizeof(TomlDateTime)); value.dt = (TomlDateTime*)malloc(sizeof(TomlDateTime));
memset(value.value.dt, 0, sizeof(TomlDateTime)); memset(value.dt, 0, sizeof(TomlDateTime));
break; break;
} }
return value; return value;
@@ -45,8 +64,8 @@ TomlValue TomlValue_copy_str(str s)
TomlValue TomlValue_move_str(str s){ TomlValue TomlValue_move_str(str s){
TomlValue value = {0}; TomlValue value = {0};
value.value.s = (str*)malloc(sizeof(str)); value.s = (str*)malloc(sizeof(str));
*value.value.s = s; *value.s = s;
value.type = TLIBTOML_STRING; value.type = TLIBTOML_STRING;
return value; return value;
} }
@@ -54,7 +73,7 @@ TomlValue TomlValue_move_str(str s){
TomlValue TomlValue_new_table(void) TomlValue TomlValue_new_table(void)
{ {
TomlValue value = {0}; TomlValue value = {0};
value.value.table = TomlTable_new(); value.table = TomlTable_new();
value.type = TLIBTOML_TABLE; value.type = TLIBTOML_TABLE;
return value; return value;
} }
@@ -62,7 +81,7 @@ TomlValue TomlValue_new_table(void)
TomlValue TomlValue_new_array(void) TomlValue TomlValue_new_array(void)
{ {
TomlValue value = {0}; TomlValue value = {0};
value.value.array = TomlArray_new(); value.array = TomlArray_new();
value.type = TLIBTOML_ARRAY; value.type = TLIBTOML_ARRAY;
return value; return value;
} }
@@ -70,7 +89,7 @@ TomlValue TomlValue_new_array(void)
TomlValue TomlValue_new_integer(i64 integer) TomlValue TomlValue_new_integer(i64 integer)
{ {
TomlValue value = {0}; TomlValue value = {0};
value.value.i = integer; value.i = integer;
value.type = TLIBTOML_INTEGER; value.type = TLIBTOML_INTEGER;
return value; return value;
} }
@@ -78,7 +97,7 @@ TomlValue TomlValue_new_integer(i64 integer)
TomlValue TomlValue_new_float(f64 float_) TomlValue TomlValue_new_float(f64 float_)
{ {
TomlValue value = {0}; TomlValue value = {0};
value.value.f = float_; value.f = float_;
value.type = TLIBTOML_FLOAT; value.type = TLIBTOML_FLOAT;
return value; return value;
} }
@@ -91,7 +110,7 @@ TomlValue TomlValue_new_datetime(void)
TomlValue TomlValue_new_bool(bool b) TomlValue TomlValue_new_bool(bool b)
{ {
TomlValue value = {0}; TomlValue value = {0};
value.value.b = b; value.b = b;
value.type = TLIBTOML_BOOLEAN; value.type = TLIBTOML_BOOLEAN;
return value; return value;
} }
@@ -103,16 +122,16 @@ void TomlValue_destroy(TomlValue* self)
switch (self->type) { switch (self->type) {
case TLIBTOML_STRING: case TLIBTOML_STRING:
str_free(self->value.s); str_free(self->s);
break; break;
case TLIBTOML_TABLE: case TLIBTOML_TABLE:
TomlTable_free(self->value.table); TomlTable_free(self->table);
break; break;
case TLIBTOML_ARRAY: case TLIBTOML_ARRAY:
TomlArray_free(self->value.array); TomlArray_free(self->array);
break; break;
case TLIBTOML_DATETIME: case TLIBTOML_DATETIME:
free(self->value.dt); free(self->dt);
break; break;
default: default:
break; break;

View File

@@ -19,49 +19,23 @@ Result(TomlTable*) toml_load_str_filename(str s, cstr filename)
Result(TomlTable*) toml_load_file_filename(FILE* file, cstr filename) Result(TomlTable*) toml_load_file_filename(FILE* file, cstr filename)
{ {
Deferral(4); Deferral(1);
const u32 file_chunk_size = 8*1024; str file_content;
StringBuilder sb = StringBuilder_alloc(file_chunk_size); try_void(file_readWholeText(file, &file_content));
Defer(StringBuilder_destroy(&sb)); Defer(str_destroy(file_content));
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; try(TomlTable* table, p, toml_load_str_filename(file_content, filename));
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); Return RESULT_VALUE(p, table);
} }
Result(TomlTable*) toml_load_str(str s)
{
return toml_load_str_filename(s, "<string>");
}
Result(TomlTable*) toml_load_file(FILE* file)
{
return toml_load_file_filename(file, "<stream>");
}
Result(TomlTable*) toml_load_filename(cstr filename) Result(TomlTable*) toml_load_filename(cstr filename)
{ {
Deferral(1); Deferral(1);
try(FILE* f, p, file_open(filename, FO_ReadExisting)); try(FILE* f, p, file_open(filename, FO_ReadExisting));
Defer(file_close(f));
try(TomlTable* table, p, toml_load_file_filename(f, filename)); try(TomlTable* table, p, toml_load_file_filename(f, filename));
Return RESULT_VALUE(p, table); Return RESULT_VALUE(p, table);

View File

@@ -30,7 +30,7 @@ Result(void) toml_parse_array(TomlParser* self, TomlValue* out_value)
TomlValue value; TomlValue value;
try_void(toml_parse_value(self, &value)); try_void(toml_parse_value(self, &value));
TomlArray_append(array_value.value.array, value); TomlArray_append(array_value.array, value);
while (self->ptr < self->end) { while (self->ptr < self->end) {
if (isspace(*self->ptr)) { if (isspace(*self->ptr)) {

View File

@@ -71,7 +71,7 @@ Result(void) toml_parse_inline_table(TomlParser* self, TomlValue* out_value)
TomlValue value; TomlValue value;
try_void(toml_parse_value(self, &value)); try_void(toml_parse_value(self, &value));
TomlTable_set(table_value.value.table, key, value); TomlTable_set(table_value.table, key, value);
str_destroy(key); str_destroy(key);
while (self->ptr < self->end && (*self->ptr == ' ' ||* self->ptr == '\t')) { while (self->ptr < self->end && (*self->ptr == ' ' ||* self->ptr == '\t')) {

View File

@@ -14,32 +14,32 @@ Result(Table*) toml_walk_table_path(TomlParser* parser, TomlTable* table,
if (is_array) { if (is_array) {
u64 i = 0; u64 i = 0;
for (; i < key_path->len - 1; i++) { for (; i < key_path->len - 1; i++) {
str part = *key_path->data[i].value.s; str part = *key_path->data[i].s;
TomlValue* t = TomlTable_get(real_table, part); TomlValue* t = TomlTable_get(real_table, part);
if (t == NULL) { if (t == NULL) {
if (create_if_not_exist) { if (create_if_not_exist) {
TomlValue new_table_value = TomlValue_new_table(); TomlValue new_table_value = TomlValue_new_table();
TomlTable_set(real_table, part, new_table_value); TomlTable_set(real_table, part, new_table_value);
real_table = new_table_value.value.table; real_table = new_table_value.table;
} else { } else {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: not found key '" FMT_str "'", "%s:%d:%d: not found key '" FMT_str "'",
parser->filename, parser->lineno, parser->colno, part.len, part.data); parser->filename, parser->lineno, parser->colno, part.len, part.data);
} }
} else { } else {
real_table = t->value.table; real_table = t->table;
} }
} }
str part = *key_path->data[i].value.s; str part = *key_path->data[i].s;
TomlValue* t = TomlTable_get(real_table, part); TomlValue* t = TomlTable_get(real_table, part);
if (t == NULL) { if (t == NULL) {
if (create_if_not_exist) { if (create_if_not_exist) {
TomlValue array_value = TomlValue_new_array(); TomlValue array_value = TomlValue_new_array();
TomlValue new_table_value = TomlValue_new_table(); TomlValue new_table_value = TomlValue_new_table();
TomlArray_append(array_value.value.array, new_table_value); TomlArray_append(array_value.array, new_table_value);
TomlTable_set(real_table, part, array_value); TomlTable_set(real_table, part, array_value);
real_table = new_table_value.value.table; real_table = new_table_value.table;
} else { } else {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: not found key '" FMT_str "'", "%s:%d:%d: not found key '" FMT_str "'",
@@ -53,18 +53,18 @@ Result(Table*) toml_walk_table_path(TomlParser* parser, TomlTable* table,
} }
TomlValue new_table_value = TomlValue_new_table(); TomlValue new_table_value = TomlValue_new_table();
TomlArray_append(t->value.array, new_table_value); TomlArray_append(t->array, new_table_value);
real_table = new_table_value.value.table; real_table = new_table_value.table;
} }
} else { } else {
for (u64 i = 0; i < key_path->len; i++) { for (u64 i = 0; i < key_path->len; i++) {
str part = *key_path->data[i].value.s; str part = *key_path->data[i].s;
TomlValue* t = TomlTable_get(real_table, part); TomlValue* t = TomlTable_get(real_table, part);
if (t == NULL) { if (t == NULL) {
if (create_if_not_exist) { if (create_if_not_exist) {
TomlValue new_table_value = TomlValue_new_table(); TomlValue new_table_value = TomlValue_new_table();
TomlTable_set(real_table, part, new_table_value); TomlTable_set(real_table, part, new_table_value);
real_table = new_table_value.value.table; real_table = new_table_value.table;
} else { } else {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX, Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: not found key '" FMT_str "'", "%s:%d:%d: not found key '" FMT_str "'",
@@ -72,9 +72,9 @@ Result(Table*) toml_walk_table_path(TomlParser* parser, TomlTable* table,
} }
} else { } else {
if (t->type == TLIBTOML_ARRAY) { if (t->type == TLIBTOML_ARRAY) {
real_table = t->value.array->data[t->value.array->len - 1].value.table; real_table = t->array->data[t->array->len - 1].table;
} else if (t->type == TLIBTOML_TABLE) { } else if (t->type == TLIBTOML_TABLE) {
real_table = t->value.table; real_table = t->table;
} }
} }
} }

View File

@@ -32,25 +32,25 @@ void print_value(const TomlValue* value)
assert(false && "invalid type"); assert(false && "invalid type");
break; break;
case TLIBTOML_TABLE: case TLIBTOML_TABLE:
print_table(value->value.table); print_table(value->table);
break; break;
case TLIBTOML_ARRAY: case TLIBTOML_ARRAY:
print_array(value->value.array); print_array(value->array);
break; break;
case TLIBTOML_STRING: case TLIBTOML_STRING:
printf("'" FMT_str "'", value->value.s->len, value->value.s->data); printf("'" FMT_str "'", value->s->len, value->s->data);
break; break;
case TLIBTOML_INTEGER: case TLIBTOML_INTEGER:
printf("%" PRId64, value->value.i); printf("%" PRId64, value->i);
break; break;
case TLIBTOML_FLOAT: case TLIBTOML_FLOAT:
printf("%f", value->value.f); printf("%f", value->f);
break; break;
case TLIBTOML_DATETIME: case TLIBTOML_DATETIME:
printf("(datetime)"); printf("(datetime)");
break; break;
case TLIBTOML_BOOLEAN: case TLIBTOML_BOOLEAN:
printf("%s", value->value.b ? "true" : "false"); printf("%s", value->b ? "true" : "false");
break; break;
} }
} }
@@ -58,7 +58,7 @@ void print_value(const TomlValue* value)
void print_keyval(HashMapKeyValue* keyval) void print_keyval(HashMapKeyValue* keyval)
{ {
printf("\"%s\": ", keyval->key.data); printf("\"%s\": ", keyval->key.data);
print_value(keyval->value); print_value(keyval->value_ptr);
} }
void print_table(const TomlTable* table) void print_table(const TomlTable* table)

View File

@@ -5,9 +5,12 @@
DEP_WORKING_DIR="$DEPENDENCIES_DIR/tlibtoml" DEP_WORKING_DIR="$DEPENDENCIES_DIR/tlibtoml"
user_config_path="project.config.user"
absolute_dep_dir=$(realpath "$DEPENDENCIES_DIR")
function setup_user_config(){ function setup_user_config(){
local user_config_path="project.config.user" # Set variable `DEPENDENCIES_DIR`` in `tlibtoml/project.config.user`
local absolute_dep_dir=$(realpath "$DEPENDENCIES_DIR") # to the directory where `tlibc`` is installed
file_copy_default_if_not_present "$user_config_path" "$user_config_path.default" file_copy_default_if_not_present "$user_config_path" "$user_config_path.default"
replace_var_value_in_script "$user_config_path" "DEPENDENCIES_DIR" "$absolute_dep_dir" replace_var_value_in_script "$user_config_path" "DEPENDENCIES_DIR" "$absolute_dep_dir"
} }