GCC Code Coverage Report


Directory: ./
File: src/parserClassConfig.cpp
Date: 2025-04-25 19:10:50
Exec Total Coverage
Lines: 109 147 74.1%
Branches: 171 362 47.2%

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