GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tmp_project/FileParser/src/parser_toml.cpp Lines: 117 125 93.6 %
Date: 2025-07-15 03:08:35 Branches: 277 345 80.3 %

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
17
PTomlParserData default_PTomlParserData(){
20
	PTomlParserData data;
21
17
	data.isRun = true;
22
17
	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
90
bool parse_toml_isParse(const PTomlParserData & data){
39
90
	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
45
bool parse_toml_varName(std::string & varName, PFileParser & parser){
48
45
	varName = parser.getStrComposedOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
49
45
	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
43
bool parse_toml_varValue(DicoValue & var, PFileParser & parser, PTomlParserData & data){
59

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





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






13
				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
36
		std::string strValue("");
80

36
		if(parser.isMatch("\"\"\"")){
81
1
			var.setValue(parser.getUntilKeyWithoutPatern("\"\"\""));
82
35
		}else if(parse_yml_string(strValue, parser)){
83
14
			var.setValue(strValue);
84

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

20
		}else if(parser.isMatch("false")){
87
1
			var.setValue("false");
88
		}else{
89
38
			std::string valueNumber(parser.getStrComposedOf("0123456789.-+e"));
90
19
			if(valueNumber != ""){
91
15
				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
37
	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
32
bool parse_tomlCompactDico(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
109

32
	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
45
bool parse_toml_varBase(DicoValue & var, PFileParser & parser, PTomlParserData & data){
136
90
	std::string varName("");
137
45
	if(!parse_toml_varName(varName, parser)){return false;}
138

34
	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
32
	var.setKey(varName);
144
32
	bool b(true);
145
32
	if(parse_tomlCompactDico(var, parser, data)){}
146
29
	else if(parse_toml_varValue(var, parser, data)){}
147
5
	else{b = false;}
148
32
	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
45
bool parse_toml_var(DicoValue & dico, PFileParser & parser, PTomlParserData & data){
158
90
	DicoValue var;
159
45
	if(!parse_toml_varBase(var, parser, data)){return false;}
160

27
	dico.getMapChild()[var.getKey()] = var;
161
27
	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
18
DicoValue * parse_get_parent_dico(DicoValue & parent, const std::vector<std::string> & vecDicoName){
183
18
	DicoValue * output = &parent;
184
37
	for(std::vector<std::string>::const_iterator it(vecDicoName.begin()); it != vecDicoName.end(); ++it){
185
19
		output = &(output->getMapChild()[*it]);
186
19
		output->setKey(*it);
187
	}
188
18
	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
17
bool parse_toml_dico_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
198

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





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

36
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
206
35
		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
16
	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
19
bool parse_toml_table_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
226

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





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


5
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
235
5
		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
2
	dicoDef->getVecChild().push_back(table);
246
247
2
	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
17
bool parser_toml_fileParser(DicoValue & dico, PFileParser & parser){
256
17
	PTomlParserData data(default_PTomlParserData());
257
17
	parser.getStrComposedOf(" \t\n");		//Skip all blank characters
258


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

21
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
260
19
		else if(parse_toml_table_def(dico, parser, data)){}
261
17
		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
17
	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
18
bool parser_toml(DicoValue & dico, const std::string & fileName){
277
36
	PFileParser parser;
278
18
	parser.setWhiteSpace(" \n\t");
279
18
	parser.setSeparator(":-'\",{}[]>|");
280
18
	parser.setEscapeChar('\\');
281
18
	if(!parser.open(fileName)){
282

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