moved doxygen to doc folder and still working on csv

This commit is contained in:
herbglitch 2024-12-08 22:19:43 -07:00
parent ca6a9c118f
commit 280a70c6e8
24 changed files with 282 additions and 105 deletions

View file

@ -1,6 +1,6 @@
PROJECT_NAME = ge_lib PROJECT_NAME = ge_lib
PROJECT_NUMBER = 0.0.0 PROJECT_NUMBER = 0.0.0
OUTPUT_DIRECTORY = ./doxygen/ OUTPUT_DIRECTORY = ./doc/doxygen/
OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_ALL = YES EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES EXTRACT_PRIVATE = YES

View file

Before

Width:  |  Height:  |  Size: 218 KiB

After

Width:  |  Height:  |  Size: 218 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before After
Before After

View file

@ -59,7 +59,7 @@ typedef void (* ARC_ParserData_CreateFn)(void **data, ARC_ParserTagToken *parsed
/** /**
* @brief TODO: write this * @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 * @brief creates an ARC_Parser type

View file

@ -13,7 +13,8 @@ extern "C" {
/* /*
<line> -> <data> NEWLINE <line> | <data> | NEWLINE <line> | LAMBDA <line> -> <data> NEWLINE <line> | <data> | NEWLINE <line> | LAMBDA
<data> -> <string> COMMA <data> | <string> <data> -> <string> COMMA <data> | <string>
<string> -> COMMON_CHAR <string> | COMON_CHAR <string> -> <nonCommaChar> <string> | <nonCommaChar>
<nonCommaChar> -> 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/out] data the csv data casted into the users type
* @param[in] string an value of the csv as a string * @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 * @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 * @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 * @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 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 { typedef struct ARC_ParserCSVData {
ARC_Bool hasHeader; ARC_Bool hasHeader;
@ -47,9 +47,7 @@ typedef struct ARC_ParserCSVData {
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
void **data; void ***data;
ARC_ParserCSV_DestroyTypeFn destroyTypeFn;
} ARC_ParserCSVData; } 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); 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 #ifdef __cplusplus
} }
#endif #endif

View file

@ -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 //do the same thing as clear but this time pass in the userData as well to clean that up
if(parser->destroyDataFn != NULL){ 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); free(parser->destroyDataFn);
} }
@ -345,9 +346,9 @@ void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){
} }
void ARC_Parser_ClearData(ARC_Parser *parser){ 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){ 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 //TODO: might want to error here

View file

@ -1,7 +1,9 @@
#include "arc/std/parser/csv.h" #include "arc/std/parser/csv.h"
#include "arc/std/parser/helpers.h" #include "arc/std/parser/helpers.h"
#include "arc/std/bool.h"
#include "arc/std/parser.h" #include "arc/std/parser.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
typedef struct ARC_ParserCSVUserData { typedef struct ARC_ParserCSVUserData {
@ -11,22 +13,205 @@ typedef struct ARC_ParserCSVUserData {
} ARC_ParserCSVUserData; } ARC_ParserCSVUserData;
void ARC_ParserCSV_InitLexerRulesFn(ARC_Lexer *lexer){ 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){ 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, "<line>")){
return ARC_PARSER_CSV_LINE;
}
if(ARC_String_EqualsCStringWithStrlen(string, "<data>")){
return ARC_PARSER_CSV_DATA;
}
if(ARC_String_EqualsCStringWithStrlen(string, "<string>")){
return ARC_PARSER_CSV_STRING;
}
if(ARC_String_EqualsCStringWithStrlen(string, "<nonCommaChar>")){
return ARC_PARSER_CSV_NON_COMMA_CHAR;
}
return ~(uint32_t)0;
}
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;
}
}
}
//<line> -> <data> NEWLINE <line> | <data> | NEWLINE <line> | 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){ void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData){
if(data == NULL){ 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; return;
} }
} }
void ARC_ParserCSVData_DestroyFn(void *data, void *userData){ 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){ if(data != NULL){
ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data; ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data;
//cleanup the headers
for(uint32_t x = 0; x < csvData->width; x++){ for(uint32_t x = 0; x < csvData->width; x++){
ARC_String *string = csvData->headers[x]; ARC_String *string = csvData->headers[x];
ARC_String_Destroy(string); ARC_String_Destroy(string);
@ -34,22 +219,30 @@ void ARC_ParserCSVData_DestroyFn(void *data, void *userData){
free(csvData->headers); free(csvData->headers);
for(uint32_t y = 0; y < csvData->height; y++){ 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); free(csvData->data);
} }
if(userData != NULL){ if(clear == ARC_False){
free((ARC_ParserCSVUserData *)userData); free(csvUserData);
} }
} }
void ARC_ParserCSV_CreateAsParser(ARC_Parser **parser, ARC_Bool header, ARC_ParserCSV_CastTypeFn castTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn){ void ARC_ParserCSV_CreateAsParser(ARC_Parser **parser, ARC_Bool header, ARC_ParserCSV_CastTypeFn castTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn){
/* ~ define the language as a string ~ */ /* ~ define the language as a string ~ */
char *languageCString = char *languageCString =
"<line> -> <data> NEWLINE <line> | <data> | NEWLINE <line> | LAMBDA" "<line> -> <data> NEWLINE <line> | <data> | NEWLINE <line> | LAMBDA\n"
"<data> -> <string> COMMA <data> | <string>" "<data> -> <string> COMMA <data> | <string>\n"
"<string> -> COMMON_CHAR <string> | COMON_CHAR"; "<string> -> <nonCommaChar> <string> | <nonCommaChar>\n"
"<nonCommaChar> -> CHAR_BEFORE_COMMA | CHAR_AFTER_COMMA\n";
ARC_String *languageString; ARC_String *languageString;
ARC_String_CreateWithStrlen(&languageString, languageCString); ARC_String_CreateWithStrlen(&languageString, languageCString);

View file

@ -1,4 +1,5 @@
#include "arc/std/parser/parserlang.h" #include "arc/std/parser/parserlang.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include "arc/std/lexer.h" #include "arc/std/lexer.h"
#include "arc/std/parser.h" #include "arc/std/parser.h"
@ -39,12 +40,12 @@ void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){
ARC_String_Destroy(arrowString); ARC_String_Destroy(arrowString);
} }
void ARC_ParserLang_VectorDestroyVector(void *data){ void ARC_ParserLang_VectorDestroyVectorFn(void *data){
ARC_Vector *vector = (ARC_Vector *)data; ARC_Vector *vector = (ARC_Vector *)data;
ARC_Vector_Destroy(vector); ARC_Vector_Destroy(vector);
} }
void ARC_ParserLang_VectorDestroyUInt32(void *data){ void ARC_ParserLang_VectorDestroyUInt32Fn(void *data){
uint32_t *uint = (uint32_t *)data; uint32_t *uint = (uint32_t *)data;
free(uint); free(uint);
} }
@ -161,7 +162,7 @@ void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_Pars
uint32_t tokensOrTagsIndex = 0; uint32_t tokensOrTagsIndex = 0;
ARC_Vector *orTokensOrTags = NULL; ARC_Vector *orTokensOrTags = NULL;
ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32; ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32Fn;
switch(childTagToken->id){ switch(childTagToken->id){
case ARC_PARSERLANG_ARGUMENT: case ARC_PARSERLANG_ARGUMENT:
@ -213,12 +214,12 @@ void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagTo
/* ~ Tokens Or Tags Array ~ */ /* ~ Tokens Or Tags Array ~ */
//create a vector to store another vector of data //create a vector to store another vector of data
ARC_Vector *tokensOrTags; ARC_Vector *tokensOrTags;
ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserLang_VectorDestroyVector; ARC_Vector_DestroyDataFn destroyVectorFn = ARC_ParserLang_VectorDestroyVectorFn;
ARC_Vector_Create(&tokensOrTags, NULL, &destroyVectorFn); ARC_Vector_Create(&tokensOrTags, NULL, &destroyVectorFn);
//create vector within the tokens or tags vector to store the or rule in //create vector within the tokens or tags vector to store the or rule in
ARC_Vector *orTokensOrTags; ARC_Vector *orTokensOrTags;
ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32; ARC_Vector_DestroyDataFn destroyUint32Fn = ARC_ParserLang_VectorDestroyUInt32Fn;
ARC_Vector_Create(&orTokensOrTags, NULL, &destroyUint32Fn); ARC_Vector_Create(&orTokensOrTags, NULL, &destroyUint32Fn);
//add the first or vector to the tokensOrTags //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 //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){ if(userData != NULL){
ARC_Parser_GetStringIdFn *getStringIdFn = (ARC_Parser_GetStringIdFn *)userData; ARC_Parser_GetStringIdFn *getStringIdFn = (ARC_Parser_GetStringIdFn *)userData;
free(getStringIdFn); free(getStringIdFn);
} }
//check if there is data to free //if not clearing (full destroy) check if there is data to free
if((ARC_Vector *)data != NULL){ if(clear == ARC_False && (ARC_Vector *)data != NULL){
ARC_Vector_Destroy((ARC_Vector *)data); ARC_Vector_Destroy((ARC_Vector *)data);
} }
} }

View file

@ -1,70 +0,0 @@
int i = 32;
<defineIntLine> -> INT <variable> EQUALS <value> SEMICOLON
<variable> -> <alphaChar> <variableBody>
<variableBody> -> <alphaCharOrNum> <variableBody> | LAMBDA
<alphaCharOrNum> -> UPPER_ALPHA_CHAR | LOWER_ALPHA_CHAR | NUMBER
<value> -> NUMBER <valueBody>
<valueBody> -> NUMBER <valueBody> | 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
│ ┌─────────────────
│ │ ;
│ └─────────────────
└───────────────────

View file

@ -1,4 +1,5 @@
#include "../test.h" #include "../test.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include "arc/std/parser.h" #include "arc/std/parser.h"
#include "arc/std/parser/helpers.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); 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){ if(data == NULL){
return; return;
} }
@ -254,7 +255,7 @@ void TEST_ParserData_CreateCharFn(void **data, ARC_ParserTagToken *parsedData, v
*data = (void *)alphaChar; *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){ if(data == NULL){
return; return;
} }

View file

@ -0,0 +1,44 @@
#include "../../test.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
#include "arc/std/parser/csv.h"
#include <stdlib.h>
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);
}