commit f4d4a8ab0043be496f8e0532b4aae41aaeee4b67 Author: cannoli-fruit Date: Wed Jul 8 22:34:18 2026 -0400 init diff --git a/.gitingnore b/.gitingnore new file mode 100644 index 0000000..f8305e7 --- /dev/null +++ b/.gitingnore @@ -0,0 +1 @@ +a.out \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a42ecc0 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# LAZY.h +I like C but i'm also getting tired of writing dynamic arrays, hopefully this is just all the default data structures and utilities for having fun in C. + +Don't expect production ready, I'll probably change most things a decent amount +If you want consistency just clone the header file and don't update diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..7ab4a92 --- /dev/null +++ b/TODO.md @@ -0,0 +1,3 @@ +# TODO +Change all string slice functions to start with lz_slc + diff --git a/a.out b/a.out new file mode 100755 index 0000000..70dc073 Binary files /dev/null and b/a.out differ diff --git a/examples/da_float.c b/examples/da_float.c new file mode 100644 index 0000000..08455a3 --- /dev/null +++ b/examples/da_float.c @@ -0,0 +1,17 @@ +#include +#define LAZY_IMPL +#include "lazy.h" + +int main() { + Lz_DA(float) nums = {0}; + lz_da_reserve(nums, 64); + for (int i = 0; i < 32; ++i) { + lz_da_append(nums, 2.0*i); + } + + for (int i = 0; i < nums.cnt; ++i) { + printf("%f\n", nums.elts[i]); + } + + return 0; +} diff --git a/examples/da_ins.c b/examples/da_ins.c new file mode 100644 index 0000000..01d7664 --- /dev/null +++ b/examples/da_ins.c @@ -0,0 +1,22 @@ +#include +#define LAZY_IMPL +#include "../lazy.h" + +int main() { + Lz_DA(int) xs = {0}; + lz_da_append(xs, 1); + lz_da_append(xs, 3); + lz_da_append(xs, 4); + lz_da_shrink_to_fit(xs); + + for (int i = 0; i < xs.cnt; ++i) { + printf("%d: %d\n", i, xs.elts[i]); + } + + printf("\n"); + lz_da_insert(xs,1,2); + + for (int i = 0; i < xs.cnt; ++i) { + printf("%d: %d\n", i, xs.elts[i]); + } +} diff --git a/examples/sb_concat.c b/examples/sb_concat.c new file mode 100644 index 0000000..a2a2af8 --- /dev/null +++ b/examples/sb_concat.c @@ -0,0 +1,14 @@ +#include +#define LAZY_IMPL +#include "../lazy.h" + +int main() { + Lz_SB sb1 = lz_sb_from_cstr("Hello "); + Lz_SB sb2 = lz_sb_from_cstr("World!"); + + lz_da_concat(sb1,sb2); + + printf(LZ_STR_FMT"\n", LZ_STR_PRINTF(sb1)); + + return 0; +} diff --git a/examples/string_split.c b/examples/string_split.c new file mode 100644 index 0000000..0de3d94 --- /dev/null +++ b/examples/string_split.c @@ -0,0 +1,25 @@ +#define LAZY_IMPL +#include "lazy.h" +#include +#include +#include + +int isnotalpha(int x) { return !isalpha(x); } + +int main() { + char *src = strdup("This is a list of words, which apparently has been referred to previously as a sentence") + Lz_Slc s = lz_cstr_to_slc(src); + + Lz_Slc word; + int i = 0; + do { + lz_split_slc_typ(&s, isnotalpha, &word); + printf("Word %d: "LZ_SLC_FMT"\n", i, LZ_SLC_PRINTF(word)); + ++i; + } while(s.len != 0); + + free(src); + + return 0; + +} diff --git a/examples/string_trim.c b/examples/string_trim.c new file mode 100644 index 0000000..83b3502 --- /dev/null +++ b/examples/string_trim.c @@ -0,0 +1,17 @@ +#include +#include +#define LAZY_IMPL +#include "lazy.h" + +int main() { + char *src = strdup(" \t This text has some extra whitespace \t "); + Lz_Slc s = lz_cstr_to_slc(src); + + printf("|"LZ_SLC_FMT"|\n", LZ_SLC_PRINTF(s)); + lz_trim_typ(&s, isspace); + printf("|"LZ_SLC_FMT"|\n", LZ_SLC_PRINTF(s)); + + free(src); // excessive but this is how you should do it + + return 0; +} diff --git a/lazy.h b/lazy.h new file mode 100644 index 0000000..055591b --- /dev/null +++ b/lazy.h @@ -0,0 +1,162 @@ +#include +#include +#include +#include + +#define LZ_STR_FMT "%.*s" +#define LZ_STR_PRINTF(slc) (int)slc.cnt, slc.data + +typedef struct { + char *data; + size_t cnt; +} Lz_Slc; + +void lz_trim_left_typ(Lz_Slc *src, int (*classfunc)(int)); +void lz_trim_right_typ(Lz_Slc *src, int (*classfunc)(int)); +void lz_trim_typ(Lz_Slc *src, int (*classfunc)(int)); +void lz_drop_left(Lz_Slc *src, size_t n); +void lz_drop_right(Lz_Slc *src, size_t n); +void lz_split_slc(Lz_Slc *src, char delim, Lz_Slc *dst); +void lz_split_slc_typ(Lz_Slc *src, int (*classfunc)(int), Lz_Slc *dst); +Lz_Slc lz_cstr_to_slc(char *dat); + +#define Lz_DA(T) struct {T *data; size_t cnt; size_t cap; } +#define lz_da_append(da, x) do { \ + if ((da).cap > (da).cnt) {\ + (da).data[(da).cnt++] = (x);\ + } else if((da).cap == 0) {\ + (da).data = malloc(256*sizeof(*(da).data));\ + (da).cap = 256;\ + (da).cnt = 0;\ + (da).data[(da).cnt++] = (x);\ + } else {\ + (da).data = realloc((da).data, sizeof(*(da).data)*(da).cap*(2));\ + (da).cap *= 2;\ + (da).data[(da).cnt++] = (x);\ + }\ +} while(0) +#define lz_da_insert(da, i, x) do {\ + if ((i) > (da).cnt) {\ + assert(0 && "Insert out of dynamic array size");\ + }\ + if ((i) < 0) {\ + assert(0 && "Negative index of insertion");\ + }\ + if ((da).cap > (da).cnt) {\ + memmove((da).data+(i)+1,(da).data+(i),((da).cnt-(i))*sizeof(*(da).data));\ + (da).data[i] = (x);\ + (da).cnt++;\ + } else if ((da).cap == (da).cnt) {\ + (da).data = realloc((da).data, sizeof(*(da).data)*(da).cap*2);\ + (da).cap *= 2;\ + memmove((da).data+(i)+1,(da).data+(i),((da).cnt-(i))*sizeof(*(da).data));\ + (da).data[i] = (x);\ + (da).cnt++;\ + } else {\ + assert(0 && "Unreachable thru proper dynamic array functions");\ + }\ +} while(0) +#define lz_da_pop(da) do {\ + if ((da).cnt > 0) {\ + (da).cnt--;\ + }\ +} while(0) +#define lz_da_concat(dst,src) do {\ + if (sizeof(*(dst).data) != sizeof(*(dst).data)) {\ + assert(0 && "Mismatched types of arrays being concatenated");\ + }\ + lz_da_reserve((dst),((src).cnt+(dst).cnt));\ + memcpy((dst).data+(dst).cnt, (src).data, (src).cnt*sizeof(*(dst).data));\ + (dst).cnt = ((src).cnt+(dst).cnt);\ +} while(0) +#define lz_da_destroy(da) do { free((da).data); } while (0); +#define lz_da_reserve(da, size) do {\ + if ((da).cap < (size)) {\ + (da).data = realloc((da).data, (size)*sizeof(*(da).data));\ + (da).cap = (size);\ + }\ +} while (0) +#define lz_da_shrink_to_fit(da) do {\ + if ((da).cnt == (da).cap) break;\ + (da).data = realloc((da).data, (da).cnt * sizeof(*(da).data));\ + (da).cap = (da).cnt;\ +} while(0) + +typedef Lz_DA(char) Lz_SB; + +#ifdef LAZY_IMPL +void lz_drop_left(Lz_Slc *src, size_t n) { + if (src->cnt < n) n = src->cnt; + src->data += n; + src->cnt -= n; +} + +void lz_drop_right(Lz_Slc *src, size_t n) { + if (src->cnt < n) n = src->cnt; + src->cnt -= n; +} + +void lz_trim_left_typ(Lz_Slc *src, int (*classfunc)(int)) { + while (classfunc(src->data[0])) { + lz_drop_left(src, 1); + } +} + +void lz_trim_right_typ(Lz_Slc *src, int (*classfunc)(int)) { + while (classfunc(src->data[src->cnt-1])) { + lz_drop_right(src, 1); + } +} + +void lz_trim_typ(Lz_Slc *src, int (*classfunc)(int)) { + lz_trim_left_typ(src, classfunc); + lz_trim_right_typ(src, classfunc); +} + +void lz_split_slc(Lz_Slc *src, char delim, Lz_Slc *dst) { + size_t i = 0; + while (i < src->cnt && src->data[i] != delim) { + ++i; + } + dst->data = src->data; + dst->cnt = i; + if (src->cnt != i) { + src->data += i+1; + src->cnt -= i+1; + } else { + src->cnt = 0; + } +} + +void lz_split_slc_typ(Lz_Slc *src, int (*classfunc)(int), Lz_Slc *dst) { + size_t i = 0; + while (i < src->cnt && !classfunc(src->data[i])) { + ++i; + } + dst->data = src->data; + dst->cnt = i; + if (src->cnt != i) { + src->data += i+1; + src->cnt -= i+1; + } else { + src->cnt = 0; + } + lz_trim_left_typ(src, classfunc); +} + +Lz_SB lz_sb_from_cstr(const char *dat) { + size_t len = strlen(dat); + Lz_SB sb = {0}; + lz_da_reserve(sb, len); + memcpy(sb.data, dat, len*sizeof(char)); + sb.cnt = len; + return sb; +} + +Lz_Slc lz_cstr_to_slc(char *dat) { + Lz_Slc out = {0}; + out.data = dat; + out.cnt = strlen(dat); + return out; +} +#endif