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