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_CHECKSTATE_ANY
: // [r1] v2
302 case OPTYPE_CHECKSTATE_ALL
:
303 u
.expr
.r1
=p
.u
.expr
.r1
?p
.u
.expr
.r1
->clone():0;
304 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
306 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
307 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
308 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
309 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
310 u
.expr
.b4
= p
.u
.expr
.b4
;
312 case OPTYPE_MATCH
: // v1 t2
313 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
314 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
316 case OPTYPE_ISCHOSEN
: // r1 i2
317 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
318 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
320 case OPTYPE_ISCHOSEN_V
: // v1 i2
321 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
322 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
324 case OPTYPE_ISCHOSEN_T
: // t1 i2
325 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
326 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
328 case OPTYPE_ACTIVATE_REFD
:
329 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
330 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
331 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
333 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
334 u
.expr
.state
= EXPR_CHECKED
;
337 case OPTYPE_EXECUTE_REFD
:
338 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
339 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
340 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
342 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
343 u
.expr
.state
= EXPR_CHECKED
;
345 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
348 case OPTYPE_ANY2UNISTR
:
349 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
352 FATAL_ERROR("Value::Value()");
361 u
.refd_fat
= p
.u
.refd_fat
;
364 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
365 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
366 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
369 u
.refered
= p
.u
.refered
->clone();
372 FATAL_ERROR("Value::Value()");
376 void Value::clean_up()
399 case V_UNDEF_LOWERID
:
407 delete u
.str
.val_str
;
408 clean_up_string_elements(u
.str
.str_elements
);
411 delete u
.ustr
.val_ustr
;
412 clean_up_string_elements(u
.ustr
.ustr_elements
);
420 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
421 delete (*u
.oid_comps
)[i
];
422 u
.oid_comps
->clear();
430 delete u
.choice
.alt_name
;
431 delete u
.choice
.alt_value
;
450 delete u
.invoke
.t_list
;
451 delete u
.invoke
.ap_list
;
455 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
464 FATAL_ERROR("Value::clean_up()");
468 void Value::clean_up_expr()
470 switch (u
.expr
.state
) {
472 case EXPR_CHECKING_ERR
:
473 FATAL_ERROR("Value::clean_up_expr()");
477 switch (u
.expr
.v_optype
) {
478 case OPTYPE_RND
: // -
479 case OPTYPE_COMP_NULL
:
480 case OPTYPE_COMP_MTC
:
481 case OPTYPE_COMP_SYSTEM
:
482 case OPTYPE_COMP_SELF
:
483 case OPTYPE_COMP_RUNNING_ANY
:
484 case OPTYPE_COMP_RUNNING_ALL
:
485 case OPTYPE_COMP_ALIVE_ANY
:
486 case OPTYPE_COMP_ALIVE_ALL
:
487 case OPTYPE_TMR_RUNNING_ANY
:
488 case OPTYPE_GETVERDICT
:
489 case OPTYPE_TESTCASENAME
:
490 case OPTYPE_PROF_RUNNING
:
492 case OPTYPE_UNARYPLUS
: // v1
493 case OPTYPE_UNARYMINUS
:
500 case OPTYPE_CHAR2INT
:
501 case OPTYPE_CHAR2OCT
:
502 case OPTYPE_COMP_RUNNING
:
503 case OPTYPE_COMP_ALIVE
:
504 case OPTYPE_FLOAT2INT
:
505 case OPTYPE_FLOAT2STR
:
510 case OPTYPE_INT2CHAR
:
511 case OPTYPE_INT2FLOAT
:
513 case OPTYPE_INT2UNICHAR
:
515 case OPTYPE_OCT2CHAR
:
520 case OPTYPE_STR2FLOAT
:
524 case OPTYPE_UNICHAR2INT
:
525 case OPTYPE_UNICHAR2CHAR
:
526 case OPTYPE_ENUM2INT
:
527 case OPTYPE_RNDWITHVAL
:
528 case OPTYPE_REMOVE_BOM
:
529 case OPTYPE_GET_STRINGENCODING
:
530 case OPTYPE_DECODE_BASE64
:
533 case OPTYPE_ADD
: // v1 v2
534 case OPTYPE_SUBTRACT
:
535 case OPTYPE_MULTIPLY
:
559 case OPTYPE_UNICHAR2OCT
:
560 case OPTYPE_OCT2UNICHAR
:
561 case OPTYPE_ENCODE_BASE64
:
579 case OPTYPE_DECOMP
: // v1 v2 v3
590 case OPTYPE_LENGTHOF
: // ti1
591 case OPTYPE_SIZEOF
: // ti1
592 case OPTYPE_VALUEOF
: // ti1
596 case OPTYPE_ISPRESENT
:
597 case OPTYPE_TTCN2STRING
:
600 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
604 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
609 case OPTYPE_UNDEF_RUNNING
:
610 case OPTYPE_TMR_READ
:
611 case OPTYPE_TMR_RUNNING
:
612 case OPTYPE_ACTIVATE
:
615 case OPTYPE_EXECUTE
: // r1 [v2]
619 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
620 case OPTYPE_CHECKSTATE_ALL
:
624 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
629 case OPTYPE_MATCH
: // v1 t2
633 case OPTYPE_ISCHOSEN
: // r1 i2
637 case OPTYPE_ISCHOSEN_V
: // v1 i2
641 case OPTYPE_ISCHOSEN_T
: // t1 i2
645 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
647 if(u
.expr
.state
!=EXPR_CHECKED
)
648 delete u
.expr
.t_list2
;
650 delete u
.expr
.ap_list2
;
652 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
654 if(u
.expr
.state
!=EXPR_CHECKED
)
655 delete u
.expr
.t_list2
;
657 delete u
.expr
.ap_list2
;
661 case OPTYPE_ANY2UNISTR
:
662 delete u
.expr
.logargs
;
665 FATAL_ERROR("Value::clean_up_expr()");
669 void Value::copy_and_destroy(Value
*src
)
672 valuetype
= src
->valuetype
;
674 // update the pointer used for caching if it points to the value itself
675 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
676 src
->valuetype
= V_ERROR
;
680 Value::Value(valuetype_t p_vt
)
681 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
692 u
.oid_comps
=new vector
<OID_comp
>();
695 u
.ids
=new map
<string
, Identifier
>();
698 FATAL_ERROR("Value::Value()");
702 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
703 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
707 u
.val_bool
=p_val_bool
;
710 FATAL_ERROR("Value::Value()");
714 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
715 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
719 u
.val_Int
=new int_val_t(p_val_Int
);
722 FATAL_ERROR("Value::Value()");
726 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
727 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
734 FATAL_ERROR("Value::Value()");
738 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
739 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
741 if(!p_val_str
) FATAL_ERROR("NULL parameter");
748 set_val_str(p_val_str
);
751 FATAL_ERROR("Value::Value()");
755 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
756 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
758 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
759 set_val_ustr(p_val_ustr
);
760 u
.ustr
.convert_str
= false;
763 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
764 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
766 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
769 u
.char_syms
= p_char_syms
;
772 FATAL_ERROR("Value::Value()");
776 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
777 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
780 FATAL_ERROR("NULL parameter");
784 case V_UNDEF_LOWERID
:
788 FATAL_ERROR("Value::Value()");
792 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
793 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
796 FATAL_ERROR("NULL parameter");
799 u
.choice
.alt_name
=p_id
;
800 u
.choice
.alt_value
=p_val
;
803 FATAL_ERROR("Value::Value()");
807 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
808 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
812 u
.val_Real
=p_val_Real
;
815 FATAL_ERROR("Value::Value()");
819 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
820 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
822 if(!p_vs
) FATAL_ERROR("NULL parameter");
830 FATAL_ERROR("Value::Value()");
834 Value::Value(valuetype_t p_vt
, Value
*p_v
,
835 Ttcn::ParsedActualParameters
*p_t_list
)
836 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
838 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
842 u
.invoke
.t_list
= p_t_list
;
843 u
.invoke
.ap_list
= 0;
846 FATAL_ERROR("Value::Value()");
851 Value::Value(operationtype_t p_optype
)
852 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
854 u
.expr
.v_optype
= p_optype
;
855 u
.expr
.state
= EXPR_NOT_CHECKED
;
858 case OPTYPE_COMP_NULL
:
859 case OPTYPE_COMP_MTC
:
860 case OPTYPE_COMP_SYSTEM
:
861 case OPTYPE_COMP_SELF
:
862 case OPTYPE_COMP_RUNNING_ANY
:
863 case OPTYPE_COMP_RUNNING_ALL
:
864 case OPTYPE_COMP_ALIVE_ANY
:
865 case OPTYPE_COMP_ALIVE_ALL
:
866 case OPTYPE_TMR_RUNNING_ANY
:
867 case OPTYPE_GETVERDICT
:
868 case OPTYPE_TESTCASENAME
:
869 case OPTYPE_PROF_RUNNING
:
872 FATAL_ERROR("Value::Value()");
877 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
878 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
880 u
.expr
.v_optype
= p_optype
;
881 u
.expr
.state
= EXPR_NOT_CHECKED
;
883 case OPTYPE_UNARYPLUS
:
884 case OPTYPE_UNARYMINUS
:
891 case OPTYPE_CHAR2INT
:
892 case OPTYPE_CHAR2OCT
:
893 case OPTYPE_COMP_RUNNING
:
894 case OPTYPE_COMP_ALIVE
:
895 case OPTYPE_FLOAT2INT
:
896 case OPTYPE_FLOAT2STR
:
901 case OPTYPE_INT2CHAR
:
902 case OPTYPE_INT2FLOAT
:
904 case OPTYPE_INT2UNICHAR
:
906 case OPTYPE_OCT2CHAR
:
911 case OPTYPE_STR2FLOAT
:
915 case OPTYPE_UNICHAR2INT
:
916 case OPTYPE_UNICHAR2CHAR
:
917 case OPTYPE_ENUM2INT
:
918 case OPTYPE_RNDWITHVAL
:
919 case OPTYPE_REMOVE_BOM
:
920 case OPTYPE_GET_STRINGENCODING
:
921 case OPTYPE_DECODE_BASE64
:
922 if(!p_v1
) FATAL_ERROR("Value::Value()");
926 FATAL_ERROR("Value::Value()");
931 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
932 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
934 u
.expr
.v_optype
= p_optype
;
935 u
.expr
.state
= EXPR_NOT_CHECKED
;
937 case OPTYPE_LENGTHOF
:
943 case OPTYPE_ENCVALUE_UNICHAR
:
944 case OPTYPE_ISPRESENT
:
945 case OPTYPE_TTCN2STRING
:
946 if(!p_ti1
) FATAL_ERROR("Value::Value()");
950 FATAL_ERROR("Value::Value()");
955 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
956 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
958 u
.expr
.v_optype
= p_optype
;
959 u
.expr
.state
= EXPR_NOT_CHECKED
;
961 case OPTYPE_UNDEF_RUNNING
:
962 case OPTYPE_TMR_READ
:
963 case OPTYPE_TMR_RUNNING
:
964 case OPTYPE_ACTIVATE
:
965 if(!p_r1
) FATAL_ERROR("Value::Value()");
969 FATAL_ERROR("Value::Value()");
974 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
975 Ttcn::ParsedActualParameters
*p_ap_list
)
976 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
978 u
.expr
.v_optype
= p_optype
;
979 u
.expr
.state
= EXPR_NOT_CHECKED
;
981 case OPTYPE_ACTIVATE_REFD
:
982 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
984 u
.expr
.t_list2
= p_ap_list
;
987 FATAL_ERROR("Value::Value()");
992 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
993 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
994 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
996 u
.expr
.v_optype
= p_optype
;
997 u
.expr
.state
= EXPR_NOT_CHECKED
;
999 case OPTYPE_EXECUTE_REFD
:
1000 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
1002 u
.expr
.t_list2
= p_t_list2
;
1006 FATAL_ERROR("Value::Value()");
1010 // r1 [v2] or [r1] v2
1011 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
1012 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1014 u
.expr
.v_optype
= p_optype
;
1015 u
.expr
.state
= EXPR_NOT_CHECKED
;
1017 case OPTYPE_EXECUTE
:
1018 if(!p_r1
) FATAL_ERROR("Value::Value()");
1022 case OPTYPE_CHECKSTATE_ANY
:
1023 case OPTYPE_CHECKSTATE_ALL
:
1024 if(!p_v2
) FATAL_ERROR("Value::Value()");
1025 u
.expr
.r1
=p_r1
; // may be null if any port or all port
1029 FATAL_ERROR("Value::Value()");
1034 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
1035 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
1036 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1038 u
.expr
.v_optype
= p_optype
;
1039 u
.expr
.state
= EXPR_NOT_CHECKED
;
1041 case OPTYPE_COMP_CREATE
:
1042 if(!p_r1
) FATAL_ERROR("Value::Value()");
1049 FATAL_ERROR("Value::Value()");
1054 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
1055 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1057 u
.expr
.v_optype
= p_optype
;
1058 u
.expr
.state
= EXPR_NOT_CHECKED
;
1061 case OPTYPE_SUBTRACT
:
1062 case OPTYPE_MULTIPLY
:
1083 case OPTYPE_INT2BIT
:
1084 case OPTYPE_INT2HEX
:
1085 case OPTYPE_INT2OCT
:
1086 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1090 case OPTYPE_UNICHAR2OCT
:
1091 case OPTYPE_OCT2UNICHAR
:
1092 case OPTYPE_ENCODE_BASE64
:
1093 if(!p_v1
) FATAL_ERROR("Value::Value()");
1095 // p_v2 may be NULL if there is no second param
1099 FATAL_ERROR("Value::Value()");
1104 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1105 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1106 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1108 u
.expr
.v_optype
= p_optype
;
1109 u
.expr
.state
= EXPR_NOT_CHECKED
;
1111 case OPTYPE_REPLACE
:
1112 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1119 FATAL_ERROR("Value::Value()");
1124 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1125 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1127 u
.expr
.v_optype
= p_optype
;
1128 u
.expr
.state
= EXPR_NOT_CHECKED
;
1131 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1137 FATAL_ERROR("Value::Value()");
1142 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
)
1143 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1145 u
.expr
.v_optype
= p_optype
;
1146 u
.expr
.state
= EXPR_NOT_CHECKED
;
1148 case OPTYPE_ENCVALUE_UNICHAR
:
1149 if(!p_ti1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1154 FATAL_ERROR("Value::Value()");
1159 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1160 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1162 u
.expr
.v_optype
=p_optype
;
1163 u
.expr
.state
=EXPR_NOT_CHECKED
;
1166 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1172 FATAL_ERROR("Value::Value()");
1177 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1178 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1180 u
.expr
.v_optype
=p_optype
;
1181 u
.expr
.state
=EXPR_NOT_CHECKED
;
1184 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1190 FATAL_ERROR("Value::Value()");
1195 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1196 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1198 u
.expr
.v_optype
= p_optype
;
1199 u
.expr
.state
= EXPR_NOT_CHECKED
;
1202 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1207 FATAL_ERROR("Value::Value()");
1212 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
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_ISCHOSEN
:
1220 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1225 FATAL_ERROR("Value::Value()");
1229 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1230 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1232 u
.expr
.v_optype
= p_optype
;
1233 u
.expr
.state
= EXPR_NOT_CHECKED
;
1235 case OPTYPE_LOG2STR
:
1236 case OPTYPE_ANY2UNISTR
:
1237 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1238 u
.expr
.logargs
= p_logargs
;
1241 FATAL_ERROR("Value::Value()");
1245 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1246 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1248 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1249 switch (p_macrotype
) {
1250 case MACRO_MODULEID
:
1251 case MACRO_FILENAME
:
1252 case MACRO_BFILENAME
:
1253 case MACRO_FILEPATH
:
1254 case MACRO_LINENUMBER
:
1255 case MACRO_LINENUMBER_C
:
1256 case MACRO_DEFINITIONID
:
1258 case MACRO_TESTCASEID
:
1261 FATAL_ERROR("Value::Value()");
1263 u
.macro
= p_macrotype
;
1266 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1267 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1269 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1276 FATAL_ERROR("Value::Value()");
1280 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1281 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1283 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1287 u
.ref
.refd_last
= 0;
1293 FATAL_ERROR("Value::Value()");
1297 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1298 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1300 if(!p_block
) FATAL_ERROR("NULL parameter");
1306 FATAL_ERROR("Value::Value()");
1310 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1311 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1313 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1314 switch (p_verdict
) {
1317 case Verdict_INCONC
:
1322 FATAL_ERROR("Value::Value()");
1324 u
.verdict
= p_verdict
;
1327 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1328 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1330 u
.expr
.v_optype
= p_optype
;
1331 u
.expr
.state
= EXPR_NOT_CHECKED
;
1334 case OPTYPE_DECVALUE_UNICHAR
:
1335 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1340 FATAL_ERROR("Value::Value()");
1345 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
,
1347 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1349 u
.expr
.v_optype
= p_optype
;
1350 u
.expr
.state
= EXPR_NOT_CHECKED
;
1352 case OPTYPE_DECVALUE_UNICHAR
:
1353 if(!p_r1
|| !p_r2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1359 FATAL_ERROR("Value::Value()");
1368 Value
*Value::clone() const
1370 return new Value(*this);
1373 Value::operationtype_t
Value::get_optype() const
1375 if(valuetype
!=V_EXPR
)
1376 FATAL_ERROR("Value::get_optype()");
1377 return u
.expr
.v_optype
;
1380 void Value::set_my_governor(Type
*p_gov
)
1383 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1387 Type
*Value::get_my_governor() const
1392 void Value::set_fullname(const string
& p_fullname
)
1394 GovernedSimple::set_fullname(p_fullname
);
1397 u
.char_syms
->set_fullname(p_fullname
);
1401 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1402 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1405 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1406 u
.choice
.alt_name
->get_dispname());
1411 u
.val_vs
->set_fullname(p_fullname
);
1415 u
.val_nvs
->set_fullname(p_fullname
);
1418 u
.ref
.ref
->set_fullname(p_fullname
);
1421 u
.refered
->set_fullname(p_fullname
);
1424 u
.invoke
.v
->set_fullname(p_fullname
);
1425 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1426 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1429 set_fullname_expr(p_fullname
);
1436 void Value::set_my_scope(Scope
*p_scope
)
1438 GovernedSimple::set_my_scope(p_scope
);
1441 u
.char_syms
->set_my_scope(p_scope
);
1445 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1446 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1449 u
.choice
.alt_value
->set_my_scope(p_scope
);
1454 u
.val_vs
->set_my_scope(p_scope
);
1458 u
.val_nvs
->set_my_scope(p_scope
);
1461 u
.ref
.ref
->set_my_scope(p_scope
);
1464 u
.refered
->set_my_scope(p_scope
);
1467 u
.invoke
.v
->set_my_scope(p_scope
);
1468 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1469 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1472 set_my_scope_expr(p_scope
);
1479 void Value::set_fullname_expr(const string
& p_fullname
)
1481 switch (u
.expr
.v_optype
) {
1482 case OPTYPE_RND
: // -
1483 case OPTYPE_COMP_NULL
:
1484 case OPTYPE_COMP_MTC
:
1485 case OPTYPE_COMP_SYSTEM
:
1486 case OPTYPE_COMP_SELF
:
1487 case OPTYPE_COMP_RUNNING_ANY
:
1488 case OPTYPE_COMP_RUNNING_ALL
:
1489 case OPTYPE_COMP_ALIVE_ANY
:
1490 case OPTYPE_COMP_ALIVE_ALL
:
1491 case OPTYPE_TMR_RUNNING_ANY
:
1492 case OPTYPE_GETVERDICT
:
1493 case OPTYPE_TESTCASENAME
:
1494 case OPTYPE_PROF_RUNNING
:
1496 case OPTYPE_UNARYPLUS
: // v1
1497 case OPTYPE_UNARYMINUS
:
1500 case OPTYPE_BIT2HEX
:
1501 case OPTYPE_BIT2INT
:
1502 case OPTYPE_BIT2OCT
:
1503 case OPTYPE_BIT2STR
:
1504 case OPTYPE_CHAR2INT
:
1505 case OPTYPE_CHAR2OCT
:
1506 case OPTYPE_COMP_RUNNING
:
1507 case OPTYPE_COMP_ALIVE
:
1508 case OPTYPE_FLOAT2INT
:
1509 case OPTYPE_FLOAT2STR
:
1510 case OPTYPE_HEX2BIT
:
1511 case OPTYPE_HEX2INT
:
1512 case OPTYPE_HEX2OCT
:
1513 case OPTYPE_HEX2STR
:
1514 case OPTYPE_INT2CHAR
:
1515 case OPTYPE_INT2FLOAT
:
1516 case OPTYPE_INT2STR
:
1517 case OPTYPE_INT2UNICHAR
:
1518 case OPTYPE_OCT2BIT
:
1519 case OPTYPE_OCT2CHAR
:
1520 case OPTYPE_OCT2HEX
:
1521 case OPTYPE_OCT2INT
:
1522 case OPTYPE_OCT2STR
:
1523 case OPTYPE_STR2BIT
:
1524 case OPTYPE_STR2FLOAT
:
1525 case OPTYPE_STR2HEX
:
1526 case OPTYPE_STR2INT
:
1527 case OPTYPE_STR2OCT
:
1528 case OPTYPE_UNICHAR2INT
:
1529 case OPTYPE_UNICHAR2CHAR
:
1530 case OPTYPE_ENUM2INT
:
1531 case OPTYPE_RNDWITHVAL
:
1532 case OPTYPE_REMOVE_BOM
:
1533 case OPTYPE_GET_STRINGENCODING
:
1534 case OPTYPE_DECODE_BASE64
:
1535 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1537 case OPTYPE_ADD
: // v1 v2
1538 case OPTYPE_SUBTRACT
:
1539 case OPTYPE_MULTIPLY
:
1560 case OPTYPE_INT2BIT
:
1561 case OPTYPE_INT2HEX
:
1562 case OPTYPE_INT2OCT
:
1563 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1564 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1566 case OPTYPE_UNICHAR2OCT
:
1567 case OPTYPE_OCT2UNICHAR
:
1568 case OPTYPE_ENCODE_BASE64
:
1569 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1570 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1573 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1574 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1577 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1578 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1579 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1582 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1583 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1584 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1586 case OPTYPE_DECOMP
: // v1 v2 v3
1587 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1588 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1589 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1591 case OPTYPE_REPLACE
:
1592 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1593 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1594 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1595 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1597 case OPTYPE_LENGTHOF
: // ti1
1598 case OPTYPE_SIZEOF
: // ti1
1599 case OPTYPE_VALUEOF
: // ti1
1600 case OPTYPE_ISVALUE
:
1601 case OPTYPE_ISBOUND
:
1603 case OPTYPE_ISPRESENT
:
1604 case OPTYPE_TTCN2STRING
:
1605 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1607 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
1608 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1609 if (u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1611 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1612 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1613 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1614 if (u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1615 case OPTYPE_UNDEF_RUNNING
: // r1
1616 case OPTYPE_TMR_READ
:
1617 case OPTYPE_TMR_RUNNING
:
1618 case OPTYPE_ACTIVATE
:
1619 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1621 case OPTYPE_EXECUTE
: // r1 [v2]
1622 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1623 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1625 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1626 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1627 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1628 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1630 case OPTYPE_MATCH
: // v1 t2
1631 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1632 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1634 case OPTYPE_ISCHOSEN
: // r1 i2
1635 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1637 case OPTYPE_ISCHOSEN_V
: // v1 i2
1638 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1640 case OPTYPE_ISCHOSEN_T
: // t1 i2
1641 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1643 case OPTYPE_ACTIVATE_REFD
:
1644 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1645 if(u
.expr
.state
!=EXPR_CHECKED
)
1646 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1648 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1650 case OPTYPE_EXECUTE_REFD
:
1651 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1652 if(u
.expr
.state
!=EXPR_CHECKED
)
1653 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1655 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1657 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1659 case OPTYPE_LOG2STR
:
1660 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1662 case OPTYPE_ANY2UNISTR
:
1663 u
.expr
.logargs
->set_fullname(p_fullname
+".<logarg>");
1665 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
1666 case OPTYPE_CHECKSTATE_ALL
:
1667 u
.expr
.v2
->set_fullname(p_fullname
+".<operand1>");
1670 FATAL_ERROR("Value::set_fullname_expr()");
1674 void Value::set_my_scope_expr(Scope
*p_scope
)
1676 switch (u
.expr
.v_optype
) {
1677 case OPTYPE_RND
: // -
1678 case OPTYPE_COMP_NULL
:
1679 case OPTYPE_COMP_MTC
:
1680 case OPTYPE_COMP_SYSTEM
:
1681 case OPTYPE_COMP_SELF
:
1682 case OPTYPE_COMP_RUNNING_ANY
:
1683 case OPTYPE_COMP_RUNNING_ALL
:
1684 case OPTYPE_COMP_ALIVE_ANY
:
1685 case OPTYPE_COMP_ALIVE_ALL
:
1686 case OPTYPE_TMR_RUNNING_ANY
:
1687 case OPTYPE_GETVERDICT
:
1688 case OPTYPE_TESTCASENAME
:
1689 case OPTYPE_PROF_RUNNING
:
1691 case OPTYPE_UNARYPLUS
: // v1
1692 case OPTYPE_UNARYMINUS
:
1695 case OPTYPE_BIT2HEX
:
1696 case OPTYPE_BIT2INT
:
1697 case OPTYPE_BIT2OCT
:
1698 case OPTYPE_BIT2STR
:
1699 case OPTYPE_CHAR2INT
:
1700 case OPTYPE_CHAR2OCT
:
1701 case OPTYPE_COMP_RUNNING
:
1702 case OPTYPE_COMP_ALIVE
:
1703 case OPTYPE_FLOAT2INT
:
1704 case OPTYPE_FLOAT2STR
:
1705 case OPTYPE_HEX2BIT
:
1706 case OPTYPE_HEX2INT
:
1707 case OPTYPE_HEX2OCT
:
1708 case OPTYPE_HEX2STR
:
1709 case OPTYPE_INT2CHAR
:
1710 case OPTYPE_INT2FLOAT
:
1711 case OPTYPE_INT2STR
:
1712 case OPTYPE_INT2UNICHAR
:
1713 case OPTYPE_OCT2BIT
:
1714 case OPTYPE_OCT2CHAR
:
1715 case OPTYPE_OCT2HEX
:
1716 case OPTYPE_OCT2INT
:
1717 case OPTYPE_OCT2STR
:
1718 case OPTYPE_STR2BIT
:
1719 case OPTYPE_STR2FLOAT
:
1720 case OPTYPE_STR2HEX
:
1721 case OPTYPE_STR2INT
:
1722 case OPTYPE_STR2OCT
:
1723 case OPTYPE_UNICHAR2INT
:
1724 case OPTYPE_UNICHAR2CHAR
:
1725 case OPTYPE_ENUM2INT
:
1726 case OPTYPE_RNDWITHVAL
:
1727 case OPTYPE_REMOVE_BOM
:
1728 case OPTYPE_GET_STRINGENCODING
:
1729 case OPTYPE_DECODE_BASE64
:
1730 u
.expr
.v1
->set_my_scope(p_scope
);
1732 case OPTYPE_ADD
: // v1 v2
1733 case OPTYPE_SUBTRACT
:
1734 case OPTYPE_MULTIPLY
:
1755 case OPTYPE_INT2BIT
:
1756 case OPTYPE_INT2HEX
:
1757 case OPTYPE_INT2OCT
:
1758 u
.expr
.v1
->set_my_scope(p_scope
);
1759 u
.expr
.v2
->set_my_scope(p_scope
);
1761 case OPTYPE_UNICHAR2OCT
:
1762 case OPTYPE_OCT2UNICHAR
:
1763 case OPTYPE_ENCODE_BASE64
:
1764 u
.expr
.v1
->set_my_scope(p_scope
);
1765 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1768 u
.expr
.r1
->set_my_scope(p_scope
);
1769 u
.expr
.r2
->set_my_scope(p_scope
);
1772 u
.expr
.ti1
->set_my_scope(p_scope
);
1773 u
.expr
.v2
->set_my_scope(p_scope
);
1774 u
.expr
.v3
->set_my_scope(p_scope
);
1777 u
.expr
.ti1
->set_my_scope(p_scope
);
1778 u
.expr
.t2
->set_my_scope(p_scope
);
1779 u
.expr
.v3
->set_my_scope(p_scope
);
1781 case OPTYPE_DECOMP
: // v1 v2 v3
1782 u
.expr
.v1
->set_my_scope(p_scope
);
1783 u
.expr
.v2
->set_my_scope(p_scope
);
1784 u
.expr
.v3
->set_my_scope(p_scope
);
1786 case OPTYPE_REPLACE
:
1787 u
.expr
.ti1
->set_my_scope(p_scope
);
1788 u
.expr
.v2
->set_my_scope(p_scope
);
1789 u
.expr
.v3
->set_my_scope(p_scope
);
1790 u
.expr
.ti4
->set_my_scope(p_scope
);
1792 case OPTYPE_LENGTHOF
: // ti1
1793 case OPTYPE_SIZEOF
: // ti1
1794 case OPTYPE_VALUEOF
: // ti1
1795 case OPTYPE_ISVALUE
:
1796 case OPTYPE_ISBOUND
:
1798 case OPTYPE_ISPRESENT
:
1799 case OPTYPE_TTCN2STRING
:
1800 u
.expr
.ti1
->set_my_scope(p_scope
);
1802 case OPTYPE_ENCVALUE_UNICHAR
: //ti1 [v2]
1803 u
.expr
.ti1
->set_my_scope(p_scope
);
1804 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1806 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1807 u
.expr
.r1
->set_my_scope(p_scope
);
1808 u
.expr
.r2
->set_my_scope(p_scope
);
1809 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1811 case OPTYPE_UNDEF_RUNNING
: // r1
1812 case OPTYPE_TMR_READ
:
1813 case OPTYPE_TMR_RUNNING
:
1814 case OPTYPE_ACTIVATE
:
1815 u
.expr
.r1
->set_my_scope(p_scope
);
1817 case OPTYPE_EXECUTE
: // r1 [v2]
1818 u
.expr
.r1
->set_my_scope(p_scope
);
1819 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1821 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
1822 case OPTYPE_CHECKSTATE_ALL
:
1823 if(u
.expr
.r1
) u
.expr
.r1
->set_my_scope(p_scope
);
1824 u
.expr
.v2
->set_my_scope(p_scope
);
1826 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1827 u
.expr
.r1
->set_my_scope(p_scope
);
1828 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1829 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1831 case OPTYPE_MATCH
: // v1 t2
1832 u
.expr
.v1
->set_my_scope(p_scope
);
1833 u
.expr
.t2
->set_my_scope(p_scope
);
1835 case OPTYPE_ISCHOSEN
: // r1 i2
1836 u
.expr
.r1
->set_my_scope(p_scope
);
1838 case OPTYPE_ISCHOSEN_V
: // v1 i2
1839 u
.expr
.v1
->set_my_scope(p_scope
);
1841 case OPTYPE_ISCHOSEN_T
: // t1 i2
1842 u
.expr
.t1
->set_my_scope(p_scope
);
1844 case OPTYPE_ACTIVATE_REFD
:
1845 u
.expr
.v1
->set_my_scope(p_scope
);
1846 if(u
.expr
.state
!=EXPR_CHECKED
) {
1847 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1849 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1851 case OPTYPE_EXECUTE_REFD
:
1852 u
.expr
.v1
->set_my_scope(p_scope
);
1853 if(u
.expr
.state
!=EXPR_CHECKED
) {
1854 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1856 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1859 u
.expr
.v3
->set_my_scope(p_scope
);
1861 case OPTYPE_LOG2STR
:
1862 case OPTYPE_ANY2UNISTR
:
1863 u
.expr
.logargs
->set_my_scope(p_scope
);
1866 FATAL_ERROR("Value::set_my_scope_expr()");
1870 void Value::set_genname_recursive(const string
& p_genname
)
1872 size_t genname_len
= p_genname
.size();
1873 if (genname_len
>= 4 &&
1874 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1875 // if the genname ends with ()() (i.e. the value stands for an optional
1876 // field) then drop the last () from the own genname, but leave it for
1877 // the embedded values
1878 set_genname(p_genname
.substr(0, genname_len
- 2));
1879 } else set_genname(p_genname
);
1882 string
embedded_genname(p_genname
);
1883 embedded_genname
+= '.';
1884 // If this is a choice value for an anytype, prepend the AT_ prefix
1885 // to the name of the alternative. The genname is used later in
1886 // Common::Value::generate_code_init_se()
1887 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1888 embedded_genname
+= "AT_";
1889 embedded_genname
+= u
.choice
.alt_name
->get_name();
1890 embedded_genname
+= "()";
1891 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1895 if (!is_indexed()) {
1896 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1897 for (size_t i
= 0; i
< nof_vs
; i
++) {
1898 string
embedded_genname(p_genname
);
1899 embedded_genname
+= '[';
1900 embedded_genname
+= Int2string(i
);
1901 embedded_genname
+= ']';
1902 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1905 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1906 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1907 string
embedded_genname(p_genname
);
1908 embedded_genname
+= '[';
1909 embedded_genname
+= Int2string(i
);
1910 embedded_genname
+= ']';
1911 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1912 ->set_genname_recursive(embedded_genname
);
1917 if (!my_governor
) return; // error recovery
1918 Type
*type
= my_governor
->get_type_refd_last();
1919 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1920 Int offset
= type
->get_dimension()->get_offset();
1921 if (!is_indexed()) {
1922 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1923 for (size_t i
= 0; i
< nof_vs
; i
++) {
1924 string
embedded_genname(p_genname
);
1925 embedded_genname
+= '[';
1926 embedded_genname
+= Int2string(offset
+ i
);
1927 embedded_genname
+= ']';
1928 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1931 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1932 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1933 string
embedded_genname(p_genname
);
1934 embedded_genname
+= '[';
1935 embedded_genname
+= Int2string(offset
+ i
);
1936 embedded_genname
+= ']';
1937 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1938 ->set_genname_recursive(embedded_genname
);
1944 if (!my_governor
) return; // error recovery
1945 Type
*t
= my_governor
->get_type_refd_last();
1946 if (!t
->is_secho()) return; // error recovery
1947 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1948 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1949 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1950 const Identifier
& id
= nv
->get_name();
1951 if (!t
->has_comp_withName(id
)) return; // error recovery
1952 string
embedded_genname(p_genname
);
1953 embedded_genname
+= '.';
1954 embedded_genname
+= id
.get_name();
1955 embedded_genname
+= "()";
1956 if (t
->get_comp_byName(id
)->get_is_optional())
1957 embedded_genname
+= "()";
1958 nv
->get_value()->set_genname_recursive(embedded_genname
);
1966 void Value::set_genname_prefix(const char *p_genname_prefix
)
1968 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1971 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1976 if (!is_indexed()) {
1977 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1978 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1980 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1981 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1982 ->set_genname_prefix(p_genname_prefix
);
1987 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1988 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1989 ->set_genname_prefix(p_genname_prefix
);
1996 void Value::set_code_section(code_section_t p_code_section
)
1998 GovernedSimple::set_code_section(p_code_section
);
2001 switch (u
.expr
.v_optype
) {
2002 case OPTYPE_RND
: // -
2003 case OPTYPE_COMP_NULL
:
2004 case OPTYPE_COMP_MTC
:
2005 case OPTYPE_COMP_SYSTEM
:
2006 case OPTYPE_COMP_SELF
:
2007 case OPTYPE_COMP_RUNNING_ANY
:
2008 case OPTYPE_COMP_RUNNING_ALL
:
2009 case OPTYPE_COMP_ALIVE_ANY
:
2010 case OPTYPE_COMP_ALIVE_ALL
:
2011 case OPTYPE_TMR_RUNNING_ANY
:
2012 case OPTYPE_GETVERDICT
:
2013 case OPTYPE_TESTCASENAME
:
2014 case OPTYPE_PROF_RUNNING
:
2016 case OPTYPE_UNARYPLUS
: // v1
2017 case OPTYPE_UNARYMINUS
:
2020 case OPTYPE_BIT2HEX
:
2021 case OPTYPE_BIT2INT
:
2022 case OPTYPE_BIT2OCT
:
2023 case OPTYPE_BIT2STR
:
2024 case OPTYPE_CHAR2INT
:
2025 case OPTYPE_CHAR2OCT
:
2026 case OPTYPE_COMP_RUNNING
:
2027 case OPTYPE_COMP_ALIVE
:
2028 case OPTYPE_FLOAT2INT
:
2029 case OPTYPE_FLOAT2STR
:
2030 case OPTYPE_HEX2BIT
:
2031 case OPTYPE_HEX2INT
:
2032 case OPTYPE_HEX2OCT
:
2033 case OPTYPE_HEX2STR
:
2034 case OPTYPE_INT2CHAR
:
2035 case OPTYPE_INT2FLOAT
:
2036 case OPTYPE_INT2STR
:
2037 case OPTYPE_INT2UNICHAR
:
2038 case OPTYPE_OCT2BIT
:
2039 case OPTYPE_OCT2CHAR
:
2040 case OPTYPE_OCT2HEX
:
2041 case OPTYPE_OCT2INT
:
2042 case OPTYPE_OCT2STR
:
2043 case OPTYPE_STR2BIT
:
2044 case OPTYPE_STR2FLOAT
:
2045 case OPTYPE_STR2HEX
:
2046 case OPTYPE_STR2INT
:
2047 case OPTYPE_STR2OCT
:
2048 case OPTYPE_UNICHAR2INT
:
2049 case OPTYPE_UNICHAR2CHAR
:
2050 case OPTYPE_ENUM2INT
:
2051 case OPTYPE_RNDWITHVAL
:
2052 case OPTYPE_GET_STRINGENCODING
:
2053 case OPTYPE_DECODE_BASE64
:
2054 case OPTYPE_REMOVE_BOM
:
2055 u
.expr
.v1
->set_code_section(p_code_section
);
2057 case OPTYPE_ADD
: // v1 v2
2058 case OPTYPE_SUBTRACT
:
2059 case OPTYPE_MULTIPLY
:
2080 case OPTYPE_INT2BIT
:
2081 case OPTYPE_INT2HEX
:
2082 case OPTYPE_INT2OCT
:
2083 u
.expr
.v1
->set_code_section(p_code_section
);
2084 u
.expr
.v2
->set_code_section(p_code_section
);
2086 case OPTYPE_UNICHAR2OCT
:
2087 case OPTYPE_OCT2UNICHAR
:
2088 case OPTYPE_ENCODE_BASE64
:
2089 u
.expr
.v1
->set_code_section(p_code_section
);
2090 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2093 u
.expr
.r1
->set_code_section(p_code_section
);
2094 u
.expr
.r2
->set_code_section(p_code_section
);
2097 u
.expr
.ti1
->set_code_section(p_code_section
);
2098 u
.expr
.v2
->set_code_section(p_code_section
);
2099 u
.expr
.v3
->set_code_section(p_code_section
);
2102 u
.expr
.ti1
->set_code_section(p_code_section
);
2103 u
.expr
.t2
->set_code_section(p_code_section
);
2104 u
.expr
.v3
->set_code_section(p_code_section
);
2106 case OPTYPE_DECOMP
: // v1 v2 v3
2107 u
.expr
.v1
->set_code_section(p_code_section
);
2108 u
.expr
.v2
->set_code_section(p_code_section
);
2109 u
.expr
.v3
->set_code_section(p_code_section
);
2111 case OPTYPE_REPLACE
:
2112 u
.expr
.ti1
->set_code_section(p_code_section
);
2113 u
.expr
.v2
->set_code_section(p_code_section
);
2114 u
.expr
.v3
->set_code_section(p_code_section
);
2115 u
.expr
.ti4
->set_code_section(p_code_section
);
2117 case OPTYPE_LENGTHOF
: // ti1
2118 case OPTYPE_SIZEOF
: // ti1
2119 case OPTYPE_VALUEOF
: // ti1
2120 case OPTYPE_ISVALUE
:
2121 case OPTYPE_ISBOUND
:
2123 case OPTYPE_ISPRESENT
:
2124 case OPTYPE_TTCN2STRING
:
2125 u
.expr
.ti1
->set_code_section(p_code_section
);
2127 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
2128 u
.expr
.ti1
->set_code_section(p_code_section
);
2129 if (u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2131 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
2132 u
.expr
.r1
->set_code_section(p_code_section
);
2133 u
.expr
.r2
->set_code_section(p_code_section
);
2134 if (u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2136 case OPTYPE_UNDEF_RUNNING
: // r1
2137 case OPTYPE_TMR_READ
:
2138 case OPTYPE_TMR_RUNNING
:
2139 case OPTYPE_ACTIVATE
:
2140 u
.expr
.r1
->set_code_section(p_code_section
);
2142 case OPTYPE_EXECUTE
: // r1 [v2]
2143 u
.expr
.r1
->set_code_section(p_code_section
);
2144 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2146 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
2147 case OPTYPE_CHECKSTATE_ALL
:
2148 if(u
.expr
.r1
) u
.expr
.r1
->set_code_section(p_code_section
);
2149 u
.expr
.v2
->set_code_section(p_code_section
);
2151 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2152 u
.expr
.r1
->set_code_section(p_code_section
);
2153 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2154 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2156 case OPTYPE_MATCH
: // v1 t2
2157 u
.expr
.v1
->set_code_section(p_code_section
);
2158 u
.expr
.t2
->set_code_section(p_code_section
);
2160 case OPTYPE_ISCHOSEN
: // r1 i2
2161 u
.expr
.r1
->set_code_section(p_code_section
);
2163 case OPTYPE_ISCHOSEN_V
: // v1 i2
2164 u
.expr
.v1
->set_code_section(p_code_section
);
2166 case OPTYPE_ISCHOSEN_T
: // t1 i2
2167 u
.expr
.t1
->set_code_section(p_code_section
);
2169 case OPTYPE_ACTIVATE_REFD
:
2170 u
.expr
.v1
->set_code_section(p_code_section
);
2171 if(u
.expr
.state
!=EXPR_CHECKED
)
2172 u
.expr
.t_list2
->set_code_section(p_code_section
);
2174 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2175 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2176 u
.expr
.state
= EXPR_CHECKED
;
2179 case OPTYPE_EXECUTE_REFD
:
2180 u
.expr
.v1
->set_code_section(p_code_section
);
2181 if(u
.expr
.state
!=EXPR_CHECKED
)
2182 u
.expr
.t_list2
->set_code_section(p_code_section
);
2184 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2185 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2186 u
.expr
.state
= EXPR_CHECKED
;
2189 u
.expr
.v3
->set_code_section(p_code_section
);
2191 case OPTYPE_LOG2STR
:
2192 case OPTYPE_ANY2UNISTR
:
2193 u
.expr
.logargs
->set_code_section(p_code_section
);
2196 FATAL_ERROR("Value::set_code_section()");
2200 u
.choice
.alt_value
->set_code_section(p_code_section
);
2205 if (!is_indexed()) {
2206 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2207 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2209 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2210 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2215 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2216 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2217 ->set_code_section(p_code_section
);
2220 u
.ref
.ref
->set_code_section(p_code_section
);
2223 u
.refered
->set_code_section(p_code_section
);
2226 u
.invoke
.v
->set_code_section(p_code_section
);
2227 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2228 if(u
.invoke
.ap_list
)
2229 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2230 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2237 void Value::change_sign()
2241 *u
.val_Int
=-*u
.val_Int
;
2249 FATAL_ERROR("Value::change_sign()");
2253 void Value::add_oid_comp(OID_comp
* p_comp
)
2256 FATAL_ERROR("NULL parameter");
2257 u
.oid_comps
->add(p_comp
);
2258 p_comp
->set_fullname(get_fullname()+"."
2259 +Int2string(u
.oid_comps
->size()));
2260 p_comp
->set_my_scope(my_scope
);
2263 void Value::set_valuetype(valuetype_t p_valuetype
)
2265 if (valuetype
== V_ERROR
) return;
2266 else if (p_valuetype
== V_ERROR
) {
2267 if(valuetype
==V_EXPR
) {
2268 switch(u
.expr
.state
) {
2270 u
.expr
.state
=EXPR_CHECKING_ERR
;
2272 case EXPR_CHECKING_ERR
:
2279 valuetype
= V_ERROR
;
2283 case V_UNDEF_LOWERID
:
2284 switch(p_valuetype
) {
2289 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2290 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2291 u
.ref
.ref
->set_my_scope(get_my_scope());
2292 u
.ref
.ref
->set_fullname(get_fullname());
2293 u
.ref
.ref
->set_location(*this);
2294 u
.ref
.refd_last
= 0;
2297 FATAL_ERROR("Value::set_valuetype()");
2300 case V_UNDEF_BLOCK
: {
2301 Block
*t_block
=u
.block
;
2303 switch(p_valuetype
) {
2305 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2306 v
=dynamic_cast<Value
*>(node
);
2309 u
.ids
=new map
<string
, Identifier
>();
2312 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2316 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2317 v
=dynamic_cast<Value
*>(node
);
2320 u
.val_vs
=new Values();
2323 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2325 u
.val_vs
->set_my_scope(get_my_scope());
2326 u
.val_vs
->set_fullname(get_fullname());
2329 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2330 v
=dynamic_cast<Value
*>(node
);
2333 u
.val_vs
=new Values();
2336 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2338 u
.val_vs
->set_my_scope(get_my_scope());
2339 u
.val_vs
->set_fullname(get_fullname());
2342 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2343 v
=dynamic_cast<Value
*>(node
);
2346 u
.val_nvs
=new NamedValues();
2349 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2351 u
.val_nvs
->set_my_scope(get_my_scope());
2352 u
.val_nvs
->set_fullname(get_fullname());
2355 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2356 v
=dynamic_cast<Value
*>(node
);
2359 u
.val_nvs
=new NamedValues();
2362 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2364 u
.val_nvs
->set_my_scope(get_my_scope());
2365 u
.val_nvs
->set_fullname(get_fullname());
2368 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2369 v
=dynamic_cast<Value
*>(node
);
2372 u
.oid_comps
=new vector
<OID_comp
>();
2375 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2377 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2378 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2381 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2382 v
=dynamic_cast<Value
*>(node
);
2385 u
.oid_comps
=new vector
<OID_comp
>();
2388 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2390 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2391 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2394 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2395 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2398 u
.char_syms
=new CharSyms();
2400 u
.char_syms
->set_my_scope(get_my_scope());
2401 u
.char_syms
->set_fullname(get_fullname());
2404 FATAL_ERROR("Value::set_valuetype()");
2410 if (p_valuetype
== V_USTR
) {
2411 Value
*v_last
= get_value_refd_last();
2412 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2413 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2416 u
.ustr
.convert_str
= true; // will be converted back to string
2417 } else FATAL_ERROR("Value::set_valuetype()");
2420 switch(p_valuetype
) {
2422 const string
& str
= u
.char_syms
->get_string();
2424 set_val_str(new string(str
));
2427 const ustring
& ustr
= u
.char_syms
->get_ustring();
2429 set_val_ustr(new ustring(ustr
));
2430 u
.ustr
.convert_str
= false;
2432 case V_ISO2022STR
: {
2433 const string
& str
= u
.char_syms
->get_iso2022string();
2435 set_val_str(new string(str
));
2438 FATAL_ERROR("Value::set_valuetype()");
2443 if (p_valuetype
== V_REAL
)
2444 val_Real
= u
.val_Int
->to_real();
2445 else FATAL_ERROR("Value::set_valuetype()");
2447 u
.val_Real
= val_Real
;
2450 clean_up_string_elements(u
.str
.str_elements
);
2451 string
*old_str
= u
.str
.val_str
;
2452 switch(p_valuetype
) {
2454 set_val_str(hex2bit(*old_str
));
2457 set_val_str(asn_hex2oct(*old_str
));
2460 FATAL_ERROR("Value::set_valuetype()");
2465 clean_up_string_elements(u
.str
.str_elements
);
2466 if (p_valuetype
== V_OSTR
) {
2467 string
*old_str
= u
.str
.val_str
;
2468 set_val_str(asn_bit2oct(*old_str
));
2470 } else FATAL_ERROR("Value::set_valuetype()");
2473 clean_up_string_elements(u
.str
.str_elements
);
2474 switch(p_valuetype
) {
2476 string
*old_str
= u
.str
.val_str
;
2477 set_val_ustr(new ustring(*old_str
));
2478 u
.ustr
.convert_str
= true; // will be converted back to string
2485 FATAL_ERROR("Value::set_valuetype()");
2486 } // switch p_valuetype
2489 clean_up_string_elements(u
.ustr
.ustr_elements
);
2490 switch(p_valuetype
) {
2492 ustring
*old_str
= u
.ustr
.val_ustr
;
2493 size_t nof_chars
= old_str
->size();
2494 bool warning_flag
= false;
2495 for (size_t i
= 0; i
< nof_chars
; i
++) {
2496 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2497 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2498 error("This string value cannot contain multiple-byte characters, "
2499 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2500 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2502 p_valuetype
= V_ERROR
;
2504 } else if (uchar
.cell
> 127 && !warning_flag
) {
2505 warning("This string value may not contain characters with code "
2506 "higher than 127, but it has character with code %u (0x%02X) "
2507 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2508 warning_flag
= true;
2511 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2515 error("ISO-10646 string value cannot be converted to "
2517 delete u
.ustr
.val_ustr
;
2518 p_valuetype
= V_ERROR
;
2521 FATAL_ERROR("Value::set_valuetype()");
2522 } // switch p_valuetype
2525 switch (p_valuetype
) {
2527 NamedValues
*nvs
= u
.val_nvs
;
2528 if (nvs
->get_nof_nvs() < 1) {
2529 error("Union value must have one active field");
2531 valuetype
= V_ERROR
;
2533 } else if (nvs
->get_nof_nvs() > 1) {
2534 error("Only one field was expected in union value instead of %lu",
2535 (unsigned long) nvs
->get_nof_nvs());
2537 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2538 u
.choice
.alt_name
= nv
->get_name().clone();
2539 u
.choice
.alt_value
= nv
->steal_value();
2546 NamedValues
*nvs
= u
.val_nvs
;
2550 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2551 if (nvs
->has_nv_withName(id_mant
)) {
2552 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2553 ->get_value_refd_last();
2554 if (v_tmp
->get_valuetype() == V_INT
) {
2555 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2556 if (*i_mant_int
> INT_MAX
) {
2557 error("Mantissa `%s' should be less than `%d'",
2558 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2561 i_mant
= i_mant_int
->get_val();
2569 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2570 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2571 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2572 Value
*v_tmp
= v
->get_value_refd_last();
2573 if (v_tmp
->get_valuetype() == V_INT
) {
2574 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2575 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2576 v
->error("Base of the REAL must be 2 or 10");
2579 i_base
= i_base_int
->get_val();
2587 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2588 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2589 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2590 ->get_value_refd_last();
2591 if (v_tmp
->get_valuetype() == V_INT
) {
2592 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2593 if (*i_exp_int
> INT_MAX
) {
2594 error("Exponent `%s' should be less than `%d'",
2595 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2598 i_exp
= i_exp_int
->get_val();
2607 valuetype
= V_ERROR
;
2610 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2611 static_cast<double>(i_exp
));
2617 FATAL_ERROR("Value::set_valuetype()");
2621 switch (p_valuetype
) {
2623 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2624 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2625 Type
*t
= my_governor
->get_type_refd_last();
2626 switch (t
->get_typetype()) {
2631 FATAL_ERROR("Value::set_valuetype()");
2633 Values
*vals
= u
.val_vs
;
2634 size_t nof_vals
= vals
->get_nof_vs();
2635 size_t nof_comps
= t
->get_nof_comps();
2636 if (nof_vals
> nof_comps
) {
2637 error("Too many elements in value list notation for type `%s': "
2638 "%lu was expected instead of %lu",
2639 t
->get_typename().c_str(),
2640 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2644 if (nof_vals
<= nof_comps
) {
2645 upper_limit
= nof_vals
;
2648 upper_limit
= nof_comps
;
2651 u
.val_nvs
= new NamedValues
;
2652 for (size_t i
= 0; i
< upper_limit
; i
++) {
2653 Value
*v
= vals
->steal_v_byIndex(i
);
2654 if (v
->valuetype
!= V_NOTUSED
) {
2658 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2659 nv
->set_location(*v
);
2660 u
.val_nvs
->add_nv(nv
);
2662 u
.val_nvs
->set_my_scope(get_my_scope());
2663 u
.val_nvs
->set_fullname(get_fullname());
2665 if (allnotused
&& nof_vals
> 0)
2666 warning("All elements of value list notation for type `%s' are not "
2667 "used symbols (`-')", t
->get_typename().c_str());
2670 // { } -> empty set value
2671 if (u
.val_vs
->get_nof_vs() != 0)
2672 FATAL_ERROR("Value::set_valuetype()");
2674 u
.val_nvs
= new NamedValues
;
2678 // SEQOF -> SETOF or ARRAY: trivial
2681 FATAL_ERROR("Value::set_valuetype()");
2686 if (p_valuetype
== V_NOTUSED
) {
2690 FATAL_ERROR("Value::set_valuetype()");
2694 switch (p_valuetype
) {
2695 case V_DEFAULT_NULL
:
2700 FATAL_ERROR("Value::set_valuetype()");
2704 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2705 FATAL_ERROR("Value::set_valuetype()");
2709 FATAL_ERROR("Value::set_valuetype()");
2711 valuetype
=p_valuetype
;
2714 void Value::set_valuetype_COMP_NULL()
2716 if(valuetype
== V_ERROR
) return;
2717 if(valuetype
==V_TTCN3_NULL
) {
2719 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2720 // Nothing to check.
2721 u
.expr
.state
=EXPR_CHECKED
;
2723 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2726 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2728 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2730 u
.val_Int
= new int_val_t(p_val_int
);
2732 } else FATAL_ERROR("Value::set_valuetype()");
2735 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2737 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2741 } else FATAL_ERROR("Value::set_valuetype()");
2744 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2746 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2750 } else FATAL_ERROR("Value::set_valuetype()");
2753 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2755 switch (p_valuetype
) {
2759 if (valuetype
== V_REFER
&& p_ass
) break;
2762 FATAL_ERROR("Value::set_valuetype()");
2766 valuetype
= p_valuetype
;
2769 bool Value::is_undef_lowerid()
2771 switch (valuetype
) {
2772 case V_UNDEF_LOWERID
:
2775 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2776 !u
.expr
.ti1
->get_DerivedRef()) {
2777 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2785 const Identifier
& Value::get_undef_lowerid()
2787 switch (valuetype
) {
2788 case V_UNDEF_LOWERID
:
2791 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2792 FATAL_ERROR("Value::get_undef_lowerid()");
2793 return u
.expr
.ti1
->get_Template()->get_specific_value()
2794 ->get_undef_lowerid();
2796 FATAL_ERROR("Value::get_undef_lowerid()");
2798 const Identifier
*dummy
= 0;
2802 void Value::set_lowerid_to_ref()
2804 switch (valuetype
) {
2805 case V_UNDEF_LOWERID
:
2806 set_valuetype(V_REFD
);
2809 // if the governor of the expression is not known (in log(), etc...)
2810 // then the governor is taken from the reference (using
2811 // v1/ti1->get_expr_governor()), but that runs before the
2812 // params were checked, this smells like a workaround :)
2813 switch (u
.expr
.v_optype
) {
2816 u
.expr
.v1
->set_lowerid_to_ref();
2819 u
.expr
.v1
->set_lowerid_to_ref();
2820 u
.expr
.v2
->set_lowerid_to_ref();
2822 case OPTYPE_VALUEOF
:
2823 case OPTYPE_ISVALUE
:
2824 case OPTYPE_ISBOUND
:
2825 case OPTYPE_ISPRESENT
:
2828 case OPTYPE_REPLACE
:
2829 case OPTYPE_TTCN2STRING
:
2830 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2831 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2832 "In the operand of operation `%s'",
2834 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2836 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2837 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2838 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2839 "In the operand of operation `%s'",
2841 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2844 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2845 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2846 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2847 "In the operand of operation `%s'",
2849 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2862 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2864 switch (valuetype
) {
2872 case V_UNDEF_LOWERID
:
2879 return Type::T_UNDEF
;
2883 FATAL_ERROR("Value::get_expr_returntype()");
2885 return Type::T_ERROR
;
2888 Type
*t
= get_expr_governor(exp_val
);
2889 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2890 else return Type::T_ERROR
; }
2892 return Type::T_FUNCTION
;
2894 return Type::T_ALTSTEP
;
2896 return Type::T_TESTCASE
;
2898 switch(u
.expr
.v_optype
) {
2899 case OPTYPE_COMP_NULL
:
2900 case OPTYPE_COMP_MTC
:
2901 case OPTYPE_COMP_SYSTEM
:
2902 case OPTYPE_COMP_SELF
:
2903 case OPTYPE_COMP_CREATE
:
2904 return Type::T_COMPONENT
;
2905 case OPTYPE_UNDEF_RUNNING
:
2906 case OPTYPE_COMP_RUNNING
:
2907 case OPTYPE_COMP_RUNNING_ANY
:
2908 case OPTYPE_COMP_RUNNING_ALL
:
2909 case OPTYPE_COMP_ALIVE
:
2910 case OPTYPE_COMP_ALIVE_ANY
:
2911 case OPTYPE_COMP_ALIVE_ALL
:
2912 case OPTYPE_TMR_RUNNING
:
2913 case OPTYPE_TMR_RUNNING_ANY
:
2925 case OPTYPE_ISPRESENT
:
2926 case OPTYPE_ISCHOSEN
:
2927 case OPTYPE_ISCHOSEN_V
:
2928 case OPTYPE_ISCHOSEN_T
:
2929 case OPTYPE_ISVALUE
:
2930 case OPTYPE_ISBOUND
:
2931 case OPTYPE_PROF_RUNNING
:
2932 case OPTYPE_CHECKSTATE_ANY
:
2933 case OPTYPE_CHECKSTATE_ALL
:
2934 return Type::T_BOOL
;
2935 case OPTYPE_GETVERDICT
:
2936 return Type::T_VERDICT
;
2937 case OPTYPE_VALUEOF
: {
2938 Error_Context
cntxt(this, "In the operand of operation `%s'",
2940 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2941 case OPTYPE_TMR_READ
:
2942 case OPTYPE_INT2FLOAT
:
2943 case OPTYPE_STR2FLOAT
:
2945 case OPTYPE_RNDWITHVAL
:
2946 return Type::T_REAL
;
2947 case OPTYPE_ACTIVATE
:
2948 return Type::T_DEFAULT
;
2949 case OPTYPE_ACTIVATE_REFD
:
2950 return Type::T_DEFAULT
;
2951 case OPTYPE_EXECUTE
:
2952 case OPTYPE_EXECUTE_REFD
:
2953 return Type::T_VERDICT
;
2954 case OPTYPE_UNARYPLUS
: // v1
2955 case OPTYPE_UNARYMINUS
: {
2956 Type::typetype_t tmp_tt
;
2958 Error_Context
cntxt(this, "In the operand of operation `%s'",
2960 u
.expr
.v1
->set_lowerid_to_ref();
2961 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2968 get_value_refd_last(); // to report the error
2969 return Type::T_ERROR
;
2972 case OPTYPE_ADD
: // v1 v2
2973 case OPTYPE_SUBTRACT
:
2974 case OPTYPE_MULTIPLY
:
2975 case OPTYPE_DIVIDE
: {
2976 Type::typetype_t tmp_tt
;
2978 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2980 u
.expr
.v1
->set_lowerid_to_ref();
2981 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2988 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2989 Type::typetype_t tmp_tt2
;
2991 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2993 u
.expr
.v2
->set_lowerid_to_ref();
2994 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2996 Type::typetype_t ret_val
=Type::T_ERROR
;
2997 bool maybeconcat
=false;
3002 if(tmp_tt2
==tmp_tt
) {
3009 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
3011 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
3012 ret_val
=Type::T_USTR
;
3013 else ret_val
=Type::T_CSTR
;
3020 error("Did you mean the concat operation (`&') instead of"
3021 " addition operator (`+')?");
3022 u
.expr
.v_optype
=OPTYPE_CONCAT
;
3026 get_value_refd_last(); // to report the error
3027 return Type::T_ERROR
;
3030 case OPTYPE_NOT4B
: // v1
3031 case OPTYPE_AND4B
: // v1 v2
3036 Type::typetype_t tmp_tt
;
3038 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
3039 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
3041 u
.expr
.v1
->set_lowerid_to_ref();
3042 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3050 get_value_refd_last(); // to report the error
3051 return Type::T_ERROR
;
3054 case OPTYPE_ROTL
: // v1 v2
3056 Type::typetype_t tmp_tt
;
3058 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
3059 u
.expr
.v_optype
==OPTYPE_ROTL
3060 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
3062 u
.expr
.v1
->set_lowerid_to_ref();
3063 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3076 get_value_refd_last(); // to report the error
3077 return Type::T_ERROR
;
3081 case OPTYPE_REPLACE
: {
3082 Type::typetype_t tmp_tt
;
3084 Error_Context
cntxt(this, "In the operand of operation `%s'",
3086 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3087 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3099 get_value_refd_last(); // to report the error
3100 return Type::T_ERROR
;
3103 case OPTYPE_REGEXP
: {
3104 Type::typetype_t tmp_tt
;
3106 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3108 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3109 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3116 get_value_refd_last(); // to report the error
3117 return Type::T_ERROR
;
3120 case OPTYPE_CONCAT
: { // v1 v2
3121 Type::typetype_t tmp_tt
;
3123 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3125 u
.expr
.v1
->set_lowerid_to_ref();
3126 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3138 get_value_refd_last(); // to report the error
3139 return Type::T_ERROR
;
3144 case OPTYPE_CHAR2INT
:
3145 case OPTYPE_UNICHAR2INT
:
3146 case OPTYPE_BIT2INT
:
3147 case OPTYPE_HEX2INT
:
3148 case OPTYPE_OCT2INT
:
3149 case OPTYPE_STR2INT
:
3150 case OPTYPE_FLOAT2INT
:
3151 case OPTYPE_LENGTHOF
:
3154 case OPTYPE_ENUM2INT
:
3155 case OPTYPE_DECVALUE_UNICHAR
:
3157 case OPTYPE_BIT2STR
:
3158 case OPTYPE_FLOAT2STR
:
3159 case OPTYPE_HEX2STR
:
3160 case OPTYPE_INT2CHAR
:
3161 case OPTYPE_INT2STR
:
3162 case OPTYPE_OCT2CHAR
:
3163 case OPTYPE_OCT2STR
:
3164 case OPTYPE_UNICHAR2CHAR
:
3165 case OPTYPE_LOG2STR
:
3166 case OPTYPE_TESTCASENAME
:
3167 case OPTYPE_TTCN2STRING
:
3168 case OPTYPE_GET_STRINGENCODING
:
3169 case OPTYPE_ENCODE_BASE64
:
3170 return Type::T_CSTR
;
3171 case OPTYPE_INT2UNICHAR
:
3172 case OPTYPE_OCT2UNICHAR
:
3173 case OPTYPE_ENCVALUE_UNICHAR
:
3174 case OPTYPE_ANY2UNISTR
:
3175 return Type::T_USTR
;
3176 case OPTYPE_INT2BIT
:
3177 case OPTYPE_HEX2BIT
:
3178 case OPTYPE_OCT2BIT
:
3179 case OPTYPE_STR2BIT
:
3181 return Type::T_BSTR
;
3182 case OPTYPE_INT2HEX
:
3183 case OPTYPE_BIT2HEX
:
3184 case OPTYPE_OCT2HEX
:
3185 case OPTYPE_STR2HEX
:
3186 return Type::T_HSTR
;
3187 case OPTYPE_INT2OCT
:
3188 case OPTYPE_CHAR2OCT
:
3189 case OPTYPE_HEX2OCT
:
3190 case OPTYPE_BIT2OCT
:
3191 case OPTYPE_STR2OCT
:
3192 case OPTYPE_UNICHAR2OCT
:
3193 case OPTYPE_REMOVE_BOM
:
3194 case OPTYPE_DECODE_BASE64
:
3195 return Type::T_OSTR
;
3199 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3201 return Type::T_ERROR
;
3205 case MACRO_MODULEID
:
3206 case MACRO_FILENAME
:
3207 case MACRO_BFILENAME
:
3208 case MACRO_FILEPATH
:
3209 case MACRO_LINENUMBER
:
3210 case MACRO_DEFINITIONID
:
3212 case MACRO_TESTCASEID
:
3213 return Type::T_CSTR
;
3214 case MACRO_LINENUMBER_C
:
3217 return Type::T_ERROR
;
3220 return Type::T_NULL
;
3222 return Type::T_BOOL
;
3226 return Type::T_REAL
;
3228 return Type::T_ENUM_T
;
3230 return Type::T_BSTR
;
3232 return Type::T_HSTR
;
3234 return Type::T_OSTR
;
3236 return Type::T_CSTR
;
3238 return Type::T_USTR
;
3240 return Type::T_GENERALSTRING
;
3244 return Type::T_ROID
;
3246 return Type::T_VERDICT
;
3247 case V_DEFAULT_NULL
:
3248 return Type::T_DEFAULT
;
3250 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3252 return Type::T_ERROR
;
3256 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3258 if(my_governor
) return my_governor
;
3259 switch (valuetype
) {
3261 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3263 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3264 u
.invoke
.v
->error("A value of type function expected");
3267 t
= t
->get_type_refd_last();
3268 switch(t
->get_typetype()) {
3269 case Type::T_FUNCTION
: {
3270 Type
*t_return_type
= t
->get_function_return_type();
3271 if (!t_return_type
) {
3272 error("Reference to a %s was expected instead of invocation "
3273 "of behavior type `%s' with no return type",
3274 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3275 t
->get_fullname().c_str());
3278 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3279 error("Reference to a value was expected, but functions of type "
3280 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3281 t_return_type
->get_typename().c_str());
3284 return t_return_type
; }
3285 case Type::T_ALTSTEP
:
3288 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3289 t
->get_typename().c_str());
3294 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3296 if (!ass
) goto error
;
3297 switch (ass
->get_asstype()) {
3298 case Assignment::A_CONST
:
3299 case Assignment::A_EXT_CONST
:
3300 case Assignment::A_MODULEPAR
:
3301 case Assignment::A_MODULEPAR_TEMP
:
3302 case Assignment::A_TEMPLATE
:
3303 case Assignment::A_VAR
:
3304 case Assignment::A_VAR_TEMPLATE
:
3305 case Assignment::A_FUNCTION_RVAL
:
3306 case Assignment::A_FUNCTION_RTEMP
:
3307 case Assignment::A_EXT_FUNCTION_RVAL
:
3308 case Assignment::A_EXT_FUNCTION_RTEMP
:
3309 case Assignment::A_PAR_VAL_IN
:
3310 case Assignment::A_PAR_VAL_OUT
:
3311 case Assignment::A_PAR_VAL_INOUT
:
3312 case Assignment::A_PAR_TEMPL_IN
:
3313 case Assignment::A_PAR_TEMPL_OUT
:
3314 case Assignment::A_PAR_TEMPL_INOUT
:
3315 tmp_type
=ass
->get_Type();
3317 case Assignment::A_FUNCTION
:
3318 case Assignment::A_EXT_FUNCTION
:
3319 error("Reference to a %s was expected instead of a call of %s, which "
3320 "does not have return type",
3321 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3322 ass
->get_description().c_str());
3325 error("Reference to a %s was expected instead of %s",
3326 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3327 ass
->get_description().c_str());
3330 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3331 if(!tmp_type
) goto error
;
3334 switch (u
.expr
.v_optype
) {
3335 case OPTYPE_VALUEOF
:
3338 case OPTYPE_REPLACE
:{
3339 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3340 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3341 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3346 return u
.expr
.v1
->get_expr_governor(exp_val
);
3348 return get_expr_governor_v1v2(exp_val
);
3349 case OPTYPE_COMP_MTC
:
3350 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3352 case OPTYPE_COMP_SYSTEM
:
3353 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3355 case OPTYPE_COMP_SELF
:
3357 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3358 if (t_ros
) return t_ros
->get_component_type();
3361 case OPTYPE_COMP_CREATE
:
3362 return chk_expr_operand_comptyperef_create();
3368 return Type::get_pooltype(get_expr_returntype(exp_val
));
3371 set_valuetype(V_ERROR
);
3375 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3377 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3378 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3380 if (v2_gov
) { // both have governors
3381 // return the type that is compatible with both (if there is no type mismatch)
3382 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3385 } else return v1_gov
;
3386 } else { // v1 has no governor
3387 if (v2_gov
) return v2_gov
;
3388 else return NULL
; // neither has governor
3392 Type
*Value::get_expr_governor_last()
3394 Value
*v_last
= get_value_refd_last();
3395 if (v_last
->valuetype
== V_ERROR
) return 0;
3396 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3398 return t
->get_type_refd_last();
3401 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3403 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3404 return u
.invoke
.v
->get_expr_governor(exp_val
);
3407 const char* Value::get_opname() const
3409 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3410 switch(u
.expr
.v_optype
) {
3411 case OPTYPE_RND
: // -
3413 case OPTYPE_COMP_NULL
:
3414 return "(component) null";
3415 case OPTYPE_COMP_MTC
:
3417 case OPTYPE_COMP_SYSTEM
:
3419 case OPTYPE_COMP_SELF
:
3421 case OPTYPE_COMP_RUNNING_ANY
:
3422 return "any component.running";
3423 case OPTYPE_COMP_RUNNING_ALL
:
3424 return "all component.running";
3425 case OPTYPE_COMP_ALIVE_ANY
:
3426 return "any component.alive";
3427 case OPTYPE_COMP_ALIVE_ALL
:
3428 return "all component.alive";
3429 case OPTYPE_TMR_RUNNING_ANY
:
3430 return "any timer.running";
3431 case OPTYPE_GETVERDICT
:
3432 return "getverdict()";
3433 case OPTYPE_TESTCASENAME
:
3434 return "testcasename()";
3435 case OPTYPE_CHECKSTATE_ANY
:
3437 return "port.checkstate()";
3439 return "any port.checkstate()";
3441 case OPTYPE_CHECKSTATE_ALL
:
3443 return "port.checkstate()";
3445 return "all port.checkstate()";
3447 case OPTYPE_UNARYPLUS
: // v1
3449 case OPTYPE_UNARYMINUS
:
3455 case OPTYPE_BIT2HEX
:
3457 case OPTYPE_BIT2INT
:
3459 case OPTYPE_BIT2OCT
:
3461 case OPTYPE_BIT2STR
:
3463 case OPTYPE_CHAR2INT
:
3464 return "char2int()";
3465 case OPTYPE_CHAR2OCT
:
3466 return "char2oct()";
3467 case OPTYPE_FLOAT2INT
:
3468 return "float2int()";
3469 case OPTYPE_FLOAT2STR
:
3470 return "float2str()";
3471 case OPTYPE_HEX2BIT
:
3473 case OPTYPE_HEX2INT
:
3475 case OPTYPE_HEX2OCT
:
3477 case OPTYPE_HEX2STR
:
3479 case OPTYPE_INT2CHAR
:
3480 return "int2char()";
3481 case OPTYPE_INT2FLOAT
:
3482 return "int2float()";
3483 case OPTYPE_INT2STR
:
3485 case OPTYPE_INT2UNICHAR
:
3486 return "int2unichar()";
3487 case OPTYPE_OCT2BIT
:
3489 case OPTYPE_OCT2CHAR
:
3490 return "oct2char()";
3491 case OPTYPE_OCT2HEX
:
3493 case OPTYPE_OCT2INT
:
3495 case OPTYPE_OCT2STR
:
3497 case OPTYPE_STR2BIT
:
3499 case OPTYPE_STR2FLOAT
:
3500 return "str2float()";
3501 case OPTYPE_STR2HEX
:
3503 case OPTYPE_STR2INT
:
3505 case OPTYPE_STR2OCT
:
3507 case OPTYPE_UNICHAR2INT
:
3508 return "unichar2int()";
3509 case OPTYPE_UNICHAR2CHAR
:
3510 return "unichar2char()";
3511 case OPTYPE_UNICHAR2OCT
:
3512 return "unichar2oct()";
3513 case OPTYPE_ENUM2INT
:
3514 return "enum2int()";
3515 case OPTYPE_LENGTHOF
:
3516 return "lengthof()";
3519 case OPTYPE_RNDWITHVAL
:
3520 return "rnd (seed)";
3522 return "encvalue()";
3524 return "decvalue()";
3525 case OPTYPE_GET_STRINGENCODING
:
3526 return "get_stringencoding()";
3527 case OPTYPE_REMOVE_BOM
:
3528 return "remove_bom()";
3529 case OPTYPE_ENCODE_BASE64
:
3530 return "encode_base64()";
3531 case OPTYPE_DECODE_BASE64
:
3532 return "decode_base64()";
3533 case OPTYPE_ADD
: // v1 v2
3535 case OPTYPE_SUBTRACT
:
3537 case OPTYPE_MULTIPLY
:
3579 case OPTYPE_INT2BIT
:
3581 case OPTYPE_INT2HEX
:
3583 case OPTYPE_INT2OCT
:
3585 case OPTYPE_OCT2UNICHAR
:
3586 return "oct2unichar()";
3587 case OPTYPE_ENCVALUE_UNICHAR
:
3588 return "encvalue_unichar()";
3589 case OPTYPE_DECVALUE_UNICHAR
:
3590 return "decvalue_unichar()";
3597 case OPTYPE_REPLACE
:
3599 case OPTYPE_VALUEOF
: // t1
3601 case OPTYPE_UNDEF_RUNNING
:
3602 return "<timer or component> running";
3603 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3605 case OPTYPE_COMP_RUNNING
: // v1
3606 return "component running";
3607 case OPTYPE_COMP_ALIVE
: // v1
3609 case OPTYPE_TMR_READ
:
3610 return "timer read";
3611 case OPTYPE_TMR_RUNNING
:
3612 return "timer running";
3613 case OPTYPE_ACTIVATE
:
3614 return "activate()";
3615 case OPTYPE_ACTIVATE_REFD
:
3616 return "activate()";
3617 case OPTYPE_EXECUTE
: // r1 [v2]
3618 case OPTYPE_EXECUTE_REFD
:
3620 case OPTYPE_MATCH
: // v1 t2
3622 case OPTYPE_ISPRESENT
:
3623 return "ispresent()";
3624 case OPTYPE_ISCHOSEN
:
3625 case OPTYPE_ISCHOSEN_V
:
3626 case OPTYPE_ISCHOSEN_T
:
3627 return "ischosen()";
3628 case OPTYPE_ISVALUE
:
3630 case OPTYPE_ISBOUND
:
3632 case OPTYPE_LOG2STR
:
3634 case OPTYPE_ANY2UNISTR
:
3635 return "any2unistr()";
3636 case OPTYPE_TTCN2STRING
:
3637 return "ttcn2string()";
3638 case OPTYPE_PROF_RUNNING
:
3639 return "@profiler.running";
3641 FATAL_ERROR("Value::get_opname()");
3645 void Value::chk_expr_ref_ischosen()
3647 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3648 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3649 Assignment
*ass
=tmpref
->get_refd_assignment();
3651 set_valuetype(V_ERROR
);
3654 // Now we know whether the argument of ischosen() is a value or template.
3655 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3656 // or template (OPTYPE_ISCHOSEN_T).
3657 switch (ass
->get_asstype()) {
3658 case Assignment::A_CONST
:
3659 case Assignment::A_EXT_CONST
:
3660 case Assignment::A_MODULEPAR
:
3661 case Assignment::A_VAR
:
3662 case Assignment::A_PAR_VAL_IN
:
3663 case Assignment::A_PAR_VAL_OUT
:
3664 case Assignment::A_PAR_VAL_INOUT
:
3665 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3666 u
.expr
.v1
->set_location(*tmpref
);
3667 u
.expr
.v1
->set_my_scope(get_my_scope());
3668 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3669 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3671 case Assignment::A_MODULEPAR_TEMP
:
3672 case Assignment::A_TEMPLATE
:
3673 case Assignment::A_VAR_TEMPLATE
:
3674 case Assignment::A_PAR_TEMPL_IN
:
3675 case Assignment::A_PAR_TEMPL_OUT
:
3676 case Assignment::A_PAR_TEMPL_INOUT
:
3677 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3678 u
.expr
.t1
->set_location(*tmpref
);
3679 u
.expr
.t1
->set_my_scope(get_my_scope());
3680 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3681 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3684 tmpref
->error("Reference to a value or template was expected instead of "
3685 "%s", ass
->get_description().c_str());
3686 set_valuetype(V_ERROR
);
3691 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3692 Type::expected_value_t exp_val
)
3694 v
->set_lowerid_to_ref(); // can only be reference to enum
3695 Type
*t
= v
->get_expr_governor(exp_val
);
3696 if (v
->valuetype
==V_ERROR
) return;
3698 v
->error("Please use reference to an enumerated value as the operand of "
3699 "operation `%s'", get_opname());
3700 set_valuetype(V_ERROR
);
3703 t
= t
->get_type_refd_last();
3704 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3705 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3706 set_valuetype(V_ERROR
);
3708 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3709 v
->error("The operand of operation `%s' cannot be omit", opname
);
3710 set_valuetype(V_ERROR
);
3714 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3717 const Location
*loc
)
3719 if(tt
==Type::T_BOOL
) return;
3720 if(tt
!=Type::T_ERROR
)
3721 loc
->error("%s operand of operation `%s' should be boolean value",
3723 set_valuetype(V_ERROR
);
3726 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3729 const Location
*loc
)
3731 if(tt
==Type::T_INT
) return;
3732 if(tt
!=Type::T_ERROR
)
3733 loc
->error("%s operand of operation `%s' should be integer value",
3735 set_valuetype(V_ERROR
);
3738 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3741 const Location
*loc
)
3743 if(tt
==Type::T_REAL
) return;
3744 else if(tt
==Type::T_INT
)
3745 loc
->error("%s operand of operation `%s' should be float value."
3746 " Perhaps you missed an int2float() conversion function"
3747 " or `.0' at the end of the number",
3749 else if(tt
!=Type::T_ERROR
)
3750 loc
->error("%s operand of operation `%s' should be float value",
3752 set_valuetype(V_ERROR
);
3755 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3758 const Location
*loc
)
3767 if(tt
!=Type::T_ERROR
)
3768 loc
->error("%s operand of operation `%s' should be integer"
3771 set_valuetype(V_ERROR
);
3774 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3777 const Location
*loc
)
3782 case Type::T_ENUM_T
:
3787 if(tt
!=Type::T_ERROR
)
3788 loc
->error("%s operand of operation `%s' should be integer, float"
3789 " or enumerated value", opnum
, opname
);
3790 set_valuetype(V_ERROR
);
3793 void Value::chk_expr_operandtype_list(Type
* t
,
3796 const Location
*loc
,
3799 if (valuetype
== V_ERROR
) return;
3800 if (t
->get_typetype() == Type::T_ERROR
) {
3801 set_valuetype(V_ERROR
);
3804 if (!t
->is_list_type(allow_array
)) {
3805 loc
->error("%s operand of operation `%s' should be a string, "
3806 "`record of'%s `set of'%s value", opnum
, opname
,
3807 allow_array
? "," : " or", allow_array
? " or array" : "");
3808 set_valuetype(V_ERROR
);
3811 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3812 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3815 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3816 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3817 if (info
.is_subtype_error()) {
3819 if (info
.needs_conversion()) set_needs_conversion();
3821 if (!info
.is_erroneous()) {
3822 error("%s operand of operation `%s' is of type `%s', but a value of "
3823 "type `%s' was expected here", opnum
, opname
,
3824 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3826 error("%s", info
.get_error_str_str().c_str());
3829 if (info
.needs_conversion())
3830 set_needs_conversion();
3834 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3837 const Location
*loc
)
3849 if(tt
!=Type::T_ERROR
)
3850 loc
->error("%s operand of operation `%s' should be string value",
3852 set_valuetype(V_ERROR
);
3855 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3858 const Location
*loc
)
3867 if(tt
!=Type::T_ERROR
)
3868 loc
->error("%s operand of operation `%s' should be (universal)"
3869 " charstring value",
3871 set_valuetype(V_ERROR
);
3874 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3877 const Location
*loc
)
3879 if(tt
==Type::T_CSTR
) return;
3880 if(tt
!=Type::T_ERROR
)
3881 loc
->error("%s operand of operation `%s' should be charstring value",
3883 set_valuetype(V_ERROR
);
3886 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3889 const Location
*loc
)
3899 if(tt
!=Type::T_ERROR
)
3900 loc
->error("%s operand of operation `%s' should be binary string value",
3902 set_valuetype(V_ERROR
);
3905 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3908 const Location
*loc
)
3910 if(tt
==Type::T_BSTR
) return;
3911 if(tt
!=Type::T_ERROR
)
3912 loc
->error("%s operand of operation `%s' should be bitstring value",
3914 set_valuetype(V_ERROR
);
3917 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3920 const Location
*loc
)
3922 if(tt
==Type::T_HSTR
) return;
3923 if(tt
!=Type::T_ERROR
)
3924 loc
->error("%s operand of operation `%s' should be hexstring value",
3926 set_valuetype(V_ERROR
);
3929 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3932 const Location
*loc
)
3934 if(tt
==Type::T_OSTR
) return;
3935 if(tt
!=Type::T_ERROR
)
3936 loc
->error("%s operand of operation `%s' should be octetstring value",
3938 set_valuetype(V_ERROR
);
3941 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3942 Type::typetype_t tt2
,
3945 if(valuetype
==V_ERROR
) return;
3946 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3947 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3948 set_valuetype(V_ERROR
);
3951 if(tt1
==tt2
) return;
3952 error("The operands of operation `%s' should be of same type", opname
);
3953 set_valuetype(V_ERROR
);
3956 /* For predefined functions. */
3957 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3958 Type::typetype_t tt2
,
3963 if(valuetype
==V_ERROR
) return;
3964 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3965 set_valuetype(V_ERROR
);
3968 if(tt1
==tt2
) return;
3969 error("The %s and %s operands of operation `%s' should be of same type",
3970 opnum1
, opnum2
, opname
);
3971 set_valuetype(V_ERROR
);
3974 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3975 Value
*v1
, Value
*v2
,
3980 if (valuetype
== V_ERROR
) return;
3981 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3982 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3983 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3985 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3986 set_valuetype(V_ERROR
);
3989 if (tt1
== Type::T_UNDEF
) {
3990 if (tt2
== Type::T_UNDEF
) {
3991 if (v1
->is_undef_lowerid()) {
3992 if (v2
->is_undef_lowerid()) {
3993 Scope
*scope
= get_my_scope();
3994 Module
*my_mod
= scope
->get_scope_mod();
3995 const Identifier
& id1
= v1
->get_undef_lowerid();
3996 if (scope
->has_ass_withId(id1
)
3997 || my_mod
->has_imported_ass_withId(id1
)) {
3998 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3999 * should examine this situation better, but now I suppose
4000 * the first is ref, not enum. */
4001 v1
->set_lowerid_to_ref();
4004 const Identifier
& id2
= v2
->get_undef_lowerid();
4005 if (scope
->has_ass_withId(id2
)
4006 || my_mod
->has_imported_ass_withId(id2
)) {
4007 v2
->set_lowerid_to_ref();
4011 /* This is perhaps enum-enum, but it has no real
4012 * significance, so this should be an error. */
4014 v1
->set_lowerid_to_ref();
4017 } else if (v2
->is_undef_lowerid()) {
4018 v2
->set_lowerid_to_ref();
4021 error("Cannot determine the type of the operands in operation `%s'",
4023 set_valuetype(V_ERROR
);
4025 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
4026 v1
->set_lowerid_to_ref();
4029 /* v1 is something undefined, but not lowerid; v2 has
4030 * returntype (perhaps also governor) */
4032 } else if (tt2
== Type::T_UNDEF
) {
4033 /* but tt1 is not undef */
4034 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
4035 v2
->set_lowerid_to_ref();
4038 /* v2 is something undefined, but not lowerid; v1 has
4039 * returntype (perhaps also governor) */
4043 /* Now undef_lower_id's are converted to references, or the other
4044 * value has governor; let's see the governors, if they exist. */
4045 Type
*t1
= v1
->get_expr_governor(exp_val
);
4046 Type
*t2
= v2
->get_expr_governor(exp_val
);
4049 // Both value has governor. Are they compatible? According to 7.1.2
4050 // and C.34 it's required to have the same root types for
4051 // OPTYPE_{CONCAT,REPLACE}.
4052 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
4053 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4054 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
4055 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4056 TypeChain l_chain1
, l_chain2
;
4057 TypeChain r_chain1
, r_chain2
;
4058 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
4059 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
4060 if (!compat_t1
&& !compat_t2
) {
4061 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
4062 // the subtypes don't need to be compatible here
4063 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
4064 error("The operands of operation `%s' should be of compatible "
4065 "types", get_opname());
4066 set_valuetype(V_ERROR
);
4068 if (info1
.needs_conversion() || info2
.needs_conversion()) {
4069 set_needs_conversion(); // Avoid folding.
4074 if (info1
.is_erroneous())
4075 v1
->error("%s", info1
.get_error_str_str().c_str());
4076 else if (info2
.is_erroneous())
4077 v2
->error("%s", info2
.get_error_str_str().c_str());
4078 set_valuetype(V_ERROR
);
4081 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
4082 set_needs_conversion(); // Avoid folding.
4087 v2
->set_my_governor(t1
);
4088 t1
->chk_this_value_ref(v2
);
4089 if (v2
->valuetype
== V_OMIT
) {
4090 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4092 v1
->chk_expr_omit_comparison(exp_val
);
4094 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4096 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4097 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4102 v1
->set_my_governor(t2
);
4103 t2
->chk_this_value_ref(v1
);
4104 if (v1
->valuetype
== V_OMIT
) {
4105 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4107 v2
->chk_expr_omit_comparison(exp_val
);
4109 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4111 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4112 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4116 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4117 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
4118 // Here, it cannot be that both are T_UNDEF.
4119 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4120 error("Please use reference as %s operand of operator `%s'",
4121 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
4122 set_valuetype(V_ERROR
);
4125 // Deny type compatibility if no governors found. The typetype_t must
4126 // be the same. TODO: How can this happen?
4127 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
4128 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
4129 error("The operands of operation `%s' should be of compatible types",
4131 set_valuetype(V_ERROR
);
4136 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
4137 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
4139 if(valuetype
==V_ERROR
) return;
4140 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4141 Assignment
*t_ass
= ref
->get_refd_assignment();
4142 if(!t_ass
) goto error
;
4143 switch(t_ass
->get_asstype()) {
4144 case Assignment::A_TIMER
:
4145 case Assignment::A_PAR_TIMER
:
4146 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
4147 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
4148 chk_expr_dynamic_part(exp_val
, true);
4150 case Assignment::A_CONST
:
4151 case Assignment::A_EXT_CONST
:
4152 case Assignment::A_MODULEPAR
:
4153 case Assignment::A_VAR
:
4154 case Assignment::A_FUNCTION_RVAL
:
4155 case Assignment::A_EXT_FUNCTION_RVAL
:
4156 case Assignment::A_PAR_VAL_IN
:
4157 case Assignment::A_PAR_VAL_OUT
:
4158 case Assignment::A_PAR_VAL_INOUT
: {
4159 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
4160 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
4161 val
->set_my_scope(my_scope
);
4162 val
->set_fullname(u
.expr
.r1
->get_fullname());
4163 val
->set_location(*u
.expr
.r1
);
4165 chk_expr_operand_compref(val
, opnum
, get_opname());
4166 chk_expr_dynamic_part(exp_val
, false);
4169 ref
->error("%s operand of operation `%s' should be timer or"
4170 " component reference instead of %s",
4171 opnum
, opname
, t_ass
->get_description().c_str());
4176 set_valuetype(V_ERROR
);
4179 Type
*Value::chk_expr_operand_comptyperef_create()
4181 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4182 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4183 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4184 if (!t_ass
) goto error
;
4185 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4186 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4187 Type::EXPECTED_DYNAMIC_VALUE
);
4188 if (!t_type
) goto error
;
4189 t_type
= t_type
->get_type_refd_last();
4190 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4192 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4193 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4194 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4195 u
.expr
.r1
->error("Incompatible component types: operation "
4196 "`create' should refer to `%s' instead of "
4198 my_governor_last
->get_typename().c_str(),
4199 t_type
->get_typename().c_str());
4205 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4206 "expected in operation `create' instead of `%s'",
4207 t_type
->get_typename().c_str());
4210 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4211 "instead of %s", t_ass
->get_description().c_str());
4214 set_valuetype(V_ERROR
);
4218 void Value::chk_expr_comptype_compat()
4220 if (valuetype
!= V_EXPR
)
4221 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4222 if (!my_governor
|| !my_scope
) return;
4223 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4224 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4226 switch (u
.expr
.v_optype
) {
4227 case OPTYPE_COMP_MTC
:
4228 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4230 case OPTYPE_COMP_SYSTEM
:
4231 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4233 case OPTYPE_COMP_SELF
: {
4234 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4235 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4238 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4243 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4244 error("Incompatible component types: a component reference of "
4245 "type `%s' was expected, but `%s' has type `%s'",
4246 my_governor_last
->get_typename().c_str(), get_opname(),
4247 t_comptype
->get_typename().c_str());
4248 set_valuetype(V_ERROR
);
4252 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4255 if(valuetype
== V_ERROR
) return;
4256 switch(val
->get_valuetype()) {
4258 Error_Context
cntxt(this, "In `%s' operation", opname
);
4259 Value
*v_last
= val
->get_value_refd_last();
4260 if(!v_last
) goto error
;
4261 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4263 t
= t
->get_type_refd_last();
4264 if(t
->get_typetype() != Type::T_COMPONENT
) {
4265 v_last
->error("%s operand of operation `%s': Type mismatch:"
4266 " component reference was expected instead of `%s'",
4267 opnum
, opname
, t
->get_typename().c_str());
4272 Reference
*ref
= val
->get_reference();
4273 Assignment
*t_ass
= ref
->get_refd_assignment();
4275 if (!t_ass
) goto error
;
4276 switch(t_ass
->get_asstype()) {
4277 case Assignment::A_CONST
:
4278 t_val
= t_ass
->get_Value();
4280 case Assignment::A_EXT_CONST
:
4281 case Assignment::A_MODULEPAR
:
4282 case Assignment::A_VAR
:
4283 case Assignment::A_FUNCTION_RVAL
:
4284 case Assignment::A_EXT_FUNCTION_RVAL
:
4285 case Assignment::A_PAR_VAL_IN
:
4286 case Assignment::A_PAR_VAL_OUT
:
4287 case Assignment::A_PAR_VAL_INOUT
: {
4288 Type
*t_type
=t_ass
->get_Type()
4289 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4290 if(!t_type
) goto error
;
4291 t_type
=t_type
->get_type_refd_last();
4292 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4293 ref
->error("%s operand of operation `%s': Type mismatch:"
4294 " component reference was expected instead of `%s'",
4295 opnum
, opname
, t_type
->get_typename().c_str());
4300 ref
->error("%s operand of operation `%s' should be"
4301 " component reference instead of %s",
4302 opnum
, opname
, t_ass
->get_description().c_str());
4306 ReferenceChain
refch(this, "While searching referenced value");
4307 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4309 t_val
= t_val
->get_value_refd_last();
4310 if (t_val
->valuetype
!= V_EXPR
) return;
4311 switch (t_val
->u
.expr
.v_optype
) {
4312 case OPTYPE_COMP_NULL
:
4313 ref
->error("%s operand of operation `%s' refers to `null' component "
4314 "reference", opnum
, opname
);
4316 case OPTYPE_COMP_MTC
:
4317 ref
->error("%s operand of operation `%s' refers to the component "
4318 "reference of the `mtc'", opnum
, opname
);
4320 case OPTYPE_COMP_SYSTEM
:
4321 ref
->error("%s operand of operation `%s' refers to the component "
4322 "reference of the `system'", opnum
, opname
);
4330 FATAL_ERROR("Value::chk_expr_operand_compref()");
4333 set_valuetype(V_ERROR
);
4336 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4340 if(valuetype
==V_ERROR
) return;
4341 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4342 Assignment
*t_ass
= ref
->get_refd_assignment();
4343 if(!t_ass
) goto error
;
4344 switch(t_ass
->get_asstype()) {
4345 case Assignment::A_TIMER
: {
4346 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4347 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4348 Type::EXPECTED_DYNAMIC_VALUE
);
4349 else if (ref
->get_subrefs()) {
4350 ref
->error("%s operand of operation `%s': "
4351 "Reference to single timer `%s' cannot have field or array "
4352 "sub-references", opnum
, opname
,
4353 t_ass
->get_id().get_dispname().c_str());
4357 case Assignment::A_PAR_TIMER
:
4358 if (ref
->get_subrefs()) {
4359 ref
->error("%s operand of operation `%s': "
4360 "Reference to %s cannot have field or array sub-references",
4361 opnum
, opname
, t_ass
->get_description().c_str());
4366 ref
->error("%s operand of operation `%s' should be timer"
4368 opnum
, opname
, t_ass
->get_description().c_str());
4373 set_valuetype(V_ERROR
);
4376 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4380 if(valuetype
==V_ERROR
) return;
4381 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4382 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4383 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4384 Error_Context
cntxt(this, "In `%s' operation", opname
);
4385 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4388 void Value::chk_expr_operand_activate_refd(Value
*val
,
4389 Ttcn::TemplateInstances
* t_list2
,
4390 Ttcn::ActualParList
*&parlist
,
4394 if(valuetype
==V_ERROR
) return;
4395 Error_Context
cntxt(this, "In `%s' operation", opname
);
4396 Type
*t
= val
->get_expr_governor_last();
4398 switch (t
->get_typetype()) {
4400 set_valuetype(V_ERROR
);
4402 case Type::T_ALTSTEP
: {
4403 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4404 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4408 set_valuetype(V_ERROR
);
4410 parlist
->set_fullname(get_fullname());
4411 parlist
->set_my_scope(get_my_scope());
4412 if (!fp_list
->chk_activate_argument(parlist
,
4413 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4417 error("Reference to an altstep was expected in the argument of "
4418 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4419 set_valuetype(V_ERROR
);
4422 } else set_valuetype(V_ERROR
);
4425 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4429 if(valuetype
==V_ERROR
) return;
4430 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4431 Error_Context
cntxt(this, "In `%s' operation", opname
);
4432 Assignment
*t_ass
= ref
->get_refd_assignment();
4433 bool error_flag
= false;
4435 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4436 ref
->error("Reference to a testcase was expected in the argument "
4437 "instead of %s", t_ass
->get_description().c_str());
4440 } else error_flag
= true;
4442 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4443 Value
*v_last
= val
->get_value_refd_last();
4444 switch (v_last
->valuetype
) {
4446 ttcn3float v_real
= v_last
->get_val_Real();
4448 val
->error("The testcase guard timer has negative value: `%s'",
4449 Real2string(v_real
).c_str());
4460 if (error_flag
) set_valuetype(V_ERROR
);
4463 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4464 Ttcn::TemplateInstances
* t_list2
,
4465 Ttcn::ActualParList
*&parlist
,
4470 if(valuetype
==V_ERROR
) return;
4471 Error_Context
cntxt(this, "In `%s' operation", opname
);
4472 Type
*t
= v1
->get_expr_governor_last();
4474 switch (t
->get_typetype()) {
4476 set_valuetype(V_ERROR
);
4478 case Type::T_TESTCASE
: {
4479 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4480 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4484 set_valuetype(V_ERROR
);
4486 parlist
->set_fullname(get_fullname());
4487 parlist
->set_my_scope(get_my_scope());
4491 v1
->error("Reference to a value of type testcase was expected in the "
4492 "argument of `derefers()' instead of `%s'",
4493 t
->get_typename().c_str());
4494 set_valuetype(V_ERROR
);
4497 } else set_valuetype(V_ERROR
);
4499 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4500 Value
*v_last
= v3
->get_value_refd_last();
4501 switch (v_last
->valuetype
) {
4503 ttcn3float v_real
= v_last
->get_val_Real();
4505 v3
->error("The testcase guard timer has negative value: `%s'",
4506 Real2string(v_real
).c_str());
4507 set_valuetype(V_ERROR
);
4511 set_valuetype(V_ERROR
);
4519 void Value::chk_invoke(Type::expected_value_t exp_val
)
4521 if(valuetype
== V_ERROR
) return;
4522 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4523 if(!u
.invoke
.t_list
) return; //already checked
4524 Error_Context
cntxt(this, "In `apply()' operation");
4525 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4527 set_valuetype(V_ERROR
);
4530 switch (t
->get_typetype()) {
4532 set_valuetype(V_ERROR
);
4534 case Type::T_FUNCTION
:
4537 u
.invoke
.v
->error("A value of type function was expected in the "
4538 "argument instead of `%s'", t
->get_typename().c_str());
4539 set_valuetype(V_ERROR
);
4542 my_scope
->chk_runs_on_clause(t
, *this, "call");
4543 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4544 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4545 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4546 delete u
.invoke
.t_list
;
4547 u
.invoke
.t_list
= 0;
4550 u
.invoke
.ap_list
= 0;
4552 parlist
->set_fullname(get_fullname());
4553 parlist
->set_my_scope(get_my_scope());
4554 u
.invoke
.ap_list
= parlist
;
4557 case Type::EXPECTED_CONSTANT
:
4558 error("An evaluable constant value was expected instead of operation "
4560 set_valuetype(V_ERROR
);
4562 case Type::EXPECTED_STATIC_VALUE
:
4563 error("A static value was expected instead of operation `apply()'");
4564 set_valuetype(V_ERROR
);
4571 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4572 ReferenceChain
*refch
,
4573 Type::expected_value_t exp_val
)
4575 bool self_ref
= false;
4576 if(valuetype
==V_ERROR
) return;
4577 // Commented out to report more errors :)
4578 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4579 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4580 switch(val
->get_valuetype()) {
4582 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4587 val
->get_value_refd_last(refch
, exp_val
);
4592 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4597 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4598 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4600 bool self_ref
= false;
4602 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4603 ti
->error("Reference to a %s value was expected instead of an in-line "
4604 "modified template",
4605 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4606 set_valuetype(V_ERROR
);
4609 Template
*templ
= ti
->get_Template();
4610 switch (templ
->get_templatetype()) {
4611 case Template::TEMPLATE_REFD
:
4613 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4614 templ
= templ
->get_template_refd_last(refch
);
4615 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4616 set_valuetype(V_ERROR
);
4618 ti
->error("Reference to a %s value was expected instead of %s",
4619 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4620 templ
->get_reference()->get_refd_assignment()
4621 ->get_description().c_str());
4622 set_valuetype(V_ERROR
);
4625 case Template::SPECIFIC_VALUE
: {
4626 Value
*val
= templ
->get_specific_value();
4627 switch (val
->get_valuetype()) {
4629 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4632 val
->get_value_refd_last(refch
, exp_val
);
4636 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4638 case Template::TEMPLATE_ERROR
:
4639 set_valuetype(V_ERROR
);
4648 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4651 if(valuetype
==V_ERROR
) return;
4652 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4653 if(val
->is_unfoldable()) return;
4654 if(*val
->get_val_Int()<0) {
4655 val
->error("%s operand of operation `%s' should not be negative",
4657 set_valuetype(V_ERROR
);
4661 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4664 if(valuetype
==V_ERROR
) return;
4665 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4666 if(val
->is_unfoldable()) return;
4667 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4668 val
->error("%s operand of operation `%s' should be in range 0..127",
4670 set_valuetype(V_ERROR
);
4674 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4677 if(valuetype
==V_ERROR
) return;
4678 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4679 if(val
->is_unfoldable()) return;
4680 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4681 val
->error("%s operand of operation `%s' should be in range"
4682 " 0..2147483647", opnum
, opname
);
4683 set_valuetype(V_ERROR
);
4687 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4690 if(valuetype
==V_ERROR
) return;
4691 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4692 if(val
->is_unfoldable()) return;
4693 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4695 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4697 val
->error("%s operand of operation `%s' should not be zero",
4699 set_valuetype(V_ERROR
);
4703 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4706 if (valuetype
== V_ERROR
) return;
4707 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4708 if (val
->get_expr_returntype() != Type::T_INT
) return;
4709 if (val
->is_unfoldable()) return;
4710 const int_val_t
*val_int
= val
->get_val_Int();
4711 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4712 val
->error("%s operand of operation `%s' should be less than `%d' "
4713 "instead of `%s'", opnum
, opname
, INT_MAX
,
4714 (val_int
->t_str()).c_str());
4715 set_valuetype(V_ERROR
);
4719 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4722 if(valuetype
==V_ERROR
) return;
4723 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4724 if(val
->is_unfoldable()) return;
4725 if(val
->get_val_strlen()!=1) {
4726 val
->error("%s operand of operation `%s' should be of length 1",
4728 set_valuetype(V_ERROR
);
4732 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4735 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4736 Value
*v_last
= val
->get_value_refd_last();
4737 if (v_last
->valuetype
== V_CSTR
) {
4738 size_t len
= v_last
->get_val_strlen();
4740 val
->error("%s operand of operation `%s' should contain even number "
4741 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4742 set_valuetype(V_ERROR
);
4744 } else if (v_last
->valuetype
== V_REFD
) {
4745 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4746 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4747 val
->error("%s operand of operation `%s' should contain even number "
4748 "of characters, but a string element contains 1", opnum
, opname
);
4749 set_valuetype(V_ERROR
);
4754 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4757 if(valuetype
==V_ERROR
) return;
4758 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4759 if(val
->is_unfoldable()) return;
4760 const string
& s
=val
->get_val_str();
4761 for(size_t i
=0; i
<s
.size(); i
++) {
4763 if(!(c
=='0' || c
=='1')) {
4764 val
->error("%s operand of operation `%s' can contain only"
4765 " binary digits (position %lu is `%c')",
4766 opnum
, opname
, (unsigned long) i
, c
);
4767 set_valuetype(V_ERROR
);
4773 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4776 if(valuetype
==V_ERROR
) return;
4777 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4778 if(val
->is_unfoldable()) return;
4779 const string
& s
=val
->get_val_str();
4780 for(size_t i
=0; i
<s
.size(); i
++) {
4782 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4783 val
->error("%s operand of operation `%s' can contain only valid "
4784 "hexadecimal digits (position %lu is `%c')",
4785 opnum
, opname
, (unsigned long) i
, c
);
4786 set_valuetype(V_ERROR
);
4792 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4795 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4796 Value
*v
= val
->get_value_refd_last();
4797 if (v
->valuetype
!= V_OSTR
) return;
4798 const string
& s
= val
->get_val_str();
4799 size_t n_octets
= s
.size() / 2;
4800 for (size_t i
= 0; i
< n_octets
; i
++) {
4802 if (!(c
>= '0' && c
<= '7')) {
4803 val
->error("%s operand of operation `%s' shall consist of octets "
4804 "within the range 00 .. 7F, but the string `%s'O contains octet "
4805 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4807 set_valuetype(V_ERROR
);
4813 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4816 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4817 Value
*v_last
= val
->get_value_refd_last();
4818 if (v_last
->valuetype
!= V_CSTR
) return;
4819 const string
& s
= v_last
->get_val_str();
4820 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4822 // state: expected characters
4823 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4824 // S_FIRST: first digit
4825 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4826 // S_END: trailing whitespace
4827 // S_ERR: error was found, stop
4828 for (size_t i
= 0; i
< s
.size(); i
++) {
4833 if (c
== '+' || c
== '-') state
= S_FIRST
;
4834 else if (c
== '0') state
= S_ZERO
;
4835 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4836 else if (string::is_whitespace(c
)) {
4837 if (state
== S_INITIAL
) {
4838 val
->warning("Leading whitespace was detected and ignored in the "
4839 "operand of operation `%s'", opname
);
4840 state
= S_INITIAL_WS
;
4842 } else state
= S_ERR
;
4845 if (c
== '0') state
= S_ZERO
;
4846 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4850 if (c
>= '0' && c
<= '9') {
4851 val
->warning("Leading zero digit was detected and ignored in the "
4852 "operand of operation `%s'", opname
);
4854 } else if (string::is_whitespace(c
)) state
= S_END
;
4858 if (c
>= '0' && c
<= '9') {}
4859 else if (string::is_whitespace(c
)) state
= S_END
;
4863 if (!string::is_whitespace(c
)) state
= S_ERR
;
4868 if (state
== S_ERR
) {
4869 if (string::is_printable(c
)) {
4870 val
->error("%s operand of operation `%s' should be a string "
4871 "containing a valid integer value, but invalid character `%c' "
4872 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4874 val
->error("%s operand of operation `%s' should be a string "
4875 "containing a valid integer value, but invalid character with "
4876 "character code %u was detected at index %lu", opnum
, opname
, c
,
4879 set_valuetype(V_ERROR
);
4886 val
->error("%s operand of operation `%s' should be a string containing a "
4887 "valid integer value instead of an empty string", opnum
, opname
);
4888 set_valuetype(V_ERROR
);
4891 val
->error("%s operand of operation `%s' should be a string containing a "
4892 "valid integer value, but only a sign character was detected", opnum
,
4894 set_valuetype(V_ERROR
);
4897 val
->warning("Trailing whitespace was detected and ignored in the "
4898 "operand of operation `%s'", opname
);
4905 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4908 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4909 Value
*v_last
= val
->get_value_refd_last();
4910 if (v_last
->valuetype
== V_REFD
) {
4911 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4912 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4913 val
->error("%s operand of operation `%s' should be a string containing "
4914 "a valid float value instead of a string element, which cannot "
4915 "represent a floating point number", opnum
, opname
);
4916 set_valuetype(V_ERROR
);
4919 } else if (v_last
->valuetype
!= V_CSTR
) return;
4920 const string
& s
= v_last
->get_val_str();
4921 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4922 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4924 // state: expected characters
4925 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4926 // leading whitespace
4927 // S_FIRST_M: first digit of integer part in mantissa
4928 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4929 // S_FIRST_F: first digit of fraction
4930 // S_MORE_F: more digits of fraction, E, trailing whitespace
4931 // S_INITIAL_E: +, -, first digit of exponent
4932 // S_FIRST_E: first digit of exponent
4933 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4934 // S_END: trailing whitespace
4935 // S_ERR: error was found, stop
4936 for (size_t i
= 0; i
< s
.size(); i
++) {
4941 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4942 else if (c
== '0') state
= S_ZERO_M
;
4943 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4944 else if (string::is_whitespace(c
)) {
4945 if (state
== S_INITIAL
) {
4946 val
->warning("Leading whitespace was detected and ignored in the "
4947 "operand of operation `%s'", opname
);
4948 state
= S_INITIAL_WS
;
4950 } else state
= S_ERR
;
4953 if (c
== '0') state
= S_ZERO_M
;
4954 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4958 if (c
== '.') state
= S_FIRST_F
;
4959 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4960 else if (c
>= '0' && c
<= '9') {
4961 val
->warning("Leading zero digit was detected and ignored in the "
4962 "mantissa of the operand of operation `%s'", opname
);
4964 } else state
= S_ERR
;
4967 if (c
== '.') state
= S_FIRST_F
;
4968 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4969 else if (c
>= '0' && c
<= '9') {}
4973 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4977 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4978 else if (c
>= '0' && c
<= '9') {}
4979 else if (string::is_whitespace(c
)) state
= S_END
;
4983 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4984 else if (c
== '0') state
= S_ZERO_E
;
4985 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4989 if (c
== '0') state
= S_ZERO_E
;
4990 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4994 if (c
>= '0' && c
<= '9') {
4995 val
->warning("Leading zero digit was detected and ignored in the "
4996 "exponent of the operand of operation `%s'", opname
);
4998 } else if (string::is_whitespace(c
)) state
= S_END
;
5002 if (c
>= '0' && c
<= '9') {}
5003 else if (string::is_whitespace(c
)) state
= S_END
;
5007 if (!string::is_whitespace(c
)) state
= S_ERR
;
5012 if (state
== S_ERR
) {
5013 if (string::is_printable(c
)) {
5014 val
->error("%s operand of operation `%s' should be a string "
5015 "containing a valid float value, but invalid character `%c' "
5016 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
5018 val
->error("%s operand of operation `%s' should be a string "
5019 "containing a valid float value, but invalid character with "
5020 "character code %u was detected at index %lu", opnum
, opname
, c
,
5023 set_valuetype(V_ERROR
);
5030 val
->error("%s operand of operation `%s' should be a string containing a "
5031 "valid float value instead of an empty string", opnum
, opname
);
5032 set_valuetype(V_ERROR
);
5035 val
->error("%s operand of operation `%s' should be a string containing a "
5036 "valid float value, but only a sign character was detected", opnum
,
5038 set_valuetype(V_ERROR
);
5042 // HL67862: Missing decimal dot allowed for str2float
5045 // HL67862: Missing fraction part is allowed for str2float
5049 val
->error("%s operand of operation `%s' should be a string containing a "
5050 "valid float value, but the exponent is missing after the `E' sign",
5052 set_valuetype(V_ERROR
);
5055 val
->warning("Trailing whitespace was detected and ignored in the "
5056 "operand of operation `%s'", opname
);
5063 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
5066 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5067 Value
*v
= val
->get_value_refd_last();
5068 if (v
->valuetype
!= V_USTR
) return;
5069 const ustring
& us
= v
->get_val_ustr();
5070 for (size_t i
= 0; i
< us
.size(); i
++) {
5071 const ustring::universal_char
& uchar
= us
[i
];
5072 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
5074 val
->error("%s operand of operation `%s' shall consist of characters "
5075 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5076 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5077 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
5078 uchar
.row
, uchar
.cell
, (unsigned long) i
);
5079 set_valuetype(V_ERROR
);
5085 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
5088 if(valuetype
==V_ERROR
) return;
5089 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5090 if(val
->is_unfoldable()) return;
5091 const string
& bstr
=val
->get_val_str();
5092 // see also PredefFunc.cc::bit2int()
5093 size_t nof_bits
= bstr
.size();
5094 // skip the leading zeros
5095 size_t start_index
= 0;
5096 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
5097 // check whether the remaining bits fit in Int
5098 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
5099 val
->error("%s operand of operation `%s' is too large (maximum number"
5100 " of bits in integer is %lu)",
5101 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5102 set_valuetype(V_ERROR
);
5106 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
5109 if(valuetype
==V_ERROR
) return;
5110 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5111 if(val
->is_unfoldable()) return;
5112 const string
& hstr
=val
->get_val_str();
5113 // see also PredefFunc.cc::hex2int()
5114 size_t nof_digits
= hstr
.size();
5115 // skip the leading zeros
5116 size_t start_index
= 0;
5117 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
5118 // check whether the remaining hex digits fit in Int
5119 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
5120 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
5121 char_to_hexdigit(hstr
[start_index
]) > 7)) {
5122 val
->error("%s operand of operation `%s' is too large (maximum number"
5123 " of bits in integer is %lu)",
5124 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5125 set_valuetype(V_ERROR
);
5129 void Value::chk_expr_operands_int2binstr()
5131 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5132 if (u
.expr
.v1
->is_unfoldable()) return;
5133 if (u
.expr
.v2
->is_unfoldable()) return;
5134 // It is already checked that i1 and i2 are non-negative.
5135 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5136 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
5137 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
5138 if (!i2
->is_native()) {
5139 u
.expr
.v2
->error("The length of the resulting string is too large for "
5140 "being represented in memory");
5141 set_valuetype(V_ERROR
);
5144 Int nof_bits
= i2
->get_val();
5145 if (u
.expr
.v1
->is_unfoldable()) return;
5146 switch (u
.expr
.v_optype
) {
5147 case OPTYPE_INT2BIT
:
5149 case OPTYPE_INT2HEX
:
5152 case OPTYPE_INT2OCT
:
5156 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5158 if (*i1
>> nof_bits
> 0) { // Expensive?
5159 u
.expr
.v1
->error("Value %s does not fit in length %s",
5160 i1
->t_str().c_str(), i2
->t_str().c_str());
5161 set_valuetype(V_ERROR
);
5165 void Value::chk_expr_operands_str_samelen()
5167 if(valuetype
==V_ERROR
) return;
5168 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5169 Value
*v1
=u
.expr
.v1
;
5170 if(v1
->is_unfoldable()) return;
5171 Value
*v2
=u
.expr
.v2
;
5172 if(v2
->is_unfoldable()) return;
5173 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5174 size_t i1
=v1
->get_val_strlen();
5175 size_t i2
=v2
->get_val_strlen();
5177 error("The operands should have the same length");
5178 set_valuetype(V_ERROR
);
5182 void Value::chk_expr_operands_replace()
5184 // The fourth operand doesn't need to be checked at all here.
5185 if(valuetype
==V_ERROR
) return;
5186 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5187 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5190 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5191 size_t list_len
= 0;
5192 bool list_len_known
= false;
5193 if (v1
->valuetype
== V_REFD
) {
5194 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5195 if (subrefs
&& subrefs
->refers_to_string_element()) {
5196 warning("Replacing a string element does not make any sense");
5198 list_len_known
= true;
5201 if (!v1
->is_unfoldable()) {
5202 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5203 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5204 list_len_known
= true;
5206 if (!list_len_known
) return;
5207 if (u
.expr
.v2
->is_unfoldable()) {
5208 if (!u
.expr
.v3
->is_unfoldable()) {
5209 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5210 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5211 error("Third operand `len' (%s) is greater than the length of "
5212 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5213 (unsigned long)list_len
);
5214 set_valuetype(V_ERROR
);
5218 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5219 if (u
.expr
.v3
->is_unfoldable()) {
5220 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5221 error("Second operand `index' (%s) is greater than the length of "
5222 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5223 (unsigned long)list_len
);
5224 set_valuetype(V_ERROR
);
5227 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5228 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5229 error("The sum of second operand `index' (%s) and third operand "
5230 "`len' (%s) is greater than the length of the first operand (%lu)",
5231 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5232 (unsigned long)list_len
);
5233 set_valuetype(V_ERROR
);
5239 void Value::chk_expr_operands_substr()
5241 if(valuetype
==V_ERROR
) return;
5242 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5243 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5246 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5247 size_t list_len
= 0;
5248 bool list_len_known
= false;
5249 if (v1
->valuetype
== V_REFD
) {
5250 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5251 if (subrefs
&& subrefs
->refers_to_string_element()) {
5252 warning("Taking the substring of a string element does not make any "
5255 list_len_known
= true;
5258 if (!list_len_known
&& !v1
->is_unfoldable()) {
5259 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5260 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5261 list_len_known
= true;
5263 // Do nothing if the length of the first operand is unknown.
5264 if (!list_len_known
) return;
5265 if (u
.expr
.v2
->is_unfoldable()) {
5266 if (!u
.expr
.v3
->is_unfoldable()) {
5267 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5268 // Only the third operand is known.
5269 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5270 error("Third operand `returncount' (%s) is greater than the "
5271 "length of the first operand (%lu)",
5272 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5273 set_valuetype(V_ERROR
);
5277 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5278 if (u
.expr
.v3
->is_unfoldable()) {
5279 // Only the second operand is known.
5280 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5281 error("Second operand `index' (%s) is greater than the length "
5282 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5283 (unsigned long)list_len
);
5284 set_valuetype(V_ERROR
);
5287 // Both second and third operands are known.
5288 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5289 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5290 error("The sum of second operand `index' (%s) and third operand "
5291 "`returncount' (%s) is greater than the length of the first operand "
5292 "(%lu)", (index_int_2
->t_str()).c_str(),
5293 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5294 set_valuetype(V_ERROR
);
5300 void Value::chk_expr_operands_regexp()
5302 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5303 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5304 Value
* v2
= u
.expr
.t2
->get_specific_value();
5305 if (!v1
|| !v2
) return;
5307 Error_Context
cntxt(this, "In operation `regexp()'");
5308 Value
* v1_last
= v1
->get_value_refd_last();
5309 if (v1_last
->valuetype
== V_CSTR
) {
5310 // the input string is available at compile time
5311 const string
& instr
= v1_last
->get_val_str();
5312 const char *input_str
= instr
.c_str();
5313 size_t instr_len
= strlen(input_str
);
5314 if (instr_len
< instr
.size()) {
5315 v1
->warning("The first operand of `regexp()' contains a "
5316 "character with character code zero at index %s. The rest of the "
5317 "string will be ignored during matching",
5318 Int2string(instr_len
).c_str());
5322 size_t nof_groups
= 0;
5323 Value
*v2_last
= v2
->get_value_refd_last();
5325 if (v2_last
->valuetype
== V_CSTR
) {
5326 // the pattern is available at compile time
5327 const string
& expression
= v2_last
->get_val_str();
5328 const char *pattern_str
= expression
.c_str();
5329 size_t pattern_len
= strlen(pattern_str
);
5330 if (pattern_len
< expression
.size()) {
5331 v2
->warning("The second operand of `regexp()' contains a "
5332 "character with character code zero at index %s. The rest of the "
5333 "string will be ignored during matching",
5334 Int2string(pattern_len
).c_str());
5338 Error_Context
cntxt2(v2
, "In character string pattern");
5339 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5341 if (posix_str
!= NULL
) {
5342 regex_t posix_regexp
;
5343 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5346 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5347 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5348 "regcomp() failed: %s", msg
);
5350 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5352 v2
->error("The character pattern in the second operand of "
5353 "`regexp()' does not contain any groups");
5354 set_valuetype(V_ERROR
);
5356 regfree(&posix_regexp
);
5359 // the pattern is faulty
5360 // the error has been reported by TTCN_pattern_to_regexp
5361 set_valuetype(V_ERROR
);
5364 if (nof_groups
> 0) {
5365 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5366 if (v3
->valuetype
== V_INT
) {
5367 // the group number is available at compile time
5368 const int_val_t
*groupno_int
= v3
->get_val_Int();
5369 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5370 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5371 "large: The requested group index is %s, but the pattern "
5372 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5373 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5374 set_valuetype(V_ERROR
);
5380 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5381 Type::expected_value_t exp_val
)
5383 const char *opname
= get_opname();
5384 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5386 const Location
*loc
;
5387 bool error_flag
= false;
5388 switch (u
.expr
.v_optype
) {
5389 case OPTYPE_ISCHOSEN_V
:
5390 // u.expr.v1 is always a referenced value
5391 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5393 u
.expr
.v1
->set_my_governor(t_governor
);
5394 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5395 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5396 } else error_flag
= true;
5399 case OPTYPE_ISCHOSEN_T
:
5400 // u.expr.t1 is always a referenced template
5401 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5402 exp_val
= Type::EXPECTED_TEMPLATE
;
5403 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5405 u
.expr
.t1
->set_my_governor(t_governor
);
5407 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5409 u
.expr
.t1
->get_template_refd_last(refch
);
5410 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5412 } else error_flag
= true;
5413 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5414 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5415 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5416 u
.expr
.t1
->get_reference()->get_refd_assignment()
5417 ->get_description().c_str());
5423 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5428 t_governor
= t_governor
->get_type_refd_last();
5429 switch (t_governor
->get_typetype()) {
5433 case Type::T_CHOICE_A
:
5434 case Type::T_CHOICE_T
:
5435 case Type::T_ANYTYPE
:
5436 case Type::T_OPENTYPE
:
5437 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5438 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5439 "%s does not have a field named `%s'" :
5440 "Union type `%s' does not have a field named `%s'",
5441 t_governor
->get_typename().c_str(),
5442 u
.expr
.i2
->get_dispname().c_str());
5447 loc
->error("The operand of operation `%s' should be a union value "
5448 "or template instead of `%s'", opname
,
5449 t_governor
->get_typename().c_str());
5454 if (error_flag
) set_valuetype(V_ERROR
);
5457 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5458 Type::expected_value_t exp_val
) {
5460 Error_Context
cntxt(this, "In the parameter of %s",
5461 u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
? "encvalue_unichar()" : "encvalue()");
5462 Type
t_chk(Type::T_ERROR
);
5465 Type::expected_value_t ti_exp_val
= exp_val
;
5466 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5467 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5469 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5471 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5472 if (valuetype
!=V_ERROR
)
5473 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5474 t_type
= t_type
->get_type_refd_last();
5476 error("Cannot determine type of value");
5481 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5482 error("Expecting a value of a type with coding attributes in first"
5483 "parameter of encvalue() which belongs to a generic type '%s'",
5484 t_type->get_typename().c_str());
5488 if(!disable_attribute_validation()) {
5489 t_type
->chk_coding(true);
5492 switch (t_type
->get_typetype()) {
5497 case Type::T_REFDSPEC
:
5498 case Type::T_SELTYPE
:
5499 case Type::T_VERDICT
:
5501 case Type::T_COMPONENT
:
5502 case Type::T_DEFAULT
:
5503 case Type::T_SIGNATURE
:
5504 case Type::T_FUNCTION
:
5505 case Type::T_ALTSTEP
:
5506 case Type::T_TESTCASE
:
5507 error("Type of parameter of encvalue() cannot be '%s'",
5508 t_type
->get_typename().c_str());
5515 set_valuetype(V_ERROR
);
5518 void Value::chk_expr_operands_decode(operationtype_t p_optype
)
5520 Error_Context
cntxt(this, "In the parameters of %s",
5521 p_optype
== OPTYPE_DECVALUE_UNICHAR
? "decvalue_unichar()" : "decvalue()");
5522 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5523 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5525 Assignment
* t_ass
= ref
->get_refd_assignment();
5528 error("Could not determine the assignment for first parameter");
5531 switch (t_ass
->get_asstype()) {
5532 case Assignment::A_PAR_VAL_IN
:
5533 t_ass
->use_as_lvalue(*this);
5535 case Assignment::A_CONST
:
5536 case Assignment::A_EXT_CONST
:
5537 case Assignment::A_MODULEPAR
:
5538 case Assignment::A_MODULEPAR_TEMP
:
5539 case Assignment::A_TEMPLATE
:
5540 ref
->error("Reference to '%s' cannot be used as the first operand of "
5541 "the 'decvalue' operation", t_ass
->get_assname());
5544 case Assignment::A_VAR
:
5545 case Assignment::A_PAR_VAL_OUT
:
5546 case Assignment::A_PAR_VAL_INOUT
:
5548 case Assignment::A_VAR_TEMPLATE
:
5549 case Assignment::A_PAR_TEMPL_IN
:
5550 case Assignment::A_PAR_TEMPL_OUT
:
5551 case Assignment::A_PAR_TEMPL_INOUT
: {
5552 Template
* t
= new Template(ref
->clone());
5553 t
->set_location(*ref
);
5554 t
->set_my_scope(get_my_scope());
5555 t
->set_fullname(get_fullname()+".<operand>");
5556 Template
* t_last
= t
->get_template_refd_last();
5557 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5559 ref
->error("Specific value template was expected instead of '%s'.",
5560 t
->get_template_refd_last()->get_templatetype_str());
5567 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5570 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5571 Type::EXPECTED_DYNAMIC_VALUE
);
5577 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5578 error("First parameter has to be a bitstring");
5582 case OPTYPE_DECVALUE_UNICHAR
:
5583 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_USTR
){
5584 error("First parameter has to be a universal charstring");
5589 FATAL_ERROR("Value::chk_expr_decode_operands()");
5594 t_subrefs
= ref
->get_subrefs();
5595 t_ass
= ref
->get_refd_assignment();
5598 error("Could not determine the assignment for second parameter");
5601 // Extra check for HM59355.
5602 switch (t_ass
->get_asstype()) {
5603 case Assignment::A_VAR
:
5604 case Assignment::A_PAR_VAL_IN
:
5605 case Assignment::A_PAR_VAL_OUT
:
5606 case Assignment::A_PAR_VAL_INOUT
:
5609 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5612 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5613 Type::EXPECTED_DYNAMIC_VALUE
);
5617 t_type
= t_type
->get_type_refd_last();
5618 switch (t_type
->get_typetype()) {
5623 case Type::T_REFDSPEC
:
5624 case Type::T_SELTYPE
:
5625 case Type::T_VERDICT
:
5627 case Type::T_COMPONENT
:
5628 case Type::T_DEFAULT
:
5629 case Type::T_SIGNATURE
:
5630 case Type::T_FUNCTION
:
5631 case Type::T_ALTSTEP
:
5632 case Type::T_TESTCASE
:
5633 error("Type of second parameter cannot be %s",
5634 t_type
->get_typename().c_str());
5640 if(!disable_attribute_validation()) {
5641 t_type
->chk_coding(false);
5646 set_valuetype(V_ERROR
);
5649 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5651 Ttcn::FieldOrArrayRefs
*subrefs
;
5652 Identifier
*field_id
= 0;
5655 if (valuetype
== V_ERROR
) return;
5656 else if (valuetype
!= V_REFD
) {
5657 error("Only a referenced value can be compared with `omit'");
5660 subrefs
= u
.ref
.ref
->get_subrefs();
5661 if (subrefs
) field_id
= subrefs
->remove_last_field();
5663 error("Only a reference pointing to an optional record or set field "
5664 "can be compared with `omit'");
5667 t_ass
= u
.ref
.ref
->get_refd_assignment();
5668 if (!t_ass
) goto error
;
5669 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5670 if (!t_type
) goto error
;
5671 t_type
= t_type
->get_type_refd_last();
5672 switch (t_type
->get_typetype()) {
5681 error("Only a reference pointing to an optional field of a record"
5682 " or set type can be compared with `omit'");
5685 if (!t_type
->has_comp_withName(*field_id
)) {
5686 error("Type `%s' does not have field named `%s'",
5687 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5689 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5690 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5691 "`omit'", field_id
->get_dispname().c_str(),
5692 t_type
->get_typename().c_str());
5695 // putting the last field_id back to subrefs
5696 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5699 set_valuetype(V_ERROR
);
5703 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5704 Type::expected_value_t exp_val
)
5706 if(valuetype
==V_ERROR
) return -1;
5707 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5708 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5709 exp_val
=Type::EXPECTED_TEMPLATE
;
5711 Error_Context
cntxt(this, "In the operand of"
5712 " operation `%s'", get_opname());
5715 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5718 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5721 t_templ
= t_templ
->get_template_refd_last(refch
);
5723 // Timer and port arrays are handled separately
5724 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5725 Value
* val
= t_templ
->get_specific_value();
5726 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5727 val
->set_lowerid_to_ref();
5729 if (val
&& val
->get_valuetype() == V_REFD
) {
5730 Reference
* ref
= val
->get_reference();
5731 Assignment
* t_ass
= ref
->get_refd_assignment();
5732 Common::Assignment::asstype_t asstype
=
5733 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5734 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5735 if (t_ass
->get_Dimensions()) {
5736 // here we have a timer or port array
5737 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5738 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5739 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5740 Type::EXPECTED_DYNAMIC_VALUE
);
5743 refd_dim
= t_subrefs
->get_nof_refs();
5744 size_t nof_dims
= t_dims
->get_nof_dims();
5745 if (refd_dim
>= nof_dims
) {
5746 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5747 t_ass
->get_assname());
5748 set_valuetype(V_ERROR
);
5751 } else refd_dim
= 0;
5752 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5754 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5755 t_ass
->get_description().c_str());
5756 set_valuetype(V_ERROR
);
5765 Assignment
* t_ass
= 0;
5767 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5768 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5770 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5771 t_type
= t_type
->get_type_refd_last();
5773 error("Cannot determine type of value");
5777 if(valuetype
==V_ERROR
) return -1;
5779 t_templ
= t_templ
->get_template_refd_last(refch
);
5780 switch(t_templ
->get_templatetype()) {
5781 case Template::TEMPLATE_ERROR
:
5783 case Template::INDEXED_TEMPLATE_LIST
:
5785 case Template::TEMPLATE_REFD
:
5786 case Template::TEMPLATE_LIST
:
5787 case Template::NAMED_TEMPLATE_LIST
:
5790 case Template::SPECIFIC_VALUE
:
5792 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5794 switch(t_val
->get_valuetype()) {
5804 ref
= t_val
->get_reference();
5805 t_ass
= ref
->get_refd_assignment();
5806 t_subrefs
= ref
->get_subrefs();
5810 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5811 t_val
->create_stringRepr().c_str());
5818 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5819 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5824 switch(t_ass
->get_asstype()) {
5825 case Assignment::A_ERROR
:
5827 case Assignment::A_CONST
:
5828 t_val
= t_ass
->get_Value();
5830 case Assignment::A_EXT_CONST
:
5831 case Assignment::A_MODULEPAR
:
5832 case Assignment::A_MODULEPAR_TEMP
:
5833 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5834 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5835 "expected instead of %s", t_ass
->get_description().c_str());
5839 case Assignment::A_VAR
:
5840 case Assignment::A_PAR_VAL_IN
:
5841 case Assignment::A_PAR_VAL_OUT
:
5842 case Assignment::A_PAR_VAL_INOUT
:
5844 case Type::EXPECTED_CONSTANT
:
5845 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5846 t_ass
->get_description().c_str());
5849 case Type::EXPECTED_STATIC_VALUE
:
5850 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5851 t_ass
->get_description().c_str());
5858 case Assignment::A_TEMPLATE
:
5859 t_templ
= t_ass
->get_Template();
5861 case Assignment::A_VAR_TEMPLATE
:
5862 case Assignment::A_PAR_TEMPL_IN
:
5863 case Assignment::A_PAR_TEMPL_OUT
:
5864 case Assignment::A_PAR_TEMPL_INOUT
:
5865 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5866 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5867 t_ass
->get_description().c_str());
5870 case Assignment::A_FUNCTION_RVAL
:
5871 case Assignment::A_EXT_FUNCTION_RVAL
:
5873 case Type::EXPECTED_CONSTANT
:
5874 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5875 "the return value of %s", t_ass
->get_description().c_str());
5878 case Type::EXPECTED_STATIC_VALUE
:
5879 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5880 "the return value of %s", t_ass
->get_description().c_str());
5887 case Assignment::A_FUNCTION_RTEMP
:
5888 case Assignment::A_EXT_FUNCTION_RTEMP
:
5889 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5890 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5891 " of %s, which returns a template",
5892 t_ass
->get_description().c_str());
5895 case Assignment::A_TIMER
:
5896 case Assignment::A_PORT
:
5897 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5898 // sizeof is applicable to timer and port arrays
5899 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5901 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5902 t_ass
->get_description().c_str());
5905 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5906 Type::EXPECTED_DYNAMIC_VALUE
);
5909 refd_dim
= t_subrefs
->get_nof_refs();
5910 size_t nof_dims
= t_dims
->get_nof_dims();
5911 if (refd_dim
> nof_dims
) goto error
;
5912 else if (refd_dim
== nof_dims
) {
5913 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5914 t_ass
->get_assname());
5917 } else refd_dim
= 0;
5918 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5922 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5923 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5924 t_ass
->get_description().c_str());
5928 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5929 if (!t_type
) goto error
;
5930 t_type
= t_type
->get_type_refd_last();
5932 switch(t_type
->get_typetype()) {
5949 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5950 " set, set of, objid or array was expected");
5955 // check for index overflows in subrefs if possible
5957 switch (t_val
->get_valuetype()) {
5961 if (t_val
->is_indexed()) {
5968 /* The reference points to a constant. */
5969 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5970 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5971 if (!t_val
) goto error
;
5972 t_val
=t_val
->get_value_refd_last(refch
);
5973 } else { t_val
= 0; }
5974 } else if (t_templ
) {
5975 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5976 time. Don't try to evaluate it at compile time. */
5977 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5979 /* The reference points to a static template. */
5980 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5981 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5982 if (!t_templ
) goto error
;
5983 t_templ
= t_templ
->get_template_refd_last(refch
);
5984 } else { t_templ
= 0; }
5987 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5989 switch(t_templ
->get_templatetype()) {
5990 case Template::TEMPLATE_ERROR
:
5992 case Template::TEMPLATE_REFD
:
5996 case Template::SPECIFIC_VALUE
:
5997 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
6000 case Template::TEMPLATE_LIST
:
6001 case Template::NAMED_TEMPLATE_LIST
:
6004 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
6005 t_templ
->get_templatetype_str(),
6006 t_templ
->get_fullname().c_str());
6011 switch(t_val
->get_valuetype()) {
6022 // error is already reported
6031 if(t_type
->get_typetype()==Type::T_ARRAY
) {
6032 result
= t_type
->get_dimension()->get_size();
6034 else if(t_templ
) { // sizeof()
6035 switch(t_templ
->get_templatetype()) {
6036 case Template::TEMPLATE_LIST
:
6037 if(t_templ
->temps_contains_anyornone_symbol()) {
6038 if(t_templ
->is_length_restricted()) {
6039 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
6040 if (lr
->get_is_range()) {
6041 Value
*v_upper
= lr
->get_upper_value();
6043 if (v_upper
->valuetype
== V_INT
) {
6045 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
6046 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
6049 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
6050 "templates without exact size");
6055 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
6056 "templates containing `*' without upper boundary in the "
6057 "length restriction");
6061 Value
*v_single
= lr
->get_single_value();
6062 if (v_single
->valuetype
== V_INT
)
6063 result
= v_single
->u
.val_Int
->get_val();
6066 else { // not length restricted
6067 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
6068 " containing `*' without length restriction");
6072 else result
=t_templ
->get_nof_listitems();
6074 case Template::NAMED_TEMPLATE_LIST
:
6076 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
6077 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
6078 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
6081 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6085 switch(t_val
->get_valuetype()) {
6092 result
=t_val
->get_nof_comps();
6097 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
6098 if(t_val
->get_se_comp_byIndex(i
)->get_value()
6099 ->get_valuetype()!=V_OMIT
) result
++;
6103 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6109 set_valuetype(V_ERROR
);
6113 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
6115 Type
*governor
= ti
->get_expr_governor(exp_val
);
6117 ti
->get_Template()->set_lowerid_to_ref();
6118 governor
= ti
->get_expr_governor(exp_val
);
6122 ti
->append_stringRepr( str
);
6123 ti
->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6124 "If type is known, use valueof(<type>: %s) as argument.",
6125 str
.c_str(), get_opname(), str
.c_str());
6126 set_valuetype(V_ERROR
);
6131 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
6134 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
6135 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
6136 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
6137 Type::EXPECTED_TEMPLATE
: exp_val
);
6139 Template
*t_temp
= u
.expr
.t2
->get_Template();
6140 if (t_temp
->is_undef_lowerid()) {
6141 // We convert the template to reference first even if the value is also
6142 // an undef lowerid. The user can prevent this by explicit type
6144 t_temp
->set_lowerid_to_ref();
6146 } else if (u
.expr
.v1
->is_undef_lowerid()) {
6147 u
.expr
.v1
->set_lowerid_to_ref();
6152 error("Cannot determine the type of arguments in `match()' operation");
6153 set_valuetype(V_ERROR
);
6156 u
.expr
.v1
->set_my_governor(governor
);
6158 Error_Context
cntxt(this, "In the first argument of `match()'"
6160 governor
->chk_this_value_ref(u
.expr
.v1
);
6161 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
6162 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6165 Error_Context
cntxt(this, "In the second argument of `match()' "
6167 u
.expr
.t2
->chk(governor
);
6171 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
6172 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
6174 Ttcn::StatementBlock
*my_sb
;
6176 case Type::EXPECTED_CONSTANT
:
6177 error("An evaluable constant value was expected instead of operation "
6178 "`%s'", get_opname());
6180 case Type::EXPECTED_STATIC_VALUE
:
6181 error("A static value was expected instead of operation `%s'",
6187 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6188 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
6190 error("Operation `%s' is allowed only within statements",
6194 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6195 error("Operation `%s' is not allowed in the control part",
6199 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6200 error("Operation `%s' cannot be used in a definition that has "
6201 "`runs on' clause", get_opname());
6204 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6205 error("Operation `%s' can be used only in a definition that has "
6206 "`runs on' clause", get_opname());
6211 set_valuetype(V_ERROR
);
6214 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6216 if(valuetype
==V_ERROR
) return;
6217 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6218 if(v
->is_unfoldable()) return;
6219 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6220 ttcn3float r
= v
->get_val_Real();
6221 if (isSpecialFloatValue(r
)) {
6222 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6223 opnum
, opname
, Real2string(r
).c_str());
6224 set_valuetype(V_ERROR
);
6228 void Value::chk_expr_operands(ReferenceChain
*refch
,
6229 Type::expected_value_t exp_val
)
6231 const char *first
="First", *second
="Second", *third
="Third",
6232 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6233 Value
*v1
, *v2
, *v3
;
6234 Type::typetype_t tt1
, tt2
, tt3
;
6235 Type
t_chk(Type::T_ERROR
);
6237 const char *opname
=get_opname();
6239 // first classify the unchecked ischosen() operation
6240 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6242 switch (u
.expr
.v_optype
) {
6243 case OPTYPE_COMP_NULL
:
6244 case OPTYPE_TESTCASENAME
:
6245 case OPTYPE_PROF_RUNNING
:
6247 case OPTYPE_COMP_MTC
:
6248 case OPTYPE_COMP_SYSTEM
:
6249 chk_expr_comptype_compat();
6251 case OPTYPE_RND
: // -
6252 case OPTYPE_TMR_RUNNING_ANY
:
6253 chk_expr_dynamic_part(exp_val
, true);
6255 case OPTYPE_COMP_RUNNING_ANY
:
6256 case OPTYPE_COMP_RUNNING_ALL
:
6257 case OPTYPE_COMP_ALIVE_ANY
:
6258 case OPTYPE_COMP_ALIVE_ALL
:
6259 case OPTYPE_GETVERDICT
:
6260 chk_expr_dynamic_part(exp_val
, false);
6262 case OPTYPE_COMP_SELF
:
6263 chk_expr_comptype_compat();
6264 chk_expr_dynamic_part(exp_val
, false, true, false);
6266 case OPTYPE_UNARYPLUS
: // v1
6267 case OPTYPE_UNARYMINUS
:
6270 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6271 v1
->set_lowerid_to_ref();
6272 tt1
=v1
->get_expr_returntype(exp_val
);
6273 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6274 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6280 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6281 v1
->set_lowerid_to_ref();
6282 tt1
=v1
->get_expr_returntype(exp_val
);
6283 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6284 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
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_binstr(tt1
, the
, opname
, v1
);
6294 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6297 case OPTYPE_BIT2HEX
:
6298 case OPTYPE_BIT2OCT
:
6299 case OPTYPE_BIT2STR
:
6302 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6303 v1
->set_lowerid_to_ref();
6304 tt1
=v1
->get_expr_returntype(exp_val
);
6305 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6306 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6309 case OPTYPE_BIT2INT
:
6312 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6313 v1
->set_lowerid_to_ref();
6314 tt1
=v1
->get_expr_returntype(exp_val
);
6315 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6316 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6317 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6320 case OPTYPE_CHAR2INT
:
6323 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6324 v1
->set_lowerid_to_ref();
6325 tt1
=v1
->get_expr_returntype(exp_val
);
6326 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6327 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6328 chk_expr_val_len1(v1
, the
, opname
);
6331 case OPTYPE_CHAR2OCT
:
6334 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6335 v1
->set_lowerid_to_ref();
6336 tt1
=v1
->get_expr_returntype(exp_val
);
6337 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6338 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6341 case OPTYPE_STR2INT
:
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_int(v1
, the
, opname
);
6352 case OPTYPE_STR2FLOAT
:
6355 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6356 v1
->set_lowerid_to_ref();
6357 tt1
=v1
->get_expr_returntype(exp_val
);
6358 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6359 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6360 chk_expr_val_str_float(v1
, the
, opname
);
6363 case OPTYPE_STR2BIT
:
6366 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6367 v1
->set_lowerid_to_ref();
6368 tt1
=v1
->get_expr_returntype(exp_val
);
6369 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6370 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6371 chk_expr_val_str_bindigits(v1
, the
, opname
);
6374 case OPTYPE_STR2HEX
:
6377 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6378 v1
->set_lowerid_to_ref();
6379 tt1
=v1
->get_expr_returntype(exp_val
);
6380 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6381 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6382 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6385 case OPTYPE_STR2OCT
:
6388 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6389 v1
->set_lowerid_to_ref();
6390 tt1
=v1
->get_expr_returntype(exp_val
);
6391 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6392 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6393 chk_expr_val_str_len_even(v1
, the
, opname
);
6394 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6397 case OPTYPE_ENUM2INT
:
6400 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6401 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6402 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6406 chk_expr_operand_encode(refch
, exp_val
);
6408 case OPTYPE_FLOAT2INT
:
6409 case OPTYPE_FLOAT2STR
:
6412 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6413 v1
->set_lowerid_to_ref();
6414 tt1
=v1
->get_expr_returntype(exp_val
);
6415 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6416 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6417 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6418 chk_expr_operand_valid_float(v1
, the
, opname
);
6421 case OPTYPE_RNDWITHVAL
:
6424 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6425 v1
->set_lowerid_to_ref();
6426 tt1
=v1
->get_expr_returntype(exp_val
);
6427 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6428 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6429 chk_expr_operand_valid_float(v1
, the
, opname
);
6431 chk_expr_dynamic_part(exp_val
, true);
6433 case OPTYPE_HEX2BIT
:
6434 case OPTYPE_HEX2OCT
:
6435 case OPTYPE_HEX2STR
:
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_hstr(tt1
, the
, opname
, v1
);
6442 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6445 case OPTYPE_HEX2INT
:
6448 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6449 v1
->set_lowerid_to_ref();
6450 tt1
=v1
->get_expr_returntype(exp_val
);
6451 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6452 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6453 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6456 case OPTYPE_INT2CHAR
:
6459 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6460 v1
->set_lowerid_to_ref();
6461 tt1
=v1
->get_expr_returntype(exp_val
);
6462 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6463 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6464 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6467 case OPTYPE_INT2UNICHAR
:
6470 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6471 v1
->set_lowerid_to_ref();
6472 tt1
=v1
->get_expr_returntype(exp_val
);
6473 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6474 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6475 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6478 case OPTYPE_INT2FLOAT
:
6479 case OPTYPE_INT2STR
:
6482 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6483 v1
->set_lowerid_to_ref();
6484 tt1
=v1
->get_expr_returntype(exp_val
);
6485 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6486 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6489 case OPTYPE_OCT2BIT
:
6490 case OPTYPE_OCT2HEX
:
6491 case OPTYPE_OCT2STR
:
6494 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6495 v1
->set_lowerid_to_ref();
6496 tt1
=v1
->get_expr_returntype(exp_val
);
6497 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6498 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6501 case OPTYPE_OCT2INT
:
6504 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6505 v1
->set_lowerid_to_ref();
6506 tt1
=v1
->get_expr_returntype(exp_val
);
6507 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6508 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6509 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6513 case OPTYPE_OCT2CHAR
:
6516 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6517 v1
->set_lowerid_to_ref();
6518 tt1
=v1
->get_expr_returntype(exp_val
);
6519 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6520 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6521 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6524 case OPTYPE_REMOVE_BOM
:
6527 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6528 v1
->set_lowerid_to_ref();
6529 tt1
=v1
->get_expr_returntype(exp_val
);
6530 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6531 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6534 case OPTYPE_GET_STRINGENCODING
:
6537 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6538 v1
->set_lowerid_to_ref();
6539 tt1
=v1
->get_expr_returntype(exp_val
);
6540 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6541 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6544 case OPTYPE_ENCODE_BASE64
:
6547 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6548 v1
->set_lowerid_to_ref();
6549 tt1
=v1
->get_expr_returntype(exp_val
);
6550 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6551 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6553 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6556 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6557 v2
->set_lowerid_to_ref();
6558 tt2
=v2
->get_expr_returntype(exp_val
);
6559 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6560 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6563 case OPTYPE_DECODE_BASE64
:
6566 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6567 v1
->set_lowerid_to_ref();
6568 tt1
=v1
->get_expr_returntype(exp_val
);
6569 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6570 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6573 case OPTYPE_UNICHAR2INT
:
6576 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6577 v1
->set_lowerid_to_ref();
6578 tt1
=v1
->get_expr_returntype(exp_val
);
6579 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6580 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6581 chk_expr_val_len1(v1
, the
, opname
);
6584 case OPTYPE_UNICHAR2CHAR
:
6587 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6588 v1
->set_lowerid_to_ref();
6589 tt1
=v1
->get_expr_returntype(exp_val
);
6590 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6591 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6592 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6595 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6598 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6599 v1
->set_lowerid_to_ref();
6600 tt1
=v1
->get_expr_returntype(exp_val
);
6601 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6602 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6604 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6607 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6608 v2
->set_lowerid_to_ref();
6609 tt2
=v2
->get_expr_returntype(exp_val
);
6610 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6611 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6614 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6617 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6618 v1
->set_lowerid_to_ref();
6619 tt1
=v1
->get_expr_returntype(exp_val
);
6620 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6621 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6623 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6626 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6627 v2
->set_lowerid_to_ref();
6628 tt2
=v2
->get_expr_returntype(exp_val
);
6629 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6630 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6633 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
6634 chk_expr_operand_encode(refch
, exp_val
);
6635 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6638 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6639 v2
->set_lowerid_to_ref();
6640 tt2
=v2
->get_expr_returntype(exp_val
);
6641 chk_expr_operandtype_charstr(tt2
, second
, opname
, v2
);
6642 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6645 case OPTYPE_DECVALUE_UNICHAR
:
6646 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR
);
6647 v3
=u
.expr
.v3
? u
.expr
.v3
: 0;
6650 Error_Context
cntxt(this, "In the thrid operand of operation `%s'", opname
);
6651 v3
->set_lowerid_to_ref();
6652 tt3
=v3
->get_expr_returntype(exp_val
);
6653 chk_expr_operandtype_charstr(tt3
, third
, opname
, v3
);
6654 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6657 case OPTYPE_ADD
: // v1 v2
6658 case OPTYPE_SUBTRACT
:
6659 case OPTYPE_MULTIPLY
:
6663 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6664 v1
->set_lowerid_to_ref();
6665 tt1
=v1
->get_expr_returntype(exp_val
);
6666 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6667 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6668 chk_expr_operand_valid_float(v1
, first
, opname
);
6672 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6673 v2
->set_lowerid_to_ref();
6674 tt2
=v2
->get_expr_returntype(exp_val
);
6675 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6676 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6677 chk_expr_operand_valid_float(v2
, second
, opname
);
6678 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6679 chk_expr_val_int_float_not0(v2
, second
, opname
);
6681 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6687 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6688 v1
->set_lowerid_to_ref();
6689 tt1
=v1
->get_expr_returntype(exp_val
);
6690 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6691 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6695 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6696 v2
->set_lowerid_to_ref();
6697 tt2
=v2
->get_expr_returntype(exp_val
);
6698 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6699 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6700 chk_expr_val_int_float_not0(v2
, right
, opname
);
6703 case OPTYPE_CONCAT
: {
6706 v1
->set_lowerid_to_ref();
6707 v2
->set_lowerid_to_ref();
6708 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6710 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6711 tt1
=v1
->get_expr_returntype(exp_val
);
6712 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6713 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6716 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6717 tt2
=v2
->get_expr_returntype(exp_val
);
6718 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6719 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6721 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6722 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6723 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6724 } else { // other list types
6725 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6726 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6728 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6729 set_valuetype(V_ERROR
);
6732 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6733 v1_gov
->chk_this_value_ref(v1
);
6734 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6735 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6736 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6740 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6741 set_valuetype(V_ERROR
);
6744 // for recof/setof literals set the type from v1
6746 v2
->set_my_governor(v1_gov
);
6749 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6751 v2_gov
->chk_this_value_ref(v2
);
6752 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6753 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6754 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6755 if (valuetype
== V_ERROR
) return;
6756 // 7.1.2 says that we shouldn't allow type compatibility.
6757 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6758 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6759 error("The operands of operation `%s' should be of compatible "
6760 "types", get_opname());
6769 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6771 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6773 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6776 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6778 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6779 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6780 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6781 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6782 * "a == not b" is not allowed. (HL69107)
6783 * The various *Expressions implement operator precedence in the std.
6784 * Titan's parser has only one Expression and relies on Bison
6785 * for operator precedence. The check below brings Titan in line
6786 * with the standard by explicitly making "a == not b" an error */
6787 if (v2
->get_valuetype() == V_EXPR
6788 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6789 error("The operation `%s' is not allowed to be "
6790 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6791 set_valuetype(V_ERROR
);
6801 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6803 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6805 tt1
=v1
->get_expr_returntype(exp_val
);
6806 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6807 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6810 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6812 tt2
=v2
->get_expr_returntype(exp_val
);
6813 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6814 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6822 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6824 v1
->set_lowerid_to_ref();
6825 tt1
=v1
->get_expr_returntype(exp_val
);
6826 chk_expr_operandtype_bool(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'",
6833 v2
->set_lowerid_to_ref();
6834 tt2
=v2
->get_expr_returntype(exp_val
);
6835 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6836 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6844 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6846 v1
->set_lowerid_to_ref();
6847 tt1
=v1
->get_expr_returntype(exp_val
);
6848 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6849 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6853 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6855 v2
->set_lowerid_to_ref();
6856 tt2
=v2
->get_expr_returntype(exp_val
);
6857 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6858 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6860 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6861 chk_expr_operands_str_samelen();
6867 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6868 v1
->set_lowerid_to_ref();
6869 tt1
=v1
->get_expr_returntype(exp_val
);
6870 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6871 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6875 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6876 v2
->set_lowerid_to_ref();
6877 tt2
=v2
->get_expr_returntype(exp_val
);
6878 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6879 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6880 chk_expr_val_large_int(v2
, right
, opname
);
6886 v1
->set_lowerid_to_ref();
6887 if (v1
->is_string_type(exp_val
)) {
6888 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6889 tt1
=v1
->get_expr_returntype(exp_val
);
6890 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6891 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6892 } else { // other list types
6893 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6894 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6895 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6897 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6898 v1_gov
->chk_this_value_ref(v1
);
6899 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6900 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6901 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6906 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6907 v2
->set_lowerid_to_ref();
6908 tt2
=v2
->get_expr_returntype(exp_val
);
6909 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6910 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6911 chk_expr_val_large_int(v2
, right
, opname
);
6914 case OPTYPE_INT2BIT
:
6915 case OPTYPE_INT2HEX
:
6916 case OPTYPE_INT2OCT
:
6919 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6920 v1
->set_lowerid_to_ref();
6921 tt1
=v1
->get_expr_returntype(exp_val
);
6922 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6923 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6924 chk_expr_val_int_pos0(v1
, first
, opname
);
6928 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6929 v2
->set_lowerid_to_ref();
6930 tt2
=v2
->get_expr_returntype(exp_val
);
6931 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6932 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6933 chk_expr_val_int_pos0(v2
, second
, opname
);
6935 chk_expr_operands_int2binstr();
6938 chk_expr_operands_decode(OPTYPE_DECODE
);
6942 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6943 Type::expected_value_t ti_exp_val
= exp_val
;
6944 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6945 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6946 if (!governor
) return;
6947 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6948 if (valuetype
!=V_ERROR
)
6949 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6950 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6954 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6955 v2
->set_lowerid_to_ref();
6956 tt2
=v2
->get_expr_returntype(exp_val
);
6957 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6958 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6959 chk_expr_val_int_pos0(v2
, second
, opname
);
6963 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6964 v3
->set_lowerid_to_ref();
6965 tt3
=v3
->get_expr_returntype(exp_val
);
6966 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6967 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6968 chk_expr_val_int_pos0(v3
, third
, opname
);
6970 chk_expr_operands_substr();
6972 case OPTYPE_REGEXP
: {
6973 Type::expected_value_t ti_exp_val
= exp_val
;
6974 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6976 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6977 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6978 if (!governor
) return;
6979 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6980 if (valuetype
!=V_ERROR
) {
6981 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6982 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6983 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6987 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6988 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6989 if (!governor
) return;
6990 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6991 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6992 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6996 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6997 v3
->set_lowerid_to_ref();
6998 tt3
=v3
->get_expr_returntype(exp_val
);
6999 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
7000 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7001 chk_expr_val_int_pos0(v3
, third
, opname
);
7003 chk_expr_operands_regexp();
7005 case OPTYPE_ISCHOSEN
:
7006 // do nothing: the operand is erroneous
7007 // the error was already reported in chk_expr_ref_ischosen()
7009 case OPTYPE_ISCHOSEN_V
: // v1 i2
7010 case OPTYPE_ISCHOSEN_T
: // t1 i2
7011 chk_expr_operands_ischosen(refch
, exp_val
);
7013 case OPTYPE_VALUEOF
: { // ti1
7014 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7015 exp_val
= Type::EXPECTED_TEMPLATE
;
7016 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7017 Type
*governor
= my_governor
;
7018 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7019 if (!governor
) return;
7020 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7021 if (valuetype
== V_ERROR
) return;
7022 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7024 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
7025 case OPTYPE_ISBOUND
: {
7026 Template
*templ
= u
.expr
.ti1
->get_Template();
7027 switch (templ
->get_templatetype()) {
7028 case Template::TEMPLATE_REFD
:
7029 templ
->get_reference()->setUsedInIsbound();
7031 case Template::SPECIFIC_VALUE
: {
7032 Value
*value
= templ
->get_specific_value();
7033 if (Value::V_REFD
== value
->get_valuetype()) {
7034 value
->get_reference()->setUsedInIsbound();
7042 case OPTYPE_ISVALUE
: {// ti1
7043 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
7044 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7045 exp_val
= Type::EXPECTED_TEMPLATE
;
7046 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7047 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7048 if (!governor
) return;
7049 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
7050 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7052 case OPTYPE_SIZEOF
: // ti1
7053 /* this checking is too complex, do the checking during eval... */
7055 case OPTYPE_LENGTHOF
: { // ti1
7056 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7057 exp_val
= Type::EXPECTED_TEMPLATE
;
7058 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7059 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7060 if (!governor
) return;
7061 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
7062 if (valuetype
== V_ERROR
) return;
7063 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7065 case OPTYPE_MATCH
: // v1 t2
7066 chk_expr_operands_match(exp_val
);
7068 case OPTYPE_UNDEF_RUNNING
: // r1
7069 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
7071 case OPTYPE_COMP_ALIVE
:
7072 case OPTYPE_COMP_RUNNING
: //v1
7073 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
7074 chk_expr_dynamic_part(exp_val
, false);
7076 case OPTYPE_TMR_READ
: // r1
7077 case OPTYPE_TMR_RUNNING
: // r1
7078 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
7079 chk_expr_dynamic_part(exp_val
, true);
7081 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
7082 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
7083 chk_expr_dynamic_part(exp_val
, true, false, false);
7085 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7086 chk_expr_operand_comptyperef_create();
7089 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7090 v2
->set_lowerid_to_ref();
7091 tt2
=v2
->get_expr_returntype(exp_val
);
7092 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
7093 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7097 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
7098 v3
->set_lowerid_to_ref();
7099 tt3
=v3
->get_expr_returntype(exp_val
);
7100 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
7101 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7103 chk_expr_dynamic_part(exp_val
, false);
7105 case OPTYPE_ACTIVATE
: // r1 // altstep
7106 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
7107 chk_expr_dynamic_part(exp_val
, true);
7109 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
7110 case OPTYPE_CHECKSTATE_ALL
:
7111 chk_expr_dynamic_part(exp_val
, false);
7114 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7115 v2
->set_lowerid_to_ref();
7116 tt2
=v2
->get_expr_returntype(exp_val
);
7117 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
7118 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7121 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
7122 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7123 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
7125 delete u
.expr
.t_list2
;
7126 u
.expr
.ap_list2
= parlist
;
7127 chk_expr_dynamic_part(exp_val
, true);
7129 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
7130 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7131 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
7132 u
.expr
.v3
, the
, opname
);
7133 delete u
.expr
.t_list2
;
7134 u
.expr
.ap_list2
= parlist
;
7135 chk_expr_dynamic_part(exp_val
, true);
7138 error("Built-in function `%s' is not yet supported", opname
);
7139 set_valuetype(V_ERROR
);
7141 case OPTYPE_REPLACE
: {
7142 Type::expected_value_t ti_exp_val
= exp_val
;
7143 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7144 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7146 Error_Context
cntxt(this, "In the first operand of operation `%s'",
7148 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7149 if (!governor
) return;
7150 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7151 if (valuetype
!= V_ERROR
)
7152 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7153 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
7157 Error_Context
cntxt(this, "In the second operand of operation `%s'",
7159 v2
->set_lowerid_to_ref();
7160 tt2
= v2
->get_expr_returntype(exp_val
);
7161 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
7162 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7163 chk_expr_val_int_pos0(v2
, second
, opname
);
7167 Error_Context
cntxt(this, "In the third operand of operation `%s'",
7169 v3
->set_lowerid_to_ref();
7170 tt3
= v3
->get_expr_returntype(exp_val
);
7171 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
7172 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7173 chk_expr_val_int_pos0(v3
, third
, opname
);
7176 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
7178 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
7179 if (!governor
) return;
7180 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
7181 if (valuetype
!= V_ERROR
)
7182 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
7183 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
7185 chk_expr_operands_replace();
7187 case OPTYPE_LOG2STR
:
7188 case OPTYPE_ANY2UNISTR
: {
7189 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7190 u
.expr
.logargs
->chk();
7191 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
7193 case OPTYPE_TTCN2STRING
: {
7194 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
7195 Type::expected_value_t ti_exp_val
= exp_val
;
7196 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7197 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7198 if (!governor
) return;
7199 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7202 FATAL_ERROR("chk_expr_operands()");
7206 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7207 // the result of evaluating the expression. E.g. V_BOOL for
7209 void Value::evaluate_value(ReferenceChain
*refch
,
7210 Type::expected_value_t exp_val
)
7212 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
7213 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
7215 u
.expr
.state
=EXPR_CHECKING
;
7217 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
7218 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
7219 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
7221 if(valuetype
==V_ERROR
) return;
7222 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
7223 u
.expr
.state
=EXPR_CHECKED
;
7224 set_valuetype(V_ERROR
);
7228 u
.expr
.state
=EXPR_CHECKED
;
7230 Value
*v1
, *v2
, *v3
, *v4
;
7231 switch(u
.expr
.v_optype
) {
7232 case OPTYPE_RND
: // -
7233 case OPTYPE_COMP_NULL
: // the only foldable in this group
7234 case OPTYPE_COMP_MTC
:
7235 case OPTYPE_COMP_SYSTEM
:
7236 case OPTYPE_COMP_SELF
:
7237 case OPTYPE_COMP_RUNNING_ANY
:
7238 case OPTYPE_COMP_RUNNING_ALL
:
7239 case OPTYPE_COMP_ALIVE_ANY
:
7240 case OPTYPE_COMP_ALIVE_ALL
:
7241 case OPTYPE_TMR_RUNNING_ANY
:
7242 case OPTYPE_GETVERDICT
:
7243 case OPTYPE_PROF_RUNNING
:
7244 case OPTYPE_RNDWITHVAL
: // v1
7245 case OPTYPE_COMP_RUNNING
: // v1
7246 case OPTYPE_COMP_ALIVE
:
7247 case OPTYPE_TMR_READ
:
7248 case OPTYPE_TMR_RUNNING
:
7249 case OPTYPE_ACTIVATE
:
7250 case OPTYPE_ACTIVATE_REFD
:
7251 case OPTYPE_EXECUTE
: // r1 [v2]
7252 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7253 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7254 case OPTYPE_MATCH
: // v1 t2
7255 case OPTYPE_ISCHOSEN_T
:
7256 case OPTYPE_LOG2STR
:
7257 case OPTYPE_ANY2UNISTR
:
7260 case OPTYPE_ISBOUND
:
7261 case OPTYPE_ISPRESENT
:
7262 case OPTYPE_TTCN2STRING
:
7263 case OPTYPE_UNICHAR2OCT
:
7264 case OPTYPE_OCT2UNICHAR
:
7265 case OPTYPE_ENCODE_BASE64
:
7266 case OPTYPE_DECODE_BASE64
:
7267 case OPTYPE_ENCVALUE_UNICHAR
:
7268 case OPTYPE_DECVALUE_UNICHAR
:
7269 case OPTYPE_CHECKSTATE_ANY
:
7270 case OPTYPE_CHECKSTATE_ALL
:
7272 case OPTYPE_TESTCASENAME
: { // -
7273 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7274 Ttcn::StatementBlock
*my_sb
=
7275 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7277 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7278 if (!my_def
) { // In control part.
7279 set_val_str(new string(""));
7281 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7282 set_val_str(new string(my_def
->get_id().get_dispname()));
7286 case OPTYPE_UNARYPLUS
: // v1
7289 copy_and_destroy(v1
);
7291 case OPTYPE_UNARYMINUS
:
7292 if (is_unfoldable()) break;
7293 v1
= u
.expr
.v1
->get_value_refd_last();
7294 switch (v1
->valuetype
) {
7296 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7297 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7303 ttcn3float r
= v1
->get_val_Real();
7309 FATAL_ERROR("Value::evaluate_value()");
7313 if(is_unfoldable()) break;
7314 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7319 case OPTYPE_NOT4B
: {
7320 if(is_unfoldable()) break;
7321 v1
=u
.expr
.v1
->get_value_refd_last();
7322 const string
& s
= v1
->get_val_str();
7323 valuetype_t vt
=v1
->valuetype
;
7326 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7328 case OPTYPE_BIT2HEX
: {
7329 if(is_unfoldable()) break;
7330 v1
=u
.expr
.v1
->get_value_refd_last();
7331 const string
& s
= v1
->get_val_str();
7334 set_val_str(bit2hex(s
));
7336 case OPTYPE_BIT2OCT
: {
7337 if(is_unfoldable()) break;
7338 v1
=u
.expr
.v1
->get_value_refd_last();
7339 const string
& s
= v1
->get_val_str();
7342 set_val_str(bit2oct(s
));
7344 case OPTYPE_BIT2STR
:
7345 case OPTYPE_HEX2STR
:
7346 case OPTYPE_OCT2STR
: {
7347 if(is_unfoldable()) break;
7348 v1
=u
.expr
.v1
->get_value_refd_last();
7349 const string
& s
= v1
->get_val_str();
7352 set_val_str(new string(s
));
7354 case OPTYPE_BIT2INT
: {
7355 if (is_unfoldable()) break;
7356 v1
= u
.expr
.v1
->get_value_refd_last();
7357 const string
& s
= v1
->get_val_str();
7360 u
.val_Int
= bit2int(s
);
7362 case OPTYPE_CHAR2INT
: {
7363 if (is_unfoldable()) break;
7364 v1
= u
.expr
.v1
->get_value_refd_last();
7365 char c
= v1
->get_val_str()[0];
7368 u
.val_Int
= new int_val_t((Int
)c
);
7370 case OPTYPE_CHAR2OCT
: {
7371 if(is_unfoldable()) break;
7372 v1
=u
.expr
.v1
->get_value_refd_last();
7373 const string
& s
= v1
->get_val_str();
7376 set_val_str(char2oct(s
));
7378 case OPTYPE_STR2INT
: {
7379 if (is_unfoldable()) break;
7380 v1
= u
.expr
.v1
->get_value_refd_last();
7381 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7385 /** \todo hiba eseten lenyeli... */
7387 case OPTYPE_STR2FLOAT
: {
7388 if(is_unfoldable()) break;
7389 v1
=u
.expr
.v1
->get_value_refd_last();
7390 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7394 /** \todo hiba eseten lenyeli... */
7396 case OPTYPE_STR2BIT
: {
7397 if(is_unfoldable()) break;
7398 v1
=u
.expr
.v1
->get_value_refd_last();
7399 const string
& s
= v1
->get_val_str();
7402 set_val_str(new string(s
));
7404 case OPTYPE_STR2HEX
:
7405 case OPTYPE_OCT2HEX
: {
7406 if(is_unfoldable()) break;
7407 v1
=u
.expr
.v1
->get_value_refd_last();
7408 const string
& s
= v1
->get_val_str();
7411 set_val_str(to_uppercase(s
));
7413 case OPTYPE_STR2OCT
: {
7414 if(is_unfoldable()) break;
7415 v1
=u
.expr
.v1
->get_value_refd_last();
7416 const string
& s
= v1
->get_val_str();
7419 set_val_str(to_uppercase(s
));
7421 case OPTYPE_FLOAT2INT
: {
7422 if (is_unfoldable()) break;
7423 v1
= u
.expr
.v1
->get_value_refd_last();
7424 ttcn3float r
= v1
->get_val_Real();
7427 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7429 case OPTYPE_FLOAT2STR
: {
7430 if(is_unfoldable()) break;
7431 v1
=u
.expr
.v1
->get_value_refd_last();
7432 ttcn3float r
=v1
->get_val_Real();
7435 set_val_str(float2str(r
));
7437 case OPTYPE_HEX2BIT
:
7438 case OPTYPE_OCT2BIT
: {
7439 if(is_unfoldable()) break;
7440 v1
=u
.expr
.v1
->get_value_refd_last();
7441 const string
& s
= v1
->get_val_str();
7444 set_val_str(hex2bit(s
));
7446 case OPTYPE_HEX2INT
:
7447 case OPTYPE_OCT2INT
: {
7448 if(is_unfoldable()) break;
7449 v1
=u
.expr
.v1
->get_value_refd_last();
7450 const string
& s
= v1
->get_val_str();
7453 u
.val_Int
=hex2int(s
);
7455 case OPTYPE_HEX2OCT
: {
7456 if(is_unfoldable()) break;
7457 v1
=u
.expr
.v1
->get_value_refd_last();
7458 const string
& s
= v1
->get_val_str();
7461 set_val_str(hex2oct(s
));
7463 case OPTYPE_INT2CHAR
: {
7464 if (is_unfoldable()) break;
7465 v1
= u
.expr
.v1
->get_value_refd_last();
7466 const int_val_t
*c_int
= v1
->get_val_Int();
7467 char c
= static_cast<char>(c_int
->get_val());
7470 set_val_str(new string(1, &c
));
7472 case OPTYPE_INT2UNICHAR
: {
7473 if (is_unfoldable()) break;
7474 v1
= u
.expr
.v1
->get_value_refd_last();
7475 const int_val_t
*i_int
= v1
->get_val_Int();
7476 Int i
= i_int
->get_val();
7479 set_val_ustr(int2unichar(i
));
7480 u
.ustr
.convert_str
= false;
7482 case OPTYPE_INT2FLOAT
: {
7483 if (is_unfoldable()) break;
7484 v1
= u
.expr
.v1
->get_value_refd_last();
7485 const int_val_t
*i_int
= v1
->get_val_Int();
7486 Real i_int_real
= i_int
->to_real();
7489 u
.val_Real
= i_int_real
;
7491 case OPTYPE_INT2STR
: {
7492 if (is_unfoldable()) break;
7493 v1
= u
.expr
.v1
->get_value_refd_last();
7494 const int_val_t
*i_int
= v1
->get_val_Int();
7495 string
*i_int_str
= new string(i_int
->t_str());
7498 set_val_str(i_int_str
);
7500 case OPTYPE_OCT2CHAR
: {
7501 if(is_unfoldable()) break;
7502 v1
=u
.expr
.v1
->get_value_refd_last();
7503 const string
& s
= v1
->get_val_str();
7506 set_val_str(oct2char(s
));
7508 case OPTYPE_GET_STRINGENCODING
: {
7509 if(is_unfoldable()) break;
7510 v1
= u
.expr
.v1
->get_value_refd_last();
7511 const string
& s1
= v1
->get_val_str();
7514 set_val_str(get_stringencoding(s1
));
7516 case OPTYPE_REMOVE_BOM
: {
7517 if(is_unfoldable()) break;
7518 v1
= u
.expr
.v1
->get_value_refd_last();
7519 const string
& s1
= v1
->get_val_str();
7522 set_val_str(remove_bom(s1
));
7524 case OPTYPE_ENUM2INT
: {
7525 if(is_unfoldable()) break;
7526 v1
=u
.expr
.v1
->get_value_refd_last();
7527 Type
* enum_type
= v1
->get_my_governor();
7528 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7531 u
.val_Int
= new int_val_t(enum_val
);
7533 case OPTYPE_UNICHAR2INT
:
7534 if (is_unfoldable()) {
7535 // replace the operation with char2int() if the operand is a charstring
7536 // value to avoid its unnecessary conversion to universal charstring
7537 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7538 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7540 v1
=u
.expr
.v1
->get_value_refd_last();
7541 const ustring
& s
= v1
->get_val_ustr();
7544 u
.val_Int
=new int_val_t(unichar2int(s
));
7547 case OPTYPE_UNICHAR2CHAR
:
7549 if (is_unfoldable()) {
7550 // replace the operation with its operand if it is a charstring
7551 // value to avoid its unnecessary conversion to universal charstring
7552 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7554 copy_and_destroy(v1
);
7557 v1
= v1
->get_value_refd_last();
7558 const ustring
& s
= v1
->get_val_ustr();
7561 set_val_str(new string(s
));
7564 case OPTYPE_MULTIPLY
: { // v1 v2
7565 if (!is_unfoldable()) goto eval_arithmetic
;
7566 v1
= u
.expr
.v1
->get_value_refd_last();
7567 v2
= u
.expr
.v2
->get_value_refd_last();
7568 if (v1
->is_unfoldable()) v1
= v2
;
7569 if (v1
->is_unfoldable()) break;
7570 switch(v1
->valuetype
) {
7572 if (*v1
->get_val_Int() != 0) break;
7575 u
.val_Int
= new int_val_t((Int
)0);
7578 if (v1
->get_val_Real() != 0.0) break;
7584 FATAL_ERROR("Value::evaluate_value()");
7587 case OPTYPE_ADD
: // v1 v2
7588 case OPTYPE_SUBTRACT
:
7593 if(is_unfoldable()) break;
7594 v1
=u
.expr
.v1
->get_value_refd_last();
7595 v2
=u
.expr
.v2
->get_value_refd_last();
7596 operationtype_t ot
=u
.expr
.v_optype
;
7597 switch (v1
->valuetype
) {
7599 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7600 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7605 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7607 case OPTYPE_SUBTRACT
:
7608 u
.val_Int
= new int_val_t(*i1
- *i2
);
7610 case OPTYPE_MULTIPLY
:
7611 u
.val_Int
= new int_val_t(*i1
* *i2
);
7614 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7617 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7620 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7623 FATAL_ERROR("Value::evaluate_value()");
7629 ttcn3float r1
=v1
->get_val_Real();
7630 ttcn3float r2
=v2
->get_val_Real();
7637 case OPTYPE_SUBTRACT
:
7640 case OPTYPE_MULTIPLY
:
7647 FATAL_ERROR("Value::evaluate_value()");
7651 FATAL_ERROR("Value::evaluate_value()");
7654 case OPTYPE_CONCAT
: {
7655 if(is_unfoldable()) break;
7656 v1
=u
.expr
.v1
->get_value_refd_last();
7657 v2
=u
.expr
.v2
->get_value_refd_last();
7658 valuetype_t vt
= v1
->valuetype
;
7659 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7660 const ustring
& s1
= v1
->get_val_ustr();
7661 const ustring
& s2
= v2
->get_val_ustr();
7664 set_val_ustr(new ustring(s1
+ s2
));
7665 u
.ustr
.convert_str
= false;
7667 const string
& s1
= v1
->get_val_str();
7668 const string
& s2
= v2
->get_val_str();
7671 set_val_str(new string(s1
+ s2
));
7675 if(is_unfoldable()) break;
7676 v1
=u
.expr
.v1
->get_value_refd_last();
7677 v2
=u
.expr
.v2
->get_value_refd_last();
7684 if(is_unfoldable()) break;
7685 v1
=u
.expr
.v1
->get_value_refd_last();
7686 v2
=u
.expr
.v2
->get_value_refd_last();
7693 if(is_unfoldable()) break;
7694 v1
=u
.expr
.v1
->get_value_refd_last();
7695 v2
=u
.expr
.v2
->get_value_refd_last();
7702 if(is_unfoldable()) break;
7703 v1
=u
.expr
.v1
->get_value_refd_last();
7704 v2
=u
.expr
.v2
->get_value_refd_last();
7711 if(is_unfoldable()) break;
7712 v1
=u
.expr
.v1
->get_value_refd_last();
7713 v2
=u
.expr
.v2
->get_value_refd_last();
7720 if(is_unfoldable()) break;
7721 v1
=u
.expr
.v1
->get_value_refd_last();
7722 v2
=u
.expr
.v2
->get_value_refd_last();
7729 v1
= u
.expr
.v1
->get_value_refd_last();
7730 if (v1
->valuetype
== V_BOOL
) {
7731 if (v1
->get_val_bool()) {
7732 // the left operand is a literal "true"
7733 // substitute the expression with the right operand
7736 copy_and_destroy(v2
);
7738 // the left operand is a literal "false"
7739 // the result must be false regardless the right operand
7740 // because of the short circuit evaluation rule
7746 // we must keep the left operand because of the potential side effects
7747 // the right operand can only be eliminated if it is a literal "true"
7748 v2
= u
.expr
.v2
->get_value_refd_last();
7749 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7752 copy_and_destroy(v1
);
7757 v1
= u
.expr
.v1
->get_value_refd_last();
7758 if (v1
->valuetype
== V_BOOL
) {
7759 if (v1
->get_val_bool()) {
7760 // the left operand is a literal "true"
7761 // the result must be true regardless the right operand
7762 // because of the short circuit evaluation rule
7767 // the left operand is a literal "false"
7768 // substitute the expression with the right operand
7771 copy_and_destroy(v2
);
7774 // we must keep the left operand because of the potential side effects
7775 // the right operand can only be eliminated if it is a literal "false"
7776 v2
= u
.expr
.v2
->get_value_refd_last();
7777 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7780 copy_and_destroy(v1
);
7785 if(is_unfoldable()) break;
7786 v1
=u
.expr
.v1
->get_value_refd_last();
7787 v2
=u
.expr
.v2
->get_value_refd_last();
7788 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7793 case OPTYPE_AND4B
: {
7794 if(is_unfoldable()) break;
7795 v1
=u
.expr
.v1
->get_value_refd_last();
7796 v2
=u
.expr
.v2
->get_value_refd_last();
7797 valuetype_t vt
=v1
->valuetype
;
7798 const string
& s1
= v1
->get_val_str();
7799 const string
& s2
= v2
->get_val_str();
7802 set_val_str(and4b(s1
, s2
));
7805 if(is_unfoldable()) break;
7806 v1
=u
.expr
.v1
->get_value_refd_last();
7807 v2
=u
.expr
.v2
->get_value_refd_last();
7808 valuetype_t vt
=v1
->valuetype
;
7809 const string
& s1
= v1
->get_val_str();
7810 const string
& s2
= v2
->get_val_str();
7813 set_val_str(or4b(s1
, s2
));
7815 case OPTYPE_XOR4B
: {
7816 if(is_unfoldable()) break;
7817 v1
=u
.expr
.v1
->get_value_refd_last();
7818 v2
=u
.expr
.v2
->get_value_refd_last();
7819 valuetype_t vt
=v1
->valuetype
;
7820 const string
& s1
= v1
->get_val_str();
7821 const string
& s2
= v2
->get_val_str();
7824 set_val_str(xor4b(s1
, s2
));
7827 if(is_unfoldable()) break;
7828 v1
=u
.expr
.v1
->get_value_refd_last();
7829 v2
=u
.expr
.v2
->get_value_refd_last();
7830 valuetype_t vt
=v1
->valuetype
;
7831 const string
& s
= v1
->get_val_str();
7832 const int_val_t
*i_int
= v2
->get_val_Int();
7833 Int i
=i_int
->get_val();
7834 if(vt
==V_OSTR
) i
*=2;
7837 set_val_str(shift_left(s
, i
));
7840 if(is_unfoldable()) break;
7841 v1
=u
.expr
.v1
->get_value_refd_last();
7842 v2
=u
.expr
.v2
->get_value_refd_last();
7843 valuetype_t vt
=v1
->valuetype
;
7844 const string
& s
= v1
->get_val_str();
7845 const int_val_t
*i_int
= v2
->get_val_Int();
7846 Int i
=i_int
->get_val();
7847 if(vt
==V_OSTR
) i
*=2;
7850 set_val_str(shift_right(s
, i
));
7853 if(is_unfoldable()) break;
7854 v1
=u
.expr
.v1
->get_value_refd_last();
7855 v2
=u
.expr
.v2
->get_value_refd_last();
7856 valuetype_t vt
=v1
->valuetype
;
7857 const int_val_t
*i_int
=v2
->get_val_Int();
7858 Int i
=i_int
->get_val();
7860 const ustring
& s
= v1
->get_val_ustr();
7863 set_val_ustr(rotate_left(s
, i
));
7864 u
.ustr
.convert_str
= false;
7867 if(vt
==V_OSTR
) i
*=2;
7868 const string
& s
= v1
->get_val_str();
7871 set_val_str(rotate_left(s
, i
));
7875 if(is_unfoldable()) break;
7876 v1
=u
.expr
.v1
->get_value_refd_last();
7877 v2
=u
.expr
.v2
->get_value_refd_last();
7878 valuetype_t vt
=v1
->valuetype
;
7879 const int_val_t
*i_int
=v2
->get_val_Int();
7880 Int i
=i_int
->get_val();
7882 const ustring
& s
= v1
->get_val_ustr();
7885 set_val_ustr(rotate_right(s
, i
));
7886 u
.ustr
.convert_str
= false;
7889 if(vt
==V_OSTR
) i
*=2;
7890 const string
& s
= v1
->get_val_str();
7893 set_val_str(rotate_right(s
, i
));
7896 case OPTYPE_INT2BIT
: {
7897 if (is_unfoldable()) break;
7898 v1
= u
.expr
.v1
->get_value_refd_last();
7899 v2
= u
.expr
.v2
->get_value_refd_last();
7900 const int_val_t
*i1_int
= v1
->get_val_Int();
7901 const int_val_t
*i2_int
= v2
->get_val_Int();
7902 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7907 case OPTYPE_INT2HEX
: {
7908 if (is_unfoldable()) break;
7909 v1
= u
.expr
.v1
->get_value_refd_last();
7910 v2
= u
.expr
.v2
->get_value_refd_last();
7911 const int_val_t
*i1_int
= v1
->get_val_Int();
7912 const int_val_t
*i2_int
= v2
->get_val_Int();
7913 // Do it before the `clean_up'. i2_int is already checked.
7914 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7919 case OPTYPE_INT2OCT
: {
7920 if (is_unfoldable()) break;
7921 v1
= u
.expr
.v1
->get_value_refd_last();
7922 v2
= u
.expr
.v2
->get_value_refd_last();
7923 const int_val_t
i1_int(*v1
->get_val_Int());
7924 // `v2' is a native integer.
7925 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7928 set_val_str(int2hex(i1_int
, i2_int
));
7930 case OPTYPE_SUBSTR
: {
7931 if(is_unfoldable()) break;
7932 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7933 v2
=u
.expr
.v2
->get_value_refd_last();
7934 v3
=u
.expr
.v3
->get_value_refd_last();
7935 valuetype_t vt
=v1
->valuetype
;
7936 const int_val_t
*i2_int
=v2
->get_val_Int();
7937 const int_val_t
*i3_int
=v3
->get_val_Int();
7938 Int i2
=i2_int
->get_val();
7939 Int i3
=i3_int
->get_val();
7941 const ustring
& s
= v1
->get_val_ustr();
7944 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7945 u
.ustr
.convert_str
= false;
7952 const string
& s
= v1
->get_val_str();
7955 set_val_str(new string(s
.substr(i2
, i3
)));
7958 case OPTYPE_REPLACE
: {
7959 if(is_unfoldable()) break;
7960 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7961 v2
=u
.expr
.v2
->get_value_refd_last();
7962 v3
=u
.expr
.v3
->get_value_refd_last();
7963 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7964 valuetype_t vt
=v1
->valuetype
;
7965 const int_val_t
*i2_int
=v2
->get_val_Int();
7966 const int_val_t
*i3_int
=v3
->get_val_Int();
7967 Int i2
=i2_int
->get_val();
7968 Int i3
=i3_int
->get_val();
7971 string
*s1
= new string(v1
->get_val_str());
7972 const string
& s2
= v4
->get_val_str();
7975 s1
->replace(i2
, i3
, s2
);
7979 string
*s1
= new string(v1
->get_val_str());
7980 const string
& s2
= v4
->get_val_str();
7983 s1
->replace(i2
, i3
, s2
);
7989 string
*s1
= new string(v1
->get_val_str());
7990 const string
& s2
= v4
->get_val_str();
7993 s1
->replace(i2
, i3
, s2
);
7997 string
*s1
= new string(v1
->get_val_str());
7998 const string
& s2
= v4
->get_val_str();
8001 s1
->replace(i2
, i3
, s2
);
8005 ustring
*s1
= new ustring(v1
->get_val_ustr());
8006 const ustring
& s2
= v4
->get_val_ustr();
8009 s1
->replace(i2
, i3
, s2
);
8011 u
.ustr
.convert_str
= false;
8014 FATAL_ERROR("Value::evaluate_value()");
8017 case OPTYPE_REGEXP
: {
8018 if (is_unfoldable()) break;
8019 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
8020 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
8021 v3
=u
.expr
.v3
->get_value_refd_last();
8022 const int_val_t
*i3_int
= v3
->get_val_Int();
8023 Int i3
= i3_int
->get_val();
8024 if (v1
->valuetype
== V_CSTR
) {
8025 const string
& s1
= v1
->get_val_str();
8026 const string
& s2
= v2
->get_val_str();
8027 string
*result
= regexp(s1
, s2
, i3
);
8030 set_val_str(result
);
8031 } if (v1
->valuetype
== V_USTR
) {
8032 const ustring
& s1
= v1
->get_val_ustr();
8033 const ustring
& s2
= v2
->get_val_ustr();
8034 ustring
*result
= regexp(s1
, s2
, i3
);
8037 set_val_ustr(result
);
8038 u
.ustr
.convert_str
= false;
8041 case OPTYPE_LENGTHOF
:{
8042 if(is_unfoldable()) break;
8043 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
8044 ->get_value_refd_last();
8046 if(v1
->is_string_type(exp_val
)) {
8047 i
=v1
->get_val_strlen();
8048 } else { // v1 is be seq/set of or array
8049 switch (v1
->valuetype
) {
8053 if(v1
->u
.val_vs
->is_indexed())
8054 { i
= v1
->u
.val_vs
->get_nof_ivs();}
8055 else { i
= v1
->u
.val_vs
->get_nof_vs();}
8058 FATAL_ERROR("Value::evaluate_value()");
8063 u
.val_Int
=new int_val_t(i
);
8065 case OPTYPE_SIZEOF
: {
8066 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
8070 u
.val_Int
=new int_val_t(i
);
8073 case OPTYPE_ISVALUE
: {
8074 if(is_unfoldable()) break;
8075 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
8076 && u
.expr
.ti1
->get_Template()->is_Value();
8078 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
8079 is_singleval
= other_val
->evaluate_isvalue(false);
8080 // is_singleval now contains the compile-time result of isvalue
8085 u
.val_bool
= is_singleval
;
8087 case OPTYPE_ISCHOSEN_V
: {
8088 if (is_unfoldable()) break;
8089 v1
= u
.expr
.v1
->get_value_refd_last();
8090 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
8095 case OPTYPE_VALUEOF
: // ti1
8096 if (!u
.expr
.ti1
->get_DerivedRef() &&
8097 u
.expr
.ti1
->get_Template()->is_Value() &&
8098 !u
.expr
.ti1
->get_Type()) {
8099 // FIXME actually if the template instance has a type
8100 // it might still be foldable.
8101 // the argument is a single specific value
8102 v1
= u
.expr
.ti1
->get_Template()->get_Value();
8103 Type
*governor
= my_governor
;
8104 if (governor
== NULL
) {
8105 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
8106 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
8108 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
8109 if (governor
== NULL
)
8110 FATAL_ERROR("Value::evaluate_value()");
8112 valuetype
= v1
->valuetype
;
8114 set_my_governor(governor
);
8115 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
8116 u
.ref
.refd_last
= this;
8117 v1
->valuetype
= V_ERROR
;
8121 case OPTYPE_UNDEF_RUNNING
:
8123 FATAL_ERROR("Value::evaluate_value()");
8127 bool Value::evaluate_isvalue(bool from_sequence
)
8129 switch (valuetype
) {
8131 // Omit is not a value unless a member of a sequence or set
8132 return from_sequence
;
8135 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8136 case V_BOOL
: /**< boolean */
8137 case V_NAMEDINT
: /**< integer / named number */
8138 case V_NAMEDBITS
: /**< named bits (identifiers) */
8139 case V_INT
: /**< integer */
8140 case V_REAL
: /**< real/float */
8141 case V_ENUM
: /**< enumerated */
8142 case V_BSTR
: /**< bitstring */
8143 case V_HSTR
: /**< hexstring */
8144 case V_OSTR
: /**< octetstring */
8145 case V_CSTR
: /**< charstring */
8146 case V_USTR
: /**< universal charstring */
8147 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
8148 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
8149 case V_OID
: /**< object identifier */
8150 case V_ROID
: /**< relative object identifier */
8151 case V_VERDICT
: /**< all verdicts */
8152 return true; // values of built-in types return true
8154 // Code below was adapted from is_unfoldable(), false returned early.
8156 return u
.choice
.alt_value
->evaluate_isvalue(false);
8161 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8162 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
8170 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8171 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8172 ->evaluate_isvalue(true)) return false;
8177 // alas, get_value_refd_last prevents this function from const
8178 return get_value_refd_last()->evaluate_isvalue(false);
8181 switch (u
.expr
.v_optype
) {
8182 // A constant null component reference is a corner case: it is foldable
8183 // but escapes unmodified from evaluate_value.
8184 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8185 // or is transformed into some other valuetype in evaluate_value.
8186 case OPTYPE_COMP_NULL
:
8189 break; // and fall through to the FATAL_ERROR
8193 FATAL_ERROR("Value::evaluate_isvalue()");
8199 void Value::evaluate_macro(Type::expected_value_t exp_val
)
8202 case MACRO_MODULEID
:
8204 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8205 set_val_str(new string(my_scope
->get_scope_mod()
8206 ->get_modid().get_dispname()));
8209 case MACRO_FILENAME
:
8210 case MACRO_BFILENAME
: {
8211 const char *t_filename
= get_filename();
8213 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8214 set_val_str(new string(t_filename
));
8217 case MACRO_FILEPATH
: {
8218 const char *t_filename
= get_filename();
8220 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8221 char *t_filepath
= canonize_input_file(t_filename
);
8223 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8224 set_val_str(new string(t_filepath
));
8228 case MACRO_LINENUMBER
: {
8229 int t_lineno
= get_first_line();
8231 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8232 set_val_str(new string(Int2string(t_lineno
)));
8235 case MACRO_LINENUMBER_C
: {
8236 int t_lineno
= get_first_line();
8238 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8239 u
.val_Int
= new int_val_t(t_lineno
);
8242 case MACRO_DEFINITIONID
: {
8243 // cut the second part from the fullname separated by dots
8244 const string
& t_fullname
= get_fullname();
8245 size_t first_char
= t_fullname
.find('.') + 1;
8246 if (first_char
>= t_fullname
.size())
8247 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8248 t_fullname
.c_str());
8249 set_val_str(new string(t_fullname
.substr(first_char
,
8250 t_fullname
.find('.', first_char
) - first_char
)));
8254 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8255 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8259 case MACRO_TESTCASEID
: {
8260 if (exp_val
== Type::EXPECTED_CONSTANT
||
8261 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8262 error("A %s value was expected instead of macro `%%testcaseId', "
8263 "which is evaluated at runtime",
8264 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8268 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8269 Ttcn::StatementBlock
*my_sb
=
8270 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8272 error("Usage of macro %%testcaseId is allowed only within the "
8273 "statement blocks of functions, altsteps and testcases");
8276 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8278 error("Macro %%testcaseId cannot be used in the control part. "
8279 "It is allowed only within the statement blocks of functions, "
8280 "altsteps and testcases");
8283 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8284 // folding is possible only within testcases
8285 set_val_str(new string(my_def
->get_id().get_dispname()));
8290 FATAL_ERROR("Value::evaluate_macro()");
8294 set_valuetype(V_ERROR
);
8297 void Value::add_id(Identifier
*p_id
)
8301 if(u
.ids
->has_key(p_id
->get_name())) {
8302 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8303 // The Value does not take ownership for the identifier,
8304 // so it must be deleted (add_is acts as a sink).
8307 else u
.ids
->add(p_id
->get_name(), p_id
);
8310 FATAL_ERROR("Value::add_id()");
8314 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8315 Type::expected_value_t exp_val
)
8317 set_lowerid_to_ref();
8318 switch (valuetype
) {
8320 // there might be a better place for this
8321 chk_invoke(exp_val
);
8324 // use the cache if available
8325 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8327 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8329 // the referred definition is not found
8330 set_valuetype(V_ERROR
);
8332 switch (ass
->get_asstype()) {
8333 case Assignment::A_OBJECT
:
8334 case Assignment::A_OS
: {
8335 // the referred definition is an ASN.1 object or object set
8336 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8337 if (!setting
|| setting
->get_st() == S_ERROR
) {
8338 // remain silent, the error has been already reported
8339 set_valuetype(V_ERROR
);
8341 } else if (setting
->get_st() != S_V
) {
8342 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8343 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8344 set_valuetype(V_ERROR
);
8349 refch
->mark_state();
8350 destroy_refch
= false;
8352 refch
= new ReferenceChain(this,
8353 "While searching referenced value");
8354 destroy_refch
= true;
8356 if (refch
->add(get_fullname())) {
8357 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8358 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8359 // in case of circular recursion the valuetype is already set
8360 // to V_ERROR, so don't set the cache
8361 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8363 // a circular recursion was detected
8364 set_valuetype(V_ERROR
);
8366 if (destroy_refch
) delete refch
;
8367 else refch
->prev_state();
8369 case Assignment::A_CONST
: {
8370 // the referred definition is a constant
8373 refch
->mark_state();
8374 destroy_refch
= false;
8376 refch
= new ReferenceChain(this,
8377 "While searching referenced value");
8378 destroy_refch
= true;
8380 if (refch
->add(get_fullname())) {
8381 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8382 Value
*v_refd
= ass
->get_Value()
8383 ->get_refd_sub_value(subrefs
, 0,
8384 u
.ref
.ref
->getUsedInIsbound(), refch
);
8386 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8387 // in case of circular recursion the valuetype is already set
8388 // to V_ERROR, so don't set the cache
8389 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8390 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8391 u
.ref
.refd_last
= this;
8392 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8393 u
.ref
.refd_last
= this;
8395 // the sub-reference points to a non-existent field
8396 set_valuetype(V_ERROR
);
8399 // a circular recursion was detected
8400 set_valuetype(V_ERROR
);
8402 if (destroy_refch
) delete refch
;
8403 else refch
->prev_state();
8405 case Assignment::A_EXT_CONST
:
8406 case Assignment::A_MODULEPAR
:
8407 case Assignment::A_VAR
:
8408 case Assignment::A_FUNCTION_RVAL
:
8409 case Assignment::A_EXT_FUNCTION_RVAL
:
8410 case Assignment::A_PAR_VAL_IN
:
8411 case Assignment::A_PAR_VAL_OUT
:
8412 case Assignment::A_PAR_VAL_INOUT
:
8413 // the referred definition is not a constant
8414 u
.ref
.refd_last
= this;
8416 case Assignment::A_FUNCTION
:
8417 case Assignment::A_EXT_FUNCTION
:
8418 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8419 "call of %s, which does not have return type",
8420 ass
->get_description().c_str());
8421 set_valuetype(V_ERROR
);
8423 case Assignment::A_FUNCTION_RTEMP
:
8424 case Assignment::A_EXT_FUNCTION_RTEMP
:
8425 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8426 "call of %s, which returns a template",
8427 ass
->get_description().c_str());
8428 set_valuetype(V_ERROR
);
8431 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8432 ass
->get_description().c_str());
8433 set_valuetype(V_ERROR
);
8436 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8440 // try to evaluate the expression
8443 refch
->mark_state();
8444 destroy_refch
=false;
8447 refch
=new ReferenceChain(this, "While evaluating expression");
8450 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8451 else set_valuetype(V_ERROR
);
8452 if(destroy_refch
) delete refch
;
8453 else refch
->prev_state();
8456 evaluate_macro(exp_val
);
8459 // return this for all other value types
8464 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8466 /* Note that the logic here needs to be in sync with evaluate_value,
8467 * and possibly others, i.e. if evaluate_value is called for a Value
8468 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8469 bool Value::is_unfoldable(ReferenceChain
*refch
,
8470 Type::expected_value_t exp_val
)
8472 if (UnfoldabilityCheck::is_running(this)) {
8473 // This function is already running on this value => infinite recursion
8477 UnfoldabilityCheck
checker(this);
8479 if (get_needs_conversion()) return true;
8480 switch (valuetype
) {
8484 case V_UNDEF_LOWERID
:
8488 // these value types are eliminated during semantic analysis
8489 FATAL_ERROR("Value::is_unfoldable()");
8494 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8498 if (!is_indexed()) {
8499 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8500 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8504 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8505 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8512 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8513 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8514 ->is_unfoldable(refch
, exp_val
)) return true;
8520 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8521 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8525 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8526 if(v_last
==this) return true; // there weren't any references to chase
8527 else return v_last
->is_unfoldable(refch
, exp_val
);
8530 // classify the unchecked ischosen() operation, if it was not done so far
8531 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8532 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8533 switch (u
.expr
.v_optype
) {
8534 case OPTYPE_RND
: // -
8535 case OPTYPE_COMP_MTC
:
8536 case OPTYPE_COMP_SYSTEM
:
8537 case OPTYPE_COMP_SELF
:
8538 case OPTYPE_COMP_RUNNING_ANY
:
8539 case OPTYPE_COMP_RUNNING_ALL
:
8540 case OPTYPE_COMP_ALIVE_ANY
:
8541 case OPTYPE_COMP_ALIVE_ALL
:
8542 case OPTYPE_TMR_RUNNING_ANY
:
8543 case OPTYPE_GETVERDICT
:
8544 case OPTYPE_TESTCASENAME
:
8545 case OPTYPE_PROF_RUNNING
:
8546 case OPTYPE_RNDWITHVAL
: // v1
8547 case OPTYPE_MATCH
: // v1 t2
8548 case OPTYPE_UNDEF_RUNNING
: // v1
8549 case OPTYPE_COMP_RUNNING
:
8550 case OPTYPE_COMP_ALIVE
:
8551 case OPTYPE_TMR_READ
:
8552 case OPTYPE_TMR_RUNNING
:
8553 case OPTYPE_ACTIVATE
:
8554 case OPTYPE_ACTIVATE_REFD
:
8555 case OPTYPE_EXECUTE
: // r1 [v2]
8556 case OPTYPE_EXECUTE_REFD
:
8557 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8558 case OPTYPE_ISCHOSEN
:
8559 case OPTYPE_ISCHOSEN_T
:
8560 case OPTYPE_SIZEOF
: // ti1
8563 case OPTYPE_OCT2UNICHAR
:
8564 case OPTYPE_UNICHAR2OCT
:
8565 case OPTYPE_ENCODE_BASE64
:
8566 case OPTYPE_DECODE_BASE64
:
8567 case OPTYPE_ENCVALUE_UNICHAR
:
8568 case OPTYPE_DECVALUE_UNICHAR
:
8569 case OPTYPE_CHECKSTATE_ANY
:
8570 case OPTYPE_CHECKSTATE_ALL
:
8572 case OPTYPE_COMP_NULL
: // -
8574 case OPTYPE_UNARYPLUS
: // v1
8575 case OPTYPE_UNARYMINUS
:
8578 case OPTYPE_BIT2HEX
:
8579 case OPTYPE_BIT2INT
:
8580 case OPTYPE_BIT2OCT
:
8581 case OPTYPE_BIT2STR
:
8582 case OPTYPE_CHAR2INT
:
8583 case OPTYPE_CHAR2OCT
:
8584 case OPTYPE_FLOAT2INT
:
8585 case OPTYPE_FLOAT2STR
:
8586 case OPTYPE_HEX2BIT
:
8587 case OPTYPE_HEX2INT
:
8588 case OPTYPE_HEX2OCT
:
8589 case OPTYPE_HEX2STR
:
8590 case OPTYPE_INT2CHAR
:
8591 case OPTYPE_INT2FLOAT
:
8592 case OPTYPE_INT2STR
:
8593 case OPTYPE_INT2UNICHAR
:
8594 case OPTYPE_OCT2BIT
:
8595 case OPTYPE_OCT2CHAR
:
8596 case OPTYPE_OCT2HEX
:
8597 case OPTYPE_OCT2INT
:
8598 case OPTYPE_OCT2STR
:
8599 case OPTYPE_STR2BIT
:
8600 case OPTYPE_STR2FLOAT
:
8601 case OPTYPE_STR2HEX
:
8602 case OPTYPE_STR2INT
:
8603 case OPTYPE_STR2OCT
:
8604 case OPTYPE_UNICHAR2INT
:
8605 case OPTYPE_UNICHAR2CHAR
:
8606 case OPTYPE_ENUM2INT
:
8607 case OPTYPE_GET_STRINGENCODING
:
8608 case OPTYPE_REMOVE_BOM
:
8609 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8610 case OPTYPE_ISBOUND
: /*{
8611 //TODO once we have the time for it make isbound foldable.
8612 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8613 Template* temp = u.expr.ti1->get_Template();
8614 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8615 Value* specificValue = temp->get_specific_value();
8616 if (specificValue->get_valuetype() == Value::V_REFD) {
8620 return specificValue->is_unfoldable(refch, exp_val);
8621 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8626 case OPTYPE_ISPRESENT
:
8627 // TODO: "if you have motivation"
8629 case OPTYPE_ISVALUE
: // ti1
8631 case OPTYPE_LENGTHOF
: // ti1
8632 return u
.expr
.ti1
->get_DerivedRef() != 0
8633 || u
.expr
.ti1
->get_Template()->get_templatetype()
8634 != Template::SPECIFIC_VALUE
8635 || u
.expr
.ti1
->get_Template()->get_specific_value()
8636 ->is_unfoldable(refch
, exp_val
);
8640 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8642 case OPTYPE_ADD
: // v1 v2
8643 case OPTYPE_SUBTRACT
:
8644 case OPTYPE_MULTIPLY
:
8660 case OPTYPE_INT2BIT
:
8661 case OPTYPE_INT2HEX
:
8662 case OPTYPE_INT2OCT
:
8663 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8664 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8665 case OPTYPE_AND
: // short-circuit evaluation
8666 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8667 || (u
.expr
.v1
->get_val_bool() &&
8668 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8669 case OPTYPE_OR
: // short-circuit evaluation
8670 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8671 || (!u
.expr
.v1
->get_val_bool() &&
8672 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8674 if (!u
.expr
.ti1
->get_specific_value()) return true;
8675 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8676 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8677 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8678 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8680 if (!u
.expr
.ti1
->get_specific_value() ||
8681 !u
.expr
.t2
->get_specific_value()) return true;
8682 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8683 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8684 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8686 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8687 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8688 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8689 case OPTYPE_REPLACE
: {
8690 if (!u
.expr
.ti1
->get_specific_value() ||
8691 !u
.expr
.ti4
->get_specific_value()) return true;
8692 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8693 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8694 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8695 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8696 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8698 case OPTYPE_VALUEOF
: // ti1
8699 /* \todo if you have motivation to implement the eval function
8702 case OPTYPE_ISCHOSEN_V
:
8703 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8704 case OPTYPE_LOG2STR
:
8705 case OPTYPE_ANY2UNISTR
:
8706 case OPTYPE_TTCN2STRING
:
8709 FATAL_ERROR("Value::is_unfoldable()");
8711 break; // should never get here
8714 case MACRO_TESTCASEID
:
8715 // this is known only at runtime
8721 // all literal values are foldable
8726 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8727 size_t start_i
, bool usedInIsbound
,
8728 ReferenceChain
*refch
)
8730 if (!subrefs
) return this;
8732 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8734 v
= v
->get_value_refd_last(refch
);
8735 switch(v
->valuetype
) {
8744 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8745 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8746 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8747 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8752 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8753 bool usedInIsbound
, const Location
& loc
)
8755 if (valuetype
== V_OMIT
) {
8756 loc
.error("Reference to field `%s' of omit value `%s'",
8757 field_id
.get_dispname().c_str(), get_fullname().c_str());
8760 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8761 Type
*t
= my_governor
->get_type_refd_last();
8762 switch (t
->get_typetype()) {
8766 case Type::T_CHOICE_A
:
8767 case Type::T_CHOICE_T
:
8768 case Type::T_OPENTYPE
:
8769 case Type::T_ANYTYPE
:
8770 if (!t
->has_comp_withName(field_id
)) {
8771 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8772 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8774 } else if (valuetype
!= V_CHOICE
) {
8775 // remain silent, the error is already reported
8777 } else if (*u
.choice
.alt_name
== field_id
) {
8779 return u
.choice
.alt_value
;
8781 if (!usedInIsbound
) {
8782 loc
.error("Reference to inactive field `%s' in a value of union type "
8783 "`%s'. The active field is `%s'",
8784 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8785 u
.choice
.alt_name
->get_dispname().c_str());
8791 if (!t
->has_comp_withName(field_id
)) {
8792 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8793 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8795 } else if (valuetype
!= V_SEQ
) {
8796 // remain silent, the error has been already reported
8801 if (!t
->has_comp_withName(field_id
)) {
8802 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8803 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8805 } else if (valuetype
!= V_SET
) {
8806 // remain silent, the error has been already reported
8810 loc
.error("Invalid field reference `%s': type `%s' "
8811 "does not have fields", field_id
.get_dispname().c_str(),
8812 t
->get_typename().c_str());
8815 // the common end for record & set types
8816 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8818 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8819 } else if (!is_asn1()) {
8820 if (!usedInIsbound
) {
8821 loc
.error("Reference to unbound field `%s'",
8822 field_id
.get_dispname().c_str());
8823 // this is an error in TTCN-3, which has been already reported
8827 CompField
*cf
= t
->get_comp_byName(field_id
);
8828 if (cf
->get_is_optional()) {
8829 // creating an explicit omit value
8830 Value
*v
= new Value(V_OMIT
);
8831 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8832 v
->set_my_scope(get_my_scope());
8833 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8835 } else if (cf
->has_default()) {
8836 // returning the component's default value
8837 return cf
->get_defval();
8839 // this is an error in ASN.1, which has been already reported
8845 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8846 ReferenceChain
*refch
)
8848 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8850 bool index_available
= false;
8851 if (!v_index
->is_unfoldable()) {
8852 if (v_index
->valuetype
== V_INT
) {
8853 index
= v_index
->get_val_Int()->get_val();
8854 index_available
= true;
8856 array_index
->error("An integer value was expected as index");
8859 if (valuetype
== V_OMIT
) {
8860 array_index
->error("Accessing an element with index of omit value `%s'",
8861 get_fullname().c_str());
8864 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8865 Type
*t
= my_governor
->get_type_refd_last();
8866 switch (t
->get_typetype()) {
8871 if (index_available
) {
8873 array_index
->error("A non-negative integer value was expected "
8874 "instead of %s for indexing a value of `record "
8875 "of' type `%s'", Int2string(index
).c_str(),
8876 t
->get_typename().c_str());
8879 switch (valuetype
) {
8881 if (!is_indexed()) {
8882 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8883 if (!usedInIsbound
) {
8884 array_index
->error("Index overflow in a value of `record of' "
8885 "type `%s': the index is %s, but the value "
8886 "has only %lu elements",
8887 t
->get_typename().c_str(),
8888 Int2string(index
).c_str(),
8889 (unsigned long)u
.val_vs
->get_nof_vs());
8893 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8894 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8895 temp
->error("Not used symbol is not allowed in this context");
8896 return u
.val_vs
->get_v_byIndex(index
);
8899 // Search the appropriate constant index.
8900 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8901 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8902 ->get_value_refd_last();
8903 if (iv_index
->get_valuetype() != V_INT
) continue;
8904 if (iv_index
->get_val_Int()->get_val() == index
)
8905 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8911 // remain silent, the error has been already reported
8915 // the error has been reported above
8919 if (index_available
) {
8921 array_index
->error("A non-negative integer value was expected "
8922 "instead of %s for indexing a value of `set of' type `%s'",
8923 Int2string(index
).c_str(), t
->get_typename().c_str());
8926 switch (valuetype
) {
8928 if (!is_indexed()) {
8929 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8930 if (!usedInIsbound
) {
8931 array_index
->error("Index overflow in a value of `set of' type "
8932 "`%s': the index is %s, but the value has "
8933 "only %lu elements",
8934 t
->get_typename().c_str(),
8935 Int2string(index
).c_str(),
8936 (unsigned long)u
.val_vs
->get_nof_vs());
8940 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8941 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8942 temp
->error("Not used symbol is not allowed in this context");
8946 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8947 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8948 ->get_value_refd_last();
8949 if (iv_index
->get_valuetype() != V_INT
) continue;
8950 if (iv_index
->get_val_Int()->get_val() == index
)
8951 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8957 // remain silent, the error has been already reported
8961 // the error has been reported above
8965 if (index_available
) {
8966 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8967 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8968 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8969 // perform the index transformation
8970 index
-= dim
->get_offset();
8971 if (!is_indexed()) {
8972 // check for index underflow/overflow or too few elements in the
8975 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8977 else return u
.val_vs
->get_v_byIndex(index
);
8979 if (index
< 0) return 0;
8980 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8981 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8982 ->get_value_refd_last();
8983 if (iv_index
->get_valuetype() != V_INT
) continue;
8984 if (iv_index
->get_val_Int()->get_val() == index
)
8985 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8990 // remain silent, the error has been already reported
8994 // the error has been reported above
8998 case Type::T_BSTR_A
:
9003 case Type::T_UTF8STRING
:
9004 case Type::T_NUMERICSTRING
:
9005 case Type::T_PRINTABLESTRING
:
9006 case Type::T_TELETEXSTRING
:
9007 case Type::T_VIDEOTEXSTRING
:
9008 case Type::T_IA5STRING
:
9009 case Type::T_GRAPHICSTRING
:
9010 case Type::T_VISIBLESTRING
:
9011 case Type::T_GENERALSTRING
:
9012 case Type::T_UNIVERSALSTRING
:
9013 case Type::T_BMPSTRING
:
9014 case Type::T_UTCTIME
:
9015 case Type::T_GENERALIZEDTIME
:
9016 case Type::T_OBJECTDESCRIPTOR
:
9017 if (index_available
) return get_string_element(index
, *array_index
);
9020 array_index
->error("Invalid array element reference: type `%s' cannot "
9021 "be indexed", t
->get_typename().c_str());
9026 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
9029 loc
.error("A non-negative integer value was expected instead of %s "
9030 "for indexing a string element", Int2string(index
).c_str());
9033 size_t string_length
;
9034 switch (valuetype
) {
9039 string_length
= u
.str
.val_str
->size();
9042 string_length
= u
.str
.val_str
->size() / 2;
9045 string_length
= u
.ustr
.val_ustr
->size();
9048 // remain silent, the error has been already reported
9051 if (index
>= static_cast<Int
>(string_length
)) {
9052 loc
.error("Index overflow when accessing a string element: "
9053 "the index is %s, but the string has only %lu elements",
9054 Int2string(index
).c_str(), (unsigned long) string_length
);
9057 switch (valuetype
) {
9062 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
9063 return (*u
.str
.str_elements
)[index
];
9065 Value
*t_val
= new Value(valuetype
,
9066 new string(u
.str
.val_str
->substr(index
, 1)));
9067 add_string_element(index
, t_val
, u
.str
.str_elements
);
9071 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
9072 return (*u
.str
.str_elements
)[index
];
9074 Value
*t_val
= new Value(V_OSTR
,
9075 new string(u
.str
.val_str
->substr(2 * index
, 2)));
9076 add_string_element(index
, t_val
, u
.str
.str_elements
);
9080 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
9081 return (*u
.ustr
.ustr_elements
)[index
];
9083 Value
*t_val
= new Value(V_USTR
,
9084 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
9085 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
9089 FATAL_ERROR("Value::get_string_element()");
9094 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
9095 Type::expected_value_t exp_val
)
9097 set_lowerid_to_ref();
9098 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
9099 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
9101 error("A value or expression of type %s was expected", type_name
);
9102 if (valuetype
== V_REFD
) {
9103 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
9104 t_chk
->chk_this_refd_value(this, 0, exp_val
);
9106 get_value_refd_last(0, exp_val
);
9107 if (error_flag
) set_valuetype(V_ERROR
);
9108 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
9111 int Value::is_parsed_infinity()
9113 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
9115 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
9116 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
9117 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
9122 bool Value::get_val_bool()
9125 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9127 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
9128 return v
->u
.val_bool
;
9131 int_val_t
* Value::get_val_Int()
9134 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9136 switch (v
->valuetype
) {
9139 case V_UNDEF_LOWERID
:
9140 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9141 "`%s'", (*u
.val_id
).get_dispname().c_str());
9143 FATAL_ERROR("Value::get_val_Int()");
9145 return v
->u
.val_Int
;
9148 const Identifier
* Value::get_val_id()
9153 case V_UNDEF_LOWERID
:
9156 FATAL_ERROR("Value::get_val_id()");
9161 const ttcn3float
& Value::get_val_Real()
9164 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9166 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
9167 return v
->u
.val_Real
;
9170 string
Value::get_val_str()
9172 Value
*v
= get_value_refd_last();
9173 switch (v
->valuetype
) {
9178 return *v
->u
.str
.val_str
;
9180 return v
->u
.char_syms
->get_string();
9182 error("Cannot use ISO-10646 string value in string context");
9185 error("Cannot use ISO-2022 string value in string context");
9190 error("Cannot use this value in charstring value context");
9195 ustring
Value::get_val_ustr()
9197 Value
*v
= get_value_refd_last();
9198 switch (v
->valuetype
) {
9200 return ustring(*v
->u
.str
.val_str
);
9202 return *v
->u
.ustr
.val_ustr
;
9204 return v
->u
.char_syms
->get_ustring();
9206 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9211 error("Cannot use this value in ISO-10646 string context");
9216 string
Value::get_val_iso2022str()
9218 Value
*v
= get_value_refd_last();
9219 switch (v
->valuetype
) {
9222 return *v
->u
.str
.val_str
;
9224 return v
->u
.char_syms
->get_iso2022string();
9226 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9231 error("Cannot use this value in ISO-2022 string context");
9236 size_t Value::get_val_strlen()
9238 Value
*v
= get_value_refd_last();
9239 switch (v
->valuetype
) {
9244 return v
->u
.str
.val_str
->size();
9246 return v
->u
.str
.val_str
->size()/2;
9248 return v
->u
.char_syms
->get_len();
9250 return v
->u
.ustr
.val_ustr
->size();
9254 error("Cannot use this value in string value context");
9259 Value::verdict_t
Value::get_val_verdict()
9265 FATAL_ERROR("Value::get_val_verdict()");
9270 size_t Value::get_nof_comps()
9272 switch (valuetype
) {
9276 return u
.oid_comps
->size();
9280 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9281 else return u
.val_vs
->get_nof_vs();
9284 return u
.val_nvs
->get_nof_nvs();
9289 return u
.str
.val_str
->size();
9291 return u
.str
.val_str
->size()/2;
9293 return u
.ustr
.val_ustr
->size();
9295 FATAL_ERROR("Value::get_nof_comps()");
9300 bool Value::is_indexed() const
9302 switch (valuetype
) {
9306 // Applicable only for list-types. Assigning a record/SEQUENCE or
9307 // set/SET with indexed notation is not supported.
9308 return u
.val_vs
->is_indexed();
9310 FATAL_ERROR("Value::is_indexed()");
9316 const Identifier
& Value::get_alt_name()
9318 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9319 return *u
.choice
.alt_name
;
9322 Value
*Value::get_alt_value()
9324 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9325 return u
.choice
.alt_value
;
9328 void Value::set_alt_name_to_lowercase()
9330 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9331 string new_name
= u
.choice
.alt_name
->get_name();
9332 if (isupper(new_name
[0])) {
9333 new_name
[0] = tolower(new_name
[0]);
9334 if (new_name
[new_name
.size() - 1] == '_') {
9335 // an underscore is inserted at the end of the alternative name if it's
9336 // a basic type's name (since it would conflict with the class generated
9338 // remove the underscore, it won't conflict with anything if its name
9339 // starts with a lowercase letter
9340 new_name
.replace(new_name
.size() - 1, 1, "");
9342 delete u
.choice
.alt_name
;
9343 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9347 bool Value::has_oid_error()
9350 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9352 switch (valuetype
) {
9355 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9356 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9363 bool Value::get_oid_comps(vector
<string
>& comps
)
9365 bool ret_val
= true;
9367 switch (valuetype
) {
9369 v
= get_value_refd_last();
9373 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9374 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9375 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9376 // not all components can be calculated in compile-time
9382 FATAL_ERROR("Value::get_oid_comps()");
9387 void Value::add_se_comp(NamedValue
* nv
) {
9388 switch (valuetype
) {
9392 u
.val_nvs
= new NamedValues();
9393 u
.val_nvs
->add_nv(nv
);
9396 FATAL_ERROR("Value::add_se_comp()");
9400 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9405 return u
.val_nvs
->get_nv_byIndex(n
);
9407 FATAL_ERROR("Value::get_se_comp_byIndex()");
9412 Value
*Value::get_comp_byIndex(size_t n
)
9414 switch (valuetype
) {
9418 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9419 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9421 FATAL_ERROR("Value::get_comp_byIndex()");
9426 Value
*Value::get_index_byIndex(size_t n
)
9428 switch (valuetype
) {
9432 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9433 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9435 FATAL_ERROR("Value::get_index_byIndex()");
9440 bool Value::has_comp_withName(const Identifier
& p_name
)
9445 return u
.val_nvs
->has_nv_withName(p_name
);
9447 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9449 FATAL_ERROR("Value::get_has_comp_withName()");
9454 bool Value::field_is_chosen(const Identifier
& p_name
)
9456 Value
*v
=get_value_refd_last();
9457 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9458 return *v
->u
.choice
.alt_name
==p_name
;
9461 bool Value::field_is_present(const Identifier
& p_name
)
9463 Value
*v
=get_value_refd_last();
9464 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9465 FATAL_ERROR("Value::field_is_present()");
9466 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9467 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9468 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9471 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9476 return u
.val_nvs
->get_nv_byName(p_name
);
9478 FATAL_ERROR("Value::get_se_comp_byName()");
9483 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9488 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9490 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9491 return u
.choice
.alt_value
;
9495 FATAL_ERROR("Value::get_se_comp_byName()");
9500 void Value::chk_dupl_id()
9505 u
.val_nvs
->chk_dupl_id();
9508 FATAL_ERROR("Value::chk_dupl_id()");
9512 size_t Value::get_nof_ids() const
9516 return u
.ids
->size();
9519 FATAL_ERROR("Value::get_nof_ids()");
9524 Identifier
* Value::get_id_byIndex(size_t p_i
)
9528 return u
.ids
->get_nth_elem(p_i
);
9531 FATAL_ERROR("Value::get_id_byIndex()");
9536 bool Value::has_id(const Identifier
& p_id
)
9540 return u
.ids
->has_key(p_id
.get_name());
9543 FATAL_ERROR("Value::has_id()");
9548 Reference
*Value::get_reference() const
9550 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9554 Reference
*Value::get_refered() const
9556 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9560 Common::Assignment
*Value::get_refd_fat() const
9568 FATAL_ERROR("Value::get_refd_fat()");
9572 Ttcn::Reference
* Value::steal_ttcn_ref()
9574 Ttcn::Reference
*ret_val
=
9575 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9576 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9580 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9582 Ttcn::Ref_base
*t_ref
;
9583 if(valuetype
==V_REFD
) {
9584 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9585 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9588 else if(valuetype
==V_UNDEF_LOWERID
) {
9589 t_ref
=new Ttcn::Reference(u
.val_id
);
9590 t_ref
->set_location(*this);
9591 t_ref
->set_fullname(get_fullname());
9592 t_ref
->set_my_scope(get_my_scope());
9596 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9599 set_valuetype(V_ERROR
);
9603 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9604 Ttcn::ActualParList
*& p_ap
)
9606 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9609 p_ti
= u
.invoke
.t_list
;
9610 u
.invoke
.t_list
= 0;
9611 p_ap
= u
.invoke
.ap_list
;
9612 u
.invoke
.ap_list
= 0;
9613 set_valuetype(V_ERROR
);
9616 Common::Assignment
* Value::get_refd_assignment()
9625 FATAL_ERROR("Value::get_refd_assignment()");
9635 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9640 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9649 void Value::chk_OID(ReferenceChain
& refch
)
9651 if (checked
) return;
9652 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9653 FATAL_ERROR("Value::chk_OID()");
9654 if (!refch
.add(get_fullname())) {
9658 OID_comp::oidstate_t state
= OID_comp::START
;
9659 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9661 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9664 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9665 error("An OBJECT IDENTIFIER value must have at least "
9666 "two components"); // X.680 (07/2002) 31.10
9669 void Value::chk_ROID(ReferenceChain
& refch
)
9671 if (checked
) return;
9672 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9673 FATAL_ERROR("Value::chk_ROID()");
9674 if (!refch
.add(get_fullname())) {
9678 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9680 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9685 void Value::chk_recursions(ReferenceChain
& refch
)
9687 if (recurs_checked
) return;
9688 Value
*v
= get_value_refd_last();
9689 if (refch
.add(v
->get_fullname())) {
9690 switch (v
->valuetype
) {
9692 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9697 if (!v
->is_indexed()) {
9698 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9700 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9704 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9706 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9707 ->chk_recursions(refch
);
9714 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9716 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9721 chk_recursions_expr(refch
);
9726 if (v
->err_descr
) { // FIXME: make this work
9727 v
->err_descr
->chk_recursions(refch
);
9730 recurs_checked
= true;
9733 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9735 // first classify the unchecked ischosen() operation
9736 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9737 switch (u
.expr
.v_optype
) {
9738 case OPTYPE_UNARYPLUS
: // v1
9739 case OPTYPE_UNARYMINUS
:
9742 case OPTYPE_BIT2HEX
:
9743 case OPTYPE_BIT2INT
:
9744 case OPTYPE_BIT2OCT
:
9745 case OPTYPE_BIT2STR
:
9746 case OPTYPE_CHAR2INT
:
9747 case OPTYPE_CHAR2OCT
:
9748 case OPTYPE_FLOAT2INT
:
9749 case OPTYPE_FLOAT2STR
:
9750 case OPTYPE_HEX2BIT
:
9751 case OPTYPE_HEX2INT
:
9752 case OPTYPE_HEX2OCT
:
9753 case OPTYPE_HEX2STR
:
9754 case OPTYPE_INT2CHAR
:
9755 case OPTYPE_INT2FLOAT
:
9756 case OPTYPE_INT2STR
:
9757 case OPTYPE_INT2UNICHAR
:
9758 case OPTYPE_OCT2BIT
:
9759 case OPTYPE_OCT2CHAR
:
9760 case OPTYPE_OCT2HEX
:
9761 case OPTYPE_OCT2INT
:
9762 case OPTYPE_OCT2STR
:
9763 case OPTYPE_STR2BIT
:
9764 case OPTYPE_STR2FLOAT
:
9765 case OPTYPE_STR2HEX
:
9766 case OPTYPE_STR2INT
:
9767 case OPTYPE_STR2OCT
:
9768 case OPTYPE_UNICHAR2INT
:
9769 case OPTYPE_ENUM2INT
:
9770 case OPTYPE_UNICHAR2CHAR
:
9771 case OPTYPE_RNDWITHVAL
:
9772 case OPTYPE_ISCHOSEN_V
:
9773 case OPTYPE_GET_STRINGENCODING
:
9774 case OPTYPE_REMOVE_BOM
:
9775 case OPTYPE_DECODE_BASE64
:
9777 u
.expr
.v1
->chk_recursions(refch
);
9780 case OPTYPE_ISCHOSEN_T
:
9782 u
.expr
.t1
->chk_recursions(refch
);
9785 case OPTYPE_ADD
: // v1 v2
9786 case OPTYPE_SUBTRACT
:
9787 case OPTYPE_MULTIPLY
:
9808 case OPTYPE_INT2BIT
:
9809 case OPTYPE_INT2HEX
:
9810 case OPTYPE_INT2OCT
:
9812 u
.expr
.v1
->chk_recursions(refch
);
9815 u
.expr
.v2
->chk_recursions(refch
);
9818 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9819 case OPTYPE_OCT2UNICHAR
:
9820 case OPTYPE_ENCODE_BASE64
:
9822 u
.expr
.v1
->chk_recursions(refch
);
9826 u
.expr
.v2
->chk_recursions(refch
);
9831 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9832 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9836 u
.expr
.ti1
->chk_recursions(refch
);
9839 u
.expr
.v2
->chk_recursions(refch
);
9842 u
.expr
.v3
->chk_recursions(refch
);
9847 u
.expr
.ti1
->chk_recursions(refch
);
9850 u
.expr
.t2
->chk_recursions(refch
);
9853 u
.expr
.v3
->chk_recursions(refch
);
9856 case OPTYPE_DECOMP
: // v1 v2 v3
9858 u
.expr
.v1
->chk_recursions(refch
);
9861 u
.expr
.v2
->chk_recursions(refch
);
9864 u
.expr
.v3
->chk_recursions(refch
);
9867 case OPTYPE_REPLACE
:
9869 u
.expr
.ti1
->chk_recursions(refch
);
9872 u
.expr
.v2
->chk_recursions(refch
);
9875 u
.expr
.v3
->chk_recursions(refch
);
9878 u
.expr
.ti4
->chk_recursions(refch
);
9881 case OPTYPE_LENGTHOF
: // ti1
9882 case OPTYPE_SIZEOF
: // ti1
9883 case OPTYPE_VALUEOF
: // ti1
9885 case OPTYPE_ISPRESENT
:
9886 case OPTYPE_TTCN2STRING
:
9888 u
.expr
.ti1
->chk_recursions(refch
);
9891 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
9893 u
.expr
.ti1
->chk_recursions(refch
);
9897 u
.expr
.v2
->chk_recursions(refch
);
9901 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
9902 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9903 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9906 u
.expr
.v3
->chk_recursions(refch
);
9910 case OPTYPE_MATCH
: // v1 t2
9912 u
.expr
.v1
->chk_recursions(refch
);
9915 u
.expr
.t2
->chk_recursions(refch
);
9918 case OPTYPE_LOG2STR
:
9919 case OPTYPE_ANY2UNISTR
:
9920 u
.expr
.logargs
->chk_recursions(refch
);
9927 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9928 ReferenceChain
& refch
) {
9929 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9930 Assignment
*ass
= ref
->get_refd_assignment();
9932 set_valuetype(V_ERROR
);
9935 switch (ass
->get_asstype()) {
9936 case Assignment::A_CONST
:
9937 case Assignment::A_EXT_CONST
:
9938 case Assignment::A_MODULEPAR
:
9939 case Assignment::A_VAR
:
9940 case Assignment::A_PAR_VAL_IN
:
9941 case Assignment::A_PAR_VAL_OUT
:
9942 case Assignment::A_PAR_VAL_INOUT
: {
9943 Value
* v
= new Value(V_REFD
, ref
);
9944 v
->set_location(*ref
);
9945 v
->set_my_scope(get_my_scope());
9946 v
->set_fullname(get_fullname()+".<operand>");
9948 v
->chk_recursions(refch
);
9952 case Assignment::A_MODULEPAR_TEMP
:
9953 case Assignment::A_TEMPLATE
:
9954 case Assignment::A_VAR_TEMPLATE
:
9955 case Assignment::A_PAR_TEMPL_IN
:
9956 case Assignment::A_PAR_TEMPL_OUT
:
9957 case Assignment::A_PAR_TEMPL_INOUT
: {
9958 Template
* t
= new Template(ref
->clone());
9959 t
->set_location(*ref
);
9960 t
->set_my_scope(get_my_scope());
9961 t
->set_fullname(get_fullname()+".<operand>");
9963 t
->chk_recursions(refch
);
9968 // remain silent, the error has been already reported
9969 set_valuetype(V_ERROR
);
9974 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9976 bool self_ref
= false;
9977 switch (t
->get_templatetype()) {
9978 case Ttcn::Template::SPECIFIC_VALUE
: {
9979 Value
*v
= t
->get_specific_value();
9980 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9981 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9982 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9984 case Ttcn::Template::TEMPLATE_REFD
: {
9985 Ttcn::Ref_base
*refb
= t
->get_reference();
9986 Common::Assignment
*ass
= refb
->get_refd_assignment();
9987 self_ref
|= (ass
== lhs
);
9989 case Ttcn::Template::ALL_FROM
:
9990 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9991 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9993 case Ttcn::Template::TEMPLATE_LIST
:
9994 case Ttcn::Template::SUPERSET_MATCH
:
9995 case Ttcn::Template::SUBSET_MATCH
:
9996 case Ttcn::Template::PERMUTATION_MATCH
:
9997 case Ttcn::Template::COMPLEMENTED_LIST
:
9998 case Ttcn::Template::VALUE_LIST
: {
9999 size_t num
= t
->get_nof_comps();
10000 for (size_t i
= 0; i
< num
; ++i
) {
10001 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
10004 // not yet clear whether we should use this or the above for TEMPLATE_LIST
10005 // case Ttcn::Template::TEMPLATE_LIST: {
10006 // size_t num = t->get_nof_listitems();
10007 // for (size_t i=0; i < num; ++i) {
10008 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
10011 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
10012 size_t nnt
= t
->get_nof_comps();
10013 for (size_t i
=0; i
< nnt
; ++i
) {
10014 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
10015 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
10018 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
10019 size_t nnt
= t
->get_nof_comps();
10020 for (size_t i
=0; i
< nnt
; ++i
) {
10021 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
10022 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
10025 case Ttcn::Template::VALUE_RANGE
: {
10026 Ttcn::ValueRange
*vr
= t
->get_value_range();
10027 Common::Value
*v
= vr
->get_min_v();
10028 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
10029 v
= vr
->get_max_v();
10030 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
10032 case Ttcn::Template::CSTR_PATTERN
:
10033 case Ttcn::Template::USTR_PATTERN
: {
10034 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
10035 self_ref
|= ps
->chk_self_ref(lhs
);
10037 case Ttcn::Template::BSTR_PATTERN
:
10038 case Ttcn::Template::HSTR_PATTERN
:
10039 case Ttcn::Template::OSTR_PATTERN
: {
10040 // FIXME: cannot access u.pattern
10042 case Ttcn::Template::ANY_VALUE
:
10043 case Ttcn::Template::ANY_OR_OMIT
:
10044 case Ttcn::Template::OMIT_VALUE
:
10045 case Ttcn::Template::TEMPLATE_NOTUSED
:
10046 break; // self-ref can't happen
10047 case Ttcn::Template::TEMPLATE_INVOKE
:
10048 break; // assume self-ref can't happen
10049 case Ttcn::Template::TEMPLATE_ERROR
:
10050 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
10053 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
10054 // break; // and hope for the best
10059 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
10061 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
10062 namedbool is_str_elem
= NOT_STR_ELEM
;
10063 if (v
->valuetype
== V_REFD
) {
10064 Reference
*ref
= v
->get_reference();
10065 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
10066 if (subrefs
&& subrefs
->refers_to_string_element()) {
10067 is_str_elem
= IS_STR_ELEM
;
10070 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
10071 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
10075 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
10077 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
10078 if (!lhs
) FATAL_ERROR("no lhs!");
10079 bool self_ref
= false;
10080 switch (u
.expr
.v_optype
) {
10081 case OPTYPE_RND
: // -
10082 case OPTYPE_TESTCASENAME
: // -
10083 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
10084 case OPTYPE_COMP_MTC
: // -
10085 case OPTYPE_COMP_SYSTEM
: // -
10086 case OPTYPE_COMP_SELF
: // -
10087 case OPTYPE_COMP_RUNNING_ANY
: // -
10088 case OPTYPE_COMP_RUNNING_ALL
: // -
10089 case OPTYPE_COMP_ALIVE_ANY
: // -
10090 case OPTYPE_COMP_ALIVE_ALL
: // -
10091 case OPTYPE_TMR_RUNNING_ANY
: // -
10092 case OPTYPE_GETVERDICT
: // -
10093 case OPTYPE_PROF_RUNNING
: // -
10094 case OPTYPE_CHECKSTATE_ANY
:
10095 case OPTYPE_CHECKSTATE_ALL
:
10096 break; // nothing to do
10098 case OPTYPE_MATCH
: // v1 t2
10099 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10101 case OPTYPE_UNARYPLUS
: // v1
10102 case OPTYPE_UNARYMINUS
: // v1
10103 case OPTYPE_NOT
: // v1
10104 case OPTYPE_NOT4B
: // v1
10105 case OPTYPE_BIT2HEX
: // v1
10106 case OPTYPE_BIT2INT
: // v1
10107 case OPTYPE_BIT2OCT
: // v1
10108 case OPTYPE_BIT2STR
: // v1
10109 case OPTYPE_CHAR2INT
: // v1
10110 case OPTYPE_CHAR2OCT
: // v1
10111 case OPTYPE_FLOAT2INT
: // v1
10112 case OPTYPE_FLOAT2STR
: // v1
10113 case OPTYPE_HEX2BIT
: // v1
10114 case OPTYPE_HEX2INT
: // v1
10115 case OPTYPE_HEX2OCT
: // v1
10116 case OPTYPE_HEX2STR
: // v1
10117 case OPTYPE_INT2CHAR
: // v1
10118 case OPTYPE_INT2FLOAT
: // v1
10119 case OPTYPE_INT2STR
: // v1
10120 case OPTYPE_INT2UNICHAR
: // v1
10121 case OPTYPE_OCT2BIT
: // v1
10122 case OPTYPE_OCT2CHAR
: // v1
10123 case OPTYPE_OCT2HEX
: // v1
10124 case OPTYPE_OCT2INT
: // v1
10125 case OPTYPE_OCT2STR
: // v1
10126 case OPTYPE_STR2BIT
: // v1
10127 case OPTYPE_STR2FLOAT
: // v1
10128 case OPTYPE_STR2HEX
: // v1
10129 case OPTYPE_STR2INT
: // v1
10130 case OPTYPE_STR2OCT
: // v1
10131 case OPTYPE_UNICHAR2INT
: // v1
10132 case OPTYPE_UNICHAR2CHAR
: // v1
10133 case OPTYPE_ENUM2INT
: // v1
10134 case OPTYPE_RNDWITHVAL
: // v1
10135 case OPTYPE_COMP_RUNNING
: // v1
10136 case OPTYPE_COMP_ALIVE
: // v1
10137 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
10138 case OPTYPE_GET_STRINGENCODING
:
10139 case OPTYPE_DECODE_BASE64
:
10140 case OPTYPE_REMOVE_BOM
:
10141 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10143 case OPTYPE_ADD
: // v1 v2
10144 case OPTYPE_SUBTRACT
: // v1 v2
10145 case OPTYPE_MULTIPLY
: // v1 v2
10146 case OPTYPE_DIVIDE
: // v1 v2
10147 case OPTYPE_MOD
: // v1 v2
10148 case OPTYPE_REM
: // v1 v2
10149 case OPTYPE_CONCAT
: // v1 v2
10150 case OPTYPE_EQ
: // v1 v2
10151 case OPTYPE_LT
: // v1 v2
10152 case OPTYPE_GT
: // v1 v2
10153 case OPTYPE_NE
: // v1 v2
10154 case OPTYPE_GE
: // v1 v2
10155 case OPTYPE_LE
: // v1 v2
10156 case OPTYPE_AND
: // v1 v2
10157 case OPTYPE_OR
: // v1 v2
10158 case OPTYPE_XOR
: // v1 v2
10159 case OPTYPE_AND4B
: // v1 v2
10160 case OPTYPE_OR4B
: // v1 v2
10161 case OPTYPE_XOR4B
: // v1 v2
10162 case OPTYPE_SHL
: // v1 v2
10163 case OPTYPE_SHR
: // v1 v2
10164 case OPTYPE_ROTL
: // v1 v2
10165 case OPTYPE_ROTR
: // v1 v2
10166 case OPTYPE_INT2BIT
: // v1 v2
10167 case OPTYPE_INT2HEX
: // v1 v2
10168 case OPTYPE_INT2OCT
: // v1 v2
10169 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10170 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10172 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
10173 case OPTYPE_OCT2UNICHAR
:
10174 case OPTYPE_ENCODE_BASE64
:
10175 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10176 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10178 case OPTYPE_DECOMP
: // v1 v2 v3
10179 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10180 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10181 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10184 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
10185 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
10187 case OPTYPE_SUBSTR
: // ti1 v2 v3
10188 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10189 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
10190 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
10193 case OPTYPE_REGEXP
: // ti1 t2 v3
10194 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10195 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10197 case OPTYPE_LENGTHOF
: // ti1
10198 case OPTYPE_SIZEOF
: // ti1
10199 case OPTYPE_VALUEOF
: // ti1
10200 case OPTYPE_ENCODE
: // ti1
10201 case OPTYPE_TTCN2STRING
:
10202 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10204 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
10205 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10206 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10208 case OPTYPE_DECVALUE_UNICHAR
: { // r1 r2 [v3]
10209 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10210 self_ref
|= (ass
== lhs
);
10211 if (u
.expr
.v3
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10214 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
10215 // component.create -- assume no self-ref
10216 case OPTYPE_ACTIVATE
: // r1
10217 // defaultref := activate(altstep) -- assume no self-ref
10218 case OPTYPE_TMR_RUNNING
: // r1
10219 // boolvar := a_timer.running -- assume no self-ref
10223 case OPTYPE_ANY2UNISTR
:
10224 case OPTYPE_LOG2STR
: {// logargs
10225 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
10226 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
10227 switch (la
->get_type()) {
10228 case Ttcn::LogArgument::L_UNDEF
:
10229 case Ttcn::LogArgument::L_ERROR
:
10230 FATAL_ERROR("%s argument type",
10231 u
.expr
.v_optype
== OPTYPE_ANY2UNISTR
? "any2unistr" : "log2str");
10232 break; // not reached
10234 case Ttcn::LogArgument::L_MACRO
:
10235 case Ttcn::LogArgument::L_STR
:
10236 break; // self reference not possible
10238 case Ttcn::LogArgument::L_VAL
:
10239 case Ttcn::LogArgument::L_MATCH
:
10240 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
10243 case Ttcn::LogArgument::L_REF
: {
10244 Ttcn::Ref_base
*ref
= la
->get_ref();
10245 Common::Assignment
*ass
= ref
->get_refd_assignment();
10246 self_ref
|= (ass
== lhs
);
10249 case Ttcn::LogArgument::L_TI
: {
10250 Ttcn::TemplateInstance
*ti
= la
->get_ti();
10251 Ttcn::Template
*t
= ti
->get_Template();
10252 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10255 // no default please
10256 } // switch la->logargtype
10260 case OPTYPE_DECODE
: { // r1 r2
10261 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10262 self_ref
|= (ass
== lhs
);
10264 case OPTYPE_EXECUTE
: // r1 [v2]
10266 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10270 case OPTYPE_UNDEF_RUNNING
: // r1
10271 case OPTYPE_TMR_READ
: { // r1
10272 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
10273 self_ref
|= (ass
== lhs
);
10276 case OPTYPE_ISCHOSEN_T
: // t1 i2
10277 case OPTYPE_ISBOUND
: // ti1
10278 case OPTYPE_ISVALUE
: // ti1
10279 case OPTYPE_ISPRESENT
: { // ti1
10281 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10282 else t
= u
.expr
.ti1
->get_Template();
10283 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10286 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10288 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10291 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10292 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10296 case NUMBER_OF_OPTYPES
: // can never happen
10297 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10298 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10300 } // switch u.expr.v_optype
10305 string
Value::create_stringRepr()
10307 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10308 switch (valuetype
) {
10310 return string("<erroneous>");
10312 return string("NULL");
10314 if (!parse_only
&& is_asn1()) {
10315 if (u
.val_bool
) return string("TRUE");
10316 else return string("FALSE");
10319 if (u
.val_bool
) return string("true");
10320 else return string("false");
10323 return u
.val_Int
->t_str();
10325 return Real2string(u
.val_Real
);
10328 case V_UNDEF_LOWERID
:
10329 return u
.val_id
->get_name();
10330 case V_NAMEDBITS
: {
10331 string
ret_val("{ ");
10332 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10333 if (i
>0) ret_val
+= ' ';
10334 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10339 string
ret_val('\'');
10340 ret_val
+= *u
.str
.val_str
;
10344 string
ret_val('\'');
10345 ret_val
+= *u
.str
.val_str
;
10349 string
ret_val('\'');
10350 ret_val
+= *u
.str
.val_str
;
10355 return u
.str
.val_str
->get_stringRepr();
10357 return u
.ustr
.val_ustr
->get_stringRepr();
10359 /** \todo stringrepr of V_CHARSYMS */
10360 return string("<sorry, string representation of charsyms "
10361 "not implemented>");
10365 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10367 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10368 if (i
>0) ret_val
+= ' ';
10369 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10374 if (!parse_only
&& is_asn1()) {
10375 string
ret_val(u
.choice
.alt_name
->get_dispname());
10377 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10381 string
ret_val("{ ");
10382 ret_val
+= u
.choice
.alt_name
->get_dispname();
10384 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10391 string
ret_val("{ ");
10392 if (!is_indexed()) {
10393 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10394 if (i
> 0) ret_val
+= ", ";
10395 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10398 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10399 if (i
> 0) ret_val
+= ", ";
10400 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10407 string
ret_val("{ ");
10408 bool asn1_flag
= !parse_only
&& is_asn1();
10409 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10410 if (i
> 0) ret_val
+= ", ";
10411 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10412 ret_val
+= nv
->get_name().get_dispname();
10413 if (asn1_flag
) ret_val
+= ' ';
10414 else ret_val
+= " := ";
10415 ret_val
+= nv
->get_value()->get_stringRepr();
10420 // do not evaluate the reference if it is not done so far
10421 // (e.g. in parse-only mode)
10422 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10423 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10424 else return t_val
->get_stringRepr(); }
10426 return string("omit");
10428 switch (u
.verdict
) {
10430 return string("none");
10432 return string("pass");
10433 case Verdict_INCONC
:
10434 return string("inconc");
10436 return string("fail");
10437 case Verdict_ERROR
:
10438 return string("error");
10440 return string("<unknown verdict value>");
10442 case V_DEFAULT_NULL
:
10444 return string("null");
10446 switch (u
.expr
.v_optype
) {
10448 return string("rnd()");
10449 case OPTYPE_TESTCASENAME
:
10450 return string("testcasename()");
10451 case OPTYPE_UNARYPLUS
:
10452 return create_stringRepr_unary("+");
10453 case OPTYPE_UNARYMINUS
:
10454 return create_stringRepr_unary("-");
10456 return create_stringRepr_unary("not");
10458 return create_stringRepr_unary("not4b");
10459 case OPTYPE_BIT2HEX
:
10460 return create_stringRepr_predef1("bit2hex");
10461 case OPTYPE_BIT2INT
:
10462 return create_stringRepr_predef1("bit2int");
10463 case OPTYPE_BIT2OCT
:
10464 return create_stringRepr_predef1("bit2oct");
10465 case OPTYPE_BIT2STR
:
10466 return create_stringRepr_predef1("bit2str");
10467 case OPTYPE_CHAR2INT
:
10468 return create_stringRepr_predef1("char2int");
10469 case OPTYPE_CHAR2OCT
:
10470 return create_stringRepr_predef1("char2oct");
10471 case OPTYPE_FLOAT2INT
:
10472 return create_stringRepr_predef1("float2int");
10473 case OPTYPE_FLOAT2STR
:
10474 return create_stringRepr_predef1("float2str");
10475 case OPTYPE_HEX2BIT
:
10476 return create_stringRepr_predef1("hex2bit");
10477 case OPTYPE_HEX2INT
:
10478 return create_stringRepr_predef1("hex2int");
10479 case OPTYPE_HEX2OCT
:
10480 return create_stringRepr_predef1("hex2oct");
10481 case OPTYPE_HEX2STR
:
10482 return create_stringRepr_predef1("hex2str");
10483 case OPTYPE_INT2CHAR
:
10484 return create_stringRepr_predef1("int2char");
10485 case OPTYPE_INT2FLOAT
:
10486 return create_stringRepr_predef1("int2float");
10487 case OPTYPE_INT2STR
:
10488 return create_stringRepr_predef1("int2str");
10489 case OPTYPE_INT2UNICHAR
:
10490 return create_stringRepr_predef1("int2unichar");
10491 case OPTYPE_OCT2BIT
:
10492 return create_stringRepr_predef1("oct2bit");
10493 case OPTYPE_OCT2CHAR
:
10494 return create_stringRepr_predef1("oct2char");
10495 case OPTYPE_OCT2HEX
:
10496 return create_stringRepr_predef1("oct2hex");
10497 case OPTYPE_OCT2INT
:
10498 return create_stringRepr_predef1("oct2int");
10499 case OPTYPE_OCT2STR
:
10500 return create_stringRepr_predef1("oct2str");
10501 case OPTYPE_GET_STRINGENCODING
:
10502 return create_stringRepr_predef1("get_stringencoding");
10503 case OPTYPE_REMOVE_BOM
:
10504 return create_stringRepr_predef1("remove_bom");
10505 case OPTYPE_ENCODE_BASE64
: {
10506 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10507 else return create_stringRepr_predef1("encode_base64");
10509 case OPTYPE_DECODE_BASE64
:
10510 return create_stringRepr_predef1("decode_base64");
10511 case OPTYPE_OCT2UNICHAR
:{
10512 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10513 else return create_stringRepr_predef1("oct2unichar");
10515 case OPTYPE_UNICHAR2OCT
: {
10516 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10517 else return create_stringRepr_predef1("unichar2oct");
10519 case OPTYPE_ENCVALUE_UNICHAR
: {
10520 if (u
.expr
.v2
) return create_stringRepr_predef2("encvalue_unichar");
10521 else return create_stringRepr_predef1("encvalue_unichar");
10523 case OPTYPE_DECVALUE_UNICHAR
: {
10525 string
ret_val("decvalue_unichar");
10527 ret_val
+= u
.expr
.v1
->get_stringRepr();
10529 ret_val
+= u
.expr
.v2
->get_stringRepr();
10531 ret_val
+= u
.expr
.v3
->get_stringRepr();
10535 else return create_stringRepr_predef2("decvalue_unichar");
10537 case OPTYPE_STR2BIT
:
10538 return create_stringRepr_predef1("str2bit");
10539 case OPTYPE_STR2FLOAT
:
10540 return create_stringRepr_predef1("str2float");
10541 case OPTYPE_STR2HEX
:
10542 return create_stringRepr_predef1("str2hex");
10543 case OPTYPE_STR2INT
:
10544 return create_stringRepr_predef1("str2int");
10545 case OPTYPE_STR2OCT
:
10546 return create_stringRepr_predef1("str2oct");
10547 case OPTYPE_UNICHAR2INT
:
10548 return create_stringRepr_predef1("unichar2int");
10549 case OPTYPE_UNICHAR2CHAR
:
10550 return create_stringRepr_predef1("unichar2char");
10551 case OPTYPE_ENUM2INT
:
10552 return create_stringRepr_predef1("enum2int");
10553 case OPTYPE_ENCODE
:
10554 return create_stringRepr_predef1("encvalue");
10555 case OPTYPE_DECODE
:
10556 return create_stringRepr_predef2("decvalue");
10557 case OPTYPE_RNDWITHVAL
:
10558 return create_stringRepr_predef1("rnd");
10560 return create_stringRepr_infix("+");
10561 case OPTYPE_SUBTRACT
:
10562 return create_stringRepr_infix("-");
10563 case OPTYPE_MULTIPLY
:
10564 return create_stringRepr_infix("*");
10565 case OPTYPE_DIVIDE
:
10566 return create_stringRepr_infix("/");
10568 return create_stringRepr_infix("mod");
10570 return create_stringRepr_infix("rem");
10571 case OPTYPE_CONCAT
:
10572 return create_stringRepr_infix("&");
10574 return create_stringRepr_infix("==");
10576 return create_stringRepr_infix("<");
10578 return create_stringRepr_infix(">");
10580 return create_stringRepr_infix("!=");
10582 return create_stringRepr_infix(">=");
10584 return create_stringRepr_infix("<=");
10586 return create_stringRepr_infix("and");
10588 return create_stringRepr_infix("or");
10590 return create_stringRepr_infix("xor");
10592 return create_stringRepr_infix("and4b");
10594 return create_stringRepr_infix("or4b");
10596 return create_stringRepr_infix("xor4b");
10598 return create_stringRepr_infix("<<");
10600 return create_stringRepr_infix(">>");
10602 return create_stringRepr_infix("<@");
10604 return create_stringRepr_infix("@>");
10605 case OPTYPE_INT2BIT
:
10606 return create_stringRepr_predef2("int2bit");
10607 case OPTYPE_INT2HEX
:
10608 return create_stringRepr_predef2("int2hex");
10609 case OPTYPE_INT2OCT
:
10610 return create_stringRepr_predef2("int2oct");
10611 case OPTYPE_SUBSTR
: {
10612 string
ret_val("substr(");
10613 u
.expr
.ti1
->append_stringRepr(ret_val
);
10615 ret_val
+= u
.expr
.v2
->get_stringRepr();
10617 ret_val
+= u
.expr
.v3
->get_stringRepr();
10621 case OPTYPE_REGEXP
: {
10622 string
ret_val("regexp(");
10623 u
.expr
.ti1
->append_stringRepr(ret_val
);
10625 u
.expr
.t2
->append_stringRepr(ret_val
);
10627 ret_val
+= u
.expr
.v3
->get_stringRepr();
10631 case OPTYPE_DECOMP
: {
10632 string
ret_val("decomp(");
10633 ret_val
+= u
.expr
.v1
->get_stringRepr();
10635 ret_val
+= u
.expr
.v2
->get_stringRepr();
10637 ret_val
+= u
.expr
.v3
->get_stringRepr();
10641 case OPTYPE_REPLACE
: {
10642 string
ret_val("replace(");
10643 u
.expr
.ti1
->append_stringRepr(ret_val
);
10645 ret_val
+= u
.expr
.v2
->get_stringRepr();
10647 ret_val
+= u
.expr
.v3
->get_stringRepr();
10649 u
.expr
.ti4
->append_stringRepr(ret_val
);
10653 case OPTYPE_ISPRESENT
: {
10654 string
ret_val("ispresent(");
10655 u
.expr
.ti1
->append_stringRepr(ret_val
);
10658 case OPTYPE_ISCHOSEN
: {
10659 string
ret_val("ischosen(");
10660 ret_val
+= u
.expr
.r1
->get_dispname();
10662 ret_val
+= u
.expr
.i2
->get_dispname();
10665 case OPTYPE_ISCHOSEN_V
: {
10666 string
ret_val("ischosen(");
10667 ret_val
+= u
.expr
.v1
->get_stringRepr();
10669 ret_val
+= u
.expr
.i2
->get_dispname();
10672 case OPTYPE_ISCHOSEN_T
: {
10673 string
ret_val("ischosen(");
10674 ret_val
+= u
.expr
.t1
->get_stringRepr();
10676 ret_val
+= u
.expr
.i2
->get_dispname();
10679 case OPTYPE_LENGTHOF
: {
10680 string
ret_val("lengthof(");
10681 u
.expr
.ti1
->append_stringRepr(ret_val
);
10684 case OPTYPE_SIZEOF
: {
10685 string
ret_val("sizeof(");
10686 u
.expr
.ti1
->append_stringRepr(ret_val
);
10689 case OPTYPE_ISVALUE
: {
10690 string
ret_val("isvalue(");
10691 u
.expr
.ti1
->append_stringRepr(ret_val
);
10694 case OPTYPE_VALUEOF
: {
10695 string
ret_val("valueof(");
10696 u
.expr
.ti1
->append_stringRepr(ret_val
);
10699 case OPTYPE_LOG2STR
:
10700 return string("log2str(...)");
10701 case OPTYPE_ANY2UNISTR
:
10702 return string("any2unistr(...)");
10703 case OPTYPE_MATCH
: {
10704 string
ret_val("match(");
10705 ret_val
+= u
.expr
.v1
->get_stringRepr();
10707 u
.expr
.t2
->append_stringRepr(ret_val
);
10710 case OPTYPE_TTCN2STRING
: {
10711 string
ret_val("ttcn2string(");
10712 u
.expr
.ti1
->append_stringRepr(ret_val
);
10716 case OPTYPE_UNDEF_RUNNING
:
10717 return u
.expr
.r1
->get_dispname() + ".running";
10718 case OPTYPE_COMP_NULL
:
10719 return string("null");
10720 case OPTYPE_COMP_MTC
:
10721 return string("mtc");
10722 case OPTYPE_COMP_SYSTEM
:
10723 return string("system");
10724 case OPTYPE_COMP_SELF
:
10725 return string("self");
10726 case OPTYPE_COMP_CREATE
: {
10727 string
ret_val(u
.expr
.r1
->get_dispname());
10728 ret_val
+= ".create";
10729 if (u
.expr
.v2
|| u
.expr
.v3
) {
10731 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10732 else ret_val
+= '-';
10735 ret_val
+= u
.expr
.v3
->get_stringRepr();
10739 if (u
.expr
.b4
) ret_val
+= " alive";
10741 case OPTYPE_COMP_RUNNING
:
10742 return u
.expr
.v1
->get_stringRepr() + ".running";
10743 case OPTYPE_COMP_RUNNING_ANY
:
10744 return string("any component.running");
10745 case OPTYPE_COMP_RUNNING_ALL
:
10746 return string("all component.running");
10747 case OPTYPE_COMP_ALIVE
:
10748 return u
.expr
.v1
->get_stringRepr() + ".alive";
10749 case OPTYPE_COMP_ALIVE_ANY
:
10750 return string("any component.alive");
10751 case OPTYPE_COMP_ALIVE_ALL
:
10752 return string("all component.alive");
10753 case OPTYPE_TMR_READ
:
10754 return u
.expr
.r1
->get_dispname() + ".read";
10755 case OPTYPE_TMR_RUNNING
:
10756 return u
.expr
.r1
->get_dispname() + ".running";
10757 case OPTYPE_TMR_RUNNING_ANY
:
10758 return string("any timer.running");
10759 case OPTYPE_CHECKSTATE_ANY
:
10760 case OPTYPE_CHECKSTATE_ALL
: {
10761 string
ret_val("");
10765 if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ANY
) {
10766 ret_val
+= "any port";
10767 } else if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ALL
) {
10768 ret_val
+= "all port";
10771 ret_val
+= "checkstate(";
10772 ret_val
+= u
.expr
.v2
->get_stringRepr();
10775 case OPTYPE_GETVERDICT
:
10776 return string("getverdict");
10777 case OPTYPE_ACTIVATE
: {
10778 string
ret_val("activate(");
10779 ret_val
+= u
.expr
.r1
->get_dispname();
10782 case OPTYPE_ACTIVATE_REFD
: {
10783 string
ret_val("activate(derefer(");
10784 ret_val
+= u
.expr
.v1
->get_stringRepr();
10786 if (u
.expr
.state
== EXPR_CHECKED
) {
10787 if (u
.expr
.ap_list2
) {
10788 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10789 for (size_t i
= 0; i
< nof_pars
; i
++) {
10790 if (i
> 0) ret_val
+= ", ";
10791 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10795 if (u
.expr
.t_list2
) {
10796 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10797 for (size_t i
= 0; i
< nof_pars
; i
++) {
10798 if (i
> 0) ret_val
+= ", ";
10799 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10805 case OPTYPE_EXECUTE
: {
10806 string
ret_val("execute(");
10807 ret_val
+= u
.expr
.r1
->get_dispname();
10810 ret_val
+= u
.expr
.v2
->get_stringRepr();
10814 case OPTYPE_EXECUTE_REFD
: {
10815 string
ret_val("execute(derefers(");
10816 ret_val
+= u
.expr
.v1
->get_stringRepr();
10818 if (u
.expr
.state
== EXPR_CHECKED
) {
10819 if (u
.expr
.ap_list2
) {
10820 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10821 for (size_t i
= 0; i
< nof_pars
; i
++) {
10822 if (i
> 0) ret_val
+= ", ";
10823 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10827 if (u
.expr
.t_list2
) {
10828 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10829 for (size_t i
= 0; i
< nof_pars
; i
++) {
10830 if (i
> 0) ret_val
+= ", ";
10831 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10838 ret_val
+= u
.expr
.v3
->get_stringRepr();
10842 case OPTYPE_PROF_RUNNING
:
10843 return string("@profiler.running");
10845 return string("<unsupported optype>");
10846 } // switch u.expr.v_optype
10849 case MACRO_MODULEID
:
10850 return string("%moduleId");
10851 case MACRO_FILENAME
:
10852 return string("%fileName");
10853 case MACRO_BFILENAME
:
10854 return string("__BFILE__");
10855 case MACRO_FILEPATH
:
10856 return string("__FILE__");
10857 case MACRO_LINENUMBER
:
10858 return string("%lineNumber");
10859 case MACRO_LINENUMBER_C
:
10860 return string("__LINE__");
10861 case MACRO_DEFINITIONID
:
10862 return string("%definitionId");
10864 return string("__SCOPE__");
10865 case MACRO_TESTCASEID
:
10866 return string("%testcaseId");
10868 return string("<unknown macro>");
10869 } // switch u.macro
10871 return string('-');
10875 string
ret_val("refers(");
10876 ret_val
+= u
.refd_fat
->get_assname();
10881 ret_val
+= u
.invoke
.v
->get_stringRepr();
10882 ret_val
+= ".apply(";
10883 if (u
.invoke
.ap_list
) {
10884 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10885 for (size_t i
= 0; i
< nof_pars
; i
++) {
10886 if (i
> 0) ret_val
+= ", ";
10887 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10889 } else if (u
.invoke
.t_list
) {
10890 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10891 for (size_t i
= 0; i
< nof_pars
; i
++) {
10892 if (i
> 0) ret_val
+= ", ";
10893 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10899 string
ret_val("refers(");
10900 ret_val
+= u
.refered
->get_dispname();
10904 return string("<unsupported valuetype>");
10905 } // switch valuetype
10908 string
Value::create_stringRepr_unary(const char *operator_str
)
10910 string
ret_val(operator_str
);
10912 ret_val
+= u
.expr
.v1
->get_stringRepr();
10917 string
Value::create_stringRepr_infix(const char *operator_str
)
10919 string
ret_val('(');
10920 ret_val
+= u
.expr
.v1
->get_stringRepr();
10922 ret_val
+= operator_str
;
10924 ret_val
+= u
.expr
.v2
->get_stringRepr();
10929 string
Value::create_stringRepr_predef1(const char *function_name
)
10931 string
ret_val(function_name
);
10933 if (u
.expr
.v_optype
== OPTYPE_ENCODE
|| u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
) { // ti1, not v1
10934 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10936 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10941 string
Value::create_stringRepr_predef2(const char *function_name
)
10943 string
ret_val(function_name
);
10945 ret_val
+= u
.expr
.v1
->get_stringRepr();
10947 ret_val
+= u
.expr
.v2
->get_stringRepr();
10952 bool Value::operator==(Value
& val
)
10954 Value
*left
= get_value_refd_last();
10955 Type
*left_governor
= left
->get_my_governor();
10956 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10957 Value
*right
= val
.get_value_refd_last();
10958 Type
*right_governor
= right
->get_my_governor();
10959 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10960 if (left_governor
&& right_governor
10961 && !left_governor
->is_compatible(right_governor
, NULL
)
10962 && !right_governor
->is_compatible(left_governor
, NULL
))
10963 FATAL_ERROR("Value::operator==");
10965 // Not-A-Value is not equal to anything (NaN analogy:)
10966 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10969 switch (left
->valuetype
) {
10972 case V_DEFAULT_NULL
:
10975 return left
->valuetype
== right
->valuetype
;
10977 return right
->valuetype
== V_BOOL
&&
10978 left
->get_val_bool() == right
->get_val_bool();
10980 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10981 == *right
->get_val_Int();
10983 return right
->valuetype
== V_REAL
&&
10984 left
->get_val_Real() == right
->get_val_Real();
10986 switch (right
->valuetype
) {
10988 return left
->get_val_str() == right
->get_val_str();
10990 return right
->get_val_ustr() == left
->get_val_str();
10992 return right
->get_val_iso2022str() == left
->get_val_str();
10999 return left
->valuetype
== right
->valuetype
&&
11000 left
->get_val_str() == right
->get_val_str();
11002 switch (right
->valuetype
) {
11004 return left
->get_val_ustr() == right
->get_val_str();
11006 return left
->get_val_ustr() == right
->get_val_ustr();
11008 return left
->get_val_ustr() == right
->get_val_iso2022str();
11013 switch (right
->valuetype
) {
11015 return left
->get_val_iso2022str() == right
->get_val_str();
11017 // The appropriate operator==() is missing. The operands are swapped,
11018 // but it shouldn't be a problem.
11019 return right
->get_val_ustr() == left
->get_val_iso2022str();
11021 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
11026 return right
->valuetype
== V_ENUM
&&
11027 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
11030 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
11031 vector
<string
> act
, other
;
11032 get_oid_comps(act
);
11033 val
.get_oid_comps(other
);
11034 size_t act_size
= act
.size(), other_size
= other
.size();
11036 if (act_size
== other_size
) {
11038 for (size_t i
= 0; i
< act_size
; i
++)
11039 if (*act
[i
] != *other
[i
]) {
11043 } else ret_val
= false;
11044 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
11046 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
11049 } else return false;
11051 return right
->valuetype
== V_CHOICE
&&
11052 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
11053 *(left
->get_alt_value()) == *(right
->get_alt_value());
11056 if (!left_governor
) FATAL_ERROR("Value::operator==");
11057 if (left
->valuetype
!= right
->valuetype
) return false;
11058 size_t nof_comps
= left_governor
->get_nof_comps();
11059 for (size_t i
= 0; i
< nof_comps
; i
++) {
11060 Value
*lval
= NULL
, *rval
= NULL
;
11061 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
11062 const Identifier
& field_name
= cfl
->get_name();
11063 if (left
->has_comp_withName(field_name
)) {
11064 lval
= left
->get_comp_value_byName(field_name
);
11065 if (right
->has_comp_withName(field_name
)) {
11066 rval
= right
->get_comp_value_byName(field_name
);
11067 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
11068 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
11070 else if (!(*lval
== *rval
))
11073 if (cfl
->has_default()) {
11074 if (!(*lval
== *cfl
->get_defval()))
11077 if (lval
->valuetype
!= V_OMIT
)
11082 if(right
->has_comp_withName(field_name
)) {
11083 rval
= right
->get_comp_value_byName(field_name
);
11084 if(cfl
->has_default()) {
11085 if(rval
->valuetype
==V_OMIT
) return false;
11087 lval
= cfl
->get_defval();
11088 if (!(*lval
==*rval
)) return false;
11097 if (left
->valuetype
!= right
->valuetype
) return false;
11098 size_t ncomps
= get_nof_comps();
11099 if (ncomps
!= right
->get_nof_comps()) return false;
11101 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
11102 bool found
= false;
11103 map
<IndexedValue
*, void> uncovered
;
11104 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
11105 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
11107 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
11109 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
11110 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
11111 *(right
->get_comp_byIndex(i
)) &&
11112 *(uncovered
.get_nth_key(j
)->get_index()) ==
11113 *(right
->get_index_byIndex(i
))) {
11115 uncovered
.erase(uncovered
.get_nth_key(j
));
11123 } else if (left
->is_indexed() || right
->is_indexed()) {
11124 Value
* indexed_one
= 0;
11125 Value
* not_indexed_one
= 0;
11127 if(left
->is_indexed()) { // left is indexed, right is not
11128 indexed_one
= left
;
11129 not_indexed_one
= right
;
11130 } else { // right indexed, left is not
11131 indexed_one
= right
;
11132 not_indexed_one
= left
;
11135 for(size_t i
= 0; i
< ncomps
; ++i
) {
11136 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
11137 if(!(ind
->valuetype
== V_INT
&&
11138 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
11139 *(indexed_one
->get_comp_byIndex(i
))))
11143 } else { // none of them is indexed
11144 for (size_t i
= 0; i
< ncomps
; i
++) {
11145 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
11152 if (right
->valuetype
!= V_SETOF
) return false;
11153 size_t ncomps
= get_nof_comps();
11154 if (ncomps
!= right
->get_nof_comps()) return false;
11155 if (ncomps
== 0) return true;
11156 map
<size_t, void> uncovered
;
11157 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
11158 for (size_t i
= 0; i
< ncomps
; i
++) {
11159 Value
*left_item
= left
->get_comp_byIndex(i
);
11160 bool pair_found
= false;
11161 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
11162 size_t right_index
= uncovered
.get_nth_key(j
);
11163 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
11164 uncovered
.erase(right_index
);
11176 return right
->valuetype
== V_VERDICT
&&
11177 left
->get_val_verdict() == right
->get_val_verdict();
11181 return left
->valuetype
== right
->valuetype
&&
11182 left
->get_refd_assignment() == right
->get_refd_assignment();
11184 FATAL_ERROR("Value::operator==");
11189 bool Value::operator<(Value
& val
)
11191 Value
*left
= get_value_refd_last();
11192 Type
*left_governor
= left
->get_my_governor();
11193 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
11194 Value
*right
= val
.get_value_refd_last();
11195 Type
*right_governor
= right
->get_my_governor();
11196 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
11197 if (left
->get_valuetype() != right
->get_valuetype())
11198 FATAL_ERROR("Value::operator<");
11201 return *left
->get_val_Int() < *right
->get_val_Int();
11203 return (left
->get_val_Real() < right
->get_val_Real());
11205 if(!left_governor
|| !right_governor
)
11206 FATAL_ERROR("Value::operator<");
11207 if(left_governor
!=right_governor
)
11208 FATAL_ERROR("Value::operator<");
11209 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
11210 right_governor
->get_enum_val_byId(*right
->get_val_id()));
11212 FATAL_ERROR("Value::operator<");
11217 bool Value::is_string_type(Type::expected_value_t exp_val
)
11219 switch (get_expr_returntype(exp_val
)) {
11231 void Value::generate_code_expr(expression_struct
*expr
)
11233 if (has_single_expr()) {
11234 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
11236 switch (valuetype
) {
11238 generate_code_expr_expr(expr
);
11246 const string
& tmp_id
= get_temporary_id();
11247 const char *tmp_id_str
= tmp_id
.c_str();
11248 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11249 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
11250 set_genname_recursive(tmp_id
);
11251 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11252 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11255 const string
& tmp_id
= get_temporary_id();
11256 const char *tmp_id_str
= tmp_id
.c_str();
11257 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
11259 set_genname_recursive(tmp_id
);
11260 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11261 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11264 if (!get_needs_conversion()) {
11265 u
.ref
.ref
->generate_code_const_ref(expr
);
11267 Type
*my_gov
= get_expr_governor_last();
11268 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
11269 ->get_field_type(u
.ref
.ref
->get_subrefs(),
11270 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
11271 // Make sure that nothing goes wrong.
11272 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
11273 FATAL_ERROR("Value::generate_code_expr()");
11274 expression_struct expr_tmp
;
11275 Code::init_expr(&expr_tmp
);
11276 const string
& tmp_id1
= get_temporary_id();
11277 const char *tmp_id_str1
= tmp_id1
.c_str();
11278 const string
& tmp_id2
= get_temporary_id();
11279 const char *tmp_id_str2
= tmp_id2
.c_str();
11280 expr
->preamble
= mputprintf(expr
->preamble
,
11281 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
11283 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11284 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
11285 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11286 expr
->preamble
= mputprintf(expr
->preamble
,
11288 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11289 "and `%s' are not compatible at run-time\");\n",
11290 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11291 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
11292 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
11293 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
11294 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11298 generate_code_expr_invoke(expr
);
11301 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
11306 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
11308 generate_code_expr(expr
);
11309 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11310 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11313 bool Value::can_use_increment(Reference
*ref
) const
11315 if (valuetype
!= V_EXPR
) {
11318 switch (u
.expr
.v_optype
) {
11320 case OPTYPE_SUBTRACT
:
11325 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11326 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11327 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11328 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11329 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11330 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11336 char *Value::generate_code_init(char *str
, const char *name
)
11338 if (get_code_generated()) return str
;
11340 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11342 switch (valuetype
) {
11356 case V_DEFAULT_NULL
:
11361 // These values have a single string equivalent.
11362 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11365 if (u
.val_Int
->is_native_fit())
11366 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11368 // It's always an INTEGER.
11369 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11370 "}\n", get_single_expr().c_str(), name
);
11374 expression_struct expr
;
11375 Code::init_expr(&expr
);
11376 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11377 generate_code_expr(&expr
);
11378 str
= Code::merge_free_expr(str
, &expr
);
11381 str
= generate_code_init_choice(str
, name
);
11385 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11386 else str
= generate_code_init_indexed(str
, name
);
11389 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11390 else str
= generate_code_init_indexed(str
, name
);
11394 str
= generate_code_init_se(str
, name
);
11397 str
= generate_code_init_refd(str
, name
);
11401 case MACRO_TESTCASEID
:
11402 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11405 // all others must already be evaluated away
11406 FATAL_ERROR("Value::generate_code_init()");
11410 // unbound value, don't generate anything
11413 FATAL_ERROR("Value::generate_code_init()");
11416 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11418 set_code_generated();
11422 char *Value::rearrange_init_code(char *str
, Common::Module
* usage_mod
)
11424 switch (valuetype
) {
11426 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11428 str
= parlist
->rearrange_init_code(str
, usage_mod
);
11432 str
= u
.invoke
.v
->rearrange_init_code(str
, usage_mod
);
11433 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, usage_mod
);
11436 switch (u
.expr
.v_optype
) {
11437 case OPTYPE_UNARYPLUS
:
11438 case OPTYPE_UNARYMINUS
:
11441 case OPTYPE_BIT2HEX
:
11442 case OPTYPE_BIT2INT
:
11443 case OPTYPE_BIT2OCT
:
11444 case OPTYPE_BIT2STR
:
11445 case OPTYPE_CHAR2INT
:
11446 case OPTYPE_CHAR2OCT
:
11447 case OPTYPE_FLOAT2INT
:
11448 case OPTYPE_FLOAT2STR
:
11449 case OPTYPE_HEX2BIT
:
11450 case OPTYPE_HEX2INT
:
11451 case OPTYPE_HEX2OCT
:
11452 case OPTYPE_HEX2STR
:
11453 case OPTYPE_INT2CHAR
:
11454 case OPTYPE_INT2FLOAT
:
11455 case OPTYPE_INT2STR
:
11456 case OPTYPE_INT2UNICHAR
:
11457 case OPTYPE_OCT2BIT
:
11458 case OPTYPE_OCT2CHAR
:
11459 case OPTYPE_OCT2HEX
:
11460 case OPTYPE_OCT2INT
:
11461 case OPTYPE_OCT2STR
:
11462 case OPTYPE_STR2BIT
:
11463 case OPTYPE_STR2FLOAT
:
11464 case OPTYPE_STR2HEX
:
11465 case OPTYPE_STR2INT
:
11466 case OPTYPE_STR2OCT
:
11467 case OPTYPE_UNICHAR2INT
:
11468 case OPTYPE_UNICHAR2CHAR
:
11469 case OPTYPE_ENUM2INT
:
11470 case OPTYPE_ISCHOSEN_V
:
11471 case OPTYPE_GET_STRINGENCODING
:
11472 case OPTYPE_REMOVE_BOM
:
11473 case OPTYPE_DECODE_BASE64
:
11474 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11476 case OPTYPE_DECODE
: {
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
);
11486 case OPTYPE_SUBTRACT
:
11487 case OPTYPE_MULTIPLY
:
11488 case OPTYPE_DIVIDE
:
11491 case OPTYPE_CONCAT
:
11508 case OPTYPE_INT2BIT
:
11509 case OPTYPE_INT2HEX
:
11510 case OPTYPE_INT2OCT
:
11511 //case OPTYPE_DECODE:
11512 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11513 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11515 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11516 case OPTYPE_OCT2UNICHAR
:
11517 case OPTYPE_ENCODE_BASE64
:
11518 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11519 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11521 case OPTYPE_SUBSTR
:
11522 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11523 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11524 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11526 case OPTYPE_REGEXP
:
11527 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11528 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11529 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11531 case OPTYPE_DECOMP
:
11532 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11533 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11534 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11536 case OPTYPE_REPLACE
:
11537 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11538 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11539 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11540 str
= u
.expr
.ti4
->rearrange_init_code(str
, usage_mod
);
11542 case OPTYPE_LENGTHOF
:
11543 case OPTYPE_SIZEOF
:
11544 case OPTYPE_VALUEOF
:
11545 case OPTYPE_ENCODE
:
11546 case OPTYPE_ISPRESENT
:
11547 case OPTYPE_TTCN2STRING
:
11548 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11550 case OPTYPE_ENCVALUE_UNICHAR
:
11551 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11552 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11554 case OPTYPE_DECVALUE_UNICHAR
: {
11555 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11556 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11557 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11559 parlist
= u
.expr
.r2
->get_parlist();
11560 ass
= u
.expr
.r2
->get_refd_assignment();
11561 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11562 if (u
.expr
.v3
) str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11564 case OPTYPE_ISCHOSEN_T
:
11565 str
= u
.expr
.t1
->rearrange_init_code(str
, usage_mod
);
11568 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11569 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11572 // other kinds of expressions cannot appear within templates
11582 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11583 size_t& blockcount
)
11585 char *s2
= memptystr();
11586 char *s1
= generate_code_tmp(NULL
, s2
);
11588 if (blockcount
== 0) {
11589 str
= mputstr(str
, "{\n");
11592 str
= mputstr(str
, s2
);
11595 str
=mputstr(str
, prefix
);
11596 str
=mputstr(str
, s1
);
11601 char *Value::generate_code_tmp(char *str
, char*& init
)
11603 expression_struct expr
;
11604 Code::init_expr(&expr
);
11605 generate_code_expr_mandatory(&expr
);
11606 if (expr
.preamble
|| expr
.postamble
) {
11607 if (valuetype
== V_EXPR
&&
11608 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11609 // a temporary variable is already introduced
11610 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11611 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11612 str
= mputstr(str
, expr
.expr
);
11614 const string
& tmp_id
= get_temporary_id();
11615 const char *tmp_id_str
= tmp_id
.c_str();
11616 init
= mputprintf(init
, "%s %s;\n"
11618 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11619 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11621 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11622 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11623 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11624 init
= mputstr(init
, "}\n");
11625 str
= mputstr(str
, tmp_id_str
);
11627 } else str
= mputstr(str
, expr
.expr
);
11628 Code::free_expr(&expr
);
11632 void Value::generate_code_log(expression_struct
*expr
)
11634 if (explicit_cast_needed()) {
11635 char *expr_backup
= expr
->expr
;
11637 generate_code_expr(expr
);
11638 const string
& tmp_id
= get_temporary_id();
11639 const char *tmp_id_str
= tmp_id
.c_str();
11640 // We have to create a temporary object, because the parser of GCC
11641 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11642 // constructor call that is, this does not work: type(...).log(); but
11643 // this works: type tmp(...); tmp.log();.
11644 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11645 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11648 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11650 generate_code_expr(expr
);
11652 expr
->expr
= mputstr(expr
->expr
, ".log()");
11655 void Value::generate_code_log_match(expression_struct
*expr
)
11657 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11658 FATAL_ERROR("Value::generate_code_log_match()");
11659 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11660 // compliance the whole code-generation should be checked. Standalone
11661 // constructs like: "A(a[0].f());" should be avoided. The current
11662 // solution for HK38721 uses an additional assignment to overcome the
11663 // issue. The generated code will be slower, but it's needed for old GCC
11664 // versions in specific circumstances.
11665 if (u
.expr
.t2
->needs_temp_ref()) {
11666 char *expr_backup
= expr
->expr
;
11668 u
.expr
.t2
->generate_code(expr
);
11669 const string
& tmp_id
= get_temporary_id();
11670 const char *tmp_id_str
= tmp_id
.c_str();
11671 expr
->preamble
= mputprintf(expr
->preamble
,
11672 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11673 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11675 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11677 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11678 // some reason "(A(NS::B)).a(C);" compiles fine.
11679 expr
->expr
= mputc(expr
->expr
, '(');
11680 u
.expr
.t2
->generate_code(expr
);
11681 expr
->expr
= mputc(expr
->expr
, ')');
11683 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11684 u
.expr
.v1
->generate_code_expr(expr
);
11685 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11688 void Value::generate_code_expr_expr(expression_struct
*expr
)
11690 switch (u
.expr
.v_optype
) {
11692 generate_code_expr_rnd(expr
, 0);
11694 case OPTYPE_UNARYPLUS
:
11695 // same as without the '+' operator
11696 u
.expr
.v1
->generate_code_expr(expr
);
11698 case OPTYPE_UNARYMINUS
:
11699 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11702 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11705 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11707 case OPTYPE_BIT2HEX
:
11708 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11710 case OPTYPE_BIT2INT
:
11711 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11713 case OPTYPE_BIT2OCT
:
11714 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11716 case OPTYPE_BIT2STR
:
11717 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11719 case OPTYPE_CHAR2INT
:
11720 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11722 case OPTYPE_CHAR2OCT
:
11723 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11725 case OPTYPE_FLOAT2INT
:
11726 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11728 case OPTYPE_FLOAT2STR
:
11729 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11731 case OPTYPE_HEX2BIT
:
11732 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11734 case OPTYPE_HEX2INT
:
11735 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11737 case OPTYPE_HEX2OCT
:
11738 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11740 case OPTYPE_HEX2STR
:
11741 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11743 case OPTYPE_INT2CHAR
:
11744 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11746 case OPTYPE_INT2FLOAT
:
11747 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11749 case OPTYPE_INT2STR
:
11750 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11752 case OPTYPE_INT2UNICHAR
:
11753 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11755 case OPTYPE_OCT2BIT
:
11756 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11758 case OPTYPE_OCT2CHAR
:
11759 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11761 case OPTYPE_GET_STRINGENCODING
:
11762 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11764 case OPTYPE_REMOVE_BOM
:
11765 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11767 case OPTYPE_ENCODE_BASE64
:
11769 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11771 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11773 case OPTYPE_DECODE_BASE64
:
11774 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11776 case OPTYPE_OCT2UNICHAR
:
11778 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11780 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11782 case OPTYPE_UNICHAR2OCT
:
11784 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11786 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11788 case OPTYPE_ENCVALUE_UNICHAR
:
11789 generate_code_expr_encvalue_unichar(expr
);
11791 case OPTYPE_DECVALUE_UNICHAR
:
11792 generate_code_expr_decvalue_unichar(expr
);
11794 case OPTYPE_OCT2HEX
:
11795 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11797 case OPTYPE_OCT2INT
:
11798 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11800 case OPTYPE_OCT2STR
:
11801 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11803 case OPTYPE_STR2BIT
:
11804 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11806 case OPTYPE_STR2FLOAT
:
11807 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11809 case OPTYPE_STR2HEX
:
11810 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11812 case OPTYPE_STR2INT
:
11813 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11815 case OPTYPE_STR2OCT
:
11816 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11818 case OPTYPE_UNICHAR2INT
:
11819 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11821 case OPTYPE_UNICHAR2CHAR
:
11822 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11824 case OPTYPE_ENUM2INT
: {
11825 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11826 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11827 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11828 enum_type
->get_genname_value(my_scope
).c_str());
11829 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11830 expr
->expr
= mputc(expr
->expr
, ')');
11832 case OPTYPE_ENCODE
:
11833 generate_code_expr_encode(expr
);
11835 case OPTYPE_DECODE
:
11836 generate_code_expr_decode(expr
);
11838 case OPTYPE_RNDWITHVAL
:
11839 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11842 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11844 case OPTYPE_SUBTRACT
:
11845 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11847 case OPTYPE_MULTIPLY
:
11848 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11850 case OPTYPE_DIVIDE
:
11851 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11854 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11857 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11859 case OPTYPE_CONCAT
:
11860 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11863 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11866 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11869 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11872 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11875 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11878 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11882 generate_code_expr_and_or(expr
);
11885 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11888 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11891 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11894 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11897 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11900 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11903 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11906 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11908 case OPTYPE_INT2BIT
:
11909 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11911 case OPTYPE_INT2HEX
:
11912 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11914 case OPTYPE_INT2OCT
:
11915 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11917 case OPTYPE_SUBSTR
:
11918 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11919 else generate_code_expr_substr_replace_compat(expr
);
11921 case OPTYPE_REGEXP
:
11922 generate_code_expr_regexp(expr
);
11924 case OPTYPE_DECOMP
:
11925 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11927 case OPTYPE_REPLACE
:
11928 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11929 else generate_code_expr_substr_replace_compat(expr
);
11931 case OPTYPE_ISCHOSEN
: // r1 i2
11932 FATAL_ERROR("Value::generate_code_expr_expr()");
11934 case OPTYPE_ISCHOSEN_V
: // v1 i2
11935 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11936 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11937 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11938 u
.expr
.i2
->get_name().c_str());
11940 case OPTYPE_ISCHOSEN_T
: // t1 i2
11941 u
.expr
.t1
->generate_code_expr(expr
);
11942 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11943 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11944 u
.expr
.i2
->get_name().c_str());
11946 case OPTYPE_ISPRESENT
:
11947 case OPTYPE_ISBOUND
: {
11948 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11949 ->get_templatetype();
11950 if (temp
== Template::SPECIFIC_VALUE
) {
11951 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11952 ->get_specific_value();
11953 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11954 Ttcn::Reference
* reference
=
11955 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11957 reference
->generate_code_ispresentbound(expr
, false,
11958 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11962 } else if (temp
== Template::TEMPLATE_REFD
){
11963 Ttcn::Reference
* reference
=
11964 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11965 ->get_reference());
11967 reference
->generate_code_ispresentbound(expr
, true,
11968 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11974 case OPTYPE_LENGTHOF
: // ti1
11975 // fall through, separated later
11976 case OPTYPE_SIZEOF
: // ti1
11977 // fall through, separated later
11978 case OPTYPE_ISVALUE
: { // ti1
11979 if (u
.expr
.ti1
->is_only_specific_value()) {
11980 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11981 bool cast_needed
= t_val
->explicit_cast_needed(
11982 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11984 // the ambiguous C++ expression is converted to the value class
11985 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11986 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11989 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11990 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11991 t_val
->generate_code_expr(expr
);
11993 t_val
->generate_code_expr_mandatory(expr
);
11996 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11998 else u
.expr
.ti1
->generate_code(expr
);
12000 switch (u
.expr
.v_optype
) {
12001 case OPTYPE_ISBOUND
:
12002 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
12004 case OPTYPE_ISPRESENT
:
12005 expr
->expr
=mputprintf(expr
->expr
, ".is_present()");
12007 case OPTYPE_SIZEOF
:
12008 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
12010 case OPTYPE_LENGTHOF
:
12011 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
12013 case OPTYPE_ISVALUE
:
12014 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
12017 FATAL_ERROR("Value::generate_code_expr_expr()");
12020 case OPTYPE_VALUEOF
: // ti1
12021 u
.expr
.ti1
->generate_code(expr
);
12022 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
12024 case OPTYPE_MATCH
: // v1 t2
12025 u
.expr
.t2
->generate_code(expr
);
12026 expr
->expr
= mputstr(expr
->expr
, ".match(");
12027 u
.expr
.v1
->generate_code_expr(expr
);
12028 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
12030 case OPTYPE_UNDEF_RUNNING
:
12031 // it is resolved during semantic check
12032 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
12034 case OPTYPE_COMP_NULL
: // -
12035 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
12037 case OPTYPE_COMP_MTC
: // -
12038 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
12040 case OPTYPE_COMP_SYSTEM
: // -
12041 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
12043 case OPTYPE_COMP_SELF
: // -
12044 expr
->expr
=mputstr(expr
->expr
, "self");
12046 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
12047 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
12050 case OPTYPE_COMP_RUNNING
: // v1
12051 u
.expr
.v1
->generate_code_expr(expr
);
12052 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
12053 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
12054 expr
->expr
= mputstr(expr
->expr
, ".running()");
12056 case OPTYPE_COMP_RUNNING_ANY
: // -
12057 expr
->expr
=mputstr(expr
->expr
,
12058 "TTCN_Runtime::component_running(ANY_COMPREF)");
12060 case OPTYPE_COMP_RUNNING_ALL
: // -
12061 expr
->expr
=mputstr(expr
->expr
,
12062 "TTCN_Runtime::component_running(ALL_COMPREF)");
12064 case OPTYPE_COMP_ALIVE
: // v1
12065 u
.expr
.v1
->generate_code_expr(expr
);
12066 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
12067 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
12068 expr
->expr
= mputstr(expr
->expr
, ".alive()");
12070 case OPTYPE_COMP_ALIVE_ANY
: // -
12071 expr
->expr
= mputstr(expr
->expr
,
12072 "TTCN_Runtime::component_alive(ANY_COMPREF)");
12074 case OPTYPE_COMP_ALIVE_ALL
: // -
12075 expr
->expr
= mputstr(expr
->expr
,
12076 "TTCN_Runtime::component_alive(ALL_COMPREF)");
12078 case OPTYPE_TMR_READ
: // r1
12079 u
.expr
.r1
->generate_code(expr
);
12080 expr
->expr
= mputstr(expr
->expr
, ".read()");
12082 case OPTYPE_TMR_RUNNING
: // r1
12083 u
.expr
.r1
->generate_code(expr
);
12084 expr
->expr
= mputstr(expr
->expr
, ".running()");
12086 case OPTYPE_TMR_RUNNING_ANY
: // -
12087 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
12089 case OPTYPE_GETVERDICT
: // -
12090 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
12092 case OPTYPE_TESTCASENAME
: // -
12093 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
12095 case OPTYPE_ACTIVATE
: // r1
12096 generate_code_expr_activate(expr
);
12098 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
12099 case OPTYPE_CHECKSTATE_ALL
:
12100 generate_code_expr_checkstate(expr
);
12102 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
12103 generate_code_expr_activate_refd(expr
);
12105 case OPTYPE_EXECUTE
: // r1 [v2]
12106 generate_code_expr_execute(expr
);
12108 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
12109 generate_code_expr_execute_refd(expr
);
12111 case OPTYPE_LOG2STR
:
12112 case OPTYPE_ANY2UNISTR
:
12113 u
.expr
.logargs
->generate_code_expr(expr
);
12115 case OPTYPE_TTCN2STRING
: {
12116 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
12117 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
12118 param_governor
= param_governor
->get_type_refd_last();
12119 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
12120 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
12121 u
.expr
.ti1
->get_Template()->is_Value()) {
12122 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
12125 bool cast_needed
= v
->explicit_cast_needed();
12127 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
12129 v
->generate_code_expr(expr
);
12131 expr
->expr
= mputstr(expr
->expr
, ")");
12135 u
.expr
.ti1
->generate_code(expr
);
12137 expr
->expr
= mputstr(expr
->expr
, ")");
12139 case OPTYPE_PROF_RUNNING
:
12140 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
12143 FATAL_ERROR("Value::generate_code_expr_expr()");
12147 void Value::generate_code_expr_unary(expression_struct
*expr
,
12148 const char *operator_str
, Value
*v1
)
12150 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
12151 v1
->generate_code_expr_mandatory(expr
);
12152 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
12155 void Value::generate_code_expr_infix(expression_struct
*expr
,
12156 const char *operator_str
, Value
*v1
,
12157 Value
*v2
, bool optional_allowed
)
12159 if (!get_needs_conversion()) {
12160 expr
->expr
= mputc(expr
->expr
, '(');
12161 if (optional_allowed
) v1
->generate_code_expr(expr
);
12162 else v1
->generate_code_expr_mandatory(expr
);
12163 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
12164 if (optional_allowed
) v2
->generate_code_expr(expr
);
12165 else v2
->generate_code_expr_mandatory(expr
);
12166 expr
->expr
= mputc(expr
->expr
, ')');
12167 } else { // Temporary variable for the converted value.
12168 const string
& tmp_id1
= get_temporary_id();
12169 const char *tmp_id_str1
= tmp_id1
.c_str();
12170 expression_struct expr_tmp
;
12171 Code::init_expr(&expr_tmp
);
12172 switch (u
.expr
.v_optype
) {
12175 // Always "v1 -> v2".
12176 Type
*t1
= v1
->get_expr_governor_last();
12177 Type
*t2
= v2
->get_expr_governor_last();
12178 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
12179 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12180 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12181 if (expr_tmp
.preamble
)
12182 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12183 expr
->preamble
= mputprintf(expr
->preamble
,
12185 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12186 "and `%s' are not compatible at run-time\");\n",
12187 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
12188 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
12189 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
12190 t2
->get_typename().c_str(), t1
->get_typename().c_str());
12191 Code::free_expr(&expr_tmp
);
12192 if (optional_allowed
) v1
->generate_code_expr(expr
);
12193 else v1
->generate_code_expr_mandatory(expr
);
12194 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
12197 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12198 // functions. The governors of all operands must exist at this point.
12201 case OPTYPE_CONCAT
: {
12202 const string
& tmp_id2
= get_temporary_id();
12203 const char *tmp_id_str2
= tmp_id2
.c_str();
12204 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
12205 Type
*my_gov
= my_governor
->get_type_refd_last();
12206 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
12207 ->get_type_refd_last();
12208 if (!t1_gov
|| my_gov
== t1_gov
)
12209 FATAL_ERROR("Value::generate_code_expr_infix()");
12210 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
12211 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
12212 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
12213 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
12214 else v1
->generate_code_expr_mandatory(&expr_tmp
);
12215 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
12216 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12217 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12218 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
12219 expr
->preamble
= mputprintf(expr
->preamble
,
12221 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12222 "and `%s' are not compatible at run-time\");\n",
12223 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
12224 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
12225 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
12226 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
12227 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
12230 FATAL_ERROR("Value::generate_code_expr_infix()");
12236 void Value::generate_code_expr_and_or(expression_struct
*expr
)
12238 if (u
.expr
.v2
->needs_short_circuit()) {
12239 // introduce a temporary variable to store the result of the operation
12240 const string
& tmp_id
= get_temporary_id();
12241 const char *tmp_id_str
= tmp_id
.c_str();
12242 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
12243 expression_struct expr2
;
12244 // the left operand must be evaluated anyway
12245 Code::init_expr(&expr2
);
12246 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12247 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
12248 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12249 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
12250 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
12251 // evaluate the right operand only when necessary
12252 // in this case the final result will be the right operand
12253 Code::init_expr(&expr2
);
12254 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12255 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
12256 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12257 // the result is now in the temporary variable
12258 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
12260 // use the overloaded operator to get better error messages
12261 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
12262 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
12266 void Value::generate_code_expr_predef1(expression_struct
*expr
,
12267 const char *function_name
,
12270 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12271 v1
->generate_code_expr_mandatory(expr
);
12272 expr
->expr
= mputc(expr
->expr
, ')');
12275 void Value::generate_code_expr_predef2(expression_struct
*expr
,
12276 const char *function_name
,
12277 Value
*v1
, Value
*v2
)
12279 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12280 v1
->generate_code_expr_mandatory(expr
);
12281 expr
->expr
= mputstr(expr
->expr
, ", ");
12282 v2
->generate_code_expr_mandatory(expr
);
12283 expr
->expr
= mputc(expr
->expr
, ')');
12286 void Value::generate_code_expr_predef3(expression_struct
*expr
,
12287 const char *function_name
,
12288 Value
*v1
, Value
*v2
, Value
*v3
)
12290 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12291 v1
->generate_code_expr_mandatory(expr
);
12292 expr
->expr
= mputstr(expr
->expr
, ", ");
12293 v2
->generate_code_expr_mandatory(expr
);
12294 expr
->expr
= mputstr(expr
->expr
, ", ");
12295 v3
->generate_code_expr_mandatory(expr
);
12296 expr
->expr
= mputc(expr
->expr
, ')');
12299 void Value::generate_code_expr_substr(expression_struct
*expr
)
12302 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12303 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12304 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12305 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
12306 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12307 else u
.expr
.ti1
->generate_code(expr
);
12308 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12309 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
12310 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12311 expr
->expr
= mputstr(expr
->expr
, "(int)");
12312 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12313 expr
->expr
= mputstr(expr
->expr
, ", ");
12314 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12315 expr
->expr
= mputstr(expr
->expr
, "(int)");
12316 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12317 expr
->expr
= mputc(expr
->expr
, ')');
12320 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
12322 expression_struct expr_tmp
;
12323 Code::init_expr(&expr_tmp
);
12324 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
12325 ->get_type_refd_last();
12326 if (!t1
|| t1
== my_governor
->get_type_refd_last())
12327 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12328 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
12329 generate_code_expr_substr(&expr_tmp
);
12330 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
12331 generate_code_expr_replace(&expr_tmp
);
12333 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12335 // Two temporaries to store the result of substr() or replace() and to
12336 // store the converted value.
12337 const string
& tmp_id1
= get_temporary_id();
12338 const char *tmp_id_str1
= tmp_id1
.c_str();
12339 const string
& tmp_id2
= get_temporary_id();
12340 const char *tmp_id_str2
= tmp_id2
.c_str();
12341 if (expr_tmp
.preamble
)
12342 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12343 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12344 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12345 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12346 if (expr_tmp
.postamble
)
12347 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12348 Code::free_expr(&expr_tmp
);
12349 expr
->preamble
= mputprintf(expr
->preamble
,
12350 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12351 "`%s' are not compatible at run-time\");\n",
12352 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12353 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12354 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12355 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12358 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12360 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12361 Value
* v2
= u
.expr
.t2
->get_specific_value();
12362 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12363 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12364 else u
.expr
.ti1
->generate_code(expr
);
12365 expr
->expr
= mputstr(expr
->expr
, ", ");
12366 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12367 else u
.expr
.t2
->generate_code(expr
);
12368 expr
->expr
= mputstr(expr
->expr
, ", ");
12369 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12370 expr
->expr
= mputc(expr
->expr
, ')');
12373 void Value::generate_code_expr_replace(expression_struct
*expr
)
12375 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12376 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12378 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12379 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12380 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12381 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12382 else u
.expr
.ti1
->generate_code(expr
);
12383 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12384 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12385 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12386 expr
->expr
= mputstr(expr
->expr
, "(int)");
12387 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12388 expr
->expr
= mputstr(expr
->expr
, ", ");
12389 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12390 expr
->expr
= mputstr(expr
->expr
, "(int)");
12391 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12392 expr
->expr
= mputstr(expr
->expr
, ", ");
12394 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12395 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12396 Value
* v4_last
= v4
->get_value_refd_last();
12397 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12398 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12399 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12401 v4
->generate_code_expr_mandatory(expr
);
12403 else u
.expr
.ti4
->generate_code(expr
);
12404 expr
->expr
= mputc(expr
->expr
, ')');
12407 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12410 if(!v1
) // simple random generation
12411 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12412 else { // random generation with seeding
12413 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12414 v1
->generate_code_expr_mandatory(expr
);
12415 expr
->expr
= mputc(expr
->expr
, ')');
12419 void Value::generate_code_expr_create(expression_struct
*expr
,
12420 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12422 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12423 // first two arguments: component type
12424 Assignment
*t_ass
= type
->get_refd_assignment();
12425 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12426 FATAL_ERROR("Value::generate_code_expr_create()");
12427 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12428 Type::EXPECTED_DYNAMIC_VALUE
);
12429 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12430 comptype
= comptype
->get_type_refd_last();
12431 expr
->expr
= comptype
->get_CompBody()
12432 ->generate_code_comptype_name(expr
->expr
);
12433 expr
->expr
= mputstr(expr
->expr
, ", ");
12434 // third argument: component name
12436 Value
*t_val
= name
->get_value_refd_last();
12437 if (t_val
->valuetype
== V_CSTR
) {
12438 // the argument is foldable to a string literal
12439 size_t str_len
= t_val
->u
.str
.val_str
->size();
12440 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12441 expr
->expr
= mputc(expr
->expr
, '"');
12442 for (size_t i
= 0; i
< str_len
; i
++)
12443 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12444 expr
->expr
= mputc(expr
->expr
, '"');
12445 } else name
->generate_code_expr_mandatory(expr
);
12446 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12447 expr
->expr
= mputstr(expr
->expr
, ", ");
12448 // fourth argument: location
12450 Value
*t_val
= location
->get_value_refd_last();
12451 if (t_val
->valuetype
== V_CSTR
) {
12452 // the argument is foldable to a string literal
12453 size_t str_len
= t_val
->u
.str
.val_str
->size();
12454 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12455 expr
->expr
= mputc(expr
->expr
, '"');
12456 for (size_t i
= 0; i
< str_len
; i
++)
12457 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12458 expr
->expr
= mputc(expr
->expr
, '"');
12459 } else location
->generate_code_expr_mandatory(expr
);
12460 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12461 // fifth argument: alive flag
12462 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12465 void Value::generate_code_expr_activate(expression_struct
*expr
)
12467 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12468 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12469 FATAL_ERROR("Value::generate_code_expr_activate()");
12470 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12471 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12472 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12473 expr
->expr
= mputc(expr
->expr
, ')');
12476 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12478 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12479 if (v_last
->valuetype
== V_ALTSTEP
) {
12480 // the referred altstep is known
12481 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12482 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12484 // the referred altstep is unknown
12485 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12486 expr
->expr
= mputstr(expr
->expr
,".activate(");
12488 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12489 expr
->expr
= mputc(expr
->expr
, ')');
12492 void Value::generate_code_expr_execute(expression_struct
*expr
)
12494 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12495 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12496 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12497 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12498 if (parlist
->get_nof_pars() > 0) {
12499 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12501 expr
->expr
= mputstr(expr
->expr
, ", ");
12504 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12505 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12506 expr
->expr
= mputc(expr
->expr
, ')');
12507 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12510 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12512 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12513 if (v_last
->valuetype
== V_TESTCASE
) {
12514 // the referred testcase is known
12515 Assignment
*testcase
= v_last
->get_refd_fat();
12516 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12517 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12518 u
.expr
.ap_list2
->generate_code_alias(expr
,
12519 testcase
->get_FormalParList(), 0, false);
12521 // the referred testcase is unknown
12522 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12523 expr
->expr
= mputstr(expr
->expr
,".execute(");
12524 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12526 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12527 expr
->expr
= mputstr(expr
->expr
, ", ");
12529 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12530 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12531 expr
->expr
= mputc(expr
->expr
, ')');
12532 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12535 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12537 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12538 if (last_v
->get_valuetype() == V_FUNCTION
) {
12539 // the referred function is known
12540 Assignment
*function
= last_v
->get_refd_fat();
12541 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12542 function
->get_genname_from_scope(my_scope
).c_str());
12543 u
.invoke
.ap_list
->generate_code_alias(expr
,
12544 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12546 // the referred function is unknown
12547 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12548 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12549 Type
* gov_last
= last_v
->get_expr_governor_last();
12550 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12551 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12553 expr
->expr
= mputc(expr
->expr
, ')');
12556 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12559 // if the referenced value points to an optional value field the
12560 // generated code has to be corrected at the end:
12561 // `fieldid()' => `fieldid()()'
12562 Assignment
*ass
= ref
->get_refd_assignment();
12563 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12564 switch (ass
->get_asstype()) {
12565 case Assignment::A_CONST
:
12566 case Assignment::A_EXT_CONST
:
12567 case Assignment::A_MODULEPAR
:
12568 case Assignment::A_VAR
:
12569 case Assignment::A_FUNCTION_RVAL
:
12570 case Assignment::A_EXT_FUNCTION_RVAL
:
12571 case Assignment::A_PAR_VAL_IN
:
12572 case Assignment::A_PAR_VAL_OUT
:
12573 case Assignment::A_PAR_VAL_INOUT
:
12574 // only these are mapped to value objects
12575 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12576 expr
->expr
= mputstr(expr
->expr
, "()");
12583 void Value::generate_code_expr_encode(expression_struct
*expr
)
12587 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12588 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12589 v1
= templ
->get_specific_value();
12590 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12592 expression_struct expr2
;
12593 Code::init_expr(&expr2
);
12595 bool is_templ
= false;
12596 switch (templ
->get_templatetype()) {
12597 case Template::SPECIFIC_VALUE
:
12598 v1
->generate_code_expr_mandatory(&expr2
);
12601 u
.expr
.ti1
->generate_code(&expr2
);
12606 if (!gov_last
->is_coding_by_function()) {
12607 const string
& tmp_id
= get_temporary_id();
12608 const string
& tmp_buf_id
= get_temporary_id();
12609 const string
& tmp_ref_id
= get_temporary_id();
12610 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12612 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12613 tmp_buf_id
.c_str());
12614 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12615 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12616 expr
->preamble
= mputc (expr
->preamble
, '\n');
12618 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12619 gov_last
->get_genname_typedescriptor(
12620 u
.expr
.ti1
->get_Template()->get_my_scope()
12622 tmp_ref_id
.c_str(),
12624 if (is_templ
) // make a value out of the template, if needed
12625 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12626 expr
->preamble
= mputprintf(expr
->preamble
,
12627 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12628 tmp_ref_id
.c_str(),
12629 gov_last
->get_genname_typedescriptor(
12630 u
.expr
.ti1
->get_Template()->get_my_scope()
12632 tmp_buf_id
.c_str(),
12633 gov_last
->get_coding(true).c_str()
12635 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12636 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12637 tmp_buf_id
.c_str(),
12640 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12641 if (expr2
.postamble
)
12642 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12644 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12645 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12646 is_templ
? ".valueof()" : "");
12647 Code::free_expr(&expr2
);
12650 void Value::generate_code_expr_decode(expression_struct
*expr
)
12652 expression_struct expr1
, expr2
;
12653 Code::init_expr(&expr1
);
12654 Code::init_expr(&expr2
);
12655 u
.expr
.r1
->generate_code(&expr1
);
12656 u
.expr
.r2
->generate_code(&expr2
);
12658 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12659 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12660 get_type_refd_last();
12662 if (expr1
.preamble
)
12663 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12664 if (expr2
.preamble
)
12665 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12667 if (!_type
->is_coding_by_function()) {
12668 const string
& tmp_id
= get_temporary_id();
12669 const string
& buffer_id
= get_temporary_id();
12670 const string
& retval_id
= get_temporary_id();
12671 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12672 field_is_optional(u
.expr
.r2
->get_subrefs());
12674 expr
->preamble
= mputprintf(expr
->preamble
,
12675 "TTCN_Buffer %s(bit2oct(%s));\n"
12677 "TTCN_EncDec::set_error_behavior("
12678 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12679 "TTCN_EncDec::clear_error();\n",
12684 expr
->preamble
= mputprintf(expr
->preamble
,
12685 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12687 optional
? "()" : "",
12688 _type
->get_genname_typedescriptor(
12689 u
.expr
.r2
->get_my_scope()
12692 _type
->get_coding(false).c_str()
12694 expr
->preamble
= mputprintf(expr
->preamble
,
12695 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12696 "case TTCN_EncDec::ET_NONE: {\n"
12698 "OCTETSTRING %s;\n"
12699 "%s.get_string(%s);\n"
12700 "%s = oct2bit(%s);\n"
12703 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12704 "case TTCN_EncDec::ET_LEN_ERR:\n"
12710 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12711 "TTCN_EncDec::EB_DEFAULT);\n"
12712 "TTCN_EncDec::clear_error();\n",
12723 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12725 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12726 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12727 if (expr1
.postamble
)
12728 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12729 if (expr2
.postamble
)
12730 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12731 Code::free_expr(&expr1
);
12732 Code::free_expr(&expr2
);
12735 void Value::generate_code_expr_encvalue_unichar(expression_struct
*expr
)
12739 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12740 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12741 v1
= templ
->get_specific_value();
12742 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12744 expression_struct expr2
;
12745 Code::init_expr(&expr2
);
12747 bool is_templ
= false;
12748 switch (templ
->get_templatetype()) {
12749 case Template::SPECIFIC_VALUE
:
12750 v1
->generate_code_expr_mandatory(&expr2
);
12753 u
.expr
.ti1
->generate_code(&expr2
);
12758 if (!gov_last
->is_coding_by_function()) {
12759 const string
& tmp_id
= get_temporary_id();
12760 const string
& tmp_buf_id
= get_temporary_id();
12761 const string
& tmp_ref_id
= get_temporary_id();
12762 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12764 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12765 tmp_buf_id
.c_str());
12766 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12767 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12768 expr
->preamble
= mputc (expr
->preamble
, '\n');
12770 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12771 gov_last
->get_genname_typedescriptor(
12772 u
.expr
.ti1
->get_Template()->get_my_scope()
12774 tmp_ref_id
.c_str(),
12776 if (is_templ
) // make a value out of the template, if needed
12777 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12778 expr
->preamble
= mputprintf(expr
->preamble
,
12779 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12780 tmp_ref_id
.c_str(),
12781 gov_last
->get_genname_typedescriptor(
12782 u
.expr
.ti1
->get_Template()->get_my_scope()
12784 tmp_buf_id
.c_str(),
12785 gov_last
->get_coding(true).c_str()
12787 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12788 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12789 tmp_buf_id
.c_str(),
12792 const char * v2_code
= NULL
;
12794 v2_code
= generate_code_char_coding_check(expr
, u
.expr
.v2
, "encvalue_unichar");
12796 expr
->expr
= mputprintf(expr
->expr
, "oct2unichar(%s", tmp_id
.c_str());
12798 expr
->expr
= mputprintf(expr
->expr
, ", %s", v2_code
);
12800 expr
->expr
= mputprintf(expr
->expr
, ", \"UTF-8\""); //default
12802 expr
->expr
= mputprintf(expr
->expr
, ")");
12803 if (expr2
.postamble
)
12804 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12806 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12807 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12808 is_templ
? ".valueof()" : "");
12809 Code::free_expr(&expr2
);
12812 void Value::generate_code_expr_decvalue_unichar(expression_struct
*expr
)
12814 expression_struct expr1
, expr2
;
12815 Code::init_expr(&expr1
);
12816 Code::init_expr(&expr2
);
12817 u
.expr
.r1
->generate_code(&expr1
);
12818 u
.expr
.r2
->generate_code(&expr2
);
12820 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12821 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12822 get_type_refd_last();
12824 if (expr1
.preamble
)
12825 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12826 if (expr2
.preamble
)
12827 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12829 if (!_type
->is_coding_by_function()) {
12830 const string
& tmp_id
= get_temporary_id();
12831 const string
& buffer_id
= get_temporary_id();
12832 const string
& retval_id
= get_temporary_id();
12833 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12834 field_is_optional(u
.expr
.r2
->get_subrefs());
12836 const char* v3_code
= NULL
;
12838 v3_code
= generate_code_char_coding_check(expr
, u
.expr
.v3
, "decvalue_unichar");
12840 expr
->preamble
= mputprintf(expr
->preamble
,
12841 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12843 "TTCN_EncDec::set_error_behavior("
12844 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12845 "TTCN_EncDec::clear_error();\n",
12848 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12851 expr
->preamble
= mputprintf(expr
->preamble
,
12852 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12854 optional
? "()" : "",
12855 _type
->get_genname_typedescriptor(
12856 u
.expr
.r2
->get_my_scope()
12859 _type
->get_coding(false).c_str()
12861 expr
->preamble
= mputprintf(expr
->preamble
,
12862 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12863 "case TTCN_EncDec::ET_NONE: {\n"
12865 "OCTETSTRING %s;\n"
12866 "%s.get_string(%s);\n"
12867 "%s = oct2unichar(%s, %s);\n"
12870 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12871 "case TTCN_EncDec::ET_LEN_ERR:\n"
12877 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12878 "TTCN_EncDec::EB_DEFAULT);\n"
12879 "TTCN_EncDec::clear_error();\n",
12886 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12891 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12893 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12894 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12895 if (expr1
.postamble
)
12896 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12897 if (expr2
.postamble
)
12898 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12899 Code::free_expr(&expr1
);
12900 Code::free_expr(&expr2
);
12903 void Value::generate_code_expr_checkstate(expression_struct
*expr
)
12906 // It is a port if r1 is not null
12907 u
.expr
.r1
->generate_code_const_ref(expr
);
12908 expr
->expr
= mputstr(expr
->expr
, ".");
12910 // it is an any or all port if r1 is null
12911 if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ANY
) {
12912 expr
->expr
= mputstr(expr
->expr
, "PORT::any_");
12913 } else if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ALL
) {
12914 expr
->expr
= mputstr(expr
->expr
, "PORT::all_");
12916 FATAL_ERROR("Value::generate_code_expr_checkstate()");
12919 expr
->expr
= mputstr(expr
->expr
, "check_port_state(");
12920 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12921 expr
->expr
= mputstr(expr
->expr
, ")");
12924 char* Value::generate_code_char_coding_check(expression_struct
*expr
, Value
*v
, const char *name
)
12926 expression_struct expr2
;
12927 Code::init_expr(&expr2
);
12928 v
->generate_code_expr_mandatory(&expr2
);
12929 expr
->preamble
= mputprintf(expr
->preamble
,
12930 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12931 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12932 " \"UTF-32BE\" != %s) {\n"
12933 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12934 "}\n", //todo errorbehaviour?
12947 char *Value::generate_code_init_choice(char *str
, const char *name
)
12949 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12950 // Safe as long as get_name() returns a const string&, not a temporary.
12951 const char *alt_prefix
=
12952 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12954 if (u
.choice
.alt_value
->needs_temp_ref()) {
12955 const string
& tmp_id
= get_temporary_id();
12956 const char *tmp_id_str
= tmp_id
.c_str();
12957 str
= mputprintf(str
, "{\n"
12958 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12959 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12960 alt_prefix
, alt_name
);
12961 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12962 str
= mputstr(str
, "}\n");
12964 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12965 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12966 Free(embedded_name
);
12971 char *Value::generate_code_init_seof(char *str
, const char *name
)
12973 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12975 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12976 const string
& embedded_type
=
12977 my_governor
->get_ofType()->get_genname_value(my_scope
);
12978 const char *embedded_type_str
= embedded_type
.c_str();
12979 for (size_t i
= 0; i
< nof_vs
; i
++) {
12980 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12982 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12983 else if (comp_v
->needs_temp_ref()) {
12984 const string
& tmp_id
= get_temporary_id();
12985 const char *tmp_id_str
= tmp_id
.c_str();
12986 str
= mputprintf(str
, "{\n"
12987 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12988 (unsigned long) i
);
12989 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12990 str
= mputstr(str
, "}\n");
12992 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12993 str
= comp_v
->generate_code_init(str
, embedded_name
);
12994 Free(embedded_name
);
12998 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
13003 char *Value::generate_code_init_indexed(char *str
, const char *name
)
13005 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
13007 // Previous values can be truncated. The concept is similar to
13009 Type
*t_last
= my_governor
->get_type_refd_last();
13010 const string
& oftype_name
=
13011 t_last
->get_ofType()->get_genname_value(my_scope
);
13012 const char *oftype_name_str
= oftype_name
.c_str();
13013 for (size_t i
= 0; i
< nof_ivs
; i
++) {
13014 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
13015 const string
& tmp_id_1
= get_temporary_id();
13016 str
= mputstr(str
, "{\n");
13017 Value
*index
= iv
->get_index();
13018 if (index
->get_valuetype() != V_INT
) {
13019 const string
& tmp_id_2
= get_temporary_id();
13020 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
13021 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
13022 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
13023 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
13025 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
13026 tmp_id_1
.c_str(), name
,
13027 (index
->get_val_Int()->t_str()).c_str());
13029 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
13030 str
= mputstr(str
, "}\n");
13032 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
13036 char *Value::generate_code_init_array(char *str
, const char *name
)
13038 size_t nof_vs
= u
.val_vs
->get_nof_vs();
13039 Type
*t_last
= my_governor
->get_type_refd_last();
13040 Int index_offset
= t_last
->get_dimension()->get_offset();
13041 const string
& embedded_type
=
13042 t_last
->get_ofType()->get_genname_value(my_scope
);
13043 const char *embedded_type_str
= embedded_type
.c_str();
13044 for (size_t i
= 0; i
< nof_vs
; i
++) {
13045 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
13046 if (comp_v
->valuetype
== V_NOTUSED
) continue;
13047 else if (comp_v
->needs_temp_ref()) {
13048 const string
& tmp_id
= get_temporary_id();
13049 const char *tmp_id_str
= tmp_id
.c_str();
13050 str
= mputprintf(str
, "{\n"
13051 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
13052 Int2string(index_offset
+ i
).c_str());
13053 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
13054 str
= mputstr(str
, "}\n");
13056 char *embedded_name
= mprintf("%s[%s]", name
,
13057 Int2string(index_offset
+ i
).c_str());
13058 str
= comp_v
->generate_code_init(str
, embedded_name
);
13059 Free(embedded_name
);
13065 char *Value::generate_code_init_se(char *str
, const char *name
)
13067 Type
*type
= my_governor
->get_type_refd_last();
13068 size_t nof_comps
= type
->get_nof_comps();
13069 if (nof_comps
> 0) {
13070 for (size_t i
= 0; i
< nof_comps
; i
++) {
13071 CompField
*cf
= type
->get_comp_byIndex(i
);
13072 const Identifier
& field_id
= cf
->get_name();
13073 const char *field_name
= field_id
.get_name().c_str();
13075 if (u
.val_nvs
->has_nv_withName(field_id
)) {
13076 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
13077 if (field_v
->valuetype
== V_NOTUSED
) continue;
13078 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
13079 } else if (is_asn1()) {
13080 if (cf
->has_default()) {
13081 // handle like a referenced value
13082 Value
*defval
= cf
->get_defval();
13083 if (needs_init_precede(defval
)) {
13084 str
= defval
->generate_code_init(str
,
13085 defval
->get_lhs_name().c_str());
13087 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
13088 defval
->get_genname_own(my_scope
).c_str());
13091 if (!cf
->get_is_optional())
13092 FATAL_ERROR("Value::generate_code_init()");
13099 // the value is not omit
13100 if (field_v
->needs_temp_ref()) {
13101 const string
& tmp_id
= get_temporary_id();
13102 const char *tmp_id_str
= tmp_id
.c_str();
13103 str
= mputprintf(str
, "{\n"
13104 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
13105 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
13107 str
= field_v
->generate_code_init(str
, tmp_id_str
);
13108 str
= mputstr(str
, "}\n");
13110 char *embedded_name
= mprintf("%s.%s()", name
,
13112 if (cf
->get_is_optional() && field_v
->is_compound())
13113 embedded_name
= mputstr(embedded_name
, "()");
13114 str
= field_v
->generate_code_init(str
, embedded_name
);
13115 Free(embedded_name
);
13118 // the value is omit
13119 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
13124 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
13129 char *Value::generate_code_init_refd(char *str
, const char *name
)
13131 Value
*v
= get_value_refd_last();
13133 // the referred value is not available at compile time
13134 // the code generation is based on the reference
13135 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
13136 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
13138 expression_struct expr
;
13139 Code::init_expr(&expr
);
13140 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
13141 u
.ref
.ref
->generate_code_const_ref(&expr
);
13142 str
= Code::merge_free_expr(str
, &expr
);
13145 // the referred value is available at compile time
13146 // the code generation is based on the referred value
13147 if (v
->has_single_expr() &&
13148 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
13149 // simple substitution for in-line values within the same module
13150 str
= mputprintf(str
, "%s = %s;\n", name
,
13151 v
->get_single_expr().c_str());
13153 // use a simple reference to reduce code size
13154 if (needs_init_precede(v
)) {
13155 // the referred value must be initialized first
13156 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
13157 // temporary id should be introduced for the lhs
13158 const string
& tmp_id
= get_temporary_id();
13159 const char *tmp_id_str
= tmp_id
.c_str();
13160 str
= mputprintf(str
, "{\n"
13162 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13163 tmp_id_str
, v
->get_lhs_name().c_str());
13164 str
= v
->generate_code_init(str
, tmp_id_str
);
13165 str
= mputstr(str
, "}\n");
13167 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
13170 str
= mputprintf(str
, "%s = %s;\n", name
,
13171 v
->get_genname_own(my_scope
).c_str());
13177 void Value::generate_json_value(JSON_Tokenizer
& json
,
13178 bool allow_special_float
, /* = true */
13179 bool union_value_list
, /* = false */
13180 Ttcn::JsonOmitCombination
* omit_combo
/* = NULL */)
13182 switch (valuetype
) {
13184 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
13187 Real r
= get_val_Real();
13188 if (r
== REAL_INFINITY
) {
13189 if (allow_special_float
) {
13190 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
13193 else if (r
== -REAL_INFINITY
) {
13194 if (allow_special_float
) {
13195 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
13199 if (allow_special_float
) {
13200 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
13204 // true if decimal representation possible (use %f format)
13205 bool decimal_repr
= (r
== 0.0)
13206 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
13207 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
13208 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
13209 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
13214 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
13220 char* str
= convert_to_json_string(get_val_str().c_str());
13221 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13225 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13226 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13231 json
.put_next_token(JSON_TOKEN_STRING
,
13232 (string('\"') + create_stringRepr() + string('\"')).c_str());
13236 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
13237 if (!u
.val_vs
->is_indexed()) {
13238 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
13239 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
, allow_special_float
,
13240 union_value_list
, omit_combo
);
13244 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
13245 // look for the entry with index equal to i
13246 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
13247 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
13248 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
,
13249 allow_special_float
, union_value_list
, omit_combo
);
13255 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
13259 // omitted fields have 2 possible JSON values (the field is absent, or it's
13260 // present with value 'null'), each combination of omitted values must be
13262 if (omit_combo
== NULL
) {
13263 FATAL_ERROR("Value::generate_json_value - no combo");
13265 size_t len
= get_nof_comps();
13266 // generate the JSON object from the present combination
13267 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13268 for (size_t i
= 0; i
< len
; ++i
) {
13269 Ttcn::JsonOmitCombination::omit_state_t state
= omit_combo
->get_state(this, i
);
13270 if (state
== Ttcn::JsonOmitCombination::OMITTED_ABSENT
) {
13271 // the field is absent, don't insert anything
13274 // use the field's alias, if it has one
13275 const char* alias
= NULL
;
13276 if (my_governor
!= NULL
) {
13277 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13278 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
13279 if (field_attrib
!= NULL
) {
13280 alias
= field_attrib
->alias
;
13283 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13284 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
13285 if (state
== Ttcn::JsonOmitCombination::OMITTED_NULL
) {
13286 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
13289 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
,
13290 allow_special_float
, union_value_list
, omit_combo
);
13293 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13296 bool as_value
= !union_value_list
&& my_governor
!= NULL
&&
13297 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
13298 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
13300 // no 'as value' coding instruction, insert an object with one field
13301 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13302 // use the field's alias, if it has one
13303 const char* alias
= NULL
;
13304 if (my_governor
!= NULL
) {
13305 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13306 get_alt_name())->get_type()->get_json_attributes();
13307 if (field_attrib
!= NULL
) {
13308 alias
= field_attrib
->alias
;
13311 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13312 get_alt_name().get_ttcnname().c_str());
13314 get_alt_value()->generate_json_value(json
, allow_special_float
,
13315 union_value_list
, omit_combo
);
13317 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13321 Value
* v
= get_value_refd_last();
13323 v
->generate_json_value(json
, allow_special_float
, union_value_list
, omit_combo
);
13328 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
13332 bool Value::explicit_cast_needed(bool forIsValue
)
13334 Value
*v_last
= get_value_refd_last();
13335 if (v_last
!= this) {
13336 // this is a foldable referenced value
13337 // if the reference points to an imported or compound value the code
13338 // generation will be based on the reference so cast is not needed
13339 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
13340 || !v_last
->has_single_expr()) return false;
13341 } else if (v_last
->valuetype
== V_REFD
) {
13342 // this is an unfoldable reference (v_last==this)
13343 // explicit cast is needed only for string element references
13344 if (forIsValue
) return false;
13345 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
13346 return t_subrefs
&& t_subrefs
->refers_to_string_element();
13348 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
13349 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
13350 switch (t_governor
->get_typetype()) {
13354 case Type::T_INT_A
:
13356 case Type::T_ENUM_A
:
13357 case Type::T_ENUM_T
:
13358 case Type::T_VERDICT
:
13359 case Type::T_COMPONENT
:
13360 // these are mapped to built-in C/C++ types
13362 case Type::T_SEQ_A
:
13363 case Type::T_SEQ_T
:
13364 case Type::T_SET_A
:
13365 case Type::T_SET_T
:
13366 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13367 return t_governor
->get_nof_comps() == 0;
13368 case Type::T_SEQOF
:
13369 case Type::T_SETOF
:
13370 // the C++ equivalent of value {} is ambiguous
13373 case Type::T_FUNCTION
:
13374 case Type::T_ALTSTEP
:
13375 case Type::T_TESTCASE
:
13382 bool Value::has_single_expr()
13384 if (get_needs_conversion()) return false;
13385 switch (valuetype
) {
13387 return has_single_expr_expr();
13390 // a union or array value cannot be represented as an in-line expression
13394 // only an empty record/set of value can be represented as an in-line
13396 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
13397 else return u
.val_vs
->get_nof_ivs() == 0;
13400 // only a value for an empty record/set type can be represented as an
13401 // in-line expression
13402 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
13403 Type
*type
= my_governor
->get_type_refd_last();
13404 return type
->get_nof_comps() == 0; }
13406 Value
*v_last
= get_value_refd_last();
13407 // If the above call hit an error and set_valuetype(V_ERROR),
13408 // then u.ref.ref has been freed. Avoid the segfault.
13409 if (valuetype
== V_ERROR
)
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()) return true;
13414 else return u
.ref
.ref
->has_single_expr(); }
13416 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
13420 case V_UNDEF_LOWERID
:
13421 case V_UNDEF_BLOCK
:
13423 // these values cannot occur during code generation
13424 FATAL_ERROR("Value::has_single_expr()");
13426 return u
.val_Int
->is_native_fit();
13428 // should only happen when generating code for an unbound record/set value
13431 // other value types (literal values) do not need temporary reference
13436 string
Value::get_single_expr()
13438 switch (valuetype
) {
13440 return string("ASN_NULL_VALUE");
13442 return string(u
.val_bool
? "TRUE" : "FALSE");
13444 if (u
.val_Int
->is_native_fit()) { // Be sure.
13445 return u
.val_Int
->t_str();
13447 // get_single_expr may be called only if has_single_expr() is true.
13448 // The only exception is V_INT, where get_single_expr may be called
13449 // even if is_native_fit (which is used to implement has_single_expr)
13451 string
ret_val('"');
13452 ret_val
+= u
.val_Int
->t_str();
13457 return Real2code(u
.val_Real
);
13459 return get_single_expr_enum();
13461 return get_my_scope()->get_scope_mod_gen()
13462 ->add_bitstring_literal(*u
.str
.val_str
);
13464 return get_my_scope()->get_scope_mod_gen()
13465 ->add_hexstring_literal(*u
.str
.val_str
);
13467 return get_my_scope()->get_scope_mod_gen()
13468 ->add_octetstring_literal(*u
.str
.val_str
);
13470 return get_my_scope()->get_scope_mod_gen()
13471 ->add_charstring_literal(*u
.str
.val_str
);
13473 if (u
.ustr
.convert_str
) {
13474 set_valuetype(V_CSTR
);
13475 return get_my_scope()->get_scope_mod_gen()
13476 ->add_charstring_literal(*u
.str
.val_str
);
13478 return get_my_scope()->get_scope_mod_gen()
13479 ->add_ustring_literal(*u
.ustr
.val_ustr
);
13481 return get_single_expr_iso2022str();
13484 vector
<string
> comps
;
13485 bool is_constant
= get_oid_comps(comps
);
13486 size_t nof_comps
= comps
.size();
13488 for (size_t i
= 0; i
< nof_comps
; i
++) {
13489 if (i
> 0) oi_str
+= ", ";
13490 oi_str
+= *(comps
[i
]);
13492 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
13495 // the objid only contains constants
13496 // => create a literal and return its name
13497 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
13499 // the objid contains at least one variable
13500 // => append the number of components before the component values in the string and return it
13501 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
13504 if (u
.val_vs
->get_nof_vs() > 0)
13505 FATAL_ERROR("Value::get_single_expr()");
13506 return string("NULL_VALUE");
13509 if (u
.val_nvs
->get_nof_nvs() > 0)
13510 FATAL_ERROR("Value::get_single_expr()");
13511 return string("NULL_VALUE");
13513 Value
*v_last
= get_value_refd_last();
13514 if (v_last
!= this && v_last
->has_single_expr() &&
13515 v_last
->my_scope
->get_scope_mod_gen() ==
13516 my_scope
->get_scope_mod_gen()) {
13517 // the reference points to another single value in the same module
13518 return v_last
->get_single_expr();
13520 // convert the reference to a single expression
13521 expression_struct expr
;
13522 Code::init_expr(&expr
);
13523 u
.ref
.ref
->generate_code_const_ref(&expr
);
13524 if (expr
.preamble
|| expr
.postamble
)
13525 FATAL_ERROR("Value::get_single_expr()");
13526 string
ret_val(expr
.expr
);
13527 Code::free_expr(&expr
);
13531 return string("OMIT_VALUE");
13533 switch (u
.verdict
) {
13535 return string("NONE");
13537 return string("PASS");
13538 case Verdict_INCONC
:
13539 return string("INCONC");
13541 return string("FAIL");
13542 case Verdict_ERROR
:
13543 return string("ERROR");
13545 FATAL_ERROR("Value::get_single_expr()");
13548 case V_DEFAULT_NULL
:
13549 return string("NULL_COMPREF");
13551 string
ret_val('(');
13552 ret_val
+= my_governor
->get_genname_value(my_scope
);
13553 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13557 expression_struct expr
;
13558 Code::init_expr(&expr
);
13559 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13560 else generate_code_expr_invoke(&expr
);
13561 if (expr
.preamble
|| expr
.postamble
)
13562 FATAL_ERROR("Value::get_single_expr()");
13563 string
ret_val(expr
.expr
);
13564 Code::free_expr(&expr
);
13568 case MACRO_TESTCASEID
:
13569 return string("TTCN_Runtime::get_testcase_id_macro()");
13571 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13577 return get_single_expr_fat();
13579 FATAL_ERROR("Value::get_single_expr()");
13584 bool Value::has_single_expr_expr()
13586 switch (u
.expr
.v_optype
) {
13587 case OPTYPE_RND
: // -
13588 case OPTYPE_COMP_NULL
:
13589 case OPTYPE_COMP_MTC
:
13590 case OPTYPE_COMP_SYSTEM
:
13591 case OPTYPE_COMP_SELF
:
13592 case OPTYPE_COMP_RUNNING_ANY
:
13593 case OPTYPE_COMP_RUNNING_ALL
:
13594 case OPTYPE_COMP_ALIVE_ANY
:
13595 case OPTYPE_COMP_ALIVE_ALL
:
13596 case OPTYPE_TMR_RUNNING_ANY
:
13597 case OPTYPE_GETVERDICT
:
13598 case OPTYPE_TESTCASENAME
:
13599 case OPTYPE_PROF_RUNNING
:
13600 case OPTYPE_CHECKSTATE_ANY
:
13601 case OPTYPE_CHECKSTATE_ALL
:
13603 case OPTYPE_ENCODE
:
13604 case OPTYPE_DECODE
:
13605 case OPTYPE_ISBOUND
:
13606 case OPTYPE_ISPRESENT
:
13607 case OPTYPE_TTCN2STRING
:
13608 case OPTYPE_ENCVALUE_UNICHAR
:
13609 case OPTYPE_DECVALUE_UNICHAR
:
13611 case OPTYPE_UNARYPLUS
: // v1
13612 case OPTYPE_UNARYMINUS
:
13615 case OPTYPE_BIT2HEX
:
13616 case OPTYPE_BIT2INT
:
13617 case OPTYPE_BIT2OCT
:
13618 case OPTYPE_BIT2STR
:
13619 case OPTYPE_CHAR2INT
:
13620 case OPTYPE_CHAR2OCT
:
13621 case OPTYPE_FLOAT2INT
:
13622 case OPTYPE_FLOAT2STR
:
13623 case OPTYPE_HEX2BIT
:
13624 case OPTYPE_HEX2INT
:
13625 case OPTYPE_HEX2OCT
:
13626 case OPTYPE_HEX2STR
:
13627 case OPTYPE_INT2CHAR
:
13628 case OPTYPE_INT2FLOAT
:
13629 case OPTYPE_INT2STR
:
13630 case OPTYPE_INT2UNICHAR
:
13631 case OPTYPE_OCT2BIT
:
13632 case OPTYPE_OCT2CHAR
:
13633 case OPTYPE_OCT2HEX
:
13634 case OPTYPE_OCT2INT
:
13635 case OPTYPE_OCT2STR
:
13636 case OPTYPE_STR2BIT
:
13637 case OPTYPE_STR2FLOAT
:
13638 case OPTYPE_STR2HEX
:
13639 case OPTYPE_STR2INT
:
13640 case OPTYPE_STR2OCT
:
13641 case OPTYPE_UNICHAR2INT
:
13642 case OPTYPE_UNICHAR2CHAR
:
13643 case OPTYPE_ENUM2INT
:
13644 case OPTYPE_RNDWITHVAL
:
13645 case OPTYPE_ISCHOSEN_V
: // v1 i2
13646 case OPTYPE_COMP_RUNNING
:
13647 case OPTYPE_COMP_ALIVE
:
13648 case OPTYPE_GET_STRINGENCODING
:
13649 case OPTYPE_REMOVE_BOM
:
13650 case OPTYPE_DECODE_BASE64
:
13651 return u
.expr
.v1
->has_single_expr();
13652 case OPTYPE_ISCHOSEN_T
: // t1 i2
13653 return u
.expr
.t1
->has_single_expr();
13654 case OPTYPE_ADD
: // v1 v2
13655 case OPTYPE_SUBTRACT
:
13656 case OPTYPE_MULTIPLY
:
13657 case OPTYPE_DIVIDE
:
13660 case OPTYPE_CONCAT
:
13675 case OPTYPE_INT2BIT
:
13676 case OPTYPE_INT2HEX
:
13677 case OPTYPE_INT2OCT
:
13678 return u
.expr
.v1
->has_single_expr() &&
13679 u
.expr
.v2
->has_single_expr();
13680 case OPTYPE_UNICHAR2OCT
:
13681 case OPTYPE_OCT2UNICHAR
:
13682 case OPTYPE_ENCODE_BASE64
:
13683 return u
.expr
.v1
->has_single_expr() &&
13684 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13687 return u
.expr
.v1
->has_single_expr() &&
13688 u
.expr
.v2
->has_single_expr() &&
13689 !u
.expr
.v2
->needs_short_circuit();
13690 case OPTYPE_SUBSTR
:
13691 return u
.expr
.ti1
->has_single_expr() &&
13692 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13693 case OPTYPE_REGEXP
:
13694 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13695 u
.expr
.v3
->has_single_expr();
13696 case OPTYPE_DECOMP
: // v1 v2 v3
13697 return u
.expr
.v1
->has_single_expr() &&
13698 u
.expr
.v2
->has_single_expr() &&
13699 u
.expr
.v3
->has_single_expr();
13700 case OPTYPE_REPLACE
:
13701 return u
.expr
.ti1
->has_single_expr() &&
13702 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13703 u
.expr
.ti4
->has_single_expr();
13704 case OPTYPE_ISVALUE
: // ti1
13705 case OPTYPE_LENGTHOF
: // ti1
13706 case OPTYPE_SIZEOF
: // ti1
13707 case OPTYPE_VALUEOF
: // ti1
13708 return u
.expr
.ti1
->has_single_expr();
13709 case OPTYPE_LOG2STR
:
13710 case OPTYPE_ANY2UNISTR
:
13711 return u
.expr
.logargs
->has_single_expr();
13712 case OPTYPE_MATCH
: // v1 t2
13713 return u
.expr
.v1
->has_single_expr() &&
13714 u
.expr
.t2
->has_single_expr();
13715 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13716 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13717 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13718 case OPTYPE_TMR_READ
: // r1
13719 case OPTYPE_TMR_RUNNING
:
13720 case OPTYPE_ACTIVATE
:
13721 return u
.expr
.r1
->has_single_expr();
13722 case OPTYPE_EXECUTE
: // r1 [v2]
13723 return u
.expr
.r1
->has_single_expr() &&
13724 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13725 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13726 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13727 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13728 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13729 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13731 FATAL_ERROR("Value::has_single_expr_expr()");
13735 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13737 if (!v
->has_single_expr()) return false;
13738 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13739 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13743 string
Value::get_single_expr_enum()
13745 string
ret_val(my_governor
->get_genname_value(my_scope
));
13747 ret_val
+= u
.val_id
->get_name();
13751 string
Value::get_single_expr_iso2022str()
13754 Type
*type
= get_my_governor()->get_type_refd_last();
13755 switch (type
->get_typetype()) {
13756 case Type::T_TELETEXSTRING
:
13757 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13759 case Type::T_VIDEOTEXSTRING
:
13760 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13762 case Type::T_GRAPHICSTRING
:
13763 case Type::T_OBJECTDESCRIPTOR
:
13764 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13766 case Type::T_GENERALSTRING
:
13767 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13770 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13773 string
*ostr
= char2oct(*u
.str
.val_str
);
13774 ret_val
+= get_my_scope()->get_scope_mod_gen()
13775 ->add_octetstring_literal(*ostr
);
13781 string
Value::get_single_expr_fat()
13783 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13784 // the ampersand operator is not really necessary to obtain the function
13785 // pointer, but some older versions of GCC cannot instantiate the
13786 // appropriate operator=() member of class OPTIONAL when necessary
13787 // if only the function name is given
13788 string
ret_val('&');
13789 switch (valuetype
) {
13791 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13794 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13795 ret_val
+= "_instance";
13798 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13801 FATAL_ERROR("Value::get_single_expr_fat()");
13806 bool Value::is_compound()
13808 switch (valuetype
) {
13821 bool Value::needs_temp_ref()
13823 switch (valuetype
) {
13826 if (!is_indexed()) {
13827 // Temporary reference is needed if the value has at least one real
13828 // element (i.e. it is not empty or contains only not used symbols).
13829 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13830 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13833 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13834 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13835 ->valuetype
!= V_NOTUSED
)
13841 size_t nof_real_vs
= 0;
13842 if (!is_indexed()) {
13843 // Temporary reference is needed if the array value has at least two
13844 // real elements (excluding not used symbols).
13845 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13846 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13848 if (nof_real_vs
> 1) return true;
13852 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13853 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13854 ->valuetype
!= V_NOTUSED
) {
13856 if (nof_real_vs
> 1) return true;
13864 // it depends on the type since fields with omit or default value
13865 // may not be present
13866 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13868 // incomplete values are allowed in TTCN-3
13869 // we should check the number of value components
13870 return u
.val_nvs
->get_nof_nvs() > 1;
13875 case V_UNDEF_LOWERID
:
13876 case V_UNDEF_BLOCK
:
13878 // these values cannot occur during code generation
13879 FATAL_ERROR("Value::needs_temp_ref()");
13881 return !u
.val_Int
->is_native();
13883 // other value types (literal values) do not need temporary reference
13888 bool Value::needs_short_circuit()
13890 switch (valuetype
) {
13898 // sub-expressions should be evaluated only if necessary
13901 FATAL_ERROR("Value::needs_short_circuit()");
13903 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13904 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13905 switch (t_ass
->get_asstype()) {
13906 case Assignment::A_FUNCTION_RVAL
:
13907 case Assignment::A_EXT_FUNCTION_RVAL
:
13908 // avoid unnecessary call of a function
13910 case Assignment::A_CONST
:
13911 case Assignment::A_EXT_CONST
:
13912 case Assignment::A_MODULEPAR
:
13913 case Assignment::A_VAR
:
13914 case Assignment::A_PAR_VAL_IN
:
13915 case Assignment::A_PAR_VAL_OUT
:
13916 case Assignment::A_PAR_VAL_INOUT
:
13917 // depends on field/array sub-references, which is examined below
13920 FATAL_ERROR("Value::needs_short_circuit()");
13922 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13924 // the evaluation of the reference does not have side effects
13925 // (i.e. false shall be returned) only if all sub-references point to
13926 // mandatory fields of record/set types, and neither sub-reference points
13927 // to a field of a union type
13928 Type
*t_type
= t_ass
->get_Type();
13929 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13930 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13931 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13932 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13933 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13934 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13935 t_cf
->get_is_optional()) return true;
13936 t_type
= t_cf
->get_type();
13937 } else return true;
13943 void Value::dump(unsigned level
) const
13945 switch (valuetype
) {
13969 case V_DEFAULT_NULL
:
13977 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13981 DEBUG(level
, "Value: reference");
13982 u
.ref
.ref
->dump(level
+ 1);
13984 case V_UNDEF_LOWERID
:
13985 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13987 case V_UNDEF_BLOCK
:
13988 DEBUG(level
, "Value: {block}");
13991 DEBUG(level
, "Value: null");
13994 DEBUG(level
, "Value: invoke");
13995 u
.invoke
.v
->dump(level
+ 1);
13996 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13997 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
14000 DEBUG(level
, "Value: unknown type: %d", valuetype
);
14004 void Value::add_string_element(size_t index
, Value
*v_element
,
14005 map
<size_t, Value
>*& string_elements
)
14007 v_element
->set_my_scope(get_my_scope());
14008 v_element
->set_my_governor(get_my_governor());
14009 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
14010 v_element
->set_location(*this);
14011 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
14012 string_elements
->add(index
, v_element
);
14015 ///////////////////////////////////////////////////////////////////////////////
14016 // class LazyParamData
14018 int LazyParamData::depth
= 0;
14019 bool LazyParamData::used_as_lvalue
= false;
14020 vector
<string
>* LazyParamData::type_vec
= NULL
;
14021 vector
<string
>* LazyParamData::refd_vec
= NULL
;
14023 void LazyParamData::init(bool p_used_as_lvalue
) {
14024 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
14026 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
14027 used_as_lvalue
= p_used_as_lvalue
;
14028 type_vec
= new vector
<string
>;
14029 refd_vec
= new vector
<string
>;
14034 void LazyParamData::clean() {
14035 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
14036 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
14039 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
14044 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
14052 bool LazyParamData::in_lazy() {
14053 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
14057 // returns a temporary id instead of the C++ reference to a definition
14058 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
14059 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
14060 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
14061 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
14062 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
14063 // store the type of the assignment
14064 string
* type_str
= new string
;
14065 switch (ass
->get_asstype()) {
14066 case Assignment::A_MODULEPAR_TEMP
:
14067 case Assignment::A_TEMPLATE
:
14068 case Assignment::A_VAR_TEMPLATE
:
14069 case Assignment::A_PAR_TEMPL_IN
:
14070 case Assignment::A_PAR_TEMPL_OUT
:
14071 case Assignment::A_PAR_TEMPL_INOUT
:
14072 *type_str
= ass
->get_Type()->get_genname_template(scope
);
14075 *type_str
= ass
->get_Type()->get_genname_value(scope
);
14077 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
14078 bool refd_ass_is_lazy_fpar
= false;
14079 switch (ass
->get_asstype()) {
14080 case Assignment::A_PAR_VAL
:
14081 case Assignment::A_PAR_VAL_IN
:
14082 case Assignment::A_PAR_TEMPL_IN
:
14083 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
14084 if (refd_ass_is_lazy_fpar
) {
14085 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
14091 // add the "const" part if the referenced assignment is a constant thing
14092 if (!refd_ass_is_lazy_fpar
) {
14093 switch (ass
->get_asstype()) {
14094 case Assignment::A_CONST
:
14095 case Assignment::A_OC
:
14096 case Assignment::A_OBJECT
:
14097 case Assignment::A_OS
:
14098 case Assignment::A_VS
:
14099 case Assignment::A_EXT_CONST
:
14100 case Assignment::A_MODULEPAR
:
14101 case Assignment::A_MODULEPAR_TEMP
:
14102 case Assignment::A_TEMPLATE
:
14103 case Assignment::A_PAR_VAL
:
14104 case Assignment::A_PAR_VAL_IN
:
14105 case Assignment::A_PAR_TEMPL_IN
:
14106 *type_str
= string("const ") + *type_str
;
14114 type_vec
->add(type_str
);
14115 // store the C++ reference string
14116 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
14117 if (refd_ass_is_lazy_fpar
) {
14118 Type
* refd_ass_type
= ass
->get_Type();
14119 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
);
14120 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
14122 return get_member_name(refd_vec
->size()-1);
14126 string
LazyParamData::get_member_name(size_t idx
) {
14127 return string("lpm_") + Int2string(idx
);
14130 string
LazyParamData::get_constr_param_name(size_t idx
) {
14131 return string("lpp_") + Int2string(idx
);
14134 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
14135 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14136 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
14137 const string
& tmp_id
= val
->get_temporary_id();
14138 const char *tmp_id_str
= tmp_id
.c_str();
14139 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14140 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
14142 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14144 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14146 val
->generate_code_expr(expr
);
14150 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
14151 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14152 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
14153 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
14154 const char *tmp_id_str
= tmp_id
.c_str();
14155 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14156 temp
->get_Template()->get_my_governor()
14157 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
14158 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14159 tmp_id_str
, temp
->get_Template());
14160 // Not incorporated into gen_conv_code() yet.
14161 if (gen_restriction_check
!= TR_NONE
)
14162 expr
->preamble
= Template::generate_restriction_check_code(
14163 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
14164 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14165 } else temp
->generate_code(expr
, gen_restriction_check
);
14168 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14169 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14171 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14172 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14173 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14174 expression_struct value_expr
;
14175 Code::init_expr(&value_expr
);
14176 generate_code_for_value(&value_expr
, value
, scope
);
14177 // the id of the instance of Lazy_Param which will be used as the actual parameter
14178 const string
& lazy_param_id
= value
->get_temporary_id();
14179 if (value_expr
.preamble
) {
14180 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
14182 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14183 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14184 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
14185 Code::free_expr(&value_expr
);
14186 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14189 // only if the formal parameter is *not* used as lvalue
14190 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
14191 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
14193 bool refd_ass_is_lazy_fpar
= false;
14194 switch (refd_ass
->get_asstype()) {
14195 case Assignment::A_PAR_VAL
:
14196 case Assignment::A_PAR_VAL_IN
:
14197 case Assignment::A_PAR_TEMPL_IN
:
14198 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14203 if (refd_ass_is_lazy_fpar
) {
14204 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14209 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14210 expression_struct value_expr
;
14211 Code::init_expr(&value_expr
);
14212 generate_code_for_value(&value_expr
, value
, scope
);
14213 // the id of the instance of Lazy_Param which will be used as the actual parameter
14214 string lazy_param_id
= value
->get_temporary_id();
14215 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
14216 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
14219 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
14220 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14222 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14223 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14224 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14225 expression_struct tmpl_expr
;
14226 Code::init_expr(&tmpl_expr
);
14227 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14228 // the id of the instance of Lazy_Param which will be used as the actual parameter
14229 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
14230 if (tmpl_expr
.preamble
) {
14231 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
14233 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14234 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14235 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
14236 Code::free_expr(&tmpl_expr
);
14237 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14240 // only if the formal parameter is *not* used as lvalue
14241 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
14242 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
14244 bool refd_ass_is_lazy_fpar
= false;
14245 switch (refd_ass
->get_asstype()) {
14246 case Assignment::A_PAR_VAL
:
14247 case Assignment::A_PAR_VAL_IN
:
14248 case Assignment::A_PAR_TEMPL_IN
:
14249 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14254 if (refd_ass_is_lazy_fpar
) {
14255 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14260 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14261 expression_struct tmpl_expr
;
14262 Code::init_expr(&tmpl_expr
);
14263 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14264 // the id of the instance of Lazy_Param which will be used as the actual parameter
14265 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
14266 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
14267 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
14270 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
14271 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
14272 if (type_vec
->size()>0) {
14273 // private members of the local class will be const references to the objects referenced by the expression
14274 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14275 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
14277 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
14278 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
14279 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14280 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14281 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
14283 expr
->preamble
= mputstr(expr
->preamble
, "): ");
14284 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14285 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14286 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
14288 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
14289 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
14291 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
14292 // use the temporary expr structure to fill the body of the eval_expr() function
14293 if (param_expr
.preamble
) {
14294 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
14296 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
14297 if (param_expr
.postamble
) {
14298 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
14300 Code::free_expr(¶m_expr
);
14301 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
14302 "};\n" // end of local class definition
14304 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
14305 if (type_vec
->size()>0) {
14306 expr
->preamble
= mputc(expr
->preamble
, '(');
14307 // paramteres of the constructor are references to the objects used in the expression
14308 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
14309 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14310 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
14312 expr
->preamble
= mputc(expr
->preamble
, ')');
14314 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
14315 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14316 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
14319 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
14320 expression_struct ref_expr
;
14321 Code::init_expr(&ref_expr
);
14322 ref
->generate_code(&ref_expr
);
14323 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
14324 if (ref_expr
.preamble
) {
14325 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
14327 Assignment
* ass
= ref
->get_refd_assignment();
14328 // determine C++ type of the assignment
14330 switch (ass
->get_asstype()) {
14331 case Assignment::A_MODULEPAR_TEMP
:
14332 case Assignment::A_TEMPLATE
:
14333 case Assignment::A_VAR_TEMPLATE
:
14334 case Assignment::A_PAR_TEMPL_IN
:
14335 case Assignment::A_PAR_TEMPL_OUT
:
14336 case Assignment::A_PAR_TEMPL_INOUT
:
14337 type_str
= ass
->get_Type()->get_genname_template(scope
);
14340 type_str
= ass
->get_Type()->get_genname_value(scope
);
14342 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14343 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
14344 if (ref_expr
.postamble
) {
14345 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
14347 Code::free_expr(&ref_expr
);
14348 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14351 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14352 const string
& lazy_param_id
= value
->get_temporary_id();
14353 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14354 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14355 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
14356 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14359 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
14360 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
14361 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14362 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14363 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
14364 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14367 } // namespace Common