diff --git a/include/extra/memory.h b/include/extra/memory.h index e27f73b..e5a595e 100644 --- a/include/extra/memory.h +++ b/include/extra/memory.h @@ -12,10 +12,11 @@ typedef struct libcdsb_stack_node { void* value; } stack_t; -extern void libcdsb_stack_init (stack_t* stack) Nonnull__(1); -extern void libcdsb_stack_push (stack_t* stack, void* value) Nonnull__(1); -extern void* libcdsb_stack_pop (stack_t* stack) Nonnull__(1); -extern void libcdsb_stack_flush(stack_t* stack) Nonnull__(1); +extern void libcdsb_stack_init (stack_t* stack) Nonnull__(1); +extern void libcdsb_stack_push (stack_t* stack, void* value) Nonnull__(1); +extern void libcdsb_stack_push_many(stack_t* stack, size_t n, ...) Nonnull__(1); +extern void* libcdsb_stack_pop (stack_t* stack) Nonnull__(1); +extern void libcdsb_stack_flush (stack_t* stack) Nonnull__(1); extern void* libcdsb_aalloc (size_t a, size_t n) Warn_unused_result__; extern void* libcdsb_malloc (size_t n) Warn_unused_result__; @@ -30,9 +31,10 @@ extern void libcdsb_free(void* s); #define realloc libcdsb_realloc #define free libcdsb_free -#define stack_init libcdsb_stack_init -#define stack_push libcdsb_stack_push -#define stack_pop libcdsb_stack_pop -#define stack_flush libcdsb_stack_flush +#define stack_init libcdsb_stack_init +#define stack_push libcdsb_stack_push +#define stack_push_many libcdsb_stack_push_many +#define stack_pop libcdsb_stack_pop +#define stack_flush libcdsb_stack_flush #endif /* LIBCDSB_EXTRA_MEMORY_H */ diff --git a/src/extra-stack.c b/src/extra-stack.c index f78fdb0..563a177 100644 --- a/src/extra-stack.c +++ b/src/extra-stack.c @@ -1,6 +1,7 @@ /* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ +#include #include #include "__internal/include.h" #undef malloc @@ -26,6 +27,31 @@ void libcdsb_stack_push(stack_t* x, void* value) { x->value = value; } +void libcdsb_stack_push_many(stack_t* x, size_t c, ...) { + + va_list args; + stack_t* n; + va_start(args, c); + + if (c) { + if (!x->value) { + x->value = va_arg(args, void*); + --c; + } + + while (c--) { + if (!(n = malloc(sizeof(*n)))) + abort(); + + n->prev = x->prev; + n->value = x->value; + x->prev = n; + } + } + + va_end(args); +} + void* libcdsb_stack_pop(stack_t* x) { stack_t* n;