From de65adbc1b2d1b3efdbe6a023bb7435f84b2f3a7 Mon Sep 17 00:00:00 2001 From: nodist Date: Sat, 3 Oct 2026 08:50:07 -0400 Subject: redesign --- include/README | 9 -- include/kpl.h | 39 -------- include/kpl/code.h | 25 ------ include/kpl/color.h | 119 ------------------------- include/kpl/io.h | 25 ------ include/kpl/macro.h | 15 ---- include/kpl/process.h | 39 -------- include/kpl/queue.h | 53 ----------- include/kpl/system.h | 21 ----- include/kpl/type.h | 53 ----------- include/kpl_test.h | 45 ---------- source/README | 17 ---- source/config.c | 242 -------------------------------------------------- source/kpl.c | 20 ----- source/queue.c | 91 ------------------- test/README | 62 ------------- test/config.c | 51 ----------- test/queue.c | 96 -------------------- test/test.c | 151 ------------------------------- 19 files changed, 1173 deletions(-) delete mode 100644 include/README delete mode 100644 include/kpl.h delete mode 100644 include/kpl/code.h delete mode 100644 include/kpl/color.h delete mode 100644 include/kpl/io.h delete mode 100644 include/kpl/macro.h delete mode 100644 include/kpl/process.h delete mode 100644 include/kpl/queue.h delete mode 100644 include/kpl/system.h delete mode 100644 include/kpl/type.h delete mode 100644 include/kpl_test.h delete mode 100644 source/README delete mode 100644 source/config.c delete mode 100644 source/kpl.c delete mode 100644 source/queue.c delete mode 100644 test/README delete mode 100644 test/config.c delete mode 100644 test/queue.c delete mode 100644 test/test.c diff --git a/include/README b/include/README deleted file mode 100644 index b182099..0000000 --- a/include/README +++ /dev/null @@ -1,9 +0,0 @@ -Headers - ---- - -Complier Flags: - -KPL_COLOR_OFF # Turn off colored pretty printing - ---- diff --git a/include/kpl.h b/include/kpl.h deleted file mode 100644 index 833c18b..0000000 --- a/include/kpl.h +++ /dev/null @@ -1,39 +0,0 @@ - -#pragma once - -#define KPL_VERSION "0.0.0" - -// All headers in one file for including - -#include "kpl/queue.h" -#include "kpl/io.h" -#include "kpl/process.h" -#include "kpl/code.h" - -typedef enum : uint32_t { - KPL_CONFIG_FLAG_EVAL = 1 << 0, - KPL_CONFIG_FLAG_REPL = 1 << 1 -} kpl_config_flags; - -typedef struct { - uint32_t flags; - int32_t argc, main_module_arg_index; - const char **argv, *module_extension, *version; - kpl_config_io io; - kpl_config_thread thread; - kpl_config_code code; -} kpl_config; - -void kpl_config_init(kpl_config *config); - -bool kpl_config_valid_module_exension(kpl_config *config, const char *module_name); - -int32_t kpl_config_parse_args(kpl_config *config, const int32_t argc, const char *argv[]); - -typedef struct _kpl_env { - kpl_config config; - _Atomic ssize_t total_priority; - kpl_io io; - kpl_process process; - kpl_code code; -} kpl_env; diff --git a/include/kpl/code.h b/include/kpl/code.h deleted file mode 100644 index 1902c42..0000000 --- a/include/kpl/code.h +++ /dev/null @@ -1,25 +0,0 @@ - -#pragma once - -// Queues and trees for code life cycle - -#include "kpl/queue.h" - -typedef enum : int8_t { - KPL_CONFIG_CODE_QUEUE_POW2_MIN = 4, - KPL_CONFIG_CODE_QUEUE_POW2_DEFAULT = 7, - KPL_CONFIG_CODE_QUEUE_POW2_MAX = 10, -} kpl_config_code_queue_pow; - -typedef struct { - int8_t queue_pow2; -} kpl_config_code; - -// TODO namespace tree - -// TODO module tree - -typedef struct { - kpl_config_code *config_code; - kpl_ring_queue code_queue; -} kpl_code; diff --git a/include/kpl/color.h b/include/kpl/color.h deleted file mode 100644 index 1f77dcb..0000000 --- a/include/kpl/color.h +++ /dev/null @@ -1,119 +0,0 @@ - -#pragma once - -// C string pretty printing macros - -#define KPL_COLOR_CONCAT(COLOR) KPL_COLOR_ ## COLOR - -#ifndef KPL_COLOR_OFF - -#define KPL_COLOR(A) "\e[" KPL_COLOR_CONCAT(A) "m" -#define KPL_COLOR2(A, B) "\e[" KPL_COLOR_CONCAT(A) ";" KPL_COLOR_CONCAT(B) "m" -#define KPL_COLOR3(A, B, C) "\e[" KPL_COLOR_CONCAT(A) ";" KPL_COLOR_CONCAT(B) ";" KPL_COLOR_CONCAT(C) "m" - -#define KPL_COLOR_RESET "0" -#define KPL_COLOR_BOLD "1" -#define KPL_COLOR_FAINT "2" -#define KPL_COLOR_ITALIC "3" -#define KPL_COLOR_UNDERLINE "4" -#define KPL_COLOR_BLINK "5" -#define KPL_COLOR_REVERSE "7" -#define KPL_COLOR_HIDDEN "8" -#define KPL_COLOR_RESET_BOLD "21" -#define KPL_COLOR_RESET_FAINT "22" -#define KPL_COLOR_RESET_ITALIC "23" -#define KPL_COLOR_RESET_UNDERLINE "24" -#define KPL_COLOR_RESET_BLINK "25" -#define KPL_COLOR_RESET_REVERSE "27" -#define KPL_COLOR_RESET_HIDDEN "28" -#define KPL_COLOR_BLACK "30" -#define KPL_COLOR_RED "31" -#define KPL_COLOR_GREEN "32" -#define KPL_COLOR_YELLOW "33" -#define KPL_COLOR_BLUE "34" -#define KPL_COLOR_MAGENTA "35" -#define KPL_COLOR_CYAN "36" -#define KPL_COLOR_GREY "37" -#define KPL_COLOR_DEFAULT "39" -#define KPL_COLOR_BG_BLACK "30" -#define KPL_COLOR_BG_RED "41" -#define KPL_COLOR_BG_GREEN "42" -#define KPL_COLOR_BG_YELLOW "43" -#define KPL_COLOR_BG_BLUE "44" -#define KPL_COLOR_BG_MAGENTA "45" -#define KPL_COLOR_BG_CYAN "46" -#define KPL_COLOR_BG_GREY "47" -#define KPL_COLOR_DARK_GREY "90" -#define KPL_COLOR_LIGHT_RED "91" -#define KPL_COLOR_LIGHT_GREEN "92" -#define KPL_COLOR_LIGHT_YELLOW "93" -#define KPL_COLOR_LIGHT_BLUE "94" -#define KPL_COLOR_LIGHT_MAGENTA "95" -#define KPL_COLOR_LIGHT_CYAN "96" -#define KPL_COLOR_WHITE "97" -#define KPL_COLOR_BG_DARK_GREY "100" -#define KPL_COLOR_BG_LIGHT_RED "101" -#define KPL_COLOR_BG_LIGHT_GREEN "102" -#define KPL_COLOR_BG_LIGHT_YELLOW "103" -#define KPL_COLOR_BG_LIGHT_BLUE "104" -#define KPL_COLOR_BG_LIGHT_MAGENTA "105" -#define KPL_COLOR_BG_LIGHT_CYAN "106" -#define KPL_COLOR_BG_WHITE "107" - -#else - -#define KPL_COLOR(A) KPL_COLOR_CONCAT(A) -#define KPL_COLOR2(A, B) KPL_COLOR_CONCAT(A) KPL_COLOR_CONCAT(B) -#define KPL_COLOR3(A, B, C) KPL_COLOR_CONCAT(A) KPL_COLOR_CONCAT(B) KPL_COLOR_CONCAT(C) - - -#define KPL_COLOR_RESET "" -#define KPL_COLOR_BOLD "" -#define KPL_COLOR_FAINT "" -#define KPL_COLOR_ITALIC "" -#define KPL_COLOR_UNDERLINE "" -#define KPL_COLOR_BLINK "" -#define KPL_COLOR_REVERSE "" -#define KPL_COLOR_HIDDEN "" -#define KPL_COLOR_RESET_BOLD "" -#define KPL_COLOR_RESET_FAINT "" -#define KPL_COLOR_RESET_ITALIC "" -#define KPL_COLOR_RESET_UNDERLINE "" -#define KPL_COLOR_RESET_BLINK "" -#define KPL_COLOR_RESET_REVERSE "" -#define KPL_COLOR_RESET_HIDDEN "" -#define KPL_COLOR_BLACK "" -#define KPL_COLOR_RED "" -#define KPL_COLOR_GREEN "" -#define KPL_COLOR_YELLOW "" -#define KPL_COLOR_BLUE "" -#define KPL_COLOR_MAGENTA "" -#define KPL_COLOR_CYAN "" -#define KPL_COLOR_GREY "" -#define KPL_COLOR_DEFAULT "" -#define KPL_COLOR_BG_BLACK "" -#define KPL_COLOR_BG_RED "" -#define KPL_COLOR_BG_GREEN "" -#define KPL_COLOR_BG_YELLOW "" -#define KPL_COLOR_BG_BLUE "" -#define KPL_COLOR_BG_MAGENTA "" -#define KPL_COLOR_BG_CYAN "" -#define KPL_COLOR_BG_GREY "" -#define KPL_COLOR_DARK_GREY "" -#define KPL_COLOR_LIGHT_RED "" -#define KPL_COLOR_LIGHT_GREEN "" -#define KPL_COLOR_LIGHT_YELLOW "" -#define KPL_COLOR_LIGHT_BLUE "" -#define KPL_COLOR_LIGHT_MAGENTA "" -#define KPL_COLOR_LIGHT_CYAN "" -#define KPL_COLOR_WHITE "" -#define KPL_COLOR_BG_DARK_GREY "" -#define KPL_COLOR_BG_LIGHT_RED "" -#define KPL_COLOR_BG_LIGHT_GREEN "" -#define KPL_COLOR_BG_LIGHT_YELLOW "" -#define KPL_COLOR_BG_LIGHT_BLUE "" -#define KPL_COLOR_BG_LIGHT_MAGENTA "" -#define KPL_COLOR_BG_LIGHT_CYAN "" -#define KPL_COLOR_BG_WHITE "" - -#endif diff --git a/include/kpl/io.h b/include/kpl/io.h deleted file mode 100644 index a1b4b3f..0000000 --- a/include/kpl/io.h +++ /dev/null @@ -1,25 +0,0 @@ - -#pragma once - -// Io through io_uring - -#include "kpl/macro.h" - -typedef enum : int8_t { - KPL_CONFIG_IO_QUEUE_POW2_MIN = 4, - KPL_CONFIG_IO_QUEUE_POW2_DEFAULT = 10, - KPL_CONFIG_IO_QUEUE_POW2_MAX = 16 -} kpl_io_queue_pow_options; - -typedef struct { - int8_t queue_pow2; -} kpl_config_io; - -typedef struct { - kpl_config_io *config_io; - // TODO -} kpl_io; - -bool kpl_io_init(kpl_io *io); - -void kpl_io_free(kpl_io *io); diff --git a/include/kpl/macro.h b/include/kpl/macro.h deleted file mode 100644 index e0b59e5..0000000 --- a/include/kpl/macro.h +++ /dev/null @@ -1,15 +0,0 @@ - -#pragma once - -// KPL specific macros - -#include "color.h" -#include "type.h" - -#define _KPL_PRINT_(MESSAGE_COLOR, MESSAGE) printf(KPL_COLOR2(BOLD, MESSAGE_COLOR) "TODO " KPL_COLOR(RESET) KPL_COLOR(BOLD) "%s" KPL_COLOR(RESET) ":" KPL_COLOR(LIGHT_BLUE) "%s" KPL_COLOR(RESET) ":" KPL_COLOR(LIGHT_MAGENTA) "%d" KPL_COLOR(RESET) "::" KPL_COLOR(MESSAGE_COLOR) "%s\n" KPL_COLOR(RESET), __FILE__, __FUNCTION__, __LINE__, MESSAGE) - -#define KPL_PRINT_TODO(MESSAGE) _KPL_PRINT_(LIGHT_YELLOW, MESSAGE) - -#define KPL_PRINT_ERROR(MESSAGE) _KPL_PRINT_(LIGHT_RED, MESSAGE) - -#define KPL_PAGE_SIZE_ROUND(SIZE) ((SIZE + (getpagesize() - 1)) & ~(getpagesize() - 1)) diff --git a/include/kpl/process.h b/include/kpl/process.h deleted file mode 100644 index 528365a..0000000 --- a/include/kpl/process.h +++ /dev/null @@ -1,39 +0,0 @@ - -#pragma once - -// Kpl threads, allocators, atomic queues and garbage collection - -#include "kpl/queue.h" - -typedef enum : int8_t { - KPL_CONFIG_THREAD_COUNT_AFFINITY = -1, - KPL_CONFIG_THREAD_COUNT_MAX = 127 -} kpl_config_thread_count; - -typedef enum : uint8_t { - KPL_CONFIG_THREAD_RING_POOL_COUNT = 28, - KPL_CONFIG_THREAD_RING_POOL_MIN_OBJECT_SIZE_POW2 = 5, - KPL_CONFIG_THREAD_RING_POOL_MAX_OBJECT_SIZE_POW2 = 27, - KPL_CONFIG_THREAD_RING_POOL_MIN_RING_SIZE_POW2 = 6, - KPL_CONFIG_THREAD_RING_POOL_MAX_RING_SIZE_POW2 = 20 -} kpl_config_thread_ring_pool; - -typedef struct { - int8_t count, ring_pool_entries_pow2[KPL_CONFIG_THREAD_RING_POOL_COUNT]; -} kpl_config_thread; - -typedef struct { - int32_t thread_id; - _Atomic ssize_t priority; - kpl_env *env; - kpl_task_queue task_queue; - // TODO - sem_t sem; - pthread_t pthread; -} kpl_thread; - -typedef struct { - kpl_config_thread *config_thread; - kpl_thread *threads; - kpl_ring_queue memory_pool[KPL_CONFIG_THREAD_RING_POOL_COUNT]; -} kpl_process; diff --git a/include/kpl/queue.h b/include/kpl/queue.h deleted file mode 100644 index 0107434..0000000 --- a/include/kpl/queue.h +++ /dev/null @@ -1,53 +0,0 @@ - -#pragma once - -// KPL atomic queues - -#include "kpl/macro.h" - -typedef struct { - kpl_task *_Atomic head, *tail; - struct { - kpl_task *_Atomic next; - } dummy; -} kpl_task_queue; - -inline void kpl_task_queue_init(kpl_task_queue *task_queue) { - __atomic_store_n(&task_queue->dummy.next, NULL, __ATOMIC_RELAXED); - __atomic_store_n(&task_queue->head, &task_queue->dummy, __ATOMIC_RELAXED); - task_queue->tail = (kpl_task*) &task_queue->dummy; -} - -inline void kpl_task_queue_add(kpl_task_queue *task_queue, kpl_task *task) { - __atomic_store_n(&task->next, NULL, __ATOMIC_RELAXED); - kpl_task *head = __atomic_exchange_n(&task_queue->head, task, __ATOMIC_SEQ_CST); - __atomic_store_n(&head->next, task, __ATOMIC_RELEASE); -} - -kpl_task *kpl_task_queue_next(kpl_task_queue *task_queue); - -typedef enum : int8_t { - KPL_RING_QUEUE_MIN_POW2 = 4, - KPL_RING_QUEUE_MAX_POW2 = 30 -} kpl_ring_queue_pow2_sizes; - -typedef struct { - _Atomic ssize_t index; - void *data; -} kpl_ring_queue_item; - -typedef struct { - size_t mmap_size, items_mask; - _Atomic ssize_t head_index, tail_index; - kpl_ring_queue_item *items; -} kpl_ring_queue; - -bool kpl_ring_queue_init(kpl_ring_queue *ring_queue, int8_t size_pow2); - -inline void kpl_ring_queue_free(kpl_ring_queue *ring_queue) { - munmap(ring_queue->items, ring_queue->mmap_size); -} - -bool kpl_ring_queue_add(kpl_ring_queue *ring_queue, void *data); - -void *kpl_ring_queue_next(kpl_ring_queue *ring_queue); diff --git a/include/kpl/system.h b/include/kpl/system.h deleted file mode 100644 index 2d1ec48..0000000 --- a/include/kpl/system.h +++ /dev/null @@ -1,21 +0,0 @@ - -#pragma once - -// System headers - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/include/kpl/type.h b/include/kpl/type.h deleted file mode 100644 index 5003cf0..0000000 --- a/include/kpl/type.h +++ /dev/null @@ -1,53 +0,0 @@ - -#pragma once - -// KPL specific types - -#include "system.h" - -typedef enum : int32_t { - KPL_EXIT_CODE_SUCCESS = 0, - KPL_EXIT_CODE_ERROR = 1, - KPL_EXIT_CODE_HELP = 2 -} kpl_exit_code; - -typedef uint8_t kpl_utf8[4]; - -typedef union { - uint8_t u8; - int8_t i8; - uint16_t u16; - int16_t i16; - uint32_t u32; - int32_t i32; - uint64_t u64; - int64_t i64; - kpl_utf8 utf8; - float f32; - double f64; - void *ptr; -} kpl_value; - -typedef struct { - kpl_value value; - int64_t tag; -} kpl_result; - -typedef struct _kpl_task kpl_task; - -typedef struct _kpl_env kpl_env; - -typedef void kpl_task_fn(kpl_task *task, kpl_env *env); - -typedef struct _kpl_task { - struct _kpl_task *_Atomic next, *join; - kpl_task_fn *task_fn; - int32_t io_res; - uint32_t io_flags; - int32_t thread_id; - _Atomic bool canceled __attribute__((aligned(4))), join_ready __attribute__((aligned(8))); - kpl_result result; - // TODO TASK ARGUMENTS -} kpl_task; - - diff --git a/include/kpl_test.h b/include/kpl_test.h deleted file mode 100644 index c1645e2..0000000 --- a/include/kpl_test.h +++ /dev/null @@ -1,45 +0,0 @@ - -#pragma once - -// KPL testing framework - -#include "kpl.h" - -typedef struct _kpl_test kpl_test; - -typedef void kpl_test_function(__attribute__((unused)) kpl_test *_test); - -typedef struct _kpl_test { - int32_t error_line_number; // -1 for no error - char *file_name, *test_name, *error_message; - kpl_test_function *test_function; - struct _kpl_test *next_test; -} kpl_test; - -void kpl_test_add(kpl_test *_test); - -#define _KPL_TEST_FN_NAME(NAME) _kpl_test_function_ ## NAME - -#define _KPL_TEST_FN(NAME) static void _KPL_TEST_FN_NAME(NAME)(__attribute__((unused)) kpl_test *_test) - -#define KPL_TEST(NAME) _KPL_TEST_FN(NAME); \ -static void __attribute__((constructor)) _kpl_test_constructor_ ## NAME(void) { \ - static kpl_test _test = { \ - .error_line_number = -1, \ - .file_name = __FILE__, .test_name = #NAME, .error_message = NULL, \ - .test_function = _KPL_TEST_FN_NAME(NAME), \ - .next_test = NULL \ - }; \ - kpl_test_add(&_test); \ -} \ -_KPL_TEST_FN(NAME) - -#define KPL_FAIL(MESSAGE) do { \ - _test->error_line_number = __LINE__; \ - _test->error_message = MESSAGE; \ -} while (0) - -#define KPL_ASSERT(CONDITION, MESSAGE) do { \ - if (!(CONDITION)) \ - KPL_FAIL(#CONDITION "; " MESSAGE); \ -} while (0) diff --git a/source/README b/source/README deleted file mode 100644 index 0ec82e2..0000000 --- a/source/README +++ /dev/null @@ -1,17 +0,0 @@ -Source - ---- - -Includes: - -#include "kpl.h" - -This is the only header for any C file in the source folder - ---- - -Complier Flags: - -KPL_MAIN # For standalone exec, off for testing or including in other code - ---- diff --git a/source/config.c b/source/config.c deleted file mode 100644 index 31de7d4..0000000 --- a/source/config.c +++ /dev/null @@ -1,242 +0,0 @@ - -#include "kpl.h" - -static const kpl_config default_config = { - .argc = -1, .main_module_arg_index = -1, .version = KPL_VERSION, - .argv = NULL, .module_extension = ".kpl", - .flags = 0, - .io = { - .queue_pow2 = KPL_CONFIG_IO_QUEUE_POW2_DEFAULT - }, - .thread = { - .count = KPL_CONFIG_THREAD_COUNT_AFFINITY, - .ring_pool_entries_pow2 = { - [0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 13, - [6] = 13, [7] = 13, [8] = 13, [9] = 13, [10] = 13, [11] = 13, - [12] = 13, [13] = 13, [14] = 13, [15] = 13, [16] = 13, [17] = 13, - [18] = 13, [19] = 13, [20] = 13, [21] = 13, [22] = 13, [23] = 13, - [24] = 13, [25] = 13, [26] = 13, [27] = 13 - } - }, - .code = { - .queue_pow2 = KPL_CONFIG_CODE_QUEUE_POW2_DEFAULT - } -}; - -void kpl_config_init(kpl_config *config) { - memcpy(config, &default_config, sizeof(kpl_config)); -} - -typedef int32_t kpl_arg_match_fn(const char *match_str, const int32_t match_str_index, kpl_config *config); - -typedef struct { - const char *match_str, *help_message; - kpl_arg_match_fn *arg_match_fn; -} kpl_arg_match; - - -static int32_t kpl_arg_match_module_extension(const char *match_str, const int32_t match_str_index, kpl_config *config) { - config->module_extension = match_str + match_str_index; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_io_queue_pow2(const char *match_str, const int32_t match_str_index, kpl_config *config) { - int32_t queue_pow2 = atoi(match_str + match_str_index); - if (queue_pow2 < KPL_CONFIG_IO_QUEUE_POW2_MIN || queue_pow2 > KPL_CONFIG_IO_QUEUE_POW2_MAX) - return KPL_EXIT_CODE_ERROR; - config->io.queue_pow2 = queue_pow2; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_thread_count(const char *match_str, const int32_t match_str_index, kpl_config *config) { - int32_t thread_count = atoi(match_str + match_str_index); - if (thread_count <= 0 || thread_count > KPL_CONFIG_THREAD_COUNT_MAX) - return KPL_EXIT_CODE_ERROR; - config->thread.count = thread_count; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_memory_pool_pow2(const char *match_str, const int32_t match_str_index, kpl_config *config) { - char *endptr; - int32_t object_size_pow2 = strtol(match_str + match_str_index, &endptr, 10); - if (object_size_pow2 < KPL_CONFIG_THREAD_RING_POOL_MIN_OBJECT_SIZE_POW2 || - object_size_pow2 > KPL_CONFIG_THREAD_RING_POOL_MAX_OBJECT_SIZE_POW2) - return KPL_EXIT_CODE_ERROR; - while (*endptr && !isdigit(*endptr)) - endptr++; - int32_t entry_size_pow2 = strtol(endptr, NULL, 10); - if (entry_size_pow2 < KPL_CONFIG_THREAD_RING_POOL_MIN_RING_SIZE_POW2 || - entry_size_pow2 > KPL_CONFIG_THREAD_RING_POOL_MAX_RING_SIZE_POW2) - return KPL_EXIT_CODE_ERROR; - config->thread.ring_pool_entries_pow2[object_size_pow2] = entry_size_pow2; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_code_queue_pow2(const char *match_str, const int32_t match_str_index, kpl_config *config) { - int32_t queue_pow2 = atoi(match_str + match_str_index); - if (queue_pow2 < KPL_CONFIG_CODE_QUEUE_POW2_MIN || queue_pow2 > KPL_CONFIG_CODE_QUEUE_POW2_MAX) - return KPL_EXIT_CODE_ERROR; - config->code.queue_pow2 = queue_pow2; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_eval(const char *match_str, const int32_t match_str_index, kpl_config *config) { - (void) match_str; - (void) match_str_index; - config->flags |= KPL_CONFIG_FLAG_EVAL; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_repl(const char *match_str, const int32_t match_str_index, kpl_config *config) { - (void) match_str; - (void) match_str_index; - config->flags |= KPL_CONFIG_FLAG_REPL; - return KPL_EXIT_CODE_SUCCESS; -} - -static int32_t kpl_arg_match_version(const char *match_str, const int32_t match_str_index, kpl_config *config) { - (void) match_str_index; - printf("\nKevin's Programming Language (" KPL_COLOR(LIGHT_BLUE) "KPL" KPL_COLOR(RESET) - "), Version: " KPL_COLOR(LIGHT_GREEN) "%s\n" KPL_COLOR(RESET), - config->version); - if (match_str) - putchar('\n'); - return KPL_EXIT_CODE_HELP; -} - -static int32_t kpl_arg_match_help(const char *match_str, const int32_t match_str_index, kpl_config *config); - -static kpl_arg_match arg_match_array[] = { - { - .match_str = "--module-extension=", - .help_message="[WORD]; Change the module extension for imports (default .kpl)", - .arg_match_fn = kpl_arg_match_module_extension - }, - { - .match_str = "--io-queue-pow2=", - .help_message = "[NUMBER]; Power of 2 for calculating the size of the io_uring queue", - .arg_match_fn = kpl_arg_match_io_queue_pow2 - }, - { - .match_str = "--thread-count=", - .help_message = "[NUMBER]; Number of running threads, minimum is 1", - .arg_match_fn = kpl_arg_match_thread_count - }, - { - .match_str = "--memory-pool-pow2=", - .help_message = "[NUMBER1],[NUMBER2]; Set the memory pool [NUMBER1] to have 2 ** [NUMBER2] entires", - .arg_match_fn = kpl_arg_match_memory_pool_pow2 - }, - { - .match_str = "--code-queue-pow2=", - .help_message = "[NUMBER]; Power of 2 for calculating the size of the code queue", - .arg_match_fn = kpl_arg_match_code_queue_pow2 - }, - { - .match_str = "--eval", - .help_message = " [STRING...]; Evaluate next argument(s) as modules", - .arg_match_fn = kpl_arg_match_eval - }, - { - .match_str = "--repl", - .help_message = "; Start (R)ead, (E)valuate, (P)rint, (L)oop", - .arg_match_fn = kpl_arg_match_repl - }, - { - .match_str = "--version", - .help_message = "; Show version", - .arg_match_fn = kpl_arg_match_version - }, - { - .match_str = "--help", - .help_message = "; Show help", - .arg_match_fn = kpl_arg_match_help - }, - { .match_str = NULL, .help_message = NULL, .arg_match_fn = NULL } -}; - -static int32_t kpl_arg_match_help(const char *match_str, const int32_t match_str_index, kpl_config *config) { - (void) match_str; - (void) match_str_index; - kpl_arg_match_version(NULL, 0, config); - printf("\nUsage " KPL_COLOR(BOLD) "%s" KPL_COLOR(RESET) KPL_COLOR(WHITE) " [OPTIONS] [MODULE]" KPL_COLOR(RESET) - KPL_COLOR(BOLD) "%s\n\n" KPL_COLOR(RESET), config->argv[0], config->module_extension); - printf("Where " KPL_COLOR(WHITE) "[OPTIONS]" KPL_COLOR(RESET) " are:\n"); - const kpl_arg_match *match_array = arg_match_array; - while (match_array->match_str) { - printf(KPL_COLOR(LIGHT_YELLOW) "\t%s" KPL_COLOR(RESET) "%s\n", - match_array->match_str, match_array->help_message); - match_array++; - } - putchar('\n'); - return KPL_EXIT_CODE_HELP; -} - -static bool kpl_valid_match_str_index(const char *match_str_array, const char *match_str_arg, int32_t match_str_index) { - return match_str_array[match_str_index] && - match_str_array[match_str_index] == match_str_arg[match_str_index]; -} - -static bool kpl_valid_match_str(const char *match_str_array, const char *match_str_arg, int32_t match_str_index) { - return !match_str_array[match_str_index] && (!match_str_arg[match_str_index] || - (match_str_arg[match_str_index] && match_str_array[match_str_index - 1] == '=')); -} - -bool kpl_config_valid_module_exension(kpl_config *config, const char *module_name) { - size_t name_length = strlen(module_name), module_extension_length = strlen(config->module_extension); - return name_length > module_extension_length && - strcmp(module_name + name_length - module_extension_length, config->module_extension) == 0; -} - -int32_t kpl_config_parse_args(kpl_config *config, const int32_t argc, const char *argv[]) { - config->argc = argc; - config->argv = argv; - if (argc == 1) { - printf(KPL_COLOR(LIGHT_RED) "\nNo Module Specified\n" KPL_COLOR(RESET)); - return kpl_arg_match_help(NULL, 0, config); - } - int32_t arg_index = 1; - while (arg_index < argc && !config->flags) { - int32_t match_str_index = 0; - const char *match_str_arg = argv[arg_index]; - const kpl_arg_match *match_array = arg_match_array; - while (match_array->match_str) { - while (kpl_valid_match_str_index(match_array->match_str, match_str_arg, match_str_index)) - match_str_index++; - if (kpl_valid_match_str(match_array->match_str, match_str_arg, match_str_index)) { - int32_t exit_status = match_array->arg_match_fn(match_str_arg, match_str_index, config); - if (exit_status != KPL_EXIT_CODE_SUCCESS) { - if (exit_status == KPL_EXIT_CODE_ERROR) - printf(KPL_COLOR(LIGHT_RED) "\nInvalid Option: " KPL_COLOR(BOLD) "%s\n" KPL_COLOR(RESET), - match_str_arg); - return exit_status; - } - break; - } - match_str_index = 0; - match_array++; - } - if (!match_array->match_str) - break; - arg_index++; - } - config->main_module_arg_index = arg_index; - if (config->flags) { - if ((config->flags & KPL_CONFIG_FLAG_EVAL) && argc - arg_index < 1) { - printf(KPL_COLOR(LIGHT_RED) "\nInvalid EVAL\n" KPL_COLOR(RESET)); - return kpl_arg_match_help(NULL, 0, config); - } - if ((config->flags & KPL_CONFIG_FLAG_REPL) && argc != arg_index) { - printf(KPL_COLOR(LIGHT_RED) "\nInvalid REPL\n" KPL_COLOR(RESET)); - return kpl_arg_match_help(NULL, 0, config); - } - return KPL_EXIT_CODE_SUCCESS; - } - if (!kpl_config_valid_module_exension(config, argv[arg_index])) { - printf(KPL_COLOR(LIGHT_RED) "\nInvalid " KPL_COLOR(RESET) - KPL_COLOR(WHITE) "[OPTION]/[MODULE]: " KPL_COLOR(RESET) - KPL_COLOR2(BOLD, LIGHT_RED) "%s\n" KPL_COLOR(RESET), argv[arg_index]); - return kpl_arg_match_help(NULL, 0, config); - } - return KPL_EXIT_CODE_SUCCESS; -} diff --git a/source/kpl.c b/source/kpl.c deleted file mode 100644 index cc98b4b..0000000 --- a/source/kpl.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include "kpl.h" - -#ifdef KPL_MAIN -int32_t main(const int32_t argc, const char *argv[]) { - int32_t exit_status = KPL_EXIT_CODE_SUCCESS; - kpl_env env; - kpl_config_init(&env.config); - if ((exit_status = kpl_config_parse_args(&env.config, argc, argv))) - return exit_status; - KPL_PRINT_TODO("INIT KPL"); - if (env.config.flags & KPL_CONFIG_FLAG_EVAL) - KPL_PRINT_TODO("RUN EVAL"); - else if (env.config.flags & KPL_CONFIG_FLAG_REPL) - KPL_PRINT_TODO("RUN REPL"); - else - KPL_PRINT_TODO("RUN MODULE"); - return exit_status; -} -#endif diff --git a/source/queue.c b/source/queue.c deleted file mode 100644 index 350c4e2..0000000 --- a/source/queue.c +++ /dev/null @@ -1,91 +0,0 @@ - -#include "kpl.h" - -extern inline void kpl_task_queue_init(kpl_task_queue *task_queue); - -extern inline void kpl_task_queue_add(kpl_task_queue *task_queue, kpl_task *task); - -kpl_task *kpl_task_queue_next(kpl_task_queue *task_queue) { - kpl_task *task = NULL; - for (;;) { - kpl_task *tail = task_queue->tail, *next = __atomic_load_n(&tail->next, __ATOMIC_ACQUIRE); - if (tail == (kpl_task*) &task_queue->dummy) { - if (!next) - break; - tail = task_queue->tail = next; - next = __atomic_load_n(&tail->next, __ATOMIC_ACQUIRE); - } - if (!next) { - kpl_task *head = __atomic_load_n(&task_queue->head, __ATOMIC_ACQUIRE); - if (tail != head) - continue; - kpl_task_queue_add(task_queue, (kpl_task*) &task_queue->dummy); - next = __atomic_load_n(&tail->next, __ATOMIC_ACQUIRE); - } - if (next) { - task_queue->tail = next; - task = tail; - break; - } - } - if (task) - __atomic_store_n(&task->next, NULL, __ATOMIC_RELAXED); - return task; -} - -bool kpl_ring_queue_init(kpl_ring_queue *ring_queue, int8_t size_pow2) { - if (size_pow2 < KPL_RING_QUEUE_MIN_POW2 || size_pow2 > KPL_RING_QUEUE_MAX_POW2) - return false; - size_t size = 1L << size_pow2; - ring_queue->mmap_size = KPL_PAGE_SIZE_ROUND(sizeof(kpl_ring_queue_item) * size); - ring_queue->items = mmap(NULL, ring_queue->mmap_size, - PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - ring_queue->items_mask = size - 1; - __atomic_store_n(&ring_queue->head_index, 0, __ATOMIC_RELAXED); - __atomic_store_n(&ring_queue->tail_index, 0, __ATOMIC_RELAXED); - for (size_t index = 0; index < size; index++) - __atomic_store_n(&ring_queue->items[index].index, index, __ATOMIC_RELAXED); - return true; -} - -extern inline void kpl_ring_queue_free(kpl_ring_queue *ring_queue); - -bool kpl_ring_queue_add(kpl_ring_queue *ring_queue, void *data) { - for (;;) { - ssize_t tail_index = __atomic_load_n(&ring_queue->tail_index, __ATOMIC_RELAXED); - kpl_ring_queue_item *item = &ring_queue->items[tail_index & ring_queue->items_mask]; - ssize_t item_index = __atomic_load_n(&item->index, __ATOMIC_ACQUIRE), diff = item_index - tail_index; - if (diff > 0) - continue; - if (diff < 0) - break; - if (!__atomic_compare_exchange_n(&ring_queue->tail_index, &tail_index, tail_index + 1, true, - __ATOMIC_RELAXED, __ATOMIC_RELAXED)) - continue; - item->data = data; - __atomic_store_n(&item->index, tail_index + 1, __ATOMIC_RELEASE); - return true; - } - return false; -} - -void *kpl_ring_queue_next(kpl_ring_queue *ring_queue) { - for (;;) { - ssize_t head_index = __atomic_load_n(&ring_queue->head_index, __ATOMIC_RELAXED); - kpl_ring_queue_item *item = &ring_queue->items[head_index & ring_queue->items_mask]; - ssize_t item_index = __atomic_load_n(&item->index, __ATOMIC_ACQUIRE), - diff = item_index - (head_index + 1); - if (diff > 0) - continue; - if (diff < 0) - break; - if (!__atomic_compare_exchange_n(&ring_queue->head_index, &head_index, head_index + 1, true, - __ATOMIC_RELAXED, __ATOMIC_RELAXED)) - continue; - void *data = item->data; - item->data = NULL; - __atomic_store_n(&item->index, head_index + ring_queue->items_mask + 1, __ATOMIC_RELEASE); - return data; - } - return NULL; -} diff --git a/test/README b/test/README deleted file mode 100644 index f1c86df..0000000 --- a/test/README +++ /dev/null @@ -1,62 +0,0 @@ -Testing - ---- - -File Layout: - -The test files mirror the src files, so a function in src/file.c would have a test in test/file.c - ---- - -Includes: - -#include "kpl_test.h" - -This is the only include a .c file in the test folder needs - ---- - -Writing Tests: - -KPL_TEST(test_name) { - // TEST CODE -} - -Tests pass by default - ---- - -Asserting: - -KPL_ASSERT(CONDITION, FAIL_MESSAGE); - ---- - -Failing: - -KPL_FAIL(FAIL_MESSAGE); - ---- - -Building: - -make kpl_test # build test exec -make kpl_test_memory # build test exec with address, leak and undefined sanitizer -make kpl_test_thread # build test exec with thread sanitizer - -All objects need to be built with the same sanitizer and do not run valgrind when sanitizers are added - ---- - -Running: - -./kpl_test # Run all tests -./kpl_test NAME # Run test named NAME -./kpl_test NAME1 NAME2 ... # Run selected tests named NAM1 NAME2 ... -./kpl_test -h # Show help - ---- - -Compiler Flags: - ---- diff --git a/test/config.c b/test/config.c deleted file mode 100644 index 978e003..0000000 --- a/test/config.c +++ /dev/null @@ -1,51 +0,0 @@ - -#include "kpl_test.h" - -KPL_TEST(show_help) { - kpl_config config; - const int32_t argc = 2; - const char *argv[] = { "./kpl", "--help", "not_used" }; - kpl_config_init(&config); - int32_t code = kpl_config_parse_args(&config, argc, argv); - KPL_ASSERT(code == KPL_EXIT_CODE_HELP, "Invalid help exit code"); -} - -KPL_TEST(change_module_extension) { - kpl_config config; - const int32_t argc = 3; - const char *argv[] = { "./kpl", "--module-extension=.l", "./file.l" }; - kpl_config_init(&config); - int32_t code = kpl_config_parse_args(&config, argc, argv); - KPL_ASSERT(code == KPL_EXIT_CODE_SUCCESS, "Invalid exit code"); - KPL_ASSERT(strcmp(config.module_extension, ".l") == 0, "Invalid new module extension"); -} - -KPL_TEST(io_queue_pow2) { - kpl_config config; - const int32_t argc = 3; - const char *argv[] = { "./kpl", "--io-queue-pow2=14", "./file.kpl" }; - kpl_config_init(&config); - int32_t code = kpl_config_parse_args(&config, argc, argv); - KPL_ASSERT(code == KPL_EXIT_CODE_SUCCESS, "Invalid exit code"); - KPL_ASSERT(config.io.queue_pow2 == 14, "Invalid io queue power of two"); -} - -KPL_TEST(thread_count) { - kpl_config config; - const int32_t argc = 3; - const char *argv[] = { "./kpl", "--thread-count=1", "./file.kpl" }; - kpl_config_init(&config); - int32_t code = kpl_config_parse_args(&config, argc, argv); - KPL_ASSERT(code == KPL_EXIT_CODE_SUCCESS, "Invalid exit code"); - KPL_ASSERT(config.thread.count == 1, "Invalid thread count"); -} - -KPL_TEST(memory_pool_pow2) { - kpl_config config; - const int32_t argc = 3; - const char *argv[] = { "./kpl", "--memory-pool-pow2=6,7", "./file.kpl" }; - kpl_config_init(&config); - int32_t code = kpl_config_parse_args(&config, argc, argv); - KPL_ASSERT(code == KPL_EXIT_CODE_SUCCESS, "Invalid exit code"); - KPL_ASSERT(config.thread.ring_pool_entries_pow2[6] == 7, "Invalid entries pow2"); -} diff --git a/test/queue.c b/test/queue.c deleted file mode 100644 index 0f63322..0000000 --- a/test/queue.c +++ /dev/null @@ -1,96 +0,0 @@ - -#include "kpl_test.h" - -typedef struct { - _Atomic int32_t increments; - bool pop_error; - kpl_task_queue task_queue; - pthread_t pthread; -} kpl_task_queue_thread_test; - -#define TASK_QUEUE_THREAD_COUNT 3 - -#define TASK_QUEUE_PER_THREAD_INCREMENTS 10 - -static const int32_t kpl_task_queue_total_increments = TASK_QUEUE_THREAD_COUNT * TASK_QUEUE_PER_THREAD_INCREMENTS; - -static kpl_task_queue_thread_test task_queue_threads[TASK_QUEUE_THREAD_COUNT] = {}; - -static void *task_queue_thread_fn(void *arg) { - const int32_t thread_id = (int32_t) (intptr_t) arg; - for (int32_t round = 0; round < TASK_QUEUE_PER_THREAD_INCREMENTS; round++) { - for (int32_t id = 0; id < TASK_QUEUE_THREAD_COUNT; id++) { - kpl_task *task = calloc(1, sizeof(kpl_task)); - kpl_task_queue_add(&task_queue_threads[id].task_queue, task); - } - kpl_task *task = kpl_task_queue_next(&task_queue_threads[thread_id].task_queue); - if (task) { - task_queue_threads[thread_id].increments++; - free(task); - } else { - task_queue_threads[thread_id].pop_error = true; - break; - } - } - return NULL; -} - -KPL_TEST(task_queue_threads) { - for (int32_t id = 0; id < TASK_QUEUE_THREAD_COUNT; id++) - kpl_task_queue_init(&task_queue_threads[id].task_queue); - for (int32_t id = 0; id < TASK_QUEUE_THREAD_COUNT; id++) - pthread_create(&task_queue_threads[id].pthread, NULL, task_queue_thread_fn, (void*) (intptr_t) id); - for (int32_t id = 0; id < TASK_QUEUE_THREAD_COUNT; id++) - pthread_join(task_queue_threads[id].pthread, NULL); - for (int32_t id = 0; id < TASK_QUEUE_THREAD_COUNT; id++) { - kpl_task *task = NULL; - while ((task = kpl_task_queue_next(&task_queue_threads[id].task_queue))) { - task_queue_threads[id].increments++; - free(task); - } - KPL_ASSERT(!task_queue_threads[id].pop_error, "Task queue pop failed"); - KPL_ASSERT(task_queue_threads[id].increments == kpl_task_queue_total_increments, - "Invalid number of increments"); - } -} - -#define RING_QUEUE_THREAD_COUNT 3 - -#define RING_QUEUE_SLOTS_PER_THREAD 1000 - -#define RING_QUEUE_SLOT_LENGTH (RING_QUEUE_THREAD_COUNT * RING_QUEUE_SLOTS_PER_THREAD) - -static pthread_t ring_queue_threads[RING_QUEUE_THREAD_COUNT] = {}; - -static bool ring_queue_test_slots[RING_QUEUE_SLOT_LENGTH] = {}; - -static kpl_ring_queue ring_queue; - -static void *ring_queue_thread_fn(void *arg) { - const int32_t thread_id = (int32_t) (intptr_t) arg; - int32_t slot_index; - for (int32_t round = 1; round < RING_QUEUE_SLOTS_PER_THREAD; round++) { - slot_index = thread_id * RING_QUEUE_SLOTS_PER_THREAD + round; - if (!kpl_ring_queue_add(&ring_queue, (void*) (intptr_t) slot_index)) - break; - if ((slot_index = (int32_t) (intptr_t) kpl_ring_queue_next(&ring_queue))) - ring_queue_test_slots[slot_index] = true; - } - while ((slot_index = (int32_t) (intptr_t) kpl_ring_queue_next(&ring_queue))) - ring_queue_test_slots[slot_index] = true; - return NULL; -} - -KPL_TEST(ring_queue_threads) { - for (int32_t skip_round = 0; skip_round < RING_QUEUE_THREAD_COUNT; skip_round++) - ring_queue_test_slots[skip_round * RING_QUEUE_SLOTS_PER_THREAD] = true; - KPL_ASSERT(kpl_ring_queue_init(&ring_queue, 12), "Ring queue should init"); - for (int32_t id = 0; id < RING_QUEUE_THREAD_COUNT; id++) - pthread_create(&ring_queue_threads[id], NULL, ring_queue_thread_fn, (void*) (intptr_t) id); - for (int32_t id = 0; id < RING_QUEUE_THREAD_COUNT; id++) - pthread_join(ring_queue_threads[id], NULL); - for (int32_t slot_index = 0; slot_index < RING_QUEUE_SLOT_LENGTH; slot_index++) { - KPL_ASSERT(ring_queue_test_slots[slot_index], "Slot should have been set"); - } - kpl_ring_queue_free(&ring_queue); -} diff --git a/test/test.c b/test/test.c deleted file mode 100644 index 04cade6..0000000 --- a/test/test.c +++ /dev/null @@ -1,151 +0,0 @@ - -#include "kpl_test.h" - -static kpl_test *_kpl_test_head = NULL, *_kpl_test_tail = NULL, *_kpl_error_head = NULL, *_kpl_error_tail = NULL; - -static int32_t _kpl_test_count = 0, _kpl_test_error_count = 0; - -void kpl_test_add(kpl_test *_test) { - _kpl_test_count++; - if (_kpl_test_head) - _kpl_test_tail = _kpl_test_tail->next_test = _test; - else - _kpl_test_head = _kpl_test_tail = _test; -} - -static void kpl_test_report(kpl_test *_test) { - printf(KPL_COLOR(BOLD) "%s" KPL_COLOR(RESET) ":" KPL_COLOR(LIGHT_CYAN) "%s" KPL_COLOR(RESET), - _test->file_name, _test->test_name); -} - -static void kpl_test_report_success(kpl_test *_test) { - printf(KPL_COLOR2(BOLD, LIGHT_GREEN) "PASSED " KPL_COLOR(RESET)); - kpl_test_report(_test); - putchar('\n'); -} - -static void kpl_test_report_error(kpl_test *_test, bool failed_status) { - if (failed_status) - printf(KPL_COLOR2(BOLD, LIGHT_RED) "FAILED " KPL_COLOR(RESET)); - kpl_test_report(_test); - printf(":" KPL_COLOR(LIGHT_MAGENTA) "%d" KPL_COLOR(RESET) "::" - KPL_COLOR(LIGHT_RED) "%s\n" KPL_COLOR(RESET), _test->error_line_number, _test->error_message); -} - -static int32_t kpl_test_error_list(void) { - if (!_kpl_test_error_count) { - printf(KPL_COLOR2(BOLD, LIGHT_GREEN) "ALL TESTS PASSED\n" KPL_COLOR(RESET)); - return KPL_EXIT_CODE_SUCCESS; - } - printf(KPL_COLOR2(BOLD, LIGHT_RED) "FAILED TEST COUNT:" KPL_COLOR(RESET) - KPL_COLOR(WHITE) " %d\n\n" KPL_COLOR(RESET), _kpl_test_error_count); - while (_kpl_error_head) { - kpl_test_report_error(_kpl_error_head, false); - putchar('\n'); - _kpl_error_head = _kpl_error_head->next_test; - } - return KPL_EXIT_CODE_ERROR; -} - -static void kpl_test_run(kpl_test *_test) { - _test->test_function(_test); - if (_test->error_line_number == -1) { - kpl_test_report_success(_test); - return; - } - _kpl_test_error_count++; - kpl_test_report_error(_test, true); - if (_kpl_error_head) - _kpl_error_tail = _kpl_error_tail->next_test = _test; - else - _kpl_error_head = _kpl_error_tail = _test; -} - -static kpl_test *kpl_test_next(void) { - if (!_kpl_test_head) - return NULL; - kpl_test *_test = _kpl_test_head; - _kpl_test_head = _kpl_test_head->next_test; - _test->next_test = NULL; - return _test; -} - -static int32_t kpl_test_run_all(void) { - kpl_test *_test = NULL; - while ((_test = kpl_test_next())) - kpl_test_run(_test); - return kpl_test_error_list(); -} - -static int32_t kpl_test_help(const char *argv0) { - printf("\nUsage: " KPL_COLOR(BOLD) "%s " KPL_COLOR(RESET) - KPL_COLOR(WHITE) "[OPTIONS] [TEST NAMES]\n\n" KPL_COLOR(RESET), argv0); - printf("Where " KPL_COLOR(WHITE) "[OPTIONS]" KPL_COLOR(RESET) " are:\n"); - printf(KPL_COLOR(LIGHT_YELLOW) "\t-a " KPL_COLOR(RESET) "Run All Tests\n"); - printf(KPL_COLOR(LIGHT_YELLOW) "\t-h " KPL_COLOR(RESET) "Show Help\n"); - printf(KPL_COLOR(LIGHT_YELLOW) "\t-l " KPL_COLOR(RESET) "List Test Names\n"); - putchar('\n'); - return KPL_EXIT_CODE_HELP; -} - -static int32_t kpl_test_list(void) { - printf("\nTest Count: " KPL_COLOR(WHITE) "%d\n\n" - KPL_COLOR(RESET) KPL_COLOR(LIGHT_CYAN), _kpl_test_count); - while (_kpl_test_head) { - printf("%s ", _kpl_test_head->test_name); - _kpl_test_head = _kpl_test_head->next_test; - } - printf(KPL_COLOR(RESET) "\n\n"); - return KPL_EXIT_CODE_HELP; -} - -static int32_t kpl_test_run_by_name(const int32_t argc, const char *argv[], const int32_t named_arg_index) { - if (named_arg_index == argc) { - printf(KPL_COLOR(LIGHT_RED) "\nNo Tests Specified\n" KPL_COLOR(RESET)); - return kpl_test_help(argv[0]); - } - int32_t tests_ran = 0; - kpl_test *_test = NULL; - while ((_test = kpl_test_next())) - for (int32_t test_name_index = named_arg_index; test_name_index < argc; test_name_index++) - if (strcmp(argv[test_name_index], _test->test_name) == 0) { - kpl_test_run(_test); - tests_ran++; - } - if (!tests_ran) { - printf(KPL_COLOR(LIGHT_RED) "\nNo Matching Tests Found, for help run: " KPL_COLOR(RESET) - KPL_COLOR(BOLD) "%s -h\n\n" KPL_COLOR(RESET), argv[0]); - return KPL_EXIT_CODE_ERROR; - } - return kpl_test_error_list(); -} - -int32_t main(const int32_t argc, const char *argv[]) { - int32_t arg_index = 1; - while (arg_index < argc) { - if (argv[arg_index][0] != '-' || !argv[arg_index][1] || argv[arg_index][2]) - break; - switch (argv[arg_index][1]) { - case 'a': - return kpl_test_run_all(); - case 'h': - return kpl_test_help(argv[0]); - case 'l': - return kpl_test_list(); - default: - return kpl_test_run_by_name(argc, argv, arg_index); - } - arg_index++; - } - return kpl_test_run_by_name(argc, argv, arg_index); -} - -KPL_TEST(pass_by_default) { - // Pass by default - // Uncomment below to f ail - // KPL_FAIL("Failure message"); -} - -KPL_TEST(counting) { - KPL_ASSERT(_kpl_test_count > 0, "Test counter not incrementing"); -} -- cgit v1.2.3