From 945343daa08986878de0476bce56817b450a3278 Mon Sep 17 00:00:00 2001 From: Squibid Date: Sat, 15 Nov 2025 21:47:45 -0500 Subject: [PATCH] feat(stack): introduce a stack ds, internally this uses a sll --- README.md | 14 ++++++++++++++ ds.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ ds.h | 38 ++++++++++++++++++++++++++++++++++++++ test.c | 22 ++++++++++++++++++++++ 4 files changed, 127 insertions(+) diff --git a/README.md b/README.md index 650a3c6..1affa24 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,20 @@ ds_hmp_free(&hmp, NULL); free(b); ``` +## Stack +```c +char *a = "a"; +char *b = "b"; + +ds_stack_t *stack = ds_stack_init(); +ds_stack_push(stack, a); // [ "a" ] +ds_stack_push(stack, b); // [ "b", "a" ] +ds_stack_peek(stack, 0); // "b" +ds_stack_pop(stack); // "b" +ds_stack_pop(stack); // "a" +free(stack); +``` + # TODO - [ ] more data structures - [x] tests diff --git a/ds.c b/ds.c index 25f36b3..73ab51a 100644 --- a/ds.c +++ b/ds.c @@ -367,3 +367,56 @@ void return NULL; } + +ds_stack_t +*ds_stack_init(void) +{ + ds_stack_t *stack = malloc(sizeof(ds_stack_t)); + stack->n = 0; + + return stack; +} + +int +ds_stack_push(ds_stack_t *stack, void *data) +{ + if (stack->n == 0) { + stack->items = ds_sll_new_node(data); + stack->n++; + return 0; + } + int r = ds_sll_add(&stack->items, data, 0); + if (!r) { + stack->n++; + } + return r; +} + +void +*ds_stack_pop(ds_stack_t *stack) +{ + void *r = ds_sll_remove(&stack->items, 0); + if (r != NULL) { + stack->n--; + } + return r; +} + +void +*ds_stack_peek(ds_stack_t *stack, unsigned x) +{ + int i; + ds_sll_t *cur; + + if (x > stack->n) { + return NULL; + } + + for (cur = stack->items, i = 0; cur; cur = cur->next, i++) { + if (i == x) { + return cur->data; + } + } + + return NULL; +} diff --git a/ds.h b/ds.h index 93e99db..e7bec5c 100644 --- a/ds.h +++ b/ds.h @@ -22,6 +22,11 @@ typedef struct { void *val; } _ds_hmp_kv_t; +typedef struct { + unsigned n; + ds_sll_t *items; +} ds_stack_t; + #define ds_ll_foreach(t, ll) for (t *cur = ll; cur; cur = cur->next) /** @@ -168,4 +173,37 @@ void *ds_hmp_get(ds_hmp_t *hmp, char *key); */ void *ds_hmp_remove(ds_hmp_t *hmp, char *key); +/** + * @brief initialize a new stack + * + * @return the stack + */ +ds_stack_t *ds_stack_init(void); + +/** + * @brief push new data onto the stack + * + * @param stack the stack + * @param data the data + * @return 0 on success + */ +int ds_stack_push(ds_stack_t *stack, void *data); + +/** + * @brief pop the data off the top of the stack + * + * @param stack the stack + * @return the data + */ +void *ds_stack_pop(ds_stack_t *stack); + +/** + * @brief peek forward x items + * + * @param stack the stack + * @param x how many items to look ahead + * @return the data or NULL if out of range + */ +void *ds_stack_peek(ds_stack_t *stack, unsigned x); + #endif diff --git a/test.c b/test.c index dc84bc9..1031eb4 100644 --- a/test.c +++ b/test.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -76,4 +77,25 @@ main(int argc, char *argv[]) free(a); ); + + test("stack", + char *a = "a"; + char *b = "b"; + char *c = "c"; + + ds_stack_t *stack = ds_stack_init(); + it("pushes an item", ds_stack_push(stack, a) == 0); + it("pops an item", ds_stack_pop(stack) == a); + + ds_stack_push(stack, b); + ds_stack_push(stack, c); + + it("peeks ahead", ds_stack_peek(stack, 0) == c); + it("peeks past the stack", ds_stack_peek(stack, INT_MAX) == NULL); + + ds_stack_pop(stack); + ds_stack_pop(stack); + + free(stack); + ); }