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