GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tmp_project/FileParser/src/parser_toml.cpp Lines: 117 125 93.6 %
Date: 2024-12-09 15:41:43 Branches: 280 343 81.6 %

Line Branch Exec Source
1
/***************************************
2
	Auteur : Pierre Aubert
3
	Mail : pierre.aubert@lapp.in2p3.fr
4
	Licence : CeCILL-C
5
****************************************/
6
7
8
#include "parser_toml.h"
9
10
///@brief Data used to parse a toml file
11
struct PTomlParserData{
12
	///True to continue the parsing, false to stop
13
	bool isRun;
14
};
15
16
///Default value of PYmlParserData
17
/**	@return default PYmlParserData
18
*/
19
28
PTomlParserData default_PTomlParserData(){
20
	PTomlParserData data;
21
28
	data.isRun = true;
22
28
	return data;
23
}
24
25
bool parse_toml_var(DicoValue & dico, PFileParser & parser, PTomlParserData & data);
26
bool parse_toml_all(DicoValue & parent, PFileParser & parser, PTomlParserData & data);
27
28
///Stop the file parsing
29
/**	@param[out] data : parsing data
30
*/
31
11
void parse_toml_stopParsing(PTomlParserData & data){
32
11
	data.isRun = false;
33
11
}
34
35
///Say if the file parsing is enable
36
/**	@param data : parsing data
37
*/
38
494
bool parse_toml_isParse(const PTomlParserData & data){
39
494
	return data.isRun;
40
}
41
42
///Parse a toml var name
43
/**	@param[out] varName : variable name
44
 * 	@param parser : parser to be used
45
 * 	@return true on success, false otherwise
46
*/
47
256
bool parse_toml_varName(std::string & varName, PFileParser & parser){
48
256
	varName = parser.getStrComposedOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
49
256
	return varName != "";
50
}
51
52
///Parse a toml var name
53
/**	@param[out] var : Value to be updated
54
 * 	@param[out] parser : parser to be used
55
 * 	@param[out] data : extra parser data to be used
56
 * 	@return true on success, false otherwise
57
*/
58
254
bool parse_toml_varValue(DicoValue & var, PFileParser & parser, PTomlParserData & data){
59

254
	if(parser.isMatch("[")){	//The value is a list
60





41
		while(!parser.isEndOfFile() && !parser.isMatch("]") && parse_toml_isParse(data)){	//Let's parse the values of the Variable
61
25
			DicoValue subValue;
62
25
			if(parse_toml_varValue(subValue, parser, data)){
63
24
				var.getVecChild().push_back(subValue);
64
65






24
				if(!parser.isMatch(",") && !parser.isMatchRewind("]")){	//We expect one element or a comma to add more
66

1
					std::cerr << "parse_toml_varValue : expect ',' or ']' forunclosed list of values at " << parser.getLocation() << std::endl;
67
1
					parse_toml_stopParsing(data);
68
1
					return false;
69
				}
70
			}else{
71

1
				if(!parser.isMatch("]")){
72

1
					std::cerr << "parse_toml_varBase : missing ']' token to close empty list of value at " << parser.getLocation() << std::endl;
73
1
					parse_toml_stopParsing(data);
74
1
					return false;
75
				}
76
			}
77
		}
78
	}else{
79
236
		std::string strValue("");
80

236
		if(parser.isMatch("\"\"\"")){
81
1
			var.setValue(parser.getUntilKeyWithoutPatern("\"\"\""));
82
235
		}else if(parse_yml_string(strValue, parser)){
83
186
			var.setValue(strValue);
84

49
		}else if(parser.isMatch("true")){
85
1
			var.setValue("true");
86

48
		}else if(parser.isMatch("false")){
87
1
			var.setValue("false");
88
		}else{
89
94
			std::string valueNumber(parser.getStrComposedOf("0123456789.-+e"));
90
47
			if(valueNumber != ""){
91
43
				var.setValue(valueNumber);
92
			}else{
93

4
				std::cerr << "parse_toml_varValue : missing value of variable '"<<var.getKey()<<"' at " << parser.getLocation() << std::endl;
94
4
				parse_toml_stopParsing(data);
95
4
				return false;
96
			}
97
		}
98
	}
99
248
	return true;
100
}
101
102
///Parse a compact dico definition
103
/**	@param[out] parent : parent of parsed dico
104
 * 	@param[out] parser : parser to be used
105
 * 	@param[out] data : extra parser data to be used
106
 * 	@return true on success, false otherwise
107
*/
108
232
bool parse_tomlCompactDico(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
109

232
	if(!parser.isMatch("{")){return false;}
110





9
	while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatch("}")){	//Let's parse the vatiables of the Dico
111

6
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
112
5
		else if(parse_toml_var(parent, parser, data)){
113






3
			if(!parser.isMatch(",") && !parser.isMatchRewind("}")){	//We expect one element or a comma to add more
114
				std::cerr << "parse_tomlCompactDico : expect ',' or '}' for unclosed dictionary of values at " << parser.getLocation() << std::endl;
115
				parse_toml_stopParsing(data);
116
				return false;
117
			}
118
		}else{
119

2
			if(!parser.isMatch("}")){
120
2
				std::cerr << "parse_tomlCompactDico : missing '}' token to close empty dictionary of value at " << parser.getLocation() << std::endl;
121
2
				parse_toml_stopParsing(data);
122
2
				return false;
123
			}
124
		}
125
	}
