From 94f861b114ffc61a9a03120b5b27511ef2c19f9e Mon Sep 17 00:00:00 2001 From: Penguin Date: Tue, 12 Apr 2022 16:57:58 -0500 Subject: [PATCH] added a queue --- Queue/build/Makefile | 51 ++++++++++++++++++ Queue/inc/p_queue.h | 20 +++++++ Queue/queue.c | 47 ++++++++++++++++ Queue/queue.h | 125 +++++++++++++++++++++++++++++++++++++++++++ Queue/src/p_queue.c | 1 + 5 files changed, 244 insertions(+) create mode 100644 Queue/build/Makefile create mode 100644 Queue/inc/p_queue.h create mode 100644 Queue/queue.c create mode 100644 Queue/queue.h create mode 100644 Queue/src/p_queue.c diff --git a/Queue/build/Makefile b/Queue/build/Makefile new file mode 100644 index 0000000..8c95b83 --- /dev/null +++ b/Queue/build/Makefile @@ -0,0 +1,51 @@ +PRJNAME=pqueue +PRJOUT=lib$(PRJNAME).a + +TESTSOUT=$(PRJNAME)_tests +EXAMPLESOUT=$(PRJNAME)_example +CC=gcc +SIZE=size +MK_DIR=mkdir -p + +CFLAGS=\ +-Wall \ +-DDEBUG \ +-std=gnu11 \ +-ffunctions-sections \ +-O3 \ +-g3 + + +ARFLAGS=\ + +# Core Stuff +CORE_SUB_DIRS=src +CORE_INC_DIRS=\ +-I../cfg \ +-I../inc + +# Tests +TESTS_SUB_DIRS=\ +test/src + +TESTS_INC_DIRS=\ +-I../tests/inc \ +-I../test/cfg + +# Examples +EXAMPLES_SUB_DIRS=\ +EXAMPLES_INC_DIRS=\ + +.PHONY: all tests examples clean + +all: $(CORE_SUB_DIRS) $(PRJOUT) +tests: all $(TESTS_SUB_DIRS) $(TESTSOUT) +examples: all $(EXAMPLES_SUB_DIRS) $(EXAMPLESOUT) + +$(PRJOUT): $(CORE_OBJS) + $(AR) $(CORE_INC_DIRS) $(CFLAGS) $(ARFLAGS) $@ $< + +$(TESTSOUT): $(TEST_OBJS) + $(CC) $(CFLAGS) -o $< $(TEST_OBJS) + +$(EXAMPLESOUT) diff --git a/Queue/inc/p_queue.h b/Queue/inc/p_queue.h new file mode 100644 index 0000000..10eb031 --- /dev/null +++ b/Queue/inc/p_queue.h @@ -0,0 +1,20 @@ +#ifndef __P_QUEUE_H__ +#define __P_QUEUE_H__ + +#include + +typedef enum PB_Q_STATUS { + PB_Q_GOOD = 0, + PB_Q_BAD = 1, // generic bad + PB_Q_BAD_LENGTH = 2, + PB_Q_NULL_BUFFER = 3, + PB_Q_NULL_QUEUE = 4 +} PB_Q_STATUS; + +typedef struct p_queue { + uint8_t *elements; + ssize_t len; + +} p_queue; + +#endif diff --git a/Queue/queue.c b/Queue/queue.c new file mode 100644 index 0000000..d7c4791 --- /dev/null +++ b/Queue/queue.c @@ -0,0 +1,47 @@ +#include "queue.h" + +QUEUE(int, 4); + +queue_int_t queue; + +void display(queue_int_t* queue) +{ + if (queue->csize == 0) + { + printf("queue is empty\n"); + } + else + { + printf("Queue:\n"); + int i = queue->head; + for (int j = 0; j < queue->csize; j++) + { + printf("[%d]: %d ", i + j, queue->data[(i + j) % queue->msize]); + } + printf("\n"); + } +} + +int main(int argv, char** argc) +{ + queue_int_init(&queue); + + // queue.enqueue(&queue, 10); + queue.empty(&queue); + printf("csize: %d\n", queue.csize); + queue.enqueue(&queue, 20); + queue.enqueue(&queue, 30); + queue.enqueue(&queue, 40); + display(&queue); + queue.enqueue(&queue, 10); + + int val = 0; + queue.dequeue(&queue, &val); + queue.dequeue(&queue, &val); + + display(&queue); + + queue.empty(&queue); + + display(&queue); +} diff --git a/Queue/queue.h b/Queue/queue.h new file mode 100644 index 0000000..4976972 --- /dev/null +++ b/Queue/queue.h @@ -0,0 +1,125 @@ +#ifndef __QUEUE_H__ +#define __QUEUE_H__ + +#include +#include +#include + +#define MAX_QUEUE_SIZE (512) + +typedef enum PB_STATUS +{ + PB_GOOD = 0, + PB_BAD = 1, + PB_BAD_BUFFER_SIZE = 2, + PB_NULL_BUFFER = 3, + PB_NULL_DATA = 4, + PB_EMPTY_QUEUE = 5, + PB_FULL_QUEUE = 6 +} PB_STATUS; + +// This macro defines a queue type. It doesn't make a queue for you. +// See below for an example on how to make a queue. +// Creates a type of queue_${type}_t of size ${size}. +// the size will be fixed for all instances of that type unfortunately. +#define QUEUE(type, size) \ + typedef struct queue_##type##_t \ + { \ + int data[size]; \ + int head; \ + int tail; \ + int msize; \ + int csize; \ + \ + PB_STATUS (*enqueue)(struct queue_##type##_t * queue, type val); \ + PB_STATUS (*dequeue)(struct queue_##type##_t * queue, type* val); \ + void (*empty)(struct queue_##type##_t * queue); \ + bool (*is_full)(struct queue_##type##_t * queue); \ + \ + } queue_##type##_t; \ + \ + bool queue_##type##_is_full(queue_##type##_t* queue) \ + { \ + return (queue->csize == queue->msize); \ + } \ + \ + void queue_##type##_empty(queue_##type##_t* queue) \ + { \ + memset(queue->data, 0, sizeof(type) * queue->msize); \ + queue->head = -1; \ + queue->tail = -1; \ + queue->csize = 0; \ + } \ + \ + PB_STATUS queue_##type##_enqueue(queue_##type##_t* queue, type val) \ + { \ + PB_STATUS ret = PB_GOOD; \ + if (queue->is_full(queue)) \ + { \ + ret = PB_FULL_QUEUE; \ + } \ + else \ + { \ + if (queue->head == -1) \ + { \ + queue->head = 0; \ + queue->csize = 0; \ + queue->tail = queue->msize - 1; \ + } \ + queue->tail = (queue->tail + 1) % queue->msize; \ + queue->data[queue->tail] = val; \ + queue->csize++; \ + } \ + return ret; \ + } \ + \ + PB_STATUS queue_##type##_dequeue(queue_##type##_t* queue, type* val) \ + { \ + PB_STATUS ret = PB_GOOD; \ + if (queue->csize == 0) \ + { \ + ret = PB_EMPTY_QUEUE; \ + } \ + else \ + { \ + *val = queue->data[queue->head]; \ + queue->head = (queue->head + 1) % queue->csize; \ + queue->csize -= 1; \ + } \ + return ret; \ + } \ + PB_STATUS queue_##type##_init(queue_##type##_t* queue) \ + { \ + PB_STATUS ret = PB_GOOD; \ + do \ + { \ + if (!queue) \ + { \ + ret = PB_NULL_BUFFER; \ + break; \ + } \ + \ + if (size > MAX_QUEUE_SIZE || size <= 0) \ + { \ + ret = PB_BAD_BUFFER_SIZE; \ + break; \ + } \ + } while (0); \ + queue->msize = size; \ + queue->head = -1; \ + queue->tail = -1; \ + queue->csize = 0; \ + queue->enqueue = queue_##type##_enqueue; \ + queue->dequeue = queue_##type##_dequeue; \ + queue->empty = queue_##type##_empty; \ + queue->is_full = queue_##type##_is_full; \ + return ret; \ + } + +// Example: +// QUEUE(int, 4); +// queue_int_t queue; +// // in .c +// queue_int_init(&queue); + +#endif diff --git a/Queue/src/p_queue.c b/Queue/src/p_queue.c new file mode 100644 index 0000000..ecf299a --- /dev/null +++ b/Queue/src/p_queue.c @@ -0,0 +1 @@ +#include "p_queue.h"