Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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