From 8a0dd6f7f857e300254738539d9260f592a33f6c Mon Sep 17 00:00:00 2001 From: xavi Date: Tue, 23 Dec 2025 22:41:16 -0800 Subject: [PATCH] Added initial files and made an ncurses Hello World --- c_projects/tiktaktoe/Makefile | 97 +++++++++++++ c_projects/tiktaktoe/include/tiktaktoe.c | 5 + c_projects/tiktaktoe/include/tiktaktoe.h | 3 + c_projects/tiktaktoe/src/main.c | 6 + c_projects/tiktaktoe/src/tiktaktoe.c | 10 ++ c_projects/tiktaktoe/tests/include/test.h | 162 ++++++++++++++++++++++ c_projects/tiktaktoe/tests/test.c | 28 ++++ 7 files changed, 311 insertions(+) create mode 100644 c_projects/tiktaktoe/Makefile create mode 100644 c_projects/tiktaktoe/include/tiktaktoe.c create mode 100644 c_projects/tiktaktoe/include/tiktaktoe.h create mode 100644 c_projects/tiktaktoe/src/main.c create mode 100644 c_projects/tiktaktoe/src/tiktaktoe.c create mode 100644 c_projects/tiktaktoe/tests/include/test.h create mode 100644 c_projects/tiktaktoe/tests/test.c diff --git a/c_projects/tiktaktoe/Makefile b/c_projects/tiktaktoe/Makefile new file mode 100644 index 0000000..3fd87d8 --- /dev/null +++ b/c_projects/tiktaktoe/Makefile @@ -0,0 +1,97 @@ +# MakeFile for tiktaktoe +# Created 12/23/2025 +# Authored by: xavi +.POSIX: + +# DIRECTORIES +SRC_DIR := src +INCLUDE_DIR := include +OBJ_DIR := obj +TESTS_DIR := tests +TESTS_INCL_DIR := $(TESTS_DIR)/include +SUBMODULES_DIR := submodules + +# Final Binary Name +PROJECT_NAME := tiktaktoe +PROJECT_OBJ := $(OBJ_DIR)/$(PROJECT_NAME).o + +# SUBMODULE VARS FOR GENERATING STATIC LIBS +SUBMODULES := $(wildcard $(SUBMODULES_DIR)/*) +SUBBARE := $(SUBMODULES:$(SUBMODULES_DIR)/%=%) +SUBMODULE_SLIB := $(foreach m,$(SUBBARE),$(SUBMODULES_DIR)/$(m)/$(m).a) + + +STATIC_LIBS = $(shell find ./ -name "*.a") + +# C compiler settings +CC := gcc +INCLUDE_LIST := $(foreach m,$(SUBMODULES),$(m)/$(INCLUDE_DIR)) $(INCLUDE_DIR) $(TESTS_INCL_DIR) +INCLUDES := $(addprefix -I,$(INCLUDE_LIST)) +CFLAGS := -ggdb -Wall -Wextra -MMD -MP -lncurses -fsanitize=address +DFLAGS := + +# Main Executable Filename +MAIN := main.c + +# Files +SRC := $(filter-out $(SRC_DIR)/$(MAIN), $(wildcard $(SRC_DIR)/*.c)) +OBJ := $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o) +TESTS := $(wildcard $(TESTS_DIR)/*.c) + +# Get Dependencies from gcc using -MMD and -MP +DEPENDENCIES := $(OBJ:%.o=%.d) + +all: $(PROJECT_NAME) + +# CREATE STATIC LIBRARY OF MODULE +$(PROJECT_NAME).a: $(PROJECT_OBJ) check_submods + ar rcs $(@) $(<) + +# CREATE TEST EXECUTABLES +$(TESTS:$(TESTS_DIR)/%.c=%): %: $(OBJ_DIR)/%.o $(OBJ) check_submods + $(CC) $(CFLAGS) $(DFLAGS) -o $(@) $(<) $(OBJ) $(STATIC_LIBS) + +# CREATE TEST OBJS +$(OBJ_DIR)/%.o: $(TESTS_DIR)/%.c $(OBJ) + $(CC) $(CFLAGS) $(DFLAGS) $(INCLUDES) -c -o $(@) $(^) + +# CREATE MAIN OBJ +$(PROJECT_NAME): $(MAIN:%.c=$(OBJ_DIR)/%.o) $(OBJ) check_submods + $(CC) $(CFLAGS) $(DFLAGS) -o $(@) $(<) $(OBJ) $(STATIC_LIBS) + +# CREATE OBJS +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c + $(CC) $(CFLAGS) $(DFLAGS) $(INCLUDES) -c -o $(@) $(<) + +# RECURSE THROUGH SUBMODULES AND RUN MAKE *.a +$(SUBMODULE_SLIB): + $(MAKE) -C $(dir $(@)) $(notdir $(@)) + +check_submods: $(SUBMODULE_SLIB) + + +# RECURSE AND CLEAN ALL FILES +clean: + @for sm in $(SUBMODULES) ; do \ + $(MAKE) -C $$sm clean ; \ + done + rm -f $(PROJECT_NAME) $(OBJ_DIR)/* $(TESTS:$(TESTS_DIR)/%.c=%) ./*.a + +-include $(DEPENDENCIES) + +help: + @echo "SUBMODULES: $(SUBMODULES)" + @echo "SUBMODULE_SLIB: $(SUBMODULE_SLIB)" + @echo "STATIC_LIBS: $(STATIC_LIBS)" + +.PHONY: clean all check_submods help + +# Create Project Hierarchy + +dirs: $(SRC_DIR) $(OBJ_DIR) $(TESTS_DIR) $(INCLUDE_DIR) $(SUBMODULES_DIR) $(SRC_DIR)/$(MAIN) + +$(SRC_DIR) $(OBJ_DIR) $(TESTS_DIR) $(INCLUDE_DIR) $(SUBMODULES_DIR): + mkdir -p $(@) + +$(SRC_DIR)/$(MAIN): + touch $(SRC_DIR)/$(MAIN) diff --git a/c_projects/tiktaktoe/include/tiktaktoe.c b/c_projects/tiktaktoe/include/tiktaktoe.c new file mode 100644 index 0000000..bd508f3 --- /dev/null +++ b/c_projects/tiktaktoe/include/tiktaktoe.c @@ -0,0 +1,5 @@ +#include "tiktaktoe.h" + +int start_tiktaktoe(){ + return 0; +} diff --git a/c_projects/tiktaktoe/include/tiktaktoe.h b/c_projects/tiktaktoe/include/tiktaktoe.h new file mode 100644 index 0000000..d8ab180 --- /dev/null +++ b/c_projects/tiktaktoe/include/tiktaktoe.h @@ -0,0 +1,3 @@ +#include + +int start_tiktaktoe(); diff --git a/c_projects/tiktaktoe/src/main.c b/c_projects/tiktaktoe/src/main.c new file mode 100644 index 0000000..9ec66c6 --- /dev/null +++ b/c_projects/tiktaktoe/src/main.c @@ -0,0 +1,6 @@ +#include "tiktaktoe.h" + +int main(){ + start_tiktaktoe(); + return 0; +} diff --git a/c_projects/tiktaktoe/src/tiktaktoe.c b/c_projects/tiktaktoe/src/tiktaktoe.c new file mode 100644 index 0000000..0ef9bac --- /dev/null +++ b/c_projects/tiktaktoe/src/tiktaktoe.c @@ -0,0 +1,10 @@ +#include "tiktaktoe.h" + +int start_tiktaktoe(){ + initscr(); + printw("Hello World !!!"); + refresh(); + getch(); + endwin(); + return 0; +} diff --git a/c_projects/tiktaktoe/tests/include/test.h b/c_projects/tiktaktoe/tests/include/test.h new file mode 100644 index 0000000..45e4fe5 --- /dev/null +++ b/c_projects/tiktaktoe/tests/include/test.h @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include + +// printf Formating +#define X_RED "\x1B[31m" +#define X_GREEN "\x1B[32m" +#define X_YELLOW "\x1B[33m" +#define X_RST "\x1B[0m" + + +// TEST FRAMEWORK STRUCT +typedef struct testnode{ + char* name; + int (*op)(void); + struct testnode* next; +}testnode; + +// LL nodes +static testnode* head = NULL; +static testnode* tail = NULL; +static testnode* ptr = NULL; + +// TEST FRAMEWORK MACRO +// create a new node and pass in the name of the test. Then make a new function +// that adds the test to the LL. __attribute__((constructor)) has the function +// run before main +#define TEST(UNIT)\ + static int UNIT(void);\ + static testnode UNIT##node = {#UNIT, UNIT, NULL};\ + __attribute__((constructor)) \ + static void add##UNIT(void){ \ + if (head == NULL){\ + head = &UNIT##node;\ + tail = head;\ + return; \ + }\ + ptr = tail;\ + tail = &UNIT##node;\ + ptr->next = tail;\ + }\ + static int UNIT(void) + +// TEST HELPER FUNCTIONS and STRUCTS +typedef enum {START, END} header_opt; +static void ptest_headers(header_opt option){ + switch (option){ + case START: + printf("\n-------------------\n"); + printf(" Starting Tests\n"); + printf("-------------------\n"); + break; + case END: + printf("-------------------\n"); + printf(" ENDING TESTS\n"); + printf("-------------------\n\n"); + break; + default: + printf("error: Wrong option in ptest_headers()\n"); + exit(-1); + } +} + +typedef enum {PASS, FAIL}rc_opt; +static void ppass_fail(rc_opt rc){ + switch (rc){ + case PASS: + printf("%s[PASS]%s ", X_GREEN, X_RST); + printf("%s", ptr->name); + break; + case FAIL: + printf("%s[FAIL]%s ", X_RED, X_RST); + printf("%s ", ptr->name); + break; + default: + printf("error: Unknown return code"); + exit(-1); + } + +} + +static int presult(int status){ + if (WIFEXITED(status)){ + int rc = WEXITSTATUS(status); + if (rc == 0) { + ppass_fail(PASS); + return 0; + } + else{ + ppass_fail(FAIL); + printf("- Exit Code %s(%d)%s", + X_YELLOW, rc, X_RST); + return 1; + } + } + else if (WIFSIGNALED(status)){ + ppass_fail(FAIL); + printf("- Termination Signal %s(%d)%s", + X_YELLOW, WTERMSIG(status), X_RST); + return 1; + } + else{ + printf("%s[FAIL]%s ", X_RED, X_RST); + printf("%s ", ptr->name); + printf("- Unknown Error "); + return 1; + } +} + +static int run_child(){ + int status; + pid_t cpid = fork(); + if (cpid < 0){ + perror("fork"); + exit(EXIT_FAILURE); + } + + if (cpid == 0){ + int rc = ptr->op(); + _exit(rc); + }else{ + if (waitpid(cpid, &status, 0) < 0){ + perror("waitpid"); + exit(EXIT_FAILURE); + } + } + + return status; +} + +static int run_tests(){ + int total_tests = 0; + int errors = 0; + + ptest_headers(START); + + ptr = head; + while (ptr != NULL){ + total_tests++; + + + if(presult(run_child())){ + errors++; + } + + printf("\n"); + ptr = ptr->next; + } + + + printf("\nTests completed with %s%d PASS%s", X_GREEN, total_tests - errors, X_RST); + printf(" and %s%d FAIL%s\n", X_RED, errors, X_RST); + + ptest_headers(END); + + if (errors > 0){ + return 1; + } + return 0; +} diff --git a/c_projects/tiktaktoe/tests/test.c b/c_projects/tiktaktoe/tests/test.c new file mode 100644 index 0000000..7e73b8c --- /dev/null +++ b/c_projects/tiktaktoe/tests/test.c @@ -0,0 +1,28 @@ +#include "test.h" + +// INCLUDE PROJECT HEADERS + + +// DEFINE TESTS +TEST(success){ + return 0; +} + +TEST(fail){ + int i = 1; + assert(i == 0); + printf("after assert\n"); + return i; +} + +TEST(segfault){ + int* x = NULL; + int y = *x; + return y; +} + +// END OF TEST DEFINITIONS + +int main(void){ + return run_tests(); +}