diff --git a/Doxyfile b/Doxyfile index 340951c..80ae249 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,6 +1,6 @@ PROJECT_NAME = ge_lib PROJECT_NUMBER = 0.0.0 -OUTPUT_DIRECTORY = ./doxygen/ +OUTPUT_DIRECTORY = ./doc/doxygen/ OPTIMIZE_OUTPUT_FOR_C = YES EXTRACT_ALL = YES EXTRACT_PRIVATE = YES diff --git a/doxygen/doxygen-awesome-css/.github/workflows/publish.yaml b/doc/doxygen/doxygen-awesome-css/.github/workflows/publish.yaml similarity index 100% rename from doxygen/doxygen-awesome-css/.github/workflows/publish.yaml rename to doc/doxygen/doxygen-awesome-css/.github/workflows/publish.yaml diff --git a/doxygen/doxygen-awesome-css/.gitignore b/doc/doxygen/doxygen-awesome-css/.gitignore similarity index 100% rename from doxygen/doxygen-awesome-css/.gitignore rename to doc/doxygen/doxygen-awesome-css/.gitignore diff --git a/doxygen/doxygen-awesome-css/LICENSE b/doc/doxygen/doxygen-awesome-css/LICENSE similarity index 100% rename from doxygen/doxygen-awesome-css/LICENSE rename to doc/doxygen/doxygen-awesome-css/LICENSE diff --git a/doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css b/doc/doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css similarity index 100% rename from doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css rename to doc/doxygen/doxygen-awesome-css/docs/doxygen-custom/custom.css diff --git a/doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html b/doc/doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html similarity index 100% rename from doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html rename to doc/doxygen/doxygen-awesome-css/docs/doxygen-custom/footer.html diff --git a/doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html b/doc/doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html similarity index 100% rename from doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html rename to doc/doxygen/doxygen-awesome-css/docs/doxygen-custom/header.html diff --git a/doxygen/doxygen-awesome-css/docs/page.dox b/doc/doxygen/doxygen-awesome-css/docs/page.dox similarity index 100% rename from doxygen/doxygen-awesome-css/docs/page.dox rename to doc/doxygen/doxygen-awesome-css/docs/page.dox diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js b/doc/doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js similarity index 100% rename from doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js rename to doc/doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css b/doc/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css similarity index 100% rename from doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css rename to doc/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css b/doc/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css similarity index 100% rename from doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css rename to doc/doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css diff --git a/doxygen/doxygen-awesome-css/doxygen-awesome.css b/doc/doxygen/doxygen-awesome-css/doxygen-awesome.css similarity index 100% rename from doxygen/doxygen-awesome-css/doxygen-awesome.css rename to doc/doxygen/doxygen-awesome-css/doxygen-awesome.css diff --git a/doxygen/doxygen-awesome-css/footer.html b/doc/doxygen/doxygen-awesome-css/footer.html similarity index 100% rename from doxygen/doxygen-awesome-css/footer.html rename to doc/doxygen/doxygen-awesome-css/footer.html diff --git a/doxygen/doxygen-awesome-css/header.html b/doc/doxygen/doxygen-awesome-css/header.html similarity index 100% rename from doxygen/doxygen-awesome-css/header.html rename to doc/doxygen/doxygen-awesome-css/header.html diff --git a/doxygen/doxygen-awesome-css/img/screenshot.png b/doc/doxygen/doxygen-awesome-css/img/screenshot.png similarity index 100% rename from doxygen/doxygen-awesome-css/img/screenshot.png rename to doc/doxygen/doxygen-awesome-css/img/screenshot.png diff --git a/doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg b/doc/doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg similarity index 100% rename from doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg rename to doc/doxygen/doxygen-awesome-css/img/theme-variations.drawio.svg diff --git a/include/arc/std/parser.h b/include/arc/std/parser.h index d6ba98d..49915ba 100644 --- a/include/arc/std/parser.h +++ b/include/arc/std/parser.h @@ -59,7 +59,7 @@ typedef void (* ARC_ParserData_CreateFn)(void **data, ARC_ParserTagToken *parsed /** * @brief TODO: write this */ -typedef void (* ARC_ParserData_DestroyFn)(void *data, void *userData); +typedef void (* ARC_ParserData_DestroyFn)(void *data, ARC_Bool clear, void *userData); /** * @brief creates an ARC_Parser type diff --git a/include/arc/std/parser/csv.h b/include/arc/std/parser/csv.h index 757fd1c..5b81e55 100644 --- a/include/arc/std/parser/csv.h +++ b/include/arc/std/parser/csv.h @@ -11,9 +11,10 @@ extern "C" { #include /* - -> NEWLINE | | NEWLINE | LAMBDA - -> COMMA | - -> COMMON_CHAR | COMON_CHAR + -> NEWLINE | | NEWLINE | LAMBDA + -> COMMA | + -> | + -> CHAR_BEFORE_COMMA | CHAR_AFTER_COMMA */ /** @@ -24,7 +25,7 @@ extern "C" { * @param[in/out] data the csv data casted into the users type * @param[in] string an value of the csv as a string */ -typedef uint32_t (* ARC_ParserCSV_CastTypeFn)(void **data, ARC_String *string); +typedef void (* ARC_ParserCSV_CastTypeFn)(void **data, ARC_String *string); /** * @brief a callback for the csv parser to use to free csv data @@ -33,13 +34,12 @@ typedef uint32_t (* ARC_ParserCSV_CastTypeFn)(void **data, ARC_String *string); * * @param[in] data the csv data to free */ -typedef uint32_t (* ARC_ParserCSV_DestroyTypeFn)(void *data); +typedef void (* ARC_ParserCSV_DestroyTypeFn)(void *data); /** * @brief defines a csv data type, data is set by the callback passed in when createing a parserCSV as parser * * @note this data can be retieved after parsing by calling get data, check arc/std/parser.h for more information - * @note destroyTypeFn is stored here (for clearing as userdata is not passed in then) but should not be used by anything but the parser */ typedef struct ARC_ParserCSVData { ARC_Bool hasHeader; @@ -47,9 +47,7 @@ typedef struct ARC_ParserCSVData { uint32_t width; uint32_t height; - void **data; - - ARC_ParserCSV_DestroyTypeFn destroyTypeFn; + void ***data; } ARC_ParserCSVData; /** @@ -62,6 +60,15 @@ typedef struct ARC_ParserCSVData { */ void ARC_ParserCSV_CreateAsParser(ARC_Parser **parser, ARC_Bool header, ARC_ParserCSV_CastTypeFn castTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn); +#define ARC_PARSER_CSV_CHAR_COMMA 1 +#define ARC_PARSER_CSV_CHAR_NEWLINE 2 +#define ARC_PARSER_CSV_CHAR_BEFORE_COMMA 3 +#define ARC_PARSER_CSV_CHAR_AFTER_COMMA 4 +#define ARC_PARSER_CSV_LINE 5 +#define ARC_PARSER_CSV_DATA 6 +#define ARC_PARSER_CSV_STRING 7 +#define ARC_PARSER_CSV_NON_COMMA_CHAR 8 + #ifdef __cplusplus } #endif diff --git a/src/std/parser.c b/src/std/parser.c index bd5d23a..07d244b 100644 --- a/src/std/parser.c +++ b/src/std/parser.c @@ -144,7 +144,8 @@ void ARC_Parser_Destroy(ARC_Parser *parser){ //do the same thing as clear but this time pass in the userData as well to clean that up if(parser->destroyDataFn != NULL){ - (*(parser->destroyDataFn))(parser->data, parser->userData); + //set to false to indicate full destroy instead of clear + (*(parser->destroyDataFn))(parser->data, ARC_False, parser->userData); free(parser->destroyDataFn); } @@ -345,9 +346,9 @@ void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){ } void ARC_Parser_ClearData(ARC_Parser *parser){ - //check if that data exists and the destructor exists to make sure they can be run + //check if that data exists and the destructor exists to make sure they can be run, set to true to indicate clear if(parser->data != NULL && parser->destroyDataFn != NULL){ - (*(parser->destroyDataFn))(parser->data, NULL); + (*(parser->destroyDataFn))(parser->data, ARC_True, parser->userData); } //TODO: might want to error here diff --git a/src/std/parser/csv.c b/src/std/parser/csv.c index cb8bfca..ce02ba2 100644 --- a/src/std/parser/csv.c +++ b/src/std/parser/csv.c @@ -1,7 +1,9 @@ #include "arc/std/parser/csv.h" #include "arc/std/parser/helpers.h" +#include "arc/std/bool.h" #include "arc/std/parser.h" #include +#include #include typedef struct ARC_ParserCSVUserData { @@ -11,22 +13,205 @@ typedef struct ARC_ParserCSVUserData { } ARC_ParserCSVUserData; void ARC_ParserCSV_InitLexerRulesFn(ARC_Lexer *lexer){ + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_PARSER_CSV_CHAR_COMMA , ',' )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_PARSER_CSV_CHAR_NEWLINE, '\n')); + + //NOTE: used an ascii table to get these values + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_PARSER_CSV_CHAR_BEFORE_COMMA, 0x21, 0x2b)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_PARSER_CSV_CHAR_AFTER_COMMA , 0x2d, 0x7e)); } uint32_t ARC_ParserCSV_GetStringIdFn(ARC_String *string){ - return 0; + if(ARC_String_EqualsCStringWithStrlen(string, "COMMA")){ + return ARC_PARSER_CSV_CHAR_COMMA; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "NEWLINE")){ + return ARC_PARSER_CSV_CHAR_NEWLINE; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "CHAR_BEFORE_COMMA")){ + return ARC_PARSER_CSV_CHAR_BEFORE_COMMA; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "CHAR_AFTER_COMMA")){ + return ARC_PARSER_CSV_CHAR_AFTER_COMMA; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_PARSER_CSV_LINE; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_PARSER_CSV_DATA; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_PARSER_CSV_STRING; + } + + if(ARC_String_EqualsCStringWithStrlen(string, "")){ + return ARC_PARSER_CSV_NON_COMMA_CHAR; + } + + return ~(uint32_t)0; } -void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ - if(data == NULL){ - return; +void ARC_ParserCSVData_VectorDestroyVectorFn(void *data){ + ARC_Vector *vector = (ARC_Vector *)data; + ARC_Vector_Destroy(vector); +} + +void ARC_ParserCSVData_GetDataTag(ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData){ + //loop through the tags either recursing to next body or adding data to vector + for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); + + ARC_String *stringData = NULL; + ARC_Vector *row = NULL; + uint32_t rowIndex = 0; + + switch(childTagToken->id){ + //recuse to run the next line + case ARC_PARSER_CSV_STRING: + //get the string of the data + ARC_String_Create(&stringData, NULL, 0); + ARC_ParserData_HelperRecurseStringAdd(&stringData, childTagToken); + + //move data string and cleanup + void *data; + userData->castTypeFn(&data, stringData); + ARC_String_Destroy(stringData); + + //get the last row vector + rowIndex = ARC_Vector_GetSize(dataVector) - 1; + row = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex); + + //add the data to the row vector + ARC_Vector_Add(row, data); + continue; + + case ARC_PARSER_CSV_DATA: + ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData); + continue; + + default: + //this should only be the case for the comma + continue; + } } } -void ARC_ParserCSVData_DestroyFn(void *data, void *userData){ +// -> NEWLINE | | NEWLINE | LAMBDA +void ARC_ParserCSVData_RunLineTag(ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData){ + //loop through the tags either going to the next line or the next body + for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){ + ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index); + + ARC_Vector *row; + + switch(childTagToken->id){ + //recuse to run the next line + case ARC_PARSER_CSV_LINE: + ARC_ParserCSVData_RunLineTag(dataVector, childTagToken, userData); + continue; + + case ARC_PARSER_CSV_DATA: + continue; + + //add a new row for each new line + case ARC_PARSER_CSV_CHAR_NEWLINE: + //create a new row + ARC_Vector_Create(&row, NULL, NULL); + ARC_Vector_Add(dataVector, (void *)row); + continue; + + default: + continue; + } + } +} + +void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ + if(data == NULL || userData == NULL){ + //TODO: error here? + return; + } + + //cast the csv data back to its original type + ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData; + + //crate a vector for the data to be stored in before being copied to a 2d array + ARC_Vector *dataVector; + ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserCSVData_VectorDestroyVectorFn; + ARC_Vector_Create(&dataVector, NULL, &destroyVectorFn); + + //create the first row vector, does not need a destroy function as its contents will be moved + ARC_Vector *dataRowVector; + ARC_Vector_Create(&dataRowVector, NULL, NULL); + + //add the row to the dataVector + ARC_Vector_Add(dataVector, (void *)dataRowVector); + + //recursively add data from the parsedData to the data vector + ARC_ParserCSVData_RunLineTag(dataVector, parsedData, csvUserData); + if(ARC_Vector_GetSize(dataVector) == 0){ + //TODO: iterate and clear the vector + ARC_Vector_Destroy(dataVector); + return; + } + + //get the first row of dataVector for its width + dataRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, 0); + + //check that all the rows are the same size + for(uint32_t rowIndex = 1; rowIndex < ARC_Vector_GetSize(dataVector); rowIndex++){ + ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex); + + //TODO: probs want to error + //cleanup and exit if they don't match + if(ARC_Vector_GetSize(dataRowVector) != ARC_Vector_GetSize(currentRowVector)){ + //TODO: iterate and clear the vector + ARC_Vector_Destroy(dataVector); + return; + } + } + + uint32_t dataStartIndex = 0; + if(csvUserData->header == ARC_True){ + //TODO: headers + dataStartIndex++; + } + + //create the data that will be saved + ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)malloc(sizeof(ARC_ParserCSVData)); + csvData->height = ARC_Vector_GetSize(dataVector) - dataStartIndex; + csvData->width = ARC_Vector_GetSize(dataRowVector); + + //copy the data + for(uint32_t y = 0; y < csvData->height; y++){ + csvData->data[y] = (void **)malloc(sizeof(void *) * csvData->width); + ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, y + dataStartIndex); + + for(uint32_t x = 0; x < csvData->width; x++){ + csvData->data[y][x] = ARC_Vector_Get(currentRowVector, x); + } + } + + ARC_Vector_Destroy(dataVector); + + *data = (void *)csvData; +} + +void ARC_ParserCSVData_DestroyFn(void *data, ARC_Bool clear, void *userData){ + if(userData == NULL){ return; } + + ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData; + if(data != NULL){ ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data; + //cleanup the headers for(uint32_t x = 0; x < csvData->width; x++){ ARC_String *string = csvData->headers[x]; ARC_String_Destroy(string); @@ -34,22 +219,30 @@ void ARC_ParserCSVData_DestroyFn(void *data, void *userData){ free(csvData->headers); for(uint32_t y = 0; y < csvData->height; y++){ - csvData->destroyTypeFn(csvData->data[y]); + //cleanup each element in the data + for(uint32_t x = 0; x < csvData->width; x++){ + csvUserData->destroyTypeFn(csvData->data[y] + x); + } + + //cleanup each row of data + free(csvData->data[y]); } + //cleanup the data free(csvData->data); } - if(userData != NULL){ - free((ARC_ParserCSVUserData *)userData); + if(clear == ARC_False){ + free(csvUserData); } } void ARC_ParserCSV_CreateAsParser(ARC_Parser **parser, ARC_Bool header, ARC_ParserCSV_CastTypeFn castTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn){ /* ~ define the language as a string ~ */ char *languageCString = - " -> NEWLINE | | NEWLINE | LAMBDA" - " -> COMMA | " - " -> COMMON_CHAR | COMON_CHAR"; + " -> NEWLINE | | NEWLINE | LAMBDA\n" + " -> COMMA | \n" + " -> | \n" + " -> CHAR_BEFORE_COMMA | CHAR_AFTER_COMMA\n"; ARC_String *languageString; ARC_String_CreateWithStrlen(&languageString, languageCString); diff --git a/src/std/parser/parserlang.c b/src/std/parser/parserlang.c index 0ef12a8..ae4d4c4 100644 --- a/src/std/parser/parserlang.c +++ b/src/std/parser/parserlang.c @@ -1,4 +1,5 @@ #include "arc/std/parser/parserlang.h" +#include "arc/std/bool.h" #include "arc/std/errno.h" #include "arc/std/lexer.h" #include "arc/std/parser.h" @@ -39,12 +40,12 @@ void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){ ARC_String_Destroy(arrowString); } -void ARC_ParserLang_VectorDestroyVector(void *data){ +void ARC_ParserLang_VectorDestroyVectorFn(void *data){ ARC_Vector *vector = (ARC_Vector *)data; ARC_Vector_Destroy(vector); } -void ARC_ParserLang_VectorDestroyUInt32(void *data){ +void ARC_ParserLang_VectorDestroyUInt32Fn(void *data){ uint32_t *uint = (uint32_t *)data; free(uint); } @@ -161,7 +162,7 @@ void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_Pars uint32_t tokensOrTagsIndex = 0; ARC_Vector *orTokensOrTags = NULL; - ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32; + ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32Fn; switch(childTagToken->id){ case ARC_PARSERLANG_ARGUMENT: @@ -213,12 +214,12 @@ void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagTo /* ~ Tokens Or Tags Array ~ */ //create a vector to store another vector of data ARC_Vector *tokensOrTags; - ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserLang_VectorDestroyVector; + ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserLang_VectorDestroyVectorFn; ARC_Vector_Create(&tokensOrTags, NULL, &destroyVectorFn); //create vector within the tokens or tags vector to store the or rule in ARC_Vector *orTokensOrTags; - ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32; + ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32Fn; ARC_Vector_Create(&orTokensOrTags, NULL, &destroyUint32Fn); //add the first or vector to the tokensOrTags @@ -308,14 +309,14 @@ void ARC_ParserLang_CreateDataFn(void **data, ARC_ParserTagToken *parsedData, vo } //private function to destroy the saved data for the language -void ARC_ParserLang_DestroyDataFn(void *data, void *userData){ +void ARC_ParserLang_DestroyDataFn(void *data, ARC_Bool clear, void *userData){ if(userData != NULL){ ARC_Parser_GetStringIdFn *getStringIdFn = (ARC_Parser_GetStringIdFn *)userData; free(getStringIdFn); } - //check if there is data to free - if((ARC_Vector *)data != NULL){ + //if not clearing (full destroy) check if there is data to free + if(clear == ARC_False && (ARC_Vector *)data != NULL){ ARC_Vector_Destroy((ARC_Vector *)data); } } diff --git a/temp_parser.txt b/temp_parser.txt deleted file mode 100644 index 1e326d4..0000000 --- a/temp_parser.txt +++ /dev/null @@ -1,70 +0,0 @@ -int i = 32; - - -> INT EQUALS SEMICOLON - -> - -> | LAMBDA - -> UPPER_ALPHA_CHAR | LOWER_ALPHA_CHAR | NUMBER - -> NUMBER - -> NUMBER | LAMBDA - -typedef struct TEMP_LangVar = { - ARC_String *name; - void *data; -} TEMP_LangVar; - -void *(* ARC_Parser_ConstantCallbackFn)(void **data, void *parentdata); - -defineIntLine -┌─────────────────── TEMP_LangVar var = { NULL, NULL } -│ INT -│ ┌───────────────── <- NULL -│ │ int -│ └───────────────── -│ -│ variable -│ ┌───────────────── ARC_String_Create(&(var.name)); -│ │ alphaChar -│ │ ┌─────────────── ARC_String_Append(var.name, "i"); -│ │ │ i -│ │ └─────────────── -│ │ -│ │ variableBody -│ │ ┌─────────────── -│ │ │ LAMBDA -│ │ └─────────────── -│ └───────────────── -│ -│ EQUALS -│ ┌───────────────── -│ │ = -│ └───────────────── -│ -│ value -│ ┌───────────────── var.name = malloc(sizeof(int32_t)); -│ │ NUMBER -│ │ ┌─────────────── *(var.name) = 3 -│ │ │ 3 -│ │ └─────────────── -│ │ -│ │ valueBody -│ │ ┌─────────────── -│ │ │ NUMBER -│ │ │ ┌───────────── *(var.name) = *var.name * 10 + 2 -│ │ │ │ 2 -│ │ │ └───────────── -│ │ │ -│ │ │ valueBody -│ │ │ ┌───────────── -│ │ │ │ LAMBDA -│ │ │ └───────────── -│ │ └─────────────── -│ └───────────────── -│ -│ SEMICOLON -│ ┌───────────────── -│ │ ; -│ └───────────────── -└─────────────────── - - - diff --git a/tests/std/parser.c b/tests/std/parser.c index a1f4aa3..96c7034 100644 --- a/tests/std/parser.c +++ b/tests/std/parser.c @@ -1,4 +1,5 @@ #include "../test.h" +#include "arc/std/bool.h" #include "arc/std/errno.h" #include "arc/std/parser.h" #include "arc/std/parser/helpers.h" @@ -21,7 +22,7 @@ void TEST_ParserData_CreateStringFn(void **data, ARC_ParserTagToken *parsedData, ARC_ParserData_HelperRecurseStringAdd((ARC_String **)data, parsedData); } -void TEST_ParserData_DestroyStringFn(void *data, void *userData){ +void TEST_ParserData_DestroyStringFn(void *data, ARC_Bool clear, void *userData){ if(data == NULL){ return; } @@ -254,7 +255,7 @@ void TEST_ParserData_CreateCharFn(void **data, ARC_ParserTagToken *parsedData, v *data = (void *)alphaChar; } -void TEST_ParserData_DestroyCharFn(void *data, void *userData){ +void TEST_ParserData_DestroyCharFn(void *data, ARC_Bool clear, void *userData){ if(data == NULL){ return; } diff --git a/tests/std/parser/csv.c b/tests/std/parser/csv.c index e69de29..bfb9900 100644 --- a/tests/std/parser/csv.c +++ b/tests/std/parser/csv.c @@ -0,0 +1,44 @@ +#include "../../test.h" +#include "arc/std/bool.h" +#include "arc/std/errno.h" +#include "arc/std/parser/csv.h" +#include + +void TEST_ParserCSV_CastTypeFn(void **data, ARC_String *string){ + int32_t *int32Data = (int32_t *)malloc(sizeof(int32_t)); + *int32Data = (int32_t)ARC_String_ToInt64_t(string); + + *data = (void *)int32Data; +} + +void TEST_ParserCSV_DestroyTypeFn(void *data){ + free((int32_t *)data); +} + + +ARC_TEST(Parser_ParserCSV_BasicTest){ + ARC_Parser *parser; + ARC_ParserCSV_CreateAsParser(&parser, ARC_False, TEST_ParserCSV_CastTypeFn, TEST_ParserCSV_DestroyTypeFn); + + const char *tempCString = + "1,1,2,2" + "2,3,4,5" + "4,2,4,1" + "7,7,7,7"; + + ARC_String *tempString; + ARC_String_CreateWithStrlen(&tempString, (char *)tempCString); + + //this destroys string, so no need for cleanup + ARC_Parser_Parse(parser, &tempString); + ARC_CHECK(arc_errno == 0); + + ARC_ParserCSVData *data = (ARC_ParserCSVData *)ARC_Parser_GetData(parser); + for(uint32_t y = 0; y < data->height; y++){ + for(uint32_t x = 0; x < data->width; x++){ + printf("%u", ((uint32_t *)(data->data[y]))[x]); + } + } + + ARC_Parser_Destroy(parser); +}