GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: tmp_project/FileParser/src/PMultiFileParser.cpp Lines: 78 151 51.7 %
Date: 2023-10-11 10:52:07 Branches: 50 125 40.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
2
PMultiFileParser::PMultiFileParser(const std::string & inputDirectory, const std::string & outputDirectory){
15
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 std::string & configFile){
28
4
	if(configFile == "") return false;
29
6
	PFileParser parser;
30
3
	p_listFileParser.push_back(parser);
31
3
	p_listFileParser.back().setSeparator(MULTI_PARSER_SEPARATORS_STRING);
32
3
	p_parser = &p_listFileParser.back();
33
3
	if(!p_parser->open(configFile)){
34

1
		std::cerr << "PMultiFileParser::load : can't open file '" << configFile << "'" << std::endl;
35
1
		return false;
36
	}
37
2
	return fullParsing();
38
}
39
40
///Set the file content to be parsed
41
/**	@param fileContent : file content to be parsed
42
*/
43
2
void PMultiFileParser::setFileContent(const std::string & fileContent){
44
2
	if(p_parser == NULL){
45
1
		PFileParser parser;
46
1
		p_listFileParser.push_back(parser);
47
1
		p_listFileParser.back().setSeparator(MULTI_PARSER_SEPARATORS_STRING);
48
1
		p_parser = &p_listFileParser.back();
49
	}
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
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


8
	while(!p_parser->isEndOfFile() && isParseGood && p_run){
65
5
		long unsigned int currentPos = p_parser->getCurrentCharIdx();
66
5
		isParseGood = parseFile();
67

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
3
	if(p_run) postLoadFile();
75
3
	p_listFileParser.pop_back();
76
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 std::string & beginStringComment, const std::string & endStringComment){
93
	p_listCommentConfig.push_back(PMultiCommentConfig(beginStringComment, endStringComment));
94
}
95
96
///Get the last comment
97
/**	@return last comment
98
*/
99
const std::string & PMultiFileParser::getLastComment() const{
100
	return p_lastComment;
101
}
102
103
///Get the last comment
104
/**	@return last comment
105
*/
106
std::string & 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
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
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
1
	std::cerr << "\tAt row :\n" << p_parser->getCurrentRow() << std::endl;
140
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 std::string & tokenExpected, const std::string & 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 std::string & tokenExpected, const std::string & 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



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


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 std::string & 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 std::string & 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 std::vector<std::string> & 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 std::string & patern, const std::string & 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
std::string PMultiFileParser::isMatch(const std::vector<std::string> & vecToken){
251
	//Remove comments
252
	skipComment();
253
	//Check if the token matches
254
	return p_parser->isMatch(vecToken);
255
}
256
257
///Check if the one entry of the vector of token matches
258
/**	@param listToken : list of token
259
 * 	@return matched string, or empty string if there is no match
260
*/
261
std::string PMultiFileParser::isMatch(const std::list<std::string> & listToken){
262
	//Remove comments
263
	skipComment();
264
	//Check if the token matches
265
	return p_parser->isMatch(listToken);
266
}
267
268
///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)
269
/**	@param vecToken : vector of token
270
 * 	@return matched string, or empty string if there is no match
271
*/
272
std::string PMultiFileParser::isMatchToken(const std::vector<std::string> & vecToken){
273
	//Remove comments
274
	skipComment();
275
	//Check if the token matches
276
	return p_parser->isMatchToken(vecToken);
277
}
278
279
///Check the matching between the current caracters and all the string in the list but treats the string as a token (cannot be part of a word)
280
/**	@param listToken : list of token
281
 * 	@return matched string, or empty string if there is no match
282
*/
283
std::string PMultiFileParser::isMatchToken(const std::list<std::string> & listToken){
284
	//Remove comments
285
	skipComment();
286
	//Check if the token matches
287
	return p_parser->isMatchToken(listToken);
288
}
289
290
///Get the string composed of charset charcters
291
/**	@param charset : set of allowed characters
292
 * 	@return corresponding string composed of characters in the given charset
293
*/
294
std::string PMultiFileParser::getStrComposedOf(const std::string & charset){
295
	//Remove comments
296
	skipComment();
297
	//Check if the token matches
298
	return p_parser->getStrComposedOf(charset);
299
}
300
301
///Get the current token and skip the comment
302
void PMultiFileParser::getCurrentTokenWithoutComment(){
303
	if(!p_run) return;
304
	p_lastComment = "";
305
	if(p_listCommentConfig.size() != 0lu){
306
		bool currentTokenIsComment(true);
307
		while(currentTokenIsComment && p_run && !p_parser->isEndOfFile()){
308
			PListMultiCommentConfig::iterator it(p_listCommentConfig.begin());
309
			currentTokenIsComment = false;
310
			while(it != p_listCommentConfig.end() && !currentTokenIsComment){
311
				if(p_parser->isMatch(it->first)){
312
					p_lastComment = p_parser->getUntilKey(it->second);
313
					currentTokenIsComment = true;
314
				}
315
				++it;
316
			}
317
		}
318
	}
319
	p_currentToken = p_parser->getNextToken();
320
}
321
322
///Gets the current parser
323
/**	@return pointer to the current parser
324
*/
325
6
PFileParser * PMultiFileParser::getCurrentParser(){
326
6
	return p_parser;
327
}
328
329
///Initialisation function of the class PMultiFileParser
330
/**	@param inputDirectory : input directory of the PMultiFileParser
331
 * 	@param outputDirectory : output directory of the PMultiFileParser
332
*/
333
2
void PMultiFileParser::initialisationPMultiFileParser(const std::string & inputDirectory, const std::string & outputDirectory){
334
2
	p_run = true;
335
2
	p_inputDirectory = inputDirectory;
336
2
	p_outputDirectory = outputDirectory;
337
2
	p_currentToken = "";
338
2
	clearComment();
339
2
	p_parser = NULL;
340
2
}
341
342
343
344
345