aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornodist <kevin.comas.git@gmail.com>2026-10-06 17:13:01 -0400
committernodist <kevin.comas.git@gmail.com>2026-10-06 17:13:01 -0400
commit7bd050ccf74222e1b659f2fd6826a86e6afbcc94 (patch)
tree30bae9ca5dd110f32cd4abb10d42ea4d872b4d82
parentde65adbc1b2d1b3efdbe6a023bb7435f84b2f3a7 (diff)
basic tests
-rw-r--r--README8
-rw-r--r--include/README12
-rw-r--r--include/kpl.h9
-rw-r--r--include/kpl/base.h33
-rw-r--r--include/kpl/class.h34
-rw-r--r--include/kpl/color.h120
-rw-r--r--include/kpl/object.h33
-rw-r--r--include/kpl/runtime.h52
-rw-r--r--include/kpl/tree.h61
-rw-r--r--include/kpl_test.h69
-rw-r--r--source/README9
-rw-r--r--source/kpl.c11
-rw-r--r--source/tree.c37
-rw-r--r--test/README31
-rw-r--r--test/test.c77
-rwxr-xr-xvm.sh2
16 files changed, 597 insertions, 1 deletions
diff --git a/README b/README
index f6037f9..0c71762 100644
--- a/README
+++ b/README
@@ -26,6 +26,14 @@ Running:
Testing:
+./kpl_test # Run all tests
+
+./kpl_test NAME1... # Run test by test name
+
+---
+
+Cross Architecture Testing:
+
See TESTING
---
diff --git a/include/README b/include/README
new file mode 100644
index 0000000..6800f87
--- /dev/null
+++ b/include/README
@@ -0,0 +1,12 @@
+Header Files
+
+---
+
+Includes:
+
+Only include one of these files in the source
+
+kpl.h # For the main kpl application
+kpl_test.h # For Testing
+
+---
diff --git a/include/kpl.h b/include/kpl.h
new file mode 100644
index 0000000..913edb7
--- /dev/null
+++ b/include/kpl.h
@@ -0,0 +1,9 @@
+/*
+ * This is the only header included in any c source file
+ */
+
+#pragma once
+
+#include "kpl/runtime.h"
+
+#define KPL_VERSION "0.0.0"
diff --git a/include/kpl/base.h b/include/kpl/base.h
new file mode 100644
index 0000000..144fd51
--- /dev/null
+++ b/include/kpl/base.h
@@ -0,0 +1,33 @@
+/*
+ * The header for headers included in kpl.h
+ */
+
+#pragma once
+
+// System includes
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <ctype.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/uio.h>
+#include <linux/fs.h>
+#include <linux/io_uring.h>
+// KPL includes
+#include "color.h"
+#include "class.h"
+#include "object.h"
+#include "tree.h"
+
+typedef enum : int32_t {
+ KPL_EXIT_CODE_SUCCESS = 0,
+ KPL_EXIT_CODE_ERROR = 1
+} kpl_exit_code;
diff --git a/include/kpl/class.h b/include/kpl/class.h
new file mode 100644
index 0000000..b1b7054
--- /dev/null
+++ b/include/kpl/class.h
@@ -0,0 +1,34 @@
+/*
+ * The kpl class a 64bit value with an table of functions
+ */
+
+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 {
+// TODO KPL INTERFACE
+} kpl_interface;
+
+typedef struct {
+ kpl_value value;
+ kpl_interface *interface;
+} kpl_class;
diff --git a/include/kpl/color.h b/include/kpl/color.h
new file mode 100644
index 0000000..dc7fe20
--- /dev/null
+++ b/include/kpl/color.h
@@ -0,0 +1,120 @@
+/*
+ * Colors for pretty printing
+ */
+
+#pragma once
+
+#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/object.h b/include/kpl/object.h
new file mode 100644
index 0000000..0f54a5e
--- /dev/null
+++ b/include/kpl/object.h
@@ -0,0 +1,33 @@
+/*
+ * KPL specific objects
+ */
+
+#pragma once
+
+// for atomic linked list queue
+// size in bytes, index on the kpl_threads array
+#define KPL_OBJECT_HEADER(STRUCT_NAME) \
+ struct STRUCT_NAME *_Atomic queue_next; \
+ int32_t obj_size, thread_id
+
+typedef struct _kpl_object {
+ KPL_OBJECT_HEADER(_kpl_object);
+} kpl_object; // all kpl objects allocated by the kpl allocator extend this header
+
+typedef struct {
+ kpl_object *_Atomic head, *tail; // head is modified with atomic exchange
+ struct {
+ kpl_object *_Atomic queue_next;
+ } dummy; // head and tail are never null will always point to this
+} kpl_object_queue; // atomic linked list queue any thread can add, only owner thread can remove
+
+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 {
+ KPL_OBJECT_HEADER(_kpl_task);
+ // TODO
+} kpl_task;
diff --git a/include/kpl/runtime.h b/include/kpl/runtime.h
new file mode 100644
index 0000000..2adf402
--- /dev/null
+++ b/include/kpl/runtime.h
@@ -0,0 +1,52 @@
+/*
+ * KPL allocators, io and threading
+ */
+
+#pragma once
+
+#include "base.h"
+
+typedef enum : uint8_t {
+ KPL_MEMORY_ALLOCATOR_MIN_POW2 = 7,
+ KPL_MEMORY_ALLOCATOR_MAX_POW2 = 30
+} kpl_memory_allocator_enum;
+
+/*
+ * All allocations are rounded to the next power of two at lest to a min or error if over max
+ * Each power of two has a bucket in the memory pool for reuse
+ */
+typedef struct {
+// TODO MEMORY ALLOCATOR
+} kpl_memory_allocator;
+
+typedef enum : uint8_t {
+ KPL_MEMORY_POOL_COUNT = 31
+} kpl_memory_pool_enum;
+
+// TODO IO URING
+
+// TODO JIT ALLOCATOR
+
+typedef struct {
+ kpl_memory_allocator allocator;
+ kpl_object_queue memory_pools[KPL_MEMORY_POOL_COUNT]; // each index represents 2 ** INDEX size in bytes
+ // TODO io_uring
+ // TODO jit allocator
+ _Atomic ssize_t priority; // running + the total number of tasks in threads queue, lower is higher priority
+ kpl_object_queue task_queue;
+ pthread_t pthread; // not used for main thread
+ sem_t sem; // wait when no task queue and io queue is empty
+} kpl_thread;
+
+typedef enum : int32_t {
+ KPL_THREAD_DETERIMINE_COUNT = -1,
+ KPL_THREAD_MAIN_ID = 0
+} kpl_thread_enum;
+
+typedef struct _kpl_env {
+ int32_t thread_count; // -1 updates this value to max possible, 0 invalid, >= 1 for specific number
+ _Atomic ssize_t total_priority; // the sum of the threads priority fields, application stops on zero
+ kpl_thread *thread_array; // 0 is main thread, >= 1 are spawned pthreads
+ kpl_tree *namespace_tree, *module_tree; // *namespace_tree lookups are thread safe, *module_tree needs mutex
+ pthread_mutex_t module_tree_mutex;
+} kpl_env; // kpl state, no globals
diff --git a/include/kpl/tree.h b/include/kpl/tree.h
new file mode 100644
index 0000000..8e52524
--- /dev/null
+++ b/include/kpl/tree.h
@@ -0,0 +1,61 @@
+/*
+ * KPL tree
+ */
+
+#pragma once
+
+// tree_duplicate is a linked stack
+#define KPL_TREE_HEADER(STRUCT_NAME) \
+ struct STRUCT_NAME *tree_left, *tree_right, *tree_duplicate; \
+ int32_t tree_height
+
+/*
+ * Recursive AVL saves 8 bytes per object (no need for parent pointer) and keeps the insertion and finding simple
+ */
+typedef struct _kpl_tree_node {
+ KPL_TREE_HEADER(_kpl_tree_node);
+} kpl_tree_node;
+
+typedef enum : int32_t {
+ KPL_TREE_TREE_HEIGHT_INIT = 1
+} kpl_tree_enum;
+
+/*
+ * -1 search left, 1 search right, 0 found
+ */
+typedef int32_t kpl_tree_node_compare_fn(const void *node_a, const void *node_b);
+
+typedef void kpl_tree_node_free_fn(void *node);
+
+/*
+ * KPL needs tree with insertion and find operations, deletion is not needed, all nodes are freed on tree free
+ */
+typedef struct {
+ kpl_tree_node *root_node;
+ kpl_tree_node_compare_fn *node_compare_fn;
+ kpl_tree_node_free_fn *node_free_fn;
+} kpl_tree;
+
+#define KPL_TREE_INIT_STATIC(COMPARE_FN, FREE_FN) \
+ (kpl_tree) { .root_node = NULL, .node_compare_fn = COMPARE_FN, .node_free_fn = FREE_FN }
+
+inline void kpl_tree_init(kpl_tree *tree, kpl_tree_node_compare_fn node_compare_fn,
+ kpl_tree_node_free_fn node_free_fn) {
+ tree->root_node = NULL;
+ tree->node_compare_fn = node_compare_fn;
+ tree->node_free_fn = node_free_fn;
+}
+
+void kpl_tree_free(kpl_tree *tree);
+
+/*
+ * *find is stack allocated
+ * NULL for not found
+ */
+void *kpl_tree_find(kpl_tree *tree, const void *find_node);
+
+/*
+ * *insert is heap allocated
+ * All inserts succeed, duplicates are added to *tree_duplicate
+ */
+void kpl_tree_insert(kpl_tree *tree, void *insert_node);
diff --git a/include/kpl_test.h b/include/kpl_test.h
new file mode 100644
index 0000000..a656761
--- /dev/null
+++ b/include/kpl_test.h
@@ -0,0 +1,69 @@
+/*
+ * This is the only header included in any c test file
+ */
+
+#pragma once
+
+#include "kpl.h"
+
+typedef enum : int32_t {
+ KPL_TEST_ERROR_LINE_NUMBER_INIT = -1,
+} kpl_test_enum;
+
+typedef struct _kpl_test kpl_test;
+
+typedef void kpl_test_fn(__attribute__((unused)) kpl_test *_test);
+
+/*
+ * The kpl_test object is used to build a static singly linked list and a static tree
+ * The list is for running all tests and moving failed tests to an error linked list
+ * The tree is used for running tests by name
+ */
+typedef struct _kpl_test {
+ KPL_TREE_HEADER(_kpl_test);
+ int32_t error_line_number; // -1 line number for no error
+ struct _kpl_test *list_next;
+ const char *source_file, *name, *error_message; // static c strings only
+ kpl_test_fn *test_fn;
+} kpl_test; // Per test object, lists and trees are globals
+
+void _kpl_test_add(kpl_test *_test); // do not call outside KPL_TEST macro
+
+#define _KPL_TEST_FN_DEFINITION(NAME) static void NAME(__attribute__((unused)) kpl_test *_test)
+
+/*
+ * Each test is a static function added to the test list and tree by a static gnu constructor function
+ * The NAME becomes the function name _NAME becomes the constructor name, only one name can be used per file
+ */
+#define KPL_TEST(NAME) _KPL_TEST_FN_DEFINITION(NAME); \
+static void __attribute__((constructor)) _ ## NAME(void) { \
+ static kpl_test _test = { \
+ .tree_left = NULL, .tree_right = NULL, .tree_duplicate = NULL, \
+ .tree_height = KPL_TREE_TREE_HEIGHT_INIT, \
+ .error_line_number = KPL_TEST_ERROR_LINE_NUMBER_INIT, \
+ .list_next = NULL, \
+ .source_file = __FILE__, .name = #NAME, .error_message = NULL, \
+ .test_fn = NAME \
+ }; \
+ _kpl_test_add(&_test); \
+} \
+_KPL_TEST_FN_DEFINITION(NAME)
+
+/*
+ * MESSAGE is a static c string, sets the error fields in a test once, aborting the rest of test
+ * Can only be called within a KPL_TEST
+ */
+#define KPL_FAIL(MESSAGE) do { \
+ _test->error_line_number = __LINE__; \
+ _test->error_message = MESSAGE; \
+ return; \
+} while (0)
+
+/*
+ * CONDITION is statement evaluating to true or false, MESSAGE is a static c string, false invokes KPL_FAIL
+ * Can only be called within KPL_TEST
+ */
+#define KPL_ASSERT(CONDITION, MESSAGE) do { \
+ if (!(CONDITION)) \
+ KPL_FAIL(#CONDITION "; " MESSAGE); \
+} while (0)
diff --git a/source/README b/source/README
new file mode 100644
index 0000000..016daa8
--- /dev/null
+++ b/source/README
@@ -0,0 +1,9 @@
+Source Files
+
+---
+
+Compiler Flags
+
+KPL_COLOR_OFF # Turn off internal pretty printing, does not effect source file pretty printing
+
+---
diff --git a/source/kpl.c b/source/kpl.c
new file mode 100644
index 0000000..55ca994
--- /dev/null
+++ b/source/kpl.c
@@ -0,0 +1,11 @@
+/*
+ * Core kpl functions and entry point
+ */
+
+#include "kpl.h"
+
+#ifdef KPL_MAIN
+int32_t main(void) {
+ return 0;
+}
+#endif
diff --git a/source/tree.c b/source/tree.c
new file mode 100644
index 0000000..dcae485
--- /dev/null
+++ b/source/tree.c
@@ -0,0 +1,37 @@
+
+#include "kpl.h"
+
+extern inline void kpl_tree_init(kpl_tree *tree, kpl_tree_node_compare_fn node_compare_fn,
+ kpl_tree_node_free_fn node_free_fn);
+
+static void kpl_tree_free_helper(kpl_tree_node *node, kpl_tree_node_free_fn node_free_fn) {
+ if (node->tree_left)
+ kpl_tree_free_helper(node->tree_left, node_free_fn);
+ if (node->tree_right)
+ kpl_tree_free_helper(node->tree_right, node_free_fn);
+ node_free_fn(node);
+}
+
+void kpl_tree_free(kpl_tree *tree) {
+ kpl_tree_free_helper(tree->root_node, tree->node_free_fn);
+}
+
+static void *kpl_tree_find_helper(kpl_tree_node *root_node, const void *find_node,
+ kpl_tree_node_compare_fn compare_fn) {
+ if (!root_node)
+ return NULL;
+ int32_t compare = compare_fn(root_node, find_node);
+ if (compare < 0)
+ return kpl_tree_find_helper(root_node->tree_left, find_node, compare_fn);
+ if (compare > 0)
+ return kpl_tree_find_helper(root_node->tree_right, find_node, compare_fn);
+ return root_node;
+}
+
+void *kpl_tree_find(kpl_tree *tree, const void *find_node) {
+ return kpl_tree_find_helper(tree->root_node, find_node, tree->node_compare_fn);
+}
+
+void kpl_tree_insert(kpl_tree *tree, void *insert_node) {
+ // TODO
+}
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..4ef67e0
--- /dev/null
+++ b/test/README
@@ -0,0 +1,31 @@
+Test Files
+
+---
+
+Testing:
+
+Each test is a function wrapped in a macro
+
+KPL_TEST(my_test) {
+ // code here
+}
+
+Each test passes by default
+
+---
+
+Testing Macros:
+
+The testing framework provides two macros KPL_ASSERT and KPL_FAIL
+
+Both macros can only be used inside a KPL_TEST function
+
+Asserting:
+
+KPL_ASSSERT(condition, "Fail Message");
+
+---
+
+Failing:
+
+KPL_FAIL("The test failed");
diff --git a/test/test.c b/test/test.c
new file mode 100644
index 0000000..6cede92
--- /dev/null
+++ b/test/test.c
@@ -0,0 +1,77 @@
+
+#include "kpl_test.h"
+
+static int32_t kpl_test_tree_compare(const void *node_a, const void *node_b) {
+ const kpl_test *test_a = node_a, *test_b = node_b;
+ return strcmp(test_a->name, test_b->name);
+}
+
+static kpl_tree test_tree = KPL_TREE_INIT_STATIC(kpl_test_tree_compare, NULL);
+
+static kpl_test *test_head = NULL, *test_tail = NULL, *error_head = NULL, *error_tail = NULL;
+
+void _kpl_test_add(kpl_test *_test) {
+ if (!test_head)
+ test_head = test_tail = _test;
+ else
+ test_tail = test_tail->list_next = _test;
+ kpl_tree_insert(&test_tree, _test);
+}
+
+static void kpl_test_report(const kpl_test *_test) {
+ printf(KPL_COLOR(BOLD) "%s" KPL_COLOR(RESET) ":" KPL_COLOR(LIGHT_CYAN) "%s" KPL_COLOR(RESET),
+ _test->source_file, _test->name);
+ if (_test->error_line_number == KPL_TEST_ERROR_LINE_NUMBER_INIT) {
+ printf(KPL_COLOR(LIGHT_GREEN) " PASS\n" KPL_COLOR(RESET));
+ return;
+ }
+ 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_report_error(void) {
+ if (!error_head) {
+ printf(KPL_COLOR2(BOLD, GREEN) "PASSED\n" KPL_COLOR(RESET));
+ return KPL_EXIT_CODE_SUCCESS;
+ }
+ printf(KPL_COLOR2(BOLD, RED) "FAILED\n" KPL_COLOR(RESET));
+ while (error_head) {
+ kpl_test *_test = error_head;
+ error_head = error_head->list_next;
+ kpl_test_report(_test);
+ }
+ return KPL_EXIT_CODE_ERROR;
+}
+
+static void kpl_test_run_one(kpl_test *_test) {
+ _test->list_next = NULL;
+ _test->test_fn(_test);
+ kpl_test_report(_test);
+ if (_test->error_line_number == KPL_TEST_ERROR_LINE_NUMBER_INIT)
+ return;
+ if (!error_head)
+ error_head = error_tail = _test;
+ else
+ error_tail = error_tail->list_next = _test;
+}
+
+static int32_t kpl_test_run_all(void) {
+ while (test_head) {
+ kpl_test *_test = test_head;
+ test_head = test_head->list_next;
+ kpl_test_run_one(_test);
+ }
+ return kpl_test_report_error();
+}
+
+int32_t main(int32_t argc, char *argv[]) {
+ if (argc < 2)
+ return kpl_test_run_all();
+ // TODO run by name
+ return kpl_test_report_error();
+}
+
+KPL_TEST(pass_by_default) {
+ // pass, uncomment below to fail
+ // KPL_FAIL("example fail");
+}
diff --git a/vm.sh b/vm.sh
index 7a4830f..8914208 100755
--- a/vm.sh
+++ b/vm.sh
@@ -12,7 +12,7 @@ CORES="2"
MEMORY="2G"
DEVICE="virtio-net-pci,netdev=net0"
HDA_URL="https://cloud.debian.org/images/cloud/trixie/latest"
-TEST_COMMAND="make kpl_test && arch && ./kpl_test -a"
+TEST_COMMAND="make kpl_test && arch && ./kpl_test"
CLEAN_COMMAND="make clean; find -type f -regex '^.*\.[ch]' -exec rm -v {} \;"
X64="X64"
A64="A64"