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