GCC Code Coverage Report


Directory: ./
File: src/FrontEnd/parserClassConfig.cpp
Date: 2026-10-16 17:52:29
Exec Total Coverage
Lines: 107 151 70.9%
Functions: 9 10 90.0%
Branches: 170 311 54.7%

Line Branch Exec Source
1
2 /***************************************
3 Auteur : Pierre Aubert
4 Mail : pierre.aubert@lapp.in2p3.fr
5 Licence : LGPL-3.0-only
6 ****************************************/
7
8 #include <iostream>
9 #include "class_attribute_utils.h"
10 #include "parserClassConfig.h"
11
12 ///Affiche une erreur de token non attendu
13 /** @param parser : file parser
14 * @param token : token qui pose problème
15 */
16 ✗ void errorUnexpectedToken(const PFileParser & parser, const PString & token){
17 ✗ std::cerr << "errorUnexpectedToken : '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
18 ✗ std::cerr << "unexpected token '" << token << "'" << std::endl;
19 ✗ }
20
21 ///Get class name from parser
22 /** @param parser : PFileParser to be used
23 * @return class name
24 */
25 21 PString getClassName(PFileParser & parser){
26
2/2
✓ Branch 0 (2→3) taken 21 times.
✓ Branch 2 (3→4) taken 21 times.
21 PString name = parser.getStrComposedOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
27
3/4
✓ Branch 0 (14→15) taken 21 times.
✓ Branch 2 (15→16) taken 21 times.
✗ Branch 4 (17→6) not taken.
✓ Branch 5 (17→18) taken 21 times.
21 while(parser.isMatch("::")){
28 ✗ name += "::" + parser.getStrComposedOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
29 }
30 21 return name;
31 ✗ }
32
33 ///Fonction qui met à jour un commentaire
34 /** @param parser : file parser
35 * @param currentComment : commentaire que l'on veut mettre à jour
36 * @return true si on l'a mis à jour, false sinon
37 */
38 78 bool updateCurrentComment(PFileParser & parser, PString & currentComment){
39
4/4
✓ Branch 0 (2→3) taken 78 times.
✓ Branch 2 (3→4) taken 78 times.
✓ Branch 4 (5→6) taken 35 times.
✓ Branch 5 (5→17) taken 43 times.
78 if(parser.isMatch("//")){
40
1/2
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 35 times.
35 if(currentComment != ""){currentComment += "\n";}
41
4/4
✓ Branch 0 (9→10) taken 35 times.
✓ Branch 2 (10→11) taken 35 times.
✓ Branch 4 (11→12) taken 35 times.
✓ Branch 6 (12→13) taken 35 times.
35 currentComment += "//" + parser.getUntilKeyWithoutPatern("\n");
42
3/4
✓ Branch 0 (17→18) taken 43 times.
✓ Branch 2 (18→19) taken 43 times.
✗ Branch 4 (20→21) not taken.
✓ Branch 5 (20→32) taken 43 times.
43 }else if(parser.isMatch("/*")){
43 ✗ if(currentComment != ""){currentComment += "\n";}
44 ✗ currentComment += "/*" + parser.getUntilKey("*/");
45 }else{
46 43 return false;
47 }
48 35 return true;
49 }
50
51 ///Update a template definition
52 /** @param parser : file parser
53 * @param currentTemplate : template to be updated
54 * @return true on success, false otherwise
55 */
56 13 bool updateCurrentTemplate(PFileParser & parser, PVecString & currentTemplate){
57
3/4
✓ Branch 0 (2→3) taken 13 times.
✓ Branch 2 (3→4) taken 13 times.
✓ Branch 4 (5→6) taken 13 times.
✗ Branch 5 (5→7) not taken.
13 if(!parser.isMatch("template")){return false;}
58 ✗ if(!parser.isMatch("<")){return false;}
59
60 ✗ currentTemplate = parser.getUntilKeyWithoutPaternRecurse(">", "<").split(',');
61
62 ✗ return true;
63 }
64
65 ///Parse a PClassConfig
66 /** @param[out] config : PClassConfig
67 * @param[out] parser : file parser
68 * @param[out] currentComment : current commet
69 * @return true on success, false otherwise
70 */
71 22 bool parseClassConfigAttribut(PClassConfig & config, PFileParser & parser, PString & currentComment){
72
1/1
✓ Branch 0 (2→3) taken 22 times.
22 parser.skipWhiteSpace();
73
4/4
✓ Branch 0 (3→4) taken 22 times.
✓ Branch 2 (4→5) taken 22 times.
✓ Branch 4 (5→6) taken 22 times.
✓ Branch 6 (6→7) taken 22 times.
22 PString attribut(parser.getUntilKeyWithoutPatern(";").eraseChar("\n"));
74
1/1
✓ Branch 0 (10→11) taken 22 times.
22 PString defaultValue("");
75
2/2
✓ Branch 0 (11→12) taken 22 times.
✓ Branch 2 (12→13) taken 22 times.
22 size_t bracePos(attribut.findPatternIndex("{"));
76
2/2
✓ Branch 0 (15→16) taken 4 times.
✓ Branch 1 (15→29) taken 18 times.
22 if(bracePos != attribut.size()){
77
4/4
✓ Branch 0 (16→17) taken 4 times.
✓ Branch 2 (17→18) taken 4 times.
✓ Branch 4 (18→19) taken 4 times.
✓ Branch 6 (19→20) taken 4 times.
4 defaultValue = PString(attribut.substr(bracePos)).eraseFirstLastChar(" \n\t");
78
2/2
✓ Branch 0 (25→26) taken 4 times.
✓ Branch 2 (26→27) taken 4 times.
4 attribut = attribut.substr(0, bracePos);
79 }
80
2/2
✓ Branch 0 (29→30) taken 22 times.
✓ Branch 2 (30→31) taken 22 times.
22 PVecString listToken(attribut.split(" \n\t"));
81
1/1
✓ Branch 0 (33→34) taken 22 times.
22 PString attributName(listToken.back());
82 22 listToken.pop_back();
83
1/1
✓ Branch 0 (35→36) taken 22 times.
22 PString attributType("");
84
2/2
✓ Branch 0 (52→37) taken 24 times.
✓ Branch 1 (52→53) taken 22 times.
92 for(PVecString::iterator it(listToken.begin()); it != listToken.end(); ++it){
85
2/2
✓ Branch 0 (39→40) taken 24 times.
✓ Branch 2 (40→41) taken 24 times.
24 attributType += *it + " ";
86 }
87
2/2
✓ Branch 0 (53→54) taken 22 times.
✓ Branch 2 (54→55) taken 22 times.
22 attributType = attributType.eraseFirstLastChar(" \n\t");
88
1/1
✓ Branch 0 (58→59) taken 22 times.
22 PClassAttribute attr(createClassAttribute(attributType, attributName, currentComment));
89
4/4
✓ Branch 0 (59→60) taken 22 times.
✓ Branch 2 (60→61) taken 4 times.
✓ Branch 3 (60→62) taken 18 times.
✓ Branch 4 (61→62) taken 4 times.
22 if(defaultValue != ""){attr.setDefaultValue(defaultValue);}
90
1/1
✓ Branch 0 (62→63) taken 22 times.
22 config.addAttribute(attr);
91
1/1
✓ Branch 0 (63→64) taken 22 times.
22 currentComment = "";
92 22 return true;
93 22 }
94
95 ///Parse the parents of the PClassConfig
96 /** @param[out] config : PClassConfig
97 * @param[out] parser : file parser
98 * @return true on success, false otherwise
99 */
100 9 bool parseParentOfClassConfig(PClassConfig & config, PFileParser & parser){
101
3/4
✓ Branch 0 (2→3) taken 9 times.
✓ Branch 2 (3→4) taken 9 times.
✓ Branch 4 (5→6) taken 9 times.
✗ Branch 5 (5→7) not taken.
9 if(!parser.isMatch("(")) return true;
102
103 ✗ while(!parser.isEndOfFile() && parser.isMatch(")")){
104 ✗ PString parentDef(getClassName(parser));
105 ✗ if(parentDef == ""){
106 ✗ break;
107 }
108 ✗ config.addParentClass(parentDef);
109 ✗ if(parser.isMatch(")")){break;}
110
111 ✗ if(!parser.isMatch(",")){
112 ✗ errorUnexpectedToken(parser, parser.getNextToken());
113 ✗ return false;
114 }
115 ✗ }
116 ✗ return true;
117 }
118
119 ///Parse enum attribute value
120 /** @param[out] config : PClassConfig
121 * @param[out] parser : file parser
122 * @param[out] currentComment : current commet
123 * @return true on success, false otherwise
124 */
125 8 bool parseEnumValue(PClassConfig & config, PFileParser & parser, PString & currentComment){
126
2/2
✓ Branch 0 (2→3) taken 8 times.
✓ Branch 2 (3→4) taken 8 times.
8 PString enumValue(getClassName(parser)), value("");
127
3/4
✓ Branch 0 (4→5) taken 8 times.
✓ Branch 2 (5→6) taken 8 times.
✓ Branch 4 (7→8) taken 8 times.
✗ Branch 5 (7→14) not taken.
8 if(!parser.isMatch("=")){
128
2/2
✓ Branch 0 (8→9) taken 8 times.
✓ Branch 2 (9→10) taken 8 times.
8 value = parser.getStrComposedOf("0123456789xu");
129 }
130
2/2
✓ Branch 0 (14→15) taken 8 times.
✓ Branch 2 (15→16) taken 8 times.
8 PClassAttribute attr(createClassAttribute("int /* just to remember*/", enumValue, currentComment));
131
1/1
✓ Branch 0 (17→18) taken 8 times.
8 attr.setDefaultValue(value);
132
1/1
✓ Branch 0 (18→19) taken 8 times.
8 config.addAttribute(attr);
133
1/1
✓ Branch 0 (19→20) taken 8 times.
8 currentComment = "";
134
2/2
✓ Branch 0 (20→21) taken 8 times.
✓ Branch 2 (21→22) taken 8 times.
8 parser.isMatch(","); //We consume the comma if there is one
135 8 return true;
136 8 }
137
138 ///Parse an enum definition
139 /** @param[out] listClassConfig : list of PClassConfig
140 * @param[out] parser : file parser
141 * @param[out] currentComment : current comment
142 * @return true on success, false otherwise
143 */
144 13 bool parseEnumConfig(std::vector<PClassConfig> & listClassConfig, PFileParser & parser, PString & currentComment){
145
4/4
✓ Branch 0 (2→3) taken 13 times.
✓ Branch 2 (3→4) taken 13 times.
✓ Branch 4 (5→6) taken 9 times.
✓ Branch 5 (5→7) taken 4 times.
13 if(!parser.isMatchToken("enum")){return false;}
146
1/1
✓ Branch 0 (7→8) taken 4 times.
4 PClassConfig config;
147
1/1
✓ Branch 0 (8→9) taken 4 times.
4 config.setIsEnum(true);
148
1/1
✓ Branch 0 (9→10) taken 4 times.
4 PString enumName(getClassName(parser)); //Get the name of the enum
149
4/4
✓ Branch 0 (10→11) taken 4 times.
✓ Branch 2 (11→12) taken 4 times.
✓ Branch 4 (12→13) taken 4 times.
✓ Branch 6 (13→14) taken 4 times.
4 std::cout << "parseEnumConfig : find enum : '"<<enumName<<"'" << std::endl;
150
1/1
✓ Branch 0 (14→15) taken 4 times.
4 config.setName(enumName);
151
1/1
✓ Branch 0 (15→16) taken 4 times.
4 config.setClassDocumentation(currentComment);
152
1/1
✓ Branch 0 (16→17) taken 4 times.
4 currentComment = "";
153
1/1
✓ Branch 0 (17→18) taken 4 times.
4 parser.skipWhiteSpace();
154
3/4
✓ Branch 0 (18→19) taken 4 times.
✓ Branch 2 (19→20) taken 4 times.
✗ Branch 4 (21→22) not taken.
✓ Branch 5 (21→30) taken 4 times.
4 if(!parser.isMatch("{")){
155 ✗ errorUnexpectedToken(parser, parser.getNextToken());
156 ✗ std::cerr << "\tExpect '{' after enum name '"<<enumName<<"'" << std::endl;
157 ✗ return false;
158 }
159 4 bool searchingData(true);
160
10/15
✓ Branch 0 (42→43) taken 12 times.
✓ Branch 2 (43→44) taken 12 times.
✗ Branch 3 (43→49) not taken.
✓ Branch 4 (44→45) taken 12 times.
✗ Branch 5 (44→49) not taken.
✓ Branch 6 (45→46) taken 12 times.
✓ Branch 8 (46→47) taken 12 times.
✓ Branch 10 (47→48) taken 8 times.
✓ Branch 11 (47→49) taken 4 times.
✓ Branch 12 (50→51) taken 12 times.
✗ Branch 13 (50→52) not taken.
✓ Branch 14 (52→31) taken 8 times.
✓ Branch 15 (52→53) taken 4 times.
✗ Branch 16 (71→72) not taken.
✗ Branch 17 (71→73) not taken.
16 while(!parser.isEndOfFile() && searchingData && !parser.isMatch("}")){
161
2/3
✓ Branch 0 (31→32) taken 8 times.
✗ Branch 2 (32→33) not taken.
✓ Branch 3 (32→34) taken 8 times.
8 if(updateCurrentComment(parser, currentComment)){}
162 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PDataGroup ou de PDataVar ou PDataTable
163
2/3
✓ Branch 0 (34→35) taken 8 times.
✗ Branch 2 (35→36) not taken.
✓ Branch 3 (35→40) taken 8 times.
8 if(!parseEnumValue(config, parser, currentComment)){
164 ✗ errorUnexpectedToken(parser, parser.getNextToken());
165 ✗ return false;
166 }
167 }
168 }
169
1/1
✓ Branch 0 (53→54) taken 4 times.
4 listClassConfig.push_back(config);
170 4 return true;
171 4 }
172
173 ///Parse a PClassConfig
174 /** @param[out] listClassConfig : list of PClassConfig
175 * @param[out] parser : file parser
176 * @param[out] currentComment : current comment
177 * @param[out] listTemplate : list of the template to be used in the defined class
178 * @return true on success, false otherwise
179 */
180 9 bool parsePClassConfig(std::vector<PClassConfig> & listClassConfig, PFileParser & parser, PString & currentComment, PVecString & listTemplate){
181
1/1
✓ Branch 0 (2→3) taken 9 times.
9 PClassConfig config;
182
1/1
✓ Branch 0 (3→4) taken 9 times.
9 PString fullName(getClassName(parser));
183
1/1
✓ Branch 0 (4→5) taken 9 times.
9 size_t separator = fullName.rfind("::");
184
2/2
✓ Branch 0 (5→6) taken 9 times.
✓ Branch 2 (6→7) taken 9 times.
9 PString className, namespaceName;
185
1/2
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→18) taken 9 times.
9 if(separator != PString::npos){
186 ✗ className = fullName.substr(separator + 2);
187 ✗ namespaceName = fullName.substr(0, separator);
188 ✗ std::cout << "parsePClassConfig : find namespaceName : '"<<namespaceName<<"'" << std::endl;
189 }else{
190
1/1
✓ Branch 0 (18→19) taken 9 times.
9 className = fullName;
191 }
192
4/4
✓ Branch 0 (19→20) taken 9 times.
✓ Branch 2 (20→21) taken 9 times.
✓ Branch 4 (21→22) taken 9 times.
✓ Branch 6 (22→23) taken 9 times.
9 std::cout << "parsePClassConfig : find className : '"<<className<<"'" << std::endl;
193
1/1
✓ Branch 0 (23→24) taken 9 times.
9 config.setName(className);
194
1/1
✓ Branch 0 (24→25) taken 9 times.
9 config.setNamespace(namespaceName);
195
1/1
✓ Branch 0 (25→26) taken 9 times.
9 config.setClassDocumentation(currentComment);
196
1/1
✓ Branch 0 (26→27) taken 9 times.
9 config.setListTemplate(listTemplate);
197
1/1
✓ Branch 0 (27→28) taken 9 times.
9 currentComment = "";
198 9 listTemplate.clear();
199
1/1
✓ Branch 0 (29→30) taken 9 times.
9 parser.skipWhiteSpace();
200
201
2/3
✓ Branch 0 (30→31) taken 9 times.
✗ Branch 2 (31→32) not taken.
✓ Branch 3 (31→45) taken 9 times.
9 if(!parseParentOfClassConfig(config, parser)){
202 ✗ std::cerr << "parsePClassConfig : file '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
203 ✗ std::cerr << "\tmissing ')' : can't parse parents of the class '"<<config.getName()<<"'" << std::endl;
204 }
205
2/3
✓ Branch 0 (45→46) taken 9 times.
✗ Branch 2 (46→47) not taken.
✓ Branch 3 (46→58) taken 9 times.
9 if(parser.isEndOfFile()){
206 ✗ std::cerr << "parsePClassConfig : file '" << parser.getFileName() << "' line " << parser.getLine() << std::endl;
207 ✗ std::cerr << "\tmissing '}'" << std::endl;
208 ✗ return false;
209 }
210
3/4
✓ Branch 0 (58→59) taken 9 times.
✓ Branch 2 (59→60) taken 9 times.
✗ Branch 4 (61→62) not taken.
✓ Branch 5 (61→70) taken 9 times.
9 if(!parser.isMatch("{")){
211 ✗ errorUnexpectedToken(parser, parser.getNextToken());
212 ✗ std::cerr << "\tExpect '{' after class name '"<<className<<"'" << std::endl;
213 ✗ return false;
214 }
215
216 9 bool searchingData(true);
217
10/15
✓ Branch 0 (82→83) taken 53 times.
✓ Branch 2 (83→84) taken 53 times.
✗ Branch 3 (83→89) not taken.
✓ Branch 4 (84→85) taken 53 times.
✗ Branch 5 (84→89) not taken.
✓ Branch 6 (85→86) taken 53 times.
✓ Branch 8 (86→87) taken 53 times.
✓ Branch 10 (87→88) taken 44 times.
✓ Branch 11 (87→89) taken 9 times.
✓ Branch 12 (90→91) taken 53 times.
✗ Branch 13 (90→92) not taken.
✓ Branch 14 (92→71) taken 44 times.
✓ Branch 15 (92→93) taken 9 times.
✗ Branch 16 (122→123) not taken.
✗ Branch 17 (122→124) not taken.
62 while(!parser.isEndOfFile() && searchingData && !parser.isMatch("}")){
218
3/3
✓ Branch 0 (71→72) taken 44 times.
✓ Branch 2 (72→73) taken 22 times.
✓ Branch 3 (72→74) taken 22 times.
44 if(updateCurrentComment(parser, currentComment)){}
219 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PDataGroup ou de PDataVar ou PDataTable
220
2/3
✓ Branch 0 (74→75) taken 22 times.
✗ Branch 2 (75→76) not taken.
✓ Branch 3 (75→80) taken 22 times.
22 if(!parseClassConfigAttribut(config, parser, currentComment)){
221 ✗ errorUnexpectedToken(parser, parser.getNextToken());
222 ✗ return false;
223 }
224 }
225 }
226
1/1
✓ Branch 0 (93→94) taken 9 times.
9 listClassConfig.push_back(config);
227 9 return true;
228 9 }
229
230 ///Parser list class config
231 /** @param[out] listClassConfig : list of class config
232 * @param listInclude : list of include
233 * @param fileName : file name of the config
234 * @return true on success, false otherwise
235 */
236 8 bool parserClassConfig(std::vector<PClassConfig> & listClassConfig, PVecPath & listInclude, const PPath & fileName){
237
2/3
✓ Branch 0 (2→3) taken 8 times.
✗ Branch 2 (3→4) not taken.
✓ Branch 3 (3→5) taken 8 times.
8 if(fileName == "") return false;
238
1/1
✓ Branch 0 (5→6) taken 8 times.
8 PFileParser parser;
239
2/2
✓ Branch 0 (6→7) taken 8 times.
✓ Branch 2 (7→8) taken 8 times.
8 parser.setWhiteSpace(" \t\n");
240
2/2
✓ Branch 0 (9→10) taken 8 times.
✓ Branch 2 (10→11) taken 8 times.
8 parser.setSeparator("{};/*");
241
2/3
✓ Branch 0 (12→13) taken 8 times.
✗ Branch 2 (13→14) not taken.
✓ Branch 3 (13→15) taken 8 times.
8 if(!parser.open(fileName)) return false;
242
1/1
✓ Branch 0 (15→16) taken 8 times.
8 PString currentComment("");
243 8 PVecString listTemplate;
244
3/3
✓ Branch 0 (52→53) taken 34 times.
✓ Branch 2 (53→18) taken 26 times.
✓ Branch 3 (53→54) taken 8 times.
34 while(!parser.isEndOfFile()){
245
3/4
✓ Branch 0 (18→19) taken 26 times.
✓ Branch 2 (19→20) taken 26 times.
✗ Branch 4 (21→22) not taken.
✓ Branch 5 (21→38) taken 26 times.
26 if(parser.isMatch("#")){
246 ✗ if(parser.isMatch("include")){
247 ✗ listInclude.push_back(parser.getUntilKeyWithoutPatern("\n").eraseChar(" \t\n"));
248 }
249
3/3
✓ Branch 0 (38→39) taken 26 times.
✓ Branch 2 (39→40) taken 13 times.
✓ Branch 3 (39→50) taken 13 times.
26 }else if(updateCurrentComment(parser, currentComment)){}
250
2/3
✓ Branch 0 (40→41) taken 13 times.
✓ Branch 2 (41→42) taken 13 times.
✗ Branch 3 (41→50) not taken.
13 else if(updateCurrentTemplate(parser, listTemplate)){}
251
3/3
✓ Branch 0 (42→43) taken 13 times.
✓ Branch 2 (43→44) taken 9 times.
✓ Branch 3 (43→50) taken 4 times.
13 else if(parseEnumConfig(listClassConfig, parser, currentComment)){}
252 else{ //Si ce n'est pas un séparateur, c'est que l'on a trouvé un nom, de PClassConfig
253
2/3
✓ Branch 0 (44→45) taken 9 times.
✗ Branch 2 (45→46) not taken.
✓ Branch 3 (45→50) taken 9 times.
9 if(!parsePClassConfig(listClassConfig, parser, currentComment, listTemplate)){
254 ✗ errorUnexpectedToken(parser, parser.getNextToken());
255 ✗ return false;
256 }
257 }
258
1/1
✓ Branch 0 (50→51) taken 26 times.
26 parser.skipWhiteSpace();
259 }
260 8 return true;
261 8 }
262
263
264
265