diff --git a/include/bits/memory.h b/include/bits/memory.h index 5cc4635..5cb7d1b 100644 --- a/include/bits/memory.h +++ b/include/bits/memory.h @@ -12,6 +12,11 @@ typedef struct libcdsb_stack_node { void* value; } stack_t; +typedef struct libcdsb_queue { + struct libcdsb_stack_node* back; + struct libcdsb_stack_node* front; +} queue_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_push_many(stack_t* stack, size_t n, ...) Nonnull__(1); @@ -19,6 +24,12 @@ extern void* libcdsb_stack_pop (stack_t* stack) Nonnull__(1) extern void libcdsb_stack_reverse (stack_t* stack) Nonnull__(1); extern void libcdsb_stack_flush (stack_t* stack) Nonnull__(1); +extern void libcdsb_queue_init (queue_t* queue) Nonnull__(1); +extern void libcdsb_queue_push (queue_t* queue, void* value) Nonnull__(1); +extern void libcdsb_queue_push_many(queue_t* queue, size_t n, ...) Nonnull__(1); +extern void* libcdsb_queue_pop (queue_t* queue) Nonnull__(1); +extern void libcdsb_queue_flush (queue_t* queue) 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__; extern void* libcdsb_calloc (size_t n, size_t c) Warn_unused_result__; diff --git a/src/queue.c b/src/queue.c new file mode 100644 index 0000000..65f89d7 --- /dev/null +++ b/src/queue.c @@ -0,0 +1,95 @@ +/* This software is licensed by the MIT License, see LICENSE file */ +/* Copyright © 2022 Gregory Lirent */ + +#include +#include +#include "__internal/include.h" +#undef malloc +#undef free + +void libcdsb_queue_init(queue_t* x) { + memset(x, 0, sizeof(*x)); +} + + +void libcdsb_queue_push(queue_t* x, void* value) { + stack_t* n; + + if (!(n = malloc(sizeof(*n)))) + abort(); + + n->prev = 0; + + if (!x->back) { + x->front = n; + x->back = n; + } else x->back->prev = n; + + n->value = value; +} + + +void libcdsb_queue_push_many(queue_t* x, size_t c, ...) { + va_list args; + stack_t* n; + va_start(args, c); + + if (c) { + + if (!x->back) { + if (!(n = malloc(sizeof(*n)))) + abort(); + + x->front = n; + x->back = n; + n->prev = 0; + n->value = va_arg(args, void*); + --c; + } + + while (c--) { + if (!(n = malloc(sizeof(*n)))) + abort(); + + x->back->prev = n; + n->prev = 0; + n->value = va_arg(args, void*); + } + } + + va_end(args); +} + + +void* libcdsb_queue_pop(queue_t* x) { + stack_t* n; + void* v; + + if (x->front) { + n = x->front; + v = n->value; + + if (!(x->front = n->prev)) { + x->back = 0; + } + + free(n); + } else v = 0; + + return v; +} + + +void libcdsb_queue_flush(queue_t* x) { + stack_t* c; + + c = x->front; + + while (x->front) { + c = x->front; + x->front = c->prev; + free(c); + } + + x->back = 0; +} diff --git a/src/stack.c b/src/stack.c index bdaca67..b084cbf 100644 --- a/src/stack.c +++ b/src/stack.c @@ -47,6 +47,7 @@ void libcdsb_stack_push_many(stack_t* x, size_t c, ...) { n->prev = x->prev; n->value = x->value; x->prev = n; + x->value = va_arg(args, void*); } }