Archeus 0.0.0
A C library and game engine that focuses on documentation
Loading...
Searching...
No Matches
csv.c File Reference
#include "arc/std/parser/csv.h"
#include "arc/std/parser/helpers.h"
#include "arc/std/bool.h"
#include "arc/std/parser.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

Go to the source code of this file.

Data Structures

struct  ARC_ParserCSVUserData
 

Typedefs

typedef struct ARC_ParserCSVUserData ARC_ParserCSVUserData
 

Functions

void ARC_ParserCSV_InitLexerRulesFn (ARC_Lexer *lexer)
 
uint32_t ARC_ParserCSV_GetStringIdFn (ARC_String *string)
 
void ARC_ParserCSVData_VectorDestroyVectorFn (void *data)
 
void ARC_ParserCSVData_GetDataTag (ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData)
 
void ARC_ParserCSVData_RunLineTag (ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData)
 
void ARC_ParserCSVData_CreateFn (void **data, ARC_ParserTagToken *parsedData, void *userData)
 
void ARC_ParserCSVData_DestroyFn (void *data, ARC_Bool clear, void *userData)
 
void ARC_ParserCSV_CreateAsParser (ARC_Parser **parser, ARC_Bool header, ARC_ParserCSV_CastTypeFn castTypeFn, ARC_ParserCSV_DestroyTypeFn destroyTypeFn)
 creates a parser for the Parser Lang
 

Typedef Documentation

◆ ARC_ParserCSVUserData

typedef struct ARC_ParserCSVUserData ARC_ParserCSVUserData

Function Documentation

◆ ARC_ParserCSV_CreateAsParser()

void ARC_ParserCSV_CreateAsParser ( ARC_Parser ** parser,
ARC_Bool header,
ARC_ParserCSV_CastTypeFn castTypeFn,
ARC_ParserCSV_DestroyTypeFn destroyTypeFn )

creates a parser for the Parser Lang

Note
the rules will be inited for the parser lang
the parsed data will be saved as a vector of ARC_ParserLanguageTag
Parameters
[out]parserthe parser to create

Definition at line 302 of file csv.c.

302 {
303 /* ~ define the language as a string ~ */
304 char *languageCString =
305 "<line> -> <data> NEWLINE <line> | <data> | NEWLINE <line> | LAMBDA\n"
306 "<data> -> <string> COMMA <data> | <string>\n"
307 "<string> -> <nonCommaChar> <string> | <nonCommaChar>\n"
308 "<nonCommaChar> -> CHAR_BEFORE_COMMA | CHAR_AFTER_COMMA\n";
309
310 ARC_String *languageString;
311 ARC_String_CreateWithStrlen(&languageString, languageCString);
312
313 /* ~ init the userdata ~ */
315 userdata->header = header;
316 userdata->castTypeFn = castTypeFn;
317 userdata->destroyTypeFn = destroyTypeFn;
318
319 /* ~ create the language ~ */
322 ARC_Parser_CreateFromString(parser, languageString, ARC_ParserCSV_InitLexerRulesFn, ARC_ParserCSV_GetStringIdFn, &createCharFn, &destroyCharFn, userdata);
323
324 //cleanup
325 ARC_String_Destroy(languageString);
326}
void ARC_ParserCSV_InitLexerRulesFn(ARC_Lexer *lexer)
Definition csv.c:15
uint32_t ARC_ParserCSV_GetStringIdFn(ARC_String *string)
Definition csv.c:24
void ARC_ParserCSVData_CreateFn(void **data, ARC_ParserTagToken *parsedData, void *userData)
Definition csv.c:157
void ARC_ParserCSVData_DestroyFn(void *data, ARC_Bool clear, void *userData)
Definition csv.c:263
void ARC_Parser_CreateFromString(ARC_Parser **parser, ARC_String *languageString, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_Parser_GetStringIdFn getStringIdFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn, void *userData)
creates an ARC_Parser type from a string
Definition parser.c:105
void(* ARC_ParserData_CreateFn)(void **data, ARC_ParserTagToken *parsedData, void *userData)
TODO: write this.
Definition parser.h:57
void(* ARC_ParserData_DestroyFn)(void *data, ARC_Bool clear, void *userData)
TODO: write this.
Definition parser.h:62
void ARC_String_CreateWithStrlen(ARC_String **string, char *data)
creates ARC_String type with strinlen
Definition string.c:32
void ARC_String_Destroy(ARC_String *string)
destroys ARC_String type
Definition string.c:52
ARC_ParserCSV_CastTypeFn castTypeFn
Definition csv.c:11
ARC_Bool header
Definition csv.c:10
ARC_ParserCSV_DestroyTypeFn destroyTypeFn
Definition csv.c:12
substring position within a string
Definition string.h:14

