Restructure

This commit is contained in:
Gvidas Juknevičius 2025-01-29 23:21:18 +02:00
parent 0165e7d682
commit 69811ba0f2
Signed by: MCorange
GPG Key ID: 12B1346D720B7FBB
25 changed files with 332 additions and 25 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
/.cache /.cache
compile_commands.json compile_commands.json
/test /test
/mcutil

View File

@ -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 OUTD ?= ./build
@ -7,7 +7,7 @@ LD = gcc
AR = ar AR = ar
# -fblocks # -fblocks
CCARGS = -fpic -Wall -O3 -Wall -Isrc/include CCARGS = -fpic -Wall -O3 -Wall -I include
LDARGS = LDARGS =
# -lBlocksRuntime # -lBlocksRuntime
@ -30,4 +30,3 @@ build/obj/%.o: src/%.c

View File

@ -2,7 +2,7 @@
#ifndef _H_MCUTIL_COLLEC_GEN_VEC #ifndef _H_MCUTIL_COLLEC_GEN_VEC
#define _H_MCUTIL_COLLEC_GEN_VEC #define _H_MCUTIL_COLLEC_GEN_VEC
#include "mcutil.h" #include "mcutil/mcutil.h"
#include <stddef.h> #include <stddef.h>
#define MCU_GEN_VEC_INITIAL_SIZE 32 #define MCU_GEN_VEC_INITIAL_SIZE 32

View File

@ -4,7 +4,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "mcutil.h" #include "mcutil/mcutil.h"
typedef struct mcu_hash_map_node_s { typedef struct mcu_hash_map_node_s {
uint8_t key[16]; uint8_t key[16];

View File

@ -1,7 +1,7 @@
#ifndef _H_MCU_STR #ifndef _H_MCU_STR
#define _H_MCU_STR #define _H_MCU_STR
#include "mcutil.h" #include "mcutil/mcutil.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>

View File

@ -0,0 +1,21 @@
#ifndef _H_MCUTIL_COLLEC_GEN_VEC
#define _H_MCUTIL_COLLEC_GEN_VEC
#include "mcutil/mcutil.h"
#include <stddef.h>
#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

View File

@ -0,0 +1,33 @@
#ifndef _H_MCU_COLLECT_HASH_MAP
#define _H_MCU_COLLECT_HASH_MAP
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#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

View File

@ -0,0 +1,42 @@
#ifndef _H_MCU_STR
#define _H_MCU_STR
#include "mcutil/mcutil.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#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

View File

@ -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 <stddef.h>
#include <stdint.h>
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

View File

@ -1,7 +1,7 @@
#ifndef _H_MCU_RESULT #ifndef _H_MCU_RESULT
#define _H_MCU_RESULT #define _H_MCU_RESULT
#include "str.h" #include "mcutil/collect/str.h"
#include <stdbool.h> #include <stdbool.h>
typedef struct mcu_error_s { typedef struct mcu_error_s {

View File

@ -0,0 +1,30 @@
#ifndef _H_MCU_TEST
#define _H_MCU_TEST
#include <stddef.h>
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

32
include/mcutil/iter.h Normal file
View File

@ -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

28
include/mcutil/lambda.h Normal file
View File

@ -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

36
include/mcutil/mcutil.h Normal file
View File

@ -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

34
include/mcutil/result.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef _H_MCU_RESULT
#define _H_MCU_RESULT
#include "mcutil/collect/str.h"
#include <stdbool.h>
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

30
include/mcutil/test.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _H_MCU_TEST
#define _H_MCU_TEST
#include <stddef.h>
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

View File

@ -1,8 +1,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "mcutil.h" #include "mcutil/mcutil.h"
#include "collect/gen_vec.h" #include "mcutil/collect/gen_vec.h"
MCU_API void mcu_gen_vec_init(gen_vec_t* gv) { MCU_API void mcu_gen_vec_init(gen_vec_t* gv) {
gv->inner = MCU_ALLOC(sizeof(void*)*MCU_GEN_VEC_INITIAL_SIZE); gv->inner = MCU_ALLOC(sizeof(void*)*MCU_GEN_VEC_INITIAL_SIZE);

View File

@ -1,11 +1,11 @@
#include "collect/hash_map.h" #include "mcutil/collect/hash_map.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include "mcutil.h" #include "mcutil/mcutil.h"
#include "hash/md5.h" #include "mcutil/hash/md5.h"
MCU_API mcu_hash_map_t mcu_hm_new() { MCU_API mcu_hash_map_t mcu_hm_new() {
return (mcu_hash_map_t){ return (mcu_hash_map_t){

View File

@ -1,6 +1,6 @@
#include "str.h" #include "mcutil/collect/str.h"
#include "mcutil.h" #include "mcutil/mcutil.h"
MCU_API mcu_str_t mcu_str_new(const char* str) { MCU_API mcu_str_t mcu_str_new(const char* str) {
size_t len = strlen(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; size_t removed_count = 0;
for (size_t i = 0; i < str->len; i++) { for (size_t i = 0; i < str->len; i++) {
if ( if (
str->inner[i] == ' ' | (str->inner[i] == ' ' ) |
str->inner[i] == '\t' | (str->inner[i] == '\t') |
str->inner[i] == '\r' | (str->inner[i] == '\r') |
str->inner[i] == '\n' (str->inner[i] == '\n')
) { ) {
removed_count += 1; removed_count += 1;
} else { } 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) { MCU_API void mcu_str_trim_end(mcu_str_t* str) {
for (size_t i = str->len - 1; i >= 0; i--) { for (size_t i = str->len - 1; i >= 0; i--) {
if ( if (
str->inner[i] == ' ' | (str->inner[i] == ' ' ) |
str->inner[i] == '\t' | (str->inner[i] == '\t') |
str->inner[i] == '\r' | (str->inner[i] == '\r') |
str->inner[i] == '\n' (str->inner[i] == '\n')
) { ) {
str->len -= 1; str->len -= 1;
str->inner[i] = '\0'; str->inner[i] = '\0';

View File

@ -14,7 +14,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "hash/md5.h" #include "mcutil/hash/md5.h"
// from RFC 1321, Section 3.4: // from RFC 1321, Section 3.4:
#define F(X, Y, Z) (((X) & (Y)) | ((~(X)) & (Z))) #define F(X, Y, Z) (((X) & (Y)) | ((~(X)) & (Z)))

3
test.c
View File

@ -1,5 +1,4 @@
// #include "collec/gen_vec.h" #include <mcutil/test.h>
#include "result.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>