GCC Code Coverage Report


Directory: ./
File: src/PMultiFileParser.cpp
Date: 2025-09-08 16:55:04
Exec Total Coverage
Lines: 81 151 53.6%
Functions: 14 30 46.7%
Branches: 58 126 46.0%

Line Branch Exec Source
1 /***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5 ****************************************/
6
7 #include "PMultiFileParser.h"
8
9
10 ///Default constructeur of PMultiFileParser
11 /** @param inputDirectory : input directory of the PMultiFileParser
12 * @param outputDirectory : output directory of the PMultiFileParser
13 */
14
4/4
✓ Branch 0 (3→4) taken 2 times.
✓ Branch 2 (4→5) taken 2 times.
✓ Branch 4 (5→6) taken 2 times.
✓ Branch 6 (6→7) taken 2 times.
2 PMultiFileParser::PMultiFileParser(const PPath & inputDirectory, const PPath & outputDirectory){
15
1/1
✓ Branch 0 (8→9) taken 2 times.
2 initialisationPMultiFileParser(inputDirectory, outputDirectory);
16 2 }
17
18 ///Destructeur of PMultiFileParser
19 2 PMultiFileParser::~PMultiFileParser(){
20
21 2 }
22
23 ///Load the PMultiFileParser with the configFile
24 /** @param configFile : file name of the cnofiguration file
25 * @return true on success, false otherwise
26 */
27 4 bool PMultiFileParser::load(const PPath & configFile){
28
3/3
✓ Branch 0 (2→3) taken 4 times.
✓ Branch 2 (3→4) taken 1 times.
✓ Branch 3 (3→5) taken 3 times.
4 if(configFile == "") return false;
29
1/1
✓ Branch 0 (5→6) taken 3 times.
3 PFileParser parser;
30
1/1
✓ Branch 0 (6→7) taken 3 times.
3 p_listFileParser.push_back(parser);
31
2/2
✓ Branch 0 (8→9) taken 3 times.
✓ Branch 2 (9→10) taken 3 times.
3 p_listFileParser.back().setSeparator(MULTI_PARSER_SEPARATORS_STRING);
32 3 p_parser = &p_listFileParser.back();
33
3/3
✓ Branch 0 (12→13) taken 3 times.
✓ Branch 2 (13→14) taken 1 times.
✓ Branch 3 (13→19) taken 2 times.
3 if(!p_parser->open(configFile)){
34
4/4
✓ Branch 0 (14→15) taken 1 times.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 4 (16→17) taken 1 times.
✓ Branch 6 (17→18) taken 1 times.
1 std::cerr << "PMultiFileParser::load : can't open file '" << configFile << "'" << std::endl;
35 1 return false;
36 }
37
1/1
✓ Branch 0 (19→20) taken 2 times.
2 return fullParsing();
38 3 }
39
40 ///Set the file content to be parsed
41 /** @param fileContent : file content to be parsed
42 */
43 2 void PMultiFileParser::setFileContent(const PString & fileContent){
44
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→12) taken 1 times.
2 if(p_parser == NULL){
45
1/1
✓ Branch 0 (3→4) taken 1 times.
1 PFileParser parser;
46
1/1
✓ Branch 0 (4→5) taken 1 times.
1 p_listFileParser.push_back(parser);
47
2/2
✓ Branch 0 (6→7) taken 1 times.
✓ Branch 2 (7→8) taken 1 times.
1 p_listFileParser.back().setSeparator(MULTI_PARSER_SEPARATORS_STRING);
48 1 p_parser = &p_listFileParser.back();
49 1 }
50 2 p_parser = &p_listFileParser.back();
51 2 p_parser->setFileContent(fileContent);
52 2 }
53
54 ///Perform the full parsing pf data
55 /** @return true on success, false otherwise
56 */
57 4 bool PMultiFileParser::fullParsing(){
58
2/2
✓ Branch 0 (2→3) taken 1 times.
✓ Branch 1 (2→6) taken 3 times.
4 if(p_parser == NULL){
59 1 std::cerr << "PMultiFileParser::fullParsing : the parser is not initialised, please call PMultiFileParser::load or PMultiFileParser::setFileContent before this function" << std::endl;
60 1 return false;
61 }
62 3 preLoadFile();
63 3 bool isParseGood(true);
64
7/8
✓ Branch 0 (29→30) taken 6 times.
✓ Branch 1 (29→33) taken 2 times.
✓ Branch 2 (30→31) taken 5 times.
✓ Branch 3 (30→33) taken 1 times.
✓ Branch 4 (31→32) taken 5 times.
✗ Branch 5 (31→33) not taken.
✓ Branch 6 (34→8) taken 5 times.
✓ Branch 7 (34→35) taken 3 times.
8 while(!p_parser->isEndOfFile() && isParseGood && p_run){
65 5 long unsigned int currentPos = p_parser->getCurrentCharIdx();
66 5 isParseGood = parseFile();
67
2/6
✗ Branch 0 (11→12) not taken.
✓ Branch 1 (11→15) taken 5 times.
✗ Branch 2 (13→14) not taken.
✗ Branch 3 (13→15) not taken.
✗ Branch 4 (16→17) not taken.
✓ Branch 5 (16→27) taken 5 times.
5 if(currentPos == p_parser->getCurrentCharIdx() && !p_parser->isEndOfFile()){
68 std::cerr << "PMultiFileParser::fullParsing : the parser is stucked at the position :" << std::endl << "\t" << p_parser->getLocation() << std::endl;
69 unexpectedToken();
70 pointAtRow();
71 p_run = false;
72 }
73 }
74
2/2
✓ Branch 0 (35→36) taken 2 times.
✓ Branch 1 (35→37) taken 1 times.
3 if(p_run) postLoadFile();
75 3 p_listFileParser.pop_back();
76
2/2
✓ Branch 0 (39→40) taken 2 times.
✓ Branch 1 (39→42) taken 1 times.
3 if(p_listFileParser.size() > 0lu) p_parser = &p_listFileParser.back();
77 1 else p_parser = NULL;
78 3 return p_run;
79 }
80
81 ///Adds a comment config for the parser
82 /** @param commentConfig : comment config for the PMultiFileParser
83 */
84 void PMultiFileParser::addCommentConfig(const PMultiCommentConfig & commentConfig){
85 p_listCommentConfig.push_back(commentConfig);
86 }
87
88 ///Adds a comment config for the parser
89 /** @param beginStringComment : string which defines the begining of a comment
90 * @param endStringComment : string which defines the ending of a comment
91 */
92 void PMultiFileParser::addCommentConfig(const PString & beginStringComment, const PString & endStringComment){
93 p_listCommentConfig.push_back(PMultiCommentConfig(beginStringComment, endStringComment));
94 }
95
96 ///Get the last comment
97 /** @return last comment
98 */
99 const PString & PMultiFileParser::getLastComment() const{
100 return p_lastComment;
101 }
102
103 ///Get the last comment
104 /** @return last comment
105 */
106 PString & PMultiFileParser::getLastComment(){
107 return p_lastComment;
108 }
109
110 ///Pre load file
111 void PMultiFileParser::preLoadFile(){
112
113 }
114
115 ///Post load file
116 void PMultiFileParser::postLoadFile(){
117
118 }
119
120 ///Stop the parsing of all the files
121 1 void PMultiFileParser::stopParsing(){
122 1 p_run = false;
123 1 }
124
125 ///Write a parsing error
126 1 void PMultiFileParser::errorAt(){
127
4/4
✓ Branch 0 (3→4) taken 1 times.
✓ Branch 2 (4→5) taken 1 times.
✓ Branch 4 (5→6) taken 1 times.
✓ Branch 6 (6→7) taken 1 times.
1 std::cerr << "\033[31mError at " << p_parser->getLocation() << " :\033[0m" << std::endl;
128 1 }
129
130 ///Print unexpected token error
131 1 void PMultiFileParser::unexpectedToken(){
132 1 errorAt();
133
4/4
✓ Branch 0 (4→5) taken 1 times.
✓ Branch 2 (5→6) taken 1 times.
✓ Branch 4 (6→7) taken 1 times.
✓ Branch 6 (7→8) taken 1 times.
1 std::cerr << "PMultiFileParser::parseFile : unexpected token '"<<p_parser->getNextToken()<<"'" << std::endl;
134 1 stopParsing();
135 1 }
136
137 ///Point the problem
138 1 void PMultiFileParser::pointAtRow(){
139
3/3
✓ Branch 0 (3→4) taken 1 times.
✓ Branch 2 (4→5) taken 1 times.
✓ Branch 4 (5→6) taken 1 times.
1 std::cerr << "\tAt row :\n" << p_parser->getCurrentRow() << std::endl;
140
2/2
✓ Branch 0 (11→8) taken 4 times.
✓ Branch 1 (11→12) taken 1 times.
5 for(size_t i(0lu); i < p_parser->getColumn(); ++i){
141 4 std::cerr << " ";
142 }
143 1 std::cerr << "^" << std::endl;
144 1 }
145
146 ///Check if the p_currentToken == tokenExpected
147 /** @param tokenExpected : token we expect
148 * @param tokenBefore : token before the exprected one
149 * @return true if the p_currentToken == tokenExpected, false otherwise with an error message
150 */
151 bool PMultiFileParser::checkExpectedToken(const PString & tokenExpected, const PString & tokenBefore){
152 if(tokenExpected == p_currentToken) return true;
153 errorAt();
154 std::cerr << "Unexpected token '"<<p_currentToken<<"'" << std::endl;
155 std::cerr << "Expected token '"<<tokenExpected<<"'" << std::endl;
156 if(tokenBefore != "") std::cerr << " after " << tokenBefore << std::endl;
157 stopParsing();
158 return false;
159 }
160
161 ///Check if the tokenExpected match
162 /** @param tokenExpected : token we expect
163 * @param tokenBefore : token before the exprected one
164 * @return true if the p_currentToken == tokenExpected, false otherwise with an error message
165 */
166 bool PMultiFileParser::checkExpectedMatch(const PString & tokenExpected, const PString & tokenBefore){
167 if(p_parser->isMatch(tokenExpected)) return true;
168 errorAt();
169 std::cerr << "Unexpected token '"<<p_parser->getNextToken()<<"'" << std::endl;
170 std::cerr << "Expected token '"<<tokenExpected<<"'" << std::endl;
171 if(tokenBefore != "") std::cerr << " after " << tokenBefore << std::endl;
172 stopParsing();
173 return false;
174 }
175
176 ///Skip comment
177 8 void PMultiFileParser::skipComment(){
178 8 bool isCommentFound(false);
179 do{
180 8 isCommentFound = false;
181 8 PListMultiCommentConfig::iterator it(p_listCommentConfig.begin());
182
2/11
✗ Branch 0 (19→20) not taken.
✓ Branch 1 (19→25) taken 8 times.
✗ Branch 2 (20→21) not taken.
✗ Branch 3 (20→25) not taken.
✗ Branch 4 (21→22) not taken.
✗ Branch 5 (21→25) not taken.
✗ Branch 6 (22→23) not taken.
✗ Branch 8 (23→24) not taken.
✗ Branch 9 (23→25) not taken.
✗ Branch 10 (26→5) not taken.
✓ Branch 11 (26→27) taken 8 times.
8 while(it != p_listCommentConfig.end() && !isCommentFound && p_run && !p_parser->isEndOfFile()){
183 if(p_parser->isMatch(it->first)){
184 p_lastComment += it->first + p_parser->getUntilKey(it->second);
185 isCommentFound = true;
186 }
187 ++it;
188 }
189
2/8
✗ Branch 0 (27→28) not taken.
✓ Branch 1 (27→32) taken 8 times.
✗ Branch 2 (28→29) not taken.
✗ Branch 3 (28→32) not taken.
✗ Branch 4 (30→31) not taken.
✗ Branch 5 (30→32) not taken.
✗ Branch 6 (33→34) not taken.
✓ Branch 7 (33→35) taken 8 times.
8 }while(isCommentFound && p_run && !p_parser->isEndOfFile());
190 8 }
191
192 ///Clear comment
193 2 void PMultiFileParser::clearComment(){
194 2 p_lastComment = "";
195 2 }
196
197 ///Check if the given token matches the current read file
198 /** @param token : token to be checked
199 * @return true on success, false otherwise
200 * This function isMatch takes account the comments
201 */
202 8 bool PMultiFileParser::isMatch(const PString & token){
203 //Remove comments
204 8 skipComment();
205 //Check if the token matches
206 8 return p_parser->isMatch(token);
207 }
208
209 ///Check if the given token matches the current read file and goes back even if the token matches
210 /** @param token : token to be checked
211 * @return true on success, false otherwise
212 * This function isMatch takes account the comments
213 */
214 bool PMultiFileParser::isMatchRewind(const PString & token){
215 //Remove comments
216 skipComment();
217 //Check if the token matches
218 return p_parser->isMatchRewind(token);
219 }
220
221 ///Match a sequence of token in a vector
222 /** @param patern : set of token to match in this order and totally
223 * @param alwaysPopBack : true to make the PFileParser at the exact same place before the check even is the sequence matches
224 * @return true if the full sequence matches, false otherwise
225 */
226 bool PMultiFileParser::isMatchSeq(const PVecString & patern, bool alwaysPopBack){
227 //Remove comments
228 skipComment();
229 //Check if the token matches
230 return p_parser->isMatchSeq(patern, alwaysPopBack);
231 }
232
233 ///Says if the patern match with the current caracters of the PFileParser
234 /** @param patern : patern we want to check (this patern should not begin with white caracters)
235 * @param forbiddenCharBefore : lisr of characters which cannot be just before the first character of the patern
236 * @return true if the patern match, false otherwise
237 * If the patern match, the current char will be in the next char of the patern
238 */
239 bool PMultiFileParser::isMatch(const PString & patern, const PString & forbiddenCharBefore){
240 //Remove comments
241 skipComment();
242 //Check if the token matches
243 return p_parser->isMatch(patern, forbiddenCharBefore);
244 }
245
246 ///Check if the one entry of the vector of token matches
247 /** @param vecToken : vector of token
248 * @return matched string, or empty string if there is no match
249 */
250 PString PMultiFileParser::isMatch(const PVecString & vecToken){
251 //Remove comments
252 skipComment();
253 //Check if the token matches
254 return p_parser->isMatch(vecToken);
255 }
256
257 ///Check the matching between the current caracters and all the string in the vector but treats the string as a token (cannot be part of a word)
258 /** @param vecToken : vector of token
259 * @return matched string, or empty string if there is no match
260 */
261 PString PMultiFileParser::isMatchToken(const PVecString & vecToken){
262 //Remove comments
263 skipComment();
264 //Check if the token matches
265 return p_parser->isMatchToken(vecToken);
266 }
267
268 ///Get the string composed of charset charcters
269 /** @param charset : set of allowed characters
270 * @return corresponding string composed of characters in the given charset
271 */
272 PString PMultiFileParser::getStrComposedOf(const PString & charset){
273 //Remove comments
274 skipComment();
275 //Check if the token matches
276 return p_parser->getStrComposedOf(charset);
277 }
278
279 ///Get the current token and skip the comment
280 void PMultiFileParser::getCurrentTokenWithoutComment(){
281 if(!p_run) return;
282 p_lastComment = "";
283 if(p_listCommentConfig.size() != 0lu){
284 bool currentTokenIsComment(true);
285 while(currentTokenIsComment && p_run && !p_parser->isEndOfFile()){
286 PListMultiCommentConfig::iterator it(p_listCommentConfig.begin());
287 currentTokenIsComment = false;
288 while(it != p_listCommentConfig.end() && !currentTokenIsComment){
289 if(p_parser->isMatch(it->first)){
290 p_lastComment = p_parser->getUntilKey(it->second);
291 currentTokenIsComment = true;
292 }
293 ++it;
294 }
295 }
296 }
297 p_currentToken = p_parser->getNextToken();
298 }
299
300 ///Gets the current parser
301 /** @return pointer to the current parser
302 */
303 6 PFileParser * PMultiFileParser::getCurrentParser(){
304 6 return p_parser;
305 }
306
307 ///Initialisation function of the class PMultiFileParser
308 /** @param inputDirectory : input directory of the PMultiFileParser
309 * @param outputDirectory : output directory of the PMultiFileParser
310 */
311 2 void PMultiFileParser::initialisationPMultiFileParser(const PPath & inputDirectory, const PPath & outputDirectory){
312 2 p_run = true;
313 2 p_inputDirectory = inputDirectory;
314 2 p_outputDirectory = outputDirectory;
315 2 p_currentToken = "";
316 2 clearComment();
317 2 p_parser = NULL;
318 2 }
319
320
321
322
323
324