References ARC_Parser_CreateFromString(), ARC_ParserCSV_GetStringIdFn(), ARC_ParserCSV_InitLexerRulesFn(), ARC_ParserCSVData_CreateFn(), ARC_ParserCSVData_DestroyFn(), ARC_String_CreateWithStrlen(), ARC_String_Destroy(), ARC_ParserCSVUserData::castTypeFn, ARC_ParserCSVUserData::destroyTypeFn, and ARC_ParserCSVUserData::header.

◆ ARC_ParserCSV_GetStringIdFn()

uint32_t ARC_ParserCSV_GetStringIdFn ( ARC_String * string)

Definition at line 24 of file csv.c.

24 {
25 if(ARC_String_EqualsCStringWithStrlen(string, "LAMBDA")){
27 }
28
29 if(ARC_String_EqualsCStringWithStrlen(string, "COMMA")){
31 }
32
33 if(ARC_String_EqualsCStringWithStrlen(string, "NEWLINE")){
35 }
36
37 if(ARC_String_EqualsCStringWithStrlen(string, "CHAR_BEFORE_COMMA")){
39 }
40
41 if(ARC_String_EqualsCStringWithStrlen(string, "CHAR_AFTER_COMMA")){
43 }
44
45 if(ARC_String_EqualsCStringWithStrlen(string, "<line>")){
47 }
48
49 if(ARC_String_EqualsCStringWithStrlen(string, "<data>")){
51 }
52
53 if(ARC_String_EqualsCStringWithStrlen(string, "<string>")){
55 }
56
57 if(ARC_String_EqualsCStringWithStrlen(string, "<nonCommaChar>")){
59 }
60
61 return ~(uint32_t)0;
62}
#define ARC_PARSER_CSV_CHAR_AFTER_COMMA
Definition csv.h:66
#define ARC_PARSER_CSV_CHAR_BEFORE_COMMA
Definition csv.h:65
#define ARC_PARSER_CSV_CHAR_COMMA
Definition csv.h:63
#define ARC_PARSER_CSV_DATA
Definition csv.h:68
#define ARC_PARSER_CSV_STRING
Definition csv.h:69
#define ARC_PARSER_CSV_LINE
Definition csv.h:67
#define ARC_PARSER_CSV_CHAR_NEWLINE
Definition csv.h:64
#define ARC_PARSER_CSV_NON_COMMA_CHAR
Definition csv.h:70
#define ARC_PARSER_TAG_LAMBDA
basic tag for letting the parser know it is ok to end
Definition parser.h:150
ARC_Bool ARC_String_EqualsCStringWithStrlen(ARC_String *string, const char *cstring)
check if ARC_String and cstring match
Definition string.c:171

References ARC_PARSER_CSV_CHAR_AFTER_COMMA, ARC_PARSER_CSV_CHAR_BEFORE_COMMA, ARC_PARSER_CSV_CHAR_COMMA, ARC_PARSER_CSV_CHAR_NEWLINE, ARC_PARSER_CSV_DATA, ARC_PARSER_CSV_LINE, ARC_PARSER_CSV_NON_COMMA_CHAR, ARC_PARSER_CSV_STRING, ARC_PARSER_TAG_LAMBDA, and ARC_String_EqualsCStringWithStrlen().

Referenced by ARC_ParserCSV_CreateAsParser().

◆ ARC_ParserCSV_InitLexerRulesFn()

void ARC_ParserCSV_InitLexerRulesFn ( ARC_Lexer * lexer)

Definition at line 15 of file csv.c.

15 {
18
19 //NOTE: used an ascii table to get these values
22}
void ARC_Lexer_RegisterTokenRule(ARC_Lexer *lexer, ARC_LexerTokenRule tokenRule)
adds a token rule to a lexer
Definition lexer.c:79
ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharRule(uint32_t id, char character)
creates a ARC_LexerTokenRule with a given id and character
Definition lexer.c:378
ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(uint32_t id, char start, char end)
creates a ARC_LexerTokenRule with a given id and character range
Definition lexer.c:400

