34 ParserError(
int err = 0,
int lin = 0,
int cha = 0)
35 : errorNumber(err), lineInFile(lin), charInLine(cha) {}
46 std::pair<long, long> range;
63 struct TLPTokenParser {
66 TLPTokenParser(std::istream &i) : curLine(0), is(i) {}
68 bool newLine(
char ch,
int &curPos) {
84 TLPToken nextToken(TLPValue &val,
int &curPos) {
86 bool endOfStream =
false, strGet =
false, slashMode =
false, started =
false, stop =
false,
90 while ((!stop) && (endOfStream = !(is.get(ch).fail()))) {
97 if (!newLine(ch, curPos))
147 if (!newLine(ch, curPos))
169 if (!newLine(ch, curPos))
230 if (!started && !endOfStream)
233 char *endPtr =
nullptr;
234 const char *cstr = val.str.c_str();
236 long resultl = strtol(cstr, &endPtr, 10);
241 unsigned long strlength = val.str.length();
243 if (endPtr == (cstr + strlength)) {
244 val.integer = resultl;
249 if (endPtr > cstr && (cstr + strlength) > (endPtr + 2)) {
250 val.range.first = resultl;
252 if ((endPtr[0] ==
'.') && (endPtr[1] ==
'.')) {
253 char *beginPtr = endPtr + 2;
255 resultl = strtol(beginPtr, &endPtr, 10);
260 if (endPtr == (cstr + strlength)) {
261 if (resultl < val.range.first)
264 val.range.second = resultl;
272 double resultd = strtod(cstr, &endPtr);
277 if (endPtr == (cstr + strlength)) {
282 if (strcasecmp(cstr,
"true") == 0) {
287 if (strcasecmp(cstr,
"false") == 0) {
300 virtual ~TLPBuilder() {}
301 virtual bool addBool(
const bool) = 0;
302 virtual bool addInt(
const int) = 0;
303 virtual bool addRange(
int,
int) = 0;
304 virtual bool addDouble(
const double) = 0;
305 virtual bool addString(
const std::string &) = 0;
306 virtual bool addStruct(
const std::string &, TLPBuilder *&) = 0;
307 virtual bool close() = 0;
308 virtual bool canRead() {
311 virtual bool read(std::istream &) {
318 struct TLPTrue :
public TLPBuilder {
319 bool addBool(
const bool)
override {
322 bool addInt(
const int)
override {
325 bool addRange(
int,
int)
override {
328 bool addDouble(
const double)
override {
331 bool addString(
const std::string &)
override {
334 bool addStruct(
const std::string & , TLPBuilder *&newBuilder)
override {
335 newBuilder =
new TLPTrue();
338 bool close()
override {
343 struct TLPFalse :
public TLPBuilder {
344 bool addBool(
const bool)
override {
347 bool addInt(
const int)
override {
350 bool addRange(
int,
int)
override {
353 bool addDouble(
const double)
override {
356 bool addString(
const std::string &)
override {
359 bool addStruct(
const std::string & , TLPBuilder *&newBuilder)
override {
360 newBuilder =
new TLPFalse();
363 bool close()
override {
369 std::list<TLPBuilder *> builderStack;
370 std::istream &inputStream;
371 TLPTokenParser *tokenParser;
372 PluginProgress *pluginProgress;
373 std::string errorMsg;
374 int fileSize, curPos;
377 TLPParser(std::istream &inputStream, TLPBuilder *builder, PluginProgress *pluginProgress,
378 int size,
bool dispComment =
false)
379 : inputStream(inputStream), pluginProgress(pluginProgress), fileSize(size), curPos(0),
380 displayComment(dispComment) {
381 builderStack.push_front(builder);
382 builder->parser =
this;
386 while (!builderStack.empty()) {
387 TLPBuilder *builder = builderStack.front();
388 builderStack.pop_front();
390 if (builderStack.empty() || builder != builderStack.front())
395 bool formatError(
const std::string &value) {
396 std::stringstream ess;
397 ess <<
"Error when parsing '" << value.c_str() <<
"' at line " << tokenParser->curLine + 1;
401 else if (!errorMsg.empty())
402 ess << std::endl << errorMsg;
404 pluginProgress->setError(ess.str());
409 TLPTokenParser tParser(inputStream);
410 tokenParser = &tParser;
411 TLPToken currentToken;
412 TLPValue currentValue;
414 while ((currentToken = tokenParser->nextToken(currentValue, curPos)) != ENDOFSTREAM) {
415 if (curPos % 2000 == 1)
416 if (pluginProgress->progress(curPos, fileSize) !=
TLP_CONTINUE)
419 switch (currentToken) {
421 currentToken = tokenParser->nextToken(currentValue, curPos);
423 if (currentToken != STRINGTOKEN)
424 return formatError(currentValue.str);
426 TLPBuilder *newBuilder;
428 if (builderStack.front()->addStruct(currentValue.str, newBuilder)) {
429 newBuilder->parser =
this;
430 builderStack.push_front(newBuilder);
432 if (newBuilder->canRead())
433 if (!newBuilder->read(inputStream))
434 return formatError(currentValue.str);
436 return formatError(currentValue.str);
442 if (!builderStack.front()->addBool(currentValue.boolean))
443 return formatError(currentValue.str);
449 if (!builderStack.front()->addInt(currentValue.integer))
450 return formatError(currentValue.str);
456 if (!builderStack.front()->addRange(currentValue.range.first, currentValue.range.second))
457 return formatError(currentValue.str);
463 if (!builderStack.front()->addDouble(currentValue.real))
464 return formatError(currentValue.str);
470 if (!builderStack.front()->addString(currentValue.str))
471 return formatError(currentValue.str);
477 if (builderStack.front()->close()) {
478 TLPBuilder *builder = builderStack.front();
479 builderStack.pop_front();
481 if (builder != builderStack.front())
484 return formatError(currentValue.str);
489 return formatError(currentValue.str);
497 tlp::debug() <<
"Comment line:" << tokenParser->curLine <<
"->" << currentValue.str;
507 pluginProgress->progress(fileSize, fileSize);
char * getStrError()
Returns the error message associated to errno.