GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
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 |
Generated by: GCOVR (Version 4.2) |