diff --git a/CMakeLists.txt b/CMakeLists.txt index 819e9de..8c78e13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,7 +132,7 @@ if(ARCHEUS_STD_TESTS) #tests/std/vector.c #tests/std/lexer.c - tests/std/parser.c + #tests/std/parser.c tests/std/parser/csv.c tests/std/parser/parserlang.c diff --git a/src/std/parser.c b/src/std/parser.c index 07d244b..2825bb4 100644 --- a/src/std/parser.c +++ b/src/std/parser.c @@ -336,9 +336,9 @@ void ARC_Parser_Parse(ARC_Parser *parser, ARC_String **data){ (*(parser->createDataFn))(&(parser->data), tagToken, parser->userData); } + ARC_ParserTagToken_Destroy(tagToken); //cleanup ARC_Lexer_Clear(parser->lexer); - ARC_ParserTagToken_Destroy(tagToken); } void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){ diff --git a/src/std/parser/csv.c b/src/std/parser/csv.c index ce02ba2..7d97e28 100644 --- a/src/std/parser/csv.c +++ b/src/std/parser/csv.c @@ -22,6 +22,10 @@ void ARC_ParserCSV_InitLexerRulesFn(ARC_Lexer *lexer){ } uint32_t ARC_ParserCSV_GetStringIdFn(ARC_String *string){ + if(ARC_String_EqualsCStringWithStrlen(string, "LAMBDA")){ + return ARC_PARSER_TAG_LAMBDA; + } + if(ARC_String_EqualsCStringWithStrlen(string, "COMMA")){ return ARC_PARSER_CSV_CHAR_COMMA; } @@ -116,7 +120,9 @@ void ARC_ParserCSVData_RunLineTag(ARC_Vector *dataVector, ARC_ParserTagToken *ta ARC_ParserCSVData_RunLineTag(dataVector, childTagToken, userData); continue; + //get the row data case ARC_PARSER_CSV_DATA: + ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData); continue; //add a new row for each new line @@ -133,8 +139,10 @@ void ARC_ParserCSVData_RunLineTag(ARC_Vector *dataVector, ARC_ParserTagToken *ta } void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ + *data = NULL; if(data == NULL || userData == NULL){ //TODO: error here? + *data = NULL; return; } @@ -161,37 +169,92 @@ void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, voi 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++; } + //init the height and width of all found rows, height starts at 1 as the first row is already found + uint32_t dataHeight = 1; + uint32_t dataWidth = 0; + + //TODO: fix this for headers + //get the first non-empty row of dataVector for its width + for(; dataStartIndex < ARC_Vector_GetSize(dataVector); dataStartIndex++){ + dataRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, dataStartIndex); + dataWidth = ARC_Vector_GetSize(dataRowVector); + + //breakout if a valid row is found + if(dataWidth != 0){ + break; + } + } + + //fix this for headers + //check if a valid row if found + if(dataWidth == 0){ + //TODO: iterate and clear the vector + //TODO: error here? + *data = NULL; + ARC_Vector_Destroy(dataVector); + return; + } + + //check that all the rows are the same size + for(uint32_t rowIndex = dataStartIndex + 1; rowIndex < ARC_Vector_GetSize(dataVector); rowIndex++){ + ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex); + + //skip an empty line + uint32_t currentRowVectorSize = ARC_Vector_GetSize(currentRowVector); + if(currentRowVectorSize == 0){ + continue; + } + + //a row was found so update the height + dataHeight++; + + //TODO: probs want to error + //cleanup and exit if they don't match + if(dataWidth != currentRowVectorSize){ + //TODO: iterate and clear the vector + ARC_Vector_Destroy(dataVector); + return; + } + } + //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); + csvData->hasHeader = csvUserData->header; + //TODO: fix this + csvData->headers = NULL; + csvData->height = dataHeight; + csvData->width = dataWidth; + + if(csvData->height == 0 || csvData->width == 0){ + //TODO: error here? + free(csvData); + *data = NULL; + return; + } + + //init location to copy data to + csvData->data = (void ***)malloc(sizeof(void **) * csvData->height); //copy the data - for(uint32_t y = 0; y < csvData->height; y++){ + uint32_t rowIndex = 0; + for(uint32_t y = 0; y < csvData->height; y++, rowIndex++){ + ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex + dataStartIndex); + + //skip an empty line + uint32_t currentRowVectorSize = ARC_Vector_GetSize(currentRowVector); + if(currentRowVectorSize == 0){ + y--; + continue; + } + + //create the current row 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); @@ -204,24 +267,28 @@ void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, voi } void ARC_ParserCSVData_DestroyFn(void *data, ARC_Bool clear, void *userData){ - if(userData == NULL){ return; } + 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); + //cleanup the headers if they exist + if(csvData->hasHeader == ARC_True){ + for(uint32_t x = 0; x < csvData->width; x++){ + ARC_String *string = csvData->headers[x]; + ARC_String_Destroy(string); + } + free(csvData->headers); } - free(csvData->headers); for(uint32_t y = 0; y < csvData->height; y++){ //cleanup each element in the data for(uint32_t x = 0; x < csvData->width; x++){ - csvUserData->destroyTypeFn(csvData->data[y] + x); + csvUserData->destroyTypeFn(csvData->data[y][x]); } //cleanup each row of data diff --git a/tests/std/parser/csv.c b/tests/std/parser/csv.c index bfb9900..6ea3333 100644 --- a/tests/std/parser/csv.c +++ b/tests/std/parser/csv.c @@ -21,10 +21,10 @@ ARC_TEST(Parser_ParserCSV_BasicTest){ 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"; + "1,1,2,2\n" + "2,3,4,5\n" + "4,2,4,1\n" + "7,7,7,7\n"; ARC_String *tempString; ARC_String_CreateWithStrlen(&tempString, (char *)tempCString); @@ -34,10 +34,12 @@ ARC_TEST(Parser_ParserCSV_BasicTest){ 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]); + printf("%d ", *(int32_t *)(data->data[y][x])); } + printf("\n"); } ARC_Parser_Destroy(parser);