From c263d02b36aa7782085aaa2e20fb0f227928e201 Mon Sep 17 00:00:00 2001 From: Timerix Date: Thu, 27 Nov 2025 01:46:44 +0500 Subject: [PATCH] added tlibtoml submodule --- .gitmodules | 3 ++ .vscode/c_cpp_properties.json | 2 +- README.md | 7 ++-- dependencies/tlibc | 2 +- dependencies/tlibtoml | 1 + dependencies/tlibtoml.config | 30 +++++++++++++++++ include/tcp-chat/server.h | 10 +++++- project.config | 7 ++-- src/cli/main.c | 2 +- src/cli/modes/ServerMode.c | 18 +++++++---- src/config.c | 34 -------------------- src/config.h | 6 ---- src/server/server.c | 59 ++++++++++++++++------------------ tcp-chat-server.config.default | 9 ------ tcp-chat-server.toml.default | 13 ++++++++ 15 files changed, 108 insertions(+), 95 deletions(-) create mode 160000 dependencies/tlibtoml create mode 100644 dependencies/tlibtoml.config delete mode 100644 src/config.c delete mode 100644 src/config.h delete mode 100644 tcp-chat-server.config.default create mode 100644 tcp-chat-server.toml.default diff --git a/.gitmodules b/.gitmodules index 2d1c599..52a74b3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "dependencies/tlibc"] path = dependencies/tlibc url = https://timerix.ddns.net/git/timerix/tlibc.git +[submodule "dependencies/tlibtoml"] + path = dependencies/tlibtoml + url = https://timerix.ddns.net/git/Timerix/tlibtoml.git diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 4c31012..ff6a5f5 100755 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -7,8 +7,8 @@ "src", "include", "dependencies/BearSSL/inc", - "dependencies/BearSSL/src", "dependencies/tlibc/include", + "dependencies/tlibtoml/include", "${default}" ], "cStandard": "c99" diff --git a/README.md b/README.md index d63a824..37632b9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,10 @@ git clone --recurse-submodules --depth 0 https://timerix.ddns.net/git/Timerix/tcp-chat.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. Build executable ``` @@ -23,7 +26,7 @@ cd bin ``` **Server:** 1. ```sh - cp tcp-chat-server.config.default bin/tcp-chat-server.config + cp tcp-chat-server.toml.default bin/tcp-chat-server.toml ``` 2. Edit config 3. ```sh diff --git a/dependencies/tlibc b/dependencies/tlibc index 8a40caa..ea6c20f 160000 --- a/dependencies/tlibc +++ b/dependencies/tlibc @@ -1 +1 @@ -Subproject commit 8a40caaf1044f9fe2c327c4d3c60a3310efd6142 +Subproject commit ea6c20f430f4536631f379697ae56fc8b5fd5d17 diff --git a/dependencies/tlibtoml b/dependencies/tlibtoml new file mode 160000 index 0000000..a0e280d --- /dev/null +++ b/dependencies/tlibtoml @@ -0,0 +1 @@ +Subproject commit a0e280d77b6d8967239b14915609eef422f6ba0b diff --git a/dependencies/tlibtoml.config b/dependencies/tlibtoml.config new file mode 100644 index 0000000..19ea58b --- /dev/null +++ b/dependencies/tlibtoml.config @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# This is a dependency config. +# You can copy it to another project to add tlibtoml dependency. + +DEP_WORKING_DIR="$DEPENDENCIES_DIR/tlibtoml" + +user_config_path="project.config.user" +absolute_dep_dir=$(realpath "$DEPENDENCIES_DIR") + +function setup_user_config(){ + # Set variable `DEPENDENCIES_DIR`` in `tlibtoml/project.config.user` + # to the directory where `tlibc`` is installed + 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" +} + +if [[ "$TASK" = *_dbg ]]; then + dep_build_target="build_static_lib_dbg" +else + dep_build_target="build_static_lib" +fi +DEP_PRE_BUILD_COMMAND="setup_user_config" +DEP_BUILD_COMMAND="cbuild $dep_build_target" +DEP_POST_BUILD_COMMAND="" +DEP_CLEAN_COMMAND="cbuild clean" +DEP_DYNAMIC_OUT_FILES="" +DEP_STATIC_OUT_FILES="bin/tlibtoml.a" +DEP_OTHER_OUT_FILES="" +PRESERVE_OUT_DIRECTORY_STRUCTURE=false diff --git a/include/tcp-chat/server.h b/include/tcp-chat/server.h index 630322f..6f99a7a 100644 --- a/include/tcp-chat/server.h +++ b/include/tcp-chat/server.h @@ -5,6 +5,14 @@ typedef struct Server Server; -Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func); +/// @param config_file_content config in toml format +/// @param config_file_name to use in error messages +/// @param logger some shared data for your log function +/// @param log_func log function that you have to implement +/// @return +Result(Server*) Server_create(str config_file_content, cstr config_file_name, + void* logger, LogFunction_t log_func); + void Server_free(Server* server); + Result(void) Server_run(Server* server); diff --git a/project.config b/project.config index 275c818..44269f5 100644 --- a/project.config +++ b/project.config @@ -24,7 +24,7 @@ SRC_CPP="$(find src -name '*.cpp')" # See cbuild/example_dependency_configs DEPENDENCY_CONFIGS_DIR='dependencies' # List of dependency config files in DEPENDENCY_CONFIGS_DIR separated by space. -ENABLED_DEPENDENCIES='tlibc bearssl' +ENABLED_DEPENDENCIES='bearssl tlibc tlibtoml' # OBJDIR structure: # ├── objects/ - Compiled object files. Cleans on each call of build task @@ -35,7 +35,10 @@ OBJDIR="obj" OUTDIR="bin" STATIC_LIB_FILE="$PROJECT.a" -INCLUDE="-Isrc -Iinclude -I$DEPENDENCIES_DIR/BearSSL/inc -I$DEPENDENCIES_DIR/tlibc/include" +INCLUDE="-Isrc -Iinclude + -I$DEPENDENCIES_DIR/BearSSL/inc + -I$DEPENDENCIES_DIR/tlibc/include + -I$DEPENDENCIES_DIR/tlibtoml/include" # OS-specific options case "$OS" in diff --git a/src/cli/main.c b/src/cli/main.c index aee1e26..3229afe 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -4,7 +4,7 @@ #include "modes/modes.h" #define _DEFAULT_CONFIG_PATH_CLIENT "tcp-chat-client.config" -#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.config" +#define _DEFAULT_CONFIG_PATH_SERVER "tcp-chat-server.toml" #define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL)) diff --git a/src/cli/modes/ServerMode.c b/src/cli/modes/ServerMode.c index ae31be6..c0083f4 100644 --- a/src/cli/modes/ServerMode.c +++ b/src/cli/modes/ServerMode.c @@ -67,10 +67,9 @@ Result(void) run_ServerMode(cstr config_path) { Defer(file_close(config_file)); // read whole file into str - Array(u8) config_buf = Array_u8_construct(NULL, 0); - try_void(file_readWhole(config_file, &config_buf)); - Defer(Array_u8_destroy(&config_buf)); - str config_str = Array_u8_castTo_str(config_buf, false); + str config_file_content = str_null; + try_void(file_readWholeText(config_file, &config_file_content)); + Defer(str_destroy(config_file_content)); // create logger ServerLogger logger; @@ -78,14 +77,19 @@ Result(void) run_ServerMode(cstr config_path) { Defer(ServerLogger_destroy(&logger)); // init server - try(Server* server, p, Server_create(config_str, &logger, log_func)); + try(Server* server, p, + Server_create( + config_file_content, config_path, + &logger, log_func + ) + ); Defer(Server_free(server)); // manually close file and free config_buf file_close(config_file); config_file = NULL; - Array_u8_destroy(&config_buf); - config_buf.data = NULL; + str_destroy(config_file_content); + config_file_content.data = NULL; // start infinite loop on main thread try_void(Server_run(server)); diff --git a/src/config.c b/src/config.c deleted file mode 100644 index 59fd19a..0000000 --- a/src/config.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "config.h" - -Result(void) config_findValue(str config_str, str key, str* value, bool throwNotFoundError){ - u32 line_n = 0; - while(config_str.len > 0){ - line_n++; - i32 line_end = str_seekChar(config_str, '\n', 0); - if(line_end < 0) - line_end = config_str.len - 1; - str line = str_sliceBefore(config_str, line_end); - config_str = str_sliceAfter(config_str, line_end + 1); - - i32 sep_pos = str_seekChar(line, '=', 1); - if(sep_pos < 0){ - //not a 'key = value' line - continue; - } - - str line_key = str_sliceBefore(line, sep_pos - 1); - str_trim(&line_key, false); - if(str_equals(line_key, key)){ - str line_value = str_sliceAfter(line, sep_pos + 1); - str_trim(&line_value, false); - *value = line_value; - return RESULT_VOID; - } - } - - if(throwNotFoundError){ - char* err_msg = sprintf_malloc("can't find key '"FMT_str"'", key.len, key.data); - return RESULT_ERROR(err_msg, true); - } - return RESULT_VOID; -} diff --git a/src/config.h b/src/config.h deleted file mode 100644 index 61f8c76..0000000 --- a/src/config.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "tlibc/errors.h" -#include "tlibc/string/str.h" - -/// searches for pattern `key = value` -Result(void) config_findValue(str config_str, str key, str* value, bool throwNotFoundError); diff --git a/src/server/server.c b/src/server/server.c index 66d6268..7a84377 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -3,9 +3,9 @@ #include "tlibc/time.h" #include "tlibc/base64.h" #include "server/server_internal.h" -#include "config.h" #include "network/tcp-chat-protocol/v1.h" #include "server/responses/responses.h" +#include "tlibtoml.h" static void* handleConnection(void* _args); static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_ctx); @@ -36,7 +36,9 @@ void Server_free(Server* self){ #define LOG_FUNC log_func #define LOG_CONTEXT log_ctx -Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_func){ +Result(Server*) Server_create(str config_file_content, cstr config_file_name, + void* logger, LogFunction_t log_func) + { Deferral(16); cstr log_ctx = "ServerInit"; @@ -47,53 +49,48 @@ Result(Server*) Server_create(str config_str, void* logger, LogFunction_t log_fu self->logger = logger; self->log_func = log_func; + logDebug("parsing config"); + try(TomlTable* config_toml, p, toml_load_str_filename(config_file_content, config_file_name)); + Defer(TomlTable_free(config_toml)); // parse name - str tmp_str = str_null; - try_void(config_findValue(config_str, STR("name"), &tmp_str, true)); - self->name = str_copy(tmp_str); + try(str* v_name, p, TomlTable_get_str(config_toml, STR("name"))); + self->name = str_copy(*v_name); // parse description - try_void(config_findValue(config_str, STR("description"), &tmp_str, true)); - self->description = str_copy(tmp_str); + try(str* v_desc, p, TomlTable_get_str(config_toml, STR("description"))); + self->description = str_copy(*v_desc); // parse landing_channel_id - try_void(config_findValue(config_str, STR("landing_channel_id"), &tmp_str, true)); - char* lci_cstr = str_copy(tmp_str).data; - Defer(free(lci_cstr)); - if(sscanf(lci_cstr, FMT_u64, &self->landing_channel_id) != 1){ - Return RESULT_ERROR("can't parse 'landing_channel_id' value as number", false); - } + try(i64 v_landing_channel_id, i, TomlTable_get_integer(config_toml, STR("landing_channel_id"))); + self->landing_channel_id = v_landing_channel_id; // parse local_address - try_void(config_findValue(config_str, STR("local_address"), &tmp_str, true)); - char* local_end_cstr = str_copy(tmp_str).data; - Defer(free(local_end_cstr)); - try_void(EndpointIPv4_parse(local_end_cstr, &self->local_end)); + try(str* v_local_address, p, TomlTable_get_str(config_toml, STR("local_address"))); + try_assert(v_local_address->isZeroTerminated); + try_void(EndpointIPv4_parse(v_local_address->data, &self->local_end)); // parse rsa_private_key - try_void(config_findValue(config_str, STR("rsa_private_key"), &tmp_str, true)); - char* sk_base64_cstr = str_copy(tmp_str).data; - Defer(free(sk_base64_cstr)); + try(str* v_rsa_sk, p, TomlTable_get_str(config_toml, STR("rsa_private_key"))); + try_assert(v_rsa_sk->isZeroTerminated); + try_void(RSA_parsePrivateKey_base64(v_rsa_sk->data, &self->rsa_sk)); // parse rsa_public_key - try_void(config_findValue(config_str, STR("rsa_public_key"), &tmp_str, true)); - char* pk_base64_cstr = str_copy(tmp_str).data; - Defer(free(pk_base64_cstr)); - - try_void(RSA_parsePrivateKey_base64(sk_base64_cstr, &self->rsa_sk)); - try_void(RSA_parsePublicKey_base64(pk_base64_cstr, &self->rsa_pk)); + try(str* v_rsa_pk, p, TomlTable_get_str(config_toml, STR("rsa_public_key"))); + try_assert(v_rsa_pk->isZeroTerminated); + try_void(RSA_parsePublicKey_base64(v_rsa_pk->data, &self->rsa_pk)); // parse db_aes_key - try_void(config_findValue(config_str, STR("db_aes_key"), &tmp_str, true)); - Array(u8) db_aes_key = Array_u8_alloc(base64_decodedSize(tmp_str.data, tmp_str.len)); + try(str* v_db_aes_key, p, TomlTable_get_str(config_toml, STR("db_aes_key"))); + str db_aes_key_s = *v_db_aes_key; + Array(u8) db_aes_key = Array_u8_alloc(base64_decodedSize(db_aes_key_s.data, db_aes_key_s.len)); Defer(free(db_aes_key.data)); - base64_decode(tmp_str.data, tmp_str.len, db_aes_key.data); + base64_decode(db_aes_key_s.data, db_aes_key_s.len, db_aes_key.data); // parse db_dir and open db - try_void(config_findValue(config_str, STR("db_dir"), &tmp_str, true)); - try(self->db, p, idb_open(tmp_str, db_aes_key)); + try(str* v_db_dir, p, TomlTable_get_str(config_toml, STR("db_dir"))); + try(self->db, p, idb_open(*v_db_dir, db_aes_key)); // build users cache logDebug("loading users..."); diff --git a/tcp-chat-server.config.default b/tcp-chat-server.config.default deleted file mode 100644 index 393f2b1..0000000 --- a/tcp-chat-server.config.default +++ /dev/null @@ -1,9 +0,0 @@ -name = test server -description = Lorem ipsum labuba aboba -landing_channel_id = 0 -local_address = 127.0.0.1:9988 -db_dir = server-db -db_aes_key = - -rsa_private_key = -rsa_public_key = diff --git a/tcp-chat-server.toml.default b/tcp-chat-server.toml.default new file mode 100644 index 0000000..d9a6ea1 --- /dev/null +++ b/tcp-chat-server.toml.default @@ -0,0 +1,13 @@ +name = "Test Server" +description = """\ + Lorem ipsum labuba aboba.\n\ + Qqqqq...\ + """ + +landing_channel_id = 0 +local_address = '127.0.0.1:9988' +db_dir = 'server-db' +db_aes_key = '' + +rsa_private_key = '' +rsa_public_key = ''