fixed csv, though there is a small memory leak
This commit is contained in:
parent
280a70c6e8
commit
2ef7a93d5a
4 changed files with 103 additions and 34 deletions
|
|
@ -132,7 +132,7 @@ if(ARCHEUS_STD_TESTS)
|
||||||
|
|
||||||
#tests/std/vector.c
|
#tests/std/vector.c
|
||||||
#tests/std/lexer.c
|
#tests/std/lexer.c
|
||||||
tests/std/parser.c
|
#tests/std/parser.c
|
||||||
tests/std/parser/csv.c
|
tests/std/parser/csv.c
|
||||||
tests/std/parser/parserlang.c
|
tests/std/parser/parserlang.c
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -336,9 +336,9 @@ void ARC_Parser_Parse(ARC_Parser *parser, ARC_String **data){
|
||||||
(*(parser->createDataFn))(&(parser->data), tagToken, parser->userData);
|
(*(parser->createDataFn))(&(parser->data), tagToken, parser->userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ARC_ParserTagToken_Destroy(tagToken);
|
||||||
//cleanup
|
//cleanup
|
||||||
ARC_Lexer_Clear(parser->lexer);
|
ARC_Lexer_Clear(parser->lexer);
|
||||||
ARC_ParserTagToken_Destroy(tagToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){
|
void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,10 @@ void ARC_ParserCSV_InitLexerRulesFn(ARC_Lexer *lexer){
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ARC_ParserCSV_GetStringIdFn(ARC_String *string){
|
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")){
|
if(ARC_String_EqualsCStringWithStrlen(string, "COMMA")){
|
||||||
return ARC_PARSER_CSV_CHAR_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);
|
ARC_ParserCSVData_RunLineTag(dataVector, childTagToken, userData);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
//get the row data
|
||||||
case ARC_PARSER_CSV_DATA:
|
case ARC_PARSER_CSV_DATA:
|
||||||
|
ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//add a new row for each new line
|
//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){
|
void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){
|
||||||
|
*data = NULL;
|
||||||
if(data == NULL || userData == NULL){
|
if(data == NULL || userData == NULL){
|
||||||
//TODO: error here?
|
//TODO: error here?
|
||||||
|
*data = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,37 +169,92 @@ void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, voi
|
||||||
return;
|
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;
|
uint32_t dataStartIndex = 0;
|
||||||
if(csvUserData->header == ARC_True){
|
if(csvUserData->header == ARC_True){
|
||||||
//TODO: headers
|
//TODO: headers
|
||||||
dataStartIndex++;
|
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
|
//create the data that will be saved
|
||||||
ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)malloc(sizeof(ARC_ParserCSVData));
|
ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)malloc(sizeof(ARC_ParserCSVData));
|
||||||
csvData->height = ARC_Vector_GetSize(dataVector) - dataStartIndex;
|
csvData->hasHeader = csvUserData->header;
|
||||||
csvData->width = ARC_Vector_GetSize(dataRowVector);
|
//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
|
//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);
|
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++){
|
for(uint32_t x = 0; x < csvData->width; x++){
|
||||||
csvData->data[y][x] = ARC_Vector_Get(currentRowVector, 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){
|
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;
|
ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData;
|
||||||
|
|
||||||
if(data != NULL){
|
if(data != NULL){
|
||||||
ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data;
|
ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data;
|
||||||
|
|
||||||
//cleanup the headers
|
//cleanup the headers if they exist
|
||||||
for(uint32_t x = 0; x < csvData->width; x++){
|
if(csvData->hasHeader == ARC_True){
|
||||||
ARC_String *string = csvData->headers[x];
|
for(uint32_t x = 0; x < csvData->width; x++){
|
||||||
ARC_String_Destroy(string);
|
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++){
|
for(uint32_t y = 0; y < csvData->height; y++){
|
||||||
//cleanup each element in the data
|
//cleanup each element in the data
|
||||||
for(uint32_t x = 0; x < csvData->width; x++){
|
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
|
//cleanup each row of data
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ ARC_TEST(Parser_ParserCSV_BasicTest){
|
||||||
ARC_ParserCSV_CreateAsParser(&parser, ARC_False, TEST_ParserCSV_CastTypeFn, TEST_ParserCSV_DestroyTypeFn);
|
ARC_ParserCSV_CreateAsParser(&parser, ARC_False, TEST_ParserCSV_CastTypeFn, TEST_ParserCSV_DestroyTypeFn);
|
||||||
|
|
||||||
const char *tempCString =
|
const char *tempCString =
|
||||||
"1,1,2,2"
|
"1,1,2,2\n"
|
||||||
"2,3,4,5"
|
"2,3,4,5\n"
|
||||||
"4,2,4,1"
|
"4,2,4,1\n"
|
||||||
"7,7,7,7";
|
"7,7,7,7\n";
|
||||||
|
|
||||||
ARC_String *tempString;
|
ARC_String *tempString;
|
||||||
ARC_String_CreateWithStrlen(&tempString, (char *)tempCString);
|
ARC_String_CreateWithStrlen(&tempString, (char *)tempCString);
|
||||||
|
|
@ -34,10 +34,12 @@ ARC_TEST(Parser_ParserCSV_BasicTest){
|
||||||
ARC_CHECK(arc_errno == 0);
|
ARC_CHECK(arc_errno == 0);
|
||||||
|
|
||||||
ARC_ParserCSVData *data = (ARC_ParserCSVData *)ARC_Parser_GetData(parser);
|
ARC_ParserCSVData *data = (ARC_ParserCSVData *)ARC_Parser_GetData(parser);
|
||||||
|
|
||||||
for(uint32_t y = 0; y < data->height; y++){
|
for(uint32_t y = 0; y < data->height; y++){
|
||||||
for(uint32_t x = 0; x < data->width; x++){
|
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);
|
ARC_Parser_Destroy(parser);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue