54 ClassImp(RooStreamParser);
60 RooStreamParser::RooStreamParser(istream& is) :
61 _is(&is), _atEOL(kFALSE), _atEOF(kFALSE), _prefix(
""), _punct(
"()[]<>|/\\:?.,=+-&^%$#@!`~")
70 RooStreamParser::RooStreamParser(istream& is,
const TString& errorPrefix) :
71 _is(&is), _atEOL(kFALSE), _atEOF(kFALSE), _prefix(errorPrefix), _punct(
"()[]<>|/\\:?.,=+-&^%$#@!`~")
80 RooStreamParser::~RooStreamParser()
89 Bool_t RooStreamParser::atEOL()
91 Int_t nc(_is->peek()) ;
92 return (nc==
'\n'||nc==-1) ;
100 void RooStreamParser::setPunctuation(
const TString& punct)
110 Bool_t RooStreamParser::isPunctChar(
char c)
const
112 const char* punct = _punct.Data() ;
113 for (
int i=0 ; i<_punct.Length() ; i++)
130 TString RooStreamParser::readToken()
133 Bool_t first(kTRUE), quotedString(kFALSE), lineCont(kFALSE) ;
134 char buffer[64000], c(0), cnext =
'\0', cprev =
' ';
135 Bool_t haveINF(kFALSE) ;
139 if (_is->eof() || _is->fail()) {
145 if (_is->peek()==
'\n') {
149 while (_is->peek()==
'#') {
157 if (bufptr >= 63999) {
158 oocoutW((TObject *)0, InputArguments)
159 <<
"RooStreamParser::readToken: token length exceeds buffer capacity, terminating token early" << endl;
169 if (_is->eof() || _is->fail() || c==
'\n')
break ;
182 if (c ==
'.' || c==
'-' || c==
'+' || c==
'/' || c==
'\\') {
186 if (cnext==
'I' || cnext==
'i') {
192 haveINF = ((cnext==
'I' && tmp1 ==
'N' && tmp2 ==
'F') || (cnext==
'i' && tmp1 ==
'n' && tmp2 ==
'f')) ;
197 _is->putback(cnext) ;
202 if (c==
'\\' && cnext==
'\\') {
211 if (c==
'/' && cnext==
'/') {
220 }
else if (!quotedString) {
229 if (isPunctChar(c) && !(c==
'.' && (isdigit(cnext)||isdigit(cprev)))
230 && !((c==
'-'||c==
'+') && isdigit(cnext) && cprev==
'e')
231 && (!first || !((c==
'-'||c==
'+') && (isdigit(cnext)||cnext==
'.'||haveINF)))) {
247 if (c==
'"' && !first) {
249 quotedString=kFALSE ;
260 if (_is->eof() || _is->bad()) {
266 oocoutW((TObject*)0,InputArguments) <<
"RooStreamParser::readToken: closing quote (\") missing" << endl ;
277 while ((isspace(c) || c==
'/') && c !=
'\n') {
280 if (_is->peek()==
'/') {
294 if (bufptr==0 && lineCont) {
300 return TString(buffer) ;
310 TString RooStreamParser::readLine()
312 char c, buffer[64000];
315 if (_is->peek() ==
'\n')
319 _is->getline(buffer, nfree,
'\n');
322 char *pcontseq = strstr(buffer,
"\\\\");
324 nfree -= (pcontseq - buffer);
326 _is->getline(pcontseq, nfree,
'\n');
328 char *nextpcontseq = strstr(pcontseq,
"\\\\");
330 nfree -= (nextpcontseq - pcontseq);
331 pcontseq = nextpcontseq;
335 char *pcomment = strstr(buffer,
"//") ;
336 if (pcomment) *pcomment=0 ;
339 char *pstart=buffer ;
340 while (isspace(*pstart)) {
343 char *pend=buffer+strlen(buffer)-1 ;
345 while (isspace(*pend)) { *pend--=0 ; }
347 if (_is->eof() || _is->fail()) {
352 return TString(pstart) ;
362 void RooStreamParser::zapToEnd(Bool_t inclContLines)
365 if (_is->peek()!=
'\n') {
371 _is->getline(buffer, nfree,
'\n');
375 char *pcontseq = strstr(buffer,
"\\\\");
377 nfree -= (pcontseq - buffer);
379 _is->getline(pcontseq, nfree,
'\n');
381 char *nextpcontseq = strstr(pcontseq,
"\\\\");
383 nfree -= (nextpcontseq - pcontseq);
384 pcontseq = nextpcontseq;
398 Bool_t RooStreamParser::expectToken(
const TString& expected, Bool_t zapOnError)
400 TString token(readToken()) ;
402 Bool_t error=token.CompareTo(expected) ;
403 if (error && !_prefix.IsNull()) {
404 oocoutW((TObject*)0,InputArguments) << _prefix <<
": parse error, expected '"
405 << expected <<
"'" <<
", got '" << token <<
"'" << endl ;
406 if (zapOnError) zapToEnd(kTRUE) ;
417 Bool_t RooStreamParser::readDouble(Double_t& value, Bool_t )
419 TString token(readToken()) ;
420 if (token.IsNull())
return kTRUE ;
421 return convertToDouble(token,value) ;
430 Bool_t RooStreamParser::convertToDouble(
const TString& token, Double_t& value)
433 const char* data=token.Data() ;
436 if (!strcasecmp(data,
"inf") || !strcasecmp(data+1,
"inf")) {
437 value = (data[0]==
'-') ? -RooNumber::infinity() : RooNumber::infinity() ;
441 value = strtod(data,&endptr) ;
442 Bool_t error = (endptr-data!=token.Length()) ;
444 if (error && !_prefix.IsNull()) {
445 oocoutE((TObject*)0,InputArguments) << _prefix <<
": parse error, cannot convert '"
446 << token <<
"'" <<
" to double precision" << endl ;
457 Bool_t RooStreamParser::readInteger(Int_t& value, Bool_t )
459 TString token(readToken()) ;
460 if (token.IsNull())
return kTRUE ;
461 return convertToInteger(token,value) ;
470 Bool_t RooStreamParser::convertToInteger(
const TString& token, Int_t& value)
473 const char* data=token.Data() ;
474 value = strtol(data,&endptr,10) ;
475 Bool_t error = (endptr-data!=token.Length()) ;
477 if (error && !_prefix.IsNull()) {
478 oocoutE((TObject*)0,InputArguments)<< _prefix <<
": parse error, cannot convert '"
479 << token <<
"'" <<
" to integer" << endl ;
491 Bool_t RooStreamParser::readString(TString& value, Bool_t )
493 TString token(readToken()) ;
494 if (token.IsNull())
return kTRUE ;
495 return convertToString(token,value) ;
503 Bool_t RooStreamParser::convertToString(
const TString& token, TString&
string)
506 char buffer[64000], *ptr;
507 strncpy(buffer, token.Data(), 63999);
508 if (token.Length() >= 63999) {
509 oocoutW((TObject *)0, InputArguments) <<
"RooStreamParser::convertToString: token length exceeds 63999, truncated"
513 int len = strlen(buffer) ;
516 if ((len) && (buffer[len-1]==
'"'))
520 ptr=(buffer[0]==
'"') ? buffer+1 : buffer ;