1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
25 * Szabo, Janos Zoltan – initial implementation
28 * Zalanyi, Balazs Andor
30 ******************************************************************************/
31 #include "../common/dbgnew.hh"
33 #include "Identifier.hh"
34 #include "Valuestuff.hh"
35 #include "PredefFunc.hh"
36 #include "CompField.hh"
37 #include "CompType.hh"
38 #include "EnumItem.hh"
39 #include "TypeCompat.hh"
40 #include "asn1/Block.hh"
41 #include "asn1/TokenBuf.hh"
47 #include "ttcn3/TtcnTemplate.hh"
48 #include "ttcn3/ArrayDimensions.hh"
50 #include "../common/pattern.hh"
52 #include "ttcn3/PatternString.hh"
53 #include "ttcn3/Statement.hh"
55 #include "ttcn3/Attributes.hh"
56 #include "../common/JSON_Tokenizer.hh"
57 #include "ttcn3/Ttcn2Json.hh"
65 static void clean_up_string_elements(map
<size_t, Value
>*& string_elements
)
67 if (string_elements
) {
68 for (size_t i
= 0; i
< string_elements
->size(); i
++)
69 delete string_elements
->get_nth_elem(i
);
70 string_elements
->clear();
71 delete string_elements
;
76 // =================================
78 // =================================
80 Value::Value(const Value
& p
)
81 : GovernedSimple(p
), valuetype(p
.valuetype
), my_governor(0)
93 u
.val_bool
=p
.u
.val_bool
;
96 u
.val_Int
=new int_val_t(*(p
.u
.val_Int
));
100 case V_UNDEF_LOWERID
:
101 u
.val_id
=p
.u
.val_id
->clone();
104 u
.val_Real
=p
.u
.val_Real
;
111 set_val_str(new string(*p
.u
.str
.val_str
));
114 set_val_ustr(new ustring(*p
.u
.ustr
.val_ustr
));
115 u
.ustr
.convert_str
= p
.u
.ustr
.convert_str
;
118 u
.char_syms
= p
.u
.char_syms
->clone();
122 u
.oid_comps
=new vector
<OID_comp
>;
123 for(size_t i
=0; i
<p
.u
.oid_comps
->size(); i
++)
124 add_oid_comp((*p
.u
.oid_comps
)[i
]->clone());
127 u
.choice
.alt_name
=p
.u
.choice
.alt_name
->clone();
128 u
.choice
.alt_value
=p
.u
.choice
.alt_value
->clone();
133 u
.val_vs
=p
.u
.val_vs
->clone();
137 u
.val_nvs
=p
.u
.val_nvs
->clone();
140 u
.ref
.ref
=p
.u
.ref
.ref
->clone();
144 for(size_t i
=0; i
<p
.u
.ids
->size(); i
++) {
145 Identifier
*id
= p
.u
.ids
->get_nth_elem(i
);
146 u
.ids
->add(id
->get_name(), id
->clone());
150 u
.block
=p
.u
.block
->clone();
153 u
.verdict
=p
.u
.verdict
;
156 u
.expr
.v_optype
= p
.u
.expr
.v_optype
;
157 u
.expr
.state
= EXPR_NOT_CHECKED
;
158 switch(u
.expr
.v_optype
) {
159 case OPTYPE_RND
: // -
160 case OPTYPE_COMP_NULL
:
161 case OPTYPE_COMP_MTC
:
162 case OPTYPE_COMP_SYSTEM
:
163 case OPTYPE_COMP_SELF
:
164 case OPTYPE_COMP_RUNNING_ANY
:
165 case OPTYPE_COMP_RUNNING_ALL
:
166 case OPTYPE_COMP_ALIVE_ANY
:
167 case OPTYPE_COMP_ALIVE_ALL
:
168 case OPTYPE_TMR_RUNNING_ANY
:
169 case OPTYPE_GETVERDICT
:
170 case OPTYPE_TESTCASENAME
:
171 case OPTYPE_PROF_RUNNING
:
173 case OPTYPE_UNARYPLUS
: // v1
174 case OPTYPE_UNARYMINUS
:
181 case OPTYPE_CHAR2INT
:
182 case OPTYPE_CHAR2OCT
:
183 case OPTYPE_COMP_RUNNING
:
184 case OPTYPE_COMP_ALIVE
:
185 case OPTYPE_FLOAT2INT
:
186 case OPTYPE_FLOAT2STR
:
191 case OPTYPE_INT2CHAR
:
192 case OPTYPE_INT2FLOAT
:
194 case OPTYPE_INT2UNICHAR
:
196 case OPTYPE_OCT2CHAR
:
201 case OPTYPE_STR2FLOAT
:
205 case OPTYPE_UNICHAR2INT
:
206 case OPTYPE_UNICHAR2CHAR
:
207 case OPTYPE_ENUM2INT
:
208 case OPTYPE_RNDWITHVAL
:
209 case OPTYPE_GET_STRINGENCODING
:
210 case OPTYPE_DECODE_BASE64
:
211 case OPTYPE_REMOVE_BOM
:
212 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
214 case OPTYPE_ADD
: // v1 v2
215 case OPTYPE_SUBTRACT
:
216 case OPTYPE_MULTIPLY
:
240 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
241 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
243 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
244 case OPTYPE_OCT2UNICHAR
:
245 case OPTYPE_ENCODE_BASE64
:
246 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
247 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
250 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
251 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
254 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
255 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
256 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
259 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
260 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
261 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
263 case OPTYPE_DECOMP
: // v1 v2 v3
264 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
265 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
266 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
269 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
270 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
271 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
272 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
274 case OPTYPE_LENGTHOF
: // ti1
275 case OPTYPE_SIZEOF
: // ti1
276 case OPTYPE_VALUEOF
: // ti1
278 case OPTYPE_ISPRESENT
:
279 case OPTYPE_TTCN2STRING
:
280 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
282 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
283 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
284 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
286 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
287 u
.expr
.r1
= p
.u
.expr
.r1
->clone();
288 u
.expr
.r2
= p
.u
.expr
.r2
->clone();
289 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
291 case OPTYPE_UNDEF_RUNNING
:
292 case OPTYPE_TMR_READ
:
293 case OPTYPE_TMR_RUNNING
:
294 case OPTYPE_ACTIVATE
:
295 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
297 case OPTYPE_EXECUTE
: // r1 [v2]
298 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
299 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
301 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
302 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
303 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
304 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
305 u
.expr
.b4
= p
.u
.expr
.b4
;
307 case OPTYPE_MATCH
: // v1 t2
308 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
309 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
311 case OPTYPE_ISCHOSEN
: // r1 i2
312 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
313 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
315 case OPTYPE_ISCHOSEN_V
: // v1 i2
316 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
317 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
319 case OPTYPE_ISCHOSEN_T
: // t1 i2
320 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
321 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
323 case OPTYPE_ACTIVATE_REFD
:
324 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
325 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
326 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
328 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
329 u
.expr
.state
= EXPR_CHECKED
;
332 case OPTYPE_EXECUTE_REFD
:
333 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
334 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
335 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
337 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
338 u
.expr
.state
= EXPR_CHECKED
;
340 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
343 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
346 FATAL_ERROR("Value::Value()");
355 u
.refd_fat
= p
.u
.refd_fat
;
358 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
359 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
360 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
363 u
.refered
= p
.u
.refered
->clone();
366 FATAL_ERROR("Value::Value()");
370 void Value::clean_up()
393 case V_UNDEF_LOWERID
:
401 delete u
.str
.val_str
;
402 clean_up_string_elements(u
.str
.str_elements
);
405 delete u
.ustr
.val_ustr
;
406 clean_up_string_elements(u
.ustr
.ustr_elements
);
414 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
415 delete (*u
.oid_comps
)[i
];
416 u
.oid_comps
->clear();
424 delete u
.choice
.alt_name
;
425 delete u
.choice
.alt_value
;
444 delete u
.invoke
.t_list
;
445 delete u
.invoke
.ap_list
;
449 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
458 FATAL_ERROR("Value::clean_up()");
462 void Value::clean_up_expr()
464 switch (u
.expr
.state
) {
466 case EXPR_CHECKING_ERR
:
467 FATAL_ERROR("Value::clean_up_expr()");
471 switch (u
.expr
.v_optype
) {
472 case OPTYPE_RND
: // -
473 case OPTYPE_COMP_NULL
:
474 case OPTYPE_COMP_MTC
:
475 case OPTYPE_COMP_SYSTEM
:
476 case OPTYPE_COMP_SELF
:
477 case OPTYPE_COMP_RUNNING_ANY
:
478 case OPTYPE_COMP_RUNNING_ALL
:
479 case OPTYPE_COMP_ALIVE_ANY
:
480 case OPTYPE_COMP_ALIVE_ALL
:
481 case OPTYPE_TMR_RUNNING_ANY
:
482 case OPTYPE_GETVERDICT
:
483 case OPTYPE_TESTCASENAME
:
484 case OPTYPE_PROF_RUNNING
:
486 case OPTYPE_UNARYPLUS
: // v1
487 case OPTYPE_UNARYMINUS
:
494 case OPTYPE_CHAR2INT
:
495 case OPTYPE_CHAR2OCT
:
496 case OPTYPE_COMP_RUNNING
:
497 case OPTYPE_COMP_ALIVE
:
498 case OPTYPE_FLOAT2INT
:
499 case OPTYPE_FLOAT2STR
:
504 case OPTYPE_INT2CHAR
:
505 case OPTYPE_INT2FLOAT
:
507 case OPTYPE_INT2UNICHAR
:
509 case OPTYPE_OCT2CHAR
:
514 case OPTYPE_STR2FLOAT
:
518 case OPTYPE_UNICHAR2INT
:
519 case OPTYPE_UNICHAR2CHAR
:
520 case OPTYPE_ENUM2INT
:
521 case OPTYPE_RNDWITHVAL
:
522 case OPTYPE_REMOVE_BOM
:
523 case OPTYPE_GET_STRINGENCODING
:
524 case OPTYPE_DECODE_BASE64
:
527 case OPTYPE_ADD
: // v1 v2
528 case OPTYPE_SUBTRACT
:
529 case OPTYPE_MULTIPLY
:
553 case OPTYPE_UNICHAR2OCT
:
554 case OPTYPE_OCT2UNICHAR
:
555 case OPTYPE_ENCODE_BASE64
:
573 case OPTYPE_DECOMP
: // v1 v2 v3
584 case OPTYPE_LENGTHOF
: // ti1
585 case OPTYPE_SIZEOF
: // ti1
586 case OPTYPE_VALUEOF
: // ti1
590 case OPTYPE_ISPRESENT
:
591 case OPTYPE_TTCN2STRING
:
594 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
598 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
603 case OPTYPE_UNDEF_RUNNING
:
604 case OPTYPE_TMR_READ
:
605 case OPTYPE_TMR_RUNNING
:
606 case OPTYPE_ACTIVATE
:
609 case OPTYPE_EXECUTE
: // r1 [v2]
613 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
618 case OPTYPE_MATCH
: // v1 t2
622 case OPTYPE_ISCHOSEN
: // r1 i2
626 case OPTYPE_ISCHOSEN_V
: // v1 i2
630 case OPTYPE_ISCHOSEN_T
: // t1 i2
634 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
636 if(u
.expr
.state
!=EXPR_CHECKED
)
637 delete u
.expr
.t_list2
;
639 delete u
.expr
.ap_list2
;
641 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
643 if(u
.expr
.state
!=EXPR_CHECKED
)
644 delete u
.expr
.t_list2
;
646 delete u
.expr
.ap_list2
;
650 delete u
.expr
.logargs
;
653 FATAL_ERROR("Value::clean_up_expr()");
657 void Value::copy_and_destroy(Value
*src
)
660 valuetype
= src
->valuetype
;
662 // update the pointer used for caching if it points to the value itself
663 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
664 src
->valuetype
= V_ERROR
;
668 Value::Value(valuetype_t p_vt
)
669 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
680 u
.oid_comps
=new vector
<OID_comp
>();
683 u
.ids
=new map
<string
, Identifier
>();
686 FATAL_ERROR("Value::Value()");
690 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
691 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
695 u
.val_bool
=p_val_bool
;
698 FATAL_ERROR("Value::Value()");
702 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
703 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
707 u
.val_Int
=new int_val_t(p_val_Int
);
710 FATAL_ERROR("Value::Value()");
714 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
715 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
722 FATAL_ERROR("Value::Value()");
726 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
727 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
729 if(!p_val_str
) FATAL_ERROR("NULL parameter");
736 set_val_str(p_val_str
);
739 FATAL_ERROR("Value::Value()");
743 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
744 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
746 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
747 set_val_ustr(p_val_ustr
);
748 u
.ustr
.convert_str
= false;
751 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
752 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
754 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
757 u
.char_syms
= p_char_syms
;
760 FATAL_ERROR("Value::Value()");
764 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
765 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
768 FATAL_ERROR("NULL parameter");
772 case V_UNDEF_LOWERID
:
776 FATAL_ERROR("Value::Value()");
780 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
781 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
784 FATAL_ERROR("NULL parameter");
787 u
.choice
.alt_name
=p_id
;
788 u
.choice
.alt_value
=p_val
;
791 FATAL_ERROR("Value::Value()");
795 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
796 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
800 u
.val_Real
=p_val_Real
;
803 FATAL_ERROR("Value::Value()");
807 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
808 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
810 if(!p_vs
) FATAL_ERROR("NULL parameter");
818 FATAL_ERROR("Value::Value()");
822 Value::Value(valuetype_t p_vt
, Value
*p_v
,
823 Ttcn::ParsedActualParameters
*p_t_list
)
824 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
826 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
830 u
.invoke
.t_list
= p_t_list
;
831 u
.invoke
.ap_list
= 0;
834 FATAL_ERROR("Value::Value()");
839 Value::Value(operationtype_t p_optype
)
840 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
842 u
.expr
.v_optype
= p_optype
;
843 u
.expr
.state
= EXPR_NOT_CHECKED
;
846 case OPTYPE_COMP_NULL
:
847 case OPTYPE_COMP_MTC
:
848 case OPTYPE_COMP_SYSTEM
:
849 case OPTYPE_COMP_SELF
:
850 case OPTYPE_COMP_RUNNING_ANY
:
851 case OPTYPE_COMP_RUNNING_ALL
:
852 case OPTYPE_COMP_ALIVE_ANY
:
853 case OPTYPE_COMP_ALIVE_ALL
:
854 case OPTYPE_TMR_RUNNING_ANY
:
855 case OPTYPE_GETVERDICT
:
856 case OPTYPE_TESTCASENAME
:
857 case OPTYPE_PROF_RUNNING
:
860 FATAL_ERROR("Value::Value()");
865 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
866 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
868 u
.expr
.v_optype
= p_optype
;
869 u
.expr
.state
= EXPR_NOT_CHECKED
;
871 case OPTYPE_UNARYPLUS
:
872 case OPTYPE_UNARYMINUS
:
879 case OPTYPE_CHAR2INT
:
880 case OPTYPE_CHAR2OCT
:
881 case OPTYPE_COMP_RUNNING
:
882 case OPTYPE_COMP_ALIVE
:
883 case OPTYPE_FLOAT2INT
:
884 case OPTYPE_FLOAT2STR
:
889 case OPTYPE_INT2CHAR
:
890 case OPTYPE_INT2FLOAT
:
892 case OPTYPE_INT2UNICHAR
:
894 case OPTYPE_OCT2CHAR
:
899 case OPTYPE_STR2FLOAT
:
903 case OPTYPE_UNICHAR2INT
:
904 case OPTYPE_UNICHAR2CHAR
:
905 case OPTYPE_ENUM2INT
:
906 case OPTYPE_RNDWITHVAL
:
907 case OPTYPE_REMOVE_BOM
:
908 case OPTYPE_GET_STRINGENCODING
:
909 case OPTYPE_DECODE_BASE64
:
910 if(!p_v1
) FATAL_ERROR("Value::Value()");
914 FATAL_ERROR("Value::Value()");
919 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
920 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
922 u
.expr
.v_optype
= p_optype
;
923 u
.expr
.state
= EXPR_NOT_CHECKED
;
925 case OPTYPE_LENGTHOF
:
931 case OPTYPE_ENCVALUE_UNICHAR
:
932 case OPTYPE_ISPRESENT
:
933 case OPTYPE_TTCN2STRING
:
934 if(!p_ti1
) FATAL_ERROR("Value::Value()");
938 FATAL_ERROR("Value::Value()");
943 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
944 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
946 u
.expr
.v_optype
= p_optype
;
947 u
.expr
.state
= EXPR_NOT_CHECKED
;
949 case OPTYPE_UNDEF_RUNNING
:
950 case OPTYPE_TMR_READ
:
951 case OPTYPE_TMR_RUNNING
:
952 case OPTYPE_ACTIVATE
:
953 if(!p_r1
) FATAL_ERROR("Value::Value()");
957 FATAL_ERROR("Value::Value()");
962 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
963 Ttcn::ParsedActualParameters
*p_ap_list
)
964 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
966 u
.expr
.v_optype
= p_optype
;
967 u
.expr
.state
= EXPR_NOT_CHECKED
;
969 case OPTYPE_ACTIVATE_REFD
:
970 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
972 u
.expr
.t_list2
= p_ap_list
;
975 FATAL_ERROR("Value::Value()");
980 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
981 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
982 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
984 u
.expr
.v_optype
= p_optype
;
985 u
.expr
.state
= EXPR_NOT_CHECKED
;
987 case OPTYPE_EXECUTE_REFD
:
988 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
990 u
.expr
.t_list2
= p_t_list2
;
994 FATAL_ERROR("Value::Value()");
999 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
1000 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1002 u
.expr
.v_optype
= p_optype
;
1003 u
.expr
.state
= EXPR_NOT_CHECKED
;
1005 case OPTYPE_EXECUTE
:
1006 if(!p_r1
) FATAL_ERROR("Value::Value()");
1011 FATAL_ERROR("Value::Value()");
1016 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
1017 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
1018 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1020 u
.expr
.v_optype
= p_optype
;
1021 u
.expr
.state
= EXPR_NOT_CHECKED
;
1023 case OPTYPE_COMP_CREATE
:
1024 if(!p_r1
) FATAL_ERROR("Value::Value()");
1031 FATAL_ERROR("Value::Value()");
1036 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
1037 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1039 u
.expr
.v_optype
= p_optype
;
1040 u
.expr
.state
= EXPR_NOT_CHECKED
;
1043 case OPTYPE_SUBTRACT
:
1044 case OPTYPE_MULTIPLY
:
1065 case OPTYPE_INT2BIT
:
1066 case OPTYPE_INT2HEX
:
1067 case OPTYPE_INT2OCT
:
1068 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1072 case OPTYPE_UNICHAR2OCT
:
1073 case OPTYPE_OCT2UNICHAR
:
1074 case OPTYPE_ENCODE_BASE64
:
1075 if(!p_v1
) FATAL_ERROR("Value::Value()");
1077 // p_v2 may be NULL if there is no second param
1081 FATAL_ERROR("Value::Value()");
1086 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1087 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1088 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1090 u
.expr
.v_optype
= p_optype
;
1091 u
.expr
.state
= EXPR_NOT_CHECKED
;
1093 case OPTYPE_REPLACE
:
1094 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1101 FATAL_ERROR("Value::Value()");
1106 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1107 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1109 u
.expr
.v_optype
= p_optype
;
1110 u
.expr
.state
= EXPR_NOT_CHECKED
;
1113 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1119 FATAL_ERROR("Value::Value()");
1124 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
)
1125 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1127 u
.expr
.v_optype
= p_optype
;
1128 u
.expr
.state
= EXPR_NOT_CHECKED
;
1130 case OPTYPE_ENCVALUE_UNICHAR
:
1131 if(!p_ti1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1136 FATAL_ERROR("Value::Value()");
1141 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1142 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1144 u
.expr
.v_optype
=p_optype
;
1145 u
.expr
.state
=EXPR_NOT_CHECKED
;
1148 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1154 FATAL_ERROR("Value::Value()");
1159 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1160 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1162 u
.expr
.v_optype
=p_optype
;
1163 u
.expr
.state
=EXPR_NOT_CHECKED
;
1166 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1172 FATAL_ERROR("Value::Value()");
1177 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1178 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1180 u
.expr
.v_optype
= p_optype
;
1181 u
.expr
.state
= EXPR_NOT_CHECKED
;
1184 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1189 FATAL_ERROR("Value::Value()");
1194 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1196 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1198 u
.expr
.v_optype
= p_optype
;
1199 u
.expr
.state
= EXPR_NOT_CHECKED
;
1201 case OPTYPE_ISCHOSEN
:
1202 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1207 FATAL_ERROR("Value::Value()");
1211 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1212 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1214 u
.expr
.v_optype
= p_optype
;
1215 u
.expr
.state
= EXPR_NOT_CHECKED
;
1217 case OPTYPE_LOG2STR
:
1218 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1219 u
.expr
.logargs
= p_logargs
;
1222 FATAL_ERROR("Value::Value()");
1226 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1227 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1229 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1230 switch (p_macrotype
) {
1231 case MACRO_MODULEID
:
1232 case MACRO_FILENAME
:
1233 case MACRO_BFILENAME
:
1234 case MACRO_FILEPATH
:
1235 case MACRO_LINENUMBER
:
1236 case MACRO_LINENUMBER_C
:
1237 case MACRO_DEFINITIONID
:
1239 case MACRO_TESTCASEID
:
1242 FATAL_ERROR("Value::Value()");
1244 u
.macro
= p_macrotype
;
1247 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1248 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1250 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1257 FATAL_ERROR("Value::Value()");
1261 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1262 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1264 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1268 u
.ref
.refd_last
= 0;
1274 FATAL_ERROR("Value::Value()");
1278 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1279 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1281 if(!p_block
) FATAL_ERROR("NULL parameter");
1287 FATAL_ERROR("Value::Value()");
1291 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1292 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1294 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1295 switch (p_verdict
) {
1298 case Verdict_INCONC
:
1303 FATAL_ERROR("Value::Value()");
1305 u
.verdict
= p_verdict
;
1308 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1309 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1311 u
.expr
.v_optype
= p_optype
;
1312 u
.expr
.state
= EXPR_NOT_CHECKED
;
1315 case OPTYPE_DECVALUE_UNICHAR
:
1316 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1321 FATAL_ERROR("Value::Value()");
1326 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
,
1328 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1330 u
.expr
.v_optype
= p_optype
;
1331 u
.expr
.state
= EXPR_NOT_CHECKED
;
1333 case OPTYPE_DECVALUE_UNICHAR
:
1334 if(!p_r1
|| !p_r2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1340 FATAL_ERROR("Value::Value()");
1349 Value
*Value::clone() const
1351 return new Value(*this);
1354 Value::operationtype_t
Value::get_optype() const
1356 if(valuetype
!=V_EXPR
)
1357 FATAL_ERROR("Value::get_optype()");
1358 return u
.expr
.v_optype
;
1361 void Value::set_my_governor(Type
*p_gov
)
1364 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1368 Type
*Value::get_my_governor() const
1373 void Value::set_fullname(const string
& p_fullname
)
1375 GovernedSimple::set_fullname(p_fullname
);
1378 u
.char_syms
->set_fullname(p_fullname
);
1382 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1383 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1386 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1387 u
.choice
.alt_name
->get_dispname());
1392 u
.val_vs
->set_fullname(p_fullname
);
1396 u
.val_nvs
->set_fullname(p_fullname
);
1399 u
.ref
.ref
->set_fullname(p_fullname
);
1402 u
.refered
->set_fullname(p_fullname
);
1405 u
.invoke
.v
->set_fullname(p_fullname
);
1406 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1407 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1410 set_fullname_expr(p_fullname
);
1417 void Value::set_my_scope(Scope
*p_scope
)
1419 GovernedSimple::set_my_scope(p_scope
);
1422 u
.char_syms
->set_my_scope(p_scope
);
1426 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1427 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1430 u
.choice
.alt_value
->set_my_scope(p_scope
);
1435 u
.val_vs
->set_my_scope(p_scope
);
1439 u
.val_nvs
->set_my_scope(p_scope
);
1442 u
.ref
.ref
->set_my_scope(p_scope
);
1445 u
.refered
->set_my_scope(p_scope
);
1448 u
.invoke
.v
->set_my_scope(p_scope
);
1449 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1450 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1453 set_my_scope_expr(p_scope
);
1460 void Value::set_fullname_expr(const string
& p_fullname
)
1462 switch (u
.expr
.v_optype
) {
1463 case OPTYPE_RND
: // -
1464 case OPTYPE_COMP_NULL
:
1465 case OPTYPE_COMP_MTC
:
1466 case OPTYPE_COMP_SYSTEM
:
1467 case OPTYPE_COMP_SELF
:
1468 case OPTYPE_COMP_RUNNING_ANY
:
1469 case OPTYPE_COMP_RUNNING_ALL
:
1470 case OPTYPE_COMP_ALIVE_ANY
:
1471 case OPTYPE_COMP_ALIVE_ALL
:
1472 case OPTYPE_TMR_RUNNING_ANY
:
1473 case OPTYPE_GETVERDICT
:
1474 case OPTYPE_TESTCASENAME
:
1475 case OPTYPE_PROF_RUNNING
:
1477 case OPTYPE_UNARYPLUS
: // v1
1478 case OPTYPE_UNARYMINUS
:
1481 case OPTYPE_BIT2HEX
:
1482 case OPTYPE_BIT2INT
:
1483 case OPTYPE_BIT2OCT
:
1484 case OPTYPE_BIT2STR
:
1485 case OPTYPE_CHAR2INT
:
1486 case OPTYPE_CHAR2OCT
:
1487 case OPTYPE_COMP_RUNNING
:
1488 case OPTYPE_COMP_ALIVE
:
1489 case OPTYPE_FLOAT2INT
:
1490 case OPTYPE_FLOAT2STR
:
1491 case OPTYPE_HEX2BIT
:
1492 case OPTYPE_HEX2INT
:
1493 case OPTYPE_HEX2OCT
:
1494 case OPTYPE_HEX2STR
:
1495 case OPTYPE_INT2CHAR
:
1496 case OPTYPE_INT2FLOAT
:
1497 case OPTYPE_INT2STR
:
1498 case OPTYPE_INT2UNICHAR
:
1499 case OPTYPE_OCT2BIT
:
1500 case OPTYPE_OCT2CHAR
:
1501 case OPTYPE_OCT2HEX
:
1502 case OPTYPE_OCT2INT
:
1503 case OPTYPE_OCT2STR
:
1504 case OPTYPE_STR2BIT
:
1505 case OPTYPE_STR2FLOAT
:
1506 case OPTYPE_STR2HEX
:
1507 case OPTYPE_STR2INT
:
1508 case OPTYPE_STR2OCT
:
1509 case OPTYPE_UNICHAR2INT
:
1510 case OPTYPE_UNICHAR2CHAR
:
1511 case OPTYPE_ENUM2INT
:
1512 case OPTYPE_RNDWITHVAL
:
1513 case OPTYPE_REMOVE_BOM
:
1514 case OPTYPE_GET_STRINGENCODING
:
1515 case OPTYPE_DECODE_BASE64
:
1516 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1518 case OPTYPE_ADD
: // v1 v2
1519 case OPTYPE_SUBTRACT
:
1520 case OPTYPE_MULTIPLY
:
1541 case OPTYPE_INT2BIT
:
1542 case OPTYPE_INT2HEX
:
1543 case OPTYPE_INT2OCT
:
1544 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1545 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1547 case OPTYPE_UNICHAR2OCT
:
1548 case OPTYPE_OCT2UNICHAR
:
1549 case OPTYPE_ENCODE_BASE64
:
1550 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1551 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1554 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1555 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1558 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1559 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1560 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1563 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1564 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1565 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1567 case OPTYPE_DECOMP
: // v1 v2 v3
1568 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1569 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1570 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1572 case OPTYPE_REPLACE
:
1573 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1574 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1575 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1576 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1578 case OPTYPE_LENGTHOF
: // ti1
1579 case OPTYPE_SIZEOF
: // ti1
1580 case OPTYPE_VALUEOF
: // ti1
1581 case OPTYPE_ISVALUE
:
1582 case OPTYPE_ISBOUND
:
1584 case OPTYPE_ISPRESENT
:
1585 case OPTYPE_TTCN2STRING
:
1586 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1588 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
1589 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1590 if (u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1592 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1593 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1594 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1595 if (u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1596 case OPTYPE_UNDEF_RUNNING
: // r1
1597 case OPTYPE_TMR_READ
:
1598 case OPTYPE_TMR_RUNNING
:
1599 case OPTYPE_ACTIVATE
:
1600 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1602 case OPTYPE_EXECUTE
: // r1 [v2]
1603 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1604 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1606 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1607 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1608 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1609 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1611 case OPTYPE_MATCH
: // v1 t2
1612 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1613 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1615 case OPTYPE_ISCHOSEN
: // r1 i2
1616 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1618 case OPTYPE_ISCHOSEN_V
: // v1 i2
1619 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1621 case OPTYPE_ISCHOSEN_T
: // t1 i2
1622 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1624 case OPTYPE_ACTIVATE_REFD
:
1625 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1626 if(u
.expr
.state
!=EXPR_CHECKED
)
1627 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1629 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1631 case OPTYPE_EXECUTE_REFD
:
1632 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1633 if(u
.expr
.state
!=EXPR_CHECKED
)
1634 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1636 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1638 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1640 case OPTYPE_LOG2STR
:
1641 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1644 FATAL_ERROR("Value::set_fullname_expr()");
1648 void Value::set_my_scope_expr(Scope
*p_scope
)
1650 switch (u
.expr
.v_optype
) {
1651 case OPTYPE_RND
: // -
1652 case OPTYPE_COMP_NULL
:
1653 case OPTYPE_COMP_MTC
:
1654 case OPTYPE_COMP_SYSTEM
:
1655 case OPTYPE_COMP_SELF
:
1656 case OPTYPE_COMP_RUNNING_ANY
:
1657 case OPTYPE_COMP_RUNNING_ALL
:
1658 case OPTYPE_COMP_ALIVE_ANY
:
1659 case OPTYPE_COMP_ALIVE_ALL
:
1660 case OPTYPE_TMR_RUNNING_ANY
:
1661 case OPTYPE_GETVERDICT
:
1662 case OPTYPE_TESTCASENAME
:
1663 case OPTYPE_PROF_RUNNING
:
1665 case OPTYPE_UNARYPLUS
: // v1
1666 case OPTYPE_UNARYMINUS
:
1669 case OPTYPE_BIT2HEX
:
1670 case OPTYPE_BIT2INT
:
1671 case OPTYPE_BIT2OCT
:
1672 case OPTYPE_BIT2STR
:
1673 case OPTYPE_CHAR2INT
:
1674 case OPTYPE_CHAR2OCT
:
1675 case OPTYPE_COMP_RUNNING
:
1676 case OPTYPE_COMP_ALIVE
:
1677 case OPTYPE_FLOAT2INT
:
1678 case OPTYPE_FLOAT2STR
:
1679 case OPTYPE_HEX2BIT
:
1680 case OPTYPE_HEX2INT
:
1681 case OPTYPE_HEX2OCT
:
1682 case OPTYPE_HEX2STR
:
1683 case OPTYPE_INT2CHAR
:
1684 case OPTYPE_INT2FLOAT
:
1685 case OPTYPE_INT2STR
:
1686 case OPTYPE_INT2UNICHAR
:
1687 case OPTYPE_OCT2BIT
:
1688 case OPTYPE_OCT2CHAR
:
1689 case OPTYPE_OCT2HEX
:
1690 case OPTYPE_OCT2INT
:
1691 case OPTYPE_OCT2STR
:
1692 case OPTYPE_STR2BIT
:
1693 case OPTYPE_STR2FLOAT
:
1694 case OPTYPE_STR2HEX
:
1695 case OPTYPE_STR2INT
:
1696 case OPTYPE_STR2OCT
:
1697 case OPTYPE_UNICHAR2INT
:
1698 case OPTYPE_UNICHAR2CHAR
:
1699 case OPTYPE_ENUM2INT
:
1700 case OPTYPE_RNDWITHVAL
:
1701 case OPTYPE_REMOVE_BOM
:
1702 case OPTYPE_GET_STRINGENCODING
:
1703 case OPTYPE_DECODE_BASE64
:
1704 u
.expr
.v1
->set_my_scope(p_scope
);
1706 case OPTYPE_ADD
: // v1 v2
1707 case OPTYPE_SUBTRACT
:
1708 case OPTYPE_MULTIPLY
:
1729 case OPTYPE_INT2BIT
:
1730 case OPTYPE_INT2HEX
:
1731 case OPTYPE_INT2OCT
:
1732 u
.expr
.v1
->set_my_scope(p_scope
);
1733 u
.expr
.v2
->set_my_scope(p_scope
);
1735 case OPTYPE_UNICHAR2OCT
:
1736 case OPTYPE_OCT2UNICHAR
:
1737 case OPTYPE_ENCODE_BASE64
:
1738 u
.expr
.v1
->set_my_scope(p_scope
);
1739 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1742 u
.expr
.r1
->set_my_scope(p_scope
);
1743 u
.expr
.r2
->set_my_scope(p_scope
);
1746 u
.expr
.ti1
->set_my_scope(p_scope
);
1747 u
.expr
.v2
->set_my_scope(p_scope
);
1748 u
.expr
.v3
->set_my_scope(p_scope
);
1751 u
.expr
.ti1
->set_my_scope(p_scope
);
1752 u
.expr
.t2
->set_my_scope(p_scope
);
1753 u
.expr
.v3
->set_my_scope(p_scope
);
1755 case OPTYPE_DECOMP
: // v1 v2 v3
1756 u
.expr
.v1
->set_my_scope(p_scope
);
1757 u
.expr
.v2
->set_my_scope(p_scope
);
1758 u
.expr
.v3
->set_my_scope(p_scope
);
1760 case OPTYPE_REPLACE
:
1761 u
.expr
.ti1
->set_my_scope(p_scope
);
1762 u
.expr
.v2
->set_my_scope(p_scope
);
1763 u
.expr
.v3
->set_my_scope(p_scope
);
1764 u
.expr
.ti4
->set_my_scope(p_scope
);
1766 case OPTYPE_LENGTHOF
: // ti1
1767 case OPTYPE_SIZEOF
: // ti1
1768 case OPTYPE_VALUEOF
: // ti1
1769 case OPTYPE_ISVALUE
:
1770 case OPTYPE_ISBOUND
:
1772 case OPTYPE_ISPRESENT
:
1773 case OPTYPE_TTCN2STRING
:
1774 u
.expr
.ti1
->set_my_scope(p_scope
);
1776 case OPTYPE_ENCVALUE_UNICHAR
: //ti1 [v2]
1777 u
.expr
.ti1
->set_my_scope(p_scope
);
1778 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1780 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1781 u
.expr
.r1
->set_my_scope(p_scope
);
1782 u
.expr
.r2
->set_my_scope(p_scope
);
1783 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1785 case OPTYPE_UNDEF_RUNNING
: // r1
1786 case OPTYPE_TMR_READ
:
1787 case OPTYPE_TMR_RUNNING
:
1788 case OPTYPE_ACTIVATE
:
1789 u
.expr
.r1
->set_my_scope(p_scope
);
1791 case OPTYPE_EXECUTE
: // r1 [v2]
1792 u
.expr
.r1
->set_my_scope(p_scope
);
1793 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1795 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1796 u
.expr
.r1
->set_my_scope(p_scope
);
1797 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1798 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1800 case OPTYPE_MATCH
: // v1 t2
1801 u
.expr
.v1
->set_my_scope(p_scope
);
1802 u
.expr
.t2
->set_my_scope(p_scope
);
1804 case OPTYPE_ISCHOSEN
: // r1 i2
1805 u
.expr
.r1
->set_my_scope(p_scope
);
1807 case OPTYPE_ISCHOSEN_V
: // v1 i2
1808 u
.expr
.v1
->set_my_scope(p_scope
);
1810 case OPTYPE_ISCHOSEN_T
: // t1 i2
1811 u
.expr
.t1
->set_my_scope(p_scope
);
1813 case OPTYPE_ACTIVATE_REFD
:
1814 u
.expr
.v1
->set_my_scope(p_scope
);
1815 if(u
.expr
.state
!=EXPR_CHECKED
) {
1816 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1818 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1820 case OPTYPE_EXECUTE_REFD
:
1821 u
.expr
.v1
->set_my_scope(p_scope
);
1822 if(u
.expr
.state
!=EXPR_CHECKED
) {
1823 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1825 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1828 u
.expr
.v3
->set_my_scope(p_scope
);
1830 case OPTYPE_LOG2STR
:
1831 u
.expr
.logargs
->set_my_scope(p_scope
);
1834 FATAL_ERROR("Value::set_my_scope_expr()");
1838 void Value::set_genname_recursive(const string
& p_genname
)
1840 size_t genname_len
= p_genname
.size();
1841 if (genname_len
>= 4 &&
1842 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1843 // if the genname ends with ()() (i.e. the value stands for an optional
1844 // field) then drop the last () from the own genname, but leave it for
1845 // the embedded values
1846 set_genname(p_genname
.substr(0, genname_len
- 2));
1847 } else set_genname(p_genname
);
1850 string
embedded_genname(p_genname
);
1851 embedded_genname
+= '.';
1852 // If this is a choice value for an anytype, prepend the AT_ prefix
1853 // to the name of the alternative. The genname is used later in
1854 // Common::Value::generate_code_init_se()
1855 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1856 embedded_genname
+= "AT_";
1857 embedded_genname
+= u
.choice
.alt_name
->get_name();
1858 embedded_genname
+= "()";
1859 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1863 if (!is_indexed()) {
1864 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1865 for (size_t i
= 0; i
< nof_vs
; i
++) {
1866 string
embedded_genname(p_genname
);
1867 embedded_genname
+= '[';
1868 embedded_genname
+= Int2string(i
);
1869 embedded_genname
+= ']';
1870 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1873 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1874 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1875 string
embedded_genname(p_genname
);
1876 embedded_genname
+= '[';
1877 embedded_genname
+= Int2string(i
);
1878 embedded_genname
+= ']';
1879 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1880 ->set_genname_recursive(embedded_genname
);
1885 if (!my_governor
) return; // error recovery
1886 Type
*type
= my_governor
->get_type_refd_last();
1887 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1888 Int offset
= type
->get_dimension()->get_offset();
1889 if (!is_indexed()) {
1890 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1891 for (size_t i
= 0; i
< nof_vs
; i
++) {
1892 string
embedded_genname(p_genname
);
1893 embedded_genname
+= '[';
1894 embedded_genname
+= Int2string(offset
+ i
);
1895 embedded_genname
+= ']';
1896 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1899 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1900 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1901 string
embedded_genname(p_genname
);
1902 embedded_genname
+= '[';
1903 embedded_genname
+= Int2string(offset
+ i
);
1904 embedded_genname
+= ']';
1905 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1906 ->set_genname_recursive(embedded_genname
);
1912 if (!my_governor
) return; // error recovery
1913 Type
*t
= my_governor
->get_type_refd_last();
1914 if (!t
->is_secho()) return; // error recovery
1915 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1916 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1917 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1918 const Identifier
& id
= nv
->get_name();
1919 if (!t
->has_comp_withName(id
)) return; // error recovery
1920 string
embedded_genname(p_genname
);
1921 embedded_genname
+= '.';
1922 embedded_genname
+= id
.get_name();
1923 embedded_genname
+= "()";
1924 if (t
->get_comp_byName(id
)->get_is_optional())
1925 embedded_genname
+= "()";
1926 nv
->get_value()->set_genname_recursive(embedded_genname
);
1934 void Value::set_genname_prefix(const char *p_genname_prefix
)
1936 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1939 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1944 if (!is_indexed()) {
1945 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1946 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1948 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1949 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1950 ->set_genname_prefix(p_genname_prefix
);
1955 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1956 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1957 ->set_genname_prefix(p_genname_prefix
);
1964 void Value::set_code_section(code_section_t p_code_section
)
1966 GovernedSimple::set_code_section(p_code_section
);
1969 switch (u
.expr
.v_optype
) {
1970 case OPTYPE_RND
: // -
1971 case OPTYPE_COMP_NULL
:
1972 case OPTYPE_COMP_MTC
:
1973 case OPTYPE_COMP_SYSTEM
:
1974 case OPTYPE_COMP_SELF
:
1975 case OPTYPE_COMP_RUNNING_ANY
:
1976 case OPTYPE_COMP_RUNNING_ALL
:
1977 case OPTYPE_COMP_ALIVE_ANY
:
1978 case OPTYPE_COMP_ALIVE_ALL
:
1979 case OPTYPE_TMR_RUNNING_ANY
:
1980 case OPTYPE_GETVERDICT
:
1981 case OPTYPE_TESTCASENAME
:
1982 case OPTYPE_PROF_RUNNING
:
1984 case OPTYPE_UNARYPLUS
: // v1
1985 case OPTYPE_UNARYMINUS
:
1988 case OPTYPE_BIT2HEX
:
1989 case OPTYPE_BIT2INT
:
1990 case OPTYPE_BIT2OCT
:
1991 case OPTYPE_BIT2STR
:
1992 case OPTYPE_CHAR2INT
:
1993 case OPTYPE_CHAR2OCT
:
1994 case OPTYPE_COMP_RUNNING
:
1995 case OPTYPE_COMP_ALIVE
:
1996 case OPTYPE_FLOAT2INT
:
1997 case OPTYPE_FLOAT2STR
:
1998 case OPTYPE_HEX2BIT
:
1999 case OPTYPE_HEX2INT
:
2000 case OPTYPE_HEX2OCT
:
2001 case OPTYPE_HEX2STR
:
2002 case OPTYPE_INT2CHAR
:
2003 case OPTYPE_INT2FLOAT
:
2004 case OPTYPE_INT2STR
:
2005 case OPTYPE_INT2UNICHAR
:
2006 case OPTYPE_OCT2BIT
:
2007 case OPTYPE_OCT2CHAR
:
2008 case OPTYPE_OCT2HEX
:
2009 case OPTYPE_OCT2INT
:
2010 case OPTYPE_OCT2STR
:
2011 case OPTYPE_STR2BIT
:
2012 case OPTYPE_STR2FLOAT
:
2013 case OPTYPE_STR2HEX
:
2014 case OPTYPE_STR2INT
:
2015 case OPTYPE_STR2OCT
:
2016 case OPTYPE_UNICHAR2INT
:
2017 case OPTYPE_UNICHAR2CHAR
:
2018 case OPTYPE_ENUM2INT
:
2019 case OPTYPE_RNDWITHVAL
:
2020 case OPTYPE_GET_STRINGENCODING
:
2021 case OPTYPE_DECODE_BASE64
:
2022 case OPTYPE_REMOVE_BOM
:
2023 u
.expr
.v1
->set_code_section(p_code_section
);
2025 case OPTYPE_ADD
: // v1 v2
2026 case OPTYPE_SUBTRACT
:
2027 case OPTYPE_MULTIPLY
:
2048 case OPTYPE_INT2BIT
:
2049 case OPTYPE_INT2HEX
:
2050 case OPTYPE_INT2OCT
:
2051 u
.expr
.v1
->set_code_section(p_code_section
);
2052 u
.expr
.v2
->set_code_section(p_code_section
);
2054 case OPTYPE_UNICHAR2OCT
:
2055 case OPTYPE_OCT2UNICHAR
:
2056 case OPTYPE_ENCODE_BASE64
:
2057 u
.expr
.v1
->set_code_section(p_code_section
);
2058 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2061 u
.expr
.r1
->set_code_section(p_code_section
);
2062 u
.expr
.r2
->set_code_section(p_code_section
);
2065 u
.expr
.ti1
->set_code_section(p_code_section
);
2066 u
.expr
.v2
->set_code_section(p_code_section
);
2067 u
.expr
.v3
->set_code_section(p_code_section
);
2070 u
.expr
.ti1
->set_code_section(p_code_section
);
2071 u
.expr
.t2
->set_code_section(p_code_section
);
2072 u
.expr
.v3
->set_code_section(p_code_section
);
2074 case OPTYPE_DECOMP
: // v1 v2 v3
2075 u
.expr
.v1
->set_code_section(p_code_section
);
2076 u
.expr
.v2
->set_code_section(p_code_section
);
2077 u
.expr
.v3
->set_code_section(p_code_section
);
2079 case OPTYPE_REPLACE
:
2080 u
.expr
.ti1
->set_code_section(p_code_section
);
2081 u
.expr
.v2
->set_code_section(p_code_section
);
2082 u
.expr
.v3
->set_code_section(p_code_section
);
2083 u
.expr
.ti4
->set_code_section(p_code_section
);
2085 case OPTYPE_LENGTHOF
: // ti1
2086 case OPTYPE_SIZEOF
: // ti1
2087 case OPTYPE_VALUEOF
: // ti1
2088 case OPTYPE_ISVALUE
:
2089 case OPTYPE_ISBOUND
:
2091 case OPTYPE_ISPRESENT
:
2092 case OPTYPE_TTCN2STRING
:
2093 u
.expr
.ti1
->set_code_section(p_code_section
);
2095 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
2096 u
.expr
.ti1
->set_code_section(p_code_section
);
2097 if (u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2099 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
2100 u
.expr
.r1
->set_code_section(p_code_section
);
2101 u
.expr
.r2
->set_code_section(p_code_section
);
2102 if (u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2104 case OPTYPE_UNDEF_RUNNING
: // r1
2105 case OPTYPE_TMR_READ
:
2106 case OPTYPE_TMR_RUNNING
:
2107 case OPTYPE_ACTIVATE
:
2108 u
.expr
.r1
->set_code_section(p_code_section
);
2110 case OPTYPE_EXECUTE
: // r1 [v2]
2111 u
.expr
.r1
->set_code_section(p_code_section
);
2112 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2114 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2115 u
.expr
.r1
->set_code_section(p_code_section
);
2116 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2117 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2119 case OPTYPE_MATCH
: // v1 t2
2120 u
.expr
.v1
->set_code_section(p_code_section
);
2121 u
.expr
.t2
->set_code_section(p_code_section
);
2123 case OPTYPE_ISCHOSEN
: // r1 i2
2124 u
.expr
.r1
->set_code_section(p_code_section
);
2126 case OPTYPE_ISCHOSEN_V
: // v1 i2
2127 u
.expr
.v1
->set_code_section(p_code_section
);
2129 case OPTYPE_ISCHOSEN_T
: // t1 i2
2130 u
.expr
.t1
->set_code_section(p_code_section
);
2132 case OPTYPE_ACTIVATE_REFD
:
2133 u
.expr
.v1
->set_code_section(p_code_section
);
2134 if(u
.expr
.state
!=EXPR_CHECKED
)
2135 u
.expr
.t_list2
->set_code_section(p_code_section
);
2137 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2138 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2139 u
.expr
.state
= EXPR_CHECKED
;
2142 case OPTYPE_EXECUTE_REFD
:
2143 u
.expr
.v1
->set_code_section(p_code_section
);
2144 if(u
.expr
.state
!=EXPR_CHECKED
)
2145 u
.expr
.t_list2
->set_code_section(p_code_section
);
2147 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2148 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2149 u
.expr
.state
= EXPR_CHECKED
;
2152 u
.expr
.v3
->set_code_section(p_code_section
);
2154 case OPTYPE_LOG2STR
:
2155 u
.expr
.logargs
->set_code_section(p_code_section
);
2158 FATAL_ERROR("Value::set_code_section()");
2162 u
.choice
.alt_value
->set_code_section(p_code_section
);
2167 if (!is_indexed()) {
2168 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2169 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2171 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2172 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2177 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2178 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2179 ->set_code_section(p_code_section
);
2182 u
.ref
.ref
->set_code_section(p_code_section
);
2185 u
.refered
->set_code_section(p_code_section
);
2188 u
.invoke
.v
->set_code_section(p_code_section
);
2189 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2190 if(u
.invoke
.ap_list
)
2191 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2192 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2199 void Value::change_sign()
2203 *u
.val_Int
=-*u
.val_Int
;
2211 FATAL_ERROR("Value::change_sign()");
2215 void Value::add_oid_comp(OID_comp
* p_comp
)
2218 FATAL_ERROR("NULL parameter");
2219 u
.oid_comps
->add(p_comp
);
2220 p_comp
->set_fullname(get_fullname()+"."
2221 +Int2string(u
.oid_comps
->size()));
2222 p_comp
->set_my_scope(my_scope
);
2225 void Value::set_valuetype(valuetype_t p_valuetype
)
2227 if (valuetype
== V_ERROR
) return;
2228 else if (p_valuetype
== V_ERROR
) {
2229 if(valuetype
==V_EXPR
) {
2230 switch(u
.expr
.state
) {
2232 u
.expr
.state
=EXPR_CHECKING_ERR
;
2234 case EXPR_CHECKING_ERR
:
2241 valuetype
= V_ERROR
;
2245 case V_UNDEF_LOWERID
:
2246 switch(p_valuetype
) {
2251 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2252 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2253 u
.ref
.ref
->set_my_scope(get_my_scope());
2254 u
.ref
.ref
->set_fullname(get_fullname());
2255 u
.ref
.ref
->set_location(*this);
2256 u
.ref
.refd_last
= 0;
2259 FATAL_ERROR("Value::set_valuetype()");
2262 case V_UNDEF_BLOCK
: {
2263 Block
*t_block
=u
.block
;
2265 switch(p_valuetype
) {
2267 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2268 v
=dynamic_cast<Value
*>(node
);
2271 u
.ids
=new map
<string
, Identifier
>();
2274 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2278 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2279 v
=dynamic_cast<Value
*>(node
);
2282 u
.val_vs
=new Values();
2285 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2287 u
.val_vs
->set_my_scope(get_my_scope());
2288 u
.val_vs
->set_fullname(get_fullname());
2291 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2292 v
=dynamic_cast<Value
*>(node
);
2295 u
.val_vs
=new Values();
2298 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2300 u
.val_vs
->set_my_scope(get_my_scope());
2301 u
.val_vs
->set_fullname(get_fullname());
2304 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2305 v
=dynamic_cast<Value
*>(node
);
2308 u
.val_nvs
=new NamedValues();
2311 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2313 u
.val_nvs
->set_my_scope(get_my_scope());
2314 u
.val_nvs
->set_fullname(get_fullname());
2317 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2318 v
=dynamic_cast<Value
*>(node
);
2321 u
.val_nvs
=new NamedValues();
2324 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2326 u
.val_nvs
->set_my_scope(get_my_scope());
2327 u
.val_nvs
->set_fullname(get_fullname());
2330 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2331 v
=dynamic_cast<Value
*>(node
);
2334 u
.oid_comps
=new vector
<OID_comp
>();
2337 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2339 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2340 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2343 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2344 v
=dynamic_cast<Value
*>(node
);
2347 u
.oid_comps
=new vector
<OID_comp
>();
2350 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2352 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2353 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2356 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2357 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2360 u
.char_syms
=new CharSyms();
2362 u
.char_syms
->set_my_scope(get_my_scope());
2363 u
.char_syms
->set_fullname(get_fullname());
2366 FATAL_ERROR("Value::set_valuetype()");
2372 if (p_valuetype
== V_USTR
) {
2373 Value
*v_last
= get_value_refd_last();
2374 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2375 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2378 u
.ustr
.convert_str
= true; // will be converted back to string
2379 } else FATAL_ERROR("Value::set_valuetype()");
2382 switch(p_valuetype
) {
2384 const string
& str
= u
.char_syms
->get_string();
2386 set_val_str(new string(str
));
2389 const ustring
& ustr
= u
.char_syms
->get_ustring();
2391 set_val_ustr(new ustring(ustr
));
2392 u
.ustr
.convert_str
= false;
2394 case V_ISO2022STR
: {
2395 const string
& str
= u
.char_syms
->get_iso2022string();
2397 set_val_str(new string(str
));
2400 FATAL_ERROR("Value::set_valuetype()");
2405 if (p_valuetype
== V_REAL
)
2406 val_Real
= u
.val_Int
->to_real();
2407 else FATAL_ERROR("Value::set_valuetype()");
2409 u
.val_Real
= val_Real
;
2412 clean_up_string_elements(u
.str
.str_elements
);
2413 string
*old_str
= u
.str
.val_str
;
2414 switch(p_valuetype
) {
2416 set_val_str(hex2bit(*old_str
));
2419 set_val_str(asn_hex2oct(*old_str
));
2422 FATAL_ERROR("Value::set_valuetype()");
2427 clean_up_string_elements(u
.str
.str_elements
);
2428 if (p_valuetype
== V_OSTR
) {
2429 string
*old_str
= u
.str
.val_str
;
2430 set_val_str(asn_bit2oct(*old_str
));
2432 } else FATAL_ERROR("Value::set_valuetype()");
2435 clean_up_string_elements(u
.str
.str_elements
);
2436 switch(p_valuetype
) {
2438 string
*old_str
= u
.str
.val_str
;
2439 set_val_ustr(new ustring(*old_str
));
2440 u
.ustr
.convert_str
= true; // will be converted back to string
2447 FATAL_ERROR("Value::set_valuetype()");
2448 } // switch p_valuetype
2451 clean_up_string_elements(u
.ustr
.ustr_elements
);
2452 switch(p_valuetype
) {
2454 ustring
*old_str
= u
.ustr
.val_ustr
;
2455 size_t nof_chars
= old_str
->size();
2456 bool warning_flag
= false;
2457 for (size_t i
= 0; i
< nof_chars
; i
++) {
2458 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2459 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2460 error("This string value cannot contain multiple-byte characters, "
2461 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2462 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2464 p_valuetype
= V_ERROR
;
2466 } else if (uchar
.cell
> 127 && !warning_flag
) {
2467 warning("This string value may not contain characters with code "
2468 "higher than 127, but it has character with code %u (0x%02X) "
2469 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2470 warning_flag
= true;
2473 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2477 error("ISO-10646 string value cannot be converted to "
2479 delete u
.ustr
.val_ustr
;
2480 p_valuetype
= V_ERROR
;
2483 FATAL_ERROR("Value::set_valuetype()");
2484 } // switch p_valuetype
2487 switch (p_valuetype
) {
2489 NamedValues
*nvs
= u
.val_nvs
;
2490 if (nvs
->get_nof_nvs() < 1) {
2491 error("Union value must have one active field");
2493 valuetype
= V_ERROR
;
2495 } else if (nvs
->get_nof_nvs() > 1) {
2496 error("Only one field was expected in union value instead of %lu",
2497 (unsigned long) nvs
->get_nof_nvs());
2499 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2500 u
.choice
.alt_name
= nv
->get_name().clone();
2501 u
.choice
.alt_value
= nv
->steal_value();
2508 NamedValues
*nvs
= u
.val_nvs
;
2512 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2513 if (nvs
->has_nv_withName(id_mant
)) {
2514 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2515 ->get_value_refd_last();
2516 if (v_tmp
->get_valuetype() == V_INT
) {
2517 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2518 if (*i_mant_int
> INT_MAX
) {
2519 error("Mantissa `%s' should be less than `%d'",
2520 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2523 i_mant
= i_mant_int
->get_val();
2531 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2532 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2533 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2534 Value
*v_tmp
= v
->get_value_refd_last();
2535 if (v_tmp
->get_valuetype() == V_INT
) {
2536 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2537 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2538 v
->error("Base of the REAL must be 2 or 10");
2541 i_base
= i_base_int
->get_val();
2549 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2550 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2551 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2552 ->get_value_refd_last();
2553 if (v_tmp
->get_valuetype() == V_INT
) {
2554 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2555 if (*i_exp_int
> INT_MAX
) {
2556 error("Exponent `%s' should be less than `%d'",
2557 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2560 i_exp
= i_exp_int
->get_val();
2569 valuetype
= V_ERROR
;
2572 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2573 static_cast<double>(i_exp
));
2579 FATAL_ERROR("Value::set_valuetype()");
2583 switch (p_valuetype
) {
2585 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2586 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2587 Type
*t
= my_governor
->get_type_refd_last();
2588 switch (t
->get_typetype()) {
2593 FATAL_ERROR("Value::set_valuetype()");
2595 Values
*vals
= u
.val_vs
;
2596 size_t nof_vals
= vals
->get_nof_vs();
2597 size_t nof_comps
= t
->get_nof_comps();
2598 if (nof_vals
> nof_comps
) {
2599 error("Too many elements in value list notation for type `%s': "
2600 "%lu was expected instead of %lu",
2601 t
->get_typename().c_str(),
2602 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2606 if (nof_vals
<= nof_comps
) {
2607 upper_limit
= nof_vals
;
2610 upper_limit
= nof_comps
;
2613 u
.val_nvs
= new NamedValues
;
2614 for (size_t i
= 0; i
< upper_limit
; i
++) {
2615 Value
*v
= vals
->steal_v_byIndex(i
);
2616 if (v
->valuetype
!= V_NOTUSED
) {
2620 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2621 nv
->set_location(*v
);
2622 u
.val_nvs
->add_nv(nv
);
2624 u
.val_nvs
->set_my_scope(get_my_scope());
2625 u
.val_nvs
->set_fullname(get_fullname());
2627 if (allnotused
&& nof_vals
> 0)
2628 warning("All elements of value list notation for type `%s' are not "
2629 "used symbols (`-')", t
->get_typename().c_str());
2632 // { } -> empty set value
2633 if (u
.val_vs
->get_nof_vs() != 0)
2634 FATAL_ERROR("Value::set_valuetype()");
2636 u
.val_nvs
= new NamedValues
;
2640 // SEQOF -> SETOF or ARRAY: trivial
2643 FATAL_ERROR("Value::set_valuetype()");
2648 if (p_valuetype
== V_NOTUSED
) {
2652 FATAL_ERROR("Value::set_valuetype()");
2656 switch (p_valuetype
) {
2657 case V_DEFAULT_NULL
:
2662 FATAL_ERROR("Value::set_valuetype()");
2666 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2667 FATAL_ERROR("Value::set_valuetype()");
2671 FATAL_ERROR("Value::set_valuetype()");
2673 valuetype
=p_valuetype
;
2676 void Value::set_valuetype_COMP_NULL()
2678 if(valuetype
== V_ERROR
) return;
2679 if(valuetype
==V_TTCN3_NULL
) {
2681 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2682 // Nothing to check.
2683 u
.expr
.state
=EXPR_CHECKED
;
2685 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2688 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2690 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2692 u
.val_Int
= new int_val_t(p_val_int
);
2694 } else FATAL_ERROR("Value::set_valuetype()");
2697 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2699 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2703 } else FATAL_ERROR("Value::set_valuetype()");
2706 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2708 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2712 } else FATAL_ERROR("Value::set_valuetype()");
2715 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2717 switch (p_valuetype
) {
2721 if (valuetype
== V_REFER
&& p_ass
) break;
2724 FATAL_ERROR("Value::set_valuetype()");
2728 valuetype
= p_valuetype
;
2731 bool Value::is_undef_lowerid()
2733 switch (valuetype
) {
2734 case V_UNDEF_LOWERID
:
2737 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2738 !u
.expr
.ti1
->get_DerivedRef()) {
2739 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2747 const Identifier
& Value::get_undef_lowerid()
2749 switch (valuetype
) {
2750 case V_UNDEF_LOWERID
:
2753 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2754 FATAL_ERROR("Value::get_undef_lowerid()");
2755 return u
.expr
.ti1
->get_Template()->get_specific_value()
2756 ->get_undef_lowerid();
2758 FATAL_ERROR("Value::get_undef_lowerid()");
2760 const Identifier
*dummy
= 0;
2764 void Value::set_lowerid_to_ref()
2766 switch (valuetype
) {
2767 case V_UNDEF_LOWERID
:
2768 set_valuetype(V_REFD
);
2771 // if the governor of the expression is not known (in log(), etc...)
2772 // then the governor is taken from the reference (using
2773 // v1/ti1->get_expr_governor()), but that runs before the
2774 // params were checked, this smells like a workaround :)
2775 switch (u
.expr
.v_optype
) {
2778 u
.expr
.v1
->set_lowerid_to_ref();
2781 u
.expr
.v1
->set_lowerid_to_ref();
2782 u
.expr
.v2
->set_lowerid_to_ref();
2784 case OPTYPE_VALUEOF
:
2785 case OPTYPE_ISVALUE
:
2786 case OPTYPE_ISBOUND
:
2787 case OPTYPE_ISPRESENT
:
2790 case OPTYPE_REPLACE
:
2791 case OPTYPE_TTCN2STRING
:
2792 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2793 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2794 "In the operand of operation `%s'",
2796 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2798 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2799 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2800 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2801 "In the operand of operation `%s'",
2803 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2806 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2807 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2808 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2809 "In the operand of operation `%s'",
2811 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2824 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2826 switch (valuetype
) {
2834 case V_UNDEF_LOWERID
:
2841 return Type::T_UNDEF
;
2845 FATAL_ERROR("Value::get_expr_returntype()");
2847 return Type::T_ERROR
;
2850 Type
*t
= get_expr_governor(exp_val
);
2851 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2852 else return Type::T_ERROR
; }
2854 return Type::T_FUNCTION
;
2856 return Type::T_ALTSTEP
;
2858 return Type::T_TESTCASE
;
2860 switch(u
.expr
.v_optype
) {
2861 case OPTYPE_COMP_NULL
:
2862 case OPTYPE_COMP_MTC
:
2863 case OPTYPE_COMP_SYSTEM
:
2864 case OPTYPE_COMP_SELF
:
2865 case OPTYPE_COMP_CREATE
:
2866 return Type::T_COMPONENT
;
2867 case OPTYPE_UNDEF_RUNNING
:
2868 case OPTYPE_COMP_RUNNING
:
2869 case OPTYPE_COMP_RUNNING_ANY
:
2870 case OPTYPE_COMP_RUNNING_ALL
:
2871 case OPTYPE_COMP_ALIVE
:
2872 case OPTYPE_COMP_ALIVE_ANY
:
2873 case OPTYPE_COMP_ALIVE_ALL
:
2874 case OPTYPE_TMR_RUNNING
:
2875 case OPTYPE_TMR_RUNNING_ANY
:
2887 case OPTYPE_ISPRESENT
:
2888 case OPTYPE_ISCHOSEN
:
2889 case OPTYPE_ISCHOSEN_V
:
2890 case OPTYPE_ISCHOSEN_T
:
2891 case OPTYPE_ISVALUE
:
2892 case OPTYPE_ISBOUND
:
2893 case OPTYPE_PROF_RUNNING
:
2894 return Type::T_BOOL
;
2895 case OPTYPE_GETVERDICT
:
2896 return Type::T_VERDICT
;
2897 case OPTYPE_VALUEOF
: {
2898 Error_Context
cntxt(this, "In the operand of operation `%s'",
2900 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2901 case OPTYPE_TMR_READ
:
2902 case OPTYPE_INT2FLOAT
:
2903 case OPTYPE_STR2FLOAT
:
2905 case OPTYPE_RNDWITHVAL
:
2906 return Type::T_REAL
;
2907 case OPTYPE_ACTIVATE
:
2908 return Type::T_DEFAULT
;
2909 case OPTYPE_ACTIVATE_REFD
:
2910 return Type::T_DEFAULT
;
2911 case OPTYPE_EXECUTE
:
2912 case OPTYPE_EXECUTE_REFD
:
2913 return Type::T_VERDICT
;
2914 case OPTYPE_UNARYPLUS
: // v1
2915 case OPTYPE_UNARYMINUS
: {
2916 Type::typetype_t tmp_tt
;
2918 Error_Context
cntxt(this, "In the operand of operation `%s'",
2920 u
.expr
.v1
->set_lowerid_to_ref();
2921 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2928 get_value_refd_last(); // to report the error
2929 return Type::T_ERROR
;
2932 case OPTYPE_ADD
: // v1 v2
2933 case OPTYPE_SUBTRACT
:
2934 case OPTYPE_MULTIPLY
:
2935 case OPTYPE_DIVIDE
: {
2936 Type::typetype_t tmp_tt
;
2938 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2940 u
.expr
.v1
->set_lowerid_to_ref();
2941 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2948 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2949 Type::typetype_t tmp_tt2
;
2951 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2953 u
.expr
.v2
->set_lowerid_to_ref();
2954 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2956 Type::typetype_t ret_val
=Type::T_ERROR
;
2957 bool maybeconcat
=false;
2962 if(tmp_tt2
==tmp_tt
) {
2969 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2971 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2972 ret_val
=Type::T_USTR
;
2973 else ret_val
=Type::T_CSTR
;
2980 error("Did you mean the concat operation (`&') instead of"
2981 " addition operator (`+')?");
2982 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2986 get_value_refd_last(); // to report the error
2987 return Type::T_ERROR
;
2990 case OPTYPE_NOT4B
: // v1
2991 case OPTYPE_AND4B
: // v1 v2
2996 Type::typetype_t tmp_tt
;
2998 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
2999 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
3001 u
.expr
.v1
->set_lowerid_to_ref();
3002 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3010 get_value_refd_last(); // to report the error
3011 return Type::T_ERROR
;
3014 case OPTYPE_ROTL
: // v1 v2
3016 Type::typetype_t tmp_tt
;
3018 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
3019 u
.expr
.v_optype
==OPTYPE_ROTL
3020 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
3022 u
.expr
.v1
->set_lowerid_to_ref();
3023 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3036 get_value_refd_last(); // to report the error
3037 return Type::T_ERROR
;
3041 case OPTYPE_REPLACE
: {
3042 Type::typetype_t tmp_tt
;
3044 Error_Context
cntxt(this, "In the operand of operation `%s'",
3046 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3047 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3059 get_value_refd_last(); // to report the error
3060 return Type::T_ERROR
;
3063 case OPTYPE_REGEXP
: {
3064 Type::typetype_t tmp_tt
;
3066 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3068 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3069 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3076 get_value_refd_last(); // to report the error
3077 return Type::T_ERROR
;
3080 case OPTYPE_CONCAT
: { // v1 v2
3081 Type::typetype_t tmp_tt
;
3083 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3085 u
.expr
.v1
->set_lowerid_to_ref();
3086 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3098 get_value_refd_last(); // to report the error
3099 return Type::T_ERROR
;
3104 case OPTYPE_CHAR2INT
:
3105 case OPTYPE_UNICHAR2INT
:
3106 case OPTYPE_BIT2INT
:
3107 case OPTYPE_HEX2INT
:
3108 case OPTYPE_OCT2INT
:
3109 case OPTYPE_STR2INT
:
3110 case OPTYPE_FLOAT2INT
:
3111 case OPTYPE_LENGTHOF
:
3114 case OPTYPE_ENUM2INT
:
3115 case OPTYPE_DECVALUE_UNICHAR
:
3117 case OPTYPE_BIT2STR
:
3118 case OPTYPE_FLOAT2STR
:
3119 case OPTYPE_HEX2STR
:
3120 case OPTYPE_INT2CHAR
:
3121 case OPTYPE_INT2STR
:
3122 case OPTYPE_OCT2CHAR
:
3123 case OPTYPE_OCT2STR
:
3124 case OPTYPE_UNICHAR2CHAR
:
3125 case OPTYPE_LOG2STR
:
3126 case OPTYPE_TESTCASENAME
:
3127 case OPTYPE_TTCN2STRING
:
3128 case OPTYPE_GET_STRINGENCODING
:
3129 case OPTYPE_ENCODE_BASE64
:
3130 return Type::T_CSTR
;
3131 case OPTYPE_INT2UNICHAR
:
3132 case OPTYPE_OCT2UNICHAR
:
3133 case OPTYPE_ENCVALUE_UNICHAR
:
3134 return Type::T_USTR
;
3135 case OPTYPE_INT2BIT
:
3136 case OPTYPE_HEX2BIT
:
3137 case OPTYPE_OCT2BIT
:
3138 case OPTYPE_STR2BIT
:
3140 return Type::T_BSTR
;
3141 case OPTYPE_INT2HEX
:
3142 case OPTYPE_BIT2HEX
:
3143 case OPTYPE_OCT2HEX
:
3144 case OPTYPE_STR2HEX
:
3145 return Type::T_HSTR
;
3146 case OPTYPE_INT2OCT
:
3147 case OPTYPE_CHAR2OCT
:
3148 case OPTYPE_HEX2OCT
:
3149 case OPTYPE_BIT2OCT
:
3150 case OPTYPE_STR2OCT
:
3151 case OPTYPE_UNICHAR2OCT
:
3152 case OPTYPE_REMOVE_BOM
:
3153 case OPTYPE_DECODE_BASE64
:
3154 return Type::T_OSTR
;
3158 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3160 return Type::T_ERROR
;
3164 case MACRO_MODULEID
:
3165 case MACRO_FILENAME
:
3166 case MACRO_BFILENAME
:
3167 case MACRO_FILEPATH
:
3168 case MACRO_LINENUMBER
:
3169 case MACRO_DEFINITIONID
:
3171 case MACRO_TESTCASEID
:
3172 return Type::T_CSTR
;
3173 case MACRO_LINENUMBER_C
:
3176 return Type::T_ERROR
;
3179 return Type::T_NULL
;
3181 return Type::T_BOOL
;
3185 return Type::T_REAL
;
3187 return Type::T_ENUM_T
;
3189 return Type::T_BSTR
;
3191 return Type::T_HSTR
;
3193 return Type::T_OSTR
;
3195 return Type::T_CSTR
;
3197 return Type::T_USTR
;
3199 return Type::T_GENERALSTRING
;
3203 return Type::T_ROID
;
3205 return Type::T_VERDICT
;
3206 case V_DEFAULT_NULL
:
3207 return Type::T_DEFAULT
;
3209 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3211 return Type::T_ERROR
;
3215 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3217 if(my_governor
) return my_governor
;
3218 switch (valuetype
) {
3220 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3222 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3223 u
.invoke
.v
->error("A value of type function expected");
3226 t
= t
->get_type_refd_last();
3227 switch(t
->get_typetype()) {
3228 case Type::T_FUNCTION
: {
3229 Type
*t_return_type
= t
->get_function_return_type();
3230 if (!t_return_type
) {
3231 error("Reference to a %s was expected instead of invocation "
3232 "of behavior type `%s' with no return type",
3233 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3234 t
->get_fullname().c_str());
3237 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3238 error("Reference to a value was expected, but functions of type "
3239 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3240 t_return_type
->get_typename().c_str());
3243 return t_return_type
; }
3244 case Type::T_ALTSTEP
:
3247 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3248 t
->get_typename().c_str());
3253 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3255 if (!ass
) goto error
;
3256 switch (ass
->get_asstype()) {
3257 case Assignment::A_CONST
:
3258 case Assignment::A_EXT_CONST
:
3259 case Assignment::A_MODULEPAR
:
3260 case Assignment::A_MODULEPAR_TEMP
:
3261 case Assignment::A_TEMPLATE
:
3262 case Assignment::A_VAR
:
3263 case Assignment::A_VAR_TEMPLATE
:
3264 case Assignment::A_FUNCTION_RVAL
:
3265 case Assignment::A_FUNCTION_RTEMP
:
3266 case Assignment::A_EXT_FUNCTION_RVAL
:
3267 case Assignment::A_EXT_FUNCTION_RTEMP
:
3268 case Assignment::A_PAR_VAL_IN
:
3269 case Assignment::A_PAR_VAL_OUT
:
3270 case Assignment::A_PAR_VAL_INOUT
:
3271 case Assignment::A_PAR_TEMPL_IN
:
3272 case Assignment::A_PAR_TEMPL_OUT
:
3273 case Assignment::A_PAR_TEMPL_INOUT
:
3274 tmp_type
=ass
->get_Type();
3276 case Assignment::A_FUNCTION
:
3277 case Assignment::A_EXT_FUNCTION
:
3278 error("Reference to a %s was expected instead of a call of %s, which "
3279 "does not have return type",
3280 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3281 ass
->get_description().c_str());
3284 error("Reference to a %s was expected instead of %s",
3285 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3286 ass
->get_description().c_str());
3289 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3290 if(!tmp_type
) goto error
;
3293 switch (u
.expr
.v_optype
) {
3294 case OPTYPE_VALUEOF
:
3297 case OPTYPE_REPLACE
:{
3298 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3299 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3300 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3305 return u
.expr
.v1
->get_expr_governor(exp_val
);
3307 return get_expr_governor_v1v2(exp_val
);
3308 case OPTYPE_COMP_MTC
:
3309 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3311 case OPTYPE_COMP_SYSTEM
:
3312 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3314 case OPTYPE_COMP_SELF
:
3316 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3317 if (t_ros
) return t_ros
->get_component_type();
3320 case OPTYPE_COMP_CREATE
:
3321 return chk_expr_operand_comptyperef_create();
3327 return Type::get_pooltype(get_expr_returntype(exp_val
));
3330 set_valuetype(V_ERROR
);
3334 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3336 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3337 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3339 if (v2_gov
) { // both have governors
3340 // return the type that is compatible with both (if there is no type mismatch)
3341 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3344 } else return v1_gov
;
3345 } else { // v1 has no governor
3346 if (v2_gov
) return v2_gov
;
3347 else return NULL
; // neither has governor
3351 Type
*Value::get_expr_governor_last()
3353 Value
*v_last
= get_value_refd_last();
3354 if (v_last
->valuetype
== V_ERROR
) return 0;
3355 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3357 return t
->get_type_refd_last();
3360 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3362 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3363 return u
.invoke
.v
->get_expr_governor(exp_val
);
3366 const char* Value::get_opname() const
3368 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3369 switch(u
.expr
.v_optype
) {
3370 case OPTYPE_RND
: // -
3372 case OPTYPE_COMP_NULL
:
3373 return "(component) null";
3374 case OPTYPE_COMP_MTC
:
3376 case OPTYPE_COMP_SYSTEM
:
3378 case OPTYPE_COMP_SELF
:
3380 case OPTYPE_COMP_RUNNING_ANY
:
3381 return "any component.running";
3382 case OPTYPE_COMP_RUNNING_ALL
:
3383 return "all component.running";
3384 case OPTYPE_COMP_ALIVE_ANY
:
3385 return "any component.alive";
3386 case OPTYPE_COMP_ALIVE_ALL
:
3387 return "all component.alive";
3388 case OPTYPE_TMR_RUNNING_ANY
:
3389 return "any timer.running";
3390 case OPTYPE_GETVERDICT
:
3391 return "getverdict()";
3392 case OPTYPE_TESTCASENAME
:
3393 return "testcasename()";
3394 case OPTYPE_UNARYPLUS
: // v1
3396 case OPTYPE_UNARYMINUS
:
3402 case OPTYPE_BIT2HEX
:
3404 case OPTYPE_BIT2INT
:
3406 case OPTYPE_BIT2OCT
:
3408 case OPTYPE_BIT2STR
:
3410 case OPTYPE_CHAR2INT
:
3411 return "char2int()";
3412 case OPTYPE_CHAR2OCT
:
3413 return "char2oct()";
3414 case OPTYPE_FLOAT2INT
:
3415 return "float2int()";
3416 case OPTYPE_FLOAT2STR
:
3417 return "float2str()";
3418 case OPTYPE_HEX2BIT
:
3420 case OPTYPE_HEX2INT
:
3422 case OPTYPE_HEX2OCT
:
3424 case OPTYPE_HEX2STR
:
3426 case OPTYPE_INT2CHAR
:
3427 return "int2char()";
3428 case OPTYPE_INT2FLOAT
:
3429 return "int2float()";
3430 case OPTYPE_INT2STR
:
3432 case OPTYPE_INT2UNICHAR
:
3433 return "int2unichar()";
3434 case OPTYPE_OCT2BIT
:
3436 case OPTYPE_OCT2CHAR
:
3437 return "oct2char()";
3438 case OPTYPE_OCT2HEX
:
3440 case OPTYPE_OCT2INT
:
3442 case OPTYPE_OCT2STR
:
3444 case OPTYPE_STR2BIT
:
3446 case OPTYPE_STR2FLOAT
:
3447 return "str2float()";
3448 case OPTYPE_STR2HEX
:
3450 case OPTYPE_STR2INT
:
3452 case OPTYPE_STR2OCT
:
3454 case OPTYPE_UNICHAR2INT
:
3455 return "unichar2int()";
3456 case OPTYPE_UNICHAR2CHAR
:
3457 return "unichar2char()";
3458 case OPTYPE_UNICHAR2OCT
:
3459 return "unichar2oct()";
3460 case OPTYPE_ENUM2INT
:
3461 return "enum2int()";
3462 case OPTYPE_LENGTHOF
:
3463 return "lengthof()";
3466 case OPTYPE_RNDWITHVAL
:
3467 return "rnd (seed)";
3469 return "encvalue()";
3471 return "decvalue()";
3472 case OPTYPE_GET_STRINGENCODING
:
3473 return "get_stringencoding()";
3474 case OPTYPE_REMOVE_BOM
:
3475 return "remove_bom()";
3476 case OPTYPE_ENCODE_BASE64
:
3477 return "encode_base64()";
3478 case OPTYPE_DECODE_BASE64
:
3479 return "decode_base64()";
3480 case OPTYPE_ADD
: // v1 v2
3482 case OPTYPE_SUBTRACT
:
3484 case OPTYPE_MULTIPLY
:
3526 case OPTYPE_INT2BIT
:
3528 case OPTYPE_INT2HEX
:
3530 case OPTYPE_INT2OCT
:
3532 case OPTYPE_OCT2UNICHAR
:
3533 return "oct2unichar()";
3534 case OPTYPE_ENCVALUE_UNICHAR
:
3535 return "encvalue_unichar()";
3536 case OPTYPE_DECVALUE_UNICHAR
:
3537 return "decvalue_unichar()";
3544 case OPTYPE_REPLACE
:
3546 case OPTYPE_VALUEOF
: // t1
3548 case OPTYPE_UNDEF_RUNNING
:
3549 return "<timer or component> running";
3550 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3552 case OPTYPE_COMP_RUNNING
: // v1
3553 return "component running";
3554 case OPTYPE_COMP_ALIVE
: // v1
3556 case OPTYPE_TMR_READ
:
3557 return "timer read";
3558 case OPTYPE_TMR_RUNNING
:
3559 return "timer running";
3560 case OPTYPE_ACTIVATE
:
3561 return "activate()";
3562 case OPTYPE_ACTIVATE_REFD
:
3563 return "activate()";
3564 case OPTYPE_EXECUTE
: // r1 [v2]
3565 case OPTYPE_EXECUTE_REFD
:
3567 case OPTYPE_MATCH
: // v1 t2
3569 case OPTYPE_ISPRESENT
:
3570 return "ispresent()";
3571 case OPTYPE_ISCHOSEN
:
3572 case OPTYPE_ISCHOSEN_V
:
3573 case OPTYPE_ISCHOSEN_T
:
3574 return "ischosen()";
3575 case OPTYPE_ISVALUE
:
3577 case OPTYPE_ISBOUND
:
3579 case OPTYPE_LOG2STR
:
3581 case OPTYPE_TTCN2STRING
:
3582 return "ttcn2string()";
3583 case OPTYPE_PROF_RUNNING
:
3584 return "@profiler.running";
3586 FATAL_ERROR("Value::get_opname()");
3590 void Value::chk_expr_ref_ischosen()
3592 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3593 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3594 Assignment
*ass
=tmpref
->get_refd_assignment();
3596 set_valuetype(V_ERROR
);
3599 // Now we know whether the argument of ischosen() is a value or template.
3600 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3601 // or template (OPTYPE_ISCHOSEN_T).
3602 switch (ass
->get_asstype()) {
3603 case Assignment::A_CONST
:
3604 case Assignment::A_EXT_CONST
:
3605 case Assignment::A_MODULEPAR
:
3606 case Assignment::A_VAR
:
3607 case Assignment::A_PAR_VAL_IN
:
3608 case Assignment::A_PAR_VAL_OUT
:
3609 case Assignment::A_PAR_VAL_INOUT
:
3610 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3611 u
.expr
.v1
->set_location(*tmpref
);
3612 u
.expr
.v1
->set_my_scope(get_my_scope());
3613 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3614 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3616 case Assignment::A_MODULEPAR_TEMP
:
3617 case Assignment::A_TEMPLATE
:
3618 case Assignment::A_VAR_TEMPLATE
:
3619 case Assignment::A_PAR_TEMPL_IN
:
3620 case Assignment::A_PAR_TEMPL_OUT
:
3621 case Assignment::A_PAR_TEMPL_INOUT
:
3622 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3623 u
.expr
.t1
->set_location(*tmpref
);
3624 u
.expr
.t1
->set_my_scope(get_my_scope());
3625 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3626 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3629 tmpref
->error("Reference to a value or template was expected instead of "
3630 "%s", ass
->get_description().c_str());
3631 set_valuetype(V_ERROR
);
3636 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3637 Type::expected_value_t exp_val
)
3639 v
->set_lowerid_to_ref(); // can only be reference to enum
3640 Type
*t
= v
->get_expr_governor(exp_val
);
3641 if (v
->valuetype
==V_ERROR
) return;
3643 v
->error("Please use reference to an enumerated value as the operand of "
3644 "operation `%s'", get_opname());
3645 set_valuetype(V_ERROR
);
3648 t
= t
->get_type_refd_last();
3649 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3650 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3651 set_valuetype(V_ERROR
);
3653 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3654 v
->error("The operand of operation `%s' cannot be omit", opname
);
3655 set_valuetype(V_ERROR
);
3659 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3662 const Location
*loc
)
3664 if(tt
==Type::T_BOOL
) return;
3665 if(tt
!=Type::T_ERROR
)
3666 loc
->error("%s operand of operation `%s' should be boolean value",
3668 set_valuetype(V_ERROR
);
3671 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3674 const Location
*loc
)
3676 if(tt
==Type::T_INT
) return;
3677 if(tt
!=Type::T_ERROR
)
3678 loc
->error("%s operand of operation `%s' should be integer value",
3680 set_valuetype(V_ERROR
);
3683 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3686 const Location
*loc
)
3688 if(tt
==Type::T_REAL
) return;
3689 else if(tt
==Type::T_INT
)
3690 loc
->error("%s operand of operation `%s' should be float value."
3691 " Perhaps you missed an int2float() conversion function"
3692 " or `.0' at the end of the number",
3694 else if(tt
!=Type::T_ERROR
)
3695 loc
->error("%s operand of operation `%s' should be float value",
3697 set_valuetype(V_ERROR
);
3700 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3703 const Location
*loc
)
3712 if(tt
!=Type::T_ERROR
)
3713 loc
->error("%s operand of operation `%s' should be integer"
3716 set_valuetype(V_ERROR
);
3719 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3722 const Location
*loc
)
3727 case Type::T_ENUM_T
:
3732 if(tt
!=Type::T_ERROR
)
3733 loc
->error("%s operand of operation `%s' should be integer, float"
3734 " or enumerated value", opnum
, opname
);
3735 set_valuetype(V_ERROR
);
3738 void Value::chk_expr_operandtype_list(Type
* t
,
3741 const Location
*loc
,
3744 if (valuetype
== V_ERROR
) return;
3745 if (t
->get_typetype() == Type::T_ERROR
) {
3746 set_valuetype(V_ERROR
);
3749 if (!t
->is_list_type(allow_array
)) {
3750 loc
->error("%s operand of operation `%s' should be a string, "
3751 "`record of'%s `set of'%s value", opnum
, opname
,
3752 allow_array
? "," : " or", allow_array
? " or array" : "");
3753 set_valuetype(V_ERROR
);
3756 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3757 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3760 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3761 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3762 if (info
.is_subtype_error()) {
3764 if (info
.needs_conversion()) set_needs_conversion();
3766 if (!info
.is_erroneous()) {
3767 error("%s operand of operation `%s' is of type `%s', but a value of "
3768 "type `%s' was expected here", opnum
, opname
,
3769 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3771 error("%s", info
.get_error_str_str().c_str());
3774 if (info
.needs_conversion())
3775 set_needs_conversion();
3779 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3782 const Location
*loc
)
3794 if(tt
!=Type::T_ERROR
)
3795 loc
->error("%s operand of operation `%s' should be string value",
3797 set_valuetype(V_ERROR
);
3800 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3803 const Location
*loc
)
3812 if(tt
!=Type::T_ERROR
)
3813 loc
->error("%s operand of operation `%s' should be (universal)"
3814 " charstring value",
3816 set_valuetype(V_ERROR
);
3819 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3822 const Location
*loc
)
3824 if(tt
==Type::T_CSTR
) return;
3825 if(tt
!=Type::T_ERROR
)
3826 loc
->error("%s operand of operation `%s' should be charstring value",
3828 set_valuetype(V_ERROR
);
3831 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3834 const Location
*loc
)
3844 if(tt
!=Type::T_ERROR
)
3845 loc
->error("%s operand of operation `%s' should be binary string value",
3847 set_valuetype(V_ERROR
);
3850 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3853 const Location
*loc
)
3855 if(tt
==Type::T_BSTR
) return;
3856 if(tt
!=Type::T_ERROR
)
3857 loc
->error("%s operand of operation `%s' should be bitstring value",
3859 set_valuetype(V_ERROR
);
3862 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3865 const Location
*loc
)
3867 if(tt
==Type::T_HSTR
) return;
3868 if(tt
!=Type::T_ERROR
)
3869 loc
->error("%s operand of operation `%s' should be hexstring value",
3871 set_valuetype(V_ERROR
);
3874 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3877 const Location
*loc
)
3879 if(tt
==Type::T_OSTR
) return;
3880 if(tt
!=Type::T_ERROR
)
3881 loc
->error("%s operand of operation `%s' should be octetstring value",
3883 set_valuetype(V_ERROR
);
3886 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3887 Type::typetype_t tt2
,
3890 if(valuetype
==V_ERROR
) return;
3891 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3892 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3893 set_valuetype(V_ERROR
);
3896 if(tt1
==tt2
) return;
3897 error("The operands of operation `%s' should be of same type", opname
);
3898 set_valuetype(V_ERROR
);
3901 /* For predefined functions. */
3902 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3903 Type::typetype_t tt2
,
3908 if(valuetype
==V_ERROR
) return;
3909 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3910 set_valuetype(V_ERROR
);
3913 if(tt1
==tt2
) return;
3914 error("The %s and %s operands of operation `%s' should be of same type",
3915 opnum1
, opnum2
, opname
);
3916 set_valuetype(V_ERROR
);
3919 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3920 Value
*v1
, Value
*v2
,
3925 if (valuetype
== V_ERROR
) return;
3926 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3927 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3928 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3930 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3931 set_valuetype(V_ERROR
);
3934 if (tt1
== Type::T_UNDEF
) {
3935 if (tt2
== Type::T_UNDEF
) {
3936 if (v1
->is_undef_lowerid()) {
3937 if (v2
->is_undef_lowerid()) {
3938 Scope
*scope
= get_my_scope();
3939 Module
*my_mod
= scope
->get_scope_mod();
3940 const Identifier
& id1
= v1
->get_undef_lowerid();
3941 if (scope
->has_ass_withId(id1
)
3942 || my_mod
->has_imported_ass_withId(id1
)) {
3943 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3944 * should examine this situation better, but now I suppose
3945 * the first is ref, not enum. */
3946 v1
->set_lowerid_to_ref();
3949 const Identifier
& id2
= v2
->get_undef_lowerid();
3950 if (scope
->has_ass_withId(id2
)
3951 || my_mod
->has_imported_ass_withId(id2
)) {
3952 v2
->set_lowerid_to_ref();
3956 /* This is perhaps enum-enum, but it has no real
3957 * significance, so this should be an error. */
3959 v1
->set_lowerid_to_ref();
3962 } else if (v2
->is_undef_lowerid()) {
3963 v2
->set_lowerid_to_ref();
3966 error("Cannot determine the type of the operands in operation `%s'",
3968 set_valuetype(V_ERROR
);
3970 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3971 v1
->set_lowerid_to_ref();
3974 /* v1 is something undefined, but not lowerid; v2 has
3975 * returntype (perhaps also governor) */
3977 } else if (tt2
== Type::T_UNDEF
) {
3978 /* but tt1 is not undef */
3979 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3980 v2
->set_lowerid_to_ref();
3983 /* v2 is something undefined, but not lowerid; v1 has
3984 * returntype (perhaps also governor) */
3988 /* Now undef_lower_id's are converted to references, or the other
3989 * value has governor; let's see the governors, if they exist. */
3990 Type
*t1
= v1
->get_expr_governor(exp_val
);
3991 Type
*t2
= v2
->get_expr_governor(exp_val
);
3994 // Both value has governor. Are they compatible? According to 7.1.2
3995 // and C.34 it's required to have the same root types for
3996 // OPTYPE_{CONCAT,REPLACE}.
3997 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
3998 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3999 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
4000 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4001 TypeChain l_chain1
, l_chain2
;
4002 TypeChain r_chain1
, r_chain2
;
4003 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
4004 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
4005 if (!compat_t1
&& !compat_t2
) {
4006 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
4007 // the subtypes don't need to be compatible here
4008 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
4009 error("The operands of operation `%s' should be of compatible "
4010 "types", get_opname());
4011 set_valuetype(V_ERROR
);
4013 if (info1
.needs_conversion() || info2
.needs_conversion()) {
4014 set_needs_conversion(); // Avoid folding.
4019 if (info1
.is_erroneous())
4020 v1
->error("%s", info1
.get_error_str_str().c_str());
4021 else if (info2
.is_erroneous())
4022 v2
->error("%s", info2
.get_error_str_str().c_str());
4023 set_valuetype(V_ERROR
);
4026 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
4027 set_needs_conversion(); // Avoid folding.
4032 v2
->set_my_governor(t1
);
4033 t1
->chk_this_value_ref(v2
);
4034 if (v2
->valuetype
== V_OMIT
) {
4035 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4037 v1
->chk_expr_omit_comparison(exp_val
);
4039 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4041 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4042 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4047 v1
->set_my_governor(t2
);
4048 t2
->chk_this_value_ref(v1
);
4049 if (v1
->valuetype
== V_OMIT
) {
4050 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4052 v2
->chk_expr_omit_comparison(exp_val
);
4054 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4056 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4057 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4061 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4062 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
4063 // Here, it cannot be that both are T_UNDEF.
4064 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4065 error("Please use reference as %s operand of operator `%s'",
4066 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
4067 set_valuetype(V_ERROR
);
4070 // Deny type compatibility if no governors found. The typetype_t must
4071 // be the same. TODO: How can this happen?
4072 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
4073 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
4074 error("The operands of operation `%s' should be of compatible types",
4076 set_valuetype(V_ERROR
);
4081 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
4082 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
4084 if(valuetype
==V_ERROR
) return;
4085 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4086 Assignment
*t_ass
= ref
->get_refd_assignment();
4087 if(!t_ass
) goto error
;
4088 switch(t_ass
->get_asstype()) {
4089 case Assignment::A_TIMER
:
4090 case Assignment::A_PAR_TIMER
:
4091 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
4092 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
4093 chk_expr_dynamic_part(exp_val
, true);
4095 case Assignment::A_CONST
:
4096 case Assignment::A_EXT_CONST
:
4097 case Assignment::A_MODULEPAR
:
4098 case Assignment::A_VAR
:
4099 case Assignment::A_FUNCTION_RVAL
:
4100 case Assignment::A_EXT_FUNCTION_RVAL
:
4101 case Assignment::A_PAR_VAL_IN
:
4102 case Assignment::A_PAR_VAL_OUT
:
4103 case Assignment::A_PAR_VAL_INOUT
: {
4104 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
4105 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
4106 val
->set_my_scope(my_scope
);
4107 val
->set_fullname(u
.expr
.r1
->get_fullname());
4108 val
->set_location(*u
.expr
.r1
);
4110 chk_expr_operand_compref(val
, opnum
, get_opname());
4111 chk_expr_dynamic_part(exp_val
, false);
4114 ref
->error("%s operand of operation `%s' should be timer or"
4115 " component reference instead of %s",
4116 opnum
, opname
, t_ass
->get_description().c_str());
4121 set_valuetype(V_ERROR
);
4124 Type
*Value::chk_expr_operand_comptyperef_create()
4126 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4127 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4128 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4129 if (!t_ass
) goto error
;
4130 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4131 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4132 Type::EXPECTED_DYNAMIC_VALUE
);
4133 if (!t_type
) goto error
;
4134 t_type
= t_type
->get_type_refd_last();
4135 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4137 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4138 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4139 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4140 u
.expr
.r1
->error("Incompatible component types: operation "
4141 "`create' should refer to `%s' instead of "
4143 my_governor_last
->get_typename().c_str(),
4144 t_type
->get_typename().c_str());
4150 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4151 "expected in operation `create' instead of `%s'",
4152 t_type
->get_typename().c_str());
4155 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4156 "instead of %s", t_ass
->get_description().c_str());
4159 set_valuetype(V_ERROR
);
4163 void Value::chk_expr_comptype_compat()
4165 if (valuetype
!= V_EXPR
)
4166 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4167 if (!my_governor
|| !my_scope
) return;
4168 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4169 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4171 switch (u
.expr
.v_optype
) {
4172 case OPTYPE_COMP_MTC
:
4173 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4175 case OPTYPE_COMP_SYSTEM
:
4176 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4178 case OPTYPE_COMP_SELF
: {
4179 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4180 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4183 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4188 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4189 error("Incompatible component types: a component reference of "
4190 "type `%s' was expected, but `%s' has type `%s'",
4191 my_governor_last
->get_typename().c_str(), get_opname(),
4192 t_comptype
->get_typename().c_str());
4193 set_valuetype(V_ERROR
);
4197 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4200 if(valuetype
== V_ERROR
) return;
4201 switch(val
->get_valuetype()) {
4203 Error_Context
cntxt(this, "In `%s' operation", opname
);
4204 Value
*v_last
= val
->get_value_refd_last();
4205 if(!v_last
) goto error
;
4206 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4208 t
= t
->get_type_refd_last();
4209 if(t
->get_typetype() != Type::T_COMPONENT
) {
4210 v_last
->error("%s operand of operation `%s': Type mismatch:"
4211 " component reference was expected instead of `%s'",
4212 opnum
, opname
, t
->get_typename().c_str());
4217 Reference
*ref
= val
->get_reference();
4218 Assignment
*t_ass
= ref
->get_refd_assignment();
4220 if (!t_ass
) goto error
;
4221 switch(t_ass
->get_asstype()) {
4222 case Assignment::A_CONST
:
4223 t_val
= t_ass
->get_Value();
4225 case Assignment::A_EXT_CONST
:
4226 case Assignment::A_MODULEPAR
:
4227 case Assignment::A_VAR
:
4228 case Assignment::A_FUNCTION_RVAL
:
4229 case Assignment::A_EXT_FUNCTION_RVAL
:
4230 case Assignment::A_PAR_VAL_IN
:
4231 case Assignment::A_PAR_VAL_OUT
:
4232 case Assignment::A_PAR_VAL_INOUT
: {
4233 Type
*t_type
=t_ass
->get_Type()
4234 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4235 if(!t_type
) goto error
;
4236 t_type
=t_type
->get_type_refd_last();
4237 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4238 ref
->error("%s operand of operation `%s': Type mismatch:"
4239 " component reference was expected instead of `%s'",
4240 opnum
, opname
, t_type
->get_typename().c_str());
4245 ref
->error("%s operand of operation `%s' should be"
4246 " component reference instead of %s",
4247 opnum
, opname
, t_ass
->get_description().c_str());
4251 ReferenceChain
refch(this, "While searching referenced value");
4252 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4254 t_val
= t_val
->get_value_refd_last();
4255 if (t_val
->valuetype
!= V_EXPR
) return;
4256 switch (t_val
->u
.expr
.v_optype
) {
4257 case OPTYPE_COMP_NULL
:
4258 ref
->error("%s operand of operation `%s' refers to `null' component "
4259 "reference", opnum
, opname
);
4261 case OPTYPE_COMP_MTC
:
4262 ref
->error("%s operand of operation `%s' refers to the component "
4263 "reference of the `mtc'", opnum
, opname
);
4265 case OPTYPE_COMP_SYSTEM
:
4266 ref
->error("%s operand of operation `%s' refers to the component "
4267 "reference of the `system'", opnum
, opname
);
4275 FATAL_ERROR("Value::chk_expr_operand_compref()");
4278 set_valuetype(V_ERROR
);
4281 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4285 if(valuetype
==V_ERROR
) return;
4286 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4287 Assignment
*t_ass
= ref
->get_refd_assignment();
4288 if(!t_ass
) goto error
;
4289 switch(t_ass
->get_asstype()) {
4290 case Assignment::A_TIMER
: {
4291 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4292 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4293 Type::EXPECTED_DYNAMIC_VALUE
);
4294 else if (ref
->get_subrefs()) {
4295 ref
->error("%s operand of operation `%s': "
4296 "Reference to single timer `%s' cannot have field or array "
4297 "sub-references", opnum
, opname
,
4298 t_ass
->get_id().get_dispname().c_str());
4302 case Assignment::A_PAR_TIMER
:
4303 if (ref
->get_subrefs()) {
4304 ref
->error("%s operand of operation `%s': "
4305 "Reference to %s cannot have field or array sub-references",
4306 opnum
, opname
, t_ass
->get_description().c_str());
4311 ref
->error("%s operand of operation `%s' should be timer"
4313 opnum
, opname
, t_ass
->get_description().c_str());
4318 set_valuetype(V_ERROR
);
4321 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4325 if(valuetype
==V_ERROR
) return;
4326 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4327 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4328 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4329 Error_Context
cntxt(this, "In `%s' operation", opname
);
4330 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4333 void Value::chk_expr_operand_activate_refd(Value
*val
,
4334 Ttcn::TemplateInstances
* t_list2
,
4335 Ttcn::ActualParList
*&parlist
,
4339 if(valuetype
==V_ERROR
) return;
4340 Error_Context
cntxt(this, "In `%s' operation", opname
);
4341 Type
*t
= val
->get_expr_governor_last();
4343 switch (t
->get_typetype()) {
4345 set_valuetype(V_ERROR
);
4347 case Type::T_ALTSTEP
: {
4348 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4349 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4353 set_valuetype(V_ERROR
);
4355 parlist
->set_fullname(get_fullname());
4356 parlist
->set_my_scope(get_my_scope());
4357 if (!fp_list
->chk_activate_argument(parlist
,
4358 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4362 error("Reference to an altstep was expected in the argument of "
4363 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4364 set_valuetype(V_ERROR
);
4367 } else set_valuetype(V_ERROR
);
4370 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4374 if(valuetype
==V_ERROR
) return;
4375 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4376 Error_Context
cntxt(this, "In `%s' operation", opname
);
4377 Assignment
*t_ass
= ref
->get_refd_assignment();
4378 bool error_flag
= false;
4380 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4381 ref
->error("Reference to a testcase was expected in the argument "
4382 "instead of %s", t_ass
->get_description().c_str());
4385 } else error_flag
= true;
4387 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4388 Value
*v_last
= val
->get_value_refd_last();
4389 switch (v_last
->valuetype
) {
4391 ttcn3float v_real
= v_last
->get_val_Real();
4393 val
->error("The testcase guard timer has negative value: `%s'",
4394 Real2string(v_real
).c_str());
4405 if (error_flag
) set_valuetype(V_ERROR
);
4408 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4409 Ttcn::TemplateInstances
* t_list2
,
4410 Ttcn::ActualParList
*&parlist
,
4415 if(valuetype
==V_ERROR
) return;
4416 Error_Context
cntxt(this, "In `%s' operation", opname
);
4417 Type
*t
= v1
->get_expr_governor_last();
4419 switch (t
->get_typetype()) {
4421 set_valuetype(V_ERROR
);
4423 case Type::T_TESTCASE
: {
4424 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4425 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4429 set_valuetype(V_ERROR
);
4431 parlist
->set_fullname(get_fullname());
4432 parlist
->set_my_scope(get_my_scope());
4436 v1
->error("Reference to a value of type testcase was expected in the "
4437 "argument of `derefers()' instead of `%s'",
4438 t
->get_typename().c_str());
4439 set_valuetype(V_ERROR
);
4442 } else set_valuetype(V_ERROR
);
4444 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4445 Value
*v_last
= v3
->get_value_refd_last();
4446 switch (v_last
->valuetype
) {
4448 ttcn3float v_real
= v_last
->get_val_Real();
4450 v3
->error("The testcase guard timer has negative value: `%s'",
4451 Real2string(v_real
).c_str());
4452 set_valuetype(V_ERROR
);
4456 set_valuetype(V_ERROR
);
4464 void Value::chk_invoke(Type::expected_value_t exp_val
)
4466 if(valuetype
== V_ERROR
) return;
4467 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4468 if(!u
.invoke
.t_list
) return; //already checked
4469 Error_Context
cntxt(this, "In `apply()' operation");
4470 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4472 set_valuetype(V_ERROR
);
4475 switch (t
->get_typetype()) {
4477 set_valuetype(V_ERROR
);
4479 case Type::T_FUNCTION
:
4482 u
.invoke
.v
->error("A value of type function was expected in the "
4483 "argument instead of `%s'", t
->get_typename().c_str());
4484 set_valuetype(V_ERROR
);
4487 my_scope
->chk_runs_on_clause(t
, *this, "call");
4488 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4489 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4490 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4491 delete u
.invoke
.t_list
;
4492 u
.invoke
.t_list
= 0;
4495 u
.invoke
.ap_list
= 0;
4497 parlist
->set_fullname(get_fullname());
4498 parlist
->set_my_scope(get_my_scope());
4499 u
.invoke
.ap_list
= parlist
;
4502 case Type::EXPECTED_CONSTANT
:
4503 error("An evaluable constant value was expected instead of operation "
4505 set_valuetype(V_ERROR
);
4507 case Type::EXPECTED_STATIC_VALUE
:
4508 error("A static value was expected instead of operation `apply()'");
4509 set_valuetype(V_ERROR
);
4516 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4517 ReferenceChain
*refch
,
4518 Type::expected_value_t exp_val
)
4520 bool self_ref
= false;
4521 if(valuetype
==V_ERROR
) return;
4522 // Commented out to report more errors :)
4523 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4524 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4525 switch(val
->get_valuetype()) {
4527 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4532 val
->get_value_refd_last(refch
, exp_val
);
4537 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4542 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4543 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4545 bool self_ref
= false;
4547 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4548 ti
->error("Reference to a %s value was expected instead of an in-line "
4549 "modified template",
4550 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4551 set_valuetype(V_ERROR
);
4554 Template
*templ
= ti
->get_Template();
4555 switch (templ
->get_templatetype()) {
4556 case Template::TEMPLATE_REFD
:
4558 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4559 templ
= templ
->get_template_refd_last(refch
);
4560 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4561 set_valuetype(V_ERROR
);
4563 ti
->error("Reference to a %s value was expected instead of %s",
4564 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4565 templ
->get_reference()->get_refd_assignment()
4566 ->get_description().c_str());
4567 set_valuetype(V_ERROR
);
4570 case Template::SPECIFIC_VALUE
: {
4571 Value
*val
= templ
->get_specific_value();
4572 switch (val
->get_valuetype()) {
4574 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4577 val
->get_value_refd_last(refch
, exp_val
);
4581 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4583 case Template::TEMPLATE_ERROR
:
4584 set_valuetype(V_ERROR
);
4593 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4596 if(valuetype
==V_ERROR
) return;
4597 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4598 if(val
->is_unfoldable()) return;
4599 if(*val
->get_val_Int()<0) {
4600 val
->error("%s operand of operation `%s' should not be negative",
4602 set_valuetype(V_ERROR
);
4606 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4609 if(valuetype
==V_ERROR
) return;
4610 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4611 if(val
->is_unfoldable()) return;
4612 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4613 val
->error("%s operand of operation `%s' should be in range 0..127",
4615 set_valuetype(V_ERROR
);
4619 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4622 if(valuetype
==V_ERROR
) return;
4623 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4624 if(val
->is_unfoldable()) return;
4625 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4626 val
->error("%s operand of operation `%s' should be in range"
4627 " 0..2147483647", opnum
, opname
);
4628 set_valuetype(V_ERROR
);
4632 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4635 if(valuetype
==V_ERROR
) return;
4636 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4637 if(val
->is_unfoldable()) return;
4638 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4640 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4642 val
->error("%s operand of operation `%s' should not be zero",
4644 set_valuetype(V_ERROR
);
4648 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4651 if (valuetype
== V_ERROR
) return;
4652 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4653 if (val
->get_expr_returntype() != Type::T_INT
) return;
4654 if (val
->is_unfoldable()) return;
4655 const int_val_t
*val_int
= val
->get_val_Int();
4656 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4657 val
->error("%s operand of operation `%s' should be less than `%d' "
4658 "instead of `%s'", opnum
, opname
, INT_MAX
,
4659 (val_int
->t_str()).c_str());
4660 set_valuetype(V_ERROR
);
4664 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4667 if(valuetype
==V_ERROR
) return;
4668 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4669 if(val
->is_unfoldable()) return;
4670 if(val
->get_val_strlen()!=1) {
4671 val
->error("%s operand of operation `%s' should be of length 1",
4673 set_valuetype(V_ERROR
);
4677 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4680 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4681 Value
*v_last
= val
->get_value_refd_last();
4682 if (v_last
->valuetype
== V_CSTR
) {
4683 size_t len
= v_last
->get_val_strlen();
4685 val
->error("%s operand of operation `%s' should contain even number "
4686 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4687 set_valuetype(V_ERROR
);
4689 } else if (v_last
->valuetype
== V_REFD
) {
4690 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4691 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4692 val
->error("%s operand of operation `%s' should contain even number "
4693 "of characters, but a string element contains 1", opnum
, opname
);
4694 set_valuetype(V_ERROR
);
4699 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4702 if(valuetype
==V_ERROR
) return;
4703 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4704 if(val
->is_unfoldable()) return;
4705 const string
& s
=val
->get_val_str();
4706 for(size_t i
=0; i
<s
.size(); i
++) {
4708 if(!(c
=='0' || c
=='1')) {
4709 val
->error("%s operand of operation `%s' can contain only"
4710 " binary digits (position %lu is `%c')",
4711 opnum
, opname
, (unsigned long) i
, c
);
4712 set_valuetype(V_ERROR
);
4718 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4721 if(valuetype
==V_ERROR
) return;
4722 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4723 if(val
->is_unfoldable()) return;
4724 const string
& s
=val
->get_val_str();
4725 for(size_t i
=0; i
<s
.size(); i
++) {
4727 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4728 val
->error("%s operand of operation `%s' can contain only valid "
4729 "hexadecimal digits (position %lu is `%c')",
4730 opnum
, opname
, (unsigned long) i
, c
);
4731 set_valuetype(V_ERROR
);
4737 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4740 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4741 Value
*v
= val
->get_value_refd_last();
4742 if (v
->valuetype
!= V_OSTR
) return;
4743 const string
& s
= val
->get_val_str();
4744 size_t n_octets
= s
.size() / 2;
4745 for (size_t i
= 0; i
< n_octets
; i
++) {
4747 if (!(c
>= '0' && c
<= '7')) {
4748 val
->error("%s operand of operation `%s' shall consist of octets "
4749 "within the range 00 .. 7F, but the string `%s'O contains octet "
4750 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4752 set_valuetype(V_ERROR
);
4758 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4761 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4762 Value
*v_last
= val
->get_value_refd_last();
4763 if (v_last
->valuetype
!= V_CSTR
) return;
4764 const string
& s
= v_last
->get_val_str();
4765 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4767 // state: expected characters
4768 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4769 // S_FIRST: first digit
4770 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4771 // S_END: trailing whitespace
4772 // S_ERR: error was found, stop
4773 for (size_t i
= 0; i
< s
.size(); i
++) {
4778 if (c
== '+' || c
== '-') state
= S_FIRST
;
4779 else if (c
== '0') state
= S_ZERO
;
4780 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4781 else if (string::is_whitespace(c
)) {
4782 if (state
== S_INITIAL
) {
4783 val
->warning("Leading whitespace was detected and ignored in the "
4784 "operand of operation `%s'", opname
);
4785 state
= S_INITIAL_WS
;
4787 } else state
= S_ERR
;
4790 if (c
== '0') state
= S_ZERO
;
4791 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4795 if (c
>= '0' && c
<= '9') {
4796 val
->warning("Leading zero digit was detected and ignored in the "
4797 "operand of operation `%s'", opname
);
4799 } else if (string::is_whitespace(c
)) state
= S_END
;
4803 if (c
>= '0' && c
<= '9') {}
4804 else if (string::is_whitespace(c
)) state
= S_END
;
4808 if (!string::is_whitespace(c
)) state
= S_ERR
;
4813 if (state
== S_ERR
) {
4814 if (string::is_printable(c
)) {
4815 val
->error("%s operand of operation `%s' should be a string "
4816 "containing a valid integer value, but invalid character `%c' "
4817 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4819 val
->error("%s operand of operation `%s' should be a string "
4820 "containing a valid integer value, but invalid character with "
4821 "character code %u was detected at index %lu", opnum
, opname
, c
,
4824 set_valuetype(V_ERROR
);
4831 val
->error("%s operand of operation `%s' should be a string containing a "
4832 "valid integer value instead of an empty string", opnum
, opname
);
4833 set_valuetype(V_ERROR
);
4836 val
->error("%s operand of operation `%s' should be a string containing a "
4837 "valid integer value, but only a sign character was detected", opnum
,
4839 set_valuetype(V_ERROR
);
4842 val
->warning("Trailing whitespace was detected and ignored in the "
4843 "operand of operation `%s'", opname
);
4850 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4853 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4854 Value
*v_last
= val
->get_value_refd_last();
4855 if (v_last
->valuetype
== V_REFD
) {
4856 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4857 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4858 val
->error("%s operand of operation `%s' should be a string containing "
4859 "a valid float value instead of a string element, which cannot "
4860 "represent a floating point number", opnum
, opname
);
4861 set_valuetype(V_ERROR
);
4864 } else if (v_last
->valuetype
!= V_CSTR
) return;
4865 const string
& s
= v_last
->get_val_str();
4866 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4867 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4869 // state: expected characters
4870 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4871 // leading whitespace
4872 // S_FIRST_M: first digit of integer part in mantissa
4873 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4874 // S_FIRST_F: first digit of fraction
4875 // S_MORE_F: more digits of fraction, E, trailing whitespace
4876 // S_INITIAL_E: +, -, first digit of exponent
4877 // S_FIRST_E: first digit of exponent
4878 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4879 // S_END: trailing whitespace
4880 // S_ERR: error was found, stop
4881 for (size_t i
= 0; i
< s
.size(); i
++) {
4886 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4887 else if (c
== '0') state
= S_ZERO_M
;
4888 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4889 else if (string::is_whitespace(c
)) {
4890 if (state
== S_INITIAL
) {
4891 val
->warning("Leading whitespace was detected and ignored in the "
4892 "operand of operation `%s'", opname
);
4893 state
= S_INITIAL_WS
;
4895 } else state
= S_ERR
;
4898 if (c
== '0') state
= S_ZERO_M
;
4899 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4903 if (c
== '.') state
= S_FIRST_F
;
4904 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4905 else if (c
>= '0' && c
<= '9') {
4906 val
->warning("Leading zero digit was detected and ignored in the "
4907 "mantissa of the operand of operation `%s'", opname
);
4909 } else state
= S_ERR
;
4912 if (c
== '.') state
= S_FIRST_F
;
4913 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4914 else if (c
>= '0' && c
<= '9') {}
4918 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4922 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4923 else if (c
>= '0' && c
<= '9') {}
4924 else if (string::is_whitespace(c
)) state
= S_END
;
4928 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4929 else if (c
== '0') state
= S_ZERO_E
;
4930 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4934 if (c
== '0') state
= S_ZERO_E
;
4935 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4939 if (c
>= '0' && c
<= '9') {
4940 val
->warning("Leading zero digit was detected and ignored in the "
4941 "exponent of the operand of operation `%s'", opname
);
4943 } else if (string::is_whitespace(c
)) state
= S_END
;
4947 if (c
>= '0' && c
<= '9') {}
4948 else if (string::is_whitespace(c
)) state
= S_END
;
4952 if (!string::is_whitespace(c
)) state
= S_ERR
;
4957 if (state
== S_ERR
) {
4958 if (string::is_printable(c
)) {
4959 val
->error("%s operand of operation `%s' should be a string "
4960 "containing a valid float value, but invalid character `%c' "
4961 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4963 val
->error("%s operand of operation `%s' should be a string "
4964 "containing a valid float value, but invalid character with "
4965 "character code %u was detected at index %lu", opnum
, opname
, c
,
4968 set_valuetype(V_ERROR
);
4975 val
->error("%s operand of operation `%s' should be a string containing a "
4976 "valid float value instead of an empty string", opnum
, opname
);
4977 set_valuetype(V_ERROR
);
4980 val
->error("%s operand of operation `%s' should be a string containing a "
4981 "valid float value, but only a sign character was detected", opnum
,
4983 set_valuetype(V_ERROR
);
4987 // HL67862: Missing decimal dot allowed for str2float
4990 // HL67862: Missing fraction part is allowed for str2float
4994 val
->error("%s operand of operation `%s' should be a string containing a "
4995 "valid float value, but the exponent is missing after the `E' sign",
4997 set_valuetype(V_ERROR
);
5000 val
->warning("Trailing whitespace was detected and ignored in the "
5001 "operand of operation `%s'", opname
);
5008 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
5011 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5012 Value
*v
= val
->get_value_refd_last();
5013 if (v
->valuetype
!= V_USTR
) return;
5014 const ustring
& us
= v
->get_val_ustr();
5015 for (size_t i
= 0; i
< us
.size(); i
++) {
5016 const ustring::universal_char
& uchar
= us
[i
];
5017 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
5019 val
->error("%s operand of operation `%s' shall consist of characters "
5020 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5021 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5022 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
5023 uchar
.row
, uchar
.cell
, (unsigned long) i
);
5024 set_valuetype(V_ERROR
);
5030 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
5033 if(valuetype
==V_ERROR
) return;
5034 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5035 if(val
->is_unfoldable()) return;
5036 const string
& bstr
=val
->get_val_str();
5037 // see also PredefFunc.cc::bit2int()
5038 size_t nof_bits
= bstr
.size();
5039 // skip the leading zeros
5040 size_t start_index
= 0;
5041 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
5042 // check whether the remaining bits fit in Int
5043 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
5044 val
->error("%s operand of operation `%s' is too large (maximum number"
5045 " of bits in integer is %lu)",
5046 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5047 set_valuetype(V_ERROR
);
5051 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
5054 if(valuetype
==V_ERROR
) return;
5055 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5056 if(val
->is_unfoldable()) return;
5057 const string
& hstr
=val
->get_val_str();
5058 // see also PredefFunc.cc::hex2int()
5059 size_t nof_digits
= hstr
.size();
5060 // skip the leading zeros
5061 size_t start_index
= 0;
5062 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
5063 // check whether the remaining hex digits fit in Int
5064 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
5065 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
5066 char_to_hexdigit(hstr
[start_index
]) > 7)) {
5067 val
->error("%s operand of operation `%s' is too large (maximum number"
5068 " of bits in integer is %lu)",
5069 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5070 set_valuetype(V_ERROR
);
5074 void Value::chk_expr_operands_int2binstr()
5076 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5077 if (u
.expr
.v1
->is_unfoldable()) return;
5078 if (u
.expr
.v2
->is_unfoldable()) return;
5079 // It is already checked that i1 and i2 are non-negative.
5080 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5081 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
5082 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
5083 if (!i2
->is_native()) {
5084 u
.expr
.v2
->error("The length of the resulting string is too large for "
5085 "being represented in memory");
5086 set_valuetype(V_ERROR
);
5089 Int nof_bits
= i2
->get_val();
5090 if (u
.expr
.v1
->is_unfoldable()) return;
5091 switch (u
.expr
.v_optype
) {
5092 case OPTYPE_INT2BIT
:
5094 case OPTYPE_INT2HEX
:
5097 case OPTYPE_INT2OCT
:
5101 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5103 if (*i1
>> nof_bits
> 0) { // Expensive?
5104 u
.expr
.v1
->error("Value %s does not fit in length %s",
5105 i1
->t_str().c_str(), i2
->t_str().c_str());
5106 set_valuetype(V_ERROR
);
5110 void Value::chk_expr_operands_str_samelen()
5112 if(valuetype
==V_ERROR
) return;
5113 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5114 Value
*v1
=u
.expr
.v1
;
5115 if(v1
->is_unfoldable()) return;
5116 Value
*v2
=u
.expr
.v2
;
5117 if(v2
->is_unfoldable()) return;
5118 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5119 size_t i1
=v1
->get_val_strlen();
5120 size_t i2
=v2
->get_val_strlen();
5122 error("The operands should have the same length");
5123 set_valuetype(V_ERROR
);
5127 void Value::chk_expr_operands_replace()
5129 // The fourth operand doesn't need to be checked at all here.
5130 if(valuetype
==V_ERROR
) return;
5131 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5132 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5135 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5136 size_t list_len
= 0;
5137 bool list_len_known
= false;
5138 if (v1
->valuetype
== V_REFD
) {
5139 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5140 if (subrefs
&& subrefs
->refers_to_string_element()) {
5141 warning("Replacing a string element does not make any sense");
5143 list_len_known
= true;
5146 if (!v1
->is_unfoldable()) {
5147 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5148 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5149 list_len_known
= true;
5151 if (!list_len_known
) return;
5152 if (u
.expr
.v2
->is_unfoldable()) {
5153 if (!u
.expr
.v3
->is_unfoldable()) {
5154 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5155 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5156 error("Third operand `len' (%s) is greater than the length of "
5157 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5158 (unsigned long)list_len
);
5159 set_valuetype(V_ERROR
);
5163 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5164 if (u
.expr
.v3
->is_unfoldable()) {
5165 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5166 error("Second operand `index' (%s) is greater than the length of "
5167 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5168 (unsigned long)list_len
);
5169 set_valuetype(V_ERROR
);
5172 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5173 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5174 error("The sum of second operand `index' (%s) and third operand "
5175 "`len' (%s) is greater than the length of the first operand (%lu)",
5176 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5177 (unsigned long)list_len
);
5178 set_valuetype(V_ERROR
);
5184 void Value::chk_expr_operands_substr()
5186 if(valuetype
==V_ERROR
) return;
5187 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5188 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5191 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5192 size_t list_len
= 0;
5193 bool list_len_known
= false;
5194 if (v1
->valuetype
== V_REFD
) {
5195 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5196 if (subrefs
&& subrefs
->refers_to_string_element()) {
5197 warning("Taking the substring of a string element does not make any "
5200 list_len_known
= true;
5203 if (!list_len_known
&& !v1
->is_unfoldable()) {
5204 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5205 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5206 list_len_known
= true;
5208 // Do nothing if the length of the first operand is unknown.
5209 if (!list_len_known
) return;
5210 if (u
.expr
.v2
->is_unfoldable()) {
5211 if (!u
.expr
.v3
->is_unfoldable()) {
5212 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5213 // Only the third operand is known.
5214 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5215 error("Third operand `returncount' (%s) is greater than the "
5216 "length of the first operand (%lu)",
5217 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5218 set_valuetype(V_ERROR
);
5222 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5223 if (u
.expr
.v3
->is_unfoldable()) {
5224 // Only the second operand is known.
5225 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5226 error("Second operand `index' (%s) is greater than the length "
5227 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5228 (unsigned long)list_len
);
5229 set_valuetype(V_ERROR
);
5232 // Both second and third operands are known.
5233 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5234 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5235 error("The sum of second operand `index' (%s) and third operand "
5236 "`returncount' (%s) is greater than the length of the first operand "
5237 "(%lu)", (index_int_2
->t_str()).c_str(),
5238 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5239 set_valuetype(V_ERROR
);
5245 void Value::chk_expr_operands_regexp()
5247 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5248 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5249 Value
* v2
= u
.expr
.t2
->get_specific_value();
5250 if (!v1
|| !v2
) return;
5252 Error_Context
cntxt(this, "In operation `regexp()'");
5253 Value
* v1_last
= v1
->get_value_refd_last();
5254 if (v1_last
->valuetype
== V_CSTR
) {
5255 // the input string is available at compile time
5256 const string
& instr
= v1_last
->get_val_str();
5257 const char *input_str
= instr
.c_str();
5258 size_t instr_len
= strlen(input_str
);
5259 if (instr_len
< instr
.size()) {
5260 v1
->warning("The first operand of `regexp()' contains a "
5261 "character with character code zero at index %s. The rest of the "
5262 "string will be ignored during matching",
5263 Int2string(instr_len
).c_str());
5267 size_t nof_groups
= 0;
5268 Value
*v2_last
= v2
->get_value_refd_last();
5270 if (v2_last
->valuetype
== V_CSTR
) {
5271 // the pattern is available at compile time
5272 const string
& expression
= v2_last
->get_val_str();
5273 const char *pattern_str
= expression
.c_str();
5274 size_t pattern_len
= strlen(pattern_str
);
5275 if (pattern_len
< expression
.size()) {
5276 v2
->warning("The second operand of `regexp()' contains a "
5277 "character with character code zero at index %s. The rest of the "
5278 "string will be ignored during matching",
5279 Int2string(pattern_len
).c_str());
5283 Error_Context
cntxt2(v2
, "In character string pattern");
5284 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5286 if (posix_str
!= NULL
) {
5287 regex_t posix_regexp
;
5288 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5291 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5292 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5293 "regcomp() failed: %s", msg
);
5295 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5297 v2
->error("The character pattern in the second operand of "
5298 "`regexp()' does not contain any groups");
5299 set_valuetype(V_ERROR
);
5301 regfree(&posix_regexp
);
5304 // the pattern is faulty
5305 // the error has been reported by TTCN_pattern_to_regexp
5306 set_valuetype(V_ERROR
);
5309 if (nof_groups
> 0) {
5310 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5311 if (v3
->valuetype
== V_INT
) {
5312 // the group number is available at compile time
5313 const int_val_t
*groupno_int
= v3
->get_val_Int();
5314 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5315 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5316 "large: The requested group index is %s, but the pattern "
5317 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5318 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5319 set_valuetype(V_ERROR
);
5325 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5326 Type::expected_value_t exp_val
)
5328 const char *opname
= get_opname();
5329 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5331 const Location
*loc
;
5332 bool error_flag
= false;
5333 switch (u
.expr
.v_optype
) {
5334 case OPTYPE_ISCHOSEN_V
:
5335 // u.expr.v1 is always a referenced value
5336 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5338 u
.expr
.v1
->set_my_governor(t_governor
);
5339 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5340 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5341 } else error_flag
= true;
5344 case OPTYPE_ISCHOSEN_T
:
5345 // u.expr.t1 is always a referenced template
5346 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5347 exp_val
= Type::EXPECTED_TEMPLATE
;
5348 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5350 u
.expr
.t1
->set_my_governor(t_governor
);
5352 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5354 u
.expr
.t1
->get_template_refd_last(refch
);
5355 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5357 } else error_flag
= true;
5358 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5359 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5360 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5361 u
.expr
.t1
->get_reference()->get_refd_assignment()
5362 ->get_description().c_str());
5368 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5373 t_governor
= t_governor
->get_type_refd_last();
5374 switch (t_governor
->get_typetype()) {
5378 case Type::T_CHOICE_A
:
5379 case Type::T_CHOICE_T
:
5380 case Type::T_ANYTYPE
:
5381 case Type::T_OPENTYPE
:
5382 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5383 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5384 "%s does not have a field named `%s'" :
5385 "Union type `%s' does not have a field named `%s'",
5386 t_governor
->get_typename().c_str(),
5387 u
.expr
.i2
->get_dispname().c_str());
5392 loc
->error("The operand of operation `%s' should be a union value "
5393 "or template instead of `%s'", opname
,
5394 t_governor
->get_typename().c_str());
5399 if (error_flag
) set_valuetype(V_ERROR
);
5402 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5403 Type::expected_value_t exp_val
) {
5405 Error_Context
cntxt(this, "In the parameter of encvalue()");
5406 Type
t_chk(Type::T_ERROR
);
5409 Type::expected_value_t ti_exp_val
= exp_val
;
5410 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5411 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5413 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5415 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5416 if (valuetype
!=V_ERROR
)
5417 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5418 t_type
= t_type
->get_type_refd_last();
5420 error("Cannot determine type of value");
5425 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5426 error("Expecting a value of a type with coding attributes in first"
5427 "parameter of encvalue() which belongs to a generic type '%s'",
5428 t_type->get_typename().c_str());
5432 if(!disable_attribute_validation()) {
5433 t_type
->chk_coding(true);
5436 switch (t_type
->get_typetype()) {
5441 case Type::T_REFDSPEC
:
5442 case Type::T_SELTYPE
:
5443 case Type::T_VERDICT
:
5445 case Type::T_COMPONENT
:
5446 case Type::T_DEFAULT
:
5447 case Type::T_SIGNATURE
:
5448 case Type::T_FUNCTION
:
5449 case Type::T_ALTSTEP
:
5450 case Type::T_TESTCASE
:
5451 error("Type of parameter of encvalue() cannot be '%s'",
5452 t_type
->get_typename().c_str());
5459 set_valuetype(V_ERROR
);
5462 void Value::chk_expr_operands_decode(operationtype_t p_optype
)
5464 Error_Context
cntxt(this, "In the parameters of decvalue()"); //todo
5465 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5466 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5468 Assignment
* t_ass
= ref
->get_refd_assignment();
5471 error("Could not determine the assignment for first parameter");
5474 switch (t_ass
->get_asstype()) {
5475 case Assignment::A_PAR_VAL_IN
:
5476 t_ass
->use_as_lvalue(*this);
5478 case Assignment::A_CONST
:
5479 case Assignment::A_EXT_CONST
:
5480 case Assignment::A_MODULEPAR
:
5481 case Assignment::A_MODULEPAR_TEMP
:
5482 case Assignment::A_TEMPLATE
:
5483 ref
->error("Reference to '%s' cannot be used as the first operand of "
5484 "the 'decvalue' operation", t_ass
->get_assname());
5487 case Assignment::A_VAR
:
5488 case Assignment::A_PAR_VAL_OUT
:
5489 case Assignment::A_PAR_VAL_INOUT
:
5491 case Assignment::A_VAR_TEMPLATE
:
5492 case Assignment::A_PAR_TEMPL_IN
:
5493 case Assignment::A_PAR_TEMPL_OUT
:
5494 case Assignment::A_PAR_TEMPL_INOUT
: {
5495 Template
* t
= new Template(ref
->clone());
5496 t
->set_location(*ref
);
5497 t
->set_my_scope(get_my_scope());
5498 t
->set_fullname(get_fullname()+".<operand>");
5499 Template
* t_last
= t
->get_template_refd_last();
5500 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5502 ref
->error("Specific value template was expected instead of '%s'.",
5503 t
->get_template_refd_last()->get_templatetype_str());
5510 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5513 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5514 Type::EXPECTED_DYNAMIC_VALUE
);
5520 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5521 error("First parameter has to be a bitstring");
5525 case OPTYPE_DECVALUE_UNICHAR
:
5526 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_USTR
){
5527 error("First parameter has to be a universal charstring");
5532 FATAL_ERROR("Value::chk_expr_decode_operands()");
5537 t_subrefs
= ref
->get_subrefs();
5538 t_ass
= ref
->get_refd_assignment();
5541 error("Could not determine the assignment for second parameter");
5544 // Extra check for HM59355.
5545 switch (t_ass
->get_asstype()) {
5546 case Assignment::A_VAR
:
5547 case Assignment::A_PAR_VAL_IN
:
5548 case Assignment::A_PAR_VAL_OUT
:
5549 case Assignment::A_PAR_VAL_INOUT
:
5552 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5555 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5556 Type::EXPECTED_DYNAMIC_VALUE
);
5560 t_type
= t_type
->get_type_refd_last();
5561 switch (t_type
->get_typetype()) {
5566 case Type::T_REFDSPEC
:
5567 case Type::T_SELTYPE
:
5568 case Type::T_VERDICT
:
5570 case Type::T_COMPONENT
:
5571 case Type::T_DEFAULT
:
5572 case Type::T_SIGNATURE
:
5573 case Type::T_FUNCTION
:
5574 case Type::T_ALTSTEP
:
5575 case Type::T_TESTCASE
:
5576 error("Type of second parameter cannot be %s",
5577 t_type
->get_typename().c_str());
5583 if(!disable_attribute_validation()) {
5584 t_type
->chk_coding(false);
5589 set_valuetype(V_ERROR
);
5592 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5594 Ttcn::FieldOrArrayRefs
*subrefs
;
5595 Identifier
*field_id
= 0;
5598 if (valuetype
== V_ERROR
) return;
5599 else if (valuetype
!= V_REFD
) {
5600 error("Only a referenced value can be compared with `omit'");
5603 subrefs
= u
.ref
.ref
->get_subrefs();
5604 if (subrefs
) field_id
= subrefs
->remove_last_field();
5606 error("Only a reference pointing to an optional record or set field "
5607 "can be compared with `omit'");
5610 t_ass
= u
.ref
.ref
->get_refd_assignment();
5611 if (!t_ass
) goto error
;
5612 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5613 if (!t_type
) goto error
;
5614 t_type
= t_type
->get_type_refd_last();
5615 switch (t_type
->get_typetype()) {
5624 error("Only a reference pointing to an optional field of a record"
5625 " or set type can be compared with `omit'");
5628 if (!t_type
->has_comp_withName(*field_id
)) {
5629 error("Type `%s' does not have field named `%s'",
5630 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5632 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5633 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5634 "`omit'", field_id
->get_dispname().c_str(),
5635 t_type
->get_typename().c_str());
5638 // putting the last field_id back to subrefs
5639 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5642 set_valuetype(V_ERROR
);
5646 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5647 Type::expected_value_t exp_val
)
5649 if(valuetype
==V_ERROR
) return -1;
5650 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5651 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5652 exp_val
=Type::EXPECTED_TEMPLATE
;
5654 Error_Context
cntxt(this, "In the operand of"
5655 " operation `%s'", get_opname());
5658 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5661 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5664 t_templ
= t_templ
->get_template_refd_last(refch
);
5666 // Timer and port arrays are handled separately
5667 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5668 Value
* val
= t_templ
->get_specific_value();
5669 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5670 val
->set_lowerid_to_ref();
5672 if (val
&& val
->get_valuetype() == V_REFD
) {
5673 Reference
* ref
= val
->get_reference();
5674 Assignment
* t_ass
= ref
->get_refd_assignment();
5675 Common::Assignment::asstype_t asstype
=
5676 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5677 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5678 if (t_ass
->get_Dimensions()) {
5679 // here we have a timer or port array
5680 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5681 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5682 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5683 Type::EXPECTED_DYNAMIC_VALUE
);
5686 refd_dim
= t_subrefs
->get_nof_refs();
5687 size_t nof_dims
= t_dims
->get_nof_dims();
5688 if (refd_dim
>= nof_dims
) {
5689 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5690 t_ass
->get_assname());
5691 set_valuetype(V_ERROR
);
5694 } else refd_dim
= 0;
5695 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5697 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5698 t_ass
->get_description().c_str());
5699 set_valuetype(V_ERROR
);
5708 Assignment
* t_ass
= 0;
5710 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5711 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5713 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5714 t_type
= t_type
->get_type_refd_last();
5716 error("Cannot determine type of value");
5720 if(valuetype
==V_ERROR
) return -1;
5722 t_templ
= t_templ
->get_template_refd_last(refch
);
5723 switch(t_templ
->get_templatetype()) {
5724 case Template::TEMPLATE_ERROR
:
5726 case Template::INDEXED_TEMPLATE_LIST
:
5728 case Template::TEMPLATE_REFD
:
5729 case Template::TEMPLATE_LIST
:
5730 case Template::NAMED_TEMPLATE_LIST
:
5733 case Template::SPECIFIC_VALUE
:
5735 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5737 switch(t_val
->get_valuetype()) {
5747 ref
= t_val
->get_reference();
5748 t_ass
= ref
->get_refd_assignment();
5749 t_subrefs
= ref
->get_subrefs();
5753 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5754 t_val
->create_stringRepr().c_str());
5761 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5762 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5767 switch(t_ass
->get_asstype()) {
5768 case Assignment::A_ERROR
:
5770 case Assignment::A_CONST
:
5771 t_val
= t_ass
->get_Value();
5773 case Assignment::A_EXT_CONST
:
5774 case Assignment::A_MODULEPAR
:
5775 case Assignment::A_MODULEPAR_TEMP
:
5776 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5777 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5778 "expected instead of %s", t_ass
->get_description().c_str());
5782 case Assignment::A_VAR
:
5783 case Assignment::A_PAR_VAL_IN
:
5784 case Assignment::A_PAR_VAL_OUT
:
5785 case Assignment::A_PAR_VAL_INOUT
:
5787 case Type::EXPECTED_CONSTANT
:
5788 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5789 t_ass
->get_description().c_str());
5792 case Type::EXPECTED_STATIC_VALUE
:
5793 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5794 t_ass
->get_description().c_str());
5801 case Assignment::A_TEMPLATE
:
5802 t_templ
= t_ass
->get_Template();
5804 case Assignment::A_VAR_TEMPLATE
:
5805 case Assignment::A_PAR_TEMPL_IN
:
5806 case Assignment::A_PAR_TEMPL_OUT
:
5807 case Assignment::A_PAR_TEMPL_INOUT
:
5808 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5809 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5810 t_ass
->get_description().c_str());
5813 case Assignment::A_FUNCTION_RVAL
:
5814 case Assignment::A_EXT_FUNCTION_RVAL
:
5816 case Type::EXPECTED_CONSTANT
:
5817 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5818 "the return value of %s", t_ass
->get_description().c_str());
5821 case Type::EXPECTED_STATIC_VALUE
:
5822 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5823 "the return value of %s", t_ass
->get_description().c_str());
5830 case Assignment::A_FUNCTION_RTEMP
:
5831 case Assignment::A_EXT_FUNCTION_RTEMP
:
5832 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5833 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5834 " of %s, which returns a template",
5835 t_ass
->get_description().c_str());
5838 case Assignment::A_TIMER
:
5839 case Assignment::A_PORT
:
5840 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5841 // sizeof is applicable to timer and port arrays
5842 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5844 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5845 t_ass
->get_description().c_str());
5848 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5849 Type::EXPECTED_DYNAMIC_VALUE
);
5852 refd_dim
= t_subrefs
->get_nof_refs();
5853 size_t nof_dims
= t_dims
->get_nof_dims();
5854 if (refd_dim
> nof_dims
) goto error
;
5855 else if (refd_dim
== nof_dims
) {
5856 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5857 t_ass
->get_assname());
5860 } else refd_dim
= 0;
5861 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5865 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5866 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5867 t_ass
->get_description().c_str());
5871 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5872 if (!t_type
) goto error
;
5873 t_type
= t_type
->get_type_refd_last();
5875 switch(t_type
->get_typetype()) {
5892 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5893 " set, set of, objid or array was expected");
5898 // check for index overflows in subrefs if possible
5900 switch (t_val
->get_valuetype()) {
5904 if (t_val
->is_indexed()) {
5911 /* The reference points to a constant. */
5912 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5913 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5914 if (!t_val
) goto error
;
5915 t_val
=t_val
->get_value_refd_last(refch
);
5916 } else { t_val
= 0; }
5917 } else if (t_templ
) {
5918 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5919 time. Don't try to evaluate it at compile time. */
5920 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5922 /* The reference points to a static template. */
5923 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5924 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5925 if (!t_templ
) goto error
;
5926 t_templ
= t_templ
->get_template_refd_last(refch
);
5927 } else { t_templ
= 0; }
5930 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5932 switch(t_templ
->get_templatetype()) {
5933 case Template::TEMPLATE_ERROR
:
5935 case Template::TEMPLATE_REFD
:
5939 case Template::SPECIFIC_VALUE
:
5940 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5943 case Template::TEMPLATE_LIST
:
5944 case Template::NAMED_TEMPLATE_LIST
:
5947 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5948 t_templ
->get_templatetype_str(),
5949 t_templ
->get_fullname().c_str());
5954 switch(t_val
->get_valuetype()) {
5965 // error is already reported
5974 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5975 result
= t_type
->get_dimension()->get_size();
5977 else if(t_templ
) { // sizeof()
5978 switch(t_templ
->get_templatetype()) {
5979 case Template::TEMPLATE_LIST
:
5980 if(t_templ
->temps_contains_anyornone_symbol()) {
5981 if(t_templ
->is_length_restricted()) {
5982 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5983 if (lr
->get_is_range()) {
5984 Value
*v_upper
= lr
->get_upper_value();
5986 if (v_upper
->valuetype
== V_INT
) {
5988 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
5989 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
5992 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5993 "templates without exact size");
5998 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5999 "templates containing `*' without upper boundary in the "
6000 "length restriction");
6004 Value
*v_single
= lr
->get_single_value();
6005 if (v_single
->valuetype
== V_INT
)
6006 result
= v_single
->u
.val_Int
->get_val();
6009 else { // not length restricted
6010 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
6011 " containing `*' without length restriction");
6015 else result
=t_templ
->get_nof_listitems();
6017 case Template::NAMED_TEMPLATE_LIST
:
6019 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
6020 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
6021 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
6024 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6028 switch(t_val
->get_valuetype()) {
6035 result
=t_val
->get_nof_comps();
6040 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
6041 if(t_val
->get_se_comp_byIndex(i
)->get_value()
6042 ->get_valuetype()!=V_OMIT
) result
++;
6046 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6052 set_valuetype(V_ERROR
);
6056 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
6058 Type
*governor
= ti
->get_expr_governor(exp_val
);
6060 ti
->get_Template()->set_lowerid_to_ref();
6061 governor
= ti
->get_expr_governor(exp_val
);
6065 ti
->append_stringRepr( str
);
6066 ti
->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6067 "If type is known, use valueof(<type>: %s) as argument.",
6068 str
.c_str(), get_opname(), str
.c_str());
6069 set_valuetype(V_ERROR
);
6074 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
6077 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
6078 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
6079 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
6080 Type::EXPECTED_TEMPLATE
: exp_val
);
6082 Template
*t_temp
= u
.expr
.t2
->get_Template();
6083 if (t_temp
->is_undef_lowerid()) {
6084 // We convert the template to reference first even if the value is also
6085 // an undef lowerid. The user can prevent this by explicit type
6087 t_temp
->set_lowerid_to_ref();
6089 } else if (u
.expr
.v1
->is_undef_lowerid()) {
6090 u
.expr
.v1
->set_lowerid_to_ref();
6095 error("Cannot determine the type of arguments in `match()' operation");
6096 set_valuetype(V_ERROR
);
6099 u
.expr
.v1
->set_my_governor(governor
);
6101 Error_Context
cntxt(this, "In the first argument of `match()'"
6103 governor
->chk_this_value_ref(u
.expr
.v1
);
6104 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
6105 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6108 Error_Context
cntxt(this, "In the second argument of `match()' "
6110 u
.expr
.t2
->chk(governor
);
6114 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
6115 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
6117 Ttcn::StatementBlock
*my_sb
;
6119 case Type::EXPECTED_CONSTANT
:
6120 error("An evaluable constant value was expected instead of operation "
6121 "`%s'", get_opname());
6123 case Type::EXPECTED_STATIC_VALUE
:
6124 error("A static value was expected instead of operation `%s'",
6130 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6131 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
6133 error("Operation `%s' is allowed only within statements",
6137 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6138 error("Operation `%s' is not allowed in the control part",
6142 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6143 error("Operation `%s' cannot be used in a definition that has "
6144 "`runs on' clause", get_opname());
6147 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6148 error("Operation `%s' can be used only in a definition that has "
6149 "`runs on' clause", get_opname());
6154 set_valuetype(V_ERROR
);
6157 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6159 if(valuetype
==V_ERROR
) return;
6160 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6161 if(v
->is_unfoldable()) return;
6162 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6163 ttcn3float r
= v
->get_val_Real();
6164 if (isSpecialFloatValue(r
)) {
6165 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6166 opnum
, opname
, Real2string(r
).c_str());
6167 set_valuetype(V_ERROR
);
6171 void Value::chk_expr_operands(ReferenceChain
*refch
,
6172 Type::expected_value_t exp_val
)
6174 const char *first
="First", *second
="Second", *third
="Third",
6175 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6176 Value
*v1
, *v2
, *v3
;
6177 Type::typetype_t tt1
, tt2
, tt3
;
6178 Type
t_chk(Type::T_ERROR
);
6180 const char *opname
=get_opname();
6182 // first classify the unchecked ischosen() operation
6183 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6185 switch (u
.expr
.v_optype
) {
6186 case OPTYPE_COMP_NULL
:
6187 case OPTYPE_TESTCASENAME
:
6188 case OPTYPE_PROF_RUNNING
:
6190 case OPTYPE_COMP_MTC
:
6191 case OPTYPE_COMP_SYSTEM
:
6192 chk_expr_comptype_compat();
6194 case OPTYPE_RND
: // -
6195 case OPTYPE_TMR_RUNNING_ANY
:
6196 chk_expr_dynamic_part(exp_val
, true);
6198 case OPTYPE_COMP_RUNNING_ANY
:
6199 case OPTYPE_COMP_RUNNING_ALL
:
6200 case OPTYPE_COMP_ALIVE_ANY
:
6201 case OPTYPE_COMP_ALIVE_ALL
:
6202 case OPTYPE_GETVERDICT
:
6203 chk_expr_dynamic_part(exp_val
, false);
6205 case OPTYPE_COMP_SELF
:
6206 chk_expr_comptype_compat();
6207 chk_expr_dynamic_part(exp_val
, false, true, false);
6209 case OPTYPE_UNARYPLUS
: // v1
6210 case OPTYPE_UNARYMINUS
:
6213 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6214 v1
->set_lowerid_to_ref();
6215 tt1
=v1
->get_expr_returntype(exp_val
);
6216 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6217 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6223 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6224 v1
->set_lowerid_to_ref();
6225 tt1
=v1
->get_expr_returntype(exp_val
);
6226 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6227 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6233 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6234 v1
->set_lowerid_to_ref();
6235 tt1
=v1
->get_expr_returntype(exp_val
);
6236 chk_expr_operandtype_binstr(tt1
, the
, opname
, v1
);
6237 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6240 case OPTYPE_BIT2HEX
:
6241 case OPTYPE_BIT2OCT
:
6242 case OPTYPE_BIT2STR
:
6245 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6246 v1
->set_lowerid_to_ref();
6247 tt1
=v1
->get_expr_returntype(exp_val
);
6248 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6249 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6252 case OPTYPE_BIT2INT
:
6255 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6256 v1
->set_lowerid_to_ref();
6257 tt1
=v1
->get_expr_returntype(exp_val
);
6258 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6259 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6260 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6263 case OPTYPE_CHAR2INT
:
6266 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6267 v1
->set_lowerid_to_ref();
6268 tt1
=v1
->get_expr_returntype(exp_val
);
6269 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6270 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6271 chk_expr_val_len1(v1
, the
, opname
);
6274 case OPTYPE_CHAR2OCT
:
6277 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6278 v1
->set_lowerid_to_ref();
6279 tt1
=v1
->get_expr_returntype(exp_val
);
6280 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6281 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6284 case OPTYPE_STR2INT
:
6287 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6288 v1
->set_lowerid_to_ref();
6289 tt1
=v1
->get_expr_returntype(exp_val
);
6290 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6291 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6292 chk_expr_val_str_int(v1
, the
, opname
);
6295 case OPTYPE_STR2FLOAT
:
6298 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6299 v1
->set_lowerid_to_ref();
6300 tt1
=v1
->get_expr_returntype(exp_val
);
6301 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6302 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6303 chk_expr_val_str_float(v1
, the
, opname
);
6306 case OPTYPE_STR2BIT
:
6309 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6310 v1
->set_lowerid_to_ref();
6311 tt1
=v1
->get_expr_returntype(exp_val
);
6312 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6313 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6314 chk_expr_val_str_bindigits(v1
, the
, opname
);
6317 case OPTYPE_STR2HEX
:
6320 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6321 v1
->set_lowerid_to_ref();
6322 tt1
=v1
->get_expr_returntype(exp_val
);
6323 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6324 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6325 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6328 case OPTYPE_STR2OCT
:
6331 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6332 v1
->set_lowerid_to_ref();
6333 tt1
=v1
->get_expr_returntype(exp_val
);
6334 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6335 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6336 chk_expr_val_str_len_even(v1
, the
, opname
);
6337 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6340 case OPTYPE_ENUM2INT
:
6343 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6344 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6345 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6349 chk_expr_operand_encode(refch
, exp_val
);
6351 case OPTYPE_FLOAT2INT
:
6352 case OPTYPE_FLOAT2STR
:
6355 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6356 v1
->set_lowerid_to_ref();
6357 tt1
=v1
->get_expr_returntype(exp_val
);
6358 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6359 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6360 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6361 chk_expr_operand_valid_float(v1
, the
, opname
);
6364 case OPTYPE_RNDWITHVAL
:
6367 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6368 v1
->set_lowerid_to_ref();
6369 tt1
=v1
->get_expr_returntype(exp_val
);
6370 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6371 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6372 chk_expr_operand_valid_float(v1
, the
, opname
);
6374 chk_expr_dynamic_part(exp_val
, true);
6376 case OPTYPE_HEX2BIT
:
6377 case OPTYPE_HEX2OCT
:
6378 case OPTYPE_HEX2STR
:
6381 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6382 v1
->set_lowerid_to_ref();
6383 tt1
=v1
->get_expr_returntype(exp_val
);
6384 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6385 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6388 case OPTYPE_HEX2INT
:
6391 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6392 v1
->set_lowerid_to_ref();
6393 tt1
=v1
->get_expr_returntype(exp_val
);
6394 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6395 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6396 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6399 case OPTYPE_INT2CHAR
:
6402 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6403 v1
->set_lowerid_to_ref();
6404 tt1
=v1
->get_expr_returntype(exp_val
);
6405 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6406 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6407 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6410 case OPTYPE_INT2UNICHAR
:
6413 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6414 v1
->set_lowerid_to_ref();
6415 tt1
=v1
->get_expr_returntype(exp_val
);
6416 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6417 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6418 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6421 case OPTYPE_INT2FLOAT
:
6422 case OPTYPE_INT2STR
:
6425 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6426 v1
->set_lowerid_to_ref();
6427 tt1
=v1
->get_expr_returntype(exp_val
);
6428 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6429 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6432 case OPTYPE_OCT2BIT
:
6433 case OPTYPE_OCT2HEX
:
6434 case OPTYPE_OCT2STR
:
6437 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6438 v1
->set_lowerid_to_ref();
6439 tt1
=v1
->get_expr_returntype(exp_val
);
6440 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6441 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6444 case OPTYPE_OCT2INT
:
6447 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6448 v1
->set_lowerid_to_ref();
6449 tt1
=v1
->get_expr_returntype(exp_val
);
6450 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6451 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6452 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6456 case OPTYPE_OCT2CHAR
:
6459 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6460 v1
->set_lowerid_to_ref();
6461 tt1
=v1
->get_expr_returntype(exp_val
);
6462 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6463 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6464 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6467 case OPTYPE_REMOVE_BOM
:
6470 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6471 v1
->set_lowerid_to_ref();
6472 tt1
=v1
->get_expr_returntype(exp_val
);
6473 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6474 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6477 case OPTYPE_GET_STRINGENCODING
:
6480 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6481 v1
->set_lowerid_to_ref();
6482 tt1
=v1
->get_expr_returntype(exp_val
);
6483 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6484 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6487 case OPTYPE_ENCODE_BASE64
:
6490 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6491 v1
->set_lowerid_to_ref();
6492 tt1
=v1
->get_expr_returntype(exp_val
);
6493 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6494 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6496 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6499 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6500 v2
->set_lowerid_to_ref();
6501 tt2
=v2
->get_expr_returntype(exp_val
);
6502 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6503 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6506 case OPTYPE_DECODE_BASE64
:
6509 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6510 v1
->set_lowerid_to_ref();
6511 tt1
=v1
->get_expr_returntype(exp_val
);
6512 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6513 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6516 case OPTYPE_UNICHAR2INT
:
6519 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6520 v1
->set_lowerid_to_ref();
6521 tt1
=v1
->get_expr_returntype(exp_val
);
6522 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6523 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6524 chk_expr_val_len1(v1
, the
, opname
);
6527 case OPTYPE_UNICHAR2CHAR
:
6530 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6531 v1
->set_lowerid_to_ref();
6532 tt1
=v1
->get_expr_returntype(exp_val
);
6533 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6534 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6535 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6538 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6541 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6542 v1
->set_lowerid_to_ref();
6543 tt1
=v1
->get_expr_returntype(exp_val
);
6544 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6545 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6547 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6550 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6551 v2
->set_lowerid_to_ref();
6552 tt2
=v2
->get_expr_returntype(exp_val
);
6553 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6554 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6557 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6560 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6561 v1
->set_lowerid_to_ref();
6562 tt1
=v1
->get_expr_returntype(exp_val
);
6563 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6564 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6566 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6569 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6570 v2
->set_lowerid_to_ref();
6571 tt2
=v2
->get_expr_returntype(exp_val
);
6572 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6573 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6576 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
6577 chk_expr_operand_encode(refch
, exp_val
);
6578 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6581 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6582 v2
->set_lowerid_to_ref();
6583 tt2
=v2
->get_expr_returntype(exp_val
);
6584 chk_expr_operandtype_charstr(tt2
, second
, opname
, v2
);
6585 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6588 case OPTYPE_DECVALUE_UNICHAR
:
6589 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR
);
6590 v3
=u
.expr
.v3
? u
.expr
.v3
: 0;
6593 Error_Context
cntxt(this, "In the thrid operand of operation `%s'", opname
);
6594 v3
->set_lowerid_to_ref();
6595 tt3
=v3
->get_expr_returntype(exp_val
);
6596 chk_expr_operandtype_charstr(tt3
, third
, opname
, v3
);
6597 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6600 case OPTYPE_ADD
: // v1 v2
6601 case OPTYPE_SUBTRACT
:
6602 case OPTYPE_MULTIPLY
:
6606 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6607 v1
->set_lowerid_to_ref();
6608 tt1
=v1
->get_expr_returntype(exp_val
);
6609 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6610 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6611 chk_expr_operand_valid_float(v1
, first
, opname
);
6615 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6616 v2
->set_lowerid_to_ref();
6617 tt2
=v2
->get_expr_returntype(exp_val
);
6618 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6619 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6620 chk_expr_operand_valid_float(v2
, second
, opname
);
6621 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6622 chk_expr_val_int_float_not0(v2
, second
, opname
);
6624 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6630 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6631 v1
->set_lowerid_to_ref();
6632 tt1
=v1
->get_expr_returntype(exp_val
);
6633 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6634 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6638 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6639 v2
->set_lowerid_to_ref();
6640 tt2
=v2
->get_expr_returntype(exp_val
);
6641 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6642 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6643 chk_expr_val_int_float_not0(v2
, right
, opname
);
6646 case OPTYPE_CONCAT
: {
6649 v1
->set_lowerid_to_ref();
6650 v2
->set_lowerid_to_ref();
6651 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6653 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6654 tt1
=v1
->get_expr_returntype(exp_val
);
6655 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6656 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6659 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6660 tt2
=v2
->get_expr_returntype(exp_val
);
6661 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6662 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6664 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6665 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6666 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6667 } else { // other list types
6668 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6669 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6671 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6672 set_valuetype(V_ERROR
);
6675 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6676 v1_gov
->chk_this_value_ref(v1
);
6677 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6678 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6679 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6683 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6684 set_valuetype(V_ERROR
);
6687 // for recof/setof literals set the type from v1
6689 v2
->set_my_governor(v1_gov
);
6692 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6694 v2_gov
->chk_this_value_ref(v2
);
6695 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6696 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6697 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6698 if (valuetype
== V_ERROR
) return;
6699 // 7.1.2 says that we shouldn't allow type compatibility.
6700 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6701 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6702 error("The operands of operation `%s' should be of compatible "
6703 "types", get_opname());
6712 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6714 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6716 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6719 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6721 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6722 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6723 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6724 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6725 * "a == not b" is not allowed. (HL69107)
6726 * The various *Expressions implement operator precedence in the std.
6727 * Titan's parser has only one Expression and relies on Bison
6728 * for operator precedence. The check below brings Titan in line
6729 * with the standard by explicitly making "a == not b" an error */
6730 if (v2
->get_valuetype() == V_EXPR
6731 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6732 error("The operation `%s' is not allowed to be "
6733 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6734 set_valuetype(V_ERROR
);
6744 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6746 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6748 tt1
=v1
->get_expr_returntype(exp_val
);
6749 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6750 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6753 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6755 tt2
=v2
->get_expr_returntype(exp_val
);
6756 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6757 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6765 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6767 v1
->set_lowerid_to_ref();
6768 tt1
=v1
->get_expr_returntype(exp_val
);
6769 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6770 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6774 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6776 v2
->set_lowerid_to_ref();
6777 tt2
=v2
->get_expr_returntype(exp_val
);
6778 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6779 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6787 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6789 v1
->set_lowerid_to_ref();
6790 tt1
=v1
->get_expr_returntype(exp_val
);
6791 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6792 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6796 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6798 v2
->set_lowerid_to_ref();
6799 tt2
=v2
->get_expr_returntype(exp_val
);
6800 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6801 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6803 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6804 chk_expr_operands_str_samelen();
6810 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6811 v1
->set_lowerid_to_ref();
6812 tt1
=v1
->get_expr_returntype(exp_val
);
6813 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6814 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6818 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6819 v2
->set_lowerid_to_ref();
6820 tt2
=v2
->get_expr_returntype(exp_val
);
6821 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6822 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6823 chk_expr_val_large_int(v2
, right
, opname
);
6829 v1
->set_lowerid_to_ref();
6830 if (v1
->is_string_type(exp_val
)) {
6831 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6832 tt1
=v1
->get_expr_returntype(exp_val
);
6833 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6834 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6835 } else { // other list types
6836 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6837 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6838 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6840 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6841 v1_gov
->chk_this_value_ref(v1
);
6842 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6843 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6844 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6849 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6850 v2
->set_lowerid_to_ref();
6851 tt2
=v2
->get_expr_returntype(exp_val
);
6852 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6853 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6854 chk_expr_val_large_int(v2
, right
, opname
);
6857 case OPTYPE_INT2BIT
:
6858 case OPTYPE_INT2HEX
:
6859 case OPTYPE_INT2OCT
:
6862 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6863 v1
->set_lowerid_to_ref();
6864 tt1
=v1
->get_expr_returntype(exp_val
);
6865 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6866 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6867 chk_expr_val_int_pos0(v1
, first
, opname
);
6871 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6872 v2
->set_lowerid_to_ref();
6873 tt2
=v2
->get_expr_returntype(exp_val
);
6874 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6875 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6876 chk_expr_val_int_pos0(v2
, second
, opname
);
6878 chk_expr_operands_int2binstr();
6881 chk_expr_operands_decode(OPTYPE_DECODE
);
6885 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6886 Type::expected_value_t ti_exp_val
= exp_val
;
6887 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6888 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6889 if (!governor
) return;
6890 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6891 if (valuetype
!=V_ERROR
)
6892 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6893 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6897 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6898 v2
->set_lowerid_to_ref();
6899 tt2
=v2
->get_expr_returntype(exp_val
);
6900 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6901 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6902 chk_expr_val_int_pos0(v2
, second
, opname
);
6906 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6907 v3
->set_lowerid_to_ref();
6908 tt3
=v3
->get_expr_returntype(exp_val
);
6909 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6910 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6911 chk_expr_val_int_pos0(v3
, third
, opname
);
6913 chk_expr_operands_substr();
6915 case OPTYPE_REGEXP
: {
6916 Type::expected_value_t ti_exp_val
= exp_val
;
6917 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6919 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6920 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6921 if (!governor
) return;
6922 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6923 if (valuetype
!=V_ERROR
) {
6924 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6925 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6926 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6930 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6931 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6932 if (!governor
) return;
6933 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6934 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6935 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6939 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6940 v3
->set_lowerid_to_ref();
6941 tt3
=v3
->get_expr_returntype(exp_val
);
6942 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6943 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6944 chk_expr_val_int_pos0(v3
, third
, opname
);
6946 chk_expr_operands_regexp();
6948 case OPTYPE_ISCHOSEN
:
6949 // do nothing: the operand is erroneous
6950 // the error was already reported in chk_expr_ref_ischosen()
6952 case OPTYPE_ISCHOSEN_V
: // v1 i2
6953 case OPTYPE_ISCHOSEN_T
: // t1 i2
6954 chk_expr_operands_ischosen(refch
, exp_val
);
6956 case OPTYPE_VALUEOF
: { // ti1
6957 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6958 exp_val
= Type::EXPECTED_TEMPLATE
;
6959 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6960 Type
*governor
= my_governor
;
6961 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6962 if (!governor
) return;
6963 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6964 if (valuetype
== V_ERROR
) return;
6965 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6967 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6968 case OPTYPE_ISBOUND
: {
6969 Template
*templ
= u
.expr
.ti1
->get_Template();
6970 switch (templ
->get_templatetype()) {
6971 case Template::TEMPLATE_REFD
:
6972 templ
->get_reference()->setUsedInIsbound();
6974 case Template::SPECIFIC_VALUE
: {
6975 Value
*value
= templ
->get_specific_value();
6976 if (Value::V_REFD
== value
->get_valuetype()) {
6977 value
->get_reference()->setUsedInIsbound();
6985 case OPTYPE_ISVALUE
: {// ti1
6986 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6987 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6988 exp_val
= Type::EXPECTED_TEMPLATE
;
6989 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6990 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6991 if (!governor
) return;
6992 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
6993 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6995 case OPTYPE_SIZEOF
: // ti1
6996 /* this checking is too complex, do the checking during eval... */
6998 case OPTYPE_LENGTHOF
: { // ti1
6999 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7000 exp_val
= Type::EXPECTED_TEMPLATE
;
7001 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7002 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7003 if (!governor
) return;
7004 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
7005 if (valuetype
== V_ERROR
) return;
7006 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7008 case OPTYPE_MATCH
: // v1 t2
7009 chk_expr_operands_match(exp_val
);
7011 case OPTYPE_UNDEF_RUNNING
: // r1
7012 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
7014 case OPTYPE_COMP_ALIVE
:
7015 case OPTYPE_COMP_RUNNING
: //v1
7016 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
7017 chk_expr_dynamic_part(exp_val
, false);
7019 case OPTYPE_TMR_READ
: // r1
7020 case OPTYPE_TMR_RUNNING
: // r1
7021 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
7022 chk_expr_dynamic_part(exp_val
, true);
7024 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
7025 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
7026 chk_expr_dynamic_part(exp_val
, true, false, false);
7028 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7029 chk_expr_operand_comptyperef_create();
7032 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7033 v2
->set_lowerid_to_ref();
7034 tt2
=v2
->get_expr_returntype(exp_val
);
7035 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
7036 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7040 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
7041 v3
->set_lowerid_to_ref();
7042 tt3
=v3
->get_expr_returntype(exp_val
);
7043 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
7044 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7046 chk_expr_dynamic_part(exp_val
, false);
7048 case OPTYPE_ACTIVATE
: // r1 // altstep
7049 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
7050 chk_expr_dynamic_part(exp_val
, true);
7052 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
7053 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7054 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
7056 delete u
.expr
.t_list2
;
7057 u
.expr
.ap_list2
= parlist
;
7058 chk_expr_dynamic_part(exp_val
, true);
7060 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
7061 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7062 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
7063 u
.expr
.v3
, the
, opname
);
7064 delete u
.expr
.t_list2
;
7065 u
.expr
.ap_list2
= parlist
;
7066 chk_expr_dynamic_part(exp_val
, true);
7069 error("Built-in function `%s' is not yet supported", opname
);
7070 set_valuetype(V_ERROR
);
7072 case OPTYPE_REPLACE
: {
7073 Type::expected_value_t ti_exp_val
= exp_val
;
7074 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7075 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7077 Error_Context
cntxt(this, "In the first operand of operation `%s'",
7079 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7080 if (!governor
) return;
7081 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7082 if (valuetype
!= V_ERROR
)
7083 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7084 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
7088 Error_Context
cntxt(this, "In the second operand of operation `%s'",
7090 v2
->set_lowerid_to_ref();
7091 tt2
= v2
->get_expr_returntype(exp_val
);
7092 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
7093 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7094 chk_expr_val_int_pos0(v2
, second
, opname
);
7098 Error_Context
cntxt(this, "In the third operand of operation `%s'",
7100 v3
->set_lowerid_to_ref();
7101 tt3
= v3
->get_expr_returntype(exp_val
);
7102 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
7103 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7104 chk_expr_val_int_pos0(v3
, third
, opname
);
7107 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
7109 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
7110 if (!governor
) return;
7111 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
7112 if (valuetype
!= V_ERROR
)
7113 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
7114 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
7116 chk_expr_operands_replace();
7118 case OPTYPE_LOG2STR
: {
7119 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7120 u
.expr
.logargs
->chk();
7121 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
7123 case OPTYPE_TTCN2STRING
: {
7124 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
7125 Type::expected_value_t ti_exp_val
= exp_val
;
7126 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7127 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7128 if (!governor
) return;
7129 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7132 FATAL_ERROR("chk_expr_operands()");
7136 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7137 // the result of evaluating the expression. E.g. V_BOOL for
7139 void Value::evaluate_value(ReferenceChain
*refch
,
7140 Type::expected_value_t exp_val
)
7142 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
7143 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
7145 u
.expr
.state
=EXPR_CHECKING
;
7147 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
7148 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
7149 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
7151 if(valuetype
==V_ERROR
) return;
7152 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
7153 u
.expr
.state
=EXPR_CHECKED
;
7154 set_valuetype(V_ERROR
);
7158 u
.expr
.state
=EXPR_CHECKED
;
7160 Value
*v1
, *v2
, *v3
, *v4
;
7161 switch(u
.expr
.v_optype
) {
7162 case OPTYPE_RND
: // -
7163 case OPTYPE_COMP_NULL
: // the only foldable in this group
7164 case OPTYPE_COMP_MTC
:
7165 case OPTYPE_COMP_SYSTEM
:
7166 case OPTYPE_COMP_SELF
:
7167 case OPTYPE_COMP_RUNNING_ANY
:
7168 case OPTYPE_COMP_RUNNING_ALL
:
7169 case OPTYPE_COMP_ALIVE_ANY
:
7170 case OPTYPE_COMP_ALIVE_ALL
:
7171 case OPTYPE_TMR_RUNNING_ANY
:
7172 case OPTYPE_GETVERDICT
:
7173 case OPTYPE_PROF_RUNNING
:
7174 case OPTYPE_RNDWITHVAL
: // v1
7175 case OPTYPE_COMP_RUNNING
: // v1
7176 case OPTYPE_COMP_ALIVE
:
7177 case OPTYPE_TMR_READ
:
7178 case OPTYPE_TMR_RUNNING
:
7179 case OPTYPE_ACTIVATE
:
7180 case OPTYPE_ACTIVATE_REFD
:
7181 case OPTYPE_EXECUTE
: // r1 [v2]
7182 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7183 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7184 case OPTYPE_MATCH
: // v1 t2
7185 case OPTYPE_ISCHOSEN_T
:
7186 case OPTYPE_LOG2STR
:
7189 case OPTYPE_ISBOUND
:
7190 case OPTYPE_ISPRESENT
:
7191 case OPTYPE_TTCN2STRING
:
7192 case OPTYPE_UNICHAR2OCT
:
7193 case OPTYPE_OCT2UNICHAR
:
7194 case OPTYPE_ENCODE_BASE64
:
7195 case OPTYPE_DECODE_BASE64
:
7196 case OPTYPE_ENCVALUE_UNICHAR
:
7197 case OPTYPE_DECVALUE_UNICHAR
:
7199 case OPTYPE_TESTCASENAME
: { // -
7200 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7201 Ttcn::StatementBlock
*my_sb
=
7202 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7204 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7205 if (!my_def
) { // In control part.
7206 set_val_str(new string(""));
7208 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7209 set_val_str(new string(my_def
->get_id().get_dispname()));
7213 case OPTYPE_UNARYPLUS
: // v1
7216 copy_and_destroy(v1
);
7218 case OPTYPE_UNARYMINUS
:
7219 if (is_unfoldable()) break;
7220 v1
= u
.expr
.v1
->get_value_refd_last();
7221 switch (v1
->valuetype
) {
7223 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7224 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7230 ttcn3float r
= v1
->get_val_Real();
7236 FATAL_ERROR("Value::evaluate_value()");
7240 if(is_unfoldable()) break;
7241 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7246 case OPTYPE_NOT4B
: {
7247 if(is_unfoldable()) break;
7248 v1
=u
.expr
.v1
->get_value_refd_last();
7249 const string
& s
= v1
->get_val_str();
7250 valuetype_t vt
=v1
->valuetype
;
7253 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7255 case OPTYPE_BIT2HEX
: {
7256 if(is_unfoldable()) break;
7257 v1
=u
.expr
.v1
->get_value_refd_last();
7258 const string
& s
= v1
->get_val_str();
7261 set_val_str(bit2hex(s
));
7263 case OPTYPE_BIT2OCT
: {
7264 if(is_unfoldable()) break;
7265 v1
=u
.expr
.v1
->get_value_refd_last();
7266 const string
& s
= v1
->get_val_str();
7269 set_val_str(bit2oct(s
));
7271 case OPTYPE_BIT2STR
:
7272 case OPTYPE_HEX2STR
:
7273 case OPTYPE_OCT2STR
: {
7274 if(is_unfoldable()) break;
7275 v1
=u
.expr
.v1
->get_value_refd_last();
7276 const string
& s
= v1
->get_val_str();
7279 set_val_str(new string(s
));
7281 case OPTYPE_BIT2INT
: {
7282 if (is_unfoldable()) break;
7283 v1
= u
.expr
.v1
->get_value_refd_last();
7284 const string
& s
= v1
->get_val_str();
7287 u
.val_Int
= bit2int(s
);
7289 case OPTYPE_CHAR2INT
: {
7290 if (is_unfoldable()) break;
7291 v1
= u
.expr
.v1
->get_value_refd_last();
7292 char c
= v1
->get_val_str()[0];
7295 u
.val_Int
= new int_val_t((Int
)c
);
7297 case OPTYPE_CHAR2OCT
: {
7298 if(is_unfoldable()) break;
7299 v1
=u
.expr
.v1
->get_value_refd_last();
7300 const string
& s
= v1
->get_val_str();
7303 set_val_str(char2oct(s
));
7305 case OPTYPE_STR2INT
: {
7306 if (is_unfoldable()) break;
7307 v1
= u
.expr
.v1
->get_value_refd_last();
7308 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7312 /** \todo hiba eseten lenyeli... */
7314 case OPTYPE_STR2FLOAT
: {
7315 if(is_unfoldable()) break;
7316 v1
=u
.expr
.v1
->get_value_refd_last();
7317 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7321 /** \todo hiba eseten lenyeli... */
7323 case OPTYPE_STR2BIT
: {
7324 if(is_unfoldable()) break;
7325 v1
=u
.expr
.v1
->get_value_refd_last();
7326 const string
& s
= v1
->get_val_str();
7329 set_val_str(new string(s
));
7331 case OPTYPE_STR2HEX
:
7332 case OPTYPE_OCT2HEX
: {
7333 if(is_unfoldable()) break;
7334 v1
=u
.expr
.v1
->get_value_refd_last();
7335 const string
& s
= v1
->get_val_str();
7338 set_val_str(to_uppercase(s
));
7340 case OPTYPE_STR2OCT
: {
7341 if(is_unfoldable()) break;
7342 v1
=u
.expr
.v1
->get_value_refd_last();
7343 const string
& s
= v1
->get_val_str();
7346 set_val_str(to_uppercase(s
));
7348 case OPTYPE_FLOAT2INT
: {
7349 if (is_unfoldable()) break;
7350 v1
= u
.expr
.v1
->get_value_refd_last();
7351 ttcn3float r
= v1
->get_val_Real();
7354 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7356 case OPTYPE_FLOAT2STR
: {
7357 if(is_unfoldable()) break;
7358 v1
=u
.expr
.v1
->get_value_refd_last();
7359 ttcn3float r
=v1
->get_val_Real();
7362 set_val_str(float2str(r
));
7364 case OPTYPE_HEX2BIT
:
7365 case OPTYPE_OCT2BIT
: {
7366 if(is_unfoldable()) break;
7367 v1
=u
.expr
.v1
->get_value_refd_last();
7368 const string
& s
= v1
->get_val_str();
7371 set_val_str(hex2bit(s
));
7373 case OPTYPE_HEX2INT
:
7374 case OPTYPE_OCT2INT
: {
7375 if(is_unfoldable()) break;
7376 v1
=u
.expr
.v1
->get_value_refd_last();
7377 const string
& s
= v1
->get_val_str();
7380 u
.val_Int
=hex2int(s
);
7382 case OPTYPE_HEX2OCT
: {
7383 if(is_unfoldable()) break;
7384 v1
=u
.expr
.v1
->get_value_refd_last();
7385 const string
& s
= v1
->get_val_str();
7388 set_val_str(hex2oct(s
));
7390 case OPTYPE_INT2CHAR
: {
7391 if (is_unfoldable()) break;
7392 v1
= u
.expr
.v1
->get_value_refd_last();
7393 const int_val_t
*c_int
= v1
->get_val_Int();
7394 char c
= static_cast<char>(c_int
->get_val());
7397 set_val_str(new string(1, &c
));
7399 case OPTYPE_INT2UNICHAR
: {
7400 if (is_unfoldable()) break;
7401 v1
= u
.expr
.v1
->get_value_refd_last();
7402 const int_val_t
*i_int
= v1
->get_val_Int();
7403 Int i
= i_int
->get_val();
7406 set_val_ustr(int2unichar(i
));
7407 u
.ustr
.convert_str
= false;
7409 case OPTYPE_INT2FLOAT
: {
7410 if (is_unfoldable()) break;
7411 v1
= u
.expr
.v1
->get_value_refd_last();
7412 const int_val_t
*i_int
= v1
->get_val_Int();
7413 Real i_int_real
= i_int
->to_real();
7416 u
.val_Real
= i_int_real
;
7418 case OPTYPE_INT2STR
: {
7419 if (is_unfoldable()) break;
7420 v1
= u
.expr
.v1
->get_value_refd_last();
7421 const int_val_t
*i_int
= v1
->get_val_Int();
7422 string
*i_int_str
= new string(i_int
->t_str());
7425 set_val_str(i_int_str
);
7427 case OPTYPE_OCT2CHAR
: {
7428 if(is_unfoldable()) break;
7429 v1
=u
.expr
.v1
->get_value_refd_last();
7430 const string
& s
= v1
->get_val_str();
7433 set_val_str(oct2char(s
));
7435 case OPTYPE_GET_STRINGENCODING
: {
7436 if(is_unfoldable()) break;
7437 v1
= u
.expr
.v1
->get_value_refd_last();
7438 const string
& s1
= v1
->get_val_str();
7441 set_val_str(get_stringencoding(s1
));
7443 case OPTYPE_REMOVE_BOM
: {
7444 if(is_unfoldable()) break;
7445 v1
= u
.expr
.v1
->get_value_refd_last();
7446 const string
& s1
= v1
->get_val_str();
7449 set_val_str(remove_bom(s1
));
7451 case OPTYPE_ENUM2INT
: {
7452 if(is_unfoldable()) break;
7453 v1
=u
.expr
.v1
->get_value_refd_last();
7454 Type
* enum_type
= v1
->get_my_governor();
7455 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7458 u
.val_Int
= new int_val_t(enum_val
);
7460 case OPTYPE_UNICHAR2INT
:
7461 if (is_unfoldable()) {
7462 // replace the operation with char2int() if the operand is a charstring
7463 // value to avoid its unnecessary conversion to universal charstring
7464 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7465 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7467 v1
=u
.expr
.v1
->get_value_refd_last();
7468 const ustring
& s
= v1
->get_val_ustr();
7471 u
.val_Int
=new int_val_t(unichar2int(s
));
7474 case OPTYPE_UNICHAR2CHAR
:
7476 if (is_unfoldable()) {
7477 // replace the operation with its operand if it is a charstring
7478 // value to avoid its unnecessary conversion to universal charstring
7479 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7481 copy_and_destroy(v1
);
7484 v1
= v1
->get_value_refd_last();
7485 const ustring
& s
= v1
->get_val_ustr();
7488 set_val_str(new string(s
));
7491 case OPTYPE_MULTIPLY
: { // v1 v2
7492 if (!is_unfoldable()) goto eval_arithmetic
;
7493 v1
= u
.expr
.v1
->get_value_refd_last();
7494 v2
= u
.expr
.v2
->get_value_refd_last();
7495 if (v1
->is_unfoldable()) v1
= v2
;
7496 if (v1
->is_unfoldable()) break;
7497 switch(v1
->valuetype
) {
7499 if (*v1
->get_val_Int() != 0) break;
7502 u
.val_Int
= new int_val_t((Int
)0);
7505 if (v1
->get_val_Real() != 0.0) break;
7511 FATAL_ERROR("Value::evaluate_value()");
7514 case OPTYPE_ADD
: // v1 v2
7515 case OPTYPE_SUBTRACT
:
7520 if(is_unfoldable()) break;
7521 v1
=u
.expr
.v1
->get_value_refd_last();
7522 v2
=u
.expr
.v2
->get_value_refd_last();
7523 operationtype_t ot
=u
.expr
.v_optype
;
7524 switch (v1
->valuetype
) {
7526 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7527 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7532 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7534 case OPTYPE_SUBTRACT
:
7535 u
.val_Int
= new int_val_t(*i1
- *i2
);
7537 case OPTYPE_MULTIPLY
:
7538 u
.val_Int
= new int_val_t(*i1
* *i2
);
7541 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7544 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7547 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7550 FATAL_ERROR("Value::evaluate_value()");
7556 ttcn3float r1
=v1
->get_val_Real();
7557 ttcn3float r2
=v2
->get_val_Real();
7564 case OPTYPE_SUBTRACT
:
7567 case OPTYPE_MULTIPLY
:
7574 FATAL_ERROR("Value::evaluate_value()");
7578 FATAL_ERROR("Value::evaluate_value()");
7581 case OPTYPE_CONCAT
: {
7582 if(is_unfoldable()) break;
7583 v1
=u
.expr
.v1
->get_value_refd_last();
7584 v2
=u
.expr
.v2
->get_value_refd_last();
7585 valuetype_t vt
= v1
->valuetype
;
7586 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7587 const ustring
& s1
= v1
->get_val_ustr();
7588 const ustring
& s2
= v2
->get_val_ustr();
7591 set_val_ustr(new ustring(s1
+ s2
));
7592 u
.ustr
.convert_str
= false;
7594 const string
& s1
= v1
->get_val_str();
7595 const string
& s2
= v2
->get_val_str();
7598 set_val_str(new string(s1
+ s2
));
7602 if(is_unfoldable()) break;
7603 v1
=u
.expr
.v1
->get_value_refd_last();
7604 v2
=u
.expr
.v2
->get_value_refd_last();
7611 if(is_unfoldable()) break;
7612 v1
=u
.expr
.v1
->get_value_refd_last();
7613 v2
=u
.expr
.v2
->get_value_refd_last();
7620 if(is_unfoldable()) break;
7621 v1
=u
.expr
.v1
->get_value_refd_last();
7622 v2
=u
.expr
.v2
->get_value_refd_last();
7629 if(is_unfoldable()) break;
7630 v1
=u
.expr
.v1
->get_value_refd_last();
7631 v2
=u
.expr
.v2
->get_value_refd_last();
7638 if(is_unfoldable()) break;
7639 v1
=u
.expr
.v1
->get_value_refd_last();
7640 v2
=u
.expr
.v2
->get_value_refd_last();
7647 if(is_unfoldable()) break;
7648 v1
=u
.expr
.v1
->get_value_refd_last();
7649 v2
=u
.expr
.v2
->get_value_refd_last();
7656 v1
= u
.expr
.v1
->get_value_refd_last();
7657 if (v1
->valuetype
== V_BOOL
) {
7658 if (v1
->get_val_bool()) {
7659 // the left operand is a literal "true"
7660 // substitute the expression with the right operand
7663 copy_and_destroy(v2
);
7665 // the left operand is a literal "false"
7666 // the result must be false regardless the right operand
7667 // because of the short circuit evaluation rule
7673 // we must keep the left operand because of the potential side effects
7674 // the right operand can only be eliminated if it is a literal "true"
7675 v2
= u
.expr
.v2
->get_value_refd_last();
7676 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7679 copy_and_destroy(v1
);
7684 v1
= u
.expr
.v1
->get_value_refd_last();
7685 if (v1
->valuetype
== V_BOOL
) {
7686 if (v1
->get_val_bool()) {
7687 // the left operand is a literal "true"
7688 // the result must be true regardless the right operand
7689 // because of the short circuit evaluation rule
7694 // the left operand is a literal "false"
7695 // substitute the expression with the right operand
7698 copy_and_destroy(v2
);
7701 // we must keep the left operand because of the potential side effects
7702 // the right operand can only be eliminated if it is a literal "false"
7703 v2
= u
.expr
.v2
->get_value_refd_last();
7704 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7707 copy_and_destroy(v1
);
7712 if(is_unfoldable()) break;
7713 v1
=u
.expr
.v1
->get_value_refd_last();
7714 v2
=u
.expr
.v2
->get_value_refd_last();
7715 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7720 case OPTYPE_AND4B
: {
7721 if(is_unfoldable()) break;
7722 v1
=u
.expr
.v1
->get_value_refd_last();
7723 v2
=u
.expr
.v2
->get_value_refd_last();
7724 valuetype_t vt
=v1
->valuetype
;
7725 const string
& s1
= v1
->get_val_str();
7726 const string
& s2
= v2
->get_val_str();
7729 set_val_str(and4b(s1
, s2
));
7732 if(is_unfoldable()) break;
7733 v1
=u
.expr
.v1
->get_value_refd_last();
7734 v2
=u
.expr
.v2
->get_value_refd_last();
7735 valuetype_t vt
=v1
->valuetype
;
7736 const string
& s1
= v1
->get_val_str();
7737 const string
& s2
= v2
->get_val_str();
7740 set_val_str(or4b(s1
, s2
));
7742 case OPTYPE_XOR4B
: {
7743 if(is_unfoldable()) break;
7744 v1
=u
.expr
.v1
->get_value_refd_last();
7745 v2
=u
.expr
.v2
->get_value_refd_last();
7746 valuetype_t vt
=v1
->valuetype
;
7747 const string
& s1
= v1
->get_val_str();
7748 const string
& s2
= v2
->get_val_str();
7751 set_val_str(xor4b(s1
, s2
));
7754 if(is_unfoldable()) break;
7755 v1
=u
.expr
.v1
->get_value_refd_last();
7756 v2
=u
.expr
.v2
->get_value_refd_last();
7757 valuetype_t vt
=v1
->valuetype
;
7758 const string
& s
= v1
->get_val_str();
7759 const int_val_t
*i_int
= v2
->get_val_Int();
7760 Int i
=i_int
->get_val();
7761 if(vt
==V_OSTR
) i
*=2;
7764 set_val_str(shift_left(s
, i
));
7767 if(is_unfoldable()) break;
7768 v1
=u
.expr
.v1
->get_value_refd_last();
7769 v2
=u
.expr
.v2
->get_value_refd_last();
7770 valuetype_t vt
=v1
->valuetype
;
7771 const string
& s
= v1
->get_val_str();
7772 const int_val_t
*i_int
= v2
->get_val_Int();
7773 Int i
=i_int
->get_val();
7774 if(vt
==V_OSTR
) i
*=2;
7777 set_val_str(shift_right(s
, i
));
7780 if(is_unfoldable()) break;
7781 v1
=u
.expr
.v1
->get_value_refd_last();
7782 v2
=u
.expr
.v2
->get_value_refd_last();
7783 valuetype_t vt
=v1
->valuetype
;
7784 const int_val_t
*i_int
=v2
->get_val_Int();
7785 Int i
=i_int
->get_val();
7787 const ustring
& s
= v1
->get_val_ustr();
7790 set_val_ustr(rotate_left(s
, i
));
7791 u
.ustr
.convert_str
= false;
7794 if(vt
==V_OSTR
) i
*=2;
7795 const string
& s
= v1
->get_val_str();
7798 set_val_str(rotate_left(s
, i
));
7802 if(is_unfoldable()) break;
7803 v1
=u
.expr
.v1
->get_value_refd_last();
7804 v2
=u
.expr
.v2
->get_value_refd_last();
7805 valuetype_t vt
=v1
->valuetype
;
7806 const int_val_t
*i_int
=v2
->get_val_Int();
7807 Int i
=i_int
->get_val();
7809 const ustring
& s
= v1
->get_val_ustr();
7812 set_val_ustr(rotate_right(s
, i
));
7813 u
.ustr
.convert_str
= false;
7816 if(vt
==V_OSTR
) i
*=2;
7817 const string
& s
= v1
->get_val_str();
7820 set_val_str(rotate_right(s
, i
));
7823 case OPTYPE_INT2BIT
: {
7824 if (is_unfoldable()) break;
7825 v1
= u
.expr
.v1
->get_value_refd_last();
7826 v2
= u
.expr
.v2
->get_value_refd_last();
7827 const int_val_t
*i1_int
= v1
->get_val_Int();
7828 const int_val_t
*i2_int
= v2
->get_val_Int();
7829 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7834 case OPTYPE_INT2HEX
: {
7835 if (is_unfoldable()) break;
7836 v1
= u
.expr
.v1
->get_value_refd_last();
7837 v2
= u
.expr
.v2
->get_value_refd_last();
7838 const int_val_t
*i1_int
= v1
->get_val_Int();
7839 const int_val_t
*i2_int
= v2
->get_val_Int();
7840 // Do it before the `clean_up'. i2_int is already checked.
7841 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7846 case OPTYPE_INT2OCT
: {
7847 if (is_unfoldable()) break;
7848 v1
= u
.expr
.v1
->get_value_refd_last();
7849 v2
= u
.expr
.v2
->get_value_refd_last();
7850 const int_val_t
i1_int(*v1
->get_val_Int());
7851 // `v2' is a native integer.
7852 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7855 set_val_str(int2hex(i1_int
, i2_int
));
7857 case OPTYPE_SUBSTR
: {
7858 if(is_unfoldable()) break;
7859 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7860 v2
=u
.expr
.v2
->get_value_refd_last();
7861 v3
=u
.expr
.v3
->get_value_refd_last();
7862 valuetype_t vt
=v1
->valuetype
;
7863 const int_val_t
*i2_int
=v2
->get_val_Int();
7864 const int_val_t
*i3_int
=v3
->get_val_Int();
7865 Int i2
=i2_int
->get_val();
7866 Int i3
=i3_int
->get_val();
7868 const ustring
& s
= v1
->get_val_ustr();
7871 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7872 u
.ustr
.convert_str
= false;
7879 const string
& s
= v1
->get_val_str();
7882 set_val_str(new string(s
.substr(i2
, i3
)));
7885 case OPTYPE_REPLACE
: {
7886 if(is_unfoldable()) break;
7887 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7888 v2
=u
.expr
.v2
->get_value_refd_last();
7889 v3
=u
.expr
.v3
->get_value_refd_last();
7890 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7891 valuetype_t vt
=v1
->valuetype
;
7892 const int_val_t
*i2_int
=v2
->get_val_Int();
7893 const int_val_t
*i3_int
=v3
->get_val_Int();
7894 Int i2
=i2_int
->get_val();
7895 Int i3
=i3_int
->get_val();
7898 string
*s1
= new string(v1
->get_val_str());
7899 const string
& s2
= v4
->get_val_str();
7902 s1
->replace(i2
, i3
, s2
);
7906 string
*s1
= new string(v1
->get_val_str());
7907 const string
& s2
= v4
->get_val_str();
7910 s1
->replace(i2
, i3
, s2
);
7916 string
*s1
= new string(v1
->get_val_str());
7917 const string
& s2
= v4
->get_val_str();
7920 s1
->replace(i2
, i3
, s2
);
7924 string
*s1
= new string(v1
->get_val_str());
7925 const string
& s2
= v4
->get_val_str();
7928 s1
->replace(i2
, i3
, s2
);
7932 ustring
*s1
= new ustring(v1
->get_val_ustr());
7933 const ustring
& s2
= v4
->get_val_ustr();
7936 s1
->replace(i2
, i3
, s2
);
7938 u
.ustr
.convert_str
= false;
7941 FATAL_ERROR("Value::evaluate_value()");
7944 case OPTYPE_REGEXP
: {
7945 if (is_unfoldable()) break;
7946 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7947 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7948 v3
=u
.expr
.v3
->get_value_refd_last();
7949 const int_val_t
*i3_int
= v3
->get_val_Int();
7950 Int i3
= i3_int
->get_val();
7951 if (v1
->valuetype
== V_CSTR
) {
7952 const string
& s1
= v1
->get_val_str();
7953 const string
& s2
= v2
->get_val_str();
7954 string
*result
= regexp(s1
, s2
, i3
);
7957 set_val_str(result
);
7958 } if (v1
->valuetype
== V_USTR
) {
7959 const ustring
& s1
= v1
->get_val_ustr();
7960 const ustring
& s2
= v2
->get_val_ustr();
7961 ustring
*result
= regexp(s1
, s2
, i3
);
7964 set_val_ustr(result
);
7965 u
.ustr
.convert_str
= false;
7968 case OPTYPE_LENGTHOF
:{
7969 if(is_unfoldable()) break;
7970 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7971 ->get_value_refd_last();
7973 if(v1
->is_string_type(exp_val
)) {
7974 i
=v1
->get_val_strlen();
7975 } else { // v1 is be seq/set of or array
7976 switch (v1
->valuetype
) {
7980 if(v1
->u
.val_vs
->is_indexed())
7981 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7982 else { i
= v1
->u
.val_vs
->get_nof_vs();}
7985 FATAL_ERROR("Value::evaluate_value()");
7990 u
.val_Int
=new int_val_t(i
);
7992 case OPTYPE_SIZEOF
: {
7993 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
7997 u
.val_Int
=new int_val_t(i
);
8000 case OPTYPE_ISVALUE
: {
8001 if(is_unfoldable()) break;
8002 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
8003 && u
.expr
.ti1
->get_Template()->is_Value();
8005 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
8006 is_singleval
= other_val
->evaluate_isvalue(false);
8007 // is_singleval now contains the compile-time result of isvalue
8012 u
.val_bool
= is_singleval
;
8014 case OPTYPE_ISCHOSEN_V
: {
8015 if (is_unfoldable()) break;
8016 v1
= u
.expr
.v1
->get_value_refd_last();
8017 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
8022 case OPTYPE_VALUEOF
: // ti1
8023 if (!u
.expr
.ti1
->get_DerivedRef() &&
8024 u
.expr
.ti1
->get_Template()->is_Value() &&
8025 !u
.expr
.ti1
->get_Type()) {
8026 // FIXME actually if the template instance has a type
8027 // it might still be foldable.
8028 // the argument is a single specific value
8029 v1
= u
.expr
.ti1
->get_Template()->get_Value();
8030 Type
*governor
= my_governor
;
8031 if (governor
== NULL
) {
8032 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
8033 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
8035 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
8036 if (governor
== NULL
)
8037 FATAL_ERROR("Value::evaluate_value()");
8039 valuetype
= v1
->valuetype
;
8041 set_my_governor(governor
);
8042 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
8043 u
.ref
.refd_last
= this;
8044 v1
->valuetype
= V_ERROR
;
8048 case OPTYPE_UNDEF_RUNNING
:
8050 FATAL_ERROR("Value::evaluate_value()");
8054 bool Value::evaluate_isvalue(bool from_sequence
)
8056 switch (valuetype
) {
8058 // Omit is not a value unless a member of a sequence or set
8059 return from_sequence
;
8062 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8063 case V_BOOL
: /**< boolean */
8064 case V_NAMEDINT
: /**< integer / named number */
8065 case V_NAMEDBITS
: /**< named bits (identifiers) */
8066 case V_INT
: /**< integer */
8067 case V_REAL
: /**< real/float */
8068 case V_ENUM
: /**< enumerated */
8069 case V_BSTR
: /**< bitstring */
8070 case V_HSTR
: /**< hexstring */
8071 case V_OSTR
: /**< octetstring */
8072 case V_CSTR
: /**< charstring */
8073 case V_USTR
: /**< universal charstring */
8074 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
8075 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
8076 case V_OID
: /**< object identifier */
8077 case V_ROID
: /**< relative object identifier */
8078 case V_VERDICT
: /**< all verdicts */
8079 return true; // values of built-in types return true
8081 // Code below was adapted from is_unfoldable(), false returned early.
8083 return u
.choice
.alt_value
->evaluate_isvalue(false);
8088 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8089 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
8097 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8098 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8099 ->evaluate_isvalue(true)) return false;
8104 // alas, get_value_refd_last prevents this function from const
8105 return get_value_refd_last()->evaluate_isvalue(false);
8108 switch (u
.expr
.v_optype
) {
8109 // A constant null component reference is a corner case: it is foldable
8110 // but escapes unmodified from evaluate_value.
8111 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8112 // or is transformed into some other valuetype in evaluate_value.
8113 case OPTYPE_COMP_NULL
:
8116 break; // and fall through to the FATAL_ERROR
8120 FATAL_ERROR("Value::evaluate_isvalue()");
8126 void Value::evaluate_macro(Type::expected_value_t exp_val
)
8129 case MACRO_MODULEID
:
8131 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8132 set_val_str(new string(my_scope
->get_scope_mod()
8133 ->get_modid().get_dispname()));
8136 case MACRO_FILENAME
:
8137 case MACRO_BFILENAME
: {
8138 const char *t_filename
= get_filename();
8140 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8141 set_val_str(new string(t_filename
));
8144 case MACRO_FILEPATH
: {
8145 const char *t_filename
= get_filename();
8147 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8148 char *t_filepath
= canonize_input_file(t_filename
);
8150 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8151 set_val_str(new string(t_filepath
));
8155 case MACRO_LINENUMBER
: {
8156 int t_lineno
= get_first_line();
8158 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8159 set_val_str(new string(Int2string(t_lineno
)));
8162 case MACRO_LINENUMBER_C
: {
8163 int t_lineno
= get_first_line();
8165 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8166 u
.val_Int
= new int_val_t(t_lineno
);
8169 case MACRO_DEFINITIONID
: {
8170 // cut the second part from the fullname separated by dots
8171 const string
& t_fullname
= get_fullname();
8172 size_t first_char
= t_fullname
.find('.') + 1;
8173 if (first_char
>= t_fullname
.size())
8174 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8175 t_fullname
.c_str());
8176 set_val_str(new string(t_fullname
.substr(first_char
,
8177 t_fullname
.find('.', first_char
) - first_char
)));
8181 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8182 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8186 case MACRO_TESTCASEID
: {
8187 if (exp_val
== Type::EXPECTED_CONSTANT
||
8188 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8189 error("A %s value was expected instead of macro `%%testcaseId', "
8190 "which is evaluated at runtime",
8191 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8195 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8196 Ttcn::StatementBlock
*my_sb
=
8197 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8199 error("Usage of macro %%testcaseId is allowed only within the "
8200 "statement blocks of functions, altsteps and testcases");
8203 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8205 error("Macro %%testcaseId cannot be used in the control part. "
8206 "It is allowed only within the statement blocks of functions, "
8207 "altsteps and testcases");
8210 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8211 // folding is possible only within testcases
8212 set_val_str(new string(my_def
->get_id().get_dispname()));
8217 FATAL_ERROR("Value::evaluate_macro()");
8221 set_valuetype(V_ERROR
);
8224 void Value::add_id(Identifier
*p_id
)
8228 if(u
.ids
->has_key(p_id
->get_name())) {
8229 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8230 // The Value does not take ownership for the identifier,
8231 // so it must be deleted (add_is acts as a sink).
8234 else u
.ids
->add(p_id
->get_name(), p_id
);
8237 FATAL_ERROR("Value::add_id()");
8241 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8242 Type::expected_value_t exp_val
)
8244 set_lowerid_to_ref();
8245 switch (valuetype
) {
8247 // there might be a better place for this
8248 chk_invoke(exp_val
);
8251 // use the cache if available
8252 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8254 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8256 // the referred definition is not found
8257 set_valuetype(V_ERROR
);
8259 switch (ass
->get_asstype()) {
8260 case Assignment::A_OBJECT
:
8261 case Assignment::A_OS
: {
8262 // the referred definition is an ASN.1 object or object set
8263 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8264 if (!setting
|| setting
->get_st() == S_ERROR
) {
8265 // remain silent, the error has been already reported
8266 set_valuetype(V_ERROR
);
8268 } else if (setting
->get_st() != S_V
) {
8269 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8270 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8271 set_valuetype(V_ERROR
);
8276 refch
->mark_state();
8277 destroy_refch
= false;
8279 refch
= new ReferenceChain(this,
8280 "While searching referenced value");
8281 destroy_refch
= true;
8283 if (refch
->add(get_fullname())) {
8284 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8285 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8286 // in case of circular recursion the valuetype is already set
8287 // to V_ERROR, so don't set the cache
8288 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8290 // a circular recursion was detected
8291 set_valuetype(V_ERROR
);
8293 if (destroy_refch
) delete refch
;
8294 else refch
->prev_state();
8296 case Assignment::A_CONST
: {
8297 // the referred definition is a constant
8300 refch
->mark_state();
8301 destroy_refch
= false;
8303 refch
= new ReferenceChain(this,
8304 "While searching referenced value");
8305 destroy_refch
= true;
8307 if (refch
->add(get_fullname())) {
8308 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8309 Value
*v_refd
= ass
->get_Value()
8310 ->get_refd_sub_value(subrefs
, 0,
8311 u
.ref
.ref
->getUsedInIsbound(), refch
);
8313 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8314 // in case of circular recursion the valuetype is already set
8315 // to V_ERROR, so don't set the cache
8316 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8317 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8318 u
.ref
.refd_last
= this;
8319 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8320 u
.ref
.refd_last
= this;
8322 // the sub-reference points to a non-existent field
8323 set_valuetype(V_ERROR
);
8326 // a circular recursion was detected
8327 set_valuetype(V_ERROR
);
8329 if (destroy_refch
) delete refch
;
8330 else refch
->prev_state();
8332 case Assignment::A_EXT_CONST
:
8333 case Assignment::A_MODULEPAR
:
8334 case Assignment::A_VAR
:
8335 case Assignment::A_FUNCTION_RVAL
:
8336 case Assignment::A_EXT_FUNCTION_RVAL
:
8337 case Assignment::A_PAR_VAL_IN
:
8338 case Assignment::A_PAR_VAL_OUT
:
8339 case Assignment::A_PAR_VAL_INOUT
:
8340 // the referred definition is not a constant
8341 u
.ref
.refd_last
= this;
8343 case Assignment::A_FUNCTION
:
8344 case Assignment::A_EXT_FUNCTION
:
8345 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8346 "call of %s, which does not have return type",
8347 ass
->get_description().c_str());
8348 set_valuetype(V_ERROR
);
8350 case Assignment::A_FUNCTION_RTEMP
:
8351 case Assignment::A_EXT_FUNCTION_RTEMP
:
8352 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8353 "call of %s, which returns a template",
8354 ass
->get_description().c_str());
8355 set_valuetype(V_ERROR
);
8358 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8359 ass
->get_description().c_str());
8360 set_valuetype(V_ERROR
);
8363 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8367 // try to evaluate the expression
8370 refch
->mark_state();
8371 destroy_refch
=false;
8374 refch
=new ReferenceChain(this, "While evaluating expression");
8377 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8378 else set_valuetype(V_ERROR
);
8379 if(destroy_refch
) delete refch
;
8380 else refch
->prev_state();
8383 evaluate_macro(exp_val
);
8386 // return this for all other value types
8391 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8393 /* Note that the logic here needs to be in sync with evaluate_value,
8394 * and possibly others, i.e. if evaluate_value is called for a Value
8395 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8396 bool Value::is_unfoldable(ReferenceChain
*refch
,
8397 Type::expected_value_t exp_val
)
8399 if (UnfoldabilityCheck::is_running(this)) {
8400 // This function is already running on this value => infinite recursion
8404 UnfoldabilityCheck
checker(this);
8406 if (get_needs_conversion()) return true;
8407 switch (valuetype
) {
8411 case V_UNDEF_LOWERID
:
8415 // these value types are eliminated during semantic analysis
8416 FATAL_ERROR("Value::is_unfoldable()");
8421 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8425 if (!is_indexed()) {
8426 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8427 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8431 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8432 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8439 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8440 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8441 ->is_unfoldable(refch
, exp_val
)) return true;
8447 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8448 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8452 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8453 if(v_last
==this) return true; // there weren't any references to chase
8454 else return v_last
->is_unfoldable(refch
, exp_val
);
8457 // classify the unchecked ischosen() operation, if it was not done so far
8458 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8459 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8460 switch (u
.expr
.v_optype
) {
8461 case OPTYPE_RND
: // -
8462 case OPTYPE_COMP_MTC
:
8463 case OPTYPE_COMP_SYSTEM
:
8464 case OPTYPE_COMP_SELF
:
8465 case OPTYPE_COMP_RUNNING_ANY
:
8466 case OPTYPE_COMP_RUNNING_ALL
:
8467 case OPTYPE_COMP_ALIVE_ANY
:
8468 case OPTYPE_COMP_ALIVE_ALL
:
8469 case OPTYPE_TMR_RUNNING_ANY
:
8470 case OPTYPE_GETVERDICT
:
8471 case OPTYPE_TESTCASENAME
:
8472 case OPTYPE_PROF_RUNNING
:
8473 case OPTYPE_RNDWITHVAL
: // v1
8474 case OPTYPE_MATCH
: // v1 t2
8475 case OPTYPE_UNDEF_RUNNING
: // v1
8476 case OPTYPE_COMP_RUNNING
:
8477 case OPTYPE_COMP_ALIVE
:
8478 case OPTYPE_TMR_READ
:
8479 case OPTYPE_TMR_RUNNING
:
8480 case OPTYPE_ACTIVATE
:
8481 case OPTYPE_ACTIVATE_REFD
:
8482 case OPTYPE_EXECUTE
: // r1 [v2]
8483 case OPTYPE_EXECUTE_REFD
:
8484 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8485 case OPTYPE_ISCHOSEN
:
8486 case OPTYPE_ISCHOSEN_T
:
8487 case OPTYPE_SIZEOF
: // ti1
8490 case OPTYPE_OCT2UNICHAR
:
8491 case OPTYPE_UNICHAR2OCT
:
8492 case OPTYPE_ENCODE_BASE64
:
8493 case OPTYPE_DECODE_BASE64
:
8494 case OPTYPE_ENCVALUE_UNICHAR
:
8495 case OPTYPE_DECVALUE_UNICHAR
:
8497 case OPTYPE_COMP_NULL
: // -
8499 case OPTYPE_UNARYPLUS
: // v1
8500 case OPTYPE_UNARYMINUS
:
8503 case OPTYPE_BIT2HEX
:
8504 case OPTYPE_BIT2INT
:
8505 case OPTYPE_BIT2OCT
:
8506 case OPTYPE_BIT2STR
:
8507 case OPTYPE_CHAR2INT
:
8508 case OPTYPE_CHAR2OCT
:
8509 case OPTYPE_FLOAT2INT
:
8510 case OPTYPE_FLOAT2STR
:
8511 case OPTYPE_HEX2BIT
:
8512 case OPTYPE_HEX2INT
:
8513 case OPTYPE_HEX2OCT
:
8514 case OPTYPE_HEX2STR
:
8515 case OPTYPE_INT2CHAR
:
8516 case OPTYPE_INT2FLOAT
:
8517 case OPTYPE_INT2STR
:
8518 case OPTYPE_INT2UNICHAR
:
8519 case OPTYPE_OCT2BIT
:
8520 case OPTYPE_OCT2CHAR
:
8521 case OPTYPE_OCT2HEX
:
8522 case OPTYPE_OCT2INT
:
8523 case OPTYPE_OCT2STR
:
8524 case OPTYPE_STR2BIT
:
8525 case OPTYPE_STR2FLOAT
:
8526 case OPTYPE_STR2HEX
:
8527 case OPTYPE_STR2INT
:
8528 case OPTYPE_STR2OCT
:
8529 case OPTYPE_UNICHAR2INT
:
8530 case OPTYPE_UNICHAR2CHAR
:
8531 case OPTYPE_ENUM2INT
:
8532 case OPTYPE_GET_STRINGENCODING
:
8533 case OPTYPE_REMOVE_BOM
:
8534 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8535 case OPTYPE_ISBOUND
: /*{
8536 //TODO once we have the time for it make isbound foldable.
8537 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8538 Template* temp = u.expr.ti1->get_Template();
8539 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8540 Value* specificValue = temp->get_specific_value();
8541 if (specificValue->get_valuetype() == Value::V_REFD) {
8545 return specificValue->is_unfoldable(refch, exp_val);
8546 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8551 case OPTYPE_ISPRESENT
:
8552 // TODO: "if you have motivation"
8554 case OPTYPE_ISVALUE
: // ti1
8556 case OPTYPE_LENGTHOF
: // ti1
8557 return u
.expr
.ti1
->get_DerivedRef() != 0
8558 || u
.expr
.ti1
->get_Template()->get_templatetype()
8559 != Template::SPECIFIC_VALUE
8560 || u
.expr
.ti1
->get_Template()->get_specific_value()
8561 ->is_unfoldable(refch
, exp_val
);
8565 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8567 case OPTYPE_ADD
: // v1 v2
8568 case OPTYPE_SUBTRACT
:
8569 case OPTYPE_MULTIPLY
:
8585 case OPTYPE_INT2BIT
:
8586 case OPTYPE_INT2HEX
:
8587 case OPTYPE_INT2OCT
:
8588 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8589 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8590 case OPTYPE_AND
: // short-circuit evaluation
8591 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8592 || (u
.expr
.v1
->get_val_bool() &&
8593 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8594 case OPTYPE_OR
: // short-circuit evaluation
8595 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8596 || (!u
.expr
.v1
->get_val_bool() &&
8597 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8599 if (!u
.expr
.ti1
->get_specific_value()) return true;
8600 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8601 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8602 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8603 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8605 if (!u
.expr
.ti1
->get_specific_value() ||
8606 !u
.expr
.t2
->get_specific_value()) return true;
8607 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8608 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8609 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8611 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8612 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8613 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8614 case OPTYPE_REPLACE
: {
8615 if (!u
.expr
.ti1
->get_specific_value() ||
8616 !u
.expr
.ti4
->get_specific_value()) return true;
8617 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8618 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8619 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8620 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8621 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8623 case OPTYPE_VALUEOF
: // ti1
8624 /* \todo if you have motivation to implement the eval function
8627 case OPTYPE_ISCHOSEN_V
:
8628 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8629 case OPTYPE_LOG2STR
:
8630 case OPTYPE_TTCN2STRING
:
8633 FATAL_ERROR("Value::is_unfoldable()");
8635 break; // should never get here
8638 case MACRO_TESTCASEID
:
8639 // this is known only at runtime
8645 // all literal values are foldable
8650 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8651 size_t start_i
, bool usedInIsbound
,
8652 ReferenceChain
*refch
)
8654 if (!subrefs
) return this;
8656 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8658 v
= v
->get_value_refd_last(refch
);
8659 switch(v
->valuetype
) {
8668 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8669 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8670 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8671 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8676 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8677 bool usedInIsbound
, const Location
& loc
)
8679 if (valuetype
== V_OMIT
) {
8680 loc
.error("Reference to field `%s' of omit value `%s'",
8681 field_id
.get_dispname().c_str(), get_fullname().c_str());
8684 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8685 Type
*t
= my_governor
->get_type_refd_last();
8686 switch (t
->get_typetype()) {
8690 case Type::T_CHOICE_A
:
8691 case Type::T_CHOICE_T
:
8692 case Type::T_OPENTYPE
:
8693 case Type::T_ANYTYPE
:
8694 if (!t
->has_comp_withName(field_id
)) {
8695 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8696 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8698 } else if (valuetype
!= V_CHOICE
) {
8699 // remain silent, the error is already reported
8701 } else if (*u
.choice
.alt_name
== field_id
) {
8703 return u
.choice
.alt_value
;
8705 if (!usedInIsbound
) {
8706 loc
.error("Reference to inactive field `%s' in a value of union type "
8707 "`%s'. The active field is `%s'",
8708 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8709 u
.choice
.alt_name
->get_dispname().c_str());
8715 if (!t
->has_comp_withName(field_id
)) {
8716 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8717 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8719 } else if (valuetype
!= V_SEQ
) {
8720 // remain silent, the error has been already reported
8725 if (!t
->has_comp_withName(field_id
)) {
8726 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8727 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8729 } else if (valuetype
!= V_SET
) {
8730 // remain silent, the error has been already reported
8734 loc
.error("Invalid field reference `%s': type `%s' "
8735 "does not have fields", field_id
.get_dispname().c_str(),
8736 t
->get_typename().c_str());
8739 // the common end for record & set types
8740 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8742 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8743 } else if (!is_asn1()) {
8744 if (!usedInIsbound
) {
8745 loc
.error("Reference to unbound field `%s'",
8746 field_id
.get_dispname().c_str());
8747 // this is an error in TTCN-3, which has been already reported
8751 CompField
*cf
= t
->get_comp_byName(field_id
);
8752 if (cf
->get_is_optional()) {
8753 // creating an explicit omit value
8754 Value
*v
= new Value(V_OMIT
);
8755 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8756 v
->set_my_scope(get_my_scope());
8757 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8759 } else if (cf
->has_default()) {
8760 // returning the component's default value
8761 return cf
->get_defval();
8763 // this is an error in ASN.1, which has been already reported
8769 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8770 ReferenceChain
*refch
)
8772 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8774 bool index_available
= false;
8775 if (!v_index
->is_unfoldable()) {
8776 if (v_index
->valuetype
== V_INT
) {
8777 index
= v_index
->get_val_Int()->get_val();
8778 index_available
= true;
8780 array_index
->error("An integer value was expected as index");
8783 if (valuetype
== V_OMIT
) {
8784 array_index
->error("Accessing an element with index of omit value `%s'",
8785 get_fullname().c_str());
8788 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8789 Type
*t
= my_governor
->get_type_refd_last();
8790 switch (t
->get_typetype()) {
8795 if (index_available
) {
8797 array_index
->error("A non-negative integer value was expected "
8798 "instead of %s for indexing a value of `record "
8799 "of' type `%s'", Int2string(index
).c_str(),
8800 t
->get_typename().c_str());
8803 switch (valuetype
) {
8805 if (!is_indexed()) {
8806 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8807 if (!usedInIsbound
) {
8808 array_index
->error("Index overflow in a value of `record of' "
8809 "type `%s': the index is %s, but the value "
8810 "has only %lu elements",
8811 t
->get_typename().c_str(),
8812 Int2string(index
).c_str(),
8813 (unsigned long)u
.val_vs
->get_nof_vs());
8817 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8818 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8819 temp
->error("Not used symbol is not allowed in this context");
8820 return u
.val_vs
->get_v_byIndex(index
);
8823 // Search the appropriate constant index.
8824 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8825 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8826 ->get_value_refd_last();
8827 if (iv_index
->get_valuetype() != V_INT
) continue;
8828 if (iv_index
->get_val_Int()->get_val() == index
)
8829 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8835 // remain silent, the error has been already reported
8839 // the error has been reported above
8843 if (index_available
) {
8845 array_index
->error("A non-negative integer value was expected "
8846 "instead of %s for indexing a value of `set of' type `%s'",
8847 Int2string(index
).c_str(), t
->get_typename().c_str());
8850 switch (valuetype
) {
8852 if (!is_indexed()) {
8853 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8854 if (!usedInIsbound
) {
8855 array_index
->error("Index overflow in a value of `set of' type "
8856 "`%s': the index is %s, but the value has "
8857 "only %lu elements",
8858 t
->get_typename().c_str(),
8859 Int2string(index
).c_str(),
8860 (unsigned long)u
.val_vs
->get_nof_vs());
8864 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8865 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8866 temp
->error("Not used symbol is not allowed in this context");
8870 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8871 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8872 ->get_value_refd_last();
8873 if (iv_index
->get_valuetype() != V_INT
) continue;
8874 if (iv_index
->get_val_Int()->get_val() == index
)
8875 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8881 // remain silent, the error has been already reported
8885 // the error has been reported above
8889 if (index_available
) {
8890 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8891 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8892 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8893 // perform the index transformation
8894 index
-= dim
->get_offset();
8895 if (!is_indexed()) {
8896 // check for index underflow/overflow or too few elements in the
8899 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8901 else return u
.val_vs
->get_v_byIndex(index
);
8903 if (index
< 0) return 0;
8904 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8905 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8906 ->get_value_refd_last();
8907 if (iv_index
->get_valuetype() != V_INT
) continue;
8908 if (iv_index
->get_val_Int()->get_val() == index
)
8909 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8914 // remain silent, the error has been already reported
8918 // the error has been reported above
8922 case Type::T_BSTR_A
:
8927 case Type::T_UTF8STRING
:
8928 case Type::T_NUMERICSTRING
:
8929 case Type::T_PRINTABLESTRING
:
8930 case Type::T_TELETEXSTRING
:
8931 case Type::T_VIDEOTEXSTRING
:
8932 case Type::T_IA5STRING
:
8933 case Type::T_GRAPHICSTRING
:
8934 case Type::T_VISIBLESTRING
:
8935 case Type::T_GENERALSTRING
:
8936 case Type::T_UNIVERSALSTRING
:
8937 case Type::T_BMPSTRING
:
8938 case Type::T_UTCTIME
:
8939 case Type::T_GENERALIZEDTIME
:
8940 case Type::T_OBJECTDESCRIPTOR
:
8941 if (index_available
) return get_string_element(index
, *array_index
);
8944 array_index
->error("Invalid array element reference: type `%s' cannot "
8945 "be indexed", t
->get_typename().c_str());
8950 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8953 loc
.error("A non-negative integer value was expected instead of %s "
8954 "for indexing a string element", Int2string(index
).c_str());
8957 size_t string_length
;
8958 switch (valuetype
) {
8963 string_length
= u
.str
.val_str
->size();
8966 string_length
= u
.str
.val_str
->size() / 2;
8969 string_length
= u
.ustr
.val_ustr
->size();
8972 // remain silent, the error has been already reported
8975 if (index
>= static_cast<Int
>(string_length
)) {
8976 loc
.error("Index overflow when accessing a string element: "
8977 "the index is %s, but the string has only %lu elements",
8978 Int2string(index
).c_str(), (unsigned long) string_length
);
8981 switch (valuetype
) {
8986 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8987 return (*u
.str
.str_elements
)[index
];
8989 Value
*t_val
= new Value(valuetype
,
8990 new string(u
.str
.val_str
->substr(index
, 1)));
8991 add_string_element(index
, t_val
, u
.str
.str_elements
);
8995 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8996 return (*u
.str
.str_elements
)[index
];
8998 Value
*t_val
= new Value(V_OSTR
,
8999 new string(u
.str
.val_str
->substr(2 * index
, 2)));
9000 add_string_element(index
, t_val
, u
.str
.str_elements
);
9004 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
9005 return (*u
.ustr
.ustr_elements
)[index
];
9007 Value
*t_val
= new Value(V_USTR
,
9008 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
9009 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
9013 FATAL_ERROR("Value::get_string_element()");
9018 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
9019 Type::expected_value_t exp_val
)
9021 set_lowerid_to_ref();
9022 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
9023 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
9025 error("A value or expression of type %s was expected", type_name
);
9026 if (valuetype
== V_REFD
) {
9027 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
9028 t_chk
->chk_this_refd_value(this, 0, exp_val
);
9030 get_value_refd_last(0, exp_val
);
9031 if (error_flag
) set_valuetype(V_ERROR
);
9032 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
9035 int Value::is_parsed_infinity()
9037 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
9039 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
9040 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
9041 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
9046 bool Value::get_val_bool()
9049 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9051 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
9052 return v
->u
.val_bool
;
9055 int_val_t
* Value::get_val_Int()
9058 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9060 switch (v
->valuetype
) {
9063 case V_UNDEF_LOWERID
:
9064 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9065 "`%s'", (*u
.val_id
).get_dispname().c_str());
9067 FATAL_ERROR("Value::get_val_Int()");
9069 return v
->u
.val_Int
;
9072 const Identifier
* Value::get_val_id()
9077 case V_UNDEF_LOWERID
:
9080 FATAL_ERROR("Value::get_val_id()");
9085 const ttcn3float
& Value::get_val_Real()
9088 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9090 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
9091 return v
->u
.val_Real
;
9094 string
Value::get_val_str()
9096 Value
*v
= get_value_refd_last();
9097 switch (v
->valuetype
) {
9102 return *v
->u
.str
.val_str
;
9104 return v
->u
.char_syms
->get_string();
9106 error("Cannot use ISO-10646 string value in string context");
9109 error("Cannot use ISO-2022 string value in string context");
9114 error("Cannot use this value in charstring value context");
9119 ustring
Value::get_val_ustr()
9121 Value
*v
= get_value_refd_last();
9122 switch (v
->valuetype
) {
9124 return ustring(*v
->u
.str
.val_str
);
9126 return *v
->u
.ustr
.val_ustr
;
9128 return v
->u
.char_syms
->get_ustring();
9130 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9135 error("Cannot use this value in ISO-10646 string context");
9140 string
Value::get_val_iso2022str()
9142 Value
*v
= get_value_refd_last();
9143 switch (v
->valuetype
) {
9146 return *v
->u
.str
.val_str
;
9148 return v
->u
.char_syms
->get_iso2022string();
9150 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9155 error("Cannot use this value in ISO-2022 string context");
9160 size_t Value::get_val_strlen()
9162 Value
*v
= get_value_refd_last();
9163 switch (v
->valuetype
) {
9168 return v
->u
.str
.val_str
->size();
9170 return v
->u
.str
.val_str
->size()/2;
9172 return v
->u
.char_syms
->get_len();
9174 return v
->u
.ustr
.val_ustr
->size();
9178 error("Cannot use this value in string value context");
9183 Value::verdict_t
Value::get_val_verdict()
9189 FATAL_ERROR("Value::get_val_verdict()");
9194 size_t Value::get_nof_comps()
9196 switch (valuetype
) {
9200 return u
.oid_comps
->size();
9204 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9205 else return u
.val_vs
->get_nof_vs();
9208 return u
.val_nvs
->get_nof_nvs();
9213 return u
.str
.val_str
->size();
9215 return u
.str
.val_str
->size()/2;
9217 return u
.ustr
.val_ustr
->size();
9219 FATAL_ERROR("Value::get_nof_comps()");
9224 bool Value::is_indexed() const
9226 switch (valuetype
) {
9230 // Applicable only for list-types. Assigning a record/SEQUENCE or
9231 // set/SET with indexed notation is not supported.
9232 return u
.val_vs
->is_indexed();
9234 FATAL_ERROR("Value::is_indexed()");
9240 const Identifier
& Value::get_alt_name()
9242 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9243 return *u
.choice
.alt_name
;
9246 Value
*Value::get_alt_value()
9248 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9249 return u
.choice
.alt_value
;
9252 void Value::set_alt_name_to_lowercase()
9254 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9255 string new_name
= u
.choice
.alt_name
->get_name();
9256 if (isupper(new_name
[0])) {
9257 new_name
[0] = tolower(new_name
[0]);
9258 if (new_name
[new_name
.size() - 1] == '_') {
9259 // an underscore is inserted at the end of the alternative name if it's
9260 // a basic type's name (since it would conflict with the class generated
9262 // remove the underscore, it won't conflict with anything if its name
9263 // starts with a lowercase letter
9264 new_name
.replace(new_name
.size() - 1, 1, "");
9266 delete u
.choice
.alt_name
;
9267 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9271 bool Value::has_oid_error()
9274 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9276 switch (valuetype
) {
9279 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9280 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9287 bool Value::get_oid_comps(vector
<string
>& comps
)
9289 bool ret_val
= true;
9291 switch (valuetype
) {
9293 v
= get_value_refd_last();
9297 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9298 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9299 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9300 // not all components can be calculated in compile-time
9306 FATAL_ERROR("Value::get_oid_comps()");
9311 void Value::add_se_comp(NamedValue
* nv
) {
9312 switch (valuetype
) {
9316 u
.val_nvs
= new NamedValues();
9317 u
.val_nvs
->add_nv(nv
);
9320 FATAL_ERROR("Value::add_se_comp()");
9324 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9329 return u
.val_nvs
->get_nv_byIndex(n
);
9331 FATAL_ERROR("Value::get_se_comp_byIndex()");
9336 Value
*Value::get_comp_byIndex(size_t n
)
9338 switch (valuetype
) {
9342 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9343 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9345 FATAL_ERROR("Value::get_comp_byIndex()");
9350 Value
*Value::get_index_byIndex(size_t n
)
9352 switch (valuetype
) {
9356 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9357 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9359 FATAL_ERROR("Value::get_index_byIndex()");
9364 bool Value::has_comp_withName(const Identifier
& p_name
)
9369 return u
.val_nvs
->has_nv_withName(p_name
);
9371 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9373 FATAL_ERROR("Value::get_has_comp_withName()");
9378 bool Value::field_is_chosen(const Identifier
& p_name
)
9380 Value
*v
=get_value_refd_last();
9381 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9382 return *v
->u
.choice
.alt_name
==p_name
;
9385 bool Value::field_is_present(const Identifier
& p_name
)
9387 Value
*v
=get_value_refd_last();
9388 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9389 FATAL_ERROR("Value::field_is_present()");
9390 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9391 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9392 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9395 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9400 return u
.val_nvs
->get_nv_byName(p_name
);
9402 FATAL_ERROR("Value::get_se_comp_byName()");
9407 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9412 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9414 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9415 return u
.choice
.alt_value
;
9419 FATAL_ERROR("Value::get_se_comp_byName()");
9424 void Value::chk_dupl_id()
9429 u
.val_nvs
->chk_dupl_id();
9432 FATAL_ERROR("Value::chk_dupl_id()");
9436 size_t Value::get_nof_ids() const
9440 return u
.ids
->size();
9443 FATAL_ERROR("Value::get_nof_ids()");
9448 Identifier
* Value::get_id_byIndex(size_t p_i
)
9452 return u
.ids
->get_nth_elem(p_i
);
9455 FATAL_ERROR("Value::get_id_byIndex()");
9460 bool Value::has_id(const Identifier
& p_id
)
9464 return u
.ids
->has_key(p_id
.get_name());
9467 FATAL_ERROR("Value::has_id()");
9472 Reference
*Value::get_reference() const
9474 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9478 Reference
*Value::get_refered() const
9480 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9484 Common::Assignment
*Value::get_refd_fat() const
9492 FATAL_ERROR("Value::get_refd_fat()");
9496 Ttcn::Reference
* Value::steal_ttcn_ref()
9498 Ttcn::Reference
*ret_val
=
9499 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9500 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9504 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9506 Ttcn::Ref_base
*t_ref
;
9507 if(valuetype
==V_REFD
) {
9508 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9509 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9512 else if(valuetype
==V_UNDEF_LOWERID
) {
9513 t_ref
=new Ttcn::Reference(u
.val_id
);
9514 t_ref
->set_location(*this);
9515 t_ref
->set_fullname(get_fullname());
9516 t_ref
->set_my_scope(get_my_scope());
9520 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9523 set_valuetype(V_ERROR
);
9527 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9528 Ttcn::ActualParList
*& p_ap
)
9530 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9533 p_ti
= u
.invoke
.t_list
;
9534 u
.invoke
.t_list
= 0;
9535 p_ap
= u
.invoke
.ap_list
;
9536 u
.invoke
.ap_list
= 0;
9537 set_valuetype(V_ERROR
);
9540 Common::Assignment
* Value::get_refd_assignment()
9549 FATAL_ERROR("Value::get_refd_assignment()");
9559 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9564 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9573 void Value::chk_OID(ReferenceChain
& refch
)
9575 if (checked
) return;
9576 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9577 FATAL_ERROR("Value::chk_OID()");
9578 if (!refch
.add(get_fullname())) {
9582 OID_comp::oidstate_t state
= OID_comp::START
;
9583 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9585 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9588 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9589 error("An OBJECT IDENTIFIER value must have at least "
9590 "two components"); // X.680 (07/2002) 31.10
9593 void Value::chk_ROID(ReferenceChain
& refch
)
9595 if (checked
) return;
9596 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9597 FATAL_ERROR("Value::chk_ROID()");
9598 if (!refch
.add(get_fullname())) {
9602 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9604 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9609 void Value::chk_recursions(ReferenceChain
& refch
)
9611 if (recurs_checked
) return;
9612 Value
*v
= get_value_refd_last();
9613 if (refch
.add(v
->get_fullname())) {
9614 switch (v
->valuetype
) {
9616 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9621 if (!v
->is_indexed()) {
9622 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9624 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9628 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9630 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9631 ->chk_recursions(refch
);
9638 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9640 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9645 chk_recursions_expr(refch
);
9650 if (v
->err_descr
) { // FIXME: make this work
9651 v
->err_descr
->chk_recursions(refch
);
9654 recurs_checked
= true;
9657 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9659 // first classify the unchecked ischosen() operation
9660 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9661 switch (u
.expr
.v_optype
) {
9662 case OPTYPE_UNARYPLUS
: // v1
9663 case OPTYPE_UNARYMINUS
:
9666 case OPTYPE_BIT2HEX
:
9667 case OPTYPE_BIT2INT
:
9668 case OPTYPE_BIT2OCT
:
9669 case OPTYPE_BIT2STR
:
9670 case OPTYPE_CHAR2INT
:
9671 case OPTYPE_CHAR2OCT
:
9672 case OPTYPE_FLOAT2INT
:
9673 case OPTYPE_FLOAT2STR
:
9674 case OPTYPE_HEX2BIT
:
9675 case OPTYPE_HEX2INT
:
9676 case OPTYPE_HEX2OCT
:
9677 case OPTYPE_HEX2STR
:
9678 case OPTYPE_INT2CHAR
:
9679 case OPTYPE_INT2FLOAT
:
9680 case OPTYPE_INT2STR
:
9681 case OPTYPE_INT2UNICHAR
:
9682 case OPTYPE_OCT2BIT
:
9683 case OPTYPE_OCT2CHAR
:
9684 case OPTYPE_OCT2HEX
:
9685 case OPTYPE_OCT2INT
:
9686 case OPTYPE_OCT2STR
:
9687 case OPTYPE_STR2BIT
:
9688 case OPTYPE_STR2FLOAT
:
9689 case OPTYPE_STR2HEX
:
9690 case OPTYPE_STR2INT
:
9691 case OPTYPE_STR2OCT
:
9692 case OPTYPE_UNICHAR2INT
:
9693 case OPTYPE_ENUM2INT
:
9694 case OPTYPE_UNICHAR2CHAR
:
9695 case OPTYPE_RNDWITHVAL
:
9696 case OPTYPE_ISCHOSEN_V
:
9697 case OPTYPE_GET_STRINGENCODING
:
9698 case OPTYPE_REMOVE_BOM
:
9699 case OPTYPE_DECODE_BASE64
:
9701 u
.expr
.v1
->chk_recursions(refch
);
9704 case OPTYPE_ISCHOSEN_T
:
9706 u
.expr
.t1
->chk_recursions(refch
);
9709 case OPTYPE_ADD
: // v1 v2
9710 case OPTYPE_SUBTRACT
:
9711 case OPTYPE_MULTIPLY
:
9732 case OPTYPE_INT2BIT
:
9733 case OPTYPE_INT2HEX
:
9734 case OPTYPE_INT2OCT
:
9736 u
.expr
.v1
->chk_recursions(refch
);
9739 u
.expr
.v2
->chk_recursions(refch
);
9742 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9743 case OPTYPE_OCT2UNICHAR
:
9744 case OPTYPE_ENCODE_BASE64
:
9746 u
.expr
.v1
->chk_recursions(refch
);
9750 u
.expr
.v2
->chk_recursions(refch
);
9755 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9756 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9760 u
.expr
.ti1
->chk_recursions(refch
);
9763 u
.expr
.v2
->chk_recursions(refch
);
9766 u
.expr
.v3
->chk_recursions(refch
);
9771 u
.expr
.ti1
->chk_recursions(refch
);
9774 u
.expr
.t2
->chk_recursions(refch
);
9777 u
.expr
.v3
->chk_recursions(refch
);
9780 case OPTYPE_DECOMP
: // v1 v2 v3
9782 u
.expr
.v1
->chk_recursions(refch
);
9785 u
.expr
.v2
->chk_recursions(refch
);
9788 u
.expr
.v3
->chk_recursions(refch
);
9791 case OPTYPE_REPLACE
:
9793 u
.expr
.ti1
->chk_recursions(refch
);
9796 u
.expr
.v2
->chk_recursions(refch
);
9799 u
.expr
.v3
->chk_recursions(refch
);
9802 u
.expr
.ti4
->chk_recursions(refch
);
9805 case OPTYPE_LENGTHOF
: // ti1
9806 case OPTYPE_SIZEOF
: // ti1
9807 case OPTYPE_VALUEOF
: // ti1
9809 case OPTYPE_ISPRESENT
:
9810 case OPTYPE_TTCN2STRING
:
9812 u
.expr
.ti1
->chk_recursions(refch
);
9815 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
9817 u
.expr
.ti1
->chk_recursions(refch
);
9821 u
.expr
.v2
->chk_recursions(refch
);
9825 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
9826 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9827 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9830 u
.expr
.v3
->chk_recursions(refch
);
9834 case OPTYPE_MATCH
: // v1 t2
9836 u
.expr
.v1
->chk_recursions(refch
);
9839 u
.expr
.t2
->chk_recursions(refch
);
9842 case OPTYPE_LOG2STR
:
9843 u
.expr
.logargs
->chk_recursions(refch
);
9850 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9851 ReferenceChain
& refch
) {
9852 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9853 Assignment
*ass
= ref
->get_refd_assignment();
9855 set_valuetype(V_ERROR
);
9858 switch (ass
->get_asstype()) {
9859 case Assignment::A_CONST
:
9860 case Assignment::A_EXT_CONST
:
9861 case Assignment::A_MODULEPAR
:
9862 case Assignment::A_VAR
:
9863 case Assignment::A_PAR_VAL_IN
:
9864 case Assignment::A_PAR_VAL_OUT
:
9865 case Assignment::A_PAR_VAL_INOUT
: {
9866 Value
* v
= new Value(V_REFD
, ref
);
9867 v
->set_location(*ref
);
9868 v
->set_my_scope(get_my_scope());
9869 v
->set_fullname(get_fullname()+".<operand>");
9871 v
->chk_recursions(refch
);
9875 case Assignment::A_MODULEPAR_TEMP
:
9876 case Assignment::A_TEMPLATE
:
9877 case Assignment::A_VAR_TEMPLATE
:
9878 case Assignment::A_PAR_TEMPL_IN
:
9879 case Assignment::A_PAR_TEMPL_OUT
:
9880 case Assignment::A_PAR_TEMPL_INOUT
: {
9881 Template
* t
= new Template(ref
->clone());
9882 t
->set_location(*ref
);
9883 t
->set_my_scope(get_my_scope());
9884 t
->set_fullname(get_fullname()+".<operand>");
9886 t
->chk_recursions(refch
);
9891 // remain silent, the error has been already reported
9892 set_valuetype(V_ERROR
);
9897 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9899 bool self_ref
= false;
9900 switch (t
->get_templatetype()) {
9901 case Ttcn::Template::SPECIFIC_VALUE
: {
9902 Value
*v
= t
->get_specific_value();
9903 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9904 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9905 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9907 case Ttcn::Template::TEMPLATE_REFD
: {
9908 Ttcn::Ref_base
*refb
= t
->get_reference();
9909 Common::Assignment
*ass
= refb
->get_refd_assignment();
9910 self_ref
|= (ass
== lhs
);
9912 case Ttcn::Template::ALL_FROM
:
9913 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9914 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9916 case Ttcn::Template::TEMPLATE_LIST
:
9917 case Ttcn::Template::SUPERSET_MATCH
:
9918 case Ttcn::Template::SUBSET_MATCH
:
9919 case Ttcn::Template::PERMUTATION_MATCH
:
9920 case Ttcn::Template::COMPLEMENTED_LIST
:
9921 case Ttcn::Template::VALUE_LIST
: {
9922 size_t num
= t
->get_nof_comps();
9923 for (size_t i
= 0; i
< num
; ++i
) {
9924 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9927 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9928 // case Ttcn::Template::TEMPLATE_LIST: {
9929 // size_t num = t->get_nof_listitems();
9930 // for (size_t i=0; i < num; ++i) {
9931 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9934 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9935 size_t nnt
= t
->get_nof_comps();
9936 for (size_t i
=0; i
< nnt
; ++i
) {
9937 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9938 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9941 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9942 size_t nnt
= t
->get_nof_comps();
9943 for (size_t i
=0; i
< nnt
; ++i
) {
9944 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9945 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9948 case Ttcn::Template::VALUE_RANGE
: {
9949 Ttcn::ValueRange
*vr
= t
->get_value_range();
9950 Common::Value
*v
= vr
->get_min_v();
9951 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9952 v
= vr
->get_max_v();
9953 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9955 case Ttcn::Template::CSTR_PATTERN
:
9956 case Ttcn::Template::USTR_PATTERN
: {
9957 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9958 self_ref
|= ps
->chk_self_ref(lhs
);
9960 case Ttcn::Template::BSTR_PATTERN
:
9961 case Ttcn::Template::HSTR_PATTERN
:
9962 case Ttcn::Template::OSTR_PATTERN
: {
9963 // FIXME: cannot access u.pattern
9965 case Ttcn::Template::ANY_VALUE
:
9966 case Ttcn::Template::ANY_OR_OMIT
:
9967 case Ttcn::Template::OMIT_VALUE
:
9968 case Ttcn::Template::TEMPLATE_NOTUSED
:
9969 break; // self-ref can't happen
9970 case Ttcn::Template::TEMPLATE_INVOKE
:
9971 break; // assume self-ref can't happen
9972 case Ttcn::Template::TEMPLATE_ERROR
:
9973 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9976 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9977 // break; // and hope for the best
9982 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
9984 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
9985 namedbool is_str_elem
= NOT_STR_ELEM
;
9986 if (v
->valuetype
== V_REFD
) {
9987 Reference
*ref
= v
->get_reference();
9988 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
9989 if (subrefs
&& subrefs
->refers_to_string_element()) {
9990 is_str_elem
= IS_STR_ELEM
;
9993 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9994 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
9998 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
10000 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
10001 if (!lhs
) FATAL_ERROR("no lhs!");
10002 bool self_ref
= false;
10003 switch (u
.expr
.v_optype
) {
10004 case OPTYPE_RND
: // -
10005 case OPTYPE_TESTCASENAME
: // -
10006 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
10007 case OPTYPE_COMP_MTC
: // -
10008 case OPTYPE_COMP_SYSTEM
: // -
10009 case OPTYPE_COMP_SELF
: // -
10010 case OPTYPE_COMP_RUNNING_ANY
: // -
10011 case OPTYPE_COMP_RUNNING_ALL
: // -
10012 case OPTYPE_COMP_ALIVE_ANY
: // -
10013 case OPTYPE_COMP_ALIVE_ALL
: // -
10014 case OPTYPE_TMR_RUNNING_ANY
: // -
10015 case OPTYPE_GETVERDICT
: // -
10016 case OPTYPE_PROF_RUNNING
: // -
10017 break; // nothing to do
10019 case OPTYPE_MATCH
: // v1 t2
10020 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10022 case OPTYPE_UNARYPLUS
: // v1
10023 case OPTYPE_UNARYMINUS
: // v1
10024 case OPTYPE_NOT
: // v1
10025 case OPTYPE_NOT4B
: // v1
10026 case OPTYPE_BIT2HEX
: // v1
10027 case OPTYPE_BIT2INT
: // v1
10028 case OPTYPE_BIT2OCT
: // v1
10029 case OPTYPE_BIT2STR
: // v1
10030 case OPTYPE_CHAR2INT
: // v1
10031 case OPTYPE_CHAR2OCT
: // v1
10032 case OPTYPE_FLOAT2INT
: // v1
10033 case OPTYPE_FLOAT2STR
: // v1
10034 case OPTYPE_HEX2BIT
: // v1
10035 case OPTYPE_HEX2INT
: // v1
10036 case OPTYPE_HEX2OCT
: // v1
10037 case OPTYPE_HEX2STR
: // v1
10038 case OPTYPE_INT2CHAR
: // v1
10039 case OPTYPE_INT2FLOAT
: // v1
10040 case OPTYPE_INT2STR
: // v1
10041 case OPTYPE_INT2UNICHAR
: // v1
10042 case OPTYPE_OCT2BIT
: // v1
10043 case OPTYPE_OCT2CHAR
: // v1
10044 case OPTYPE_OCT2HEX
: // v1
10045 case OPTYPE_OCT2INT
: // v1
10046 case OPTYPE_OCT2STR
: // v1
10047 case OPTYPE_STR2BIT
: // v1
10048 case OPTYPE_STR2FLOAT
: // v1
10049 case OPTYPE_STR2HEX
: // v1
10050 case OPTYPE_STR2INT
: // v1
10051 case OPTYPE_STR2OCT
: // v1
10052 case OPTYPE_UNICHAR2INT
: // v1
10053 case OPTYPE_UNICHAR2CHAR
: // v1
10054 case OPTYPE_ENUM2INT
: // v1
10055 case OPTYPE_RNDWITHVAL
: // v1
10056 case OPTYPE_COMP_RUNNING
: // v1
10057 case OPTYPE_COMP_ALIVE
: // v1
10058 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
10059 case OPTYPE_GET_STRINGENCODING
:
10060 case OPTYPE_DECODE_BASE64
:
10061 case OPTYPE_REMOVE_BOM
:
10062 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10064 case OPTYPE_ADD
: // v1 v2
10065 case OPTYPE_SUBTRACT
: // v1 v2
10066 case OPTYPE_MULTIPLY
: // v1 v2
10067 case OPTYPE_DIVIDE
: // v1 v2
10068 case OPTYPE_MOD
: // v1 v2
10069 case OPTYPE_REM
: // v1 v2
10070 case OPTYPE_CONCAT
: // v1 v2
10071 case OPTYPE_EQ
: // v1 v2
10072 case OPTYPE_LT
: // v1 v2
10073 case OPTYPE_GT
: // v1 v2
10074 case OPTYPE_NE
: // v1 v2
10075 case OPTYPE_GE
: // v1 v2
10076 case OPTYPE_LE
: // v1 v2
10077 case OPTYPE_AND
: // v1 v2
10078 case OPTYPE_OR
: // v1 v2
10079 case OPTYPE_XOR
: // v1 v2
10080 case OPTYPE_AND4B
: // v1 v2
10081 case OPTYPE_OR4B
: // v1 v2
10082 case OPTYPE_XOR4B
: // v1 v2
10083 case OPTYPE_SHL
: // v1 v2
10084 case OPTYPE_SHR
: // v1 v2
10085 case OPTYPE_ROTL
: // v1 v2
10086 case OPTYPE_ROTR
: // v1 v2
10087 case OPTYPE_INT2BIT
: // v1 v2
10088 case OPTYPE_INT2HEX
: // v1 v2
10089 case OPTYPE_INT2OCT
: // v1 v2
10090 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10091 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10093 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
10094 case OPTYPE_OCT2UNICHAR
:
10095 case OPTYPE_ENCODE_BASE64
:
10096 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10097 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10099 case OPTYPE_DECOMP
: // v1 v2 v3
10100 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10101 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10102 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10105 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
10106 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
10108 case OPTYPE_SUBSTR
: // ti1 v2 v3
10109 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10110 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
10111 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
10114 case OPTYPE_REGEXP
: // ti1 t2 v3
10115 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10116 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10118 case OPTYPE_LENGTHOF
: // ti1
10119 case OPTYPE_SIZEOF
: // ti1
10120 case OPTYPE_VALUEOF
: // ti1
10121 case OPTYPE_ENCODE
: // ti1
10122 case OPTYPE_TTCN2STRING
:
10123 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10125 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
10126 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10127 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10129 case OPTYPE_DECVALUE_UNICHAR
: { // r1 r2 [v3]
10130 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10131 self_ref
|= (ass
== lhs
);
10132 if (u
.expr
.v3
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10135 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
10136 // component.create -- assume no self-ref
10137 case OPTYPE_ACTIVATE
: // r1
10138 // defaultref := activate(altstep) -- assume no self-ref
10139 case OPTYPE_TMR_RUNNING
: // r1
10140 // boolvar := a_timer.running -- assume no self-ref
10144 case OPTYPE_LOG2STR
: {// logargs
10145 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
10146 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
10147 switch (la
->get_type()) {
10148 case Ttcn::LogArgument::L_UNDEF
:
10149 case Ttcn::LogArgument::L_ERROR
:
10150 FATAL_ERROR("log2str argument type");
10151 break; // not reached
10153 case Ttcn::LogArgument::L_MACRO
:
10154 case Ttcn::LogArgument::L_STR
:
10155 break; // self reference not possible
10157 case Ttcn::LogArgument::L_VAL
:
10158 case Ttcn::LogArgument::L_MATCH
:
10159 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
10162 case Ttcn::LogArgument::L_REF
: {
10163 Ttcn::Ref_base
*ref
= la
->get_ref();
10164 Common::Assignment
*ass
= ref
->get_refd_assignment();
10165 self_ref
|= (ass
== lhs
);
10168 case Ttcn::LogArgument::L_TI
: {
10169 Ttcn::TemplateInstance
*ti
= la
->get_ti();
10170 Ttcn::Template
*t
= ti
->get_Template();
10171 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10174 // no default please
10175 } // switch la->logargtype
10179 case OPTYPE_DECODE
: { // r1 r2
10180 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10181 self_ref
|= (ass
== lhs
);
10183 case OPTYPE_EXECUTE
: // r1 [v2]
10185 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10189 case OPTYPE_UNDEF_RUNNING
: // r1
10190 case OPTYPE_TMR_READ
: { // r1
10191 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
10192 self_ref
|= (ass
== lhs
);
10195 case OPTYPE_ISCHOSEN_T
: // t1 i2
10196 case OPTYPE_ISBOUND
: // ti1
10197 case OPTYPE_ISVALUE
: // ti1
10198 case OPTYPE_ISPRESENT
: { // ti1
10200 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10201 else t
= u
.expr
.ti1
->get_Template();
10202 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10205 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10207 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10210 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10211 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10215 case NUMBER_OF_OPTYPES
: // can never happen
10216 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10217 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10219 } // switch u.expr.v_optype
10224 string
Value::create_stringRepr()
10226 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10227 switch (valuetype
) {
10229 return string("<erroneous>");
10231 return string("NULL");
10233 if (!parse_only
&& is_asn1()) {
10234 if (u
.val_bool
) return string("TRUE");
10235 else return string("FALSE");
10238 if (u
.val_bool
) return string("true");
10239 else return string("false");
10242 return u
.val_Int
->t_str();
10244 return Real2string(u
.val_Real
);
10247 case V_UNDEF_LOWERID
:
10248 return u
.val_id
->get_name();
10249 case V_NAMEDBITS
: {
10250 string
ret_val("{ ");
10251 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10252 if (i
>0) ret_val
+= ' ';
10253 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10258 string
ret_val('\'');
10259 ret_val
+= *u
.str
.val_str
;
10263 string
ret_val('\'');
10264 ret_val
+= *u
.str
.val_str
;
10268 string
ret_val('\'');
10269 ret_val
+= *u
.str
.val_str
;
10274 return u
.str
.val_str
->get_stringRepr();
10276 return u
.ustr
.val_ustr
->get_stringRepr();
10278 /** \todo stringrepr of V_CHARSYMS */
10279 return string("<sorry, string representation of charsyms "
10280 "not implemented>");
10284 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10286 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10287 if (i
>0) ret_val
+= ' ';
10288 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10293 if (!parse_only
&& is_asn1()) {
10294 string
ret_val(u
.choice
.alt_name
->get_dispname());
10296 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10300 string
ret_val("{ ");
10301 ret_val
+= u
.choice
.alt_name
->get_dispname();
10303 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10310 string
ret_val("{ ");
10311 if (!is_indexed()) {
10312 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10313 if (i
> 0) ret_val
+= ", ";
10314 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10317 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10318 if (i
> 0) ret_val
+= ", ";
10319 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10326 string
ret_val("{ ");
10327 bool asn1_flag
= !parse_only
&& is_asn1();
10328 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10329 if (i
> 0) ret_val
+= ", ";
10330 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10331 ret_val
+= nv
->get_name().get_dispname();
10332 if (asn1_flag
) ret_val
+= ' ';
10333 else ret_val
+= " := ";
10334 ret_val
+= nv
->get_value()->get_stringRepr();
10339 // do not evaluate the reference if it is not done so far
10340 // (e.g. in parse-only mode)
10341 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10342 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10343 else return t_val
->get_stringRepr(); }
10345 return string("omit");
10347 switch (u
.verdict
) {
10349 return string("none");
10351 return string("pass");
10352 case Verdict_INCONC
:
10353 return string("inconc");
10355 return string("fail");
10356 case Verdict_ERROR
:
10357 return string("error");
10359 return string("<unknown verdict value>");
10361 case V_DEFAULT_NULL
:
10363 return string("null");
10365 switch (u
.expr
.v_optype
) {
10367 return string("rnd()");
10368 case OPTYPE_TESTCASENAME
:
10369 return string("testcasename()");
10370 case OPTYPE_UNARYPLUS
:
10371 return create_stringRepr_unary("+");
10372 case OPTYPE_UNARYMINUS
:
10373 return create_stringRepr_unary("-");
10375 return create_stringRepr_unary("not");
10377 return create_stringRepr_unary("not4b");
10378 case OPTYPE_BIT2HEX
:
10379 return create_stringRepr_predef1("bit2hex");
10380 case OPTYPE_BIT2INT
:
10381 return create_stringRepr_predef1("bit2int");
10382 case OPTYPE_BIT2OCT
:
10383 return create_stringRepr_predef1("bit2oct");
10384 case OPTYPE_BIT2STR
:
10385 return create_stringRepr_predef1("bit2str");
10386 case OPTYPE_CHAR2INT
:
10387 return create_stringRepr_predef1("char2int");
10388 case OPTYPE_CHAR2OCT
:
10389 return create_stringRepr_predef1("char2oct");
10390 case OPTYPE_FLOAT2INT
:
10391 return create_stringRepr_predef1("float2int");
10392 case OPTYPE_FLOAT2STR
:
10393 return create_stringRepr_predef1("float2str");
10394 case OPTYPE_HEX2BIT
:
10395 return create_stringRepr_predef1("hex2bit");
10396 case OPTYPE_HEX2INT
:
10397 return create_stringRepr_predef1("hex2int");
10398 case OPTYPE_HEX2OCT
:
10399 return create_stringRepr_predef1("hex2oct");
10400 case OPTYPE_HEX2STR
:
10401 return create_stringRepr_predef1("hex2str");
10402 case OPTYPE_INT2CHAR
:
10403 return create_stringRepr_predef1("int2char");
10404 case OPTYPE_INT2FLOAT
:
10405 return create_stringRepr_predef1("int2float");
10406 case OPTYPE_INT2STR
:
10407 return create_stringRepr_predef1("int2str");
10408 case OPTYPE_INT2UNICHAR
:
10409 return create_stringRepr_predef1("int2unichar");
10410 case OPTYPE_OCT2BIT
:
10411 return create_stringRepr_predef1("oct2bit");
10412 case OPTYPE_OCT2CHAR
:
10413 return create_stringRepr_predef1("oct2char");
10414 case OPTYPE_OCT2HEX
:
10415 return create_stringRepr_predef1("oct2hex");
10416 case OPTYPE_OCT2INT
:
10417 return create_stringRepr_predef1("oct2int");
10418 case OPTYPE_OCT2STR
:
10419 return create_stringRepr_predef1("oct2str");
10420 case OPTYPE_GET_STRINGENCODING
:
10421 return create_stringRepr_predef1("get_stringencoding");
10422 case OPTYPE_REMOVE_BOM
:
10423 return create_stringRepr_predef1("remove_bom");
10424 case OPTYPE_ENCODE_BASE64
: {
10425 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10426 else return create_stringRepr_predef1("encode_base64");
10428 case OPTYPE_DECODE_BASE64
:
10429 return create_stringRepr_predef1("decode_base64");
10430 case OPTYPE_OCT2UNICHAR
:{
10431 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10432 else return create_stringRepr_predef1("oct2unichar");
10434 case OPTYPE_UNICHAR2OCT
: {
10435 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10436 else return create_stringRepr_predef1("unichar2oct");
10438 case OPTYPE_ENCVALUE_UNICHAR
: {
10439 if (u
.expr
.v2
) return create_stringRepr_predef2("encvalue_unichar");
10440 else return create_stringRepr_predef1("encvalue_unichar");
10442 case OPTYPE_DECVALUE_UNICHAR
: {
10444 string
ret_val("decvalue_unichar");
10446 ret_val
+= u
.expr
.v1
->get_stringRepr();
10448 ret_val
+= u
.expr
.v2
->get_stringRepr();
10450 ret_val
+= u
.expr
.v3
->get_stringRepr();
10454 else return create_stringRepr_predef2("decvalue_unichar");
10456 case OPTYPE_STR2BIT
:
10457 return create_stringRepr_predef1("str2bit");
10458 case OPTYPE_STR2FLOAT
:
10459 return create_stringRepr_predef1("str2float");
10460 case OPTYPE_STR2HEX
:
10461 return create_stringRepr_predef1("str2hex");
10462 case OPTYPE_STR2INT
:
10463 return create_stringRepr_predef1("str2int");
10464 case OPTYPE_STR2OCT
:
10465 return create_stringRepr_predef1("str2oct");
10466 case OPTYPE_UNICHAR2INT
:
10467 return create_stringRepr_predef1("unichar2int");
10468 case OPTYPE_UNICHAR2CHAR
:
10469 return create_stringRepr_predef1("unichar2char");
10470 case OPTYPE_ENUM2INT
:
10471 return create_stringRepr_predef1("enum2int");
10472 case OPTYPE_ENCODE
:
10473 return create_stringRepr_predef1("encvalue");
10474 case OPTYPE_DECODE
:
10475 return create_stringRepr_predef2("decvalue");
10476 case OPTYPE_RNDWITHVAL
:
10477 return create_stringRepr_predef1("rnd");
10479 return create_stringRepr_infix("+");
10480 case OPTYPE_SUBTRACT
:
10481 return create_stringRepr_infix("-");
10482 case OPTYPE_MULTIPLY
:
10483 return create_stringRepr_infix("*");
10484 case OPTYPE_DIVIDE
:
10485 return create_stringRepr_infix("/");
10487 return create_stringRepr_infix("mod");
10489 return create_stringRepr_infix("rem");
10490 case OPTYPE_CONCAT
:
10491 return create_stringRepr_infix("&");
10493 return create_stringRepr_infix("==");
10495 return create_stringRepr_infix("<");
10497 return create_stringRepr_infix(">");
10499 return create_stringRepr_infix("!=");
10501 return create_stringRepr_infix(">=");
10503 return create_stringRepr_infix("<=");
10505 return create_stringRepr_infix("and");
10507 return create_stringRepr_infix("or");
10509 return create_stringRepr_infix("xor");
10511 return create_stringRepr_infix("and4b");
10513 return create_stringRepr_infix("or4b");
10515 return create_stringRepr_infix("xor4b");
10517 return create_stringRepr_infix("<<");
10519 return create_stringRepr_infix(">>");
10521 return create_stringRepr_infix("<@");
10523 return create_stringRepr_infix("@>");
10524 case OPTYPE_INT2BIT
:
10525 return create_stringRepr_predef2("int2bit");
10526 case OPTYPE_INT2HEX
:
10527 return create_stringRepr_predef2("int2hex");
10528 case OPTYPE_INT2OCT
:
10529 return create_stringRepr_predef2("int2oct");
10530 case OPTYPE_SUBSTR
: {
10531 string
ret_val("substr(");
10532 u
.expr
.ti1
->append_stringRepr(ret_val
);
10534 ret_val
+= u
.expr
.v2
->get_stringRepr();
10536 ret_val
+= u
.expr
.v3
->get_stringRepr();
10540 case OPTYPE_REGEXP
: {
10541 string
ret_val("regexp(");
10542 u
.expr
.ti1
->append_stringRepr(ret_val
);
10544 u
.expr
.t2
->append_stringRepr(ret_val
);
10546 ret_val
+= u
.expr
.v3
->get_stringRepr();
10550 case OPTYPE_DECOMP
: {
10551 string
ret_val("decomp(");
10552 ret_val
+= u
.expr
.v1
->get_stringRepr();
10554 ret_val
+= u
.expr
.v2
->get_stringRepr();
10556 ret_val
+= u
.expr
.v3
->get_stringRepr();
10560 case OPTYPE_REPLACE
: {
10561 string
ret_val("replace(");
10562 u
.expr
.ti1
->append_stringRepr(ret_val
);
10564 ret_val
+= u
.expr
.v2
->get_stringRepr();
10566 ret_val
+= u
.expr
.v3
->get_stringRepr();
10568 u
.expr
.ti4
->append_stringRepr(ret_val
);
10572 case OPTYPE_ISPRESENT
: {
10573 string
ret_val("ispresent(");
10574 u
.expr
.ti1
->append_stringRepr(ret_val
);
10577 case OPTYPE_ISCHOSEN
: {
10578 string
ret_val("ischosen(");
10579 ret_val
+= u
.expr
.r1
->get_dispname();
10581 ret_val
+= u
.expr
.i2
->get_dispname();
10584 case OPTYPE_ISCHOSEN_V
: {
10585 string
ret_val("ischosen(");
10586 ret_val
+= u
.expr
.v1
->get_stringRepr();
10588 ret_val
+= u
.expr
.i2
->get_dispname();
10591 case OPTYPE_ISCHOSEN_T
: {
10592 string
ret_val("ischosen(");
10593 ret_val
+= u
.expr
.t1
->get_stringRepr();
10595 ret_val
+= u
.expr
.i2
->get_dispname();
10598 case OPTYPE_LENGTHOF
: {
10599 string
ret_val("lengthof(");
10600 u
.expr
.ti1
->append_stringRepr(ret_val
);
10603 case OPTYPE_SIZEOF
: {
10604 string
ret_val("sizeof(");
10605 u
.expr
.ti1
->append_stringRepr(ret_val
);
10608 case OPTYPE_ISVALUE
: {
10609 string
ret_val("isvalue(");
10610 u
.expr
.ti1
->append_stringRepr(ret_val
);
10613 case OPTYPE_VALUEOF
: {
10614 string
ret_val("valueof(");
10615 u
.expr
.ti1
->append_stringRepr(ret_val
);
10618 case OPTYPE_LOG2STR
:
10619 return string("log2str(...)");
10620 case OPTYPE_MATCH
: {
10621 string
ret_val("match(");
10622 ret_val
+= u
.expr
.v1
->get_stringRepr();
10624 u
.expr
.t2
->append_stringRepr(ret_val
);
10627 case OPTYPE_TTCN2STRING
: {
10628 string
ret_val("ttcn2string(");
10629 u
.expr
.ti1
->append_stringRepr(ret_val
);
10633 case OPTYPE_UNDEF_RUNNING
:
10634 return u
.expr
.r1
->get_dispname() + ".running";
10635 case OPTYPE_COMP_NULL
:
10636 return string("null");
10637 case OPTYPE_COMP_MTC
:
10638 return string("mtc");
10639 case OPTYPE_COMP_SYSTEM
:
10640 return string("system");
10641 case OPTYPE_COMP_SELF
:
10642 return string("self");
10643 case OPTYPE_COMP_CREATE
: {
10644 string
ret_val(u
.expr
.r1
->get_dispname());
10645 ret_val
+= ".create";
10646 if (u
.expr
.v2
|| u
.expr
.v3
) {
10648 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10649 else ret_val
+= '-';
10652 ret_val
+= u
.expr
.v3
->get_stringRepr();
10656 if (u
.expr
.b4
) ret_val
+= " alive";
10658 case OPTYPE_COMP_RUNNING
:
10659 return u
.expr
.v1
->get_stringRepr() + ".running";
10660 case OPTYPE_COMP_RUNNING_ANY
:
10661 return string("any component.running");
10662 case OPTYPE_COMP_RUNNING_ALL
:
10663 return string("all component.running");
10664 case OPTYPE_COMP_ALIVE
:
10665 return u
.expr
.v1
->get_stringRepr() + ".alive";
10666 case OPTYPE_COMP_ALIVE_ANY
:
10667 return string("any component.alive");
10668 case OPTYPE_COMP_ALIVE_ALL
:
10669 return string("all component.alive");
10670 case OPTYPE_TMR_READ
:
10671 return u
.expr
.r1
->get_dispname() + ".read";
10672 case OPTYPE_TMR_RUNNING
:
10673 return u
.expr
.r1
->get_dispname() + ".running";
10674 case OPTYPE_TMR_RUNNING_ANY
:
10675 return string("any timer.running");
10676 case OPTYPE_GETVERDICT
:
10677 return string("getverdict");
10678 case OPTYPE_ACTIVATE
: {
10679 string
ret_val("activate(");
10680 ret_val
+= u
.expr
.r1
->get_dispname();
10683 case OPTYPE_ACTIVATE_REFD
: {
10684 string
ret_val("activate(derefer(");
10685 ret_val
+= u
.expr
.v1
->get_stringRepr();
10687 if (u
.expr
.state
== EXPR_CHECKED
) {
10688 if (u
.expr
.ap_list2
) {
10689 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10690 for (size_t i
= 0; i
< nof_pars
; i
++) {
10691 if (i
> 0) ret_val
+= ", ";
10692 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10696 if (u
.expr
.t_list2
) {
10697 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10698 for (size_t i
= 0; i
< nof_pars
; i
++) {
10699 if (i
> 0) ret_val
+= ", ";
10700 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10706 case OPTYPE_EXECUTE
: {
10707 string
ret_val("execute(");
10708 ret_val
+= u
.expr
.r1
->get_dispname();
10711 ret_val
+= u
.expr
.v2
->get_stringRepr();
10715 case OPTYPE_EXECUTE_REFD
: {
10716 string
ret_val("execute(derefers(");
10717 ret_val
+= u
.expr
.v1
->get_stringRepr();
10719 if (u
.expr
.state
== EXPR_CHECKED
) {
10720 if (u
.expr
.ap_list2
) {
10721 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10722 for (size_t i
= 0; i
< nof_pars
; i
++) {
10723 if (i
> 0) ret_val
+= ", ";
10724 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10728 if (u
.expr
.t_list2
) {
10729 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10730 for (size_t i
= 0; i
< nof_pars
; i
++) {
10731 if (i
> 0) ret_val
+= ", ";
10732 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10739 ret_val
+= u
.expr
.v3
->get_stringRepr();
10743 case OPTYPE_PROF_RUNNING
:
10744 return string("@profiler.running");
10746 return string("<unsupported optype>");
10747 } // switch u.expr.v_optype
10750 case MACRO_MODULEID
:
10751 return string("%moduleId");
10752 case MACRO_FILENAME
:
10753 return string("%fileName");
10754 case MACRO_BFILENAME
:
10755 return string("__BFILE__");
10756 case MACRO_FILEPATH
:
10757 return string("__FILE__");
10758 case MACRO_LINENUMBER
:
10759 return string("%lineNumber");
10760 case MACRO_LINENUMBER_C
:
10761 return string("__LINE__");
10762 case MACRO_DEFINITIONID
:
10763 return string("%definitionId");
10765 return string("__SCOPE__");
10766 case MACRO_TESTCASEID
:
10767 return string("%testcaseId");
10769 return string("<unknown macro>");
10770 } // switch u.macro
10772 return string('-');
10776 string
ret_val("refers(");
10777 ret_val
+= u
.refd_fat
->get_assname();
10782 ret_val
+= u
.invoke
.v
->get_stringRepr();
10783 ret_val
+= ".apply(";
10784 if (u
.invoke
.ap_list
) {
10785 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10786 for (size_t i
= 0; i
< nof_pars
; i
++) {
10787 if (i
> 0) ret_val
+= ", ";
10788 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10790 } else if (u
.invoke
.t_list
) {
10791 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10792 for (size_t i
= 0; i
< nof_pars
; i
++) {
10793 if (i
> 0) ret_val
+= ", ";
10794 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10800 string
ret_val("refers(");
10801 ret_val
+= u
.refered
->get_dispname();
10805 return string("<unsupported valuetype>");
10806 } // switch valuetype
10809 string
Value::create_stringRepr_unary(const char *operator_str
)
10811 string
ret_val(operator_str
);
10813 ret_val
+= u
.expr
.v1
->get_stringRepr();
10818 string
Value::create_stringRepr_infix(const char *operator_str
)
10820 string
ret_val('(');
10821 ret_val
+= u
.expr
.v1
->get_stringRepr();
10823 ret_val
+= operator_str
;
10825 ret_val
+= u
.expr
.v2
->get_stringRepr();
10830 string
Value::create_stringRepr_predef1(const char *function_name
)
10832 string
ret_val(function_name
);
10834 if (u
.expr
.v_optype
== OPTYPE_ENCODE
|| u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
) { // ti1, not v1
10835 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10837 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10842 string
Value::create_stringRepr_predef2(const char *function_name
)
10844 string
ret_val(function_name
);
10846 ret_val
+= u
.expr
.v1
->get_stringRepr();
10848 ret_val
+= u
.expr
.v2
->get_stringRepr();
10853 bool Value::operator==(Value
& val
)
10855 Value
*left
= get_value_refd_last();
10856 Type
*left_governor
= left
->get_my_governor();
10857 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10858 Value
*right
= val
.get_value_refd_last();
10859 Type
*right_governor
= right
->get_my_governor();
10860 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10861 if (left_governor
&& right_governor
10862 && !left_governor
->is_compatible(right_governor
, NULL
)
10863 && !right_governor
->is_compatible(left_governor
, NULL
))
10864 FATAL_ERROR("Value::operator==");
10866 // Not-A-Value is not equal to anything (NaN analogy:)
10867 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10870 switch (left
->valuetype
) {
10873 case V_DEFAULT_NULL
:
10876 return left
->valuetype
== right
->valuetype
;
10878 return right
->valuetype
== V_BOOL
&&
10879 left
->get_val_bool() == right
->get_val_bool();
10881 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10882 == *right
->get_val_Int();
10884 return right
->valuetype
== V_REAL
&&
10885 left
->get_val_Real() == right
->get_val_Real();
10887 switch (right
->valuetype
) {
10889 return left
->get_val_str() == right
->get_val_str();
10891 return right
->get_val_ustr() == left
->get_val_str();
10893 return right
->get_val_iso2022str() == left
->get_val_str();
10900 return left
->valuetype
== right
->valuetype
&&
10901 left
->get_val_str() == right
->get_val_str();
10903 switch (right
->valuetype
) {
10905 return left
->get_val_ustr() == right
->get_val_str();
10907 return left
->get_val_ustr() == right
->get_val_ustr();
10909 return left
->get_val_ustr() == right
->get_val_iso2022str();
10914 switch (right
->valuetype
) {
10916 return left
->get_val_iso2022str() == right
->get_val_str();
10918 // The appropriate operator==() is missing. The operands are swapped,
10919 // but it shouldn't be a problem.
10920 return right
->get_val_ustr() == left
->get_val_iso2022str();
10922 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10927 return right
->valuetype
== V_ENUM
&&
10928 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10931 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10932 vector
<string
> act
, other
;
10933 get_oid_comps(act
);
10934 val
.get_oid_comps(other
);
10935 size_t act_size
= act
.size(), other_size
= other
.size();
10937 if (act_size
== other_size
) {
10939 for (size_t i
= 0; i
< act_size
; i
++)
10940 if (*act
[i
] != *other
[i
]) {
10944 } else ret_val
= false;
10945 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10947 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10950 } else return false;
10952 return right
->valuetype
== V_CHOICE
&&
10953 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10954 *(left
->get_alt_value()) == *(right
->get_alt_value());
10957 if (!left_governor
) FATAL_ERROR("Value::operator==");
10958 if (left
->valuetype
!= right
->valuetype
) return false;
10959 size_t nof_comps
= left_governor
->get_nof_comps();
10960 for (size_t i
= 0; i
< nof_comps
; i
++) {
10961 Value
*lval
= NULL
, *rval
= NULL
;
10962 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10963 const Identifier
& field_name
= cfl
->get_name();
10964 if (left
->has_comp_withName(field_name
)) {
10965 lval
= left
->get_comp_value_byName(field_name
);
10966 if (right
->has_comp_withName(field_name
)) {
10967 rval
= right
->get_comp_value_byName(field_name
);
10968 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10969 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10971 else if (!(*lval
== *rval
))
10974 if (cfl
->has_default()) {
10975 if (!(*lval
== *cfl
->get_defval()))
10978 if (lval
->valuetype
!= V_OMIT
)
10983 if(right
->has_comp_withName(field_name
)) {
10984 rval
= right
->get_comp_value_byName(field_name
);
10985 if(cfl
->has_default()) {
10986 if(rval
->valuetype
==V_OMIT
) return false;
10988 lval
= cfl
->get_defval();
10989 if (!(*lval
==*rval
)) return false;
10998 if (left
->valuetype
!= right
->valuetype
) return false;
10999 size_t ncomps
= get_nof_comps();
11000 if (ncomps
!= right
->get_nof_comps()) return false;
11002 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
11003 bool found
= false;
11004 map
<IndexedValue
*, void> uncovered
;
11005 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
11006 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
11008 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
11010 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
11011 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
11012 *(right
->get_comp_byIndex(i
)) &&
11013 *(uncovered
.get_nth_key(j
)->get_index()) ==
11014 *(right
->get_index_byIndex(i
))) {
11016 uncovered
.erase(uncovered
.get_nth_key(j
));
11024 } else if (left
->is_indexed() || right
->is_indexed()) {
11025 Value
* indexed_one
= 0;
11026 Value
* not_indexed_one
= 0;
11028 if(left
->is_indexed()) { // left is indexed, right is not
11029 indexed_one
= left
;
11030 not_indexed_one
= right
;
11031 } else { // right indexed, left is not
11032 indexed_one
= right
;
11033 not_indexed_one
= left
;
11036 for(size_t i
= 0; i
< ncomps
; ++i
) {
11037 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
11038 if(!(ind
->valuetype
== V_INT
&&
11039 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
11040 *(indexed_one
->get_comp_byIndex(i
))))
11044 } else { // none of them is indexed
11045 for (size_t i
= 0; i
< ncomps
; i
++) {
11046 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
11053 if (right
->valuetype
!= V_SETOF
) return false;
11054 size_t ncomps
= get_nof_comps();
11055 if (ncomps
!= right
->get_nof_comps()) return false;
11056 if (ncomps
== 0) return true;
11057 map
<size_t, void> uncovered
;
11058 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
11059 for (size_t i
= 0; i
< ncomps
; i
++) {
11060 Value
*left_item
= left
->get_comp_byIndex(i
);
11061 bool pair_found
= false;
11062 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
11063 size_t right_index
= uncovered
.get_nth_key(j
);
11064 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
11065 uncovered
.erase(right_index
);
11077 return right
->valuetype
== V_VERDICT
&&
11078 left
->get_val_verdict() == right
->get_val_verdict();
11082 return left
->valuetype
== right
->valuetype
&&
11083 left
->get_refd_assignment() == right
->get_refd_assignment();
11085 FATAL_ERROR("Value::operator==");
11090 bool Value::operator<(Value
& val
)
11092 Value
*left
= get_value_refd_last();
11093 Type
*left_governor
= left
->get_my_governor();
11094 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
11095 Value
*right
= val
.get_value_refd_last();
11096 Type
*right_governor
= right
->get_my_governor();
11097 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
11098 if (left
->get_valuetype() != right
->get_valuetype())
11099 FATAL_ERROR("Value::operator<");
11102 return *left
->get_val_Int() < *right
->get_val_Int();
11104 return (left
->get_val_Real() < right
->get_val_Real());
11106 if(!left_governor
|| !right_governor
)
11107 FATAL_ERROR("Value::operator<");
11108 if(left_governor
!=right_governor
)
11109 FATAL_ERROR("Value::operator<");
11110 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
11111 right_governor
->get_enum_val_byId(*right
->get_val_id()));
11113 FATAL_ERROR("Value::operator<");
11118 bool Value::is_string_type(Type::expected_value_t exp_val
)
11120 switch (get_expr_returntype(exp_val
)) {
11132 void Value::generate_code_expr(expression_struct
*expr
)
11134 if (has_single_expr()) {
11135 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
11137 switch (valuetype
) {
11139 generate_code_expr_expr(expr
);
11147 const string
& tmp_id
= get_temporary_id();
11148 const char *tmp_id_str
= tmp_id
.c_str();
11149 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11150 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
11151 set_genname_recursive(tmp_id
);
11152 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11153 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11156 const string
& tmp_id
= get_temporary_id();
11157 const char *tmp_id_str
= tmp_id
.c_str();
11158 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
11160 set_genname_recursive(tmp_id
);
11161 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11162 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11165 if (!get_needs_conversion()) {
11166 u
.ref
.ref
->generate_code_const_ref(expr
);
11168 Type
*my_gov
= get_expr_governor_last();
11169 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
11170 ->get_field_type(u
.ref
.ref
->get_subrefs(),
11171 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
11172 // Make sure that nothing goes wrong.
11173 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
11174 FATAL_ERROR("Value::generate_code_expr()");
11175 expression_struct expr_tmp
;
11176 Code::init_expr(&expr_tmp
);
11177 const string
& tmp_id1
= get_temporary_id();
11178 const char *tmp_id_str1
= tmp_id1
.c_str();
11179 const string
& tmp_id2
= get_temporary_id();
11180 const char *tmp_id_str2
= tmp_id2
.c_str();
11181 expr
->preamble
= mputprintf(expr
->preamble
,
11182 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
11184 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11185 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
11186 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11187 expr
->preamble
= mputprintf(expr
->preamble
,
11189 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11190 "and `%s' are not compatible at run-time\");\n",
11191 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11192 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
11193 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
11194 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
11195 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11199 generate_code_expr_invoke(expr
);
11202 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
11207 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
11209 generate_code_expr(expr
);
11210 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11211 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11214 bool Value::can_use_increment(Reference
*ref
) const
11216 if (valuetype
!= V_EXPR
) {
11219 switch (u
.expr
.v_optype
) {
11221 case OPTYPE_SUBTRACT
:
11226 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11227 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11228 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11229 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11230 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11231 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11237 char *Value::generate_code_init(char *str
, const char *name
)
11239 if (get_code_generated()) return str
;
11241 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11243 switch (valuetype
) {
11257 case V_DEFAULT_NULL
:
11262 // These values have a single string equivalent.
11263 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11266 if (u
.val_Int
->is_native_fit())
11267 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11269 // It's always an INTEGER.
11270 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11271 "}\n", get_single_expr().c_str(), name
);
11275 expression_struct expr
;
11276 Code::init_expr(&expr
);
11277 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11278 generate_code_expr(&expr
);
11279 str
= Code::merge_free_expr(str
, &expr
);
11282 str
= generate_code_init_choice(str
, name
);
11286 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11287 else str
= generate_code_init_indexed(str
, name
);
11290 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11291 else str
= generate_code_init_indexed(str
, name
);
11295 str
= generate_code_init_se(str
, name
);
11298 str
= generate_code_init_refd(str
, name
);
11302 case MACRO_TESTCASEID
:
11303 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11306 // all others must already be evaluated away
11307 FATAL_ERROR("Value::generate_code_init()");
11311 // unbound value, don't generate anything
11314 FATAL_ERROR("Value::generate_code_init()");
11317 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11319 set_code_generated();
11323 char *Value::rearrange_init_code(char *str
, Common::Module
* usage_mod
)
11325 switch (valuetype
) {
11327 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11329 str
= parlist
->rearrange_init_code(str
, usage_mod
);
11333 str
= u
.invoke
.v
->rearrange_init_code(str
, usage_mod
);
11334 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, usage_mod
);
11337 switch (u
.expr
.v_optype
) {
11338 case OPTYPE_UNARYPLUS
:
11339 case OPTYPE_UNARYMINUS
:
11342 case OPTYPE_BIT2HEX
:
11343 case OPTYPE_BIT2INT
:
11344 case OPTYPE_BIT2OCT
:
11345 case OPTYPE_BIT2STR
:
11346 case OPTYPE_CHAR2INT
:
11347 case OPTYPE_CHAR2OCT
:
11348 case OPTYPE_FLOAT2INT
:
11349 case OPTYPE_FLOAT2STR
:
11350 case OPTYPE_HEX2BIT
:
11351 case OPTYPE_HEX2INT
:
11352 case OPTYPE_HEX2OCT
:
11353 case OPTYPE_HEX2STR
:
11354 case OPTYPE_INT2CHAR
:
11355 case OPTYPE_INT2FLOAT
:
11356 case OPTYPE_INT2STR
:
11357 case OPTYPE_INT2UNICHAR
:
11358 case OPTYPE_OCT2BIT
:
11359 case OPTYPE_OCT2CHAR
:
11360 case OPTYPE_OCT2HEX
:
11361 case OPTYPE_OCT2INT
:
11362 case OPTYPE_OCT2STR
:
11363 case OPTYPE_STR2BIT
:
11364 case OPTYPE_STR2FLOAT
:
11365 case OPTYPE_STR2HEX
:
11366 case OPTYPE_STR2INT
:
11367 case OPTYPE_STR2OCT
:
11368 case OPTYPE_UNICHAR2INT
:
11369 case OPTYPE_UNICHAR2CHAR
:
11370 case OPTYPE_ENUM2INT
:
11371 case OPTYPE_ISCHOSEN_V
:
11372 case OPTYPE_GET_STRINGENCODING
:
11373 case OPTYPE_REMOVE_BOM
:
11374 case OPTYPE_DECODE_BASE64
:
11375 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11377 case OPTYPE_DECODE
: {
11378 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11379 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11380 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11382 parlist
= u
.expr
.r2
->get_parlist();
11383 ass
= u
.expr
.r2
->get_refd_assignment();
11384 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11387 case OPTYPE_SUBTRACT
:
11388 case OPTYPE_MULTIPLY
:
11389 case OPTYPE_DIVIDE
:
11392 case OPTYPE_CONCAT
:
11409 case OPTYPE_INT2BIT
:
11410 case OPTYPE_INT2HEX
:
11411 case OPTYPE_INT2OCT
:
11412 //case OPTYPE_DECODE:
11413 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11414 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11416 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11417 case OPTYPE_OCT2UNICHAR
:
11418 case OPTYPE_ENCODE_BASE64
:
11419 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11420 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11422 case OPTYPE_SUBSTR
:
11423 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11424 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11425 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11427 case OPTYPE_REGEXP
:
11428 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11429 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11430 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11432 case OPTYPE_DECOMP
:
11433 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11434 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11435 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11437 case OPTYPE_REPLACE
:
11438 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11439 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11440 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11441 str
= u
.expr
.ti4
->rearrange_init_code(str
, usage_mod
);
11443 case OPTYPE_LENGTHOF
:
11444 case OPTYPE_SIZEOF
:
11445 case OPTYPE_VALUEOF
:
11446 case OPTYPE_ENCODE
:
11447 case OPTYPE_ISPRESENT
:
11448 case OPTYPE_TTCN2STRING
:
11449 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11451 case OPTYPE_ENCVALUE_UNICHAR
:
11452 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11453 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11455 case OPTYPE_DECVALUE_UNICHAR
: {
11456 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11457 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11458 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11460 parlist
= u
.expr
.r2
->get_parlist();
11461 ass
= u
.expr
.r2
->get_refd_assignment();
11462 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11463 if (u
.expr
.v3
) str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11465 case OPTYPE_ISCHOSEN_T
:
11466 str
= u
.expr
.t1
->rearrange_init_code(str
, usage_mod
);
11469 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11470 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11473 // other kinds of expressions cannot appear within templates
11483 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11484 size_t& blockcount
)
11486 char *s2
= memptystr();
11487 char *s1
= generate_code_tmp(NULL
, s2
);
11489 if (blockcount
== 0) {
11490 str
= mputstr(str
, "{\n");
11493 str
= mputstr(str
, s2
);
11496 str
=mputstr(str
, prefix
);
11497 str
=mputstr(str
, s1
);
11502 char *Value::generate_code_tmp(char *str
, char*& init
)
11504 expression_struct expr
;
11505 Code::init_expr(&expr
);
11506 generate_code_expr_mandatory(&expr
);
11507 if (expr
.preamble
|| expr
.postamble
) {
11508 if (valuetype
== V_EXPR
&&
11509 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11510 // a temporary variable is already introduced
11511 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11512 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11513 str
= mputstr(str
, expr
.expr
);
11515 const string
& tmp_id
= get_temporary_id();
11516 const char *tmp_id_str
= tmp_id
.c_str();
11517 init
= mputprintf(init
, "%s %s;\n"
11519 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11520 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11522 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11523 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11524 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11525 init
= mputstr(init
, "}\n");
11526 str
= mputstr(str
, tmp_id_str
);
11528 } else str
= mputstr(str
, expr
.expr
);
11529 Code::free_expr(&expr
);
11533 void Value::generate_code_log(expression_struct
*expr
)
11535 if (explicit_cast_needed()) {
11536 char *expr_backup
= expr
->expr
;
11538 generate_code_expr(expr
);
11539 const string
& tmp_id
= get_temporary_id();
11540 const char *tmp_id_str
= tmp_id
.c_str();
11541 // We have to create a temporary object, because the parser of GCC
11542 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11543 // constructor call that is, this does not work: type(...).log(); but
11544 // this works: type tmp(...); tmp.log();.
11545 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11546 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11549 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11551 generate_code_expr(expr
);
11553 expr
->expr
= mputstr(expr
->expr
, ".log()");
11556 void Value::generate_code_log_match(expression_struct
*expr
)
11558 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11559 FATAL_ERROR("Value::generate_code_log_match()");
11560 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11561 // compliance the whole code-generation should be checked. Standalone
11562 // constructs like: "A(a[0].f());" should be avoided. The current
11563 // solution for HK38721 uses an additional assignment to overcome the
11564 // issue. The generated code will be slower, but it's needed for old GCC
11565 // versions in specific circumstances.
11566 if (u
.expr
.t2
->needs_temp_ref()) {
11567 char *expr_backup
= expr
->expr
;
11569 u
.expr
.t2
->generate_code(expr
);
11570 const string
& tmp_id
= get_temporary_id();
11571 const char *tmp_id_str
= tmp_id
.c_str();
11572 expr
->preamble
= mputprintf(expr
->preamble
,
11573 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11574 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11576 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11578 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11579 // some reason "(A(NS::B)).a(C);" compiles fine.
11580 expr
->expr
= mputc(expr
->expr
, '(');
11581 u
.expr
.t2
->generate_code(expr
);
11582 expr
->expr
= mputc(expr
->expr
, ')');
11584 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11585 u
.expr
.v1
->generate_code_expr(expr
);
11586 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11589 void Value::generate_code_expr_expr(expression_struct
*expr
)
11591 switch (u
.expr
.v_optype
) {
11593 generate_code_expr_rnd(expr
, 0);
11595 case OPTYPE_UNARYPLUS
:
11596 // same as without the '+' operator
11597 u
.expr
.v1
->generate_code_expr(expr
);
11599 case OPTYPE_UNARYMINUS
:
11600 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11603 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11606 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11608 case OPTYPE_BIT2HEX
:
11609 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11611 case OPTYPE_BIT2INT
:
11612 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11614 case OPTYPE_BIT2OCT
:
11615 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11617 case OPTYPE_BIT2STR
:
11618 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11620 case OPTYPE_CHAR2INT
:
11621 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11623 case OPTYPE_CHAR2OCT
:
11624 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11626 case OPTYPE_FLOAT2INT
:
11627 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11629 case OPTYPE_FLOAT2STR
:
11630 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11632 case OPTYPE_HEX2BIT
:
11633 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11635 case OPTYPE_HEX2INT
:
11636 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11638 case OPTYPE_HEX2OCT
:
11639 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11641 case OPTYPE_HEX2STR
:
11642 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11644 case OPTYPE_INT2CHAR
:
11645 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11647 case OPTYPE_INT2FLOAT
:
11648 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11650 case OPTYPE_INT2STR
:
11651 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11653 case OPTYPE_INT2UNICHAR
:
11654 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11656 case OPTYPE_OCT2BIT
:
11657 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11659 case OPTYPE_OCT2CHAR
:
11660 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11662 case OPTYPE_GET_STRINGENCODING
:
11663 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11665 case OPTYPE_REMOVE_BOM
:
11666 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11668 case OPTYPE_ENCODE_BASE64
:
11670 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11672 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11674 case OPTYPE_DECODE_BASE64
:
11675 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11677 case OPTYPE_OCT2UNICHAR
:
11679 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11681 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11683 case OPTYPE_UNICHAR2OCT
:
11685 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11687 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11689 case OPTYPE_ENCVALUE_UNICHAR
:
11690 generate_code_expr_encvalue_unichar(expr
);
11692 case OPTYPE_DECVALUE_UNICHAR
:
11693 generate_code_expr_decvalue_unichar(expr
);
11695 case OPTYPE_OCT2HEX
:
11696 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11698 case OPTYPE_OCT2INT
:
11699 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11701 case OPTYPE_OCT2STR
:
11702 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11704 case OPTYPE_STR2BIT
:
11705 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11707 case OPTYPE_STR2FLOAT
:
11708 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11710 case OPTYPE_STR2HEX
:
11711 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11713 case OPTYPE_STR2INT
:
11714 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11716 case OPTYPE_STR2OCT
:
11717 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11719 case OPTYPE_UNICHAR2INT
:
11720 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11722 case OPTYPE_UNICHAR2CHAR
:
11723 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11725 case OPTYPE_ENUM2INT
: {
11726 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11727 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11728 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11729 enum_type
->get_genname_value(my_scope
).c_str());
11730 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11731 expr
->expr
= mputc(expr
->expr
, ')');
11733 case OPTYPE_ENCODE
:
11734 generate_code_expr_encode(expr
);
11736 case OPTYPE_DECODE
:
11737 generate_code_expr_decode(expr
);
11739 case OPTYPE_RNDWITHVAL
:
11740 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11743 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11745 case OPTYPE_SUBTRACT
:
11746 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11748 case OPTYPE_MULTIPLY
:
11749 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11751 case OPTYPE_DIVIDE
:
11752 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11755 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11758 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11760 case OPTYPE_CONCAT
:
11761 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11764 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11767 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11770 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11773 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11776 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11779 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11783 generate_code_expr_and_or(expr
);
11786 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11789 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11792 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11795 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11798 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11801 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11804 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11807 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11809 case OPTYPE_INT2BIT
:
11810 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11812 case OPTYPE_INT2HEX
:
11813 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11815 case OPTYPE_INT2OCT
:
11816 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11818 case OPTYPE_SUBSTR
:
11819 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11820 else generate_code_expr_substr_replace_compat(expr
);
11822 case OPTYPE_REGEXP
:
11823 generate_code_expr_regexp(expr
);
11825 case OPTYPE_DECOMP
:
11826 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11828 case OPTYPE_REPLACE
:
11829 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11830 else generate_code_expr_substr_replace_compat(expr
);
11832 case OPTYPE_ISCHOSEN
: // r1 i2
11833 FATAL_ERROR("Value::generate_code_expr_expr()");
11835 case OPTYPE_ISCHOSEN_V
: // v1 i2
11836 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11837 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11838 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11839 u
.expr
.i2
->get_name().c_str());
11841 case OPTYPE_ISCHOSEN_T
: // t1 i2
11842 u
.expr
.t1
->generate_code_expr(expr
);
11843 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11844 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11845 u
.expr
.i2
->get_name().c_str());
11847 case OPTYPE_ISPRESENT
:
11848 case OPTYPE_ISBOUND
: {
11849 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11850 ->get_templatetype();
11851 if (temp
== Template::SPECIFIC_VALUE
) {
11852 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11853 ->get_specific_value();
11854 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11855 Ttcn::Reference
* reference
=
11856 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11858 reference
->generate_code_ispresentbound(expr
, false,
11859 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11863 } else if (temp
== Template::TEMPLATE_REFD
){
11864 Ttcn::Reference
* reference
=
11865 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11866 ->get_reference());
11868 reference
->generate_code_ispresentbound(expr
, true,
11869 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11875 case OPTYPE_LENGTHOF
: // ti1
11876 // fall through, separated later
11877 case OPTYPE_SIZEOF
: // ti1
11878 // fall through, separated later
11879 case OPTYPE_ISVALUE
: { // ti1
11880 if (u
.expr
.ti1
->is_only_specific_value()) {
11881 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11882 bool cast_needed
= t_val
->explicit_cast_needed(
11883 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11885 // the ambiguous C++ expression is converted to the value class
11886 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11887 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11890 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11891 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11892 t_val
->generate_code_expr(expr
);
11894 t_val
->generate_code_expr_mandatory(expr
);
11897 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11899 else u
.expr
.ti1
->generate_code(expr
);
11901 switch (u
.expr
.v_optype
) {
11902 case OPTYPE_ISBOUND
:
11903 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11905 case OPTYPE_ISPRESENT
:
11906 expr
->expr
=mputprintf(expr
->expr
, ".is_present()");
11908 case OPTYPE_SIZEOF
:
11909 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11911 case OPTYPE_LENGTHOF
:
11912 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11914 case OPTYPE_ISVALUE
:
11915 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11918 FATAL_ERROR("Value::generate_code_expr_expr()");
11921 case OPTYPE_VALUEOF
: // ti1
11922 u
.expr
.ti1
->generate_code(expr
);
11923 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11925 case OPTYPE_MATCH
: // v1 t2
11926 u
.expr
.t2
->generate_code(expr
);
11927 expr
->expr
= mputstr(expr
->expr
, ".match(");
11928 u
.expr
.v1
->generate_code_expr(expr
);
11929 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11931 case OPTYPE_UNDEF_RUNNING
:
11932 // it is resolved during semantic check
11933 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11935 case OPTYPE_COMP_NULL
: // -
11936 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11938 case OPTYPE_COMP_MTC
: // -
11939 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11941 case OPTYPE_COMP_SYSTEM
: // -
11942 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11944 case OPTYPE_COMP_SELF
: // -
11945 expr
->expr
=mputstr(expr
->expr
, "self");
11947 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11948 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11951 case OPTYPE_COMP_RUNNING
: // v1
11952 u
.expr
.v1
->generate_code_expr(expr
);
11953 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11954 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11955 expr
->expr
= mputstr(expr
->expr
, ".running()");
11957 case OPTYPE_COMP_RUNNING_ANY
: // -
11958 expr
->expr
=mputstr(expr
->expr
,
11959 "TTCN_Runtime::component_running(ANY_COMPREF)");
11961 case OPTYPE_COMP_RUNNING_ALL
: // -
11962 expr
->expr
=mputstr(expr
->expr
,
11963 "TTCN_Runtime::component_running(ALL_COMPREF)");
11965 case OPTYPE_COMP_ALIVE
: // v1
11966 u
.expr
.v1
->generate_code_expr(expr
);
11967 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11968 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11969 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11971 case OPTYPE_COMP_ALIVE_ANY
: // -
11972 expr
->expr
= mputstr(expr
->expr
,
11973 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11975 case OPTYPE_COMP_ALIVE_ALL
: // -
11976 expr
->expr
= mputstr(expr
->expr
,
11977 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11979 case OPTYPE_TMR_READ
: // r1
11980 u
.expr
.r1
->generate_code(expr
);
11981 expr
->expr
= mputstr(expr
->expr
, ".read()");
11983 case OPTYPE_TMR_RUNNING
: // r1
11984 u
.expr
.r1
->generate_code(expr
);
11985 expr
->expr
= mputstr(expr
->expr
, ".running()");
11987 case OPTYPE_TMR_RUNNING_ANY
: // -
11988 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
11990 case OPTYPE_GETVERDICT
: // -
11991 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
11993 case OPTYPE_TESTCASENAME
: // -
11994 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
11996 case OPTYPE_ACTIVATE
: // r1
11997 generate_code_expr_activate(expr
);
11999 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
12000 generate_code_expr_activate_refd(expr
);
12002 case OPTYPE_EXECUTE
: // r1 [v2]
12003 generate_code_expr_execute(expr
);
12005 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
12006 generate_code_expr_execute_refd(expr
);
12008 case OPTYPE_LOG2STR
:
12009 u
.expr
.logargs
->generate_code_expr(expr
);
12011 case OPTYPE_TTCN2STRING
: {
12012 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
12013 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
12014 param_governor
= param_governor
->get_type_refd_last();
12015 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
12016 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
12017 u
.expr
.ti1
->get_Template()->is_Value()) {
12018 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
12021 bool cast_needed
= v
->explicit_cast_needed();
12023 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
12025 v
->generate_code_expr(expr
);
12027 expr
->expr
= mputstr(expr
->expr
, ")");
12031 u
.expr
.ti1
->generate_code(expr
);
12033 expr
->expr
= mputstr(expr
->expr
, ")");
12035 case OPTYPE_PROF_RUNNING
:
12036 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
12039 FATAL_ERROR("Value::generate_code_expr_expr()");
12043 void Value::generate_code_expr_unary(expression_struct
*expr
,
12044 const char *operator_str
, Value
*v1
)
12046 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
12047 v1
->generate_code_expr_mandatory(expr
);
12048 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
12051 void Value::generate_code_expr_infix(expression_struct
*expr
,
12052 const char *operator_str
, Value
*v1
,
12053 Value
*v2
, bool optional_allowed
)
12055 if (!get_needs_conversion()) {
12056 expr
->expr
= mputc(expr
->expr
, '(');
12057 if (optional_allowed
) v1
->generate_code_expr(expr
);
12058 else v1
->generate_code_expr_mandatory(expr
);
12059 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
12060 if (optional_allowed
) v2
->generate_code_expr(expr
);
12061 else v2
->generate_code_expr_mandatory(expr
);
12062 expr
->expr
= mputc(expr
->expr
, ')');
12063 } else { // Temporary variable for the converted value.
12064 const string
& tmp_id1
= get_temporary_id();
12065 const char *tmp_id_str1
= tmp_id1
.c_str();
12066 expression_struct expr_tmp
;
12067 Code::init_expr(&expr_tmp
);
12068 switch (u
.expr
.v_optype
) {
12071 // Always "v1 -> v2".
12072 Type
*t1
= v1
->get_expr_governor_last();
12073 Type
*t2
= v2
->get_expr_governor_last();
12074 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
12075 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12076 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12077 if (expr_tmp
.preamble
)
12078 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12079 expr
->preamble
= mputprintf(expr
->preamble
,
12081 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12082 "and `%s' are not compatible at run-time\");\n",
12083 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
12084 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
12085 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
12086 t2
->get_typename().c_str(), t1
->get_typename().c_str());
12087 Code::free_expr(&expr_tmp
);
12088 if (optional_allowed
) v1
->generate_code_expr(expr
);
12089 else v1
->generate_code_expr_mandatory(expr
);
12090 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
12093 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12094 // functions. The governors of all operands must exist at this point.
12097 case OPTYPE_CONCAT
: {
12098 const string
& tmp_id2
= get_temporary_id();
12099 const char *tmp_id_str2
= tmp_id2
.c_str();
12100 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
12101 Type
*my_gov
= my_governor
->get_type_refd_last();
12102 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
12103 ->get_type_refd_last();
12104 if (!t1_gov
|| my_gov
== t1_gov
)
12105 FATAL_ERROR("Value::generate_code_expr_infix()");
12106 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
12107 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
12108 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
12109 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
12110 else v1
->generate_code_expr_mandatory(&expr_tmp
);
12111 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
12112 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12113 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12114 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
12115 expr
->preamble
= mputprintf(expr
->preamble
,
12117 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12118 "and `%s' are not compatible at run-time\");\n",
12119 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
12120 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
12121 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
12122 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
12123 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
12126 FATAL_ERROR("Value::generate_code_expr_infix()");
12132 void Value::generate_code_expr_and_or(expression_struct
*expr
)
12134 if (u
.expr
.v2
->needs_short_circuit()) {
12135 // introduce a temporary variable to store the result of the operation
12136 const string
& tmp_id
= get_temporary_id();
12137 const char *tmp_id_str
= tmp_id
.c_str();
12138 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
12139 expression_struct expr2
;
12140 // the left operand must be evaluated anyway
12141 Code::init_expr(&expr2
);
12142 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12143 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
12144 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12145 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
12146 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
12147 // evaluate the right operand only when necessary
12148 // in this case the final result will be the right operand
12149 Code::init_expr(&expr2
);
12150 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12151 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
12152 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12153 // the result is now in the temporary variable
12154 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
12156 // use the overloaded operator to get better error messages
12157 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
12158 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
12162 void Value::generate_code_expr_predef1(expression_struct
*expr
,
12163 const char *function_name
,
12166 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12167 v1
->generate_code_expr_mandatory(expr
);
12168 expr
->expr
= mputc(expr
->expr
, ')');
12171 void Value::generate_code_expr_predef2(expression_struct
*expr
,
12172 const char *function_name
,
12173 Value
*v1
, Value
*v2
)
12175 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12176 v1
->generate_code_expr_mandatory(expr
);
12177 expr
->expr
= mputstr(expr
->expr
, ", ");
12178 v2
->generate_code_expr_mandatory(expr
);
12179 expr
->expr
= mputc(expr
->expr
, ')');
12182 void Value::generate_code_expr_predef3(expression_struct
*expr
,
12183 const char *function_name
,
12184 Value
*v1
, Value
*v2
, Value
*v3
)
12186 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12187 v1
->generate_code_expr_mandatory(expr
);
12188 expr
->expr
= mputstr(expr
->expr
, ", ");
12189 v2
->generate_code_expr_mandatory(expr
);
12190 expr
->expr
= mputstr(expr
->expr
, ", ");
12191 v3
->generate_code_expr_mandatory(expr
);
12192 expr
->expr
= mputc(expr
->expr
, ')');
12195 void Value::generate_code_expr_substr(expression_struct
*expr
)
12198 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12199 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12200 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12201 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
12202 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12203 else u
.expr
.ti1
->generate_code(expr
);
12204 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12205 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
12206 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12207 expr
->expr
= mputstr(expr
->expr
, "(int)");
12208 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12209 expr
->expr
= mputstr(expr
->expr
, ", ");
12210 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12211 expr
->expr
= mputstr(expr
->expr
, "(int)");
12212 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12213 expr
->expr
= mputc(expr
->expr
, ')');
12216 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
12218 expression_struct expr_tmp
;
12219 Code::init_expr(&expr_tmp
);
12220 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
12221 ->get_type_refd_last();
12222 if (!t1
|| t1
== my_governor
->get_type_refd_last())
12223 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12224 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
12225 generate_code_expr_substr(&expr_tmp
);
12226 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
12227 generate_code_expr_replace(&expr_tmp
);
12229 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12231 // Two temporaries to store the result of substr() or replace() and to
12232 // store the converted value.
12233 const string
& tmp_id1
= get_temporary_id();
12234 const char *tmp_id_str1
= tmp_id1
.c_str();
12235 const string
& tmp_id2
= get_temporary_id();
12236 const char *tmp_id_str2
= tmp_id2
.c_str();
12237 if (expr_tmp
.preamble
)
12238 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12239 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12240 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12241 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12242 if (expr_tmp
.postamble
)
12243 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12244 Code::free_expr(&expr_tmp
);
12245 expr
->preamble
= mputprintf(expr
->preamble
,
12246 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12247 "`%s' are not compatible at run-time\");\n",
12248 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12249 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12250 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12251 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12254 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12256 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12257 Value
* v2
= u
.expr
.t2
->get_specific_value();
12258 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12259 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12260 else u
.expr
.ti1
->generate_code(expr
);
12261 expr
->expr
= mputstr(expr
->expr
, ", ");
12262 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12263 else u
.expr
.t2
->generate_code(expr
);
12264 expr
->expr
= mputstr(expr
->expr
, ", ");
12265 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12266 expr
->expr
= mputc(expr
->expr
, ')');
12269 void Value::generate_code_expr_replace(expression_struct
*expr
)
12271 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12272 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12274 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12275 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12276 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12277 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12278 else u
.expr
.ti1
->generate_code(expr
);
12279 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12280 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12281 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12282 expr
->expr
= mputstr(expr
->expr
, "(int)");
12283 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12284 expr
->expr
= mputstr(expr
->expr
, ", ");
12285 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12286 expr
->expr
= mputstr(expr
->expr
, "(int)");
12287 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12288 expr
->expr
= mputstr(expr
->expr
, ", ");
12290 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12291 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12292 Value
* v4_last
= v4
->get_value_refd_last();
12293 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12294 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12295 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12297 v4
->generate_code_expr_mandatory(expr
);
12299 else u
.expr
.ti4
->generate_code(expr
);
12300 expr
->expr
= mputc(expr
->expr
, ')');
12303 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12306 if(!v1
) // simple random generation
12307 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12308 else { // random generation with seeding
12309 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12310 v1
->generate_code_expr_mandatory(expr
);
12311 expr
->expr
= mputc(expr
->expr
, ')');
12315 void Value::generate_code_expr_create(expression_struct
*expr
,
12316 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12318 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12319 // first two arguments: component type
12320 Assignment
*t_ass
= type
->get_refd_assignment();
12321 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12322 FATAL_ERROR("Value::generate_code_expr_create()");
12323 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12324 Type::EXPECTED_DYNAMIC_VALUE
);
12325 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12326 comptype
= comptype
->get_type_refd_last();
12327 expr
->expr
= comptype
->get_CompBody()
12328 ->generate_code_comptype_name(expr
->expr
);
12329 expr
->expr
= mputstr(expr
->expr
, ", ");
12330 // third argument: component name
12332 Value
*t_val
= name
->get_value_refd_last();
12333 if (t_val
->valuetype
== V_CSTR
) {
12334 // the argument is foldable to a string literal
12335 size_t str_len
= t_val
->u
.str
.val_str
->size();
12336 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12337 expr
->expr
= mputc(expr
->expr
, '"');
12338 for (size_t i
= 0; i
< str_len
; i
++)
12339 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12340 expr
->expr
= mputc(expr
->expr
, '"');
12341 } else name
->generate_code_expr_mandatory(expr
);
12342 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12343 expr
->expr
= mputstr(expr
->expr
, ", ");
12344 // fourth argument: location
12346 Value
*t_val
= location
->get_value_refd_last();
12347 if (t_val
->valuetype
== V_CSTR
) {
12348 // the argument is foldable to a string literal
12349 size_t str_len
= t_val
->u
.str
.val_str
->size();
12350 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12351 expr
->expr
= mputc(expr
->expr
, '"');
12352 for (size_t i
= 0; i
< str_len
; i
++)
12353 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12354 expr
->expr
= mputc(expr
->expr
, '"');
12355 } else location
->generate_code_expr_mandatory(expr
);
12356 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12357 // fifth argument: alive flag
12358 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12361 void Value::generate_code_expr_activate(expression_struct
*expr
)
12363 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12364 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12365 FATAL_ERROR("Value::generate_code_expr_activate()");
12366 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12367 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12368 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12369 expr
->expr
= mputc(expr
->expr
, ')');
12372 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12374 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12375 if (v_last
->valuetype
== V_ALTSTEP
) {
12376 // the referred altstep is known
12377 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12378 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12380 // the referred altstep is unknown
12381 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12382 expr
->expr
= mputstr(expr
->expr
,".activate(");
12384 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12385 expr
->expr
= mputc(expr
->expr
, ')');
12388 void Value::generate_code_expr_execute(expression_struct
*expr
)
12390 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12391 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12392 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12393 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12394 if (parlist
->get_nof_pars() > 0) {
12395 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12397 expr
->expr
= mputstr(expr
->expr
, ", ");
12400 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12401 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12402 expr
->expr
= mputc(expr
->expr
, ')');
12403 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12406 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12408 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12409 if (v_last
->valuetype
== V_TESTCASE
) {
12410 // the referred testcase is known
12411 Assignment
*testcase
= v_last
->get_refd_fat();
12412 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12413 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12414 u
.expr
.ap_list2
->generate_code_alias(expr
,
12415 testcase
->get_FormalParList(), 0, false);
12417 // the referred testcase is unknown
12418 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12419 expr
->expr
= mputstr(expr
->expr
,".execute(");
12420 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12422 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12423 expr
->expr
= mputstr(expr
->expr
, ", ");
12425 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12426 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12427 expr
->expr
= mputc(expr
->expr
, ')');
12428 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12431 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12433 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12434 if (last_v
->get_valuetype() == V_FUNCTION
) {
12435 // the referred function is known
12436 Assignment
*function
= last_v
->get_refd_fat();
12437 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12438 function
->get_genname_from_scope(my_scope
).c_str());
12439 u
.invoke
.ap_list
->generate_code_alias(expr
,
12440 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12442 // the referred function is unknown
12443 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12444 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12445 Type
* gov_last
= last_v
->get_expr_governor_last();
12446 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12447 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12449 expr
->expr
= mputc(expr
->expr
, ')');
12452 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12455 // if the referenced value points to an optional value field the
12456 // generated code has to be corrected at the end:
12457 // `fieldid()' => `fieldid()()'
12458 Assignment
*ass
= ref
->get_refd_assignment();
12459 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12460 switch (ass
->get_asstype()) {
12461 case Assignment::A_CONST
:
12462 case Assignment::A_EXT_CONST
:
12463 case Assignment::A_MODULEPAR
:
12464 case Assignment::A_VAR
:
12465 case Assignment::A_FUNCTION_RVAL
:
12466 case Assignment::A_EXT_FUNCTION_RVAL
:
12467 case Assignment::A_PAR_VAL_IN
:
12468 case Assignment::A_PAR_VAL_OUT
:
12469 case Assignment::A_PAR_VAL_INOUT
:
12470 // only these are mapped to value objects
12471 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12472 expr
->expr
= mputstr(expr
->expr
, "()");
12479 void Value::generate_code_expr_encode(expression_struct
*expr
)
12483 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12484 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12485 v1
= templ
->get_specific_value();
12486 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12488 expression_struct expr2
;
12489 Code::init_expr(&expr2
);
12491 bool is_templ
= false;
12492 switch (templ
->get_templatetype()) {
12493 case Template::SPECIFIC_VALUE
:
12494 v1
->generate_code_expr_mandatory(&expr2
);
12497 u
.expr
.ti1
->generate_code(&expr2
);
12502 if (!gov_last
->is_coding_by_function()) {
12503 const string
& tmp_id
= get_temporary_id();
12504 const string
& tmp_buf_id
= get_temporary_id();
12505 const string
& tmp_ref_id
= get_temporary_id();
12506 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12508 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12509 tmp_buf_id
.c_str());
12510 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12511 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12512 expr
->preamble
= mputc (expr
->preamble
, '\n');
12514 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12515 gov_last
->get_genname_typedescriptor(
12516 u
.expr
.ti1
->get_Template()->get_my_scope()
12518 tmp_ref_id
.c_str(),
12520 if (is_templ
) // make a value out of the template, if needed
12521 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12522 expr
->preamble
= mputprintf(expr
->preamble
,
12523 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12524 tmp_ref_id
.c_str(),
12525 gov_last
->get_genname_typedescriptor(
12526 u
.expr
.ti1
->get_Template()->get_my_scope()
12528 tmp_buf_id
.c_str(),
12529 gov_last
->get_coding(true).c_str()
12531 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12532 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12533 tmp_buf_id
.c_str(),
12536 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12537 if (expr2
.postamble
)
12538 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12540 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12541 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12542 is_templ
? ".valueof()" : "");
12543 Code::free_expr(&expr2
);
12546 void Value::generate_code_expr_decode(expression_struct
*expr
)
12548 expression_struct expr1
, expr2
;
12549 Code::init_expr(&expr1
);
12550 Code::init_expr(&expr2
);
12551 u
.expr
.r1
->generate_code(&expr1
);
12552 u
.expr
.r2
->generate_code(&expr2
);
12554 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12555 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12556 get_type_refd_last();
12558 if (expr1
.preamble
)
12559 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12560 if (expr2
.preamble
)
12561 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12563 if (!_type
->is_coding_by_function()) {
12564 const string
& tmp_id
= get_temporary_id();
12565 const string
& buffer_id
= get_temporary_id();
12566 const string
& retval_id
= get_temporary_id();
12567 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12568 field_is_optional(u
.expr
.r2
->get_subrefs());
12570 expr
->preamble
= mputprintf(expr
->preamble
,
12571 "TTCN_Buffer %s(bit2oct(%s));\n"
12573 "TTCN_EncDec::set_error_behavior("
12574 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12575 "TTCN_EncDec::clear_error();\n",
12580 expr
->preamble
= mputprintf(expr
->preamble
,
12581 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12583 optional
? "()" : "",
12584 _type
->get_genname_typedescriptor(
12585 u
.expr
.r2
->get_my_scope()
12588 _type
->get_coding(false).c_str()
12590 expr
->preamble
= mputprintf(expr
->preamble
,
12591 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12592 "case TTCN_EncDec::ET_NONE: {\n"
12594 "OCTETSTRING %s;\n"
12595 "%s.get_string(%s);\n"
12596 "%s = oct2bit(%s);\n"
12599 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12600 "case TTCN_EncDec::ET_LEN_ERR:\n"
12606 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12607 "TTCN_EncDec::EB_DEFAULT);\n"
12608 "TTCN_EncDec::clear_error();\n",
12619 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12621 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12622 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12623 if (expr1
.postamble
)
12624 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12625 if (expr2
.postamble
)
12626 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12627 Code::free_expr(&expr1
);
12628 Code::free_expr(&expr2
);
12631 void Value::generate_code_expr_encvalue_unichar(expression_struct
*expr
)
12635 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12636 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12637 v1
= templ
->get_specific_value();
12638 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12640 expression_struct expr2
;
12641 Code::init_expr(&expr2
);
12643 bool is_templ
= false;
12644 switch (templ
->get_templatetype()) {
12645 case Template::SPECIFIC_VALUE
:
12646 v1
->generate_code_expr_mandatory(&expr2
);
12649 u
.expr
.ti1
->generate_code(&expr2
);
12654 if (!gov_last
->is_coding_by_function()) {
12655 const string
& tmp_id
= get_temporary_id();
12656 const string
& tmp_buf_id
= get_temporary_id();
12657 const string
& tmp_ref_id
= get_temporary_id();
12658 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12660 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12661 tmp_buf_id
.c_str());
12662 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12663 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12664 expr
->preamble
= mputc (expr
->preamble
, '\n');
12666 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12667 gov_last
->get_genname_typedescriptor(
12668 u
.expr
.ti1
->get_Template()->get_my_scope()
12670 tmp_ref_id
.c_str(),
12672 if (is_templ
) // make a value out of the template, if needed
12673 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12674 expr
->preamble
= mputprintf(expr
->preamble
,
12675 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12676 tmp_ref_id
.c_str(),
12677 gov_last
->get_genname_typedescriptor(
12678 u
.expr
.ti1
->get_Template()->get_my_scope()
12680 tmp_buf_id
.c_str(),
12681 gov_last
->get_coding(true).c_str()
12683 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12684 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12685 tmp_buf_id
.c_str(),
12688 const char * v2_code
= NULL
;
12690 v2_code
= generate_code_char_coding_check(expr
, u
.expr
.v2
, "encvalue_unichar");
12692 expr
->expr
= mputprintf(expr
->expr
, "oct2unichar(%s", tmp_id
.c_str());
12694 expr
->expr
= mputprintf(expr
->expr
, ", %s", v2_code
);
12696 expr
->expr
= mputprintf(expr
->expr
, ", \"UTF-8\""); //default
12698 expr
->expr
= mputprintf(expr
->expr
, ")");
12699 if (expr2
.postamble
)
12700 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12702 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12703 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12704 is_templ
? ".valueof()" : "");
12705 Code::free_expr(&expr2
);
12708 void Value::generate_code_expr_decvalue_unichar(expression_struct
*expr
)
12710 expression_struct expr1
, expr2
;
12711 Code::init_expr(&expr1
);
12712 Code::init_expr(&expr2
);
12713 u
.expr
.r1
->generate_code(&expr1
);
12714 u
.expr
.r2
->generate_code(&expr2
);
12716 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12717 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12718 get_type_refd_last();
12720 if (expr1
.preamble
)
12721 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12722 if (expr2
.preamble
)
12723 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12725 if (!_type
->is_coding_by_function()) {
12726 const string
& tmp_id
= get_temporary_id();
12727 const string
& buffer_id
= get_temporary_id();
12728 const string
& retval_id
= get_temporary_id();
12729 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12730 field_is_optional(u
.expr
.r2
->get_subrefs());
12732 const char* v3_code
= NULL
;
12734 v3_code
= generate_code_char_coding_check(expr
, u
.expr
.v3
, "decvalue_unichar");
12736 expr
->preamble
= mputprintf(expr
->preamble
,
12737 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12739 "TTCN_EncDec::set_error_behavior("
12740 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12741 "TTCN_EncDec::clear_error();\n",
12744 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12747 expr
->preamble
= mputprintf(expr
->preamble
,
12748 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12750 optional
? "()" : "",
12751 _type
->get_genname_typedescriptor(
12752 u
.expr
.r2
->get_my_scope()
12755 _type
->get_coding(false).c_str()
12757 expr
->preamble
= mputprintf(expr
->preamble
,
12758 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12759 "case TTCN_EncDec::ET_NONE: {\n"
12761 "OCTETSTRING %s;\n"
12762 "%s.get_string(%s);\n"
12763 "%s = oct2unichar(%s, %s);\n"
12766 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12767 "case TTCN_EncDec::ET_LEN_ERR:\n"
12773 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12774 "TTCN_EncDec::EB_DEFAULT);\n"
12775 "TTCN_EncDec::clear_error();\n",
12782 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12787 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12789 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12790 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12791 if (expr1
.postamble
)
12792 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12793 if (expr2
.postamble
)
12794 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12795 Code::free_expr(&expr1
);
12796 Code::free_expr(&expr2
);
12799 char* Value::generate_code_char_coding_check(expression_struct
*expr
, Value
*v
, const char *name
)
12801 expression_struct expr2
;
12802 Code::init_expr(&expr2
);
12803 v
->generate_code_expr_mandatory(&expr2
);
12804 expr
->preamble
= mputprintf(expr
->preamble
,
12805 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12806 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12807 " \"UTF-32BE\" != %s) {\n"
12808 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12809 "}\n", //todo errorbehaviour?
12822 char *Value::generate_code_init_choice(char *str
, const char *name
)
12824 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12825 // Safe as long as get_name() returns a const string&, not a temporary.
12826 const char *alt_prefix
=
12827 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12829 if (u
.choice
.alt_value
->needs_temp_ref()) {
12830 const string
& tmp_id
= get_temporary_id();
12831 const char *tmp_id_str
= tmp_id
.c_str();
12832 str
= mputprintf(str
, "{\n"
12833 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12834 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12835 alt_prefix
, alt_name
);
12836 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12837 str
= mputstr(str
, "}\n");
12839 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12840 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12841 Free(embedded_name
);
12846 char *Value::generate_code_init_seof(char *str
, const char *name
)
12848 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12850 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12851 const string
& embedded_type
=
12852 my_governor
->get_ofType()->get_genname_value(my_scope
);
12853 const char *embedded_type_str
= embedded_type
.c_str();
12854 for (size_t i
= 0; i
< nof_vs
; i
++) {
12855 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12857 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12858 else if (comp_v
->needs_temp_ref()) {
12859 const string
& tmp_id
= get_temporary_id();
12860 const char *tmp_id_str
= tmp_id
.c_str();
12861 str
= mputprintf(str
, "{\n"
12862 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12863 (unsigned long) i
);
12864 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12865 str
= mputstr(str
, "}\n");
12867 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12868 str
= comp_v
->generate_code_init(str
, embedded_name
);
12869 Free(embedded_name
);
12873 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12878 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12880 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12882 // Previous values can be truncated. The concept is similar to
12884 Type
*t_last
= my_governor
->get_type_refd_last();
12885 const string
& oftype_name
=
12886 t_last
->get_ofType()->get_genname_value(my_scope
);
12887 const char *oftype_name_str
= oftype_name
.c_str();
12888 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12889 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12890 const string
& tmp_id_1
= get_temporary_id();
12891 str
= mputstr(str
, "{\n");
12892 Value
*index
= iv
->get_index();
12893 if (index
->get_valuetype() != V_INT
) {
12894 const string
& tmp_id_2
= get_temporary_id();
12895 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12896 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12897 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12898 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12900 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12901 tmp_id_1
.c_str(), name
,
12902 (index
->get_val_Int()->t_str()).c_str());
12904 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12905 str
= mputstr(str
, "}\n");
12907 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12911 char *Value::generate_code_init_array(char *str
, const char *name
)
12913 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12914 Type
*t_last
= my_governor
->get_type_refd_last();
12915 Int index_offset
= t_last
->get_dimension()->get_offset();
12916 const string
& embedded_type
=
12917 t_last
->get_ofType()->get_genname_value(my_scope
);
12918 const char *embedded_type_str
= embedded_type
.c_str();
12919 for (size_t i
= 0; i
< nof_vs
; i
++) {
12920 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12921 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12922 else if (comp_v
->needs_temp_ref()) {
12923 const string
& tmp_id
= get_temporary_id();
12924 const char *tmp_id_str
= tmp_id
.c_str();
12925 str
= mputprintf(str
, "{\n"
12926 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12927 Int2string(index_offset
+ i
).c_str());
12928 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12929 str
= mputstr(str
, "}\n");
12931 char *embedded_name
= mprintf("%s[%s]", name
,
12932 Int2string(index_offset
+ i
).c_str());
12933 str
= comp_v
->generate_code_init(str
, embedded_name
);
12934 Free(embedded_name
);
12940 char *Value::generate_code_init_se(char *str
, const char *name
)
12942 Type
*type
= my_governor
->get_type_refd_last();
12943 size_t nof_comps
= type
->get_nof_comps();
12944 if (nof_comps
> 0) {
12945 for (size_t i
= 0; i
< nof_comps
; i
++) {
12946 CompField
*cf
= type
->get_comp_byIndex(i
);
12947 const Identifier
& field_id
= cf
->get_name();
12948 const char *field_name
= field_id
.get_name().c_str();
12950 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12951 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12952 if (field_v
->valuetype
== V_NOTUSED
) continue;
12953 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12954 } else if (is_asn1()) {
12955 if (cf
->has_default()) {
12956 // handle like a referenced value
12957 Value
*defval
= cf
->get_defval();
12958 if (needs_init_precede(defval
)) {
12959 str
= defval
->generate_code_init(str
,
12960 defval
->get_lhs_name().c_str());
12962 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12963 defval
->get_genname_own(my_scope
).c_str());
12966 if (!cf
->get_is_optional())
12967 FATAL_ERROR("Value::generate_code_init()");
12974 // the value is not omit
12975 if (field_v
->needs_temp_ref()) {
12976 const string
& tmp_id
= get_temporary_id();
12977 const char *tmp_id_str
= tmp_id
.c_str();
12978 str
= mputprintf(str
, "{\n"
12979 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
12980 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12982 str
= field_v
->generate_code_init(str
, tmp_id_str
);
12983 str
= mputstr(str
, "}\n");
12985 char *embedded_name
= mprintf("%s.%s()", name
,
12987 if (cf
->get_is_optional() && field_v
->is_compound())
12988 embedded_name
= mputstr(embedded_name
, "()");
12989 str
= field_v
->generate_code_init(str
, embedded_name
);
12990 Free(embedded_name
);
12993 // the value is omit
12994 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
12999 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
13004 char *Value::generate_code_init_refd(char *str
, const char *name
)
13006 Value
*v
= get_value_refd_last();
13008 // the referred value is not available at compile time
13009 // the code generation is based on the reference
13010 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
13011 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
13013 expression_struct expr
;
13014 Code::init_expr(&expr
);
13015 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
13016 u
.ref
.ref
->generate_code_const_ref(&expr
);
13017 str
= Code::merge_free_expr(str
, &expr
);
13020 // the referred value is available at compile time
13021 // the code generation is based on the referred value
13022 if (v
->has_single_expr() &&
13023 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
13024 // simple substitution for in-line values within the same module
13025 str
= mputprintf(str
, "%s = %s;\n", name
,
13026 v
->get_single_expr().c_str());
13028 // use a simple reference to reduce code size
13029 if (needs_init_precede(v
)) {
13030 // the referred value must be initialized first
13031 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
13032 // temporary id should be introduced for the lhs
13033 const string
& tmp_id
= get_temporary_id();
13034 const char *tmp_id_str
= tmp_id
.c_str();
13035 str
= mputprintf(str
, "{\n"
13037 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13038 tmp_id_str
, v
->get_lhs_name().c_str());
13039 str
= v
->generate_code_init(str
, tmp_id_str
);
13040 str
= mputstr(str
, "}\n");
13042 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
13045 str
= mputprintf(str
, "%s = %s;\n", name
,
13046 v
->get_genname_own(my_scope
).c_str());
13052 void Value::generate_json_value(JSON_Tokenizer
& json
,
13053 bool allow_special_float
, /* = true */
13054 bool union_value_list
, /* = false */
13055 Ttcn::JsonOmitCombination
* omit_combo
/* = NULL */)
13057 switch (valuetype
) {
13059 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
13062 Real r
= get_val_Real();
13063 if (r
== REAL_INFINITY
) {
13064 if (allow_special_float
) {
13065 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
13068 else if (r
== -REAL_INFINITY
) {
13069 if (allow_special_float
) {
13070 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
13074 if (allow_special_float
) {
13075 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
13079 // true if decimal representation possible (use %f format)
13080 bool decimal_repr
= (r
== 0.0)
13081 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
13082 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
13083 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
13084 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
13089 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
13095 char* str
= convert_to_json_string(get_val_str().c_str());
13096 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13100 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13101 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13106 json
.put_next_token(JSON_TOKEN_STRING
,
13107 (string('\"') + create_stringRepr() + string('\"')).c_str());
13111 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
13112 if (!u
.val_vs
->is_indexed()) {
13113 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
13114 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
, allow_special_float
,
13115 union_value_list
, omit_combo
);
13119 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
13120 // look for the entry with index equal to i
13121 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
13122 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
13123 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
,
13124 allow_special_float
, union_value_list
, omit_combo
);
13130 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
13134 // omitted fields have 2 possible JSON values (the field is absent, or it's
13135 // present with value 'null'), each combination of omitted values must be
13137 if (omit_combo
== NULL
) {
13138 FATAL_ERROR("Value::generate_json_value - no combo");
13140 size_t len
= get_nof_comps();
13141 // generate the JSON object from the present combination
13142 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13143 for (size_t i
= 0; i
< len
; ++i
) {
13144 Ttcn::JsonOmitCombination::omit_state_t state
= omit_combo
->get_state(this, i
);
13145 if (state
== Ttcn::JsonOmitCombination::OMITTED_ABSENT
) {
13146 // the field is absent, don't insert anything
13149 // use the field's alias, if it has one
13150 const char* alias
= NULL
;
13151 if (my_governor
!= NULL
) {
13152 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13153 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
13154 if (field_attrib
!= NULL
) {
13155 alias
= field_attrib
->alias
;
13158 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13159 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
13160 if (state
== Ttcn::JsonOmitCombination::OMITTED_NULL
) {
13161 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
13164 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
,
13165 allow_special_float
, union_value_list
, omit_combo
);
13168 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13171 bool as_value
= !union_value_list
&& my_governor
!= NULL
&&
13172 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
13173 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
13175 // no 'as value' coding instruction, insert an object with one field
13176 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13177 // use the field's alias, if it has one
13178 const char* alias
= NULL
;
13179 if (my_governor
!= NULL
) {
13180 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13181 get_alt_name())->get_type()->get_json_attributes();
13182 if (field_attrib
!= NULL
) {
13183 alias
= field_attrib
->alias
;
13186 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13187 get_alt_name().get_ttcnname().c_str());
13189 get_alt_value()->generate_json_value(json
, allow_special_float
,
13190 union_value_list
, omit_combo
);
13192 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13196 Value
* v
= get_value_refd_last();
13198 v
->generate_json_value(json
, allow_special_float
, union_value_list
, omit_combo
);
13203 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
13207 bool Value::explicit_cast_needed(bool forIsValue
)
13209 Value
*v_last
= get_value_refd_last();
13210 if (v_last
!= this) {
13211 // this is a foldable referenced value
13212 // if the reference points to an imported or compound value the code
13213 // generation will be based on the reference so cast is not needed
13214 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
13215 || !v_last
->has_single_expr()) return false;
13216 } else if (v_last
->valuetype
== V_REFD
) {
13217 // this is an unfoldable reference (v_last==this)
13218 // explicit cast is needed only for string element references
13219 if (forIsValue
) return false;
13220 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
13221 return t_subrefs
&& t_subrefs
->refers_to_string_element();
13223 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
13224 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
13225 switch (t_governor
->get_typetype()) {
13229 case Type::T_INT_A
:
13231 case Type::T_ENUM_A
:
13232 case Type::T_ENUM_T
:
13233 case Type::T_VERDICT
:
13234 case Type::T_COMPONENT
:
13235 // these are mapped to built-in C/C++ types
13237 case Type::T_SEQ_A
:
13238 case Type::T_SEQ_T
:
13239 case Type::T_SET_A
:
13240 case Type::T_SET_T
:
13241 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13242 return t_governor
->get_nof_comps() == 0;
13243 case Type::T_SEQOF
:
13244 case Type::T_SETOF
:
13245 // the C++ equivalent of value {} is ambiguous
13248 case Type::T_FUNCTION
:
13249 case Type::T_ALTSTEP
:
13250 case Type::T_TESTCASE
:
13257 bool Value::has_single_expr()
13259 if (get_needs_conversion()) return false;
13260 switch (valuetype
) {
13262 return has_single_expr_expr();
13265 // a union or array value cannot be represented as an in-line expression
13269 // only an empty record/set of value can be represented as an in-line
13271 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
13272 else return u
.val_vs
->get_nof_ivs() == 0;
13275 // only a value for an empty record/set type can be represented as an
13276 // in-line expression
13277 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
13278 Type
*type
= my_governor
->get_type_refd_last();
13279 return type
->get_nof_comps() == 0; }
13281 Value
*v_last
= get_value_refd_last();
13282 // If the above call hit an error and set_valuetype(V_ERROR),
13283 // then u.ref.ref has been freed. Avoid the segfault.
13284 if (valuetype
== V_ERROR
)
13286 if (v_last
!= this && v_last
->has_single_expr() &&
13287 v_last
->my_scope
->get_scope_mod_gen() ==
13288 my_scope
->get_scope_mod_gen()) return true;
13289 else return u
.ref
.ref
->has_single_expr(); }
13291 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
13295 case V_UNDEF_LOWERID
:
13296 case V_UNDEF_BLOCK
:
13298 // these values cannot occur during code generation
13299 FATAL_ERROR("Value::has_single_expr()");
13301 return u
.val_Int
->is_native_fit();
13303 // should only happen when generating code for an unbound record/set value
13306 // other value types (literal values) do not need temporary reference
13311 string
Value::get_single_expr()
13313 switch (valuetype
) {
13315 return string("ASN_NULL_VALUE");
13317 return string(u
.val_bool
? "TRUE" : "FALSE");
13319 if (u
.val_Int
->is_native_fit()) { // Be sure.
13320 return u
.val_Int
->t_str();
13322 // get_single_expr may be called only if has_single_expr() is true.
13323 // The only exception is V_INT, where get_single_expr may be called
13324 // even if is_native_fit (which is used to implement has_single_expr)
13326 string
ret_val('"');
13327 ret_val
+= u
.val_Int
->t_str();
13332 return Real2code(u
.val_Real
);
13334 return get_single_expr_enum();
13336 return get_my_scope()->get_scope_mod_gen()
13337 ->add_bitstring_literal(*u
.str
.val_str
);
13339 return get_my_scope()->get_scope_mod_gen()
13340 ->add_hexstring_literal(*u
.str
.val_str
);
13342 return get_my_scope()->get_scope_mod_gen()
13343 ->add_octetstring_literal(*u
.str
.val_str
);
13345 return get_my_scope()->get_scope_mod_gen()
13346 ->add_charstring_literal(*u
.str
.val_str
);
13348 if (u
.ustr
.convert_str
) {
13349 set_valuetype(V_CSTR
);
13350 return get_my_scope()->get_scope_mod_gen()
13351 ->add_charstring_literal(*u
.str
.val_str
);
13353 return get_my_scope()->get_scope_mod_gen()
13354 ->add_ustring_literal(*u
.ustr
.val_ustr
);
13356 return get_single_expr_iso2022str();
13359 vector
<string
> comps
;
13360 bool is_constant
= get_oid_comps(comps
);
13361 size_t nof_comps
= comps
.size();
13363 for (size_t i
= 0; i
< nof_comps
; i
++) {
13364 if (i
> 0) oi_str
+= ", ";
13365 oi_str
+= *(comps
[i
]);
13367 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
13370 // the objid only contains constants
13371 // => create a literal and return its name
13372 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
13374 // the objid contains at least one variable
13375 // => append the number of components before the component values in the string and return it
13376 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
13379 if (u
.val_vs
->get_nof_vs() > 0)
13380 FATAL_ERROR("Value::get_single_expr()");
13381 return string("NULL_VALUE");
13384 if (u
.val_nvs
->get_nof_nvs() > 0)
13385 FATAL_ERROR("Value::get_single_expr()");
13386 return string("NULL_VALUE");
13388 Value
*v_last
= get_value_refd_last();
13389 if (v_last
!= this && v_last
->has_single_expr() &&
13390 v_last
->my_scope
->get_scope_mod_gen() ==
13391 my_scope
->get_scope_mod_gen()) {
13392 // the reference points to another single value in the same module
13393 return v_last
->get_single_expr();
13395 // convert the reference to a single expression
13396 expression_struct expr
;
13397 Code::init_expr(&expr
);
13398 u
.ref
.ref
->generate_code_const_ref(&expr
);
13399 if (expr
.preamble
|| expr
.postamble
)
13400 FATAL_ERROR("Value::get_single_expr()");
13401 string
ret_val(expr
.expr
);
13402 Code::free_expr(&expr
);
13406 return string("OMIT_VALUE");
13408 switch (u
.verdict
) {
13410 return string("NONE");
13412 return string("PASS");
13413 case Verdict_INCONC
:
13414 return string("INCONC");
13416 return string("FAIL");
13417 case Verdict_ERROR
:
13418 return string("ERROR");
13420 FATAL_ERROR("Value::get_single_expr()");
13423 case V_DEFAULT_NULL
:
13424 return string("NULL_COMPREF");
13426 string
ret_val('(');
13427 ret_val
+= my_governor
->get_genname_value(my_scope
);
13428 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13432 expression_struct expr
;
13433 Code::init_expr(&expr
);
13434 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13435 else generate_code_expr_invoke(&expr
);
13436 if (expr
.preamble
|| expr
.postamble
)
13437 FATAL_ERROR("Value::get_single_expr()");
13438 string
ret_val(expr
.expr
);
13439 Code::free_expr(&expr
);
13443 case MACRO_TESTCASEID
:
13444 return string("TTCN_Runtime::get_testcase_id_macro()");
13446 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13452 return get_single_expr_fat();
13454 FATAL_ERROR("Value::get_single_expr()");
13459 bool Value::has_single_expr_expr()
13461 switch (u
.expr
.v_optype
) {
13462 case OPTYPE_RND
: // -
13463 case OPTYPE_COMP_NULL
:
13464 case OPTYPE_COMP_MTC
:
13465 case OPTYPE_COMP_SYSTEM
:
13466 case OPTYPE_COMP_SELF
:
13467 case OPTYPE_COMP_RUNNING_ANY
:
13468 case OPTYPE_COMP_RUNNING_ALL
:
13469 case OPTYPE_COMP_ALIVE_ANY
:
13470 case OPTYPE_COMP_ALIVE_ALL
:
13471 case OPTYPE_TMR_RUNNING_ANY
:
13472 case OPTYPE_GETVERDICT
:
13473 case OPTYPE_TESTCASENAME
:
13474 case OPTYPE_PROF_RUNNING
:
13476 case OPTYPE_ENCODE
:
13477 case OPTYPE_DECODE
:
13478 case OPTYPE_ISBOUND
:
13479 case OPTYPE_ISPRESENT
:
13480 case OPTYPE_TTCN2STRING
:
13481 case OPTYPE_ENCVALUE_UNICHAR
:
13482 case OPTYPE_DECVALUE_UNICHAR
:
13484 case OPTYPE_UNARYPLUS
: // v1
13485 case OPTYPE_UNARYMINUS
:
13488 case OPTYPE_BIT2HEX
:
13489 case OPTYPE_BIT2INT
:
13490 case OPTYPE_BIT2OCT
:
13491 case OPTYPE_BIT2STR
:
13492 case OPTYPE_CHAR2INT
:
13493 case OPTYPE_CHAR2OCT
:
13494 case OPTYPE_FLOAT2INT
:
13495 case OPTYPE_FLOAT2STR
:
13496 case OPTYPE_HEX2BIT
:
13497 case OPTYPE_HEX2INT
:
13498 case OPTYPE_HEX2OCT
:
13499 case OPTYPE_HEX2STR
:
13500 case OPTYPE_INT2CHAR
:
13501 case OPTYPE_INT2FLOAT
:
13502 case OPTYPE_INT2STR
:
13503 case OPTYPE_INT2UNICHAR
:
13504 case OPTYPE_OCT2BIT
:
13505 case OPTYPE_OCT2CHAR
:
13506 case OPTYPE_OCT2HEX
:
13507 case OPTYPE_OCT2INT
:
13508 case OPTYPE_OCT2STR
:
13509 case OPTYPE_STR2BIT
:
13510 case OPTYPE_STR2FLOAT
:
13511 case OPTYPE_STR2HEX
:
13512 case OPTYPE_STR2INT
:
13513 case OPTYPE_STR2OCT
:
13514 case OPTYPE_UNICHAR2INT
:
13515 case OPTYPE_UNICHAR2CHAR
:
13516 case OPTYPE_ENUM2INT
:
13517 case OPTYPE_RNDWITHVAL
:
13518 case OPTYPE_ISCHOSEN_V
: // v1 i2
13519 case OPTYPE_COMP_RUNNING
:
13520 case OPTYPE_COMP_ALIVE
:
13521 case OPTYPE_GET_STRINGENCODING
:
13522 case OPTYPE_REMOVE_BOM
:
13523 case OPTYPE_DECODE_BASE64
:
13524 return u
.expr
.v1
->has_single_expr();
13525 case OPTYPE_ISCHOSEN_T
: // t1 i2
13526 return u
.expr
.t1
->has_single_expr();
13527 case OPTYPE_ADD
: // v1 v2
13528 case OPTYPE_SUBTRACT
:
13529 case OPTYPE_MULTIPLY
:
13530 case OPTYPE_DIVIDE
:
13533 case OPTYPE_CONCAT
:
13548 case OPTYPE_INT2BIT
:
13549 case OPTYPE_INT2HEX
:
13550 case OPTYPE_INT2OCT
:
13551 return u
.expr
.v1
->has_single_expr() &&
13552 u
.expr
.v2
->has_single_expr();
13553 case OPTYPE_UNICHAR2OCT
:
13554 case OPTYPE_OCT2UNICHAR
:
13555 case OPTYPE_ENCODE_BASE64
:
13556 return u
.expr
.v1
->has_single_expr() &&
13557 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13560 return u
.expr
.v1
->has_single_expr() &&
13561 u
.expr
.v2
->has_single_expr() &&
13562 !u
.expr
.v2
->needs_short_circuit();
13563 case OPTYPE_SUBSTR
:
13564 return u
.expr
.ti1
->has_single_expr() &&
13565 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13566 case OPTYPE_REGEXP
:
13567 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13568 u
.expr
.v3
->has_single_expr();
13569 case OPTYPE_DECOMP
: // v1 v2 v3
13570 return u
.expr
.v1
->has_single_expr() &&
13571 u
.expr
.v2
->has_single_expr() &&
13572 u
.expr
.v3
->has_single_expr();
13573 case OPTYPE_REPLACE
:
13574 return u
.expr
.ti1
->has_single_expr() &&
13575 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13576 u
.expr
.ti4
->has_single_expr();
13577 case OPTYPE_ISVALUE
: // ti1
13578 case OPTYPE_LENGTHOF
: // ti1
13579 case OPTYPE_SIZEOF
: // ti1
13580 case OPTYPE_VALUEOF
: // ti1
13581 return u
.expr
.ti1
->has_single_expr();
13582 case OPTYPE_LOG2STR
:
13583 return u
.expr
.logargs
->has_single_expr();
13584 case OPTYPE_MATCH
: // v1 t2
13585 return u
.expr
.v1
->has_single_expr() &&
13586 u
.expr
.t2
->has_single_expr();
13587 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13588 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13589 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13590 case OPTYPE_TMR_READ
: // r1
13591 case OPTYPE_TMR_RUNNING
:
13592 case OPTYPE_ACTIVATE
:
13593 return u
.expr
.r1
->has_single_expr();
13594 case OPTYPE_EXECUTE
: // r1 [v2]
13595 return u
.expr
.r1
->has_single_expr() &&
13596 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13597 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13598 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13599 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13600 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13601 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13603 FATAL_ERROR("Value::has_single_expr_expr()");
13607 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13609 if (!v
->has_single_expr()) return false;
13610 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13611 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13615 string
Value::get_single_expr_enum()
13617 string
ret_val(my_governor
->get_genname_value(my_scope
));
13619 ret_val
+= u
.val_id
->get_name();
13623 string
Value::get_single_expr_iso2022str()
13626 Type
*type
= get_my_governor()->get_type_refd_last();
13627 switch (type
->get_typetype()) {
13628 case Type::T_TELETEXSTRING
:
13629 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13631 case Type::T_VIDEOTEXSTRING
:
13632 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13634 case Type::T_GRAPHICSTRING
:
13635 case Type::T_OBJECTDESCRIPTOR
:
13636 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13638 case Type::T_GENERALSTRING
:
13639 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13642 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13645 string
*ostr
= char2oct(*u
.str
.val_str
);
13646 ret_val
+= get_my_scope()->get_scope_mod_gen()
13647 ->add_octetstring_literal(*ostr
);
13653 string
Value::get_single_expr_fat()
13655 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13656 // the ampersand operator is not really necessary to obtain the function
13657 // pointer, but some older versions of GCC cannot instantiate the
13658 // appropriate operator=() member of class OPTIONAL when necessary
13659 // if only the function name is given
13660 string
ret_val('&');
13661 switch (valuetype
) {
13663 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13666 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13667 ret_val
+= "_instance";
13670 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13673 FATAL_ERROR("Value::get_single_expr_fat()");
13678 bool Value::is_compound()
13680 switch (valuetype
) {
13693 bool Value::needs_temp_ref()
13695 switch (valuetype
) {
13698 if (!is_indexed()) {
13699 // Temporary reference is needed if the value has at least one real
13700 // element (i.e. it is not empty or contains only not used symbols).
13701 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13702 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13705 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13706 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13707 ->valuetype
!= V_NOTUSED
)
13713 size_t nof_real_vs
= 0;
13714 if (!is_indexed()) {
13715 // Temporary reference is needed if the array value has at least two
13716 // real elements (excluding not used symbols).
13717 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13718 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13720 if (nof_real_vs
> 1) return true;
13724 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13725 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13726 ->valuetype
!= V_NOTUSED
) {
13728 if (nof_real_vs
> 1) return true;
13736 // it depends on the type since fields with omit or default value
13737 // may not be present
13738 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13740 // incomplete values are allowed in TTCN-3
13741 // we should check the number of value components
13742 return u
.val_nvs
->get_nof_nvs() > 1;
13747 case V_UNDEF_LOWERID
:
13748 case V_UNDEF_BLOCK
:
13750 // these values cannot occur during code generation
13751 FATAL_ERROR("Value::needs_temp_ref()");
13753 return !u
.val_Int
->is_native();
13755 // other value types (literal values) do not need temporary reference
13760 bool Value::needs_short_circuit()
13762 switch (valuetype
) {
13770 // sub-expressions should be evaluated only if necessary
13773 FATAL_ERROR("Value::needs_short_circuit()");
13775 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13776 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13777 switch (t_ass
->get_asstype()) {
13778 case Assignment::A_FUNCTION_RVAL
:
13779 case Assignment::A_EXT_FUNCTION_RVAL
:
13780 // avoid unnecessary call of a function
13782 case Assignment::A_CONST
:
13783 case Assignment::A_EXT_CONST
:
13784 case Assignment::A_MODULEPAR
:
13785 case Assignment::A_VAR
:
13786 case Assignment::A_PAR_VAL_IN
:
13787 case Assignment::A_PAR_VAL_OUT
:
13788 case Assignment::A_PAR_VAL_INOUT
:
13789 // depends on field/array sub-references, which is examined below
13792 FATAL_ERROR("Value::needs_short_circuit()");
13794 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13796 // the evaluation of the reference does not have side effects
13797 // (i.e. false shall be returned) only if all sub-references point to
13798 // mandatory fields of record/set types, and neither sub-reference points
13799 // to a field of a union type
13800 Type
*t_type
= t_ass
->get_Type();
13801 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13802 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13803 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13804 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13805 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13806 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13807 t_cf
->get_is_optional()) return true;
13808 t_type
= t_cf
->get_type();
13809 } else return true;
13815 void Value::dump(unsigned level
) const
13817 switch (valuetype
) {
13841 case V_DEFAULT_NULL
:
13849 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13853 DEBUG(level
, "Value: reference");
13854 u
.ref
.ref
->dump(level
+ 1);
13856 case V_UNDEF_LOWERID
:
13857 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13859 case V_UNDEF_BLOCK
:
13860 DEBUG(level
, "Value: {block}");
13863 DEBUG(level
, "Value: null");
13866 DEBUG(level
, "Value: invoke");
13867 u
.invoke
.v
->dump(level
+ 1);
13868 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13869 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13872 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13876 void Value::add_string_element(size_t index
, Value
*v_element
,
13877 map
<size_t, Value
>*& string_elements
)
13879 v_element
->set_my_scope(get_my_scope());
13880 v_element
->set_my_governor(get_my_governor());
13881 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13882 v_element
->set_location(*this);
13883 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13884 string_elements
->add(index
, v_element
);
13887 ///////////////////////////////////////////////////////////////////////////////
13888 // class LazyParamData
13890 int LazyParamData::depth
= 0;
13891 bool LazyParamData::used_as_lvalue
= false;
13892 vector
<string
>* LazyParamData::type_vec
= NULL
;
13893 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13895 void LazyParamData::init(bool p_used_as_lvalue
) {
13896 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13898 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13899 used_as_lvalue
= p_used_as_lvalue
;
13900 type_vec
= new vector
<string
>;
13901 refd_vec
= new vector
<string
>;
13906 void LazyParamData::clean() {
13907 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13908 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13911 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13916 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13924 bool LazyParamData::in_lazy() {
13925 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13929 // returns a temporary id instead of the C++ reference to a definition
13930 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13931 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13932 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13933 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13934 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13935 // store the type of the assignment
13936 string
* type_str
= new string
;
13937 switch (ass
->get_asstype()) {
13938 case Assignment::A_MODULEPAR_TEMP
:
13939 case Assignment::A_TEMPLATE
:
13940 case Assignment::A_VAR_TEMPLATE
:
13941 case Assignment::A_PAR_TEMPL_IN
:
13942 case Assignment::A_PAR_TEMPL_OUT
:
13943 case Assignment::A_PAR_TEMPL_INOUT
:
13944 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13947 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13949 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13950 bool refd_ass_is_lazy_fpar
= false;
13951 switch (ass
->get_asstype()) {
13952 case Assignment::A_PAR_VAL
:
13953 case Assignment::A_PAR_VAL_IN
:
13954 case Assignment::A_PAR_TEMPL_IN
:
13955 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13956 if (refd_ass_is_lazy_fpar
) {
13957 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13963 // add the "const" part if the referenced assignment is a constant thing
13964 if (!refd_ass_is_lazy_fpar
) {
13965 switch (ass
->get_asstype()) {
13966 case Assignment::A_CONST
:
13967 case Assignment::A_OC
:
13968 case Assignment::A_OBJECT
:
13969 case Assignment::A_OS
:
13970 case Assignment::A_VS
:
13971 case Assignment::A_EXT_CONST
:
13972 case Assignment::A_MODULEPAR
:
13973 case Assignment::A_MODULEPAR_TEMP
:
13974 case Assignment::A_TEMPLATE
:
13975 case Assignment::A_PAR_VAL
:
13976 case Assignment::A_PAR_VAL_IN
:
13977 case Assignment::A_PAR_TEMPL_IN
:
13978 *type_str
= string("const ") + *type_str
;
13986 type_vec
->add(type_str
);
13987 // store the C++ reference string
13988 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
13989 if (refd_ass_is_lazy_fpar
) {
13990 Type
* refd_ass_type
= ass
->get_Type();
13991 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
);
13992 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
13994 return get_member_name(refd_vec
->size()-1);
13998 string
LazyParamData::get_member_name(size_t idx
) {
13999 return string("lpm_") + Int2string(idx
);
14002 string
LazyParamData::get_constr_param_name(size_t idx
) {
14003 return string("lpp_") + Int2string(idx
);
14006 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
14007 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14008 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
14009 const string
& tmp_id
= val
->get_temporary_id();
14010 const char *tmp_id_str
= tmp_id
.c_str();
14011 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14012 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
14014 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14016 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14018 val
->generate_code_expr(expr
);
14022 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
14023 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14024 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
14025 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
14026 const char *tmp_id_str
= tmp_id
.c_str();
14027 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14028 temp
->get_Template()->get_my_governor()
14029 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
14030 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14031 tmp_id_str
, temp
->get_Template());
14032 // Not incorporated into gen_conv_code() yet.
14033 if (gen_restriction_check
!= TR_NONE
)
14034 expr
->preamble
= Template::generate_restriction_check_code(
14035 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
14036 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14037 } else temp
->generate_code(expr
, gen_restriction_check
);
14040 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14041 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14043 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14044 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14045 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14046 expression_struct value_expr
;
14047 Code::init_expr(&value_expr
);
14048 generate_code_for_value(&value_expr
, value
, scope
);
14049 // the id of the instance of Lazy_Param which will be used as the actual parameter
14050 const string
& lazy_param_id
= value
->get_temporary_id();
14051 if (value_expr
.preamble
) {
14052 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
14054 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14055 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14056 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
14057 Code::free_expr(&value_expr
);
14058 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14061 // only if the formal parameter is *not* used as lvalue
14062 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
14063 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
14065 bool refd_ass_is_lazy_fpar
= false;
14066 switch (refd_ass
->get_asstype()) {
14067 case Assignment::A_PAR_VAL
:
14068 case Assignment::A_PAR_VAL_IN
:
14069 case Assignment::A_PAR_TEMPL_IN
:
14070 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14075 if (refd_ass_is_lazy_fpar
) {
14076 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14081 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14082 expression_struct value_expr
;
14083 Code::init_expr(&value_expr
);
14084 generate_code_for_value(&value_expr
, value
, scope
);
14085 // the id of the instance of Lazy_Param which will be used as the actual parameter
14086 string lazy_param_id
= value
->get_temporary_id();
14087 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
14088 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
14091 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
14092 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14094 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14095 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14096 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14097 expression_struct tmpl_expr
;
14098 Code::init_expr(&tmpl_expr
);
14099 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14100 // the id of the instance of Lazy_Param which will be used as the actual parameter
14101 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
14102 if (tmpl_expr
.preamble
) {
14103 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
14105 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14106 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14107 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
14108 Code::free_expr(&tmpl_expr
);
14109 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14112 // only if the formal parameter is *not* used as lvalue
14113 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
14114 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
14116 bool refd_ass_is_lazy_fpar
= false;
14117 switch (refd_ass
->get_asstype()) {
14118 case Assignment::A_PAR_VAL
:
14119 case Assignment::A_PAR_VAL_IN
:
14120 case Assignment::A_PAR_TEMPL_IN
:
14121 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14126 if (refd_ass_is_lazy_fpar
) {
14127 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14132 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14133 expression_struct tmpl_expr
;
14134 Code::init_expr(&tmpl_expr
);
14135 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14136 // the id of the instance of Lazy_Param which will be used as the actual parameter
14137 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
14138 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
14139 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
14142 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
14143 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
14144 if (type_vec
->size()>0) {
14145 // private members of the local class will be const references to the objects referenced by the expression
14146 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14147 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
14149 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
14150 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
14151 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14152 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14153 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
14155 expr
->preamble
= mputstr(expr
->preamble
, "): ");
14156 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14157 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14158 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
14160 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
14161 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
14163 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
14164 // use the temporary expr structure to fill the body of the eval_expr() function
14165 if (param_expr
.preamble
) {
14166 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
14168 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
14169 if (param_expr
.postamble
) {
14170 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
14172 Code::free_expr(¶m_expr
);
14173 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
14174 "};\n" // end of local class definition
14176 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
14177 if (type_vec
->size()>0) {
14178 expr
->preamble
= mputc(expr
->preamble
, '(');
14179 // paramteres of the constructor are references to the objects used in the expression
14180 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
14181 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14182 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
14184 expr
->preamble
= mputc(expr
->preamble
, ')');
14186 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
14187 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14188 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
14191 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
14192 expression_struct ref_expr
;
14193 Code::init_expr(&ref_expr
);
14194 ref
->generate_code(&ref_expr
);
14195 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
14196 if (ref_expr
.preamble
) {
14197 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
14199 Assignment
* ass
= ref
->get_refd_assignment();
14200 // determine C++ type of the assignment
14202 switch (ass
->get_asstype()) {
14203 case Assignment::A_MODULEPAR_TEMP
:
14204 case Assignment::A_TEMPLATE
:
14205 case Assignment::A_VAR_TEMPLATE
:
14206 case Assignment::A_PAR_TEMPL_IN
:
14207 case Assignment::A_PAR_TEMPL_OUT
:
14208 case Assignment::A_PAR_TEMPL_INOUT
:
14209 type_str
= ass
->get_Type()->get_genname_template(scope
);
14212 type_str
= ass
->get_Type()->get_genname_value(scope
);
14214 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14215 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
14216 if (ref_expr
.postamble
) {
14217 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
14219 Code::free_expr(&ref_expr
);
14220 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14223 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14224 const string
& lazy_param_id
= value
->get_temporary_id();
14225 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14226 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14227 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
14228 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14231 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
14232 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
14233 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14234 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14235 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
14236 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14239 } // namespace Common