1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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"
33 #include "../common/JSON_Tokenizer.hh"
34 #include "ttcn3/Ttcn2Json.hh"
42 static void clean_up_string_elements(map
<size_t, Value
>*& string_elements
)
44 if (string_elements
) {
45 for (size_t i
= 0; i
< string_elements
->size(); i
++)
46 delete string_elements
->get_nth_elem(i
);
47 string_elements
->clear();
48 delete string_elements
;
53 // =================================
55 // =================================
57 Value::Value(const Value
& p
)
58 : GovernedSimple(p
), valuetype(p
.valuetype
), my_governor(0)
70 u
.val_bool
=p
.u
.val_bool
;
73 u
.val_Int
=new int_val_t(*(p
.u
.val_Int
));
78 u
.val_id
=p
.u
.val_id
->clone();
81 u
.val_Real
=p
.u
.val_Real
;
88 set_val_str(new string(*p
.u
.str
.val_str
));
91 set_val_ustr(new ustring(*p
.u
.ustr
.val_ustr
));
92 u
.ustr
.convert_str
= p
.u
.ustr
.convert_str
;
95 u
.char_syms
= p
.u
.char_syms
->clone();
99 u
.oid_comps
=new vector
<OID_comp
>;
100 for(size_t i
=0; i
<p
.u
.oid_comps
->size(); i
++)
101 add_oid_comp((*p
.u
.oid_comps
)[i
]->clone());
104 u
.choice
.alt_name
=p
.u
.choice
.alt_name
->clone();
105 u
.choice
.alt_value
=p
.u
.choice
.alt_value
->clone();
110 u
.val_vs
=p
.u
.val_vs
->clone();
114 u
.val_nvs
=p
.u
.val_nvs
->clone();
117 u
.ref
.ref
=p
.u
.ref
.ref
->clone();
121 for(size_t i
=0; i
<p
.u
.ids
->size(); i
++) {
122 Identifier
*id
= p
.u
.ids
->get_nth_elem(i
);
123 u
.ids
->add(id
->get_name(), id
->clone());
127 u
.block
=p
.u
.block
->clone();
130 u
.verdict
=p
.u
.verdict
;
133 u
.expr
.v_optype
= p
.u
.expr
.v_optype
;
134 u
.expr
.state
= EXPR_NOT_CHECKED
;
135 switch(u
.expr
.v_optype
) {
136 case OPTYPE_RND
: // -
137 case OPTYPE_COMP_NULL
:
138 case OPTYPE_COMP_MTC
:
139 case OPTYPE_COMP_SYSTEM
:
140 case OPTYPE_COMP_SELF
:
141 case OPTYPE_COMP_RUNNING_ANY
:
142 case OPTYPE_COMP_RUNNING_ALL
:
143 case OPTYPE_COMP_ALIVE_ANY
:
144 case OPTYPE_COMP_ALIVE_ALL
:
145 case OPTYPE_TMR_RUNNING_ANY
:
146 case OPTYPE_GETVERDICT
:
147 case OPTYPE_TESTCASENAME
:
148 case OPTYPE_PROF_RUNNING
:
150 case OPTYPE_UNARYPLUS
: // v1
151 case OPTYPE_UNARYMINUS
:
158 case OPTYPE_CHAR2INT
:
159 case OPTYPE_CHAR2OCT
:
160 case OPTYPE_COMP_RUNNING
:
161 case OPTYPE_COMP_ALIVE
:
162 case OPTYPE_FLOAT2INT
:
163 case OPTYPE_FLOAT2STR
:
168 case OPTYPE_INT2CHAR
:
169 case OPTYPE_INT2FLOAT
:
171 case OPTYPE_INT2UNICHAR
:
173 case OPTYPE_OCT2CHAR
:
178 case OPTYPE_STR2FLOAT
:
182 case OPTYPE_UNICHAR2INT
:
183 case OPTYPE_UNICHAR2CHAR
:
184 case OPTYPE_ENUM2INT
:
185 case OPTYPE_RNDWITHVAL
:
186 case OPTYPE_GET_STRINGENCODING
:
187 case OPTYPE_DECODE_BASE64
:
188 case OPTYPE_REMOVE_BOM
:
189 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
191 case OPTYPE_ADD
: // v1 v2
192 case OPTYPE_SUBTRACT
:
193 case OPTYPE_MULTIPLY
:
217 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
218 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
220 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
221 case OPTYPE_OCT2UNICHAR
:
222 case OPTYPE_ENCODE_BASE64
:
223 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
224 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
227 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
228 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
231 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
232 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
233 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
236 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
237 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
238 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
240 case OPTYPE_DECOMP
: // v1 v2 v3
241 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
242 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
243 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
246 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
247 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
248 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
249 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
251 case OPTYPE_LENGTHOF
: // ti1
252 case OPTYPE_SIZEOF
: // ti1
253 case OPTYPE_VALUEOF
: // ti1
255 case OPTYPE_ISPRESENT
:
256 case OPTYPE_TTCN2STRING
:
257 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
259 case OPTYPE_UNDEF_RUNNING
:
260 case OPTYPE_TMR_READ
:
261 case OPTYPE_TMR_RUNNING
:
262 case OPTYPE_ACTIVATE
:
263 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
265 case OPTYPE_EXECUTE
: // r1 [v2]
266 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
267 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
269 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
270 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
271 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
272 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
273 u
.expr
.b4
= p
.u
.expr
.b4
;
275 case OPTYPE_MATCH
: // v1 t2
276 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
277 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
279 case OPTYPE_ISCHOSEN
: // r1 i2
280 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
281 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
283 case OPTYPE_ISCHOSEN_V
: // v1 i2
284 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
285 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
287 case OPTYPE_ISCHOSEN_T
: // t1 i2
288 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
289 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
291 case OPTYPE_ACTIVATE_REFD
:
292 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
293 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
294 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
296 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
297 u
.expr
.state
= EXPR_CHECKED
;
300 case OPTYPE_EXECUTE_REFD
:
301 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
302 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
303 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
305 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
306 u
.expr
.state
= EXPR_CHECKED
;
308 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
311 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
314 FATAL_ERROR("Value::Value()");
323 u
.refd_fat
= p
.u
.refd_fat
;
326 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
327 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
328 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
331 u
.refered
= p
.u
.refered
->clone();
334 FATAL_ERROR("Value::Value()");
338 void Value::clean_up()
361 case V_UNDEF_LOWERID
:
369 delete u
.str
.val_str
;
370 clean_up_string_elements(u
.str
.str_elements
);
373 delete u
.ustr
.val_ustr
;
374 clean_up_string_elements(u
.ustr
.ustr_elements
);
382 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
383 delete (*u
.oid_comps
)[i
];
384 u
.oid_comps
->clear();
392 delete u
.choice
.alt_name
;
393 delete u
.choice
.alt_value
;
412 delete u
.invoke
.t_list
;
413 delete u
.invoke
.ap_list
;
417 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
426 FATAL_ERROR("Value::clean_up()");
430 void Value::clean_up_expr()
432 switch (u
.expr
.state
) {
434 case EXPR_CHECKING_ERR
:
435 FATAL_ERROR("Value::clean_up_expr()");
439 switch (u
.expr
.v_optype
) {
440 case OPTYPE_RND
: // -
441 case OPTYPE_COMP_NULL
:
442 case OPTYPE_COMP_MTC
:
443 case OPTYPE_COMP_SYSTEM
:
444 case OPTYPE_COMP_SELF
:
445 case OPTYPE_COMP_RUNNING_ANY
:
446 case OPTYPE_COMP_RUNNING_ALL
:
447 case OPTYPE_COMP_ALIVE_ANY
:
448 case OPTYPE_COMP_ALIVE_ALL
:
449 case OPTYPE_TMR_RUNNING_ANY
:
450 case OPTYPE_GETVERDICT
:
451 case OPTYPE_TESTCASENAME
:
452 case OPTYPE_PROF_RUNNING
:
454 case OPTYPE_UNARYPLUS
: // v1
455 case OPTYPE_UNARYMINUS
:
462 case OPTYPE_CHAR2INT
:
463 case OPTYPE_CHAR2OCT
:
464 case OPTYPE_COMP_RUNNING
:
465 case OPTYPE_COMP_ALIVE
:
466 case OPTYPE_FLOAT2INT
:
467 case OPTYPE_FLOAT2STR
:
472 case OPTYPE_INT2CHAR
:
473 case OPTYPE_INT2FLOAT
:
475 case OPTYPE_INT2UNICHAR
:
477 case OPTYPE_OCT2CHAR
:
482 case OPTYPE_STR2FLOAT
:
486 case OPTYPE_UNICHAR2INT
:
487 case OPTYPE_UNICHAR2CHAR
:
488 case OPTYPE_ENUM2INT
:
489 case OPTYPE_RNDWITHVAL
:
490 case OPTYPE_REMOVE_BOM
:
491 case OPTYPE_GET_STRINGENCODING
:
492 case OPTYPE_DECODE_BASE64
:
495 case OPTYPE_ADD
: // v1 v2
496 case OPTYPE_SUBTRACT
:
497 case OPTYPE_MULTIPLY
:
521 case OPTYPE_UNICHAR2OCT
:
522 case OPTYPE_OCT2UNICHAR
:
523 case OPTYPE_ENCODE_BASE64
:
541 case OPTYPE_DECOMP
: // v1 v2 v3
552 case OPTYPE_LENGTHOF
: // ti1
553 case OPTYPE_SIZEOF
: // ti1
554 case OPTYPE_VALUEOF
: // ti1
558 case OPTYPE_ISPRESENT
:
559 case OPTYPE_TTCN2STRING
:
562 case OPTYPE_UNDEF_RUNNING
:
563 case OPTYPE_TMR_READ
:
564 case OPTYPE_TMR_RUNNING
:
565 case OPTYPE_ACTIVATE
:
568 case OPTYPE_EXECUTE
: // r1 [v2]
572 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
577 case OPTYPE_MATCH
: // v1 t2
581 case OPTYPE_ISCHOSEN
: // r1 i2
585 case OPTYPE_ISCHOSEN_V
: // v1 i2
589 case OPTYPE_ISCHOSEN_T
: // t1 i2
593 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
595 if(u
.expr
.state
!=EXPR_CHECKED
)
596 delete u
.expr
.t_list2
;
598 delete u
.expr
.ap_list2
;
600 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
602 if(u
.expr
.state
!=EXPR_CHECKED
)
603 delete u
.expr
.t_list2
;
605 delete u
.expr
.ap_list2
;
609 delete u
.expr
.logargs
;
612 FATAL_ERROR("Value::clean_up_expr()");
616 void Value::copy_and_destroy(Value
*src
)
619 valuetype
= src
->valuetype
;
621 // update the pointer used for caching if it points to the value itself
622 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
623 src
->valuetype
= V_ERROR
;
627 Value::Value(valuetype_t p_vt
)
628 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
639 u
.oid_comps
=new vector
<OID_comp
>();
642 u
.ids
=new map
<string
, Identifier
>();
645 FATAL_ERROR("Value::Value()");
649 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
650 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
654 u
.val_bool
=p_val_bool
;
657 FATAL_ERROR("Value::Value()");
661 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
662 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
666 u
.val_Int
=new int_val_t(p_val_Int
);
669 FATAL_ERROR("Value::Value()");
673 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
674 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
681 FATAL_ERROR("Value::Value()");
685 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
686 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
688 if(!p_val_str
) FATAL_ERROR("NULL parameter");
695 set_val_str(p_val_str
);
698 FATAL_ERROR("Value::Value()");
702 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
703 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
705 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
706 set_val_ustr(p_val_ustr
);
707 u
.ustr
.convert_str
= false;
710 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
711 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
713 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
716 u
.char_syms
= p_char_syms
;
719 FATAL_ERROR("Value::Value()");
723 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
724 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
727 FATAL_ERROR("NULL parameter");
731 case V_UNDEF_LOWERID
:
735 FATAL_ERROR("Value::Value()");
739 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
740 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
743 FATAL_ERROR("NULL parameter");
746 u
.choice
.alt_name
=p_id
;
747 u
.choice
.alt_value
=p_val
;
750 FATAL_ERROR("Value::Value()");
754 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
755 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
759 u
.val_Real
=p_val_Real
;
762 FATAL_ERROR("Value::Value()");
766 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
767 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
769 if(!p_vs
) FATAL_ERROR("NULL parameter");
777 FATAL_ERROR("Value::Value()");
781 Value::Value(valuetype_t p_vt
, Value
*p_v
,
782 Ttcn::ParsedActualParameters
*p_t_list
)
783 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
785 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
789 u
.invoke
.t_list
= p_t_list
;
790 u
.invoke
.ap_list
= 0;
793 FATAL_ERROR("Value::Value()");
798 Value::Value(operationtype_t p_optype
)
799 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
801 u
.expr
.v_optype
= p_optype
;
802 u
.expr
.state
= EXPR_NOT_CHECKED
;
805 case OPTYPE_COMP_NULL
:
806 case OPTYPE_COMP_MTC
:
807 case OPTYPE_COMP_SYSTEM
:
808 case OPTYPE_COMP_SELF
:
809 case OPTYPE_COMP_RUNNING_ANY
:
810 case OPTYPE_COMP_RUNNING_ALL
:
811 case OPTYPE_COMP_ALIVE_ANY
:
812 case OPTYPE_COMP_ALIVE_ALL
:
813 case OPTYPE_TMR_RUNNING_ANY
:
814 case OPTYPE_GETVERDICT
:
815 case OPTYPE_TESTCASENAME
:
816 case OPTYPE_PROF_RUNNING
:
819 FATAL_ERROR("Value::Value()");
824 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
825 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
827 u
.expr
.v_optype
= p_optype
;
828 u
.expr
.state
= EXPR_NOT_CHECKED
;
830 case OPTYPE_UNARYPLUS
:
831 case OPTYPE_UNARYMINUS
:
838 case OPTYPE_CHAR2INT
:
839 case OPTYPE_CHAR2OCT
:
840 case OPTYPE_COMP_RUNNING
:
841 case OPTYPE_COMP_ALIVE
:
842 case OPTYPE_FLOAT2INT
:
843 case OPTYPE_FLOAT2STR
:
848 case OPTYPE_INT2CHAR
:
849 case OPTYPE_INT2FLOAT
:
851 case OPTYPE_INT2UNICHAR
:
853 case OPTYPE_OCT2CHAR
:
858 case OPTYPE_STR2FLOAT
:
862 case OPTYPE_UNICHAR2INT
:
863 case OPTYPE_UNICHAR2CHAR
:
864 case OPTYPE_ENUM2INT
:
865 case OPTYPE_RNDWITHVAL
:
866 case OPTYPE_REMOVE_BOM
:
867 case OPTYPE_GET_STRINGENCODING
:
868 case OPTYPE_DECODE_BASE64
:
869 if(!p_v1
) FATAL_ERROR("Value::Value()");
873 FATAL_ERROR("Value::Value()");
878 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
879 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
881 u
.expr
.v_optype
= p_optype
;
882 u
.expr
.state
= EXPR_NOT_CHECKED
;
884 case OPTYPE_LENGTHOF
:
890 case OPTYPE_ISPRESENT
:
891 case OPTYPE_TTCN2STRING
:
892 if(!p_ti1
) FATAL_ERROR("Value::Value()");
896 FATAL_ERROR("Value::Value()");
901 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
902 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
904 u
.expr
.v_optype
= p_optype
;
905 u
.expr
.state
= EXPR_NOT_CHECKED
;
907 case OPTYPE_UNDEF_RUNNING
:
908 case OPTYPE_TMR_READ
:
909 case OPTYPE_TMR_RUNNING
:
910 case OPTYPE_ACTIVATE
:
911 if(!p_r1
) FATAL_ERROR("Value::Value()");
915 FATAL_ERROR("Value::Value()");
920 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
921 Ttcn::ParsedActualParameters
*p_ap_list
)
922 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
924 u
.expr
.v_optype
= p_optype
;
925 u
.expr
.state
= EXPR_NOT_CHECKED
;
927 case OPTYPE_ACTIVATE_REFD
:
928 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
930 u
.expr
.t_list2
= p_ap_list
;
933 FATAL_ERROR("Value::Value()");
938 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
939 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
940 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
942 u
.expr
.v_optype
= p_optype
;
943 u
.expr
.state
= EXPR_NOT_CHECKED
;
945 case OPTYPE_EXECUTE_REFD
:
946 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
948 u
.expr
.t_list2
= p_t_list2
;
952 FATAL_ERROR("Value::Value()");
957 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
958 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
960 u
.expr
.v_optype
= p_optype
;
961 u
.expr
.state
= EXPR_NOT_CHECKED
;
964 if(!p_r1
) FATAL_ERROR("Value::Value()");
969 FATAL_ERROR("Value::Value()");
974 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
975 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
976 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
978 u
.expr
.v_optype
= p_optype
;
979 u
.expr
.state
= EXPR_NOT_CHECKED
;
981 case OPTYPE_COMP_CREATE
:
982 if(!p_r1
) FATAL_ERROR("Value::Value()");
989 FATAL_ERROR("Value::Value()");
994 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
995 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
997 u
.expr
.v_optype
= p_optype
;
998 u
.expr
.state
= EXPR_NOT_CHECKED
;
1001 case OPTYPE_SUBTRACT
:
1002 case OPTYPE_MULTIPLY
:
1023 case OPTYPE_INT2BIT
:
1024 case OPTYPE_INT2HEX
:
1025 case OPTYPE_INT2OCT
:
1026 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1030 case OPTYPE_UNICHAR2OCT
:
1031 case OPTYPE_OCT2UNICHAR
:
1032 case OPTYPE_ENCODE_BASE64
:
1033 if(!p_v1
) FATAL_ERROR("Value::Value()");
1035 // p_v2 may be NULL if there is no second param
1039 FATAL_ERROR("Value::Value()");
1044 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1045 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1046 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1048 u
.expr
.v_optype
= p_optype
;
1049 u
.expr
.state
= EXPR_NOT_CHECKED
;
1051 case OPTYPE_REPLACE
:
1052 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1059 FATAL_ERROR("Value::Value()");
1064 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1065 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1067 u
.expr
.v_optype
= p_optype
;
1068 u
.expr
.state
= EXPR_NOT_CHECKED
;
1071 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1077 FATAL_ERROR("Value::Value()");
1082 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1083 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1085 u
.expr
.v_optype
=p_optype
;
1086 u
.expr
.state
=EXPR_NOT_CHECKED
;
1089 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1095 FATAL_ERROR("Value::Value()");
1100 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1101 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1103 u
.expr
.v_optype
=p_optype
;
1104 u
.expr
.state
=EXPR_NOT_CHECKED
;
1107 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1113 FATAL_ERROR("Value::Value()");
1118 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1119 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1121 u
.expr
.v_optype
= p_optype
;
1122 u
.expr
.state
= EXPR_NOT_CHECKED
;
1125 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1130 FATAL_ERROR("Value::Value()");
1135 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1137 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1139 u
.expr
.v_optype
= p_optype
;
1140 u
.expr
.state
= EXPR_NOT_CHECKED
;
1142 case OPTYPE_ISCHOSEN
:
1143 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1148 FATAL_ERROR("Value::Value()");
1152 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1153 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1155 u
.expr
.v_optype
= p_optype
;
1156 u
.expr
.state
= EXPR_NOT_CHECKED
;
1158 case OPTYPE_LOG2STR
:
1159 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1160 u
.expr
.logargs
= p_logargs
;
1163 FATAL_ERROR("Value::Value()");
1167 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1168 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1170 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1171 switch (p_macrotype
) {
1172 case MACRO_MODULEID
:
1173 case MACRO_FILENAME
:
1174 case MACRO_BFILENAME
:
1175 case MACRO_FILEPATH
:
1176 case MACRO_LINENUMBER
:
1177 case MACRO_LINENUMBER_C
:
1178 case MACRO_DEFINITIONID
:
1180 case MACRO_TESTCASEID
:
1183 FATAL_ERROR("Value::Value()");
1185 u
.macro
= p_macrotype
;
1188 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1189 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1191 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1198 FATAL_ERROR("Value::Value()");
1202 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1203 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1205 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1209 u
.ref
.refd_last
= 0;
1215 FATAL_ERROR("Value::Value()");
1219 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1220 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1222 if(!p_block
) FATAL_ERROR("NULL parameter");
1228 FATAL_ERROR("Value::Value()");
1232 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1233 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1235 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1236 switch (p_verdict
) {
1239 case Verdict_INCONC
:
1244 FATAL_ERROR("Value::Value()");
1246 u
.verdict
= p_verdict
;
1249 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1250 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1252 u
.expr
.v_optype
= p_optype
;
1253 u
.expr
.state
= EXPR_NOT_CHECKED
;
1256 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1261 FATAL_ERROR("Value::Value()");
1270 Value
*Value::clone() const
1272 return new Value(*this);
1275 Value::operationtype_t
Value::get_optype() const
1277 if(valuetype
!=V_EXPR
)
1278 FATAL_ERROR("Value::get_optype()");
1279 return u
.expr
.v_optype
;
1282 void Value::set_my_governor(Type
*p_gov
)
1285 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1289 Type
*Value::get_my_governor() const
1294 void Value::set_fullname(const string
& p_fullname
)
1296 GovernedSimple::set_fullname(p_fullname
);
1299 u
.char_syms
->set_fullname(p_fullname
);
1303 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1304 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1307 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1308 u
.choice
.alt_name
->get_dispname());
1313 u
.val_vs
->set_fullname(p_fullname
);
1317 u
.val_nvs
->set_fullname(p_fullname
);
1320 u
.ref
.ref
->set_fullname(p_fullname
);
1323 u
.refered
->set_fullname(p_fullname
);
1326 u
.invoke
.v
->set_fullname(p_fullname
);
1327 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1328 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1331 set_fullname_expr(p_fullname
);
1338 void Value::set_my_scope(Scope
*p_scope
)
1340 GovernedSimple::set_my_scope(p_scope
);
1343 u
.char_syms
->set_my_scope(p_scope
);
1347 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1348 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1351 u
.choice
.alt_value
->set_my_scope(p_scope
);
1356 u
.val_vs
->set_my_scope(p_scope
);
1360 u
.val_nvs
->set_my_scope(p_scope
);
1363 u
.ref
.ref
->set_my_scope(p_scope
);
1366 u
.refered
->set_my_scope(p_scope
);
1369 u
.invoke
.v
->set_my_scope(p_scope
);
1370 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1371 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1374 set_my_scope_expr(p_scope
);
1381 void Value::set_fullname_expr(const string
& p_fullname
)
1383 switch (u
.expr
.v_optype
) {
1384 case OPTYPE_RND
: // -
1385 case OPTYPE_COMP_NULL
:
1386 case OPTYPE_COMP_MTC
:
1387 case OPTYPE_COMP_SYSTEM
:
1388 case OPTYPE_COMP_SELF
:
1389 case OPTYPE_COMP_RUNNING_ANY
:
1390 case OPTYPE_COMP_RUNNING_ALL
:
1391 case OPTYPE_COMP_ALIVE_ANY
:
1392 case OPTYPE_COMP_ALIVE_ALL
:
1393 case OPTYPE_TMR_RUNNING_ANY
:
1394 case OPTYPE_GETVERDICT
:
1395 case OPTYPE_TESTCASENAME
:
1396 case OPTYPE_PROF_RUNNING
:
1398 case OPTYPE_UNARYPLUS
: // v1
1399 case OPTYPE_UNARYMINUS
:
1402 case OPTYPE_BIT2HEX
:
1403 case OPTYPE_BIT2INT
:
1404 case OPTYPE_BIT2OCT
:
1405 case OPTYPE_BIT2STR
:
1406 case OPTYPE_CHAR2INT
:
1407 case OPTYPE_CHAR2OCT
:
1408 case OPTYPE_COMP_RUNNING
:
1409 case OPTYPE_COMP_ALIVE
:
1410 case OPTYPE_FLOAT2INT
:
1411 case OPTYPE_FLOAT2STR
:
1412 case OPTYPE_HEX2BIT
:
1413 case OPTYPE_HEX2INT
:
1414 case OPTYPE_HEX2OCT
:
1415 case OPTYPE_HEX2STR
:
1416 case OPTYPE_INT2CHAR
:
1417 case OPTYPE_INT2FLOAT
:
1418 case OPTYPE_INT2STR
:
1419 case OPTYPE_INT2UNICHAR
:
1420 case OPTYPE_OCT2BIT
:
1421 case OPTYPE_OCT2CHAR
:
1422 case OPTYPE_OCT2HEX
:
1423 case OPTYPE_OCT2INT
:
1424 case OPTYPE_OCT2STR
:
1425 case OPTYPE_STR2BIT
:
1426 case OPTYPE_STR2FLOAT
:
1427 case OPTYPE_STR2HEX
:
1428 case OPTYPE_STR2INT
:
1429 case OPTYPE_STR2OCT
:
1430 case OPTYPE_UNICHAR2INT
:
1431 case OPTYPE_UNICHAR2CHAR
:
1432 case OPTYPE_ENUM2INT
:
1433 case OPTYPE_RNDWITHVAL
:
1434 case OPTYPE_REMOVE_BOM
:
1435 case OPTYPE_GET_STRINGENCODING
:
1436 case OPTYPE_DECODE_BASE64
:
1437 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1439 case OPTYPE_ADD
: // v1 v2
1440 case OPTYPE_SUBTRACT
:
1441 case OPTYPE_MULTIPLY
:
1462 case OPTYPE_INT2BIT
:
1463 case OPTYPE_INT2HEX
:
1464 case OPTYPE_INT2OCT
:
1465 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1466 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1468 case OPTYPE_UNICHAR2OCT
:
1469 case OPTYPE_OCT2UNICHAR
:
1470 case OPTYPE_ENCODE_BASE64
:
1471 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1472 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1475 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1476 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1479 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1480 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1481 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1484 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1485 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1486 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1488 case OPTYPE_DECOMP
: // v1 v2 v3
1489 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1490 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1491 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1493 case OPTYPE_REPLACE
:
1494 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1495 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1496 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1497 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1499 case OPTYPE_LENGTHOF
: // ti1
1500 case OPTYPE_SIZEOF
: // ti1
1501 case OPTYPE_VALUEOF
: // ti1
1502 case OPTYPE_ISVALUE
:
1503 case OPTYPE_ISBOUND
:
1505 case OPTYPE_ISPRESENT
:
1506 case OPTYPE_TTCN2STRING
:
1507 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1509 case OPTYPE_UNDEF_RUNNING
: // r1
1510 case OPTYPE_TMR_READ
:
1511 case OPTYPE_TMR_RUNNING
:
1512 case OPTYPE_ACTIVATE
:
1513 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1515 case OPTYPE_EXECUTE
: // r1 [v2]
1516 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1517 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1519 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1520 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1521 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1522 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1524 case OPTYPE_MATCH
: // v1 t2
1525 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1526 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1528 case OPTYPE_ISCHOSEN
: // r1 i2
1529 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1531 case OPTYPE_ISCHOSEN_V
: // v1 i2
1532 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1534 case OPTYPE_ISCHOSEN_T
: // t1 i2
1535 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1537 case OPTYPE_ACTIVATE_REFD
:
1538 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1539 if(u
.expr
.state
!=EXPR_CHECKED
)
1540 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1542 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1544 case OPTYPE_EXECUTE_REFD
:
1545 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1546 if(u
.expr
.state
!=EXPR_CHECKED
)
1547 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1549 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1551 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1553 case OPTYPE_LOG2STR
:
1554 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1557 FATAL_ERROR("Value::set_fullname_expr()");
1561 void Value::set_my_scope_expr(Scope
*p_scope
)
1563 switch (u
.expr
.v_optype
) {
1564 case OPTYPE_RND
: // -
1565 case OPTYPE_COMP_NULL
:
1566 case OPTYPE_COMP_MTC
:
1567 case OPTYPE_COMP_SYSTEM
:
1568 case OPTYPE_COMP_SELF
:
1569 case OPTYPE_COMP_RUNNING_ANY
:
1570 case OPTYPE_COMP_RUNNING_ALL
:
1571 case OPTYPE_COMP_ALIVE_ANY
:
1572 case OPTYPE_COMP_ALIVE_ALL
:
1573 case OPTYPE_TMR_RUNNING_ANY
:
1574 case OPTYPE_GETVERDICT
:
1575 case OPTYPE_TESTCASENAME
:
1576 case OPTYPE_PROF_RUNNING
:
1578 case OPTYPE_UNARYPLUS
: // v1
1579 case OPTYPE_UNARYMINUS
:
1582 case OPTYPE_BIT2HEX
:
1583 case OPTYPE_BIT2INT
:
1584 case OPTYPE_BIT2OCT
:
1585 case OPTYPE_BIT2STR
:
1586 case OPTYPE_CHAR2INT
:
1587 case OPTYPE_CHAR2OCT
:
1588 case OPTYPE_COMP_RUNNING
:
1589 case OPTYPE_COMP_ALIVE
:
1590 case OPTYPE_FLOAT2INT
:
1591 case OPTYPE_FLOAT2STR
:
1592 case OPTYPE_HEX2BIT
:
1593 case OPTYPE_HEX2INT
:
1594 case OPTYPE_HEX2OCT
:
1595 case OPTYPE_HEX2STR
:
1596 case OPTYPE_INT2CHAR
:
1597 case OPTYPE_INT2FLOAT
:
1598 case OPTYPE_INT2STR
:
1599 case OPTYPE_INT2UNICHAR
:
1600 case OPTYPE_OCT2BIT
:
1601 case OPTYPE_OCT2CHAR
:
1602 case OPTYPE_OCT2HEX
:
1603 case OPTYPE_OCT2INT
:
1604 case OPTYPE_OCT2STR
:
1605 case OPTYPE_STR2BIT
:
1606 case OPTYPE_STR2FLOAT
:
1607 case OPTYPE_STR2HEX
:
1608 case OPTYPE_STR2INT
:
1609 case OPTYPE_STR2OCT
:
1610 case OPTYPE_UNICHAR2INT
:
1611 case OPTYPE_UNICHAR2CHAR
:
1612 case OPTYPE_ENUM2INT
:
1613 case OPTYPE_RNDWITHVAL
:
1614 case OPTYPE_REMOVE_BOM
:
1615 case OPTYPE_GET_STRINGENCODING
:
1616 case OPTYPE_DECODE_BASE64
:
1617 u
.expr
.v1
->set_my_scope(p_scope
);
1619 case OPTYPE_ADD
: // v1 v2
1620 case OPTYPE_SUBTRACT
:
1621 case OPTYPE_MULTIPLY
:
1642 case OPTYPE_INT2BIT
:
1643 case OPTYPE_INT2HEX
:
1644 case OPTYPE_INT2OCT
:
1645 u
.expr
.v1
->set_my_scope(p_scope
);
1646 u
.expr
.v2
->set_my_scope(p_scope
);
1648 case OPTYPE_UNICHAR2OCT
:
1649 case OPTYPE_OCT2UNICHAR
:
1650 case OPTYPE_ENCODE_BASE64
:
1651 u
.expr
.v1
->set_my_scope(p_scope
);
1652 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1655 u
.expr
.r1
->set_my_scope(p_scope
);
1656 u
.expr
.r2
->set_my_scope(p_scope
);
1659 u
.expr
.ti1
->set_my_scope(p_scope
);
1660 u
.expr
.v2
->set_my_scope(p_scope
);
1661 u
.expr
.v3
->set_my_scope(p_scope
);
1664 u
.expr
.ti1
->set_my_scope(p_scope
);
1665 u
.expr
.t2
->set_my_scope(p_scope
);
1666 u
.expr
.v3
->set_my_scope(p_scope
);
1668 case OPTYPE_DECOMP
: // v1 v2 v3
1669 u
.expr
.v1
->set_my_scope(p_scope
);
1670 u
.expr
.v2
->set_my_scope(p_scope
);
1671 u
.expr
.v3
->set_my_scope(p_scope
);
1673 case OPTYPE_REPLACE
:
1674 u
.expr
.ti1
->set_my_scope(p_scope
);
1675 u
.expr
.v2
->set_my_scope(p_scope
);
1676 u
.expr
.v3
->set_my_scope(p_scope
);
1677 u
.expr
.ti4
->set_my_scope(p_scope
);
1679 case OPTYPE_LENGTHOF
: // ti1
1680 case OPTYPE_SIZEOF
: // ti1
1681 case OPTYPE_VALUEOF
: // ti1
1682 case OPTYPE_ISVALUE
:
1683 case OPTYPE_ISBOUND
:
1685 case OPTYPE_ISPRESENT
:
1686 case OPTYPE_TTCN2STRING
:
1687 u
.expr
.ti1
->set_my_scope(p_scope
);
1689 case OPTYPE_UNDEF_RUNNING
: // r1
1690 case OPTYPE_TMR_READ
:
1691 case OPTYPE_TMR_RUNNING
:
1692 case OPTYPE_ACTIVATE
:
1693 u
.expr
.r1
->set_my_scope(p_scope
);
1695 case OPTYPE_EXECUTE
: // r1 [v2]
1696 u
.expr
.r1
->set_my_scope(p_scope
);
1697 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1699 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1700 u
.expr
.r1
->set_my_scope(p_scope
);
1701 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1702 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1704 case OPTYPE_MATCH
: // v1 t2
1705 u
.expr
.v1
->set_my_scope(p_scope
);
1706 u
.expr
.t2
->set_my_scope(p_scope
);
1708 case OPTYPE_ISCHOSEN
: // r1 i2
1709 u
.expr
.r1
->set_my_scope(p_scope
);
1711 case OPTYPE_ISCHOSEN_V
: // v1 i2
1712 u
.expr
.v1
->set_my_scope(p_scope
);
1714 case OPTYPE_ISCHOSEN_T
: // t1 i2
1715 u
.expr
.t1
->set_my_scope(p_scope
);
1717 case OPTYPE_ACTIVATE_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
);
1724 case OPTYPE_EXECUTE_REFD
:
1725 u
.expr
.v1
->set_my_scope(p_scope
);
1726 if(u
.expr
.state
!=EXPR_CHECKED
) {
1727 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1729 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1732 u
.expr
.v3
->set_my_scope(p_scope
);
1734 case OPTYPE_LOG2STR
:
1735 u
.expr
.logargs
->set_my_scope(p_scope
);
1738 FATAL_ERROR("Value::set_my_scope_expr()");
1742 void Value::set_genname_recursive(const string
& p_genname
)
1744 size_t genname_len
= p_genname
.size();
1745 if (genname_len
>= 4 &&
1746 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1747 // if the genname ends with ()() (i.e. the value stands for an optional
1748 // field) then drop the last () from the own genname, but leave it for
1749 // the embedded values
1750 set_genname(p_genname
.substr(0, genname_len
- 2));
1751 } else set_genname(p_genname
);
1754 string
embedded_genname(p_genname
);
1755 embedded_genname
+= '.';
1756 // If this is a choice value for an anytype, prepend the AT_ prefix
1757 // to the name of the alternative. The genname is used later in
1758 // Common::Value::generate_code_init_se()
1759 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1760 embedded_genname
+= "AT_";
1761 embedded_genname
+= u
.choice
.alt_name
->get_name();
1762 embedded_genname
+= "()";
1763 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1767 if (!is_indexed()) {
1768 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1769 for (size_t i
= 0; i
< nof_vs
; i
++) {
1770 string
embedded_genname(p_genname
);
1771 embedded_genname
+= '[';
1772 embedded_genname
+= Int2string(i
);
1773 embedded_genname
+= ']';
1774 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1777 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1778 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1779 string
embedded_genname(p_genname
);
1780 embedded_genname
+= '[';
1781 embedded_genname
+= Int2string(i
);
1782 embedded_genname
+= ']';
1783 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1784 ->set_genname_recursive(embedded_genname
);
1789 if (!my_governor
) return; // error recovery
1790 Type
*type
= my_governor
->get_type_refd_last();
1791 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1792 Int offset
= type
->get_dimension()->get_offset();
1793 if (!is_indexed()) {
1794 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1795 for (size_t i
= 0; i
< nof_vs
; i
++) {
1796 string
embedded_genname(p_genname
);
1797 embedded_genname
+= '[';
1798 embedded_genname
+= Int2string(offset
+ i
);
1799 embedded_genname
+= ']';
1800 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1803 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1804 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1805 string
embedded_genname(p_genname
);
1806 embedded_genname
+= '[';
1807 embedded_genname
+= Int2string(offset
+ i
);
1808 embedded_genname
+= ']';
1809 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1810 ->set_genname_recursive(embedded_genname
);
1816 if (!my_governor
) return; // error recovery
1817 Type
*t
= my_governor
->get_type_refd_last();
1818 if (!t
->is_secho()) return; // error recovery
1819 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1820 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1821 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1822 const Identifier
& id
= nv
->get_name();
1823 if (!t
->has_comp_withName(id
)) return; // error recovery
1824 string
embedded_genname(p_genname
);
1825 embedded_genname
+= '.';
1826 embedded_genname
+= id
.get_name();
1827 embedded_genname
+= "()";
1828 if (t
->get_comp_byName(id
)->get_is_optional())
1829 embedded_genname
+= "()";
1830 nv
->get_value()->set_genname_recursive(embedded_genname
);
1838 void Value::set_genname_prefix(const char *p_genname_prefix
)
1840 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1843 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1848 if (!is_indexed()) {
1849 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1850 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1852 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1853 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1854 ->set_genname_prefix(p_genname_prefix
);
1859 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1860 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1861 ->set_genname_prefix(p_genname_prefix
);
1868 void Value::set_code_section(code_section_t p_code_section
)
1870 GovernedSimple::set_code_section(p_code_section
);
1873 switch (u
.expr
.v_optype
) {
1874 case OPTYPE_RND
: // -
1875 case OPTYPE_COMP_NULL
:
1876 case OPTYPE_COMP_MTC
:
1877 case OPTYPE_COMP_SYSTEM
:
1878 case OPTYPE_COMP_SELF
:
1879 case OPTYPE_COMP_RUNNING_ANY
:
1880 case OPTYPE_COMP_RUNNING_ALL
:
1881 case OPTYPE_COMP_ALIVE_ANY
:
1882 case OPTYPE_COMP_ALIVE_ALL
:
1883 case OPTYPE_TMR_RUNNING_ANY
:
1884 case OPTYPE_GETVERDICT
:
1885 case OPTYPE_TESTCASENAME
:
1886 case OPTYPE_PROF_RUNNING
:
1888 case OPTYPE_UNARYPLUS
: // v1
1889 case OPTYPE_UNARYMINUS
:
1892 case OPTYPE_BIT2HEX
:
1893 case OPTYPE_BIT2INT
:
1894 case OPTYPE_BIT2OCT
:
1895 case OPTYPE_BIT2STR
:
1896 case OPTYPE_CHAR2INT
:
1897 case OPTYPE_CHAR2OCT
:
1898 case OPTYPE_COMP_RUNNING
:
1899 case OPTYPE_COMP_ALIVE
:
1900 case OPTYPE_FLOAT2INT
:
1901 case OPTYPE_FLOAT2STR
:
1902 case OPTYPE_HEX2BIT
:
1903 case OPTYPE_HEX2INT
:
1904 case OPTYPE_HEX2OCT
:
1905 case OPTYPE_HEX2STR
:
1906 case OPTYPE_INT2CHAR
:
1907 case OPTYPE_INT2FLOAT
:
1908 case OPTYPE_INT2STR
:
1909 case OPTYPE_INT2UNICHAR
:
1910 case OPTYPE_OCT2BIT
:
1911 case OPTYPE_OCT2CHAR
:
1912 case OPTYPE_OCT2HEX
:
1913 case OPTYPE_OCT2INT
:
1914 case OPTYPE_OCT2STR
:
1915 case OPTYPE_STR2BIT
:
1916 case OPTYPE_STR2FLOAT
:
1917 case OPTYPE_STR2HEX
:
1918 case OPTYPE_STR2INT
:
1919 case OPTYPE_STR2OCT
:
1920 case OPTYPE_UNICHAR2INT
:
1921 case OPTYPE_UNICHAR2CHAR
:
1922 case OPTYPE_ENUM2INT
:
1923 case OPTYPE_RNDWITHVAL
:
1924 case OPTYPE_GET_STRINGENCODING
:
1925 case OPTYPE_DECODE_BASE64
:
1926 case OPTYPE_REMOVE_BOM
:
1927 u
.expr
.v1
->set_code_section(p_code_section
);
1929 case OPTYPE_ADD
: // v1 v2
1930 case OPTYPE_SUBTRACT
:
1931 case OPTYPE_MULTIPLY
:
1952 case OPTYPE_INT2BIT
:
1953 case OPTYPE_INT2HEX
:
1954 case OPTYPE_INT2OCT
:
1955 u
.expr
.v1
->set_code_section(p_code_section
);
1956 u
.expr
.v2
->set_code_section(p_code_section
);
1958 case OPTYPE_UNICHAR2OCT
:
1959 case OPTYPE_OCT2UNICHAR
:
1960 case OPTYPE_ENCODE_BASE64
:
1961 u
.expr
.v1
->set_code_section(p_code_section
);
1962 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
1965 u
.expr
.r1
->set_code_section(p_code_section
);
1966 u
.expr
.r2
->set_code_section(p_code_section
);
1969 u
.expr
.ti1
->set_code_section(p_code_section
);
1970 u
.expr
.v2
->set_code_section(p_code_section
);
1971 u
.expr
.v3
->set_code_section(p_code_section
);
1974 u
.expr
.ti1
->set_code_section(p_code_section
);
1975 u
.expr
.t2
->set_code_section(p_code_section
);
1976 u
.expr
.v3
->set_code_section(p_code_section
);
1978 case OPTYPE_DECOMP
: // v1 v2 v3
1979 u
.expr
.v1
->set_code_section(p_code_section
);
1980 u
.expr
.v2
->set_code_section(p_code_section
);
1981 u
.expr
.v3
->set_code_section(p_code_section
);
1983 case OPTYPE_REPLACE
:
1984 u
.expr
.ti1
->set_code_section(p_code_section
);
1985 u
.expr
.v2
->set_code_section(p_code_section
);
1986 u
.expr
.v3
->set_code_section(p_code_section
);
1987 u
.expr
.ti4
->set_code_section(p_code_section
);
1989 case OPTYPE_LENGTHOF
: // ti1
1990 case OPTYPE_SIZEOF
: // ti1
1991 case OPTYPE_VALUEOF
: // ti1
1992 case OPTYPE_ISVALUE
:
1993 case OPTYPE_ISBOUND
:
1995 case OPTYPE_ISPRESENT
:
1996 case OPTYPE_TTCN2STRING
:
1997 u
.expr
.ti1
->set_code_section(p_code_section
);
1999 case OPTYPE_UNDEF_RUNNING
: // r1
2000 case OPTYPE_TMR_READ
:
2001 case OPTYPE_TMR_RUNNING
:
2002 case OPTYPE_ACTIVATE
:
2003 u
.expr
.r1
->set_code_section(p_code_section
);
2005 case OPTYPE_EXECUTE
: // r1 [v2]
2006 u
.expr
.r1
->set_code_section(p_code_section
);
2007 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2009 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2010 u
.expr
.r1
->set_code_section(p_code_section
);
2011 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2012 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2014 case OPTYPE_MATCH
: // v1 t2
2015 u
.expr
.v1
->set_code_section(p_code_section
);
2016 u
.expr
.t2
->set_code_section(p_code_section
);
2018 case OPTYPE_ISCHOSEN
: // r1 i2
2019 u
.expr
.r1
->set_code_section(p_code_section
);
2021 case OPTYPE_ISCHOSEN_V
: // v1 i2
2022 u
.expr
.v1
->set_code_section(p_code_section
);
2024 case OPTYPE_ISCHOSEN_T
: // t1 i2
2025 u
.expr
.t1
->set_code_section(p_code_section
);
2027 case OPTYPE_ACTIVATE_REFD
:
2028 u
.expr
.v1
->set_code_section(p_code_section
);
2029 if(u
.expr
.state
!=EXPR_CHECKED
)
2030 u
.expr
.t_list2
->set_code_section(p_code_section
);
2032 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2033 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2034 u
.expr
.state
= EXPR_CHECKED
;
2037 case OPTYPE_EXECUTE_REFD
:
2038 u
.expr
.v1
->set_code_section(p_code_section
);
2039 if(u
.expr
.state
!=EXPR_CHECKED
)
2040 u
.expr
.t_list2
->set_code_section(p_code_section
);
2042 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2043 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2044 u
.expr
.state
= EXPR_CHECKED
;
2047 u
.expr
.v3
->set_code_section(p_code_section
);
2049 case OPTYPE_LOG2STR
:
2050 u
.expr
.logargs
->set_code_section(p_code_section
);
2053 FATAL_ERROR("Value::set_code_section()");
2057 u
.choice
.alt_value
->set_code_section(p_code_section
);
2062 if (!is_indexed()) {
2063 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2064 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2066 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2067 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2072 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2073 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2074 ->set_code_section(p_code_section
);
2077 u
.ref
.ref
->set_code_section(p_code_section
);
2080 u
.refered
->set_code_section(p_code_section
);
2083 u
.invoke
.v
->set_code_section(p_code_section
);
2084 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2085 if(u
.invoke
.ap_list
)
2086 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2087 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2094 void Value::change_sign()
2098 *u
.val_Int
=-*u
.val_Int
;
2106 FATAL_ERROR("Value::change_sign()");
2110 void Value::add_oid_comp(OID_comp
* p_comp
)
2113 FATAL_ERROR("NULL parameter");
2114 u
.oid_comps
->add(p_comp
);
2115 p_comp
->set_fullname(get_fullname()+"."
2116 +Int2string(u
.oid_comps
->size()));
2117 p_comp
->set_my_scope(my_scope
);
2120 void Value::set_valuetype(valuetype_t p_valuetype
)
2122 if (valuetype
== V_ERROR
) return;
2123 else if (p_valuetype
== V_ERROR
) {
2124 if(valuetype
==V_EXPR
) {
2125 switch(u
.expr
.state
) {
2127 u
.expr
.state
=EXPR_CHECKING_ERR
;
2129 case EXPR_CHECKING_ERR
:
2136 valuetype
= V_ERROR
;
2140 case V_UNDEF_LOWERID
:
2141 switch(p_valuetype
) {
2146 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2147 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2148 u
.ref
.ref
->set_my_scope(get_my_scope());
2149 u
.ref
.ref
->set_fullname(get_fullname());
2150 u
.ref
.ref
->set_location(*this);
2151 u
.ref
.refd_last
= 0;
2154 FATAL_ERROR("Value::set_valuetype()");
2157 case V_UNDEF_BLOCK
: {
2158 Block
*t_block
=u
.block
;
2160 switch(p_valuetype
) {
2162 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2163 v
=dynamic_cast<Value
*>(node
);
2166 u
.ids
=new map
<string
, Identifier
>();
2169 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2173 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2174 v
=dynamic_cast<Value
*>(node
);
2177 u
.val_vs
=new Values();
2180 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2182 u
.val_vs
->set_my_scope(get_my_scope());
2183 u
.val_vs
->set_fullname(get_fullname());
2186 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2187 v
=dynamic_cast<Value
*>(node
);
2190 u
.val_vs
=new Values();
2193 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2195 u
.val_vs
->set_my_scope(get_my_scope());
2196 u
.val_vs
->set_fullname(get_fullname());
2199 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2200 v
=dynamic_cast<Value
*>(node
);
2203 u
.val_nvs
=new NamedValues();
2206 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2208 u
.val_nvs
->set_my_scope(get_my_scope());
2209 u
.val_nvs
->set_fullname(get_fullname());
2212 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2213 v
=dynamic_cast<Value
*>(node
);
2216 u
.val_nvs
=new NamedValues();
2219 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2221 u
.val_nvs
->set_my_scope(get_my_scope());
2222 u
.val_nvs
->set_fullname(get_fullname());
2225 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2226 v
=dynamic_cast<Value
*>(node
);
2229 u
.oid_comps
=new vector
<OID_comp
>();
2232 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2234 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2235 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2238 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2239 v
=dynamic_cast<Value
*>(node
);
2242 u
.oid_comps
=new vector
<OID_comp
>();
2245 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2247 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2248 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2251 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2252 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2255 u
.char_syms
=new CharSyms();
2257 u
.char_syms
->set_my_scope(get_my_scope());
2258 u
.char_syms
->set_fullname(get_fullname());
2261 FATAL_ERROR("Value::set_valuetype()");
2267 if (p_valuetype
== V_USTR
) {
2268 Value
*v_last
= get_value_refd_last();
2269 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2270 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2273 u
.ustr
.convert_str
= true; // will be converted back to string
2274 } else FATAL_ERROR("Value::set_valuetype()");
2277 switch(p_valuetype
) {
2279 const string
& str
= u
.char_syms
->get_string();
2281 set_val_str(new string(str
));
2284 const ustring
& ustr
= u
.char_syms
->get_ustring();
2286 set_val_ustr(new ustring(ustr
));
2287 u
.ustr
.convert_str
= false;
2289 case V_ISO2022STR
: {
2290 const string
& str
= u
.char_syms
->get_iso2022string();
2292 set_val_str(new string(str
));
2295 FATAL_ERROR("Value::set_valuetype()");
2300 if (p_valuetype
== V_REAL
)
2301 val_Real
= u
.val_Int
->to_real();
2302 else FATAL_ERROR("Value::set_valuetype()");
2304 u
.val_Real
= val_Real
;
2307 clean_up_string_elements(u
.str
.str_elements
);
2308 string
*old_str
= u
.str
.val_str
;
2309 switch(p_valuetype
) {
2311 set_val_str(hex2bit(*old_str
));
2314 set_val_str(asn_hex2oct(*old_str
));
2317 FATAL_ERROR("Value::set_valuetype()");
2322 clean_up_string_elements(u
.str
.str_elements
);
2323 if (p_valuetype
== V_OSTR
) {
2324 string
*old_str
= u
.str
.val_str
;
2325 set_val_str(asn_bit2oct(*old_str
));
2327 } else FATAL_ERROR("Value::set_valuetype()");
2330 clean_up_string_elements(u
.str
.str_elements
);
2331 switch(p_valuetype
) {
2333 string
*old_str
= u
.str
.val_str
;
2334 set_val_ustr(new ustring(*old_str
));
2335 u
.ustr
.convert_str
= true; // will be converted back to string
2342 FATAL_ERROR("Value::set_valuetype()");
2343 } // switch p_valuetype
2346 clean_up_string_elements(u
.ustr
.ustr_elements
);
2347 switch(p_valuetype
) {
2349 ustring
*old_str
= u
.ustr
.val_ustr
;
2350 size_t nof_chars
= old_str
->size();
2351 bool warning_flag
= false;
2352 for (size_t i
= 0; i
< nof_chars
; i
++) {
2353 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2354 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2355 error("This string value cannot contain multiple-byte characters, "
2356 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2357 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2359 p_valuetype
= V_ERROR
;
2361 } else if (uchar
.cell
> 127 && !warning_flag
) {
2362 warning("This string value may not contain characters with code "
2363 "higher than 127, but it has character with code %u (0x%02X) "
2364 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2365 warning_flag
= true;
2368 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2372 error("ISO-10646 string value cannot be converted to "
2374 delete u
.ustr
.val_ustr
;
2375 p_valuetype
= V_ERROR
;
2378 FATAL_ERROR("Value::set_valuetype()");
2379 } // switch p_valuetype
2382 switch (p_valuetype
) {
2384 NamedValues
*nvs
= u
.val_nvs
;
2385 if (nvs
->get_nof_nvs() < 1) {
2386 error("Union value must have one active field");
2388 valuetype
= V_ERROR
;
2390 } else if (nvs
->get_nof_nvs() > 1) {
2391 error("Only one field was expected in union value instead of %lu",
2392 (unsigned long) nvs
->get_nof_nvs());
2394 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2395 u
.choice
.alt_name
= nv
->get_name().clone();
2396 u
.choice
.alt_value
= nv
->steal_value();
2403 NamedValues
*nvs
= u
.val_nvs
;
2407 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2408 if (nvs
->has_nv_withName(id_mant
)) {
2409 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2410 ->get_value_refd_last();
2411 if (v_tmp
->get_valuetype() == V_INT
) {
2412 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2413 if (*i_mant_int
> INT_MAX
) {
2414 error("Mantissa `%s' should be less than `%d'",
2415 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2418 i_mant
= i_mant_int
->get_val();
2426 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2427 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2428 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2429 Value
*v_tmp
= v
->get_value_refd_last();
2430 if (v_tmp
->get_valuetype() == V_INT
) {
2431 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2432 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2433 v
->error("Base of the REAL must be 2 or 10");
2436 i_base
= i_base_int
->get_val();
2444 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2445 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2446 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2447 ->get_value_refd_last();
2448 if (v_tmp
->get_valuetype() == V_INT
) {
2449 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2450 if (*i_exp_int
> INT_MAX
) {
2451 error("Exponent `%s' should be less than `%d'",
2452 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2455 i_exp
= i_exp_int
->get_val();
2464 valuetype
= V_ERROR
;
2467 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2468 static_cast<double>(i_exp
));
2471 FATAL_ERROR("Value::set_valuetype()");
2475 switch (p_valuetype
) {
2477 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2478 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2479 Type
*t
= my_governor
->get_type_refd_last();
2480 switch (t
->get_typetype()) {
2485 FATAL_ERROR("Value::set_valuetype()");
2487 Values
*vals
= u
.val_vs
;
2488 size_t nof_vals
= vals
->get_nof_vs();
2489 size_t nof_comps
= t
->get_nof_comps();
2490 if (nof_vals
> nof_comps
) {
2491 error("Too many elements in value list notation for type `%s': "
2492 "%lu was expected instead of %lu",
2493 t
->get_typename().c_str(),
2494 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2498 if (nof_vals
<= nof_comps
) {
2499 upper_limit
= nof_vals
;
2502 upper_limit
= nof_comps
;
2505 u
.val_nvs
= new NamedValues
;
2506 for (size_t i
= 0; i
< upper_limit
; i
++) {
2507 Value
*v
= vals
->steal_v_byIndex(i
);
2508 if (v
->valuetype
!= V_NOTUSED
) {
2512 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2513 nv
->set_location(*v
);
2514 u
.val_nvs
->add_nv(nv
);
2516 u
.val_nvs
->set_my_scope(get_my_scope());
2517 u
.val_nvs
->set_fullname(get_fullname());
2519 if (allnotused
&& nof_vals
> 0)
2520 warning("All elements of value list notation for type `%s' are not "
2521 "used symbols (`-')", t
->get_typename().c_str());
2524 // { } -> empty set value
2525 if (u
.val_vs
->get_nof_vs() != 0)
2526 FATAL_ERROR("Value::set_valuetype()");
2528 u
.val_nvs
= new NamedValues
;
2532 // SEQOF -> SETOF or ARRAY: trivial
2535 FATAL_ERROR("Value::set_valuetype()");
2539 switch (p_valuetype
) {
2540 case V_DEFAULT_NULL
:
2545 FATAL_ERROR("Value::set_valuetype()");
2549 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2550 FATAL_ERROR("Value::set_valuetype()");
2554 FATAL_ERROR("Value::set_valuetype()");
2556 valuetype
=p_valuetype
;
2559 void Value::set_valuetype_COMP_NULL()
2561 if(valuetype
== V_ERROR
) return;
2562 if(valuetype
==V_TTCN3_NULL
) {
2564 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2565 // Nothing to check.
2566 u
.expr
.state
=EXPR_CHECKED
;
2568 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2571 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2573 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2575 u
.val_Int
= new int_val_t(p_val_int
);
2577 } else FATAL_ERROR("Value::set_valuetype()");
2580 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2582 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2586 } else FATAL_ERROR("Value::set_valuetype()");
2589 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2591 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2595 } else FATAL_ERROR("Value::set_valuetype()");
2598 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2600 switch (p_valuetype
) {
2604 if (valuetype
== V_REFER
&& p_ass
) break;
2607 FATAL_ERROR("Value::set_valuetype()");
2611 valuetype
= p_valuetype
;
2614 bool Value::is_undef_lowerid()
2616 switch (valuetype
) {
2617 case V_UNDEF_LOWERID
:
2620 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2621 !u
.expr
.ti1
->get_DerivedRef()) {
2622 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2630 const Identifier
& Value::get_undef_lowerid()
2632 switch (valuetype
) {
2633 case V_UNDEF_LOWERID
:
2636 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2637 FATAL_ERROR("Value::get_undef_lowerid()");
2638 return u
.expr
.ti1
->get_Template()->get_specific_value()
2639 ->get_undef_lowerid();
2641 FATAL_ERROR("Value::get_undef_lowerid()");
2643 const Identifier
*dummy
= 0;
2647 void Value::set_lowerid_to_ref()
2649 switch (valuetype
) {
2650 case V_UNDEF_LOWERID
:
2651 set_valuetype(V_REFD
);
2654 // if the governor of the expression is not known (in log(), etc...)
2655 // then the governor is taken from the reference (using
2656 // v1/ti1->get_expr_governor()), but that runs before the
2657 // params were checked, this smells like a workaround :)
2658 switch (u
.expr
.v_optype
) {
2661 u
.expr
.v1
->set_lowerid_to_ref();
2664 u
.expr
.v1
->set_lowerid_to_ref();
2665 u
.expr
.v2
->set_lowerid_to_ref();
2667 case OPTYPE_VALUEOF
:
2668 case OPTYPE_ISVALUE
:
2669 case OPTYPE_ISBOUND
:
2670 case OPTYPE_ISPRESENT
:
2673 case OPTYPE_REPLACE
:
2674 case OPTYPE_TTCN2STRING
:
2675 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2676 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2677 "In the operand of operation `%s'",
2679 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2681 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2682 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2683 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2684 "In the operand of operation `%s'",
2686 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2689 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2690 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2691 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2692 "In the operand of operation `%s'",
2694 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2707 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2709 switch (valuetype
) {
2717 case V_UNDEF_LOWERID
:
2724 return Type::T_UNDEF
;
2728 FATAL_ERROR("Value::get_expr_returntype()");
2730 return Type::T_ERROR
;
2733 Type
*t
= get_expr_governor(exp_val
);
2734 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2735 else return Type::T_ERROR
; }
2737 return Type::T_FUNCTION
;
2739 return Type::T_ALTSTEP
;
2741 return Type::T_TESTCASE
;
2743 switch(u
.expr
.v_optype
) {
2744 case OPTYPE_COMP_NULL
:
2745 case OPTYPE_COMP_MTC
:
2746 case OPTYPE_COMP_SYSTEM
:
2747 case OPTYPE_COMP_SELF
:
2748 case OPTYPE_COMP_CREATE
:
2749 return Type::T_COMPONENT
;
2750 case OPTYPE_UNDEF_RUNNING
:
2751 case OPTYPE_COMP_RUNNING
:
2752 case OPTYPE_COMP_RUNNING_ANY
:
2753 case OPTYPE_COMP_RUNNING_ALL
:
2754 case OPTYPE_COMP_ALIVE
:
2755 case OPTYPE_COMP_ALIVE_ANY
:
2756 case OPTYPE_COMP_ALIVE_ALL
:
2757 case OPTYPE_TMR_RUNNING
:
2758 case OPTYPE_TMR_RUNNING_ANY
:
2770 case OPTYPE_ISPRESENT
:
2771 case OPTYPE_ISCHOSEN
:
2772 case OPTYPE_ISCHOSEN_V
:
2773 case OPTYPE_ISCHOSEN_T
:
2774 case OPTYPE_ISVALUE
:
2775 case OPTYPE_ISBOUND
:
2776 case OPTYPE_PROF_RUNNING
:
2777 return Type::T_BOOL
;
2778 case OPTYPE_GETVERDICT
:
2779 return Type::T_VERDICT
;
2780 case OPTYPE_VALUEOF
: {
2781 Error_Context
cntxt(this, "In the operand of operation `%s'",
2783 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2784 case OPTYPE_TMR_READ
:
2785 case OPTYPE_INT2FLOAT
:
2786 case OPTYPE_STR2FLOAT
:
2788 case OPTYPE_RNDWITHVAL
:
2789 return Type::T_REAL
;
2790 case OPTYPE_ACTIVATE
:
2791 return Type::T_DEFAULT
;
2792 case OPTYPE_ACTIVATE_REFD
:
2793 return Type::T_DEFAULT
;
2794 case OPTYPE_EXECUTE
:
2795 case OPTYPE_EXECUTE_REFD
:
2796 return Type::T_VERDICT
;
2797 case OPTYPE_UNARYPLUS
: // v1
2798 case OPTYPE_UNARYMINUS
: {
2799 Type::typetype_t tmp_tt
;
2801 Error_Context
cntxt(this, "In the operand of operation `%s'",
2803 u
.expr
.v1
->set_lowerid_to_ref();
2804 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2811 get_value_refd_last(); // to report the error
2812 return Type::T_ERROR
;
2815 case OPTYPE_ADD
: // v1 v2
2816 case OPTYPE_SUBTRACT
:
2817 case OPTYPE_MULTIPLY
:
2818 case OPTYPE_DIVIDE
: {
2819 Type::typetype_t tmp_tt
;
2821 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2823 u
.expr
.v1
->set_lowerid_to_ref();
2824 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2831 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2832 Type::typetype_t tmp_tt2
;
2834 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2836 u
.expr
.v2
->set_lowerid_to_ref();
2837 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2839 Type::typetype_t ret_val
=Type::T_ERROR
;
2840 bool maybeconcat
=false;
2845 if(tmp_tt2
==tmp_tt
) {
2852 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2854 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2855 ret_val
=Type::T_USTR
;
2856 else ret_val
=Type::T_CSTR
;
2863 error("Did you mean the concat operation (`&') instead of"
2864 " addition operator (`+')?");
2865 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2869 get_value_refd_last(); // to report the error
2870 return Type::T_ERROR
;
2873 case OPTYPE_NOT4B
: // v1
2874 case OPTYPE_AND4B
: // v1 v2
2879 Type::typetype_t tmp_tt
;
2881 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
2882 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
2884 u
.expr
.v1
->set_lowerid_to_ref();
2885 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2893 get_value_refd_last(); // to report the error
2894 return Type::T_ERROR
;
2897 case OPTYPE_ROTL
: // v1 v2
2899 Type::typetype_t tmp_tt
;
2901 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
2902 u
.expr
.v_optype
==OPTYPE_ROTL
2903 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
2905 u
.expr
.v1
->set_lowerid_to_ref();
2906 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2919 get_value_refd_last(); // to report the error
2920 return Type::T_ERROR
;
2924 case OPTYPE_REPLACE
: {
2925 Type::typetype_t tmp_tt
;
2927 Error_Context
cntxt(this, "In the operand of operation `%s'",
2929 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2930 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2942 get_value_refd_last(); // to report the error
2943 return Type::T_ERROR
;
2946 case OPTYPE_REGEXP
: {
2947 Type::typetype_t tmp_tt
;
2949 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2951 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2952 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2959 get_value_refd_last(); // to report the error
2960 return Type::T_ERROR
;
2963 case OPTYPE_CONCAT
: { // v1 v2
2964 Type::typetype_t tmp_tt
;
2966 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2968 u
.expr
.v1
->set_lowerid_to_ref();
2969 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2981 get_value_refd_last(); // to report the error
2982 return Type::T_ERROR
;
2987 case OPTYPE_CHAR2INT
:
2988 case OPTYPE_UNICHAR2INT
:
2989 case OPTYPE_BIT2INT
:
2990 case OPTYPE_HEX2INT
:
2991 case OPTYPE_OCT2INT
:
2992 case OPTYPE_STR2INT
:
2993 case OPTYPE_FLOAT2INT
:
2994 case OPTYPE_LENGTHOF
:
2997 case OPTYPE_ENUM2INT
:
2999 case OPTYPE_BIT2STR
:
3000 case OPTYPE_FLOAT2STR
:
3001 case OPTYPE_HEX2STR
:
3002 case OPTYPE_INT2CHAR
:
3003 case OPTYPE_INT2STR
:
3004 case OPTYPE_OCT2CHAR
:
3005 case OPTYPE_OCT2STR
:
3006 case OPTYPE_UNICHAR2CHAR
:
3007 case OPTYPE_LOG2STR
:
3008 case OPTYPE_TESTCASENAME
:
3009 case OPTYPE_TTCN2STRING
:
3010 case OPTYPE_GET_STRINGENCODING
:
3011 case OPTYPE_ENCODE_BASE64
:
3012 return Type::T_CSTR
;
3013 case OPTYPE_INT2UNICHAR
:
3014 case OPTYPE_OCT2UNICHAR
:
3015 return Type::T_USTR
;
3016 case OPTYPE_INT2BIT
:
3017 case OPTYPE_HEX2BIT
:
3018 case OPTYPE_OCT2BIT
:
3019 case OPTYPE_STR2BIT
:
3021 return Type::T_BSTR
;
3022 case OPTYPE_INT2HEX
:
3023 case OPTYPE_BIT2HEX
:
3024 case OPTYPE_OCT2HEX
:
3025 case OPTYPE_STR2HEX
:
3026 return Type::T_HSTR
;
3027 case OPTYPE_INT2OCT
:
3028 case OPTYPE_CHAR2OCT
:
3029 case OPTYPE_HEX2OCT
:
3030 case OPTYPE_BIT2OCT
:
3031 case OPTYPE_STR2OCT
:
3032 case OPTYPE_UNICHAR2OCT
:
3033 case OPTYPE_REMOVE_BOM
:
3034 case OPTYPE_DECODE_BASE64
:
3035 return Type::T_OSTR
;
3039 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3041 return Type::T_ERROR
;
3045 case MACRO_MODULEID
:
3046 case MACRO_FILENAME
:
3047 case MACRO_BFILENAME
:
3048 case MACRO_FILEPATH
:
3049 case MACRO_LINENUMBER
:
3050 case MACRO_DEFINITIONID
:
3052 case MACRO_TESTCASEID
:
3053 return Type::T_CSTR
;
3054 case MACRO_LINENUMBER_C
:
3057 return Type::T_ERROR
;
3060 return Type::T_NULL
;
3062 return Type::T_BOOL
;
3066 return Type::T_REAL
;
3068 return Type::T_ENUM_T
;
3070 return Type::T_BSTR
;
3072 return Type::T_HSTR
;
3074 return Type::T_OSTR
;
3076 return Type::T_CSTR
;
3078 return Type::T_USTR
;
3080 return Type::T_GENERALSTRING
;
3084 return Type::T_ROID
;
3086 return Type::T_VERDICT
;
3087 case V_DEFAULT_NULL
:
3088 return Type::T_DEFAULT
;
3090 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3092 return Type::T_ERROR
;
3096 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3098 if(my_governor
) return my_governor
;
3099 switch (valuetype
) {
3101 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3103 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3104 u
.invoke
.v
->error("A value of type function expected");
3107 t
= t
->get_type_refd_last();
3108 switch(t
->get_typetype()) {
3109 case Type::T_FUNCTION
: {
3110 Type
*t_return_type
= t
->get_function_return_type();
3111 if (!t_return_type
) {
3112 error("Reference to a %s was expected instead of invocation "
3113 "of behavior type `%s' with no return type",
3114 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3115 t
->get_fullname().c_str());
3118 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3119 error("Reference to a value was expected, but functions of type "
3120 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3121 t_return_type
->get_typename().c_str());
3124 return t_return_type
; }
3125 case Type::T_ALTSTEP
:
3128 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3129 t
->get_typename().c_str());
3134 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3136 if (!ass
) goto error
;
3137 switch (ass
->get_asstype()) {
3138 case Assignment::A_CONST
:
3139 case Assignment::A_EXT_CONST
:
3140 case Assignment::A_MODULEPAR
:
3141 case Assignment::A_MODULEPAR_TEMP
:
3142 case Assignment::A_TEMPLATE
:
3143 case Assignment::A_VAR
:
3144 case Assignment::A_VAR_TEMPLATE
:
3145 case Assignment::A_FUNCTION_RVAL
:
3146 case Assignment::A_FUNCTION_RTEMP
:
3147 case Assignment::A_EXT_FUNCTION_RVAL
:
3148 case Assignment::A_EXT_FUNCTION_RTEMP
:
3149 case Assignment::A_PAR_VAL_IN
:
3150 case Assignment::A_PAR_VAL_OUT
:
3151 case Assignment::A_PAR_VAL_INOUT
:
3152 case Assignment::A_PAR_TEMPL_IN
:
3153 case Assignment::A_PAR_TEMPL_OUT
:
3154 case Assignment::A_PAR_TEMPL_INOUT
:
3155 tmp_type
=ass
->get_Type();
3157 case Assignment::A_FUNCTION
:
3158 case Assignment::A_EXT_FUNCTION
:
3159 error("Reference to a %s was expected instead of a call of %s, which "
3160 "does not have return type",
3161 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3162 ass
->get_description().c_str());
3165 error("Reference to a %s was expected instead of %s",
3166 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3167 ass
->get_description().c_str());
3170 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3171 if(!tmp_type
) goto error
;
3174 switch (u
.expr
.v_optype
) {
3175 case OPTYPE_VALUEOF
:
3178 case OPTYPE_REPLACE
:{
3179 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3180 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3181 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3186 return u
.expr
.v1
->get_expr_governor(exp_val
);
3188 return get_expr_governor_v1v2(exp_val
);
3189 case OPTYPE_COMP_MTC
:
3190 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3192 case OPTYPE_COMP_SYSTEM
:
3193 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3195 case OPTYPE_COMP_SELF
:
3197 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3198 if (t_ros
) return t_ros
->get_component_type();
3201 case OPTYPE_COMP_CREATE
:
3202 return chk_expr_operand_comptyperef_create();
3208 return Type::get_pooltype(get_expr_returntype(exp_val
));
3211 set_valuetype(V_ERROR
);
3215 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3217 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3218 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3220 if (v2_gov
) { // both have governors
3221 // return the type that is compatible with both (if there is no type mismatch)
3222 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3225 } else return v1_gov
;
3226 } else { // v1 has no governor
3227 if (v2_gov
) return v2_gov
;
3228 else return NULL
; // neither has governor
3232 Type
*Value::get_expr_governor_last()
3234 Value
*v_last
= get_value_refd_last();
3235 if (v_last
->valuetype
== V_ERROR
) return 0;
3236 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3238 return t
->get_type_refd_last();
3241 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3243 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3244 return u
.invoke
.v
->get_expr_governor(exp_val
);
3247 const char* Value::get_opname() const
3249 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3250 switch(u
.expr
.v_optype
) {
3251 case OPTYPE_RND
: // -
3253 case OPTYPE_COMP_NULL
:
3254 return "(component) null";
3255 case OPTYPE_COMP_MTC
:
3257 case OPTYPE_COMP_SYSTEM
:
3259 case OPTYPE_COMP_SELF
:
3261 case OPTYPE_COMP_RUNNING_ANY
:
3262 return "any component.running";
3263 case OPTYPE_COMP_RUNNING_ALL
:
3264 return "all component.running";
3265 case OPTYPE_COMP_ALIVE_ANY
:
3266 return "any component.alive";
3267 case OPTYPE_COMP_ALIVE_ALL
:
3268 return "all component.alive";
3269 case OPTYPE_TMR_RUNNING_ANY
:
3270 return "any timer.running";
3271 case OPTYPE_GETVERDICT
:
3272 return "getverdict()";
3273 case OPTYPE_TESTCASENAME
:
3274 return "testcasename()";
3275 case OPTYPE_UNARYPLUS
: // v1
3277 case OPTYPE_UNARYMINUS
:
3283 case OPTYPE_BIT2HEX
:
3285 case OPTYPE_BIT2INT
:
3287 case OPTYPE_BIT2OCT
:
3289 case OPTYPE_BIT2STR
:
3291 case OPTYPE_CHAR2INT
:
3292 return "char2int()";
3293 case OPTYPE_CHAR2OCT
:
3294 return "char2oct()";
3295 case OPTYPE_FLOAT2INT
:
3296 return "float2int()";
3297 case OPTYPE_FLOAT2STR
:
3298 return "float2str()";
3299 case OPTYPE_HEX2BIT
:
3301 case OPTYPE_HEX2INT
:
3303 case OPTYPE_HEX2OCT
:
3305 case OPTYPE_HEX2STR
:
3307 case OPTYPE_INT2CHAR
:
3308 return "int2char()";
3309 case OPTYPE_INT2FLOAT
:
3310 return "int2float()";
3311 case OPTYPE_INT2STR
:
3313 case OPTYPE_INT2UNICHAR
:
3314 return "int2unichar()";
3315 case OPTYPE_OCT2BIT
:
3317 case OPTYPE_OCT2CHAR
:
3318 return "oct2char()";
3319 case OPTYPE_OCT2HEX
:
3321 case OPTYPE_OCT2INT
:
3323 case OPTYPE_OCT2STR
:
3325 case OPTYPE_STR2BIT
:
3327 case OPTYPE_STR2FLOAT
:
3328 return "str2float()";
3329 case OPTYPE_STR2HEX
:
3331 case OPTYPE_STR2INT
:
3333 case OPTYPE_STR2OCT
:
3335 case OPTYPE_UNICHAR2INT
:
3336 return "unichar2int()";
3337 case OPTYPE_UNICHAR2CHAR
:
3338 return "unichar2char()";
3339 case OPTYPE_UNICHAR2OCT
:
3340 return "unichar2oct()";
3341 case OPTYPE_ENUM2INT
:
3342 return "enum2int()";
3343 case OPTYPE_LENGTHOF
:
3344 return "lengthof()";
3347 case OPTYPE_RNDWITHVAL
:
3348 return "rnd (seed)";
3350 return "encvalue()";
3352 return "decvalue()";
3353 case OPTYPE_GET_STRINGENCODING
:
3354 return "get_stringencoding()";
3355 case OPTYPE_REMOVE_BOM
:
3356 return "remove_bom()";
3357 case OPTYPE_ENCODE_BASE64
:
3358 return "encode_base64()";
3359 case OPTYPE_DECODE_BASE64
:
3360 return "decode_base64()";
3361 case OPTYPE_ADD
: // v1 v2
3363 case OPTYPE_SUBTRACT
:
3365 case OPTYPE_MULTIPLY
:
3407 case OPTYPE_INT2BIT
:
3409 case OPTYPE_INT2HEX
:
3411 case OPTYPE_INT2OCT
:
3413 case OPTYPE_OCT2UNICHAR
:
3414 return "oct2unichar()";
3421 case OPTYPE_REPLACE
:
3423 case OPTYPE_VALUEOF
: // t1
3425 case OPTYPE_UNDEF_RUNNING
:
3426 return "<timer or component> running";
3427 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3429 case OPTYPE_COMP_RUNNING
: // v1
3430 return "component running";
3431 case OPTYPE_COMP_ALIVE
: // v1
3433 case OPTYPE_TMR_READ
:
3434 return "timer read";
3435 case OPTYPE_TMR_RUNNING
:
3436 return "timer running";
3437 case OPTYPE_ACTIVATE
:
3438 return "activate()";
3439 case OPTYPE_ACTIVATE_REFD
:
3440 return "activate()";
3441 case OPTYPE_EXECUTE
: // r1 [v2]
3442 case OPTYPE_EXECUTE_REFD
:
3444 case OPTYPE_MATCH
: // v1 t2
3446 case OPTYPE_ISPRESENT
:
3447 return "ispresent()";
3448 case OPTYPE_ISCHOSEN
:
3449 case OPTYPE_ISCHOSEN_V
:
3450 case OPTYPE_ISCHOSEN_T
:
3451 return "ischosen()";
3452 case OPTYPE_ISVALUE
:
3454 case OPTYPE_ISBOUND
:
3456 case OPTYPE_LOG2STR
:
3458 case OPTYPE_TTCN2STRING
:
3459 return "ttcn2string()";
3460 case OPTYPE_PROF_RUNNING
:
3461 return "@profiler.running";
3463 FATAL_ERROR("Value::get_opname()");
3467 void Value::chk_expr_ref_ischosen()
3469 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3470 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3471 Assignment
*ass
=tmpref
->get_refd_assignment();
3473 set_valuetype(V_ERROR
);
3476 // Now we know whether the argument of ischosen() is a value or template.
3477 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3478 // or template (OPTYPE_ISCHOSEN_T).
3479 switch (ass
->get_asstype()) {
3480 case Assignment::A_CONST
:
3481 case Assignment::A_EXT_CONST
:
3482 case Assignment::A_MODULEPAR
:
3483 case Assignment::A_VAR
:
3484 case Assignment::A_PAR_VAL_IN
:
3485 case Assignment::A_PAR_VAL_OUT
:
3486 case Assignment::A_PAR_VAL_INOUT
:
3487 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3488 u
.expr
.v1
->set_location(*tmpref
);
3489 u
.expr
.v1
->set_my_scope(get_my_scope());
3490 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3491 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3493 case Assignment::A_MODULEPAR_TEMP
:
3494 case Assignment::A_TEMPLATE
:
3495 case Assignment::A_VAR_TEMPLATE
:
3496 case Assignment::A_PAR_TEMPL_IN
:
3497 case Assignment::A_PAR_TEMPL_OUT
:
3498 case Assignment::A_PAR_TEMPL_INOUT
:
3499 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3500 u
.expr
.t1
->set_location(*tmpref
);
3501 u
.expr
.t1
->set_my_scope(get_my_scope());
3502 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3503 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3506 tmpref
->error("Reference to a value or template was expected instead of "
3507 "%s", ass
->get_description().c_str());
3508 set_valuetype(V_ERROR
);
3513 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3514 Type::expected_value_t exp_val
)
3516 v
->set_lowerid_to_ref(); // can only be reference to enum
3517 Type
*t
= v
->get_expr_governor(exp_val
);
3518 if (v
->valuetype
==V_ERROR
) return;
3520 v
->error("Please use reference to an enumerated value as the operand of "
3521 "operation `%s'", get_opname());
3522 set_valuetype(V_ERROR
);
3525 t
= t
->get_type_refd_last();
3526 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3527 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3528 set_valuetype(V_ERROR
);
3530 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3531 v
->error("The operand of operation `%s' cannot be omit", opname
);
3532 set_valuetype(V_ERROR
);
3536 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3539 const Location
*loc
)
3541 if(tt
==Type::T_BOOL
) return;
3542 if(tt
!=Type::T_ERROR
)
3543 loc
->error("%s operand of operation `%s' should be boolean value",
3545 set_valuetype(V_ERROR
);
3548 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3551 const Location
*loc
)
3553 if(tt
==Type::T_INT
) return;
3554 if(tt
!=Type::T_ERROR
)
3555 loc
->error("%s operand of operation `%s' should be integer value",
3557 set_valuetype(V_ERROR
);
3560 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3563 const Location
*loc
)
3565 if(tt
==Type::T_REAL
) return;
3566 else if(tt
==Type::T_INT
)
3567 loc
->error("%s operand of operation `%s' should be float value."
3568 " Perhaps you missed an int2float() conversion function"
3569 " or `.0' at the end of the number",
3571 else if(tt
!=Type::T_ERROR
)
3572 loc
->error("%s operand of operation `%s' should be float value",
3574 set_valuetype(V_ERROR
);
3577 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3580 const Location
*loc
)
3589 if(tt
!=Type::T_ERROR
)
3590 loc
->error("%s operand of operation `%s' should be integer"
3593 set_valuetype(V_ERROR
);
3596 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3599 const Location
*loc
)
3604 case Type::T_ENUM_T
:
3609 if(tt
!=Type::T_ERROR
)
3610 loc
->error("%s operand of operation `%s' should be integer, float"
3611 " or enumerated value", opnum
, opname
);
3612 set_valuetype(V_ERROR
);
3615 void Value::chk_expr_operandtype_list(Type
* t
,
3618 const Location
*loc
,
3621 if (valuetype
== V_ERROR
) return;
3622 if (t
->get_typetype() == Type::T_ERROR
) {
3623 set_valuetype(V_ERROR
);
3626 if (!t
->is_list_type(allow_array
)) {
3627 loc
->error("%s operand of operation `%s' should be a string, "
3628 "`record of'%s `set of'%s value", opnum
, opname
,
3629 allow_array
? "," : " or", allow_array
? " or array" : "");
3630 set_valuetype(V_ERROR
);
3633 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3634 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3637 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3638 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3639 if (info
.is_subtype_error()) {
3641 if (info
.needs_conversion()) set_needs_conversion();
3643 if (!info
.is_erroneous()) {
3644 error("%s operand of operation `%s' is of type `%s', but a value of "
3645 "type `%s' was expected here", opnum
, opname
,
3646 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3648 error("%s", info
.get_error_str_str().c_str());
3651 if (info
.needs_conversion())
3652 set_needs_conversion();
3656 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3659 const Location
*loc
)
3671 if(tt
!=Type::T_ERROR
)
3672 loc
->error("%s operand of operation `%s' should be string value",
3674 set_valuetype(V_ERROR
);
3677 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3680 const Location
*loc
)
3689 if(tt
!=Type::T_ERROR
)
3690 loc
->error("%s operand of operation `%s' should be (universal)"
3691 " charstring value",
3693 set_valuetype(V_ERROR
);
3696 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3699 const Location
*loc
)
3701 if(tt
==Type::T_CSTR
) return;
3702 if(tt
!=Type::T_ERROR
)
3703 loc
->error("%s operand of operation `%s' should be charstring value",
3705 set_valuetype(V_ERROR
);
3708 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3711 const Location
*loc
)
3721 if(tt
!=Type::T_ERROR
)
3722 loc
->error("%s operand of operation `%s' should be binary string value",
3724 set_valuetype(V_ERROR
);
3727 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3730 const Location
*loc
)
3732 if(tt
==Type::T_BSTR
) return;
3733 if(tt
!=Type::T_ERROR
)
3734 loc
->error("%s operand of operation `%s' should be bitstring value",
3736 set_valuetype(V_ERROR
);
3739 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3742 const Location
*loc
)
3744 if(tt
==Type::T_HSTR
) return;
3745 if(tt
!=Type::T_ERROR
)
3746 loc
->error("%s operand of operation `%s' should be hexstring value",
3748 set_valuetype(V_ERROR
);
3751 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3754 const Location
*loc
)
3756 if(tt
==Type::T_OSTR
) return;
3757 if(tt
!=Type::T_ERROR
)
3758 loc
->error("%s operand of operation `%s' should be octetstring value",
3760 set_valuetype(V_ERROR
);
3763 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3764 Type::typetype_t tt2
,
3767 if(valuetype
==V_ERROR
) return;
3768 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3769 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3770 set_valuetype(V_ERROR
);
3773 if(tt1
==tt2
) return;
3774 error("The operands of operation `%s' should be of same type", opname
);
3775 set_valuetype(V_ERROR
);
3778 /* For predefined functions. */
3779 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3780 Type::typetype_t tt2
,
3785 if(valuetype
==V_ERROR
) return;
3786 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3787 set_valuetype(V_ERROR
);
3790 if(tt1
==tt2
) return;
3791 error("The %s and %s operands of operation `%s' should be of same type",
3792 opnum1
, opnum2
, opname
);
3793 set_valuetype(V_ERROR
);
3796 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3797 Value
*v1
, Value
*v2
,
3802 if (valuetype
== V_ERROR
) return;
3803 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3804 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3805 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3807 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3808 set_valuetype(V_ERROR
);
3811 if (tt1
== Type::T_UNDEF
) {
3812 if (tt2
== Type::T_UNDEF
) {
3813 if (v1
->is_undef_lowerid()) {
3814 if (v2
->is_undef_lowerid()) {
3815 Scope
*scope
= get_my_scope();
3816 Module
*my_mod
= scope
->get_scope_mod();
3817 const Identifier
& id1
= v1
->get_undef_lowerid();
3818 if (scope
->has_ass_withId(id1
)
3819 || my_mod
->has_imported_ass_withId(id1
)) {
3820 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3821 * should examine this situation better, but now I suppose
3822 * the first is ref, not enum. */
3823 v1
->set_lowerid_to_ref();
3826 const Identifier
& id2
= v2
->get_undef_lowerid();
3827 if (scope
->has_ass_withId(id2
)
3828 || my_mod
->has_imported_ass_withId(id2
)) {
3829 v2
->set_lowerid_to_ref();
3833 /* This is perhaps enum-enum, but it has no real
3834 * significance, so this should be an error. */
3836 v1
->set_lowerid_to_ref();
3839 } else if (v2
->is_undef_lowerid()) {
3840 v2
->set_lowerid_to_ref();
3843 error("Cannot determine the type of the operands in operation `%s'",
3845 set_valuetype(V_ERROR
);
3847 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3848 v1
->set_lowerid_to_ref();
3851 /* v1 is something undefined, but not lowerid; v2 has
3852 * returntype (perhaps also governor) */
3854 } else if (tt2
== Type::T_UNDEF
) {
3855 /* but tt1 is not undef */
3856 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3857 v2
->set_lowerid_to_ref();
3860 /* v2 is something undefined, but not lowerid; v1 has
3861 * returntype (perhaps also governor) */
3865 /* Now undef_lower_id's are converted to references, or the other
3866 * value has governor; let's see the governors, if they exist. */
3867 Type
*t1
= v1
->get_expr_governor(exp_val
);
3868 Type
*t2
= v2
->get_expr_governor(exp_val
);
3871 // Both value has governor. Are they compatible? According to 7.1.2
3872 // and C.34 it's required to have the same root types for
3873 // OPTYPE_{CONCAT,REPLACE}.
3874 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
3875 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3876 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
3877 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3878 TypeChain l_chain1
, l_chain2
;
3879 TypeChain r_chain1
, r_chain2
;
3880 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
3881 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
3882 if (!compat_t1
&& !compat_t2
) {
3883 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
3884 // the subtypes don't need to be compatible here
3885 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
3886 error("The operands of operation `%s' should be of compatible "
3887 "types", get_opname());
3888 set_valuetype(V_ERROR
);
3890 if (info1
.needs_conversion() || info2
.needs_conversion()) {
3891 set_needs_conversion(); // Avoid folding.
3896 if (info1
.is_erroneous())
3897 v1
->error("%s", info1
.get_error_str_str().c_str());
3898 else if (info2
.is_erroneous())
3899 v2
->error("%s", info2
.get_error_str_str().c_str());
3900 set_valuetype(V_ERROR
);
3903 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
3904 set_needs_conversion(); // Avoid folding.
3909 v2
->set_my_governor(t1
);
3910 t1
->chk_this_value_ref(v2
);
3911 if (v2
->valuetype
== V_OMIT
) {
3912 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3914 v1
->chk_expr_omit_comparison(exp_val
);
3916 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3918 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3919 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3924 v1
->set_my_governor(t2
);
3925 t2
->chk_this_value_ref(v1
);
3926 if (v1
->valuetype
== V_OMIT
) {
3927 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3929 v2
->chk_expr_omit_comparison(exp_val
);
3931 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3933 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3934 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3938 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3939 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
3940 // Here, it cannot be that both are T_UNDEF.
3941 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3942 error("Please use reference as %s operand of operator `%s'",
3943 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
3944 set_valuetype(V_ERROR
);
3947 // Deny type compatibility if no governors found. The typetype_t must
3948 // be the same. TODO: How can this happen?
3949 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
3950 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
3951 error("The operands of operation `%s' should be of compatible types",
3953 set_valuetype(V_ERROR
);
3958 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
3959 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
3961 if(valuetype
==V_ERROR
) return;
3962 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3963 Assignment
*t_ass
= ref
->get_refd_assignment();
3964 if(!t_ass
) goto error
;
3965 switch(t_ass
->get_asstype()) {
3966 case Assignment::A_TIMER
:
3967 case Assignment::A_PAR_TIMER
:
3968 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
3969 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
3970 chk_expr_dynamic_part(exp_val
, true);
3972 case Assignment::A_CONST
:
3973 case Assignment::A_EXT_CONST
:
3974 case Assignment::A_MODULEPAR
:
3975 case Assignment::A_VAR
:
3976 case Assignment::A_FUNCTION_RVAL
:
3977 case Assignment::A_EXT_FUNCTION_RVAL
:
3978 case Assignment::A_PAR_VAL_IN
:
3979 case Assignment::A_PAR_VAL_OUT
:
3980 case Assignment::A_PAR_VAL_INOUT
: {
3981 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
3982 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
3983 val
->set_my_scope(my_scope
);
3984 val
->set_fullname(u
.expr
.r1
->get_fullname());
3985 val
->set_location(*u
.expr
.r1
);
3987 chk_expr_operand_compref(val
, opnum
, get_opname());
3988 chk_expr_dynamic_part(exp_val
, false);
3991 ref
->error("%s operand of operation `%s' should be timer or"
3992 " component reference instead of %s",
3993 opnum
, opname
, t_ass
->get_description().c_str());
3998 set_valuetype(V_ERROR
);
4001 Type
*Value::chk_expr_operand_comptyperef_create()
4003 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4004 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4005 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4006 if (!t_ass
) goto error
;
4007 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4008 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4009 Type::EXPECTED_DYNAMIC_VALUE
);
4010 if (!t_type
) goto error
;
4011 t_type
= t_type
->get_type_refd_last();
4012 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4014 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4015 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4016 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4017 u
.expr
.r1
->error("Incompatible component types: operation "
4018 "`create' should refer to `%s' instead of "
4020 my_governor_last
->get_typename().c_str(),
4021 t_type
->get_typename().c_str());
4027 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4028 "expected in operation `create' instead of `%s'",
4029 t_type
->get_typename().c_str());
4032 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4033 "instead of %s", t_ass
->get_description().c_str());
4036 set_valuetype(V_ERROR
);
4040 void Value::chk_expr_comptype_compat()
4042 if (valuetype
!= V_EXPR
)
4043 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4044 if (!my_governor
|| !my_scope
) return;
4045 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4046 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4048 switch (u
.expr
.v_optype
) {
4049 case OPTYPE_COMP_MTC
:
4050 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4052 case OPTYPE_COMP_SYSTEM
:
4053 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4055 case OPTYPE_COMP_SELF
: {
4056 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4057 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4060 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4065 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4066 error("Incompatible component types: a component reference of "
4067 "type `%s' was expected, but `%s' has type `%s'",
4068 my_governor_last
->get_typename().c_str(), get_opname(),
4069 t_comptype
->get_typename().c_str());
4070 set_valuetype(V_ERROR
);
4074 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4077 if(valuetype
== V_ERROR
) return;
4078 switch(val
->get_valuetype()) {
4080 Error_Context
cntxt(this, "In `%s' operation", opname
);
4081 Value
*v_last
= val
->get_value_refd_last();
4082 if(!v_last
) goto error
;
4083 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4085 t
= t
->get_type_refd_last();
4086 if(t
->get_typetype() != Type::T_COMPONENT
) {
4087 v_last
->error("%s operand of operation `%s': Type mismatch:"
4088 " component reference was expected instead of `%s'",
4089 opnum
, opname
, t
->get_typename().c_str());
4094 Reference
*ref
= val
->get_reference();
4095 Assignment
*t_ass
= ref
->get_refd_assignment();
4097 if (!t_ass
) goto error
;
4098 switch(t_ass
->get_asstype()) {
4099 case Assignment::A_CONST
:
4100 t_val
= t_ass
->get_Value();
4102 case Assignment::A_EXT_CONST
:
4103 case Assignment::A_MODULEPAR
:
4104 case Assignment::A_VAR
:
4105 case Assignment::A_FUNCTION_RVAL
:
4106 case Assignment::A_EXT_FUNCTION_RVAL
:
4107 case Assignment::A_PAR_VAL_IN
:
4108 case Assignment::A_PAR_VAL_OUT
:
4109 case Assignment::A_PAR_VAL_INOUT
: {
4110 Type
*t_type
=t_ass
->get_Type()
4111 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4112 if(!t_type
) goto error
;
4113 t_type
=t_type
->get_type_refd_last();
4114 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4115 ref
->error("%s operand of operation `%s': Type mismatch:"
4116 " component reference was expected instead of `%s'",
4117 opnum
, opname
, t_type
->get_typename().c_str());
4122 ref
->error("%s operand of operation `%s' should be"
4123 " component reference instead of %s",
4124 opnum
, opname
, t_ass
->get_description().c_str());
4128 ReferenceChain
refch(this, "While searching referenced value");
4129 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4131 t_val
= t_val
->get_value_refd_last();
4132 if (t_val
->valuetype
!= V_EXPR
) return;
4133 switch (t_val
->u
.expr
.v_optype
) {
4134 case OPTYPE_COMP_NULL
:
4135 ref
->error("%s operand of operation `%s' refers to `null' component "
4136 "reference", opnum
, opname
);
4138 case OPTYPE_COMP_MTC
:
4139 ref
->error("%s operand of operation `%s' refers to the component "
4140 "reference of the `mtc'", opnum
, opname
);
4142 case OPTYPE_COMP_SYSTEM
:
4143 ref
->error("%s operand of operation `%s' refers to the component "
4144 "reference of the `system'", opnum
, opname
);
4152 FATAL_ERROR("Value::chk_expr_operand_compref()");
4155 set_valuetype(V_ERROR
);
4158 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4162 if(valuetype
==V_ERROR
) return;
4163 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4164 Assignment
*t_ass
= ref
->get_refd_assignment();
4165 if(!t_ass
) goto error
;
4166 switch(t_ass
->get_asstype()) {
4167 case Assignment::A_TIMER
: {
4168 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4169 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4170 Type::EXPECTED_DYNAMIC_VALUE
);
4171 else if (ref
->get_subrefs()) {
4172 ref
->error("%s operand of operation `%s': "
4173 "Reference to single timer `%s' cannot have field or array "
4174 "sub-references", opnum
, opname
,
4175 t_ass
->get_id().get_dispname().c_str());
4179 case Assignment::A_PAR_TIMER
:
4180 if (ref
->get_subrefs()) {
4181 ref
->error("%s operand of operation `%s': "
4182 "Reference to %s cannot have field or array sub-references",
4183 opnum
, opname
, t_ass
->get_description().c_str());
4188 ref
->error("%s operand of operation `%s' should be timer"
4190 opnum
, opname
, t_ass
->get_description().c_str());
4195 set_valuetype(V_ERROR
);
4198 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4202 if(valuetype
==V_ERROR
) return;
4203 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4204 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4205 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4206 Error_Context
cntxt(this, "In `%s' operation", opname
);
4207 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4210 void Value::chk_expr_operand_activate_refd(Value
*val
,
4211 Ttcn::TemplateInstances
* t_list2
,
4212 Ttcn::ActualParList
*&parlist
,
4216 if(valuetype
==V_ERROR
) return;
4217 Error_Context
cntxt(this, "In `%s' operation", opname
);
4218 Type
*t
= val
->get_expr_governor_last();
4220 switch (t
->get_typetype()) {
4222 set_valuetype(V_ERROR
);
4224 case Type::T_ALTSTEP
: {
4225 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4226 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4230 set_valuetype(V_ERROR
);
4232 parlist
->set_fullname(get_fullname());
4233 parlist
->set_my_scope(get_my_scope());
4234 if (!fp_list
->chk_activate_argument(parlist
,
4235 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4239 error("Reference to an altstep was expected in the argument of "
4240 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4241 set_valuetype(V_ERROR
);
4244 } else set_valuetype(V_ERROR
);
4247 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4251 if(valuetype
==V_ERROR
) return;
4252 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4253 Error_Context
cntxt(this, "In `%s' operation", opname
);
4254 Assignment
*t_ass
= ref
->get_refd_assignment();
4255 bool error_flag
= false;
4257 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4258 ref
->error("Reference to a testcase was expected in the argument "
4259 "instead of %s", t_ass
->get_description().c_str());
4262 } else error_flag
= true;
4264 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4265 Value
*v_last
= val
->get_value_refd_last();
4266 switch (v_last
->valuetype
) {
4268 ttcn3float v_real
= v_last
->get_val_Real();
4270 val
->error("The testcase guard timer has negative value: `%s'",
4271 Real2string(v_real
).c_str());
4282 if (error_flag
) set_valuetype(V_ERROR
);
4285 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4286 Ttcn::TemplateInstances
* t_list2
,
4287 Ttcn::ActualParList
*&parlist
,
4292 if(valuetype
==V_ERROR
) return;
4293 Error_Context
cntxt(this, "In `%s' operation", opname
);
4294 Type
*t
= v1
->get_expr_governor_last();
4296 switch (t
->get_typetype()) {
4298 set_valuetype(V_ERROR
);
4300 case Type::T_TESTCASE
: {
4301 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4302 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4306 set_valuetype(V_ERROR
);
4308 parlist
->set_fullname(get_fullname());
4309 parlist
->set_my_scope(get_my_scope());
4313 v1
->error("Reference to a value of type testcase was expected in the "
4314 "argument of `derefers()' instead of `%s'",
4315 t
->get_typename().c_str());
4316 set_valuetype(V_ERROR
);
4319 } else set_valuetype(V_ERROR
);
4321 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4322 Value
*v_last
= v3
->get_value_refd_last();
4323 switch (v_last
->valuetype
) {
4325 ttcn3float v_real
= v_last
->get_val_Real();
4327 v3
->error("The testcase guard timer has negative value: `%s'",
4328 Real2string(v_real
).c_str());
4329 set_valuetype(V_ERROR
);
4333 set_valuetype(V_ERROR
);
4341 void Value::chk_invoke(Type::expected_value_t exp_val
)
4343 if(valuetype
== V_ERROR
) return;
4344 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4345 if(!u
.invoke
.t_list
) return; //already checked
4346 Error_Context
cntxt(this, "In `apply()' operation");
4347 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4349 set_valuetype(V_ERROR
);
4352 switch (t
->get_typetype()) {
4354 set_valuetype(V_ERROR
);
4356 case Type::T_FUNCTION
:
4359 u
.invoke
.v
->error("A value of type function was expected in the "
4360 "argument instead of `%s'", t
->get_typename().c_str());
4361 set_valuetype(V_ERROR
);
4364 my_scope
->chk_runs_on_clause(t
, *this, "call");
4365 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4366 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4367 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4368 delete u
.invoke
.t_list
;
4369 u
.invoke
.t_list
= 0;
4372 u
.invoke
.ap_list
= 0;
4374 parlist
->set_fullname(get_fullname());
4375 parlist
->set_my_scope(get_my_scope());
4376 u
.invoke
.ap_list
= parlist
;
4379 case Type::EXPECTED_CONSTANT
:
4380 error("An evaluable constant value was expected instead of operation "
4382 set_valuetype(V_ERROR
);
4384 case Type::EXPECTED_STATIC_VALUE
:
4385 error("A static value was expected instead of operation `apply()'");
4386 set_valuetype(V_ERROR
);
4393 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4394 ReferenceChain
*refch
,
4395 Type::expected_value_t exp_val
)
4397 bool self_ref
= false;
4398 if(valuetype
==V_ERROR
) return;
4399 // Commented out to report more errors :)
4400 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4401 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4402 switch(val
->get_valuetype()) {
4404 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4409 val
->get_value_refd_last(refch
, exp_val
);
4414 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4419 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4420 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4422 bool self_ref
= false;
4424 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4425 ti
->error("Reference to a %s value was expected instead of an in-line "
4426 "modified template",
4427 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4428 set_valuetype(V_ERROR
);
4431 Template
*templ
= ti
->get_Template();
4432 switch (templ
->get_templatetype()) {
4433 case Template::TEMPLATE_REFD
:
4435 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4436 templ
= templ
->get_template_refd_last(refch
);
4437 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4438 set_valuetype(V_ERROR
);
4440 ti
->error("Reference to a %s value was expected instead of %s",
4441 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4442 templ
->get_reference()->get_refd_assignment()
4443 ->get_description().c_str());
4444 set_valuetype(V_ERROR
);
4447 case Template::SPECIFIC_VALUE
: {
4448 Value
*val
= templ
->get_specific_value();
4449 switch (val
->get_valuetype()) {
4451 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4454 val
->get_value_refd_last(refch
, exp_val
);
4458 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4460 case Template::TEMPLATE_ERROR
:
4461 set_valuetype(V_ERROR
);
4470 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4473 if(valuetype
==V_ERROR
) return;
4474 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4475 if(val
->is_unfoldable()) return;
4476 if(*val
->get_val_Int()<0) {
4477 val
->error("%s operand of operation `%s' should not be negative",
4479 set_valuetype(V_ERROR
);
4483 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4486 if(valuetype
==V_ERROR
) return;
4487 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4488 if(val
->is_unfoldable()) return;
4489 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4490 val
->error("%s operand of operation `%s' should be in range 0..127",
4492 set_valuetype(V_ERROR
);
4496 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4499 if(valuetype
==V_ERROR
) return;
4500 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4501 if(val
->is_unfoldable()) return;
4502 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4503 val
->error("%s operand of operation `%s' should be in range"
4504 " 0..2147483647", opnum
, opname
);
4505 set_valuetype(V_ERROR
);
4509 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4512 if(valuetype
==V_ERROR
) return;
4513 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4514 if(val
->is_unfoldable()) return;
4515 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4517 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4519 val
->error("%s operand of operation `%s' should not be zero",
4521 set_valuetype(V_ERROR
);
4525 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4528 if (valuetype
== V_ERROR
) return;
4529 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4530 if (val
->get_expr_returntype() != Type::T_INT
) return;
4531 if (val
->is_unfoldable()) return;
4532 const int_val_t
*val_int
= val
->get_val_Int();
4533 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4534 val
->error("%s operand of operation `%s' should be less than `%d' "
4535 "instead of `%s'", opnum
, opname
, INT_MAX
,
4536 (val_int
->t_str()).c_str());
4537 set_valuetype(V_ERROR
);
4541 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4544 if(valuetype
==V_ERROR
) return;
4545 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4546 if(val
->is_unfoldable()) return;
4547 if(val
->get_val_strlen()!=1) {
4548 val
->error("%s operand of operation `%s' should be of length 1",
4550 set_valuetype(V_ERROR
);
4554 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4557 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4558 Value
*v_last
= val
->get_value_refd_last();
4559 if (v_last
->valuetype
== V_CSTR
) {
4560 size_t len
= v_last
->get_val_strlen();
4562 val
->error("%s operand of operation `%s' should contain even number "
4563 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4564 set_valuetype(V_ERROR
);
4566 } else if (v_last
->valuetype
== V_REFD
) {
4567 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4568 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4569 val
->error("%s operand of operation `%s' should contain even number "
4570 "of characters, but a string element contains 1", opnum
, opname
);
4571 set_valuetype(V_ERROR
);
4576 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4579 if(valuetype
==V_ERROR
) return;
4580 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4581 if(val
->is_unfoldable()) return;
4582 const string
& s
=val
->get_val_str();
4583 for(size_t i
=0; i
<s
.size(); i
++) {
4585 if(!(c
=='0' || c
=='1')) {
4586 val
->error("%s operand of operation `%s' can contain only"
4587 " binary digits (position %lu is `%c')",
4588 opnum
, opname
, (unsigned long) i
, c
);
4589 set_valuetype(V_ERROR
);
4595 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4598 if(valuetype
==V_ERROR
) return;
4599 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4600 if(val
->is_unfoldable()) return;
4601 const string
& s
=val
->get_val_str();
4602 for(size_t i
=0; i
<s
.size(); i
++) {
4604 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4605 val
->error("%s operand of operation `%s' can contain only valid "
4606 "hexadecimal digits (position %lu is `%c')",
4607 opnum
, opname
, (unsigned long) i
, c
);
4608 set_valuetype(V_ERROR
);
4614 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4617 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4618 Value
*v
= val
->get_value_refd_last();
4619 if (v
->valuetype
!= V_OSTR
) return;
4620 const string
& s
= val
->get_val_str();
4621 size_t n_octets
= s
.size() / 2;
4622 for (size_t i
= 0; i
< n_octets
; i
++) {
4624 if (!(c
>= '0' && c
<= '7')) {
4625 val
->error("%s operand of operation `%s' shall consist of octets "
4626 "within the range 00 .. 7F, but the string `%s'O contains octet "
4627 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4629 set_valuetype(V_ERROR
);
4635 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4638 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4639 Value
*v_last
= val
->get_value_refd_last();
4640 if (v_last
->valuetype
!= V_CSTR
) return;
4641 const string
& s
= v_last
->get_val_str();
4642 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4644 // state: expected characters
4645 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4646 // S_FIRST: first digit
4647 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4648 // S_END: trailing whitespace
4649 // S_ERR: error was found, stop
4650 for (size_t i
= 0; i
< s
.size(); i
++) {
4655 if (c
== '+' || c
== '-') state
= S_FIRST
;
4656 else if (c
== '0') state
= S_ZERO
;
4657 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4658 else if (string::is_whitespace(c
)) {
4659 if (state
== S_INITIAL
) {
4660 val
->warning("Leading whitespace was detected and ignored in the "
4661 "operand of operation `%s'", opname
);
4662 state
= S_INITIAL_WS
;
4664 } else state
= S_ERR
;
4667 if (c
== '0') state
= S_ZERO
;
4668 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4672 if (c
>= '0' && c
<= '9') {
4673 val
->warning("Leading zero digit was detected and ignored in the "
4674 "operand of operation `%s'", opname
);
4676 } else if (string::is_whitespace(c
)) state
= S_END
;
4680 if (c
>= '0' && c
<= '9') {}
4681 else if (string::is_whitespace(c
)) state
= S_END
;
4685 if (!string::is_whitespace(c
)) state
= S_ERR
;
4690 if (state
== S_ERR
) {
4691 if (string::is_printable(c
)) {
4692 val
->error("%s operand of operation `%s' should be a string "
4693 "containing a valid integer value, but invalid character `%c' "
4694 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4696 val
->error("%s operand of operation `%s' should be a string "
4697 "containing a valid integer value, but invalid character with "
4698 "character code %u was detected at index %lu", opnum
, opname
, c
,
4701 set_valuetype(V_ERROR
);
4708 val
->error("%s operand of operation `%s' should be a string containing a "
4709 "valid integer value instead of an empty string", opnum
, opname
);
4710 set_valuetype(V_ERROR
);
4713 val
->error("%s operand of operation `%s' should be a string containing a "
4714 "valid integer value, but only a sign character was detected", opnum
,
4716 set_valuetype(V_ERROR
);
4719 val
->warning("Trailing whitespace was detected and ignored in the "
4720 "operand of operation `%s'", opname
);
4727 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4730 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4731 Value
*v_last
= val
->get_value_refd_last();
4732 if (v_last
->valuetype
== V_REFD
) {
4733 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4734 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4735 val
->error("%s operand of operation `%s' should be a string containing "
4736 "a valid float value instead of a string element, which cannot "
4737 "represent a floating point number", opnum
, opname
);
4738 set_valuetype(V_ERROR
);
4741 } else if (v_last
->valuetype
!= V_CSTR
) return;
4742 const string
& s
= v_last
->get_val_str();
4743 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4744 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4746 // state: expected characters
4747 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4748 // leading whitespace
4749 // S_FIRST_M: first digit of integer part in mantissa
4750 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4751 // S_FIRST_F: first digit of fraction
4752 // S_MORE_F: more digits of fraction, E, trailing whitespace
4753 // S_INITIAL_E: +, -, first digit of exponent
4754 // S_FIRST_E: first digit of exponent
4755 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4756 // S_END: trailing whitespace
4757 // S_ERR: error was found, stop
4758 for (size_t i
= 0; i
< s
.size(); i
++) {
4763 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4764 else if (c
== '0') state
= S_ZERO_M
;
4765 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4766 else if (string::is_whitespace(c
)) {
4767 if (state
== S_INITIAL
) {
4768 val
->warning("Leading whitespace was detected and ignored in the "
4769 "operand of operation `%s'", opname
);
4770 state
= S_INITIAL_WS
;
4772 } else state
= S_ERR
;
4775 if (c
== '0') state
= S_ZERO_M
;
4776 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4780 if (c
== '.') state
= S_FIRST_F
;
4781 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4782 else if (c
>= '0' && c
<= '9') {
4783 val
->warning("Leading zero digit was detected and ignored in the "
4784 "mantissa of the operand of operation `%s'", opname
);
4786 } else state
= S_ERR
;
4789 if (c
== '.') state
= S_FIRST_F
;
4790 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4791 else if (c
>= '0' && c
<= '9') {}
4795 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4799 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4800 else if (c
>= '0' && c
<= '9') {}
4801 else if (string::is_whitespace(c
)) state
= S_END
;
4805 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4806 else if (c
== '0') state
= S_ZERO_E
;
4807 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4811 if (c
== '0') state
= S_ZERO_E
;
4812 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4816 if (c
>= '0' && c
<= '9') {
4817 val
->warning("Leading zero digit was detected and ignored in the "
4818 "exponent of the operand of operation `%s'", opname
);
4820 } else if (string::is_whitespace(c
)) state
= S_END
;
4824 if (c
>= '0' && c
<= '9') {}
4825 else if (string::is_whitespace(c
)) state
= S_END
;
4829 if (!string::is_whitespace(c
)) state
= S_ERR
;
4834 if (state
== S_ERR
) {
4835 if (string::is_printable(c
)) {
4836 val
->error("%s operand of operation `%s' should be a string "
4837 "containing a valid float value, but invalid character `%c' "
4838 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4840 val
->error("%s operand of operation `%s' should be a string "
4841 "containing a valid float value, but invalid character with "
4842 "character code %u was detected at index %lu", opnum
, opname
, c
,
4845 set_valuetype(V_ERROR
);
4852 val
->error("%s operand of operation `%s' should be a string containing a "
4853 "valid float value instead of an empty string", opnum
, opname
);
4854 set_valuetype(V_ERROR
);
4857 val
->error("%s operand of operation `%s' should be a string containing a "
4858 "valid float value, but only a sign character was detected", opnum
,
4860 set_valuetype(V_ERROR
);
4864 // HL67862: Missing decimal dot allowed for str2float
4867 // HL67862: Missing fraction part is allowed for str2float
4871 val
->error("%s operand of operation `%s' should be a string containing a "
4872 "valid float value, but the exponent is missing after the `E' sign",
4874 set_valuetype(V_ERROR
);
4877 val
->warning("Trailing whitespace was detected and ignored in the "
4878 "operand of operation `%s'", opname
);
4885 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
4888 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4889 Value
*v
= val
->get_value_refd_last();
4890 if (v
->valuetype
!= V_USTR
) return;
4891 const ustring
& us
= v
->get_val_ustr();
4892 for (size_t i
= 0; i
< us
.size(); i
++) {
4893 const ustring::universal_char
& uchar
= us
[i
];
4894 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
4896 val
->error("%s operand of operation `%s' shall consist of characters "
4897 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4898 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4899 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
4900 uchar
.row
, uchar
.cell
, (unsigned long) i
);
4901 set_valuetype(V_ERROR
);
4907 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
4910 if(valuetype
==V_ERROR
) return;
4911 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4912 if(val
->is_unfoldable()) return;
4913 const string
& bstr
=val
->get_val_str();
4914 // see also PredefFunc.cc::bit2int()
4915 size_t nof_bits
= bstr
.size();
4916 // skip the leading zeros
4917 size_t start_index
= 0;
4918 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
4919 // check whether the remaining bits fit in Int
4920 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
4921 val
->error("%s operand of operation `%s' is too large (maximum number"
4922 " of bits in integer is %lu)",
4923 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4924 set_valuetype(V_ERROR
);
4928 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
4931 if(valuetype
==V_ERROR
) return;
4932 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4933 if(val
->is_unfoldable()) return;
4934 const string
& hstr
=val
->get_val_str();
4935 // see also PredefFunc.cc::hex2int()
4936 size_t nof_digits
= hstr
.size();
4937 // skip the leading zeros
4938 size_t start_index
= 0;
4939 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
4940 // check whether the remaining hex digits fit in Int
4941 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
4942 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
4943 char_to_hexdigit(hstr
[start_index
]) > 7)) {
4944 val
->error("%s operand of operation `%s' is too large (maximum number"
4945 " of bits in integer is %lu)",
4946 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4947 set_valuetype(V_ERROR
);
4951 void Value::chk_expr_operands_int2binstr()
4953 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4954 if (u
.expr
.v1
->is_unfoldable()) return;
4955 if (u
.expr
.v2
->is_unfoldable()) return;
4956 // It is already checked that i1 and i2 are non-negative.
4957 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4958 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
4959 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
4960 if (!i2
->is_native()) {
4961 u
.expr
.v2
->error("The length of the resulting string is too large for "
4962 "being represented in memory");
4963 set_valuetype(V_ERROR
);
4966 Int nof_bits
= i2
->get_val();
4967 if (u
.expr
.v1
->is_unfoldable()) return;
4968 switch (u
.expr
.v_optype
) {
4969 case OPTYPE_INT2BIT
:
4971 case OPTYPE_INT2HEX
:
4974 case OPTYPE_INT2OCT
:
4978 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4980 if (*i1
>> nof_bits
> 0) { // Expensive?
4981 u
.expr
.v1
->error("Value %s does not fit in length %s",
4982 i1
->t_str().c_str(), i2
->t_str().c_str());
4983 set_valuetype(V_ERROR
);
4987 void Value::chk_expr_operands_str_samelen()
4989 if(valuetype
==V_ERROR
) return;
4990 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4991 Value
*v1
=u
.expr
.v1
;
4992 if(v1
->is_unfoldable()) return;
4993 Value
*v2
=u
.expr
.v2
;
4994 if(v2
->is_unfoldable()) return;
4995 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4996 size_t i1
=v1
->get_val_strlen();
4997 size_t i2
=v2
->get_val_strlen();
4999 error("The operands should have the same length");
5000 set_valuetype(V_ERROR
);
5004 void Value::chk_expr_operands_replace()
5006 // The fourth operand doesn't need to be checked at all here.
5007 if(valuetype
==V_ERROR
) return;
5008 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5009 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5012 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5013 size_t list_len
= 0;
5014 bool list_len_known
= false;
5015 if (v1
->valuetype
== V_REFD
) {
5016 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5017 if (subrefs
&& subrefs
->refers_to_string_element()) {
5018 warning("Replacing a string element does not make any sense");
5020 list_len_known
= true;
5023 if (!v1
->is_unfoldable()) {
5024 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5025 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5026 list_len_known
= true;
5028 if (!list_len_known
) return;
5029 if (u
.expr
.v2
->is_unfoldable()) {
5030 if (!u
.expr
.v3
->is_unfoldable()) {
5031 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5032 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5033 error("Third operand `len' (%s) is greater than the length of "
5034 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5035 (unsigned long)list_len
);
5036 set_valuetype(V_ERROR
);
5040 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5041 if (u
.expr
.v3
->is_unfoldable()) {
5042 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5043 error("Second operand `index' (%s) is greater than the length of "
5044 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5045 (unsigned long)list_len
);
5046 set_valuetype(V_ERROR
);
5049 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5050 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5051 error("The sum of second operand `index' (%s) and third operand "
5052 "`len' (%s) is greater than the length of the first operand (%lu)",
5053 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5054 (unsigned long)list_len
);
5055 set_valuetype(V_ERROR
);
5061 void Value::chk_expr_operands_substr()
5063 if(valuetype
==V_ERROR
) return;
5064 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5065 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5068 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5069 size_t list_len
= 0;
5070 bool list_len_known
= false;
5071 if (v1
->valuetype
== V_REFD
) {
5072 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5073 if (subrefs
&& subrefs
->refers_to_string_element()) {
5074 warning("Taking the substring of a string element does not make any "
5077 list_len_known
= true;
5080 if (!list_len_known
&& !v1
->is_unfoldable()) {
5081 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5082 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5083 list_len_known
= true;
5085 // Do nothing if the length of the first operand is unknown.
5086 if (!list_len_known
) return;
5087 if (u
.expr
.v2
->is_unfoldable()) {
5088 if (!u
.expr
.v3
->is_unfoldable()) {
5089 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5090 // Only the third operand is known.
5091 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5092 error("Third operand `returncount' (%s) is greater than the "
5093 "length of the first operand (%lu)",
5094 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5095 set_valuetype(V_ERROR
);
5099 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5100 if (u
.expr
.v3
->is_unfoldable()) {
5101 // Only the second operand is known.
5102 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5103 error("Second operand `index' (%s) is greater than the length "
5104 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5105 (unsigned long)list_len
);
5106 set_valuetype(V_ERROR
);
5109 // Both second and third operands are known.
5110 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5111 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5112 error("The sum of second operand `index' (%s) and third operand "
5113 "`returncount' (%s) is greater than the length of the first operand "
5114 "(%lu)", (index_int_2
->t_str()).c_str(),
5115 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5116 set_valuetype(V_ERROR
);
5122 void Value::chk_expr_operands_regexp()
5124 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5125 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5126 Value
* v2
= u
.expr
.t2
->get_specific_value();
5127 if (!v1
|| !v2
) return;
5129 Error_Context
cntxt(this, "In operation `regexp()'");
5130 Value
* v1_last
= v1
->get_value_refd_last();
5131 if (v1_last
->valuetype
== V_CSTR
) {
5132 // the input string is available at compile time
5133 const string
& instr
= v1_last
->get_val_str();
5134 const char *input_str
= instr
.c_str();
5135 size_t instr_len
= strlen(input_str
);
5136 if (instr_len
< instr
.size()) {
5137 v1
->warning("The first operand of `regexp()' contains a "
5138 "character with character code zero at index %s. The rest of the "
5139 "string will be ignored during matching",
5140 Int2string(instr_len
).c_str());
5144 size_t nof_groups
= 0;
5145 Value
*v2_last
= v2
->get_value_refd_last();
5147 if (v2_last
->valuetype
== V_CSTR
) {
5148 // the pattern is available at compile time
5149 const string
& expression
= v2_last
->get_val_str();
5150 const char *pattern_str
= expression
.c_str();
5151 size_t pattern_len
= strlen(pattern_str
);
5152 if (pattern_len
< expression
.size()) {
5153 v2
->warning("The second operand of `regexp()' contains a "
5154 "character with character code zero at index %s. The rest of the "
5155 "string will be ignored during matching",
5156 Int2string(pattern_len
).c_str());
5160 Error_Context
cntxt2(v2
, "In character string pattern");
5161 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5163 if (posix_str
!= NULL
) {
5164 regex_t posix_regexp
;
5165 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5168 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5169 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5170 "regcomp() failed: %s", msg
);
5172 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5174 v2
->error("The character pattern in the second operand of "
5175 "`regexp()' does not contain any groups");
5176 set_valuetype(V_ERROR
);
5178 regfree(&posix_regexp
);
5181 // the pattern is faulty
5182 // the error has been reported by TTCN_pattern_to_regexp
5183 set_valuetype(V_ERROR
);
5186 if (nof_groups
> 0) {
5187 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5188 if (v3
->valuetype
== V_INT
) {
5189 // the group number is available at compile time
5190 const int_val_t
*groupno_int
= v3
->get_val_Int();
5191 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5192 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5193 "large: The requested group index is %s, but the pattern "
5194 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5195 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5196 set_valuetype(V_ERROR
);
5202 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5203 Type::expected_value_t exp_val
)
5205 const char *opname
= get_opname();
5206 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5208 const Location
*loc
;
5209 bool error_flag
= false;
5210 switch (u
.expr
.v_optype
) {
5211 case OPTYPE_ISCHOSEN_V
:
5212 // u.expr.v1 is always a referenced value
5213 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5215 u
.expr
.v1
->set_my_governor(t_governor
);
5216 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5217 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5218 } else error_flag
= true;
5221 case OPTYPE_ISCHOSEN_T
:
5222 // u.expr.t1 is always a referenced template
5223 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5224 exp_val
= Type::EXPECTED_TEMPLATE
;
5225 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5227 u
.expr
.t1
->set_my_governor(t_governor
);
5229 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5231 u
.expr
.t1
->get_template_refd_last(refch
);
5232 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5234 } else error_flag
= true;
5235 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5236 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5237 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5238 u
.expr
.t1
->get_reference()->get_refd_assignment()
5239 ->get_description().c_str());
5245 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5250 t_governor
= t_governor
->get_type_refd_last();
5251 switch (t_governor
->get_typetype()) {
5255 case Type::T_CHOICE_A
:
5256 case Type::T_CHOICE_T
:
5257 case Type::T_ANYTYPE
:
5258 case Type::T_OPENTYPE
:
5259 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5260 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5261 "%s does not have a field named `%s'" :
5262 "Union type `%s' does not have a field named `%s'",
5263 t_governor
->get_typename().c_str(),
5264 u
.expr
.i2
->get_dispname().c_str());
5269 loc
->error("The operand of operation `%s' should be a union value "
5270 "or template instead of `%s'", opname
,
5271 t_governor
->get_typename().c_str());
5276 if (error_flag
) set_valuetype(V_ERROR
);
5279 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5280 Type::expected_value_t exp_val
) {
5282 Error_Context
cntxt(this, "In the parameter of encvalue()");
5283 Type
t_chk(Type::T_ERROR
);
5286 Type::expected_value_t ti_exp_val
= exp_val
;
5287 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5288 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5290 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5292 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5293 if (valuetype
!=V_ERROR
)
5294 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5295 t_type
= t_type
->get_type_refd_last();
5297 error("Cannot determine type of value");
5302 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5303 error("Expecting a value of a type with coding attributes in first"
5304 "parameter of encvalue() which belongs to a generic type '%s'",
5305 t_type->get_typename().c_str());
5309 if(!disable_attribute_validation()) {
5310 t_type
->chk_coding(true);
5313 switch (t_type
->get_typetype()) {
5318 case Type::T_REFDSPEC
:
5319 case Type::T_SELTYPE
:
5320 case Type::T_VERDICT
:
5322 case Type::T_COMPONENT
:
5323 case Type::T_DEFAULT
:
5324 case Type::T_SIGNATURE
:
5325 case Type::T_FUNCTION
:
5326 case Type::T_ALTSTEP
:
5327 case Type::T_TESTCASE
:
5328 error("Type of parameter of encvalue() cannot be '%s'",
5329 t_type
->get_typename().c_str());
5336 set_valuetype(V_ERROR
);
5339 void Value::chk_expr_operands_decode()
5341 Error_Context
cntxt(this, "In the parameters of decvalue()");
5342 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5343 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5345 Assignment
* t_ass
= ref
->get_refd_assignment();
5348 error("Could not determine the assignment for first parameter");
5351 switch (t_ass
->get_asstype()) {
5352 case Assignment::A_PAR_VAL_IN
:
5353 t_ass
->use_as_lvalue(*this);
5355 case Assignment::A_CONST
:
5356 case Assignment::A_EXT_CONST
:
5357 case Assignment::A_MODULEPAR
:
5358 case Assignment::A_MODULEPAR_TEMP
:
5359 case Assignment::A_TEMPLATE
:
5360 ref
->error("Reference to '%s' cannot be used as the first operand of "
5361 "the 'decvalue' operation", t_ass
->get_assname());
5364 case Assignment::A_VAR
:
5365 case Assignment::A_PAR_VAL_OUT
:
5366 case Assignment::A_PAR_VAL_INOUT
:
5368 case Assignment::A_VAR_TEMPLATE
:
5369 case Assignment::A_PAR_TEMPL_IN
:
5370 case Assignment::A_PAR_TEMPL_OUT
:
5371 case Assignment::A_PAR_TEMPL_INOUT
: {
5372 Template
* t
= new Template(ref
->clone());
5373 t
->set_location(*ref
);
5374 t
->set_my_scope(get_my_scope());
5375 t
->set_fullname(get_fullname()+".<operand>");
5376 Template
* t_last
= t
->get_template_refd_last();
5377 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5379 ref
->error("Specific value template was expected instead of '%s'.",
5380 t
->get_template_refd_last()->get_templatetype_str());
5387 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5390 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5391 Type::EXPECTED_DYNAMIC_VALUE
);
5395 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5396 error("First parameter has to be a bitstring");
5401 t_subrefs
= ref
->get_subrefs();
5402 t_ass
= ref
->get_refd_assignment();
5405 error("Could not determine the assignment for second parameter");
5408 // Extra check for HM59355.
5409 switch (t_ass
->get_asstype()) {
5410 case Assignment::A_VAR
:
5411 case Assignment::A_PAR_VAL_IN
:
5412 case Assignment::A_PAR_VAL_OUT
:
5413 case Assignment::A_PAR_VAL_INOUT
:
5416 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5419 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5420 Type::EXPECTED_DYNAMIC_VALUE
);
5424 t_type
= t_type
->get_type_refd_last();
5425 switch (t_type
->get_typetype()) {
5430 case Type::T_REFDSPEC
:
5431 case Type::T_SELTYPE
:
5432 case Type::T_VERDICT
:
5434 case Type::T_COMPONENT
:
5435 case Type::T_DEFAULT
:
5436 case Type::T_SIGNATURE
:
5437 case Type::T_FUNCTION
:
5438 case Type::T_ALTSTEP
:
5439 case Type::T_TESTCASE
:
5440 error("Type of second parameter cannot be %s",
5441 t_type
->get_typename().c_str());
5447 if(!disable_attribute_validation()) {
5448 t_type
->chk_coding(false);
5453 set_valuetype(V_ERROR
);
5456 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5458 Ttcn::FieldOrArrayRefs
*subrefs
;
5459 Identifier
*field_id
= 0;
5462 if (valuetype
== V_ERROR
) return;
5463 else if (valuetype
!= V_REFD
) {
5464 error("Only a referenced value can be compared with `omit'");
5467 subrefs
= u
.ref
.ref
->get_subrefs();
5468 if (subrefs
) field_id
= subrefs
->remove_last_field();
5470 error("Only a reference pointing to an optional record or set field "
5471 "can be compared with `omit'");
5474 t_ass
= u
.ref
.ref
->get_refd_assignment();
5475 if (!t_ass
) goto error
;
5476 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5477 if (!t_type
) goto error
;
5478 t_type
= t_type
->get_type_refd_last();
5479 switch (t_type
->get_typetype()) {
5488 error("Only a reference pointing to an optional field of a record"
5489 " or set type can be compared with `omit'");
5492 if (!t_type
->has_comp_withName(*field_id
)) {
5493 error("Type `%s' does not have field named `%s'",
5494 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5496 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5497 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5498 "`omit'", field_id
->get_dispname().c_str(),
5499 t_type
->get_typename().c_str());
5502 // putting the last field_id back to subrefs
5503 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5506 set_valuetype(V_ERROR
);
5510 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5511 Type::expected_value_t exp_val
)
5513 if(valuetype
==V_ERROR
) return -1;
5514 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5515 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5516 exp_val
=Type::EXPECTED_TEMPLATE
;
5518 Error_Context
cntxt(this, "In the operand of"
5519 " operation `%s'", get_opname());
5522 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5525 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5528 t_templ
= t_templ
->get_template_refd_last(refch
);
5530 // Timer and port arrays are handled separately
5531 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5532 Value
* val
= t_templ
->get_specific_value();
5533 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5534 val
->set_lowerid_to_ref();
5536 if (val
&& val
->get_valuetype() == V_REFD
) {
5537 Reference
* ref
= val
->get_reference();
5538 Assignment
* t_ass
= ref
->get_refd_assignment();
5539 Common::Assignment::asstype_t asstype
=
5540 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5541 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5542 if (t_ass
->get_Dimensions()) {
5543 // here we have a timer or port array
5544 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5545 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5546 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5547 Type::EXPECTED_DYNAMIC_VALUE
);
5550 refd_dim
= t_subrefs
->get_nof_refs();
5551 size_t nof_dims
= t_dims
->get_nof_dims();
5552 if (refd_dim
>= nof_dims
) {
5553 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5554 t_ass
->get_assname());
5555 set_valuetype(V_ERROR
);
5558 } else refd_dim
= 0;
5559 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5561 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5562 t_ass
->get_description().c_str());
5563 set_valuetype(V_ERROR
);
5572 Assignment
* t_ass
= 0;
5574 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5575 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5577 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5578 t_type
= t_type
->get_type_refd_last();
5580 error("Cannot determine type of value");
5584 if(valuetype
==V_ERROR
) return -1;
5586 t_templ
= t_templ
->get_template_refd_last(refch
);
5587 switch(t_templ
->get_templatetype()) {
5588 case Template::TEMPLATE_ERROR
:
5590 case Template::INDEXED_TEMPLATE_LIST
:
5592 case Template::TEMPLATE_REFD
:
5593 case Template::TEMPLATE_LIST
:
5594 case Template::NAMED_TEMPLATE_LIST
:
5597 case Template::SPECIFIC_VALUE
:
5599 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5601 switch(t_val
->get_valuetype()) {
5611 ref
= t_val
->get_reference();
5612 t_ass
= ref
->get_refd_assignment();
5613 t_subrefs
= ref
->get_subrefs();
5617 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5618 t_val
->create_stringRepr().c_str());
5625 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5626 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5631 switch(t_ass
->get_asstype()) {
5632 case Assignment::A_ERROR
:
5634 case Assignment::A_CONST
:
5635 t_val
= t_ass
->get_Value();
5637 case Assignment::A_EXT_CONST
:
5638 case Assignment::A_MODULEPAR
:
5639 case Assignment::A_MODULEPAR_TEMP
:
5640 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5641 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5642 "expected instead of %s", t_ass
->get_description().c_str());
5646 case Assignment::A_VAR
:
5647 case Assignment::A_PAR_VAL_IN
:
5648 case Assignment::A_PAR_VAL_OUT
:
5649 case Assignment::A_PAR_VAL_INOUT
:
5651 case Type::EXPECTED_CONSTANT
:
5652 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5653 t_ass
->get_description().c_str());
5656 case Type::EXPECTED_STATIC_VALUE
:
5657 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5658 t_ass
->get_description().c_str());
5665 case Assignment::A_TEMPLATE
:
5666 t_templ
= t_ass
->get_Template();
5668 case Assignment::A_VAR_TEMPLATE
:
5669 case Assignment::A_PAR_TEMPL_IN
:
5670 case Assignment::A_PAR_TEMPL_OUT
:
5671 case Assignment::A_PAR_TEMPL_INOUT
:
5672 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5673 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5674 t_ass
->get_description().c_str());
5677 case Assignment::A_FUNCTION_RVAL
:
5678 case Assignment::A_EXT_FUNCTION_RVAL
:
5680 case Type::EXPECTED_CONSTANT
:
5681 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5682 "the return value of %s", t_ass
->get_description().c_str());
5685 case Type::EXPECTED_STATIC_VALUE
:
5686 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5687 "the return value of %s", t_ass
->get_description().c_str());
5694 case Assignment::A_FUNCTION_RTEMP
:
5695 case Assignment::A_EXT_FUNCTION_RTEMP
:
5696 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5697 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5698 " of %s, which returns a template",
5699 t_ass
->get_description().c_str());
5702 case Assignment::A_TIMER
:
5703 case Assignment::A_PORT
:
5704 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5705 // sizeof is applicable to timer and port arrays
5706 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5708 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5709 t_ass
->get_description().c_str());
5712 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5713 Type::EXPECTED_DYNAMIC_VALUE
);
5716 refd_dim
= t_subrefs
->get_nof_refs();
5717 size_t nof_dims
= t_dims
->get_nof_dims();
5718 if (refd_dim
> nof_dims
) goto error
;
5719 else if (refd_dim
== nof_dims
) {
5720 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5721 t_ass
->get_assname());
5724 } else refd_dim
= 0;
5725 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5729 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5730 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5731 t_ass
->get_description().c_str());
5735 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5736 if (!t_type
) goto error
;
5737 t_type
= t_type
->get_type_refd_last();
5739 switch(t_type
->get_typetype()) {
5756 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5757 " set, set of, objid or array was expected");
5762 // check for index overflows in subrefs if possible
5764 switch (t_val
->get_valuetype()) {
5768 if (t_val
->is_indexed()) {
5775 /* The reference points to a constant. */
5776 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5777 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5778 if (!t_val
) goto error
;
5779 t_val
=t_val
->get_value_refd_last(refch
);
5780 } else { t_val
= 0; }
5781 } else if (t_templ
) {
5782 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5783 time. Don't try to evaluate it at compile time. */
5784 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5786 /* The reference points to a static template. */
5787 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5788 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5789 if (!t_templ
) goto error
;
5790 t_templ
= t_templ
->get_template_refd_last(refch
);
5791 } else { t_templ
= 0; }
5794 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5796 switch(t_templ
->get_templatetype()) {
5797 case Template::TEMPLATE_ERROR
:
5799 case Template::TEMPLATE_REFD
:
5803 case Template::SPECIFIC_VALUE
:
5804 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5807 case Template::TEMPLATE_LIST
:
5808 case Template::NAMED_TEMPLATE_LIST
:
5811 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5812 t_templ
->get_templatetype_str(),
5813 t_templ
->get_fullname().c_str());
5818 switch(t_val
->get_valuetype()) {
5829 // error is already reported
5838 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5839 result
= t_type
->get_dimension()->get_size();
5841 else if(t_templ
) { // sizeof()
5842 switch(t_templ
->get_templatetype()) {
5843 case Template::TEMPLATE_LIST
:
5844 if(t_templ
->temps_contains_anyornone_symbol()) {
5845 if(t_templ
->is_length_restricted()) {
5846 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5847 if (lr
->get_is_range()) {
5848 Value
*v_upper
= lr
->get_upper_value();
5850 if (v_upper
->valuetype
== V_INT
) {
5852 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
5853 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
5856 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5857 "templates without exact size");
5862 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5863 "templates containing `*' without upper boundary in the "
5864 "length restriction");
5868 Value
*v_single
= lr
->get_single_value();
5869 if (v_single
->valuetype
== V_INT
)
5870 result
= v_single
->u
.val_Int
->get_val();
5873 else { // not length restricted
5874 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
5875 " containing `*' without length restriction");
5879 else result
=t_templ
->get_nof_listitems();
5881 case Template::NAMED_TEMPLATE_LIST
:
5883 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
5884 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
5885 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
5888 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5892 switch(t_val
->get_valuetype()) {
5899 result
=t_val
->get_nof_comps();
5904 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
5905 if(t_val
->get_se_comp_byIndex(i
)->get_value()
5906 ->get_valuetype()!=V_OMIT
) result
++;
5910 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5916 set_valuetype(V_ERROR
);
5920 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
5922 Type
*governor
= ti
->get_expr_governor(exp_val
);
5924 ti
->get_Template()->set_lowerid_to_ref();
5925 governor
= ti
->get_expr_governor(exp_val
);
5929 ti
->append_stringRepr( str
);
5930 ti
->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5931 "If type is known, use valuof(<type>: %s) as argument.",
5932 str
.c_str(), get_opname(), str
.c_str());
5933 set_valuetype(V_ERROR
);
5938 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
5941 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5942 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
5943 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
5944 Type::EXPECTED_TEMPLATE
: exp_val
);
5946 Template
*t_temp
= u
.expr
.t2
->get_Template();
5947 if (t_temp
->is_undef_lowerid()) {
5948 // We convert the template to reference first even if the value is also
5949 // an undef lowerid. The user can prevent this by explicit type
5951 t_temp
->set_lowerid_to_ref();
5953 } else if (u
.expr
.v1
->is_undef_lowerid()) {
5954 u
.expr
.v1
->set_lowerid_to_ref();
5959 error("Cannot determine the type of arguments in `match()' operation");
5960 set_valuetype(V_ERROR
);
5963 u
.expr
.v1
->set_my_governor(governor
);
5965 Error_Context
cntxt(this, "In the first argument of `match()'"
5967 governor
->chk_this_value_ref(u
.expr
.v1
);
5968 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
5969 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
5972 Error_Context
cntxt(this, "In the second argument of `match()' "
5974 u
.expr
.t2
->chk(governor
);
5978 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
5979 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
5981 Ttcn::StatementBlock
*my_sb
;
5983 case Type::EXPECTED_CONSTANT
:
5984 error("An evaluable constant value was expected instead of operation "
5985 "`%s'", get_opname());
5987 case Type::EXPECTED_STATIC_VALUE
:
5988 error("A static value was expected instead of operation `%s'",
5994 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5995 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
5997 error("Operation `%s' is allowed only within statements",
6001 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6002 error("Operation `%s' is not allowed in the control part",
6006 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6007 error("Operation `%s' cannot be used in a definition that has "
6008 "`runs on' clause", get_opname());
6011 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6012 error("Operation `%s' can be used only in a definition that has "
6013 "`runs on' clause", get_opname());
6018 set_valuetype(V_ERROR
);
6021 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6023 if(valuetype
==V_ERROR
) return;
6024 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6025 if(v
->is_unfoldable()) return;
6026 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6027 ttcn3float r
= v
->get_val_Real();
6028 if (isSpecialFloatValue(r
)) {
6029 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6030 opnum
, opname
, Real2string(r
).c_str());
6031 set_valuetype(V_ERROR
);
6035 void Value::chk_expr_operands(ReferenceChain
*refch
,
6036 Type::expected_value_t exp_val
)
6038 const char *first
="First", *second
="Second", *third
="Third",
6039 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6040 Value
*v1
, *v2
, *v3
;
6041 Type::typetype_t tt1
, tt2
, tt3
;
6042 Type
t_chk(Type::T_ERROR
);
6044 const char *opname
=get_opname();
6046 // first classify the unchecked ischosen() operation
6047 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6049 switch (u
.expr
.v_optype
) {
6050 case OPTYPE_COMP_NULL
:
6051 case OPTYPE_TESTCASENAME
:
6052 case OPTYPE_PROF_RUNNING
:
6054 case OPTYPE_COMP_MTC
:
6055 case OPTYPE_COMP_SYSTEM
:
6056 chk_expr_comptype_compat();
6058 case OPTYPE_RND
: // -
6059 case OPTYPE_TMR_RUNNING_ANY
:
6060 chk_expr_dynamic_part(exp_val
, true);
6062 case OPTYPE_COMP_RUNNING_ANY
:
6063 case OPTYPE_COMP_RUNNING_ALL
:
6064 case OPTYPE_COMP_ALIVE_ANY
:
6065 case OPTYPE_COMP_ALIVE_ALL
:
6066 case OPTYPE_GETVERDICT
:
6067 chk_expr_dynamic_part(exp_val
, false);
6069 case OPTYPE_COMP_SELF
:
6070 chk_expr_comptype_compat();
6071 chk_expr_dynamic_part(exp_val
, false, true, false);
6073 case OPTYPE_UNARYPLUS
: // v1
6074 case OPTYPE_UNARYMINUS
:
6077 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6078 v1
->set_lowerid_to_ref();
6079 tt1
=v1
->get_expr_returntype(exp_val
);
6080 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6081 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6087 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6088 v1
->set_lowerid_to_ref();
6089 tt1
=v1
->get_expr_returntype(exp_val
);
6090 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6091 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
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_binstr(tt1
, the
, opname
, v1
);
6101 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6104 case OPTYPE_BIT2HEX
:
6105 case OPTYPE_BIT2OCT
:
6106 case OPTYPE_BIT2STR
:
6109 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6110 v1
->set_lowerid_to_ref();
6111 tt1
=v1
->get_expr_returntype(exp_val
);
6112 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6113 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6116 case OPTYPE_BIT2INT
:
6119 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6120 v1
->set_lowerid_to_ref();
6121 tt1
=v1
->get_expr_returntype(exp_val
);
6122 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6123 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6124 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6127 case OPTYPE_CHAR2INT
:
6130 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6131 v1
->set_lowerid_to_ref();
6132 tt1
=v1
->get_expr_returntype(exp_val
);
6133 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6134 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6135 chk_expr_val_len1(v1
, the
, opname
);
6138 case OPTYPE_CHAR2OCT
:
6141 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6142 v1
->set_lowerid_to_ref();
6143 tt1
=v1
->get_expr_returntype(exp_val
);
6144 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6145 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6148 case OPTYPE_STR2INT
:
6151 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6152 v1
->set_lowerid_to_ref();
6153 tt1
=v1
->get_expr_returntype(exp_val
);
6154 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6155 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6156 chk_expr_val_str_int(v1
, the
, opname
);
6159 case OPTYPE_STR2FLOAT
:
6162 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6163 v1
->set_lowerid_to_ref();
6164 tt1
=v1
->get_expr_returntype(exp_val
);
6165 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6166 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6167 chk_expr_val_str_float(v1
, the
, opname
);
6170 case OPTYPE_STR2BIT
:
6173 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6174 v1
->set_lowerid_to_ref();
6175 tt1
=v1
->get_expr_returntype(exp_val
);
6176 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6177 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6178 chk_expr_val_str_bindigits(v1
, the
, opname
);
6181 case OPTYPE_STR2HEX
:
6184 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6185 v1
->set_lowerid_to_ref();
6186 tt1
=v1
->get_expr_returntype(exp_val
);
6187 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6188 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6189 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6192 case OPTYPE_STR2OCT
:
6195 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6196 v1
->set_lowerid_to_ref();
6197 tt1
=v1
->get_expr_returntype(exp_val
);
6198 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6199 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6200 chk_expr_val_str_len_even(v1
, the
, opname
);
6201 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6204 case OPTYPE_ENUM2INT
:
6207 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6208 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6209 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6213 chk_expr_operand_encode(refch
, exp_val
);
6215 case OPTYPE_FLOAT2INT
:
6216 case OPTYPE_FLOAT2STR
:
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 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6225 chk_expr_operand_valid_float(v1
, the
, opname
);
6228 case OPTYPE_RNDWITHVAL
:
6231 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6232 v1
->set_lowerid_to_ref();
6233 tt1
=v1
->get_expr_returntype(exp_val
);
6234 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6235 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6236 chk_expr_operand_valid_float(v1
, the
, opname
);
6238 chk_expr_dynamic_part(exp_val
, true);
6240 case OPTYPE_HEX2BIT
:
6241 case OPTYPE_HEX2OCT
:
6242 case OPTYPE_HEX2STR
:
6245 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6246 v1
->set_lowerid_to_ref();
6247 tt1
=v1
->get_expr_returntype(exp_val
);
6248 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6249 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6252 case OPTYPE_HEX2INT
:
6255 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6256 v1
->set_lowerid_to_ref();
6257 tt1
=v1
->get_expr_returntype(exp_val
);
6258 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6259 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6260 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6263 case OPTYPE_INT2CHAR
:
6266 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6267 v1
->set_lowerid_to_ref();
6268 tt1
=v1
->get_expr_returntype(exp_val
);
6269 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6270 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6271 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6274 case OPTYPE_INT2UNICHAR
:
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
);
6282 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6285 case OPTYPE_INT2FLOAT
:
6286 case OPTYPE_INT2STR
:
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_int(tt1
, the
, opname
, v1
);
6293 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6296 case OPTYPE_OCT2BIT
:
6297 case OPTYPE_OCT2HEX
:
6298 case OPTYPE_OCT2STR
:
6301 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6302 v1
->set_lowerid_to_ref();
6303 tt1
=v1
->get_expr_returntype(exp_val
);
6304 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6305 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6308 case OPTYPE_OCT2INT
:
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 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6320 case OPTYPE_OCT2CHAR
:
6323 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6324 v1
->set_lowerid_to_ref();
6325 tt1
=v1
->get_expr_returntype(exp_val
);
6326 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6327 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6328 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6331 case OPTYPE_REMOVE_BOM
:
6334 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6335 v1
->set_lowerid_to_ref();
6336 tt1
=v1
->get_expr_returntype(exp_val
);
6337 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6338 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6341 case OPTYPE_GET_STRINGENCODING
:
6344 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6345 v1
->set_lowerid_to_ref();
6346 tt1
=v1
->get_expr_returntype(exp_val
);
6347 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6348 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6351 case OPTYPE_ENCODE_BASE64
:
6354 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6355 v1
->set_lowerid_to_ref();
6356 tt1
=v1
->get_expr_returntype(exp_val
);
6357 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6358 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6360 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6363 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6364 v2
->set_lowerid_to_ref();
6365 tt2
=v2
->get_expr_returntype(exp_val
);
6366 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6367 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6370 case OPTYPE_DECODE_BASE64
:
6373 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6374 v1
->set_lowerid_to_ref();
6375 tt1
=v1
->get_expr_returntype(exp_val
);
6376 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6377 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6380 case OPTYPE_UNICHAR2INT
:
6383 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6384 v1
->set_lowerid_to_ref();
6385 tt1
=v1
->get_expr_returntype(exp_val
);
6386 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6387 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6388 chk_expr_val_len1(v1
, the
, opname
);
6391 case OPTYPE_UNICHAR2CHAR
:
6394 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6395 v1
->set_lowerid_to_ref();
6396 tt1
=v1
->get_expr_returntype(exp_val
);
6397 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6398 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6399 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6402 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6405 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6406 v1
->set_lowerid_to_ref();
6407 tt1
=v1
->get_expr_returntype(exp_val
);
6408 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6409 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6411 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6414 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6415 v2
->set_lowerid_to_ref();
6416 tt2
=v2
->get_expr_returntype(exp_val
);
6417 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6418 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6421 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6424 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6425 v1
->set_lowerid_to_ref();
6426 tt1
=v1
->get_expr_returntype(exp_val
);
6427 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6428 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6430 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6433 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6434 v2
->set_lowerid_to_ref();
6435 tt2
=v2
->get_expr_returntype(exp_val
);
6436 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6437 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6440 case OPTYPE_ADD
: // v1 v2
6441 case OPTYPE_SUBTRACT
:
6442 case OPTYPE_MULTIPLY
:
6446 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6447 v1
->set_lowerid_to_ref();
6448 tt1
=v1
->get_expr_returntype(exp_val
);
6449 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6450 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6451 chk_expr_operand_valid_float(v1
, first
, opname
);
6455 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6456 v2
->set_lowerid_to_ref();
6457 tt2
=v2
->get_expr_returntype(exp_val
);
6458 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6459 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6460 chk_expr_operand_valid_float(v2
, second
, opname
);
6461 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6462 chk_expr_val_int_float_not0(v2
, second
, opname
);
6464 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6470 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6471 v1
->set_lowerid_to_ref();
6472 tt1
=v1
->get_expr_returntype(exp_val
);
6473 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6474 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6478 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6479 v2
->set_lowerid_to_ref();
6480 tt2
=v2
->get_expr_returntype(exp_val
);
6481 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6482 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6483 chk_expr_val_int_float_not0(v2
, right
, opname
);
6486 case OPTYPE_CONCAT
: {
6489 v1
->set_lowerid_to_ref();
6490 v2
->set_lowerid_to_ref();
6491 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6493 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6494 tt1
=v1
->get_expr_returntype(exp_val
);
6495 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6496 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6499 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6500 tt2
=v2
->get_expr_returntype(exp_val
);
6501 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6502 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6504 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6505 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6506 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6507 } else { // other list types
6508 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6509 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6511 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6512 set_valuetype(V_ERROR
);
6515 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6516 v1_gov
->chk_this_value_ref(v1
);
6517 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6518 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6519 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6523 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6524 set_valuetype(V_ERROR
);
6527 // for recof/setof literals set the type from v1
6529 v2
->set_my_governor(v1_gov
);
6532 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6534 v2_gov
->chk_this_value_ref(v2
);
6535 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6536 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6537 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6538 if (valuetype
== V_ERROR
) return;
6539 // 7.1.2 says that we shouldn't allow type compatibility.
6540 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6541 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6542 error("The operands of operation `%s' should be of compatible "
6543 "types", get_opname());
6552 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6554 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6556 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6559 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6561 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6562 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6563 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6564 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6565 * "a == not b" is not allowed. (HL69107)
6566 * The various *Expressions implement operator precedence in the std.
6567 * Titan's parser has only one Expression and relies on Bison
6568 * for operator precedence. The check below brings Titan in line
6569 * with the standard by explicitly making "a == not b" an error */
6570 if (v2
->get_valuetype() == V_EXPR
6571 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6572 error("The operation `%s' is not allowed to be "
6573 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6574 set_valuetype(V_ERROR
);
6584 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6586 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6588 tt1
=v1
->get_expr_returntype(exp_val
);
6589 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6590 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6593 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6595 tt2
=v2
->get_expr_returntype(exp_val
);
6596 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6597 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6605 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6607 v1
->set_lowerid_to_ref();
6608 tt1
=v1
->get_expr_returntype(exp_val
);
6609 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6610 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6614 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6616 v2
->set_lowerid_to_ref();
6617 tt2
=v2
->get_expr_returntype(exp_val
);
6618 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6619 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6627 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6629 v1
->set_lowerid_to_ref();
6630 tt1
=v1
->get_expr_returntype(exp_val
);
6631 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6632 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6636 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6638 v2
->set_lowerid_to_ref();
6639 tt2
=v2
->get_expr_returntype(exp_val
);
6640 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6641 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6643 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6644 chk_expr_operands_str_samelen();
6650 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6651 v1
->set_lowerid_to_ref();
6652 tt1
=v1
->get_expr_returntype(exp_val
);
6653 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6654 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6658 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6659 v2
->set_lowerid_to_ref();
6660 tt2
=v2
->get_expr_returntype(exp_val
);
6661 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6662 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6663 chk_expr_val_large_int(v2
, right
, opname
);
6669 v1
->set_lowerid_to_ref();
6670 if (v1
->is_string_type(exp_val
)) {
6671 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6672 tt1
=v1
->get_expr_returntype(exp_val
);
6673 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6674 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6675 } else { // other list types
6676 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6677 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6678 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6680 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6681 v1_gov
->chk_this_value_ref(v1
);
6682 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6683 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6684 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6689 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6690 v2
->set_lowerid_to_ref();
6691 tt2
=v2
->get_expr_returntype(exp_val
);
6692 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6693 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6694 chk_expr_val_large_int(v2
, right
, opname
);
6697 case OPTYPE_INT2BIT
:
6698 case OPTYPE_INT2HEX
:
6699 case OPTYPE_INT2OCT
:
6702 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6703 v1
->set_lowerid_to_ref();
6704 tt1
=v1
->get_expr_returntype(exp_val
);
6705 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6706 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6707 chk_expr_val_int_pos0(v1
, first
, opname
);
6711 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6712 v2
->set_lowerid_to_ref();
6713 tt2
=v2
->get_expr_returntype(exp_val
);
6714 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6715 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6716 chk_expr_val_int_pos0(v2
, second
, opname
);
6718 chk_expr_operands_int2binstr();
6721 chk_expr_operands_decode();
6725 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6726 Type::expected_value_t ti_exp_val
= exp_val
;
6727 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6728 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6729 if (!governor
) return;
6730 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6731 if (valuetype
!=V_ERROR
)
6732 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6733 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6737 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6738 v2
->set_lowerid_to_ref();
6739 tt2
=v2
->get_expr_returntype(exp_val
);
6740 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6741 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6742 chk_expr_val_int_pos0(v2
, second
, opname
);
6746 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6747 v3
->set_lowerid_to_ref();
6748 tt3
=v3
->get_expr_returntype(exp_val
);
6749 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6750 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6751 chk_expr_val_int_pos0(v3
, third
, opname
);
6753 chk_expr_operands_substr();
6755 case OPTYPE_REGEXP
: {
6756 Type::expected_value_t ti_exp_val
= exp_val
;
6757 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6759 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6760 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6761 if (!governor
) return;
6762 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6763 if (valuetype
!=V_ERROR
) {
6764 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6765 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6766 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6770 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6771 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6772 if (!governor
) return;
6773 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6774 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6775 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6779 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6780 v3
->set_lowerid_to_ref();
6781 tt3
=v3
->get_expr_returntype(exp_val
);
6782 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6783 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6784 chk_expr_val_int_pos0(v3
, third
, opname
);
6786 chk_expr_operands_regexp();
6788 case OPTYPE_ISCHOSEN
:
6789 // do nothing: the operand is erroneous
6790 // the error was already reported in chk_expr_ref_ischosen()
6792 case OPTYPE_ISCHOSEN_V
: // v1 i2
6793 case OPTYPE_ISCHOSEN_T
: // t1 i2
6794 chk_expr_operands_ischosen(refch
, exp_val
);
6796 case OPTYPE_VALUEOF
: { // ti1
6797 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6798 exp_val
= Type::EXPECTED_TEMPLATE
;
6799 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6800 Type
*governor
= my_governor
;
6801 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6802 if (!governor
) return;
6803 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6804 if (valuetype
== V_ERROR
) return;
6805 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6807 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6808 case OPTYPE_ISBOUND
: {
6809 Template
*templ
= u
.expr
.ti1
->get_Template();
6810 switch (templ
->get_templatetype()) {
6811 case Template::TEMPLATE_REFD
:
6812 templ
->get_reference()->setUsedInIsbound();
6814 case Template::SPECIFIC_VALUE
: {
6815 Value
*value
= templ
->get_specific_value();
6816 if (Value::V_REFD
== value
->get_valuetype()) {
6817 value
->get_reference()->setUsedInIsbound();
6825 case OPTYPE_ISVALUE
: {// ti1
6826 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
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 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
6833 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6835 case OPTYPE_SIZEOF
: // ti1
6836 /* this checking is too complex, do the checking during eval... */
6838 case OPTYPE_LENGTHOF
: { // ti1
6839 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6840 exp_val
= Type::EXPECTED_TEMPLATE
;
6841 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6842 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6843 if (!governor
) return;
6844 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
6845 if (valuetype
== V_ERROR
) return;
6846 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6848 case OPTYPE_MATCH
: // v1 t2
6849 chk_expr_operands_match(exp_val
);
6851 case OPTYPE_UNDEF_RUNNING
: // r1
6852 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
6854 case OPTYPE_COMP_ALIVE
:
6855 case OPTYPE_COMP_RUNNING
: //v1
6856 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
6857 chk_expr_dynamic_part(exp_val
, false);
6859 case OPTYPE_TMR_READ
: // r1
6860 case OPTYPE_TMR_RUNNING
: // r1
6861 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
6862 chk_expr_dynamic_part(exp_val
, true);
6864 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
6865 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
6866 chk_expr_dynamic_part(exp_val
, true, false, false);
6868 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
6869 chk_expr_operand_comptyperef_create();
6872 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6873 v2
->set_lowerid_to_ref();
6874 tt2
=v2
->get_expr_returntype(exp_val
);
6875 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
6876 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6880 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6881 v3
->set_lowerid_to_ref();
6882 tt3
=v3
->get_expr_returntype(exp_val
);
6883 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
6884 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6886 chk_expr_dynamic_part(exp_val
, false);
6888 case OPTYPE_ACTIVATE
: // r1 // altstep
6889 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
6890 chk_expr_dynamic_part(exp_val
, true);
6892 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
6893 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6894 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
6896 delete u
.expr
.t_list2
;
6897 u
.expr
.ap_list2
= parlist
;
6898 chk_expr_dynamic_part(exp_val
, true);
6900 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
6901 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6902 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
6903 u
.expr
.v3
, the
, opname
);
6904 delete u
.expr
.t_list2
;
6905 u
.expr
.ap_list2
= parlist
;
6906 chk_expr_dynamic_part(exp_val
, true);
6909 error("Built-in function `%s' is not yet supported", opname
);
6910 set_valuetype(V_ERROR
);
6912 case OPTYPE_REPLACE
: {
6913 Type::expected_value_t ti_exp_val
= exp_val
;
6914 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6915 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6917 Error_Context
cntxt(this, "In the first operand of operation `%s'",
6919 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6920 if (!governor
) return;
6921 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6922 if (valuetype
!= V_ERROR
)
6923 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6924 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6928 Error_Context
cntxt(this, "In the second operand of operation `%s'",
6930 v2
->set_lowerid_to_ref();
6931 tt2
= v2
->get_expr_returntype(exp_val
);
6932 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6933 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6934 chk_expr_val_int_pos0(v2
, second
, opname
);
6938 Error_Context
cntxt(this, "In the third operand of operation `%s'",
6940 v3
->set_lowerid_to_ref();
6941 tt3
= v3
->get_expr_returntype(exp_val
);
6942 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6943 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6944 chk_expr_val_int_pos0(v3
, third
, opname
);
6947 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
6949 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
6950 if (!governor
) return;
6951 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
6952 if (valuetype
!= V_ERROR
)
6953 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
6954 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
6956 chk_expr_operands_replace();
6958 case OPTYPE_LOG2STR
: {
6959 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6960 u
.expr
.logargs
->chk();
6961 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
6963 case OPTYPE_TTCN2STRING
: {
6964 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
6965 Type::expected_value_t ti_exp_val
= exp_val
;
6966 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6967 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6968 if (!governor
) return;
6969 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6972 FATAL_ERROR("chk_expr_operands()");
6976 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6977 // the result of evaluating the expression. E.g. V_BOOL for
6979 void Value::evaluate_value(ReferenceChain
*refch
,
6980 Type::expected_value_t exp_val
)
6982 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
6983 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
6985 u
.expr
.state
=EXPR_CHECKING
;
6987 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
6988 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
6989 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
6991 if(valuetype
==V_ERROR
) return;
6992 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
6993 u
.expr
.state
=EXPR_CHECKED
;
6994 set_valuetype(V_ERROR
);
6998 u
.expr
.state
=EXPR_CHECKED
;
7000 Value
*v1
, *v2
, *v3
, *v4
;
7001 switch(u
.expr
.v_optype
) {
7002 case OPTYPE_RND
: // -
7003 case OPTYPE_COMP_NULL
: // the only foldable in this group
7004 case OPTYPE_COMP_MTC
:
7005 case OPTYPE_COMP_SYSTEM
:
7006 case OPTYPE_COMP_SELF
:
7007 case OPTYPE_COMP_RUNNING_ANY
:
7008 case OPTYPE_COMP_RUNNING_ALL
:
7009 case OPTYPE_COMP_ALIVE_ANY
:
7010 case OPTYPE_COMP_ALIVE_ALL
:
7011 case OPTYPE_TMR_RUNNING_ANY
:
7012 case OPTYPE_GETVERDICT
:
7013 case OPTYPE_PROF_RUNNING
:
7014 case OPTYPE_RNDWITHVAL
: // v1
7015 case OPTYPE_COMP_RUNNING
: // v1
7016 case OPTYPE_COMP_ALIVE
:
7017 case OPTYPE_TMR_READ
:
7018 case OPTYPE_TMR_RUNNING
:
7019 case OPTYPE_ACTIVATE
:
7020 case OPTYPE_ACTIVATE_REFD
:
7021 case OPTYPE_EXECUTE
: // r1 [v2]
7022 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7023 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7024 case OPTYPE_MATCH
: // v1 t2
7025 case OPTYPE_ISCHOSEN_T
:
7026 case OPTYPE_LOG2STR
:
7029 case OPTYPE_ISBOUND
:
7030 case OPTYPE_ISPRESENT
:
7031 case OPTYPE_TTCN2STRING
:
7032 case OPTYPE_UNICHAR2OCT
:
7033 case OPTYPE_OCT2UNICHAR
:
7034 case OPTYPE_ENCODE_BASE64
:
7035 case OPTYPE_DECODE_BASE64
:
7037 case OPTYPE_TESTCASENAME
: { // -
7038 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7039 Ttcn::StatementBlock
*my_sb
=
7040 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7042 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7043 if (!my_def
) { // In control part.
7044 set_val_str(new string(""));
7046 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7047 set_val_str(new string(my_def
->get_id().get_dispname()));
7051 case OPTYPE_UNARYPLUS
: // v1
7054 copy_and_destroy(v1
);
7056 case OPTYPE_UNARYMINUS
:
7057 if (is_unfoldable()) break;
7058 v1
= u
.expr
.v1
->get_value_refd_last();
7059 switch (v1
->valuetype
) {
7061 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7062 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7068 ttcn3float r
= v1
->get_val_Real();
7074 FATAL_ERROR("Value::evaluate_value()");
7078 if(is_unfoldable()) break;
7079 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7084 case OPTYPE_NOT4B
: {
7085 if(is_unfoldable()) break;
7086 v1
=u
.expr
.v1
->get_value_refd_last();
7087 const string
& s
= v1
->get_val_str();
7088 valuetype_t vt
=v1
->valuetype
;
7091 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7093 case OPTYPE_BIT2HEX
: {
7094 if(is_unfoldable()) break;
7095 v1
=u
.expr
.v1
->get_value_refd_last();
7096 const string
& s
= v1
->get_val_str();
7099 set_val_str(bit2hex(s
));
7101 case OPTYPE_BIT2OCT
: {
7102 if(is_unfoldable()) break;
7103 v1
=u
.expr
.v1
->get_value_refd_last();
7104 const string
& s
= v1
->get_val_str();
7107 set_val_str(bit2oct(s
));
7109 case OPTYPE_BIT2STR
:
7110 case OPTYPE_HEX2STR
:
7111 case OPTYPE_OCT2STR
: {
7112 if(is_unfoldable()) break;
7113 v1
=u
.expr
.v1
->get_value_refd_last();
7114 const string
& s
= v1
->get_val_str();
7117 set_val_str(new string(s
));
7119 case OPTYPE_BIT2INT
: {
7120 if (is_unfoldable()) break;
7121 v1
= u
.expr
.v1
->get_value_refd_last();
7122 const string
& s
= v1
->get_val_str();
7125 u
.val_Int
= bit2int(s
);
7127 case OPTYPE_CHAR2INT
: {
7128 if (is_unfoldable()) break;
7129 v1
= u
.expr
.v1
->get_value_refd_last();
7130 char c
= v1
->get_val_str()[0];
7133 u
.val_Int
= new int_val_t((Int
)c
);
7135 case OPTYPE_CHAR2OCT
: {
7136 if(is_unfoldable()) break;
7137 v1
=u
.expr
.v1
->get_value_refd_last();
7138 const string
& s
= v1
->get_val_str();
7141 set_val_str(char2oct(s
));
7143 case OPTYPE_STR2INT
: {
7144 if (is_unfoldable()) break;
7145 v1
= u
.expr
.v1
->get_value_refd_last();
7146 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7150 /** \todo hiba eseten lenyeli... */
7152 case OPTYPE_STR2FLOAT
: {
7153 if(is_unfoldable()) break;
7154 v1
=u
.expr
.v1
->get_value_refd_last();
7155 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7159 /** \todo hiba eseten lenyeli... */
7161 case OPTYPE_STR2BIT
: {
7162 if(is_unfoldable()) break;
7163 v1
=u
.expr
.v1
->get_value_refd_last();
7164 const string
& s
= v1
->get_val_str();
7167 set_val_str(new string(s
));
7169 case OPTYPE_STR2HEX
:
7170 case OPTYPE_OCT2HEX
: {
7171 if(is_unfoldable()) break;
7172 v1
=u
.expr
.v1
->get_value_refd_last();
7173 const string
& s
= v1
->get_val_str();
7176 set_val_str(to_uppercase(s
));
7178 case OPTYPE_STR2OCT
: {
7179 if(is_unfoldable()) break;
7180 v1
=u
.expr
.v1
->get_value_refd_last();
7181 const string
& s
= v1
->get_val_str();
7184 set_val_str(to_uppercase(s
));
7186 case OPTYPE_FLOAT2INT
: {
7187 if (is_unfoldable()) break;
7188 v1
= u
.expr
.v1
->get_value_refd_last();
7189 ttcn3float r
= v1
->get_val_Real();
7192 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7194 case OPTYPE_FLOAT2STR
: {
7195 if(is_unfoldable()) break;
7196 v1
=u
.expr
.v1
->get_value_refd_last();
7197 ttcn3float r
=v1
->get_val_Real();
7200 set_val_str(float2str(r
));
7202 case OPTYPE_HEX2BIT
:
7203 case OPTYPE_OCT2BIT
: {
7204 if(is_unfoldable()) break;
7205 v1
=u
.expr
.v1
->get_value_refd_last();
7206 const string
& s
= v1
->get_val_str();
7209 set_val_str(hex2bit(s
));
7211 case OPTYPE_HEX2INT
:
7212 case OPTYPE_OCT2INT
: {
7213 if(is_unfoldable()) break;
7214 v1
=u
.expr
.v1
->get_value_refd_last();
7215 const string
& s
= v1
->get_val_str();
7218 u
.val_Int
=hex2int(s
);
7220 case OPTYPE_HEX2OCT
: {
7221 if(is_unfoldable()) break;
7222 v1
=u
.expr
.v1
->get_value_refd_last();
7223 const string
& s
= v1
->get_val_str();
7226 set_val_str(hex2oct(s
));
7228 case OPTYPE_INT2CHAR
: {
7229 if (is_unfoldable()) break;
7230 v1
= u
.expr
.v1
->get_value_refd_last();
7231 const int_val_t
*c_int
= v1
->get_val_Int();
7232 char c
= static_cast<char>(c_int
->get_val());
7235 set_val_str(new string(1, &c
));
7237 case OPTYPE_INT2UNICHAR
: {
7238 if (is_unfoldable()) break;
7239 v1
= u
.expr
.v1
->get_value_refd_last();
7240 const int_val_t
*i_int
= v1
->get_val_Int();
7241 Int i
= i_int
->get_val();
7244 set_val_ustr(int2unichar(i
));
7245 u
.ustr
.convert_str
= false;
7247 case OPTYPE_INT2FLOAT
: {
7248 if (is_unfoldable()) break;
7249 v1
= u
.expr
.v1
->get_value_refd_last();
7250 const int_val_t
*i_int
= v1
->get_val_Int();
7251 Real i_int_real
= i_int
->to_real();
7254 u
.val_Real
= i_int_real
;
7256 case OPTYPE_INT2STR
: {
7257 if (is_unfoldable()) break;
7258 v1
= u
.expr
.v1
->get_value_refd_last();
7259 const int_val_t
*i_int
= v1
->get_val_Int();
7260 string
*i_int_str
= new string(i_int
->t_str());
7263 set_val_str(i_int_str
);
7265 case OPTYPE_OCT2CHAR
: {
7266 if(is_unfoldable()) break;
7267 v1
=u
.expr
.v1
->get_value_refd_last();
7268 const string
& s
= v1
->get_val_str();
7271 set_val_str(oct2char(s
));
7273 case OPTYPE_GET_STRINGENCODING
: {
7274 if(is_unfoldable()) break;
7275 v1
= u
.expr
.v1
->get_value_refd_last();
7276 const string
& s1
= v1
->get_val_str();
7279 set_val_str(get_stringencoding(s1
));
7281 case OPTYPE_REMOVE_BOM
: {
7282 if(is_unfoldable()) break;
7283 v1
= u
.expr
.v1
->get_value_refd_last();
7284 const string
& s1
= v1
->get_val_str();
7287 set_val_str(remove_bom(s1
));
7289 case OPTYPE_ENUM2INT
: {
7290 if(is_unfoldable()) break;
7291 v1
=u
.expr
.v1
->get_value_refd_last();
7292 Type
* enum_type
= v1
->get_my_governor();
7293 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7296 u
.val_Int
= new int_val_t(enum_val
);
7298 case OPTYPE_UNICHAR2INT
:
7299 if (is_unfoldable()) {
7300 // replace the operation with char2int() if the operand is a charstring
7301 // value to avoid its unnecessary conversion to universal charstring
7302 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7303 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7305 v1
=u
.expr
.v1
->get_value_refd_last();
7306 const ustring
& s
= v1
->get_val_ustr();
7309 u
.val_Int
=new int_val_t(unichar2int(s
));
7312 case OPTYPE_UNICHAR2CHAR
:
7314 if (is_unfoldable()) {
7315 // replace the operation with its operand if it is a charstring
7316 // value to avoid its unnecessary conversion to universal charstring
7317 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7319 copy_and_destroy(v1
);
7322 v1
= v1
->get_value_refd_last();
7323 const ustring
& s
= v1
->get_val_ustr();
7326 set_val_str(new string(s
));
7329 case OPTYPE_MULTIPLY
: { // v1 v2
7330 if (!is_unfoldable()) goto eval_arithmetic
;
7331 v1
= u
.expr
.v1
->get_value_refd_last();
7332 v2
= u
.expr
.v2
->get_value_refd_last();
7333 if (v1
->is_unfoldable()) v1
= v2
;
7334 if (v1
->is_unfoldable()) break;
7335 switch(v1
->valuetype
) {
7337 if (*v1
->get_val_Int() != 0) break;
7340 u
.val_Int
= new int_val_t((Int
)0);
7343 if (v1
->get_val_Real() != 0.0) break;
7349 FATAL_ERROR("Value::evaluate_value()");
7352 case OPTYPE_ADD
: // v1 v2
7353 case OPTYPE_SUBTRACT
:
7358 if(is_unfoldable()) break;
7359 v1
=u
.expr
.v1
->get_value_refd_last();
7360 v2
=u
.expr
.v2
->get_value_refd_last();
7361 operationtype_t ot
=u
.expr
.v_optype
;
7362 switch (v1
->valuetype
) {
7364 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7365 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7370 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7372 case OPTYPE_SUBTRACT
:
7373 u
.val_Int
= new int_val_t(*i1
- *i2
);
7375 case OPTYPE_MULTIPLY
:
7376 u
.val_Int
= new int_val_t(*i1
* *i2
);
7379 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7382 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7385 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7388 FATAL_ERROR("Value::evaluate_value()");
7394 ttcn3float r1
=v1
->get_val_Real();
7395 ttcn3float r2
=v2
->get_val_Real();
7402 case OPTYPE_SUBTRACT
:
7405 case OPTYPE_MULTIPLY
:
7412 FATAL_ERROR("Value::evaluate_value()");
7416 FATAL_ERROR("Value::evaluate_value()");
7419 case OPTYPE_CONCAT
: {
7420 if(is_unfoldable()) break;
7421 v1
=u
.expr
.v1
->get_value_refd_last();
7422 v2
=u
.expr
.v2
->get_value_refd_last();
7423 valuetype_t vt
= v1
->valuetype
;
7424 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7425 const ustring
& s1
= v1
->get_val_ustr();
7426 const ustring
& s2
= v2
->get_val_ustr();
7429 set_val_ustr(new ustring(s1
+ s2
));
7430 u
.ustr
.convert_str
= false;
7432 const string
& s1
= v1
->get_val_str();
7433 const string
& s2
= v2
->get_val_str();
7436 set_val_str(new string(s1
+ s2
));
7440 if(is_unfoldable()) break;
7441 v1
=u
.expr
.v1
->get_value_refd_last();
7442 v2
=u
.expr
.v2
->get_value_refd_last();
7449 if(is_unfoldable()) break;
7450 v1
=u
.expr
.v1
->get_value_refd_last();
7451 v2
=u
.expr
.v2
->get_value_refd_last();
7458 if(is_unfoldable()) break;
7459 v1
=u
.expr
.v1
->get_value_refd_last();
7460 v2
=u
.expr
.v2
->get_value_refd_last();
7467 if(is_unfoldable()) break;
7468 v1
=u
.expr
.v1
->get_value_refd_last();
7469 v2
=u
.expr
.v2
->get_value_refd_last();
7476 if(is_unfoldable()) break;
7477 v1
=u
.expr
.v1
->get_value_refd_last();
7478 v2
=u
.expr
.v2
->get_value_refd_last();
7485 if(is_unfoldable()) break;
7486 v1
=u
.expr
.v1
->get_value_refd_last();
7487 v2
=u
.expr
.v2
->get_value_refd_last();
7494 v1
= u
.expr
.v1
->get_value_refd_last();
7495 if (v1
->valuetype
== V_BOOL
) {
7496 if (v1
->get_val_bool()) {
7497 // the left operand is a literal "true"
7498 // substitute the expression with the right operand
7501 copy_and_destroy(v2
);
7503 // the left operand is a literal "false"
7504 // the result must be false regardless the right operand
7505 // because of the short circuit evaluation rule
7511 // we must keep the left operand because of the potential side effects
7512 // the right operand can only be eliminated if it is a literal "true"
7513 v2
= u
.expr
.v2
->get_value_refd_last();
7514 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7517 copy_and_destroy(v1
);
7522 v1
= u
.expr
.v1
->get_value_refd_last();
7523 if (v1
->valuetype
== V_BOOL
) {
7524 if (v1
->get_val_bool()) {
7525 // the left operand is a literal "true"
7526 // the result must be true regardless the right operand
7527 // because of the short circuit evaluation rule
7532 // the left operand is a literal "false"
7533 // substitute the expression with the right operand
7536 copy_and_destroy(v2
);
7539 // we must keep the left operand because of the potential side effects
7540 // the right operand can only be eliminated if it is a literal "false"
7541 v2
= u
.expr
.v2
->get_value_refd_last();
7542 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7545 copy_and_destroy(v1
);
7550 if(is_unfoldable()) break;
7551 v1
=u
.expr
.v1
->get_value_refd_last();
7552 v2
=u
.expr
.v2
->get_value_refd_last();
7553 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7558 case OPTYPE_AND4B
: {
7559 if(is_unfoldable()) break;
7560 v1
=u
.expr
.v1
->get_value_refd_last();
7561 v2
=u
.expr
.v2
->get_value_refd_last();
7562 valuetype_t vt
=v1
->valuetype
;
7563 const string
& s1
= v1
->get_val_str();
7564 const string
& s2
= v2
->get_val_str();
7567 set_val_str(and4b(s1
, s2
));
7570 if(is_unfoldable()) break;
7571 v1
=u
.expr
.v1
->get_value_refd_last();
7572 v2
=u
.expr
.v2
->get_value_refd_last();
7573 valuetype_t vt
=v1
->valuetype
;
7574 const string
& s1
= v1
->get_val_str();
7575 const string
& s2
= v2
->get_val_str();
7578 set_val_str(or4b(s1
, s2
));
7580 case OPTYPE_XOR4B
: {
7581 if(is_unfoldable()) break;
7582 v1
=u
.expr
.v1
->get_value_refd_last();
7583 v2
=u
.expr
.v2
->get_value_refd_last();
7584 valuetype_t vt
=v1
->valuetype
;
7585 const string
& s1
= v1
->get_val_str();
7586 const string
& s2
= v2
->get_val_str();
7589 set_val_str(xor4b(s1
, s2
));
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_left(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 string
& s
= v1
->get_val_str();
7610 const int_val_t
*i_int
= v2
->get_val_Int();
7611 Int i
=i_int
->get_val();
7612 if(vt
==V_OSTR
) i
*=2;
7615 set_val_str(shift_right(s
, i
));
7618 if(is_unfoldable()) break;
7619 v1
=u
.expr
.v1
->get_value_refd_last();
7620 v2
=u
.expr
.v2
->get_value_refd_last();
7621 valuetype_t vt
=v1
->valuetype
;
7622 const int_val_t
*i_int
=v2
->get_val_Int();
7623 Int i
=i_int
->get_val();
7625 const ustring
& s
= v1
->get_val_ustr();
7628 set_val_ustr(rotate_left(s
, i
));
7629 u
.ustr
.convert_str
= false;
7632 if(vt
==V_OSTR
) i
*=2;
7633 const string
& s
= v1
->get_val_str();
7636 set_val_str(rotate_left(s
, i
));
7640 if(is_unfoldable()) break;
7641 v1
=u
.expr
.v1
->get_value_refd_last();
7642 v2
=u
.expr
.v2
->get_value_refd_last();
7643 valuetype_t vt
=v1
->valuetype
;
7644 const int_val_t
*i_int
=v2
->get_val_Int();
7645 Int i
=i_int
->get_val();
7647 const ustring
& s
= v1
->get_val_ustr();
7650 set_val_ustr(rotate_right(s
, i
));
7651 u
.ustr
.convert_str
= false;
7654 if(vt
==V_OSTR
) i
*=2;
7655 const string
& s
= v1
->get_val_str();
7658 set_val_str(rotate_right(s
, i
));
7661 case OPTYPE_INT2BIT
: {
7662 if (is_unfoldable()) break;
7663 v1
= u
.expr
.v1
->get_value_refd_last();
7664 v2
= u
.expr
.v2
->get_value_refd_last();
7665 const int_val_t
*i1_int
= v1
->get_val_Int();
7666 const int_val_t
*i2_int
= v2
->get_val_Int();
7667 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7672 case OPTYPE_INT2HEX
: {
7673 if (is_unfoldable()) break;
7674 v1
= u
.expr
.v1
->get_value_refd_last();
7675 v2
= u
.expr
.v2
->get_value_refd_last();
7676 const int_val_t
*i1_int
= v1
->get_val_Int();
7677 const int_val_t
*i2_int
= v2
->get_val_Int();
7678 // Do it before the `clean_up'. i2_int is already checked.
7679 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7684 case OPTYPE_INT2OCT
: {
7685 if (is_unfoldable()) break;
7686 v1
= u
.expr
.v1
->get_value_refd_last();
7687 v2
= u
.expr
.v2
->get_value_refd_last();
7688 const int_val_t
i1_int(*v1
->get_val_Int());
7689 // `v2' is a native integer.
7690 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7693 set_val_str(int2hex(i1_int
, i2_int
));
7695 case OPTYPE_SUBSTR
: {
7696 if(is_unfoldable()) break;
7697 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7698 v2
=u
.expr
.v2
->get_value_refd_last();
7699 v3
=u
.expr
.v3
->get_value_refd_last();
7700 valuetype_t vt
=v1
->valuetype
;
7701 const int_val_t
*i2_int
=v2
->get_val_Int();
7702 const int_val_t
*i3_int
=v3
->get_val_Int();
7703 Int i2
=i2_int
->get_val();
7704 Int i3
=i3_int
->get_val();
7706 const ustring
& s
= v1
->get_val_ustr();
7709 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7710 u
.ustr
.convert_str
= false;
7717 const string
& s
= v1
->get_val_str();
7720 set_val_str(new string(s
.substr(i2
, i3
)));
7723 case OPTYPE_REPLACE
: {
7724 if(is_unfoldable()) break;
7725 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7726 v2
=u
.expr
.v2
->get_value_refd_last();
7727 v3
=u
.expr
.v3
->get_value_refd_last();
7728 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7729 valuetype_t vt
=v1
->valuetype
;
7730 const int_val_t
*i2_int
=v2
->get_val_Int();
7731 const int_val_t
*i3_int
=v3
->get_val_Int();
7732 Int i2
=i2_int
->get_val();
7733 Int i3
=i3_int
->get_val();
7736 string
*s1
= new string(v1
->get_val_str());
7737 const string
& s2
= v4
->get_val_str();
7740 s1
->replace(i2
, i3
, s2
);
7744 string
*s1
= new string(v1
->get_val_str());
7745 const string
& s2
= v4
->get_val_str();
7748 s1
->replace(i2
, i3
, s2
);
7754 string
*s1
= new string(v1
->get_val_str());
7755 const string
& s2
= v4
->get_val_str();
7758 s1
->replace(i2
, i3
, s2
);
7762 string
*s1
= new string(v1
->get_val_str());
7763 const string
& s2
= v4
->get_val_str();
7766 s1
->replace(i2
, i3
, s2
);
7770 ustring
*s1
= new ustring(v1
->get_val_ustr());
7771 const ustring
& s2
= v4
->get_val_ustr();
7774 s1
->replace(i2
, i3
, s2
);
7776 u
.ustr
.convert_str
= false;
7779 FATAL_ERROR("Value::evaluate_value()");
7782 case OPTYPE_REGEXP
: {
7783 if (is_unfoldable()) break;
7784 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7785 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7786 v3
=u
.expr
.v3
->get_value_refd_last();
7787 const int_val_t
*i3_int
= v3
->get_val_Int();
7788 Int i3
= i3_int
->get_val();
7789 if (v1
->valuetype
== V_CSTR
) {
7790 const string
& s1
= v1
->get_val_str();
7791 const string
& s2
= v2
->get_val_str();
7792 string
*result
= regexp(s1
, s2
, i3
);
7795 set_val_str(result
);
7796 } if (v1
->valuetype
== V_USTR
) {
7797 const ustring
& s1
= v1
->get_val_ustr();
7798 const ustring
& s2
= v2
->get_val_ustr();
7799 ustring
*result
= regexp(s1
, s2
, i3
);
7802 set_val_ustr(result
);
7803 u
.ustr
.convert_str
= false;
7806 case OPTYPE_LENGTHOF
:{
7807 if(is_unfoldable()) break;
7808 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7809 ->get_value_refd_last();
7811 if(v1
->is_string_type(exp_val
)) {
7812 i
=v1
->get_val_strlen();
7813 } else { // v1 is be seq/set of or array
7814 switch (v1
->valuetype
) {
7818 if(v1
->u
.val_vs
->is_indexed())
7819 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7820 else { i
= v1
->u
.val_vs
->get_nof_vs();}
7823 FATAL_ERROR("Value::evaluate_value()");
7828 u
.val_Int
=new int_val_t(i
);
7830 case OPTYPE_SIZEOF
: {
7831 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
7835 u
.val_Int
=new int_val_t(i
);
7838 case OPTYPE_ISVALUE
: {
7839 if(is_unfoldable()) break;
7840 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
7841 && u
.expr
.ti1
->get_Template()->is_Value();
7843 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
7844 is_singleval
= other_val
->evaluate_isvalue(false);
7845 // is_singleval now contains the compile-time result of isvalue
7850 u
.val_bool
= is_singleval
;
7852 case OPTYPE_ISCHOSEN_V
: {
7853 if (is_unfoldable()) break;
7854 v1
= u
.expr
.v1
->get_value_refd_last();
7855 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
7860 case OPTYPE_VALUEOF
: // ti1
7861 if (!u
.expr
.ti1
->get_DerivedRef() &&
7862 u
.expr
.ti1
->get_Template()->is_Value() &&
7863 !u
.expr
.ti1
->get_Type()) {
7864 // FIXME actually if the template instance has a type
7865 // it might still be foldable.
7866 // the argument is a single specific value
7867 v1
= u
.expr
.ti1
->get_Template()->get_Value();
7868 Type
*governor
= my_governor
;
7869 if (governor
== NULL
) {
7870 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
7871 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
7873 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
7874 if (governor
== NULL
)
7875 FATAL_ERROR("Value::evaluate_value()");
7877 valuetype
= v1
->valuetype
;
7879 set_my_governor(governor
);
7880 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
7881 u
.ref
.refd_last
= this;
7882 v1
->valuetype
= V_ERROR
;
7886 case OPTYPE_UNDEF_RUNNING
:
7888 FATAL_ERROR("Value::evaluate_value()");
7892 bool Value::evaluate_isvalue(bool from_sequence
)
7894 switch (valuetype
) {
7896 // Omit is not a value unless a member of a sequence or set
7897 return from_sequence
;
7900 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7901 case V_BOOL
: /**< boolean */
7902 case V_NAMEDINT
: /**< integer / named number */
7903 case V_NAMEDBITS
: /**< named bits (identifiers) */
7904 case V_INT
: /**< integer */
7905 case V_REAL
: /**< real/float */
7906 case V_ENUM
: /**< enumerated */
7907 case V_BSTR
: /**< bitstring */
7908 case V_HSTR
: /**< hexstring */
7909 case V_OSTR
: /**< octetstring */
7910 case V_CSTR
: /**< charstring */
7911 case V_USTR
: /**< universal charstring */
7912 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
7913 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
7914 case V_OID
: /**< object identifier */
7915 case V_ROID
: /**< relative object identifier */
7916 case V_VERDICT
: /**< all verdicts */
7917 return true; // values of built-in types return true
7919 // Code below was adapted from is_unfoldable(), false returned early.
7921 return u
.choice
.alt_value
->evaluate_isvalue(false);
7926 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
7927 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
7935 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
7936 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
7937 ->evaluate_isvalue(true)) return false;
7942 // alas, get_value_refd_last prevents this function from const
7943 return get_value_refd_last()->evaluate_isvalue(false);
7946 switch (u
.expr
.v_optype
) {
7947 // A constant null component reference is a corner case: it is foldable
7948 // but escapes unmodified from evaluate_value.
7949 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7950 // or is transformed into some other valuetype in evaluate_value.
7951 case OPTYPE_COMP_NULL
:
7954 break; // and fall through to the FATAL_ERROR
7958 FATAL_ERROR("Value::evaluate_isvalue()");
7964 void Value::evaluate_macro(Type::expected_value_t exp_val
)
7967 case MACRO_MODULEID
:
7969 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7970 set_val_str(new string(my_scope
->get_scope_mod()
7971 ->get_modid().get_dispname()));
7974 case MACRO_FILENAME
:
7975 case MACRO_BFILENAME
: {
7976 const char *t_filename
= get_filename();
7978 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7979 set_val_str(new string(t_filename
));
7982 case MACRO_FILEPATH
: {
7983 const char *t_filename
= get_filename();
7985 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7986 char *t_filepath
= canonize_input_file(t_filename
);
7988 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7989 set_val_str(new string(t_filepath
));
7993 case MACRO_LINENUMBER
: {
7994 int t_lineno
= get_first_line();
7996 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7997 set_val_str(new string(Int2string(t_lineno
)));
8000 case MACRO_LINENUMBER_C
: {
8001 int t_lineno
= get_first_line();
8003 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8004 u
.val_Int
= new int_val_t(t_lineno
);
8007 case MACRO_DEFINITIONID
: {
8008 // cut the second part from the fullname separated by dots
8009 const string
& t_fullname
= get_fullname();
8010 size_t first_char
= t_fullname
.find('.') + 1;
8011 if (first_char
>= t_fullname
.size())
8012 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8013 t_fullname
.c_str());
8014 set_val_str(new string(t_fullname
.substr(first_char
,
8015 t_fullname
.find('.', first_char
) - first_char
)));
8019 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8020 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8024 case MACRO_TESTCASEID
: {
8025 if (exp_val
== Type::EXPECTED_CONSTANT
||
8026 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8027 error("A %s value was expected instead of macro `%%testcaseId', "
8028 "which is evaluated at runtime",
8029 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8033 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8034 Ttcn::StatementBlock
*my_sb
=
8035 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8037 error("Usage of macro %%testcaseId is allowed only within the "
8038 "statement blocks of functions, altsteps and testcases");
8041 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8043 error("Macro %%testcaseId cannot be used in the control part. "
8044 "It is allowed only within the statement blocks of functions, "
8045 "altsteps and testcases");
8048 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8049 // folding is possible only within testcases
8050 set_val_str(new string(my_def
->get_id().get_dispname()));
8055 FATAL_ERROR("Value::evaluate_macro()");
8059 set_valuetype(V_ERROR
);
8062 void Value::add_id(Identifier
*p_id
)
8066 if(u
.ids
->has_key(p_id
->get_name())) {
8067 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8068 // The Value does not take ownership for the identifier,
8069 // so it must be deleted (add_is acts as a sink).
8072 else u
.ids
->add(p_id
->get_name(), p_id
);
8075 FATAL_ERROR("Value::add_id()");
8079 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8080 Type::expected_value_t exp_val
)
8082 set_lowerid_to_ref();
8083 switch (valuetype
) {
8085 // there might be a better place for this
8086 chk_invoke(exp_val
);
8089 // use the cache if available
8090 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8092 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8094 // the referred definition is not found
8095 set_valuetype(V_ERROR
);
8097 switch (ass
->get_asstype()) {
8098 case Assignment::A_OBJECT
:
8099 case Assignment::A_OS
: {
8100 // the referred definition is an ASN.1 object or object set
8101 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8102 if (!setting
|| setting
->get_st() == S_ERROR
) {
8103 // remain silent, the error has been already reported
8104 set_valuetype(V_ERROR
);
8106 } else if (setting
->get_st() != S_V
) {
8107 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8108 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8109 set_valuetype(V_ERROR
);
8114 refch
->mark_state();
8115 destroy_refch
= false;
8117 refch
= new ReferenceChain(this,
8118 "While searching referenced value");
8119 destroy_refch
= true;
8121 if (refch
->add(get_fullname())) {
8122 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8123 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8124 // in case of circular recursion the valuetype is already set
8125 // to V_ERROR, so don't set the cache
8126 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8128 // a circular recursion was detected
8129 set_valuetype(V_ERROR
);
8131 if (destroy_refch
) delete refch
;
8132 else refch
->prev_state();
8134 case Assignment::A_CONST
: {
8135 // the referred definition is a constant
8138 refch
->mark_state();
8139 destroy_refch
= false;
8141 refch
= new ReferenceChain(this,
8142 "While searching referenced value");
8143 destroy_refch
= true;
8145 if (refch
->add(get_fullname())) {
8146 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8147 Value
*v_refd
= ass
->get_Value()
8148 ->get_refd_sub_value(subrefs
, 0,
8149 u
.ref
.ref
->getUsedInIsbound(), refch
);
8151 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8152 // in case of circular recursion the valuetype is already set
8153 // to V_ERROR, so don't set the cache
8154 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8155 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8156 u
.ref
.refd_last
= this;
8157 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8158 u
.ref
.refd_last
= this;
8160 // the sub-reference points to a non-existent field
8161 set_valuetype(V_ERROR
);
8164 // a circular recursion was detected
8165 set_valuetype(V_ERROR
);
8167 if (destroy_refch
) delete refch
;
8168 else refch
->prev_state();
8170 case Assignment::A_EXT_CONST
:
8171 case Assignment::A_MODULEPAR
:
8172 case Assignment::A_VAR
:
8173 case Assignment::A_FUNCTION_RVAL
:
8174 case Assignment::A_EXT_FUNCTION_RVAL
:
8175 case Assignment::A_PAR_VAL_IN
:
8176 case Assignment::A_PAR_VAL_OUT
:
8177 case Assignment::A_PAR_VAL_INOUT
:
8178 // the referred definition is not a constant
8179 u
.ref
.refd_last
= this;
8181 case Assignment::A_FUNCTION
:
8182 case Assignment::A_EXT_FUNCTION
:
8183 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8184 "call of %s, which does not have return type",
8185 ass
->get_description().c_str());
8186 set_valuetype(V_ERROR
);
8188 case Assignment::A_FUNCTION_RTEMP
:
8189 case Assignment::A_EXT_FUNCTION_RTEMP
:
8190 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8191 "call of %s, which returns a template",
8192 ass
->get_description().c_str());
8193 set_valuetype(V_ERROR
);
8196 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8197 ass
->get_description().c_str());
8198 set_valuetype(V_ERROR
);
8201 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8205 // try to evaluate the expression
8208 refch
->mark_state();
8209 destroy_refch
=false;
8212 refch
=new ReferenceChain(this, "While evaluating expression");
8215 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8216 else set_valuetype(V_ERROR
);
8217 if(destroy_refch
) delete refch
;
8218 else refch
->prev_state();
8221 evaluate_macro(exp_val
);
8224 // return this for all other value types
8229 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8231 /* Note that the logic here needs to be in sync with evaluate_value,
8232 * and possibly others, i.e. if evaluate_value is called for a Value
8233 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8234 bool Value::is_unfoldable(ReferenceChain
*refch
,
8235 Type::expected_value_t exp_val
)
8237 if (UnfoldabilityCheck::is_running(this)) {
8238 // This function is already running on this value => infinite recursion
8242 UnfoldabilityCheck
checker(this);
8244 if (get_needs_conversion()) return true;
8245 switch (valuetype
) {
8249 case V_UNDEF_LOWERID
:
8253 // these value types are eliminated during semantic analysis
8254 FATAL_ERROR("Value::is_unfoldable()");
8259 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8263 if (!is_indexed()) {
8264 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8265 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8269 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8270 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8277 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8278 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8279 ->is_unfoldable(refch
, exp_val
)) return true;
8285 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8286 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8290 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8291 if(v_last
==this) return true; // there weren't any references to chase
8292 else return v_last
->is_unfoldable(refch
, exp_val
);
8295 // classify the unchecked ischosen() operation, if it was not done so far
8296 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8297 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8298 switch (u
.expr
.v_optype
) {
8299 case OPTYPE_RND
: // -
8300 case OPTYPE_COMP_MTC
:
8301 case OPTYPE_COMP_SYSTEM
:
8302 case OPTYPE_COMP_SELF
:
8303 case OPTYPE_COMP_RUNNING_ANY
:
8304 case OPTYPE_COMP_RUNNING_ALL
:
8305 case OPTYPE_COMP_ALIVE_ANY
:
8306 case OPTYPE_COMP_ALIVE_ALL
:
8307 case OPTYPE_TMR_RUNNING_ANY
:
8308 case OPTYPE_GETVERDICT
:
8309 case OPTYPE_TESTCASENAME
:
8310 case OPTYPE_PROF_RUNNING
:
8311 case OPTYPE_RNDWITHVAL
: // v1
8312 case OPTYPE_MATCH
: // v1 t2
8313 case OPTYPE_UNDEF_RUNNING
: // v1
8314 case OPTYPE_COMP_RUNNING
:
8315 case OPTYPE_COMP_ALIVE
:
8316 case OPTYPE_TMR_READ
:
8317 case OPTYPE_TMR_RUNNING
:
8318 case OPTYPE_ACTIVATE
:
8319 case OPTYPE_ACTIVATE_REFD
:
8320 case OPTYPE_EXECUTE
: // r1 [v2]
8321 case OPTYPE_EXECUTE_REFD
:
8322 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8323 case OPTYPE_ISCHOSEN
:
8324 case OPTYPE_ISCHOSEN_T
:
8325 case OPTYPE_SIZEOF
: // ti1
8328 case OPTYPE_OCT2UNICHAR
:
8329 case OPTYPE_UNICHAR2OCT
:
8330 case OPTYPE_ENCODE_BASE64
:
8331 case OPTYPE_DECODE_BASE64
:
8333 case OPTYPE_COMP_NULL
: // -
8335 case OPTYPE_UNARYPLUS
: // v1
8336 case OPTYPE_UNARYMINUS
:
8339 case OPTYPE_BIT2HEX
:
8340 case OPTYPE_BIT2INT
:
8341 case OPTYPE_BIT2OCT
:
8342 case OPTYPE_BIT2STR
:
8343 case OPTYPE_CHAR2INT
:
8344 case OPTYPE_CHAR2OCT
:
8345 case OPTYPE_FLOAT2INT
:
8346 case OPTYPE_FLOAT2STR
:
8347 case OPTYPE_HEX2BIT
:
8348 case OPTYPE_HEX2INT
:
8349 case OPTYPE_HEX2OCT
:
8350 case OPTYPE_HEX2STR
:
8351 case OPTYPE_INT2CHAR
:
8352 case OPTYPE_INT2FLOAT
:
8353 case OPTYPE_INT2STR
:
8354 case OPTYPE_INT2UNICHAR
:
8355 case OPTYPE_OCT2BIT
:
8356 case OPTYPE_OCT2CHAR
:
8357 case OPTYPE_OCT2HEX
:
8358 case OPTYPE_OCT2INT
:
8359 case OPTYPE_OCT2STR
:
8360 case OPTYPE_STR2BIT
:
8361 case OPTYPE_STR2FLOAT
:
8362 case OPTYPE_STR2HEX
:
8363 case OPTYPE_STR2INT
:
8364 case OPTYPE_STR2OCT
:
8365 case OPTYPE_UNICHAR2INT
:
8366 case OPTYPE_UNICHAR2CHAR
:
8367 case OPTYPE_ENUM2INT
:
8368 case OPTYPE_GET_STRINGENCODING
:
8369 case OPTYPE_REMOVE_BOM
:
8370 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8371 case OPTYPE_ISBOUND
: /*{
8372 //TODO once we have the time for it make isbound foldable.
8373 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8374 Template* temp = u.expr.ti1->get_Template();
8375 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8376 Value* specificValue = temp->get_specific_value();
8377 if (specificValue->get_valuetype() == Value::V_REFD) {
8381 return specificValue->is_unfoldable(refch, exp_val);
8382 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8387 case OPTYPE_ISPRESENT
:
8388 // TODO: "if you have motivation"
8390 case OPTYPE_ISVALUE
: // ti1
8392 case OPTYPE_LENGTHOF
: // ti1
8393 return u
.expr
.ti1
->get_DerivedRef() != 0
8394 || u
.expr
.ti1
->get_Template()->get_templatetype()
8395 != Template::SPECIFIC_VALUE
8396 || u
.expr
.ti1
->get_Template()->get_specific_value()
8397 ->is_unfoldable(refch
, exp_val
);
8401 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8403 case OPTYPE_ADD
: // v1 v2
8404 case OPTYPE_SUBTRACT
:
8405 case OPTYPE_MULTIPLY
:
8421 case OPTYPE_INT2BIT
:
8422 case OPTYPE_INT2HEX
:
8423 case OPTYPE_INT2OCT
:
8424 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8425 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8426 case OPTYPE_AND
: // short-circuit evaluation
8427 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8428 || (u
.expr
.v1
->get_val_bool() &&
8429 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8430 case OPTYPE_OR
: // short-circuit evaluation
8431 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8432 || (!u
.expr
.v1
->get_val_bool() &&
8433 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8435 if (!u
.expr
.ti1
->get_specific_value()) return true;
8436 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8437 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8438 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8439 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8441 if (!u
.expr
.ti1
->get_specific_value() ||
8442 !u
.expr
.t2
->get_specific_value()) return true;
8443 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8444 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8445 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8447 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8448 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8449 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8450 case OPTYPE_REPLACE
: {
8451 if (!u
.expr
.ti1
->get_specific_value() ||
8452 !u
.expr
.ti4
->get_specific_value()) return true;
8453 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8454 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8455 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8456 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8457 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8459 case OPTYPE_VALUEOF
: // ti1
8460 /* \todo if you have motivation to implement the eval function
8463 case OPTYPE_ISCHOSEN_V
:
8464 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8465 case OPTYPE_LOG2STR
:
8466 case OPTYPE_TTCN2STRING
:
8469 FATAL_ERROR("Value::is_unfoldable()");
8471 break; // should never get here
8474 case MACRO_TESTCASEID
:
8475 // this is known only at runtime
8481 // all literal values are foldable
8486 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8487 size_t start_i
, bool usedInIsbound
,
8488 ReferenceChain
*refch
)
8490 if (!subrefs
) return this;
8492 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8494 v
= v
->get_value_refd_last(refch
);
8495 switch(v
->valuetype
) {
8504 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8505 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8506 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8507 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8512 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8513 bool usedInIsbound
, const Location
& loc
)
8515 if (valuetype
== V_OMIT
) {
8516 loc
.error("Reference to field `%s' of omit value `%s'",
8517 field_id
.get_dispname().c_str(), get_fullname().c_str());
8520 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8521 Type
*t
= my_governor
->get_type_refd_last();
8522 switch (t
->get_typetype()) {
8526 case Type::T_CHOICE_A
:
8527 case Type::T_CHOICE_T
:
8528 case Type::T_OPENTYPE
:
8529 case Type::T_ANYTYPE
:
8530 if (!t
->has_comp_withName(field_id
)) {
8531 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8532 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8534 } else if (valuetype
!= V_CHOICE
) {
8535 // remain silent, the error is already reported
8537 } else if (*u
.choice
.alt_name
== field_id
) {
8539 return u
.choice
.alt_value
;
8541 if (!usedInIsbound
) {
8542 loc
.error("Reference to inactive field `%s' in a value of union type "
8543 "`%s'. The active field is `%s'",
8544 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8545 u
.choice
.alt_name
->get_dispname().c_str());
8551 if (!t
->has_comp_withName(field_id
)) {
8552 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8553 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8555 } else if (valuetype
!= V_SEQ
) {
8556 // remain silent, the error has been already reported
8561 if (!t
->has_comp_withName(field_id
)) {
8562 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8563 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8565 } else if (valuetype
!= V_SET
) {
8566 // remain silent, the error has been already reported
8570 loc
.error("Invalid field reference `%s': type `%s' "
8571 "does not have fields", field_id
.get_dispname().c_str(),
8572 t
->get_typename().c_str());
8575 // the common end for record & set types
8576 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8578 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8579 } else if (!is_asn1()) {
8580 if (!usedInIsbound
) {
8581 loc
.error("Reference to unbound field `%s'",
8582 field_id
.get_dispname().c_str());
8583 // this is an error in TTCN-3, which has been already reported
8587 CompField
*cf
= t
->get_comp_byName(field_id
);
8588 if (cf
->get_is_optional()) {
8589 // creating an explicit omit value
8590 Value
*v
= new Value(V_OMIT
);
8591 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8592 v
->set_my_scope(get_my_scope());
8593 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8595 } else if (cf
->has_default()) {
8596 // returning the component's default value
8597 return cf
->get_defval();
8599 // this is an error in ASN.1, which has been already reported
8605 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8606 ReferenceChain
*refch
)
8608 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8610 bool index_available
= false;
8611 if (!v_index
->is_unfoldable()) {
8612 if (v_index
->valuetype
== V_INT
) {
8613 index
= v_index
->get_val_Int()->get_val();
8614 index_available
= true;
8616 array_index
->error("An integer value was expected as index");
8619 if (valuetype
== V_OMIT
) {
8620 array_index
->error("Accessing an element with index of omit value `%s'",
8621 get_fullname().c_str());
8624 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8625 Type
*t
= my_governor
->get_type_refd_last();
8626 switch (t
->get_typetype()) {
8631 if (index_available
) {
8633 array_index
->error("A non-negative integer value was expected "
8634 "instead of %s for indexing a value of `record "
8635 "of' type `%s'", Int2string(index
).c_str(),
8636 t
->get_typename().c_str());
8639 switch (valuetype
) {
8641 if (!is_indexed()) {
8642 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8643 if (!usedInIsbound
) {
8644 array_index
->error("Index overflow in a value of `record of' "
8645 "type `%s': the index is %s, but the value "
8646 "has only %lu elements",
8647 t
->get_typename().c_str(),
8648 Int2string(index
).c_str(),
8649 (unsigned long)u
.val_vs
->get_nof_vs());
8653 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8654 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8655 temp
->error("Not used symbol is not allowed in this context");
8656 return u
.val_vs
->get_v_byIndex(index
);
8659 // Search the appropriate constant index.
8660 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8661 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8662 ->get_value_refd_last();
8663 if (iv_index
->get_valuetype() != V_INT
) continue;
8664 if (iv_index
->get_val_Int()->get_val() == index
)
8665 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8671 // remain silent, the error has been already reported
8675 // the error has been reported above
8679 if (index_available
) {
8681 array_index
->error("A non-negative integer value was expected "
8682 "instead of %s for indexing a value of `set of' type `%s'",
8683 Int2string(index
).c_str(), t
->get_typename().c_str());
8686 switch (valuetype
) {
8688 if (!is_indexed()) {
8689 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8690 if (!usedInIsbound
) {
8691 array_index
->error("Index overflow in a value of `set of' type "
8692 "`%s': the index is %s, but the value has "
8693 "only %lu elements",
8694 t
->get_typename().c_str(),
8695 Int2string(index
).c_str(),
8696 (unsigned long)u
.val_vs
->get_nof_vs());
8700 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8701 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8702 temp
->error("Not used symbol is not allowed in this context");
8706 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8707 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8708 ->get_value_refd_last();
8709 if (iv_index
->get_valuetype() != V_INT
) continue;
8710 if (iv_index
->get_val_Int()->get_val() == index
)
8711 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8717 // remain silent, the error has been already reported
8721 // the error has been reported above
8725 if (index_available
) {
8726 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8727 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8728 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8729 // perform the index transformation
8730 index
-= dim
->get_offset();
8731 if (!is_indexed()) {
8732 // check for index underflow/overflow or too few elements in the
8735 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8737 else return u
.val_vs
->get_v_byIndex(index
);
8739 if (index
< 0) return 0;
8740 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8741 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8742 ->get_value_refd_last();
8743 if (iv_index
->get_valuetype() != V_INT
) continue;
8744 if (iv_index
->get_val_Int()->get_val() == index
)
8745 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8750 // remain silent, the error has been already reported
8754 // the error has been reported above
8758 case Type::T_BSTR_A
:
8763 case Type::T_UTF8STRING
:
8764 case Type::T_NUMERICSTRING
:
8765 case Type::T_PRINTABLESTRING
:
8766 case Type::T_TELETEXSTRING
:
8767 case Type::T_VIDEOTEXSTRING
:
8768 case Type::T_IA5STRING
:
8769 case Type::T_GRAPHICSTRING
:
8770 case Type::T_VISIBLESTRING
:
8771 case Type::T_GENERALSTRING
:
8772 case Type::T_UNIVERSALSTRING
:
8773 case Type::T_BMPSTRING
:
8774 case Type::T_UTCTIME
:
8775 case Type::T_GENERALIZEDTIME
:
8776 case Type::T_OBJECTDESCRIPTOR
:
8777 if (index_available
) return get_string_element(index
, *array_index
);
8780 array_index
->error("Invalid array element reference: type `%s' cannot "
8781 "be indexed", t
->get_typename().c_str());
8786 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8789 loc
.error("A non-negative integer value was expected instead of %s "
8790 "for indexing a string element", Int2string(index
).c_str());
8793 size_t string_length
;
8794 switch (valuetype
) {
8799 string_length
= u
.str
.val_str
->size();
8802 string_length
= u
.str
.val_str
->size() / 2;
8805 string_length
= u
.ustr
.val_ustr
->size();
8808 // remain silent, the error has been already reported
8811 if (index
>= static_cast<Int
>(string_length
)) {
8812 loc
.error("Index overflow when accessing a string element: "
8813 "the index is %s, but the string has only %lu elements",
8814 Int2string(index
).c_str(), (unsigned long) string_length
);
8817 switch (valuetype
) {
8822 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8823 return (*u
.str
.str_elements
)[index
];
8825 Value
*t_val
= new Value(valuetype
,
8826 new string(u
.str
.val_str
->substr(index
, 1)));
8827 add_string_element(index
, t_val
, u
.str
.str_elements
);
8831 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8832 return (*u
.str
.str_elements
)[index
];
8834 Value
*t_val
= new Value(V_OSTR
,
8835 new string(u
.str
.val_str
->substr(2 * index
, 2)));
8836 add_string_element(index
, t_val
, u
.str
.str_elements
);
8840 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
8841 return (*u
.ustr
.ustr_elements
)[index
];
8843 Value
*t_val
= new Value(V_USTR
,
8844 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
8845 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
8849 FATAL_ERROR("Value::get_string_element()");
8854 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
8855 Type::expected_value_t exp_val
)
8857 set_lowerid_to_ref();
8858 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
8859 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
8861 error("A value or expression of type %s was expected", type_name
);
8862 if (valuetype
== V_REFD
) {
8863 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
8864 t_chk
->chk_this_refd_value(this, 0, exp_val
);
8866 get_value_refd_last(0, exp_val
);
8867 if (error_flag
) set_valuetype(V_ERROR
);
8868 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
8871 int Value::is_parsed_infinity()
8873 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
8875 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
8876 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
8877 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
8882 bool Value::get_val_bool()
8885 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8887 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
8888 return v
->u
.val_bool
;
8891 int_val_t
* Value::get_val_Int()
8894 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8896 switch (v
->valuetype
) {
8899 case V_UNDEF_LOWERID
:
8900 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8901 "`%s'", (*u
.val_id
).get_dispname().c_str());
8903 FATAL_ERROR("Value::get_val_Int()");
8905 return v
->u
.val_Int
;
8908 const Identifier
* Value::get_val_id()
8913 case V_UNDEF_LOWERID
:
8916 FATAL_ERROR("Value::get_val_id()");
8921 const ttcn3float
& Value::get_val_Real()
8924 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8926 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
8927 return v
->u
.val_Real
;
8930 string
Value::get_val_str()
8932 Value
*v
= get_value_refd_last();
8933 switch (v
->valuetype
) {
8938 return *v
->u
.str
.val_str
;
8940 return v
->u
.char_syms
->get_string();
8942 error("Cannot use ISO-10646 string value in string context");
8945 error("Cannot use ISO-2022 string value in string context");
8950 error("Cannot use this value in charstring value context");
8955 ustring
Value::get_val_ustr()
8957 Value
*v
= get_value_refd_last();
8958 switch (v
->valuetype
) {
8960 return ustring(*v
->u
.str
.val_str
);
8962 return *v
->u
.ustr
.val_ustr
;
8964 return v
->u
.char_syms
->get_ustring();
8966 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8971 error("Cannot use this value in ISO-10646 string context");
8976 string
Value::get_val_iso2022str()
8978 Value
*v
= get_value_refd_last();
8979 switch (v
->valuetype
) {
8982 return *v
->u
.str
.val_str
;
8984 return v
->u
.char_syms
->get_iso2022string();
8986 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8991 error("Cannot use this value in ISO-2022 string context");
8996 size_t Value::get_val_strlen()
8998 Value
*v
= get_value_refd_last();
8999 switch (v
->valuetype
) {
9004 return v
->u
.str
.val_str
->size();
9006 return v
->u
.str
.val_str
->size()/2;
9008 return v
->u
.char_syms
->get_len();
9010 return v
->u
.ustr
.val_ustr
->size();
9014 error("Cannot use this value in string value context");
9019 Value::verdict_t
Value::get_val_verdict()
9025 FATAL_ERROR("Value::get_val_verdict()");
9030 size_t Value::get_nof_comps()
9032 switch (valuetype
) {
9036 return u
.oid_comps
->size();
9040 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9041 else return u
.val_vs
->get_nof_vs();
9044 return u
.val_nvs
->get_nof_nvs();
9049 return u
.str
.val_str
->size();
9051 return u
.str
.val_str
->size()/2;
9053 return u
.ustr
.val_ustr
->size();
9055 FATAL_ERROR("Value::get_nof_comps()");
9060 bool Value::is_indexed() const
9062 switch (valuetype
) {
9066 // Applicable only for list-types. Assigning a record/SEQUENCE or
9067 // set/SET with indexed notation is not supported.
9068 return u
.val_vs
->is_indexed();
9070 FATAL_ERROR("Value::is_indexed()");
9076 const Identifier
& Value::get_alt_name()
9078 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9079 return *u
.choice
.alt_name
;
9082 Value
*Value::get_alt_value()
9084 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9085 return u
.choice
.alt_value
;
9088 void Value::set_alt_name_to_lowercase()
9090 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9091 string new_name
= u
.choice
.alt_name
->get_name();
9092 if (isupper(new_name
[0])) {
9093 new_name
[0] = tolower(new_name
[0]);
9094 if (new_name
[new_name
.size() - 1] == '_') {
9095 // an underscore is inserted at the end of the alternative name if it's
9096 // a basic type's name (since it would conflict with the class generated
9098 // remove the underscore, it won't conflict with anything if its name
9099 // starts with a lowercase letter
9100 new_name
.replace(new_name
.size() - 1, 1, "");
9102 delete u
.choice
.alt_name
;
9103 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9107 bool Value::has_oid_error()
9110 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9112 switch (valuetype
) {
9115 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9116 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9123 bool Value::get_oid_comps(vector
<string
>& comps
)
9125 bool ret_val
= true;
9127 switch (valuetype
) {
9129 v
= get_value_refd_last();
9133 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9134 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9135 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9136 // not all components can be calculated in compile-time
9142 FATAL_ERROR("Value::get_oid_comps()");
9147 void Value::add_se_comp(NamedValue
* nv
) {
9148 switch (valuetype
) {
9152 u
.val_nvs
= new NamedValues();
9153 u
.val_nvs
->add_nv(nv
);
9156 FATAL_ERROR("Value::add_se_comp()");
9160 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9165 return u
.val_nvs
->get_nv_byIndex(n
);
9167 FATAL_ERROR("Value::get_se_comp_byIndex()");
9172 Value
*Value::get_comp_byIndex(size_t n
)
9174 switch (valuetype
) {
9178 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9179 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9181 FATAL_ERROR("Value::get_comp_byIndex()");
9186 Value
*Value::get_index_byIndex(size_t n
)
9188 switch (valuetype
) {
9192 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9193 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9195 FATAL_ERROR("Value::get_index_byIndex()");
9200 bool Value::has_comp_withName(const Identifier
& p_name
)
9205 return u
.val_nvs
->has_nv_withName(p_name
);
9207 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9209 FATAL_ERROR("Value::get_has_comp_withName()");
9214 bool Value::field_is_chosen(const Identifier
& p_name
)
9216 Value
*v
=get_value_refd_last();
9217 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9218 return *v
->u
.choice
.alt_name
==p_name
;
9221 bool Value::field_is_present(const Identifier
& p_name
)
9223 Value
*v
=get_value_refd_last();
9224 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9225 FATAL_ERROR("Value::field_is_present()");
9226 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9227 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9228 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9231 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9236 return u
.val_nvs
->get_nv_byName(p_name
);
9238 FATAL_ERROR("Value::get_se_comp_byName()");
9243 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9248 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9250 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9251 return u
.choice
.alt_value
;
9255 FATAL_ERROR("Value::get_se_comp_byName()");
9260 void Value::chk_dupl_id()
9265 u
.val_nvs
->chk_dupl_id();
9268 FATAL_ERROR("Value::chk_dupl_id()");
9272 size_t Value::get_nof_ids() const
9276 return u
.ids
->size();
9279 FATAL_ERROR("Value::get_nof_ids()");
9284 Identifier
* Value::get_id_byIndex(size_t p_i
)
9288 return u
.ids
->get_nth_elem(p_i
);
9291 FATAL_ERROR("Value::get_id_byIndex()");
9296 bool Value::has_id(const Identifier
& p_id
)
9300 return u
.ids
->has_key(p_id
.get_name());
9303 FATAL_ERROR("Value::has_id()");
9308 Reference
*Value::get_reference() const
9310 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9314 Reference
*Value::get_refered() const
9316 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9320 Common::Assignment
*Value::get_refd_fat() const
9328 FATAL_ERROR("Value::get_refd_fat()");
9332 Ttcn::Reference
* Value::steal_ttcn_ref()
9334 Ttcn::Reference
*ret_val
=
9335 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9336 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9340 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9342 Ttcn::Ref_base
*t_ref
;
9343 if(valuetype
==V_REFD
) {
9344 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9345 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9348 else if(valuetype
==V_UNDEF_LOWERID
) {
9349 t_ref
=new Ttcn::Reference(u
.val_id
);
9350 t_ref
->set_location(*this);
9351 t_ref
->set_fullname(get_fullname());
9352 t_ref
->set_my_scope(get_my_scope());
9356 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9359 set_valuetype(V_ERROR
);
9363 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9364 Ttcn::ActualParList
*& p_ap
)
9366 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9369 p_ti
= u
.invoke
.t_list
;
9370 u
.invoke
.t_list
= 0;
9371 p_ap
= u
.invoke
.ap_list
;
9372 u
.invoke
.ap_list
= 0;
9373 set_valuetype(V_ERROR
);
9376 Common::Assignment
* Value::get_refd_assignment()
9385 FATAL_ERROR("Value::get_refd_assignment()");
9395 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9400 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9409 void Value::chk_OID(ReferenceChain
& refch
)
9411 if (checked
) return;
9412 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9413 FATAL_ERROR("Value::chk_OID()");
9414 if (!refch
.add(get_fullname())) {
9418 OID_comp::oidstate_t state
= OID_comp::START
;
9419 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9421 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9424 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9425 error("An OBJECT IDENTIFIER value must have at least "
9426 "two components"); // X.680 (07/2002) 31.10
9429 void Value::chk_ROID(ReferenceChain
& refch
)
9431 if (checked
) return;
9432 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9433 FATAL_ERROR("Value::chk_ROID()");
9434 if (!refch
.add(get_fullname())) {
9438 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9440 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9445 void Value::chk_recursions(ReferenceChain
& refch
)
9447 if (recurs_checked
) return;
9448 Value
*v
= get_value_refd_last();
9449 if (refch
.add(v
->get_fullname())) {
9450 switch (v
->valuetype
) {
9452 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9457 if (!v
->is_indexed()) {
9458 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9460 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9464 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9466 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9467 ->chk_recursions(refch
);
9474 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9476 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9481 chk_recursions_expr(refch
);
9486 if (v
->err_descr
) { // FIXME: make this work
9487 v
->err_descr
->chk_recursions(refch
);
9490 recurs_checked
= true;
9493 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9495 // first classify the unchecked ischosen() operation
9496 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9497 switch (u
.expr
.v_optype
) {
9498 case OPTYPE_UNARYPLUS
: // v1
9499 case OPTYPE_UNARYMINUS
:
9502 case OPTYPE_BIT2HEX
:
9503 case OPTYPE_BIT2INT
:
9504 case OPTYPE_BIT2OCT
:
9505 case OPTYPE_BIT2STR
:
9506 case OPTYPE_CHAR2INT
:
9507 case OPTYPE_CHAR2OCT
:
9508 case OPTYPE_FLOAT2INT
:
9509 case OPTYPE_FLOAT2STR
:
9510 case OPTYPE_HEX2BIT
:
9511 case OPTYPE_HEX2INT
:
9512 case OPTYPE_HEX2OCT
:
9513 case OPTYPE_HEX2STR
:
9514 case OPTYPE_INT2CHAR
:
9515 case OPTYPE_INT2FLOAT
:
9516 case OPTYPE_INT2STR
:
9517 case OPTYPE_INT2UNICHAR
:
9518 case OPTYPE_OCT2BIT
:
9519 case OPTYPE_OCT2CHAR
:
9520 case OPTYPE_OCT2HEX
:
9521 case OPTYPE_OCT2INT
:
9522 case OPTYPE_OCT2STR
:
9523 case OPTYPE_STR2BIT
:
9524 case OPTYPE_STR2FLOAT
:
9525 case OPTYPE_STR2HEX
:
9526 case OPTYPE_STR2INT
:
9527 case OPTYPE_STR2OCT
:
9528 case OPTYPE_UNICHAR2INT
:
9529 case OPTYPE_ENUM2INT
:
9530 case OPTYPE_UNICHAR2CHAR
:
9531 case OPTYPE_RNDWITHVAL
:
9532 case OPTYPE_ISCHOSEN_V
:
9533 case OPTYPE_GET_STRINGENCODING
:
9534 case OPTYPE_REMOVE_BOM
:
9535 case OPTYPE_DECODE_BASE64
:
9537 u
.expr
.v1
->chk_recursions(refch
);
9540 case OPTYPE_ISCHOSEN_T
:
9542 u
.expr
.t1
->chk_recursions(refch
);
9545 case OPTYPE_ADD
: // v1 v2
9546 case OPTYPE_SUBTRACT
:
9547 case OPTYPE_MULTIPLY
:
9568 case OPTYPE_INT2BIT
:
9569 case OPTYPE_INT2HEX
:
9570 case OPTYPE_INT2OCT
:
9572 u
.expr
.v1
->chk_recursions(refch
);
9575 u
.expr
.v2
->chk_recursions(refch
);
9578 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9579 case OPTYPE_OCT2UNICHAR
:
9580 case OPTYPE_ENCODE_BASE64
:
9582 u
.expr
.v1
->chk_recursions(refch
);
9586 u
.expr
.v2
->chk_recursions(refch
);
9591 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9592 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9596 u
.expr
.ti1
->chk_recursions(refch
);
9599 u
.expr
.v2
->chk_recursions(refch
);
9602 u
.expr
.v3
->chk_recursions(refch
);
9607 u
.expr
.ti1
->chk_recursions(refch
);
9610 u
.expr
.t2
->chk_recursions(refch
);
9613 u
.expr
.v3
->chk_recursions(refch
);
9616 case OPTYPE_DECOMP
: // v1 v2 v3
9618 u
.expr
.v1
->chk_recursions(refch
);
9621 u
.expr
.v2
->chk_recursions(refch
);
9624 u
.expr
.v3
->chk_recursions(refch
);
9627 case OPTYPE_REPLACE
:
9629 u
.expr
.ti1
->chk_recursions(refch
);
9632 u
.expr
.v2
->chk_recursions(refch
);
9635 u
.expr
.v3
->chk_recursions(refch
);
9638 u
.expr
.ti4
->chk_recursions(refch
);
9641 case OPTYPE_LENGTHOF
: // ti1
9642 case OPTYPE_SIZEOF
: // ti1
9643 case OPTYPE_VALUEOF
: // ti1
9645 case OPTYPE_ISPRESENT
:
9646 case OPTYPE_TTCN2STRING
:
9648 u
.expr
.ti1
->chk_recursions(refch
);
9651 case OPTYPE_MATCH
: // v1 t2
9653 u
.expr
.v1
->chk_recursions(refch
);
9656 u
.expr
.t2
->chk_recursions(refch
);
9659 case OPTYPE_LOG2STR
:
9660 u
.expr
.logargs
->chk_recursions(refch
);
9667 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9668 ReferenceChain
& refch
) {
9669 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9670 Assignment
*ass
= ref
->get_refd_assignment();
9672 set_valuetype(V_ERROR
);
9675 switch (ass
->get_asstype()) {
9676 case Assignment::A_CONST
:
9677 case Assignment::A_EXT_CONST
:
9678 case Assignment::A_MODULEPAR
:
9679 case Assignment::A_VAR
:
9680 case Assignment::A_PAR_VAL_IN
:
9681 case Assignment::A_PAR_VAL_OUT
:
9682 case Assignment::A_PAR_VAL_INOUT
: {
9683 Value
* v
= new Value(V_REFD
, ref
);
9684 v
->set_location(*ref
);
9685 v
->set_my_scope(get_my_scope());
9686 v
->set_fullname(get_fullname()+".<operand>");
9688 v
->chk_recursions(refch
);
9692 case Assignment::A_MODULEPAR_TEMP
:
9693 case Assignment::A_TEMPLATE
:
9694 case Assignment::A_VAR_TEMPLATE
:
9695 case Assignment::A_PAR_TEMPL_IN
:
9696 case Assignment::A_PAR_TEMPL_OUT
:
9697 case Assignment::A_PAR_TEMPL_INOUT
: {
9698 Template
* t
= new Template(ref
->clone());
9699 t
->set_location(*ref
);
9700 t
->set_my_scope(get_my_scope());
9701 t
->set_fullname(get_fullname()+".<operand>");
9703 t
->chk_recursions(refch
);
9708 // remain silent, the error has been already reported
9709 set_valuetype(V_ERROR
);
9714 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9716 bool self_ref
= false;
9717 switch (t
->get_templatetype()) {
9718 case Ttcn::Template::SPECIFIC_VALUE
: {
9719 Value
*v
= t
->get_specific_value();
9720 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9721 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9722 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9724 case Ttcn::Template::TEMPLATE_REFD
: {
9725 Ttcn::Ref_base
*refb
= t
->get_reference();
9726 Common::Assignment
*ass
= refb
->get_refd_assignment();
9727 self_ref
|= (ass
== lhs
);
9729 case Ttcn::Template::ALL_FROM
:
9730 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9731 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9733 case Ttcn::Template::TEMPLATE_LIST
:
9734 case Ttcn::Template::SUPERSET_MATCH
:
9735 case Ttcn::Template::SUBSET_MATCH
:
9736 case Ttcn::Template::PERMUTATION_MATCH
:
9737 case Ttcn::Template::COMPLEMENTED_LIST
:
9738 case Ttcn::Template::VALUE_LIST
: {
9739 size_t num
= t
->get_nof_comps();
9740 for (size_t i
= 0; i
< num
; ++i
) {
9741 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9744 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9745 // case Ttcn::Template::TEMPLATE_LIST: {
9746 // size_t num = t->get_nof_listitems();
9747 // for (size_t i=0; i < num; ++i) {
9748 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9751 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9752 size_t nnt
= t
->get_nof_comps();
9753 for (size_t i
=0; i
< nnt
; ++i
) {
9754 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9755 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9758 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9759 size_t nnt
= t
->get_nof_comps();
9760 for (size_t i
=0; i
< nnt
; ++i
) {
9761 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9762 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9765 case Ttcn::Template::VALUE_RANGE
: {
9766 Ttcn::ValueRange
*vr
= t
->get_value_range();
9767 Common::Value
*v
= vr
->get_min_v();
9768 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9769 v
= vr
->get_max_v();
9770 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9772 case Ttcn::Template::CSTR_PATTERN
:
9773 case Ttcn::Template::USTR_PATTERN
: {
9774 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9775 self_ref
|= ps
->chk_self_ref(lhs
);
9777 case Ttcn::Template::BSTR_PATTERN
:
9778 case Ttcn::Template::HSTR_PATTERN
:
9779 case Ttcn::Template::OSTR_PATTERN
: {
9780 // FIXME: cannot access u.pattern
9782 case Ttcn::Template::ANY_VALUE
:
9783 case Ttcn::Template::ANY_OR_OMIT
:
9784 case Ttcn::Template::OMIT_VALUE
:
9785 case Ttcn::Template::TEMPLATE_NOTUSED
:
9786 break; // self-ref can't happen
9787 case Ttcn::Template::TEMPLATE_INVOKE
:
9788 break; // assume self-ref can't happen
9789 case Ttcn::Template::TEMPLATE_ERROR
:
9790 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9793 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9794 // break; // and hope for the best
9799 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
9801 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
9802 namedbool is_str_elem
= NOT_STR_ELEM
;
9803 if (v
->valuetype
== V_REFD
) {
9804 Reference
*ref
= v
->get_reference();
9805 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
9806 if (subrefs
&& subrefs
->refers_to_string_element()) {
9807 is_str_elem
= IS_STR_ELEM
;
9810 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9811 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
9815 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
9817 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
9818 if (!lhs
) FATAL_ERROR("no lhs!");
9819 bool self_ref
= false;
9820 switch (u
.expr
.v_optype
) {
9821 case OPTYPE_RND
: // -
9822 case OPTYPE_TESTCASENAME
: // -
9823 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
9824 case OPTYPE_COMP_MTC
: // -
9825 case OPTYPE_COMP_SYSTEM
: // -
9826 case OPTYPE_COMP_SELF
: // -
9827 case OPTYPE_COMP_RUNNING_ANY
: // -
9828 case OPTYPE_COMP_RUNNING_ALL
: // -
9829 case OPTYPE_COMP_ALIVE_ANY
: // -
9830 case OPTYPE_COMP_ALIVE_ALL
: // -
9831 case OPTYPE_TMR_RUNNING_ANY
: // -
9832 case OPTYPE_GETVERDICT
: // -
9833 case OPTYPE_PROF_RUNNING
: // -
9834 break; // nothing to do
9836 case OPTYPE_MATCH
: // v1 t2
9837 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9839 case OPTYPE_UNARYPLUS
: // v1
9840 case OPTYPE_UNARYMINUS
: // v1
9841 case OPTYPE_NOT
: // v1
9842 case OPTYPE_NOT4B
: // v1
9843 case OPTYPE_BIT2HEX
: // v1
9844 case OPTYPE_BIT2INT
: // v1
9845 case OPTYPE_BIT2OCT
: // v1
9846 case OPTYPE_BIT2STR
: // v1
9847 case OPTYPE_CHAR2INT
: // v1
9848 case OPTYPE_CHAR2OCT
: // v1
9849 case OPTYPE_FLOAT2INT
: // v1
9850 case OPTYPE_FLOAT2STR
: // v1
9851 case OPTYPE_HEX2BIT
: // v1
9852 case OPTYPE_HEX2INT
: // v1
9853 case OPTYPE_HEX2OCT
: // v1
9854 case OPTYPE_HEX2STR
: // v1
9855 case OPTYPE_INT2CHAR
: // v1
9856 case OPTYPE_INT2FLOAT
: // v1
9857 case OPTYPE_INT2STR
: // v1
9858 case OPTYPE_INT2UNICHAR
: // v1
9859 case OPTYPE_OCT2BIT
: // v1
9860 case OPTYPE_OCT2CHAR
: // v1
9861 case OPTYPE_OCT2HEX
: // v1
9862 case OPTYPE_OCT2INT
: // v1
9863 case OPTYPE_OCT2STR
: // v1
9864 case OPTYPE_STR2BIT
: // v1
9865 case OPTYPE_STR2FLOAT
: // v1
9866 case OPTYPE_STR2HEX
: // v1
9867 case OPTYPE_STR2INT
: // v1
9868 case OPTYPE_STR2OCT
: // v1
9869 case OPTYPE_UNICHAR2INT
: // v1
9870 case OPTYPE_UNICHAR2CHAR
: // v1
9871 case OPTYPE_ENUM2INT
: // v1
9872 case OPTYPE_RNDWITHVAL
: // v1
9873 case OPTYPE_COMP_RUNNING
: // v1
9874 case OPTYPE_COMP_ALIVE
: // v1
9875 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
9876 case OPTYPE_GET_STRINGENCODING
:
9877 case OPTYPE_DECODE_BASE64
:
9878 case OPTYPE_REMOVE_BOM
:
9879 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9881 case OPTYPE_ADD
: // v1 v2
9882 case OPTYPE_SUBTRACT
: // v1 v2
9883 case OPTYPE_MULTIPLY
: // v1 v2
9884 case OPTYPE_DIVIDE
: // v1 v2
9885 case OPTYPE_MOD
: // v1 v2
9886 case OPTYPE_REM
: // v1 v2
9887 case OPTYPE_CONCAT
: // v1 v2
9888 case OPTYPE_EQ
: // v1 v2
9889 case OPTYPE_LT
: // v1 v2
9890 case OPTYPE_GT
: // v1 v2
9891 case OPTYPE_NE
: // v1 v2
9892 case OPTYPE_GE
: // v1 v2
9893 case OPTYPE_LE
: // v1 v2
9894 case OPTYPE_AND
: // v1 v2
9895 case OPTYPE_OR
: // v1 v2
9896 case OPTYPE_XOR
: // v1 v2
9897 case OPTYPE_AND4B
: // v1 v2
9898 case OPTYPE_OR4B
: // v1 v2
9899 case OPTYPE_XOR4B
: // v1 v2
9900 case OPTYPE_SHL
: // v1 v2
9901 case OPTYPE_SHR
: // v1 v2
9902 case OPTYPE_ROTL
: // v1 v2
9903 case OPTYPE_ROTR
: // v1 v2
9904 case OPTYPE_INT2BIT
: // v1 v2
9905 case OPTYPE_INT2HEX
: // v1 v2
9906 case OPTYPE_INT2OCT
: // v1 v2
9907 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9908 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9910 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9911 case OPTYPE_OCT2UNICHAR
:
9912 case OPTYPE_ENCODE_BASE64
:
9913 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9914 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9916 case OPTYPE_DECOMP
: // v1 v2 v3
9917 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9918 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9919 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9922 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
9923 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
9925 case OPTYPE_SUBSTR
: // ti1 v2 v3
9926 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9927 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
9928 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
9931 case OPTYPE_REGEXP
: // ti1 t2 v3
9932 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9933 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9935 case OPTYPE_LENGTHOF
: // ti1
9936 case OPTYPE_SIZEOF
: // ti1
9937 case OPTYPE_VALUEOF
: // ti1
9938 case OPTYPE_ENCODE
: // ti1
9939 case OPTYPE_TTCN2STRING
:
9940 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9943 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
9944 // component.create -- assume no self-ref
9945 case OPTYPE_ACTIVATE
: // r1
9946 // defaultref := activate(altstep) -- assume no self-ref
9947 case OPTYPE_TMR_RUNNING
: // r1
9948 // boolvar := a_timer.running -- assume no self-ref
9952 case OPTYPE_LOG2STR
: {// logargs
9953 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
9954 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
9955 switch (la
->get_type()) {
9956 case Ttcn::LogArgument::L_UNDEF
:
9957 case Ttcn::LogArgument::L_ERROR
:
9958 FATAL_ERROR("log2str argument type");
9959 break; // not reached
9961 case Ttcn::LogArgument::L_MACRO
:
9962 case Ttcn::LogArgument::L_STR
:
9963 break; // self reference not possible
9965 case Ttcn::LogArgument::L_VAL
:
9966 case Ttcn::LogArgument::L_MATCH
:
9967 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
9970 case Ttcn::LogArgument::L_REF
: {
9971 Ttcn::Ref_base
*ref
= la
->get_ref();
9972 Common::Assignment
*ass
= ref
->get_refd_assignment();
9973 self_ref
|= (ass
== lhs
);
9976 case Ttcn::LogArgument::L_TI
: {
9977 Ttcn::TemplateInstance
*ti
= la
->get_ti();
9978 Ttcn::Template
*t
= ti
->get_Template();
9979 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
9982 // no default please
9983 } // switch la->logargtype
9987 case OPTYPE_DECODE
: { // r1 r2
9988 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
9989 self_ref
|= (ass
== lhs
);
9991 case OPTYPE_EXECUTE
: // r1 [v2]
9993 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9997 case OPTYPE_UNDEF_RUNNING
: // r1
9998 case OPTYPE_TMR_READ
: { // r1
9999 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
10000 self_ref
|= (ass
== lhs
);
10003 case OPTYPE_ISCHOSEN_T
: // t1 i2
10004 case OPTYPE_ISBOUND
: // ti1
10005 case OPTYPE_ISVALUE
: // ti1
10006 case OPTYPE_ISPRESENT
: { // ti1
10008 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10009 else t
= u
.expr
.ti1
->get_Template();
10010 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10013 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10015 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10018 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10019 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10023 case NUMBER_OF_OPTYPES
: // can never happen
10024 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10025 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10027 } // switch u.expr.v_optype
10032 string
Value::create_stringRepr()
10034 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10035 switch (valuetype
) {
10037 return string("<erroneous>");
10039 return string("NULL");
10041 if (!parse_only
&& is_asn1()) {
10042 if (u
.val_bool
) return string("TRUE");
10043 else return string("FALSE");
10046 if (u
.val_bool
) return string("true");
10047 else return string("false");
10050 return u
.val_Int
->t_str();
10052 return Real2string(u
.val_Real
);
10055 case V_UNDEF_LOWERID
:
10056 return u
.val_id
->get_name();
10057 case V_NAMEDBITS
: {
10058 string
ret_val("{ ");
10059 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10060 if (i
>0) ret_val
+= ' ';
10061 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10066 string
ret_val('\'');
10067 ret_val
+= *u
.str
.val_str
;
10071 string
ret_val('\'');
10072 ret_val
+= *u
.str
.val_str
;
10076 string
ret_val('\'');
10077 ret_val
+= *u
.str
.val_str
;
10082 return u
.str
.val_str
->get_stringRepr();
10084 return u
.ustr
.val_ustr
->get_stringRepr();
10086 /** \todo stringrepr of V_CHARSYMS */
10087 return string("<sorry, string representation of charsyms "
10088 "not implemented>");
10092 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10094 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10095 if (i
>0) ret_val
+= ' ';
10096 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10101 if (!parse_only
&& is_asn1()) {
10102 string
ret_val(u
.choice
.alt_name
->get_dispname());
10104 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10108 string
ret_val("{ ");
10109 ret_val
+= u
.choice
.alt_name
->get_dispname();
10111 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10118 string
ret_val("{ ");
10119 if (!is_indexed()) {
10120 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10121 if (i
> 0) ret_val
+= ", ";
10122 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10125 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10126 if (i
> 0) ret_val
+= ", ";
10127 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10134 string
ret_val("{ ");
10135 bool asn1_flag
= !parse_only
&& is_asn1();
10136 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10137 if (i
> 0) ret_val
+= ", ";
10138 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10139 ret_val
+= nv
->get_name().get_dispname();
10140 if (asn1_flag
) ret_val
+= ' ';
10141 else ret_val
+= " := ";
10142 ret_val
+= nv
->get_value()->get_stringRepr();
10147 // do not evaluate the reference if it is not done so far
10148 // (e.g. in parse-only mode)
10149 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10150 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10151 else return t_val
->get_stringRepr(); }
10153 return string("omit");
10155 switch (u
.verdict
) {
10157 return string("none");
10159 return string("pass");
10160 case Verdict_INCONC
:
10161 return string("inconc");
10163 return string("fail");
10164 case Verdict_ERROR
:
10165 return string("error");
10167 return string("<unknown verdict value>");
10169 case V_DEFAULT_NULL
:
10171 return string("null");
10173 switch (u
.expr
.v_optype
) {
10175 return string("rnd()");
10176 case OPTYPE_TESTCASENAME
:
10177 return string("testcasename()");
10178 case OPTYPE_UNARYPLUS
:
10179 return create_stringRepr_unary("+");
10180 case OPTYPE_UNARYMINUS
:
10181 return create_stringRepr_unary("-");
10183 return create_stringRepr_unary("not");
10185 return create_stringRepr_unary("not4b");
10186 case OPTYPE_BIT2HEX
:
10187 return create_stringRepr_predef1("bit2hex");
10188 case OPTYPE_BIT2INT
:
10189 return create_stringRepr_predef1("bit2int");
10190 case OPTYPE_BIT2OCT
:
10191 return create_stringRepr_predef1("bit2oct");
10192 case OPTYPE_BIT2STR
:
10193 return create_stringRepr_predef1("bit2str");
10194 case OPTYPE_CHAR2INT
:
10195 return create_stringRepr_predef1("char2int");
10196 case OPTYPE_CHAR2OCT
:
10197 return create_stringRepr_predef1("char2oct");
10198 case OPTYPE_FLOAT2INT
:
10199 return create_stringRepr_predef1("float2int");
10200 case OPTYPE_FLOAT2STR
:
10201 return create_stringRepr_predef1("float2str");
10202 case OPTYPE_HEX2BIT
:
10203 return create_stringRepr_predef1("hex2bit");
10204 case OPTYPE_HEX2INT
:
10205 return create_stringRepr_predef1("hex2int");
10206 case OPTYPE_HEX2OCT
:
10207 return create_stringRepr_predef1("hex2oct");
10208 case OPTYPE_HEX2STR
:
10209 return create_stringRepr_predef1("hex2str");
10210 case OPTYPE_INT2CHAR
:
10211 return create_stringRepr_predef1("int2char");
10212 case OPTYPE_INT2FLOAT
:
10213 return create_stringRepr_predef1("int2float");
10214 case OPTYPE_INT2STR
:
10215 return create_stringRepr_predef1("int2str");
10216 case OPTYPE_INT2UNICHAR
:
10217 return create_stringRepr_predef1("int2unichar");
10218 case OPTYPE_OCT2BIT
:
10219 return create_stringRepr_predef1("oct2bit");
10220 case OPTYPE_OCT2CHAR
:
10221 return create_stringRepr_predef1("oct2char");
10222 case OPTYPE_OCT2HEX
:
10223 return create_stringRepr_predef1("oct2hex");
10224 case OPTYPE_OCT2INT
:
10225 return create_stringRepr_predef1("oct2int");
10226 case OPTYPE_OCT2STR
:
10227 return create_stringRepr_predef1("oct2str");
10228 case OPTYPE_GET_STRINGENCODING
:
10229 return create_stringRepr_predef1("get_stringencoding");
10230 case OPTYPE_REMOVE_BOM
:
10231 return create_stringRepr_predef1("remove_bom");
10232 case OPTYPE_ENCODE_BASE64
: {
10233 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10234 else return create_stringRepr_predef1("encode_base64");
10236 case OPTYPE_DECODE_BASE64
:
10237 return create_stringRepr_predef1("decode_base64");
10238 case OPTYPE_OCT2UNICHAR
:{
10239 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10240 else return create_stringRepr_predef1("oct2unichar");
10242 case OPTYPE_UNICHAR2OCT
: {
10243 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10244 else return create_stringRepr_predef1("unichar2oct");
10246 case OPTYPE_STR2BIT
:
10247 return create_stringRepr_predef1("str2bit");
10248 case OPTYPE_STR2FLOAT
:
10249 return create_stringRepr_predef1("str2float");
10250 case OPTYPE_STR2HEX
:
10251 return create_stringRepr_predef1("str2hex");
10252 case OPTYPE_STR2INT
:
10253 return create_stringRepr_predef1("str2int");
10254 case OPTYPE_STR2OCT
:
10255 return create_stringRepr_predef1("str2oct");
10256 case OPTYPE_UNICHAR2INT
:
10257 return create_stringRepr_predef1("unichar2int");
10258 case OPTYPE_UNICHAR2CHAR
:
10259 return create_stringRepr_predef1("unichar2char");
10260 case OPTYPE_ENUM2INT
:
10261 return create_stringRepr_predef1("enum2int");
10262 case OPTYPE_ENCODE
:
10263 return create_stringRepr_predef1("encvalue");
10264 case OPTYPE_DECODE
:
10265 return create_stringRepr_predef2("decvalue");
10266 case OPTYPE_RNDWITHVAL
:
10267 return create_stringRepr_predef1("rnd");
10269 return create_stringRepr_infix("+");
10270 case OPTYPE_SUBTRACT
:
10271 return create_stringRepr_infix("-");
10272 case OPTYPE_MULTIPLY
:
10273 return create_stringRepr_infix("*");
10274 case OPTYPE_DIVIDE
:
10275 return create_stringRepr_infix("/");
10277 return create_stringRepr_infix("mod");
10279 return create_stringRepr_infix("rem");
10280 case OPTYPE_CONCAT
:
10281 return create_stringRepr_infix("&");
10283 return create_stringRepr_infix("==");
10285 return create_stringRepr_infix("<");
10287 return create_stringRepr_infix(">");
10289 return create_stringRepr_infix("!=");
10291 return create_stringRepr_infix(">=");
10293 return create_stringRepr_infix("<=");
10295 return create_stringRepr_infix("and");
10297 return create_stringRepr_infix("or");
10299 return create_stringRepr_infix("xor");
10301 return create_stringRepr_infix("and4b");
10303 return create_stringRepr_infix("or4b");
10305 return create_stringRepr_infix("xor4b");
10307 return create_stringRepr_infix("<<");
10309 return create_stringRepr_infix(">>");
10311 return create_stringRepr_infix("<@");
10313 return create_stringRepr_infix("@>");
10314 case OPTYPE_INT2BIT
:
10315 return create_stringRepr_predef2("int2bit");
10316 case OPTYPE_INT2HEX
:
10317 return create_stringRepr_predef2("int2hex");
10318 case OPTYPE_INT2OCT
:
10319 return create_stringRepr_predef2("int2oct");
10320 case OPTYPE_SUBSTR
: {
10321 string
ret_val("substr(");
10322 u
.expr
.ti1
->append_stringRepr(ret_val
);
10324 ret_val
+= u
.expr
.v2
->get_stringRepr();
10326 ret_val
+= u
.expr
.v3
->get_stringRepr();
10330 case OPTYPE_REGEXP
: {
10331 string
ret_val("regexp(");
10332 u
.expr
.ti1
->append_stringRepr(ret_val
);
10334 u
.expr
.t2
->append_stringRepr(ret_val
);
10336 ret_val
+= u
.expr
.v3
->get_stringRepr();
10340 case OPTYPE_DECOMP
: {
10341 string
ret_val("decomp(");
10342 ret_val
+= u
.expr
.v1
->get_stringRepr();
10344 ret_val
+= u
.expr
.v2
->get_stringRepr();
10346 ret_val
+= u
.expr
.v3
->get_stringRepr();
10350 case OPTYPE_REPLACE
: {
10351 string
ret_val("replace(");
10352 u
.expr
.ti1
->append_stringRepr(ret_val
);
10354 ret_val
+= u
.expr
.v2
->get_stringRepr();
10356 ret_val
+= u
.expr
.v3
->get_stringRepr();
10358 u
.expr
.ti4
->append_stringRepr(ret_val
);
10362 case OPTYPE_ISPRESENT
: {
10363 string
ret_val("ispresent(");
10364 u
.expr
.ti1
->append_stringRepr(ret_val
);
10367 case OPTYPE_ISCHOSEN
: {
10368 string
ret_val("ischosen(");
10369 ret_val
+= u
.expr
.r1
->get_dispname();
10371 ret_val
+= u
.expr
.i2
->get_dispname();
10374 case OPTYPE_ISCHOSEN_V
: {
10375 string
ret_val("ischosen(");
10376 ret_val
+= u
.expr
.v1
->get_stringRepr();
10378 ret_val
+= u
.expr
.i2
->get_dispname();
10381 case OPTYPE_ISCHOSEN_T
: {
10382 string
ret_val("ischosen(");
10383 ret_val
+= u
.expr
.t1
->get_stringRepr();
10385 ret_val
+= u
.expr
.i2
->get_dispname();
10388 case OPTYPE_LENGTHOF
: {
10389 string
ret_val("lengthof(");
10390 u
.expr
.ti1
->append_stringRepr(ret_val
);
10393 case OPTYPE_SIZEOF
: {
10394 string
ret_val("sizeof(");
10395 u
.expr
.ti1
->append_stringRepr(ret_val
);
10398 case OPTYPE_ISVALUE
: {
10399 string
ret_val("isvalue(");
10400 u
.expr
.ti1
->append_stringRepr(ret_val
);
10403 case OPTYPE_VALUEOF
: {
10404 string
ret_val("valueof(");
10405 u
.expr
.ti1
->append_stringRepr(ret_val
);
10408 case OPTYPE_LOG2STR
:
10409 return string("log2str(...)");
10410 case OPTYPE_MATCH
: {
10411 string
ret_val("match(");
10412 ret_val
+= u
.expr
.v1
->get_stringRepr();
10414 u
.expr
.t2
->append_stringRepr(ret_val
);
10417 case OPTYPE_TTCN2STRING
: {
10418 string
ret_val("ttcn2string(");
10419 u
.expr
.ti1
->append_stringRepr(ret_val
);
10423 case OPTYPE_UNDEF_RUNNING
:
10424 return u
.expr
.r1
->get_dispname() + ".running";
10425 case OPTYPE_COMP_NULL
:
10426 return string("null");
10427 case OPTYPE_COMP_MTC
:
10428 return string("mtc");
10429 case OPTYPE_COMP_SYSTEM
:
10430 return string("system");
10431 case OPTYPE_COMP_SELF
:
10432 return string("self");
10433 case OPTYPE_COMP_CREATE
: {
10434 string
ret_val(u
.expr
.r1
->get_dispname());
10435 ret_val
+= ".create";
10436 if (u
.expr
.v2
|| u
.expr
.v3
) {
10438 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10439 else ret_val
+= '-';
10442 ret_val
+= u
.expr
.v3
->get_stringRepr();
10446 if (u
.expr
.b4
) ret_val
+= " alive";
10448 case OPTYPE_COMP_RUNNING
:
10449 return u
.expr
.v1
->get_stringRepr() + ".running";
10450 case OPTYPE_COMP_RUNNING_ANY
:
10451 return string("any component.running");
10452 case OPTYPE_COMP_RUNNING_ALL
:
10453 return string("all component.running");
10454 case OPTYPE_COMP_ALIVE
:
10455 return u
.expr
.v1
->get_stringRepr() + ".alive";
10456 case OPTYPE_COMP_ALIVE_ANY
:
10457 return string("any component.alive");
10458 case OPTYPE_COMP_ALIVE_ALL
:
10459 return string("all component.alive");
10460 case OPTYPE_TMR_READ
:
10461 return u
.expr
.r1
->get_dispname() + ".read";
10462 case OPTYPE_TMR_RUNNING
:
10463 return u
.expr
.r1
->get_dispname() + ".running";
10464 case OPTYPE_TMR_RUNNING_ANY
:
10465 return string("any timer.running");
10466 case OPTYPE_GETVERDICT
:
10467 return string("getverdict");
10468 case OPTYPE_ACTIVATE
: {
10469 string
ret_val("activate(");
10470 ret_val
+= u
.expr
.r1
->get_dispname();
10473 case OPTYPE_ACTIVATE_REFD
: {
10474 string
ret_val("activate(derefer(");
10475 ret_val
+= u
.expr
.v1
->get_stringRepr();
10477 if (u
.expr
.state
== EXPR_CHECKED
) {
10478 if (u
.expr
.ap_list2
) {
10479 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10480 for (size_t i
= 0; i
< nof_pars
; i
++) {
10481 if (i
> 0) ret_val
+= ", ";
10482 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10486 if (u
.expr
.t_list2
) {
10487 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10488 for (size_t i
= 0; i
< nof_pars
; i
++) {
10489 if (i
> 0) ret_val
+= ", ";
10490 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10496 case OPTYPE_EXECUTE
: {
10497 string
ret_val("execute(");
10498 ret_val
+= u
.expr
.r1
->get_dispname();
10501 ret_val
+= u
.expr
.v2
->get_stringRepr();
10505 case OPTYPE_EXECUTE_REFD
: {
10506 string
ret_val("execute(derefers(");
10507 ret_val
+= u
.expr
.v1
->get_stringRepr();
10509 if (u
.expr
.state
== EXPR_CHECKED
) {
10510 if (u
.expr
.ap_list2
) {
10511 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10512 for (size_t i
= 0; i
< nof_pars
; i
++) {
10513 if (i
> 0) ret_val
+= ", ";
10514 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10518 if (u
.expr
.t_list2
) {
10519 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10520 for (size_t i
= 0; i
< nof_pars
; i
++) {
10521 if (i
> 0) ret_val
+= ", ";
10522 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10529 ret_val
+= u
.expr
.v3
->get_stringRepr();
10533 case OPTYPE_PROF_RUNNING
:
10534 return string("@profiler.running");
10536 return string("<unsupported optype>");
10537 } // switch u.expr.v_optype
10540 case MACRO_MODULEID
:
10541 return string("%moduleId");
10542 case MACRO_FILENAME
:
10543 return string("%fileName");
10544 case MACRO_BFILENAME
:
10545 return string("__BFILE__");
10546 case MACRO_FILEPATH
:
10547 return string("__FILE__");
10548 case MACRO_LINENUMBER
:
10549 return string("%lineNumber");
10550 case MACRO_LINENUMBER_C
:
10551 return string("__LINE__");
10552 case MACRO_DEFINITIONID
:
10553 return string("%definitionId");
10555 return string("__SCOPE__");
10556 case MACRO_TESTCASEID
:
10557 return string("%testcaseId");
10559 return string("<unknown macro>");
10560 } // switch u.macro
10562 return string('-');
10566 string
ret_val("refers(");
10567 ret_val
+= u
.refd_fat
->get_assname();
10572 ret_val
+= u
.invoke
.v
->get_stringRepr();
10573 ret_val
+= ".apply(";
10574 if (u
.invoke
.ap_list
) {
10575 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10576 for (size_t i
= 0; i
< nof_pars
; i
++) {
10577 if (i
> 0) ret_val
+= ", ";
10578 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10580 } else if (u
.invoke
.t_list
) {
10581 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10582 for (size_t i
= 0; i
< nof_pars
; i
++) {
10583 if (i
> 0) ret_val
+= ", ";
10584 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10590 string
ret_val("refers(");
10591 ret_val
+= u
.refered
->get_dispname();
10595 return string("<unsupported valuetype>");
10596 } // switch valuetype
10599 string
Value::create_stringRepr_unary(const char *operator_str
)
10601 string
ret_val(operator_str
);
10603 ret_val
+= u
.expr
.v1
->get_stringRepr();
10608 string
Value::create_stringRepr_infix(const char *operator_str
)
10610 string
ret_val('(');
10611 ret_val
+= u
.expr
.v1
->get_stringRepr();
10613 ret_val
+= operator_str
;
10615 ret_val
+= u
.expr
.v2
->get_stringRepr();
10620 string
Value::create_stringRepr_predef1(const char *function_name
)
10622 string
ret_val(function_name
);
10624 if (u
.expr
.v_optype
== OPTYPE_ENCODE
) { // ti1, not v1
10625 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10627 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10632 string
Value::create_stringRepr_predef2(const char *function_name
)
10634 string
ret_val(function_name
);
10636 ret_val
+= u
.expr
.v1
->get_stringRepr();
10638 ret_val
+= u
.expr
.v2
->get_stringRepr();
10643 bool Value::operator==(Value
& val
)
10645 Value
*left
= get_value_refd_last();
10646 Type
*left_governor
= left
->get_my_governor();
10647 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10648 Value
*right
= val
.get_value_refd_last();
10649 Type
*right_governor
= right
->get_my_governor();
10650 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10651 if (left_governor
&& right_governor
10652 && !left_governor
->is_compatible(right_governor
, NULL
)
10653 && !right_governor
->is_compatible(left_governor
, NULL
))
10654 FATAL_ERROR("Value::operator==");
10656 // Not-A-Value is not equal to anything (NaN analogy:)
10657 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10660 switch (left
->valuetype
) {
10663 case V_DEFAULT_NULL
:
10666 return left
->valuetype
== right
->valuetype
;
10668 return right
->valuetype
== V_BOOL
&&
10669 left
->get_val_bool() == right
->get_val_bool();
10671 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10672 == *right
->get_val_Int();
10674 return right
->valuetype
== V_REAL
&&
10675 left
->get_val_Real() == right
->get_val_Real();
10677 switch (right
->valuetype
) {
10679 return left
->get_val_str() == right
->get_val_str();
10681 return right
->get_val_ustr() == left
->get_val_str();
10683 return right
->get_val_iso2022str() == left
->get_val_str();
10690 return left
->valuetype
== right
->valuetype
&&
10691 left
->get_val_str() == right
->get_val_str();
10693 switch (right
->valuetype
) {
10695 return left
->get_val_ustr() == right
->get_val_str();
10697 return left
->get_val_ustr() == right
->get_val_ustr();
10699 return left
->get_val_ustr() == right
->get_val_iso2022str();
10704 switch (right
->valuetype
) {
10706 return left
->get_val_iso2022str() == right
->get_val_str();
10708 // The appropriate operator==() is missing. The operands are swapped,
10709 // but it shouldn't be a problem.
10710 return right
->get_val_ustr() == left
->get_val_iso2022str();
10712 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10717 return right
->valuetype
== V_ENUM
&&
10718 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10721 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10722 vector
<string
> act
, other
;
10723 get_oid_comps(act
);
10724 val
.get_oid_comps(other
);
10725 size_t act_size
= act
.size(), other_size
= other
.size();
10727 if (act_size
== other_size
) {
10729 for (size_t i
= 0; i
< act_size
; i
++)
10730 if (*act
[i
] != *other
[i
]) {
10734 } else ret_val
= false;
10735 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10737 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10740 } else return false;
10742 return right
->valuetype
== V_CHOICE
&&
10743 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10744 *(left
->get_alt_value()) == *(right
->get_alt_value());
10747 if (!left_governor
) FATAL_ERROR("Value::operator==");
10748 if (left
->valuetype
!= right
->valuetype
) return false;
10749 size_t nof_comps
= left_governor
->get_nof_comps();
10750 for (size_t i
= 0; i
< nof_comps
; i
++) {
10751 Value
*lval
= NULL
, *rval
= NULL
;
10752 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10753 const Identifier
& field_name
= cfl
->get_name();
10754 if (left
->has_comp_withName(field_name
)) {
10755 lval
= left
->get_comp_value_byName(field_name
);
10756 if (right
->has_comp_withName(field_name
)) {
10757 rval
= right
->get_comp_value_byName(field_name
);
10758 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10759 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10761 else if (!(*lval
== *rval
))
10764 if (cfl
->has_default()) {
10765 if (!(*lval
== *cfl
->get_defval()))
10768 if (lval
->valuetype
!= V_OMIT
)
10773 if(right
->has_comp_withName(field_name
)) {
10774 rval
= right
->get_comp_value_byName(field_name
);
10775 if(cfl
->has_default()) {
10776 if(rval
->valuetype
==V_OMIT
) return false;
10778 lval
= cfl
->get_defval();
10779 if (!(*lval
==*rval
)) return false;
10788 if (left
->valuetype
!= right
->valuetype
) return false;
10789 size_t ncomps
= get_nof_comps();
10790 if (ncomps
!= right
->get_nof_comps()) return false;
10792 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
10793 bool found
= false;
10794 map
<IndexedValue
*, void> uncovered
;
10795 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
10796 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
10798 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
10800 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
10801 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
10802 *(right
->get_comp_byIndex(i
)) &&
10803 *(uncovered
.get_nth_key(j
)->get_index()) ==
10804 *(right
->get_index_byIndex(i
))) {
10806 uncovered
.erase(uncovered
.get_nth_key(j
));
10814 } else if (left
->is_indexed() || right
->is_indexed()) {
10815 Value
* indexed_one
= 0;
10816 Value
* not_indexed_one
= 0;
10818 if(left
->is_indexed()) { // left is indexed, right is not
10819 indexed_one
= left
;
10820 not_indexed_one
= right
;
10821 } else { // right indexed, left is not
10822 indexed_one
= right
;
10823 not_indexed_one
= left
;
10826 for(size_t i
= 0; i
< ncomps
; ++i
) {
10827 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
10828 if(!(ind
->valuetype
== V_INT
&&
10829 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
10830 *(indexed_one
->get_comp_byIndex(i
))))
10834 } else { // none of them is indexed
10835 for (size_t i
= 0; i
< ncomps
; i
++) {
10836 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
10843 if (right
->valuetype
!= V_SETOF
) return false;
10844 size_t ncomps
= get_nof_comps();
10845 if (ncomps
!= right
->get_nof_comps()) return false;
10846 if (ncomps
== 0) return true;
10847 map
<size_t, void> uncovered
;
10848 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
10849 for (size_t i
= 0; i
< ncomps
; i
++) {
10850 Value
*left_item
= left
->get_comp_byIndex(i
);
10851 bool pair_found
= false;
10852 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
10853 size_t right_index
= uncovered
.get_nth_key(j
);
10854 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
10855 uncovered
.erase(right_index
);
10867 return right
->valuetype
== V_VERDICT
&&
10868 left
->get_val_verdict() == right
->get_val_verdict();
10872 return left
->valuetype
== right
->valuetype
&&
10873 left
->get_refd_assignment() == right
->get_refd_assignment();
10875 FATAL_ERROR("Value::operator==");
10880 bool Value::operator<(Value
& val
)
10882 Value
*left
= get_value_refd_last();
10883 Type
*left_governor
= left
->get_my_governor();
10884 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
10885 Value
*right
= val
.get_value_refd_last();
10886 Type
*right_governor
= right
->get_my_governor();
10887 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
10888 if (left
->get_valuetype() != right
->get_valuetype())
10889 FATAL_ERROR("Value::operator<");
10892 return *left
->get_val_Int() < *right
->get_val_Int();
10894 return (left
->get_val_Real() < right
->get_val_Real());
10896 if(!left_governor
|| !right_governor
)
10897 FATAL_ERROR("Value::operator<");
10898 if(left_governor
!=right_governor
)
10899 FATAL_ERROR("Value::operator<");
10900 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
10901 right_governor
->get_enum_val_byId(*right
->get_val_id()));
10903 FATAL_ERROR("Value::operator<");
10908 bool Value::is_string_type(Type::expected_value_t exp_val
)
10910 switch (get_expr_returntype(exp_val
)) {
10922 void Value::generate_code_expr(expression_struct
*expr
)
10924 if (has_single_expr()) {
10925 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
10927 switch (valuetype
) {
10929 generate_code_expr_expr(expr
);
10937 const string
& tmp_id
= get_temporary_id();
10938 const char *tmp_id_str
= tmp_id
.c_str();
10939 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
10940 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
10941 set_genname_recursive(tmp_id
);
10942 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10943 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10946 const string
& tmp_id
= get_temporary_id();
10947 const char *tmp_id_str
= tmp_id
.c_str();
10948 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
10950 set_genname_recursive(tmp_id
);
10951 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10952 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10955 if (!get_needs_conversion()) {
10956 u
.ref
.ref
->generate_code_const_ref(expr
);
10958 Type
*my_gov
= get_expr_governor_last();
10959 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
10960 ->get_field_type(u
.ref
.ref
->get_subrefs(),
10961 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
10962 // Make sure that nothing goes wrong.
10963 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
10964 FATAL_ERROR("Value::generate_code_expr()");
10965 expression_struct expr_tmp
;
10966 Code::init_expr(&expr_tmp
);
10967 const string
& tmp_id1
= get_temporary_id();
10968 const char *tmp_id_str1
= tmp_id1
.c_str();
10969 const string
& tmp_id2
= get_temporary_id();
10970 const char *tmp_id_str2
= tmp_id2
.c_str();
10971 expr
->preamble
= mputprintf(expr
->preamble
,
10972 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
10974 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
10975 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
10976 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
10977 expr
->preamble
= mputprintf(expr
->preamble
,
10979 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10980 "and `%s' are not compatible at run-time\");\n",
10981 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
10982 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
10983 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
10984 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
10985 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
10989 generate_code_expr_invoke(expr
);
10992 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
10997 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
10999 generate_code_expr(expr
);
11000 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11001 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11004 bool Value::can_use_increment(Reference
*ref
) const
11006 if (valuetype
!= V_EXPR
) {
11009 switch (u
.expr
.v_optype
) {
11011 case OPTYPE_SUBTRACT
:
11016 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11017 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11018 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11019 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11020 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11021 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11027 char *Value::generate_code_init(char *str
, const char *name
)
11029 if (get_code_generated()) return str
;
11031 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11033 switch (valuetype
) {
11047 case V_DEFAULT_NULL
:
11052 // These values have a single string equivalent.
11053 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11056 if (u
.val_Int
->is_native_fit())
11057 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11059 // It's always an INTEGER.
11060 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11061 "}\n", get_single_expr().c_str(), name
);
11065 expression_struct expr
;
11066 Code::init_expr(&expr
);
11067 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11068 generate_code_expr(&expr
);
11069 str
= Code::merge_free_expr(str
, &expr
);
11072 str
= generate_code_init_choice(str
, name
);
11076 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11077 else str
= generate_code_init_indexed(str
, name
);
11080 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11081 else str
= generate_code_init_indexed(str
, name
);
11085 str
= generate_code_init_se(str
, name
);
11088 str
= generate_code_init_refd(str
, name
);
11092 case MACRO_TESTCASEID
:
11093 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11096 // all others must already be evaluated away
11097 FATAL_ERROR("Value::generate_code_init()");
11101 FATAL_ERROR("Value::generate_code_init()");
11104 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11106 set_code_generated();
11110 char *Value::rearrange_init_code(char *str
)
11112 switch (valuetype
) {
11114 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11116 str
= parlist
->rearrange_init_code(str
,
11117 u
.ref
.ref
->get_refd_assignment()->get_my_scope()->get_scope_mod_gen());
11121 str
= u
.invoke
.v
->rearrange_init_code(str
);
11122 str
= u
.invoke
.ap_list
->rearrange_init_code(str
,
11123 u
.invoke
.v
->get_expr_governor_last()->get_my_scope()->get_scope_mod_gen());
11126 switch (u
.expr
.v_optype
) {
11127 case OPTYPE_UNARYPLUS
:
11128 case OPTYPE_UNARYMINUS
:
11131 case OPTYPE_BIT2HEX
:
11132 case OPTYPE_BIT2INT
:
11133 case OPTYPE_BIT2OCT
:
11134 case OPTYPE_BIT2STR
:
11135 case OPTYPE_CHAR2INT
:
11136 case OPTYPE_CHAR2OCT
:
11137 case OPTYPE_FLOAT2INT
:
11138 case OPTYPE_FLOAT2STR
:
11139 case OPTYPE_HEX2BIT
:
11140 case OPTYPE_HEX2INT
:
11141 case OPTYPE_HEX2OCT
:
11142 case OPTYPE_HEX2STR
:
11143 case OPTYPE_INT2CHAR
:
11144 case OPTYPE_INT2FLOAT
:
11145 case OPTYPE_INT2STR
:
11146 case OPTYPE_INT2UNICHAR
:
11147 case OPTYPE_OCT2BIT
:
11148 case OPTYPE_OCT2CHAR
:
11149 case OPTYPE_OCT2HEX
:
11150 case OPTYPE_OCT2INT
:
11151 case OPTYPE_OCT2STR
:
11152 case OPTYPE_STR2BIT
:
11153 case OPTYPE_STR2FLOAT
:
11154 case OPTYPE_STR2HEX
:
11155 case OPTYPE_STR2INT
:
11156 case OPTYPE_STR2OCT
:
11157 case OPTYPE_UNICHAR2INT
:
11158 case OPTYPE_UNICHAR2CHAR
:
11159 case OPTYPE_ENUM2INT
:
11160 case OPTYPE_ISCHOSEN_V
:
11161 case OPTYPE_GET_STRINGENCODING
:
11162 case OPTYPE_REMOVE_BOM
:
11163 case OPTYPE_DECODE_BASE64
:
11164 str
= u
.expr
.v1
->rearrange_init_code(str
);
11166 case OPTYPE_DECODE
: {
11167 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11168 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11169 if (parlist
) str
= parlist
->rearrange_init_code(str
, ass
->get_my_scope()->get_scope_mod_gen());
11171 parlist
= u
.expr
.r2
->get_parlist();
11172 ass
= u
.expr
.r2
->get_refd_assignment();
11173 if (parlist
) str
= parlist
->rearrange_init_code(str
, ass
->get_my_scope()->get_scope_mod_gen());
11176 case OPTYPE_SUBTRACT
:
11177 case OPTYPE_MULTIPLY
:
11178 case OPTYPE_DIVIDE
:
11181 case OPTYPE_CONCAT
:
11198 case OPTYPE_INT2BIT
:
11199 case OPTYPE_INT2HEX
:
11200 case OPTYPE_INT2OCT
:
11201 //case OPTYPE_DECODE:
11202 str
= u
.expr
.v1
->rearrange_init_code(str
);
11203 str
= u
.expr
.v2
->rearrange_init_code(str
);
11205 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11206 case OPTYPE_OCT2UNICHAR
:
11207 case OPTYPE_ENCODE_BASE64
:
11208 str
= u
.expr
.v1
->rearrange_init_code(str
);
11209 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
);
11211 case OPTYPE_SUBSTR
:
11212 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11213 str
= u
.expr
.v2
->rearrange_init_code(str
);
11214 str
= u
.expr
.v3
->rearrange_init_code(str
);
11216 case OPTYPE_REGEXP
:
11217 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11218 str
= u
.expr
.t2
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11219 str
= u
.expr
.v3
->rearrange_init_code(str
);
11221 case OPTYPE_DECOMP
:
11222 str
= u
.expr
.v1
->rearrange_init_code(str
);
11223 str
= u
.expr
.v2
->rearrange_init_code(str
);
11224 str
= u
.expr
.v3
->rearrange_init_code(str
);
11226 case OPTYPE_REPLACE
:
11227 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11228 str
= u
.expr
.v2
->rearrange_init_code(str
);
11229 str
= u
.expr
.v3
->rearrange_init_code(str
);
11230 str
= u
.expr
.ti4
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11232 case OPTYPE_LENGTHOF
:
11233 case OPTYPE_SIZEOF
:
11234 case OPTYPE_VALUEOF
:
11235 case OPTYPE_ENCODE
:
11236 case OPTYPE_ISPRESENT
:
11237 case OPTYPE_TTCN2STRING
:
11238 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11240 case OPTYPE_ISCHOSEN_T
:
11241 str
= u
.expr
.t1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11244 str
= u
.expr
.v1
->rearrange_init_code(str
);
11245 str
= u
.expr
.t2
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11248 // other kinds of expressions cannot appear within templates
11258 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11259 size_t& blockcount
)
11261 char *s2
= memptystr();
11262 char *s1
= generate_code_tmp(NULL
, s2
);
11264 if (blockcount
== 0) {
11265 str
= mputstr(str
, "{\n");
11268 str
= mputstr(str
, s2
);
11271 str
=mputstr(str
, prefix
);
11272 str
=mputstr(str
, s1
);
11277 char *Value::generate_code_tmp(char *str
, char*& init
)
11279 expression_struct expr
;
11280 Code::init_expr(&expr
);
11281 generate_code_expr_mandatory(&expr
);
11282 if (expr
.preamble
|| expr
.postamble
) {
11283 if (valuetype
== V_EXPR
&&
11284 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11285 // a temporary variable is already introduced
11286 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11287 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11288 str
= mputstr(str
, expr
.expr
);
11290 const string
& tmp_id
= get_temporary_id();
11291 const char *tmp_id_str
= tmp_id
.c_str();
11292 init
= mputprintf(init
, "%s %s;\n"
11294 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11295 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11297 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11298 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11299 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11300 init
= mputstr(init
, "}\n");
11301 str
= mputstr(str
, tmp_id_str
);
11303 } else str
= mputstr(str
, expr
.expr
);
11304 Code::free_expr(&expr
);
11308 void Value::generate_code_log(expression_struct
*expr
)
11310 if (explicit_cast_needed()) {
11311 char *expr_backup
= expr
->expr
;
11313 generate_code_expr(expr
);
11314 const string
& tmp_id
= get_temporary_id();
11315 const char *tmp_id_str
= tmp_id
.c_str();
11316 // We have to create a temporary object, because the parser of GCC
11317 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11318 // constructor call that is, this does not work: type(...).log(); but
11319 // this works: type tmp(...); tmp.log();.
11320 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11321 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11324 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11326 generate_code_expr(expr
);
11328 expr
->expr
= mputstr(expr
->expr
, ".log()");
11331 void Value::generate_code_log_match(expression_struct
*expr
)
11333 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11334 FATAL_ERROR("Value::generate_code_log_match()");
11335 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11336 // compliance the whole code-generation should be checked. Standalone
11337 // constructs like: "A(a[0].f());" should be avoided. The current
11338 // solution for HK38721 uses an additional assignment to overcome the
11339 // issue. The generated code will be slower, but it's needed for old GCC
11340 // versions in specific circumstances.
11341 if (u
.expr
.t2
->needs_temp_ref()) {
11342 char *expr_backup
= expr
->expr
;
11344 u
.expr
.t2
->generate_code(expr
);
11345 const string
& tmp_id
= get_temporary_id();
11346 const char *tmp_id_str
= tmp_id
.c_str();
11347 expr
->preamble
= mputprintf(expr
->preamble
,
11348 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11349 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11351 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11353 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11354 // some reason "(A(NS::B)).a(C);" compiles fine.
11355 expr
->expr
= mputc(expr
->expr
, '(');
11356 u
.expr
.t2
->generate_code(expr
);
11357 expr
->expr
= mputc(expr
->expr
, ')');
11359 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11360 u
.expr
.v1
->generate_code_expr(expr
);
11361 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11364 void Value::generate_code_expr_expr(expression_struct
*expr
)
11366 switch (u
.expr
.v_optype
) {
11368 generate_code_expr_rnd(expr
, 0);
11370 case OPTYPE_UNARYPLUS
:
11371 // same as without the '+' operator
11372 u
.expr
.v1
->generate_code_expr(expr
);
11374 case OPTYPE_UNARYMINUS
:
11375 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11378 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11381 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11383 case OPTYPE_BIT2HEX
:
11384 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11386 case OPTYPE_BIT2INT
:
11387 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11389 case OPTYPE_BIT2OCT
:
11390 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11392 case OPTYPE_BIT2STR
:
11393 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11395 case OPTYPE_CHAR2INT
:
11396 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11398 case OPTYPE_CHAR2OCT
:
11399 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11401 case OPTYPE_FLOAT2INT
:
11402 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11404 case OPTYPE_FLOAT2STR
:
11405 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11407 case OPTYPE_HEX2BIT
:
11408 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11410 case OPTYPE_HEX2INT
:
11411 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11413 case OPTYPE_HEX2OCT
:
11414 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11416 case OPTYPE_HEX2STR
:
11417 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11419 case OPTYPE_INT2CHAR
:
11420 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11422 case OPTYPE_INT2FLOAT
:
11423 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11425 case OPTYPE_INT2STR
:
11426 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11428 case OPTYPE_INT2UNICHAR
:
11429 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11431 case OPTYPE_OCT2BIT
:
11432 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11434 case OPTYPE_OCT2CHAR
:
11435 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11437 case OPTYPE_GET_STRINGENCODING
:
11438 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11440 case OPTYPE_REMOVE_BOM
:
11441 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11443 case OPTYPE_ENCODE_BASE64
:
11445 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11447 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11449 case OPTYPE_DECODE_BASE64
:
11450 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11452 case OPTYPE_OCT2UNICHAR
:
11454 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11456 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11458 case OPTYPE_UNICHAR2OCT
:
11460 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11462 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11464 case OPTYPE_OCT2HEX
:
11465 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11467 case OPTYPE_OCT2INT
:
11468 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11470 case OPTYPE_OCT2STR
:
11471 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11473 case OPTYPE_STR2BIT
:
11474 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11476 case OPTYPE_STR2FLOAT
:
11477 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11479 case OPTYPE_STR2HEX
:
11480 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11482 case OPTYPE_STR2INT
:
11483 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11485 case OPTYPE_STR2OCT
:
11486 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11488 case OPTYPE_UNICHAR2INT
:
11489 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11491 case OPTYPE_UNICHAR2CHAR
:
11492 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11494 case OPTYPE_ENUM2INT
: {
11495 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11496 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11497 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11498 enum_type
->get_genname_value(my_scope
).c_str());
11499 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11500 expr
->expr
= mputc(expr
->expr
, ')');
11502 case OPTYPE_ENCODE
:
11503 generate_code_expr_encode(expr
);
11505 case OPTYPE_DECODE
:
11506 generate_code_expr_decode(expr
);
11508 case OPTYPE_RNDWITHVAL
:
11509 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11512 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11514 case OPTYPE_SUBTRACT
:
11515 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11517 case OPTYPE_MULTIPLY
:
11518 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11520 case OPTYPE_DIVIDE
:
11521 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11524 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11527 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11529 case OPTYPE_CONCAT
:
11530 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11533 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11536 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11539 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11542 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11545 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11548 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11552 generate_code_expr_and_or(expr
);
11555 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11558 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11561 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11564 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11567 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11570 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11573 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11576 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11578 case OPTYPE_INT2BIT
:
11579 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11581 case OPTYPE_INT2HEX
:
11582 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11584 case OPTYPE_INT2OCT
:
11585 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11587 case OPTYPE_SUBSTR
:
11588 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11589 else generate_code_expr_substr_replace_compat(expr
);
11591 case OPTYPE_REGEXP
:
11592 generate_code_expr_regexp(expr
);
11594 case OPTYPE_DECOMP
:
11595 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11597 case OPTYPE_REPLACE
:
11598 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11599 else generate_code_expr_substr_replace_compat(expr
);
11601 case OPTYPE_ISCHOSEN
: // r1 i2
11602 FATAL_ERROR("Value::generate_code_expr_expr()");
11604 case OPTYPE_ISCHOSEN_V
: // v1 i2
11605 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11606 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11607 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11608 u
.expr
.i2
->get_name().c_str());
11610 case OPTYPE_ISCHOSEN_T
: // t1 i2
11611 u
.expr
.t1
->generate_code_expr(expr
);
11612 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11613 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11614 u
.expr
.i2
->get_name().c_str());
11616 case OPTYPE_ISPRESENT
:
11617 case OPTYPE_ISBOUND
: {
11618 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11619 ->get_templatetype();
11620 if (temp
== Template::SPECIFIC_VALUE
) {
11621 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11622 ->get_specific_value();
11623 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11624 Ttcn::Reference
* reference
=
11625 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11627 reference
->generate_code_ispresentbound(expr
, false,
11628 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11632 } else if (temp
== Template::TEMPLATE_REFD
){
11633 Ttcn::Reference
* reference
=
11634 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11635 ->get_reference());
11637 reference
->generate_code_ispresentbound(expr
, true,
11638 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11644 case OPTYPE_LENGTHOF
: // ti1
11645 // fall through, separated later
11646 case OPTYPE_SIZEOF
: // ti1
11647 // fall through, separated later
11648 case OPTYPE_ISVALUE
: { // ti1
11649 if (u
.expr
.ti1
->is_only_specific_value()) {
11650 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11651 bool cast_needed
= t_val
->explicit_cast_needed(
11652 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11654 // the ambiguous C++ expression is converted to the value class
11655 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11656 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11659 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11660 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11661 t_val
->generate_code_expr(expr
);
11663 t_val
->generate_code_expr_mandatory(expr
);
11666 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11668 else u
.expr
.ti1
->generate_code(expr
);
11670 switch (u
.expr
.v_optype
) {
11671 case OPTYPE_ISBOUND
:
11672 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11674 case OPTYPE_ISPRESENT
:
11675 expr
->expr
=mputprintf(expr
->expr
, ".is_present(%s)",
11676 omit_in_value_list
? "TRUE" : "");
11678 case OPTYPE_SIZEOF
:
11679 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11681 case OPTYPE_LENGTHOF
:
11682 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11684 case OPTYPE_ISVALUE
:
11685 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11688 FATAL_ERROR("Value::generate_code_expr_expr()");
11691 case OPTYPE_VALUEOF
: // ti1
11692 u
.expr
.ti1
->generate_code(expr
);
11693 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11695 case OPTYPE_MATCH
: // v1 t2
11696 u
.expr
.t2
->generate_code(expr
);
11697 expr
->expr
= mputstr(expr
->expr
, ".match(");
11698 u
.expr
.v1
->generate_code_expr(expr
);
11699 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11701 case OPTYPE_UNDEF_RUNNING
:
11702 // it is resolved during semantic check
11703 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11705 case OPTYPE_COMP_NULL
: // -
11706 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11708 case OPTYPE_COMP_MTC
: // -
11709 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11711 case OPTYPE_COMP_SYSTEM
: // -
11712 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11714 case OPTYPE_COMP_SELF
: // -
11715 expr
->expr
=mputstr(expr
->expr
, "self");
11717 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11718 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11721 case OPTYPE_COMP_RUNNING
: // v1
11722 u
.expr
.v1
->generate_code_expr(expr
);
11723 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11724 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11725 expr
->expr
= mputstr(expr
->expr
, ".running()");
11727 case OPTYPE_COMP_RUNNING_ANY
: // -
11728 expr
->expr
=mputstr(expr
->expr
,
11729 "TTCN_Runtime::component_running(ANY_COMPREF)");
11731 case OPTYPE_COMP_RUNNING_ALL
: // -
11732 expr
->expr
=mputstr(expr
->expr
,
11733 "TTCN_Runtime::component_running(ALL_COMPREF)");
11735 case OPTYPE_COMP_ALIVE
: // v1
11736 u
.expr
.v1
->generate_code_expr(expr
);
11737 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11738 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11739 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11741 case OPTYPE_COMP_ALIVE_ANY
: // -
11742 expr
->expr
= mputstr(expr
->expr
,
11743 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11745 case OPTYPE_COMP_ALIVE_ALL
: // -
11746 expr
->expr
= mputstr(expr
->expr
,
11747 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11749 case OPTYPE_TMR_READ
: // r1
11750 u
.expr
.r1
->generate_code(expr
);
11751 expr
->expr
= mputstr(expr
->expr
, ".read()");
11753 case OPTYPE_TMR_RUNNING
: // r1
11754 u
.expr
.r1
->generate_code(expr
);
11755 expr
->expr
= mputstr(expr
->expr
, ".running()");
11757 case OPTYPE_TMR_RUNNING_ANY
: // -
11758 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
11760 case OPTYPE_GETVERDICT
: // -
11761 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
11763 case OPTYPE_TESTCASENAME
: // -
11764 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
11766 case OPTYPE_ACTIVATE
: // r1
11767 generate_code_expr_activate(expr
);
11769 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
11770 generate_code_expr_activate_refd(expr
);
11772 case OPTYPE_EXECUTE
: // r1 [v2]
11773 generate_code_expr_execute(expr
);
11775 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
11776 generate_code_expr_execute_refd(expr
);
11778 case OPTYPE_LOG2STR
:
11779 u
.expr
.logargs
->generate_code_expr(expr
);
11781 case OPTYPE_TTCN2STRING
: {
11782 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
11783 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
11784 param_governor
= param_governor
->get_type_refd_last();
11785 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
11786 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
11787 u
.expr
.ti1
->get_Template()->is_Value()) {
11788 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
11791 bool cast_needed
= v
->explicit_cast_needed();
11793 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
11795 v
->generate_code_expr(expr
);
11797 expr
->expr
= mputstr(expr
->expr
, ")");
11801 u
.expr
.ti1
->generate_code(expr
);
11803 expr
->expr
= mputstr(expr
->expr
, ")");
11805 case OPTYPE_PROF_RUNNING
:
11806 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
11809 FATAL_ERROR("Value::generate_code_expr_expr()");
11813 void Value::generate_code_expr_unary(expression_struct
*expr
,
11814 const char *operator_str
, Value
*v1
)
11816 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
11817 v1
->generate_code_expr_mandatory(expr
);
11818 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
11821 void Value::generate_code_expr_infix(expression_struct
*expr
,
11822 const char *operator_str
, Value
*v1
,
11823 Value
*v2
, bool optional_allowed
)
11825 if (!get_needs_conversion()) {
11826 expr
->expr
= mputc(expr
->expr
, '(');
11827 if (optional_allowed
) v1
->generate_code_expr(expr
);
11828 else v1
->generate_code_expr_mandatory(expr
);
11829 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
11830 if (optional_allowed
) v2
->generate_code_expr(expr
);
11831 else v2
->generate_code_expr_mandatory(expr
);
11832 expr
->expr
= mputc(expr
->expr
, ')');
11833 } else { // Temporary variable for the converted value.
11834 const string
& tmp_id1
= get_temporary_id();
11835 const char *tmp_id_str1
= tmp_id1
.c_str();
11836 expression_struct expr_tmp
;
11837 Code::init_expr(&expr_tmp
);
11838 switch (u
.expr
.v_optype
) {
11841 // Always "v1 -> v2".
11842 Type
*t1
= v1
->get_expr_governor_last();
11843 Type
*t2
= v2
->get_expr_governor_last();
11844 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
11845 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11846 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11847 if (expr_tmp
.preamble
)
11848 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11849 expr
->preamble
= mputprintf(expr
->preamble
,
11851 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11852 "and `%s' are not compatible at run-time\");\n",
11853 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
11854 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
11855 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
11856 t2
->get_typename().c_str(), t1
->get_typename().c_str());
11857 Code::free_expr(&expr_tmp
);
11858 if (optional_allowed
) v1
->generate_code_expr(expr
);
11859 else v1
->generate_code_expr_mandatory(expr
);
11860 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
11863 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11864 // functions. The governors of all operands must exist at this point.
11867 case OPTYPE_CONCAT
: {
11868 const string
& tmp_id2
= get_temporary_id();
11869 const char *tmp_id_str2
= tmp_id2
.c_str();
11870 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
11871 Type
*my_gov
= my_governor
->get_type_refd_last();
11872 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
11873 ->get_type_refd_last();
11874 if (!t1_gov
|| my_gov
== t1_gov
)
11875 FATAL_ERROR("Value::generate_code_expr_infix()");
11876 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11877 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
11878 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11879 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
11880 else v1
->generate_code_expr_mandatory(&expr_tmp
);
11881 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
11882 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11883 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11884 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11885 expr
->preamble
= mputprintf(expr
->preamble
,
11887 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11888 "and `%s' are not compatible at run-time\");\n",
11889 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11890 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
11891 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
11892 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
11893 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11896 FATAL_ERROR("Value::generate_code_expr_infix()");
11902 void Value::generate_code_expr_and_or(expression_struct
*expr
)
11904 if (u
.expr
.v2
->needs_short_circuit()) {
11905 // introduce a temporary variable to store the result of the operation
11906 const string
& tmp_id
= get_temporary_id();
11907 const char *tmp_id_str
= tmp_id
.c_str();
11908 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
11909 expression_struct expr2
;
11910 // the left operand must be evaluated anyway
11911 Code::init_expr(&expr2
);
11912 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11913 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
11914 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11915 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
11916 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
11917 // evaluate the right operand only when necessary
11918 // in this case the final result will be the right operand
11919 Code::init_expr(&expr2
);
11920 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11921 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
11922 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11923 // the result is now in the temporary variable
11924 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11926 // use the overloaded operator to get better error messages
11927 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
11928 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
11932 void Value::generate_code_expr_predef1(expression_struct
*expr
,
11933 const char *function_name
,
11936 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11937 v1
->generate_code_expr_mandatory(expr
);
11938 expr
->expr
= mputc(expr
->expr
, ')');
11941 void Value::generate_code_expr_predef2(expression_struct
*expr
,
11942 const char *function_name
,
11943 Value
*v1
, Value
*v2
)
11945 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11946 v1
->generate_code_expr_mandatory(expr
);
11947 expr
->expr
= mputstr(expr
->expr
, ", ");
11948 v2
->generate_code_expr_mandatory(expr
);
11949 expr
->expr
= mputc(expr
->expr
, ')');
11952 void Value::generate_code_expr_predef3(expression_struct
*expr
,
11953 const char *function_name
,
11954 Value
*v1
, Value
*v2
, Value
*v3
)
11956 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11957 v1
->generate_code_expr_mandatory(expr
);
11958 expr
->expr
= mputstr(expr
->expr
, ", ");
11959 v2
->generate_code_expr_mandatory(expr
);
11960 expr
->expr
= mputstr(expr
->expr
, ", ");
11961 v3
->generate_code_expr_mandatory(expr
);
11962 expr
->expr
= mputc(expr
->expr
, ')');
11965 void Value::generate_code_expr_substr(expression_struct
*expr
)
11968 Value
* v1
= u
.expr
.ti1
->get_specific_value();
11969 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11970 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11971 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
11972 if (v1
) v1
->generate_code_expr_mandatory(expr
);
11973 else u
.expr
.ti1
->generate_code(expr
);
11974 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
11975 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
11976 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
11977 expr
->expr
= mputstr(expr
->expr
, "(int)");
11978 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
11979 expr
->expr
= mputstr(expr
->expr
, ", ");
11980 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
11981 expr
->expr
= mputstr(expr
->expr
, "(int)");
11982 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
11983 expr
->expr
= mputc(expr
->expr
, ')');
11986 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
11988 expression_struct expr_tmp
;
11989 Code::init_expr(&expr_tmp
);
11990 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11991 ->get_type_refd_last();
11992 if (!t1
|| t1
== my_governor
->get_type_refd_last())
11993 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11994 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
11995 generate_code_expr_substr(&expr_tmp
);
11996 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
11997 generate_code_expr_replace(&expr_tmp
);
11999 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12001 // Two temporaries to store the result of substr() or replace() and to
12002 // store the converted value.
12003 const string
& tmp_id1
= get_temporary_id();
12004 const char *tmp_id_str1
= tmp_id1
.c_str();
12005 const string
& tmp_id2
= get_temporary_id();
12006 const char *tmp_id_str2
= tmp_id2
.c_str();
12007 if (expr_tmp
.preamble
)
12008 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12009 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12010 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12011 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12012 if (expr_tmp
.postamble
)
12013 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12014 Code::free_expr(&expr_tmp
);
12015 expr
->preamble
= mputprintf(expr
->preamble
,
12016 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12017 "`%s' are not compatible at run-time\");\n",
12018 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12019 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12020 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12021 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12024 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12026 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12027 Value
* v2
= u
.expr
.t2
->get_specific_value();
12028 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12029 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12030 else u
.expr
.ti1
->generate_code(expr
);
12031 expr
->expr
= mputstr(expr
->expr
, ", ");
12032 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12033 else u
.expr
.t2
->generate_code(expr
);
12034 expr
->expr
= mputstr(expr
->expr
, ", ");
12035 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12036 expr
->expr
= mputc(expr
->expr
, ')');
12039 void Value::generate_code_expr_replace(expression_struct
*expr
)
12041 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12042 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12044 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12045 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12046 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12047 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12048 else u
.expr
.ti1
->generate_code(expr
);
12049 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12050 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12051 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12052 expr
->expr
= mputstr(expr
->expr
, "(int)");
12053 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12054 expr
->expr
= mputstr(expr
->expr
, ", ");
12055 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12056 expr
->expr
= mputstr(expr
->expr
, "(int)");
12057 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12058 expr
->expr
= mputstr(expr
->expr
, ", ");
12060 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12061 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12062 Value
* v4_last
= v4
->get_value_refd_last();
12063 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12064 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12065 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12067 v4
->generate_code_expr_mandatory(expr
);
12069 else u
.expr
.ti4
->generate_code(expr
);
12070 expr
->expr
= mputc(expr
->expr
, ')');
12073 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12076 if(!v1
) // simple random generation
12077 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12078 else { // random generation with seeding
12079 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12080 v1
->generate_code_expr_mandatory(expr
);
12081 expr
->expr
= mputc(expr
->expr
, ')');
12085 void Value::generate_code_expr_create(expression_struct
*expr
,
12086 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12088 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12089 // first two arguments: component type
12090 Assignment
*t_ass
= type
->get_refd_assignment();
12091 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12092 FATAL_ERROR("Value::generate_code_expr_create()");
12093 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12094 Type::EXPECTED_DYNAMIC_VALUE
);
12095 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12096 comptype
= comptype
->get_type_refd_last();
12097 expr
->expr
= comptype
->get_CompBody()
12098 ->generate_code_comptype_name(expr
->expr
);
12099 expr
->expr
= mputstr(expr
->expr
, ", ");
12100 // third argument: component name
12102 Value
*t_val
= name
->get_value_refd_last();
12103 if (t_val
->valuetype
== V_CSTR
) {
12104 // the argument is foldable to a string literal
12105 size_t str_len
= t_val
->u
.str
.val_str
->size();
12106 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12107 expr
->expr
= mputc(expr
->expr
, '"');
12108 for (size_t i
= 0; i
< str_len
; i
++)
12109 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12110 expr
->expr
= mputc(expr
->expr
, '"');
12111 } else name
->generate_code_expr_mandatory(expr
);
12112 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12113 expr
->expr
= mputstr(expr
->expr
, ", ");
12114 // fourth argument: location
12116 Value
*t_val
= location
->get_value_refd_last();
12117 if (t_val
->valuetype
== V_CSTR
) {
12118 // the argument is foldable to a string literal
12119 size_t str_len
= t_val
->u
.str
.val_str
->size();
12120 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12121 expr
->expr
= mputc(expr
->expr
, '"');
12122 for (size_t i
= 0; i
< str_len
; i
++)
12123 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12124 expr
->expr
= mputc(expr
->expr
, '"');
12125 } else location
->generate_code_expr_mandatory(expr
);
12126 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12127 // fifth argument: alive flag
12128 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12131 void Value::generate_code_expr_activate(expression_struct
*expr
)
12133 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12134 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12135 FATAL_ERROR("Value::generate_code_expr_activate()");
12136 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12137 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12138 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12139 expr
->expr
= mputc(expr
->expr
, ')');
12142 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12144 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12145 if (v_last
->valuetype
== V_ALTSTEP
) {
12146 // the referred altstep is known
12147 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12148 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12150 // the referred altstep is unknown
12151 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12152 expr
->expr
= mputstr(expr
->expr
,".activate(");
12154 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12155 expr
->expr
= mputc(expr
->expr
, ')');
12158 void Value::generate_code_expr_execute(expression_struct
*expr
)
12160 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12161 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12162 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12163 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12164 if (parlist
->get_nof_pars() > 0) {
12165 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12167 expr
->expr
= mputstr(expr
->expr
, ", ");
12170 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12171 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12172 expr
->expr
= mputc(expr
->expr
, ')');
12173 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12176 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12178 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12179 if (v_last
->valuetype
== V_TESTCASE
) {
12180 // the referred testcase is known
12181 Assignment
*testcase
= v_last
->get_refd_fat();
12182 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12183 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12184 u
.expr
.ap_list2
->generate_code_alias(expr
,
12185 testcase
->get_FormalParList(), 0, false);
12187 // the referred testcase is unknown
12188 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12189 expr
->expr
= mputstr(expr
->expr
,".execute(");
12190 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12192 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12193 expr
->expr
= mputstr(expr
->expr
, ", ");
12195 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12196 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12197 expr
->expr
= mputc(expr
->expr
, ')');
12198 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12201 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12203 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12204 if (last_v
->get_valuetype() == V_FUNCTION
) {
12205 // the referred function is known
12206 Assignment
*function
= last_v
->get_refd_fat();
12207 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12208 function
->get_genname_from_scope(my_scope
).c_str());
12209 u
.invoke
.ap_list
->generate_code_alias(expr
,
12210 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12212 // the referred function is unknown
12213 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12214 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12215 Type
* gov_last
= last_v
->get_expr_governor_last();
12216 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12217 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12219 expr
->expr
= mputc(expr
->expr
, ')');
12222 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12225 // if the referenced value points to an optional value field the
12226 // generated code has to be corrected at the end:
12227 // `fieldid()' => `fieldid()()'
12228 Assignment
*ass
= ref
->get_refd_assignment();
12229 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12230 switch (ass
->get_asstype()) {
12231 case Assignment::A_CONST
:
12232 case Assignment::A_EXT_CONST
:
12233 case Assignment::A_MODULEPAR
:
12234 case Assignment::A_VAR
:
12235 case Assignment::A_FUNCTION_RVAL
:
12236 case Assignment::A_EXT_FUNCTION_RVAL
:
12237 case Assignment::A_PAR_VAL_IN
:
12238 case Assignment::A_PAR_VAL_OUT
:
12239 case Assignment::A_PAR_VAL_INOUT
:
12240 // only these are mapped to value objects
12241 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12242 expr
->expr
= mputstr(expr
->expr
, "()");
12249 void Value::generate_code_expr_encode(expression_struct
*expr
)
12253 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12254 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12255 v1
= templ
->get_specific_value();
12256 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12258 expression_struct expr2
;
12259 Code::init_expr(&expr2
);
12261 bool is_templ
= false;
12262 switch (templ
->get_templatetype()) {
12263 case Template::SPECIFIC_VALUE
:
12264 v1
->generate_code_expr_mandatory(&expr2
);
12267 u
.expr
.ti1
->generate_code(&expr2
);
12272 if (!gov_last
->is_coding_by_function()) {
12273 const string
& tmp_id
= get_temporary_id();
12274 const string
& tmp_buf_id
= get_temporary_id();
12275 const string
& tmp_ref_id
= get_temporary_id();
12276 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12278 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12279 tmp_buf_id
.c_str());
12280 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12281 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12282 expr
->preamble
= mputc (expr
->preamble
, '\n');
12284 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12285 gov_last
->get_genname_typedescriptor(
12286 u
.expr
.ti1
->get_Template()->get_my_scope()
12288 tmp_ref_id
.c_str(),
12290 if (is_templ
) // make a value out of the template, if needed
12291 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12292 expr
->preamble
= mputprintf(expr
->preamble
,
12293 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12294 tmp_ref_id
.c_str(),
12295 gov_last
->get_genname_typedescriptor(
12296 u
.expr
.ti1
->get_Template()->get_my_scope()
12298 tmp_buf_id
.c_str(),
12299 gov_last
->get_coding(true).c_str()
12301 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12302 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12303 tmp_buf_id
.c_str(),
12306 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12307 if (expr2
.postamble
)
12308 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12310 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12311 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12312 is_templ
? ".valueof()" : "");
12313 Code::free_expr(&expr2
);
12316 void Value::generate_code_expr_decode(expression_struct
*expr
)
12318 expression_struct expr1
, expr2
;
12319 Code::init_expr(&expr1
);
12320 Code::init_expr(&expr2
);
12321 u
.expr
.r1
->generate_code(&expr1
);
12322 u
.expr
.r2
->generate_code(&expr2
);
12324 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12325 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12326 get_type_refd_last();
12328 if (expr1
.preamble
)
12329 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12330 if (expr2
.preamble
)
12331 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12333 if (!_type
->is_coding_by_function()) {
12334 const string
& tmp_id
= get_temporary_id();
12335 const string
& buffer_id
= get_temporary_id();
12336 const string
& retval_id
= get_temporary_id();
12337 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12338 field_is_optional(u
.expr
.r2
->get_subrefs());
12340 expr
->preamble
= mputprintf(expr
->preamble
,
12341 "TTCN_Buffer %s(bit2oct(%s));\n"
12343 "TTCN_EncDec::set_error_behavior("
12344 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12345 "TTCN_EncDec::clear_error();\n",
12350 expr
->preamble
= mputprintf(expr
->preamble
,
12351 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12353 optional
? "()" : "",
12354 _type
->get_genname_typedescriptor(
12355 u
.expr
.r2
->get_my_scope()
12358 _type
->get_coding(false).c_str()
12360 expr
->preamble
= mputprintf(expr
->preamble
,
12361 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12362 "case TTCN_EncDec::ET_NONE: {\n"
12364 "OCTETSTRING %s;\n"
12365 "%s.get_string(%s);\n"
12366 "%s = oct2bit(%s);\n"
12369 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12370 "case TTCN_EncDec::ET_LEN_ERR:\n"
12376 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12377 "TTCN_EncDec::EB_DEFAULT);\n"
12378 "TTCN_EncDec::clear_error();\n",
12389 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12391 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12392 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12393 if (expr1
.postamble
)
12394 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12395 if (expr2
.postamble
)
12396 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12397 Code::free_expr(&expr1
);
12398 Code::free_expr(&expr2
);
12401 char *Value::generate_code_init_choice(char *str
, const char *name
)
12403 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12404 // Safe as long as get_name() returns a const string&, not a temporary.
12405 const char *alt_prefix
=
12406 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12408 if (u
.choice
.alt_value
->needs_temp_ref()) {
12409 const string
& tmp_id
= get_temporary_id();
12410 const char *tmp_id_str
= tmp_id
.c_str();
12411 str
= mputprintf(str
, "{\n"
12412 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12413 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12414 alt_prefix
, alt_name
);
12415 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12416 str
= mputstr(str
, "}\n");
12418 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12419 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12420 Free(embedded_name
);
12425 char *Value::generate_code_init_seof(char *str
, const char *name
)
12427 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12429 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12430 const string
& embedded_type
=
12431 my_governor
->get_ofType()->get_genname_value(my_scope
);
12432 const char *embedded_type_str
= embedded_type
.c_str();
12433 for (size_t i
= 0; i
< nof_vs
; i
++) {
12434 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12436 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12437 else if (comp_v
->needs_temp_ref()) {
12438 const string
& tmp_id
= get_temporary_id();
12439 const char *tmp_id_str
= tmp_id
.c_str();
12440 str
= mputprintf(str
, "{\n"
12441 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12442 (unsigned long) i
);
12443 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12444 str
= mputstr(str
, "}\n");
12446 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12447 str
= comp_v
->generate_code_init(str
, embedded_name
);
12448 Free(embedded_name
);
12452 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12457 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12459 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12461 // Previous values can be truncated. The concept is similar to
12463 Type
*t_last
= my_governor
->get_type_refd_last();
12464 const string
& oftype_name
=
12465 t_last
->get_ofType()->get_genname_value(my_scope
);
12466 const char *oftype_name_str
= oftype_name
.c_str();
12467 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12468 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12469 const string
& tmp_id_1
= get_temporary_id();
12470 str
= mputstr(str
, "{\n");
12471 Value
*index
= iv
->get_index();
12472 if (index
->get_valuetype() != V_INT
) {
12473 const string
& tmp_id_2
= get_temporary_id();
12474 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12475 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12476 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12477 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12479 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12480 tmp_id_1
.c_str(), name
,
12481 (index
->get_val_Int()->t_str()).c_str());
12483 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12484 str
= mputstr(str
, "}\n");
12486 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12490 char *Value::generate_code_init_array(char *str
, const char *name
)
12492 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12493 Type
*t_last
= my_governor
->get_type_refd_last();
12494 Int index_offset
= t_last
->get_dimension()->get_offset();
12495 const string
& embedded_type
=
12496 t_last
->get_ofType()->get_genname_value(my_scope
);
12497 const char *embedded_type_str
= embedded_type
.c_str();
12498 for (size_t i
= 0; i
< nof_vs
; i
++) {
12499 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12500 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12501 else if (comp_v
->needs_temp_ref()) {
12502 const string
& tmp_id
= get_temporary_id();
12503 const char *tmp_id_str
= tmp_id
.c_str();
12504 str
= mputprintf(str
, "{\n"
12505 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12506 Int2string(index_offset
+ i
).c_str());
12507 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12508 str
= mputstr(str
, "}\n");
12510 char *embedded_name
= mprintf("%s[%s]", name
,
12511 Int2string(index_offset
+ i
).c_str());
12512 str
= comp_v
->generate_code_init(str
, embedded_name
);
12513 Free(embedded_name
);
12519 char *Value::generate_code_init_se(char *str
, const char *name
)
12521 Type
*type
= my_governor
->get_type_refd_last();
12522 size_t nof_comps
= type
->get_nof_comps();
12523 if (nof_comps
> 0) {
12524 for (size_t i
= 0; i
< nof_comps
; i
++) {
12525 CompField
*cf
= type
->get_comp_byIndex(i
);
12526 const Identifier
& field_id
= cf
->get_name();
12527 const char *field_name
= field_id
.get_name().c_str();
12529 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12530 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12531 if (field_v
->valuetype
== V_NOTUSED
) continue;
12532 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12533 } else if (is_asn1()) {
12534 if (cf
->has_default()) {
12535 // handle like a referenced value
12536 Value
*defval
= cf
->get_defval();
12537 if (needs_init_precede(defval
)) {
12538 str
= defval
->generate_code_init(str
,
12539 defval
->get_lhs_name().c_str());
12541 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12542 defval
->get_genname_own(my_scope
).c_str());
12545 if (!cf
->get_is_optional())
12546 FATAL_ERROR("Value::generate_code_init()");
12553 // the value is not omit
12554 if (field_v
->needs_temp_ref()) {
12555 const string
& tmp_id
= get_temporary_id();
12556 const char *tmp_id_str
= tmp_id
.c_str();
12557 str
= mputprintf(str
, "{\n"
12558 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
12559 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12561 str
= field_v
->generate_code_init(str
, tmp_id_str
);
12562 str
= mputstr(str
, "}\n");
12564 char *embedded_name
= mprintf("%s.%s()", name
,
12566 if (cf
->get_is_optional() && field_v
->is_compound())
12567 embedded_name
= mputstr(embedded_name
, "()");
12568 str
= field_v
->generate_code_init(str
, embedded_name
);
12569 Free(embedded_name
);
12572 // the value is omit
12573 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
12578 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12583 char *Value::generate_code_init_refd(char *str
, const char *name
)
12585 Value
*v
= get_value_refd_last();
12587 // the referred value is not available at compile time
12588 // the code generation is based on the reference
12589 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
12590 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
12592 expression_struct expr
;
12593 Code::init_expr(&expr
);
12594 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
12595 u
.ref
.ref
->generate_code_const_ref(&expr
);
12596 str
= Code::merge_free_expr(str
, &expr
);
12599 // the referred value is available at compile time
12600 // the code generation is based on the referred value
12601 if (v
->has_single_expr() &&
12602 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
12603 // simple substitution for in-line values within the same module
12604 str
= mputprintf(str
, "%s = %s;\n", name
,
12605 v
->get_single_expr().c_str());
12607 // use a simple reference to reduce code size
12608 if (needs_init_precede(v
)) {
12609 // the referred value must be initialized first
12610 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
12611 // temporary id should be introduced for the lhs
12612 const string
& tmp_id
= get_temporary_id();
12613 const char *tmp_id_str
= tmp_id
.c_str();
12614 str
= mputprintf(str
, "{\n"
12616 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
12617 tmp_id_str
, v
->get_lhs_name().c_str());
12618 str
= v
->generate_code_init(str
, tmp_id_str
);
12619 str
= mputstr(str
, "}\n");
12621 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
12624 str
= mputprintf(str
, "%s = %s;\n", name
,
12625 v
->get_genname_own(my_scope
).c_str());
12631 void Value::generate_json_value(JSON_Tokenizer
& json
,
12632 bool allow_special_float
, /* = true */
12633 bool union_value_list
, /* = false */
12634 Ttcn::JsonOmitCombination
* omit_combo
/* = NULL */)
12636 switch (valuetype
) {
12638 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
12641 Real r
= get_val_Real();
12642 if (r
== REAL_INFINITY
) {
12643 if (allow_special_float
) {
12644 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
12647 else if (r
== -REAL_INFINITY
) {
12648 if (allow_special_float
) {
12649 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
12653 if (allow_special_float
) {
12654 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
12658 // true if decimal representation possible (use %f format)
12659 bool decimal_repr
= (r
== 0.0)
12660 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
12661 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
12662 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
12663 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
12668 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
12674 char* str
= convert_to_json_string(get_val_str().c_str());
12675 json
.put_next_token(JSON_TOKEN_STRING
, str
);
12679 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
12680 json
.put_next_token(JSON_TOKEN_STRING
, str
);
12685 json
.put_next_token(JSON_TOKEN_STRING
,
12686 (string('\"') + create_stringRepr() + string('\"')).c_str());
12690 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
12691 if (!u
.val_vs
->is_indexed()) {
12692 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
12693 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
, allow_special_float
,
12694 union_value_list
, omit_combo
);
12698 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
12699 // look for the entry with index equal to i
12700 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
12701 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
12702 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
,
12703 allow_special_float
, union_value_list
, omit_combo
);
12709 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
12713 // omitted fields have 2 possible JSON values (the field is absent, or it's
12714 // present with value 'null'), each combination of omitted values must be
12716 if (omit_combo
== NULL
) {
12717 FATAL_ERROR("Value::generate_json_value - no combo");
12719 size_t len
= get_nof_comps();
12720 // generate the JSON object from the present combination
12721 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
12722 for (size_t i
= 0; i
< len
; ++i
) {
12723 Ttcn::JsonOmitCombination::omit_state_t state
= omit_combo
->get_state(this, i
);
12724 if (state
== Ttcn::JsonOmitCombination::OMITTED_ABSENT
) {
12725 // the field is absent, don't insert anything
12728 // use the field's alias, if it has one
12729 const char* alias
= NULL
;
12730 if (my_governor
!= NULL
) {
12731 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
12732 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
12733 if (field_attrib
!= NULL
) {
12734 alias
= field_attrib
->alias
;
12737 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
12738 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
12739 if (state
== Ttcn::JsonOmitCombination::OMITTED_NULL
) {
12740 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
12743 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
,
12744 allow_special_float
, union_value_list
, omit_combo
);
12747 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
12750 bool as_value
= !union_value_list
&& my_governor
!= NULL
&&
12751 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
12752 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
12754 // no 'as value' coding instruction, insert an object with one field
12755 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
12756 // use the field's alias, if it has one
12757 const char* alias
= NULL
;
12758 if (my_governor
!= NULL
) {
12759 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
12760 get_alt_name())->get_type()->get_json_attributes();
12761 if (field_attrib
!= NULL
) {
12762 alias
= field_attrib
->alias
;
12765 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
12766 get_alt_name().get_ttcnname().c_str());
12768 get_alt_value()->generate_json_value(json
, allow_special_float
,
12769 union_value_list
, omit_combo
);
12771 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
12775 Value
* v
= get_value_refd_last();
12777 v
->generate_json_value(json
, allow_special_float
, union_value_list
, omit_combo
);
12782 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
12786 bool Value::explicit_cast_needed(bool forIsValue
)
12788 Value
*v_last
= get_value_refd_last();
12789 if (v_last
!= this) {
12790 // this is a foldable referenced value
12791 // if the reference points to an imported or compound value the code
12792 // generation will be based on the reference so cast is not needed
12793 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
12794 || !v_last
->has_single_expr()) return false;
12795 } else if (v_last
->valuetype
== V_REFD
) {
12796 // this is an unfoldable reference (v_last==this)
12797 // explicit cast is needed only for string element references
12798 if (forIsValue
) return false;
12799 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
12800 return t_subrefs
&& t_subrefs
->refers_to_string_element();
12802 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
12803 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
12804 switch (t_governor
->get_typetype()) {
12808 case Type::T_INT_A
:
12810 case Type::T_ENUM_A
:
12811 case Type::T_ENUM_T
:
12812 case Type::T_VERDICT
:
12813 case Type::T_COMPONENT
:
12814 // these are mapped to built-in C/C++ types
12816 case Type::T_SEQ_A
:
12817 case Type::T_SEQ_T
:
12818 case Type::T_SET_A
:
12819 case Type::T_SET_T
:
12820 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12821 return t_governor
->get_nof_comps() == 0;
12822 case Type::T_SEQOF
:
12823 case Type::T_SETOF
:
12824 // the C++ equivalent of value {} is ambiguous
12827 case Type::T_FUNCTION
:
12828 case Type::T_ALTSTEP
:
12829 case Type::T_TESTCASE
:
12836 bool Value::has_single_expr()
12838 if (get_needs_conversion()) return false;
12839 switch (valuetype
) {
12841 return has_single_expr_expr();
12844 // a union or array value cannot be represented as an in-line expression
12848 // only an empty record/set of value can be represented as an in-line
12850 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
12851 else return u
.val_vs
->get_nof_ivs() == 0;
12854 // only a value for an empty record/set type can be represented as an
12855 // in-line expression
12856 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
12857 Type
*type
= my_governor
->get_type_refd_last();
12858 return type
->get_nof_comps() == 0; }
12860 Value
*v_last
= get_value_refd_last();
12861 // If the above call hit an error and set_valuetype(V_ERROR),
12862 // then u.ref.ref has been freed. Avoid the segfault.
12863 if (valuetype
== V_ERROR
)
12865 if (v_last
!= this && v_last
->has_single_expr() &&
12866 v_last
->my_scope
->get_scope_mod_gen() ==
12867 my_scope
->get_scope_mod_gen()) return true;
12868 else return u
.ref
.ref
->has_single_expr(); }
12870 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
12874 case V_UNDEF_LOWERID
:
12875 case V_UNDEF_BLOCK
:
12877 // these values cannot occur during code generation
12878 FATAL_ERROR("Value::has_single_expr()");
12880 return u
.val_Int
->is_native_fit();
12882 // other value types (literal values) do not need temporary reference
12887 string
Value::get_single_expr()
12889 switch (valuetype
) {
12891 return string("ASN_NULL_VALUE");
12893 return string(u
.val_bool
? "TRUE" : "FALSE");
12895 if (u
.val_Int
->is_native_fit()) { // Be sure.
12896 return u
.val_Int
->t_str();
12898 // get_single_expr may be called only if has_single_expr() is true.
12899 // The only exception is V_INT, where get_single_expr may be called
12900 // even if is_native_fit (which is used to implement has_single_expr)
12902 string
ret_val('"');
12903 ret_val
+= u
.val_Int
->t_str();
12908 return Real2code(u
.val_Real
);
12910 return get_single_expr_enum();
12912 return get_my_scope()->get_scope_mod_gen()
12913 ->add_bitstring_literal(*u
.str
.val_str
);
12915 return get_my_scope()->get_scope_mod_gen()
12916 ->add_hexstring_literal(*u
.str
.val_str
);
12918 return get_my_scope()->get_scope_mod_gen()
12919 ->add_octetstring_literal(*u
.str
.val_str
);
12921 return get_my_scope()->get_scope_mod_gen()
12922 ->add_charstring_literal(*u
.str
.val_str
);
12924 if (u
.ustr
.convert_str
) {
12925 set_valuetype(V_CSTR
);
12926 return get_my_scope()->get_scope_mod_gen()
12927 ->add_charstring_literal(*u
.str
.val_str
);
12929 return get_my_scope()->get_scope_mod_gen()
12930 ->add_ustring_literal(*u
.ustr
.val_ustr
);
12932 return get_single_expr_iso2022str();
12935 vector
<string
> comps
;
12936 bool is_constant
= get_oid_comps(comps
);
12937 size_t nof_comps
= comps
.size();
12939 for (size_t i
= 0; i
< nof_comps
; i
++) {
12940 if (i
> 0) oi_str
+= ", ";
12941 oi_str
+= *(comps
[i
]);
12943 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
12946 // the objid only contains constants
12947 // => create a literal and return its name
12948 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
12950 // the objid contains at least one variable
12951 // => append the number of components before the component values in the string and return it
12952 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
12955 if (u
.val_vs
->get_nof_vs() > 0)
12956 FATAL_ERROR("Value::get_single_expr()");
12957 return string("NULL_VALUE");
12960 if (u
.val_nvs
->get_nof_nvs() > 0)
12961 FATAL_ERROR("Value::get_single_expr()");
12962 return string("NULL_VALUE");
12964 Value
*v_last
= get_value_refd_last();
12965 if (v_last
!= this && v_last
->has_single_expr() &&
12966 v_last
->my_scope
->get_scope_mod_gen() ==
12967 my_scope
->get_scope_mod_gen()) {
12968 // the reference points to another single value in the same module
12969 return v_last
->get_single_expr();
12971 // convert the reference to a single expression
12972 expression_struct expr
;
12973 Code::init_expr(&expr
);
12974 u
.ref
.ref
->generate_code_const_ref(&expr
);
12975 if (expr
.preamble
|| expr
.postamble
)
12976 FATAL_ERROR("Value::get_single_expr()");
12977 string
ret_val(expr
.expr
);
12978 Code::free_expr(&expr
);
12982 return string("OMIT_VALUE");
12984 switch (u
.verdict
) {
12986 return string("NONE");
12988 return string("PASS");
12989 case Verdict_INCONC
:
12990 return string("INCONC");
12992 return string("FAIL");
12993 case Verdict_ERROR
:
12994 return string("ERROR");
12996 FATAL_ERROR("Value::get_single_expr()");
12999 case V_DEFAULT_NULL
:
13000 return string("NULL_COMPREF");
13002 string
ret_val('(');
13003 ret_val
+= my_governor
->get_genname_value(my_scope
);
13004 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13008 expression_struct expr
;
13009 Code::init_expr(&expr
);
13010 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13011 else generate_code_expr_invoke(&expr
);
13012 if (expr
.preamble
|| expr
.postamble
)
13013 FATAL_ERROR("Value::get_single_expr()");
13014 string
ret_val(expr
.expr
);
13015 Code::free_expr(&expr
);
13019 case MACRO_TESTCASEID
:
13020 return string("TTCN_Runtime::get_testcase_id_macro()");
13022 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13028 return get_single_expr_fat();
13030 FATAL_ERROR("Value::get_single_expr()");
13035 bool Value::has_single_expr_expr()
13037 switch (u
.expr
.v_optype
) {
13038 case OPTYPE_RND
: // -
13039 case OPTYPE_COMP_NULL
:
13040 case OPTYPE_COMP_MTC
:
13041 case OPTYPE_COMP_SYSTEM
:
13042 case OPTYPE_COMP_SELF
:
13043 case OPTYPE_COMP_RUNNING_ANY
:
13044 case OPTYPE_COMP_RUNNING_ALL
:
13045 case OPTYPE_COMP_ALIVE_ANY
:
13046 case OPTYPE_COMP_ALIVE_ALL
:
13047 case OPTYPE_TMR_RUNNING_ANY
:
13048 case OPTYPE_GETVERDICT
:
13049 case OPTYPE_TESTCASENAME
:
13050 case OPTYPE_PROF_RUNNING
:
13052 case OPTYPE_ENCODE
:
13053 case OPTYPE_DECODE
:
13054 case OPTYPE_ISBOUND
:
13055 case OPTYPE_ISPRESENT
:
13056 case OPTYPE_TTCN2STRING
:
13058 case OPTYPE_UNARYPLUS
: // v1
13059 case OPTYPE_UNARYMINUS
:
13062 case OPTYPE_BIT2HEX
:
13063 case OPTYPE_BIT2INT
:
13064 case OPTYPE_BIT2OCT
:
13065 case OPTYPE_BIT2STR
:
13066 case OPTYPE_CHAR2INT
:
13067 case OPTYPE_CHAR2OCT
:
13068 case OPTYPE_FLOAT2INT
:
13069 case OPTYPE_FLOAT2STR
:
13070 case OPTYPE_HEX2BIT
:
13071 case OPTYPE_HEX2INT
:
13072 case OPTYPE_HEX2OCT
:
13073 case OPTYPE_HEX2STR
:
13074 case OPTYPE_INT2CHAR
:
13075 case OPTYPE_INT2FLOAT
:
13076 case OPTYPE_INT2STR
:
13077 case OPTYPE_INT2UNICHAR
:
13078 case OPTYPE_OCT2BIT
:
13079 case OPTYPE_OCT2CHAR
:
13080 case OPTYPE_OCT2HEX
:
13081 case OPTYPE_OCT2INT
:
13082 case OPTYPE_OCT2STR
:
13083 case OPTYPE_STR2BIT
:
13084 case OPTYPE_STR2FLOAT
:
13085 case OPTYPE_STR2HEX
:
13086 case OPTYPE_STR2INT
:
13087 case OPTYPE_STR2OCT
:
13088 case OPTYPE_UNICHAR2INT
:
13089 case OPTYPE_UNICHAR2CHAR
:
13090 case OPTYPE_ENUM2INT
:
13091 case OPTYPE_RNDWITHVAL
:
13092 case OPTYPE_ISCHOSEN_V
: // v1 i2
13093 case OPTYPE_COMP_RUNNING
:
13094 case OPTYPE_COMP_ALIVE
:
13095 case OPTYPE_GET_STRINGENCODING
:
13096 case OPTYPE_REMOVE_BOM
:
13097 case OPTYPE_DECODE_BASE64
:
13098 return u
.expr
.v1
->has_single_expr();
13099 case OPTYPE_ISCHOSEN_T
: // t1 i2
13100 return u
.expr
.t1
->has_single_expr();
13101 case OPTYPE_ADD
: // v1 v2
13102 case OPTYPE_SUBTRACT
:
13103 case OPTYPE_MULTIPLY
:
13104 case OPTYPE_DIVIDE
:
13107 case OPTYPE_CONCAT
:
13122 case OPTYPE_INT2BIT
:
13123 case OPTYPE_INT2HEX
:
13124 case OPTYPE_INT2OCT
:
13125 return u
.expr
.v1
->has_single_expr() &&
13126 u
.expr
.v2
->has_single_expr();
13127 case OPTYPE_UNICHAR2OCT
:
13128 case OPTYPE_OCT2UNICHAR
:
13129 case OPTYPE_ENCODE_BASE64
:
13130 return u
.expr
.v1
->has_single_expr() &&
13131 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13134 return u
.expr
.v1
->has_single_expr() &&
13135 u
.expr
.v2
->has_single_expr() &&
13136 !u
.expr
.v2
->needs_short_circuit();
13137 case OPTYPE_SUBSTR
:
13138 return u
.expr
.ti1
->has_single_expr() &&
13139 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13140 case OPTYPE_REGEXP
:
13141 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13142 u
.expr
.v3
->has_single_expr();
13143 case OPTYPE_DECOMP
: // v1 v2 v3
13144 return u
.expr
.v1
->has_single_expr() &&
13145 u
.expr
.v2
->has_single_expr() &&
13146 u
.expr
.v3
->has_single_expr();
13147 case OPTYPE_REPLACE
:
13148 return u
.expr
.ti1
->has_single_expr() &&
13149 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13150 u
.expr
.ti4
->has_single_expr();
13151 case OPTYPE_ISVALUE
: // ti1
13152 case OPTYPE_LENGTHOF
: // ti1
13153 case OPTYPE_SIZEOF
: // ti1
13154 case OPTYPE_VALUEOF
: // ti1
13155 return u
.expr
.ti1
->has_single_expr();
13156 case OPTYPE_LOG2STR
:
13157 return u
.expr
.logargs
->has_single_expr();
13158 case OPTYPE_MATCH
: // v1 t2
13159 return u
.expr
.v1
->has_single_expr() &&
13160 u
.expr
.t2
->has_single_expr();
13161 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13162 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13163 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13164 case OPTYPE_TMR_READ
: // r1
13165 case OPTYPE_TMR_RUNNING
:
13166 case OPTYPE_ACTIVATE
:
13167 return u
.expr
.r1
->has_single_expr();
13168 case OPTYPE_EXECUTE
: // r1 [v2]
13169 return u
.expr
.r1
->has_single_expr() &&
13170 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13171 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13172 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13173 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13174 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13175 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13177 FATAL_ERROR("Value::has_single_expr_expr()");
13181 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13183 if (!v
->has_single_expr()) return false;
13184 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13185 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13189 string
Value::get_single_expr_enum()
13191 string
ret_val(my_governor
->get_genname_value(my_scope
));
13193 ret_val
+= u
.val_id
->get_name();
13197 string
Value::get_single_expr_iso2022str()
13200 Type
*type
= get_my_governor()->get_type_refd_last();
13201 switch (type
->get_typetype()) {
13202 case Type::T_TELETEXSTRING
:
13203 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13205 case Type::T_VIDEOTEXSTRING
:
13206 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13208 case Type::T_GRAPHICSTRING
:
13209 case Type::T_OBJECTDESCRIPTOR
:
13210 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13212 case Type::T_GENERALSTRING
:
13213 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13216 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13219 string
*ostr
= char2oct(*u
.str
.val_str
);
13220 ret_val
+= get_my_scope()->get_scope_mod_gen()
13221 ->add_octetstring_literal(*ostr
);
13227 string
Value::get_single_expr_fat()
13229 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13230 // the ampersand operator is not really necessary to obtain the function
13231 // pointer, but some older versions of GCC cannot instantiate the
13232 // appropriate operator=() member of class OPTIONAL when necessary
13233 // if only the function name is given
13234 string
ret_val('&');
13235 switch (valuetype
) {
13237 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13240 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13241 ret_val
+= "_instance";
13244 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13247 FATAL_ERROR("Value::get_single_expr_fat()");
13252 bool Value::is_compound()
13254 switch (valuetype
) {
13267 bool Value::needs_temp_ref()
13269 switch (valuetype
) {
13272 if (!is_indexed()) {
13273 // Temporary reference is needed if the value has at least one real
13274 // element (i.e. it is not empty or contains only not used symbols).
13275 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13276 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13279 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13280 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13281 ->valuetype
!= V_NOTUSED
)
13287 size_t nof_real_vs
= 0;
13288 if (!is_indexed()) {
13289 // Temporary reference is needed if the array value has at least two
13290 // real elements (excluding not used symbols).
13291 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13292 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13294 if (nof_real_vs
> 1) return true;
13298 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13299 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13300 ->valuetype
!= V_NOTUSED
) {
13302 if (nof_real_vs
> 1) return true;
13310 // it depends on the type since fields with omit or default value
13311 // may not be present
13312 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13314 // incomplete values are allowed in TTCN-3
13315 // we should check the number of value components
13316 return u
.val_nvs
->get_nof_nvs() > 1;
13321 case V_UNDEF_LOWERID
:
13322 case V_UNDEF_BLOCK
:
13324 // these values cannot occur during code generation
13325 FATAL_ERROR("Value::needs_temp_ref()");
13327 return !u
.val_Int
->is_native();
13329 // other value types (literal values) do not need temporary reference
13334 bool Value::needs_short_circuit()
13336 switch (valuetype
) {
13344 // sub-expressions should be evaluated only if necessary
13347 FATAL_ERROR("Value::needs_short_circuit()");
13349 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13350 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13351 switch (t_ass
->get_asstype()) {
13352 case Assignment::A_FUNCTION_RVAL
:
13353 case Assignment::A_EXT_FUNCTION_RVAL
:
13354 // avoid unnecessary call of a function
13356 case Assignment::A_CONST
:
13357 case Assignment::A_EXT_CONST
:
13358 case Assignment::A_MODULEPAR
:
13359 case Assignment::A_VAR
:
13360 case Assignment::A_PAR_VAL_IN
:
13361 case Assignment::A_PAR_VAL_OUT
:
13362 case Assignment::A_PAR_VAL_INOUT
:
13363 // depends on field/array sub-references, which is examined below
13366 FATAL_ERROR("Value::needs_short_circuit()");
13368 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13370 // the evaluation of the reference does not have side effects
13371 // (i.e. false shall be returned) only if all sub-references point to
13372 // mandatory fields of record/set types, and neither sub-reference points
13373 // to a field of a union type
13374 Type
*t_type
= t_ass
->get_Type();
13375 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13376 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13377 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13378 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13379 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13380 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13381 t_cf
->get_is_optional()) return true;
13382 t_type
= t_cf
->get_type();
13383 } else return true;
13389 void Value::dump(unsigned level
) const
13391 switch (valuetype
) {
13415 case V_DEFAULT_NULL
:
13423 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13427 DEBUG(level
, "Value: reference");
13428 u
.ref
.ref
->dump(level
+ 1);
13430 case V_UNDEF_LOWERID
:
13431 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13433 case V_UNDEF_BLOCK
:
13434 DEBUG(level
, "Value: {block}");
13437 DEBUG(level
, "Value: null");
13440 DEBUG(level
, "Value: invoke");
13441 u
.invoke
.v
->dump(level
+ 1);
13442 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13443 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13446 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13450 void Value::add_string_element(size_t index
, Value
*v_element
,
13451 map
<size_t, Value
>*& string_elements
)
13453 v_element
->set_my_scope(get_my_scope());
13454 v_element
->set_my_governor(get_my_governor());
13455 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13456 v_element
->set_location(*this);
13457 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13458 string_elements
->add(index
, v_element
);
13461 ///////////////////////////////////////////////////////////////////////////////
13462 // class LazyParamData
13464 int LazyParamData::depth
= 0;
13465 bool LazyParamData::used_as_lvalue
= false;
13466 vector
<string
>* LazyParamData::type_vec
= NULL
;
13467 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13469 void LazyParamData::init(bool p_used_as_lvalue
) {
13470 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13472 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13473 used_as_lvalue
= p_used_as_lvalue
;
13474 type_vec
= new vector
<string
>;
13475 refd_vec
= new vector
<string
>;
13480 void LazyParamData::clean() {
13481 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13482 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13485 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13490 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13498 bool LazyParamData::in_lazy() {
13499 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13503 // returns a temporary id instead of the C++ reference to a definition
13504 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13505 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13506 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13507 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13508 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13509 // store the type of the assignment
13510 string
* type_str
= new string
;
13511 switch (ass
->get_asstype()) {
13512 case Assignment::A_MODULEPAR_TEMP
:
13513 case Assignment::A_TEMPLATE
:
13514 case Assignment::A_VAR_TEMPLATE
:
13515 case Assignment::A_PAR_TEMPL_IN
:
13516 case Assignment::A_PAR_TEMPL_OUT
:
13517 case Assignment::A_PAR_TEMPL_INOUT
:
13518 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13521 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13523 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13524 bool refd_ass_is_lazy_fpar
= false;
13525 switch (ass
->get_asstype()) {
13526 case Assignment::A_PAR_VAL
:
13527 case Assignment::A_PAR_VAL_IN
:
13528 case Assignment::A_PAR_TEMPL_IN
:
13529 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13530 if (refd_ass_is_lazy_fpar
) {
13531 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13537 // add the "const" part if the referenced assignment is a constant thing
13538 if (!refd_ass_is_lazy_fpar
) {
13539 switch (ass
->get_asstype()) {
13540 case Assignment::A_CONST
:
13541 case Assignment::A_OC
:
13542 case Assignment::A_OBJECT
:
13543 case Assignment::A_OS
:
13544 case Assignment::A_VS
:
13545 case Assignment::A_EXT_CONST
:
13546 case Assignment::A_MODULEPAR
:
13547 case Assignment::A_MODULEPAR_TEMP
:
13548 case Assignment::A_TEMPLATE
:
13549 case Assignment::A_PAR_VAL
:
13550 case Assignment::A_PAR_VAL_IN
:
13551 case Assignment::A_PAR_TEMPL_IN
:
13552 *type_str
= string("const ") + *type_str
;
13560 type_vec
->add(type_str
);
13561 // store the C++ reference string
13562 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
13563 if (refd_ass_is_lazy_fpar
) {
13564 Type
* refd_ass_type
= ass
->get_Type();
13565 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
);
13566 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
13568 return get_member_name(refd_vec
->size()-1);
13572 string
LazyParamData::get_member_name(size_t idx
) {
13573 return string("lpm_") + Int2string(idx
);
13576 string
LazyParamData::get_constr_param_name(size_t idx
) {
13577 return string("lpp_") + Int2string(idx
);
13580 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
13581 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13582 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
13583 const string
& tmp_id
= val
->get_temporary_id();
13584 const char *tmp_id_str
= tmp_id
.c_str();
13585 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13586 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13588 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13590 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13592 val
->generate_code_expr(expr
);
13596 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
13597 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13598 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
13599 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
13600 const char *tmp_id_str
= tmp_id
.c_str();
13601 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13602 temp
->get_Template()->get_my_governor()
13603 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
13604 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13605 tmp_id_str
, temp
->get_Template());
13606 // Not incorporated into gen_conv_code() yet.
13607 if (gen_restriction_check
!= TR_NONE
)
13608 expr
->preamble
= Template::generate_restriction_check_code(
13609 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
13610 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13611 } else temp
->generate_code(expr
, gen_restriction_check
);
13614 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13615 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13617 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13618 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13619 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13620 expression_struct value_expr
;
13621 Code::init_expr(&value_expr
);
13622 generate_code_for_value(&value_expr
, value
, scope
);
13623 // the id of the instance of Lazy_Param which will be used as the actual parameter
13624 const string
& lazy_param_id
= value
->get_temporary_id();
13625 if (value_expr
.preamble
) {
13626 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
13628 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13629 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13630 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
13631 Code::free_expr(&value_expr
);
13632 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13635 // only if the formal parameter is *not* used as lvalue
13636 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
13637 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
13639 bool refd_ass_is_lazy_fpar
= false;
13640 switch (refd_ass
->get_asstype()) {
13641 case Assignment::A_PAR_VAL
:
13642 case Assignment::A_PAR_VAL_IN
:
13643 case Assignment::A_PAR_TEMPL_IN
:
13644 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13649 if (refd_ass_is_lazy_fpar
) {
13650 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13655 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13656 expression_struct value_expr
;
13657 Code::init_expr(&value_expr
);
13658 generate_code_for_value(&value_expr
, value
, scope
);
13659 // the id of the instance of Lazy_Param which will be used as the actual parameter
13660 string lazy_param_id
= value
->get_temporary_id();
13661 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
13662 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
13665 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
13666 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13668 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13669 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13670 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13671 expression_struct tmpl_expr
;
13672 Code::init_expr(&tmpl_expr
);
13673 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13674 // the id of the instance of Lazy_Param which will be used as the actual parameter
13675 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
13676 if (tmpl_expr
.preamble
) {
13677 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
13679 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13680 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13681 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
13682 Code::free_expr(&tmpl_expr
);
13683 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13686 // only if the formal parameter is *not* used as lvalue
13687 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
13688 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
13690 bool refd_ass_is_lazy_fpar
= false;
13691 switch (refd_ass
->get_asstype()) {
13692 case Assignment::A_PAR_VAL
:
13693 case Assignment::A_PAR_VAL_IN
:
13694 case Assignment::A_PAR_TEMPL_IN
:
13695 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13700 if (refd_ass_is_lazy_fpar
) {
13701 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13706 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13707 expression_struct tmpl_expr
;
13708 Code::init_expr(&tmpl_expr
);
13709 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13710 // the id of the instance of Lazy_Param which will be used as the actual parameter
13711 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
13712 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
13713 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
13716 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
13717 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
13718 if (type_vec
->size()>0) {
13719 // private members of the local class will be const references to the objects referenced by the expression
13720 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13721 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
13723 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
13724 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
13725 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13726 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13727 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
13729 expr
->preamble
= mputstr(expr
->preamble
, "): ");
13730 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13731 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13732 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
13734 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
13735 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
13737 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
13738 // use the temporary expr structure to fill the body of the eval_expr() function
13739 if (param_expr
.preamble
) {
13740 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
13742 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
13743 if (param_expr
.postamble
) {
13744 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
13746 Code::free_expr(¶m_expr
);
13747 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
13748 "};\n" // end of local class definition
13750 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
13751 if (type_vec
->size()>0) {
13752 expr
->preamble
= mputc(expr
->preamble
, '(');
13753 // paramteres of the constructor are references to the objects used in the expression
13754 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
13755 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13756 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
13758 expr
->preamble
= mputc(expr
->preamble
, ')');
13760 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
13761 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13762 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
13765 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
13766 expression_struct ref_expr
;
13767 Code::init_expr(&ref_expr
);
13768 ref
->generate_code(&ref_expr
);
13769 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
13770 if (ref_expr
.preamble
) {
13771 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
13773 Assignment
* ass
= ref
->get_refd_assignment();
13774 // determine C++ type of the assignment
13776 switch (ass
->get_asstype()) {
13777 case Assignment::A_MODULEPAR_TEMP
:
13778 case Assignment::A_TEMPLATE
:
13779 case Assignment::A_VAR_TEMPLATE
:
13780 case Assignment::A_PAR_TEMPL_IN
:
13781 case Assignment::A_PAR_TEMPL_OUT
:
13782 case Assignment::A_PAR_TEMPL_INOUT
:
13783 type_str
= ass
->get_Type()->get_genname_template(scope
);
13786 type_str
= ass
->get_Type()->get_genname_value(scope
);
13788 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13789 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
13790 if (ref_expr
.postamble
) {
13791 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
13793 Code::free_expr(&ref_expr
);
13794 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13797 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13798 const string
& lazy_param_id
= value
->get_temporary_id();
13799 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13800 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13801 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
13802 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13805 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
13806 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
13807 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13808 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13809 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
13810 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13813 } // namespace Common