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