1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "../common/dbgnew.hh"
10 #include "Identifier.hh"
11 #include "Valuestuff.hh"
12 #include "PredefFunc.hh"
13 #include "CompField.hh"
14 #include "CompType.hh"
15 #include "EnumItem.hh"
16 #include "TypeCompat.hh"
17 #include "asn1/Block.hh"
18 #include "asn1/TokenBuf.hh"
24 #include "ttcn3/TtcnTemplate.hh"
25 #include "ttcn3/ArrayDimensions.hh"
27 #include "../common/pattern.hh"
29 #include "ttcn3/PatternString.hh"
30 #include "ttcn3/Statement.hh"
32 #include "ttcn3/Attributes.hh"
40 static void clean_up_string_elements(map
<size_t, Value
>*& string_elements
)
42 if (string_elements
) {
43 for (size_t i
= 0; i
< string_elements
->size(); i
++)
44 delete string_elements
->get_nth_elem(i
);
45 string_elements
->clear();
46 delete string_elements
;
51 // =================================
53 // =================================
55 Value::Value(const Value
& p
)
56 : GovernedSimple(p
), valuetype(p
.valuetype
), my_governor(0)
68 u
.val_bool
=p
.u
.val_bool
;
71 u
.val_Int
=new int_val_t(*(p
.u
.val_Int
));
76 u
.val_id
=p
.u
.val_id
->clone();
79 u
.val_Real
=p
.u
.val_Real
;
86 set_val_str(new string(*p
.u
.str
.val_str
));
89 set_val_ustr(new ustring(*p
.u
.ustr
.val_ustr
));
90 u
.ustr
.convert_str
= p
.u
.ustr
.convert_str
;
93 u
.char_syms
= p
.u
.char_syms
->clone();
97 u
.oid_comps
=new vector
<OID_comp
>;
98 for(size_t i
=0; i
<p
.u
.oid_comps
->size(); i
++)
99 add_oid_comp((*p
.u
.oid_comps
)[i
]->clone());
102 u
.choice
.alt_name
=p
.u
.choice
.alt_name
->clone();
103 u
.choice
.alt_value
=p
.u
.choice
.alt_value
->clone();
108 u
.val_vs
=p
.u
.val_vs
->clone();
112 u
.val_nvs
=p
.u
.val_nvs
->clone();
115 u
.ref
.ref
=p
.u
.ref
.ref
->clone();
119 for(size_t i
=0; i
<p
.u
.ids
->size(); i
++) {
120 Identifier
*id
= p
.u
.ids
->get_nth_elem(i
);
121 u
.ids
->add(id
->get_name(), id
->clone());
125 u
.block
=p
.u
.block
->clone();
128 u
.verdict
=p
.u
.verdict
;
131 u
.expr
.v_optype
= p
.u
.expr
.v_optype
;
132 u
.expr
.state
= EXPR_NOT_CHECKED
;
133 switch(u
.expr
.v_optype
) {
134 case OPTYPE_RND
: // -
135 case OPTYPE_COMP_NULL
:
136 case OPTYPE_COMP_MTC
:
137 case OPTYPE_COMP_SYSTEM
:
138 case OPTYPE_COMP_SELF
:
139 case OPTYPE_COMP_RUNNING_ANY
:
140 case OPTYPE_COMP_RUNNING_ALL
:
141 case OPTYPE_COMP_ALIVE_ANY
:
142 case OPTYPE_COMP_ALIVE_ALL
:
143 case OPTYPE_TMR_RUNNING_ANY
:
144 case OPTYPE_GETVERDICT
:
145 case OPTYPE_TESTCASENAME
:
146 case OPTYPE_PROF_RUNNING
:
148 case OPTYPE_UNARYPLUS
: // v1
149 case OPTYPE_UNARYMINUS
:
156 case OPTYPE_CHAR2INT
:
157 case OPTYPE_CHAR2OCT
:
158 case OPTYPE_COMP_RUNNING
:
159 case OPTYPE_COMP_ALIVE
:
160 case OPTYPE_FLOAT2INT
:
161 case OPTYPE_FLOAT2STR
:
166 case OPTYPE_INT2CHAR
:
167 case OPTYPE_INT2FLOAT
:
169 case OPTYPE_INT2UNICHAR
:
171 case OPTYPE_OCT2CHAR
:
176 case OPTYPE_STR2FLOAT
:
180 case OPTYPE_UNICHAR2INT
:
181 case OPTYPE_UNICHAR2CHAR
:
182 case OPTYPE_ENUM2INT
:
183 case OPTYPE_RNDWITHVAL
:
184 case OPTYPE_GET_STRINGENCODING
:
185 case OPTYPE_DECODE_BASE64
:
186 case OPTYPE_REMOVE_BOM
:
187 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
189 case OPTYPE_ADD
: // v1 v2
190 case OPTYPE_SUBTRACT
:
191 case OPTYPE_MULTIPLY
:
215 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
216 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
218 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
219 case OPTYPE_OCT2UNICHAR
:
220 case OPTYPE_ENCODE_BASE64
:
221 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
222 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
225 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
226 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
229 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
230 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
231 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
234 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
235 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
236 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
238 case OPTYPE_DECOMP
: // v1 v2 v3
239 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
240 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
241 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
244 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
245 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
246 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
247 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
249 case OPTYPE_LENGTHOF
: // ti1
250 case OPTYPE_SIZEOF
: // ti1
251 case OPTYPE_VALUEOF
: // ti1
253 case OPTYPE_ISPRESENT
:
254 case OPTYPE_TTCN2STRING
:
255 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
257 case OPTYPE_UNDEF_RUNNING
:
258 case OPTYPE_TMR_READ
:
259 case OPTYPE_TMR_RUNNING
:
260 case OPTYPE_ACTIVATE
:
261 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
263 case OPTYPE_EXECUTE
: // r1 [v2]
264 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
265 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
267 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
268 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
269 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
270 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
271 u
.expr
.b4
= p
.u
.expr
.b4
;
273 case OPTYPE_MATCH
: // v1 t2
274 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
275 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
277 case OPTYPE_ISCHOSEN
: // r1 i2
278 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
279 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
281 case OPTYPE_ISCHOSEN_V
: // v1 i2
282 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
283 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
285 case OPTYPE_ISCHOSEN_T
: // t1 i2
286 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
287 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
289 case OPTYPE_ACTIVATE_REFD
:
290 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
291 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
292 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
294 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
295 u
.expr
.state
= EXPR_CHECKED
;
298 case OPTYPE_EXECUTE_REFD
:
299 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
300 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
301 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
303 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
304 u
.expr
.state
= EXPR_CHECKED
;
306 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
309 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
312 FATAL_ERROR("Value::Value()");
321 u
.refd_fat
= p
.u
.refd_fat
;
324 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
325 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
326 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
329 u
.refered
= p
.u
.refered
->clone();
332 FATAL_ERROR("Value::Value()");
336 void Value::clean_up()
359 case V_UNDEF_LOWERID
:
367 delete u
.str
.val_str
;
368 clean_up_string_elements(u
.str
.str_elements
);
371 delete u
.ustr
.val_ustr
;
372 clean_up_string_elements(u
.ustr
.ustr_elements
);
380 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
381 delete (*u
.oid_comps
)[i
];
382 u
.oid_comps
->clear();
390 delete u
.choice
.alt_name
;
391 delete u
.choice
.alt_value
;
410 delete u
.invoke
.t_list
;
411 delete u
.invoke
.ap_list
;
415 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
424 FATAL_ERROR("Value::clean_up()");
428 void Value::clean_up_expr()
430 switch (u
.expr
.state
) {
432 case EXPR_CHECKING_ERR
:
433 FATAL_ERROR("Value::clean_up_expr()");
437 switch (u
.expr
.v_optype
) {
438 case OPTYPE_RND
: // -
439 case OPTYPE_COMP_NULL
:
440 case OPTYPE_COMP_MTC
:
441 case OPTYPE_COMP_SYSTEM
:
442 case OPTYPE_COMP_SELF
:
443 case OPTYPE_COMP_RUNNING_ANY
:
444 case OPTYPE_COMP_RUNNING_ALL
:
445 case OPTYPE_COMP_ALIVE_ANY
:
446 case OPTYPE_COMP_ALIVE_ALL
:
447 case OPTYPE_TMR_RUNNING_ANY
:
448 case OPTYPE_GETVERDICT
:
449 case OPTYPE_TESTCASENAME
:
450 case OPTYPE_PROF_RUNNING
:
452 case OPTYPE_UNARYPLUS
: // v1
453 case OPTYPE_UNARYMINUS
:
460 case OPTYPE_CHAR2INT
:
461 case OPTYPE_CHAR2OCT
:
462 case OPTYPE_COMP_RUNNING
:
463 case OPTYPE_COMP_ALIVE
:
464 case OPTYPE_FLOAT2INT
:
465 case OPTYPE_FLOAT2STR
:
470 case OPTYPE_INT2CHAR
:
471 case OPTYPE_INT2FLOAT
:
473 case OPTYPE_INT2UNICHAR
:
475 case OPTYPE_OCT2CHAR
:
480 case OPTYPE_STR2FLOAT
:
484 case OPTYPE_UNICHAR2INT
:
485 case OPTYPE_UNICHAR2CHAR
:
486 case OPTYPE_ENUM2INT
:
487 case OPTYPE_RNDWITHVAL
:
488 case OPTYPE_REMOVE_BOM
:
489 case OPTYPE_GET_STRINGENCODING
:
490 case OPTYPE_DECODE_BASE64
:
493 case OPTYPE_ADD
: // v1 v2
494 case OPTYPE_SUBTRACT
:
495 case OPTYPE_MULTIPLY
:
519 case OPTYPE_UNICHAR2OCT
:
520 case OPTYPE_OCT2UNICHAR
:
521 case OPTYPE_ENCODE_BASE64
:
539 case OPTYPE_DECOMP
: // v1 v2 v3
550 case OPTYPE_LENGTHOF
: // ti1
551 case OPTYPE_SIZEOF
: // ti1
552 case OPTYPE_VALUEOF
: // ti1
556 case OPTYPE_ISPRESENT
:
557 case OPTYPE_TTCN2STRING
:
560 case OPTYPE_UNDEF_RUNNING
:
561 case OPTYPE_TMR_READ
:
562 case OPTYPE_TMR_RUNNING
:
563 case OPTYPE_ACTIVATE
:
566 case OPTYPE_EXECUTE
: // r1 [v2]
570 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
575 case OPTYPE_MATCH
: // v1 t2
579 case OPTYPE_ISCHOSEN
: // r1 i2
583 case OPTYPE_ISCHOSEN_V
: // v1 i2
587 case OPTYPE_ISCHOSEN_T
: // t1 i2
591 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
593 if(u
.expr
.state
!=EXPR_CHECKED
)
594 delete u
.expr
.t_list2
;
596 delete u
.expr
.ap_list2
;
598 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
600 if(u
.expr
.state
!=EXPR_CHECKED
)
601 delete u
.expr
.t_list2
;
603 delete u
.expr
.ap_list2
;
607 delete u
.expr
.logargs
;
610 FATAL_ERROR("Value::clean_up_expr()");
614 void Value::copy_and_destroy(Value
*src
)
617 valuetype
= src
->valuetype
;
619 // update the pointer used for caching if it points to the value itself
620 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
621 src
->valuetype
= V_ERROR
;
625 Value::Value(valuetype_t p_vt
)
626 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
637 u
.oid_comps
=new vector
<OID_comp
>();
640 u
.ids
=new map
<string
, Identifier
>();
643 FATAL_ERROR("Value::Value()");
647 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
648 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
652 u
.val_bool
=p_val_bool
;
655 FATAL_ERROR("Value::Value()");
659 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
660 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
664 u
.val_Int
=new int_val_t(p_val_Int
);
667 FATAL_ERROR("Value::Value()");
671 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
672 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
679 FATAL_ERROR("Value::Value()");
683 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
684 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
686 if(!p_val_str
) FATAL_ERROR("NULL parameter");
693 set_val_str(p_val_str
);
696 FATAL_ERROR("Value::Value()");
700 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
701 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
703 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
704 set_val_ustr(p_val_ustr
);
705 u
.ustr
.convert_str
= false;
708 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
709 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
711 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
714 u
.char_syms
= p_char_syms
;
717 FATAL_ERROR("Value::Value()");
721 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
722 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
725 FATAL_ERROR("NULL parameter");
729 case V_UNDEF_LOWERID
:
733 FATAL_ERROR("Value::Value()");
737 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
738 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
741 FATAL_ERROR("NULL parameter");
744 u
.choice
.alt_name
=p_id
;
745 u
.choice
.alt_value
=p_val
;
748 FATAL_ERROR("Value::Value()");
752 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
753 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
757 u
.val_Real
=p_val_Real
;
760 FATAL_ERROR("Value::Value()");
764 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
765 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
767 if(!p_vs
) FATAL_ERROR("NULL parameter");
775 FATAL_ERROR("Value::Value()");
779 Value::Value(valuetype_t p_vt
, Value
*p_v
,
780 Ttcn::ParsedActualParameters
*p_t_list
)
781 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
783 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
787 u
.invoke
.t_list
= p_t_list
;
788 u
.invoke
.ap_list
= 0;
791 FATAL_ERROR("Value::Value()");
796 Value::Value(operationtype_t p_optype
)
797 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
799 u
.expr
.v_optype
= p_optype
;
800 u
.expr
.state
= EXPR_NOT_CHECKED
;
803 case OPTYPE_COMP_NULL
:
804 case OPTYPE_COMP_MTC
:
805 case OPTYPE_COMP_SYSTEM
:
806 case OPTYPE_COMP_SELF
:
807 case OPTYPE_COMP_RUNNING_ANY
:
808 case OPTYPE_COMP_RUNNING_ALL
:
809 case OPTYPE_COMP_ALIVE_ANY
:
810 case OPTYPE_COMP_ALIVE_ALL
:
811 case OPTYPE_TMR_RUNNING_ANY
:
812 case OPTYPE_GETVERDICT
:
813 case OPTYPE_TESTCASENAME
:
814 case OPTYPE_PROF_RUNNING
:
817 FATAL_ERROR("Value::Value()");
822 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
823 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
825 u
.expr
.v_optype
= p_optype
;
826 u
.expr
.state
= EXPR_NOT_CHECKED
;
828 case OPTYPE_UNARYPLUS
:
829 case OPTYPE_UNARYMINUS
:
836 case OPTYPE_CHAR2INT
:
837 case OPTYPE_CHAR2OCT
:
838 case OPTYPE_COMP_RUNNING
:
839 case OPTYPE_COMP_ALIVE
:
840 case OPTYPE_FLOAT2INT
:
841 case OPTYPE_FLOAT2STR
:
846 case OPTYPE_INT2CHAR
:
847 case OPTYPE_INT2FLOAT
:
849 case OPTYPE_INT2UNICHAR
:
851 case OPTYPE_OCT2CHAR
:
856 case OPTYPE_STR2FLOAT
:
860 case OPTYPE_UNICHAR2INT
:
861 case OPTYPE_UNICHAR2CHAR
:
862 case OPTYPE_ENUM2INT
:
863 case OPTYPE_RNDWITHVAL
:
864 case OPTYPE_REMOVE_BOM
:
865 case OPTYPE_GET_STRINGENCODING
:
866 case OPTYPE_DECODE_BASE64
:
867 if(!p_v1
) FATAL_ERROR("Value::Value()");
871 FATAL_ERROR("Value::Value()");
876 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
877 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
879 u
.expr
.v_optype
= p_optype
;
880 u
.expr
.state
= EXPR_NOT_CHECKED
;
882 case OPTYPE_LENGTHOF
:
888 case OPTYPE_ISPRESENT
:
889 case OPTYPE_TTCN2STRING
:
890 if(!p_ti1
) FATAL_ERROR("Value::Value()");
894 FATAL_ERROR("Value::Value()");
899 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
900 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
902 u
.expr
.v_optype
= p_optype
;
903 u
.expr
.state
= EXPR_NOT_CHECKED
;
905 case OPTYPE_UNDEF_RUNNING
:
906 case OPTYPE_TMR_READ
:
907 case OPTYPE_TMR_RUNNING
:
908 case OPTYPE_ACTIVATE
:
909 if(!p_r1
) FATAL_ERROR("Value::Value()");
913 FATAL_ERROR("Value::Value()");
918 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
919 Ttcn::ParsedActualParameters
*p_ap_list
)
920 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
922 u
.expr
.v_optype
= p_optype
;
923 u
.expr
.state
= EXPR_NOT_CHECKED
;
925 case OPTYPE_ACTIVATE_REFD
:
926 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
928 u
.expr
.t_list2
= p_ap_list
;
931 FATAL_ERROR("Value::Value()");
936 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
937 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
938 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
940 u
.expr
.v_optype
= p_optype
;
941 u
.expr
.state
= EXPR_NOT_CHECKED
;
943 case OPTYPE_EXECUTE_REFD
:
944 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
946 u
.expr
.t_list2
= p_t_list2
;
950 FATAL_ERROR("Value::Value()");
955 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
956 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
958 u
.expr
.v_optype
= p_optype
;
959 u
.expr
.state
= EXPR_NOT_CHECKED
;
962 if(!p_r1
) FATAL_ERROR("Value::Value()");
967 FATAL_ERROR("Value::Value()");
972 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
973 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
974 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
976 u
.expr
.v_optype
= p_optype
;
977 u
.expr
.state
= EXPR_NOT_CHECKED
;
979 case OPTYPE_COMP_CREATE
:
980 if(!p_r1
) FATAL_ERROR("Value::Value()");
987 FATAL_ERROR("Value::Value()");
992 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
993 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
995 u
.expr
.v_optype
= p_optype
;
996 u
.expr
.state
= EXPR_NOT_CHECKED
;
999 case OPTYPE_SUBTRACT
:
1000 case OPTYPE_MULTIPLY
:
1021 case OPTYPE_INT2BIT
:
1022 case OPTYPE_INT2HEX
:
1023 case OPTYPE_INT2OCT
:
1024 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1028 case OPTYPE_UNICHAR2OCT
:
1029 case OPTYPE_OCT2UNICHAR
:
1030 case OPTYPE_ENCODE_BASE64
:
1031 if(!p_v1
) FATAL_ERROR("Value::Value()");
1033 // p_v2 may be NULL if there is no second param
1037 FATAL_ERROR("Value::Value()");
1042 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1043 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1044 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1046 u
.expr
.v_optype
= p_optype
;
1047 u
.expr
.state
= EXPR_NOT_CHECKED
;
1049 case OPTYPE_REPLACE
:
1050 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1057 FATAL_ERROR("Value::Value()");
1062 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1063 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1065 u
.expr
.v_optype
= p_optype
;
1066 u
.expr
.state
= EXPR_NOT_CHECKED
;
1069 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1075 FATAL_ERROR("Value::Value()");
1080 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1081 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1083 u
.expr
.v_optype
=p_optype
;
1084 u
.expr
.state
=EXPR_NOT_CHECKED
;
1087 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1093 FATAL_ERROR("Value::Value()");
1098 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1099 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1101 u
.expr
.v_optype
=p_optype
;
1102 u
.expr
.state
=EXPR_NOT_CHECKED
;
1105 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1111 FATAL_ERROR("Value::Value()");
1116 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1117 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1119 u
.expr
.v_optype
= p_optype
;
1120 u
.expr
.state
= EXPR_NOT_CHECKED
;
1123 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1128 FATAL_ERROR("Value::Value()");
1133 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1135 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1137 u
.expr
.v_optype
= p_optype
;
1138 u
.expr
.state
= EXPR_NOT_CHECKED
;
1140 case OPTYPE_ISCHOSEN
:
1141 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1146 FATAL_ERROR("Value::Value()");
1150 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1151 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1153 u
.expr
.v_optype
= p_optype
;
1154 u
.expr
.state
= EXPR_NOT_CHECKED
;
1156 case OPTYPE_LOG2STR
:
1157 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1158 u
.expr
.logargs
= p_logargs
;
1161 FATAL_ERROR("Value::Value()");
1165 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1166 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1168 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1169 switch (p_macrotype
) {
1170 case MACRO_MODULEID
:
1171 case MACRO_FILENAME
:
1172 case MACRO_BFILENAME
:
1173 case MACRO_FILEPATH
:
1174 case MACRO_LINENUMBER
:
1175 case MACRO_LINENUMBER_C
:
1176 case MACRO_DEFINITIONID
:
1178 case MACRO_TESTCASEID
:
1181 FATAL_ERROR("Value::Value()");
1183 u
.macro
= p_macrotype
;
1186 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1187 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1189 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1196 FATAL_ERROR("Value::Value()");
1200 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1201 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1203 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1207 u
.ref
.refd_last
= 0;
1213 FATAL_ERROR("Value::Value()");
1217 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1218 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1220 if(!p_block
) FATAL_ERROR("NULL parameter");
1226 FATAL_ERROR("Value::Value()");
1230 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1231 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1233 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1234 switch (p_verdict
) {
1237 case Verdict_INCONC
:
1242 FATAL_ERROR("Value::Value()");
1244 u
.verdict
= p_verdict
;
1247 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1248 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1250 u
.expr
.v_optype
= p_optype
;
1251 u
.expr
.state
= EXPR_NOT_CHECKED
;
1254 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1259 FATAL_ERROR("Value::Value()");
1268 Value
*Value::clone() const
1270 return new Value(*this);
1273 Value::operationtype_t
Value::get_optype() const
1275 if(valuetype
!=V_EXPR
)
1276 FATAL_ERROR("Value::get_optype()");
1277 return u
.expr
.v_optype
;
1280 void Value::set_my_governor(Type
*p_gov
)
1283 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1287 Type
*Value::get_my_governor() const
1292 void Value::set_fullname(const string
& p_fullname
)
1294 GovernedSimple::set_fullname(p_fullname
);
1297 u
.char_syms
->set_fullname(p_fullname
);
1301 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1302 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1305 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1306 u
.choice
.alt_name
->get_dispname());
1311 u
.val_vs
->set_fullname(p_fullname
);
1315 u
.val_nvs
->set_fullname(p_fullname
);
1318 u
.ref
.ref
->set_fullname(p_fullname
);
1321 u
.refered
->set_fullname(p_fullname
);
1324 u
.invoke
.v
->set_fullname(p_fullname
);
1325 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1326 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1329 set_fullname_expr(p_fullname
);
1336 void Value::set_my_scope(Scope
*p_scope
)
1338 GovernedSimple::set_my_scope(p_scope
);
1341 u
.char_syms
->set_my_scope(p_scope
);
1345 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1346 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1349 u
.choice
.alt_value
->set_my_scope(p_scope
);
1354 u
.val_vs
->set_my_scope(p_scope
);
1358 u
.val_nvs
->set_my_scope(p_scope
);
1361 u
.ref
.ref
->set_my_scope(p_scope
);
1364 u
.refered
->set_my_scope(p_scope
);
1367 u
.invoke
.v
->set_my_scope(p_scope
);
1368 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1369 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1372 set_my_scope_expr(p_scope
);
1379 void Value::set_fullname_expr(const string
& p_fullname
)
1381 switch (u
.expr
.v_optype
) {
1382 case OPTYPE_RND
: // -
1383 case OPTYPE_COMP_NULL
:
1384 case OPTYPE_COMP_MTC
:
1385 case OPTYPE_COMP_SYSTEM
:
1386 case OPTYPE_COMP_SELF
:
1387 case OPTYPE_COMP_RUNNING_ANY
:
1388 case OPTYPE_COMP_RUNNING_ALL
:
1389 case OPTYPE_COMP_ALIVE_ANY
:
1390 case OPTYPE_COMP_ALIVE_ALL
:
1391 case OPTYPE_TMR_RUNNING_ANY
:
1392 case OPTYPE_GETVERDICT
:
1393 case OPTYPE_TESTCASENAME
:
1394 case OPTYPE_PROF_RUNNING
:
1396 case OPTYPE_UNARYPLUS
: // v1
1397 case OPTYPE_UNARYMINUS
:
1400 case OPTYPE_BIT2HEX
:
1401 case OPTYPE_BIT2INT
:
1402 case OPTYPE_BIT2OCT
:
1403 case OPTYPE_BIT2STR
:
1404 case OPTYPE_CHAR2INT
:
1405 case OPTYPE_CHAR2OCT
:
1406 case OPTYPE_COMP_RUNNING
:
1407 case OPTYPE_COMP_ALIVE
:
1408 case OPTYPE_FLOAT2INT
:
1409 case OPTYPE_FLOAT2STR
:
1410 case OPTYPE_HEX2BIT
:
1411 case OPTYPE_HEX2INT
:
1412 case OPTYPE_HEX2OCT
:
1413 case OPTYPE_HEX2STR
:
1414 case OPTYPE_INT2CHAR
:
1415 case OPTYPE_INT2FLOAT
:
1416 case OPTYPE_INT2STR
:
1417 case OPTYPE_INT2UNICHAR
:
1418 case OPTYPE_OCT2BIT
:
1419 case OPTYPE_OCT2CHAR
:
1420 case OPTYPE_OCT2HEX
:
1421 case OPTYPE_OCT2INT
:
1422 case OPTYPE_OCT2STR
:
1423 case OPTYPE_STR2BIT
:
1424 case OPTYPE_STR2FLOAT
:
1425 case OPTYPE_STR2HEX
:
1426 case OPTYPE_STR2INT
:
1427 case OPTYPE_STR2OCT
:
1428 case OPTYPE_UNICHAR2INT
:
1429 case OPTYPE_UNICHAR2CHAR
:
1430 case OPTYPE_ENUM2INT
:
1431 case OPTYPE_RNDWITHVAL
:
1432 case OPTYPE_REMOVE_BOM
:
1433 case OPTYPE_GET_STRINGENCODING
:
1434 case OPTYPE_DECODE_BASE64
:
1435 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1437 case OPTYPE_ADD
: // v1 v2
1438 case OPTYPE_SUBTRACT
:
1439 case OPTYPE_MULTIPLY
:
1460 case OPTYPE_INT2BIT
:
1461 case OPTYPE_INT2HEX
:
1462 case OPTYPE_INT2OCT
:
1463 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1464 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1466 case OPTYPE_UNICHAR2OCT
:
1467 case OPTYPE_OCT2UNICHAR
:
1468 case OPTYPE_ENCODE_BASE64
:
1469 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1470 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1473 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1474 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1477 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1478 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1479 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1482 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1483 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1484 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1486 case OPTYPE_DECOMP
: // v1 v2 v3
1487 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1488 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1489 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1491 case OPTYPE_REPLACE
:
1492 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1493 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1494 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1495 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1497 case OPTYPE_LENGTHOF
: // ti1
1498 case OPTYPE_SIZEOF
: // ti1
1499 case OPTYPE_VALUEOF
: // ti1
1500 case OPTYPE_ISVALUE
:
1501 case OPTYPE_ISBOUND
:
1503 case OPTYPE_ISPRESENT
:
1504 case OPTYPE_TTCN2STRING
:
1505 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1507 case OPTYPE_UNDEF_RUNNING
: // r1
1508 case OPTYPE_TMR_READ
:
1509 case OPTYPE_TMR_RUNNING
:
1510 case OPTYPE_ACTIVATE
:
1511 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1513 case OPTYPE_EXECUTE
: // r1 [v2]
1514 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1515 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1517 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1518 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1519 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1520 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1522 case OPTYPE_MATCH
: // v1 t2
1523 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1524 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1526 case OPTYPE_ISCHOSEN
: // r1 i2
1527 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1529 case OPTYPE_ISCHOSEN_V
: // v1 i2
1530 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1532 case OPTYPE_ISCHOSEN_T
: // t1 i2
1533 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1535 case OPTYPE_ACTIVATE_REFD
:
1536 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1537 if(u
.expr
.state
!=EXPR_CHECKED
)
1538 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1540 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1542 case OPTYPE_EXECUTE_REFD
:
1543 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1544 if(u
.expr
.state
!=EXPR_CHECKED
)
1545 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1547 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1549 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1551 case OPTYPE_LOG2STR
:
1552 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1555 FATAL_ERROR("Value::set_fullname_expr()");
1559 void Value::set_my_scope_expr(Scope
*p_scope
)
1561 switch (u
.expr
.v_optype
) {
1562 case OPTYPE_RND
: // -
1563 case OPTYPE_COMP_NULL
:
1564 case OPTYPE_COMP_MTC
:
1565 case OPTYPE_COMP_SYSTEM
:
1566 case OPTYPE_COMP_SELF
:
1567 case OPTYPE_COMP_RUNNING_ANY
:
1568 case OPTYPE_COMP_RUNNING_ALL
:
1569 case OPTYPE_COMP_ALIVE_ANY
:
1570 case OPTYPE_COMP_ALIVE_ALL
:
1571 case OPTYPE_TMR_RUNNING_ANY
:
1572 case OPTYPE_GETVERDICT
:
1573 case OPTYPE_TESTCASENAME
:
1574 case OPTYPE_PROF_RUNNING
:
1576 case OPTYPE_UNARYPLUS
: // v1
1577 case OPTYPE_UNARYMINUS
:
1580 case OPTYPE_BIT2HEX
:
1581 case OPTYPE_BIT2INT
:
1582 case OPTYPE_BIT2OCT
:
1583 case OPTYPE_BIT2STR
:
1584 case OPTYPE_CHAR2INT
:
1585 case OPTYPE_CHAR2OCT
:
1586 case OPTYPE_COMP_RUNNING
:
1587 case OPTYPE_COMP_ALIVE
:
1588 case OPTYPE_FLOAT2INT
:
1589 case OPTYPE_FLOAT2STR
:
1590 case OPTYPE_HEX2BIT
:
1591 case OPTYPE_HEX2INT
:
1592 case OPTYPE_HEX2OCT
:
1593 case OPTYPE_HEX2STR
:
1594 case OPTYPE_INT2CHAR
:
1595 case OPTYPE_INT2FLOAT
:
1596 case OPTYPE_INT2STR
:
1597 case OPTYPE_INT2UNICHAR
:
1598 case OPTYPE_OCT2BIT
:
1599 case OPTYPE_OCT2CHAR
:
1600 case OPTYPE_OCT2HEX
:
1601 case OPTYPE_OCT2INT
:
1602 case OPTYPE_OCT2STR
:
1603 case OPTYPE_STR2BIT
:
1604 case OPTYPE_STR2FLOAT
:
1605 case OPTYPE_STR2HEX
:
1606 case OPTYPE_STR2INT
:
1607 case OPTYPE_STR2OCT
:
1608 case OPTYPE_UNICHAR2INT
:
1609 case OPTYPE_UNICHAR2CHAR
:
1610 case OPTYPE_ENUM2INT
:
1611 case OPTYPE_RNDWITHVAL
:
1612 case OPTYPE_REMOVE_BOM
:
1613 case OPTYPE_GET_STRINGENCODING
:
1614 case OPTYPE_DECODE_BASE64
:
1615 u
.expr
.v1
->set_my_scope(p_scope
);
1617 case OPTYPE_ADD
: // v1 v2
1618 case OPTYPE_SUBTRACT
:
1619 case OPTYPE_MULTIPLY
:
1640 case OPTYPE_INT2BIT
:
1641 case OPTYPE_INT2HEX
:
1642 case OPTYPE_INT2OCT
:
1643 u
.expr
.v1
->set_my_scope(p_scope
);
1644 u
.expr
.v2
->set_my_scope(p_scope
);
1646 case OPTYPE_UNICHAR2OCT
:
1647 case OPTYPE_OCT2UNICHAR
:
1648 case OPTYPE_ENCODE_BASE64
:
1649 u
.expr
.v1
->set_my_scope(p_scope
);
1650 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1653 u
.expr
.r1
->set_my_scope(p_scope
);
1654 u
.expr
.r2
->set_my_scope(p_scope
);
1657 u
.expr
.ti1
->set_my_scope(p_scope
);
1658 u
.expr
.v2
->set_my_scope(p_scope
);
1659 u
.expr
.v3
->set_my_scope(p_scope
);
1662 u
.expr
.ti1
->set_my_scope(p_scope
);
1663 u
.expr
.t2
->set_my_scope(p_scope
);
1664 u
.expr
.v3
->set_my_scope(p_scope
);
1666 case OPTYPE_DECOMP
: // v1 v2 v3
1667 u
.expr
.v1
->set_my_scope(p_scope
);
1668 u
.expr
.v2
->set_my_scope(p_scope
);
1669 u
.expr
.v3
->set_my_scope(p_scope
);
1671 case OPTYPE_REPLACE
:
1672 u
.expr
.ti1
->set_my_scope(p_scope
);
1673 u
.expr
.v2
->set_my_scope(p_scope
);
1674 u
.expr
.v3
->set_my_scope(p_scope
);
1675 u
.expr
.ti4
->set_my_scope(p_scope
);
1677 case OPTYPE_LENGTHOF
: // ti1
1678 case OPTYPE_SIZEOF
: // ti1
1679 case OPTYPE_VALUEOF
: // ti1
1680 case OPTYPE_ISVALUE
:
1681 case OPTYPE_ISBOUND
:
1683 case OPTYPE_ISPRESENT
:
1684 case OPTYPE_TTCN2STRING
:
1685 u
.expr
.ti1
->set_my_scope(p_scope
);
1687 case OPTYPE_UNDEF_RUNNING
: // r1
1688 case OPTYPE_TMR_READ
:
1689 case OPTYPE_TMR_RUNNING
:
1690 case OPTYPE_ACTIVATE
:
1691 u
.expr
.r1
->set_my_scope(p_scope
);
1693 case OPTYPE_EXECUTE
: // r1 [v2]
1694 u
.expr
.r1
->set_my_scope(p_scope
);
1695 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1697 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1698 u
.expr
.r1
->set_my_scope(p_scope
);
1699 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1700 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1702 case OPTYPE_MATCH
: // v1 t2
1703 u
.expr
.v1
->set_my_scope(p_scope
);
1704 u
.expr
.t2
->set_my_scope(p_scope
);
1706 case OPTYPE_ISCHOSEN
: // r1 i2
1707 u
.expr
.r1
->set_my_scope(p_scope
);
1709 case OPTYPE_ISCHOSEN_V
: // v1 i2
1710 u
.expr
.v1
->set_my_scope(p_scope
);
1712 case OPTYPE_ISCHOSEN_T
: // t1 i2
1713 u
.expr
.t1
->set_my_scope(p_scope
);
1715 case OPTYPE_ACTIVATE_REFD
:
1716 u
.expr
.v1
->set_my_scope(p_scope
);
1717 if(u
.expr
.state
!=EXPR_CHECKED
) {
1718 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1720 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1722 case OPTYPE_EXECUTE_REFD
:
1723 u
.expr
.v1
->set_my_scope(p_scope
);
1724 if(u
.expr
.state
!=EXPR_CHECKED
) {
1725 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1727 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1730 u
.expr
.v3
->set_my_scope(p_scope
);
1732 case OPTYPE_LOG2STR
:
1733 u
.expr
.logargs
->set_my_scope(p_scope
);
1736 FATAL_ERROR("Value::set_my_scope_expr()");
1740 void Value::set_genname_recursive(const string
& p_genname
)
1742 size_t genname_len
= p_genname
.size();
1743 if (genname_len
>= 4 &&
1744 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1745 // if the genname ends with ()() (i.e. the value stands for an optional
1746 // field) then drop the last () from the own genname, but leave it for
1747 // the embedded values
1748 set_genname(p_genname
.substr(0, genname_len
- 2));
1749 } else set_genname(p_genname
);
1752 string
embedded_genname(p_genname
);
1753 embedded_genname
+= '.';
1754 // If this is a choice value for an anytype, prepend the AT_ prefix
1755 // to the name of the alternative. The genname is used later in
1756 // Common::Value::generate_code_init_se()
1757 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1758 embedded_genname
+= "AT_";
1759 embedded_genname
+= u
.choice
.alt_name
->get_name();
1760 embedded_genname
+= "()";
1761 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1765 if (!is_indexed()) {
1766 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1767 for (size_t i
= 0; i
< nof_vs
; i
++) {
1768 string
embedded_genname(p_genname
);
1769 embedded_genname
+= '[';
1770 embedded_genname
+= Int2string(i
);
1771 embedded_genname
+= ']';
1772 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1775 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1776 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1777 string
embedded_genname(p_genname
);
1778 embedded_genname
+= '[';
1779 embedded_genname
+= Int2string(i
);
1780 embedded_genname
+= ']';
1781 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1782 ->set_genname_recursive(embedded_genname
);
1787 if (!my_governor
) return; // error recovery
1788 Type
*type
= my_governor
->get_type_refd_last();
1789 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1790 Int offset
= type
->get_dimension()->get_offset();
1791 if (!is_indexed()) {
1792 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1793 for (size_t i
= 0; i
< nof_vs
; i
++) {
1794 string
embedded_genname(p_genname
);
1795 embedded_genname
+= '[';
1796 embedded_genname
+= Int2string(offset
+ i
);
1797 embedded_genname
+= ']';
1798 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1801 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1802 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1803 string
embedded_genname(p_genname
);
1804 embedded_genname
+= '[';
1805 embedded_genname
+= Int2string(offset
+ i
);
1806 embedded_genname
+= ']';
1807 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1808 ->set_genname_recursive(embedded_genname
);
1814 if (!my_governor
) return; // error recovery
1815 Type
*t
= my_governor
->get_type_refd_last();
1816 if (!t
->is_secho()) return; // error recovery
1817 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1818 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1819 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1820 const Identifier
& id
= nv
->get_name();
1821 if (!t
->has_comp_withName(id
)) return; // error recovery
1822 string
embedded_genname(p_genname
);
1823 embedded_genname
+= '.';
1824 embedded_genname
+= id
.get_name();
1825 embedded_genname
+= "()";
1826 if (t
->get_comp_byName(id
)->get_is_optional())
1827 embedded_genname
+= "()";
1828 nv
->get_value()->set_genname_recursive(embedded_genname
);
1836 void Value::set_genname_prefix(const char *p_genname_prefix
)
1838 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1841 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1846 if (!is_indexed()) {
1847 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1848 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1850 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1851 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1852 ->set_genname_prefix(p_genname_prefix
);
1857 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1858 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1859 ->set_genname_prefix(p_genname_prefix
);
1866 void Value::set_code_section(code_section_t p_code_section
)
1868 GovernedSimple::set_code_section(p_code_section
);
1871 switch (u
.expr
.v_optype
) {
1872 case OPTYPE_RND
: // -
1873 case OPTYPE_COMP_NULL
:
1874 case OPTYPE_COMP_MTC
:
1875 case OPTYPE_COMP_SYSTEM
:
1876 case OPTYPE_COMP_SELF
:
1877 case OPTYPE_COMP_RUNNING_ANY
:
1878 case OPTYPE_COMP_RUNNING_ALL
:
1879 case OPTYPE_COMP_ALIVE_ANY
:
1880 case OPTYPE_COMP_ALIVE_ALL
:
1881 case OPTYPE_TMR_RUNNING_ANY
:
1882 case OPTYPE_GETVERDICT
:
1883 case OPTYPE_TESTCASENAME
:
1884 case OPTYPE_PROF_RUNNING
:
1886 case OPTYPE_UNARYPLUS
: // v1
1887 case OPTYPE_UNARYMINUS
:
1890 case OPTYPE_BIT2HEX
:
1891 case OPTYPE_BIT2INT
:
1892 case OPTYPE_BIT2OCT
:
1893 case OPTYPE_BIT2STR
:
1894 case OPTYPE_CHAR2INT
:
1895 case OPTYPE_CHAR2OCT
:
1896 case OPTYPE_COMP_RUNNING
:
1897 case OPTYPE_COMP_ALIVE
:
1898 case OPTYPE_FLOAT2INT
:
1899 case OPTYPE_FLOAT2STR
:
1900 case OPTYPE_HEX2BIT
:
1901 case OPTYPE_HEX2INT
:
1902 case OPTYPE_HEX2OCT
:
1903 case OPTYPE_HEX2STR
:
1904 case OPTYPE_INT2CHAR
:
1905 case OPTYPE_INT2FLOAT
:
1906 case OPTYPE_INT2STR
:
1907 case OPTYPE_INT2UNICHAR
:
1908 case OPTYPE_OCT2BIT
:
1909 case OPTYPE_OCT2CHAR
:
1910 case OPTYPE_OCT2HEX
:
1911 case OPTYPE_OCT2INT
:
1912 case OPTYPE_OCT2STR
:
1913 case OPTYPE_STR2BIT
:
1914 case OPTYPE_STR2FLOAT
:
1915 case OPTYPE_STR2HEX
:
1916 case OPTYPE_STR2INT
:
1917 case OPTYPE_STR2OCT
:
1918 case OPTYPE_UNICHAR2INT
:
1919 case OPTYPE_UNICHAR2CHAR
:
1920 case OPTYPE_ENUM2INT
:
1921 case OPTYPE_RNDWITHVAL
:
1922 case OPTYPE_GET_STRINGENCODING
:
1923 case OPTYPE_DECODE_BASE64
:
1924 case OPTYPE_REMOVE_BOM
:
1925 u
.expr
.v1
->set_code_section(p_code_section
);
1927 case OPTYPE_ADD
: // v1 v2
1928 case OPTYPE_SUBTRACT
:
1929 case OPTYPE_MULTIPLY
:
1950 case OPTYPE_INT2BIT
:
1951 case OPTYPE_INT2HEX
:
1952 case OPTYPE_INT2OCT
:
1953 u
.expr
.v1
->set_code_section(p_code_section
);
1954 u
.expr
.v2
->set_code_section(p_code_section
);
1956 case OPTYPE_UNICHAR2OCT
:
1957 case OPTYPE_OCT2UNICHAR
:
1958 case OPTYPE_ENCODE_BASE64
:
1959 u
.expr
.v1
->set_code_section(p_code_section
);
1960 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
1963 u
.expr
.r1
->set_code_section(p_code_section
);
1964 u
.expr
.r2
->set_code_section(p_code_section
);
1967 u
.expr
.ti1
->set_code_section(p_code_section
);
1968 u
.expr
.v2
->set_code_section(p_code_section
);
1969 u
.expr
.v3
->set_code_section(p_code_section
);
1972 u
.expr
.ti1
->set_code_section(p_code_section
);
1973 u
.expr
.t2
->set_code_section(p_code_section
);
1974 u
.expr
.v3
->set_code_section(p_code_section
);
1976 case OPTYPE_DECOMP
: // v1 v2 v3
1977 u
.expr
.v1
->set_code_section(p_code_section
);
1978 u
.expr
.v2
->set_code_section(p_code_section
);
1979 u
.expr
.v3
->set_code_section(p_code_section
);
1981 case OPTYPE_REPLACE
:
1982 u
.expr
.ti1
->set_code_section(p_code_section
);
1983 u
.expr
.v2
->set_code_section(p_code_section
);
1984 u
.expr
.v3
->set_code_section(p_code_section
);
1985 u
.expr
.ti4
->set_code_section(p_code_section
);
1987 case OPTYPE_LENGTHOF
: // ti1
1988 case OPTYPE_SIZEOF
: // ti1
1989 case OPTYPE_VALUEOF
: // ti1
1990 case OPTYPE_ISVALUE
:
1991 case OPTYPE_ISBOUND
:
1993 case OPTYPE_ISPRESENT
:
1994 case OPTYPE_TTCN2STRING
:
1995 u
.expr
.ti1
->set_code_section(p_code_section
);
1997 case OPTYPE_UNDEF_RUNNING
: // r1
1998 case OPTYPE_TMR_READ
:
1999 case OPTYPE_TMR_RUNNING
:
2000 case OPTYPE_ACTIVATE
:
2001 u
.expr
.r1
->set_code_section(p_code_section
);
2003 case OPTYPE_EXECUTE
: // r1 [v2]
2004 u
.expr
.r1
->set_code_section(p_code_section
);
2005 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2007 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2008 u
.expr
.r1
->set_code_section(p_code_section
);
2009 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2010 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2012 case OPTYPE_MATCH
: // v1 t2
2013 u
.expr
.v1
->set_code_section(p_code_section
);
2014 u
.expr
.t2
->set_code_section(p_code_section
);
2016 case OPTYPE_ISCHOSEN
: // r1 i2
2017 u
.expr
.r1
->set_code_section(p_code_section
);
2019 case OPTYPE_ISCHOSEN_V
: // v1 i2
2020 u
.expr
.v1
->set_code_section(p_code_section
);
2022 case OPTYPE_ISCHOSEN_T
: // t1 i2
2023 u
.expr
.t1
->set_code_section(p_code_section
);
2025 case OPTYPE_ACTIVATE_REFD
:
2026 u
.expr
.v1
->set_code_section(p_code_section
);
2027 if(u
.expr
.state
!=EXPR_CHECKED
)
2028 u
.expr
.t_list2
->set_code_section(p_code_section
);
2030 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2031 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2032 u
.expr
.state
= EXPR_CHECKED
;
2035 case OPTYPE_EXECUTE_REFD
:
2036 u
.expr
.v1
->set_code_section(p_code_section
);
2037 if(u
.expr
.state
!=EXPR_CHECKED
)
2038 u
.expr
.t_list2
->set_code_section(p_code_section
);
2040 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2041 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2042 u
.expr
.state
= EXPR_CHECKED
;
2045 u
.expr
.v3
->set_code_section(p_code_section
);
2047 case OPTYPE_LOG2STR
:
2048 u
.expr
.logargs
->set_code_section(p_code_section
);
2051 FATAL_ERROR("Value::set_code_section()");
2055 u
.choice
.alt_value
->set_code_section(p_code_section
);
2060 if (!is_indexed()) {
2061 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2062 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2064 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2065 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2070 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2071 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2072 ->set_code_section(p_code_section
);
2075 u
.ref
.ref
->set_code_section(p_code_section
);
2078 u
.refered
->set_code_section(p_code_section
);
2081 u
.invoke
.v
->set_code_section(p_code_section
);
2082 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2083 if(u
.invoke
.ap_list
)
2084 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2085 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2092 void Value::change_sign()
2096 *u
.val_Int
=-*u
.val_Int
;
2104 FATAL_ERROR("Value::change_sign()");
2108 void Value::add_oid_comp(OID_comp
* p_comp
)
2111 FATAL_ERROR("NULL parameter");
2112 u
.oid_comps
->add(p_comp
);
2113 p_comp
->set_fullname(get_fullname()+"."
2114 +Int2string(u
.oid_comps
->size()));
2115 p_comp
->set_my_scope(my_scope
);
2118 void Value::set_valuetype(valuetype_t p_valuetype
)
2120 if (valuetype
== V_ERROR
) return;
2121 else if (p_valuetype
== V_ERROR
) {
2122 if(valuetype
==V_EXPR
) {
2123 switch(u
.expr
.state
) {
2125 u
.expr
.state
=EXPR_CHECKING_ERR
;
2127 case EXPR_CHECKING_ERR
:
2134 valuetype
= V_ERROR
;
2138 case V_UNDEF_LOWERID
:
2139 switch(p_valuetype
) {
2144 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2145 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2146 u
.ref
.ref
->set_my_scope(get_my_scope());
2147 u
.ref
.ref
->set_fullname(get_fullname());
2148 u
.ref
.ref
->set_location(*this);
2149 u
.ref
.refd_last
= 0;
2152 FATAL_ERROR("Value::set_valuetype()");
2155 case V_UNDEF_BLOCK
: {
2156 Block
*t_block
=u
.block
;
2158 switch(p_valuetype
) {
2160 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2161 v
=dynamic_cast<Value
*>(node
);
2164 u
.ids
=new map
<string
, Identifier
>();
2167 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2171 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2172 v
=dynamic_cast<Value
*>(node
);
2175 u
.val_vs
=new Values();
2178 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2180 u
.val_vs
->set_my_scope(get_my_scope());
2181 u
.val_vs
->set_fullname(get_fullname());
2184 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2185 v
=dynamic_cast<Value
*>(node
);
2188 u
.val_vs
=new Values();
2191 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2193 u
.val_vs
->set_my_scope(get_my_scope());
2194 u
.val_vs
->set_fullname(get_fullname());
2197 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2198 v
=dynamic_cast<Value
*>(node
);
2201 u
.val_nvs
=new NamedValues();
2204 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2206 u
.val_nvs
->set_my_scope(get_my_scope());
2207 u
.val_nvs
->set_fullname(get_fullname());
2210 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2211 v
=dynamic_cast<Value
*>(node
);
2214 u
.val_nvs
=new NamedValues();
2217 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2219 u
.val_nvs
->set_my_scope(get_my_scope());
2220 u
.val_nvs
->set_fullname(get_fullname());
2223 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2224 v
=dynamic_cast<Value
*>(node
);
2227 u
.oid_comps
=new vector
<OID_comp
>();
2230 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2232 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2233 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2236 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2237 v
=dynamic_cast<Value
*>(node
);
2240 u
.oid_comps
=new vector
<OID_comp
>();
2243 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2245 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2246 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2249 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2250 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2253 u
.char_syms
=new CharSyms();
2255 u
.char_syms
->set_my_scope(get_my_scope());
2256 u
.char_syms
->set_fullname(get_fullname());
2259 FATAL_ERROR("Value::set_valuetype()");
2265 if (p_valuetype
== V_USTR
) {
2266 Value
*v_last
= get_value_refd_last();
2267 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2268 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2271 u
.ustr
.convert_str
= true; // will be converted back to string
2272 } else FATAL_ERROR("Value::set_valuetype()");
2275 switch(p_valuetype
) {
2277 const string
& str
= u
.char_syms
->get_string();
2279 set_val_str(new string(str
));
2282 const ustring
& ustr
= u
.char_syms
->get_ustring();
2284 set_val_ustr(new ustring(ustr
));
2285 u
.ustr
.convert_str
= false;
2287 case V_ISO2022STR
: {
2288 const string
& str
= u
.char_syms
->get_iso2022string();
2290 set_val_str(new string(str
));
2293 FATAL_ERROR("Value::set_valuetype()");
2298 if (p_valuetype
== V_REAL
)
2299 val_Real
= u
.val_Int
->to_real();
2300 else FATAL_ERROR("Value::set_valuetype()");
2302 u
.val_Real
= val_Real
;
2305 clean_up_string_elements(u
.str
.str_elements
);
2306 string
*old_str
= u
.str
.val_str
;
2307 switch(p_valuetype
) {
2309 set_val_str(hex2bit(*old_str
));
2312 set_val_str(asn_hex2oct(*old_str
));
2315 FATAL_ERROR("Value::set_valuetype()");
2320 clean_up_string_elements(u
.str
.str_elements
);
2321 if (p_valuetype
== V_OSTR
) {
2322 string
*old_str
= u
.str
.val_str
;
2323 set_val_str(asn_bit2oct(*old_str
));
2325 } else FATAL_ERROR("Value::set_valuetype()");
2328 clean_up_string_elements(u
.str
.str_elements
);
2329 switch(p_valuetype
) {
2331 string
*old_str
= u
.str
.val_str
;
2332 set_val_ustr(new ustring(*old_str
));
2333 u
.ustr
.convert_str
= true; // will be converted back to string
2340 FATAL_ERROR("Value::set_valuetype()");
2341 } // switch p_valuetype
2344 clean_up_string_elements(u
.ustr
.ustr_elements
);
2345 switch(p_valuetype
) {
2347 ustring
*old_str
= u
.ustr
.val_ustr
;
2348 size_t nof_chars
= old_str
->size();
2349 bool warning_flag
= false;
2350 for (size_t i
= 0; i
< nof_chars
; i
++) {
2351 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2352 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2353 error("This string value cannot contain multiple-byte characters, "
2354 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2355 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2357 p_valuetype
= V_ERROR
;
2359 } else if (uchar
.cell
> 127 && !warning_flag
) {
2360 warning("This string value may not contain characters with code "
2361 "higher than 127, but it has character with code %u (0x%02X) "
2362 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2363 warning_flag
= true;
2366 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2370 error("ISO-10646 string value cannot be converted to "
2372 delete u
.ustr
.val_ustr
;
2373 p_valuetype
= V_ERROR
;
2376 FATAL_ERROR("Value::set_valuetype()");
2377 } // switch p_valuetype
2380 switch (p_valuetype
) {
2382 NamedValues
*nvs
= u
.val_nvs
;
2383 if (nvs
->get_nof_nvs() < 1) {
2384 error("Union value must have one active field");
2386 valuetype
= V_ERROR
;
2388 } else if (nvs
->get_nof_nvs() > 1) {
2389 error("Only one field was expected in union value instead of %lu",
2390 (unsigned long) nvs
->get_nof_nvs());
2392 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2393 u
.choice
.alt_name
= nv
->get_name().clone();
2394 u
.choice
.alt_value
= nv
->steal_value();
2401 NamedValues
*nvs
= u
.val_nvs
;
2405 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2406 if (nvs
->has_nv_withName(id_mant
)) {
2407 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2408 ->get_value_refd_last();
2409 if (v_tmp
->get_valuetype() == V_INT
) {
2410 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2411 if (*i_mant_int
> INT_MAX
) {
2412 error("Mantissa `%s' should be less than `%d'",
2413 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2416 i_mant
= i_mant_int
->get_val();
2424 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2425 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2426 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2427 Value
*v_tmp
= v
->get_value_refd_last();
2428 if (v_tmp
->get_valuetype() == V_INT
) {
2429 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2430 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2431 v
->error("Base of the REAL must be 2 or 10");
2434 i_base
= i_base_int
->get_val();
2442 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2443 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2444 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2445 ->get_value_refd_last();
2446 if (v_tmp
->get_valuetype() == V_INT
) {
2447 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2448 if (*i_exp_int
> INT_MAX
) {
2449 error("Exponent `%s' should be less than `%d'",
2450 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2453 i_exp
= i_exp_int
->get_val();
2462 valuetype
= V_ERROR
;
2465 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2466 static_cast<double>(i_exp
));
2469 FATAL_ERROR("Value::set_valuetype()");
2473 switch (p_valuetype
) {
2475 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2476 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2477 Type
*t
= my_governor
->get_type_refd_last();
2478 switch (t
->get_typetype()) {
2483 FATAL_ERROR("Value::set_valuetype()");
2485 Values
*vals
= u
.val_vs
;
2486 size_t nof_vals
= vals
->get_nof_vs();
2487 size_t nof_comps
= t
->get_nof_comps();
2488 if (nof_vals
> nof_comps
) {
2489 error("Too many elements in value list notation for type `%s': "
2490 "%lu was expected instead of %lu",
2491 t
->get_typename().c_str(),
2492 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2496 if (nof_vals
<= nof_comps
) {
2497 upper_limit
= nof_vals
;
2500 upper_limit
= nof_comps
;
2503 u
.val_nvs
= new NamedValues
;
2504 for (size_t i
= 0; i
< upper_limit
; i
++) {
2505 Value
*v
= vals
->steal_v_byIndex(i
);
2506 if (v
->valuetype
!= V_NOTUSED
) {
2510 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2511 nv
->set_location(*v
);
2512 u
.val_nvs
->add_nv(nv
);
2514 u
.val_nvs
->set_my_scope(get_my_scope());
2515 u
.val_nvs
->set_fullname(get_fullname());
2517 if (allnotused
&& nof_vals
> 0)
2518 warning("All elements of value list notation for type `%s' are not "
2519 "used symbols (`-')", t
->get_typename().c_str());
2522 // { } -> empty set value
2523 if (u
.val_vs
->get_nof_vs() != 0)
2524 FATAL_ERROR("Value::set_valuetype()");
2526 u
.val_nvs
= new NamedValues
;
2530 // SEQOF -> SETOF or ARRAY: trivial
2533 FATAL_ERROR("Value::set_valuetype()");
2537 switch (p_valuetype
) {
2538 case V_DEFAULT_NULL
:
2543 FATAL_ERROR("Value::set_valuetype()");
2547 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2548 FATAL_ERROR("Value::set_valuetype()");
2552 FATAL_ERROR("Value::set_valuetype()");
2554 valuetype
=p_valuetype
;
2557 void Value::set_valuetype_COMP_NULL()
2559 if(valuetype
== V_ERROR
) return;
2560 if(valuetype
==V_TTCN3_NULL
) {
2562 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2563 // Nothing to check.
2564 u
.expr
.state
=EXPR_CHECKED
;
2566 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2569 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2571 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2573 u
.val_Int
= new int_val_t(p_val_int
);
2575 } else FATAL_ERROR("Value::set_valuetype()");
2578 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2580 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2584 } else FATAL_ERROR("Value::set_valuetype()");
2587 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2589 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2593 } else FATAL_ERROR("Value::set_valuetype()");
2596 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2598 switch (p_valuetype
) {
2602 if (valuetype
== V_REFER
&& p_ass
) break;
2605 FATAL_ERROR("Value::set_valuetype()");
2609 valuetype
= p_valuetype
;
2612 bool Value::is_undef_lowerid()
2614 switch (valuetype
) {
2615 case V_UNDEF_LOWERID
:
2618 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2619 !u
.expr
.ti1
->get_DerivedRef()) {
2620 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2628 const Identifier
& Value::get_undef_lowerid()
2630 switch (valuetype
) {
2631 case V_UNDEF_LOWERID
:
2634 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2635 FATAL_ERROR("Value::get_undef_lowerid()");
2636 return u
.expr
.ti1
->get_Template()->get_specific_value()
2637 ->get_undef_lowerid();
2639 FATAL_ERROR("Value::get_undef_lowerid()");
2641 const Identifier
*dummy
= 0;
2645 void Value::set_lowerid_to_ref()
2647 switch (valuetype
) {
2648 case V_UNDEF_LOWERID
:
2649 set_valuetype(V_REFD
);
2652 // if the governor of the expression is not known (in log(), etc...)
2653 // then the governor is taken from the reference (using
2654 // v1/ti1->get_expr_governor()), but that runs before the
2655 // params were checked, this smells like a workaround :)
2656 switch (u
.expr
.v_optype
) {
2659 u
.expr
.v1
->set_lowerid_to_ref();
2662 u
.expr
.v1
->set_lowerid_to_ref();
2663 u
.expr
.v2
->set_lowerid_to_ref();
2665 case OPTYPE_VALUEOF
:
2666 case OPTYPE_ISVALUE
:
2667 case OPTYPE_ISBOUND
:
2668 case OPTYPE_ISPRESENT
:
2671 case OPTYPE_REPLACE
:
2672 case OPTYPE_TTCN2STRING
:
2673 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2674 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2675 "In the operand of operation `%s'",
2677 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2679 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2680 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2681 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2682 "In the operand of operation `%s'",
2684 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2687 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2688 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2689 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2690 "In the operand of operation `%s'",
2692 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2705 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2707 switch (valuetype
) {
2715 case V_UNDEF_LOWERID
:
2722 return Type::T_UNDEF
;
2726 FATAL_ERROR("Value::get_expr_returntype()");
2728 return Type::T_ERROR
;
2731 Type
*t
= get_expr_governor(exp_val
);
2732 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2733 else return Type::T_ERROR
; }
2735 return Type::T_FUNCTION
;
2737 return Type::T_ALTSTEP
;
2739 return Type::T_TESTCASE
;
2741 switch(u
.expr
.v_optype
) {
2742 case OPTYPE_COMP_NULL
:
2743 case OPTYPE_COMP_MTC
:
2744 case OPTYPE_COMP_SYSTEM
:
2745 case OPTYPE_COMP_SELF
:
2746 case OPTYPE_COMP_CREATE
:
2747 return Type::T_COMPONENT
;
2748 case OPTYPE_UNDEF_RUNNING
:
2749 case OPTYPE_COMP_RUNNING
:
2750 case OPTYPE_COMP_RUNNING_ANY
:
2751 case OPTYPE_COMP_RUNNING_ALL
:
2752 case OPTYPE_COMP_ALIVE
:
2753 case OPTYPE_COMP_ALIVE_ANY
:
2754 case OPTYPE_COMP_ALIVE_ALL
:
2755 case OPTYPE_TMR_RUNNING
:
2756 case OPTYPE_TMR_RUNNING_ANY
:
2768 case OPTYPE_ISPRESENT
:
2769 case OPTYPE_ISCHOSEN
:
2770 case OPTYPE_ISCHOSEN_V
:
2771 case OPTYPE_ISCHOSEN_T
:
2772 case OPTYPE_ISVALUE
:
2773 case OPTYPE_ISBOUND
:
2774 case OPTYPE_PROF_RUNNING
:
2775 return Type::T_BOOL
;
2776 case OPTYPE_GETVERDICT
:
2777 return Type::T_VERDICT
;
2778 case OPTYPE_VALUEOF
: {
2779 Error_Context
cntxt(this, "In the operand of operation `%s'",
2781 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2782 case OPTYPE_TMR_READ
:
2783 case OPTYPE_INT2FLOAT
:
2784 case OPTYPE_STR2FLOAT
:
2786 case OPTYPE_RNDWITHVAL
:
2787 return Type::T_REAL
;
2788 case OPTYPE_ACTIVATE
:
2789 return Type::T_DEFAULT
;
2790 case OPTYPE_ACTIVATE_REFD
:
2791 return Type::T_DEFAULT
;
2792 case OPTYPE_EXECUTE
:
2793 case OPTYPE_EXECUTE_REFD
:
2794 return Type::T_VERDICT
;
2795 case OPTYPE_UNARYPLUS
: // v1
2796 case OPTYPE_UNARYMINUS
: {
2797 Type::typetype_t tmp_tt
;
2799 Error_Context
cntxt(this, "In the operand of operation `%s'",
2801 u
.expr
.v1
->set_lowerid_to_ref();
2802 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2809 get_value_refd_last(); // to report the error
2810 return Type::T_ERROR
;
2813 case OPTYPE_ADD
: // v1 v2
2814 case OPTYPE_SUBTRACT
:
2815 case OPTYPE_MULTIPLY
:
2816 case OPTYPE_DIVIDE
: {
2817 Type::typetype_t tmp_tt
;
2819 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2821 u
.expr
.v1
->set_lowerid_to_ref();
2822 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2829 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2830 Type::typetype_t tmp_tt2
;
2832 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2834 u
.expr
.v2
->set_lowerid_to_ref();
2835 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2837 Type::typetype_t ret_val
=Type::T_ERROR
;
2838 bool maybeconcat
=false;
2843 if(tmp_tt2
==tmp_tt
) {
2850 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2852 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2853 ret_val
=Type::T_USTR
;
2854 else ret_val
=Type::T_CSTR
;
2861 error("Did you mean the concat operation (`&') instead of"
2862 " addition operator (`+')?");
2863 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2867 get_value_refd_last(); // to report the error
2868 return Type::T_ERROR
;
2871 case OPTYPE_NOT4B
: // v1
2872 case OPTYPE_AND4B
: // v1 v2
2877 Type::typetype_t tmp_tt
;
2879 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
2880 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
2882 u
.expr
.v1
->set_lowerid_to_ref();
2883 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2891 get_value_refd_last(); // to report the error
2892 return Type::T_ERROR
;
2895 case OPTYPE_ROTL
: // v1 v2
2897 Type::typetype_t tmp_tt
;
2899 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
2900 u
.expr
.v_optype
==OPTYPE_ROTL
2901 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
2903 u
.expr
.v1
->set_lowerid_to_ref();
2904 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2917 get_value_refd_last(); // to report the error
2918 return Type::T_ERROR
;
2922 case OPTYPE_REPLACE
: {
2923 Type::typetype_t tmp_tt
;
2925 Error_Context
cntxt(this, "In the operand of operation `%s'",
2927 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2928 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2940 get_value_refd_last(); // to report the error
2941 return Type::T_ERROR
;
2944 case OPTYPE_REGEXP
: {
2945 Type::typetype_t tmp_tt
;
2947 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2949 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2950 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2957 get_value_refd_last(); // to report the error
2958 return Type::T_ERROR
;
2961 case OPTYPE_CONCAT
: { // v1 v2
2962 Type::typetype_t tmp_tt
;
2964 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2966 u
.expr
.v1
->set_lowerid_to_ref();
2967 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2979 get_value_refd_last(); // to report the error
2980 return Type::T_ERROR
;
2985 case OPTYPE_CHAR2INT
:
2986 case OPTYPE_UNICHAR2INT
:
2987 case OPTYPE_BIT2INT
:
2988 case OPTYPE_HEX2INT
:
2989 case OPTYPE_OCT2INT
:
2990 case OPTYPE_STR2INT
:
2991 case OPTYPE_FLOAT2INT
:
2992 case OPTYPE_LENGTHOF
:
2995 case OPTYPE_ENUM2INT
:
2997 case OPTYPE_BIT2STR
:
2998 case OPTYPE_FLOAT2STR
:
2999 case OPTYPE_HEX2STR
:
3000 case OPTYPE_INT2CHAR
:
3001 case OPTYPE_INT2STR
:
3002 case OPTYPE_OCT2CHAR
:
3003 case OPTYPE_OCT2STR
:
3004 case OPTYPE_UNICHAR2CHAR
:
3005 case OPTYPE_LOG2STR
:
3006 case OPTYPE_TESTCASENAME
:
3007 case OPTYPE_TTCN2STRING
:
3008 case OPTYPE_GET_STRINGENCODING
:
3009 case OPTYPE_ENCODE_BASE64
:
3010 return Type::T_CSTR
;
3011 case OPTYPE_INT2UNICHAR
:
3012 case OPTYPE_OCT2UNICHAR
:
3013 return Type::T_USTR
;
3014 case OPTYPE_INT2BIT
:
3015 case OPTYPE_HEX2BIT
:
3016 case OPTYPE_OCT2BIT
:
3017 case OPTYPE_STR2BIT
:
3019 return Type::T_BSTR
;
3020 case OPTYPE_INT2HEX
:
3021 case OPTYPE_BIT2HEX
:
3022 case OPTYPE_OCT2HEX
:
3023 case OPTYPE_STR2HEX
:
3024 return Type::T_HSTR
;
3025 case OPTYPE_INT2OCT
:
3026 case OPTYPE_CHAR2OCT
:
3027 case OPTYPE_HEX2OCT
:
3028 case OPTYPE_BIT2OCT
:
3029 case OPTYPE_STR2OCT
:
3030 case OPTYPE_UNICHAR2OCT
:
3031 case OPTYPE_REMOVE_BOM
:
3032 case OPTYPE_DECODE_BASE64
:
3033 return Type::T_OSTR
;
3037 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3039 return Type::T_ERROR
;
3043 case MACRO_MODULEID
:
3044 case MACRO_FILENAME
:
3045 case MACRO_BFILENAME
:
3046 case MACRO_FILEPATH
:
3047 case MACRO_LINENUMBER
:
3048 case MACRO_DEFINITIONID
:
3050 case MACRO_TESTCASEID
:
3051 return Type::T_CSTR
;
3052 case MACRO_LINENUMBER_C
:
3055 return Type::T_ERROR
;
3058 return Type::T_NULL
;
3060 return Type::T_BOOL
;
3064 return Type::T_REAL
;
3066 return Type::T_ENUM_T
;
3068 return Type::T_BSTR
;
3070 return Type::T_HSTR
;
3072 return Type::T_OSTR
;
3074 return Type::T_CSTR
;
3076 return Type::T_USTR
;
3078 return Type::T_GENERALSTRING
;
3082 return Type::T_ROID
;
3084 return Type::T_VERDICT
;
3085 case V_DEFAULT_NULL
:
3086 return Type::T_DEFAULT
;
3088 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3090 return Type::T_ERROR
;
3094 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3096 if(my_governor
) return my_governor
;
3097 switch (valuetype
) {
3099 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3101 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3102 u
.invoke
.v
->error("A value of type function expected");
3105 t
= t
->get_type_refd_last();
3106 switch(t
->get_typetype()) {
3107 case Type::T_FUNCTION
: {
3108 Type
*t_return_type
= t
->get_function_return_type();
3109 if (!t_return_type
) {
3110 error("Reference to a %s was expected instead of invocation "
3111 "of behavior type `%s' with no return type",
3112 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3113 t
->get_fullname().c_str());
3116 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3117 error("Reference to a value was expected, but functions of type "
3118 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3119 t_return_type
->get_typename().c_str());
3122 return t_return_type
; }
3123 case Type::T_ALTSTEP
:
3126 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3127 t
->get_typename().c_str());
3132 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3134 if (!ass
) goto error
;
3135 switch (ass
->get_asstype()) {
3136 case Assignment::A_CONST
:
3137 case Assignment::A_EXT_CONST
:
3138 case Assignment::A_MODULEPAR
:
3139 case Assignment::A_MODULEPAR_TEMP
:
3140 case Assignment::A_TEMPLATE
:
3141 case Assignment::A_VAR
:
3142 case Assignment::A_VAR_TEMPLATE
:
3143 case Assignment::A_FUNCTION_RVAL
:
3144 case Assignment::A_FUNCTION_RTEMP
:
3145 case Assignment::A_EXT_FUNCTION_RVAL
:
3146 case Assignment::A_EXT_FUNCTION_RTEMP
:
3147 case Assignment::A_PAR_VAL_IN
:
3148 case Assignment::A_PAR_VAL_OUT
:
3149 case Assignment::A_PAR_VAL_INOUT
:
3150 case Assignment::A_PAR_TEMPL_IN
:
3151 case Assignment::A_PAR_TEMPL_OUT
:
3152 case Assignment::A_PAR_TEMPL_INOUT
:
3153 tmp_type
=ass
->get_Type();
3155 case Assignment::A_FUNCTION
:
3156 case Assignment::A_EXT_FUNCTION
:
3157 error("Reference to a %s was expected instead of a call of %s, which "
3158 "does not have return type",
3159 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3160 ass
->get_description().c_str());
3163 error("Reference to a %s was expected instead of %s",
3164 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3165 ass
->get_description().c_str());
3168 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3169 if(!tmp_type
) goto error
;
3172 switch (u
.expr
.v_optype
) {
3173 case OPTYPE_VALUEOF
:
3176 case OPTYPE_REPLACE
:{
3177 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3178 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3179 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3184 return u
.expr
.v1
->get_expr_governor(exp_val
);
3186 return get_expr_governor_v1v2(exp_val
);
3187 case OPTYPE_COMP_MTC
:
3188 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3190 case OPTYPE_COMP_SYSTEM
:
3191 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3193 case OPTYPE_COMP_SELF
:
3195 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3196 if (t_ros
) return t_ros
->get_component_type();
3199 case OPTYPE_COMP_CREATE
:
3200 return chk_expr_operand_comptyperef_create();
3206 return Type::get_pooltype(get_expr_returntype(exp_val
));
3209 set_valuetype(V_ERROR
);
3213 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3215 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3216 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3218 if (v2_gov
) { // both have governors
3219 // return the type that is compatible with both (if there is no type mismatch)
3220 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3223 } else return v1_gov
;
3224 } else { // v1 has no governor
3225 if (v2_gov
) return v2_gov
;
3226 else return NULL
; // neither has governor
3230 Type
*Value::get_expr_governor_last()
3232 Value
*v_last
= get_value_refd_last();
3233 if (v_last
->valuetype
== V_ERROR
) return 0;
3234 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3236 return t
->get_type_refd_last();
3239 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3241 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3242 return u
.invoke
.v
->get_expr_governor(exp_val
);
3245 const char* Value::get_opname() const
3247 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3248 switch(u
.expr
.v_optype
) {
3249 case OPTYPE_RND
: // -
3251 case OPTYPE_COMP_NULL
:
3252 return "(component) null";
3253 case OPTYPE_COMP_MTC
:
3255 case OPTYPE_COMP_SYSTEM
:
3257 case OPTYPE_COMP_SELF
:
3259 case OPTYPE_COMP_RUNNING_ANY
:
3260 return "any component.running";
3261 case OPTYPE_COMP_RUNNING_ALL
:
3262 return "all component.running";
3263 case OPTYPE_COMP_ALIVE_ANY
:
3264 return "any component.alive";
3265 case OPTYPE_COMP_ALIVE_ALL
:
3266 return "all component.alive";
3267 case OPTYPE_TMR_RUNNING_ANY
:
3268 return "any timer.running";
3269 case OPTYPE_GETVERDICT
:
3270 return "getverdict()";
3271 case OPTYPE_TESTCASENAME
:
3272 return "testcasename()";
3273 case OPTYPE_UNARYPLUS
: // v1
3275 case OPTYPE_UNARYMINUS
:
3281 case OPTYPE_BIT2HEX
:
3283 case OPTYPE_BIT2INT
:
3285 case OPTYPE_BIT2OCT
:
3287 case OPTYPE_BIT2STR
:
3289 case OPTYPE_CHAR2INT
:
3290 return "char2int()";
3291 case OPTYPE_CHAR2OCT
:
3292 return "char2oct()";
3293 case OPTYPE_FLOAT2INT
:
3294 return "float2int()";
3295 case OPTYPE_FLOAT2STR
:
3296 return "float2str()";
3297 case OPTYPE_HEX2BIT
:
3299 case OPTYPE_HEX2INT
:
3301 case OPTYPE_HEX2OCT
:
3303 case OPTYPE_HEX2STR
:
3305 case OPTYPE_INT2CHAR
:
3306 return "int2char()";
3307 case OPTYPE_INT2FLOAT
:
3308 return "int2float()";
3309 case OPTYPE_INT2STR
:
3311 case OPTYPE_INT2UNICHAR
:
3312 return "int2unichar()";
3313 case OPTYPE_OCT2BIT
:
3315 case OPTYPE_OCT2CHAR
:
3316 return "oct2char()";
3317 case OPTYPE_OCT2HEX
:
3319 case OPTYPE_OCT2INT
:
3321 case OPTYPE_OCT2STR
:
3323 case OPTYPE_STR2BIT
:
3325 case OPTYPE_STR2FLOAT
:
3326 return "str2float()";
3327 case OPTYPE_STR2HEX
:
3329 case OPTYPE_STR2INT
:
3331 case OPTYPE_STR2OCT
:
3333 case OPTYPE_UNICHAR2INT
:
3334 return "unichar2int()";
3335 case OPTYPE_UNICHAR2CHAR
:
3336 return "unichar2char()";
3337 case OPTYPE_UNICHAR2OCT
:
3338 return "unichar2oct()";
3339 case OPTYPE_ENUM2INT
:
3340 return "enum2int()";
3341 case OPTYPE_LENGTHOF
:
3342 return "lengthof()";
3345 case OPTYPE_RNDWITHVAL
:
3346 return "rnd (seed)";
3348 return "encvalue()";
3350 return "decvalue()";
3351 case OPTYPE_GET_STRINGENCODING
:
3352 return "get_stringencoding()";
3353 case OPTYPE_REMOVE_BOM
:
3354 return "remove_bom()";
3355 case OPTYPE_ENCODE_BASE64
:
3356 return "encode_base64()";
3357 case OPTYPE_DECODE_BASE64
:
3358 return "decode_base64()";
3359 case OPTYPE_ADD
: // v1 v2
3361 case OPTYPE_SUBTRACT
:
3363 case OPTYPE_MULTIPLY
:
3405 case OPTYPE_INT2BIT
:
3407 case OPTYPE_INT2HEX
:
3409 case OPTYPE_INT2OCT
:
3411 case OPTYPE_OCT2UNICHAR
:
3412 return "oct2unichar()";
3419 case OPTYPE_REPLACE
:
3421 case OPTYPE_VALUEOF
: // t1
3423 case OPTYPE_UNDEF_RUNNING
:
3424 return "<timer or component> running";
3425 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3427 case OPTYPE_COMP_RUNNING
: // v1
3428 return "component running";
3429 case OPTYPE_COMP_ALIVE
: // v1
3431 case OPTYPE_TMR_READ
:
3432 return "timer read";
3433 case OPTYPE_TMR_RUNNING
:
3434 return "timer running";
3435 case OPTYPE_ACTIVATE
:
3436 return "activate()";
3437 case OPTYPE_ACTIVATE_REFD
:
3438 return "activate()";
3439 case OPTYPE_EXECUTE
: // r1 [v2]
3440 case OPTYPE_EXECUTE_REFD
:
3442 case OPTYPE_MATCH
: // v1 t2
3444 case OPTYPE_ISPRESENT
:
3445 return "ispresent()";
3446 case OPTYPE_ISCHOSEN
:
3447 case OPTYPE_ISCHOSEN_V
:
3448 case OPTYPE_ISCHOSEN_T
:
3449 return "ischosen()";
3450 case OPTYPE_ISVALUE
:
3452 case OPTYPE_ISBOUND
:
3454 case OPTYPE_LOG2STR
:
3456 case OPTYPE_TTCN2STRING
:
3457 return "ttcn2string()";
3458 case OPTYPE_PROF_RUNNING
:
3459 return "@profiler.running";
3461 FATAL_ERROR("Value::get_opname()");
3465 void Value::chk_expr_ref_ischosen()
3467 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3468 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3469 Assignment
*ass
=tmpref
->get_refd_assignment();
3471 set_valuetype(V_ERROR
);
3474 // Now we know whether the argument of ischosen() is a value or template.
3475 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3476 // or template (OPTYPE_ISCHOSEN_T).
3477 switch (ass
->get_asstype()) {
3478 case Assignment::A_CONST
:
3479 case Assignment::A_EXT_CONST
:
3480 case Assignment::A_MODULEPAR
:
3481 case Assignment::A_VAR
:
3482 case Assignment::A_PAR_VAL_IN
:
3483 case Assignment::A_PAR_VAL_OUT
:
3484 case Assignment::A_PAR_VAL_INOUT
:
3485 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3486 u
.expr
.v1
->set_location(*tmpref
);
3487 u
.expr
.v1
->set_my_scope(get_my_scope());
3488 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3489 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3491 case Assignment::A_MODULEPAR_TEMP
:
3492 case Assignment::A_TEMPLATE
:
3493 case Assignment::A_VAR_TEMPLATE
:
3494 case Assignment::A_PAR_TEMPL_IN
:
3495 case Assignment::A_PAR_TEMPL_OUT
:
3496 case Assignment::A_PAR_TEMPL_INOUT
:
3497 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3498 u
.expr
.t1
->set_location(*tmpref
);
3499 u
.expr
.t1
->set_my_scope(get_my_scope());
3500 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3501 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3504 tmpref
->error("Reference to a value or template was expected instead of "
3505 "%s", ass
->get_description().c_str());
3506 set_valuetype(V_ERROR
);
3511 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3512 Type::expected_value_t exp_val
)
3514 v
->set_lowerid_to_ref(); // can only be reference to enum
3515 Type
*t
= v
->get_expr_governor(exp_val
);
3516 if (v
->valuetype
==V_ERROR
) return;
3518 v
->error("Please use reference to an enumerated value as the operand of "
3519 "operation `%s'", get_opname());
3520 set_valuetype(V_ERROR
);
3523 t
= t
->get_type_refd_last();
3524 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3525 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3526 set_valuetype(V_ERROR
);
3528 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3529 v
->error("The operand of operation `%s' cannot be omit", opname
);
3530 set_valuetype(V_ERROR
);
3534 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3537 const Location
*loc
)
3539 if(tt
==Type::T_BOOL
) return;
3540 if(tt
!=Type::T_ERROR
)
3541 loc
->error("%s operand of operation `%s' should be boolean value",
3543 set_valuetype(V_ERROR
);
3546 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3549 const Location
*loc
)
3551 if(tt
==Type::T_INT
) return;
3552 if(tt
!=Type::T_ERROR
)
3553 loc
->error("%s operand of operation `%s' should be integer value",
3555 set_valuetype(V_ERROR
);
3558 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3561 const Location
*loc
)
3563 if(tt
==Type::T_REAL
) return;
3564 else if(tt
==Type::T_INT
)
3565 loc
->error("%s operand of operation `%s' should be float value."
3566 " Perhaps you missed an int2float() conversion function"
3567 " or `.0' at the end of the number",
3569 else if(tt
!=Type::T_ERROR
)
3570 loc
->error("%s operand of operation `%s' should be float value",
3572 set_valuetype(V_ERROR
);
3575 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3578 const Location
*loc
)
3587 if(tt
!=Type::T_ERROR
)
3588 loc
->error("%s operand of operation `%s' should be integer"
3591 set_valuetype(V_ERROR
);
3594 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3597 const Location
*loc
)
3602 case Type::T_ENUM_T
:
3607 if(tt
!=Type::T_ERROR
)
3608 loc
->error("%s operand of operation `%s' should be integer, float"
3609 " or enumerated value", opnum
, opname
);
3610 set_valuetype(V_ERROR
);
3613 void Value::chk_expr_operandtype_list(Type
* t
,
3616 const Location
*loc
,
3619 if (valuetype
== V_ERROR
) return;
3620 if (t
->get_typetype() == Type::T_ERROR
) {
3621 set_valuetype(V_ERROR
);
3624 if (!t
->is_list_type(allow_array
)) {
3625 loc
->error("%s operand of operation `%s' should be a string, "
3626 "`record of'%s `set of'%s value", opnum
, opname
,
3627 allow_array
? "," : " or", allow_array
? " or array" : "");
3628 set_valuetype(V_ERROR
);
3631 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3632 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3635 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3636 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3637 if (info
.is_subtype_error()) {
3639 if (info
.needs_conversion()) set_needs_conversion();
3641 if (!info
.is_erroneous()) {
3642 error("%s operand of operation `%s' is of type `%s', but a value of "
3643 "type `%s' was expected here", opnum
, opname
,
3644 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3646 error("%s", info
.get_error_str_str().c_str());
3649 if (info
.needs_conversion())
3650 set_needs_conversion();
3654 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3657 const Location
*loc
)
3669 if(tt
!=Type::T_ERROR
)
3670 loc
->error("%s operand of operation `%s' should be string value",
3672 set_valuetype(V_ERROR
);
3675 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3678 const Location
*loc
)
3687 if(tt
!=Type::T_ERROR
)
3688 loc
->error("%s operand of operation `%s' should be (universal)"
3689 " charstring value",
3691 set_valuetype(V_ERROR
);
3694 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3697 const Location
*loc
)
3699 if(tt
==Type::T_CSTR
) return;
3700 if(tt
!=Type::T_ERROR
)
3701 loc
->error("%s operand of operation `%s' should be charstring value",
3703 set_valuetype(V_ERROR
);
3706 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3709 const Location
*loc
)
3719 if(tt
!=Type::T_ERROR
)
3720 loc
->error("%s operand of operation `%s' should be binary string value",
3722 set_valuetype(V_ERROR
);
3725 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3728 const Location
*loc
)
3730 if(tt
==Type::T_BSTR
) return;
3731 if(tt
!=Type::T_ERROR
)
3732 loc
->error("%s operand of operation `%s' should be bitstring value",
3734 set_valuetype(V_ERROR
);
3737 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3740 const Location
*loc
)
3742 if(tt
==Type::T_HSTR
) return;
3743 if(tt
!=Type::T_ERROR
)
3744 loc
->error("%s operand of operation `%s' should be hexstring value",
3746 set_valuetype(V_ERROR
);
3749 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3752 const Location
*loc
)
3754 if(tt
==Type::T_OSTR
) return;
3755 if(tt
!=Type::T_ERROR
)
3756 loc
->error("%s operand of operation `%s' should be octetstring value",
3758 set_valuetype(V_ERROR
);
3761 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3762 Type::typetype_t tt2
,
3765 if(valuetype
==V_ERROR
) return;
3766 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3767 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3768 set_valuetype(V_ERROR
);
3771 if(tt1
==tt2
) return;
3772 error("The operands of operation `%s' should be of same type", opname
);
3773 set_valuetype(V_ERROR
);
3776 /* For predefined functions. */
3777 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3778 Type::typetype_t tt2
,
3783 if(valuetype
==V_ERROR
) return;
3784 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3785 set_valuetype(V_ERROR
);
3788 if(tt1
==tt2
) return;
3789 error("The %s and %s operands of operation `%s' should be of same type",
3790 opnum1
, opnum2
, opname
);
3791 set_valuetype(V_ERROR
);
3794 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3795 Value
*v1
, Value
*v2
,
3800 if (valuetype
== V_ERROR
) return;
3801 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3802 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3803 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3805 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3806 set_valuetype(V_ERROR
);
3809 if (tt1
== Type::T_UNDEF
) {
3810 if (tt2
== Type::T_UNDEF
) {
3811 if (v1
->is_undef_lowerid()) {
3812 if (v2
->is_undef_lowerid()) {
3813 Scope
*scope
= get_my_scope();
3814 Module
*my_mod
= scope
->get_scope_mod();
3815 const Identifier
& id1
= v1
->get_undef_lowerid();
3816 if (scope
->has_ass_withId(id1
)
3817 || my_mod
->has_imported_ass_withId(id1
)) {
3818 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3819 * should examine this situation better, but now I suppose
3820 * the first is ref, not enum. */
3821 v1
->set_lowerid_to_ref();
3824 const Identifier
& id2
= v2
->get_undef_lowerid();
3825 if (scope
->has_ass_withId(id2
)
3826 || my_mod
->has_imported_ass_withId(id2
)) {
3827 v2
->set_lowerid_to_ref();
3831 /* This is perhaps enum-enum, but it has no real
3832 * significance, so this should be an error. */
3834 v1
->set_lowerid_to_ref();
3837 } else if (v2
->is_undef_lowerid()) {
3838 v2
->set_lowerid_to_ref();
3841 error("Cannot determine the type of the operands in operation `%s'",
3843 set_valuetype(V_ERROR
);
3845 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3846 v1
->set_lowerid_to_ref();
3849 /* v1 is something undefined, but not lowerid; v2 has
3850 * returntype (perhaps also governor) */
3852 } else if (tt2
== Type::T_UNDEF
) {
3853 /* but tt1 is not undef */
3854 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3855 v2
->set_lowerid_to_ref();
3858 /* v2 is something undefined, but not lowerid; v1 has
3859 * returntype (perhaps also governor) */
3863 /* Now undef_lower_id's are converted to references, or the other
3864 * value has governor; let's see the governors, if they exist. */
3865 Type
*t1
= v1
->get_expr_governor(exp_val
);
3866 Type
*t2
= v2
->get_expr_governor(exp_val
);
3869 // Both value has governor. Are they compatible? According to 7.1.2
3870 // and C.34 it's required to have the same root types for
3871 // OPTYPE_{CONCAT,REPLACE}.
3872 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
3873 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3874 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
3875 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3876 TypeChain l_chain1
, l_chain2
;
3877 TypeChain r_chain1
, r_chain2
;
3878 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
3879 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
3880 if (!compat_t1
&& !compat_t2
) {
3881 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
3882 // the subtypes don't need to be compatible here
3883 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
3884 error("The operands of operation `%s' should be of compatible "
3885 "types", get_opname());
3886 set_valuetype(V_ERROR
);
3888 if (info1
.needs_conversion() || info2
.needs_conversion()) {
3889 set_needs_conversion(); // Avoid folding.
3894 if (info1
.is_erroneous())
3895 v1
->error("%s", info1
.get_error_str_str().c_str());
3896 else if (info2
.is_erroneous())
3897 v2
->error("%s", info2
.get_error_str_str().c_str());
3898 set_valuetype(V_ERROR
);
3901 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
3902 set_needs_conversion(); // Avoid folding.
3907 v2
->set_my_governor(t1
);
3908 t1
->chk_this_value_ref(v2
);
3909 if (v2
->valuetype
== V_OMIT
) {
3910 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3912 v1
->chk_expr_omit_comparison(exp_val
);
3914 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3916 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3917 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3922 v1
->set_my_governor(t2
);
3923 t2
->chk_this_value_ref(v1
);
3924 if (v1
->valuetype
== V_OMIT
) {
3925 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3927 v2
->chk_expr_omit_comparison(exp_val
);
3929 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3931 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3932 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3936 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3937 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
3938 // Here, it cannot be that both are T_UNDEF.
3939 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3940 error("Please use reference as %s operand of operator `%s'",
3941 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
3942 set_valuetype(V_ERROR
);
3945 // Deny type compatibility if no governors found. The typetype_t must
3946 // be the same. TODO: How can this happen?
3947 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
3948 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
3949 error("The operands of operation `%s' should be of compatible types",
3951 set_valuetype(V_ERROR
);
3956 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
3957 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
3959 if(valuetype
==V_ERROR
) return;
3960 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3961 Assignment
*t_ass
= ref
->get_refd_assignment();
3962 if(!t_ass
) goto error
;
3963 switch(t_ass
->get_asstype()) {
3964 case Assignment::A_TIMER
:
3965 case Assignment::A_PAR_TIMER
:
3966 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
3967 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
3968 chk_expr_dynamic_part(exp_val
, true);
3970 case Assignment::A_CONST
:
3971 case Assignment::A_EXT_CONST
:
3972 case Assignment::A_MODULEPAR
:
3973 case Assignment::A_VAR
:
3974 case Assignment::A_FUNCTION_RVAL
:
3975 case Assignment::A_EXT_FUNCTION_RVAL
:
3976 case Assignment::A_PAR_VAL_IN
:
3977 case Assignment::A_PAR_VAL_OUT
:
3978 case Assignment::A_PAR_VAL_INOUT
: {
3979 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
3980 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
3981 val
->set_my_scope(my_scope
);
3982 val
->set_fullname(u
.expr
.r1
->get_fullname());
3983 val
->set_location(*u
.expr
.r1
);
3985 chk_expr_operand_compref(val
, opnum
, get_opname());
3986 chk_expr_dynamic_part(exp_val
, false);
3989 ref
->error("%s operand of operation `%s' should be timer or"
3990 " component reference instead of %s",
3991 opnum
, opname
, t_ass
->get_description().c_str());
3996 set_valuetype(V_ERROR
);
3999 Type
*Value::chk_expr_operand_comptyperef_create()
4001 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4002 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4003 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4004 if (!t_ass
) goto error
;
4005 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4006 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4007 Type::EXPECTED_DYNAMIC_VALUE
);
4008 if (!t_type
) goto error
;
4009 t_type
= t_type
->get_type_refd_last();
4010 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4012 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4013 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4014 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4015 u
.expr
.r1
->error("Incompatible component types: operation "
4016 "`create' should refer to `%s' instead of "
4018 my_governor_last
->get_typename().c_str(),
4019 t_type
->get_typename().c_str());
4025 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4026 "expected in operation `create' instead of `%s'",
4027 t_type
->get_typename().c_str());
4030 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4031 "instead of %s", t_ass
->get_description().c_str());
4034 set_valuetype(V_ERROR
);
4038 void Value::chk_expr_comptype_compat()
4040 if (valuetype
!= V_EXPR
)
4041 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4042 if (!my_governor
|| !my_scope
) return;
4043 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4044 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4046 switch (u
.expr
.v_optype
) {
4047 case OPTYPE_COMP_MTC
:
4048 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4050 case OPTYPE_COMP_SYSTEM
:
4051 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4053 case OPTYPE_COMP_SELF
: {
4054 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4055 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4058 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4063 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4064 error("Incompatible component types: a component reference of "
4065 "type `%s' was expected, but `%s' has type `%s'",
4066 my_governor_last
->get_typename().c_str(), get_opname(),
4067 t_comptype
->get_typename().c_str());
4068 set_valuetype(V_ERROR
);
4072 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4075 if(valuetype
== V_ERROR
) return;
4076 switch(val
->get_valuetype()) {
4078 Error_Context
cntxt(this, "In `%s' operation", opname
);
4079 Value
*v_last
= val
->get_value_refd_last();
4080 if(!v_last
) goto error
;
4081 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4083 t
= t
->get_type_refd_last();
4084 if(t
->get_typetype() != Type::T_COMPONENT
) {
4085 v_last
->error("%s operand of operation `%s': Type mismatch:"
4086 " component reference was expected instead of `%s'",
4087 opnum
, opname
, t
->get_typename().c_str());
4092 Reference
*ref
= val
->get_reference();
4093 Assignment
*t_ass
= ref
->get_refd_assignment();
4095 if (!t_ass
) goto error
;
4096 switch(t_ass
->get_asstype()) {
4097 case Assignment::A_CONST
:
4098 t_val
= t_ass
->get_Value();
4100 case Assignment::A_EXT_CONST
:
4101 case Assignment::A_MODULEPAR
:
4102 case Assignment::A_VAR
:
4103 case Assignment::A_FUNCTION_RVAL
:
4104 case Assignment::A_EXT_FUNCTION_RVAL
:
4105 case Assignment::A_PAR_VAL_IN
:
4106 case Assignment::A_PAR_VAL_OUT
:
4107 case Assignment::A_PAR_VAL_INOUT
: {
4108 Type
*t_type
=t_ass
->get_Type()
4109 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4110 if(!t_type
) goto error
;
4111 t_type
=t_type
->get_type_refd_last();
4112 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4113 ref
->error("%s operand of operation `%s': Type mismatch:"
4114 " component reference was expected instead of `%s'",
4115 opnum
, opname
, t_type
->get_typename().c_str());
4120 ref
->error("%s operand of operation `%s' should be"
4121 " component reference instead of %s",
4122 opnum
, opname
, t_ass
->get_description().c_str());
4126 ReferenceChain
refch(this, "While searching referenced value");
4127 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4129 t_val
= t_val
->get_value_refd_last();
4130 if (t_val
->valuetype
!= V_EXPR
) return;
4131 switch (t_val
->u
.expr
.v_optype
) {
4132 case OPTYPE_COMP_NULL
:
4133 ref
->error("%s operand of operation `%s' refers to `null' component "
4134 "reference", opnum
, opname
);
4136 case OPTYPE_COMP_MTC
:
4137 ref
->error("%s operand of operation `%s' refers to the component "
4138 "reference of the `mtc'", opnum
, opname
);
4140 case OPTYPE_COMP_SYSTEM
:
4141 ref
->error("%s operand of operation `%s' refers to the component "
4142 "reference of the `system'", opnum
, opname
);
4150 FATAL_ERROR("Value::chk_expr_operand_compref()");
4153 set_valuetype(V_ERROR
);
4156 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4160 if(valuetype
==V_ERROR
) return;
4161 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4162 Assignment
*t_ass
= ref
->get_refd_assignment();
4163 if(!t_ass
) goto error
;
4164 switch(t_ass
->get_asstype()) {
4165 case Assignment::A_TIMER
: {
4166 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4167 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4168 Type::EXPECTED_DYNAMIC_VALUE
);
4169 else if (ref
->get_subrefs()) {
4170 ref
->error("%s operand of operation `%s': "
4171 "Reference to single timer `%s' cannot have field or array "
4172 "sub-references", opnum
, opname
,
4173 t_ass
->get_id().get_dispname().c_str());
4177 case Assignment::A_PAR_TIMER
:
4178 if (ref
->get_subrefs()) {
4179 ref
->error("%s operand of operation `%s': "
4180 "Reference to %s cannot have field or array sub-references",
4181 opnum
, opname
, t_ass
->get_description().c_str());
4186 ref
->error("%s operand of operation `%s' should be timer"
4188 opnum
, opname
, t_ass
->get_description().c_str());
4193 set_valuetype(V_ERROR
);
4196 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4200 if(valuetype
==V_ERROR
) return;
4201 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4202 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4203 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4204 Error_Context
cntxt(this, "In `%s' operation", opname
);
4205 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4208 void Value::chk_expr_operand_activate_refd(Value
*val
,
4209 Ttcn::TemplateInstances
* t_list2
,
4210 Ttcn::ActualParList
*&parlist
,
4214 if(valuetype
==V_ERROR
) return;
4215 Error_Context
cntxt(this, "In `%s' operation", opname
);
4216 Type
*t
= val
->get_expr_governor_last();
4218 switch (t
->get_typetype()) {
4220 set_valuetype(V_ERROR
);
4222 case Type::T_ALTSTEP
: {
4223 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4224 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4228 set_valuetype(V_ERROR
);
4230 parlist
->set_fullname(get_fullname());
4231 parlist
->set_my_scope(get_my_scope());
4232 if (!fp_list
->chk_activate_argument(parlist
,
4233 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4237 error("Reference to an altstep was expected in the argument of "
4238 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4239 set_valuetype(V_ERROR
);
4242 } else set_valuetype(V_ERROR
);
4245 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4249 if(valuetype
==V_ERROR
) return;
4250 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4251 Error_Context
cntxt(this, "In `%s' operation", opname
);
4252 Assignment
*t_ass
= ref
->get_refd_assignment();
4253 bool error_flag
= false;
4255 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4256 ref
->error("Reference to a testcase was expected in the argument "
4257 "instead of %s", t_ass
->get_description().c_str());
4260 } else error_flag
= true;
4262 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4263 Value
*v_last
= val
->get_value_refd_last();
4264 switch (v_last
->valuetype
) {
4266 ttcn3float v_real
= v_last
->get_val_Real();
4268 val
->error("The testcase guard timer has negative value: `%s'",
4269 Real2string(v_real
).c_str());
4280 if (error_flag
) set_valuetype(V_ERROR
);
4283 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4284 Ttcn::TemplateInstances
* t_list2
,
4285 Ttcn::ActualParList
*&parlist
,
4290 if(valuetype
==V_ERROR
) return;
4291 Error_Context
cntxt(this, "In `%s' operation", opname
);
4292 Type
*t
= v1
->get_expr_governor_last();
4294 switch (t
->get_typetype()) {
4296 set_valuetype(V_ERROR
);
4298 case Type::T_TESTCASE
: {
4299 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4300 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4304 set_valuetype(V_ERROR
);
4306 parlist
->set_fullname(get_fullname());
4307 parlist
->set_my_scope(get_my_scope());
4311 v1
->error("Reference to a value of type testcase was expected in the "
4312 "argument of `derefers()' instead of `%s'",
4313 t
->get_typename().c_str());
4314 set_valuetype(V_ERROR
);
4317 } else set_valuetype(V_ERROR
);
4319 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4320 Value
*v_last
= v3
->get_value_refd_last();
4321 switch (v_last
->valuetype
) {
4323 ttcn3float v_real
= v_last
->get_val_Real();
4325 v3
->error("The testcase guard timer has negative value: `%s'",
4326 Real2string(v_real
).c_str());
4327 set_valuetype(V_ERROR
);
4331 set_valuetype(V_ERROR
);
4339 void Value::chk_invoke(Type::expected_value_t exp_val
)
4341 if(valuetype
== V_ERROR
) return;
4342 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4343 if(!u
.invoke
.t_list
) return; //already checked
4344 Error_Context
cntxt(this, "In `apply()' operation");
4345 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4347 set_valuetype(V_ERROR
);
4350 switch (t
->get_typetype()) {
4352 set_valuetype(V_ERROR
);
4354 case Type::T_FUNCTION
:
4357 u
.invoke
.v
->error("A value of type function was expected in the "
4358 "argument instead of `%s'", t
->get_typename().c_str());
4359 set_valuetype(V_ERROR
);
4362 my_scope
->chk_runs_on_clause(t
, *this, "call");
4363 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4364 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4365 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4366 delete u
.invoke
.t_list
;
4367 u
.invoke
.t_list
= 0;
4370 u
.invoke
.ap_list
= 0;
4372 parlist
->set_fullname(get_fullname());
4373 parlist
->set_my_scope(get_my_scope());
4374 u
.invoke
.ap_list
= parlist
;
4377 case Type::EXPECTED_CONSTANT
:
4378 error("An evaluatable constant value was expected instead of operation "
4380 set_valuetype(V_ERROR
);
4382 case Type::EXPECTED_STATIC_VALUE
:
4383 error("A static value was expected instead of operation `apply()'");
4384 set_valuetype(V_ERROR
);
4391 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4392 ReferenceChain
*refch
,
4393 Type::expected_value_t exp_val
)
4395 bool self_ref
= false;
4396 if(valuetype
==V_ERROR
) return;
4397 // Commented out to report more errors :)
4398 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4399 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4400 switch(val
->get_valuetype()) {
4402 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4407 val
->get_value_refd_last(refch
, exp_val
);
4412 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4417 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4418 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4420 bool self_ref
= false;
4422 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4423 ti
->error("Reference to a %s value was expected instead of an in-line "
4424 "modified template",
4425 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4426 set_valuetype(V_ERROR
);
4429 Template
*templ
= ti
->get_Template();
4430 switch (templ
->get_templatetype()) {
4431 case Template::TEMPLATE_REFD
:
4433 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4434 templ
= templ
->get_template_refd_last(refch
);
4435 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4436 set_valuetype(V_ERROR
);
4438 ti
->error("Reference to a %s value was expected instead of %s",
4439 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4440 templ
->get_reference()->get_refd_assignment()
4441 ->get_description().c_str());
4442 set_valuetype(V_ERROR
);
4445 case Template::SPECIFIC_VALUE
: {
4446 Value
*val
= templ
->get_specific_value();
4447 switch (val
->get_valuetype()) {
4449 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4452 val
->get_value_refd_last(refch
, exp_val
);
4456 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4458 case Template::TEMPLATE_ERROR
:
4459 set_valuetype(V_ERROR
);
4468 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4471 if(valuetype
==V_ERROR
) return;
4472 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4473 if(val
->is_unfoldable()) return;
4474 if(*val
->get_val_Int()<0) {
4475 val
->error("%s operand of operation `%s' should not be negative",
4477 set_valuetype(V_ERROR
);
4481 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4484 if(valuetype
==V_ERROR
) return;
4485 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4486 if(val
->is_unfoldable()) return;
4487 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4488 val
->error("%s operand of operation `%s' should be in range 0..127",
4490 set_valuetype(V_ERROR
);
4494 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4497 if(valuetype
==V_ERROR
) return;
4498 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4499 if(val
->is_unfoldable()) return;
4500 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4501 val
->error("%s operand of operation `%s' should be in range"
4502 " 0..2147483647", opnum
, opname
);
4503 set_valuetype(V_ERROR
);
4507 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4510 if(valuetype
==V_ERROR
) return;
4511 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4512 if(val
->is_unfoldable()) return;
4513 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4515 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4517 val
->error("%s operand of operation `%s' should not be zero",
4519 set_valuetype(V_ERROR
);
4523 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4526 if (valuetype
== V_ERROR
) return;
4527 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4528 if (val
->get_expr_returntype() != Type::T_INT
) return;
4529 if (val
->is_unfoldable()) return;
4530 const int_val_t
*val_int
= val
->get_val_Int();
4531 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4532 val
->error("%s operand of operation `%s' should be less than `%d' "
4533 "instead of `%s'", opnum
, opname
, INT_MAX
,
4534 (val_int
->t_str()).c_str());
4535 set_valuetype(V_ERROR
);
4539 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4542 if(valuetype
==V_ERROR
) return;
4543 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4544 if(val
->is_unfoldable()) return;
4545 if(val
->get_val_strlen()!=1) {
4546 val
->error("%s operand of operation `%s' should be of length 1",
4548 set_valuetype(V_ERROR
);
4552 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4555 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4556 Value
*v_last
= val
->get_value_refd_last();
4557 if (v_last
->valuetype
== V_CSTR
) {
4558 size_t len
= v_last
->get_val_strlen();
4560 val
->error("%s operand of operation `%s' should contain even number "
4561 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4562 set_valuetype(V_ERROR
);
4564 } else if (v_last
->valuetype
== V_REFD
) {
4565 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4566 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4567 val
->error("%s operand of operation `%s' should contain even number "
4568 "of characters, but a string element contains 1", opnum
, opname
);
4569 set_valuetype(V_ERROR
);
4574 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4577 if(valuetype
==V_ERROR
) return;
4578 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4579 if(val
->is_unfoldable()) return;
4580 const string
& s
=val
->get_val_str();
4581 for(size_t i
=0; i
<s
.size(); i
++) {
4583 if(!(c
=='0' || c
=='1')) {
4584 val
->error("%s operand of operation `%s' can contain only"
4585 " binary digits (position %lu is `%c')",
4586 opnum
, opname
, (unsigned long) i
, c
);
4587 set_valuetype(V_ERROR
);
4593 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4596 if(valuetype
==V_ERROR
) return;
4597 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4598 if(val
->is_unfoldable()) return;
4599 const string
& s
=val
->get_val_str();
4600 for(size_t i
=0; i
<s
.size(); i
++) {
4602 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4603 val
->error("%s operand of operation `%s' can contain only valid "
4604 "hexadecimal digits (position %lu is `%c')",
4605 opnum
, opname
, (unsigned long) i
, c
);
4606 set_valuetype(V_ERROR
);
4612 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4615 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4616 Value
*v
= val
->get_value_refd_last();
4617 if (v
->valuetype
!= V_OSTR
) return;
4618 const string
& s
= val
->get_val_str();
4619 size_t n_octets
= s
.size() / 2;
4620 for (size_t i
= 0; i
< n_octets
; i
++) {
4622 if (!(c
>= '0' && c
<= '7')) {
4623 val
->error("%s operand of operation `%s' shall consist of octets "
4624 "within the range 00 .. 7F, but the string `%s'O contains octet "
4625 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4627 set_valuetype(V_ERROR
);
4633 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4636 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4637 Value
*v_last
= val
->get_value_refd_last();
4638 if (v_last
->valuetype
!= V_CSTR
) return;
4639 const string
& s
= v_last
->get_val_str();
4640 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4642 // state: expected characters
4643 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4644 // S_FIRST: first digit
4645 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4646 // S_END: trailing whitespace
4647 // S_ERR: error was found, stop
4648 for (size_t i
= 0; i
< s
.size(); i
++) {
4653 if (c
== '+' || c
== '-') state
= S_FIRST
;
4654 else if (c
== '0') state
= S_ZERO
;
4655 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4656 else if (string::is_whitespace(c
)) {
4657 if (state
== S_INITIAL
) {
4658 val
->warning("Leading whitespace was detected and ignored in the "
4659 "operand of operation `%s'", opname
);
4660 state
= S_INITIAL_WS
;
4662 } else state
= S_ERR
;
4665 if (c
== '0') state
= S_ZERO
;
4666 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4670 if (c
>= '0' && c
<= '9') {
4671 val
->warning("Leading zero digit was detected and ignored in the "
4672 "operand of operation `%s'", opname
);
4674 } else if (string::is_whitespace(c
)) state
= S_END
;
4678 if (c
>= '0' && c
<= '9') {}
4679 else if (string::is_whitespace(c
)) state
= S_END
;
4683 if (!string::is_whitespace(c
)) state
= S_ERR
;
4688 if (state
== S_ERR
) {
4689 if (string::is_printable(c
)) {
4690 val
->error("%s operand of operation `%s' should be a string "
4691 "containing a valid integer value, but invalid character `%c' "
4692 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4694 val
->error("%s operand of operation `%s' should be a string "
4695 "containing a valid integer value, but invalid character with "
4696 "character code %u was detected at index %lu", opnum
, opname
, c
,
4699 set_valuetype(V_ERROR
);
4706 val
->error("%s operand of operation `%s' should be a string containing a "
4707 "valid integer value instead of an empty string", opnum
, opname
);
4708 set_valuetype(V_ERROR
);
4711 val
->error("%s operand of operation `%s' should be a string containing a "
4712 "valid integer value, but only a sign character was detected", opnum
,
4714 set_valuetype(V_ERROR
);
4717 val
->warning("Trailing whitespace was detected and ignored in the "
4718 "operand of operation `%s'", opname
);
4725 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4728 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4729 Value
*v_last
= val
->get_value_refd_last();
4730 if (v_last
->valuetype
== V_REFD
) {
4731 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4732 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4733 val
->error("%s operand of operation `%s' should be a string containing "
4734 "a valid float value instead of a string element, which cannot "
4735 "represent a floating point number", opnum
, opname
);
4736 set_valuetype(V_ERROR
);
4739 } else if (v_last
->valuetype
!= V_CSTR
) return;
4740 const string
& s
= v_last
->get_val_str();
4741 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4742 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4744 // state: expected characters
4745 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4746 // leading whitespace
4747 // S_FIRST_M: first digit of integer part in mantissa
4748 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4749 // S_FIRST_F: first digit of fraction
4750 // S_MORE_F: more digits of fraction, E, trailing whitespace
4751 // S_INITIAL_E: +, -, first digit of exponent
4752 // S_FIRST_E: first digit of exponent
4753 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4754 // S_END: trailing whitespace
4755 // S_ERR: error was found, stop
4756 for (size_t i
= 0; i
< s
.size(); i
++) {
4761 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4762 else if (c
== '0') state
= S_ZERO_M
;
4763 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4764 else if (string::is_whitespace(c
)) {
4765 if (state
== S_INITIAL
) {
4766 val
->warning("Leading whitespace was detected and ignored in the "
4767 "operand of operation `%s'", opname
);
4768 state
= S_INITIAL_WS
;
4770 } else state
= S_ERR
;
4773 if (c
== '0') state
= S_ZERO_M
;
4774 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4778 if (c
== '.') state
= S_FIRST_F
;
4779 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4780 else if (c
>= '0' && c
<= '9') {
4781 val
->warning("Leading zero digit was detected and ignored in the "
4782 "mantissa of the operand of operation `%s'", opname
);
4784 } else state
= S_ERR
;
4787 if (c
== '.') state
= S_FIRST_F
;
4788 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4789 else if (c
>= '0' && c
<= '9') {}
4793 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4797 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4798 else if (c
>= '0' && c
<= '9') {}
4799 else if (string::is_whitespace(c
)) state
= S_END
;
4803 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4804 else if (c
== '0') state
= S_ZERO_E
;
4805 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4809 if (c
== '0') state
= S_ZERO_E
;
4810 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4814 if (c
>= '0' && c
<= '9') {
4815 val
->warning("Leading zero digit was detected and ignored in the "
4816 "exponent of the operand of operation `%s'", opname
);
4818 } else if (string::is_whitespace(c
)) state
= S_END
;
4822 if (c
>= '0' && c
<= '9') {}
4823 else if (string::is_whitespace(c
)) state
= S_END
;
4827 if (!string::is_whitespace(c
)) state
= S_ERR
;
4832 if (state
== S_ERR
) {
4833 if (string::is_printable(c
)) {
4834 val
->error("%s operand of operation `%s' should be a string "
4835 "containing a valid float value, but invalid character `%c' "
4836 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4838 val
->error("%s operand of operation `%s' should be a string "
4839 "containing a valid float value, but invalid character with "
4840 "character code %u was detected at index %lu", opnum
, opname
, c
,
4843 set_valuetype(V_ERROR
);
4850 val
->error("%s operand of operation `%s' should be a string containing a "
4851 "valid float value instead of an empty string", opnum
, opname
);
4852 set_valuetype(V_ERROR
);
4855 val
->error("%s operand of operation `%s' should be a string containing a "
4856 "valid float value, but only a sign character was detected", opnum
,
4858 set_valuetype(V_ERROR
);
4862 // HL67862: Missing decimal dot allowed for str2float
4865 // HL67862: Missing fraction part is allowed for str2float
4869 val
->error("%s operand of operation `%s' should be a string containing a "
4870 "valid float value, but the exponent is missing after the `E' sign",
4872 set_valuetype(V_ERROR
);
4875 val
->warning("Trailing whitespace was detected and ignored in the "
4876 "operand of operation `%s'", opname
);
4883 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
4886 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4887 Value
*v
= val
->get_value_refd_last();
4888 if (v
->valuetype
!= V_USTR
) return;
4889 const ustring
& us
= v
->get_val_ustr();
4890 for (size_t i
= 0; i
< us
.size(); i
++) {
4891 const ustring::universal_char
& uchar
= us
[i
];
4892 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
4894 val
->error("%s operand of operation `%s' shall consist of characters "
4895 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4896 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4897 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
4898 uchar
.row
, uchar
.cell
, (unsigned long) i
);
4899 set_valuetype(V_ERROR
);
4905 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
4908 if(valuetype
==V_ERROR
) return;
4909 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4910 if(val
->is_unfoldable()) return;
4911 const string
& bstr
=val
->get_val_str();
4912 // see also PredefFunc.cc::bit2int()
4913 size_t nof_bits
= bstr
.size();
4914 // skip the leading zeros
4915 size_t start_index
= 0;
4916 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
4917 // check whether the remaining bits fit in Int
4918 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
4919 val
->error("%s operand of operation `%s' is too large (maximum number"
4920 " of bits in integer is %lu)",
4921 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4922 set_valuetype(V_ERROR
);
4926 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
4929 if(valuetype
==V_ERROR
) return;
4930 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4931 if(val
->is_unfoldable()) return;
4932 const string
& hstr
=val
->get_val_str();
4933 // see also PredefFunc.cc::hex2int()
4934 size_t nof_digits
= hstr
.size();
4935 // skip the leading zeros
4936 size_t start_index
= 0;
4937 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
4938 // check whether the remaining hex digits fit in Int
4939 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
4940 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
4941 char_to_hexdigit(hstr
[start_index
]) > 7)) {
4942 val
->error("%s operand of operation `%s' is too large (maximum number"
4943 " of bits in integer is %lu)",
4944 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4945 set_valuetype(V_ERROR
);
4949 void Value::chk_expr_operands_int2binstr()
4951 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4952 if (u
.expr
.v1
->is_unfoldable()) return;
4953 if (u
.expr
.v2
->is_unfoldable()) return;
4954 // It is already checked that i1 and i2 are non-negative.
4955 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4956 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
4957 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
4958 if (!i2
->is_native()) {
4959 u
.expr
.v2
->error("The length of the resulting string is too large for "
4960 "being represented in memory");
4961 set_valuetype(V_ERROR
);
4964 Int nof_bits
= i2
->get_val();
4965 if (u
.expr
.v1
->is_unfoldable()) return;
4966 switch (u
.expr
.v_optype
) {
4967 case OPTYPE_INT2BIT
:
4969 case OPTYPE_INT2HEX
:
4972 case OPTYPE_INT2OCT
:
4976 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4978 if (*i1
>> nof_bits
> 0) { // Expensive?
4979 u
.expr
.v1
->error("Value %s does not fit in length %s",
4980 i1
->t_str().c_str(), i2
->t_str().c_str());
4981 set_valuetype(V_ERROR
);
4985 void Value::chk_expr_operands_str_samelen()
4987 if(valuetype
==V_ERROR
) return;
4988 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4989 Value
*v1
=u
.expr
.v1
;
4990 if(v1
->is_unfoldable()) return;
4991 Value
*v2
=u
.expr
.v2
;
4992 if(v2
->is_unfoldable()) return;
4993 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4994 size_t i1
=v1
->get_val_strlen();
4995 size_t i2
=v2
->get_val_strlen();
4997 error("The operands should have the same length");
4998 set_valuetype(V_ERROR
);
5002 void Value::chk_expr_operands_replace()
5004 // The fourth operand doesn't need to be checked at all here.
5005 if(valuetype
==V_ERROR
) return;
5006 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5007 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5010 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5011 size_t list_len
= 0;
5012 bool list_len_known
= false;
5013 if (v1
->valuetype
== V_REFD
) {
5014 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5015 if (subrefs
&& subrefs
->refers_to_string_element()) {
5016 warning("Replacing a string element does not make any sense");
5018 list_len_known
= true;
5021 if (!v1
->is_unfoldable()) {
5022 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5023 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5024 list_len_known
= true;
5026 if (!list_len_known
) return;
5027 if (u
.expr
.v2
->is_unfoldable()) {
5028 if (!u
.expr
.v3
->is_unfoldable()) {
5029 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5030 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5031 error("Third operand `len' (%s) is greater than the length of "
5032 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5033 (unsigned long)list_len
);
5034 set_valuetype(V_ERROR
);
5038 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5039 if (u
.expr
.v3
->is_unfoldable()) {
5040 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5041 error("Second operand `index' (%s) is greater than the length of "
5042 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5043 (unsigned long)list_len
);
5044 set_valuetype(V_ERROR
);
5047 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5048 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5049 error("The sum of second operand `index' (%s) and third operand "
5050 "`len' (%s) is greater than the length of the first operand (%lu)",
5051 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5052 (unsigned long)list_len
);
5053 set_valuetype(V_ERROR
);
5059 void Value::chk_expr_operands_substr()
5061 if(valuetype
==V_ERROR
) return;
5062 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5063 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5066 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5067 size_t list_len
= 0;
5068 bool list_len_known
= false;
5069 if (v1
->valuetype
== V_REFD
) {
5070 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5071 if (subrefs
&& subrefs
->refers_to_string_element()) {
5072 warning("Taking the substring of a string element does not make any "
5075 list_len_known
= true;
5078 if (!list_len_known
&& !v1
->is_unfoldable()) {
5079 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5080 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5081 list_len_known
= true;
5083 // Do nothing if the length of the first operand is unknown.
5084 if (!list_len_known
) return;
5085 if (u
.expr
.v2
->is_unfoldable()) {
5086 if (!u
.expr
.v3
->is_unfoldable()) {
5087 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5088 // Only the third operand is known.
5089 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5090 error("Third operand `returncount' (%s) is greater than the "
5091 "length of the first operand (%lu)",
5092 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5093 set_valuetype(V_ERROR
);
5097 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5098 if (u
.expr
.v3
->is_unfoldable()) {
5099 // Only the second operand is known.
5100 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5101 error("Second operand `index' (%s) is greater than the length "
5102 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5103 (unsigned long)list_len
);
5104 set_valuetype(V_ERROR
);
5107 // Both second and third operands are known.
5108 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5109 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5110 error("The sum of second operand `index' (%s) and third operand "
5111 "`returncount' (%s) is greater than the length of the first operand "
5112 "(%lu)", (index_int_2
->t_str()).c_str(),
5113 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5114 set_valuetype(V_ERROR
);
5120 void Value::chk_expr_operands_regexp()
5122 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5123 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5124 Value
* v2
= u
.expr
.t2
->get_specific_value();
5125 if (!v1
|| !v2
) return;
5127 Error_Context
cntxt(this, "In operation `regexp()'");
5128 Value
* v1_last
= v1
->get_value_refd_last();
5129 if (v1_last
->valuetype
== V_CSTR
) {
5130 // the input string is available at compile time
5131 const string
& instr
= v1_last
->get_val_str();
5132 const char *input_str
= instr
.c_str();
5133 size_t instr_len
= strlen(input_str
);
5134 if (instr_len
< instr
.size()) {
5135 v1
->warning("The first operand of `regexp()' contains a "
5136 "character with character code zero at index %s. The rest of the "
5137 "string will be ignored during matching",
5138 Int2string(instr_len
).c_str());
5142 size_t nof_groups
= 0;
5143 Value
*v2_last
= v2
->get_value_refd_last();
5145 if (v2_last
->valuetype
== V_CSTR
) {
5146 // the pattern is available at compile time
5147 const string
& expression
= v2_last
->get_val_str();
5148 const char *pattern_str
= expression
.c_str();
5149 size_t pattern_len
= strlen(pattern_str
);
5150 if (pattern_len
< expression
.size()) {
5151 v2
->warning("The second operand of `regexp()' contains a "
5152 "character with character code zero at index %s. The rest of the "
5153 "string will be ignored during matching",
5154 Int2string(pattern_len
).c_str());
5158 Error_Context
cntxt2(v2
, "In character string pattern");
5159 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5161 if (posix_str
!= NULL
) {
5162 regex_t posix_regexp
;
5163 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5166 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5167 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5168 "regcomp() failed: %s", msg
);
5170 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5172 v2
->error("The character pattern in the second operand of "
5173 "`regexp()' does not contain any groups");
5174 set_valuetype(V_ERROR
);
5176 regfree(&posix_regexp
);
5179 // the pattern is faulty
5180 // the error has been reported by TTCN_pattern_to_regexp
5181 set_valuetype(V_ERROR
);
5184 if (nof_groups
> 0) {
5185 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5186 if (v3
->valuetype
== V_INT
) {
5187 // the group number is available at compile time
5188 const int_val_t
*groupno_int
= v3
->get_val_Int();
5189 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5190 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5191 "large: The requested group index is %s, but the pattern "
5192 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5193 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5194 set_valuetype(V_ERROR
);
5200 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5201 Type::expected_value_t exp_val
)
5203 const char *opname
= get_opname();
5204 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5206 const Location
*loc
;
5207 bool error_flag
= false;
5208 switch (u
.expr
.v_optype
) {
5209 case OPTYPE_ISCHOSEN_V
:
5210 // u.expr.v1 is always a referenced value
5211 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5213 u
.expr
.v1
->set_my_governor(t_governor
);
5214 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5215 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5216 } else error_flag
= true;
5219 case OPTYPE_ISCHOSEN_T
:
5220 // u.expr.t1 is always a referenced template
5221 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5222 exp_val
= Type::EXPECTED_TEMPLATE
;
5223 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5225 u
.expr
.t1
->set_my_governor(t_governor
);
5227 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5229 u
.expr
.t1
->get_template_refd_last(refch
);
5230 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5232 } else error_flag
= true;
5233 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5234 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5235 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5236 u
.expr
.t1
->get_reference()->get_refd_assignment()
5237 ->get_description().c_str());
5243 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5248 t_governor
= t_governor
->get_type_refd_last();
5249 switch (t_governor
->get_typetype()) {
5253 case Type::T_CHOICE_A
:
5254 case Type::T_CHOICE_T
:
5255 case Type::T_ANYTYPE
:
5256 case Type::T_OPENTYPE
:
5257 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5258 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5259 "%s does not have a field named `%s'" :
5260 "Union type `%s' does not have a field named `%s'",
5261 t_governor
->get_typename().c_str(),
5262 u
.expr
.i2
->get_dispname().c_str());
5267 loc
->error("The operand of operation `%s' should be a union value "
5268 "or template instead of `%s'", opname
,
5269 t_governor
->get_typename().c_str());
5274 if (error_flag
) set_valuetype(V_ERROR
);
5277 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5278 Type::expected_value_t exp_val
) {
5280 Error_Context
cntxt(this, "In the parameter of encvalue()");
5281 Type
t_chk(Type::T_ERROR
);
5284 Type::expected_value_t ti_exp_val
= exp_val
;
5285 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5286 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5288 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5290 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5291 if (valuetype
!=V_ERROR
)
5292 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5293 t_type
= t_type
->get_type_refd_last();
5295 error("Cannot determine type of value");
5300 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5301 error("Expecting a value of a type with coding attributes in first"
5302 "parameter of encvalue() which belongs to a generic type '%s'",
5303 t_type->get_typename().c_str());
5307 if(!disable_attribute_validation()) {
5308 t_type
->chk_coding(true);
5311 switch (t_type
->get_typetype()) {
5316 case Type::T_REFDSPEC
:
5317 case Type::T_SELTYPE
:
5318 case Type::T_VERDICT
:
5320 case Type::T_COMPONENT
:
5321 case Type::T_DEFAULT
:
5322 case Type::T_SIGNATURE
:
5323 case Type::T_FUNCTION
:
5324 case Type::T_ALTSTEP
:
5325 case Type::T_TESTCASE
:
5326 error("Type of parameter of encvalue() cannot be '%s'",
5327 t_type
->get_typename().c_str());
5334 set_valuetype(V_ERROR
);
5337 void Value::chk_expr_operands_decode()
5339 Error_Context
cntxt(this, "In the parameters of decvalue()");
5340 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5341 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5343 Assignment
* t_ass
= ref
->get_refd_assignment();
5346 error("Could not determine the assignment for first parameter");
5349 switch (t_ass
->get_asstype()) {
5350 case Assignment::A_PAR_VAL_IN
:
5351 t_ass
->use_as_lvalue(*this);
5353 case Assignment::A_CONST
:
5354 case Assignment::A_EXT_CONST
:
5355 case Assignment::A_MODULEPAR
:
5356 case Assignment::A_MODULEPAR_TEMP
:
5357 case Assignment::A_TEMPLATE
:
5358 ref
->error("Reference to '%s' cannot be used as the first operand of "
5359 "the 'decvalue' operation", t_ass
->get_assname());
5362 case Assignment::A_VAR
:
5363 case Assignment::A_PAR_VAL_OUT
:
5364 case Assignment::A_PAR_VAL_INOUT
:
5366 case Assignment::A_VAR_TEMPLATE
:
5367 case Assignment::A_PAR_TEMPL_IN
:
5368 case Assignment::A_PAR_TEMPL_OUT
:
5369 case Assignment::A_PAR_TEMPL_INOUT
: {
5370 Template
* t
= new Template(ref
->clone());
5371 t
->set_location(*ref
);
5372 t
->set_my_scope(get_my_scope());
5373 t
->set_fullname(get_fullname()+".<operand>");
5374 Template
* t_last
= t
->get_template_refd_last();
5375 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5377 ref
->error("Specific value template was expected instead of '%s'.",
5378 t
->get_template_refd_last()->get_templatetype_str());
5385 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5388 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5389 Type::EXPECTED_DYNAMIC_VALUE
);
5393 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5394 error("First parameter has to be a bitstring");
5399 t_subrefs
= ref
->get_subrefs();
5400 t_ass
= ref
->get_refd_assignment();
5403 error("Could not determine the assignment for second parameter");
5406 // Extra check for HM59355.
5407 switch (t_ass
->get_asstype()) {
5408 case Assignment::A_VAR
:
5409 case Assignment::A_PAR_VAL_IN
:
5410 case Assignment::A_PAR_VAL_OUT
:
5411 case Assignment::A_PAR_VAL_INOUT
:
5414 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5417 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5418 Type::EXPECTED_DYNAMIC_VALUE
);
5422 t_type
= t_type
->get_type_refd_last();
5423 switch (t_type
->get_typetype()) {
5428 case Type::T_REFDSPEC
:
5429 case Type::T_SELTYPE
:
5430 case Type::T_VERDICT
:
5432 case Type::T_COMPONENT
:
5433 case Type::T_DEFAULT
:
5434 case Type::T_SIGNATURE
:
5435 case Type::T_FUNCTION
:
5436 case Type::T_ALTSTEP
:
5437 case Type::T_TESTCASE
:
5438 error("Type of second parameter cannot be %s",
5439 t_type
->get_typename().c_str());
5445 if(!disable_attribute_validation()) {
5446 t_type
->chk_coding(false);
5451 set_valuetype(V_ERROR
);
5454 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5456 Ttcn::FieldOrArrayRefs
*subrefs
;
5457 Identifier
*field_id
= 0;
5460 if (valuetype
== V_ERROR
) return;
5461 else if (valuetype
!= V_REFD
) {
5462 error("Only a referenced value can be compared with `omit'");
5465 subrefs
= u
.ref
.ref
->get_subrefs();
5466 if (subrefs
) field_id
= subrefs
->remove_last_field();
5468 error("Only a reference pointing to an optional record or set field "
5469 "can be compared with `omit'");
5472 t_ass
= u
.ref
.ref
->get_refd_assignment();
5473 if (!t_ass
) goto error
;
5474 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5475 if (!t_type
) goto error
;
5476 t_type
= t_type
->get_type_refd_last();
5477 switch (t_type
->get_typetype()) {
5486 error("Only a reference pointing to an optional field of a record"
5487 " or set type can be compared with `omit'");
5490 if (!t_type
->has_comp_withName(*field_id
)) {
5491 error("Type `%s' does not have field named `%s'",
5492 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5494 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5495 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5496 "`omit'", field_id
->get_dispname().c_str(),
5497 t_type
->get_typename().c_str());
5500 // putting the last field_id back to subrefs
5501 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5504 set_valuetype(V_ERROR
);
5508 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5509 Type::expected_value_t exp_val
)
5511 if(valuetype
==V_ERROR
) return -1;
5512 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5513 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5514 exp_val
=Type::EXPECTED_TEMPLATE
;
5516 Error_Context
cntxt(this, "In the operand of"
5517 " operation `%s'", get_opname());
5520 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5523 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5526 t_templ
= t_templ
->get_template_refd_last(refch
);
5528 // Timer and port arrays are handled separately
5529 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5530 Value
* val
= t_templ
->get_specific_value();
5531 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5532 val
->set_lowerid_to_ref();
5534 if (val
&& val
->get_valuetype() == V_REFD
) {
5535 Reference
* ref
= val
->get_reference();
5536 Assignment
* t_ass
= ref
->get_refd_assignment();
5537 Common::Assignment::asstype_t asstype
=
5538 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5539 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5540 if (t_ass
->get_Dimensions()) {
5541 // here we have a timer or port array
5542 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5543 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5544 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5545 Type::EXPECTED_DYNAMIC_VALUE
);
5548 refd_dim
= t_subrefs
->get_nof_refs();
5549 size_t nof_dims
= t_dims
->get_nof_dims();
5550 if (refd_dim
>= nof_dims
) {
5551 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5552 t_ass
->get_assname());
5553 set_valuetype(V_ERROR
);
5556 } else refd_dim
= 0;
5557 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5559 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5560 t_ass
->get_description().c_str());
5561 set_valuetype(V_ERROR
);
5570 Assignment
* t_ass
= 0;
5572 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5573 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5575 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5576 t_type
= t_type
->get_type_refd_last();
5578 error("Cannot determine type of value");
5582 if(valuetype
==V_ERROR
) return -1;
5584 t_templ
= t_templ
->get_template_refd_last(refch
);
5585 switch(t_templ
->get_templatetype()) {
5586 case Template::TEMPLATE_ERROR
:
5588 case Template::INDEXED_TEMPLATE_LIST
:
5590 case Template::TEMPLATE_REFD
:
5591 case Template::TEMPLATE_LIST
:
5592 case Template::NAMED_TEMPLATE_LIST
:
5595 case Template::SPECIFIC_VALUE
:
5597 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5599 switch(t_val
->get_valuetype()) {
5609 ref
= t_val
->get_reference();
5610 t_ass
= ref
->get_refd_assignment();
5611 t_subrefs
= ref
->get_subrefs();
5615 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5616 t_val
->create_stringRepr().c_str());
5623 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5624 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5629 switch(t_ass
->get_asstype()) {
5630 case Assignment::A_ERROR
:
5632 case Assignment::A_CONST
:
5633 t_val
= t_ass
->get_Value();
5635 case Assignment::A_EXT_CONST
:
5636 case Assignment::A_MODULEPAR
:
5637 case Assignment::A_MODULEPAR_TEMP
:
5638 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5639 u
.expr
.ti1
->error("Reference to an (evaluatable) constant value was "
5640 "expected instead of %s", t_ass
->get_description().c_str());
5644 case Assignment::A_VAR
:
5645 case Assignment::A_PAR_VAL_IN
:
5646 case Assignment::A_PAR_VAL_OUT
:
5647 case Assignment::A_PAR_VAL_INOUT
:
5649 case Type::EXPECTED_CONSTANT
:
5650 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5651 t_ass
->get_description().c_str());
5654 case Type::EXPECTED_STATIC_VALUE
:
5655 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5656 t_ass
->get_description().c_str());
5663 case Assignment::A_TEMPLATE
:
5664 t_templ
= t_ass
->get_Template();
5666 case Assignment::A_VAR_TEMPLATE
:
5667 case Assignment::A_PAR_TEMPL_IN
:
5668 case Assignment::A_PAR_TEMPL_OUT
:
5669 case Assignment::A_PAR_TEMPL_INOUT
:
5670 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5671 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5672 t_ass
->get_description().c_str());
5675 case Assignment::A_FUNCTION_RVAL
:
5676 case Assignment::A_EXT_FUNCTION_RVAL
:
5678 case Type::EXPECTED_CONSTANT
:
5679 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5680 "the return value of %s", t_ass
->get_description().c_str());
5683 case Type::EXPECTED_STATIC_VALUE
:
5684 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5685 "the return value of %s", t_ass
->get_description().c_str());
5692 case Assignment::A_FUNCTION_RTEMP
:
5693 case Assignment::A_EXT_FUNCTION_RTEMP
:
5694 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5695 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5696 " of %s, which returns a template",
5697 t_ass
->get_description().c_str());
5700 case Assignment::A_TIMER
:
5701 case Assignment::A_PORT
:
5702 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5703 // sizeof is applicable to timer and port arrays
5704 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5706 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5707 t_ass
->get_description().c_str());
5710 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5711 Type::EXPECTED_DYNAMIC_VALUE
);
5714 refd_dim
= t_subrefs
->get_nof_refs();
5715 size_t nof_dims
= t_dims
->get_nof_dims();
5716 if (refd_dim
> nof_dims
) goto error
;
5717 else if (refd_dim
== nof_dims
) {
5718 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5719 t_ass
->get_assname());
5722 } else refd_dim
= 0;
5723 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5727 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5728 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5729 t_ass
->get_description().c_str());
5733 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5734 if (!t_type
) goto error
;
5735 t_type
= t_type
->get_type_refd_last();
5737 switch(t_type
->get_typetype()) {
5754 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5755 " set, set of, objid or array was expected");
5760 // check for index overflows in subrefs if possible
5762 switch (t_val
->get_valuetype()) {
5766 if (t_val
->is_indexed()) {
5773 /* The reference points to a constant. */
5774 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5775 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5776 if (!t_val
) goto error
;
5777 t_val
=t_val
->get_value_refd_last(refch
);
5778 } else { t_val
= 0; }
5779 } else if (t_templ
) {
5780 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5781 time. Don't try to evaluate it at compile time. */
5782 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5784 /* The reference points to a static template. */
5785 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5786 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5787 if (!t_templ
) goto error
;
5788 t_templ
= t_templ
->get_template_refd_last(refch
);
5789 } else { t_templ
= 0; }
5792 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5794 switch(t_templ
->get_templatetype()) {
5795 case Template::TEMPLATE_ERROR
:
5797 case Template::TEMPLATE_REFD
:
5801 case Template::SPECIFIC_VALUE
:
5802 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5805 case Template::TEMPLATE_LIST
:
5806 case Template::NAMED_TEMPLATE_LIST
:
5809 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5810 t_templ
->get_templatetype_str(),
5811 t_templ
->get_fullname().c_str());
5816 switch(t_val
->get_valuetype()) {
5827 // error is already reported
5836 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5837 result
= t_type
->get_dimension()->get_size();
5839 else if(t_templ
) { // sizeof()
5840 switch(t_templ
->get_templatetype()) {
5841 case Template::TEMPLATE_LIST
:
5842 if(t_templ
->temps_contains_anyornone_symbol()) {
5843 if(t_templ
->is_length_restricted()) {
5844 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5845 if (lr
->get_is_range()) {
5846 Value
*v_upper
= lr
->get_upper_value();
5848 if (v_upper
->valuetype
== V_INT
) {
5850 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
5851 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
5854 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5855 "templates without exact size");
5860 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5861 "templates containing `*' without upper boundary in the "
5862 "length restriction");
5866 Value
*v_single
= lr
->get_single_value();
5867 if (v_single
->valuetype
== V_INT
)
5868 result
= v_single
->u
.val_Int
->get_val();
5871 else { // not length restricted
5872 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
5873 " containing `*' without length restriction");
5877 else result
=t_templ
->get_nof_listitems();
5879 case Template::NAMED_TEMPLATE_LIST
:
5881 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
5882 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
5883 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
5886 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5890 switch(t_val
->get_valuetype()) {
5897 result
=t_val
->get_nof_comps();
5902 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
5903 if(t_val
->get_se_comp_byIndex(i
)->get_value()
5904 ->get_valuetype()!=V_OMIT
) result
++;
5908 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5914 set_valuetype(V_ERROR
);
5918 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
5920 Type
*governor
= ti
->get_expr_governor(exp_val
);
5922 ti
->get_Template()->set_lowerid_to_ref();
5923 governor
= ti
->get_expr_governor(exp_val
);
5927 ti
->append_stringRepr( str
);
5928 ti
->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5929 "If type is known, use valuof(<type>: %s) as argument.",
5930 str
.c_str(), get_opname(), str
.c_str());
5931 set_valuetype(V_ERROR
);
5936 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
5939 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5940 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
5941 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
5942 Type::EXPECTED_TEMPLATE
: exp_val
);
5944 Template
*t_temp
= u
.expr
.t2
->get_Template();
5945 if (t_temp
->is_undef_lowerid()) {
5946 // We convert the template to reference first even if the value is also
5947 // an undef lowerid. The user can prevent this by explicit type
5949 t_temp
->set_lowerid_to_ref();
5951 } else if (u
.expr
.v1
->is_undef_lowerid()) {
5952 u
.expr
.v1
->set_lowerid_to_ref();
5957 error("Cannot determine the type of arguments in `match()' operation");
5958 set_valuetype(V_ERROR
);
5961 u
.expr
.v1
->set_my_governor(governor
);
5963 Error_Context
cntxt(this, "In the first argument of `match()'"
5965 governor
->chk_this_value_ref(u
.expr
.v1
);
5966 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
5967 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
5970 Error_Context
cntxt(this, "In the second argument of `match()' "
5972 u
.expr
.t2
->chk(governor
);
5976 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
5977 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
5979 Ttcn::StatementBlock
*my_sb
;
5981 case Type::EXPECTED_CONSTANT
:
5982 error("An evaluatable constant value was expected instead of operation "
5983 "`%s'", get_opname());
5985 case Type::EXPECTED_STATIC_VALUE
:
5986 error("A static value was expected instead of operation `%s'",
5992 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5993 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
5995 error("Operation `%s' is allowed only within statements",
5999 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6000 error("Operation `%s' is not allowed in the control part",
6004 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6005 error("Operation `%s' cannot be used in a definition that has "
6006 "`runs on' clause", get_opname());
6009 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6010 error("Operation `%s' can be used only in a definition that has "
6011 "`runs on' clause", get_opname());
6016 set_valuetype(V_ERROR
);
6019 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6021 if(valuetype
==V_ERROR
) return;
6022 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6023 if(v
->is_unfoldable()) return;
6024 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6025 ttcn3float r
= v
->get_val_Real();
6026 if (isSpecialFloatValue(r
)) {
6027 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6028 opnum
, opname
, Real2string(r
).c_str());
6029 set_valuetype(V_ERROR
);
6033 void Value::chk_expr_operands(ReferenceChain
*refch
,
6034 Type::expected_value_t exp_val
)
6036 const char *first
="First", *second
="Second", *third
="Third",
6037 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6038 Value
*v1
, *v2
, *v3
;
6039 Type::typetype_t tt1
, tt2
, tt3
;
6040 Type
t_chk(Type::T_ERROR
);
6042 const char *opname
=get_opname();
6044 // first classify the unchecked ischosen() operation
6045 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6047 switch (u
.expr
.v_optype
) {
6048 case OPTYPE_COMP_NULL
:
6049 case OPTYPE_TESTCASENAME
:
6050 case OPTYPE_PROF_RUNNING
:
6052 case OPTYPE_COMP_MTC
:
6053 case OPTYPE_COMP_SYSTEM
:
6054 chk_expr_comptype_compat();
6056 case OPTYPE_RND
: // -
6057 case OPTYPE_TMR_RUNNING_ANY
:
6058 chk_expr_dynamic_part(exp_val
, true);
6060 case OPTYPE_COMP_RUNNING_ANY
:
6061 case OPTYPE_COMP_RUNNING_ALL
:
6062 case OPTYPE_COMP_ALIVE_ANY
:
6063 case OPTYPE_COMP_ALIVE_ALL
:
6064 case OPTYPE_GETVERDICT
:
6065 chk_expr_dynamic_part(exp_val
, false);
6067 case OPTYPE_COMP_SELF
:
6068 chk_expr_comptype_compat();
6069 chk_expr_dynamic_part(exp_val
, false, true, false);
6071 case OPTYPE_UNARYPLUS
: // v1
6072 case OPTYPE_UNARYMINUS
:
6075 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6076 v1
->set_lowerid_to_ref();
6077 tt1
=v1
->get_expr_returntype(exp_val
);
6078 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6079 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6085 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6086 v1
->set_lowerid_to_ref();
6087 tt1
=v1
->get_expr_returntype(exp_val
);
6088 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6089 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6095 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6096 v1
->set_lowerid_to_ref();
6097 tt1
=v1
->get_expr_returntype(exp_val
);
6098 chk_expr_operandtype_binstr(tt1
, the
, opname
, v1
);
6099 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6102 case OPTYPE_BIT2HEX
:
6103 case OPTYPE_BIT2OCT
:
6104 case OPTYPE_BIT2STR
:
6107 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6108 v1
->set_lowerid_to_ref();
6109 tt1
=v1
->get_expr_returntype(exp_val
);
6110 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6111 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6114 case OPTYPE_BIT2INT
:
6117 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6118 v1
->set_lowerid_to_ref();
6119 tt1
=v1
->get_expr_returntype(exp_val
);
6120 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6121 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6122 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6125 case OPTYPE_CHAR2INT
:
6128 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6129 v1
->set_lowerid_to_ref();
6130 tt1
=v1
->get_expr_returntype(exp_val
);
6131 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6132 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6133 chk_expr_val_len1(v1
, the
, opname
);
6136 case OPTYPE_CHAR2OCT
:
6139 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6140 v1
->set_lowerid_to_ref();
6141 tt1
=v1
->get_expr_returntype(exp_val
);
6142 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6143 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6146 case OPTYPE_STR2INT
:
6149 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6150 v1
->set_lowerid_to_ref();
6151 tt1
=v1
->get_expr_returntype(exp_val
);
6152 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6153 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6154 chk_expr_val_str_int(v1
, the
, opname
);
6157 case OPTYPE_STR2FLOAT
:
6160 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6161 v1
->set_lowerid_to_ref();
6162 tt1
=v1
->get_expr_returntype(exp_val
);
6163 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6164 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6165 chk_expr_val_str_float(v1
, the
, opname
);
6168 case OPTYPE_STR2BIT
:
6171 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6172 v1
->set_lowerid_to_ref();
6173 tt1
=v1
->get_expr_returntype(exp_val
);
6174 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6175 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6176 chk_expr_val_str_bindigits(v1
, the
, opname
);
6179 case OPTYPE_STR2HEX
:
6182 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6183 v1
->set_lowerid_to_ref();
6184 tt1
=v1
->get_expr_returntype(exp_val
);
6185 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6186 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6187 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6190 case OPTYPE_STR2OCT
:
6193 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6194 v1
->set_lowerid_to_ref();
6195 tt1
=v1
->get_expr_returntype(exp_val
);
6196 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6197 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6198 chk_expr_val_str_len_even(v1
, the
, opname
);
6199 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6202 case OPTYPE_ENUM2INT
:
6205 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6206 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6207 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6211 chk_expr_operand_encode(refch
, exp_val
);
6213 case OPTYPE_FLOAT2INT
:
6214 case OPTYPE_FLOAT2STR
:
6217 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6218 v1
->set_lowerid_to_ref();
6219 tt1
=v1
->get_expr_returntype(exp_val
);
6220 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6221 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6222 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6223 chk_expr_operand_valid_float(v1
, the
, opname
);
6226 case OPTYPE_RNDWITHVAL
:
6229 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6230 v1
->set_lowerid_to_ref();
6231 tt1
=v1
->get_expr_returntype(exp_val
);
6232 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6233 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6234 chk_expr_operand_valid_float(v1
, the
, opname
);
6236 chk_expr_dynamic_part(exp_val
, true);
6238 case OPTYPE_HEX2BIT
:
6239 case OPTYPE_HEX2OCT
:
6240 case OPTYPE_HEX2STR
:
6243 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6244 v1
->set_lowerid_to_ref();
6245 tt1
=v1
->get_expr_returntype(exp_val
);
6246 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6247 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6250 case OPTYPE_HEX2INT
:
6253 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6254 v1
->set_lowerid_to_ref();
6255 tt1
=v1
->get_expr_returntype(exp_val
);
6256 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6257 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6258 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6261 case OPTYPE_INT2CHAR
:
6264 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6265 v1
->set_lowerid_to_ref();
6266 tt1
=v1
->get_expr_returntype(exp_val
);
6267 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6268 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6269 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6272 case OPTYPE_INT2UNICHAR
:
6275 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6276 v1
->set_lowerid_to_ref();
6277 tt1
=v1
->get_expr_returntype(exp_val
);
6278 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6279 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6280 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6283 case OPTYPE_INT2FLOAT
:
6284 case OPTYPE_INT2STR
:
6287 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6288 v1
->set_lowerid_to_ref();
6289 tt1
=v1
->get_expr_returntype(exp_val
);
6290 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6291 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6294 case OPTYPE_OCT2BIT
:
6295 case OPTYPE_OCT2HEX
:
6296 case OPTYPE_OCT2STR
:
6299 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6300 v1
->set_lowerid_to_ref();
6301 tt1
=v1
->get_expr_returntype(exp_val
);
6302 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6303 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6306 case OPTYPE_OCT2INT
:
6309 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6310 v1
->set_lowerid_to_ref();
6311 tt1
=v1
->get_expr_returntype(exp_val
);
6312 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6313 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6314 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6318 case OPTYPE_OCT2CHAR
:
6321 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6322 v1
->set_lowerid_to_ref();
6323 tt1
=v1
->get_expr_returntype(exp_val
);
6324 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6325 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6326 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6329 case OPTYPE_REMOVE_BOM
:
6332 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6333 v1
->set_lowerid_to_ref();
6334 tt1
=v1
->get_expr_returntype(exp_val
);
6335 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6336 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6339 case OPTYPE_GET_STRINGENCODING
:
6342 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6343 v1
->set_lowerid_to_ref();
6344 tt1
=v1
->get_expr_returntype(exp_val
);
6345 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6346 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6349 case OPTYPE_ENCODE_BASE64
:
6352 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6353 v1
->set_lowerid_to_ref();
6354 tt1
=v1
->get_expr_returntype(exp_val
);
6355 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6356 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6358 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6361 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6362 v2
->set_lowerid_to_ref();
6363 tt2
=v2
->get_expr_returntype(exp_val
);
6364 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6365 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6368 case OPTYPE_DECODE_BASE64
:
6371 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6372 v1
->set_lowerid_to_ref();
6373 tt1
=v1
->get_expr_returntype(exp_val
);
6374 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6375 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6378 case OPTYPE_UNICHAR2INT
:
6381 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6382 v1
->set_lowerid_to_ref();
6383 tt1
=v1
->get_expr_returntype(exp_val
);
6384 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6385 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6386 chk_expr_val_len1(v1
, the
, opname
);
6389 case OPTYPE_UNICHAR2CHAR
:
6392 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6393 v1
->set_lowerid_to_ref();
6394 tt1
=v1
->get_expr_returntype(exp_val
);
6395 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6396 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6397 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6400 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6403 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6404 v1
->set_lowerid_to_ref();
6405 tt1
=v1
->get_expr_returntype(exp_val
);
6406 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6407 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6409 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6412 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6413 v2
->set_lowerid_to_ref();
6414 tt2
=v2
->get_expr_returntype(exp_val
);
6415 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6416 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6419 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6422 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6423 v1
->set_lowerid_to_ref();
6424 tt1
=v1
->get_expr_returntype(exp_val
);
6425 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6426 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6428 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6431 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6432 v2
->set_lowerid_to_ref();
6433 tt2
=v2
->get_expr_returntype(exp_val
);
6434 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6435 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6438 case OPTYPE_ADD
: // v1 v2
6439 case OPTYPE_SUBTRACT
:
6440 case OPTYPE_MULTIPLY
:
6444 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6445 v1
->set_lowerid_to_ref();
6446 tt1
=v1
->get_expr_returntype(exp_val
);
6447 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6448 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6449 chk_expr_operand_valid_float(v1
, first
, opname
);
6453 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6454 v2
->set_lowerid_to_ref();
6455 tt2
=v2
->get_expr_returntype(exp_val
);
6456 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6457 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6458 chk_expr_operand_valid_float(v2
, second
, opname
);
6459 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6460 chk_expr_val_int_float_not0(v2
, second
, opname
);
6462 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6468 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6469 v1
->set_lowerid_to_ref();
6470 tt1
=v1
->get_expr_returntype(exp_val
);
6471 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6472 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6476 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6477 v2
->set_lowerid_to_ref();
6478 tt2
=v2
->get_expr_returntype(exp_val
);
6479 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6480 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6481 chk_expr_val_int_float_not0(v2
, right
, opname
);
6484 case OPTYPE_CONCAT
: {
6487 v1
->set_lowerid_to_ref();
6488 v2
->set_lowerid_to_ref();
6489 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6491 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6492 tt1
=v1
->get_expr_returntype(exp_val
);
6493 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6494 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6497 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6498 tt2
=v2
->get_expr_returntype(exp_val
);
6499 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6500 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6502 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6503 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6504 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6505 } else { // other list types
6506 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6507 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6509 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6510 set_valuetype(V_ERROR
);
6513 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6514 v1_gov
->chk_this_value_ref(v1
);
6515 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6516 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6517 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6521 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6522 set_valuetype(V_ERROR
);
6525 // for recof/setof literals set the type from v1
6527 v2
->set_my_governor(v1_gov
);
6530 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6532 v2_gov
->chk_this_value_ref(v2
);
6533 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6534 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6535 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6536 if (valuetype
== V_ERROR
) return;
6537 // 7.1.2 says that we shouldn't allow type compatibility.
6538 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6539 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6540 error("The operands of operation `%s' should be of compatible "
6541 "types", get_opname());
6550 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6552 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6554 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6557 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6559 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6560 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6561 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6562 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6563 * "a == not b" is not allowed. (HL69107)
6564 * The various *Expressions implement operator precedence in the std.
6565 * Titan's parser has only one Expression and relies on Bison
6566 * for operator precedence. The check below brings Titan in line
6567 * with the standard by explicitly making "a == not b" an error */
6568 if (v2
->get_valuetype() == V_EXPR
6569 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6570 error("The operation `%s' is not allowed to be "
6571 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6572 set_valuetype(V_ERROR
);
6582 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6584 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6586 tt1
=v1
->get_expr_returntype(exp_val
);
6587 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6588 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6591 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6593 tt2
=v2
->get_expr_returntype(exp_val
);
6594 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6595 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6603 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6605 v1
->set_lowerid_to_ref();
6606 tt1
=v1
->get_expr_returntype(exp_val
);
6607 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6608 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6612 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6614 v2
->set_lowerid_to_ref();
6615 tt2
=v2
->get_expr_returntype(exp_val
);
6616 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6617 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6625 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6627 v1
->set_lowerid_to_ref();
6628 tt1
=v1
->get_expr_returntype(exp_val
);
6629 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6630 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6634 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6636 v2
->set_lowerid_to_ref();
6637 tt2
=v2
->get_expr_returntype(exp_val
);
6638 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6639 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6641 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6642 chk_expr_operands_str_samelen();
6648 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6649 v1
->set_lowerid_to_ref();
6650 tt1
=v1
->get_expr_returntype(exp_val
);
6651 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6652 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6656 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6657 v2
->set_lowerid_to_ref();
6658 tt2
=v2
->get_expr_returntype(exp_val
);
6659 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6660 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6661 chk_expr_val_large_int(v2
, right
, opname
);
6667 v1
->set_lowerid_to_ref();
6668 if (v1
->is_string_type(exp_val
)) {
6669 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6670 tt1
=v1
->get_expr_returntype(exp_val
);
6671 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6672 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6673 } else { // other list types
6674 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6675 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6676 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6678 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6679 v1_gov
->chk_this_value_ref(v1
);
6680 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6681 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6682 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6687 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6688 v2
->set_lowerid_to_ref();
6689 tt2
=v2
->get_expr_returntype(exp_val
);
6690 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6691 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6692 chk_expr_val_large_int(v2
, right
, opname
);
6695 case OPTYPE_INT2BIT
:
6696 case OPTYPE_INT2HEX
:
6697 case OPTYPE_INT2OCT
:
6700 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6701 v1
->set_lowerid_to_ref();
6702 tt1
=v1
->get_expr_returntype(exp_val
);
6703 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6704 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6705 chk_expr_val_int_pos0(v1
, first
, opname
);
6709 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6710 v2
->set_lowerid_to_ref();
6711 tt2
=v2
->get_expr_returntype(exp_val
);
6712 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6713 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6714 chk_expr_val_int_pos0(v2
, second
, opname
);
6716 chk_expr_operands_int2binstr();
6719 chk_expr_operands_decode();
6723 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6724 Type::expected_value_t ti_exp_val
= exp_val
;
6725 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6726 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6727 if (!governor
) return;
6728 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6729 if (valuetype
!=V_ERROR
)
6730 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6731 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6735 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6736 v2
->set_lowerid_to_ref();
6737 tt2
=v2
->get_expr_returntype(exp_val
);
6738 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6739 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6740 chk_expr_val_int_pos0(v2
, second
, opname
);
6744 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6745 v3
->set_lowerid_to_ref();
6746 tt3
=v3
->get_expr_returntype(exp_val
);
6747 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6748 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6749 chk_expr_val_int_pos0(v3
, third
, opname
);
6751 chk_expr_operands_substr();
6753 case OPTYPE_REGEXP
: {
6754 Type::expected_value_t ti_exp_val
= exp_val
;
6755 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6757 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6758 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6759 if (!governor
) return;
6760 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6761 if (valuetype
!=V_ERROR
) {
6762 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6763 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6764 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6768 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6769 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6770 if (!governor
) return;
6771 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6772 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6773 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6777 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6778 v3
->set_lowerid_to_ref();
6779 tt3
=v3
->get_expr_returntype(exp_val
);
6780 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6781 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6782 chk_expr_val_int_pos0(v3
, third
, opname
);
6784 chk_expr_operands_regexp();
6786 case OPTYPE_ISCHOSEN
:
6787 // do nothing: the operand is erroneous
6788 // the error was already reported in chk_expr_ref_ischosen()
6790 case OPTYPE_ISCHOSEN_V
: // v1 i2
6791 case OPTYPE_ISCHOSEN_T
: // t1 i2
6792 chk_expr_operands_ischosen(refch
, exp_val
);
6794 case OPTYPE_VALUEOF
: { // ti1
6795 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6796 exp_val
= Type::EXPECTED_TEMPLATE
;
6797 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6798 Type
*governor
= my_governor
;
6799 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6800 if (!governor
) return;
6801 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6802 if (valuetype
== V_ERROR
) return;
6803 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6805 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6806 case OPTYPE_ISBOUND
: {
6807 Template
*templ
= u
.expr
.ti1
->get_Template();
6808 switch (templ
->get_templatetype()) {
6809 case Template::TEMPLATE_REFD
:
6810 templ
->get_reference()->setUsedInIsbound();
6812 case Template::SPECIFIC_VALUE
: {
6813 Value
*value
= templ
->get_specific_value();
6814 if (Value::V_REFD
== value
->get_valuetype()) {
6815 value
->get_reference()->setUsedInIsbound();
6823 case OPTYPE_ISVALUE
: {// ti1
6824 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6825 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6826 exp_val
= Type::EXPECTED_TEMPLATE
;
6827 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6828 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6829 if (!governor
) return;
6830 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
6831 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6833 case OPTYPE_SIZEOF
: // ti1
6834 /* this checking is too complex, do the checking during eval... */
6836 case OPTYPE_LENGTHOF
: { // ti1
6837 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6838 exp_val
= Type::EXPECTED_TEMPLATE
;
6839 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6840 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6841 if (!governor
) return;
6842 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
6843 if (valuetype
== V_ERROR
) return;
6844 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6846 case OPTYPE_MATCH
: // v1 t2
6847 chk_expr_operands_match(exp_val
);
6849 case OPTYPE_UNDEF_RUNNING
: // r1
6850 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
6852 case OPTYPE_COMP_ALIVE
:
6853 case OPTYPE_COMP_RUNNING
: //v1
6854 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
6855 chk_expr_dynamic_part(exp_val
, false);
6857 case OPTYPE_TMR_READ
: // r1
6858 case OPTYPE_TMR_RUNNING
: // r1
6859 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
6860 chk_expr_dynamic_part(exp_val
, true);
6862 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
6863 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
6864 chk_expr_dynamic_part(exp_val
, true, false, false);
6866 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
6867 chk_expr_operand_comptyperef_create();
6870 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6871 v2
->set_lowerid_to_ref();
6872 tt2
=v2
->get_expr_returntype(exp_val
);
6873 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
6874 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6878 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6879 v3
->set_lowerid_to_ref();
6880 tt3
=v3
->get_expr_returntype(exp_val
);
6881 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
6882 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6884 chk_expr_dynamic_part(exp_val
, false);
6886 case OPTYPE_ACTIVATE
: // r1 // altstep
6887 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
6888 chk_expr_dynamic_part(exp_val
, true);
6890 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
6891 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6892 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
6894 delete u
.expr
.t_list2
;
6895 u
.expr
.ap_list2
= parlist
;
6896 chk_expr_dynamic_part(exp_val
, true);
6898 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
6899 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6900 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
6901 u
.expr
.v3
, the
, opname
);
6902 delete u
.expr
.t_list2
;
6903 u
.expr
.ap_list2
= parlist
;
6904 chk_expr_dynamic_part(exp_val
, true);
6907 error("Built-in function `%s' is not yet supported", opname
);
6908 set_valuetype(V_ERROR
);
6910 case OPTYPE_REPLACE
: {
6911 Type::expected_value_t ti_exp_val
= exp_val
;
6912 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6913 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6915 Error_Context
cntxt(this, "In the first operand of operation `%s'",
6917 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6918 if (!governor
) return;
6919 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6920 if (valuetype
!= V_ERROR
)
6921 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6922 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6926 Error_Context
cntxt(this, "In the second operand of operation `%s'",
6928 v2
->set_lowerid_to_ref();
6929 tt2
= v2
->get_expr_returntype(exp_val
);
6930 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6931 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6932 chk_expr_val_int_pos0(v2
, second
, opname
);
6936 Error_Context
cntxt(this, "In the third operand of operation `%s'",
6938 v3
->set_lowerid_to_ref();
6939 tt3
= v3
->get_expr_returntype(exp_val
);
6940 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6941 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6942 chk_expr_val_int_pos0(v3
, third
, opname
);
6945 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
6947 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
6948 if (!governor
) return;
6949 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
6950 if (valuetype
!= V_ERROR
)
6951 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
6952 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
6954 chk_expr_operands_replace();
6956 case OPTYPE_LOG2STR
: {
6957 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6958 u
.expr
.logargs
->chk();
6959 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
6961 case OPTYPE_TTCN2STRING
: {
6962 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
6963 Type::expected_value_t ti_exp_val
= exp_val
;
6964 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6965 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6966 if (!governor
) return;
6967 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6970 FATAL_ERROR("chk_expr_operands()");
6974 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6975 // the result of evaluating the expression. E.g. V_BOOL for
6977 void Value::evaluate_value(ReferenceChain
*refch
,
6978 Type::expected_value_t exp_val
)
6980 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
6981 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
6983 u
.expr
.state
=EXPR_CHECKING
;
6985 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
6986 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
6987 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
6989 if(valuetype
==V_ERROR
) return;
6990 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
6991 u
.expr
.state
=EXPR_CHECKED
;
6992 set_valuetype(V_ERROR
);
6996 u
.expr
.state
=EXPR_CHECKED
;
6998 Value
*v1
, *v2
, *v3
, *v4
;
6999 switch(u
.expr
.v_optype
) {
7000 case OPTYPE_RND
: // -
7001 case OPTYPE_COMP_NULL
: // the only foldable in this group
7002 case OPTYPE_COMP_MTC
:
7003 case OPTYPE_COMP_SYSTEM
:
7004 case OPTYPE_COMP_SELF
:
7005 case OPTYPE_COMP_RUNNING_ANY
:
7006 case OPTYPE_COMP_RUNNING_ALL
:
7007 case OPTYPE_COMP_ALIVE_ANY
:
7008 case OPTYPE_COMP_ALIVE_ALL
:
7009 case OPTYPE_TMR_RUNNING_ANY
:
7010 case OPTYPE_GETVERDICT
:
7011 case OPTYPE_PROF_RUNNING
:
7012 case OPTYPE_RNDWITHVAL
: // v1
7013 case OPTYPE_COMP_RUNNING
: // v1
7014 case OPTYPE_COMP_ALIVE
:
7015 case OPTYPE_TMR_READ
:
7016 case OPTYPE_TMR_RUNNING
:
7017 case OPTYPE_ACTIVATE
:
7018 case OPTYPE_ACTIVATE_REFD
:
7019 case OPTYPE_EXECUTE
: // r1 [v2]
7020 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7021 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7022 case OPTYPE_MATCH
: // v1 t2
7023 case OPTYPE_ISCHOSEN_T
:
7024 case OPTYPE_LOG2STR
:
7027 case OPTYPE_ISBOUND
:
7028 case OPTYPE_ISPRESENT
:
7029 case OPTYPE_TTCN2STRING
:
7030 case OPTYPE_UNICHAR2OCT
:
7031 case OPTYPE_OCT2UNICHAR
:
7032 case OPTYPE_ENCODE_BASE64
:
7033 case OPTYPE_DECODE_BASE64
:
7035 case OPTYPE_TESTCASENAME
: { // -
7036 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7037 Ttcn::StatementBlock
*my_sb
=
7038 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7040 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7041 if (!my_def
) { // In control part.
7042 set_val_str(new string(""));
7044 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7045 set_val_str(new string(my_def
->get_id().get_dispname()));
7049 case OPTYPE_UNARYPLUS
: // v1
7052 copy_and_destroy(v1
);
7054 case OPTYPE_UNARYMINUS
:
7055 if (is_unfoldable()) break;
7056 v1
= u
.expr
.v1
->get_value_refd_last();
7057 switch (v1
->valuetype
) {
7059 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7060 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7066 ttcn3float r
= v1
->get_val_Real();
7072 FATAL_ERROR("Value::evaluate_value()");
7076 if(is_unfoldable()) break;
7077 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7082 case OPTYPE_NOT4B
: {
7083 if(is_unfoldable()) break;
7084 v1
=u
.expr
.v1
->get_value_refd_last();
7085 const string
& s
= v1
->get_val_str();
7086 valuetype_t vt
=v1
->valuetype
;
7089 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7091 case OPTYPE_BIT2HEX
: {
7092 if(is_unfoldable()) break;
7093 v1
=u
.expr
.v1
->get_value_refd_last();
7094 const string
& s
= v1
->get_val_str();
7097 set_val_str(bit2hex(s
));
7099 case OPTYPE_BIT2OCT
: {
7100 if(is_unfoldable()) break;
7101 v1
=u
.expr
.v1
->get_value_refd_last();
7102 const string
& s
= v1
->get_val_str();
7105 set_val_str(bit2oct(s
));
7107 case OPTYPE_BIT2STR
:
7108 case OPTYPE_HEX2STR
:
7109 case OPTYPE_OCT2STR
: {
7110 if(is_unfoldable()) break;
7111 v1
=u
.expr
.v1
->get_value_refd_last();
7112 const string
& s
= v1
->get_val_str();
7115 set_val_str(new string(s
));
7117 case OPTYPE_BIT2INT
: {
7118 if (is_unfoldable()) break;
7119 v1
= u
.expr
.v1
->get_value_refd_last();
7120 const string
& s
= v1
->get_val_str();
7123 u
.val_Int
= bit2int(s
);
7125 case OPTYPE_CHAR2INT
: {
7126 if (is_unfoldable()) break;
7127 v1
= u
.expr
.v1
->get_value_refd_last();
7128 char c
= v1
->get_val_str()[0];
7131 u
.val_Int
= new int_val_t((Int
)c
);
7133 case OPTYPE_CHAR2OCT
: {
7134 if(is_unfoldable()) break;
7135 v1
=u
.expr
.v1
->get_value_refd_last();
7136 const string
& s
= v1
->get_val_str();
7139 set_val_str(char2oct(s
));
7141 case OPTYPE_STR2INT
: {
7142 if (is_unfoldable()) break;
7143 v1
= u
.expr
.v1
->get_value_refd_last();
7144 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7148 /** \todo hiba eseten lenyeli... */
7150 case OPTYPE_STR2FLOAT
: {
7151 if(is_unfoldable()) break;
7152 v1
=u
.expr
.v1
->get_value_refd_last();
7153 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7157 /** \todo hiba eseten lenyeli... */
7159 case OPTYPE_STR2BIT
: {
7160 if(is_unfoldable()) break;
7161 v1
=u
.expr
.v1
->get_value_refd_last();
7162 const string
& s
= v1
->get_val_str();
7165 set_val_str(new string(s
));
7167 case OPTYPE_STR2HEX
:
7168 case OPTYPE_OCT2HEX
: {
7169 if(is_unfoldable()) break;
7170 v1
=u
.expr
.v1
->get_value_refd_last();
7171 const string
& s
= v1
->get_val_str();
7174 set_val_str(to_uppercase(s
));
7176 case OPTYPE_STR2OCT
: {
7177 if(is_unfoldable()) break;
7178 v1
=u
.expr
.v1
->get_value_refd_last();
7179 const string
& s
= v1
->get_val_str();
7182 set_val_str(to_uppercase(s
));
7184 case OPTYPE_FLOAT2INT
: {
7185 if (is_unfoldable()) break;
7186 v1
= u
.expr
.v1
->get_value_refd_last();
7187 ttcn3float r
= v1
->get_val_Real();
7190 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7192 case OPTYPE_FLOAT2STR
: {
7193 if(is_unfoldable()) break;
7194 v1
=u
.expr
.v1
->get_value_refd_last();
7195 ttcn3float r
=v1
->get_val_Real();
7198 set_val_str(float2str(r
));
7200 case OPTYPE_HEX2BIT
:
7201 case OPTYPE_OCT2BIT
: {
7202 if(is_unfoldable()) break;
7203 v1
=u
.expr
.v1
->get_value_refd_last();
7204 const string
& s
= v1
->get_val_str();
7207 set_val_str(hex2bit(s
));
7209 case OPTYPE_HEX2INT
:
7210 case OPTYPE_OCT2INT
: {
7211 if(is_unfoldable()) break;
7212 v1
=u
.expr
.v1
->get_value_refd_last();
7213 const string
& s
= v1
->get_val_str();
7216 u
.val_Int
=hex2int(s
);
7218 case OPTYPE_HEX2OCT
: {
7219 if(is_unfoldable()) break;
7220 v1
=u
.expr
.v1
->get_value_refd_last();
7221 const string
& s
= v1
->get_val_str();
7224 set_val_str(hex2oct(s
));
7226 case OPTYPE_INT2CHAR
: {
7227 if (is_unfoldable()) break;
7228 v1
= u
.expr
.v1
->get_value_refd_last();
7229 const int_val_t
*c_int
= v1
->get_val_Int();
7230 char c
= static_cast<char>(c_int
->get_val());
7233 set_val_str(new string(1, &c
));
7235 case OPTYPE_INT2UNICHAR
: {
7236 if (is_unfoldable()) break;
7237 v1
= u
.expr
.v1
->get_value_refd_last();
7238 const int_val_t
*i_int
= v1
->get_val_Int();
7239 Int i
= i_int
->get_val();
7242 set_val_ustr(int2unichar(i
));
7243 u
.ustr
.convert_str
= false;
7245 case OPTYPE_INT2FLOAT
: {
7246 if (is_unfoldable()) break;
7247 v1
= u
.expr
.v1
->get_value_refd_last();
7248 const int_val_t
*i_int
= v1
->get_val_Int();
7249 Real i_int_real
= i_int
->to_real();
7252 u
.val_Real
= i_int_real
;
7254 case OPTYPE_INT2STR
: {
7255 if (is_unfoldable()) break;
7256 v1
= u
.expr
.v1
->get_value_refd_last();
7257 const int_val_t
*i_int
= v1
->get_val_Int();
7258 string
*i_int_str
= new string(i_int
->t_str());
7261 set_val_str(i_int_str
);
7263 case OPTYPE_OCT2CHAR
: {
7264 if(is_unfoldable()) break;
7265 v1
=u
.expr
.v1
->get_value_refd_last();
7266 const string
& s
= v1
->get_val_str();
7269 set_val_str(oct2char(s
));
7271 case OPTYPE_GET_STRINGENCODING
: {
7272 if(is_unfoldable()) break;
7273 v1
= u
.expr
.v1
->get_value_refd_last();
7274 const string
& s1
= v1
->get_val_str();
7277 set_val_str(get_stringencoding(s1
));
7279 case OPTYPE_REMOVE_BOM
: {
7280 if(is_unfoldable()) break;
7281 v1
= u
.expr
.v1
->get_value_refd_last();
7282 const string
& s1
= v1
->get_val_str();
7285 set_val_str(remove_bom(s1
));
7287 case OPTYPE_ENUM2INT
: {
7288 if(is_unfoldable()) break;
7289 v1
=u
.expr
.v1
->get_value_refd_last();
7290 Type
* enum_type
= v1
->get_my_governor();
7291 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7294 u
.val_Int
= new int_val_t(enum_val
);
7296 case OPTYPE_UNICHAR2INT
:
7297 if (is_unfoldable()) {
7298 // replace the operation with char2int() if the operand is a charstring
7299 // value to avoid its unnecessary conversion to universal charstring
7300 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7301 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7303 v1
=u
.expr
.v1
->get_value_refd_last();
7304 const ustring
& s
= v1
->get_val_ustr();
7307 u
.val_Int
=new int_val_t(unichar2int(s
));
7310 case OPTYPE_UNICHAR2CHAR
:
7312 if (is_unfoldable()) {
7313 // replace the operation with its operand if it is a charstring
7314 // value to avoid its unnecessary conversion to universal charstring
7315 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7317 copy_and_destroy(v1
);
7320 v1
= v1
->get_value_refd_last();
7321 const ustring
& s
= v1
->get_val_ustr();
7324 set_val_str(new string(s
));
7327 case OPTYPE_MULTIPLY
: { // v1 v2
7328 if (!is_unfoldable()) goto eval_arithmetic
;
7329 v1
= u
.expr
.v1
->get_value_refd_last();
7330 v2
= u
.expr
.v2
->get_value_refd_last();
7331 if (v1
->is_unfoldable()) v1
= v2
;
7332 if (v1
->is_unfoldable()) break;
7333 switch(v1
->valuetype
) {
7335 if (*v1
->get_val_Int() != 0) break;
7338 u
.val_Int
= new int_val_t((Int
)0);
7341 if (v1
->get_val_Real() != 0.0) break;
7347 FATAL_ERROR("Value::evaluate_value()");
7350 case OPTYPE_ADD
: // v1 v2
7351 case OPTYPE_SUBTRACT
:
7356 if(is_unfoldable()) break;
7357 v1
=u
.expr
.v1
->get_value_refd_last();
7358 v2
=u
.expr
.v2
->get_value_refd_last();
7359 operationtype_t ot
=u
.expr
.v_optype
;
7360 switch (v1
->valuetype
) {
7362 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7363 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7368 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7370 case OPTYPE_SUBTRACT
:
7371 u
.val_Int
= new int_val_t(*i1
- *i2
);
7373 case OPTYPE_MULTIPLY
:
7374 u
.val_Int
= new int_val_t(*i1
* *i2
);
7377 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7380 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7383 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7386 FATAL_ERROR("Value::evaluate_value()");
7392 ttcn3float r1
=v1
->get_val_Real();
7393 ttcn3float r2
=v2
->get_val_Real();
7400 case OPTYPE_SUBTRACT
:
7403 case OPTYPE_MULTIPLY
:
7410 FATAL_ERROR("Value::evaluate_value()");
7414 FATAL_ERROR("Value::evaluate_value()");
7417 case OPTYPE_CONCAT
: {
7418 if(is_unfoldable()) break;
7419 v1
=u
.expr
.v1
->get_value_refd_last();
7420 v2
=u
.expr
.v2
->get_value_refd_last();
7421 valuetype_t vt
= v1
->valuetype
;
7422 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7423 const ustring
& s1
= v1
->get_val_ustr();
7424 const ustring
& s2
= v2
->get_val_ustr();
7427 set_val_ustr(new ustring(s1
+ s2
));
7428 u
.ustr
.convert_str
= false;
7430 const string
& s1
= v1
->get_val_str();
7431 const string
& s2
= v2
->get_val_str();
7434 set_val_str(new string(s1
+ s2
));
7438 if(is_unfoldable()) break;
7439 v1
=u
.expr
.v1
->get_value_refd_last();
7440 v2
=u
.expr
.v2
->get_value_refd_last();
7447 if(is_unfoldable()) break;
7448 v1
=u
.expr
.v1
->get_value_refd_last();
7449 v2
=u
.expr
.v2
->get_value_refd_last();
7456 if(is_unfoldable()) break;
7457 v1
=u
.expr
.v1
->get_value_refd_last();
7458 v2
=u
.expr
.v2
->get_value_refd_last();
7465 if(is_unfoldable()) break;
7466 v1
=u
.expr
.v1
->get_value_refd_last();
7467 v2
=u
.expr
.v2
->get_value_refd_last();
7474 if(is_unfoldable()) break;
7475 v1
=u
.expr
.v1
->get_value_refd_last();
7476 v2
=u
.expr
.v2
->get_value_refd_last();
7483 if(is_unfoldable()) break;
7484 v1
=u
.expr
.v1
->get_value_refd_last();
7485 v2
=u
.expr
.v2
->get_value_refd_last();
7492 v1
= u
.expr
.v1
->get_value_refd_last();
7493 if (v1
->valuetype
== V_BOOL
) {
7494 if (v1
->get_val_bool()) {
7495 // the left operand is a literal "true"
7496 // substitute the expression with the right operand
7499 copy_and_destroy(v2
);
7501 // the left operand is a literal "false"
7502 // the result must be false regardless the right operand
7503 // because of the short circuit evaluation rule
7509 // we must keep the left operand because of the potential side effects
7510 // the right operand can only be eliminated if it is a literal "true"
7511 v2
= u
.expr
.v2
->get_value_refd_last();
7512 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7515 copy_and_destroy(v1
);
7520 v1
= u
.expr
.v1
->get_value_refd_last();
7521 if (v1
->valuetype
== V_BOOL
) {
7522 if (v1
->get_val_bool()) {
7523 // the left operand is a literal "true"
7524 // the result must be true regardless the right operand
7525 // because of the short circuit evaluation rule
7530 // the left operand is a literal "false"
7531 // substitute the expression with the right operand
7534 copy_and_destroy(v2
);
7537 // we must keep the left operand because of the potential side effects
7538 // the right operand can only be eliminated if it is a literal "false"
7539 v2
= u
.expr
.v2
->get_value_refd_last();
7540 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7543 copy_and_destroy(v1
);
7548 if(is_unfoldable()) break;
7549 v1
=u
.expr
.v1
->get_value_refd_last();
7550 v2
=u
.expr
.v2
->get_value_refd_last();
7551 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7556 case OPTYPE_AND4B
: {
7557 if(is_unfoldable()) break;
7558 v1
=u
.expr
.v1
->get_value_refd_last();
7559 v2
=u
.expr
.v2
->get_value_refd_last();
7560 valuetype_t vt
=v1
->valuetype
;
7561 const string
& s1
= v1
->get_val_str();
7562 const string
& s2
= v2
->get_val_str();
7565 set_val_str(and4b(s1
, s2
));
7568 if(is_unfoldable()) break;
7569 v1
=u
.expr
.v1
->get_value_refd_last();
7570 v2
=u
.expr
.v2
->get_value_refd_last();
7571 valuetype_t vt
=v1
->valuetype
;
7572 const string
& s1
= v1
->get_val_str();
7573 const string
& s2
= v2
->get_val_str();
7576 set_val_str(or4b(s1
, s2
));
7578 case OPTYPE_XOR4B
: {
7579 if(is_unfoldable()) break;
7580 v1
=u
.expr
.v1
->get_value_refd_last();
7581 v2
=u
.expr
.v2
->get_value_refd_last();
7582 valuetype_t vt
=v1
->valuetype
;
7583 const string
& s1
= v1
->get_val_str();
7584 const string
& s2
= v2
->get_val_str();
7587 set_val_str(xor4b(s1
, s2
));
7590 if(is_unfoldable()) break;
7591 v1
=u
.expr
.v1
->get_value_refd_last();
7592 v2
=u
.expr
.v2
->get_value_refd_last();
7593 valuetype_t vt
=v1
->valuetype
;
7594 const string
& s
= v1
->get_val_str();
7595 const int_val_t
*i_int
= v2
->get_val_Int();
7596 Int i
=i_int
->get_val();
7597 if(vt
==V_OSTR
) i
*=2;
7600 set_val_str(shift_left(s
, i
));
7603 if(is_unfoldable()) break;
7604 v1
=u
.expr
.v1
->get_value_refd_last();
7605 v2
=u
.expr
.v2
->get_value_refd_last();
7606 valuetype_t vt
=v1
->valuetype
;
7607 const string
& s
= v1
->get_val_str();
7608 const int_val_t
*i_int
= v2
->get_val_Int();
7609 Int i
=i_int
->get_val();
7610 if(vt
==V_OSTR
) i
*=2;
7613 set_val_str(shift_right(s
, i
));
7616 if(is_unfoldable()) break;
7617 v1
=u
.expr
.v1
->get_value_refd_last();
7618 v2
=u
.expr
.v2
->get_value_refd_last();
7619 valuetype_t vt
=v1
->valuetype
;
7620 const int_val_t
*i_int
=v2
->get_val_Int();
7621 Int i
=i_int
->get_val();
7623 const ustring
& s
= v1
->get_val_ustr();
7626 set_val_ustr(rotate_left(s
, i
));
7627 u
.ustr
.convert_str
= false;
7630 if(vt
==V_OSTR
) i
*=2;
7631 const string
& s
= v1
->get_val_str();
7634 set_val_str(rotate_left(s
, i
));
7638 if(is_unfoldable()) break;
7639 v1
=u
.expr
.v1
->get_value_refd_last();
7640 v2
=u
.expr
.v2
->get_value_refd_last();
7641 valuetype_t vt
=v1
->valuetype
;
7642 const int_val_t
*i_int
=v2
->get_val_Int();
7643 Int i
=i_int
->get_val();
7645 const ustring
& s
= v1
->get_val_ustr();
7648 set_val_ustr(rotate_right(s
, i
));
7649 u
.ustr
.convert_str
= false;
7652 if(vt
==V_OSTR
) i
*=2;
7653 const string
& s
= v1
->get_val_str();
7656 set_val_str(rotate_right(s
, i
));
7659 case OPTYPE_INT2BIT
: {
7660 if (is_unfoldable()) break;
7661 v1
= u
.expr
.v1
->get_value_refd_last();
7662 v2
= u
.expr
.v2
->get_value_refd_last();
7663 const int_val_t
*i1_int
= v1
->get_val_Int();
7664 const int_val_t
*i2_int
= v2
->get_val_Int();
7665 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7670 case OPTYPE_INT2HEX
: {
7671 if (is_unfoldable()) break;
7672 v1
= u
.expr
.v1
->get_value_refd_last();
7673 v2
= u
.expr
.v2
->get_value_refd_last();
7674 const int_val_t
*i1_int
= v1
->get_val_Int();
7675 const int_val_t
*i2_int
= v2
->get_val_Int();
7676 // Do it before the `clean_up'. i2_int is already checked.
7677 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7682 case OPTYPE_INT2OCT
: {
7683 if (is_unfoldable()) break;
7684 v1
= u
.expr
.v1
->get_value_refd_last();
7685 v2
= u
.expr
.v2
->get_value_refd_last();
7686 const int_val_t
i1_int(*v1
->get_val_Int());
7687 // `v2' is a native integer.
7688 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7691 set_val_str(int2hex(i1_int
, i2_int
));
7693 case OPTYPE_SUBSTR
: {
7694 if(is_unfoldable()) break;
7695 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7696 v2
=u
.expr
.v2
->get_value_refd_last();
7697 v3
=u
.expr
.v3
->get_value_refd_last();
7698 valuetype_t vt
=v1
->valuetype
;
7699 const int_val_t
*i2_int
=v2
->get_val_Int();
7700 const int_val_t
*i3_int
=v3
->get_val_Int();
7701 Int i2
=i2_int
->get_val();
7702 Int i3
=i3_int
->get_val();
7704 const ustring
& s
= v1
->get_val_ustr();
7707 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7708 u
.ustr
.convert_str
= false;
7715 const string
& s
= v1
->get_val_str();
7718 set_val_str(new string(s
.substr(i2
, i3
)));
7721 case OPTYPE_REPLACE
: {
7722 if(is_unfoldable()) break;
7723 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7724 v2
=u
.expr
.v2
->get_value_refd_last();
7725 v3
=u
.expr
.v3
->get_value_refd_last();
7726 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7727 valuetype_t vt
=v1
->valuetype
;
7728 const int_val_t
*i2_int
=v2
->get_val_Int();
7729 const int_val_t
*i3_int
=v3
->get_val_Int();
7730 Int i2
=i2_int
->get_val();
7731 Int i3
=i3_int
->get_val();
7734 string
*s1
= new string(v1
->get_val_str());
7735 const string
& s2
= v4
->get_val_str();
7738 s1
->replace(i2
, i3
, s2
);
7742 string
*s1
= new string(v1
->get_val_str());
7743 const string
& s2
= v4
->get_val_str();
7746 s1
->replace(i2
, i3
, s2
);
7752 string
*s1
= new string(v1
->get_val_str());
7753 const string
& s2
= v4
->get_val_str();
7756 s1
->replace(i2
, i3
, s2
);
7760 string
*s1
= new string(v1
->get_val_str());
7761 const string
& s2
= v4
->get_val_str();
7764 s1
->replace(i2
, i3
, s2
);
7768 ustring
*s1
= new ustring(v1
->get_val_ustr());
7769 const ustring
& s2
= v4
->get_val_ustr();
7772 s1
->replace(i2
, i3
, s2
);
7774 u
.ustr
.convert_str
= false;
7777 FATAL_ERROR("Value::evaluate_value()");
7780 case OPTYPE_REGEXP
: {
7781 if (is_unfoldable()) break;
7782 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7783 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7784 v3
=u
.expr
.v3
->get_value_refd_last();
7785 const int_val_t
*i3_int
= v3
->get_val_Int();
7786 Int i3
= i3_int
->get_val();
7787 if (v1
->valuetype
== V_CSTR
) {
7788 const string
& s1
= v1
->get_val_str();
7789 const string
& s2
= v2
->get_val_str();
7790 string
*result
= regexp(s1
, s2
, i3
);
7793 set_val_str(result
);
7794 } if (v1
->valuetype
== V_USTR
) {
7795 const ustring
& s1
= v1
->get_val_ustr();
7796 const ustring
& s2
= v2
->get_val_ustr();
7797 ustring
*result
= regexp(s1
, s2
, i3
);
7800 set_val_ustr(result
);
7801 u
.ustr
.convert_str
= false;
7804 case OPTYPE_LENGTHOF
:{
7805 if(is_unfoldable()) break;
7806 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7807 ->get_value_refd_last();
7809 if(v1
->is_string_type(exp_val
)) {
7810 i
=v1
->get_val_strlen();
7811 } else { // v1 is be seq/set of or array
7812 switch (v1
->valuetype
) {
7816 if(v1
->u
.val_vs
->is_indexed())
7817 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7818 else { i
= v1
->u
.val_vs
->get_nof_vs();}
7821 FATAL_ERROR("Value::evaluate_value()");
7826 u
.val_Int
=new int_val_t(i
);
7828 case OPTYPE_SIZEOF
: {
7829 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
7833 u
.val_Int
=new int_val_t(i
);
7836 case OPTYPE_ISVALUE
: {
7837 if(is_unfoldable()) break;
7838 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
7839 && u
.expr
.ti1
->get_Template()->is_Value();
7841 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
7842 is_singleval
= other_val
->evaluate_isvalue(false);
7843 // is_singleval now contains the compile-time result of isvalue
7848 u
.val_bool
= is_singleval
;
7850 case OPTYPE_ISCHOSEN_V
: {
7851 if (is_unfoldable()) break;
7852 v1
= u
.expr
.v1
->get_value_refd_last();
7853 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
7858 case OPTYPE_VALUEOF
: // ti1
7859 if (!u
.expr
.ti1
->get_DerivedRef() &&
7860 u
.expr
.ti1
->get_Template()->is_Value() &&
7861 !u
.expr
.ti1
->get_Type()) {
7862 // FIXME actually if the template instance has a type
7863 // it might still be foldable.
7864 // the argument is a single specific value
7865 v1
= u
.expr
.ti1
->get_Template()->get_Value();
7866 Type
*governor
= my_governor
;
7867 if (governor
== NULL
) {
7868 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
7869 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
7871 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
7872 if (governor
== NULL
)
7873 FATAL_ERROR("Value::evaluate_value()");
7875 valuetype
= v1
->valuetype
;
7877 set_my_governor(governor
);
7878 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
7879 u
.ref
.refd_last
= this;
7880 v1
->valuetype
= V_ERROR
;
7884 case OPTYPE_UNDEF_RUNNING
:
7886 FATAL_ERROR("Value::evaluate_value()");
7890 bool Value::evaluate_isvalue(bool from_sequence
)
7892 switch (valuetype
) {
7894 // Omit is not a value unless a member of a sequence or set
7895 return from_sequence
;
7898 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7899 case V_BOOL
: /**< boolean */
7900 case V_NAMEDINT
: /**< integer / named number */
7901 case V_NAMEDBITS
: /**< named bits (identifiers) */
7902 case V_INT
: /**< integer */
7903 case V_REAL
: /**< real/float */
7904 case V_ENUM
: /**< enumerated */
7905 case V_BSTR
: /**< bitstring */
7906 case V_HSTR
: /**< hexstring */
7907 case V_OSTR
: /**< octetstring */
7908 case V_CSTR
: /**< charstring */
7909 case V_USTR
: /**< universal charstring */
7910 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
7911 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
7912 case V_OID
: /**< object identifier */
7913 case V_ROID
: /**< relative object identifier */
7914 case V_VERDICT
: /**< all verdicts */
7915 return true; // values of built-in types return true
7917 // Code below was adapted from is_unfoldable(), false returned early.
7919 return u
.choice
.alt_value
->evaluate_isvalue(false);
7924 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
7925 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
7933 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
7934 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
7935 ->evaluate_isvalue(true)) return false;
7940 // alas, get_value_refd_last prevents this function from const
7941 return get_value_refd_last()->evaluate_isvalue(false);
7944 switch (u
.expr
.v_optype
) {
7945 // A constant null component reference is a corner case: it is foldable
7946 // but escapes unmodified from evaluate_value.
7947 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7948 // or is transformed into some other valuetype in evaluate_value.
7949 case OPTYPE_COMP_NULL
:
7952 break; // and fall through to the FATAL_ERROR
7956 FATAL_ERROR("Value::evaluate_isvalue()");
7962 void Value::evaluate_macro(Type::expected_value_t exp_val
)
7965 case MACRO_MODULEID
:
7967 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7968 set_val_str(new string(my_scope
->get_scope_mod()
7969 ->get_modid().get_dispname()));
7972 case MACRO_FILENAME
:
7973 case MACRO_BFILENAME
: {
7974 const char *t_filename
= get_filename();
7976 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7977 set_val_str(new string(t_filename
));
7980 case MACRO_FILEPATH
: {
7981 const char *t_filename
= get_filename();
7983 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7984 char *t_filepath
= canonize_input_file(t_filename
);
7986 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7987 set_val_str(new string(t_filepath
));
7991 case MACRO_LINENUMBER
: {
7992 int t_lineno
= get_first_line();
7994 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7995 set_val_str(new string(Int2string(t_lineno
)));
7998 case MACRO_LINENUMBER_C
: {
7999 int t_lineno
= get_first_line();
8001 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8002 u
.val_Int
= new int_val_t(t_lineno
);
8005 case MACRO_DEFINITIONID
: {
8006 // cut the second part from the fullname separated by dots
8007 const string
& t_fullname
= get_fullname();
8008 size_t first_char
= t_fullname
.find('.') + 1;
8009 if (first_char
>= t_fullname
.size())
8010 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8011 t_fullname
.c_str());
8012 set_val_str(new string(t_fullname
.substr(first_char
,
8013 t_fullname
.find('.', first_char
) - first_char
)));
8017 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8018 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8022 case MACRO_TESTCASEID
: {
8023 if (exp_val
== Type::EXPECTED_CONSTANT
||
8024 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8025 error("A %s value was expected instead of macro `%%testcaseId', "
8026 "which is evaluated at runtime",
8027 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8031 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8032 Ttcn::StatementBlock
*my_sb
=
8033 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8035 error("Usage of macro %%testcaseId is allowed only within the "
8036 "statement blocks of functions, altsteps and testcases");
8039 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8041 error("Macro %%testcaseId cannot be used in the control part. "
8042 "It is allowed only within the statement blocks of functions, "
8043 "altsteps and testcases");
8046 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8047 // folding is possible only within testcases
8048 set_val_str(new string(my_def
->get_id().get_dispname()));
8053 FATAL_ERROR("Value::evaluate_macro()");
8057 set_valuetype(V_ERROR
);
8060 void Value::add_id(Identifier
*p_id
)
8064 if(u
.ids
->has_key(p_id
->get_name())) {
8065 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8066 // The Value does not take ownership for the identifier,
8067 // so it must be deleted (add_is acts as a sink).
8070 else u
.ids
->add(p_id
->get_name(), p_id
);
8073 FATAL_ERROR("Value::add_id()");
8077 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8078 Type::expected_value_t exp_val
)
8080 set_lowerid_to_ref();
8081 switch (valuetype
) {
8083 // there might be a better place for this
8084 chk_invoke(exp_val
);
8087 // use the cache if available
8088 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8090 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8092 // the referred definition is not found
8093 set_valuetype(V_ERROR
);
8095 switch (ass
->get_asstype()) {
8096 case Assignment::A_OBJECT
:
8097 case Assignment::A_OS
: {
8098 // the referred definition is an ASN.1 object or object set
8099 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8100 if (!setting
|| setting
->get_st() == S_ERROR
) {
8101 // remain silent, the error has been already reported
8102 set_valuetype(V_ERROR
);
8104 } else if (setting
->get_st() != S_V
) {
8105 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8106 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8107 set_valuetype(V_ERROR
);
8112 refch
->mark_state();
8113 destroy_refch
= false;
8115 refch
= new ReferenceChain(this,
8116 "While searching referenced value");
8117 destroy_refch
= true;
8119 if (refch
->add(get_fullname())) {
8120 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8121 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8122 // in case of circular recursion the valuetype is already set
8123 // to V_ERROR, so don't set the cache
8124 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8126 // a circular recursion was detected
8127 set_valuetype(V_ERROR
);
8129 if (destroy_refch
) delete refch
;
8130 else refch
->prev_state();
8132 case Assignment::A_CONST
: {
8133 // the referred definition is a constant
8136 refch
->mark_state();
8137 destroy_refch
= false;
8139 refch
= new ReferenceChain(this,
8140 "While searching referenced value");
8141 destroy_refch
= true;
8143 if (refch
->add(get_fullname())) {
8144 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8145 Value
*v_refd
= ass
->get_Value()
8146 ->get_refd_sub_value(subrefs
, 0,
8147 u
.ref
.ref
->getUsedInIsbound(), refch
);
8149 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8150 // in case of circular recursion the valuetype is already set
8151 // to V_ERROR, so don't set the cache
8152 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8153 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8154 u
.ref
.refd_last
= this;
8155 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8156 u
.ref
.refd_last
= this;
8158 // the sub-reference points to a non-existent field
8159 set_valuetype(V_ERROR
);
8162 // a circular recursion was detected
8163 set_valuetype(V_ERROR
);
8165 if (destroy_refch
) delete refch
;
8166 else refch
->prev_state();
8168 case Assignment::A_EXT_CONST
:
8169 case Assignment::A_MODULEPAR
:
8170 case Assignment::A_VAR
:
8171 case Assignment::A_FUNCTION_RVAL
:
8172 case Assignment::A_EXT_FUNCTION_RVAL
:
8173 case Assignment::A_PAR_VAL_IN
:
8174 case Assignment::A_PAR_VAL_OUT
:
8175 case Assignment::A_PAR_VAL_INOUT
:
8176 // the referred definition is not a constant
8177 u
.ref
.refd_last
= this;
8179 case Assignment::A_FUNCTION
:
8180 case Assignment::A_EXT_FUNCTION
:
8181 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8182 "call of %s, which does not have return type",
8183 ass
->get_description().c_str());
8184 set_valuetype(V_ERROR
);
8186 case Assignment::A_FUNCTION_RTEMP
:
8187 case Assignment::A_EXT_FUNCTION_RTEMP
:
8188 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8189 "call of %s, which returns a template",
8190 ass
->get_description().c_str());
8191 set_valuetype(V_ERROR
);
8194 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8195 ass
->get_description().c_str());
8196 set_valuetype(V_ERROR
);
8199 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8203 // try to evaluate the expression
8206 refch
->mark_state();
8207 destroy_refch
=false;
8210 refch
=new ReferenceChain(this, "While evaluating expression");
8213 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8214 else set_valuetype(V_ERROR
);
8215 if(destroy_refch
) delete refch
;
8216 else refch
->prev_state();
8219 evaluate_macro(exp_val
);
8222 // return this for all other value types
8227 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8229 /* Note that the logic here needs to be in sync with evaluate_value,
8230 * and possibly others, i.e. if evaluate_value is called for a Value
8231 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8232 bool Value::is_unfoldable(ReferenceChain
*refch
,
8233 Type::expected_value_t exp_val
)
8235 if (UnfoldabilityCheck::is_running(this)) {
8236 // This function is already running on this value => infinite recursion
8240 UnfoldabilityCheck
checker(this);
8242 if (get_needs_conversion()) return true;
8243 switch (valuetype
) {
8247 case V_UNDEF_LOWERID
:
8251 // these value types are eliminated during semantic analysis
8252 FATAL_ERROR("Value::is_unfoldable()");
8257 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8261 if (!is_indexed()) {
8262 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8263 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8267 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8268 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8275 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8276 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8277 ->is_unfoldable(refch
, exp_val
)) return true;
8283 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8284 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8288 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8289 if(v_last
==this) return true; // there weren't any references to chase
8290 else return v_last
->is_unfoldable(refch
, exp_val
);
8293 // classify the unchecked ischosen() operation, if it was not done so far
8294 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8295 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8296 switch (u
.expr
.v_optype
) {
8297 case OPTYPE_RND
: // -
8298 case OPTYPE_COMP_MTC
:
8299 case OPTYPE_COMP_SYSTEM
:
8300 case OPTYPE_COMP_SELF
:
8301 case OPTYPE_COMP_RUNNING_ANY
:
8302 case OPTYPE_COMP_RUNNING_ALL
:
8303 case OPTYPE_COMP_ALIVE_ANY
:
8304 case OPTYPE_COMP_ALIVE_ALL
:
8305 case OPTYPE_TMR_RUNNING_ANY
:
8306 case OPTYPE_GETVERDICT
:
8307 case OPTYPE_TESTCASENAME
:
8308 case OPTYPE_PROF_RUNNING
:
8309 case OPTYPE_RNDWITHVAL
: // v1
8310 case OPTYPE_MATCH
: // v1 t2
8311 case OPTYPE_UNDEF_RUNNING
: // v1
8312 case OPTYPE_COMP_RUNNING
:
8313 case OPTYPE_COMP_ALIVE
:
8314 case OPTYPE_TMR_READ
:
8315 case OPTYPE_TMR_RUNNING
:
8316 case OPTYPE_ACTIVATE
:
8317 case OPTYPE_ACTIVATE_REFD
:
8318 case OPTYPE_EXECUTE
: // r1 [v2]
8319 case OPTYPE_EXECUTE_REFD
:
8320 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8321 case OPTYPE_ISCHOSEN
:
8322 case OPTYPE_ISCHOSEN_T
:
8323 case OPTYPE_SIZEOF
: // ti1
8326 case OPTYPE_OCT2UNICHAR
:
8327 case OPTYPE_UNICHAR2OCT
:
8328 case OPTYPE_ENCODE_BASE64
:
8329 case OPTYPE_DECODE_BASE64
:
8331 case OPTYPE_COMP_NULL
: // -
8333 case OPTYPE_UNARYPLUS
: // v1
8334 case OPTYPE_UNARYMINUS
:
8337 case OPTYPE_BIT2HEX
:
8338 case OPTYPE_BIT2INT
:
8339 case OPTYPE_BIT2OCT
:
8340 case OPTYPE_BIT2STR
:
8341 case OPTYPE_CHAR2INT
:
8342 case OPTYPE_CHAR2OCT
:
8343 case OPTYPE_FLOAT2INT
:
8344 case OPTYPE_FLOAT2STR
:
8345 case OPTYPE_HEX2BIT
:
8346 case OPTYPE_HEX2INT
:
8347 case OPTYPE_HEX2OCT
:
8348 case OPTYPE_HEX2STR
:
8349 case OPTYPE_INT2CHAR
:
8350 case OPTYPE_INT2FLOAT
:
8351 case OPTYPE_INT2STR
:
8352 case OPTYPE_INT2UNICHAR
:
8353 case OPTYPE_OCT2BIT
:
8354 case OPTYPE_OCT2CHAR
:
8355 case OPTYPE_OCT2HEX
:
8356 case OPTYPE_OCT2INT
:
8357 case OPTYPE_OCT2STR
:
8358 case OPTYPE_STR2BIT
:
8359 case OPTYPE_STR2FLOAT
:
8360 case OPTYPE_STR2HEX
:
8361 case OPTYPE_STR2INT
:
8362 case OPTYPE_STR2OCT
:
8363 case OPTYPE_UNICHAR2INT
:
8364 case OPTYPE_UNICHAR2CHAR
:
8365 case OPTYPE_ENUM2INT
:
8366 case OPTYPE_GET_STRINGENCODING
:
8367 case OPTYPE_REMOVE_BOM
:
8368 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8369 case OPTYPE_ISBOUND
: /*{
8370 //TODO once we have the time for it make isbound foldable.
8371 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8372 Template* temp = u.expr.ti1->get_Template();
8373 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8374 Value* specificValue = temp->get_specific_value();
8375 if (specificValue->get_valuetype() == Value::V_REFD) {
8379 return specificValue->is_unfoldable(refch, exp_val);
8380 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8385 case OPTYPE_ISPRESENT
:
8386 // TODO: "if you have motivation"
8388 case OPTYPE_ISVALUE
: // ti1
8390 case OPTYPE_LENGTHOF
: // ti1
8391 return u
.expr
.ti1
->get_DerivedRef() != 0
8392 || u
.expr
.ti1
->get_Template()->get_templatetype()
8393 != Template::SPECIFIC_VALUE
8394 || u
.expr
.ti1
->get_Template()->get_specific_value()
8395 ->is_unfoldable(refch
, exp_val
);
8399 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8401 case OPTYPE_ADD
: // v1 v2
8402 case OPTYPE_SUBTRACT
:
8403 case OPTYPE_MULTIPLY
:
8419 case OPTYPE_INT2BIT
:
8420 case OPTYPE_INT2HEX
:
8421 case OPTYPE_INT2OCT
:
8422 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8423 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8424 case OPTYPE_AND
: // short-circuit evaluation
8425 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8426 || (u
.expr
.v1
->get_val_bool() &&
8427 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8428 case OPTYPE_OR
: // short-circuit evaluation
8429 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8430 || (!u
.expr
.v1
->get_val_bool() &&
8431 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8433 if (!u
.expr
.ti1
->get_specific_value()) return true;
8434 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8435 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8436 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8437 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8439 if (!u
.expr
.ti1
->get_specific_value() ||
8440 !u
.expr
.t2
->get_specific_value()) return true;
8441 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8442 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8443 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8445 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8446 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8447 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8448 case OPTYPE_REPLACE
: {
8449 if (!u
.expr
.ti1
->get_specific_value() ||
8450 !u
.expr
.ti4
->get_specific_value()) return true;
8451 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8452 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8453 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8454 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8455 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8457 case OPTYPE_VALUEOF
: // ti1
8458 /* \todo if you have motivation to implement the eval function
8461 case OPTYPE_ISCHOSEN_V
:
8462 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8463 case OPTYPE_LOG2STR
:
8464 case OPTYPE_TTCN2STRING
:
8467 FATAL_ERROR("Value::is_unfoldable()");
8469 break; // should never get here
8472 case MACRO_TESTCASEID
:
8473 // this is known only at runtime
8479 // all literal values are foldable
8484 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8485 size_t start_i
, bool usedInIsbound
,
8486 ReferenceChain
*refch
)
8488 if (!subrefs
) return this;
8490 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8492 v
= v
->get_value_refd_last(refch
);
8493 switch(v
->valuetype
) {
8502 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8503 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8504 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8505 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8510 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8511 bool usedInIsbound
, const Location
& loc
)
8513 if (valuetype
== V_OMIT
) {
8514 loc
.error("Reference to field `%s' of omit value `%s'",
8515 field_id
.get_dispname().c_str(), get_fullname().c_str());
8518 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8519 Type
*t
= my_governor
->get_type_refd_last();
8520 switch (t
->get_typetype()) {
8524 case Type::T_CHOICE_A
:
8525 case Type::T_CHOICE_T
:
8526 case Type::T_OPENTYPE
:
8527 case Type::T_ANYTYPE
:
8528 if (!t
->has_comp_withName(field_id
)) {
8529 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8530 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8532 } else if (valuetype
!= V_CHOICE
) {
8533 // remain silent, the error is already reported
8535 } else if (*u
.choice
.alt_name
== field_id
) {
8537 return u
.choice
.alt_value
;
8539 if (!usedInIsbound
) {
8540 loc
.error("Reference to inactive field `%s' in a value of union type "
8541 "`%s'. The active field is `%s'",
8542 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8543 u
.choice
.alt_name
->get_dispname().c_str());
8549 if (!t
->has_comp_withName(field_id
)) {
8550 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8551 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8553 } else if (valuetype
!= V_SEQ
) {
8554 // remain silent, the error has been already reported
8559 if (!t
->has_comp_withName(field_id
)) {
8560 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8561 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8563 } else if (valuetype
!= V_SET
) {
8564 // remain silent, the error has been already reported
8568 loc
.error("Invalid field reference `%s': type `%s' "
8569 "does not have fields", field_id
.get_dispname().c_str(),
8570 t
->get_typename().c_str());
8573 // the common end for record & set types
8574 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8576 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8577 } else if (!is_asn1()) {
8578 if (!usedInIsbound
) {
8579 loc
.error("Reference to unbound field `%s'",
8580 field_id
.get_dispname().c_str());
8581 // this is an error in TTCN-3, which has been already reported
8585 CompField
*cf
= t
->get_comp_byName(field_id
);
8586 if (cf
->get_is_optional()) {
8587 // creating an explicit omit value
8588 Value
*v
= new Value(V_OMIT
);
8589 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8590 v
->set_my_scope(get_my_scope());
8591 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8593 } else if (cf
->has_default()) {
8594 // returning the component's default value
8595 return cf
->get_defval();
8597 // this is an error in ASN.1, which has been already reported
8603 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8604 ReferenceChain
*refch
)
8606 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8608 bool index_available
= false;
8609 if (!v_index
->is_unfoldable()) {
8610 if (v_index
->valuetype
== V_INT
) {
8611 index
= v_index
->get_val_Int()->get_val();
8612 index_available
= true;
8614 array_index
->error("An integer value was expected as index");
8617 if (valuetype
== V_OMIT
) {
8618 array_index
->error("Accessing an element with index of omit value `%s'",
8619 get_fullname().c_str());
8622 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8623 Type
*t
= my_governor
->get_type_refd_last();
8624 switch (t
->get_typetype()) {
8629 if (index_available
) {
8631 array_index
->error("A non-negative integer value was expected "
8632 "instead of %s for indexing a value of `record "
8633 "of' type `%s'", Int2string(index
).c_str(),
8634 t
->get_typename().c_str());
8637 switch (valuetype
) {
8639 if (!is_indexed()) {
8640 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8641 if (!usedInIsbound
) {
8642 array_index
->error("Index overflow in a value of `record of' "
8643 "type `%s': the index is %s, but the value "
8644 "has only %lu elements",
8645 t
->get_typename().c_str(),
8646 Int2string(index
).c_str(),
8647 (unsigned long)u
.val_vs
->get_nof_vs());
8651 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8652 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8653 temp
->error("Not used symbol is not allowed in this context");
8654 return u
.val_vs
->get_v_byIndex(index
);
8657 // Search the appropriate constant index.
8658 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8659 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8660 ->get_value_refd_last();
8661 if (iv_index
->get_valuetype() != V_INT
) continue;
8662 if (iv_index
->get_val_Int()->get_val() == index
)
8663 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8669 // remain silent, the error has been already reported
8673 // the error has been reported above
8677 if (index_available
) {
8679 array_index
->error("A non-negative integer value was expected "
8680 "instead of %s for indexing a value of `set of' type `%s'",
8681 Int2string(index
).c_str(), t
->get_typename().c_str());
8684 switch (valuetype
) {
8686 if (!is_indexed()) {
8687 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8688 if (!usedInIsbound
) {
8689 array_index
->error("Index overflow in a value of `set of' type "
8690 "`%s': the index is %s, but the value has "
8691 "only %lu elements",
8692 t
->get_typename().c_str(),
8693 Int2string(index
).c_str(),
8694 (unsigned long)u
.val_vs
->get_nof_vs());
8698 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8699 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8700 temp
->error("Not used symbol is not allowed in this context");
8704 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8705 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8706 ->get_value_refd_last();
8707 if (iv_index
->get_valuetype() != V_INT
) continue;
8708 if (iv_index
->get_val_Int()->get_val() == index
)
8709 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8715 // remain silent, the error has been already reported
8719 // the error has been reported above
8723 if (index_available
) {
8724 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8725 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8726 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8727 // perform the index transformation
8728 index
-= dim
->get_offset();
8729 if (!is_indexed()) {
8730 // check for index underflow/overflow or too few elements in the
8733 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8735 else return u
.val_vs
->get_v_byIndex(index
);
8737 if (index
< 0) return 0;
8738 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8739 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8740 ->get_value_refd_last();
8741 if (iv_index
->get_valuetype() != V_INT
) continue;
8742 if (iv_index
->get_val_Int()->get_val() == index
)
8743 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8748 // remain silent, the error has been already reported
8752 // the error has been reported above
8756 case Type::T_BSTR_A
:
8761 case Type::T_UTF8STRING
:
8762 case Type::T_NUMERICSTRING
:
8763 case Type::T_PRINTABLESTRING
:
8764 case Type::T_TELETEXSTRING
:
8765 case Type::T_VIDEOTEXSTRING
:
8766 case Type::T_IA5STRING
:
8767 case Type::T_GRAPHICSTRING
:
8768 case Type::T_VISIBLESTRING
:
8769 case Type::T_GENERALSTRING
:
8770 case Type::T_UNIVERSALSTRING
:
8771 case Type::T_BMPSTRING
:
8772 case Type::T_UTCTIME
:
8773 case Type::T_GENERALIZEDTIME
:
8774 case Type::T_OBJECTDESCRIPTOR
:
8775 if (index_available
) return get_string_element(index
, *array_index
);
8778 array_index
->error("Invalid array element reference: type `%s' cannot "
8779 "be indexed", t
->get_typename().c_str());
8784 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8787 loc
.error("A non-negative integer value was expected instead of %s "
8788 "for indexing a string element", Int2string(index
).c_str());
8791 size_t string_length
;
8792 switch (valuetype
) {
8797 string_length
= u
.str
.val_str
->size();
8800 string_length
= u
.str
.val_str
->size() / 2;
8803 string_length
= u
.ustr
.val_ustr
->size();
8806 // remain silent, the error has been already reported
8809 if (index
>= static_cast<Int
>(string_length
)) {
8810 loc
.error("Index overflow when accessing a string element: "
8811 "the index is %s, but the string has only %lu elements",
8812 Int2string(index
).c_str(), (unsigned long) string_length
);
8815 switch (valuetype
) {
8820 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8821 return (*u
.str
.str_elements
)[index
];
8823 Value
*t_val
= new Value(valuetype
,
8824 new string(u
.str
.val_str
->substr(index
, 1)));
8825 add_string_element(index
, t_val
, u
.str
.str_elements
);
8829 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8830 return (*u
.str
.str_elements
)[index
];
8832 Value
*t_val
= new Value(V_OSTR
,
8833 new string(u
.str
.val_str
->substr(2 * index
, 2)));
8834 add_string_element(index
, t_val
, u
.str
.str_elements
);
8838 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
8839 return (*u
.ustr
.ustr_elements
)[index
];
8841 Value
*t_val
= new Value(V_USTR
,
8842 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
8843 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
8847 FATAL_ERROR("Value::get_string_element()");
8852 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
8853 Type::expected_value_t exp_val
)
8855 set_lowerid_to_ref();
8856 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
8857 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
8859 error("A value or expression of type %s was expected", type_name
);
8860 if (valuetype
== V_REFD
) {
8861 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
8862 t_chk
->chk_this_refd_value(this, 0, exp_val
);
8864 get_value_refd_last(0, exp_val
);
8865 if (error_flag
) set_valuetype(V_ERROR
);
8866 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
8869 int Value::is_parsed_infinity()
8871 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
8873 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
8874 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
8875 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
8880 bool Value::get_val_bool()
8883 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8885 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
8886 return v
->u
.val_bool
;
8889 int_val_t
* Value::get_val_Int()
8892 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8894 switch (v
->valuetype
) {
8897 case V_UNDEF_LOWERID
:
8898 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8899 "`%s'", (*u
.val_id
).get_dispname().c_str());
8901 FATAL_ERROR("Value::get_val_Int()");
8903 return v
->u
.val_Int
;
8906 const Identifier
* Value::get_val_id()
8911 case V_UNDEF_LOWERID
:
8914 FATAL_ERROR("Value::get_val_id()");
8919 const ttcn3float
& Value::get_val_Real()
8922 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8924 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
8925 return v
->u
.val_Real
;
8928 string
Value::get_val_str()
8930 Value
*v
= get_value_refd_last();
8931 switch (v
->valuetype
) {
8936 return *v
->u
.str
.val_str
;
8938 return v
->u
.char_syms
->get_string();
8940 error("Cannot use ISO-10646 string value in string context");
8943 error("Cannot use ISO-2022 string value in string context");
8948 error("Cannot use this value in charstring value context");
8953 ustring
Value::get_val_ustr()
8955 Value
*v
= get_value_refd_last();
8956 switch (v
->valuetype
) {
8958 return ustring(*v
->u
.str
.val_str
);
8960 return *v
->u
.ustr
.val_ustr
;
8962 return v
->u
.char_syms
->get_ustring();
8964 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8969 error("Cannot use this value in ISO-10646 string context");
8974 string
Value::get_val_iso2022str()
8976 Value
*v
= get_value_refd_last();
8977 switch (v
->valuetype
) {
8980 return *v
->u
.str
.val_str
;
8982 return v
->u
.char_syms
->get_iso2022string();
8984 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8989 error("Cannot use this value in ISO-2022 string context");
8994 size_t Value::get_val_strlen()
8996 Value
*v
= get_value_refd_last();
8997 switch (v
->valuetype
) {
9002 return v
->u
.str
.val_str
->size();
9004 return v
->u
.str
.val_str
->size()/2;
9006 return v
->u
.char_syms
->get_len();
9008 return v
->u
.ustr
.val_ustr
->size();
9012 error("Cannot use this value in string value context");
9017 Value::verdict_t
Value::get_val_verdict()
9023 FATAL_ERROR("Value::get_val_verdict()");
9028 size_t Value::get_nof_comps()
9030 switch (valuetype
) {
9034 return u
.oid_comps
->size();
9038 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9039 else return u
.val_vs
->get_nof_vs();
9042 return u
.val_nvs
->get_nof_nvs();
9047 return u
.str
.val_str
->size();
9049 return u
.str
.val_str
->size()/2;
9051 return u
.ustr
.val_ustr
->size();
9053 FATAL_ERROR("Value::get_nof_comps()");
9058 bool Value::is_indexed() const
9060 switch (valuetype
) {
9064 // Applicable only for list-types. Assigning a record/SEQUENCE or
9065 // set/SET with indexed notation is not supported.
9066 return u
.val_vs
->is_indexed();
9068 FATAL_ERROR("Value::is_indexed()");
9074 const Identifier
& Value::get_alt_name()
9076 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9077 return *u
.choice
.alt_name
;
9080 Value
*Value::get_alt_value()
9082 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9083 return u
.choice
.alt_value
;
9086 bool Value::has_oid_error()
9089 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9091 switch (valuetype
) {
9094 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9095 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9102 bool Value::get_oid_comps(vector
<string
>& comps
)
9104 bool ret_val
= true;
9106 switch (valuetype
) {
9108 v
= get_value_refd_last();
9112 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9113 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9114 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9115 // not all components can be calculated in compile-time
9121 FATAL_ERROR("Value::get_oid_comps()");
9126 void Value::add_se_comp(NamedValue
* nv
) {
9127 switch (valuetype
) {
9131 u
.val_nvs
= new NamedValues();
9132 u
.val_nvs
->add_nv(nv
);
9135 FATAL_ERROR("Value::add_se_comp()");
9139 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9144 return u
.val_nvs
->get_nv_byIndex(n
);
9146 FATAL_ERROR("Value::get_se_comp_byIndex()");
9151 Value
*Value::get_comp_byIndex(size_t n
)
9153 switch (valuetype
) {
9157 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9158 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9160 FATAL_ERROR("Value::get_comp_byIndex()");
9165 Value
*Value::get_index_byIndex(size_t n
)
9167 switch (valuetype
) {
9171 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9172 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9174 FATAL_ERROR("Value::get_index_byIndex()");
9179 bool Value::has_comp_withName(const Identifier
& p_name
)
9184 return u
.val_nvs
->has_nv_withName(p_name
);
9186 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9188 FATAL_ERROR("Value::get_has_comp_withName()");
9193 bool Value::field_is_chosen(const Identifier
& p_name
)
9195 Value
*v
=get_value_refd_last();
9196 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9197 return *v
->u
.choice
.alt_name
==p_name
;
9200 bool Value::field_is_present(const Identifier
& p_name
)
9202 Value
*v
=get_value_refd_last();
9203 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9204 FATAL_ERROR("Value::field_is_present()");
9205 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9206 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9207 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9210 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9215 return u
.val_nvs
->get_nv_byName(p_name
);
9217 FATAL_ERROR("Value::get_se_comp_byName()");
9222 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9227 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9229 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9230 return u
.choice
.alt_value
;
9234 FATAL_ERROR("Value::get_se_comp_byName()");
9239 void Value::chk_dupl_id()
9244 u
.val_nvs
->chk_dupl_id();
9247 FATAL_ERROR("Value::chk_dupl_id()");
9251 size_t Value::get_nof_ids() const
9255 return u
.ids
->size();
9258 FATAL_ERROR("Value::get_nof_ids()");
9263 Identifier
* Value::get_id_byIndex(size_t p_i
)
9267 return u
.ids
->get_nth_elem(p_i
);
9270 FATAL_ERROR("Value::get_id_byIndex()");
9275 bool Value::has_id(const Identifier
& p_id
)
9279 return u
.ids
->has_key(p_id
.get_name());
9282 FATAL_ERROR("Value::has_id()");
9287 Reference
*Value::get_reference() const
9289 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9293 Reference
*Value::get_refered() const
9295 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9299 Common::Assignment
*Value::get_refd_fat() const
9307 FATAL_ERROR("Value::get_refd_fat()");
9311 Ttcn::Reference
* Value::steal_ttcn_ref()
9313 Ttcn::Reference
*ret_val
=
9314 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9315 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9319 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9321 Ttcn::Ref_base
*t_ref
;
9322 if(valuetype
==V_REFD
) {
9323 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9324 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9327 else if(valuetype
==V_UNDEF_LOWERID
) {
9328 t_ref
=new Ttcn::Reference(u
.val_id
);
9329 t_ref
->set_location(*this);
9330 t_ref
->set_fullname(get_fullname());
9331 t_ref
->set_my_scope(get_my_scope());
9335 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9338 set_valuetype(V_ERROR
);
9342 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9343 Ttcn::ActualParList
*& p_ap
)
9345 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9348 p_ti
= u
.invoke
.t_list
;
9349 u
.invoke
.t_list
= 0;
9350 p_ap
= u
.invoke
.ap_list
;
9351 u
.invoke
.ap_list
= 0;
9352 set_valuetype(V_ERROR
);
9355 Common::Assignment
* Value::get_refd_assignment()
9364 FATAL_ERROR("Value::get_refd_assignment()");
9374 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9379 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9388 void Value::chk_OID(ReferenceChain
& refch
)
9390 if (checked
) return;
9391 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9392 FATAL_ERROR("Value::chk_OID()");
9393 if (!refch
.add(get_fullname())) {
9397 OID_comp::oidstate_t state
= OID_comp::START
;
9398 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9400 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9403 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9404 error("An OBJECT IDENTIFIER value must have at least "
9405 "two components"); // X.680 (07/2002) 31.10
9408 void Value::chk_ROID(ReferenceChain
& refch
)
9410 if (checked
) return;
9411 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9412 FATAL_ERROR("Value::chk_ROID()");
9413 if (!refch
.add(get_fullname())) {
9417 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9419 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9424 void Value::chk_recursions(ReferenceChain
& refch
)
9426 if (recurs_checked
) return;
9427 Value
*v
= get_value_refd_last();
9428 if (refch
.add(v
->get_fullname())) {
9429 switch (v
->valuetype
) {
9431 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9436 if (!v
->is_indexed()) {
9437 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9439 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9443 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9445 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9446 ->chk_recursions(refch
);
9453 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9455 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9460 chk_recursions_expr(refch
);
9465 if (v
->err_descr
) { // FIXME: make this work
9466 v
->err_descr
->chk_recursions(refch
);
9469 recurs_checked
= true;
9472 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9474 // first classify the unchecked ischosen() operation
9475 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9476 switch (u
.expr
.v_optype
) {
9477 case OPTYPE_UNARYPLUS
: // v1
9478 case OPTYPE_UNARYMINUS
:
9481 case OPTYPE_BIT2HEX
:
9482 case OPTYPE_BIT2INT
:
9483 case OPTYPE_BIT2OCT
:
9484 case OPTYPE_BIT2STR
:
9485 case OPTYPE_CHAR2INT
:
9486 case OPTYPE_CHAR2OCT
:
9487 case OPTYPE_FLOAT2INT
:
9488 case OPTYPE_FLOAT2STR
:
9489 case OPTYPE_HEX2BIT
:
9490 case OPTYPE_HEX2INT
:
9491 case OPTYPE_HEX2OCT
:
9492 case OPTYPE_HEX2STR
:
9493 case OPTYPE_INT2CHAR
:
9494 case OPTYPE_INT2FLOAT
:
9495 case OPTYPE_INT2STR
:
9496 case OPTYPE_INT2UNICHAR
:
9497 case OPTYPE_OCT2BIT
:
9498 case OPTYPE_OCT2CHAR
:
9499 case OPTYPE_OCT2HEX
:
9500 case OPTYPE_OCT2INT
:
9501 case OPTYPE_OCT2STR
:
9502 case OPTYPE_STR2BIT
:
9503 case OPTYPE_STR2FLOAT
:
9504 case OPTYPE_STR2HEX
:
9505 case OPTYPE_STR2INT
:
9506 case OPTYPE_STR2OCT
:
9507 case OPTYPE_UNICHAR2INT
:
9508 case OPTYPE_ENUM2INT
:
9509 case OPTYPE_UNICHAR2CHAR
:
9510 case OPTYPE_RNDWITHVAL
:
9511 case OPTYPE_ISCHOSEN_V
:
9512 case OPTYPE_GET_STRINGENCODING
:
9513 case OPTYPE_REMOVE_BOM
:
9514 case OPTYPE_DECODE_BASE64
:
9516 u
.expr
.v1
->chk_recursions(refch
);
9519 case OPTYPE_ISCHOSEN_T
:
9521 u
.expr
.t1
->chk_recursions(refch
);
9524 case OPTYPE_ADD
: // v1 v2
9525 case OPTYPE_SUBTRACT
:
9526 case OPTYPE_MULTIPLY
:
9547 case OPTYPE_INT2BIT
:
9548 case OPTYPE_INT2HEX
:
9549 case OPTYPE_INT2OCT
:
9551 u
.expr
.v1
->chk_recursions(refch
);
9554 u
.expr
.v2
->chk_recursions(refch
);
9557 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9558 case OPTYPE_OCT2UNICHAR
:
9559 case OPTYPE_ENCODE_BASE64
:
9561 u
.expr
.v1
->chk_recursions(refch
);
9565 u
.expr
.v2
->chk_recursions(refch
);
9570 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9571 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9575 u
.expr
.ti1
->chk_recursions(refch
);
9578 u
.expr
.v2
->chk_recursions(refch
);
9581 u
.expr
.v3
->chk_recursions(refch
);
9586 u
.expr
.ti1
->chk_recursions(refch
);
9589 u
.expr
.t2
->chk_recursions(refch
);
9592 u
.expr
.v3
->chk_recursions(refch
);
9595 case OPTYPE_DECOMP
: // v1 v2 v3
9597 u
.expr
.v1
->chk_recursions(refch
);
9600 u
.expr
.v2
->chk_recursions(refch
);
9603 u
.expr
.v3
->chk_recursions(refch
);
9606 case OPTYPE_REPLACE
:
9608 u
.expr
.ti1
->chk_recursions(refch
);
9611 u
.expr
.v2
->chk_recursions(refch
);
9614 u
.expr
.v3
->chk_recursions(refch
);
9617 u
.expr
.ti4
->chk_recursions(refch
);
9620 case OPTYPE_LENGTHOF
: // ti1
9621 case OPTYPE_SIZEOF
: // ti1
9622 case OPTYPE_VALUEOF
: // ti1
9624 case OPTYPE_ISPRESENT
:
9625 case OPTYPE_TTCN2STRING
:
9627 u
.expr
.ti1
->chk_recursions(refch
);
9630 case OPTYPE_MATCH
: // v1 t2
9632 u
.expr
.v1
->chk_recursions(refch
);
9635 u
.expr
.t2
->chk_recursions(refch
);
9638 case OPTYPE_LOG2STR
:
9639 u
.expr
.logargs
->chk_recursions(refch
);
9646 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9647 ReferenceChain
& refch
) {
9648 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9649 Assignment
*ass
= ref
->get_refd_assignment();
9651 set_valuetype(V_ERROR
);
9654 switch (ass
->get_asstype()) {
9655 case Assignment::A_CONST
:
9656 case Assignment::A_EXT_CONST
:
9657 case Assignment::A_MODULEPAR
:
9658 case Assignment::A_VAR
:
9659 case Assignment::A_PAR_VAL_IN
:
9660 case Assignment::A_PAR_VAL_OUT
:
9661 case Assignment::A_PAR_VAL_INOUT
: {
9662 Value
* v
= new Value(V_REFD
, ref
);
9663 v
->set_location(*ref
);
9664 v
->set_my_scope(get_my_scope());
9665 v
->set_fullname(get_fullname()+".<operand>");
9667 v
->chk_recursions(refch
);
9671 case Assignment::A_MODULEPAR_TEMP
:
9672 case Assignment::A_TEMPLATE
:
9673 case Assignment::A_VAR_TEMPLATE
:
9674 case Assignment::A_PAR_TEMPL_IN
:
9675 case Assignment::A_PAR_TEMPL_OUT
:
9676 case Assignment::A_PAR_TEMPL_INOUT
: {
9677 Template
* t
= new Template(ref
->clone());
9678 t
->set_location(*ref
);
9679 t
->set_my_scope(get_my_scope());
9680 t
->set_fullname(get_fullname()+".<operand>");
9682 t
->chk_recursions(refch
);
9687 // remain silent, the error has been already reported
9688 set_valuetype(V_ERROR
);
9693 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9695 bool self_ref
= false;
9696 switch (t
->get_templatetype()) {
9697 case Ttcn::Template::SPECIFIC_VALUE
: {
9698 Value
*v
= t
->get_specific_value();
9699 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9700 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9701 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9703 case Ttcn::Template::TEMPLATE_REFD
: {
9704 Ttcn::Ref_base
*refb
= t
->get_reference();
9705 Common::Assignment
*ass
= refb
->get_refd_assignment();
9706 self_ref
|= (ass
== lhs
);
9708 case Ttcn::Template::ALL_FROM
:
9709 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9710 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9712 case Ttcn::Template::TEMPLATE_LIST
:
9713 case Ttcn::Template::SUPERSET_MATCH
:
9714 case Ttcn::Template::SUBSET_MATCH
:
9715 case Ttcn::Template::PERMUTATION_MATCH
:
9716 case Ttcn::Template::COMPLEMENTED_LIST
:
9717 case Ttcn::Template::VALUE_LIST
: {
9718 size_t num
= t
->get_nof_comps();
9719 for (size_t i
= 0; i
< num
; ++i
) {
9720 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9723 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9724 // case Ttcn::Template::TEMPLATE_LIST: {
9725 // size_t num = t->get_nof_listitems();
9726 // for (size_t i=0; i < num; ++i) {
9727 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9730 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9731 size_t nnt
= t
->get_nof_comps();
9732 for (size_t i
=0; i
< nnt
; ++i
) {
9733 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9734 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9737 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9738 size_t nnt
= t
->get_nof_comps();
9739 for (size_t i
=0; i
< nnt
; ++i
) {
9740 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9741 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9744 case Ttcn::Template::VALUE_RANGE
: {
9745 Ttcn::ValueRange
*vr
= t
->get_value_range();
9746 Common::Value
*v
= vr
->get_min_v();
9747 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9748 v
= vr
->get_max_v();
9749 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9751 case Ttcn::Template::CSTR_PATTERN
:
9752 case Ttcn::Template::USTR_PATTERN
: {
9753 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9754 self_ref
|= ps
->chk_self_ref(lhs
);
9756 case Ttcn::Template::BSTR_PATTERN
:
9757 case Ttcn::Template::HSTR_PATTERN
:
9758 case Ttcn::Template::OSTR_PATTERN
: {
9759 // FIXME: cannot access u.pattern
9761 case Ttcn::Template::ANY_VALUE
:
9762 case Ttcn::Template::ANY_OR_OMIT
:
9763 case Ttcn::Template::OMIT_VALUE
:
9764 case Ttcn::Template::TEMPLATE_NOTUSED
:
9765 break; // self-ref can't happen
9766 case Ttcn::Template::TEMPLATE_INVOKE
:
9767 break; // assume self-ref can't happen
9768 case Ttcn::Template::TEMPLATE_ERROR
:
9769 FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9770 break; // not reached
9772 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9773 // break; // and hope for the best
9778 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
9780 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
9781 namedbool is_str_elem
= NOT_STR_ELEM
;
9782 if (v
->valuetype
== V_REFD
) {
9783 Reference
*ref
= v
->get_reference();
9784 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
9785 if (subrefs
&& subrefs
->refers_to_string_element()) {
9786 is_str_elem
= IS_STR_ELEM
;
9789 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9790 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
9794 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
9796 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
9797 if (!lhs
) FATAL_ERROR("no lhs!");
9798 bool self_ref
= false;
9799 switch (u
.expr
.v_optype
) {
9800 case OPTYPE_RND
: // -
9801 case OPTYPE_TESTCASENAME
: // -
9802 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
9803 case OPTYPE_COMP_MTC
: // -
9804 case OPTYPE_COMP_SYSTEM
: // -
9805 case OPTYPE_COMP_SELF
: // -
9806 case OPTYPE_COMP_RUNNING_ANY
: // -
9807 case OPTYPE_COMP_RUNNING_ALL
: // -
9808 case OPTYPE_COMP_ALIVE_ANY
: // -
9809 case OPTYPE_COMP_ALIVE_ALL
: // -
9810 case OPTYPE_TMR_RUNNING_ANY
: // -
9811 case OPTYPE_GETVERDICT
: // -
9812 case OPTYPE_PROF_RUNNING
: // -
9813 break; // nothing to do
9815 case OPTYPE_MATCH
: // v1 t2
9816 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9818 case OPTYPE_UNARYPLUS
: // v1
9819 case OPTYPE_UNARYMINUS
: // v1
9820 case OPTYPE_NOT
: // v1
9821 case OPTYPE_NOT4B
: // v1
9822 case OPTYPE_BIT2HEX
: // v1
9823 case OPTYPE_BIT2INT
: // v1
9824 case OPTYPE_BIT2OCT
: // v1
9825 case OPTYPE_BIT2STR
: // v1
9826 case OPTYPE_CHAR2INT
: // v1
9827 case OPTYPE_CHAR2OCT
: // v1
9828 case OPTYPE_FLOAT2INT
: // v1
9829 case OPTYPE_FLOAT2STR
: // v1
9830 case OPTYPE_HEX2BIT
: // v1
9831 case OPTYPE_HEX2INT
: // v1
9832 case OPTYPE_HEX2OCT
: // v1
9833 case OPTYPE_HEX2STR
: // v1
9834 case OPTYPE_INT2CHAR
: // v1
9835 case OPTYPE_INT2FLOAT
: // v1
9836 case OPTYPE_INT2STR
: // v1
9837 case OPTYPE_INT2UNICHAR
: // v1
9838 case OPTYPE_OCT2BIT
: // v1
9839 case OPTYPE_OCT2CHAR
: // v1
9840 case OPTYPE_OCT2HEX
: // v1
9841 case OPTYPE_OCT2INT
: // v1
9842 case OPTYPE_OCT2STR
: // v1
9843 case OPTYPE_STR2BIT
: // v1
9844 case OPTYPE_STR2FLOAT
: // v1
9845 case OPTYPE_STR2HEX
: // v1
9846 case OPTYPE_STR2INT
: // v1
9847 case OPTYPE_STR2OCT
: // v1
9848 case OPTYPE_UNICHAR2INT
: // v1
9849 case OPTYPE_UNICHAR2CHAR
: // v1
9850 case OPTYPE_ENUM2INT
: // v1
9851 case OPTYPE_RNDWITHVAL
: // v1
9852 case OPTYPE_COMP_RUNNING
: // v1
9853 case OPTYPE_COMP_ALIVE
: // v1
9854 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
9855 case OPTYPE_GET_STRINGENCODING
:
9856 case OPTYPE_DECODE_BASE64
:
9857 case OPTYPE_REMOVE_BOM
:
9858 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9860 case OPTYPE_ADD
: // v1 v2
9861 case OPTYPE_SUBTRACT
: // v1 v2
9862 case OPTYPE_MULTIPLY
: // v1 v2
9863 case OPTYPE_DIVIDE
: // v1 v2
9864 case OPTYPE_MOD
: // v1 v2
9865 case OPTYPE_REM
: // v1 v2
9866 case OPTYPE_CONCAT
: // v1 v2
9867 case OPTYPE_EQ
: // v1 v2
9868 case OPTYPE_LT
: // v1 v2
9869 case OPTYPE_GT
: // v1 v2
9870 case OPTYPE_NE
: // v1 v2
9871 case OPTYPE_GE
: // v1 v2
9872 case OPTYPE_LE
: // v1 v2
9873 case OPTYPE_AND
: // v1 v2
9874 case OPTYPE_OR
: // v1 v2
9875 case OPTYPE_XOR
: // v1 v2
9876 case OPTYPE_AND4B
: // v1 v2
9877 case OPTYPE_OR4B
: // v1 v2
9878 case OPTYPE_XOR4B
: // v1 v2
9879 case OPTYPE_SHL
: // v1 v2
9880 case OPTYPE_SHR
: // v1 v2
9881 case OPTYPE_ROTL
: // v1 v2
9882 case OPTYPE_ROTR
: // v1 v2
9883 case OPTYPE_INT2BIT
: // v1 v2
9884 case OPTYPE_INT2HEX
: // v1 v2
9885 case OPTYPE_INT2OCT
: // v1 v2
9886 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9887 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9889 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9890 case OPTYPE_OCT2UNICHAR
:
9891 case OPTYPE_ENCODE_BASE64
:
9892 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9893 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9895 case OPTYPE_DECOMP
: // v1 v2 v3
9896 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9897 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9898 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9901 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
9902 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
9904 case OPTYPE_SUBSTR
: // ti1 v2 v3
9905 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9906 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
9907 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
9910 case OPTYPE_REGEXP
: // ti1 t2 v3
9911 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9912 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9914 case OPTYPE_LENGTHOF
: // ti1
9915 case OPTYPE_SIZEOF
: // ti1
9916 case OPTYPE_VALUEOF
: // ti1
9917 case OPTYPE_ENCODE
: // ti1
9918 case OPTYPE_TTCN2STRING
:
9919 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9922 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
9923 // component.create -- assume no self-ref
9924 case OPTYPE_ACTIVATE
: // r1
9925 // defaultref := activate(altstep) -- assume no self-ref
9926 case OPTYPE_TMR_RUNNING
: // r1
9927 // boolvar := a_timer.running -- assume no self-ref
9931 case OPTYPE_LOG2STR
: {// logargs
9932 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
9933 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
9934 switch (la
->get_type()) {
9935 case Ttcn::LogArgument::L_UNDEF
:
9936 case Ttcn::LogArgument::L_ERROR
:
9937 FATAL_ERROR("log2str argument type");
9938 break; // not reached
9940 case Ttcn::LogArgument::L_MACRO
:
9941 case Ttcn::LogArgument::L_STR
:
9942 break; // self reference not possible
9944 case Ttcn::LogArgument::L_VAL
:
9945 case Ttcn::LogArgument::L_MATCH
:
9946 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
9949 case Ttcn::LogArgument::L_REF
: {
9950 Ttcn::Ref_base
*ref
= la
->get_ref();
9951 Common::Assignment
*ass
= ref
->get_refd_assignment();
9952 self_ref
|= (ass
== lhs
);
9955 case Ttcn::LogArgument::L_TI
: {
9956 Ttcn::TemplateInstance
*ti
= la
->get_ti();
9957 Ttcn::Template
*t
= ti
->get_Template();
9958 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
9961 // no default please
9962 } // switch la->logargtype
9966 case OPTYPE_DECODE
: { // r1 r2
9967 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
9968 self_ref
|= (ass
== lhs
);
9970 case OPTYPE_EXECUTE
: // r1 [v2]
9972 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9976 case OPTYPE_UNDEF_RUNNING
: // r1
9977 case OPTYPE_TMR_READ
: { // r1
9978 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
9979 self_ref
|= (ass
== lhs
);
9982 case OPTYPE_ISCHOSEN_T
: // t1 i2
9983 case OPTYPE_ISBOUND
: // ti1
9984 case OPTYPE_ISVALUE
: // ti1
9985 case OPTYPE_ISPRESENT
: { // ti1
9987 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
9988 else t
= u
.expr
.ti1
->get_Template();
9989 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
9992 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
9994 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9997 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
9998 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10002 case NUMBER_OF_OPTYPES
: // can never happen
10003 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10004 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10006 } // switch u.expr.v_optype
10011 string
Value::create_stringRepr()
10013 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10014 switch (valuetype
) {
10016 return string("<erroneous>");
10018 return string("NULL");
10020 if (!parse_only
&& is_asn1()) {
10021 if (u
.val_bool
) return string("TRUE");
10022 else return string("FALSE");
10025 if (u
.val_bool
) return string("true");
10026 else return string("false");
10029 return u
.val_Int
->t_str();
10031 return Real2string(u
.val_Real
);
10034 case V_UNDEF_LOWERID
:
10035 return u
.val_id
->get_name();
10036 case V_NAMEDBITS
: {
10037 string
ret_val("{ ");
10038 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10039 if (i
>0) ret_val
+= ' ';
10040 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10045 string
ret_val('\'');
10046 ret_val
+= *u
.str
.val_str
;
10050 string
ret_val('\'');
10051 ret_val
+= *u
.str
.val_str
;
10055 string
ret_val('\'');
10056 ret_val
+= *u
.str
.val_str
;
10061 return u
.str
.val_str
->get_stringRepr();
10063 return u
.ustr
.val_ustr
->get_stringRepr();
10065 /** \todo stringrepr of V_CHARSYMS */
10066 return string("<sorry, string representation of charsyms "
10067 "not implemented>");
10071 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10073 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10074 if (i
>0) ret_val
+= ' ';
10075 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10080 if (!parse_only
&& is_asn1()) {
10081 string
ret_val(u
.choice
.alt_name
->get_dispname());
10083 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10087 string
ret_val("{ ");
10088 ret_val
+= u
.choice
.alt_name
->get_dispname();
10090 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10097 string
ret_val("{ ");
10098 if (!is_indexed()) {
10099 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10100 if (i
> 0) ret_val
+= ", ";
10101 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10104 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10105 if (i
> 0) ret_val
+= ", ";
10106 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10113 string
ret_val("{ ");
10114 bool asn1_flag
= !parse_only
&& is_asn1();
10115 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10116 if (i
> 0) ret_val
+= ", ";
10117 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10118 ret_val
+= nv
->get_name().get_dispname();
10119 if (asn1_flag
) ret_val
+= ' ';
10120 else ret_val
+= " := ";
10121 ret_val
+= nv
->get_value()->get_stringRepr();
10126 // do not evaluate the reference if it is not done so far
10127 // (e.g. in parse-only mode)
10128 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10129 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10130 else return t_val
->get_stringRepr(); }
10132 return string("omit");
10134 switch (u
.verdict
) {
10136 return string("none");
10138 return string("pass");
10139 case Verdict_INCONC
:
10140 return string("inconc");
10142 return string("fail");
10143 case Verdict_ERROR
:
10144 return string("error");
10146 return string("<unknown verdict value>");
10148 case V_DEFAULT_NULL
:
10150 return string("null");
10152 switch (u
.expr
.v_optype
) {
10154 return string("rnd()");
10155 case OPTYPE_TESTCASENAME
:
10156 return string("testcasename()");
10157 case OPTYPE_UNARYPLUS
:
10158 return create_stringRepr_unary("+");
10159 case OPTYPE_UNARYMINUS
:
10160 return create_stringRepr_unary("-");
10162 return create_stringRepr_unary("not");
10164 return create_stringRepr_unary("not4b");
10165 case OPTYPE_BIT2HEX
:
10166 return create_stringRepr_predef1("bit2hex");
10167 case OPTYPE_BIT2INT
:
10168 return create_stringRepr_predef1("bit2int");
10169 case OPTYPE_BIT2OCT
:
10170 return create_stringRepr_predef1("bit2oct");
10171 case OPTYPE_BIT2STR
:
10172 return create_stringRepr_predef1("bit2str");
10173 case OPTYPE_CHAR2INT
:
10174 return create_stringRepr_predef1("char2int");
10175 case OPTYPE_CHAR2OCT
:
10176 return create_stringRepr_predef1("char2oct");
10177 case OPTYPE_FLOAT2INT
:
10178 return create_stringRepr_predef1("float2int");
10179 case OPTYPE_FLOAT2STR
:
10180 return create_stringRepr_predef1("float2str");
10181 case OPTYPE_HEX2BIT
:
10182 return create_stringRepr_predef1("hex2bit");
10183 case OPTYPE_HEX2INT
:
10184 return create_stringRepr_predef1("hex2int");
10185 case OPTYPE_HEX2OCT
:
10186 return create_stringRepr_predef1("hex2oct");
10187 case OPTYPE_HEX2STR
:
10188 return create_stringRepr_predef1("hex2str");
10189 case OPTYPE_INT2CHAR
:
10190 return create_stringRepr_predef1("int2char");
10191 case OPTYPE_INT2FLOAT
:
10192 return create_stringRepr_predef1("int2float");
10193 case OPTYPE_INT2STR
:
10194 return create_stringRepr_predef1("int2str");
10195 case OPTYPE_INT2UNICHAR
:
10196 return create_stringRepr_predef1("int2unichar");
10197 case OPTYPE_OCT2BIT
:
10198 return create_stringRepr_predef1("oct2bit");
10199 case OPTYPE_OCT2CHAR
:
10200 return create_stringRepr_predef1("oct2char");
10201 case OPTYPE_OCT2HEX
:
10202 return create_stringRepr_predef1("oct2hex");
10203 case OPTYPE_OCT2INT
:
10204 return create_stringRepr_predef1("oct2int");
10205 case OPTYPE_OCT2STR
:
10206 return create_stringRepr_predef1("oct2str");
10207 case OPTYPE_GET_STRINGENCODING
:
10208 return create_stringRepr_predef1("get_stringencoding");
10209 case OPTYPE_REMOVE_BOM
:
10210 return create_stringRepr_predef1("remove_bom");
10211 case OPTYPE_ENCODE_BASE64
: {
10212 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10213 else return create_stringRepr_predef1("encode_base64");
10215 case OPTYPE_DECODE_BASE64
:
10216 return create_stringRepr_predef1("decode_base64");
10217 case OPTYPE_OCT2UNICHAR
:{
10218 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10219 else return create_stringRepr_predef1("oct2unichar");
10221 case OPTYPE_UNICHAR2OCT
: {
10222 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10223 else return create_stringRepr_predef1("unichar2oct");
10225 case OPTYPE_STR2BIT
:
10226 return create_stringRepr_predef1("str2bit");
10227 case OPTYPE_STR2FLOAT
:
10228 return create_stringRepr_predef1("str2float");
10229 case OPTYPE_STR2HEX
:
10230 return create_stringRepr_predef1("str2hex");
10231 case OPTYPE_STR2INT
:
10232 return create_stringRepr_predef1("str2int");
10233 case OPTYPE_STR2OCT
:
10234 return create_stringRepr_predef1("str2oct");
10235 case OPTYPE_UNICHAR2INT
:
10236 return create_stringRepr_predef1("unichar2int");
10237 case OPTYPE_UNICHAR2CHAR
:
10238 return create_stringRepr_predef1("unichar2char");
10239 case OPTYPE_ENUM2INT
:
10240 return create_stringRepr_predef1("enum2int");
10241 case OPTYPE_ENCODE
:
10242 return create_stringRepr_predef1("encvalue");
10243 case OPTYPE_DECODE
:
10244 return create_stringRepr_predef2("decvalue");
10245 case OPTYPE_RNDWITHVAL
:
10246 return create_stringRepr_predef1("rnd");
10248 return create_stringRepr_infix("+");
10249 case OPTYPE_SUBTRACT
:
10250 return create_stringRepr_infix("-");
10251 case OPTYPE_MULTIPLY
:
10252 return create_stringRepr_infix("*");
10253 case OPTYPE_DIVIDE
:
10254 return create_stringRepr_infix("/");
10256 return create_stringRepr_infix("mod");
10258 return create_stringRepr_infix("rem");
10259 case OPTYPE_CONCAT
:
10260 return create_stringRepr_infix("&");
10262 return create_stringRepr_infix("==");
10264 return create_stringRepr_infix("<");
10266 return create_stringRepr_infix(">");
10268 return create_stringRepr_infix("!=");
10270 return create_stringRepr_infix(">=");
10272 return create_stringRepr_infix("<=");
10274 return create_stringRepr_infix("and");
10276 return create_stringRepr_infix("or");
10278 return create_stringRepr_infix("xor");
10280 return create_stringRepr_infix("and4b");
10282 return create_stringRepr_infix("or4b");
10284 return create_stringRepr_infix("xor4b");
10286 return create_stringRepr_infix("<<");
10288 return create_stringRepr_infix(">>");
10290 return create_stringRepr_infix("<@");
10292 return create_stringRepr_infix("@>");
10293 case OPTYPE_INT2BIT
:
10294 return create_stringRepr_predef2("int2bit");
10295 case OPTYPE_INT2HEX
:
10296 return create_stringRepr_predef2("int2hex");
10297 case OPTYPE_INT2OCT
:
10298 return create_stringRepr_predef2("int2oct");
10299 case OPTYPE_SUBSTR
: {
10300 string
ret_val("substr(");
10301 u
.expr
.ti1
->append_stringRepr(ret_val
);
10303 ret_val
+= u
.expr
.v2
->get_stringRepr();
10305 ret_val
+= u
.expr
.v3
->get_stringRepr();
10309 case OPTYPE_REGEXP
: {
10310 string
ret_val("regexp(");
10311 u
.expr
.ti1
->append_stringRepr(ret_val
);
10313 u
.expr
.t2
->append_stringRepr(ret_val
);
10315 ret_val
+= u
.expr
.v3
->get_stringRepr();
10319 case OPTYPE_DECOMP
: {
10320 string
ret_val("decomp(");
10321 ret_val
+= u
.expr
.v1
->get_stringRepr();
10323 ret_val
+= u
.expr
.v2
->get_stringRepr();
10325 ret_val
+= u
.expr
.v3
->get_stringRepr();
10329 case OPTYPE_REPLACE
: {
10330 string
ret_val("replace(");
10331 u
.expr
.ti1
->append_stringRepr(ret_val
);
10333 ret_val
+= u
.expr
.v2
->get_stringRepr();
10335 ret_val
+= u
.expr
.v3
->get_stringRepr();
10337 u
.expr
.ti4
->append_stringRepr(ret_val
);
10341 case OPTYPE_ISPRESENT
: {
10342 string
ret_val("ispresent(");
10343 u
.expr
.ti1
->append_stringRepr(ret_val
);
10346 case OPTYPE_ISCHOSEN
: {
10347 string
ret_val("ischosen(");
10348 ret_val
+= u
.expr
.r1
->get_dispname();
10350 ret_val
+= u
.expr
.i2
->get_dispname();
10353 case OPTYPE_ISCHOSEN_V
: {
10354 string
ret_val("ischosen(");
10355 ret_val
+= u
.expr
.v1
->get_stringRepr();
10357 ret_val
+= u
.expr
.i2
->get_dispname();
10360 case OPTYPE_ISCHOSEN_T
: {
10361 string
ret_val("ischosen(");
10362 ret_val
+= u
.expr
.t1
->get_stringRepr();
10364 ret_val
+= u
.expr
.i2
->get_dispname();
10367 case OPTYPE_LENGTHOF
: {
10368 string
ret_val("lengthof(");
10369 u
.expr
.ti1
->append_stringRepr(ret_val
);
10372 case OPTYPE_SIZEOF
: {
10373 string
ret_val("sizeof(");
10374 u
.expr
.ti1
->append_stringRepr(ret_val
);
10377 case OPTYPE_ISVALUE
: {
10378 string
ret_val("isvalue(");
10379 u
.expr
.ti1
->append_stringRepr(ret_val
);
10382 case OPTYPE_VALUEOF
: {
10383 string
ret_val("valueof(");
10384 u
.expr
.ti1
->append_stringRepr(ret_val
);
10387 case OPTYPE_LOG2STR
:
10388 return string("log2str(...)");
10389 case OPTYPE_MATCH
: {
10390 string
ret_val("match(");
10391 ret_val
+= u
.expr
.v1
->get_stringRepr();
10393 u
.expr
.t2
->append_stringRepr(ret_val
);
10396 case OPTYPE_TTCN2STRING
: {
10397 string
ret_val("ttcn2string(");
10398 u
.expr
.ti1
->append_stringRepr(ret_val
);
10402 case OPTYPE_UNDEF_RUNNING
:
10403 return u
.expr
.r1
->get_dispname() + ".running";
10404 case OPTYPE_COMP_NULL
:
10405 return string("null");
10406 case OPTYPE_COMP_MTC
:
10407 return string("mtc");
10408 case OPTYPE_COMP_SYSTEM
:
10409 return string("system");
10410 case OPTYPE_COMP_SELF
:
10411 return string("self");
10412 case OPTYPE_COMP_CREATE
: {
10413 string
ret_val(u
.expr
.r1
->get_dispname());
10414 ret_val
+= ".create";
10415 if (u
.expr
.v2
|| u
.expr
.v3
) {
10417 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10418 else ret_val
+= '-';
10421 ret_val
+= u
.expr
.v3
->get_stringRepr();
10425 if (u
.expr
.b4
) ret_val
+= " alive";
10427 case OPTYPE_COMP_RUNNING
:
10428 return u
.expr
.v1
->get_stringRepr() + ".running";
10429 case OPTYPE_COMP_RUNNING_ANY
:
10430 return string("any component.running");
10431 case OPTYPE_COMP_RUNNING_ALL
:
10432 return string("all component.running");
10433 case OPTYPE_COMP_ALIVE
:
10434 return u
.expr
.v1
->get_stringRepr() + ".alive";
10435 case OPTYPE_COMP_ALIVE_ANY
:
10436 return string("any component.alive");
10437 case OPTYPE_COMP_ALIVE_ALL
:
10438 return string("all component.alive");
10439 case OPTYPE_TMR_READ
:
10440 return u
.expr
.r1
->get_dispname() + ".read";
10441 case OPTYPE_TMR_RUNNING
:
10442 return u
.expr
.r1
->get_dispname() + ".running";
10443 case OPTYPE_TMR_RUNNING_ANY
:
10444 return string("any timer.running");
10445 case OPTYPE_GETVERDICT
:
10446 return string("getverdict");
10447 case OPTYPE_ACTIVATE
: {
10448 string
ret_val("activate(");
10449 ret_val
+= u
.expr
.r1
->get_dispname();
10452 case OPTYPE_ACTIVATE_REFD
: {
10453 string
ret_val("activate(derefer(");
10454 ret_val
+= u
.expr
.v1
->get_stringRepr();
10456 if (u
.expr
.state
== EXPR_CHECKED
) {
10457 if (u
.expr
.ap_list2
) {
10458 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10459 for (size_t i
= 0; i
< nof_pars
; i
++) {
10460 if (i
> 0) ret_val
+= ", ";
10461 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10465 if (u
.expr
.t_list2
) {
10466 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10467 for (size_t i
= 0; i
< nof_pars
; i
++) {
10468 if (i
> 0) ret_val
+= ", ";
10469 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10475 case OPTYPE_EXECUTE
: {
10476 string
ret_val("execute(");
10477 ret_val
+= u
.expr
.r1
->get_dispname();
10480 ret_val
+= u
.expr
.v2
->get_stringRepr();
10484 case OPTYPE_EXECUTE_REFD
: {
10485 string
ret_val("execute(derefers(");
10486 ret_val
+= u
.expr
.v1
->get_stringRepr();
10488 if (u
.expr
.state
== EXPR_CHECKED
) {
10489 if (u
.expr
.ap_list2
) {
10490 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10491 for (size_t i
= 0; i
< nof_pars
; i
++) {
10492 if (i
> 0) ret_val
+= ", ";
10493 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10497 if (u
.expr
.t_list2
) {
10498 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10499 for (size_t i
= 0; i
< nof_pars
; i
++) {
10500 if (i
> 0) ret_val
+= ", ";
10501 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10508 ret_val
+= u
.expr
.v3
->get_stringRepr();
10512 case OPTYPE_PROF_RUNNING
:
10513 return string("@profiler.running");
10515 return string("<unsupported optype>");
10516 } // switch u.expr.v_optype
10519 case MACRO_MODULEID
:
10520 return string("%moduleId");
10521 case MACRO_FILENAME
:
10522 return string("%fileName");
10523 case MACRO_BFILENAME
:
10524 return string("__BFILE__");
10525 case MACRO_FILEPATH
:
10526 return string("__FILE__");
10527 case MACRO_LINENUMBER
:
10528 return string("%lineNumber");
10529 case MACRO_LINENUMBER_C
:
10530 return string("__LINE__");
10531 case MACRO_DEFINITIONID
:
10532 return string("%definitionId");
10534 return string("__SCOPE__");
10535 case MACRO_TESTCASEID
:
10536 return string("%testcaseId");
10538 return string("<unknown macro>");
10539 } // switch u.macro
10541 return string('-');
10545 string
ret_val("refers(");
10546 ret_val
+= u
.refd_fat
->get_assname();
10551 ret_val
+= u
.invoke
.v
->get_stringRepr();
10552 ret_val
+= ".apply(";
10553 if (u
.invoke
.ap_list
) {
10554 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10555 for (size_t i
= 0; i
< nof_pars
; i
++) {
10556 if (i
> 0) ret_val
+= ", ";
10557 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10559 } else if (u
.invoke
.t_list
) {
10560 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10561 for (size_t i
= 0; i
< nof_pars
; i
++) {
10562 if (i
> 0) ret_val
+= ", ";
10563 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10569 string
ret_val("refers(");
10570 ret_val
+= u
.refered
->get_dispname();
10574 return string("<unsupported valuetype>");
10575 } // switch valuetype
10578 string
Value::create_stringRepr_unary(const char *operator_str
)
10580 string
ret_val(operator_str
);
10582 ret_val
+= u
.expr
.v1
->get_stringRepr();
10587 string
Value::create_stringRepr_infix(const char *operator_str
)
10589 string
ret_val('(');
10590 ret_val
+= u
.expr
.v1
->get_stringRepr();
10592 ret_val
+= operator_str
;
10594 ret_val
+= u
.expr
.v2
->get_stringRepr();
10599 string
Value::create_stringRepr_predef1(const char *function_name
)
10601 string
ret_val(function_name
);
10603 if (u
.expr
.v_optype
== OPTYPE_ENCODE
) { // ti1, not v1
10604 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10606 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10611 string
Value::create_stringRepr_predef2(const char *function_name
)
10613 string
ret_val(function_name
);
10615 ret_val
+= u
.expr
.v1
->get_stringRepr();
10617 ret_val
+= u
.expr
.v2
->get_stringRepr();
10622 bool Value::operator==(Value
& val
)
10624 Value
*left
= get_value_refd_last();
10625 Type
*left_governor
= left
->get_my_governor();
10626 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10627 Value
*right
= val
.get_value_refd_last();
10628 Type
*right_governor
= right
->get_my_governor();
10629 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10630 if (left_governor
&& right_governor
10631 && !left_governor
->is_compatible(right_governor
, NULL
)
10632 && !right_governor
->is_compatible(left_governor
, NULL
))
10633 FATAL_ERROR("Value::operator==");
10635 // Not-A-Value is not equal to anything (NaN analogy:)
10636 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10639 switch (left
->valuetype
) {
10642 case V_DEFAULT_NULL
:
10645 return left
->valuetype
== right
->valuetype
;
10647 return right
->valuetype
== V_BOOL
&&
10648 left
->get_val_bool() == right
->get_val_bool();
10650 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10651 == *right
->get_val_Int();
10653 return right
->valuetype
== V_REAL
&&
10654 left
->get_val_Real() == right
->get_val_Real();
10656 switch (right
->valuetype
) {
10658 return left
->get_val_str() == right
->get_val_str();
10660 return right
->get_val_ustr() == left
->get_val_str();
10662 return right
->get_val_iso2022str() == left
->get_val_str();
10669 return left
->valuetype
== right
->valuetype
&&
10670 left
->get_val_str() == right
->get_val_str();
10672 switch (right
->valuetype
) {
10674 return left
->get_val_ustr() == right
->get_val_str();
10676 return left
->get_val_ustr() == right
->get_val_ustr();
10678 return left
->get_val_ustr() == right
->get_val_iso2022str();
10683 switch (right
->valuetype
) {
10685 return left
->get_val_iso2022str() == right
->get_val_str();
10687 // The appropriate operator==() is missing. The operands are swapped,
10688 // but it shouldn't be a problem.
10689 return right
->get_val_ustr() == left
->get_val_iso2022str();
10691 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10696 return right
->valuetype
== V_ENUM
&&
10697 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10700 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10701 vector
<string
> act
, other
;
10702 get_oid_comps(act
);
10703 val
.get_oid_comps(other
);
10704 size_t act_size
= act
.size(), other_size
= other
.size();
10706 if (act_size
== other_size
) {
10708 for (size_t i
= 0; i
< act_size
; i
++)
10709 if (*act
[i
] != *other
[i
]) {
10713 } else ret_val
= false;
10714 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10716 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10719 } else return false;
10721 return right
->valuetype
== V_CHOICE
&&
10722 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10723 *(left
->get_alt_value()) == *(right
->get_alt_value());
10726 if (!left_governor
) FATAL_ERROR("Value::operator==");
10727 if (left
->valuetype
!= right
->valuetype
) return false;
10728 size_t nof_comps
= left_governor
->get_nof_comps();
10729 for (size_t i
= 0; i
< nof_comps
; i
++) {
10730 Value
*lval
= NULL
, *rval
= NULL
;
10731 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10732 const Identifier
& field_name
= cfl
->get_name();
10733 if (left
->has_comp_withName(field_name
)) {
10734 lval
= left
->get_comp_value_byName(field_name
);
10735 if (right
->has_comp_withName(field_name
)) {
10736 rval
= right
->get_comp_value_byName(field_name
);
10737 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10738 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10740 else if (!(*lval
== *rval
))
10743 if (cfl
->has_default()) {
10744 if (!(*lval
== *cfl
->get_defval()))
10747 if (lval
->valuetype
!= V_OMIT
)
10752 if(right
->has_comp_withName(field_name
)) {
10753 rval
= right
->get_comp_value_byName(field_name
);
10754 if(cfl
->has_default()) {
10755 if(rval
->valuetype
==V_OMIT
) return false;
10757 lval
= cfl
->get_defval();
10758 if (!(*lval
==*rval
)) return false;
10767 if (left
->valuetype
!= right
->valuetype
) return false;
10768 size_t ncomps
= get_nof_comps();
10769 if (ncomps
!= right
->get_nof_comps()) return false;
10771 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
10772 bool found
= false;
10773 map
<IndexedValue
*, void> uncovered
;
10774 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
10775 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
10777 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
10779 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
10780 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
10781 *(right
->get_comp_byIndex(i
)) &&
10782 *(uncovered
.get_nth_key(j
)->get_index()) ==
10783 *(right
->get_index_byIndex(i
))) {
10785 uncovered
.erase(uncovered
.get_nth_key(j
));
10793 } else if (left
->is_indexed() || right
->is_indexed()) {
10794 Value
* indexed_one
= 0;
10795 Value
* not_indexed_one
= 0;
10797 if(left
->is_indexed()) { // left is indexed, right is not
10798 indexed_one
= left
;
10799 not_indexed_one
= right
;
10800 } else { // right indexed, left is not
10801 indexed_one
= right
;
10802 not_indexed_one
= left
;
10805 for(size_t i
= 0; i
< ncomps
; ++i
) {
10806 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
10807 if(!(ind
->valuetype
== V_INT
&&
10808 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
10809 *(indexed_one
->get_comp_byIndex(i
))))
10813 } else { // none of them is indexed
10814 for (size_t i
= 0; i
< ncomps
; i
++) {
10815 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
10822 if (right
->valuetype
!= V_SETOF
) return false;
10823 size_t ncomps
= get_nof_comps();
10824 if (ncomps
!= right
->get_nof_comps()) return false;
10825 if (ncomps
== 0) return true;
10826 map
<size_t, void> uncovered
;
10827 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
10828 for (size_t i
= 0; i
< ncomps
; i
++) {
10829 Value
*left_item
= left
->get_comp_byIndex(i
);
10830 bool pair_found
= false;
10831 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
10832 size_t right_index
= uncovered
.get_nth_key(j
);
10833 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
10834 uncovered
.erase(right_index
);
10846 return right
->valuetype
== V_VERDICT
&&
10847 left
->get_val_verdict() == right
->get_val_verdict();
10851 return left
->valuetype
== right
->valuetype
&&
10852 left
->get_refd_assignment() == right
->get_refd_assignment();
10854 FATAL_ERROR("Value::operator==");
10859 bool Value::operator<(Value
& val
)
10861 Value
*left
= get_value_refd_last();
10862 Type
*left_governor
= left
->get_my_governor();
10863 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
10864 Value
*right
= val
.get_value_refd_last();
10865 Type
*right_governor
= right
->get_my_governor();
10866 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
10867 if (left
->get_valuetype() != right
->get_valuetype())
10868 FATAL_ERROR("Value::operator<");
10871 return *left
->get_val_Int() < *right
->get_val_Int();
10873 return (left
->get_val_Real() < right
->get_val_Real());
10875 if(!left_governor
|| !right_governor
)
10876 FATAL_ERROR("Value::operator<");
10877 if(left_governor
!=right_governor
)
10878 FATAL_ERROR("Value::operator<");
10879 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
10880 right_governor
->get_enum_val_byId(*right
->get_val_id()));
10882 FATAL_ERROR("Value::operator<");
10887 bool Value::is_string_type(Type::expected_value_t exp_val
)
10889 switch (get_expr_returntype(exp_val
)) {
10901 void Value::generate_code_expr(expression_struct
*expr
)
10903 if (has_single_expr()) {
10904 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
10906 switch (valuetype
) {
10908 generate_code_expr_expr(expr
);
10916 const string
& tmp_id
= get_temporary_id();
10917 const char *tmp_id_str
= tmp_id
.c_str();
10918 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
10919 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
10920 set_genname_recursive(tmp_id
);
10921 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10922 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10925 const string
& tmp_id
= get_temporary_id();
10926 const char *tmp_id_str
= tmp_id
.c_str();
10927 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
10929 set_genname_recursive(tmp_id
);
10930 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10931 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10934 if (!get_needs_conversion()) {
10935 u
.ref
.ref
->generate_code_const_ref(expr
);
10937 Type
*my_gov
= get_expr_governor_last();
10938 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
10939 ->get_field_type(u
.ref
.ref
->get_subrefs(),
10940 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
10941 // Make sure that nothing goes wrong.
10942 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
10943 FATAL_ERROR("Value::generate_code_expr()");
10944 expression_struct expr_tmp
;
10945 Code::init_expr(&expr_tmp
);
10946 const string
& tmp_id1
= get_temporary_id();
10947 const char *tmp_id_str1
= tmp_id1
.c_str();
10948 const string
& tmp_id2
= get_temporary_id();
10949 const char *tmp_id_str2
= tmp_id2
.c_str();
10950 expr
->preamble
= mputprintf(expr
->preamble
,
10951 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
10953 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
10954 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
10955 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
10956 expr
->preamble
= mputprintf(expr
->preamble
,
10958 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10959 "and `%s' are not compatible at run-time\");\n",
10960 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
10961 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
10962 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
10963 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
10964 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
10968 generate_code_expr_invoke(expr
);
10971 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
10976 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
10978 generate_code_expr(expr
);
10979 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
10980 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
10983 bool Value::can_use_increment(Reference
*ref
) const
10985 if (valuetype
!= V_EXPR
) {
10988 switch (u
.expr
.v_optype
) {
10990 case OPTYPE_SUBTRACT
:
10995 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
10996 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
10997 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
10998 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
10999 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11000 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11006 char *Value::generate_code_init(char *str
, const char *name
)
11008 if (get_code_generated()) return str
;
11010 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11012 switch (valuetype
) {
11026 case V_DEFAULT_NULL
:
11031 // These values have a single string equivalent.
11032 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11035 if (u
.val_Int
->is_native_fit())
11036 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11038 // It's always an INTEGER.
11039 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11040 "}\n", get_single_expr().c_str(), name
);
11044 expression_struct expr
;
11045 Code::init_expr(&expr
);
11046 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11047 generate_code_expr(&expr
);
11048 str
= Code::merge_free_expr(str
, &expr
);
11051 str
= generate_code_init_choice(str
, name
);
11055 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11056 else str
= generate_code_init_indexed(str
, name
);
11059 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11060 else str
= generate_code_init_indexed(str
, name
);
11064 str
= generate_code_init_se(str
, name
);
11067 str
= generate_code_init_refd(str
, name
);
11071 case MACRO_TESTCASEID
:
11072 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11075 // all others must already be evaluated away
11076 FATAL_ERROR("Value::generate_code_init()");
11080 FATAL_ERROR("Value::generate_code_init()");
11083 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11085 set_code_generated();
11089 char *Value::rearrange_init_code(char *str
)
11091 switch (valuetype
) {
11093 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11095 str
= parlist
->rearrange_init_code(str
,
11096 u
.ref
.ref
->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()
11097 == my_scope
->get_scope_mod_gen());
11101 str
= u
.invoke
.v
->rearrange_init_code(str
);
11102 bool type_is_local
= u
.invoke
.v
->get_expr_governor_last()->get_my_scope()
11103 ->get_scope_mod_gen() == my_scope
->get_scope_mod_gen();
11104 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, type_is_local
);
11107 switch (u
.expr
.v_optype
) {
11108 case OPTYPE_UNARYPLUS
:
11109 case OPTYPE_UNARYMINUS
:
11112 case OPTYPE_BIT2HEX
:
11113 case OPTYPE_BIT2INT
:
11114 case OPTYPE_BIT2OCT
:
11115 case OPTYPE_BIT2STR
:
11116 case OPTYPE_CHAR2INT
:
11117 case OPTYPE_CHAR2OCT
:
11118 case OPTYPE_FLOAT2INT
:
11119 case OPTYPE_FLOAT2STR
:
11120 case OPTYPE_HEX2BIT
:
11121 case OPTYPE_HEX2INT
:
11122 case OPTYPE_HEX2OCT
:
11123 case OPTYPE_HEX2STR
:
11124 case OPTYPE_INT2CHAR
:
11125 case OPTYPE_INT2FLOAT
:
11126 case OPTYPE_INT2STR
:
11127 case OPTYPE_INT2UNICHAR
:
11128 case OPTYPE_OCT2BIT
:
11129 case OPTYPE_OCT2CHAR
:
11130 case OPTYPE_OCT2HEX
:
11131 case OPTYPE_OCT2INT
:
11132 case OPTYPE_OCT2STR
:
11133 case OPTYPE_STR2BIT
:
11134 case OPTYPE_STR2FLOAT
:
11135 case OPTYPE_STR2HEX
:
11136 case OPTYPE_STR2INT
:
11137 case OPTYPE_STR2OCT
:
11138 case OPTYPE_UNICHAR2INT
:
11139 case OPTYPE_UNICHAR2CHAR
:
11140 case OPTYPE_ENUM2INT
:
11141 case OPTYPE_ISCHOSEN_V
:
11142 case OPTYPE_GET_STRINGENCODING
:
11143 case OPTYPE_REMOVE_BOM
:
11144 case OPTYPE_DECODE_BASE64
:
11145 str
= u
.expr
.v1
->rearrange_init_code(str
);
11147 case OPTYPE_DECODE
: {
11148 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11149 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11150 bool rearrange
= (ass
->get_my_scope()->get_scope_mod_gen() ==
11151 my_scope
->get_scope_mod_gen());
11152 if (parlist
) str
= parlist
->rearrange_init_code(str
, rearrange
);
11154 parlist
= u
.expr
.r2
->get_parlist();
11155 ass
= u
.expr
.r2
->get_refd_assignment();
11156 rearrange
= (ass
->get_my_scope()->get_scope_mod_gen() ==
11157 my_scope
->get_scope_mod_gen());
11158 if (parlist
) str
= parlist
->rearrange_init_code(str
, rearrange
);
11161 case OPTYPE_SUBTRACT
:
11162 case OPTYPE_MULTIPLY
:
11163 case OPTYPE_DIVIDE
:
11166 case OPTYPE_CONCAT
:
11183 case OPTYPE_INT2BIT
:
11184 case OPTYPE_INT2HEX
:
11185 case OPTYPE_INT2OCT
:
11186 //case OPTYPE_DECODE:
11187 str
= u
.expr
.v1
->rearrange_init_code(str
);
11188 str
= u
.expr
.v2
->rearrange_init_code(str
);
11190 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11191 case OPTYPE_OCT2UNICHAR
:
11192 case OPTYPE_ENCODE_BASE64
:
11193 str
= u
.expr
.v1
->rearrange_init_code(str
);
11194 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
);
11196 case OPTYPE_SUBSTR
:
11197 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11198 str
= u
.expr
.v2
->rearrange_init_code(str
);
11199 str
= u
.expr
.v3
->rearrange_init_code(str
);
11201 case OPTYPE_REGEXP
:
11202 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11203 str
= u
.expr
.t2
->rearrange_init_code(str
);
11204 str
= u
.expr
.v3
->rearrange_init_code(str
);
11206 case OPTYPE_DECOMP
:
11207 str
= u
.expr
.v1
->rearrange_init_code(str
);
11208 str
= u
.expr
.v2
->rearrange_init_code(str
);
11209 str
= u
.expr
.v3
->rearrange_init_code(str
);
11211 case OPTYPE_REPLACE
:
11212 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11213 str
= u
.expr
.v2
->rearrange_init_code(str
);
11214 str
= u
.expr
.v3
->rearrange_init_code(str
);
11215 str
= u
.expr
.ti4
->rearrange_init_code(str
);
11217 case OPTYPE_LENGTHOF
:
11218 case OPTYPE_SIZEOF
:
11219 case OPTYPE_VALUEOF
:
11220 case OPTYPE_ENCODE
:
11221 case OPTYPE_ISPRESENT
:
11222 case OPTYPE_TTCN2STRING
:
11223 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11225 case OPTYPE_ISCHOSEN_T
:
11226 str
= u
.expr
.t1
->rearrange_init_code(str
);
11229 str
= u
.expr
.v1
->rearrange_init_code(str
);
11230 str
= u
.expr
.t2
->rearrange_init_code(str
);
11233 // other kinds of expressions cannot appear within templates
11243 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11244 size_t& blockcount
)
11246 char *s2
= memptystr();
11247 char *s1
= generate_code_tmp(NULL
, s2
);
11249 if (blockcount
== 0) {
11250 str
= mputstr(str
, "{\n");
11253 str
= mputstr(str
, s2
);
11256 str
=mputstr(str
, prefix
);
11257 str
=mputstr(str
, s1
);
11262 char *Value::generate_code_tmp(char *str
, char*& init
)
11264 expression_struct expr
;
11265 Code::init_expr(&expr
);
11266 generate_code_expr_mandatory(&expr
);
11267 if (expr
.preamble
|| expr
.postamble
) {
11268 if (valuetype
== V_EXPR
&&
11269 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11270 // a temporary variable is already introduced
11271 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11272 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11273 str
= mputstr(str
, expr
.expr
);
11275 const string
& tmp_id
= get_temporary_id();
11276 const char *tmp_id_str
= tmp_id
.c_str();
11277 init
= mputprintf(init
, "%s %s;\n"
11279 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11280 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11282 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11283 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11284 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11285 init
= mputstr(init
, "}\n");
11286 str
= mputstr(str
, tmp_id_str
);
11288 } else str
= mputstr(str
, expr
.expr
);
11289 Code::free_expr(&expr
);
11293 void Value::generate_code_log(expression_struct
*expr
)
11295 if (explicit_cast_needed()) {
11296 char *expr_backup
= expr
->expr
;
11298 generate_code_expr(expr
);
11299 const string
& tmp_id
= get_temporary_id();
11300 const char *tmp_id_str
= tmp_id
.c_str();
11301 // We have to create a temporary object, because the parser of GCC
11302 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11303 // constructor call that is, this does not work: type(...).log(); but
11304 // this works: type tmp(...); tmp.log();.
11305 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11306 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11309 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11311 generate_code_expr(expr
);
11313 expr
->expr
= mputstr(expr
->expr
, ".log()");
11316 void Value::generate_code_log_match(expression_struct
*expr
)
11318 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11319 FATAL_ERROR("Value::generate_code_log_match()");
11320 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11321 // compliance the whole code-generation should be checked. Standalone
11322 // constructs like: "A(a[0].f());" should be avoided. The current
11323 // solution for HK38721 uses an additional assignment to overcome the
11324 // issue. The generated code will be slower, but it's needed for old GCC
11325 // versions in specific circumstances.
11326 if (u
.expr
.t2
->needs_temp_ref()) {
11327 char *expr_backup
= expr
->expr
;
11329 u
.expr
.t2
->generate_code(expr
);
11330 const string
& tmp_id
= get_temporary_id();
11331 const char *tmp_id_str
= tmp_id
.c_str();
11332 expr
->preamble
= mputprintf(expr
->preamble
,
11333 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11334 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11336 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11338 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11339 // some reason "(A(NS::B)).a(C);" compiles fine.
11340 expr
->expr
= mputc(expr
->expr
, '(');
11341 u
.expr
.t2
->generate_code(expr
);
11342 expr
->expr
= mputc(expr
->expr
, ')');
11344 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11345 u
.expr
.v1
->generate_code_expr(expr
);
11346 expr
->expr
= mputc(expr
->expr
, ')');
11349 void Value::generate_code_expr_expr(expression_struct
*expr
)
11351 switch (u
.expr
.v_optype
) {
11353 generate_code_expr_rnd(expr
, 0);
11355 case OPTYPE_UNARYPLUS
:
11356 // same as without the '+' operator
11357 u
.expr
.v1
->generate_code_expr(expr
);
11359 case OPTYPE_UNARYMINUS
:
11360 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11363 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11366 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11368 case OPTYPE_BIT2HEX
:
11369 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11371 case OPTYPE_BIT2INT
:
11372 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11374 case OPTYPE_BIT2OCT
:
11375 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11377 case OPTYPE_BIT2STR
:
11378 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11380 case OPTYPE_CHAR2INT
:
11381 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11383 case OPTYPE_CHAR2OCT
:
11384 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11386 case OPTYPE_FLOAT2INT
:
11387 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11389 case OPTYPE_FLOAT2STR
:
11390 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11392 case OPTYPE_HEX2BIT
:
11393 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11395 case OPTYPE_HEX2INT
:
11396 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11398 case OPTYPE_HEX2OCT
:
11399 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11401 case OPTYPE_HEX2STR
:
11402 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11404 case OPTYPE_INT2CHAR
:
11405 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11407 case OPTYPE_INT2FLOAT
:
11408 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11410 case OPTYPE_INT2STR
:
11411 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11413 case OPTYPE_INT2UNICHAR
:
11414 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11416 case OPTYPE_OCT2BIT
:
11417 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11419 case OPTYPE_OCT2CHAR
:
11420 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11422 case OPTYPE_GET_STRINGENCODING
:
11423 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11425 case OPTYPE_REMOVE_BOM
:
11426 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11428 case OPTYPE_ENCODE_BASE64
:
11430 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11432 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11434 case OPTYPE_DECODE_BASE64
:
11435 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11437 case OPTYPE_OCT2UNICHAR
:
11439 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11441 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11443 case OPTYPE_UNICHAR2OCT
:
11445 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11447 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11449 case OPTYPE_OCT2HEX
:
11450 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11452 case OPTYPE_OCT2INT
:
11453 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11455 case OPTYPE_OCT2STR
:
11456 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11458 case OPTYPE_STR2BIT
:
11459 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11461 case OPTYPE_STR2FLOAT
:
11462 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11464 case OPTYPE_STR2HEX
:
11465 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11467 case OPTYPE_STR2INT
:
11468 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11470 case OPTYPE_STR2OCT
:
11471 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11473 case OPTYPE_UNICHAR2INT
:
11474 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11476 case OPTYPE_UNICHAR2CHAR
:
11477 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11479 case OPTYPE_ENUM2INT
: {
11480 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11481 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11482 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11483 enum_type
->get_genname_value(my_scope
).c_str());
11484 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11485 expr
->expr
= mputc(expr
->expr
, ')');
11487 case OPTYPE_ENCODE
:
11488 generate_code_expr_encode(expr
);
11490 case OPTYPE_DECODE
:
11491 generate_code_expr_decode(expr
);
11493 case OPTYPE_RNDWITHVAL
:
11494 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11497 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11499 case OPTYPE_SUBTRACT
:
11500 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11502 case OPTYPE_MULTIPLY
:
11503 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11505 case OPTYPE_DIVIDE
:
11506 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11509 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11512 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11514 case OPTYPE_CONCAT
:
11515 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11518 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11521 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11524 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11527 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11530 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11533 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11537 generate_code_expr_and_or(expr
);
11540 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11543 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11546 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11549 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11552 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11555 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11558 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11561 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11563 case OPTYPE_INT2BIT
:
11564 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11566 case OPTYPE_INT2HEX
:
11567 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11569 case OPTYPE_INT2OCT
:
11570 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11572 case OPTYPE_SUBSTR
:
11573 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11574 else generate_code_expr_substr_replace_compat(expr
);
11576 case OPTYPE_REGEXP
:
11577 generate_code_expr_regexp(expr
);
11579 case OPTYPE_DECOMP
:
11580 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11582 case OPTYPE_REPLACE
:
11583 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11584 else generate_code_expr_substr_replace_compat(expr
);
11586 case OPTYPE_ISCHOSEN
: // r1 i2
11587 FATAL_ERROR("Value::generate_code_expr_expr()");
11589 case OPTYPE_ISCHOSEN_V
: // v1 i2
11590 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11591 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11592 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11593 u
.expr
.i2
->get_name().c_str());
11595 case OPTYPE_ISCHOSEN_T
: // t1 i2
11596 u
.expr
.t1
->generate_code_expr(expr
);
11597 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11598 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11599 u
.expr
.i2
->get_name().c_str());
11601 case OPTYPE_ISPRESENT
:
11602 case OPTYPE_ISBOUND
: {
11603 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11604 ->get_templatetype();
11605 if (temp
== Template::SPECIFIC_VALUE
) {
11606 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11607 ->get_specific_value();
11608 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11609 Ttcn::Reference
* reference
=
11610 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11612 reference
->generate_code_ispresentbound(expr
, false,
11613 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11617 } else if (temp
== Template::TEMPLATE_REFD
){
11618 Ttcn::Reference
* reference
=
11619 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11620 ->get_reference());
11622 reference
->generate_code_ispresentbound(expr
, true,
11623 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11629 case OPTYPE_LENGTHOF
: // ti1
11630 // fall through, separated later
11631 case OPTYPE_SIZEOF
: // ti1
11632 // fall through, separated later
11633 case OPTYPE_ISVALUE
: { // ti1
11634 if (u
.expr
.ti1
->is_only_specific_value()) {
11635 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11636 bool cast_needed
= t_val
->explicit_cast_needed(
11637 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11639 // the ambiguous C++ expression is converted to the value class
11640 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11641 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11644 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11645 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11646 t_val
->generate_code_expr(expr
);
11648 t_val
->generate_code_expr_mandatory(expr
);
11651 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11653 else u
.expr
.ti1
->generate_code(expr
);
11655 switch (u
.expr
.v_optype
) {
11656 case OPTYPE_ISBOUND
:
11657 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11659 case OPTYPE_ISPRESENT
:
11660 expr
->expr
=mputstr(expr
->expr
, ".is_present()");
11662 case OPTYPE_SIZEOF
:
11663 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11665 case OPTYPE_LENGTHOF
:
11666 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11668 case OPTYPE_ISVALUE
:
11669 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11672 FATAL_ERROR("Value::generate_code_expr_expr()");
11675 case OPTYPE_VALUEOF
: // ti1
11676 u
.expr
.ti1
->generate_code(expr
);
11677 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11679 case OPTYPE_MATCH
: // v1 t2
11680 u
.expr
.t2
->generate_code(expr
);
11681 expr
->expr
= mputstr(expr
->expr
, ".match(");
11682 u
.expr
.v1
->generate_code_expr(expr
);
11683 expr
->expr
= mputc(expr
->expr
, ')');
11685 case OPTYPE_UNDEF_RUNNING
:
11686 // it is resolved during semantic check
11687 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11689 case OPTYPE_COMP_NULL
: // -
11690 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11692 case OPTYPE_COMP_MTC
: // -
11693 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11695 case OPTYPE_COMP_SYSTEM
: // -
11696 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11698 case OPTYPE_COMP_SELF
: // -
11699 expr
->expr
=mputstr(expr
->expr
, "self");
11701 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11702 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11705 case OPTYPE_COMP_RUNNING
: // v1
11706 u
.expr
.v1
->generate_code_expr(expr
);
11707 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11708 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11709 expr
->expr
= mputstr(expr
->expr
, ".running()");
11711 case OPTYPE_COMP_RUNNING_ANY
: // -
11712 expr
->expr
=mputstr(expr
->expr
,
11713 "TTCN_Runtime::component_running(ANY_COMPREF)");
11715 case OPTYPE_COMP_RUNNING_ALL
: // -
11716 expr
->expr
=mputstr(expr
->expr
,
11717 "TTCN_Runtime::component_running(ALL_COMPREF)");
11719 case OPTYPE_COMP_ALIVE
: // v1
11720 u
.expr
.v1
->generate_code_expr(expr
);
11721 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11722 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11723 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11725 case OPTYPE_COMP_ALIVE_ANY
: // -
11726 expr
->expr
= mputstr(expr
->expr
,
11727 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11729 case OPTYPE_COMP_ALIVE_ALL
: // -
11730 expr
->expr
= mputstr(expr
->expr
,
11731 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11733 case OPTYPE_TMR_READ
: // r1
11734 u
.expr
.r1
->generate_code(expr
);
11735 expr
->expr
= mputstr(expr
->expr
, ".read()");
11737 case OPTYPE_TMR_RUNNING
: // r1
11738 u
.expr
.r1
->generate_code(expr
);
11739 expr
->expr
= mputstr(expr
->expr
, ".running()");
11741 case OPTYPE_TMR_RUNNING_ANY
: // -
11742 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
11744 case OPTYPE_GETVERDICT
: // -
11745 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
11747 case OPTYPE_TESTCASENAME
: // -
11748 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
11750 case OPTYPE_ACTIVATE
: // r1
11751 generate_code_expr_activate(expr
);
11753 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
11754 generate_code_expr_activate_refd(expr
);
11756 case OPTYPE_EXECUTE
: // r1 [v2]
11757 generate_code_expr_execute(expr
);
11759 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
11760 generate_code_expr_execute_refd(expr
);
11762 case OPTYPE_LOG2STR
:
11763 u
.expr
.logargs
->generate_code_expr(expr
);
11765 case OPTYPE_TTCN2STRING
: {
11766 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
11767 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
11768 param_governor
= param_governor
->get_type_refd_last();
11769 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
11770 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
11771 u
.expr
.ti1
->get_Template()->is_Value()) {
11772 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
11775 bool cast_needed
= v
->explicit_cast_needed();
11777 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
11779 v
->generate_code_expr(expr
);
11781 expr
->expr
= mputstr(expr
->expr
, ")");
11785 u
.expr
.ti1
->generate_code(expr
);
11787 expr
->expr
= mputstr(expr
->expr
, ")");
11789 case OPTYPE_PROF_RUNNING
:
11790 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
11793 FATAL_ERROR("Value::generate_code_expr_expr()");
11797 void Value::generate_code_expr_unary(expression_struct
*expr
,
11798 const char *operator_str
, Value
*v1
)
11800 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
11801 v1
->generate_code_expr_mandatory(expr
);
11802 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
11805 void Value::generate_code_expr_infix(expression_struct
*expr
,
11806 const char *operator_str
, Value
*v1
,
11807 Value
*v2
, bool optional_allowed
)
11809 if (!get_needs_conversion()) {
11810 expr
->expr
= mputc(expr
->expr
, '(');
11811 if (optional_allowed
) v1
->generate_code_expr(expr
);
11812 else v1
->generate_code_expr_mandatory(expr
);
11813 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
11814 if (optional_allowed
) v2
->generate_code_expr(expr
);
11815 else v2
->generate_code_expr_mandatory(expr
);
11816 expr
->expr
= mputc(expr
->expr
, ')');
11817 } else { // Temporary variable for the converted value.
11818 const string
& tmp_id1
= get_temporary_id();
11819 const char *tmp_id_str1
= tmp_id1
.c_str();
11820 expression_struct expr_tmp
;
11821 Code::init_expr(&expr_tmp
);
11822 switch (u
.expr
.v_optype
) {
11825 // Always "v1 -> v2".
11826 Type
*t1
= v1
->get_expr_governor_last();
11827 Type
*t2
= v2
->get_expr_governor_last();
11828 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
11829 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11830 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11831 if (expr_tmp
.preamble
)
11832 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11833 expr
->preamble
= mputprintf(expr
->preamble
,
11835 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11836 "and `%s' are not compatible at run-time\");\n",
11837 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
11838 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
11839 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
11840 t2
->get_typename().c_str(), t1
->get_typename().c_str());
11841 Code::free_expr(&expr_tmp
);
11842 if (optional_allowed
) v1
->generate_code_expr(expr
);
11843 else v1
->generate_code_expr_mandatory(expr
);
11844 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
11847 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11848 // functions. The governors of all operands must exist at this point.
11851 case OPTYPE_CONCAT
: {
11852 const string
& tmp_id2
= get_temporary_id();
11853 const char *tmp_id_str2
= tmp_id2
.c_str();
11854 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
11855 Type
*my_gov
= my_governor
->get_type_refd_last();
11856 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
11857 ->get_type_refd_last();
11858 if (!t1_gov
|| my_gov
== t1_gov
)
11859 FATAL_ERROR("Value::generate_code_expr_infix()");
11860 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11861 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
11862 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11863 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
11864 else v1
->generate_code_expr_mandatory(&expr_tmp
);
11865 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
11866 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11867 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11868 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11869 expr
->preamble
= mputprintf(expr
->preamble
,
11871 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11872 "and `%s' are not compatible at run-time\");\n",
11873 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11874 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
11875 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
11876 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
11877 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11880 FATAL_ERROR("Value::generate_code_expr_infix()");
11886 void Value::generate_code_expr_and_or(expression_struct
*expr
)
11888 if (u
.expr
.v2
->needs_short_circuit()) {
11889 // introduce a temporary variable to store the result of the operation
11890 const string
& tmp_id
= get_temporary_id();
11891 const char *tmp_id_str
= tmp_id
.c_str();
11892 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
11893 expression_struct expr2
;
11894 // the left operand must be evaluated anyway
11895 Code::init_expr(&expr2
);
11896 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11897 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
11898 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11899 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
11900 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
11901 // evaluate the right operand only when necessary
11902 // in this case the final result will be the right operand
11903 Code::init_expr(&expr2
);
11904 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11905 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
11906 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11907 // the result is now in the temporary variable
11908 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11910 // use the overloaded operator to get better error messages
11911 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
11912 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
11916 void Value::generate_code_expr_predef1(expression_struct
*expr
,
11917 const char *function_name
,
11920 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11921 v1
->generate_code_expr_mandatory(expr
);
11922 expr
->expr
= mputc(expr
->expr
, ')');
11925 void Value::generate_code_expr_predef2(expression_struct
*expr
,
11926 const char *function_name
,
11927 Value
*v1
, Value
*v2
)
11929 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11930 v1
->generate_code_expr_mandatory(expr
);
11931 expr
->expr
= mputstr(expr
->expr
, ", ");
11932 v2
->generate_code_expr_mandatory(expr
);
11933 expr
->expr
= mputc(expr
->expr
, ')');
11936 void Value::generate_code_expr_predef3(expression_struct
*expr
,
11937 const char *function_name
,
11938 Value
*v1
, Value
*v2
, Value
*v3
)
11940 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11941 v1
->generate_code_expr_mandatory(expr
);
11942 expr
->expr
= mputstr(expr
->expr
, ", ");
11943 v2
->generate_code_expr_mandatory(expr
);
11944 expr
->expr
= mputstr(expr
->expr
, ", ");
11945 v3
->generate_code_expr_mandatory(expr
);
11946 expr
->expr
= mputc(expr
->expr
, ')');
11949 void Value::generate_code_expr_substr(expression_struct
*expr
)
11952 Value
* v1
= u
.expr
.ti1
->get_specific_value();
11953 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11954 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11955 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
11956 if (v1
) v1
->generate_code_expr_mandatory(expr
);
11957 else u
.expr
.ti1
->generate_code(expr
);
11958 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
11959 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
11960 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
11961 expr
->expr
= mputstr(expr
->expr
, "(int)");
11962 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
11963 expr
->expr
= mputstr(expr
->expr
, ", ");
11964 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
11965 expr
->expr
= mputstr(expr
->expr
, "(int)");
11966 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
11967 expr
->expr
= mputc(expr
->expr
, ')');
11970 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
11972 expression_struct expr_tmp
;
11973 Code::init_expr(&expr_tmp
);
11974 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11975 ->get_type_refd_last();
11976 if (!t1
|| t1
== my_governor
->get_type_refd_last())
11977 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11978 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
11979 generate_code_expr_substr(&expr_tmp
);
11980 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
11981 generate_code_expr_replace(&expr_tmp
);
11983 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11985 // Two temporaries to store the result of substr() or replace() and to
11986 // store the converted value.
11987 const string
& tmp_id1
= get_temporary_id();
11988 const char *tmp_id_str1
= tmp_id1
.c_str();
11989 const string
& tmp_id2
= get_temporary_id();
11990 const char *tmp_id_str2
= tmp_id2
.c_str();
11991 if (expr_tmp
.preamble
)
11992 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11993 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
11994 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
11995 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
11996 if (expr_tmp
.postamble
)
11997 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
11998 Code::free_expr(&expr_tmp
);
11999 expr
->preamble
= mputprintf(expr
->preamble
,
12000 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12001 "`%s' are not compatible at run-time\");\n",
12002 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12003 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12004 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12005 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12008 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12010 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12011 Value
* v2
= u
.expr
.t2
->get_specific_value();
12012 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12013 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12014 else u
.expr
.ti1
->generate_code(expr
);
12015 expr
->expr
= mputstr(expr
->expr
, ", ");
12016 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12017 else u
.expr
.t2
->generate_code(expr
);
12018 expr
->expr
= mputstr(expr
->expr
, ", ");
12019 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12020 expr
->expr
= mputc(expr
->expr
, ')');
12023 void Value::generate_code_expr_replace(expression_struct
*expr
)
12025 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12026 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12028 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12029 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12030 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12031 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12032 else u
.expr
.ti1
->generate_code(expr
);
12033 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12034 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12035 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12036 expr
->expr
= mputstr(expr
->expr
, "(int)");
12037 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12038 expr
->expr
= mputstr(expr
->expr
, ", ");
12039 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12040 expr
->expr
= mputstr(expr
->expr
, "(int)");
12041 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12042 expr
->expr
= mputstr(expr
->expr
, ", ");
12044 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12045 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12046 Value
* v4_last
= v4
->get_value_refd_last();
12047 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12048 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12049 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_stringRepr().c_str());
12051 v4
->generate_code_expr_mandatory(expr
);
12053 else u
.expr
.ti4
->generate_code(expr
);
12054 expr
->expr
= mputc(expr
->expr
, ')');
12057 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12060 if(!v1
) // simple random generation
12061 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12062 else { // random generation with seeding
12063 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12064 v1
->generate_code_expr_mandatory(expr
);
12065 expr
->expr
= mputc(expr
->expr
, ')');
12069 void Value::generate_code_expr_create(expression_struct
*expr
,
12070 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12072 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12073 // first two arguments: component type
12074 Assignment
*t_ass
= type
->get_refd_assignment();
12075 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12076 FATAL_ERROR("Value::generate_code_expr_create()");
12077 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12078 Type::EXPECTED_DYNAMIC_VALUE
);
12079 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12080 comptype
= comptype
->get_type_refd_last();
12081 expr
->expr
= comptype
->get_CompBody()
12082 ->generate_code_comptype_name(expr
->expr
);
12083 expr
->expr
= mputstr(expr
->expr
, ", ");
12084 // third argument: component name
12086 Value
*t_val
= name
->get_value_refd_last();
12087 if (t_val
->valuetype
== V_CSTR
) {
12088 // the argument is foldable to a string literal
12089 size_t str_len
= t_val
->u
.str
.val_str
->size();
12090 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12091 expr
->expr
= mputc(expr
->expr
, '"');
12092 for (size_t i
= 0; i
< str_len
; i
++)
12093 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12094 expr
->expr
= mputc(expr
->expr
, '"');
12095 } else name
->generate_code_expr_mandatory(expr
);
12096 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12097 expr
->expr
= mputstr(expr
->expr
, ", ");
12098 // fourth argument: location
12100 Value
*t_val
= location
->get_value_refd_last();
12101 if (t_val
->valuetype
== V_CSTR
) {
12102 // the argument is foldable to a string literal
12103 size_t str_len
= t_val
->u
.str
.val_str
->size();
12104 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12105 expr
->expr
= mputc(expr
->expr
, '"');
12106 for (size_t i
= 0; i
< str_len
; i
++)
12107 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12108 expr
->expr
= mputc(expr
->expr
, '"');
12109 } else location
->generate_code_expr_mandatory(expr
);
12110 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12111 // fifth argument: alive flag
12112 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12115 void Value::generate_code_expr_activate(expression_struct
*expr
)
12117 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12118 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12119 FATAL_ERROR("Value::generate_code_expr_activate()");
12120 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12121 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12122 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12123 expr
->expr
= mputc(expr
->expr
, ')');
12126 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12128 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12129 if (v_last
->valuetype
== V_ALTSTEP
) {
12130 // the referred altstep is known
12131 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12132 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12134 // the referred altstep is unknown
12135 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12136 expr
->expr
= mputstr(expr
->expr
,".activate(");
12138 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12139 expr
->expr
= mputc(expr
->expr
, ')');
12142 void Value::generate_code_expr_execute(expression_struct
*expr
)
12144 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12145 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12146 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12147 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12148 if (parlist
->get_nof_pars() > 0) {
12149 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12151 expr
->expr
= mputstr(expr
->expr
, ", ");
12154 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12155 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12156 expr
->expr
= mputc(expr
->expr
, ')');
12157 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12160 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12162 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12163 if (v_last
->valuetype
== V_TESTCASE
) {
12164 // the referred testcase is known
12165 Assignment
*testcase
= v_last
->get_refd_fat();
12166 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12167 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12168 u
.expr
.ap_list2
->generate_code_alias(expr
,
12169 testcase
->get_FormalParList(), 0, false);
12171 // the referred testcase is unknown
12172 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12173 expr
->expr
= mputstr(expr
->expr
,".execute(");
12174 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12176 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12177 expr
->expr
= mputstr(expr
->expr
, ", ");
12179 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12180 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12181 expr
->expr
= mputc(expr
->expr
, ')');
12182 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12185 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12187 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12188 if (last_v
->get_valuetype() == V_FUNCTION
) {
12189 // the referred function is known
12190 Assignment
*function
= last_v
->get_refd_fat();
12191 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12192 function
->get_genname_from_scope(my_scope
).c_str());
12193 u
.invoke
.ap_list
->generate_code_alias(expr
,
12194 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12196 // the referred function is unknown
12197 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12198 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12199 Type
* gov_last
= last_v
->get_expr_governor_last();
12200 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12201 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12203 expr
->expr
= mputc(expr
->expr
, ')');
12206 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12209 // if the referenced value points to an optional value field the
12210 // generated code has to be corrected at the end:
12211 // `fieldid()' => `fieldid()()'
12212 Assignment
*ass
= ref
->get_refd_assignment();
12213 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12214 switch (ass
->get_asstype()) {
12215 case Assignment::A_CONST
:
12216 case Assignment::A_EXT_CONST
:
12217 case Assignment::A_MODULEPAR
:
12218 case Assignment::A_VAR
:
12219 case Assignment::A_FUNCTION_RVAL
:
12220 case Assignment::A_EXT_FUNCTION_RVAL
:
12221 case Assignment::A_PAR_VAL_IN
:
12222 case Assignment::A_PAR_VAL_OUT
:
12223 case Assignment::A_PAR_VAL_INOUT
:
12224 // only these are mapped to value objects
12225 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12226 expr
->expr
= mputstr(expr
->expr
, "()");
12233 void Value::generate_code_expr_encode(expression_struct
*expr
)
12237 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12238 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12239 v1
= templ
->get_specific_value();
12240 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12242 expression_struct expr2
;
12243 Code::init_expr(&expr2
);
12245 bool is_templ
= false;
12246 switch (templ
->get_templatetype()) {
12247 case Template::SPECIFIC_VALUE
:
12248 v1
->generate_code_expr_mandatory(&expr2
);
12251 u
.expr
.ti1
->generate_code(&expr2
);
12256 if (!gov_last
->is_coding_by_function()) {
12257 const string
& tmp_id
= get_temporary_id();
12258 const string
& tmp_buf_id
= get_temporary_id();
12259 const string
& tmp_ref_id
= get_temporary_id();
12260 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12262 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12263 tmp_buf_id
.c_str());
12264 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12265 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12266 expr
->preamble
= mputc (expr
->preamble
, '\n');
12268 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12269 gov_last
->get_genname_typedescriptor(
12270 u
.expr
.ti1
->get_Template()->get_my_scope()
12272 tmp_ref_id
.c_str(),
12274 if (is_templ
) // make a value out of the template, if needed
12275 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12276 expr
->preamble
= mputprintf(expr
->preamble
,
12277 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12278 tmp_ref_id
.c_str(),
12279 gov_last
->get_genname_typedescriptor(
12280 u
.expr
.ti1
->get_Template()->get_my_scope()
12282 tmp_buf_id
.c_str(),
12283 gov_last
->get_coding(true).c_str()
12285 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12286 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12287 tmp_buf_id
.c_str(),
12290 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12291 if (expr2
.postamble
)
12292 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12294 expr
->expr
= mputprintf(expr
->expr
, "%s(%s)",
12295 gov_last
->get_coding(true).c_str(), expr2
.expr
);
12296 Code::free_expr(&expr2
);
12299 void Value::generate_code_expr_decode(expression_struct
*expr
)
12301 expression_struct expr1
, expr2
;
12302 Code::init_expr(&expr1
);
12303 Code::init_expr(&expr2
);
12304 u
.expr
.r1
->generate_code(&expr1
);
12305 u
.expr
.r2
->generate_code(&expr2
);
12307 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12308 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12309 get_type_refd_last();
12311 if (expr1
.preamble
)
12312 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12313 if (expr2
.preamble
)
12314 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12316 if (!_type
->is_coding_by_function()) {
12317 const string
& tmp_id
= get_temporary_id();
12318 const string
& buffer_id
= get_temporary_id();
12319 const string
& retval_id
= get_temporary_id();
12320 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12321 field_is_optional(u
.expr
.r2
->get_subrefs());
12323 expr
->preamble
= mputprintf(expr
->preamble
,
12324 "TTCN_Buffer %s(bit2oct(%s));\n"
12326 "TTCN_EncDec::set_error_behavior("
12327 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12328 "TTCN_EncDec::clear_error();\n",
12333 expr
->preamble
= mputprintf(expr
->preamble
,
12334 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12336 optional
? "()" : "",
12337 _type
->get_genname_typedescriptor(
12338 u
.expr
.r2
->get_my_scope()
12341 _type
->get_coding(false).c_str()
12343 expr
->preamble
= mputprintf(expr
->preamble
,
12344 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12345 "case TTCN_EncDec::ET_NONE: {\n"
12347 "OCTETSTRING %s;\n"
12348 "%s.get_string(%s);\n"
12349 "%s = oct2bit(%s);\n"
12352 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12353 "case TTCN_EncDec::ET_LEN_ERR:\n"
12359 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12360 "TTCN_EncDec::EB_DEFAULT);\n"
12361 "TTCN_EncDec::clear_error();\n",
12372 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12374 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12375 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12376 if (expr1
.postamble
)
12377 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12378 if (expr2
.postamble
)
12379 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12380 Code::free_expr(&expr1
);
12381 Code::free_expr(&expr2
);
12384 char *Value::generate_code_init_choice(char *str
, const char *name
)
12386 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12387 // Safe as long as get_name() returns a const string&, not a temporary.
12388 const char *alt_prefix
=
12389 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12391 if (u
.choice
.alt_value
->needs_temp_ref()) {
12392 const string
& tmp_id
= get_temporary_id();
12393 const char *tmp_id_str
= tmp_id
.c_str();
12394 str
= mputprintf(str
, "{\n"
12395 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12396 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12397 alt_prefix
, alt_name
);
12398 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12399 str
= mputstr(str
, "}\n");
12401 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12402 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12403 Free(embedded_name
);
12408 char *Value::generate_code_init_seof(char *str
, const char *name
)
12410 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12412 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12413 const string
& embedded_type
=
12414 my_governor
->get_ofType()->get_genname_value(my_scope
);
12415 const char *embedded_type_str
= embedded_type
.c_str();
12416 for (size_t i
= 0; i
< nof_vs
; i
++) {
12417 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12419 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12420 else if (comp_v
->needs_temp_ref()) {
12421 const string
& tmp_id
= get_temporary_id();
12422 const char *tmp_id_str
= tmp_id
.c_str();
12423 str
= mputprintf(str
, "{\n"
12424 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12425 (unsigned long) i
);
12426 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12427 str
= mputstr(str
, "}\n");
12429 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12430 str
= comp_v
->generate_code_init(str
, embedded_name
);
12431 Free(embedded_name
);
12435 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12440 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12442 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12444 // Previous values can be truncated. The concept is similar to
12446 Type
*t_last
= my_governor
->get_type_refd_last();
12447 const string
& oftype_name
=
12448 t_last
->get_ofType()->get_genname_value(my_scope
);
12449 const char *oftype_name_str
= oftype_name
.c_str();
12450 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12451 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12452 const string
& tmp_id_1
= get_temporary_id();
12453 str
= mputstr(str
, "{\n");
12454 Value
*index
= iv
->get_index();
12455 if (index
->get_valuetype() != V_INT
) {
12456 const string
& tmp_id_2
= get_temporary_id();
12457 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12458 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12459 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12460 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12462 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12463 tmp_id_1
.c_str(), name
,
12464 (index
->get_val_Int()->t_str()).c_str());
12466 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12467 str
= mputstr(str
, "}\n");
12469 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12473 char *Value::generate_code_init_array(char *str
, const char *name
)
12475 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12476 Type
*t_last
= my_governor
->get_type_refd_last();
12477 Int index_offset
= t_last
->get_dimension()->get_offset();
12478 const string
& embedded_type
=
12479 t_last
->get_ofType()->get_genname_value(my_scope
);
12480 const char *embedded_type_str
= embedded_type
.c_str();
12481 for (size_t i
= 0; i
< nof_vs
; i
++) {
12482 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12483 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12484 else if (comp_v
->needs_temp_ref()) {
12485 const string
& tmp_id
= get_temporary_id();
12486 const char *tmp_id_str
= tmp_id
.c_str();
12487 str
= mputprintf(str
, "{\n"
12488 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12489 Int2string(index_offset
+ i
).c_str());
12490 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12491 str
= mputstr(str
, "}\n");
12493 char *embedded_name
= mprintf("%s[%s]", name
,
12494 Int2string(index_offset
+ i
).c_str());
12495 str
= comp_v
->generate_code_init(str
, embedded_name
);
12496 Free(embedded_name
);
12502 char *Value::generate_code_init_se(char *str
, const char *name
)
12504 Type
*type
= my_governor
->get_type_refd_last();
12505 size_t nof_comps
= type
->get_nof_comps();
12506 if (nof_comps
> 0) {
12507 for (size_t i
= 0; i
< nof_comps
; i
++) {
12508 CompField
*cf
= type
->get_comp_byIndex(i
);
12509 const Identifier
& field_id
= cf
->get_name();
12510 const char *field_name
= field_id
.get_name().c_str();
12512 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12513 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12514 if (field_v
->valuetype
== V_NOTUSED
) continue;
12515 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12516 } else if (is_asn1()) {
12517 if (cf
->has_default()) {
12518 // handle like a referenced value
12519 Value
*defval
= cf
->get_defval();
12520 if (needs_init_precede(defval
)) {
12521 str
= defval
->generate_code_init(str
,
12522 defval
->get_lhs_name().c_str());
12524 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12525 defval
->get_genname_own(my_scope
).c_str());
12528 if (!cf
->get_is_optional())
12529 FATAL_ERROR("Value::generate_code_init()");
12536 // the value is not omit
12537 if (field_v
->needs_temp_ref()) {
12538 const string
& tmp_id
= get_temporary_id();
12539 const char *tmp_id_str
= tmp_id
.c_str();
12540 str
= mputprintf(str
, "{\n"
12541 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
12542 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12544 str
= field_v
->generate_code_init(str
, tmp_id_str
);
12545 str
= mputstr(str
, "}\n");
12547 char *embedded_name
= mprintf("%s.%s()", name
,
12549 if (cf
->get_is_optional() && field_v
->is_compound())
12550 embedded_name
= mputstr(embedded_name
, "()");
12551 str
= field_v
->generate_code_init(str
, embedded_name
);
12552 Free(embedded_name
);
12555 // the value is omit
12556 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
12561 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12566 char *Value::generate_code_init_refd(char *str
, const char *name
)
12568 Value
*v
= get_value_refd_last();
12570 // the referred value is not available at compile time
12571 // the code generation is based on the reference
12572 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
12573 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
12575 expression_struct expr
;
12576 Code::init_expr(&expr
);
12577 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
12578 u
.ref
.ref
->generate_code_const_ref(&expr
);
12579 str
= Code::merge_free_expr(str
, &expr
);
12582 // the referred value is available at compile time
12583 // the code generation is based on the referred value
12584 if (v
->has_single_expr() &&
12585 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
12586 // simple substitution for in-line values within the same module
12587 str
= mputprintf(str
, "%s = %s;\n", name
,
12588 v
->get_single_expr().c_str());
12590 // use a simple reference to reduce code size
12591 if (needs_init_precede(v
)) {
12592 // the referred value must be initialized first
12593 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
12594 // temporary id should be introduced for the lhs
12595 const string
& tmp_id
= get_temporary_id();
12596 const char *tmp_id_str
= tmp_id
.c_str();
12597 str
= mputprintf(str
, "{\n"
12599 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
12600 tmp_id_str
, v
->get_lhs_name().c_str());
12601 str
= v
->generate_code_init(str
, tmp_id_str
);
12602 str
= mputstr(str
, "}\n");
12604 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
12607 str
= mputprintf(str
, "%s = %s;\n", name
,
12608 v
->get_genname_own(my_scope
).c_str());
12614 bool Value::explicit_cast_needed(bool forIsValue
)
12616 Value
*v_last
= get_value_refd_last();
12617 if (v_last
!= this) {
12618 // this is a foldable referenced value
12619 // if the reference points to an imported or compound value the code
12620 // generation will be based on the reference so cast is not needed
12621 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
12622 || !v_last
->has_single_expr()) return false;
12623 } else if (v_last
->valuetype
== V_REFD
) {
12624 // this is an unfoldable reference (v_last==this)
12625 // explicit cast is needed only for string element references
12626 if (forIsValue
) return false;
12627 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
12628 return t_subrefs
&& t_subrefs
->refers_to_string_element();
12630 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
12631 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
12632 switch (t_governor
->get_typetype()) {
12636 case Type::T_INT_A
:
12638 case Type::T_ENUM_A
:
12639 case Type::T_ENUM_T
:
12640 case Type::T_VERDICT
:
12641 case Type::T_COMPONENT
:
12642 // these are mapped to built-in C/C++ types
12644 case Type::T_SEQ_A
:
12645 case Type::T_SEQ_T
:
12646 case Type::T_SET_A
:
12647 case Type::T_SET_T
:
12648 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12649 return t_governor
->get_nof_comps() == 0;
12650 case Type::T_SEQOF
:
12651 case Type::T_SETOF
:
12652 // the C++ equivalent of value {} is ambiguous
12655 case Type::T_FUNCTION
:
12656 case Type::T_ALTSTEP
:
12657 case Type::T_TESTCASE
:
12664 bool Value::has_single_expr()
12666 if (get_needs_conversion()) return false;
12667 switch (valuetype
) {
12669 return has_single_expr_expr();
12672 // a union or array value cannot be represented as an in-line expression
12676 // only an empty record/set of value can be represented as an in-line
12678 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
12679 else return u
.val_vs
->get_nof_ivs() == 0;
12682 // only a value for an empty record/set type can be represented as an
12683 // in-line expression
12684 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
12685 Type
*type
= my_governor
->get_type_refd_last();
12686 return type
->get_nof_comps() == 0; }
12688 Value
*v_last
= get_value_refd_last();
12689 // If the above call hit an error and set_valuetype(V_ERROR),
12690 // then u.ref.ref has been freed. Avoid the segfault.
12691 if (valuetype
== V_ERROR
)
12693 if (v_last
!= this && v_last
->has_single_expr() &&
12694 v_last
->my_scope
->get_scope_mod_gen() ==
12695 my_scope
->get_scope_mod_gen()) return true;
12696 else return u
.ref
.ref
->has_single_expr(); }
12698 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
12702 case V_UNDEF_LOWERID
:
12703 case V_UNDEF_BLOCK
:
12705 // these values cannot occur during code generation
12706 FATAL_ERROR("Value::has_single_expr()");
12708 return u
.val_Int
->is_native_fit();
12710 // other value types (literal values) do not need temporary reference
12715 string
Value::get_single_expr()
12717 switch (valuetype
) {
12719 return string("ASN_NULL_VALUE");
12721 return string(u
.val_bool
? "TRUE" : "FALSE");
12723 if (u
.val_Int
->is_native_fit()) { // Be sure.
12724 return u
.val_Int
->t_str();
12726 // get_single_expr may be called only if has_single_expr() is true.
12727 // The only exception is V_INT, where get_single_expr may be called
12728 // even if is_native_fit (which is used to implement has_single_expr)
12730 string
ret_val('"');
12731 ret_val
+= u
.val_Int
->t_str();
12736 return Real2code(u
.val_Real
);
12738 return get_single_expr_enum();
12740 return get_my_scope()->get_scope_mod_gen()
12741 ->add_bitstring_literal(*u
.str
.val_str
);
12743 return get_my_scope()->get_scope_mod_gen()
12744 ->add_hexstring_literal(*u
.str
.val_str
);
12746 return get_my_scope()->get_scope_mod_gen()
12747 ->add_octetstring_literal(*u
.str
.val_str
);
12749 return get_my_scope()->get_scope_mod_gen()
12750 ->add_charstring_literal(*u
.str
.val_str
);
12752 if (u
.ustr
.convert_str
) {
12753 set_valuetype(V_CSTR
);
12754 return get_my_scope()->get_scope_mod_gen()
12755 ->add_charstring_literal(*u
.str
.val_str
);
12757 return get_my_scope()->get_scope_mod_gen()
12758 ->add_ustring_literal(*u
.ustr
.val_ustr
);
12760 return get_single_expr_iso2022str();
12763 vector
<string
> comps
;
12764 bool is_constant
= get_oid_comps(comps
);
12765 size_t nof_comps
= comps
.size();
12767 for (size_t i
= 0; i
< nof_comps
; i
++) {
12768 if (i
> 0) oi_str
+= ", ";
12769 oi_str
+= *(comps
[i
]);
12771 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
12774 // the objid only contains constants
12775 // => create a literal and return its name
12776 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
12778 // the objid contains at least one variable
12779 // => append the number of components before the component values in the string and return it
12780 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
12783 if (u
.val_vs
->get_nof_vs() > 0)
12784 FATAL_ERROR("Value::get_single_expr()");
12785 return string("NULL_VALUE");
12788 if (u
.val_nvs
->get_nof_nvs() > 0)
12789 FATAL_ERROR("Value::get_single_expr()");
12790 return string("NULL_VALUE");
12792 Value
*v_last
= get_value_refd_last();
12793 if (v_last
!= this && v_last
->has_single_expr() &&
12794 v_last
->my_scope
->get_scope_mod_gen() ==
12795 my_scope
->get_scope_mod_gen()) {
12796 // the reference points to another single value in the same module
12797 return v_last
->get_single_expr();
12799 // convert the reference to a single expression
12800 expression_struct expr
;
12801 Code::init_expr(&expr
);
12802 u
.ref
.ref
->generate_code_const_ref(&expr
);
12803 if (expr
.preamble
|| expr
.postamble
)
12804 FATAL_ERROR("Value::get_single_expr()");
12805 string
ret_val(expr
.expr
);
12806 Code::free_expr(&expr
);
12810 return string("OMIT_VALUE");
12812 switch (u
.verdict
) {
12814 return string("NONE");
12816 return string("PASS");
12817 case Verdict_INCONC
:
12818 return string("INCONC");
12820 return string("FAIL");
12821 case Verdict_ERROR
:
12822 return string("ERROR");
12824 FATAL_ERROR("Value::get_single_expr()");
12827 case V_DEFAULT_NULL
:
12828 return string("NULL_COMPREF");
12830 string
ret_val('(');
12831 ret_val
+= my_governor
->get_genname_value(my_scope
);
12832 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
12836 expression_struct expr
;
12837 Code::init_expr(&expr
);
12838 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
12839 else generate_code_expr_invoke(&expr
);
12840 if (expr
.preamble
|| expr
.postamble
)
12841 FATAL_ERROR("Value::get_single_expr()");
12842 string
ret_val(expr
.expr
);
12843 Code::free_expr(&expr
);
12847 case MACRO_TESTCASEID
:
12848 return string("TTCN_Runtime::get_testcase_id_macro()");
12850 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
12856 return get_single_expr_fat();
12858 FATAL_ERROR("Value::get_single_expr()");
12863 bool Value::has_single_expr_expr()
12865 switch (u
.expr
.v_optype
) {
12866 case OPTYPE_RND
: // -
12867 case OPTYPE_COMP_NULL
:
12868 case OPTYPE_COMP_MTC
:
12869 case OPTYPE_COMP_SYSTEM
:
12870 case OPTYPE_COMP_SELF
:
12871 case OPTYPE_COMP_RUNNING_ANY
:
12872 case OPTYPE_COMP_RUNNING_ALL
:
12873 case OPTYPE_COMP_ALIVE_ANY
:
12874 case OPTYPE_COMP_ALIVE_ALL
:
12875 case OPTYPE_TMR_RUNNING_ANY
:
12876 case OPTYPE_GETVERDICT
:
12877 case OPTYPE_TESTCASENAME
:
12878 case OPTYPE_PROF_RUNNING
:
12880 case OPTYPE_ENCODE
:
12881 case OPTYPE_DECODE
:
12882 case OPTYPE_ISBOUND
:
12883 case OPTYPE_ISPRESENT
:
12884 case OPTYPE_TTCN2STRING
:
12886 case OPTYPE_UNARYPLUS
: // v1
12887 case OPTYPE_UNARYMINUS
:
12890 case OPTYPE_BIT2HEX
:
12891 case OPTYPE_BIT2INT
:
12892 case OPTYPE_BIT2OCT
:
12893 case OPTYPE_BIT2STR
:
12894 case OPTYPE_CHAR2INT
:
12895 case OPTYPE_CHAR2OCT
:
12896 case OPTYPE_FLOAT2INT
:
12897 case OPTYPE_FLOAT2STR
:
12898 case OPTYPE_HEX2BIT
:
12899 case OPTYPE_HEX2INT
:
12900 case OPTYPE_HEX2OCT
:
12901 case OPTYPE_HEX2STR
:
12902 case OPTYPE_INT2CHAR
:
12903 case OPTYPE_INT2FLOAT
:
12904 case OPTYPE_INT2STR
:
12905 case OPTYPE_INT2UNICHAR
:
12906 case OPTYPE_OCT2BIT
:
12907 case OPTYPE_OCT2CHAR
:
12908 case OPTYPE_OCT2HEX
:
12909 case OPTYPE_OCT2INT
:
12910 case OPTYPE_OCT2STR
:
12911 case OPTYPE_STR2BIT
:
12912 case OPTYPE_STR2FLOAT
:
12913 case OPTYPE_STR2HEX
:
12914 case OPTYPE_STR2INT
:
12915 case OPTYPE_STR2OCT
:
12916 case OPTYPE_UNICHAR2INT
:
12917 case OPTYPE_UNICHAR2CHAR
:
12918 case OPTYPE_ENUM2INT
:
12919 case OPTYPE_RNDWITHVAL
:
12920 case OPTYPE_ISCHOSEN_V
: // v1 i2
12921 case OPTYPE_COMP_RUNNING
:
12922 case OPTYPE_COMP_ALIVE
:
12923 case OPTYPE_GET_STRINGENCODING
:
12924 case OPTYPE_REMOVE_BOM
:
12925 case OPTYPE_DECODE_BASE64
:
12926 return u
.expr
.v1
->has_single_expr();
12927 case OPTYPE_ISCHOSEN_T
: // t1 i2
12928 return u
.expr
.t1
->has_single_expr();
12929 case OPTYPE_ADD
: // v1 v2
12930 case OPTYPE_SUBTRACT
:
12931 case OPTYPE_MULTIPLY
:
12932 case OPTYPE_DIVIDE
:
12935 case OPTYPE_CONCAT
:
12950 case OPTYPE_INT2BIT
:
12951 case OPTYPE_INT2HEX
:
12952 case OPTYPE_INT2OCT
:
12953 return u
.expr
.v1
->has_single_expr() &&
12954 u
.expr
.v2
->has_single_expr();
12955 case OPTYPE_UNICHAR2OCT
:
12956 case OPTYPE_OCT2UNICHAR
:
12957 case OPTYPE_ENCODE_BASE64
:
12958 return u
.expr
.v1
->has_single_expr() &&
12959 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
12962 return u
.expr
.v1
->has_single_expr() &&
12963 u
.expr
.v2
->has_single_expr() &&
12964 !u
.expr
.v2
->needs_short_circuit();
12965 case OPTYPE_SUBSTR
:
12966 return u
.expr
.ti1
->has_single_expr() &&
12967 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
12968 case OPTYPE_REGEXP
:
12969 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
12970 u
.expr
.v3
->has_single_expr();
12971 case OPTYPE_DECOMP
: // v1 v2 v3
12972 return u
.expr
.v1
->has_single_expr() &&
12973 u
.expr
.v2
->has_single_expr() &&
12974 u
.expr
.v3
->has_single_expr();
12975 case OPTYPE_REPLACE
:
12976 return u
.expr
.ti1
->has_single_expr() &&
12977 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
12978 u
.expr
.ti4
->has_single_expr();
12979 case OPTYPE_ISVALUE
: // ti1
12980 case OPTYPE_LENGTHOF
: // ti1
12981 case OPTYPE_SIZEOF
: // ti1
12982 case OPTYPE_VALUEOF
: // ti1
12983 return u
.expr
.ti1
->has_single_expr();
12984 case OPTYPE_LOG2STR
:
12985 return u
.expr
.logargs
->has_single_expr();
12986 case OPTYPE_MATCH
: // v1 t2
12987 return u
.expr
.v1
->has_single_expr() &&
12988 u
.expr
.t2
->has_single_expr();
12989 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
12990 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
12991 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
12992 case OPTYPE_TMR_READ
: // r1
12993 case OPTYPE_TMR_RUNNING
:
12994 case OPTYPE_ACTIVATE
:
12995 return u
.expr
.r1
->has_single_expr();
12996 case OPTYPE_EXECUTE
: // r1 [v2]
12997 return u
.expr
.r1
->has_single_expr() &&
12998 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
12999 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13000 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13001 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13002 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13003 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13005 FATAL_ERROR("Value::has_single_expr_expr()");
13009 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13011 if (!v
->has_single_expr()) return false;
13012 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13013 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13017 string
Value::get_single_expr_enum()
13019 string
ret_val(my_governor
->get_genname_value(my_scope
));
13021 ret_val
+= u
.val_id
->get_name();
13025 string
Value::get_single_expr_iso2022str()
13028 Type
*type
= get_my_governor()->get_type_refd_last();
13029 switch (type
->get_typetype()) {
13030 case Type::T_TELETEXSTRING
:
13031 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13033 case Type::T_VIDEOTEXSTRING
:
13034 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13036 case Type::T_GRAPHICSTRING
:
13037 case Type::T_OBJECTDESCRIPTOR
:
13038 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13040 case Type::T_GENERALSTRING
:
13041 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13044 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13047 string
*ostr
= char2oct(*u
.str
.val_str
);
13048 ret_val
+= get_my_scope()->get_scope_mod_gen()
13049 ->add_octetstring_literal(*ostr
);
13055 string
Value::get_single_expr_fat()
13057 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13058 // the ampersand operator is not really necessary to obtain the function
13059 // pointer, but some older versions of GCC cannot instantiate the
13060 // appropriate operator=() member of class OPTIONAL when necessary
13061 // if only the function name is given
13062 string
ret_val('&');
13063 switch (valuetype
) {
13065 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13068 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13069 ret_val
+= "_instance";
13072 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13075 FATAL_ERROR("Value::get_single_expr_fat()");
13080 bool Value::is_compound()
13082 switch (valuetype
) {
13095 bool Value::needs_temp_ref()
13097 switch (valuetype
) {
13100 if (!is_indexed()) {
13101 // Temporary reference is needed if the value has at least one real
13102 // element (i.e. it is not empty or contains only not used symbols).
13103 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13104 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13107 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13108 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13109 ->valuetype
!= V_NOTUSED
)
13115 size_t nof_real_vs
= 0;
13116 if (!is_indexed()) {
13117 // Temporary reference is needed if the array value has at least two
13118 // real elements (excluding not used symbols).
13119 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13120 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13122 if (nof_real_vs
> 1) return true;
13126 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13127 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13128 ->valuetype
!= V_NOTUSED
) {
13130 if (nof_real_vs
> 1) return true;
13138 // it depends on the type since fields with omit or default value
13139 // may not be present
13140 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13142 // incomplete values are allowed in TTCN-3
13143 // we should check the number of value components
13144 return u
.val_nvs
->get_nof_nvs() > 1;
13149 case V_UNDEF_LOWERID
:
13150 case V_UNDEF_BLOCK
:
13152 // these values cannot occur during code generation
13153 FATAL_ERROR("Value::needs_temp_ref()");
13155 return !u
.val_Int
->is_native();
13157 // other value types (literal values) do not need temporary reference
13162 bool Value::needs_short_circuit()
13164 switch (valuetype
) {
13172 // sub-expressions should be evaluated only if necessary
13175 FATAL_ERROR("Value::needs_short_circuit()");
13177 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13178 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13179 switch (t_ass
->get_asstype()) {
13180 case Assignment::A_FUNCTION_RVAL
:
13181 case Assignment::A_EXT_FUNCTION_RVAL
:
13182 // avoid unnecessary call of a function
13184 case Assignment::A_CONST
:
13185 case Assignment::A_EXT_CONST
:
13186 case Assignment::A_MODULEPAR
:
13187 case Assignment::A_VAR
:
13188 case Assignment::A_PAR_VAL_IN
:
13189 case Assignment::A_PAR_VAL_OUT
:
13190 case Assignment::A_PAR_VAL_INOUT
:
13191 // depends on field/array sub-references, which is examined below
13194 FATAL_ERROR("Value::needs_short_circuit()");
13196 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13198 // the evaluation of the reference does not have side effects
13199 // (i.e. false shall be returned) only if all sub-references point to
13200 // mandatory fields of record/set types, and neither sub-reference points
13201 // to a field of a union type
13202 Type
*t_type
= t_ass
->get_Type();
13203 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13204 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13205 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13206 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13207 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13208 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13209 t_cf
->get_is_optional()) return true;
13210 t_type
= t_cf
->get_type();
13211 } else return true;
13217 void Value::dump(unsigned level
) const
13219 switch (valuetype
) {
13243 case V_DEFAULT_NULL
:
13251 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13255 DEBUG(level
, "Value: reference");
13256 u
.ref
.ref
->dump(level
+ 1);
13258 case V_UNDEF_LOWERID
:
13259 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13261 case V_UNDEF_BLOCK
:
13262 DEBUG(level
, "Value: {block}");
13265 DEBUG(level
, "Value: null");
13268 DEBUG(level
, "Value: invoke");
13269 u
.invoke
.v
->dump(level
+ 1);
13270 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13271 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13274 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13278 void Value::add_string_element(size_t index
, Value
*v_element
,
13279 map
<size_t, Value
>*& string_elements
)
13281 v_element
->set_my_scope(get_my_scope());
13282 v_element
->set_my_governor(get_my_governor());
13283 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13284 v_element
->set_location(*this);
13285 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13286 string_elements
->add(index
, v_element
);
13289 ///////////////////////////////////////////////////////////////////////////////
13290 // class LazyParamData
13292 int LazyParamData::depth
= 0;
13293 bool LazyParamData::used_as_lvalue
= false;
13294 vector
<string
>* LazyParamData::type_vec
= NULL
;
13295 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13297 void LazyParamData::init(bool p_used_as_lvalue
) {
13298 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13300 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13301 used_as_lvalue
= p_used_as_lvalue
;
13302 type_vec
= new vector
<string
>;
13303 refd_vec
= new vector
<string
>;
13308 void LazyParamData::clean() {
13309 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13310 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13313 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13318 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13326 bool LazyParamData::in_lazy() {
13327 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13331 // returns a temporary id instead of the C++ reference to a definition
13332 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13333 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13334 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13335 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13336 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13337 // store the type of the assignment
13338 string
* type_str
= new string
;
13339 switch (ass
->get_asstype()) {
13340 case Assignment::A_MODULEPAR_TEMP
:
13341 case Assignment::A_TEMPLATE
:
13342 case Assignment::A_VAR_TEMPLATE
:
13343 case Assignment::A_PAR_TEMPL_IN
:
13344 case Assignment::A_PAR_TEMPL_OUT
:
13345 case Assignment::A_PAR_TEMPL_INOUT
:
13346 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13349 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13351 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13352 bool refd_ass_is_lazy_fpar
= false;
13353 switch (ass
->get_asstype()) {
13354 case Assignment::A_PAR_VAL
:
13355 case Assignment::A_PAR_VAL_IN
:
13356 case Assignment::A_PAR_TEMPL_IN
:
13357 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13358 if (refd_ass_is_lazy_fpar
) {
13359 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13365 // add the "const" part if the referenced assignment is a constant thing
13366 if (!refd_ass_is_lazy_fpar
) {
13367 switch (ass
->get_asstype()) {
13368 case Assignment::A_CONST
:
13369 case Assignment::A_OC
:
13370 case Assignment::A_OBJECT
:
13371 case Assignment::A_OS
:
13372 case Assignment::A_VS
:
13373 case Assignment::A_EXT_CONST
:
13374 case Assignment::A_MODULEPAR
:
13375 case Assignment::A_MODULEPAR_TEMP
:
13376 case Assignment::A_TEMPLATE
:
13377 case Assignment::A_PAR_VAL
:
13378 case Assignment::A_PAR_VAL_IN
:
13379 case Assignment::A_PAR_TEMPL_IN
:
13380 *type_str
= string("const ") + *type_str
;
13388 type_vec
->add(type_str
);
13389 // store the C++ reference string
13390 refd_vec
->add(new string(ass
->get_genname_from_scope(scope
,""))); // the "" parameter makes sure that no casting to type is generated into the string
13391 if (refd_ass_is_lazy_fpar
) {
13392 Type
* refd_ass_type
= ass
->get_Type();
13393 string refd_ass_type_genname
= (ass
->get_asstype()==Assignment::A_PAR_TEMPL_IN
) ? refd_ass_type
->get_genname_template(scope
) : refd_ass_type
->get_genname_value(scope
);
13394 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
13396 return get_member_name(refd_vec
->size()-1);
13400 string
LazyParamData::get_member_name(size_t idx
) {
13401 return string("lpm_") + Int2string(idx
);
13404 string
LazyParamData::get_constr_param_name(size_t idx
) {
13405 return string("lpp_") + Int2string(idx
);
13408 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
13409 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13410 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
13411 const string
& tmp_id
= val
->get_temporary_id();
13412 const char *tmp_id_str
= tmp_id
.c_str();
13413 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13414 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13416 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13418 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13420 val
->generate_code_expr(expr
);
13424 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
13425 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13426 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
13427 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
13428 const char *tmp_id_str
= tmp_id
.c_str();
13429 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13430 temp
->get_Template()->get_my_governor()
13431 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
13432 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13433 tmp_id_str
, temp
->get_Template());
13434 // Not incorporated into gen_conv_code() yet.
13435 if (gen_restriction_check
!= TR_NONE
)
13436 expr
->preamble
= Template::generate_restriction_check_code(
13437 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
13438 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13439 } else temp
->generate_code(expr
, gen_restriction_check
);
13442 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13443 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13445 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13446 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13447 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13448 expression_struct value_expr
;
13449 Code::init_expr(&value_expr
);
13450 generate_code_for_value(&value_expr
, value
, scope
);
13451 // the id of the instance of Lazy_Param which will be used as the actual parameter
13452 const string
& lazy_param_id
= value
->get_temporary_id();
13453 if (value_expr
.preamble
) {
13454 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
13456 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13457 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13458 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
13459 Code::free_expr(&value_expr
);
13460 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13463 // only if the formal parameter is *not* used as lvalue
13464 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
13465 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
13467 bool refd_ass_is_lazy_fpar
= false;
13468 switch (refd_ass
->get_asstype()) {
13469 case Assignment::A_PAR_VAL
:
13470 case Assignment::A_PAR_VAL_IN
:
13471 case Assignment::A_PAR_TEMPL_IN
:
13472 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13477 if (refd_ass_is_lazy_fpar
) {
13478 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13483 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13484 expression_struct value_expr
;
13485 Code::init_expr(&value_expr
);
13486 generate_code_for_value(&value_expr
, value
, scope
);
13487 // the id of the instance of Lazy_Param which will be used as the actual parameter
13488 string lazy_param_id
= value
->get_temporary_id();
13489 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
13490 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
13493 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
13494 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13496 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13497 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13498 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13499 expression_struct tmpl_expr
;
13500 Code::init_expr(&tmpl_expr
);
13501 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13502 // the id of the instance of Lazy_Param which will be used as the actual parameter
13503 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
13504 if (tmpl_expr
.preamble
) {
13505 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
13507 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13508 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13509 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
13510 Code::free_expr(&tmpl_expr
);
13511 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13514 // only if the formal parameter is *not* used as lvalue
13515 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
13516 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
13518 bool refd_ass_is_lazy_fpar
= false;
13519 switch (refd_ass
->get_asstype()) {
13520 case Assignment::A_PAR_VAL
:
13521 case Assignment::A_PAR_VAL_IN
:
13522 case Assignment::A_PAR_TEMPL_IN
:
13523 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13528 if (refd_ass_is_lazy_fpar
) {
13529 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13534 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13535 expression_struct tmpl_expr
;
13536 Code::init_expr(&tmpl_expr
);
13537 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13538 // the id of the instance of Lazy_Param which will be used as the actual parameter
13539 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
13540 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
13541 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
13544 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
13545 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
13546 if (type_vec
->size()>0) {
13547 // private members of the local class will be const references to the objects referenced by the expression
13548 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13549 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
13551 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
13552 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
13553 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13554 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13555 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
13557 expr
->preamble
= mputstr(expr
->preamble
, "): ");
13558 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13559 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13560 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
13562 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
13563 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
13565 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
13566 // use the temporary expr structure to fill the body of the eval_expr() function
13567 if (param_expr
.preamble
) {
13568 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
13570 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
13571 if (param_expr
.postamble
) {
13572 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
13574 Code::free_expr(¶m_expr
);
13575 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
13576 "};\n" // end of local class definition
13578 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
13579 if (type_vec
->size()>0) {
13580 expr
->preamble
= mputc(expr
->preamble
, '(');
13581 // paramteres of the constructor are references to the objects used in the expression
13582 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
13583 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13584 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
13586 expr
->preamble
= mputc(expr
->preamble
, ')');
13588 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
13589 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13590 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
13593 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
13594 expression_struct ref_expr
;
13595 Code::init_expr(&ref_expr
);
13596 ref
->generate_code(&ref_expr
);
13597 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
13598 if (ref_expr
.preamble
) {
13599 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
13601 Assignment
* ass
= ref
->get_refd_assignment();
13602 // determine C++ type of the assignment
13604 switch (ass
->get_asstype()) {
13605 case Assignment::A_MODULEPAR_TEMP
:
13606 case Assignment::A_TEMPLATE
:
13607 case Assignment::A_VAR_TEMPLATE
:
13608 case Assignment::A_PAR_TEMPL_IN
:
13609 case Assignment::A_PAR_TEMPL_OUT
:
13610 case Assignment::A_PAR_TEMPL_INOUT
:
13611 type_str
= ass
->get_Type()->get_genname_template(scope
);
13614 type_str
= ass
->get_Type()->get_genname_value(scope
);
13616 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13617 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
13618 if (ref_expr
.postamble
) {
13619 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
13621 Code::free_expr(&ref_expr
);
13622 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13625 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13626 const string
& lazy_param_id
= value
->get_temporary_id();
13627 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13628 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13629 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
13630 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13633 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
13634 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
13635 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13636 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13637 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
13638 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13641 } // namespace Common