GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tmp_project/FileParser/src/parser_toml.cpp Lines: 114 122 93.4 %
Date: 2023-10-11 10:52:07 Branches: 267 330 80.9 %

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

253
	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
235
		std::string strValue("");
80
235
		if(parse_yml_string(strValue, parser)){
81
186
			var.setValue(strValue);
82

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

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

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

231
	if(!parser.isMatch("{")){return false;}
108





8
	while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatch("}")){	//Let's parse the vatiables of the Dico
109
5
		if(parse_toml_var(parent, parser, data)){
110






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

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

233
	if(!parser.isMatch("=")){
136

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

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

30
	if(!parser.isMatch("[")){return false;}
196
87
	std::string dicoName(parser.getUntilKeyWithoutPatern("]"));
197
29
	std::vector<std::string> vecDicoName = cutStringVector(dicoName, '.');
198
29
	DicoValue * dicoDef = parse_get_parent_dico(parent, vecDicoName);
199
200
// 	dicoDef.setKey(dicoName);
201





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

101
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
203
79
		else if(parse_toml_var(*dicoDef, parser, data)){
204
// 			parent.getMapChild()[dicoName] = *dicoDef;
205
		}
206
	}
207
208
29
	return true;
209
}
210
211
///Parse a dico definition
212
/**	@param[out] parent : parent VecValue
213
 * 	@param[out] parser : PFileParser to be used
214
 * 	@param[out] data : extra parser data to be used
215
 * 	@return true on success, false otherwise
216
*/
217
53
bool parse_toml_table_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
218

53
	if(!parser.isMatch("[[")){return false;}
219
69
	std::string dicoName(parser.getUntilKeyWithoutPatern("]]"));
220
46
	std::vector<std::string> vecDicoName = cutStringVector(dicoName, '.');
221
23
	DicoValue * dicoDef = parse_get_parent_dico(parent, vecDicoName);
222
// 	DicoValue dicoDef;
223
// 	dicoDef.setKey(dicoName);
224
23
	DicoValue table;
225





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

272
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
227
170
		else if(parse_toml_var(table, parser, data)){
228
// 			parent.getMapChild()[dicoName] = *dicoDef;
229
		}
230
	}
231
23
	dicoDef->getVecChild().push_back(table);
232
233
23
	return true;
234
}
235
236
///Parse a yml file and update the given VecValue
237
/**	@param[out] dico : dictionary of values
238
 * 	@param parser : PFileParser to be used
239
 * 	@return true on success, false otherwise
240
*/
241
27
bool parser_toml_fileParser(DicoValue & dico, PFileParser & parser){
242
27
	PTomlParserData data(default_PTomlParserData());
243
27
	parser.getStrComposedOf(" \t\n");		//Skip all blank characters
244


81
	while(!parser.isEndOfFile() && parse_toml_isParse(data)){
245

54
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
246
53
		else if(parse_toml_table_def(dico, parser, data)){}
247
30
		else if(parse_toml_dico_def(dico, parser, data)){}
248
		else{
249

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

1
			std::cerr << "\tunexpected token '"<<parser.getNextToken()<<"'" << std::endl;
251
1
			parse_toml_stopParsing(data);
252
		}
253
	}
254
27
	return data.isRun;
255
}
256
257
///Parse a toml file and update the given DicoValue
258
/**	@param[out] dico : dictionary of values
259
 * 	@param fileName : name of the file to be parsed
260
 * 	@return true on success, false otherwise
261
*/
262
28
bool parser_toml(DicoValue & dico, const std::string & fileName){
263
56
	PFileParser parser;
264
28
	parser.setWhiteSpace(" \n\t");
265
28
	parser.setSeparator(":-'\",{}[]>|");
266
28
	parser.setEscapeChar('\\');
267
28
	if(!parser.open(fileName)){
268

1
		std::cerr << "parser_toml : cannot open file '"<<fileName<<"'" << std::endl;
269
1
		return false;
270
	}
271
27
	bool b(parser_toml_fileParser(dico, parser));
272
27
	return b;
273
}
274