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 #include "G4UIcommand.hh"
00032 #include "G4UImessenger.hh"
00033 #include "G4UImanager.hh"
00034 #include "G4UIcommandStatus.hh"
00035 #include "G4StateManager.hh"
00036 #include "G4UnitsTable.hh"
00037 #include "G4Tokenizer.hh"
00038 #include "G4ios.hh"
00039 #include <sstream>
00040
00041 G4UIcommand::G4UIcommand()
00042 : messenger(0), bp(0), token(IDENTIFIER), paramERR(0)
00043 {
00044 }
00045
00046 G4UIcommand::G4UIcommand(const char * theCommandPath,
00047 G4UImessenger * theMessenger)
00048 :messenger(theMessenger),token(IDENTIFIER),paramERR(0)
00049 {
00050 G4String comStr = theCommandPath;
00051 if(!theMessenger)
00052 {
00053 if(comStr(comStr.length()-1)!='/')
00054 {
00055 G4cerr << "G4UIcommand Warning : " << G4endl;
00056 G4cerr << " <" << theCommandPath << "> must be a directory." << G4endl;
00057 G4cerr << " '/' is appended." << G4endl;
00058 comStr += "/";
00059 }
00060 }
00061 G4UIcommandCommonConstructorCode (comStr);
00062 G4String nullString;
00063 availabelStateList.clear();
00064 availabelStateList.push_back(G4State_PreInit);
00065 availabelStateList.push_back(G4State_Init);
00066 availabelStateList.push_back(G4State_Idle);
00067 availabelStateList.push_back(G4State_GeomClosed);
00068 availabelStateList.push_back(G4State_EventProc);
00069 availabelStateList.push_back(G4State_Abort);
00070 }
00071
00072 void G4UIcommand::G4UIcommandCommonConstructorCode
00073 (const char * theCommandPath)
00074 {
00075 commandPath = theCommandPath;
00076 commandName = theCommandPath;
00077 G4int commandNameIndex = commandName.last('/');
00078 commandName.remove(0,commandNameIndex+1);
00079
00080 G4UImanager::GetUIpointer()->AddNewCommand(this);
00081 }
00082
00083 G4UIcommand::~G4UIcommand()
00084 {
00085 G4UImanager* fUImanager = G4UImanager::GetUIpointer();
00086 if(fUImanager) fUImanager->RemoveCommand(this);
00087
00088 G4int n_parameterEntry = parameter.size();
00089 for( G4int i_thParameter=0; i_thParameter < n_parameterEntry; i_thParameter++ )
00090 { delete parameter[i_thParameter]; }
00091 parameter.clear();
00092 }
00093
00094 G4int G4UIcommand::operator==(const G4UIcommand &right) const
00095 {
00096 return ( commandPath == right.GetCommandPath() );
00097 }
00098
00099 G4int G4UIcommand::operator!=(const G4UIcommand &right) const
00100 {
00101 return ( commandPath != right.GetCommandPath() );
00102 }
00103
00104 G4int G4UIcommand::DoIt(G4String parameterList)
00105 {
00106 G4String correctParameters;
00107 G4int n_parameterEntry = parameter.size();
00108 if( n_parameterEntry != 0 )
00109 {
00110 G4String aToken;
00111 G4String correctToken;
00112 G4Tokenizer parameterToken( parameterList );
00113 for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
00114 {
00115 if(i_thParameter > 0)
00116 {
00117 correctParameters.append(" ");
00118 }
00119 aToken = parameterToken();
00120 if( aToken.length()>0 && aToken(0)=='"' )
00121 {
00122 while( aToken(aToken.length()-1) != '"'
00123 || ( aToken.length()==1 && aToken(0)=='"' ))
00124 {
00125 G4String additionalToken = parameterToken();
00126 if( additionalToken.isNull() )
00127 { return fParameterUnreadable+i_thParameter; }
00128 aToken += " ";
00129 aToken += additionalToken;
00130 }
00131 }
00132 else if(i_thParameter==n_parameterEntry-1 && parameter[i_thParameter]->GetParameterType()=='s')
00133 {
00134 G4String anotherToken;
00135 while(!((anotherToken=parameterToken()).isNull()))
00136 {
00137 G4int idxs = anotherToken.index("#");
00138 if(idxs==G4int(std::string::npos))
00139 {
00140 aToken += " ";
00141 aToken += anotherToken;
00142 }
00143 else if(idxs>0)
00144 {
00145 aToken += " ";
00146 aToken += anotherToken(0,idxs);
00147 break;
00148 }
00149 else
00150 { break; }
00151 }
00152 }
00153
00154 if( aToken.isNull() || aToken == "!" )
00155 {
00156 if(parameter[i_thParameter]->IsOmittable())
00157 {
00158 if(parameter[i_thParameter]->GetCurrentAsDefault())
00159 {
00160 G4Tokenizer cvSt(messenger->GetCurrentValue(this));
00161 G4String parVal;
00162 for(G4int ii=0;ii<i_thParameter;ii++)
00163 {
00164 parVal = cvSt();
00165 if (parVal(0)=='"')
00166 {
00167 while( parVal(parVal.length()-1) != '"' )
00168 {
00169 G4String additionalToken = cvSt();
00170 if( additionalToken.isNull() )
00171 { return fParameterUnreadable+i_thParameter; }
00172 parVal += " ";
00173 parVal += additionalToken;
00174 }
00175 }
00176 }
00177 G4String aCVToken = cvSt();
00178 if (aCVToken(0)=='"')
00179 {
00180 while( aCVToken(aCVToken.length()-1) != '"' )
00181 {
00182 G4String additionalToken = cvSt();
00183 if( additionalToken.isNull() )
00184 { return fParameterUnreadable+i_thParameter; }
00185 aCVToken += " ";
00186 aCVToken += additionalToken;
00187 }
00188
00189 }
00190 correctParameters.append(aCVToken);
00191 }
00192 else
00193 { correctParameters.append(parameter[i_thParameter]->GetDefaultValue()); }
00194 }
00195 else
00196 { return fParameterUnreadable+i_thParameter; }
00197 }
00198 else
00199 {
00200 G4int stat = parameter[i_thParameter]->CheckNewValue( aToken );
00201 if(stat) return stat+i_thParameter;
00202 correctParameters.append(aToken);
00203 }
00204 }
00205 }
00206
00207 if(CheckNewValue( correctParameters ))
00208 { return fParameterOutOfRange+99; }
00209
00210 messenger->SetNewValue( this, correctParameters );
00211 return 0;
00212 }
00213
00214 G4String G4UIcommand::GetCurrentValue()
00215 {
00216 return messenger->GetCurrentValue(this);
00217 }
00218
00219 void G4UIcommand::AvailableForStates(G4ApplicationState s1)
00220 {
00221 availabelStateList.clear();
00222 availabelStateList.push_back(s1);
00223 }
00224
00225 void G4UIcommand::AvailableForStates(G4ApplicationState s1,
00226 G4ApplicationState s2)
00227 {
00228 availabelStateList.clear();
00229 availabelStateList.push_back(s1);
00230 availabelStateList.push_back(s2);
00231 }
00232
00233 void G4UIcommand::AvailableForStates(G4ApplicationState s1,
00234 G4ApplicationState s2,
00235 G4ApplicationState s3)
00236 {
00237 availabelStateList.clear();
00238 availabelStateList.push_back(s1);
00239 availabelStateList.push_back(s2);
00240 availabelStateList.push_back(s3);
00241 }
00242
00243 void G4UIcommand::AvailableForStates(G4ApplicationState s1,
00244 G4ApplicationState s2,
00245 G4ApplicationState s3,
00246 G4ApplicationState s4)
00247 {
00248 availabelStateList.clear();
00249 availabelStateList.push_back(s1);
00250 availabelStateList.push_back(s2);
00251 availabelStateList.push_back(s3);
00252 availabelStateList.push_back(s4);
00253 }
00254
00255 void G4UIcommand::AvailableForStates(G4ApplicationState s1,
00256 G4ApplicationState s2,
00257 G4ApplicationState s3,
00258 G4ApplicationState s4,
00259 G4ApplicationState s5)
00260 {
00261 availabelStateList.clear();
00262 availabelStateList.push_back(s1);
00263 availabelStateList.push_back(s2);
00264 availabelStateList.push_back(s3);
00265 availabelStateList.push_back(s4);
00266 availabelStateList.push_back(s5);
00267 }
00268
00269 G4bool G4UIcommand::IsAvailable()
00270 {
00271 G4bool av = false;
00272 G4ApplicationState currentState
00273 = G4StateManager::GetStateManager()->GetCurrentState();
00274
00275 G4int nState = availabelStateList.size();
00276 for(G4int i=0;i<nState;i++)
00277 {
00278 if(availabelStateList[i]==currentState)
00279 {
00280 av = true;
00281 break;
00282 }
00283 }
00284
00285 return av;
00286 }
00287
00288 G4double G4UIcommand::ValueOf(const char* unitName)
00289 {
00290 G4double value = 0.;
00291 value = G4UnitDefinition::GetValueOf(unitName);
00292 return value;
00293 }
00294
00295 G4String G4UIcommand::CategoryOf(const char* unitName)
00296 {
00297 return G4UnitDefinition::GetCategory(unitName);
00298 }
00299
00300 G4String G4UIcommand::UnitsList(const char* unitCategory)
00301 {
00302 G4String retStr;
00303 G4UnitsTable& UTbl = G4UnitDefinition::GetUnitsTable();
00304 size_t i;
00305 for(i=0;i<UTbl.size();i++)
00306 { if(UTbl[i]->GetName()==unitCategory) break; }
00307 if(i==UTbl.size())
00308 {
00309 G4cerr << "Unit category <" << unitCategory << "> is not defined." << G4endl;
00310 return retStr;
00311 }
00312 G4UnitsContainer& UCnt = UTbl[i]->GetUnitsList();
00313 retStr = UCnt[0]->GetSymbol();
00314 G4int je = UCnt.size();
00315 for(G4int j=1;j<je;j++)
00316 {
00317 retStr += " ";
00318 retStr += UCnt[j]->GetSymbol();
00319 }
00320 for(G4int k=0;k<je;k++)
00321 {
00322 retStr += " ";
00323 retStr += UCnt[k]->GetName();
00324 }
00325 return retStr;
00326 }
00327
00328 void G4UIcommand::List()
00329 {
00330 G4cout << G4endl;
00331 G4cout << G4endl;
00332 if(commandPath(commandPath.length()-1)!='/')
00333 { G4cout << "Command " << commandPath << G4endl; }
00334 G4cout << "Guidance :" << G4endl;
00335 G4int n_guidanceEntry = commandGuidance.size();
00336 for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ )
00337 { G4cout << commandGuidance[i_thGuidance] << G4endl; }
00338 if( ! rangeString.isNull() )
00339 { G4cout << " Range of parameters : " << rangeString << G4endl; }
00340 G4int n_parameterEntry = parameter.size();
00341 if( n_parameterEntry > 0 )
00342 {
00343 for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
00344 { parameter[i_thParameter]->List(); }
00345 }
00346 G4cout << G4endl;
00347 }
00348
00349 G4String G4UIcommand::ConvertToString(G4bool boolVal)
00350 {
00351 G4String vl = "0";
00352 if(boolVal) vl = "1";
00353 return vl;
00354 }
00355
00356 G4String G4UIcommand::ConvertToString(G4int intValue)
00357 {
00358 std::ostringstream os;
00359 os << intValue;
00360 G4String vl = os.str();
00361 return vl;
00362 }
00363
00364 G4String G4UIcommand::ConvertToString(G4double doubleValue)
00365 {
00366 std::ostringstream os;
00367 os << doubleValue;
00368 G4String vl = os.str();
00369 return vl;
00370 }
00371
00372 G4String G4UIcommand::ConvertToString(G4double doubleValue,const char* unitName)
00373 {
00374 G4String unt = unitName;
00375 G4double uv = ValueOf(unitName);
00376
00377 std::ostringstream os;
00378 os << doubleValue/uv << " " << unitName;
00379 G4String vl = os.str();
00380 return vl;
00381 }
00382
00383 G4String G4UIcommand::ConvertToString(G4ThreeVector vec)
00384 {
00385 std::ostringstream os;
00386 os << vec.x() << " " << vec.y() << " " << vec.z();
00387 G4String vl = os.str();
00388 return vl;
00389 }
00390
00391 G4String G4UIcommand::ConvertToString(G4ThreeVector vec,const char* unitName)
00392 {
00393 G4String unt = unitName;
00394 G4double uv = ValueOf(unitName);
00395
00396 std::ostringstream os;
00397 os << vec.x()/uv << " " << vec.y()/uv << " " << vec.z()/uv
00398 << " " << unitName;
00399 G4String vl = os.str();
00400 return vl;
00401 }
00402
00403 G4bool G4UIcommand::ConvertToBool(const char* st)
00404 {
00405 G4String v = st;
00406 v.toUpper();
00407 G4bool vl = false;
00408 if( v=="Y" || v=="YES" || v=="1" || v=="T" || v=="TRUE" )
00409 { vl = true; }
00410 return vl;
00411 }
00412
00413 G4int G4UIcommand::ConvertToInt(const char* st)
00414 {
00415 G4int vl;
00416 std::istringstream is(st);
00417 is >> vl;
00418 return vl;
00419 }
00420
00421 G4double G4UIcommand::ConvertToDouble(const char* st)
00422 {
00423 G4double vl;
00424 std::istringstream is(st);
00425 is >> vl;
00426 return vl;
00427 }
00428
00429 G4double G4UIcommand::ConvertToDimensionedDouble(const char* st)
00430 {
00431 G4double vl;
00432 char unts[30];
00433
00434 std::istringstream is(st);
00435 is >> vl >> unts;
00436 G4String unt = unts;
00437
00438 return (vl*ValueOf(unt));
00439 }
00440
00441 G4ThreeVector G4UIcommand::ConvertTo3Vector(const char* st)
00442 {
00443 G4double vx;
00444 G4double vy;
00445 G4double vz;
00446 std::istringstream is(st);
00447 is >> vx >> vy >> vz;
00448 return G4ThreeVector(vx,vy,vz);
00449 }
00450
00451 G4ThreeVector G4UIcommand::ConvertToDimensioned3Vector(const char* st)
00452 {
00453 G4double vx;
00454 G4double vy;
00455 G4double vz;
00456 char unts[30];
00457 std::istringstream is(st);
00458 is >> vx >> vy >> vz >> unts;
00459 G4String unt = unts;
00460 G4double uv = ValueOf(unt);
00461 return G4ThreeVector(vx*uv,vy*uv,vz*uv);
00462 }
00463
00464
00465
00466
00467
00468 #include <ctype.h>
00469
00470
00471
00472
00473 G4int G4UIcommand::
00474 CheckNewValue(const char * newValue)
00475 {
00476 yystype result;
00477
00478 if( ! rangeString.isNull() )
00479 { if( RangeCheck(newValue) == 0 ) return fParameterOutOfRange; }
00480 return 0;
00481 }
00482
00483
00484
00485 G4int G4UIcommand::
00486 TypeCheck(const char * t)
00487 {
00488 G4String aNewValue;
00489 char type;
00490 std::istringstream is(t);
00491 for (unsigned i=0; i< parameter.size(); i++) {
00492 is >> aNewValue;
00493 type = toupper(parameter[i]->GetParameterType());
00494 switch ( type ) {
00495 case 'D':
00496 if( IsDouble(aNewValue)==0 ){
00497 G4cerr << aNewValue << ": double value expected."
00498 << G4endl;
00499 return 0;
00500 } break;
00501 case 'I':
00502 if( IsInt(aNewValue,20)==0 ){
00503 G4cerr <<aNewValue<<": integer expected."
00504 <<G4endl;
00505 return 0;
00506 } break;
00507 case 'S':
00508 break;
00509 case 'B':
00510 aNewValue.toUpper();
00511 if (aNewValue == "Y" || aNewValue == "N"
00512 ||aNewValue == "YES" || aNewValue == "NO"
00513 ||aNewValue == "1" || aNewValue == "0"
00514 ||aNewValue == "T" || aNewValue == "F"
00515 ||aNewValue == "TRUE" || aNewValue == "FALSE")
00516 return 1;
00517 else return 0;
00518 break;
00519 default: ;
00520 }
00521 }
00522 return 1;
00523 }
00524
00525
00526 G4int G4UIcommand::
00527 IsInt(const char* buf, short maxDigits)
00528 {
00529 const char* p= buf;
00530 G4int length=0;
00531 if( *p == '+' || *p == '-') { ++p; }
00532 if( isdigit( (G4int)(*p) )) {
00533 while( isdigit( (G4int)(*p) )) { ++p; ++length; }
00534 if( *p == '\0' ) {
00535 if( length > maxDigits) {
00536 G4cerr <<"digit length exceeds"<<G4endl;
00537 return 0;
00538 }
00539 return 1;
00540 } else {
00541
00542 }
00543 } else {
00544
00545 }
00546 return 0;
00547 }
00548
00549
00550 G4int G4UIcommand::
00551 ExpectExponent(const char* str)
00552 {
00553 G4int maxExplength;
00554 if( IsInt( str, maxExplength=7 )) return 1;
00555 else return 0;
00556 }
00557
00558
00559 G4int G4UIcommand::
00560 IsDouble(const char* buf)
00561 {
00562 const char* p= buf;
00563 switch( *p) {
00564 case '+': case '-': ++p;
00565 if( isdigit(*p) ) {
00566 while( isdigit( (G4int)(*p) )) { ++p; }
00567 switch ( *p ) {
00568 case '\0': return 1;
00569
00570 case 'E': case 'e':
00571 return ExpectExponent(++p );
00572
00573 case '.': ++p;
00574 if( *p == '\0' ) return 1;
00575 if( *p == 'e' || *p =='E' ) return ExpectExponent(++p );
00576 if( isdigit(*p) ) {
00577 while( isdigit( (G4int)(*p) )) { ++p; }
00578 if( *p == '\0' ) return 1;
00579 if( *p == 'e' || *p =='E') return ExpectExponent(++p);
00580 } else return 0; break;
00581 default: return 0;
00582 }
00583 }
00584 if( *p == '.' ) { ++p;
00585 if( isdigit(*p) ) {
00586 while( isdigit( (G4int)(*p) )) { ++p; }
00587 if( *p == '\0' ) return 1;
00588 if( *p == 'e' || *p =='E') return ExpectExponent(++p);
00589 }
00590 }
00591 break;
00592 case '.': ++p;
00593 if( isdigit(*p) ) {
00594 while( isdigit( (G4int)(*p) )) { ++p; }
00595 if( *p == '\0' ) return 1;
00596 if( *p == 'e' || *p =='E' ) return ExpectExponent(++p);
00597 } break;
00598 default:
00599 if( isdigit(*p) ) {
00600 while( isdigit( (G4int)(*p) )) { ++p; }
00601 if( *p == '\0' ) return 1;
00602 if( *p == 'e' || *p =='E') return ExpectExponent(++p);
00603 if( *p == '.' ) { ++p;
00604 if( *p == '\0' ) return 1;
00605 if( *p == 'e' || *p =='E') return ExpectExponent(++p);
00606 if( isdigit(*p) ) {
00607 while( isdigit( (G4int)(*p) )) { ++p; }
00608 if( *p == '\0' ) return 1;
00609 if( *p == 'e' || *p =='E') return ExpectExponent(++p);
00610 }
00611 }
00612 }
00613 }
00614 return 0;
00615 }
00616
00617
00618
00619 G4int G4UIcommand::
00620 RangeCheck(const char* t) {
00621 yystype result;
00622 char type;
00623 bp = 0;
00624 std::istringstream is(t);
00625 for (unsigned i=0; i< parameter.size(); i++) {
00626 type= toupper(parameter[i]->GetParameterType());
00627 switch ( type ) {
00628 case 'D': is >> newVal[i].D; break;
00629 case 'I': is >> newVal[i].I; break;
00630 case 'S':
00631 case 'B':
00632 default: ;
00633 }
00634 }
00635
00636 token= Yylex();
00637 result = Expression();
00638
00639 if( paramERR == 1 ) return 0;
00640 if( result.type != CONSTINT) {
00641 G4cerr << "Illegal Expression in parameter range." << G4endl;
00642 return 0;
00643 }
00644 if ( result.I ) return 1;
00645 G4cerr << "parameter out of range: "<< rangeString << G4endl;
00646 return 0;
00647 }
00648
00649
00650 yystype G4UIcommand::
00651 Expression(void)
00652 {
00653 yystype result;
00654 #ifdef DEBUG
00655 G4cerr << " Expression()" << G4endl;
00656 #endif
00657 result = LogicalORExpression();
00658 return result;
00659 }
00660
00661 yystype G4UIcommand::
00662 LogicalORExpression(void)
00663 {
00664 yystype result;
00665 yystype p;
00666 p = LogicalANDExpression();
00667 if( token != LOGICALOR) return p;
00668 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
00669 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
00670 paramERR = 1;
00671 }
00672 result.I = p.I;
00673 while (token == LOGICALOR)
00674 {
00675 token = Yylex();
00676 p = LogicalANDExpression();
00677 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
00678 G4cerr << "Parameter range: illegal type at '||'" <<G4endl;
00679 paramERR = 1;
00680 }
00681 switch (p.type) {
00682 case CONSTINT:
00683 result.I += p.I;
00684 result.type = CONSTINT; break;
00685 case CONSTDOUBLE:
00686 result.I += (p.D != 0.0);
00687 result.type = CONSTINT; break;
00688 default:
00689 G4cerr << "Parameter range: unknown type"<<G4endl;
00690 paramERR = 1;
00691 }
00692 }
00693 return result;
00694 }
00695
00696 yystype G4UIcommand::
00697 LogicalANDExpression(void)
00698 {
00699 yystype result;
00700 yystype p;
00701 p = EqualityExpression();
00702 if( token != LOGICALAND) return p;
00703 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
00704 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
00705 paramERR = 1;
00706 }
00707 result.I = p.I;
00708 while (token == LOGICALAND)
00709 {
00710 token = Yylex();
00711 p = EqualityExpression();
00712 if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
00713 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
00714 paramERR = 1;
00715 }
00716 switch (p.type) {
00717 case CONSTINT:
00718 result.I *= p.I;
00719 result.type = CONSTINT; break;
00720 case CONSTDOUBLE:
00721 result.I *= (p.D != 0.0);
00722 result.type = CONSTINT; break;
00723 default:
00724 G4cerr << "Parameter range: unknown type."<< G4endl;
00725 paramERR = 1;
00726 }
00727 }
00728 return result;
00729 }
00730
00731
00732 yystype G4UIcommand::
00733 EqualityExpression(void)
00734 {
00735 yystype arg1, arg2;
00736 G4int operat;
00737 yystype result;
00738 #ifdef DEBUG
00739 G4cerr << " EqualityExpression()" <<G4endl;
00740 #endif
00741 result = RelationalExpression();
00742 if( token==EQ || token==NE ) {
00743 operat = token;
00744 token = Yylex();
00745 arg1 = result;
00746 arg2 = RelationalExpression();
00747 result.I = Eval2( arg1, operat, arg2 );
00748 result.type = CONSTINT;
00749 #ifdef DEBUG
00750 G4cerr << " return code of Eval2(): " << result.I <<G4endl;
00751 #endif
00752 } else {
00753 if (result.type != CONSTINT && result.type != CONSTDOUBLE) {
00754 G4cerr << "Parameter range: error at EqualityExpression"
00755 << G4endl;
00756 paramERR = 1;
00757 }
00758 }
00759 return result;
00760 }
00761
00762
00763 yystype G4UIcommand::
00764 RelationalExpression(void)
00765 {
00766 yystype arg1, arg2;
00767 G4int operat;
00768 yystype result;
00769 #ifdef DEBUG
00770 G4cerr << " RelationalExpression()" <<G4endl;
00771 #endif
00772
00773 arg1 = AdditiveExpression();
00774 if( token==GT || token==GE || token==LT || token==LE ) {
00775 operat = token;
00776 token = Yylex();
00777 arg2 = AdditiveExpression();
00778 result.I = Eval2( arg1, operat, arg2 );
00779 result.type = CONSTINT;
00780 #ifdef DEBUG
00781 G4cerr << " return code of Eval2(): " << result.I << G4endl;
00782 #endif
00783 } else {
00784 result = arg1;
00785 }
00786 #ifdef DEBUG
00787 G4cerr <<" return RelationalExpression()"<< G4endl;
00788 #endif
00789 return result;
00790 }
00791
00792 yystype G4UIcommand::
00793 AdditiveExpression(void)
00794 { yystype result;
00795 result = MultiplicativeExpression();
00796 if( token != '+' && token != '-' ) return result;
00797 G4cerr << "Parameter range: operator "
00798 << (char)token
00799 << " is not supported." << G4endl;
00800 paramERR = 1;
00801 return result;
00802 }
00803
00804 yystype G4UIcommand::
00805 MultiplicativeExpression(void)
00806 { yystype result;
00807 result = UnaryExpression();
00808 if( token != '*' && token != '/' && token != '%' ) return result;
00809 G4cerr << "Parameter range: operator "
00810 << (char)token
00811 << " is not supported." << G4endl;
00812 paramERR = 1;
00813 return result;
00814 }
00815
00816 yystype G4UIcommand::
00817 UnaryExpression(void)
00818 {
00819 yystype result;
00820 yystype p;
00821 #ifdef DEBUG
00822 G4cerr <<" UnaryExpression"<< G4endl;
00823 #endif
00824 switch(token) {
00825 case '-':
00826 token = Yylex();
00827 p = UnaryExpression();
00828 if (p.type == CONSTINT) {
00829 result.I = - p.I;
00830 result.type = CONSTINT;
00831 }
00832 if (p.type == CONSTDOUBLE) {
00833 result.D = - p.D;
00834 result.type = CONSTDOUBLE;
00835 } break;
00836 case '+':
00837 token = Yylex();
00838 result = UnaryExpression(); break;
00839 case '!':
00840 token = Yylex();
00841 G4cerr << "Parameter range error: "
00842 << "operator '!' is not supported (sorry)."
00843 << G4endl;
00844 paramERR = 1;
00845 result = UnaryExpression(); break;
00846 default:
00847 result = PrimaryExpression();
00848 }
00849 return result;
00850 }
00851
00852
00853 yystype G4UIcommand::
00854 PrimaryExpression(void)
00855 {
00856 yystype result;
00857 #ifdef DEBUG
00858 G4cerr <<" primary_exp"<<G4endl;
00859 #endif
00860 switch (token) {
00861 case IDENTIFIER:
00862 result.S = yylval.S;
00863 result.type = token;
00864 token = Yylex(); break;
00865 case CONSTINT:
00866 result.I = yylval.I;
00867 result.type = token;
00868 token= Yylex(); break;
00869 case CONSTDOUBLE:
00870 result.D = yylval.D;
00871 result.type = token;
00872 token = Yylex(); break;
00873 case '(' :
00874 token= Yylex();
00875 result = Expression();
00876 if( token != ')' ) {
00877 G4cerr << " ')' expected" << G4endl;
00878 paramERR = 1;
00879 }
00880 token = Yylex();
00881 break;
00882 default:
00883 return result;
00884 }
00885 return result;
00886 }
00887
00888
00889
00890 G4int G4UIcommand::
00891 Eval2(yystype arg1, G4int op, yystype arg2)
00892 {
00893 char newValtype;
00894 if( (arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER)) {
00895 G4cerr << commandName
00896 << ": meaningless comparison"
00897 << G4endl;
00898 paramERR = 1;
00899 }
00900
00901 if( arg1.type == IDENTIFIER) {
00902 unsigned i = IndexOf( arg1.S );
00903 newValtype = toupper(parameter[i]->GetParameterType());
00904 switch ( newValtype ) {
00905 case 'I':
00906 if( arg2.type == CONSTINT ) {
00907 return CompareInt( newVal[i].I, op, arg2.I );
00908 } else {
00909 G4cerr << "integer operand expected for "
00910 << rangeString
00911 << '.' << G4endl;
00912 } break;
00913 case 'D':
00914 if( arg2.type == CONSTDOUBLE ) {
00915 return CompareDouble( newVal[i].D, op, arg2.D );
00916 } else
00917 if ( arg2.type == CONSTINT ) {
00918 return CompareDouble( newVal[i].D, op, arg2.I );
00919 } break;
00920 default: ;
00921 }
00922 }
00923 if( arg2.type == IDENTIFIER) {
00924 unsigned i = IndexOf( arg2.S );
00925 newValtype = toupper(parameter[i]->GetParameterType());
00926 switch ( newValtype ) {
00927 case 'I':
00928 if( arg1.type == CONSTINT ) {
00929 return CompareInt( arg1.I, op, newVal[i].I );
00930 } else {
00931 G4cerr << "integer operand expected for "
00932 << rangeString
00933 << '.' << G4endl;
00934 } break;
00935 case 'D':
00936 if( arg1.type == CONSTDOUBLE ) {
00937 return CompareDouble( arg1.D, op, newVal[i].D );
00938 } else
00939 if ( arg1.type == CONSTINT ) {
00940 return CompareDouble( arg1.I, op, newVal[i].D );
00941 } break;
00942 default: ;
00943 }
00944 }
00945 return 0;
00946 }
00947
00948 G4int G4UIcommand::
00949 CompareInt(G4int arg1, G4int op, G4int arg2)
00950 {
00951 G4int result=-1;
00952 G4String opr;
00953 switch (op) {
00954 case GT: result = ( arg1 > arg2); opr= ">" ; break;
00955 case GE: result = ( arg1 >= arg2); opr= ">="; break;
00956 case LT: result = ( arg1 < arg2); opr= "<" ; break;
00957 case LE: result = ( arg1 <= arg2); opr= "<="; break;
00958 case EQ: result = ( arg1 == arg2); opr= "=="; break;
00959 case NE: result = ( arg1 != arg2); opr= "!="; break;
00960 default:
00961 G4cerr << "Parameter range: error at CompareInt" << G4endl;
00962 paramERR = 1;
00963 }
00964 #ifdef DEBUG
00965 G4cerr << "CompareInt "
00966 << arg1 << " " << opr << arg2
00967 << " result: " << result
00968 << G4endl;
00969 #endif
00970 return result;
00971 }
00972
00973 G4int G4UIcommand::
00974 CompareDouble(G4double arg1, G4int op, G4double arg2)
00975 {
00976 G4int result=-1;
00977 G4String opr;
00978 switch (op) {
00979 case GT: result = ( arg1 > arg2); opr= ">"; break;
00980 case GE: result = ( arg1 >= arg2); opr= ">="; break;
00981 case LT: result = ( arg1 < arg2); opr= "<"; break;
00982 case LE: result = ( arg1 <= arg2); opr= "<="; break;
00983 case EQ: result = ( arg1 == arg2); opr= "=="; break;
00984 case NE: result = ( arg1 != arg2); opr= "!="; break;
00985 default:
00986 G4cerr << "Parameter range: error at CompareDouble"
00987 << G4endl;
00988 paramERR = 1;
00989 }
00990 #ifdef DEBUG
00991 G4cerr << "CompareDouble "
00992 << arg1 <<" " << opr << " "<< arg2
00993 << " result: " << result
00994 << G4endl;
00995 #endif
00996 return result;
00997 }
00998
00999 unsigned G4UIcommand::
01000 IndexOf(const char* nam)
01001 {
01002 unsigned i;
01003 G4String pname;
01004 for( i=0; i<parameter.size(); i++)
01005 {
01006 pname = parameter[i]-> GetParameterName();
01007 if( pname == nam ) {
01008 return i;
01009 }
01010 }
01011 paramERR = 1;
01012 G4cerr << "parameter name:"<<nam<<" not found."<< G4endl;
01013 return 0;
01014 }
01015
01016
01017 unsigned G4UIcommand::
01018 IsParameter(const char* nam)
01019 {
01020 G4String pname;
01021 for(unsigned i=0; i<parameter.size(); i++)
01022 {
01023 pname = parameter[i]-> GetParameterName();
01024 if( pname == nam ) return 1;
01025 }
01026 return 0;
01027 }
01028
01029
01030
01031
01032 tokenNum G4UIcommand::
01033 Yylex()
01034 {
01035 G4int c;
01036 G4String buf;
01037
01038 while(( c= G4UIpGetc())==' '|| c=='\t' || c== '\n' )
01039 ;
01040 if (c== EOF)
01041 return (tokenNum)EOF;
01042 buf= "";
01043 if (isdigit(c) || c== '.') {
01044 do {
01045 buf += G4String((unsigned char)c);
01046 c=G4UIpGetc();
01047 } while (c=='.' || isdigit(c) ||
01048 c=='e' || c=='E' || c=='+' || c=='-');
01049 G4UIpUngetc(c);
01050 const char* t = buf;
01051 std::istringstream is(t);
01052 if ( IsInt(buf.data(),20) ) {
01053 is >> yylval.I;
01054 return CONSTINT;
01055 } else
01056 if ( IsDouble(buf.data()) ) {
01057 is >> yylval.D;
01058 return CONSTDOUBLE;
01059 } else {
01060 G4cerr << buf<<": numeric format error."<<G4endl;
01061 }
01062 }
01063 buf="";
01064 if (isalpha(c)|| c=='_') {
01065 do {
01066 buf += G4String((unsigned char)c);
01067 } while ((c=G4UIpGetc()) != EOF && (isalnum(c) || c=='_'));
01068 G4UIpUngetc(c);
01069 if( IsParameter(buf) ) {
01070 yylval.S =buf;
01071 return IDENTIFIER;
01072 } else {
01073 G4cerr << buf << " is not a parameter name."<< G4endl;
01074 paramERR = 1;
01075 }
01076 }
01077 switch (c) {
01078 case '>': return (tokenNum) Follow('=', GE, GT);
01079 case '<': return (tokenNum) Follow('=', LE, LT);
01080 case '=': return (tokenNum) Follow('=', EQ, '=');
01081 case '!': return (tokenNum) Follow('=', NE, '!');
01082 case '|': return (tokenNum) Follow('|', LOGICALOR, '|');
01083 case '&': return (tokenNum) Follow('&', LOGICALAND, '&');
01084 default:
01085 return (tokenNum) c;
01086 }
01087 }
01088
01089
01090 G4int G4UIcommand::
01091 Follow(G4int expect, G4int ifyes, G4int ifno)
01092 {
01093 G4int c = G4UIpGetc();
01094 if ( c== expect)
01095 return ifyes;
01096 G4UIpUngetc(c);
01097 return ifno;
01098 }
01099
01100
01101 G4int G4UIcommand::
01102 G4UIpGetc() {
01103 G4int length = rangeString.length();
01104 if( bp < length)
01105 return rangeString(bp++);
01106 else
01107 return EOF;
01108 }
01109 G4int G4UIcommand::
01110 G4UIpUngetc(G4int c) {
01111 if (c<0) return -1;
01112 if (bp >0 && c == rangeString(bp-1)) {
01113 --bp;
01114 } else {
01115 G4cerr << "G4UIpUngetc() failed." << G4endl;
01116 G4cerr << "bp="<<bp <<" c="<<c
01117 << " pR(bp-1)=" << rangeString(bp-1)
01118 << G4endl;
01119 paramERR = 1;
01120 return -1;
01121 }
01122 return 0;
01123 }