References ARC_Lexer_RegisterTokenRule(), ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(), ARC_LexerTokenRule_CreateAndReturnMatchCharRule(), ARC_PARSER_CSV_CHAR_AFTER_COMMA, ARC_PARSER_CSV_CHAR_BEFORE_COMMA, ARC_PARSER_CSV_CHAR_COMMA, and ARC_PARSER_CSV_CHAR_NEWLINE.

Referenced by ARC_ParserCSV_CreateAsParser().

◆ ARC_ParserCSVData_CreateFn()

void ARC_ParserCSVData_CreateFn ( void ** data,
ARC_ParserTagToken * parsedData,
void * userData )

Definition at line 157 of file csv.c.

157 {
158 *data = NULL;
159 if(data == NULL || userData == NULL){
160 //TODO: error here?
161 *data = NULL;
162 return;
163 }
164
165 //cast the csv data back to its original type
166 ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData;
167
168 //crate a vector for the data to be stored in before being copied to a 2d array
169 ARC_Vector *dataVector;
171 ARC_Vector_Create(&dataVector, NULL, &destroyVectorFn);
172
173 //create the first row vector, does not need a destroy function as its contents will be moved
174 ARC_Vector *dataRowVector;
175 ARC_Vector_Create(&dataRowVector, NULL, NULL);
176
177 //add the row to the dataVector
178 ARC_Vector_Add(dataVector, (void *)dataRowVector);
179
180 //recursively add data from the parsedData to the data vector
181 ARC_ParserCSVData_RunLineTag(dataVector, parsedData, csvUserData);
182
183 //get the first line to check if it has any values
184 dataRowVector = ARC_Vector_Get(dataVector, 0);
185 if(ARC_Vector_GetSize(dataRowVector) == 0){
186 //TODO: iterate and clear the vector
187 ARC_Vector_Destroy(dataVector);
188 return;
189 }
190
191 //create the data that will be saved
192 ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)malloc(sizeof(ARC_ParserCSVData));
193 csvData->hasHeader = csvUserData->header;
194 csvData->headers = NULL;
195 csvData->height = 0;
196 csvData->width = ARC_Vector_GetSize(dataRowVector);
197 csvData->data = NULL;
198
199 //create the starting index (to offset the header if it exists)
200 uint32_t heightStartIndex = 0;
201
202 //store the headers if they exist
203 if(csvData->hasHeader == ARC_True){
204 heightStartIndex++;
205
206 //copy the headers
207 csvData->headers = (ARC_String **)malloc(sizeof(ARC_String *) * csvData->width);
208 for(uint32_t headerIndex = 0; headerIndex < csvData->width; headerIndex++){
209 csvData->headers[headerIndex] = (ARC_String *)ARC_Vector_Get(dataRowVector, headerIndex);
210 }
211 }
212
213 //check that all the rows are the same size
214 for(uint32_t rowIndex = heightStartIndex; rowIndex < ARC_Vector_GetSize(dataVector); rowIndex++){
215 ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex);
216
217 //skip an empty line (this should only be the case for the last line)
218 uint32_t currentRowVectorSize = ARC_Vector_GetSize(currentRowVector);
219 if(currentRowVectorSize == 0){
220 continue;
221 }
222
223 //a row was found so update the height
224 csvData->height++;
225
226 //TODO: probs want to error
227 //cleanup and exit if they don't match
228 if(csvData->width != currentRowVectorSize){
229 //TODO: iterate and clear the vector
230 ARC_Vector_Destroy(dataVector);
231 return;
232 }
233 }
234
235 //init location to copy data to
236 csvData->data = (void ***)malloc(sizeof(void **) * csvData->height);
237
238 //copy the data
239 uint32_t rowIndex = 0;
240 for(uint32_t y = 0; y < csvData->height; y++, rowIndex++){
241 ARC_Vector *currentRowVector = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex + heightStartIndex);
242
243 //skip an empty line (should only be the case for the last line)
244 uint32_t currentRowVectorSize = ARC_Vector_GetSize(currentRowVector);
245 if(currentRowVectorSize == 0){
246 y--;
247 continue;
248 }
249
250 //create the current row
251 csvData->data[y] = (void **)malloc(sizeof(void *) * csvData->width);
252
253 for(uint32_t x = 0; x < csvData->width; x++){
254 csvData->data[y][x] = ARC_Vector_Get(currentRowVector, x);
255 }
256 }
257
258 ARC_Vector_Destroy(dataVector);
259
260 *data = (void *)csvData;
261}
#define ARC_True
Definition bool.h:11
void ARC_ParserCSVData_VectorDestroyVectorFn(void *data)
Definition csv.c:64
void ARC_ParserCSVData_RunLineTag(ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData)
Definition csv.c:118
defines a csv data type, data is set by the callback passed in when createing a parserCSV as parser
Definition csv.h:44
uint32_t height
Definition csv.h:49
uint32_t width
Definition csv.h:48
void *** data
Definition csv.h:50
ARC_String ** headers
Definition csv.h:46
ARC_Bool hasHeader
Definition csv.h:45
void(* ARC_Vector_DestroyDataFn)(void *data)
a callback that cleans up memory when it is removed from the vector
Definition vector.h:31
uint32_t ARC_Vector_GetSize(ARC_Vector *vector)
gets the current size of an ARC_Vector as an unsigned 32 bit integer
Definition vector.c:146
void * ARC_Vector_Get(ARC_Vector *vector, uint32_t index)
gets an item from an ARC_Vector at a position index
Definition vector.c:150
void ARC_Vector_Add(ARC_Vector *vector, void *data)
adds an item to an ARC_Vector
Definition vector.c:67
void ARC_Vector_Destroy(ARC_Vector *vector)
destroys an ARC_Vector
Definition vector.c:51
void ARC_Vector_Create(ARC_Vector **vector, ARC_Vector_CompareDataFn *compareDataFn, ARC_Vector_DestroyDataFn *destroyDataFn)
creates an ARC_Vector which is an "expandable" array
Definition vector.c:28

