Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4UIparameter.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// G4UIparameter
27//
28// Author: Makoto Asai, 1997
29// --------------------------------------------------------------------
30
31#include "G4UIparameter.hh"
32#include "G4UIcommandStatus.hh"
33#include "G4Tokenizer.hh"
34#include "G4ios.hh"
35#include "G4UIcommand.hh"
36
37#include <sstream>
38#include <ctype.h> // for CheckNewValue()
39
40using namespace G4UItokenNum;
41
42// --------------------------------------------------------------------
44{
45 parameterType = theType;
46}
47
48// --------------------------------------------------------------------
49G4UIparameter::G4UIparameter(const char* theName, char theType,
50 G4bool theOmittable)
51{
52 parameterName = theName;
53 parameterType = theType;
54 omittable = theOmittable;
55}
56
57// --------------------------------------------------------------------
59
60// --------------------------------------------------------------------
62{
63 return (this == &right);
64}
65
66// --------------------------------------------------------------------
68{
69 return (this != &right);
70}
71
72// --------------------------------------------------------------------
74{
75 G4cout << G4endl << "Parameter : " << parameterName << G4endl;
76 if(!parameterGuidance.empty())
77 {
78 G4cout << parameterGuidance << G4endl;
79 }
80 G4cout << " Parameter type : " << parameterType << G4endl;
81 if(omittable)
82 {
83 G4cout << " Omittable : True" << G4endl;
84 }
85 else
86 {
87 G4cout << " Omittable : False" << G4endl;
88 }
89 if(currentAsDefaultFlag)
90 {
91 G4cout << " Default value : taken from the current value" << G4endl;
92 }
93 else if(!defaultValue.empty())
94 {
95 G4cout << " Default value : " << defaultValue << G4endl;
96 }
97 if(!parameterRange.empty())
98 {
99 G4cout << " Parameter range : " << parameterRange << G4endl;
100 }
101 if(!parameterCandidate.empty())
102 {
103 G4cout << " Candidates : " << parameterCandidate << G4endl;
104 }
105}
106
107// --------------------------------------------------------------------
109{
110 std::ostringstream os;
111 os << theDefaultValue;
112 defaultValue = os.str();
113}
114
115// --------------------------------------------------------------------
117{
118 std::ostringstream os;
119 os << theDefaultValue;
120 defaultValue = os.str();
121}
122
123// --------------------------------------------------------------------
125{
126 std::ostringstream os;
127 os << theDefaultValue;
128 defaultValue = os.str();
129}
130
131// --------------------------------------------------------------------
132void G4UIparameter::SetDefaultUnit(const char* theDefaultUnit)
133{
134 char type = (char)std::toupper(parameterType);
135 if(type != 'S')
136 {
138 ed << "This method can be used only for a string-type parameter that is "
139 "used to specify a unit.\n"
140 << "This parameter <" << parameterName << "> is defined as ";
141 switch(type)
142 {
143 case 'D':
144 ed << "double.";
145 break;
146 case 'I':
147 ed << "integer.";
148 break;
149 case 'L':
150 ed << "long int.";
151 break;
152 case 'B':
153 ed << "bool.";
154 break;
155 default:
156 ed << "undefined.";
157 }
158 G4Exception("G4UIparameter::SetDefaultUnit", "INTERCOM2010", FatalException,
159 ed);
160 }
161 SetDefaultValue(theDefaultUnit);
164}
165
166// ---------- CheckNewValue() related routines ------------------------
167
168//#include "checkNewValue_debug.icc"
169//#define DEBUG 1
170
171// --------------------------------------------------------------------
173{
174 if(TypeCheck(newValue) == 0)
175 {
177 }
178 if(!parameterRange.empty())
179 {
180 if(RangeCheck(newValue) == 0)
181 {
183 }
184 }
185 if(!parameterCandidate.empty())
186 {
187 if(CandidateCheck(newValue) == 0)
188 {
190 }
191 }
192 return 0; // succeeded
193}
194
195// --------------------------------------------------------------------
196G4int G4UIparameter::CandidateCheck(const char* newValue)
197{
198 G4Tokenizer candidateTokenizer(parameterCandidate);
199 G4String aToken;
200 G4int iToken = 0;
201 while(!(aToken = candidateTokenizer()).empty())
202 {
203 ++iToken;
204 if(aToken == newValue)
205 {
206 return iToken;
207 }
208 }
209 G4cerr << "parameter value (" << newValue
210 << ") is not listed in the candidate List." << G4endl;
211 G4cerr << " Candidates are:";
212 G4Tokenizer candidateListTokenizer(parameterCandidate);
213 while(!(aToken = candidateListTokenizer()).empty())
214 {
215 G4cerr << ' ' << aToken;
216 }
217 G4cerr << G4endl;
218
219 return 0;
220}
221
222// --------------------------------------------------------------------
223G4int G4UIparameter::RangeCheck(const char* newValue)
224{
225 yystype result;
226 bp = 0; // reset buffer pointer for G4UIpGetc()
227 std::istringstream is(newValue);
228 char type = (char)std::toupper(parameterType);
229 switch(type)
230 {
231 case 'D':
232 is >> newVal.D;
233 break;
234 case 'I':
235 is >> newVal.I;
236 break;
237 case 'L':
238 is >> newVal.L;
239 break;
240 default:;
241 }
242 // PrintToken(); // Print tokens (consumes all tokens)
243 token = Yylex();
244 result = Expression();
245 if(paramERR == 1)
246 {
247 return 0;
248 }
249 if(result.type != CONSTINT)
250 {
251 G4cerr << "Illegal Expression in parameter range." << G4endl;
252 return 0;
253 }
254 if(result.I != 0)
255 {
256 return 1;
257 }
258 G4cerr << "parameter out of range: " << parameterRange << G4endl;
259 return 0;
260}
261
262// --------------------------------------------------------------------
263G4int G4UIparameter::TypeCheck(const char* newValue)
264{
265 G4String newValueString(newValue);
266 char type = (char)std::toupper(parameterType);
267 switch(type)
268 {
269 case 'D':
270 if(IsDouble(newValueString.data()) == 0)
271 {
272 G4cerr << newValue << ": double value expected." << G4endl;
273 return 0;
274 }
275 break;
276 case 'I':
277 if(IsInt(newValueString.data(), 10) == 0)
278 {
279 G4cerr << newValue << ": integer expected." << G4endl;
280 return 0;
281 }
282 break;
283 case 'L':
284 if(IsInt(newValueString.data(), 20) == 0)
285 {
286 G4cerr << newValue << ": long int expected." << G4endl;
287 return 0;
288 }
289 break;
290 case 'S':
291 break;
292 case 'B':
293 G4StrUtil::to_upper(newValueString);
294 if(newValueString == "Y" || newValueString == "N" ||
295 newValueString == "YES" || newValueString == "NO" ||
296 newValueString == "1" || newValueString == "0" ||
297 newValueString == "T" || newValueString == "F" ||
298 newValueString == "TRUE" || newValueString == "FALSE")
299 {
300 return 1;
301 }
302 else
303 {
304 G4cerr << newValue << ": bool expected." << G4endl;
305 return 0;
306 }
307 default:;
308 }
309 return 1;
310}
311
312// --------------------------------------------------------------------
313G4int G4UIparameter::IsInt(const char* buf,
314 short maxDigits) // do not allow any std::ws
315{
316 const char* p = buf;
317 G4int length = 0;
318 if(*p == '+' || *p == '-')
319 {
320 ++p;
321 }
322 if(isdigit((G4int) (*p)) != 0)
323 {
324 while(isdigit((G4int) (*p)) != 0)
325 {
326 ++p;
327 ++length;
328 }
329 if(*p == '\0')
330 {
331 if(length > maxDigits)
332 {
333 G4cerr << "digit length exceeds" << G4endl;
334 return 0;
335 }
336 return 1;
337 }
338 else
339 {
340 // G4cerr <<"illegal character after int:"<<buf<<G4endl;
341 }
342 }
343 else
344 {
345 // G4cerr <<"illegal int:"<<buf<<G4endl;
346 }
347 return 0;
348}
349
350// --------------------------------------------------------------------
351G4int G4UIparameter::ExpectExponent(const char* str) // used only by IsDouble()
352{
353 G4int maxExplength;
354 if(IsInt(str, maxExplength = 7) != 0)
355 {
356 return 1;
357 }
358 else
359 {
360 return 0;
361 }
362}
363
364// --------------------------------------------------------------------
365G4int G4UIparameter::IsDouble(
366 const char* buf) // see state diagram for this spec.
367{
368 const char* p = buf;
369 switch(*p)
370 {
371 case '+':
372 case '-':
373 ++p;
374 if(isdigit(*p) != 0)
375 {
376 while(isdigit((G4int) (*p)) != 0)
377 {
378 ++p;
379 }
380 switch(*p)
381 {
382 case '\0':
383 return 1; // break;
384 case 'E':
385 case 'e':
386 return ExpectExponent(++p); // break;
387 case '.':
388 ++p;
389 if(*p == '\0')
390 {
391 return 1;
392 }
393 if(*p == 'e' || *p == 'E')
394 {
395 return ExpectExponent(++p);
396 }
397 if(isdigit(*p) != 0)
398 {
399 while(isdigit((G4int) (*p)) != 0)
400 {
401 ++p;
402 }
403 if(*p == '\0')
404 {
405 return 1;
406 }
407 if(*p == 'e' || *p == 'E')
408 {
409 return ExpectExponent(++p);
410 }
411 }
412 else
413 {
414 return 0;
415 }
416 break;
417 default:
418 return 0;
419 }
420 }
421 if(*p == '.')
422 {
423 ++p;
424 if(isdigit(*p) != 0)
425 {
426 while(isdigit((G4int) (*p)) != 0)
427 {
428 ++p;
429 }
430 if(*p == '\0')
431 {
432 return 1;
433 }
434 if(*p == 'e' || *p == 'E')
435 {
436 return ExpectExponent(++p);
437 }
438 }
439 }
440 break;
441 case '.':
442 ++p;
443 if(isdigit(*p) != 0)
444 {
445 while(isdigit((G4int) (*p)) != 0)
446 {
447 ++p;
448 }
449 if(*p == '\0')
450 {
451 return 1;
452 }
453 if(*p == 'e' || *p == 'E')
454 {
455 return ExpectExponent(++p);
456 }
457 }
458 break;
459 default: // digit is expected
460 if(isdigit(*p) != 0)
461 {
462 while(isdigit((G4int) (*p)) != 0)
463 {
464 ++p;
465 }
466 if(*p == '\0')
467 {
468 return 1;
469 }
470 if(*p == 'e' || *p == 'E')
471 {
472 return ExpectExponent(++p);
473 }
474 if(*p == '.')
475 {
476 ++p;
477 if(*p == '\0')
478 {
479 return 1;
480 }
481 if(*p == 'e' || *p == 'E')
482 {
483 return ExpectExponent(++p);
484 }
485 if(isdigit(*p) != 0)
486 {
487 while(isdigit((G4int) (*p)) != 0)
488 {
489 ++p;
490 }
491 if(*p == '\0')
492 {
493 return 1;
494 }
495 if(*p == 'e' || *p == 'E')
496 {
497 return ExpectExponent(++p);
498 }
499 }
500 }
501 }
502 }
503 return 0;
504}
505
506// ------------------ syntax node functions ------------------
507
508yystype G4UIparameter::Expression()
509{
510 yystype result;
511#ifdef DEBUG
512 G4cerr << " Expression()" << G4endl;
513#endif
514 result = LogicalORExpression();
515 return result;
516}
517
518// --------------------------------------------------------------------
519yystype G4UIparameter::LogicalORExpression()
520{
521 yystype result;
522 yystype p;
523 p = LogicalANDExpression();
524 if(token != LOGICALOR)
525 {
526 return p;
527 }
528 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
529 {
530 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
531 paramERR = 1;
532 }
533 result.I = p.I;
534 while(token == LOGICALOR)
535 {
536 token = Yylex();
537 p = LogicalANDExpression();
538 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
539 {
540 G4cerr << "Parameter range: illegal type at '||'" << G4endl;
541 paramERR = 1;
542 }
543 switch(p.type)
544 {
545 case CONSTINT:
546 result.I += p.I;
547 result.type = CONSTINT;
548 break;
549 case CONSTLONG:
550 result.I += static_cast<int>(p.L != 0L);
551 result.type = CONSTINT;
552 break;
553 case CONSTDOUBLE:
554 result.I += static_cast<int>(p.D != 0.0);
555 result.type = CONSTINT;
556 break;
557 default:
558 G4cerr << "Parameter range: unknown type" << G4endl;
559 paramERR = 1;
560 }
561 }
562 return result;
563}
564
565// --------------------------------------------------------------------
566yystype G4UIparameter::LogicalANDExpression()
567{
568 yystype result;
569 yystype p;
570 p = EqualityExpression();
571 if(token != LOGICALAND)
572 {
573 return p;
574 }
575 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
576 {
577 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
578 paramERR = 1;
579 }
580 result.I = p.I;
581 while(token == LOGICALAND)
582 {
583 token = Yylex();
584 p = EqualityExpression();
585 if(p.type == CONSTSTRING || p.type == IDENTIFIER)
586 {
587 G4cerr << "Parameter range: illegal type at '&&'" << G4endl;
588 paramERR = 1;
589 }
590 switch(p.type)
591 {
592 case CONSTINT:
593 result.I *= p.I;
594 result.type = CONSTINT;
595 break;
596 case CONSTLONG:
597 result.I *= static_cast<int>(p.L != 0L);
598 result.type = CONSTINT;
599 break;
600 case CONSTDOUBLE:
601 result.I *= static_cast<int>(p.D != 0.0);
602 result.type = CONSTINT;
603 break;
604 default:
605 G4cerr << "Parameter range: unknown type." << G4endl;
606 paramERR = 1;
607 }
608 }
609 return result;
610}
611
612// --------------------------------------------------------------------
613yystype G4UIparameter::EqualityExpression()
614{
615 yystype arg1, arg2;
616 G4int operat;
617 yystype result;
618#ifdef DEBUG
619 G4cerr << " EqualityExpression()" << G4endl;
620#endif
621 result = RelationalExpression();
622 if(token == EQ || token == NE)
623 {
624 operat = token;
625 token = Yylex();
626 arg1 = result;
627 arg2 = RelationalExpression();
628 result.I = Eval2(arg1, operat, arg2); // semantic action
629 result.type = CONSTINT;
630#ifdef DEBUG
631 G4cerr << " return code of Eval2(): " << result.I << G4endl;
632#endif
633 }
634 else
635 {
636 if(result.type != CONSTINT && result.type != CONSTDOUBLE)
637 {
638 G4cerr << "Parameter range: error at EqualityExpression" << G4endl;
639 paramERR = 1;
640 }
641 }
642 return result;
643}
644
645// --------------------------------------------------------------------
646yystype G4UIparameter::RelationalExpression()
647{
648 yystype arg1, arg2;
649 G4int operat;
650 yystype result;
651#ifdef DEBUG
652 G4cerr << " RelationalExpression()" << G4endl;
653#endif
654
655 arg1 = AdditiveExpression();
656 if(token == GT || token == GE || token == LT || token == LE)
657 {
658 operat = token;
659 token = Yylex();
660 arg2 = AdditiveExpression();
661 result.I = Eval2(arg1, operat, arg2); // semantic action
662 result.type = CONSTINT;
663#ifdef DEBUG
664 G4cerr << " return Eval2(): " << G4endl;
665#endif
666 }
667 else
668 {
669 result = arg1;
670 }
671#ifdef DEBUG
672 G4cerr << " return RelationalExpression()" << G4endl;
673#endif
674 return result;
675}
676
677// --------------------------------------------------------------------
678yystype G4UIparameter::AdditiveExpression()
679{
680 yystype result;
681 result = MultiplicativeExpression();
682 if(token != '+' && token != '-')
683 {
684 return result;
685 }
686 G4cerr << "Parameter range: operator " << (char) token << " is not supported."
687 << G4endl;
688 paramERR = 1;
689 return result;
690}
691
692// --------------------------------------------------------------------
693yystype G4UIparameter::MultiplicativeExpression()
694{
695 yystype result;
696 result = UnaryExpression();
697 if(token != '*' && token != '/' && token != '%')
698 {
699 return result;
700 }
701 G4cerr << "Parameter range: operator " << (char) token << " is not supported."
702 << G4endl;
703 paramERR = 1;
704 return result;
705}
706
707// --------------------------------------------------------------------
708yystype G4UIparameter::UnaryExpression()
709{
710 yystype result;
711 yystype p;
712#ifdef DEBUG
713 G4cerr << " UnaryExpression" << G4endl;
714#endif
715 switch(token)
716 {
717 case '-':
718 token = Yylex();
719 p = UnaryExpression();
720 if(p.type == CONSTINT)
721 {
722 result.I = -p.I;
723 result.type = CONSTINT;
724 }
725 if(p.type == CONSTLONG)
726 {
727 result.L = -p.L;
728 result.type = CONSTLONG;
729 }
730 if(p.type == CONSTDOUBLE)
731 {
732 result.D = -p.D;
733 result.type = CONSTDOUBLE;
734 }
735 break;
736 case '+':
737 token = Yylex();
738 result = UnaryExpression();
739 break;
740 case '!':
741 token = Yylex();
742 G4cerr << "Parameter range error: "
743 << "operator '!' is not supported (sorry)." << G4endl;
744 paramERR = 1;
745 result = UnaryExpression();
746 break;
747 default:
748 result = PrimaryExpression();
749 }
750 return result;
751}
752
753// --------------------------------------------------------------------
754yystype G4UIparameter::PrimaryExpression()
755{
756 yystype result;
757#ifdef DEBUG
758 G4cerr << " PrimaryExpression" << G4endl;
759#endif
760 switch(token)
761 {
762 case IDENTIFIER:
763 result.S = yylval.S;
764 result.type = token;
765 token = Yylex();
766 break;
767 case CONSTINT:
768 result.I = yylval.I;
769 result.type = token;
770 token = Yylex();
771 break;
772 case CONSTLONG:
773 result.L = yylval.L;
774 result.type = token;
775 token = Yylex();
776 break;
777 case CONSTDOUBLE:
778 result.D = yylval.D;
779 result.type = token;
780 token = Yylex();
781 break;
782 case '(':
783 token = Yylex();
784 result = Expression();
785 if(token != ')')
786 {
787 G4cerr << " ')' expected" << G4endl;
788 paramERR = 1;
789 }
790 token = Yylex();
791 break;
792 default:
793 return result;
794 }
795 return result; // never executed
796}
797
798//---------------- semantic routines ---------------------------------
799
800G4int G4UIparameter::Eval2(const yystype& arg1, G4int op, const yystype& arg2)
801{
802 if((arg1.type != IDENTIFIER) && (arg2.type != IDENTIFIER))
803 {
804 G4cerr << parameterName << ": meaningless comparison " << G4int(arg1.type)
805 << " " << G4int(arg2.type) << G4endl;
806 paramERR = 1;
807 }
808 char type = (char)std::toupper(parameterType);
809 if(arg1.type == IDENTIFIER)
810 {
811 switch(type)
812 {
813 case 'I':
814 if(arg2.type == CONSTINT)
815 {
816 return CompareInt(newVal.I, op, arg2.I);
817 }
818 else
819 {
820 G4cerr << "integer operand expected for " << parameterRange << '.'
821 << G4endl;
822 }
823 break;
824 case 'L':
825 if(arg2.type == CONSTLONG)
826 {
827 return CompareLong(newVal.L, op, arg2.L);
828 }
829 else
830 {
831 G4cerr << "long int operand expected for " << parameterRange << '.'
832 << G4endl;
833 }
834 break;
835 case 'D':
836 if(arg2.type == CONSTDOUBLE)
837 {
838 return CompareDouble(newVal.D, op, arg2.D);
839 }
840 else if(arg2.type == CONSTINT)
841 { // integral promotion
842 return CompareDouble(newVal.D, op, arg2.I);
843 }
844 else if(arg2.type == CONSTLONG)
845 {
846 return CompareDouble(newVal.D, op, arg2.L);
847 }
848 break;
849 default:;
850 }
851 }
852 if(arg2.type == IDENTIFIER)
853 {
854 switch(type)
855 {
856 case 'I':
857 if(arg1.type == CONSTINT)
858 {
859 return CompareInt(arg1.I, op, newVal.I);
860 }
861 else
862 {
863 G4cerr << "integer operand expected for " << parameterRange << '.'
864 << G4endl;
865 }
866 break;
867 case 'L':
868 if(arg1.type == CONSTLONG)
869 {
870 return CompareLong(arg1.L, op, newVal.L);
871 }
872 else
873 {
874 G4cerr << "long int operand expected for " << parameterRange << '.'
875 << G4endl;
876 }
877 break;
878 case 'D':
879 if(arg1.type == CONSTDOUBLE)
880 {
881 return CompareDouble(arg1.D, op, newVal.D);
882 }
883 else if(arg1.type == CONSTINT)
884 { // integral promotion
885 return CompareDouble(arg1.I, op, newVal.D);
886 }
887 else if(arg1.type == CONSTLONG)
888 { // integral promotion
889 return CompareDouble(arg1.L, op, newVal.D);
890 }
891 break;
892 default:;
893 }
894 }
895 G4cerr << "no param name is specified at the param range." << G4endl;
896 return 0;
897}
898
899// --------------------------------------------------------------------
900G4int G4UIparameter::CompareInt(G4int arg1, G4int op, G4int arg2)
901{
902 G4int result = -1;
903 G4String opr;
904 switch(op)
905 {
906 case GT:
907 result = static_cast<G4int>(arg1 > arg2);
908 opr = ">";
909 break;
910 case GE:
911 result = static_cast<G4int>(arg1 >= arg2);
912 opr = ">=";
913 break;
914 case LT:
915 result = static_cast<G4int>(arg1 < arg2);
916 opr = "<";
917 break;
918 case LE:
919 result = static_cast<G4int>(arg1 <= arg2);
920 opr = "<=";
921 break;
922 case EQ:
923 result = static_cast<G4int>(arg1 == arg2);
924 opr = "==";
925 break;
926 case NE:
927 result = static_cast<G4int>(arg1 != arg2);
928 opr = "!=";
929 break;
930 default:
931 G4cerr << "Parameter range: error at CompareInt" << G4endl;
932 paramERR = 1;
933 }
934#ifdef DEBUG
935 G4cerr << "CompareInt " << arg1 << " " << opr << arg2 << " result: " << result
936 << G4endl;
937#endif
938 return result;
939}
940
941// --------------------------------------------------------------------
942G4int G4UIparameter::CompareLong(G4long arg1, G4int op, G4long arg2)
943{
944 G4int result = -1;
945 G4String opr;
946 switch(op)
947 {
948 case GT:
949 result = static_cast<G4int>(arg1 > arg2);
950 opr = ">";
951 break;
952 case GE:
953 result = static_cast<G4int>(arg1 >= arg2);
954 opr = ">=";
955 break;
956 case LT:
957 result = static_cast<G4int>(arg1 < arg2);
958 opr = "<";
959 break;
960 case LE:
961 result = static_cast<G4int>(arg1 <= arg2);
962 opr = "<=";
963 break;
964 case EQ:
965 result = static_cast<G4int>(arg1 == arg2);
966 opr = "==";
967 break;
968 case NE:
969 result = static_cast<G4int>(arg1 != arg2);
970 opr = "!=";
971 break;
972 default:
973 G4cerr << "Parameter range: error at CompareInt" << G4endl;
974 paramERR = 1;
975 }
976#ifdef DEBUG
977 G4cerr << "CompareInt " << arg1 << " " << opr << arg2 << " result: " << result
978 << G4endl;
979#endif
980 return result;
981}
982
983// --------------------------------------------------------------------
984G4int G4UIparameter::CompareDouble(G4double arg1, G4int op, G4double arg2)
985{
986 G4int result = -1;
987 G4String opr;
988 switch(op)
989 {
990 case GT:
991 result = static_cast<G4int>(arg1 > arg2);
992 opr = ">";
993 break;
994 case GE:
995 result = static_cast<G4int>(arg1 >= arg2);
996 opr = ">=";
997 break;
998 case LT:
999 result = static_cast<G4int>(arg1 < arg2);
1000 opr = "<";
1001 break;
1002 case LE:
1003 result = static_cast<G4int>(arg1 <= arg2);
1004 opr = "<=";
1005 break;
1006 case EQ:
1007 result = static_cast<G4int>(arg1 == arg2);
1008 opr = "==";
1009 break;
1010 case NE:
1011 result = static_cast<G4int>(arg1 != arg2);
1012 opr = "!=";
1013 break;
1014 default:
1015 G4cerr << "Parameter range: error at CompareDouble" << G4endl;
1016 paramERR = 1;
1017 }
1018#ifdef DEBUG
1019 G4cerr << "CompareDouble " << arg1 << " " << opr << " " << arg2
1020 << " result: " << result << G4endl;
1021#endif
1022 return result;
1023}
1024
1025// --------------------- utility functions --------------------------
1026
1027tokenNum G4UIparameter::Yylex() // reads input and returns token number KR486
1028{ // (returns EOF)
1029 G4int c;
1030 G4String buf;
1031
1032 while((c = G4UIpGetc()) == ' ' || c == '\t' || c == '\n')
1033 {
1034 ;
1035 }
1036 if(c == EOF)
1037 {
1038 return (tokenNum) EOF; // KR488
1039 }
1040 buf = "";
1041 if((isdigit(c) != 0) || c == '.')
1042 { // I or D
1043 do
1044 {
1045 buf += (unsigned char) c;
1046 c = G4UIpGetc();
1047 } while(c == '.' || (isdigit(c) != 0) || c == 'e' || c == 'E' || c == '+' ||
1048 c == '-');
1049 G4UIpUngetc(c);
1050 const char* t = buf;
1051 std::istringstream is(t);
1052 if(IsInt(buf.data(), 20) != 0)
1053 {
1054 is >> yylval.I;
1055 return CONSTINT;
1056 }
1057 else if(IsDouble(buf.data()) != 0)
1058 {
1059 is >> yylval.D;
1060 return CONSTDOUBLE;
1061 }
1062 else
1063 {
1064 G4cerr << buf << ": numeric format error." << G4endl;
1065 }
1066 }
1067 buf = "";
1068 if((isalpha(c) != 0) || c == '_')
1069 { // IDENTIFIER
1070 do
1071 {
1072 buf += (unsigned char) c;
1073 } while((c = G4UIpGetc()) != EOF && ((isalnum(c) != 0) || c == '_'));
1074 G4UIpUngetc(c);
1075 if(buf == parameterName)
1076 {
1077 yylval.S = buf;
1078 return IDENTIFIER;
1079 }
1080 else
1081 {
1082 G4cerr << buf << " is not a parameter name." << G4endl;
1083 paramERR = 1;
1084 }
1085 }
1086 switch(c)
1087 {
1088 case '>':
1089 return (tokenNum) Follow('=', GE, GT);
1090 case '<':
1091 return (tokenNum) Follow('=', LE, LT);
1092 case '=':
1093 return (tokenNum) Follow('=', EQ, '=');
1094 case '!':
1095 return (tokenNum) Follow('=', NE, '!');
1096 case '|':
1097 return (tokenNum) Follow('|', LOGICALOR, '|');
1098 case '&':
1099 return (tokenNum) Follow('&', LOGICALAND, '&');
1100 default:
1101 return (tokenNum) c;
1102 }
1103}
1104
1105// --------------------------------------------------------------------
1106G4int G4UIparameter::Follow(G4int expect, G4int ifyes, G4int ifno)
1107{
1108 G4int c = G4UIpGetc();
1109 if(c == expect)
1110 {
1111 return ifyes;
1112 }
1113 G4UIpUngetc(c);
1114 return ifno;
1115}
1116
1117//------------------ low level routines -----------------------------
1118
1119G4int G4UIparameter::G4UIpGetc()
1120{ // emulation of getc()
1121 G4int length = (G4int)parameterRange.length();
1122 if(bp < length)
1123 {
1124 return parameterRange[bp++];
1125 }
1126 else
1127 {
1128 return EOF;
1129 }
1130}
1131
1132// --------------------------------------------------------------------
1133G4int G4UIparameter::G4UIpUngetc(G4int c)
1134{ // emulation of ungetc()
1135 if(c < 0)
1136 {
1137 return -1;
1138 }
1139 if(bp > 0 && c == parameterRange[bp - 1])
1140 {
1141 --bp;
1142 }
1143 else
1144 {
1145 G4cerr << "G4UIpUngetc() failed." << G4endl;
1146 G4cerr << "bp=" << bp << " c=" << c
1147 << " pR(bp-1)=" << parameterRange[bp - 1] << G4endl;
1148 paramERR = 1;
1149 return -1;
1150 }
1151 return 0;
1152}
1153// ***** end of CheckNewValue() related code ******
@ 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
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
double G4double
Definition: G4Types.hh:83
long G4long
Definition: G4Types.hh:87
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
@ fParameterOutOfCandidates
@ fParameterUnreadable
@ fParameterOutOfRange
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4String CategoryOf(const char *unitName)
Definition: G4UIcommand.cc:370
static G4String UnitsList(const char *unitCategory)
Definition: G4UIcommand.cc:376
void SetDefaultValue(const char *theDefaultValue)
G4int CheckNewValue(const char *newValue)
G4UIparameter()=default
void SetParameterCandidates(const char *theString)
G4bool operator!=(const G4UIparameter &right) const
G4bool operator==(const G4UIparameter &right) const
void SetDefaultUnit(const char *theDefaultUnit)
void to_upper(G4String &str)
Convert string to uppercase.
yystype { tokenNum type{ tokenNum::NONE } yystype
Definition: G4UItokenNum.hh:67