Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// G4UIcommand
27//
28// Author: Makoto Asai (SLAC), 1998
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
42#include "G4UItokenNum.hh"
43
44#include "G4Threading.hh"
45
46using namespace G4UItokenNum;
47
48// --------------------------------------------------------------------
50{
51}
52
53// --------------------------------------------------------------------
54G4UIcommand::G4UIcommand(const char* theCommandPath,
55 G4UImessenger* theMessenger, G4bool tBB)
56 : toBeBroadcasted(tBB)
57 , messenger(theMessenger)
58{
59 G4String comStr = theCommandPath;
60 if(!theMessenger)
61 { // this must be a directory
62 if(comStr(comStr.length() - 1) != '/')
63 {
64 G4cerr << "G4UIcommand Warning : " << G4endl;
65 G4cerr << " <" << theCommandPath << "> must be a directory." << G4endl;
66 G4cerr << " '/' is appended." << G4endl;
67 comStr += "/";
68 }
69 }
70 G4UIcommandCommonConstructorCode(comStr);
71 G4String nullString;
72 availabelStateList.clear();
73 availabelStateList.push_back(G4State_PreInit);
74 availabelStateList.push_back(G4State_Init);
75 availabelStateList.push_back(G4State_Idle);
76 availabelStateList.push_back(G4State_GeomClosed);
77 availabelStateList.push_back(G4State_EventProc);
78 availabelStateList.push_back(G4State_Abort);
79}
80
81// --------------------------------------------------------------------
82void G4UIcommand::G4UIcommandCommonConstructorCode(const char* theCommandPath)
83{
84 commandPath = theCommandPath;
85 commandName = theCommandPath;
86 G4int commandNameIndex = commandName.last('/');
87 commandName.remove(0, commandNameIndex + 1);
88#ifdef G4MULTITHREADED
89 if(messenger && messenger->CommandsShouldBeInMaster() &&
91 {
92 toBeBroadcasted = false;
94 }
95 else
96 {
98 }
99#else
101#endif
102}
103
104// --------------------------------------------------------------------
106{
108 if(fUImanager)
109 {
110 fUImanager->RemoveCommand(this);
111 }
112
113 G4int n_parameterEntry = parameter.size();
114 for(G4int i_thParameter = 0; i_thParameter < n_parameterEntry;
115 ++i_thParameter)
116 {
117 delete parameter[i_thParameter];
118 }
119 parameter.clear();
120}
121
122// --------------------------------------------------------------------
124{
125 return (commandPath == right.GetCommandPath());
126}
127
128// --------------------------------------------------------------------
130{
131 return (commandPath != right.GetCommandPath());
132}
133
134// --------------------------------------------------------------------
136{
137 G4String correctParameters;
138 G4int n_parameterEntry = parameter.size();
139 if(n_parameterEntry != 0)
140 {
141 G4String aToken;
142 G4String correctToken;
143 G4Tokenizer parameterToken(parameterList);
144 for(G4int i_thParameter = 0; i_thParameter < n_parameterEntry;
145 ++i_thParameter)
146 {
147 if(i_thParameter > 0)
148 {
149 correctParameters.append(" ");
150 }
151 aToken = parameterToken();
152 if(aToken.length() > 0 && aToken(0) == '"')
153 {
154 while(aToken(aToken.length() - 1) != '"' ||
155 (aToken.length() == 1 && aToken(0) == '"'))
156 {
157 G4String additionalToken = parameterToken();
158 if(additionalToken.isNull())
159 {
160 return fParameterUnreadable + i_thParameter;
161 }
162 aToken += " ";
163 aToken += additionalToken;
164 }
165 }
166 else if(i_thParameter == n_parameterEntry - 1 &&
167 parameter[i_thParameter]->GetParameterType() == 's')
168 {
169 G4String anotherToken;
170 while(!((anotherToken = parameterToken()).isNull()))
171 {
172 G4int idxs = anotherToken.index("#");
173 if(idxs == G4int(std::string::npos))
174 {
175 aToken += " ";
176 aToken += anotherToken;
177 }
178 else if(idxs > 0)
179 {
180 aToken += " ";
181 aToken += anotherToken(0, idxs);
182 break;
183 }
184 else
185 {
186 break;
187 }
188 }
189 }
190
191 if(aToken.isNull() || aToken == "!")
192 {
193 if(parameter[i_thParameter]->IsOmittable())
194 {
195 if(parameter[i_thParameter]->GetCurrentAsDefault())
196 {
197 G4Tokenizer cvSt(messenger->GetCurrentValue(this));
198 G4String parVal;
199 for(G4int ii = 0; ii < i_thParameter; ++ii)
200 {
201 parVal = cvSt();
202 if(parVal(0) == '"')
203 {
204 while(parVal(parVal.length() - 1) != '"')
205 {
206 G4String additionalToken = cvSt();
207 if(additionalToken.isNull())
208 {
209 return fParameterUnreadable + i_thParameter;
210 }
211 parVal += " ";
212 parVal += additionalToken;
213 }
214 }
215 }
216 G4String aCVToken = cvSt();
217 if(aCVToken(0) == '"')
218 {
219 while(aCVToken(aCVToken.length() - 1) != '"')
220 {
221 G4String additionalToken = cvSt();
222 if(additionalToken.isNull())
223 {
224 return fParameterUnreadable + i_thParameter;
225 }
226 aCVToken += " ";
227 aCVToken += additionalToken;
228 }
229 // aCVToken.strip(G4String::both,'"');
230 }
231 correctParameters.append(aCVToken);
232 }
233 else
234 {
235 correctParameters.append(
236 parameter[i_thParameter]->GetDefaultValue());
237 }
238 }
239 else
240 {
241 return fParameterUnreadable + i_thParameter;
242 }
243 }
244 else
245 {
246 G4int stat = parameter[i_thParameter]->CheckNewValue(aToken);
247 if(stat)
248 return stat + i_thParameter;
249 correctParameters.append(aToken);
250 }
251 }
252 }
253
254 if(CheckNewValue(correctParameters))
255 {
256 return fParameterOutOfRange + 99;
257 }
258
260 return 0;
261
262 messenger->SetNewValue(this, correctParameters);
263 return 0;
264}
265
266// --------------------------------------------------------------------
268{
269 return messenger->GetCurrentValue(this);
270}
271
272// --------------------------------------------------------------------
274{
275 availabelStateList.clear();
276 availabelStateList.push_back(s1);
277}
278
279// --------------------------------------------------------------------
282{
283 availabelStateList.clear();
284 availabelStateList.push_back(s1);
285 availabelStateList.push_back(s2);
286}
287
288// --------------------------------------------------------------------
292{
293 availabelStateList.clear();
294 availabelStateList.push_back(s1);
295 availabelStateList.push_back(s2);
296 availabelStateList.push_back(s3);
297}
298
299// --------------------------------------------------------------------
304{
305 availabelStateList.clear();
306 availabelStateList.push_back(s1);
307 availabelStateList.push_back(s2);
308 availabelStateList.push_back(s3);
309 availabelStateList.push_back(s4);
310}
311
312// --------------------------------------------------------------------
318{
319 availabelStateList.clear();
320 availabelStateList.push_back(s1);
321 availabelStateList.push_back(s2);
322 availabelStateList.push_back(s3);
323 availabelStateList.push_back(s4);
324 availabelStateList.push_back(s5);
325}
326
327// --------------------------------------------------------------------
329{
330 G4bool av = false;
331 G4ApplicationState currentState =
333
334 G4int nState = availabelStateList.size();
335 for(G4int i = 0; i < nState; ++i)
336 {
337 if(availabelStateList[i] == currentState)
338 {
339 av = true;
340 break;
341 }
342 }
343
344 return av;
345}
346
347// --------------------------------------------------------------------
348G4double G4UIcommand::ValueOf(const char* unitName)
349{
350 G4double value = 0.;
351 value = G4UnitDefinition::GetValueOf(unitName);
352 return value;
353}
354
355// --------------------------------------------------------------------
357{
358 return G4UnitDefinition::GetCategory(unitName);
359}
360
361// --------------------------------------------------------------------
362G4String G4UIcommand::UnitsList(const char* unitCategory)
363{
364 G4String retStr;
366 std::size_t i;
367 for(i = 0; i < UTbl.size(); ++i)
368 {
369 if(UTbl[i]->GetName() == unitCategory)
370 break;
371 }
372 if(i == UTbl.size())
373 {
374 G4cerr << "Unit category <" << unitCategory << "> is not defined."
375 << G4endl;
376 return retStr;
377 }
378 G4UnitsContainer& UCnt = UTbl[i]->GetUnitsList();
379 retStr = UCnt[0]->GetSymbol();
380 G4int je = UCnt.size();
381 for(G4int j = 1; j < je; ++j)
382 {
383 retStr += " ";
384 retStr += UCnt[j]->GetSymbol();
385 }
386 for(G4int k = 0; k < je; ++k)
387 {
388 retStr += " ";
389 retStr += UCnt[k]->GetName();
390 }
391 return retStr;
392}
393
394// --------------------------------------------------------------------
396{
397 G4cout << G4endl;
398 G4cout << G4endl;
399 if(commandPath(commandPath.length() - 1) != '/')
400 {
401 G4cout << "Command " << commandPath << G4endl;
402 }
404 {
405 G4cout << " ---- available only in worker thread" << G4endl;
406 }
407 G4cout << "Guidance :" << G4endl;
408 G4int n_guidanceEntry = commandGuidance.size();
409 for(G4int i_thGuidance = 0; i_thGuidance < n_guidanceEntry; ++i_thGuidance)
410 {
411 G4cout << commandGuidance[i_thGuidance] << G4endl;
412 }
413 if(!rangeString.isNull())
414 {
415 G4cout << " Range of parameters : " << rangeString << G4endl;
416 }
417 G4int n_parameterEntry = parameter.size();
418 if(n_parameterEntry > 0)
419 {
420 for(G4int i_thParameter = 0; i_thParameter < n_parameterEntry;
421 ++i_thParameter)
422 {
423 parameter[i_thParameter]->List();
424 }
425 }
426 G4cout << G4endl;
427}
428
429// --------------------------------------------------------------------
431{
432 G4String vl = "0";
433 if(boolVal)
434 vl = "1";
435 return vl;
436}
437
438// --------------------------------------------------------------------
440{
441 std::ostringstream os;
442 os << intValue;
443 G4String vl = os.str();
444 return vl;
445}
446
447// --------------------------------------------------------------------
449{
450 std::ostringstream os;
451 os << longValue;
452 G4String vl = os.str();
453 return vl;
454}
455
456// --------------------------------------------------------------------
458{
459 std::ostringstream os;
461 {
462 os << std::setprecision(17) << doubleValue;
463 }
464 else
465 {
466 os << doubleValue;
467 }
468 G4String vl = os.str();
469 return vl;
470}
471
472// --------------------------------------------------------------------
474 const char* unitName)
475{
476 G4String unt = unitName;
477 G4double uv = ValueOf(unitName);
478
479 std::ostringstream os;
481 {
482 os << std::setprecision(17) << doubleValue / uv << " " << unitName;
483 }
484 else
485 {
486 os << doubleValue / uv << " " << unitName;
487 }
488 G4String vl = os.str();
489 return vl;
490}
491
492// --------------------------------------------------------------------
494{
495 std::ostringstream os;
497 {
498 os << std::setprecision(17) << vec.x() << " " << vec.y() << " " << vec.z();
499 }
500 else
501 {
502 os << vec.x() << " " << vec.y() << " " << vec.z();
503 }
504 G4String vl = os.str();
505 return vl;
506}
507
508// --------------------------------------------------------------------
510{
511 G4String unt = unitName;
512 G4double uv = ValueOf(unitName);
513
514 std::ostringstream os;
516 {
517 os << std::setprecision(17) << vec.x() / uv << " " << vec.y() / uv << " "
518 << vec.z() / uv << " " << unitName;
519 }
520 else
521 {
522 os << vec.x() / uv << " " << vec.y() / uv << " " << vec.z() / uv << " "
523 << unitName;
524 }
525 G4String vl = os.str();
526 return vl;
527}
528
529// --------------------------------------------------------------------
531{
532 G4String v = st;
533 v.toUpper();
534 G4bool vl = false;
535 if(v == "Y" || v == "YES" || v == "1" || v == "T" || v == "TRUE")
536 {
537 vl = true;
538 }
539 return vl;
540}
541
542// --------------------------------------------------------------------
544{
545 G4int vl;
546 std::istringstream is(st);
547 is >> vl;
548 return vl;
549}
550
551// --------------------------------------------------------------------
553{
554 G4long vl;
555 std::istringstream is(st);
556 is >> vl;
557 return vl;
558}
559
560// --------------------------------------------------------------------
562{
563 G4double vl;
564 std::istringstream is(st);
565 is >> vl;
566 return vl;
567}
568
569// --------------------------------------------------------------------
571{
572 G4double vl;
573 char unts[30];
574
575 std::istringstream is(st);
576 is >> vl >> unts;
577 G4String unt = unts;
578
579 return (vl * ValueOf(unt));
580}
581
582// --------------------------------------------------------------------
584{
585 G4double vx;
586 G4double vy;
587 G4double vz;
588 std::istringstream is(st);
589 is >> vx >> vy >> vz;
590 return G4ThreeVector(vx, vy, vz);
591}
592
593// --------------------------------------------------------------------
595{
596 G4double vx;
597 G4double vy;
598 G4double vz;
599 char unts[30];
600 std::istringstream is(st);
601 is >> vx >> vy >> vz >> unts;
602 G4String unt = unts;
603 G4double uv = ValueOf(unt);
604 return G4ThreeVector(vx * uv, vy * uv, vz * uv);
605}
606
607// ----- the following is used by CheckNewValue() --------------------
608
609#include <ctype.h> // isalpha(), toupper()
610
612{
613 yystype result;
614 // if( TypeCheck(newValue) == 0 ) return 1;
615 if(!rangeString.isNull())
616 {
617 if(RangeCheck(newValue) == 0)
619 }
620 return 0; // succeeded
621}
622
623// --------------------------------------------------------------------
624G4int G4UIcommand::TypeCheck(const char* t)
625{
626 G4String aNewValue;
627 char type;
628 std::istringstream is(t);
629 for(unsigned i = 0; i < parameter.size(); ++i)
630 {
631 is >> aNewValue;
632 type = toupper(parameter[i]->GetParameterType());
633 switch(type)
634 {
635 case 'D':
636 if(IsDouble(aNewValue) == 0)
637 {
638 G4cerr << aNewValue << ": double value expected." << G4endl;
639 return 0;
640 }
641 break;
642 case 'I':
643 if(IsInt(aNewValue, 10) == 0)
644 {
645 G4cerr << aNewValue << ": integer expected." << G4endl;
646 return 0;
647 }
648 break;
649 case 'L':
650 if(IsInt(aNewValue, 20) == 0)
651 {
652 G4cerr << aNewValue << ": long int expected." << G4endl;
653 return 0;
654 }
655 break;
656 case 'S':
657 break;
658 case 'B':
659 aNewValue.toUpper();
660 if(aNewValue == "Y" || aNewValue == "N" || aNewValue == "YES" ||
661 aNewValue == "NO" || aNewValue == "1" || aNewValue == "0" ||
662 aNewValue == "T" || aNewValue == "F" || aNewValue == "TRUE" ||
663 aNewValue == "FALSE")
664 return 1;
665 else
666 return 0;
667 break;
668 default:;
669 }
670 }
671 return 1;
672}
673
674// --------------------------------------------------------------------
675G4int G4UIcommand::IsInt(const char* buf, short maxDigits)
676{
677 const char* p = buf;
678 G4int length = 0;
679 if(*p == '+' || *p == '-')
680 {
681 ++p;
682 }
683 if(isdigit((G4int)(*p)))
684 {
685 while(isdigit((G4int)(*p)))
686 {
687 ++p;
688 ++length;
689 }
690 if(*p == '\0')
691 {
692 if(length > maxDigits)
693 {
694 G4cerr << "digit length exceeds" << G4endl;
695 return 0;
696 }
697 return 1;
698 }
699 else
700 {
701 // G4cerr <<"illegal character after int:"<<buf<<G4endl;
702 }
703 }
704 else
705 {
706 // G4cerr <<"illegal int:"<<buf<<G4endl;
707 }
708 return 0;
709}
710
711// --------------------------------------------------------------------
712G4int G4UIcommand::ExpectExponent(const char* str) // used only by IsDouble()
713{
714 G4int maxExplength;
715 if(IsInt(str, maxExplength = 7))
716 return 1;
717 else
718 return 0;
719}
720
721// --------------------------------------------------------------------
722G4int G4UIcommand::IsDouble(const char* buf)
723{
724 const char* p = buf;
725 switch(*p)
726 {
727 case '+':
728 case '-':
729 ++p;
730 if(isdigit(*p))
731 {
732 while(isdigit((G4int)(*p)))
733 {
734 ++p;
735 }
736 switch(*p)
737 {
738 case '\0':
739 return 1;
740 // break;
741 case 'E':
742 case 'e':
743 return ExpectExponent(++p);
744 // break;
745 case '.':
746 ++p;
747 if(*p == '\0')
748 return 1;
749 if(*p == 'e' || *p == 'E')
750 return ExpectExponent(++p);
751 if(isdigit(*p))
752 {
753 while(isdigit((G4int)(*p)))
754 {
755 ++p;
756 }
757 if(*p == '\0')
758 return 1;
759 if(*p == 'e' || *p == 'E')
760 return ExpectExponent(++p);
761 }
762 else
763 return 0;
764 break;
765 default:
766 return 0;
767 }
768 }
769 if(*p == '.')
770 {
771 ++p;
772 if(isdigit(*p))
773 {
774 while(isdigit((G4int)(*p)))
775 {
776 ++p;
777 }
778 if(*p == '\0')
779 return 1;
780 if(*p == 'e' || *p == 'E')
781 return ExpectExponent(++p);
782 }
783 }
784 break;
785 case '.':
786 ++p;
787 if(isdigit(*p))
788 {
789 while(isdigit((G4int)(*p)))
790 {
791 ++p;
792 }
793 if(*p == '\0')
794 return 1;
795 if(*p == 'e' || *p == 'E')
796 return ExpectExponent(++p);
797 }
798 break;
799 default: // digit is expected
800 if(isdigit(*p))
801 {
802 while(isdigit((G4int)(*p)))
803 {
804 ++p;
805 }
806 if(*p == '\0')
807 return 1;
808 if(*p == 'e' || *p == 'E')
809 return ExpectExponent(++p);
810 if(*p == '.')
811 {
812 ++p;
813 if(*p == '\0')
814 return 1;
815 if(*p == 'e' || *p == 'E')
816 return ExpectExponent(++p);
817 if(isdigit(*p))
818 {
819 while(isdigit((G4int)(*p)))
820 {
821 ++p;
822 }
823 if(*p == '\0')
824 return 1;
825 if(*p == 'e' || *p == 'E')
826 return ExpectExponent(++p);
827 }
828 }
829 }
830 }
831 return 0;
832}
833
834// --------------------------------------------------------------------
835G4int G4UIcommand::RangeCheck(const char* t)
836{
837 yystype result;
838 char type;
839 bp = 0; // reset buffer pointer for G4UIpGetc()
840 std::istringstream is(t);
841 for(unsigned i = 0; i < parameter.size(); ++i)
842 {
843 type = toupper(parameter[i]->GetParameterType());
844 switch(type)
845 {
846 case 'D':
847 is >> newVal[i].D;
848 break;
849 case 'I':
850 is >> newVal[i].I;
851 break;
852 case 'L':
853 is >> newVal[i].L;
854 break;
855 case 'S':
856 is >> newVal[i].S;
857 break;
858 case 'B':
859 is >> newVal[i].C;
860 break;
861 default:;
862 }
863 }
864 // PrintToken(); // Print tokens (consumes all tokens)
865 token = Yylex();
866 result = Expression();
867
868 if(paramERR == 1)
869 return 0;
870 if(result.type != CONSTINT)
871 {
872 G4cerr << "Illegal Expression in parameter range." << G4endl;
873 return 0;
874 }
875 if(result.I)
876 return 1;
877 G4cerr << "parameter out of range: " << rangeString << G4endl;
878 return 0;
879}
880
881// ------------------ syntax node functions ------------------
882
883yystype G4UIcommand::Expression(void)
884{
885 yystype result;
886#ifdef DEBUG
887 G4cerr << " Expression()" << G4endl;
888#endif
889 result = LogicalORExpression();
890 return result;
891}
892
893// --------------------------------------------------------------------
894yystype G4UIcommand::LogicalORExpression(void)
895{
896 yystype result;
897 yystype p;
898 p = LogicalANDExpression();
899 if(token != LOGICALOR)
900 return p;
901 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
902 {
903 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
904 paramERR = 1;
905 }
906 result.I = p.I;
907 while(token == LOGICALOR)
908 {
909 token = Yylex();
910 p = LogicalANDExpression();
911 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
912 {
913 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
914 paramERR = 1;
915 }
916 switch(p.type)
917 {
918 case CONSTINT:
919 result.I += p.I;
920 result.type = CONSTINT;
921 break;
922 case CONSTLONG:
923 result.I += (p.L != 0L);
924 result.type = CONSTINT;
925 break;
926 case CONSTDOUBLE:
927 result.I += (p.D != 0.0);
928 result.type = CONSTINT;
929 break;
930 default:
931 G4cerr << "Parameter range: unknown type" << G4endl;
932 paramERR = 1;
933 }
934 }
935 return result;
936}
937
938// --------------------------------------------------------------------
939yystype G4UIcommand::LogicalANDExpression(void)
940{
941 yystype result;
942 yystype p;
943 p = EqualityExpression();
944 if(token != LOGICALAND)
945 return p;
946 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
947 {
948 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
949 paramERR = 1;
950 }
951 result.I = p.I;
952 while(token == LOGICALAND)
953 {
954 token = Yylex();
955 p = EqualityExpression();
956 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
957 {
958 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
959 paramERR = 1;
960 }
961 switch(p.type)
962 {
963 case CONSTINT:
964 result.I *= p.I;
965 result.type = CONSTINT;
966 break;
967 case CONSTLONG:
968 result.I *= (p.L != 0L);
969 result.type = CONSTINT;
970 break;
971 case CONSTDOUBLE:
972 result.I *= (p.D != 0.0);
973 result.type = CONSTINT;
974 break;
975 default:
976 G4cerr << "Parameter range: unknown type." << G4endl;
977 paramERR = 1;
978 }
979 }
980 return result;
981}
982
983// --------------------------------------------------------------------
984yystype G4UIcommand::EqualityExpression(void)
985{
986 yystype arg1, arg2;
987 G4int operat;
988 yystype result;
989#ifdef DEBUG
990 G4cerr << " EqualityExpression()" << G4endl;
991#endif
992 result = RelationalExpression();
993 if(token == EQ || token == NE)
994 {
995 operat = token;
996 token = Yylex();
997 arg1 = result;
998 arg2 = RelationalExpression();
999 result.I = Eval2(arg1, operat, arg2); // semantic action
1000 result.type = CONSTINT;
1001#ifdef DEBUG
1002 G4cerr << " return code of Eval2(): " << result.I << G4endl;
1003#endif
1004 }
1005 else
1006 {
1007 if(result.type != CONSTINT && result.type != CONSTDOUBLE)
1008 {
1009 G4cerr << "Parameter range: error at EqualityExpression" << G4endl;
1010 paramERR = 1;
1011 }
1012 }
1013 return result;
1014}
1015
1016// --------------------------------------------------------------------
1017yystype G4UIcommand::RelationalExpression(void)
1018{
1019 yystype arg1, arg2;
1020 G4int operat;
1021 yystype result;
1022#ifdef DEBUG
1023 G4cerr << " RelationalExpression()" << G4endl;
1024#endif
1025
1026 arg1 = AdditiveExpression();
1027 if(token == GT || token == GE || token == LT || token == LE)
1028 {
1029 operat = token;
1030 token = Yylex();
1031 arg2 = AdditiveExpression();
1032 result.I = Eval2(arg1, operat, arg2); // semantic action
1033 result.type = CONSTINT;
1034#ifdef DEBUG
1035 G4cerr << " return code of Eval2(): " << result.I << G4endl;
1036#endif
1037 }
1038 else
1039 {
1040 result = arg1;
1041 }
1042#ifdef DEBUG
1043 G4cerr << " return RelationalExpression()" << G4endl;
1044#endif
1045 return result;
1046}
1047
1048// --------------------------------------------------------------------
1049yystype G4UIcommand::AdditiveExpression(void)
1050{
1051 yystype result;
1052 result = MultiplicativeExpression();
1053 if(token != '+' && token != '-')
1054 return result;
1055 G4cerr << "Parameter range: operator " << (char) token << " is not supported."
1056 << G4endl;
1057 paramERR = 1;
1058 return result;
1059}
1060
1061// --------------------------------------------------------------------
1062yystype G4UIcommand::MultiplicativeExpression(void)
1063{
1064 yystype result;
1065 result = UnaryExpression();
1066 if(token != '*' && token != '/' && token != '%')
1067 return result;
1068 G4cerr << "Parameter range: operator " << (char) token << " is not supported."
1069 << G4endl;
1070 paramERR = 1;
1071 return result;
1072}
1073
1074// --------------------------------------------------------------------
1075yystype G4UIcommand::UnaryExpression(void)
1076{
1077 yystype result;
1078 yystype p;
1079#ifdef DEBUG
1080 G4cerr << " UnaryExpression" << G4endl;
1081#endif
1082 switch(token)
1083 {
1084 case '-':
1085 token = Yylex();
1086 p = UnaryExpression();
1087 if(p.type == CONSTINT)
1088 {
1089 result.I = -p.I;
1090 result.type = CONSTINT;
1091 }
1092 if(p.type == CONSTLONG)
1093 {
1094 result.L = -p.L;
1095 result.type = CONSTLONG;
1096 }
1097 if(p.type == CONSTDOUBLE)
1098 {
1099 result.D = -p.D;
1100 result.type = CONSTDOUBLE;
1101 }
1102 break;
1103 case '+':
1104 token = Yylex();
1105 result = UnaryExpression();
1106 break;
1107 case '!':
1108 token = Yylex();
1109 G4cerr << "Parameter range error: "
1110 << "operator '!' is not supported (sorry)." << G4endl;
1111 paramERR = 1;
1112 result = UnaryExpression();
1113 break;
1114 default:
1115 result = PrimaryExpression();
1116 }
1117 return result;
1118}
1119
1120// --------------------------------------------------------------------
1121yystype G4UIcommand::PrimaryExpression(void)
1122{
1123 yystype result;
1124#ifdef DEBUG
1125 G4cerr << " primary_exp" << G4endl;
1126#endif
1127 switch(token)
1128 {
1129 case IDENTIFIER:
1130 result.S = yylval.S;
1131 result.type = token;
1132 token = Yylex();
1133 break;
1134 case CONSTINT:
1135 result.I = yylval.I;
1136 result.type = token;
1137 token = Yylex();
1138 break;
1139 case CONSTLONG:
1140 result.L = yylval.L;
1141 result.type = token;
1142 token = Yylex();
1143 break;
1144 case CONSTDOUBLE:
1145 result.D = yylval.D;
1146 result.type = token;
1147 token = Yylex();
1148 break;
1149 case '(':
1150 token = Yylex();
1151 result = Expression();
1152 if(token != ')')
1153 {
1154 G4cerr << " ')' expected" << G4endl;
1155 paramERR = 1;
1156 }
1157 token = Yylex();
1158 break;
1159 default:
1160 return result;
1161 }
1162 return result; // never executed
1163}
1164
1165//---------------- semantic routines ----------------------------------
1166
1167G4int G4UIcommand::Eval2(yystype arg1, G4int op, yystype arg2)
1168{
1169 char newValtype;
1170 if((arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER))
1171 {
1172 G4cerr << commandName << ": meaningless comparison" << G4endl;
1173 paramERR = 1;
1174 }
1175
1176 if(arg1.type == IDENTIFIER)
1177 {
1178 unsigned i = IndexOf(arg1.S);
1179 newValtype = toupper(parameter[i]->GetParameterType());
1180 switch(newValtype)
1181 {
1182 case 'I':
1183 if(arg2.type == CONSTINT)
1184 {
1185 return CompareInt(newVal[i].I, op, arg2.I);
1186 //===================================================================
1187 // MA - 2018.07.23
1188 }
1189 else if(arg2.type == IDENTIFIER)
1190 {
1191 unsigned iii = IndexOf(arg2.S);
1192 char newValtype2 = toupper(parameter[iii]->GetParameterType());
1193 if(newValtype2 == 'I')
1194 {
1195 return CompareInt(newVal[i].I, op, newVal[iii].I);
1196 }
1197 else if(newValtype2 == 'L')
1198 {
1199 G4cerr << "Warning : Integer is compared with long int : "
1200 << rangeString << G4endl;
1201 return CompareLong(newVal[i].I, op, newVal[iii].L);
1202 }
1203 else if(newValtype2 == 'D')
1204 {
1205 G4cerr << "Warning : Integer is compared with double : "
1206 << rangeString << G4endl;
1207 return CompareDouble(newVal[i].I, op, newVal[iii].D);
1208 }
1209 //===================================================================
1210 }
1211 else
1212 {
1213 G4cerr << "integer operand expected for " << rangeString << '.'
1214 << G4endl;
1215 }
1216 break;
1217 case 'L':
1218 if(arg2.type == CONSTINT)
1219 {
1220 return CompareLong(newVal[i].L, op, arg2.I);
1221 }
1222 else if(arg2.type == CONSTLONG)
1223 {
1224 return CompareLong(newVal[i].L, op, arg2.L);
1225 }
1226 else if(arg2.type == IDENTIFIER)
1227 {
1228 unsigned iii = IndexOf(arg2.S);
1229 char newValtype2 = toupper(parameter[iii]->GetParameterType());
1230 if(newValtype2 == 'I')
1231 {
1232 return CompareLong(newVal[i].L, op, newVal[iii].I);
1233 }
1234 if(newValtype2 == 'L')
1235 {
1236 return CompareLong(newVal[i].L, op, newVal[iii].L);
1237 }
1238 else if(newValtype2 == 'D')
1239 {
1240 G4cerr << "Warning : Long int is compared with double : "
1241 << rangeString << G4endl;
1242 return CompareDouble(newVal[i].L, op, newVal[iii].D);
1243 }
1244 //===================================================================
1245 }
1246 else
1247 {
1248 G4cerr << "integer operand expected for " << rangeString << '.'
1249 << G4endl;
1250 }
1251 break;
1252 case 'D':
1253 if(arg2.type == CONSTDOUBLE)
1254 {
1255 return CompareDouble(newVal[i].D, op, arg2.D);
1256 }
1257 else if(arg2.type == CONSTINT)
1258 { // integral promotion
1259 return CompareDouble(newVal[i].D, op, arg2.I);
1260 //===================================================================
1261 // MA - 2018.07.23
1262 }
1263 else if(arg2.type == CONSTLONG)
1264 {
1265 return CompareDouble(newVal[i].D, op, arg2.L);
1266 }
1267 else if(arg2.type == IDENTIFIER)
1268 {
1269 unsigned iii = IndexOf(arg2.S);
1270 char newValtype2 = toupper(parameter[iii]->GetParameterType());
1271 if(newValtype2 == 'I')
1272 {
1273 return CompareDouble(newVal[i].D, op, newVal[iii].I);
1274 }
1275 else if(newValtype2 == 'L')
1276 {
1277 return CompareDouble(newVal[i].D, op, newVal[iii].L);
1278 }
1279 else if(newValtype2 == 'D')
1280 {
1281 return CompareDouble(newVal[i].D, op, newVal[iii].D);
1282 }
1283 //===================================================================
1284 }
1285 break;
1286 default:;
1287 }
1288 }
1289 if(arg2.type == IDENTIFIER)
1290 {
1291 unsigned i = IndexOf(arg2.S);
1292 newValtype = toupper(parameter[i]->GetParameterType());
1293 switch(newValtype)
1294 {
1295 case 'I':
1296 if(arg1.type == CONSTINT)
1297 {
1298 return CompareInt(arg1.I, op, newVal[i].I);
1299 }
1300 else
1301 {
1302 G4cerr << "integer operand expected for " << rangeString << '.'
1303 << G4endl;
1304 }
1305 break;
1306 case 'L':
1307 if(arg1.type == CONSTLONG)
1308 {
1309 return CompareLong(arg1.L, op, newVal[i].L);
1310 }
1311 else
1312 {
1313 G4cerr << "long int operand expected for " << rangeString << '.'
1314 << G4endl;
1315 }
1316 break;
1317 case 'D':
1318 if(arg1.type == CONSTDOUBLE)
1319 {
1320 return CompareDouble(arg1.D, op, newVal[i].D);
1321 }
1322 else if(arg1.type == CONSTINT)
1323 { // integral promotion
1324 return CompareDouble(arg1.I, op, newVal[i].D);
1325 }
1326 break;
1327 default:;
1328 }
1329 }
1330 return 0;
1331}
1332
1333// --------------------------------------------------------------------
1334G4int G4UIcommand::CompareInt(G4int arg1, G4int op, G4int arg2)
1335{
1336 G4int result = -1;
1337 G4String opr;
1338 switch(op)
1339 {
1340 case GT:
1341 result = (arg1 > arg2);
1342 opr = ">";
1343 break;
1344 case GE:
1345 result = (arg1 >= arg2);
1346 opr = ">=";
1347 break;
1348 case LT:
1349 result = (arg1 < arg2);
1350 opr = "<";
1351 break;
1352 case LE:
1353 result = (arg1 <= arg2);
1354 opr = "<=";
1355 break;
1356 case EQ:
1357 result = (arg1 == arg2);
1358 opr = "==";
1359 break;
1360 case NE:
1361 result = (arg1 != arg2);
1362 opr = "!=";
1363 break;
1364 default:
1365 G4cerr << "Parameter range: error at CompareInt" << G4endl;
1366 paramERR = 1;
1367 }
1368#ifdef DEBUG
1369 G4cerr << "CompareInt " << arg1 << " " << opr << arg2 << " result: " << result
1370 << G4endl;
1371#endif
1372 return result;
1373}
1374
1375// --------------------------------------------------------------------
1376G4int G4UIcommand::CompareLong(G4long arg1, G4int op, G4long arg2)
1377{
1378 G4int result = -1;
1379 G4String opr;
1380 switch(op)
1381 {
1382 case GT:
1383 result = (arg1 > arg2);
1384 opr = ">";
1385 break;
1386 case GE:
1387 result = (arg1 >= arg2);
1388 opr = ">=";
1389 break;
1390 case LT:
1391 result = (arg1 < arg2);
1392 opr = "<";
1393 break;
1394 case LE:
1395 result = (arg1 <= arg2);
1396 opr = "<=";
1397 break;
1398 case EQ:
1399 result = (arg1 == arg2);
1400 opr = "==";
1401 break;
1402 case NE:
1403 result = (arg1 != arg2);
1404 opr = "!=";
1405 break;
1406 default:
1407 G4cerr << "Parameter range: error at CompareInt" << G4endl;
1408 paramERR = 1;
1409 }
1410#ifdef DEBUG
1411 G4cerr << "CompareInt " << arg1 << " " << opr << arg2 << " result: " << result
1412 << G4endl;
1413#endif
1414 return result;
1415}
1416
1417// --------------------------------------------------------------------
1418G4int G4UIcommand::CompareDouble(G4double arg1, G4int op, G4double arg2)
1419{
1420 G4int result = -1;
1421 G4String opr;
1422 switch(op)
1423 {
1424 case GT:
1425 result = (arg1 > arg2);
1426 opr = ">";
1427 break;
1428 case GE:
1429 result = (arg1 >= arg2);
1430 opr = ">=";
1431 break;
1432 case LT:
1433 result = (arg1 < arg2);
1434 opr = "<";
1435 break;
1436 case LE:
1437 result = (arg1 <= arg2);
1438 opr = "<=";
1439 break;
1440 case EQ:
1441 result = (arg1 == arg2);
1442 opr = "==";
1443 break;
1444 case NE:
1445 result = (arg1 != arg2);
1446 opr = "!=";
1447 break;
1448 default:
1449 G4cerr << "Parameter range: error at CompareDouble" << G4endl;
1450 paramERR = 1;
1451 }
1452#ifdef DEBUG
1453 G4cerr << "CompareDouble " << arg1 << " " << opr << " " << arg2
1454 << " result: " << result << G4endl;
1455#endif
1456 return result;
1457}
1458
1459// --------------------------------------------------------------------
1460unsigned G4UIcommand::IndexOf(const char* nam)
1461{
1462 unsigned i;
1463 G4String pname;
1464 for(i = 0; i < parameter.size(); ++i)
1465 {
1466 pname = parameter[i]->GetParameterName();
1467 if(pname == nam)
1468 {
1469 return i;
1470 }
1471 }
1472 paramERR = 1;
1473 G4cerr << "parameter name:" << nam << " not found." << G4endl;
1474 return 0;
1475}
1476
1477// --------------------------------------------------------------------
1478unsigned G4UIcommand::IsParameter(const char* nam)
1479{
1480 G4String pname;
1481 for(unsigned i = 0; i < parameter.size(); ++i)
1482 {
1483 pname = parameter[i]->GetParameterName();
1484 if(pname == nam)
1485 return 1;
1486 }
1487 return 0;
1488}
1489
1490// --------------------- utility functions ----------------------------
1491
1492tokenNum G4UIcommand::Yylex() // reads input and returns token number, KR486
1493{ // (returns EOF)
1494 G4int c;
1495 G4String buf;
1496
1497 while((c = G4UIpGetc()) == ' ' || c == '\t' || c == '\n')
1498 ;
1499 if(c == EOF)
1500 return (tokenNum) EOF; // KR488
1501 buf = "";
1502 if(isdigit(c) || c == '.')
1503 { // I or D
1504 do
1505 {
1506 buf += G4String((unsigned char) c);
1507 c = G4UIpGetc();
1508 } while(c == '.' || isdigit(c) || c == 'e' || c == 'E' || c == '+' ||
1509 c == '-');
1510 G4UIpUngetc(c);
1511 const char* t = buf;
1512 std::istringstream is(t);
1513 if(IsInt(buf.data(), 20))
1514 {
1515 is >> yylval.I;
1516 return CONSTINT;
1517 }
1518 else if(IsDouble(buf.data()))
1519 {
1520 is >> yylval.D;
1521 return CONSTDOUBLE;
1522 }
1523 else
1524 {
1525 G4cerr << buf << ": numeric format error." << G4endl;
1526 }
1527 }
1528 buf = "";
1529 if(isalpha(c) || c == '_')
1530 { // IDENTIFIER
1531 do
1532 {
1533 buf += G4String((unsigned char) c);
1534 } while((c = G4UIpGetc()) != EOF && (isalnum(c) || c == '_'));
1535 G4UIpUngetc(c);
1536 if(IsParameter(buf))
1537 {
1538 yylval.S = buf;
1539 return IDENTIFIER;
1540 }
1541 else
1542 {
1543 G4cerr << buf << " is not a parameter name." << G4endl;
1544 paramERR = 1;
1545 }
1546 }
1547 switch(c)
1548 {
1549 case '>':
1550 return (tokenNum) Follow('=', GE, GT);
1551 case '<':
1552 return (tokenNum) Follow('=', LE, LT);
1553 case '=':
1554 return (tokenNum) Follow('=', EQ, '=');
1555 case '!':
1556 return (tokenNum) Follow('=', NE, '!');
1557 case '|':
1558 return (tokenNum) Follow('|', LOGICALOR, '|');
1559 case '&':
1560 return (tokenNum) Follow('&', LOGICALAND, '&');
1561 default:
1562 return (tokenNum) c;
1563 }
1564}
1565
1566// --------------------------------------------------------------------
1567G4int G4UIcommand::Follow(G4int expect, G4int ifyes, G4int ifno)
1568{
1569 G4int c = G4UIpGetc();
1570 if(c == expect)
1571 return ifyes;
1572 G4UIpUngetc(c);
1573 return ifno;
1574}
1575
1576//------------------ low level routines -------------------------------
1577
1578G4int G4UIcommand::G4UIpGetc()
1579{ // emulation of getc()
1580 G4int length = rangeString.length();
1581 if(bp < length)
1582 return rangeString(bp++);
1583 else
1584 return EOF;
1585}
1586
1587// --------------------------------------------------------------------
1588G4int G4UIcommand::G4UIpUngetc(G4int c)
1589{ // emulation of ungetc()
1590 if(c < 0)
1591 return -1;
1592 if(bp > 0 && c == rangeString(bp - 1))
1593 {
1594 --bp;
1595 }
1596 else
1597 {
1598 G4cerr << "G4UIpUngetc() failed." << G4endl;
1599 G4cerr << "bp=" << bp << " c=" << c << " pR(bp-1)=" << rangeString(bp - 1)
1600 << G4endl;
1601 paramERR = 1;
1602 return -1;
1603 }
1604 return 0;
1605}
@ GT
Definition: Evaluator.cc:65
@ LT
Definition: Evaluator.cc:65
@ NE
Definition: Evaluator.cc:65
@ GE
Definition: Evaluator.cc:65
@ LE
Definition: Evaluator.cc:65
@ EQ
Definition: Evaluator.cc:65
G4ApplicationState
@ G4State_EventProc
@ G4State_Init
@ G4State_Idle
@ G4State_Abort
@ G4State_GeomClosed
@ G4State_PreInit
double D(double temp)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
long G4long
Definition: G4Types.hh:87
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
@ fParameterUnreadable
@ fParameterOutOfRange
std::vector< G4UnitDefinition * > G4UnitsContainer
std::vector< G4UnitsCategory * > G4UnitsTable
Definition: G4UnitsTable.hh:68
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double y() const
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
G4String & remove(str_size)
G4String & append(const G4String &)
str_size index(const char *, G4int pos=0) const
G4bool isNull() const
std::size_t last(char) const
void toUpper()
const char * data() const
static G4ThreeVector ConvertTo3Vector(const char *st)
Definition: G4UIcommand.cc:583
G4bool toBeBroadcasted
Definition: G4UIcommand.hh:205
static G4String CategoryOf(const char *unitName)
Definition: G4UIcommand.cc:356
static G4double ValueOf(const char *unitName)
Definition: G4UIcommand.cc:348
virtual ~G4UIcommand()
Definition: G4UIcommand.cc:105
static G4long ConvertToLongInt(const char *st)
Definition: G4UIcommand.cc:552
virtual G4int DoIt(G4String parameterList)
Definition: G4UIcommand.cc:135
G4bool operator==(const G4UIcommand &right) const
Definition: G4UIcommand.cc:123
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:430
const G4String & GetCommandPath() const
Definition: G4UIcommand.hh:136
G4int CheckNewValue(const char *newValue)
Definition: G4UIcommand.cc:611
G4bool IsAvailable()
Definition: G4UIcommand.cc:328
static G4int ConvertToInt(const char *st)
Definition: G4UIcommand.cc:543
static G4String UnitsList(const char *unitCategory)
Definition: G4UIcommand.cc:362
static G4bool ConvertToBool(const char *st)
Definition: G4UIcommand.cc:530
static G4double ConvertToDouble(const char *st)
Definition: G4UIcommand.cc:561
static G4double ConvertToDimensionedDouble(const char *st)
Definition: G4UIcommand.cc:570
virtual void List()
Definition: G4UIcommand.cc:395
G4bool workerThreadOnly
Definition: G4UIcommand.hh:207
void AvailableForStates(G4ApplicationState s1)
Definition: G4UIcommand.cc:273
G4bool operator!=(const G4UIcommand &right) const
Definition: G4UIcommand.cc:129
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
Definition: G4UIcommand.cc:594
G4String GetCurrentValue()
Definition: G4UIcommand.cc:267
static G4bool DoublePrecisionStr()
Definition: G4UImanager.cc:158
static G4UImanager * GetMasterUIpointer()
Definition: G4UImanager.cc:91
void AddNewCommand(G4UIcommand *newCommand)
Definition: G4UImanager.cc:271
void RemoveCommand(G4UIcommand *aCommand)
Definition: G4UImanager.cc:287
static G4UImanager * GetUIpointer()
Definition: G4UImanager.cc:77
virtual G4String GetCurrentValue(G4UIcommand *command)
G4bool CommandsShouldBeInMaster() const
virtual void SetNewValue(G4UIcommand *command, G4String newValue)
static G4double GetValueOf(const G4String &)
static G4String GetCategory(const G4String &)
static G4UnitsTable & GetUnitsTable()
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
G4bool IsMasterThread()
Definition: G4Threading.cc:124