References ARC_ParserCSVData_RunLineTag(), ARC_ParserCSVData_VectorDestroyVectorFn(), ARC_True, ARC_Vector_Add(), ARC_Vector_Create(), ARC_Vector_Destroy(), ARC_Vector_Get(), ARC_Vector_GetSize(), ARC_ParserCSVData::data, ARC_ParserCSVData::hasHeader, ARC_ParserCSVUserData::header, ARC_ParserCSVData::headers, ARC_ParserCSVData::height, and ARC_ParserCSVData::width.

Referenced by ARC_ParserCSV_CreateAsParser().

◆ ARC_ParserCSVData_DestroyFn()

void ARC_ParserCSVData_DestroyFn ( void * data,
ARC_Bool clear,
void * userData )

Definition at line 263 of file csv.c.

263 {
264 if(userData == NULL){
265 return;
266 }
267
268 ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData;
269
270 if(data != NULL){
271 ARC_ParserCSVData *csvData = (ARC_ParserCSVData *)data;
272
273 //cleanup the headers if they exist
274 if(csvData->hasHeader == ARC_True){
275 for(uint32_t x = 0; x < csvData->width; x++){
276 ARC_String *string = csvData->headers[x];
277 ARC_String_Destroy(string);
278 }
279 free(csvData->headers);
280 }
281
282 for(uint32_t y = 0; y < csvData->height; y++){
283 //cleanup each element in the data
284 for(uint32_t x = 0; x < csvData->width; x++){
285 csvUserData->destroyTypeFn(csvData->data[y][x]);
286 }
287
288 //cleanup each row of data
289 free(csvData->data[y]);
290 }
291
292 //cleanup the data
293 free(csvData->data);
294 free(csvData);
295 }
296
297 if(clear == ARC_False){
298 free(csvUserData);
299 }
300}
#define ARC_False
Definition bool.h:12

References ARC_False, ARC_String_Destroy(), ARC_True, ARC_ParserCSVData::data, ARC_ParserCSVUserData::destroyTypeFn, ARC_ParserCSVData::hasHeader, ARC_ParserCSVData::headers, ARC_ParserCSVData::height, and ARC_ParserCSVData::width.

Referenced by ARC_ParserCSV_CreateAsParser().

◆ ARC_ParserCSVData_GetDataTag()

void ARC_ParserCSVData_GetDataTag ( ARC_Vector * dataVector,
ARC_ParserTagToken * tagToken,
ARC_ParserCSVUserData * userData )

Definition at line 69 of file csv.c.

