From b9c44821df36c488b7ead015110edd309b614fb4 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sat, 20 Jan 2024 11:13:51 +0100 Subject: strings TODO --- source/kit/parse.c | 2 ++ source/kit/parse.h | 17 +++++++++++ source/kit/print.c | 2 ++ source/kit/print.h | 49 +++++++++++++++++++++++++++++++ source/kit/process.h | 2 ++ source/kit/process.posix.c | 48 ++++++++++++++++++------------ source/kit/string_builder.h | 51 ++++++++++++++++++++++++++++++++ source/kit/string_ref.h | 71 +++++++++++++++++++++++++++++++++++++++++++-- source/kit/utf8.h | 47 ++++++++++++++++++++++++++++++ 9 files changed, 268 insertions(+), 21 deletions(-) create mode 100644 source/kit/parse.c create mode 100644 source/kit/parse.h create mode 100644 source/kit/print.c create mode 100644 source/kit/print.h create mode 100644 source/kit/utf8.h (limited to 'source') diff --git a/source/kit/parse.c b/source/kit/parse.c new file mode 100644 index 0000000..042e2d0 --- /dev/null +++ b/source/kit/parse.c @@ -0,0 +1,2 @@ +#include "parse.h" + diff --git a/source/kit/parse.h b/source/kit/parse.h new file mode 100644 index 0000000..e07559a --- /dev/null +++ b/source/kit/parse.h @@ -0,0 +1,17 @@ +#ifndef KIT_PARSE_H +#define KIT_PARSE_H + +#include "string_builder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#ifndef KIT_DISABLE_SHORT_NAMES +#endif + +#endif diff --git a/source/kit/print.c b/source/kit/print.c new file mode 100644 index 0000000..5c98910 --- /dev/null +++ b/source/kit/print.c @@ -0,0 +1,2 @@ +#include "print.h" + diff --git a/source/kit/print.h b/source/kit/print.h new file mode 100644 index 0000000..799a011 --- /dev/null +++ b/source/kit/print.h @@ -0,0 +1,49 @@ +#ifndef KIT_PRINT_H +#define KIT_PRINT_H + +#include "string_builder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + KIT_PRINT_ALIGN_RIGHT = 1, + KIT_PRINT_UNSIGNED = (1 << 1), + KIT_PRINT_BIN = (1 << 2), + KIT_PRINT_OCT = (1 << 3), + KIT_PRINT_DEC = (1 << 4), + KIT_PRINT_HEX = (1 << 5), + KIT_PRINT_PRECISE = (1 << 6), + KIT_PRINT_UTF8 = (1 << 7), +}; + +s32 kit_print_int(kit_str_builder_t *s, i64 value, i64 width, c8 fill, + u32 flags); + +s32 kit_print_float(kit_str_builder_t *s, f64 value, i64 width, + c8 fill, u32 flags); + +s32 kit_print_esc(kit_str_builder_t *s, kit_str_t value, + c8 escape_char, kit_str_t special_symbols, + u32 flags); + +#ifdef __cplusplus +} +#endif + +#ifndef KIT_DISABLE_SHORT_NAMES +# define PRINT_ALIGN_RIGHT KIT_PRINT_ALIGN_RIGHT +# define PRINT_UNSIGNED KIT_PRINT_UNSIGNED +# define PRINT_BIN KIT_PRINT_BIN +# define PRINT_OCT KIT_PRINT_OCT +# define PRINT_DEC KIT_PRINT_DEC +# define PRINT_HEX KIT_PRINT_HEX +# define PRINT_PRECISE KIT_PRINT_PRECISE +# define PRINT_UTF8 KIT_PRINT_UTF8 +# define print_int kit_print_int +# define print_float kit_print_float +# define print_esckit_print_esc +#endif + +#endif diff --git a/source/kit/process.h b/source/kit/process.h index f0aa200..9ee7ccf 100644 --- a/source/kit/process.h +++ b/source/kit/process.h @@ -20,11 +20,13 @@ enum { KIT_PROCESS_NO_ARGUMENTS = 1, KIT_PROCESS_NO_ENVIRONMENT = (1 << 1), KIT_PROCESS_NO_PIPES = (1 << 2), + KIT_PROCESS_FORK = (1 << 3), }; typedef struct { s32 status; u8 exit_code; + b8 current_is_forked; #if !defined(_WIN32) || defined(__CYGWIN__) b8 _ready; b8 _running; diff --git a/source/kit/process.posix.c b/source/kit/process.posix.c index b4039e6..961f058 100644 --- a/source/kit/process.posix.c +++ b/source/kit/process.posix.c @@ -8,10 +8,17 @@ # include # include -char *kit_process_argv_null_[] = { "", NULL }; -char *kit_process_env_null_[] = { NULL }; +static char *kit_process_argv_null_[] = { "", NULL }; +static char *kit_process_env_null_[] = { NULL }; -char **kit_init_argv_(kit_process_args_t args, u32 flags) { +static char *kit_process_str_(kit_str_t s) { + // FIXME + // + + return BS(s); +} + +static char **kit_init_argv_(kit_process_args_t args, u32 flags) { // TODO // @@ -21,7 +28,7 @@ char **kit_init_argv_(kit_process_args_t args, u32 flags) { return NULL; } -char **kit_init_envp_(kit_process_env_t env, u32 flags) { +static char **kit_init_envp_(kit_process_env_t env, u32 flags) { // TODO // @@ -91,11 +98,6 @@ s32 kit_process_init(kit_process_t *p, kit_process_info_t info) { pid_t id = fork(); - // NOTE - // We can safely use BS because there's only one thread after - // fork. - // - switch (id) { case -1: return KIT_ERROR_FORK_FAILED; @@ -103,6 +105,9 @@ s32 kit_process_init(kit_process_t *p, kit_process_info_t info) { // Child process // + p->status = KIT_OK; + p->current_is_forked = 1; + if ((info.flags & KIT_PROCESS_NO_PIPES) == 0) { // Redirect IO if (dup2(pipe_in[0], STDIN_FILENO) == -1 || @@ -129,26 +134,31 @@ s32 kit_process_init(kit_process_t *p, kit_process_info_t info) { // Change working directory if (info.working_directory.size != 0 && - chdir(BS(info.working_directory)) == -1) { + chdir(kit_process_str_(info.working_directory)) == -1) { assert(0); return KIT_ERROR_CHDIR_FAILED; } - execve(BS(info.file_name), - kit_init_argv_(info.command_line, info.flags), - kit_init_envp_(info.environment, info.flags)); - // Doesn't return on success + if ((info.flags & KIT_PROCESS_FORK) == 0) { + execve(kit_process_str_(info.file_name), + kit_init_argv_(info.command_line, info.flags), + kit_init_envp_(info.environment, info.flags)); + // Doesn't return on success + + return KIT_ERROR_EXECVE_FAILED; + } - return KIT_ERROR_EXECVE_FAILED; + return KIT_OK; default: // Parent process // - p->status = KIT_OK; - p->_ready = 1; - p->_running = 1; - p->_id = id; + p->status = KIT_OK; + p->current_is_forked = 0; + p->_ready = 1; + p->_running = 1; + p->_id = id; if ((info.flags & KIT_PROCESS_NO_PIPES) == 0) { p->_stdin = pipe_in[1]; diff --git a/source/kit/string_builder.h b/source/kit/string_builder.h index 2cca27a..5cc12ee 100644 --- a/source/kit/string_builder.h +++ b/source/kit/string_builder.h @@ -23,7 +23,11 @@ typedef KIT_DA(char) kit_str_builder_t; static kit_str_builder_t kit_str_build(kit_str_t s, kit_allocator_t *alloc) { + assert(s.size >= 0 && (s.size == 0 || s.values != NULL)); kit_str_builder_t builder; + memset(&builder, 0, sizeof builder); + if (s.size < 0 || (s.size != 0 && s.values == NULL)) + return builder; KIT_DA_INIT(builder, s.size, alloc); assert(builder.size == s.size); if (builder.size == s.size) @@ -31,6 +35,18 @@ static kit_str_builder_t kit_str_build(kit_str_t s, return builder; } +static kit_str_builder_t kit_substr_build(kit_str_t s, i64 index, + i64 size, + kit_allocator_t *alloc) { + assert(index + size <= s.size); + if (index + size > s.size) { + kit_str_builder_t builder; + memset(&builder, 0, sizeof builder); + return builder; + } + return kit_str_build(kit_str(size, s.values + index), alloc); +} + static s32 kit_str_append(kit_str_builder_t *a, kit_str_t b) { assert(a != NULL); if (a == NULL) @@ -45,6 +61,38 @@ static s32 kit_str_append(kit_str_builder_t *a, kit_str_t b) { return KIT_OK; } +static s32 kit_str_insert(kit_str_builder_t *a, i64 index, + kit_str_t b) { + assert(a != NULL && index >= 0 && index <= a->size); + if (a == NULL || index < 0 || index > a->size) + return KIT_ERROR_INVALID_ARGUMENT; + if (b.size <= 0) + return KIT_OK; + i64 n = a->size; + KIT_DA_RESIZE(*a, n + b.size); + if (a->size != n + b.size) + return KIT_ERROR_BAD_ALLOC; + if (index < n) + memmove(a->values + (index + b.size), a->values + index, + n - index); + memcpy(a->values + index, b.values, b.size); + return KIT_OK; +} + +static s32 kit_str_erase(kit_str_builder_t *a, i64 index, i64 size) { + assert(a != NULL && index >= 0 && size >= 0 && + index + size <= a->size); + if (a == NULL || index < 0 || size < 0 || index + size > a->size) + return KIT_ERROR_INVALID_ARGUMENT; + if (size <= 0) + return KIT_OK; + if (index + size < a->size) + memmove(a->values + index, a->values + (index + size), + a->size - index - size); + KIT_DA_RESIZE(*a, a->size - size); + return KIT_OK; +} + #ifdef __GNUC__ # pragma GCC pop_options # pragma GCC diagnostic pop @@ -57,7 +105,10 @@ static s32 kit_str_append(kit_str_builder_t *a, kit_str_t b) { #ifndef KIT_DISABLE_SHORT_NAMES # define str_builder_t kit_str_builder_t # define str_build kit_str_build +# define substr_build kit_substr_build # define str_append kit_str_append +# define str_insert kit_str_insert +# define str_erase kit_str_erase #endif #endif diff --git a/source/kit/string_ref.h b/source/kit/string_ref.h index 38ade80..8e76d06 100644 --- a/source/kit/string_ref.h +++ b/source/kit/string_ref.h @@ -3,6 +3,7 @@ #include "array_ref.h" +#include #include #ifdef __cplusplus @@ -24,6 +25,68 @@ static kit_str_t kit_str(i64 size, char const *static_string) { return s; } +enum { + KIT_STR_NOT_FOUND = -1, +}; + +static i64 kit_str_find(kit_str_t a, kit_str_t b) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + for (i64 index = 0; index + b.size <= a.size; index++) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) + return index; + return -1; +} + +static i64 kit_str_find_back(kit_str_t a, kit_str_t b) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + for (i64 index = a.size - b.size; index >= 0; index--) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) + return index; + return -1; +} + +static i64 kit_str_find_n(kit_str_t a, kit_str_t b, i64 n) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + i64 count = 0; + for (i64 index = 0; index + b.size <= a.size; index++) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) { + if (count == n) + return index; + else + count++; + } + return -1; +} + +static i64 kit_str_find_back_n(kit_str_t a, kit_str_t b, i64 n) { + assert(a.size >= 0 && (a.size == 0 || a.values != NULL) && + b.size >= 0 && (b.size == 0 || b.values != NULL)); + if (a.size < 0 || (a.size != 0 && a.values == NULL) || b.size < 0 || + (b.size != 0 && b.values == NULL)) + return -1; + i64 count = 0; + for (i64 index = a.size - b.size; index >= 0; index--) + if (KIT_AR_EQUAL(kit_str(b.size, a.values + index), b)) { + if (count == n) + return index; + else + count++; + } + return -1; +} + // Make a barbarian string for C standard library functions. // Not thread safe. // Use with caution. @@ -57,9 +120,13 @@ static char *kit_make_bs(kit_str_t s) { #ifndef KIT_DISABLE_SHORT_NAMES # define BS(...) kit_make_bs(KIT_WRAP_STR(__VA_ARGS__)) - # define str_t kit_str_t - +# define str kit_str +# define str_find kit_str_find +# define str_find_back kit_str_find_back +# define str_find_n kit_str_find_n +# define str_find_back_n kit_str_find_back_n +# define STR_NOT_FOUND KIT_STR_NOT_FOUND # define SZ KIT_SZ # define WRAP_BS KIT_WRAP_BS # define WRAP_STR KIT_WRAP_STR diff --git a/source/kit/utf8.h b/source/kit/utf8.h new file mode 100644 index 0000000..d053224 --- /dev/null +++ b/source/kit/utf8.h @@ -0,0 +1,47 @@ +#ifndef KIT_UTF8_H +#define KIT_UTF8_H + +#include "string_builder.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-function" +# pragma GCC diagnostic ignored "-Wunknown-pragmas" +# pragma GCC push_options +# pragma GCC optimize("O3") +#endif + +static s32 kit_utf8_count(kit_str_t s, i64 *count) { + return KIT_ERROR_NOT_IMPLEMENTED; +} + +static s32 kit_utf8_offset(kit_str_t s, i64 count, i64 *offset) { + return KIT_ERROR_NOT_IMPLEMENTED; +} + +static s32 kit_utf8_decode(kit_str_t s, i64 offset, i64 *size, + c32 *value) { + return KIT_ERROR_NOT_IMPLEMENTED; +} + +static s32 kit_utf8_encode(kit_str_builder_t *s, c32 value) { + return KIT_ERROR_NOT_IMPLEMENTED; +} + +#if defined(__GNUC__) || defined(__clang__) +# pragma GCC pop_options +# pragma GCC diagnostic pop +#endif + +#ifdef __cplusplus +} +#endif + +#ifndef KIT_DISABLE_SHORT_NAMES +#endif + +#endif -- cgit v1.2.3