From b364a39849fc4a6f6837f8558b7520efc24ae96c Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Sun, 25 Jan 2026 16:00:20 -0500 Subject: bring in some library functions and restructure --- array.c | 55 ++++++++++++++++------------ array.h | 20 ++++------- str.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ str.h | 37 +++++++++++++++++++ types.h | 11 ++++++ 5 files changed, 210 insertions(+), 37 deletions(-) create mode 100644 str.c create mode 100644 str.h create mode 100644 types.h diff --git a/array.c b/array.c index d8765c1..7d55041 100644 --- a/array.c +++ b/array.c @@ -1,39 +1,48 @@ #include "array.h" #include "crash.h" #include +#include -#define CRASH_IF_OOB(array, idx) {\ - if (idx >= array->length)\ - crash("Array access out of bounds: %ld >= %ld\n", idx, array->length);\ +#define CRASH_IF_OOB(array, len) {\ + if (len > array.length)\ + crash("Array access out of bounds: %ld > %ld\n", len, array.length);\ } -void* array_at(const array_t* array, size_t idx) { +void* array_at(const array_t array, size_t idx) { CRASH_IF_OOB(array, idx); - return (char*)array->__data + idx*array->elemsz; + return (char*)array.__data + idx*array.elemsz; } -char* str_at(const str_t* str, size_t idx) { - CRASH_IF_OOB(str, idx); - return str->__data + idx; +array_t array_slice(const array_t array, size_t start, size_t length) { + CRASH_IF_OOB(array, start + length); + array_t slice = { + .length = length, + .__data = (char*)array.__data + start * array.elemsz + }; + return slice; } -str_t str_slice(const str_t* str, size_t start, size_t length) { - CRASH_IF_OOB(str, start + length - 1); - str_t slice = {.length = length, .__data = str->__data + start}; - return slice; +array_t array_init(void* data, size_t length, size_t elemsz) { + array_t array = {.length = length, .elemsz = elemsz, .__data = data}; + return array; } -void str_c_str( - char* dst, - size_t dst_size, - const str_t* src -) { - if (src->length >= dst_size) +array_t array_heap_alloc(size_t length, size_t elemsz) { + void* data_ptr = calloc(length, elemsz); + if (data_ptr == NULL) crash( - "String is too long to hold in C string buffer: %ld >= %ld\n", - src->length, - dst_size); + "Out of memory allocating %ld elements of size %ld\n", + length, + elemsz); + + array_t container = { + .length = length, + .elemsz = elemsz, + .__data = data_ptr, + }; + return container; +} - memmove(dst, src->__data, src->length); - dst[src->length] = 0; +void array_heap_destroy(array_t array) { + free(array.__data); } diff --git a/array.h b/array.h index 5634dc7..ded3216 100644 --- a/array.h +++ b/array.h @@ -1,6 +1,6 @@ #ifndef __SAFEC_ARRAY_H #define __SAFEC_ARRAY_H -#include +#include "types.h" typedef struct { size_t length; @@ -8,20 +8,12 @@ typedef struct { void* __data; } array_t; -void* array_at(const array_t* array, size_t idx); +void* array_at(const array_t array, size_t idx); +array_t array_slice(const array_t array, size_t start, size_t length); -typedef struct { - size_t length; - char* __data; -} str_t; +array_t array_init(void* data, size_t length, size_t elemsz); -char* str_at(const str_t* str, size_t idx); -str_t str_slice(const str_t* str, size_t start, size_t length); -void str_c_str( - char* dst, - size_t dst_size, - const str_t* src -); +array_t array_heap_alloc(size_t length, size_t elemsz); +void array_heap_destroy(array_t array); -/* TODO: reimplement string.h functions for this new string construct */ #endif diff --git a/str.c b/str.c new file mode 100644 index 0000000..5f03e35 --- /dev/null +++ b/str.c @@ -0,0 +1,124 @@ +#include "str.h" +#include "crash.h" +#include +#include + +#define CRASH_IF_OOB(str, len) {\ + if (len > str.length)\ + crash("String access out of bounds: %ld > %ld\n", len, str.length);\ +} + +static inline char* alloc_data_ptr(size_t length) { + char* data_ptr = malloc(length); + if (data_ptr == NULL) + crash("Out of memory allocating new string of length %ld\n", length); + return data_ptr; +} + +static inline char* alloc_c_str(size_t length) { + char* c_str = malloc(length + 1); + if (c_str == NULL) + crash("Out of memory allocating C string buffer of size %ld", length + 1); + + c_str[length] = 0; + return c_str; +} + +char* str_at(const str_t str, size_t idx) { + CRASH_IF_OOB(str, idx + 1); + return str.__data + idx; +} + +str_t str_slice(const str_t str, size_t start, size_t length) { + CRASH_IF_OOB(str, start + length); + str_t slice = {.length = length, .__data = str.__data + start}; + return slice; +} + +int str_cmp(const str_t s1, const str_t s2) { + if (s1.length == s2.length) + return memcmp(s1.__data, s2.__data, s1.length); + else if (s1.length > s2.length) { + int cmp = memcmp(s1.__data, s2.__data, s2.length); + if (cmp != 0) return cmp; + return 1; + } else { + int cmp = memcmp(s1.__data, s2.__data, s1.length); + if (cmp != 0) return cmp; + return -1; + } +} + +ssize_t str_indexof(const str_t str, char c) { + for (ssize_t i = 0; i < str.length; i++) { + if (str.__data[i] == c) return i; + } + return -1; +} + +ssize_t str_rindexof(const str_t str, char c) { + for (ssize_t i = (ssize_t)str.length - 1; i >= 0; i--) { + if (str.__data[i] == c) return i; + } + return -1; +} + +str_t str_heap_dup(const str_t str) { + char* data_ptr = alloc_data_ptr(str.length); + str_t dup_str = {.length = str.length, .__data = data_ptr}; + return dup_str; +} + +str_t str_heap_cat(const str_t s1, const str_t s2) { + size_t new_len = s1.length + s2.length; + char* data_ptr = alloc_data_ptr(new_len); + str_t cat_str = {.length = new_len, .__data = data_ptr}; + return cat_str; +} + +void str_to_c_str(char* dst, size_t dst_size, const str_t* src) { + if (src->length >= dst_size) + crash( + "String is too long to hold in C string buffer: %ld >= %ld\n", + src->length, + dst_size); + + memmove(dst, src->__data, src->length); + dst[src->length] = 0; +} + +char* str_to_heap_c_str(const str_t src) { + char* dst = alloc_c_str(src.length); + memcpy(dst, src.__data, src.length); + return dst; +} + +str_t str_init(char* data, size_t length) { + str_t str = {.length = length, .__data = data}; + return str; +} + +str_t str_heap_alloc(size_t length) { + char* data_ptr = alloc_data_ptr(length); + str_t str = {.length = length, .__data = data_ptr}; + return str; +} + +str_t str_heap_alloc_iv(const char* c_str) { + size_t length = strlen(c_str); + char* data_ptr = alloc_data_ptr(length); + memcpy(data_ptr, c_str, length); + str_t str = {.length = length, .__data = data_ptr}; + return str; +} + +str_t str_heap_alloc_iv_slice(const char* c_str, size_t start, size_t length) { + char* data_ptr = alloc_data_ptr(length); + memcpy(data_ptr, c_str + start, length); + str_t str = {.length = length, .__data = data_ptr}; + return str; +} + +void str_heap_destroy(str_t str) { + free(str.__data); +} diff --git a/str.h b/str.h new file mode 100644 index 0000000..f87f68e --- /dev/null +++ b/str.h @@ -0,0 +1,37 @@ +#ifndef __SAFEC_STR_H +#define __SAFEC_STR_H +#include "types.h" + +typedef struct { + size_t length; + char* __data; +} str_t; + +// TODO: heap-allocing the pointer is stupid just return a value +// should just heap-alloc __data + +char* str_at(const str_t str, size_t idx); +str_t str_slice(const str_t str, size_t start, size_t length); +int str_cmp(const str_t s1, const str_t s2); + +/* not found = -1 */ +ssize_t str_indexof(const str_t str, char c); +ssize_t str_rindexof(const str_t str, char c); + +str_t str_heap_dup(const str_t str); +str_t str_heap_cat(const str_t s1, const str_t s2); + +/* TODO: implement string.h functions for this new string construct */ + +/* `dst` will be overwritten with the contents of `src` */ +void str_to_c_str(char* dst, size_t dst_size, const str_t* src); +char* str_to_heap_c_str(const str_t str); + +str_t str_init(char* data, size_t length); + +str_t str_heap_alloc(size_t length); +str_t str_heap_alloc_iv(const char* c_str); +str_t str_heap_alloc_iv_slice(const char* c_str, size_t start, size_t length); +void str_heap_destroy(str_t str); + +#endif diff --git a/types.h b/types.h new file mode 100644 index 0000000..d1d3ca8 --- /dev/null +++ b/types.h @@ -0,0 +1,11 @@ +#ifndef __SAFEC_TYPES_H +#define __SAFEC_TYPES_H + +#include +#include +#include + +typedef uintptr_t size_t; +typedef intptr_t ssize_t; + +#endif -- cgit v1.2.3