21 #ifndef DOXYGEN_NOTFOR_DEVEL 
   33   ParserError(
int err=0,
int lin=0,
int cha=0):errorNumber(err),lineInFile(lin),charInLine(cha) {}
 
   44   std::pair<long, long> range;
 
   47 enum TLPToken { BOOLTOKEN,ENDOFSTREAM,STRINGTOKEN,INTTOKEN,DOUBLETOKEN,IDTOKEN,ERRORINFILE,OPENTOKEN,CLOSETOKEN,COMMENTTOKEN,RANGETOKEN};
 
   49 struct TLPTokenParser {
 
   53   TLPTokenParser(std::istream &i):curLine(0),curChar(0),is(i) {}
 
   54   TLPToken nextToken(TLPValue &val,
int &curPos) {
 
   56     bool endOfStream=
false,strGet=
false,slashMode=
false,started=
false,stop=
false,strComment=
false;
 
   59     while ( (!stop) && (endOfStream=!(is.get(ch).fail()))) {
 
  136           if (started) stop=
true;
 
  145           if (started) stop=
true;
 
  151           if (!started) 
return OPENTOKEN;
 
  162           if (!started) 
return CLOSETOKEN;
 
  202     if (!started && !endOfStream) 
return ENDOFSTREAM;
 
  205     const char *cstr = val.str.c_str();
 
  207     long resultl= strtol(cstr, &endPtr, 10);
 
  212     unsigned long strlength = val.str.length();
 
  214     if (endPtr==(cstr+ strlength)) {
 
  220     if (endPtr > cstr && (cstr + strlength) > (endPtr + 2)) {
 
  221       val.range.first = resultl;
 
  223       if ((endPtr[0] == 
'.') && (endPtr[1] == 
'.')) {
 
  224         char* beginPtr = endPtr + 2;
 
  226         resultl = strtol(beginPtr, &endPtr, 10);
 
  231         if (endPtr == (cstr + strlength)) {
 
  232           if (resultl < val.range.first)
 
  235           val.range.second = resultl;
 
  243     double resultd=strtod(cstr, &endPtr);
 
  248     if (endPtr==(cstr + strlength)) {
 
  253     if (strcasecmp(cstr, 
"true")==0) {
 
  258     if (strcasecmp(cstr, 
"false")==0) {
 
  263     if (started) 
return STRINGTOKEN;
 
  270   virtual ~TLPBuilder() {}
 
  271   virtual bool addBool(
const bool)=0;
 
  272   virtual bool addInt(
const int)=0;
 
  273   virtual bool addRange(
int, 
int)=0;
 
  274   virtual bool addDouble(
const double)=0;
 
  275   virtual bool addString(
const std::string &)=0;
 
  276   virtual bool addStruct(
const std::string&,TLPBuilder*&)=0;
 
  277   virtual bool close() =0;
 
  278   virtual bool canRead() {
 
  281   virtual bool read(std::istream&) {
 
  286 struct TLPTrue:
public TLPBuilder {
 
  287   bool addBool(
const bool) {
 
  290   bool addInt(
const int) {
 
  293   bool addRange(
int, 
int) {
 
  296   bool addDouble(
const double) {
 
  299   bool addString(
const std::string &) {
 
  302   bool addStruct(
const std::string& , TLPBuilder*&newBuilder) {
 
  303     newBuilder=
new TLPTrue();
 
  311 struct TLPFalse:
public TLPBuilder {
 
  312   bool addBool(
const bool) {
 
  315   bool addInt(
const int) {
 
  318   bool addRange(
int, 
int) {
 
  321   bool addDouble(
const double) {
 
  324   bool addString(
const std::string &) {
 
  327   bool addStruct(
const std::string& , TLPBuilder*&newBuilder) {
 
  328     newBuilder=
new TLPFalse();
 
  336 template <
bool displayComment>
 
  338   std::list<TLPBuilder *> builderStack;
 
  339   std::istream &inputStream;
 
  340   TLPTokenParser *tokenParser;
 
  341   PluginProgress *pluginProgress;
 
  344   TLPParser(std::istream &inputStream,TLPBuilder *builder,PluginProgress *pluginProgress,
int size): inputStream(inputStream),
 
  345     pluginProgress(pluginProgress),
 
  348     builderStack.push_front(builder);
 
  352     while (!builderStack.empty()) {
 
  353       TLPBuilder *builder = builderStack.front();
 
  354       builderStack.pop_front();
 
  356       if (builderStack.empty() || builder != builderStack.front())
 
  362     std::stringstream ess;
 
  363     ess << 
"Error when parsing char " << tokenParser->curChar
 
  364         << 
" at line " << tokenParser->curLine + 1;
 
  367       ess << std::endl << strerror(errno);
 
  369     pluginProgress->setError(ess.str());
 
  374     TLPTokenParser tParser(inputStream);
 
  375     tokenParser= &tParser;
 
  376     TLPToken currentToken;
 
  377     TLPValue currentValue;
 
  379     while ((currentToken=tokenParser->nextToken(currentValue,curPos))!=ENDOFSTREAM) {
 
  380       if (curPos%2000==1) 
if (pluginProgress->progress(curPos,fileSize)!=
TLP_CONTINUE)
 
  383       switch (currentToken) {
 
  385         currentToken=tokenParser->nextToken(currentValue,curPos);
 
  387         if (currentToken!=STRINGTOKEN)
 
  388           return formatError();
 
  390         TLPBuilder *newBuilder;
 
  392         if (builderStack.front()->addStruct(currentValue.str, newBuilder)) {
 
  393           builderStack.push_front(newBuilder);
 
  395           if (newBuilder->canRead())
 
  396             if (!newBuilder->read(inputStream))
 
  397               return formatError();
 
  400           return formatError();
 
  406         if (!builderStack.front()->addBool(currentValue.boolean))
 
  407           return formatError();
 
  413         if (!builderStack.front()->addInt(currentValue.integer))
 
  414           return formatError();
 
  420         if (!builderStack.front()->addRange(currentValue.range.first,
 
  421                                             currentValue.range.second))
 
  422           return formatError();
 
  428         if (!builderStack.front()->addDouble(currentValue.real))
 
  429           return formatError();
 
  435         if (!builderStack.front()->addString(currentValue.str))
 
  436           return formatError();
 
  442         if (builderStack.front()->close()) {
 
  443           TLPBuilder * builder = builderStack.front();
 
  444           builderStack.pop_front();
 
  446           if (builder != builderStack.front())
 
  450           return formatError();
 
  455         return formatError();
 
  462         if (displayComment) tlp::debug() << 
"Comment line:" << tokenParser->curLine << 
"->" <<  currentValue.str;
 
  478 #endif // DOXYGEN_NOTFOR_DEVEL