From 6a26e00438766d6ef646577569ec540b162908d2 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 20 Apr 2026 22:04:29 +0100 Subject: [PATCH] serial: implement returning fx_result values from (de)serialisers --- serial/bitcode.c | 16 +- serial/ctx.c | 40 +++- serial/include/fx/serial/ctx.h | 28 ++- serial/toml.c | 419 ++++++++++++++++++--------------- 4 files changed, 290 insertions(+), 213 deletions(-) diff --git a/serial/bitcode.c b/serial/bitcode.c index 259a47b..038071d 100644 --- a/serial/bitcode.c +++ b/serial/bitcode.c @@ -3,18 +3,22 @@ /*** VIRTUAL FUNCTIONS ********************************************************/ -static enum fx_status bitcode_serialise( - fx_serial_ctx *serial, fx_object *src, fx_stream *dest, +static struct fx_error *bitcode_serialise( + fx_serial_ctx *serial, + fx_object *src, + fx_stream *dest, enum fx_serial_flags flags) { - return FX_ERR_NOT_SUPPORTED; + return FX_RESULT_ERR(NOT_SUPPORTED); } -static enum fx_status bitcode_deserialise( - fx_serial_ctx *serial, fx_stream *src, fx_object **dest, +static struct fx_error *bitcode_deserialise( + fx_serial_ctx *serial, + fx_stream *src, + fx_object **dest, enum fx_serial_flags flags) { - return FX_ERR_NOT_SUPPORTED; + return FX_RESULT_ERR(NOT_SUPPORTED); } static void bitcode_serial_ctx_init(fx_object *obj, void *priv) diff --git a/serial/ctx.c b/serial/ctx.c index a284ed4..c806227 100644 --- a/serial/ctx.c +++ b/serial/ctx.c @@ -10,14 +10,16 @@ static void serial_ctx_init(fx_object *obj, void *priv) { - fx_serial_ctx_data *data = fx_object_get_protected(obj, FX_TYPE_SERIAL_CTX); + fx_serial_ctx_data *data + = fx_object_get_protected(obj, FX_TYPE_SERIAL_CTX); data->ctx_streambuf = fx_stream_buffer_create_dynamic(2048); } static void serial_ctx_fini(fx_object *obj, void *priv) { - fx_serial_ctx_data *data = fx_object_get_protected(obj, FX_TYPE_SERIAL_CTX); + fx_serial_ctx_data *data + = fx_object_get_protected(obj, FX_TYPE_SERIAL_CTX); fx_stream_buffer_unref(data->ctx_streambuf); } @@ -40,18 +42,36 @@ FX_TYPE_DEFINITION_END(fx_serial_ctx) /*** ITERATOR FUNCTIONS *******************************************************/ -enum fx_status fx_serial_ctx_serialise( - fx_serial_ctx *ctx, fx_object *src, fx_stream *dest, enum fx_serial_flags flags) +fx_result fx_serial_ctx_serialise( + fx_serial_ctx *ctx, + fx_object *src, + fx_stream *dest, + enum fx_serial_flags flags) { FX_CLASS_DISPATCH_VIRTUAL( - fx_serial_ctx, FX_TYPE_SERIAL_CTX, FX_ERR_NOT_SUPPORTED, - s_serialise, ctx, src, dest, flags); + fx_serial_ctx, + FX_TYPE_SERIAL_CTX, + FX_RESULT_ERR(NOT_SUPPORTED), + s_serialise, + ctx, + src, + dest, + flags); } -enum fx_status fx_serial_ctx_deserialise( - fx_serial_ctx *ctx, fx_stream *src, fx_object **dest, enum fx_serial_flags flags) +fx_result fx_serial_ctx_deserialise( + fx_serial_ctx *ctx, + fx_stream *src, + fx_object **dest, + enum fx_serial_flags flags) { FX_CLASS_DISPATCH_VIRTUAL( - fx_serial_ctx, FX_TYPE_SERIAL_CTX, FX_ERR_NOT_SUPPORTED, - s_deserialise, ctx, src, dest, flags); + fx_serial_ctx, + FX_TYPE_SERIAL_CTX, + FX_RESULT_ERR(NOT_SUPPORTED), + s_deserialise, + ctx, + src, + dest, + flags); } diff --git a/serial/include/fx/serial/ctx.h b/serial/include/fx/serial/ctx.h index dd08a25..166d262 100644 --- a/serial/include/fx/serial/ctx.h +++ b/serial/include/fx/serial/ctx.h @@ -19,10 +19,16 @@ typedef enum fx_serial_flags { FX_DECLARE_TYPE(fx_serial_ctx); FX_TYPE_CLASS_DECLARATION_BEGIN(fx_serial_ctx) - fx_status (*s_serialise)( - fx_serial_ctx *, fx_object *, fx_stream *, fx_serial_flags); - fx_status (*s_deserialise)( - fx_serial_ctx *, fx_stream *, fx_object **, fx_serial_flags); + fx_result (*s_serialise)( + fx_serial_ctx *, + fx_object *, + fx_stream *, + fx_serial_flags); + fx_result (*s_deserialise)( + fx_serial_ctx *, + fx_stream *, + fx_object **, + fx_serial_flags); FX_TYPE_CLASS_DECLARATION_END(fx_serial_ctx) typedef struct fx_serial_ctx_data { @@ -31,11 +37,17 @@ typedef struct fx_serial_ctx_data { FX_API fx_type fx_serial_ctx_get_type(void); -FX_API fx_status fx_serial_ctx_serialise( - fx_serial_ctx *ctx, fx_object *src, fx_stream *dest, fx_serial_flags flags); +FX_API fx_result fx_serial_ctx_serialise( + fx_serial_ctx *ctx, + fx_object *src, + fx_stream *dest, + fx_serial_flags flags); -FX_API fx_status fx_serial_ctx_deserialise( - fx_serial_ctx *ctx, fx_stream *src, fx_object **dest, fx_serial_flags flags); +FX_API fx_result fx_serial_ctx_deserialise( + fx_serial_ctx *ctx, + fx_stream *src, + fx_object **dest, + fx_serial_flags flags); FX_DECLS_END; diff --git a/serial/toml.c b/serial/toml.c index 56bb727..479d083 100644 --- a/serial/toml.c +++ b/serial/toml.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -14,21 +15,23 @@ #include #define IS_VALID_KEY_COMPONENT(tok) \ - ((tok) && ((tok)->tok_type == TOK_WORD || (tok)->tok_type == TOK_STRING)) + ((tok) \ + && ((tok)->tok_type == TOK_WORD || (tok)->tok_type == TOK_STRING)) -#define ENABLE_EXTENDED_LEXING(ctx) \ - do { \ - ctx->ctx_flags &= ~CTX_ENABLE_LONG_SYMBOLS; \ - ctx->ctx_flags |= CTX_ENABLE_NUMBERS | CTX_ENABLE_TIMESTAMPS \ - | CTX_ENABLE_BOOLS | CTX_ENABLE_MULTILINE_STRING; \ +#define ENABLE_EXTENDED_LEXING(ctx) \ + do { \ + ctx->ctx_flags &= ~CTX_ENABLE_LONG_SYMBOLS; \ + ctx->ctx_flags |= CTX_ENABLE_NUMBERS | CTX_ENABLE_TIMESTAMPS \ + | CTX_ENABLE_BOOLS \ + | CTX_ENABLE_MULTILINE_STRING; \ } while (0) -#define DISABLE_EXTENDED_LEXING(ctx) \ - do { \ - ctx->ctx_flags |= CTX_ENABLE_LONG_SYMBOLS; \ - ctx->ctx_flags \ - &= ~(CTX_ENABLE_NUMBERS | CTX_ENABLE_TIMESTAMPS \ - | CTX_ENABLE_BOOLS | CTX_ENABLE_MULTILINE_STRING); \ +#define DISABLE_EXTENDED_LEXING(ctx) \ + do { \ + ctx->ctx_flags |= CTX_ENABLE_LONG_SYMBOLS; \ + ctx->ctx_flags &= ~( \ + CTX_ENABLE_NUMBERS | CTX_ENABLE_TIMESTAMPS \ + | CTX_ENABLE_BOOLS | CTX_ENABLE_MULTILINE_STRING); \ } while (0) enum object_flags { @@ -112,14 +115,16 @@ struct ctx { fx_string *ctx_wordbuf; fx_string *ctx_linebuf; fx_iterator *ctx_linebuf_ptr; - enum fx_status ctx_status; + fx_result ctx_result; fx_hashmap *ctx_objects_flags; fx_queue ctx_tokens; }; static void ctx_set_object_flags( - struct ctx *ctx, fx_object *obj, enum object_flags flags) + struct ctx *ctx, + fx_object *obj, + enum object_flags flags) { if (!obj) { return; @@ -150,7 +155,9 @@ static void ctx_set_object_flags( } static void ctx_clear_object_flags( - struct ctx *ctx, fx_object *obj, enum object_flags mask) + struct ctx *ctx, + fx_object *obj, + enum object_flags mask) { if (!obj) { return; @@ -192,7 +199,8 @@ static enum object_flags ctx_get_object_flags(struct ctx *ctx, fx_object *obj) .key_flags = FX_HASHMAP_KEY_F_INTVALUE, }; - const fx_hashmap_value *value = fx_hashmap_get(ctx->ctx_objects_flags, &key); + const fx_hashmap_value *value + = fx_hashmap_get(ctx->ctx_objects_flags, &key); if (value) { return (enum object_flags)(uintptr_t)value->value_data; } @@ -200,7 +208,7 @@ static enum object_flags ctx_get_object_flags(struct ctx *ctx, fx_object *obj) return 0; } -static enum fx_status data_available(struct ctx *ctx) +static fx_status data_available(struct ctx *ctx) { size_t len = fx_string_get_size(ctx->ctx_linebuf, FX_STRLEN_NORMAL); if (len == 0) { @@ -210,7 +218,7 @@ static enum fx_status data_available(struct ctx *ctx) return fx_iterator_get_status(ctx->ctx_linebuf_ptr); } -static enum fx_status refill_linebuf(struct ctx *ctx) +static fx_result refill_linebuf(struct ctx *ctx) { if (ctx->ctx_linebuf_ptr) { fx_iterator_unref(ctx->ctx_linebuf_ptr); @@ -221,21 +229,21 @@ static enum fx_status refill_linebuf(struct ctx *ctx) fx_stringstream *buf = fx_stringstream_create(); - enum fx_status status = fx_stream_read_line_s(ctx->ctx_src, buf); + fx_status status = fx_stream_read_line_s(ctx->ctx_src, buf); if (!FX_OK(status)) { - return status; + return FX_RESULT_STATUS(status); } status = fx_string_replace_all_with_stringstream(ctx->ctx_linebuf, buf); if (!FX_OK(status)) { - return status; + return FX_RESULT_STATUS(status); } fx_stringstream_unref(buf); ctx->ctx_linebuf_ptr = fx_iterator_begin(ctx->ctx_linebuf); - return FX_SUCCESS; + return FX_RESULT_SUCCESS; } static fx_string *get_wordbuf(struct ctx *ctx) @@ -265,28 +273,29 @@ static bool is_valid_char(fx_wchar c) static fx_wchar advance_char(struct ctx *ctx) { - enum fx_status status = data_available(ctx); + fx_status status = data_available(ctx); + fx_result result = FX_RESULT_SUCCESS; if (status == FX_ERR_NO_DATA) { - status = refill_linebuf(ctx); + result = refill_linebuf(ctx); } - if (!FX_OK(status)) { - ctx->ctx_status = status; + if (fx_result_is_error(result)) { + ctx->ctx_result = fx_result_propagate(result); return -1; } status = data_available(ctx); if (!FX_OK(status)) { - ctx->ctx_status = status; + ctx->ctx_result = fx_result_propagate(result); return -1; } - const char *s = fx_string_ptr(ctx->ctx_linebuf); + const char *s = fx_string_get_cstr(ctx->ctx_linebuf); fx_wchar c = fx_iterator_get_value(ctx->ctx_linebuf_ptr).v_int; if (!is_valid_char(c)) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); return -1; } @@ -297,28 +306,29 @@ static fx_wchar advance_char(struct ctx *ctx) static fx_wchar peek_char(struct ctx *ctx) { - enum fx_status status = data_available(ctx); + fx_status status = data_available(ctx); + fx_result result = FX_RESULT_SUCCESS; if (status == FX_ERR_NO_DATA) { - status = refill_linebuf(ctx); + result = refill_linebuf(ctx); } - if (!FX_OK(status)) { - ctx->ctx_status = status; + if (fx_result_is_error(result)) { + ctx->ctx_result = fx_result_propagate(result); return -1; } status = data_available(ctx); if (!FX_OK(status)) { - ctx->ctx_status = status; + ctx->ctx_result = fx_result_propagate(result); return -1; } - const char *s = fx_string_ptr(ctx->ctx_linebuf); + const char *s = fx_string_get_cstr(ctx->ctx_linebuf); fx_wchar c = fx_iterator_get_value(ctx->ctx_linebuf_ptr).v_int; if (!is_valid_char(c)) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); return -1; } @@ -396,7 +406,8 @@ static void discard_token(struct ctx *ctx) static bool try_convert_word_to_timestamp(struct ctx *ctx, fx_string *token_str) { fx_datetime *dt = fx_datetime_parse( - FX_DATETIME_FORMAT_RFC3339, fx_string_ptr(token_str)); + FX_DATETIME_FORMAT_RFC3339, + fx_string_get_cstr(token_str)); if (!dt) { return false; } @@ -411,7 +422,7 @@ static bool try_convert_word_to_timestamp(struct ctx *ctx, fx_string *token_str) #if 0 static bool try_convert_word_to_timestamp(struct ctx *ctx, fx_string *token_str) { - const char *s = fx_string_ptr(token_str); + const char *s = fx_string_get_cstr(token_str); size_t len = fx_string_get_size(token_str, FX_STRLEN_NORMAL); size_t i = 0, c = 0; @@ -618,7 +629,7 @@ static bool try_convert_word_to_number(struct ctx *ctx, fx_string *token_str) size_t len = fx_string_get_size(token_str, FX_STRLEN_NORMAL); fx_string *str = fx_string_duplicate(token_str); struct token *tok = NULL; - const char *s = fx_string_ptr(str); + const char *s = fx_string_get_cstr(str); if (len == 0) { return false; @@ -654,7 +665,9 @@ static bool try_convert_word_to_number(struct ctx *ctx, fx_string *token_str) case 'E': break; case '\0': - tok = enqueue_token(ctx, is_decimal ? TOK_FLOAT : TOK_INT); + tok = enqueue_token( + ctx, + is_decimal ? TOK_FLOAT : TOK_INT); tok->tok_value.i.v = 0; return true; default: @@ -687,7 +700,7 @@ static bool try_convert_word_to_number(struct ctx *ctx, fx_string *token_str) return false; } - size_t to_remove = (s - fx_string_ptr(str)) + i; + size_t to_remove = (s - fx_string_get_cstr(str)) + i; fx_string_remove(str, to_remove, 1); i--; previous = c; @@ -818,7 +831,7 @@ static bool try_convert_word_to_number(struct ctx *ctx, fx_string *token_str) static bool try_convert_word_to_bool(struct ctx *ctx, fx_string *token_str) { - const char *s = fx_string_ptr(token_str); + const char *s = fx_string_get_cstr(token_str); struct token *tok = NULL; if (!strcmp(s, "true")) { @@ -851,14 +864,14 @@ static void split_word(struct ctx *ctx, fx_string *wordbuf) for (long i = 0; i < len; i++) { if (prev == '.' && s[i] == '.') { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); break; } prev = s[i]; } - if (!FX_OK(ctx->ctx_status)) { + if (!FX_OK(ctx->ctx_result)) { free(s); return; } @@ -878,7 +891,7 @@ static void split_word(struct ctx *ctx, fx_string *wordbuf) while (tok) { if (*tok == 0) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); break; } @@ -902,7 +915,10 @@ static void split_word(struct ctx *ctx, fx_string *wordbuf) const char *delims[] = {"."}; size_t nr_delims = sizeof delims / sizeof delims[0]; fx_iterator *it = fx_string_tokenise( - wordbuf, delims, nr_delims, FX_STRING_TOK_F_INCLUDE_EMPTY_TOKENS); + wordbuf, + delims, + nr_delims, + FX_STRING_TOK_F_INCLUDE_EMPTY_TOKENS); size_t i = 0; fx_foreach_c(const char *, tok, it) @@ -931,7 +947,7 @@ static void read_number(struct ctx *ctx) while (1) { c = peek_char(ctx); - if (c == -1 || !FX_OK(ctx->ctx_status)) { + if (c == -1 || fx_result_is_error(ctx->ctx_result)) { break; } @@ -949,7 +965,7 @@ static void read_number(struct ctx *ctx) bool is_number = try_convert_word_to_number(ctx, wordbuf); if (!is_number) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); } } @@ -961,11 +977,12 @@ static void read_word(struct ctx *ctx) while (1) { c = peek_char(ctx); - if (c == -1 || !FX_OK(ctx->ctx_status)) { + if (c == -1 || fx_result_is_error(ctx->ctx_result)) { break; } - bool ok = fx_wchar_is_alnum(c) || c == '_' || c == '-' || c == '.'; + bool ok = fx_wchar_is_alnum(c) || c == '_' || c == '-' + || c == '.'; if (ctx->ctx_flags & CTX_ENABLE_TIMESTAMPS) { ok = ok || c == ':' || c == ' ' || c == '+'; @@ -987,7 +1004,7 @@ static void read_word(struct ctx *ctx) fx_string_trim(wordbuf); if (fx_string_get_size(wordbuf, FX_STRLEN_NORMAL) == 0) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); return; } @@ -1013,7 +1030,7 @@ static void read_word(struct ctx *ctx) /* only allow ASCII numbers/letters here */ bool ok = isalnum(c) || c == '_' || c == '-' || c == '.'; if (!ok) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); return; } } @@ -1108,7 +1125,7 @@ static void read_string(struct ctx *ctx, bool squote) } if (multiline && !(ctx->ctx_flags & CTX_ENABLE_MULTILINE_STRING)) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); return; } @@ -1121,7 +1138,7 @@ static void read_string(struct ctx *ctx, bool squote) while (!fail) { c = peek_char(ctx); if (c == -1) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } @@ -1132,7 +1149,7 @@ static void read_string(struct ctx *ctx, bool squote) cr = true; continue; } else { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } @@ -1157,7 +1174,8 @@ static void read_string(struct ctx *ctx, bool squote) } if (c != '\n') { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result + = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } @@ -1202,18 +1220,20 @@ static void read_string(struct ctx *ctx, bool squote) case 'U': c = read_unicode_sequence(ctx); if (c == FX_WCHAR_INVALID) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result + = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } - ctx->ctx_status = FX_OK(fx_string_append_wc(str, c)) - ? FX_SUCCESS - : FX_ERR_BAD_FORMAT; - fail = !FX_OK(ctx->ctx_status); + ctx->ctx_result + = FX_OK(fx_string_append_wc(str, c)) + ? FX_SUCCESS + : FX_RESULT_ERR(BAD_FORMAT); + fail = !FX_OK(ctx->ctx_result); break; default: - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); fail = true; break; } @@ -1229,7 +1249,7 @@ static void read_string(struct ctx *ctx, bool squote) else if (c == '\n') { if (!multiline) { fail = true; - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); break; } @@ -1341,7 +1361,8 @@ static void read_symbol(struct ctx *ctx) break; case ']': if (!(ctx->ctx_flags & CTX_ENABLE_LONG_SYMBOLS)) { - /* if we're parsing more complex values, don't generate double-symbol tokens */ + /* if we're parsing more complex values, don't generate + * double-symbol tokens */ tok->tok_type = TOK_RIGHT_BRACKET; break; } @@ -1365,7 +1386,7 @@ static void read_symbol(struct ctx *ctx) break; default: discard_token(ctx); - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); break; } } @@ -1379,7 +1400,7 @@ static void read_newline(struct ctx *ctx) } enqueue_token(ctx, TOK_NEWLINE); - ctx->ctx_status = FX_SUCCESS; + ctx->ctx_result = FX_SUCCESS; } static void read_comment(struct ctx *ctx) @@ -1398,7 +1419,7 @@ static void read_comment(struct ctx *ctx) } if (cr) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); break; } @@ -1411,10 +1432,10 @@ static void read_comment(struct ctx *ctx) } if (cr) { - ctx->ctx_status = FX_ERR_BAD_FORMAT; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); } - if (!FX_OK(ctx->ctx_status)) { + if (!FX_OK(ctx->ctx_result)) { return; } @@ -1438,13 +1459,13 @@ static bool is_symbol(fx_wchar c) } } -static enum fx_status advance_token(struct ctx *ctx) +static fx_result advance_token(struct ctx *ctx) { fx_wchar c = FX_WCHAR_INVALID; discard_token(ctx); if (!fx_queue_empty(&ctx->ctx_tokens)) { - return FX_SUCCESS; + return FX_RESULT_SUCCESS; } start: @@ -1456,7 +1477,7 @@ start: if (c == -1) { ctx->ctx_flags |= CTX_EOF; - return FX_ERR_NO_DATA; + return FX_RESULT_ERR(NO_DATA); } #if 1 @@ -1466,8 +1487,8 @@ start: } #endif - if (!FX_OK(ctx->ctx_status)) { - return ctx->ctx_status; + if (!FX_OK(ctx->ctx_result)) { + return ctx->ctx_result; } if (c == '\r') { @@ -1475,8 +1496,8 @@ start: c = peek_char(ctx); if (c != '\n') { - ctx->ctx_status = FX_ERR_BAD_FORMAT; - return ctx->ctx_status; + ctx->ctx_result = FX_RESULT_ERR(BAD_FORMAT); + return ctx->ctx_result; } } @@ -1484,7 +1505,8 @@ start: read_string(ctx, false); } else if (c == '\'') { read_string(ctx, true); - } else if ((c == '+' || c == '-') && ctx->ctx_flags & CTX_ENABLE_NUMBERS) { + } else if ( + (c == '+' || c == '-') && ctx->ctx_flags & CTX_ENABLE_NUMBERS) { read_number(ctx); } else if (is_symbol(c)) { read_symbol(ctx); @@ -1494,7 +1516,7 @@ start: read_word(ctx); } - return ctx->ctx_status; + return ctx->ctx_result; } static struct token *peek_token(struct ctx *ctx) @@ -1530,7 +1552,7 @@ static void ctx_cleanup(struct ctx *ctx) } } -static enum fx_status ctx_init(struct ctx *ctx) +static fx_result ctx_init(struct ctx *ctx) { memset(ctx, 0x0, sizeof *ctx); @@ -1539,14 +1561,16 @@ static enum fx_status ctx_init(struct ctx *ctx) ctx->ctx_objects_flags = fx_hashmap_create(NULL, NULL); - return FX_SUCCESS; + return FX_RESULT_SUCCESS; } -static enum fx_status toml_serialise( - fx_serial_ctx *serial, fx_object *src, fx_stream *dest, +static fx_result toml_serialise( + fx_serial_ctx *serial, + fx_object *src, + fx_stream *dest, enum fx_serial_flags flags) { - return FX_ERR_NOT_SUPPORTED; + return FX_RESULT_ERR(NOT_SUPPORTED); } static void print_token(struct token *tok) @@ -1556,10 +1580,10 @@ static void print_token(struct token *tok) printf("TOK_NONE\n"); break; case TOK_WORD: - printf("TOK_WORD %s\n", fx_string_ptr(tok->tok_str)); + printf("TOK_WORD %s\n", fx_string_get_cstr(tok->tok_str)); break; case TOK_STRING: - printf("TOK_STRING %s\n", fx_string_ptr(tok->tok_str)); + printf("TOK_STRING %s\n", fx_string_get_cstr(tok->tok_str)); break; case TOK_TIMESTAMP: printf("TOK_TIMESTAMP %04ld-%02ld-%02ld " @@ -1636,10 +1660,10 @@ static void print_token(struct token *tok) } } -static enum fx_status parse_value(struct ctx *ctx, fx_object **result); -static enum fx_status parse_key_value_pair(struct ctx *ctx, fx_dict *container); +static fx_result parse_value(struct ctx *ctx, fx_object **result); +static fx_result parse_key_value_pair(struct ctx *ctx, fx_dict *container); -static enum fx_status parse_timestamp(struct ctx *ctx, fx_object **result) +static fx_result parse_timestamp(struct ctx *ctx, fx_object **result) { struct token *tok = peek_token(ctx); fx_datetime *dt = tok->tok_value.time; @@ -1649,24 +1673,24 @@ static enum fx_status parse_timestamp(struct ctx *ctx, fx_object **result) return FX_SUCCESS; } -static enum fx_status parse_string(struct ctx *ctx, fx_object **result) +static fx_result parse_string(struct ctx *ctx, fx_object **result) { struct token *tok = peek_token(ctx); fx_string *str = fx_string_duplicate(tok->tok_str); if (!str) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } *result = (str); return FX_SUCCESS; } -static enum fx_status parse_int(struct ctx *ctx, fx_object **result) +static fx_result parse_int(struct ctx *ctx, fx_object **result) { struct token *tok = peek_token(ctx); fx_number *val = FX_LONGLONG(tok->tok_value.i.v); if (!val) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } if (tok->tok_value.i.inf) { @@ -1687,12 +1711,12 @@ static enum fx_status parse_int(struct ctx *ctx, fx_object **result) return FX_SUCCESS; } -static enum fx_status parse_float(struct ctx *ctx, fx_object **result) +static fx_result parse_float(struct ctx *ctx, fx_object **result) { struct token *tok = peek_token(ctx); fx_number *val = FX_DOUBLE(tok->tok_value.f.v); if (!val) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } if (tok->tok_value.f.inf) { @@ -1713,19 +1737,19 @@ static enum fx_status parse_float(struct ctx *ctx, fx_object **result) return FX_SUCCESS; } -static enum fx_status parse_bool(struct ctx *ctx, fx_object **result) +static fx_result parse_bool(struct ctx *ctx, fx_object **result) { struct token *tok = peek_token(ctx); fx_number *val = FX_INT8(tok->tok_value.b); if (!val) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } *result = (val); return FX_SUCCESS; } -static enum fx_status parse_table_inline(struct ctx *ctx, fx_object **result) +static fx_result parse_table_inline(struct ctx *ctx, fx_object **result) { DISABLE_EXTENDED_LEXING(ctx); @@ -1733,7 +1757,7 @@ static enum fx_status parse_table_inline(struct ctx *ctx, fx_object **result) fx_dict *table = fx_dict_create(); if (!table) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } struct token *tok = peek_token(ctx); @@ -1746,7 +1770,7 @@ static enum fx_status parse_table_inline(struct ctx *ctx, fx_object **result) while (!done) { fx_object *value; - enum fx_status status = parse_key_value_pair(ctx, table); + fx_result status = parse_key_value_pair(ctx, table); if (!FX_OK(status)) { fx_dict_unref(table); return status; @@ -1768,7 +1792,7 @@ static enum fx_status parse_table_inline(struct ctx *ctx, fx_object **result) break; default: fx_dict_unref(table); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } } @@ -1786,7 +1810,7 @@ static void skip_newlines(struct ctx *ctx) } } -static enum fx_status parse_array_inline(struct ctx *ctx, fx_object **result) +static fx_result parse_array_inline(struct ctx *ctx, fx_object **result) { bool done = false; ENABLE_EXTENDED_LEXING(ctx); @@ -1795,13 +1819,13 @@ static enum fx_status parse_array_inline(struct ctx *ctx, fx_object **result) fx_array *array = fx_array_create(); if (!array) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } struct token *tok = peek_token(ctx); if (!tok) { fx_array_unref(array); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } if (tok->tok_type == TOK_RIGHT_BRACKET) { @@ -1815,7 +1839,7 @@ static enum fx_status parse_array_inline(struct ctx *ctx, fx_object **result) if (!tok) { fx_array_unref(array); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } if (tok->tok_type == TOK_RIGHT_BRACKET) { @@ -1824,7 +1848,7 @@ static enum fx_status parse_array_inline(struct ctx *ctx, fx_object **result) } fx_object *value; - enum fx_status status = parse_value(ctx, &value); + fx_result status = parse_value(ctx, &value); if (!FX_OK(status)) { fx_array_unref(array); return status; @@ -1845,7 +1869,7 @@ static enum fx_status parse_array_inline(struct ctx *ctx, fx_object **result) if (!tok || tok->tok_type != TOK_COMMA) { fx_array_unref(array); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } ENABLE_EXTENDED_LEXING(ctx); @@ -1857,12 +1881,12 @@ static enum fx_status parse_array_inline(struct ctx *ctx, fx_object **result) return FX_SUCCESS; } -static enum fx_status parse_value(struct ctx *ctx, fx_object **result) +static fx_result parse_value(struct ctx *ctx, fx_object **result) { struct token *tok = peek_token(ctx); if (!tok) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } switch (tok->tok_type) { @@ -1881,26 +1905,26 @@ static enum fx_status parse_value(struct ctx *ctx, fx_object **result) case TOK_LEFT_BRACE: return parse_table_inline(ctx, result); default: - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } } -static enum fx_status parse_key_value_pair(struct ctx *ctx, fx_dict *container) +static fx_result parse_key_value_pair(struct ctx *ctx, fx_dict *container) { struct token *tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } fx_string *key = fx_string_duplicate(tok->tok_str); if (!key) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } advance_token(ctx); tok = peek_token(ctx); if (!tok) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } while (tok && tok->tok_type == TOK_DOT) { @@ -1908,16 +1932,19 @@ static enum fx_status parse_key_value_pair(struct ctx *ctx, fx_dict *container) if (!sub_dict) { sub_dict = (fx_dict_create()); fx_dict_put_sk(container, key, FX_RV(sub_dict)); - } else if (sub_dict && !fx_object_is_type(sub_dict, FX_TYPE_DICT)) { + } else if ( + sub_dict + && !fx_object_is_type(sub_dict, FX_TYPE_DICT)) { free(key); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } #if 1 enum object_flags flags = ctx_get_object_flags(ctx, sub_dict); - if (flags & (OBJECT_KV_END_DEFINED | OBJECT_HEADER_END_DEFINED)) { + if (flags + & (OBJECT_KV_END_DEFINED | OBJECT_HEADER_END_DEFINED)) { free(key); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } #endif @@ -1927,14 +1954,14 @@ static enum fx_status parse_key_value_pair(struct ctx *ctx, fx_dict *container) tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { free(key); - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } container = sub_dict; fx_string_unref(key); key = fx_string_duplicate(tok->tok_str); if (!key) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } advance_token(ctx); @@ -1942,32 +1969,33 @@ static enum fx_status parse_key_value_pair(struct ctx *ctx, fx_dict *container) } if (fx_dict_has_skey(container, key)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } if (!tok) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } if (tok->tok_type != TOK_EQUAL) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } ENABLE_EXTENDED_LEXING(ctx); advance_token(ctx); fx_object *value = NULL; - enum fx_status status = parse_value(ctx, &value); + fx_result result = parse_value(ctx, &value); DISABLE_EXTENDED_LEXING(ctx); - if (!FX_OK(status)) { - return status; + if (fx_result_is_error(result)) { + return result; } - status = advance_token(ctx); - if (!FX_OK(status) && status != FX_ERR_NO_DATA) { - return status; + result = advance_token(ctx); + if (fx_result_is_error(result) + && fx_error_get_status_code(result) != FX_ERR_NO_DATA) { + return fx_result_propagate(result); } fx_dict_put_sk(container, key, FX_RV(value)); @@ -1980,24 +2008,26 @@ static enum fx_status parse_key_value_pair(struct ctx *ctx, fx_dict *container) return FX_SUCCESS; } -static enum fx_status parse_table_header( - struct ctx *ctx, fx_dict *container, fx_dict **new_container) +static fx_result parse_table_header( + struct ctx *ctx, + fx_dict *container, + fx_dict **new_container) { advance_token(ctx); struct token *tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } fx_string *key = fx_string_duplicate(tok->tok_str); if (!key) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } advance_token(ctx); tok = peek_token(ctx); if (!tok) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } while (tok && tok->tok_type == TOK_DOT) { @@ -2008,19 +2038,21 @@ static enum fx_status parse_table_header( fx_dict_put_sk(container, key, FX_RV(sub_dict)); } else if (fx_object_is_type(sub_dict, FX_TYPE_ARRAY)) { - sub_dict = fx_array_at(sub_dict, fx_array_size(sub_dict) - 1); + sub_dict = fx_array_at( + sub_dict, + fx_array_size(sub_dict) - 1); } else if (!fx_object_is_type(sub_dict, FX_TYPE_DICT)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } if (flags & OBJECT_KV_END_DEFINED) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } advance_token(ctx); tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } ctx_set_object_flags(ctx, sub_dict, OBJECT_HEADER_MID_DEFINED); @@ -2029,7 +2061,7 @@ static enum fx_status parse_table_header( fx_string_unref(key); key = fx_string_duplicate(tok->tok_str); if (!key) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } advance_token(ctx); @@ -2037,7 +2069,7 @@ static enum fx_status parse_table_header( } if (!tok || tok->tok_type != TOK_RIGHT_BRACKET) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } fx_dict *new_table = fx_dict_at_sk(container, key); @@ -2047,21 +2079,21 @@ static enum fx_status parse_table_header( if (!new_table) { free(key); - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } fx_dict_put_sk(container, key, FX_RV(new_table)); } if (!fx_object_is_type((new_table), FX_TYPE_DICT)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } enum object_flags flags = ctx_get_object_flags(ctx, (new_table)); if (flags & (OBJECT_HEADER_END_DEFINED | OBJECT_KV_MID_DEFINED | OBJECT_KV_END_DEFINED)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } ctx_set_object_flags(ctx, (new_table), OBJECT_HEADER_END_DEFINED); @@ -2072,24 +2104,26 @@ static enum fx_status parse_table_header( return FX_SUCCESS; } -static enum fx_status parse_array_header( - struct ctx *ctx, fx_dict *container, fx_dict **new_container) +static fx_result parse_array_header( + struct ctx *ctx, + fx_dict *container, + fx_dict **new_container) { advance_token(ctx); struct token *tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } fx_string *key = fx_string_duplicate(tok->tok_str); if (!key) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } advance_token(ctx); tok = peek_token(ctx); if (!tok) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } while (tok && tok->tok_type == TOK_DOT) { @@ -2098,22 +2132,24 @@ static enum fx_status parse_array_header( sub_dict = (fx_dict_create()); fx_dict_put_sk(container, key, FX_RV(sub_dict)); } else if (fx_object_is_type(sub_dict, FX_TYPE_ARRAY)) { - sub_dict = fx_array_at(sub_dict, fx_array_size(sub_dict) - 1); + sub_dict = fx_array_at( + sub_dict, + fx_array_size(sub_dict) - 1); } else if (!fx_object_is_type(sub_dict, FX_TYPE_DICT)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } advance_token(ctx); tok = peek_token(ctx); if (!IS_VALID_KEY_COMPONENT(tok)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } container = sub_dict; fx_string_unref(key); key = fx_string_duplicate(tok->tok_str); if (!key) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } advance_token(ctx); @@ -2121,7 +2157,7 @@ static enum fx_status parse_array_header( } if (!tok || tok->tok_type != TOK_DOUBLE_RIGHT_BRACKET) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } fx_array *array = fx_dict_get_sk(container, key); @@ -2129,18 +2165,18 @@ static enum fx_status parse_array_header( array = fx_array_create(); fx_dict_put_sk(container, key, FX_RV(array)); } else if (!fx_object_is_type(array, FX_TYPE_ARRAY)) { - return FX_ERR_BAD_FORMAT; + return FX_RESULT_ERR(BAD_FORMAT); } free(key); enum object_flags flags = ctx_get_object_flags(ctx, (array)); if (flags & OBJECT_KV_END_DEFINED) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } fx_dict *new_table = fx_dict_create(); if (!new_table) { - return FX_ERR_NO_MEMORY; + return FX_RESULT_ERR(NO_MEMORY); } fx_array_append(array, FX_RV(new_table)); @@ -2150,13 +2186,13 @@ static enum fx_status parse_array_header( return FX_SUCCESS; } -static enum fx_status parse_root(struct ctx *ctx, fx_dict **result) +static fx_result parse_root(struct ctx *ctx, fx_dict **out) { - enum fx_status status = FX_SUCCESS; + fx_result result = FX_RESULT_SUCCESS; fx_dict *root = fx_dict_create(); fx_dict *current = root; - while (!(ctx->ctx_flags & CTX_EOF) && FX_OK(status)) { + while (!(ctx->ctx_flags & CTX_EOF) && fx_result_is_success(result)) { struct token *tok = peek_token(ctx); if (!tok) { break; @@ -2164,37 +2200,37 @@ static enum fx_status parse_root(struct ctx *ctx, fx_dict **result) switch (tok->tok_type) { case TOK_LEFT_BRACKET: - status = parse_table_header(ctx, root, ¤t); - if (!FX_OK(status)) { + result = parse_table_header(ctx, root, ¤t); + if (fx_result_is_error(result)) { break; } tok = peek_token(ctx); if (tok && tok->tok_type != TOK_NEWLINE) { - status = FX_ERR_BAD_FORMAT; + result = FX_RESULT_ERR(BAD_FORMAT); } break; case TOK_DOUBLE_LEFT_BRACKET: - status = parse_array_header(ctx, root, ¤t); - if (!FX_OK(status)) { + result = parse_array_header(ctx, root, ¤t); + if (fx_result_is_error(result)) { break; } tok = peek_token(ctx); if (tok && tok->tok_type != TOK_NEWLINE) { - status = FX_ERR_BAD_FORMAT; + result = FX_RESULT_ERR(BAD_FORMAT); } break; case TOK_WORD: case TOK_STRING: - status = parse_key_value_pair(ctx, current); - if (!FX_OK(status)) { + result = parse_key_value_pair(ctx, current); + if (fx_result_is_error(result)) { break; } tok = peek_token(ctx); if (tok && tok->tok_type != TOK_NEWLINE) { - status = FX_ERR_BAD_FORMAT; + result = FX_RESULT_ERR(BAD_FORMAT); } advance_token(ctx); break; @@ -2202,68 +2238,73 @@ static enum fx_status parse_root(struct ctx *ctx, fx_dict **result) advance_token(ctx); break; default: - status = FX_ERR_BAD_FORMAT; + result = FX_RESULT_ERR(BAD_FORMAT); break; } - if (!FX_OK(ctx->ctx_status) && ctx->ctx_status != FX_ERR_NO_DATA) { - status = ctx->ctx_status; + if (fx_result_is_error(ctx->ctx_result) + && fx_error_get_status_code(ctx->ctx_result) + != FX_ERR_NO_DATA) { + result = ctx->ctx_result; } } - if (!FX_OK(status)) { + if (fx_result_is_error(result)) { fx_dict_unref(root); root = NULL; } - *result = root; - return status; + *out = root; + return result; } -static enum fx_status toml_deserialise( - fx_serial_ctx *serial, fx_stream *src, fx_object **dest, +static fx_result toml_deserialise( + fx_serial_ctx *serial, + fx_stream *src, + fx_object **dest, enum fx_serial_flags flags) { struct ctx ctx = {0}; - enum fx_status status = ctx_init(&ctx); + fx_result result = ctx_init(&ctx); - if (!FX_OK(status)) { - return status; + if (fx_result_is_error(result)) { + return fx_result_propagate(result); } ctx.ctx_src = src; ctx.ctx_flags = CTX_ENABLE_LONG_SYMBOLS; - status = advance_token(&ctx); + result = advance_token(&ctx); - if (!FX_OK(ctx.ctx_status) && ctx.ctx_status != FX_ERR_NO_DATA) { - return ctx.ctx_status; + if (fx_result_is_error(result) + && fx_error_get_status_code(result) != FX_ERR_NO_DATA) { + return fx_result_propagate(result); } if (ctx.ctx_flags & CTX_EOF) { *dest = (fx_dict_create()); - return FX_SUCCESS; + return FX_RESULT_SUCCESS; } - fx_dict *result = NULL; - status = parse_root(&ctx, &result); - if (!FX_OK(status)) { - return status; + fx_dict *data = NULL; + ctx.ctx_result = parse_root(&ctx, &data); + if (fx_result_is_error(ctx.ctx_result)) { + return fx_result_propagate(ctx.ctx_result); } - *dest = (result); + *dest = (data); #if 0 ctx.ctx_flags = CTX_ENABLE_NUMBERS | CTX_ENABLE_TIMESTAMPS | CTX_ENABLE_BOOLS; - while (!(ctx.ctx_flags & CTX_EOF) && FX_OK(ctx.ctx_status)) { + while (!(ctx.ctx_flags & CTX_EOF) && FX_OK(ctx.ctx_result)) { struct token *tok = peek_token(&ctx); print_token(tok); status = advance_token(&ctx); } #endif - return FX_SUCCESS; + return FX_RESULT_SUCCESS; } /*** VIRTUAL FUNCTIONS ********************************************************/