126
3
	return true;
127
}
128
129
///Parse a toml var name
130
/**	@param[out] var : variable DicoValue to be used
131
 * 	@param[out] parser : parser to be used
132
 * 	@param[out] data : extra parser data to be used
133
 * 	@return true on success, false otherwise
134
*/
135
256
bool parse_toml_varBase(DicoValue & var, PFileParser & parser, PTomlParserData & data){
136
512
	std::string varName("");
137
256
	if(!parse_toml_varName(varName, parser)){return false;}
138

234
	if(!parser.isMatch("=")){
139

2
		std::cerr << "parse_toml_varBase : missing '=' token to define value of variable '"<<varName<<"' at " << parser.getLocation() << std::endl;
140
2
		parse_toml_stopParsing(data);
141
2
		return false;
142
	}
143
232
	var.setKey(varName);
144
232
	bool b(true);
145
232
	if(parse_tomlCompactDico(var, parser, data)){}
146
229
	else if(parse_toml_varValue(var, parser, data)){}
147
5
	else{b = false;}
148
232
	return b;
149
}
150
151
///Parse a toml var name
152
/**	@param[out] dico : DicoValue to be used
153
 * 	@param[out] parser : parser to be used
154
 * 	@param[out] data : extra parser data to be used
155
 * 	@return true on success, false otherwise
156
*/
157
256
bool parse_toml_var(DicoValue & dico, PFileParser & parser, PTomlParserData & data){
158
512
	DicoValue var;
159
256
	if(!parse_toml_varBase(var, parser, data)){return false;}
160

227
	dico.getMapChild()[var.getKey()] = var;
161
227
	return true;
162
}
163
164
///Parse a toml var name
165
/**	@param[out] dico : DicoValue to be used
166
 * 	@param[out] parser : parser to be used
167
 * 	@param[out] data : extra parser data to be used
168
 * 	@return true on success, false otherwise
169
*/
170
bool parse_toml_varTable(DicoValue & dico, PFileParser & parser, PTomlParserData & data){
171
	DicoValue var;
172
	if(!parse_toml_varBase(var, parser, data)){return false;}
173
	dico.getVecChild().push_back(var);
174
	return true;
175
}
176
177
///Get the parent dictionary by respect to the vecDicoName
178
/**	@param parent : main DicoValue
179
 * 	@param vecDicoName : name of the parent DicoValue of the following attributes
180
 * 	@return pointer to the parent DicoValue of the following attributes
181
*/
182
53
DicoValue * parse_get_parent_dico(DicoValue & parent, const std::vector<std::string> & vecDicoName){
183
53
	DicoValue * output = &parent;
184
107
	for(std::vector<std::string>::const_iterator it(vecDicoName.begin()); it != vecDicoName.end(); ++it){
185
54
		output = &(output->getMapChild()[*it]);
186
54
		output->setKey(*it);
187
	}
188
53
	return output;
189
}
190
191
///Parse a dico definition
192
/**	@param[out] parent : parent VecValue
193
 * 	@param[out] parser : PFileParser to be used
194
 * 	@param[out] data : extra parser data to be used
195
 * 	@return true on success, false otherwise
196
*/
197
31
bool parse_toml_dico_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
198

