Geant4 11.2.2
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
33#include "G4StateManager.hh"
34#include "G4Threading.hh"
35#include "G4Tokenizer.hh"
36#include "G4UIcommandStatus.hh"
37#include "G4UImanager.hh"
38#include "G4UImessenger.hh"
39#include "G4UIparsing.hh"
40#include "G4UItokenNum.hh"
41#include "G4UnitsTable.hh"
42#include "G4ios.hh"
43
44#include <cctype> // isalpha(), toupper()
45#include <iomanip>
46#include <sstream>
47
48using namespace G4UItokenNum;
49
50// --------------------------------------------------------------------
51G4UIcommand::G4UIcommand(const char* theCommandPath, G4UImessenger* theMessenger, G4bool tBB)
52 : toBeBroadcasted(tBB), messenger(theMessenger)
53{
54 G4String comStr = theCommandPath;
55 G4UIcommandCommonConstructorCode(comStr);
56 availabelStateList = {G4State_PreInit, G4State_Init, G4State_Idle,
58}
59
60// --------------------------------------------------------------------
61void G4UIcommand::G4UIcommandCommonConstructorCode(const char* theCommandPath)
62{
63 commandPath = theCommandPath;
64 commandName = theCommandPath;
65 auto commandNameIndex = (G4int)commandName.rfind('/');
66 commandName.erase(0, commandNameIndex + 1);
67#ifdef G4MULTITHREADED
68 if ((messenger != nullptr) && messenger->CommandsShouldBeInMaster()
70 {
71 toBeBroadcasted = false;
73 }
74 else {
76 }
77#else
79#endif
80}
81
82// --------------------------------------------------------------------
84{
85 if (messenger == nullptr) { // this must be a directory
86 if (typ != CmdDirectory) {
88 ed << "A UI command <" << commandPath << "> is defined without vaild messenger.";
89 G4Exception("G4UIcommand::SetCommandType", "UI2031", FatalException, ed);
90 }
91 else if (commandPath.back() != '/') {
93 ed << "G4UIcommand Warning : \n"
94 << " <" << commandPath << "> must be a directory."
95 << " '/' is appended.";
96 G4Exception("G4UIcommand::SetCommandType", "UI2032", JustWarning, ed);
97 commandPath += "/";
98 }
99 }
100 commandType = typ;
101}
102
103// --------------------------------------------------------------------
105{
107 if (fUImanager != nullptr) {
108 fUImanager->RemoveCommand(this);
109 }
110
111 for (const auto& p : parameter) {
112 delete p;
113 }
114}
115
116// --------------------------------------------------------------------
118{
119 return (commandPath == right.GetCommandPath());
120}
121
122// --------------------------------------------------------------------
124{
125 return (commandPath != right.GetCommandPath());
126}
127
128// --------------------------------------------------------------------
130{
131 G4String correctParameters;
132 std::size_t n_parameterEntry = parameter.size();
133 if (n_parameterEntry != 0) {
134 G4String aToken;
135 G4String correctToken;
136 G4Tokenizer parameterToken(parameterList);
137 for (std::size_t i_thParameter = 0; i_thParameter < n_parameterEntry; ++i_thParameter) {
138 if (i_thParameter > 0) {
139 correctParameters.append(" ");
140 }
141 aToken = parameterToken();
142 if (aToken.length() > 0 && aToken[0] == '"') {
143 while (aToken.back() != '"' || (aToken.length() == 1 && aToken[0] == '"')) {
144 G4String additionalToken = parameterToken();
145 if (additionalToken.empty()) {
146 return G4int(fParameterUnreadable + i_thParameter);
147 }
148 aToken += " ";
149 aToken += additionalToken;
150 }
151 }
152 else if (i_thParameter == n_parameterEntry - 1
153 && parameter[i_thParameter]->GetParameterType() == 's')
154 {
155 G4String anotherToken;
156 while (!((anotherToken = parameterToken()).empty())) {
157 std::size_t idxs = anotherToken.find('#');
158 if (idxs == std::string::npos) {
159 aToken += " ";
160 aToken += anotherToken;
161 }
162 else if (idxs > 0) {
163 aToken += " ";
164 aToken += anotherToken.substr(0, idxs);
165 break;
166 }
167 else {
168 break;
169 }
170 }
171 }
172
173 if (aToken.empty() || aToken == "!") {
174 if (parameter[i_thParameter]->IsOmittable()) {
175 if (parameter[i_thParameter]->GetCurrentAsDefault()) {
176 G4Tokenizer cvSt(messenger->GetCurrentValue(this));
177 G4String parVal;
178 for (std::size_t ii = 0; ii < i_thParameter; ++ii) {
179 parVal = cvSt();
180 if (parVal[0] == '"') {
181 while (parVal.back() != '"') {
182 G4String additionalToken = cvSt();
183 if (additionalToken.empty()) {
184 return G4int(fParameterUnreadable + i_thParameter);
185 }
186 parVal += " ";
187 parVal += additionalToken;
188 }
189 }
190 }
191 G4String aCVToken = cvSt();
192 if (aCVToken[0] == '"') {
193 while (aCVToken.back() != '"') {
194 G4String additionalToken = cvSt();
195 if (additionalToken.empty()) {
196 return G4int(fParameterUnreadable + i_thParameter);
197 }
198 aCVToken += " ";
199 aCVToken += additionalToken;
200 }
201 }
202 correctParameters.append(aCVToken);
203 }
204 else {
205 correctParameters.append(parameter[i_thParameter]->GetDefaultValue());
206 }
207 }
208 else {
209 return G4int(fParameterUnreadable + i_thParameter);
210 }
211 }
212 else {
213 G4int stat = parameter[i_thParameter]->CheckNewValue(aToken);
214 if (stat != 0) {
215 return stat + G4int(i_thParameter);
216 }
217 correctParameters.append(aToken);
218 }
219 }
220 }
221
222 if (CheckNewValue(correctParameters) != 0) {
223 return fParameterOutOfRange + 99;
224 }
225
227 return 0;
228 }
229
230 messenger->SetNewValue(this, correctParameters);
231 return 0;
232}
233
234// --------------------------------------------------------------------
236{
237 return messenger->GetCurrentValue(this);
238}
239
240// --------------------------------------------------------------------
242{
243 availabelStateList = {s1};
244}
245
246// --------------------------------------------------------------------
248{
249 availabelStateList = {s1, s2};
250}
251
252// --------------------------------------------------------------------
255{
256 availabelStateList = {s1, s2, s3};
257}
258
259// --------------------------------------------------------------------
262{
263 availabelStateList = {s1, s2, s3, s4};
264}
265
266// --------------------------------------------------------------------
270{
271 availabelStateList = {s1, s2, s3, s4, s5};
272}
273
274// --------------------------------------------------------------------
276{
278
279 for (const auto& s : availabelStateList) {
280 if (s == currentState) {
281 return true;
282 }
283 }
284
285 return false;
286}
287
288// --------------------------------------------------------------------
289G4double G4UIcommand::ValueOf(const char* unitName)
290{
291 return G4UnitDefinition::GetValueOf(unitName);
292}
293
294// --------------------------------------------------------------------
296{
297 return G4UnitDefinition::GetCategory(unitName);
298}
299
300// --------------------------------------------------------------------
301G4String G4UIcommand::UnitsList(const char* unitCategory)
302{
304
305 auto ucatIter = std::find_if(std::cbegin(UTbl), std::cend(UTbl), [&unitCategory](const auto& ud) {
306 return ud->GetName() == unitCategory;
307 });
308
309 if (ucatIter == std::cend(UTbl)) {
310 G4cerr << "Unit category <" << unitCategory << "> is not defined." << G4endl;
311 return G4String();
312 }
313
314 G4String symList;
315 G4String nameList;
316 G4UnitsContainer& UCnt = (*ucatIter)->GetUnitsList();
317
318 for (const auto& uDef : UCnt) {
319 symList += uDef->GetSymbol();
320 symList += " ";
321 nameList += uDef->GetName();
322 nameList += " ";
323 }
324 symList += nameList;
325 G4StrUtil::rstrip(symList);
326 return symList;
327}
328
329// --------------------------------------------------------------------
331{
332 G4cout << G4endl;
333 G4cout << G4endl;
334 if (commandPath.back() != '/') {
335 G4cout << "Command " << commandPath << G4endl;
336 }
337 if (workerThreadOnly) {
338 G4cout << " ---- available only in worker thread" << G4endl;
339 }
340
341 G4cout << "Guidance :" << G4endl;
342 for (const auto& i_thGuidance : commandGuidance) {
343 G4cout << i_thGuidance << G4endl;
344 }
345
346 if (!rangeExpression.empty()) {
347 G4cout << " Range of parameters : " << rangeExpression << G4endl;
348 }
349
350 for (const auto& i_thParameter : parameter) {
351 i_thParameter->List();
352 }
353 G4cout << G4endl;
354}
355
356// --------------------------------------------------------------------
358{
359 return boolVal ? "1" : "0";
360}
361
362// --------------------------------------------------------------------
364{
365 return G4UIparsing::TtoS(intValue);
366}
367
368// --------------------------------------------------------------------
370{
371 return G4UIparsing::TtoS(longValue);
372}
373
374// --------------------------------------------------------------------
376{
377 std::ostringstream os;
379 os << std::setprecision(17);
380 }
381 os << doubleValue;
382 return os.str();
383}
384
385// --------------------------------------------------------------------
386G4String G4UIcommand::ConvertToString(G4double doubleValue, const char* unitName)
387{
388 std::ostringstream os;
390 os << std::setprecision(17);
391 }
392 os << doubleValue / ValueOf(unitName) << " " << unitName;
393 return os.str();
394}
395
396// --------------------------------------------------------------------
398{
399 std::ostringstream os;
401 os << std::setprecision(17);
402 }
403 os << vec.x() << " " << vec.y() << " " << vec.z();
404 return os.str();
405}
406
407// --------------------------------------------------------------------
408G4String G4UIcommand::ConvertToString(const G4ThreeVector& vec, const char* unitName)
409{
410 G4double uv = ValueOf(unitName);
411
412 std::ostringstream os;
414 os << std::setprecision(17);
415 }
416 os << vec.x() / uv << " " << vec.y() / uv << " " << vec.z() / uv << " " << unitName;
417 return os.str();
418}
419
420// --------------------------------------------------------------------
422{
423 G4String v = G4StrUtil::to_upper_copy(st);
424 return (v == "Y" || v == "YES" || v == "1" || v == "T" || v == "TRUE");
425}
426
427// --------------------------------------------------------------------
429{
430 return G4UIparsing::StoT<G4int>(st);
431}
432
433// --------------------------------------------------------------------
435{
436 return G4UIparsing::StoT<G4long>(st);
437}
438
439// --------------------------------------------------------------------
441{
443}
444
445// --------------------------------------------------------------------
447{
448 G4double vl;
449 char unts[30];
450
451 std::istringstream is(st);
452 is >> vl >> unts;
453 G4String unt = unts;
454
455 return (vl * ValueOf(unt));
456}
457
458// --------------------------------------------------------------------
460{
461 G4double vx;
462 G4double vy;
463 G4double vz;
464 std::istringstream is(st);
465 is >> vx >> vy >> vz;
466 return G4ThreeVector(vx, vy, vz);
467}
468
469// --------------------------------------------------------------------
471{
472 G4double vx;
473 G4double vy;
474 G4double vz;
475 char unts[30];
476 std::istringstream is(st);
477 is >> vx >> vy >> vz >> unts;
478 G4String unt = unts;
479 G4double uv = ValueOf(unt);
480 return G4ThreeVector(vx * uv, vy * uv, vz * uv);
481}
482
483// ----- the following is used by CheckNewValue() --------------------
484
486{
487 yystype result;
488 if (!RangeCheck(newValue)) {
490 }
491 return 0; // succeeded
492}
493
494// --------------------------------------------------------------------
495G4bool G4UIcommand::RangeCheck(const char* t)
496{
497 if (rangeExpression.empty()) {
498 return true;
499 }
500
501 yystype result;
502 char type;
503 bp = 0; // reset buffer pointer for G4UIpGetc()
504 std::istringstream is(t);
505 for (unsigned i = 0; i < parameter.size(); ++i) {
506 type = (char)std::toupper(parameter[i]->GetParameterType());
507 switch (type) {
508 case 'D':
509 is >> newVal[i].D;
510 break;
511 case 'I':
512 is >> newVal[i].I;
513 break;
514 case 'L':
515 is >> newVal[i].L;
516 break;
517 case 'S':
518 is >> newVal[i].S;
519 break;
520 case 'B':
521 is >> newVal[i].C;
522 break;
523 default:;
524 }
525 }
526 token = Yylex();
527 result = Expression();
528
529 if (paramERR == 1) {
530 return false;
531 }
532 if (result.type != CONSTINT) {
533 G4cerr << "Illegal Expression in parameter range." << G4endl;
534 return false;
535 }
536 if (result.I != 0) {
537 return true;
538 }
539 G4cerr << "parameter out of range: " << rangeExpression << G4endl;
540 return false;
541}
542
543// ------------------ syntax node functions ------------------
544
545yystype G4UIcommand::Expression()
546{
547 return LogicalORExpression();
548}
549
550// --------------------------------------------------------------------
551yystype G4UIcommand::LogicalORExpression()
552{
553 yystype result;
554 yystype p;
555 p = LogicalANDExpression();
556 if (token != LOGICALOR) {
557 return p;
558 }
559 if (p.type == CONSTSTRING || p.type == IDENTIFIER) {
560 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
561 paramERR = 1;
562 }
563 result.I = p.I;
564 while (token == LOGICALOR) {
565 token = Yylex();
566 p = LogicalANDExpression();
567 if (p.type == CONSTSTRING || p.type == IDENTIFIER) {
568 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
569 paramERR = 1;
570 }
571 switch (p.type) {
572 case CONSTINT:
573 result.I += p.I;
574 result.type = CONSTINT;
575 break;
576 case CONSTLONG:
577 result.I += static_cast<int>(p.L != 0L);
578 result.type = CONSTINT;
579 break;
580 case CONSTDOUBLE:
581 result.I += static_cast<int>(p.D != 0.0);
582 result.type = CONSTINT;
583 break;
584 default:
585 G4cerr << "Parameter range: unknown type" << G4endl;
586 paramERR = 1;
587 }
588 }
589 return result;
590}
591
592// --------------------------------------------------------------------
593yystype G4UIcommand::LogicalANDExpression()
594{
595 yystype result;
596 yystype p;
597 p = EqualityExpression();
598 if (token != LOGICALAND) {
599 return p;
600 }
601 if (p.type == CONSTSTRING || p.type == IDENTIFIER) {
602 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
603 paramERR = 1;
604 }
605 result.I = p.I;
606 while (token == LOGICALAND) {
607 token = Yylex();
608 p = EqualityExpression();
609 if (p.type == CONSTSTRING || p.type == IDENTIFIER) {
610 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
611 paramERR = 1;
612 }
613 switch (p.type) {
614 case CONSTINT:
615 result.I *= p.I;
616 result.type = CONSTINT;
617 break;
618 case CONSTLONG:
619 result.I *= static_cast<int>(p.L != 0L);
620 result.type = CONSTINT;
621 break;
622 case CONSTDOUBLE:
623 result.I *= static_cast<int>(p.D != 0.0);
624 result.type = CONSTINT;
625 break;
626 default:
627 G4cerr << "Parameter range: unknown type." << G4endl;
628 paramERR = 1;
629 }
630 }
631 return result;
632}
633
634// --------------------------------------------------------------------
635yystype G4UIcommand::EqualityExpression()
636{
637 yystype arg1, arg2;
638 G4int operat;
639 yystype result;
640 result = RelationalExpression();
641 if (token == EQ || token == NE) {
642 operat = token;
643 token = Yylex();
644 arg1 = result;
645 arg2 = RelationalExpression();
646 result.I = Eval2(arg1, operat, arg2); // semantic action
647 result.type = CONSTINT;
648 }
649 else {
650 if (result.type != CONSTINT && result.type != CONSTDOUBLE) {
651 G4cerr << "Parameter range: error at EqualityExpression" << G4endl;
652 paramERR = 1;
653 }
654 }
655 return result;
656}
657
658// --------------------------------------------------------------------
659yystype G4UIcommand::RelationalExpression()
660{
661 yystype arg1, arg2;
662 G4int operat;
663 yystype result;
664
665 arg1 = AdditiveExpression();
666 if (token == GT || token == GE || token == LT || token == LE) {
667 operat = token;
668 token = Yylex();
669 arg2 = AdditiveExpression();
670 result.I = Eval2(arg1, operat, arg2); // semantic action
671 result.type = CONSTINT;
672 }
673 else {
674 result = arg1;
675 }
676 return result;
677}
678
679// --------------------------------------------------------------------
680yystype G4UIcommand::AdditiveExpression()
681{
682 yystype result = MultiplicativeExpression();
683 if (token != '+' && token != '-') {
684 return result;
685 }
686 G4cerr << "Parameter range: operator " << (char)token << " is not supported." << G4endl;
687 paramERR = 1;
688 return result;
689}
690
691// --------------------------------------------------------------------
692yystype G4UIcommand::MultiplicativeExpression()
693{
694 yystype result = UnaryExpression();
695 if (token != '*' && token != '/' && token != '%') {
696 return result;
697 }
698 G4cerr << "Parameter range: operator " << (char)token << " is not supported." << G4endl;
699 paramERR = 1;
700 return result;
701}
702
703// --------------------------------------------------------------------
704yystype G4UIcommand::UnaryExpression()
705{
706 yystype result;
707 yystype p;
708 switch (token) {
709 case '-':
710 token = Yylex();
711 p = UnaryExpression();
712 if (p.type == CONSTINT) {
713 result.I = -p.I;
714 result.type = CONSTINT;
715 }
716 if (p.type == CONSTLONG) {
717 result.L = -p.L;
718 result.type = CONSTLONG;
719 }
720 if (p.type == CONSTDOUBLE) {
721 result.D = -p.D;
722 result.type = CONSTDOUBLE;
723 }
724 break;
725 case '+':
726 token = Yylex();
727 result = UnaryExpression();
728 break;
729 case '!':
730 token = Yylex();
731 G4cerr << "Parameter range error: "
732 << "operator '!' is not supported (sorry)." << G4endl;
733 paramERR = 1;
734 result = UnaryExpression();
735 break;
736 default:
737 result = PrimaryExpression();
738 }
739 return result;
740}
741
742// --------------------------------------------------------------------
743yystype G4UIcommand::PrimaryExpression()
744{
745 yystype result;
746 switch (token) {
747 case IDENTIFIER:
748 result.S = yylval.S;
749 result.type = token;
750 token = Yylex();
751 break;
752 case CONSTINT:
753 result.I = yylval.I;
754 result.type = token;
755 token = Yylex();
756 break;
757 case CONSTLONG:
758 result.L = yylval.L;
759 result.type = token;
760 token = Yylex();
761 break;
762 case CONSTDOUBLE:
763 result.D = yylval.D;
764 result.type = token;
765 token = Yylex();
766 break;
767 case '(':
768 token = Yylex();
769 result = Expression();
770 if (token != ')') {
771 G4cerr << " ')' expected" << G4endl;
772 paramERR = 1;
773 }
774 token = Yylex();
775 break;
776 default:
777 return result;
778 }
779 return result; // never executed
780}
781
782//---------------- semantic routines ----------------------------------
783
784G4int G4UIcommand::Eval2(const yystype& arg1, G4int op, const yystype& arg2)
785{
786 char newValtype;
787 if ((arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER)) {
788 G4cerr << commandName << ": meaningless comparison" << G4endl;
789 paramERR = 1;
790 }
791
792 if (arg1.type == IDENTIFIER) {
793 unsigned i = IndexOf(arg1.S);
794 newValtype = (char)std::toupper(parameter[i]->GetParameterType());
795 switch (newValtype) {
796 case 'I':
797 if (arg2.type == CONSTINT) {
798 return G4UIparsing::CompareInt(newVal[i].I, op, arg2.I, paramERR);
799 //===================================================================
800 // MA - 2018.07.23
801 }
802 else if (arg2.type == IDENTIFIER) {
803 unsigned iii = IndexOf(arg2.S);
804 char newValtype2 = (char)std::toupper(parameter[iii]->GetParameterType());
805 if (newValtype2 == 'I') {
806 return G4UIparsing::CompareInt(newVal[i].I, op, newVal[iii].I, paramERR);
807 }
808 if (newValtype2 == 'L') {
809 G4cerr << "Warning : Integer is compared with long int : " << rangeExpression << G4endl;
810 return G4UIparsing::CompareLong(newVal[i].I, op, newVal[iii].L, paramERR);
811 }
812 if (newValtype2 == 'D') {
813 G4cerr << "Warning : Integer is compared with double : " << rangeExpression << G4endl;
814 return G4UIparsing::CompareDouble(newVal[i].I, op, newVal[iii].D, paramERR);
815 }
816 //===================================================================
817 }
818 else {
819 G4cerr << "integer operand expected for " << rangeExpression << '.' << G4endl;
820 }
821 break;
822 case 'L':
823 if (arg2.type == CONSTINT) {
824 return G4UIparsing::CompareLong(newVal[i].L, op, arg2.I, paramERR);
825 }
826 else if (arg2.type == CONSTLONG) {
827 return G4UIparsing::CompareLong(newVal[i].L, op, arg2.L, paramERR);
828 }
829 else if (arg2.type == IDENTIFIER) {
830 unsigned iii = IndexOf(arg2.S);
831 char newValtype2 = (char)std::toupper(parameter[iii]->GetParameterType());
832 if (newValtype2 == 'I') {
833 return G4UIparsing::CompareLong(newVal[i].L, op, newVal[iii].I, paramERR);
834 }
835 if (newValtype2 == 'L') {
836 return G4UIparsing::CompareLong(newVal[i].L, op, newVal[iii].L, paramERR);
837 }
838 if (newValtype2 == 'D') {
839 G4cerr << "Warning : Long int is compared with double : " << rangeExpression << G4endl;
840 return G4UIparsing::CompareDouble(newVal[i].L, op, newVal[iii].D, paramERR);
841 }
842 //===================================================================
843 }
844 else {
845 G4cerr << "integer operand expected for " << rangeExpression << '.' << G4endl;
846 }
847 break;
848 case 'D':
849 if (arg2.type == CONSTDOUBLE) {
850 return G4UIparsing::CompareDouble(newVal[i].D, op, arg2.D, paramERR);
851 }
852 else if (arg2.type == CONSTINT) { // integral promotion
853 return G4UIparsing::CompareDouble(newVal[i].D, op, arg2.I, paramERR);
854 //===================================================================
855 // MA - 2018.07.23
856 }
857 else if (arg2.type == CONSTLONG) {
858 return G4UIparsing::CompareDouble(newVal[i].D, op, arg2.L, paramERR);
859 }
860 else if (arg2.type == IDENTIFIER) {
861 unsigned iii = IndexOf(arg2.S);
862 char newValtype2 = (char)std::toupper(parameter[iii]->GetParameterType());
863 if (newValtype2 == 'I') {
864 return G4UIparsing::CompareDouble(newVal[i].D, op, newVal[iii].I, paramERR);
865 }
866 if (newValtype2 == 'L') {
867 return G4UIparsing::CompareDouble(newVal[i].D, op, newVal[iii].L, paramERR);
868 }
869 if (newValtype2 == 'D') {
870 return G4UIparsing::CompareDouble(newVal[i].D, op, newVal[iii].D, paramERR);
871 }
872 //===================================================================
873 }
874 break;
875 default:;
876 }
877 }
878 if (arg2.type == IDENTIFIER) {
879 unsigned i = IndexOf(arg2.S);
880 newValtype = (char)std::toupper(parameter[i]->GetParameterType());
881 switch (newValtype) {
882 case 'I':
883 if (arg1.type == CONSTINT) {
884 return G4UIparsing::CompareInt(arg1.I, op, newVal[i].I, paramERR);
885 }
886 else {
887 G4cerr << "integer operand expected for " << rangeExpression << '.' << G4endl;
888 }
889 break;
890 case 'L':
891 if (arg1.type == CONSTLONG) {
892 return G4UIparsing::CompareLong(arg1.L, op, newVal[i].L, paramERR);
893 }
894 else {
895 G4cerr << "long int operand expected for " << rangeExpression << '.' << G4endl;
896 }
897 break;
898 case 'D':
899 if (arg1.type == CONSTDOUBLE) {
900 return G4UIparsing::CompareDouble(arg1.D, op, newVal[i].D, paramERR);
901 }
902 else if (arg1.type == CONSTINT) { // integral promotion
903 return G4UIparsing::CompareDouble(arg1.I, op, newVal[i].D, paramERR);
904 }
905 break;
906 default:;
907 }
908 }
909 return 0;
910}
911
912// --------------------------------------------------------------------
913unsigned G4UIcommand::IndexOf(const char* nam)
914{
915 for (unsigned i = 0; i < parameter.size(); ++i) {
916 if (parameter[i]->GetParameterName() == nam) {
917 return i;
918 }
919 }
920 paramERR = 1;
921 G4cerr << "parameter name:" << nam << " not found." << G4endl;
922 return 0;
923}
924
925// --------------------------------------------------------------------
926unsigned G4UIcommand::IsParameter(const char* nam)
927{
928 for (auto& i : parameter) {
929 if (i->GetParameterName() == nam) {
930 return 1;
931 }
932 }
933 return 0;
934}
935
936// --------------------- utility functions ----------------------------
937
938tokenNum G4UIcommand::Yylex() // reads input and returns token number, KR486
939{ // (returns EOF)
940 G4int c;
941 G4String buf;
942
943 while ((c = G4UIpGetc()) == ' ' || c == '\t' || c == '\n') {
944 ;
945 }
946 if (c == EOF) {
947 return (tokenNum)EOF; // KR488
948 }
949 buf = "";
950 if ((isdigit(c) != 0) || c == '.') { // I or D
951 do {
952 buf += (unsigned char)c;
953 c = G4UIpGetc();
954 } while (c == '.' || (isdigit(c) != 0) || c == 'e' || c == 'E' || c == '+' || c == '-');
955 G4UIpUngetc(c);
956 const char* t = buf;
957 std::istringstream is(t);
958 if (G4UIparsing::IsInt(buf.data(), 20)) {
959 is >> yylval.I;
960 return CONSTINT;
961 }
962 if (G4UIparsing::IsDouble(buf.data())) {
963 is >> yylval.D;
964 return CONSTDOUBLE;
965 }
966
967 G4cerr << buf << ": numeric format error." << G4endl;
968 }
969 buf = "";
970 if ((isalpha(c) != 0) || c == '_') { // IDENTIFIER
971 do {
972 buf += (unsigned char)c;
973 } while ((c = G4UIpGetc()) != EOF && ((isalnum(c) != 0) || c == '_'));
974 G4UIpUngetc(c);
975 if (IsParameter(buf) != 0u) {
976 yylval.S = buf;
977 return IDENTIFIER;
978 }
979
980 G4cerr << buf << " is not a parameter name." << G4endl;
981 paramERR = 1;
982 }
983 switch (c) {
984 case '>':
985 return (tokenNum)Follow('=', GE, GT);
986 case '<':
987 return (tokenNum)Follow('=', LE, LT);
988 case '=':
989 return (tokenNum)Follow('=', EQ, '=');
990 case '!':
991 return (tokenNum)Follow('=', NE, '!');
992 case '|':
993 return (tokenNum)Follow('|', LOGICALOR, '|');
994 case '&':
995 return (tokenNum)Follow('&', LOGICALAND, '&');
996 default:
997 return (tokenNum)c;
998 }
999}
1000
1001// --------------------------------------------------------------------
1002G4int G4UIcommand::Follow(G4int expect, G4int ifyes, G4int ifno)
1003{
1004 G4int c = G4UIpGetc();
1005 if (c == expect) {
1006 return ifyes;
1007 }
1008 G4UIpUngetc(c);
1009 return ifno;
1010}
1011
1012//------------------ low level routines -------------------------------
1013
1014G4int G4UIcommand::G4UIpGetc()
1015{ // emulation of getc()
1016 std::size_t length = rangeExpression.length();
1017 if (bp < (G4int)length) {
1018 return rangeExpression[bp++];
1019 }
1020
1021 return EOF;
1022}
1023
1024// --------------------------------------------------------------------
1025G4int G4UIcommand::G4UIpUngetc(G4int c)
1026{ // emulation of ungetc()
1027 if (c < 0) {
1028 return -1;
1029 }
1030 if (bp > 0 && c == rangeExpression[bp - 1]) {
1031 --bp;
1032 }
1033 else {
1034 G4cerr << "G4UIpUngetc() failed." << G4endl;
1035 G4cerr << "bp=" << bp << " c=" << c << " pR(bp-1)=" << rangeExpression[bp - 1] << G4endl;
1036 paramERR = 1;
1037 return -1;
1038 }
1039 return 0;
1040}
@ GT
Definition Evaluator.cc:68
@ LT
Definition Evaluator.cc:68
@ NE
Definition Evaluator.cc:68
@ GE
Definition Evaluator.cc:68
@ LE
Definition Evaluator.cc:68
@ EQ
Definition Evaluator.cc:68
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)
std::ostringstream G4ExceptionDescription
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
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double y() const
const G4ApplicationState & GetCurrentState() const
static G4StateManager * GetStateManager()
G4UIcommand()=default
static G4ThreeVector ConvertTo3Vector(const char *st)
G4bool toBeBroadcasted
static G4String CategoryOf(const char *unitName)
static G4double ValueOf(const char *unitName)
virtual ~G4UIcommand()
void SetCommandType(CommandType)
static G4long ConvertToLongInt(const char *st)
virtual G4int DoIt(G4String parameterList)
G4bool operator==(const G4UIcommand &right) const
static G4String ConvertToString(G4bool boolVal)
const G4String & GetCommandPath() const
G4int CheckNewValue(const char *newValue)
G4bool IsAvailable()
static G4int ConvertToInt(const char *st)
static G4String UnitsList(const char *unitCategory)
static G4bool ConvertToBool(const char *st)
static G4double ConvertToDouble(const char *st)
static G4double ConvertToDimensionedDouble(const char *st)
virtual void List()
G4bool workerThreadOnly
void AvailableForStates(G4ApplicationState s1)
G4bool operator!=(const G4UIcommand &right) const
static G4ThreeVector ConvertToDimensioned3Vector(const char *st)
G4String GetCurrentValue()
static G4bool DoublePrecisionStr()
static G4UImanager * GetMasterUIpointer()
void AddNewCommand(G4UIcommand *newCommand)
void RemoveCommand(G4UIcommand *aCommand)
static G4UImanager * GetUIpointer()
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()
G4bool IsMasterThread()
G4bool IsDouble(const char *str)
T StoT(const G4String &s)
G4int CompareLong(G4long arg1, G4int op, G4long arg2, G4int &errCode)
G4String TtoS(T value)
G4int CompareDouble(G4double arg1, G4int op, G4double arg2, G4int &errCode)
G4bool IsInt(const char *str, short maxDigits)
G4int CompareInt(G4int arg1, G4int op, G4int arg2, G4int &errCode)