feat: add stack

This commit is contained in:
2025-09-10 16:45:50 +02:00
parent 9c037c5e25
commit 610bf5dab9
8 changed files with 161 additions and 12 deletions

View File

@@ -9,6 +9,7 @@ A small, personal C library for learning and experimentation.
- Thread-safe dynamic strings
- Thread-safe circular queues
- Thread-safe vectors
- Stack
## Usage

View File

@@ -10,6 +10,7 @@ src = files(
'queue/myqueue.c',
'string/mystring.c',
'vector/myvector.c',
'stack/mystack.c',
)
testlib = files(
@@ -20,6 +21,7 @@ testlib = files(
'test/string/str2.c',
'test/string/str3.c',
'test/vector/v1.c',
'test/stack/s1.c',
)
sources = src + testlib

88
stack/mystack.c Normal file
View File

@@ -0,0 +1,88 @@
#include "mystack.h"
#include <stdlib.h>
#include <threads.h>
stack_s *stack_new(size_t initial_capacity, size_t element_size) {
if (element_size == 0) {
return NULL;
}
stack_s *stack = (stack_s *)malloc(sizeof(stack_s));
if (stack == NULL) {
return NULL;
}
if (mtx_init(&stack->lock, mtx_recursive) != thrd_success) {
free(stack);
return NULL;
}
/* Allocate the vec data */
stack->data = vec_new(initial_capacity, element_size);
if (stack->data == NULL) {
free(stack);
return NULL;
}
stack->elem_size = element_size;
return stack;
}
void *stack_pop(stack_s *stack) {
if (stack == NULL) {
return NULL;
}
if (mtx_lock(&stack->lock) != thrd_success) {
return NULL;
}
void *elem = vec_pop(stack->data);
mtx_unlock(&stack->lock);
return elem;
}
int stack_push(stack_s *stack, void *elem) {
if (stack == NULL || elem == NULL) {
return -1;
}
if (mtx_lock(&stack->lock) != thrd_success) {
return -1;
}
int ret = vec_push(stack->data, elem);
mtx_unlock(&stack->lock);
return ret;
}
void *stack_top(stack_s *stack) {
if (stack == NULL) {
return NULL;
}
if (mtx_lock(&stack->lock) != thrd_success) {
return NULL;
}
void *elem = vec_get(stack->data, stack->data->size - 1);
mtx_unlock(&stack->lock);
return elem;
}
void stack_free(stack_s *stack) {
if (stack == NULL) {
return;
}
vec_free(stack->data);
free(stack);
}

25
stack/mystack.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef MYCLIB_STACK_H
#define MYCLIB_STACK_H
#include <stddef.h>
#include <threads.h>
#include "../vector/myvector.h"
typedef struct stack {
vec_s *data;
size_t elem_size;
mtx_t lock;
} stack_s;
stack_s *stack_new(size_t initial_capacity, size_t element_size);
void *stack_pop(stack_s *stack);
int stack_push(stack_s *stack, void *elem);
void *stack_top(stack_s *stack);
void stack_free(stack_s *stack);
#endif

23
test/stack/s1.c Normal file
View File

@@ -0,0 +1,23 @@
#include <assert.h>
#include <stdlib.h>
#include "../../stack/mystack.h"
void test_s1(void) {
stack_s *stack = stack_new(32, sizeof(int));
int num = 10;
stack_push(stack, &num);
num = 13;
stack_push(stack, &num);
int *rv = (int *)stack_top(stack);
assert(*rv == 13);
free(rv);
rv = (int *)stack_pop(stack);
assert(*rv == 13);
free(rv);
stack_free(stack);

View File

@@ -5,15 +5,17 @@
#include <assert.h>
#include <stdio.h>
void test_hm1();
void test_hm1(void);
void test_q1();
void test_q1(void);
void test_str1();
void test_str2();
void test_str3();
void test_str1(void);
void test_str2(void);
void test_str3(void);
void test_v1();
void test_v1(void);
void test_s1(void);
int main(void) {
puts("==== [Running Hashmap tests] ====");
@@ -38,5 +40,10 @@ int main(void) {
puts("OK!");
puts("");
puts("==== [Running Stack tests] ====");
test_s1();
puts("OK!");
puts("");
return 0;
}

View File

@@ -1,5 +1,4 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "../../vector/myvector.h"
@@ -15,11 +14,12 @@ static void multiply(size_t index, void *elem) {
e->age = e->age * 2;
}
/* Another way to use foreach */
/* Another way to use foreach
static void print(size_t index, void *elem) {
my_elem_s *e = (my_elem_s *)elem;
printf("%s (%d)\n", e->name, e->age);
}
*/
/* Compare function used to sort */
int my_cmp(const void *a, const void *b) {
@@ -70,13 +70,10 @@ void test_v1() {
/* Iterate for each element */
vec_foreach(v, multiply);
/* Print each element */
puts("Before sort:");
vec_foreach(v, print);
// vec_foreach(v, print);
/* Sort */
vec_sort(v, my_cmp);
puts("After sort:");
vec_foreach(v, print);
/* Deallocate the vector */
vec_free(v);

View File

@@ -305,7 +305,13 @@ int vec_sort(vec_s *vec, int (*cmp)(const void *a, const void *b)) {
return -1;
}
if (mtx_lock(&vec->lock) != thrd_success) {
return -1;
}
qsort(vec->data, vec->size, vec->elem_size, cmp);
mtx_unlock(&vec->lock);
return 0;
}