Geant4  10.01.p02
G4UIcommand.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4UIcommand.cc 84281 2014-10-13 07:21:50Z gcosmo $
28 //
29 //
30 
31 #include "G4UIcommand.hh"
32 #include "G4UImessenger.hh"
33 #include "G4UImanager.hh"
34 #include "G4UIcommandStatus.hh"
35 #include "G4StateManager.hh"
36 #include "G4UnitsTable.hh"
37 #include "G4Tokenizer.hh"
38 #include "G4ios.hh"
39 #include <sstream>
40 
42  : messenger(0), toBeBroadcasted(false), toBeFlushed(false), workerThreadOnly(false),
43  bp(0), token(IDENTIFIER), paramERR(0)
44 {
45 }
46 
47 G4UIcommand::G4UIcommand(const char * theCommandPath,
48  G4UImessenger * theMessenger, G4bool tBB)
49 :messenger(theMessenger),toBeBroadcasted(tBB),toBeFlushed(false), workerThreadOnly(false),
50 token(IDENTIFIER),paramERR(0)
51 {
52  G4String comStr = theCommandPath;
53  if(!theMessenger)
54  { // this must be a directory
55  if(comStr(comStr.length()-1)!='/')
56  {
57  G4cerr << "G4UIcommand Warning : " << G4endl;
58  G4cerr << " <" << theCommandPath << "> must be a directory." << G4endl;
59  G4cerr << " '/' is appended." << G4endl;
60  comStr += "/";
61  }
62  }
64  G4String nullString;
65  availabelStateList.clear();
72 }
73 
74 #ifdef G4MULTITHREADED
75 #include "G4Threading.hh"
76 #endif
77 
79 (const char * theCommandPath)
80 {
81  commandPath = theCommandPath;
82  commandName = theCommandPath;
83  G4int commandNameIndex = commandName.last('/');
84  commandName.remove(0,commandNameIndex+1);
85 #ifdef G4MULTITHREADED
86  if(messenger && messenger->CommandsShouldBeInMaster()
88  {
89  toBeBroadcasted = false;
91  }
92  else
94 #else
96 #endif
97 }
98 
100 {
101  G4UImanager* fUImanager = G4UImanager::GetUIpointer();
102  if(fUImanager) fUImanager->RemoveCommand(this);
103 
104  G4int n_parameterEntry = parameter.size();
105  for( G4int i_thParameter=0; i_thParameter < n_parameterEntry; i_thParameter++ )
106  { delete parameter[i_thParameter]; }
107  parameter.clear();
108 }
109 
111 {
112  return ( commandPath == right.GetCommandPath() );
113 }
114 
116 {
117  return ( commandPath != right.GetCommandPath() );
118 }
119 
120 #include "G4Threading.hh"
121 
123 {
124  G4String correctParameters;
125  G4int n_parameterEntry = parameter.size();
126  if( n_parameterEntry != 0 )
127  {
128  G4String aToken;
129  G4String correctToken;
130  G4Tokenizer parameterToken( parameterList );
131  for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
132  {
133  if(i_thParameter > 0)
134  {
135  correctParameters.append(" ");
136  }
137  aToken = parameterToken();
138  if( aToken.length()>0 && aToken(0)=='"' )
139  {
140  while( aToken(aToken.length()-1) != '"'
141  || ( aToken.length()==1 && aToken(0)=='"' ))
142  {
143  G4String additionalToken = parameterToken();
144  if( additionalToken.isNull() )
145  { return fParameterUnreadable+i_thParameter; }
146  aToken += " ";
147  aToken += additionalToken;
148  }
149  }
150  else if(i_thParameter==n_parameterEntry-1 && parameter[i_thParameter]->GetParameterType()=='s')
151  {
152  G4String anotherToken;
153  while(!((anotherToken=parameterToken()).isNull()))
154  {
155  G4int idxs = anotherToken.index("#");
156  if(idxs==G4int(std::string::npos))
157  {
158  aToken += " ";
159  aToken += anotherToken;
160  }
161  else if(idxs>0)
162  {
163  aToken += " ";
164  aToken += anotherToken(0,idxs);
165  break;
166  }
167  else
168  { break; }
169  }
170  }
171 
172  if( aToken.isNull() || aToken == "!" )
173  {
174  if(parameter[i_thParameter]->IsOmittable())
175  {
176  if(parameter[i_thParameter]->GetCurrentAsDefault())
177  {
179  G4String parVal;
180  for(G4int ii=0;ii<i_thParameter;ii++)
181  {
182  parVal = cvSt();
183  if (parVal(0)=='"')
184  {
185  while( parVal(parVal.length()-1) != '"' )
186  {
187  G4String additionalToken = cvSt();
188  if( additionalToken.isNull() )
189  { return fParameterUnreadable+i_thParameter; }
190  parVal += " ";
191  parVal += additionalToken;
192  }
193  }
194  }
195  G4String aCVToken = cvSt();
196  if (aCVToken(0)=='"')
197  {
198  while( aCVToken(aCVToken.length()-1) != '"' )
199  {
200  G4String additionalToken = cvSt();
201  if( additionalToken.isNull() )
202  { return fParameterUnreadable+i_thParameter; }
203  aCVToken += " ";
204  aCVToken += additionalToken;
205  }
206  // aCVToken.strip(G4String::both,'"');
207  }
208  correctParameters.append(aCVToken);
209  }
210  else
211  { correctParameters.append(parameter[i_thParameter]->GetDefaultValue()); }
212  }
213  else
214  { return fParameterUnreadable+i_thParameter; }
215  }
216  else
217  {
218  G4int stat = parameter[i_thParameter]->CheckNewValue( aToken );
219  if(stat) return stat+i_thParameter;
220  correctParameters.append(aToken);
221  }
222  }
223  }
224 
225  if(CheckNewValue( correctParameters ))
226  { return fParameterOutOfRange+99; }
227 
229 
230  messenger->SetNewValue( this, correctParameters );
231  return 0;
232 }
233 
235 {
236  return messenger->GetCurrentValue(this);
237 }
238 
240 {
241  availabelStateList.clear();
242  availabelStateList.push_back(s1);
243 }
244 
247 {
248  availabelStateList.clear();
249  availabelStateList.push_back(s1);
250  availabelStateList.push_back(s2);
251 }
252 
256 {
257  availabelStateList.clear();
258  availabelStateList.push_back(s1);
259  availabelStateList.push_back(s2);
260  availabelStateList.push_back(s3);
261 }
262 
267 {
268  availabelStateList.clear();
269  availabelStateList.push_back(s1);
270  availabelStateList.push_back(s2);
271  availabelStateList.push_back(s3);
272  availabelStateList.push_back(s4);
273 }
274 
280 {
281  availabelStateList.clear();
282  availabelStateList.push_back(s1);
283  availabelStateList.push_back(s2);
284  availabelStateList.push_back(s3);
285  availabelStateList.push_back(s4);
286  availabelStateList.push_back(s5);
287 }
288 
290 {
291  G4bool av = false;
292  G4ApplicationState currentState
294 
295  G4int nState = availabelStateList.size();
296  for(G4int i=0;i<nState;i++)
297  {
298  if(availabelStateList[i]==currentState)
299  {
300  av = true;
301  break;
302  }
303  }
304 
305  return av;
306 }
307 
308 G4double G4UIcommand::ValueOf(const char* unitName)
309 {
310  G4double value = 0.;
311  value = G4UnitDefinition::GetValueOf(unitName);
312  return value;
313 }
314 
315 G4String G4UIcommand::CategoryOf(const char* unitName)
316 {
317  return G4UnitDefinition::GetCategory(unitName);
318 }
319 
320 G4String G4UIcommand::UnitsList(const char* unitCategory)
321 {
322  G4String retStr;
324  size_t i;
325  for(i=0;i<UTbl.size();i++)
326  { if(UTbl[i]->GetName()==unitCategory) break; }
327  if(i==UTbl.size())
328  {
329  G4cerr << "Unit category <" << unitCategory << "> is not defined." << G4endl;
330  return retStr;
331  }
332  G4UnitsContainer& UCnt = UTbl[i]->GetUnitsList();
333  retStr = UCnt[0]->GetSymbol();
334  G4int je = UCnt.size();
335  for(G4int j=1;j<je;j++)
336  {
337  retStr += " ";
338  retStr += UCnt[j]->GetSymbol();
339  }
340  for(G4int k=0;k<je;k++)
341  {
342  retStr += " ";
343  retStr += UCnt[k]->GetName();
344  }
345  return retStr;
346 }
347 
349 {
350  G4cout << G4endl;
351  G4cout << G4endl;
352  if(commandPath(commandPath.length()-1)!='/')
353  { G4cout << "Command " << commandPath << G4endl; }
354  if(workerThreadOnly)
355  { G4cout << " ---- available only in worker thread" << G4endl; }
356  G4cout << "Guidance :" << G4endl;
357  G4int n_guidanceEntry = commandGuidance.size();
358  for( G4int i_thGuidance=0; i_thGuidance < n_guidanceEntry; i_thGuidance++ )
359  { G4cout << commandGuidance[i_thGuidance] << G4endl; }
360  if( ! rangeString.isNull() )
361  { G4cout << " Range of parameters : " << rangeString << G4endl; }
362  G4int n_parameterEntry = parameter.size();
363  if( n_parameterEntry > 0 )
364  {
365  for( G4int i_thParameter=0; i_thParameter<n_parameterEntry; i_thParameter++ )
366  { parameter[i_thParameter]->List(); }
367  }
368  G4cout << G4endl;
369 }
370 
372 {
373  G4String vl = "0";
374  if(boolVal) vl = "1";
375  return vl;
376 }
377 
379 {
380  std::ostringstream os;
381  os << intValue;
382  G4String vl = os.str();
383  return vl;
384 }
385 
387 {
388  std::ostringstream os;
389  os << doubleValue;
390  G4String vl = os.str();
391  return vl;
392 }
393 
394 G4String G4UIcommand::ConvertToString(G4double doubleValue,const char* unitName)
395 {
396  G4String unt = unitName;
397  G4double uv = ValueOf(unitName);
398 
399  std::ostringstream os;
400  os << doubleValue/uv << " " << unitName;
401  G4String vl = os.str();
402  return vl;
403 }
404 
406 {
407  std::ostringstream os;
408  os << vec.x() << " " << vec.y() << " " << vec.z();
409  G4String vl = os.str();
410  return vl;
411 }
412 
414 {
415  G4String unt = unitName;
416  G4double uv = ValueOf(unitName);
417 
418  std::ostringstream os;
419  os << vec.x()/uv << " " << vec.y()/uv << " " << vec.z()/uv
420  << " " << unitName;
421  G4String vl = os.str();
422  return vl;
423 }
424 
426 {
427  G4String v = st;
428  v.toUpper();
429  G4bool vl = false;
430  if( v=="Y" || v=="YES" || v=="1" || v=="T" || v=="TRUE" )
431  { vl = true; }
432  return vl;
433 }
434 
436 {
437  G4int vl;
438  std::istringstream is(st);
439  is >> vl;
440  return vl;
441 }
442 
444 {
445  G4double vl;
446  std::istringstream is(st);
447  is >> vl;
448  return vl;
449 }
450 
452 {
453  G4double vl;
454  char unts[30];
455 
456  std::istringstream is(st);
457  is >> vl >> unts;
458  G4String unt = unts;
459 
460  return (vl*ValueOf(unt));
461 }
462 
464 {
465  G4double vx;
466  G4double vy;
467  G4double vz;
468  std::istringstream is(st);
469  is >> vx >> vy >> vz;
470  return G4ThreeVector(vx,vy,vz);
471 }
472 
474 {
475  G4double vx;
476  G4double vy;
477  G4double vz;
478  char unts[30];
479  std::istringstream is(st);
480  is >> vx >> vy >> vz >> unts;
481  G4String unt = unts;
482  G4double uv = ValueOf(unt);
483  return G4ThreeVector(vx*uv,vy*uv,vz*uv);
484 }
485 
486 
487 // ----- the following is used by CheckNewValue() ------------
488 
489 
490 #include <ctype.h> // isalpha(), toupper()
491 
492 //#include "checkNewValue_debug.icc"
493 //#define DEBUG 1
494 
496 CheckNewValue(const char * newValue)
497 {
498  yystype result;
499  // if( TypeCheck(newValue) == 0 ) return 1;
500  if( ! rangeString.isNull() )
501  { if( RangeCheck(newValue) == 0 ) return fParameterOutOfRange; }
502  return 0; // succeeded
503 }
504 
505 // ------------------ type check routines -------------------
506 
508 TypeCheck(const char * t)
509 {
510  G4String aNewValue;
511  char type;
512  std::istringstream is(t);
513  for (unsigned i=0; i< parameter.size(); i++) {
514  is >> aNewValue;
515  type = toupper(parameter[i]->GetParameterType());
516  switch ( type ) {
517  case 'D':
518  if( IsDouble(aNewValue)==0 ){
519  G4cerr << aNewValue << ": double value expected."
520  << G4endl;
521  return 0;
522  } break;
523  case 'I':
524  if( IsInt(aNewValue,20)==0 ){
525  G4cerr <<aNewValue<<": integer expected."
526  <<G4endl;
527  return 0;
528  } break;
529  case 'S':
530  break;
531  case 'B':
532  aNewValue.toUpper();
533  if (aNewValue == "Y" || aNewValue == "N"
534  ||aNewValue == "YES" || aNewValue == "NO"
535  ||aNewValue == "1" || aNewValue == "0"
536  ||aNewValue == "T" || aNewValue == "F"
537  ||aNewValue == "TRUE" || aNewValue == "FALSE")
538  return 1;
539  else return 0;
540  break;
541  default: ;
542  }
543  }
544  return 1;
545 }
546 
547 
549 IsInt(const char* buf, short maxDigits)
550 {
551  const char* p= buf;
552  G4int length=0;
553  if( *p == '+' || *p == '-') { ++p; }
554  if( isdigit( (G4int)(*p) )) {
555  while( isdigit( (G4int)(*p) )) { ++p; ++length; }
556  if( *p == '\0' ) {
557  if( length > maxDigits) {
558  G4cerr <<"digit length exceeds"<<G4endl;
559  return 0;
560  }
561  return 1;
562  } else {
563  // G4cerr <<"illegal character after int:"<<buf<<G4endl;
564  }
565  } else {
566  // G4cerr <<"illegal int:"<<buf<<G4endl;
567  }
568  return 0;
569 }
570 
571 
573 ExpectExponent(const char* str) // used only by IsDouble()
574 {
575  G4int maxExplength;
576  if( IsInt( str, maxExplength=7 )) return 1;
577  else return 0;
578 }
579 
580 
582 IsDouble(const char* buf)
583 {
584  const char* p= buf;
585  switch( *p) {
586  case '+': case '-': ++p;
587  if( isdigit(*p) ) {
588  while( isdigit( (G4int)(*p) )) { ++p; }
589  switch ( *p ) {
590  case '\0': return 1;
591  // break;
592  case 'E': case 'e':
593  return ExpectExponent(++p );
594  // break;
595  case '.': ++p;
596  if( *p == '\0' ) return 1;
597  if( *p == 'e' || *p =='E' ) return ExpectExponent(++p );
598  if( isdigit(*p) ) {
599  while( isdigit( (G4int)(*p) )) { ++p; }
600  if( *p == '\0' ) return 1;
601  if( *p == 'e' || *p =='E') return ExpectExponent(++p);
602  } else return 0; break;
603  default: return 0;
604  }
605  }
606  if( *p == '.' ) { ++p;
607  if( isdigit(*p) ) {
608  while( isdigit( (G4int)(*p) )) { ++p; }
609  if( *p == '\0' ) return 1;
610  if( *p == 'e' || *p =='E') return ExpectExponent(++p);
611  }
612  }
613  break;
614  case '.': ++p;
615  if( isdigit(*p) ) {
616  while( isdigit( (G4int)(*p) )) { ++p; }
617  if( *p == '\0' ) return 1;
618  if( *p == 'e' || *p =='E' ) return ExpectExponent(++p);
619  } break;
620  default: // digit is expected
621  if( isdigit(*p) ) {
622  while( isdigit( (G4int)(*p) )) { ++p; }
623  if( *p == '\0' ) return 1;
624  if( *p == 'e' || *p =='E') return ExpectExponent(++p);
625  if( *p == '.' ) { ++p;
626  if( *p == '\0' ) return 1;
627  if( *p == 'e' || *p =='E') return ExpectExponent(++p);
628  if( isdigit(*p) ) {
629  while( isdigit( (G4int)(*p) )) { ++p; }
630  if( *p == '\0' ) return 1;
631  if( *p == 'e' || *p =='E') return ExpectExponent(++p);
632  }
633  }
634  }
635  }
636  return 0;
637 }
638 
639 
640 // ------------------ range Check routines -------------------
642 RangeCheck(const char* t) {
643  yystype result;
644  char type;
645  bp = 0; // reset buffer pointer for G4UIpGetc()
646  std::istringstream is(t);
647  for (unsigned i=0; i< parameter.size(); i++) {
648  type= toupper(parameter[i]->GetParameterType());
649  switch ( type ) {
650  case 'D': is >> newVal[i].D; break;
651  case 'I': is >> newVal[i].I; break;
652  case 'S':
653  case 'B':
654  default: ;
655  }
656  }
657  // PrintToken(); // Print tokens (consumes all tokens)
658  token= Yylex();
659  result = Expression();
660 
661  if( paramERR == 1 ) return 0;
662  if( result.type != CONSTINT) {
663  G4cerr << "Illegal Expression in parameter range." << G4endl;
664  return 0;
665  }
666  if ( result.I ) return 1;
667  G4cerr << "parameter out of range: "<< rangeString << G4endl;
668  return 0;
669 }
670 
671 // ------------------ syntax node functions ------------------
674 {
675  yystype result;
676  #ifdef DEBUG
677  G4cerr << " Expression()" << G4endl;
678  #endif
679  result = LogicalORExpression();
680  return result;
681 }
682 
685 {
686  yystype result;
687  yystype p;
688  p = LogicalANDExpression();
689  if( token != LOGICALOR) return p;
690  if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
691  G4cerr << "Parameter range: illegal type at '||'" << G4endl;
692  paramERR = 1;
693  }
694  result.I = p.I;
695  while (token == LOGICALOR)
696  {
697  token = Yylex();
698  p = LogicalANDExpression();
699  if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
700  G4cerr << "Parameter range: illegal type at '||'" <<G4endl;
701  paramERR = 1;
702  }
703  switch (p.type) {
704  case CONSTINT:
705  result.I += p.I;
706  result.type = CONSTINT; break;
707  case CONSTDOUBLE:
708  result.I += (p.D != 0.0);
709  result.type = CONSTINT; break;
710  default:
711  G4cerr << "Parameter range: unknown type"<<G4endl;
712  paramERR = 1;
713  }
714  }
715  return result;
716 }
717 
720 {
721  yystype result;
722  yystype p;
723  p = EqualityExpression();
724  if( token != LOGICALAND) return p;
725  if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
726  G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
727  paramERR = 1;
728  }
729  result.I = p.I;
730  while (token == LOGICALAND)
731  {
732  token = Yylex();
733  p = EqualityExpression();
734  if( p.type == CONSTSTRING || p.type == IDENTIFIER ) {
735  G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
736  paramERR = 1;
737  }
738  switch (p.type) {
739  case CONSTINT:
740  result.I *= p.I;
741  result.type = CONSTINT; break;
742  case CONSTDOUBLE:
743  result.I *= (p.D != 0.0);
744  result.type = CONSTINT; break;
745  default:
746  G4cerr << "Parameter range: unknown type."<< G4endl;
747  paramERR = 1;
748  }
749  }
750  return result;
751 }
752 
753 
756 {
757  yystype arg1, arg2;
758  G4int operat;
759  yystype result;
760  #ifdef DEBUG
761  G4cerr << " EqualityExpression()" <<G4endl;
762  #endif
763  result = RelationalExpression();
764  if( token==EQ || token==NE ) {
765  operat = token;
766  token = Yylex();
767  arg1 = result;
768  arg2 = RelationalExpression();
769  result.I = Eval2( arg1, operat, arg2 ); // semantic action
770  result.type = CONSTINT;
771  #ifdef DEBUG
772  G4cerr << " return code of Eval2(): " << result.I <<G4endl;
773  #endif
774  } else {
775  if (result.type != CONSTINT && result.type != CONSTDOUBLE) {
776  G4cerr << "Parameter range: error at EqualityExpression"
777  << G4endl;
778  paramERR = 1;
779  }
780  }
781  return result;
782 }
783 
784 
787 {
788  yystype arg1, arg2;
789  G4int operat;
790  yystype result;
791  #ifdef DEBUG
792  G4cerr << " RelationalExpression()" <<G4endl;
793  #endif
794 
795  arg1 = AdditiveExpression();
796  if( token==GT || token==GE || token==LT || token==LE ) {
797  operat = token;
798  token = Yylex();
799  arg2 = AdditiveExpression();
800  result.I = Eval2( arg1, operat, arg2 ); // semantic action
801  result.type = CONSTINT;
802  #ifdef DEBUG
803  G4cerr << " return code of Eval2(): " << result.I << G4endl;
804  #endif
805  } else {
806  result = arg1;
807  }
808  #ifdef DEBUG
809  G4cerr <<" return RelationalExpression()"<< G4endl;
810  #endif
811  return result;
812 }
813 
816 { yystype result;
817  result = MultiplicativeExpression();
818  if( token != '+' && token != '-' ) return result;
819  G4cerr << "Parameter range: operator "
820  << (char)token
821  << " is not supported." << G4endl;
822  paramERR = 1;
823  return result;
824 }
825 
828 { yystype result;
829  result = UnaryExpression();
830  if( token != '*' && token != '/' && token != '%' ) return result;
831  G4cerr << "Parameter range: operator "
832  << (char)token
833  << " is not supported." << G4endl;
834  paramERR = 1;
835  return result;
836 }
837 
840 {
841  yystype result;
842  yystype p;
843  #ifdef DEBUG
844  G4cerr <<" UnaryExpression"<< G4endl;
845  #endif
846  switch(token) {
847  case '-':
848  token = Yylex();
849  p = UnaryExpression();
850  if (p.type == CONSTINT) {
851  result.I = - p.I;
852  result.type = CONSTINT;
853  }
854  if (p.type == CONSTDOUBLE) {
855  result.D = - p.D;
856  result.type = CONSTDOUBLE;
857  } break;
858  case '+':
859  token = Yylex();
860  result = UnaryExpression(); break;
861  case '!':
862  token = Yylex();
863  G4cerr << "Parameter range error: "
864  << "operator '!' is not supported (sorry)."
865  << G4endl;
866  paramERR = 1;
867  result = UnaryExpression(); break;
868  default:
869  result = PrimaryExpression();
870  }
871  return result;
872 }
873 
874 
877 {
878  yystype result;
879  #ifdef DEBUG
880  G4cerr <<" primary_exp"<<G4endl;
881  #endif
882  switch (token) {
883  case IDENTIFIER:
884  result.S = yylval.S;
885  result.type = token;
886  token = Yylex(); break;
887  case CONSTINT:
888  result.I = yylval.I;
889  result.type = token;
890  token= Yylex(); break;
891  case CONSTDOUBLE:
892  result.D = yylval.D;
893  result.type = token;
894  token = Yylex(); break;
895  case '(' :
896  token= Yylex();
897  result = Expression();
898  if( token != ')' ) {
899  G4cerr << " ')' expected" << G4endl;
900  paramERR = 1;
901  }
902  token = Yylex();
903  break;
904  default:
905  return result;
906  }
907  return result; // never executed
908 }
909 
910 //---------------- semantic routines ---------------------------------
911 
913 Eval2(yystype arg1, G4int op, yystype arg2)
914 {
915  char newValtype;
916  if( (arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER)) {
918  << ": meaningless comparison"
919  << G4endl;
920  paramERR = 1;
921  }
922 
923  if( arg1.type == IDENTIFIER) {
924  unsigned i = IndexOf( arg1.S );
925  newValtype = toupper(parameter[i]->GetParameterType());
926  switch ( newValtype ) {
927  case 'I':
928  if( arg2.type == CONSTINT ) {
929  return CompareInt( newVal[i].I, op, arg2.I );
930  } else {
931  G4cerr << "integer operand expected for "
932  << rangeString
933  << '.' << G4endl;
934  } break;
935  case 'D':
936  if( arg2.type == CONSTDOUBLE ) {
937  return CompareDouble( newVal[i].D, op, arg2.D );
938  } else
939  if ( arg2.type == CONSTINT ) { // integral promotion
940  return CompareDouble( newVal[i].D, op, arg2.I );
941  } break;
942  default: ;
943  }
944  }
945  if( arg2.type == IDENTIFIER) {
946  unsigned i = IndexOf( arg2.S );
947  newValtype = toupper(parameter[i]->GetParameterType());
948  switch ( newValtype ) {
949  case 'I':
950  if( arg1.type == CONSTINT ) {
951  return CompareInt( arg1.I, op, newVal[i].I );
952  } else {
953  G4cerr << "integer operand expected for "
954  << rangeString
955  << '.' << G4endl;
956  } break;
957  case 'D':
958  if( arg1.type == CONSTDOUBLE ) {
959  return CompareDouble( arg1.D, op, newVal[i].D );
960  } else
961  if ( arg1.type == CONSTINT ) { // integral promotion
962  return CompareDouble( arg1.I, op, newVal[i].D );
963  } break;
964  default: ;
965  }
966  }
967  return 0;
968 }
969 
971 CompareInt(G4int arg1, G4int op, G4int arg2)
972 {
973  G4int result=-1;
974  G4String opr;
975  switch (op) {
976  case GT: result = ( arg1 > arg2); opr= ">" ; break;
977  case GE: result = ( arg1 >= arg2); opr= ">="; break;
978  case LT: result = ( arg1 < arg2); opr= "<" ; break;
979  case LE: result = ( arg1 <= arg2); opr= "<="; break;
980  case EQ: result = ( arg1 == arg2); opr= "=="; break;
981  case NE: result = ( arg1 != arg2); opr= "!="; break;
982  default:
983  G4cerr << "Parameter range: error at CompareInt" << G4endl;
984  paramERR = 1;
985  }
986  #ifdef DEBUG
987  G4cerr << "CompareInt "
988  << arg1 << " " << opr << arg2
989  << " result: " << result
990  << G4endl;
991  #endif
992  return result;
993 }
994 
997 {
998  G4int result=-1;
999  G4String opr;
1000  switch (op) {
1001  case GT: result = ( arg1 > arg2); opr= ">"; break;
1002  case GE: result = ( arg1 >= arg2); opr= ">="; break;
1003  case LT: result = ( arg1 < arg2); opr= "<"; break;
1004  case LE: result = ( arg1 <= arg2); opr= "<="; break;
1005  case EQ: result = ( arg1 == arg2); opr= "=="; break;
1006  case NE: result = ( arg1 != arg2); opr= "!="; break;
1007  default:
1008  G4cerr << "Parameter range: error at CompareDouble"
1009  << G4endl;
1010  paramERR = 1;
1011  }
1012  #ifdef DEBUG
1013  G4cerr << "CompareDouble "
1014  << arg1 <<" " << opr << " "<< arg2
1015  << " result: " << result
1016  << G4endl;
1017  #endif
1018  return result;
1019 }
1020 
1021 unsigned G4UIcommand::
1022 IndexOf(const char* nam)
1023 {
1024  unsigned i;
1025  G4String pname;
1026  for( i=0; i<parameter.size(); i++)
1027  {
1028  pname = parameter[i]-> GetParameterName();
1029  if( pname == nam ) {
1030  return i;
1031  }
1032  }
1033  paramERR = 1;
1034  G4cerr << "parameter name:"<<nam<<" not found."<< G4endl;
1035  return 0;
1036 }
1037 
1038 
1039 unsigned G4UIcommand::
1040 IsParameter(const char* nam)
1041 {
1042  G4String pname;
1043  for(unsigned i=0; i<parameter.size(); i++)
1044  {
1045  pname = parameter[i]-> GetParameterName();
1046  if( pname == nam ) return 1;
1047  }
1048  return 0;
1049 }
1050 
1051 
1052 // --------------------- utility functions --------------------------
1053 
1055 Yylex() // reads input and returns token number, KR486
1056 { // (returns EOF)
1057  G4int c;
1058  G4String buf;
1059 
1060  while(( c= G4UIpGetc())==' '|| c=='\t' || c== '\n' )
1061  ;
1062  if (c== EOF)
1063  return (tokenNum)EOF; // KR488
1064  buf= "";
1065  if (isdigit(c) || c== '.') { // I or D
1066  do {
1067  buf += G4String((unsigned char)c);
1068  c=G4UIpGetc();
1069  } while (c=='.' || isdigit(c) ||
1070  c=='e' || c=='E' || c=='+' || c=='-');
1071  G4UIpUngetc(c);
1072  const char* t = buf;
1073  std::istringstream is(t);
1074  if ( IsInt(buf.data(),20) ) {
1075  is >> yylval.I;
1076  return CONSTINT;
1077  } else
1078  if ( IsDouble(buf.data()) ) {
1079  is >> yylval.D;
1080  return CONSTDOUBLE;
1081  } else {
1082  G4cerr << buf<<": numeric format error."<<G4endl;
1083  }
1084  }
1085  buf="";
1086  if (isalpha(c)|| c=='_') { // IDENTIFIER
1087  do {
1088  buf += G4String((unsigned char)c);
1089  } while ((c=G4UIpGetc()) != EOF && (isalnum(c) || c=='_'));
1090  G4UIpUngetc(c);
1091  if( IsParameter(buf) ) {
1092  yylval.S =buf;
1093  return IDENTIFIER;
1094  } else {
1095  G4cerr << buf << " is not a parameter name."<< G4endl;
1096  paramERR = 1;
1097  }
1098  }
1099  switch (c) {
1100  case '>': return (tokenNum) Follow('=', GE, GT);
1101  case '<': return (tokenNum) Follow('=', LE, LT);
1102  case '=': return (tokenNum) Follow('=', EQ, '=');
1103  case '!': return (tokenNum) Follow('=', NE, '!');
1104  case '|': return (tokenNum) Follow('|', LOGICALOR, '|');
1105  case '&': return (tokenNum) Follow('&', LOGICALAND, '&');
1106  default:
1107  return (tokenNum) c;
1108  }
1109 }
1110 
1111 
1113 Follow(G4int expect, G4int ifyes, G4int ifno)
1114 {
1115  G4int c = G4UIpGetc();
1116  if ( c== expect)
1117  return ifyes;
1118  G4UIpUngetc(c);
1119  return ifno;
1120 }
1121 
1122 //------------------ low level routines -----------------------------
1124 G4UIpGetc() { // emulation of getc()
1125  G4int length = rangeString.length();
1126  if( bp < length)
1127  return rangeString(bp++);
1128  else
1129  return EOF;
1130 }
1132 G4UIpUngetc(G4int c) { // emulation of ungetc()
1133  if (c<0) return -1;
1134  if (bp >0 && c == rangeString(bp-1)) {
1135  --bp;
1136  } else {
1137  G4cerr << "G4UIpUngetc() failed." << G4endl;
1138  G4cerr << "bp="<<bp <<" c="<<c
1139  << " pR(bp-1)=" << rangeString(bp-1)
1140  << G4endl;
1141  paramERR = 1;
1142  return -1;
1143  }
1144  return 0;
1145 }
G4UImessenger * messenger
Definition: G4UIcommand.hh:116
yystype MultiplicativeExpression(void)
Definition: G4UIcommand.cc:827
std::vector< yystype > newVal
Definition: G4UIcommand.hh:236
tokenNum
Definition: G4UItokenNum.hh:36
G4int Eval2(yystype arg1, G4int op, yystype arg2)
Definition: G4UIcommand.cc:913
G4String commandName
Definition: G4UIcommand.hh:118
G4bool IsAvailable()
Definition: G4UIcommand.cc:289
G4int G4UIpGetc(void)
virtual G4String GetCurrentValue(G4UIcommand *command)
CLHEP::Hep3Vector G4ThreeVector
G4int operator!=(const G4UIcommand &right) const
Definition: G4UIcommand.cc:115
static G4UImanager * GetMasterUIpointer()
Definition: G4UImanager.cc:71
G4String S
Definition: G4UItokenNum.hh:66
G4int IsInt(const char *str, short maxLength)
Definition: G4UIcommand.cc:549
Definition: Evaluator.cc:66
std::vector< G4UnitsCategory * > G4UnitsTable
Definition: G4UnitsTable.hh:59
unsigned IndexOf(const char *)
yystype PrimaryExpression(void)
Definition: G4UIcommand.cc:876
virtual void SetNewValue(G4UIcommand *command, G4String newValue)
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:371
G4int CompareDouble(G4double arg1, G4int op, G4double arg2)
Definition: G4UIcommand.cc:996
tokenNum Yylex(void)
G4int TypeCheck(const char *t)
Definition: G4UIcommand.cc:508
G4String rangeString
Definition: G4UIcommand.hh:119
Definition: Evaluator.cc:66
std::vector< G4ApplicationState > availabelStateList
Definition: G4UIcommand.hh:122
yystype UnaryExpression(void)
Definition: G4UIcommand.cc:839
int G4int
Definition: G4Types.hh:78
G4int paramERR
Definition: G4UIcommand.hh:237
static G4ThreeVector ConvertTo3Vector(const char *st)
Definition: G4UIcommand.cc:463
static G4double ConvertToDimensionedDouble(const char *st)
Definition: G4UIcommand.cc:451
G4int Follow(G4int expect, G4int ifyes, G4int ifno)
G4int ExpectExponent(const char *str)
Definition: G4UIcommand.cc:573
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:58
Definition: Evaluator.cc:66
tokenNum token
Definition: G4UIcommand.hh:234
static G4StateManager * GetStateManager()
static G4double GetValueOf(const G4String &)
yystype LogicalANDExpression(void)
Definition: G4UIcommand.cc:719
G4GLOB_DLL std::ostream G4cout
G4bool workerThreadOnly
Definition: G4UIcommand.hh:181
G4int CheckNewValue(const char *newValue)
Definition: G4UIcommand.cc:496
yystype LogicalORExpression(void)
Definition: G4UIcommand.cc:684
str_size index(const char *, G4int pos=0) const
G4int I
Definition: G4UItokenNum.hh:64
void G4UIcommandCommonConstructorCode(const char *theCommandPath)
Definition: G4UIcommand.cc:79
static G4String UnitsList(const char *unitCategory)
Definition: G4UIcommand.cc:320
static G4bool ConvertToBool(const char *st)
Definition: G4UIcommand.cc:425
void toUpper()
yystype Expression(void)
Definition: G4UIcommand.cc:673
unsigned IsParameter(const char *)
bool G4bool
Definition: G4Types.hh:79
G4int IsDouble(const char *str)
Definition: G4UIcommand.cc:582
static G4double ConvertToDouble(const char *st)
Definition: G4UIcommand.cc:443
void RemoveCommand(G4UIcommand *aCommand)
Definition: G4UImanager.cc:266
const G4String & GetCommandPath() const
Definition: G4UIcommand.hh:139
void AvailableForStates(G4ApplicationState s1)
Definition: G4UIcommand.cc:239
G4ApplicationState GetCurrentState() const
Definition: Evaluator.cc:66
tokenNum type
Definition: G4UItokenNum.hh:62
yystype AdditiveExpression(void)
Definition: G4UIcommand.cc:815
static G4int ConvertToInt(const char *st)
Definition: G4UIcommand.cc:435
G4bool IsWorkerThread()
Definition: G4Threading.cc:128
static G4UnitsTable & GetUnitsTable()
G4int operator==(const G4UIcommand &right) const
Definition: G4UIcommand.cc:110
static G4String GetCategory(const G4String &)
Definition: Evaluator.cc:66
const char * data() const
yystype yylval
Definition: G4UIcommand.hh:235
void AddNewCommand(G4UIcommand *newCommand)
Definition: G4UImanager.cc:254
G4int G4UIpUngetc(G4int c)
G4String & append(const G4String &)
static G4double ValueOf(const char *unitName)
Definition: G4UIcommand.cc:308
static const G4double bp
yystype EqualityExpression(void)
Definition: G4UIcommand.cc:755
yystype RelationalExpression(void)
Definition: G4UIcommand.cc:786
#define G4endl
Definition: G4ios.hh:61
G4String commandPath
Definition: G4UIcommand.hh:117
Definition: Evaluator.cc:66
double G4double
Definition: G4Types.hh:76
std::vector< G4UnitDefinition * > G4UnitsContainer
std::vector< G4String > commandGuidance
Definition: G4UIcommand.hh:121
G4double D
Definition: G4UItokenNum.hh:63
virtual void List()
Definition: G4UIcommand.cc:348
virtual ~G4UIcommand()
Definition: G4UIcommand.cc:99
std::vector< G4UIparameter * > parameter
Definition: G4UIcommand.hh:120
static G4String CategoryOf(const char *unitName)
Definition: G4UIcommand.cc:315
G4bool isNull() const
virtual G4int DoIt(G4String parameterList)
Definition: G4UIcommand.cc:122
G4int CompareInt(G4int arg1, G4int op, G4int arg2)
Definition: G4UIcommand.cc:971
G4ApplicationState
G4String GetCurrentValue()
Definition: G4UIcommand.cc:234
G4int RangeCheck(const char *t)
Definition: G4UIcommand.cc:642
G4GLOB_DLL std::ostream G4cerr
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
Definition: G4UIcommand.cc:473