#include "RooFit.h"
#include "Riostream.h"
#include "Riostream.h"
#include <stdlib.h>
#include <ctype.h>
#ifndef _WIN32
#include <strings.h>
#endif
#include "RooStreamParser.h"
#include "RooNumber.h"
ClassImp(RooStreamParser)
RooStreamParser::RooStreamParser(istream& is) : 
  _is(is), _atEOF(kFALSE), _prefix(""), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
{
  
}
RooStreamParser::RooStreamParser(istream& is, const TString& errorPrefix) : 
  _is(is), _atEOF(kFALSE), _prefix(errorPrefix), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
{
  
}
RooStreamParser::~RooStreamParser()
{
  
}
void RooStreamParser::setPunctuation(const TString& punct) 
{
  
  _punct = punct ;
}
Bool_t RooStreamParser::isPunctChar(char c) const 
{
  
  const char* punct = _punct.Data() ;
  for (int i=0 ; i<_punct.Length() ; i++)
    if (punct[i] == c) {
      return kTRUE ;
    }
  return kFALSE ;
}
TString RooStreamParser::readToken() 
{
  
  
  Bool_t first(kTRUE), quotedString(kFALSE), lineCont(kFALSE) ;
  char buffer[10240], c, cnext, cprev=' ' ;
  Int_t bufptr(0) ;
  
   if (_is.eof() || _is.fail()) {
     _atEOF = kTRUE ;
     return TString("") ;
   }
  
  if (_is.peek()=='\n') {
    _is.get(c) ;
    
    while (_is.peek()=='#') {
      zapToEnd(kFALSE) ;
      _is.get(c) ; 
    }
  }
  while(1) {
    
    if (bufptr>=10239) {
      cout << "RooStreamParser::readToken: token length exceeds buffer capacity, terminating token early" << endl ;
      break ;
    }
    
    _is.get(c) ;
    
    
    if (_is.eof() || _is.fail() || c=='\n') break ;
    
    if (isspace(c)) {
      if (first) 
	continue ; 
      else 
	if (!quotedString) {
	  break ;
	}
    }
    
    if (c == '.' || c=='-' || c=='+' || c=='/' || c=='\\') {
      _is.get(cnext) ;
      _is.putback(cnext) ;
    }
    
    if (c=='\\' && cnext=='\\') {
      
      zapToEnd(kFALSE) ;
      _is.get(c) ;
      lineCont=kTRUE ;
      break ;
    }
    
    if (c=='/' && cnext=='/') {
      zapToEnd(kFALSE) ;
      break ;
    }
    
    if (c=='"') {
      if (first) {
	quotedString=kTRUE ;		
      } else if (!quotedString) {
	
	_is.putback('"') ;
	break ;
      }
    }
    if (!quotedString) {
      
      if (isPunctChar(c) && !(c=='.' && (isdigit(cnext)||isdigit(cprev))) 
	  && !((c=='-'||c=='+') && (isdigit(cnext)||cnext=='.'||cnext=='i'||cnext=='I'))) {
	if (first) {
	  
	  buffer[bufptr++]=c ;
	  break ;
	} else {
	  
	  _is.putback(c) ;
	  break ;
	} 
      }       
    } else {
      
      
      if (c=='"' && !first) {
	buffer[bufptr++]=c ;	
	quotedString=kFALSE ;
	break ;
      }
    }
    
    buffer[bufptr++]=c ;
    first=kFALSE ;
    cprev=c ;
  }
  if (_is.eof() || _is.bad()) {
    _atEOF = kTRUE ;
  }
  
  if (quotedString) {
    cout << "RooStreamParser::readToken: closing quote (\") missing" << endl ;
  }
  
  if (c=='\n') {
    if (!lineCont) {
      _is.putback(c) ;
    }
  } else {
    c = _is.peek() ;
    while ((isspace(c) || c=='/') && c != '\n') {
      if (c=='/') {
	_is.get(c) ;
	if (_is.peek()=='/') {
	  zapToEnd(kFALSE) ;	
	} else {
	  _is.putback('/') ;
	}
	break ;
      } else {
	_is.get(c) ;
	c = _is.peek() ;
      }
    }
  }
  
  if (bufptr==0 && lineCont) {
    return readToken() ;
  }
  
  
  buffer[bufptr]=0 ;
  return TString(buffer) ;
}
TString RooStreamParser::readLine() 
{
  
  char c,buffer[10240] ;
  Int_t nfree(10239) ; 
  
  if (_is.peek()=='\n') _is.get(c) ;
  
  _is.getline(buffer,nfree,'\n') ;
  
  char *pcontseq = strstr(buffer,"\\\\") ;
  if (pcontseq) nfree -= (pcontseq-buffer) ;
  while(pcontseq) {
    _is.getline(pcontseq,nfree,'\n') ;
    char* nextpcontseq = strstr(pcontseq,"\\\\") ;
    if (nextpcontseq) nfree -= (nextpcontseq-pcontseq) ;
    pcontseq = nextpcontseq ;
  }    
  
  char *pcomment = strstr(buffer,"//") ;
  if (pcomment) *pcomment=0 ;
  
  char *pstart=buffer ;
  while (isspace(*pstart)) {
    pstart++ ;
  }
  char *pend=buffer+strlen(buffer)-1 ;
  if (pend>pstart)
    while (isspace(*pend)) { *pend--=0 ; }
  if (_is.eof() || _is.fail()) {
    _atEOF = kTRUE ;
  }
  
  return TString(pstart) ;
}
void RooStreamParser::zapToEnd(Bool_t inclContLines) 
{
  
  if (_is.peek()!='\n') {
    char buffer[10240] ;
    Int_t nfree(10239) ; 
    
    _is.getline(buffer,nfree,'\n') ;
    if (inclContLines) {
      
      char *pcontseq = strstr(buffer,"\\\\") ;
      if (pcontseq) nfree -= (pcontseq-buffer) ;
      while(pcontseq) {
	_is.getline(pcontseq,nfree,'\n') ;
	
	char* nextpcontseq = strstr(pcontseq,"\\\\") ;
	if (nextpcontseq) nfree -= (nextpcontseq-pcontseq) ;
	pcontseq = nextpcontseq ;
      }    
    }
    
   _is.putback('\n') ;
  }
}
Bool_t RooStreamParser::expectToken(const TString& expected, Bool_t zapOnError) 
{
  
  TString token(readToken()) ;
  Bool_t error=token.CompareTo(expected) ;
  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, expected '" 
	 << expected << "'" << ", got '" << token << "'" << endl ;
    if (zapOnError) zapToEnd(kTRUE) ;
  }
  return error ;
}
Bool_t RooStreamParser::readDouble(Double_t& value, Bool_t ) 
{
  
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToDouble(token,value) ;
  
}
Bool_t RooStreamParser::convertToDouble(const TString& token, Double_t& value) 
{
  
  char* endptr = 0;
  const char* data=token.Data() ;
  
  if (!strcasecmp(data,"inf") || !strcasecmp(data+1,"inf")) {
    value = (data[0]=='-') ? -RooNumber::infinity : RooNumber::infinity ;
    return kFALSE ;
  }
  value = strtod(data,&endptr) ;
  Bool_t error = (endptr-data!=token.Length()) ;
  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, cannot convert '" 
	 << token << "'" << " to double precision" <<  endl ;
  }
  return error ;
}
Bool_t RooStreamParser::readInteger(Int_t& value, Bool_t ) 
{
  
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToInteger(token,value) ;
}
Bool_t RooStreamParser::convertToInteger(const TString& token, Int_t& value) 
{
  
  char* endptr = 0;
  const char* data=token.Data() ;
  value = strtol(data,&endptr,10) ;
  Bool_t error = (endptr-data!=token.Length()) ;
  if (error && !_prefix.IsNull()) {
    cout << _prefix << ": parse error, cannot convert '" 
	 << token << "'" << " to integer" <<  endl ;
  }
  return error ;
}
Bool_t RooStreamParser::readString(TString& value, Bool_t ) 
{
  
  TString token(readToken()) ;
  if (token.IsNull()) return kTRUE ;
  return convertToString(token,value) ;
}
Bool_t RooStreamParser::convertToString(const TString& token, TString& string) 
{
  
  
  char buffer[10240],*ptr ;
  strncpy(buffer,token.Data(),10239) ;
  if (token.Length()>=10239) {
    cout << "RooStreamParser::convertToString: token length exceeds 1023, truncated" << endl ;
    buffer[10239]=0 ;
  }
  int len = strlen(buffer) ;
  
  if ((len) && (buffer[len-1]=='"'))
    buffer[len-1]=0 ;
  
  ptr=(buffer[0]=='"') ? buffer+1 : buffer ;
  string = ptr ;
  return kFALSE ;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.