#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 "RooMsgService.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()
{
}
Bool_t RooStreamParser::atEOL()
{
Int_t nc(_is->peek()) ;
return (nc=='\n'||nc==-1) ;
}
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(0), 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) {
oocoutW((TObject*)0,InputArguments) << "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) {
oocoutW((TObject*)0,InputArguments) << "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()) {
oocoutW((TObject*)0,InputArguments) << _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()) {
oocoutE((TObject*)0,InputArguments) << _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()) {
oocoutE((TObject*)0,InputArguments)<< _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) {
oocoutW((TObject*)0,InputArguments) << "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 ;
}
Last change: Wed Jun 25 08:34:18 2008
Last generated: 2008-06-25 08:34
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.