From 0165e7d6823e80c028e47821305b37f22ee02ce9 Mon Sep 17 00:00:00 2001 From: MCorange Date: Tue, 28 Jan 2025 23:42:26 +0200 Subject: [PATCH] owO? --- .gitignore | 4 + Makefile | 33 +++++++ src/collect/gen_vec.c | 56 +++++++++++ src/collect/hash_map.c | 93 ++++++++++++++++++ src/collect/str.c | 102 ++++++++++++++++++++ src/hash/md5.c | 171 +++++++++++++++++++++++++++++++++ src/include/collect/gen_vec.h | 21 ++++ src/include/collect/hash_map.h | 33 +++++++ src/include/collect/str.h | 42 ++++++++ src/include/hash/md5.h | 22 +++++ src/include/iter.h | 32 ++++++ {mccu => src}/include/lambda.h | 4 +- src/include/mcutil.h | 29 ++++++ src/include/result.h | 34 +++++++ test.c | 14 +++ 15 files changed, 688 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/collect/gen_vec.c create mode 100644 src/collect/hash_map.c create mode 100644 src/collect/str.c create mode 100644 src/hash/md5.c create mode 100644 src/include/collect/gen_vec.h create mode 100644 src/include/collect/hash_map.h create mode 100644 src/include/collect/str.h create mode 100644 src/include/hash/md5.h create mode 100644 src/include/iter.h rename {mccu => src}/include/lambda.h (92%) create mode 100644 src/include/mcutil.h create mode 100644 src/include/result.h create mode 100644 test.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..468e22d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/build +/.cache +compile_commands.json +/test diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3a4c816 --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +# Literaly only need thos so i can get a compile_commands.json so my clangd lsp stops yelling at me + +OUTD ?= ./build + +CC = gcc +LD = gcc +AR = ar + +# -fblocks +CCARGS = -fpic -Wall -O3 -Wall -Isrc/include +LDARGS = +# -lBlocksRuntime + +srcs = $(wildcard src/**/*.c) $(wildcard src/*.c) +objs = $(patsubst src/%.c,$(OUTD)/obj/%.o,$(srcs)) + +# $(OUTD)/libmcutil.so +all: $(objs) $(OUTD)/libmcutil.a + compiledb -n make + +$(OUTD)/libmcutil.so: $(objs) + $(LD) -o $@ $^ -shared $(LDARGS) + +$(OUTD)/libmcutil.a: $(objs) + $(AR) rcs $@ $^ + +build/obj/%.o: src/%.c + mkdir -p $(dir $@) + $(CC) -c -o $@ $< $(CCARGS) + + + + diff --git a/src/collect/gen_vec.c b/src/collect/gen_vec.c new file mode 100644 index 0000000..7805fdb --- /dev/null +++ b/src/collect/gen_vec.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include "mcutil.h" +#include "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); + gv->capacity = MCU_GEN_VEC_INITIAL_SIZE; +} + + +MCU_API void mcu_gen_vec_insert_front(gen_vec_t* gv, void* data) { + assert(gv && "Null ptr passed as gen_vec_t"); + if (!gv->inner) mcu_gen_vec_init(gv); + if (gv->count == gv->capacity) { + gv->inner = MCU_REALLOC(gv->inner, (gv->capacity * sizeof(void*)) * 2); + gv->capacity *= 2; + } + + size_t count = sizeof(void*)*gv->count; + void* tmp = MCU_ALLOC(count); + memcpy(tmp, gv->inner, count); + memcpy(gv->inner + sizeof(void*), tmp, count); + gv->inner[0] = data; + MCU_FREE(tmp); +} + +MCU_API void mcu_gen_vec_insert_back(gen_vec_t* gv, void* data) { + assert(gv && "Null ptr passed as gen_vec_t"); + if (!gv->inner) mcu_gen_vec_init(gv); + if (gv->count == gv->capacity) { + gv->inner = MCU_REALLOC(gv->inner, (gv->capacity * sizeof(void*)) * 2); + gv->capacity *= 2; + } + gv->inner[gv->count++] = data; +} + +MCU_API void* mcu_gen_vec_remove_back(gen_vec_t *gv) { + assert(gv && "Null ptr passed as gen_vec_t"); + if (gv->count == 0) return NULL; + return gv->inner[gv->count--]; +} + +MCU_API void* mcu_gen_vec_remove_front(gen_vec_t *gv) { + assert(gv && "Null ptr passed as gen_vec_t"); + if (gv->count == 0) return NULL; + void* data = gv->inner[0]; + size_t count = sizeof(void*)*gv->count; + void* tmp = MCU_ALLOC(count); + memcpy(tmp, gv->inner, count); + memcpy(gv->inner - sizeof(void*), tmp, count); + MCU_FREE(tmp); + gv->count--; + return data; +} diff --git a/src/collect/hash_map.c b/src/collect/hash_map.c new file mode 100644 index 0000000..c935d3d --- /dev/null +++ b/src/collect/hash_map.c @@ -0,0 +1,93 @@ +#include "collect/hash_map.h" +#include +#include +#include +#include +#include +#include "mcutil.h" +#include "hash/md5.h" + +MCU_API mcu_hash_map_t mcu_hm_new() { + return (mcu_hash_map_t){ + .nodes = MCU_ALLOC(sizeof(mcu_hash_map_node_t)), + }; +} + +MCU_API void _mcu_hm_insert(mcu_hash_map_t* hm, const void* key, const size_t key_len, const void* value) { + mcu_md5_context ctx = {0}; + mcu_md5_init(&ctx); + mcu_md5_digest(&ctx, (void*)key, key_len); + uint8_t key_res[16]; + mcu_md5_output(&ctx, key_res); + + mcu_hash_map_node_t* node = hm->nodes; + while (true) { + if (!node->next) { + node->next = MCU_ALLOC(sizeof(mcu_hash_map_node_t)); + node->next->next = NULL; + memcpy(node->next->key, key_res, 16); + node->next->value = (void*)value; + return; + } + node = node->next; + } +} + +MCU_API void* _mcu_hm_get(mcu_hash_map_t* hm, const void* key, const size_t key_len) { + mcu_md5_context ctx = {0}; + mcu_md5_init(&ctx); + mcu_md5_digest(&ctx, (void*)key, key_len); + uint8_t key_res[16]; + mcu_md5_output(&ctx, key_res); + + mcu_hash_map_node_t* node = hm->nodes; + while (true) { + if (memcmp(node->key, key_res, 16) == 0) { + return node->value; + } else { + if (!node->next) return NULL; + node = node->next; + } + } +} + +MCU_API void* _mcu_hm_remove(mcu_hash_map_t* hm, const void* key, const size_t key_len) { + mcu_md5_context ctx = {0}; + mcu_md5_init(&ctx); + mcu_md5_digest(&ctx, (void*)key, key_len); + uint8_t key_res[16]; + mcu_md5_output(&ctx, key_res); + + mcu_hash_map_node_t* node = hm->nodes; + mcu_hash_map_node_t* prev = hm->nodes; + while (true) { + if (memcmp(node->key, key_res, 16) == 0) { + void* val = node->value; + prev->next = node->next; + return val; + } else { + if (!node->next) return NULL; + prev = node; + node = node->next; + } + } +} + +MCU_API void mcu_free(mcu_hash_map_t* hm) { + mcu_hash_map_node_t* node = hm->nodes; + while (true) { + if (node->next) return; + MCU_FREE(node); + node = node->next; + } +} + +MCU_API void mcu_free_all(mcu_hash_map_t* hm) { + mcu_hash_map_node_t* node = hm->nodes; + while (true) { + if (node->next) return; + MCU_FREE(node); + MCU_FREE(node->value); + node = node->next; + } +} diff --git a/src/collect/str.c b/src/collect/str.c new file mode 100644 index 0000000..75882d4 --- /dev/null +++ b/src/collect/str.c @@ -0,0 +1,102 @@ + +#include "str.h" +#include "mcutil.h" + +MCU_API mcu_str_t mcu_str_new(const char* str) { + size_t len = strlen(str); + char* buf = MCU_ALLOC(len*sizeof(char)*2); + memcpy(buf, str, len*sizeof(char)); + return (mcu_str_t){ + .inner = buf, + ._null = 0, + .cap = len * 2, + .len = len, + }; +} + +MCU_API void mcu_str_append(mcu_str_t* to, const mcu_str_t* from) { + if (to->len + from->len >= to->cap) { + to->inner = MCU_REALLOC(to->inner, (to->len + from->len) * 2); + } + memcpy(to->inner + (to->len * sizeof(char)), from->inner, from->len); +} + +/// Strip the whitespace from the front of the string +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' + ) { + removed_count += 1; + } else { + break; + } + } + + memcpy( + str->inner, + str->inner + (sizeof(char) * removed_count), + str->len - removed_count + ); + str->len -= removed_count; +} + +/// Strip the whitespace from the front of the string +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->len -= 1; + str->inner[i] = '\0'; + } else { + break; + } + } +} + +/// Strip the whitespace from the front and end of the string +MCU_API void mcu_str_trim(mcu_str_t* str) { + mcu_str_trim_front(str); + mcu_str_trim_end(str); +} + +MCU_API void mcu_str_replace(mcu_str_t* str, const mcu_str_t* from, const mcu_str_t* to) { + for (size_t i = 0; i < str->len; i++) { + if (str->inner[i] == from->inner[0]) continue; + + for (size_t ii = 0; ii < from->len; ii++) { + if (i + ii > str->len) break; + if (str->inner[i + ii] == from->inner[ii]) { + if (ii != from->len - 1) continue; + + str->inner = MCU_REALLOC(str->inner, + str->len + ( + (to->len - from->len) > 0 ? + (to->len - from->len) : + 0 + )); + memcpy( + str->inner + ((i + to->len) * sizeof(char)), + str->inner + ((i + from->len) * sizeof(char)), + (str->len - i - from->len) + ); + memcpy( + str->inner + i, + from->inner, + from->len + ); + return; + } else { + break; + } + } + } +} diff --git a/src/hash/md5.c b/src/hash/md5.c new file mode 100644 index 0000000..dcc7ae2 --- /dev/null +++ b/src/hash/md5.c @@ -0,0 +1,171 @@ +// Taken from https://breder.org/md5-implementation +// Author header continues below + +// MD5 (Message-Digest Algorithm 5) +// Copyright Victor Breder 2024 +// SPDX-License-Identifier: MIT + +// Implemented from reference RFC 1321 available at +// + +#include +#include +#include +#include +#include + +#include "hash/md5.h" + +// from RFC 1321, Section 3.4: +#define F(X, Y, Z) (((X) & (Y)) | ((~(X)) & (Z))) +#define G(X, Y, Z) (((X) & (Z)) | (Y & (~(Z)))) +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) +#define I(X, Y, Z) ((Y) ^ ((X) | (~(Z)))) + +static +uint32_t rotl(uint32_t x, int s) { return (x << s) | (x >> (32 - s)); } +#define STEP(OP, a, b, c, d, k, s, i) do{ \ + a = b + rotl(a + OP(b, c, d) + X[k] + i, s); \ + }while(0) + +#define TO_I32(x,i) ((x[i]) | (x[i+1]<<8) | (x[i+2]<<16) | (x[i+3]<<24)) +static +void mcu_md5_block(mcu_md5_context* ctx, const uint8_t m[64]) { + assert(ctx != NULL); + + uint32_t X[16] = { + TO_I32(m,0), TO_I32(m,4), TO_I32(m,8), TO_I32(m,12), + TO_I32(m,16), TO_I32(m,20), TO_I32(m,24), TO_I32(m,28), + TO_I32(m,32), TO_I32(m,36), TO_I32(m,40), TO_I32(m,44), + TO_I32(m,48), TO_I32(m,52), TO_I32(m,56), TO_I32(m,60) + }; + + uint32_t a = ctx->a; + uint32_t b = ctx->b; + uint32_t c = ctx->c; + uint32_t d = ctx->d; + + STEP(F, a, b, c, d, 0, 7, 0xd76aa478); + STEP(F, d, a, b, c, 1, 12, 0xe8c7b756); + STEP(F, c, d, a, b, 2, 17, 0x242070db); + STEP(F, b, c, d, a, 3, 22, 0xc1bdceee); + STEP(F, a, b, c, d, 4, 7, 0xf57c0faf); + STEP(F, d, a, b, c, 5, 12, 0x4787c62a); + STEP(F, c, d, a, b, 6, 17, 0xa8304613); + STEP(F, b, c, d, a, 7, 22, 0xfd469501); + STEP(F, a, b, c, d, 8, 7, 0x698098d8); + STEP(F, d, a, b, c, 9, 12, 0x8b44f7af); + STEP(F, c, d, a, b, 10, 17, 0xffff5bb1); + STEP(F, b, c, d, a, 11, 22, 0x895cd7be); + STEP(F, a, b, c, d, 12, 7, 0x6b901122); + STEP(F, d, a, b, c, 13, 12, 0xfd987193); + STEP(F, c, d, a, b, 14, 17, 0xa679438e); + STEP(F, b, c, d, a, 15, 22, 0x49b40821); + STEP(G, a, b, c, d, 1, 5, 0xf61e2562); + STEP(G, d, a, b, c, 6, 9, 0xc040b340); + STEP(G, c, d, a, b, 11, 14, 0x265e5a51); + STEP(G, b, c, d, a, 0, 20, 0xe9b6c7aa); + STEP(G, a, b, c, d, 5, 5, 0xd62f105d); + STEP(G, d, a, b, c, 10, 9, 0x02441453); + STEP(G, c, d, a, b, 15, 14, 0xd8a1e681); + STEP(G, b, c, d, a, 4, 20, 0xe7d3fbc8); + STEP(G, a, b, c, d, 9, 5, 0x21e1cde6); + STEP(G, d, a, b, c, 14, 9, 0xc33707d6); + STEP(G, c, d, a, b, 3, 14, 0xf4d50d87); + STEP(G, b, c, d, a, 8, 20, 0x455a14ed); + STEP(G, a, b, c, d, 13, 5, 0xa9e3e905); + STEP(G, d, a, b, c, 2, 9, 0xfcefa3f8); + STEP(G, c, d, a, b, 7, 14, 0x676f02d9); + STEP(G, b, c, d, a, 12, 20, 0x8d2a4c8a); + STEP(H, a, b, c, d, 5, 4, 0xfffa3942); + STEP(H, d, a, b, c, 8, 11, 0x8771f681); + STEP(H, c, d, a, b, 11, 16, 0x6d9d6122); + STEP(H, b, c, d, a, 14, 23, 0xfde5380c); + STEP(H, a, b, c, d, 1, 4, 0xa4beea44); + STEP(H, d, a, b, c, 4, 11, 0x4bdecfa9); + STEP(H, c, d, a, b, 7, 16, 0xf6bb4b60); + STEP(H, b, c, d, a, 10, 23, 0xbebfbc70); + STEP(H, a, b, c, d, 13, 4, 0x289b7ec6); + STEP(H, d, a, b, c, 0, 11, 0xeaa127fa); + STEP(H, c, d, a, b, 3, 16, 0xd4ef3085); + STEP(H, b, c, d, a, 6, 23, 0x04881d05); + STEP(H, a, b, c, d, 9, 4, 0xd9d4d039); + STEP(H, d, a, b, c, 12, 11, 0xe6db99e5); + STEP(H, c, d, a, b, 15, 16, 0x1fa27cf8); + STEP(H, b, c, d, a, 2, 23, 0xc4ac5665); + STEP(I, a, b, c, d, 0, 6, 0xf4292244); + STEP(I, d, a, b, c, 7, 10, 0x432aff97); + STEP(I, c, d, a, b, 14, 15, 0xab9423a7); + STEP(I, b, c, d, a, 5, 21, 0xfc93a039); + STEP(I, a, b, c, d, 12, 6, 0x655b59c3); + STEP(I, d, a, b, c, 3, 10, 0x8f0ccc92); + STEP(I, c, d, a, b, 10, 15, 0xffeff47d); + STEP(I, b, c, d, a, 1, 21, 0x85845dd1); + STEP(I, a, b, c, d, 8, 6, 0x6fa87e4f); + STEP(I, d, a, b, c, 15, 10, 0xfe2ce6e0); + STEP(I, c, d, a, b, 6, 15, 0xa3014314); + STEP(I, b, c, d, a, 13, 21, 0x4e0811a1); + STEP(I, a, b, c, d, 4, 6, 0xf7537e82); + STEP(I, d, a, b, c, 11, 10, 0xbd3af235); + STEP(I, c, d, a, b, 2, 15, 0x2ad7d2bb); + STEP(I, b, c, d, a, 9, 21, 0xeb86d391); + + ctx->a += a; + ctx->b += b; + ctx->c += c; + ctx->d += d; + + memset(X, 0, sizeof(X)); +} + +void mcu_md5_init(mcu_md5_context* ctx) { + assert(ctx != NULL); + memset(ctx, 0, sizeof(mcu_md5_context)); + // initialization values from RFC 1321, Section 3.3: + ctx->a = 0x67452301; + ctx->b = 0xEFCDAB89; + ctx->c = 0x98BADCFE; + ctx->d = 0x10325476; +} + +#define TO_U8(x,o,i) do{ \ + o[i] = (x) & 0xFF; \ + o[i+1] = ((x) >> 8) & 0xFF; \ + o[i+2] = ((x) >> 16) & 0xFF; \ + o[i+3] = ((x) >> 24) & 0xFF; }while(0) + +void mcu_md5_digest(mcu_md5_context* ctx, void* buffer, size_t size) { + uint8_t* bytes = (uint8_t*)buffer; + uint64_t message_bits = size * 8; + ssize_t rem_size = size; + while (rem_size > 64) { + mcu_md5_block(ctx, bytes); + bytes += 64; + rem_size -= 64; + } + uint8_t scratch[64]; + memset(scratch, 0, 64); + memcpy(scratch, bytes, rem_size); + if (rem_size == 64) { + mcu_md5_block(ctx, scratch); + memset(scratch, 0, 64); + scratch[0] = 0x80; + } else { + scratch[rem_size] = 0x80; + if (64 - (rem_size + 1) < 8) { + mcu_md5_block(ctx, scratch); + memset(scratch, 0, 64); + } + } + TO_U8(message_bits, scratch, 56); + TO_U8(message_bits>>32, scratch, 60); + mcu_md5_block(ctx, scratch); + memset(scratch, 0x00, 64); +} + +void mcu_md5_output(mcu_md5_context* ctx, uint8_t out[16]) { + TO_U8(ctx->a, out, 0); + TO_U8(ctx->b, out, 4); + TO_U8(ctx->c, out, 8); + TO_U8(ctx->d, out, 12); +} diff --git a/src/include/collect/gen_vec.h b/src/include/collect/gen_vec.h new file mode 100644 index 0000000..a3ba3fd --- /dev/null +++ b/src/include/collect/gen_vec.h @@ -0,0 +1,21 @@ + +#ifndef _H_MCUTIL_COLLEC_GEN_VEC +#define _H_MCUTIL_COLLEC_GEN_VEC + +#include "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/src/include/collect/hash_map.h b/src/include/collect/hash_map.h new file mode 100644 index 0000000..c0fbe66 --- /dev/null +++ b/src/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.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/src/include/collect/str.h b/src/include/collect/str.h new file mode 100644 index 0000000..b5c1fc0 --- /dev/null +++ b/src/include/collect/str.h @@ -0,0 +1,42 @@ +#ifndef _H_MCU_STR +#define _H_MCU_STR + +#include "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/src/include/hash/md5.h b/src/include/hash/md5.h new file mode 100644 index 0000000..78a86b5 --- /dev/null +++ b/src/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/src/include/iter.h new file mode 100644 index 0000000..927e2ea --- /dev/null +++ b/src/include/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/mccu/include/lambda.h b/src/include/lambda.h similarity index 92% rename from mccu/include/lambda.h rename to src/include/lambda.h index 701f7ad..56a086d 100644 --- a/mccu/include/lambda.h +++ b/src/include/lambda.h @@ -1,5 +1,5 @@ -#ifndef _H_MCORANGE_LAMBDA -#define _H_MCORANGE_LAMBDA +#ifndef _H_MCUTIL_LAMBDA +#define _H_MCUTIL_LAMBDA #if defined(_MSC_VER) && !defined(__MC_LMBD_DEF) #define __MC_LMBD_DEF diff --git a/src/include/mcutil.h b/src/include/mcutil.h new file mode 100644 index 0000000..f61bc01 --- /dev/null +++ b/src/include/mcutil.h @@ -0,0 +1,29 @@ + +#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__) + #define MCU_API __attribute__((visibility("default"))) +#else + #define MCU_API + #pragma warning Unknown dynamic link import/export semantics. +#endif + + +#endif diff --git a/src/include/result.h b/src/include/result.h new file mode 100644 index 0000000..c788511 --- /dev/null +++ b/src/include/result.h @@ -0,0 +1,34 @@ +#ifndef _H_MCU_RESULT +#define _H_MCU_RESULT + +#include "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/test.c b/test.c new file mode 100644 index 0000000..7d1c0d2 --- /dev/null +++ b/test.c @@ -0,0 +1,14 @@ +// #include "collec/gen_vec.h" +#include "result.h" +#include +#include + +int main(void) { + int a = 1; + mcu_result_t good = Ok(&a); + mcu_result_t bad = Err("Owo?"); + mcu_result_unwrap(good); + mcu_result_unwrap(bad); + + return 0; +}