21 #ifndef DOXYGEN_NOTFOR_DEVEL
34 ParserError(
int err=0,
int lin=0,
int cha=0):errorNumber(err),lineInFile(lin),charInLine(cha) {}
45 std::pair<long, long> range;
48 enum TLPToken { BOOLTOKEN,ENDOFSTREAM,STRINGTOKEN,INTTOKEN,DOUBLETOKEN,IDTOKEN,ERRORINFILE,OPENTOKEN,CLOSETOKEN,COMMENTTOKEN,RANGETOKEN};
50 struct TLPTokenParser {
54 TLPTokenParser(std::istream &i):curLine(0),curChar(0),is(i) {}
55 TLPToken nextToken(TLPValue &val,
int &curPos) {
57 bool endOfStream=
false,strGet=
false,slashMode=
false,started=
false,stop=
false,strComment=
false;
60 while ( (!stop) && (endOfStream=!(is.get(ch).fail()))) {
137 if (started) stop=
true;
146 if (started) stop=
true;
152 if (!started)
return OPENTOKEN;
163 if (!started)
return CLOSETOKEN;
203 if (!started && !endOfStream)
return ENDOFSTREAM;
206 const char *cstr = val.str.c_str();
208 long resultl= strtol(cstr, &endPtr, 10);
213 unsigned long strlength = val.str.length();
215 if (endPtr==(cstr+ strlength)) {
221 if (endPtr > cstr && (cstr + strlength) > (endPtr + 2)) {
222 val.range.first = resultl;
224 if ((endPtr[0] ==
'.') && (endPtr[1] ==
'.')) {
225 char* beginPtr = endPtr + 2;
227 resultl = strtol(beginPtr, &endPtr, 10);
232 if (endPtr == (cstr + strlength)) {
233 if (resultl < val.range.first)
236 val.range.second = resultl;
244 double resultd=strtod(cstr, &endPtr);
249 if (endPtr==(cstr + strlength)) {
254 if (strcasecmp(cstr,
"true")==0) {
259 if (strcasecmp(cstr,
"false")==0) {
264 if (started)
return STRINGTOKEN;
271 virtual ~TLPBuilder() {}
272 virtual bool addBool(
const bool)=0;
273 virtual bool addInt(
const int)=0;
274 virtual bool addRange(
int,
int)=0;
275 virtual bool addDouble(
const double)=0;
276 virtual bool addString(
const std::string &)=0;
277 virtual bool addStruct(
const std::string&,TLPBuilder*&)=0;
278 virtual bool close() =0;
279 virtual bool canRead() {
282 virtual bool read(std::istream&) {
287 struct TLPTrue:
public TLPBuilder {
288 bool addBool(
const bool) {
291 bool addInt(
const int) {
294 bool addRange(
int,
int) {
297 bool addDouble(
const double) {
300 bool addString(
const std::string &) {
303 bool addStruct(
const std::string& , TLPBuilder*&newBuilder) {
304 newBuilder=
new TLPTrue();
312 struct TLPFalse:
public TLPBuilder {
313 bool addBool(
const bool) {
316 bool addInt(
const int) {
319 bool addRange(
int,
int) {
322 bool addDouble(
const double) {
325 bool addString(
const std::string &) {
328 bool addStruct(
const std::string& , TLPBuilder*&newBuilder) {
329 newBuilder=
new TLPFalse();
337 template <
bool displayComment>
339 std::list<TLPBuilder *> builderStack;
340 std::istream &inputStream;
341 TLPTokenParser *tokenParser;
342 PluginProgress *pluginProgress;
345 TLPParser(std::istream &inputStream,TLPBuilder *builder,PluginProgress *pluginProgress,
int size): inputStream(inputStream),
346 pluginProgress(pluginProgress),
349 builderStack.push_front(builder);
353 while (!builderStack.empty()) {
354 TLPBuilder *builder = builderStack.front();
355 builderStack.pop_front();
357 if (builderStack.empty() || builder != builderStack.front())
363 std::stringstream ess;
364 ess <<
"Error when parsing char " << tokenParser->curChar
365 <<
" at line " << tokenParser->curLine + 1;
368 ess << std::endl << strerror(errno);
370 pluginProgress->setError(ess.str());
375 TLPTokenParser tParser(inputStream);
376 tokenParser= &tParser;
377 TLPToken currentToken;
378 TLPValue currentValue;
380 while ((currentToken=tokenParser->nextToken(currentValue,curPos))!=ENDOFSTREAM) {
381 if (curPos%2000==1)
if (pluginProgress->progress(curPos,fileSize)!=
TLP_CONTINUE)
384 switch (currentToken) {
386 currentToken=tokenParser->nextToken(currentValue,curPos);
388 if (currentToken!=STRINGTOKEN)
389 return formatError();
391 TLPBuilder *newBuilder;
393 if (builderStack.front()->addStruct(currentValue.str, newBuilder)) {
394 builderStack.push_front(newBuilder);
396 if (newBuilder->canRead())
397 if (!newBuilder->read(inputStream))
398 return formatError();
401 return formatError();
407 if (!builderStack.front()->addBool(currentValue.boolean))
408 return formatError();
414 if (!builderStack.front()->addInt(currentValue.integer))
415 return formatError();
421 if (!builderStack.front()->addRange(currentValue.range.first,
422 currentValue.range.second))
423 return formatError();
429 if (!builderStack.front()->addDouble(currentValue.real))
430 return formatError();
436 if (!builderStack.front()->addString(currentValue.str))
437 return formatError();
443 if (builderStack.front()->close()) {
444 TLPBuilder * builder = builderStack.front();
445 builderStack.pop_front();
447 if (builder != builderStack.front())
451 return formatError();
456 return formatError();
463 if (displayComment) qDebug() <<
"Comment line:" << tokenParser->curLine <<
"->" << currentValue.str;
479 #endif // DOXYGEN_NOTFOR_DEVEL