From 93dc0fa053c0055469a1ee65ac0ba7a6babcd533 Mon Sep 17 00:00:00 2001 From: herbglitch Date: Tue, 27 Aug 2024 03:23:29 -0600 Subject: [PATCH] updated vector to video version, will probably break a lot --- include/arc/std/errno.h | 26 ++++--- include/arc/std/lexer.h | 31 ++++++++ include/arc/std/parser.h | 0 include/arc/std/vector.h | 93 ++++++++++++++---------- src/std/errno.c | 15 +++- src/std/lexer.c | 0 src/std/parser.c | 0 src/std/vector.c | 126 +++++++++++++++++++------------- temp.txt | 48 ++++++++++++ tests/src/vector.c | 153 +++++++++++++++++++++++++++++++++++++++ tests/test.c | 22 ++++++ tests/test.h | 44 +++++++++++ 12 files changed, 461 insertions(+), 97 deletions(-) create mode 100644 include/arc/std/lexer.h create mode 100644 include/arc/std/parser.h create mode 100644 src/std/lexer.c create mode 100644 src/std/parser.c create mode 100644 temp.txt create mode 100644 tests/src/vector.c create mode 100644 tests/test.c create mode 100644 tests/test.h diff --git a/include/arc/std/errno.h b/include/arc/std/errno.h index 15096a2..79fb015 100644 --- a/include/arc/std/errno.h +++ b/include/arc/std/errno.h @@ -17,19 +17,27 @@ extern "C" { extern int32_t arc_errno; +#ifdef ARC_DEBUG + #include + //this is handy to override for if they user is doing terminal output and wants to change where logs are sent + extern FILE *arc_errno_log_file; + + #ifndef ARC_DEBUG_LOG_STREAM_OVERRIDE + //this functin will be called on start, handy to set the log file to stdout if it is not overrided + void __attribute__ ((constructor)) ARC_Errno_SetDefaultStream(void); + #endif // !ARC_DEBUG_LOG_STREAM_OVERRIDE +#endif // !ARC_DEBUG + #ifdef __cplusplus } #endif #ifdef ARC_DEBUG -# include -# define ARC_DEBUG_LOG(ERR, STR, ...) printf("[ERROR %d] " STR "\n", ERR, __VA_ARGS__) -# define ARC_DEBUG_ERR(STR) printf("[ERROR %d] " STR "\n", arc_errno) + #define ARC_DEBUG_LOG_ERROR(STR) fprintf(arc_errno_log_file, "[ERROR %d] " STR "\n", arc_errno) + #define ARC_DEBUG_LOG_ERROR_WITH_VARIABLES(STR, ...) fprintf(arc_errno_log_file, "[ERROR %d] " STR "\n", arc_errno, __VA_ARGS__) #else -# define ARC_DEBUG_LOG(ERR, STR, ...) -# define ARC_DEBUG_ERR(STR) -#endif + #define ARC_DEBUG_LOG_ERROR(STR) + #define ARC_DEBUG_LOG_ERROR_WITH_VARIABLES(STR, ...) +#endif // !ARC_DEBUG -#define ARC_ERR_CHECK(FUNC) FUNC; if(arc_errno){ ARC_DEBUG_LOG(arc_errno, "%s", #FUNC); return; } - -#endif //ARC_STD_ERRNO_H_ \ No newline at end of file +#endif // !ARC_STD_ERRNO_H_ diff --git a/include/arc/std/lexer.h b/include/arc/std/lexer.h new file mode 100644 index 0000000..a68f65d --- /dev/null +++ b/include/arc/std/lexer.h @@ -0,0 +1,31 @@ +#ifndef ARC_STD_LEXER_H_ +#define ARC_STD_LEXER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief a lexer type +*/ +typedef struct ARC_Lexer ARC_Lexer; + +/** + * @brief + * + * @param[out] lexer +*/ +void ARC_Lexer_Create(ARC_Lexer **lexer); + +/** + * @brief + * + * @param[in] lexer ARC_Lexer to free +*/ +void ARC_Lexer_Destroy(ARC_Lexer *lexer); + +#ifdef __cplusplus +} +#endif + +#endif // !ARC_STD_LEXER_H_ diff --git a/include/arc/std/parser.h b/include/arc/std/parser.h new file mode 100644 index 0000000..e69de29 diff --git a/include/arc/std/vector.h b/include/arc/std/vector.h index dad261c..23ea203 100644 --- a/include/arc/std/vector.h +++ b/include/arc/std/vector.h @@ -5,81 +5,100 @@ extern "C" { #endif +#include "arc/std/bool.h" #include /** * @brief a dynamic array type - */ +*/ typedef struct ARC_Vector ARC_Vector; /** - * @brief data comparison function ptr + * @brief a callback that allows the user to define a way to check the data stored in a vector for a match * - * @param a first data struct - * @param b second data struct + * @param[in] dataA the first data to check + * @param[in] dataB the second data to check * - * @return 0 when a == b, TODO: return and ARC_Bool + * @return ARC_True when dataA == dataB, and ARC_False otherwise */ -typedef int32_t (* ARC_Vector_CompareDataFn)(void *a, void *b); +typedef ARC_Bool (* ARC_Vector_CompareDataFn)(void *dataA, void *dataB); /** - * @brief creates ARC_Vector type + * @brief creates an ARC_Vector which is an "expandable" array * - * @param vector ARC_Vector to initialize - */ -void ARC_Vector_Create(ARC_Vector **vector); + * @note for this basic implementation, the array will double in size every time the capacity is hit + * @note the array will also half in size when the array is only half filled + * + * @param[out] vector ARC_Vector to initialize + * @param[in] compareDataFn a callback that checks if data stored in the array matches, + * if set to NULL and ARC_Vector_Remove is called, the pointer addresses will be compared +*/ +void ARC_Vector_Create(ARC_Vector **vector, ARC_Vector_CompareDataFn *compareDataFn); /** - * @brief destroyes ARC_Vector type - */ + * @brief destroys an ARC_Vector + * + * @note this will not free the items stored in the vector + * @note please make sure to clear and free the children before destroying an ARC_Vector + * + * @param[in] vector ARC_Vector to free +*/ void ARC_Vector_Destroy(ARC_Vector *vector); /** - * @brief adds value to vector + * @brief adds an item to an ARC_Vector * - * @param vector ARC_Vector to add to - * @param data data that is being added - */ + * @note this will error if you add more than 4,294,967,295 items (the max value of an unsigned int 32) + * + * @param[in] vector ARC_Vector to add to + * @param[in] data data that is being added +*/ void ARC_Vector_Add(ARC_Vector *vector, void *data); /** - * @brief remove from ARC_Vector + * @brief removes an item from a matching item in an ARC_Vector * - * @param vector ARC_Vector to remove from - * @param data data that is being removed - * @param compare comparison callback to get check if data should be removed - */ -void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare); + * @note this function uses the ARC_Vector_CompareDataFn that the ARC_Vector was created with + * @note this function will not throw an error if there is no match + * + * @param[in] vector ARC_Vector to remove from + * @param[in] data matching data to remove +*/ +void ARC_Vector_Remove(ARC_Vector *vector, void *data); /** - * @brief remove from ARC_Vector + * @brief removes an item from an ARC_Vector at an index * - * @param vector ARC_Vector to remove from - * @param index index of data that is being removed - */ + * @note this function will error if trying to remove an index that is outside the bounds of the ARC_Vector + * + * @param[in] vector ARC_Vector to remove from + * @param[in] index position of data to remove +*/ void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t index); /** - * @brief gets size of vector + * @brief gets the current size of an ARC_Vector as an unsigned 32 bit integer * - * @param vector ARC_Vector to get size from + * @param[in] vector ARC_Vector to get current size from * - * @return the pointer of the vectors size, TODO: don't pass as a pointer - */ -uint32_t ARC_Vector_Size(ARC_Vector *vector); + * @return the current size as a unsigned 32 bit integer +*/ +uint32_t ARC_Vector_GetSize(ARC_Vector *vector); /** - * @brief gets data from ARC_Vector at position index + * @brief gets an item from an ARC_Vector at a position index * - * @param vector ARC_Vector to get data from - * @param index position of data in ARC_Vector + * @note this function will error if trying to get an index that is outside the bounds of the ARC_Vector * - * @return pointer to data on success, NULL on fail - */ + * @param[in] vector ARC_Vector to get data from + * @param[in] index position of data to get + * + * @return a void * item, or NULL on error +*/ void *ARC_Vector_Get(ARC_Vector *vector, uint32_t index); #ifdef __cplusplus } #endif -#endif //ARC_STD_VECTOR_H_ \ No newline at end of file +#endif // !ARC_STD_VECTOR_H_ diff --git a/src/std/errno.c b/src/std/errno.c index f6748b2..69f3df7 100644 --- a/src/std/errno.c +++ b/src/std/errno.c @@ -1,3 +1,16 @@ #include "arc/std/errno.h" -int32_t arc_errno = 0; \ No newline at end of file +#include + +int32_t arc_errno = 0; + +#if ARC_DEBUG + #include + FILE *arc_errno_log_file = NULL; + + #ifndef ARC_DEBUG_LOG_STREAM_OVERRIDE + void ARC_Errno_SetDefaultStream(void){ + arc_errno_log_file = stdout; + } + #endif +#endif diff --git a/src/std/lexer.c b/src/std/lexer.c new file mode 100644 index 0000000..e69de29 diff --git a/src/std/parser.c b/src/std/parser.c new file mode 100644 index 0000000..e69de29 diff --git a/src/std/vector.c b/src/std/vector.c index d9d5707..e49c1b4 100644 --- a/src/std/vector.c +++ b/src/std/vector.c @@ -1,105 +1,131 @@ + #include "arc/std/vector.h" +#include "arc/std/bool.h" #include "arc/std/errno.h" -#include #include -#include +#include struct ARC_Vector { - uint32_t currentSize, capacity; + uint32_t currentCapacity; + uint32_t currentSize; + void **data; + + ARC_Vector_CompareDataFn compareDataFn; }; -void ARC_Vector_Create(ARC_Vector **vector){ - *vector = (ARC_Vector *) malloc(sizeof(ARC_Vector)); - (*vector)->currentSize = 0; - (*vector)->capacity = 1; - (*vector)->data = (void **)malloc(sizeof(void *)); +//this is a private function used as the default check for removing data from a given pointer +ARC_Bool ARC_Vector_CompareDataDefaultFn(void *dataA, void *dataB){ + if(dataA == dataB){ + return ARC_True; + } + + return ARC_False; +} + +void ARC_Vector_Create(ARC_Vector **vector, ARC_Vector_CompareDataFn *compareDataFn){ + //create the vector + *vector = (ARC_Vector *)malloc(sizeof(ARC_Vector)); + + //initialize all the values stored in the vector + (*vector)->data = (void **)malloc(sizeof(void *)); + (*vector)->currentCapacity = 1; + (*vector)->currentSize = 0; + + //set a default for compareDataFn, then override it if it is passed in through parameters + (*vector)->compareDataFn = ARC_Vector_CompareDataDefaultFn; + if(compareDataFn != NULL){ + (*vector)->compareDataFn = *compareDataFn; + } } void ARC_Vector_Destroy(ARC_Vector *vector){ + //free everything stored in the vector free(vector->data); + + //free the vector free(vector); } void ARC_Vector_Add(ARC_Vector *vector, void *data){ + //check to see if the current size is the same as a max uint32_t and if so it will overflow so throw an error if(vector->currentSize == ~((uint32_t)0)){ arc_errno = ARC_ERRNO_OVERFLOW; + ARC_DEBUG_LOG_ERROR("ARC_Vector_Add(vector, data), vector at max capacity tried adding another value"); return; } - if(vector->currentSize == vector->capacity){ - if(!vector->capacity){ - ++vector->capacity; - } - vector->capacity <<= 1; + //check if we are at the max of the current capacity + if(vector->currentSize == vector->currentCapacity){ + //increase the current capacity by double + vector->currentCapacity <<= 1; - vector->data = (void *)realloc(vector->data, sizeof(void *) * vector->capacity); + //if for some reason the capacity is 0, we should set it to one so we do not error on realloc + if(vector->currentCapacity != 0){ + vector->currentCapacity++; + } + + //resize the vectors array and copy the contents at the same time + vector->data = (void **)realloc(vector->data, sizeof(void *) * vector->currentCapacity); } + //add to the vectors array and increase its current size vector->data[vector->currentSize] = data; - ++(vector->currentSize); + vector->currentSize++; } -//this function removes the redundant checking currentSize and index that would happen if ARC_Vector_Remove called ARC_Vector_RemoveIndex -void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t index); +void ARC_Vector_Remove(ARC_Vector *vector, void *data){ + //iterate through every item to check to see if it exists + for(uint32_t index = 0; index < vector->currentSize; index++){ + //keep the code cleaner by pulling the current index data into a temp variable + void *dataB = vector->data[index]; -void ARC_Vector_Remove(ARC_Vector *vector, void *data, ARC_Vector_CompareDataFn compare){ - if(!vector->currentSize){ - arc_errno = ARC_ERRNO_DATA; - return; - } - - for(uint32_t i = 0; i < vector->currentSize; i++){ - if(!compare(data, vector->data[i])){ - ARC_Vector_RemoveIndexNoCheck(vector, i); - return; + //check if the data matches, and if so remove by index + if(vector->compareDataFn(data, dataB) == ARC_True){ + ARC_Vector_RemoveIndex(vector, index); } } - - //no matching data found in compare function - arc_errno = ARC_ERRNO_DATA; } void ARC_Vector_RemoveIndex(ARC_Vector *vector, uint32_t index){ - if(!vector->currentSize || index >= vector->currentSize){ + //check to make sure the given index is in bounds of the vector + if(index >= vector->currentSize){ arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR("ARC_Vector_Add(vector, data), vector at max capacity tried adding another value"); return; } - ARC_Vector_RemoveIndexNoCheck(vector, index); -} - -void ARC_Vector_RemoveIndexNoCheck(ARC_Vector *vector, uint32_t index){ - for(uint32_t i = index; i <= vector->currentSize; i++){ - if(i + 1 >= vector->currentSize - 1){ - break; - } - vector->data[i] = vector->data[i + 1]; + //we will be using index to iterate as we will not use it again, so we can skip the first part of the for loop + for(; index + 1 < vector->currentSize; index++){ + //override the data from index to the end by shifting it back one + vector->data[index] = vector->data[index + 1]; } - --vector->currentSize; + //we have removed the item so we can decrease the current size + vector->currentSize--; - if(vector->currentSize != vector->capacity >> 1){ + //if the current size is half the current capacity or the current capacity is at the smallest limit, we do not need to do anything else + if(vector->currentSize != vector->currentCapacity >> 1 || vector->currentCapacity == 1){ return; } - vector->capacity >>= 1; - if(vector->capacity <= 0){ - vector->capacity = 1; - } - - vector->data = (void *)realloc(vector->data, sizeof(void *) * vector->capacity); + //half the capacity and copy it into a smaller array + vector->currentCapacity >>= 1; + vector->data = (void **)realloc(vector->data, sizeof(void *) * vector->currentCapacity); } -uint32_t ARC_Vector_Size(ARC_Vector *vector){ +uint32_t ARC_Vector_GetSize(ARC_Vector *vector){ return vector->currentSize; } void *ARC_Vector_Get(ARC_Vector *vector, uint32_t index){ + //check to make sure the given index is in bounds of the vector if(index >= vector->currentSize){ + arc_errno = ARC_ERRNO_DATA; + ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Vector_Get(vector, %u), null value as the index was out of bounds", index); return NULL; } return vector->data[index]; -} \ No newline at end of file +} diff --git a/temp.txt b/temp.txt new file mode 100644 index 0000000..153c754 --- /dev/null +++ b/temp.txt @@ -0,0 +1,48 @@ + -> EOF + + -> | LAMBDA + -> | LAMBDA + -> | LAMBDA + -> | LAMBDA + -> | LAMBDA + -> | LAMBDA + -> | LAMBDA + + -> HASH + -> | + + -> | + -> SLASH SLASH | NEWLINE + -> SLASH ASTERISK ASTERISK SLASH + -> STRING | LAMBDA + + -> LEFT_CURLY_BRACE RIGHT_CURLY_BRACE + -> COLON COLON + + -> LEFT_PAREN RIGHT_PAREN LEFT_CURLY_BRACE RIGHT_CURLY_BRACE + -> | LAMBDA + -> COMMA | LAMBDA + + -> EQUALS SEMICOLON + -> | LAMBDA + -> | + -> | + -> SYMBOL + -> LEFT_PAREN RIGHT_PAREN | + -> | + -> | + -> LEFT_CURLY_BRACE RIGHT_CURLY_BRACE SEMICOLON + -> COMMA | LAMBDA + + -> LEFT_PAREN SEMICOLON + -> + -> COMMA + + -> + -> + -> + + -> | NUM + -> CHAR + -> | LAMBDA + -> CHAR | NUM diff --git a/tests/src/vector.c b/tests/src/vector.c new file mode 100644 index 0000000..15fa581 --- /dev/null +++ b/tests/src/vector.c @@ -0,0 +1,153 @@ +#include "../test.h" +#include "arc/std/bool.h" +#include "arc/std/errno.h" +#include "arc/std/vector.h" +#include + +ARC_Bool TEST_Vector_CompareDataFn(void *dataA, void *dataB){ + if(*(int32_t *)dataA == *(int32_t *)dataB){ + return ARC_True; + } + + return ARC_False; +} + +ARC_TEST(Vector_Add_RemoveIndex_Get){ + ARC_Vector *vector; + ARC_Vector_Create(&vector, NULL); + + int32_t val0 = 0; + int32_t val1 = 1; + int32_t val2 = 2; + int32_t val3 = 3; + int32_t val4 = 4; + + ARC_Vector_Add(vector, &val0); + ARC_Vector_Add(vector, &val1); + ARC_Vector_Add(vector, &val2); + ARC_Vector_Add(vector, &val3); + ARC_Vector_Add(vector, &val4); + + ARC_CHECK(0 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_CHECK(2 == *(int32_t *)ARC_Vector_Get(vector, 2)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 3)); + ARC_CHECK(4 == *(int32_t *)ARC_Vector_Get(vector, 4)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(2 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 2)); + ARC_CHECK(4 == *(int32_t *)ARC_Vector_Get(vector, 3)); + ARC_Vector_RemoveIndex(vector, 3); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(2 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 2)); + ARC_Vector_RemoveIndex(vector, 1); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_Vector_RemoveIndex(vector, 1); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_Vector_Destroy(vector); +} + +ARC_TEST(Vector_Add_Remove_Get){ + ARC_Vector *vector; + ARC_Vector_CompareDataFn testCompareDataFn = TEST_Vector_CompareDataFn; + ARC_Vector_Create(&vector, &testCompareDataFn); + + int32_t val0 = 0; + int32_t val1 = 1; + int32_t val2 = 2; + int32_t val3 = 3; + int32_t val4 = 4; + + ARC_Vector_Add(vector, &val0); + ARC_Vector_Add(vector, &val1); + ARC_Vector_Add(vector, &val2); + ARC_Vector_Add(vector, &val3); + ARC_Vector_Add(vector, &val4); + + ARC_CHECK(0 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_CHECK(2 == *(int32_t *)ARC_Vector_Get(vector, 2)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 3)); + ARC_CHECK(4 == *(int32_t *)ARC_Vector_Get(vector, 4)); + ARC_Vector_Remove(vector, &val0); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(2 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 2)); + ARC_CHECK(4 == *(int32_t *)ARC_Vector_Get(vector, 3)); + ARC_Vector_Remove(vector, &val4); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(2 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 2)); + ARC_Vector_Remove(vector, &val2); + + ARC_CHECK(1 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 1)); + ARC_Vector_Remove(vector, &val1); + + ARC_CHECK(3 == *(int32_t *)ARC_Vector_Get(vector, 0)); + ARC_Vector_Remove(vector, &val3); + + ARC_Vector_Destroy(vector); +} + +ARC_TEST(Vector_Add_RemoveIndex_GetSize){ + ARC_Vector *vector; + ARC_Vector_Create(&vector, NULL); + + int32_t val0 = 0; + int32_t val1 = 1; + int32_t val2 = 2; + int32_t val3 = 3; + int32_t val4 = 4; + + ARC_Vector_Add(vector, &val0); + ARC_Vector_Add(vector, &val1); + ARC_Vector_Add(vector, &val2); + ARC_Vector_Add(vector, &val3); + ARC_Vector_Add(vector, &val4); + + ARC_CHECK(5 == ARC_Vector_GetSize(vector)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_CHECK(4 == ARC_Vector_GetSize(vector)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_CHECK(3 == ARC_Vector_GetSize(vector)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_CHECK(2 == ARC_Vector_GetSize(vector)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_CHECK(1 == ARC_Vector_GetSize(vector)); + ARC_Vector_RemoveIndex(vector, 0); + + ARC_CHECK(0 == ARC_Vector_GetSize(vector)); + + ARC_Vector_Destroy(vector); +} + +ARC_TEST(Vector_Add_RemoveIndex_Get_Try_Out_Of_Bounds){ + ARC_Vector *vector; + ARC_Vector_Create(&vector, NULL); + + int32_t val0 = 0; + + ARC_Vector_Add(vector, &val0); + ARC_CHECK(NULL == ARC_Vector_Get(vector, 1)); + arc_errno = 0; + + ARC_Vector_RemoveIndex(vector, 0); + + ARC_Vector_Destroy(vector); +} diff --git a/tests/test.c b/tests/test.c new file mode 100644 index 0000000..d1ff162 --- /dev/null +++ b/tests/test.c @@ -0,0 +1,22 @@ +#include "test.h" + +#include "arc/std/errno.h" +#include +#include + +uint32_t *temp_arc_test_num_checks_run__ARC_TEST__ = NULL; +uint32_t *temp_arc_test_num_checks_passed__ARC_TEST__ = NULL; + +void ARC_Test_SetErrnoStream(void){ + arc_errno_log_file = fopen("tests/test_error_out.txt", "w"); +} + +void ARC_Test_UnsetErrnoStream(void){ + fclose(arc_errno_log_file); +} + +#ifndef ARC_TEST_NO_MAIN +int main(void){ + return 0; +} +#endif diff --git a/tests/test.h b/tests/test.h new file mode 100644 index 0000000..7fa0312 --- /dev/null +++ b/tests/test.h @@ -0,0 +1,44 @@ +#ifndef ARC_TEST_H_ +#define ARC_TEST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +extern uint32_t *temp_arc_test_num_checks_run__ARC_TEST__; +extern uint32_t *temp_arc_test_num_checks_passed__ARC_TEST__; + +void ARC_Test_SetErrnoStream(void) __attribute__ ((constructor)); +void ARC_Test_UnsetErrnoStream(void) __attribute__ ((destructor)); + +#define ARC_TEST_START_MESSAGE(MESSAGE) void ARC_TEST_START_MESSAGE__ ## MESSAGE(void) __attribute__ ((constructor));\ + uint32_t arc_test_num_checks_run__ARC_TEST__ ## MESSAGE = 0;\ + uint32_t arc_test_num_checks_passed__ARC_TEST__ ## MESSAGE = 0;\ + void ARC_TEST_START_MESSAGE__ ## MESSAGE(void){\ + printf("[ARC TEST] Running: %s\n", #MESSAGE);\ + temp_arc_test_num_checks_run__ARC_TEST__ = &arc_test_num_checks_run__ARC_TEST__ ## MESSAGE; \ + temp_arc_test_num_checks_passed__ARC_TEST__ = &arc_test_num_checks_passed__ARC_TEST__ ## MESSAGE; \ + } + +#define ARC_TEST_END_MESSAGE(MESSAGE) void ARC_TEST_END_MESSAGE__ ## MESSAGE(void) __attribute__ ((destructor));\ + void ARC_TEST_END_MESSAGE__ ## MESSAGE(void){\ + printf("[ARC TEST] RUN: %4u, PASSED: %4u, FAILED: %4u, Completed: %s\n", arc_test_num_checks_run__ARC_TEST__ ## MESSAGE, arc_test_num_checks_passed__ARC_TEST__ ## MESSAGE, arc_test_num_checks_run__ARC_TEST__ ## MESSAGE - arc_test_num_checks_passed__ARC_TEST__ ## MESSAGE, #MESSAGE);\ + } + +#define ARC_TEST(MESSAGE) ARC_TEST_START_MESSAGE(MESSAGE) ARC_TEST_END_MESSAGE(MESSAGE) void ARC_TEST__ ## MESSAGE(void) __attribute__ ((constructor)); void ARC_TEST__ ## MESSAGE (void) + +#define ARC_CHECK(TEST)\ + if(temp_arc_test_num_checks_run__ARC_TEST__ == NULL || temp_arc_test_num_checks_passed__ARC_TEST__ == NULL){ return; }\ + printf(" %4u) ", *temp_arc_test_num_checks_run__ARC_TEST__);\ + ++*temp_arc_test_num_checks_run__ARC_TEST__;\ + if(TEST){ printf("PASS\t\n"); ++*temp_arc_test_num_checks_passed__ARC_TEST__; }\ + else { printf("FAIL\t%s\n", #TEST); } + +#ifdef __cplusplus +} +#endif + +#endif // !ARC_TEST_H_