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
:
147 case OPTYPE_UNARYPLUS
: // v1
148 case OPTYPE_UNARYMINUS
:
155 case OPTYPE_CHAR2INT
:
156 case OPTYPE_CHAR2OCT
:
157 case OPTYPE_COMP_RUNNING
:
158 case OPTYPE_COMP_ALIVE
:
159 case OPTYPE_FLOAT2INT
:
160 case OPTYPE_FLOAT2STR
:
165 case OPTYPE_INT2CHAR
:
166 case OPTYPE_INT2FLOAT
:
168 case OPTYPE_INT2UNICHAR
:
170 case OPTYPE_OCT2CHAR
:
175 case OPTYPE_STR2FLOAT
:
179 case OPTYPE_UNICHAR2INT
:
180 case OPTYPE_UNICHAR2CHAR
:
181 case OPTYPE_ENUM2INT
:
182 case OPTYPE_RNDWITHVAL
:
183 case OPTYPE_GET_STRINGENCODING
:
184 case OPTYPE_DECODE_BASE64
:
185 case OPTYPE_REMOVE_BOM
:
186 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
188 case OPTYPE_ADD
: // v1 v2
189 case OPTYPE_SUBTRACT
:
190 case OPTYPE_MULTIPLY
:
214 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
215 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
217 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
218 case OPTYPE_OCT2UNICHAR
:
219 case OPTYPE_ENCODE_BASE64
:
220 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
221 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
224 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
225 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
228 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
229 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
230 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
233 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
234 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
235 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
237 case OPTYPE_DECOMP
: // v1 v2 v3
238 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
239 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
240 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
243 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
244 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
245 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
246 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
248 case OPTYPE_LENGTHOF
: // ti1
249 case OPTYPE_SIZEOF
: // ti1
250 case OPTYPE_VALUEOF
: // ti1
252 case OPTYPE_ISPRESENT
:
253 case OPTYPE_TTCN2STRING
:
254 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
256 case OPTYPE_UNDEF_RUNNING
:
257 case OPTYPE_TMR_READ
:
258 case OPTYPE_TMR_RUNNING
:
259 case OPTYPE_ACTIVATE
:
260 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
262 case OPTYPE_EXECUTE
: // r1 [v2]
263 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
264 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
266 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
267 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
268 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
269 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
270 u
.expr
.b4
= p
.u
.expr
.b4
;
272 case OPTYPE_MATCH
: // v1 t2
273 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
274 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
276 case OPTYPE_ISCHOSEN
: // r1 i2
277 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
278 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
280 case OPTYPE_ISCHOSEN_V
: // v1 i2
281 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
282 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
284 case OPTYPE_ISCHOSEN_T
: // t1 i2
285 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
286 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
288 case OPTYPE_ACTIVATE_REFD
:
289 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
290 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
291 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
293 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
294 u
.expr
.state
= EXPR_CHECKED
;
297 case OPTYPE_EXECUTE_REFD
:
298 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
299 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
300 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
302 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
303 u
.expr
.state
= EXPR_CHECKED
;
305 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
308 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
311 FATAL_ERROR("Value::Value()");
320 u
.refd_fat
= p
.u
.refd_fat
;
323 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
324 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
325 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
328 u
.refered
= p
.u
.refered
->clone();
331 FATAL_ERROR("Value::Value()");
335 void Value::clean_up()
358 case V_UNDEF_LOWERID
:
366 delete u
.str
.val_str
;
367 clean_up_string_elements(u
.str
.str_elements
);
370 delete u
.ustr
.val_ustr
;
371 clean_up_string_elements(u
.ustr
.ustr_elements
);
379 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
380 delete (*u
.oid_comps
)[i
];
381 u
.oid_comps
->clear();
389 delete u
.choice
.alt_name
;
390 delete u
.choice
.alt_value
;
409 delete u
.invoke
.t_list
;
410 delete u
.invoke
.ap_list
;
414 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
423 FATAL_ERROR("Value::clean_up()");
427 void Value::clean_up_expr()
429 switch (u
.expr
.state
) {
431 case EXPR_CHECKING_ERR
:
432 FATAL_ERROR("Value::clean_up_expr()");
436 switch (u
.expr
.v_optype
) {
437 case OPTYPE_RND
: // -
438 case OPTYPE_COMP_NULL
:
439 case OPTYPE_COMP_MTC
:
440 case OPTYPE_COMP_SYSTEM
:
441 case OPTYPE_COMP_SELF
:
442 case OPTYPE_COMP_RUNNING_ANY
:
443 case OPTYPE_COMP_RUNNING_ALL
:
444 case OPTYPE_COMP_ALIVE_ANY
:
445 case OPTYPE_COMP_ALIVE_ALL
:
446 case OPTYPE_TMR_RUNNING_ANY
:
447 case OPTYPE_GETVERDICT
:
448 case OPTYPE_TESTCASENAME
:
450 case OPTYPE_UNARYPLUS
: // v1
451 case OPTYPE_UNARYMINUS
:
458 case OPTYPE_CHAR2INT
:
459 case OPTYPE_CHAR2OCT
:
460 case OPTYPE_COMP_RUNNING
:
461 case OPTYPE_COMP_ALIVE
:
462 case OPTYPE_FLOAT2INT
:
463 case OPTYPE_FLOAT2STR
:
468 case OPTYPE_INT2CHAR
:
469 case OPTYPE_INT2FLOAT
:
471 case OPTYPE_INT2UNICHAR
:
473 case OPTYPE_OCT2CHAR
:
478 case OPTYPE_STR2FLOAT
:
482 case OPTYPE_UNICHAR2INT
:
483 case OPTYPE_UNICHAR2CHAR
:
484 case OPTYPE_ENUM2INT
:
485 case OPTYPE_RNDWITHVAL
:
486 case OPTYPE_REMOVE_BOM
:
487 case OPTYPE_GET_STRINGENCODING
:
488 case OPTYPE_DECODE_BASE64
:
491 case OPTYPE_ADD
: // v1 v2
492 case OPTYPE_SUBTRACT
:
493 case OPTYPE_MULTIPLY
:
517 case OPTYPE_UNICHAR2OCT
:
518 case OPTYPE_OCT2UNICHAR
:
519 case OPTYPE_ENCODE_BASE64
:
537 case OPTYPE_DECOMP
: // v1 v2 v3
548 case OPTYPE_LENGTHOF
: // ti1
549 case OPTYPE_SIZEOF
: // ti1
550 case OPTYPE_VALUEOF
: // ti1
554 case OPTYPE_ISPRESENT
:
555 case OPTYPE_TTCN2STRING
:
558 case OPTYPE_UNDEF_RUNNING
:
559 case OPTYPE_TMR_READ
:
560 case OPTYPE_TMR_RUNNING
:
561 case OPTYPE_ACTIVATE
:
564 case OPTYPE_EXECUTE
: // r1 [v2]
568 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
573 case OPTYPE_MATCH
: // v1 t2
577 case OPTYPE_ISCHOSEN
: // r1 i2
581 case OPTYPE_ISCHOSEN_V
: // v1 i2
585 case OPTYPE_ISCHOSEN_T
: // t1 i2
589 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
591 if(u
.expr
.state
!=EXPR_CHECKED
)
592 delete u
.expr
.t_list2
;
594 delete u
.expr
.ap_list2
;
596 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
598 if(u
.expr
.state
!=EXPR_CHECKED
)
599 delete u
.expr
.t_list2
;
601 delete u
.expr
.ap_list2
;
605 delete u
.expr
.logargs
;
608 FATAL_ERROR("Value::clean_up_expr()");
612 void Value::copy_and_destroy(Value
*src
)
615 valuetype
= src
->valuetype
;
617 // update the pointer used for caching if it points to the value itself
618 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
619 src
->valuetype
= V_ERROR
;
623 Value::Value(valuetype_t p_vt
)
624 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
635 u
.oid_comps
=new vector
<OID_comp
>();
638 u
.ids
=new map
<string
, Identifier
>();
641 FATAL_ERROR("Value::Value()");
645 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
646 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
650 u
.val_bool
=p_val_bool
;
653 FATAL_ERROR("Value::Value()");
657 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
658 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
662 u
.val_Int
=new int_val_t(p_val_Int
);
665 FATAL_ERROR("Value::Value()");
669 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
670 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
677 FATAL_ERROR("Value::Value()");
681 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
682 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
684 if(!p_val_str
) FATAL_ERROR("NULL parameter");
691 set_val_str(p_val_str
);
694 FATAL_ERROR("Value::Value()");
698 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
699 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
701 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
702 set_val_ustr(p_val_ustr
);
703 u
.ustr
.convert_str
= false;
706 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
707 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
709 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
712 u
.char_syms
= p_char_syms
;
715 FATAL_ERROR("Value::Value()");
719 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
720 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
723 FATAL_ERROR("NULL parameter");
727 case V_UNDEF_LOWERID
:
731 FATAL_ERROR("Value::Value()");
735 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
736 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
739 FATAL_ERROR("NULL parameter");
742 u
.choice
.alt_name
=p_id
;
743 u
.choice
.alt_value
=p_val
;
746 FATAL_ERROR("Value::Value()");
750 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
751 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
755 u
.val_Real
=p_val_Real
;
758 FATAL_ERROR("Value::Value()");
762 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
763 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
765 if(!p_vs
) FATAL_ERROR("NULL parameter");
773 FATAL_ERROR("Value::Value()");
777 Value::Value(valuetype_t p_vt
, Value
*p_v
,
778 Ttcn::ParsedActualParameters
*p_t_list
)
779 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
781 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
785 u
.invoke
.t_list
= p_t_list
;
786 u
.invoke
.ap_list
= 0;
789 FATAL_ERROR("Value::Value()");
794 Value::Value(operationtype_t p_optype
)
795 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
797 u
.expr
.v_optype
= p_optype
;
798 u
.expr
.state
= EXPR_NOT_CHECKED
;
801 case OPTYPE_COMP_NULL
:
802 case OPTYPE_COMP_MTC
:
803 case OPTYPE_COMP_SYSTEM
:
804 case OPTYPE_COMP_SELF
:
805 case OPTYPE_COMP_RUNNING_ANY
:
806 case OPTYPE_COMP_RUNNING_ALL
:
807 case OPTYPE_COMP_ALIVE_ANY
:
808 case OPTYPE_COMP_ALIVE_ALL
:
809 case OPTYPE_TMR_RUNNING_ANY
:
810 case OPTYPE_GETVERDICT
:
811 case OPTYPE_TESTCASENAME
:
814 FATAL_ERROR("Value::Value()");
819 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
820 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
822 u
.expr
.v_optype
= p_optype
;
823 u
.expr
.state
= EXPR_NOT_CHECKED
;
825 case OPTYPE_UNARYPLUS
:
826 case OPTYPE_UNARYMINUS
:
833 case OPTYPE_CHAR2INT
:
834 case OPTYPE_CHAR2OCT
:
835 case OPTYPE_COMP_RUNNING
:
836 case OPTYPE_COMP_ALIVE
:
837 case OPTYPE_FLOAT2INT
:
838 case OPTYPE_FLOAT2STR
:
843 case OPTYPE_INT2CHAR
:
844 case OPTYPE_INT2FLOAT
:
846 case OPTYPE_INT2UNICHAR
:
848 case OPTYPE_OCT2CHAR
:
853 case OPTYPE_STR2FLOAT
:
857 case OPTYPE_UNICHAR2INT
:
858 case OPTYPE_UNICHAR2CHAR
:
859 case OPTYPE_ENUM2INT
:
860 case OPTYPE_RNDWITHVAL
:
861 case OPTYPE_REMOVE_BOM
:
862 case OPTYPE_GET_STRINGENCODING
:
863 case OPTYPE_DECODE_BASE64
:
864 if(!p_v1
) FATAL_ERROR("Value::Value()");
868 FATAL_ERROR("Value::Value()");
873 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
874 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
876 u
.expr
.v_optype
= p_optype
;
877 u
.expr
.state
= EXPR_NOT_CHECKED
;
879 case OPTYPE_LENGTHOF
:
885 case OPTYPE_ISPRESENT
:
886 case OPTYPE_TTCN2STRING
:
887 if(!p_ti1
) FATAL_ERROR("Value::Value()");
891 FATAL_ERROR("Value::Value()");
896 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
897 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
899 u
.expr
.v_optype
= p_optype
;
900 u
.expr
.state
= EXPR_NOT_CHECKED
;
902 case OPTYPE_UNDEF_RUNNING
:
903 case OPTYPE_TMR_READ
:
904 case OPTYPE_TMR_RUNNING
:
905 case OPTYPE_ACTIVATE
:
906 if(!p_r1
) FATAL_ERROR("Value::Value()");
910 FATAL_ERROR("Value::Value()");
915 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
916 Ttcn::ParsedActualParameters
*p_ap_list
)
917 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
919 u
.expr
.v_optype
= p_optype
;
920 u
.expr
.state
= EXPR_NOT_CHECKED
;
922 case OPTYPE_ACTIVATE_REFD
:
923 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
925 u
.expr
.t_list2
= p_ap_list
;
928 FATAL_ERROR("Value::Value()");
933 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
934 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
935 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
937 u
.expr
.v_optype
= p_optype
;
938 u
.expr
.state
= EXPR_NOT_CHECKED
;
940 case OPTYPE_EXECUTE_REFD
:
941 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
943 u
.expr
.t_list2
= p_t_list2
;
947 FATAL_ERROR("Value::Value()");
952 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
953 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
955 u
.expr
.v_optype
= p_optype
;
956 u
.expr
.state
= EXPR_NOT_CHECKED
;
959 if(!p_r1
) FATAL_ERROR("Value::Value()");
964 FATAL_ERROR("Value::Value()");
969 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
970 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
971 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
973 u
.expr
.v_optype
= p_optype
;
974 u
.expr
.state
= EXPR_NOT_CHECKED
;
976 case OPTYPE_COMP_CREATE
:
977 if(!p_r1
) FATAL_ERROR("Value::Value()");
984 FATAL_ERROR("Value::Value()");
989 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
990 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
992 u
.expr
.v_optype
= p_optype
;
993 u
.expr
.state
= EXPR_NOT_CHECKED
;
996 case OPTYPE_SUBTRACT
:
997 case OPTYPE_MULTIPLY
:
1018 case OPTYPE_INT2BIT
:
1019 case OPTYPE_INT2HEX
:
1020 case OPTYPE_INT2OCT
:
1021 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1025 case OPTYPE_UNICHAR2OCT
:
1026 case OPTYPE_OCT2UNICHAR
:
1027 case OPTYPE_ENCODE_BASE64
:
1028 if(!p_v1
) FATAL_ERROR("Value::Value()");
1030 // p_v2 may be NULL if there is no second param
1034 FATAL_ERROR("Value::Value()");
1039 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1040 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1041 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1043 u
.expr
.v_optype
= p_optype
;
1044 u
.expr
.state
= EXPR_NOT_CHECKED
;
1046 case OPTYPE_REPLACE
:
1047 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1054 FATAL_ERROR("Value::Value()");
1059 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1060 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1062 u
.expr
.v_optype
= p_optype
;
1063 u
.expr
.state
= EXPR_NOT_CHECKED
;
1066 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1072 FATAL_ERROR("Value::Value()");
1077 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1078 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1080 u
.expr
.v_optype
=p_optype
;
1081 u
.expr
.state
=EXPR_NOT_CHECKED
;
1084 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1090 FATAL_ERROR("Value::Value()");
1095 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1096 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1098 u
.expr
.v_optype
=p_optype
;
1099 u
.expr
.state
=EXPR_NOT_CHECKED
;
1102 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1108 FATAL_ERROR("Value::Value()");
1113 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1114 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1116 u
.expr
.v_optype
= p_optype
;
1117 u
.expr
.state
= EXPR_NOT_CHECKED
;
1120 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1125 FATAL_ERROR("Value::Value()");
1130 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1132 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1134 u
.expr
.v_optype
= p_optype
;
1135 u
.expr
.state
= EXPR_NOT_CHECKED
;
1137 case OPTYPE_ISCHOSEN
:
1138 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1143 FATAL_ERROR("Value::Value()");
1147 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1148 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1150 u
.expr
.v_optype
= p_optype
;
1151 u
.expr
.state
= EXPR_NOT_CHECKED
;
1153 case OPTYPE_LOG2STR
:
1154 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1155 u
.expr
.logargs
= p_logargs
;
1158 FATAL_ERROR("Value::Value()");
1162 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1163 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1165 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1166 switch (p_macrotype
) {
1167 case MACRO_MODULEID
:
1168 case MACRO_FILENAME
:
1169 case MACRO_BFILENAME
:
1170 case MACRO_FILEPATH
:
1171 case MACRO_LINENUMBER
:
1172 case MACRO_LINENUMBER_C
:
1173 case MACRO_DEFINITIONID
:
1175 case MACRO_TESTCASEID
:
1178 FATAL_ERROR("Value::Value()");
1180 u
.macro
= p_macrotype
;
1183 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1184 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1186 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1193 FATAL_ERROR("Value::Value()");
1197 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1198 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1200 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1204 u
.ref
.refd_last
= 0;
1210 FATAL_ERROR("Value::Value()");
1214 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1215 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1217 if(!p_block
) FATAL_ERROR("NULL parameter");
1223 FATAL_ERROR("Value::Value()");
1227 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1228 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1230 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1231 switch (p_verdict
) {
1234 case Verdict_INCONC
:
1239 FATAL_ERROR("Value::Value()");
1241 u
.verdict
= p_verdict
;
1244 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1245 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1247 u
.expr
.v_optype
= p_optype
;
1248 u
.expr
.state
= EXPR_NOT_CHECKED
;
1251 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1256 FATAL_ERROR("Value::Value()");
1265 Value
*Value::clone() const
1267 return new Value(*this);
1270 Value::operationtype_t
Value::get_optype() const
1272 if(valuetype
!=V_EXPR
)
1273 FATAL_ERROR("Value::get_optype()");
1274 return u
.expr
.v_optype
;
1277 void Value::set_my_governor(Type
*p_gov
)
1280 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1284 Type
*Value::get_my_governor() const
1289 void Value::set_fullname(const string
& p_fullname
)
1291 GovernedSimple::set_fullname(p_fullname
);
1294 u
.char_syms
->set_fullname(p_fullname
);
1298 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1299 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1302 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1303 u
.choice
.alt_name
->get_dispname());
1308 u
.val_vs
->set_fullname(p_fullname
);
1312 u
.val_nvs
->set_fullname(p_fullname
);
1315 u
.ref
.ref
->set_fullname(p_fullname
);
1318 u
.refered
->set_fullname(p_fullname
);
1321 u
.invoke
.v
->set_fullname(p_fullname
);
1322 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1323 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1326 set_fullname_expr(p_fullname
);
1333 void Value::set_my_scope(Scope
*p_scope
)
1335 GovernedSimple::set_my_scope(p_scope
);
1338 u
.char_syms
->set_my_scope(p_scope
);
1342 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1343 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1346 u
.choice
.alt_value
->set_my_scope(p_scope
);
1351 u
.val_vs
->set_my_scope(p_scope
);
1355 u
.val_nvs
->set_my_scope(p_scope
);
1358 u
.ref
.ref
->set_my_scope(p_scope
);
1361 u
.refered
->set_my_scope(p_scope
);
1364 u
.invoke
.v
->set_my_scope(p_scope
);
1365 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1366 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1369 set_my_scope_expr(p_scope
);
1376 void Value::set_fullname_expr(const string
& p_fullname
)
1378 switch (u
.expr
.v_optype
) {
1379 case OPTYPE_RND
: // -
1380 case OPTYPE_COMP_NULL
:
1381 case OPTYPE_COMP_MTC
:
1382 case OPTYPE_COMP_SYSTEM
:
1383 case OPTYPE_COMP_SELF
:
1384 case OPTYPE_COMP_RUNNING_ANY
:
1385 case OPTYPE_COMP_RUNNING_ALL
:
1386 case OPTYPE_COMP_ALIVE_ANY
:
1387 case OPTYPE_COMP_ALIVE_ALL
:
1388 case OPTYPE_TMR_RUNNING_ANY
:
1389 case OPTYPE_GETVERDICT
:
1390 case OPTYPE_TESTCASENAME
:
1392 case OPTYPE_UNARYPLUS
: // v1
1393 case OPTYPE_UNARYMINUS
:
1396 case OPTYPE_BIT2HEX
:
1397 case OPTYPE_BIT2INT
:
1398 case OPTYPE_BIT2OCT
:
1399 case OPTYPE_BIT2STR
:
1400 case OPTYPE_CHAR2INT
:
1401 case OPTYPE_CHAR2OCT
:
1402 case OPTYPE_COMP_RUNNING
:
1403 case OPTYPE_COMP_ALIVE
:
1404 case OPTYPE_FLOAT2INT
:
1405 case OPTYPE_FLOAT2STR
:
1406 case OPTYPE_HEX2BIT
:
1407 case OPTYPE_HEX2INT
:
1408 case OPTYPE_HEX2OCT
:
1409 case OPTYPE_HEX2STR
:
1410 case OPTYPE_INT2CHAR
:
1411 case OPTYPE_INT2FLOAT
:
1412 case OPTYPE_INT2STR
:
1413 case OPTYPE_INT2UNICHAR
:
1414 case OPTYPE_OCT2BIT
:
1415 case OPTYPE_OCT2CHAR
:
1416 case OPTYPE_OCT2HEX
:
1417 case OPTYPE_OCT2INT
:
1418 case OPTYPE_OCT2STR
:
1419 case OPTYPE_STR2BIT
:
1420 case OPTYPE_STR2FLOAT
:
1421 case OPTYPE_STR2HEX
:
1422 case OPTYPE_STR2INT
:
1423 case OPTYPE_STR2OCT
:
1424 case OPTYPE_UNICHAR2INT
:
1425 case OPTYPE_UNICHAR2CHAR
:
1426 case OPTYPE_ENUM2INT
:
1427 case OPTYPE_RNDWITHVAL
:
1428 case OPTYPE_REMOVE_BOM
:
1429 case OPTYPE_GET_STRINGENCODING
:
1430 case OPTYPE_DECODE_BASE64
:
1431 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1433 case OPTYPE_ADD
: // v1 v2
1434 case OPTYPE_SUBTRACT
:
1435 case OPTYPE_MULTIPLY
:
1456 case OPTYPE_INT2BIT
:
1457 case OPTYPE_INT2HEX
:
1458 case OPTYPE_INT2OCT
:
1459 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1460 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1462 case OPTYPE_UNICHAR2OCT
:
1463 case OPTYPE_OCT2UNICHAR
:
1464 case OPTYPE_ENCODE_BASE64
:
1465 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1466 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1469 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1470 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1473 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1474 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1475 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1478 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1479 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1480 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1482 case OPTYPE_DECOMP
: // v1 v2 v3
1483 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1484 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1485 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1487 case OPTYPE_REPLACE
:
1488 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1489 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1490 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1491 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1493 case OPTYPE_LENGTHOF
: // ti1
1494 case OPTYPE_SIZEOF
: // ti1
1495 case OPTYPE_VALUEOF
: // ti1
1496 case OPTYPE_ISVALUE
:
1497 case OPTYPE_ISBOUND
:
1499 case OPTYPE_ISPRESENT
:
1500 case OPTYPE_TTCN2STRING
:
1501 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1503 case OPTYPE_UNDEF_RUNNING
: // r1
1504 case OPTYPE_TMR_READ
:
1505 case OPTYPE_TMR_RUNNING
:
1506 case OPTYPE_ACTIVATE
:
1507 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1509 case OPTYPE_EXECUTE
: // r1 [v2]
1510 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1511 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1513 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1514 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1515 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1516 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1518 case OPTYPE_MATCH
: // v1 t2
1519 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1520 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1522 case OPTYPE_ISCHOSEN
: // r1 i2
1523 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1525 case OPTYPE_ISCHOSEN_V
: // v1 i2
1526 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1528 case OPTYPE_ISCHOSEN_T
: // t1 i2
1529 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1531 case OPTYPE_ACTIVATE_REFD
:
1532 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1533 if(u
.expr
.state
!=EXPR_CHECKED
)
1534 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1536 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1538 case OPTYPE_EXECUTE_REFD
:
1539 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1540 if(u
.expr
.state
!=EXPR_CHECKED
)
1541 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1543 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1545 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1547 case OPTYPE_LOG2STR
:
1548 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1551 FATAL_ERROR("Value::set_fullname_expr()");
1555 void Value::set_my_scope_expr(Scope
*p_scope
)
1557 switch (u
.expr
.v_optype
) {
1558 case OPTYPE_RND
: // -
1559 case OPTYPE_COMP_NULL
:
1560 case OPTYPE_COMP_MTC
:
1561 case OPTYPE_COMP_SYSTEM
:
1562 case OPTYPE_COMP_SELF
:
1563 case OPTYPE_COMP_RUNNING_ANY
:
1564 case OPTYPE_COMP_RUNNING_ALL
:
1565 case OPTYPE_COMP_ALIVE_ANY
:
1566 case OPTYPE_COMP_ALIVE_ALL
:
1567 case OPTYPE_TMR_RUNNING_ANY
:
1568 case OPTYPE_GETVERDICT
:
1569 case OPTYPE_TESTCASENAME
:
1571 case OPTYPE_UNARYPLUS
: // v1
1572 case OPTYPE_UNARYMINUS
:
1575 case OPTYPE_BIT2HEX
:
1576 case OPTYPE_BIT2INT
:
1577 case OPTYPE_BIT2OCT
:
1578 case OPTYPE_BIT2STR
:
1579 case OPTYPE_CHAR2INT
:
1580 case OPTYPE_CHAR2OCT
:
1581 case OPTYPE_COMP_RUNNING
:
1582 case OPTYPE_COMP_ALIVE
:
1583 case OPTYPE_FLOAT2INT
:
1584 case OPTYPE_FLOAT2STR
:
1585 case OPTYPE_HEX2BIT
:
1586 case OPTYPE_HEX2INT
:
1587 case OPTYPE_HEX2OCT
:
1588 case OPTYPE_HEX2STR
:
1589 case OPTYPE_INT2CHAR
:
1590 case OPTYPE_INT2FLOAT
:
1591 case OPTYPE_INT2STR
:
1592 case OPTYPE_INT2UNICHAR
:
1593 case OPTYPE_OCT2BIT
:
1594 case OPTYPE_OCT2CHAR
:
1595 case OPTYPE_OCT2HEX
:
1596 case OPTYPE_OCT2INT
:
1597 case OPTYPE_OCT2STR
:
1598 case OPTYPE_STR2BIT
:
1599 case OPTYPE_STR2FLOAT
:
1600 case OPTYPE_STR2HEX
:
1601 case OPTYPE_STR2INT
:
1602 case OPTYPE_STR2OCT
:
1603 case OPTYPE_UNICHAR2INT
:
1604 case OPTYPE_UNICHAR2CHAR
:
1605 case OPTYPE_ENUM2INT
:
1606 case OPTYPE_RNDWITHVAL
:
1607 case OPTYPE_REMOVE_BOM
:
1608 case OPTYPE_GET_STRINGENCODING
:
1609 case OPTYPE_DECODE_BASE64
:
1610 u
.expr
.v1
->set_my_scope(p_scope
);
1612 case OPTYPE_ADD
: // v1 v2
1613 case OPTYPE_SUBTRACT
:
1614 case OPTYPE_MULTIPLY
:
1635 case OPTYPE_INT2BIT
:
1636 case OPTYPE_INT2HEX
:
1637 case OPTYPE_INT2OCT
:
1638 u
.expr
.v1
->set_my_scope(p_scope
);
1639 u
.expr
.v2
->set_my_scope(p_scope
);
1641 case OPTYPE_UNICHAR2OCT
:
1642 case OPTYPE_OCT2UNICHAR
:
1643 case OPTYPE_ENCODE_BASE64
:
1644 u
.expr
.v1
->set_my_scope(p_scope
);
1645 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1648 u
.expr
.r1
->set_my_scope(p_scope
);
1649 u
.expr
.r2
->set_my_scope(p_scope
);
1652 u
.expr
.ti1
->set_my_scope(p_scope
);
1653 u
.expr
.v2
->set_my_scope(p_scope
);
1654 u
.expr
.v3
->set_my_scope(p_scope
);
1657 u
.expr
.ti1
->set_my_scope(p_scope
);
1658 u
.expr
.t2
->set_my_scope(p_scope
);
1659 u
.expr
.v3
->set_my_scope(p_scope
);
1661 case OPTYPE_DECOMP
: // v1 v2 v3
1662 u
.expr
.v1
->set_my_scope(p_scope
);
1663 u
.expr
.v2
->set_my_scope(p_scope
);
1664 u
.expr
.v3
->set_my_scope(p_scope
);
1666 case OPTYPE_REPLACE
:
1667 u
.expr
.ti1
->set_my_scope(p_scope
);
1668 u
.expr
.v2
->set_my_scope(p_scope
);
1669 u
.expr
.v3
->set_my_scope(p_scope
);
1670 u
.expr
.ti4
->set_my_scope(p_scope
);
1672 case OPTYPE_LENGTHOF
: // ti1
1673 case OPTYPE_SIZEOF
: // ti1
1674 case OPTYPE_VALUEOF
: // ti1
1675 case OPTYPE_ISVALUE
:
1676 case OPTYPE_ISBOUND
:
1678 case OPTYPE_ISPRESENT
:
1679 case OPTYPE_TTCN2STRING
:
1680 u
.expr
.ti1
->set_my_scope(p_scope
);
1682 case OPTYPE_UNDEF_RUNNING
: // r1
1683 case OPTYPE_TMR_READ
:
1684 case OPTYPE_TMR_RUNNING
:
1685 case OPTYPE_ACTIVATE
:
1686 u
.expr
.r1
->set_my_scope(p_scope
);
1688 case OPTYPE_EXECUTE
: // r1 [v2]
1689 u
.expr
.r1
->set_my_scope(p_scope
);
1690 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1692 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1693 u
.expr
.r1
->set_my_scope(p_scope
);
1694 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1695 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1697 case OPTYPE_MATCH
: // v1 t2
1698 u
.expr
.v1
->set_my_scope(p_scope
);
1699 u
.expr
.t2
->set_my_scope(p_scope
);
1701 case OPTYPE_ISCHOSEN
: // r1 i2
1702 u
.expr
.r1
->set_my_scope(p_scope
);
1704 case OPTYPE_ISCHOSEN_V
: // v1 i2
1705 u
.expr
.v1
->set_my_scope(p_scope
);
1707 case OPTYPE_ISCHOSEN_T
: // t1 i2
1708 u
.expr
.t1
->set_my_scope(p_scope
);
1710 case OPTYPE_ACTIVATE_REFD
:
1711 u
.expr
.v1
->set_my_scope(p_scope
);
1712 if(u
.expr
.state
!=EXPR_CHECKED
) {
1713 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1715 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1717 case OPTYPE_EXECUTE_REFD
:
1718 u
.expr
.v1
->set_my_scope(p_scope
);
1719 if(u
.expr
.state
!=EXPR_CHECKED
) {
1720 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1722 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1725 u
.expr
.v3
->set_my_scope(p_scope
);
1727 case OPTYPE_LOG2STR
:
1728 u
.expr
.logargs
->set_my_scope(p_scope
);
1731 FATAL_ERROR("Value::set_my_scope_expr()");
1735 void Value::set_genname_recursive(const string
& p_genname
)
1737 size_t genname_len
= p_genname
.size();
1738 if (genname_len
>= 4 &&
1739 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1740 // if the genname ends with ()() (i.e. the value stands for an optional
1741 // field) then drop the last () from the own genname, but leave it for
1742 // the embedded values
1743 set_genname(p_genname
.substr(0, genname_len
- 2));
1744 } else set_genname(p_genname
);
1747 string
embedded_genname(p_genname
);
1748 embedded_genname
+= '.';
1749 // If this is a choice value for an anytype, prepend the AT_ prefix
1750 // to the name of the alternative. The genname is used later in
1751 // Common::Value::generate_code_init_se()
1752 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1753 embedded_genname
+= "AT_";
1754 embedded_genname
+= u
.choice
.alt_name
->get_name();
1755 embedded_genname
+= "()";
1756 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1760 if (!is_indexed()) {
1761 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1762 for (size_t i
= 0; i
< nof_vs
; i
++) {
1763 string
embedded_genname(p_genname
);
1764 embedded_genname
+= '[';
1765 embedded_genname
+= Int2string(i
);
1766 embedded_genname
+= ']';
1767 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1770 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1771 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1772 string
embedded_genname(p_genname
);
1773 embedded_genname
+= '[';
1774 embedded_genname
+= Int2string(i
);
1775 embedded_genname
+= ']';
1776 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1777 ->set_genname_recursive(embedded_genname
);
1782 if (!my_governor
) return; // error recovery
1783 Type
*type
= my_governor
->get_type_refd_last();
1784 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1785 Int offset
= type
->get_dimension()->get_offset();
1786 if (!is_indexed()) {
1787 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1788 for (size_t i
= 0; i
< nof_vs
; i
++) {
1789 string
embedded_genname(p_genname
);
1790 embedded_genname
+= '[';
1791 embedded_genname
+= Int2string(offset
+ i
);
1792 embedded_genname
+= ']';
1793 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1796 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1797 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1798 string
embedded_genname(p_genname
);
1799 embedded_genname
+= '[';
1800 embedded_genname
+= Int2string(offset
+ i
);
1801 embedded_genname
+= ']';
1802 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1803 ->set_genname_recursive(embedded_genname
);
1809 if (!my_governor
) return; // error recovery
1810 Type
*t
= my_governor
->get_type_refd_last();
1811 if (!t
->is_secho()) return; // error recovery
1812 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1813 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1814 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1815 const Identifier
& id
= nv
->get_name();
1816 if (!t
->has_comp_withName(id
)) return; // error recovery
1817 string
embedded_genname(p_genname
);
1818 embedded_genname
+= '.';
1819 embedded_genname
+= id
.get_name();
1820 embedded_genname
+= "()";
1821 if (t
->get_comp_byName(id
)->get_is_optional())
1822 embedded_genname
+= "()";
1823 nv
->get_value()->set_genname_recursive(embedded_genname
);
1831 void Value::set_genname_prefix(const char *p_genname_prefix
)
1833 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1836 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1841 if (!is_indexed()) {
1842 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1843 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1845 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1846 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1847 ->set_genname_prefix(p_genname_prefix
);
1852 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1853 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1854 ->set_genname_prefix(p_genname_prefix
);
1861 void Value::set_code_section(code_section_t p_code_section
)
1863 GovernedSimple::set_code_section(p_code_section
);
1866 switch (u
.expr
.v_optype
) {
1867 case OPTYPE_RND
: // -
1868 case OPTYPE_COMP_NULL
:
1869 case OPTYPE_COMP_MTC
:
1870 case OPTYPE_COMP_SYSTEM
:
1871 case OPTYPE_COMP_SELF
:
1872 case OPTYPE_COMP_RUNNING_ANY
:
1873 case OPTYPE_COMP_RUNNING_ALL
:
1874 case OPTYPE_COMP_ALIVE_ANY
:
1875 case OPTYPE_COMP_ALIVE_ALL
:
1876 case OPTYPE_TMR_RUNNING_ANY
:
1877 case OPTYPE_GETVERDICT
:
1878 case OPTYPE_TESTCASENAME
:
1880 case OPTYPE_UNARYPLUS
: // v1
1881 case OPTYPE_UNARYMINUS
:
1884 case OPTYPE_BIT2HEX
:
1885 case OPTYPE_BIT2INT
:
1886 case OPTYPE_BIT2OCT
:
1887 case OPTYPE_BIT2STR
:
1888 case OPTYPE_CHAR2INT
:
1889 case OPTYPE_CHAR2OCT
:
1890 case OPTYPE_COMP_RUNNING
:
1891 case OPTYPE_COMP_ALIVE
:
1892 case OPTYPE_FLOAT2INT
:
1893 case OPTYPE_FLOAT2STR
:
1894 case OPTYPE_HEX2BIT
:
1895 case OPTYPE_HEX2INT
:
1896 case OPTYPE_HEX2OCT
:
1897 case OPTYPE_HEX2STR
:
1898 case OPTYPE_INT2CHAR
:
1899 case OPTYPE_INT2FLOAT
:
1900 case OPTYPE_INT2STR
:
1901 case OPTYPE_INT2UNICHAR
:
1902 case OPTYPE_OCT2BIT
:
1903 case OPTYPE_OCT2CHAR
:
1904 case OPTYPE_OCT2HEX
:
1905 case OPTYPE_OCT2INT
:
1906 case OPTYPE_OCT2STR
:
1907 case OPTYPE_STR2BIT
:
1908 case OPTYPE_STR2FLOAT
:
1909 case OPTYPE_STR2HEX
:
1910 case OPTYPE_STR2INT
:
1911 case OPTYPE_STR2OCT
:
1912 case OPTYPE_UNICHAR2INT
:
1913 case OPTYPE_UNICHAR2CHAR
:
1914 case OPTYPE_ENUM2INT
:
1915 case OPTYPE_RNDWITHVAL
:
1916 case OPTYPE_GET_STRINGENCODING
:
1917 case OPTYPE_DECODE_BASE64
:
1918 case OPTYPE_REMOVE_BOM
:
1919 u
.expr
.v1
->set_code_section(p_code_section
);
1921 case OPTYPE_ADD
: // v1 v2
1922 case OPTYPE_SUBTRACT
:
1923 case OPTYPE_MULTIPLY
:
1944 case OPTYPE_INT2BIT
:
1945 case OPTYPE_INT2HEX
:
1946 case OPTYPE_INT2OCT
:
1947 u
.expr
.v1
->set_code_section(p_code_section
);
1948 u
.expr
.v2
->set_code_section(p_code_section
);
1950 case OPTYPE_UNICHAR2OCT
:
1951 case OPTYPE_OCT2UNICHAR
:
1952 case OPTYPE_ENCODE_BASE64
:
1953 u
.expr
.v1
->set_code_section(p_code_section
);
1954 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
1957 u
.expr
.r1
->set_code_section(p_code_section
);
1958 u
.expr
.r2
->set_code_section(p_code_section
);
1961 u
.expr
.ti1
->set_code_section(p_code_section
);
1962 u
.expr
.v2
->set_code_section(p_code_section
);
1963 u
.expr
.v3
->set_code_section(p_code_section
);
1966 u
.expr
.ti1
->set_code_section(p_code_section
);
1967 u
.expr
.t2
->set_code_section(p_code_section
);
1968 u
.expr
.v3
->set_code_section(p_code_section
);
1970 case OPTYPE_DECOMP
: // v1 v2 v3
1971 u
.expr
.v1
->set_code_section(p_code_section
);
1972 u
.expr
.v2
->set_code_section(p_code_section
);
1973 u
.expr
.v3
->set_code_section(p_code_section
);
1975 case OPTYPE_REPLACE
:
1976 u
.expr
.ti1
->set_code_section(p_code_section
);
1977 u
.expr
.v2
->set_code_section(p_code_section
);
1978 u
.expr
.v3
->set_code_section(p_code_section
);
1979 u
.expr
.ti4
->set_code_section(p_code_section
);
1981 case OPTYPE_LENGTHOF
: // ti1
1982 case OPTYPE_SIZEOF
: // ti1
1983 case OPTYPE_VALUEOF
: // ti1
1984 case OPTYPE_ISVALUE
:
1985 case OPTYPE_ISBOUND
:
1987 case OPTYPE_ISPRESENT
:
1988 case OPTYPE_TTCN2STRING
:
1989 u
.expr
.ti1
->set_code_section(p_code_section
);
1991 case OPTYPE_UNDEF_RUNNING
: // r1
1992 case OPTYPE_TMR_READ
:
1993 case OPTYPE_TMR_RUNNING
:
1994 case OPTYPE_ACTIVATE
:
1995 u
.expr
.r1
->set_code_section(p_code_section
);
1997 case OPTYPE_EXECUTE
: // r1 [v2]
1998 u
.expr
.r1
->set_code_section(p_code_section
);
1999 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2001 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2002 u
.expr
.r1
->set_code_section(p_code_section
);
2003 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2004 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2006 case OPTYPE_MATCH
: // v1 t2
2007 u
.expr
.v1
->set_code_section(p_code_section
);
2008 u
.expr
.t2
->set_code_section(p_code_section
);
2010 case OPTYPE_ISCHOSEN
: // r1 i2
2011 u
.expr
.r1
->set_code_section(p_code_section
);
2013 case OPTYPE_ISCHOSEN_V
: // v1 i2
2014 u
.expr
.v1
->set_code_section(p_code_section
);
2016 case OPTYPE_ISCHOSEN_T
: // t1 i2
2017 u
.expr
.t1
->set_code_section(p_code_section
);
2019 case OPTYPE_ACTIVATE_REFD
:
2020 u
.expr
.v1
->set_code_section(p_code_section
);
2021 if(u
.expr
.state
!=EXPR_CHECKED
)
2022 u
.expr
.t_list2
->set_code_section(p_code_section
);
2024 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2025 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2026 u
.expr
.state
= EXPR_CHECKED
;
2029 case OPTYPE_EXECUTE_REFD
:
2030 u
.expr
.v1
->set_code_section(p_code_section
);
2031 if(u
.expr
.state
!=EXPR_CHECKED
)
2032 u
.expr
.t_list2
->set_code_section(p_code_section
);
2034 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2035 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2036 u
.expr
.state
= EXPR_CHECKED
;
2039 u
.expr
.v3
->set_code_section(p_code_section
);
2041 case OPTYPE_LOG2STR
:
2042 u
.expr
.logargs
->set_code_section(p_code_section
);
2045 FATAL_ERROR("Value::set_code_section()");
2049 u
.choice
.alt_value
->set_code_section(p_code_section
);
2054 if (!is_indexed()) {
2055 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2056 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2058 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2059 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2064 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2065 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2066 ->set_code_section(p_code_section
);
2069 u
.ref
.ref
->set_code_section(p_code_section
);
2072 u
.refered
->set_code_section(p_code_section
);
2075 u
.invoke
.v
->set_code_section(p_code_section
);
2076 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2077 if(u
.invoke
.ap_list
)
2078 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2079 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2086 void Value::change_sign()
2090 *u
.val_Int
=-*u
.val_Int
;
2098 FATAL_ERROR("Value::change_sign()");
2102 void Value::add_oid_comp(OID_comp
* p_comp
)
2105 FATAL_ERROR("NULL parameter");
2106 u
.oid_comps
->add(p_comp
);
2107 p_comp
->set_fullname(get_fullname()+"."
2108 +Int2string(u
.oid_comps
->size()));
2109 p_comp
->set_my_scope(my_scope
);
2112 void Value::set_valuetype(valuetype_t p_valuetype
)
2114 if (valuetype
== V_ERROR
) return;
2115 else if (p_valuetype
== V_ERROR
) {
2116 if(valuetype
==V_EXPR
) {
2117 switch(u
.expr
.state
) {
2119 u
.expr
.state
=EXPR_CHECKING_ERR
;
2121 case EXPR_CHECKING_ERR
:
2128 valuetype
= V_ERROR
;
2132 case V_UNDEF_LOWERID
:
2133 switch(p_valuetype
) {
2138 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2139 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2140 u
.ref
.ref
->set_my_scope(get_my_scope());
2141 u
.ref
.ref
->set_fullname(get_fullname());
2142 u
.ref
.ref
->set_location(*this);
2143 u
.ref
.refd_last
= 0;
2146 FATAL_ERROR("Value::set_valuetype()");
2149 case V_UNDEF_BLOCK
: {
2150 Block
*t_block
=u
.block
;
2152 switch(p_valuetype
) {
2154 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2155 v
=dynamic_cast<Value
*>(node
);
2158 u
.ids
=new map
<string
, Identifier
>();
2161 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2165 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2166 v
=dynamic_cast<Value
*>(node
);
2169 u
.val_vs
=new Values();
2172 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2174 u
.val_vs
->set_my_scope(get_my_scope());
2175 u
.val_vs
->set_fullname(get_fullname());
2178 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2179 v
=dynamic_cast<Value
*>(node
);
2182 u
.val_vs
=new Values();
2185 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2187 u
.val_vs
->set_my_scope(get_my_scope());
2188 u
.val_vs
->set_fullname(get_fullname());
2191 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2192 v
=dynamic_cast<Value
*>(node
);
2195 u
.val_nvs
=new NamedValues();
2198 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2200 u
.val_nvs
->set_my_scope(get_my_scope());
2201 u
.val_nvs
->set_fullname(get_fullname());
2204 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2205 v
=dynamic_cast<Value
*>(node
);
2208 u
.val_nvs
=new NamedValues();
2211 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2213 u
.val_nvs
->set_my_scope(get_my_scope());
2214 u
.val_nvs
->set_fullname(get_fullname());
2217 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2218 v
=dynamic_cast<Value
*>(node
);
2221 u
.oid_comps
=new vector
<OID_comp
>();
2224 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2226 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2227 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2230 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2231 v
=dynamic_cast<Value
*>(node
);
2234 u
.oid_comps
=new vector
<OID_comp
>();
2237 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2239 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2240 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2243 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2244 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2247 u
.char_syms
=new CharSyms();
2249 u
.char_syms
->set_my_scope(get_my_scope());
2250 u
.char_syms
->set_fullname(get_fullname());
2253 FATAL_ERROR("Value::set_valuetype()");
2259 if (p_valuetype
== V_USTR
) {
2260 Value
*v_last
= get_value_refd_last();
2261 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2262 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2265 u
.ustr
.convert_str
= true; // will be converted back to string
2266 } else FATAL_ERROR("Value::set_valuetype()");
2269 switch(p_valuetype
) {
2271 const string
& str
= u
.char_syms
->get_string();
2273 set_val_str(new string(str
));
2276 const ustring
& ustr
= u
.char_syms
->get_ustring();
2278 set_val_ustr(new ustring(ustr
));
2279 u
.ustr
.convert_str
= false;
2281 case V_ISO2022STR
: {
2282 const string
& str
= u
.char_syms
->get_iso2022string();
2284 set_val_str(new string(str
));
2287 FATAL_ERROR("Value::set_valuetype()");
2292 if (p_valuetype
== V_REAL
)
2293 val_Real
= u
.val_Int
->to_real();
2294 else FATAL_ERROR("Value::set_valuetype()");
2296 u
.val_Real
= val_Real
;
2299 clean_up_string_elements(u
.str
.str_elements
);
2300 string
*old_str
= u
.str
.val_str
;
2301 switch(p_valuetype
) {
2303 set_val_str(hex2bit(*old_str
));
2306 set_val_str(asn_hex2oct(*old_str
));
2309 FATAL_ERROR("Value::set_valuetype()");
2314 clean_up_string_elements(u
.str
.str_elements
);
2315 if (p_valuetype
== V_OSTR
) {
2316 string
*old_str
= u
.str
.val_str
;
2317 set_val_str(asn_bit2oct(*old_str
));
2319 } else FATAL_ERROR("Value::set_valuetype()");
2322 clean_up_string_elements(u
.str
.str_elements
);
2323 switch(p_valuetype
) {
2325 string
*old_str
= u
.str
.val_str
;
2326 set_val_ustr(new ustring(*old_str
));
2327 u
.ustr
.convert_str
= true; // will be converted back to string
2334 FATAL_ERROR("Value::set_valuetype()");
2335 } // switch p_valuetype
2338 clean_up_string_elements(u
.ustr
.ustr_elements
);
2339 switch(p_valuetype
) {
2341 ustring
*old_str
= u
.ustr
.val_ustr
;
2342 size_t nof_chars
= old_str
->size();
2343 bool warning_flag
= false;
2344 for (size_t i
= 0; i
< nof_chars
; i
++) {
2345 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2346 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2347 error("This string value cannot contain multiple-byte characters, "
2348 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2349 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2351 p_valuetype
= V_ERROR
;
2353 } else if (uchar
.cell
> 127 && !warning_flag
) {
2354 warning("This string value may not contain characters with code "
2355 "higher than 127, but it has character with code %u (0x%02X) "
2356 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2357 warning_flag
= true;
2360 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2364 error("ISO-10646 string value cannot be converted to "
2366 delete u
.ustr
.val_ustr
;
2367 p_valuetype
= V_ERROR
;
2370 FATAL_ERROR("Value::set_valuetype()");
2371 } // switch p_valuetype
2374 switch (p_valuetype
) {
2376 NamedValues
*nvs
= u
.val_nvs
;
2377 if (nvs
->get_nof_nvs() < 1) {
2378 error("Union value must have one active field");
2380 valuetype
= V_ERROR
;
2382 } else if (nvs
->get_nof_nvs() > 1) {
2383 error("Only one field was expected in union value instead of %lu",
2384 (unsigned long) nvs
->get_nof_nvs());
2386 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2387 u
.choice
.alt_name
= nv
->get_name().clone();
2388 u
.choice
.alt_value
= nv
->steal_value();
2395 NamedValues
*nvs
= u
.val_nvs
;
2399 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2400 if (nvs
->has_nv_withName(id_mant
)) {
2401 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2402 ->get_value_refd_last();
2403 if (v_tmp
->get_valuetype() == V_INT
) {
2404 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2405 if (*i_mant_int
> INT_MAX
) {
2406 error("Mantissa `%s' should be less than `%d'",
2407 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2410 i_mant
= i_mant_int
->get_val();
2418 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2419 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2420 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2421 Value
*v_tmp
= v
->get_value_refd_last();
2422 if (v_tmp
->get_valuetype() == V_INT
) {
2423 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2424 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2425 v
->error("Base of the REAL must be 2 or 10");
2428 i_base
= i_base_int
->get_val();
2436 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2437 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2438 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2439 ->get_value_refd_last();
2440 if (v_tmp
->get_valuetype() == V_INT
) {
2441 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2442 if (*i_exp_int
> INT_MAX
) {
2443 error("Exponent `%s' should be less than `%d'",
2444 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2447 i_exp
= i_exp_int
->get_val();
2456 valuetype
= V_ERROR
;
2459 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2460 static_cast<double>(i_exp
));
2463 FATAL_ERROR("Value::set_valuetype()");
2467 switch (p_valuetype
) {
2469 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2470 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2471 Type
*t
= my_governor
->get_type_refd_last();
2472 switch (t
->get_typetype()) {
2477 FATAL_ERROR("Value::set_valuetype()");
2479 Values
*vals
= u
.val_vs
;
2480 size_t nof_vals
= vals
->get_nof_vs();
2481 size_t nof_comps
= t
->get_nof_comps();
2482 if (nof_vals
> nof_comps
) {
2483 error("Too many elements in value list notation for type `%s': "
2484 "%lu was expected instead of %lu",
2485 t
->get_typename().c_str(),
2486 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2490 if (nof_vals
<= nof_comps
) {
2491 upper_limit
= nof_vals
;
2494 upper_limit
= nof_comps
;
2497 u
.val_nvs
= new NamedValues
;
2498 for (size_t i
= 0; i
< upper_limit
; i
++) {
2499 Value
*v
= vals
->steal_v_byIndex(i
);
2500 if (v
->valuetype
!= V_NOTUSED
) {
2504 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2505 nv
->set_location(*v
);
2506 u
.val_nvs
->add_nv(nv
);
2508 u
.val_nvs
->set_my_scope(get_my_scope());
2509 u
.val_nvs
->set_fullname(get_fullname());
2511 if (allnotused
&& nof_vals
> 0)
2512 warning("All elements of value list notation for type `%s' are not "
2513 "used symbols (`-')", t
->get_typename().c_str());
2516 // { } -> empty set value
2517 if (u
.val_vs
->get_nof_vs() != 0)
2518 FATAL_ERROR("Value::set_valuetype()");
2520 u
.val_nvs
= new NamedValues
;
2524 // SEQOF -> SETOF or ARRAY: trivial
2527 FATAL_ERROR("Value::set_valuetype()");
2531 switch (p_valuetype
) {
2532 case V_DEFAULT_NULL
:
2537 FATAL_ERROR("Value::set_valuetype()");
2541 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2542 FATAL_ERROR("Value::set_valuetype()");
2546 FATAL_ERROR("Value::set_valuetype()");
2548 valuetype
=p_valuetype
;
2551 void Value::set_valuetype_COMP_NULL()
2553 if(valuetype
== V_ERROR
) return;
2554 if(valuetype
==V_TTCN3_NULL
) {
2556 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2557 // Nothing to check.
2558 u
.expr
.state
=EXPR_CHECKED
;
2560 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2563 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2565 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2567 u
.val_Int
= new int_val_t(p_val_int
);
2569 } else FATAL_ERROR("Value::set_valuetype()");
2572 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2574 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2578 } else FATAL_ERROR("Value::set_valuetype()");
2581 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2583 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2587 } else FATAL_ERROR("Value::set_valuetype()");
2590 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2592 switch (p_valuetype
) {
2596 if (valuetype
== V_REFER
&& p_ass
) break;
2599 FATAL_ERROR("Value::set_valuetype()");
2603 valuetype
= p_valuetype
;
2606 bool Value::is_undef_lowerid()
2608 switch (valuetype
) {
2609 case V_UNDEF_LOWERID
:
2612 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2613 !u
.expr
.ti1
->get_DerivedRef()) {
2614 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2622 const Identifier
& Value::get_undef_lowerid()
2624 switch (valuetype
) {
2625 case V_UNDEF_LOWERID
:
2628 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2629 FATAL_ERROR("Value::get_undef_lowerid()");
2630 return u
.expr
.ti1
->get_Template()->get_specific_value()
2631 ->get_undef_lowerid();
2633 FATAL_ERROR("Value::get_undef_lowerid()");
2635 const Identifier
*dummy
= 0;
2639 void Value::set_lowerid_to_ref()
2641 switch (valuetype
) {
2642 case V_UNDEF_LOWERID
:
2643 set_valuetype(V_REFD
);
2646 // if the governor of the expression is not known (in log(), etc...)
2647 // then the governor is taken from the reference (using
2648 // v1/ti1->get_expr_governor()), but that runs before the
2649 // params were checked, this smells like a workaround :)
2650 switch (u
.expr
.v_optype
) {
2653 u
.expr
.v1
->set_lowerid_to_ref();
2656 u
.expr
.v1
->set_lowerid_to_ref();
2657 u
.expr
.v2
->set_lowerid_to_ref();
2659 case OPTYPE_VALUEOF
:
2660 case OPTYPE_ISVALUE
:
2661 case OPTYPE_ISBOUND
:
2662 case OPTYPE_ISPRESENT
:
2665 case OPTYPE_REPLACE
:
2666 case OPTYPE_TTCN2STRING
:
2667 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2668 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2669 "In the operand of operation `%s'",
2671 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2673 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2674 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2675 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2676 "In the operand of operation `%s'",
2678 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2681 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2682 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2683 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2684 "In the operand of operation `%s'",
2686 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2699 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2701 switch (valuetype
) {
2709 case V_UNDEF_LOWERID
:
2716 return Type::T_UNDEF
;
2720 FATAL_ERROR("Value::get_expr_returntype()");
2722 return Type::T_ERROR
;
2725 Type
*t
= get_expr_governor(exp_val
);
2726 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2727 else return Type::T_ERROR
; }
2729 return Type::T_FUNCTION
;
2731 return Type::T_ALTSTEP
;
2733 return Type::T_TESTCASE
;
2735 switch(u
.expr
.v_optype
) {
2736 case OPTYPE_COMP_NULL
:
2737 case OPTYPE_COMP_MTC
:
2738 case OPTYPE_COMP_SYSTEM
:
2739 case OPTYPE_COMP_SELF
:
2740 case OPTYPE_COMP_CREATE
:
2741 return Type::T_COMPONENT
;
2742 case OPTYPE_UNDEF_RUNNING
:
2743 case OPTYPE_COMP_RUNNING
:
2744 case OPTYPE_COMP_RUNNING_ANY
:
2745 case OPTYPE_COMP_RUNNING_ALL
:
2746 case OPTYPE_COMP_ALIVE
:
2747 case OPTYPE_COMP_ALIVE_ANY
:
2748 case OPTYPE_COMP_ALIVE_ALL
:
2749 case OPTYPE_TMR_RUNNING
:
2750 case OPTYPE_TMR_RUNNING_ANY
:
2762 case OPTYPE_ISPRESENT
:
2763 case OPTYPE_ISCHOSEN
:
2764 case OPTYPE_ISCHOSEN_V
:
2765 case OPTYPE_ISCHOSEN_T
:
2766 case OPTYPE_ISVALUE
:
2767 case OPTYPE_ISBOUND
:
2768 return Type::T_BOOL
;
2769 case OPTYPE_GETVERDICT
:
2770 return Type::T_VERDICT
;
2771 case OPTYPE_VALUEOF
: {
2772 Error_Context
cntxt(this, "In the operand of operation `%s'",
2774 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2775 case OPTYPE_TMR_READ
:
2776 case OPTYPE_INT2FLOAT
:
2777 case OPTYPE_STR2FLOAT
:
2779 case OPTYPE_RNDWITHVAL
:
2780 return Type::T_REAL
;
2781 case OPTYPE_ACTIVATE
:
2782 return Type::T_DEFAULT
;
2783 case OPTYPE_ACTIVATE_REFD
:
2784 return Type::T_DEFAULT
;
2785 case OPTYPE_EXECUTE
:
2786 case OPTYPE_EXECUTE_REFD
:
2787 return Type::T_VERDICT
;
2788 case OPTYPE_UNARYPLUS
: // v1
2789 case OPTYPE_UNARYMINUS
: {
2790 Type::typetype_t tmp_tt
;
2792 Error_Context
cntxt(this, "In the operand of operation `%s'",
2794 u
.expr
.v1
->set_lowerid_to_ref();
2795 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2802 get_value_refd_last(); // to report the error
2803 return Type::T_ERROR
;
2806 case OPTYPE_ADD
: // v1 v2
2807 case OPTYPE_SUBTRACT
:
2808 case OPTYPE_MULTIPLY
:
2809 case OPTYPE_DIVIDE
: {
2810 Type::typetype_t tmp_tt
;
2812 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2814 u
.expr
.v1
->set_lowerid_to_ref();
2815 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2822 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2823 Type::typetype_t tmp_tt2
;
2825 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2827 u
.expr
.v2
->set_lowerid_to_ref();
2828 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2830 Type::typetype_t ret_val
=Type::T_ERROR
;
2831 bool maybeconcat
=false;
2836 if(tmp_tt2
==tmp_tt
) {
2843 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2845 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2846 ret_val
=Type::T_USTR
;
2847 else ret_val
=Type::T_CSTR
;
2854 error("Did you mean the concat operation (`&') instead of"
2855 " addition operator (`+')?");
2856 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2860 get_value_refd_last(); // to report the error
2861 return Type::T_ERROR
;
2864 case OPTYPE_NOT4B
: // v1
2865 case OPTYPE_AND4B
: // v1 v2
2870 Type::typetype_t tmp_tt
;
2872 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
2873 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
2875 u
.expr
.v1
->set_lowerid_to_ref();
2876 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2884 get_value_refd_last(); // to report the error
2885 return Type::T_ERROR
;
2888 case OPTYPE_ROTL
: // v1 v2
2890 Type::typetype_t tmp_tt
;
2892 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
2893 u
.expr
.v_optype
==OPTYPE_ROTL
2894 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
2896 u
.expr
.v1
->set_lowerid_to_ref();
2897 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2910 get_value_refd_last(); // to report the error
2911 return Type::T_ERROR
;
2915 case OPTYPE_REPLACE
: {
2916 Type::typetype_t tmp_tt
;
2918 Error_Context
cntxt(this, "In the operand of operation `%s'",
2920 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2921 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2933 get_value_refd_last(); // to report the error
2934 return Type::T_ERROR
;
2937 case OPTYPE_REGEXP
: {
2938 Type::typetype_t tmp_tt
;
2940 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2942 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2943 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2950 get_value_refd_last(); // to report the error
2951 return Type::T_ERROR
;
2954 case OPTYPE_CONCAT
: { // v1 v2
2955 Type::typetype_t tmp_tt
;
2957 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2959 u
.expr
.v1
->set_lowerid_to_ref();
2960 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2972 get_value_refd_last(); // to report the error
2973 return Type::T_ERROR
;
2978 case OPTYPE_CHAR2INT
:
2979 case OPTYPE_UNICHAR2INT
:
2980 case OPTYPE_BIT2INT
:
2981 case OPTYPE_HEX2INT
:
2982 case OPTYPE_OCT2INT
:
2983 case OPTYPE_STR2INT
:
2984 case OPTYPE_FLOAT2INT
:
2985 case OPTYPE_LENGTHOF
:
2988 case OPTYPE_ENUM2INT
:
2990 case OPTYPE_BIT2STR
:
2991 case OPTYPE_FLOAT2STR
:
2992 case OPTYPE_HEX2STR
:
2993 case OPTYPE_INT2CHAR
:
2994 case OPTYPE_INT2STR
:
2995 case OPTYPE_OCT2CHAR
:
2996 case OPTYPE_OCT2STR
:
2997 case OPTYPE_UNICHAR2CHAR
:
2998 case OPTYPE_LOG2STR
:
2999 case OPTYPE_TESTCASENAME
:
3000 case OPTYPE_TTCN2STRING
:
3001 case OPTYPE_GET_STRINGENCODING
:
3002 case OPTYPE_ENCODE_BASE64
:
3003 return Type::T_CSTR
;
3004 case OPTYPE_INT2UNICHAR
:
3005 case OPTYPE_OCT2UNICHAR
:
3006 return Type::T_USTR
;
3007 case OPTYPE_INT2BIT
:
3008 case OPTYPE_HEX2BIT
:
3009 case OPTYPE_OCT2BIT
:
3010 case OPTYPE_STR2BIT
:
3012 return Type::T_BSTR
;
3013 case OPTYPE_INT2HEX
:
3014 case OPTYPE_BIT2HEX
:
3015 case OPTYPE_OCT2HEX
:
3016 case OPTYPE_STR2HEX
:
3017 return Type::T_HSTR
;
3018 case OPTYPE_INT2OCT
:
3019 case OPTYPE_CHAR2OCT
:
3020 case OPTYPE_HEX2OCT
:
3021 case OPTYPE_BIT2OCT
:
3022 case OPTYPE_STR2OCT
:
3023 case OPTYPE_UNICHAR2OCT
:
3024 case OPTYPE_REMOVE_BOM
:
3025 case OPTYPE_DECODE_BASE64
:
3026 return Type::T_OSTR
;
3030 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3032 return Type::T_ERROR
;
3036 case MACRO_MODULEID
:
3037 case MACRO_FILENAME
:
3038 case MACRO_BFILENAME
:
3039 case MACRO_FILEPATH
:
3040 case MACRO_LINENUMBER
:
3041 case MACRO_DEFINITIONID
:
3043 case MACRO_TESTCASEID
:
3044 return Type::T_CSTR
;
3045 case MACRO_LINENUMBER_C
:
3048 return Type::T_ERROR
;
3051 return Type::T_NULL
;
3053 return Type::T_BOOL
;
3057 return Type::T_REAL
;
3059 return Type::T_ENUM_T
;
3061 return Type::T_BSTR
;
3063 return Type::T_HSTR
;
3065 return Type::T_OSTR
;
3067 return Type::T_CSTR
;
3069 return Type::T_USTR
;
3071 return Type::T_GENERALSTRING
;
3075 return Type::T_ROID
;
3077 return Type::T_VERDICT
;
3078 case V_DEFAULT_NULL
:
3079 return Type::T_DEFAULT
;
3081 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3083 return Type::T_ERROR
;
3087 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3089 if(my_governor
) return my_governor
;
3090 switch (valuetype
) {
3092 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3094 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3095 u
.invoke
.v
->error("A value of type function expected");
3098 t
= t
->get_type_refd_last();
3099 switch(t
->get_typetype()) {
3100 case Type::T_FUNCTION
: {
3101 Type
*t_return_type
= t
->get_function_return_type();
3102 if (!t_return_type
) {
3103 error("Reference to a %s was expected instead of invocation "
3104 "of behavior type `%s' with no return type",
3105 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3106 t
->get_fullname().c_str());
3109 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3110 error("Reference to a value was expected, but functions of type "
3111 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3112 t_return_type
->get_typename().c_str());
3115 return t_return_type
; }
3116 case Type::T_ALTSTEP
:
3119 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3120 t
->get_typename().c_str());
3125 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3127 if (!ass
) goto error
;
3128 switch (ass
->get_asstype()) {
3129 case Assignment::A_CONST
:
3130 case Assignment::A_EXT_CONST
:
3131 case Assignment::A_MODULEPAR
:
3132 case Assignment::A_MODULEPAR_TEMP
:
3133 case Assignment::A_TEMPLATE
:
3134 case Assignment::A_VAR
:
3135 case Assignment::A_VAR_TEMPLATE
:
3136 case Assignment::A_FUNCTION_RVAL
:
3137 case Assignment::A_FUNCTION_RTEMP
:
3138 case Assignment::A_EXT_FUNCTION_RVAL
:
3139 case Assignment::A_EXT_FUNCTION_RTEMP
:
3140 case Assignment::A_PAR_VAL_IN
:
3141 case Assignment::A_PAR_VAL_OUT
:
3142 case Assignment::A_PAR_VAL_INOUT
:
3143 case Assignment::A_PAR_TEMPL_IN
:
3144 case Assignment::A_PAR_TEMPL_OUT
:
3145 case Assignment::A_PAR_TEMPL_INOUT
:
3146 tmp_type
=ass
->get_Type();
3148 case Assignment::A_FUNCTION
:
3149 case Assignment::A_EXT_FUNCTION
:
3150 error("Reference to a %s was expected instead of a call of %s, which "
3151 "does not have return type",
3152 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3153 ass
->get_description().c_str());
3156 error("Reference to a %s was expected instead of %s",
3157 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3158 ass
->get_description().c_str());
3161 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3162 if(!tmp_type
) goto error
;
3165 switch (u
.expr
.v_optype
) {
3166 case OPTYPE_VALUEOF
:
3169 case OPTYPE_REPLACE
:{
3170 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3171 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3172 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3177 return u
.expr
.v1
->get_expr_governor(exp_val
);
3179 return get_expr_governor_v1v2(exp_val
);
3180 case OPTYPE_COMP_MTC
:
3181 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3183 case OPTYPE_COMP_SYSTEM
:
3184 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3186 case OPTYPE_COMP_SELF
:
3188 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3189 if (t_ros
) return t_ros
->get_component_type();
3192 case OPTYPE_COMP_CREATE
:
3193 return chk_expr_operand_comptyperef_create();
3199 return Type::get_pooltype(get_expr_returntype(exp_val
));
3202 set_valuetype(V_ERROR
);
3206 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3208 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3209 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3211 if (v2_gov
) { // both have governors
3212 // return the type that is compatible with both (if there is no type mismatch)
3213 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3216 } else return v1_gov
;
3217 } else { // v1 has no governor
3218 if (v2_gov
) return v2_gov
;
3219 else return NULL
; // neither has governor
3223 Type
*Value::get_expr_governor_last()
3225 Value
*v_last
= get_value_refd_last();
3226 if (v_last
->valuetype
== V_ERROR
) return 0;
3227 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3229 return t
->get_type_refd_last();
3232 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3234 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3235 return u
.invoke
.v
->get_expr_governor(exp_val
);
3238 const char* Value::get_opname() const
3240 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3241 switch(u
.expr
.v_optype
) {
3242 case OPTYPE_RND
: // -
3244 case OPTYPE_COMP_NULL
:
3245 return "(component) null";
3246 case OPTYPE_COMP_MTC
:
3248 case OPTYPE_COMP_SYSTEM
:
3250 case OPTYPE_COMP_SELF
:
3252 case OPTYPE_COMP_RUNNING_ANY
:
3253 return "any component.running";
3254 case OPTYPE_COMP_RUNNING_ALL
:
3255 return "all component.running";
3256 case OPTYPE_COMP_ALIVE_ANY
:
3257 return "any component.alive";
3258 case OPTYPE_COMP_ALIVE_ALL
:
3259 return "all component.alive";
3260 case OPTYPE_TMR_RUNNING_ANY
:
3261 return "any timer.running";
3262 case OPTYPE_GETVERDICT
:
3263 return "getverdict()";
3264 case OPTYPE_TESTCASENAME
:
3265 return "testcasename()";
3266 case OPTYPE_UNARYPLUS
: // v1
3268 case OPTYPE_UNARYMINUS
:
3274 case OPTYPE_BIT2HEX
:
3276 case OPTYPE_BIT2INT
:
3278 case OPTYPE_BIT2OCT
:
3280 case OPTYPE_BIT2STR
:
3282 case OPTYPE_CHAR2INT
:
3283 return "char2int()";
3284 case OPTYPE_CHAR2OCT
:
3285 return "char2oct()";
3286 case OPTYPE_FLOAT2INT
:
3287 return "float2int()";
3288 case OPTYPE_FLOAT2STR
:
3289 return "float2str()";
3290 case OPTYPE_HEX2BIT
:
3292 case OPTYPE_HEX2INT
:
3294 case OPTYPE_HEX2OCT
:
3296 case OPTYPE_HEX2STR
:
3298 case OPTYPE_INT2CHAR
:
3299 return "int2char()";
3300 case OPTYPE_INT2FLOAT
:
3301 return "int2float()";
3302 case OPTYPE_INT2STR
:
3304 case OPTYPE_INT2UNICHAR
:
3305 return "int2unichar()";
3306 case OPTYPE_OCT2BIT
:
3308 case OPTYPE_OCT2CHAR
:
3309 return "oct2char()";
3310 case OPTYPE_OCT2HEX
:
3312 case OPTYPE_OCT2INT
:
3314 case OPTYPE_OCT2STR
:
3316 case OPTYPE_STR2BIT
:
3318 case OPTYPE_STR2FLOAT
:
3319 return "str2float()";
3320 case OPTYPE_STR2HEX
:
3322 case OPTYPE_STR2INT
:
3324 case OPTYPE_STR2OCT
:
3326 case OPTYPE_UNICHAR2INT
:
3327 return "unichar2int()";
3328 case OPTYPE_UNICHAR2CHAR
:
3329 return "unichar2char()";
3330 case OPTYPE_UNICHAR2OCT
:
3331 return "unichar2oct()";
3332 case OPTYPE_ENUM2INT
:
3333 return "enum2int()";
3334 case OPTYPE_LENGTHOF
:
3335 return "lengthof()";
3338 case OPTYPE_RNDWITHVAL
:
3339 return "rnd (seed)";
3341 return "encvalue()";
3343 return "decvalue()";
3344 case OPTYPE_GET_STRINGENCODING
:
3345 return "get_stringencoding()";
3346 case OPTYPE_REMOVE_BOM
:
3347 return "remove_bom()";
3348 case OPTYPE_ENCODE_BASE64
:
3349 return "encode_base64()";
3350 case OPTYPE_DECODE_BASE64
:
3351 return "decode_base64()";
3352 case OPTYPE_ADD
: // v1 v2
3354 case OPTYPE_SUBTRACT
:
3356 case OPTYPE_MULTIPLY
:
3398 case OPTYPE_INT2BIT
:
3400 case OPTYPE_INT2HEX
:
3402 case OPTYPE_INT2OCT
:
3404 case OPTYPE_OCT2UNICHAR
:
3405 return "oct2unichar()";
3412 case OPTYPE_REPLACE
:
3414 case OPTYPE_VALUEOF
: // t1
3416 case OPTYPE_UNDEF_RUNNING
:
3417 return "<timer or component> running";
3418 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3420 case OPTYPE_COMP_RUNNING
: // v1
3421 return "component running";
3422 case OPTYPE_COMP_ALIVE
: // v1
3424 case OPTYPE_TMR_READ
:
3425 return "timer read";
3426 case OPTYPE_TMR_RUNNING
:
3427 return "timer running";
3428 case OPTYPE_ACTIVATE
:
3429 return "activate()";
3430 case OPTYPE_ACTIVATE_REFD
:
3431 return "activate()";
3432 case OPTYPE_EXECUTE
: // r1 [v2]
3433 case OPTYPE_EXECUTE_REFD
:
3435 case OPTYPE_MATCH
: // v1 t2
3437 case OPTYPE_ISPRESENT
:
3438 return "ispresent()";
3439 case OPTYPE_ISCHOSEN
:
3440 case OPTYPE_ISCHOSEN_V
:
3441 case OPTYPE_ISCHOSEN_T
:
3442 return "ischosen()";
3443 case OPTYPE_ISVALUE
:
3445 case OPTYPE_ISBOUND
:
3447 case OPTYPE_LOG2STR
:
3449 case OPTYPE_TTCN2STRING
:
3450 return "ttcn2string()";
3452 FATAL_ERROR("Value::get_opname()");
3456 void Value::chk_expr_ref_ischosen()
3458 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3459 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3460 Assignment
*ass
=tmpref
->get_refd_assignment();
3462 set_valuetype(V_ERROR
);
3465 // Now we know whether the argument of ischosen() is a value or template.
3466 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3467 // or template (OPTYPE_ISCHOSEN_T).
3468 switch (ass
->get_asstype()) {
3469 case Assignment::A_CONST
:
3470 case Assignment::A_EXT_CONST
:
3471 case Assignment::A_MODULEPAR
:
3472 case Assignment::A_VAR
:
3473 case Assignment::A_PAR_VAL_IN
:
3474 case Assignment::A_PAR_VAL_OUT
:
3475 case Assignment::A_PAR_VAL_INOUT
:
3476 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3477 u
.expr
.v1
->set_location(*tmpref
);
3478 u
.expr
.v1
->set_my_scope(get_my_scope());
3479 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3480 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3482 case Assignment::A_MODULEPAR_TEMP
:
3483 case Assignment::A_TEMPLATE
:
3484 case Assignment::A_VAR_TEMPLATE
:
3485 case Assignment::A_PAR_TEMPL_IN
:
3486 case Assignment::A_PAR_TEMPL_OUT
:
3487 case Assignment::A_PAR_TEMPL_INOUT
:
3488 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3489 u
.expr
.t1
->set_location(*tmpref
);
3490 u
.expr
.t1
->set_my_scope(get_my_scope());
3491 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3492 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3495 tmpref
->error("Reference to a value or template was expected instead of "
3496 "%s", ass
->get_description().c_str());
3497 set_valuetype(V_ERROR
);
3502 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3503 Type::expected_value_t exp_val
)
3505 v
->set_lowerid_to_ref(); // can only be reference to enum
3506 Type
*t
= v
->get_expr_governor(exp_val
);
3507 if (v
->valuetype
==V_ERROR
) return;
3509 v
->error("Please use reference to an enumerated value as the operand of "
3510 "operation `%s'", get_opname());
3511 set_valuetype(V_ERROR
);
3514 t
= t
->get_type_refd_last();
3515 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3516 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3517 set_valuetype(V_ERROR
);
3519 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3520 v
->error("The operand of operation `%s' cannot be omit", opname
);
3521 set_valuetype(V_ERROR
);
3525 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3528 const Location
*loc
)
3530 if(tt
==Type::T_BOOL
) return;
3531 if(tt
!=Type::T_ERROR
)
3532 loc
->error("%s operand of operation `%s' should be boolean value",
3534 set_valuetype(V_ERROR
);
3537 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3540 const Location
*loc
)
3542 if(tt
==Type::T_INT
) return;
3543 if(tt
!=Type::T_ERROR
)
3544 loc
->error("%s operand of operation `%s' should be integer value",
3546 set_valuetype(V_ERROR
);
3549 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3552 const Location
*loc
)
3554 if(tt
==Type::T_REAL
) return;
3555 else if(tt
==Type::T_INT
)
3556 loc
->error("%s operand of operation `%s' should be float value."
3557 " Perhaps you missed an int2float() conversion function"
3558 " or `.0' at the end of the number",
3560 else if(tt
!=Type::T_ERROR
)
3561 loc
->error("%s operand of operation `%s' should be float value",
3563 set_valuetype(V_ERROR
);
3566 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3569 const Location
*loc
)
3578 if(tt
!=Type::T_ERROR
)
3579 loc
->error("%s operand of operation `%s' should be integer"
3582 set_valuetype(V_ERROR
);
3585 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3588 const Location
*loc
)
3593 case Type::T_ENUM_T
:
3598 if(tt
!=Type::T_ERROR
)
3599 loc
->error("%s operand of operation `%s' should be integer, float"
3600 " or enumerated value", opnum
, opname
);
3601 set_valuetype(V_ERROR
);
3604 void Value::chk_expr_operandtype_list(Type
* t
,
3607 const Location
*loc
,
3610 if (valuetype
== V_ERROR
) return;
3611 if (t
->get_typetype() == Type::T_ERROR
) {
3612 set_valuetype(V_ERROR
);
3615 if (!t
->is_list_type(allow_array
)) {
3616 loc
->error("%s operand of operation `%s' should be a string, "
3617 "`record of'%s `set of'%s value", opnum
, opname
,
3618 allow_array
? "," : " or", allow_array
? " or array" : "");
3619 set_valuetype(V_ERROR
);
3622 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3623 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3626 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3627 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3628 if (info
.is_subtype_error()) {
3630 if (info
.needs_conversion()) set_needs_conversion();
3632 if (!info
.is_erroneous()) {
3633 error("%s operand of operation `%s' is of type `%s', but a value of "
3634 "type `%s' was expected here", opnum
, opname
,
3635 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3637 error("%s", info
.get_error_str_str().c_str());
3640 if (info
.needs_conversion())
3641 set_needs_conversion();
3645 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3648 const Location
*loc
)
3660 if(tt
!=Type::T_ERROR
)
3661 loc
->error("%s operand of operation `%s' should be string value",
3663 set_valuetype(V_ERROR
);
3666 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3669 const Location
*loc
)
3678 if(tt
!=Type::T_ERROR
)
3679 loc
->error("%s operand of operation `%s' should be (universal)"
3680 " charstring value",
3682 set_valuetype(V_ERROR
);
3685 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3688 const Location
*loc
)
3690 if(tt
==Type::T_CSTR
) return;
3691 if(tt
!=Type::T_ERROR
)
3692 loc
->error("%s operand of operation `%s' should be charstring value",
3694 set_valuetype(V_ERROR
);
3697 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3700 const Location
*loc
)
3710 if(tt
!=Type::T_ERROR
)
3711 loc
->error("%s operand of operation `%s' should be binary string value",
3713 set_valuetype(V_ERROR
);
3716 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3719 const Location
*loc
)
3721 if(tt
==Type::T_BSTR
) return;
3722 if(tt
!=Type::T_ERROR
)
3723 loc
->error("%s operand of operation `%s' should be bitstring value",
3725 set_valuetype(V_ERROR
);
3728 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3731 const Location
*loc
)
3733 if(tt
==Type::T_HSTR
) return;
3734 if(tt
!=Type::T_ERROR
)
3735 loc
->error("%s operand of operation `%s' should be hexstring value",
3737 set_valuetype(V_ERROR
);
3740 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3743 const Location
*loc
)
3745 if(tt
==Type::T_OSTR
) return;
3746 if(tt
!=Type::T_ERROR
)
3747 loc
->error("%s operand of operation `%s' should be octetstring value",
3749 set_valuetype(V_ERROR
);
3752 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3753 Type::typetype_t tt2
,
3756 if(valuetype
==V_ERROR
) return;
3757 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3758 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3759 set_valuetype(V_ERROR
);
3762 if(tt1
==tt2
) return;
3763 error("The operands of operation `%s' should be of same type", opname
);
3764 set_valuetype(V_ERROR
);
3767 /* For predefined functions. */
3768 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3769 Type::typetype_t tt2
,
3774 if(valuetype
==V_ERROR
) return;
3775 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3776 set_valuetype(V_ERROR
);
3779 if(tt1
==tt2
) return;
3780 error("The %s and %s operands of operation `%s' should be of same type",
3781 opnum1
, opnum2
, opname
);
3782 set_valuetype(V_ERROR
);
3785 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3786 Value
*v1
, Value
*v2
,
3791 if (valuetype
== V_ERROR
) return;
3792 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3793 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3794 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3796 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3797 set_valuetype(V_ERROR
);
3800 if (tt1
== Type::T_UNDEF
) {
3801 if (tt2
== Type::T_UNDEF
) {
3802 if (v1
->is_undef_lowerid()) {
3803 if (v2
->is_undef_lowerid()) {
3804 Scope
*scope
= get_my_scope();
3805 Module
*my_mod
= scope
->get_scope_mod();
3806 const Identifier
& id1
= v1
->get_undef_lowerid();
3807 if (scope
->has_ass_withId(id1
)
3808 || my_mod
->has_imported_ass_withId(id1
)) {
3809 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3810 * should examine this situation better, but now I suppose
3811 * the first is ref, not enum. */
3812 v1
->set_lowerid_to_ref();
3815 const Identifier
& id2
= v2
->get_undef_lowerid();
3816 if (scope
->has_ass_withId(id2
)
3817 || my_mod
->has_imported_ass_withId(id2
)) {
3818 v2
->set_lowerid_to_ref();
3822 /* This is perhaps enum-enum, but it has no real
3823 * significance, so this should be an error. */
3825 v1
->set_lowerid_to_ref();
3828 } else if (v2
->is_undef_lowerid()) {
3829 v2
->set_lowerid_to_ref();
3832 error("Cannot determine the type of the operands in operation `%s'",
3834 set_valuetype(V_ERROR
);
3836 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3837 v1
->set_lowerid_to_ref();
3840 /* v1 is something undefined, but not lowerid; v2 has
3841 * returntype (perhaps also governor) */
3843 } else if (tt2
== Type::T_UNDEF
) {
3844 /* but tt1 is not undef */
3845 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3846 v2
->set_lowerid_to_ref();
3849 /* v2 is something undefined, but not lowerid; v1 has
3850 * returntype (perhaps also governor) */
3854 /* Now undef_lower_id's are converted to references, or the other
3855 * value has governor; let's see the governors, if they exist. */
3856 Type
*t1
= v1
->get_expr_governor(exp_val
);
3857 Type
*t2
= v2
->get_expr_governor(exp_val
);
3860 // Both value has governor. Are they compatible? According to 7.1.2
3861 // and C.34 it's required to have the same root types for
3862 // OPTYPE_{CONCAT,REPLACE}.
3863 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
3864 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3865 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
3866 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3867 TypeChain l_chain1
, l_chain2
;
3868 TypeChain r_chain1
, r_chain2
;
3869 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
3870 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
3871 if (!compat_t1
&& !compat_t2
) {
3872 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
3873 // the subtypes don't need to be compatible here
3874 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
3875 error("The operands of operation `%s' should be of compatible "
3876 "types", get_opname());
3877 set_valuetype(V_ERROR
);
3879 if (info1
.needs_conversion() || info2
.needs_conversion()) {
3880 set_needs_conversion(); // Avoid folding.
3885 if (info1
.is_erroneous())
3886 v1
->error("%s", info1
.get_error_str_str().c_str());
3887 else if (info2
.is_erroneous())
3888 v2
->error("%s", info2
.get_error_str_str().c_str());
3889 set_valuetype(V_ERROR
);
3892 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
3893 set_needs_conversion(); // Avoid folding.
3898 v2
->set_my_governor(t1
);
3899 t1
->chk_this_value_ref(v2
);
3900 if (v2
->valuetype
== V_OMIT
) {
3901 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3903 v1
->chk_expr_omit_comparison(exp_val
);
3905 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3907 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3908 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3913 v1
->set_my_governor(t2
);
3914 t2
->chk_this_value_ref(v1
);
3915 if (v1
->valuetype
== V_OMIT
) {
3916 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3918 v2
->chk_expr_omit_comparison(exp_val
);
3920 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3922 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3923 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3927 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3928 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
3929 // Here, it cannot be that both are T_UNDEF.
3930 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3931 error("Please use reference as %s operand of operator `%s'",
3932 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
3933 set_valuetype(V_ERROR
);
3936 // Deny type compatibility if no governors found. The typetype_t must
3937 // be the same. TODO: How can this happen?
3938 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
3939 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
3940 error("The operands of operation `%s' should be of compatible types",
3942 set_valuetype(V_ERROR
);
3947 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
3948 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
3950 if(valuetype
==V_ERROR
) return;
3951 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3952 Assignment
*t_ass
= ref
->get_refd_assignment();
3953 if(!t_ass
) goto error
;
3954 switch(t_ass
->get_asstype()) {
3955 case Assignment::A_TIMER
:
3956 case Assignment::A_PAR_TIMER
:
3957 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
3958 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
3959 chk_expr_dynamic_part(exp_val
, true);
3961 case Assignment::A_CONST
:
3962 case Assignment::A_EXT_CONST
:
3963 case Assignment::A_MODULEPAR
:
3964 case Assignment::A_VAR
:
3965 case Assignment::A_FUNCTION_RVAL
:
3966 case Assignment::A_EXT_FUNCTION_RVAL
:
3967 case Assignment::A_PAR_VAL_IN
:
3968 case Assignment::A_PAR_VAL_OUT
:
3969 case Assignment::A_PAR_VAL_INOUT
: {
3970 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
3971 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
3972 val
->set_my_scope(my_scope
);
3973 val
->set_fullname(u
.expr
.r1
->get_fullname());
3974 val
->set_location(*u
.expr
.r1
);
3976 chk_expr_operand_compref(val
, opnum
, get_opname());
3977 chk_expr_dynamic_part(exp_val
, false);
3980 ref
->error("%s operand of operation `%s' should be timer or"
3981 " component reference instead of %s",
3982 opnum
, opname
, t_ass
->get_description().c_str());
3987 set_valuetype(V_ERROR
);
3990 Type
*Value::chk_expr_operand_comptyperef_create()
3992 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
3993 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
3994 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
3995 if (!t_ass
) goto error
;
3996 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
3997 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
3998 Type::EXPECTED_DYNAMIC_VALUE
);
3999 if (!t_type
) goto error
;
4000 t_type
= t_type
->get_type_refd_last();
4001 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4003 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4004 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4005 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4006 u
.expr
.r1
->error("Incompatible component types: operation "
4007 "`create' should refer to `%s' instead of "
4009 my_governor_last
->get_typename().c_str(),
4010 t_type
->get_typename().c_str());
4016 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4017 "expected in operation `create' instead of `%s'",
4018 t_type
->get_typename().c_str());
4021 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4022 "instead of %s", t_ass
->get_description().c_str());
4025 set_valuetype(V_ERROR
);
4029 void Value::chk_expr_comptype_compat()
4031 if (valuetype
!= V_EXPR
)
4032 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4033 if (!my_governor
|| !my_scope
) return;
4034 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4035 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4037 switch (u
.expr
.v_optype
) {
4038 case OPTYPE_COMP_MTC
:
4039 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4041 case OPTYPE_COMP_SYSTEM
:
4042 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4044 case OPTYPE_COMP_SELF
: {
4045 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4046 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4049 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4054 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4055 error("Incompatible component types: a component reference of "
4056 "type `%s' was expected, but `%s' has type `%s'",
4057 my_governor_last
->get_typename().c_str(), get_opname(),
4058 t_comptype
->get_typename().c_str());
4059 set_valuetype(V_ERROR
);
4063 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4066 if(valuetype
== V_ERROR
) return;
4067 switch(val
->get_valuetype()) {
4069 Error_Context
cntxt(this, "In `%s' operation", opname
);
4070 Value
*v_last
= val
->get_value_refd_last();
4071 if(!v_last
) goto error
;
4072 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4074 t
= t
->get_type_refd_last();
4075 if(t
->get_typetype() != Type::T_COMPONENT
) {
4076 v_last
->error("%s operand of operation `%s': Type mismatch:"
4077 " component reference was expected instead of `%s'",
4078 opnum
, opname
, t
->get_typename().c_str());
4083 Reference
*ref
= val
->get_reference();
4084 Assignment
*t_ass
= ref
->get_refd_assignment();
4086 if (!t_ass
) goto error
;
4087 switch(t_ass
->get_asstype()) {
4088 case Assignment::A_CONST
:
4089 t_val
= t_ass
->get_Value();
4091 case Assignment::A_EXT_CONST
:
4092 case Assignment::A_MODULEPAR
:
4093 case Assignment::A_VAR
:
4094 case Assignment::A_FUNCTION_RVAL
:
4095 case Assignment::A_EXT_FUNCTION_RVAL
:
4096 case Assignment::A_PAR_VAL_IN
:
4097 case Assignment::A_PAR_VAL_OUT
:
4098 case Assignment::A_PAR_VAL_INOUT
: {
4099 Type
*t_type
=t_ass
->get_Type()
4100 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4101 if(!t_type
) goto error
;
4102 t_type
=t_type
->get_type_refd_last();
4103 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4104 ref
->error("%s operand of operation `%s': Type mismatch:"
4105 " component reference was expected instead of `%s'",
4106 opnum
, opname
, t_type
->get_typename().c_str());
4111 ref
->error("%s operand of operation `%s' should be"
4112 " component reference instead of %s",
4113 opnum
, opname
, t_ass
->get_description().c_str());
4117 ReferenceChain
refch(this, "While searching referenced value");
4118 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4120 t_val
= t_val
->get_value_refd_last();
4121 if (t_val
->valuetype
!= V_EXPR
) return;
4122 switch (t_val
->u
.expr
.v_optype
) {
4123 case OPTYPE_COMP_NULL
:
4124 ref
->error("%s operand of operation `%s' refers to `null' component "
4125 "reference", opnum
, opname
);
4127 case OPTYPE_COMP_MTC
:
4128 ref
->error("%s operand of operation `%s' refers to the component "
4129 "reference of the `mtc'", opnum
, opname
);
4131 case OPTYPE_COMP_SYSTEM
:
4132 ref
->error("%s operand of operation `%s' refers to the component "
4133 "reference of the `system'", opnum
, opname
);
4141 FATAL_ERROR("Value::chk_expr_operand_compref()");
4144 set_valuetype(V_ERROR
);
4147 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4151 if(valuetype
==V_ERROR
) return;
4152 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4153 Assignment
*t_ass
= ref
->get_refd_assignment();
4154 if(!t_ass
) goto error
;
4155 switch(t_ass
->get_asstype()) {
4156 case Assignment::A_TIMER
: {
4157 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4158 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4159 Type::EXPECTED_DYNAMIC_VALUE
);
4160 else if (ref
->get_subrefs()) {
4161 ref
->error("%s operand of operation `%s': "
4162 "Reference to single timer `%s' cannot have field or array "
4163 "sub-references", opnum
, opname
,
4164 t_ass
->get_id().get_dispname().c_str());
4168 case Assignment::A_PAR_TIMER
:
4169 if (ref
->get_subrefs()) {
4170 ref
->error("%s operand of operation `%s': "
4171 "Reference to %s cannot have field or array sub-references",
4172 opnum
, opname
, t_ass
->get_description().c_str());
4177 ref
->error("%s operand of operation `%s' should be timer"
4179 opnum
, opname
, t_ass
->get_description().c_str());
4184 set_valuetype(V_ERROR
);
4187 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4191 if(valuetype
==V_ERROR
) return;
4192 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4193 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4194 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4195 Error_Context
cntxt(this, "In `%s' operation", opname
);
4196 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4199 void Value::chk_expr_operand_activate_refd(Value
*val
,
4200 Ttcn::TemplateInstances
* t_list2
,
4201 Ttcn::ActualParList
*&parlist
,
4205 if(valuetype
==V_ERROR
) return;
4206 Error_Context
cntxt(this, "In `%s' operation", opname
);
4207 Type
*t
= val
->get_expr_governor_last();
4209 switch (t
->get_typetype()) {
4211 set_valuetype(V_ERROR
);
4213 case Type::T_ALTSTEP
: {
4214 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4215 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4219 set_valuetype(V_ERROR
);
4221 parlist
->set_fullname(get_fullname());
4222 parlist
->set_my_scope(get_my_scope());
4223 if (!fp_list
->chk_activate_argument(parlist
,
4224 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4228 error("Reference to an altstep was expected in the argument of "
4229 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4230 set_valuetype(V_ERROR
);
4233 } else set_valuetype(V_ERROR
);
4236 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4240 if(valuetype
==V_ERROR
) return;
4241 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4242 Error_Context
cntxt(this, "In `%s' operation", opname
);
4243 Assignment
*t_ass
= ref
->get_refd_assignment();
4244 bool error_flag
= false;
4246 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4247 ref
->error("Reference to a testcase was expected in the argument "
4248 "instead of %s", t_ass
->get_description().c_str());
4251 } else error_flag
= true;
4253 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4254 Value
*v_last
= val
->get_value_refd_last();
4255 switch (v_last
->valuetype
) {
4257 ttcn3float v_real
= v_last
->get_val_Real();
4259 val
->error("The testcase guard timer has negative value: `%s'",
4260 Real2string(v_real
).c_str());
4271 if (error_flag
) set_valuetype(V_ERROR
);
4274 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4275 Ttcn::TemplateInstances
* t_list2
,
4276 Ttcn::ActualParList
*&parlist
,
4281 if(valuetype
==V_ERROR
) return;
4282 Error_Context
cntxt(this, "In `%s' operation", opname
);
4283 Type
*t
= v1
->get_expr_governor_last();
4285 switch (t
->get_typetype()) {
4287 set_valuetype(V_ERROR
);
4289 case Type::T_TESTCASE
: {
4290 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4291 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4295 set_valuetype(V_ERROR
);
4297 parlist
->set_fullname(get_fullname());
4298 parlist
->set_my_scope(get_my_scope());
4302 v1
->error("Reference to a value of type testcase was expected in the "
4303 "argument of `derefers()' instead of `%s'",
4304 t
->get_typename().c_str());
4305 set_valuetype(V_ERROR
);
4308 } else set_valuetype(V_ERROR
);
4310 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4311 Value
*v_last
= v3
->get_value_refd_last();
4312 switch (v_last
->valuetype
) {
4314 ttcn3float v_real
= v_last
->get_val_Real();
4316 v3
->error("The testcase guard timer has negative value: `%s'",
4317 Real2string(v_real
).c_str());
4318 set_valuetype(V_ERROR
);
4322 set_valuetype(V_ERROR
);
4330 void Value::chk_invoke(Type::expected_value_t exp_val
)
4332 if(valuetype
== V_ERROR
) return;
4333 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4334 if(!u
.invoke
.t_list
) return; //already checked
4335 Error_Context
cntxt(this, "In `apply()' operation");
4336 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4338 set_valuetype(V_ERROR
);
4341 switch (t
->get_typetype()) {
4343 set_valuetype(V_ERROR
);
4345 case Type::T_FUNCTION
:
4348 u
.invoke
.v
->error("A value of type function was expected in the "
4349 "argument instead of `%s'", t
->get_typename().c_str());
4350 set_valuetype(V_ERROR
);
4353 my_scope
->chk_runs_on_clause(t
, *this, "call");
4354 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4355 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4356 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4357 delete u
.invoke
.t_list
;
4358 u
.invoke
.t_list
= 0;
4361 u
.invoke
.ap_list
= 0;
4363 parlist
->set_fullname(get_fullname());
4364 parlist
->set_my_scope(get_my_scope());
4365 u
.invoke
.ap_list
= parlist
;
4368 case Type::EXPECTED_CONSTANT
:
4369 error("An evaluatable constant value was expected instead of operation "
4371 set_valuetype(V_ERROR
);
4373 case Type::EXPECTED_STATIC_VALUE
:
4374 error("A static value was expected instead of operation `apply()'");
4375 set_valuetype(V_ERROR
);
4382 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4383 ReferenceChain
*refch
,
4384 Type::expected_value_t exp_val
)
4386 bool self_ref
= false;
4387 if(valuetype
==V_ERROR
) return;
4388 // Commented out to report more errors :)
4389 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4390 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4391 switch(val
->get_valuetype()) {
4393 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4398 val
->get_value_refd_last(refch
, exp_val
);
4403 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4408 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4409 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4411 bool self_ref
= false;
4413 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4414 ti
->error("Reference to a %s value was expected instead of an in-line "
4415 "modified template",
4416 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4417 set_valuetype(V_ERROR
);
4420 Template
*templ
= ti
->get_Template();
4421 switch (templ
->get_templatetype()) {
4422 case Template::TEMPLATE_REFD
:
4424 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4425 templ
= templ
->get_template_refd_last(refch
);
4426 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4427 set_valuetype(V_ERROR
);
4429 ti
->error("Reference to a %s value was expected instead of %s",
4430 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4431 templ
->get_reference()->get_refd_assignment()
4432 ->get_description().c_str());
4433 set_valuetype(V_ERROR
);
4436 case Template::SPECIFIC_VALUE
: {
4437 Value
*val
= templ
->get_specific_value();
4438 switch (val
->get_valuetype()) {
4440 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4443 val
->get_value_refd_last(refch
, exp_val
);
4447 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4449 case Template::TEMPLATE_ERROR
:
4450 set_valuetype(V_ERROR
);
4459 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4462 if(valuetype
==V_ERROR
) return;
4463 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4464 if(val
->is_unfoldable()) return;
4465 if(*val
->get_val_Int()<0) {
4466 val
->error("%s operand of operation `%s' should not be negative",
4468 set_valuetype(V_ERROR
);
4472 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4475 if(valuetype
==V_ERROR
) return;
4476 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4477 if(val
->is_unfoldable()) return;
4478 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4479 val
->error("%s operand of operation `%s' should be in range 0..127",
4481 set_valuetype(V_ERROR
);
4485 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4488 if(valuetype
==V_ERROR
) return;
4489 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4490 if(val
->is_unfoldable()) return;
4491 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4492 val
->error("%s operand of operation `%s' should be in range"
4493 " 0..2147483647", opnum
, opname
);
4494 set_valuetype(V_ERROR
);
4498 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4501 if(valuetype
==V_ERROR
) return;
4502 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4503 if(val
->is_unfoldable()) return;
4504 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4506 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4508 val
->error("%s operand of operation `%s' should not be zero",
4510 set_valuetype(V_ERROR
);
4514 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4517 if (valuetype
== V_ERROR
) return;
4518 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4519 if (val
->get_expr_returntype() != Type::T_INT
) return;
4520 if (val
->is_unfoldable()) return;
4521 const int_val_t
*val_int
= val
->get_val_Int();
4522 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4523 val
->error("%s operand of operation `%s' should be less than `%d' "
4524 "instead of `%s'", opnum
, opname
, INT_MAX
,
4525 (val_int
->t_str()).c_str());
4526 set_valuetype(V_ERROR
);
4530 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4533 if(valuetype
==V_ERROR
) return;
4534 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4535 if(val
->is_unfoldable()) return;
4536 if(val
->get_val_strlen()!=1) {
4537 val
->error("%s operand of operation `%s' should be of length 1",
4539 set_valuetype(V_ERROR
);
4543 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4546 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4547 Value
*v_last
= val
->get_value_refd_last();
4548 if (v_last
->valuetype
== V_CSTR
) {
4549 size_t len
= v_last
->get_val_strlen();
4551 val
->error("%s operand of operation `%s' should contain even number "
4552 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4553 set_valuetype(V_ERROR
);
4555 } else if (v_last
->valuetype
== V_REFD
) {
4556 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4557 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4558 val
->error("%s operand of operation `%s' should contain even number "
4559 "of characters, but a string element contains 1", opnum
, opname
);
4560 set_valuetype(V_ERROR
);
4565 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4568 if(valuetype
==V_ERROR
) return;
4569 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4570 if(val
->is_unfoldable()) return;
4571 const string
& s
=val
->get_val_str();
4572 for(size_t i
=0; i
<s
.size(); i
++) {
4574 if(!(c
=='0' || c
=='1')) {
4575 val
->error("%s operand of operation `%s' can contain only"
4576 " binary digits (position %lu is `%c')",
4577 opnum
, opname
, (unsigned long) i
, c
);
4578 set_valuetype(V_ERROR
);
4584 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4587 if(valuetype
==V_ERROR
) return;
4588 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4589 if(val
->is_unfoldable()) return;
4590 const string
& s
=val
->get_val_str();
4591 for(size_t i
=0; i
<s
.size(); i
++) {
4593 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4594 val
->error("%s operand of operation `%s' can contain only valid "
4595 "hexadecimal digits (position %lu is `%c')",
4596 opnum
, opname
, (unsigned long) i
, c
);
4597 set_valuetype(V_ERROR
);
4603 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4606 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4607 Value
*v
= val
->get_value_refd_last();
4608 if (v
->valuetype
!= V_OSTR
) return;
4609 const string
& s
= val
->get_val_str();
4610 size_t n_octets
= s
.size() / 2;
4611 for (size_t i
= 0; i
< n_octets
; i
++) {
4613 if (!(c
>= '0' && c
<= '7')) {
4614 val
->error("%s operand of operation `%s' shall consist of octets "
4615 "within the range 00 .. 7F, but the string `%s'O contains octet "
4616 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4618 set_valuetype(V_ERROR
);
4624 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4627 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4628 Value
*v_last
= val
->get_value_refd_last();
4629 if (v_last
->valuetype
!= V_CSTR
) return;
4630 const string
& s
= v_last
->get_val_str();
4631 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4633 // state: expected characters
4634 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4635 // S_FIRST: first digit
4636 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4637 // S_END: trailing whitespace
4638 // S_ERR: error was found, stop
4639 for (size_t i
= 0; i
< s
.size(); i
++) {
4644 if (c
== '+' || c
== '-') state
= S_FIRST
;
4645 else if (c
== '0') state
= S_ZERO
;
4646 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4647 else if (string::is_whitespace(c
)) {
4648 if (state
== S_INITIAL
) {
4649 val
->warning("Leading whitespace was detected and ignored in the "
4650 "operand of operation `%s'", opname
);
4651 state
= S_INITIAL_WS
;
4653 } else state
= S_ERR
;
4656 if (c
== '0') state
= S_ZERO
;
4657 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4661 if (c
>= '0' && c
<= '9') {
4662 val
->warning("Leading zero digit was detected and ignored in the "
4663 "operand of operation `%s'", opname
);
4665 } else if (string::is_whitespace(c
)) state
= S_END
;
4669 if (c
>= '0' && c
<= '9') {}
4670 else if (string::is_whitespace(c
)) state
= S_END
;
4674 if (!string::is_whitespace(c
)) state
= S_ERR
;
4679 if (state
== S_ERR
) {
4680 if (string::is_printable(c
)) {
4681 val
->error("%s operand of operation `%s' should be a string "
4682 "containing a valid integer value, but invalid character `%c' "
4683 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4685 val
->error("%s operand of operation `%s' should be a string "
4686 "containing a valid integer value, but invalid character with "
4687 "character code %u was detected at index %lu", opnum
, opname
, c
,
4690 set_valuetype(V_ERROR
);
4697 val
->error("%s operand of operation `%s' should be a string containing a "
4698 "valid integer value instead of an empty string", opnum
, opname
);
4699 set_valuetype(V_ERROR
);
4702 val
->error("%s operand of operation `%s' should be a string containing a "
4703 "valid integer value, but only a sign character was detected", opnum
,
4705 set_valuetype(V_ERROR
);
4708 val
->warning("Trailing whitespace was detected and ignored in the "
4709 "operand of operation `%s'", opname
);
4716 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4719 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4720 Value
*v_last
= val
->get_value_refd_last();
4721 if (v_last
->valuetype
== V_REFD
) {
4722 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4723 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4724 val
->error("%s operand of operation `%s' should be a string containing "
4725 "a valid float value instead of a string element, which cannot "
4726 "represent a floating point number", opnum
, opname
);
4727 set_valuetype(V_ERROR
);
4730 } else if (v_last
->valuetype
!= V_CSTR
) return;
4731 const string
& s
= v_last
->get_val_str();
4732 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4733 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4735 // state: expected characters
4736 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4737 // leading whitespace
4738 // S_FIRST_M: first digit of integer part in mantissa
4739 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4740 // S_FIRST_F: first digit of fraction
4741 // S_MORE_F: more digits of fraction, E, trailing whitespace
4742 // S_INITIAL_E: +, -, first digit of exponent
4743 // S_FIRST_E: first digit of exponent
4744 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4745 // S_END: trailing whitespace
4746 // S_ERR: error was found, stop
4747 for (size_t i
= 0; i
< s
.size(); i
++) {
4752 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4753 else if (c
== '0') state
= S_ZERO_M
;
4754 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4755 else if (string::is_whitespace(c
)) {
4756 if (state
== S_INITIAL
) {
4757 val
->warning("Leading whitespace was detected and ignored in the "
4758 "operand of operation `%s'", opname
);
4759 state
= S_INITIAL_WS
;
4761 } else state
= S_ERR
;
4764 if (c
== '0') state
= S_ZERO_M
;
4765 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4769 if (c
== '.') state
= S_FIRST_F
;
4770 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4771 else if (c
>= '0' && c
<= '9') {
4772 val
->warning("Leading zero digit was detected and ignored in the "
4773 "mantissa of the operand of operation `%s'", opname
);
4775 } else state
= S_ERR
;
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') {}
4784 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4788 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4789 else if (c
>= '0' && c
<= '9') {}
4790 else if (string::is_whitespace(c
)) state
= S_END
;
4794 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4795 else if (c
== '0') state
= S_ZERO_E
;
4796 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4800 if (c
== '0') state
= S_ZERO_E
;
4801 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4805 if (c
>= '0' && c
<= '9') {
4806 val
->warning("Leading zero digit was detected and ignored in the "
4807 "exponent of the operand of operation `%s'", opname
);
4809 } else if (string::is_whitespace(c
)) state
= S_END
;
4813 if (c
>= '0' && c
<= '9') {}
4814 else if (string::is_whitespace(c
)) state
= S_END
;
4818 if (!string::is_whitespace(c
)) state
= S_ERR
;
4823 if (state
== S_ERR
) {
4824 if (string::is_printable(c
)) {
4825 val
->error("%s operand of operation `%s' should be a string "
4826 "containing a valid float value, but invalid character `%c' "
4827 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4829 val
->error("%s operand of operation `%s' should be a string "
4830 "containing a valid float value, but invalid character with "
4831 "character code %u was detected at index %lu", opnum
, opname
, c
,
4834 set_valuetype(V_ERROR
);
4841 val
->error("%s operand of operation `%s' should be a string containing a "
4842 "valid float value instead of an empty string", opnum
, opname
);
4843 set_valuetype(V_ERROR
);
4846 val
->error("%s operand of operation `%s' should be a string containing a "
4847 "valid float value, but only a sign character was detected", opnum
,
4849 set_valuetype(V_ERROR
);
4853 // HL67862: Missing decimal dot allowed for str2float
4856 // HL67862: Missing fraction part is allowed for str2float
4860 val
->error("%s operand of operation `%s' should be a string containing a "
4861 "valid float value, but the exponent is missing after the `E' sign",
4863 set_valuetype(V_ERROR
);
4866 val
->warning("Trailing whitespace was detected and ignored in the "
4867 "operand of operation `%s'", opname
);
4874 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
4877 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4878 Value
*v
= val
->get_value_refd_last();
4879 if (v
->valuetype
!= V_USTR
) return;
4880 const ustring
& us
= v
->get_val_ustr();
4881 for (size_t i
= 0; i
< us
.size(); i
++) {
4882 const ustring::universal_char
& uchar
= us
[i
];
4883 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
4885 val
->error("%s operand of operation `%s' shall consist of characters "
4886 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4887 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4888 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
4889 uchar
.row
, uchar
.cell
, (unsigned long) i
);
4890 set_valuetype(V_ERROR
);
4896 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
4899 if(valuetype
==V_ERROR
) return;
4900 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4901 if(val
->is_unfoldable()) return;
4902 const string
& bstr
=val
->get_val_str();
4903 // see also PredefFunc.cc::bit2int()
4904 size_t nof_bits
= bstr
.size();
4905 // skip the leading zeros
4906 size_t start_index
= 0;
4907 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
4908 // check whether the remaining bits fit in Int
4909 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
4910 val
->error("%s operand of operation `%s' is too large (maximum number"
4911 " of bits in integer is %lu)",
4912 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4913 set_valuetype(V_ERROR
);
4917 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
4920 if(valuetype
==V_ERROR
) return;
4921 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4922 if(val
->is_unfoldable()) return;
4923 const string
& hstr
=val
->get_val_str();
4924 // see also PredefFunc.cc::hex2int()
4925 size_t nof_digits
= hstr
.size();
4926 // skip the leading zeros
4927 size_t start_index
= 0;
4928 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
4929 // check whether the remaining hex digits fit in Int
4930 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
4931 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
4932 char_to_hexdigit(hstr
[start_index
]) > 7)) {
4933 val
->error("%s operand of operation `%s' is too large (maximum number"
4934 " of bits in integer is %lu)",
4935 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4936 set_valuetype(V_ERROR
);
4940 void Value::chk_expr_operands_int2binstr()
4942 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4943 if (u
.expr
.v1
->is_unfoldable()) return;
4944 if (u
.expr
.v2
->is_unfoldable()) return;
4945 // It is already checked that i1 and i2 are non-negative.
4946 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4947 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
4948 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
4949 if (!i2
->is_native()) {
4950 u
.expr
.v2
->error("The length of the resulting string is too large for "
4951 "being represented in memory");
4952 set_valuetype(V_ERROR
);
4955 Int nof_bits
= i2
->get_val();
4956 if (u
.expr
.v1
->is_unfoldable()) return;
4957 switch (u
.expr
.v_optype
) {
4958 case OPTYPE_INT2BIT
:
4960 case OPTYPE_INT2HEX
:
4963 case OPTYPE_INT2OCT
:
4967 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4969 if (*i1
>> nof_bits
> 0) { // Expensive?
4970 u
.expr
.v1
->error("Value %s does not fit in length %s",
4971 i1
->t_str().c_str(), i2
->t_str().c_str());
4972 set_valuetype(V_ERROR
);
4976 void Value::chk_expr_operands_str_samelen()
4978 if(valuetype
==V_ERROR
) return;
4979 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4980 Value
*v1
=u
.expr
.v1
;
4981 if(v1
->is_unfoldable()) return;
4982 Value
*v2
=u
.expr
.v2
;
4983 if(v2
->is_unfoldable()) return;
4984 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4985 size_t i1
=v1
->get_val_strlen();
4986 size_t i2
=v2
->get_val_strlen();
4988 error("The operands should have the same length");
4989 set_valuetype(V_ERROR
);
4993 void Value::chk_expr_operands_replace()
4995 // The fourth operand doesn't need to be checked at all here.
4996 if(valuetype
==V_ERROR
) return;
4997 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4998 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5001 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5002 size_t list_len
= 0;
5003 bool list_len_known
= false;
5004 if (v1
->valuetype
== V_REFD
) {
5005 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5006 if (subrefs
&& subrefs
->refers_to_string_element()) {
5007 warning("Replacing a string element does not make any sense");
5009 list_len_known
= true;
5012 if (!v1
->is_unfoldable()) {
5013 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5014 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5015 list_len_known
= true;
5017 if (!list_len_known
) return;
5018 if (u
.expr
.v2
->is_unfoldable()) {
5019 if (!u
.expr
.v3
->is_unfoldable()) {
5020 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5021 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5022 error("Third operand `len' (%s) is greater than the length of "
5023 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5024 (unsigned long)list_len
);
5025 set_valuetype(V_ERROR
);
5029 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5030 if (u
.expr
.v3
->is_unfoldable()) {
5031 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5032 error("Second operand `index' (%s) is greater than the length of "
5033 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5034 (unsigned long)list_len
);
5035 set_valuetype(V_ERROR
);
5038 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5039 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5040 error("The sum of second operand `index' (%s) and third operand "
5041 "`len' (%s) is greater than the length of the first operand (%lu)",
5042 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5043 (unsigned long)list_len
);
5044 set_valuetype(V_ERROR
);
5050 void Value::chk_expr_operands_substr()
5052 if(valuetype
==V_ERROR
) return;
5053 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5054 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5057 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5058 size_t list_len
= 0;
5059 bool list_len_known
= false;
5060 if (v1
->valuetype
== V_REFD
) {
5061 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5062 if (subrefs
&& subrefs
->refers_to_string_element()) {
5063 warning("Taking the substring of a string element does not make any "
5066 list_len_known
= true;
5069 if (!list_len_known
&& !v1
->is_unfoldable()) {
5070 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5071 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5072 list_len_known
= true;
5074 // Do nothing if the length of the first operand is unknown.
5075 if (!list_len_known
) return;
5076 if (u
.expr
.v2
->is_unfoldable()) {
5077 if (!u
.expr
.v3
->is_unfoldable()) {
5078 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5079 // Only the third operand is known.
5080 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5081 error("Third operand `returncount' (%s) is greater than the "
5082 "length of the first operand (%lu)",
5083 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5084 set_valuetype(V_ERROR
);
5088 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5089 if (u
.expr
.v3
->is_unfoldable()) {
5090 // Only the second operand is known.
5091 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5092 error("Second operand `index' (%s) is greater than the length "
5093 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5094 (unsigned long)list_len
);
5095 set_valuetype(V_ERROR
);
5098 // Both second and third operands are known.
5099 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5100 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5101 error("The sum of second operand `index' (%s) and third operand "
5102 "`returncount' (%s) is greater than the length of the first operand "
5103 "(%lu)", (index_int_2
->t_str()).c_str(),
5104 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5105 set_valuetype(V_ERROR
);
5111 void Value::chk_expr_operands_regexp()
5113 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5114 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5115 Value
* v2
= u
.expr
.t2
->get_specific_value();
5116 if (!v1
|| !v2
) return;
5118 Error_Context
cntxt(this, "In operation `regexp()'");
5119 Value
* v1_last
= v1
->get_value_refd_last();
5120 if (v1_last
->valuetype
== V_CSTR
) {
5121 // the input string is available at compile time
5122 const string
& instr
= v1_last
->get_val_str();
5123 const char *input_str
= instr
.c_str();
5124 size_t instr_len
= strlen(input_str
);
5125 if (instr_len
< instr
.size()) {
5126 v1
->warning("The first operand of `regexp()' contains a "
5127 "character with character code zero at index %s. The rest of the "
5128 "string will be ignored during matching",
5129 Int2string(instr_len
).c_str());
5133 size_t nof_groups
= 0;
5134 Value
*v2_last
= v2
->get_value_refd_last();
5136 if (v2_last
->valuetype
== V_CSTR
) {
5137 // the pattern is available at compile time
5138 const string
& expression
= v2_last
->get_val_str();
5139 const char *pattern_str
= expression
.c_str();
5140 size_t pattern_len
= strlen(pattern_str
);
5141 if (pattern_len
< expression
.size()) {
5142 v2
->warning("The second operand of `regexp()' contains a "
5143 "character with character code zero at index %s. The rest of the "
5144 "string will be ignored during matching",
5145 Int2string(pattern_len
).c_str());
5149 Error_Context
cntxt2(v2
, "In character string pattern");
5150 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5152 if (posix_str
!= NULL
) {
5153 regex_t posix_regexp
;
5154 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5157 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5158 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5159 "regcomp() failed: %s", msg
);
5161 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5163 v2
->error("The character pattern in the second operand of "
5164 "`regexp()' does not contain any groups");
5165 set_valuetype(V_ERROR
);
5167 regfree(&posix_regexp
);
5170 // the pattern is faulty
5171 // the error has been reported by TTCN_pattern_to_regexp
5172 set_valuetype(V_ERROR
);
5175 if (nof_groups
> 0) {
5176 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5177 if (v3
->valuetype
== V_INT
) {
5178 // the group number is available at compile time
5179 const int_val_t
*groupno_int
= v3
->get_val_Int();
5180 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5181 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5182 "large: The requested group index is %s, but the pattern "
5183 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5184 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5185 set_valuetype(V_ERROR
);
5191 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5192 Type::expected_value_t exp_val
)
5194 const char *opname
= get_opname();
5195 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5197 const Location
*loc
;
5198 bool error_flag
= false;
5199 switch (u
.expr
.v_optype
) {
5200 case OPTYPE_ISCHOSEN_V
:
5201 // u.expr.v1 is always a referenced value
5202 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5204 u
.expr
.v1
->set_my_governor(t_governor
);
5205 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5206 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5207 } else error_flag
= true;
5210 case OPTYPE_ISCHOSEN_T
:
5211 // u.expr.t1 is always a referenced template
5212 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5213 exp_val
= Type::EXPECTED_TEMPLATE
;
5214 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5216 u
.expr
.t1
->set_my_governor(t_governor
);
5218 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5220 u
.expr
.t1
->get_template_refd_last(refch
);
5221 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5223 } else error_flag
= true;
5224 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5225 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5226 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5227 u
.expr
.t1
->get_reference()->get_refd_assignment()
5228 ->get_description().c_str());
5234 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5239 t_governor
= t_governor
->get_type_refd_last();
5240 switch (t_governor
->get_typetype()) {
5244 case Type::T_CHOICE_A
:
5245 case Type::T_CHOICE_T
:
5246 case Type::T_ANYTYPE
:
5247 case Type::T_OPENTYPE
:
5248 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5249 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5250 "%s does not have a field named `%s'" :
5251 "Union type `%s' does not have a field named `%s'",
5252 t_governor
->get_typename().c_str(),
5253 u
.expr
.i2
->get_dispname().c_str());
5258 loc
->error("The operand of operation `%s' should be a union value "
5259 "or template instead of `%s'", opname
,
5260 t_governor
->get_typename().c_str());
5265 if (error_flag
) set_valuetype(V_ERROR
);
5268 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5269 Type::expected_value_t exp_val
) {
5271 Error_Context
cntxt(this, "In the parameter of encvalue()");
5272 Type
t_chk(Type::T_ERROR
);
5275 Type::expected_value_t ti_exp_val
= exp_val
;
5276 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5277 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5279 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5281 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5282 if (valuetype
!=V_ERROR
)
5283 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5284 t_type
= t_type
->get_type_refd_last();
5286 error("Cannot determine type of value");
5291 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5292 error("Expecting a value of a type with coding attributes in first"
5293 "parameter of encvalue() which belongs to a generic type '%s'",
5294 t_type->get_typename().c_str());
5298 if(!disable_attribute_validation()) {
5299 t_type
->chk_coding(true);
5302 switch (t_type
->get_typetype()) {
5307 case Type::T_REFDSPEC
:
5308 case Type::T_SELTYPE
:
5309 case Type::T_VERDICT
:
5311 case Type::T_COMPONENT
:
5312 case Type::T_DEFAULT
:
5313 case Type::T_SIGNATURE
:
5314 case Type::T_FUNCTION
:
5315 case Type::T_ALTSTEP
:
5316 case Type::T_TESTCASE
:
5317 error("Type of parameter of encvalue() cannot be '%s'",
5318 t_type
->get_typename().c_str());
5325 set_valuetype(V_ERROR
);
5328 void Value::chk_expr_operands_decode()
5330 Error_Context
cntxt(this, "In the parameters of decvalue()");
5331 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5332 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5334 Assignment
* t_ass
= ref
->get_refd_assignment();
5337 error("Could not determine the assignment for first parameter");
5340 switch (t_ass
->get_asstype()) {
5341 case Assignment::A_PAR_VAL_IN
:
5342 t_ass
->use_as_lvalue(*this);
5344 case Assignment::A_CONST
:
5345 case Assignment::A_EXT_CONST
:
5346 case Assignment::A_MODULEPAR
:
5347 case Assignment::A_MODULEPAR_TEMP
:
5348 case Assignment::A_TEMPLATE
:
5349 ref
->error("Reference to '%s' cannot be used as the first operand of "
5350 "the 'decvalue' operation", t_ass
->get_assname());
5353 case Assignment::A_VAR
:
5354 case Assignment::A_PAR_VAL_OUT
:
5355 case Assignment::A_PAR_VAL_INOUT
:
5357 case Assignment::A_VAR_TEMPLATE
:
5358 case Assignment::A_PAR_TEMPL_IN
:
5359 case Assignment::A_PAR_TEMPL_OUT
:
5360 case Assignment::A_PAR_TEMPL_INOUT
: {
5361 Template
* t
= new Template(ref
->clone());
5362 t
->set_location(*ref
);
5363 t
->set_my_scope(get_my_scope());
5364 t
->set_fullname(get_fullname()+".<operand>");
5365 Template
* t_last
= t
->get_template_refd_last();
5366 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5368 ref
->error("Specific value template was expected instead of '%s'.",
5369 t
->get_template_refd_last()->get_templatetype_str());
5376 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5379 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5380 Type::EXPECTED_DYNAMIC_VALUE
);
5384 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5385 error("First parameter has to be a bitstring");
5390 t_subrefs
= ref
->get_subrefs();
5391 t_ass
= ref
->get_refd_assignment();
5394 error("Could not determine the assignment for second parameter");
5397 // Extra check for HM59355.
5398 switch (t_ass
->get_asstype()) {
5399 case Assignment::A_VAR
:
5400 case Assignment::A_PAR_VAL_IN
:
5401 case Assignment::A_PAR_VAL_OUT
:
5402 case Assignment::A_PAR_VAL_INOUT
:
5405 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5408 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5409 Type::EXPECTED_DYNAMIC_VALUE
);
5413 t_type
= t_type
->get_type_refd_last();
5414 switch (t_type
->get_typetype()) {
5419 case Type::T_REFDSPEC
:
5420 case Type::T_SELTYPE
:
5421 case Type::T_VERDICT
:
5423 case Type::T_COMPONENT
:
5424 case Type::T_DEFAULT
:
5425 case Type::T_SIGNATURE
:
5426 case Type::T_FUNCTION
:
5427 case Type::T_ALTSTEP
:
5428 case Type::T_TESTCASE
:
5429 error("Type of second parameter cannot be %s",
5430 t_type
->get_typename().c_str());
5436 if(!disable_attribute_validation()) {
5437 t_type
->chk_coding(false);
5442 set_valuetype(V_ERROR
);
5445 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5447 Ttcn::FieldOrArrayRefs
*subrefs
;
5448 Identifier
*field_id
= 0;
5451 if (valuetype
== V_ERROR
) return;
5452 else if (valuetype
!= V_REFD
) {
5453 error("Only a referenced value can be compared with `omit'");
5456 subrefs
= u
.ref
.ref
->get_subrefs();
5457 if (subrefs
) field_id
= subrefs
->remove_last_field();
5459 error("Only a reference pointing to an optional record or set field "
5460 "can be compared with `omit'");
5463 t_ass
= u
.ref
.ref
->get_refd_assignment();
5464 if (!t_ass
) goto error
;
5465 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5466 if (!t_type
) goto error
;
5467 t_type
= t_type
->get_type_refd_last();
5468 switch (t_type
->get_typetype()) {
5477 error("Only a reference pointing to an optional field of a record"
5478 " or set type can be compared with `omit'");
5481 if (!t_type
->has_comp_withName(*field_id
)) {
5482 error("Type `%s' does not have field named `%s'",
5483 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5485 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5486 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5487 "`omit'", field_id
->get_dispname().c_str(),
5488 t_type
->get_typename().c_str());
5491 // putting the last field_id back to subrefs
5492 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5495 set_valuetype(V_ERROR
);
5499 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5500 Type::expected_value_t exp_val
)
5502 if(valuetype
==V_ERROR
) return -1;
5503 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5504 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5505 exp_val
=Type::EXPECTED_TEMPLATE
;
5507 Error_Context
cntxt(this, "In the operand of"
5508 " operation `%s'", get_opname());
5511 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5514 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5517 t_templ
= t_templ
->get_template_refd_last(refch
);
5519 // Timer and port arrays are handled separately
5520 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5521 Value
* val
= t_templ
->get_specific_value();
5522 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5523 val
->set_lowerid_to_ref();
5525 if (val
&& val
->get_valuetype() == V_REFD
) {
5526 Reference
* ref
= val
->get_reference();
5527 Assignment
* t_ass
= ref
->get_refd_assignment();
5528 Common::Assignment::asstype_t asstype
=
5529 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5530 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5531 if (t_ass
->get_Dimensions()) {
5532 // here we have a timer or port array
5533 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5534 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5535 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5536 Type::EXPECTED_DYNAMIC_VALUE
);
5539 refd_dim
= t_subrefs
->get_nof_refs();
5540 size_t nof_dims
= t_dims
->get_nof_dims();
5541 if (refd_dim
>= nof_dims
) {
5542 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5543 t_ass
->get_assname());
5544 set_valuetype(V_ERROR
);
5547 } else refd_dim
= 0;
5548 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5550 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5551 t_ass
->get_description().c_str());
5552 set_valuetype(V_ERROR
);
5561 Assignment
* t_ass
= 0;
5563 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5564 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5566 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5567 t_type
= t_type
->get_type_refd_last();
5569 error("Cannot determine type of value");
5573 if(valuetype
==V_ERROR
) return -1;
5575 t_templ
= t_templ
->get_template_refd_last(refch
);
5576 switch(t_templ
->get_templatetype()) {
5577 case Template::TEMPLATE_ERROR
:
5579 case Template::INDEXED_TEMPLATE_LIST
:
5581 case Template::TEMPLATE_REFD
:
5582 case Template::TEMPLATE_LIST
:
5583 case Template::NAMED_TEMPLATE_LIST
:
5586 case Template::SPECIFIC_VALUE
:
5588 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5590 switch(t_val
->get_valuetype()) {
5600 ref
= t_val
->get_reference();
5601 t_ass
= ref
->get_refd_assignment();
5602 t_subrefs
= ref
->get_subrefs();
5606 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5607 t_val
->create_stringRepr().c_str());
5614 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5615 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5620 switch(t_ass
->get_asstype()) {
5621 case Assignment::A_ERROR
:
5623 case Assignment::A_CONST
:
5624 t_val
= t_ass
->get_Value();
5626 case Assignment::A_EXT_CONST
:
5627 case Assignment::A_MODULEPAR
:
5628 case Assignment::A_MODULEPAR_TEMP
:
5629 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5630 u
.expr
.ti1
->error("Reference to an (evaluatable) constant value was "
5631 "expected instead of %s", t_ass
->get_description().c_str());
5635 case Assignment::A_VAR
:
5636 case Assignment::A_PAR_VAL_IN
:
5637 case Assignment::A_PAR_VAL_OUT
:
5638 case Assignment::A_PAR_VAL_INOUT
:
5640 case Type::EXPECTED_CONSTANT
:
5641 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5642 t_ass
->get_description().c_str());
5645 case Type::EXPECTED_STATIC_VALUE
:
5646 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5647 t_ass
->get_description().c_str());
5654 case Assignment::A_TEMPLATE
:
5655 t_templ
= t_ass
->get_Template();
5657 case Assignment::A_VAR_TEMPLATE
:
5658 case Assignment::A_PAR_TEMPL_IN
:
5659 case Assignment::A_PAR_TEMPL_OUT
:
5660 case Assignment::A_PAR_TEMPL_INOUT
:
5661 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5662 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5663 t_ass
->get_description().c_str());
5666 case Assignment::A_FUNCTION_RVAL
:
5667 case Assignment::A_EXT_FUNCTION_RVAL
:
5669 case Type::EXPECTED_CONSTANT
:
5670 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5671 "the return value of %s", t_ass
->get_description().c_str());
5674 case Type::EXPECTED_STATIC_VALUE
:
5675 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5676 "the return value of %s", t_ass
->get_description().c_str());
5683 case Assignment::A_FUNCTION_RTEMP
:
5684 case Assignment::A_EXT_FUNCTION_RTEMP
:
5685 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5686 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5687 " of %s, which returns a template",
5688 t_ass
->get_description().c_str());
5691 case Assignment::A_TIMER
:
5692 case Assignment::A_PORT
:
5693 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5694 // sizeof is applicable to timer and port arrays
5695 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5697 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5698 t_ass
->get_description().c_str());
5701 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5702 Type::EXPECTED_DYNAMIC_VALUE
);
5705 refd_dim
= t_subrefs
->get_nof_refs();
5706 size_t nof_dims
= t_dims
->get_nof_dims();
5707 if (refd_dim
> nof_dims
) goto error
;
5708 else if (refd_dim
== nof_dims
) {
5709 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5710 t_ass
->get_assname());
5713 } else refd_dim
= 0;
5714 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5718 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5719 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5720 t_ass
->get_description().c_str());
5724 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5725 if (!t_type
) goto error
;
5726 t_type
= t_type
->get_type_refd_last();
5728 switch(t_type
->get_typetype()) {
5745 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5746 " set, set of, objid or array was expected");
5751 // check for index overflows in subrefs if possible
5753 switch (t_val
->get_valuetype()) {
5757 if (t_val
->is_indexed()) {
5764 /* The reference points to a constant. */
5765 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5766 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5767 if (!t_val
) goto error
;
5768 t_val
=t_val
->get_value_refd_last(refch
);
5769 } else { t_val
= 0; }
5770 } else if (t_templ
) {
5771 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5772 time. Don't try to evaluate it at compile time. */
5773 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5775 /* The reference points to a static template. */
5776 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5777 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5778 if (!t_templ
) goto error
;
5779 t_templ
= t_templ
->get_template_refd_last(refch
);
5780 } else { t_templ
= 0; }
5783 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5785 switch(t_templ
->get_templatetype()) {
5786 case Template::TEMPLATE_ERROR
:
5788 case Template::TEMPLATE_REFD
:
5792 case Template::SPECIFIC_VALUE
:
5793 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5796 case Template::TEMPLATE_LIST
:
5797 case Template::NAMED_TEMPLATE_LIST
:
5800 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5801 t_templ
->get_templatetype_str(),
5802 t_templ
->get_fullname().c_str());
5807 switch(t_val
->get_valuetype()) {
5818 // error is already reported
5827 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5828 result
= t_type
->get_dimension()->get_size();
5830 else if(t_templ
) { // sizeof()
5831 switch(t_templ
->get_templatetype()) {
5832 case Template::TEMPLATE_LIST
:
5833 if(t_templ
->temps_contains_anyornone_symbol()) {
5834 if(t_templ
->is_length_restricted()) {
5835 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5836 if (lr
->get_is_range()) {
5837 Value
*v_upper
= lr
->get_upper_value();
5839 if (v_upper
->valuetype
== V_INT
) {
5841 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
5842 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
5845 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5846 "templates without exact size");
5851 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5852 "templates containing `*' without upper boundary in the "
5853 "length restriction");
5857 Value
*v_single
= lr
->get_single_value();
5858 if (v_single
->valuetype
== V_INT
)
5859 result
= v_single
->u
.val_Int
->get_val();
5862 else { // not length restricted
5863 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
5864 " containing `*' without length restriction");
5868 else result
=t_templ
->get_nof_listitems();
5870 case Template::NAMED_TEMPLATE_LIST
:
5872 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
5873 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
5874 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
5877 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5881 switch(t_val
->get_valuetype()) {
5888 result
=t_val
->get_nof_comps();
5893 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
5894 if(t_val
->get_se_comp_byIndex(i
)->get_value()
5895 ->get_valuetype()!=V_OMIT
) result
++;
5899 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5905 set_valuetype(V_ERROR
);
5909 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
5911 Type
*governor
= ti
->get_expr_governor(exp_val
);
5913 ti
->get_Template()->set_lowerid_to_ref();
5914 governor
= ti
->get_expr_governor(exp_val
);
5918 ti
->append_stringRepr( str
);
5919 ti
->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5920 "If type is known, use valuof(<type>: %s) as argument.",
5921 str
.c_str(), get_opname(), str
.c_str());
5922 set_valuetype(V_ERROR
);
5927 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
5930 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5931 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
5932 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
5933 Type::EXPECTED_TEMPLATE
: exp_val
);
5935 Template
*t_temp
= u
.expr
.t2
->get_Template();
5936 if (t_temp
->is_undef_lowerid()) {
5937 // We convert the template to reference first even if the value is also
5938 // an undef lowerid. The user can prevent this by explicit type
5940 t_temp
->set_lowerid_to_ref();
5942 } else if (u
.expr
.v1
->is_undef_lowerid()) {
5943 u
.expr
.v1
->set_lowerid_to_ref();
5948 error("Cannot determine the type of arguments in `match()' operation");
5949 set_valuetype(V_ERROR
);
5952 u
.expr
.v1
->set_my_governor(governor
);
5954 Error_Context
cntxt(this, "In the first argument of `match()'"
5956 governor
->chk_this_value_ref(u
.expr
.v1
);
5957 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
5958 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
5961 Error_Context
cntxt(this, "In the second argument of `match()' "
5963 u
.expr
.t2
->chk(governor
);
5967 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
5968 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
5970 Ttcn::StatementBlock
*my_sb
;
5972 case Type::EXPECTED_CONSTANT
:
5973 error("An evaluatable constant value was expected instead of operation "
5974 "`%s'", get_opname());
5976 case Type::EXPECTED_STATIC_VALUE
:
5977 error("A static value was expected instead of operation `%s'",
5983 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5984 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
5986 error("Operation `%s' is allowed only within statements",
5990 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
5991 error("Operation `%s' is not allowed in the control part",
5995 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
5996 error("Operation `%s' cannot be used in a definition that has "
5997 "`runs on' clause", get_opname());
6000 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6001 error("Operation `%s' can be used only in a definition that has "
6002 "`runs on' clause", get_opname());
6007 set_valuetype(V_ERROR
);
6010 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6012 if(valuetype
==V_ERROR
) return;
6013 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6014 if(v
->is_unfoldable()) return;
6015 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6016 ttcn3float r
= v
->get_val_Real();
6017 if (isSpecialFloatValue(r
)) {
6018 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6019 opnum
, opname
, Real2string(r
).c_str());
6020 set_valuetype(V_ERROR
);
6024 void Value::chk_expr_operands(ReferenceChain
*refch
,
6025 Type::expected_value_t exp_val
)
6027 const char *first
="First", *second
="Second", *third
="Third",
6028 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6029 Value
*v1
, *v2
, *v3
;
6030 Type::typetype_t tt1
, tt2
, tt3
;
6031 Type
t_chk(Type::T_ERROR
);
6033 const char *opname
=get_opname();
6035 // first classify the unchecked ischosen() operation
6036 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6038 switch (u
.expr
.v_optype
) {
6039 case OPTYPE_COMP_NULL
:
6040 case OPTYPE_TESTCASENAME
:
6042 case OPTYPE_COMP_MTC
:
6043 case OPTYPE_COMP_SYSTEM
:
6044 chk_expr_comptype_compat();
6046 case OPTYPE_RND
: // -
6047 case OPTYPE_TMR_RUNNING_ANY
:
6048 chk_expr_dynamic_part(exp_val
, true);
6050 case OPTYPE_COMP_RUNNING_ANY
:
6051 case OPTYPE_COMP_RUNNING_ALL
:
6052 case OPTYPE_COMP_ALIVE_ANY
:
6053 case OPTYPE_COMP_ALIVE_ALL
:
6054 case OPTYPE_GETVERDICT
:
6055 chk_expr_dynamic_part(exp_val
, false);
6057 case OPTYPE_COMP_SELF
:
6058 chk_expr_comptype_compat();
6059 chk_expr_dynamic_part(exp_val
, false, true, false);
6061 case OPTYPE_UNARYPLUS
: // v1
6062 case OPTYPE_UNARYMINUS
:
6065 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6066 v1
->set_lowerid_to_ref();
6067 tt1
=v1
->get_expr_returntype(exp_val
);
6068 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6069 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
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_bool(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_binstr(tt1
, the
, opname
, v1
);
6089 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6092 case OPTYPE_BIT2HEX
:
6093 case OPTYPE_BIT2OCT
:
6094 case OPTYPE_BIT2STR
:
6097 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6098 v1
->set_lowerid_to_ref();
6099 tt1
=v1
->get_expr_returntype(exp_val
);
6100 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6101 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6104 case OPTYPE_BIT2INT
:
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
);
6112 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6115 case OPTYPE_CHAR2INT
:
6118 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6119 v1
->set_lowerid_to_ref();
6120 tt1
=v1
->get_expr_returntype(exp_val
);
6121 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6122 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6123 chk_expr_val_len1(v1
, the
, opname
);
6126 case OPTYPE_CHAR2OCT
:
6129 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6130 v1
->set_lowerid_to_ref();
6131 tt1
=v1
->get_expr_returntype(exp_val
);
6132 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6133 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6136 case OPTYPE_STR2INT
:
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
);
6144 chk_expr_val_str_int(v1
, the
, opname
);
6147 case OPTYPE_STR2FLOAT
:
6150 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6151 v1
->set_lowerid_to_ref();
6152 tt1
=v1
->get_expr_returntype(exp_val
);
6153 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6154 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6155 chk_expr_val_str_float(v1
, the
, opname
);
6158 case OPTYPE_STR2BIT
:
6161 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6162 v1
->set_lowerid_to_ref();
6163 tt1
=v1
->get_expr_returntype(exp_val
);
6164 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6165 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6166 chk_expr_val_str_bindigits(v1
, the
, opname
);
6169 case OPTYPE_STR2HEX
:
6172 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6173 v1
->set_lowerid_to_ref();
6174 tt1
=v1
->get_expr_returntype(exp_val
);
6175 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6176 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6177 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6180 case OPTYPE_STR2OCT
:
6183 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6184 v1
->set_lowerid_to_ref();
6185 tt1
=v1
->get_expr_returntype(exp_val
);
6186 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6187 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6188 chk_expr_val_str_len_even(v1
, the
, opname
);
6189 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6192 case OPTYPE_ENUM2INT
:
6195 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6196 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6197 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6201 chk_expr_operand_encode(refch
, exp_val
);
6203 case OPTYPE_FLOAT2INT
:
6204 case OPTYPE_FLOAT2STR
:
6207 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6208 v1
->set_lowerid_to_ref();
6209 tt1
=v1
->get_expr_returntype(exp_val
);
6210 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6211 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6212 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6213 chk_expr_operand_valid_float(v1
, the
, opname
);
6216 case OPTYPE_RNDWITHVAL
:
6219 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6220 v1
->set_lowerid_to_ref();
6221 tt1
=v1
->get_expr_returntype(exp_val
);
6222 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6223 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6224 chk_expr_operand_valid_float(v1
, the
, opname
);
6226 chk_expr_dynamic_part(exp_val
, true);
6228 case OPTYPE_HEX2BIT
:
6229 case OPTYPE_HEX2OCT
:
6230 case OPTYPE_HEX2STR
:
6233 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6234 v1
->set_lowerid_to_ref();
6235 tt1
=v1
->get_expr_returntype(exp_val
);
6236 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6237 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6240 case OPTYPE_HEX2INT
:
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
);
6248 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6251 case OPTYPE_INT2CHAR
:
6254 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6255 v1
->set_lowerid_to_ref();
6256 tt1
=v1
->get_expr_returntype(exp_val
);
6257 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6258 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6259 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6262 case OPTYPE_INT2UNICHAR
:
6265 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6266 v1
->set_lowerid_to_ref();
6267 tt1
=v1
->get_expr_returntype(exp_val
);
6268 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6269 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6270 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6273 case OPTYPE_INT2FLOAT
:
6274 case OPTYPE_INT2STR
:
6277 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6278 v1
->set_lowerid_to_ref();
6279 tt1
=v1
->get_expr_returntype(exp_val
);
6280 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6281 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6284 case OPTYPE_OCT2BIT
:
6285 case OPTYPE_OCT2HEX
:
6286 case OPTYPE_OCT2STR
:
6289 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6290 v1
->set_lowerid_to_ref();
6291 tt1
=v1
->get_expr_returntype(exp_val
);
6292 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6293 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6296 case OPTYPE_OCT2INT
:
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
);
6304 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6308 case OPTYPE_OCT2CHAR
:
6311 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6312 v1
->set_lowerid_to_ref();
6313 tt1
=v1
->get_expr_returntype(exp_val
);
6314 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6315 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6316 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6319 case OPTYPE_REMOVE_BOM
:
6322 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6323 v1
->set_lowerid_to_ref();
6324 tt1
=v1
->get_expr_returntype(exp_val
);
6325 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6326 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6329 case OPTYPE_GET_STRINGENCODING
:
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_ENCODE_BASE64
:
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
);
6348 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6351 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6352 v2
->set_lowerid_to_ref();
6353 tt2
=v2
->get_expr_returntype(exp_val
);
6354 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6355 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6358 case OPTYPE_DECODE_BASE64
:
6361 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6362 v1
->set_lowerid_to_ref();
6363 tt1
=v1
->get_expr_returntype(exp_val
);
6364 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6365 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6368 case OPTYPE_UNICHAR2INT
:
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_charstr(tt1
, the
, opname
, v1
);
6375 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6376 chk_expr_val_len1(v1
, the
, opname
);
6379 case OPTYPE_UNICHAR2CHAR
:
6382 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6383 v1
->set_lowerid_to_ref();
6384 tt1
=v1
->get_expr_returntype(exp_val
);
6385 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6386 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6387 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6390 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6393 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6394 v1
->set_lowerid_to_ref();
6395 tt1
=v1
->get_expr_returntype(exp_val
);
6396 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6397 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6399 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6402 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6403 v2
->set_lowerid_to_ref();
6404 tt2
=v2
->get_expr_returntype(exp_val
);
6405 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6406 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6409 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6412 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6413 v1
->set_lowerid_to_ref();
6414 tt1
=v1
->get_expr_returntype(exp_val
);
6415 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6416 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6418 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6421 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6422 v2
->set_lowerid_to_ref();
6423 tt2
=v2
->get_expr_returntype(exp_val
);
6424 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6425 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6428 case OPTYPE_ADD
: // v1 v2
6429 case OPTYPE_SUBTRACT
:
6430 case OPTYPE_MULTIPLY
:
6434 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6435 v1
->set_lowerid_to_ref();
6436 tt1
=v1
->get_expr_returntype(exp_val
);
6437 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6438 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6439 chk_expr_operand_valid_float(v1
, first
, opname
);
6443 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6444 v2
->set_lowerid_to_ref();
6445 tt2
=v2
->get_expr_returntype(exp_val
);
6446 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6447 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6448 chk_expr_operand_valid_float(v2
, second
, opname
);
6449 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6450 chk_expr_val_int_float_not0(v2
, second
, opname
);
6452 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6458 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6459 v1
->set_lowerid_to_ref();
6460 tt1
=v1
->get_expr_returntype(exp_val
);
6461 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6462 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6466 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6467 v2
->set_lowerid_to_ref();
6468 tt2
=v2
->get_expr_returntype(exp_val
);
6469 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6470 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6471 chk_expr_val_int_float_not0(v2
, right
, opname
);
6474 case OPTYPE_CONCAT
: {
6477 v1
->set_lowerid_to_ref();
6478 v2
->set_lowerid_to_ref();
6479 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6481 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6482 tt1
=v1
->get_expr_returntype(exp_val
);
6483 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6484 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6487 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6488 tt2
=v2
->get_expr_returntype(exp_val
);
6489 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6490 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6492 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6493 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6494 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6495 } else { // other list types
6496 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6497 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6499 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6500 set_valuetype(V_ERROR
);
6503 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6504 v1_gov
->chk_this_value_ref(v1
);
6505 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6506 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6507 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6511 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6512 set_valuetype(V_ERROR
);
6515 // for recof/setof literals set the type from v1
6517 v2
->set_my_governor(v1_gov
);
6520 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6522 v2_gov
->chk_this_value_ref(v2
);
6523 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6524 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6525 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6526 if (valuetype
== V_ERROR
) return;
6527 // 7.1.2 says that we shouldn't allow type compatibility.
6528 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6529 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6530 error("The operands of operation `%s' should be of compatible "
6531 "types", get_opname());
6540 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6542 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6544 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6547 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6549 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6550 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6551 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6552 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6553 * "a == not b" is not allowed. (HL69107)
6554 * The various *Expressions implement operator precedence in the std.
6555 * Titan's parser has only one Expression and relies on Bison
6556 * for operator precedence. The check below brings Titan in line
6557 * with the standard by explicitly making "a == not b" an error */
6558 if (v2
->get_valuetype() == V_EXPR
6559 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6560 error("The operation `%s' is not allowed to be "
6561 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6562 set_valuetype(V_ERROR
);
6572 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6574 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6576 tt1
=v1
->get_expr_returntype(exp_val
);
6577 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6578 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6581 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6583 tt2
=v2
->get_expr_returntype(exp_val
);
6584 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6585 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6593 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6595 v1
->set_lowerid_to_ref();
6596 tt1
=v1
->get_expr_returntype(exp_val
);
6597 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6598 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6602 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6604 v2
->set_lowerid_to_ref();
6605 tt2
=v2
->get_expr_returntype(exp_val
);
6606 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6607 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6615 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6617 v1
->set_lowerid_to_ref();
6618 tt1
=v1
->get_expr_returntype(exp_val
);
6619 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6620 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6624 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6626 v2
->set_lowerid_to_ref();
6627 tt2
=v2
->get_expr_returntype(exp_val
);
6628 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6629 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6631 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6632 chk_expr_operands_str_samelen();
6638 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6639 v1
->set_lowerid_to_ref();
6640 tt1
=v1
->get_expr_returntype(exp_val
);
6641 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6642 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6646 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6647 v2
->set_lowerid_to_ref();
6648 tt2
=v2
->get_expr_returntype(exp_val
);
6649 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6650 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6651 chk_expr_val_large_int(v2
, right
, opname
);
6657 v1
->set_lowerid_to_ref();
6658 if (v1
->is_string_type(exp_val
)) {
6659 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6660 tt1
=v1
->get_expr_returntype(exp_val
);
6661 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6662 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6663 } else { // other list types
6664 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6665 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6666 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6668 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6669 v1_gov
->chk_this_value_ref(v1
);
6670 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6671 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6672 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6677 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6678 v2
->set_lowerid_to_ref();
6679 tt2
=v2
->get_expr_returntype(exp_val
);
6680 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6681 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6682 chk_expr_val_large_int(v2
, right
, opname
);
6685 case OPTYPE_INT2BIT
:
6686 case OPTYPE_INT2HEX
:
6687 case OPTYPE_INT2OCT
:
6690 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6691 v1
->set_lowerid_to_ref();
6692 tt1
=v1
->get_expr_returntype(exp_val
);
6693 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6694 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6695 chk_expr_val_int_pos0(v1
, first
, opname
);
6699 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6700 v2
->set_lowerid_to_ref();
6701 tt2
=v2
->get_expr_returntype(exp_val
);
6702 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6703 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6704 chk_expr_val_int_pos0(v2
, second
, opname
);
6706 chk_expr_operands_int2binstr();
6709 chk_expr_operands_decode();
6713 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6714 Type::expected_value_t ti_exp_val
= exp_val
;
6715 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6716 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6717 if (!governor
) return;
6718 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6719 if (valuetype
!=V_ERROR
)
6720 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6721 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6725 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6726 v2
->set_lowerid_to_ref();
6727 tt2
=v2
->get_expr_returntype(exp_val
);
6728 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6729 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6730 chk_expr_val_int_pos0(v2
, second
, opname
);
6734 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6735 v3
->set_lowerid_to_ref();
6736 tt3
=v3
->get_expr_returntype(exp_val
);
6737 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6738 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6739 chk_expr_val_int_pos0(v3
, third
, opname
);
6741 chk_expr_operands_substr();
6743 case OPTYPE_REGEXP
: {
6744 Type::expected_value_t ti_exp_val
= exp_val
;
6745 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6747 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6748 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6749 if (!governor
) return;
6750 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6751 if (valuetype
!=V_ERROR
) {
6752 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6753 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6754 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6758 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6759 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6760 if (!governor
) return;
6761 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6762 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6763 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6767 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6768 v3
->set_lowerid_to_ref();
6769 tt3
=v3
->get_expr_returntype(exp_val
);
6770 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6771 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6772 chk_expr_val_int_pos0(v3
, third
, opname
);
6774 chk_expr_operands_regexp();
6776 case OPTYPE_ISCHOSEN
:
6777 // do nothing: the operand is erroneous
6778 // the error was already reported in chk_expr_ref_ischosen()
6780 case OPTYPE_ISCHOSEN_V
: // v1 i2
6781 case OPTYPE_ISCHOSEN_T
: // t1 i2
6782 chk_expr_operands_ischosen(refch
, exp_val
);
6784 case OPTYPE_VALUEOF
: { // ti1
6785 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6786 exp_val
= Type::EXPECTED_TEMPLATE
;
6787 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6788 Type
*governor
= my_governor
;
6789 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6790 if (!governor
) return;
6791 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6792 if (valuetype
== V_ERROR
) return;
6793 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6795 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6796 case OPTYPE_ISBOUND
: {
6797 Template
*templ
= u
.expr
.ti1
->get_Template();
6798 switch (templ
->get_templatetype()) {
6799 case Template::TEMPLATE_REFD
:
6800 templ
->get_reference()->setUsedInIsbound();
6802 case Template::SPECIFIC_VALUE
: {
6803 Value
*value
= templ
->get_specific_value();
6804 if (Value::V_REFD
== value
->get_valuetype()) {
6805 value
->get_reference()->setUsedInIsbound();
6813 case OPTYPE_ISVALUE
: {// ti1
6814 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6815 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6816 exp_val
= Type::EXPECTED_TEMPLATE
;
6817 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6818 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6819 if (!governor
) return;
6820 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
6821 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6823 case OPTYPE_SIZEOF
: // ti1
6824 /* this checking is too complex, do the checking during eval... */
6826 case OPTYPE_LENGTHOF
: { // ti1
6827 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6828 exp_val
= Type::EXPECTED_TEMPLATE
;
6829 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6830 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6831 if (!governor
) return;
6832 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
6833 if (valuetype
== V_ERROR
) return;
6834 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6836 case OPTYPE_MATCH
: // v1 t2
6837 chk_expr_operands_match(exp_val
);
6839 case OPTYPE_UNDEF_RUNNING
: // r1
6840 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
6842 case OPTYPE_COMP_ALIVE
:
6843 case OPTYPE_COMP_RUNNING
: //v1
6844 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
6845 chk_expr_dynamic_part(exp_val
, false);
6847 case OPTYPE_TMR_READ
: // r1
6848 case OPTYPE_TMR_RUNNING
: // r1
6849 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
6850 chk_expr_dynamic_part(exp_val
, true);
6852 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
6853 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
6854 chk_expr_dynamic_part(exp_val
, true, false, false);
6856 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
6857 chk_expr_operand_comptyperef_create();
6860 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6861 v2
->set_lowerid_to_ref();
6862 tt2
=v2
->get_expr_returntype(exp_val
);
6863 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
6864 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6868 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6869 v3
->set_lowerid_to_ref();
6870 tt3
=v3
->get_expr_returntype(exp_val
);
6871 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
6872 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6874 chk_expr_dynamic_part(exp_val
, false);
6876 case OPTYPE_ACTIVATE
: // r1 // altstep
6877 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
6878 chk_expr_dynamic_part(exp_val
, true);
6880 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
6881 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6882 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
6884 delete u
.expr
.t_list2
;
6885 u
.expr
.ap_list2
= parlist
;
6886 chk_expr_dynamic_part(exp_val
, true);
6888 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
6889 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6890 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
6891 u
.expr
.v3
, the
, opname
);
6892 delete u
.expr
.t_list2
;
6893 u
.expr
.ap_list2
= parlist
;
6894 chk_expr_dynamic_part(exp_val
, true);
6897 error("Built-in function `%s' is not yet supported", opname
);
6898 set_valuetype(V_ERROR
);
6900 case OPTYPE_REPLACE
: {
6901 Type::expected_value_t ti_exp_val
= exp_val
;
6902 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6903 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6905 Error_Context
cntxt(this, "In the first operand of operation `%s'",
6907 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6908 if (!governor
) return;
6909 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6910 if (valuetype
!= V_ERROR
)
6911 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6912 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6916 Error_Context
cntxt(this, "In the second operand of operation `%s'",
6918 v2
->set_lowerid_to_ref();
6919 tt2
= v2
->get_expr_returntype(exp_val
);
6920 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6921 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6922 chk_expr_val_int_pos0(v2
, second
, opname
);
6926 Error_Context
cntxt(this, "In the third operand of operation `%s'",
6928 v3
->set_lowerid_to_ref();
6929 tt3
= v3
->get_expr_returntype(exp_val
);
6930 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6931 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6932 chk_expr_val_int_pos0(v3
, third
, opname
);
6935 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
6937 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
6938 if (!governor
) return;
6939 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
6940 if (valuetype
!= V_ERROR
)
6941 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
6942 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
6944 chk_expr_operands_replace();
6946 case OPTYPE_LOG2STR
: {
6947 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6948 u
.expr
.logargs
->chk();
6949 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
6951 case OPTYPE_TTCN2STRING
: {
6952 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
6953 Type::expected_value_t ti_exp_val
= exp_val
;
6954 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6955 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6956 if (!governor
) return;
6957 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6960 FATAL_ERROR("chk_expr_operands()");
6964 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6965 // the result of evaluating the expression. E.g. V_BOOL for
6967 void Value::evaluate_value(ReferenceChain
*refch
,
6968 Type::expected_value_t exp_val
)
6970 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
6971 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
6973 u
.expr
.state
=EXPR_CHECKING
;
6975 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
6976 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
6977 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
6979 if(valuetype
==V_ERROR
) return;
6980 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
6981 u
.expr
.state
=EXPR_CHECKED
;
6982 set_valuetype(V_ERROR
);
6986 u
.expr
.state
=EXPR_CHECKED
;
6988 Value
*v1
, *v2
, *v3
, *v4
;
6989 switch(u
.expr
.v_optype
) {
6990 case OPTYPE_RND
: // -
6991 case OPTYPE_COMP_NULL
: // the only foldable in this group
6992 case OPTYPE_COMP_MTC
:
6993 case OPTYPE_COMP_SYSTEM
:
6994 case OPTYPE_COMP_SELF
:
6995 case OPTYPE_COMP_RUNNING_ANY
:
6996 case OPTYPE_COMP_RUNNING_ALL
:
6997 case OPTYPE_COMP_ALIVE_ANY
:
6998 case OPTYPE_COMP_ALIVE_ALL
:
6999 case OPTYPE_TMR_RUNNING_ANY
:
7000 case OPTYPE_GETVERDICT
:
7001 case OPTYPE_RNDWITHVAL
: // v1
7002 case OPTYPE_COMP_RUNNING
: // v1
7003 case OPTYPE_COMP_ALIVE
:
7004 case OPTYPE_TMR_READ
:
7005 case OPTYPE_TMR_RUNNING
:
7006 case OPTYPE_ACTIVATE
:
7007 case OPTYPE_ACTIVATE_REFD
:
7008 case OPTYPE_EXECUTE
: // r1 [v2]
7009 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7010 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7011 case OPTYPE_MATCH
: // v1 t2
7012 case OPTYPE_ISCHOSEN_T
:
7013 case OPTYPE_LOG2STR
:
7016 case OPTYPE_ISBOUND
:
7017 case OPTYPE_ISPRESENT
:
7018 case OPTYPE_TTCN2STRING
:
7019 case OPTYPE_UNICHAR2OCT
:
7020 case OPTYPE_OCT2UNICHAR
:
7021 case OPTYPE_ENCODE_BASE64
:
7022 case OPTYPE_DECODE_BASE64
:
7024 case OPTYPE_TESTCASENAME
: { // -
7025 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7026 Ttcn::StatementBlock
*my_sb
=
7027 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7029 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7030 if (!my_def
) { // In control part.
7031 set_val_str(new string(""));
7033 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7034 set_val_str(new string(my_def
->get_id().get_dispname()));
7038 case OPTYPE_UNARYPLUS
: // v1
7041 copy_and_destroy(v1
);
7043 case OPTYPE_UNARYMINUS
:
7044 if (is_unfoldable()) break;
7045 v1
= u
.expr
.v1
->get_value_refd_last();
7046 switch (v1
->valuetype
) {
7048 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7049 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7055 ttcn3float r
= v1
->get_val_Real();
7061 FATAL_ERROR("Value::evaluate_value()");
7065 if(is_unfoldable()) break;
7066 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7071 case OPTYPE_NOT4B
: {
7072 if(is_unfoldable()) break;
7073 v1
=u
.expr
.v1
->get_value_refd_last();
7074 const string
& s
= v1
->get_val_str();
7075 valuetype_t vt
=v1
->valuetype
;
7078 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7080 case OPTYPE_BIT2HEX
: {
7081 if(is_unfoldable()) break;
7082 v1
=u
.expr
.v1
->get_value_refd_last();
7083 const string
& s
= v1
->get_val_str();
7086 set_val_str(bit2hex(s
));
7088 case OPTYPE_BIT2OCT
: {
7089 if(is_unfoldable()) break;
7090 v1
=u
.expr
.v1
->get_value_refd_last();
7091 const string
& s
= v1
->get_val_str();
7094 set_val_str(bit2oct(s
));
7096 case OPTYPE_BIT2STR
:
7097 case OPTYPE_HEX2STR
:
7098 case OPTYPE_OCT2STR
: {
7099 if(is_unfoldable()) break;
7100 v1
=u
.expr
.v1
->get_value_refd_last();
7101 const string
& s
= v1
->get_val_str();
7104 set_val_str(new string(s
));
7106 case OPTYPE_BIT2INT
: {
7107 if (is_unfoldable()) break;
7108 v1
= u
.expr
.v1
->get_value_refd_last();
7109 const string
& s
= v1
->get_val_str();
7112 u
.val_Int
= bit2int(s
);
7114 case OPTYPE_CHAR2INT
: {
7115 if (is_unfoldable()) break;
7116 v1
= u
.expr
.v1
->get_value_refd_last();
7117 char c
= v1
->get_val_str()[0];
7120 u
.val_Int
= new int_val_t((Int
)c
);
7122 case OPTYPE_CHAR2OCT
: {
7123 if(is_unfoldable()) break;
7124 v1
=u
.expr
.v1
->get_value_refd_last();
7125 const string
& s
= v1
->get_val_str();
7128 set_val_str(char2oct(s
));
7130 case OPTYPE_STR2INT
: {
7131 if (is_unfoldable()) break;
7132 v1
= u
.expr
.v1
->get_value_refd_last();
7133 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7137 /** \todo hiba eseten lenyeli... */
7139 case OPTYPE_STR2FLOAT
: {
7140 if(is_unfoldable()) break;
7141 v1
=u
.expr
.v1
->get_value_refd_last();
7142 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7146 /** \todo hiba eseten lenyeli... */
7148 case OPTYPE_STR2BIT
: {
7149 if(is_unfoldable()) break;
7150 v1
=u
.expr
.v1
->get_value_refd_last();
7151 const string
& s
= v1
->get_val_str();
7154 set_val_str(new string(s
));
7156 case OPTYPE_STR2HEX
:
7157 case OPTYPE_OCT2HEX
: {
7158 if(is_unfoldable()) break;
7159 v1
=u
.expr
.v1
->get_value_refd_last();
7160 const string
& s
= v1
->get_val_str();
7163 set_val_str(to_uppercase(s
));
7165 case OPTYPE_STR2OCT
: {
7166 if(is_unfoldable()) break;
7167 v1
=u
.expr
.v1
->get_value_refd_last();
7168 const string
& s
= v1
->get_val_str();
7171 set_val_str(to_uppercase(s
));
7173 case OPTYPE_FLOAT2INT
: {
7174 if (is_unfoldable()) break;
7175 v1
= u
.expr
.v1
->get_value_refd_last();
7176 ttcn3float r
= v1
->get_val_Real();
7179 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7181 case OPTYPE_FLOAT2STR
: {
7182 if(is_unfoldable()) break;
7183 v1
=u
.expr
.v1
->get_value_refd_last();
7184 ttcn3float r
=v1
->get_val_Real();
7187 set_val_str(float2str(r
));
7189 case OPTYPE_HEX2BIT
:
7190 case OPTYPE_OCT2BIT
: {
7191 if(is_unfoldable()) break;
7192 v1
=u
.expr
.v1
->get_value_refd_last();
7193 const string
& s
= v1
->get_val_str();
7196 set_val_str(hex2bit(s
));
7198 case OPTYPE_HEX2INT
:
7199 case OPTYPE_OCT2INT
: {
7200 if(is_unfoldable()) break;
7201 v1
=u
.expr
.v1
->get_value_refd_last();
7202 const string
& s
= v1
->get_val_str();
7205 u
.val_Int
=hex2int(s
);
7207 case OPTYPE_HEX2OCT
: {
7208 if(is_unfoldable()) break;
7209 v1
=u
.expr
.v1
->get_value_refd_last();
7210 const string
& s
= v1
->get_val_str();
7213 set_val_str(hex2oct(s
));
7215 case OPTYPE_INT2CHAR
: {
7216 if (is_unfoldable()) break;
7217 v1
= u
.expr
.v1
->get_value_refd_last();
7218 const int_val_t
*c_int
= v1
->get_val_Int();
7219 char c
= static_cast<char>(c_int
->get_val());
7222 set_val_str(new string(1, &c
));
7224 case OPTYPE_INT2UNICHAR
: {
7225 if (is_unfoldable()) break;
7226 v1
= u
.expr
.v1
->get_value_refd_last();
7227 const int_val_t
*i_int
= v1
->get_val_Int();
7228 Int i
= i_int
->get_val();
7231 set_val_ustr(int2unichar(i
));
7232 u
.ustr
.convert_str
= false;
7234 case OPTYPE_INT2FLOAT
: {
7235 if (is_unfoldable()) break;
7236 v1
= u
.expr
.v1
->get_value_refd_last();
7237 const int_val_t
*i_int
= v1
->get_val_Int();
7238 Real i_int_real
= i_int
->to_real();
7241 u
.val_Real
= i_int_real
;
7243 case OPTYPE_INT2STR
: {
7244 if (is_unfoldable()) break;
7245 v1
= u
.expr
.v1
->get_value_refd_last();
7246 const int_val_t
*i_int
= v1
->get_val_Int();
7247 string
*i_int_str
= new string(i_int
->t_str());
7250 set_val_str(i_int_str
);
7252 case OPTYPE_OCT2CHAR
: {
7253 if(is_unfoldable()) break;
7254 v1
=u
.expr
.v1
->get_value_refd_last();
7255 const string
& s
= v1
->get_val_str();
7258 set_val_str(oct2char(s
));
7260 case OPTYPE_GET_STRINGENCODING
: {
7261 if(is_unfoldable()) break;
7262 v1
= u
.expr
.v1
->get_value_refd_last();
7263 const string
& s1
= v1
->get_val_str();
7266 set_val_str(get_stringencoding(s1
));
7268 case OPTYPE_REMOVE_BOM
: {
7269 if(is_unfoldable()) break;
7270 v1
= u
.expr
.v1
->get_value_refd_last();
7271 const string
& s1
= v1
->get_val_str();
7274 set_val_str(remove_bom(s1
));
7276 case OPTYPE_ENUM2INT
: {
7277 if(is_unfoldable()) break;
7278 v1
=u
.expr
.v1
->get_value_refd_last();
7279 Type
* enum_type
= v1
->get_my_governor();
7280 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7283 u
.val_Int
= new int_val_t(enum_val
);
7285 case OPTYPE_UNICHAR2INT
:
7286 if (is_unfoldable()) {
7287 // replace the operation with char2int() if the operand is a charstring
7288 // value to avoid its unnecessary conversion to universal charstring
7289 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7290 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7292 v1
=u
.expr
.v1
->get_value_refd_last();
7293 const ustring
& s
= v1
->get_val_ustr();
7296 u
.val_Int
=new int_val_t(unichar2int(s
));
7299 case OPTYPE_UNICHAR2CHAR
:
7301 if (is_unfoldable()) {
7302 // replace the operation with its operand if it is a charstring
7303 // value to avoid its unnecessary conversion to universal charstring
7304 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7306 copy_and_destroy(v1
);
7309 v1
= v1
->get_value_refd_last();
7310 const ustring
& s
= v1
->get_val_ustr();
7313 set_val_str(new string(s
));
7316 case OPTYPE_MULTIPLY
: { // v1 v2
7317 if (!is_unfoldable()) goto eval_arithmetic
;
7318 v1
= u
.expr
.v1
->get_value_refd_last();
7319 v2
= u
.expr
.v2
->get_value_refd_last();
7320 if (v1
->is_unfoldable()) v1
= v2
;
7321 if (v1
->is_unfoldable()) break;
7322 switch(v1
->valuetype
) {
7324 if (*v1
->get_val_Int() != 0) break;
7327 u
.val_Int
= new int_val_t((Int
)0);
7330 if (v1
->get_val_Real() != 0.0) break;
7336 FATAL_ERROR("Value::evaluate_value()");
7339 case OPTYPE_ADD
: // v1 v2
7340 case OPTYPE_SUBTRACT
:
7345 if(is_unfoldable()) break;
7346 v1
=u
.expr
.v1
->get_value_refd_last();
7347 v2
=u
.expr
.v2
->get_value_refd_last();
7348 operationtype_t ot
=u
.expr
.v_optype
;
7349 switch (v1
->valuetype
) {
7351 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7352 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7357 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7359 case OPTYPE_SUBTRACT
:
7360 u
.val_Int
= new int_val_t(*i1
- *i2
);
7362 case OPTYPE_MULTIPLY
:
7363 u
.val_Int
= new int_val_t(*i1
* *i2
);
7366 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7369 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7372 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7375 FATAL_ERROR("Value::evaluate_value()");
7381 ttcn3float r1
=v1
->get_val_Real();
7382 ttcn3float r2
=v2
->get_val_Real();
7389 case OPTYPE_SUBTRACT
:
7392 case OPTYPE_MULTIPLY
:
7399 FATAL_ERROR("Value::evaluate_value()");
7403 FATAL_ERROR("Value::evaluate_value()");
7406 case OPTYPE_CONCAT
: {
7407 if(is_unfoldable()) break;
7408 v1
=u
.expr
.v1
->get_value_refd_last();
7409 v2
=u
.expr
.v2
->get_value_refd_last();
7410 valuetype_t vt
= v1
->valuetype
;
7411 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7412 const ustring
& s1
= v1
->get_val_ustr();
7413 const ustring
& s2
= v2
->get_val_ustr();
7416 set_val_ustr(new ustring(s1
+ s2
));
7417 u
.ustr
.convert_str
= false;
7419 const string
& s1
= v1
->get_val_str();
7420 const string
& s2
= v2
->get_val_str();
7423 set_val_str(new string(s1
+ s2
));
7427 if(is_unfoldable()) break;
7428 v1
=u
.expr
.v1
->get_value_refd_last();
7429 v2
=u
.expr
.v2
->get_value_refd_last();
7436 if(is_unfoldable()) break;
7437 v1
=u
.expr
.v1
->get_value_refd_last();
7438 v2
=u
.expr
.v2
->get_value_refd_last();
7445 if(is_unfoldable()) break;
7446 v1
=u
.expr
.v1
->get_value_refd_last();
7447 v2
=u
.expr
.v2
->get_value_refd_last();
7454 if(is_unfoldable()) break;
7455 v1
=u
.expr
.v1
->get_value_refd_last();
7456 v2
=u
.expr
.v2
->get_value_refd_last();
7463 if(is_unfoldable()) break;
7464 v1
=u
.expr
.v1
->get_value_refd_last();
7465 v2
=u
.expr
.v2
->get_value_refd_last();
7472 if(is_unfoldable()) break;
7473 v1
=u
.expr
.v1
->get_value_refd_last();
7474 v2
=u
.expr
.v2
->get_value_refd_last();
7481 v1
= u
.expr
.v1
->get_value_refd_last();
7482 if (v1
->valuetype
== V_BOOL
) {
7483 if (v1
->get_val_bool()) {
7484 // the left operand is a literal "true"
7485 // substitute the expression with the right operand
7488 copy_and_destroy(v2
);
7490 // the left operand is a literal "false"
7491 // the result must be false regardless the right operand
7492 // because of the short circuit evaluation rule
7498 // we must keep the left operand because of the potential side effects
7499 // the right operand can only be eliminated if it is a literal "true"
7500 v2
= u
.expr
.v2
->get_value_refd_last();
7501 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7504 copy_and_destroy(v1
);
7509 v1
= u
.expr
.v1
->get_value_refd_last();
7510 if (v1
->valuetype
== V_BOOL
) {
7511 if (v1
->get_val_bool()) {
7512 // the left operand is a literal "true"
7513 // the result must be true regardless the right operand
7514 // because of the short circuit evaluation rule
7519 // the left operand is a literal "false"
7520 // substitute the expression with the right operand
7523 copy_and_destroy(v2
);
7526 // we must keep the left operand because of the potential side effects
7527 // the right operand can only be eliminated if it is a literal "false"
7528 v2
= u
.expr
.v2
->get_value_refd_last();
7529 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7532 copy_and_destroy(v1
);
7537 if(is_unfoldable()) break;
7538 v1
=u
.expr
.v1
->get_value_refd_last();
7539 v2
=u
.expr
.v2
->get_value_refd_last();
7540 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7545 case OPTYPE_AND4B
: {
7546 if(is_unfoldable()) break;
7547 v1
=u
.expr
.v1
->get_value_refd_last();
7548 v2
=u
.expr
.v2
->get_value_refd_last();
7549 valuetype_t vt
=v1
->valuetype
;
7550 const string
& s1
= v1
->get_val_str();
7551 const string
& s2
= v2
->get_val_str();
7554 set_val_str(and4b(s1
, s2
));
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(or4b(s1
, s2
));
7567 case OPTYPE_XOR4B
: {
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(xor4b(s1
, s2
));
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
& s
= v1
->get_val_str();
7584 const int_val_t
*i_int
= v2
->get_val_Int();
7585 Int i
=i_int
->get_val();
7586 if(vt
==V_OSTR
) i
*=2;
7589 set_val_str(shift_left(s
, i
));
7592 if(is_unfoldable()) break;
7593 v1
=u
.expr
.v1
->get_value_refd_last();
7594 v2
=u
.expr
.v2
->get_value_refd_last();
7595 valuetype_t vt
=v1
->valuetype
;
7596 const string
& s
= v1
->get_val_str();
7597 const int_val_t
*i_int
= v2
->get_val_Int();
7598 Int i
=i_int
->get_val();
7599 if(vt
==V_OSTR
) i
*=2;
7602 set_val_str(shift_right(s
, i
));
7605 if(is_unfoldable()) break;
7606 v1
=u
.expr
.v1
->get_value_refd_last();
7607 v2
=u
.expr
.v2
->get_value_refd_last();
7608 valuetype_t vt
=v1
->valuetype
;
7609 const int_val_t
*i_int
=v2
->get_val_Int();
7610 Int i
=i_int
->get_val();
7612 const ustring
& s
= v1
->get_val_ustr();
7615 set_val_ustr(rotate_left(s
, i
));
7616 u
.ustr
.convert_str
= false;
7619 if(vt
==V_OSTR
) i
*=2;
7620 const string
& s
= v1
->get_val_str();
7623 set_val_str(rotate_left(s
, i
));
7627 if(is_unfoldable()) break;
7628 v1
=u
.expr
.v1
->get_value_refd_last();
7629 v2
=u
.expr
.v2
->get_value_refd_last();
7630 valuetype_t vt
=v1
->valuetype
;
7631 const int_val_t
*i_int
=v2
->get_val_Int();
7632 Int i
=i_int
->get_val();
7634 const ustring
& s
= v1
->get_val_ustr();
7637 set_val_ustr(rotate_right(s
, i
));
7638 u
.ustr
.convert_str
= false;
7641 if(vt
==V_OSTR
) i
*=2;
7642 const string
& s
= v1
->get_val_str();
7645 set_val_str(rotate_right(s
, i
));
7648 case OPTYPE_INT2BIT
: {
7649 if (is_unfoldable()) break;
7650 v1
= u
.expr
.v1
->get_value_refd_last();
7651 v2
= u
.expr
.v2
->get_value_refd_last();
7652 const int_val_t
*i1_int
= v1
->get_val_Int();
7653 const int_val_t
*i2_int
= v2
->get_val_Int();
7654 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7659 case OPTYPE_INT2HEX
: {
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 // Do it before the `clean_up'. i2_int is already checked.
7666 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7671 case OPTYPE_INT2OCT
: {
7672 if (is_unfoldable()) break;
7673 v1
= u
.expr
.v1
->get_value_refd_last();
7674 v2
= u
.expr
.v2
->get_value_refd_last();
7675 const int_val_t
i1_int(*v1
->get_val_Int());
7676 // `v2' is a native integer.
7677 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7680 set_val_str(int2hex(i1_int
, i2_int
));
7682 case OPTYPE_SUBSTR
: {
7683 if(is_unfoldable()) break;
7684 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7685 v2
=u
.expr
.v2
->get_value_refd_last();
7686 v3
=u
.expr
.v3
->get_value_refd_last();
7687 valuetype_t vt
=v1
->valuetype
;
7688 const int_val_t
*i2_int
=v2
->get_val_Int();
7689 const int_val_t
*i3_int
=v3
->get_val_Int();
7690 Int i2
=i2_int
->get_val();
7691 Int i3
=i3_int
->get_val();
7693 const ustring
& s
= v1
->get_val_ustr();
7696 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7697 u
.ustr
.convert_str
= false;
7704 const string
& s
= v1
->get_val_str();
7707 set_val_str(new string(s
.substr(i2
, i3
)));
7710 case OPTYPE_REPLACE
: {
7711 if(is_unfoldable()) break;
7712 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7713 v2
=u
.expr
.v2
->get_value_refd_last();
7714 v3
=u
.expr
.v3
->get_value_refd_last();
7715 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7716 valuetype_t vt
=v1
->valuetype
;
7717 const int_val_t
*i2_int
=v2
->get_val_Int();
7718 const int_val_t
*i3_int
=v3
->get_val_Int();
7719 Int i2
=i2_int
->get_val();
7720 Int i3
=i3_int
->get_val();
7723 string
*s1
= new string(v1
->get_val_str());
7724 const string
& s2
= v4
->get_val_str();
7727 s1
->replace(i2
, i3
, s2
);
7731 string
*s1
= new string(v1
->get_val_str());
7732 const string
& s2
= v4
->get_val_str();
7735 s1
->replace(i2
, i3
, s2
);
7741 string
*s1
= new string(v1
->get_val_str());
7742 const string
& s2
= v4
->get_val_str();
7745 s1
->replace(i2
, i3
, s2
);
7749 string
*s1
= new string(v1
->get_val_str());
7750 const string
& s2
= v4
->get_val_str();
7753 s1
->replace(i2
, i3
, s2
);
7757 ustring
*s1
= new ustring(v1
->get_val_ustr());
7758 const ustring
& s2
= v4
->get_val_ustr();
7761 s1
->replace(i2
, i3
, s2
);
7763 u
.ustr
.convert_str
= false;
7766 FATAL_ERROR("Value::evaluate_value()");
7769 case OPTYPE_REGEXP
: {
7770 if (is_unfoldable()) break;
7771 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7772 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7773 v3
=u
.expr
.v3
->get_value_refd_last();
7774 const int_val_t
*i3_int
= v3
->get_val_Int();
7775 Int i3
= i3_int
->get_val();
7776 if (v1
->valuetype
== V_CSTR
) {
7777 const string
& s1
= v1
->get_val_str();
7778 const string
& s2
= v2
->get_val_str();
7779 string
*result
= regexp(s1
, s2
, i3
);
7782 set_val_str(result
);
7783 } if (v1
->valuetype
== V_USTR
) {
7784 const ustring
& s1
= v1
->get_val_ustr();
7785 const ustring
& s2
= v2
->get_val_ustr();
7786 ustring
*result
= regexp(s1
, s2
, i3
);
7789 set_val_ustr(result
);
7790 u
.ustr
.convert_str
= false;
7793 case OPTYPE_LENGTHOF
:{
7794 if(is_unfoldable()) break;
7795 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7796 ->get_value_refd_last();
7798 if(v1
->is_string_type(exp_val
)) {
7799 i
=v1
->get_val_strlen();
7800 } else { // v1 is be seq/set of or array
7801 switch (v1
->valuetype
) {
7805 if(v1
->u
.val_vs
->is_indexed())
7806 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7807 else { i
= v1
->u
.val_vs
->get_nof_vs();}
7810 FATAL_ERROR("Value::evaluate_value()");
7815 u
.val_Int
=new int_val_t(i
);
7817 case OPTYPE_SIZEOF
: {
7818 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
7822 u
.val_Int
=new int_val_t(i
);
7825 case OPTYPE_ISVALUE
: {
7826 if(is_unfoldable()) break;
7827 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
7828 && u
.expr
.ti1
->get_Template()->is_Value();
7830 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
7831 is_singleval
= other_val
->evaluate_isvalue(false);
7832 // is_singleval now contains the compile-time result of isvalue
7837 u
.val_bool
= is_singleval
;
7839 case OPTYPE_ISCHOSEN_V
: {
7840 if (is_unfoldable()) break;
7841 v1
= u
.expr
.v1
->get_value_refd_last();
7842 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
7847 case OPTYPE_VALUEOF
: // ti1
7848 if (!u
.expr
.ti1
->get_DerivedRef() &&
7849 u
.expr
.ti1
->get_Template()->is_Value() &&
7850 !u
.expr
.ti1
->get_Type()) {
7851 // FIXME actually if the template instance has a type
7852 // it might still be foldable.
7853 // the argument is a single specific value
7854 v1
= u
.expr
.ti1
->get_Template()->get_Value();
7855 Type
*governor
= my_governor
;
7856 if (governor
== NULL
) {
7857 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
7858 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
7860 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
7861 if (governor
== NULL
)
7862 FATAL_ERROR("Value::evaluate_value()");
7864 valuetype
= v1
->valuetype
;
7866 set_my_governor(governor
);
7867 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
7868 u
.ref
.refd_last
= this;
7869 v1
->valuetype
= V_ERROR
;
7873 case OPTYPE_UNDEF_RUNNING
:
7875 FATAL_ERROR("Value::evaluate_value()");
7879 bool Value::evaluate_isvalue(bool from_sequence
)
7881 switch (valuetype
) {
7883 // Omit is not a value unless a member of a sequence or set
7884 return from_sequence
;
7887 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7888 case V_BOOL
: /**< boolean */
7889 case V_NAMEDINT
: /**< integer / named number */
7890 case V_NAMEDBITS
: /**< named bits (identifiers) */
7891 case V_INT
: /**< integer */
7892 case V_REAL
: /**< real/float */
7893 case V_ENUM
: /**< enumerated */
7894 case V_BSTR
: /**< bitstring */
7895 case V_HSTR
: /**< hexstring */
7896 case V_OSTR
: /**< octetstring */
7897 case V_CSTR
: /**< charstring */
7898 case V_USTR
: /**< universal charstring */
7899 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
7900 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
7901 case V_OID
: /**< object identifier */
7902 case V_ROID
: /**< relative object identifier */
7903 case V_VERDICT
: /**< all verdicts */
7904 return true; // values of built-in types return true
7906 // Code below was adapted from is_unfoldable(), false returned early.
7908 return u
.choice
.alt_value
->evaluate_isvalue(false);
7913 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
7914 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
7922 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
7923 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
7924 ->evaluate_isvalue(true)) return false;
7929 // alas, get_value_refd_last prevents this function from const
7930 return get_value_refd_last()->evaluate_isvalue(false);
7933 switch (u
.expr
.v_optype
) {
7934 // A constant null component reference is a corner case: it is foldable
7935 // but escapes unmodified from evaluate_value.
7936 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7937 // or is transformed into some other valuetype in evaluate_value.
7938 case OPTYPE_COMP_NULL
:
7941 break; // and fall through to the FATAL_ERROR
7945 FATAL_ERROR("Value::evaluate_isvalue()");
7951 void Value::evaluate_macro(Type::expected_value_t exp_val
)
7954 case MACRO_MODULEID
:
7956 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7957 set_val_str(new string(my_scope
->get_scope_mod()
7958 ->get_modid().get_dispname()));
7961 case MACRO_FILENAME
:
7962 case MACRO_BFILENAME
: {
7963 const char *t_filename
= get_filename();
7965 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7966 set_val_str(new string(t_filename
));
7969 case MACRO_FILEPATH
: {
7970 const char *t_filename
= get_filename();
7972 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7973 char *t_filepath
= canonize_input_file(t_filename
);
7975 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7976 set_val_str(new string(t_filepath
));
7980 case MACRO_LINENUMBER
: {
7981 int t_lineno
= get_first_line();
7983 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7984 set_val_str(new string(Int2string(t_lineno
)));
7987 case MACRO_LINENUMBER_C
: {
7988 int t_lineno
= get_first_line();
7990 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7991 u
.val_Int
= new int_val_t(t_lineno
);
7994 case MACRO_DEFINITIONID
: {
7995 // cut the second part from the fullname separated by dots
7996 const string
& t_fullname
= get_fullname();
7997 size_t first_char
= t_fullname
.find('.') + 1;
7998 if (first_char
>= t_fullname
.size())
7999 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8000 t_fullname
.c_str());
8001 set_val_str(new string(t_fullname
.substr(first_char
,
8002 t_fullname
.find('.', first_char
) - first_char
)));
8006 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8007 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8011 case MACRO_TESTCASEID
: {
8012 if (exp_val
== Type::EXPECTED_CONSTANT
||
8013 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8014 error("A %s value was expected instead of macro `%%testcaseId', "
8015 "which is evaluated at runtime",
8016 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8020 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8021 Ttcn::StatementBlock
*my_sb
=
8022 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8024 error("Usage of macro %%testcaseId is allowed only within the "
8025 "statement blocks of functions, altsteps and testcases");
8028 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8030 error("Macro %%testcaseId cannot be used in the control part. "
8031 "It is allowed only within the statement blocks of functions, "
8032 "altsteps and testcases");
8035 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8036 // folding is possible only within testcases
8037 set_val_str(new string(my_def
->get_id().get_dispname()));
8042 FATAL_ERROR("Value::evaluate_macro()");
8046 set_valuetype(V_ERROR
);
8049 void Value::add_id(Identifier
*p_id
)
8053 if(u
.ids
->has_key(p_id
->get_name())) {
8054 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8055 // The Value does not take ownership for the identifier,
8056 // so it must be deleted (add_is acts as a sink).
8059 else u
.ids
->add(p_id
->get_name(), p_id
);
8062 FATAL_ERROR("Value::add_id()");
8066 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8067 Type::expected_value_t exp_val
)
8069 set_lowerid_to_ref();
8070 switch (valuetype
) {
8072 // there might be a better place for this
8073 chk_invoke(exp_val
);
8076 // use the cache if available
8077 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8079 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8081 // the referred definition is not found
8082 set_valuetype(V_ERROR
);
8084 switch (ass
->get_asstype()) {
8085 case Assignment::A_OBJECT
:
8086 case Assignment::A_OS
: {
8087 // the referred definition is an ASN.1 object or object set
8088 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8089 if (!setting
|| setting
->get_st() == S_ERROR
) {
8090 // remain silent, the error has been already reported
8091 set_valuetype(V_ERROR
);
8093 } else if (setting
->get_st() != S_V
) {
8094 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8095 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8096 set_valuetype(V_ERROR
);
8101 refch
->mark_state();
8102 destroy_refch
= false;
8104 refch
= new ReferenceChain(this,
8105 "While searching referenced value");
8106 destroy_refch
= true;
8108 if (refch
->add(get_fullname())) {
8109 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8110 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8111 // in case of circular recursion the valuetype is already set
8112 // to V_ERROR, so don't set the cache
8113 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8115 // a circular recursion was detected
8116 set_valuetype(V_ERROR
);
8118 if (destroy_refch
) delete refch
;
8119 else refch
->prev_state();
8121 case Assignment::A_CONST
: {
8122 // the referred definition is a constant
8125 refch
->mark_state();
8126 destroy_refch
= false;
8128 refch
= new ReferenceChain(this,
8129 "While searching referenced value");
8130 destroy_refch
= true;
8132 if (refch
->add(get_fullname())) {
8133 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8134 Value
*v_refd
= ass
->get_Value()
8135 ->get_refd_sub_value(subrefs
, 0,
8136 u
.ref
.ref
->getUsedInIsbound(), refch
);
8138 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8139 // in case of circular recursion the valuetype is already set
8140 // to V_ERROR, so don't set the cache
8141 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8142 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8143 u
.ref
.refd_last
= this;
8144 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8145 u
.ref
.refd_last
= this;
8147 // the sub-reference points to a non-existent field
8148 set_valuetype(V_ERROR
);
8151 // a circular recursion was detected
8152 set_valuetype(V_ERROR
);
8154 if (destroy_refch
) delete refch
;
8155 else refch
->prev_state();
8157 case Assignment::A_EXT_CONST
:
8158 case Assignment::A_MODULEPAR
:
8159 case Assignment::A_VAR
:
8160 case Assignment::A_FUNCTION_RVAL
:
8161 case Assignment::A_EXT_FUNCTION_RVAL
:
8162 case Assignment::A_PAR_VAL_IN
:
8163 case Assignment::A_PAR_VAL_OUT
:
8164 case Assignment::A_PAR_VAL_INOUT
:
8165 // the referred definition is not a constant
8166 u
.ref
.refd_last
= this;
8168 case Assignment::A_FUNCTION
:
8169 case Assignment::A_EXT_FUNCTION
:
8170 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8171 "call of %s, which does not have return type",
8172 ass
->get_description().c_str());
8173 set_valuetype(V_ERROR
);
8175 case Assignment::A_FUNCTION_RTEMP
:
8176 case Assignment::A_EXT_FUNCTION_RTEMP
:
8177 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8178 "call of %s, which returns a template",
8179 ass
->get_description().c_str());
8180 set_valuetype(V_ERROR
);
8183 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8184 ass
->get_description().c_str());
8185 set_valuetype(V_ERROR
);
8188 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8192 // try to evaluate the expression
8195 refch
->mark_state();
8196 destroy_refch
=false;
8199 refch
=new ReferenceChain(this, "While evaluating expression");
8202 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8203 else set_valuetype(V_ERROR
);
8204 if(destroy_refch
) delete refch
;
8205 else refch
->prev_state();
8208 evaluate_macro(exp_val
);
8211 // return this for all other value types
8216 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8218 /* Note that the logic here needs to be in sync with evaluate_value,
8219 * and possibly others, i.e. if evaluate_value is called for a Value
8220 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8221 bool Value::is_unfoldable(ReferenceChain
*refch
,
8222 Type::expected_value_t exp_val
)
8224 if (UnfoldabilityCheck::is_running(this)) {
8225 // This function is already running on this value => infinite recursion
8229 UnfoldabilityCheck
checker(this);
8231 if (get_needs_conversion()) return true;
8232 switch (valuetype
) {
8236 case V_UNDEF_LOWERID
:
8240 // these value types are eliminated during semantic analysis
8241 FATAL_ERROR("Value::is_unfoldable()");
8246 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8250 if (!is_indexed()) {
8251 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8252 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8256 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8257 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8264 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8265 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8266 ->is_unfoldable(refch
, exp_val
)) return true;
8272 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8273 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8277 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8278 if(v_last
==this) return true; // there weren't any references to chase
8279 else return v_last
->is_unfoldable(refch
, exp_val
);
8282 // classify the unchecked ischosen() operation, if it was not done so far
8283 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8284 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8285 switch (u
.expr
.v_optype
) {
8286 case OPTYPE_RND
: // -
8287 case OPTYPE_COMP_MTC
:
8288 case OPTYPE_COMP_SYSTEM
:
8289 case OPTYPE_COMP_SELF
:
8290 case OPTYPE_COMP_RUNNING_ANY
:
8291 case OPTYPE_COMP_RUNNING_ALL
:
8292 case OPTYPE_COMP_ALIVE_ANY
:
8293 case OPTYPE_COMP_ALIVE_ALL
:
8294 case OPTYPE_TMR_RUNNING_ANY
:
8295 case OPTYPE_GETVERDICT
:
8296 case OPTYPE_TESTCASENAME
:
8297 case OPTYPE_RNDWITHVAL
: // v1
8298 case OPTYPE_MATCH
: // v1 t2
8299 case OPTYPE_UNDEF_RUNNING
: // v1
8300 case OPTYPE_COMP_RUNNING
:
8301 case OPTYPE_COMP_ALIVE
:
8302 case OPTYPE_TMR_READ
:
8303 case OPTYPE_TMR_RUNNING
:
8304 case OPTYPE_ACTIVATE
:
8305 case OPTYPE_ACTIVATE_REFD
:
8306 case OPTYPE_EXECUTE
: // r1 [v2]
8307 case OPTYPE_EXECUTE_REFD
:
8308 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8309 case OPTYPE_ISCHOSEN
:
8310 case OPTYPE_ISCHOSEN_T
:
8311 case OPTYPE_SIZEOF
: // ti1
8314 case OPTYPE_OCT2UNICHAR
:
8315 case OPTYPE_UNICHAR2OCT
:
8316 case OPTYPE_ENCODE_BASE64
:
8317 case OPTYPE_DECODE_BASE64
:
8319 case OPTYPE_COMP_NULL
: // -
8321 case OPTYPE_UNARYPLUS
: // v1
8322 case OPTYPE_UNARYMINUS
:
8325 case OPTYPE_BIT2HEX
:
8326 case OPTYPE_BIT2INT
:
8327 case OPTYPE_BIT2OCT
:
8328 case OPTYPE_BIT2STR
:
8329 case OPTYPE_CHAR2INT
:
8330 case OPTYPE_CHAR2OCT
:
8331 case OPTYPE_FLOAT2INT
:
8332 case OPTYPE_FLOAT2STR
:
8333 case OPTYPE_HEX2BIT
:
8334 case OPTYPE_HEX2INT
:
8335 case OPTYPE_HEX2OCT
:
8336 case OPTYPE_HEX2STR
:
8337 case OPTYPE_INT2CHAR
:
8338 case OPTYPE_INT2FLOAT
:
8339 case OPTYPE_INT2STR
:
8340 case OPTYPE_INT2UNICHAR
:
8341 case OPTYPE_OCT2BIT
:
8342 case OPTYPE_OCT2CHAR
:
8343 case OPTYPE_OCT2HEX
:
8344 case OPTYPE_OCT2INT
:
8345 case OPTYPE_OCT2STR
:
8346 case OPTYPE_STR2BIT
:
8347 case OPTYPE_STR2FLOAT
:
8348 case OPTYPE_STR2HEX
:
8349 case OPTYPE_STR2INT
:
8350 case OPTYPE_STR2OCT
:
8351 case OPTYPE_UNICHAR2INT
:
8352 case OPTYPE_UNICHAR2CHAR
:
8353 case OPTYPE_ENUM2INT
:
8354 case OPTYPE_GET_STRINGENCODING
:
8355 case OPTYPE_REMOVE_BOM
:
8356 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8357 case OPTYPE_ISBOUND
: /*{
8358 //TODO once we have the time for it make isbound foldable.
8359 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8360 Template* temp = u.expr.ti1->get_Template();
8361 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8362 Value* specificValue = temp->get_specific_value();
8363 if (specificValue->get_valuetype() == Value::V_REFD) {
8367 return specificValue->is_unfoldable(refch, exp_val);
8368 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8373 case OPTYPE_ISPRESENT
:
8374 // TODO: "if you have motivation"
8376 case OPTYPE_ISVALUE
: // ti1
8378 case OPTYPE_LENGTHOF
: // ti1
8379 return u
.expr
.ti1
->get_DerivedRef() != 0
8380 || u
.expr
.ti1
->get_Template()->get_templatetype()
8381 != Template::SPECIFIC_VALUE
8382 || u
.expr
.ti1
->get_Template()->get_specific_value()
8383 ->is_unfoldable(refch
, exp_val
);
8387 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8389 case OPTYPE_ADD
: // v1 v2
8390 case OPTYPE_SUBTRACT
:
8391 case OPTYPE_MULTIPLY
:
8407 case OPTYPE_INT2BIT
:
8408 case OPTYPE_INT2HEX
:
8409 case OPTYPE_INT2OCT
:
8410 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8411 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8412 case OPTYPE_AND
: // short-circuit evaluation
8413 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8414 || (u
.expr
.v1
->get_val_bool() &&
8415 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8416 case OPTYPE_OR
: // short-circuit evaluation
8417 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8418 || (!u
.expr
.v1
->get_val_bool() &&
8419 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8421 if (!u
.expr
.ti1
->get_specific_value()) return true;
8422 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8423 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8424 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8425 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8427 if (!u
.expr
.ti1
->get_specific_value() ||
8428 !u
.expr
.t2
->get_specific_value()) return true;
8429 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8430 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8431 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8433 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8434 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8435 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8436 case OPTYPE_REPLACE
: {
8437 if (!u
.expr
.ti1
->get_specific_value() ||
8438 !u
.expr
.ti4
->get_specific_value()) return true;
8439 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8440 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8441 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8442 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8443 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8445 case OPTYPE_VALUEOF
: // ti1
8446 /* \todo if you have motivation to implement the eval function
8449 case OPTYPE_ISCHOSEN_V
:
8450 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8451 case OPTYPE_LOG2STR
:
8452 case OPTYPE_TTCN2STRING
:
8455 FATAL_ERROR("Value::is_unfoldable()");
8457 break; // should never get here
8460 case MACRO_TESTCASEID
:
8461 // this is known only at runtime
8467 // all literal values are foldable
8472 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8473 size_t start_i
, bool usedInIsbound
,
8474 ReferenceChain
*refch
)
8476 if (!subrefs
) return this;
8478 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8480 v
= v
->get_value_refd_last(refch
);
8481 switch(v
->valuetype
) {
8490 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8491 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8492 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8493 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8498 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8499 bool usedInIsbound
, const Location
& loc
)
8501 if (valuetype
== V_OMIT
) {
8502 loc
.error("Reference to field `%s' of omit value `%s'",
8503 field_id
.get_dispname().c_str(), get_fullname().c_str());
8506 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8507 Type
*t
= my_governor
->get_type_refd_last();
8508 switch (t
->get_typetype()) {
8512 case Type::T_CHOICE_A
:
8513 case Type::T_CHOICE_T
:
8514 case Type::T_OPENTYPE
:
8515 case Type::T_ANYTYPE
:
8516 if (!t
->has_comp_withName(field_id
)) {
8517 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8518 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8520 } else if (valuetype
!= V_CHOICE
) {
8521 // remain silent, the error is already reported
8523 } else if (*u
.choice
.alt_name
== field_id
) {
8525 return u
.choice
.alt_value
;
8527 if (!usedInIsbound
) {
8528 loc
.error("Reference to inactive field `%s' in a value of union type "
8529 "`%s'. The active field is `%s'",
8530 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8531 u
.choice
.alt_name
->get_dispname().c_str());
8537 if (!t
->has_comp_withName(field_id
)) {
8538 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8539 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8541 } else if (valuetype
!= V_SEQ
) {
8542 // remain silent, the error has been already reported
8547 if (!t
->has_comp_withName(field_id
)) {
8548 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8549 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8551 } else if (valuetype
!= V_SET
) {
8552 // remain silent, the error has been already reported
8556 loc
.error("Invalid field reference `%s': type `%s' "
8557 "does not have fields", field_id
.get_dispname().c_str(),
8558 t
->get_typename().c_str());
8561 // the common end for record & set types
8562 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8564 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8565 } else if (!is_asn1()) {
8566 if (!usedInIsbound
) {
8567 loc
.error("Reference to unbound field `%s'",
8568 field_id
.get_dispname().c_str());
8569 // this is an error in TTCN-3, which has been already reported
8573 CompField
*cf
= t
->get_comp_byName(field_id
);
8574 if (cf
->get_is_optional()) {
8575 // creating an explicit omit value
8576 Value
*v
= new Value(V_OMIT
);
8577 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8578 v
->set_my_scope(get_my_scope());
8579 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8581 } else if (cf
->has_default()) {
8582 // returning the component's default value
8583 return cf
->get_defval();
8585 // this is an error in ASN.1, which has been already reported
8591 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8592 ReferenceChain
*refch
)
8594 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8596 bool index_available
= false;
8597 if (!v_index
->is_unfoldable()) {
8598 if (v_index
->valuetype
== V_INT
) {
8599 index
= v_index
->get_val_Int()->get_val();
8600 index_available
= true;
8602 array_index
->error("An integer value was expected as index");
8605 if (valuetype
== V_OMIT
) {
8606 array_index
->error("Accessing an element with index of omit value `%s'",
8607 get_fullname().c_str());
8610 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8611 Type
*t
= my_governor
->get_type_refd_last();
8612 switch (t
->get_typetype()) {
8617 if (index_available
) {
8619 array_index
->error("A non-negative integer value was expected "
8620 "instead of %s for indexing a value of `record "
8621 "of' type `%s'", Int2string(index
).c_str(),
8622 t
->get_typename().c_str());
8625 switch (valuetype
) {
8627 if (!is_indexed()) {
8628 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8629 if (!usedInIsbound
) {
8630 array_index
->error("Index overflow in a value of `record of' "
8631 "type `%s': the index is %s, but the value "
8632 "has only %lu elements",
8633 t
->get_typename().c_str(),
8634 Int2string(index
).c_str(),
8635 (unsigned long)u
.val_vs
->get_nof_vs());
8639 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8640 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8641 temp
->error("Not used symbol is not allowed in this context");
8642 return u
.val_vs
->get_v_byIndex(index
);
8645 // Search the appropriate constant index.
8646 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8647 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8648 ->get_value_refd_last();
8649 if (iv_index
->get_valuetype() != V_INT
) continue;
8650 if (iv_index
->get_val_Int()->get_val() == index
)
8651 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8657 // remain silent, the error has been already reported
8661 // the error has been reported above
8665 if (index_available
) {
8667 array_index
->error("A non-negative integer value was expected "
8668 "instead of %s for indexing a value of `set of' type `%s'",
8669 Int2string(index
).c_str(), t
->get_typename().c_str());
8672 switch (valuetype
) {
8674 if (!is_indexed()) {
8675 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8676 if (!usedInIsbound
) {
8677 array_index
->error("Index overflow in a value of `set of' type "
8678 "`%s': the index is %s, but the value has "
8679 "only %lu elements",
8680 t
->get_typename().c_str(),
8681 Int2string(index
).c_str(),
8682 (unsigned long)u
.val_vs
->get_nof_vs());
8686 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8687 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8688 temp
->error("Not used symbol is not allowed in this context");
8692 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8693 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8694 ->get_value_refd_last();
8695 if (iv_index
->get_valuetype() != V_INT
) continue;
8696 if (iv_index
->get_val_Int()->get_val() == index
)
8697 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8703 // remain silent, the error has been already reported
8707 // the error has been reported above
8711 if (index_available
) {
8712 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8713 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8714 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8715 // perform the index transformation
8716 index
-= dim
->get_offset();
8717 if (!is_indexed()) {
8718 // check for index underflow/overflow or too few elements in the
8721 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8723 else return u
.val_vs
->get_v_byIndex(index
);
8725 if (index
< 0) return 0;
8726 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8727 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8728 ->get_value_refd_last();
8729 if (iv_index
->get_valuetype() != V_INT
) continue;
8730 if (iv_index
->get_val_Int()->get_val() == index
)
8731 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8736 // remain silent, the error has been already reported
8740 // the error has been reported above
8744 case Type::T_BSTR_A
:
8749 case Type::T_UTF8STRING
:
8750 case Type::T_NUMERICSTRING
:
8751 case Type::T_PRINTABLESTRING
:
8752 case Type::T_TELETEXSTRING
:
8753 case Type::T_VIDEOTEXSTRING
:
8754 case Type::T_IA5STRING
:
8755 case Type::T_GRAPHICSTRING
:
8756 case Type::T_VISIBLESTRING
:
8757 case Type::T_GENERALSTRING
:
8758 case Type::T_UNIVERSALSTRING
:
8759 case Type::T_BMPSTRING
:
8760 case Type::T_UTCTIME
:
8761 case Type::T_GENERALIZEDTIME
:
8762 case Type::T_OBJECTDESCRIPTOR
:
8763 if (index_available
) return get_string_element(index
, *array_index
);
8766 array_index
->error("Invalid array element reference: type `%s' cannot "
8767 "be indexed", t
->get_typename().c_str());
8772 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8775 loc
.error("A non-negative integer value was expected instead of %s "
8776 "for indexing a string element", Int2string(index
).c_str());
8779 size_t string_length
;
8780 switch (valuetype
) {
8785 string_length
= u
.str
.val_str
->size();
8788 string_length
= u
.str
.val_str
->size() / 2;
8791 string_length
= u
.ustr
.val_ustr
->size();
8794 // remain silent, the error has been already reported
8797 if (index
>= static_cast<Int
>(string_length
)) {
8798 loc
.error("Index overflow when accessing a string element: "
8799 "the index is %s, but the string has only %lu elements",
8800 Int2string(index
).c_str(), (unsigned long) string_length
);
8803 switch (valuetype
) {
8808 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8809 return (*u
.str
.str_elements
)[index
];
8811 Value
*t_val
= new Value(valuetype
,
8812 new string(u
.str
.val_str
->substr(index
, 1)));
8813 add_string_element(index
, t_val
, u
.str
.str_elements
);
8817 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8818 return (*u
.str
.str_elements
)[index
];
8820 Value
*t_val
= new Value(V_OSTR
,
8821 new string(u
.str
.val_str
->substr(2 * index
, 2)));
8822 add_string_element(index
, t_val
, u
.str
.str_elements
);
8826 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
8827 return (*u
.ustr
.ustr_elements
)[index
];
8829 Value
*t_val
= new Value(V_USTR
,
8830 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
8831 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
8835 FATAL_ERROR("Value::get_string_element()");
8840 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
8841 Type::expected_value_t exp_val
)
8843 set_lowerid_to_ref();
8844 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
8845 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
8847 error("A value or expression of type %s was expected", type_name
);
8848 if (valuetype
== V_REFD
) {
8849 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
8850 t_chk
->chk_this_refd_value(this, 0, exp_val
);
8852 get_value_refd_last(0, exp_val
);
8853 if (error_flag
) set_valuetype(V_ERROR
);
8854 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
8857 int Value::is_parsed_infinity()
8859 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
8861 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
8862 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
8863 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
8868 bool Value::get_val_bool()
8871 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8873 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
8874 return v
->u
.val_bool
;
8877 int_val_t
* Value::get_val_Int()
8880 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8882 switch (v
->valuetype
) {
8885 case V_UNDEF_LOWERID
:
8886 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8887 "`%s'", (*u
.val_id
).get_dispname().c_str());
8889 FATAL_ERROR("Value::get_val_Int()");
8891 return v
->u
.val_Int
;
8894 const Identifier
* Value::get_val_id()
8899 case V_UNDEF_LOWERID
:
8902 FATAL_ERROR("Value::get_val_id()");
8907 const ttcn3float
& Value::get_val_Real()
8910 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8912 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
8913 return v
->u
.val_Real
;
8916 string
Value::get_val_str()
8918 Value
*v
= get_value_refd_last();
8919 switch (v
->valuetype
) {
8924 return *v
->u
.str
.val_str
;
8926 return v
->u
.char_syms
->get_string();
8928 error("Cannot use ISO-10646 string value in string context");
8931 error("Cannot use ISO-2022 string value in string context");
8936 error("Cannot use this value in charstring value context");
8941 ustring
Value::get_val_ustr()
8943 Value
*v
= get_value_refd_last();
8944 switch (v
->valuetype
) {
8946 return ustring(*v
->u
.str
.val_str
);
8948 return *v
->u
.ustr
.val_ustr
;
8950 return v
->u
.char_syms
->get_ustring();
8952 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8957 error("Cannot use this value in ISO-10646 string context");
8962 string
Value::get_val_iso2022str()
8964 Value
*v
= get_value_refd_last();
8965 switch (v
->valuetype
) {
8968 return *v
->u
.str
.val_str
;
8970 return v
->u
.char_syms
->get_iso2022string();
8972 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8977 error("Cannot use this value in ISO-2022 string context");
8982 size_t Value::get_val_strlen()
8984 Value
*v
= get_value_refd_last();
8985 switch (v
->valuetype
) {
8990 return v
->u
.str
.val_str
->size();
8992 return v
->u
.str
.val_str
->size()/2;
8994 return v
->u
.char_syms
->get_len();
8996 return v
->u
.ustr
.val_ustr
->size();
9000 error("Cannot use this value in string value context");
9005 Value::verdict_t
Value::get_val_verdict()
9011 FATAL_ERROR("Value::get_val_verdict()");
9016 size_t Value::get_nof_comps()
9018 switch (valuetype
) {
9022 return u
.oid_comps
->size();
9026 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9027 else return u
.val_vs
->get_nof_vs();
9030 return u
.val_nvs
->get_nof_nvs();
9035 return u
.str
.val_str
->size();
9037 return u
.str
.val_str
->size()/2;
9039 return u
.ustr
.val_ustr
->size();
9041 FATAL_ERROR("Value::get_nof_comps()");
9046 bool Value::is_indexed() const
9048 switch (valuetype
) {
9052 // Applicable only for list-types. Assigning a record/SEQUENCE or
9053 // set/SET with indexed notation is not supported.
9054 return u
.val_vs
->is_indexed();
9056 FATAL_ERROR("Value::is_indexed()");
9062 const Identifier
& Value::get_alt_name()
9064 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9065 return *u
.choice
.alt_name
;
9068 Value
*Value::get_alt_value()
9070 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9071 return u
.choice
.alt_value
;
9074 bool Value::has_oid_error()
9077 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9079 switch (valuetype
) {
9082 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9083 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9090 bool Value::get_oid_comps(vector
<string
>& comps
)
9092 bool ret_val
= true;
9094 switch (valuetype
) {
9096 v
= get_value_refd_last();
9100 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9101 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9102 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9103 // not all components can be calculated in compile-time
9109 FATAL_ERROR("Value::get_oid_comps()");
9114 void Value::add_se_comp(NamedValue
* nv
) {
9115 switch (valuetype
) {
9119 u
.val_nvs
= new NamedValues();
9120 u
.val_nvs
->add_nv(nv
);
9123 FATAL_ERROR("Value::add_se_comp()");
9127 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9132 return u
.val_nvs
->get_nv_byIndex(n
);
9134 FATAL_ERROR("Value::get_se_comp_byIndex()");
9139 Value
*Value::get_comp_byIndex(size_t n
)
9141 switch (valuetype
) {
9145 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9146 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9148 FATAL_ERROR("Value::get_comp_byIndex()");
9153 Value
*Value::get_index_byIndex(size_t n
)
9155 switch (valuetype
) {
9159 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9160 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9162 FATAL_ERROR("Value::get_index_byIndex()");
9167 bool Value::has_comp_withName(const Identifier
& p_name
)
9172 return u
.val_nvs
->has_nv_withName(p_name
);
9174 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9176 FATAL_ERROR("Value::get_has_comp_withName()");
9181 bool Value::field_is_chosen(const Identifier
& p_name
)
9183 Value
*v
=get_value_refd_last();
9184 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9185 return *v
->u
.choice
.alt_name
==p_name
;
9188 bool Value::field_is_present(const Identifier
& p_name
)
9190 Value
*v
=get_value_refd_last();
9191 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9192 FATAL_ERROR("Value::field_is_present()");
9193 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9194 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9195 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9198 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9203 return u
.val_nvs
->get_nv_byName(p_name
);
9205 FATAL_ERROR("Value::get_se_comp_byName()");
9210 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9215 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9217 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9218 return u
.choice
.alt_value
;
9222 FATAL_ERROR("Value::get_se_comp_byName()");
9227 void Value::chk_dupl_id()
9232 u
.val_nvs
->chk_dupl_id();
9235 FATAL_ERROR("Value::chk_dupl_id()");
9239 size_t Value::get_nof_ids() const
9243 return u
.ids
->size();
9246 FATAL_ERROR("Value::get_nof_ids()");
9251 Identifier
* Value::get_id_byIndex(size_t p_i
)
9255 return u
.ids
->get_nth_elem(p_i
);
9258 FATAL_ERROR("Value::get_id_byIndex()");
9263 bool Value::has_id(const Identifier
& p_id
)
9267 return u
.ids
->has_key(p_id
.get_name());
9270 FATAL_ERROR("Value::has_id()");
9275 Reference
*Value::get_reference() const
9277 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9281 Reference
*Value::get_refered() const
9283 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9287 Common::Assignment
*Value::get_refd_fat() const
9295 FATAL_ERROR("Value::get_refd_fat()");
9299 Ttcn::Reference
* Value::steal_ttcn_ref()
9301 Ttcn::Reference
*ret_val
=
9302 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9303 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9307 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9309 Ttcn::Ref_base
*t_ref
;
9310 if(valuetype
==V_REFD
) {
9311 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9312 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9315 else if(valuetype
==V_UNDEF_LOWERID
) {
9316 t_ref
=new Ttcn::Reference(u
.val_id
);
9317 t_ref
->set_location(*this);
9318 t_ref
->set_fullname(get_fullname());
9319 t_ref
->set_my_scope(get_my_scope());
9323 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9326 set_valuetype(V_ERROR
);
9330 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9331 Ttcn::ActualParList
*& p_ap
)
9333 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9336 p_ti
= u
.invoke
.t_list
;
9337 u
.invoke
.t_list
= 0;
9338 p_ap
= u
.invoke
.ap_list
;
9339 u
.invoke
.ap_list
= 0;
9340 set_valuetype(V_ERROR
);
9343 Common::Assignment
* Value::get_refd_assignment()
9352 FATAL_ERROR("Value::get_refd_assignment()");
9362 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9367 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9376 void Value::chk_OID(ReferenceChain
& refch
)
9378 if (checked
) return;
9379 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9380 FATAL_ERROR("Value::chk_OID()");
9381 if (!refch
.add(get_fullname())) {
9385 OID_comp::oidstate_t state
= OID_comp::START
;
9386 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9388 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9391 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9392 error("An OBJECT IDENTIFIER value must have at least "
9393 "two components"); // X.680 (07/2002) 31.10
9396 void Value::chk_ROID(ReferenceChain
& refch
)
9398 if (checked
) return;
9399 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9400 FATAL_ERROR("Value::chk_ROID()");
9401 if (!refch
.add(get_fullname())) {
9405 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9407 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9412 void Value::chk_recursions(ReferenceChain
& refch
)
9414 if (recurs_checked
) return;
9415 Value
*v
= get_value_refd_last();
9416 if (refch
.add(v
->get_fullname())) {
9417 switch (v
->valuetype
) {
9419 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9424 if (!v
->is_indexed()) {
9425 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9427 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9431 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9433 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9434 ->chk_recursions(refch
);
9441 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9443 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9448 chk_recursions_expr(refch
);
9453 if (v
->err_descr
) { // FIXME: make this work
9454 v
->err_descr
->chk_recursions(refch
);
9457 recurs_checked
= true;
9460 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9462 // first classify the unchecked ischosen() operation
9463 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9464 switch (u
.expr
.v_optype
) {
9465 case OPTYPE_UNARYPLUS
: // v1
9466 case OPTYPE_UNARYMINUS
:
9469 case OPTYPE_BIT2HEX
:
9470 case OPTYPE_BIT2INT
:
9471 case OPTYPE_BIT2OCT
:
9472 case OPTYPE_BIT2STR
:
9473 case OPTYPE_CHAR2INT
:
9474 case OPTYPE_CHAR2OCT
:
9475 case OPTYPE_FLOAT2INT
:
9476 case OPTYPE_FLOAT2STR
:
9477 case OPTYPE_HEX2BIT
:
9478 case OPTYPE_HEX2INT
:
9479 case OPTYPE_HEX2OCT
:
9480 case OPTYPE_HEX2STR
:
9481 case OPTYPE_INT2CHAR
:
9482 case OPTYPE_INT2FLOAT
:
9483 case OPTYPE_INT2STR
:
9484 case OPTYPE_INT2UNICHAR
:
9485 case OPTYPE_OCT2BIT
:
9486 case OPTYPE_OCT2CHAR
:
9487 case OPTYPE_OCT2HEX
:
9488 case OPTYPE_OCT2INT
:
9489 case OPTYPE_OCT2STR
:
9490 case OPTYPE_STR2BIT
:
9491 case OPTYPE_STR2FLOAT
:
9492 case OPTYPE_STR2HEX
:
9493 case OPTYPE_STR2INT
:
9494 case OPTYPE_STR2OCT
:
9495 case OPTYPE_UNICHAR2INT
:
9496 case OPTYPE_ENUM2INT
:
9497 case OPTYPE_UNICHAR2CHAR
:
9498 case OPTYPE_RNDWITHVAL
:
9499 case OPTYPE_ISCHOSEN_V
:
9500 case OPTYPE_GET_STRINGENCODING
:
9501 case OPTYPE_REMOVE_BOM
:
9502 case OPTYPE_DECODE_BASE64
:
9504 u
.expr
.v1
->chk_recursions(refch
);
9507 case OPTYPE_ISCHOSEN_T
:
9509 u
.expr
.t1
->chk_recursions(refch
);
9512 case OPTYPE_ADD
: // v1 v2
9513 case OPTYPE_SUBTRACT
:
9514 case OPTYPE_MULTIPLY
:
9535 case OPTYPE_INT2BIT
:
9536 case OPTYPE_INT2HEX
:
9537 case OPTYPE_INT2OCT
:
9539 u
.expr
.v1
->chk_recursions(refch
);
9542 u
.expr
.v2
->chk_recursions(refch
);
9545 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9546 case OPTYPE_OCT2UNICHAR
:
9547 case OPTYPE_ENCODE_BASE64
:
9549 u
.expr
.v1
->chk_recursions(refch
);
9553 u
.expr
.v2
->chk_recursions(refch
);
9558 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9559 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9563 u
.expr
.ti1
->chk_recursions(refch
);
9566 u
.expr
.v2
->chk_recursions(refch
);
9569 u
.expr
.v3
->chk_recursions(refch
);
9574 u
.expr
.ti1
->chk_recursions(refch
);
9577 u
.expr
.t2
->chk_recursions(refch
);
9580 u
.expr
.v3
->chk_recursions(refch
);
9583 case OPTYPE_DECOMP
: // v1 v2 v3
9585 u
.expr
.v1
->chk_recursions(refch
);
9588 u
.expr
.v2
->chk_recursions(refch
);
9591 u
.expr
.v3
->chk_recursions(refch
);
9594 case OPTYPE_REPLACE
:
9596 u
.expr
.ti1
->chk_recursions(refch
);
9599 u
.expr
.v2
->chk_recursions(refch
);
9602 u
.expr
.v3
->chk_recursions(refch
);
9605 u
.expr
.ti4
->chk_recursions(refch
);
9608 case OPTYPE_LENGTHOF
: // ti1
9609 case OPTYPE_SIZEOF
: // ti1
9610 case OPTYPE_VALUEOF
: // ti1
9612 case OPTYPE_ISPRESENT
:
9613 case OPTYPE_TTCN2STRING
:
9615 u
.expr
.ti1
->chk_recursions(refch
);
9618 case OPTYPE_MATCH
: // v1 t2
9620 u
.expr
.v1
->chk_recursions(refch
);
9623 u
.expr
.t2
->chk_recursions(refch
);
9626 case OPTYPE_LOG2STR
:
9627 u
.expr
.logargs
->chk_recursions(refch
);
9634 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9635 ReferenceChain
& refch
) {
9636 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9637 Assignment
*ass
= ref
->get_refd_assignment();
9639 set_valuetype(V_ERROR
);
9642 switch (ass
->get_asstype()) {
9643 case Assignment::A_CONST
:
9644 case Assignment::A_EXT_CONST
:
9645 case Assignment::A_MODULEPAR
:
9646 case Assignment::A_VAR
:
9647 case Assignment::A_PAR_VAL_IN
:
9648 case Assignment::A_PAR_VAL_OUT
:
9649 case Assignment::A_PAR_VAL_INOUT
: {
9650 Value
* v
= new Value(V_REFD
, ref
);
9651 v
->set_location(*ref
);
9652 v
->set_my_scope(get_my_scope());
9653 v
->set_fullname(get_fullname()+".<operand>");
9655 v
->chk_recursions(refch
);
9659 case Assignment::A_MODULEPAR_TEMP
:
9660 case Assignment::A_TEMPLATE
:
9661 case Assignment::A_VAR_TEMPLATE
:
9662 case Assignment::A_PAR_TEMPL_IN
:
9663 case Assignment::A_PAR_TEMPL_OUT
:
9664 case Assignment::A_PAR_TEMPL_INOUT
: {
9665 Template
* t
= new Template(ref
->clone());
9666 t
->set_location(*ref
);
9667 t
->set_my_scope(get_my_scope());
9668 t
->set_fullname(get_fullname()+".<operand>");
9670 t
->chk_recursions(refch
);
9675 // remain silent, the error has been already reported
9676 set_valuetype(V_ERROR
);
9681 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9683 bool self_ref
= false;
9684 switch (t
->get_templatetype()) {
9685 case Ttcn::Template::SPECIFIC_VALUE
: {
9686 Value
*v
= t
->get_specific_value();
9687 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9688 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9689 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9691 case Ttcn::Template::TEMPLATE_REFD
: {
9692 Ttcn::Ref_base
*refb
= t
->get_reference();
9693 Common::Assignment
*ass
= refb
->get_refd_assignment();
9694 self_ref
|= (ass
== lhs
);
9696 case Ttcn::Template::ALL_FROM
:
9697 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9698 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9700 case Ttcn::Template::TEMPLATE_LIST
:
9701 case Ttcn::Template::SUPERSET_MATCH
:
9702 case Ttcn::Template::SUBSET_MATCH
:
9703 case Ttcn::Template::PERMUTATION_MATCH
:
9704 case Ttcn::Template::COMPLEMENTED_LIST
:
9705 case Ttcn::Template::VALUE_LIST
: {
9706 size_t num
= t
->get_nof_comps();
9707 for (size_t i
= 0; i
< num
; ++i
) {
9708 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9711 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9712 // case Ttcn::Template::TEMPLATE_LIST: {
9713 // size_t num = t->get_nof_listitems();
9714 // for (size_t i=0; i < num; ++i) {
9715 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9718 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9719 size_t nnt
= t
->get_nof_comps();
9720 for (size_t i
=0; i
< nnt
; ++i
) {
9721 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9722 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9725 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9726 size_t nnt
= t
->get_nof_comps();
9727 for (size_t i
=0; i
< nnt
; ++i
) {
9728 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9729 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9732 case Ttcn::Template::VALUE_RANGE
: {
9733 Ttcn::ValueRange
*vr
= t
->get_value_range();
9734 Common::Value
*v
= vr
->get_min_v();
9735 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9736 v
= vr
->get_max_v();
9737 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9739 case Ttcn::Template::CSTR_PATTERN
:
9740 case Ttcn::Template::USTR_PATTERN
: {
9741 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9742 self_ref
|= ps
->chk_self_ref(lhs
);
9744 case Ttcn::Template::BSTR_PATTERN
:
9745 case Ttcn::Template::HSTR_PATTERN
:
9746 case Ttcn::Template::OSTR_PATTERN
: {
9747 // FIXME: cannot access u.pattern
9749 case Ttcn::Template::ANY_VALUE
:
9750 case Ttcn::Template::ANY_OR_OMIT
:
9751 case Ttcn::Template::OMIT_VALUE
:
9752 case Ttcn::Template::TEMPLATE_NOTUSED
:
9753 break; // self-ref can't happen
9754 case Ttcn::Template::TEMPLATE_INVOKE
:
9755 break; // assume self-ref can't happen
9756 case Ttcn::Template::TEMPLATE_ERROR
:
9757 FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9758 break; // not reached
9760 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9761 // break; // and hope for the best
9766 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
9768 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
9769 namedbool is_str_elem
= NOT_STR_ELEM
;
9770 if (v
->valuetype
== V_REFD
) {
9771 Reference
*ref
= v
->get_reference();
9772 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
9773 if (subrefs
&& subrefs
->refers_to_string_element()) {
9774 is_str_elem
= IS_STR_ELEM
;
9777 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9778 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
9782 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
9784 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
9785 if (!lhs
) FATAL_ERROR("no lhs!");
9786 bool self_ref
= false;
9787 switch (u
.expr
.v_optype
) {
9788 case OPTYPE_RND
: // -
9789 case OPTYPE_TESTCASENAME
: // -
9790 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
9791 case OPTYPE_COMP_MTC
: // -
9792 case OPTYPE_COMP_SYSTEM
: // -
9793 case OPTYPE_COMP_SELF
: // -
9794 case OPTYPE_COMP_RUNNING_ANY
: // -
9795 case OPTYPE_COMP_RUNNING_ALL
: // -
9796 case OPTYPE_COMP_ALIVE_ANY
: // -
9797 case OPTYPE_COMP_ALIVE_ALL
: // -
9798 case OPTYPE_TMR_RUNNING_ANY
: // -
9799 case OPTYPE_GETVERDICT
: // -
9800 break; // nothing to do
9802 case OPTYPE_MATCH
: // v1 t2
9803 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9805 case OPTYPE_UNARYPLUS
: // v1
9806 case OPTYPE_UNARYMINUS
: // v1
9807 case OPTYPE_NOT
: // v1
9808 case OPTYPE_NOT4B
: // v1
9809 case OPTYPE_BIT2HEX
: // v1
9810 case OPTYPE_BIT2INT
: // v1
9811 case OPTYPE_BIT2OCT
: // v1
9812 case OPTYPE_BIT2STR
: // v1
9813 case OPTYPE_CHAR2INT
: // v1
9814 case OPTYPE_CHAR2OCT
: // v1
9815 case OPTYPE_FLOAT2INT
: // v1
9816 case OPTYPE_FLOAT2STR
: // v1
9817 case OPTYPE_HEX2BIT
: // v1
9818 case OPTYPE_HEX2INT
: // v1
9819 case OPTYPE_HEX2OCT
: // v1
9820 case OPTYPE_HEX2STR
: // v1
9821 case OPTYPE_INT2CHAR
: // v1
9822 case OPTYPE_INT2FLOAT
: // v1
9823 case OPTYPE_INT2STR
: // v1
9824 case OPTYPE_INT2UNICHAR
: // v1
9825 case OPTYPE_OCT2BIT
: // v1
9826 case OPTYPE_OCT2CHAR
: // v1
9827 case OPTYPE_OCT2HEX
: // v1
9828 case OPTYPE_OCT2INT
: // v1
9829 case OPTYPE_OCT2STR
: // v1
9830 case OPTYPE_STR2BIT
: // v1
9831 case OPTYPE_STR2FLOAT
: // v1
9832 case OPTYPE_STR2HEX
: // v1
9833 case OPTYPE_STR2INT
: // v1
9834 case OPTYPE_STR2OCT
: // v1
9835 case OPTYPE_UNICHAR2INT
: // v1
9836 case OPTYPE_UNICHAR2CHAR
: // v1
9837 case OPTYPE_ENUM2INT
: // v1
9838 case OPTYPE_RNDWITHVAL
: // v1
9839 case OPTYPE_COMP_RUNNING
: // v1
9840 case OPTYPE_COMP_ALIVE
: // v1
9841 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
9842 case OPTYPE_GET_STRINGENCODING
:
9843 case OPTYPE_DECODE_BASE64
:
9844 case OPTYPE_REMOVE_BOM
:
9845 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9847 case OPTYPE_ADD
: // v1 v2
9848 case OPTYPE_SUBTRACT
: // v1 v2
9849 case OPTYPE_MULTIPLY
: // v1 v2
9850 case OPTYPE_DIVIDE
: // v1 v2
9851 case OPTYPE_MOD
: // v1 v2
9852 case OPTYPE_REM
: // v1 v2
9853 case OPTYPE_CONCAT
: // v1 v2
9854 case OPTYPE_EQ
: // v1 v2
9855 case OPTYPE_LT
: // v1 v2
9856 case OPTYPE_GT
: // v1 v2
9857 case OPTYPE_NE
: // v1 v2
9858 case OPTYPE_GE
: // v1 v2
9859 case OPTYPE_LE
: // v1 v2
9860 case OPTYPE_AND
: // v1 v2
9861 case OPTYPE_OR
: // v1 v2
9862 case OPTYPE_XOR
: // v1 v2
9863 case OPTYPE_AND4B
: // v1 v2
9864 case OPTYPE_OR4B
: // v1 v2
9865 case OPTYPE_XOR4B
: // v1 v2
9866 case OPTYPE_SHL
: // v1 v2
9867 case OPTYPE_SHR
: // v1 v2
9868 case OPTYPE_ROTL
: // v1 v2
9869 case OPTYPE_ROTR
: // v1 v2
9870 case OPTYPE_INT2BIT
: // v1 v2
9871 case OPTYPE_INT2HEX
: // v1 v2
9872 case OPTYPE_INT2OCT
: // v1 v2
9873 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9874 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9876 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9877 case OPTYPE_OCT2UNICHAR
:
9878 case OPTYPE_ENCODE_BASE64
:
9879 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9880 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9882 case OPTYPE_DECOMP
: // v1 v2 v3
9883 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9884 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9885 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9888 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
9889 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
9891 case OPTYPE_SUBSTR
: // ti1 v2 v3
9892 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9893 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
9894 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
9897 case OPTYPE_REGEXP
: // ti1 t2 v3
9898 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9899 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9901 case OPTYPE_LENGTHOF
: // ti1
9902 case OPTYPE_SIZEOF
: // ti1
9903 case OPTYPE_VALUEOF
: // ti1
9904 case OPTYPE_ENCODE
: // ti1
9905 case OPTYPE_TTCN2STRING
:
9906 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9909 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
9910 // component.create -- assume no self-ref
9911 case OPTYPE_ACTIVATE
: // r1
9912 // defaultref := activate(altstep) -- assume no self-ref
9913 case OPTYPE_TMR_RUNNING
: // r1
9914 // boolvar := a_timer.running -- assume no self-ref
9918 case OPTYPE_LOG2STR
: {// logargs
9919 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
9920 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
9921 switch (la
->get_type()) {
9922 case Ttcn::LogArgument::L_UNDEF
:
9923 case Ttcn::LogArgument::L_ERROR
:
9924 FATAL_ERROR("log2str argument type");
9925 break; // not reached
9927 case Ttcn::LogArgument::L_MACRO
:
9928 case Ttcn::LogArgument::L_STR
:
9929 break; // self reference not possible
9931 case Ttcn::LogArgument::L_VAL
:
9932 case Ttcn::LogArgument::L_MATCH
:
9933 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
9936 case Ttcn::LogArgument::L_REF
: {
9937 Ttcn::Ref_base
*ref
= la
->get_ref();
9938 Common::Assignment
*ass
= ref
->get_refd_assignment();
9939 self_ref
|= (ass
== lhs
);
9942 case Ttcn::LogArgument::L_TI
: {
9943 Ttcn::TemplateInstance
*ti
= la
->get_ti();
9944 Ttcn::Template
*t
= ti
->get_Template();
9945 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
9948 // no default please
9949 } // switch la->logargtype
9953 case OPTYPE_DECODE
: { // r1 r2
9954 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
9955 self_ref
|= (ass
== lhs
);
9957 case OPTYPE_EXECUTE
: // r1 [v2]
9959 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9963 case OPTYPE_UNDEF_RUNNING
: // r1
9964 case OPTYPE_TMR_READ
: { // r1
9965 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
9966 self_ref
|= (ass
== lhs
);
9969 case OPTYPE_ISCHOSEN_T
: // t1 i2
9970 case OPTYPE_ISBOUND
: // ti1
9971 case OPTYPE_ISVALUE
: // ti1
9972 case OPTYPE_ISPRESENT
: { // ti1
9974 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
9975 else t
= u
.expr
.ti1
->get_Template();
9976 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
9979 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
9981 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9984 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
9985 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9989 case NUMBER_OF_OPTYPES
: // can never happen
9990 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
9991 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
9993 } // switch u.expr.v_optype
9998 string
Value::create_stringRepr()
10000 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10001 switch (valuetype
) {
10003 return string("<erroneous>");
10005 return string("NULL");
10007 if (!parse_only
&& is_asn1()) {
10008 if (u
.val_bool
) return string("TRUE");
10009 else return string("FALSE");
10012 if (u
.val_bool
) return string("true");
10013 else return string("false");
10016 return u
.val_Int
->t_str();
10018 return Real2string(u
.val_Real
);
10021 case V_UNDEF_LOWERID
:
10022 return u
.val_id
->get_name();
10023 case V_NAMEDBITS
: {
10024 string
ret_val("{ ");
10025 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10026 if (i
>0) ret_val
+= ' ';
10027 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10032 string
ret_val('\'');
10033 ret_val
+= *u
.str
.val_str
;
10037 string
ret_val('\'');
10038 ret_val
+= *u
.str
.val_str
;
10042 string
ret_val('\'');
10043 ret_val
+= *u
.str
.val_str
;
10048 return u
.str
.val_str
->get_stringRepr();
10050 return u
.ustr
.val_ustr
->get_stringRepr();
10052 /** \todo stringrepr of V_CHARSYMS */
10053 return string("<sorry, string representation of charsyms "
10054 "not implemented>");
10058 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10060 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10061 if (i
>0) ret_val
+= ' ';
10062 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10067 if (!parse_only
&& is_asn1()) {
10068 string
ret_val(u
.choice
.alt_name
->get_dispname());
10070 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10074 string
ret_val("{ ");
10075 ret_val
+= u
.choice
.alt_name
->get_dispname();
10077 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10084 string
ret_val("{ ");
10085 if (!is_indexed()) {
10086 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10087 if (i
> 0) ret_val
+= ", ";
10088 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10091 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10092 if (i
> 0) ret_val
+= ", ";
10093 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10100 string
ret_val("{ ");
10101 bool asn1_flag
= !parse_only
&& is_asn1();
10102 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10103 if (i
> 0) ret_val
+= ", ";
10104 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10105 ret_val
+= nv
->get_name().get_dispname();
10106 if (asn1_flag
) ret_val
+= ' ';
10107 else ret_val
+= " := ";
10108 ret_val
+= nv
->get_value()->get_stringRepr();
10113 // do not evaluate the reference if it is not done so far
10114 // (e.g. in parse-only mode)
10115 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10116 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10117 else return t_val
->get_stringRepr(); }
10119 return string("omit");
10121 switch (u
.verdict
) {
10123 return string("none");
10125 return string("pass");
10126 case Verdict_INCONC
:
10127 return string("inconc");
10129 return string("fail");
10130 case Verdict_ERROR
:
10131 return string("error");
10133 return string("<unknown verdict value>");
10135 case V_DEFAULT_NULL
:
10137 return string("null");
10139 switch (u
.expr
.v_optype
) {
10141 return string("rnd()");
10142 case OPTYPE_TESTCASENAME
:
10143 return string("testcasename()");
10144 case OPTYPE_UNARYPLUS
:
10145 return create_stringRepr_unary("+");
10146 case OPTYPE_UNARYMINUS
:
10147 return create_stringRepr_unary("-");
10149 return create_stringRepr_unary("not");
10151 return create_stringRepr_unary("not4b");
10152 case OPTYPE_BIT2HEX
:
10153 return create_stringRepr_predef1("bit2hex");
10154 case OPTYPE_BIT2INT
:
10155 return create_stringRepr_predef1("bit2int");
10156 case OPTYPE_BIT2OCT
:
10157 return create_stringRepr_predef1("bit2oct");
10158 case OPTYPE_BIT2STR
:
10159 return create_stringRepr_predef1("bit2str");
10160 case OPTYPE_CHAR2INT
:
10161 return create_stringRepr_predef1("char2int");
10162 case OPTYPE_CHAR2OCT
:
10163 return create_stringRepr_predef1("char2oct");
10164 case OPTYPE_FLOAT2INT
:
10165 return create_stringRepr_predef1("float2int");
10166 case OPTYPE_FLOAT2STR
:
10167 return create_stringRepr_predef1("float2str");
10168 case OPTYPE_HEX2BIT
:
10169 return create_stringRepr_predef1("hex2bit");
10170 case OPTYPE_HEX2INT
:
10171 return create_stringRepr_predef1("hex2int");
10172 case OPTYPE_HEX2OCT
:
10173 return create_stringRepr_predef1("hex2oct");
10174 case OPTYPE_HEX2STR
:
10175 return create_stringRepr_predef1("hex2str");
10176 case OPTYPE_INT2CHAR
:
10177 return create_stringRepr_predef1("int2char");
10178 case OPTYPE_INT2FLOAT
:
10179 return create_stringRepr_predef1("int2float");
10180 case OPTYPE_INT2STR
:
10181 return create_stringRepr_predef1("int2str");
10182 case OPTYPE_INT2UNICHAR
:
10183 return create_stringRepr_predef1("int2unichar");
10184 case OPTYPE_OCT2BIT
:
10185 return create_stringRepr_predef1("oct2bit");
10186 case OPTYPE_OCT2CHAR
:
10187 return create_stringRepr_predef1("oct2char");
10188 case OPTYPE_OCT2HEX
:
10189 return create_stringRepr_predef1("oct2hex");
10190 case OPTYPE_OCT2INT
:
10191 return create_stringRepr_predef1("oct2int");
10192 case OPTYPE_OCT2STR
:
10193 return create_stringRepr_predef1("oct2str");
10194 case OPTYPE_GET_STRINGENCODING
:
10195 return create_stringRepr_predef1("get_stringencoding");
10196 case OPTYPE_REMOVE_BOM
:
10197 return create_stringRepr_predef1("remove_bom");
10198 case OPTYPE_ENCODE_BASE64
: {
10199 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10200 else return create_stringRepr_predef1("encode_base64");
10202 case OPTYPE_DECODE_BASE64
:
10203 return create_stringRepr_predef1("decode_base64");
10204 case OPTYPE_OCT2UNICHAR
:{
10205 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10206 else return create_stringRepr_predef1("oct2unichar");
10208 case OPTYPE_UNICHAR2OCT
: {
10209 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10210 else return create_stringRepr_predef1("unichar2oct");
10212 case OPTYPE_STR2BIT
:
10213 return create_stringRepr_predef1("str2bit");
10214 case OPTYPE_STR2FLOAT
:
10215 return create_stringRepr_predef1("str2float");
10216 case OPTYPE_STR2HEX
:
10217 return create_stringRepr_predef1("str2hex");
10218 case OPTYPE_STR2INT
:
10219 return create_stringRepr_predef1("str2int");
10220 case OPTYPE_STR2OCT
:
10221 return create_stringRepr_predef1("str2oct");
10222 case OPTYPE_UNICHAR2INT
:
10223 return create_stringRepr_predef1("unichar2int");
10224 case OPTYPE_UNICHAR2CHAR
:
10225 return create_stringRepr_predef1("unichar2char");
10226 case OPTYPE_ENUM2INT
:
10227 return create_stringRepr_predef1("enum2int");
10228 case OPTYPE_ENCODE
:
10229 return create_stringRepr_predef1("encvalue");
10230 case OPTYPE_DECODE
:
10231 return create_stringRepr_predef2("decvalue");
10232 case OPTYPE_RNDWITHVAL
:
10233 return create_stringRepr_predef1("rnd");
10235 return create_stringRepr_infix("+");
10236 case OPTYPE_SUBTRACT
:
10237 return create_stringRepr_infix("-");
10238 case OPTYPE_MULTIPLY
:
10239 return create_stringRepr_infix("*");
10240 case OPTYPE_DIVIDE
:
10241 return create_stringRepr_infix("/");
10243 return create_stringRepr_infix("mod");
10245 return create_stringRepr_infix("rem");
10246 case OPTYPE_CONCAT
:
10247 return create_stringRepr_infix("&");
10249 return create_stringRepr_infix("==");
10251 return create_stringRepr_infix("<");
10253 return create_stringRepr_infix(">");
10255 return create_stringRepr_infix("!=");
10257 return create_stringRepr_infix(">=");
10259 return create_stringRepr_infix("<=");
10261 return create_stringRepr_infix("and");
10263 return create_stringRepr_infix("or");
10265 return create_stringRepr_infix("xor");
10267 return create_stringRepr_infix("and4b");
10269 return create_stringRepr_infix("or4b");
10271 return create_stringRepr_infix("xor4b");
10273 return create_stringRepr_infix("<<");
10275 return create_stringRepr_infix(">>");
10277 return create_stringRepr_infix("<@");
10279 return create_stringRepr_infix("@>");
10280 case OPTYPE_INT2BIT
:
10281 return create_stringRepr_predef2("int2bit");
10282 case OPTYPE_INT2HEX
:
10283 return create_stringRepr_predef2("int2hex");
10284 case OPTYPE_INT2OCT
:
10285 return create_stringRepr_predef2("int2oct");
10286 case OPTYPE_SUBSTR
: {
10287 string
ret_val("substr(");
10288 u
.expr
.ti1
->append_stringRepr(ret_val
);
10290 ret_val
+= u
.expr
.v2
->get_stringRepr();
10292 ret_val
+= u
.expr
.v3
->get_stringRepr();
10296 case OPTYPE_REGEXP
: {
10297 string
ret_val("regexp(");
10298 u
.expr
.ti1
->append_stringRepr(ret_val
);
10300 u
.expr
.t2
->append_stringRepr(ret_val
);
10302 ret_val
+= u
.expr
.v3
->get_stringRepr();
10306 case OPTYPE_DECOMP
: {
10307 string
ret_val("decomp(");
10308 ret_val
+= u
.expr
.v1
->get_stringRepr();
10310 ret_val
+= u
.expr
.v2
->get_stringRepr();
10312 ret_val
+= u
.expr
.v3
->get_stringRepr();
10316 case OPTYPE_REPLACE
: {
10317 string
ret_val("replace(");
10318 u
.expr
.ti1
->append_stringRepr(ret_val
);
10320 ret_val
+= u
.expr
.v2
->get_stringRepr();
10322 ret_val
+= u
.expr
.v3
->get_stringRepr();
10324 u
.expr
.ti4
->append_stringRepr(ret_val
);
10328 case OPTYPE_ISPRESENT
: {
10329 string
ret_val("ispresent(");
10330 u
.expr
.ti1
->append_stringRepr(ret_val
);
10333 case OPTYPE_ISCHOSEN
: {
10334 string
ret_val("ischosen(");
10335 ret_val
+= u
.expr
.r1
->get_dispname();
10337 ret_val
+= u
.expr
.i2
->get_dispname();
10340 case OPTYPE_ISCHOSEN_V
: {
10341 string
ret_val("ischosen(");
10342 ret_val
+= u
.expr
.v1
->get_stringRepr();
10344 ret_val
+= u
.expr
.i2
->get_dispname();
10347 case OPTYPE_ISCHOSEN_T
: {
10348 string
ret_val("ischosen(");
10349 ret_val
+= u
.expr
.t1
->get_stringRepr();
10351 ret_val
+= u
.expr
.i2
->get_dispname();
10354 case OPTYPE_LENGTHOF
: {
10355 string
ret_val("lengthof(");
10356 u
.expr
.ti1
->append_stringRepr(ret_val
);
10359 case OPTYPE_SIZEOF
: {
10360 string
ret_val("sizeof(");
10361 u
.expr
.ti1
->append_stringRepr(ret_val
);
10364 case OPTYPE_ISVALUE
: {
10365 string
ret_val("isvalue(");
10366 u
.expr
.ti1
->append_stringRepr(ret_val
);
10369 case OPTYPE_VALUEOF
: {
10370 string
ret_val("valueof(");
10371 u
.expr
.ti1
->append_stringRepr(ret_val
);
10374 case OPTYPE_LOG2STR
:
10375 return string("log2str(...)");
10376 case OPTYPE_MATCH
: {
10377 string
ret_val("match(");
10378 ret_val
+= u
.expr
.v1
->get_stringRepr();
10380 u
.expr
.t2
->append_stringRepr(ret_val
);
10383 case OPTYPE_TTCN2STRING
: {
10384 string
ret_val("ttcn2string(");
10385 u
.expr
.ti1
->append_stringRepr(ret_val
);
10389 case OPTYPE_UNDEF_RUNNING
:
10390 return u
.expr
.r1
->get_dispname() + ".running";
10391 case OPTYPE_COMP_NULL
:
10392 return string("null");
10393 case OPTYPE_COMP_MTC
:
10394 return string("mtc");
10395 case OPTYPE_COMP_SYSTEM
:
10396 return string("system");
10397 case OPTYPE_COMP_SELF
:
10398 return string("self");
10399 case OPTYPE_COMP_CREATE
: {
10400 string
ret_val(u
.expr
.r1
->get_dispname());
10401 ret_val
+= ".create";
10402 if (u
.expr
.v2
|| u
.expr
.v3
) {
10404 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10405 else ret_val
+= '-';
10408 ret_val
+= u
.expr
.v3
->get_stringRepr();
10412 if (u
.expr
.b4
) ret_val
+= " alive";
10414 case OPTYPE_COMP_RUNNING
:
10415 return u
.expr
.v1
->get_stringRepr() + ".running";
10416 case OPTYPE_COMP_RUNNING_ANY
:
10417 return string("any component.running");
10418 case OPTYPE_COMP_RUNNING_ALL
:
10419 return string("all component.running");
10420 case OPTYPE_COMP_ALIVE
:
10421 return u
.expr
.v1
->get_stringRepr() + ".alive";
10422 case OPTYPE_COMP_ALIVE_ANY
:
10423 return string("any component.alive");
10424 case OPTYPE_COMP_ALIVE_ALL
:
10425 return string("all component.alive");
10426 case OPTYPE_TMR_READ
:
10427 return u
.expr
.r1
->get_dispname() + ".read";
10428 case OPTYPE_TMR_RUNNING
:
10429 return u
.expr
.r1
->get_dispname() + ".running";
10430 case OPTYPE_TMR_RUNNING_ANY
:
10431 return string("any timer.running");
10432 case OPTYPE_GETVERDICT
:
10433 return string("getverdict");
10434 case OPTYPE_ACTIVATE
: {
10435 string
ret_val("activate(");
10436 ret_val
+= u
.expr
.r1
->get_dispname();
10439 case OPTYPE_ACTIVATE_REFD
: {
10440 string
ret_val("activate(derefer(");
10441 ret_val
+= u
.expr
.v1
->get_stringRepr();
10443 if (u
.expr
.state
== EXPR_CHECKED
) {
10444 if (u
.expr
.ap_list2
) {
10445 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10446 for (size_t i
= 0; i
< nof_pars
; i
++) {
10447 if (i
> 0) ret_val
+= ", ";
10448 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10452 if (u
.expr
.t_list2
) {
10453 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10454 for (size_t i
= 0; i
< nof_pars
; i
++) {
10455 if (i
> 0) ret_val
+= ", ";
10456 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10462 case OPTYPE_EXECUTE
: {
10463 string
ret_val("execute(");
10464 ret_val
+= u
.expr
.r1
->get_dispname();
10467 ret_val
+= u
.expr
.v2
->get_stringRepr();
10471 case OPTYPE_EXECUTE_REFD
: {
10472 string
ret_val("execute(derefers(");
10473 ret_val
+= u
.expr
.v1
->get_stringRepr();
10475 if (u
.expr
.state
== EXPR_CHECKED
) {
10476 if (u
.expr
.ap_list2
) {
10477 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10478 for (size_t i
= 0; i
< nof_pars
; i
++) {
10479 if (i
> 0) ret_val
+= ", ";
10480 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10484 if (u
.expr
.t_list2
) {
10485 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10486 for (size_t i
= 0; i
< nof_pars
; i
++) {
10487 if (i
> 0) ret_val
+= ", ";
10488 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10495 ret_val
+= u
.expr
.v3
->get_stringRepr();
10500 return string("<unsupported optype>");
10501 } // switch u.expr.v_optype
10504 case MACRO_MODULEID
:
10505 return string("%moduleId");
10506 case MACRO_FILENAME
:
10507 return string("%fileName");
10508 case MACRO_BFILENAME
:
10509 return string("__BFILE__");
10510 case MACRO_FILEPATH
:
10511 return string("__FILE__");
10512 case MACRO_LINENUMBER
:
10513 return string("%lineNumber");
10514 case MACRO_LINENUMBER_C
:
10515 return string("__LINE__");
10516 case MACRO_DEFINITIONID
:
10517 return string("%definitionId");
10519 return string("__SCOPE__");
10520 case MACRO_TESTCASEID
:
10521 return string("%testcaseId");
10523 return string("<unknown macro>");
10524 } // switch u.macro
10526 return string('-');
10530 string
ret_val("refers(");
10531 ret_val
+= u
.refd_fat
->get_assname();
10536 ret_val
+= u
.invoke
.v
->get_stringRepr();
10537 ret_val
+= ".apply(";
10538 if (u
.invoke
.ap_list
) {
10539 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10540 for (size_t i
= 0; i
< nof_pars
; i
++) {
10541 if (i
> 0) ret_val
+= ", ";
10542 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10544 } else if (u
.invoke
.t_list
) {
10545 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10546 for (size_t i
= 0; i
< nof_pars
; i
++) {
10547 if (i
> 0) ret_val
+= ", ";
10548 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10554 string
ret_val("refers(");
10555 ret_val
+= u
.refered
->get_dispname();
10559 return string("<unsupported valuetype>");
10560 } // switch valuetype
10563 string
Value::create_stringRepr_unary(const char *operator_str
)
10565 string
ret_val(operator_str
);
10567 ret_val
+= u
.expr
.v1
->get_stringRepr();
10572 string
Value::create_stringRepr_infix(const char *operator_str
)
10574 string
ret_val('(');
10575 ret_val
+= u
.expr
.v1
->get_stringRepr();
10577 ret_val
+= operator_str
;
10579 ret_val
+= u
.expr
.v2
->get_stringRepr();
10584 string
Value::create_stringRepr_predef1(const char *function_name
)
10586 string
ret_val(function_name
);
10588 if (u
.expr
.v_optype
== OPTYPE_ENCODE
) { // ti1, not v1
10589 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10591 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10596 string
Value::create_stringRepr_predef2(const char *function_name
)
10598 string
ret_val(function_name
);
10600 ret_val
+= u
.expr
.v1
->get_stringRepr();
10602 ret_val
+= u
.expr
.v2
->get_stringRepr();
10607 bool Value::operator==(Value
& val
)
10609 Value
*left
= get_value_refd_last();
10610 Type
*left_governor
= left
->get_my_governor();
10611 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10612 Value
*right
= val
.get_value_refd_last();
10613 Type
*right_governor
= right
->get_my_governor();
10614 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10615 if (left_governor
&& right_governor
10616 && !left_governor
->is_compatible(right_governor
, NULL
)
10617 && !right_governor
->is_compatible(left_governor
, NULL
))
10618 FATAL_ERROR("Value::operator==");
10620 // Not-A-Value is not equal to anything (NaN analogy:)
10621 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10624 switch (left
->valuetype
) {
10627 case V_DEFAULT_NULL
:
10630 return left
->valuetype
== right
->valuetype
;
10632 return right
->valuetype
== V_BOOL
&&
10633 left
->get_val_bool() == right
->get_val_bool();
10635 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10636 == *right
->get_val_Int();
10638 return right
->valuetype
== V_REAL
&&
10639 left
->get_val_Real() == right
->get_val_Real();
10641 switch (right
->valuetype
) {
10643 return left
->get_val_str() == right
->get_val_str();
10645 return right
->get_val_ustr() == left
->get_val_str();
10647 return right
->get_val_iso2022str() == left
->get_val_str();
10654 return left
->valuetype
== right
->valuetype
&&
10655 left
->get_val_str() == right
->get_val_str();
10657 switch (right
->valuetype
) {
10659 return left
->get_val_ustr() == right
->get_val_str();
10661 return left
->get_val_ustr() == right
->get_val_ustr();
10663 return left
->get_val_ustr() == right
->get_val_iso2022str();
10668 switch (right
->valuetype
) {
10670 return left
->get_val_iso2022str() == right
->get_val_str();
10672 // The appropriate operator==() is missing. The operands are swapped,
10673 // but it shouldn't be a problem.
10674 return right
->get_val_ustr() == left
->get_val_iso2022str();
10676 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10681 return right
->valuetype
== V_ENUM
&&
10682 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10685 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10686 vector
<string
> act
, other
;
10687 get_oid_comps(act
);
10688 val
.get_oid_comps(other
);
10689 size_t act_size
= act
.size(), other_size
= other
.size();
10691 if (act_size
== other_size
) {
10693 for (size_t i
= 0; i
< act_size
; i
++)
10694 if (*act
[i
] != *other
[i
]) {
10698 } else ret_val
= false;
10699 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10701 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10704 } else return false;
10706 return right
->valuetype
== V_CHOICE
&&
10707 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10708 *(left
->get_alt_value()) == *(right
->get_alt_value());
10711 if (!left_governor
) FATAL_ERROR("Value::operator==");
10712 if (left
->valuetype
!= right
->valuetype
) return false;
10713 size_t nof_comps
= left_governor
->get_nof_comps();
10714 for (size_t i
= 0; i
< nof_comps
; i
++) {
10715 Value
*lval
= NULL
, *rval
= NULL
;
10716 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10717 const Identifier
& field_name
= cfl
->get_name();
10718 if (left
->has_comp_withName(field_name
)) {
10719 lval
= left
->get_comp_value_byName(field_name
);
10720 if (right
->has_comp_withName(field_name
)) {
10721 rval
= right
->get_comp_value_byName(field_name
);
10722 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10723 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10725 else if (!(*lval
== *rval
))
10728 if (cfl
->has_default()) {
10729 if (!(*lval
== *cfl
->get_defval()))
10732 if (lval
->valuetype
!= V_OMIT
)
10737 if(right
->has_comp_withName(field_name
)) {
10738 rval
= right
->get_comp_value_byName(field_name
);
10739 if(cfl
->has_default()) {
10740 if(rval
->valuetype
==V_OMIT
) return false;
10742 lval
= cfl
->get_defval();
10743 if (!(*lval
==*rval
)) return false;
10752 if (left
->valuetype
!= right
->valuetype
) return false;
10753 size_t ncomps
= get_nof_comps();
10754 if (ncomps
!= right
->get_nof_comps()) return false;
10756 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
10757 bool found
= false;
10758 map
<IndexedValue
*, void> uncovered
;
10759 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
10760 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
10762 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
10764 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
10765 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
10766 *(right
->get_comp_byIndex(i
)) &&
10767 *(uncovered
.get_nth_key(j
)->get_index()) ==
10768 *(right
->get_index_byIndex(i
))) {
10770 uncovered
.erase(uncovered
.get_nth_key(j
));
10778 } else if (left
->is_indexed() || right
->is_indexed()) {
10779 Value
* indexed_one
= 0;
10780 Value
* not_indexed_one
= 0;
10782 if(left
->is_indexed()) { // left is indexed, right is not
10783 indexed_one
= left
;
10784 not_indexed_one
= right
;
10785 } else { // right indexed, left is not
10786 indexed_one
= right
;
10787 not_indexed_one
= left
;
10790 for(size_t i
= 0; i
< ncomps
; ++i
) {
10791 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
10792 if(!(ind
->valuetype
== V_INT
&&
10793 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
10794 *(indexed_one
->get_comp_byIndex(i
))))
10798 } else { // none of them is indexed
10799 for (size_t i
= 0; i
< ncomps
; i
++) {
10800 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
10807 if (right
->valuetype
!= V_SETOF
) return false;
10808 size_t ncomps
= get_nof_comps();
10809 if (ncomps
!= right
->get_nof_comps()) return false;
10810 if (ncomps
== 0) return true;
10811 map
<size_t, void> uncovered
;
10812 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
10813 for (size_t i
= 0; i
< ncomps
; i
++) {
10814 Value
*left_item
= left
->get_comp_byIndex(i
);
10815 bool pair_found
= false;
10816 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
10817 size_t right_index
= uncovered
.get_nth_key(j
);
10818 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
10819 uncovered
.erase(right_index
);
10831 return right
->valuetype
== V_VERDICT
&&
10832 left
->get_val_verdict() == right
->get_val_verdict();
10836 return left
->valuetype
== right
->valuetype
&&
10837 left
->get_refd_assignment() == right
->get_refd_assignment();
10839 FATAL_ERROR("Value::operator==");
10844 bool Value::operator<(Value
& val
)
10846 Value
*left
= get_value_refd_last();
10847 Type
*left_governor
= left
->get_my_governor();
10848 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
10849 Value
*right
= val
.get_value_refd_last();
10850 Type
*right_governor
= right
->get_my_governor();
10851 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
10852 if (left
->get_valuetype() != right
->get_valuetype())
10853 FATAL_ERROR("Value::operator<");
10856 return *left
->get_val_Int() < *right
->get_val_Int();
10858 return (left
->get_val_Real() < right
->get_val_Real());
10860 if(!left_governor
|| !right_governor
)
10861 FATAL_ERROR("Value::operator<");
10862 if(left_governor
!=right_governor
)
10863 FATAL_ERROR("Value::operator<");
10864 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
10865 right_governor
->get_enum_val_byId(*right
->get_val_id()));
10867 FATAL_ERROR("Value::operator<");
10872 bool Value::is_string_type(Type::expected_value_t exp_val
)
10874 switch (get_expr_returntype(exp_val
)) {
10886 void Value::generate_code_expr(expression_struct
*expr
)
10888 if (has_single_expr()) {
10889 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
10891 switch (valuetype
) {
10893 generate_code_expr_expr(expr
);
10901 const string
& tmp_id
= get_temporary_id();
10902 const char *tmp_id_str
= tmp_id
.c_str();
10903 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
10904 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
10905 set_genname_recursive(tmp_id
);
10906 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10907 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10910 const string
& tmp_id
= get_temporary_id();
10911 const char *tmp_id_str
= tmp_id
.c_str();
10912 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
10914 set_genname_recursive(tmp_id
);
10915 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10916 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10919 if (!get_needs_conversion()) {
10920 u
.ref
.ref
->generate_code_const_ref(expr
);
10922 Type
*my_gov
= get_expr_governor_last();
10923 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
10924 ->get_field_type(u
.ref
.ref
->get_subrefs(),
10925 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
10926 // Make sure that nothing goes wrong.
10927 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
10928 FATAL_ERROR("Value::generate_code_expr()");
10929 expression_struct expr_tmp
;
10930 Code::init_expr(&expr_tmp
);
10931 const string
& tmp_id1
= get_temporary_id();
10932 const char *tmp_id_str1
= tmp_id1
.c_str();
10933 const string
& tmp_id2
= get_temporary_id();
10934 const char *tmp_id_str2
= tmp_id2
.c_str();
10935 expr
->preamble
= mputprintf(expr
->preamble
,
10936 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
10938 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
10939 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
10940 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
10941 expr
->preamble
= mputprintf(expr
->preamble
,
10943 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10944 "and `%s' are not compatible at run-time\");\n",
10945 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
10946 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
10947 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
10948 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
10949 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
10953 generate_code_expr_invoke(expr
);
10956 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
10961 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
10963 generate_code_expr(expr
);
10964 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
10965 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
10968 bool Value::can_use_increment(Reference
*ref
) const
10970 if (valuetype
!= V_EXPR
) {
10973 switch (u
.expr
.v_optype
) {
10975 case OPTYPE_SUBTRACT
:
10980 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
10981 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
10982 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
10983 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
10984 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
10985 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
10991 char *Value::generate_code_init(char *str
, const char *name
)
10993 if (get_code_generated()) return str
;
10995 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
10997 switch (valuetype
) {
11011 case V_DEFAULT_NULL
:
11016 // These values have a single string equivalent.
11017 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11020 if (u
.val_Int
->is_native_fit())
11021 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11023 // It's always an INTEGER.
11024 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11025 "}\n", get_single_expr().c_str(), name
);
11029 expression_struct expr
;
11030 Code::init_expr(&expr
);
11031 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11032 generate_code_expr(&expr
);
11033 str
= Code::merge_free_expr(str
, &expr
);
11036 str
= generate_code_init_choice(str
, name
);
11040 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11041 else str
= generate_code_init_indexed(str
, name
);
11044 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11045 else str
= generate_code_init_indexed(str
, name
);
11049 str
= generate_code_init_se(str
, name
);
11052 str
= generate_code_init_refd(str
, name
);
11056 case MACRO_TESTCASEID
:
11057 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11060 // all others must already be evaluated away
11061 FATAL_ERROR("Value::generate_code_init()");
11065 FATAL_ERROR("Value::generate_code_init()");
11068 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11070 set_code_generated();
11074 char *Value::rearrange_init_code(char *str
)
11076 switch (valuetype
) {
11078 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11080 str
= parlist
->rearrange_init_code(str
,
11081 u
.ref
.ref
->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()
11082 == my_scope
->get_scope_mod_gen());
11086 str
= u
.invoke
.v
->rearrange_init_code(str
);
11087 bool type_is_local
= u
.invoke
.v
->get_expr_governor_last()->get_my_scope()
11088 ->get_scope_mod_gen() == my_scope
->get_scope_mod_gen();
11089 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, type_is_local
);
11092 switch (u
.expr
.v_optype
) {
11093 case OPTYPE_UNARYPLUS
:
11094 case OPTYPE_UNARYMINUS
:
11097 case OPTYPE_BIT2HEX
:
11098 case OPTYPE_BIT2INT
:
11099 case OPTYPE_BIT2OCT
:
11100 case OPTYPE_BIT2STR
:
11101 case OPTYPE_CHAR2INT
:
11102 case OPTYPE_CHAR2OCT
:
11103 case OPTYPE_FLOAT2INT
:
11104 case OPTYPE_FLOAT2STR
:
11105 case OPTYPE_HEX2BIT
:
11106 case OPTYPE_HEX2INT
:
11107 case OPTYPE_HEX2OCT
:
11108 case OPTYPE_HEX2STR
:
11109 case OPTYPE_INT2CHAR
:
11110 case OPTYPE_INT2FLOAT
:
11111 case OPTYPE_INT2STR
:
11112 case OPTYPE_INT2UNICHAR
:
11113 case OPTYPE_OCT2BIT
:
11114 case OPTYPE_OCT2CHAR
:
11115 case OPTYPE_OCT2HEX
:
11116 case OPTYPE_OCT2INT
:
11117 case OPTYPE_OCT2STR
:
11118 case OPTYPE_STR2BIT
:
11119 case OPTYPE_STR2FLOAT
:
11120 case OPTYPE_STR2HEX
:
11121 case OPTYPE_STR2INT
:
11122 case OPTYPE_STR2OCT
:
11123 case OPTYPE_UNICHAR2INT
:
11124 case OPTYPE_UNICHAR2CHAR
:
11125 case OPTYPE_ENUM2INT
:
11126 case OPTYPE_ISCHOSEN_V
:
11127 case OPTYPE_GET_STRINGENCODING
:
11128 case OPTYPE_REMOVE_BOM
:
11129 case OPTYPE_DECODE_BASE64
:
11130 str
= u
.expr
.v1
->rearrange_init_code(str
);
11132 case OPTYPE_DECODE
: {
11133 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11134 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11135 bool rearrange
= (ass
->get_my_scope()->get_scope_mod_gen() ==
11136 my_scope
->get_scope_mod_gen());
11137 if (parlist
) str
= parlist
->rearrange_init_code(str
, rearrange
);
11139 parlist
= u
.expr
.r2
->get_parlist();
11140 ass
= u
.expr
.r2
->get_refd_assignment();
11141 rearrange
= (ass
->get_my_scope()->get_scope_mod_gen() ==
11142 my_scope
->get_scope_mod_gen());
11143 if (parlist
) str
= parlist
->rearrange_init_code(str
, rearrange
);
11146 case OPTYPE_SUBTRACT
:
11147 case OPTYPE_MULTIPLY
:
11148 case OPTYPE_DIVIDE
:
11151 case OPTYPE_CONCAT
:
11168 case OPTYPE_INT2BIT
:
11169 case OPTYPE_INT2HEX
:
11170 case OPTYPE_INT2OCT
:
11171 //case OPTYPE_DECODE:
11172 str
= u
.expr
.v1
->rearrange_init_code(str
);
11173 str
= u
.expr
.v2
->rearrange_init_code(str
);
11175 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11176 case OPTYPE_OCT2UNICHAR
:
11177 case OPTYPE_ENCODE_BASE64
:
11178 str
= u
.expr
.v1
->rearrange_init_code(str
);
11179 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
);
11181 case OPTYPE_SUBSTR
:
11182 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11183 str
= u
.expr
.v2
->rearrange_init_code(str
);
11184 str
= u
.expr
.v3
->rearrange_init_code(str
);
11186 case OPTYPE_REGEXP
:
11187 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11188 str
= u
.expr
.t2
->rearrange_init_code(str
);
11189 str
= u
.expr
.v3
->rearrange_init_code(str
);
11191 case OPTYPE_DECOMP
:
11192 str
= u
.expr
.v1
->rearrange_init_code(str
);
11193 str
= u
.expr
.v2
->rearrange_init_code(str
);
11194 str
= u
.expr
.v3
->rearrange_init_code(str
);
11196 case OPTYPE_REPLACE
:
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
);
11200 str
= u
.expr
.ti4
->rearrange_init_code(str
);
11202 case OPTYPE_LENGTHOF
:
11203 case OPTYPE_SIZEOF
:
11204 case OPTYPE_VALUEOF
:
11205 case OPTYPE_ENCODE
:
11206 case OPTYPE_ISPRESENT
:
11207 case OPTYPE_TTCN2STRING
:
11208 str
= u
.expr
.ti1
->rearrange_init_code(str
);
11210 case OPTYPE_ISCHOSEN_T
:
11211 str
= u
.expr
.t1
->rearrange_init_code(str
);
11214 str
= u
.expr
.v1
->rearrange_init_code(str
);
11215 str
= u
.expr
.t2
->rearrange_init_code(str
);
11218 // other kinds of expressions cannot appear within templates
11228 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11229 size_t& blockcount
)
11231 char *s2
= memptystr();
11232 char *s1
= generate_code_tmp(NULL
, s2
);
11234 if (blockcount
== 0) {
11235 str
= mputstr(str
, "{\n");
11238 str
= mputstr(str
, s2
);
11241 str
=mputstr(str
, prefix
);
11242 str
=mputstr(str
, s1
);
11247 char *Value::generate_code_tmp(char *str
, char*& init
)
11249 expression_struct expr
;
11250 Code::init_expr(&expr
);
11251 generate_code_expr_mandatory(&expr
);
11252 if (expr
.preamble
|| expr
.postamble
) {
11253 if (valuetype
== V_EXPR
&&
11254 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11255 // a temporary variable is already introduced
11256 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11257 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11258 str
= mputstr(str
, expr
.expr
);
11260 const string
& tmp_id
= get_temporary_id();
11261 const char *tmp_id_str
= tmp_id
.c_str();
11262 init
= mputprintf(init
, "%s %s;\n"
11264 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11265 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11267 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11268 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11269 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11270 init
= mputstr(init
, "}\n");
11271 str
= mputstr(str
, tmp_id_str
);
11273 } else str
= mputstr(str
, expr
.expr
);
11274 Code::free_expr(&expr
);
11278 void Value::generate_code_log(expression_struct
*expr
)
11280 if (explicit_cast_needed()) {
11281 char *expr_backup
= expr
->expr
;
11283 generate_code_expr(expr
);
11284 const string
& tmp_id
= get_temporary_id();
11285 const char *tmp_id_str
= tmp_id
.c_str();
11286 // We have to create a temporary object, because the parser of GCC
11287 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11288 // constructor call that is, this does not work: type(...).log(); but
11289 // this works: type tmp(...); tmp.log();.
11290 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11291 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11294 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11296 generate_code_expr(expr
);
11298 expr
->expr
= mputstr(expr
->expr
, ".log()");
11301 void Value::generate_code_log_match(expression_struct
*expr
)
11303 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11304 FATAL_ERROR("Value::generate_code_log_match()");
11305 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11306 // compliance the whole code-generation should be checked. Standalone
11307 // constructs like: "A(a[0].f());" should be avoided. The current
11308 // solution for HK38721 uses an additional assignment to overcome the
11309 // issue. The generated code will be slower, but it's needed for old GCC
11310 // versions in specific circumstances.
11311 if (u
.expr
.t2
->needs_temp_ref()) {
11312 char *expr_backup
= expr
->expr
;
11314 u
.expr
.t2
->generate_code(expr
);
11315 const string
& tmp_id
= get_temporary_id();
11316 const char *tmp_id_str
= tmp_id
.c_str();
11317 expr
->preamble
= mputprintf(expr
->preamble
,
11318 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11319 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11321 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11323 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11324 // some reason "(A(NS::B)).a(C);" compiles fine.
11325 expr
->expr
= mputc(expr
->expr
, '(');
11326 u
.expr
.t2
->generate_code(expr
);
11327 expr
->expr
= mputc(expr
->expr
, ')');
11329 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11330 u
.expr
.v1
->generate_code_expr(expr
);
11331 expr
->expr
= mputc(expr
->expr
, ')');
11334 void Value::generate_code_expr_expr(expression_struct
*expr
)
11336 switch (u
.expr
.v_optype
) {
11338 generate_code_expr_rnd(expr
, 0);
11340 case OPTYPE_UNARYPLUS
:
11341 // same as without the '+' operator
11342 u
.expr
.v1
->generate_code_expr(expr
);
11344 case OPTYPE_UNARYMINUS
:
11345 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11348 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11351 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11353 case OPTYPE_BIT2HEX
:
11354 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11356 case OPTYPE_BIT2INT
:
11357 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11359 case OPTYPE_BIT2OCT
:
11360 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11362 case OPTYPE_BIT2STR
:
11363 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11365 case OPTYPE_CHAR2INT
:
11366 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11368 case OPTYPE_CHAR2OCT
:
11369 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11371 case OPTYPE_FLOAT2INT
:
11372 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11374 case OPTYPE_FLOAT2STR
:
11375 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11377 case OPTYPE_HEX2BIT
:
11378 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11380 case OPTYPE_HEX2INT
:
11381 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11383 case OPTYPE_HEX2OCT
:
11384 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11386 case OPTYPE_HEX2STR
:
11387 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11389 case OPTYPE_INT2CHAR
:
11390 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11392 case OPTYPE_INT2FLOAT
:
11393 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11395 case OPTYPE_INT2STR
:
11396 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11398 case OPTYPE_INT2UNICHAR
:
11399 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11401 case OPTYPE_OCT2BIT
:
11402 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11404 case OPTYPE_OCT2CHAR
:
11405 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11407 case OPTYPE_GET_STRINGENCODING
:
11408 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11410 case OPTYPE_REMOVE_BOM
:
11411 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11413 case OPTYPE_ENCODE_BASE64
:
11415 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11417 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11419 case OPTYPE_DECODE_BASE64
:
11420 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11422 case OPTYPE_OCT2UNICHAR
:
11424 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11426 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11428 case OPTYPE_UNICHAR2OCT
:
11430 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11432 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11434 case OPTYPE_OCT2HEX
:
11435 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11437 case OPTYPE_OCT2INT
:
11438 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11440 case OPTYPE_OCT2STR
:
11441 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11443 case OPTYPE_STR2BIT
:
11444 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11446 case OPTYPE_STR2FLOAT
:
11447 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11449 case OPTYPE_STR2HEX
:
11450 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11452 case OPTYPE_STR2INT
:
11453 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11455 case OPTYPE_STR2OCT
:
11456 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11458 case OPTYPE_UNICHAR2INT
:
11459 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11461 case OPTYPE_UNICHAR2CHAR
:
11462 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11464 case OPTYPE_ENUM2INT
: {
11465 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11466 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11467 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11468 enum_type
->get_genname_value(my_scope
).c_str());
11469 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11470 expr
->expr
= mputc(expr
->expr
, ')');
11472 case OPTYPE_ENCODE
:
11473 generate_code_expr_encode(expr
);
11475 case OPTYPE_DECODE
:
11476 generate_code_expr_decode(expr
);
11478 case OPTYPE_RNDWITHVAL
:
11479 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11482 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11484 case OPTYPE_SUBTRACT
:
11485 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11487 case OPTYPE_MULTIPLY
:
11488 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11490 case OPTYPE_DIVIDE
:
11491 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11494 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11497 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11499 case OPTYPE_CONCAT
:
11500 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11503 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11506 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11509 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11512 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
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
, false);
11522 generate_code_expr_and_or(expr
);
11525 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11528 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11531 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11534 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11537 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
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);
11548 case OPTYPE_INT2BIT
:
11549 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11551 case OPTYPE_INT2HEX
:
11552 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11554 case OPTYPE_INT2OCT
:
11555 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11557 case OPTYPE_SUBSTR
:
11558 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11559 else generate_code_expr_substr_replace_compat(expr
);
11561 case OPTYPE_REGEXP
:
11562 generate_code_expr_regexp(expr
);
11564 case OPTYPE_DECOMP
:
11565 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11567 case OPTYPE_REPLACE
:
11568 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11569 else generate_code_expr_substr_replace_compat(expr
);
11571 case OPTYPE_ISCHOSEN
: // r1 i2
11572 FATAL_ERROR("Value::generate_code_expr_expr()");
11574 case OPTYPE_ISCHOSEN_V
: // v1 i2
11575 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11576 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11577 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11578 u
.expr
.i2
->get_name().c_str());
11580 case OPTYPE_ISCHOSEN_T
: // t1 i2
11581 u
.expr
.t1
->generate_code_expr(expr
);
11582 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11583 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11584 u
.expr
.i2
->get_name().c_str());
11586 case OPTYPE_ISPRESENT
:
11587 case OPTYPE_ISBOUND
: {
11588 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11589 ->get_templatetype();
11590 if (temp
== Template::SPECIFIC_VALUE
) {
11591 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11592 ->get_specific_value();
11593 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11594 Ttcn::Reference
* reference
=
11595 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11597 reference
->generate_code_ispresentbound(expr
, false,
11598 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11602 } else if (temp
== Template::TEMPLATE_REFD
){
11603 Ttcn::Reference
* reference
=
11604 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11605 ->get_reference());
11607 reference
->generate_code_ispresentbound(expr
, true,
11608 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11614 case OPTYPE_LENGTHOF
: // ti1
11615 // fall through, separated later
11616 case OPTYPE_SIZEOF
: // ti1
11617 // fall through, separated later
11618 case OPTYPE_ISVALUE
: { // ti1
11619 if (u
.expr
.ti1
->is_only_specific_value()) {
11620 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11621 bool cast_needed
= t_val
->explicit_cast_needed(
11622 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11624 // the ambiguous C++ expression is converted to the value class
11625 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11626 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11629 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11630 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11631 t_val
->generate_code_expr(expr
);
11633 t_val
->generate_code_expr_mandatory(expr
);
11636 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11638 else u
.expr
.ti1
->generate_code(expr
);
11640 switch (u
.expr
.v_optype
) {
11641 case OPTYPE_ISBOUND
:
11642 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11644 case OPTYPE_ISPRESENT
:
11645 expr
->expr
=mputstr(expr
->expr
, ".is_present()");
11647 case OPTYPE_SIZEOF
:
11648 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11650 case OPTYPE_LENGTHOF
:
11651 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11653 case OPTYPE_ISVALUE
:
11654 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11657 FATAL_ERROR("Value::generate_code_expr_expr()");
11660 case OPTYPE_VALUEOF
: // ti1
11661 u
.expr
.ti1
->generate_code(expr
);
11662 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11664 case OPTYPE_MATCH
: // v1 t2
11665 u
.expr
.t2
->generate_code(expr
);
11666 expr
->expr
= mputstr(expr
->expr
, ".match(");
11667 u
.expr
.v1
->generate_code_expr(expr
);
11668 expr
->expr
= mputc(expr
->expr
, ')');
11670 case OPTYPE_UNDEF_RUNNING
:
11671 // it is resolved during semantic check
11672 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11674 case OPTYPE_COMP_NULL
: // -
11675 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11677 case OPTYPE_COMP_MTC
: // -
11678 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11680 case OPTYPE_COMP_SYSTEM
: // -
11681 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11683 case OPTYPE_COMP_SELF
: // -
11684 expr
->expr
=mputstr(expr
->expr
, "self");
11686 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11687 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11690 case OPTYPE_COMP_RUNNING
: // v1
11691 u
.expr
.v1
->generate_code_expr(expr
);
11692 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11693 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11694 expr
->expr
= mputstr(expr
->expr
, ".running()");
11696 case OPTYPE_COMP_RUNNING_ANY
: // -
11697 expr
->expr
=mputstr(expr
->expr
,
11698 "TTCN_Runtime::component_running(ANY_COMPREF)");
11700 case OPTYPE_COMP_RUNNING_ALL
: // -
11701 expr
->expr
=mputstr(expr
->expr
,
11702 "TTCN_Runtime::component_running(ALL_COMPREF)");
11704 case OPTYPE_COMP_ALIVE
: // v1
11705 u
.expr
.v1
->generate_code_expr(expr
);
11706 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11707 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11708 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11710 case OPTYPE_COMP_ALIVE_ANY
: // -
11711 expr
->expr
= mputstr(expr
->expr
,
11712 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11714 case OPTYPE_COMP_ALIVE_ALL
: // -
11715 expr
->expr
= mputstr(expr
->expr
,
11716 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11718 case OPTYPE_TMR_READ
: // r1
11719 u
.expr
.r1
->generate_code(expr
);
11720 expr
->expr
= mputstr(expr
->expr
, ".read()");
11722 case OPTYPE_TMR_RUNNING
: // r1
11723 u
.expr
.r1
->generate_code(expr
);
11724 expr
->expr
= mputstr(expr
->expr
, ".running()");
11726 case OPTYPE_TMR_RUNNING_ANY
: // -
11727 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
11729 case OPTYPE_GETVERDICT
: // -
11730 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
11732 case OPTYPE_TESTCASENAME
: // -
11733 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
11735 case OPTYPE_ACTIVATE
: // r1
11736 generate_code_expr_activate(expr
);
11738 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
11739 generate_code_expr_activate_refd(expr
);
11741 case OPTYPE_EXECUTE
: // r1 [v2]
11742 generate_code_expr_execute(expr
);
11744 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
11745 generate_code_expr_execute_refd(expr
);
11747 case OPTYPE_LOG2STR
:
11748 u
.expr
.logargs
->generate_code_expr(expr
);
11750 case OPTYPE_TTCN2STRING
: {
11751 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
11752 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
11753 param_governor
= param_governor
->get_type_refd_last();
11754 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
11755 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
11756 u
.expr
.ti1
->get_Template()->is_Value()) {
11757 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
11760 bool cast_needed
= v
->explicit_cast_needed();
11762 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
11764 v
->generate_code_expr(expr
);
11766 expr
->expr
= mputstr(expr
->expr
, ")");
11770 u
.expr
.ti1
->generate_code(expr
);
11772 expr
->expr
= mputstr(expr
->expr
, ")");
11775 FATAL_ERROR("Value::generate_code_expr_expr()");
11779 void Value::generate_code_expr_unary(expression_struct
*expr
,
11780 const char *operator_str
, Value
*v1
)
11782 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
11783 v1
->generate_code_expr_mandatory(expr
);
11784 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
11787 void Value::generate_code_expr_infix(expression_struct
*expr
,
11788 const char *operator_str
, Value
*v1
,
11789 Value
*v2
, bool optional_allowed
)
11791 if (!get_needs_conversion()) {
11792 expr
->expr
= mputc(expr
->expr
, '(');
11793 if (optional_allowed
) v1
->generate_code_expr(expr
);
11794 else v1
->generate_code_expr_mandatory(expr
);
11795 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
11796 if (optional_allowed
) v2
->generate_code_expr(expr
);
11797 else v2
->generate_code_expr_mandatory(expr
);
11798 expr
->expr
= mputc(expr
->expr
, ')');
11799 } else { // Temporary variable for the converted value.
11800 const string
& tmp_id1
= get_temporary_id();
11801 const char *tmp_id_str1
= tmp_id1
.c_str();
11802 expression_struct expr_tmp
;
11803 Code::init_expr(&expr_tmp
);
11804 switch (u
.expr
.v_optype
) {
11807 // Always "v1 -> v2".
11808 Type
*t1
= v1
->get_expr_governor_last();
11809 Type
*t2
= v2
->get_expr_governor_last();
11810 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
11811 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11812 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11813 if (expr_tmp
.preamble
)
11814 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11815 expr
->preamble
= mputprintf(expr
->preamble
,
11817 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11818 "and `%s' are not compatible at run-time\");\n",
11819 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
11820 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
11821 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
11822 t2
->get_typename().c_str(), t1
->get_typename().c_str());
11823 Code::free_expr(&expr_tmp
);
11824 if (optional_allowed
) v1
->generate_code_expr(expr
);
11825 else v1
->generate_code_expr_mandatory(expr
);
11826 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
11829 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11830 // functions. The governors of all operands must exist at this point.
11833 case OPTYPE_CONCAT
: {
11834 const string
& tmp_id2
= get_temporary_id();
11835 const char *tmp_id_str2
= tmp_id2
.c_str();
11836 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
11837 Type
*my_gov
= my_governor
->get_type_refd_last();
11838 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
11839 ->get_type_refd_last();
11840 if (!t1_gov
|| my_gov
== t1_gov
)
11841 FATAL_ERROR("Value::generate_code_expr_infix()");
11842 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11843 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
11844 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11845 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
11846 else v1
->generate_code_expr_mandatory(&expr_tmp
);
11847 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
11848 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11849 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11850 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11851 expr
->preamble
= mputprintf(expr
->preamble
,
11853 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11854 "and `%s' are not compatible at run-time\");\n",
11855 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11856 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
11857 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
11858 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
11859 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11862 FATAL_ERROR("Value::generate_code_expr_infix()");
11868 void Value::generate_code_expr_and_or(expression_struct
*expr
)
11870 if (u
.expr
.v2
->needs_short_circuit()) {
11871 // introduce a temporary variable to store the result of the operation
11872 const string
& tmp_id
= get_temporary_id();
11873 const char *tmp_id_str
= tmp_id
.c_str();
11874 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
11875 expression_struct expr2
;
11876 // the left operand must be evaluated anyway
11877 Code::init_expr(&expr2
);
11878 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11879 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
11880 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11881 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
11882 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
11883 // evaluate the right operand only when necessary
11884 // in this case the final result will be the right operand
11885 Code::init_expr(&expr2
);
11886 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11887 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
11888 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11889 // the result is now in the temporary variable
11890 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11892 // use the overloaded operator to get better error messages
11893 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
11894 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
11898 void Value::generate_code_expr_predef1(expression_struct
*expr
,
11899 const char *function_name
,
11902 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11903 v1
->generate_code_expr_mandatory(expr
);
11904 expr
->expr
= mputc(expr
->expr
, ')');
11907 void Value::generate_code_expr_predef2(expression_struct
*expr
,
11908 const char *function_name
,
11909 Value
*v1
, Value
*v2
)
11911 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11912 v1
->generate_code_expr_mandatory(expr
);
11913 expr
->expr
= mputstr(expr
->expr
, ", ");
11914 v2
->generate_code_expr_mandatory(expr
);
11915 expr
->expr
= mputc(expr
->expr
, ')');
11918 void Value::generate_code_expr_predef3(expression_struct
*expr
,
11919 const char *function_name
,
11920 Value
*v1
, Value
*v2
, Value
*v3
)
11922 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11923 v1
->generate_code_expr_mandatory(expr
);
11924 expr
->expr
= mputstr(expr
->expr
, ", ");
11925 v2
->generate_code_expr_mandatory(expr
);
11926 expr
->expr
= mputstr(expr
->expr
, ", ");
11927 v3
->generate_code_expr_mandatory(expr
);
11928 expr
->expr
= mputc(expr
->expr
, ')');
11931 void Value::generate_code_expr_substr(expression_struct
*expr
)
11934 Value
* v1
= u
.expr
.ti1
->get_specific_value();
11935 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11936 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11937 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
11938 if (v1
) v1
->generate_code_expr_mandatory(expr
);
11939 else u
.expr
.ti1
->generate_code(expr
);
11940 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
11941 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
11942 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
11943 expr
->expr
= mputstr(expr
->expr
, "(int)");
11944 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
11945 expr
->expr
= mputstr(expr
->expr
, ", ");
11946 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
11947 expr
->expr
= mputstr(expr
->expr
, "(int)");
11948 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
11949 expr
->expr
= mputc(expr
->expr
, ')');
11952 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
11954 expression_struct expr_tmp
;
11955 Code::init_expr(&expr_tmp
);
11956 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11957 ->get_type_refd_last();
11958 if (!t1
|| t1
== my_governor
->get_type_refd_last())
11959 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11960 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
11961 generate_code_expr_substr(&expr_tmp
);
11962 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
11963 generate_code_expr_replace(&expr_tmp
);
11965 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11967 // Two temporaries to store the result of substr() or replace() and to
11968 // store the converted value.
11969 const string
& tmp_id1
= get_temporary_id();
11970 const char *tmp_id_str1
= tmp_id1
.c_str();
11971 const string
& tmp_id2
= get_temporary_id();
11972 const char *tmp_id_str2
= tmp_id2
.c_str();
11973 if (expr_tmp
.preamble
)
11974 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11975 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
11976 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
11977 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
11978 if (expr_tmp
.postamble
)
11979 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
11980 Code::free_expr(&expr_tmp
);
11981 expr
->preamble
= mputprintf(expr
->preamble
,
11982 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
11983 "`%s' are not compatible at run-time\");\n",
11984 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
11985 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
11986 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
11987 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
11990 void Value::generate_code_expr_regexp(expression_struct
*expr
)
11992 Value
* v1
= u
.expr
.ti1
->get_specific_value();
11993 Value
* v2
= u
.expr
.t2
->get_specific_value();
11994 expr
->expr
= mputstr(expr
->expr
, "regexp(");
11995 if (v1
) v1
->generate_code_expr_mandatory(expr
);
11996 else u
.expr
.ti1
->generate_code(expr
);
11997 expr
->expr
= mputstr(expr
->expr
, ", ");
11998 if (v2
) v2
->generate_code_expr_mandatory(expr
);
11999 else u
.expr
.t2
->generate_code(expr
);
12000 expr
->expr
= mputstr(expr
->expr
, ", ");
12001 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12002 expr
->expr
= mputc(expr
->expr
, ')');
12005 void Value::generate_code_expr_replace(expression_struct
*expr
)
12007 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12008 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12010 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12011 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12012 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12013 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12014 else u
.expr
.ti1
->generate_code(expr
);
12015 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12016 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12017 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12018 expr
->expr
= mputstr(expr
->expr
, "(int)");
12019 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12020 expr
->expr
= mputstr(expr
->expr
, ", ");
12021 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12022 expr
->expr
= mputstr(expr
->expr
, "(int)");
12023 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12024 expr
->expr
= mputstr(expr
->expr
, ", ");
12026 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12027 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12028 Value
* v4_last
= v4
->get_value_refd_last();
12029 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12030 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12031 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_stringRepr().c_str());
12033 v4
->generate_code_expr_mandatory(expr
);
12035 else u
.expr
.ti4
->generate_code(expr
);
12036 expr
->expr
= mputc(expr
->expr
, ')');
12039 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12042 if(!v1
) // simple random generation
12043 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12044 else { // random generation with seeding
12045 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12046 v1
->generate_code_expr_mandatory(expr
);
12047 expr
->expr
= mputc(expr
->expr
, ')');
12051 void Value::generate_code_expr_create(expression_struct
*expr
,
12052 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12054 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12055 // first two arguments: component type
12056 Assignment
*t_ass
= type
->get_refd_assignment();
12057 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12058 FATAL_ERROR("Value::generate_code_expr_create()");
12059 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12060 Type::EXPECTED_DYNAMIC_VALUE
);
12061 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12062 comptype
= comptype
->get_type_refd_last();
12063 expr
->expr
= comptype
->get_CompBody()
12064 ->generate_code_comptype_name(expr
->expr
);
12065 expr
->expr
= mputstr(expr
->expr
, ", ");
12066 // third argument: component name
12068 Value
*t_val
= name
->get_value_refd_last();
12069 if (t_val
->valuetype
== V_CSTR
) {
12070 // the argument is foldable to a string literal
12071 size_t str_len
= t_val
->u
.str
.val_str
->size();
12072 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12073 expr
->expr
= mputc(expr
->expr
, '"');
12074 for (size_t i
= 0; i
< str_len
; i
++)
12075 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12076 expr
->expr
= mputc(expr
->expr
, '"');
12077 } else name
->generate_code_expr_mandatory(expr
);
12078 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12079 expr
->expr
= mputstr(expr
->expr
, ", ");
12080 // fourth argument: location
12082 Value
*t_val
= location
->get_value_refd_last();
12083 if (t_val
->valuetype
== V_CSTR
) {
12084 // the argument is foldable to a string literal
12085 size_t str_len
= t_val
->u
.str
.val_str
->size();
12086 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12087 expr
->expr
= mputc(expr
->expr
, '"');
12088 for (size_t i
= 0; i
< str_len
; i
++)
12089 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12090 expr
->expr
= mputc(expr
->expr
, '"');
12091 } else location
->generate_code_expr_mandatory(expr
);
12092 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12093 // fifth argument: alive flag
12094 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12097 void Value::generate_code_expr_activate(expression_struct
*expr
)
12099 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12100 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12101 FATAL_ERROR("Value::generate_code_expr_activate()");
12102 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12103 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12104 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12105 expr
->expr
= mputc(expr
->expr
, ')');
12108 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12110 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12111 if (v_last
->valuetype
== V_ALTSTEP
) {
12112 // the referred altstep is known
12113 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12114 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12116 // the referred altstep is unknown
12117 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12118 expr
->expr
= mputstr(expr
->expr
,".activate(");
12120 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12121 expr
->expr
= mputc(expr
->expr
, ')');
12124 void Value::generate_code_expr_execute(expression_struct
*expr
)
12126 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12127 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12128 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12129 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12130 if (parlist
->get_nof_pars() > 0) {
12131 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12133 expr
->expr
= mputstr(expr
->expr
, ", ");
12136 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12137 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12138 expr
->expr
= mputc(expr
->expr
, ')');
12139 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12142 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12144 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12145 if (v_last
->valuetype
== V_TESTCASE
) {
12146 // the referred testcase is known
12147 Assignment
*testcase
= v_last
->get_refd_fat();
12148 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12149 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12150 u
.expr
.ap_list2
->generate_code_alias(expr
,
12151 testcase
->get_FormalParList(), 0, false);
12153 // the referred testcase is unknown
12154 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12155 expr
->expr
= mputstr(expr
->expr
,".execute(");
12156 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12158 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12159 expr
->expr
= mputstr(expr
->expr
, ", ");
12161 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12162 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12163 expr
->expr
= mputc(expr
->expr
, ')');
12164 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12167 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12169 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12170 if (last_v
->get_valuetype() == V_FUNCTION
) {
12171 // the referred function is known
12172 Assignment
*function
= last_v
->get_refd_fat();
12173 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12174 function
->get_genname_from_scope(my_scope
).c_str());
12175 u
.invoke
.ap_list
->generate_code_alias(expr
,
12176 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12178 // the referred function is unknown
12179 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12180 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12181 Type
* gov_last
= last_v
->get_expr_governor_last();
12182 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12183 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12185 expr
->expr
= mputc(expr
->expr
, ')');
12188 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12191 // if the referenced value points to an optional value field the
12192 // generated code has to be corrected at the end:
12193 // `fieldid()' => `fieldid()()'
12194 Assignment
*ass
= ref
->get_refd_assignment();
12195 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12196 switch (ass
->get_asstype()) {
12197 case Assignment::A_CONST
:
12198 case Assignment::A_EXT_CONST
:
12199 case Assignment::A_MODULEPAR
:
12200 case Assignment::A_VAR
:
12201 case Assignment::A_FUNCTION_RVAL
:
12202 case Assignment::A_EXT_FUNCTION_RVAL
:
12203 case Assignment::A_PAR_VAL_IN
:
12204 case Assignment::A_PAR_VAL_OUT
:
12205 case Assignment::A_PAR_VAL_INOUT
:
12206 // only these are mapped to value objects
12207 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12208 expr
->expr
= mputstr(expr
->expr
, "()");
12215 void Value::generate_code_expr_encode(expression_struct
*expr
)
12219 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12220 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12221 v1
= templ
->get_specific_value();
12222 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12224 expression_struct expr2
;
12225 Code::init_expr(&expr2
);
12227 bool is_templ
= false;
12228 switch (templ
->get_templatetype()) {
12229 case Template::SPECIFIC_VALUE
:
12230 v1
->generate_code_expr_mandatory(&expr2
);
12233 u
.expr
.ti1
->generate_code(&expr2
);
12238 if (!gov_last
->is_coding_by_function()) {
12239 const string
& tmp_id
= get_temporary_id();
12240 const string
& tmp_buf_id
= get_temporary_id();
12241 const string
& tmp_ref_id
= get_temporary_id();
12242 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12244 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12245 tmp_buf_id
.c_str());
12246 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12247 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12248 expr
->preamble
= mputc (expr
->preamble
, '\n');
12250 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12251 gov_last
->get_genname_typedescriptor(
12252 u
.expr
.ti1
->get_Template()->get_my_scope()
12254 tmp_ref_id
.c_str(),
12256 if (is_templ
) // make a value out of the template, if needed
12257 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12258 expr
->preamble
= mputprintf(expr
->preamble
,
12259 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12260 tmp_ref_id
.c_str(),
12261 gov_last
->get_genname_typedescriptor(
12262 u
.expr
.ti1
->get_Template()->get_my_scope()
12264 tmp_buf_id
.c_str(),
12265 gov_last
->get_coding(true).c_str()
12267 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12268 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12269 tmp_buf_id
.c_str(),
12272 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12273 if (expr2
.postamble
)
12274 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12276 expr
->expr
= mputprintf(expr
->expr
, "%s(%s)",
12277 gov_last
->get_coding(true).c_str(), expr2
.expr
);
12278 Code::free_expr(&expr2
);
12281 void Value::generate_code_expr_decode(expression_struct
*expr
)
12283 expression_struct expr1
, expr2
;
12284 Code::init_expr(&expr1
);
12285 Code::init_expr(&expr2
);
12286 u
.expr
.r1
->generate_code(&expr1
);
12287 u
.expr
.r2
->generate_code(&expr2
);
12289 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12290 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12291 get_type_refd_last();
12293 if (expr1
.preamble
)
12294 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12295 if (expr2
.preamble
)
12296 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12298 if (!_type
->is_coding_by_function()) {
12299 const string
& tmp_id
= get_temporary_id();
12300 const string
& buffer_id
= get_temporary_id();
12301 const string
& retval_id
= get_temporary_id();
12302 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12303 field_is_optional(u
.expr
.r2
->get_subrefs());
12305 expr
->preamble
= mputprintf(expr
->preamble
,
12306 "TTCN_Buffer %s(bit2oct(%s));\n"
12308 "TTCN_EncDec::set_error_behavior("
12309 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12310 "TTCN_EncDec::clear_error();\n",
12315 expr
->preamble
= mputprintf(expr
->preamble
,
12316 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12318 optional
? "()" : "",
12319 _type
->get_genname_typedescriptor(
12320 u
.expr
.r2
->get_my_scope()
12323 _type
->get_coding(false).c_str()
12325 expr
->preamble
= mputprintf(expr
->preamble
,
12326 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12327 "case TTCN_EncDec::ET_NONE: {\n"
12329 "OCTETSTRING %s;\n"
12330 "%s.get_string(%s);\n"
12331 "%s = oct2bit(%s);\n"
12334 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12335 "case TTCN_EncDec::ET_LEN_ERR:\n"
12341 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12342 "TTCN_EncDec::EB_DEFAULT);\n"
12343 "TTCN_EncDec::clear_error();\n",
12354 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12356 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12357 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12358 if (expr1
.postamble
)
12359 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12360 if (expr2
.postamble
)
12361 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12362 Code::free_expr(&expr1
);
12363 Code::free_expr(&expr2
);
12366 char *Value::generate_code_init_choice(char *str
, const char *name
)
12368 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12369 // Safe as long as get_name() returns a const string&, not a temporary.
12370 const char *alt_prefix
=
12371 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12373 if (u
.choice
.alt_value
->needs_temp_ref()) {
12374 const string
& tmp_id
= get_temporary_id();
12375 const char *tmp_id_str
= tmp_id
.c_str();
12376 str
= mputprintf(str
, "{\n"
12377 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12378 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12379 alt_prefix
, alt_name
);
12380 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12381 str
= mputstr(str
, "}\n");
12383 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12384 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12385 Free(embedded_name
);
12390 char *Value::generate_code_init_seof(char *str
, const char *name
)
12392 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12394 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12395 const string
& embedded_type
=
12396 my_governor
->get_ofType()->get_genname_value(my_scope
);
12397 const char *embedded_type_str
= embedded_type
.c_str();
12398 for (size_t i
= 0; i
< nof_vs
; i
++) {
12399 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12401 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12402 else if (comp_v
->needs_temp_ref()) {
12403 const string
& tmp_id
= get_temporary_id();
12404 const char *tmp_id_str
= tmp_id
.c_str();
12405 str
= mputprintf(str
, "{\n"
12406 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12407 (unsigned long) i
);
12408 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12409 str
= mputstr(str
, "}\n");
12411 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12412 str
= comp_v
->generate_code_init(str
, embedded_name
);
12413 Free(embedded_name
);
12417 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12422 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12424 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12426 // Previous values can be truncated. The concept is similar to
12428 Type
*t_last
= my_governor
->get_type_refd_last();
12429 const string
& oftype_name
=
12430 t_last
->get_ofType()->get_genname_value(my_scope
);
12431 const char *oftype_name_str
= oftype_name
.c_str();
12432 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12433 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12434 const string
& tmp_id_1
= get_temporary_id();
12435 str
= mputstr(str
, "{\n");
12436 Value
*index
= iv
->get_index();
12437 if (index
->get_valuetype() != V_INT
) {
12438 const string
& tmp_id_2
= get_temporary_id();
12439 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12440 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12441 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12442 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12444 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12445 tmp_id_1
.c_str(), name
,
12446 (index
->get_val_Int()->t_str()).c_str());
12448 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12449 str
= mputstr(str
, "}\n");
12451 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12455 char *Value::generate_code_init_array(char *str
, const char *name
)
12457 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12458 Type
*t_last
= my_governor
->get_type_refd_last();
12459 Int index_offset
= t_last
->get_dimension()->get_offset();
12460 const string
& embedded_type
=
12461 t_last
->get_ofType()->get_genname_value(my_scope
);
12462 const char *embedded_type_str
= embedded_type
.c_str();
12463 for (size_t i
= 0; i
< nof_vs
; i
++) {
12464 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12465 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12466 else if (comp_v
->needs_temp_ref()) {
12467 const string
& tmp_id
= get_temporary_id();
12468 const char *tmp_id_str
= tmp_id
.c_str();
12469 str
= mputprintf(str
, "{\n"
12470 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12471 Int2string(index_offset
+ i
).c_str());
12472 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12473 str
= mputstr(str
, "}\n");
12475 char *embedded_name
= mprintf("%s[%s]", name
,
12476 Int2string(index_offset
+ i
).c_str());
12477 str
= comp_v
->generate_code_init(str
, embedded_name
);
12478 Free(embedded_name
);
12484 char *Value::generate_code_init_se(char *str
, const char *name
)
12486 Type
*type
= my_governor
->get_type_refd_last();
12487 size_t nof_comps
= type
->get_nof_comps();
12488 if (nof_comps
> 0) {
12489 for (size_t i
= 0; i
< nof_comps
; i
++) {
12490 CompField
*cf
= type
->get_comp_byIndex(i
);
12491 const Identifier
& field_id
= cf
->get_name();
12492 const char *field_name
= field_id
.get_name().c_str();
12494 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12495 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12496 if (field_v
->valuetype
== V_NOTUSED
) continue;
12497 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12498 } else if (is_asn1()) {
12499 if (cf
->has_default()) {
12500 // handle like a referenced value
12501 Value
*defval
= cf
->get_defval();
12502 if (needs_init_precede(defval
)) {
12503 str
= defval
->generate_code_init(str
,
12504 defval
->get_lhs_name().c_str());
12506 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12507 defval
->get_genname_own(my_scope
).c_str());
12510 if (!cf
->get_is_optional())
12511 FATAL_ERROR("Value::generate_code_init()");
12518 // the value is not omit
12519 if (field_v
->needs_temp_ref()) {
12520 const string
& tmp_id
= get_temporary_id();
12521 const char *tmp_id_str
= tmp_id
.c_str();
12522 str
= mputprintf(str
, "{\n"
12523 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
12524 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12526 str
= field_v
->generate_code_init(str
, tmp_id_str
);
12527 str
= mputstr(str
, "}\n");
12529 char *embedded_name
= mprintf("%s.%s()", name
,
12531 if (cf
->get_is_optional() && field_v
->is_compound())
12532 embedded_name
= mputstr(embedded_name
, "()");
12533 str
= field_v
->generate_code_init(str
, embedded_name
);
12534 Free(embedded_name
);
12537 // the value is omit
12538 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
12543 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12548 char *Value::generate_code_init_refd(char *str
, const char *name
)
12550 Value
*v
= get_value_refd_last();
12552 // the referred value is not available at compile time
12553 // the code generation is based on the reference
12554 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
12555 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
12557 expression_struct expr
;
12558 Code::init_expr(&expr
);
12559 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
12560 u
.ref
.ref
->generate_code_const_ref(&expr
);
12561 str
= Code::merge_free_expr(str
, &expr
);
12564 // the referred value is available at compile time
12565 // the code generation is based on the referred value
12566 if (v
->has_single_expr() &&
12567 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
12568 // simple substitution for in-line values within the same module
12569 str
= mputprintf(str
, "%s = %s;\n", name
,
12570 v
->get_single_expr().c_str());
12572 // use a simple reference to reduce code size
12573 if (needs_init_precede(v
)) {
12574 // the referred value must be initialized first
12575 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
12576 // temporary id should be introduced for the lhs
12577 const string
& tmp_id
= get_temporary_id();
12578 const char *tmp_id_str
= tmp_id
.c_str();
12579 str
= mputprintf(str
, "{\n"
12581 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
12582 tmp_id_str
, v
->get_lhs_name().c_str());
12583 str
= v
->generate_code_init(str
, tmp_id_str
);
12584 str
= mputstr(str
, "}\n");
12586 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
12589 str
= mputprintf(str
, "%s = %s;\n", name
,
12590 v
->get_genname_own(my_scope
).c_str());
12596 bool Value::explicit_cast_needed(bool forIsValue
)
12598 Value
*v_last
= get_value_refd_last();
12599 if (v_last
!= this) {
12600 // this is a foldable referenced value
12601 // if the reference points to an imported or compound value the code
12602 // generation will be based on the reference so cast is not needed
12603 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
12604 || !v_last
->has_single_expr()) return false;
12605 } else if (v_last
->valuetype
== V_REFD
) {
12606 // this is an unfoldable reference (v_last==this)
12607 // explicit cast is needed only for string element references
12608 if (forIsValue
) return false;
12609 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
12610 return t_subrefs
&& t_subrefs
->refers_to_string_element();
12612 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
12613 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
12614 switch (t_governor
->get_typetype()) {
12618 case Type::T_INT_A
:
12620 case Type::T_ENUM_A
:
12621 case Type::T_ENUM_T
:
12622 case Type::T_VERDICT
:
12623 case Type::T_COMPONENT
:
12624 // these are mapped to built-in C/C++ types
12626 case Type::T_SEQ_A
:
12627 case Type::T_SEQ_T
:
12628 case Type::T_SET_A
:
12629 case Type::T_SET_T
:
12630 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12631 return t_governor
->get_nof_comps() == 0;
12632 case Type::T_SEQOF
:
12633 case Type::T_SETOF
:
12634 // the C++ equivalent of value {} is ambiguous
12637 case Type::T_FUNCTION
:
12638 case Type::T_ALTSTEP
:
12639 case Type::T_TESTCASE
:
12646 bool Value::has_single_expr()
12648 if (get_needs_conversion()) return false;
12649 switch (valuetype
) {
12651 return has_single_expr_expr();
12654 // a union or array value cannot be represented as an in-line expression
12658 // only an empty record/set of value can be represented as an in-line
12660 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
12661 else return u
.val_vs
->get_nof_ivs() == 0;
12664 // only a value for an empty record/set type can be represented as an
12665 // in-line expression
12666 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
12667 Type
*type
= my_governor
->get_type_refd_last();
12668 return type
->get_nof_comps() == 0; }
12670 Value
*v_last
= get_value_refd_last();
12671 // If the above call hit an error and set_valuetype(V_ERROR),
12672 // then u.ref.ref has been freed. Avoid the segfault.
12673 if (valuetype
== V_ERROR
)
12675 if (v_last
!= this && v_last
->has_single_expr() &&
12676 v_last
->my_scope
->get_scope_mod_gen() ==
12677 my_scope
->get_scope_mod_gen()) return true;
12678 else return u
.ref
.ref
->has_single_expr(); }
12680 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
12684 case V_UNDEF_LOWERID
:
12685 case V_UNDEF_BLOCK
:
12687 // these values cannot occur during code generation
12688 FATAL_ERROR("Value::has_single_expr()");
12690 return u
.val_Int
->is_native_fit();
12692 // other value types (literal values) do not need temporary reference
12697 string
Value::get_single_expr()
12699 switch (valuetype
) {
12701 return string("ASN_NULL_VALUE");
12703 return string(u
.val_bool
? "TRUE" : "FALSE");
12705 if (u
.val_Int
->is_native_fit()) { // Be sure.
12706 return u
.val_Int
->t_str();
12708 // get_single_expr may be called only if has_single_expr() is true.
12709 // The only exception is V_INT, where get_single_expr may be called
12710 // even if is_native_fit (which is used to implement has_single_expr)
12712 string
ret_val('"');
12713 ret_val
+= u
.val_Int
->t_str();
12718 return Real2code(u
.val_Real
);
12720 return get_single_expr_enum();
12722 return get_my_scope()->get_scope_mod_gen()
12723 ->add_bitstring_literal(*u
.str
.val_str
);
12725 return get_my_scope()->get_scope_mod_gen()
12726 ->add_hexstring_literal(*u
.str
.val_str
);
12728 return get_my_scope()->get_scope_mod_gen()
12729 ->add_octetstring_literal(*u
.str
.val_str
);
12731 return get_my_scope()->get_scope_mod_gen()
12732 ->add_charstring_literal(*u
.str
.val_str
);
12734 if (u
.ustr
.convert_str
) {
12735 set_valuetype(V_CSTR
);
12736 return get_my_scope()->get_scope_mod_gen()
12737 ->add_charstring_literal(*u
.str
.val_str
);
12739 return get_my_scope()->get_scope_mod_gen()
12740 ->add_ustring_literal(*u
.ustr
.val_ustr
);
12742 return get_single_expr_iso2022str();
12745 vector
<string
> comps
;
12746 bool is_constant
= get_oid_comps(comps
);
12747 size_t nof_comps
= comps
.size();
12749 for (size_t i
= 0; i
< nof_comps
; i
++) {
12750 if (i
> 0) oi_str
+= ", ";
12751 oi_str
+= *(comps
[i
]);
12753 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
12756 // the objid only contains constants
12757 // => create a literal and return its name
12758 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
12760 // the objid contains at least one variable
12761 // => append the number of components before the component values in the string and return it
12762 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
12765 if (u
.val_vs
->get_nof_vs() > 0)
12766 FATAL_ERROR("Value::get_single_expr()");
12767 return string("NULL_VALUE");
12770 if (u
.val_nvs
->get_nof_nvs() > 0)
12771 FATAL_ERROR("Value::get_single_expr()");
12772 return string("NULL_VALUE");
12774 Value
*v_last
= get_value_refd_last();
12775 if (v_last
!= this && v_last
->has_single_expr() &&
12776 v_last
->my_scope
->get_scope_mod_gen() ==
12777 my_scope
->get_scope_mod_gen()) {
12778 // the reference points to another single value in the same module
12779 return v_last
->get_single_expr();
12781 // convert the reference to a single expression
12782 expression_struct expr
;
12783 Code::init_expr(&expr
);
12784 u
.ref
.ref
->generate_code_const_ref(&expr
);
12785 if (expr
.preamble
|| expr
.postamble
)
12786 FATAL_ERROR("Value::get_single_expr()");
12787 string
ret_val(expr
.expr
);
12788 Code::free_expr(&expr
);
12792 return string("OMIT_VALUE");
12794 switch (u
.verdict
) {
12796 return string("NONE");
12798 return string("PASS");
12799 case Verdict_INCONC
:
12800 return string("INCONC");
12802 return string("FAIL");
12803 case Verdict_ERROR
:
12804 return string("ERROR");
12806 FATAL_ERROR("Value::get_single_expr()");
12809 case V_DEFAULT_NULL
:
12810 return string("NULL_COMPREF");
12812 string
ret_val('(');
12813 ret_val
+= my_governor
->get_genname_value(my_scope
);
12814 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
12818 expression_struct expr
;
12819 Code::init_expr(&expr
);
12820 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
12821 else generate_code_expr_invoke(&expr
);
12822 if (expr
.preamble
|| expr
.postamble
)
12823 FATAL_ERROR("Value::get_single_expr()");
12824 string
ret_val(expr
.expr
);
12825 Code::free_expr(&expr
);
12829 case MACRO_TESTCASEID
:
12830 return string("TTCN_Runtime::get_testcase_id_macro()");
12832 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
12838 return get_single_expr_fat();
12840 FATAL_ERROR("Value::get_single_expr()");
12845 bool Value::has_single_expr_expr()
12847 switch (u
.expr
.v_optype
) {
12848 case OPTYPE_RND
: // -
12849 case OPTYPE_COMP_NULL
:
12850 case OPTYPE_COMP_MTC
:
12851 case OPTYPE_COMP_SYSTEM
:
12852 case OPTYPE_COMP_SELF
:
12853 case OPTYPE_COMP_RUNNING_ANY
:
12854 case OPTYPE_COMP_RUNNING_ALL
:
12855 case OPTYPE_COMP_ALIVE_ANY
:
12856 case OPTYPE_COMP_ALIVE_ALL
:
12857 case OPTYPE_TMR_RUNNING_ANY
:
12858 case OPTYPE_GETVERDICT
:
12859 case OPTYPE_TESTCASENAME
:
12861 case OPTYPE_ENCODE
:
12862 case OPTYPE_DECODE
:
12863 case OPTYPE_ISBOUND
:
12864 case OPTYPE_ISPRESENT
:
12865 case OPTYPE_TTCN2STRING
:
12867 case OPTYPE_UNARYPLUS
: // v1
12868 case OPTYPE_UNARYMINUS
:
12871 case OPTYPE_BIT2HEX
:
12872 case OPTYPE_BIT2INT
:
12873 case OPTYPE_BIT2OCT
:
12874 case OPTYPE_BIT2STR
:
12875 case OPTYPE_CHAR2INT
:
12876 case OPTYPE_CHAR2OCT
:
12877 case OPTYPE_FLOAT2INT
:
12878 case OPTYPE_FLOAT2STR
:
12879 case OPTYPE_HEX2BIT
:
12880 case OPTYPE_HEX2INT
:
12881 case OPTYPE_HEX2OCT
:
12882 case OPTYPE_HEX2STR
:
12883 case OPTYPE_INT2CHAR
:
12884 case OPTYPE_INT2FLOAT
:
12885 case OPTYPE_INT2STR
:
12886 case OPTYPE_INT2UNICHAR
:
12887 case OPTYPE_OCT2BIT
:
12888 case OPTYPE_OCT2CHAR
:
12889 case OPTYPE_OCT2HEX
:
12890 case OPTYPE_OCT2INT
:
12891 case OPTYPE_OCT2STR
:
12892 case OPTYPE_STR2BIT
:
12893 case OPTYPE_STR2FLOAT
:
12894 case OPTYPE_STR2HEX
:
12895 case OPTYPE_STR2INT
:
12896 case OPTYPE_STR2OCT
:
12897 case OPTYPE_UNICHAR2INT
:
12898 case OPTYPE_UNICHAR2CHAR
:
12899 case OPTYPE_ENUM2INT
:
12900 case OPTYPE_RNDWITHVAL
:
12901 case OPTYPE_ISCHOSEN_V
: // v1 i2
12902 case OPTYPE_COMP_RUNNING
:
12903 case OPTYPE_COMP_ALIVE
:
12904 case OPTYPE_GET_STRINGENCODING
:
12905 case OPTYPE_REMOVE_BOM
:
12906 case OPTYPE_DECODE_BASE64
:
12907 return u
.expr
.v1
->has_single_expr();
12908 case OPTYPE_ISCHOSEN_T
: // t1 i2
12909 return u
.expr
.t1
->has_single_expr();
12910 case OPTYPE_ADD
: // v1 v2
12911 case OPTYPE_SUBTRACT
:
12912 case OPTYPE_MULTIPLY
:
12913 case OPTYPE_DIVIDE
:
12916 case OPTYPE_CONCAT
:
12931 case OPTYPE_INT2BIT
:
12932 case OPTYPE_INT2HEX
:
12933 case OPTYPE_INT2OCT
:
12934 return u
.expr
.v1
->has_single_expr() &&
12935 u
.expr
.v2
->has_single_expr();
12936 case OPTYPE_UNICHAR2OCT
:
12937 case OPTYPE_OCT2UNICHAR
:
12938 case OPTYPE_ENCODE_BASE64
:
12939 return u
.expr
.v1
->has_single_expr() &&
12940 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
12943 return u
.expr
.v1
->has_single_expr() &&
12944 u
.expr
.v2
->has_single_expr() &&
12945 !u
.expr
.v2
->needs_short_circuit();
12946 case OPTYPE_SUBSTR
:
12947 return u
.expr
.ti1
->has_single_expr() &&
12948 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
12949 case OPTYPE_REGEXP
:
12950 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
12951 u
.expr
.v3
->has_single_expr();
12952 case OPTYPE_DECOMP
: // v1 v2 v3
12953 return u
.expr
.v1
->has_single_expr() &&
12954 u
.expr
.v2
->has_single_expr() &&
12955 u
.expr
.v3
->has_single_expr();
12956 case OPTYPE_REPLACE
:
12957 return u
.expr
.ti1
->has_single_expr() &&
12958 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
12959 u
.expr
.ti4
->has_single_expr();
12960 case OPTYPE_ISVALUE
: // ti1
12961 case OPTYPE_LENGTHOF
: // ti1
12962 case OPTYPE_SIZEOF
: // ti1
12963 case OPTYPE_VALUEOF
: // ti1
12964 return u
.expr
.ti1
->has_single_expr();
12965 case OPTYPE_LOG2STR
:
12966 return u
.expr
.logargs
->has_single_expr();
12967 case OPTYPE_MATCH
: // v1 t2
12968 return u
.expr
.v1
->has_single_expr() &&
12969 u
.expr
.t2
->has_single_expr();
12970 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
12971 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
12972 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
12973 case OPTYPE_TMR_READ
: // r1
12974 case OPTYPE_TMR_RUNNING
:
12975 case OPTYPE_ACTIVATE
:
12976 return u
.expr
.r1
->has_single_expr();
12977 case OPTYPE_EXECUTE
: // r1 [v2]
12978 return u
.expr
.r1
->has_single_expr() &&
12979 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
12980 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
12981 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
12982 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
12983 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
12984 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
12986 FATAL_ERROR("Value::has_single_expr_expr()");
12990 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
12992 if (!v
->has_single_expr()) return false;
12993 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
12994 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
12998 string
Value::get_single_expr_enum()
13000 string
ret_val(my_governor
->get_genname_value(my_scope
));
13002 ret_val
+= u
.val_id
->get_name();
13006 string
Value::get_single_expr_iso2022str()
13009 Type
*type
= get_my_governor()->get_type_refd_last();
13010 switch (type
->get_typetype()) {
13011 case Type::T_TELETEXSTRING
:
13012 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13014 case Type::T_VIDEOTEXSTRING
:
13015 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13017 case Type::T_GRAPHICSTRING
:
13018 case Type::T_OBJECTDESCRIPTOR
:
13019 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13021 case Type::T_GENERALSTRING
:
13022 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13025 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13028 string
*ostr
= char2oct(*u
.str
.val_str
);
13029 ret_val
+= get_my_scope()->get_scope_mod_gen()
13030 ->add_octetstring_literal(*ostr
);
13036 string
Value::get_single_expr_fat()
13038 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13039 // the ampersand operator is not really necessary to obtain the function
13040 // pointer, but some older versions of GCC cannot instantiate the
13041 // appropriate operator=() member of class OPTIONAL when necessary
13042 // if only the function name is given
13043 string
ret_val('&');
13044 switch (valuetype
) {
13046 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13049 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13050 ret_val
+= "_instance";
13053 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13056 FATAL_ERROR("Value::get_single_expr_fat()");
13061 bool Value::is_compound()
13063 switch (valuetype
) {
13076 bool Value::needs_temp_ref()
13078 switch (valuetype
) {
13081 if (!is_indexed()) {
13082 // Temporary reference is needed if the value has at least one real
13083 // element (i.e. it is not empty or contains only not used symbols).
13084 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13085 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13088 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13089 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13090 ->valuetype
!= V_NOTUSED
)
13096 size_t nof_real_vs
= 0;
13097 if (!is_indexed()) {
13098 // Temporary reference is needed if the array value has at least two
13099 // real elements (excluding not used symbols).
13100 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13101 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13103 if (nof_real_vs
> 1) 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
) {
13111 if (nof_real_vs
> 1) return true;
13119 // it depends on the type since fields with omit or default value
13120 // may not be present
13121 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13123 // incomplete values are allowed in TTCN-3
13124 // we should check the number of value components
13125 return u
.val_nvs
->get_nof_nvs() > 1;
13130 case V_UNDEF_LOWERID
:
13131 case V_UNDEF_BLOCK
:
13133 // these values cannot occur during code generation
13134 FATAL_ERROR("Value::needs_temp_ref()");
13136 return !u
.val_Int
->is_native();
13138 // other value types (literal values) do not need temporary reference
13143 bool Value::needs_short_circuit()
13145 switch (valuetype
) {
13153 // sub-expressions should be evaluated only if necessary
13156 FATAL_ERROR("Value::needs_short_circuit()");
13158 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13159 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13160 switch (t_ass
->get_asstype()) {
13161 case Assignment::A_FUNCTION_RVAL
:
13162 case Assignment::A_EXT_FUNCTION_RVAL
:
13163 // avoid unnecessary call of a function
13165 case Assignment::A_CONST
:
13166 case Assignment::A_EXT_CONST
:
13167 case Assignment::A_MODULEPAR
:
13168 case Assignment::A_VAR
:
13169 case Assignment::A_PAR_VAL_IN
:
13170 case Assignment::A_PAR_VAL_OUT
:
13171 case Assignment::A_PAR_VAL_INOUT
:
13172 // depends on field/array sub-references, which is examined below
13175 FATAL_ERROR("Value::needs_short_circuit()");
13177 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13179 // the evaluation of the reference does not have side effects
13180 // (i.e. false shall be returned) only if all sub-references point to
13181 // mandatory fields of record/set types
13182 Type
*t_type
= t_ass
->get_Type();
13183 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13184 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13185 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13186 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13187 if (t_cf
->get_is_optional()) return true;
13188 t_type
= t_cf
->get_type();
13189 } else return true;
13195 void Value::dump(unsigned level
) const
13197 switch (valuetype
) {
13221 case V_DEFAULT_NULL
:
13229 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13233 DEBUG(level
, "Value: reference");
13234 u
.ref
.ref
->dump(level
+ 1);
13236 case V_UNDEF_LOWERID
:
13237 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13239 case V_UNDEF_BLOCK
:
13240 DEBUG(level
, "Value: {block}");
13243 DEBUG(level
, "Value: null");
13246 DEBUG(level
, "Value: invoke");
13247 u
.invoke
.v
->dump(level
+ 1);
13248 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13249 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13252 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13256 void Value::add_string_element(size_t index
, Value
*v_element
,
13257 map
<size_t, Value
>*& string_elements
)
13259 v_element
->set_my_scope(get_my_scope());
13260 v_element
->set_my_governor(get_my_governor());
13261 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13262 v_element
->set_location(*this);
13263 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13264 string_elements
->add(index
, v_element
);
13267 ///////////////////////////////////////////////////////////////////////////////
13268 // class LazyParamData
13270 int LazyParamData::depth
= 0;
13271 bool LazyParamData::used_as_lvalue
= false;
13272 vector
<string
>* LazyParamData::type_vec
= NULL
;
13273 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13275 void LazyParamData::init(bool p_used_as_lvalue
) {
13276 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13278 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13279 used_as_lvalue
= p_used_as_lvalue
;
13280 type_vec
= new vector
<string
>;
13281 refd_vec
= new vector
<string
>;
13286 void LazyParamData::clean() {
13287 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13288 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13291 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13296 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13304 bool LazyParamData::in_lazy() {
13305 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13309 // returns a temporary id instead of the C++ reference to a definition
13310 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13311 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13312 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13313 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13314 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13315 // store the type of the assignment
13316 string
* type_str
= new string
;
13317 switch (ass
->get_asstype()) {
13318 case Assignment::A_MODULEPAR_TEMP
:
13319 case Assignment::A_TEMPLATE
:
13320 case Assignment::A_VAR_TEMPLATE
:
13321 case Assignment::A_PAR_TEMPL_IN
:
13322 case Assignment::A_PAR_TEMPL_OUT
:
13323 case Assignment::A_PAR_TEMPL_INOUT
:
13324 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13327 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13329 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13330 bool refd_ass_is_lazy_fpar
= false;
13331 switch (ass
->get_asstype()) {
13332 case Assignment::A_PAR_VAL
:
13333 case Assignment::A_PAR_VAL_IN
:
13334 case Assignment::A_PAR_TEMPL_IN
:
13335 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13336 if (refd_ass_is_lazy_fpar
) {
13337 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13343 // add the "const" part if the referenced assignment is a constant thing
13344 if (!refd_ass_is_lazy_fpar
) {
13345 switch (ass
->get_asstype()) {
13346 case Assignment::A_CONST
:
13347 case Assignment::A_OC
:
13348 case Assignment::A_OBJECT
:
13349 case Assignment::A_OS
:
13350 case Assignment::A_VS
:
13351 case Assignment::A_EXT_CONST
:
13352 case Assignment::A_MODULEPAR
:
13353 case Assignment::A_MODULEPAR_TEMP
:
13354 case Assignment::A_TEMPLATE
:
13355 case Assignment::A_PAR_VAL
:
13356 case Assignment::A_PAR_VAL_IN
:
13357 case Assignment::A_PAR_TEMPL_IN
:
13358 *type_str
= string("const ") + *type_str
;
13366 type_vec
->add(type_str
);
13367 // store the C++ reference string
13368 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
13369 if (refd_ass_is_lazy_fpar
) {
13370 Type
* refd_ass_type
= ass
->get_Type();
13371 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
);
13372 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
13374 return get_member_name(refd_vec
->size()-1);
13378 string
LazyParamData::get_member_name(size_t idx
) {
13379 return string("lpm_") + Int2string(idx
);
13382 string
LazyParamData::get_constr_param_name(size_t idx
) {
13383 return string("lpp_") + Int2string(idx
);
13386 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
13387 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13388 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
13389 const string
& tmp_id
= val
->get_temporary_id();
13390 const char *tmp_id_str
= tmp_id
.c_str();
13391 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13392 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13394 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13396 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13398 val
->generate_code_expr(expr
);
13402 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
13403 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13404 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
13405 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
13406 const char *tmp_id_str
= tmp_id
.c_str();
13407 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13408 temp
->get_Template()->get_my_governor()
13409 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
13410 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13411 tmp_id_str
, temp
->get_Template());
13412 // Not incorporated into gen_conv_code() yet.
13413 if (gen_restriction_check
!= TR_NONE
)
13414 expr
->preamble
= Template::generate_restriction_check_code(
13415 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
13416 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13417 } else temp
->generate_code(expr
, gen_restriction_check
);
13420 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13421 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13423 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13424 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13425 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13426 expression_struct value_expr
;
13427 Code::init_expr(&value_expr
);
13428 generate_code_for_value(&value_expr
, value
, scope
);
13429 // the id of the instance of Lazy_Param which will be used as the actual parameter
13430 const string
& lazy_param_id
= value
->get_temporary_id();
13431 if (value_expr
.preamble
) {
13432 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
13434 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13435 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13436 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
13437 Code::free_expr(&value_expr
);
13438 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13441 // only if the formal parameter is *not* used as lvalue
13442 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
13443 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
13445 bool refd_ass_is_lazy_fpar
= false;
13446 switch (refd_ass
->get_asstype()) {
13447 case Assignment::A_PAR_VAL
:
13448 case Assignment::A_PAR_VAL_IN
:
13449 case Assignment::A_PAR_TEMPL_IN
:
13450 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13455 if (refd_ass_is_lazy_fpar
) {
13456 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13461 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13462 expression_struct value_expr
;
13463 Code::init_expr(&value_expr
);
13464 generate_code_for_value(&value_expr
, value
, scope
);
13465 // the id of the instance of Lazy_Param which will be used as the actual parameter
13466 string lazy_param_id
= value
->get_temporary_id();
13467 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
13468 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
13471 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
13472 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13474 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13475 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13476 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13477 expression_struct tmpl_expr
;
13478 Code::init_expr(&tmpl_expr
);
13479 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13480 // the id of the instance of Lazy_Param which will be used as the actual parameter
13481 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
13482 if (tmpl_expr
.preamble
) {
13483 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
13485 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13486 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13487 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
13488 Code::free_expr(&tmpl_expr
);
13489 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13492 // only if the formal parameter is *not* used as lvalue
13493 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
13494 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
13496 bool refd_ass_is_lazy_fpar
= false;
13497 switch (refd_ass
->get_asstype()) {
13498 case Assignment::A_PAR_VAL
:
13499 case Assignment::A_PAR_VAL_IN
:
13500 case Assignment::A_PAR_TEMPL_IN
:
13501 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13506 if (refd_ass_is_lazy_fpar
) {
13507 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13512 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13513 expression_struct tmpl_expr
;
13514 Code::init_expr(&tmpl_expr
);
13515 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13516 // the id of the instance of Lazy_Param which will be used as the actual parameter
13517 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
13518 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
13519 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
13522 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
13523 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
13524 if (type_vec
->size()>0) {
13525 // private members of the local class will be const references to the objects referenced by the expression
13526 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13527 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
13529 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
13530 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
13531 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13532 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13533 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
13535 expr
->preamble
= mputstr(expr
->preamble
, "): ");
13536 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13537 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13538 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
13540 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
13541 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
13543 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
13544 // use the temporary expr structure to fill the body of the eval_expr() function
13545 if (param_expr
.preamble
) {
13546 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
13548 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
13549 if (param_expr
.postamble
) {
13550 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
13552 Code::free_expr(¶m_expr
);
13553 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
13554 "};\n" // end of local class definition
13556 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
13557 if (type_vec
->size()>0) {
13558 expr
->preamble
= mputc(expr
->preamble
, '(');
13559 // paramteres of the constructor are references to the objects used in the expression
13560 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
13561 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13562 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
13564 expr
->preamble
= mputc(expr
->preamble
, ')');
13566 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
13567 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13568 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
13571 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
13572 expression_struct ref_expr
;
13573 Code::init_expr(&ref_expr
);
13574 ref
->generate_code(&ref_expr
);
13575 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
13576 if (ref_expr
.preamble
) {
13577 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
13579 Assignment
* ass
= ref
->get_refd_assignment();
13580 // determine C++ type of the assignment
13582 switch (ass
->get_asstype()) {
13583 case Assignment::A_MODULEPAR_TEMP
:
13584 case Assignment::A_TEMPLATE
:
13585 case Assignment::A_VAR_TEMPLATE
:
13586 case Assignment::A_PAR_TEMPL_IN
:
13587 case Assignment::A_PAR_TEMPL_OUT
:
13588 case Assignment::A_PAR_TEMPL_INOUT
:
13589 type_str
= ass
->get_Type()->get_genname_template(scope
);
13592 type_str
= ass
->get_Type()->get_genname_value(scope
);
13594 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13595 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
13596 if (ref_expr
.postamble
) {
13597 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
13599 Code::free_expr(&ref_expr
);
13600 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13603 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13604 const string
& lazy_param_id
= value
->get_temporary_id();
13605 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13606 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13607 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
13608 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13611 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
13612 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
13613 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13614 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13615 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
13616 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13619 } // namespace Common