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 {
53 TLPTokenParser(std::istream &i):curLine(0),is(i) {}
55 bool newLine(
char ch,
int &curPos) {
71 TLPToken nextToken(TLPValue &val,
int &curPos) {
73 bool endOfStream=
false,strGet=
false,slashMode=
false,started=
false,stop=
false,strComment=
false;
76 while ( (!stop) && (endOfStream=!(is.get(ch).fail()))) {
83 if (!newLine(ch, curPos))
135 if (!newLine(ch, curPos))
150 if (started) stop=
true;
156 if (!newLine(ch, curPos))
159 if (started) stop=
true;
164 if (!started)
return OPENTOKEN;
174 if (!started)
return CLOSETOKEN;
214 if (!started && !endOfStream)
return ENDOFSTREAM;
217 const char *cstr = val.str.c_str();
219 long resultl= strtol(cstr, &endPtr, 10);
224 unsigned long strlength = val.str.length();
226 if (endPtr==(cstr+ strlength)) {
232 if (endPtr > cstr && (cstr + strlength) > (endPtr + 2)) {
233 val.range.first = resultl;
235 if ((endPtr[0] ==
'.') && (endPtr[1] ==
'.')) {
236 char* beginPtr = endPtr + 2;
238 resultl = strtol(beginPtr, &endPtr, 10);
243 if (endPtr == (cstr + strlength)) {
244 if (resultl < val.range.first)
247 val.range.second = resultl;
255 double resultd=strtod(cstr, &endPtr);
260 if (endPtr==(cstr + strlength)) {
265 if (strcasecmp(cstr,
"true")==0) {
270 if (strcasecmp(cstr,
"false")==0) {
275 if (started)
return STRINGTOKEN;
282 virtual ~TLPBuilder() {}
283 virtual bool addBool(
const bool)=0;
284 virtual bool addInt(
const int)=0;
285 virtual bool addRange(
int,
int)=0;
286 virtual bool addDouble(
const double)=0;
287 virtual bool addString(
const std::string &)=0;
288 virtual bool addStruct(
const std::string&,TLPBuilder*&)=0;
289 virtual bool close() =0;
290 virtual bool canRead() {
293 virtual bool read(std::istream&) {
298 struct TLPTrue:
public TLPBuilder {
299 bool addBool(
const bool) {
302 bool addInt(
const int) {
305 bool addRange(
int,
int) {
308 bool addDouble(
const double) {
311 bool addString(
const std::string &) {
314 bool addStruct(
const std::string& , TLPBuilder*&newBuilder) {
315 newBuilder=
new TLPTrue();
323 struct TLPFalse:
public TLPBuilder {
324 bool addBool(
const bool) {
327 bool addInt(
const int) {
330 bool addRange(
int,
int) {
333 bool addDouble(
const double) {
336 bool addString(
const std::string &) {
339 bool addStruct(
const std::string& , TLPBuilder*&newBuilder) {
340 newBuilder=
new TLPFalse();
348 template <
bool displayComment>
350 std::list<TLPBuilder *> builderStack;
351 std::istream &inputStream;
352 TLPTokenParser *tokenParser;
353 PluginProgress *pluginProgress;
356 TLPParser(std::istream &inputStream,TLPBuilder *builder,PluginProgress *pluginProgress,
int size): inputStream(inputStream),
357 pluginProgress(pluginProgress),
360 builderStack.push_front(builder);
364 while (!builderStack.empty()) {
365 TLPBuilder *builder = builderStack.front();
366 builderStack.pop_front();
368 if (builderStack.empty() || builder != builderStack.front())
373 bool formatError(
const std::string& value) {
374 std::stringstream ess;
375 ess <<
"Error when parsing '" << value.c_str()
376 <<
"' at line " << tokenParser->curLine + 1;
379 ess << std::endl << strerror(errno);
381 pluginProgress->setError(ess.str());
386 TLPTokenParser tParser(inputStream);
387 tokenParser= &tParser;
388 TLPToken currentToken;
389 TLPValue currentValue;
391 while ((currentToken=tokenParser->nextToken(currentValue,curPos))!=ENDOFSTREAM) {
392 if (curPos%2000==1)
if (pluginProgress->progress(curPos,fileSize)!=
TLP_CONTINUE)
395 switch (currentToken) {
397 currentToken=tokenParser->nextToken(currentValue, curPos);
399 if (currentToken!=STRINGTOKEN)
400 return formatError(currentValue.str);
402 TLPBuilder *newBuilder;
404 if (builderStack.front()->addStruct(currentValue.str, newBuilder)) {
405 builderStack.push_front(newBuilder);
407 if (newBuilder->canRead())
408 if (!newBuilder->read(inputStream))
409 return formatError(currentValue.str);
412 return formatError(currentValue.str);
418 if (!builderStack.front()->addBool(currentValue.boolean))
419 return formatError(currentValue.str);
425 if (!builderStack.front()->addInt(currentValue.integer))
426 return formatError(currentValue.str);
432 if (!builderStack.front()->addRange(currentValue.range.first,
433 currentValue.range.second))
434 return formatError(currentValue.str);
440 if (!builderStack.front()->addDouble(currentValue.real))
441 return formatError(currentValue.str);
447 if (!builderStack.front()->addString(currentValue.str))
448 return formatError(currentValue.str);
454 if (builderStack.front()->close()) {
455 TLPBuilder * builder = builderStack.front();
456 builderStack.pop_front();
458 if (builder != builderStack.front())
462 return formatError(currentValue.str);
467 return formatError(currentValue.str);
474 if (displayComment) tlp::debug() <<
"Comment line:" << tokenParser->curLine <<
"->" << currentValue.str;
484 pluginProgress->progress(fileSize,fileSize);
492 #endif // TLPPARSER_H