diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f8aeee --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +doble_initial.exe +highscores.txt +runStackTest.exe +stack.o diff --git a/makefile b/makefile index 1f15f75..5893c0b 100644 --- a/makefile +++ b/makefile @@ -1,49 +1,49 @@ -CC = gcc -FLAGS = -g -Wall -lm - -ifeq ($(OS),Windows_NT) - include makefile_windows.variables -else - UNAME = $(shell uname) - ifeq ($(UNAME),Linux) - include makefile_linux.variables - else - include makefile_mac.variables - endif -endif - -raylibfolder = ./raylib -unityfolder = ./unity - -# -------------------------- -# Initiales Programm bauen (zum ausprobieren) -# -------------------------- -doble_initial: - $(CC) -o doble_initial $(BINARIES)/libdoble_complete.a - -# -------------------------- -# Selbst implementiertes Programm bauen -# -------------------------- -program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o - -doble : main.o $(program_obj_files) - $(CC) $(FLAGS) $^ -o doble - -$(program_obj_filesobj_files): %.o: %.c - $(CC) -c $(FLAGS) $^ -o $@ - -# -------------------------- -# Unit Tests -# -------------------------- -unitTests: - echo "needs to be implemented" - -# -------------------------- -# Clean -# -------------------------- -clean: -ifeq ($(OS),Windows_NT) - del /f *.o doble -else - rm -f *.o doble +CC = gcc +FLAGS = -g -Wall -lm + +ifeq ($(OS),Windows_NT) + include makefile_windows.variables +else + UNAME = $(shell uname) + ifeq ($(UNAME),Linux) + include makefile_linux.variables + else + include makefile_mac.variables + endif +endif + +raylibfolder = ./raylib +unityfolder = ./unity + +# -------------------------- +# Initiales Programm bauen (zum ausprobieren) +# -------------------------- +doble_initial: + $(CC) -o doble_initial $(BINARIES)/libdoble_complete.a + +# -------------------------- +# Selbst implementiertes Programm bauen +# -------------------------- +program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o + +doble : main.o $(program_obj_files) + $(CC) $(FLAGS) $^ -o doble + +$(program_obj_filesobj_files): %.o: %.c + $(CC) -c $(FLAGS) $^ -o $@ + +# -------------------------- +# Unit Tests +# -------------------------- +unitTests: stack.o test_stack.c $(unityfolder)/unity.c + $(CC) $(FLAGS) -I$(unityfolder) -o runStackTest test_stack.c stack.o $(unityfolder)/unity.c + +# -------------------------- +# Clean +# -------------------------- +clean: +ifeq ($(OS),Windows_NT) + del /f *.o doble +else + rm -f *.o doble endif \ No newline at end of file diff --git a/stack.c b/stack.c index e3a90d4..5bfb882 100644 --- a/stack.c +++ b/stack.c @@ -1,33 +1,91 @@ -#include -#include "stack.h" - -//TODO: grundlegende Stackfunktionen implementieren: -/* * `push`: legt ein Element oben auf den Stack, - * `pop`: entfernt das oberste Element, - * `top`: liefert das oberste Element zurück, - * `clearStack`: gibt den gesamten Speicher frei. */ - -// Pushes data as pointer onto the stack. -StackNode *push(StackNode *stack, void *data) -{ - -} - -// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be -// freed by caller.) -StackNode *pop(StackNode *stack) -{ - -} - -// Returns the data of the top element. -void *top(StackNode *stack) -{ - -} - -// Clears stack and releases all memory. -void clearStack(StackNode *stack) -{ - +#include +#include "stack.h" + +// TODO: grundlegende Stackfunktionen implementieren: +/* * `push`: legt ein Element oben auf den Stack, + * `pop`: entfernt das oberste Element, + * `top`: liefert das oberste Element zurück, + * `clearStack`: gibt den gesamten Speicher frei. */ + +// Pushes data as pointer onto the stack. +StackNode *push(StackNode *stack, void *data) +{ + StackNode *tempNode, *newNode; + + newNode = malloc(sizeof(StackNode)); + newNode->value = 3; + newNode->next = NULL; + + if (stack == NULL) + { + stack = newNode; + return stack; + } + + tempNode = stack; + while (tempNode->next != NULL) + { + tempNode = tempNode->next; + } + tempNode->next = newNode; + + return stack; +} + +// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be +// freed by caller.) +StackNode *pop(StackNode *stack) +{ + StackNode *tempNode; + + if (stack == NULL) + { + return stack; + } + + tempNode = stack; + while (tempNode->next->next != NULL) + { + tempNode = tempNode->next; + } + free(tempNode->next); + tempNode->next = NULL; + + return stack; +} + +// Returns the data of the top element. +void *top(StackNode *stack) +{ + StackNode *tempNode; + + if (stack == NULL) + { + return NULL; + } + + tempNode = stack; + while (tempNode->next != NULL) + { + tempNode = tempNode->next; + } + + return &tempNode->value; +} + +// Clears stack and releases all memory. +void clearStack(StackNode *stack) +{ + StackNode *tempNode; + + if (stack == NULL) + { + return; + } + + tempNode = stack; + while (tempNode != NULL) + { + tempNode = pop(tempNode); + } } \ No newline at end of file diff --git a/stack.h b/stack.h index f7d542d..d7cc86a 100644 --- a/stack.h +++ b/stack.h @@ -1,25 +1,29 @@ -#ifndef STACK_H -#define STACK_H - -/* A stack is a special type of queue which uses the LIFO (last in, first out) principle. -This means that with each new element all other elements are pushed deeper into the stack. -The latest element is taken from the stack. */ - -#include - -//TODO: passenden Datentyp als struct anlegen - -// Pushes data as pointer onto the stack. -StackNode *push(StackNode *stack, void *data); - -// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be -// freed by caller.) -StackNode *pop(StackNode *stack); - -// Returns the data of the top element. -void *top(StackNode *stack); - -// Clears stack and releases all memory. -void clearStack(StackNode *stack); - -#endif +#ifndef STACK_H +#define STACK_H + +/* A stack is a special type of queue which uses the LIFO (last in, first out) principle. +This means that with each new element all other elements are pushed deeper into the stack. +The latest element is taken from the stack. */ + +#include + +//TODO: passenden Datentyp als struct anlegen +typedef struct Node { + int value; + struct Node* next; +} StackNode; + +// Pushes data as pointer onto the stack. +StackNode *push(StackNode *stack, void *data); + +// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be +// freed by caller.) +StackNode *pop(StackNode *stack); + +// Returns the data of the top element. +void *top(StackNode *stack); + +// Clears stack and releases all memory. +void clearStack(StackNode *stack); + +#endif diff --git a/test_stack.c b/test_stack.c new file mode 100644 index 0000000..2acb342 --- /dev/null +++ b/test_stack.c @@ -0,0 +1,89 @@ +#include +#include +#include "stack.h" +#include "unity.h" + +StackNode* setup(int value, StackNode* next) { + StackNode* node = malloc(sizeof(StackNode)); // allocate memory on heap + if (node == NULL) { + perror("malloc failed"); + exit(EXIT_FAILURE); // or handle the error differently + } + node->value = value; + node->next = next; + return node; +} + +void test_pop(void) +{ + StackNode* node2 = setup(3, NULL); + StackNode* node1 = setup(2, node2); + StackNode* header = setup(1, node1); + StackNode* temp; + + temp = pop(header); + int after = 0; + while(temp) + { + after++; + temp = temp->next; + } + + + TEST_ASSERT_EQUAL_INT(2, after); + TEST_ASSERT_NULL(node1->next); +} + +void test_top(void) +{ + StackNode* node2 = setup(3, NULL); + StackNode* node1 = setup(2, node2); + StackNode* header = setup(1, node1); + + int data = *(int *)top(header); + TEST_ASSERT_EQUAL_INT(node2->value, data); +} + +void test_clear() +{ + StackNode* node2 = setup(3, NULL); + StackNode* node1 = setup(2, node2); + StackNode* header = setup(1, node1); + StackNode* temp; + + clearStack(header); + temp = header; + + int after = 0; + while(temp) + { + after++; + temp = temp->next; + } + + + TEST_ASSERT_NULL(after); +} + +void setUp(void) +{ + // Falls notwendig, kann hier Vorbereitungsarbeit gemacht werden +} + +void tearDown(void) +{ + // Hier kann Bereinigungsarbeit nach jedem Test durchgeführt werden +} + +int main() +{ + UNITY_BEGIN(); + + printf("============================\nStack tests\n============================\n"); + + RUN_TEST(test_pop); + RUN_TEST(test_top); + RUN_TEST(test_clear); + + return UNITY_END(); +} \ No newline at end of file diff --git a/unittest.h b/unittest.h new file mode 100644 index 0000000..ff5faa9 --- /dev/null +++ b/unittest.h @@ -0,0 +1,10 @@ +#ifndef UNITTTESTS_H +#define UNITTTESTS_H + +#include + +typedef int (*UnitTestType)(void); + +#define RUN_UNIT_TEST(fct) printf("%80s: %d\n", #fct, fct()) + +#endif