31
	if(!parser.isMatch("[")){return false;}
199
90
	std::string dicoName(parser.getUntilKeyWithoutPatern("]"));
200
30
	std::vector<std::string> vecDicoName = cutStringVector(dicoName, '.');
201
30
	DicoValue * dicoDef = parse_get_parent_dico(parent, vecDicoName);
202
203
// 	dicoDef.setKey(dicoName);
204





133
	while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){	//Let's parse the vatiables of the Dico
205

103
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
206
81
		else if(parse_toml_var(*dicoDef, parser, data)){
207
// 			parent.getMapChild()[dicoName] = *dicoDef;
208
		}
209
// 		else{
210
// 			std::cerr << "parse_toml_dico_def : error at " << parser.getLocation() << std::endl;
211
// 			std::cerr << "\tcannot parse [definition]" << std::endl;
212
// 			parse_toml_stopParsing(data);
213
// 			return true;
214
// 		}
215
	}
216
30
	return true;
217
}
218
219
///Parse a dico definition
220
/**	@param[out] parent : parent VecValue
221
 * 	@param[out] parser : PFileParser to be used
222
 * 	@param[out] data : extra parser data to be used
223
 * 	@return true on success, false otherwise
224
*/
225
54
bool parse_toml_table_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
226

54
	if(!parser.isMatch("[[")){return false;}
227
69
	std::string dicoName(parser.getUntilKeyWithoutPatern("]]"));
228
46
	std::vector<std::string> vecDicoName = cutStringVector(dicoName, '.');
229
23
	DicoValue * dicoDef = parse_get_parent_dico(parent, vecDicoName);
230
// 	DicoValue dicoDef;
231
// 	dicoDef.setKey(dicoName);
232
23
	DicoValue table;
233





295
	while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){	//Let's parse the vatiables of the Dico
234

272
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
235
170
		else if(parse_toml_var(table, parser, data)){
236
// 			parent.getMapChild()[dicoName] = *dicoDef;
237
		}
238
// 		else{
239
// 			std::cerr << "parse_toml_table_def : error at " << parser.getLocation() << std::endl;
240
// 			std::cerr << "\tcannot parse [[table_definition]]" << std::endl;
241
// 			parse_toml_stopParsing(data);
242
// 			return true;
243
// 		}
244
	}
245
23
	dicoDef->getVecChild().push_back(table);
246
247
23
	return true;
248
}
249
250
///Parse a yml file and update the given VecValue
251
/**	@param[out] dico : dictionary of values
252
 * 	@param parser : PFileParser to be used
253
 * 	@return true on success, false otherwise
254
*/
255
28
bool parser_toml_fileParser(DicoValue & dico, PFileParser & parser){
256
28
	PTomlParserData data(default_PTomlParserData());
257
28
	parser.getStrComposedOf(" \t\n");		//Skip all blank characters
258


84
	while(!parser.isEndOfFile() && parse_toml_isParse(data)){
259

56
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
260
54
		else if(parse_toml_table_def(dico, parser, data)){}
261
31
		else if(parse_toml_dico_def(dico, parser, data)){}
262
		else{
263

1
			std::cerr << "parser_toml_fileParser : error at " << parser.getLocation() << std::endl;
264

1
			std::cerr << "\tunexpected token '"<<parser.getNextToken()<<"'" << std::endl;
265
1
			parse_toml_stopParsing(data);
266
		}
267
	}
268
28
	return data.isRun;
269
}
270
271
///Parse a toml file and update the given DicoValue
272
/**	@param[out] dico : dictionary of values
273
 * 	@param fileName : name of the file to be parsed
274
 * 	@return true on success, false otherwise
275
*/
276
29
bool parser_toml(DicoValue & dico, const std::string & fileName){
277
58
	PFileParser parser;
278
29
	parser.setWhiteSpace(" \n\t");
279
29
	parser.setSeparator(":-'\",{}[]>|");
280
29
	parser.setEscapeChar('\\');
281
29
	if(!parser.open(fileName)){
282

1
		std::cerr << "parser_toml : cannot open file '"<<fileName<<"'" << std::endl;
283
1
		return false;
284
	}
285
28
	bool b(parser_toml_fileParser(dico, parser));
286
28
	return b;
287
}
288