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$ 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 is not listed in the candidate List." << G4endl; >> 161 return 0; >> 162 } >> 163 >> 164 G4int G4UIparameter:: >> 165 RangeCheck(const char* newValue) { >> 166 yystype result; >> 167 bp = 0; // reset buffer pointer for G4UIpGetc() >> 168 std::istringstream is(newValue); >> 169 char type = toupper( parameterType ); >> 170 switch (type) { >> 171 case 'D': { is >> newVal.D; } break; >> 172 case 'I': { is >> newVal.I; } break; >> 173 default: ; >> 174 } >> 175 // PrintToken(); // Print tokens (consumes all tokens) >> 176 token= Yylex(); >> 177 result = Expression(); >> 178 if( paramERR == 1 ) return 0; >> 179 if( result.type != CONSTINT) { >> 180 G4cerr << "Illegal Expression in parameter range." << G4endl; >> 181 return 0; >> 182 } >> 183 if ( result.I ) return 1; >> 184 G4cerr << "parameter out of range: "<< parameterRange << G4endl; >> 185 return 0; >> 186 } >> 187 >> 188 >> 189 G4int G4UIparameter:: >> 190 TypeCheck(const char* newValue) 98 { 191 { 99 defaultValue = G4UIparsing::TtoS(theDefaultV << 192 G4String newValueString(newValue); >> 193 char type = toupper( parameterType ); >> 194 switch(type) { >> 195 case 'D': >> 196 if( IsDouble(newValueString.data())== 0) { >> 197 G4cerr<<newValue<<": double value expected." >> 198 << G4endl; >> 199 return 0; >> 200 } break; >> 201 case 'I': >> 202 if( IsInt(newValueString.data(),20)== 0) { >> 203 G4cerr<<newValue<<": integer expected." >> 204 << G4endl; >> 205 return 0; >> 206 } break; >> 207 case 'S': break; >> 208 case 'B': >> 209 newValueString.toUpper(); >> 210 if ( newValueString == "Y" || newValueString == "N" >> 211 ||newValueString == "YES" || newValueString == "NO" >> 212 ||newValueString == "1" || newValueString == "0" >> 213 ||newValueString == "T" || newValueString == "F" >> 214 ||newValueString == "TRUE" || newValueString == "FALSE") >> 215 return 1; >> 216 else { >> 217 G4cerr<<newValue<<": bool expected." << G4endl; >> 218 return 0; >> 219 } >> 220 default: ; >> 221 } >> 222 return 1; 100 } 223 } 101 224 102 // ------------------------------------------- << 225 103 void G4UIparameter::SetDefaultUnit(const char* << 226 G4int G4UIparameter:: >> 227 IsInt(const char* buf, short maxDigits) // do not allow any std::ws 104 { 228 { 105 char type = (char)std::toupper(parameterType << 229 const char* p= buf; 106 if (type != 'S') { << 230 G4int length=0; 107 G4ExceptionDescription ed; << 231 if( *p == '+' || *p == '-') { ++p; } 108 ed << "This method can be used only for a << 232 if( isdigit( (G4int)(*p) )) { 109 "used to specify a unit.\n" << 233 while( isdigit( (G4int)(*p) )) { ++p; ++length; } 110 << "This parameter <" << parameterName << 234 if( *p == '\0' ) { 111 switch (type) { << 235 if( length > maxDigits) { 112 case 'D': << 236 G4cerr <<"digit length exceeds"<<G4endl; 113 ed << "double."; << 237 return 0; 114 break; << 238 } 115 case 'I': << 239 return 1; 116 ed << "integer."; << 240 } else { 117 break; << 241 // G4cerr <<"illegal character after int:"<<buf<<G4endl; 118 case 'L': << 242 } 119 ed << "long int."; << 243 } else { 120 break; << 244 // G4cerr <<"illegal int:"<<buf<<G4endl; 121 case 'B': << 245 } 122 ed << "bool."; << 246 return 0; 123 break; << 247 } >> 248 >> 249 >> 250 G4int G4UIparameter:: >> 251 ExpectExponent(const char* str) // used only by IsDouble() >> 252 { >> 253 G4int maxExplength; >> 254 if( IsInt( str, maxExplength=7 )) return 1; >> 255 else return 0; >> 256 } >> 257 >> 258 G4int G4UIparameter:: >> 259 IsDouble(const char* buf) // see state diagram for this spec. >> 260 { >> 261 const char* p= buf; >> 262 switch( *p) { >> 263 case '+': case '-': ++p; >> 264 if( isdigit(*p) ) { >> 265 while( isdigit( (G4int)(*p) )) { ++p; } >> 266 switch ( *p ) { >> 267 case '\0': return 1; //break; >> 268 case 'E': case 'e': >> 269 return ExpectExponent(++p ); //break; >> 270 case '.': ++p; >> 271 if( *p == '\0' ) return 1; >> 272 if( *p == 'e' || *p =='E' ) return ExpectExponent(++p ); >> 273 if( isdigit(*p) ) { >> 274 while( isdigit( (G4int)(*p) )) { ++p; } >> 275 if( *p == '\0' ) return 1; >> 276 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 277 } else return 0; break; >> 278 default: return 0; >> 279 } >> 280 } >> 281 if( *p == '.' ) { ++p; >> 282 if( isdigit(*p) ) { >> 283 while( isdigit( (G4int)(*p) )) { ++p; } >> 284 if( *p == '\0' ) return 1; >> 285 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 286 } >> 287 } >> 288 break; >> 289 case '.': ++p; >> 290 if( isdigit(*p) ) { >> 291 while( isdigit( (G4int)(*p) )) { ++p; } >> 292 if( *p == '\0' ) return 1; >> 293 if( *p == 'e' || *p =='E' ) return ExpectExponent(++p); >> 294 } break; >> 295 default: // digit is expected >> 296 if( isdigit(*p) ) { >> 297 while( isdigit( (G4int)(*p) )) { ++p; } >> 298 if( *p == '\0' ) return 1; >> 299 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 300 if( *p == '.' ) { ++p; >> 301 if( *p == '\0' ) return 1; >> 302 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 303 if( isdigit(*p) ) { >> 304 while( isdigit( (G4int)(*p) )) { ++p; } >> 305 if( *p == '\0' ) return 1; >> 306 if( *p == 'e' || *p =='E') return ExpectExponent(++p); >> 307 } >> 308 } >> 309 } >> 310 } >> 311 return 0; >> 312 } >> 313 >> 314 >> 315 // ------------------ syntax node functions ------------------ >> 316 >> 317 yystype G4UIparameter:: >> 318 Expression(void) >> 319 { >> 320 yystype result; >> 321 #ifdef DEBUG >> 322 G4cerr << " Expression()" << G4endl; >> 323 #endif >> 324 result = LogicalORExpression(); >> 325 return result; >> 326 } >> 327 >> 328 yystype G4UIparameter:: >> 329 LogicalORExpression(void) >> 330 { >> 331 yystype result; >> 332 yystype p; >> 333 p = LogicalANDExpression(); >> 334 if( token != LOGICALOR) return p; >> 335 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 336 G4cerr << "Parameter range: illegal type at '||'" << G4endl; >> 337 paramERR = 1; >> 338 } >> 339 result.I = p.I; >> 340 while (token == LOGICALOR) >> 341 { >> 342 token = Yylex(); >> 343 p = LogicalANDExpression(); >> 344 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 345 G4cerr << "Parameter range: illegal type at '||'" <<G4endl; >> 346 paramERR = 1; >> 347 } >> 348 switch (p.type) { >> 349 case CONSTINT: >> 350 result.I += p.I; >> 351 result.type = CONSTINT; break; >> 352 case CONSTDOUBLE: >> 353 result.I += (p.D != 0.0); >> 354 result.type = CONSTINT; break; >> 355 default: >> 356 G4cerr << "Parameter range: unknown type"<<G4endl; >> 357 paramERR = 1; >> 358 } >> 359 } >> 360 return result; >> 361 } >> 362 >> 363 yystype G4UIparameter:: >> 364 LogicalANDExpression(void) >> 365 { >> 366 yystype result; >> 367 yystype p; >> 368 p = EqualityExpression(); >> 369 if( token != LOGICALAND) return p; >> 370 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 371 G4cerr << "Parameter range: illegal type at '&&'" << G4endl; >> 372 paramERR = 1; >> 373 } >> 374 result.I = p.I; >> 375 while (token == LOGICALAND) >> 376 { >> 377 token = Yylex(); >> 378 p = EqualityExpression(); >> 379 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) { >> 380 G4cerr << "Parameter range: illegal type at '&&'" << G4endl; >> 381 paramERR = 1; >> 382 } >> 383 switch (p.type) { >> 384 case CONSTINT: >> 385 result.I *= p.I; >> 386 result.type = CONSTINT; break; >> 387 case CONSTDOUBLE: >> 388 result.I *= (p.D != 0.0); >> 389 result.type = CONSTINT; break; >> 390 default: >> 391 G4cerr << "Parameter range: unknown type."<< G4endl; >> 392 paramERR = 1; >> 393 } >> 394 } >> 395 return result; >> 396 } >> 397 >> 398 >> 399 yystype G4UIparameter:: >> 400 EqualityExpression(void) >> 401 { >> 402 yystype arg1, arg2; >> 403 G4int operat; >> 404 yystype result; >> 405 #ifdef DEBUG >> 406 G4cerr << " EqualityExpression()" <<G4endl; >> 407 #endif >> 408 result = RelationalExpression(); >> 409 if( token==EQ || token==NE ) { >> 410 operat = token; >> 411 token = Yylex(); >> 412 arg1 = result; >> 413 arg2 = RelationalExpression(); >> 414 result.I = Eval2( arg1, operat, arg2 ); // semantic action >> 415 result.type = CONSTINT; >> 416 #ifdef DEBUG >> 417 G4cerr << " return code of Eval2(): " << result.I <<G4endl; >> 418 #endif >> 419 } else { >> 420 if (result.type != CONSTINT && result.type != CONSTDOUBLE) { >> 421 G4cerr << "Parameter range: error at EqualityExpression" >> 422 << G4endl; >> 423 paramERR = 1; >> 424 } >> 425 } >> 426 return result; >> 427 } >> 428 >> 429 >> 430 yystype G4UIparameter:: >> 431 RelationalExpression(void) >> 432 { >> 433 yystype arg1, arg2; >> 434 G4int operat; >> 435 yystype result; >> 436 #ifdef DEBUG >> 437 G4cerr << " RelationalExpression()" <<G4endl; >> 438 #endif >> 439 >> 440 arg1 = AdditiveExpression(); >> 441 if( token==GT || token==GE || token==LT || token==LE ) { >> 442 operat = token; >> 443 token = Yylex(); >> 444 arg2 = AdditiveExpression(); >> 445 result.I = Eval2( arg1, operat, arg2 ); // semantic action >> 446 result.type = CONSTINT; >> 447 #ifdef DEBUG >> 448 G4cerr << " return Eval2(): " << G4endl; >> 449 #endif >> 450 } else { >> 451 result = arg1; >> 452 } >> 453 #ifdef DEBUG >> 454 G4cerr <<" return RelationalExpression()" <<G4endl; >> 455 #endif >> 456 return result; >> 457 } >> 458 >> 459 yystype G4UIparameter:: >> 460 AdditiveExpression(void) >> 461 { yystype result; >> 462 result = MultiplicativeExpression(); >> 463 if( token != '+' && token != '-' ) return result; >> 464 G4cerr << "Parameter range: operator " >> 465 << (char)token >> 466 << " is not supported." << G4endl; >> 467 paramERR = 1; >> 468 return result; >> 469 } >> 470 >> 471 yystype G4UIparameter:: >> 472 MultiplicativeExpression(void) >> 473 { yystype result; >> 474 result = UnaryExpression(); >> 475 if( token != '*' && token != '/' && token != '%' ) return result; >> 476 G4cerr << "Parameter range: operator " >> 477 << (char)token >> 478 << " is not supported." << G4endl; >> 479 paramERR = 1; >> 480 return result; >> 481 } >> 482 >> 483 yystype G4UIparameter:: >> 484 UnaryExpression(void) >> 485 { >> 486 yystype result; >> 487 yystype p; >> 488 #ifdef DEBUG >> 489 G4cerr <<" UnaryExpression"<< G4endl; >> 490 #endif >> 491 switch(token) { >> 492 case '-': >> 493 token = Yylex(); >> 494 p = UnaryExpression(); >> 495 if (p.type == CONSTINT) { >> 496 result.I = - p.I; >> 497 result.type = CONSTINT; >> 498 } >> 499 if (p.type == CONSTDOUBLE) { >> 500 result.D = - p.D; >> 501 result.type = CONSTDOUBLE; >> 502 } break; >> 503 case '+': >> 504 token = Yylex(); >> 505 result = UnaryExpression(); break; >> 506 case '!': >> 507 token = Yylex(); >> 508 G4cerr << "Parameter range error: " >> 509 << "operator '!' is not supported (sorry)." >> 510 << G4endl; >> 511 paramERR = 1; >> 512 result = UnaryExpression(); break; >> 513 default: >> 514 result = PrimaryExpression(); >> 515 } >> 516 return result; >> 517 } >> 518 >> 519 >> 520 yystype G4UIparameter:: >> 521 PrimaryExpression(void) >> 522 { >> 523 yystype result; >> 524 #ifdef DEBUG >> 525 G4cerr <<" PrimaryExpression" << G4endl; >> 526 #endif >> 527 switch (token) { >> 528 case IDENTIFIER: >> 529 result.S = yylval.S; >> 530 result.type = token; >> 531 token = Yylex(); break; >> 532 case CONSTINT: >> 533 result.I = yylval.I; >> 534 result.type = token; >> 535 token= Yylex(); break; >> 536 case CONSTDOUBLE: >> 537 result.D = yylval.D; >> 538 result.type = token; >> 539 token = Yylex(); break; >> 540 case '(' : >> 541 token= Yylex(); >> 542 result = Expression(); >> 543 if( token != ')' ) { >> 544 G4cerr << " ')' expected" << G4endl; >> 545 paramERR = 1; >> 546 } >> 547 token = Yylex(); >> 548 break; >> 549 default: >> 550 return result; >> 551 } >> 552 return result; // never executed >> 553 } >> 554 >> 555 //---------------- semantic routines --------------------------------- >> 556 >> 557 G4int G4UIparameter:: >> 558 Eval2(yystype arg1, G4int op, yystype arg2) >> 559 { >> 560 if( (arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER)) { >> 561 G4cerr << parameterName >> 562 << ": meaningless comparison " >> 563 << G4int(arg1.type) << " " << G4int(arg2.type) << G4endl; >> 564 paramERR = 1; >> 565 } >> 566 char type = toupper( parameterType ); >> 567 if( arg1.type == IDENTIFIER) { >> 568 switch (type) { >> 569 case 'I': >> 570 if ( arg2.type == CONSTINT ) { >> 571 return CompareInt( newVal.I, op, arg2.I ); >> 572 } else { >> 573 G4cerr << "integer operand expected for " >> 574 << parameterRange << '.' >> 575 << G4endl; >> 576 } >> 577 break; >> 578 case 'D': >> 579 if ( arg2.type == CONSTDOUBLE ) { >> 580 return CompareDouble( newVal.D, op, arg2.D ); >> 581 } else >> 582 if ( arg2.type == CONSTINT ) { // integral promotion >> 583 return CompareDouble( newVal.D, op, arg2.I ); >> 584 } break; >> 585 default: ; >> 586 } >> 587 } >> 588 if( arg2.type == IDENTIFIER) { >> 589 switch (type) { >> 590 case 'I': >> 591 if ( arg1.type == CONSTINT ) { >> 592 return CompareInt( arg1.I, op, newVal.I ); >> 593 } else { >> 594 G4cerr << "integer operand expected for " >> 595 << parameterRange << '.' >> 596 << G4endl; >> 597 } >> 598 break; >> 599 case 'D': >> 600 if ( arg1.type == CONSTDOUBLE ) { >> 601 return CompareDouble( arg1.D, op, newVal.D ); >> 602 } else >> 603 if ( arg1.type == CONSTINT ) { // integral promotion >> 604 return CompareDouble( arg1.I, op, newVal.D ); >> 605 } break; >> 606 default: ; >> 607 } >> 608 } >> 609 G4cerr << "no param name is specified at the param range."<<G4endl; >> 610 return 0; >> 611 } >> 612 >> 613 G4int G4UIparameter:: >> 614 CompareInt(G4int arg1, G4int op, G4int arg2) >> 615 { >> 616 G4int result=-1; >> 617 G4String opr; >> 618 switch (op) { >> 619 case GT: result = ( arg1 > arg2); opr= ">" ; break; >> 620 case GE: result = ( arg1 >= arg2); opr= ">="; break; >> 621 case LT: result = ( arg1 < arg2); opr= "<" ; break; >> 622 case LE: result = ( arg1 <= arg2); opr= "<="; break; >> 623 case EQ: result = ( arg1 == arg2); opr= "=="; break; >> 624 case NE: result = ( arg1 != arg2); opr= "!="; break; >> 625 default: >> 626 G4cerr << "Parameter range: error at CompareInt" << G4endl; >> 627 paramERR = 1; >> 628 } >> 629 #ifdef DEBUG >> 630 G4cerr << "CompareInt " >> 631 << arg1 << " " << opr << arg2 >> 632 << " result: " << result >> 633 << G4endl; >> 634 #endif >> 635 return result; >> 636 } >> 637 >> 638 G4int G4UIparameter:: >> 639 CompareDouble(G4double arg1, G4int op, G4double arg2) >> 640 { >> 641 G4int result=-1; >> 642 G4String opr; >> 643 switch (op) { >> 644 case GT: result = ( arg1 > arg2); opr= ">"; break; >> 645 case GE: result = ( arg1 >= arg2); opr= ">="; break; >> 646 case LT: result = ( arg1 < arg2); opr= "<"; break; >> 647 case LE: result = ( arg1 <= arg2); opr= "<="; break; >> 648 case EQ: result = ( arg1 == arg2); opr= "=="; break; >> 649 case NE: result = ( arg1 != arg2); opr= "!="; break; >> 650 default: >> 651 G4cerr << "Parameter range: error at CompareDouble" << G4endl; >> 652 paramERR = 1; >> 653 } >> 654 #ifdef DEBUG >> 655 G4cerr << "CompareDouble " >> 656 << arg1 <<" " << opr << " "<< arg2 >> 657 << " result: " << result >> 658 << G4endl; >> 659 #endif >> 660 return result; >> 661 } >> 662 >> 663 // --------------------- utility functions -------------------------- >> 664 >> 665 tokenNum G4UIparameter:: >> 666 Yylex() // reads input and returns token number KR486 >> 667 { // (returns EOF) >> 668 G4int c; >> 669 G4String buf; >> 670 >> 671 while(( c= G4UIpGetc())==' '|| c=='\t' || c== '\n' ) >> 672 ; >> 673 if (c== EOF) >> 674 return (tokenNum)EOF; // KR488 >> 675 buf= ""; >> 676 if (isdigit(c) || c== '.') { // I or D >> 677 do { >> 678 buf += G4String((unsigned char)c); >> 679 c=G4UIpGetc(); >> 680 } while (c=='.' || isdigit(c) || >> 681 c=='e' || c=='E' || c=='+' || c=='-'); >> 682 G4UIpUngetc(c); >> 683 const char* t = buf; >> 684 std::istringstream is(t); >> 685 if ( IsInt(buf.data(),20) ) { >> 686 is >> yylval.I; >> 687 return CONSTINT; >> 688 } else >> 689 if ( IsDouble(buf.data()) ) { >> 690 is >> yylval.D; >> 691 return CONSTDOUBLE; >> 692 } else { >> 693 G4cerr << buf<<": numeric format error."<<G4endl; >> 694 } >> 695 } >> 696 buf=""; >> 697 if (isalpha(c)|| c=='_') { // IDENTIFIER >> 698 do { >> 699 buf += G4String((unsigned char)c); >> 700 } while ((c=G4UIpGetc()) != EOF && (isalnum(c) || c=='_')); >> 701 G4UIpUngetc(c); >> 702 if( buf == parameterName ) { >> 703 yylval.S =buf; >> 704 return IDENTIFIER; >> 705 } else { >> 706 G4cerr << buf << " is not a parameter name."<< G4endl; >> 707 paramERR = 1; >> 708 } >> 709 } >> 710 switch (c) { >> 711 case '>': return (tokenNum) Follow('=', GE, GT); >> 712 case '<': return (tokenNum) Follow('=', LE, LT); >> 713 case '=': return (tokenNum) Follow('=', EQ, '='); >> 714 case '!': return (tokenNum) Follow('=', NE, '!'); >> 715 case '|': return (tokenNum) Follow('|', LOGICALOR, '|'); >> 716 case '&': return (tokenNum) Follow('&', LOGICALAND, '&'); 124 default: 717 default: 125 ed << "undefined."; << 718 return (tokenNum) c; >> 719 } >> 720 } >> 721 >> 722 >> 723 G4int G4UIparameter:: >> 724 Follow(G4int expect, G4int ifyes, G4int ifno) >> 725 { >> 726 G4int c = G4UIpGetc(); >> 727 if ( c== expect) >> 728 return ifyes; >> 729 G4UIpUngetc(c); >> 730 return ifno; >> 731 } >> 732 >> 733 //------------------ low level routines ----------------------------- >> 734 G4int G4UIparameter:: >> 735 G4UIpGetc() { // emulation of getc() >> 736 G4int length = parameterRange.length(); >> 737 if( bp < length) >> 738 return parameterRange(bp++); >> 739 else >> 740 return EOF; >> 741 } >> 742 G4int G4UIparameter:: >> 743 G4UIpUngetc(G4int c) { // emulation of ungetc() >> 744 if (c<0) return -1; >> 745 if (bp >0 && c == parameterRange(bp-1)) { >> 746 --bp; >> 747 } else { >> 748 G4cerr << "G4UIpUngetc() failed." << G4endl; >> 749 G4cerr << "bp="<<bp <<" c="<<c >> 750 << " pR(bp-1)=" << parameterRange(bp-1) >> 751 << G4endl; >> 752 paramERR = 1; >> 753 return -1; 126 } 754 } 127 G4Exception("G4UIparameter::SetDefaultUnit << 755 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 } 756 } >> 757 // ***** end of CheckNewValue() related code ****** >> 758 217 759