Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Inital commit
- Loading branch information
Showing
7 changed files
with
321 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
CC=gcc | ||
CFLAGS=-g -std=c99 | ||
SUT_DIR=simple_unit_test | ||
OFILES=queue.o queue_test.o $(addprefix $(SUT_DIR)/, simple_unit_test.o) | ||
|
||
all: queue_test | ||
|
||
queue_test: $(OFILES) | ||
$(CC) -o $@ $(OFILES) | ||
|
||
queue.o: queue.c | ||
$(CC) $(CFLAGS) -c $< | ||
|
||
queue_test.o: queue_test.c | ||
$(CC) $(CFLAGS) -c $< | ||
|
||
simple_unit_test.o: $(SUT_DIR)/simple_unit_test.c | ||
$(CC) $(CFLAGS) -c $< | ||
|
||
clean: | ||
@echo "Cleaning..." | ||
rm -f *.o $(SUT_DIR)/*.o queue_test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,48 @@ | ||
# queue | ||
A queue for you | ||
# A queue for you! | ||
|
||
This is dead a simple queue implementation that only supports integers and | ||
has the following interface: | ||
```c | ||
/* Create a brand new queue out of thin air. */ | ||
Queue* create_queue(); | ||
|
||
/* Take a peek at what's at the front of the queue. */ | ||
int front(Queue* queue); | ||
|
||
/* Take a peek at what's at the back of the queue. */ | ||
int back(Queue* queue); | ||
|
||
/* Enqueue an integer to the front of the queue. */ | ||
void enqueue(Queue* queue, int data); | ||
|
||
/* Dequeue an integer from the queue. */ | ||
int dequeue(Queue* queue); | ||
|
||
/* Send the queue into non-existance. */ | ||
void destroy_queue(Queue* queue); | ||
|
||
/* Print out all of the elements of the queue. */ | ||
void print_queue(Queue* queue); | ||
|
||
/* Determine how many elements are in the queue. */ | ||
size_t size(Queue* queue); | ||
|
||
/* Determine if the queue is empty like my soul. */ | ||
int is_empty(Queue* queue); | ||
``` | ||
## How to use | ||
To use this wonderful queue, just include `"queue.h"` and you're good to go! | ||
## Testing | ||
If you'd like to verify this queue implementation actually works, you can run | ||
the unit tests! All the unit tests are located in `queue_test.c` and make use | ||
of my amazing `simple_unit_test` testing framework. | ||
To run the unit tests: | ||
```c | ||
$ make | ||
$ ./queue_test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
#include <assert.h> | ||
#include <stdlib.h> | ||
#include "queue.h" | ||
|
||
Queue* create_queue() { | ||
Queue* queue = malloc(sizeof(Queue)); | ||
queue->size = 0; | ||
queue->head = NULL; | ||
queue->tail = NULL; | ||
return queue; | ||
} | ||
|
||
int front(Queue* queue) { | ||
assert(!is_empty(queue)); | ||
return queue->head->data; | ||
} | ||
|
||
int back(Queue* queue) { | ||
assert(!is_empty(queue)); | ||
return queue->tail->data; | ||
} | ||
|
||
void enqueue(Queue* queue, int data) { | ||
QueueNode* node = malloc(sizeof(QueueNode)); | ||
node->data = data; | ||
node->next = queue->head; | ||
if (is_empty(queue)) { | ||
queue->head = queue->tail = node; | ||
} else { | ||
queue->tail->next = node; | ||
queue->tail = node; | ||
} | ||
queue->size++; | ||
} | ||
|
||
int dequeue(Queue* queue) { | ||
assert(!is_empty(queue)); | ||
int data = front(queue); | ||
QueueNode* dequeued_node = queue->head; | ||
queue->head = queue->head->next; | ||
free(dequeued_node); | ||
queue->size--; | ||
return data; | ||
} | ||
|
||
void destroy_queue(Queue* queue) { | ||
return; | ||
} | ||
|
||
void print_queue(Queue* queue) { | ||
return; | ||
} | ||
|
||
size_t size(Queue* queue) { | ||
return queue->size; | ||
} | ||
|
||
int is_empty(Queue* queue) { | ||
return queue->size == 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef __QUEUE_H | ||
#define __QUEUE_H | ||
|
||
#include <stdlib.h> | ||
|
||
typedef struct QueueNode { | ||
int data; | ||
struct QueueNode* next; | ||
} QueueNode; | ||
|
||
typedef struct Queue { | ||
size_t size; | ||
QueueNode* head; | ||
QueueNode* tail; | ||
} Queue; | ||
|
||
/* Create a brand new queue out of thin air. */ | ||
Queue* create_queue(); | ||
|
||
/* Take a peek at what's at the front of the queue. */ | ||
int front(Queue* queue); | ||
|
||
/* Take a peek at what's at the back of the queue. */ | ||
int back(Queue* queue); | ||
|
||
/* Enqueue an integer to the front of the queue. */ | ||
void enqueue(Queue* queue, int data); | ||
|
||
/* Dequeue an integer from the queue. */ | ||
int dequeue(Queue* queue); | ||
|
||
/* Send the queue into non-existance. */ | ||
void destroy_queue(Queue* queue); | ||
|
||
/* Print out all of the elements of the queue. */ | ||
void print_queue(Queue* queue); | ||
|
||
/* Determine how many elements are in the queue. */ | ||
size_t size(Queue* queue); | ||
|
||
/* Determine if the queue is empty like my soul. */ | ||
int is_empty(Queue* queue); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#include "./simple_unit_test/simple_unit_test.h" | ||
#include "queue.h" | ||
|
||
|
||
int test_create_queue() { | ||
Queue* queue = create_queue(); | ||
CHECK(assert_not_null(queue)); | ||
CHECK(assert_equal_int(size(queue), 0)); | ||
CHECK(assert_true(is_empty(queue))); | ||
destroy_queue(queue); | ||
return 0; | ||
} | ||
|
||
int test_enqueue() { | ||
Queue* queue = create_queue(); | ||
|
||
enqueue(queue, 1); | ||
CHECK(assert_equal_int(size(queue), 1)); | ||
CHECK(assert_false(is_empty(queue))); | ||
CHECK(assert_equal_int(front(queue), 1)); | ||
CHECK(assert_equal_int(back(queue), 1)); | ||
|
||
enqueue(queue, 2); | ||
CHECK(assert_equal_int(size(queue), 2)); | ||
CHECK(assert_equal_int(front(queue), 1)); | ||
CHECK(assert_equal_int(back(queue), 2)); | ||
return 0; | ||
} | ||
|
||
int test_dequeue() { | ||
Queue* queue = create_queue(); | ||
|
||
enqueue(queue, 1); | ||
dequeue(queue); | ||
CHECK(assert_true(is_empty(queue))); | ||
|
||
for (int i = 1; i <= 10; i++) { | ||
enqueue(queue, i); | ||
} | ||
|
||
dequeue(queue); | ||
dequeue(queue); | ||
CHECK(assert_equal_int(size(queue), 8)); | ||
CHECK(assert_equal_int(front(queue), 3)); | ||
CHECK(assert_equal_int(back(queue), 10)); | ||
return 0; | ||
} | ||
|
||
int main() { | ||
run_test("test_create_queue", test_create_queue); | ||
run_test("test_enqueue", test_enqueue); | ||
run_test("test_dequeue", test_dequeue); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include "simple_unit_test.h" | ||
|
||
|
||
void run_test(const char* test_name, TestProcedure procedure) { | ||
printf("%s======== Running test: %s =========%s\n", KCYN, test_name, KWHT); | ||
int test_result = procedure(); | ||
if (test_result > 0) { | ||
fprintf(stderr, "TEST %sFAILED%s: Exiting\n", KRED, KWHT); | ||
} else { | ||
printf("TEST %sPASSED%s\n", KGRN, KWHT); | ||
} | ||
} | ||
|
||
int assert_equal_int(int actual, int expected) { | ||
if (actual != expected) { | ||
printf("Assertion error: expected %d, but got %d\n", expected, actual); | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
int assert_true(int val) { | ||
if (!val) { | ||
printf("Assertion error: %d is not true\n", val); | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
int assert_false(int val) { | ||
if (val) { | ||
printf("Assertion error: %d is not false\n", val); | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
int assert_null(void* ptr) { | ||
if (ptr != NULL) { | ||
printf("Assertion error: %p is not NULL\n", ptr); | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
int assert_not_null(void* ptr) { | ||
if (ptr == NULL) { | ||
printf("Assertion error: %p value is not non-NULL\n", ptr); | ||
return 1; | ||
} | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef __SIMPLE_UNIT_TEST_H | ||
#define __SIMPLE_UNIT_TEST_H | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
|
||
#define CHECK(val) if (val) { printf("Line number %d\n", __LINE__); return 1; } | ||
#define KNRM "\x1B[0m" | ||
#define KRED "\x1B[31m" | ||
#define KGRN "\x1B[32m" | ||
#define KYEL "\x1B[33m" | ||
#define KBLU "\x1B[34m" | ||
#define KMAG "\x1B[35m" | ||
#define KCYN "\x1B[36m" | ||
#define KWHT "\x1B[37m" | ||
|
||
|
||
typedef int (*TestProcedure)(void); | ||
|
||
/* Run a test with the given name and procedure. */ | ||
void run_test(const char* test_name, TestProcedure procedure); | ||
|
||
/* Assert that two integers are equal. */ | ||
int assert_equal_int(int actual, int expected); | ||
|
||
/* Assert that a value is true. */ | ||
int assert_true(int val); | ||
|
||
/* Assert that a value is false. */ | ||
int assert_false(int val); | ||
|
||
/* Assert that a pointer is null. */ | ||
int assert_null(void* ptr); | ||
|
||
/* Assert that a pointer is not null. */ | ||
int assert_not_null(void* ptr); | ||
|
||
#endif |