69 {
70 //cast the csv data back to its original type
71 ARC_ParserCSVUserData *csvUserData = (ARC_ParserCSVUserData *)userData;
72
73 //loop through the tags either recursing to next body or adding data to vector
74 for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
75 ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
76
77 ARC_String *stringData = NULL;
78 ARC_Vector *row = NULL;
79 uint32_t rowIndex = 0;
80
81 switch(childTagToken->id){
82 //recuse to run the next line
84 //get the string of the data
85 ARC_String_Create(&stringData, NULL, 0);
86 ARC_ParserData_HelperRecurseStringAdd(&stringData, childTagToken);
87
88 //move data string and cleanup
89 void *data = (void *)stringData;
90
91 //get the last row vector
92 rowIndex = ARC_Vector_GetSize(dataVector) - 1;
93 row = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex);
94
95 //only call the userData cast type callback if it is not a header
96 if(rowIndex != 0 || csvUserData->header == ARC_False){
97 data = NULL;
98 userData->castTypeFn(&data, stringData);
99 ARC_String_Destroy(stringData);
100 }
101
102 //add the data to the row vector
103 ARC_Vector_Add(row, data);
104 continue;
105
107 ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData);
108 continue;
109
110 default:
111 //this should only be the case for the comma
112 continue;
113 }
114 }
115}
void ARC_ParserCSVData_GetDataTag(ARC_Vector *dataVector, ARC_ParserTagToken *tagToken, ARC_ParserCSVUserData *userData)
Definition csv.c:69
void ARC_ParserData_HelperRecurseStringAdd(ARC_String **data, ARC_ParserTagToken *tagToken)
recurses through a tag token adding token strings to a main string
Definition helpers.c:4
void ARC_String_Create(ARC_String **string, char *data, uint64_t length)
creates ARC_String type
Definition string.c:9
a parser type used inside of the parser data create function
Definition parser.h:35
uint32_t id
Definition parser.h:36
ARC_Vector * tagTokens
Definition parser.h:39

References ARC_False, ARC_PARSER_CSV_DATA, ARC_PARSER_CSV_STRING, ARC_ParserCSVData_GetDataTag(), ARC_ParserData_HelperRecurseStringAdd(), ARC_String_Create(), ARC_String_Destroy(), ARC_Vector_Add(), ARC_Vector_Get(), ARC_Vector_GetSize(), ARC_ParserCSVUserData::castTypeFn, ARC_ParserCSVUserData::header, ARC_ParserTagToken::id, and ARC_ParserTagToken::tagTokens.

Referenced by ARC_ParserCSVData_GetDataTag(), and ARC_ParserCSVData_RunLineTag().

◆ ARC_ParserCSVData_RunLineTag()

void ARC_ParserCSVData_RunLineTag ( ARC_Vector * dataVector,
ARC_ParserTagToken * tagToken,
ARC_ParserCSVUserData * userData )

Definition at line 118 of file csv.c.

118 {
119 //loop through the tags either going to the next line or the next body
120 for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
121 ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
122
123 ARC_Vector *row = NULL;
124 uint32_t rowIndex = 0;
125
126 switch(childTagToken->id){
127 //recuse to run the next line
129 ARC_ParserCSVData_RunLineTag(dataVector, childTagToken, userData);
130 continue;
131
132 //get the row data
134 ARC_ParserCSVData_GetDataTag(dataVector, childTagToken, userData);
135 continue;
136
137 //add a new row for each new line
139 //check if current is not empty (no need to create another empty row)
140 rowIndex = ARC_Vector_GetSize(dataVector) - 1;
141 row = (ARC_Vector *)ARC_Vector_Get(dataVector, rowIndex);
142 if(ARC_Vector_GetSize(row) == 0){
143 continue;
144 }
145
146 //create and add a new row
147 ARC_Vector_Create(&row, NULL, NULL);
148 ARC_Vector_Add(dataVector, (void *)row);
149 continue;
150
151 default:
152 continue;
153 }
154 }
155}

References ARC_PARSER_CSV_CHAR_NEWLINE, ARC_PARSER_CSV_DATA, ARC_PARSER_CSV_LINE, ARC_ParserCSVData_GetDataTag(), ARC_ParserCSVData_RunLineTag(), ARC_Vector_Add(), ARC_Vector_Create(), ARC_Vector_Get(), ARC_Vector_GetSize(), ARC_ParserTagToken::id, and ARC_ParserTagToken::tagTokens.

Referenced by ARC_ParserCSVData_CreateFn(), and ARC_ParserCSVData_RunLineTag().

◆ ARC_ParserCSVData_VectorDestroyVectorFn()

void ARC_ParserCSVData_VectorDestroyVectorFn ( void * data)

Definition at line 64 of file csv.c.

64 {
65 ARC_Vector *vector = (ARC_Vector *)data;
66 ARC_Vector_Destroy(vector);
67}

References ARC_Vector_Destroy().

Referenced by ARC_ParserCSVData_CreateFn().