GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tmp_project/FileParser/src/parser_toml.cpp Lines: 114 122 93.4 %
Date: 2024-09-10 03:06:26 Branches: 264 332 79.5 %

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

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

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

20
		}else if(parser.isMatch("false")){
85
1
			var.setValue("false");
86
		}else{
87
38
			std::string valueNumber(parser.getStrComposedOf("0123456789.-"));
88
19
			if(valueNumber != ""){
89
15
				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
36
	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
31
bool parse_tomlCompactDico(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
107

31
	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
43
bool parse_toml_varBase(DicoValue & var, PFileParser & parser, PTomlParserData & data){
133
86
	std::string varName("");
134
43
	if(!parse_toml_varName(varName, parser)){return false;}
135

33
	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
31
	var.setKey(varName);
141
31
	bool b(true);
142
31
	if(parse_tomlCompactDico(var, parser, data)){}
143
28
	else if(parse_toml_varValue(var, parser, data)){}
144
5
	else{b = false;}
145
31
	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
43
bool parse_toml_var(DicoValue & dico, PFileParser & parser, PTomlParserData & data){
155
86
	DicoValue var;
156
43
	if(!parse_toml_varBase(var, parser, data)){return false;}
157

26
	dico.getMapChild()[var.getKey()] = var;
158
26
	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
17
DicoValue * parse_get_parent_dico(DicoValue & parent, const std::vector<std::string> & vecDicoName){
180
17
	DicoValue * output = &parent;
181
35
	for(std::vector<std::string>::const_iterator it(vecDicoName.begin()); it != vecDicoName.end(); ++it){
182
18
		output = &(output->getMapChild()[*it]);
183
18
		output->setKey(*it);
184
	}
185
17
	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
16
bool parse_toml_dico_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
195

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





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

34
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
203
33
		else if(parse_toml_var(*dicoDef, parser, data)){
204
// 			parent.getMapChild()[dicoName] = *dicoDef;
205
		}
206
	}
207
208
15
	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
18
bool parse_toml_table_def(DicoValue & parent, PFileParser & parser, PTomlParserData & data){
218

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





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


5
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
227
5
		else if(parse_toml_var(table, parser, data)){
228
// 			parent.getMapChild()[dicoName] = *dicoDef;
229
		}
230
	}
231
2
	dicoDef->getVecChild().push_back(table);
232
233
2
	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
16
bool parser_toml_fileParser(DicoValue & dico, PFileParser & parser){
242
16
	PTomlParserData data(default_PTomlParserData());
243
16
	parser.getStrComposedOf(" \t\n");		//Skip all blank characters
244


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

19
		if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
246
18
		else if(parse_toml_table_def(dico, parser, data)){}
247
16
		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
16
	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
17
bool parser_toml(DicoValue & dico, const std::string & fileName){
263
34
	PFileParser parser;
264
17
	parser.setWhiteSpace(" \n\t");
265
17
	parser.setSeparator(":-'\",{}[]>|");
266
17
	parser.setEscapeChar('\\');
267
17
	if(!parser.open(fileName)){
268

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