00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "RooFit.h"
00038
00039 #include "Riostream.h"
00040 #include "Riostream.h"
00041 #include <stdlib.h>
00042 #include <ctype.h>
00043
00044 #ifndef _WIN32
00045 #include <strings.h>
00046 #endif
00047
00048 #include "RooStreamParser.h"
00049 #include "RooMsgService.h"
00050 #include "RooNumber.h"
00051
00052
00053 ClassImp(RooStreamParser)
00054
00055
00056
00057 RooStreamParser::RooStreamParser(istream& is) :
00058 _is(&is), _atEOL(kFALSE), _atEOF(kFALSE), _prefix(""), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
00059 {
00060
00061 }
00062
00063
00064
00065 RooStreamParser::RooStreamParser(istream& is, const TString& errorPrefix) :
00066 _is(&is), _atEOL(kFALSE), _atEOF(kFALSE), _prefix(errorPrefix), _punct("()[]<>|/\\:?.,=+-&^%$#@!`~")
00067 {
00068
00069
00070 }
00071
00072
00073
00074
00075 RooStreamParser::~RooStreamParser()
00076 {
00077
00078 }
00079
00080
00081
00082
00083 Bool_t RooStreamParser::atEOL()
00084 {
00085
00086
00087 Int_t nc(_is->peek()) ;
00088 return (nc=='\n'||nc==-1) ;
00089 }
00090
00091
00092
00093
00094 void RooStreamParser::setPunctuation(const TString& punct)
00095 {
00096
00097
00098 _punct = punct ;
00099 }
00100
00101
00102
00103
00104 Bool_t RooStreamParser::isPunctChar(char c) const
00105 {
00106
00107
00108 const char* punct = _punct.Data() ;
00109 for (int i=0 ; i<_punct.Length() ; i++)
00110 if (punct[i] == c) {
00111 return kTRUE ;
00112 }
00113 return kFALSE ;
00114 }
00115
00116
00117
00118
00119 TString RooStreamParser::readToken()
00120 {
00121
00122
00123
00124
00125
00126
00127
00128
00129 Bool_t first(kTRUE), quotedString(kFALSE), lineCont(kFALSE) ;
00130 char buffer[10240], c(0), cnext, cprev=' ' ;
00131 Int_t bufptr(0) ;
00132
00133
00134 if (_is->eof() || _is->fail()) {
00135 _atEOF = kTRUE ;
00136 return TString("") ;
00137 }
00138
00139
00140 if (_is->peek()=='\n') {
00141 _is->get(c) ;
00142
00143
00144 while (_is->peek()=='#') {
00145 zapToEnd(kFALSE) ;
00146 _is->get(c) ;
00147 }
00148 }
00149
00150 while(1) {
00151
00152 if (bufptr>=10239) {
00153 oocoutW((TObject*)0,InputArguments) << "RooStreamParser::readToken: token length exceeds buffer capacity, terminating token early" << endl ;
00154 break ;
00155 }
00156
00157
00158 _is->get(c) ;
00159
00160
00161
00162 if (_is->eof() || _is->fail() || c=='\n') break ;
00163
00164
00165 if (isspace(c)) {
00166 if (first)
00167 continue ;
00168 else
00169 if (!quotedString) {
00170 break ;
00171 }
00172 }
00173
00174
00175 if (c == '.' || c=='-' || c=='+' || c=='/' || c=='\\') {
00176 _is->get(cnext) ;
00177 _is->putback(cnext) ;
00178 }
00179
00180
00181 if (c=='\\' && cnext=='\\') {
00182
00183 zapToEnd(kFALSE) ;
00184 _is->get(c) ;
00185 lineCont=kTRUE ;
00186 break ;
00187 }
00188
00189
00190 if (c=='/' && cnext=='/') {
00191 zapToEnd(kFALSE) ;
00192 break ;
00193 }
00194
00195
00196 if (c=='"') {
00197 if (first) {
00198 quotedString=kTRUE ;
00199 } else if (!quotedString) {
00200
00201 _is->putback('"') ;
00202 break ;
00203 }
00204 }
00205
00206 if (!quotedString) {
00207
00208 if (isPunctChar(c) && !(c=='.' && (isdigit(cnext)||isdigit(cprev)))
00209 && !((c=='-'||c=='+') && (isdigit(cnext)||cnext=='.'||cnext=='i'||cnext=='I'))) {
00210 if (first) {
00211
00212 buffer[bufptr++]=c ;
00213 break ;
00214 } else {
00215
00216 _is->putback(c) ;
00217 break ;
00218 }
00219 }
00220 } else {
00221
00222
00223
00224 if (c=='"' && !first) {
00225 buffer[bufptr++]=c ;
00226 quotedString=kFALSE ;
00227 break ;
00228 }
00229 }
00230
00231
00232 buffer[bufptr++]=c ;
00233 first=kFALSE ;
00234 cprev=c ;
00235 }
00236
00237 if (_is->eof() || _is->bad()) {
00238 _atEOF = kTRUE ;
00239 }
00240
00241
00242 if (quotedString) {
00243 oocoutW((TObject*)0,InputArguments) << "RooStreamParser::readToken: closing quote (\") missing" << endl ;
00244 }
00245
00246
00247 if (c=='\n') {
00248 if (!lineCont) {
00249 _is->putback(c) ;
00250 }
00251 } else {
00252 c = _is->peek() ;
00253
00254 while ((isspace(c) || c=='/') && c != '\n') {
00255 if (c=='/') {
00256 _is->get(c) ;
00257 if (_is->peek()=='/') {
00258 zapToEnd(kFALSE) ;
00259 } else {
00260 _is->putback('/') ;
00261 }
00262 break ;
00263 } else {
00264 _is->get(c) ;
00265 c = _is->peek() ;
00266 }
00267 }
00268 }
00269
00270
00271 if (bufptr==0 && lineCont) {
00272 return readToken() ;
00273 }
00274
00275
00276 buffer[bufptr]=0 ;
00277 return TString(buffer) ;
00278 }
00279
00280
00281
00282
00283 TString RooStreamParser::readLine()
00284 {
00285
00286
00287
00288
00289 char c,buffer[10240] ;
00290 Int_t nfree(10239) ;
00291
00292 if (_is->peek()=='\n') _is->get(c) ;
00293
00294
00295 _is->getline(buffer,nfree,'\n') ;
00296
00297
00298 char *pcontseq = strstr(buffer,"\\\\") ;
00299 if (pcontseq) nfree -= (pcontseq-buffer) ;
00300 while(pcontseq) {
00301 _is->getline(pcontseq,nfree,'\n') ;
00302
00303 char* nextpcontseq = strstr(pcontseq,"\\\\") ;
00304 if (nextpcontseq) nfree -= (nextpcontseq-pcontseq) ;
00305 pcontseq = nextpcontseq ;
00306 }
00307
00308
00309 char *pcomment = strstr(buffer,"//") ;
00310 if (pcomment) *pcomment=0 ;
00311
00312
00313 char *pstart=buffer ;
00314 while (isspace(*pstart)) {
00315 pstart++ ;
00316 }
00317 char *pend=buffer+strlen(buffer)-1 ;
00318 if (pend>pstart)
00319 while (isspace(*pend)) { *pend--=0 ; }
00320
00321 if (_is->eof() || _is->fail()) {
00322 _atEOF = kTRUE ;
00323 }
00324
00325
00326 return TString(pstart) ;
00327 }
00328
00329
00330
00331
00332 void RooStreamParser::zapToEnd(Bool_t inclContLines)
00333 {
00334
00335
00336
00337
00338
00339 if (_is->peek()!='\n') {
00340
00341 char buffer[10240] ;
00342 Int_t nfree(10239) ;
00343
00344
00345 _is->getline(buffer,nfree,'\n') ;
00346
00347 if (inclContLines) {
00348
00349 char *pcontseq = strstr(buffer,"\\\\") ;
00350 if (pcontseq) nfree -= (pcontseq-buffer) ;
00351 while(pcontseq) {
00352 _is->getline(pcontseq,nfree,'\n') ;
00353
00354 char* nextpcontseq = strstr(pcontseq,"\\\\") ;
00355 if (nextpcontseq) nfree -= (nextpcontseq-pcontseq) ;
00356 pcontseq = nextpcontseq ;
00357 }
00358 }
00359
00360
00361 _is->putback('\n') ;
00362 }
00363 }
00364
00365
00366
00367
00368 Bool_t RooStreamParser::expectToken(const TString& expected, Bool_t zapOnError)
00369 {
00370
00371
00372 TString token(readToken()) ;
00373
00374 Bool_t error=token.CompareTo(expected) ;
00375 if (error && !_prefix.IsNull()) {
00376 oocoutW((TObject*)0,InputArguments) << _prefix << ": parse error, expected '"
00377 << expected << "'" << ", got '" << token << "'" << endl ;
00378 if (zapOnError) zapToEnd(kTRUE) ;
00379 }
00380 return error ;
00381 }
00382
00383
00384
00385
00386 Bool_t RooStreamParser::readDouble(Double_t& value, Bool_t )
00387 {
00388
00389
00390
00391 TString token(readToken()) ;
00392 if (token.IsNull()) return kTRUE ;
00393 return convertToDouble(token,value) ;
00394
00395 }
00396
00397
00398
00399
00400 Bool_t RooStreamParser::convertToDouble(const TString& token, Double_t& value)
00401 {
00402
00403
00404 char* endptr = 0;
00405 const char* data=token.Data() ;
00406
00407
00408 if (!strcasecmp(data,"inf") || !strcasecmp(data+1,"inf")) {
00409 value = (data[0]=='-') ? -RooNumber::infinity() : RooNumber::infinity() ;
00410 return kFALSE ;
00411 }
00412
00413 value = strtod(data,&endptr) ;
00414 Bool_t error = (endptr-data!=token.Length()) ;
00415
00416 if (error && !_prefix.IsNull()) {
00417 oocoutE((TObject*)0,InputArguments) << _prefix << ": parse error, cannot convert '"
00418 << token << "'" << " to double precision" << endl ;
00419 }
00420 return error ;
00421 }
00422
00423
00424
00425
00426 Bool_t RooStreamParser::readInteger(Int_t& value, Bool_t )
00427 {
00428
00429
00430
00431 TString token(readToken()) ;
00432 if (token.IsNull()) return kTRUE ;
00433 return convertToInteger(token,value) ;
00434 }
00435
00436
00437
00438
00439 Bool_t RooStreamParser::convertToInteger(const TString& token, Int_t& value)
00440 {
00441
00442
00443
00444 char* endptr = 0;
00445 const char* data=token.Data() ;
00446 value = strtol(data,&endptr,10) ;
00447 Bool_t error = (endptr-data!=token.Length()) ;
00448
00449 if (error && !_prefix.IsNull()) {
00450 oocoutE((TObject*)0,InputArguments)<< _prefix << ": parse error, cannot convert '"
00451 << token << "'" << " to integer" << endl ;
00452 }
00453 return error ;
00454 }
00455
00456
00457
00458
00459 Bool_t RooStreamParser::readString(TString& value, Bool_t )
00460 {
00461
00462
00463
00464
00465 TString token(readToken()) ;
00466 if (token.IsNull()) return kTRUE ;
00467 return convertToString(token,value) ;
00468 }
00469
00470
00471
00472
00473 Bool_t RooStreamParser::convertToString(const TString& token, TString& string)
00474 {
00475
00476
00477
00478 char buffer[10240],*ptr ;
00479 strncpy(buffer,token.Data(),10239) ;
00480 if (token.Length()>=10239) {
00481 oocoutW((TObject*)0,InputArguments) << "RooStreamParser::convertToString: token length exceeds 1023, truncated" << endl ;
00482 buffer[10239]=0 ;
00483 }
00484 int len = strlen(buffer) ;
00485
00486
00487 if ((len) && (buffer[len-1]=='"'))
00488 buffer[len-1]=0 ;
00489
00490
00491 ptr=(buffer[0]=='"') ? buffer+1 : buffer ;
00492
00493 string = ptr ;
00494 return kFALSE ;
00495 }