From 69811ba0f2e50a383b4ccd5ed2c8043d242f7f06 Mon Sep 17 00:00:00 2001 From: MCorange Date: Wed, 29 Jan 2025 23:21:18 +0200 Subject: [PATCH] Restructure --- .gitignore | 1 + Makefile | 5 +-- .../mcutil}/collect/gen_vec.h | 2 +- .../mcutil}/collect/hash_map.h | 2 +- {src/include => include/mcutil}/collect/str.h | 2 +- {src/include => include/mcutil}/hash/md5.h | 0 include/mcutil/include/collect/gen_vec.h | 21 ++++++++++ include/mcutil/include/collect/hash_map.h | 33 +++++++++++++++ include/mcutil/include/collect/str.h | 42 +++++++++++++++++++ include/mcutil/include/hash/md5.h | 22 ++++++++++ {src => include/mcutil}/include/iter.h | 0 {src => include/mcutil}/include/lambda.h | 0 {src => include/mcutil}/include/mcutil.h | 0 {src => include/mcutil}/include/result.h | 2 +- include/mcutil/include/test.h | 30 +++++++++++++ include/mcutil/iter.h | 32 ++++++++++++++ include/mcutil/lambda.h | 28 +++++++++++++ include/mcutil/mcutil.h | 36 ++++++++++++++++ include/mcutil/result.h | 34 +++++++++++++++ include/mcutil/test.h | 30 +++++++++++++ src/collect/gen_vec.c | 4 +- src/collect/hash_map.c | 6 +-- src/collect/str.c | 20 ++++----- src/hash/md5.c | 2 +- test.c | 3 +- 25 files changed, 332 insertions(+), 25 deletions(-) rename {src/include => include/mcutil}/collect/gen_vec.h (94%) rename {src/include => include/mcutil}/collect/hash_map.h (97%) rename {src/include => include/mcutil}/collect/str.h (97%) rename {src/include => include/mcutil}/hash/md5.h (100%) create mode 100644 include/mcutil/include/collect/gen_vec.h create mode 100644 include/mcutil/include/collect/hash_map.h create mode 100644 include/mcutil/include/collect/str.h create mode 100644 include/mcutil/include/hash/md5.h rename {src => include/mcutil}/include/iter.h (100%) rename {src => include/mcutil}/include/lambda.h (100%) rename {src => include/mcutil}/include/mcutil.h (100%) rename {src => include/mcutil}/include/result.h (96%) create mode 100644 include/mcutil/include/test.h create mode 100644 include/mcutil/iter.h create mode 100644 include/mcutil/lambda.h create mode 100644 include/mcutil/mcutil.h create mode 100644 include/mcutil/result.h create mode 100644 include/mcutil/test.h diff --git a/.gitignore b/.gitignore index 468e22d..6b7e52e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /.cache compile_commands.json /test +/mcutil diff --git a/Makefile b/Makefile index 3a4c816..e5baebb 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Literaly only need thos so i can get a compile_commands.json so my clangd lsp stops yelling at me +# Literally only need this so i can get a compile_commands.json so my clangd lsp stops yelling at me OUTD ?= ./build @@ -7,7 +7,7 @@ LD = gcc AR = ar # -fblocks -CCARGS = -fpic -Wall -O3 -Wall -Isrc/include +CCARGS = -fpic -Wall -O3 -Wall -I include LDARGS = # -lBlocksRuntime @@ -30,4 +30,3 @@ build/obj/%.o: src/%.c - diff --git a/src/include/collect/gen_vec.h b/include/mcutil/collect/gen_vec.h similarity index 94% rename from src/include/collect/gen_vec.h rename to include/mcutil/collect/gen_vec.h index a3ba3fd..a549a42 100644 --- a/src/include/collect/gen_vec.h +++ b/include/mcutil/collect/gen_vec.h @@ -2,7 +2,7 @@ #ifndef _H_MCUTIL_COLLEC_GEN_VEC #define _H_MCUTIL_COLLEC_GEN_VEC -#include "mcutil.h" +#include "mcutil/mcutil.h" #include #define MCU_GEN_VEC_INITIAL_SIZE 32 diff --git a/src/include/collect/hash_map.h b/include/mcutil/collect/hash_map.h similarity index 97% rename from src/include/collect/hash_map.h rename to include/mcutil/collect/hash_map.h index c0fbe66..6d24601 100644 --- a/src/include/collect/hash_map.h +++ b/include/mcutil/collect/hash_map.h @@ -4,7 +4,7 @@ #include #include #include -#include "mcutil.h" +#include "mcutil/mcutil.h" typedef struct mcu_hash_map_node_s { uint8_t key[16]; diff --git a/src/include/collect/str.h b/include/mcutil/collect/str.h similarity index 97% rename from src/include/collect/str.h rename to include/mcutil/collect/str.h index b5c1fc0..b62d87f 100644 --- a/src/include/collect/str.h +++ b/include/mcutil/collect/str.h @@ -1,7 +1,7 @@ #ifndef _H_MCU_STR #define _H_MCU_STR -#include "mcutil.h" +#include "mcutil/mcutil.h" #include #include #include diff --git a/src/include/hash/md5.h b/include/mcutil/hash/md5.h similarity index 100% rename from src/include/hash/md5.h rename to include/mcutil/hash/md5.h diff --git a/include/mcutil/include/collect/gen_vec.h b/include/mcutil/include/collect/gen_vec.h new file mode 100644 index 0000000..a549a42 --- /dev/null +++ b/include/mcutil/include/collect/gen_vec.h @@ -0,0 +1,21 @@ + +#ifndef _H_MCUTIL_COLLEC_GEN_VEC +#define _H_MCUTIL_COLLEC_GEN_VEC + +#include "mcutil/mcutil.h" +#include + +#define MCU_GEN_VEC_INITIAL_SIZE 32 + +typedef struct gen_vec_s { + void** inner; + size_t count; + size_t capacity; +} gen_vec_t; + +MCU_API void mcu_gen_vec_insert_front(gen_vec_t* gv, void* data); +MCU_API void mcu_gen_vec_insert_back(gen_vec_t* gv, void* data); +MCU_API void* mcu_gen_vec_remove_back(gen_vec_t *gv); +MCU_API void* mcu_gen_vec_remove_front(gen_vec_t *gv); + +#endif diff --git a/include/mcutil/include/collect/hash_map.h b/include/mcutil/include/collect/hash_map.h new file mode 100644 index 0000000..6d24601 --- /dev/null +++ b/include/mcutil/include/collect/hash_map.h @@ -0,0 +1,33 @@ +#ifndef _H_MCU_COLLECT_HASH_MAP +#define _H_MCU_COLLECT_HASH_MAP + +#include +#include +#include +#include "mcutil/mcutil.h" + +typedef struct mcu_hash_map_node_s { + uint8_t key[16]; + void* value; + struct mcu_hash_map_node_s* next; +} mcu_hash_map_node_t; + +typedef struct mcu_hash_map_s { + mcu_hash_map_node_t* nodes; +} mcu_hash_map_t; + + +#define mcu_hm_insert(hm, key, value) _mcu_hm_insert((hm), (key), (const size_t)sizeof(key), (value)); +#define mcu_hm_get(hm, key) _mcu_hm_insert((hm), (key), (const size_t)sizeof(key)); +#define mcu_hm_remove(hm, key) _mcu_hm_insert((hm), (key), (const size_t)sizeof(key)); + +MCU_API mcu_hash_map_t mcu_hm_new(); +MCU_API void _mcu_hm_insert(mcu_hash_map_t* hm, const void* key, const size_t key_len, const void* value); +MCU_API void* _mcu_hm_get (mcu_hash_map_t* hm, const void* key, const size_t key_len); +MCU_API void* _mcu_hm_remove(mcu_hash_map_t* hm, const void* key, const size_t key_len); +/// Frees the hashmap but not the pointers inside the values +MCU_API void mcu_free(mcu_hash_map_t* hm); +/// Frees the hashmap and the pointers inside the values +MCU_API void mcu_free_all(mcu_hash_map_t* hm); + +#endif // _H_MCU_COLLECT_HASH_MAP diff --git a/include/mcutil/include/collect/str.h b/include/mcutil/include/collect/str.h new file mode 100644 index 0000000..b62d87f --- /dev/null +++ b/include/mcutil/include/collect/str.h @@ -0,0 +1,42 @@ +#ifndef _H_MCU_STR +#define _H_MCU_STR + +#include "mcutil/mcutil.h" +#include +#include +#include + +#define mcu_str_append_cstr(to, from) mc_str_append((to), mc_str_new(from)) +#define mcu_str_free(str) MCU_FREE((str)->inner) + +typedef struct mcu_str_s { + char* inner; + uint8_t _null; + size_t len; + size_t cap; +} mcu_str_t; + +/// Creates a new owned string +/// You can just use printf as normal with this cause you can safely cast this into char* +MCU_API mcu_str_t mcu_str_new(const char* str); + +/// Append the string 'from' onto string 'to' +MCU_API void mcu_str_append(mcu_str_t* to, const mcu_str_t* from); + +/// Strip the whitespace from the front of the string +MCU_API void mcu_str_trim_front(mcu_str_t* str); + +/// Strip the whitespace from the front of the string +MCU_API void mcu_str_trim_end(mcu_str_t* str); + +/// Strip the whitespace from the front and end of the string +MCU_API void mcu_str_trim(mcu_str_t* str); + +/// Replace string 'from' to string 'to' +/// Hopefully this works, i hope +MCU_API void mcu_str_replace(mcu_str_t* str, const mcu_str_t* from, const mcu_str_t* to); + + + + +#endif // _H_MCU_STR diff --git a/include/mcutil/include/hash/md5.h b/include/mcutil/include/hash/md5.h new file mode 100644 index 0000000..78a86b5 --- /dev/null +++ b/include/mcutil/include/hash/md5.h @@ -0,0 +1,22 @@ +// Taken from https://breder.org/md5-implementation +// Author header continues below + +// MD5 (Message-Digest Algorithm 5) +// Copyright Victor Breder 2024 +// SPDX-License-Identifier: MIT + +#ifndef _H_MCU_HASH_MD5 +#define _H_MCU_HASH_MD5 + +#include +#include + +typedef struct { + uint32_t a, b, c, d; +} mcu_md5_context; + +void mcu_md5_init(mcu_md5_context* ctx); +void mcu_md5_digest(mcu_md5_context* ctx, void* buffer, size_t size); +void mcu_md5_output(mcu_md5_context* ctx, uint8_t out[16]); + +#endif // _H_MCU_HASH_MD5 diff --git a/src/include/iter.h b/include/mcutil/include/iter.h similarity index 100% rename from src/include/iter.h rename to include/mcutil/include/iter.h diff --git a/src/include/lambda.h b/include/mcutil/include/lambda.h similarity index 100% rename from src/include/lambda.h rename to include/mcutil/include/lambda.h diff --git a/src/include/mcutil.h b/include/mcutil/include/mcutil.h similarity index 100% rename from src/include/mcutil.h rename to include/mcutil/include/mcutil.h diff --git a/src/include/result.h b/include/mcutil/include/result.h similarity index 96% rename from src/include/result.h rename to include/mcutil/include/result.h index c788511..9840c25 100644 --- a/src/include/result.h +++ b/include/mcutil/include/result.h @@ -1,7 +1,7 @@ #ifndef _H_MCU_RESULT #define _H_MCU_RESULT -#include "str.h" +#include "mcutil/collect/str.h" #include typedef struct mcu_error_s { diff --git a/include/mcutil/include/test.h b/include/mcutil/include/test.h new file mode 100644 index 0000000..9287490 --- /dev/null +++ b/include/mcutil/include/test.h @@ -0,0 +1,30 @@ +#ifndef _H_MCU_TEST +#define _H_MCU_TEST + +#include +typedef struct mcu_test_case_s { + const char* short_name; + int (*test_fn)(void); + // If `test_fn` returns non zero, it will get the (ret_val - 1) value of this array, + // if this is null it will show up as `(none)`, so return 1 for the first error type. + const char* error_types[]; +} mcu_test_case_t; + + +#define RUN_TEST_CASES(cases) \ + for (size_t i = 0; i < sizeof(cases)/sizeof(mcu_test_case_t); i++) { \ + mcu_test_case_t* test_case = &(cases)[i]; \ + int ret = (test_case->test_fn)(); \ + if (!ret) { \ + printf("(%s): FAIL - Returned non zero (%d)\n", \ + test_case->short_name, ret); \ + printf("(%s): REASON: %s\n", \ + test_case->short_name, test_case->error_types[ret-1]); \ + exit(1); \ + } else { \ + printf("(%s): FAIL\n", test_case->short_name); \ + } \ + } + +#endif // _H_MCU_TEST + diff --git a/include/mcutil/iter.h b/include/mcutil/iter.h new file mode 100644 index 0000000..927e2ea --- /dev/null +++ b/include/mcutil/iter.h @@ -0,0 +1,32 @@ +#ifndef _H_MCU_ITER +#define _H_MCU_ITER + + +#define mcu_for_char_in_str(str, var_name, body) for (int __mcu_i; __mcu_i < (str)->len; __mcu_i++) { \ + char var_name = (str)->inner[__mcu_i]; \ + {body} \ +} + +/// The cast will always have an appended pointer +#define mcu_for_item_in_vec(vec, var_name, cast, body) for (int __mcu_il __mcu_i < (vec)->count; __mcu_i++) { \ + cast* var_name = (cast*)(vec)-inner[__mcu_i]; \ + {body} \ +} + +/// If we want to have the keys actual value too we would have to store it in the collection, this is not needed, usually? +/// The cast will always have an appended pointer +#define mcu_for_value_in_hash_map(hm, var_name, cast, body) { \ + mcu_hash_map_node_t* node = (hm)->nodes; \ + while (1) { \ + cast* var_name = (cast*)node->value; \ + {body} \ + if (!node->next) break; \ + node = node->next; \ + } \ +} + + + + +#endif // _H_MCU_ITER + diff --git a/include/mcutil/lambda.h b/include/mcutil/lambda.h new file mode 100644 index 0000000..5f1e221 --- /dev/null +++ b/include/mcutil/lambda.h @@ -0,0 +1,28 @@ +#ifndef _H_MCUTIL_LAMBDA +#define _H_MCUTIL_LAMBDA + +#if defined(_MSC_VER) && !defined(__MC_LMBD_DEF) + #define __MCU_LMBD_DEF + #error "msc TODO" +#endif + +#if defined(__clang__) && !defined(__MCU_LMBD_DEF) + #if !__has_extension(blocks) + #error "Clang blocks feature is required, compile with '-fblocks -lBlocksRuntime' \ +and make sure you have libblocksruntime(-dev) installed" + #endif + + #define __MCU_LMBD_DEF + #define lambda(ret_t, args_t, body) ( ^ ret_t args_t body ) +#endif + +#if defined(__GNUC__) && !defined(__MCU_LMBD_DEF) + #define __MCU_LMBD_DEF + #define lambda(ret_t, args_t, body) ({ ret_t lambda##__LINE__ args_t body &lambda##__LINE__; }) +#endif + +#if !defined(__MCU_LMBD_DEF) + #error "Unsupported compiler" +#endif + +#endif diff --git a/include/mcutil/mcutil.h b/include/mcutil/mcutil.h new file mode 100644 index 0000000..ce94236 --- /dev/null +++ b/include/mcutil/mcutil.h @@ -0,0 +1,36 @@ + +#ifndef _H_MCUTIL +#define _H_MCUTIL + +// https://fdiv.net/2015/10/08/emulating-defer-c-clang-or-gccblocks + +#ifndef MCU_ALLOC + #define MCU_ALLOC malloc +#endif + +#ifndef MCU_REALLOC + #define MCU_REALLOC realloc +#endif + +#ifndef MCU_FREE + #define MCU_FREE free +#endif + +#if defined(_MSC_VER) + #define MCU_API __declspec(dllexport) +#elif defined(__GNUC__) || defined(__clang__) + #define MCU_API __attribute__((visibility("default"))) +#else + #define MCU_API + #pragma warning Unknown dynamic link import/export semantics. +#endif + +#ifdef MCUTIL_IMPLEMENTATION +// Add all new files +#include "../../src/collect/gen_vec.c" +#include "../../src/collect/hash_map.c" +#include "../../src/collect/str.c" +#include "../../src/collect/md5.c" +#endif // MCUTIL_IMPLEMENTATION + +#endif // _H_MCUTIL diff --git a/include/mcutil/result.h b/include/mcutil/result.h new file mode 100644 index 0000000..9840c25 --- /dev/null +++ b/include/mcutil/result.h @@ -0,0 +1,34 @@ +#ifndef _H_MCU_RESULT +#define _H_MCU_RESULT + +#include "mcutil/collect/str.h" +#include + +typedef struct mcu_error_s { + mcu_str_t reason; + const char* file; + int line; +} mcu_error_t; + +typedef struct mcu_result_s { + union { + void* res; + mcu_error_t err; + }; + bool is_err; +} mcu_result_t; + +#define Ok(val) (mcu_result_t){ .is_err=false, .res = val } +#define Err(_reason) (mcu_result_t){ .is_err=true, .err = (mcu_error_t){ .reason=mcu_str_new(_reason), .file=__FILE__, .line=__LINE__ }} +#define mcu_result_unwrap(result) ({ \ + if ((result).is_err) { \ + printf("%s:%d: PANIC: Unwrapped on error value%s\n", \ + (result).err.file, (result).err.line, \ + (result).err.reason.inner); \ + exit(1); \ + }; \ + (result).res; \ +}) + + +#endif // _H_MCU_RESULT diff --git a/include/mcutil/test.h b/include/mcutil/test.h new file mode 100644 index 0000000..9287490 --- /dev/null +++ b/include/mcutil/test.h @@ -0,0 +1,30 @@ +#ifndef _H_MCU_TEST +#define _H_MCU_TEST + +#include +typedef struct mcu_test_case_s { + const char* short_name; + int (*test_fn)(void); + // If `test_fn` returns non zero, it will get the (ret_val - 1) value of this array, + // if this is null it will show up as `(none)`, so return 1 for the first error type. + const char* error_types[]; +} mcu_test_case_t; + + +#define RUN_TEST_CASES(cases) \ + for (size_t i = 0; i < sizeof(cases)/sizeof(mcu_test_case_t); i++) { \ + mcu_test_case_t* test_case = &(cases)[i]; \ + int ret = (test_case->test_fn)(); \ + if (!ret) { \ + printf("(%s): FAIL - Returned non zero (%d)\n", \ + test_case->short_name, ret); \ + printf("(%s): REASON: %s\n", \ + test_case->short_name, test_case->error_types[ret-1]); \ + exit(1); \ + } else { \ + printf("(%s): FAIL\n", test_case->short_name); \ + } \ + } + +#endif // _H_MCU_TEST + diff --git a/src/collect/gen_vec.c b/src/collect/gen_vec.c index 7805fdb..7ee6bcb 100644 --- a/src/collect/gen_vec.c +++ b/src/collect/gen_vec.c @@ -1,8 +1,8 @@ #include #include #include -#include "mcutil.h" -#include "collect/gen_vec.h" +#include "mcutil/mcutil.h" +#include "mcutil/collect/gen_vec.h" MCU_API void mcu_gen_vec_init(gen_vec_t* gv) { gv->inner = MCU_ALLOC(sizeof(void*)*MCU_GEN_VEC_INITIAL_SIZE); diff --git a/src/collect/hash_map.c b/src/collect/hash_map.c index c935d3d..d562885 100644 --- a/src/collect/hash_map.c +++ b/src/collect/hash_map.c @@ -1,11 +1,11 @@ -#include "collect/hash_map.h" +#include "mcutil/collect/hash_map.h" #include #include #include #include #include -#include "mcutil.h" -#include "hash/md5.h" +#include "mcutil/mcutil.h" +#include "mcutil/hash/md5.h" MCU_API mcu_hash_map_t mcu_hm_new() { return (mcu_hash_map_t){ diff --git a/src/collect/str.c b/src/collect/str.c index 75882d4..ddc6a5c 100644 --- a/src/collect/str.c +++ b/src/collect/str.c @@ -1,6 +1,6 @@ -#include "str.h" -#include "mcutil.h" +#include "mcutil/collect/str.h" +#include "mcutil/mcutil.h" MCU_API mcu_str_t mcu_str_new(const char* str) { size_t len = strlen(str); @@ -26,10 +26,10 @@ MCU_API void mcu_str_trim_front(mcu_str_t* str) { size_t removed_count = 0; for (size_t i = 0; i < str->len; i++) { if ( - str->inner[i] == ' ' | - str->inner[i] == '\t' | - str->inner[i] == '\r' | - str->inner[i] == '\n' + (str->inner[i] == ' ' ) | + (str->inner[i] == '\t') | + (str->inner[i] == '\r') | + (str->inner[i] == '\n') ) { removed_count += 1; } else { @@ -49,10 +49,10 @@ MCU_API void mcu_str_trim_front(mcu_str_t* str) { MCU_API void mcu_str_trim_end(mcu_str_t* str) { for (size_t i = str->len - 1; i >= 0; i--) { if ( - str->inner[i] == ' ' | - str->inner[i] == '\t' | - str->inner[i] == '\r' | - str->inner[i] == '\n' + (str->inner[i] == ' ' ) | + (str->inner[i] == '\t') | + (str->inner[i] == '\r') | + (str->inner[i] == '\n') ) { str->len -= 1; str->inner[i] = '\0'; diff --git a/src/hash/md5.c b/src/hash/md5.c index dcc7ae2..9f90c34 100644 --- a/src/hash/md5.c +++ b/src/hash/md5.c @@ -14,7 +14,7 @@ #include #include -#include "hash/md5.h" +#include "mcutil/hash/md5.h" // from RFC 1321, Section 3.4: #define F(X, Y, Z) (((X) & (Y)) | ((~(X)) & (Z))) diff --git a/test.c b/test.c index 7d1c0d2..b2badeb 100644 --- a/test.c +++ b/test.c @@ -1,5 +1,4 @@ -// #include "collec/gen_vec.h" -#include "result.h" +#include #include #include