From cce2320974e214e81ebf2564c4e17f1c9912ae88 Mon Sep 17 00:00:00 2001 From: Daniel Bulant Date: Mon, 2 Dec 2024 20:12:11 +0100 Subject: [PATCH] start working on c --- .vscode/settings.json | 6 ++ 2024/c/.gitignore | 1 + 2024/c/01.c | 124 ++++++++++++++++++++++++++++++++++++++++++ 2024/c/Makefile | 14 +++++ 4 files changed, 145 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 2024/c/.gitignore create mode 100644 2024/c/01.c create mode 100644 2024/c/Makefile diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..2ac52f0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "*.nomad": "hcl", + "vector": "c" + } +} \ No newline at end of file diff --git a/2024/c/.gitignore b/2024/c/.gitignore new file mode 100644 index 0000000..c5e82d7 --- /dev/null +++ b/2024/c/.gitignore @@ -0,0 +1 @@ +bin \ No newline at end of file diff --git a/2024/c/01.c b/2024/c/01.c new file mode 100644 index 0000000..7561aae --- /dev/null +++ b/2024/c/01.c @@ -0,0 +1,124 @@ +#include +#include +#include + +#define usize unsigned long + +// A Vector type +struct DynSlice { + void* data; + usize size; + usize capacity; + usize size_of; +}; + +// Constructs a new dyn slice, a vector type +// default capacity is 0 and no backing data is allocated, use DS_grow +struct DynSlice DS_create(usize size_of) { + struct DynSlice slice; + slice.data = NULL; + slice.size = 0; + slice.capacity = 0; + slice.size_of = size_of; + return slice; +} + +// Exit with message and error code 1 +void panic(char* msg) { + printf("%s\n", msg); + exit(1); +} + +// Grows slice to at least the given size (nearest power of 2 higher) +// panics if malloc fails +void DS_grow(struct DynSlice* slice, usize newcap) { + usize cap = slice->capacity; + usize size = slice->size; + printf("Growing %li %li\n", cap, size); + + void* dataptr = slice->data; + + if(cap == 0) cap = 1; + while(cap < newcap) { + cap <<= 1; + } + + void* newdataptr = malloc(cap * slice->size_of); + if(newdataptr == NULL) { + panic("DS malloc failed during grow"); + } + if(dataptr) { + memcpy(newdataptr, dataptr, size * slice->size_of); + free(dataptr); + } + slice->capacity = cap; + slice->data = newdataptr; +} + +void DS_debugprint(struct DynSlice* slice) { + printf("dynslice, size %li, cap %li, size of %li", slice->size, slice->capacity, slice->size_of); +} + +// Pushes a new object. Accepts a pointer to said object. Copies. +// returns index of pushed data +// assumes size_of from slice. Take care of types lol. +usize DS_push(struct DynSlice* slice, void* ptr) { + usize cap = slice->capacity; + usize size = slice->size; + if(cap <= size) { + DS_grow(slice, cap+1); + } + memcpy(slice->data + slice->size * slice->size_of, ptr, slice->size_of); + slice->size += 1; + return size; +} + +// Extends a slice from another array-like object +void DS_extend(struct DynSlice* slice, void* ptr, usize count) { + if(slice->capacity < slice->size + count) DS_grow(slice, slice->size + count); + printf("extending %li\n", count); + DS_debugprint(slice); + memcpy(slice->data + slice->size * slice->size_of, ptr, slice->size_of * count); + slice->size += count; +} + +// Extends DynSlice from another DynSlice, checking their sizes for (partial) memory safety +void DS_extend_slice(struct DynSlice* target, struct DynSlice* src) { + if(target->size_of != src->size_of) { + panic("DS invalid extend_slice, different sizes"); + } + DS_extend(target, src->data, src->size); +} + +// Extends a slice from string. Checks size_of is correct, and calls strlen +void DS_extend_string(struct DynSlice* slice, void* ptr) { + if(slice->size_of != sizeof(char)) panic("DS extend string on a non-char slice"); + usize len = strlen(ptr); + DS_extend(slice, ptr, len); +} + +// Drops slice in place - resets to empty +void DS_drop(struct DynSlice* slice) { + slice->capacity = 0; + slice->size = 0; + free(slice->data); +} + +// Gets pointer to a single element, checking it's size +void* DS_get(struct DynSlice* slice, usize i) { + if(slice->size >= i) { + panic("DS Get out of bounds"); + } + return slice->data + i * slice->size_of; +} + +int main() { + // FILE* file = fopen("input.txt", "r"); + setvbuf(stdout, NULL, _IONBF, 0); + struct DynSlice example = DS_create(sizeof(char)); + DS_extend_string(&example, "Hello, "); + DS_extend_string(&example, "world!"); + DS_push(&example, '\0'); + printf("%s\n", (char*)example.data); + DS_drop(&example); +} \ No newline at end of file diff --git a/2024/c/Makefile b/2024/c/Makefile new file mode 100644 index 0000000..b1b7360 --- /dev/null +++ b/2024/c/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -g + +all: 01 + +createdir: + mkdir -p bin + +01: createdir 01.c + gcc 01.c -o bin/01 + ./bin/01 + +clean: + rm -r bin \ No newline at end of file