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 case OPTYPE_ANY2UNISTR
:
344 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
347 FATAL_ERROR("Value::Value()");
356 u
.refd_fat
= p
.u
.refd_fat
;
359 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
360 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
361 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
364 u
.refered
= p
.u
.refered
->clone();
367 FATAL_ERROR("Value::Value()");
371 void Value::clean_up()
394 case V_UNDEF_LOWERID
:
402 delete u
.str
.val_str
;
403 clean_up_string_elements(u
.str
.str_elements
);
406 delete u
.ustr
.val_ustr
;
407 clean_up_string_elements(u
.ustr
.ustr_elements
);
415 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
416 delete (*u
.oid_comps
)[i
];
417 u
.oid_comps
->clear();
425 delete u
.choice
.alt_name
;
426 delete u
.choice
.alt_value
;
445 delete u
.invoke
.t_list
;
446 delete u
.invoke
.ap_list
;
450 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
459 FATAL_ERROR("Value::clean_up()");
463 void Value::clean_up_expr()
465 switch (u
.expr
.state
) {
467 case EXPR_CHECKING_ERR
:
468 FATAL_ERROR("Value::clean_up_expr()");
472 switch (u
.expr
.v_optype
) {
473 case OPTYPE_RND
: // -
474 case OPTYPE_COMP_NULL
:
475 case OPTYPE_COMP_MTC
:
476 case OPTYPE_COMP_SYSTEM
:
477 case OPTYPE_COMP_SELF
:
478 case OPTYPE_COMP_RUNNING_ANY
:
479 case OPTYPE_COMP_RUNNING_ALL
:
480 case OPTYPE_COMP_ALIVE_ANY
:
481 case OPTYPE_COMP_ALIVE_ALL
:
482 case OPTYPE_TMR_RUNNING_ANY
:
483 case OPTYPE_GETVERDICT
:
484 case OPTYPE_TESTCASENAME
:
485 case OPTYPE_PROF_RUNNING
:
487 case OPTYPE_UNARYPLUS
: // v1
488 case OPTYPE_UNARYMINUS
:
495 case OPTYPE_CHAR2INT
:
496 case OPTYPE_CHAR2OCT
:
497 case OPTYPE_COMP_RUNNING
:
498 case OPTYPE_COMP_ALIVE
:
499 case OPTYPE_FLOAT2INT
:
500 case OPTYPE_FLOAT2STR
:
505 case OPTYPE_INT2CHAR
:
506 case OPTYPE_INT2FLOAT
:
508 case OPTYPE_INT2UNICHAR
:
510 case OPTYPE_OCT2CHAR
:
515 case OPTYPE_STR2FLOAT
:
519 case OPTYPE_UNICHAR2INT
:
520 case OPTYPE_UNICHAR2CHAR
:
521 case OPTYPE_ENUM2INT
:
522 case OPTYPE_RNDWITHVAL
:
523 case OPTYPE_REMOVE_BOM
:
524 case OPTYPE_GET_STRINGENCODING
:
525 case OPTYPE_DECODE_BASE64
:
528 case OPTYPE_ADD
: // v1 v2
529 case OPTYPE_SUBTRACT
:
530 case OPTYPE_MULTIPLY
:
554 case OPTYPE_UNICHAR2OCT
:
555 case OPTYPE_OCT2UNICHAR
:
556 case OPTYPE_ENCODE_BASE64
:
574 case OPTYPE_DECOMP
: // v1 v2 v3
585 case OPTYPE_LENGTHOF
: // ti1
586 case OPTYPE_SIZEOF
: // ti1
587 case OPTYPE_VALUEOF
: // ti1
591 case OPTYPE_ISPRESENT
:
592 case OPTYPE_TTCN2STRING
:
595 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
599 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
604 case OPTYPE_UNDEF_RUNNING
:
605 case OPTYPE_TMR_READ
:
606 case OPTYPE_TMR_RUNNING
:
607 case OPTYPE_ACTIVATE
:
610 case OPTYPE_EXECUTE
: // r1 [v2]
614 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
619 case OPTYPE_MATCH
: // v1 t2
623 case OPTYPE_ISCHOSEN
: // r1 i2
627 case OPTYPE_ISCHOSEN_V
: // v1 i2
631 case OPTYPE_ISCHOSEN_T
: // t1 i2
635 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
637 if(u
.expr
.state
!=EXPR_CHECKED
)
638 delete u
.expr
.t_list2
;
640 delete u
.expr
.ap_list2
;
642 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
644 if(u
.expr
.state
!=EXPR_CHECKED
)
645 delete u
.expr
.t_list2
;
647 delete u
.expr
.ap_list2
;
651 case OPTYPE_ANY2UNISTR
:
652 delete u
.expr
.logargs
;
655 FATAL_ERROR("Value::clean_up_expr()");
659 void Value::copy_and_destroy(Value
*src
)
662 valuetype
= src
->valuetype
;
664 // update the pointer used for caching if it points to the value itself
665 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
666 src
->valuetype
= V_ERROR
;
670 Value::Value(valuetype_t p_vt
)
671 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
682 u
.oid_comps
=new vector
<OID_comp
>();
685 u
.ids
=new map
<string
, Identifier
>();
688 FATAL_ERROR("Value::Value()");
692 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
693 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
697 u
.val_bool
=p_val_bool
;
700 FATAL_ERROR("Value::Value()");
704 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
705 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
709 u
.val_Int
=new int_val_t(p_val_Int
);
712 FATAL_ERROR("Value::Value()");
716 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
717 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
724 FATAL_ERROR("Value::Value()");
728 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
729 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
731 if(!p_val_str
) FATAL_ERROR("NULL parameter");
738 set_val_str(p_val_str
);
741 FATAL_ERROR("Value::Value()");
745 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
746 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
748 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
749 set_val_ustr(p_val_ustr
);
750 u
.ustr
.convert_str
= false;
753 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
754 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
756 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
759 u
.char_syms
= p_char_syms
;
762 FATAL_ERROR("Value::Value()");
766 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
767 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
770 FATAL_ERROR("NULL parameter");
774 case V_UNDEF_LOWERID
:
778 FATAL_ERROR("Value::Value()");
782 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
783 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
786 FATAL_ERROR("NULL parameter");
789 u
.choice
.alt_name
=p_id
;
790 u
.choice
.alt_value
=p_val
;
793 FATAL_ERROR("Value::Value()");
797 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
798 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
802 u
.val_Real
=p_val_Real
;
805 FATAL_ERROR("Value::Value()");
809 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
810 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
812 if(!p_vs
) FATAL_ERROR("NULL parameter");
820 FATAL_ERROR("Value::Value()");
824 Value::Value(valuetype_t p_vt
, Value
*p_v
,
825 Ttcn::ParsedActualParameters
*p_t_list
)
826 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
828 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
832 u
.invoke
.t_list
= p_t_list
;
833 u
.invoke
.ap_list
= 0;
836 FATAL_ERROR("Value::Value()");
841 Value::Value(operationtype_t p_optype
)
842 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
844 u
.expr
.v_optype
= p_optype
;
845 u
.expr
.state
= EXPR_NOT_CHECKED
;
848 case OPTYPE_COMP_NULL
:
849 case OPTYPE_COMP_MTC
:
850 case OPTYPE_COMP_SYSTEM
:
851 case OPTYPE_COMP_SELF
:
852 case OPTYPE_COMP_RUNNING_ANY
:
853 case OPTYPE_COMP_RUNNING_ALL
:
854 case OPTYPE_COMP_ALIVE_ANY
:
855 case OPTYPE_COMP_ALIVE_ALL
:
856 case OPTYPE_TMR_RUNNING_ANY
:
857 case OPTYPE_GETVERDICT
:
858 case OPTYPE_TESTCASENAME
:
859 case OPTYPE_PROF_RUNNING
:
862 FATAL_ERROR("Value::Value()");
867 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
868 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
870 u
.expr
.v_optype
= p_optype
;
871 u
.expr
.state
= EXPR_NOT_CHECKED
;
873 case OPTYPE_UNARYPLUS
:
874 case OPTYPE_UNARYMINUS
:
881 case OPTYPE_CHAR2INT
:
882 case OPTYPE_CHAR2OCT
:
883 case OPTYPE_COMP_RUNNING
:
884 case OPTYPE_COMP_ALIVE
:
885 case OPTYPE_FLOAT2INT
:
886 case OPTYPE_FLOAT2STR
:
891 case OPTYPE_INT2CHAR
:
892 case OPTYPE_INT2FLOAT
:
894 case OPTYPE_INT2UNICHAR
:
896 case OPTYPE_OCT2CHAR
:
901 case OPTYPE_STR2FLOAT
:
905 case OPTYPE_UNICHAR2INT
:
906 case OPTYPE_UNICHAR2CHAR
:
907 case OPTYPE_ENUM2INT
:
908 case OPTYPE_RNDWITHVAL
:
909 case OPTYPE_REMOVE_BOM
:
910 case OPTYPE_GET_STRINGENCODING
:
911 case OPTYPE_DECODE_BASE64
:
912 if(!p_v1
) FATAL_ERROR("Value::Value()");
916 FATAL_ERROR("Value::Value()");
921 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
922 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
924 u
.expr
.v_optype
= p_optype
;
925 u
.expr
.state
= EXPR_NOT_CHECKED
;
927 case OPTYPE_LENGTHOF
:
933 case OPTYPE_ENCVALUE_UNICHAR
:
934 case OPTYPE_ISPRESENT
:
935 case OPTYPE_TTCN2STRING
:
936 if(!p_ti1
) FATAL_ERROR("Value::Value()");
940 FATAL_ERROR("Value::Value()");
945 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
946 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
948 u
.expr
.v_optype
= p_optype
;
949 u
.expr
.state
= EXPR_NOT_CHECKED
;
951 case OPTYPE_UNDEF_RUNNING
:
952 case OPTYPE_TMR_READ
:
953 case OPTYPE_TMR_RUNNING
:
954 case OPTYPE_ACTIVATE
:
955 if(!p_r1
) FATAL_ERROR("Value::Value()");
959 FATAL_ERROR("Value::Value()");
964 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
965 Ttcn::ParsedActualParameters
*p_ap_list
)
966 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
968 u
.expr
.v_optype
= p_optype
;
969 u
.expr
.state
= EXPR_NOT_CHECKED
;
971 case OPTYPE_ACTIVATE_REFD
:
972 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
974 u
.expr
.t_list2
= p_ap_list
;
977 FATAL_ERROR("Value::Value()");
982 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
983 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
984 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
986 u
.expr
.v_optype
= p_optype
;
987 u
.expr
.state
= EXPR_NOT_CHECKED
;
989 case OPTYPE_EXECUTE_REFD
:
990 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
992 u
.expr
.t_list2
= p_t_list2
;
996 FATAL_ERROR("Value::Value()");
1001 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
1002 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1004 u
.expr
.v_optype
= p_optype
;
1005 u
.expr
.state
= EXPR_NOT_CHECKED
;
1007 case OPTYPE_EXECUTE
:
1008 if(!p_r1
) FATAL_ERROR("Value::Value()");
1013 FATAL_ERROR("Value::Value()");
1018 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
1019 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
1020 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1022 u
.expr
.v_optype
= p_optype
;
1023 u
.expr
.state
= EXPR_NOT_CHECKED
;
1025 case OPTYPE_COMP_CREATE
:
1026 if(!p_r1
) FATAL_ERROR("Value::Value()");
1033 FATAL_ERROR("Value::Value()");
1038 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
1039 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1041 u
.expr
.v_optype
= p_optype
;
1042 u
.expr
.state
= EXPR_NOT_CHECKED
;
1045 case OPTYPE_SUBTRACT
:
1046 case OPTYPE_MULTIPLY
:
1067 case OPTYPE_INT2BIT
:
1068 case OPTYPE_INT2HEX
:
1069 case OPTYPE_INT2OCT
:
1070 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1074 case OPTYPE_UNICHAR2OCT
:
1075 case OPTYPE_OCT2UNICHAR
:
1076 case OPTYPE_ENCODE_BASE64
:
1077 if(!p_v1
) FATAL_ERROR("Value::Value()");
1079 // p_v2 may be NULL if there is no second param
1083 FATAL_ERROR("Value::Value()");
1088 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1089 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1090 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1092 u
.expr
.v_optype
= p_optype
;
1093 u
.expr
.state
= EXPR_NOT_CHECKED
;
1095 case OPTYPE_REPLACE
:
1096 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1103 FATAL_ERROR("Value::Value()");
1108 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1109 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1111 u
.expr
.v_optype
= p_optype
;
1112 u
.expr
.state
= EXPR_NOT_CHECKED
;
1115 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1121 FATAL_ERROR("Value::Value()");
1126 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
)
1127 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1129 u
.expr
.v_optype
= p_optype
;
1130 u
.expr
.state
= EXPR_NOT_CHECKED
;
1132 case OPTYPE_ENCVALUE_UNICHAR
:
1133 if(!p_ti1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1138 FATAL_ERROR("Value::Value()");
1143 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1144 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1146 u
.expr
.v_optype
=p_optype
;
1147 u
.expr
.state
=EXPR_NOT_CHECKED
;
1150 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1156 FATAL_ERROR("Value::Value()");
1161 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1162 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1164 u
.expr
.v_optype
=p_optype
;
1165 u
.expr
.state
=EXPR_NOT_CHECKED
;
1168 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1174 FATAL_ERROR("Value::Value()");
1179 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1180 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1182 u
.expr
.v_optype
= p_optype
;
1183 u
.expr
.state
= EXPR_NOT_CHECKED
;
1186 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1191 FATAL_ERROR("Value::Value()");
1196 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1198 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1200 u
.expr
.v_optype
= p_optype
;
1201 u
.expr
.state
= EXPR_NOT_CHECKED
;
1203 case OPTYPE_ISCHOSEN
:
1204 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1209 FATAL_ERROR("Value::Value()");
1213 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1214 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1216 u
.expr
.v_optype
= p_optype
;
1217 u
.expr
.state
= EXPR_NOT_CHECKED
;
1219 case OPTYPE_LOG2STR
:
1220 case OPTYPE_ANY2UNISTR
:
1221 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1222 u
.expr
.logargs
= p_logargs
;
1225 FATAL_ERROR("Value::Value()");
1229 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1230 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1232 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1233 switch (p_macrotype
) {
1234 case MACRO_MODULEID
:
1235 case MACRO_FILENAME
:
1236 case MACRO_BFILENAME
:
1237 case MACRO_FILEPATH
:
1238 case MACRO_LINENUMBER
:
1239 case MACRO_LINENUMBER_C
:
1240 case MACRO_DEFINITIONID
:
1242 case MACRO_TESTCASEID
:
1245 FATAL_ERROR("Value::Value()");
1247 u
.macro
= p_macrotype
;
1250 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1251 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1253 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1260 FATAL_ERROR("Value::Value()");
1264 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1265 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1267 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1271 u
.ref
.refd_last
= 0;
1277 FATAL_ERROR("Value::Value()");
1281 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1282 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1284 if(!p_block
) FATAL_ERROR("NULL parameter");
1290 FATAL_ERROR("Value::Value()");
1294 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1295 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1297 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1298 switch (p_verdict
) {
1301 case Verdict_INCONC
:
1306 FATAL_ERROR("Value::Value()");
1308 u
.verdict
= p_verdict
;
1311 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1312 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1314 u
.expr
.v_optype
= p_optype
;
1315 u
.expr
.state
= EXPR_NOT_CHECKED
;
1318 case OPTYPE_DECVALUE_UNICHAR
:
1319 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1324 FATAL_ERROR("Value::Value()");
1329 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
,
1331 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1333 u
.expr
.v_optype
= p_optype
;
1334 u
.expr
.state
= EXPR_NOT_CHECKED
;
1336 case OPTYPE_DECVALUE_UNICHAR
:
1337 if(!p_r1
|| !p_r2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1343 FATAL_ERROR("Value::Value()");
1352 Value
*Value::clone() const
1354 return new Value(*this);
1357 Value::operationtype_t
Value::get_optype() const
1359 if(valuetype
!=V_EXPR
)
1360 FATAL_ERROR("Value::get_optype()");
1361 return u
.expr
.v_optype
;
1364 void Value::set_my_governor(Type
*p_gov
)
1367 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1371 Type
*Value::get_my_governor() const
1376 void Value::set_fullname(const string
& p_fullname
)
1378 GovernedSimple::set_fullname(p_fullname
);
1381 u
.char_syms
->set_fullname(p_fullname
);
1385 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1386 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1389 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1390 u
.choice
.alt_name
->get_dispname());
1395 u
.val_vs
->set_fullname(p_fullname
);
1399 u
.val_nvs
->set_fullname(p_fullname
);
1402 u
.ref
.ref
->set_fullname(p_fullname
);
1405 u
.refered
->set_fullname(p_fullname
);
1408 u
.invoke
.v
->set_fullname(p_fullname
);
1409 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1410 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1413 set_fullname_expr(p_fullname
);
1420 void Value::set_my_scope(Scope
*p_scope
)
1422 GovernedSimple::set_my_scope(p_scope
);
1425 u
.char_syms
->set_my_scope(p_scope
);
1429 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1430 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1433 u
.choice
.alt_value
->set_my_scope(p_scope
);
1438 u
.val_vs
->set_my_scope(p_scope
);
1442 u
.val_nvs
->set_my_scope(p_scope
);
1445 u
.ref
.ref
->set_my_scope(p_scope
);
1448 u
.refered
->set_my_scope(p_scope
);
1451 u
.invoke
.v
->set_my_scope(p_scope
);
1452 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1453 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1456 set_my_scope_expr(p_scope
);
1463 void Value::set_fullname_expr(const string
& p_fullname
)
1465 switch (u
.expr
.v_optype
) {
1466 case OPTYPE_RND
: // -
1467 case OPTYPE_COMP_NULL
:
1468 case OPTYPE_COMP_MTC
:
1469 case OPTYPE_COMP_SYSTEM
:
1470 case OPTYPE_COMP_SELF
:
1471 case OPTYPE_COMP_RUNNING_ANY
:
1472 case OPTYPE_COMP_RUNNING_ALL
:
1473 case OPTYPE_COMP_ALIVE_ANY
:
1474 case OPTYPE_COMP_ALIVE_ALL
:
1475 case OPTYPE_TMR_RUNNING_ANY
:
1476 case OPTYPE_GETVERDICT
:
1477 case OPTYPE_TESTCASENAME
:
1478 case OPTYPE_PROF_RUNNING
:
1480 case OPTYPE_UNARYPLUS
: // v1
1481 case OPTYPE_UNARYMINUS
:
1484 case OPTYPE_BIT2HEX
:
1485 case OPTYPE_BIT2INT
:
1486 case OPTYPE_BIT2OCT
:
1487 case OPTYPE_BIT2STR
:
1488 case OPTYPE_CHAR2INT
:
1489 case OPTYPE_CHAR2OCT
:
1490 case OPTYPE_COMP_RUNNING
:
1491 case OPTYPE_COMP_ALIVE
:
1492 case OPTYPE_FLOAT2INT
:
1493 case OPTYPE_FLOAT2STR
:
1494 case OPTYPE_HEX2BIT
:
1495 case OPTYPE_HEX2INT
:
1496 case OPTYPE_HEX2OCT
:
1497 case OPTYPE_HEX2STR
:
1498 case OPTYPE_INT2CHAR
:
1499 case OPTYPE_INT2FLOAT
:
1500 case OPTYPE_INT2STR
:
1501 case OPTYPE_INT2UNICHAR
:
1502 case OPTYPE_OCT2BIT
:
1503 case OPTYPE_OCT2CHAR
:
1504 case OPTYPE_OCT2HEX
:
1505 case OPTYPE_OCT2INT
:
1506 case OPTYPE_OCT2STR
:
1507 case OPTYPE_STR2BIT
:
1508 case OPTYPE_STR2FLOAT
:
1509 case OPTYPE_STR2HEX
:
1510 case OPTYPE_STR2INT
:
1511 case OPTYPE_STR2OCT
:
1512 case OPTYPE_UNICHAR2INT
:
1513 case OPTYPE_UNICHAR2CHAR
:
1514 case OPTYPE_ENUM2INT
:
1515 case OPTYPE_RNDWITHVAL
:
1516 case OPTYPE_REMOVE_BOM
:
1517 case OPTYPE_GET_STRINGENCODING
:
1518 case OPTYPE_DECODE_BASE64
:
1519 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1521 case OPTYPE_ADD
: // v1 v2
1522 case OPTYPE_SUBTRACT
:
1523 case OPTYPE_MULTIPLY
:
1544 case OPTYPE_INT2BIT
:
1545 case OPTYPE_INT2HEX
:
1546 case OPTYPE_INT2OCT
:
1547 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1548 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1550 case OPTYPE_UNICHAR2OCT
:
1551 case OPTYPE_OCT2UNICHAR
:
1552 case OPTYPE_ENCODE_BASE64
:
1553 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1554 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1557 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1558 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1561 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1562 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1563 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1566 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1567 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1568 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1570 case OPTYPE_DECOMP
: // v1 v2 v3
1571 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1572 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1573 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1575 case OPTYPE_REPLACE
:
1576 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1577 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1578 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1579 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1581 case OPTYPE_LENGTHOF
: // ti1
1582 case OPTYPE_SIZEOF
: // ti1
1583 case OPTYPE_VALUEOF
: // ti1
1584 case OPTYPE_ISVALUE
:
1585 case OPTYPE_ISBOUND
:
1587 case OPTYPE_ISPRESENT
:
1588 case OPTYPE_TTCN2STRING
:
1589 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1591 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
1592 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1593 if (u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1595 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1596 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1597 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1598 if (u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1599 case OPTYPE_UNDEF_RUNNING
: // r1
1600 case OPTYPE_TMR_READ
:
1601 case OPTYPE_TMR_RUNNING
:
1602 case OPTYPE_ACTIVATE
:
1603 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1605 case OPTYPE_EXECUTE
: // r1 [v2]
1606 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1607 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1609 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1610 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1611 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1612 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1614 case OPTYPE_MATCH
: // v1 t2
1615 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1616 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1618 case OPTYPE_ISCHOSEN
: // r1 i2
1619 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1621 case OPTYPE_ISCHOSEN_V
: // v1 i2
1622 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1624 case OPTYPE_ISCHOSEN_T
: // t1 i2
1625 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1627 case OPTYPE_ACTIVATE_REFD
:
1628 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1629 if(u
.expr
.state
!=EXPR_CHECKED
)
1630 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1632 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1634 case OPTYPE_EXECUTE_REFD
:
1635 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1636 if(u
.expr
.state
!=EXPR_CHECKED
)
1637 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1639 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1641 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1643 case OPTYPE_LOG2STR
:
1644 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1646 case OPTYPE_ANY2UNISTR
:
1647 u
.expr
.logargs
->set_fullname(p_fullname
+".<logarg>");
1650 FATAL_ERROR("Value::set_fullname_expr()");
1654 void Value::set_my_scope_expr(Scope
*p_scope
)
1656 switch (u
.expr
.v_optype
) {
1657 case OPTYPE_RND
: // -
1658 case OPTYPE_COMP_NULL
:
1659 case OPTYPE_COMP_MTC
:
1660 case OPTYPE_COMP_SYSTEM
:
1661 case OPTYPE_COMP_SELF
:
1662 case OPTYPE_COMP_RUNNING_ANY
:
1663 case OPTYPE_COMP_RUNNING_ALL
:
1664 case OPTYPE_COMP_ALIVE_ANY
:
1665 case OPTYPE_COMP_ALIVE_ALL
:
1666 case OPTYPE_TMR_RUNNING_ANY
:
1667 case OPTYPE_GETVERDICT
:
1668 case OPTYPE_TESTCASENAME
:
1669 case OPTYPE_PROF_RUNNING
:
1671 case OPTYPE_UNARYPLUS
: // v1
1672 case OPTYPE_UNARYMINUS
:
1675 case OPTYPE_BIT2HEX
:
1676 case OPTYPE_BIT2INT
:
1677 case OPTYPE_BIT2OCT
:
1678 case OPTYPE_BIT2STR
:
1679 case OPTYPE_CHAR2INT
:
1680 case OPTYPE_CHAR2OCT
:
1681 case OPTYPE_COMP_RUNNING
:
1682 case OPTYPE_COMP_ALIVE
:
1683 case OPTYPE_FLOAT2INT
:
1684 case OPTYPE_FLOAT2STR
:
1685 case OPTYPE_HEX2BIT
:
1686 case OPTYPE_HEX2INT
:
1687 case OPTYPE_HEX2OCT
:
1688 case OPTYPE_HEX2STR
:
1689 case OPTYPE_INT2CHAR
:
1690 case OPTYPE_INT2FLOAT
:
1691 case OPTYPE_INT2STR
:
1692 case OPTYPE_INT2UNICHAR
:
1693 case OPTYPE_OCT2BIT
:
1694 case OPTYPE_OCT2CHAR
:
1695 case OPTYPE_OCT2HEX
:
1696 case OPTYPE_OCT2INT
:
1697 case OPTYPE_OCT2STR
:
1698 case OPTYPE_STR2BIT
:
1699 case OPTYPE_STR2FLOAT
:
1700 case OPTYPE_STR2HEX
:
1701 case OPTYPE_STR2INT
:
1702 case OPTYPE_STR2OCT
:
1703 case OPTYPE_UNICHAR2INT
:
1704 case OPTYPE_UNICHAR2CHAR
:
1705 case OPTYPE_ENUM2INT
:
1706 case OPTYPE_RNDWITHVAL
:
1707 case OPTYPE_REMOVE_BOM
:
1708 case OPTYPE_GET_STRINGENCODING
:
1709 case OPTYPE_DECODE_BASE64
:
1710 u
.expr
.v1
->set_my_scope(p_scope
);
1712 case OPTYPE_ADD
: // v1 v2
1713 case OPTYPE_SUBTRACT
:
1714 case OPTYPE_MULTIPLY
:
1735 case OPTYPE_INT2BIT
:
1736 case OPTYPE_INT2HEX
:
1737 case OPTYPE_INT2OCT
:
1738 u
.expr
.v1
->set_my_scope(p_scope
);
1739 u
.expr
.v2
->set_my_scope(p_scope
);
1741 case OPTYPE_UNICHAR2OCT
:
1742 case OPTYPE_OCT2UNICHAR
:
1743 case OPTYPE_ENCODE_BASE64
:
1744 u
.expr
.v1
->set_my_scope(p_scope
);
1745 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1748 u
.expr
.r1
->set_my_scope(p_scope
);
1749 u
.expr
.r2
->set_my_scope(p_scope
);
1752 u
.expr
.ti1
->set_my_scope(p_scope
);
1753 u
.expr
.v2
->set_my_scope(p_scope
);
1754 u
.expr
.v3
->set_my_scope(p_scope
);
1757 u
.expr
.ti1
->set_my_scope(p_scope
);
1758 u
.expr
.t2
->set_my_scope(p_scope
);
1759 u
.expr
.v3
->set_my_scope(p_scope
);
1761 case OPTYPE_DECOMP
: // v1 v2 v3
1762 u
.expr
.v1
->set_my_scope(p_scope
);
1763 u
.expr
.v2
->set_my_scope(p_scope
);
1764 u
.expr
.v3
->set_my_scope(p_scope
);
1766 case OPTYPE_REPLACE
:
1767 u
.expr
.ti1
->set_my_scope(p_scope
);
1768 u
.expr
.v2
->set_my_scope(p_scope
);
1769 u
.expr
.v3
->set_my_scope(p_scope
);
1770 u
.expr
.ti4
->set_my_scope(p_scope
);
1772 case OPTYPE_LENGTHOF
: // ti1
1773 case OPTYPE_SIZEOF
: // ti1
1774 case OPTYPE_VALUEOF
: // ti1
1775 case OPTYPE_ISVALUE
:
1776 case OPTYPE_ISBOUND
:
1778 case OPTYPE_ISPRESENT
:
1779 case OPTYPE_TTCN2STRING
:
1780 u
.expr
.ti1
->set_my_scope(p_scope
);
1782 case OPTYPE_ENCVALUE_UNICHAR
: //ti1 [v2]
1783 u
.expr
.ti1
->set_my_scope(p_scope
);
1784 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1786 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1787 u
.expr
.r1
->set_my_scope(p_scope
);
1788 u
.expr
.r2
->set_my_scope(p_scope
);
1789 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1791 case OPTYPE_UNDEF_RUNNING
: // r1
1792 case OPTYPE_TMR_READ
:
1793 case OPTYPE_TMR_RUNNING
:
1794 case OPTYPE_ACTIVATE
:
1795 u
.expr
.r1
->set_my_scope(p_scope
);
1797 case OPTYPE_EXECUTE
: // r1 [v2]
1798 u
.expr
.r1
->set_my_scope(p_scope
);
1799 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1801 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1802 u
.expr
.r1
->set_my_scope(p_scope
);
1803 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1804 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1806 case OPTYPE_MATCH
: // v1 t2
1807 u
.expr
.v1
->set_my_scope(p_scope
);
1808 u
.expr
.t2
->set_my_scope(p_scope
);
1810 case OPTYPE_ISCHOSEN
: // r1 i2
1811 u
.expr
.r1
->set_my_scope(p_scope
);
1813 case OPTYPE_ISCHOSEN_V
: // v1 i2
1814 u
.expr
.v1
->set_my_scope(p_scope
);
1816 case OPTYPE_ISCHOSEN_T
: // t1 i2
1817 u
.expr
.t1
->set_my_scope(p_scope
);
1819 case OPTYPE_ACTIVATE_REFD
:
1820 u
.expr
.v1
->set_my_scope(p_scope
);
1821 if(u
.expr
.state
!=EXPR_CHECKED
) {
1822 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1824 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1826 case OPTYPE_EXECUTE_REFD
:
1827 u
.expr
.v1
->set_my_scope(p_scope
);
1828 if(u
.expr
.state
!=EXPR_CHECKED
) {
1829 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1831 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1834 u
.expr
.v3
->set_my_scope(p_scope
);
1836 case OPTYPE_LOG2STR
:
1837 case OPTYPE_ANY2UNISTR
:
1838 u
.expr
.logargs
->set_my_scope(p_scope
);
1841 FATAL_ERROR("Value::set_my_scope_expr()");
1845 void Value::set_genname_recursive(const string
& p_genname
)
1847 size_t genname_len
= p_genname
.size();
1848 if (genname_len
>= 4 &&
1849 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1850 // if the genname ends with ()() (i.e. the value stands for an optional
1851 // field) then drop the last () from the own genname, but leave it for
1852 // the embedded values
1853 set_genname(p_genname
.substr(0, genname_len
- 2));
1854 } else set_genname(p_genname
);
1857 string
embedded_genname(p_genname
);
1858 embedded_genname
+= '.';
1859 // If this is a choice value for an anytype, prepend the AT_ prefix
1860 // to the name of the alternative. The genname is used later in
1861 // Common::Value::generate_code_init_se()
1862 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1863 embedded_genname
+= "AT_";
1864 embedded_genname
+= u
.choice
.alt_name
->get_name();
1865 embedded_genname
+= "()";
1866 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1870 if (!is_indexed()) {
1871 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1872 for (size_t i
= 0; i
< nof_vs
; i
++) {
1873 string
embedded_genname(p_genname
);
1874 embedded_genname
+= '[';
1875 embedded_genname
+= Int2string(i
);
1876 embedded_genname
+= ']';
1877 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1880 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1881 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1882 string
embedded_genname(p_genname
);
1883 embedded_genname
+= '[';
1884 embedded_genname
+= Int2string(i
);
1885 embedded_genname
+= ']';
1886 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1887 ->set_genname_recursive(embedded_genname
);
1892 if (!my_governor
) return; // error recovery
1893 Type
*type
= my_governor
->get_type_refd_last();
1894 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1895 Int offset
= type
->get_dimension()->get_offset();
1896 if (!is_indexed()) {
1897 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1898 for (size_t i
= 0; i
< nof_vs
; i
++) {
1899 string
embedded_genname(p_genname
);
1900 embedded_genname
+= '[';
1901 embedded_genname
+= Int2string(offset
+ i
);
1902 embedded_genname
+= ']';
1903 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1906 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1907 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1908 string
embedded_genname(p_genname
);
1909 embedded_genname
+= '[';
1910 embedded_genname
+= Int2string(offset
+ i
);
1911 embedded_genname
+= ']';
1912 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1913 ->set_genname_recursive(embedded_genname
);
1919 if (!my_governor
) return; // error recovery
1920 Type
*t
= my_governor
->get_type_refd_last();
1921 if (!t
->is_secho()) return; // error recovery
1922 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1923 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1924 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1925 const Identifier
& id
= nv
->get_name();
1926 if (!t
->has_comp_withName(id
)) return; // error recovery
1927 string
embedded_genname(p_genname
);
1928 embedded_genname
+= '.';
1929 embedded_genname
+= id
.get_name();
1930 embedded_genname
+= "()";
1931 if (t
->get_comp_byName(id
)->get_is_optional())
1932 embedded_genname
+= "()";
1933 nv
->get_value()->set_genname_recursive(embedded_genname
);
1941 void Value::set_genname_prefix(const char *p_genname_prefix
)
1943 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1946 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1951 if (!is_indexed()) {
1952 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1953 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1955 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1956 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1957 ->set_genname_prefix(p_genname_prefix
);
1962 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1963 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1964 ->set_genname_prefix(p_genname_prefix
);
1971 void Value::set_code_section(code_section_t p_code_section
)
1973 GovernedSimple::set_code_section(p_code_section
);
1976 switch (u
.expr
.v_optype
) {
1977 case OPTYPE_RND
: // -
1978 case OPTYPE_COMP_NULL
:
1979 case OPTYPE_COMP_MTC
:
1980 case OPTYPE_COMP_SYSTEM
:
1981 case OPTYPE_COMP_SELF
:
1982 case OPTYPE_COMP_RUNNING_ANY
:
1983 case OPTYPE_COMP_RUNNING_ALL
:
1984 case OPTYPE_COMP_ALIVE_ANY
:
1985 case OPTYPE_COMP_ALIVE_ALL
:
1986 case OPTYPE_TMR_RUNNING_ANY
:
1987 case OPTYPE_GETVERDICT
:
1988 case OPTYPE_TESTCASENAME
:
1989 case OPTYPE_PROF_RUNNING
:
1991 case OPTYPE_UNARYPLUS
: // v1
1992 case OPTYPE_UNARYMINUS
:
1995 case OPTYPE_BIT2HEX
:
1996 case OPTYPE_BIT2INT
:
1997 case OPTYPE_BIT2OCT
:
1998 case OPTYPE_BIT2STR
:
1999 case OPTYPE_CHAR2INT
:
2000 case OPTYPE_CHAR2OCT
:
2001 case OPTYPE_COMP_RUNNING
:
2002 case OPTYPE_COMP_ALIVE
:
2003 case OPTYPE_FLOAT2INT
:
2004 case OPTYPE_FLOAT2STR
:
2005 case OPTYPE_HEX2BIT
:
2006 case OPTYPE_HEX2INT
:
2007 case OPTYPE_HEX2OCT
:
2008 case OPTYPE_HEX2STR
:
2009 case OPTYPE_INT2CHAR
:
2010 case OPTYPE_INT2FLOAT
:
2011 case OPTYPE_INT2STR
:
2012 case OPTYPE_INT2UNICHAR
:
2013 case OPTYPE_OCT2BIT
:
2014 case OPTYPE_OCT2CHAR
:
2015 case OPTYPE_OCT2HEX
:
2016 case OPTYPE_OCT2INT
:
2017 case OPTYPE_OCT2STR
:
2018 case OPTYPE_STR2BIT
:
2019 case OPTYPE_STR2FLOAT
:
2020 case OPTYPE_STR2HEX
:
2021 case OPTYPE_STR2INT
:
2022 case OPTYPE_STR2OCT
:
2023 case OPTYPE_UNICHAR2INT
:
2024 case OPTYPE_UNICHAR2CHAR
:
2025 case OPTYPE_ENUM2INT
:
2026 case OPTYPE_RNDWITHVAL
:
2027 case OPTYPE_GET_STRINGENCODING
:
2028 case OPTYPE_DECODE_BASE64
:
2029 case OPTYPE_REMOVE_BOM
:
2030 u
.expr
.v1
->set_code_section(p_code_section
);
2032 case OPTYPE_ADD
: // v1 v2
2033 case OPTYPE_SUBTRACT
:
2034 case OPTYPE_MULTIPLY
:
2055 case OPTYPE_INT2BIT
:
2056 case OPTYPE_INT2HEX
:
2057 case OPTYPE_INT2OCT
:
2058 u
.expr
.v1
->set_code_section(p_code_section
);
2059 u
.expr
.v2
->set_code_section(p_code_section
);
2061 case OPTYPE_UNICHAR2OCT
:
2062 case OPTYPE_OCT2UNICHAR
:
2063 case OPTYPE_ENCODE_BASE64
:
2064 u
.expr
.v1
->set_code_section(p_code_section
);
2065 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2068 u
.expr
.r1
->set_code_section(p_code_section
);
2069 u
.expr
.r2
->set_code_section(p_code_section
);
2072 u
.expr
.ti1
->set_code_section(p_code_section
);
2073 u
.expr
.v2
->set_code_section(p_code_section
);
2074 u
.expr
.v3
->set_code_section(p_code_section
);
2077 u
.expr
.ti1
->set_code_section(p_code_section
);
2078 u
.expr
.t2
->set_code_section(p_code_section
);
2079 u
.expr
.v3
->set_code_section(p_code_section
);
2081 case OPTYPE_DECOMP
: // v1 v2 v3
2082 u
.expr
.v1
->set_code_section(p_code_section
);
2083 u
.expr
.v2
->set_code_section(p_code_section
);
2084 u
.expr
.v3
->set_code_section(p_code_section
);
2086 case OPTYPE_REPLACE
:
2087 u
.expr
.ti1
->set_code_section(p_code_section
);
2088 u
.expr
.v2
->set_code_section(p_code_section
);
2089 u
.expr
.v3
->set_code_section(p_code_section
);
2090 u
.expr
.ti4
->set_code_section(p_code_section
);
2092 case OPTYPE_LENGTHOF
: // ti1
2093 case OPTYPE_SIZEOF
: // ti1
2094 case OPTYPE_VALUEOF
: // ti1
2095 case OPTYPE_ISVALUE
:
2096 case OPTYPE_ISBOUND
:
2098 case OPTYPE_ISPRESENT
:
2099 case OPTYPE_TTCN2STRING
:
2100 u
.expr
.ti1
->set_code_section(p_code_section
);
2102 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
2103 u
.expr
.ti1
->set_code_section(p_code_section
);
2104 if (u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2106 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
2107 u
.expr
.r1
->set_code_section(p_code_section
);
2108 u
.expr
.r2
->set_code_section(p_code_section
);
2109 if (u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2111 case OPTYPE_UNDEF_RUNNING
: // r1
2112 case OPTYPE_TMR_READ
:
2113 case OPTYPE_TMR_RUNNING
:
2114 case OPTYPE_ACTIVATE
:
2115 u
.expr
.r1
->set_code_section(p_code_section
);
2117 case OPTYPE_EXECUTE
: // r1 [v2]
2118 u
.expr
.r1
->set_code_section(p_code_section
);
2119 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2121 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2122 u
.expr
.r1
->set_code_section(p_code_section
);
2123 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2124 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2126 case OPTYPE_MATCH
: // v1 t2
2127 u
.expr
.v1
->set_code_section(p_code_section
);
2128 u
.expr
.t2
->set_code_section(p_code_section
);
2130 case OPTYPE_ISCHOSEN
: // r1 i2
2131 u
.expr
.r1
->set_code_section(p_code_section
);
2133 case OPTYPE_ISCHOSEN_V
: // v1 i2
2134 u
.expr
.v1
->set_code_section(p_code_section
);
2136 case OPTYPE_ISCHOSEN_T
: // t1 i2
2137 u
.expr
.t1
->set_code_section(p_code_section
);
2139 case OPTYPE_ACTIVATE_REFD
:
2140 u
.expr
.v1
->set_code_section(p_code_section
);
2141 if(u
.expr
.state
!=EXPR_CHECKED
)
2142 u
.expr
.t_list2
->set_code_section(p_code_section
);
2144 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2145 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2146 u
.expr
.state
= EXPR_CHECKED
;
2149 case OPTYPE_EXECUTE_REFD
:
2150 u
.expr
.v1
->set_code_section(p_code_section
);
2151 if(u
.expr
.state
!=EXPR_CHECKED
)
2152 u
.expr
.t_list2
->set_code_section(p_code_section
);
2154 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2155 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2156 u
.expr
.state
= EXPR_CHECKED
;
2159 u
.expr
.v3
->set_code_section(p_code_section
);
2161 case OPTYPE_LOG2STR
:
2162 case OPTYPE_ANY2UNISTR
:
2163 u
.expr
.logargs
->set_code_section(p_code_section
);
2166 FATAL_ERROR("Value::set_code_section()");
2170 u
.choice
.alt_value
->set_code_section(p_code_section
);
2175 if (!is_indexed()) {
2176 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2177 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2179 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2180 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2185 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2186 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2187 ->set_code_section(p_code_section
);
2190 u
.ref
.ref
->set_code_section(p_code_section
);
2193 u
.refered
->set_code_section(p_code_section
);
2196 u
.invoke
.v
->set_code_section(p_code_section
);
2197 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2198 if(u
.invoke
.ap_list
)
2199 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2200 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2207 void Value::change_sign()
2211 *u
.val_Int
=-*u
.val_Int
;
2219 FATAL_ERROR("Value::change_sign()");
2223 void Value::add_oid_comp(OID_comp
* p_comp
)
2226 FATAL_ERROR("NULL parameter");
2227 u
.oid_comps
->add(p_comp
);
2228 p_comp
->set_fullname(get_fullname()+"."
2229 +Int2string(u
.oid_comps
->size()));
2230 p_comp
->set_my_scope(my_scope
);
2233 void Value::set_valuetype(valuetype_t p_valuetype
)
2235 if (valuetype
== V_ERROR
) return;
2236 else if (p_valuetype
== V_ERROR
) {
2237 if(valuetype
==V_EXPR
) {
2238 switch(u
.expr
.state
) {
2240 u
.expr
.state
=EXPR_CHECKING_ERR
;
2242 case EXPR_CHECKING_ERR
:
2249 valuetype
= V_ERROR
;
2253 case V_UNDEF_LOWERID
:
2254 switch(p_valuetype
) {
2259 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2260 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2261 u
.ref
.ref
->set_my_scope(get_my_scope());
2262 u
.ref
.ref
->set_fullname(get_fullname());
2263 u
.ref
.ref
->set_location(*this);
2264 u
.ref
.refd_last
= 0;
2267 FATAL_ERROR("Value::set_valuetype()");
2270 case V_UNDEF_BLOCK
: {
2271 Block
*t_block
=u
.block
;
2273 switch(p_valuetype
) {
2275 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2276 v
=dynamic_cast<Value
*>(node
);
2279 u
.ids
=new map
<string
, Identifier
>();
2282 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2286 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2287 v
=dynamic_cast<Value
*>(node
);
2290 u
.val_vs
=new Values();
2293 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2295 u
.val_vs
->set_my_scope(get_my_scope());
2296 u
.val_vs
->set_fullname(get_fullname());
2299 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2300 v
=dynamic_cast<Value
*>(node
);
2303 u
.val_vs
=new Values();
2306 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2308 u
.val_vs
->set_my_scope(get_my_scope());
2309 u
.val_vs
->set_fullname(get_fullname());
2312 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2313 v
=dynamic_cast<Value
*>(node
);
2316 u
.val_nvs
=new NamedValues();
2319 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2321 u
.val_nvs
->set_my_scope(get_my_scope());
2322 u
.val_nvs
->set_fullname(get_fullname());
2325 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2326 v
=dynamic_cast<Value
*>(node
);
2329 u
.val_nvs
=new NamedValues();
2332 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2334 u
.val_nvs
->set_my_scope(get_my_scope());
2335 u
.val_nvs
->set_fullname(get_fullname());
2338 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2339 v
=dynamic_cast<Value
*>(node
);
2342 u
.oid_comps
=new vector
<OID_comp
>();
2345 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2347 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2348 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2351 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2352 v
=dynamic_cast<Value
*>(node
);
2355 u
.oid_comps
=new vector
<OID_comp
>();
2358 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2360 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2361 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2364 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2365 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2368 u
.char_syms
=new CharSyms();
2370 u
.char_syms
->set_my_scope(get_my_scope());
2371 u
.char_syms
->set_fullname(get_fullname());
2374 FATAL_ERROR("Value::set_valuetype()");
2380 if (p_valuetype
== V_USTR
) {
2381 Value
*v_last
= get_value_refd_last();
2382 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2383 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2386 u
.ustr
.convert_str
= true; // will be converted back to string
2387 } else FATAL_ERROR("Value::set_valuetype()");
2390 switch(p_valuetype
) {
2392 const string
& str
= u
.char_syms
->get_string();
2394 set_val_str(new string(str
));
2397 const ustring
& ustr
= u
.char_syms
->get_ustring();
2399 set_val_ustr(new ustring(ustr
));
2400 u
.ustr
.convert_str
= false;
2402 case V_ISO2022STR
: {
2403 const string
& str
= u
.char_syms
->get_iso2022string();
2405 set_val_str(new string(str
));
2408 FATAL_ERROR("Value::set_valuetype()");
2413 if (p_valuetype
== V_REAL
)
2414 val_Real
= u
.val_Int
->to_real();
2415 else FATAL_ERROR("Value::set_valuetype()");
2417 u
.val_Real
= val_Real
;
2420 clean_up_string_elements(u
.str
.str_elements
);
2421 string
*old_str
= u
.str
.val_str
;
2422 switch(p_valuetype
) {
2424 set_val_str(hex2bit(*old_str
));
2427 set_val_str(asn_hex2oct(*old_str
));
2430 FATAL_ERROR("Value::set_valuetype()");
2435 clean_up_string_elements(u
.str
.str_elements
);
2436 if (p_valuetype
== V_OSTR
) {
2437 string
*old_str
= u
.str
.val_str
;
2438 set_val_str(asn_bit2oct(*old_str
));
2440 } else FATAL_ERROR("Value::set_valuetype()");
2443 clean_up_string_elements(u
.str
.str_elements
);
2444 switch(p_valuetype
) {
2446 string
*old_str
= u
.str
.val_str
;
2447 set_val_ustr(new ustring(*old_str
));
2448 u
.ustr
.convert_str
= true; // will be converted back to string
2455 FATAL_ERROR("Value::set_valuetype()");
2456 } // switch p_valuetype
2459 clean_up_string_elements(u
.ustr
.ustr_elements
);
2460 switch(p_valuetype
) {
2462 ustring
*old_str
= u
.ustr
.val_ustr
;
2463 size_t nof_chars
= old_str
->size();
2464 bool warning_flag
= false;
2465 for (size_t i
= 0; i
< nof_chars
; i
++) {
2466 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2467 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2468 error("This string value cannot contain multiple-byte characters, "
2469 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2470 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2472 p_valuetype
= V_ERROR
;
2474 } else if (uchar
.cell
> 127 && !warning_flag
) {
2475 warning("This string value may not contain characters with code "
2476 "higher than 127, but it has character with code %u (0x%02X) "
2477 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2478 warning_flag
= true;
2481 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2485 error("ISO-10646 string value cannot be converted to "
2487 delete u
.ustr
.val_ustr
;
2488 p_valuetype
= V_ERROR
;
2491 FATAL_ERROR("Value::set_valuetype()");
2492 } // switch p_valuetype
2495 switch (p_valuetype
) {
2497 NamedValues
*nvs
= u
.val_nvs
;
2498 if (nvs
->get_nof_nvs() < 1) {
2499 error("Union value must have one active field");
2501 valuetype
= V_ERROR
;
2503 } else if (nvs
->get_nof_nvs() > 1) {
2504 error("Only one field was expected in union value instead of %lu",
2505 (unsigned long) nvs
->get_nof_nvs());
2507 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2508 u
.choice
.alt_name
= nv
->get_name().clone();
2509 u
.choice
.alt_value
= nv
->steal_value();
2516 NamedValues
*nvs
= u
.val_nvs
;
2520 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2521 if (nvs
->has_nv_withName(id_mant
)) {
2522 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2523 ->get_value_refd_last();
2524 if (v_tmp
->get_valuetype() == V_INT
) {
2525 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2526 if (*i_mant_int
> INT_MAX
) {
2527 error("Mantissa `%s' should be less than `%d'",
2528 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2531 i_mant
= i_mant_int
->get_val();
2539 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2540 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2541 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2542 Value
*v_tmp
= v
->get_value_refd_last();
2543 if (v_tmp
->get_valuetype() == V_INT
) {
2544 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2545 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2546 v
->error("Base of the REAL must be 2 or 10");
2549 i_base
= i_base_int
->get_val();
2557 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2558 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2559 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2560 ->get_value_refd_last();
2561 if (v_tmp
->get_valuetype() == V_INT
) {
2562 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2563 if (*i_exp_int
> INT_MAX
) {
2564 error("Exponent `%s' should be less than `%d'",
2565 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2568 i_exp
= i_exp_int
->get_val();
2577 valuetype
= V_ERROR
;
2580 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2581 static_cast<double>(i_exp
));
2587 FATAL_ERROR("Value::set_valuetype()");
2591 switch (p_valuetype
) {
2593 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2594 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2595 Type
*t
= my_governor
->get_type_refd_last();
2596 switch (t
->get_typetype()) {
2601 FATAL_ERROR("Value::set_valuetype()");
2603 Values
*vals
= u
.val_vs
;
2604 size_t nof_vals
= vals
->get_nof_vs();
2605 size_t nof_comps
= t
->get_nof_comps();
2606 if (nof_vals
> nof_comps
) {
2607 error("Too many elements in value list notation for type `%s': "
2608 "%lu was expected instead of %lu",
2609 t
->get_typename().c_str(),
2610 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2614 if (nof_vals
<= nof_comps
) {
2615 upper_limit
= nof_vals
;
2618 upper_limit
= nof_comps
;
2621 u
.val_nvs
= new NamedValues
;
2622 for (size_t i
= 0; i
< upper_limit
; i
++) {
2623 Value
*v
= vals
->steal_v_byIndex(i
);
2624 if (v
->valuetype
!= V_NOTUSED
) {
2628 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2629 nv
->set_location(*v
);
2630 u
.val_nvs
->add_nv(nv
);
2632 u
.val_nvs
->set_my_scope(get_my_scope());
2633 u
.val_nvs
->set_fullname(get_fullname());
2635 if (allnotused
&& nof_vals
> 0)
2636 warning("All elements of value list notation for type `%s' are not "
2637 "used symbols (`-')", t
->get_typename().c_str());
2640 // { } -> empty set value
2641 if (u
.val_vs
->get_nof_vs() != 0)
2642 FATAL_ERROR("Value::set_valuetype()");
2644 u
.val_nvs
= new NamedValues
;
2648 // SEQOF -> SETOF or ARRAY: trivial
2651 FATAL_ERROR("Value::set_valuetype()");
2656 if (p_valuetype
== V_NOTUSED
) {
2660 FATAL_ERROR("Value::set_valuetype()");
2664 switch (p_valuetype
) {
2665 case V_DEFAULT_NULL
:
2670 FATAL_ERROR("Value::set_valuetype()");
2674 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2675 FATAL_ERROR("Value::set_valuetype()");
2679 FATAL_ERROR("Value::set_valuetype()");
2681 valuetype
=p_valuetype
;
2684 void Value::set_valuetype_COMP_NULL()
2686 if(valuetype
== V_ERROR
) return;
2687 if(valuetype
==V_TTCN3_NULL
) {
2689 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2690 // Nothing to check.
2691 u
.expr
.state
=EXPR_CHECKED
;
2693 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2696 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2698 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2700 u
.val_Int
= new int_val_t(p_val_int
);
2702 } else FATAL_ERROR("Value::set_valuetype()");
2705 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2707 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2711 } else FATAL_ERROR("Value::set_valuetype()");
2714 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2716 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2720 } else FATAL_ERROR("Value::set_valuetype()");
2723 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2725 switch (p_valuetype
) {
2729 if (valuetype
== V_REFER
&& p_ass
) break;
2732 FATAL_ERROR("Value::set_valuetype()");
2736 valuetype
= p_valuetype
;
2739 bool Value::is_undef_lowerid()
2741 switch (valuetype
) {
2742 case V_UNDEF_LOWERID
:
2745 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2746 !u
.expr
.ti1
->get_DerivedRef()) {
2747 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2755 const Identifier
& Value::get_undef_lowerid()
2757 switch (valuetype
) {
2758 case V_UNDEF_LOWERID
:
2761 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2762 FATAL_ERROR("Value::get_undef_lowerid()");
2763 return u
.expr
.ti1
->get_Template()->get_specific_value()
2764 ->get_undef_lowerid();
2766 FATAL_ERROR("Value::get_undef_lowerid()");
2768 const Identifier
*dummy
= 0;
2772 void Value::set_lowerid_to_ref()
2774 switch (valuetype
) {
2775 case V_UNDEF_LOWERID
:
2776 set_valuetype(V_REFD
);
2779 // if the governor of the expression is not known (in log(), etc...)
2780 // then the governor is taken from the reference (using
2781 // v1/ti1->get_expr_governor()), but that runs before the
2782 // params were checked, this smells like a workaround :)
2783 switch (u
.expr
.v_optype
) {
2786 u
.expr
.v1
->set_lowerid_to_ref();
2789 u
.expr
.v1
->set_lowerid_to_ref();
2790 u
.expr
.v2
->set_lowerid_to_ref();
2792 case OPTYPE_VALUEOF
:
2793 case OPTYPE_ISVALUE
:
2794 case OPTYPE_ISBOUND
:
2795 case OPTYPE_ISPRESENT
:
2798 case OPTYPE_REPLACE
:
2799 case OPTYPE_TTCN2STRING
:
2800 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2801 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2802 "In the operand of operation `%s'",
2804 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2806 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2807 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2808 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2809 "In the operand of operation `%s'",
2811 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2814 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2815 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2816 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2817 "In the operand of operation `%s'",
2819 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2832 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2834 switch (valuetype
) {
2842 case V_UNDEF_LOWERID
:
2849 return Type::T_UNDEF
;
2853 FATAL_ERROR("Value::get_expr_returntype()");
2855 return Type::T_ERROR
;
2858 Type
*t
= get_expr_governor(exp_val
);
2859 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2860 else return Type::T_ERROR
; }
2862 return Type::T_FUNCTION
;
2864 return Type::T_ALTSTEP
;
2866 return Type::T_TESTCASE
;
2868 switch(u
.expr
.v_optype
) {
2869 case OPTYPE_COMP_NULL
:
2870 case OPTYPE_COMP_MTC
:
2871 case OPTYPE_COMP_SYSTEM
:
2872 case OPTYPE_COMP_SELF
:
2873 case OPTYPE_COMP_CREATE
:
2874 return Type::T_COMPONENT
;
2875 case OPTYPE_UNDEF_RUNNING
:
2876 case OPTYPE_COMP_RUNNING
:
2877 case OPTYPE_COMP_RUNNING_ANY
:
2878 case OPTYPE_COMP_RUNNING_ALL
:
2879 case OPTYPE_COMP_ALIVE
:
2880 case OPTYPE_COMP_ALIVE_ANY
:
2881 case OPTYPE_COMP_ALIVE_ALL
:
2882 case OPTYPE_TMR_RUNNING
:
2883 case OPTYPE_TMR_RUNNING_ANY
:
2895 case OPTYPE_ISPRESENT
:
2896 case OPTYPE_ISCHOSEN
:
2897 case OPTYPE_ISCHOSEN_V
:
2898 case OPTYPE_ISCHOSEN_T
:
2899 case OPTYPE_ISVALUE
:
2900 case OPTYPE_ISBOUND
:
2901 case OPTYPE_PROF_RUNNING
:
2902 return Type::T_BOOL
;
2903 case OPTYPE_GETVERDICT
:
2904 return Type::T_VERDICT
;
2905 case OPTYPE_VALUEOF
: {
2906 Error_Context
cntxt(this, "In the operand of operation `%s'",
2908 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2909 case OPTYPE_TMR_READ
:
2910 case OPTYPE_INT2FLOAT
:
2911 case OPTYPE_STR2FLOAT
:
2913 case OPTYPE_RNDWITHVAL
:
2914 return Type::T_REAL
;
2915 case OPTYPE_ACTIVATE
:
2916 return Type::T_DEFAULT
;
2917 case OPTYPE_ACTIVATE_REFD
:
2918 return Type::T_DEFAULT
;
2919 case OPTYPE_EXECUTE
:
2920 case OPTYPE_EXECUTE_REFD
:
2921 return Type::T_VERDICT
;
2922 case OPTYPE_UNARYPLUS
: // v1
2923 case OPTYPE_UNARYMINUS
: {
2924 Type::typetype_t tmp_tt
;
2926 Error_Context
cntxt(this, "In the operand of operation `%s'",
2928 u
.expr
.v1
->set_lowerid_to_ref();
2929 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2936 get_value_refd_last(); // to report the error
2937 return Type::T_ERROR
;
2940 case OPTYPE_ADD
: // v1 v2
2941 case OPTYPE_SUBTRACT
:
2942 case OPTYPE_MULTIPLY
:
2943 case OPTYPE_DIVIDE
: {
2944 Type::typetype_t tmp_tt
;
2946 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2948 u
.expr
.v1
->set_lowerid_to_ref();
2949 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2956 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2957 Type::typetype_t tmp_tt2
;
2959 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2961 u
.expr
.v2
->set_lowerid_to_ref();
2962 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2964 Type::typetype_t ret_val
=Type::T_ERROR
;
2965 bool maybeconcat
=false;
2970 if(tmp_tt2
==tmp_tt
) {
2977 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2979 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2980 ret_val
=Type::T_USTR
;
2981 else ret_val
=Type::T_CSTR
;
2988 error("Did you mean the concat operation (`&') instead of"
2989 " addition operator (`+')?");
2990 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2994 get_value_refd_last(); // to report the error
2995 return Type::T_ERROR
;
2998 case OPTYPE_NOT4B
: // v1
2999 case OPTYPE_AND4B
: // v1 v2
3004 Type::typetype_t tmp_tt
;
3006 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
3007 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
3009 u
.expr
.v1
->set_lowerid_to_ref();
3010 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3018 get_value_refd_last(); // to report the error
3019 return Type::T_ERROR
;
3022 case OPTYPE_ROTL
: // v1 v2
3024 Type::typetype_t tmp_tt
;
3026 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
3027 u
.expr
.v_optype
==OPTYPE_ROTL
3028 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
3030 u
.expr
.v1
->set_lowerid_to_ref();
3031 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3044 get_value_refd_last(); // to report the error
3045 return Type::T_ERROR
;
3049 case OPTYPE_REPLACE
: {
3050 Type::typetype_t tmp_tt
;
3052 Error_Context
cntxt(this, "In the operand of operation `%s'",
3054 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3055 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3067 get_value_refd_last(); // to report the error
3068 return Type::T_ERROR
;
3071 case OPTYPE_REGEXP
: {
3072 Type::typetype_t tmp_tt
;
3074 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3076 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3077 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3084 get_value_refd_last(); // to report the error
3085 return Type::T_ERROR
;
3088 case OPTYPE_CONCAT
: { // v1 v2
3089 Type::typetype_t tmp_tt
;
3091 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3093 u
.expr
.v1
->set_lowerid_to_ref();
3094 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3106 get_value_refd_last(); // to report the error
3107 return Type::T_ERROR
;
3112 case OPTYPE_CHAR2INT
:
3113 case OPTYPE_UNICHAR2INT
:
3114 case OPTYPE_BIT2INT
:
3115 case OPTYPE_HEX2INT
:
3116 case OPTYPE_OCT2INT
:
3117 case OPTYPE_STR2INT
:
3118 case OPTYPE_FLOAT2INT
:
3119 case OPTYPE_LENGTHOF
:
3122 case OPTYPE_ENUM2INT
:
3123 case OPTYPE_DECVALUE_UNICHAR
:
3125 case OPTYPE_BIT2STR
:
3126 case OPTYPE_FLOAT2STR
:
3127 case OPTYPE_HEX2STR
:
3128 case OPTYPE_INT2CHAR
:
3129 case OPTYPE_INT2STR
:
3130 case OPTYPE_OCT2CHAR
:
3131 case OPTYPE_OCT2STR
:
3132 case OPTYPE_UNICHAR2CHAR
:
3133 case OPTYPE_LOG2STR
:
3134 case OPTYPE_TESTCASENAME
:
3135 case OPTYPE_TTCN2STRING
:
3136 case OPTYPE_GET_STRINGENCODING
:
3137 case OPTYPE_ENCODE_BASE64
:
3138 return Type::T_CSTR
;
3139 case OPTYPE_INT2UNICHAR
:
3140 case OPTYPE_OCT2UNICHAR
:
3141 case OPTYPE_ENCVALUE_UNICHAR
:
3142 case OPTYPE_ANY2UNISTR
:
3143 return Type::T_USTR
;
3144 case OPTYPE_INT2BIT
:
3145 case OPTYPE_HEX2BIT
:
3146 case OPTYPE_OCT2BIT
:
3147 case OPTYPE_STR2BIT
:
3149 return Type::T_BSTR
;
3150 case OPTYPE_INT2HEX
:
3151 case OPTYPE_BIT2HEX
:
3152 case OPTYPE_OCT2HEX
:
3153 case OPTYPE_STR2HEX
:
3154 return Type::T_HSTR
;
3155 case OPTYPE_INT2OCT
:
3156 case OPTYPE_CHAR2OCT
:
3157 case OPTYPE_HEX2OCT
:
3158 case OPTYPE_BIT2OCT
:
3159 case OPTYPE_STR2OCT
:
3160 case OPTYPE_UNICHAR2OCT
:
3161 case OPTYPE_REMOVE_BOM
:
3162 case OPTYPE_DECODE_BASE64
:
3163 return Type::T_OSTR
;
3167 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3169 return Type::T_ERROR
;
3173 case MACRO_MODULEID
:
3174 case MACRO_FILENAME
:
3175 case MACRO_BFILENAME
:
3176 case MACRO_FILEPATH
:
3177 case MACRO_LINENUMBER
:
3178 case MACRO_DEFINITIONID
:
3180 case MACRO_TESTCASEID
:
3181 return Type::T_CSTR
;
3182 case MACRO_LINENUMBER_C
:
3185 return Type::T_ERROR
;
3188 return Type::T_NULL
;
3190 return Type::T_BOOL
;
3194 return Type::T_REAL
;
3196 return Type::T_ENUM_T
;
3198 return Type::T_BSTR
;
3200 return Type::T_HSTR
;
3202 return Type::T_OSTR
;
3204 return Type::T_CSTR
;
3206 return Type::T_USTR
;
3208 return Type::T_GENERALSTRING
;
3212 return Type::T_ROID
;
3214 return Type::T_VERDICT
;
3215 case V_DEFAULT_NULL
:
3216 return Type::T_DEFAULT
;
3218 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3220 return Type::T_ERROR
;
3224 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3226 if(my_governor
) return my_governor
;
3227 switch (valuetype
) {
3229 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3231 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3232 u
.invoke
.v
->error("A value of type function expected");
3235 t
= t
->get_type_refd_last();
3236 switch(t
->get_typetype()) {
3237 case Type::T_FUNCTION
: {
3238 Type
*t_return_type
= t
->get_function_return_type();
3239 if (!t_return_type
) {
3240 error("Reference to a %s was expected instead of invocation "
3241 "of behavior type `%s' with no return type",
3242 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3243 t
->get_fullname().c_str());
3246 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3247 error("Reference to a value was expected, but functions of type "
3248 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3249 t_return_type
->get_typename().c_str());
3252 return t_return_type
; }
3253 case Type::T_ALTSTEP
:
3256 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3257 t
->get_typename().c_str());
3262 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3264 if (!ass
) goto error
;
3265 switch (ass
->get_asstype()) {
3266 case Assignment::A_CONST
:
3267 case Assignment::A_EXT_CONST
:
3268 case Assignment::A_MODULEPAR
:
3269 case Assignment::A_MODULEPAR_TEMP
:
3270 case Assignment::A_TEMPLATE
:
3271 case Assignment::A_VAR
:
3272 case Assignment::A_VAR_TEMPLATE
:
3273 case Assignment::A_FUNCTION_RVAL
:
3274 case Assignment::A_FUNCTION_RTEMP
:
3275 case Assignment::A_EXT_FUNCTION_RVAL
:
3276 case Assignment::A_EXT_FUNCTION_RTEMP
:
3277 case Assignment::A_PAR_VAL_IN
:
3278 case Assignment::A_PAR_VAL_OUT
:
3279 case Assignment::A_PAR_VAL_INOUT
:
3280 case Assignment::A_PAR_TEMPL_IN
:
3281 case Assignment::A_PAR_TEMPL_OUT
:
3282 case Assignment::A_PAR_TEMPL_INOUT
:
3283 tmp_type
=ass
->get_Type();
3285 case Assignment::A_FUNCTION
:
3286 case Assignment::A_EXT_FUNCTION
:
3287 error("Reference to a %s was expected instead of a call of %s, which "
3288 "does not have return type",
3289 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3290 ass
->get_description().c_str());
3293 error("Reference to a %s was expected instead of %s",
3294 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3295 ass
->get_description().c_str());
3298 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3299 if(!tmp_type
) goto error
;
3302 switch (u
.expr
.v_optype
) {
3303 case OPTYPE_VALUEOF
:
3306 case OPTYPE_REPLACE
:{
3307 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3308 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3309 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3314 return u
.expr
.v1
->get_expr_governor(exp_val
);
3316 return get_expr_governor_v1v2(exp_val
);
3317 case OPTYPE_COMP_MTC
:
3318 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3320 case OPTYPE_COMP_SYSTEM
:
3321 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3323 case OPTYPE_COMP_SELF
:
3325 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3326 if (t_ros
) return t_ros
->get_component_type();
3329 case OPTYPE_COMP_CREATE
:
3330 return chk_expr_operand_comptyperef_create();
3336 return Type::get_pooltype(get_expr_returntype(exp_val
));
3339 set_valuetype(V_ERROR
);
3343 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3345 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3346 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3348 if (v2_gov
) { // both have governors
3349 // return the type that is compatible with both (if there is no type mismatch)
3350 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3353 } else return v1_gov
;
3354 } else { // v1 has no governor
3355 if (v2_gov
) return v2_gov
;
3356 else return NULL
; // neither has governor
3360 Type
*Value::get_expr_governor_last()
3362 Value
*v_last
= get_value_refd_last();
3363 if (v_last
->valuetype
== V_ERROR
) return 0;
3364 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3366 return t
->get_type_refd_last();
3369 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3371 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3372 return u
.invoke
.v
->get_expr_governor(exp_val
);
3375 const char* Value::get_opname() const
3377 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3378 switch(u
.expr
.v_optype
) {
3379 case OPTYPE_RND
: // -
3381 case OPTYPE_COMP_NULL
:
3382 return "(component) null";
3383 case OPTYPE_COMP_MTC
:
3385 case OPTYPE_COMP_SYSTEM
:
3387 case OPTYPE_COMP_SELF
:
3389 case OPTYPE_COMP_RUNNING_ANY
:
3390 return "any component.running";
3391 case OPTYPE_COMP_RUNNING_ALL
:
3392 return "all component.running";
3393 case OPTYPE_COMP_ALIVE_ANY
:
3394 return "any component.alive";
3395 case OPTYPE_COMP_ALIVE_ALL
:
3396 return "all component.alive";
3397 case OPTYPE_TMR_RUNNING_ANY
:
3398 return "any timer.running";
3399 case OPTYPE_GETVERDICT
:
3400 return "getverdict()";
3401 case OPTYPE_TESTCASENAME
:
3402 return "testcasename()";
3403 case OPTYPE_UNARYPLUS
: // v1
3405 case OPTYPE_UNARYMINUS
:
3411 case OPTYPE_BIT2HEX
:
3413 case OPTYPE_BIT2INT
:
3415 case OPTYPE_BIT2OCT
:
3417 case OPTYPE_BIT2STR
:
3419 case OPTYPE_CHAR2INT
:
3420 return "char2int()";
3421 case OPTYPE_CHAR2OCT
:
3422 return "char2oct()";
3423 case OPTYPE_FLOAT2INT
:
3424 return "float2int()";
3425 case OPTYPE_FLOAT2STR
:
3426 return "float2str()";
3427 case OPTYPE_HEX2BIT
:
3429 case OPTYPE_HEX2INT
:
3431 case OPTYPE_HEX2OCT
:
3433 case OPTYPE_HEX2STR
:
3435 case OPTYPE_INT2CHAR
:
3436 return "int2char()";
3437 case OPTYPE_INT2FLOAT
:
3438 return "int2float()";
3439 case OPTYPE_INT2STR
:
3441 case OPTYPE_INT2UNICHAR
:
3442 return "int2unichar()";
3443 case OPTYPE_OCT2BIT
:
3445 case OPTYPE_OCT2CHAR
:
3446 return "oct2char()";
3447 case OPTYPE_OCT2HEX
:
3449 case OPTYPE_OCT2INT
:
3451 case OPTYPE_OCT2STR
:
3453 case OPTYPE_STR2BIT
:
3455 case OPTYPE_STR2FLOAT
:
3456 return "str2float()";
3457 case OPTYPE_STR2HEX
:
3459 case OPTYPE_STR2INT
:
3461 case OPTYPE_STR2OCT
:
3463 case OPTYPE_UNICHAR2INT
:
3464 return "unichar2int()";
3465 case OPTYPE_UNICHAR2CHAR
:
3466 return "unichar2char()";
3467 case OPTYPE_UNICHAR2OCT
:
3468 return "unichar2oct()";
3469 case OPTYPE_ENUM2INT
:
3470 return "enum2int()";
3471 case OPTYPE_LENGTHOF
:
3472 return "lengthof()";
3475 case OPTYPE_RNDWITHVAL
:
3476 return "rnd (seed)";
3478 return "encvalue()";
3480 return "decvalue()";
3481 case OPTYPE_GET_STRINGENCODING
:
3482 return "get_stringencoding()";
3483 case OPTYPE_REMOVE_BOM
:
3484 return "remove_bom()";
3485 case OPTYPE_ENCODE_BASE64
:
3486 return "encode_base64()";
3487 case OPTYPE_DECODE_BASE64
:
3488 return "decode_base64()";
3489 case OPTYPE_ADD
: // v1 v2
3491 case OPTYPE_SUBTRACT
:
3493 case OPTYPE_MULTIPLY
:
3535 case OPTYPE_INT2BIT
:
3537 case OPTYPE_INT2HEX
:
3539 case OPTYPE_INT2OCT
:
3541 case OPTYPE_OCT2UNICHAR
:
3542 return "oct2unichar()";
3543 case OPTYPE_ENCVALUE_UNICHAR
:
3544 return "encvalue_unichar()";
3545 case OPTYPE_DECVALUE_UNICHAR
:
3546 return "decvalue_unichar()";
3553 case OPTYPE_REPLACE
:
3555 case OPTYPE_VALUEOF
: // t1
3557 case OPTYPE_UNDEF_RUNNING
:
3558 return "<timer or component> running";
3559 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3561 case OPTYPE_COMP_RUNNING
: // v1
3562 return "component running";
3563 case OPTYPE_COMP_ALIVE
: // v1
3565 case OPTYPE_TMR_READ
:
3566 return "timer read";
3567 case OPTYPE_TMR_RUNNING
:
3568 return "timer running";
3569 case OPTYPE_ACTIVATE
:
3570 return "activate()";
3571 case OPTYPE_ACTIVATE_REFD
:
3572 return "activate()";
3573 case OPTYPE_EXECUTE
: // r1 [v2]
3574 case OPTYPE_EXECUTE_REFD
:
3576 case OPTYPE_MATCH
: // v1 t2
3578 case OPTYPE_ISPRESENT
:
3579 return "ispresent()";
3580 case OPTYPE_ISCHOSEN
:
3581 case OPTYPE_ISCHOSEN_V
:
3582 case OPTYPE_ISCHOSEN_T
:
3583 return "ischosen()";
3584 case OPTYPE_ISVALUE
:
3586 case OPTYPE_ISBOUND
:
3588 case OPTYPE_LOG2STR
:
3590 case OPTYPE_ANY2UNISTR
:
3591 return "any2unistr()";
3592 case OPTYPE_TTCN2STRING
:
3593 return "ttcn2string()";
3594 case OPTYPE_PROF_RUNNING
:
3595 return "@profiler.running";
3597 FATAL_ERROR("Value::get_opname()");
3601 void Value::chk_expr_ref_ischosen()
3603 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3604 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3605 Assignment
*ass
=tmpref
->get_refd_assignment();
3607 set_valuetype(V_ERROR
);
3610 // Now we know whether the argument of ischosen() is a value or template.
3611 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3612 // or template (OPTYPE_ISCHOSEN_T).
3613 switch (ass
->get_asstype()) {
3614 case Assignment::A_CONST
:
3615 case Assignment::A_EXT_CONST
:
3616 case Assignment::A_MODULEPAR
:
3617 case Assignment::A_VAR
:
3618 case Assignment::A_PAR_VAL_IN
:
3619 case Assignment::A_PAR_VAL_OUT
:
3620 case Assignment::A_PAR_VAL_INOUT
:
3621 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3622 u
.expr
.v1
->set_location(*tmpref
);
3623 u
.expr
.v1
->set_my_scope(get_my_scope());
3624 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3625 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3627 case Assignment::A_MODULEPAR_TEMP
:
3628 case Assignment::A_TEMPLATE
:
3629 case Assignment::A_VAR_TEMPLATE
:
3630 case Assignment::A_PAR_TEMPL_IN
:
3631 case Assignment::A_PAR_TEMPL_OUT
:
3632 case Assignment::A_PAR_TEMPL_INOUT
:
3633 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3634 u
.expr
.t1
->set_location(*tmpref
);
3635 u
.expr
.t1
->set_my_scope(get_my_scope());
3636 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3637 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3640 tmpref
->error("Reference to a value or template was expected instead of "
3641 "%s", ass
->get_description().c_str());
3642 set_valuetype(V_ERROR
);
3647 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3648 Type::expected_value_t exp_val
)
3650 v
->set_lowerid_to_ref(); // can only be reference to enum
3651 Type
*t
= v
->get_expr_governor(exp_val
);
3652 if (v
->valuetype
==V_ERROR
) return;
3654 v
->error("Please use reference to an enumerated value as the operand of "
3655 "operation `%s'", get_opname());
3656 set_valuetype(V_ERROR
);
3659 t
= t
->get_type_refd_last();
3660 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3661 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3662 set_valuetype(V_ERROR
);
3664 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3665 v
->error("The operand of operation `%s' cannot be omit", opname
);
3666 set_valuetype(V_ERROR
);
3670 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3673 const Location
*loc
)
3675 if(tt
==Type::T_BOOL
) return;
3676 if(tt
!=Type::T_ERROR
)
3677 loc
->error("%s operand of operation `%s' should be boolean value",
3679 set_valuetype(V_ERROR
);
3682 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3685 const Location
*loc
)
3687 if(tt
==Type::T_INT
) return;
3688 if(tt
!=Type::T_ERROR
)
3689 loc
->error("%s operand of operation `%s' should be integer value",
3691 set_valuetype(V_ERROR
);
3694 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3697 const Location
*loc
)
3699 if(tt
==Type::T_REAL
) return;
3700 else if(tt
==Type::T_INT
)
3701 loc
->error("%s operand of operation `%s' should be float value."
3702 " Perhaps you missed an int2float() conversion function"
3703 " or `.0' at the end of the number",
3705 else if(tt
!=Type::T_ERROR
)
3706 loc
->error("%s operand of operation `%s' should be float value",
3708 set_valuetype(V_ERROR
);
3711 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3714 const Location
*loc
)
3723 if(tt
!=Type::T_ERROR
)
3724 loc
->error("%s operand of operation `%s' should be integer"
3727 set_valuetype(V_ERROR
);
3730 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3733 const Location
*loc
)
3738 case Type::T_ENUM_T
:
3743 if(tt
!=Type::T_ERROR
)
3744 loc
->error("%s operand of operation `%s' should be integer, float"
3745 " or enumerated value", opnum
, opname
);
3746 set_valuetype(V_ERROR
);
3749 void Value::chk_expr_operandtype_list(Type
* t
,
3752 const Location
*loc
,
3755 if (valuetype
== V_ERROR
) return;
3756 if (t
->get_typetype() == Type::T_ERROR
) {
3757 set_valuetype(V_ERROR
);
3760 if (!t
->is_list_type(allow_array
)) {
3761 loc
->error("%s operand of operation `%s' should be a string, "
3762 "`record of'%s `set of'%s value", opnum
, opname
,
3763 allow_array
? "," : " or", allow_array
? " or array" : "");
3764 set_valuetype(V_ERROR
);
3767 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3768 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3771 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3772 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3773 if (info
.is_subtype_error()) {
3775 if (info
.needs_conversion()) set_needs_conversion();
3777 if (!info
.is_erroneous()) {
3778 error("%s operand of operation `%s' is of type `%s', but a value of "
3779 "type `%s' was expected here", opnum
, opname
,
3780 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3782 error("%s", info
.get_error_str_str().c_str());
3785 if (info
.needs_conversion())
3786 set_needs_conversion();
3790 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3793 const Location
*loc
)
3805 if(tt
!=Type::T_ERROR
)
3806 loc
->error("%s operand of operation `%s' should be string value",
3808 set_valuetype(V_ERROR
);
3811 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3814 const Location
*loc
)
3823 if(tt
!=Type::T_ERROR
)
3824 loc
->error("%s operand of operation `%s' should be (universal)"
3825 " charstring value",
3827 set_valuetype(V_ERROR
);
3830 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3833 const Location
*loc
)
3835 if(tt
==Type::T_CSTR
) return;
3836 if(tt
!=Type::T_ERROR
)
3837 loc
->error("%s operand of operation `%s' should be charstring value",
3839 set_valuetype(V_ERROR
);
3842 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3845 const Location
*loc
)
3855 if(tt
!=Type::T_ERROR
)
3856 loc
->error("%s operand of operation `%s' should be binary string value",
3858 set_valuetype(V_ERROR
);
3861 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3864 const Location
*loc
)
3866 if(tt
==Type::T_BSTR
) return;
3867 if(tt
!=Type::T_ERROR
)
3868 loc
->error("%s operand of operation `%s' should be bitstring value",
3870 set_valuetype(V_ERROR
);
3873 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3876 const Location
*loc
)
3878 if(tt
==Type::T_HSTR
) return;
3879 if(tt
!=Type::T_ERROR
)
3880 loc
->error("%s operand of operation `%s' should be hexstring value",
3882 set_valuetype(V_ERROR
);
3885 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3888 const Location
*loc
)
3890 if(tt
==Type::T_OSTR
) return;
3891 if(tt
!=Type::T_ERROR
)
3892 loc
->error("%s operand of operation `%s' should be octetstring value",
3894 set_valuetype(V_ERROR
);
3897 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3898 Type::typetype_t tt2
,
3901 if(valuetype
==V_ERROR
) return;
3902 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3903 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3904 set_valuetype(V_ERROR
);
3907 if(tt1
==tt2
) return;
3908 error("The operands of operation `%s' should be of same type", opname
);
3909 set_valuetype(V_ERROR
);
3912 /* For predefined functions. */
3913 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3914 Type::typetype_t tt2
,
3919 if(valuetype
==V_ERROR
) return;
3920 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3921 set_valuetype(V_ERROR
);
3924 if(tt1
==tt2
) return;
3925 error("The %s and %s operands of operation `%s' should be of same type",
3926 opnum1
, opnum2
, opname
);
3927 set_valuetype(V_ERROR
);
3930 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3931 Value
*v1
, Value
*v2
,
3936 if (valuetype
== V_ERROR
) return;
3937 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3938 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3939 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3941 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3942 set_valuetype(V_ERROR
);
3945 if (tt1
== Type::T_UNDEF
) {
3946 if (tt2
== Type::T_UNDEF
) {
3947 if (v1
->is_undef_lowerid()) {
3948 if (v2
->is_undef_lowerid()) {
3949 Scope
*scope
= get_my_scope();
3950 Module
*my_mod
= scope
->get_scope_mod();
3951 const Identifier
& id1
= v1
->get_undef_lowerid();
3952 if (scope
->has_ass_withId(id1
)
3953 || my_mod
->has_imported_ass_withId(id1
)) {
3954 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3955 * should examine this situation better, but now I suppose
3956 * the first is ref, not enum. */
3957 v1
->set_lowerid_to_ref();
3960 const Identifier
& id2
= v2
->get_undef_lowerid();
3961 if (scope
->has_ass_withId(id2
)
3962 || my_mod
->has_imported_ass_withId(id2
)) {
3963 v2
->set_lowerid_to_ref();
3967 /* This is perhaps enum-enum, but it has no real
3968 * significance, so this should be an error. */
3970 v1
->set_lowerid_to_ref();
3973 } else if (v2
->is_undef_lowerid()) {
3974 v2
->set_lowerid_to_ref();
3977 error("Cannot determine the type of the operands in operation `%s'",
3979 set_valuetype(V_ERROR
);
3981 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3982 v1
->set_lowerid_to_ref();
3985 /* v1 is something undefined, but not lowerid; v2 has
3986 * returntype (perhaps also governor) */
3988 } else if (tt2
== Type::T_UNDEF
) {
3989 /* but tt1 is not undef */
3990 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3991 v2
->set_lowerid_to_ref();
3994 /* v2 is something undefined, but not lowerid; v1 has
3995 * returntype (perhaps also governor) */
3999 /* Now undef_lower_id's are converted to references, or the other
4000 * value has governor; let's see the governors, if they exist. */
4001 Type
*t1
= v1
->get_expr_governor(exp_val
);
4002 Type
*t2
= v2
->get_expr_governor(exp_val
);
4005 // Both value has governor. Are they compatible? According to 7.1.2
4006 // and C.34 it's required to have the same root types for
4007 // OPTYPE_{CONCAT,REPLACE}.
4008 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
4009 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4010 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
4011 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4012 TypeChain l_chain1
, l_chain2
;
4013 TypeChain r_chain1
, r_chain2
;
4014 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
4015 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
4016 if (!compat_t1
&& !compat_t2
) {
4017 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
4018 // the subtypes don't need to be compatible here
4019 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
4020 error("The operands of operation `%s' should be of compatible "
4021 "types", get_opname());
4022 set_valuetype(V_ERROR
);
4024 if (info1
.needs_conversion() || info2
.needs_conversion()) {
4025 set_needs_conversion(); // Avoid folding.
4030 if (info1
.is_erroneous())
4031 v1
->error("%s", info1
.get_error_str_str().c_str());
4032 else if (info2
.is_erroneous())
4033 v2
->error("%s", info2
.get_error_str_str().c_str());
4034 set_valuetype(V_ERROR
);
4037 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
4038 set_needs_conversion(); // Avoid folding.
4043 v2
->set_my_governor(t1
);
4044 t1
->chk_this_value_ref(v2
);
4045 if (v2
->valuetype
== V_OMIT
) {
4046 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4048 v1
->chk_expr_omit_comparison(exp_val
);
4050 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4052 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4053 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4058 v1
->set_my_governor(t2
);
4059 t2
->chk_this_value_ref(v1
);
4060 if (v1
->valuetype
== V_OMIT
) {
4061 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4063 v2
->chk_expr_omit_comparison(exp_val
);
4065 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4067 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4068 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4072 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4073 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
4074 // Here, it cannot be that both are T_UNDEF.
4075 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4076 error("Please use reference as %s operand of operator `%s'",
4077 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
4078 set_valuetype(V_ERROR
);
4081 // Deny type compatibility if no governors found. The typetype_t must
4082 // be the same. TODO: How can this happen?
4083 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
4084 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
4085 error("The operands of operation `%s' should be of compatible types",
4087 set_valuetype(V_ERROR
);
4092 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
4093 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
4095 if(valuetype
==V_ERROR
) return;
4096 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4097 Assignment
*t_ass
= ref
->get_refd_assignment();
4098 if(!t_ass
) goto error
;
4099 switch(t_ass
->get_asstype()) {
4100 case Assignment::A_TIMER
:
4101 case Assignment::A_PAR_TIMER
:
4102 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
4103 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
4104 chk_expr_dynamic_part(exp_val
, true);
4106 case Assignment::A_CONST
:
4107 case Assignment::A_EXT_CONST
:
4108 case Assignment::A_MODULEPAR
:
4109 case Assignment::A_VAR
:
4110 case Assignment::A_FUNCTION_RVAL
:
4111 case Assignment::A_EXT_FUNCTION_RVAL
:
4112 case Assignment::A_PAR_VAL_IN
:
4113 case Assignment::A_PAR_VAL_OUT
:
4114 case Assignment::A_PAR_VAL_INOUT
: {
4115 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
4116 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
4117 val
->set_my_scope(my_scope
);
4118 val
->set_fullname(u
.expr
.r1
->get_fullname());
4119 val
->set_location(*u
.expr
.r1
);
4121 chk_expr_operand_compref(val
, opnum
, get_opname());
4122 chk_expr_dynamic_part(exp_val
, false);
4125 ref
->error("%s operand of operation `%s' should be timer or"
4126 " component reference instead of %s",
4127 opnum
, opname
, t_ass
->get_description().c_str());
4132 set_valuetype(V_ERROR
);
4135 Type
*Value::chk_expr_operand_comptyperef_create()
4137 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4138 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4139 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4140 if (!t_ass
) goto error
;
4141 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4142 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4143 Type::EXPECTED_DYNAMIC_VALUE
);
4144 if (!t_type
) goto error
;
4145 t_type
= t_type
->get_type_refd_last();
4146 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4148 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4149 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4150 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4151 u
.expr
.r1
->error("Incompatible component types: operation "
4152 "`create' should refer to `%s' instead of "
4154 my_governor_last
->get_typename().c_str(),
4155 t_type
->get_typename().c_str());
4161 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4162 "expected in operation `create' instead of `%s'",
4163 t_type
->get_typename().c_str());
4166 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4167 "instead of %s", t_ass
->get_description().c_str());
4170 set_valuetype(V_ERROR
);
4174 void Value::chk_expr_comptype_compat()
4176 if (valuetype
!= V_EXPR
)
4177 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4178 if (!my_governor
|| !my_scope
) return;
4179 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4180 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4182 switch (u
.expr
.v_optype
) {
4183 case OPTYPE_COMP_MTC
:
4184 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4186 case OPTYPE_COMP_SYSTEM
:
4187 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4189 case OPTYPE_COMP_SELF
: {
4190 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4191 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4194 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4199 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4200 error("Incompatible component types: a component reference of "
4201 "type `%s' was expected, but `%s' has type `%s'",
4202 my_governor_last
->get_typename().c_str(), get_opname(),
4203 t_comptype
->get_typename().c_str());
4204 set_valuetype(V_ERROR
);
4208 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4211 if(valuetype
== V_ERROR
) return;
4212 switch(val
->get_valuetype()) {
4214 Error_Context
cntxt(this, "In `%s' operation", opname
);
4215 Value
*v_last
= val
->get_value_refd_last();
4216 if(!v_last
) goto error
;
4217 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4219 t
= t
->get_type_refd_last();
4220 if(t
->get_typetype() != Type::T_COMPONENT
) {
4221 v_last
->error("%s operand of operation `%s': Type mismatch:"
4222 " component reference was expected instead of `%s'",
4223 opnum
, opname
, t
->get_typename().c_str());
4228 Reference
*ref
= val
->get_reference();
4229 Assignment
*t_ass
= ref
->get_refd_assignment();
4231 if (!t_ass
) goto error
;
4232 switch(t_ass
->get_asstype()) {
4233 case Assignment::A_CONST
:
4234 t_val
= t_ass
->get_Value();
4236 case Assignment::A_EXT_CONST
:
4237 case Assignment::A_MODULEPAR
:
4238 case Assignment::A_VAR
:
4239 case Assignment::A_FUNCTION_RVAL
:
4240 case Assignment::A_EXT_FUNCTION_RVAL
:
4241 case Assignment::A_PAR_VAL_IN
:
4242 case Assignment::A_PAR_VAL_OUT
:
4243 case Assignment::A_PAR_VAL_INOUT
: {
4244 Type
*t_type
=t_ass
->get_Type()
4245 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4246 if(!t_type
) goto error
;
4247 t_type
=t_type
->get_type_refd_last();
4248 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4249 ref
->error("%s operand of operation `%s': Type mismatch:"
4250 " component reference was expected instead of `%s'",
4251 opnum
, opname
, t_type
->get_typename().c_str());
4256 ref
->error("%s operand of operation `%s' should be"
4257 " component reference instead of %s",
4258 opnum
, opname
, t_ass
->get_description().c_str());
4262 ReferenceChain
refch(this, "While searching referenced value");
4263 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4265 t_val
= t_val
->get_value_refd_last();
4266 if (t_val
->valuetype
!= V_EXPR
) return;
4267 switch (t_val
->u
.expr
.v_optype
) {
4268 case OPTYPE_COMP_NULL
:
4269 ref
->error("%s operand of operation `%s' refers to `null' component "
4270 "reference", opnum
, opname
);
4272 case OPTYPE_COMP_MTC
:
4273 ref
->error("%s operand of operation `%s' refers to the component "
4274 "reference of the `mtc'", opnum
, opname
);
4276 case OPTYPE_COMP_SYSTEM
:
4277 ref
->error("%s operand of operation `%s' refers to the component "
4278 "reference of the `system'", opnum
, opname
);
4286 FATAL_ERROR("Value::chk_expr_operand_compref()");
4289 set_valuetype(V_ERROR
);
4292 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4296 if(valuetype
==V_ERROR
) return;
4297 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4298 Assignment
*t_ass
= ref
->get_refd_assignment();
4299 if(!t_ass
) goto error
;
4300 switch(t_ass
->get_asstype()) {
4301 case Assignment::A_TIMER
: {
4302 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4303 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4304 Type::EXPECTED_DYNAMIC_VALUE
);
4305 else if (ref
->get_subrefs()) {
4306 ref
->error("%s operand of operation `%s': "
4307 "Reference to single timer `%s' cannot have field or array "
4308 "sub-references", opnum
, opname
,
4309 t_ass
->get_id().get_dispname().c_str());
4313 case Assignment::A_PAR_TIMER
:
4314 if (ref
->get_subrefs()) {
4315 ref
->error("%s operand of operation `%s': "
4316 "Reference to %s cannot have field or array sub-references",
4317 opnum
, opname
, t_ass
->get_description().c_str());
4322 ref
->error("%s operand of operation `%s' should be timer"
4324 opnum
, opname
, t_ass
->get_description().c_str());
4329 set_valuetype(V_ERROR
);
4332 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4336 if(valuetype
==V_ERROR
) return;
4337 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4338 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4339 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4340 Error_Context
cntxt(this, "In `%s' operation", opname
);
4341 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4344 void Value::chk_expr_operand_activate_refd(Value
*val
,
4345 Ttcn::TemplateInstances
* t_list2
,
4346 Ttcn::ActualParList
*&parlist
,
4350 if(valuetype
==V_ERROR
) return;
4351 Error_Context
cntxt(this, "In `%s' operation", opname
);
4352 Type
*t
= val
->get_expr_governor_last();
4354 switch (t
->get_typetype()) {
4356 set_valuetype(V_ERROR
);
4358 case Type::T_ALTSTEP
: {
4359 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4360 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4364 set_valuetype(V_ERROR
);
4366 parlist
->set_fullname(get_fullname());
4367 parlist
->set_my_scope(get_my_scope());
4368 if (!fp_list
->chk_activate_argument(parlist
,
4369 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4373 error("Reference to an altstep was expected in the argument of "
4374 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4375 set_valuetype(V_ERROR
);
4378 } else set_valuetype(V_ERROR
);
4381 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4385 if(valuetype
==V_ERROR
) return;
4386 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4387 Error_Context
cntxt(this, "In `%s' operation", opname
);
4388 Assignment
*t_ass
= ref
->get_refd_assignment();
4389 bool error_flag
= false;
4391 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4392 ref
->error("Reference to a testcase was expected in the argument "
4393 "instead of %s", t_ass
->get_description().c_str());
4396 } else error_flag
= true;
4398 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4399 Value
*v_last
= val
->get_value_refd_last();
4400 switch (v_last
->valuetype
) {
4402 ttcn3float v_real
= v_last
->get_val_Real();
4404 val
->error("The testcase guard timer has negative value: `%s'",
4405 Real2string(v_real
).c_str());
4416 if (error_flag
) set_valuetype(V_ERROR
);
4419 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4420 Ttcn::TemplateInstances
* t_list2
,
4421 Ttcn::ActualParList
*&parlist
,
4426 if(valuetype
==V_ERROR
) return;
4427 Error_Context
cntxt(this, "In `%s' operation", opname
);
4428 Type
*t
= v1
->get_expr_governor_last();
4430 switch (t
->get_typetype()) {
4432 set_valuetype(V_ERROR
);
4434 case Type::T_TESTCASE
: {
4435 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4436 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4440 set_valuetype(V_ERROR
);
4442 parlist
->set_fullname(get_fullname());
4443 parlist
->set_my_scope(get_my_scope());
4447 v1
->error("Reference to a value of type testcase was expected in the "
4448 "argument of `derefers()' instead of `%s'",
4449 t
->get_typename().c_str());
4450 set_valuetype(V_ERROR
);
4453 } else set_valuetype(V_ERROR
);
4455 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4456 Value
*v_last
= v3
->get_value_refd_last();
4457 switch (v_last
->valuetype
) {
4459 ttcn3float v_real
= v_last
->get_val_Real();
4461 v3
->error("The testcase guard timer has negative value: `%s'",
4462 Real2string(v_real
).c_str());
4463 set_valuetype(V_ERROR
);
4467 set_valuetype(V_ERROR
);
4475 void Value::chk_invoke(Type::expected_value_t exp_val
)
4477 if(valuetype
== V_ERROR
) return;
4478 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4479 if(!u
.invoke
.t_list
) return; //already checked
4480 Error_Context
cntxt(this, "In `apply()' operation");
4481 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4483 set_valuetype(V_ERROR
);
4486 switch (t
->get_typetype()) {
4488 set_valuetype(V_ERROR
);
4490 case Type::T_FUNCTION
:
4493 u
.invoke
.v
->error("A value of type function was expected in the "
4494 "argument instead of `%s'", t
->get_typename().c_str());
4495 set_valuetype(V_ERROR
);
4498 my_scope
->chk_runs_on_clause(t
, *this, "call");
4499 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4500 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4501 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4502 delete u
.invoke
.t_list
;
4503 u
.invoke
.t_list
= 0;
4506 u
.invoke
.ap_list
= 0;
4508 parlist
->set_fullname(get_fullname());
4509 parlist
->set_my_scope(get_my_scope());
4510 u
.invoke
.ap_list
= parlist
;
4513 case Type::EXPECTED_CONSTANT
:
4514 error("An evaluable constant value was expected instead of operation "
4516 set_valuetype(V_ERROR
);
4518 case Type::EXPECTED_STATIC_VALUE
:
4519 error("A static value was expected instead of operation `apply()'");
4520 set_valuetype(V_ERROR
);
4527 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4528 ReferenceChain
*refch
,
4529 Type::expected_value_t exp_val
)
4531 bool self_ref
= false;
4532 if(valuetype
==V_ERROR
) return;
4533 // Commented out to report more errors :)
4534 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4535 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4536 switch(val
->get_valuetype()) {
4538 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4543 val
->get_value_refd_last(refch
, exp_val
);
4548 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4553 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4554 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4556 bool self_ref
= false;
4558 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4559 ti
->error("Reference to a %s value was expected instead of an in-line "
4560 "modified template",
4561 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4562 set_valuetype(V_ERROR
);
4565 Template
*templ
= ti
->get_Template();
4566 switch (templ
->get_templatetype()) {
4567 case Template::TEMPLATE_REFD
:
4569 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4570 templ
= templ
->get_template_refd_last(refch
);
4571 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4572 set_valuetype(V_ERROR
);
4574 ti
->error("Reference to a %s value was expected instead of %s",
4575 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4576 templ
->get_reference()->get_refd_assignment()
4577 ->get_description().c_str());
4578 set_valuetype(V_ERROR
);
4581 case Template::SPECIFIC_VALUE
: {
4582 Value
*val
= templ
->get_specific_value();
4583 switch (val
->get_valuetype()) {
4585 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4588 val
->get_value_refd_last(refch
, exp_val
);
4592 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4594 case Template::TEMPLATE_ERROR
:
4595 set_valuetype(V_ERROR
);
4604 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4607 if(valuetype
==V_ERROR
) return;
4608 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4609 if(val
->is_unfoldable()) return;
4610 if(*val
->get_val_Int()<0) {
4611 val
->error("%s operand of operation `%s' should not be negative",
4613 set_valuetype(V_ERROR
);
4617 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4620 if(valuetype
==V_ERROR
) return;
4621 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4622 if(val
->is_unfoldable()) return;
4623 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4624 val
->error("%s operand of operation `%s' should be in range 0..127",
4626 set_valuetype(V_ERROR
);
4630 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4633 if(valuetype
==V_ERROR
) return;
4634 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4635 if(val
->is_unfoldable()) return;
4636 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4637 val
->error("%s operand of operation `%s' should be in range"
4638 " 0..2147483647", opnum
, opname
);
4639 set_valuetype(V_ERROR
);
4643 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4646 if(valuetype
==V_ERROR
) return;
4647 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4648 if(val
->is_unfoldable()) return;
4649 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4651 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4653 val
->error("%s operand of operation `%s' should not be zero",
4655 set_valuetype(V_ERROR
);
4659 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4662 if (valuetype
== V_ERROR
) return;
4663 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4664 if (val
->get_expr_returntype() != Type::T_INT
) return;
4665 if (val
->is_unfoldable()) return;
4666 const int_val_t
*val_int
= val
->get_val_Int();
4667 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4668 val
->error("%s operand of operation `%s' should be less than `%d' "
4669 "instead of `%s'", opnum
, opname
, INT_MAX
,
4670 (val_int
->t_str()).c_str());
4671 set_valuetype(V_ERROR
);
4675 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4678 if(valuetype
==V_ERROR
) return;
4679 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4680 if(val
->is_unfoldable()) return;
4681 if(val
->get_val_strlen()!=1) {
4682 val
->error("%s operand of operation `%s' should be of length 1",
4684 set_valuetype(V_ERROR
);
4688 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4691 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4692 Value
*v_last
= val
->get_value_refd_last();
4693 if (v_last
->valuetype
== V_CSTR
) {
4694 size_t len
= v_last
->get_val_strlen();
4696 val
->error("%s operand of operation `%s' should contain even number "
4697 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4698 set_valuetype(V_ERROR
);
4700 } else if (v_last
->valuetype
== V_REFD
) {
4701 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4702 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4703 val
->error("%s operand of operation `%s' should contain even number "
4704 "of characters, but a string element contains 1", opnum
, opname
);
4705 set_valuetype(V_ERROR
);
4710 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4713 if(valuetype
==V_ERROR
) return;
4714 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4715 if(val
->is_unfoldable()) return;
4716 const string
& s
=val
->get_val_str();
4717 for(size_t i
=0; i
<s
.size(); i
++) {
4719 if(!(c
=='0' || c
=='1')) {
4720 val
->error("%s operand of operation `%s' can contain only"
4721 " binary digits (position %lu is `%c')",
4722 opnum
, opname
, (unsigned long) i
, c
);
4723 set_valuetype(V_ERROR
);
4729 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4732 if(valuetype
==V_ERROR
) return;
4733 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4734 if(val
->is_unfoldable()) return;
4735 const string
& s
=val
->get_val_str();
4736 for(size_t i
=0; i
<s
.size(); i
++) {
4738 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4739 val
->error("%s operand of operation `%s' can contain only valid "
4740 "hexadecimal digits (position %lu is `%c')",
4741 opnum
, opname
, (unsigned long) i
, c
);
4742 set_valuetype(V_ERROR
);
4748 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4751 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4752 Value
*v
= val
->get_value_refd_last();
4753 if (v
->valuetype
!= V_OSTR
) return;
4754 const string
& s
= val
->get_val_str();
4755 size_t n_octets
= s
.size() / 2;
4756 for (size_t i
= 0; i
< n_octets
; i
++) {
4758 if (!(c
>= '0' && c
<= '7')) {
4759 val
->error("%s operand of operation `%s' shall consist of octets "
4760 "within the range 00 .. 7F, but the string `%s'O contains octet "
4761 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4763 set_valuetype(V_ERROR
);
4769 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4772 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4773 Value
*v_last
= val
->get_value_refd_last();
4774 if (v_last
->valuetype
!= V_CSTR
) return;
4775 const string
& s
= v_last
->get_val_str();
4776 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4778 // state: expected characters
4779 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4780 // S_FIRST: first digit
4781 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4782 // S_END: trailing whitespace
4783 // S_ERR: error was found, stop
4784 for (size_t i
= 0; i
< s
.size(); i
++) {
4789 if (c
== '+' || c
== '-') state
= S_FIRST
;
4790 else if (c
== '0') state
= S_ZERO
;
4791 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4792 else if (string::is_whitespace(c
)) {
4793 if (state
== S_INITIAL
) {
4794 val
->warning("Leading whitespace was detected and ignored in the "
4795 "operand of operation `%s'", opname
);
4796 state
= S_INITIAL_WS
;
4798 } else state
= S_ERR
;
4801 if (c
== '0') state
= S_ZERO
;
4802 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4806 if (c
>= '0' && c
<= '9') {
4807 val
->warning("Leading zero digit was detected and ignored in the "
4808 "operand of operation `%s'", opname
);
4810 } else if (string::is_whitespace(c
)) state
= S_END
;
4814 if (c
>= '0' && c
<= '9') {}
4815 else if (string::is_whitespace(c
)) state
= S_END
;
4819 if (!string::is_whitespace(c
)) state
= S_ERR
;
4824 if (state
== S_ERR
) {
4825 if (string::is_printable(c
)) {
4826 val
->error("%s operand of operation `%s' should be a string "
4827 "containing a valid integer value, but invalid character `%c' "
4828 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4830 val
->error("%s operand of operation `%s' should be a string "
4831 "containing a valid integer value, but invalid character with "
4832 "character code %u was detected at index %lu", opnum
, opname
, c
,
4835 set_valuetype(V_ERROR
);
4842 val
->error("%s operand of operation `%s' should be a string containing a "
4843 "valid integer value instead of an empty string", opnum
, opname
);
4844 set_valuetype(V_ERROR
);
4847 val
->error("%s operand of operation `%s' should be a string containing a "
4848 "valid integer value, but only a sign character was detected", opnum
,
4850 set_valuetype(V_ERROR
);
4853 val
->warning("Trailing whitespace was detected and ignored in the "
4854 "operand of operation `%s'", opname
);
4861 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4864 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4865 Value
*v_last
= val
->get_value_refd_last();
4866 if (v_last
->valuetype
== V_REFD
) {
4867 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4868 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4869 val
->error("%s operand of operation `%s' should be a string containing "
4870 "a valid float value instead of a string element, which cannot "
4871 "represent a floating point number", opnum
, opname
);
4872 set_valuetype(V_ERROR
);
4875 } else if (v_last
->valuetype
!= V_CSTR
) return;
4876 const string
& s
= v_last
->get_val_str();
4877 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4878 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4880 // state: expected characters
4881 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4882 // leading whitespace
4883 // S_FIRST_M: first digit of integer part in mantissa
4884 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4885 // S_FIRST_F: first digit of fraction
4886 // S_MORE_F: more digits of fraction, E, trailing whitespace
4887 // S_INITIAL_E: +, -, first digit of exponent
4888 // S_FIRST_E: first digit of exponent
4889 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4890 // S_END: trailing whitespace
4891 // S_ERR: error was found, stop
4892 for (size_t i
= 0; i
< s
.size(); i
++) {
4897 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4898 else if (c
== '0') state
= S_ZERO_M
;
4899 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4900 else if (string::is_whitespace(c
)) {
4901 if (state
== S_INITIAL
) {
4902 val
->warning("Leading whitespace was detected and ignored in the "
4903 "operand of operation `%s'", opname
);
4904 state
= S_INITIAL_WS
;
4906 } else state
= S_ERR
;
4909 if (c
== '0') state
= S_ZERO_M
;
4910 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4914 if (c
== '.') state
= S_FIRST_F
;
4915 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4916 else if (c
>= '0' && c
<= '9') {
4917 val
->warning("Leading zero digit was detected and ignored in the "
4918 "mantissa of the operand of operation `%s'", opname
);
4920 } else state
= S_ERR
;
4923 if (c
== '.') state
= S_FIRST_F
;
4924 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4925 else if (c
>= '0' && c
<= '9') {}
4929 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4933 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4934 else if (c
>= '0' && c
<= '9') {}
4935 else if (string::is_whitespace(c
)) state
= S_END
;
4939 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4940 else if (c
== '0') state
= S_ZERO_E
;
4941 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4945 if (c
== '0') state
= S_ZERO_E
;
4946 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4950 if (c
>= '0' && c
<= '9') {
4951 val
->warning("Leading zero digit was detected and ignored in the "
4952 "exponent of the operand of operation `%s'", opname
);
4954 } else if (string::is_whitespace(c
)) state
= S_END
;
4958 if (c
>= '0' && c
<= '9') {}
4959 else if (string::is_whitespace(c
)) state
= S_END
;
4963 if (!string::is_whitespace(c
)) state
= S_ERR
;
4968 if (state
== S_ERR
) {
4969 if (string::is_printable(c
)) {
4970 val
->error("%s operand of operation `%s' should be a string "
4971 "containing a valid float value, but invalid character `%c' "
4972 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4974 val
->error("%s operand of operation `%s' should be a string "
4975 "containing a valid float value, but invalid character with "
4976 "character code %u was detected at index %lu", opnum
, opname
, c
,
4979 set_valuetype(V_ERROR
);
4986 val
->error("%s operand of operation `%s' should be a string containing a "
4987 "valid float value instead of an empty string", opnum
, opname
);
4988 set_valuetype(V_ERROR
);
4991 val
->error("%s operand of operation `%s' should be a string containing a "
4992 "valid float value, but only a sign character was detected", opnum
,
4994 set_valuetype(V_ERROR
);
4998 // HL67862: Missing decimal dot allowed for str2float
5001 // HL67862: Missing fraction part is allowed for str2float
5005 val
->error("%s operand of operation `%s' should be a string containing a "
5006 "valid float value, but the exponent is missing after the `E' sign",
5008 set_valuetype(V_ERROR
);
5011 val
->warning("Trailing whitespace was detected and ignored in the "
5012 "operand of operation `%s'", opname
);
5019 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
5022 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5023 Value
*v
= val
->get_value_refd_last();
5024 if (v
->valuetype
!= V_USTR
) return;
5025 const ustring
& us
= v
->get_val_ustr();
5026 for (size_t i
= 0; i
< us
.size(); i
++) {
5027 const ustring::universal_char
& uchar
= us
[i
];
5028 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
5030 val
->error("%s operand of operation `%s' shall consist of characters "
5031 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5032 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5033 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
5034 uchar
.row
, uchar
.cell
, (unsigned long) i
);
5035 set_valuetype(V_ERROR
);
5041 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
5044 if(valuetype
==V_ERROR
) return;
5045 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5046 if(val
->is_unfoldable()) return;
5047 const string
& bstr
=val
->get_val_str();
5048 // see also PredefFunc.cc::bit2int()
5049 size_t nof_bits
= bstr
.size();
5050 // skip the leading zeros
5051 size_t start_index
= 0;
5052 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
5053 // check whether the remaining bits fit in Int
5054 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
5055 val
->error("%s operand of operation `%s' is too large (maximum number"
5056 " of bits in integer is %lu)",
5057 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5058 set_valuetype(V_ERROR
);
5062 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
5065 if(valuetype
==V_ERROR
) return;
5066 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5067 if(val
->is_unfoldable()) return;
5068 const string
& hstr
=val
->get_val_str();
5069 // see also PredefFunc.cc::hex2int()
5070 size_t nof_digits
= hstr
.size();
5071 // skip the leading zeros
5072 size_t start_index
= 0;
5073 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
5074 // check whether the remaining hex digits fit in Int
5075 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
5076 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
5077 char_to_hexdigit(hstr
[start_index
]) > 7)) {
5078 val
->error("%s operand of operation `%s' is too large (maximum number"
5079 " of bits in integer is %lu)",
5080 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5081 set_valuetype(V_ERROR
);
5085 void Value::chk_expr_operands_int2binstr()
5087 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5088 if (u
.expr
.v1
->is_unfoldable()) return;
5089 if (u
.expr
.v2
->is_unfoldable()) return;
5090 // It is already checked that i1 and i2 are non-negative.
5091 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5092 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
5093 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
5094 if (!i2
->is_native()) {
5095 u
.expr
.v2
->error("The length of the resulting string is too large for "
5096 "being represented in memory");
5097 set_valuetype(V_ERROR
);
5100 Int nof_bits
= i2
->get_val();
5101 if (u
.expr
.v1
->is_unfoldable()) return;
5102 switch (u
.expr
.v_optype
) {
5103 case OPTYPE_INT2BIT
:
5105 case OPTYPE_INT2HEX
:
5108 case OPTYPE_INT2OCT
:
5112 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5114 if (*i1
>> nof_bits
> 0) { // Expensive?
5115 u
.expr
.v1
->error("Value %s does not fit in length %s",
5116 i1
->t_str().c_str(), i2
->t_str().c_str());
5117 set_valuetype(V_ERROR
);
5121 void Value::chk_expr_operands_str_samelen()
5123 if(valuetype
==V_ERROR
) return;
5124 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5125 Value
*v1
=u
.expr
.v1
;
5126 if(v1
->is_unfoldable()) return;
5127 Value
*v2
=u
.expr
.v2
;
5128 if(v2
->is_unfoldable()) return;
5129 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5130 size_t i1
=v1
->get_val_strlen();
5131 size_t i2
=v2
->get_val_strlen();
5133 error("The operands should have the same length");
5134 set_valuetype(V_ERROR
);
5138 void Value::chk_expr_operands_replace()
5140 // The fourth operand doesn't need to be checked at all here.
5141 if(valuetype
==V_ERROR
) return;
5142 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5143 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5146 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5147 size_t list_len
= 0;
5148 bool list_len_known
= false;
5149 if (v1
->valuetype
== V_REFD
) {
5150 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5151 if (subrefs
&& subrefs
->refers_to_string_element()) {
5152 warning("Replacing a string element does not make any sense");
5154 list_len_known
= true;
5157 if (!v1
->is_unfoldable()) {
5158 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5159 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5160 list_len_known
= true;
5162 if (!list_len_known
) return;
5163 if (u
.expr
.v2
->is_unfoldable()) {
5164 if (!u
.expr
.v3
->is_unfoldable()) {
5165 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5166 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5167 error("Third operand `len' (%s) is greater than the length of "
5168 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5169 (unsigned long)list_len
);
5170 set_valuetype(V_ERROR
);
5174 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5175 if (u
.expr
.v3
->is_unfoldable()) {
5176 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5177 error("Second operand `index' (%s) is greater than the length of "
5178 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5179 (unsigned long)list_len
);
5180 set_valuetype(V_ERROR
);
5183 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5184 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5185 error("The sum of second operand `index' (%s) and third operand "
5186 "`len' (%s) is greater than the length of the first operand (%lu)",
5187 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5188 (unsigned long)list_len
);
5189 set_valuetype(V_ERROR
);
5195 void Value::chk_expr_operands_substr()
5197 if(valuetype
==V_ERROR
) return;
5198 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5199 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5202 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5203 size_t list_len
= 0;
5204 bool list_len_known
= false;
5205 if (v1
->valuetype
== V_REFD
) {
5206 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5207 if (subrefs
&& subrefs
->refers_to_string_element()) {
5208 warning("Taking the substring of a string element does not make any "
5211 list_len_known
= true;
5214 if (!list_len_known
&& !v1
->is_unfoldable()) {
5215 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5216 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5217 list_len_known
= true;
5219 // Do nothing if the length of the first operand is unknown.
5220 if (!list_len_known
) return;
5221 if (u
.expr
.v2
->is_unfoldable()) {
5222 if (!u
.expr
.v3
->is_unfoldable()) {
5223 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5224 // Only the third operand is known.
5225 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5226 error("Third operand `returncount' (%s) is greater than the "
5227 "length of the first operand (%lu)",
5228 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5229 set_valuetype(V_ERROR
);
5233 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5234 if (u
.expr
.v3
->is_unfoldable()) {
5235 // Only the second operand is known.
5236 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5237 error("Second operand `index' (%s) is greater than the length "
5238 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5239 (unsigned long)list_len
);
5240 set_valuetype(V_ERROR
);
5243 // Both second and third operands are known.
5244 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5245 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5246 error("The sum of second operand `index' (%s) and third operand "
5247 "`returncount' (%s) is greater than the length of the first operand "
5248 "(%lu)", (index_int_2
->t_str()).c_str(),
5249 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5250 set_valuetype(V_ERROR
);
5256 void Value::chk_expr_operands_regexp()
5258 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5259 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5260 Value
* v2
= u
.expr
.t2
->get_specific_value();
5261 if (!v1
|| !v2
) return;
5263 Error_Context
cntxt(this, "In operation `regexp()'");
5264 Value
* v1_last
= v1
->get_value_refd_last();
5265 if (v1_last
->valuetype
== V_CSTR
) {
5266 // the input string is available at compile time
5267 const string
& instr
= v1_last
->get_val_str();
5268 const char *input_str
= instr
.c_str();
5269 size_t instr_len
= strlen(input_str
);
5270 if (instr_len
< instr
.size()) {
5271 v1
->warning("The first operand of `regexp()' contains a "
5272 "character with character code zero at index %s. The rest of the "
5273 "string will be ignored during matching",
5274 Int2string(instr_len
).c_str());
5278 size_t nof_groups
= 0;
5279 Value
*v2_last
= v2
->get_value_refd_last();
5281 if (v2_last
->valuetype
== V_CSTR
) {
5282 // the pattern is available at compile time
5283 const string
& expression
= v2_last
->get_val_str();
5284 const char *pattern_str
= expression
.c_str();
5285 size_t pattern_len
= strlen(pattern_str
);
5286 if (pattern_len
< expression
.size()) {
5287 v2
->warning("The second operand of `regexp()' contains a "
5288 "character with character code zero at index %s. The rest of the "
5289 "string will be ignored during matching",
5290 Int2string(pattern_len
).c_str());
5294 Error_Context
cntxt2(v2
, "In character string pattern");
5295 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5297 if (posix_str
!= NULL
) {
5298 regex_t posix_regexp
;
5299 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5302 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5303 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5304 "regcomp() failed: %s", msg
);
5306 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5308 v2
->error("The character pattern in the second operand of "
5309 "`regexp()' does not contain any groups");
5310 set_valuetype(V_ERROR
);
5312 regfree(&posix_regexp
);
5315 // the pattern is faulty
5316 // the error has been reported by TTCN_pattern_to_regexp
5317 set_valuetype(V_ERROR
);
5320 if (nof_groups
> 0) {
5321 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5322 if (v3
->valuetype
== V_INT
) {
5323 // the group number is available at compile time
5324 const int_val_t
*groupno_int
= v3
->get_val_Int();
5325 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5326 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5327 "large: The requested group index is %s, but the pattern "
5328 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5329 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5330 set_valuetype(V_ERROR
);
5336 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5337 Type::expected_value_t exp_val
)
5339 const char *opname
= get_opname();
5340 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5342 const Location
*loc
;
5343 bool error_flag
= false;
5344 switch (u
.expr
.v_optype
) {
5345 case OPTYPE_ISCHOSEN_V
:
5346 // u.expr.v1 is always a referenced value
5347 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5349 u
.expr
.v1
->set_my_governor(t_governor
);
5350 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5351 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5352 } else error_flag
= true;
5355 case OPTYPE_ISCHOSEN_T
:
5356 // u.expr.t1 is always a referenced template
5357 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5358 exp_val
= Type::EXPECTED_TEMPLATE
;
5359 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5361 u
.expr
.t1
->set_my_governor(t_governor
);
5363 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5365 u
.expr
.t1
->get_template_refd_last(refch
);
5366 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5368 } else error_flag
= true;
5369 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5370 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5371 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5372 u
.expr
.t1
->get_reference()->get_refd_assignment()
5373 ->get_description().c_str());
5379 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5384 t_governor
= t_governor
->get_type_refd_last();
5385 switch (t_governor
->get_typetype()) {
5389 case Type::T_CHOICE_A
:
5390 case Type::T_CHOICE_T
:
5391 case Type::T_ANYTYPE
:
5392 case Type::T_OPENTYPE
:
5393 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5394 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5395 "%s does not have a field named `%s'" :
5396 "Union type `%s' does not have a field named `%s'",
5397 t_governor
->get_typename().c_str(),
5398 u
.expr
.i2
->get_dispname().c_str());
5403 loc
->error("The operand of operation `%s' should be a union value "
5404 "or template instead of `%s'", opname
,
5405 t_governor
->get_typename().c_str());
5410 if (error_flag
) set_valuetype(V_ERROR
);
5413 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5414 Type::expected_value_t exp_val
) {
5416 Error_Context
cntxt(this, "In the parameter of %s",
5417 u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
? "encvalue_unichar()" : "encvalue()");
5418 Type
t_chk(Type::T_ERROR
);
5421 Type::expected_value_t ti_exp_val
= exp_val
;
5422 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5423 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5425 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5427 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5428 if (valuetype
!=V_ERROR
)
5429 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5430 t_type
= t_type
->get_type_refd_last();
5432 error("Cannot determine type of value");
5437 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5438 error("Expecting a value of a type with coding attributes in first"
5439 "parameter of encvalue() which belongs to a generic type '%s'",
5440 t_type->get_typename().c_str());
5444 if(!disable_attribute_validation()) {
5445 t_type
->chk_coding(true);
5448 switch (t_type
->get_typetype()) {
5453 case Type::T_REFDSPEC
:
5454 case Type::T_SELTYPE
:
5455 case Type::T_VERDICT
:
5457 case Type::T_COMPONENT
:
5458 case Type::T_DEFAULT
:
5459 case Type::T_SIGNATURE
:
5460 case Type::T_FUNCTION
:
5461 case Type::T_ALTSTEP
:
5462 case Type::T_TESTCASE
:
5463 error("Type of parameter of encvalue() cannot be '%s'",
5464 t_type
->get_typename().c_str());
5471 set_valuetype(V_ERROR
);
5474 void Value::chk_expr_operands_decode(operationtype_t p_optype
)
5476 Error_Context
cntxt(this, "In the parameters of %s",
5477 p_optype
== OPTYPE_DECVALUE_UNICHAR
? "decvalue_unichar()" : "decvalue()");
5478 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5479 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5481 Assignment
* t_ass
= ref
->get_refd_assignment();
5484 error("Could not determine the assignment for first parameter");
5487 switch (t_ass
->get_asstype()) {
5488 case Assignment::A_PAR_VAL_IN
:
5489 t_ass
->use_as_lvalue(*this);
5491 case Assignment::A_CONST
:
5492 case Assignment::A_EXT_CONST
:
5493 case Assignment::A_MODULEPAR
:
5494 case Assignment::A_MODULEPAR_TEMP
:
5495 case Assignment::A_TEMPLATE
:
5496 ref
->error("Reference to '%s' cannot be used as the first operand of "
5497 "the 'decvalue' operation", t_ass
->get_assname());
5500 case Assignment::A_VAR
:
5501 case Assignment::A_PAR_VAL_OUT
:
5502 case Assignment::A_PAR_VAL_INOUT
:
5504 case Assignment::A_VAR_TEMPLATE
:
5505 case Assignment::A_PAR_TEMPL_IN
:
5506 case Assignment::A_PAR_TEMPL_OUT
:
5507 case Assignment::A_PAR_TEMPL_INOUT
: {
5508 Template
* t
= new Template(ref
->clone());
5509 t
->set_location(*ref
);
5510 t
->set_my_scope(get_my_scope());
5511 t
->set_fullname(get_fullname()+".<operand>");
5512 Template
* t_last
= t
->get_template_refd_last();
5513 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5515 ref
->error("Specific value template was expected instead of '%s'.",
5516 t
->get_template_refd_last()->get_templatetype_str());
5523 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5526 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5527 Type::EXPECTED_DYNAMIC_VALUE
);
5533 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5534 error("First parameter has to be a bitstring");
5538 case OPTYPE_DECVALUE_UNICHAR
:
5539 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_USTR
){
5540 error("First parameter has to be a universal charstring");
5545 FATAL_ERROR("Value::chk_expr_decode_operands()");
5550 t_subrefs
= ref
->get_subrefs();
5551 t_ass
= ref
->get_refd_assignment();
5554 error("Could not determine the assignment for second parameter");
5557 // Extra check for HM59355.
5558 switch (t_ass
->get_asstype()) {
5559 case Assignment::A_VAR
:
5560 case Assignment::A_PAR_VAL_IN
:
5561 case Assignment::A_PAR_VAL_OUT
:
5562 case Assignment::A_PAR_VAL_INOUT
:
5565 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5568 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5569 Type::EXPECTED_DYNAMIC_VALUE
);
5573 t_type
= t_type
->get_type_refd_last();
5574 switch (t_type
->get_typetype()) {
5579 case Type::T_REFDSPEC
:
5580 case Type::T_SELTYPE
:
5581 case Type::T_VERDICT
:
5583 case Type::T_COMPONENT
:
5584 case Type::T_DEFAULT
:
5585 case Type::T_SIGNATURE
:
5586 case Type::T_FUNCTION
:
5587 case Type::T_ALTSTEP
:
5588 case Type::T_TESTCASE
:
5589 error("Type of second parameter cannot be %s",
5590 t_type
->get_typename().c_str());
5596 if(!disable_attribute_validation()) {
5597 t_type
->chk_coding(false);
5602 set_valuetype(V_ERROR
);
5605 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5607 Ttcn::FieldOrArrayRefs
*subrefs
;
5608 Identifier
*field_id
= 0;
5611 if (valuetype
== V_ERROR
) return;
5612 else if (valuetype
!= V_REFD
) {
5613 error("Only a referenced value can be compared with `omit'");
5616 subrefs
= u
.ref
.ref
->get_subrefs();
5617 if (subrefs
) field_id
= subrefs
->remove_last_field();
5619 error("Only a reference pointing to an optional record or set field "
5620 "can be compared with `omit'");
5623 t_ass
= u
.ref
.ref
->get_refd_assignment();
5624 if (!t_ass
) goto error
;
5625 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5626 if (!t_type
) goto error
;
5627 t_type
= t_type
->get_type_refd_last();
5628 switch (t_type
->get_typetype()) {
5637 error("Only a reference pointing to an optional field of a record"
5638 " or set type can be compared with `omit'");
5641 if (!t_type
->has_comp_withName(*field_id
)) {
5642 error("Type `%s' does not have field named `%s'",
5643 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5645 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5646 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5647 "`omit'", field_id
->get_dispname().c_str(),
5648 t_type
->get_typename().c_str());
5651 // putting the last field_id back to subrefs
5652 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5655 set_valuetype(V_ERROR
);
5659 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5660 Type::expected_value_t exp_val
)
5662 if(valuetype
==V_ERROR
) return -1;
5663 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5664 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5665 exp_val
=Type::EXPECTED_TEMPLATE
;
5667 Error_Context
cntxt(this, "In the operand of"
5668 " operation `%s'", get_opname());
5671 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5674 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5677 t_templ
= t_templ
->get_template_refd_last(refch
);
5679 // Timer and port arrays are handled separately
5680 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5681 Value
* val
= t_templ
->get_specific_value();
5682 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5683 val
->set_lowerid_to_ref();
5685 if (val
&& val
->get_valuetype() == V_REFD
) {
5686 Reference
* ref
= val
->get_reference();
5687 Assignment
* t_ass
= ref
->get_refd_assignment();
5688 Common::Assignment::asstype_t asstype
=
5689 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5690 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5691 if (t_ass
->get_Dimensions()) {
5692 // here we have a timer or port array
5693 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5694 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5695 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5696 Type::EXPECTED_DYNAMIC_VALUE
);
5699 refd_dim
= t_subrefs
->get_nof_refs();
5700 size_t nof_dims
= t_dims
->get_nof_dims();
5701 if (refd_dim
>= nof_dims
) {
5702 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5703 t_ass
->get_assname());
5704 set_valuetype(V_ERROR
);
5707 } else refd_dim
= 0;
5708 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5710 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5711 t_ass
->get_description().c_str());
5712 set_valuetype(V_ERROR
);
5721 Assignment
* t_ass
= 0;
5723 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5724 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5726 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5727 t_type
= t_type
->get_type_refd_last();
5729 error("Cannot determine type of value");
5733 if(valuetype
==V_ERROR
) return -1;
5735 t_templ
= t_templ
->get_template_refd_last(refch
);
5736 switch(t_templ
->get_templatetype()) {
5737 case Template::TEMPLATE_ERROR
:
5739 case Template::INDEXED_TEMPLATE_LIST
:
5741 case Template::TEMPLATE_REFD
:
5742 case Template::TEMPLATE_LIST
:
5743 case Template::NAMED_TEMPLATE_LIST
:
5746 case Template::SPECIFIC_VALUE
:
5748 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5750 switch(t_val
->get_valuetype()) {
5760 ref
= t_val
->get_reference();
5761 t_ass
= ref
->get_refd_assignment();
5762 t_subrefs
= ref
->get_subrefs();
5766 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5767 t_val
->create_stringRepr().c_str());
5774 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5775 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5780 switch(t_ass
->get_asstype()) {
5781 case Assignment::A_ERROR
:
5783 case Assignment::A_CONST
:
5784 t_val
= t_ass
->get_Value();
5786 case Assignment::A_EXT_CONST
:
5787 case Assignment::A_MODULEPAR
:
5788 case Assignment::A_MODULEPAR_TEMP
:
5789 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5790 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5791 "expected instead of %s", t_ass
->get_description().c_str());
5795 case Assignment::A_VAR
:
5796 case Assignment::A_PAR_VAL_IN
:
5797 case Assignment::A_PAR_VAL_OUT
:
5798 case Assignment::A_PAR_VAL_INOUT
:
5800 case Type::EXPECTED_CONSTANT
:
5801 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5802 t_ass
->get_description().c_str());
5805 case Type::EXPECTED_STATIC_VALUE
:
5806 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5807 t_ass
->get_description().c_str());
5814 case Assignment::A_TEMPLATE
:
5815 t_templ
= t_ass
->get_Template();
5817 case Assignment::A_VAR_TEMPLATE
:
5818 case Assignment::A_PAR_TEMPL_IN
:
5819 case Assignment::A_PAR_TEMPL_OUT
:
5820 case Assignment::A_PAR_TEMPL_INOUT
:
5821 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5822 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5823 t_ass
->get_description().c_str());
5826 case Assignment::A_FUNCTION_RVAL
:
5827 case Assignment::A_EXT_FUNCTION_RVAL
:
5829 case Type::EXPECTED_CONSTANT
:
5830 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5831 "the return value of %s", t_ass
->get_description().c_str());
5834 case Type::EXPECTED_STATIC_VALUE
:
5835 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5836 "the return value of %s", t_ass
->get_description().c_str());
5843 case Assignment::A_FUNCTION_RTEMP
:
5844 case Assignment::A_EXT_FUNCTION_RTEMP
:
5845 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5846 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5847 " of %s, which returns a template",
5848 t_ass
->get_description().c_str());
5851 case Assignment::A_TIMER
:
5852 case Assignment::A_PORT
:
5853 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5854 // sizeof is applicable to timer and port arrays
5855 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5857 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5858 t_ass
->get_description().c_str());
5861 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5862 Type::EXPECTED_DYNAMIC_VALUE
);
5865 refd_dim
= t_subrefs
->get_nof_refs();
5866 size_t nof_dims
= t_dims
->get_nof_dims();
5867 if (refd_dim
> nof_dims
) goto error
;
5868 else if (refd_dim
== nof_dims
) {
5869 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5870 t_ass
->get_assname());
5873 } else refd_dim
= 0;
5874 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5878 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5879 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5880 t_ass
->get_description().c_str());
5884 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5885 if (!t_type
) goto error
;
5886 t_type
= t_type
->get_type_refd_last();
5888 switch(t_type
->get_typetype()) {
5905 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5906 " set, set of, objid or array was expected");
5911 // check for index overflows in subrefs if possible
5913 switch (t_val
->get_valuetype()) {
5917 if (t_val
->is_indexed()) {
5924 /* The reference points to a constant. */
5925 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5926 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5927 if (!t_val
) goto error
;
5928 t_val
=t_val
->get_value_refd_last(refch
);
5929 } else { t_val
= 0; }
5930 } else if (t_templ
) {
5931 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5932 time. Don't try to evaluate it at compile time. */
5933 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5935 /* The reference points to a static template. */
5936 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5937 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5938 if (!t_templ
) goto error
;
5939 t_templ
= t_templ
->get_template_refd_last(refch
);
5940 } else { t_templ
= 0; }
5943 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5945 switch(t_templ
->get_templatetype()) {
5946 case Template::TEMPLATE_ERROR
:
5948 case Template::TEMPLATE_REFD
:
5952 case Template::SPECIFIC_VALUE
:
5953 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5956 case Template::TEMPLATE_LIST
:
5957 case Template::NAMED_TEMPLATE_LIST
:
5960 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5961 t_templ
->get_templatetype_str(),
5962 t_templ
->get_fullname().c_str());
5967 switch(t_val
->get_valuetype()) {
5978 // error is already reported
5987 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5988 result
= t_type
->get_dimension()->get_size();
5990 else if(t_templ
) { // sizeof()
5991 switch(t_templ
->get_templatetype()) {
5992 case Template::TEMPLATE_LIST
:
5993 if(t_templ
->temps_contains_anyornone_symbol()) {
5994 if(t_templ
->is_length_restricted()) {
5995 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5996 if (lr
->get_is_range()) {
5997 Value
*v_upper
= lr
->get_upper_value();
5999 if (v_upper
->valuetype
== V_INT
) {
6001 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
6002 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
6005 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
6006 "templates without exact size");
6011 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
6012 "templates containing `*' without upper boundary in the "
6013 "length restriction");
6017 Value
*v_single
= lr
->get_single_value();
6018 if (v_single
->valuetype
== V_INT
)
6019 result
= v_single
->u
.val_Int
->get_val();
6022 else { // not length restricted
6023 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
6024 " containing `*' without length restriction");
6028 else result
=t_templ
->get_nof_listitems();
6030 case Template::NAMED_TEMPLATE_LIST
:
6032 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
6033 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
6034 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
6037 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6041 switch(t_val
->get_valuetype()) {
6048 result
=t_val
->get_nof_comps();
6053 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
6054 if(t_val
->get_se_comp_byIndex(i
)->get_value()
6055 ->get_valuetype()!=V_OMIT
) result
++;
6059 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6065 set_valuetype(V_ERROR
);
6069 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
6071 Type
*governor
= ti
->get_expr_governor(exp_val
);
6073 ti
->get_Template()->set_lowerid_to_ref();
6074 governor
= ti
->get_expr_governor(exp_val
);
6078 ti
->append_stringRepr( str
);
6079 ti
->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6080 "If type is known, use valueof(<type>: %s) as argument.",
6081 str
.c_str(), get_opname(), str
.c_str());
6082 set_valuetype(V_ERROR
);
6087 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
6090 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
6091 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
6092 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
6093 Type::EXPECTED_TEMPLATE
: exp_val
);
6095 Template
*t_temp
= u
.expr
.t2
->get_Template();
6096 if (t_temp
->is_undef_lowerid()) {
6097 // We convert the template to reference first even if the value is also
6098 // an undef lowerid. The user can prevent this by explicit type
6100 t_temp
->set_lowerid_to_ref();
6102 } else if (u
.expr
.v1
->is_undef_lowerid()) {
6103 u
.expr
.v1
->set_lowerid_to_ref();
6108 error("Cannot determine the type of arguments in `match()' operation");
6109 set_valuetype(V_ERROR
);
6112 u
.expr
.v1
->set_my_governor(governor
);
6114 Error_Context
cntxt(this, "In the first argument of `match()'"
6116 governor
->chk_this_value_ref(u
.expr
.v1
);
6117 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
6118 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6121 Error_Context
cntxt(this, "In the second argument of `match()' "
6123 u
.expr
.t2
->chk(governor
);
6127 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
6128 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
6130 Ttcn::StatementBlock
*my_sb
;
6132 case Type::EXPECTED_CONSTANT
:
6133 error("An evaluable constant value was expected instead of operation "
6134 "`%s'", get_opname());
6136 case Type::EXPECTED_STATIC_VALUE
:
6137 error("A static value was expected instead of operation `%s'",
6143 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6144 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
6146 error("Operation `%s' is allowed only within statements",
6150 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6151 error("Operation `%s' is not allowed in the control part",
6155 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6156 error("Operation `%s' cannot be used in a definition that has "
6157 "`runs on' clause", get_opname());
6160 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6161 error("Operation `%s' can be used only in a definition that has "
6162 "`runs on' clause", get_opname());
6167 set_valuetype(V_ERROR
);
6170 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6172 if(valuetype
==V_ERROR
) return;
6173 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6174 if(v
->is_unfoldable()) return;
6175 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6176 ttcn3float r
= v
->get_val_Real();
6177 if (isSpecialFloatValue(r
)) {
6178 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6179 opnum
, opname
, Real2string(r
).c_str());
6180 set_valuetype(V_ERROR
);
6184 void Value::chk_expr_operands(ReferenceChain
*refch
,
6185 Type::expected_value_t exp_val
)
6187 const char *first
="First", *second
="Second", *third
="Third",
6188 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6189 Value
*v1
, *v2
, *v3
;
6190 Type::typetype_t tt1
, tt2
, tt3
;
6191 Type
t_chk(Type::T_ERROR
);
6193 const char *opname
=get_opname();
6195 // first classify the unchecked ischosen() operation
6196 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6198 switch (u
.expr
.v_optype
) {
6199 case OPTYPE_COMP_NULL
:
6200 case OPTYPE_TESTCASENAME
:
6201 case OPTYPE_PROF_RUNNING
:
6203 case OPTYPE_COMP_MTC
:
6204 case OPTYPE_COMP_SYSTEM
:
6205 chk_expr_comptype_compat();
6207 case OPTYPE_RND
: // -
6208 case OPTYPE_TMR_RUNNING_ANY
:
6209 chk_expr_dynamic_part(exp_val
, true);
6211 case OPTYPE_COMP_RUNNING_ANY
:
6212 case OPTYPE_COMP_RUNNING_ALL
:
6213 case OPTYPE_COMP_ALIVE_ANY
:
6214 case OPTYPE_COMP_ALIVE_ALL
:
6215 case OPTYPE_GETVERDICT
:
6216 chk_expr_dynamic_part(exp_val
, false);
6218 case OPTYPE_COMP_SELF
:
6219 chk_expr_comptype_compat();
6220 chk_expr_dynamic_part(exp_val
, false, true, false);
6222 case OPTYPE_UNARYPLUS
: // v1
6223 case OPTYPE_UNARYMINUS
:
6226 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6227 v1
->set_lowerid_to_ref();
6228 tt1
=v1
->get_expr_returntype(exp_val
);
6229 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6230 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6236 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6237 v1
->set_lowerid_to_ref();
6238 tt1
=v1
->get_expr_returntype(exp_val
);
6239 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6240 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6246 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6247 v1
->set_lowerid_to_ref();
6248 tt1
=v1
->get_expr_returntype(exp_val
);
6249 chk_expr_operandtype_binstr(tt1
, the
, opname
, v1
);
6250 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6253 case OPTYPE_BIT2HEX
:
6254 case OPTYPE_BIT2OCT
:
6255 case OPTYPE_BIT2STR
:
6258 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6259 v1
->set_lowerid_to_ref();
6260 tt1
=v1
->get_expr_returntype(exp_val
);
6261 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6262 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6265 case OPTYPE_BIT2INT
:
6268 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6269 v1
->set_lowerid_to_ref();
6270 tt1
=v1
->get_expr_returntype(exp_val
);
6271 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6272 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6273 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6276 case OPTYPE_CHAR2INT
:
6279 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6280 v1
->set_lowerid_to_ref();
6281 tt1
=v1
->get_expr_returntype(exp_val
);
6282 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6283 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6284 chk_expr_val_len1(v1
, the
, opname
);
6287 case OPTYPE_CHAR2OCT
:
6290 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6291 v1
->set_lowerid_to_ref();
6292 tt1
=v1
->get_expr_returntype(exp_val
);
6293 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6294 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6297 case OPTYPE_STR2INT
:
6300 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6301 v1
->set_lowerid_to_ref();
6302 tt1
=v1
->get_expr_returntype(exp_val
);
6303 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6304 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6305 chk_expr_val_str_int(v1
, the
, opname
);
6308 case OPTYPE_STR2FLOAT
:
6311 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6312 v1
->set_lowerid_to_ref();
6313 tt1
=v1
->get_expr_returntype(exp_val
);
6314 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6315 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6316 chk_expr_val_str_float(v1
, the
, opname
);
6319 case OPTYPE_STR2BIT
:
6322 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6323 v1
->set_lowerid_to_ref();
6324 tt1
=v1
->get_expr_returntype(exp_val
);
6325 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6326 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6327 chk_expr_val_str_bindigits(v1
, the
, opname
);
6330 case OPTYPE_STR2HEX
:
6333 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6334 v1
->set_lowerid_to_ref();
6335 tt1
=v1
->get_expr_returntype(exp_val
);
6336 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6337 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6338 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6341 case OPTYPE_STR2OCT
:
6344 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6345 v1
->set_lowerid_to_ref();
6346 tt1
=v1
->get_expr_returntype(exp_val
);
6347 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6348 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6349 chk_expr_val_str_len_even(v1
, the
, opname
);
6350 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6353 case OPTYPE_ENUM2INT
:
6356 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6357 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6358 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6362 chk_expr_operand_encode(refch
, exp_val
);
6364 case OPTYPE_FLOAT2INT
:
6365 case OPTYPE_FLOAT2STR
:
6368 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6369 v1
->set_lowerid_to_ref();
6370 tt1
=v1
->get_expr_returntype(exp_val
);
6371 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6372 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6373 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6374 chk_expr_operand_valid_float(v1
, the
, opname
);
6377 case OPTYPE_RNDWITHVAL
:
6380 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6381 v1
->set_lowerid_to_ref();
6382 tt1
=v1
->get_expr_returntype(exp_val
);
6383 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6384 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6385 chk_expr_operand_valid_float(v1
, the
, opname
);
6387 chk_expr_dynamic_part(exp_val
, true);
6389 case OPTYPE_HEX2BIT
:
6390 case OPTYPE_HEX2OCT
:
6391 case OPTYPE_HEX2STR
:
6394 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6395 v1
->set_lowerid_to_ref();
6396 tt1
=v1
->get_expr_returntype(exp_val
);
6397 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6398 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6401 case OPTYPE_HEX2INT
:
6404 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6405 v1
->set_lowerid_to_ref();
6406 tt1
=v1
->get_expr_returntype(exp_val
);
6407 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6408 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6409 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6412 case OPTYPE_INT2CHAR
:
6415 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6416 v1
->set_lowerid_to_ref();
6417 tt1
=v1
->get_expr_returntype(exp_val
);
6418 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6419 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6420 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6423 case OPTYPE_INT2UNICHAR
:
6426 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6427 v1
->set_lowerid_to_ref();
6428 tt1
=v1
->get_expr_returntype(exp_val
);
6429 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6430 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6431 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6434 case OPTYPE_INT2FLOAT
:
6435 case OPTYPE_INT2STR
:
6438 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6439 v1
->set_lowerid_to_ref();
6440 tt1
=v1
->get_expr_returntype(exp_val
);
6441 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6442 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6445 case OPTYPE_OCT2BIT
:
6446 case OPTYPE_OCT2HEX
:
6447 case OPTYPE_OCT2STR
:
6450 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6451 v1
->set_lowerid_to_ref();
6452 tt1
=v1
->get_expr_returntype(exp_val
);
6453 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6454 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6457 case OPTYPE_OCT2INT
:
6460 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6461 v1
->set_lowerid_to_ref();
6462 tt1
=v1
->get_expr_returntype(exp_val
);
6463 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6464 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6465 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6469 case OPTYPE_OCT2CHAR
:
6472 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6473 v1
->set_lowerid_to_ref();
6474 tt1
=v1
->get_expr_returntype(exp_val
);
6475 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6476 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6477 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6480 case OPTYPE_REMOVE_BOM
:
6483 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6484 v1
->set_lowerid_to_ref();
6485 tt1
=v1
->get_expr_returntype(exp_val
);
6486 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6487 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6490 case OPTYPE_GET_STRINGENCODING
:
6493 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6494 v1
->set_lowerid_to_ref();
6495 tt1
=v1
->get_expr_returntype(exp_val
);
6496 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6497 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6500 case OPTYPE_ENCODE_BASE64
:
6503 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6504 v1
->set_lowerid_to_ref();
6505 tt1
=v1
->get_expr_returntype(exp_val
);
6506 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6507 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6509 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6512 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6513 v2
->set_lowerid_to_ref();
6514 tt2
=v2
->get_expr_returntype(exp_val
);
6515 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6516 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6519 case OPTYPE_DECODE_BASE64
:
6522 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6523 v1
->set_lowerid_to_ref();
6524 tt1
=v1
->get_expr_returntype(exp_val
);
6525 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6526 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6529 case OPTYPE_UNICHAR2INT
:
6532 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6533 v1
->set_lowerid_to_ref();
6534 tt1
=v1
->get_expr_returntype(exp_val
);
6535 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6536 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6537 chk_expr_val_len1(v1
, the
, opname
);
6540 case OPTYPE_UNICHAR2CHAR
:
6543 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6544 v1
->set_lowerid_to_ref();
6545 tt1
=v1
->get_expr_returntype(exp_val
);
6546 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6547 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6548 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6551 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6554 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6555 v1
->set_lowerid_to_ref();
6556 tt1
=v1
->get_expr_returntype(exp_val
);
6557 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6558 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6560 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6563 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6564 v2
->set_lowerid_to_ref();
6565 tt2
=v2
->get_expr_returntype(exp_val
);
6566 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6567 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6570 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6573 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6574 v1
->set_lowerid_to_ref();
6575 tt1
=v1
->get_expr_returntype(exp_val
);
6576 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6577 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6579 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6582 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6583 v2
->set_lowerid_to_ref();
6584 tt2
=v2
->get_expr_returntype(exp_val
);
6585 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6586 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6589 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
6590 chk_expr_operand_encode(refch
, exp_val
);
6591 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6594 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6595 v2
->set_lowerid_to_ref();
6596 tt2
=v2
->get_expr_returntype(exp_val
);
6597 chk_expr_operandtype_charstr(tt2
, second
, opname
, v2
);
6598 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6601 case OPTYPE_DECVALUE_UNICHAR
:
6602 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR
);
6603 v3
=u
.expr
.v3
? u
.expr
.v3
: 0;
6606 Error_Context
cntxt(this, "In the thrid operand of operation `%s'", opname
);
6607 v3
->set_lowerid_to_ref();
6608 tt3
=v3
->get_expr_returntype(exp_val
);
6609 chk_expr_operandtype_charstr(tt3
, third
, opname
, v3
);
6610 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6613 case OPTYPE_ADD
: // v1 v2
6614 case OPTYPE_SUBTRACT
:
6615 case OPTYPE_MULTIPLY
:
6619 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6620 v1
->set_lowerid_to_ref();
6621 tt1
=v1
->get_expr_returntype(exp_val
);
6622 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6623 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6624 chk_expr_operand_valid_float(v1
, first
, opname
);
6628 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6629 v2
->set_lowerid_to_ref();
6630 tt2
=v2
->get_expr_returntype(exp_val
);
6631 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6632 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6633 chk_expr_operand_valid_float(v2
, second
, opname
);
6634 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6635 chk_expr_val_int_float_not0(v2
, second
, opname
);
6637 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6643 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6644 v1
->set_lowerid_to_ref();
6645 tt1
=v1
->get_expr_returntype(exp_val
);
6646 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6647 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6651 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6652 v2
->set_lowerid_to_ref();
6653 tt2
=v2
->get_expr_returntype(exp_val
);
6654 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6655 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6656 chk_expr_val_int_float_not0(v2
, right
, opname
);
6659 case OPTYPE_CONCAT
: {
6662 v1
->set_lowerid_to_ref();
6663 v2
->set_lowerid_to_ref();
6664 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6666 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6667 tt1
=v1
->get_expr_returntype(exp_val
);
6668 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6669 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6672 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6673 tt2
=v2
->get_expr_returntype(exp_val
);
6674 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6675 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6677 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6678 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6679 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6680 } else { // other list types
6681 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6682 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6684 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6685 set_valuetype(V_ERROR
);
6688 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6689 v1_gov
->chk_this_value_ref(v1
);
6690 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6691 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6692 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6696 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6697 set_valuetype(V_ERROR
);
6700 // for recof/setof literals set the type from v1
6702 v2
->set_my_governor(v1_gov
);
6705 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6707 v2_gov
->chk_this_value_ref(v2
);
6708 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6709 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6710 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6711 if (valuetype
== V_ERROR
) return;
6712 // 7.1.2 says that we shouldn't allow type compatibility.
6713 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6714 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6715 error("The operands of operation `%s' should be of compatible "
6716 "types", get_opname());
6725 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6727 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6729 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6732 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6734 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6735 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6736 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6737 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6738 * "a == not b" is not allowed. (HL69107)
6739 * The various *Expressions implement operator precedence in the std.
6740 * Titan's parser has only one Expression and relies on Bison
6741 * for operator precedence. The check below brings Titan in line
6742 * with the standard by explicitly making "a == not b" an error */
6743 if (v2
->get_valuetype() == V_EXPR
6744 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6745 error("The operation `%s' is not allowed to be "
6746 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6747 set_valuetype(V_ERROR
);
6757 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6759 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6761 tt1
=v1
->get_expr_returntype(exp_val
);
6762 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6763 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6766 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6768 tt2
=v2
->get_expr_returntype(exp_val
);
6769 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6770 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6778 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6780 v1
->set_lowerid_to_ref();
6781 tt1
=v1
->get_expr_returntype(exp_val
);
6782 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6783 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6787 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6789 v2
->set_lowerid_to_ref();
6790 tt2
=v2
->get_expr_returntype(exp_val
);
6791 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6792 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6800 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6802 v1
->set_lowerid_to_ref();
6803 tt1
=v1
->get_expr_returntype(exp_val
);
6804 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6805 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6809 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6811 v2
->set_lowerid_to_ref();
6812 tt2
=v2
->get_expr_returntype(exp_val
);
6813 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6814 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6816 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6817 chk_expr_operands_str_samelen();
6823 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6824 v1
->set_lowerid_to_ref();
6825 tt1
=v1
->get_expr_returntype(exp_val
);
6826 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6827 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6831 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6832 v2
->set_lowerid_to_ref();
6833 tt2
=v2
->get_expr_returntype(exp_val
);
6834 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6835 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6836 chk_expr_val_large_int(v2
, right
, opname
);
6842 v1
->set_lowerid_to_ref();
6843 if (v1
->is_string_type(exp_val
)) {
6844 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6845 tt1
=v1
->get_expr_returntype(exp_val
);
6846 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6847 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6848 } else { // other list types
6849 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6850 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6851 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6853 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6854 v1_gov
->chk_this_value_ref(v1
);
6855 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6856 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6857 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6862 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6863 v2
->set_lowerid_to_ref();
6864 tt2
=v2
->get_expr_returntype(exp_val
);
6865 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6866 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6867 chk_expr_val_large_int(v2
, right
, opname
);
6870 case OPTYPE_INT2BIT
:
6871 case OPTYPE_INT2HEX
:
6872 case OPTYPE_INT2OCT
:
6875 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6876 v1
->set_lowerid_to_ref();
6877 tt1
=v1
->get_expr_returntype(exp_val
);
6878 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6879 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6880 chk_expr_val_int_pos0(v1
, first
, opname
);
6884 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6885 v2
->set_lowerid_to_ref();
6886 tt2
=v2
->get_expr_returntype(exp_val
);
6887 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6888 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6889 chk_expr_val_int_pos0(v2
, second
, opname
);
6891 chk_expr_operands_int2binstr();
6894 chk_expr_operands_decode(OPTYPE_DECODE
);
6898 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6899 Type::expected_value_t ti_exp_val
= exp_val
;
6900 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6901 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6902 if (!governor
) return;
6903 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6904 if (valuetype
!=V_ERROR
)
6905 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6906 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6910 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6911 v2
->set_lowerid_to_ref();
6912 tt2
=v2
->get_expr_returntype(exp_val
);
6913 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6914 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6915 chk_expr_val_int_pos0(v2
, second
, opname
);
6919 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6920 v3
->set_lowerid_to_ref();
6921 tt3
=v3
->get_expr_returntype(exp_val
);
6922 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6923 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6924 chk_expr_val_int_pos0(v3
, third
, opname
);
6926 chk_expr_operands_substr();
6928 case OPTYPE_REGEXP
: {
6929 Type::expected_value_t ti_exp_val
= exp_val
;
6930 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6932 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6933 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6934 if (!governor
) return;
6935 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6936 if (valuetype
!=V_ERROR
) {
6937 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6938 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6939 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6943 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6944 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6945 if (!governor
) return;
6946 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6947 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6948 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6952 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6953 v3
->set_lowerid_to_ref();
6954 tt3
=v3
->get_expr_returntype(exp_val
);
6955 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6956 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6957 chk_expr_val_int_pos0(v3
, third
, opname
);
6959 chk_expr_operands_regexp();
6961 case OPTYPE_ISCHOSEN
:
6962 // do nothing: the operand is erroneous
6963 // the error was already reported in chk_expr_ref_ischosen()
6965 case OPTYPE_ISCHOSEN_V
: // v1 i2
6966 case OPTYPE_ISCHOSEN_T
: // t1 i2
6967 chk_expr_operands_ischosen(refch
, exp_val
);
6969 case OPTYPE_VALUEOF
: { // ti1
6970 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6971 exp_val
= Type::EXPECTED_TEMPLATE
;
6972 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6973 Type
*governor
= my_governor
;
6974 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6975 if (!governor
) return;
6976 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6977 if (valuetype
== V_ERROR
) return;
6978 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6980 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6981 case OPTYPE_ISBOUND
: {
6982 Template
*templ
= u
.expr
.ti1
->get_Template();
6983 switch (templ
->get_templatetype()) {
6984 case Template::TEMPLATE_REFD
:
6985 templ
->get_reference()->setUsedInIsbound();
6987 case Template::SPECIFIC_VALUE
: {
6988 Value
*value
= templ
->get_specific_value();
6989 if (Value::V_REFD
== value
->get_valuetype()) {
6990 value
->get_reference()->setUsedInIsbound();
6998 case OPTYPE_ISVALUE
: {// ti1
6999 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
7000 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7001 exp_val
= Type::EXPECTED_TEMPLATE
;
7002 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7003 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7004 if (!governor
) return;
7005 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
7006 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7008 case OPTYPE_SIZEOF
: // ti1
7009 /* this checking is too complex, do the checking during eval... */
7011 case OPTYPE_LENGTHOF
: { // ti1
7012 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7013 exp_val
= Type::EXPECTED_TEMPLATE
;
7014 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7015 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7016 if (!governor
) return;
7017 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
7018 if (valuetype
== V_ERROR
) return;
7019 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7021 case OPTYPE_MATCH
: // v1 t2
7022 chk_expr_operands_match(exp_val
);
7024 case OPTYPE_UNDEF_RUNNING
: // r1
7025 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
7027 case OPTYPE_COMP_ALIVE
:
7028 case OPTYPE_COMP_RUNNING
: //v1
7029 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
7030 chk_expr_dynamic_part(exp_val
, false);
7032 case OPTYPE_TMR_READ
: // r1
7033 case OPTYPE_TMR_RUNNING
: // r1
7034 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
7035 chk_expr_dynamic_part(exp_val
, true);
7037 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
7038 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
7039 chk_expr_dynamic_part(exp_val
, true, false, false);
7041 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7042 chk_expr_operand_comptyperef_create();
7045 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7046 v2
->set_lowerid_to_ref();
7047 tt2
=v2
->get_expr_returntype(exp_val
);
7048 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
7049 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7053 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
7054 v3
->set_lowerid_to_ref();
7055 tt3
=v3
->get_expr_returntype(exp_val
);
7056 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
7057 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7059 chk_expr_dynamic_part(exp_val
, false);
7061 case OPTYPE_ACTIVATE
: // r1 // altstep
7062 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
7063 chk_expr_dynamic_part(exp_val
, true);
7065 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
7066 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7067 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
7069 delete u
.expr
.t_list2
;
7070 u
.expr
.ap_list2
= parlist
;
7071 chk_expr_dynamic_part(exp_val
, true);
7073 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
7074 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7075 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
7076 u
.expr
.v3
, the
, opname
);
7077 delete u
.expr
.t_list2
;
7078 u
.expr
.ap_list2
= parlist
;
7079 chk_expr_dynamic_part(exp_val
, true);
7082 error("Built-in function `%s' is not yet supported", opname
);
7083 set_valuetype(V_ERROR
);
7085 case OPTYPE_REPLACE
: {
7086 Type::expected_value_t ti_exp_val
= exp_val
;
7087 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7088 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7090 Error_Context
cntxt(this, "In the first operand of operation `%s'",
7092 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7093 if (!governor
) return;
7094 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7095 if (valuetype
!= V_ERROR
)
7096 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7097 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
7101 Error_Context
cntxt(this, "In the second operand of operation `%s'",
7103 v2
->set_lowerid_to_ref();
7104 tt2
= v2
->get_expr_returntype(exp_val
);
7105 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
7106 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7107 chk_expr_val_int_pos0(v2
, second
, opname
);
7111 Error_Context
cntxt(this, "In the third operand of operation `%s'",
7113 v3
->set_lowerid_to_ref();
7114 tt3
= v3
->get_expr_returntype(exp_val
);
7115 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
7116 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7117 chk_expr_val_int_pos0(v3
, third
, opname
);
7120 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
7122 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
7123 if (!governor
) return;
7124 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
7125 if (valuetype
!= V_ERROR
)
7126 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
7127 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
7129 chk_expr_operands_replace();
7131 case OPTYPE_LOG2STR
:
7132 case OPTYPE_ANY2UNISTR
: {
7133 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7134 u
.expr
.logargs
->chk();
7135 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
7137 case OPTYPE_TTCN2STRING
: {
7138 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
7139 Type::expected_value_t ti_exp_val
= exp_val
;
7140 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7141 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7142 if (!governor
) return;
7143 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7146 FATAL_ERROR("chk_expr_operands()");
7150 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7151 // the result of evaluating the expression. E.g. V_BOOL for
7153 void Value::evaluate_value(ReferenceChain
*refch
,
7154 Type::expected_value_t exp_val
)
7156 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
7157 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
7159 u
.expr
.state
=EXPR_CHECKING
;
7161 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
7162 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
7163 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
7165 if(valuetype
==V_ERROR
) return;
7166 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
7167 u
.expr
.state
=EXPR_CHECKED
;
7168 set_valuetype(V_ERROR
);
7172 u
.expr
.state
=EXPR_CHECKED
;
7174 Value
*v1
, *v2
, *v3
, *v4
;
7175 switch(u
.expr
.v_optype
) {
7176 case OPTYPE_RND
: // -
7177 case OPTYPE_COMP_NULL
: // the only foldable in this group
7178 case OPTYPE_COMP_MTC
:
7179 case OPTYPE_COMP_SYSTEM
:
7180 case OPTYPE_COMP_SELF
:
7181 case OPTYPE_COMP_RUNNING_ANY
:
7182 case OPTYPE_COMP_RUNNING_ALL
:
7183 case OPTYPE_COMP_ALIVE_ANY
:
7184 case OPTYPE_COMP_ALIVE_ALL
:
7185 case OPTYPE_TMR_RUNNING_ANY
:
7186 case OPTYPE_GETVERDICT
:
7187 case OPTYPE_PROF_RUNNING
:
7188 case OPTYPE_RNDWITHVAL
: // v1
7189 case OPTYPE_COMP_RUNNING
: // v1
7190 case OPTYPE_COMP_ALIVE
:
7191 case OPTYPE_TMR_READ
:
7192 case OPTYPE_TMR_RUNNING
:
7193 case OPTYPE_ACTIVATE
:
7194 case OPTYPE_ACTIVATE_REFD
:
7195 case OPTYPE_EXECUTE
: // r1 [v2]
7196 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7197 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7198 case OPTYPE_MATCH
: // v1 t2
7199 case OPTYPE_ISCHOSEN_T
:
7200 case OPTYPE_LOG2STR
:
7201 case OPTYPE_ANY2UNISTR
:
7204 case OPTYPE_ISBOUND
:
7205 case OPTYPE_ISPRESENT
:
7206 case OPTYPE_TTCN2STRING
:
7207 case OPTYPE_UNICHAR2OCT
:
7208 case OPTYPE_OCT2UNICHAR
:
7209 case OPTYPE_ENCODE_BASE64
:
7210 case OPTYPE_DECODE_BASE64
:
7211 case OPTYPE_ENCVALUE_UNICHAR
:
7212 case OPTYPE_DECVALUE_UNICHAR
:
7214 case OPTYPE_TESTCASENAME
: { // -
7215 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7216 Ttcn::StatementBlock
*my_sb
=
7217 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7219 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7220 if (!my_def
) { // In control part.
7221 set_val_str(new string(""));
7223 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7224 set_val_str(new string(my_def
->get_id().get_dispname()));
7228 case OPTYPE_UNARYPLUS
: // v1
7231 copy_and_destroy(v1
);
7233 case OPTYPE_UNARYMINUS
:
7234 if (is_unfoldable()) break;
7235 v1
= u
.expr
.v1
->get_value_refd_last();
7236 switch (v1
->valuetype
) {
7238 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7239 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7245 ttcn3float r
= v1
->get_val_Real();
7251 FATAL_ERROR("Value::evaluate_value()");
7255 if(is_unfoldable()) break;
7256 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7261 case OPTYPE_NOT4B
: {
7262 if(is_unfoldable()) break;
7263 v1
=u
.expr
.v1
->get_value_refd_last();
7264 const string
& s
= v1
->get_val_str();
7265 valuetype_t vt
=v1
->valuetype
;
7268 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7270 case OPTYPE_BIT2HEX
: {
7271 if(is_unfoldable()) break;
7272 v1
=u
.expr
.v1
->get_value_refd_last();
7273 const string
& s
= v1
->get_val_str();
7276 set_val_str(bit2hex(s
));
7278 case OPTYPE_BIT2OCT
: {
7279 if(is_unfoldable()) break;
7280 v1
=u
.expr
.v1
->get_value_refd_last();
7281 const string
& s
= v1
->get_val_str();
7284 set_val_str(bit2oct(s
));
7286 case OPTYPE_BIT2STR
:
7287 case OPTYPE_HEX2STR
:
7288 case OPTYPE_OCT2STR
: {
7289 if(is_unfoldable()) break;
7290 v1
=u
.expr
.v1
->get_value_refd_last();
7291 const string
& s
= v1
->get_val_str();
7294 set_val_str(new string(s
));
7296 case OPTYPE_BIT2INT
: {
7297 if (is_unfoldable()) break;
7298 v1
= u
.expr
.v1
->get_value_refd_last();
7299 const string
& s
= v1
->get_val_str();
7302 u
.val_Int
= bit2int(s
);
7304 case OPTYPE_CHAR2INT
: {
7305 if (is_unfoldable()) break;
7306 v1
= u
.expr
.v1
->get_value_refd_last();
7307 char c
= v1
->get_val_str()[0];
7310 u
.val_Int
= new int_val_t((Int
)c
);
7312 case OPTYPE_CHAR2OCT
: {
7313 if(is_unfoldable()) break;
7314 v1
=u
.expr
.v1
->get_value_refd_last();
7315 const string
& s
= v1
->get_val_str();
7318 set_val_str(char2oct(s
));
7320 case OPTYPE_STR2INT
: {
7321 if (is_unfoldable()) break;
7322 v1
= u
.expr
.v1
->get_value_refd_last();
7323 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7327 /** \todo hiba eseten lenyeli... */
7329 case OPTYPE_STR2FLOAT
: {
7330 if(is_unfoldable()) break;
7331 v1
=u
.expr
.v1
->get_value_refd_last();
7332 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7336 /** \todo hiba eseten lenyeli... */
7338 case OPTYPE_STR2BIT
: {
7339 if(is_unfoldable()) break;
7340 v1
=u
.expr
.v1
->get_value_refd_last();
7341 const string
& s
= v1
->get_val_str();
7344 set_val_str(new string(s
));
7346 case OPTYPE_STR2HEX
:
7347 case OPTYPE_OCT2HEX
: {
7348 if(is_unfoldable()) break;
7349 v1
=u
.expr
.v1
->get_value_refd_last();
7350 const string
& s
= v1
->get_val_str();
7353 set_val_str(to_uppercase(s
));
7355 case OPTYPE_STR2OCT
: {
7356 if(is_unfoldable()) break;
7357 v1
=u
.expr
.v1
->get_value_refd_last();
7358 const string
& s
= v1
->get_val_str();
7361 set_val_str(to_uppercase(s
));
7363 case OPTYPE_FLOAT2INT
: {
7364 if (is_unfoldable()) break;
7365 v1
= u
.expr
.v1
->get_value_refd_last();
7366 ttcn3float r
= v1
->get_val_Real();
7369 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7371 case OPTYPE_FLOAT2STR
: {
7372 if(is_unfoldable()) break;
7373 v1
=u
.expr
.v1
->get_value_refd_last();
7374 ttcn3float r
=v1
->get_val_Real();
7377 set_val_str(float2str(r
));
7379 case OPTYPE_HEX2BIT
:
7380 case OPTYPE_OCT2BIT
: {
7381 if(is_unfoldable()) break;
7382 v1
=u
.expr
.v1
->get_value_refd_last();
7383 const string
& s
= v1
->get_val_str();
7386 set_val_str(hex2bit(s
));
7388 case OPTYPE_HEX2INT
:
7389 case OPTYPE_OCT2INT
: {
7390 if(is_unfoldable()) break;
7391 v1
=u
.expr
.v1
->get_value_refd_last();
7392 const string
& s
= v1
->get_val_str();
7395 u
.val_Int
=hex2int(s
);
7397 case OPTYPE_HEX2OCT
: {
7398 if(is_unfoldable()) break;
7399 v1
=u
.expr
.v1
->get_value_refd_last();
7400 const string
& s
= v1
->get_val_str();
7403 set_val_str(hex2oct(s
));
7405 case OPTYPE_INT2CHAR
: {
7406 if (is_unfoldable()) break;
7407 v1
= u
.expr
.v1
->get_value_refd_last();
7408 const int_val_t
*c_int
= v1
->get_val_Int();
7409 char c
= static_cast<char>(c_int
->get_val());
7412 set_val_str(new string(1, &c
));
7414 case OPTYPE_INT2UNICHAR
: {
7415 if (is_unfoldable()) break;
7416 v1
= u
.expr
.v1
->get_value_refd_last();
7417 const int_val_t
*i_int
= v1
->get_val_Int();
7418 Int i
= i_int
->get_val();
7421 set_val_ustr(int2unichar(i
));
7422 u
.ustr
.convert_str
= false;
7424 case OPTYPE_INT2FLOAT
: {
7425 if (is_unfoldable()) break;
7426 v1
= u
.expr
.v1
->get_value_refd_last();
7427 const int_val_t
*i_int
= v1
->get_val_Int();
7428 Real i_int_real
= i_int
->to_real();
7431 u
.val_Real
= i_int_real
;
7433 case OPTYPE_INT2STR
: {
7434 if (is_unfoldable()) break;
7435 v1
= u
.expr
.v1
->get_value_refd_last();
7436 const int_val_t
*i_int
= v1
->get_val_Int();
7437 string
*i_int_str
= new string(i_int
->t_str());
7440 set_val_str(i_int_str
);
7442 case OPTYPE_OCT2CHAR
: {
7443 if(is_unfoldable()) break;
7444 v1
=u
.expr
.v1
->get_value_refd_last();
7445 const string
& s
= v1
->get_val_str();
7448 set_val_str(oct2char(s
));
7450 case OPTYPE_GET_STRINGENCODING
: {
7451 if(is_unfoldable()) break;
7452 v1
= u
.expr
.v1
->get_value_refd_last();
7453 const string
& s1
= v1
->get_val_str();
7456 set_val_str(get_stringencoding(s1
));
7458 case OPTYPE_REMOVE_BOM
: {
7459 if(is_unfoldable()) break;
7460 v1
= u
.expr
.v1
->get_value_refd_last();
7461 const string
& s1
= v1
->get_val_str();
7464 set_val_str(remove_bom(s1
));
7466 case OPTYPE_ENUM2INT
: {
7467 if(is_unfoldable()) break;
7468 v1
=u
.expr
.v1
->get_value_refd_last();
7469 Type
* enum_type
= v1
->get_my_governor();
7470 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7473 u
.val_Int
= new int_val_t(enum_val
);
7475 case OPTYPE_UNICHAR2INT
:
7476 if (is_unfoldable()) {
7477 // replace the operation with char2int() if the operand is a charstring
7478 // value to avoid its unnecessary conversion to universal charstring
7479 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7480 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7482 v1
=u
.expr
.v1
->get_value_refd_last();
7483 const ustring
& s
= v1
->get_val_ustr();
7486 u
.val_Int
=new int_val_t(unichar2int(s
));
7489 case OPTYPE_UNICHAR2CHAR
:
7491 if (is_unfoldable()) {
7492 // replace the operation with its operand if it is a charstring
7493 // value to avoid its unnecessary conversion to universal charstring
7494 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7496 copy_and_destroy(v1
);
7499 v1
= v1
->get_value_refd_last();
7500 const ustring
& s
= v1
->get_val_ustr();
7503 set_val_str(new string(s
));
7506 case OPTYPE_MULTIPLY
: { // v1 v2
7507 if (!is_unfoldable()) goto eval_arithmetic
;
7508 v1
= u
.expr
.v1
->get_value_refd_last();
7509 v2
= u
.expr
.v2
->get_value_refd_last();
7510 if (v1
->is_unfoldable()) v1
= v2
;
7511 if (v1
->is_unfoldable()) break;
7512 switch(v1
->valuetype
) {
7514 if (*v1
->get_val_Int() != 0) break;
7517 u
.val_Int
= new int_val_t((Int
)0);
7520 if (v1
->get_val_Real() != 0.0) break;
7526 FATAL_ERROR("Value::evaluate_value()");
7529 case OPTYPE_ADD
: // v1 v2
7530 case OPTYPE_SUBTRACT
:
7535 if(is_unfoldable()) break;
7536 v1
=u
.expr
.v1
->get_value_refd_last();
7537 v2
=u
.expr
.v2
->get_value_refd_last();
7538 operationtype_t ot
=u
.expr
.v_optype
;
7539 switch (v1
->valuetype
) {
7541 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7542 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7547 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7549 case OPTYPE_SUBTRACT
:
7550 u
.val_Int
= new int_val_t(*i1
- *i2
);
7552 case OPTYPE_MULTIPLY
:
7553 u
.val_Int
= new int_val_t(*i1
* *i2
);
7556 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7559 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7562 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7565 FATAL_ERROR("Value::evaluate_value()");
7571 ttcn3float r1
=v1
->get_val_Real();
7572 ttcn3float r2
=v2
->get_val_Real();
7579 case OPTYPE_SUBTRACT
:
7582 case OPTYPE_MULTIPLY
:
7589 FATAL_ERROR("Value::evaluate_value()");
7593 FATAL_ERROR("Value::evaluate_value()");
7596 case OPTYPE_CONCAT
: {
7597 if(is_unfoldable()) break;
7598 v1
=u
.expr
.v1
->get_value_refd_last();
7599 v2
=u
.expr
.v2
->get_value_refd_last();
7600 valuetype_t vt
= v1
->valuetype
;
7601 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7602 const ustring
& s1
= v1
->get_val_ustr();
7603 const ustring
& s2
= v2
->get_val_ustr();
7606 set_val_ustr(new ustring(s1
+ s2
));
7607 u
.ustr
.convert_str
= false;
7609 const string
& s1
= v1
->get_val_str();
7610 const string
& s2
= v2
->get_val_str();
7613 set_val_str(new string(s1
+ s2
));
7617 if(is_unfoldable()) break;
7618 v1
=u
.expr
.v1
->get_value_refd_last();
7619 v2
=u
.expr
.v2
->get_value_refd_last();
7626 if(is_unfoldable()) break;
7627 v1
=u
.expr
.v1
->get_value_refd_last();
7628 v2
=u
.expr
.v2
->get_value_refd_last();
7635 if(is_unfoldable()) break;
7636 v1
=u
.expr
.v1
->get_value_refd_last();
7637 v2
=u
.expr
.v2
->get_value_refd_last();
7644 if(is_unfoldable()) break;
7645 v1
=u
.expr
.v1
->get_value_refd_last();
7646 v2
=u
.expr
.v2
->get_value_refd_last();
7653 if(is_unfoldable()) break;
7654 v1
=u
.expr
.v1
->get_value_refd_last();
7655 v2
=u
.expr
.v2
->get_value_refd_last();
7662 if(is_unfoldable()) break;
7663 v1
=u
.expr
.v1
->get_value_refd_last();
7664 v2
=u
.expr
.v2
->get_value_refd_last();
7671 v1
= u
.expr
.v1
->get_value_refd_last();
7672 if (v1
->valuetype
== V_BOOL
) {
7673 if (v1
->get_val_bool()) {
7674 // the left operand is a literal "true"
7675 // substitute the expression with the right operand
7678 copy_and_destroy(v2
);
7680 // the left operand is a literal "false"
7681 // the result must be false regardless the right operand
7682 // because of the short circuit evaluation rule
7688 // we must keep the left operand because of the potential side effects
7689 // the right operand can only be eliminated if it is a literal "true"
7690 v2
= u
.expr
.v2
->get_value_refd_last();
7691 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7694 copy_and_destroy(v1
);
7699 v1
= u
.expr
.v1
->get_value_refd_last();
7700 if (v1
->valuetype
== V_BOOL
) {
7701 if (v1
->get_val_bool()) {
7702 // the left operand is a literal "true"
7703 // the result must be true regardless the right operand
7704 // because of the short circuit evaluation rule
7709 // the left operand is a literal "false"
7710 // substitute the expression with the right operand
7713 copy_and_destroy(v2
);
7716 // we must keep the left operand because of the potential side effects
7717 // the right operand can only be eliminated if it is a literal "false"
7718 v2
= u
.expr
.v2
->get_value_refd_last();
7719 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7722 copy_and_destroy(v1
);
7727 if(is_unfoldable()) break;
7728 v1
=u
.expr
.v1
->get_value_refd_last();
7729 v2
=u
.expr
.v2
->get_value_refd_last();
7730 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7735 case OPTYPE_AND4B
: {
7736 if(is_unfoldable()) break;
7737 v1
=u
.expr
.v1
->get_value_refd_last();
7738 v2
=u
.expr
.v2
->get_value_refd_last();
7739 valuetype_t vt
=v1
->valuetype
;
7740 const string
& s1
= v1
->get_val_str();
7741 const string
& s2
= v2
->get_val_str();
7744 set_val_str(and4b(s1
, s2
));
7747 if(is_unfoldable()) break;
7748 v1
=u
.expr
.v1
->get_value_refd_last();
7749 v2
=u
.expr
.v2
->get_value_refd_last();
7750 valuetype_t vt
=v1
->valuetype
;
7751 const string
& s1
= v1
->get_val_str();
7752 const string
& s2
= v2
->get_val_str();
7755 set_val_str(or4b(s1
, s2
));
7757 case OPTYPE_XOR4B
: {
7758 if(is_unfoldable()) break;
7759 v1
=u
.expr
.v1
->get_value_refd_last();
7760 v2
=u
.expr
.v2
->get_value_refd_last();
7761 valuetype_t vt
=v1
->valuetype
;
7762 const string
& s1
= v1
->get_val_str();
7763 const string
& s2
= v2
->get_val_str();
7766 set_val_str(xor4b(s1
, s2
));
7769 if(is_unfoldable()) break;
7770 v1
=u
.expr
.v1
->get_value_refd_last();
7771 v2
=u
.expr
.v2
->get_value_refd_last();
7772 valuetype_t vt
=v1
->valuetype
;
7773 const string
& s
= v1
->get_val_str();
7774 const int_val_t
*i_int
= v2
->get_val_Int();
7775 Int i
=i_int
->get_val();
7776 if(vt
==V_OSTR
) i
*=2;
7779 set_val_str(shift_left(s
, i
));
7782 if(is_unfoldable()) break;
7783 v1
=u
.expr
.v1
->get_value_refd_last();
7784 v2
=u
.expr
.v2
->get_value_refd_last();
7785 valuetype_t vt
=v1
->valuetype
;
7786 const string
& s
= v1
->get_val_str();
7787 const int_val_t
*i_int
= v2
->get_val_Int();
7788 Int i
=i_int
->get_val();
7789 if(vt
==V_OSTR
) i
*=2;
7792 set_val_str(shift_right(s
, i
));
7795 if(is_unfoldable()) break;
7796 v1
=u
.expr
.v1
->get_value_refd_last();
7797 v2
=u
.expr
.v2
->get_value_refd_last();
7798 valuetype_t vt
=v1
->valuetype
;
7799 const int_val_t
*i_int
=v2
->get_val_Int();
7800 Int i
=i_int
->get_val();
7802 const ustring
& s
= v1
->get_val_ustr();
7805 set_val_ustr(rotate_left(s
, i
));
7806 u
.ustr
.convert_str
= false;
7809 if(vt
==V_OSTR
) i
*=2;
7810 const string
& s
= v1
->get_val_str();
7813 set_val_str(rotate_left(s
, i
));
7817 if(is_unfoldable()) break;
7818 v1
=u
.expr
.v1
->get_value_refd_last();
7819 v2
=u
.expr
.v2
->get_value_refd_last();
7820 valuetype_t vt
=v1
->valuetype
;
7821 const int_val_t
*i_int
=v2
->get_val_Int();
7822 Int i
=i_int
->get_val();
7824 const ustring
& s
= v1
->get_val_ustr();
7827 set_val_ustr(rotate_right(s
, i
));
7828 u
.ustr
.convert_str
= false;
7831 if(vt
==V_OSTR
) i
*=2;
7832 const string
& s
= v1
->get_val_str();
7835 set_val_str(rotate_right(s
, i
));
7838 case OPTYPE_INT2BIT
: {
7839 if (is_unfoldable()) break;
7840 v1
= u
.expr
.v1
->get_value_refd_last();
7841 v2
= u
.expr
.v2
->get_value_refd_last();
7842 const int_val_t
*i1_int
= v1
->get_val_Int();
7843 const int_val_t
*i2_int
= v2
->get_val_Int();
7844 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7849 case OPTYPE_INT2HEX
: {
7850 if (is_unfoldable()) break;
7851 v1
= u
.expr
.v1
->get_value_refd_last();
7852 v2
= u
.expr
.v2
->get_value_refd_last();
7853 const int_val_t
*i1_int
= v1
->get_val_Int();
7854 const int_val_t
*i2_int
= v2
->get_val_Int();
7855 // Do it before the `clean_up'. i2_int is already checked.
7856 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7861 case OPTYPE_INT2OCT
: {
7862 if (is_unfoldable()) break;
7863 v1
= u
.expr
.v1
->get_value_refd_last();
7864 v2
= u
.expr
.v2
->get_value_refd_last();
7865 const int_val_t
i1_int(*v1
->get_val_Int());
7866 // `v2' is a native integer.
7867 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7870 set_val_str(int2hex(i1_int
, i2_int
));
7872 case OPTYPE_SUBSTR
: {
7873 if(is_unfoldable()) break;
7874 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7875 v2
=u
.expr
.v2
->get_value_refd_last();
7876 v3
=u
.expr
.v3
->get_value_refd_last();
7877 valuetype_t vt
=v1
->valuetype
;
7878 const int_val_t
*i2_int
=v2
->get_val_Int();
7879 const int_val_t
*i3_int
=v3
->get_val_Int();
7880 Int i2
=i2_int
->get_val();
7881 Int i3
=i3_int
->get_val();
7883 const ustring
& s
= v1
->get_val_ustr();
7886 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7887 u
.ustr
.convert_str
= false;
7894 const string
& s
= v1
->get_val_str();
7897 set_val_str(new string(s
.substr(i2
, i3
)));
7900 case OPTYPE_REPLACE
: {
7901 if(is_unfoldable()) break;
7902 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7903 v2
=u
.expr
.v2
->get_value_refd_last();
7904 v3
=u
.expr
.v3
->get_value_refd_last();
7905 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7906 valuetype_t vt
=v1
->valuetype
;
7907 const int_val_t
*i2_int
=v2
->get_val_Int();
7908 const int_val_t
*i3_int
=v3
->get_val_Int();
7909 Int i2
=i2_int
->get_val();
7910 Int i3
=i3_int
->get_val();
7913 string
*s1
= new string(v1
->get_val_str());
7914 const string
& s2
= v4
->get_val_str();
7917 s1
->replace(i2
, i3
, s2
);
7921 string
*s1
= new string(v1
->get_val_str());
7922 const string
& s2
= v4
->get_val_str();
7925 s1
->replace(i2
, i3
, s2
);
7931 string
*s1
= new string(v1
->get_val_str());
7932 const string
& s2
= v4
->get_val_str();
7935 s1
->replace(i2
, i3
, s2
);
7939 string
*s1
= new string(v1
->get_val_str());
7940 const string
& s2
= v4
->get_val_str();
7943 s1
->replace(i2
, i3
, s2
);
7947 ustring
*s1
= new ustring(v1
->get_val_ustr());
7948 const ustring
& s2
= v4
->get_val_ustr();
7951 s1
->replace(i2
, i3
, s2
);
7953 u
.ustr
.convert_str
= false;
7956 FATAL_ERROR("Value::evaluate_value()");
7959 case OPTYPE_REGEXP
: {
7960 if (is_unfoldable()) break;
7961 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7962 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7963 v3
=u
.expr
.v3
->get_value_refd_last();
7964 const int_val_t
*i3_int
= v3
->get_val_Int();
7965 Int i3
= i3_int
->get_val();
7966 if (v1
->valuetype
== V_CSTR
) {
7967 const string
& s1
= v1
->get_val_str();
7968 const string
& s2
= v2
->get_val_str();
7969 string
*result
= regexp(s1
, s2
, i3
);
7972 set_val_str(result
);
7973 } if (v1
->valuetype
== V_USTR
) {
7974 const ustring
& s1
= v1
->get_val_ustr();
7975 const ustring
& s2
= v2
->get_val_ustr();
7976 ustring
*result
= regexp(s1
, s2
, i3
);
7979 set_val_ustr(result
);
7980 u
.ustr
.convert_str
= false;
7983 case OPTYPE_LENGTHOF
:{
7984 if(is_unfoldable()) break;
7985 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7986 ->get_value_refd_last();
7988 if(v1
->is_string_type(exp_val
)) {
7989 i
=v1
->get_val_strlen();
7990 } else { // v1 is be seq/set of or array
7991 switch (v1
->valuetype
) {
7995 if(v1
->u
.val_vs
->is_indexed())
7996 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7997 else { i
= v1
->u
.val_vs
->get_nof_vs();}
8000 FATAL_ERROR("Value::evaluate_value()");
8005 u
.val_Int
=new int_val_t(i
);
8007 case OPTYPE_SIZEOF
: {
8008 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
8012 u
.val_Int
=new int_val_t(i
);
8015 case OPTYPE_ISVALUE
: {
8016 if(is_unfoldable()) break;
8017 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
8018 && u
.expr
.ti1
->get_Template()->is_Value();
8020 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
8021 is_singleval
= other_val
->evaluate_isvalue(false);
8022 // is_singleval now contains the compile-time result of isvalue
8027 u
.val_bool
= is_singleval
;
8029 case OPTYPE_ISCHOSEN_V
: {
8030 if (is_unfoldable()) break;
8031 v1
= u
.expr
.v1
->get_value_refd_last();
8032 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
8037 case OPTYPE_VALUEOF
: // ti1
8038 if (!u
.expr
.ti1
->get_DerivedRef() &&
8039 u
.expr
.ti1
->get_Template()->is_Value() &&
8040 !u
.expr
.ti1
->get_Type()) {
8041 // FIXME actually if the template instance has a type
8042 // it might still be foldable.
8043 // the argument is a single specific value
8044 v1
= u
.expr
.ti1
->get_Template()->get_Value();
8045 Type
*governor
= my_governor
;
8046 if (governor
== NULL
) {
8047 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
8048 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
8050 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
8051 if (governor
== NULL
)
8052 FATAL_ERROR("Value::evaluate_value()");
8054 valuetype
= v1
->valuetype
;
8056 set_my_governor(governor
);
8057 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
8058 u
.ref
.refd_last
= this;
8059 v1
->valuetype
= V_ERROR
;
8063 case OPTYPE_UNDEF_RUNNING
:
8065 FATAL_ERROR("Value::evaluate_value()");
8069 bool Value::evaluate_isvalue(bool from_sequence
)
8071 switch (valuetype
) {
8073 // Omit is not a value unless a member of a sequence or set
8074 return from_sequence
;
8077 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8078 case V_BOOL
: /**< boolean */
8079 case V_NAMEDINT
: /**< integer / named number */
8080 case V_NAMEDBITS
: /**< named bits (identifiers) */
8081 case V_INT
: /**< integer */
8082 case V_REAL
: /**< real/float */
8083 case V_ENUM
: /**< enumerated */
8084 case V_BSTR
: /**< bitstring */
8085 case V_HSTR
: /**< hexstring */
8086 case V_OSTR
: /**< octetstring */
8087 case V_CSTR
: /**< charstring */
8088 case V_USTR
: /**< universal charstring */
8089 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
8090 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
8091 case V_OID
: /**< object identifier */
8092 case V_ROID
: /**< relative object identifier */
8093 case V_VERDICT
: /**< all verdicts */
8094 return true; // values of built-in types return true
8096 // Code below was adapted from is_unfoldable(), false returned early.
8098 return u
.choice
.alt_value
->evaluate_isvalue(false);
8103 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8104 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
8112 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8113 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8114 ->evaluate_isvalue(true)) return false;
8119 // alas, get_value_refd_last prevents this function from const
8120 return get_value_refd_last()->evaluate_isvalue(false);
8123 switch (u
.expr
.v_optype
) {
8124 // A constant null component reference is a corner case: it is foldable
8125 // but escapes unmodified from evaluate_value.
8126 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8127 // or is transformed into some other valuetype in evaluate_value.
8128 case OPTYPE_COMP_NULL
:
8131 break; // and fall through to the FATAL_ERROR
8135 FATAL_ERROR("Value::evaluate_isvalue()");
8141 void Value::evaluate_macro(Type::expected_value_t exp_val
)
8144 case MACRO_MODULEID
:
8146 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8147 set_val_str(new string(my_scope
->get_scope_mod()
8148 ->get_modid().get_dispname()));
8151 case MACRO_FILENAME
:
8152 case MACRO_BFILENAME
: {
8153 const char *t_filename
= get_filename();
8155 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8156 set_val_str(new string(t_filename
));
8159 case MACRO_FILEPATH
: {
8160 const char *t_filename
= get_filename();
8162 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8163 char *t_filepath
= canonize_input_file(t_filename
);
8165 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8166 set_val_str(new string(t_filepath
));
8170 case MACRO_LINENUMBER
: {
8171 int t_lineno
= get_first_line();
8173 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8174 set_val_str(new string(Int2string(t_lineno
)));
8177 case MACRO_LINENUMBER_C
: {
8178 int t_lineno
= get_first_line();
8180 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8181 u
.val_Int
= new int_val_t(t_lineno
);
8184 case MACRO_DEFINITIONID
: {
8185 // cut the second part from the fullname separated by dots
8186 const string
& t_fullname
= get_fullname();
8187 size_t first_char
= t_fullname
.find('.') + 1;
8188 if (first_char
>= t_fullname
.size())
8189 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8190 t_fullname
.c_str());
8191 set_val_str(new string(t_fullname
.substr(first_char
,
8192 t_fullname
.find('.', first_char
) - first_char
)));
8196 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8197 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8201 case MACRO_TESTCASEID
: {
8202 if (exp_val
== Type::EXPECTED_CONSTANT
||
8203 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8204 error("A %s value was expected instead of macro `%%testcaseId', "
8205 "which is evaluated at runtime",
8206 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8210 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8211 Ttcn::StatementBlock
*my_sb
=
8212 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8214 error("Usage of macro %%testcaseId is allowed only within the "
8215 "statement blocks of functions, altsteps and testcases");
8218 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8220 error("Macro %%testcaseId cannot be used in the control part. "
8221 "It is allowed only within the statement blocks of functions, "
8222 "altsteps and testcases");
8225 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8226 // folding is possible only within testcases
8227 set_val_str(new string(my_def
->get_id().get_dispname()));
8232 FATAL_ERROR("Value::evaluate_macro()");
8236 set_valuetype(V_ERROR
);
8239 void Value::add_id(Identifier
*p_id
)
8243 if(u
.ids
->has_key(p_id
->get_name())) {
8244 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8245 // The Value does not take ownership for the identifier,
8246 // so it must be deleted (add_is acts as a sink).
8249 else u
.ids
->add(p_id
->get_name(), p_id
);
8252 FATAL_ERROR("Value::add_id()");
8256 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8257 Type::expected_value_t exp_val
)
8259 set_lowerid_to_ref();
8260 switch (valuetype
) {
8262 // there might be a better place for this
8263 chk_invoke(exp_val
);
8266 // use the cache if available
8267 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8269 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8271 // the referred definition is not found
8272 set_valuetype(V_ERROR
);
8274 switch (ass
->get_asstype()) {
8275 case Assignment::A_OBJECT
:
8276 case Assignment::A_OS
: {
8277 // the referred definition is an ASN.1 object or object set
8278 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8279 if (!setting
|| setting
->get_st() == S_ERROR
) {
8280 // remain silent, the error has been already reported
8281 set_valuetype(V_ERROR
);
8283 } else if (setting
->get_st() != S_V
) {
8284 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8285 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8286 set_valuetype(V_ERROR
);
8291 refch
->mark_state();
8292 destroy_refch
= false;
8294 refch
= new ReferenceChain(this,
8295 "While searching referenced value");
8296 destroy_refch
= true;
8298 if (refch
->add(get_fullname())) {
8299 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8300 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8301 // in case of circular recursion the valuetype is already set
8302 // to V_ERROR, so don't set the cache
8303 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8305 // a circular recursion was detected
8306 set_valuetype(V_ERROR
);
8308 if (destroy_refch
) delete refch
;
8309 else refch
->prev_state();
8311 case Assignment::A_CONST
: {
8312 // the referred definition is a constant
8315 refch
->mark_state();
8316 destroy_refch
= false;
8318 refch
= new ReferenceChain(this,
8319 "While searching referenced value");
8320 destroy_refch
= true;
8322 if (refch
->add(get_fullname())) {
8323 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8324 Value
*v_refd
= ass
->get_Value()
8325 ->get_refd_sub_value(subrefs
, 0,
8326 u
.ref
.ref
->getUsedInIsbound(), refch
);
8328 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8329 // in case of circular recursion the valuetype is already set
8330 // to V_ERROR, so don't set the cache
8331 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8332 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8333 u
.ref
.refd_last
= this;
8334 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8335 u
.ref
.refd_last
= this;
8337 // the sub-reference points to a non-existent field
8338 set_valuetype(V_ERROR
);
8341 // a circular recursion was detected
8342 set_valuetype(V_ERROR
);
8344 if (destroy_refch
) delete refch
;
8345 else refch
->prev_state();
8347 case Assignment::A_EXT_CONST
:
8348 case Assignment::A_MODULEPAR
:
8349 case Assignment::A_VAR
:
8350 case Assignment::A_FUNCTION_RVAL
:
8351 case Assignment::A_EXT_FUNCTION_RVAL
:
8352 case Assignment::A_PAR_VAL_IN
:
8353 case Assignment::A_PAR_VAL_OUT
:
8354 case Assignment::A_PAR_VAL_INOUT
:
8355 // the referred definition is not a constant
8356 u
.ref
.refd_last
= this;
8358 case Assignment::A_FUNCTION
:
8359 case Assignment::A_EXT_FUNCTION
:
8360 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8361 "call of %s, which does not have return type",
8362 ass
->get_description().c_str());
8363 set_valuetype(V_ERROR
);
8365 case Assignment::A_FUNCTION_RTEMP
:
8366 case Assignment::A_EXT_FUNCTION_RTEMP
:
8367 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8368 "call of %s, which returns a template",
8369 ass
->get_description().c_str());
8370 set_valuetype(V_ERROR
);
8373 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8374 ass
->get_description().c_str());
8375 set_valuetype(V_ERROR
);
8378 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8382 // try to evaluate the expression
8385 refch
->mark_state();
8386 destroy_refch
=false;
8389 refch
=new ReferenceChain(this, "While evaluating expression");
8392 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8393 else set_valuetype(V_ERROR
);
8394 if(destroy_refch
) delete refch
;
8395 else refch
->prev_state();
8398 evaluate_macro(exp_val
);
8401 // return this for all other value types
8406 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8408 /* Note that the logic here needs to be in sync with evaluate_value,
8409 * and possibly others, i.e. if evaluate_value is called for a Value
8410 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8411 bool Value::is_unfoldable(ReferenceChain
*refch
,
8412 Type::expected_value_t exp_val
)
8414 if (UnfoldabilityCheck::is_running(this)) {
8415 // This function is already running on this value => infinite recursion
8419 UnfoldabilityCheck
checker(this);
8421 if (get_needs_conversion()) return true;
8422 switch (valuetype
) {
8426 case V_UNDEF_LOWERID
:
8430 // these value types are eliminated during semantic analysis
8431 FATAL_ERROR("Value::is_unfoldable()");
8436 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8440 if (!is_indexed()) {
8441 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8442 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8446 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8447 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8454 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8455 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8456 ->is_unfoldable(refch
, exp_val
)) return true;
8462 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8463 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8467 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8468 if(v_last
==this) return true; // there weren't any references to chase
8469 else return v_last
->is_unfoldable(refch
, exp_val
);
8472 // classify the unchecked ischosen() operation, if it was not done so far
8473 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8474 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8475 switch (u
.expr
.v_optype
) {
8476 case OPTYPE_RND
: // -
8477 case OPTYPE_COMP_MTC
:
8478 case OPTYPE_COMP_SYSTEM
:
8479 case OPTYPE_COMP_SELF
:
8480 case OPTYPE_COMP_RUNNING_ANY
:
8481 case OPTYPE_COMP_RUNNING_ALL
:
8482 case OPTYPE_COMP_ALIVE_ANY
:
8483 case OPTYPE_COMP_ALIVE_ALL
:
8484 case OPTYPE_TMR_RUNNING_ANY
:
8485 case OPTYPE_GETVERDICT
:
8486 case OPTYPE_TESTCASENAME
:
8487 case OPTYPE_PROF_RUNNING
:
8488 case OPTYPE_RNDWITHVAL
: // v1
8489 case OPTYPE_MATCH
: // v1 t2
8490 case OPTYPE_UNDEF_RUNNING
: // v1
8491 case OPTYPE_COMP_RUNNING
:
8492 case OPTYPE_COMP_ALIVE
:
8493 case OPTYPE_TMR_READ
:
8494 case OPTYPE_TMR_RUNNING
:
8495 case OPTYPE_ACTIVATE
:
8496 case OPTYPE_ACTIVATE_REFD
:
8497 case OPTYPE_EXECUTE
: // r1 [v2]
8498 case OPTYPE_EXECUTE_REFD
:
8499 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8500 case OPTYPE_ISCHOSEN
:
8501 case OPTYPE_ISCHOSEN_T
:
8502 case OPTYPE_SIZEOF
: // ti1
8505 case OPTYPE_OCT2UNICHAR
:
8506 case OPTYPE_UNICHAR2OCT
:
8507 case OPTYPE_ENCODE_BASE64
:
8508 case OPTYPE_DECODE_BASE64
:
8509 case OPTYPE_ENCVALUE_UNICHAR
:
8510 case OPTYPE_DECVALUE_UNICHAR
:
8512 case OPTYPE_COMP_NULL
: // -
8514 case OPTYPE_UNARYPLUS
: // v1
8515 case OPTYPE_UNARYMINUS
:
8518 case OPTYPE_BIT2HEX
:
8519 case OPTYPE_BIT2INT
:
8520 case OPTYPE_BIT2OCT
:
8521 case OPTYPE_BIT2STR
:
8522 case OPTYPE_CHAR2INT
:
8523 case OPTYPE_CHAR2OCT
:
8524 case OPTYPE_FLOAT2INT
:
8525 case OPTYPE_FLOAT2STR
:
8526 case OPTYPE_HEX2BIT
:
8527 case OPTYPE_HEX2INT
:
8528 case OPTYPE_HEX2OCT
:
8529 case OPTYPE_HEX2STR
:
8530 case OPTYPE_INT2CHAR
:
8531 case OPTYPE_INT2FLOAT
:
8532 case OPTYPE_INT2STR
:
8533 case OPTYPE_INT2UNICHAR
:
8534 case OPTYPE_OCT2BIT
:
8535 case OPTYPE_OCT2CHAR
:
8536 case OPTYPE_OCT2HEX
:
8537 case OPTYPE_OCT2INT
:
8538 case OPTYPE_OCT2STR
:
8539 case OPTYPE_STR2BIT
:
8540 case OPTYPE_STR2FLOAT
:
8541 case OPTYPE_STR2HEX
:
8542 case OPTYPE_STR2INT
:
8543 case OPTYPE_STR2OCT
:
8544 case OPTYPE_UNICHAR2INT
:
8545 case OPTYPE_UNICHAR2CHAR
:
8546 case OPTYPE_ENUM2INT
:
8547 case OPTYPE_GET_STRINGENCODING
:
8548 case OPTYPE_REMOVE_BOM
:
8549 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8550 case OPTYPE_ISBOUND
: /*{
8551 //TODO once we have the time for it make isbound foldable.
8552 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8553 Template* temp = u.expr.ti1->get_Template();
8554 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8555 Value* specificValue = temp->get_specific_value();
8556 if (specificValue->get_valuetype() == Value::V_REFD) {
8560 return specificValue->is_unfoldable(refch, exp_val);
8561 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8566 case OPTYPE_ISPRESENT
:
8567 // TODO: "if you have motivation"
8569 case OPTYPE_ISVALUE
: // ti1
8571 case OPTYPE_LENGTHOF
: // ti1
8572 return u
.expr
.ti1
->get_DerivedRef() != 0
8573 || u
.expr
.ti1
->get_Template()->get_templatetype()
8574 != Template::SPECIFIC_VALUE
8575 || u
.expr
.ti1
->get_Template()->get_specific_value()
8576 ->is_unfoldable(refch
, exp_val
);
8580 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8582 case OPTYPE_ADD
: // v1 v2
8583 case OPTYPE_SUBTRACT
:
8584 case OPTYPE_MULTIPLY
:
8600 case OPTYPE_INT2BIT
:
8601 case OPTYPE_INT2HEX
:
8602 case OPTYPE_INT2OCT
:
8603 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8604 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8605 case OPTYPE_AND
: // short-circuit evaluation
8606 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8607 || (u
.expr
.v1
->get_val_bool() &&
8608 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8609 case OPTYPE_OR
: // short-circuit evaluation
8610 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8611 || (!u
.expr
.v1
->get_val_bool() &&
8612 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8614 if (!u
.expr
.ti1
->get_specific_value()) return true;
8615 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8616 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8617 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8618 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8620 if (!u
.expr
.ti1
->get_specific_value() ||
8621 !u
.expr
.t2
->get_specific_value()) return true;
8622 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8623 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8624 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8626 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8627 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8628 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8629 case OPTYPE_REPLACE
: {
8630 if (!u
.expr
.ti1
->get_specific_value() ||
8631 !u
.expr
.ti4
->get_specific_value()) return true;
8632 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8633 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8634 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8635 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8636 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8638 case OPTYPE_VALUEOF
: // ti1
8639 /* \todo if you have motivation to implement the eval function
8642 case OPTYPE_ISCHOSEN_V
:
8643 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8644 case OPTYPE_LOG2STR
:
8645 case OPTYPE_ANY2UNISTR
:
8646 case OPTYPE_TTCN2STRING
:
8649 FATAL_ERROR("Value::is_unfoldable()");
8651 break; // should never get here
8654 case MACRO_TESTCASEID
:
8655 // this is known only at runtime
8661 // all literal values are foldable
8666 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8667 size_t start_i
, bool usedInIsbound
,
8668 ReferenceChain
*refch
)
8670 if (!subrefs
) return this;
8672 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8674 v
= v
->get_value_refd_last(refch
);
8675 switch(v
->valuetype
) {
8684 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8685 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8686 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8687 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8692 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8693 bool usedInIsbound
, const Location
& loc
)
8695 if (valuetype
== V_OMIT
) {
8696 loc
.error("Reference to field `%s' of omit value `%s'",
8697 field_id
.get_dispname().c_str(), get_fullname().c_str());
8700 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8701 Type
*t
= my_governor
->get_type_refd_last();
8702 switch (t
->get_typetype()) {
8706 case Type::T_CHOICE_A
:
8707 case Type::T_CHOICE_T
:
8708 case Type::T_OPENTYPE
:
8709 case Type::T_ANYTYPE
:
8710 if (!t
->has_comp_withName(field_id
)) {
8711 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8712 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8714 } else if (valuetype
!= V_CHOICE
) {
8715 // remain silent, the error is already reported
8717 } else if (*u
.choice
.alt_name
== field_id
) {
8719 return u
.choice
.alt_value
;
8721 if (!usedInIsbound
) {
8722 loc
.error("Reference to inactive field `%s' in a value of union type "
8723 "`%s'. The active field is `%s'",
8724 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8725 u
.choice
.alt_name
->get_dispname().c_str());
8731 if (!t
->has_comp_withName(field_id
)) {
8732 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8733 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8735 } else if (valuetype
!= V_SEQ
) {
8736 // remain silent, the error has been already reported
8741 if (!t
->has_comp_withName(field_id
)) {
8742 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8743 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8745 } else if (valuetype
!= V_SET
) {
8746 // remain silent, the error has been already reported
8750 loc
.error("Invalid field reference `%s': type `%s' "
8751 "does not have fields", field_id
.get_dispname().c_str(),
8752 t
->get_typename().c_str());
8755 // the common end for record & set types
8756 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8758 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8759 } else if (!is_asn1()) {
8760 if (!usedInIsbound
) {
8761 loc
.error("Reference to unbound field `%s'",
8762 field_id
.get_dispname().c_str());
8763 // this is an error in TTCN-3, which has been already reported
8767 CompField
*cf
= t
->get_comp_byName(field_id
);
8768 if (cf
->get_is_optional()) {
8769 // creating an explicit omit value
8770 Value
*v
= new Value(V_OMIT
);
8771 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8772 v
->set_my_scope(get_my_scope());
8773 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8775 } else if (cf
->has_default()) {
8776 // returning the component's default value
8777 return cf
->get_defval();
8779 // this is an error in ASN.1, which has been already reported
8785 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8786 ReferenceChain
*refch
)
8788 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8790 bool index_available
= false;
8791 if (!v_index
->is_unfoldable()) {
8792 if (v_index
->valuetype
== V_INT
) {
8793 index
= v_index
->get_val_Int()->get_val();
8794 index_available
= true;
8796 array_index
->error("An integer value was expected as index");
8799 if (valuetype
== V_OMIT
) {
8800 array_index
->error("Accessing an element with index of omit value `%s'",
8801 get_fullname().c_str());
8804 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8805 Type
*t
= my_governor
->get_type_refd_last();
8806 switch (t
->get_typetype()) {
8811 if (index_available
) {
8813 array_index
->error("A non-negative integer value was expected "
8814 "instead of %s for indexing a value of `record "
8815 "of' type `%s'", Int2string(index
).c_str(),
8816 t
->get_typename().c_str());
8819 switch (valuetype
) {
8821 if (!is_indexed()) {
8822 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8823 if (!usedInIsbound
) {
8824 array_index
->error("Index overflow in a value of `record of' "
8825 "type `%s': the index is %s, but the value "
8826 "has only %lu elements",
8827 t
->get_typename().c_str(),
8828 Int2string(index
).c_str(),
8829 (unsigned long)u
.val_vs
->get_nof_vs());
8833 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8834 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8835 temp
->error("Not used symbol is not allowed in this context");
8836 return u
.val_vs
->get_v_byIndex(index
);
8839 // Search the appropriate constant index.
8840 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8841 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8842 ->get_value_refd_last();
8843 if (iv_index
->get_valuetype() != V_INT
) continue;
8844 if (iv_index
->get_val_Int()->get_val() == index
)
8845 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8851 // remain silent, the error has been already reported
8855 // the error has been reported above
8859 if (index_available
) {
8861 array_index
->error("A non-negative integer value was expected "
8862 "instead of %s for indexing a value of `set of' type `%s'",
8863 Int2string(index
).c_str(), t
->get_typename().c_str());
8866 switch (valuetype
) {
8868 if (!is_indexed()) {
8869 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8870 if (!usedInIsbound
) {
8871 array_index
->error("Index overflow in a value of `set of' type "
8872 "`%s': the index is %s, but the value has "
8873 "only %lu elements",
8874 t
->get_typename().c_str(),
8875 Int2string(index
).c_str(),
8876 (unsigned long)u
.val_vs
->get_nof_vs());
8880 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8881 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8882 temp
->error("Not used symbol is not allowed in this context");
8886 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8887 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8888 ->get_value_refd_last();
8889 if (iv_index
->get_valuetype() != V_INT
) continue;
8890 if (iv_index
->get_val_Int()->get_val() == index
)
8891 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8897 // remain silent, the error has been already reported
8901 // the error has been reported above
8905 if (index_available
) {
8906 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8907 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8908 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8909 // perform the index transformation
8910 index
-= dim
->get_offset();
8911 if (!is_indexed()) {
8912 // check for index underflow/overflow or too few elements in the
8915 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8917 else return u
.val_vs
->get_v_byIndex(index
);
8919 if (index
< 0) return 0;
8920 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8921 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8922 ->get_value_refd_last();
8923 if (iv_index
->get_valuetype() != V_INT
) continue;
8924 if (iv_index
->get_val_Int()->get_val() == index
)
8925 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8930 // remain silent, the error has been already reported
8934 // the error has been reported above
8938 case Type::T_BSTR_A
:
8943 case Type::T_UTF8STRING
:
8944 case Type::T_NUMERICSTRING
:
8945 case Type::T_PRINTABLESTRING
:
8946 case Type::T_TELETEXSTRING
:
8947 case Type::T_VIDEOTEXSTRING
:
8948 case Type::T_IA5STRING
:
8949 case Type::T_GRAPHICSTRING
:
8950 case Type::T_VISIBLESTRING
:
8951 case Type::T_GENERALSTRING
:
8952 case Type::T_UNIVERSALSTRING
:
8953 case Type::T_BMPSTRING
:
8954 case Type::T_UTCTIME
:
8955 case Type::T_GENERALIZEDTIME
:
8956 case Type::T_OBJECTDESCRIPTOR
:
8957 if (index_available
) return get_string_element(index
, *array_index
);
8960 array_index
->error("Invalid array element reference: type `%s' cannot "
8961 "be indexed", t
->get_typename().c_str());
8966 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8969 loc
.error("A non-negative integer value was expected instead of %s "
8970 "for indexing a string element", Int2string(index
).c_str());
8973 size_t string_length
;
8974 switch (valuetype
) {
8979 string_length
= u
.str
.val_str
->size();
8982 string_length
= u
.str
.val_str
->size() / 2;
8985 string_length
= u
.ustr
.val_ustr
->size();
8988 // remain silent, the error has been already reported
8991 if (index
>= static_cast<Int
>(string_length
)) {
8992 loc
.error("Index overflow when accessing a string element: "
8993 "the index is %s, but the string has only %lu elements",
8994 Int2string(index
).c_str(), (unsigned long) string_length
);
8997 switch (valuetype
) {
9002 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
9003 return (*u
.str
.str_elements
)[index
];
9005 Value
*t_val
= new Value(valuetype
,
9006 new string(u
.str
.val_str
->substr(index
, 1)));
9007 add_string_element(index
, t_val
, u
.str
.str_elements
);
9011 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
9012 return (*u
.str
.str_elements
)[index
];
9014 Value
*t_val
= new Value(V_OSTR
,
9015 new string(u
.str
.val_str
->substr(2 * index
, 2)));
9016 add_string_element(index
, t_val
, u
.str
.str_elements
);
9020 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
9021 return (*u
.ustr
.ustr_elements
)[index
];
9023 Value
*t_val
= new Value(V_USTR
,
9024 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
9025 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
9029 FATAL_ERROR("Value::get_string_element()");
9034 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
9035 Type::expected_value_t exp_val
)
9037 set_lowerid_to_ref();
9038 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
9039 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
9041 error("A value or expression of type %s was expected", type_name
);
9042 if (valuetype
== V_REFD
) {
9043 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
9044 t_chk
->chk_this_refd_value(this, 0, exp_val
);
9046 get_value_refd_last(0, exp_val
);
9047 if (error_flag
) set_valuetype(V_ERROR
);
9048 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
9051 int Value::is_parsed_infinity()
9053 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
9055 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
9056 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
9057 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
9062 bool Value::get_val_bool()
9065 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9067 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
9068 return v
->u
.val_bool
;
9071 int_val_t
* Value::get_val_Int()
9074 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9076 switch (v
->valuetype
) {
9079 case V_UNDEF_LOWERID
:
9080 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9081 "`%s'", (*u
.val_id
).get_dispname().c_str());
9083 FATAL_ERROR("Value::get_val_Int()");
9085 return v
->u
.val_Int
;
9088 const Identifier
* Value::get_val_id()
9093 case V_UNDEF_LOWERID
:
9096 FATAL_ERROR("Value::get_val_id()");
9101 const ttcn3float
& Value::get_val_Real()
9104 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9106 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
9107 return v
->u
.val_Real
;
9110 string
Value::get_val_str()
9112 Value
*v
= get_value_refd_last();
9113 switch (v
->valuetype
) {
9118 return *v
->u
.str
.val_str
;
9120 return v
->u
.char_syms
->get_string();
9122 error("Cannot use ISO-10646 string value in string context");
9125 error("Cannot use ISO-2022 string value in string context");
9130 error("Cannot use this value in charstring value context");
9135 ustring
Value::get_val_ustr()
9137 Value
*v
= get_value_refd_last();
9138 switch (v
->valuetype
) {
9140 return ustring(*v
->u
.str
.val_str
);
9142 return *v
->u
.ustr
.val_ustr
;
9144 return v
->u
.char_syms
->get_ustring();
9146 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9151 error("Cannot use this value in ISO-10646 string context");
9156 string
Value::get_val_iso2022str()
9158 Value
*v
= get_value_refd_last();
9159 switch (v
->valuetype
) {
9162 return *v
->u
.str
.val_str
;
9164 return v
->u
.char_syms
->get_iso2022string();
9166 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9171 error("Cannot use this value in ISO-2022 string context");
9176 size_t Value::get_val_strlen()
9178 Value
*v
= get_value_refd_last();
9179 switch (v
->valuetype
) {
9184 return v
->u
.str
.val_str
->size();
9186 return v
->u
.str
.val_str
->size()/2;
9188 return v
->u
.char_syms
->get_len();
9190 return v
->u
.ustr
.val_ustr
->size();
9194 error("Cannot use this value in string value context");
9199 Value::verdict_t
Value::get_val_verdict()
9205 FATAL_ERROR("Value::get_val_verdict()");
9210 size_t Value::get_nof_comps()
9212 switch (valuetype
) {
9216 return u
.oid_comps
->size();
9220 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9221 else return u
.val_vs
->get_nof_vs();
9224 return u
.val_nvs
->get_nof_nvs();
9229 return u
.str
.val_str
->size();
9231 return u
.str
.val_str
->size()/2;
9233 return u
.ustr
.val_ustr
->size();
9235 FATAL_ERROR("Value::get_nof_comps()");
9240 bool Value::is_indexed() const
9242 switch (valuetype
) {
9246 // Applicable only for list-types. Assigning a record/SEQUENCE or
9247 // set/SET with indexed notation is not supported.
9248 return u
.val_vs
->is_indexed();
9250 FATAL_ERROR("Value::is_indexed()");
9256 const Identifier
& Value::get_alt_name()
9258 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9259 return *u
.choice
.alt_name
;
9262 Value
*Value::get_alt_value()
9264 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9265 return u
.choice
.alt_value
;
9268 void Value::set_alt_name_to_lowercase()
9270 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9271 string new_name
= u
.choice
.alt_name
->get_name();
9272 if (isupper(new_name
[0])) {
9273 new_name
[0] = tolower(new_name
[0]);
9274 if (new_name
[new_name
.size() - 1] == '_') {
9275 // an underscore is inserted at the end of the alternative name if it's
9276 // a basic type's name (since it would conflict with the class generated
9278 // remove the underscore, it won't conflict with anything if its name
9279 // starts with a lowercase letter
9280 new_name
.replace(new_name
.size() - 1, 1, "");
9282 delete u
.choice
.alt_name
;
9283 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9287 bool Value::has_oid_error()
9290 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9292 switch (valuetype
) {
9295 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9296 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9303 bool Value::get_oid_comps(vector
<string
>& comps
)
9305 bool ret_val
= true;
9307 switch (valuetype
) {
9309 v
= get_value_refd_last();
9313 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9314 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9315 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9316 // not all components can be calculated in compile-time
9322 FATAL_ERROR("Value::get_oid_comps()");
9327 void Value::add_se_comp(NamedValue
* nv
) {
9328 switch (valuetype
) {
9332 u
.val_nvs
= new NamedValues();
9333 u
.val_nvs
->add_nv(nv
);
9336 FATAL_ERROR("Value::add_se_comp()");
9340 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9345 return u
.val_nvs
->get_nv_byIndex(n
);
9347 FATAL_ERROR("Value::get_se_comp_byIndex()");
9352 Value
*Value::get_comp_byIndex(size_t n
)
9354 switch (valuetype
) {
9358 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9359 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9361 FATAL_ERROR("Value::get_comp_byIndex()");
9366 Value
*Value::get_index_byIndex(size_t n
)
9368 switch (valuetype
) {
9372 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9373 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9375 FATAL_ERROR("Value::get_index_byIndex()");
9380 bool Value::has_comp_withName(const Identifier
& p_name
)
9385 return u
.val_nvs
->has_nv_withName(p_name
);
9387 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9389 FATAL_ERROR("Value::get_has_comp_withName()");
9394 bool Value::field_is_chosen(const Identifier
& p_name
)
9396 Value
*v
=get_value_refd_last();
9397 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9398 return *v
->u
.choice
.alt_name
==p_name
;
9401 bool Value::field_is_present(const Identifier
& p_name
)
9403 Value
*v
=get_value_refd_last();
9404 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9405 FATAL_ERROR("Value::field_is_present()");
9406 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9407 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9408 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9411 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9416 return u
.val_nvs
->get_nv_byName(p_name
);
9418 FATAL_ERROR("Value::get_se_comp_byName()");
9423 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9428 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9430 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9431 return u
.choice
.alt_value
;
9435 FATAL_ERROR("Value::get_se_comp_byName()");
9440 void Value::chk_dupl_id()
9445 u
.val_nvs
->chk_dupl_id();
9448 FATAL_ERROR("Value::chk_dupl_id()");
9452 size_t Value::get_nof_ids() const
9456 return u
.ids
->size();
9459 FATAL_ERROR("Value::get_nof_ids()");
9464 Identifier
* Value::get_id_byIndex(size_t p_i
)
9468 return u
.ids
->get_nth_elem(p_i
);
9471 FATAL_ERROR("Value::get_id_byIndex()");
9476 bool Value::has_id(const Identifier
& p_id
)
9480 return u
.ids
->has_key(p_id
.get_name());
9483 FATAL_ERROR("Value::has_id()");
9488 Reference
*Value::get_reference() const
9490 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9494 Reference
*Value::get_refered() const
9496 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9500 Common::Assignment
*Value::get_refd_fat() const
9508 FATAL_ERROR("Value::get_refd_fat()");
9512 Ttcn::Reference
* Value::steal_ttcn_ref()
9514 Ttcn::Reference
*ret_val
=
9515 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9516 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9520 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9522 Ttcn::Ref_base
*t_ref
;
9523 if(valuetype
==V_REFD
) {
9524 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9525 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9528 else if(valuetype
==V_UNDEF_LOWERID
) {
9529 t_ref
=new Ttcn::Reference(u
.val_id
);
9530 t_ref
->set_location(*this);
9531 t_ref
->set_fullname(get_fullname());
9532 t_ref
->set_my_scope(get_my_scope());
9536 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9539 set_valuetype(V_ERROR
);
9543 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9544 Ttcn::ActualParList
*& p_ap
)
9546 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9549 p_ti
= u
.invoke
.t_list
;
9550 u
.invoke
.t_list
= 0;
9551 p_ap
= u
.invoke
.ap_list
;
9552 u
.invoke
.ap_list
= 0;
9553 set_valuetype(V_ERROR
);
9556 Common::Assignment
* Value::get_refd_assignment()
9565 FATAL_ERROR("Value::get_refd_assignment()");
9575 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9580 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9589 void Value::chk_OID(ReferenceChain
& refch
)
9591 if (checked
) return;
9592 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9593 FATAL_ERROR("Value::chk_OID()");
9594 if (!refch
.add(get_fullname())) {
9598 OID_comp::oidstate_t state
= OID_comp::START
;
9599 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9601 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9604 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9605 error("An OBJECT IDENTIFIER value must have at least "
9606 "two components"); // X.680 (07/2002) 31.10
9609 void Value::chk_ROID(ReferenceChain
& refch
)
9611 if (checked
) return;
9612 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9613 FATAL_ERROR("Value::chk_ROID()");
9614 if (!refch
.add(get_fullname())) {
9618 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9620 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9625 void Value::chk_recursions(ReferenceChain
& refch
)
9627 if (recurs_checked
) return;
9628 Value
*v
= get_value_refd_last();
9629 if (refch
.add(v
->get_fullname())) {
9630 switch (v
->valuetype
) {
9632 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9637 if (!v
->is_indexed()) {
9638 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9640 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9644 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9646 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9647 ->chk_recursions(refch
);
9654 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9656 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9661 chk_recursions_expr(refch
);
9666 if (v
->err_descr
) { // FIXME: make this work
9667 v
->err_descr
->chk_recursions(refch
);
9670 recurs_checked
= true;
9673 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9675 // first classify the unchecked ischosen() operation
9676 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9677 switch (u
.expr
.v_optype
) {
9678 case OPTYPE_UNARYPLUS
: // v1
9679 case OPTYPE_UNARYMINUS
:
9682 case OPTYPE_BIT2HEX
:
9683 case OPTYPE_BIT2INT
:
9684 case OPTYPE_BIT2OCT
:
9685 case OPTYPE_BIT2STR
:
9686 case OPTYPE_CHAR2INT
:
9687 case OPTYPE_CHAR2OCT
:
9688 case OPTYPE_FLOAT2INT
:
9689 case OPTYPE_FLOAT2STR
:
9690 case OPTYPE_HEX2BIT
:
9691 case OPTYPE_HEX2INT
:
9692 case OPTYPE_HEX2OCT
:
9693 case OPTYPE_HEX2STR
:
9694 case OPTYPE_INT2CHAR
:
9695 case OPTYPE_INT2FLOAT
:
9696 case OPTYPE_INT2STR
:
9697 case OPTYPE_INT2UNICHAR
:
9698 case OPTYPE_OCT2BIT
:
9699 case OPTYPE_OCT2CHAR
:
9700 case OPTYPE_OCT2HEX
:
9701 case OPTYPE_OCT2INT
:
9702 case OPTYPE_OCT2STR
:
9703 case OPTYPE_STR2BIT
:
9704 case OPTYPE_STR2FLOAT
:
9705 case OPTYPE_STR2HEX
:
9706 case OPTYPE_STR2INT
:
9707 case OPTYPE_STR2OCT
:
9708 case OPTYPE_UNICHAR2INT
:
9709 case OPTYPE_ENUM2INT
:
9710 case OPTYPE_UNICHAR2CHAR
:
9711 case OPTYPE_RNDWITHVAL
:
9712 case OPTYPE_ISCHOSEN_V
:
9713 case OPTYPE_GET_STRINGENCODING
:
9714 case OPTYPE_REMOVE_BOM
:
9715 case OPTYPE_DECODE_BASE64
:
9717 u
.expr
.v1
->chk_recursions(refch
);
9720 case OPTYPE_ISCHOSEN_T
:
9722 u
.expr
.t1
->chk_recursions(refch
);
9725 case OPTYPE_ADD
: // v1 v2
9726 case OPTYPE_SUBTRACT
:
9727 case OPTYPE_MULTIPLY
:
9748 case OPTYPE_INT2BIT
:
9749 case OPTYPE_INT2HEX
:
9750 case OPTYPE_INT2OCT
:
9752 u
.expr
.v1
->chk_recursions(refch
);
9755 u
.expr
.v2
->chk_recursions(refch
);
9758 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9759 case OPTYPE_OCT2UNICHAR
:
9760 case OPTYPE_ENCODE_BASE64
:
9762 u
.expr
.v1
->chk_recursions(refch
);
9766 u
.expr
.v2
->chk_recursions(refch
);
9771 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9772 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9776 u
.expr
.ti1
->chk_recursions(refch
);
9779 u
.expr
.v2
->chk_recursions(refch
);
9782 u
.expr
.v3
->chk_recursions(refch
);
9787 u
.expr
.ti1
->chk_recursions(refch
);
9790 u
.expr
.t2
->chk_recursions(refch
);
9793 u
.expr
.v3
->chk_recursions(refch
);
9796 case OPTYPE_DECOMP
: // v1 v2 v3
9798 u
.expr
.v1
->chk_recursions(refch
);
9801 u
.expr
.v2
->chk_recursions(refch
);
9804 u
.expr
.v3
->chk_recursions(refch
);
9807 case OPTYPE_REPLACE
:
9809 u
.expr
.ti1
->chk_recursions(refch
);
9812 u
.expr
.v2
->chk_recursions(refch
);
9815 u
.expr
.v3
->chk_recursions(refch
);
9818 u
.expr
.ti4
->chk_recursions(refch
);
9821 case OPTYPE_LENGTHOF
: // ti1
9822 case OPTYPE_SIZEOF
: // ti1
9823 case OPTYPE_VALUEOF
: // ti1
9825 case OPTYPE_ISPRESENT
:
9826 case OPTYPE_TTCN2STRING
:
9828 u
.expr
.ti1
->chk_recursions(refch
);
9831 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
9833 u
.expr
.ti1
->chk_recursions(refch
);
9837 u
.expr
.v2
->chk_recursions(refch
);
9841 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
9842 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9843 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9846 u
.expr
.v3
->chk_recursions(refch
);
9850 case OPTYPE_MATCH
: // v1 t2
9852 u
.expr
.v1
->chk_recursions(refch
);
9855 u
.expr
.t2
->chk_recursions(refch
);
9858 case OPTYPE_LOG2STR
:
9859 case OPTYPE_ANY2UNISTR
:
9860 u
.expr
.logargs
->chk_recursions(refch
);
9867 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9868 ReferenceChain
& refch
) {
9869 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9870 Assignment
*ass
= ref
->get_refd_assignment();
9872 set_valuetype(V_ERROR
);
9875 switch (ass
->get_asstype()) {
9876 case Assignment::A_CONST
:
9877 case Assignment::A_EXT_CONST
:
9878 case Assignment::A_MODULEPAR
:
9879 case Assignment::A_VAR
:
9880 case Assignment::A_PAR_VAL_IN
:
9881 case Assignment::A_PAR_VAL_OUT
:
9882 case Assignment::A_PAR_VAL_INOUT
: {
9883 Value
* v
= new Value(V_REFD
, ref
);
9884 v
->set_location(*ref
);
9885 v
->set_my_scope(get_my_scope());
9886 v
->set_fullname(get_fullname()+".<operand>");
9888 v
->chk_recursions(refch
);
9892 case Assignment::A_MODULEPAR_TEMP
:
9893 case Assignment::A_TEMPLATE
:
9894 case Assignment::A_VAR_TEMPLATE
:
9895 case Assignment::A_PAR_TEMPL_IN
:
9896 case Assignment::A_PAR_TEMPL_OUT
:
9897 case Assignment::A_PAR_TEMPL_INOUT
: {
9898 Template
* t
= new Template(ref
->clone());
9899 t
->set_location(*ref
);
9900 t
->set_my_scope(get_my_scope());
9901 t
->set_fullname(get_fullname()+".<operand>");
9903 t
->chk_recursions(refch
);
9908 // remain silent, the error has been already reported
9909 set_valuetype(V_ERROR
);
9914 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9916 bool self_ref
= false;
9917 switch (t
->get_templatetype()) {
9918 case Ttcn::Template::SPECIFIC_VALUE
: {
9919 Value
*v
= t
->get_specific_value();
9920 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9921 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9922 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9924 case Ttcn::Template::TEMPLATE_REFD
: {
9925 Ttcn::Ref_base
*refb
= t
->get_reference();
9926 Common::Assignment
*ass
= refb
->get_refd_assignment();
9927 self_ref
|= (ass
== lhs
);
9929 case Ttcn::Template::ALL_FROM
:
9930 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9931 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9933 case Ttcn::Template::TEMPLATE_LIST
:
9934 case Ttcn::Template::SUPERSET_MATCH
:
9935 case Ttcn::Template::SUBSET_MATCH
:
9936 case Ttcn::Template::PERMUTATION_MATCH
:
9937 case Ttcn::Template::COMPLEMENTED_LIST
:
9938 case Ttcn::Template::VALUE_LIST
: {
9939 size_t num
= t
->get_nof_comps();
9940 for (size_t i
= 0; i
< num
; ++i
) {
9941 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9944 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9945 // case Ttcn::Template::TEMPLATE_LIST: {
9946 // size_t num = t->get_nof_listitems();
9947 // for (size_t i=0; i < num; ++i) {
9948 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9951 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9952 size_t nnt
= t
->get_nof_comps();
9953 for (size_t i
=0; i
< nnt
; ++i
) {
9954 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9955 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9958 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9959 size_t nnt
= t
->get_nof_comps();
9960 for (size_t i
=0; i
< nnt
; ++i
) {
9961 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9962 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9965 case Ttcn::Template::VALUE_RANGE
: {
9966 Ttcn::ValueRange
*vr
= t
->get_value_range();
9967 Common::Value
*v
= vr
->get_min_v();
9968 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9969 v
= vr
->get_max_v();
9970 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9972 case Ttcn::Template::CSTR_PATTERN
:
9973 case Ttcn::Template::USTR_PATTERN
: {
9974 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9975 self_ref
|= ps
->chk_self_ref(lhs
);
9977 case Ttcn::Template::BSTR_PATTERN
:
9978 case Ttcn::Template::HSTR_PATTERN
:
9979 case Ttcn::Template::OSTR_PATTERN
: {
9980 // FIXME: cannot access u.pattern
9982 case Ttcn::Template::ANY_VALUE
:
9983 case Ttcn::Template::ANY_OR_OMIT
:
9984 case Ttcn::Template::OMIT_VALUE
:
9985 case Ttcn::Template::TEMPLATE_NOTUSED
:
9986 break; // self-ref can't happen
9987 case Ttcn::Template::TEMPLATE_INVOKE
:
9988 break; // assume self-ref can't happen
9989 case Ttcn::Template::TEMPLATE_ERROR
:
9990 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9993 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9994 // break; // and hope for the best
9999 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
10001 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
10002 namedbool is_str_elem
= NOT_STR_ELEM
;
10003 if (v
->valuetype
== V_REFD
) {
10004 Reference
*ref
= v
->get_reference();
10005 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
10006 if (subrefs
&& subrefs
->refers_to_string_element()) {
10007 is_str_elem
= IS_STR_ELEM
;
10010 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
10011 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
10015 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
10017 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
10018 if (!lhs
) FATAL_ERROR("no lhs!");
10019 bool self_ref
= false;
10020 switch (u
.expr
.v_optype
) {
10021 case OPTYPE_RND
: // -
10022 case OPTYPE_TESTCASENAME
: // -
10023 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
10024 case OPTYPE_COMP_MTC
: // -
10025 case OPTYPE_COMP_SYSTEM
: // -
10026 case OPTYPE_COMP_SELF
: // -
10027 case OPTYPE_COMP_RUNNING_ANY
: // -
10028 case OPTYPE_COMP_RUNNING_ALL
: // -
10029 case OPTYPE_COMP_ALIVE_ANY
: // -
10030 case OPTYPE_COMP_ALIVE_ALL
: // -
10031 case OPTYPE_TMR_RUNNING_ANY
: // -
10032 case OPTYPE_GETVERDICT
: // -
10033 case OPTYPE_PROF_RUNNING
: // -
10034 break; // nothing to do
10036 case OPTYPE_MATCH
: // v1 t2
10037 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10039 case OPTYPE_UNARYPLUS
: // v1
10040 case OPTYPE_UNARYMINUS
: // v1
10041 case OPTYPE_NOT
: // v1
10042 case OPTYPE_NOT4B
: // v1
10043 case OPTYPE_BIT2HEX
: // v1
10044 case OPTYPE_BIT2INT
: // v1
10045 case OPTYPE_BIT2OCT
: // v1
10046 case OPTYPE_BIT2STR
: // v1
10047 case OPTYPE_CHAR2INT
: // v1
10048 case OPTYPE_CHAR2OCT
: // v1
10049 case OPTYPE_FLOAT2INT
: // v1
10050 case OPTYPE_FLOAT2STR
: // v1
10051 case OPTYPE_HEX2BIT
: // v1
10052 case OPTYPE_HEX2INT
: // v1
10053 case OPTYPE_HEX2OCT
: // v1
10054 case OPTYPE_HEX2STR
: // v1
10055 case OPTYPE_INT2CHAR
: // v1
10056 case OPTYPE_INT2FLOAT
: // v1
10057 case OPTYPE_INT2STR
: // v1
10058 case OPTYPE_INT2UNICHAR
: // v1
10059 case OPTYPE_OCT2BIT
: // v1
10060 case OPTYPE_OCT2CHAR
: // v1
10061 case OPTYPE_OCT2HEX
: // v1
10062 case OPTYPE_OCT2INT
: // v1
10063 case OPTYPE_OCT2STR
: // v1
10064 case OPTYPE_STR2BIT
: // v1
10065 case OPTYPE_STR2FLOAT
: // v1
10066 case OPTYPE_STR2HEX
: // v1
10067 case OPTYPE_STR2INT
: // v1
10068 case OPTYPE_STR2OCT
: // v1
10069 case OPTYPE_UNICHAR2INT
: // v1
10070 case OPTYPE_UNICHAR2CHAR
: // v1
10071 case OPTYPE_ENUM2INT
: // v1
10072 case OPTYPE_RNDWITHVAL
: // v1
10073 case OPTYPE_COMP_RUNNING
: // v1
10074 case OPTYPE_COMP_ALIVE
: // v1
10075 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
10076 case OPTYPE_GET_STRINGENCODING
:
10077 case OPTYPE_DECODE_BASE64
:
10078 case OPTYPE_REMOVE_BOM
:
10079 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10081 case OPTYPE_ADD
: // v1 v2
10082 case OPTYPE_SUBTRACT
: // v1 v2
10083 case OPTYPE_MULTIPLY
: // v1 v2
10084 case OPTYPE_DIVIDE
: // v1 v2
10085 case OPTYPE_MOD
: // v1 v2
10086 case OPTYPE_REM
: // v1 v2
10087 case OPTYPE_CONCAT
: // v1 v2
10088 case OPTYPE_EQ
: // v1 v2
10089 case OPTYPE_LT
: // v1 v2
10090 case OPTYPE_GT
: // v1 v2
10091 case OPTYPE_NE
: // v1 v2
10092 case OPTYPE_GE
: // v1 v2
10093 case OPTYPE_LE
: // v1 v2
10094 case OPTYPE_AND
: // v1 v2
10095 case OPTYPE_OR
: // v1 v2
10096 case OPTYPE_XOR
: // v1 v2
10097 case OPTYPE_AND4B
: // v1 v2
10098 case OPTYPE_OR4B
: // v1 v2
10099 case OPTYPE_XOR4B
: // v1 v2
10100 case OPTYPE_SHL
: // v1 v2
10101 case OPTYPE_SHR
: // v1 v2
10102 case OPTYPE_ROTL
: // v1 v2
10103 case OPTYPE_ROTR
: // v1 v2
10104 case OPTYPE_INT2BIT
: // v1 v2
10105 case OPTYPE_INT2HEX
: // v1 v2
10106 case OPTYPE_INT2OCT
: // v1 v2
10107 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10108 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10110 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
10111 case OPTYPE_OCT2UNICHAR
:
10112 case OPTYPE_ENCODE_BASE64
:
10113 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10114 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10116 case OPTYPE_DECOMP
: // v1 v2 v3
10117 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10118 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10119 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10122 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
10123 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
10125 case OPTYPE_SUBSTR
: // ti1 v2 v3
10126 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10127 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
10128 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
10131 case OPTYPE_REGEXP
: // ti1 t2 v3
10132 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10133 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10135 case OPTYPE_LENGTHOF
: // ti1
10136 case OPTYPE_SIZEOF
: // ti1
10137 case OPTYPE_VALUEOF
: // ti1
10138 case OPTYPE_ENCODE
: // ti1
10139 case OPTYPE_TTCN2STRING
:
10140 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10142 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
10143 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10144 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10146 case OPTYPE_DECVALUE_UNICHAR
: { // r1 r2 [v3]
10147 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10148 self_ref
|= (ass
== lhs
);
10149 if (u
.expr
.v3
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10152 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
10153 // component.create -- assume no self-ref
10154 case OPTYPE_ACTIVATE
: // r1
10155 // defaultref := activate(altstep) -- assume no self-ref
10156 case OPTYPE_TMR_RUNNING
: // r1
10157 // boolvar := a_timer.running -- assume no self-ref
10161 case OPTYPE_ANY2UNISTR
:
10162 case OPTYPE_LOG2STR
: {// logargs
10163 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
10164 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
10165 switch (la
->get_type()) {
10166 case Ttcn::LogArgument::L_UNDEF
:
10167 case Ttcn::LogArgument::L_ERROR
:
10168 FATAL_ERROR("%s argument type",
10169 u
.expr
.v_optype
== OPTYPE_ANY2UNISTR
? "any2unistr" : "log2str");
10170 break; // not reached
10172 case Ttcn::LogArgument::L_MACRO
:
10173 case Ttcn::LogArgument::L_STR
:
10174 break; // self reference not possible
10176 case Ttcn::LogArgument::L_VAL
:
10177 case Ttcn::LogArgument::L_MATCH
:
10178 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
10181 case Ttcn::LogArgument::L_REF
: {
10182 Ttcn::Ref_base
*ref
= la
->get_ref();
10183 Common::Assignment
*ass
= ref
->get_refd_assignment();
10184 self_ref
|= (ass
== lhs
);
10187 case Ttcn::LogArgument::L_TI
: {
10188 Ttcn::TemplateInstance
*ti
= la
->get_ti();
10189 Ttcn::Template
*t
= ti
->get_Template();
10190 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10193 // no default please
10194 } // switch la->logargtype
10198 case OPTYPE_DECODE
: { // r1 r2
10199 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10200 self_ref
|= (ass
== lhs
);
10202 case OPTYPE_EXECUTE
: // r1 [v2]
10204 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10208 case OPTYPE_UNDEF_RUNNING
: // r1
10209 case OPTYPE_TMR_READ
: { // r1
10210 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
10211 self_ref
|= (ass
== lhs
);
10214 case OPTYPE_ISCHOSEN_T
: // t1 i2
10215 case OPTYPE_ISBOUND
: // ti1
10216 case OPTYPE_ISVALUE
: // ti1
10217 case OPTYPE_ISPRESENT
: { // ti1
10219 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10220 else t
= u
.expr
.ti1
->get_Template();
10221 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10224 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10226 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10229 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10230 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10234 case NUMBER_OF_OPTYPES
: // can never happen
10235 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10236 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10238 } // switch u.expr.v_optype
10243 string
Value::create_stringRepr()
10245 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10246 switch (valuetype
) {
10248 return string("<erroneous>");
10250 return string("NULL");
10252 if (!parse_only
&& is_asn1()) {
10253 if (u
.val_bool
) return string("TRUE");
10254 else return string("FALSE");
10257 if (u
.val_bool
) return string("true");
10258 else return string("false");
10261 return u
.val_Int
->t_str();
10263 return Real2string(u
.val_Real
);
10266 case V_UNDEF_LOWERID
:
10267 return u
.val_id
->get_name();
10268 case V_NAMEDBITS
: {
10269 string
ret_val("{ ");
10270 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10271 if (i
>0) ret_val
+= ' ';
10272 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10277 string
ret_val('\'');
10278 ret_val
+= *u
.str
.val_str
;
10282 string
ret_val('\'');
10283 ret_val
+= *u
.str
.val_str
;
10287 string
ret_val('\'');
10288 ret_val
+= *u
.str
.val_str
;
10293 return u
.str
.val_str
->get_stringRepr();
10295 return u
.ustr
.val_ustr
->get_stringRepr();
10297 /** \todo stringrepr of V_CHARSYMS */
10298 return string("<sorry, string representation of charsyms "
10299 "not implemented>");
10303 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10305 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10306 if (i
>0) ret_val
+= ' ';
10307 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10312 if (!parse_only
&& is_asn1()) {
10313 string
ret_val(u
.choice
.alt_name
->get_dispname());
10315 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10319 string
ret_val("{ ");
10320 ret_val
+= u
.choice
.alt_name
->get_dispname();
10322 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10329 string
ret_val("{ ");
10330 if (!is_indexed()) {
10331 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10332 if (i
> 0) ret_val
+= ", ";
10333 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10336 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10337 if (i
> 0) ret_val
+= ", ";
10338 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10345 string
ret_val("{ ");
10346 bool asn1_flag
= !parse_only
&& is_asn1();
10347 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10348 if (i
> 0) ret_val
+= ", ";
10349 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10350 ret_val
+= nv
->get_name().get_dispname();
10351 if (asn1_flag
) ret_val
+= ' ';
10352 else ret_val
+= " := ";
10353 ret_val
+= nv
->get_value()->get_stringRepr();
10358 // do not evaluate the reference if it is not done so far
10359 // (e.g. in parse-only mode)
10360 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10361 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10362 else return t_val
->get_stringRepr(); }
10364 return string("omit");
10366 switch (u
.verdict
) {
10368 return string("none");
10370 return string("pass");
10371 case Verdict_INCONC
:
10372 return string("inconc");
10374 return string("fail");
10375 case Verdict_ERROR
:
10376 return string("error");
10378 return string("<unknown verdict value>");
10380 case V_DEFAULT_NULL
:
10382 return string("null");
10384 switch (u
.expr
.v_optype
) {
10386 return string("rnd()");
10387 case OPTYPE_TESTCASENAME
:
10388 return string("testcasename()");
10389 case OPTYPE_UNARYPLUS
:
10390 return create_stringRepr_unary("+");
10391 case OPTYPE_UNARYMINUS
:
10392 return create_stringRepr_unary("-");
10394 return create_stringRepr_unary("not");
10396 return create_stringRepr_unary("not4b");
10397 case OPTYPE_BIT2HEX
:
10398 return create_stringRepr_predef1("bit2hex");
10399 case OPTYPE_BIT2INT
:
10400 return create_stringRepr_predef1("bit2int");
10401 case OPTYPE_BIT2OCT
:
10402 return create_stringRepr_predef1("bit2oct");
10403 case OPTYPE_BIT2STR
:
10404 return create_stringRepr_predef1("bit2str");
10405 case OPTYPE_CHAR2INT
:
10406 return create_stringRepr_predef1("char2int");
10407 case OPTYPE_CHAR2OCT
:
10408 return create_stringRepr_predef1("char2oct");
10409 case OPTYPE_FLOAT2INT
:
10410 return create_stringRepr_predef1("float2int");
10411 case OPTYPE_FLOAT2STR
:
10412 return create_stringRepr_predef1("float2str");
10413 case OPTYPE_HEX2BIT
:
10414 return create_stringRepr_predef1("hex2bit");
10415 case OPTYPE_HEX2INT
:
10416 return create_stringRepr_predef1("hex2int");
10417 case OPTYPE_HEX2OCT
:
10418 return create_stringRepr_predef1("hex2oct");
10419 case OPTYPE_HEX2STR
:
10420 return create_stringRepr_predef1("hex2str");
10421 case OPTYPE_INT2CHAR
:
10422 return create_stringRepr_predef1("int2char");
10423 case OPTYPE_INT2FLOAT
:
10424 return create_stringRepr_predef1("int2float");
10425 case OPTYPE_INT2STR
:
10426 return create_stringRepr_predef1("int2str");
10427 case OPTYPE_INT2UNICHAR
:
10428 return create_stringRepr_predef1("int2unichar");
10429 case OPTYPE_OCT2BIT
:
10430 return create_stringRepr_predef1("oct2bit");
10431 case OPTYPE_OCT2CHAR
:
10432 return create_stringRepr_predef1("oct2char");
10433 case OPTYPE_OCT2HEX
:
10434 return create_stringRepr_predef1("oct2hex");
10435 case OPTYPE_OCT2INT
:
10436 return create_stringRepr_predef1("oct2int");
10437 case OPTYPE_OCT2STR
:
10438 return create_stringRepr_predef1("oct2str");
10439 case OPTYPE_GET_STRINGENCODING
:
10440 return create_stringRepr_predef1("get_stringencoding");
10441 case OPTYPE_REMOVE_BOM
:
10442 return create_stringRepr_predef1("remove_bom");
10443 case OPTYPE_ENCODE_BASE64
: {
10444 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10445 else return create_stringRepr_predef1("encode_base64");
10447 case OPTYPE_DECODE_BASE64
:
10448 return create_stringRepr_predef1("decode_base64");
10449 case OPTYPE_OCT2UNICHAR
:{
10450 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10451 else return create_stringRepr_predef1("oct2unichar");
10453 case OPTYPE_UNICHAR2OCT
: {
10454 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10455 else return create_stringRepr_predef1("unichar2oct");
10457 case OPTYPE_ENCVALUE_UNICHAR
: {
10458 if (u
.expr
.v2
) return create_stringRepr_predef2("encvalue_unichar");
10459 else return create_stringRepr_predef1("encvalue_unichar");
10461 case OPTYPE_DECVALUE_UNICHAR
: {
10463 string
ret_val("decvalue_unichar");
10465 ret_val
+= u
.expr
.v1
->get_stringRepr();
10467 ret_val
+= u
.expr
.v2
->get_stringRepr();
10469 ret_val
+= u
.expr
.v3
->get_stringRepr();
10473 else return create_stringRepr_predef2("decvalue_unichar");
10475 case OPTYPE_STR2BIT
:
10476 return create_stringRepr_predef1("str2bit");
10477 case OPTYPE_STR2FLOAT
:
10478 return create_stringRepr_predef1("str2float");
10479 case OPTYPE_STR2HEX
:
10480 return create_stringRepr_predef1("str2hex");
10481 case OPTYPE_STR2INT
:
10482 return create_stringRepr_predef1("str2int");
10483 case OPTYPE_STR2OCT
:
10484 return create_stringRepr_predef1("str2oct");
10485 case OPTYPE_UNICHAR2INT
:
10486 return create_stringRepr_predef1("unichar2int");
10487 case OPTYPE_UNICHAR2CHAR
:
10488 return create_stringRepr_predef1("unichar2char");
10489 case OPTYPE_ENUM2INT
:
10490 return create_stringRepr_predef1("enum2int");
10491 case OPTYPE_ENCODE
:
10492 return create_stringRepr_predef1("encvalue");
10493 case OPTYPE_DECODE
:
10494 return create_stringRepr_predef2("decvalue");
10495 case OPTYPE_RNDWITHVAL
:
10496 return create_stringRepr_predef1("rnd");
10498 return create_stringRepr_infix("+");
10499 case OPTYPE_SUBTRACT
:
10500 return create_stringRepr_infix("-");
10501 case OPTYPE_MULTIPLY
:
10502 return create_stringRepr_infix("*");
10503 case OPTYPE_DIVIDE
:
10504 return create_stringRepr_infix("/");
10506 return create_stringRepr_infix("mod");
10508 return create_stringRepr_infix("rem");
10509 case OPTYPE_CONCAT
:
10510 return create_stringRepr_infix("&");
10512 return create_stringRepr_infix("==");
10514 return create_stringRepr_infix("<");
10516 return create_stringRepr_infix(">");
10518 return create_stringRepr_infix("!=");
10520 return create_stringRepr_infix(">=");
10522 return create_stringRepr_infix("<=");
10524 return create_stringRepr_infix("and");
10526 return create_stringRepr_infix("or");
10528 return create_stringRepr_infix("xor");
10530 return create_stringRepr_infix("and4b");
10532 return create_stringRepr_infix("or4b");
10534 return create_stringRepr_infix("xor4b");
10536 return create_stringRepr_infix("<<");
10538 return create_stringRepr_infix(">>");
10540 return create_stringRepr_infix("<@");
10542 return create_stringRepr_infix("@>");
10543 case OPTYPE_INT2BIT
:
10544 return create_stringRepr_predef2("int2bit");
10545 case OPTYPE_INT2HEX
:
10546 return create_stringRepr_predef2("int2hex");
10547 case OPTYPE_INT2OCT
:
10548 return create_stringRepr_predef2("int2oct");
10549 case OPTYPE_SUBSTR
: {
10550 string
ret_val("substr(");
10551 u
.expr
.ti1
->append_stringRepr(ret_val
);
10553 ret_val
+= u
.expr
.v2
->get_stringRepr();
10555 ret_val
+= u
.expr
.v3
->get_stringRepr();
10559 case OPTYPE_REGEXP
: {
10560 string
ret_val("regexp(");
10561 u
.expr
.ti1
->append_stringRepr(ret_val
);
10563 u
.expr
.t2
->append_stringRepr(ret_val
);
10565 ret_val
+= u
.expr
.v3
->get_stringRepr();
10569 case OPTYPE_DECOMP
: {
10570 string
ret_val("decomp(");
10571 ret_val
+= u
.expr
.v1
->get_stringRepr();
10573 ret_val
+= u
.expr
.v2
->get_stringRepr();
10575 ret_val
+= u
.expr
.v3
->get_stringRepr();
10579 case OPTYPE_REPLACE
: {
10580 string
ret_val("replace(");
10581 u
.expr
.ti1
->append_stringRepr(ret_val
);
10583 ret_val
+= u
.expr
.v2
->get_stringRepr();
10585 ret_val
+= u
.expr
.v3
->get_stringRepr();
10587 u
.expr
.ti4
->append_stringRepr(ret_val
);
10591 case OPTYPE_ISPRESENT
: {
10592 string
ret_val("ispresent(");
10593 u
.expr
.ti1
->append_stringRepr(ret_val
);
10596 case OPTYPE_ISCHOSEN
: {
10597 string
ret_val("ischosen(");
10598 ret_val
+= u
.expr
.r1
->get_dispname();
10600 ret_val
+= u
.expr
.i2
->get_dispname();
10603 case OPTYPE_ISCHOSEN_V
: {
10604 string
ret_val("ischosen(");
10605 ret_val
+= u
.expr
.v1
->get_stringRepr();
10607 ret_val
+= u
.expr
.i2
->get_dispname();
10610 case OPTYPE_ISCHOSEN_T
: {
10611 string
ret_val("ischosen(");
10612 ret_val
+= u
.expr
.t1
->get_stringRepr();
10614 ret_val
+= u
.expr
.i2
->get_dispname();
10617 case OPTYPE_LENGTHOF
: {
10618 string
ret_val("lengthof(");
10619 u
.expr
.ti1
->append_stringRepr(ret_val
);
10622 case OPTYPE_SIZEOF
: {
10623 string
ret_val("sizeof(");
10624 u
.expr
.ti1
->append_stringRepr(ret_val
);
10627 case OPTYPE_ISVALUE
: {
10628 string
ret_val("isvalue(");
10629 u
.expr
.ti1
->append_stringRepr(ret_val
);
10632 case OPTYPE_VALUEOF
: {
10633 string
ret_val("valueof(");
10634 u
.expr
.ti1
->append_stringRepr(ret_val
);
10637 case OPTYPE_LOG2STR
:
10638 return string("log2str(...)");
10639 case OPTYPE_ANY2UNISTR
:
10640 return string("any2unistr(...)");
10641 case OPTYPE_MATCH
: {
10642 string
ret_val("match(");
10643 ret_val
+= u
.expr
.v1
->get_stringRepr();
10645 u
.expr
.t2
->append_stringRepr(ret_val
);
10648 case OPTYPE_TTCN2STRING
: {
10649 string
ret_val("ttcn2string(");
10650 u
.expr
.ti1
->append_stringRepr(ret_val
);
10654 case OPTYPE_UNDEF_RUNNING
:
10655 return u
.expr
.r1
->get_dispname() + ".running";
10656 case OPTYPE_COMP_NULL
:
10657 return string("null");
10658 case OPTYPE_COMP_MTC
:
10659 return string("mtc");
10660 case OPTYPE_COMP_SYSTEM
:
10661 return string("system");
10662 case OPTYPE_COMP_SELF
:
10663 return string("self");
10664 case OPTYPE_COMP_CREATE
: {
10665 string
ret_val(u
.expr
.r1
->get_dispname());
10666 ret_val
+= ".create";
10667 if (u
.expr
.v2
|| u
.expr
.v3
) {
10669 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10670 else ret_val
+= '-';
10673 ret_val
+= u
.expr
.v3
->get_stringRepr();
10677 if (u
.expr
.b4
) ret_val
+= " alive";
10679 case OPTYPE_COMP_RUNNING
:
10680 return u
.expr
.v1
->get_stringRepr() + ".running";
10681 case OPTYPE_COMP_RUNNING_ANY
:
10682 return string("any component.running");
10683 case OPTYPE_COMP_RUNNING_ALL
:
10684 return string("all component.running");
10685 case OPTYPE_COMP_ALIVE
:
10686 return u
.expr
.v1
->get_stringRepr() + ".alive";
10687 case OPTYPE_COMP_ALIVE_ANY
:
10688 return string("any component.alive");
10689 case OPTYPE_COMP_ALIVE_ALL
:
10690 return string("all component.alive");
10691 case OPTYPE_TMR_READ
:
10692 return u
.expr
.r1
->get_dispname() + ".read";
10693 case OPTYPE_TMR_RUNNING
:
10694 return u
.expr
.r1
->get_dispname() + ".running";
10695 case OPTYPE_TMR_RUNNING_ANY
:
10696 return string("any timer.running");
10697 case OPTYPE_GETVERDICT
:
10698 return string("getverdict");
10699 case OPTYPE_ACTIVATE
: {
10700 string
ret_val("activate(");
10701 ret_val
+= u
.expr
.r1
->get_dispname();
10704 case OPTYPE_ACTIVATE_REFD
: {
10705 string
ret_val("activate(derefer(");
10706 ret_val
+= u
.expr
.v1
->get_stringRepr();
10708 if (u
.expr
.state
== EXPR_CHECKED
) {
10709 if (u
.expr
.ap_list2
) {
10710 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10711 for (size_t i
= 0; i
< nof_pars
; i
++) {
10712 if (i
> 0) ret_val
+= ", ";
10713 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10717 if (u
.expr
.t_list2
) {
10718 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10719 for (size_t i
= 0; i
< nof_pars
; i
++) {
10720 if (i
> 0) ret_val
+= ", ";
10721 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10727 case OPTYPE_EXECUTE
: {
10728 string
ret_val("execute(");
10729 ret_val
+= u
.expr
.r1
->get_dispname();
10732 ret_val
+= u
.expr
.v2
->get_stringRepr();
10736 case OPTYPE_EXECUTE_REFD
: {
10737 string
ret_val("execute(derefers(");
10738 ret_val
+= u
.expr
.v1
->get_stringRepr();
10740 if (u
.expr
.state
== EXPR_CHECKED
) {
10741 if (u
.expr
.ap_list2
) {
10742 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10743 for (size_t i
= 0; i
< nof_pars
; i
++) {
10744 if (i
> 0) ret_val
+= ", ";
10745 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10749 if (u
.expr
.t_list2
) {
10750 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10751 for (size_t i
= 0; i
< nof_pars
; i
++) {
10752 if (i
> 0) ret_val
+= ", ";
10753 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10760 ret_val
+= u
.expr
.v3
->get_stringRepr();
10764 case OPTYPE_PROF_RUNNING
:
10765 return string("@profiler.running");
10767 return string("<unsupported optype>");
10768 } // switch u.expr.v_optype
10771 case MACRO_MODULEID
:
10772 return string("%moduleId");
10773 case MACRO_FILENAME
:
10774 return string("%fileName");
10775 case MACRO_BFILENAME
:
10776 return string("__BFILE__");
10777 case MACRO_FILEPATH
:
10778 return string("__FILE__");
10779 case MACRO_LINENUMBER
:
10780 return string("%lineNumber");
10781 case MACRO_LINENUMBER_C
:
10782 return string("__LINE__");
10783 case MACRO_DEFINITIONID
:
10784 return string("%definitionId");
10786 return string("__SCOPE__");
10787 case MACRO_TESTCASEID
:
10788 return string("%testcaseId");
10790 return string("<unknown macro>");
10791 } // switch u.macro
10793 return string('-');
10797 string
ret_val("refers(");
10798 ret_val
+= u
.refd_fat
->get_assname();
10803 ret_val
+= u
.invoke
.v
->get_stringRepr();
10804 ret_val
+= ".apply(";
10805 if (u
.invoke
.ap_list
) {
10806 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10807 for (size_t i
= 0; i
< nof_pars
; i
++) {
10808 if (i
> 0) ret_val
+= ", ";
10809 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10811 } else if (u
.invoke
.t_list
) {
10812 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10813 for (size_t i
= 0; i
< nof_pars
; i
++) {
10814 if (i
> 0) ret_val
+= ", ";
10815 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10821 string
ret_val("refers(");
10822 ret_val
+= u
.refered
->get_dispname();
10826 return string("<unsupported valuetype>");
10827 } // switch valuetype
10830 string
Value::create_stringRepr_unary(const char *operator_str
)
10832 string
ret_val(operator_str
);
10834 ret_val
+= u
.expr
.v1
->get_stringRepr();
10839 string
Value::create_stringRepr_infix(const char *operator_str
)
10841 string
ret_val('(');
10842 ret_val
+= u
.expr
.v1
->get_stringRepr();
10844 ret_val
+= operator_str
;
10846 ret_val
+= u
.expr
.v2
->get_stringRepr();
10851 string
Value::create_stringRepr_predef1(const char *function_name
)
10853 string
ret_val(function_name
);
10855 if (u
.expr
.v_optype
== OPTYPE_ENCODE
|| u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
) { // ti1, not v1
10856 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10858 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10863 string
Value::create_stringRepr_predef2(const char *function_name
)
10865 string
ret_val(function_name
);
10867 ret_val
+= u
.expr
.v1
->get_stringRepr();
10869 ret_val
+= u
.expr
.v2
->get_stringRepr();
10874 bool Value::operator==(Value
& val
)
10876 Value
*left
= get_value_refd_last();
10877 Type
*left_governor
= left
->get_my_governor();
10878 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10879 Value
*right
= val
.get_value_refd_last();
10880 Type
*right_governor
= right
->get_my_governor();
10881 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10882 if (left_governor
&& right_governor
10883 && !left_governor
->is_compatible(right_governor
, NULL
)
10884 && !right_governor
->is_compatible(left_governor
, NULL
))
10885 FATAL_ERROR("Value::operator==");
10887 // Not-A-Value is not equal to anything (NaN analogy:)
10888 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10891 switch (left
->valuetype
) {
10894 case V_DEFAULT_NULL
:
10897 return left
->valuetype
== right
->valuetype
;
10899 return right
->valuetype
== V_BOOL
&&
10900 left
->get_val_bool() == right
->get_val_bool();
10902 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10903 == *right
->get_val_Int();
10905 return right
->valuetype
== V_REAL
&&
10906 left
->get_val_Real() == right
->get_val_Real();
10908 switch (right
->valuetype
) {
10910 return left
->get_val_str() == right
->get_val_str();
10912 return right
->get_val_ustr() == left
->get_val_str();
10914 return right
->get_val_iso2022str() == left
->get_val_str();
10921 return left
->valuetype
== right
->valuetype
&&
10922 left
->get_val_str() == right
->get_val_str();
10924 switch (right
->valuetype
) {
10926 return left
->get_val_ustr() == right
->get_val_str();
10928 return left
->get_val_ustr() == right
->get_val_ustr();
10930 return left
->get_val_ustr() == right
->get_val_iso2022str();
10935 switch (right
->valuetype
) {
10937 return left
->get_val_iso2022str() == right
->get_val_str();
10939 // The appropriate operator==() is missing. The operands are swapped,
10940 // but it shouldn't be a problem.
10941 return right
->get_val_ustr() == left
->get_val_iso2022str();
10943 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10948 return right
->valuetype
== V_ENUM
&&
10949 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10952 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10953 vector
<string
> act
, other
;
10954 get_oid_comps(act
);
10955 val
.get_oid_comps(other
);
10956 size_t act_size
= act
.size(), other_size
= other
.size();
10958 if (act_size
== other_size
) {
10960 for (size_t i
= 0; i
< act_size
; i
++)
10961 if (*act
[i
] != *other
[i
]) {
10965 } else ret_val
= false;
10966 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10968 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10971 } else return false;
10973 return right
->valuetype
== V_CHOICE
&&
10974 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10975 *(left
->get_alt_value()) == *(right
->get_alt_value());
10978 if (!left_governor
) FATAL_ERROR("Value::operator==");
10979 if (left
->valuetype
!= right
->valuetype
) return false;
10980 size_t nof_comps
= left_governor
->get_nof_comps();
10981 for (size_t i
= 0; i
< nof_comps
; i
++) {
10982 Value
*lval
= NULL
, *rval
= NULL
;
10983 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10984 const Identifier
& field_name
= cfl
->get_name();
10985 if (left
->has_comp_withName(field_name
)) {
10986 lval
= left
->get_comp_value_byName(field_name
);
10987 if (right
->has_comp_withName(field_name
)) {
10988 rval
= right
->get_comp_value_byName(field_name
);
10989 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10990 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10992 else if (!(*lval
== *rval
))
10995 if (cfl
->has_default()) {
10996 if (!(*lval
== *cfl
->get_defval()))
10999 if (lval
->valuetype
!= V_OMIT
)
11004 if(right
->has_comp_withName(field_name
)) {
11005 rval
= right
->get_comp_value_byName(field_name
);
11006 if(cfl
->has_default()) {
11007 if(rval
->valuetype
==V_OMIT
) return false;
11009 lval
= cfl
->get_defval();
11010 if (!(*lval
==*rval
)) return false;
11019 if (left
->valuetype
!= right
->valuetype
) return false;
11020 size_t ncomps
= get_nof_comps();
11021 if (ncomps
!= right
->get_nof_comps()) return false;
11023 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
11024 bool found
= false;
11025 map
<IndexedValue
*, void> uncovered
;
11026 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
11027 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
11029 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
11031 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
11032 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
11033 *(right
->get_comp_byIndex(i
)) &&
11034 *(uncovered
.get_nth_key(j
)->get_index()) ==
11035 *(right
->get_index_byIndex(i
))) {
11037 uncovered
.erase(uncovered
.get_nth_key(j
));
11045 } else if (left
->is_indexed() || right
->is_indexed()) {
11046 Value
* indexed_one
= 0;
11047 Value
* not_indexed_one
= 0;
11049 if(left
->is_indexed()) { // left is indexed, right is not
11050 indexed_one
= left
;
11051 not_indexed_one
= right
;
11052 } else { // right indexed, left is not
11053 indexed_one
= right
;
11054 not_indexed_one
= left
;
11057 for(size_t i
= 0; i
< ncomps
; ++i
) {
11058 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
11059 if(!(ind
->valuetype
== V_INT
&&
11060 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
11061 *(indexed_one
->get_comp_byIndex(i
))))
11065 } else { // none of them is indexed
11066 for (size_t i
= 0; i
< ncomps
; i
++) {
11067 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
11074 if (right
->valuetype
!= V_SETOF
) return false;
11075 size_t ncomps
= get_nof_comps();
11076 if (ncomps
!= right
->get_nof_comps()) return false;
11077 if (ncomps
== 0) return true;
11078 map
<size_t, void> uncovered
;
11079 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
11080 for (size_t i
= 0; i
< ncomps
; i
++) {
11081 Value
*left_item
= left
->get_comp_byIndex(i
);
11082 bool pair_found
= false;
11083 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
11084 size_t right_index
= uncovered
.get_nth_key(j
);
11085 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
11086 uncovered
.erase(right_index
);
11098 return right
->valuetype
== V_VERDICT
&&
11099 left
->get_val_verdict() == right
->get_val_verdict();
11103 return left
->valuetype
== right
->valuetype
&&
11104 left
->get_refd_assignment() == right
->get_refd_assignment();
11106 FATAL_ERROR("Value::operator==");
11111 bool Value::operator<(Value
& val
)
11113 Value
*left
= get_value_refd_last();
11114 Type
*left_governor
= left
->get_my_governor();
11115 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
11116 Value
*right
= val
.get_value_refd_last();
11117 Type
*right_governor
= right
->get_my_governor();
11118 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
11119 if (left
->get_valuetype() != right
->get_valuetype())
11120 FATAL_ERROR("Value::operator<");
11123 return *left
->get_val_Int() < *right
->get_val_Int();
11125 return (left
->get_val_Real() < right
->get_val_Real());
11127 if(!left_governor
|| !right_governor
)
11128 FATAL_ERROR("Value::operator<");
11129 if(left_governor
!=right_governor
)
11130 FATAL_ERROR("Value::operator<");
11131 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
11132 right_governor
->get_enum_val_byId(*right
->get_val_id()));
11134 FATAL_ERROR("Value::operator<");
11139 bool Value::is_string_type(Type::expected_value_t exp_val
)
11141 switch (get_expr_returntype(exp_val
)) {
11153 void Value::generate_code_expr(expression_struct
*expr
)
11155 if (has_single_expr()) {
11156 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
11158 switch (valuetype
) {
11160 generate_code_expr_expr(expr
);
11168 const string
& tmp_id
= get_temporary_id();
11169 const char *tmp_id_str
= tmp_id
.c_str();
11170 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11171 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
11172 set_genname_recursive(tmp_id
);
11173 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11174 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11177 const string
& tmp_id
= get_temporary_id();
11178 const char *tmp_id_str
= tmp_id
.c_str();
11179 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
11181 set_genname_recursive(tmp_id
);
11182 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11183 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11186 if (!get_needs_conversion()) {
11187 u
.ref
.ref
->generate_code_const_ref(expr
);
11189 Type
*my_gov
= get_expr_governor_last();
11190 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
11191 ->get_field_type(u
.ref
.ref
->get_subrefs(),
11192 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
11193 // Make sure that nothing goes wrong.
11194 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
11195 FATAL_ERROR("Value::generate_code_expr()");
11196 expression_struct expr_tmp
;
11197 Code::init_expr(&expr_tmp
);
11198 const string
& tmp_id1
= get_temporary_id();
11199 const char *tmp_id_str1
= tmp_id1
.c_str();
11200 const string
& tmp_id2
= get_temporary_id();
11201 const char *tmp_id_str2
= tmp_id2
.c_str();
11202 expr
->preamble
= mputprintf(expr
->preamble
,
11203 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
11205 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11206 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
11207 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11208 expr
->preamble
= mputprintf(expr
->preamble
,
11210 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11211 "and `%s' are not compatible at run-time\");\n",
11212 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11213 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
11214 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
11215 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
11216 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11220 generate_code_expr_invoke(expr
);
11223 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
11228 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
11230 generate_code_expr(expr
);
11231 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11232 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11235 bool Value::can_use_increment(Reference
*ref
) const
11237 if (valuetype
!= V_EXPR
) {
11240 switch (u
.expr
.v_optype
) {
11242 case OPTYPE_SUBTRACT
:
11247 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11248 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11249 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11250 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11251 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11252 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11258 char *Value::generate_code_init(char *str
, const char *name
)
11260 if (get_code_generated()) return str
;
11262 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11264 switch (valuetype
) {
11278 case V_DEFAULT_NULL
:
11283 // These values have a single string equivalent.
11284 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11287 if (u
.val_Int
->is_native_fit())
11288 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11290 // It's always an INTEGER.
11291 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11292 "}\n", get_single_expr().c_str(), name
);
11296 expression_struct expr
;
11297 Code::init_expr(&expr
);
11298 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11299 generate_code_expr(&expr
);
11300 str
= Code::merge_free_expr(str
, &expr
);
11303 str
= generate_code_init_choice(str
, name
);
11307 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11308 else str
= generate_code_init_indexed(str
, name
);
11311 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11312 else str
= generate_code_init_indexed(str
, name
);
11316 str
= generate_code_init_se(str
, name
);
11319 str
= generate_code_init_refd(str
, name
);
11323 case MACRO_TESTCASEID
:
11324 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11327 // all others must already be evaluated away
11328 FATAL_ERROR("Value::generate_code_init()");
11332 // unbound value, don't generate anything
11335 FATAL_ERROR("Value::generate_code_init()");
11338 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11340 set_code_generated();
11344 char *Value::rearrange_init_code(char *str
, Common::Module
* usage_mod
)
11346 switch (valuetype
) {
11348 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11350 str
= parlist
->rearrange_init_code(str
, usage_mod
);
11354 str
= u
.invoke
.v
->rearrange_init_code(str
, usage_mod
);
11355 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, usage_mod
);
11358 switch (u
.expr
.v_optype
) {
11359 case OPTYPE_UNARYPLUS
:
11360 case OPTYPE_UNARYMINUS
:
11363 case OPTYPE_BIT2HEX
:
11364 case OPTYPE_BIT2INT
:
11365 case OPTYPE_BIT2OCT
:
11366 case OPTYPE_BIT2STR
:
11367 case OPTYPE_CHAR2INT
:
11368 case OPTYPE_CHAR2OCT
:
11369 case OPTYPE_FLOAT2INT
:
11370 case OPTYPE_FLOAT2STR
:
11371 case OPTYPE_HEX2BIT
:
11372 case OPTYPE_HEX2INT
:
11373 case OPTYPE_HEX2OCT
:
11374 case OPTYPE_HEX2STR
:
11375 case OPTYPE_INT2CHAR
:
11376 case OPTYPE_INT2FLOAT
:
11377 case OPTYPE_INT2STR
:
11378 case OPTYPE_INT2UNICHAR
:
11379 case OPTYPE_OCT2BIT
:
11380 case OPTYPE_OCT2CHAR
:
11381 case OPTYPE_OCT2HEX
:
11382 case OPTYPE_OCT2INT
:
11383 case OPTYPE_OCT2STR
:
11384 case OPTYPE_STR2BIT
:
11385 case OPTYPE_STR2FLOAT
:
11386 case OPTYPE_STR2HEX
:
11387 case OPTYPE_STR2INT
:
11388 case OPTYPE_STR2OCT
:
11389 case OPTYPE_UNICHAR2INT
:
11390 case OPTYPE_UNICHAR2CHAR
:
11391 case OPTYPE_ENUM2INT
:
11392 case OPTYPE_ISCHOSEN_V
:
11393 case OPTYPE_GET_STRINGENCODING
:
11394 case OPTYPE_REMOVE_BOM
:
11395 case OPTYPE_DECODE_BASE64
:
11396 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11398 case OPTYPE_DECODE
: {
11399 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11400 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11401 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11403 parlist
= u
.expr
.r2
->get_parlist();
11404 ass
= u
.expr
.r2
->get_refd_assignment();
11405 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11408 case OPTYPE_SUBTRACT
:
11409 case OPTYPE_MULTIPLY
:
11410 case OPTYPE_DIVIDE
:
11413 case OPTYPE_CONCAT
:
11430 case OPTYPE_INT2BIT
:
11431 case OPTYPE_INT2HEX
:
11432 case OPTYPE_INT2OCT
:
11433 //case OPTYPE_DECODE:
11434 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11435 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11437 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11438 case OPTYPE_OCT2UNICHAR
:
11439 case OPTYPE_ENCODE_BASE64
:
11440 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11441 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11443 case OPTYPE_SUBSTR
:
11444 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11445 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11446 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11448 case OPTYPE_REGEXP
:
11449 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11450 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11451 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11453 case OPTYPE_DECOMP
:
11454 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11455 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11456 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11458 case OPTYPE_REPLACE
:
11459 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11460 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11461 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11462 str
= u
.expr
.ti4
->rearrange_init_code(str
, usage_mod
);
11464 case OPTYPE_LENGTHOF
:
11465 case OPTYPE_SIZEOF
:
11466 case OPTYPE_VALUEOF
:
11467 case OPTYPE_ENCODE
:
11468 case OPTYPE_ISPRESENT
:
11469 case OPTYPE_TTCN2STRING
:
11470 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11472 case OPTYPE_ENCVALUE_UNICHAR
:
11473 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11474 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11476 case OPTYPE_DECVALUE_UNICHAR
: {
11477 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11478 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11479 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11481 parlist
= u
.expr
.r2
->get_parlist();
11482 ass
= u
.expr
.r2
->get_refd_assignment();
11483 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11484 if (u
.expr
.v3
) str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11486 case OPTYPE_ISCHOSEN_T
:
11487 str
= u
.expr
.t1
->rearrange_init_code(str
, usage_mod
);
11490 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11491 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11494 // other kinds of expressions cannot appear within templates
11504 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11505 size_t& blockcount
)
11507 char *s2
= memptystr();
11508 char *s1
= generate_code_tmp(NULL
, s2
);
11510 if (blockcount
== 0) {
11511 str
= mputstr(str
, "{\n");
11514 str
= mputstr(str
, s2
);
11517 str
=mputstr(str
, prefix
);
11518 str
=mputstr(str
, s1
);
11523 char *Value::generate_code_tmp(char *str
, char*& init
)
11525 expression_struct expr
;
11526 Code::init_expr(&expr
);
11527 generate_code_expr_mandatory(&expr
);
11528 if (expr
.preamble
|| expr
.postamble
) {
11529 if (valuetype
== V_EXPR
&&
11530 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11531 // a temporary variable is already introduced
11532 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11533 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11534 str
= mputstr(str
, expr
.expr
);
11536 const string
& tmp_id
= get_temporary_id();
11537 const char *tmp_id_str
= tmp_id
.c_str();
11538 init
= mputprintf(init
, "%s %s;\n"
11540 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11541 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11543 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11544 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11545 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11546 init
= mputstr(init
, "}\n");
11547 str
= mputstr(str
, tmp_id_str
);
11549 } else str
= mputstr(str
, expr
.expr
);
11550 Code::free_expr(&expr
);
11554 void Value::generate_code_log(expression_struct
*expr
)
11556 if (explicit_cast_needed()) {
11557 char *expr_backup
= expr
->expr
;
11559 generate_code_expr(expr
);
11560 const string
& tmp_id
= get_temporary_id();
11561 const char *tmp_id_str
= tmp_id
.c_str();
11562 // We have to create a temporary object, because the parser of GCC
11563 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11564 // constructor call that is, this does not work: type(...).log(); but
11565 // this works: type tmp(...); tmp.log();.
11566 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11567 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11570 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11572 generate_code_expr(expr
);
11574 expr
->expr
= mputstr(expr
->expr
, ".log()");
11577 void Value::generate_code_log_match(expression_struct
*expr
)
11579 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11580 FATAL_ERROR("Value::generate_code_log_match()");
11581 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11582 // compliance the whole code-generation should be checked. Standalone
11583 // constructs like: "A(a[0].f());" should be avoided. The current
11584 // solution for HK38721 uses an additional assignment to overcome the
11585 // issue. The generated code will be slower, but it's needed for old GCC
11586 // versions in specific circumstances.
11587 if (u
.expr
.t2
->needs_temp_ref()) {
11588 char *expr_backup
= expr
->expr
;
11590 u
.expr
.t2
->generate_code(expr
);
11591 const string
& tmp_id
= get_temporary_id();
11592 const char *tmp_id_str
= tmp_id
.c_str();
11593 expr
->preamble
= mputprintf(expr
->preamble
,
11594 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11595 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11597 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11599 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11600 // some reason "(A(NS::B)).a(C);" compiles fine.
11601 expr
->expr
= mputc(expr
->expr
, '(');
11602 u
.expr
.t2
->generate_code(expr
);
11603 expr
->expr
= mputc(expr
->expr
, ')');
11605 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11606 u
.expr
.v1
->generate_code_expr(expr
);
11607 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11610 void Value::generate_code_expr_expr(expression_struct
*expr
)
11612 switch (u
.expr
.v_optype
) {
11614 generate_code_expr_rnd(expr
, 0);
11616 case OPTYPE_UNARYPLUS
:
11617 // same as without the '+' operator
11618 u
.expr
.v1
->generate_code_expr(expr
);
11620 case OPTYPE_UNARYMINUS
:
11621 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11624 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11627 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11629 case OPTYPE_BIT2HEX
:
11630 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11632 case OPTYPE_BIT2INT
:
11633 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11635 case OPTYPE_BIT2OCT
:
11636 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11638 case OPTYPE_BIT2STR
:
11639 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11641 case OPTYPE_CHAR2INT
:
11642 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11644 case OPTYPE_CHAR2OCT
:
11645 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11647 case OPTYPE_FLOAT2INT
:
11648 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11650 case OPTYPE_FLOAT2STR
:
11651 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11653 case OPTYPE_HEX2BIT
:
11654 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11656 case OPTYPE_HEX2INT
:
11657 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11659 case OPTYPE_HEX2OCT
:
11660 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11662 case OPTYPE_HEX2STR
:
11663 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11665 case OPTYPE_INT2CHAR
:
11666 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11668 case OPTYPE_INT2FLOAT
:
11669 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11671 case OPTYPE_INT2STR
:
11672 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11674 case OPTYPE_INT2UNICHAR
:
11675 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11677 case OPTYPE_OCT2BIT
:
11678 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11680 case OPTYPE_OCT2CHAR
:
11681 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11683 case OPTYPE_GET_STRINGENCODING
:
11684 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11686 case OPTYPE_REMOVE_BOM
:
11687 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11689 case OPTYPE_ENCODE_BASE64
:
11691 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11693 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11695 case OPTYPE_DECODE_BASE64
:
11696 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11698 case OPTYPE_OCT2UNICHAR
:
11700 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11702 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11704 case OPTYPE_UNICHAR2OCT
:
11706 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11708 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11710 case OPTYPE_ENCVALUE_UNICHAR
:
11711 generate_code_expr_encvalue_unichar(expr
);
11713 case OPTYPE_DECVALUE_UNICHAR
:
11714 generate_code_expr_decvalue_unichar(expr
);
11716 case OPTYPE_OCT2HEX
:
11717 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11719 case OPTYPE_OCT2INT
:
11720 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11722 case OPTYPE_OCT2STR
:
11723 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11725 case OPTYPE_STR2BIT
:
11726 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11728 case OPTYPE_STR2FLOAT
:
11729 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11731 case OPTYPE_STR2HEX
:
11732 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11734 case OPTYPE_STR2INT
:
11735 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11737 case OPTYPE_STR2OCT
:
11738 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11740 case OPTYPE_UNICHAR2INT
:
11741 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11743 case OPTYPE_UNICHAR2CHAR
:
11744 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11746 case OPTYPE_ENUM2INT
: {
11747 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11748 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11749 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11750 enum_type
->get_genname_value(my_scope
).c_str());
11751 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11752 expr
->expr
= mputc(expr
->expr
, ')');
11754 case OPTYPE_ENCODE
:
11755 generate_code_expr_encode(expr
);
11757 case OPTYPE_DECODE
:
11758 generate_code_expr_decode(expr
);
11760 case OPTYPE_RNDWITHVAL
:
11761 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11764 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11766 case OPTYPE_SUBTRACT
:
11767 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11769 case OPTYPE_MULTIPLY
:
11770 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11772 case OPTYPE_DIVIDE
:
11773 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11776 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11779 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11781 case OPTYPE_CONCAT
:
11782 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11785 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11788 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11791 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11794 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11797 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11800 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11804 generate_code_expr_and_or(expr
);
11807 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11810 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11813 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11816 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11819 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11822 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11825 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11828 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11830 case OPTYPE_INT2BIT
:
11831 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11833 case OPTYPE_INT2HEX
:
11834 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11836 case OPTYPE_INT2OCT
:
11837 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11839 case OPTYPE_SUBSTR
:
11840 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11841 else generate_code_expr_substr_replace_compat(expr
);
11843 case OPTYPE_REGEXP
:
11844 generate_code_expr_regexp(expr
);
11846 case OPTYPE_DECOMP
:
11847 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11849 case OPTYPE_REPLACE
:
11850 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11851 else generate_code_expr_substr_replace_compat(expr
);
11853 case OPTYPE_ISCHOSEN
: // r1 i2
11854 FATAL_ERROR("Value::generate_code_expr_expr()");
11856 case OPTYPE_ISCHOSEN_V
: // v1 i2
11857 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11858 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11859 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11860 u
.expr
.i2
->get_name().c_str());
11862 case OPTYPE_ISCHOSEN_T
: // t1 i2
11863 u
.expr
.t1
->generate_code_expr(expr
);
11864 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11865 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11866 u
.expr
.i2
->get_name().c_str());
11868 case OPTYPE_ISPRESENT
:
11869 case OPTYPE_ISBOUND
: {
11870 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11871 ->get_templatetype();
11872 if (temp
== Template::SPECIFIC_VALUE
) {
11873 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11874 ->get_specific_value();
11875 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11876 Ttcn::Reference
* reference
=
11877 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11879 reference
->generate_code_ispresentbound(expr
, false,
11880 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11884 } else if (temp
== Template::TEMPLATE_REFD
){
11885 Ttcn::Reference
* reference
=
11886 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11887 ->get_reference());
11889 reference
->generate_code_ispresentbound(expr
, true,
11890 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11896 case OPTYPE_LENGTHOF
: // ti1
11897 // fall through, separated later
11898 case OPTYPE_SIZEOF
: // ti1
11899 // fall through, separated later
11900 case OPTYPE_ISVALUE
: { // ti1
11901 if (u
.expr
.ti1
->is_only_specific_value()) {
11902 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11903 bool cast_needed
= t_val
->explicit_cast_needed(
11904 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11906 // the ambiguous C++ expression is converted to the value class
11907 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11908 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11911 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11912 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11913 t_val
->generate_code_expr(expr
);
11915 t_val
->generate_code_expr_mandatory(expr
);
11918 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11920 else u
.expr
.ti1
->generate_code(expr
);
11922 switch (u
.expr
.v_optype
) {
11923 case OPTYPE_ISBOUND
:
11924 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11926 case OPTYPE_ISPRESENT
:
11927 expr
->expr
=mputprintf(expr
->expr
, ".is_present()");
11929 case OPTYPE_SIZEOF
:
11930 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11932 case OPTYPE_LENGTHOF
:
11933 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11935 case OPTYPE_ISVALUE
:
11936 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11939 FATAL_ERROR("Value::generate_code_expr_expr()");
11942 case OPTYPE_VALUEOF
: // ti1
11943 u
.expr
.ti1
->generate_code(expr
);
11944 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11946 case OPTYPE_MATCH
: // v1 t2
11947 u
.expr
.t2
->generate_code(expr
);
11948 expr
->expr
= mputstr(expr
->expr
, ".match(");
11949 u
.expr
.v1
->generate_code_expr(expr
);
11950 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11952 case OPTYPE_UNDEF_RUNNING
:
11953 // it is resolved during semantic check
11954 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11956 case OPTYPE_COMP_NULL
: // -
11957 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11959 case OPTYPE_COMP_MTC
: // -
11960 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11962 case OPTYPE_COMP_SYSTEM
: // -
11963 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11965 case OPTYPE_COMP_SELF
: // -
11966 expr
->expr
=mputstr(expr
->expr
, "self");
11968 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11969 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11972 case OPTYPE_COMP_RUNNING
: // v1
11973 u
.expr
.v1
->generate_code_expr(expr
);
11974 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11975 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11976 expr
->expr
= mputstr(expr
->expr
, ".running()");
11978 case OPTYPE_COMP_RUNNING_ANY
: // -
11979 expr
->expr
=mputstr(expr
->expr
,
11980 "TTCN_Runtime::component_running(ANY_COMPREF)");
11982 case OPTYPE_COMP_RUNNING_ALL
: // -
11983 expr
->expr
=mputstr(expr
->expr
,
11984 "TTCN_Runtime::component_running(ALL_COMPREF)");
11986 case OPTYPE_COMP_ALIVE
: // v1
11987 u
.expr
.v1
->generate_code_expr(expr
);
11988 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11989 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11990 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11992 case OPTYPE_COMP_ALIVE_ANY
: // -
11993 expr
->expr
= mputstr(expr
->expr
,
11994 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11996 case OPTYPE_COMP_ALIVE_ALL
: // -
11997 expr
->expr
= mputstr(expr
->expr
,
11998 "TTCN_Runtime::component_alive(ALL_COMPREF)");
12000 case OPTYPE_TMR_READ
: // r1
12001 u
.expr
.r1
->generate_code(expr
);
12002 expr
->expr
= mputstr(expr
->expr
, ".read()");
12004 case OPTYPE_TMR_RUNNING
: // r1
12005 u
.expr
.r1
->generate_code(expr
);
12006 expr
->expr
= mputstr(expr
->expr
, ".running()");
12008 case OPTYPE_TMR_RUNNING_ANY
: // -
12009 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
12011 case OPTYPE_GETVERDICT
: // -
12012 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
12014 case OPTYPE_TESTCASENAME
: // -
12015 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
12017 case OPTYPE_ACTIVATE
: // r1
12018 generate_code_expr_activate(expr
);
12020 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
12021 generate_code_expr_activate_refd(expr
);
12023 case OPTYPE_EXECUTE
: // r1 [v2]
12024 generate_code_expr_execute(expr
);
12026 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
12027 generate_code_expr_execute_refd(expr
);
12029 case OPTYPE_LOG2STR
:
12030 case OPTYPE_ANY2UNISTR
:
12031 u
.expr
.logargs
->generate_code_expr(expr
);
12033 case OPTYPE_TTCN2STRING
: {
12034 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
12035 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
12036 param_governor
= param_governor
->get_type_refd_last();
12037 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
12038 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
12039 u
.expr
.ti1
->get_Template()->is_Value()) {
12040 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
12043 bool cast_needed
= v
->explicit_cast_needed();
12045 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
12047 v
->generate_code_expr(expr
);
12049 expr
->expr
= mputstr(expr
->expr
, ")");
12053 u
.expr
.ti1
->generate_code(expr
);
12055 expr
->expr
= mputstr(expr
->expr
, ")");
12057 case OPTYPE_PROF_RUNNING
:
12058 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
12061 FATAL_ERROR("Value::generate_code_expr_expr()");
12065 void Value::generate_code_expr_unary(expression_struct
*expr
,
12066 const char *operator_str
, Value
*v1
)
12068 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
12069 v1
->generate_code_expr_mandatory(expr
);
12070 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
12073 void Value::generate_code_expr_infix(expression_struct
*expr
,
12074 const char *operator_str
, Value
*v1
,
12075 Value
*v2
, bool optional_allowed
)
12077 if (!get_needs_conversion()) {
12078 expr
->expr
= mputc(expr
->expr
, '(');
12079 if (optional_allowed
) v1
->generate_code_expr(expr
);
12080 else v1
->generate_code_expr_mandatory(expr
);
12081 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
12082 if (optional_allowed
) v2
->generate_code_expr(expr
);
12083 else v2
->generate_code_expr_mandatory(expr
);
12084 expr
->expr
= mputc(expr
->expr
, ')');
12085 } else { // Temporary variable for the converted value.
12086 const string
& tmp_id1
= get_temporary_id();
12087 const char *tmp_id_str1
= tmp_id1
.c_str();
12088 expression_struct expr_tmp
;
12089 Code::init_expr(&expr_tmp
);
12090 switch (u
.expr
.v_optype
) {
12093 // Always "v1 -> v2".
12094 Type
*t1
= v1
->get_expr_governor_last();
12095 Type
*t2
= v2
->get_expr_governor_last();
12096 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
12097 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12098 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12099 if (expr_tmp
.preamble
)
12100 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12101 expr
->preamble
= mputprintf(expr
->preamble
,
12103 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12104 "and `%s' are not compatible at run-time\");\n",
12105 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
12106 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
12107 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
12108 t2
->get_typename().c_str(), t1
->get_typename().c_str());
12109 Code::free_expr(&expr_tmp
);
12110 if (optional_allowed
) v1
->generate_code_expr(expr
);
12111 else v1
->generate_code_expr_mandatory(expr
);
12112 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
12115 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12116 // functions. The governors of all operands must exist at this point.
12119 case OPTYPE_CONCAT
: {
12120 const string
& tmp_id2
= get_temporary_id();
12121 const char *tmp_id_str2
= tmp_id2
.c_str();
12122 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
12123 Type
*my_gov
= my_governor
->get_type_refd_last();
12124 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
12125 ->get_type_refd_last();
12126 if (!t1_gov
|| my_gov
== t1_gov
)
12127 FATAL_ERROR("Value::generate_code_expr_infix()");
12128 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
12129 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
12130 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
12131 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
12132 else v1
->generate_code_expr_mandatory(&expr_tmp
);
12133 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
12134 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12135 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12136 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
12137 expr
->preamble
= mputprintf(expr
->preamble
,
12139 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12140 "and `%s' are not compatible at run-time\");\n",
12141 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
12142 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
12143 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
12144 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
12145 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
12148 FATAL_ERROR("Value::generate_code_expr_infix()");
12154 void Value::generate_code_expr_and_or(expression_struct
*expr
)
12156 if (u
.expr
.v2
->needs_short_circuit()) {
12157 // introduce a temporary variable to store the result of the operation
12158 const string
& tmp_id
= get_temporary_id();
12159 const char *tmp_id_str
= tmp_id
.c_str();
12160 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
12161 expression_struct expr2
;
12162 // the left operand must be evaluated anyway
12163 Code::init_expr(&expr2
);
12164 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12165 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
12166 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12167 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
12168 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
12169 // evaluate the right operand only when necessary
12170 // in this case the final result will be the right operand
12171 Code::init_expr(&expr2
);
12172 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12173 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
12174 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12175 // the result is now in the temporary variable
12176 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
12178 // use the overloaded operator to get better error messages
12179 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
12180 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
12184 void Value::generate_code_expr_predef1(expression_struct
*expr
,
12185 const char *function_name
,
12188 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12189 v1
->generate_code_expr_mandatory(expr
);
12190 expr
->expr
= mputc(expr
->expr
, ')');
12193 void Value::generate_code_expr_predef2(expression_struct
*expr
,
12194 const char *function_name
,
12195 Value
*v1
, Value
*v2
)
12197 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12198 v1
->generate_code_expr_mandatory(expr
);
12199 expr
->expr
= mputstr(expr
->expr
, ", ");
12200 v2
->generate_code_expr_mandatory(expr
);
12201 expr
->expr
= mputc(expr
->expr
, ')');
12204 void Value::generate_code_expr_predef3(expression_struct
*expr
,
12205 const char *function_name
,
12206 Value
*v1
, Value
*v2
, Value
*v3
)
12208 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12209 v1
->generate_code_expr_mandatory(expr
);
12210 expr
->expr
= mputstr(expr
->expr
, ", ");
12211 v2
->generate_code_expr_mandatory(expr
);
12212 expr
->expr
= mputstr(expr
->expr
, ", ");
12213 v3
->generate_code_expr_mandatory(expr
);
12214 expr
->expr
= mputc(expr
->expr
, ')');
12217 void Value::generate_code_expr_substr(expression_struct
*expr
)
12220 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12221 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12222 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12223 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
12224 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12225 else u
.expr
.ti1
->generate_code(expr
);
12226 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12227 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
12228 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12229 expr
->expr
= mputstr(expr
->expr
, "(int)");
12230 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12231 expr
->expr
= mputstr(expr
->expr
, ", ");
12232 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12233 expr
->expr
= mputstr(expr
->expr
, "(int)");
12234 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12235 expr
->expr
= mputc(expr
->expr
, ')');
12238 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
12240 expression_struct expr_tmp
;
12241 Code::init_expr(&expr_tmp
);
12242 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
12243 ->get_type_refd_last();
12244 if (!t1
|| t1
== my_governor
->get_type_refd_last())
12245 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12246 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
12247 generate_code_expr_substr(&expr_tmp
);
12248 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
12249 generate_code_expr_replace(&expr_tmp
);
12251 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12253 // Two temporaries to store the result of substr() or replace() and to
12254 // store the converted value.
12255 const string
& tmp_id1
= get_temporary_id();
12256 const char *tmp_id_str1
= tmp_id1
.c_str();
12257 const string
& tmp_id2
= get_temporary_id();
12258 const char *tmp_id_str2
= tmp_id2
.c_str();
12259 if (expr_tmp
.preamble
)
12260 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12261 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12262 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12263 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12264 if (expr_tmp
.postamble
)
12265 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12266 Code::free_expr(&expr_tmp
);
12267 expr
->preamble
= mputprintf(expr
->preamble
,
12268 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12269 "`%s' are not compatible at run-time\");\n",
12270 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12271 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12272 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12273 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12276 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12278 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12279 Value
* v2
= u
.expr
.t2
->get_specific_value();
12280 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12281 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12282 else u
.expr
.ti1
->generate_code(expr
);
12283 expr
->expr
= mputstr(expr
->expr
, ", ");
12284 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12285 else u
.expr
.t2
->generate_code(expr
);
12286 expr
->expr
= mputstr(expr
->expr
, ", ");
12287 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12288 expr
->expr
= mputc(expr
->expr
, ')');
12291 void Value::generate_code_expr_replace(expression_struct
*expr
)
12293 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12294 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12296 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12297 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12298 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12299 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12300 else u
.expr
.ti1
->generate_code(expr
);
12301 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12302 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12303 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12304 expr
->expr
= mputstr(expr
->expr
, "(int)");
12305 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12306 expr
->expr
= mputstr(expr
->expr
, ", ");
12307 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12308 expr
->expr
= mputstr(expr
->expr
, "(int)");
12309 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12310 expr
->expr
= mputstr(expr
->expr
, ", ");
12312 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12313 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12314 Value
* v4_last
= v4
->get_value_refd_last();
12315 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12316 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12317 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12319 v4
->generate_code_expr_mandatory(expr
);
12321 else u
.expr
.ti4
->generate_code(expr
);
12322 expr
->expr
= mputc(expr
->expr
, ')');
12325 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12328 if(!v1
) // simple random generation
12329 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12330 else { // random generation with seeding
12331 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12332 v1
->generate_code_expr_mandatory(expr
);
12333 expr
->expr
= mputc(expr
->expr
, ')');
12337 void Value::generate_code_expr_create(expression_struct
*expr
,
12338 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12340 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12341 // first two arguments: component type
12342 Assignment
*t_ass
= type
->get_refd_assignment();
12343 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12344 FATAL_ERROR("Value::generate_code_expr_create()");
12345 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12346 Type::EXPECTED_DYNAMIC_VALUE
);
12347 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12348 comptype
= comptype
->get_type_refd_last();
12349 expr
->expr
= comptype
->get_CompBody()
12350 ->generate_code_comptype_name(expr
->expr
);
12351 expr
->expr
= mputstr(expr
->expr
, ", ");
12352 // third argument: component name
12354 Value
*t_val
= name
->get_value_refd_last();
12355 if (t_val
->valuetype
== V_CSTR
) {
12356 // the argument is foldable to a string literal
12357 size_t str_len
= t_val
->u
.str
.val_str
->size();
12358 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12359 expr
->expr
= mputc(expr
->expr
, '"');
12360 for (size_t i
= 0; i
< str_len
; i
++)
12361 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12362 expr
->expr
= mputc(expr
->expr
, '"');
12363 } else name
->generate_code_expr_mandatory(expr
);
12364 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12365 expr
->expr
= mputstr(expr
->expr
, ", ");
12366 // fourth argument: location
12368 Value
*t_val
= location
->get_value_refd_last();
12369 if (t_val
->valuetype
== V_CSTR
) {
12370 // the argument is foldable to a string literal
12371 size_t str_len
= t_val
->u
.str
.val_str
->size();
12372 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12373 expr
->expr
= mputc(expr
->expr
, '"');
12374 for (size_t i
= 0; i
< str_len
; i
++)
12375 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12376 expr
->expr
= mputc(expr
->expr
, '"');
12377 } else location
->generate_code_expr_mandatory(expr
);
12378 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12379 // fifth argument: alive flag
12380 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12383 void Value::generate_code_expr_activate(expression_struct
*expr
)
12385 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12386 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12387 FATAL_ERROR("Value::generate_code_expr_activate()");
12388 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12389 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12390 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12391 expr
->expr
= mputc(expr
->expr
, ')');
12394 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12396 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12397 if (v_last
->valuetype
== V_ALTSTEP
) {
12398 // the referred altstep is known
12399 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12400 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12402 // the referred altstep is unknown
12403 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12404 expr
->expr
= mputstr(expr
->expr
,".activate(");
12406 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12407 expr
->expr
= mputc(expr
->expr
, ')');
12410 void Value::generate_code_expr_execute(expression_struct
*expr
)
12412 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12413 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12414 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12415 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12416 if (parlist
->get_nof_pars() > 0) {
12417 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12419 expr
->expr
= mputstr(expr
->expr
, ", ");
12422 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12423 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12424 expr
->expr
= mputc(expr
->expr
, ')');
12425 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12428 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12430 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12431 if (v_last
->valuetype
== V_TESTCASE
) {
12432 // the referred testcase is known
12433 Assignment
*testcase
= v_last
->get_refd_fat();
12434 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12435 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12436 u
.expr
.ap_list2
->generate_code_alias(expr
,
12437 testcase
->get_FormalParList(), 0, false);
12439 // the referred testcase is unknown
12440 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12441 expr
->expr
= mputstr(expr
->expr
,".execute(");
12442 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12444 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12445 expr
->expr
= mputstr(expr
->expr
, ", ");
12447 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12448 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12449 expr
->expr
= mputc(expr
->expr
, ')');
12450 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12453 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12455 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12456 if (last_v
->get_valuetype() == V_FUNCTION
) {
12457 // the referred function is known
12458 Assignment
*function
= last_v
->get_refd_fat();
12459 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12460 function
->get_genname_from_scope(my_scope
).c_str());
12461 u
.invoke
.ap_list
->generate_code_alias(expr
,
12462 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12464 // the referred function is unknown
12465 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12466 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12467 Type
* gov_last
= last_v
->get_expr_governor_last();
12468 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12469 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12471 expr
->expr
= mputc(expr
->expr
, ')');
12474 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12477 // if the referenced value points to an optional value field the
12478 // generated code has to be corrected at the end:
12479 // `fieldid()' => `fieldid()()'
12480 Assignment
*ass
= ref
->get_refd_assignment();
12481 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12482 switch (ass
->get_asstype()) {
12483 case Assignment::A_CONST
:
12484 case Assignment::A_EXT_CONST
:
12485 case Assignment::A_MODULEPAR
:
12486 case Assignment::A_VAR
:
12487 case Assignment::A_FUNCTION_RVAL
:
12488 case Assignment::A_EXT_FUNCTION_RVAL
:
12489 case Assignment::A_PAR_VAL_IN
:
12490 case Assignment::A_PAR_VAL_OUT
:
12491 case Assignment::A_PAR_VAL_INOUT
:
12492 // only these are mapped to value objects
12493 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12494 expr
->expr
= mputstr(expr
->expr
, "()");
12501 void Value::generate_code_expr_encode(expression_struct
*expr
)
12505 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12506 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12507 v1
= templ
->get_specific_value();
12508 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12510 expression_struct expr2
;
12511 Code::init_expr(&expr2
);
12513 bool is_templ
= false;
12514 switch (templ
->get_templatetype()) {
12515 case Template::SPECIFIC_VALUE
:
12516 v1
->generate_code_expr_mandatory(&expr2
);
12519 u
.expr
.ti1
->generate_code(&expr2
);
12524 if (!gov_last
->is_coding_by_function()) {
12525 const string
& tmp_id
= get_temporary_id();
12526 const string
& tmp_buf_id
= get_temporary_id();
12527 const string
& tmp_ref_id
= get_temporary_id();
12528 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12530 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12531 tmp_buf_id
.c_str());
12532 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12533 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12534 expr
->preamble
= mputc (expr
->preamble
, '\n');
12536 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12537 gov_last
->get_genname_typedescriptor(
12538 u
.expr
.ti1
->get_Template()->get_my_scope()
12540 tmp_ref_id
.c_str(),
12542 if (is_templ
) // make a value out of the template, if needed
12543 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12544 expr
->preamble
= mputprintf(expr
->preamble
,
12545 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12546 tmp_ref_id
.c_str(),
12547 gov_last
->get_genname_typedescriptor(
12548 u
.expr
.ti1
->get_Template()->get_my_scope()
12550 tmp_buf_id
.c_str(),
12551 gov_last
->get_coding(true).c_str()
12553 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12554 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12555 tmp_buf_id
.c_str(),
12558 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12559 if (expr2
.postamble
)
12560 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12562 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12563 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12564 is_templ
? ".valueof()" : "");
12565 Code::free_expr(&expr2
);
12568 void Value::generate_code_expr_decode(expression_struct
*expr
)
12570 expression_struct expr1
, expr2
;
12571 Code::init_expr(&expr1
);
12572 Code::init_expr(&expr2
);
12573 u
.expr
.r1
->generate_code(&expr1
);
12574 u
.expr
.r2
->generate_code(&expr2
);
12576 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12577 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12578 get_type_refd_last();
12580 if (expr1
.preamble
)
12581 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12582 if (expr2
.preamble
)
12583 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12585 if (!_type
->is_coding_by_function()) {
12586 const string
& tmp_id
= get_temporary_id();
12587 const string
& buffer_id
= get_temporary_id();
12588 const string
& retval_id
= get_temporary_id();
12589 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12590 field_is_optional(u
.expr
.r2
->get_subrefs());
12592 expr
->preamble
= mputprintf(expr
->preamble
,
12593 "TTCN_Buffer %s(bit2oct(%s));\n"
12595 "TTCN_EncDec::set_error_behavior("
12596 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12597 "TTCN_EncDec::clear_error();\n",
12602 expr
->preamble
= mputprintf(expr
->preamble
,
12603 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12605 optional
? "()" : "",
12606 _type
->get_genname_typedescriptor(
12607 u
.expr
.r2
->get_my_scope()
12610 _type
->get_coding(false).c_str()
12612 expr
->preamble
= mputprintf(expr
->preamble
,
12613 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12614 "case TTCN_EncDec::ET_NONE: {\n"
12616 "OCTETSTRING %s;\n"
12617 "%s.get_string(%s);\n"
12618 "%s = oct2bit(%s);\n"
12621 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12622 "case TTCN_EncDec::ET_LEN_ERR:\n"
12628 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12629 "TTCN_EncDec::EB_DEFAULT);\n"
12630 "TTCN_EncDec::clear_error();\n",
12641 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12643 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12644 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12645 if (expr1
.postamble
)
12646 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12647 if (expr2
.postamble
)
12648 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12649 Code::free_expr(&expr1
);
12650 Code::free_expr(&expr2
);
12653 void Value::generate_code_expr_encvalue_unichar(expression_struct
*expr
)
12657 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12658 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12659 v1
= templ
->get_specific_value();
12660 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12662 expression_struct expr2
;
12663 Code::init_expr(&expr2
);
12665 bool is_templ
= false;
12666 switch (templ
->get_templatetype()) {
12667 case Template::SPECIFIC_VALUE
:
12668 v1
->generate_code_expr_mandatory(&expr2
);
12671 u
.expr
.ti1
->generate_code(&expr2
);
12676 if (!gov_last
->is_coding_by_function()) {
12677 const string
& tmp_id
= get_temporary_id();
12678 const string
& tmp_buf_id
= get_temporary_id();
12679 const string
& tmp_ref_id
= get_temporary_id();
12680 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12682 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12683 tmp_buf_id
.c_str());
12684 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12685 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12686 expr
->preamble
= mputc (expr
->preamble
, '\n');
12688 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12689 gov_last
->get_genname_typedescriptor(
12690 u
.expr
.ti1
->get_Template()->get_my_scope()
12692 tmp_ref_id
.c_str(),
12694 if (is_templ
) // make a value out of the template, if needed
12695 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12696 expr
->preamble
= mputprintf(expr
->preamble
,
12697 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12698 tmp_ref_id
.c_str(),
12699 gov_last
->get_genname_typedescriptor(
12700 u
.expr
.ti1
->get_Template()->get_my_scope()
12702 tmp_buf_id
.c_str(),
12703 gov_last
->get_coding(true).c_str()
12705 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12706 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12707 tmp_buf_id
.c_str(),
12710 const char * v2_code
= NULL
;
12712 v2_code
= generate_code_char_coding_check(expr
, u
.expr
.v2
, "encvalue_unichar");
12714 expr
->expr
= mputprintf(expr
->expr
, "oct2unichar(%s", tmp_id
.c_str());
12716 expr
->expr
= mputprintf(expr
->expr
, ", %s", v2_code
);
12718 expr
->expr
= mputprintf(expr
->expr
, ", \"UTF-8\""); //default
12720 expr
->expr
= mputprintf(expr
->expr
, ")");
12721 if (expr2
.postamble
)
12722 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12724 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12725 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12726 is_templ
? ".valueof()" : "");
12727 Code::free_expr(&expr2
);
12730 void Value::generate_code_expr_decvalue_unichar(expression_struct
*expr
)
12732 expression_struct expr1
, expr2
;
12733 Code::init_expr(&expr1
);
12734 Code::init_expr(&expr2
);
12735 u
.expr
.r1
->generate_code(&expr1
);
12736 u
.expr
.r2
->generate_code(&expr2
);
12738 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12739 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12740 get_type_refd_last();
12742 if (expr1
.preamble
)
12743 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12744 if (expr2
.preamble
)
12745 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12747 if (!_type
->is_coding_by_function()) {
12748 const string
& tmp_id
= get_temporary_id();
12749 const string
& buffer_id
= get_temporary_id();
12750 const string
& retval_id
= get_temporary_id();
12751 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12752 field_is_optional(u
.expr
.r2
->get_subrefs());
12754 const char* v3_code
= NULL
;
12756 v3_code
= generate_code_char_coding_check(expr
, u
.expr
.v3
, "decvalue_unichar");
12758 expr
->preamble
= mputprintf(expr
->preamble
,
12759 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12761 "TTCN_EncDec::set_error_behavior("
12762 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12763 "TTCN_EncDec::clear_error();\n",
12766 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12769 expr
->preamble
= mputprintf(expr
->preamble
,
12770 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12772 optional
? "()" : "",
12773 _type
->get_genname_typedescriptor(
12774 u
.expr
.r2
->get_my_scope()
12777 _type
->get_coding(false).c_str()
12779 expr
->preamble
= mputprintf(expr
->preamble
,
12780 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12781 "case TTCN_EncDec::ET_NONE: {\n"
12783 "OCTETSTRING %s;\n"
12784 "%s.get_string(%s);\n"
12785 "%s = oct2unichar(%s, %s);\n"
12788 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12789 "case TTCN_EncDec::ET_LEN_ERR:\n"
12795 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12796 "TTCN_EncDec::EB_DEFAULT);\n"
12797 "TTCN_EncDec::clear_error();\n",
12804 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12809 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12811 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12812 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12813 if (expr1
.postamble
)
12814 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12815 if (expr2
.postamble
)
12816 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12817 Code::free_expr(&expr1
);
12818 Code::free_expr(&expr2
);
12821 char* Value::generate_code_char_coding_check(expression_struct
*expr
, Value
*v
, const char *name
)
12823 expression_struct expr2
;
12824 Code::init_expr(&expr2
);
12825 v
->generate_code_expr_mandatory(&expr2
);
12826 expr
->preamble
= mputprintf(expr
->preamble
,
12827 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12828 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12829 " \"UTF-32BE\" != %s) {\n"
12830 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12831 "}\n", //todo errorbehaviour?
12844 char *Value::generate_code_init_choice(char *str
, const char *name
)
12846 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12847 // Safe as long as get_name() returns a const string&, not a temporary.
12848 const char *alt_prefix
=
12849 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12851 if (u
.choice
.alt_value
->needs_temp_ref()) {
12852 const string
& tmp_id
= get_temporary_id();
12853 const char *tmp_id_str
= tmp_id
.c_str();
12854 str
= mputprintf(str
, "{\n"
12855 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12856 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12857 alt_prefix
, alt_name
);
12858 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12859 str
= mputstr(str
, "}\n");
12861 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12862 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12863 Free(embedded_name
);
12868 char *Value::generate_code_init_seof(char *str
, const char *name
)
12870 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12872 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12873 const string
& embedded_type
=
12874 my_governor
->get_ofType()->get_genname_value(my_scope
);
12875 const char *embedded_type_str
= embedded_type
.c_str();
12876 for (size_t i
= 0; i
< nof_vs
; i
++) {
12877 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12879 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12880 else if (comp_v
->needs_temp_ref()) {
12881 const string
& tmp_id
= get_temporary_id();
12882 const char *tmp_id_str
= tmp_id
.c_str();
12883 str
= mputprintf(str
, "{\n"
12884 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12885 (unsigned long) i
);
12886 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12887 str
= mputstr(str
, "}\n");
12889 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12890 str
= comp_v
->generate_code_init(str
, embedded_name
);
12891 Free(embedded_name
);
12895 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12900 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12902 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12904 // Previous values can be truncated. The concept is similar to
12906 Type
*t_last
= my_governor
->get_type_refd_last();
12907 const string
& oftype_name
=
12908 t_last
->get_ofType()->get_genname_value(my_scope
);
12909 const char *oftype_name_str
= oftype_name
.c_str();
12910 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12911 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12912 const string
& tmp_id_1
= get_temporary_id();
12913 str
= mputstr(str
, "{\n");
12914 Value
*index
= iv
->get_index();
12915 if (index
->get_valuetype() != V_INT
) {
12916 const string
& tmp_id_2
= get_temporary_id();
12917 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12918 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12919 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12920 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12922 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12923 tmp_id_1
.c_str(), name
,
12924 (index
->get_val_Int()->t_str()).c_str());
12926 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12927 str
= mputstr(str
, "}\n");
12929 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12933 char *Value::generate_code_init_array(char *str
, const char *name
)
12935 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12936 Type
*t_last
= my_governor
->get_type_refd_last();
12937 Int index_offset
= t_last
->get_dimension()->get_offset();
12938 const string
& embedded_type
=
12939 t_last
->get_ofType()->get_genname_value(my_scope
);
12940 const char *embedded_type_str
= embedded_type
.c_str();
12941 for (size_t i
= 0; i
< nof_vs
; i
++) {
12942 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12943 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12944 else if (comp_v
->needs_temp_ref()) {
12945 const string
& tmp_id
= get_temporary_id();
12946 const char *tmp_id_str
= tmp_id
.c_str();
12947 str
= mputprintf(str
, "{\n"
12948 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12949 Int2string(index_offset
+ i
).c_str());
12950 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12951 str
= mputstr(str
, "}\n");
12953 char *embedded_name
= mprintf("%s[%s]", name
,
12954 Int2string(index_offset
+ i
).c_str());
12955 str
= comp_v
->generate_code_init(str
, embedded_name
);
12956 Free(embedded_name
);
12962 char *Value::generate_code_init_se(char *str
, const char *name
)
12964 Type
*type
= my_governor
->get_type_refd_last();
12965 size_t nof_comps
= type
->get_nof_comps();
12966 if (nof_comps
> 0) {
12967 for (size_t i
= 0; i
< nof_comps
; i
++) {
12968 CompField
*cf
= type
->get_comp_byIndex(i
);
12969 const Identifier
& field_id
= cf
->get_name();
12970 const char *field_name
= field_id
.get_name().c_str();
12972 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12973 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12974 if (field_v
->valuetype
== V_NOTUSED
) continue;
12975 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12976 } else if (is_asn1()) {
12977 if (cf
->has_default()) {
12978 // handle like a referenced value
12979 Value
*defval
= cf
->get_defval();
12980 if (needs_init_precede(defval
)) {
12981 str
= defval
->generate_code_init(str
,
12982 defval
->get_lhs_name().c_str());
12984 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12985 defval
->get_genname_own(my_scope
).c_str());
12988 if (!cf
->get_is_optional())
12989 FATAL_ERROR("Value::generate_code_init()");
12996 // the value is not omit
12997 if (field_v
->needs_temp_ref()) {
12998 const string
& tmp_id
= get_temporary_id();
12999 const char *tmp_id_str
= tmp_id
.c_str();
13000 str
= mputprintf(str
, "{\n"
13001 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
13002 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
13004 str
= field_v
->generate_code_init(str
, tmp_id_str
);
13005 str
= mputstr(str
, "}\n");
13007 char *embedded_name
= mprintf("%s.%s()", name
,
13009 if (cf
->get_is_optional() && field_v
->is_compound())
13010 embedded_name
= mputstr(embedded_name
, "()");
13011 str
= field_v
->generate_code_init(str
, embedded_name
);
13012 Free(embedded_name
);
13015 // the value is omit
13016 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
13021 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
13026 char *Value::generate_code_init_refd(char *str
, const char *name
)
13028 Value
*v
= get_value_refd_last();
13030 // the referred value is not available at compile time
13031 // the code generation is based on the reference
13032 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
13033 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
13035 expression_struct expr
;
13036 Code::init_expr(&expr
);
13037 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
13038 u
.ref
.ref
->generate_code_const_ref(&expr
);
13039 str
= Code::merge_free_expr(str
, &expr
);
13042 // the referred value is available at compile time
13043 // the code generation is based on the referred value
13044 if (v
->has_single_expr() &&
13045 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
13046 // simple substitution for in-line values within the same module
13047 str
= mputprintf(str
, "%s = %s;\n", name
,
13048 v
->get_single_expr().c_str());
13050 // use a simple reference to reduce code size
13051 if (needs_init_precede(v
)) {
13052 // the referred value must be initialized first
13053 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
13054 // temporary id should be introduced for the lhs
13055 const string
& tmp_id
= get_temporary_id();
13056 const char *tmp_id_str
= tmp_id
.c_str();
13057 str
= mputprintf(str
, "{\n"
13059 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13060 tmp_id_str
, v
->get_lhs_name().c_str());
13061 str
= v
->generate_code_init(str
, tmp_id_str
);
13062 str
= mputstr(str
, "}\n");
13064 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
13067 str
= mputprintf(str
, "%s = %s;\n", name
,
13068 v
->get_genname_own(my_scope
).c_str());
13074 void Value::generate_json_value(JSON_Tokenizer
& json
,
13075 bool allow_special_float
, /* = true */
13076 bool union_value_list
, /* = false */
13077 Ttcn::JsonOmitCombination
* omit_combo
/* = NULL */)
13079 switch (valuetype
) {
13081 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
13084 Real r
= get_val_Real();
13085 if (r
== REAL_INFINITY
) {
13086 if (allow_special_float
) {
13087 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
13090 else if (r
== -REAL_INFINITY
) {
13091 if (allow_special_float
) {
13092 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
13096 if (allow_special_float
) {
13097 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
13101 // true if decimal representation possible (use %f format)
13102 bool decimal_repr
= (r
== 0.0)
13103 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
13104 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
13105 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
13106 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
13111 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
13117 char* str
= convert_to_json_string(get_val_str().c_str());
13118 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13122 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13123 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13128 json
.put_next_token(JSON_TOKEN_STRING
,
13129 (string('\"') + create_stringRepr() + string('\"')).c_str());
13133 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
13134 if (!u
.val_vs
->is_indexed()) {
13135 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
13136 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
, allow_special_float
,
13137 union_value_list
, omit_combo
);
13141 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
13142 // look for the entry with index equal to i
13143 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
13144 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
13145 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
,
13146 allow_special_float
, union_value_list
, omit_combo
);
13152 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
13156 // omitted fields have 2 possible JSON values (the field is absent, or it's
13157 // present with value 'null'), each combination of omitted values must be
13159 if (omit_combo
== NULL
) {
13160 FATAL_ERROR("Value::generate_json_value - no combo");
13162 size_t len
= get_nof_comps();
13163 // generate the JSON object from the present combination
13164 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13165 for (size_t i
= 0; i
< len
; ++i
) {
13166 Ttcn::JsonOmitCombination::omit_state_t state
= omit_combo
->get_state(this, i
);
13167 if (state
== Ttcn::JsonOmitCombination::OMITTED_ABSENT
) {
13168 // the field is absent, don't insert anything
13171 // use the field's alias, if it has one
13172 const char* alias
= NULL
;
13173 if (my_governor
!= NULL
) {
13174 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13175 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
13176 if (field_attrib
!= NULL
) {
13177 alias
= field_attrib
->alias
;
13180 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13181 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
13182 if (state
== Ttcn::JsonOmitCombination::OMITTED_NULL
) {
13183 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
13186 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
,
13187 allow_special_float
, union_value_list
, omit_combo
);
13190 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13193 bool as_value
= !union_value_list
&& my_governor
!= NULL
&&
13194 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
13195 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
13197 // no 'as value' coding instruction, insert an object with one field
13198 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13199 // use the field's alias, if it has one
13200 const char* alias
= NULL
;
13201 if (my_governor
!= NULL
) {
13202 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13203 get_alt_name())->get_type()->get_json_attributes();
13204 if (field_attrib
!= NULL
) {
13205 alias
= field_attrib
->alias
;
13208 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13209 get_alt_name().get_ttcnname().c_str());
13211 get_alt_value()->generate_json_value(json
, allow_special_float
,
13212 union_value_list
, omit_combo
);
13214 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13218 Value
* v
= get_value_refd_last();
13220 v
->generate_json_value(json
, allow_special_float
, union_value_list
, omit_combo
);
13225 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
13229 bool Value::explicit_cast_needed(bool forIsValue
)
13231 Value
*v_last
= get_value_refd_last();
13232 if (v_last
!= this) {
13233 // this is a foldable referenced value
13234 // if the reference points to an imported or compound value the code
13235 // generation will be based on the reference so cast is not needed
13236 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
13237 || !v_last
->has_single_expr()) return false;
13238 } else if (v_last
->valuetype
== V_REFD
) {
13239 // this is an unfoldable reference (v_last==this)
13240 // explicit cast is needed only for string element references
13241 if (forIsValue
) return false;
13242 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
13243 return t_subrefs
&& t_subrefs
->refers_to_string_element();
13245 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
13246 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
13247 switch (t_governor
->get_typetype()) {
13251 case Type::T_INT_A
:
13253 case Type::T_ENUM_A
:
13254 case Type::T_ENUM_T
:
13255 case Type::T_VERDICT
:
13256 case Type::T_COMPONENT
:
13257 // these are mapped to built-in C/C++ types
13259 case Type::T_SEQ_A
:
13260 case Type::T_SEQ_T
:
13261 case Type::T_SET_A
:
13262 case Type::T_SET_T
:
13263 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13264 return t_governor
->get_nof_comps() == 0;
13265 case Type::T_SEQOF
:
13266 case Type::T_SETOF
:
13267 // the C++ equivalent of value {} is ambiguous
13270 case Type::T_FUNCTION
:
13271 case Type::T_ALTSTEP
:
13272 case Type::T_TESTCASE
:
13279 bool Value::has_single_expr()
13281 if (get_needs_conversion()) return false;
13282 switch (valuetype
) {
13284 return has_single_expr_expr();
13287 // a union or array value cannot be represented as an in-line expression
13291 // only an empty record/set of value can be represented as an in-line
13293 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
13294 else return u
.val_vs
->get_nof_ivs() == 0;
13297 // only a value for an empty record/set type can be represented as an
13298 // in-line expression
13299 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
13300 Type
*type
= my_governor
->get_type_refd_last();
13301 return type
->get_nof_comps() == 0; }
13303 Value
*v_last
= get_value_refd_last();
13304 // If the above call hit an error and set_valuetype(V_ERROR),
13305 // then u.ref.ref has been freed. Avoid the segfault.
13306 if (valuetype
== V_ERROR
)
13308 if (v_last
!= this && v_last
->has_single_expr() &&
13309 v_last
->my_scope
->get_scope_mod_gen() ==
13310 my_scope
->get_scope_mod_gen()) return true;
13311 else return u
.ref
.ref
->has_single_expr(); }
13313 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
13317 case V_UNDEF_LOWERID
:
13318 case V_UNDEF_BLOCK
:
13320 // these values cannot occur during code generation
13321 FATAL_ERROR("Value::has_single_expr()");
13323 return u
.val_Int
->is_native_fit();
13325 // should only happen when generating code for an unbound record/set value
13328 // other value types (literal values) do not need temporary reference
13333 string
Value::get_single_expr()
13335 switch (valuetype
) {
13337 return string("ASN_NULL_VALUE");
13339 return string(u
.val_bool
? "TRUE" : "FALSE");
13341 if (u
.val_Int
->is_native_fit()) { // Be sure.
13342 return u
.val_Int
->t_str();
13344 // get_single_expr may be called only if has_single_expr() is true.
13345 // The only exception is V_INT, where get_single_expr may be called
13346 // even if is_native_fit (which is used to implement has_single_expr)
13348 string
ret_val('"');
13349 ret_val
+= u
.val_Int
->t_str();
13354 return Real2code(u
.val_Real
);
13356 return get_single_expr_enum();
13358 return get_my_scope()->get_scope_mod_gen()
13359 ->add_bitstring_literal(*u
.str
.val_str
);
13361 return get_my_scope()->get_scope_mod_gen()
13362 ->add_hexstring_literal(*u
.str
.val_str
);
13364 return get_my_scope()->get_scope_mod_gen()
13365 ->add_octetstring_literal(*u
.str
.val_str
);
13367 return get_my_scope()->get_scope_mod_gen()
13368 ->add_charstring_literal(*u
.str
.val_str
);
13370 if (u
.ustr
.convert_str
) {
13371 set_valuetype(V_CSTR
);
13372 return get_my_scope()->get_scope_mod_gen()
13373 ->add_charstring_literal(*u
.str
.val_str
);
13375 return get_my_scope()->get_scope_mod_gen()
13376 ->add_ustring_literal(*u
.ustr
.val_ustr
);
13378 return get_single_expr_iso2022str();
13381 vector
<string
> comps
;
13382 bool is_constant
= get_oid_comps(comps
);
13383 size_t nof_comps
= comps
.size();
13385 for (size_t i
= 0; i
< nof_comps
; i
++) {
13386 if (i
> 0) oi_str
+= ", ";
13387 oi_str
+= *(comps
[i
]);
13389 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
13392 // the objid only contains constants
13393 // => create a literal and return its name
13394 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
13396 // the objid contains at least one variable
13397 // => append the number of components before the component values in the string and return it
13398 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
13401 if (u
.val_vs
->get_nof_vs() > 0)
13402 FATAL_ERROR("Value::get_single_expr()");
13403 return string("NULL_VALUE");
13406 if (u
.val_nvs
->get_nof_nvs() > 0)
13407 FATAL_ERROR("Value::get_single_expr()");
13408 return string("NULL_VALUE");
13410 Value
*v_last
= get_value_refd_last();
13411 if (v_last
!= this && v_last
->has_single_expr() &&
13412 v_last
->my_scope
->get_scope_mod_gen() ==
13413 my_scope
->get_scope_mod_gen()) {
13414 // the reference points to another single value in the same module
13415 return v_last
->get_single_expr();
13417 // convert the reference to a single expression
13418 expression_struct expr
;
13419 Code::init_expr(&expr
);
13420 u
.ref
.ref
->generate_code_const_ref(&expr
);
13421 if (expr
.preamble
|| expr
.postamble
)
13422 FATAL_ERROR("Value::get_single_expr()");
13423 string
ret_val(expr
.expr
);
13424 Code::free_expr(&expr
);
13428 return string("OMIT_VALUE");
13430 switch (u
.verdict
) {
13432 return string("NONE");
13434 return string("PASS");
13435 case Verdict_INCONC
:
13436 return string("INCONC");
13438 return string("FAIL");
13439 case Verdict_ERROR
:
13440 return string("ERROR");
13442 FATAL_ERROR("Value::get_single_expr()");
13445 case V_DEFAULT_NULL
:
13446 return string("NULL_COMPREF");
13448 string
ret_val('(');
13449 ret_val
+= my_governor
->get_genname_value(my_scope
);
13450 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13454 expression_struct expr
;
13455 Code::init_expr(&expr
);
13456 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13457 else generate_code_expr_invoke(&expr
);
13458 if (expr
.preamble
|| expr
.postamble
)
13459 FATAL_ERROR("Value::get_single_expr()");
13460 string
ret_val(expr
.expr
);
13461 Code::free_expr(&expr
);
13465 case MACRO_TESTCASEID
:
13466 return string("TTCN_Runtime::get_testcase_id_macro()");
13468 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13474 return get_single_expr_fat();
13476 FATAL_ERROR("Value::get_single_expr()");
13481 bool Value::has_single_expr_expr()
13483 switch (u
.expr
.v_optype
) {
13484 case OPTYPE_RND
: // -
13485 case OPTYPE_COMP_NULL
:
13486 case OPTYPE_COMP_MTC
:
13487 case OPTYPE_COMP_SYSTEM
:
13488 case OPTYPE_COMP_SELF
:
13489 case OPTYPE_COMP_RUNNING_ANY
:
13490 case OPTYPE_COMP_RUNNING_ALL
:
13491 case OPTYPE_COMP_ALIVE_ANY
:
13492 case OPTYPE_COMP_ALIVE_ALL
:
13493 case OPTYPE_TMR_RUNNING_ANY
:
13494 case OPTYPE_GETVERDICT
:
13495 case OPTYPE_TESTCASENAME
:
13496 case OPTYPE_PROF_RUNNING
:
13498 case OPTYPE_ENCODE
:
13499 case OPTYPE_DECODE
:
13500 case OPTYPE_ISBOUND
:
13501 case OPTYPE_ISPRESENT
:
13502 case OPTYPE_TTCN2STRING
:
13503 case OPTYPE_ENCVALUE_UNICHAR
:
13504 case OPTYPE_DECVALUE_UNICHAR
:
13506 case OPTYPE_UNARYPLUS
: // v1
13507 case OPTYPE_UNARYMINUS
:
13510 case OPTYPE_BIT2HEX
:
13511 case OPTYPE_BIT2INT
:
13512 case OPTYPE_BIT2OCT
:
13513 case OPTYPE_BIT2STR
:
13514 case OPTYPE_CHAR2INT
:
13515 case OPTYPE_CHAR2OCT
:
13516 case OPTYPE_FLOAT2INT
:
13517 case OPTYPE_FLOAT2STR
:
13518 case OPTYPE_HEX2BIT
:
13519 case OPTYPE_HEX2INT
:
13520 case OPTYPE_HEX2OCT
:
13521 case OPTYPE_HEX2STR
:
13522 case OPTYPE_INT2CHAR
:
13523 case OPTYPE_INT2FLOAT
:
13524 case OPTYPE_INT2STR
:
13525 case OPTYPE_INT2UNICHAR
:
13526 case OPTYPE_OCT2BIT
:
13527 case OPTYPE_OCT2CHAR
:
13528 case OPTYPE_OCT2HEX
:
13529 case OPTYPE_OCT2INT
:
13530 case OPTYPE_OCT2STR
:
13531 case OPTYPE_STR2BIT
:
13532 case OPTYPE_STR2FLOAT
:
13533 case OPTYPE_STR2HEX
:
13534 case OPTYPE_STR2INT
:
13535 case OPTYPE_STR2OCT
:
13536 case OPTYPE_UNICHAR2INT
:
13537 case OPTYPE_UNICHAR2CHAR
:
13538 case OPTYPE_ENUM2INT
:
13539 case OPTYPE_RNDWITHVAL
:
13540 case OPTYPE_ISCHOSEN_V
: // v1 i2
13541 case OPTYPE_COMP_RUNNING
:
13542 case OPTYPE_COMP_ALIVE
:
13543 case OPTYPE_GET_STRINGENCODING
:
13544 case OPTYPE_REMOVE_BOM
:
13545 case OPTYPE_DECODE_BASE64
:
13546 return u
.expr
.v1
->has_single_expr();
13547 case OPTYPE_ISCHOSEN_T
: // t1 i2
13548 return u
.expr
.t1
->has_single_expr();
13549 case OPTYPE_ADD
: // v1 v2
13550 case OPTYPE_SUBTRACT
:
13551 case OPTYPE_MULTIPLY
:
13552 case OPTYPE_DIVIDE
:
13555 case OPTYPE_CONCAT
:
13570 case OPTYPE_INT2BIT
:
13571 case OPTYPE_INT2HEX
:
13572 case OPTYPE_INT2OCT
:
13573 return u
.expr
.v1
->has_single_expr() &&
13574 u
.expr
.v2
->has_single_expr();
13575 case OPTYPE_UNICHAR2OCT
:
13576 case OPTYPE_OCT2UNICHAR
:
13577 case OPTYPE_ENCODE_BASE64
:
13578 return u
.expr
.v1
->has_single_expr() &&
13579 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13582 return u
.expr
.v1
->has_single_expr() &&
13583 u
.expr
.v2
->has_single_expr() &&
13584 !u
.expr
.v2
->needs_short_circuit();
13585 case OPTYPE_SUBSTR
:
13586 return u
.expr
.ti1
->has_single_expr() &&
13587 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13588 case OPTYPE_REGEXP
:
13589 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13590 u
.expr
.v3
->has_single_expr();
13591 case OPTYPE_DECOMP
: // v1 v2 v3
13592 return u
.expr
.v1
->has_single_expr() &&
13593 u
.expr
.v2
->has_single_expr() &&
13594 u
.expr
.v3
->has_single_expr();
13595 case OPTYPE_REPLACE
:
13596 return u
.expr
.ti1
->has_single_expr() &&
13597 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13598 u
.expr
.ti4
->has_single_expr();
13599 case OPTYPE_ISVALUE
: // ti1
13600 case OPTYPE_LENGTHOF
: // ti1
13601 case OPTYPE_SIZEOF
: // ti1
13602 case OPTYPE_VALUEOF
: // ti1
13603 return u
.expr
.ti1
->has_single_expr();
13604 case OPTYPE_LOG2STR
:
13605 case OPTYPE_ANY2UNISTR
:
13606 return u
.expr
.logargs
->has_single_expr();
13607 case OPTYPE_MATCH
: // v1 t2
13608 return u
.expr
.v1
->has_single_expr() &&
13609 u
.expr
.t2
->has_single_expr();
13610 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13611 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13612 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13613 case OPTYPE_TMR_READ
: // r1
13614 case OPTYPE_TMR_RUNNING
:
13615 case OPTYPE_ACTIVATE
:
13616 return u
.expr
.r1
->has_single_expr();
13617 case OPTYPE_EXECUTE
: // r1 [v2]
13618 return u
.expr
.r1
->has_single_expr() &&
13619 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13620 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13621 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13622 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13623 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13624 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13626 FATAL_ERROR("Value::has_single_expr_expr()");
13630 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13632 if (!v
->has_single_expr()) return false;
13633 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13634 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13638 string
Value::get_single_expr_enum()
13640 string
ret_val(my_governor
->get_genname_value(my_scope
));
13642 ret_val
+= u
.val_id
->get_name();
13646 string
Value::get_single_expr_iso2022str()
13649 Type
*type
= get_my_governor()->get_type_refd_last();
13650 switch (type
->get_typetype()) {
13651 case Type::T_TELETEXSTRING
:
13652 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13654 case Type::T_VIDEOTEXSTRING
:
13655 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13657 case Type::T_GRAPHICSTRING
:
13658 case Type::T_OBJECTDESCRIPTOR
:
13659 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13661 case Type::T_GENERALSTRING
:
13662 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13665 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13668 string
*ostr
= char2oct(*u
.str
.val_str
);
13669 ret_val
+= get_my_scope()->get_scope_mod_gen()
13670 ->add_octetstring_literal(*ostr
);
13676 string
Value::get_single_expr_fat()
13678 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13679 // the ampersand operator is not really necessary to obtain the function
13680 // pointer, but some older versions of GCC cannot instantiate the
13681 // appropriate operator=() member of class OPTIONAL when necessary
13682 // if only the function name is given
13683 string
ret_val('&');
13684 switch (valuetype
) {
13686 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13689 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13690 ret_val
+= "_instance";
13693 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13696 FATAL_ERROR("Value::get_single_expr_fat()");
13701 bool Value::is_compound()
13703 switch (valuetype
) {
13716 bool Value::needs_temp_ref()
13718 switch (valuetype
) {
13721 if (!is_indexed()) {
13722 // Temporary reference is needed if the value has at least one real
13723 // element (i.e. it is not empty or contains only not used symbols).
13724 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13725 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13728 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13729 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13730 ->valuetype
!= V_NOTUSED
)
13736 size_t nof_real_vs
= 0;
13737 if (!is_indexed()) {
13738 // Temporary reference is needed if the array value has at least two
13739 // real elements (excluding not used symbols).
13740 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13741 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13743 if (nof_real_vs
> 1) return true;
13747 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13748 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13749 ->valuetype
!= V_NOTUSED
) {
13751 if (nof_real_vs
> 1) return true;
13759 // it depends on the type since fields with omit or default value
13760 // may not be present
13761 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13763 // incomplete values are allowed in TTCN-3
13764 // we should check the number of value components
13765 return u
.val_nvs
->get_nof_nvs() > 1;
13770 case V_UNDEF_LOWERID
:
13771 case V_UNDEF_BLOCK
:
13773 // these values cannot occur during code generation
13774 FATAL_ERROR("Value::needs_temp_ref()");
13776 return !u
.val_Int
->is_native();
13778 // other value types (literal values) do not need temporary reference
13783 bool Value::needs_short_circuit()
13785 switch (valuetype
) {
13793 // sub-expressions should be evaluated only if necessary
13796 FATAL_ERROR("Value::needs_short_circuit()");
13798 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13799 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13800 switch (t_ass
->get_asstype()) {
13801 case Assignment::A_FUNCTION_RVAL
:
13802 case Assignment::A_EXT_FUNCTION_RVAL
:
13803 // avoid unnecessary call of a function
13805 case Assignment::A_CONST
:
13806 case Assignment::A_EXT_CONST
:
13807 case Assignment::A_MODULEPAR
:
13808 case Assignment::A_VAR
:
13809 case Assignment::A_PAR_VAL_IN
:
13810 case Assignment::A_PAR_VAL_OUT
:
13811 case Assignment::A_PAR_VAL_INOUT
:
13812 // depends on field/array sub-references, which is examined below
13815 FATAL_ERROR("Value::needs_short_circuit()");
13817 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13819 // the evaluation of the reference does not have side effects
13820 // (i.e. false shall be returned) only if all sub-references point to
13821 // mandatory fields of record/set types, and neither sub-reference points
13822 // to a field of a union type
13823 Type
*t_type
= t_ass
->get_Type();
13824 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13825 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13826 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13827 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13828 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13829 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13830 t_cf
->get_is_optional()) return true;
13831 t_type
= t_cf
->get_type();
13832 } else return true;
13838 void Value::dump(unsigned level
) const
13840 switch (valuetype
) {
13864 case V_DEFAULT_NULL
:
13872 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13876 DEBUG(level
, "Value: reference");
13877 u
.ref
.ref
->dump(level
+ 1);
13879 case V_UNDEF_LOWERID
:
13880 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13882 case V_UNDEF_BLOCK
:
13883 DEBUG(level
, "Value: {block}");
13886 DEBUG(level
, "Value: null");
13889 DEBUG(level
, "Value: invoke");
13890 u
.invoke
.v
->dump(level
+ 1);
13891 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13892 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13895 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13899 void Value::add_string_element(size_t index
, Value
*v_element
,
13900 map
<size_t, Value
>*& string_elements
)
13902 v_element
->set_my_scope(get_my_scope());
13903 v_element
->set_my_governor(get_my_governor());
13904 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13905 v_element
->set_location(*this);
13906 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13907 string_elements
->add(index
, v_element
);
13910 ///////////////////////////////////////////////////////////////////////////////
13911 // class LazyParamData
13913 int LazyParamData::depth
= 0;
13914 bool LazyParamData::used_as_lvalue
= false;
13915 vector
<string
>* LazyParamData::type_vec
= NULL
;
13916 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13918 void LazyParamData::init(bool p_used_as_lvalue
) {
13919 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13921 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13922 used_as_lvalue
= p_used_as_lvalue
;
13923 type_vec
= new vector
<string
>;
13924 refd_vec
= new vector
<string
>;
13929 void LazyParamData::clean() {
13930 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13931 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13934 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13939 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13947 bool LazyParamData::in_lazy() {
13948 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13952 // returns a temporary id instead of the C++ reference to a definition
13953 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13954 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13955 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13956 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13957 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13958 // store the type of the assignment
13959 string
* type_str
= new string
;
13960 switch (ass
->get_asstype()) {
13961 case Assignment::A_MODULEPAR_TEMP
:
13962 case Assignment::A_TEMPLATE
:
13963 case Assignment::A_VAR_TEMPLATE
:
13964 case Assignment::A_PAR_TEMPL_IN
:
13965 case Assignment::A_PAR_TEMPL_OUT
:
13966 case Assignment::A_PAR_TEMPL_INOUT
:
13967 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13970 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13972 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13973 bool refd_ass_is_lazy_fpar
= false;
13974 switch (ass
->get_asstype()) {
13975 case Assignment::A_PAR_VAL
:
13976 case Assignment::A_PAR_VAL_IN
:
13977 case Assignment::A_PAR_TEMPL_IN
:
13978 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13979 if (refd_ass_is_lazy_fpar
) {
13980 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13986 // add the "const" part if the referenced assignment is a constant thing
13987 if (!refd_ass_is_lazy_fpar
) {
13988 switch (ass
->get_asstype()) {
13989 case Assignment::A_CONST
:
13990 case Assignment::A_OC
:
13991 case Assignment::A_OBJECT
:
13992 case Assignment::A_OS
:
13993 case Assignment::A_VS
:
13994 case Assignment::A_EXT_CONST
:
13995 case Assignment::A_MODULEPAR
:
13996 case Assignment::A_MODULEPAR_TEMP
:
13997 case Assignment::A_TEMPLATE
:
13998 case Assignment::A_PAR_VAL
:
13999 case Assignment::A_PAR_VAL_IN
:
14000 case Assignment::A_PAR_TEMPL_IN
:
14001 *type_str
= string("const ") + *type_str
;
14009 type_vec
->add(type_str
);
14010 // store the C++ reference string
14011 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
14012 if (refd_ass_is_lazy_fpar
) {
14013 Type
* refd_ass_type
= ass
->get_Type();
14014 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
);
14015 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
14017 return get_member_name(refd_vec
->size()-1);
14021 string
LazyParamData::get_member_name(size_t idx
) {
14022 return string("lpm_") + Int2string(idx
);
14025 string
LazyParamData::get_constr_param_name(size_t idx
) {
14026 return string("lpp_") + Int2string(idx
);
14029 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
14030 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14031 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
14032 const string
& tmp_id
= val
->get_temporary_id();
14033 const char *tmp_id_str
= tmp_id
.c_str();
14034 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14035 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
14037 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14039 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14041 val
->generate_code_expr(expr
);
14045 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
14046 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14047 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
14048 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
14049 const char *tmp_id_str
= tmp_id
.c_str();
14050 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14051 temp
->get_Template()->get_my_governor()
14052 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
14053 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14054 tmp_id_str
, temp
->get_Template());
14055 // Not incorporated into gen_conv_code() yet.
14056 if (gen_restriction_check
!= TR_NONE
)
14057 expr
->preamble
= Template::generate_restriction_check_code(
14058 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
14059 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14060 } else temp
->generate_code(expr
, gen_restriction_check
);
14063 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14064 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14066 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14067 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14068 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14069 expression_struct value_expr
;
14070 Code::init_expr(&value_expr
);
14071 generate_code_for_value(&value_expr
, value
, scope
);
14072 // the id of the instance of Lazy_Param which will be used as the actual parameter
14073 const string
& lazy_param_id
= value
->get_temporary_id();
14074 if (value_expr
.preamble
) {
14075 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
14077 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14078 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14079 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
14080 Code::free_expr(&value_expr
);
14081 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14084 // only if the formal parameter is *not* used as lvalue
14085 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
14086 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
14088 bool refd_ass_is_lazy_fpar
= false;
14089 switch (refd_ass
->get_asstype()) {
14090 case Assignment::A_PAR_VAL
:
14091 case Assignment::A_PAR_VAL_IN
:
14092 case Assignment::A_PAR_TEMPL_IN
:
14093 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14098 if (refd_ass_is_lazy_fpar
) {
14099 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14104 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14105 expression_struct value_expr
;
14106 Code::init_expr(&value_expr
);
14107 generate_code_for_value(&value_expr
, value
, scope
);
14108 // the id of the instance of Lazy_Param which will be used as the actual parameter
14109 string lazy_param_id
= value
->get_temporary_id();
14110 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
14111 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
14114 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
14115 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14117 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14118 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14119 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14120 expression_struct tmpl_expr
;
14121 Code::init_expr(&tmpl_expr
);
14122 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14123 // the id of the instance of Lazy_Param which will be used as the actual parameter
14124 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
14125 if (tmpl_expr
.preamble
) {
14126 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
14128 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14129 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14130 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
14131 Code::free_expr(&tmpl_expr
);
14132 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14135 // only if the formal parameter is *not* used as lvalue
14136 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
14137 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
14139 bool refd_ass_is_lazy_fpar
= false;
14140 switch (refd_ass
->get_asstype()) {
14141 case Assignment::A_PAR_VAL
:
14142 case Assignment::A_PAR_VAL_IN
:
14143 case Assignment::A_PAR_TEMPL_IN
:
14144 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14149 if (refd_ass_is_lazy_fpar
) {
14150 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14155 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14156 expression_struct tmpl_expr
;
14157 Code::init_expr(&tmpl_expr
);
14158 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14159 // the id of the instance of Lazy_Param which will be used as the actual parameter
14160 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
14161 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
14162 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
14165 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
14166 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
14167 if (type_vec
->size()>0) {
14168 // private members of the local class will be const references to the objects referenced by the expression
14169 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14170 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
14172 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
14173 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
14174 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14175 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14176 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
14178 expr
->preamble
= mputstr(expr
->preamble
, "): ");
14179 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14180 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14181 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
14183 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
14184 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
14186 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
14187 // use the temporary expr structure to fill the body of the eval_expr() function
14188 if (param_expr
.preamble
) {
14189 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
14191 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
14192 if (param_expr
.postamble
) {
14193 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
14195 Code::free_expr(¶m_expr
);
14196 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
14197 "};\n" // end of local class definition
14199 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
14200 if (type_vec
->size()>0) {
14201 expr
->preamble
= mputc(expr
->preamble
, '(');
14202 // paramteres of the constructor are references to the objects used in the expression
14203 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
14204 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14205 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
14207 expr
->preamble
= mputc(expr
->preamble
, ')');
14209 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
14210 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14211 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
14214 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
14215 expression_struct ref_expr
;
14216 Code::init_expr(&ref_expr
);
14217 ref
->generate_code(&ref_expr
);
14218 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
14219 if (ref_expr
.preamble
) {
14220 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
14222 Assignment
* ass
= ref
->get_refd_assignment();
14223 // determine C++ type of the assignment
14225 switch (ass
->get_asstype()) {
14226 case Assignment::A_MODULEPAR_TEMP
:
14227 case Assignment::A_TEMPLATE
:
14228 case Assignment::A_VAR_TEMPLATE
:
14229 case Assignment::A_PAR_TEMPL_IN
:
14230 case Assignment::A_PAR_TEMPL_OUT
:
14231 case Assignment::A_PAR_TEMPL_INOUT
:
14232 type_str
= ass
->get_Type()->get_genname_template(scope
);
14235 type_str
= ass
->get_Type()->get_genname_value(scope
);
14237 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14238 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
14239 if (ref_expr
.postamble
) {
14240 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
14242 Code::free_expr(&ref_expr
);
14243 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14246 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14247 const string
& lazy_param_id
= value
->get_temporary_id();
14248 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14249 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14250 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
14251 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14254 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
14255 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
14256 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14257 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14258 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
14259 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14262 } // namespace Common