summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--array.c55
-rw-r--r--array.h20
-rw-r--r--str.c124
-rw-r--r--str.h37
-rw-r--r--types.h11
5 files changed, 210 insertions, 37 deletions
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 <string.h>
+#include <stdlib.h>
-#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 <stddef.h>
+#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 <stdlib.h>
+#include <string.h>
+
+#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 <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef uintptr_t size_t;
+typedef intptr_t ssize_t;
+
+#endif