Directory: | ./ |
---|---|
File: | tmp_project/PhoenixFileParser/src/PMultiFileParser.cpp |
Date: | 2025-03-14 12:18:05 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 80 | 146 | 54.8% |
Branches: | 54 | 133 | 40.6% |
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 2 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 8 taken 2 times.
✓ Branch 11 taken 2 times.
|
2 | PMultiFileParser::PMultiFileParser(const PPath & inputDirectory, const PPath & outputDirectory){ |
15 |
1/1✓ Branch 1 taken 2 times.
|
2 | initialisationPMultiFileParser(inputDirectory, outputDirectory); |
16 | 2 | } | |
17 | |||
18 | ///Destructeur of PMultiFileParser | ||
19 | 4 | PMultiFileParser::~PMultiFileParser(){ | |
20 | |||
21 | } | ||
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 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if(configFile == "") return false; |
29 |
1/1✓ Branch 1 taken 3 times.
|
3 | PFileParser parser; |
30 |
1/1✓ Branch 1 taken 3 times.
|
3 | p_listFileParser.push_back(parser); |
31 |
2/2✓ Branch 2 taken 3 times.
✓ Branch 5 taken 3 times.
|
3 | p_listFileParser.back().setSeparator(MULTI_PARSER_SEPARATORS_STRING); |
32 | 3 | p_parser = &p_listFileParser.back(); | |
33 |
3/3✓ Branch 1 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 2 times.
|
3 | if(!p_parser->open(configFile)){ |
34 |
4/4✓ Branch 1 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 10 taken 1 times.
|
1 | std::cerr << "PMultiFileParser::load : can't open file '" << configFile << "'" << std::endl; |
35 | 1 | return false; | |
36 | } | ||
37 |
1/1✓ Branch 1 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 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if(p_parser == NULL){ |
45 |
1/1✓ Branch 1 taken 1 times.
|
1 | PFileParser parser; |
46 |
1/1✓ Branch 1 taken 1 times.
|
1 | p_listFileParser.push_back(parser); |
47 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 5 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 taken 1 times.
✓ Branch 1 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 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 5 times.
✓ Branch 8 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 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 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 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if(p_run) postLoadFile(); |
75 | 3 | p_listFileParser.pop_back(); | |
76 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 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 |
3/3✓ Branch 3 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 9 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 |
3/3✓ Branch 3 taken 1 times.
✓ Branch 6 taken 1 times.
✓ Branch 9 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 |
2/2✓ Branch 3 taken 1 times.
✓ Branch 6 taken 1 times.
|
1 | std::cerr << "\tAt row :\n" << p_parser->getCurrentRow() << std::endl; |
140 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 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/12✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✓ Branch 14 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 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 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 |