Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4UIparameter << 27 // 26 // 28 // Author: Makoto Asai, 1997 << 27 // $Id: G4UIparameter.cc 79626 2014-03-10 11:18:47Z gcosmo $ 29 // ------------------------------------------- << 28 // 30 29 31 #include "G4UIparameter.hh" 30 #include "G4UIparameter.hh" 32 << 33 #include "G4Tokenizer.hh" << 34 #include "G4UIcommand.hh" << 35 #include "G4UIcommandStatus.hh" 31 #include "G4UIcommandStatus.hh" 36 #include "G4UIparsing.hh" << 32 #include "G4Tokenizer.hh" 37 #include "G4ios.hh" 33 #include "G4ios.hh" >> 34 #include <sstream> 38 35 39 // ------------------------------------------- << 36 40 G4UIparameter::G4UIparameter(char theType) << 37 G4UIparameter::G4UIparameter():paramERR(0) 41 { 38 { >> 39 G4String nullString; >> 40 parameterName = nullString; >> 41 parameterType = '\0'; >> 42 omittable = false; >> 43 parameterGuidance = nullString; >> 44 defaultValue = nullString; >> 45 parameterRange = nullString; >> 46 currentAsDefaultFlag = false; >> 47 parameterCandidate = nullString; >> 48 widget = 0; >> 49 bp = 0; >> 50 token = NONE; >> 51 } >> 52 >> 53 G4UIparameter::G4UIparameter(char theType):paramERR(0) >> 54 { >> 55 G4String nullString; >> 56 parameterName = nullString; 42 parameterType = theType; 57 parameterType = theType; >> 58 omittable = false; >> 59 parameterGuidance = nullString; >> 60 defaultValue = nullString; >> 61 parameterRange = nullString; >> 62 currentAsDefaultFlag = false; >> 63 parameterCandidate = nullString; >> 64 widget = 0; >> 65 bp = 0; >> 66 token = NONE; 43 } 67 } 44 68 45 // ------------------------------------------- << 69 G4UIparameter::G4UIparameter(const char * theName, char theType, G4bool theOmittable):paramERR(0) 46 G4UIparameter::G4UIparameter(const char* theNa << 47 { 70 { 48 parameterName = theName; 71 parameterName = theName; 49 parameterType = theType; 72 parameterType = theType; 50 omittable = theOmittable; 73 omittable = theOmittable; >> 74 G4String nullString; >> 75 parameterGuidance = nullString; >> 76 defaultValue = nullString; >> 77 parameterRange = nullString; >> 78 currentAsDefaultFlag = false; >> 79 parameterCandidate = nullString; >> 80 widget = 0; >> 81 bp = 0; >> 82 token = NONE; 51 } 83 } 52 84 53 // ------------------------------------------- << 85 G4UIparameter::~G4UIparameter() 54 G4UIparameter::~G4UIparameter() = default; << 86 { } >> 87 >> 88 G4int G4UIparameter::operator==(const G4UIparameter &right) const >> 89 { >> 90 return ( this == &right ); >> 91 } >> 92 >> 93 G4int G4UIparameter::operator!=(const G4UIparameter &right) const >> 94 { >> 95 return ( this != &right ); >> 96 } 55 97 56 // ------------------------------------------- << 57 void G4UIparameter::List() 98 void G4UIparameter::List() 58 { 99 { 59 G4cout << G4endl << "Parameter : " << parame 100 G4cout << G4endl << "Parameter : " << parameterName << G4endl; 60 if (!parameterGuidance.empty()) { << 101 if( ! parameterGuidance.isNull() ) 61 G4cout << parameterGuidance << G4endl; << 102 G4cout << parameterGuidance << G4endl ; 62 } << 63 G4cout << " Parameter type : " << parameter 103 G4cout << " Parameter type : " << parameterType << G4endl; 64 if (omittable) { << 104 if(omittable) 65 G4cout << " Omittable : True" << G4e << 105 { G4cout << " Omittable : True" << G4endl; } 66 } << 106 else 67 else { << 107 { G4cout << " Omittable : False" << G4endl; } 68 G4cout << " Omittable : False" << G4 << 108 if( currentAsDefaultFlag ) 69 } << 109 { G4cout << " Default value : taken from the current value" << G4endl; } 70 if (currentAsDefaultFlag) { << 110 else if( ! defaultValue.isNull() ) 71 G4cout << " Default value : taken from t << 111 { G4cout << " Default value : " << defaultValue << G4endl; } 72 } << 112 if( ! parameterRange.isNull() ) 73 else if (!defaultValue.empty()) { << 113 G4cout << " Parameter range : " << parameterRange << G4endl; 74 G4cout << " Default value : " << default << 114 if( ! parameterCandidate.isNull() ) 75 } << 115 G4cout << " Candidates : " << parameterCandidate << G4endl; 76 if (!rangeExpression.empty()) { << 77 G4cout << " Parameter range : " << rangeEx << 78 } << 79 if (!parameterCandidate.empty()) { << 80 G4cout << " Candidates : " << paramet << 81 } << 82 } 116 } 83 117 84 // ------------------------------------------- << 85 void G4UIparameter::SetDefaultValue(G4int theD 118 void G4UIparameter::SetDefaultValue(G4int theDefaultValue) 86 { 119 { 87 defaultValue = G4UIparsing::TtoS(theDefaultV << 120 std::ostringstream os; >> 121 os << theDefaultValue; >> 122 defaultValue = os.str(); 88 } 123 } 89 124 90 // ------------------------------------------- << 125 void G4UIparameter::SetDefaultValue(G4double theDefaultValue) 91 void G4UIparameter::SetDefaultValue(G4long the << 92 { 126 { 93 defaultValue = G4UIparsing::TtoS(theDefaultV << 127 std::ostringstream os; >> 128 os << theDefaultValue; >> 129 defaultValue = os.str(); 94 } 130 } 95 131 96 // ------------------------------------------- << 132 97 void G4UIparameter::SetDefaultValue(G4double t << 133 // ---------- CheckNewValue() related routines ----------- >> 134 #include <ctype.h> >> 135 #include "G4UItokenNum.hh" >> 136 >> 137 //#include "checkNewValue_debug.icc" >> 138 //#define DEBUG 1 >> 139 >> 140 G4int G4UIparameter:: >> 141 CheckNewValue(const char* newValue ) { >> 142 if( TypeCheck(newValue) == 0) return fParameterUnreadable; >> 143 if( ! parameterRange.isNull() ) >> 144 { if( RangeCheck(newValue) == 0 ) return fParameterOutOfRange; } >> 145 if( ! parameterCandidate.isNull() ) >> 146 { if( CandidateCheck(newValue) == 0 ) return fParameterOutOfCandidates; } >> 147 return 0; // succeeded >> 148 } >> 149 >> 150 G4int G4UIparameter:: >> 151 CandidateCheck(const char* newValue) { >> 152 G4Tokenizer candidateTokenizer(parameterCandidate); >> 153 G4String aToken; >> 154 G4int iToken = 0; >> 155 while( ! (aToken=candidateTokenizer()).isNull() ) >> 156 { >> 157 iToken++; >> 158 if(aToken==newValue) return iToken; >> 159 } >> 160 G4cerr << "parameter value (" << newValue >> 161 << ") is not listed in the candidate List." << G4endl; >> 162 return 0; >> 163 } >> 164 >> 165 G4int G4UIparameter:: >> 166 RangeCheck(const char* newValue) { >> 167 yystype result; >> 168 bp = 0; // reset buffer pointer for G4UIpGetc() >> 169 std::istringstream is(newValue); >> 170 char type = toupper( parameterType ); >> 171 switch (type) { >> 172 case 'D': { is >> newVal.D; } break; >> 173 case 'I': { is >> newVal.I; } break; >> 174 default: ; >> 175 } >> 176 // PrintToken(); // Print tokens (consumes all tokens) >> 177 token= Yylex(); >> 178 result = Expression(); >> 179 if( paramERR == 1 ) return 0; >> 180 if( result.type != CONSTINT) { >> 181 G4cerr << "Illegal Expression in parameter range." << G4endl; >> 182 return 0; >> 183 } >> 184 if ( result.I ) return 1; >> 185 G4cerr << "parameter out of range: "<< parameterRange << G4endl; >> 186 return 0; >> 187 } >> 188 >> 189 >> 190 G4int G4UIparameter:: >> 191 TypeCheck(const char* newValue) 98 { 192 { 99 defaultValue = G4UIparsing::TtoS(theDefaultV << 193 G4String newValueString(newValue); >> 194 char type = toupper( parameterType ); >> 195 switch(type) { >> 196 case 'D': >> 197 if( IsDouble(newValueString.data())== 0) { >> 198 G4cerr<<newValue<<": double value expected." >> 199 << G4endl; >> 200 return 0; >> 201 } break; >> 202 case 'I': >> 203 if( IsInt(newValueString.data(),20)== 0) { >> 204 G4cerr<<newValue<<": integer expected." >> 205 << G4endl; >> 206 return 0; >> 207 } break; >> 208 case 'S': break; >> 209 case 'B': >> 210 newValueString.toUpper(); >> 211 if ( newValueString == "Y" || newValueString == "N" >> 212 ||newValueString == "YES" || newValueString == "NO" >> 213 ||newValueString == "1" || newValueString == "0" >> 214 ||newValueString == "T" || newValueString == "F" >> 215 ||newValueString == "TRUE" || newValueString == "FALSE") >> 216 return 1; >> 217 else { >> 218 G4cerr<<newValue<<": bool expected." << G4endl; >> 219 return 0; >> 220 } >> 221 default: ; >> 222 } >> 223 return 1; 100 } 224 } 101 225 102 // ------------------------------------------- << 226 103 void G4UIparameter::SetDefaultUnit(const char* << 227 G4int G4UIparameter:: >> 228 IsInt(const char* buf, short maxDigits) // do not allow any std::ws 104 { 229 { 105 char type = (char)std::toupper(parameterType << 230 const char* p= buf; 106 if (type != 'S') { << 231 G4int length=0; 107 G4ExceptionDescription ed; << 232 if( *p == '+' || *p == '-') { ++p; } 108 ed << "This method can be used only for a << 233 if( isdigit( (G4int)(*p) )) { 109 "used to specify a unit.\n" << 234 while( isdigit( (G4int)(*p) )) { ++p; ++length; } 110 << "This parameter <" << parameterName << 235 if( *p == '\0' ) { 111 switch (type) { << 236 if( length > maxDigits) { 112 case 'D': << 237 G4cerr <<"digit length exceeds"<<G4endl; 113 ed << "double."; << 238 return 0; 114 break; << 239 } 115 case 'I': << 240 return 1; 116 ed << "integer."; << 241 } else { 117 break; << 242 // G4cerr <<"illegal character after int:"<<buf<<G4endl; 118 case 'L': << 243 } 119 ed << "long int."; << 244 } else { 120 break; << 245 // G4cerr <<"illegal int:"<<buf<<G4endl; 121 case 'B': << 246 } 122 ed << "bool."; << 247 return 0; 123 break; << 248 } >> 249 >> 250 >> 251 G4int G4UIparameter:: >> 252 ExpectExponent(const char* str) // used only by IsDouble() >> 253 { >> 254 G4int maxExplength; >> 255 if( IsInt( str, maxExplength=7 )) return 1; >> 256 else return 0; >> 257 } >> 258 >> 259 G4int G4UIparameter:: >> 260 IsDouble(const char* buf) // see state diagram for this spec. >> 261 { >> 262 const char* p= buf; >> 263 switch( *p) { >> 264 case '+': case '-': ++p; >> 265 if( isdigit(*p) ) { >> 266 while( isdigit( (G4int)(*p) )) { ++p; } >> 267 switch ( *p ) { >> 268 case '\0': return 1; //break; >> 269 case 'E': case 'e': >> 270 return ExpectExponent(++p ); //break; >> 271 case '.': ++p; >> 272 if( *p == '\0' ) return 1; >> 273 if( *p == 'e' || *p =='E' ) return ExpectExponent(++p ); >> 274 if( isdigit(*p) ) { >> 275 while( isdigit( (G4int)(*p) )) { ++p; } >> 276 if( *p == '\0' ) return 1; >> 277 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 278 } else return 0; break; >> 279 default: return 0; >> 280 } >> 281 } >> 282 if( *p == '.' ) { ++p; >> 283 if( isdigit(*p) ) { >> 284 while( isdigit( (G4int)(*p) )) { ++p; } >> 285 if( *p == '\0' ) return 1; >> 286 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 287 } >> 288 } >> 289 break; >> 290 case '.': ++p; >> 291 if( isdigit(*p) ) { >> 292 while( isdigit( (G4int)(*p) )) { ++p; } >> 293 if( *p == '\0' ) return 1; >> 294 if( *p == 'e' || *p =='E' ) return ExpectExponent(++p); >> 295 } break; >> 296 default: // digit is expected >> 297 if( isdigit(*p) ) { >> 298 while( isdigit( (G4int)(*p) )) { ++p; } >> 299 if( *p == '\0' ) return 1; >> 300 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 301 if( *p == '.' ) { ++p; >> 302 if( *p == '\0' ) return 1; >> 303 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 304 if( isdigit(*p) ) { >> 305 while( isdigit( (G4int)(*p) )) { ++p; } >> 306 if( *p == '\0' ) return 1; >> 307 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 308 } >> 309 } >> 310 } >> 311 } >> 312 return 0; >> 313 } >> 314 >> 315 >> 316 // ------------------ syntax node functions ------------------ >> 317 >> 318 yystype G4UIparameter:: >> 319 Expression(void) >> 320 { >> 321 yystype result; >> 322 #ifdef DEBUG >> 323 G4cerr << " Expression()" << G4endl; >> 324 #endif >> 325 result = LogicalORExpression(); >> 326 return result; >> 327 } >> 328 >> 329 yystype G4UIparameter:: >> 330 LogicalORExpression(void) >> 331 { >> 332 yystype result; >> 333 yystype p; >> 334 p = LogicalANDExpression(); >> 335 if( token != LOGICALOR) return p; >> 336 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 337 G4cerr << "Parameter range: illegal type at '||'" << G4endl; >> 338 paramERR = 1; >> 339 } >> 340 result.I = p.I; >> 341 while (token == LOGICALOR) >> 342 { >> 343 token = Yylex(); >> 344 p = LogicalANDExpression(); >> 345 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 346 G4cerr << "Parameter range: illegal type at '||'" <<G4endl; >> 347 paramERR = 1; >> 348 } >> 349 switch (p.type) { >> 350 case CONSTINT: >> 351 result.I += p.I; >> 352 result.type = CONSTINT; break; >> 353 case CONSTDOUBLE: >> 354 result.I += (p.D != 0.0); >> 355 result.type = CONSTINT; break; >> 356 default: >> 357 G4cerr << "Parameter range: unknown type"<<G4endl; >> 358 paramERR = 1; >> 359 } >> 360 } >> 361 return result; >> 362 } >> 363 >> 364 yystype G4UIparameter:: >> 365 LogicalANDExpression(void) >> 366 { >> 367 yystype result; >> 368 yystype p; >> 369 p = EqualityExpression(); >> 370 if( token != LOGICALAND) return p; >> 371 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 372 G4cerr << "Parameter range: illegal type at '&&'" << G4endl; >> 373 paramERR = 1; >> 374 } >> 375 result.I = p.I; >> 376 while (token == LOGICALAND) >> 377 { >> 378 token = Yylex(); >> 379 p = EqualityExpression(); >> 380 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 381 G4cerr << "Parameter range: illegal type at '&&'" << G4endl; >> 382 paramERR = 1; >> 383 } >> 384 switch (p.type) { >> 385 case CONSTINT: >> 386 result.I *= p.I; >> 387 result.type = CONSTINT; break; >> 388 case CONSTDOUBLE: >> 389 result.I *= (p.D != 0.0); >> 390 result.type = CONSTINT; break; >> 391 default: >> 392 G4cerr << "Parameter range: unknown type."<< G4endl; >> 393 paramERR = 1; >> 394 } >> 395 } >> 396 return result; >> 397 } >> 398 >> 399 >> 400 yystype G4UIparameter:: >> 401 EqualityExpression(void) >> 402 { >> 403 yystype arg1, arg2; >> 404 G4int operat; >> 405 yystype result; >> 406 #ifdef DEBUG >> 407 G4cerr << " EqualityExpression()" <<G4endl; >> 408 #endif >> 409 result = RelationalExpression(); >> 410 if( token==EQ || token==NE ) { >> 411 operat = token; >> 412 token = Yylex(); >> 413 arg1 = result; >> 414 arg2 = RelationalExpression(); >> 415 result.I = Eval2( arg1, operat, arg2 ); // semantic action >> 416 result.type = CONSTINT; >> 417 #ifdef DEBUG >> 418 G4cerr << " return code of Eval2(): " << result.I <<G4endl; >> 419 #endif >> 420 } else { >> 421 if (result.type != CONSTINT && result.type != CONSTDOUBLE) { >> 422 G4cerr << "Parameter range: error at EqualityExpression" >> 423 << G4endl; >> 424 paramERR = 1; >> 425 } >> 426 } >> 427 return result; >> 428 } >> 429 >> 430 >> 431 yystype G4UIparameter:: >> 432 RelationalExpression(void) >> 433 { >> 434 yystype arg1, arg2; >> 435 G4int operat; >> 436 yystype result; >> 437 #ifdef DEBUG >> 438 G4cerr << " RelationalExpression()" <<G4endl; >> 439 #endif >> 440 >> 441 arg1 = AdditiveExpression(); >> 442 if( token==GT || token==GE || token==LT || token==LE ) { >> 443 operat = token; >> 444 token = Yylex(); >> 445 arg2 = AdditiveExpression(); >> 446 result.I = Eval2( arg1, operat, arg2 ); // semantic action >> 447 result.type = CONSTINT; >> 448 #ifdef DEBUG >> 449 G4cerr << " return Eval2(): " << G4endl; >> 450 #endif >> 451 } else { >> 452 result = arg1; >> 453 } >> 454 #ifdef DEBUG >> 455 G4cerr <<" return RelationalExpression()" <<G4endl; >> 456 #endif >> 457 return result; >> 458 } >> 459 >> 460 yystype G4UIparameter:: >> 461 AdditiveExpression(void) >> 462 { yystype result; >> 463 result = MultiplicativeExpression(); >> 464 if( token != '+' && token != '-' ) return result; >> 465 G4cerr << "Parameter range: operator " >> 466 << (char)token >> 467 << " is not supported." << G4endl; >> 468 paramERR = 1; >> 469 return result; >> 470 } >> 471 >> 472 yystype G4UIparameter:: >> 473 MultiplicativeExpression(void) >> 474 { yystype result; >> 475 result = UnaryExpression(); >> 476 if( token != '*' && token != '/' && token != '%' ) return result; >> 477 G4cerr << "Parameter range: operator " >> 478 << (char)token >> 479 << " is not supported." << G4endl; >> 480 paramERR = 1; >> 481 return result; >> 482 } >> 483 >> 484 yystype G4UIparameter:: >> 485 UnaryExpression(void) >> 486 { >> 487 yystype result; >> 488 yystype p; >> 489 #ifdef DEBUG >> 490 G4cerr <<" UnaryExpression"<< G4endl; >> 491 #endif >> 492 switch(token) { >> 493 case '-': >> 494 token = Yylex(); >> 495 p = UnaryExpression(); >> 496 if (p.type == CONSTINT) { >> 497 result.I = - p.I; >> 498 result.type = CONSTINT; >> 499 } >> 500 if (p.type == CONSTDOUBLE) { >> 501 result.D = - p.D; >> 502 result.type = CONSTDOUBLE; >> 503 } break; >> 504 case '+': >> 505 token = Yylex(); >> 506 result = UnaryExpression(); break; >> 507 case '!': >> 508 token = Yylex(); >> 509 G4cerr << "Parameter range error: " >> 510 << "operator '!' is not supported (sorry)." >> 511 << G4endl; >> 512 paramERR = 1; >> 513 result = UnaryExpression(); break; >> 514 default: >> 515 result = PrimaryExpression(); >> 516 } >> 517 return result; >> 518 } >> 519 >> 520 >> 521 yystype G4UIparameter:: >> 522 PrimaryExpression(void) >> 523 { >> 524 yystype result; >> 525 #ifdef DEBUG >> 526 G4cerr <<" PrimaryExpression" << G4endl; >> 527 #endif >> 528 switch (token) { >> 529 case IDENTIFIER: >> 530 result.S = yylval.S; >> 531 result.type = token; >> 532 token = Yylex(); break; >> 533 case CONSTINT: >> 534 result.I = yylval.I; >> 535 result.type = token; >> 536 token= Yylex(); break; >> 537 case CONSTDOUBLE: >> 538 result.D = yylval.D; >> 539 result.type = token; >> 540 token = Yylex(); break; >> 541 case '(' : >> 542 token= Yylex(); >> 543 result = Expression(); >> 544 if( token != ')' ) { >> 545 G4cerr << " ')' expected" << G4endl; >> 546 paramERR = 1; >> 547 } >> 548 token = Yylex(); >> 549 break; >> 550 default: >> 551 return result; >> 552 } >> 553 return result; // never executed >> 554 } >> 555 >> 556 //---------------- semantic routines --------------------------------- >> 557 >> 558 G4int G4UIparameter:: >> 559 Eval2(yystype arg1, G4int op, yystype arg2) >> 560 { >> 561 if( (arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER)) { >> 562 G4cerr << parameterName >> 563 << ": meaningless comparison " >> 564 << G4int(arg1.type) << " " << G4int(arg2.type) << G4endl; >> 565 paramERR = 1; >> 566 } >> 567 char type = toupper( parameterType ); >> 568 if( arg1.type == IDENTIFIER) { >> 569 switch (type) { >> 570 case 'I': >> 571 if ( arg2.type == CONSTINT ) { >> 572 return CompareInt( newVal.I, op, arg2.I ); >> 573 } else { >> 574 G4cerr << "integer operand expected for " >> 575 << parameterRange << '.' >> 576 << G4endl; >> 577 } >> 578 break; >> 579 case 'D': >> 580 if ( arg2.type == CONSTDOUBLE ) { >> 581 return CompareDouble( newVal.D, op, arg2.D ); >> 582 } else >> 583 if ( arg2.type == CONSTINT ) { // integral promotion >> 584 return CompareDouble( newVal.D, op, arg2.I ); >> 585 } break; >> 586 default: ; >> 587 } >> 588 } >> 589 if( arg2.type == IDENTIFIER) { >> 590 switch (type) { >> 591 case 'I': >> 592 if ( arg1.type == CONSTINT ) { >> 593 return CompareInt( arg1.I, op, newVal.I ); >> 594 } else { >> 595 G4cerr << "integer operand expected for " >> 596 << parameterRange << '.' >> 597 << G4endl; >> 598 } >> 599 break; >> 600 case 'D': >> 601 if ( arg1.type == CONSTDOUBLE ) { >> 602 return CompareDouble( arg1.D, op, newVal.D ); >> 603 } else >> 604 if ( arg1.type == CONSTINT ) { // integral promotion >> 605 return CompareDouble( arg1.I, op, newVal.D ); >> 606 } break; >> 607 default: ; >> 608 } >> 609 } >> 610 G4cerr << "no param name is specified at the param range."<<G4endl; >> 611 return 0; >> 612 } >> 613 >> 614 G4int G4UIparameter:: >> 615 CompareInt(G4int arg1, G4int op, G4int arg2) >> 616 { >> 617 G4int result=-1; >> 618 G4String opr; >> 619 switch (op) { >> 620 case GT: result = ( arg1 > arg2); opr= ">" ; break; >> 621 case GE: result = ( arg1 >= arg2); opr= ">="; break; >> 622 case LT: result = ( arg1 < arg2); opr= "<" ; break; >> 623 case LE: result = ( arg1 <= arg2); opr= "<="; break; >> 624 case EQ: result = ( arg1 == arg2); opr= "=="; break; >> 625 case NE: result = ( arg1 != arg2); opr= "!="; break; >> 626 default: >> 627 G4cerr << "Parameter range: error at CompareInt" << G4endl; >> 628 paramERR = 1; >> 629 } >> 630 #ifdef DEBUG >> 631 G4cerr << "CompareInt " >> 632 << arg1 << " " << opr << arg2 >> 633 << " result: " << result >> 634 << G4endl; >> 635 #endif >> 636 return result; >> 637 } >> 638 >> 639 G4int G4UIparameter:: >> 640 CompareDouble(G4double arg1, G4int op, G4double arg2) >> 641 { >> 642 G4int result=-1; >> 643 G4String opr; >> 644 switch (op) { >> 645 case GT: result = ( arg1 > arg2); opr= ">"; break; >> 646 case GE: result = ( arg1 >= arg2); opr= ">="; break; >> 647 case LT: result = ( arg1 < arg2); opr= "<"; break; >> 648 case LE: result = ( arg1 <= arg2); opr= "<="; break; >> 649 case EQ: result = ( arg1 == arg2); opr= "=="; break; >> 650 case NE: result = ( arg1 != arg2); opr= "!="; break; >> 651 default: >> 652 G4cerr << "Parameter range: error at CompareDouble" << G4endl; >> 653 paramERR = 1; >> 654 } >> 655 #ifdef DEBUG >> 656 G4cerr << "CompareDouble " >> 657 << arg1 <<" " << opr << " "<< arg2 >> 658 << " result: " << result >> 659 << G4endl; >> 660 #endif >> 661 return result; >> 662 } >> 663 >> 664 // --------------------- utility functions -------------------------- >> 665 >> 666 tokenNum G4UIparameter:: >> 667 Yylex() // reads input and returns token number KR486 >> 668 { // (returns EOF) >> 669 G4int c; >> 670 G4String buf; >> 671 >> 672 while(( c= G4UIpGetc())==' '|| c=='\t' || c== '\n' ) >> 673 ; >> 674 if (c== EOF) >> 675 return (tokenNum)EOF; // KR488 >> 676 buf= ""; >> 677 if (isdigit(c) || c== '.') { // I or D >> 678 do { >> 679 buf += G4String((unsigned char)c); >> 680 c=G4UIpGetc(); >> 681 } while (c=='.' || isdigit(c) || >> 682 c=='e' || c=='E' || c=='+' || c=='-'); >> 683 G4UIpUngetc(c); >> 684 const char* t = buf; >> 685 std::istringstream is(t); >> 686 if ( IsInt(buf.data(),20) ) { >> 687 is >> yylval.I; >> 688 return CONSTINT; >> 689 } else >> 690 if ( IsDouble(buf.data()) ) { >> 691 is >> yylval.D; >> 692 return CONSTDOUBLE; >> 693 } else { >> 694 G4cerr << buf<<": numeric format error."<<G4endl; >> 695 } >> 696 } >> 697 buf=""; >> 698 if (isalpha(c)|| c=='_') { // IDENTIFIER >> 699 do { >> 700 buf += G4String((unsigned char)c); >> 701 } while ((c=G4UIpGetc()) != EOF && (isalnum(c) || c=='_')); >> 702 G4UIpUngetc(c); >> 703 if( buf == parameterName ) { >> 704 yylval.S =buf; >> 705 return IDENTIFIER; >> 706 } else { >> 707 G4cerr << buf << " is not a parameter name."<< G4endl; >> 708 paramERR = 1; >> 709 } >> 710 } >> 711 switch (c) { >> 712 case '>': return (tokenNum) Follow('=', GE, GT); >> 713 case '<': return (tokenNum) Follow('=', LE, LT); >> 714 case '=': return (tokenNum) Follow('=', EQ, '='); >> 715 case '!': return (tokenNum) Follow('=', NE, '!'); >> 716 case '|': return (tokenNum) Follow('|', LOGICALOR, '|'); >> 717 case '&': return (tokenNum) Follow('&', LOGICALAND, '&'); 124 default: 718 default: 125 ed << "undefined."; << 719 return (tokenNum) c; >> 720 } >> 721 } >> 722 >> 723 >> 724 G4int G4UIparameter:: >> 725 Follow(G4int expect, G4int ifyes, G4int ifno) >> 726 { >> 727 G4int c = G4UIpGetc(); >> 728 if ( c== expect) >> 729 return ifyes; >> 730 G4UIpUngetc(c); >> 731 return ifno; >> 732 } >> 733 >> 734 //------------------ low level routines ----------------------------- >> 735 G4int G4UIparameter:: >> 736 G4UIpGetc() { // emulation of getc() >> 737 G4int length = parameterRange.length(); >> 738 if( bp < length) >> 739 return parameterRange(bp++); >> 740 else >> 741 return EOF; >> 742 } >> 743 G4int G4UIparameter:: >> 744 G4UIpUngetc(G4int c) { // emulation of ungetc() >> 745 if (c<0) return -1; >> 746 if (bp >0 && c == parameterRange(bp-1)) { >> 747 --bp; >> 748 } else { >> 749 G4cerr << "G4UIpUngetc() failed." << G4endl; >> 750 G4cerr << "bp="<<bp <<" c="<<c >> 751 << " pR(bp-1)=" << parameterRange(bp-1) >> 752 << G4endl; >> 753 paramERR = 1; >> 754 return -1; 126 } 755 } 127 G4Exception("G4UIparameter::SetDefaultUnit << 756 return 0; 128 } << 129 SetDefaultValue(theDefaultUnit); << 130 SetParameterCandidates(G4UIcommand::UnitsLis << 131 } << 132 << 133 // ---------- CheckNewValue() related routines << 134 << 135 G4int G4UIparameter::CheckNewValue(const char* << 136 { << 137 if (!TypeCheck(newValue)) { << 138 return fParameterUnreadable; << 139 } << 140 if (!G4UIparsing::RangeCheck(*this, newValue << 141 return fParameterOutOfRange; << 142 } << 143 if (!CandidateCheck(newValue)) { << 144 return fParameterOutOfCandidates; << 145 } << 146 return 0; // succeeded << 147 } << 148 << 149 // ------------------------------------------- << 150 G4bool G4UIparameter::CandidateCheck(const cha << 151 { << 152 if (parameterCandidate.empty()) { << 153 return true; << 154 } << 155 << 156 G4Tokenizer candidateTokenizer(parameterCand << 157 G4String aToken; << 158 while (!(aToken = candidateTokenizer()).empt << 159 if (aToken == newValue) { << 160 return true; << 161 } << 162 } << 163 G4cerr << "parameter value (" << newValue << << 164 G4cerr << " Candidates are:"; << 165 G4Tokenizer candidateListTokenizer(parameter << 166 while (!(aToken = candidateListTokenizer()). << 167 G4cerr << ' ' << aToken; << 168 } << 169 G4cerr << G4endl; << 170 << 171 return false; << 172 } << 173 << 174 // ------------------------------------------- << 175 G4bool G4UIparameter::TypeCheck(const char* ne << 176 { << 177 G4String newValueString(newValue); << 178 char type = (char)std::toupper(parameterType << 179 switch (type) { << 180 case 'D': << 181 if (!G4UIparsing::IsDouble(newValueStrin << 182 G4cerr << newValue << ": double value << 183 return false; << 184 } << 185 break; << 186 case 'I': << 187 if (!G4UIparsing::IsInt(newValueString.d << 188 G4cerr << newValue << ": integer expec << 189 return false; << 190 } << 191 break; << 192 case 'L': << 193 if (!G4UIparsing::IsInt(newValueString.d << 194 G4cerr << newValue << ": long int expe << 195 return false; << 196 } << 197 break; << 198 case 'S': << 199 break; << 200 case 'B': << 201 G4StrUtil::to_upper(newValueString); << 202 if (newValueString == "Y" || newValueStr << 203 || newValueString == "NO" || newValu << 204 || newValueString == "T" || newValue << 205 || newValueString == "FALSE") << 206 { << 207 return true; << 208 } << 209 << 210 G4cerr << newValue << ": bool expected." << 211 return false; << 212 << 213 default:; << 214 } << 215 return true; << 216 } 757 } >> 758 // ***** end of CheckNewValue() related code ****** >> 759 217 760