Files
geant4/source/intercoms/src/G4UIcommand.cc
T
2016-06-08 15:55:53 +02:00

952 lines
27 KiB
C++

// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4UIcommand.cc,v 1.5 1999/12/15 14:50:41 gunter Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
#include "G4UIcommand.hh"
#include "G4UImessenger.hh"
#include "G4UImanager.hh"
#include "G4UIcommandStatus.hh"
#include "G4StateManager.hh"
#include "G4UnitsTable.hh"
#include "g4rw/ctoken.h"
#include "G4ios.hh"
G4UIcommand::G4UIcommand():paramERR(0) { }
G4UIcommand::G4UIcommand(const char * theCommandPath,
G4UImessenger * theMessenger)
:messenger(theMessenger), paramERR(0)
{
G4String comStr = theCommandPath;
if(!theMessenger)
{ // this must be a directory
if(comStr(comStr.length()-1)!='/')
{
G4cerr << "G4UIcommand Warning : " << G4endl;
G4cerr << " <" << theCommandPath << "> must be a directory." << G4endl;
G4cerr << " '/' is appended." << G4endl;
comStr += "/";
}
}
G4UIcommandCommonConstructorCode (comStr);
G4String nullString;
availabelStateList.clear();
availabelStateList.insert(PreInit);
availabelStateList.insert(Init);
availabelStateList.insert(Idle);
availabelStateList.insert(GeomClosed);
availabelStateList.insert(EventProc);
}
void G4UIcommand::G4UIcommandCommonConstructorCode
(const char * theCommandPath)
{
commandPath = theCommandPath;
commandName = theCommandPath;
int commandNameIndex = commandName.last('/');
commandName.remove(0,commandNameIndex+1);
G4UImanager::GetUIpointer()->AddNewCommand(this);
}
G4UIcommand::~G4UIcommand()
{
G4UImanager* fUImanager = G4UImanager::GetUIpointer();
if(fUImanager) fUImanager->RemoveCommand(this);
int n_parameterEntry = parameter.entries();
for( int i_thParameter=0; i_thParameter < n_parameterEntry; i_thParameter++ )
{ delete parameter[i_thParameter]; }
}
int G4UIcommand::operator==(const G4UIcommand &right) const
{
return ( commandPath == right.GetCommandPath() );
}
int G4UIcommand::operator!=(const G4UIcommand &right) const
{
return ( commandPath != right.GetCommandPath() );
}
G4int G4UIcommand::DoIt(G4String parameterList)
{
G4String correctParameters;
int n_parameterEntry = parameter.entries();
if( n_parameterEntry != 0 )
{
G4String aToken;
G4String correctToken;
G4Tokenizer parameterToken( parameterList );
for( int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
{
if(i_thParameter > 0)
{
correctParameters.append(" ");
}
aToken = parameterToken();
if( aToken.length()>0 && aToken(0)=='"' )
{
while( aToken(aToken.length()-1) != '"' )
{
G4String additionalToken = parameterToken();
if( additionalToken.isNull() )
{ return fParameterUnreadable+i_thParameter; }
aToken += " ";
aToken += additionalToken;
}
// aToken.strip(G4String::both,'"');
}
if( aToken.isNull() || aToken == "!" )
{
if(parameter[i_thParameter]->IsOmittable())
{
if(parameter[i_thParameter]->GetCurrentAsDefault())
{
G4Tokenizer cvt(messenger->GetCurrentValue(this));
G4String parVal;
for(int ii=0;ii<i_thParameter;ii++)
{ parVal = cvt(); }
G4String aCVToken = cvt();
if (aCVToken(0)=='"')
{
while( aCVToken(aCVToken.length()-1) != '"' )
{
G4String additionalToken = cvt();
if( additionalToken.isNull() )
{ return fParameterUnreadable+i_thParameter; }
aCVToken += " ";
aCVToken += additionalToken;
}
// aCVToken.strip(G4String::both,'"');
}
correctParameters.append(aCVToken);
}
else
{ correctParameters.append(parameter[i_thParameter]->GetDefaultValue()); }
}
else
{ return fParameterUnreadable+i_thParameter; }
}
else
{
int stat = parameter[i_thParameter]->CheckNewValue( aToken );
if(stat) return stat+i_thParameter;
correctParameters.append(aToken);
}
}
}
if(CheckNewValue( correctParameters ))
{ return fParameterOutOfRange+99; }
messenger->SetNewValue( this, correctParameters );
return 0;
}
G4String G4UIcommand::GetCurrentValue()
{
return messenger->GetCurrentValue(this);
}
void G4UIcommand::AvailableForStates(G4ApplicationState s1)
{
availabelStateList.clear();
availabelStateList.insert(s1);
}
void G4UIcommand::AvailableForStates(G4ApplicationState s1,
G4ApplicationState s2)
{
availabelStateList.clear();
availabelStateList.insert(s1);
availabelStateList.insert(s2);
}
void G4UIcommand::AvailableForStates(G4ApplicationState s1,
G4ApplicationState s2,
G4ApplicationState s3)
{
availabelStateList.clear();
availabelStateList.insert(s1);
availabelStateList.insert(s2);
availabelStateList.insert(s3);
}
void G4UIcommand::AvailableForStates(G4ApplicationState s1,
G4ApplicationState s2,
G4ApplicationState s3,
G4ApplicationState s4)
{
availabelStateList.clear();
availabelStateList.insert(s1);
availabelStateList.insert(s2);
availabelStateList.insert(s3);
availabelStateList.insert(s4);
}
void G4UIcommand::AvailableForStates(G4ApplicationState s1,
G4ApplicationState s2,
G4ApplicationState s3,
G4ApplicationState s4,
G4ApplicationState s5)
{
availabelStateList.clear();
availabelStateList.insert(s1);
availabelStateList.insert(s2);
availabelStateList.insert(s3);
availabelStateList.insert(s4);
availabelStateList.insert(s5);
}
G4bool G4UIcommand::IsAvailable()
{
G4bool av = false;
G4ApplicationState currentState
= G4StateManager::GetStateManager()->GetCurrentState();
int nState = availabelStateList.entries();
for(int i=0;i<nState;i++)
{
if(availabelStateList[i]==currentState)
{
av = true;
break;
}
}
return av;
}
G4double G4UIcommand::ValueOf(G4String unitName)
{
G4double value = 0.;
value = G4UnitDefinition::GetValueOf(unitName);
return value;
}
G4String G4UIcommand::CategoryOf(G4String unitName)
{
return G4UnitDefinition::GetCategory(unitName);
}
G4String G4UIcommand::UnitsList(G4String unitCategory)
{
G4String retStr;
G4UnitsTable& UTbl = G4UnitDefinition::GetUnitsTable();
G4int i;
for(i=0;i<UTbl.entries();i++)
{ if(UTbl[i]->GetName()==unitCategory) break; }
if(i==UTbl.entries())
{
G4cerr << "Unit category <" << unitCategory << "> is not defined." << G4endl;
return retStr;
}
G4UnitsContainer& UCnt = UTbl[i]->GetUnitsList();
retStr = UCnt[0]->GetSymbol();
G4int je = UCnt.entries();
for(int j=1;j<je;j++)
{
retStr += " ";
retStr += UCnt[j]->GetSymbol();
}
for(int k=0;k<je;k++)
{
retStr += " ";
retStr += UCnt[k]->GetName();
}
return retStr;
}
void G4UIcommand::List()
{
G4cout << G4endl;
G4cout << G4endl;
if(commandPath(commandPath.length()-1)!='/')
{ G4cout << "Command " << commandPath << G4endl; }
G4cout << "Guidance :" << G4endl;
int n_guidanceEntry = commandGuidance.entries();
for( int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ )
{ G4cout << commandGuidance[i_thGuidance] << G4endl; }
if( ! rangeString.isNull() )
{ G4cout << " Range of parameters : " << rangeString << G4endl; }
int n_parameterEntry = parameter.entries();
if( n_parameterEntry > 0 )
{
for( int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
{ parameter[i_thParameter]->List(); }
}
G4cout << G4endl;
}
// ----- the following is used by CheckNewValue() ------------
#include <ctype.h> // isalpha(), toupper()
#include "g4std/strstream"
//#include "checkNewValue_debug.icc"
//#define DEBUG 1
int G4UIcommand::
CheckNewValue(G4String newValue)
{
yystype result;
// if( TypeCheck(newValue) == 0 ) return 1;
if( ! rangeString.isNull() )
{ if( RangeCheck(newValue) == 0 ) return fParameterOutOfRange; }
return 0; // succeeded
}
// ------------------ type check routines -------------------
int G4UIcommand::
TypeCheck(G4String newValues)
{
G4String aNewValue;
char type;
const char* t = newValues;
G4std::istrstream is((char*)t);
for (unsigned i=0; i< parameter.entries(); i++) {
is >> aNewValue;
type = toupper(parameter(i)->GetParameterType());
switch ( type ) {
case 'D':
if( IsDouble(aNewValue)==0 ){
G4cerr << aNewValue << ": double value expected."
<< G4endl;
return 0;
} break;
case 'I':
if( IsInt(aNewValue,20)==0 ){
G4cerr <<aNewValue<<": integer expected."
<<G4endl;
return 0;
} break;
case 'S':
break;
case 'B':
aNewValue.toUpper();
if (aNewValue == "Y" || aNewValue == "N"
||aNewValue == "YES" || aNewValue == "NO"
||aNewValue == "1" || aNewValue == "0"
||aNewValue == "T" || aNewValue == "F"
||aNewValue == "TRUE" || aNewValue == "FALSE")
return 1;
else return 0;
break;
default: ;
}
}
return 1;
}
int G4UIcommand::
IsInt(const char* buf, short maxDigits)
{
const char* p= buf;
int length=0;
if( *p == '+' || *p == '-') { ++p; }
if( isdigit( (int)(*p) )) {
while( isdigit( (int)(*p) )) { ++p; ++length; }
if( *p == '\0' ) {
if( length > maxDigits) {
G4cerr <<"digit length exceeds"<<G4endl;
return 0;
}
return 1;
} else {
// G4cerr <<"illegal character after int:"<<buf<<G4endl;
}
} else {
// G4cerr <<"illegal int:"<<buf<<G4endl;
}
return 0;
}
int G4UIcommand::
ExpectExponent(const char* str) // used only by IsDouble()
{
int maxExplength;
if( IsInt( str, maxExplength=7 )) return 1;
else return 0;
}
int G4UIcommand::
IsDouble(const char* buf)
{
const char* p= buf;
switch( *p) {
case '+': case '-': ++p;
if( isdigit(*p) ) {
while( isdigit( (int)(*p) )) { ++p; }
switch ( *p ) {
case '\0': return 1;
// break;
case 'E': case 'e':
return ExpectExponent(++p );
// break;
case '.': ++p;
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E' ) return ExpectExponent(++p );
if( isdigit(*p) ) {
while( isdigit( (int)(*p) )) { ++p; }
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E') return ExpectExponent(++p);
} else return 0; break;
default: return 0;
}
}
if( *p == '.' ) { ++p;
if( isdigit(*p) ) {
while( isdigit( (int)(*p) )) { ++p; }
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E') return ExpectExponent(++p);
}
}
break;
case '.': ++p;
if( isdigit(*p) ) {
while( isdigit( (int)(*p) )) { ++p; }
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E' ) return ExpectExponent(++p);
} break;
default: // digit is expected
if( isdigit(*p) ) {
while( isdigit( (int)(*p) )) { ++p; }
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E') return ExpectExponent(++p);
if( *p == '.' ) { ++p;
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E') return ExpectExponent(++p);
if( isdigit(*p) ) {
while( isdigit( (int)(*p) )) { ++p; }
if( *p == '\0' ) return 1;
if( *p == 'e' || *p =='E') return ExpectExponent(++p);
}
}
}
}
return 0;
}
// ------------------ range Check routines -------------------
int G4UIcommand::
RangeCheck(G4String newValue) {
yystype result;
char type;
bp = 0; // reset buffer pointer for G4UIpGetc()
const char* t = newValue;
G4std::istrstream is((char*)t);
for (unsigned i=0; i< parameter.entries(); i++) {
type= toupper(parameter(i)->GetParameterType());
switch ( type ) {
case 'D': is >> newVal(i).D; break;
case 'I': is >> newVal(i).I; break;
case 'S':
case 'B':
default: ;
}
}
// PrintToken(); // Print tokens (consumes all tokens)
token= Yylex();
result = Expression();
if( paramERR == 1 ) return 0;
if( result.type != CONSTINT) {
G4cerr << "Illegal Expression in parameter range." << G4endl;
return 0;
}
if ( result.I ) return 1;
G4cerr << "parameter out of range: "<< rangeString << G4endl;
return 0;
}
// ------------------ syntax node functions ------------------
yystype G4UIcommand::
Expression(void)
{
yystype result;
#ifdef DEBUG
G4cerr << " Expression()" << G4endl;
#endif
result = LogicalORExpression();
return result;
}
yystype G4UIcommand::
LogicalORExpression(void)
{
yystype result;
yystype p;
p = LogicalANDExpression();
if( token != LOGICALOR) return p;
if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
G4cerr << "Parameter range: illegal type at '||'" << G4endl;
paramERR = 1;
}
result.I = p.I;
while (token == LOGICALOR)
{
token = Yylex();
p = LogicalANDExpression();
if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
G4cerr << "Parameter range: illegal type at '||'" <<G4endl;
paramERR = 1;
}
switch (p.type) {
case CONSTINT:
result.I += p.I;
result.type = CONSTINT; break;
case CONSTDOUBLE:
result.I += (p.D != 0.0);
result.type = CONSTINT; break;
default:
G4cerr << "Parameter range: unknown type"<<G4endl;
paramERR = 1;
}
}
return result;
}
yystype G4UIcommand::
LogicalANDExpression(void)
{
yystype result;
yystype p;
p = EqualityExpression();
if( token != LOGICALAND) return p;
if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
paramERR = 1;
}
result.I = p.I;
while (token == LOGICALAND)
{
token = Yylex();
p = EqualityExpression();
if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
paramERR = 1;
}
switch (p.type) {
case CONSTINT:
result.I *= p.I;
result.type = CONSTINT; break;
case CONSTDOUBLE:
result.I *= (p.D != 0.0);
result.type = CONSTINT; break;
default:
G4cerr << "Parameter range: unknown type."<< G4endl;
paramERR = 1;
}
}
return result;
}
yystype G4UIcommand::
EqualityExpression(void)
{
yystype arg1, arg2;
int operat;
yystype result;
#ifdef DEBUG
G4cerr << " EqualityExpression()" <<G4endl;
#endif
result = RelationalExpression();
if( token==EQ || token==NE ) {
operat = token;
token = Yylex();
arg1 = result;
arg2 = RelationalExpression();
result.I = Eval2( arg1, operat, arg2 ); // semantic action
result.type = CONSTINT;
#ifdef DEBUG
G4cerr << " return code of Eval2(): " << result.I <<G4endl;
#endif
} else {
if (result.type != CONSTINT && result.type != CONSTDOUBLE) {
G4cerr << "Parameter range: error at EqualityExpression"
<< G4endl;
paramERR = 1;
}
}
return result;
}
yystype G4UIcommand::
RelationalExpression(void)
{
yystype arg1, arg2;
int operat;
yystype result;
#ifdef DEBUG
G4cerr << " RelationalExpression()" <<G4endl;
#endif
arg1 = AdditiveExpression();
if( token==GT || token==GE || token==LT || token==LE ) {
operat = token;
token = Yylex();
arg2 = AdditiveExpression();
result.I = Eval2( arg1, operat, arg2 ); // semantic action
result.type = CONSTINT;
#ifdef DEBUG
G4cerr << " return code of Eval2(): " << result.I << G4endl;
#endif
} else {
result = arg1;
}
#ifdef DEBUG
G4cerr <<" return RelationalExpression()"<< G4endl;
#endif
return result;
}
yystype G4UIcommand::
AdditiveExpression(void)
{ yystype result;
result = MultiplicativeExpression();
if( token != '+' && token != '-' ) return result;
G4cerr << "Parameter range: operator "
<< (char)token
<< " is not supported." << G4endl;
paramERR = 1;
return result;
}
yystype G4UIcommand::
MultiplicativeExpression(void)
{ yystype result;
result = UnaryExpression();
if( token != '*' && token != '/' && token != '%' ) return result;
G4cerr << "Parameter range: operator "
<< (char)token
<< " is not supported." << G4endl;
paramERR = 1;
return result;
}
yystype G4UIcommand::
UnaryExpression(void)
{
yystype result;
yystype p;
#ifdef DEBUG
G4cerr <<" UnaryExpression"<< G4endl;
#endif
switch(token) {
case '-':
token = Yylex();
p = UnaryExpression();
if (p.type == CONSTINT) {
result.I = - p.I;
result.type = CONSTINT;
}
if (p.type == CONSTDOUBLE) {
result.D = - p.D;
result.type = CONSTDOUBLE;
} break;
case '+':
token = Yylex();
result = UnaryExpression(); break;
case '!':
token = Yylex();
G4cerr << "Parameter range error: "
<< "operator '!' is not supported (sorry)."
<< G4endl;
paramERR = 1;
result = UnaryExpression(); break;
default:
result = PrimaryExpression();
}
return result;
}
yystype G4UIcommand::
PrimaryExpression(void)
{
yystype result;
#ifdef DEBUG
G4cerr <<" primary_exp"<<G4endl;
#endif
switch (token) {
case IDENTIFIER:
result.S = yylval.S;
result.type = token;
token = Yylex(); break;
case CONSTINT:
result.I = yylval.I;
result.type = token;
token= Yylex(); break;
case CONSTDOUBLE:
result.D = yylval.D;
result.type = token;
token = Yylex(); break;
case '(' :
token= Yylex();
result = Expression();
if( token != ')' ) {
G4cerr << " ')' expected" << G4endl;
paramERR = 1;
}
token = Yylex();
break;
default:
return result;
}
return result; // never executed
}
//---------------- semantic routines ---------------------------------
int G4UIcommand::
Eval2(yystype arg1, int op, yystype arg2)
{
char newValtype;
if( (arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER)) {
G4cerr << commandName
<< ": meaningless comparison"
<< G4endl;
paramERR = 1;
}
if( arg1.type == IDENTIFIER) {
unsigned i = IndexOf( arg1.S );
newValtype = toupper(parameter(i)->GetParameterType());
switch ( newValtype ) {
case 'I':
if( arg2.type == CONSTINT ) {
return CompareInt( newVal(i).I, op, arg2.I );
} else {
G4cerr << "integer operand expected for "
<< rangeString
<< '.' << G4endl;
} break;
case 'D':
if( arg2.type == CONSTDOUBLE ) {
return CompareDouble( newVal(i).D, op, arg2.D );
} else
if ( arg2.type == CONSTINT ) { // integral promotion
return CompareDouble( newVal(i).D, op, arg2.I );
} break;
default: ;
}
}
if( arg2.type == IDENTIFIER) {
unsigned i = IndexOf( arg2.S );
newValtype = toupper(parameter(i)->GetParameterType());
switch ( newValtype ) {
case 'I':
if( arg1.type == CONSTINT ) {
return CompareInt( arg1.I, op, newVal(i).I );
} else {
G4cerr << "integer operand expected for "
<< rangeString
<< '.' << G4endl;
} break;
case 'D':
if( arg1.type == CONSTDOUBLE ) {
return CompareDouble( arg1.D, op, newVal(i).D );
} else
if ( arg1.type == CONSTINT ) { // integral promotion
return CompareDouble( arg1.I, op, newVal(i).D );
} break;
default: ;
}
}
return 0;
}
int G4UIcommand::
CompareInt(int arg1, int op, int arg2)
{
int result;
G4String opr;
switch (op) {
case GT: result = ( arg1 > arg2); opr= ">" ; break;
case GE: result = ( arg1 >= arg2); opr= ">="; break;
case LT: result = ( arg1 < arg2); opr= "<" ; break;
case LE: result = ( arg1 <= arg2); opr= "<="; break;
case EQ: result = ( arg1 == arg2); opr= "=="; break;
case NE: result = ( arg1 != arg2); opr= "!="; break;
default:
G4cerr << "Parameter range: error at CompareInt" << G4endl;
paramERR = 1;
}
#ifdef DEBUG
G4cerr << "CompareInt "
<< arg1 << " " << opr << arg2
<< " result: " << result
<< G4endl;
#endif
return result;
}
int G4UIcommand::
CompareDouble(double arg1, int op, double arg2)
{
int result;
G4String opr;
switch (op) {
case GT: result = ( arg1 > arg2); opr= ">"; break;
case GE: result = ( arg1 >= arg2); opr= ">="; break;
case LT: result = ( arg1 < arg2); opr= "<"; break;
case LE: result = ( arg1 <= arg2); opr= "<="; break;
case EQ: result = ( arg1 == arg2); opr= "=="; break;
case NE: result = ( arg1 != arg2); opr= "!="; break;
default:
G4cerr << "Parameter range: error at CompareDouble"
<< G4endl;
paramERR = 1;
}
#ifdef DEBUG
G4cerr << "CompareDouble "
<< arg1 <<" " << opr << " "<< arg2
<< " result: " << result
<< G4endl;
#endif
return result;
}
unsigned G4UIcommand::
IndexOf( G4String nam)
{
unsigned i;
G4String pname;
for( i=0; i<parameter.entries(); i++)
{
pname = parameter(i)-> GetParameterName();
if( pname == nam ) {
return i;
}
}
paramERR = 1;
G4cerr << "parameter name:"<<nam<<" not found."<< G4endl;
return 0;
}
unsigned G4UIcommand::
IsParameter(G4String nam)
{
G4String pname;
for(unsigned i=0; i<parameter.entries(); i++)
{
pname = parameter(i)-> GetParameterName();
if( pname == nam ) return 1;
}
return 0;
}
// --------------------- utility functions --------------------------
tokenNum G4UIcommand::
Yylex() // reads input and returns token number, KR486
{ // (returns EOF)
int c;
G4String buf;
while(( c= G4UIpGetc())==' '|| c=='\t' || c== '\n' )
;
if (c== EOF)
return (tokenNum)EOF; // KR488
buf= "";
if (isdigit(c) || c== '.') { // I or D
do {
buf += G4String((unsigned char)c);
c=G4UIpGetc();
} while (c=='.' || isdigit(c) ||
c=='e' || c=='E' || c=='+' || c=='-');
G4UIpUngetc(c);
const char* t = buf;
G4std::istrstream is((char*)t);
if ( IsInt(buf.data(),20) ) {
is >> yylval.I;
return CONSTINT;
} else
if ( IsDouble(buf.data()) ) {
is >> yylval.D;
return CONSTDOUBLE;
} else {
G4cerr << buf<<": numeric format error."<<G4endl;
}
}
buf="";
if (isalpha(c)|| c=='_') { // IDENTIFIER
do {
buf += G4String((unsigned char)c);
} while ((c=G4UIpGetc()) != EOF && (isalnum(c) || c=='_'));
G4UIpUngetc(c);
if( IsParameter(buf) ) {
yylval.S =buf;
return IDENTIFIER;
} else {
G4cerr << buf << " is not a parameter name."<< G4endl;
paramERR = 1;
}
}
switch (c) {
case '>': return (tokenNum) Follow('=', GE, GT);
case '<': return (tokenNum) Follow('=', LE, LT);
case '=': return (tokenNum) Follow('=', EQ, '=');
case '!': return (tokenNum) Follow('=', NE, '!');
case '|': return (tokenNum) Follow('|', LOGICALOR, '|');
case '&': return (tokenNum) Follow('&', LOGICALAND, '&');
default:
return (tokenNum) c;
}
}
int G4UIcommand::
Follow(int expect, int ifyes, int ifno)
{
int c = G4UIpGetc();
if ( c== expect)
return ifyes;
G4UIpUngetc(c);
return ifno;
}
//------------------ low level routines -----------------------------
int G4UIcommand::
G4UIpGetc() { // emulation of getc()
int length = rangeString.length();
if( bp < length)
return rangeString(bp++);
else
return EOF;
}
int G4UIcommand::
G4UIpUngetc(int c) { // emulation of ungetc()
if (c<0) return -1;
if (bp >0 && c == rangeString(bp-1)) {
--bp;
} else {
G4cerr << "G4UIpUngetc() failed." << G4endl;
G4cerr << "bp="<<bp <<" c="<<c
<< " pR(bp-1)=" << rangeString(bp-1)
<< G4endl;
paramERR = 1;
return -1;
}
return 0;
}