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"
41 static void clean_up_string_elements(map
<size_t, Value
>*& string_elements
)
43 if (string_elements
) {
44 for (size_t i
= 0; i
< string_elements
->size(); i
++)
45 delete string_elements
->get_nth_elem(i
);
46 string_elements
->clear();
47 delete string_elements
;
52 // =================================
54 // =================================
56 Value::Value(const Value
& p
)
57 : GovernedSimple(p
), valuetype(p
.valuetype
), my_governor(0)
69 u
.val_bool
=p
.u
.val_bool
;
72 u
.val_Int
=new int_val_t(*(p
.u
.val_Int
));
77 u
.val_id
=p
.u
.val_id
->clone();
80 u
.val_Real
=p
.u
.val_Real
;
87 set_val_str(new string(*p
.u
.str
.val_str
));
90 set_val_ustr(new ustring(*p
.u
.ustr
.val_ustr
));
91 u
.ustr
.convert_str
= p
.u
.ustr
.convert_str
;
94 u
.char_syms
= p
.u
.char_syms
->clone();
98 u
.oid_comps
=new vector
<OID_comp
>;
99 for(size_t i
=0; i
<p
.u
.oid_comps
->size(); i
++)
100 add_oid_comp((*p
.u
.oid_comps
)[i
]->clone());
103 u
.choice
.alt_name
=p
.u
.choice
.alt_name
->clone();
104 u
.choice
.alt_value
=p
.u
.choice
.alt_value
->clone();
109 u
.val_vs
=p
.u
.val_vs
->clone();
113 u
.val_nvs
=p
.u
.val_nvs
->clone();
116 u
.ref
.ref
=p
.u
.ref
.ref
->clone();
120 for(size_t i
=0; i
<p
.u
.ids
->size(); i
++) {
121 Identifier
*id
= p
.u
.ids
->get_nth_elem(i
);
122 u
.ids
->add(id
->get_name(), id
->clone());
126 u
.block
=p
.u
.block
->clone();
129 u
.verdict
=p
.u
.verdict
;
132 u
.expr
.v_optype
= p
.u
.expr
.v_optype
;
133 u
.expr
.state
= EXPR_NOT_CHECKED
;
134 switch(u
.expr
.v_optype
) {
135 case OPTYPE_RND
: // -
136 case OPTYPE_COMP_NULL
:
137 case OPTYPE_COMP_MTC
:
138 case OPTYPE_COMP_SYSTEM
:
139 case OPTYPE_COMP_SELF
:
140 case OPTYPE_COMP_RUNNING_ANY
:
141 case OPTYPE_COMP_RUNNING_ALL
:
142 case OPTYPE_COMP_ALIVE_ANY
:
143 case OPTYPE_COMP_ALIVE_ALL
:
144 case OPTYPE_TMR_RUNNING_ANY
:
145 case OPTYPE_GETVERDICT
:
146 case OPTYPE_TESTCASENAME
:
147 case OPTYPE_PROF_RUNNING
:
149 case OPTYPE_UNARYPLUS
: // v1
150 case OPTYPE_UNARYMINUS
:
157 case OPTYPE_CHAR2INT
:
158 case OPTYPE_CHAR2OCT
:
159 case OPTYPE_COMP_RUNNING
:
160 case OPTYPE_COMP_ALIVE
:
161 case OPTYPE_FLOAT2INT
:
162 case OPTYPE_FLOAT2STR
:
167 case OPTYPE_INT2CHAR
:
168 case OPTYPE_INT2FLOAT
:
170 case OPTYPE_INT2UNICHAR
:
172 case OPTYPE_OCT2CHAR
:
177 case OPTYPE_STR2FLOAT
:
181 case OPTYPE_UNICHAR2INT
:
182 case OPTYPE_UNICHAR2CHAR
:
183 case OPTYPE_ENUM2INT
:
184 case OPTYPE_RNDWITHVAL
:
185 case OPTYPE_GET_STRINGENCODING
:
186 case OPTYPE_DECODE_BASE64
:
187 case OPTYPE_REMOVE_BOM
:
188 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
190 case OPTYPE_ADD
: // v1 v2
191 case OPTYPE_SUBTRACT
:
192 case OPTYPE_MULTIPLY
:
216 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
217 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
219 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
220 case OPTYPE_OCT2UNICHAR
:
221 case OPTYPE_ENCODE_BASE64
:
222 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
223 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
226 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
227 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
230 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
231 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
232 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
235 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
236 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
237 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
239 case OPTYPE_DECOMP
: // v1 v2 v3
240 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
241 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
242 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
245 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
246 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
247 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
248 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
250 case OPTYPE_LENGTHOF
: // ti1
251 case OPTYPE_SIZEOF
: // ti1
252 case OPTYPE_VALUEOF
: // ti1
254 case OPTYPE_ISPRESENT
:
255 case OPTYPE_TTCN2STRING
:
256 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
258 case OPTYPE_UNDEF_RUNNING
:
259 case OPTYPE_TMR_READ
:
260 case OPTYPE_TMR_RUNNING
:
261 case OPTYPE_ACTIVATE
:
262 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
264 case OPTYPE_EXECUTE
: // r1 [v2]
265 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
266 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
268 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
269 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
270 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
271 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
272 u
.expr
.b4
= p
.u
.expr
.b4
;
274 case OPTYPE_MATCH
: // v1 t2
275 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
276 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
278 case OPTYPE_ISCHOSEN
: // r1 i2
279 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
280 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
282 case OPTYPE_ISCHOSEN_V
: // v1 i2
283 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
284 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
286 case OPTYPE_ISCHOSEN_T
: // t1 i2
287 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
288 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
290 case OPTYPE_ACTIVATE_REFD
:
291 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
292 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
293 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
295 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
296 u
.expr
.state
= EXPR_CHECKED
;
299 case OPTYPE_EXECUTE_REFD
:
300 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
301 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
302 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
304 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
305 u
.expr
.state
= EXPR_CHECKED
;
307 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
310 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
313 FATAL_ERROR("Value::Value()");
322 u
.refd_fat
= p
.u
.refd_fat
;
325 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
326 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
327 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
330 u
.refered
= p
.u
.refered
->clone();
333 FATAL_ERROR("Value::Value()");
337 void Value::clean_up()
360 case V_UNDEF_LOWERID
:
368 delete u
.str
.val_str
;
369 clean_up_string_elements(u
.str
.str_elements
);
372 delete u
.ustr
.val_ustr
;
373 clean_up_string_elements(u
.ustr
.ustr_elements
);
381 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
382 delete (*u
.oid_comps
)[i
];
383 u
.oid_comps
->clear();
391 delete u
.choice
.alt_name
;
392 delete u
.choice
.alt_value
;
411 delete u
.invoke
.t_list
;
412 delete u
.invoke
.ap_list
;
416 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
425 FATAL_ERROR("Value::clean_up()");
429 void Value::clean_up_expr()
431 switch (u
.expr
.state
) {
433 case EXPR_CHECKING_ERR
:
434 FATAL_ERROR("Value::clean_up_expr()");
438 switch (u
.expr
.v_optype
) {
439 case OPTYPE_RND
: // -
440 case OPTYPE_COMP_NULL
:
441 case OPTYPE_COMP_MTC
:
442 case OPTYPE_COMP_SYSTEM
:
443 case OPTYPE_COMP_SELF
:
444 case OPTYPE_COMP_RUNNING_ANY
:
445 case OPTYPE_COMP_RUNNING_ALL
:
446 case OPTYPE_COMP_ALIVE_ANY
:
447 case OPTYPE_COMP_ALIVE_ALL
:
448 case OPTYPE_TMR_RUNNING_ANY
:
449 case OPTYPE_GETVERDICT
:
450 case OPTYPE_TESTCASENAME
:
451 case OPTYPE_PROF_RUNNING
:
453 case OPTYPE_UNARYPLUS
: // v1
454 case OPTYPE_UNARYMINUS
:
461 case OPTYPE_CHAR2INT
:
462 case OPTYPE_CHAR2OCT
:
463 case OPTYPE_COMP_RUNNING
:
464 case OPTYPE_COMP_ALIVE
:
465 case OPTYPE_FLOAT2INT
:
466 case OPTYPE_FLOAT2STR
:
471 case OPTYPE_INT2CHAR
:
472 case OPTYPE_INT2FLOAT
:
474 case OPTYPE_INT2UNICHAR
:
476 case OPTYPE_OCT2CHAR
:
481 case OPTYPE_STR2FLOAT
:
485 case OPTYPE_UNICHAR2INT
:
486 case OPTYPE_UNICHAR2CHAR
:
487 case OPTYPE_ENUM2INT
:
488 case OPTYPE_RNDWITHVAL
:
489 case OPTYPE_REMOVE_BOM
:
490 case OPTYPE_GET_STRINGENCODING
:
491 case OPTYPE_DECODE_BASE64
:
494 case OPTYPE_ADD
: // v1 v2
495 case OPTYPE_SUBTRACT
:
496 case OPTYPE_MULTIPLY
:
520 case OPTYPE_UNICHAR2OCT
:
521 case OPTYPE_OCT2UNICHAR
:
522 case OPTYPE_ENCODE_BASE64
:
540 case OPTYPE_DECOMP
: // v1 v2 v3
551 case OPTYPE_LENGTHOF
: // ti1
552 case OPTYPE_SIZEOF
: // ti1
553 case OPTYPE_VALUEOF
: // ti1
557 case OPTYPE_ISPRESENT
:
558 case OPTYPE_TTCN2STRING
:
561 case OPTYPE_UNDEF_RUNNING
:
562 case OPTYPE_TMR_READ
:
563 case OPTYPE_TMR_RUNNING
:
564 case OPTYPE_ACTIVATE
:
567 case OPTYPE_EXECUTE
: // r1 [v2]
571 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
576 case OPTYPE_MATCH
: // v1 t2
580 case OPTYPE_ISCHOSEN
: // r1 i2
584 case OPTYPE_ISCHOSEN_V
: // v1 i2
588 case OPTYPE_ISCHOSEN_T
: // t1 i2
592 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
594 if(u
.expr
.state
!=EXPR_CHECKED
)
595 delete u
.expr
.t_list2
;
597 delete u
.expr
.ap_list2
;
599 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
601 if(u
.expr
.state
!=EXPR_CHECKED
)
602 delete u
.expr
.t_list2
;
604 delete u
.expr
.ap_list2
;
608 delete u
.expr
.logargs
;
611 FATAL_ERROR("Value::clean_up_expr()");
615 void Value::copy_and_destroy(Value
*src
)
618 valuetype
= src
->valuetype
;
620 // update the pointer used for caching if it points to the value itself
621 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
622 src
->valuetype
= V_ERROR
;
626 Value::Value(valuetype_t p_vt
)
627 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
638 u
.oid_comps
=new vector
<OID_comp
>();
641 u
.ids
=new map
<string
, Identifier
>();
644 FATAL_ERROR("Value::Value()");
648 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
649 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
653 u
.val_bool
=p_val_bool
;
656 FATAL_ERROR("Value::Value()");
660 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
661 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
665 u
.val_Int
=new int_val_t(p_val_Int
);
668 FATAL_ERROR("Value::Value()");
672 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
673 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
680 FATAL_ERROR("Value::Value()");
684 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
685 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
687 if(!p_val_str
) FATAL_ERROR("NULL parameter");
694 set_val_str(p_val_str
);
697 FATAL_ERROR("Value::Value()");
701 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
702 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
704 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
705 set_val_ustr(p_val_ustr
);
706 u
.ustr
.convert_str
= false;
709 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
710 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
712 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
715 u
.char_syms
= p_char_syms
;
718 FATAL_ERROR("Value::Value()");
722 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
723 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
726 FATAL_ERROR("NULL parameter");
730 case V_UNDEF_LOWERID
:
734 FATAL_ERROR("Value::Value()");
738 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
739 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
742 FATAL_ERROR("NULL parameter");
745 u
.choice
.alt_name
=p_id
;
746 u
.choice
.alt_value
=p_val
;
749 FATAL_ERROR("Value::Value()");
753 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
754 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
758 u
.val_Real
=p_val_Real
;
761 FATAL_ERROR("Value::Value()");
765 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
766 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
768 if(!p_vs
) FATAL_ERROR("NULL parameter");
776 FATAL_ERROR("Value::Value()");
780 Value::Value(valuetype_t p_vt
, Value
*p_v
,
781 Ttcn::ParsedActualParameters
*p_t_list
)
782 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
784 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
788 u
.invoke
.t_list
= p_t_list
;
789 u
.invoke
.ap_list
= 0;
792 FATAL_ERROR("Value::Value()");
797 Value::Value(operationtype_t p_optype
)
798 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
800 u
.expr
.v_optype
= p_optype
;
801 u
.expr
.state
= EXPR_NOT_CHECKED
;
804 case OPTYPE_COMP_NULL
:
805 case OPTYPE_COMP_MTC
:
806 case OPTYPE_COMP_SYSTEM
:
807 case OPTYPE_COMP_SELF
:
808 case OPTYPE_COMP_RUNNING_ANY
:
809 case OPTYPE_COMP_RUNNING_ALL
:
810 case OPTYPE_COMP_ALIVE_ANY
:
811 case OPTYPE_COMP_ALIVE_ALL
:
812 case OPTYPE_TMR_RUNNING_ANY
:
813 case OPTYPE_GETVERDICT
:
814 case OPTYPE_TESTCASENAME
:
815 case OPTYPE_PROF_RUNNING
:
818 FATAL_ERROR("Value::Value()");
823 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
824 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
826 u
.expr
.v_optype
= p_optype
;
827 u
.expr
.state
= EXPR_NOT_CHECKED
;
829 case OPTYPE_UNARYPLUS
:
830 case OPTYPE_UNARYMINUS
:
837 case OPTYPE_CHAR2INT
:
838 case OPTYPE_CHAR2OCT
:
839 case OPTYPE_COMP_RUNNING
:
840 case OPTYPE_COMP_ALIVE
:
841 case OPTYPE_FLOAT2INT
:
842 case OPTYPE_FLOAT2STR
:
847 case OPTYPE_INT2CHAR
:
848 case OPTYPE_INT2FLOAT
:
850 case OPTYPE_INT2UNICHAR
:
852 case OPTYPE_OCT2CHAR
:
857 case OPTYPE_STR2FLOAT
:
861 case OPTYPE_UNICHAR2INT
:
862 case OPTYPE_UNICHAR2CHAR
:
863 case OPTYPE_ENUM2INT
:
864 case OPTYPE_RNDWITHVAL
:
865 case OPTYPE_REMOVE_BOM
:
866 case OPTYPE_GET_STRINGENCODING
:
867 case OPTYPE_DECODE_BASE64
:
868 if(!p_v1
) FATAL_ERROR("Value::Value()");
872 FATAL_ERROR("Value::Value()");
877 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
878 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
880 u
.expr
.v_optype
= p_optype
;
881 u
.expr
.state
= EXPR_NOT_CHECKED
;
883 case OPTYPE_LENGTHOF
:
889 case OPTYPE_ISPRESENT
:
890 case OPTYPE_TTCN2STRING
:
891 if(!p_ti1
) FATAL_ERROR("Value::Value()");
895 FATAL_ERROR("Value::Value()");
900 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
901 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
903 u
.expr
.v_optype
= p_optype
;
904 u
.expr
.state
= EXPR_NOT_CHECKED
;
906 case OPTYPE_UNDEF_RUNNING
:
907 case OPTYPE_TMR_READ
:
908 case OPTYPE_TMR_RUNNING
:
909 case OPTYPE_ACTIVATE
:
910 if(!p_r1
) FATAL_ERROR("Value::Value()");
914 FATAL_ERROR("Value::Value()");
919 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
920 Ttcn::ParsedActualParameters
*p_ap_list
)
921 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
923 u
.expr
.v_optype
= p_optype
;
924 u
.expr
.state
= EXPR_NOT_CHECKED
;
926 case OPTYPE_ACTIVATE_REFD
:
927 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
929 u
.expr
.t_list2
= p_ap_list
;
932 FATAL_ERROR("Value::Value()");
937 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
938 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
939 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
941 u
.expr
.v_optype
= p_optype
;
942 u
.expr
.state
= EXPR_NOT_CHECKED
;
944 case OPTYPE_EXECUTE_REFD
:
945 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
947 u
.expr
.t_list2
= p_t_list2
;
951 FATAL_ERROR("Value::Value()");
956 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
957 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
959 u
.expr
.v_optype
= p_optype
;
960 u
.expr
.state
= EXPR_NOT_CHECKED
;
963 if(!p_r1
) FATAL_ERROR("Value::Value()");
968 FATAL_ERROR("Value::Value()");
973 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
974 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
975 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
977 u
.expr
.v_optype
= p_optype
;
978 u
.expr
.state
= EXPR_NOT_CHECKED
;
980 case OPTYPE_COMP_CREATE
:
981 if(!p_r1
) FATAL_ERROR("Value::Value()");
988 FATAL_ERROR("Value::Value()");
993 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
994 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
996 u
.expr
.v_optype
= p_optype
;
997 u
.expr
.state
= EXPR_NOT_CHECKED
;
1000 case OPTYPE_SUBTRACT
:
1001 case OPTYPE_MULTIPLY
:
1022 case OPTYPE_INT2BIT
:
1023 case OPTYPE_INT2HEX
:
1024 case OPTYPE_INT2OCT
:
1025 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1029 case OPTYPE_UNICHAR2OCT
:
1030 case OPTYPE_OCT2UNICHAR
:
1031 case OPTYPE_ENCODE_BASE64
:
1032 if(!p_v1
) FATAL_ERROR("Value::Value()");
1034 // p_v2 may be NULL if there is no second param
1038 FATAL_ERROR("Value::Value()");
1043 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1044 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1045 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1047 u
.expr
.v_optype
= p_optype
;
1048 u
.expr
.state
= EXPR_NOT_CHECKED
;
1050 case OPTYPE_REPLACE
:
1051 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1058 FATAL_ERROR("Value::Value()");
1063 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1064 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1066 u
.expr
.v_optype
= p_optype
;
1067 u
.expr
.state
= EXPR_NOT_CHECKED
;
1070 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1076 FATAL_ERROR("Value::Value()");
1081 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1082 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1084 u
.expr
.v_optype
=p_optype
;
1085 u
.expr
.state
=EXPR_NOT_CHECKED
;
1088 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1094 FATAL_ERROR("Value::Value()");
1099 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1100 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1102 u
.expr
.v_optype
=p_optype
;
1103 u
.expr
.state
=EXPR_NOT_CHECKED
;
1106 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1112 FATAL_ERROR("Value::Value()");
1117 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1118 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1120 u
.expr
.v_optype
= p_optype
;
1121 u
.expr
.state
= EXPR_NOT_CHECKED
;
1124 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1129 FATAL_ERROR("Value::Value()");
1134 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1136 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1138 u
.expr
.v_optype
= p_optype
;
1139 u
.expr
.state
= EXPR_NOT_CHECKED
;
1141 case OPTYPE_ISCHOSEN
:
1142 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1147 FATAL_ERROR("Value::Value()");
1151 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1152 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1154 u
.expr
.v_optype
= p_optype
;
1155 u
.expr
.state
= EXPR_NOT_CHECKED
;
1157 case OPTYPE_LOG2STR
:
1158 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1159 u
.expr
.logargs
= p_logargs
;
1162 FATAL_ERROR("Value::Value()");
1166 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1167 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1169 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1170 switch (p_macrotype
) {
1171 case MACRO_MODULEID
:
1172 case MACRO_FILENAME
:
1173 case MACRO_BFILENAME
:
1174 case MACRO_FILEPATH
:
1175 case MACRO_LINENUMBER
:
1176 case MACRO_LINENUMBER_C
:
1177 case MACRO_DEFINITIONID
:
1179 case MACRO_TESTCASEID
:
1182 FATAL_ERROR("Value::Value()");
1184 u
.macro
= p_macrotype
;
1187 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1188 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1190 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1197 FATAL_ERROR("Value::Value()");
1201 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1202 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1204 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1208 u
.ref
.refd_last
= 0;
1214 FATAL_ERROR("Value::Value()");
1218 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1219 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1221 if(!p_block
) FATAL_ERROR("NULL parameter");
1227 FATAL_ERROR("Value::Value()");
1231 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1232 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1234 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1235 switch (p_verdict
) {
1238 case Verdict_INCONC
:
1243 FATAL_ERROR("Value::Value()");
1245 u
.verdict
= p_verdict
;
1248 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1249 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1251 u
.expr
.v_optype
= p_optype
;
1252 u
.expr
.state
= EXPR_NOT_CHECKED
;
1255 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1260 FATAL_ERROR("Value::Value()");
1269 Value
*Value::clone() const
1271 return new Value(*this);
1274 Value::operationtype_t
Value::get_optype() const
1276 if(valuetype
!=V_EXPR
)
1277 FATAL_ERROR("Value::get_optype()");
1278 return u
.expr
.v_optype
;
1281 void Value::set_my_governor(Type
*p_gov
)
1284 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1288 Type
*Value::get_my_governor() const
1293 void Value::set_fullname(const string
& p_fullname
)
1295 GovernedSimple::set_fullname(p_fullname
);
1298 u
.char_syms
->set_fullname(p_fullname
);
1302 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1303 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1306 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1307 u
.choice
.alt_name
->get_dispname());
1312 u
.val_vs
->set_fullname(p_fullname
);
1316 u
.val_nvs
->set_fullname(p_fullname
);
1319 u
.ref
.ref
->set_fullname(p_fullname
);
1322 u
.refered
->set_fullname(p_fullname
);
1325 u
.invoke
.v
->set_fullname(p_fullname
);
1326 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1327 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1330 set_fullname_expr(p_fullname
);
1337 void Value::set_my_scope(Scope
*p_scope
)
1339 GovernedSimple::set_my_scope(p_scope
);
1342 u
.char_syms
->set_my_scope(p_scope
);
1346 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1347 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1350 u
.choice
.alt_value
->set_my_scope(p_scope
);
1355 u
.val_vs
->set_my_scope(p_scope
);
1359 u
.val_nvs
->set_my_scope(p_scope
);
1362 u
.ref
.ref
->set_my_scope(p_scope
);
1365 u
.refered
->set_my_scope(p_scope
);
1368 u
.invoke
.v
->set_my_scope(p_scope
);
1369 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1370 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1373 set_my_scope_expr(p_scope
);
1380 void Value::set_fullname_expr(const string
& p_fullname
)
1382 switch (u
.expr
.v_optype
) {
1383 case OPTYPE_RND
: // -
1384 case OPTYPE_COMP_NULL
:
1385 case OPTYPE_COMP_MTC
:
1386 case OPTYPE_COMP_SYSTEM
:
1387 case OPTYPE_COMP_SELF
:
1388 case OPTYPE_COMP_RUNNING_ANY
:
1389 case OPTYPE_COMP_RUNNING_ALL
:
1390 case OPTYPE_COMP_ALIVE_ANY
:
1391 case OPTYPE_COMP_ALIVE_ALL
:
1392 case OPTYPE_TMR_RUNNING_ANY
:
1393 case OPTYPE_GETVERDICT
:
1394 case OPTYPE_TESTCASENAME
:
1395 case OPTYPE_PROF_RUNNING
:
1397 case OPTYPE_UNARYPLUS
: // v1
1398 case OPTYPE_UNARYMINUS
:
1401 case OPTYPE_BIT2HEX
:
1402 case OPTYPE_BIT2INT
:
1403 case OPTYPE_BIT2OCT
:
1404 case OPTYPE_BIT2STR
:
1405 case OPTYPE_CHAR2INT
:
1406 case OPTYPE_CHAR2OCT
:
1407 case OPTYPE_COMP_RUNNING
:
1408 case OPTYPE_COMP_ALIVE
:
1409 case OPTYPE_FLOAT2INT
:
1410 case OPTYPE_FLOAT2STR
:
1411 case OPTYPE_HEX2BIT
:
1412 case OPTYPE_HEX2INT
:
1413 case OPTYPE_HEX2OCT
:
1414 case OPTYPE_HEX2STR
:
1415 case OPTYPE_INT2CHAR
:
1416 case OPTYPE_INT2FLOAT
:
1417 case OPTYPE_INT2STR
:
1418 case OPTYPE_INT2UNICHAR
:
1419 case OPTYPE_OCT2BIT
:
1420 case OPTYPE_OCT2CHAR
:
1421 case OPTYPE_OCT2HEX
:
1422 case OPTYPE_OCT2INT
:
1423 case OPTYPE_OCT2STR
:
1424 case OPTYPE_STR2BIT
:
1425 case OPTYPE_STR2FLOAT
:
1426 case OPTYPE_STR2HEX
:
1427 case OPTYPE_STR2INT
:
1428 case OPTYPE_STR2OCT
:
1429 case OPTYPE_UNICHAR2INT
:
1430 case OPTYPE_UNICHAR2CHAR
:
1431 case OPTYPE_ENUM2INT
:
1432 case OPTYPE_RNDWITHVAL
:
1433 case OPTYPE_REMOVE_BOM
:
1434 case OPTYPE_GET_STRINGENCODING
:
1435 case OPTYPE_DECODE_BASE64
:
1436 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1438 case OPTYPE_ADD
: // v1 v2
1439 case OPTYPE_SUBTRACT
:
1440 case OPTYPE_MULTIPLY
:
1461 case OPTYPE_INT2BIT
:
1462 case OPTYPE_INT2HEX
:
1463 case OPTYPE_INT2OCT
:
1464 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1465 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1467 case OPTYPE_UNICHAR2OCT
:
1468 case OPTYPE_OCT2UNICHAR
:
1469 case OPTYPE_ENCODE_BASE64
:
1470 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1471 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1474 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1475 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1478 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1479 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1480 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1483 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1484 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1485 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1487 case OPTYPE_DECOMP
: // v1 v2 v3
1488 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1489 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1490 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1492 case OPTYPE_REPLACE
:
1493 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1494 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1495 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1496 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1498 case OPTYPE_LENGTHOF
: // ti1
1499 case OPTYPE_SIZEOF
: // ti1
1500 case OPTYPE_VALUEOF
: // ti1
1501 case OPTYPE_ISVALUE
:
1502 case OPTYPE_ISBOUND
:
1504 case OPTYPE_ISPRESENT
:
1505 case OPTYPE_TTCN2STRING
:
1506 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1508 case OPTYPE_UNDEF_RUNNING
: // r1
1509 case OPTYPE_TMR_READ
:
1510 case OPTYPE_TMR_RUNNING
:
1511 case OPTYPE_ACTIVATE
:
1512 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1514 case OPTYPE_EXECUTE
: // r1 [v2]
1515 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1516 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1518 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1519 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1520 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1521 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1523 case OPTYPE_MATCH
: // v1 t2
1524 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1525 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1527 case OPTYPE_ISCHOSEN
: // r1 i2
1528 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1530 case OPTYPE_ISCHOSEN_V
: // v1 i2
1531 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1533 case OPTYPE_ISCHOSEN_T
: // t1 i2
1534 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1536 case OPTYPE_ACTIVATE_REFD
:
1537 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1538 if(u
.expr
.state
!=EXPR_CHECKED
)
1539 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1541 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1543 case OPTYPE_EXECUTE_REFD
:
1544 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1545 if(u
.expr
.state
!=EXPR_CHECKED
)
1546 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1548 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1550 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1552 case OPTYPE_LOG2STR
:
1553 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1556 FATAL_ERROR("Value::set_fullname_expr()");
1560 void Value::set_my_scope_expr(Scope
*p_scope
)
1562 switch (u
.expr
.v_optype
) {
1563 case OPTYPE_RND
: // -
1564 case OPTYPE_COMP_NULL
:
1565 case OPTYPE_COMP_MTC
:
1566 case OPTYPE_COMP_SYSTEM
:
1567 case OPTYPE_COMP_SELF
:
1568 case OPTYPE_COMP_RUNNING_ANY
:
1569 case OPTYPE_COMP_RUNNING_ALL
:
1570 case OPTYPE_COMP_ALIVE_ANY
:
1571 case OPTYPE_COMP_ALIVE_ALL
:
1572 case OPTYPE_TMR_RUNNING_ANY
:
1573 case OPTYPE_GETVERDICT
:
1574 case OPTYPE_TESTCASENAME
:
1575 case OPTYPE_PROF_RUNNING
:
1577 case OPTYPE_UNARYPLUS
: // v1
1578 case OPTYPE_UNARYMINUS
:
1581 case OPTYPE_BIT2HEX
:
1582 case OPTYPE_BIT2INT
:
1583 case OPTYPE_BIT2OCT
:
1584 case OPTYPE_BIT2STR
:
1585 case OPTYPE_CHAR2INT
:
1586 case OPTYPE_CHAR2OCT
:
1587 case OPTYPE_COMP_RUNNING
:
1588 case OPTYPE_COMP_ALIVE
:
1589 case OPTYPE_FLOAT2INT
:
1590 case OPTYPE_FLOAT2STR
:
1591 case OPTYPE_HEX2BIT
:
1592 case OPTYPE_HEX2INT
:
1593 case OPTYPE_HEX2OCT
:
1594 case OPTYPE_HEX2STR
:
1595 case OPTYPE_INT2CHAR
:
1596 case OPTYPE_INT2FLOAT
:
1597 case OPTYPE_INT2STR
:
1598 case OPTYPE_INT2UNICHAR
:
1599 case OPTYPE_OCT2BIT
:
1600 case OPTYPE_OCT2CHAR
:
1601 case OPTYPE_OCT2HEX
:
1602 case OPTYPE_OCT2INT
:
1603 case OPTYPE_OCT2STR
:
1604 case OPTYPE_STR2BIT
:
1605 case OPTYPE_STR2FLOAT
:
1606 case OPTYPE_STR2HEX
:
1607 case OPTYPE_STR2INT
:
1608 case OPTYPE_STR2OCT
:
1609 case OPTYPE_UNICHAR2INT
:
1610 case OPTYPE_UNICHAR2CHAR
:
1611 case OPTYPE_ENUM2INT
:
1612 case OPTYPE_RNDWITHVAL
:
1613 case OPTYPE_REMOVE_BOM
:
1614 case OPTYPE_GET_STRINGENCODING
:
1615 case OPTYPE_DECODE_BASE64
:
1616 u
.expr
.v1
->set_my_scope(p_scope
);
1618 case OPTYPE_ADD
: // v1 v2
1619 case OPTYPE_SUBTRACT
:
1620 case OPTYPE_MULTIPLY
:
1641 case OPTYPE_INT2BIT
:
1642 case OPTYPE_INT2HEX
:
1643 case OPTYPE_INT2OCT
:
1644 u
.expr
.v1
->set_my_scope(p_scope
);
1645 u
.expr
.v2
->set_my_scope(p_scope
);
1647 case OPTYPE_UNICHAR2OCT
:
1648 case OPTYPE_OCT2UNICHAR
:
1649 case OPTYPE_ENCODE_BASE64
:
1650 u
.expr
.v1
->set_my_scope(p_scope
);
1651 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1654 u
.expr
.r1
->set_my_scope(p_scope
);
1655 u
.expr
.r2
->set_my_scope(p_scope
);
1658 u
.expr
.ti1
->set_my_scope(p_scope
);
1659 u
.expr
.v2
->set_my_scope(p_scope
);
1660 u
.expr
.v3
->set_my_scope(p_scope
);
1663 u
.expr
.ti1
->set_my_scope(p_scope
);
1664 u
.expr
.t2
->set_my_scope(p_scope
);
1665 u
.expr
.v3
->set_my_scope(p_scope
);
1667 case OPTYPE_DECOMP
: // v1 v2 v3
1668 u
.expr
.v1
->set_my_scope(p_scope
);
1669 u
.expr
.v2
->set_my_scope(p_scope
);
1670 u
.expr
.v3
->set_my_scope(p_scope
);
1672 case OPTYPE_REPLACE
:
1673 u
.expr
.ti1
->set_my_scope(p_scope
);
1674 u
.expr
.v2
->set_my_scope(p_scope
);
1675 u
.expr
.v3
->set_my_scope(p_scope
);
1676 u
.expr
.ti4
->set_my_scope(p_scope
);
1678 case OPTYPE_LENGTHOF
: // ti1
1679 case OPTYPE_SIZEOF
: // ti1
1680 case OPTYPE_VALUEOF
: // ti1
1681 case OPTYPE_ISVALUE
:
1682 case OPTYPE_ISBOUND
:
1684 case OPTYPE_ISPRESENT
:
1685 case OPTYPE_TTCN2STRING
:
1686 u
.expr
.ti1
->set_my_scope(p_scope
);
1688 case OPTYPE_UNDEF_RUNNING
: // r1
1689 case OPTYPE_TMR_READ
:
1690 case OPTYPE_TMR_RUNNING
:
1691 case OPTYPE_ACTIVATE
:
1692 u
.expr
.r1
->set_my_scope(p_scope
);
1694 case OPTYPE_EXECUTE
: // r1 [v2]
1695 u
.expr
.r1
->set_my_scope(p_scope
);
1696 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1698 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1699 u
.expr
.r1
->set_my_scope(p_scope
);
1700 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1701 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1703 case OPTYPE_MATCH
: // v1 t2
1704 u
.expr
.v1
->set_my_scope(p_scope
);
1705 u
.expr
.t2
->set_my_scope(p_scope
);
1707 case OPTYPE_ISCHOSEN
: // r1 i2
1708 u
.expr
.r1
->set_my_scope(p_scope
);
1710 case OPTYPE_ISCHOSEN_V
: // v1 i2
1711 u
.expr
.v1
->set_my_scope(p_scope
);
1713 case OPTYPE_ISCHOSEN_T
: // t1 i2
1714 u
.expr
.t1
->set_my_scope(p_scope
);
1716 case OPTYPE_ACTIVATE_REFD
:
1717 u
.expr
.v1
->set_my_scope(p_scope
);
1718 if(u
.expr
.state
!=EXPR_CHECKED
) {
1719 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1721 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1723 case OPTYPE_EXECUTE_REFD
:
1724 u
.expr
.v1
->set_my_scope(p_scope
);
1725 if(u
.expr
.state
!=EXPR_CHECKED
) {
1726 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1728 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1731 u
.expr
.v3
->set_my_scope(p_scope
);
1733 case OPTYPE_LOG2STR
:
1734 u
.expr
.logargs
->set_my_scope(p_scope
);
1737 FATAL_ERROR("Value::set_my_scope_expr()");
1741 void Value::set_genname_recursive(const string
& p_genname
)
1743 size_t genname_len
= p_genname
.size();
1744 if (genname_len
>= 4 &&
1745 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1746 // if the genname ends with ()() (i.e. the value stands for an optional
1747 // field) then drop the last () from the own genname, but leave it for
1748 // the embedded values
1749 set_genname(p_genname
.substr(0, genname_len
- 2));
1750 } else set_genname(p_genname
);
1753 string
embedded_genname(p_genname
);
1754 embedded_genname
+= '.';
1755 // If this is a choice value for an anytype, prepend the AT_ prefix
1756 // to the name of the alternative. The genname is used later in
1757 // Common::Value::generate_code_init_se()
1758 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1759 embedded_genname
+= "AT_";
1760 embedded_genname
+= u
.choice
.alt_name
->get_name();
1761 embedded_genname
+= "()";
1762 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1766 if (!is_indexed()) {
1767 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1768 for (size_t i
= 0; i
< nof_vs
; i
++) {
1769 string
embedded_genname(p_genname
);
1770 embedded_genname
+= '[';
1771 embedded_genname
+= Int2string(i
);
1772 embedded_genname
+= ']';
1773 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1776 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1777 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1778 string
embedded_genname(p_genname
);
1779 embedded_genname
+= '[';
1780 embedded_genname
+= Int2string(i
);
1781 embedded_genname
+= ']';
1782 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1783 ->set_genname_recursive(embedded_genname
);
1788 if (!my_governor
) return; // error recovery
1789 Type
*type
= my_governor
->get_type_refd_last();
1790 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1791 Int offset
= type
->get_dimension()->get_offset();
1792 if (!is_indexed()) {
1793 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1794 for (size_t i
= 0; i
< nof_vs
; i
++) {
1795 string
embedded_genname(p_genname
);
1796 embedded_genname
+= '[';
1797 embedded_genname
+= Int2string(offset
+ i
);
1798 embedded_genname
+= ']';
1799 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1802 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1803 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1804 string
embedded_genname(p_genname
);
1805 embedded_genname
+= '[';
1806 embedded_genname
+= Int2string(offset
+ i
);
1807 embedded_genname
+= ']';
1808 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1809 ->set_genname_recursive(embedded_genname
);
1815 if (!my_governor
) return; // error recovery
1816 Type
*t
= my_governor
->get_type_refd_last();
1817 if (!t
->is_secho()) return; // error recovery
1818 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1819 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1820 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1821 const Identifier
& id
= nv
->get_name();
1822 if (!t
->has_comp_withName(id
)) return; // error recovery
1823 string
embedded_genname(p_genname
);
1824 embedded_genname
+= '.';
1825 embedded_genname
+= id
.get_name();
1826 embedded_genname
+= "()";
1827 if (t
->get_comp_byName(id
)->get_is_optional())
1828 embedded_genname
+= "()";
1829 nv
->get_value()->set_genname_recursive(embedded_genname
);
1837 void Value::set_genname_prefix(const char *p_genname_prefix
)
1839 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1842 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1847 if (!is_indexed()) {
1848 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1849 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1851 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1852 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1853 ->set_genname_prefix(p_genname_prefix
);
1858 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1859 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1860 ->set_genname_prefix(p_genname_prefix
);
1867 void Value::set_code_section(code_section_t p_code_section
)
1869 GovernedSimple::set_code_section(p_code_section
);
1872 switch (u
.expr
.v_optype
) {
1873 case OPTYPE_RND
: // -
1874 case OPTYPE_COMP_NULL
:
1875 case OPTYPE_COMP_MTC
:
1876 case OPTYPE_COMP_SYSTEM
:
1877 case OPTYPE_COMP_SELF
:
1878 case OPTYPE_COMP_RUNNING_ANY
:
1879 case OPTYPE_COMP_RUNNING_ALL
:
1880 case OPTYPE_COMP_ALIVE_ANY
:
1881 case OPTYPE_COMP_ALIVE_ALL
:
1882 case OPTYPE_TMR_RUNNING_ANY
:
1883 case OPTYPE_GETVERDICT
:
1884 case OPTYPE_TESTCASENAME
:
1885 case OPTYPE_PROF_RUNNING
:
1887 case OPTYPE_UNARYPLUS
: // v1
1888 case OPTYPE_UNARYMINUS
:
1891 case OPTYPE_BIT2HEX
:
1892 case OPTYPE_BIT2INT
:
1893 case OPTYPE_BIT2OCT
:
1894 case OPTYPE_BIT2STR
:
1895 case OPTYPE_CHAR2INT
:
1896 case OPTYPE_CHAR2OCT
:
1897 case OPTYPE_COMP_RUNNING
:
1898 case OPTYPE_COMP_ALIVE
:
1899 case OPTYPE_FLOAT2INT
:
1900 case OPTYPE_FLOAT2STR
:
1901 case OPTYPE_HEX2BIT
:
1902 case OPTYPE_HEX2INT
:
1903 case OPTYPE_HEX2OCT
:
1904 case OPTYPE_HEX2STR
:
1905 case OPTYPE_INT2CHAR
:
1906 case OPTYPE_INT2FLOAT
:
1907 case OPTYPE_INT2STR
:
1908 case OPTYPE_INT2UNICHAR
:
1909 case OPTYPE_OCT2BIT
:
1910 case OPTYPE_OCT2CHAR
:
1911 case OPTYPE_OCT2HEX
:
1912 case OPTYPE_OCT2INT
:
1913 case OPTYPE_OCT2STR
:
1914 case OPTYPE_STR2BIT
:
1915 case OPTYPE_STR2FLOAT
:
1916 case OPTYPE_STR2HEX
:
1917 case OPTYPE_STR2INT
:
1918 case OPTYPE_STR2OCT
:
1919 case OPTYPE_UNICHAR2INT
:
1920 case OPTYPE_UNICHAR2CHAR
:
1921 case OPTYPE_ENUM2INT
:
1922 case OPTYPE_RNDWITHVAL
:
1923 case OPTYPE_GET_STRINGENCODING
:
1924 case OPTYPE_DECODE_BASE64
:
1925 case OPTYPE_REMOVE_BOM
:
1926 u
.expr
.v1
->set_code_section(p_code_section
);
1928 case OPTYPE_ADD
: // v1 v2
1929 case OPTYPE_SUBTRACT
:
1930 case OPTYPE_MULTIPLY
:
1951 case OPTYPE_INT2BIT
:
1952 case OPTYPE_INT2HEX
:
1953 case OPTYPE_INT2OCT
:
1954 u
.expr
.v1
->set_code_section(p_code_section
);
1955 u
.expr
.v2
->set_code_section(p_code_section
);
1957 case OPTYPE_UNICHAR2OCT
:
1958 case OPTYPE_OCT2UNICHAR
:
1959 case OPTYPE_ENCODE_BASE64
:
1960 u
.expr
.v1
->set_code_section(p_code_section
);
1961 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
1964 u
.expr
.r1
->set_code_section(p_code_section
);
1965 u
.expr
.r2
->set_code_section(p_code_section
);
1968 u
.expr
.ti1
->set_code_section(p_code_section
);
1969 u
.expr
.v2
->set_code_section(p_code_section
);
1970 u
.expr
.v3
->set_code_section(p_code_section
);
1973 u
.expr
.ti1
->set_code_section(p_code_section
);
1974 u
.expr
.t2
->set_code_section(p_code_section
);
1975 u
.expr
.v3
->set_code_section(p_code_section
);
1977 case OPTYPE_DECOMP
: // v1 v2 v3
1978 u
.expr
.v1
->set_code_section(p_code_section
);
1979 u
.expr
.v2
->set_code_section(p_code_section
);
1980 u
.expr
.v3
->set_code_section(p_code_section
);
1982 case OPTYPE_REPLACE
:
1983 u
.expr
.ti1
->set_code_section(p_code_section
);
1984 u
.expr
.v2
->set_code_section(p_code_section
);
1985 u
.expr
.v3
->set_code_section(p_code_section
);
1986 u
.expr
.ti4
->set_code_section(p_code_section
);
1988 case OPTYPE_LENGTHOF
: // ti1
1989 case OPTYPE_SIZEOF
: // ti1
1990 case OPTYPE_VALUEOF
: // ti1
1991 case OPTYPE_ISVALUE
:
1992 case OPTYPE_ISBOUND
:
1994 case OPTYPE_ISPRESENT
:
1995 case OPTYPE_TTCN2STRING
:
1996 u
.expr
.ti1
->set_code_section(p_code_section
);
1998 case OPTYPE_UNDEF_RUNNING
: // r1
1999 case OPTYPE_TMR_READ
:
2000 case OPTYPE_TMR_RUNNING
:
2001 case OPTYPE_ACTIVATE
:
2002 u
.expr
.r1
->set_code_section(p_code_section
);
2004 case OPTYPE_EXECUTE
: // r1 [v2]
2005 u
.expr
.r1
->set_code_section(p_code_section
);
2006 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2008 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2009 u
.expr
.r1
->set_code_section(p_code_section
);
2010 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2011 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2013 case OPTYPE_MATCH
: // v1 t2
2014 u
.expr
.v1
->set_code_section(p_code_section
);
2015 u
.expr
.t2
->set_code_section(p_code_section
);
2017 case OPTYPE_ISCHOSEN
: // r1 i2
2018 u
.expr
.r1
->set_code_section(p_code_section
);
2020 case OPTYPE_ISCHOSEN_V
: // v1 i2
2021 u
.expr
.v1
->set_code_section(p_code_section
);
2023 case OPTYPE_ISCHOSEN_T
: // t1 i2
2024 u
.expr
.t1
->set_code_section(p_code_section
);
2026 case OPTYPE_ACTIVATE_REFD
:
2027 u
.expr
.v1
->set_code_section(p_code_section
);
2028 if(u
.expr
.state
!=EXPR_CHECKED
)
2029 u
.expr
.t_list2
->set_code_section(p_code_section
);
2031 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2032 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2033 u
.expr
.state
= EXPR_CHECKED
;
2036 case OPTYPE_EXECUTE_REFD
:
2037 u
.expr
.v1
->set_code_section(p_code_section
);
2038 if(u
.expr
.state
!=EXPR_CHECKED
)
2039 u
.expr
.t_list2
->set_code_section(p_code_section
);
2041 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2042 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2043 u
.expr
.state
= EXPR_CHECKED
;
2046 u
.expr
.v3
->set_code_section(p_code_section
);
2048 case OPTYPE_LOG2STR
:
2049 u
.expr
.logargs
->set_code_section(p_code_section
);
2052 FATAL_ERROR("Value::set_code_section()");
2056 u
.choice
.alt_value
->set_code_section(p_code_section
);
2061 if (!is_indexed()) {
2062 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2063 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2065 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2066 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2071 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2072 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2073 ->set_code_section(p_code_section
);
2076 u
.ref
.ref
->set_code_section(p_code_section
);
2079 u
.refered
->set_code_section(p_code_section
);
2082 u
.invoke
.v
->set_code_section(p_code_section
);
2083 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2084 if(u
.invoke
.ap_list
)
2085 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2086 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2093 void Value::change_sign()
2097 *u
.val_Int
=-*u
.val_Int
;
2105 FATAL_ERROR("Value::change_sign()");
2109 void Value::add_oid_comp(OID_comp
* p_comp
)
2112 FATAL_ERROR("NULL parameter");
2113 u
.oid_comps
->add(p_comp
);
2114 p_comp
->set_fullname(get_fullname()+"."
2115 +Int2string(u
.oid_comps
->size()));
2116 p_comp
->set_my_scope(my_scope
);
2119 void Value::set_valuetype(valuetype_t p_valuetype
)
2121 if (valuetype
== V_ERROR
) return;
2122 else if (p_valuetype
== V_ERROR
) {
2123 if(valuetype
==V_EXPR
) {
2124 switch(u
.expr
.state
) {
2126 u
.expr
.state
=EXPR_CHECKING_ERR
;
2128 case EXPR_CHECKING_ERR
:
2135 valuetype
= V_ERROR
;
2139 case V_UNDEF_LOWERID
:
2140 switch(p_valuetype
) {
2145 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2146 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2147 u
.ref
.ref
->set_my_scope(get_my_scope());
2148 u
.ref
.ref
->set_fullname(get_fullname());
2149 u
.ref
.ref
->set_location(*this);
2150 u
.ref
.refd_last
= 0;
2153 FATAL_ERROR("Value::set_valuetype()");
2156 case V_UNDEF_BLOCK
: {
2157 Block
*t_block
=u
.block
;
2159 switch(p_valuetype
) {
2161 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2162 v
=dynamic_cast<Value
*>(node
);
2165 u
.ids
=new map
<string
, Identifier
>();
2168 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2172 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2173 v
=dynamic_cast<Value
*>(node
);
2176 u
.val_vs
=new Values();
2179 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2181 u
.val_vs
->set_my_scope(get_my_scope());
2182 u
.val_vs
->set_fullname(get_fullname());
2185 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2186 v
=dynamic_cast<Value
*>(node
);
2189 u
.val_vs
=new Values();
2192 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2194 u
.val_vs
->set_my_scope(get_my_scope());
2195 u
.val_vs
->set_fullname(get_fullname());
2198 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2199 v
=dynamic_cast<Value
*>(node
);
2202 u
.val_nvs
=new NamedValues();
2205 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2207 u
.val_nvs
->set_my_scope(get_my_scope());
2208 u
.val_nvs
->set_fullname(get_fullname());
2211 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2212 v
=dynamic_cast<Value
*>(node
);
2215 u
.val_nvs
=new NamedValues();
2218 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2220 u
.val_nvs
->set_my_scope(get_my_scope());
2221 u
.val_nvs
->set_fullname(get_fullname());
2224 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2225 v
=dynamic_cast<Value
*>(node
);
2228 u
.oid_comps
=new vector
<OID_comp
>();
2231 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2233 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2234 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2237 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2238 v
=dynamic_cast<Value
*>(node
);
2241 u
.oid_comps
=new vector
<OID_comp
>();
2244 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2246 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2247 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2250 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2251 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2254 u
.char_syms
=new CharSyms();
2256 u
.char_syms
->set_my_scope(get_my_scope());
2257 u
.char_syms
->set_fullname(get_fullname());
2260 FATAL_ERROR("Value::set_valuetype()");
2266 if (p_valuetype
== V_USTR
) {
2267 Value
*v_last
= get_value_refd_last();
2268 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2269 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2272 u
.ustr
.convert_str
= true; // will be converted back to string
2273 } else FATAL_ERROR("Value::set_valuetype()");
2276 switch(p_valuetype
) {
2278 const string
& str
= u
.char_syms
->get_string();
2280 set_val_str(new string(str
));
2283 const ustring
& ustr
= u
.char_syms
->get_ustring();
2285 set_val_ustr(new ustring(ustr
));
2286 u
.ustr
.convert_str
= false;
2288 case V_ISO2022STR
: {
2289 const string
& str
= u
.char_syms
->get_iso2022string();
2291 set_val_str(new string(str
));
2294 FATAL_ERROR("Value::set_valuetype()");
2299 if (p_valuetype
== V_REAL
)
2300 val_Real
= u
.val_Int
->to_real();
2301 else FATAL_ERROR("Value::set_valuetype()");
2303 u
.val_Real
= val_Real
;
2306 clean_up_string_elements(u
.str
.str_elements
);
2307 string
*old_str
= u
.str
.val_str
;
2308 switch(p_valuetype
) {
2310 set_val_str(hex2bit(*old_str
));
2313 set_val_str(asn_hex2oct(*old_str
));
2316 FATAL_ERROR("Value::set_valuetype()");
2321 clean_up_string_elements(u
.str
.str_elements
);
2322 if (p_valuetype
== V_OSTR
) {
2323 string
*old_str
= u
.str
.val_str
;
2324 set_val_str(asn_bit2oct(*old_str
));
2326 } else FATAL_ERROR("Value::set_valuetype()");
2329 clean_up_string_elements(u
.str
.str_elements
);
2330 switch(p_valuetype
) {
2332 string
*old_str
= u
.str
.val_str
;
2333 set_val_ustr(new ustring(*old_str
));
2334 u
.ustr
.convert_str
= true; // will be converted back to string
2341 FATAL_ERROR("Value::set_valuetype()");
2342 } // switch p_valuetype
2345 clean_up_string_elements(u
.ustr
.ustr_elements
);
2346 switch(p_valuetype
) {
2348 ustring
*old_str
= u
.ustr
.val_ustr
;
2349 size_t nof_chars
= old_str
->size();
2350 bool warning_flag
= false;
2351 for (size_t i
= 0; i
< nof_chars
; i
++) {
2352 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2353 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2354 error("This string value cannot contain multiple-byte characters, "
2355 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2356 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2358 p_valuetype
= V_ERROR
;
2360 } else if (uchar
.cell
> 127 && !warning_flag
) {
2361 warning("This string value may not contain characters with code "
2362 "higher than 127, but it has character with code %u (0x%02X) "
2363 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2364 warning_flag
= true;
2367 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2371 error("ISO-10646 string value cannot be converted to "
2373 delete u
.ustr
.val_ustr
;
2374 p_valuetype
= V_ERROR
;
2377 FATAL_ERROR("Value::set_valuetype()");
2378 } // switch p_valuetype
2381 switch (p_valuetype
) {
2383 NamedValues
*nvs
= u
.val_nvs
;
2384 if (nvs
->get_nof_nvs() < 1) {
2385 error("Union value must have one active field");
2387 valuetype
= V_ERROR
;
2389 } else if (nvs
->get_nof_nvs() > 1) {
2390 error("Only one field was expected in union value instead of %lu",
2391 (unsigned long) nvs
->get_nof_nvs());
2393 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2394 u
.choice
.alt_name
= nv
->get_name().clone();
2395 u
.choice
.alt_value
= nv
->steal_value();
2402 NamedValues
*nvs
= u
.val_nvs
;
2406 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2407 if (nvs
->has_nv_withName(id_mant
)) {
2408 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2409 ->get_value_refd_last();
2410 if (v_tmp
->get_valuetype() == V_INT
) {
2411 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2412 if (*i_mant_int
> INT_MAX
) {
2413 error("Mantissa `%s' should be less than `%d'",
2414 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2417 i_mant
= i_mant_int
->get_val();
2425 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2426 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2427 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2428 Value
*v_tmp
= v
->get_value_refd_last();
2429 if (v_tmp
->get_valuetype() == V_INT
) {
2430 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2431 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2432 v
->error("Base of the REAL must be 2 or 10");
2435 i_base
= i_base_int
->get_val();
2443 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2444 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2445 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2446 ->get_value_refd_last();
2447 if (v_tmp
->get_valuetype() == V_INT
) {
2448 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2449 if (*i_exp_int
> INT_MAX
) {
2450 error("Exponent `%s' should be less than `%d'",
2451 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2454 i_exp
= i_exp_int
->get_val();
2463 valuetype
= V_ERROR
;
2466 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2467 static_cast<double>(i_exp
));
2470 FATAL_ERROR("Value::set_valuetype()");
2474 switch (p_valuetype
) {
2476 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2477 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2478 Type
*t
= my_governor
->get_type_refd_last();
2479 switch (t
->get_typetype()) {
2484 FATAL_ERROR("Value::set_valuetype()");
2486 Values
*vals
= u
.val_vs
;
2487 size_t nof_vals
= vals
->get_nof_vs();
2488 size_t nof_comps
= t
->get_nof_comps();
2489 if (nof_vals
> nof_comps
) {
2490 error("Too many elements in value list notation for type `%s': "
2491 "%lu was expected instead of %lu",
2492 t
->get_typename().c_str(),
2493 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2497 if (nof_vals
<= nof_comps
) {
2498 upper_limit
= nof_vals
;
2501 upper_limit
= nof_comps
;
2504 u
.val_nvs
= new NamedValues
;
2505 for (size_t i
= 0; i
< upper_limit
; i
++) {
2506 Value
*v
= vals
->steal_v_byIndex(i
);
2507 if (v
->valuetype
!= V_NOTUSED
) {
2511 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2512 nv
->set_location(*v
);
2513 u
.val_nvs
->add_nv(nv
);
2515 u
.val_nvs
->set_my_scope(get_my_scope());
2516 u
.val_nvs
->set_fullname(get_fullname());
2518 if (allnotused
&& nof_vals
> 0)
2519 warning("All elements of value list notation for type `%s' are not "
2520 "used symbols (`-')", t
->get_typename().c_str());
2523 // { } -> empty set value
2524 if (u
.val_vs
->get_nof_vs() != 0)
2525 FATAL_ERROR("Value::set_valuetype()");
2527 u
.val_nvs
= new NamedValues
;
2531 // SEQOF -> SETOF or ARRAY: trivial
2534 FATAL_ERROR("Value::set_valuetype()");
2538 switch (p_valuetype
) {
2539 case V_DEFAULT_NULL
:
2544 FATAL_ERROR("Value::set_valuetype()");
2548 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2549 FATAL_ERROR("Value::set_valuetype()");
2553 FATAL_ERROR("Value::set_valuetype()");
2555 valuetype
=p_valuetype
;
2558 void Value::set_valuetype_COMP_NULL()
2560 if(valuetype
== V_ERROR
) return;
2561 if(valuetype
==V_TTCN3_NULL
) {
2563 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2564 // Nothing to check.
2565 u
.expr
.state
=EXPR_CHECKED
;
2567 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2570 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2572 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2574 u
.val_Int
= new int_val_t(p_val_int
);
2576 } else FATAL_ERROR("Value::set_valuetype()");
2579 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2581 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2585 } else FATAL_ERROR("Value::set_valuetype()");
2588 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2590 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2594 } else FATAL_ERROR("Value::set_valuetype()");
2597 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2599 switch (p_valuetype
) {
2603 if (valuetype
== V_REFER
&& p_ass
) break;
2606 FATAL_ERROR("Value::set_valuetype()");
2610 valuetype
= p_valuetype
;
2613 bool Value::is_undef_lowerid()
2615 switch (valuetype
) {
2616 case V_UNDEF_LOWERID
:
2619 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2620 !u
.expr
.ti1
->get_DerivedRef()) {
2621 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2629 const Identifier
& Value::get_undef_lowerid()
2631 switch (valuetype
) {
2632 case V_UNDEF_LOWERID
:
2635 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2636 FATAL_ERROR("Value::get_undef_lowerid()");
2637 return u
.expr
.ti1
->get_Template()->get_specific_value()
2638 ->get_undef_lowerid();
2640 FATAL_ERROR("Value::get_undef_lowerid()");
2642 const Identifier
*dummy
= 0;
2646 void Value::set_lowerid_to_ref()
2648 switch (valuetype
) {
2649 case V_UNDEF_LOWERID
:
2650 set_valuetype(V_REFD
);
2653 // if the governor of the expression is not known (in log(), etc...)
2654 // then the governor is taken from the reference (using
2655 // v1/ti1->get_expr_governor()), but that runs before the
2656 // params were checked, this smells like a workaround :)
2657 switch (u
.expr
.v_optype
) {
2660 u
.expr
.v1
->set_lowerid_to_ref();
2663 u
.expr
.v1
->set_lowerid_to_ref();
2664 u
.expr
.v2
->set_lowerid_to_ref();
2666 case OPTYPE_VALUEOF
:
2667 case OPTYPE_ISVALUE
:
2668 case OPTYPE_ISBOUND
:
2669 case OPTYPE_ISPRESENT
:
2672 case OPTYPE_REPLACE
:
2673 case OPTYPE_TTCN2STRING
:
2674 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2675 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2676 "In the operand of operation `%s'",
2678 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2680 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2681 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2682 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2683 "In the operand of operation `%s'",
2685 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2688 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2689 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2690 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2691 "In the operand of operation `%s'",
2693 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2706 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2708 switch (valuetype
) {
2716 case V_UNDEF_LOWERID
:
2723 return Type::T_UNDEF
;
2727 FATAL_ERROR("Value::get_expr_returntype()");
2729 return Type::T_ERROR
;
2732 Type
*t
= get_expr_governor(exp_val
);
2733 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2734 else return Type::T_ERROR
; }
2736 return Type::T_FUNCTION
;
2738 return Type::T_ALTSTEP
;
2740 return Type::T_TESTCASE
;
2742 switch(u
.expr
.v_optype
) {
2743 case OPTYPE_COMP_NULL
:
2744 case OPTYPE_COMP_MTC
:
2745 case OPTYPE_COMP_SYSTEM
:
2746 case OPTYPE_COMP_SELF
:
2747 case OPTYPE_COMP_CREATE
:
2748 return Type::T_COMPONENT
;
2749 case OPTYPE_UNDEF_RUNNING
:
2750 case OPTYPE_COMP_RUNNING
:
2751 case OPTYPE_COMP_RUNNING_ANY
:
2752 case OPTYPE_COMP_RUNNING_ALL
:
2753 case OPTYPE_COMP_ALIVE
:
2754 case OPTYPE_COMP_ALIVE_ANY
:
2755 case OPTYPE_COMP_ALIVE_ALL
:
2756 case OPTYPE_TMR_RUNNING
:
2757 case OPTYPE_TMR_RUNNING_ANY
:
2769 case OPTYPE_ISPRESENT
:
2770 case OPTYPE_ISCHOSEN
:
2771 case OPTYPE_ISCHOSEN_V
:
2772 case OPTYPE_ISCHOSEN_T
:
2773 case OPTYPE_ISVALUE
:
2774 case OPTYPE_ISBOUND
:
2775 case OPTYPE_PROF_RUNNING
:
2776 return Type::T_BOOL
;
2777 case OPTYPE_GETVERDICT
:
2778 return Type::T_VERDICT
;
2779 case OPTYPE_VALUEOF
: {
2780 Error_Context
cntxt(this, "In the operand of operation `%s'",
2782 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2783 case OPTYPE_TMR_READ
:
2784 case OPTYPE_INT2FLOAT
:
2785 case OPTYPE_STR2FLOAT
:
2787 case OPTYPE_RNDWITHVAL
:
2788 return Type::T_REAL
;
2789 case OPTYPE_ACTIVATE
:
2790 return Type::T_DEFAULT
;
2791 case OPTYPE_ACTIVATE_REFD
:
2792 return Type::T_DEFAULT
;
2793 case OPTYPE_EXECUTE
:
2794 case OPTYPE_EXECUTE_REFD
:
2795 return Type::T_VERDICT
;
2796 case OPTYPE_UNARYPLUS
: // v1
2797 case OPTYPE_UNARYMINUS
: {
2798 Type::typetype_t tmp_tt
;
2800 Error_Context
cntxt(this, "In the operand of operation `%s'",
2802 u
.expr
.v1
->set_lowerid_to_ref();
2803 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2810 get_value_refd_last(); // to report the error
2811 return Type::T_ERROR
;
2814 case OPTYPE_ADD
: // v1 v2
2815 case OPTYPE_SUBTRACT
:
2816 case OPTYPE_MULTIPLY
:
2817 case OPTYPE_DIVIDE
: {
2818 Type::typetype_t tmp_tt
;
2820 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2822 u
.expr
.v1
->set_lowerid_to_ref();
2823 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2830 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2831 Type::typetype_t tmp_tt2
;
2833 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2835 u
.expr
.v2
->set_lowerid_to_ref();
2836 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2838 Type::typetype_t ret_val
=Type::T_ERROR
;
2839 bool maybeconcat
=false;
2844 if(tmp_tt2
==tmp_tt
) {
2851 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2853 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2854 ret_val
=Type::T_USTR
;
2855 else ret_val
=Type::T_CSTR
;
2862 error("Did you mean the concat operation (`&') instead of"
2863 " addition operator (`+')?");
2864 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2868 get_value_refd_last(); // to report the error
2869 return Type::T_ERROR
;
2872 case OPTYPE_NOT4B
: // v1
2873 case OPTYPE_AND4B
: // v1 v2
2878 Type::typetype_t tmp_tt
;
2880 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
2881 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
2883 u
.expr
.v1
->set_lowerid_to_ref();
2884 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2892 get_value_refd_last(); // to report the error
2893 return Type::T_ERROR
;
2896 case OPTYPE_ROTL
: // v1 v2
2898 Type::typetype_t tmp_tt
;
2900 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
2901 u
.expr
.v_optype
==OPTYPE_ROTL
2902 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
2904 u
.expr
.v1
->set_lowerid_to_ref();
2905 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2918 get_value_refd_last(); // to report the error
2919 return Type::T_ERROR
;
2923 case OPTYPE_REPLACE
: {
2924 Type::typetype_t tmp_tt
;
2926 Error_Context
cntxt(this, "In the operand of operation `%s'",
2928 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2929 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2941 get_value_refd_last(); // to report the error
2942 return Type::T_ERROR
;
2945 case OPTYPE_REGEXP
: {
2946 Type::typetype_t tmp_tt
;
2948 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2950 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2951 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2958 get_value_refd_last(); // to report the error
2959 return Type::T_ERROR
;
2962 case OPTYPE_CONCAT
: { // v1 v2
2963 Type::typetype_t tmp_tt
;
2965 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2967 u
.expr
.v1
->set_lowerid_to_ref();
2968 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2980 get_value_refd_last(); // to report the error
2981 return Type::T_ERROR
;
2986 case OPTYPE_CHAR2INT
:
2987 case OPTYPE_UNICHAR2INT
:
2988 case OPTYPE_BIT2INT
:
2989 case OPTYPE_HEX2INT
:
2990 case OPTYPE_OCT2INT
:
2991 case OPTYPE_STR2INT
:
2992 case OPTYPE_FLOAT2INT
:
2993 case OPTYPE_LENGTHOF
:
2996 case OPTYPE_ENUM2INT
:
2998 case OPTYPE_BIT2STR
:
2999 case OPTYPE_FLOAT2STR
:
3000 case OPTYPE_HEX2STR
:
3001 case OPTYPE_INT2CHAR
:
3002 case OPTYPE_INT2STR
:
3003 case OPTYPE_OCT2CHAR
:
3004 case OPTYPE_OCT2STR
:
3005 case OPTYPE_UNICHAR2CHAR
:
3006 case OPTYPE_LOG2STR
:
3007 case OPTYPE_TESTCASENAME
:
3008 case OPTYPE_TTCN2STRING
:
3009 case OPTYPE_GET_STRINGENCODING
:
3010 case OPTYPE_ENCODE_BASE64
:
3011 return Type::T_CSTR
;
3012 case OPTYPE_INT2UNICHAR
:
3013 case OPTYPE_OCT2UNICHAR
:
3014 return Type::T_USTR
;
3015 case OPTYPE_INT2BIT
:
3016 case OPTYPE_HEX2BIT
:
3017 case OPTYPE_OCT2BIT
:
3018 case OPTYPE_STR2BIT
:
3020 return Type::T_BSTR
;
3021 case OPTYPE_INT2HEX
:
3022 case OPTYPE_BIT2HEX
:
3023 case OPTYPE_OCT2HEX
:
3024 case OPTYPE_STR2HEX
:
3025 return Type::T_HSTR
;
3026 case OPTYPE_INT2OCT
:
3027 case OPTYPE_CHAR2OCT
:
3028 case OPTYPE_HEX2OCT
:
3029 case OPTYPE_BIT2OCT
:
3030 case OPTYPE_STR2OCT
:
3031 case OPTYPE_UNICHAR2OCT
:
3032 case OPTYPE_REMOVE_BOM
:
3033 case OPTYPE_DECODE_BASE64
:
3034 return Type::T_OSTR
;
3038 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3040 return Type::T_ERROR
;
3044 case MACRO_MODULEID
:
3045 case MACRO_FILENAME
:
3046 case MACRO_BFILENAME
:
3047 case MACRO_FILEPATH
:
3048 case MACRO_LINENUMBER
:
3049 case MACRO_DEFINITIONID
:
3051 case MACRO_TESTCASEID
:
3052 return Type::T_CSTR
;
3053 case MACRO_LINENUMBER_C
:
3056 return Type::T_ERROR
;
3059 return Type::T_NULL
;
3061 return Type::T_BOOL
;
3065 return Type::T_REAL
;
3067 return Type::T_ENUM_T
;
3069 return Type::T_BSTR
;
3071 return Type::T_HSTR
;
3073 return Type::T_OSTR
;
3075 return Type::T_CSTR
;
3077 return Type::T_USTR
;
3079 return Type::T_GENERALSTRING
;
3083 return Type::T_ROID
;
3085 return Type::T_VERDICT
;
3086 case V_DEFAULT_NULL
:
3087 return Type::T_DEFAULT
;
3089 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3091 return Type::T_ERROR
;
3095 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3097 if(my_governor
) return my_governor
;
3098 switch (valuetype
) {
3100 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3102 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3103 u
.invoke
.v
->error("A value of type function expected");
3106 t
= t
->get_type_refd_last();
3107 switch(t
->get_typetype()) {
3108 case Type::T_FUNCTION
: {
3109 Type
*t_return_type
= t
->get_function_return_type();
3110 if (!t_return_type
) {
3111 error("Reference to a %s was expected instead of invocation "
3112 "of behavior type `%s' with no return type",
3113 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3114 t
->get_fullname().c_str());
3117 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3118 error("Reference to a value was expected, but functions of type "
3119 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3120 t_return_type
->get_typename().c_str());
3123 return t_return_type
; }
3124 case Type::T_ALTSTEP
:
3127 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3128 t
->get_typename().c_str());
3133 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3135 if (!ass
) goto error
;
3136 switch (ass
->get_asstype()) {
3137 case Assignment::A_CONST
:
3138 case Assignment::A_EXT_CONST
:
3139 case Assignment::A_MODULEPAR
:
3140 case Assignment::A_MODULEPAR_TEMP
:
3141 case Assignment::A_TEMPLATE
:
3142 case Assignment::A_VAR
:
3143 case Assignment::A_VAR_TEMPLATE
:
3144 case Assignment::A_FUNCTION_RVAL
:
3145 case Assignment::A_FUNCTION_RTEMP
:
3146 case Assignment::A_EXT_FUNCTION_RVAL
:
3147 case Assignment::A_EXT_FUNCTION_RTEMP
:
3148 case Assignment::A_PAR_VAL_IN
:
3149 case Assignment::A_PAR_VAL_OUT
:
3150 case Assignment::A_PAR_VAL_INOUT
:
3151 case Assignment::A_PAR_TEMPL_IN
:
3152 case Assignment::A_PAR_TEMPL_OUT
:
3153 case Assignment::A_PAR_TEMPL_INOUT
:
3154 tmp_type
=ass
->get_Type();
3156 case Assignment::A_FUNCTION
:
3157 case Assignment::A_EXT_FUNCTION
:
3158 error("Reference to a %s was expected instead of a call of %s, which "
3159 "does not have return type",
3160 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3161 ass
->get_description().c_str());
3164 error("Reference to a %s was expected instead of %s",
3165 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3166 ass
->get_description().c_str());
3169 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3170 if(!tmp_type
) goto error
;
3173 switch (u
.expr
.v_optype
) {
3174 case OPTYPE_VALUEOF
:
3177 case OPTYPE_REPLACE
:{
3178 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3179 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3180 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3185 return u
.expr
.v1
->get_expr_governor(exp_val
);
3187 return get_expr_governor_v1v2(exp_val
);
3188 case OPTYPE_COMP_MTC
:
3189 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3191 case OPTYPE_COMP_SYSTEM
:
3192 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3194 case OPTYPE_COMP_SELF
:
3196 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3197 if (t_ros
) return t_ros
->get_component_type();
3200 case OPTYPE_COMP_CREATE
:
3201 return chk_expr_operand_comptyperef_create();
3207 return Type::get_pooltype(get_expr_returntype(exp_val
));
3210 set_valuetype(V_ERROR
);
3214 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3216 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3217 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3219 if (v2_gov
) { // both have governors
3220 // return the type that is compatible with both (if there is no type mismatch)
3221 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3224 } else return v1_gov
;
3225 } else { // v1 has no governor
3226 if (v2_gov
) return v2_gov
;
3227 else return NULL
; // neither has governor
3231 Type
*Value::get_expr_governor_last()
3233 Value
*v_last
= get_value_refd_last();
3234 if (v_last
->valuetype
== V_ERROR
) return 0;
3235 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3237 return t
->get_type_refd_last();
3240 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3242 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3243 return u
.invoke
.v
->get_expr_governor(exp_val
);
3246 const char* Value::get_opname() const
3248 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3249 switch(u
.expr
.v_optype
) {
3250 case OPTYPE_RND
: // -
3252 case OPTYPE_COMP_NULL
:
3253 return "(component) null";
3254 case OPTYPE_COMP_MTC
:
3256 case OPTYPE_COMP_SYSTEM
:
3258 case OPTYPE_COMP_SELF
:
3260 case OPTYPE_COMP_RUNNING_ANY
:
3261 return "any component.running";
3262 case OPTYPE_COMP_RUNNING_ALL
:
3263 return "all component.running";
3264 case OPTYPE_COMP_ALIVE_ANY
:
3265 return "any component.alive";
3266 case OPTYPE_COMP_ALIVE_ALL
:
3267 return "all component.alive";
3268 case OPTYPE_TMR_RUNNING_ANY
:
3269 return "any timer.running";
3270 case OPTYPE_GETVERDICT
:
3271 return "getverdict()";
3272 case OPTYPE_TESTCASENAME
:
3273 return "testcasename()";
3274 case OPTYPE_UNARYPLUS
: // v1
3276 case OPTYPE_UNARYMINUS
:
3282 case OPTYPE_BIT2HEX
:
3284 case OPTYPE_BIT2INT
:
3286 case OPTYPE_BIT2OCT
:
3288 case OPTYPE_BIT2STR
:
3290 case OPTYPE_CHAR2INT
:
3291 return "char2int()";
3292 case OPTYPE_CHAR2OCT
:
3293 return "char2oct()";
3294 case OPTYPE_FLOAT2INT
:
3295 return "float2int()";
3296 case OPTYPE_FLOAT2STR
:
3297 return "float2str()";
3298 case OPTYPE_HEX2BIT
:
3300 case OPTYPE_HEX2INT
:
3302 case OPTYPE_HEX2OCT
:
3304 case OPTYPE_HEX2STR
:
3306 case OPTYPE_INT2CHAR
:
3307 return "int2char()";
3308 case OPTYPE_INT2FLOAT
:
3309 return "int2float()";
3310 case OPTYPE_INT2STR
:
3312 case OPTYPE_INT2UNICHAR
:
3313 return "int2unichar()";
3314 case OPTYPE_OCT2BIT
:
3316 case OPTYPE_OCT2CHAR
:
3317 return "oct2char()";
3318 case OPTYPE_OCT2HEX
:
3320 case OPTYPE_OCT2INT
:
3322 case OPTYPE_OCT2STR
:
3324 case OPTYPE_STR2BIT
:
3326 case OPTYPE_STR2FLOAT
:
3327 return "str2float()";
3328 case OPTYPE_STR2HEX
:
3330 case OPTYPE_STR2INT
:
3332 case OPTYPE_STR2OCT
:
3334 case OPTYPE_UNICHAR2INT
:
3335 return "unichar2int()";
3336 case OPTYPE_UNICHAR2CHAR
:
3337 return "unichar2char()";
3338 case OPTYPE_UNICHAR2OCT
:
3339 return "unichar2oct()";
3340 case OPTYPE_ENUM2INT
:
3341 return "enum2int()";
3342 case OPTYPE_LENGTHOF
:
3343 return "lengthof()";
3346 case OPTYPE_RNDWITHVAL
:
3347 return "rnd (seed)";
3349 return "encvalue()";
3351 return "decvalue()";
3352 case OPTYPE_GET_STRINGENCODING
:
3353 return "get_stringencoding()";
3354 case OPTYPE_REMOVE_BOM
:
3355 return "remove_bom()";
3356 case OPTYPE_ENCODE_BASE64
:
3357 return "encode_base64()";
3358 case OPTYPE_DECODE_BASE64
:
3359 return "decode_base64()";
3360 case OPTYPE_ADD
: // v1 v2
3362 case OPTYPE_SUBTRACT
:
3364 case OPTYPE_MULTIPLY
:
3406 case OPTYPE_INT2BIT
:
3408 case OPTYPE_INT2HEX
:
3410 case OPTYPE_INT2OCT
:
3412 case OPTYPE_OCT2UNICHAR
:
3413 return "oct2unichar()";
3420 case OPTYPE_REPLACE
:
3422 case OPTYPE_VALUEOF
: // t1
3424 case OPTYPE_UNDEF_RUNNING
:
3425 return "<timer or component> running";
3426 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3428 case OPTYPE_COMP_RUNNING
: // v1
3429 return "component running";
3430 case OPTYPE_COMP_ALIVE
: // v1
3432 case OPTYPE_TMR_READ
:
3433 return "timer read";
3434 case OPTYPE_TMR_RUNNING
:
3435 return "timer running";
3436 case OPTYPE_ACTIVATE
:
3437 return "activate()";
3438 case OPTYPE_ACTIVATE_REFD
:
3439 return "activate()";
3440 case OPTYPE_EXECUTE
: // r1 [v2]
3441 case OPTYPE_EXECUTE_REFD
:
3443 case OPTYPE_MATCH
: // v1 t2
3445 case OPTYPE_ISPRESENT
:
3446 return "ispresent()";
3447 case OPTYPE_ISCHOSEN
:
3448 case OPTYPE_ISCHOSEN_V
:
3449 case OPTYPE_ISCHOSEN_T
:
3450 return "ischosen()";
3451 case OPTYPE_ISVALUE
:
3453 case OPTYPE_ISBOUND
:
3455 case OPTYPE_LOG2STR
:
3457 case OPTYPE_TTCN2STRING
:
3458 return "ttcn2string()";
3459 case OPTYPE_PROF_RUNNING
:
3460 return "@profiler.running";
3462 FATAL_ERROR("Value::get_opname()");
3466 void Value::chk_expr_ref_ischosen()
3468 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3469 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3470 Assignment
*ass
=tmpref
->get_refd_assignment();
3472 set_valuetype(V_ERROR
);
3475 // Now we know whether the argument of ischosen() is a value or template.
3476 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3477 // or template (OPTYPE_ISCHOSEN_T).
3478 switch (ass
->get_asstype()) {
3479 case Assignment::A_CONST
:
3480 case Assignment::A_EXT_CONST
:
3481 case Assignment::A_MODULEPAR
:
3482 case Assignment::A_VAR
:
3483 case Assignment::A_PAR_VAL_IN
:
3484 case Assignment::A_PAR_VAL_OUT
:
3485 case Assignment::A_PAR_VAL_INOUT
:
3486 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3487 u
.expr
.v1
->set_location(*tmpref
);
3488 u
.expr
.v1
->set_my_scope(get_my_scope());
3489 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3490 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3492 case Assignment::A_MODULEPAR_TEMP
:
3493 case Assignment::A_TEMPLATE
:
3494 case Assignment::A_VAR_TEMPLATE
:
3495 case Assignment::A_PAR_TEMPL_IN
:
3496 case Assignment::A_PAR_TEMPL_OUT
:
3497 case Assignment::A_PAR_TEMPL_INOUT
:
3498 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3499 u
.expr
.t1
->set_location(*tmpref
);
3500 u
.expr
.t1
->set_my_scope(get_my_scope());
3501 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3502 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3505 tmpref
->error("Reference to a value or template was expected instead of "
3506 "%s", ass
->get_description().c_str());
3507 set_valuetype(V_ERROR
);
3512 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3513 Type::expected_value_t exp_val
)
3515 v
->set_lowerid_to_ref(); // can only be reference to enum
3516 Type
*t
= v
->get_expr_governor(exp_val
);
3517 if (v
->valuetype
==V_ERROR
) return;
3519 v
->error("Please use reference to an enumerated value as the operand of "
3520 "operation `%s'", get_opname());
3521 set_valuetype(V_ERROR
);
3524 t
= t
->get_type_refd_last();
3525 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3526 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3527 set_valuetype(V_ERROR
);
3529 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3530 v
->error("The operand of operation `%s' cannot be omit", opname
);
3531 set_valuetype(V_ERROR
);
3535 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3538 const Location
*loc
)
3540 if(tt
==Type::T_BOOL
) return;
3541 if(tt
!=Type::T_ERROR
)
3542 loc
->error("%s operand of operation `%s' should be boolean value",
3544 set_valuetype(V_ERROR
);
3547 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3550 const Location
*loc
)
3552 if(tt
==Type::T_INT
) return;
3553 if(tt
!=Type::T_ERROR
)
3554 loc
->error("%s operand of operation `%s' should be integer value",
3556 set_valuetype(V_ERROR
);
3559 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3562 const Location
*loc
)
3564 if(tt
==Type::T_REAL
) return;
3565 else if(tt
==Type::T_INT
)
3566 loc
->error("%s operand of operation `%s' should be float value."
3567 " Perhaps you missed an int2float() conversion function"
3568 " or `.0' at the end of the number",
3570 else if(tt
!=Type::T_ERROR
)
3571 loc
->error("%s operand of operation `%s' should be float value",
3573 set_valuetype(V_ERROR
);
3576 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3579 const Location
*loc
)
3588 if(tt
!=Type::T_ERROR
)
3589 loc
->error("%s operand of operation `%s' should be integer"
3592 set_valuetype(V_ERROR
);
3595 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3598 const Location
*loc
)
3603 case Type::T_ENUM_T
:
3608 if(tt
!=Type::T_ERROR
)
3609 loc
->error("%s operand of operation `%s' should be integer, float"
3610 " or enumerated value", opnum
, opname
);
3611 set_valuetype(V_ERROR
);
3614 void Value::chk_expr_operandtype_list(Type
* t
,
3617 const Location
*loc
,
3620 if (valuetype
== V_ERROR
) return;
3621 if (t
->get_typetype() == Type::T_ERROR
) {
3622 set_valuetype(V_ERROR
);
3625 if (!t
->is_list_type(allow_array
)) {
3626 loc
->error("%s operand of operation `%s' should be a string, "
3627 "`record of'%s `set of'%s value", opnum
, opname
,
3628 allow_array
? "," : " or", allow_array
? " or array" : "");
3629 set_valuetype(V_ERROR
);
3632 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3633 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3636 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3637 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3638 if (info
.is_subtype_error()) {
3640 if (info
.needs_conversion()) set_needs_conversion();
3642 if (!info
.is_erroneous()) {
3643 error("%s operand of operation `%s' is of type `%s', but a value of "
3644 "type `%s' was expected here", opnum
, opname
,
3645 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3647 error("%s", info
.get_error_str_str().c_str());
3650 if (info
.needs_conversion())
3651 set_needs_conversion();
3655 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3658 const Location
*loc
)
3670 if(tt
!=Type::T_ERROR
)
3671 loc
->error("%s operand of operation `%s' should be string value",
3673 set_valuetype(V_ERROR
);
3676 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3679 const Location
*loc
)
3688 if(tt
!=Type::T_ERROR
)
3689 loc
->error("%s operand of operation `%s' should be (universal)"
3690 " charstring value",
3692 set_valuetype(V_ERROR
);
3695 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3698 const Location
*loc
)
3700 if(tt
==Type::T_CSTR
) return;
3701 if(tt
!=Type::T_ERROR
)
3702 loc
->error("%s operand of operation `%s' should be charstring value",
3704 set_valuetype(V_ERROR
);
3707 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3710 const Location
*loc
)
3720 if(tt
!=Type::T_ERROR
)
3721 loc
->error("%s operand of operation `%s' should be binary string value",
3723 set_valuetype(V_ERROR
);
3726 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3729 const Location
*loc
)
3731 if(tt
==Type::T_BSTR
) return;
3732 if(tt
!=Type::T_ERROR
)
3733 loc
->error("%s operand of operation `%s' should be bitstring value",
3735 set_valuetype(V_ERROR
);
3738 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3741 const Location
*loc
)
3743 if(tt
==Type::T_HSTR
) return;
3744 if(tt
!=Type::T_ERROR
)
3745 loc
->error("%s operand of operation `%s' should be hexstring value",
3747 set_valuetype(V_ERROR
);
3750 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3753 const Location
*loc
)
3755 if(tt
==Type::T_OSTR
) return;
3756 if(tt
!=Type::T_ERROR
)
3757 loc
->error("%s operand of operation `%s' should be octetstring value",
3759 set_valuetype(V_ERROR
);
3762 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3763 Type::typetype_t tt2
,
3766 if(valuetype
==V_ERROR
) return;
3767 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3768 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3769 set_valuetype(V_ERROR
);
3772 if(tt1
==tt2
) return;
3773 error("The operands of operation `%s' should be of same type", opname
);
3774 set_valuetype(V_ERROR
);
3777 /* For predefined functions. */
3778 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3779 Type::typetype_t tt2
,
3784 if(valuetype
==V_ERROR
) return;
3785 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3786 set_valuetype(V_ERROR
);
3789 if(tt1
==tt2
) return;
3790 error("The %s and %s operands of operation `%s' should be of same type",
3791 opnum1
, opnum2
, opname
);
3792 set_valuetype(V_ERROR
);
3795 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3796 Value
*v1
, Value
*v2
,
3801 if (valuetype
== V_ERROR
) return;
3802 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3803 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3804 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3806 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3807 set_valuetype(V_ERROR
);
3810 if (tt1
== Type::T_UNDEF
) {
3811 if (tt2
== Type::T_UNDEF
) {
3812 if (v1
->is_undef_lowerid()) {
3813 if (v2
->is_undef_lowerid()) {
3814 Scope
*scope
= get_my_scope();
3815 Module
*my_mod
= scope
->get_scope_mod();
3816 const Identifier
& id1
= v1
->get_undef_lowerid();
3817 if (scope
->has_ass_withId(id1
)
3818 || my_mod
->has_imported_ass_withId(id1
)) {
3819 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3820 * should examine this situation better, but now I suppose
3821 * the first is ref, not enum. */
3822 v1
->set_lowerid_to_ref();
3825 const Identifier
& id2
= v2
->get_undef_lowerid();
3826 if (scope
->has_ass_withId(id2
)
3827 || my_mod
->has_imported_ass_withId(id2
)) {
3828 v2
->set_lowerid_to_ref();
3832 /* This is perhaps enum-enum, but it has no real
3833 * significance, so this should be an error. */
3835 v1
->set_lowerid_to_ref();
3838 } else if (v2
->is_undef_lowerid()) {
3839 v2
->set_lowerid_to_ref();
3842 error("Cannot determine the type of the operands in operation `%s'",
3844 set_valuetype(V_ERROR
);
3846 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3847 v1
->set_lowerid_to_ref();
3850 /* v1 is something undefined, but not lowerid; v2 has
3851 * returntype (perhaps also governor) */
3853 } else if (tt2
== Type::T_UNDEF
) {
3854 /* but tt1 is not undef */
3855 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3856 v2
->set_lowerid_to_ref();
3859 /* v2 is something undefined, but not lowerid; v1 has
3860 * returntype (perhaps also governor) */
3864 /* Now undef_lower_id's are converted to references, or the other
3865 * value has governor; let's see the governors, if they exist. */
3866 Type
*t1
= v1
->get_expr_governor(exp_val
);
3867 Type
*t2
= v2
->get_expr_governor(exp_val
);
3870 // Both value has governor. Are they compatible? According to 7.1.2
3871 // and C.34 it's required to have the same root types for
3872 // OPTYPE_{CONCAT,REPLACE}.
3873 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
3874 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3875 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
3876 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3877 TypeChain l_chain1
, l_chain2
;
3878 TypeChain r_chain1
, r_chain2
;
3879 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
3880 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
3881 if (!compat_t1
&& !compat_t2
) {
3882 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
3883 // the subtypes don't need to be compatible here
3884 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
3885 error("The operands of operation `%s' should be of compatible "
3886 "types", get_opname());
3887 set_valuetype(V_ERROR
);
3889 if (info1
.needs_conversion() || info2
.needs_conversion()) {
3890 set_needs_conversion(); // Avoid folding.
3895 if (info1
.is_erroneous())
3896 v1
->error("%s", info1
.get_error_str_str().c_str());
3897 else if (info2
.is_erroneous())
3898 v2
->error("%s", info2
.get_error_str_str().c_str());
3899 set_valuetype(V_ERROR
);
3902 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
3903 set_needs_conversion(); // Avoid folding.
3908 v2
->set_my_governor(t1
);
3909 t1
->chk_this_value_ref(v2
);
3910 if (v2
->valuetype
== V_OMIT
) {
3911 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3913 v1
->chk_expr_omit_comparison(exp_val
);
3915 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3917 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3918 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3923 v1
->set_my_governor(t2
);
3924 t2
->chk_this_value_ref(v1
);
3925 if (v1
->valuetype
== V_OMIT
) {
3926 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3928 v2
->chk_expr_omit_comparison(exp_val
);
3930 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3932 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3933 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3937 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3938 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
3939 // Here, it cannot be that both are T_UNDEF.
3940 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3941 error("Please use reference as %s operand of operator `%s'",
3942 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
3943 set_valuetype(V_ERROR
);
3946 // Deny type compatibility if no governors found. The typetype_t must
3947 // be the same. TODO: How can this happen?
3948 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
3949 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
3950 error("The operands of operation `%s' should be of compatible types",
3952 set_valuetype(V_ERROR
);
3957 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
3958 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
3960 if(valuetype
==V_ERROR
) return;
3961 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3962 Assignment
*t_ass
= ref
->get_refd_assignment();
3963 if(!t_ass
) goto error
;
3964 switch(t_ass
->get_asstype()) {
3965 case Assignment::A_TIMER
:
3966 case Assignment::A_PAR_TIMER
:
3967 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
3968 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
3969 chk_expr_dynamic_part(exp_val
, true);
3971 case Assignment::A_CONST
:
3972 case Assignment::A_EXT_CONST
:
3973 case Assignment::A_MODULEPAR
:
3974 case Assignment::A_VAR
:
3975 case Assignment::A_FUNCTION_RVAL
:
3976 case Assignment::A_EXT_FUNCTION_RVAL
:
3977 case Assignment::A_PAR_VAL_IN
:
3978 case Assignment::A_PAR_VAL_OUT
:
3979 case Assignment::A_PAR_VAL_INOUT
: {
3980 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
3981 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
3982 val
->set_my_scope(my_scope
);
3983 val
->set_fullname(u
.expr
.r1
->get_fullname());
3984 val
->set_location(*u
.expr
.r1
);
3986 chk_expr_operand_compref(val
, opnum
, get_opname());
3987 chk_expr_dynamic_part(exp_val
, false);
3990 ref
->error("%s operand of operation `%s' should be timer or"
3991 " component reference instead of %s",
3992 opnum
, opname
, t_ass
->get_description().c_str());
3997 set_valuetype(V_ERROR
);
4000 Type
*Value::chk_expr_operand_comptyperef_create()
4002 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4003 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4004 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4005 if (!t_ass
) goto error
;
4006 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4007 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4008 Type::EXPECTED_DYNAMIC_VALUE
);
4009 if (!t_type
) goto error
;
4010 t_type
= t_type
->get_type_refd_last();
4011 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4013 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4014 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4015 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4016 u
.expr
.r1
->error("Incompatible component types: operation "
4017 "`create' should refer to `%s' instead of "
4019 my_governor_last
->get_typename().c_str(),
4020 t_type
->get_typename().c_str());
4026 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4027 "expected in operation `create' instead of `%s'",
4028 t_type
->get_typename().c_str());
4031 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4032 "instead of %s", t_ass
->get_description().c_str());
4035 set_valuetype(V_ERROR
);
4039 void Value::chk_expr_comptype_compat()
4041 if (valuetype
!= V_EXPR
)
4042 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4043 if (!my_governor
|| !my_scope
) return;
4044 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4045 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4047 switch (u
.expr
.v_optype
) {
4048 case OPTYPE_COMP_MTC
:
4049 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4051 case OPTYPE_COMP_SYSTEM
:
4052 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4054 case OPTYPE_COMP_SELF
: {
4055 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4056 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4059 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4064 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4065 error("Incompatible component types: a component reference of "
4066 "type `%s' was expected, but `%s' has type `%s'",
4067 my_governor_last
->get_typename().c_str(), get_opname(),
4068 t_comptype
->get_typename().c_str());
4069 set_valuetype(V_ERROR
);
4073 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4076 if(valuetype
== V_ERROR
) return;
4077 switch(val
->get_valuetype()) {
4079 Error_Context
cntxt(this, "In `%s' operation", opname
);
4080 Value
*v_last
= val
->get_value_refd_last();
4081 if(!v_last
) goto error
;
4082 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4084 t
= t
->get_type_refd_last();
4085 if(t
->get_typetype() != Type::T_COMPONENT
) {
4086 v_last
->error("%s operand of operation `%s': Type mismatch:"
4087 " component reference was expected instead of `%s'",
4088 opnum
, opname
, t
->get_typename().c_str());
4093 Reference
*ref
= val
->get_reference();
4094 Assignment
*t_ass
= ref
->get_refd_assignment();
4096 if (!t_ass
) goto error
;
4097 switch(t_ass
->get_asstype()) {
4098 case Assignment::A_CONST
:
4099 t_val
= t_ass
->get_Value();
4101 case Assignment::A_EXT_CONST
:
4102 case Assignment::A_MODULEPAR
:
4103 case Assignment::A_VAR
:
4104 case Assignment::A_FUNCTION_RVAL
:
4105 case Assignment::A_EXT_FUNCTION_RVAL
:
4106 case Assignment::A_PAR_VAL_IN
:
4107 case Assignment::A_PAR_VAL_OUT
:
4108 case Assignment::A_PAR_VAL_INOUT
: {
4109 Type
*t_type
=t_ass
->get_Type()
4110 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4111 if(!t_type
) goto error
;
4112 t_type
=t_type
->get_type_refd_last();
4113 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4114 ref
->error("%s operand of operation `%s': Type mismatch:"
4115 " component reference was expected instead of `%s'",
4116 opnum
, opname
, t_type
->get_typename().c_str());
4121 ref
->error("%s operand of operation `%s' should be"
4122 " component reference instead of %s",
4123 opnum
, opname
, t_ass
->get_description().c_str());
4127 ReferenceChain
refch(this, "While searching referenced value");
4128 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4130 t_val
= t_val
->get_value_refd_last();
4131 if (t_val
->valuetype
!= V_EXPR
) return;
4132 switch (t_val
->u
.expr
.v_optype
) {
4133 case OPTYPE_COMP_NULL
:
4134 ref
->error("%s operand of operation `%s' refers to `null' component "
4135 "reference", opnum
, opname
);
4137 case OPTYPE_COMP_MTC
:
4138 ref
->error("%s operand of operation `%s' refers to the component "
4139 "reference of the `mtc'", opnum
, opname
);
4141 case OPTYPE_COMP_SYSTEM
:
4142 ref
->error("%s operand of operation `%s' refers to the component "
4143 "reference of the `system'", opnum
, opname
);
4151 FATAL_ERROR("Value::chk_expr_operand_compref()");
4154 set_valuetype(V_ERROR
);
4157 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4161 if(valuetype
==V_ERROR
) return;
4162 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4163 Assignment
*t_ass
= ref
->get_refd_assignment();
4164 if(!t_ass
) goto error
;
4165 switch(t_ass
->get_asstype()) {
4166 case Assignment::A_TIMER
: {
4167 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4168 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4169 Type::EXPECTED_DYNAMIC_VALUE
);
4170 else if (ref
->get_subrefs()) {
4171 ref
->error("%s operand of operation `%s': "
4172 "Reference to single timer `%s' cannot have field or array "
4173 "sub-references", opnum
, opname
,
4174 t_ass
->get_id().get_dispname().c_str());
4178 case Assignment::A_PAR_TIMER
:
4179 if (ref
->get_subrefs()) {
4180 ref
->error("%s operand of operation `%s': "
4181 "Reference to %s cannot have field or array sub-references",
4182 opnum
, opname
, t_ass
->get_description().c_str());
4187 ref
->error("%s operand of operation `%s' should be timer"
4189 opnum
, opname
, t_ass
->get_description().c_str());
4194 set_valuetype(V_ERROR
);
4197 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4201 if(valuetype
==V_ERROR
) return;
4202 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4203 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4204 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4205 Error_Context
cntxt(this, "In `%s' operation", opname
);
4206 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4209 void Value::chk_expr_operand_activate_refd(Value
*val
,
4210 Ttcn::TemplateInstances
* t_list2
,
4211 Ttcn::ActualParList
*&parlist
,
4215 if(valuetype
==V_ERROR
) return;
4216 Error_Context
cntxt(this, "In `%s' operation", opname
);
4217 Type
*t
= val
->get_expr_governor_last();
4219 switch (t
->get_typetype()) {
4221 set_valuetype(V_ERROR
);
4223 case Type::T_ALTSTEP
: {
4224 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4225 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4229 set_valuetype(V_ERROR
);
4231 parlist
->set_fullname(get_fullname());
4232 parlist
->set_my_scope(get_my_scope());
4233 if (!fp_list
->chk_activate_argument(parlist
,
4234 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4238 error("Reference to an altstep was expected in the argument of "
4239 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4240 set_valuetype(V_ERROR
);
4243 } else set_valuetype(V_ERROR
);
4246 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4250 if(valuetype
==V_ERROR
) return;
4251 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4252 Error_Context
cntxt(this, "In `%s' operation", opname
);
4253 Assignment
*t_ass
= ref
->get_refd_assignment();
4254 bool error_flag
= false;
4256 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4257 ref
->error("Reference to a testcase was expected in the argument "
4258 "instead of %s", t_ass
->get_description().c_str());
4261 } else error_flag
= true;
4263 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4264 Value
*v_last
= val
->get_value_refd_last();
4265 switch (v_last
->valuetype
) {
4267 ttcn3float v_real
= v_last
->get_val_Real();
4269 val
->error("The testcase guard timer has negative value: `%s'",
4270 Real2string(v_real
).c_str());
4281 if (error_flag
) set_valuetype(V_ERROR
);
4284 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4285 Ttcn::TemplateInstances
* t_list2
,
4286 Ttcn::ActualParList
*&parlist
,
4291 if(valuetype
==V_ERROR
) return;
4292 Error_Context
cntxt(this, "In `%s' operation", opname
);
4293 Type
*t
= v1
->get_expr_governor_last();
4295 switch (t
->get_typetype()) {
4297 set_valuetype(V_ERROR
);
4299 case Type::T_TESTCASE
: {
4300 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4301 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4305 set_valuetype(V_ERROR
);
4307 parlist
->set_fullname(get_fullname());
4308 parlist
->set_my_scope(get_my_scope());
4312 v1
->error("Reference to a value of type testcase was expected in the "
4313 "argument of `derefers()' instead of `%s'",
4314 t
->get_typename().c_str());
4315 set_valuetype(V_ERROR
);
4318 } else set_valuetype(V_ERROR
);
4320 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4321 Value
*v_last
= v3
->get_value_refd_last();
4322 switch (v_last
->valuetype
) {
4324 ttcn3float v_real
= v_last
->get_val_Real();
4326 v3
->error("The testcase guard timer has negative value: `%s'",
4327 Real2string(v_real
).c_str());
4328 set_valuetype(V_ERROR
);
4332 set_valuetype(V_ERROR
);
4340 void Value::chk_invoke(Type::expected_value_t exp_val
)
4342 if(valuetype
== V_ERROR
) return;
4343 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4344 if(!u
.invoke
.t_list
) return; //already checked
4345 Error_Context
cntxt(this, "In `apply()' operation");
4346 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4348 set_valuetype(V_ERROR
);
4351 switch (t
->get_typetype()) {
4353 set_valuetype(V_ERROR
);
4355 case Type::T_FUNCTION
:
4358 u
.invoke
.v
->error("A value of type function was expected in the "
4359 "argument instead of `%s'", t
->get_typename().c_str());
4360 set_valuetype(V_ERROR
);
4363 my_scope
->chk_runs_on_clause(t
, *this, "call");
4364 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4365 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4366 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4367 delete u
.invoke
.t_list
;
4368 u
.invoke
.t_list
= 0;
4371 u
.invoke
.ap_list
= 0;
4373 parlist
->set_fullname(get_fullname());
4374 parlist
->set_my_scope(get_my_scope());
4375 u
.invoke
.ap_list
= parlist
;
4378 case Type::EXPECTED_CONSTANT
:
4379 error("An evaluable constant value was expected instead of operation "
4381 set_valuetype(V_ERROR
);
4383 case Type::EXPECTED_STATIC_VALUE
:
4384 error("A static value was expected instead of operation `apply()'");
4385 set_valuetype(V_ERROR
);
4392 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4393 ReferenceChain
*refch
,
4394 Type::expected_value_t exp_val
)
4396 bool self_ref
= false;
4397 if(valuetype
==V_ERROR
) return;
4398 // Commented out to report more errors :)
4399 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4400 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4401 switch(val
->get_valuetype()) {
4403 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4408 val
->get_value_refd_last(refch
, exp_val
);
4413 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4418 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4419 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4421 bool self_ref
= false;
4423 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4424 ti
->error("Reference to a %s value was expected instead of an in-line "
4425 "modified template",
4426 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4427 set_valuetype(V_ERROR
);
4430 Template
*templ
= ti
->get_Template();
4431 switch (templ
->get_templatetype()) {
4432 case Template::TEMPLATE_REFD
:
4434 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4435 templ
= templ
->get_template_refd_last(refch
);
4436 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4437 set_valuetype(V_ERROR
);
4439 ti
->error("Reference to a %s value was expected instead of %s",
4440 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4441 templ
->get_reference()->get_refd_assignment()
4442 ->get_description().c_str());
4443 set_valuetype(V_ERROR
);
4446 case Template::SPECIFIC_VALUE
: {
4447 Value
*val
= templ
->get_specific_value();
4448 switch (val
->get_valuetype()) {
4450 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4453 val
->get_value_refd_last(refch
, exp_val
);
4457 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4459 case Template::TEMPLATE_ERROR
:
4460 set_valuetype(V_ERROR
);
4469 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4472 if(valuetype
==V_ERROR
) return;
4473 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4474 if(val
->is_unfoldable()) return;
4475 if(*val
->get_val_Int()<0) {
4476 val
->error("%s operand of operation `%s' should not be negative",
4478 set_valuetype(V_ERROR
);
4482 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4485 if(valuetype
==V_ERROR
) return;
4486 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4487 if(val
->is_unfoldable()) return;
4488 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4489 val
->error("%s operand of operation `%s' should be in range 0..127",
4491 set_valuetype(V_ERROR
);
4495 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4498 if(valuetype
==V_ERROR
) return;
4499 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4500 if(val
->is_unfoldable()) return;
4501 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4502 val
->error("%s operand of operation `%s' should be in range"
4503 " 0..2147483647", opnum
, opname
);
4504 set_valuetype(V_ERROR
);
4508 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4511 if(valuetype
==V_ERROR
) return;
4512 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4513 if(val
->is_unfoldable()) return;
4514 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4516 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4518 val
->error("%s operand of operation `%s' should not be zero",
4520 set_valuetype(V_ERROR
);
4524 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4527 if (valuetype
== V_ERROR
) return;
4528 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4529 if (val
->get_expr_returntype() != Type::T_INT
) return;
4530 if (val
->is_unfoldable()) return;
4531 const int_val_t
*val_int
= val
->get_val_Int();
4532 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4533 val
->error("%s operand of operation `%s' should be less than `%d' "
4534 "instead of `%s'", opnum
, opname
, INT_MAX
,
4535 (val_int
->t_str()).c_str());
4536 set_valuetype(V_ERROR
);
4540 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4543 if(valuetype
==V_ERROR
) return;
4544 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4545 if(val
->is_unfoldable()) return;
4546 if(val
->get_val_strlen()!=1) {
4547 val
->error("%s operand of operation `%s' should be of length 1",
4549 set_valuetype(V_ERROR
);
4553 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4556 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4557 Value
*v_last
= val
->get_value_refd_last();
4558 if (v_last
->valuetype
== V_CSTR
) {
4559 size_t len
= v_last
->get_val_strlen();
4561 val
->error("%s operand of operation `%s' should contain even number "
4562 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4563 set_valuetype(V_ERROR
);
4565 } else if (v_last
->valuetype
== V_REFD
) {
4566 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4567 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4568 val
->error("%s operand of operation `%s' should contain even number "
4569 "of characters, but a string element contains 1", opnum
, opname
);
4570 set_valuetype(V_ERROR
);
4575 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4578 if(valuetype
==V_ERROR
) return;
4579 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4580 if(val
->is_unfoldable()) return;
4581 const string
& s
=val
->get_val_str();
4582 for(size_t i
=0; i
<s
.size(); i
++) {
4584 if(!(c
=='0' || c
=='1')) {
4585 val
->error("%s operand of operation `%s' can contain only"
4586 " binary digits (position %lu is `%c')",
4587 opnum
, opname
, (unsigned long) i
, c
);
4588 set_valuetype(V_ERROR
);
4594 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4597 if(valuetype
==V_ERROR
) return;
4598 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4599 if(val
->is_unfoldable()) return;
4600 const string
& s
=val
->get_val_str();
4601 for(size_t i
=0; i
<s
.size(); i
++) {
4603 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4604 val
->error("%s operand of operation `%s' can contain only valid "
4605 "hexadecimal digits (position %lu is `%c')",
4606 opnum
, opname
, (unsigned long) i
, c
);
4607 set_valuetype(V_ERROR
);
4613 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4616 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4617 Value
*v
= val
->get_value_refd_last();
4618 if (v
->valuetype
!= V_OSTR
) return;
4619 const string
& s
= val
->get_val_str();
4620 size_t n_octets
= s
.size() / 2;
4621 for (size_t i
= 0; i
< n_octets
; i
++) {
4623 if (!(c
>= '0' && c
<= '7')) {
4624 val
->error("%s operand of operation `%s' shall consist of octets "
4625 "within the range 00 .. 7F, but the string `%s'O contains octet "
4626 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4628 set_valuetype(V_ERROR
);
4634 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4637 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4638 Value
*v_last
= val
->get_value_refd_last();
4639 if (v_last
->valuetype
!= V_CSTR
) return;
4640 const string
& s
= v_last
->get_val_str();
4641 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4643 // state: expected characters
4644 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4645 // S_FIRST: first digit
4646 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4647 // S_END: trailing whitespace
4648 // S_ERR: error was found, stop
4649 for (size_t i
= 0; i
< s
.size(); i
++) {
4654 if (c
== '+' || c
== '-') state
= S_FIRST
;
4655 else if (c
== '0') state
= S_ZERO
;
4656 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4657 else if (string::is_whitespace(c
)) {
4658 if (state
== S_INITIAL
) {
4659 val
->warning("Leading whitespace was detected and ignored in the "
4660 "operand of operation `%s'", opname
);
4661 state
= S_INITIAL_WS
;
4663 } else state
= S_ERR
;
4666 if (c
== '0') state
= S_ZERO
;
4667 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4671 if (c
>= '0' && c
<= '9') {
4672 val
->warning("Leading zero digit was detected and ignored in the "
4673 "operand of operation `%s'", opname
);
4675 } else if (string::is_whitespace(c
)) state
= S_END
;
4679 if (c
>= '0' && c
<= '9') {}
4680 else if (string::is_whitespace(c
)) state
= S_END
;
4684 if (!string::is_whitespace(c
)) state
= S_ERR
;
4689 if (state
== S_ERR
) {
4690 if (string::is_printable(c
)) {
4691 val
->error("%s operand of operation `%s' should be a string "
4692 "containing a valid integer value, but invalid character `%c' "
4693 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4695 val
->error("%s operand of operation `%s' should be a string "
4696 "containing a valid integer value, but invalid character with "
4697 "character code %u was detected at index %lu", opnum
, opname
, c
,
4700 set_valuetype(V_ERROR
);
4707 val
->error("%s operand of operation `%s' should be a string containing a "
4708 "valid integer value instead of an empty string", opnum
, opname
);
4709 set_valuetype(V_ERROR
);
4712 val
->error("%s operand of operation `%s' should be a string containing a "
4713 "valid integer value, but only a sign character was detected", opnum
,
4715 set_valuetype(V_ERROR
);
4718 val
->warning("Trailing whitespace was detected and ignored in the "
4719 "operand of operation `%s'", opname
);
4726 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4729 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4730 Value
*v_last
= val
->get_value_refd_last();
4731 if (v_last
->valuetype
== V_REFD
) {
4732 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4733 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4734 val
->error("%s operand of operation `%s' should be a string containing "
4735 "a valid float value instead of a string element, which cannot "
4736 "represent a floating point number", opnum
, opname
);
4737 set_valuetype(V_ERROR
);
4740 } else if (v_last
->valuetype
!= V_CSTR
) return;
4741 const string
& s
= v_last
->get_val_str();
4742 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4743 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4745 // state: expected characters
4746 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4747 // leading whitespace
4748 // S_FIRST_M: first digit of integer part in mantissa
4749 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4750 // S_FIRST_F: first digit of fraction
4751 // S_MORE_F: more digits of fraction, E, trailing whitespace
4752 // S_INITIAL_E: +, -, first digit of exponent
4753 // S_FIRST_E: first digit of exponent
4754 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4755 // S_END: trailing whitespace
4756 // S_ERR: error was found, stop
4757 for (size_t i
= 0; i
< s
.size(); i
++) {
4762 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4763 else if (c
== '0') state
= S_ZERO_M
;
4764 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4765 else if (string::is_whitespace(c
)) {
4766 if (state
== S_INITIAL
) {
4767 val
->warning("Leading whitespace was detected and ignored in the "
4768 "operand of operation `%s'", opname
);
4769 state
= S_INITIAL_WS
;
4771 } else state
= S_ERR
;
4774 if (c
== '0') state
= S_ZERO_M
;
4775 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4779 if (c
== '.') state
= S_FIRST_F
;
4780 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4781 else if (c
>= '0' && c
<= '9') {
4782 val
->warning("Leading zero digit was detected and ignored in the "
4783 "mantissa of the operand of operation `%s'", opname
);
4785 } else state
= S_ERR
;
4788 if (c
== '.') state
= S_FIRST_F
;
4789 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4790 else if (c
>= '0' && c
<= '9') {}
4794 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4798 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4799 else if (c
>= '0' && c
<= '9') {}
4800 else if (string::is_whitespace(c
)) state
= S_END
;
4804 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4805 else if (c
== '0') state
= S_ZERO_E
;
4806 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4810 if (c
== '0') state
= S_ZERO_E
;
4811 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4815 if (c
>= '0' && c
<= '9') {
4816 val
->warning("Leading zero digit was detected and ignored in the "
4817 "exponent of the operand of operation `%s'", opname
);
4819 } else if (string::is_whitespace(c
)) state
= S_END
;
4823 if (c
>= '0' && c
<= '9') {}
4824 else if (string::is_whitespace(c
)) state
= S_END
;
4828 if (!string::is_whitespace(c
)) state
= S_ERR
;
4833 if (state
== S_ERR
) {
4834 if (string::is_printable(c
)) {
4835 val
->error("%s operand of operation `%s' should be a string "
4836 "containing a valid float value, but invalid character `%c' "
4837 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4839 val
->error("%s operand of operation `%s' should be a string "
4840 "containing a valid float value, but invalid character with "
4841 "character code %u was detected at index %lu", opnum
, opname
, c
,
4844 set_valuetype(V_ERROR
);
4851 val
->error("%s operand of operation `%s' should be a string containing a "
4852 "valid float value instead of an empty string", opnum
, opname
);
4853 set_valuetype(V_ERROR
);
4856 val
->error("%s operand of operation `%s' should be a string containing a "
4857 "valid float value, but only a sign character was detected", opnum
,
4859 set_valuetype(V_ERROR
);
4863 // HL67862: Missing decimal dot allowed for str2float
4866 // HL67862: Missing fraction part is allowed for str2float
4870 val
->error("%s operand of operation `%s' should be a string containing a "
4871 "valid float value, but the exponent is missing after the `E' sign",
4873 set_valuetype(V_ERROR
);
4876 val
->warning("Trailing whitespace was detected and ignored in the "
4877 "operand of operation `%s'", opname
);
4884 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
4887 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4888 Value
*v
= val
->get_value_refd_last();
4889 if (v
->valuetype
!= V_USTR
) return;
4890 const ustring
& us
= v
->get_val_ustr();
4891 for (size_t i
= 0; i
< us
.size(); i
++) {
4892 const ustring::universal_char
& uchar
= us
[i
];
4893 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
4895 val
->error("%s operand of operation `%s' shall consist of characters "
4896 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4897 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4898 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
4899 uchar
.row
, uchar
.cell
, (unsigned long) i
);
4900 set_valuetype(V_ERROR
);
4906 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
4909 if(valuetype
==V_ERROR
) return;
4910 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4911 if(val
->is_unfoldable()) return;
4912 const string
& bstr
=val
->get_val_str();
4913 // see also PredefFunc.cc::bit2int()
4914 size_t nof_bits
= bstr
.size();
4915 // skip the leading zeros
4916 size_t start_index
= 0;
4917 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
4918 // check whether the remaining bits fit in Int
4919 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
4920 val
->error("%s operand of operation `%s' is too large (maximum number"
4921 " of bits in integer is %lu)",
4922 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4923 set_valuetype(V_ERROR
);
4927 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
4930 if(valuetype
==V_ERROR
) return;
4931 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4932 if(val
->is_unfoldable()) return;
4933 const string
& hstr
=val
->get_val_str();
4934 // see also PredefFunc.cc::hex2int()
4935 size_t nof_digits
= hstr
.size();
4936 // skip the leading zeros
4937 size_t start_index
= 0;
4938 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
4939 // check whether the remaining hex digits fit in Int
4940 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
4941 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
4942 char_to_hexdigit(hstr
[start_index
]) > 7)) {
4943 val
->error("%s operand of operation `%s' is too large (maximum number"
4944 " of bits in integer is %lu)",
4945 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4946 set_valuetype(V_ERROR
);
4950 void Value::chk_expr_operands_int2binstr()
4952 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4953 if (u
.expr
.v1
->is_unfoldable()) return;
4954 if (u
.expr
.v2
->is_unfoldable()) return;
4955 // It is already checked that i1 and i2 are non-negative.
4956 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4957 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
4958 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
4959 if (!i2
->is_native()) {
4960 u
.expr
.v2
->error("The length of the resulting string is too large for "
4961 "being represented in memory");
4962 set_valuetype(V_ERROR
);
4965 Int nof_bits
= i2
->get_val();
4966 if (u
.expr
.v1
->is_unfoldable()) return;
4967 switch (u
.expr
.v_optype
) {
4968 case OPTYPE_INT2BIT
:
4970 case OPTYPE_INT2HEX
:
4973 case OPTYPE_INT2OCT
:
4977 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4979 if (*i1
>> nof_bits
> 0) { // Expensive?
4980 u
.expr
.v1
->error("Value %s does not fit in length %s",
4981 i1
->t_str().c_str(), i2
->t_str().c_str());
4982 set_valuetype(V_ERROR
);
4986 void Value::chk_expr_operands_str_samelen()
4988 if(valuetype
==V_ERROR
) return;
4989 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4990 Value
*v1
=u
.expr
.v1
;
4991 if(v1
->is_unfoldable()) return;
4992 Value
*v2
=u
.expr
.v2
;
4993 if(v2
->is_unfoldable()) return;
4994 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4995 size_t i1
=v1
->get_val_strlen();
4996 size_t i2
=v2
->get_val_strlen();
4998 error("The operands should have the same length");
4999 set_valuetype(V_ERROR
);
5003 void Value::chk_expr_operands_replace()
5005 // The fourth operand doesn't need to be checked at all here.
5006 if(valuetype
==V_ERROR
) return;
5007 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5008 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5011 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5012 size_t list_len
= 0;
5013 bool list_len_known
= false;
5014 if (v1
->valuetype
== V_REFD
) {
5015 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5016 if (subrefs
&& subrefs
->refers_to_string_element()) {
5017 warning("Replacing a string element does not make any sense");
5019 list_len_known
= true;
5022 if (!v1
->is_unfoldable()) {
5023 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5024 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5025 list_len_known
= true;
5027 if (!list_len_known
) return;
5028 if (u
.expr
.v2
->is_unfoldable()) {
5029 if (!u
.expr
.v3
->is_unfoldable()) {
5030 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5031 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5032 error("Third operand `len' (%s) is greater than the length of "
5033 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5034 (unsigned long)list_len
);
5035 set_valuetype(V_ERROR
);
5039 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5040 if (u
.expr
.v3
->is_unfoldable()) {
5041 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5042 error("Second operand `index' (%s) is greater than the length of "
5043 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5044 (unsigned long)list_len
);
5045 set_valuetype(V_ERROR
);
5048 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5049 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5050 error("The sum of second operand `index' (%s) and third operand "
5051 "`len' (%s) is greater than the length of the first operand (%lu)",
5052 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5053 (unsigned long)list_len
);
5054 set_valuetype(V_ERROR
);
5060 void Value::chk_expr_operands_substr()
5062 if(valuetype
==V_ERROR
) return;
5063 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5064 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5067 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5068 size_t list_len
= 0;
5069 bool list_len_known
= false;
5070 if (v1
->valuetype
== V_REFD
) {
5071 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5072 if (subrefs
&& subrefs
->refers_to_string_element()) {
5073 warning("Taking the substring of a string element does not make any "
5076 list_len_known
= true;
5079 if (!list_len_known
&& !v1
->is_unfoldable()) {
5080 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5081 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5082 list_len_known
= true;
5084 // Do nothing if the length of the first operand is unknown.
5085 if (!list_len_known
) return;
5086 if (u
.expr
.v2
->is_unfoldable()) {
5087 if (!u
.expr
.v3
->is_unfoldable()) {
5088 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5089 // Only the third operand is known.
5090 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5091 error("Third operand `returncount' (%s) is greater than the "
5092 "length of the first operand (%lu)",
5093 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5094 set_valuetype(V_ERROR
);
5098 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5099 if (u
.expr
.v3
->is_unfoldable()) {
5100 // Only the second operand is known.
5101 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5102 error("Second operand `index' (%s) is greater than the length "
5103 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5104 (unsigned long)list_len
);
5105 set_valuetype(V_ERROR
);
5108 // Both second and third operands are known.
5109 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5110 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5111 error("The sum of second operand `index' (%s) and third operand "
5112 "`returncount' (%s) is greater than the length of the first operand "
5113 "(%lu)", (index_int_2
->t_str()).c_str(),
5114 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5115 set_valuetype(V_ERROR
);
5121 void Value::chk_expr_operands_regexp()
5123 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5124 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5125 Value
* v2
= u
.expr
.t2
->get_specific_value();
5126 if (!v1
|| !v2
) return;
5128 Error_Context
cntxt(this, "In operation `regexp()'");
5129 Value
* v1_last
= v1
->get_value_refd_last();
5130 if (v1_last
->valuetype
== V_CSTR
) {
5131 // the input string is available at compile time
5132 const string
& instr
= v1_last
->get_val_str();
5133 const char *input_str
= instr
.c_str();
5134 size_t instr_len
= strlen(input_str
);
5135 if (instr_len
< instr
.size()) {
5136 v1
->warning("The first operand of `regexp()' contains a "
5137 "character with character code zero at index %s. The rest of the "
5138 "string will be ignored during matching",
5139 Int2string(instr_len
).c_str());
5143 size_t nof_groups
= 0;
5144 Value
*v2_last
= v2
->get_value_refd_last();
5146 if (v2_last
->valuetype
== V_CSTR
) {
5147 // the pattern is available at compile time
5148 const string
& expression
= v2_last
->get_val_str();
5149 const char *pattern_str
= expression
.c_str();
5150 size_t pattern_len
= strlen(pattern_str
);
5151 if (pattern_len
< expression
.size()) {
5152 v2
->warning("The second operand of `regexp()' contains a "
5153 "character with character code zero at index %s. The rest of the "
5154 "string will be ignored during matching",
5155 Int2string(pattern_len
).c_str());
5159 Error_Context
cntxt2(v2
, "In character string pattern");
5160 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5162 if (posix_str
!= NULL
) {
5163 regex_t posix_regexp
;
5164 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5167 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5168 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5169 "regcomp() failed: %s", msg
);
5171 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5173 v2
->error("The character pattern in the second operand of "
5174 "`regexp()' does not contain any groups");
5175 set_valuetype(V_ERROR
);
5177 regfree(&posix_regexp
);
5180 // the pattern is faulty
5181 // the error has been reported by TTCN_pattern_to_regexp
5182 set_valuetype(V_ERROR
);
5185 if (nof_groups
> 0) {
5186 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5187 if (v3
->valuetype
== V_INT
) {
5188 // the group number is available at compile time
5189 const int_val_t
*groupno_int
= v3
->get_val_Int();
5190 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5191 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5192 "large: The requested group index is %s, but the pattern "
5193 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5194 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5195 set_valuetype(V_ERROR
);
5201 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5202 Type::expected_value_t exp_val
)
5204 const char *opname
= get_opname();
5205 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5207 const Location
*loc
;
5208 bool error_flag
= false;
5209 switch (u
.expr
.v_optype
) {
5210 case OPTYPE_ISCHOSEN_V
:
5211 // u.expr.v1 is always a referenced value
5212 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5214 u
.expr
.v1
->set_my_governor(t_governor
);
5215 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5216 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5217 } else error_flag
= true;
5220 case OPTYPE_ISCHOSEN_T
:
5221 // u.expr.t1 is always a referenced template
5222 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5223 exp_val
= Type::EXPECTED_TEMPLATE
;
5224 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5226 u
.expr
.t1
->set_my_governor(t_governor
);
5228 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5230 u
.expr
.t1
->get_template_refd_last(refch
);
5231 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5233 } else error_flag
= true;
5234 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5235 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5236 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5237 u
.expr
.t1
->get_reference()->get_refd_assignment()
5238 ->get_description().c_str());
5244 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5249 t_governor
= t_governor
->get_type_refd_last();
5250 switch (t_governor
->get_typetype()) {
5254 case Type::T_CHOICE_A
:
5255 case Type::T_CHOICE_T
:
5256 case Type::T_ANYTYPE
:
5257 case Type::T_OPENTYPE
:
5258 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5259 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5260 "%s does not have a field named `%s'" :
5261 "Union type `%s' does not have a field named `%s'",
5262 t_governor
->get_typename().c_str(),
5263 u
.expr
.i2
->get_dispname().c_str());
5268 loc
->error("The operand of operation `%s' should be a union value "
5269 "or template instead of `%s'", opname
,
5270 t_governor
->get_typename().c_str());
5275 if (error_flag
) set_valuetype(V_ERROR
);
5278 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5279 Type::expected_value_t exp_val
) {
5281 Error_Context
cntxt(this, "In the parameter of encvalue()");
5282 Type
t_chk(Type::T_ERROR
);
5285 Type::expected_value_t ti_exp_val
= exp_val
;
5286 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5287 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5289 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5291 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5292 if (valuetype
!=V_ERROR
)
5293 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5294 t_type
= t_type
->get_type_refd_last();
5296 error("Cannot determine type of value");
5301 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5302 error("Expecting a value of a type with coding attributes in first"
5303 "parameter of encvalue() which belongs to a generic type '%s'",
5304 t_type->get_typename().c_str());
5308 if(!disable_attribute_validation()) {
5309 t_type
->chk_coding(true);
5312 switch (t_type
->get_typetype()) {
5317 case Type::T_REFDSPEC
:
5318 case Type::T_SELTYPE
:
5319 case Type::T_VERDICT
:
5321 case Type::T_COMPONENT
:
5322 case Type::T_DEFAULT
:
5323 case Type::T_SIGNATURE
:
5324 case Type::T_FUNCTION
:
5325 case Type::T_ALTSTEP
:
5326 case Type::T_TESTCASE
:
5327 error("Type of parameter of encvalue() cannot be '%s'",
5328 t_type
->get_typename().c_str());
5335 set_valuetype(V_ERROR
);
5338 void Value::chk_expr_operands_decode()
5340 Error_Context
cntxt(this, "In the parameters of decvalue()");
5341 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5342 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5344 Assignment
* t_ass
= ref
->get_refd_assignment();
5347 error("Could not determine the assignment for first parameter");
5350 switch (t_ass
->get_asstype()) {
5351 case Assignment::A_PAR_VAL_IN
:
5352 t_ass
->use_as_lvalue(*this);
5354 case Assignment::A_CONST
:
5355 case Assignment::A_EXT_CONST
:
5356 case Assignment::A_MODULEPAR
:
5357 case Assignment::A_MODULEPAR_TEMP
:
5358 case Assignment::A_TEMPLATE
:
5359 ref
->error("Reference to '%s' cannot be used as the first operand of "
5360 "the 'decvalue' operation", t_ass
->get_assname());
5363 case Assignment::A_VAR
:
5364 case Assignment::A_PAR_VAL_OUT
:
5365 case Assignment::A_PAR_VAL_INOUT
:
5367 case Assignment::A_VAR_TEMPLATE
:
5368 case Assignment::A_PAR_TEMPL_IN
:
5369 case Assignment::A_PAR_TEMPL_OUT
:
5370 case Assignment::A_PAR_TEMPL_INOUT
: {
5371 Template
* t
= new Template(ref
->clone());
5372 t
->set_location(*ref
);
5373 t
->set_my_scope(get_my_scope());
5374 t
->set_fullname(get_fullname()+".<operand>");
5375 Template
* t_last
= t
->get_template_refd_last();
5376 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5378 ref
->error("Specific value template was expected instead of '%s'.",
5379 t
->get_template_refd_last()->get_templatetype_str());
5386 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5389 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5390 Type::EXPECTED_DYNAMIC_VALUE
);
5394 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5395 error("First parameter has to be a bitstring");
5400 t_subrefs
= ref
->get_subrefs();
5401 t_ass
= ref
->get_refd_assignment();
5404 error("Could not determine the assignment for second parameter");
5407 // Extra check for HM59355.
5408 switch (t_ass
->get_asstype()) {
5409 case Assignment::A_VAR
:
5410 case Assignment::A_PAR_VAL_IN
:
5411 case Assignment::A_PAR_VAL_OUT
:
5412 case Assignment::A_PAR_VAL_INOUT
:
5415 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5418 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5419 Type::EXPECTED_DYNAMIC_VALUE
);
5423 t_type
= t_type
->get_type_refd_last();
5424 switch (t_type
->get_typetype()) {
5429 case Type::T_REFDSPEC
:
5430 case Type::T_SELTYPE
:
5431 case Type::T_VERDICT
:
5433 case Type::T_COMPONENT
:
5434 case Type::T_DEFAULT
:
5435 case Type::T_SIGNATURE
:
5436 case Type::T_FUNCTION
:
5437 case Type::T_ALTSTEP
:
5438 case Type::T_TESTCASE
:
5439 error("Type of second parameter cannot be %s",
5440 t_type
->get_typename().c_str());
5446 if(!disable_attribute_validation()) {
5447 t_type
->chk_coding(false);
5452 set_valuetype(V_ERROR
);
5455 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5457 Ttcn::FieldOrArrayRefs
*subrefs
;
5458 Identifier
*field_id
= 0;
5461 if (valuetype
== V_ERROR
) return;
5462 else if (valuetype
!= V_REFD
) {
5463 error("Only a referenced value can be compared with `omit'");
5466 subrefs
= u
.ref
.ref
->get_subrefs();
5467 if (subrefs
) field_id
= subrefs
->remove_last_field();
5469 error("Only a reference pointing to an optional record or set field "
5470 "can be compared with `omit'");
5473 t_ass
= u
.ref
.ref
->get_refd_assignment();
5474 if (!t_ass
) goto error
;
5475 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5476 if (!t_type
) goto error
;
5477 t_type
= t_type
->get_type_refd_last();
5478 switch (t_type
->get_typetype()) {
5487 error("Only a reference pointing to an optional field of a record"
5488 " or set type can be compared with `omit'");
5491 if (!t_type
->has_comp_withName(*field_id
)) {
5492 error("Type `%s' does not have field named `%s'",
5493 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5495 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5496 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5497 "`omit'", field_id
->get_dispname().c_str(),
5498 t_type
->get_typename().c_str());
5501 // putting the last field_id back to subrefs
5502 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5505 set_valuetype(V_ERROR
);
5509 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5510 Type::expected_value_t exp_val
)
5512 if(valuetype
==V_ERROR
) return -1;
5513 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5514 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5515 exp_val
=Type::EXPECTED_TEMPLATE
;
5517 Error_Context
cntxt(this, "In the operand of"
5518 " operation `%s'", get_opname());
5521 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5524 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5527 t_templ
= t_templ
->get_template_refd_last(refch
);
5529 // Timer and port arrays are handled separately
5530 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5531 Value
* val
= t_templ
->get_specific_value();
5532 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5533 val
->set_lowerid_to_ref();
5535 if (val
&& val
->get_valuetype() == V_REFD
) {
5536 Reference
* ref
= val
->get_reference();
5537 Assignment
* t_ass
= ref
->get_refd_assignment();
5538 Common::Assignment::asstype_t asstype
=
5539 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5540 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5541 if (t_ass
->get_Dimensions()) {
5542 // here we have a timer or port array
5543 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5544 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5545 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5546 Type::EXPECTED_DYNAMIC_VALUE
);
5549 refd_dim
= t_subrefs
->get_nof_refs();
5550 size_t nof_dims
= t_dims
->get_nof_dims();
5551 if (refd_dim
>= nof_dims
) {
5552 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5553 t_ass
->get_assname());
5554 set_valuetype(V_ERROR
);
5557 } else refd_dim
= 0;
5558 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5560 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5561 t_ass
->get_description().c_str());
5562 set_valuetype(V_ERROR
);
5571 Assignment
* t_ass
= 0;
5573 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5574 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5576 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5577 t_type
= t_type
->get_type_refd_last();
5579 error("Cannot determine type of value");
5583 if(valuetype
==V_ERROR
) return -1;
5585 t_templ
= t_templ
->get_template_refd_last(refch
);
5586 switch(t_templ
->get_templatetype()) {
5587 case Template::TEMPLATE_ERROR
:
5589 case Template::INDEXED_TEMPLATE_LIST
:
5591 case Template::TEMPLATE_REFD
:
5592 case Template::TEMPLATE_LIST
:
5593 case Template::NAMED_TEMPLATE_LIST
:
5596 case Template::SPECIFIC_VALUE
:
5598 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5600 switch(t_val
->get_valuetype()) {
5610 ref
= t_val
->get_reference();
5611 t_ass
= ref
->get_refd_assignment();
5612 t_subrefs
= ref
->get_subrefs();
5616 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5617 t_val
->create_stringRepr().c_str());
5624 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5625 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5630 switch(t_ass
->get_asstype()) {
5631 case Assignment::A_ERROR
:
5633 case Assignment::A_CONST
:
5634 t_val
= t_ass
->get_Value();
5636 case Assignment::A_EXT_CONST
:
5637 case Assignment::A_MODULEPAR
:
5638 case Assignment::A_MODULEPAR_TEMP
:
5639 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5640 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5641 "expected instead of %s", t_ass
->get_description().c_str());
5645 case Assignment::A_VAR
:
5646 case Assignment::A_PAR_VAL_IN
:
5647 case Assignment::A_PAR_VAL_OUT
:
5648 case Assignment::A_PAR_VAL_INOUT
:
5650 case Type::EXPECTED_CONSTANT
:
5651 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5652 t_ass
->get_description().c_str());
5655 case Type::EXPECTED_STATIC_VALUE
:
5656 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5657 t_ass
->get_description().c_str());
5664 case Assignment::A_TEMPLATE
:
5665 t_templ
= t_ass
->get_Template();
5667 case Assignment::A_VAR_TEMPLATE
:
5668 case Assignment::A_PAR_TEMPL_IN
:
5669 case Assignment::A_PAR_TEMPL_OUT
:
5670 case Assignment::A_PAR_TEMPL_INOUT
:
5671 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5672 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5673 t_ass
->get_description().c_str());
5676 case Assignment::A_FUNCTION_RVAL
:
5677 case Assignment::A_EXT_FUNCTION_RVAL
:
5679 case Type::EXPECTED_CONSTANT
:
5680 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5681 "the return value of %s", t_ass
->get_description().c_str());
5684 case Type::EXPECTED_STATIC_VALUE
:
5685 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5686 "the return value of %s", t_ass
->get_description().c_str());
5693 case Assignment::A_FUNCTION_RTEMP
:
5694 case Assignment::A_EXT_FUNCTION_RTEMP
:
5695 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5696 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5697 " of %s, which returns a template",
5698 t_ass
->get_description().c_str());
5701 case Assignment::A_TIMER
:
5702 case Assignment::A_PORT
:
5703 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5704 // sizeof is applicable to timer and port arrays
5705 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5707 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5708 t_ass
->get_description().c_str());
5711 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5712 Type::EXPECTED_DYNAMIC_VALUE
);
5715 refd_dim
= t_subrefs
->get_nof_refs();
5716 size_t nof_dims
= t_dims
->get_nof_dims();
5717 if (refd_dim
> nof_dims
) goto error
;
5718 else if (refd_dim
== nof_dims
) {
5719 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5720 t_ass
->get_assname());
5723 } else refd_dim
= 0;
5724 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5728 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5729 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5730 t_ass
->get_description().c_str());
5734 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5735 if (!t_type
) goto error
;
5736 t_type
= t_type
->get_type_refd_last();
5738 switch(t_type
->get_typetype()) {
5755 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5756 " set, set of, objid or array was expected");
5761 // check for index overflows in subrefs if possible
5763 switch (t_val
->get_valuetype()) {
5767 if (t_val
->is_indexed()) {
5774 /* The reference points to a constant. */
5775 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5776 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5777 if (!t_val
) goto error
;
5778 t_val
=t_val
->get_value_refd_last(refch
);
5779 } else { t_val
= 0; }
5780 } else if (t_templ
) {
5781 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5782 time. Don't try to evaluate it at compile time. */
5783 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5785 /* The reference points to a static template. */
5786 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5787 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5788 if (!t_templ
) goto error
;
5789 t_templ
= t_templ
->get_template_refd_last(refch
);
5790 } else { t_templ
= 0; }
5793 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5795 switch(t_templ
->get_templatetype()) {
5796 case Template::TEMPLATE_ERROR
:
5798 case Template::TEMPLATE_REFD
:
5802 case Template::SPECIFIC_VALUE
:
5803 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5806 case Template::TEMPLATE_LIST
:
5807 case Template::NAMED_TEMPLATE_LIST
:
5810 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5811 t_templ
->get_templatetype_str(),
5812 t_templ
->get_fullname().c_str());
5817 switch(t_val
->get_valuetype()) {
5828 // error is already reported
5837 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5838 result
= t_type
->get_dimension()->get_size();
5840 else if(t_templ
) { // sizeof()
5841 switch(t_templ
->get_templatetype()) {
5842 case Template::TEMPLATE_LIST
:
5843 if(t_templ
->temps_contains_anyornone_symbol()) {
5844 if(t_templ
->is_length_restricted()) {
5845 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5846 if (lr
->get_is_range()) {
5847 Value
*v_upper
= lr
->get_upper_value();
5849 if (v_upper
->valuetype
== V_INT
) {
5851 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
5852 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
5855 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5856 "templates without exact size");
5861 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5862 "templates containing `*' without upper boundary in the "
5863 "length restriction");
5867 Value
*v_single
= lr
->get_single_value();
5868 if (v_single
->valuetype
== V_INT
)
5869 result
= v_single
->u
.val_Int
->get_val();
5872 else { // not length restricted
5873 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
5874 " containing `*' without length restriction");
5878 else result
=t_templ
->get_nof_listitems();
5880 case Template::NAMED_TEMPLATE_LIST
:
5882 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
5883 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
5884 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
5887 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5891 switch(t_val
->get_valuetype()) {
5898 result
=t_val
->get_nof_comps();
5903 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
5904 if(t_val
->get_se_comp_byIndex(i
)->get_value()
5905 ->get_valuetype()!=V_OMIT
) result
++;
5909 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5915 set_valuetype(V_ERROR
);
5919 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
5921 Type
*governor
= ti
->get_expr_governor(exp_val
);
5923 ti
->get_Template()->set_lowerid_to_ref();
5924 governor
= ti
->get_expr_governor(exp_val
);
5928 ti
->append_stringRepr( str
);
5929 ti
->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5930 "If type is known, use valuof(<type>: %s) as argument.",
5931 str
.c_str(), get_opname(), str
.c_str());
5932 set_valuetype(V_ERROR
);
5937 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
5940 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5941 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
5942 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
5943 Type::EXPECTED_TEMPLATE
: exp_val
);
5945 Template
*t_temp
= u
.expr
.t2
->get_Template();
5946 if (t_temp
->is_undef_lowerid()) {
5947 // We convert the template to reference first even if the value is also
5948 // an undef lowerid. The user can prevent this by explicit type
5950 t_temp
->set_lowerid_to_ref();
5952 } else if (u
.expr
.v1
->is_undef_lowerid()) {
5953 u
.expr
.v1
->set_lowerid_to_ref();
5958 error("Cannot determine the type of arguments in `match()' operation");
5959 set_valuetype(V_ERROR
);
5962 u
.expr
.v1
->set_my_governor(governor
);
5964 Error_Context
cntxt(this, "In the first argument of `match()'"
5966 governor
->chk_this_value_ref(u
.expr
.v1
);
5967 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
5968 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
5971 Error_Context
cntxt(this, "In the second argument of `match()' "
5973 u
.expr
.t2
->chk(governor
);
5977 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
5978 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
5980 Ttcn::StatementBlock
*my_sb
;
5982 case Type::EXPECTED_CONSTANT
:
5983 error("An evaluable constant value was expected instead of operation "
5984 "`%s'", get_opname());
5986 case Type::EXPECTED_STATIC_VALUE
:
5987 error("A static value was expected instead of operation `%s'",
5993 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5994 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
5996 error("Operation `%s' is allowed only within statements",
6000 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6001 error("Operation `%s' is not allowed in the control part",
6005 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6006 error("Operation `%s' cannot be used in a definition that has "
6007 "`runs on' clause", get_opname());
6010 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6011 error("Operation `%s' can be used only in a definition that has "
6012 "`runs on' clause", get_opname());
6017 set_valuetype(V_ERROR
);
6020 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6022 if(valuetype
==V_ERROR
) return;
6023 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6024 if(v
->is_unfoldable()) return;
6025 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6026 ttcn3float r
= v
->get_val_Real();
6027 if (isSpecialFloatValue(r
)) {
6028 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6029 opnum
, opname
, Real2string(r
).c_str());
6030 set_valuetype(V_ERROR
);
6034 void Value::chk_expr_operands(ReferenceChain
*refch
,
6035 Type::expected_value_t exp_val
)
6037 const char *first
="First", *second
="Second", *third
="Third",
6038 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6039 Value
*v1
, *v2
, *v3
;
6040 Type::typetype_t tt1
, tt2
, tt3
;
6041 Type
t_chk(Type::T_ERROR
);
6043 const char *opname
=get_opname();
6045 // first classify the unchecked ischosen() operation
6046 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6048 switch (u
.expr
.v_optype
) {
6049 case OPTYPE_COMP_NULL
:
6050 case OPTYPE_TESTCASENAME
:
6051 case OPTYPE_PROF_RUNNING
:
6053 case OPTYPE_COMP_MTC
:
6054 case OPTYPE_COMP_SYSTEM
:
6055 chk_expr_comptype_compat();
6057 case OPTYPE_RND
: // -
6058 case OPTYPE_TMR_RUNNING_ANY
:
6059 chk_expr_dynamic_part(exp_val
, true);
6061 case OPTYPE_COMP_RUNNING_ANY
:
6062 case OPTYPE_COMP_RUNNING_ALL
:
6063 case OPTYPE_COMP_ALIVE_ANY
:
6064 case OPTYPE_COMP_ALIVE_ALL
:
6065 case OPTYPE_GETVERDICT
:
6066 chk_expr_dynamic_part(exp_val
, false);
6068 case OPTYPE_COMP_SELF
:
6069 chk_expr_comptype_compat();
6070 chk_expr_dynamic_part(exp_val
, false, true, false);
6072 case OPTYPE_UNARYPLUS
: // v1
6073 case OPTYPE_UNARYMINUS
:
6076 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6077 v1
->set_lowerid_to_ref();
6078 tt1
=v1
->get_expr_returntype(exp_val
);
6079 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6080 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6086 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6087 v1
->set_lowerid_to_ref();
6088 tt1
=v1
->get_expr_returntype(exp_val
);
6089 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6090 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6096 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6097 v1
->set_lowerid_to_ref();
6098 tt1
=v1
->get_expr_returntype(exp_val
);
6099 chk_expr_operandtype_binstr(tt1
, the
, opname
, v1
);
6100 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6103 case OPTYPE_BIT2HEX
:
6104 case OPTYPE_BIT2OCT
:
6105 case OPTYPE_BIT2STR
:
6108 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6109 v1
->set_lowerid_to_ref();
6110 tt1
=v1
->get_expr_returntype(exp_val
);
6111 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6112 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6115 case OPTYPE_BIT2INT
:
6118 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6119 v1
->set_lowerid_to_ref();
6120 tt1
=v1
->get_expr_returntype(exp_val
);
6121 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6122 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6123 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6126 case OPTYPE_CHAR2INT
:
6129 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6130 v1
->set_lowerid_to_ref();
6131 tt1
=v1
->get_expr_returntype(exp_val
);
6132 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6133 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6134 chk_expr_val_len1(v1
, the
, opname
);
6137 case OPTYPE_CHAR2OCT
:
6140 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6141 v1
->set_lowerid_to_ref();
6142 tt1
=v1
->get_expr_returntype(exp_val
);
6143 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6144 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6147 case OPTYPE_STR2INT
:
6150 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6151 v1
->set_lowerid_to_ref();
6152 tt1
=v1
->get_expr_returntype(exp_val
);
6153 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6154 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6155 chk_expr_val_str_int(v1
, the
, opname
);
6158 case OPTYPE_STR2FLOAT
:
6161 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6162 v1
->set_lowerid_to_ref();
6163 tt1
=v1
->get_expr_returntype(exp_val
);
6164 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6165 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6166 chk_expr_val_str_float(v1
, the
, opname
);
6169 case OPTYPE_STR2BIT
:
6172 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6173 v1
->set_lowerid_to_ref();
6174 tt1
=v1
->get_expr_returntype(exp_val
);
6175 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6176 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6177 chk_expr_val_str_bindigits(v1
, the
, opname
);
6180 case OPTYPE_STR2HEX
:
6183 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6184 v1
->set_lowerid_to_ref();
6185 tt1
=v1
->get_expr_returntype(exp_val
);
6186 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6187 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6188 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6191 case OPTYPE_STR2OCT
:
6194 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6195 v1
->set_lowerid_to_ref();
6196 tt1
=v1
->get_expr_returntype(exp_val
);
6197 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6198 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6199 chk_expr_val_str_len_even(v1
, the
, opname
);
6200 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6203 case OPTYPE_ENUM2INT
:
6206 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6207 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6208 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6212 chk_expr_operand_encode(refch
, exp_val
);
6214 case OPTYPE_FLOAT2INT
:
6215 case OPTYPE_FLOAT2STR
:
6218 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6219 v1
->set_lowerid_to_ref();
6220 tt1
=v1
->get_expr_returntype(exp_val
);
6221 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6222 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6223 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6224 chk_expr_operand_valid_float(v1
, the
, opname
);
6227 case OPTYPE_RNDWITHVAL
:
6230 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6231 v1
->set_lowerid_to_ref();
6232 tt1
=v1
->get_expr_returntype(exp_val
);
6233 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6234 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6235 chk_expr_operand_valid_float(v1
, the
, opname
);
6237 chk_expr_dynamic_part(exp_val
, true);
6239 case OPTYPE_HEX2BIT
:
6240 case OPTYPE_HEX2OCT
:
6241 case OPTYPE_HEX2STR
:
6244 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6245 v1
->set_lowerid_to_ref();
6246 tt1
=v1
->get_expr_returntype(exp_val
);
6247 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6248 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6251 case OPTYPE_HEX2INT
:
6254 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6255 v1
->set_lowerid_to_ref();
6256 tt1
=v1
->get_expr_returntype(exp_val
);
6257 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6258 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6259 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6262 case OPTYPE_INT2CHAR
:
6265 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6266 v1
->set_lowerid_to_ref();
6267 tt1
=v1
->get_expr_returntype(exp_val
);
6268 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6269 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6270 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6273 case OPTYPE_INT2UNICHAR
:
6276 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6277 v1
->set_lowerid_to_ref();
6278 tt1
=v1
->get_expr_returntype(exp_val
);
6279 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6280 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6281 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6284 case OPTYPE_INT2FLOAT
:
6285 case OPTYPE_INT2STR
:
6288 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6289 v1
->set_lowerid_to_ref();
6290 tt1
=v1
->get_expr_returntype(exp_val
);
6291 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6292 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6295 case OPTYPE_OCT2BIT
:
6296 case OPTYPE_OCT2HEX
:
6297 case OPTYPE_OCT2STR
:
6300 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6301 v1
->set_lowerid_to_ref();
6302 tt1
=v1
->get_expr_returntype(exp_val
);
6303 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6304 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6307 case OPTYPE_OCT2INT
:
6310 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6311 v1
->set_lowerid_to_ref();
6312 tt1
=v1
->get_expr_returntype(exp_val
);
6313 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6314 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6315 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6319 case OPTYPE_OCT2CHAR
:
6322 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6323 v1
->set_lowerid_to_ref();
6324 tt1
=v1
->get_expr_returntype(exp_val
);
6325 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6326 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6327 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6330 case OPTYPE_REMOVE_BOM
:
6333 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6334 v1
->set_lowerid_to_ref();
6335 tt1
=v1
->get_expr_returntype(exp_val
);
6336 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6337 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6340 case OPTYPE_GET_STRINGENCODING
:
6343 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6344 v1
->set_lowerid_to_ref();
6345 tt1
=v1
->get_expr_returntype(exp_val
);
6346 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6347 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6350 case OPTYPE_ENCODE_BASE64
:
6353 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6354 v1
->set_lowerid_to_ref();
6355 tt1
=v1
->get_expr_returntype(exp_val
);
6356 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6357 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6359 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6362 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6363 v2
->set_lowerid_to_ref();
6364 tt2
=v2
->get_expr_returntype(exp_val
);
6365 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6366 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6369 case OPTYPE_DECODE_BASE64
:
6372 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6373 v1
->set_lowerid_to_ref();
6374 tt1
=v1
->get_expr_returntype(exp_val
);
6375 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6376 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6379 case OPTYPE_UNICHAR2INT
:
6382 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6383 v1
->set_lowerid_to_ref();
6384 tt1
=v1
->get_expr_returntype(exp_val
);
6385 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6386 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6387 chk_expr_val_len1(v1
, the
, opname
);
6390 case OPTYPE_UNICHAR2CHAR
:
6393 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6394 v1
->set_lowerid_to_ref();
6395 tt1
=v1
->get_expr_returntype(exp_val
);
6396 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6397 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6398 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6401 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6404 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6405 v1
->set_lowerid_to_ref();
6406 tt1
=v1
->get_expr_returntype(exp_val
);
6407 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6408 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6410 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6413 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6414 v2
->set_lowerid_to_ref();
6415 tt2
=v2
->get_expr_returntype(exp_val
);
6416 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6417 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6420 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6423 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6424 v1
->set_lowerid_to_ref();
6425 tt1
=v1
->get_expr_returntype(exp_val
);
6426 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6427 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6429 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6432 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6433 v2
->set_lowerid_to_ref();
6434 tt2
=v2
->get_expr_returntype(exp_val
);
6435 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6436 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6439 case OPTYPE_ADD
: // v1 v2
6440 case OPTYPE_SUBTRACT
:
6441 case OPTYPE_MULTIPLY
:
6445 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6446 v1
->set_lowerid_to_ref();
6447 tt1
=v1
->get_expr_returntype(exp_val
);
6448 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6449 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6450 chk_expr_operand_valid_float(v1
, first
, opname
);
6454 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6455 v2
->set_lowerid_to_ref();
6456 tt2
=v2
->get_expr_returntype(exp_val
);
6457 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6458 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6459 chk_expr_operand_valid_float(v2
, second
, opname
);
6460 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6461 chk_expr_val_int_float_not0(v2
, second
, opname
);
6463 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6469 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6470 v1
->set_lowerid_to_ref();
6471 tt1
=v1
->get_expr_returntype(exp_val
);
6472 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6473 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6477 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6478 v2
->set_lowerid_to_ref();
6479 tt2
=v2
->get_expr_returntype(exp_val
);
6480 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6481 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6482 chk_expr_val_int_float_not0(v2
, right
, opname
);
6485 case OPTYPE_CONCAT
: {
6488 v1
->set_lowerid_to_ref();
6489 v2
->set_lowerid_to_ref();
6490 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6492 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6493 tt1
=v1
->get_expr_returntype(exp_val
);
6494 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6495 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6498 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6499 tt2
=v2
->get_expr_returntype(exp_val
);
6500 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6501 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6503 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6504 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6505 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6506 } else { // other list types
6507 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6508 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6510 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6511 set_valuetype(V_ERROR
);
6514 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6515 v1_gov
->chk_this_value_ref(v1
);
6516 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6517 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6518 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6522 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6523 set_valuetype(V_ERROR
);
6526 // for recof/setof literals set the type from v1
6528 v2
->set_my_governor(v1_gov
);
6531 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6533 v2_gov
->chk_this_value_ref(v2
);
6534 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6535 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6536 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6537 if (valuetype
== V_ERROR
) return;
6538 // 7.1.2 says that we shouldn't allow type compatibility.
6539 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6540 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6541 error("The operands of operation `%s' should be of compatible "
6542 "types", get_opname());
6551 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6553 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6555 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6558 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6560 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6561 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6562 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6563 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6564 * "a == not b" is not allowed. (HL69107)
6565 * The various *Expressions implement operator precedence in the std.
6566 * Titan's parser has only one Expression and relies on Bison
6567 * for operator precedence. The check below brings Titan in line
6568 * with the standard by explicitly making "a == not b" an error */
6569 if (v2
->get_valuetype() == V_EXPR
6570 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6571 error("The operation `%s' is not allowed to be "
6572 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6573 set_valuetype(V_ERROR
);
6583 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6585 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6587 tt1
=v1
->get_expr_returntype(exp_val
);
6588 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6589 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6592 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6594 tt2
=v2
->get_expr_returntype(exp_val
);
6595 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6596 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6604 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6606 v1
->set_lowerid_to_ref();
6607 tt1
=v1
->get_expr_returntype(exp_val
);
6608 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6609 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6613 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6615 v2
->set_lowerid_to_ref();
6616 tt2
=v2
->get_expr_returntype(exp_val
);
6617 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6618 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6626 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6628 v1
->set_lowerid_to_ref();
6629 tt1
=v1
->get_expr_returntype(exp_val
);
6630 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6631 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6635 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6637 v2
->set_lowerid_to_ref();
6638 tt2
=v2
->get_expr_returntype(exp_val
);
6639 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6640 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6642 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6643 chk_expr_operands_str_samelen();
6649 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6650 v1
->set_lowerid_to_ref();
6651 tt1
=v1
->get_expr_returntype(exp_val
);
6652 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6653 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6657 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6658 v2
->set_lowerid_to_ref();
6659 tt2
=v2
->get_expr_returntype(exp_val
);
6660 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6661 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6662 chk_expr_val_large_int(v2
, right
, opname
);
6668 v1
->set_lowerid_to_ref();
6669 if (v1
->is_string_type(exp_val
)) {
6670 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6671 tt1
=v1
->get_expr_returntype(exp_val
);
6672 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6673 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6674 } else { // other list types
6675 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6676 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6677 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6679 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6680 v1_gov
->chk_this_value_ref(v1
);
6681 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6682 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6683 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6688 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6689 v2
->set_lowerid_to_ref();
6690 tt2
=v2
->get_expr_returntype(exp_val
);
6691 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6692 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6693 chk_expr_val_large_int(v2
, right
, opname
);
6696 case OPTYPE_INT2BIT
:
6697 case OPTYPE_INT2HEX
:
6698 case OPTYPE_INT2OCT
:
6701 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6702 v1
->set_lowerid_to_ref();
6703 tt1
=v1
->get_expr_returntype(exp_val
);
6704 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6705 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6706 chk_expr_val_int_pos0(v1
, first
, opname
);
6710 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6711 v2
->set_lowerid_to_ref();
6712 tt2
=v2
->get_expr_returntype(exp_val
);
6713 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6714 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6715 chk_expr_val_int_pos0(v2
, second
, opname
);
6717 chk_expr_operands_int2binstr();
6720 chk_expr_operands_decode();
6724 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6725 Type::expected_value_t ti_exp_val
= exp_val
;
6726 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6727 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6728 if (!governor
) return;
6729 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6730 if (valuetype
!=V_ERROR
)
6731 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6732 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6736 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6737 v2
->set_lowerid_to_ref();
6738 tt2
=v2
->get_expr_returntype(exp_val
);
6739 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6740 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6741 chk_expr_val_int_pos0(v2
, second
, opname
);
6745 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6746 v3
->set_lowerid_to_ref();
6747 tt3
=v3
->get_expr_returntype(exp_val
);
6748 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6749 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6750 chk_expr_val_int_pos0(v3
, third
, opname
);
6752 chk_expr_operands_substr();
6754 case OPTYPE_REGEXP
: {
6755 Type::expected_value_t ti_exp_val
= exp_val
;
6756 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6758 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6759 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6760 if (!governor
) return;
6761 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6762 if (valuetype
!=V_ERROR
) {
6763 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6764 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6765 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6769 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6770 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6771 if (!governor
) return;
6772 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6773 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6774 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6778 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6779 v3
->set_lowerid_to_ref();
6780 tt3
=v3
->get_expr_returntype(exp_val
);
6781 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6782 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6783 chk_expr_val_int_pos0(v3
, third
, opname
);
6785 chk_expr_operands_regexp();
6787 case OPTYPE_ISCHOSEN
:
6788 // do nothing: the operand is erroneous
6789 // the error was already reported in chk_expr_ref_ischosen()
6791 case OPTYPE_ISCHOSEN_V
: // v1 i2
6792 case OPTYPE_ISCHOSEN_T
: // t1 i2
6793 chk_expr_operands_ischosen(refch
, exp_val
);
6795 case OPTYPE_VALUEOF
: { // ti1
6796 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6797 exp_val
= Type::EXPECTED_TEMPLATE
;
6798 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6799 Type
*governor
= my_governor
;
6800 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6801 if (!governor
) return;
6802 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6803 if (valuetype
== V_ERROR
) return;
6804 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6806 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6807 case OPTYPE_ISBOUND
: {
6808 Template
*templ
= u
.expr
.ti1
->get_Template();
6809 switch (templ
->get_templatetype()) {
6810 case Template::TEMPLATE_REFD
:
6811 templ
->get_reference()->setUsedInIsbound();
6813 case Template::SPECIFIC_VALUE
: {
6814 Value
*value
= templ
->get_specific_value();
6815 if (Value::V_REFD
== value
->get_valuetype()) {
6816 value
->get_reference()->setUsedInIsbound();
6824 case OPTYPE_ISVALUE
: {// ti1
6825 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6826 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6827 exp_val
= Type::EXPECTED_TEMPLATE
;
6828 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6829 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6830 if (!governor
) return;
6831 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
6832 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6834 case OPTYPE_SIZEOF
: // ti1
6835 /* this checking is too complex, do the checking during eval... */
6837 case OPTYPE_LENGTHOF
: { // ti1
6838 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6839 exp_val
= Type::EXPECTED_TEMPLATE
;
6840 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6841 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6842 if (!governor
) return;
6843 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
6844 if (valuetype
== V_ERROR
) return;
6845 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6847 case OPTYPE_MATCH
: // v1 t2
6848 chk_expr_operands_match(exp_val
);
6850 case OPTYPE_UNDEF_RUNNING
: // r1
6851 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
6853 case OPTYPE_COMP_ALIVE
:
6854 case OPTYPE_COMP_RUNNING
: //v1
6855 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
6856 chk_expr_dynamic_part(exp_val
, false);
6858 case OPTYPE_TMR_READ
: // r1
6859 case OPTYPE_TMR_RUNNING
: // r1
6860 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
6861 chk_expr_dynamic_part(exp_val
, true);
6863 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
6864 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
6865 chk_expr_dynamic_part(exp_val
, true, false, false);
6867 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
6868 chk_expr_operand_comptyperef_create();
6871 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6872 v2
->set_lowerid_to_ref();
6873 tt2
=v2
->get_expr_returntype(exp_val
);
6874 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
6875 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6879 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6880 v3
->set_lowerid_to_ref();
6881 tt3
=v3
->get_expr_returntype(exp_val
);
6882 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
6883 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6885 chk_expr_dynamic_part(exp_val
, false);
6887 case OPTYPE_ACTIVATE
: // r1 // altstep
6888 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
6889 chk_expr_dynamic_part(exp_val
, true);
6891 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
6892 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6893 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
6895 delete u
.expr
.t_list2
;
6896 u
.expr
.ap_list2
= parlist
;
6897 chk_expr_dynamic_part(exp_val
, true);
6899 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
6900 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6901 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
6902 u
.expr
.v3
, the
, opname
);
6903 delete u
.expr
.t_list2
;
6904 u
.expr
.ap_list2
= parlist
;
6905 chk_expr_dynamic_part(exp_val
, true);
6908 error("Built-in function `%s' is not yet supported", opname
);
6909 set_valuetype(V_ERROR
);
6911 case OPTYPE_REPLACE
: {
6912 Type::expected_value_t ti_exp_val
= exp_val
;
6913 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6914 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6916 Error_Context
cntxt(this, "In the first operand of operation `%s'",
6918 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6919 if (!governor
) return;
6920 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6921 if (valuetype
!= V_ERROR
)
6922 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6923 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6927 Error_Context
cntxt(this, "In the second operand of operation `%s'",
6929 v2
->set_lowerid_to_ref();
6930 tt2
= v2
->get_expr_returntype(exp_val
);
6931 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6932 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6933 chk_expr_val_int_pos0(v2
, second
, opname
);
6937 Error_Context
cntxt(this, "In the third operand of operation `%s'",
6939 v3
->set_lowerid_to_ref();
6940 tt3
= v3
->get_expr_returntype(exp_val
);
6941 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6942 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6943 chk_expr_val_int_pos0(v3
, third
, opname
);
6946 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
6948 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
6949 if (!governor
) return;
6950 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
6951 if (valuetype
!= V_ERROR
)
6952 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
6953 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
6955 chk_expr_operands_replace();
6957 case OPTYPE_LOG2STR
: {
6958 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6959 u
.expr
.logargs
->chk();
6960 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
6962 case OPTYPE_TTCN2STRING
: {
6963 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
6964 Type::expected_value_t ti_exp_val
= exp_val
;
6965 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6966 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6967 if (!governor
) return;
6968 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6971 FATAL_ERROR("chk_expr_operands()");
6975 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6976 // the result of evaluating the expression. E.g. V_BOOL for
6978 void Value::evaluate_value(ReferenceChain
*refch
,
6979 Type::expected_value_t exp_val
)
6981 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
6982 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
6984 u
.expr
.state
=EXPR_CHECKING
;
6986 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
6987 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
6988 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
6990 if(valuetype
==V_ERROR
) return;
6991 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
6992 u
.expr
.state
=EXPR_CHECKED
;
6993 set_valuetype(V_ERROR
);
6997 u
.expr
.state
=EXPR_CHECKED
;
6999 Value
*v1
, *v2
, *v3
, *v4
;
7000 switch(u
.expr
.v_optype
) {
7001 case OPTYPE_RND
: // -
7002 case OPTYPE_COMP_NULL
: // the only foldable in this group
7003 case OPTYPE_COMP_MTC
:
7004 case OPTYPE_COMP_SYSTEM
:
7005 case OPTYPE_COMP_SELF
:
7006 case OPTYPE_COMP_RUNNING_ANY
:
7007 case OPTYPE_COMP_RUNNING_ALL
:
7008 case OPTYPE_COMP_ALIVE_ANY
:
7009 case OPTYPE_COMP_ALIVE_ALL
:
7010 case OPTYPE_TMR_RUNNING_ANY
:
7011 case OPTYPE_GETVERDICT
:
7012 case OPTYPE_PROF_RUNNING
:
7013 case OPTYPE_RNDWITHVAL
: // v1
7014 case OPTYPE_COMP_RUNNING
: // v1
7015 case OPTYPE_COMP_ALIVE
:
7016 case OPTYPE_TMR_READ
:
7017 case OPTYPE_TMR_RUNNING
:
7018 case OPTYPE_ACTIVATE
:
7019 case OPTYPE_ACTIVATE_REFD
:
7020 case OPTYPE_EXECUTE
: // r1 [v2]
7021 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7022 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7023 case OPTYPE_MATCH
: // v1 t2
7024 case OPTYPE_ISCHOSEN_T
:
7025 case OPTYPE_LOG2STR
:
7028 case OPTYPE_ISBOUND
:
7029 case OPTYPE_ISPRESENT
:
7030 case OPTYPE_TTCN2STRING
:
7031 case OPTYPE_UNICHAR2OCT
:
7032 case OPTYPE_OCT2UNICHAR
:
7033 case OPTYPE_ENCODE_BASE64
:
7034 case OPTYPE_DECODE_BASE64
:
7036 case OPTYPE_TESTCASENAME
: { // -
7037 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7038 Ttcn::StatementBlock
*my_sb
=
7039 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7041 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7042 if (!my_def
) { // In control part.
7043 set_val_str(new string(""));
7045 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7046 set_val_str(new string(my_def
->get_id().get_dispname()));
7050 case OPTYPE_UNARYPLUS
: // v1
7053 copy_and_destroy(v1
);
7055 case OPTYPE_UNARYMINUS
:
7056 if (is_unfoldable()) break;
7057 v1
= u
.expr
.v1
->get_value_refd_last();
7058 switch (v1
->valuetype
) {
7060 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7061 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7067 ttcn3float r
= v1
->get_val_Real();
7073 FATAL_ERROR("Value::evaluate_value()");
7077 if(is_unfoldable()) break;
7078 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7083 case OPTYPE_NOT4B
: {
7084 if(is_unfoldable()) break;
7085 v1
=u
.expr
.v1
->get_value_refd_last();
7086 const string
& s
= v1
->get_val_str();
7087 valuetype_t vt
=v1
->valuetype
;
7090 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7092 case OPTYPE_BIT2HEX
: {
7093 if(is_unfoldable()) break;
7094 v1
=u
.expr
.v1
->get_value_refd_last();
7095 const string
& s
= v1
->get_val_str();
7098 set_val_str(bit2hex(s
));
7100 case OPTYPE_BIT2OCT
: {
7101 if(is_unfoldable()) break;
7102 v1
=u
.expr
.v1
->get_value_refd_last();
7103 const string
& s
= v1
->get_val_str();
7106 set_val_str(bit2oct(s
));
7108 case OPTYPE_BIT2STR
:
7109 case OPTYPE_HEX2STR
:
7110 case OPTYPE_OCT2STR
: {
7111 if(is_unfoldable()) break;
7112 v1
=u
.expr
.v1
->get_value_refd_last();
7113 const string
& s
= v1
->get_val_str();
7116 set_val_str(new string(s
));
7118 case OPTYPE_BIT2INT
: {
7119 if (is_unfoldable()) break;
7120 v1
= u
.expr
.v1
->get_value_refd_last();
7121 const string
& s
= v1
->get_val_str();
7124 u
.val_Int
= bit2int(s
);
7126 case OPTYPE_CHAR2INT
: {
7127 if (is_unfoldable()) break;
7128 v1
= u
.expr
.v1
->get_value_refd_last();
7129 char c
= v1
->get_val_str()[0];
7132 u
.val_Int
= new int_val_t((Int
)c
);
7134 case OPTYPE_CHAR2OCT
: {
7135 if(is_unfoldable()) break;
7136 v1
=u
.expr
.v1
->get_value_refd_last();
7137 const string
& s
= v1
->get_val_str();
7140 set_val_str(char2oct(s
));
7142 case OPTYPE_STR2INT
: {
7143 if (is_unfoldable()) break;
7144 v1
= u
.expr
.v1
->get_value_refd_last();
7145 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7149 /** \todo hiba eseten lenyeli... */
7151 case OPTYPE_STR2FLOAT
: {
7152 if(is_unfoldable()) break;
7153 v1
=u
.expr
.v1
->get_value_refd_last();
7154 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7158 /** \todo hiba eseten lenyeli... */
7160 case OPTYPE_STR2BIT
: {
7161 if(is_unfoldable()) break;
7162 v1
=u
.expr
.v1
->get_value_refd_last();
7163 const string
& s
= v1
->get_val_str();
7166 set_val_str(new string(s
));
7168 case OPTYPE_STR2HEX
:
7169 case OPTYPE_OCT2HEX
: {
7170 if(is_unfoldable()) break;
7171 v1
=u
.expr
.v1
->get_value_refd_last();
7172 const string
& s
= v1
->get_val_str();
7175 set_val_str(to_uppercase(s
));
7177 case OPTYPE_STR2OCT
: {
7178 if(is_unfoldable()) break;
7179 v1
=u
.expr
.v1
->get_value_refd_last();
7180 const string
& s
= v1
->get_val_str();
7183 set_val_str(to_uppercase(s
));
7185 case OPTYPE_FLOAT2INT
: {
7186 if (is_unfoldable()) break;
7187 v1
= u
.expr
.v1
->get_value_refd_last();
7188 ttcn3float r
= v1
->get_val_Real();
7191 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7193 case OPTYPE_FLOAT2STR
: {
7194 if(is_unfoldable()) break;
7195 v1
=u
.expr
.v1
->get_value_refd_last();
7196 ttcn3float r
=v1
->get_val_Real();
7199 set_val_str(float2str(r
));
7201 case OPTYPE_HEX2BIT
:
7202 case OPTYPE_OCT2BIT
: {
7203 if(is_unfoldable()) break;
7204 v1
=u
.expr
.v1
->get_value_refd_last();
7205 const string
& s
= v1
->get_val_str();
7208 set_val_str(hex2bit(s
));
7210 case OPTYPE_HEX2INT
:
7211 case OPTYPE_OCT2INT
: {
7212 if(is_unfoldable()) break;
7213 v1
=u
.expr
.v1
->get_value_refd_last();
7214 const string
& s
= v1
->get_val_str();
7217 u
.val_Int
=hex2int(s
);
7219 case OPTYPE_HEX2OCT
: {
7220 if(is_unfoldable()) break;
7221 v1
=u
.expr
.v1
->get_value_refd_last();
7222 const string
& s
= v1
->get_val_str();
7225 set_val_str(hex2oct(s
));
7227 case OPTYPE_INT2CHAR
: {
7228 if (is_unfoldable()) break;
7229 v1
= u
.expr
.v1
->get_value_refd_last();
7230 const int_val_t
*c_int
= v1
->get_val_Int();
7231 char c
= static_cast<char>(c_int
->get_val());
7234 set_val_str(new string(1, &c
));
7236 case OPTYPE_INT2UNICHAR
: {
7237 if (is_unfoldable()) break;
7238 v1
= u
.expr
.v1
->get_value_refd_last();
7239 const int_val_t
*i_int
= v1
->get_val_Int();
7240 Int i
= i_int
->get_val();
7243 set_val_ustr(int2unichar(i
));
7244 u
.ustr
.convert_str
= false;
7246 case OPTYPE_INT2FLOAT
: {
7247 if (is_unfoldable()) break;
7248 v1
= u
.expr
.v1
->get_value_refd_last();
7249 const int_val_t
*i_int
= v1
->get_val_Int();
7250 Real i_int_real
= i_int
->to_real();
7253 u
.val_Real
= i_int_real
;
7255 case OPTYPE_INT2STR
: {
7256 if (is_unfoldable()) break;
7257 v1
= u
.expr
.v1
->get_value_refd_last();
7258 const int_val_t
*i_int
= v1
->get_val_Int();
7259 string
*i_int_str
= new string(i_int
->t_str());
7262 set_val_str(i_int_str
);
7264 case OPTYPE_OCT2CHAR
: {
7265 if(is_unfoldable()) break;
7266 v1
=u
.expr
.v1
->get_value_refd_last();
7267 const string
& s
= v1
->get_val_str();
7270 set_val_str(oct2char(s
));
7272 case OPTYPE_GET_STRINGENCODING
: {
7273 if(is_unfoldable()) break;
7274 v1
= u
.expr
.v1
->get_value_refd_last();
7275 const string
& s1
= v1
->get_val_str();
7278 set_val_str(get_stringencoding(s1
));
7280 case OPTYPE_REMOVE_BOM
: {
7281 if(is_unfoldable()) break;
7282 v1
= u
.expr
.v1
->get_value_refd_last();
7283 const string
& s1
= v1
->get_val_str();
7286 set_val_str(remove_bom(s1
));
7288 case OPTYPE_ENUM2INT
: {
7289 if(is_unfoldable()) break;
7290 v1
=u
.expr
.v1
->get_value_refd_last();
7291 Type
* enum_type
= v1
->get_my_governor();
7292 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7295 u
.val_Int
= new int_val_t(enum_val
);
7297 case OPTYPE_UNICHAR2INT
:
7298 if (is_unfoldable()) {
7299 // replace the operation with char2int() if the operand is a charstring
7300 // value to avoid its unnecessary conversion to universal charstring
7301 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7302 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7304 v1
=u
.expr
.v1
->get_value_refd_last();
7305 const ustring
& s
= v1
->get_val_ustr();
7308 u
.val_Int
=new int_val_t(unichar2int(s
));
7311 case OPTYPE_UNICHAR2CHAR
:
7313 if (is_unfoldable()) {
7314 // replace the operation with its operand if it is a charstring
7315 // value to avoid its unnecessary conversion to universal charstring
7316 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7318 copy_and_destroy(v1
);
7321 v1
= v1
->get_value_refd_last();
7322 const ustring
& s
= v1
->get_val_ustr();
7325 set_val_str(new string(s
));
7328 case OPTYPE_MULTIPLY
: { // v1 v2
7329 if (!is_unfoldable()) goto eval_arithmetic
;
7330 v1
= u
.expr
.v1
->get_value_refd_last();
7331 v2
= u
.expr
.v2
->get_value_refd_last();
7332 if (v1
->is_unfoldable()) v1
= v2
;
7333 if (v1
->is_unfoldable()) break;
7334 switch(v1
->valuetype
) {
7336 if (*v1
->get_val_Int() != 0) break;
7339 u
.val_Int
= new int_val_t((Int
)0);
7342 if (v1
->get_val_Real() != 0.0) break;
7348 FATAL_ERROR("Value::evaluate_value()");
7351 case OPTYPE_ADD
: // v1 v2
7352 case OPTYPE_SUBTRACT
:
7357 if(is_unfoldable()) break;
7358 v1
=u
.expr
.v1
->get_value_refd_last();
7359 v2
=u
.expr
.v2
->get_value_refd_last();
7360 operationtype_t ot
=u
.expr
.v_optype
;
7361 switch (v1
->valuetype
) {
7363 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7364 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7369 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7371 case OPTYPE_SUBTRACT
:
7372 u
.val_Int
= new int_val_t(*i1
- *i2
);
7374 case OPTYPE_MULTIPLY
:
7375 u
.val_Int
= new int_val_t(*i1
* *i2
);
7378 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7381 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7384 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7387 FATAL_ERROR("Value::evaluate_value()");
7393 ttcn3float r1
=v1
->get_val_Real();
7394 ttcn3float r2
=v2
->get_val_Real();
7401 case OPTYPE_SUBTRACT
:
7404 case OPTYPE_MULTIPLY
:
7411 FATAL_ERROR("Value::evaluate_value()");
7415 FATAL_ERROR("Value::evaluate_value()");
7418 case OPTYPE_CONCAT
: {
7419 if(is_unfoldable()) break;
7420 v1
=u
.expr
.v1
->get_value_refd_last();
7421 v2
=u
.expr
.v2
->get_value_refd_last();
7422 valuetype_t vt
= v1
->valuetype
;
7423 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7424 const ustring
& s1
= v1
->get_val_ustr();
7425 const ustring
& s2
= v2
->get_val_ustr();
7428 set_val_ustr(new ustring(s1
+ s2
));
7429 u
.ustr
.convert_str
= false;
7431 const string
& s1
= v1
->get_val_str();
7432 const string
& s2
= v2
->get_val_str();
7435 set_val_str(new string(s1
+ s2
));
7439 if(is_unfoldable()) break;
7440 v1
=u
.expr
.v1
->get_value_refd_last();
7441 v2
=u
.expr
.v2
->get_value_refd_last();
7448 if(is_unfoldable()) break;
7449 v1
=u
.expr
.v1
->get_value_refd_last();
7450 v2
=u
.expr
.v2
->get_value_refd_last();
7457 if(is_unfoldable()) break;
7458 v1
=u
.expr
.v1
->get_value_refd_last();
7459 v2
=u
.expr
.v2
->get_value_refd_last();
7466 if(is_unfoldable()) break;
7467 v1
=u
.expr
.v1
->get_value_refd_last();
7468 v2
=u
.expr
.v2
->get_value_refd_last();
7475 if(is_unfoldable()) break;
7476 v1
=u
.expr
.v1
->get_value_refd_last();
7477 v2
=u
.expr
.v2
->get_value_refd_last();
7484 if(is_unfoldable()) break;
7485 v1
=u
.expr
.v1
->get_value_refd_last();
7486 v2
=u
.expr
.v2
->get_value_refd_last();
7493 v1
= u
.expr
.v1
->get_value_refd_last();
7494 if (v1
->valuetype
== V_BOOL
) {
7495 if (v1
->get_val_bool()) {
7496 // the left operand is a literal "true"
7497 // substitute the expression with the right operand
7500 copy_and_destroy(v2
);
7502 // the left operand is a literal "false"
7503 // the result must be false regardless the right operand
7504 // because of the short circuit evaluation rule
7510 // we must keep the left operand because of the potential side effects
7511 // the right operand can only be eliminated if it is a literal "true"
7512 v2
= u
.expr
.v2
->get_value_refd_last();
7513 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7516 copy_and_destroy(v1
);
7521 v1
= u
.expr
.v1
->get_value_refd_last();
7522 if (v1
->valuetype
== V_BOOL
) {
7523 if (v1
->get_val_bool()) {
7524 // the left operand is a literal "true"
7525 // the result must be true regardless the right operand
7526 // because of the short circuit evaluation rule
7531 // the left operand is a literal "false"
7532 // substitute the expression with the right operand
7535 copy_and_destroy(v2
);
7538 // we must keep the left operand because of the potential side effects
7539 // the right operand can only be eliminated if it is a literal "false"
7540 v2
= u
.expr
.v2
->get_value_refd_last();
7541 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7544 copy_and_destroy(v1
);
7549 if(is_unfoldable()) break;
7550 v1
=u
.expr
.v1
->get_value_refd_last();
7551 v2
=u
.expr
.v2
->get_value_refd_last();
7552 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7557 case OPTYPE_AND4B
: {
7558 if(is_unfoldable()) break;
7559 v1
=u
.expr
.v1
->get_value_refd_last();
7560 v2
=u
.expr
.v2
->get_value_refd_last();
7561 valuetype_t vt
=v1
->valuetype
;
7562 const string
& s1
= v1
->get_val_str();
7563 const string
& s2
= v2
->get_val_str();
7566 set_val_str(and4b(s1
, s2
));
7569 if(is_unfoldable()) break;
7570 v1
=u
.expr
.v1
->get_value_refd_last();
7571 v2
=u
.expr
.v2
->get_value_refd_last();
7572 valuetype_t vt
=v1
->valuetype
;
7573 const string
& s1
= v1
->get_val_str();
7574 const string
& s2
= v2
->get_val_str();
7577 set_val_str(or4b(s1
, s2
));
7579 case OPTYPE_XOR4B
: {
7580 if(is_unfoldable()) break;
7581 v1
=u
.expr
.v1
->get_value_refd_last();
7582 v2
=u
.expr
.v2
->get_value_refd_last();
7583 valuetype_t vt
=v1
->valuetype
;
7584 const string
& s1
= v1
->get_val_str();
7585 const string
& s2
= v2
->get_val_str();
7588 set_val_str(xor4b(s1
, s2
));
7591 if(is_unfoldable()) break;
7592 v1
=u
.expr
.v1
->get_value_refd_last();
7593 v2
=u
.expr
.v2
->get_value_refd_last();
7594 valuetype_t vt
=v1
->valuetype
;
7595 const string
& s
= v1
->get_val_str();
7596 const int_val_t
*i_int
= v2
->get_val_Int();
7597 Int i
=i_int
->get_val();
7598 if(vt
==V_OSTR
) i
*=2;
7601 set_val_str(shift_left(s
, i
));
7604 if(is_unfoldable()) break;
7605 v1
=u
.expr
.v1
->get_value_refd_last();
7606 v2
=u
.expr
.v2
->get_value_refd_last();
7607 valuetype_t vt
=v1
->valuetype
;
7608 const string
& s
= v1
->get_val_str();
7609 const int_val_t
*i_int
= v2
->get_val_Int();
7610 Int i
=i_int
->get_val();
7611 if(vt
==V_OSTR
) i
*=2;
7614 set_val_str(shift_right(s
, i
));
7617 if(is_unfoldable()) break;
7618 v1
=u
.expr
.v1
->get_value_refd_last();
7619 v2
=u
.expr
.v2
->get_value_refd_last();
7620 valuetype_t vt
=v1
->valuetype
;
7621 const int_val_t
*i_int
=v2
->get_val_Int();
7622 Int i
=i_int
->get_val();
7624 const ustring
& s
= v1
->get_val_ustr();
7627 set_val_ustr(rotate_left(s
, i
));
7628 u
.ustr
.convert_str
= false;
7631 if(vt
==V_OSTR
) i
*=2;
7632 const string
& s
= v1
->get_val_str();
7635 set_val_str(rotate_left(s
, i
));
7639 if(is_unfoldable()) break;
7640 v1
=u
.expr
.v1
->get_value_refd_last();
7641 v2
=u
.expr
.v2
->get_value_refd_last();
7642 valuetype_t vt
=v1
->valuetype
;
7643 const int_val_t
*i_int
=v2
->get_val_Int();
7644 Int i
=i_int
->get_val();
7646 const ustring
& s
= v1
->get_val_ustr();
7649 set_val_ustr(rotate_right(s
, i
));
7650 u
.ustr
.convert_str
= false;
7653 if(vt
==V_OSTR
) i
*=2;
7654 const string
& s
= v1
->get_val_str();
7657 set_val_str(rotate_right(s
, i
));
7660 case OPTYPE_INT2BIT
: {
7661 if (is_unfoldable()) break;
7662 v1
= u
.expr
.v1
->get_value_refd_last();
7663 v2
= u
.expr
.v2
->get_value_refd_last();
7664 const int_val_t
*i1_int
= v1
->get_val_Int();
7665 const int_val_t
*i2_int
= v2
->get_val_Int();
7666 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7671 case OPTYPE_INT2HEX
: {
7672 if (is_unfoldable()) break;
7673 v1
= u
.expr
.v1
->get_value_refd_last();
7674 v2
= u
.expr
.v2
->get_value_refd_last();
7675 const int_val_t
*i1_int
= v1
->get_val_Int();
7676 const int_val_t
*i2_int
= v2
->get_val_Int();
7677 // Do it before the `clean_up'. i2_int is already checked.
7678 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7683 case OPTYPE_INT2OCT
: {
7684 if (is_unfoldable()) break;
7685 v1
= u
.expr
.v1
->get_value_refd_last();
7686 v2
= u
.expr
.v2
->get_value_refd_last();
7687 const int_val_t
i1_int(*v1
->get_val_Int());
7688 // `v2' is a native integer.
7689 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7692 set_val_str(int2hex(i1_int
, i2_int
));
7694 case OPTYPE_SUBSTR
: {
7695 if(is_unfoldable()) break;
7696 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7697 v2
=u
.expr
.v2
->get_value_refd_last();
7698 v3
=u
.expr
.v3
->get_value_refd_last();
7699 valuetype_t vt
=v1
->valuetype
;
7700 const int_val_t
*i2_int
=v2
->get_val_Int();
7701 const int_val_t
*i3_int
=v3
->get_val_Int();
7702 Int i2
=i2_int
->get_val();
7703 Int i3
=i3_int
->get_val();
7705 const ustring
& s
= v1
->get_val_ustr();
7708 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7709 u
.ustr
.convert_str
= false;
7716 const string
& s
= v1
->get_val_str();
7719 set_val_str(new string(s
.substr(i2
, i3
)));
7722 case OPTYPE_REPLACE
: {
7723 if(is_unfoldable()) break;
7724 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7725 v2
=u
.expr
.v2
->get_value_refd_last();
7726 v3
=u
.expr
.v3
->get_value_refd_last();
7727 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7728 valuetype_t vt
=v1
->valuetype
;
7729 const int_val_t
*i2_int
=v2
->get_val_Int();
7730 const int_val_t
*i3_int
=v3
->get_val_Int();
7731 Int i2
=i2_int
->get_val();
7732 Int i3
=i3_int
->get_val();
7735 string
*s1
= new string(v1
->get_val_str());
7736 const string
& s2
= v4
->get_val_str();
7739 s1
->replace(i2
, i3
, s2
);
7743 string
*s1
= new string(v1
->get_val_str());
7744 const string
& s2
= v4
->get_val_str();
7747 s1
->replace(i2
, i3
, s2
);
7753 string
*s1
= new string(v1
->get_val_str());
7754 const string
& s2
= v4
->get_val_str();
7757 s1
->replace(i2
, i3
, s2
);
7761 string
*s1
= new string(v1
->get_val_str());
7762 const string
& s2
= v4
->get_val_str();
7765 s1
->replace(i2
, i3
, s2
);
7769 ustring
*s1
= new ustring(v1
->get_val_ustr());
7770 const ustring
& s2
= v4
->get_val_ustr();
7773 s1
->replace(i2
, i3
, s2
);
7775 u
.ustr
.convert_str
= false;
7778 FATAL_ERROR("Value::evaluate_value()");
7781 case OPTYPE_REGEXP
: {
7782 if (is_unfoldable()) break;
7783 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7784 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7785 v3
=u
.expr
.v3
->get_value_refd_last();
7786 const int_val_t
*i3_int
= v3
->get_val_Int();
7787 Int i3
= i3_int
->get_val();
7788 if (v1
->valuetype
== V_CSTR
) {
7789 const string
& s1
= v1
->get_val_str();
7790 const string
& s2
= v2
->get_val_str();
7791 string
*result
= regexp(s1
, s2
, i3
);
7794 set_val_str(result
);
7795 } if (v1
->valuetype
== V_USTR
) {
7796 const ustring
& s1
= v1
->get_val_ustr();
7797 const ustring
& s2
= v2
->get_val_ustr();
7798 ustring
*result
= regexp(s1
, s2
, i3
);
7801 set_val_ustr(result
);
7802 u
.ustr
.convert_str
= false;
7805 case OPTYPE_LENGTHOF
:{
7806 if(is_unfoldable()) break;
7807 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7808 ->get_value_refd_last();
7810 if(v1
->is_string_type(exp_val
)) {
7811 i
=v1
->get_val_strlen();
7812 } else { // v1 is be seq/set of or array
7813 switch (v1
->valuetype
) {
7817 if(v1
->u
.val_vs
->is_indexed())
7818 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7819 else { i
= v1
->u
.val_vs
->get_nof_vs();}
7822 FATAL_ERROR("Value::evaluate_value()");
7827 u
.val_Int
=new int_val_t(i
);
7829 case OPTYPE_SIZEOF
: {
7830 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
7834 u
.val_Int
=new int_val_t(i
);
7837 case OPTYPE_ISVALUE
: {
7838 if(is_unfoldable()) break;
7839 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
7840 && u
.expr
.ti1
->get_Template()->is_Value();
7842 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
7843 is_singleval
= other_val
->evaluate_isvalue(false);
7844 // is_singleval now contains the compile-time result of isvalue
7849 u
.val_bool
= is_singleval
;
7851 case OPTYPE_ISCHOSEN_V
: {
7852 if (is_unfoldable()) break;
7853 v1
= u
.expr
.v1
->get_value_refd_last();
7854 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
7859 case OPTYPE_VALUEOF
: // ti1
7860 if (!u
.expr
.ti1
->get_DerivedRef() &&
7861 u
.expr
.ti1
->get_Template()->is_Value() &&
7862 !u
.expr
.ti1
->get_Type()) {
7863 // FIXME actually if the template instance has a type
7864 // it might still be foldable.
7865 // the argument is a single specific value
7866 v1
= u
.expr
.ti1
->get_Template()->get_Value();
7867 Type
*governor
= my_governor
;
7868 if (governor
== NULL
) {
7869 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
7870 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
7872 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
7873 if (governor
== NULL
)
7874 FATAL_ERROR("Value::evaluate_value()");
7876 valuetype
= v1
->valuetype
;
7878 set_my_governor(governor
);
7879 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
7880 u
.ref
.refd_last
= this;
7881 v1
->valuetype
= V_ERROR
;
7885 case OPTYPE_UNDEF_RUNNING
:
7887 FATAL_ERROR("Value::evaluate_value()");
7891 bool Value::evaluate_isvalue(bool from_sequence
)
7893 switch (valuetype
) {
7895 // Omit is not a value unless a member of a sequence or set
7896 return from_sequence
;
7899 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7900 case V_BOOL
: /**< boolean */
7901 case V_NAMEDINT
: /**< integer / named number */
7902 case V_NAMEDBITS
: /**< named bits (identifiers) */
7903 case V_INT
: /**< integer */
7904 case V_REAL
: /**< real/float */
7905 case V_ENUM
: /**< enumerated */
7906 case V_BSTR
: /**< bitstring */
7907 case V_HSTR
: /**< hexstring */
7908 case V_OSTR
: /**< octetstring */
7909 case V_CSTR
: /**< charstring */
7910 case V_USTR
: /**< universal charstring */
7911 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
7912 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
7913 case V_OID
: /**< object identifier */
7914 case V_ROID
: /**< relative object identifier */
7915 case V_VERDICT
: /**< all verdicts */
7916 return true; // values of built-in types return true
7918 // Code below was adapted from is_unfoldable(), false returned early.
7920 return u
.choice
.alt_value
->evaluate_isvalue(false);
7925 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
7926 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
7934 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
7935 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
7936 ->evaluate_isvalue(true)) return false;
7941 // alas, get_value_refd_last prevents this function from const
7942 return get_value_refd_last()->evaluate_isvalue(false);
7945 switch (u
.expr
.v_optype
) {
7946 // A constant null component reference is a corner case: it is foldable
7947 // but escapes unmodified from evaluate_value.
7948 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7949 // or is transformed into some other valuetype in evaluate_value.
7950 case OPTYPE_COMP_NULL
:
7953 break; // and fall through to the FATAL_ERROR
7957 FATAL_ERROR("Value::evaluate_isvalue()");
7963 void Value::evaluate_macro(Type::expected_value_t exp_val
)
7966 case MACRO_MODULEID
:
7968 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7969 set_val_str(new string(my_scope
->get_scope_mod()
7970 ->get_modid().get_dispname()));
7973 case MACRO_FILENAME
:
7974 case MACRO_BFILENAME
: {
7975 const char *t_filename
= get_filename();
7977 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7978 set_val_str(new string(t_filename
));
7981 case MACRO_FILEPATH
: {
7982 const char *t_filename
= get_filename();
7984 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7985 char *t_filepath
= canonize_input_file(t_filename
);
7987 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7988 set_val_str(new string(t_filepath
));
7992 case MACRO_LINENUMBER
: {
7993 int t_lineno
= get_first_line();
7995 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7996 set_val_str(new string(Int2string(t_lineno
)));
7999 case MACRO_LINENUMBER_C
: {
8000 int t_lineno
= get_first_line();
8002 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8003 u
.val_Int
= new int_val_t(t_lineno
);
8006 case MACRO_DEFINITIONID
: {
8007 // cut the second part from the fullname separated by dots
8008 const string
& t_fullname
= get_fullname();
8009 size_t first_char
= t_fullname
.find('.') + 1;
8010 if (first_char
>= t_fullname
.size())
8011 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8012 t_fullname
.c_str());
8013 set_val_str(new string(t_fullname
.substr(first_char
,
8014 t_fullname
.find('.', first_char
) - first_char
)));
8018 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8019 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8023 case MACRO_TESTCASEID
: {
8024 if (exp_val
== Type::EXPECTED_CONSTANT
||
8025 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8026 error("A %s value was expected instead of macro `%%testcaseId', "
8027 "which is evaluated at runtime",
8028 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8032 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8033 Ttcn::StatementBlock
*my_sb
=
8034 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8036 error("Usage of macro %%testcaseId is allowed only within the "
8037 "statement blocks of functions, altsteps and testcases");
8040 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8042 error("Macro %%testcaseId cannot be used in the control part. "
8043 "It is allowed only within the statement blocks of functions, "
8044 "altsteps and testcases");
8047 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8048 // folding is possible only within testcases
8049 set_val_str(new string(my_def
->get_id().get_dispname()));
8054 FATAL_ERROR("Value::evaluate_macro()");
8058 set_valuetype(V_ERROR
);
8061 void Value::add_id(Identifier
*p_id
)
8065 if(u
.ids
->has_key(p_id
->get_name())) {
8066 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8067 // The Value does not take ownership for the identifier,
8068 // so it must be deleted (add_is acts as a sink).
8071 else u
.ids
->add(p_id
->get_name(), p_id
);
8074 FATAL_ERROR("Value::add_id()");
8078 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8079 Type::expected_value_t exp_val
)
8081 set_lowerid_to_ref();
8082 switch (valuetype
) {
8084 // there might be a better place for this
8085 chk_invoke(exp_val
);
8088 // use the cache if available
8089 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8091 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8093 // the referred definition is not found
8094 set_valuetype(V_ERROR
);
8096 switch (ass
->get_asstype()) {
8097 case Assignment::A_OBJECT
:
8098 case Assignment::A_OS
: {
8099 // the referred definition is an ASN.1 object or object set
8100 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8101 if (!setting
|| setting
->get_st() == S_ERROR
) {
8102 // remain silent, the error has been already reported
8103 set_valuetype(V_ERROR
);
8105 } else if (setting
->get_st() != S_V
) {
8106 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8107 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8108 set_valuetype(V_ERROR
);
8113 refch
->mark_state();
8114 destroy_refch
= false;
8116 refch
= new ReferenceChain(this,
8117 "While searching referenced value");
8118 destroy_refch
= true;
8120 if (refch
->add(get_fullname())) {
8121 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8122 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8123 // in case of circular recursion the valuetype is already set
8124 // to V_ERROR, so don't set the cache
8125 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8127 // a circular recursion was detected
8128 set_valuetype(V_ERROR
);
8130 if (destroy_refch
) delete refch
;
8131 else refch
->prev_state();
8133 case Assignment::A_CONST
: {
8134 // the referred definition is a constant
8137 refch
->mark_state();
8138 destroy_refch
= false;
8140 refch
= new ReferenceChain(this,
8141 "While searching referenced value");
8142 destroy_refch
= true;
8144 if (refch
->add(get_fullname())) {
8145 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8146 Value
*v_refd
= ass
->get_Value()
8147 ->get_refd_sub_value(subrefs
, 0,
8148 u
.ref
.ref
->getUsedInIsbound(), refch
);
8150 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8151 // in case of circular recursion the valuetype is already set
8152 // to V_ERROR, so don't set the cache
8153 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8154 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8155 u
.ref
.refd_last
= this;
8156 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8157 u
.ref
.refd_last
= this;
8159 // the sub-reference points to a non-existent field
8160 set_valuetype(V_ERROR
);
8163 // a circular recursion was detected
8164 set_valuetype(V_ERROR
);
8166 if (destroy_refch
) delete refch
;
8167 else refch
->prev_state();
8169 case Assignment::A_EXT_CONST
:
8170 case Assignment::A_MODULEPAR
:
8171 case Assignment::A_VAR
:
8172 case Assignment::A_FUNCTION_RVAL
:
8173 case Assignment::A_EXT_FUNCTION_RVAL
:
8174 case Assignment::A_PAR_VAL_IN
:
8175 case Assignment::A_PAR_VAL_OUT
:
8176 case Assignment::A_PAR_VAL_INOUT
:
8177 // the referred definition is not a constant
8178 u
.ref
.refd_last
= this;
8180 case Assignment::A_FUNCTION
:
8181 case Assignment::A_EXT_FUNCTION
:
8182 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8183 "call of %s, which does not have return type",
8184 ass
->get_description().c_str());
8185 set_valuetype(V_ERROR
);
8187 case Assignment::A_FUNCTION_RTEMP
:
8188 case Assignment::A_EXT_FUNCTION_RTEMP
:
8189 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8190 "call of %s, which returns a template",
8191 ass
->get_description().c_str());
8192 set_valuetype(V_ERROR
);
8195 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8196 ass
->get_description().c_str());
8197 set_valuetype(V_ERROR
);
8200 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8204 // try to evaluate the expression
8207 refch
->mark_state();
8208 destroy_refch
=false;
8211 refch
=new ReferenceChain(this, "While evaluating expression");
8214 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8215 else set_valuetype(V_ERROR
);
8216 if(destroy_refch
) delete refch
;
8217 else refch
->prev_state();
8220 evaluate_macro(exp_val
);
8223 // return this for all other value types
8228 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8230 /* Note that the logic here needs to be in sync with evaluate_value,
8231 * and possibly others, i.e. if evaluate_value is called for a Value
8232 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8233 bool Value::is_unfoldable(ReferenceChain
*refch
,
8234 Type::expected_value_t exp_val
)
8236 if (UnfoldabilityCheck::is_running(this)) {
8237 // This function is already running on this value => infinite recursion
8241 UnfoldabilityCheck
checker(this);
8243 if (get_needs_conversion()) return true;
8244 switch (valuetype
) {
8248 case V_UNDEF_LOWERID
:
8252 // these value types are eliminated during semantic analysis
8253 FATAL_ERROR("Value::is_unfoldable()");
8258 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8262 if (!is_indexed()) {
8263 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8264 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8268 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8269 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8276 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8277 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8278 ->is_unfoldable(refch
, exp_val
)) return true;
8284 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8285 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8289 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8290 if(v_last
==this) return true; // there weren't any references to chase
8291 else return v_last
->is_unfoldable(refch
, exp_val
);
8294 // classify the unchecked ischosen() operation, if it was not done so far
8295 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8296 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8297 switch (u
.expr
.v_optype
) {
8298 case OPTYPE_RND
: // -
8299 case OPTYPE_COMP_MTC
:
8300 case OPTYPE_COMP_SYSTEM
:
8301 case OPTYPE_COMP_SELF
:
8302 case OPTYPE_COMP_RUNNING_ANY
:
8303 case OPTYPE_COMP_RUNNING_ALL
:
8304 case OPTYPE_COMP_ALIVE_ANY
:
8305 case OPTYPE_COMP_ALIVE_ALL
:
8306 case OPTYPE_TMR_RUNNING_ANY
:
8307 case OPTYPE_GETVERDICT
:
8308 case OPTYPE_TESTCASENAME
:
8309 case OPTYPE_PROF_RUNNING
:
8310 case OPTYPE_RNDWITHVAL
: // v1
8311 case OPTYPE_MATCH
: // v1 t2
8312 case OPTYPE_UNDEF_RUNNING
: // v1
8313 case OPTYPE_COMP_RUNNING
:
8314 case OPTYPE_COMP_ALIVE
:
8315 case OPTYPE_TMR_READ
:
8316 case OPTYPE_TMR_RUNNING
:
8317 case OPTYPE_ACTIVATE
:
8318 case OPTYPE_ACTIVATE_REFD
:
8319 case OPTYPE_EXECUTE
: // r1 [v2]
8320 case OPTYPE_EXECUTE_REFD
:
8321 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8322 case OPTYPE_ISCHOSEN
:
8323 case OPTYPE_ISCHOSEN_T
:
8324 case OPTYPE_SIZEOF
: // ti1
8327 case OPTYPE_OCT2UNICHAR
:
8328 case OPTYPE_UNICHAR2OCT
:
8329 case OPTYPE_ENCODE_BASE64
:
8330 case OPTYPE_DECODE_BASE64
:
8332 case OPTYPE_COMP_NULL
: // -
8334 case OPTYPE_UNARYPLUS
: // v1
8335 case OPTYPE_UNARYMINUS
:
8338 case OPTYPE_BIT2HEX
:
8339 case OPTYPE_BIT2INT
:
8340 case OPTYPE_BIT2OCT
:
8341 case OPTYPE_BIT2STR
:
8342 case OPTYPE_CHAR2INT
:
8343 case OPTYPE_CHAR2OCT
:
8344 case OPTYPE_FLOAT2INT
:
8345 case OPTYPE_FLOAT2STR
:
8346 case OPTYPE_HEX2BIT
:
8347 case OPTYPE_HEX2INT
:
8348 case OPTYPE_HEX2OCT
:
8349 case OPTYPE_HEX2STR
:
8350 case OPTYPE_INT2CHAR
:
8351 case OPTYPE_INT2FLOAT
:
8352 case OPTYPE_INT2STR
:
8353 case OPTYPE_INT2UNICHAR
:
8354 case OPTYPE_OCT2BIT
:
8355 case OPTYPE_OCT2CHAR
:
8356 case OPTYPE_OCT2HEX
:
8357 case OPTYPE_OCT2INT
:
8358 case OPTYPE_OCT2STR
:
8359 case OPTYPE_STR2BIT
:
8360 case OPTYPE_STR2FLOAT
:
8361 case OPTYPE_STR2HEX
:
8362 case OPTYPE_STR2INT
:
8363 case OPTYPE_STR2OCT
:
8364 case OPTYPE_UNICHAR2INT
:
8365 case OPTYPE_UNICHAR2CHAR
:
8366 case OPTYPE_ENUM2INT
:
8367 case OPTYPE_GET_STRINGENCODING
:
8368 case OPTYPE_REMOVE_BOM
:
8369 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8370 case OPTYPE_ISBOUND
: /*{
8371 //TODO once we have the time for it make isbound foldable.
8372 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8373 Template* temp = u.expr.ti1->get_Template();
8374 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8375 Value* specificValue = temp->get_specific_value();
8376 if (specificValue->get_valuetype() == Value::V_REFD) {
8380 return specificValue->is_unfoldable(refch, exp_val);
8381 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8386 case OPTYPE_ISPRESENT
:
8387 // TODO: "if you have motivation"
8389 case OPTYPE_ISVALUE
: // ti1
8391 case OPTYPE_LENGTHOF
: // ti1
8392 return u
.expr
.ti1
->get_DerivedRef() != 0
8393 || u
.expr
.ti1
->get_Template()->get_templatetype()
8394 != Template::SPECIFIC_VALUE
8395 || u
.expr
.ti1
->get_Template()->get_specific_value()
8396 ->is_unfoldable(refch
, exp_val
);
8400 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8402 case OPTYPE_ADD
: // v1 v2
8403 case OPTYPE_SUBTRACT
:
8404 case OPTYPE_MULTIPLY
:
8420 case OPTYPE_INT2BIT
:
8421 case OPTYPE_INT2HEX
:
8422 case OPTYPE_INT2OCT
:
8423 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8424 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8425 case OPTYPE_AND
: // short-circuit evaluation
8426 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8427 || (u
.expr
.v1
->get_val_bool() &&
8428 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8429 case OPTYPE_OR
: // short-circuit evaluation
8430 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8431 || (!u
.expr
.v1
->get_val_bool() &&
8432 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8434 if (!u
.expr
.ti1
->get_specific_value()) return true;
8435 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8436 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8437 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8438 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8440 if (!u
.expr
.ti1
->get_specific_value() ||
8441 !u
.expr
.t2
->get_specific_value()) return true;
8442 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8443 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8444 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8446 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8447 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8448 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8449 case OPTYPE_REPLACE
: {
8450 if (!u
.expr
.ti1
->get_specific_value() ||
8451 !u
.expr
.ti4
->get_specific_value()) return true;
8452 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8453 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8454 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8455 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8456 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8458 case OPTYPE_VALUEOF
: // ti1
8459 /* \todo if you have motivation to implement the eval function
8462 case OPTYPE_ISCHOSEN_V
:
8463 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8464 case OPTYPE_LOG2STR
:
8465 case OPTYPE_TTCN2STRING
:
8468 FATAL_ERROR("Value::is_unfoldable()");
8470 break; // should never get here
8473 case MACRO_TESTCASEID
:
8474 // this is known only at runtime
8480 // all literal values are foldable
8485 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8486 size_t start_i
, bool usedInIsbound
,
8487 ReferenceChain
*refch
)
8489 if (!subrefs
) return this;
8491 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8493 v
= v
->get_value_refd_last(refch
);
8494 switch(v
->valuetype
) {
8503 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8504 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8505 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8506 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8511 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8512 bool usedInIsbound
, const Location
& loc
)
8514 if (valuetype
== V_OMIT
) {
8515 loc
.error("Reference to field `%s' of omit value `%s'",
8516 field_id
.get_dispname().c_str(), get_fullname().c_str());
8519 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8520 Type
*t
= my_governor
->get_type_refd_last();
8521 switch (t
->get_typetype()) {
8525 case Type::T_CHOICE_A
:
8526 case Type::T_CHOICE_T
:
8527 case Type::T_OPENTYPE
:
8528 case Type::T_ANYTYPE
:
8529 if (!t
->has_comp_withName(field_id
)) {
8530 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8531 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8533 } else if (valuetype
!= V_CHOICE
) {
8534 // remain silent, the error is already reported
8536 } else if (*u
.choice
.alt_name
== field_id
) {
8538 return u
.choice
.alt_value
;
8540 if (!usedInIsbound
) {
8541 loc
.error("Reference to inactive field `%s' in a value of union type "
8542 "`%s'. The active field is `%s'",
8543 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8544 u
.choice
.alt_name
->get_dispname().c_str());
8550 if (!t
->has_comp_withName(field_id
)) {
8551 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8552 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8554 } else if (valuetype
!= V_SEQ
) {
8555 // remain silent, the error has been already reported
8560 if (!t
->has_comp_withName(field_id
)) {
8561 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8562 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8564 } else if (valuetype
!= V_SET
) {
8565 // remain silent, the error has been already reported
8569 loc
.error("Invalid field reference `%s': type `%s' "
8570 "does not have fields", field_id
.get_dispname().c_str(),
8571 t
->get_typename().c_str());
8574 // the common end for record & set types
8575 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8577 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8578 } else if (!is_asn1()) {
8579 if (!usedInIsbound
) {
8580 loc
.error("Reference to unbound field `%s'",
8581 field_id
.get_dispname().c_str());
8582 // this is an error in TTCN-3, which has been already reported
8586 CompField
*cf
= t
->get_comp_byName(field_id
);
8587 if (cf
->get_is_optional()) {
8588 // creating an explicit omit value
8589 Value
*v
= new Value(V_OMIT
);
8590 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8591 v
->set_my_scope(get_my_scope());
8592 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8594 } else if (cf
->has_default()) {
8595 // returning the component's default value
8596 return cf
->get_defval();
8598 // this is an error in ASN.1, which has been already reported
8604 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8605 ReferenceChain
*refch
)
8607 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8609 bool index_available
= false;
8610 if (!v_index
->is_unfoldable()) {
8611 if (v_index
->valuetype
== V_INT
) {
8612 index
= v_index
->get_val_Int()->get_val();
8613 index_available
= true;
8615 array_index
->error("An integer value was expected as index");
8618 if (valuetype
== V_OMIT
) {
8619 array_index
->error("Accessing an element with index of omit value `%s'",
8620 get_fullname().c_str());
8623 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8624 Type
*t
= my_governor
->get_type_refd_last();
8625 switch (t
->get_typetype()) {
8630 if (index_available
) {
8632 array_index
->error("A non-negative integer value was expected "
8633 "instead of %s for indexing a value of `record "
8634 "of' type `%s'", Int2string(index
).c_str(),
8635 t
->get_typename().c_str());
8638 switch (valuetype
) {
8640 if (!is_indexed()) {
8641 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8642 if (!usedInIsbound
) {
8643 array_index
->error("Index overflow in a value of `record of' "
8644 "type `%s': the index is %s, but the value "
8645 "has only %lu elements",
8646 t
->get_typename().c_str(),
8647 Int2string(index
).c_str(),
8648 (unsigned long)u
.val_vs
->get_nof_vs());
8652 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8653 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8654 temp
->error("Not used symbol is not allowed in this context");
8655 return u
.val_vs
->get_v_byIndex(index
);
8658 // Search the appropriate constant index.
8659 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8660 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8661 ->get_value_refd_last();
8662 if (iv_index
->get_valuetype() != V_INT
) continue;
8663 if (iv_index
->get_val_Int()->get_val() == index
)
8664 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8670 // remain silent, the error has been already reported
8674 // the error has been reported above
8678 if (index_available
) {
8680 array_index
->error("A non-negative integer value was expected "
8681 "instead of %s for indexing a value of `set of' type `%s'",
8682 Int2string(index
).c_str(), t
->get_typename().c_str());
8685 switch (valuetype
) {
8687 if (!is_indexed()) {
8688 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8689 if (!usedInIsbound
) {
8690 array_index
->error("Index overflow in a value of `set of' type "
8691 "`%s': the index is %s, but the value has "
8692 "only %lu elements",
8693 t
->get_typename().c_str(),
8694 Int2string(index
).c_str(),
8695 (unsigned long)u
.val_vs
->get_nof_vs());
8699 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8700 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8701 temp
->error("Not used symbol is not allowed in this context");
8705 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8706 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8707 ->get_value_refd_last();
8708 if (iv_index
->get_valuetype() != V_INT
) continue;
8709 if (iv_index
->get_val_Int()->get_val() == index
)
8710 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8716 // remain silent, the error has been already reported
8720 // the error has been reported above
8724 if (index_available
) {
8725 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8726 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8727 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8728 // perform the index transformation
8729 index
-= dim
->get_offset();
8730 if (!is_indexed()) {
8731 // check for index underflow/overflow or too few elements in the
8734 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8736 else return u
.val_vs
->get_v_byIndex(index
);
8738 if (index
< 0) return 0;
8739 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8740 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8741 ->get_value_refd_last();
8742 if (iv_index
->get_valuetype() != V_INT
) continue;
8743 if (iv_index
->get_val_Int()->get_val() == index
)
8744 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8749 // remain silent, the error has been already reported
8753 // the error has been reported above
8757 case Type::T_BSTR_A
:
8762 case Type::T_UTF8STRING
:
8763 case Type::T_NUMERICSTRING
:
8764 case Type::T_PRINTABLESTRING
:
8765 case Type::T_TELETEXSTRING
:
8766 case Type::T_VIDEOTEXSTRING
:
8767 case Type::T_IA5STRING
:
8768 case Type::T_GRAPHICSTRING
:
8769 case Type::T_VISIBLESTRING
:
8770 case Type::T_GENERALSTRING
:
8771 case Type::T_UNIVERSALSTRING
:
8772 case Type::T_BMPSTRING
:
8773 case Type::T_UTCTIME
:
8774 case Type::T_GENERALIZEDTIME
:
8775 case Type::T_OBJECTDESCRIPTOR
:
8776 if (index_available
) return get_string_element(index
, *array_index
);
8779 array_index
->error("Invalid array element reference: type `%s' cannot "
8780 "be indexed", t
->get_typename().c_str());
8785 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8788 loc
.error("A non-negative integer value was expected instead of %s "
8789 "for indexing a string element", Int2string(index
).c_str());
8792 size_t string_length
;
8793 switch (valuetype
) {
8798 string_length
= u
.str
.val_str
->size();
8801 string_length
= u
.str
.val_str
->size() / 2;
8804 string_length
= u
.ustr
.val_ustr
->size();
8807 // remain silent, the error has been already reported
8810 if (index
>= static_cast<Int
>(string_length
)) {
8811 loc
.error("Index overflow when accessing a string element: "
8812 "the index is %s, but the string has only %lu elements",
8813 Int2string(index
).c_str(), (unsigned long) string_length
);
8816 switch (valuetype
) {
8821 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8822 return (*u
.str
.str_elements
)[index
];
8824 Value
*t_val
= new Value(valuetype
,
8825 new string(u
.str
.val_str
->substr(index
, 1)));
8826 add_string_element(index
, t_val
, u
.str
.str_elements
);
8830 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8831 return (*u
.str
.str_elements
)[index
];
8833 Value
*t_val
= new Value(V_OSTR
,
8834 new string(u
.str
.val_str
->substr(2 * index
, 2)));
8835 add_string_element(index
, t_val
, u
.str
.str_elements
);
8839 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
8840 return (*u
.ustr
.ustr_elements
)[index
];
8842 Value
*t_val
= new Value(V_USTR
,
8843 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
8844 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
8848 FATAL_ERROR("Value::get_string_element()");
8853 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
8854 Type::expected_value_t exp_val
)
8856 set_lowerid_to_ref();
8857 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
8858 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
8860 error("A value or expression of type %s was expected", type_name
);
8861 if (valuetype
== V_REFD
) {
8862 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
8863 t_chk
->chk_this_refd_value(this, 0, exp_val
);
8865 get_value_refd_last(0, exp_val
);
8866 if (error_flag
) set_valuetype(V_ERROR
);
8867 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
8870 int Value::is_parsed_infinity()
8872 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
8874 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
8875 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
8876 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
8881 bool Value::get_val_bool()
8884 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8886 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
8887 return v
->u
.val_bool
;
8890 int_val_t
* Value::get_val_Int()
8893 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8895 switch (v
->valuetype
) {
8898 case V_UNDEF_LOWERID
:
8899 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8900 "`%s'", (*u
.val_id
).get_dispname().c_str());
8902 FATAL_ERROR("Value::get_val_Int()");
8904 return v
->u
.val_Int
;
8907 const Identifier
* Value::get_val_id()
8912 case V_UNDEF_LOWERID
:
8915 FATAL_ERROR("Value::get_val_id()");
8920 const ttcn3float
& Value::get_val_Real()
8923 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8925 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
8926 return v
->u
.val_Real
;
8929 string
Value::get_val_str()
8931 Value
*v
= get_value_refd_last();
8932 switch (v
->valuetype
) {
8937 return *v
->u
.str
.val_str
;
8939 return v
->u
.char_syms
->get_string();
8941 error("Cannot use ISO-10646 string value in string context");
8944 error("Cannot use ISO-2022 string value in string context");
8949 error("Cannot use this value in charstring value context");
8954 ustring
Value::get_val_ustr()
8956 Value
*v
= get_value_refd_last();
8957 switch (v
->valuetype
) {
8959 return ustring(*v
->u
.str
.val_str
);
8961 return *v
->u
.ustr
.val_ustr
;
8963 return v
->u
.char_syms
->get_ustring();
8965 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8970 error("Cannot use this value in ISO-10646 string context");
8975 string
Value::get_val_iso2022str()
8977 Value
*v
= get_value_refd_last();
8978 switch (v
->valuetype
) {
8981 return *v
->u
.str
.val_str
;
8983 return v
->u
.char_syms
->get_iso2022string();
8985 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8990 error("Cannot use this value in ISO-2022 string context");
8995 size_t Value::get_val_strlen()
8997 Value
*v
= get_value_refd_last();
8998 switch (v
->valuetype
) {
9003 return v
->u
.str
.val_str
->size();
9005 return v
->u
.str
.val_str
->size()/2;
9007 return v
->u
.char_syms
->get_len();
9009 return v
->u
.ustr
.val_ustr
->size();
9013 error("Cannot use this value in string value context");
9018 Value::verdict_t
Value::get_val_verdict()
9024 FATAL_ERROR("Value::get_val_verdict()");
9029 size_t Value::get_nof_comps()
9031 switch (valuetype
) {
9035 return u
.oid_comps
->size();
9039 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9040 else return u
.val_vs
->get_nof_vs();
9043 return u
.val_nvs
->get_nof_nvs();
9048 return u
.str
.val_str
->size();
9050 return u
.str
.val_str
->size()/2;
9052 return u
.ustr
.val_ustr
->size();
9054 FATAL_ERROR("Value::get_nof_comps()");
9059 bool Value::is_indexed() const
9061 switch (valuetype
) {
9065 // Applicable only for list-types. Assigning a record/SEQUENCE or
9066 // set/SET with indexed notation is not supported.
9067 return u
.val_vs
->is_indexed();
9069 FATAL_ERROR("Value::is_indexed()");
9075 const Identifier
& Value::get_alt_name()
9077 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9078 return *u
.choice
.alt_name
;
9081 Value
*Value::get_alt_value()
9083 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9084 return u
.choice
.alt_value
;
9087 void Value::set_alt_name_to_lowercase()
9089 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9090 string new_name
= u
.choice
.alt_name
->get_name();
9091 if (isupper(new_name
[0])) {
9092 new_name
[0] = tolower(new_name
[0]);
9093 if (new_name
[new_name
.size() - 1] == '_') {
9094 // an underscore is inserted at the end of the alternative name if it's
9095 // a basic type's name (since it would conflict with the class generated
9097 // remove the underscore, it won't conflict with anything if its name
9098 // starts with a lowercase letter
9099 new_name
.replace(new_name
.size() - 1, 1, "");
9101 delete u
.choice
.alt_name
;
9102 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9106 bool Value::has_oid_error()
9109 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9111 switch (valuetype
) {
9114 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9115 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9122 bool Value::get_oid_comps(vector
<string
>& comps
)
9124 bool ret_val
= true;
9126 switch (valuetype
) {
9128 v
= get_value_refd_last();
9132 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9133 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9134 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9135 // not all components can be calculated in compile-time
9141 FATAL_ERROR("Value::get_oid_comps()");
9146 void Value::add_se_comp(NamedValue
* nv
) {
9147 switch (valuetype
) {
9151 u
.val_nvs
= new NamedValues();
9152 u
.val_nvs
->add_nv(nv
);
9155 FATAL_ERROR("Value::add_se_comp()");
9159 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9164 return u
.val_nvs
->get_nv_byIndex(n
);
9166 FATAL_ERROR("Value::get_se_comp_byIndex()");
9171 Value
*Value::get_comp_byIndex(size_t n
)
9173 switch (valuetype
) {
9177 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9178 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9180 FATAL_ERROR("Value::get_comp_byIndex()");
9185 Value
*Value::get_index_byIndex(size_t n
)
9187 switch (valuetype
) {
9191 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9192 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9194 FATAL_ERROR("Value::get_index_byIndex()");
9199 bool Value::has_comp_withName(const Identifier
& p_name
)
9204 return u
.val_nvs
->has_nv_withName(p_name
);
9206 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9208 FATAL_ERROR("Value::get_has_comp_withName()");
9213 bool Value::field_is_chosen(const Identifier
& p_name
)
9215 Value
*v
=get_value_refd_last();
9216 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9217 return *v
->u
.choice
.alt_name
==p_name
;
9220 bool Value::field_is_present(const Identifier
& p_name
)
9222 Value
*v
=get_value_refd_last();
9223 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9224 FATAL_ERROR("Value::field_is_present()");
9225 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9226 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9227 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9230 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9235 return u
.val_nvs
->get_nv_byName(p_name
);
9237 FATAL_ERROR("Value::get_se_comp_byName()");
9242 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9247 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9249 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9250 return u
.choice
.alt_value
;
9254 FATAL_ERROR("Value::get_se_comp_byName()");
9259 void Value::chk_dupl_id()
9264 u
.val_nvs
->chk_dupl_id();
9267 FATAL_ERROR("Value::chk_dupl_id()");
9271 size_t Value::get_nof_ids() const
9275 return u
.ids
->size();
9278 FATAL_ERROR("Value::get_nof_ids()");
9283 Identifier
* Value::get_id_byIndex(size_t p_i
)
9287 return u
.ids
->get_nth_elem(p_i
);
9290 FATAL_ERROR("Value::get_id_byIndex()");
9295 bool Value::has_id(const Identifier
& p_id
)
9299 return u
.ids
->has_key(p_id
.get_name());
9302 FATAL_ERROR("Value::has_id()");
9307 Reference
*Value::get_reference() const
9309 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9313 Reference
*Value::get_refered() const
9315 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9319 Common::Assignment
*Value::get_refd_fat() const
9327 FATAL_ERROR("Value::get_refd_fat()");
9331 Ttcn::Reference
* Value::steal_ttcn_ref()
9333 Ttcn::Reference
*ret_val
=
9334 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9335 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9339 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9341 Ttcn::Ref_base
*t_ref
;
9342 if(valuetype
==V_REFD
) {
9343 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9344 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9347 else if(valuetype
==V_UNDEF_LOWERID
) {
9348 t_ref
=new Ttcn::Reference(u
.val_id
);
9349 t_ref
->set_location(*this);
9350 t_ref
->set_fullname(get_fullname());
9351 t_ref
->set_my_scope(get_my_scope());
9355 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9358 set_valuetype(V_ERROR
);
9362 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9363 Ttcn::ActualParList
*& p_ap
)
9365 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9368 p_ti
= u
.invoke
.t_list
;
9369 u
.invoke
.t_list
= 0;
9370 p_ap
= u
.invoke
.ap_list
;
9371 u
.invoke
.ap_list
= 0;
9372 set_valuetype(V_ERROR
);
9375 Common::Assignment
* Value::get_refd_assignment()
9384 FATAL_ERROR("Value::get_refd_assignment()");
9394 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9399 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9408 void Value::chk_OID(ReferenceChain
& refch
)
9410 if (checked
) return;
9411 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9412 FATAL_ERROR("Value::chk_OID()");
9413 if (!refch
.add(get_fullname())) {
9417 OID_comp::oidstate_t state
= OID_comp::START
;
9418 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9420 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9423 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9424 error("An OBJECT IDENTIFIER value must have at least "
9425 "two components"); // X.680 (07/2002) 31.10
9428 void Value::chk_ROID(ReferenceChain
& refch
)
9430 if (checked
) return;
9431 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9432 FATAL_ERROR("Value::chk_ROID()");
9433 if (!refch
.add(get_fullname())) {
9437 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9439 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9444 void Value::chk_recursions(ReferenceChain
& refch
)
9446 if (recurs_checked
) return;
9447 Value
*v
= get_value_refd_last();
9448 if (refch
.add(v
->get_fullname())) {
9449 switch (v
->valuetype
) {
9451 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9456 if (!v
->is_indexed()) {
9457 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9459 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9463 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9465 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9466 ->chk_recursions(refch
);
9473 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9475 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9480 chk_recursions_expr(refch
);
9485 if (v
->err_descr
) { // FIXME: make this work
9486 v
->err_descr
->chk_recursions(refch
);
9489 recurs_checked
= true;
9492 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9494 // first classify the unchecked ischosen() operation
9495 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9496 switch (u
.expr
.v_optype
) {
9497 case OPTYPE_UNARYPLUS
: // v1
9498 case OPTYPE_UNARYMINUS
:
9501 case OPTYPE_BIT2HEX
:
9502 case OPTYPE_BIT2INT
:
9503 case OPTYPE_BIT2OCT
:
9504 case OPTYPE_BIT2STR
:
9505 case OPTYPE_CHAR2INT
:
9506 case OPTYPE_CHAR2OCT
:
9507 case OPTYPE_FLOAT2INT
:
9508 case OPTYPE_FLOAT2STR
:
9509 case OPTYPE_HEX2BIT
:
9510 case OPTYPE_HEX2INT
:
9511 case OPTYPE_HEX2OCT
:
9512 case OPTYPE_HEX2STR
:
9513 case OPTYPE_INT2CHAR
:
9514 case OPTYPE_INT2FLOAT
:
9515 case OPTYPE_INT2STR
:
9516 case OPTYPE_INT2UNICHAR
:
9517 case OPTYPE_OCT2BIT
:
9518 case OPTYPE_OCT2CHAR
:
9519 case OPTYPE_OCT2HEX
:
9520 case OPTYPE_OCT2INT
:
9521 case OPTYPE_OCT2STR
:
9522 case OPTYPE_STR2BIT
:
9523 case OPTYPE_STR2FLOAT
:
9524 case OPTYPE_STR2HEX
:
9525 case OPTYPE_STR2INT
:
9526 case OPTYPE_STR2OCT
:
9527 case OPTYPE_UNICHAR2INT
:
9528 case OPTYPE_ENUM2INT
:
9529 case OPTYPE_UNICHAR2CHAR
:
9530 case OPTYPE_RNDWITHVAL
:
9531 case OPTYPE_ISCHOSEN_V
:
9532 case OPTYPE_GET_STRINGENCODING
:
9533 case OPTYPE_REMOVE_BOM
:
9534 case OPTYPE_DECODE_BASE64
:
9536 u
.expr
.v1
->chk_recursions(refch
);
9539 case OPTYPE_ISCHOSEN_T
:
9541 u
.expr
.t1
->chk_recursions(refch
);
9544 case OPTYPE_ADD
: // v1 v2
9545 case OPTYPE_SUBTRACT
:
9546 case OPTYPE_MULTIPLY
:
9567 case OPTYPE_INT2BIT
:
9568 case OPTYPE_INT2HEX
:
9569 case OPTYPE_INT2OCT
:
9571 u
.expr
.v1
->chk_recursions(refch
);
9574 u
.expr
.v2
->chk_recursions(refch
);
9577 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9578 case OPTYPE_OCT2UNICHAR
:
9579 case OPTYPE_ENCODE_BASE64
:
9581 u
.expr
.v1
->chk_recursions(refch
);
9585 u
.expr
.v2
->chk_recursions(refch
);
9590 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9591 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9595 u
.expr
.ti1
->chk_recursions(refch
);
9598 u
.expr
.v2
->chk_recursions(refch
);
9601 u
.expr
.v3
->chk_recursions(refch
);
9606 u
.expr
.ti1
->chk_recursions(refch
);
9609 u
.expr
.t2
->chk_recursions(refch
);
9612 u
.expr
.v3
->chk_recursions(refch
);
9615 case OPTYPE_DECOMP
: // v1 v2 v3
9617 u
.expr
.v1
->chk_recursions(refch
);
9620 u
.expr
.v2
->chk_recursions(refch
);
9623 u
.expr
.v3
->chk_recursions(refch
);
9626 case OPTYPE_REPLACE
:
9628 u
.expr
.ti1
->chk_recursions(refch
);
9631 u
.expr
.v2
->chk_recursions(refch
);
9634 u
.expr
.v3
->chk_recursions(refch
);
9637 u
.expr
.ti4
->chk_recursions(refch
);
9640 case OPTYPE_LENGTHOF
: // ti1
9641 case OPTYPE_SIZEOF
: // ti1
9642 case OPTYPE_VALUEOF
: // ti1
9644 case OPTYPE_ISPRESENT
:
9645 case OPTYPE_TTCN2STRING
:
9647 u
.expr
.ti1
->chk_recursions(refch
);
9650 case OPTYPE_MATCH
: // v1 t2
9652 u
.expr
.v1
->chk_recursions(refch
);
9655 u
.expr
.t2
->chk_recursions(refch
);
9658 case OPTYPE_LOG2STR
:
9659 u
.expr
.logargs
->chk_recursions(refch
);
9666 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9667 ReferenceChain
& refch
) {
9668 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9669 Assignment
*ass
= ref
->get_refd_assignment();
9671 set_valuetype(V_ERROR
);
9674 switch (ass
->get_asstype()) {
9675 case Assignment::A_CONST
:
9676 case Assignment::A_EXT_CONST
:
9677 case Assignment::A_MODULEPAR
:
9678 case Assignment::A_VAR
:
9679 case Assignment::A_PAR_VAL_IN
:
9680 case Assignment::A_PAR_VAL_OUT
:
9681 case Assignment::A_PAR_VAL_INOUT
: {
9682 Value
* v
= new Value(V_REFD
, ref
);
9683 v
->set_location(*ref
);
9684 v
->set_my_scope(get_my_scope());
9685 v
->set_fullname(get_fullname()+".<operand>");
9687 v
->chk_recursions(refch
);
9691 case Assignment::A_MODULEPAR_TEMP
:
9692 case Assignment::A_TEMPLATE
:
9693 case Assignment::A_VAR_TEMPLATE
:
9694 case Assignment::A_PAR_TEMPL_IN
:
9695 case Assignment::A_PAR_TEMPL_OUT
:
9696 case Assignment::A_PAR_TEMPL_INOUT
: {
9697 Template
* t
= new Template(ref
->clone());
9698 t
->set_location(*ref
);
9699 t
->set_my_scope(get_my_scope());
9700 t
->set_fullname(get_fullname()+".<operand>");
9702 t
->chk_recursions(refch
);
9707 // remain silent, the error has been already reported
9708 set_valuetype(V_ERROR
);
9713 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9715 bool self_ref
= false;
9716 switch (t
->get_templatetype()) {
9717 case Ttcn::Template::SPECIFIC_VALUE
: {
9718 Value
*v
= t
->get_specific_value();
9719 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9720 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9721 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9723 case Ttcn::Template::TEMPLATE_REFD
: {
9724 Ttcn::Ref_base
*refb
= t
->get_reference();
9725 Common::Assignment
*ass
= refb
->get_refd_assignment();
9726 self_ref
|= (ass
== lhs
);
9728 case Ttcn::Template::ALL_FROM
:
9729 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9730 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9732 case Ttcn::Template::TEMPLATE_LIST
:
9733 case Ttcn::Template::SUPERSET_MATCH
:
9734 case Ttcn::Template::SUBSET_MATCH
:
9735 case Ttcn::Template::PERMUTATION_MATCH
:
9736 case Ttcn::Template::COMPLEMENTED_LIST
:
9737 case Ttcn::Template::VALUE_LIST
: {
9738 size_t num
= t
->get_nof_comps();
9739 for (size_t i
= 0; i
< num
; ++i
) {
9740 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9743 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9744 // case Ttcn::Template::TEMPLATE_LIST: {
9745 // size_t num = t->get_nof_listitems();
9746 // for (size_t i=0; i < num; ++i) {
9747 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9750 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9751 size_t nnt
= t
->get_nof_comps();
9752 for (size_t i
=0; i
< nnt
; ++i
) {
9753 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9754 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9757 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9758 size_t nnt
= t
->get_nof_comps();
9759 for (size_t i
=0; i
< nnt
; ++i
) {
9760 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9761 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9764 case Ttcn::Template::VALUE_RANGE
: {
9765 Ttcn::ValueRange
*vr
= t
->get_value_range();
9766 Common::Value
*v
= vr
->get_min_v();
9767 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9768 v
= vr
->get_max_v();
9769 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9771 case Ttcn::Template::CSTR_PATTERN
:
9772 case Ttcn::Template::USTR_PATTERN
: {
9773 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9774 self_ref
|= ps
->chk_self_ref(lhs
);
9776 case Ttcn::Template::BSTR_PATTERN
:
9777 case Ttcn::Template::HSTR_PATTERN
:
9778 case Ttcn::Template::OSTR_PATTERN
: {
9779 // FIXME: cannot access u.pattern
9781 case Ttcn::Template::ANY_VALUE
:
9782 case Ttcn::Template::ANY_OR_OMIT
:
9783 case Ttcn::Template::OMIT_VALUE
:
9784 case Ttcn::Template::TEMPLATE_NOTUSED
:
9785 break; // self-ref can't happen
9786 case Ttcn::Template::TEMPLATE_INVOKE
:
9787 break; // assume self-ref can't happen
9788 case Ttcn::Template::TEMPLATE_ERROR
:
9789 FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9790 break; // not reached
9792 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9793 // break; // and hope for the best
9798 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
9800 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
9801 namedbool is_str_elem
= NOT_STR_ELEM
;
9802 if (v
->valuetype
== V_REFD
) {
9803 Reference
*ref
= v
->get_reference();
9804 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
9805 if (subrefs
&& subrefs
->refers_to_string_element()) {
9806 is_str_elem
= IS_STR_ELEM
;
9809 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9810 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
9814 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
9816 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
9817 if (!lhs
) FATAL_ERROR("no lhs!");
9818 bool self_ref
= false;
9819 switch (u
.expr
.v_optype
) {
9820 case OPTYPE_RND
: // -
9821 case OPTYPE_TESTCASENAME
: // -
9822 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
9823 case OPTYPE_COMP_MTC
: // -
9824 case OPTYPE_COMP_SYSTEM
: // -
9825 case OPTYPE_COMP_SELF
: // -
9826 case OPTYPE_COMP_RUNNING_ANY
: // -
9827 case OPTYPE_COMP_RUNNING_ALL
: // -
9828 case OPTYPE_COMP_ALIVE_ANY
: // -
9829 case OPTYPE_COMP_ALIVE_ALL
: // -
9830 case OPTYPE_TMR_RUNNING_ANY
: // -
9831 case OPTYPE_GETVERDICT
: // -
9832 case OPTYPE_PROF_RUNNING
: // -
9833 break; // nothing to do
9835 case OPTYPE_MATCH
: // v1 t2
9836 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9838 case OPTYPE_UNARYPLUS
: // v1
9839 case OPTYPE_UNARYMINUS
: // v1
9840 case OPTYPE_NOT
: // v1
9841 case OPTYPE_NOT4B
: // v1
9842 case OPTYPE_BIT2HEX
: // v1
9843 case OPTYPE_BIT2INT
: // v1
9844 case OPTYPE_BIT2OCT
: // v1
9845 case OPTYPE_BIT2STR
: // v1
9846 case OPTYPE_CHAR2INT
: // v1
9847 case OPTYPE_CHAR2OCT
: // v1
9848 case OPTYPE_FLOAT2INT
: // v1
9849 case OPTYPE_FLOAT2STR
: // v1
9850 case OPTYPE_HEX2BIT
: // v1
9851 case OPTYPE_HEX2INT
: // v1
9852 case OPTYPE_HEX2OCT
: // v1
9853 case OPTYPE_HEX2STR
: // v1
9854 case OPTYPE_INT2CHAR
: // v1
9855 case OPTYPE_INT2FLOAT
: // v1
9856 case OPTYPE_INT2STR
: // v1
9857 case OPTYPE_INT2UNICHAR
: // v1
9858 case OPTYPE_OCT2BIT
: // v1
9859 case OPTYPE_OCT2CHAR
: // v1
9860 case OPTYPE_OCT2HEX
: // v1
9861 case OPTYPE_OCT2INT
: // v1
9862 case OPTYPE_OCT2STR
: // v1
9863 case OPTYPE_STR2BIT
: // v1
9864 case OPTYPE_STR2FLOAT
: // v1
9865 case OPTYPE_STR2HEX
: // v1
9866 case OPTYPE_STR2INT
: // v1
9867 case OPTYPE_STR2OCT
: // v1
9868 case OPTYPE_UNICHAR2INT
: // v1
9869 case OPTYPE_UNICHAR2CHAR
: // v1
9870 case OPTYPE_ENUM2INT
: // v1
9871 case OPTYPE_RNDWITHVAL
: // v1
9872 case OPTYPE_COMP_RUNNING
: // v1
9873 case OPTYPE_COMP_ALIVE
: // v1
9874 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
9875 case OPTYPE_GET_STRINGENCODING
:
9876 case OPTYPE_DECODE_BASE64
:
9877 case OPTYPE_REMOVE_BOM
:
9878 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9880 case OPTYPE_ADD
: // v1 v2
9881 case OPTYPE_SUBTRACT
: // v1 v2
9882 case OPTYPE_MULTIPLY
: // v1 v2
9883 case OPTYPE_DIVIDE
: // v1 v2
9884 case OPTYPE_MOD
: // v1 v2
9885 case OPTYPE_REM
: // v1 v2
9886 case OPTYPE_CONCAT
: // v1 v2
9887 case OPTYPE_EQ
: // v1 v2
9888 case OPTYPE_LT
: // v1 v2
9889 case OPTYPE_GT
: // v1 v2
9890 case OPTYPE_NE
: // v1 v2
9891 case OPTYPE_GE
: // v1 v2
9892 case OPTYPE_LE
: // v1 v2
9893 case OPTYPE_AND
: // v1 v2
9894 case OPTYPE_OR
: // v1 v2
9895 case OPTYPE_XOR
: // v1 v2
9896 case OPTYPE_AND4B
: // v1 v2
9897 case OPTYPE_OR4B
: // v1 v2
9898 case OPTYPE_XOR4B
: // v1 v2
9899 case OPTYPE_SHL
: // v1 v2
9900 case OPTYPE_SHR
: // v1 v2
9901 case OPTYPE_ROTL
: // v1 v2
9902 case OPTYPE_ROTR
: // v1 v2
9903 case OPTYPE_INT2BIT
: // v1 v2
9904 case OPTYPE_INT2HEX
: // v1 v2
9905 case OPTYPE_INT2OCT
: // v1 v2
9906 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9907 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9909 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9910 case OPTYPE_OCT2UNICHAR
:
9911 case OPTYPE_ENCODE_BASE64
:
9912 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9913 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9915 case OPTYPE_DECOMP
: // v1 v2 v3
9916 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9917 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9918 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9921 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
9922 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
9924 case OPTYPE_SUBSTR
: // ti1 v2 v3
9925 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9926 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
9927 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
9930 case OPTYPE_REGEXP
: // ti1 t2 v3
9931 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9932 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9934 case OPTYPE_LENGTHOF
: // ti1
9935 case OPTYPE_SIZEOF
: // ti1
9936 case OPTYPE_VALUEOF
: // ti1
9937 case OPTYPE_ENCODE
: // ti1
9938 case OPTYPE_TTCN2STRING
:
9939 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9942 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
9943 // component.create -- assume no self-ref
9944 case OPTYPE_ACTIVATE
: // r1
9945 // defaultref := activate(altstep) -- assume no self-ref
9946 case OPTYPE_TMR_RUNNING
: // r1
9947 // boolvar := a_timer.running -- assume no self-ref
9951 case OPTYPE_LOG2STR
: {// logargs
9952 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
9953 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
9954 switch (la
->get_type()) {
9955 case Ttcn::LogArgument::L_UNDEF
:
9956 case Ttcn::LogArgument::L_ERROR
:
9957 FATAL_ERROR("log2str argument type");
9958 break; // not reached
9960 case Ttcn::LogArgument::L_MACRO
:
9961 case Ttcn::LogArgument::L_STR
:
9962 break; // self reference not possible
9964 case Ttcn::LogArgument::L_VAL
:
9965 case Ttcn::LogArgument::L_MATCH
:
9966 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
9969 case Ttcn::LogArgument::L_REF
: {
9970 Ttcn::Ref_base
*ref
= la
->get_ref();
9971 Common::Assignment
*ass
= ref
->get_refd_assignment();
9972 self_ref
|= (ass
== lhs
);
9975 case Ttcn::LogArgument::L_TI
: {
9976 Ttcn::TemplateInstance
*ti
= la
->get_ti();
9977 Ttcn::Template
*t
= ti
->get_Template();
9978 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
9981 // no default please
9982 } // switch la->logargtype
9986 case OPTYPE_DECODE
: { // r1 r2
9987 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
9988 self_ref
|= (ass
== lhs
);
9990 case OPTYPE_EXECUTE
: // r1 [v2]
9992 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9996 case OPTYPE_UNDEF_RUNNING
: // r1
9997 case OPTYPE_TMR_READ
: { // r1
9998 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
9999 self_ref
|= (ass
== lhs
);
10002 case OPTYPE_ISCHOSEN_T
: // t1 i2
10003 case OPTYPE_ISBOUND
: // ti1
10004 case OPTYPE_ISVALUE
: // ti1
10005 case OPTYPE_ISPRESENT
: { // ti1
10007 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10008 else t
= u
.expr
.ti1
->get_Template();
10009 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10012 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10014 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10017 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10018 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10022 case NUMBER_OF_OPTYPES
: // can never happen
10023 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10024 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10026 } // switch u.expr.v_optype
10031 string
Value::create_stringRepr()
10033 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10034 switch (valuetype
) {
10036 return string("<erroneous>");
10038 return string("NULL");
10040 if (!parse_only
&& is_asn1()) {
10041 if (u
.val_bool
) return string("TRUE");
10042 else return string("FALSE");
10045 if (u
.val_bool
) return string("true");
10046 else return string("false");
10049 return u
.val_Int
->t_str();
10051 return Real2string(u
.val_Real
);
10054 case V_UNDEF_LOWERID
:
10055 return u
.val_id
->get_name();
10056 case V_NAMEDBITS
: {
10057 string
ret_val("{ ");
10058 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10059 if (i
>0) ret_val
+= ' ';
10060 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10065 string
ret_val('\'');
10066 ret_val
+= *u
.str
.val_str
;
10070 string
ret_val('\'');
10071 ret_val
+= *u
.str
.val_str
;
10075 string
ret_val('\'');
10076 ret_val
+= *u
.str
.val_str
;
10081 return u
.str
.val_str
->get_stringRepr();
10083 return u
.ustr
.val_ustr
->get_stringRepr();
10085 /** \todo stringrepr of V_CHARSYMS */
10086 return string("<sorry, string representation of charsyms "
10087 "not implemented>");
10091 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10093 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10094 if (i
>0) ret_val
+= ' ';
10095 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10100 if (!parse_only
&& is_asn1()) {
10101 string
ret_val(u
.choice
.alt_name
->get_dispname());
10103 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10107 string
ret_val("{ ");
10108 ret_val
+= u
.choice
.alt_name
->get_dispname();
10110 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10117 string
ret_val("{ ");
10118 if (!is_indexed()) {
10119 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10120 if (i
> 0) ret_val
+= ", ";
10121 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10124 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10125 if (i
> 0) ret_val
+= ", ";
10126 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10133 string
ret_val("{ ");
10134 bool asn1_flag
= !parse_only
&& is_asn1();
10135 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10136 if (i
> 0) ret_val
+= ", ";
10137 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10138 ret_val
+= nv
->get_name().get_dispname();
10139 if (asn1_flag
) ret_val
+= ' ';
10140 else ret_val
+= " := ";
10141 ret_val
+= nv
->get_value()->get_stringRepr();
10146 // do not evaluate the reference if it is not done so far
10147 // (e.g. in parse-only mode)
10148 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10149 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10150 else return t_val
->get_stringRepr(); }
10152 return string("omit");
10154 switch (u
.verdict
) {
10156 return string("none");
10158 return string("pass");
10159 case Verdict_INCONC
:
10160 return string("inconc");
10162 return string("fail");
10163 case Verdict_ERROR
:
10164 return string("error");
10166 return string("<unknown verdict value>");
10168 case V_DEFAULT_NULL
:
10170 return string("null");
10172 switch (u
.expr
.v_optype
) {
10174 return string("rnd()");
10175 case OPTYPE_TESTCASENAME
:
10176 return string("testcasename()");
10177 case OPTYPE_UNARYPLUS
:
10178 return create_stringRepr_unary("+");
10179 case OPTYPE_UNARYMINUS
:
10180 return create_stringRepr_unary("-");
10182 return create_stringRepr_unary("not");
10184 return create_stringRepr_unary("not4b");
10185 case OPTYPE_BIT2HEX
:
10186 return create_stringRepr_predef1("bit2hex");
10187 case OPTYPE_BIT2INT
:
10188 return create_stringRepr_predef1("bit2int");
10189 case OPTYPE_BIT2OCT
:
10190 return create_stringRepr_predef1("bit2oct");
10191 case OPTYPE_BIT2STR
:
10192 return create_stringRepr_predef1("bit2str");
10193 case OPTYPE_CHAR2INT
:
10194 return create_stringRepr_predef1("char2int");
10195 case OPTYPE_CHAR2OCT
:
10196 return create_stringRepr_predef1("char2oct");
10197 case OPTYPE_FLOAT2INT
:
10198 return create_stringRepr_predef1("float2int");
10199 case OPTYPE_FLOAT2STR
:
10200 return create_stringRepr_predef1("float2str");
10201 case OPTYPE_HEX2BIT
:
10202 return create_stringRepr_predef1("hex2bit");
10203 case OPTYPE_HEX2INT
:
10204 return create_stringRepr_predef1("hex2int");
10205 case OPTYPE_HEX2OCT
:
10206 return create_stringRepr_predef1("hex2oct");
10207 case OPTYPE_HEX2STR
:
10208 return create_stringRepr_predef1("hex2str");
10209 case OPTYPE_INT2CHAR
:
10210 return create_stringRepr_predef1("int2char");
10211 case OPTYPE_INT2FLOAT
:
10212 return create_stringRepr_predef1("int2float");
10213 case OPTYPE_INT2STR
:
10214 return create_stringRepr_predef1("int2str");
10215 case OPTYPE_INT2UNICHAR
:
10216 return create_stringRepr_predef1("int2unichar");
10217 case OPTYPE_OCT2BIT
:
10218 return create_stringRepr_predef1("oct2bit");
10219 case OPTYPE_OCT2CHAR
:
10220 return create_stringRepr_predef1("oct2char");
10221 case OPTYPE_OCT2HEX
:
10222 return create_stringRepr_predef1("oct2hex");
10223 case OPTYPE_OCT2INT
:
10224 return create_stringRepr_predef1("oct2int");
10225 case OPTYPE_OCT2STR
:
10226 return create_stringRepr_predef1("oct2str");
10227 case OPTYPE_GET_STRINGENCODING
:
10228 return create_stringRepr_predef1("get_stringencoding");
10229 case OPTYPE_REMOVE_BOM
:
10230 return create_stringRepr_predef1("remove_bom");
10231 case OPTYPE_ENCODE_BASE64
: {
10232 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10233 else return create_stringRepr_predef1("encode_base64");
10235 case OPTYPE_DECODE_BASE64
:
10236 return create_stringRepr_predef1("decode_base64");
10237 case OPTYPE_OCT2UNICHAR
:{
10238 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10239 else return create_stringRepr_predef1("oct2unichar");
10241 case OPTYPE_UNICHAR2OCT
: {
10242 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10243 else return create_stringRepr_predef1("unichar2oct");
10245 case OPTYPE_STR2BIT
:
10246 return create_stringRepr_predef1("str2bit");
10247 case OPTYPE_STR2FLOAT
:
10248 return create_stringRepr_predef1("str2float");
10249 case OPTYPE_STR2HEX
:
10250 return create_stringRepr_predef1("str2hex");
10251 case OPTYPE_STR2INT
:
10252 return create_stringRepr_predef1("str2int");
10253 case OPTYPE_STR2OCT
:
10254 return create_stringRepr_predef1("str2oct");
10255 case OPTYPE_UNICHAR2INT
:
10256 return create_stringRepr_predef1("unichar2int");
10257 case OPTYPE_UNICHAR2CHAR
:
10258 return create_stringRepr_predef1("unichar2char");
10259 case OPTYPE_ENUM2INT
:
10260 return create_stringRepr_predef1("enum2int");
10261 case OPTYPE_ENCODE
:
10262 return create_stringRepr_predef1("encvalue");
10263 case OPTYPE_DECODE
:
10264 return create_stringRepr_predef2("decvalue");
10265 case OPTYPE_RNDWITHVAL
:
10266 return create_stringRepr_predef1("rnd");
10268 return create_stringRepr_infix("+");
10269 case OPTYPE_SUBTRACT
:
10270 return create_stringRepr_infix("-");
10271 case OPTYPE_MULTIPLY
:
10272 return create_stringRepr_infix("*");
10273 case OPTYPE_DIVIDE
:
10274 return create_stringRepr_infix("/");
10276 return create_stringRepr_infix("mod");
10278 return create_stringRepr_infix("rem");
10279 case OPTYPE_CONCAT
:
10280 return create_stringRepr_infix("&");
10282 return create_stringRepr_infix("==");
10284 return create_stringRepr_infix("<");
10286 return create_stringRepr_infix(">");
10288 return create_stringRepr_infix("!=");
10290 return create_stringRepr_infix(">=");
10292 return create_stringRepr_infix("<=");
10294 return create_stringRepr_infix("and");
10296 return create_stringRepr_infix("or");
10298 return create_stringRepr_infix("xor");
10300 return create_stringRepr_infix("and4b");
10302 return create_stringRepr_infix("or4b");
10304 return create_stringRepr_infix("xor4b");
10306 return create_stringRepr_infix("<<");
10308 return create_stringRepr_infix(">>");
10310 return create_stringRepr_infix("<@");
10312 return create_stringRepr_infix("@>");
10313 case OPTYPE_INT2BIT
:
10314 return create_stringRepr_predef2("int2bit");
10315 case OPTYPE_INT2HEX
:
10316 return create_stringRepr_predef2("int2hex");
10317 case OPTYPE_INT2OCT
:
10318 return create_stringRepr_predef2("int2oct");
10319 case OPTYPE_SUBSTR
: {
10320 string
ret_val("substr(");
10321 u
.expr
.ti1
->append_stringRepr(ret_val
);
10323 ret_val
+= u
.expr
.v2
->get_stringRepr();
10325 ret_val
+= u
.expr
.v3
->get_stringRepr();
10329 case OPTYPE_REGEXP
: {
10330 string
ret_val("regexp(");
10331 u
.expr
.ti1
->append_stringRepr(ret_val
);
10333 u
.expr
.t2
->append_stringRepr(ret_val
);
10335 ret_val
+= u
.expr
.v3
->get_stringRepr();
10339 case OPTYPE_DECOMP
: {
10340 string
ret_val("decomp(");
10341 ret_val
+= u
.expr
.v1
->get_stringRepr();
10343 ret_val
+= u
.expr
.v2
->get_stringRepr();
10345 ret_val
+= u
.expr
.v3
->get_stringRepr();
10349 case OPTYPE_REPLACE
: {
10350 string
ret_val("replace(");
10351 u
.expr
.ti1
->append_stringRepr(ret_val
);
10353 ret_val
+= u
.expr
.v2
->get_stringRepr();
10355 ret_val
+= u
.expr
.v3
->get_stringRepr();
10357 u
.expr
.ti4
->append_stringRepr(ret_val
);
10361 case OPTYPE_ISPRESENT
: {
10362 string
ret_val("ispresent(");
10363 u
.expr
.ti1
->append_stringRepr(ret_val
);
10366 case OPTYPE_ISCHOSEN
: {
10367 string
ret_val("ischosen(");
10368 ret_val
+= u
.expr
.r1
->get_dispname();
10370 ret_val
+= u
.expr
.i2
->get_dispname();
10373 case OPTYPE_ISCHOSEN_V
: {
10374 string
ret_val("ischosen(");
10375 ret_val
+= u
.expr
.v1
->get_stringRepr();
10377 ret_val
+= u
.expr
.i2
->get_dispname();
10380 case OPTYPE_ISCHOSEN_T
: {
10381 string
ret_val("ischosen(");
10382 ret_val
+= u
.expr
.t1
->get_stringRepr();
10384 ret_val
+= u
.expr
.i2
->get_dispname();
10387 case OPTYPE_LENGTHOF
: {
10388 string
ret_val("lengthof(");
10389 u
.expr
.ti1
->append_stringRepr(ret_val
);
10392 case OPTYPE_SIZEOF
: {
10393 string
ret_val("sizeof(");
10394 u
.expr
.ti1
->append_stringRepr(ret_val
);
10397 case OPTYPE_ISVALUE
: {
10398 string
ret_val("isvalue(");
10399 u
.expr
.ti1
->append_stringRepr(ret_val
);
10402 case OPTYPE_VALUEOF
: {
10403 string
ret_val("valueof(");
10404 u
.expr
.ti1
->append_stringRepr(ret_val
);
10407 case OPTYPE_LOG2STR
:
10408 return string("log2str(...)");
10409 case OPTYPE_MATCH
: {
10410 string
ret_val("match(");
10411 ret_val
+= u
.expr
.v1
->get_stringRepr();
10413 u
.expr
.t2
->append_stringRepr(ret_val
);
10416 case OPTYPE_TTCN2STRING
: {
10417 string
ret_val("ttcn2string(");
10418 u
.expr
.ti1
->append_stringRepr(ret_val
);
10422 case OPTYPE_UNDEF_RUNNING
:
10423 return u
.expr
.r1
->get_dispname() + ".running";
10424 case OPTYPE_COMP_NULL
:
10425 return string("null");
10426 case OPTYPE_COMP_MTC
:
10427 return string("mtc");
10428 case OPTYPE_COMP_SYSTEM
:
10429 return string("system");
10430 case OPTYPE_COMP_SELF
:
10431 return string("self");
10432 case OPTYPE_COMP_CREATE
: {
10433 string
ret_val(u
.expr
.r1
->get_dispname());
10434 ret_val
+= ".create";
10435 if (u
.expr
.v2
|| u
.expr
.v3
) {
10437 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10438 else ret_val
+= '-';
10441 ret_val
+= u
.expr
.v3
->get_stringRepr();
10445 if (u
.expr
.b4
) ret_val
+= " alive";
10447 case OPTYPE_COMP_RUNNING
:
10448 return u
.expr
.v1
->get_stringRepr() + ".running";
10449 case OPTYPE_COMP_RUNNING_ANY
:
10450 return string("any component.running");
10451 case OPTYPE_COMP_RUNNING_ALL
:
10452 return string("all component.running");
10453 case OPTYPE_COMP_ALIVE
:
10454 return u
.expr
.v1
->get_stringRepr() + ".alive";
10455 case OPTYPE_COMP_ALIVE_ANY
:
10456 return string("any component.alive");
10457 case OPTYPE_COMP_ALIVE_ALL
:
10458 return string("all component.alive");
10459 case OPTYPE_TMR_READ
:
10460 return u
.expr
.r1
->get_dispname() + ".read";
10461 case OPTYPE_TMR_RUNNING
:
10462 return u
.expr
.r1
->get_dispname() + ".running";
10463 case OPTYPE_TMR_RUNNING_ANY
:
10464 return string("any timer.running");
10465 case OPTYPE_GETVERDICT
:
10466 return string("getverdict");
10467 case OPTYPE_ACTIVATE
: {
10468 string
ret_val("activate(");
10469 ret_val
+= u
.expr
.r1
->get_dispname();
10472 case OPTYPE_ACTIVATE_REFD
: {
10473 string
ret_val("activate(derefer(");
10474 ret_val
+= u
.expr
.v1
->get_stringRepr();
10476 if (u
.expr
.state
== EXPR_CHECKED
) {
10477 if (u
.expr
.ap_list2
) {
10478 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10479 for (size_t i
= 0; i
< nof_pars
; i
++) {
10480 if (i
> 0) ret_val
+= ", ";
10481 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10485 if (u
.expr
.t_list2
) {
10486 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10487 for (size_t i
= 0; i
< nof_pars
; i
++) {
10488 if (i
> 0) ret_val
+= ", ";
10489 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10495 case OPTYPE_EXECUTE
: {
10496 string
ret_val("execute(");
10497 ret_val
+= u
.expr
.r1
->get_dispname();
10500 ret_val
+= u
.expr
.v2
->get_stringRepr();
10504 case OPTYPE_EXECUTE_REFD
: {
10505 string
ret_val("execute(derefers(");
10506 ret_val
+= u
.expr
.v1
->get_stringRepr();
10508 if (u
.expr
.state
== EXPR_CHECKED
) {
10509 if (u
.expr
.ap_list2
) {
10510 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10511 for (size_t i
= 0; i
< nof_pars
; i
++) {
10512 if (i
> 0) ret_val
+= ", ";
10513 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10517 if (u
.expr
.t_list2
) {
10518 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10519 for (size_t i
= 0; i
< nof_pars
; i
++) {
10520 if (i
> 0) ret_val
+= ", ";
10521 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10528 ret_val
+= u
.expr
.v3
->get_stringRepr();
10532 case OPTYPE_PROF_RUNNING
:
10533 return string("@profiler.running");
10535 return string("<unsupported optype>");
10536 } // switch u.expr.v_optype
10539 case MACRO_MODULEID
:
10540 return string("%moduleId");
10541 case MACRO_FILENAME
:
10542 return string("%fileName");
10543 case MACRO_BFILENAME
:
10544 return string("__BFILE__");
10545 case MACRO_FILEPATH
:
10546 return string("__FILE__");
10547 case MACRO_LINENUMBER
:
10548 return string("%lineNumber");
10549 case MACRO_LINENUMBER_C
:
10550 return string("__LINE__");
10551 case MACRO_DEFINITIONID
:
10552 return string("%definitionId");
10554 return string("__SCOPE__");
10555 case MACRO_TESTCASEID
:
10556 return string("%testcaseId");
10558 return string("<unknown macro>");
10559 } // switch u.macro
10561 return string('-');
10565 string
ret_val("refers(");
10566 ret_val
+= u
.refd_fat
->get_assname();
10571 ret_val
+= u
.invoke
.v
->get_stringRepr();
10572 ret_val
+= ".apply(";
10573 if (u
.invoke
.ap_list
) {
10574 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10575 for (size_t i
= 0; i
< nof_pars
; i
++) {
10576 if (i
> 0) ret_val
+= ", ";
10577 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10579 } else if (u
.invoke
.t_list
) {
10580 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10581 for (size_t i
= 0; i
< nof_pars
; i
++) {
10582 if (i
> 0) ret_val
+= ", ";
10583 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10589 string
ret_val("refers(");
10590 ret_val
+= u
.refered
->get_dispname();
10594 return string("<unsupported valuetype>");
10595 } // switch valuetype
10598 string
Value::create_stringRepr_unary(const char *operator_str
)
10600 string
ret_val(operator_str
);
10602 ret_val
+= u
.expr
.v1
->get_stringRepr();
10607 string
Value::create_stringRepr_infix(const char *operator_str
)
10609 string
ret_val('(');
10610 ret_val
+= u
.expr
.v1
->get_stringRepr();
10612 ret_val
+= operator_str
;
10614 ret_val
+= u
.expr
.v2
->get_stringRepr();
10619 string
Value::create_stringRepr_predef1(const char *function_name
)
10621 string
ret_val(function_name
);
10623 if (u
.expr
.v_optype
== OPTYPE_ENCODE
) { // ti1, not v1
10624 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10626 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10631 string
Value::create_stringRepr_predef2(const char *function_name
)
10633 string
ret_val(function_name
);
10635 ret_val
+= u
.expr
.v1
->get_stringRepr();
10637 ret_val
+= u
.expr
.v2
->get_stringRepr();
10642 bool Value::operator==(Value
& val
)
10644 Value
*left
= get_value_refd_last();
10645 Type
*left_governor
= left
->get_my_governor();
10646 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10647 Value
*right
= val
.get_value_refd_last();
10648 Type
*right_governor
= right
->get_my_governor();
10649 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10650 if (left_governor
&& right_governor
10651 && !left_governor
->is_compatible(right_governor
, NULL
)
10652 && !right_governor
->is_compatible(left_governor
, NULL
))
10653 FATAL_ERROR("Value::operator==");
10655 // Not-A-Value is not equal to anything (NaN analogy:)
10656 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10659 switch (left
->valuetype
) {
10662 case V_DEFAULT_NULL
:
10665 return left
->valuetype
== right
->valuetype
;
10667 return right
->valuetype
== V_BOOL
&&
10668 left
->get_val_bool() == right
->get_val_bool();
10670 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10671 == *right
->get_val_Int();
10673 return right
->valuetype
== V_REAL
&&
10674 left
->get_val_Real() == right
->get_val_Real();
10676 switch (right
->valuetype
) {
10678 return left
->get_val_str() == right
->get_val_str();
10680 return right
->get_val_ustr() == left
->get_val_str();
10682 return right
->get_val_iso2022str() == left
->get_val_str();
10689 return left
->valuetype
== right
->valuetype
&&
10690 left
->get_val_str() == right
->get_val_str();
10692 switch (right
->valuetype
) {
10694 return left
->get_val_ustr() == right
->get_val_str();
10696 return left
->get_val_ustr() == right
->get_val_ustr();
10698 return left
->get_val_ustr() == right
->get_val_iso2022str();
10703 switch (right
->valuetype
) {
10705 return left
->get_val_iso2022str() == right
->get_val_str();
10707 // The appropriate operator==() is missing. The operands are swapped,
10708 // but it shouldn't be a problem.
10709 return right
->get_val_ustr() == left
->get_val_iso2022str();
10711 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10716 return right
->valuetype
== V_ENUM
&&
10717 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10720 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10721 vector
<string
> act
, other
;
10722 get_oid_comps(act
);
10723 val
.get_oid_comps(other
);
10724 size_t act_size
= act
.size(), other_size
= other
.size();
10726 if (act_size
== other_size
) {
10728 for (size_t i
= 0; i
< act_size
; i
++)
10729 if (*act
[i
] != *other
[i
]) {
10733 } else ret_val
= false;
10734 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10736 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10739 } else return false;
10741 return right
->valuetype
== V_CHOICE
&&
10742 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10743 *(left
->get_alt_value()) == *(right
->get_alt_value());
10746 if (!left_governor
) FATAL_ERROR("Value::operator==");
10747 if (left
->valuetype
!= right
->valuetype
) return false;
10748 size_t nof_comps
= left_governor
->get_nof_comps();
10749 for (size_t i
= 0; i
< nof_comps
; i
++) {
10750 Value
*lval
= NULL
, *rval
= NULL
;
10751 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10752 const Identifier
& field_name
= cfl
->get_name();
10753 if (left
->has_comp_withName(field_name
)) {
10754 lval
= left
->get_comp_value_byName(field_name
);
10755 if (right
->has_comp_withName(field_name
)) {
10756 rval
= right
->get_comp_value_byName(field_name
);
10757 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10758 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10760 else if (!(*lval
== *rval
))
10763 if (cfl
->has_default()) {
10764 if (!(*lval
== *cfl
->get_defval()))
10767 if (lval
->valuetype
!= V_OMIT
)
10772 if(right
->has_comp_withName(field_name
)) {
10773 rval
= right
->get_comp_value_byName(field_name
);
10774 if(cfl
->has_default()) {
10775 if(rval
->valuetype
==V_OMIT
) return false;
10777 lval
= cfl
->get_defval();
10778 if (!(*lval
==*rval
)) return false;
10787 if (left
->valuetype
!= right
->valuetype
) return false;
10788 size_t ncomps
= get_nof_comps();
10789 if (ncomps
!= right
->get_nof_comps()) return false;
10791 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
10792 bool found
= false;
10793 map
<IndexedValue
*, void> uncovered
;
10794 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
10795 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
10797 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
10799 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
10800 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
10801 *(right
->get_comp_byIndex(i
)) &&
10802 *(uncovered
.get_nth_key(j
)->get_index()) ==
10803 *(right
->get_index_byIndex(i
))) {
10805 uncovered
.erase(uncovered
.get_nth_key(j
));
10813 } else if (left
->is_indexed() || right
->is_indexed()) {
10814 Value
* indexed_one
= 0;
10815 Value
* not_indexed_one
= 0;
10817 if(left
->is_indexed()) { // left is indexed, right is not
10818 indexed_one
= left
;
10819 not_indexed_one
= right
;
10820 } else { // right indexed, left is not
10821 indexed_one
= right
;
10822 not_indexed_one
= left
;
10825 for(size_t i
= 0; i
< ncomps
; ++i
) {
10826 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
10827 if(!(ind
->valuetype
== V_INT
&&
10828 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
10829 *(indexed_one
->get_comp_byIndex(i
))))
10833 } else { // none of them is indexed
10834 for (size_t i
= 0; i
< ncomps
; i
++) {
10835 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
10842 if (right
->valuetype
!= V_SETOF
) return false;
10843 size_t ncomps
= get_nof_comps();
10844 if (ncomps
!= right
->get_nof_comps()) return false;
10845 if (ncomps
== 0) return true;
10846 map
<size_t, void> uncovered
;
10847 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
10848 for (size_t i
= 0; i
< ncomps
; i
++) {
10849 Value
*left_item
= left
->get_comp_byIndex(i
);
10850 bool pair_found
= false;
10851 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
10852 size_t right_index
= uncovered
.get_nth_key(j
);
10853 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
10854 uncovered
.erase(right_index
);
10866 return right
->valuetype
== V_VERDICT
&&
10867 left
->get_val_verdict() == right
->get_val_verdict();
10871 return left
->valuetype
== right
->valuetype
&&
10872 left
->get_refd_assignment() == right
->get_refd_assignment();
10874 FATAL_ERROR("Value::operator==");
10879 bool Value::operator<(Value
& val
)
10881 Value
*left
= get_value_refd_last();
10882 Type
*left_governor
= left
->get_my_governor();
10883 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
10884 Value
*right
= val
.get_value_refd_last();
10885 Type
*right_governor
= right
->get_my_governor();
10886 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
10887 if (left
->get_valuetype() != right
->get_valuetype())
10888 FATAL_ERROR("Value::operator<");
10891 return *left
->get_val_Int() < *right
->get_val_Int();
10893 return (left
->get_val_Real() < right
->get_val_Real());
10895 if(!left_governor
|| !right_governor
)
10896 FATAL_ERROR("Value::operator<");
10897 if(left_governor
!=right_governor
)
10898 FATAL_ERROR("Value::operator<");
10899 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
10900 right_governor
->get_enum_val_byId(*right
->get_val_id()));
10902 FATAL_ERROR("Value::operator<");
10907 bool Value::is_string_type(Type::expected_value_t exp_val
)
10909 switch (get_expr_returntype(exp_val
)) {
10921 void Value::generate_code_expr(expression_struct
*expr
)
10923 if (has_single_expr()) {
10924 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
10926 switch (valuetype
) {
10928 generate_code_expr_expr(expr
);
10936 const string
& tmp_id
= get_temporary_id();
10937 const char *tmp_id_str
= tmp_id
.c_str();
10938 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
10939 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
10940 set_genname_recursive(tmp_id
);
10941 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10942 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10945 const string
& tmp_id
= get_temporary_id();
10946 const char *tmp_id_str
= tmp_id
.c_str();
10947 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
10949 set_genname_recursive(tmp_id
);
10950 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10951 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10954 if (!get_needs_conversion()) {
10955 u
.ref
.ref
->generate_code_const_ref(expr
);
10957 Type
*my_gov
= get_expr_governor_last();
10958 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
10959 ->get_field_type(u
.ref
.ref
->get_subrefs(),
10960 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
10961 // Make sure that nothing goes wrong.
10962 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
10963 FATAL_ERROR("Value::generate_code_expr()");
10964 expression_struct expr_tmp
;
10965 Code::init_expr(&expr_tmp
);
10966 const string
& tmp_id1
= get_temporary_id();
10967 const char *tmp_id_str1
= tmp_id1
.c_str();
10968 const string
& tmp_id2
= get_temporary_id();
10969 const char *tmp_id_str2
= tmp_id2
.c_str();
10970 expr
->preamble
= mputprintf(expr
->preamble
,
10971 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
10973 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
10974 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
10975 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
10976 expr
->preamble
= mputprintf(expr
->preamble
,
10978 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10979 "and `%s' are not compatible at run-time\");\n",
10980 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
10981 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
10982 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
10983 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
10984 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
10988 generate_code_expr_invoke(expr
);
10991 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
10996 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
10998 generate_code_expr(expr
);
10999 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11000 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11003 bool Value::can_use_increment(Reference
*ref
) const
11005 if (valuetype
!= V_EXPR
) {
11008 switch (u
.expr
.v_optype
) {
11010 case OPTYPE_SUBTRACT
:
11015 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11016 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11017 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11018 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11019 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11020 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11026 char *Value::generate_code_init(char *str
, const char *name
)
11028 if (get_code_generated()) return str
;
11030 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11032 switch (valuetype
) {
11046 case V_DEFAULT_NULL
:
11051 // These values have a single string equivalent.
11052 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11055 if (u
.val_Int
->is_native_fit())
11056 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11058 // It's always an INTEGER.
11059 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11060 "}\n", get_single_expr().c_str(), name
);
11064 expression_struct expr
;
11065 Code::init_expr(&expr
);
11066 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11067 generate_code_expr(&expr
);
11068 str
= Code::merge_free_expr(str
, &expr
);
11071 str
= generate_code_init_choice(str
, name
);
11075 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11076 else str
= generate_code_init_indexed(str
, name
);
11079 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11080 else str
= generate_code_init_indexed(str
, name
);
11084 str
= generate_code_init_se(str
, name
);
11087 str
= generate_code_init_refd(str
, name
);
11091 case MACRO_TESTCASEID
:
11092 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11095 // all others must already be evaluated away
11096 FATAL_ERROR("Value::generate_code_init()");
11100 FATAL_ERROR("Value::generate_code_init()");
11103 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11105 set_code_generated();
11109 char *Value::rearrange_init_code(char *str
)
11111 switch (valuetype
) {
11113 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11115 str
= parlist
->rearrange_init_code(str
,
11116 u
.ref
.ref
->get_refd_assignment()->get_my_scope()->get_scope_mod_gen());
11120 str
= u
.invoke
.v
->rearrange_init_code(str
);
11121 str
= u
.invoke
.ap_list
->rearrange_init_code(str
,
11122 u
.invoke
.v
->get_expr_governor_last()->get_my_scope()->get_scope_mod_gen());
11125 switch (u
.expr
.v_optype
) {
11126 case OPTYPE_UNARYPLUS
:
11127 case OPTYPE_UNARYMINUS
:
11130 case OPTYPE_BIT2HEX
:
11131 case OPTYPE_BIT2INT
:
11132 case OPTYPE_BIT2OCT
:
11133 case OPTYPE_BIT2STR
:
11134 case OPTYPE_CHAR2INT
:
11135 case OPTYPE_CHAR2OCT
:
11136 case OPTYPE_FLOAT2INT
:
11137 case OPTYPE_FLOAT2STR
:
11138 case OPTYPE_HEX2BIT
:
11139 case OPTYPE_HEX2INT
:
11140 case OPTYPE_HEX2OCT
:
11141 case OPTYPE_HEX2STR
:
11142 case OPTYPE_INT2CHAR
:
11143 case OPTYPE_INT2FLOAT
:
11144 case OPTYPE_INT2STR
:
11145 case OPTYPE_INT2UNICHAR
:
11146 case OPTYPE_OCT2BIT
:
11147 case OPTYPE_OCT2CHAR
:
11148 case OPTYPE_OCT2HEX
:
11149 case OPTYPE_OCT2INT
:
11150 case OPTYPE_OCT2STR
:
11151 case OPTYPE_STR2BIT
:
11152 case OPTYPE_STR2FLOAT
:
11153 case OPTYPE_STR2HEX
:
11154 case OPTYPE_STR2INT
:
11155 case OPTYPE_STR2OCT
:
11156 case OPTYPE_UNICHAR2INT
:
11157 case OPTYPE_UNICHAR2CHAR
:
11158 case OPTYPE_ENUM2INT
:
11159 case OPTYPE_ISCHOSEN_V
:
11160 case OPTYPE_GET_STRINGENCODING
:
11161 case OPTYPE_REMOVE_BOM
:
11162 case OPTYPE_DECODE_BASE64
:
11163 str
= u
.expr
.v1
->rearrange_init_code(str
);
11165 case OPTYPE_DECODE
: {
11166 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11167 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11168 if (parlist
) str
= parlist
->rearrange_init_code(str
, ass
->get_my_scope()->get_scope_mod_gen());
11170 parlist
= u
.expr
.r2
->get_parlist();
11171 ass
= u
.expr
.r2
->get_refd_assignment();
11172 if (parlist
) str
= parlist
->rearrange_init_code(str
, ass
->get_my_scope()->get_scope_mod_gen());
11175 case OPTYPE_SUBTRACT
:
11176 case OPTYPE_MULTIPLY
:
11177 case OPTYPE_DIVIDE
:
11180 case OPTYPE_CONCAT
:
11197 case OPTYPE_INT2BIT
:
11198 case OPTYPE_INT2HEX
:
11199 case OPTYPE_INT2OCT
:
11200 //case OPTYPE_DECODE:
11201 str
= u
.expr
.v1
->rearrange_init_code(str
);
11202 str
= u
.expr
.v2
->rearrange_init_code(str
);
11204 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11205 case OPTYPE_OCT2UNICHAR
:
11206 case OPTYPE_ENCODE_BASE64
:
11207 str
= u
.expr
.v1
->rearrange_init_code(str
);
11208 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
);
11210 case OPTYPE_SUBSTR
:
11211 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11212 str
= u
.expr
.v2
->rearrange_init_code(str
);
11213 str
= u
.expr
.v3
->rearrange_init_code(str
);
11215 case OPTYPE_REGEXP
:
11216 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11217 str
= u
.expr
.t2
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11218 str
= u
.expr
.v3
->rearrange_init_code(str
);
11220 case OPTYPE_DECOMP
:
11221 str
= u
.expr
.v1
->rearrange_init_code(str
);
11222 str
= u
.expr
.v2
->rearrange_init_code(str
);
11223 str
= u
.expr
.v3
->rearrange_init_code(str
);
11225 case OPTYPE_REPLACE
:
11226 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11227 str
= u
.expr
.v2
->rearrange_init_code(str
);
11228 str
= u
.expr
.v3
->rearrange_init_code(str
);
11229 str
= u
.expr
.ti4
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11231 case OPTYPE_LENGTHOF
:
11232 case OPTYPE_SIZEOF
:
11233 case OPTYPE_VALUEOF
:
11234 case OPTYPE_ENCODE
:
11235 case OPTYPE_ISPRESENT
:
11236 case OPTYPE_TTCN2STRING
:
11237 str
= u
.expr
.ti1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11239 case OPTYPE_ISCHOSEN_T
:
11240 str
= u
.expr
.t1
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11243 str
= u
.expr
.v1
->rearrange_init_code(str
);
11244 str
= u
.expr
.t2
->rearrange_init_code(str
, my_scope
->get_scope_mod_gen());
11247 // other kinds of expressions cannot appear within templates
11257 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11258 size_t& blockcount
)
11260 char *s2
= memptystr();
11261 char *s1
= generate_code_tmp(NULL
, s2
);
11263 if (blockcount
== 0) {
11264 str
= mputstr(str
, "{\n");
11267 str
= mputstr(str
, s2
);
11270 str
=mputstr(str
, prefix
);
11271 str
=mputstr(str
, s1
);
11276 char *Value::generate_code_tmp(char *str
, char*& init
)
11278 expression_struct expr
;
11279 Code::init_expr(&expr
);
11280 generate_code_expr_mandatory(&expr
);
11281 if (expr
.preamble
|| expr
.postamble
) {
11282 if (valuetype
== V_EXPR
&&
11283 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11284 // a temporary variable is already introduced
11285 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11286 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11287 str
= mputstr(str
, expr
.expr
);
11289 const string
& tmp_id
= get_temporary_id();
11290 const char *tmp_id_str
= tmp_id
.c_str();
11291 init
= mputprintf(init
, "%s %s;\n"
11293 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11294 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11296 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11297 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11298 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11299 init
= mputstr(init
, "}\n");
11300 str
= mputstr(str
, tmp_id_str
);
11302 } else str
= mputstr(str
, expr
.expr
);
11303 Code::free_expr(&expr
);
11307 void Value::generate_code_log(expression_struct
*expr
)
11309 if (explicit_cast_needed()) {
11310 char *expr_backup
= expr
->expr
;
11312 generate_code_expr(expr
);
11313 const string
& tmp_id
= get_temporary_id();
11314 const char *tmp_id_str
= tmp_id
.c_str();
11315 // We have to create a temporary object, because the parser of GCC
11316 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11317 // constructor call that is, this does not work: type(...).log(); but
11318 // this works: type tmp(...); tmp.log();.
11319 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11320 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11323 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11325 generate_code_expr(expr
);
11327 expr
->expr
= mputstr(expr
->expr
, ".log()");
11330 void Value::generate_code_log_match(expression_struct
*expr
)
11332 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11333 FATAL_ERROR("Value::generate_code_log_match()");
11334 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11335 // compliance the whole code-generation should be checked. Standalone
11336 // constructs like: "A(a[0].f());" should be avoided. The current
11337 // solution for HK38721 uses an additional assignment to overcome the
11338 // issue. The generated code will be slower, but it's needed for old GCC
11339 // versions in specific circumstances.
11340 if (u
.expr
.t2
->needs_temp_ref()) {
11341 char *expr_backup
= expr
->expr
;
11343 u
.expr
.t2
->generate_code(expr
);
11344 const string
& tmp_id
= get_temporary_id();
11345 const char *tmp_id_str
= tmp_id
.c_str();
11346 expr
->preamble
= mputprintf(expr
->preamble
,
11347 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11348 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11350 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11352 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11353 // some reason "(A(NS::B)).a(C);" compiles fine.
11354 expr
->expr
= mputc(expr
->expr
, '(');
11355 u
.expr
.t2
->generate_code(expr
);
11356 expr
->expr
= mputc(expr
->expr
, ')');
11358 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11359 u
.expr
.v1
->generate_code_expr(expr
);
11360 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11363 void Value::generate_code_expr_expr(expression_struct
*expr
)
11365 switch (u
.expr
.v_optype
) {
11367 generate_code_expr_rnd(expr
, 0);
11369 case OPTYPE_UNARYPLUS
:
11370 // same as without the '+' operator
11371 u
.expr
.v1
->generate_code_expr(expr
);
11373 case OPTYPE_UNARYMINUS
:
11374 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11377 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11380 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11382 case OPTYPE_BIT2HEX
:
11383 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11385 case OPTYPE_BIT2INT
:
11386 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11388 case OPTYPE_BIT2OCT
:
11389 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11391 case OPTYPE_BIT2STR
:
11392 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11394 case OPTYPE_CHAR2INT
:
11395 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11397 case OPTYPE_CHAR2OCT
:
11398 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11400 case OPTYPE_FLOAT2INT
:
11401 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11403 case OPTYPE_FLOAT2STR
:
11404 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11406 case OPTYPE_HEX2BIT
:
11407 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11409 case OPTYPE_HEX2INT
:
11410 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11412 case OPTYPE_HEX2OCT
:
11413 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11415 case OPTYPE_HEX2STR
:
11416 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11418 case OPTYPE_INT2CHAR
:
11419 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11421 case OPTYPE_INT2FLOAT
:
11422 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11424 case OPTYPE_INT2STR
:
11425 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11427 case OPTYPE_INT2UNICHAR
:
11428 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11430 case OPTYPE_OCT2BIT
:
11431 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11433 case OPTYPE_OCT2CHAR
:
11434 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11436 case OPTYPE_GET_STRINGENCODING
:
11437 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11439 case OPTYPE_REMOVE_BOM
:
11440 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11442 case OPTYPE_ENCODE_BASE64
:
11444 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11446 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11448 case OPTYPE_DECODE_BASE64
:
11449 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11451 case OPTYPE_OCT2UNICHAR
:
11453 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11455 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11457 case OPTYPE_UNICHAR2OCT
:
11459 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11461 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11463 case OPTYPE_OCT2HEX
:
11464 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11466 case OPTYPE_OCT2INT
:
11467 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11469 case OPTYPE_OCT2STR
:
11470 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11472 case OPTYPE_STR2BIT
:
11473 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11475 case OPTYPE_STR2FLOAT
:
11476 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11478 case OPTYPE_STR2HEX
:
11479 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11481 case OPTYPE_STR2INT
:
11482 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11484 case OPTYPE_STR2OCT
:
11485 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11487 case OPTYPE_UNICHAR2INT
:
11488 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11490 case OPTYPE_UNICHAR2CHAR
:
11491 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11493 case OPTYPE_ENUM2INT
: {
11494 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11495 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11496 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11497 enum_type
->get_genname_value(my_scope
).c_str());
11498 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11499 expr
->expr
= mputc(expr
->expr
, ')');
11501 case OPTYPE_ENCODE
:
11502 generate_code_expr_encode(expr
);
11504 case OPTYPE_DECODE
:
11505 generate_code_expr_decode(expr
);
11507 case OPTYPE_RNDWITHVAL
:
11508 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11511 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11513 case OPTYPE_SUBTRACT
:
11514 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11516 case OPTYPE_MULTIPLY
:
11517 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11519 case OPTYPE_DIVIDE
:
11520 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11523 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11526 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11528 case OPTYPE_CONCAT
:
11529 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11532 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11535 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11538 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11541 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11544 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11547 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11551 generate_code_expr_and_or(expr
);
11554 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11557 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11560 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11563 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11566 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11569 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11572 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11575 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11577 case OPTYPE_INT2BIT
:
11578 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11580 case OPTYPE_INT2HEX
:
11581 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11583 case OPTYPE_INT2OCT
:
11584 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11586 case OPTYPE_SUBSTR
:
11587 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11588 else generate_code_expr_substr_replace_compat(expr
);
11590 case OPTYPE_REGEXP
:
11591 generate_code_expr_regexp(expr
);
11593 case OPTYPE_DECOMP
:
11594 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11596 case OPTYPE_REPLACE
:
11597 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11598 else generate_code_expr_substr_replace_compat(expr
);
11600 case OPTYPE_ISCHOSEN
: // r1 i2
11601 FATAL_ERROR("Value::generate_code_expr_expr()");
11603 case OPTYPE_ISCHOSEN_V
: // v1 i2
11604 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11605 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11606 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11607 u
.expr
.i2
->get_name().c_str());
11609 case OPTYPE_ISCHOSEN_T
: // t1 i2
11610 u
.expr
.t1
->generate_code_expr(expr
);
11611 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11612 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11613 u
.expr
.i2
->get_name().c_str());
11615 case OPTYPE_ISPRESENT
:
11616 case OPTYPE_ISBOUND
: {
11617 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11618 ->get_templatetype();
11619 if (temp
== Template::SPECIFIC_VALUE
) {
11620 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11621 ->get_specific_value();
11622 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11623 Ttcn::Reference
* reference
=
11624 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11626 reference
->generate_code_ispresentbound(expr
, false,
11627 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11631 } else if (temp
== Template::TEMPLATE_REFD
){
11632 Ttcn::Reference
* reference
=
11633 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11634 ->get_reference());
11636 reference
->generate_code_ispresentbound(expr
, true,
11637 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11643 case OPTYPE_LENGTHOF
: // ti1
11644 // fall through, separated later
11645 case OPTYPE_SIZEOF
: // ti1
11646 // fall through, separated later
11647 case OPTYPE_ISVALUE
: { // ti1
11648 if (u
.expr
.ti1
->is_only_specific_value()) {
11649 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11650 bool cast_needed
= t_val
->explicit_cast_needed(
11651 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11653 // the ambiguous C++ expression is converted to the value class
11654 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11655 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11658 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11659 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11660 t_val
->generate_code_expr(expr
);
11662 t_val
->generate_code_expr_mandatory(expr
);
11665 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11667 else u
.expr
.ti1
->generate_code(expr
);
11669 switch (u
.expr
.v_optype
) {
11670 case OPTYPE_ISBOUND
:
11671 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11673 case OPTYPE_ISPRESENT
:
11674 expr
->expr
=mputprintf(expr
->expr
, ".is_present(%s)",
11675 omit_in_value_list
? "TRUE" : "");
11677 case OPTYPE_SIZEOF
:
11678 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11680 case OPTYPE_LENGTHOF
:
11681 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11683 case OPTYPE_ISVALUE
:
11684 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11687 FATAL_ERROR("Value::generate_code_expr_expr()");
11690 case OPTYPE_VALUEOF
: // ti1
11691 u
.expr
.ti1
->generate_code(expr
);
11692 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11694 case OPTYPE_MATCH
: // v1 t2
11695 u
.expr
.t2
->generate_code(expr
);
11696 expr
->expr
= mputstr(expr
->expr
, ".match(");
11697 u
.expr
.v1
->generate_code_expr(expr
);
11698 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11700 case OPTYPE_UNDEF_RUNNING
:
11701 // it is resolved during semantic check
11702 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11704 case OPTYPE_COMP_NULL
: // -
11705 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11707 case OPTYPE_COMP_MTC
: // -
11708 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11710 case OPTYPE_COMP_SYSTEM
: // -
11711 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11713 case OPTYPE_COMP_SELF
: // -
11714 expr
->expr
=mputstr(expr
->expr
, "self");
11716 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11717 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11720 case OPTYPE_COMP_RUNNING
: // v1
11721 u
.expr
.v1
->generate_code_expr(expr
);
11722 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11723 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11724 expr
->expr
= mputstr(expr
->expr
, ".running()");
11726 case OPTYPE_COMP_RUNNING_ANY
: // -
11727 expr
->expr
=mputstr(expr
->expr
,
11728 "TTCN_Runtime::component_running(ANY_COMPREF)");
11730 case OPTYPE_COMP_RUNNING_ALL
: // -
11731 expr
->expr
=mputstr(expr
->expr
,
11732 "TTCN_Runtime::component_running(ALL_COMPREF)");
11734 case OPTYPE_COMP_ALIVE
: // v1
11735 u
.expr
.v1
->generate_code_expr(expr
);
11736 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11737 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11738 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11740 case OPTYPE_COMP_ALIVE_ANY
: // -
11741 expr
->expr
= mputstr(expr
->expr
,
11742 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11744 case OPTYPE_COMP_ALIVE_ALL
: // -
11745 expr
->expr
= mputstr(expr
->expr
,
11746 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11748 case OPTYPE_TMR_READ
: // r1
11749 u
.expr
.r1
->generate_code(expr
);
11750 expr
->expr
= mputstr(expr
->expr
, ".read()");
11752 case OPTYPE_TMR_RUNNING
: // r1
11753 u
.expr
.r1
->generate_code(expr
);
11754 expr
->expr
= mputstr(expr
->expr
, ".running()");
11756 case OPTYPE_TMR_RUNNING_ANY
: // -
11757 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
11759 case OPTYPE_GETVERDICT
: // -
11760 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
11762 case OPTYPE_TESTCASENAME
: // -
11763 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
11765 case OPTYPE_ACTIVATE
: // r1
11766 generate_code_expr_activate(expr
);
11768 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
11769 generate_code_expr_activate_refd(expr
);
11771 case OPTYPE_EXECUTE
: // r1 [v2]
11772 generate_code_expr_execute(expr
);
11774 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
11775 generate_code_expr_execute_refd(expr
);
11777 case OPTYPE_LOG2STR
:
11778 u
.expr
.logargs
->generate_code_expr(expr
);
11780 case OPTYPE_TTCN2STRING
: {
11781 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
11782 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
11783 param_governor
= param_governor
->get_type_refd_last();
11784 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
11785 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
11786 u
.expr
.ti1
->get_Template()->is_Value()) {
11787 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
11790 bool cast_needed
= v
->explicit_cast_needed();
11792 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
11794 v
->generate_code_expr(expr
);
11796 expr
->expr
= mputstr(expr
->expr
, ")");
11800 u
.expr
.ti1
->generate_code(expr
);
11802 expr
->expr
= mputstr(expr
->expr
, ")");
11804 case OPTYPE_PROF_RUNNING
:
11805 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
11808 FATAL_ERROR("Value::generate_code_expr_expr()");
11812 void Value::generate_code_expr_unary(expression_struct
*expr
,
11813 const char *operator_str
, Value
*v1
)
11815 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
11816 v1
->generate_code_expr_mandatory(expr
);
11817 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
11820 void Value::generate_code_expr_infix(expression_struct
*expr
,
11821 const char *operator_str
, Value
*v1
,
11822 Value
*v2
, bool optional_allowed
)
11824 if (!get_needs_conversion()) {
11825 expr
->expr
= mputc(expr
->expr
, '(');
11826 if (optional_allowed
) v1
->generate_code_expr(expr
);
11827 else v1
->generate_code_expr_mandatory(expr
);
11828 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
11829 if (optional_allowed
) v2
->generate_code_expr(expr
);
11830 else v2
->generate_code_expr_mandatory(expr
);
11831 expr
->expr
= mputc(expr
->expr
, ')');
11832 } else { // Temporary variable for the converted value.
11833 const string
& tmp_id1
= get_temporary_id();
11834 const char *tmp_id_str1
= tmp_id1
.c_str();
11835 expression_struct expr_tmp
;
11836 Code::init_expr(&expr_tmp
);
11837 switch (u
.expr
.v_optype
) {
11840 // Always "v1 -> v2".
11841 Type
*t1
= v1
->get_expr_governor_last();
11842 Type
*t2
= v2
->get_expr_governor_last();
11843 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
11844 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11845 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11846 if (expr_tmp
.preamble
)
11847 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11848 expr
->preamble
= mputprintf(expr
->preamble
,
11850 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11851 "and `%s' are not compatible at run-time\");\n",
11852 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
11853 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
11854 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
11855 t2
->get_typename().c_str(), t1
->get_typename().c_str());
11856 Code::free_expr(&expr_tmp
);
11857 if (optional_allowed
) v1
->generate_code_expr(expr
);
11858 else v1
->generate_code_expr_mandatory(expr
);
11859 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
11862 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11863 // functions. The governors of all operands must exist at this point.
11866 case OPTYPE_CONCAT
: {
11867 const string
& tmp_id2
= get_temporary_id();
11868 const char *tmp_id_str2
= tmp_id2
.c_str();
11869 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
11870 Type
*my_gov
= my_governor
->get_type_refd_last();
11871 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
11872 ->get_type_refd_last();
11873 if (!t1_gov
|| my_gov
== t1_gov
)
11874 FATAL_ERROR("Value::generate_code_expr_infix()");
11875 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11876 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
11877 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11878 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
11879 else v1
->generate_code_expr_mandatory(&expr_tmp
);
11880 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
11881 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11882 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11883 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11884 expr
->preamble
= mputprintf(expr
->preamble
,
11886 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11887 "and `%s' are not compatible at run-time\");\n",
11888 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11889 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
11890 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
11891 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
11892 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11895 FATAL_ERROR("Value::generate_code_expr_infix()");
11901 void Value::generate_code_expr_and_or(expression_struct
*expr
)
11903 if (u
.expr
.v2
->needs_short_circuit()) {
11904 // introduce a temporary variable to store the result of the operation
11905 const string
& tmp_id
= get_temporary_id();
11906 const char *tmp_id_str
= tmp_id
.c_str();
11907 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
11908 expression_struct expr2
;
11909 // the left operand must be evaluated anyway
11910 Code::init_expr(&expr2
);
11911 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11912 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
11913 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11914 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
11915 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
11916 // evaluate the right operand only when necessary
11917 // in this case the final result will be the right operand
11918 Code::init_expr(&expr2
);
11919 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11920 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
11921 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11922 // the result is now in the temporary variable
11923 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11925 // use the overloaded operator to get better error messages
11926 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
11927 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
11931 void Value::generate_code_expr_predef1(expression_struct
*expr
,
11932 const char *function_name
,
11935 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11936 v1
->generate_code_expr_mandatory(expr
);
11937 expr
->expr
= mputc(expr
->expr
, ')');
11940 void Value::generate_code_expr_predef2(expression_struct
*expr
,
11941 const char *function_name
,
11942 Value
*v1
, Value
*v2
)
11944 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11945 v1
->generate_code_expr_mandatory(expr
);
11946 expr
->expr
= mputstr(expr
->expr
, ", ");
11947 v2
->generate_code_expr_mandatory(expr
);
11948 expr
->expr
= mputc(expr
->expr
, ')');
11951 void Value::generate_code_expr_predef3(expression_struct
*expr
,
11952 const char *function_name
,
11953 Value
*v1
, Value
*v2
, Value
*v3
)
11955 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11956 v1
->generate_code_expr_mandatory(expr
);
11957 expr
->expr
= mputstr(expr
->expr
, ", ");
11958 v2
->generate_code_expr_mandatory(expr
);
11959 expr
->expr
= mputstr(expr
->expr
, ", ");
11960 v3
->generate_code_expr_mandatory(expr
);
11961 expr
->expr
= mputc(expr
->expr
, ')');
11964 void Value::generate_code_expr_substr(expression_struct
*expr
)
11967 Value
* v1
= u
.expr
.ti1
->get_specific_value();
11968 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11969 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
11970 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
11971 if (v1
) v1
->generate_code_expr_mandatory(expr
);
11972 else u
.expr
.ti1
->generate_code(expr
);
11973 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
11974 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
11975 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
11976 expr
->expr
= mputstr(expr
->expr
, "(int)");
11977 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
11978 expr
->expr
= mputstr(expr
->expr
, ", ");
11979 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
11980 expr
->expr
= mputstr(expr
->expr
, "(int)");
11981 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
11982 expr
->expr
= mputc(expr
->expr
, ')');
11985 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
11987 expression_struct expr_tmp
;
11988 Code::init_expr(&expr_tmp
);
11989 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11990 ->get_type_refd_last();
11991 if (!t1
|| t1
== my_governor
->get_type_refd_last())
11992 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11993 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
11994 generate_code_expr_substr(&expr_tmp
);
11995 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
11996 generate_code_expr_replace(&expr_tmp
);
11998 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12000 // Two temporaries to store the result of substr() or replace() and to
12001 // store the converted value.
12002 const string
& tmp_id1
= get_temporary_id();
12003 const char *tmp_id_str1
= tmp_id1
.c_str();
12004 const string
& tmp_id2
= get_temporary_id();
12005 const char *tmp_id_str2
= tmp_id2
.c_str();
12006 if (expr_tmp
.preamble
)
12007 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12008 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12009 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12010 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12011 if (expr_tmp
.postamble
)
12012 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12013 Code::free_expr(&expr_tmp
);
12014 expr
->preamble
= mputprintf(expr
->preamble
,
12015 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12016 "`%s' are not compatible at run-time\");\n",
12017 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12018 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12019 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12020 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12023 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12025 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12026 Value
* v2
= u
.expr
.t2
->get_specific_value();
12027 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12028 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12029 else u
.expr
.ti1
->generate_code(expr
);
12030 expr
->expr
= mputstr(expr
->expr
, ", ");
12031 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12032 else u
.expr
.t2
->generate_code(expr
);
12033 expr
->expr
= mputstr(expr
->expr
, ", ");
12034 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12035 expr
->expr
= mputc(expr
->expr
, ')');
12038 void Value::generate_code_expr_replace(expression_struct
*expr
)
12040 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12041 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12043 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12044 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12045 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12046 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12047 else u
.expr
.ti1
->generate_code(expr
);
12048 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12049 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12050 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12051 expr
->expr
= mputstr(expr
->expr
, "(int)");
12052 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12053 expr
->expr
= mputstr(expr
->expr
, ", ");
12054 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12055 expr
->expr
= mputstr(expr
->expr
, "(int)");
12056 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12057 expr
->expr
= mputstr(expr
->expr
, ", ");
12059 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12060 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12061 Value
* v4_last
= v4
->get_value_refd_last();
12062 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12063 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12064 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12066 v4
->generate_code_expr_mandatory(expr
);
12068 else u
.expr
.ti4
->generate_code(expr
);
12069 expr
->expr
= mputc(expr
->expr
, ')');
12072 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12075 if(!v1
) // simple random generation
12076 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12077 else { // random generation with seeding
12078 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12079 v1
->generate_code_expr_mandatory(expr
);
12080 expr
->expr
= mputc(expr
->expr
, ')');
12084 void Value::generate_code_expr_create(expression_struct
*expr
,
12085 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12087 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12088 // first two arguments: component type
12089 Assignment
*t_ass
= type
->get_refd_assignment();
12090 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12091 FATAL_ERROR("Value::generate_code_expr_create()");
12092 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12093 Type::EXPECTED_DYNAMIC_VALUE
);
12094 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12095 comptype
= comptype
->get_type_refd_last();
12096 expr
->expr
= comptype
->get_CompBody()
12097 ->generate_code_comptype_name(expr
->expr
);
12098 expr
->expr
= mputstr(expr
->expr
, ", ");
12099 // third argument: component name
12101 Value
*t_val
= name
->get_value_refd_last();
12102 if (t_val
->valuetype
== V_CSTR
) {
12103 // the argument is foldable to a string literal
12104 size_t str_len
= t_val
->u
.str
.val_str
->size();
12105 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12106 expr
->expr
= mputc(expr
->expr
, '"');
12107 for (size_t i
= 0; i
< str_len
; i
++)
12108 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12109 expr
->expr
= mputc(expr
->expr
, '"');
12110 } else name
->generate_code_expr_mandatory(expr
);
12111 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12112 expr
->expr
= mputstr(expr
->expr
, ", ");
12113 // fourth argument: location
12115 Value
*t_val
= location
->get_value_refd_last();
12116 if (t_val
->valuetype
== V_CSTR
) {
12117 // the argument is foldable to a string literal
12118 size_t str_len
= t_val
->u
.str
.val_str
->size();
12119 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12120 expr
->expr
= mputc(expr
->expr
, '"');
12121 for (size_t i
= 0; i
< str_len
; i
++)
12122 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12123 expr
->expr
= mputc(expr
->expr
, '"');
12124 } else location
->generate_code_expr_mandatory(expr
);
12125 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12126 // fifth argument: alive flag
12127 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12130 void Value::generate_code_expr_activate(expression_struct
*expr
)
12132 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12133 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12134 FATAL_ERROR("Value::generate_code_expr_activate()");
12135 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12136 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12137 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12138 expr
->expr
= mputc(expr
->expr
, ')');
12141 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12143 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12144 if (v_last
->valuetype
== V_ALTSTEP
) {
12145 // the referred altstep is known
12146 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12147 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12149 // the referred altstep is unknown
12150 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12151 expr
->expr
= mputstr(expr
->expr
,".activate(");
12153 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12154 expr
->expr
= mputc(expr
->expr
, ')');
12157 void Value::generate_code_expr_execute(expression_struct
*expr
)
12159 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12160 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12161 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12162 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12163 if (parlist
->get_nof_pars() > 0) {
12164 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12166 expr
->expr
= mputstr(expr
->expr
, ", ");
12169 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12170 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12171 expr
->expr
= mputc(expr
->expr
, ')');
12172 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12175 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12177 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12178 if (v_last
->valuetype
== V_TESTCASE
) {
12179 // the referred testcase is known
12180 Assignment
*testcase
= v_last
->get_refd_fat();
12181 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12182 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12183 u
.expr
.ap_list2
->generate_code_alias(expr
,
12184 testcase
->get_FormalParList(), 0, false);
12186 // the referred testcase is unknown
12187 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12188 expr
->expr
= mputstr(expr
->expr
,".execute(");
12189 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12191 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12192 expr
->expr
= mputstr(expr
->expr
, ", ");
12194 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12195 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12196 expr
->expr
= mputc(expr
->expr
, ')');
12197 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12200 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12202 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12203 if (last_v
->get_valuetype() == V_FUNCTION
) {
12204 // the referred function is known
12205 Assignment
*function
= last_v
->get_refd_fat();
12206 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12207 function
->get_genname_from_scope(my_scope
).c_str());
12208 u
.invoke
.ap_list
->generate_code_alias(expr
,
12209 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12211 // the referred function is unknown
12212 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12213 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12214 Type
* gov_last
= last_v
->get_expr_governor_last();
12215 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12216 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12218 expr
->expr
= mputc(expr
->expr
, ')');
12221 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12224 // if the referenced value points to an optional value field the
12225 // generated code has to be corrected at the end:
12226 // `fieldid()' => `fieldid()()'
12227 Assignment
*ass
= ref
->get_refd_assignment();
12228 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12229 switch (ass
->get_asstype()) {
12230 case Assignment::A_CONST
:
12231 case Assignment::A_EXT_CONST
:
12232 case Assignment::A_MODULEPAR
:
12233 case Assignment::A_VAR
:
12234 case Assignment::A_FUNCTION_RVAL
:
12235 case Assignment::A_EXT_FUNCTION_RVAL
:
12236 case Assignment::A_PAR_VAL_IN
:
12237 case Assignment::A_PAR_VAL_OUT
:
12238 case Assignment::A_PAR_VAL_INOUT
:
12239 // only these are mapped to value objects
12240 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12241 expr
->expr
= mputstr(expr
->expr
, "()");
12248 void Value::generate_code_expr_encode(expression_struct
*expr
)
12252 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12253 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12254 v1
= templ
->get_specific_value();
12255 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12257 expression_struct expr2
;
12258 Code::init_expr(&expr2
);
12260 bool is_templ
= false;
12261 switch (templ
->get_templatetype()) {
12262 case Template::SPECIFIC_VALUE
:
12263 v1
->generate_code_expr_mandatory(&expr2
);
12266 u
.expr
.ti1
->generate_code(&expr2
);
12271 if (!gov_last
->is_coding_by_function()) {
12272 const string
& tmp_id
= get_temporary_id();
12273 const string
& tmp_buf_id
= get_temporary_id();
12274 const string
& tmp_ref_id
= get_temporary_id();
12275 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12277 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12278 tmp_buf_id
.c_str());
12279 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12280 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12281 expr
->preamble
= mputc (expr
->preamble
, '\n');
12283 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12284 gov_last
->get_genname_typedescriptor(
12285 u
.expr
.ti1
->get_Template()->get_my_scope()
12287 tmp_ref_id
.c_str(),
12289 if (is_templ
) // make a value out of the template, if needed
12290 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12291 expr
->preamble
= mputprintf(expr
->preamble
,
12292 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12293 tmp_ref_id
.c_str(),
12294 gov_last
->get_genname_typedescriptor(
12295 u
.expr
.ti1
->get_Template()->get_my_scope()
12297 tmp_buf_id
.c_str(),
12298 gov_last
->get_coding(true).c_str()
12300 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12301 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12302 tmp_buf_id
.c_str(),
12305 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12306 if (expr2
.postamble
)
12307 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12309 expr
->expr
= mputprintf(expr
->expr
, "%s(%s)",
12310 gov_last
->get_coding(true).c_str(), expr2
.expr
);
12311 Code::free_expr(&expr2
);
12314 void Value::generate_code_expr_decode(expression_struct
*expr
)
12316 expression_struct expr1
, expr2
;
12317 Code::init_expr(&expr1
);
12318 Code::init_expr(&expr2
);
12319 u
.expr
.r1
->generate_code(&expr1
);
12320 u
.expr
.r2
->generate_code(&expr2
);
12322 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12323 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12324 get_type_refd_last();
12326 if (expr1
.preamble
)
12327 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12328 if (expr2
.preamble
)
12329 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12331 if (!_type
->is_coding_by_function()) {
12332 const string
& tmp_id
= get_temporary_id();
12333 const string
& buffer_id
= get_temporary_id();
12334 const string
& retval_id
= get_temporary_id();
12335 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12336 field_is_optional(u
.expr
.r2
->get_subrefs());
12338 expr
->preamble
= mputprintf(expr
->preamble
,
12339 "TTCN_Buffer %s(bit2oct(%s));\n"
12341 "TTCN_EncDec::set_error_behavior("
12342 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12343 "TTCN_EncDec::clear_error();\n",
12348 expr
->preamble
= mputprintf(expr
->preamble
,
12349 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12351 optional
? "()" : "",
12352 _type
->get_genname_typedescriptor(
12353 u
.expr
.r2
->get_my_scope()
12356 _type
->get_coding(false).c_str()
12358 expr
->preamble
= mputprintf(expr
->preamble
,
12359 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12360 "case TTCN_EncDec::ET_NONE: {\n"
12362 "OCTETSTRING %s;\n"
12363 "%s.get_string(%s);\n"
12364 "%s = oct2bit(%s);\n"
12367 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12368 "case TTCN_EncDec::ET_LEN_ERR:\n"
12374 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12375 "TTCN_EncDec::EB_DEFAULT);\n"
12376 "TTCN_EncDec::clear_error();\n",
12387 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12389 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12390 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12391 if (expr1
.postamble
)
12392 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12393 if (expr2
.postamble
)
12394 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12395 Code::free_expr(&expr1
);
12396 Code::free_expr(&expr2
);
12399 char *Value::generate_code_init_choice(char *str
, const char *name
)
12401 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12402 // Safe as long as get_name() returns a const string&, not a temporary.
12403 const char *alt_prefix
=
12404 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12406 if (u
.choice
.alt_value
->needs_temp_ref()) {
12407 const string
& tmp_id
= get_temporary_id();
12408 const char *tmp_id_str
= tmp_id
.c_str();
12409 str
= mputprintf(str
, "{\n"
12410 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12411 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12412 alt_prefix
, alt_name
);
12413 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12414 str
= mputstr(str
, "}\n");
12416 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12417 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12418 Free(embedded_name
);
12423 char *Value::generate_code_init_seof(char *str
, const char *name
)
12425 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12427 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12428 const string
& embedded_type
=
12429 my_governor
->get_ofType()->get_genname_value(my_scope
);
12430 const char *embedded_type_str
= embedded_type
.c_str();
12431 for (size_t i
= 0; i
< nof_vs
; i
++) {
12432 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12434 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12435 else if (comp_v
->needs_temp_ref()) {
12436 const string
& tmp_id
= get_temporary_id();
12437 const char *tmp_id_str
= tmp_id
.c_str();
12438 str
= mputprintf(str
, "{\n"
12439 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12440 (unsigned long) i
);
12441 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12442 str
= mputstr(str
, "}\n");
12444 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12445 str
= comp_v
->generate_code_init(str
, embedded_name
);
12446 Free(embedded_name
);
12450 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12455 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12457 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12459 // Previous values can be truncated. The concept is similar to
12461 Type
*t_last
= my_governor
->get_type_refd_last();
12462 const string
& oftype_name
=
12463 t_last
->get_ofType()->get_genname_value(my_scope
);
12464 const char *oftype_name_str
= oftype_name
.c_str();
12465 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12466 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12467 const string
& tmp_id_1
= get_temporary_id();
12468 str
= mputstr(str
, "{\n");
12469 Value
*index
= iv
->get_index();
12470 if (index
->get_valuetype() != V_INT
) {
12471 const string
& tmp_id_2
= get_temporary_id();
12472 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12473 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12474 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12475 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12477 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12478 tmp_id_1
.c_str(), name
,
12479 (index
->get_val_Int()->t_str()).c_str());
12481 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12482 str
= mputstr(str
, "}\n");
12484 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12488 char *Value::generate_code_init_array(char *str
, const char *name
)
12490 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12491 Type
*t_last
= my_governor
->get_type_refd_last();
12492 Int index_offset
= t_last
->get_dimension()->get_offset();
12493 const string
& embedded_type
=
12494 t_last
->get_ofType()->get_genname_value(my_scope
);
12495 const char *embedded_type_str
= embedded_type
.c_str();
12496 for (size_t i
= 0; i
< nof_vs
; i
++) {
12497 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12498 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12499 else if (comp_v
->needs_temp_ref()) {
12500 const string
& tmp_id
= get_temporary_id();
12501 const char *tmp_id_str
= tmp_id
.c_str();
12502 str
= mputprintf(str
, "{\n"
12503 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12504 Int2string(index_offset
+ i
).c_str());
12505 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12506 str
= mputstr(str
, "}\n");
12508 char *embedded_name
= mprintf("%s[%s]", name
,
12509 Int2string(index_offset
+ i
).c_str());
12510 str
= comp_v
->generate_code_init(str
, embedded_name
);
12511 Free(embedded_name
);
12517 char *Value::generate_code_init_se(char *str
, const char *name
)
12519 Type
*type
= my_governor
->get_type_refd_last();
12520 size_t nof_comps
= type
->get_nof_comps();
12521 if (nof_comps
> 0) {
12522 for (size_t i
= 0; i
< nof_comps
; i
++) {
12523 CompField
*cf
= type
->get_comp_byIndex(i
);
12524 const Identifier
& field_id
= cf
->get_name();
12525 const char *field_name
= field_id
.get_name().c_str();
12527 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12528 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12529 if (field_v
->valuetype
== V_NOTUSED
) continue;
12530 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12531 } else if (is_asn1()) {
12532 if (cf
->has_default()) {
12533 // handle like a referenced value
12534 Value
*defval
= cf
->get_defval();
12535 if (needs_init_precede(defval
)) {
12536 str
= defval
->generate_code_init(str
,
12537 defval
->get_lhs_name().c_str());
12539 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12540 defval
->get_genname_own(my_scope
).c_str());
12543 if (!cf
->get_is_optional())
12544 FATAL_ERROR("Value::generate_code_init()");
12551 // the value is not omit
12552 if (field_v
->needs_temp_ref()) {
12553 const string
& tmp_id
= get_temporary_id();
12554 const char *tmp_id_str
= tmp_id
.c_str();
12555 str
= mputprintf(str
, "{\n"
12556 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
12557 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12559 str
= field_v
->generate_code_init(str
, tmp_id_str
);
12560 str
= mputstr(str
, "}\n");
12562 char *embedded_name
= mprintf("%s.%s()", name
,
12564 if (cf
->get_is_optional() && field_v
->is_compound())
12565 embedded_name
= mputstr(embedded_name
, "()");
12566 str
= field_v
->generate_code_init(str
, embedded_name
);
12567 Free(embedded_name
);
12570 // the value is omit
12571 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
12576 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12581 char *Value::generate_code_init_refd(char *str
, const char *name
)
12583 Value
*v
= get_value_refd_last();
12585 // the referred value is not available at compile time
12586 // the code generation is based on the reference
12587 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
12588 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
12590 expression_struct expr
;
12591 Code::init_expr(&expr
);
12592 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
12593 u
.ref
.ref
->generate_code_const_ref(&expr
);
12594 str
= Code::merge_free_expr(str
, &expr
);
12597 // the referred value is available at compile time
12598 // the code generation is based on the referred value
12599 if (v
->has_single_expr() &&
12600 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
12601 // simple substitution for in-line values within the same module
12602 str
= mputprintf(str
, "%s = %s;\n", name
,
12603 v
->get_single_expr().c_str());
12605 // use a simple reference to reduce code size
12606 if (needs_init_precede(v
)) {
12607 // the referred value must be initialized first
12608 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
12609 // temporary id should be introduced for the lhs
12610 const string
& tmp_id
= get_temporary_id();
12611 const char *tmp_id_str
= tmp_id
.c_str();
12612 str
= mputprintf(str
, "{\n"
12614 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
12615 tmp_id_str
, v
->get_lhs_name().c_str());
12616 str
= v
->generate_code_init(str
, tmp_id_str
);
12617 str
= mputstr(str
, "}\n");
12619 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
12622 str
= mputprintf(str
, "%s = %s;\n", name
,
12623 v
->get_genname_own(my_scope
).c_str());
12629 /** This type contains the JSON encoding type of an omitted optional field */
12630 enum omitted_json_value_t
{
12631 NOT_OMITTED
, // the field is not omitted
12632 OMITTED_ABSENT
, // the omitted field is not present in the JSON object
12633 OMITTED_NULL
// the omitted field is set to 'null' in the JSON object
12636 /** JSON code for omitted optional fields of can be generated in 2 ways:
12637 * - the field is not present in the JSON object or
12638 * - the field is present and its value is 'null'.
12639 * Because of this all record/set values containing omitted fields have 2^N
12640 * possible JSON encodings, where N is the number of omitted fields.
12642 * This function helps go through all the possible encodings, by generating
12643 * the next combination from a previous one.
12645 * The algorithm is basically adding 1 to a binary number (where OMITTED_ABSENT
12646 * is zero, OMITTED_NULL is one, all NOT_OMITTEDs are ignored and the first bit
12647 * is the least significant bit).
12649 * Usage: generate the first combination, where all omitted fields are absent
12650 * (=all zeros), and keep calling this function until the last combination
12651 * (where all omitted fields are 'null', = all ones) is reached.
12653 * @return true, if the next combination was successfully generated, or
12654 * false, when called with the last combination */
12655 static bool next_omitted_json_combo(int* omitted_fields
, size_t len
)
12657 for (size_t i
= 0; i
< len
; ++i
) {
12658 if (omitted_fields
[i
] == OMITTED_ABSENT
) {
12659 omitted_fields
[i
] = OMITTED_NULL
;
12660 for (size_t j
= 0; j
< i
; ++j
) {
12661 if (omitted_fields
[j
] == OMITTED_NULL
) {
12662 omitted_fields
[j
] = OMITTED_ABSENT
;
12671 void Value::generate_json_value(JSON_Tokenizer
& json
, bool allow_special_float
/* = true */)
12673 switch (valuetype
) {
12675 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
12678 Real r
= get_val_Real();
12679 if (r
== REAL_INFINITY
) {
12680 if (allow_special_float
) {
12681 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
12684 else if (r
== -REAL_INFINITY
) {
12685 if (allow_special_float
) {
12686 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
12690 if (allow_special_float
) {
12691 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
12695 // true if decimal representation possible (use %f format)
12696 bool decimal_repr
= (r
== 0.0)
12697 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
12698 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
12699 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
12700 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
12705 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
12711 char* str
= convert_to_json_string(get_val_str().c_str());
12712 json
.put_next_token(JSON_TOKEN_STRING
, str
);
12716 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
12717 json
.put_next_token(JSON_TOKEN_STRING
, str
);
12722 json
.put_next_token(JSON_TOKEN_STRING
,
12723 (string('\"') + create_stringRepr() + string('\"')).c_str());
12727 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
12728 if (!u
.val_vs
->is_indexed()) {
12729 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
12730 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
);
12734 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
12735 // look for the entry with index equal to i
12736 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
12737 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
12738 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
);
12744 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
12748 // omitted fields have 2 possible JSON values (the field is absent, or it's
12749 // present with value 'null'), each combination of omitted values must be
12751 size_t len
= get_nof_comps();
12752 int* omitted_fields
= new int[len
]; // stores one combination
12753 for (size_t i
= 0; i
< len
; ++i
) {
12754 if (get_se_comp_byIndex(i
)->get_value()->valuetype
== V_OMIT
) {
12755 // all omitted fields are absent in the first combination
12756 omitted_fields
[i
] = OMITTED_ABSENT
;
12759 omitted_fields
[i
] = NOT_OMITTED
;
12763 // generate the JSON object from the present combination
12764 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
12765 for (size_t i
= 0; i
< len
; ++i
) {
12766 if (omitted_fields
[i
] == OMITTED_ABSENT
) {
12767 // the field is absent, don't insert anything
12770 // use the field's alias, if it has one
12771 const char* alias
= NULL
;
12772 if (my_governor
!= NULL
) {
12773 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
12774 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
12775 if (field_attrib
!= NULL
) {
12776 alias
= field_attrib
->alias
;
12779 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
12780 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
12781 if (omitted_fields
[i
] == OMITTED_NULL
) {
12782 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
12785 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
);
12788 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
12789 } // generate the next combination, until all combinations have been processed
12790 while (next_omitted_json_combo(omitted_fields
, len
));
12793 bool as_value
= my_governor
!= NULL
&&
12794 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
12795 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
12797 // no 'as value' coding instruction, insert an object with one field
12798 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
12799 // use the field's alias, if it has one
12800 const char* alias
= NULL
;
12801 if (my_governor
!= NULL
) {
12802 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
12803 get_alt_name())->get_type()->get_json_attributes();
12804 if (field_attrib
!= NULL
) {
12805 alias
= field_attrib
->alias
;
12808 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
12809 get_alt_name().get_ttcnname().c_str());
12811 get_alt_value()->generate_json_value(json
);
12813 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
12817 Value
* v
= get_value_refd_last();
12819 v
->generate_json_value(json
);
12824 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
12828 bool Value::explicit_cast_needed(bool forIsValue
)
12830 Value
*v_last
= get_value_refd_last();
12831 if (v_last
!= this) {
12832 // this is a foldable referenced value
12833 // if the reference points to an imported or compound value the code
12834 // generation will be based on the reference so cast is not needed
12835 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
12836 || !v_last
->has_single_expr()) return false;
12837 } else if (v_last
->valuetype
== V_REFD
) {
12838 // this is an unfoldable reference (v_last==this)
12839 // explicit cast is needed only for string element references
12840 if (forIsValue
) return false;
12841 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
12842 return t_subrefs
&& t_subrefs
->refers_to_string_element();
12844 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
12845 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
12846 switch (t_governor
->get_typetype()) {
12850 case Type::T_INT_A
:
12852 case Type::T_ENUM_A
:
12853 case Type::T_ENUM_T
:
12854 case Type::T_VERDICT
:
12855 case Type::T_COMPONENT
:
12856 // these are mapped to built-in C/C++ types
12858 case Type::T_SEQ_A
:
12859 case Type::T_SEQ_T
:
12860 case Type::T_SET_A
:
12861 case Type::T_SET_T
:
12862 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12863 return t_governor
->get_nof_comps() == 0;
12864 case Type::T_SEQOF
:
12865 case Type::T_SETOF
:
12866 // the C++ equivalent of value {} is ambiguous
12869 case Type::T_FUNCTION
:
12870 case Type::T_ALTSTEP
:
12871 case Type::T_TESTCASE
:
12878 bool Value::has_single_expr()
12880 if (get_needs_conversion()) return false;
12881 switch (valuetype
) {
12883 return has_single_expr_expr();
12886 // a union or array value cannot be represented as an in-line expression
12890 // only an empty record/set of value can be represented as an in-line
12892 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
12893 else return u
.val_vs
->get_nof_ivs() == 0;
12896 // only a value for an empty record/set type can be represented as an
12897 // in-line expression
12898 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
12899 Type
*type
= my_governor
->get_type_refd_last();
12900 return type
->get_nof_comps() == 0; }
12902 Value
*v_last
= get_value_refd_last();
12903 // If the above call hit an error and set_valuetype(V_ERROR),
12904 // then u.ref.ref has been freed. Avoid the segfault.
12905 if (valuetype
== V_ERROR
)
12907 if (v_last
!= this && v_last
->has_single_expr() &&
12908 v_last
->my_scope
->get_scope_mod_gen() ==
12909 my_scope
->get_scope_mod_gen()) return true;
12910 else return u
.ref
.ref
->has_single_expr(); }
12912 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
12916 case V_UNDEF_LOWERID
:
12917 case V_UNDEF_BLOCK
:
12919 // these values cannot occur during code generation
12920 FATAL_ERROR("Value::has_single_expr()");
12922 return u
.val_Int
->is_native_fit();
12924 // other value types (literal values) do not need temporary reference
12929 string
Value::get_single_expr()
12931 switch (valuetype
) {
12933 return string("ASN_NULL_VALUE");
12935 return string(u
.val_bool
? "TRUE" : "FALSE");
12937 if (u
.val_Int
->is_native_fit()) { // Be sure.
12938 return u
.val_Int
->t_str();
12940 // get_single_expr may be called only if has_single_expr() is true.
12941 // The only exception is V_INT, where get_single_expr may be called
12942 // even if is_native_fit (which is used to implement has_single_expr)
12944 string
ret_val('"');
12945 ret_val
+= u
.val_Int
->t_str();
12950 return Real2code(u
.val_Real
);
12952 return get_single_expr_enum();
12954 return get_my_scope()->get_scope_mod_gen()
12955 ->add_bitstring_literal(*u
.str
.val_str
);
12957 return get_my_scope()->get_scope_mod_gen()
12958 ->add_hexstring_literal(*u
.str
.val_str
);
12960 return get_my_scope()->get_scope_mod_gen()
12961 ->add_octetstring_literal(*u
.str
.val_str
);
12963 return get_my_scope()->get_scope_mod_gen()
12964 ->add_charstring_literal(*u
.str
.val_str
);
12966 if (u
.ustr
.convert_str
) {
12967 set_valuetype(V_CSTR
);
12968 return get_my_scope()->get_scope_mod_gen()
12969 ->add_charstring_literal(*u
.str
.val_str
);
12971 return get_my_scope()->get_scope_mod_gen()
12972 ->add_ustring_literal(*u
.ustr
.val_ustr
);
12974 return get_single_expr_iso2022str();
12977 vector
<string
> comps
;
12978 bool is_constant
= get_oid_comps(comps
);
12979 size_t nof_comps
= comps
.size();
12981 for (size_t i
= 0; i
< nof_comps
; i
++) {
12982 if (i
> 0) oi_str
+= ", ";
12983 oi_str
+= *(comps
[i
]);
12985 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
12988 // the objid only contains constants
12989 // => create a literal and return its name
12990 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
12992 // the objid contains at least one variable
12993 // => append the number of components before the component values in the string and return it
12994 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
12997 if (u
.val_vs
->get_nof_vs() > 0)
12998 FATAL_ERROR("Value::get_single_expr()");
12999 return string("NULL_VALUE");
13002 if (u
.val_nvs
->get_nof_nvs() > 0)
13003 FATAL_ERROR("Value::get_single_expr()");
13004 return string("NULL_VALUE");
13006 Value
*v_last
= get_value_refd_last();
13007 if (v_last
!= this && v_last
->has_single_expr() &&
13008 v_last
->my_scope
->get_scope_mod_gen() ==
13009 my_scope
->get_scope_mod_gen()) {
13010 // the reference points to another single value in the same module
13011 return v_last
->get_single_expr();
13013 // convert the reference to a single expression
13014 expression_struct expr
;
13015 Code::init_expr(&expr
);
13016 u
.ref
.ref
->generate_code_const_ref(&expr
);
13017 if (expr
.preamble
|| expr
.postamble
)
13018 FATAL_ERROR("Value::get_single_expr()");
13019 string
ret_val(expr
.expr
);
13020 Code::free_expr(&expr
);
13024 return string("OMIT_VALUE");
13026 switch (u
.verdict
) {
13028 return string("NONE");
13030 return string("PASS");
13031 case Verdict_INCONC
:
13032 return string("INCONC");
13034 return string("FAIL");
13035 case Verdict_ERROR
:
13036 return string("ERROR");
13038 FATAL_ERROR("Value::get_single_expr()");
13041 case V_DEFAULT_NULL
:
13042 return string("NULL_COMPREF");
13044 string
ret_val('(');
13045 ret_val
+= my_governor
->get_genname_value(my_scope
);
13046 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13050 expression_struct expr
;
13051 Code::init_expr(&expr
);
13052 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13053 else generate_code_expr_invoke(&expr
);
13054 if (expr
.preamble
|| expr
.postamble
)
13055 FATAL_ERROR("Value::get_single_expr()");
13056 string
ret_val(expr
.expr
);
13057 Code::free_expr(&expr
);
13061 case MACRO_TESTCASEID
:
13062 return string("TTCN_Runtime::get_testcase_id_macro()");
13064 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13070 return get_single_expr_fat();
13072 FATAL_ERROR("Value::get_single_expr()");
13077 bool Value::has_single_expr_expr()
13079 switch (u
.expr
.v_optype
) {
13080 case OPTYPE_RND
: // -
13081 case OPTYPE_COMP_NULL
:
13082 case OPTYPE_COMP_MTC
:
13083 case OPTYPE_COMP_SYSTEM
:
13084 case OPTYPE_COMP_SELF
:
13085 case OPTYPE_COMP_RUNNING_ANY
:
13086 case OPTYPE_COMP_RUNNING_ALL
:
13087 case OPTYPE_COMP_ALIVE_ANY
:
13088 case OPTYPE_COMP_ALIVE_ALL
:
13089 case OPTYPE_TMR_RUNNING_ANY
:
13090 case OPTYPE_GETVERDICT
:
13091 case OPTYPE_TESTCASENAME
:
13092 case OPTYPE_PROF_RUNNING
:
13094 case OPTYPE_ENCODE
:
13095 case OPTYPE_DECODE
:
13096 case OPTYPE_ISBOUND
:
13097 case OPTYPE_ISPRESENT
:
13098 case OPTYPE_TTCN2STRING
:
13100 case OPTYPE_UNARYPLUS
: // v1
13101 case OPTYPE_UNARYMINUS
:
13104 case OPTYPE_BIT2HEX
:
13105 case OPTYPE_BIT2INT
:
13106 case OPTYPE_BIT2OCT
:
13107 case OPTYPE_BIT2STR
:
13108 case OPTYPE_CHAR2INT
:
13109 case OPTYPE_CHAR2OCT
:
13110 case OPTYPE_FLOAT2INT
:
13111 case OPTYPE_FLOAT2STR
:
13112 case OPTYPE_HEX2BIT
:
13113 case OPTYPE_HEX2INT
:
13114 case OPTYPE_HEX2OCT
:
13115 case OPTYPE_HEX2STR
:
13116 case OPTYPE_INT2CHAR
:
13117 case OPTYPE_INT2FLOAT
:
13118 case OPTYPE_INT2STR
:
13119 case OPTYPE_INT2UNICHAR
:
13120 case OPTYPE_OCT2BIT
:
13121 case OPTYPE_OCT2CHAR
:
13122 case OPTYPE_OCT2HEX
:
13123 case OPTYPE_OCT2INT
:
13124 case OPTYPE_OCT2STR
:
13125 case OPTYPE_STR2BIT
:
13126 case OPTYPE_STR2FLOAT
:
13127 case OPTYPE_STR2HEX
:
13128 case OPTYPE_STR2INT
:
13129 case OPTYPE_STR2OCT
:
13130 case OPTYPE_UNICHAR2INT
:
13131 case OPTYPE_UNICHAR2CHAR
:
13132 case OPTYPE_ENUM2INT
:
13133 case OPTYPE_RNDWITHVAL
:
13134 case OPTYPE_ISCHOSEN_V
: // v1 i2
13135 case OPTYPE_COMP_RUNNING
:
13136 case OPTYPE_COMP_ALIVE
:
13137 case OPTYPE_GET_STRINGENCODING
:
13138 case OPTYPE_REMOVE_BOM
:
13139 case OPTYPE_DECODE_BASE64
:
13140 return u
.expr
.v1
->has_single_expr();
13141 case OPTYPE_ISCHOSEN_T
: // t1 i2
13142 return u
.expr
.t1
->has_single_expr();
13143 case OPTYPE_ADD
: // v1 v2
13144 case OPTYPE_SUBTRACT
:
13145 case OPTYPE_MULTIPLY
:
13146 case OPTYPE_DIVIDE
:
13149 case OPTYPE_CONCAT
:
13164 case OPTYPE_INT2BIT
:
13165 case OPTYPE_INT2HEX
:
13166 case OPTYPE_INT2OCT
:
13167 return u
.expr
.v1
->has_single_expr() &&
13168 u
.expr
.v2
->has_single_expr();
13169 case OPTYPE_UNICHAR2OCT
:
13170 case OPTYPE_OCT2UNICHAR
:
13171 case OPTYPE_ENCODE_BASE64
:
13172 return u
.expr
.v1
->has_single_expr() &&
13173 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13176 return u
.expr
.v1
->has_single_expr() &&
13177 u
.expr
.v2
->has_single_expr() &&
13178 !u
.expr
.v2
->needs_short_circuit();
13179 case OPTYPE_SUBSTR
:
13180 return u
.expr
.ti1
->has_single_expr() &&
13181 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13182 case OPTYPE_REGEXP
:
13183 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13184 u
.expr
.v3
->has_single_expr();
13185 case OPTYPE_DECOMP
: // v1 v2 v3
13186 return u
.expr
.v1
->has_single_expr() &&
13187 u
.expr
.v2
->has_single_expr() &&
13188 u
.expr
.v3
->has_single_expr();
13189 case OPTYPE_REPLACE
:
13190 return u
.expr
.ti1
->has_single_expr() &&
13191 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13192 u
.expr
.ti4
->has_single_expr();
13193 case OPTYPE_ISVALUE
: // ti1
13194 case OPTYPE_LENGTHOF
: // ti1
13195 case OPTYPE_SIZEOF
: // ti1
13196 case OPTYPE_VALUEOF
: // ti1
13197 return u
.expr
.ti1
->has_single_expr();
13198 case OPTYPE_LOG2STR
:
13199 return u
.expr
.logargs
->has_single_expr();
13200 case OPTYPE_MATCH
: // v1 t2
13201 return u
.expr
.v1
->has_single_expr() &&
13202 u
.expr
.t2
->has_single_expr();
13203 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13204 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13205 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13206 case OPTYPE_TMR_READ
: // r1
13207 case OPTYPE_TMR_RUNNING
:
13208 case OPTYPE_ACTIVATE
:
13209 return u
.expr
.r1
->has_single_expr();
13210 case OPTYPE_EXECUTE
: // r1 [v2]
13211 return u
.expr
.r1
->has_single_expr() &&
13212 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13213 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13214 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13215 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13216 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13217 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13219 FATAL_ERROR("Value::has_single_expr_expr()");
13223 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13225 if (!v
->has_single_expr()) return false;
13226 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13227 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13231 string
Value::get_single_expr_enum()
13233 string
ret_val(my_governor
->get_genname_value(my_scope
));
13235 ret_val
+= u
.val_id
->get_name();
13239 string
Value::get_single_expr_iso2022str()
13242 Type
*type
= get_my_governor()->get_type_refd_last();
13243 switch (type
->get_typetype()) {
13244 case Type::T_TELETEXSTRING
:
13245 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13247 case Type::T_VIDEOTEXSTRING
:
13248 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13250 case Type::T_GRAPHICSTRING
:
13251 case Type::T_OBJECTDESCRIPTOR
:
13252 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13254 case Type::T_GENERALSTRING
:
13255 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13258 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13261 string
*ostr
= char2oct(*u
.str
.val_str
);
13262 ret_val
+= get_my_scope()->get_scope_mod_gen()
13263 ->add_octetstring_literal(*ostr
);
13269 string
Value::get_single_expr_fat()
13271 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13272 // the ampersand operator is not really necessary to obtain the function
13273 // pointer, but some older versions of GCC cannot instantiate the
13274 // appropriate operator=() member of class OPTIONAL when necessary
13275 // if only the function name is given
13276 string
ret_val('&');
13277 switch (valuetype
) {
13279 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13282 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13283 ret_val
+= "_instance";
13286 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13289 FATAL_ERROR("Value::get_single_expr_fat()");
13294 bool Value::is_compound()
13296 switch (valuetype
) {
13309 bool Value::needs_temp_ref()
13311 switch (valuetype
) {
13314 if (!is_indexed()) {
13315 // Temporary reference is needed if the value has at least one real
13316 // element (i.e. it is not empty or contains only not used symbols).
13317 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13318 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13321 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13322 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13323 ->valuetype
!= V_NOTUSED
)
13329 size_t nof_real_vs
= 0;
13330 if (!is_indexed()) {
13331 // Temporary reference is needed if the array value has at least two
13332 // real elements (excluding not used symbols).
13333 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13334 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13336 if (nof_real_vs
> 1) return true;
13340 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13341 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13342 ->valuetype
!= V_NOTUSED
) {
13344 if (nof_real_vs
> 1) return true;
13352 // it depends on the type since fields with omit or default value
13353 // may not be present
13354 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13356 // incomplete values are allowed in TTCN-3
13357 // we should check the number of value components
13358 return u
.val_nvs
->get_nof_nvs() > 1;
13363 case V_UNDEF_LOWERID
:
13364 case V_UNDEF_BLOCK
:
13366 // these values cannot occur during code generation
13367 FATAL_ERROR("Value::needs_temp_ref()");
13369 return !u
.val_Int
->is_native();
13371 // other value types (literal values) do not need temporary reference
13376 bool Value::needs_short_circuit()
13378 switch (valuetype
) {
13386 // sub-expressions should be evaluated only if necessary
13389 FATAL_ERROR("Value::needs_short_circuit()");
13391 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13392 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13393 switch (t_ass
->get_asstype()) {
13394 case Assignment::A_FUNCTION_RVAL
:
13395 case Assignment::A_EXT_FUNCTION_RVAL
:
13396 // avoid unnecessary call of a function
13398 case Assignment::A_CONST
:
13399 case Assignment::A_EXT_CONST
:
13400 case Assignment::A_MODULEPAR
:
13401 case Assignment::A_VAR
:
13402 case Assignment::A_PAR_VAL_IN
:
13403 case Assignment::A_PAR_VAL_OUT
:
13404 case Assignment::A_PAR_VAL_INOUT
:
13405 // depends on field/array sub-references, which is examined below
13408 FATAL_ERROR("Value::needs_short_circuit()");
13410 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13412 // the evaluation of the reference does not have side effects
13413 // (i.e. false shall be returned) only if all sub-references point to
13414 // mandatory fields of record/set types, and neither sub-reference points
13415 // to a field of a union type
13416 Type
*t_type
= t_ass
->get_Type();
13417 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13418 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13419 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13420 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13421 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13422 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13423 t_cf
->get_is_optional()) return true;
13424 t_type
= t_cf
->get_type();
13425 } else return true;
13431 void Value::dump(unsigned level
) const
13433 switch (valuetype
) {
13457 case V_DEFAULT_NULL
:
13465 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13469 DEBUG(level
, "Value: reference");
13470 u
.ref
.ref
->dump(level
+ 1);
13472 case V_UNDEF_LOWERID
:
13473 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13475 case V_UNDEF_BLOCK
:
13476 DEBUG(level
, "Value: {block}");
13479 DEBUG(level
, "Value: null");
13482 DEBUG(level
, "Value: invoke");
13483 u
.invoke
.v
->dump(level
+ 1);
13484 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13485 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13488 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13492 void Value::add_string_element(size_t index
, Value
*v_element
,
13493 map
<size_t, Value
>*& string_elements
)
13495 v_element
->set_my_scope(get_my_scope());
13496 v_element
->set_my_governor(get_my_governor());
13497 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13498 v_element
->set_location(*this);
13499 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13500 string_elements
->add(index
, v_element
);
13503 ///////////////////////////////////////////////////////////////////////////////
13504 // class LazyParamData
13506 int LazyParamData::depth
= 0;
13507 bool LazyParamData::used_as_lvalue
= false;
13508 vector
<string
>* LazyParamData::type_vec
= NULL
;
13509 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13511 void LazyParamData::init(bool p_used_as_lvalue
) {
13512 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13514 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13515 used_as_lvalue
= p_used_as_lvalue
;
13516 type_vec
= new vector
<string
>;
13517 refd_vec
= new vector
<string
>;
13522 void LazyParamData::clean() {
13523 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13524 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13527 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13532 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13540 bool LazyParamData::in_lazy() {
13541 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13545 // returns a temporary id instead of the C++ reference to a definition
13546 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13547 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13548 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13549 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13550 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13551 // store the type of the assignment
13552 string
* type_str
= new string
;
13553 switch (ass
->get_asstype()) {
13554 case Assignment::A_MODULEPAR_TEMP
:
13555 case Assignment::A_TEMPLATE
:
13556 case Assignment::A_VAR_TEMPLATE
:
13557 case Assignment::A_PAR_TEMPL_IN
:
13558 case Assignment::A_PAR_TEMPL_OUT
:
13559 case Assignment::A_PAR_TEMPL_INOUT
:
13560 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13563 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13565 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13566 bool refd_ass_is_lazy_fpar
= false;
13567 switch (ass
->get_asstype()) {
13568 case Assignment::A_PAR_VAL
:
13569 case Assignment::A_PAR_VAL_IN
:
13570 case Assignment::A_PAR_TEMPL_IN
:
13571 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13572 if (refd_ass_is_lazy_fpar
) {
13573 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13579 // add the "const" part if the referenced assignment is a constant thing
13580 if (!refd_ass_is_lazy_fpar
) {
13581 switch (ass
->get_asstype()) {
13582 case Assignment::A_CONST
:
13583 case Assignment::A_OC
:
13584 case Assignment::A_OBJECT
:
13585 case Assignment::A_OS
:
13586 case Assignment::A_VS
:
13587 case Assignment::A_EXT_CONST
:
13588 case Assignment::A_MODULEPAR
:
13589 case Assignment::A_MODULEPAR_TEMP
:
13590 case Assignment::A_TEMPLATE
:
13591 case Assignment::A_PAR_VAL
:
13592 case Assignment::A_PAR_VAL_IN
:
13593 case Assignment::A_PAR_TEMPL_IN
:
13594 *type_str
= string("const ") + *type_str
;
13602 type_vec
->add(type_str
);
13603 // store the C++ reference string
13604 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
13605 if (refd_ass_is_lazy_fpar
) {
13606 Type
* refd_ass_type
= ass
->get_Type();
13607 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
);
13608 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
13610 return get_member_name(refd_vec
->size()-1);
13614 string
LazyParamData::get_member_name(size_t idx
) {
13615 return string("lpm_") + Int2string(idx
);
13618 string
LazyParamData::get_constr_param_name(size_t idx
) {
13619 return string("lpp_") + Int2string(idx
);
13622 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
13623 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13624 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
13625 const string
& tmp_id
= val
->get_temporary_id();
13626 const char *tmp_id_str
= tmp_id
.c_str();
13627 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13628 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13630 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13632 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13634 val
->generate_code_expr(expr
);
13638 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
13639 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13640 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
13641 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
13642 const char *tmp_id_str
= tmp_id
.c_str();
13643 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13644 temp
->get_Template()->get_my_governor()
13645 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
13646 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13647 tmp_id_str
, temp
->get_Template());
13648 // Not incorporated into gen_conv_code() yet.
13649 if (gen_restriction_check
!= TR_NONE
)
13650 expr
->preamble
= Template::generate_restriction_check_code(
13651 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
13652 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13653 } else temp
->generate_code(expr
, gen_restriction_check
);
13656 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13657 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13659 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13660 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13661 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13662 expression_struct value_expr
;
13663 Code::init_expr(&value_expr
);
13664 generate_code_for_value(&value_expr
, value
, scope
);
13665 // the id of the instance of Lazy_Param which will be used as the actual parameter
13666 const string
& lazy_param_id
= value
->get_temporary_id();
13667 if (value_expr
.preamble
) {
13668 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
13670 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13671 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13672 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
13673 Code::free_expr(&value_expr
);
13674 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13677 // only if the formal parameter is *not* used as lvalue
13678 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
13679 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
13681 bool refd_ass_is_lazy_fpar
= false;
13682 switch (refd_ass
->get_asstype()) {
13683 case Assignment::A_PAR_VAL
:
13684 case Assignment::A_PAR_VAL_IN
:
13685 case Assignment::A_PAR_TEMPL_IN
:
13686 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13691 if (refd_ass_is_lazy_fpar
) {
13692 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13697 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13698 expression_struct value_expr
;
13699 Code::init_expr(&value_expr
);
13700 generate_code_for_value(&value_expr
, value
, scope
);
13701 // the id of the instance of Lazy_Param which will be used as the actual parameter
13702 string lazy_param_id
= value
->get_temporary_id();
13703 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
13704 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
13707 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
13708 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13710 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13711 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13712 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13713 expression_struct tmpl_expr
;
13714 Code::init_expr(&tmpl_expr
);
13715 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13716 // the id of the instance of Lazy_Param which will be used as the actual parameter
13717 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
13718 if (tmpl_expr
.preamble
) {
13719 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
13721 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13722 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13723 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
13724 Code::free_expr(&tmpl_expr
);
13725 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13728 // only if the formal parameter is *not* used as lvalue
13729 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
13730 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
13732 bool refd_ass_is_lazy_fpar
= false;
13733 switch (refd_ass
->get_asstype()) {
13734 case Assignment::A_PAR_VAL
:
13735 case Assignment::A_PAR_VAL_IN
:
13736 case Assignment::A_PAR_TEMPL_IN
:
13737 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13742 if (refd_ass_is_lazy_fpar
) {
13743 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13748 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13749 expression_struct tmpl_expr
;
13750 Code::init_expr(&tmpl_expr
);
13751 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13752 // the id of the instance of Lazy_Param which will be used as the actual parameter
13753 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
13754 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
13755 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
13758 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
13759 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
13760 if (type_vec
->size()>0) {
13761 // private members of the local class will be const references to the objects referenced by the expression
13762 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13763 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
13765 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
13766 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
13767 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13768 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13769 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
13771 expr
->preamble
= mputstr(expr
->preamble
, "): ");
13772 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13773 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13774 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
13776 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
13777 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
13779 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
13780 // use the temporary expr structure to fill the body of the eval_expr() function
13781 if (param_expr
.preamble
) {
13782 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
13784 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
13785 if (param_expr
.postamble
) {
13786 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
13788 Code::free_expr(¶m_expr
);
13789 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
13790 "};\n" // end of local class definition
13792 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
13793 if (type_vec
->size()>0) {
13794 expr
->preamble
= mputc(expr
->preamble
, '(');
13795 // paramteres of the constructor are references to the objects used in the expression
13796 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
13797 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13798 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
13800 expr
->preamble
= mputc(expr
->preamble
, ')');
13802 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
13803 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13804 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
13807 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
13808 expression_struct ref_expr
;
13809 Code::init_expr(&ref_expr
);
13810 ref
->generate_code(&ref_expr
);
13811 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
13812 if (ref_expr
.preamble
) {
13813 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
13815 Assignment
* ass
= ref
->get_refd_assignment();
13816 // determine C++ type of the assignment
13818 switch (ass
->get_asstype()) {
13819 case Assignment::A_MODULEPAR_TEMP
:
13820 case Assignment::A_TEMPLATE
:
13821 case Assignment::A_VAR_TEMPLATE
:
13822 case Assignment::A_PAR_TEMPL_IN
:
13823 case Assignment::A_PAR_TEMPL_OUT
:
13824 case Assignment::A_PAR_TEMPL_INOUT
:
13825 type_str
= ass
->get_Type()->get_genname_template(scope
);
13828 type_str
= ass
->get_Type()->get_genname_value(scope
);
13830 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13831 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
13832 if (ref_expr
.postamble
) {
13833 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
13835 Code::free_expr(&ref_expr
);
13836 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13839 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13840 const string
& lazy_param_id
= value
->get_temporary_id();
13841 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13842 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13843 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
13844 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13847 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
13848 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
13849 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13850 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13851 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
13852 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13855 } // namespace Common