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_HOSTID
: // [v1]
215 u
.expr
.v1
=p
.u
.expr
.v1
?p
.u
.expr
.v1
->clone():0;
217 case OPTYPE_ADD
: // v1 v2
218 case OPTYPE_SUBTRACT
:
219 case OPTYPE_MULTIPLY
:
243 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
244 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
246 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
247 case OPTYPE_OCT2UNICHAR
:
248 case OPTYPE_ENCODE_BASE64
:
249 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
250 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
253 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
254 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
257 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
258 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
259 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
262 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
263 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
264 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
266 case OPTYPE_DECOMP
: // v1 v2 v3
267 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
268 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
269 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
272 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
273 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
274 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
275 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
277 case OPTYPE_LENGTHOF
: // ti1
278 case OPTYPE_SIZEOF
: // ti1
279 case OPTYPE_VALUEOF
: // ti1
281 case OPTYPE_ISPRESENT
:
282 case OPTYPE_TTCN2STRING
:
283 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
285 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
286 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
287 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
289 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
290 u
.expr
.r1
= p
.u
.expr
.r1
->clone();
291 u
.expr
.r2
= p
.u
.expr
.r2
->clone();
292 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
294 case OPTYPE_UNDEF_RUNNING
:
295 case OPTYPE_TMR_READ
:
296 case OPTYPE_TMR_RUNNING
:
297 case OPTYPE_ACTIVATE
:
298 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
300 case OPTYPE_EXECUTE
: // r1 [v2]
301 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
302 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
304 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
305 case OPTYPE_CHECKSTATE_ALL
:
306 u
.expr
.r1
=p
.u
.expr
.r1
?p
.u
.expr
.r1
->clone():0;
307 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
309 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
310 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
311 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
312 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
313 u
.expr
.b4
= p
.u
.expr
.b4
;
315 case OPTYPE_MATCH
: // v1 t2
316 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
317 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
319 case OPTYPE_ISCHOSEN
: // r1 i2
320 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
321 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
323 case OPTYPE_ISCHOSEN_V
: // v1 i2
324 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
325 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
327 case OPTYPE_ISCHOSEN_T
: // t1 i2
328 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
329 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
331 case OPTYPE_ACTIVATE_REFD
:
332 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
333 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
334 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
336 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
337 u
.expr
.state
= EXPR_CHECKED
;
340 case OPTYPE_EXECUTE_REFD
:
341 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
342 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
343 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
345 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
346 u
.expr
.state
= EXPR_CHECKED
;
348 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
351 case OPTYPE_ANY2UNISTR
:
352 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
355 FATAL_ERROR("Value::Value()");
364 u
.refd_fat
= p
.u
.refd_fat
;
367 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
368 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
369 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
372 u
.refered
= p
.u
.refered
->clone();
375 FATAL_ERROR("Value::Value()");
379 void Value::clean_up()
402 case V_UNDEF_LOWERID
:
410 delete u
.str
.val_str
;
411 clean_up_string_elements(u
.str
.str_elements
);
414 delete u
.ustr
.val_ustr
;
415 clean_up_string_elements(u
.ustr
.ustr_elements
);
423 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
424 delete (*u
.oid_comps
)[i
];
425 u
.oid_comps
->clear();
433 delete u
.choice
.alt_name
;
434 delete u
.choice
.alt_value
;
453 delete u
.invoke
.t_list
;
454 delete u
.invoke
.ap_list
;
458 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
467 FATAL_ERROR("Value::clean_up()");
471 void Value::clean_up_expr()
473 switch (u
.expr
.state
) {
475 case EXPR_CHECKING_ERR
:
476 FATAL_ERROR("Value::clean_up_expr()");
480 switch (u
.expr
.v_optype
) {
481 case OPTYPE_RND
: // -
482 case OPTYPE_COMP_NULL
:
483 case OPTYPE_COMP_MTC
:
484 case OPTYPE_COMP_SYSTEM
:
485 case OPTYPE_COMP_SELF
:
486 case OPTYPE_COMP_RUNNING_ANY
:
487 case OPTYPE_COMP_RUNNING_ALL
:
488 case OPTYPE_COMP_ALIVE_ANY
:
489 case OPTYPE_COMP_ALIVE_ALL
:
490 case OPTYPE_TMR_RUNNING_ANY
:
491 case OPTYPE_GETVERDICT
:
492 case OPTYPE_TESTCASENAME
:
493 case OPTYPE_PROF_RUNNING
:
495 case OPTYPE_UNARYPLUS
: // v1
496 case OPTYPE_UNARYMINUS
:
503 case OPTYPE_CHAR2INT
:
504 case OPTYPE_CHAR2OCT
:
505 case OPTYPE_COMP_RUNNING
:
506 case OPTYPE_COMP_ALIVE
:
507 case OPTYPE_FLOAT2INT
:
508 case OPTYPE_FLOAT2STR
:
513 case OPTYPE_INT2CHAR
:
514 case OPTYPE_INT2FLOAT
:
516 case OPTYPE_INT2UNICHAR
:
518 case OPTYPE_OCT2CHAR
:
523 case OPTYPE_STR2FLOAT
:
527 case OPTYPE_UNICHAR2INT
:
528 case OPTYPE_UNICHAR2CHAR
:
529 case OPTYPE_ENUM2INT
:
530 case OPTYPE_RNDWITHVAL
:
531 case OPTYPE_REMOVE_BOM
:
532 case OPTYPE_GET_STRINGENCODING
:
533 case OPTYPE_DECODE_BASE64
:
537 case OPTYPE_ADD
: // v1 v2
538 case OPTYPE_SUBTRACT
:
539 case OPTYPE_MULTIPLY
:
563 case OPTYPE_UNICHAR2OCT
:
564 case OPTYPE_OCT2UNICHAR
:
565 case OPTYPE_ENCODE_BASE64
:
583 case OPTYPE_DECOMP
: // v1 v2 v3
594 case OPTYPE_LENGTHOF
: // ti1
595 case OPTYPE_SIZEOF
: // ti1
596 case OPTYPE_VALUEOF
: // ti1
600 case OPTYPE_ISPRESENT
:
601 case OPTYPE_TTCN2STRING
:
604 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
608 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
613 case OPTYPE_UNDEF_RUNNING
:
614 case OPTYPE_TMR_READ
:
615 case OPTYPE_TMR_RUNNING
:
616 case OPTYPE_ACTIVATE
:
619 case OPTYPE_EXECUTE
: // r1 [v2]
623 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
624 case OPTYPE_CHECKSTATE_ALL
:
628 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
633 case OPTYPE_MATCH
: // v1 t2
637 case OPTYPE_ISCHOSEN
: // r1 i2
641 case OPTYPE_ISCHOSEN_V
: // v1 i2
645 case OPTYPE_ISCHOSEN_T
: // t1 i2
649 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
651 if(u
.expr
.state
!=EXPR_CHECKED
)
652 delete u
.expr
.t_list2
;
654 delete u
.expr
.ap_list2
;
656 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
658 if(u
.expr
.state
!=EXPR_CHECKED
)
659 delete u
.expr
.t_list2
;
661 delete u
.expr
.ap_list2
;
665 case OPTYPE_ANY2UNISTR
:
666 delete u
.expr
.logargs
;
669 FATAL_ERROR("Value::clean_up_expr()");
673 void Value::copy_and_destroy(Value
*src
)
676 valuetype
= src
->valuetype
;
678 // update the pointer used for caching if it points to the value itself
679 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
680 src
->valuetype
= V_ERROR
;
684 Value::Value(valuetype_t p_vt
)
685 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
696 u
.oid_comps
=new vector
<OID_comp
>();
699 u
.ids
=new map
<string
, Identifier
>();
702 FATAL_ERROR("Value::Value()");
706 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
707 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
711 u
.val_bool
=p_val_bool
;
714 FATAL_ERROR("Value::Value()");
718 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
719 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
723 u
.val_Int
=new int_val_t(p_val_Int
);
726 FATAL_ERROR("Value::Value()");
730 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
731 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
738 FATAL_ERROR("Value::Value()");
742 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
743 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
745 if(!p_val_str
) FATAL_ERROR("NULL parameter");
752 set_val_str(p_val_str
);
755 FATAL_ERROR("Value::Value()");
759 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
760 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
762 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
763 set_val_ustr(p_val_ustr
);
764 u
.ustr
.convert_str
= false;
767 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
768 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
770 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
773 u
.char_syms
= p_char_syms
;
776 FATAL_ERROR("Value::Value()");
780 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
781 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
784 FATAL_ERROR("NULL parameter");
788 case V_UNDEF_LOWERID
:
792 FATAL_ERROR("Value::Value()");
796 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
797 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
800 FATAL_ERROR("NULL parameter");
803 u
.choice
.alt_name
=p_id
;
804 u
.choice
.alt_value
=p_val
;
807 FATAL_ERROR("Value::Value()");
811 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
812 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
816 u
.val_Real
=p_val_Real
;
819 FATAL_ERROR("Value::Value()");
823 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
824 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
826 if(!p_vs
) FATAL_ERROR("NULL parameter");
834 FATAL_ERROR("Value::Value()");
838 Value::Value(valuetype_t p_vt
, Value
*p_v
,
839 Ttcn::ParsedActualParameters
*p_t_list
)
840 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
842 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
846 u
.invoke
.t_list
= p_t_list
;
847 u
.invoke
.ap_list
= 0;
850 FATAL_ERROR("Value::Value()");
855 Value::Value(operationtype_t p_optype
)
856 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
858 u
.expr
.v_optype
= p_optype
;
859 u
.expr
.state
= EXPR_NOT_CHECKED
;
862 case OPTYPE_COMP_NULL
:
863 case OPTYPE_COMP_MTC
:
864 case OPTYPE_COMP_SYSTEM
:
865 case OPTYPE_COMP_SELF
:
866 case OPTYPE_COMP_RUNNING_ANY
:
867 case OPTYPE_COMP_RUNNING_ALL
:
868 case OPTYPE_COMP_ALIVE_ANY
:
869 case OPTYPE_COMP_ALIVE_ALL
:
870 case OPTYPE_TMR_RUNNING_ANY
:
871 case OPTYPE_GETVERDICT
:
872 case OPTYPE_TESTCASENAME
:
873 case OPTYPE_PROF_RUNNING
:
876 FATAL_ERROR("Value::Value()");
881 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
882 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
884 u
.expr
.v_optype
= p_optype
;
885 u
.expr
.state
= EXPR_NOT_CHECKED
;
887 case OPTYPE_UNARYPLUS
:
888 case OPTYPE_UNARYMINUS
:
895 case OPTYPE_CHAR2INT
:
896 case OPTYPE_CHAR2OCT
:
897 case OPTYPE_COMP_RUNNING
:
898 case OPTYPE_COMP_ALIVE
:
899 case OPTYPE_FLOAT2INT
:
900 case OPTYPE_FLOAT2STR
:
905 case OPTYPE_INT2CHAR
:
906 case OPTYPE_INT2FLOAT
:
908 case OPTYPE_INT2UNICHAR
:
910 case OPTYPE_OCT2CHAR
:
915 case OPTYPE_STR2FLOAT
:
919 case OPTYPE_UNICHAR2INT
:
920 case OPTYPE_UNICHAR2CHAR
:
921 case OPTYPE_ENUM2INT
:
922 case OPTYPE_RNDWITHVAL
:
923 case OPTYPE_REMOVE_BOM
:
924 case OPTYPE_GET_STRINGENCODING
:
925 case OPTYPE_DECODE_BASE64
:
926 if(!p_v1
) FATAL_ERROR("Value::Value()");
933 FATAL_ERROR("Value::Value()");
938 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
939 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
941 u
.expr
.v_optype
= p_optype
;
942 u
.expr
.state
= EXPR_NOT_CHECKED
;
944 case OPTYPE_LENGTHOF
:
950 case OPTYPE_ENCVALUE_UNICHAR
:
951 case OPTYPE_ISPRESENT
:
952 case OPTYPE_TTCN2STRING
:
953 if(!p_ti1
) FATAL_ERROR("Value::Value()");
957 FATAL_ERROR("Value::Value()");
962 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
963 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
965 u
.expr
.v_optype
= p_optype
;
966 u
.expr
.state
= EXPR_NOT_CHECKED
;
968 case OPTYPE_UNDEF_RUNNING
:
969 case OPTYPE_TMR_READ
:
970 case OPTYPE_TMR_RUNNING
:
971 case OPTYPE_ACTIVATE
:
972 if(!p_r1
) FATAL_ERROR("Value::Value()");
976 FATAL_ERROR("Value::Value()");
981 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
982 Ttcn::ParsedActualParameters
*p_ap_list
)
983 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
985 u
.expr
.v_optype
= p_optype
;
986 u
.expr
.state
= EXPR_NOT_CHECKED
;
988 case OPTYPE_ACTIVATE_REFD
:
989 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
991 u
.expr
.t_list2
= p_ap_list
;
994 FATAL_ERROR("Value::Value()");
999 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
1000 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
1001 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1003 u
.expr
.v_optype
= p_optype
;
1004 u
.expr
.state
= EXPR_NOT_CHECKED
;
1006 case OPTYPE_EXECUTE_REFD
:
1007 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
1009 u
.expr
.t_list2
= p_t_list2
;
1013 FATAL_ERROR("Value::Value()");
1017 // r1 [v2] or [r1] v2
1018 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
1019 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1021 u
.expr
.v_optype
= p_optype
;
1022 u
.expr
.state
= EXPR_NOT_CHECKED
;
1024 case OPTYPE_EXECUTE
:
1025 if(!p_r1
) FATAL_ERROR("Value::Value()");
1029 case OPTYPE_CHECKSTATE_ANY
:
1030 case OPTYPE_CHECKSTATE_ALL
:
1031 if(!p_v2
) FATAL_ERROR("Value::Value()");
1032 u
.expr
.r1
=p_r1
; // may be null if any port or all port
1036 FATAL_ERROR("Value::Value()");
1041 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
1042 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
1043 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1045 u
.expr
.v_optype
= p_optype
;
1046 u
.expr
.state
= EXPR_NOT_CHECKED
;
1048 case OPTYPE_COMP_CREATE
:
1049 if(!p_r1
) FATAL_ERROR("Value::Value()");
1056 FATAL_ERROR("Value::Value()");
1061 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
1062 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1064 u
.expr
.v_optype
= p_optype
;
1065 u
.expr
.state
= EXPR_NOT_CHECKED
;
1068 case OPTYPE_SUBTRACT
:
1069 case OPTYPE_MULTIPLY
:
1090 case OPTYPE_INT2BIT
:
1091 case OPTYPE_INT2HEX
:
1092 case OPTYPE_INT2OCT
:
1093 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1097 case OPTYPE_UNICHAR2OCT
:
1098 case OPTYPE_OCT2UNICHAR
:
1099 case OPTYPE_ENCODE_BASE64
:
1100 if(!p_v1
) FATAL_ERROR("Value::Value()");
1102 // p_v2 may be NULL if there is no second param
1106 FATAL_ERROR("Value::Value()");
1111 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1112 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1113 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1115 u
.expr
.v_optype
= p_optype
;
1116 u
.expr
.state
= EXPR_NOT_CHECKED
;
1118 case OPTYPE_REPLACE
:
1119 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1126 FATAL_ERROR("Value::Value()");
1131 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1132 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1134 u
.expr
.v_optype
= p_optype
;
1135 u
.expr
.state
= EXPR_NOT_CHECKED
;
1138 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1144 FATAL_ERROR("Value::Value()");
1149 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
)
1150 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1152 u
.expr
.v_optype
= p_optype
;
1153 u
.expr
.state
= EXPR_NOT_CHECKED
;
1155 case OPTYPE_ENCVALUE_UNICHAR
:
1156 if(!p_ti1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1161 FATAL_ERROR("Value::Value()");
1166 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1167 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1169 u
.expr
.v_optype
=p_optype
;
1170 u
.expr
.state
=EXPR_NOT_CHECKED
;
1173 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1179 FATAL_ERROR("Value::Value()");
1184 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1185 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1187 u
.expr
.v_optype
=p_optype
;
1188 u
.expr
.state
=EXPR_NOT_CHECKED
;
1191 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1197 FATAL_ERROR("Value::Value()");
1202 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1203 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1205 u
.expr
.v_optype
= p_optype
;
1206 u
.expr
.state
= EXPR_NOT_CHECKED
;
1209 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1214 FATAL_ERROR("Value::Value()");
1219 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1221 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1223 u
.expr
.v_optype
= p_optype
;
1224 u
.expr
.state
= EXPR_NOT_CHECKED
;
1226 case OPTYPE_ISCHOSEN
:
1227 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1232 FATAL_ERROR("Value::Value()");
1236 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1237 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1239 u
.expr
.v_optype
= p_optype
;
1240 u
.expr
.state
= EXPR_NOT_CHECKED
;
1242 case OPTYPE_LOG2STR
:
1243 case OPTYPE_ANY2UNISTR
:
1244 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1245 u
.expr
.logargs
= p_logargs
;
1248 FATAL_ERROR("Value::Value()");
1252 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1253 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1255 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1256 switch (p_macrotype
) {
1257 case MACRO_MODULEID
:
1258 case MACRO_FILENAME
:
1259 case MACRO_BFILENAME
:
1260 case MACRO_FILEPATH
:
1261 case MACRO_LINENUMBER
:
1262 case MACRO_LINENUMBER_C
:
1263 case MACRO_DEFINITIONID
:
1265 case MACRO_TESTCASEID
:
1268 FATAL_ERROR("Value::Value()");
1270 u
.macro
= p_macrotype
;
1273 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1274 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1276 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1283 FATAL_ERROR("Value::Value()");
1287 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1288 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1290 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1294 u
.ref
.refd_last
= 0;
1300 FATAL_ERROR("Value::Value()");
1304 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1305 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1307 if(!p_block
) FATAL_ERROR("NULL parameter");
1313 FATAL_ERROR("Value::Value()");
1317 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1318 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1320 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1321 switch (p_verdict
) {
1324 case Verdict_INCONC
:
1329 FATAL_ERROR("Value::Value()");
1331 u
.verdict
= p_verdict
;
1334 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1335 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1337 u
.expr
.v_optype
= p_optype
;
1338 u
.expr
.state
= EXPR_NOT_CHECKED
;
1341 case OPTYPE_DECVALUE_UNICHAR
:
1342 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1347 FATAL_ERROR("Value::Value()");
1352 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
,
1354 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1356 u
.expr
.v_optype
= p_optype
;
1357 u
.expr
.state
= EXPR_NOT_CHECKED
;
1359 case OPTYPE_DECVALUE_UNICHAR
:
1360 if(!p_r1
|| !p_r2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1366 FATAL_ERROR("Value::Value()");
1375 Value
*Value::clone() const
1377 return new Value(*this);
1380 Value::operationtype_t
Value::get_optype() const
1382 if(valuetype
!=V_EXPR
)
1383 FATAL_ERROR("Value::get_optype()");
1384 return u
.expr
.v_optype
;
1387 void Value::set_my_governor(Type
*p_gov
)
1390 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1394 Type
*Value::get_my_governor() const
1399 void Value::set_fullname(const string
& p_fullname
)
1401 GovernedSimple::set_fullname(p_fullname
);
1404 u
.char_syms
->set_fullname(p_fullname
);
1408 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1409 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1412 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1413 u
.choice
.alt_name
->get_dispname());
1418 u
.val_vs
->set_fullname(p_fullname
);
1422 u
.val_nvs
->set_fullname(p_fullname
);
1425 u
.ref
.ref
->set_fullname(p_fullname
);
1428 u
.refered
->set_fullname(p_fullname
);
1431 u
.invoke
.v
->set_fullname(p_fullname
);
1432 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1433 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1436 set_fullname_expr(p_fullname
);
1443 void Value::set_my_scope(Scope
*p_scope
)
1445 GovernedSimple::set_my_scope(p_scope
);
1448 u
.char_syms
->set_my_scope(p_scope
);
1452 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1453 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1456 u
.choice
.alt_value
->set_my_scope(p_scope
);
1461 u
.val_vs
->set_my_scope(p_scope
);
1465 u
.val_nvs
->set_my_scope(p_scope
);
1468 u
.ref
.ref
->set_my_scope(p_scope
);
1471 u
.refered
->set_my_scope(p_scope
);
1474 u
.invoke
.v
->set_my_scope(p_scope
);
1475 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1476 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1479 set_my_scope_expr(p_scope
);
1486 void Value::set_fullname_expr(const string
& p_fullname
)
1488 switch (u
.expr
.v_optype
) {
1489 case OPTYPE_RND
: // -
1490 case OPTYPE_COMP_NULL
:
1491 case OPTYPE_COMP_MTC
:
1492 case OPTYPE_COMP_SYSTEM
:
1493 case OPTYPE_COMP_SELF
:
1494 case OPTYPE_COMP_RUNNING_ANY
:
1495 case OPTYPE_COMP_RUNNING_ALL
:
1496 case OPTYPE_COMP_ALIVE_ANY
:
1497 case OPTYPE_COMP_ALIVE_ALL
:
1498 case OPTYPE_TMR_RUNNING_ANY
:
1499 case OPTYPE_GETVERDICT
:
1500 case OPTYPE_TESTCASENAME
:
1501 case OPTYPE_PROF_RUNNING
:
1503 case OPTYPE_UNARYPLUS
: // v1
1504 case OPTYPE_UNARYMINUS
:
1507 case OPTYPE_BIT2HEX
:
1508 case OPTYPE_BIT2INT
:
1509 case OPTYPE_BIT2OCT
:
1510 case OPTYPE_BIT2STR
:
1511 case OPTYPE_CHAR2INT
:
1512 case OPTYPE_CHAR2OCT
:
1513 case OPTYPE_COMP_RUNNING
:
1514 case OPTYPE_COMP_ALIVE
:
1515 case OPTYPE_FLOAT2INT
:
1516 case OPTYPE_FLOAT2STR
:
1517 case OPTYPE_HEX2BIT
:
1518 case OPTYPE_HEX2INT
:
1519 case OPTYPE_HEX2OCT
:
1520 case OPTYPE_HEX2STR
:
1521 case OPTYPE_INT2CHAR
:
1522 case OPTYPE_INT2FLOAT
:
1523 case OPTYPE_INT2STR
:
1524 case OPTYPE_INT2UNICHAR
:
1525 case OPTYPE_OCT2BIT
:
1526 case OPTYPE_OCT2CHAR
:
1527 case OPTYPE_OCT2HEX
:
1528 case OPTYPE_OCT2INT
:
1529 case OPTYPE_OCT2STR
:
1530 case OPTYPE_STR2BIT
:
1531 case OPTYPE_STR2FLOAT
:
1532 case OPTYPE_STR2HEX
:
1533 case OPTYPE_STR2INT
:
1534 case OPTYPE_STR2OCT
:
1535 case OPTYPE_UNICHAR2INT
:
1536 case OPTYPE_UNICHAR2CHAR
:
1537 case OPTYPE_ENUM2INT
:
1538 case OPTYPE_RNDWITHVAL
:
1539 case OPTYPE_REMOVE_BOM
:
1540 case OPTYPE_GET_STRINGENCODING
:
1541 case OPTYPE_DECODE_BASE64
:
1542 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1544 case OPTYPE_HOSTID
: // [v1]
1545 if(u
.expr
.v1
) u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1547 case OPTYPE_ADD
: // v1 v2
1548 case OPTYPE_SUBTRACT
:
1549 case OPTYPE_MULTIPLY
:
1570 case OPTYPE_INT2BIT
:
1571 case OPTYPE_INT2HEX
:
1572 case OPTYPE_INT2OCT
:
1573 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1574 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1576 case OPTYPE_UNICHAR2OCT
:
1577 case OPTYPE_OCT2UNICHAR
:
1578 case OPTYPE_ENCODE_BASE64
:
1579 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1580 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1583 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1584 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1587 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1588 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1589 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1592 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1593 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1594 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1596 case OPTYPE_DECOMP
: // v1 v2 v3
1597 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1598 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1599 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1601 case OPTYPE_REPLACE
:
1602 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1603 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1604 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1605 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1607 case OPTYPE_LENGTHOF
: // ti1
1608 case OPTYPE_SIZEOF
: // ti1
1609 case OPTYPE_VALUEOF
: // ti1
1610 case OPTYPE_ISVALUE
:
1611 case OPTYPE_ISBOUND
:
1613 case OPTYPE_ISPRESENT
:
1614 case OPTYPE_TTCN2STRING
:
1615 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1617 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
1618 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1619 if (u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1621 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1622 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1623 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1624 if (u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1625 case OPTYPE_UNDEF_RUNNING
: // r1
1626 case OPTYPE_TMR_READ
:
1627 case OPTYPE_TMR_RUNNING
:
1628 case OPTYPE_ACTIVATE
:
1629 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1631 case OPTYPE_EXECUTE
: // r1 [v2]
1632 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1633 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1635 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1636 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1637 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1638 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1640 case OPTYPE_MATCH
: // v1 t2
1641 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1642 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1644 case OPTYPE_ISCHOSEN
: // r1 i2
1645 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1647 case OPTYPE_ISCHOSEN_V
: // v1 i2
1648 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1650 case OPTYPE_ISCHOSEN_T
: // t1 i2
1651 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1653 case OPTYPE_ACTIVATE_REFD
:
1654 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1655 if(u
.expr
.state
!=EXPR_CHECKED
)
1656 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1658 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1660 case OPTYPE_EXECUTE_REFD
:
1661 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1662 if(u
.expr
.state
!=EXPR_CHECKED
)
1663 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1665 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1667 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1669 case OPTYPE_LOG2STR
:
1670 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1672 case OPTYPE_ANY2UNISTR
:
1673 u
.expr
.logargs
->set_fullname(p_fullname
+".<logarg>");
1675 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
1676 case OPTYPE_CHECKSTATE_ALL
:
1677 u
.expr
.v2
->set_fullname(p_fullname
+".<operand1>");
1680 FATAL_ERROR("Value::set_fullname_expr()");
1684 void Value::set_my_scope_expr(Scope
*p_scope
)
1686 switch (u
.expr
.v_optype
) {
1687 case OPTYPE_RND
: // -
1688 case OPTYPE_COMP_NULL
:
1689 case OPTYPE_COMP_MTC
:
1690 case OPTYPE_COMP_SYSTEM
:
1691 case OPTYPE_COMP_SELF
:
1692 case OPTYPE_COMP_RUNNING_ANY
:
1693 case OPTYPE_COMP_RUNNING_ALL
:
1694 case OPTYPE_COMP_ALIVE_ANY
:
1695 case OPTYPE_COMP_ALIVE_ALL
:
1696 case OPTYPE_TMR_RUNNING_ANY
:
1697 case OPTYPE_GETVERDICT
:
1698 case OPTYPE_TESTCASENAME
:
1699 case OPTYPE_PROF_RUNNING
:
1701 case OPTYPE_UNARYPLUS
: // v1
1702 case OPTYPE_UNARYMINUS
:
1705 case OPTYPE_BIT2HEX
:
1706 case OPTYPE_BIT2INT
:
1707 case OPTYPE_BIT2OCT
:
1708 case OPTYPE_BIT2STR
:
1709 case OPTYPE_CHAR2INT
:
1710 case OPTYPE_CHAR2OCT
:
1711 case OPTYPE_COMP_RUNNING
:
1712 case OPTYPE_COMP_ALIVE
:
1713 case OPTYPE_FLOAT2INT
:
1714 case OPTYPE_FLOAT2STR
:
1715 case OPTYPE_HEX2BIT
:
1716 case OPTYPE_HEX2INT
:
1717 case OPTYPE_HEX2OCT
:
1718 case OPTYPE_HEX2STR
:
1719 case OPTYPE_INT2CHAR
:
1720 case OPTYPE_INT2FLOAT
:
1721 case OPTYPE_INT2STR
:
1722 case OPTYPE_INT2UNICHAR
:
1723 case OPTYPE_OCT2BIT
:
1724 case OPTYPE_OCT2CHAR
:
1725 case OPTYPE_OCT2HEX
:
1726 case OPTYPE_OCT2INT
:
1727 case OPTYPE_OCT2STR
:
1728 case OPTYPE_STR2BIT
:
1729 case OPTYPE_STR2FLOAT
:
1730 case OPTYPE_STR2HEX
:
1731 case OPTYPE_STR2INT
:
1732 case OPTYPE_STR2OCT
:
1733 case OPTYPE_UNICHAR2INT
:
1734 case OPTYPE_UNICHAR2CHAR
:
1735 case OPTYPE_ENUM2INT
:
1736 case OPTYPE_RNDWITHVAL
:
1737 case OPTYPE_REMOVE_BOM
:
1738 case OPTYPE_GET_STRINGENCODING
:
1739 case OPTYPE_DECODE_BASE64
:
1740 u
.expr
.v1
->set_my_scope(p_scope
);
1742 case OPTYPE_HOSTID
: // [v1]
1743 if(u
.expr
.v1
) u
.expr
.v1
->set_my_scope(p_scope
);
1745 case OPTYPE_ADD
: // v1 v2
1746 case OPTYPE_SUBTRACT
:
1747 case OPTYPE_MULTIPLY
:
1768 case OPTYPE_INT2BIT
:
1769 case OPTYPE_INT2HEX
:
1770 case OPTYPE_INT2OCT
:
1771 u
.expr
.v1
->set_my_scope(p_scope
);
1772 u
.expr
.v2
->set_my_scope(p_scope
);
1774 case OPTYPE_UNICHAR2OCT
:
1775 case OPTYPE_OCT2UNICHAR
:
1776 case OPTYPE_ENCODE_BASE64
:
1777 u
.expr
.v1
->set_my_scope(p_scope
);
1778 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1781 u
.expr
.r1
->set_my_scope(p_scope
);
1782 u
.expr
.r2
->set_my_scope(p_scope
);
1785 u
.expr
.ti1
->set_my_scope(p_scope
);
1786 u
.expr
.v2
->set_my_scope(p_scope
);
1787 u
.expr
.v3
->set_my_scope(p_scope
);
1790 u
.expr
.ti1
->set_my_scope(p_scope
);
1791 u
.expr
.t2
->set_my_scope(p_scope
);
1792 u
.expr
.v3
->set_my_scope(p_scope
);
1794 case OPTYPE_DECOMP
: // v1 v2 v3
1795 u
.expr
.v1
->set_my_scope(p_scope
);
1796 u
.expr
.v2
->set_my_scope(p_scope
);
1797 u
.expr
.v3
->set_my_scope(p_scope
);
1799 case OPTYPE_REPLACE
:
1800 u
.expr
.ti1
->set_my_scope(p_scope
);
1801 u
.expr
.v2
->set_my_scope(p_scope
);
1802 u
.expr
.v3
->set_my_scope(p_scope
);
1803 u
.expr
.ti4
->set_my_scope(p_scope
);
1805 case OPTYPE_LENGTHOF
: // ti1
1806 case OPTYPE_SIZEOF
: // ti1
1807 case OPTYPE_VALUEOF
: // ti1
1808 case OPTYPE_ISVALUE
:
1809 case OPTYPE_ISBOUND
:
1811 case OPTYPE_ISPRESENT
:
1812 case OPTYPE_TTCN2STRING
:
1813 u
.expr
.ti1
->set_my_scope(p_scope
);
1815 case OPTYPE_ENCVALUE_UNICHAR
: //ti1 [v2]
1816 u
.expr
.ti1
->set_my_scope(p_scope
);
1817 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1819 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
1820 u
.expr
.r1
->set_my_scope(p_scope
);
1821 u
.expr
.r2
->set_my_scope(p_scope
);
1822 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1824 case OPTYPE_UNDEF_RUNNING
: // r1
1825 case OPTYPE_TMR_READ
:
1826 case OPTYPE_TMR_RUNNING
:
1827 case OPTYPE_ACTIVATE
:
1828 u
.expr
.r1
->set_my_scope(p_scope
);
1830 case OPTYPE_EXECUTE
: // r1 [v2]
1831 u
.expr
.r1
->set_my_scope(p_scope
);
1832 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1834 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
1835 case OPTYPE_CHECKSTATE_ALL
:
1836 if(u
.expr
.r1
) u
.expr
.r1
->set_my_scope(p_scope
);
1837 u
.expr
.v2
->set_my_scope(p_scope
);
1839 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1840 u
.expr
.r1
->set_my_scope(p_scope
);
1841 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1842 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1844 case OPTYPE_MATCH
: // v1 t2
1845 u
.expr
.v1
->set_my_scope(p_scope
);
1846 u
.expr
.t2
->set_my_scope(p_scope
);
1848 case OPTYPE_ISCHOSEN
: // r1 i2
1849 u
.expr
.r1
->set_my_scope(p_scope
);
1851 case OPTYPE_ISCHOSEN_V
: // v1 i2
1852 u
.expr
.v1
->set_my_scope(p_scope
);
1854 case OPTYPE_ISCHOSEN_T
: // t1 i2
1855 u
.expr
.t1
->set_my_scope(p_scope
);
1857 case OPTYPE_ACTIVATE_REFD
:
1858 u
.expr
.v1
->set_my_scope(p_scope
);
1859 if(u
.expr
.state
!=EXPR_CHECKED
) {
1860 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1862 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1864 case OPTYPE_EXECUTE_REFD
:
1865 u
.expr
.v1
->set_my_scope(p_scope
);
1866 if(u
.expr
.state
!=EXPR_CHECKED
) {
1867 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1869 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1872 u
.expr
.v3
->set_my_scope(p_scope
);
1874 case OPTYPE_LOG2STR
:
1875 case OPTYPE_ANY2UNISTR
:
1876 u
.expr
.logargs
->set_my_scope(p_scope
);
1879 FATAL_ERROR("Value::set_my_scope_expr()");
1883 void Value::set_genname_recursive(const string
& p_genname
)
1885 size_t genname_len
= p_genname
.size();
1886 if (genname_len
>= 4 &&
1887 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1888 // if the genname ends with ()() (i.e. the value stands for an optional
1889 // field) then drop the last () from the own genname, but leave it for
1890 // the embedded values
1891 set_genname(p_genname
.substr(0, genname_len
- 2));
1892 } else set_genname(p_genname
);
1895 string
embedded_genname(p_genname
);
1896 embedded_genname
+= '.';
1897 // If this is a choice value for an anytype, prepend the AT_ prefix
1898 // to the name of the alternative. The genname is used later in
1899 // Common::Value::generate_code_init_se()
1900 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1901 embedded_genname
+= "AT_";
1902 embedded_genname
+= u
.choice
.alt_name
->get_name();
1903 embedded_genname
+= "()";
1904 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1908 if (!is_indexed()) {
1909 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1910 for (size_t i
= 0; i
< nof_vs
; i
++) {
1911 string
embedded_genname(p_genname
);
1912 embedded_genname
+= '[';
1913 embedded_genname
+= Int2string(i
);
1914 embedded_genname
+= ']';
1915 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1918 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1919 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1920 string
embedded_genname(p_genname
);
1921 embedded_genname
+= '[';
1922 embedded_genname
+= Int2string(i
);
1923 embedded_genname
+= ']';
1924 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1925 ->set_genname_recursive(embedded_genname
);
1930 if (!my_governor
) return; // error recovery
1931 Type
*type
= my_governor
->get_type_refd_last();
1932 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1933 Int offset
= type
->get_dimension()->get_offset();
1934 if (!is_indexed()) {
1935 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1936 for (size_t i
= 0; i
< nof_vs
; i
++) {
1937 string
embedded_genname(p_genname
);
1938 embedded_genname
+= '[';
1939 embedded_genname
+= Int2string(offset
+ i
);
1940 embedded_genname
+= ']';
1941 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1944 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1945 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1946 string
embedded_genname(p_genname
);
1947 embedded_genname
+= '[';
1948 embedded_genname
+= Int2string(offset
+ i
);
1949 embedded_genname
+= ']';
1950 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1951 ->set_genname_recursive(embedded_genname
);
1957 if (!my_governor
) return; // error recovery
1958 Type
*t
= my_governor
->get_type_refd_last();
1959 if (!t
->is_secho()) return; // error recovery
1960 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1961 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1962 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1963 const Identifier
& id
= nv
->get_name();
1964 if (!t
->has_comp_withName(id
)) return; // error recovery
1965 string
embedded_genname(p_genname
);
1966 embedded_genname
+= '.';
1967 embedded_genname
+= id
.get_name();
1968 embedded_genname
+= "()";
1969 if (t
->get_comp_byName(id
)->get_is_optional())
1970 embedded_genname
+= "()";
1971 nv
->get_value()->set_genname_recursive(embedded_genname
);
1979 void Value::set_genname_prefix(const char *p_genname_prefix
)
1981 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1984 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1989 if (!is_indexed()) {
1990 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1991 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1993 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1994 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1995 ->set_genname_prefix(p_genname_prefix
);
2000 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2001 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2002 ->set_genname_prefix(p_genname_prefix
);
2009 void Value::set_code_section(code_section_t p_code_section
)
2011 GovernedSimple::set_code_section(p_code_section
);
2014 switch (u
.expr
.v_optype
) {
2015 case OPTYPE_RND
: // -
2016 case OPTYPE_COMP_NULL
:
2017 case OPTYPE_COMP_MTC
:
2018 case OPTYPE_COMP_SYSTEM
:
2019 case OPTYPE_COMP_SELF
:
2020 case OPTYPE_COMP_RUNNING_ANY
:
2021 case OPTYPE_COMP_RUNNING_ALL
:
2022 case OPTYPE_COMP_ALIVE_ANY
:
2023 case OPTYPE_COMP_ALIVE_ALL
:
2024 case OPTYPE_TMR_RUNNING_ANY
:
2025 case OPTYPE_GETVERDICT
:
2026 case OPTYPE_TESTCASENAME
:
2027 case OPTYPE_PROF_RUNNING
:
2029 case OPTYPE_UNARYPLUS
: // v1
2030 case OPTYPE_UNARYMINUS
:
2033 case OPTYPE_BIT2HEX
:
2034 case OPTYPE_BIT2INT
:
2035 case OPTYPE_BIT2OCT
:
2036 case OPTYPE_BIT2STR
:
2037 case OPTYPE_CHAR2INT
:
2038 case OPTYPE_CHAR2OCT
:
2039 case OPTYPE_COMP_RUNNING
:
2040 case OPTYPE_COMP_ALIVE
:
2041 case OPTYPE_FLOAT2INT
:
2042 case OPTYPE_FLOAT2STR
:
2043 case OPTYPE_HEX2BIT
:
2044 case OPTYPE_HEX2INT
:
2045 case OPTYPE_HEX2OCT
:
2046 case OPTYPE_HEX2STR
:
2047 case OPTYPE_INT2CHAR
:
2048 case OPTYPE_INT2FLOAT
:
2049 case OPTYPE_INT2STR
:
2050 case OPTYPE_INT2UNICHAR
:
2051 case OPTYPE_OCT2BIT
:
2052 case OPTYPE_OCT2CHAR
:
2053 case OPTYPE_OCT2HEX
:
2054 case OPTYPE_OCT2INT
:
2055 case OPTYPE_OCT2STR
:
2056 case OPTYPE_STR2BIT
:
2057 case OPTYPE_STR2FLOAT
:
2058 case OPTYPE_STR2HEX
:
2059 case OPTYPE_STR2INT
:
2060 case OPTYPE_STR2OCT
:
2061 case OPTYPE_UNICHAR2INT
:
2062 case OPTYPE_UNICHAR2CHAR
:
2063 case OPTYPE_ENUM2INT
:
2064 case OPTYPE_RNDWITHVAL
:
2065 case OPTYPE_GET_STRINGENCODING
:
2066 case OPTYPE_DECODE_BASE64
:
2067 case OPTYPE_REMOVE_BOM
:
2068 u
.expr
.v1
->set_code_section(p_code_section
);
2070 case OPTYPE_HOSTID
: // [v1]
2071 if(u
.expr
.v1
) u
.expr
.v1
->set_code_section(p_code_section
);
2073 case OPTYPE_ADD
: // v1 v2
2074 case OPTYPE_SUBTRACT
:
2075 case OPTYPE_MULTIPLY
:
2096 case OPTYPE_INT2BIT
:
2097 case OPTYPE_INT2HEX
:
2098 case OPTYPE_INT2OCT
:
2099 u
.expr
.v1
->set_code_section(p_code_section
);
2100 u
.expr
.v2
->set_code_section(p_code_section
);
2102 case OPTYPE_UNICHAR2OCT
:
2103 case OPTYPE_OCT2UNICHAR
:
2104 case OPTYPE_ENCODE_BASE64
:
2105 u
.expr
.v1
->set_code_section(p_code_section
);
2106 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2109 u
.expr
.r1
->set_code_section(p_code_section
);
2110 u
.expr
.r2
->set_code_section(p_code_section
);
2113 u
.expr
.ti1
->set_code_section(p_code_section
);
2114 u
.expr
.v2
->set_code_section(p_code_section
);
2115 u
.expr
.v3
->set_code_section(p_code_section
);
2118 u
.expr
.ti1
->set_code_section(p_code_section
);
2119 u
.expr
.t2
->set_code_section(p_code_section
);
2120 u
.expr
.v3
->set_code_section(p_code_section
);
2122 case OPTYPE_DECOMP
: // v1 v2 v3
2123 u
.expr
.v1
->set_code_section(p_code_section
);
2124 u
.expr
.v2
->set_code_section(p_code_section
);
2125 u
.expr
.v3
->set_code_section(p_code_section
);
2127 case OPTYPE_REPLACE
:
2128 u
.expr
.ti1
->set_code_section(p_code_section
);
2129 u
.expr
.v2
->set_code_section(p_code_section
);
2130 u
.expr
.v3
->set_code_section(p_code_section
);
2131 u
.expr
.ti4
->set_code_section(p_code_section
);
2133 case OPTYPE_LENGTHOF
: // ti1
2134 case OPTYPE_SIZEOF
: // ti1
2135 case OPTYPE_VALUEOF
: // ti1
2136 case OPTYPE_ISVALUE
:
2137 case OPTYPE_ISBOUND
:
2139 case OPTYPE_ISPRESENT
:
2140 case OPTYPE_TTCN2STRING
:
2141 u
.expr
.ti1
->set_code_section(p_code_section
);
2143 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
2144 u
.expr
.ti1
->set_code_section(p_code_section
);
2145 if (u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2147 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
2148 u
.expr
.r1
->set_code_section(p_code_section
);
2149 u
.expr
.r2
->set_code_section(p_code_section
);
2150 if (u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2152 case OPTYPE_UNDEF_RUNNING
: // r1
2153 case OPTYPE_TMR_READ
:
2154 case OPTYPE_TMR_RUNNING
:
2155 case OPTYPE_ACTIVATE
:
2156 u
.expr
.r1
->set_code_section(p_code_section
);
2158 case OPTYPE_EXECUTE
: // r1 [v2]
2159 u
.expr
.r1
->set_code_section(p_code_section
);
2160 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2162 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
2163 case OPTYPE_CHECKSTATE_ALL
:
2164 if(u
.expr
.r1
) u
.expr
.r1
->set_code_section(p_code_section
);
2165 u
.expr
.v2
->set_code_section(p_code_section
);
2167 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2168 u
.expr
.r1
->set_code_section(p_code_section
);
2169 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2170 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2172 case OPTYPE_MATCH
: // v1 t2
2173 u
.expr
.v1
->set_code_section(p_code_section
);
2174 u
.expr
.t2
->set_code_section(p_code_section
);
2176 case OPTYPE_ISCHOSEN
: // r1 i2
2177 u
.expr
.r1
->set_code_section(p_code_section
);
2179 case OPTYPE_ISCHOSEN_V
: // v1 i2
2180 u
.expr
.v1
->set_code_section(p_code_section
);
2182 case OPTYPE_ISCHOSEN_T
: // t1 i2
2183 u
.expr
.t1
->set_code_section(p_code_section
);
2185 case OPTYPE_ACTIVATE_REFD
:
2186 u
.expr
.v1
->set_code_section(p_code_section
);
2187 if(u
.expr
.state
!=EXPR_CHECKED
)
2188 u
.expr
.t_list2
->set_code_section(p_code_section
);
2190 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2191 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2192 u
.expr
.state
= EXPR_CHECKED
;
2195 case OPTYPE_EXECUTE_REFD
:
2196 u
.expr
.v1
->set_code_section(p_code_section
);
2197 if(u
.expr
.state
!=EXPR_CHECKED
)
2198 u
.expr
.t_list2
->set_code_section(p_code_section
);
2200 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2201 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2202 u
.expr
.state
= EXPR_CHECKED
;
2205 u
.expr
.v3
->set_code_section(p_code_section
);
2207 case OPTYPE_LOG2STR
:
2208 case OPTYPE_ANY2UNISTR
:
2209 u
.expr
.logargs
->set_code_section(p_code_section
);
2212 FATAL_ERROR("Value::set_code_section()");
2216 u
.choice
.alt_value
->set_code_section(p_code_section
);
2221 if (!is_indexed()) {
2222 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2223 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2225 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2226 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2231 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2232 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2233 ->set_code_section(p_code_section
);
2236 u
.ref
.ref
->set_code_section(p_code_section
);
2239 u
.refered
->set_code_section(p_code_section
);
2242 u
.invoke
.v
->set_code_section(p_code_section
);
2243 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2244 if(u
.invoke
.ap_list
)
2245 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2246 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2253 void Value::change_sign()
2257 *u
.val_Int
=-*u
.val_Int
;
2265 FATAL_ERROR("Value::change_sign()");
2269 void Value::add_oid_comp(OID_comp
* p_comp
)
2272 FATAL_ERROR("NULL parameter");
2273 u
.oid_comps
->add(p_comp
);
2274 p_comp
->set_fullname(get_fullname()+"."
2275 +Int2string(u
.oid_comps
->size()));
2276 p_comp
->set_my_scope(my_scope
);
2279 void Value::set_valuetype(valuetype_t p_valuetype
)
2281 if (valuetype
== V_ERROR
) return;
2282 else if (p_valuetype
== V_ERROR
) {
2283 if(valuetype
==V_EXPR
) {
2284 switch(u
.expr
.state
) {
2286 u
.expr
.state
=EXPR_CHECKING_ERR
;
2288 case EXPR_CHECKING_ERR
:
2295 valuetype
= V_ERROR
;
2299 case V_UNDEF_LOWERID
:
2300 switch(p_valuetype
) {
2305 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2306 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2307 u
.ref
.ref
->set_my_scope(get_my_scope());
2308 u
.ref
.ref
->set_fullname(get_fullname());
2309 u
.ref
.ref
->set_location(*this);
2310 u
.ref
.refd_last
= 0;
2313 FATAL_ERROR("Value::set_valuetype()");
2316 case V_UNDEF_BLOCK
: {
2317 Block
*t_block
=u
.block
;
2319 switch(p_valuetype
) {
2321 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2322 v
=dynamic_cast<Value
*>(node
);
2325 u
.ids
=new map
<string
, Identifier
>();
2328 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2332 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2333 v
=dynamic_cast<Value
*>(node
);
2336 u
.val_vs
=new Values();
2339 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2341 u
.val_vs
->set_my_scope(get_my_scope());
2342 u
.val_vs
->set_fullname(get_fullname());
2345 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2346 v
=dynamic_cast<Value
*>(node
);
2349 u
.val_vs
=new Values();
2352 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2354 u
.val_vs
->set_my_scope(get_my_scope());
2355 u
.val_vs
->set_fullname(get_fullname());
2358 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2359 v
=dynamic_cast<Value
*>(node
);
2362 u
.val_nvs
=new NamedValues();
2365 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2367 u
.val_nvs
->set_my_scope(get_my_scope());
2368 u
.val_nvs
->set_fullname(get_fullname());
2371 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2372 v
=dynamic_cast<Value
*>(node
);
2375 u
.val_nvs
=new NamedValues();
2378 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2380 u
.val_nvs
->set_my_scope(get_my_scope());
2381 u
.val_nvs
->set_fullname(get_fullname());
2384 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2385 v
=dynamic_cast<Value
*>(node
);
2388 u
.oid_comps
=new vector
<OID_comp
>();
2391 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2393 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2394 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2397 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2398 v
=dynamic_cast<Value
*>(node
);
2401 u
.oid_comps
=new vector
<OID_comp
>();
2404 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2406 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2407 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2410 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2411 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2414 u
.char_syms
=new CharSyms();
2416 u
.char_syms
->set_my_scope(get_my_scope());
2417 u
.char_syms
->set_fullname(get_fullname());
2420 FATAL_ERROR("Value::set_valuetype()");
2426 if (p_valuetype
== V_USTR
) {
2427 Value
*v_last
= get_value_refd_last();
2428 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2429 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2432 u
.ustr
.convert_str
= true; // will be converted back to string
2433 } else FATAL_ERROR("Value::set_valuetype()");
2436 switch(p_valuetype
) {
2438 const string
& str
= u
.char_syms
->get_string();
2440 set_val_str(new string(str
));
2443 const ustring
& ustr
= u
.char_syms
->get_ustring();
2445 set_val_ustr(new ustring(ustr
));
2446 u
.ustr
.convert_str
= false;
2448 case V_ISO2022STR
: {
2449 const string
& str
= u
.char_syms
->get_iso2022string();
2451 set_val_str(new string(str
));
2454 FATAL_ERROR("Value::set_valuetype()");
2459 if (p_valuetype
== V_REAL
)
2460 val_Real
= u
.val_Int
->to_real();
2461 else FATAL_ERROR("Value::set_valuetype()");
2463 u
.val_Real
= val_Real
;
2466 clean_up_string_elements(u
.str
.str_elements
);
2467 string
*old_str
= u
.str
.val_str
;
2468 switch(p_valuetype
) {
2470 set_val_str(hex2bit(*old_str
));
2473 set_val_str(asn_hex2oct(*old_str
));
2476 FATAL_ERROR("Value::set_valuetype()");
2481 clean_up_string_elements(u
.str
.str_elements
);
2482 if (p_valuetype
== V_OSTR
) {
2483 string
*old_str
= u
.str
.val_str
;
2484 set_val_str(asn_bit2oct(*old_str
));
2486 } else FATAL_ERROR("Value::set_valuetype()");
2489 clean_up_string_elements(u
.str
.str_elements
);
2490 switch(p_valuetype
) {
2492 string
*old_str
= u
.str
.val_str
;
2493 set_val_ustr(new ustring(*old_str
));
2494 u
.ustr
.convert_str
= true; // will be converted back to string
2501 FATAL_ERROR("Value::set_valuetype()");
2502 } // switch p_valuetype
2505 clean_up_string_elements(u
.ustr
.ustr_elements
);
2506 switch(p_valuetype
) {
2508 ustring
*old_str
= u
.ustr
.val_ustr
;
2509 size_t nof_chars
= old_str
->size();
2510 bool warning_flag
= false;
2511 for (size_t i
= 0; i
< nof_chars
; i
++) {
2512 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2513 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2514 error("This string value cannot contain multiple-byte characters, "
2515 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2516 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2518 p_valuetype
= V_ERROR
;
2520 } else if (uchar
.cell
> 127 && !warning_flag
) {
2521 warning("This string value may not contain characters with code "
2522 "higher than 127, but it has character with code %u (0x%02X) "
2523 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2524 warning_flag
= true;
2527 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2531 error("ISO-10646 string value cannot be converted to "
2533 delete u
.ustr
.val_ustr
;
2534 p_valuetype
= V_ERROR
;
2537 FATAL_ERROR("Value::set_valuetype()");
2538 } // switch p_valuetype
2541 switch (p_valuetype
) {
2543 NamedValues
*nvs
= u
.val_nvs
;
2544 if (nvs
->get_nof_nvs() < 1) {
2545 error("Union value must have one active field");
2547 valuetype
= V_ERROR
;
2549 } else if (nvs
->get_nof_nvs() > 1) {
2550 error("Only one field was expected in union value instead of %lu",
2551 (unsigned long) nvs
->get_nof_nvs());
2553 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2554 u
.choice
.alt_name
= nv
->get_name().clone();
2555 u
.choice
.alt_value
= nv
->steal_value();
2562 NamedValues
*nvs
= u
.val_nvs
;
2566 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2567 if (nvs
->has_nv_withName(id_mant
)) {
2568 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2569 ->get_value_refd_last();
2570 if (v_tmp
->get_valuetype() == V_INT
) {
2571 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2572 if (*i_mant_int
> INT_MAX
) {
2573 error("Mantissa `%s' should be less than `%d'",
2574 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2577 i_mant
= i_mant_int
->get_val();
2585 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2586 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2587 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2588 Value
*v_tmp
= v
->get_value_refd_last();
2589 if (v_tmp
->get_valuetype() == V_INT
) {
2590 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2591 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2592 v
->error("Base of the REAL must be 2 or 10");
2595 i_base
= i_base_int
->get_val();
2603 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2604 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2605 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2606 ->get_value_refd_last();
2607 if (v_tmp
->get_valuetype() == V_INT
) {
2608 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2609 if (*i_exp_int
> INT_MAX
) {
2610 error("Exponent `%s' should be less than `%d'",
2611 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2614 i_exp
= i_exp_int
->get_val();
2623 valuetype
= V_ERROR
;
2626 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2627 static_cast<double>(i_exp
));
2633 FATAL_ERROR("Value::set_valuetype()");
2637 switch (p_valuetype
) {
2639 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2640 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2641 Type
*t
= my_governor
->get_type_refd_last();
2642 switch (t
->get_typetype()) {
2647 FATAL_ERROR("Value::set_valuetype()");
2649 Values
*vals
= u
.val_vs
;
2650 size_t nof_vals
= vals
->get_nof_vs();
2651 size_t nof_comps
= t
->get_nof_comps();
2652 if (nof_vals
> nof_comps
) {
2653 error("Too many elements in value list notation for type `%s': "
2654 "%lu was expected instead of %lu",
2655 t
->get_typename().c_str(),
2656 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2660 if (nof_vals
<= nof_comps
) {
2661 upper_limit
= nof_vals
;
2664 upper_limit
= nof_comps
;
2667 u
.val_nvs
= new NamedValues
;
2668 for (size_t i
= 0; i
< upper_limit
; i
++) {
2669 Value
*v
= vals
->steal_v_byIndex(i
);
2670 if (v
->valuetype
!= V_NOTUSED
) {
2674 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2675 nv
->set_location(*v
);
2676 u
.val_nvs
->add_nv(nv
);
2678 u
.val_nvs
->set_my_scope(get_my_scope());
2679 u
.val_nvs
->set_fullname(get_fullname());
2681 if (allnotused
&& nof_vals
> 0)
2682 warning("All elements of value list notation for type `%s' are not "
2683 "used symbols (`-')", t
->get_typename().c_str());
2686 // { } -> empty set value
2687 if (u
.val_vs
->get_nof_vs() != 0)
2688 FATAL_ERROR("Value::set_valuetype()");
2690 u
.val_nvs
= new NamedValues
;
2694 // SEQOF -> SETOF or ARRAY: trivial
2697 FATAL_ERROR("Value::set_valuetype()");
2702 if (p_valuetype
== V_NOTUSED
) {
2706 FATAL_ERROR("Value::set_valuetype()");
2710 switch (p_valuetype
) {
2711 case V_DEFAULT_NULL
:
2716 FATAL_ERROR("Value::set_valuetype()");
2720 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2721 FATAL_ERROR("Value::set_valuetype()");
2725 FATAL_ERROR("Value::set_valuetype()");
2727 valuetype
=p_valuetype
;
2730 void Value::set_valuetype_COMP_NULL()
2732 if(valuetype
== V_ERROR
) return;
2733 if(valuetype
==V_TTCN3_NULL
) {
2735 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2736 // Nothing to check.
2737 u
.expr
.state
=EXPR_CHECKED
;
2739 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2742 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2744 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2746 u
.val_Int
= new int_val_t(p_val_int
);
2748 } else FATAL_ERROR("Value::set_valuetype()");
2751 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2753 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2757 } else FATAL_ERROR("Value::set_valuetype()");
2760 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2762 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2766 } else FATAL_ERROR("Value::set_valuetype()");
2769 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2771 switch (p_valuetype
) {
2775 if (valuetype
== V_REFER
&& p_ass
) break;
2778 FATAL_ERROR("Value::set_valuetype()");
2782 valuetype
= p_valuetype
;
2785 bool Value::is_undef_lowerid()
2787 switch (valuetype
) {
2788 case V_UNDEF_LOWERID
:
2791 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2792 !u
.expr
.ti1
->get_DerivedRef()) {
2793 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2801 const Identifier
& Value::get_undef_lowerid()
2803 switch (valuetype
) {
2804 case V_UNDEF_LOWERID
:
2807 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2808 FATAL_ERROR("Value::get_undef_lowerid()");
2809 return u
.expr
.ti1
->get_Template()->get_specific_value()
2810 ->get_undef_lowerid();
2812 FATAL_ERROR("Value::get_undef_lowerid()");
2814 const Identifier
*dummy
= 0;
2818 void Value::set_lowerid_to_ref()
2820 switch (valuetype
) {
2821 case V_UNDEF_LOWERID
:
2822 set_valuetype(V_REFD
);
2825 // if the governor of the expression is not known (in log(), etc...)
2826 // then the governor is taken from the reference (using
2827 // v1/ti1->get_expr_governor()), but that runs before the
2828 // params were checked, this smells like a workaround :)
2829 switch (u
.expr
.v_optype
) {
2832 u
.expr
.v1
->set_lowerid_to_ref();
2835 u
.expr
.v1
->set_lowerid_to_ref();
2836 u
.expr
.v2
->set_lowerid_to_ref();
2838 case OPTYPE_VALUEOF
:
2839 case OPTYPE_ISVALUE
:
2840 case OPTYPE_ISBOUND
:
2841 case OPTYPE_ISPRESENT
:
2844 case OPTYPE_REPLACE
:
2845 case OPTYPE_TTCN2STRING
:
2846 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2847 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2848 "In the operand of operation `%s'",
2850 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2852 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2853 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2854 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2855 "In the operand of operation `%s'",
2857 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2860 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2861 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2862 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2863 "In the operand of operation `%s'",
2865 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2878 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2880 switch (valuetype
) {
2888 case V_UNDEF_LOWERID
:
2895 return Type::T_UNDEF
;
2899 FATAL_ERROR("Value::get_expr_returntype()");
2901 return Type::T_ERROR
;
2904 Type
*t
= get_expr_governor(exp_val
);
2905 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2906 else return Type::T_ERROR
; }
2908 return Type::T_FUNCTION
;
2910 return Type::T_ALTSTEP
;
2912 return Type::T_TESTCASE
;
2914 switch(u
.expr
.v_optype
) {
2915 case OPTYPE_COMP_NULL
:
2916 case OPTYPE_COMP_MTC
:
2917 case OPTYPE_COMP_SYSTEM
:
2918 case OPTYPE_COMP_SELF
:
2919 case OPTYPE_COMP_CREATE
:
2920 return Type::T_COMPONENT
;
2921 case OPTYPE_UNDEF_RUNNING
:
2922 case OPTYPE_COMP_RUNNING
:
2923 case OPTYPE_COMP_RUNNING_ANY
:
2924 case OPTYPE_COMP_RUNNING_ALL
:
2925 case OPTYPE_COMP_ALIVE
:
2926 case OPTYPE_COMP_ALIVE_ANY
:
2927 case OPTYPE_COMP_ALIVE_ALL
:
2928 case OPTYPE_TMR_RUNNING
:
2929 case OPTYPE_TMR_RUNNING_ANY
:
2941 case OPTYPE_ISPRESENT
:
2942 case OPTYPE_ISCHOSEN
:
2943 case OPTYPE_ISCHOSEN_V
:
2944 case OPTYPE_ISCHOSEN_T
:
2945 case OPTYPE_ISVALUE
:
2946 case OPTYPE_ISBOUND
:
2947 case OPTYPE_PROF_RUNNING
:
2948 case OPTYPE_CHECKSTATE_ANY
:
2949 case OPTYPE_CHECKSTATE_ALL
:
2950 return Type::T_BOOL
;
2951 case OPTYPE_GETVERDICT
:
2952 return Type::T_VERDICT
;
2953 case OPTYPE_VALUEOF
: {
2954 Error_Context
cntxt(this, "In the operand of operation `%s'",
2956 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2957 case OPTYPE_TMR_READ
:
2958 case OPTYPE_INT2FLOAT
:
2959 case OPTYPE_STR2FLOAT
:
2961 case OPTYPE_RNDWITHVAL
:
2962 return Type::T_REAL
;
2963 case OPTYPE_ACTIVATE
:
2964 return Type::T_DEFAULT
;
2965 case OPTYPE_ACTIVATE_REFD
:
2966 return Type::T_DEFAULT
;
2967 case OPTYPE_EXECUTE
:
2968 case OPTYPE_EXECUTE_REFD
:
2969 return Type::T_VERDICT
;
2970 case OPTYPE_UNARYPLUS
: // v1
2971 case OPTYPE_UNARYMINUS
: {
2972 Type::typetype_t tmp_tt
;
2974 Error_Context
cntxt(this, "In the operand of operation `%s'",
2976 u
.expr
.v1
->set_lowerid_to_ref();
2977 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2984 get_value_refd_last(); // to report the error
2985 return Type::T_ERROR
;
2988 case OPTYPE_ADD
: // v1 v2
2989 case OPTYPE_SUBTRACT
:
2990 case OPTYPE_MULTIPLY
:
2991 case OPTYPE_DIVIDE
: {
2992 Type::typetype_t tmp_tt
;
2994 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2996 u
.expr
.v1
->set_lowerid_to_ref();
2997 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3004 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
3005 Type::typetype_t tmp_tt2
;
3007 Error_Context
cntxt(this, "In the right operand of operation `%s'",
3009 u
.expr
.v2
->set_lowerid_to_ref();
3010 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
3012 Type::typetype_t ret_val
=Type::T_ERROR
;
3013 bool maybeconcat
=false;
3018 if(tmp_tt2
==tmp_tt
) {
3025 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
3027 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
3028 ret_val
=Type::T_USTR
;
3029 else ret_val
=Type::T_CSTR
;
3036 error("Did you mean the concat operation (`&') instead of"
3037 " addition operator (`+')?");
3038 u
.expr
.v_optype
=OPTYPE_CONCAT
;
3042 get_value_refd_last(); // to report the error
3043 return Type::T_ERROR
;
3046 case OPTYPE_NOT4B
: // v1
3047 case OPTYPE_AND4B
: // v1 v2
3052 Type::typetype_t tmp_tt
;
3054 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
3055 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
3057 u
.expr
.v1
->set_lowerid_to_ref();
3058 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3066 get_value_refd_last(); // to report the error
3067 return Type::T_ERROR
;
3070 case OPTYPE_ROTL
: // v1 v2
3072 Type::typetype_t tmp_tt
;
3074 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
3075 u
.expr
.v_optype
==OPTYPE_ROTL
3076 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
3078 u
.expr
.v1
->set_lowerid_to_ref();
3079 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3092 get_value_refd_last(); // to report the error
3093 return Type::T_ERROR
;
3097 case OPTYPE_REPLACE
: {
3098 Type::typetype_t tmp_tt
;
3100 Error_Context
cntxt(this, "In the operand of operation `%s'",
3102 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3103 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3115 get_value_refd_last(); // to report the error
3116 return Type::T_ERROR
;
3119 case OPTYPE_REGEXP
: {
3120 Type::typetype_t tmp_tt
;
3122 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3124 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
3125 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
3132 get_value_refd_last(); // to report the error
3133 return Type::T_ERROR
;
3136 case OPTYPE_CONCAT
: { // v1 v2
3137 Type::typetype_t tmp_tt
;
3139 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3141 u
.expr
.v1
->set_lowerid_to_ref();
3142 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3154 get_value_refd_last(); // to report the error
3155 return Type::T_ERROR
;
3160 case OPTYPE_CHAR2INT
:
3161 case OPTYPE_UNICHAR2INT
:
3162 case OPTYPE_BIT2INT
:
3163 case OPTYPE_HEX2INT
:
3164 case OPTYPE_OCT2INT
:
3165 case OPTYPE_STR2INT
:
3166 case OPTYPE_FLOAT2INT
:
3167 case OPTYPE_LENGTHOF
:
3170 case OPTYPE_ENUM2INT
:
3171 case OPTYPE_DECVALUE_UNICHAR
:
3173 case OPTYPE_BIT2STR
:
3174 case OPTYPE_FLOAT2STR
:
3175 case OPTYPE_HEX2STR
:
3176 case OPTYPE_INT2CHAR
:
3177 case OPTYPE_INT2STR
:
3178 case OPTYPE_OCT2CHAR
:
3179 case OPTYPE_OCT2STR
:
3180 case OPTYPE_UNICHAR2CHAR
:
3181 case OPTYPE_LOG2STR
:
3182 case OPTYPE_TESTCASENAME
:
3183 case OPTYPE_TTCN2STRING
:
3184 case OPTYPE_GET_STRINGENCODING
:
3185 case OPTYPE_ENCODE_BASE64
:
3187 return Type::T_CSTR
;
3188 case OPTYPE_INT2UNICHAR
:
3189 case OPTYPE_OCT2UNICHAR
:
3190 case OPTYPE_ENCVALUE_UNICHAR
:
3191 case OPTYPE_ANY2UNISTR
:
3192 return Type::T_USTR
;
3193 case OPTYPE_INT2BIT
:
3194 case OPTYPE_HEX2BIT
:
3195 case OPTYPE_OCT2BIT
:
3196 case OPTYPE_STR2BIT
:
3198 return Type::T_BSTR
;
3199 case OPTYPE_INT2HEX
:
3200 case OPTYPE_BIT2HEX
:
3201 case OPTYPE_OCT2HEX
:
3202 case OPTYPE_STR2HEX
:
3203 return Type::T_HSTR
;
3204 case OPTYPE_INT2OCT
:
3205 case OPTYPE_CHAR2OCT
:
3206 case OPTYPE_HEX2OCT
:
3207 case OPTYPE_BIT2OCT
:
3208 case OPTYPE_STR2OCT
:
3209 case OPTYPE_UNICHAR2OCT
:
3210 case OPTYPE_REMOVE_BOM
:
3211 case OPTYPE_DECODE_BASE64
:
3212 return Type::T_OSTR
;
3216 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3218 return Type::T_ERROR
;
3222 case MACRO_MODULEID
:
3223 case MACRO_FILENAME
:
3224 case MACRO_BFILENAME
:
3225 case MACRO_FILEPATH
:
3226 case MACRO_LINENUMBER
:
3227 case MACRO_DEFINITIONID
:
3229 case MACRO_TESTCASEID
:
3230 return Type::T_CSTR
;
3231 case MACRO_LINENUMBER_C
:
3234 return Type::T_ERROR
;
3237 return Type::T_NULL
;
3239 return Type::T_BOOL
;
3243 return Type::T_REAL
;
3245 return Type::T_ENUM_T
;
3247 return Type::T_BSTR
;
3249 return Type::T_HSTR
;
3251 return Type::T_OSTR
;
3253 return Type::T_CSTR
;
3255 return Type::T_USTR
;
3257 return Type::T_GENERALSTRING
;
3261 return Type::T_ROID
;
3263 return Type::T_VERDICT
;
3264 case V_DEFAULT_NULL
:
3265 return Type::T_DEFAULT
;
3267 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3269 return Type::T_ERROR
;
3273 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3275 if(my_governor
) return my_governor
;
3276 switch (valuetype
) {
3278 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3280 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3281 u
.invoke
.v
->error("A value of type function expected");
3284 t
= t
->get_type_refd_last();
3285 switch(t
->get_typetype()) {
3286 case Type::T_FUNCTION
: {
3287 Type
*t_return_type
= t
->get_function_return_type();
3288 if (!t_return_type
) {
3289 error("Reference to a %s was expected instead of invocation "
3290 "of behavior type `%s' with no return type",
3291 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3292 t
->get_fullname().c_str());
3295 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3296 error("Reference to a value was expected, but functions of type "
3297 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3298 t_return_type
->get_typename().c_str());
3301 return t_return_type
; }
3302 case Type::T_ALTSTEP
:
3305 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3306 t
->get_typename().c_str());
3311 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3313 if (!ass
) goto error
;
3314 switch (ass
->get_asstype()) {
3315 case Assignment::A_CONST
:
3316 case Assignment::A_EXT_CONST
:
3317 case Assignment::A_MODULEPAR
:
3318 case Assignment::A_MODULEPAR_TEMP
:
3319 case Assignment::A_TEMPLATE
:
3320 case Assignment::A_VAR
:
3321 case Assignment::A_VAR_TEMPLATE
:
3322 case Assignment::A_FUNCTION_RVAL
:
3323 case Assignment::A_FUNCTION_RTEMP
:
3324 case Assignment::A_EXT_FUNCTION_RVAL
:
3325 case Assignment::A_EXT_FUNCTION_RTEMP
:
3326 case Assignment::A_PAR_VAL_IN
:
3327 case Assignment::A_PAR_VAL_OUT
:
3328 case Assignment::A_PAR_VAL_INOUT
:
3329 case Assignment::A_PAR_TEMPL_IN
:
3330 case Assignment::A_PAR_TEMPL_OUT
:
3331 case Assignment::A_PAR_TEMPL_INOUT
:
3332 tmp_type
=ass
->get_Type();
3334 case Assignment::A_FUNCTION
:
3335 case Assignment::A_EXT_FUNCTION
:
3336 error("Reference to a %s was expected instead of a call of %s, which "
3337 "does not have return type",
3338 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3339 ass
->get_description().c_str());
3342 error("Reference to a %s was expected instead of %s",
3343 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3344 ass
->get_description().c_str());
3347 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3348 if(!tmp_type
) goto error
;
3351 switch (u
.expr
.v_optype
) {
3352 case OPTYPE_VALUEOF
:
3355 case OPTYPE_REPLACE
:{
3356 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3357 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3358 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3363 return u
.expr
.v1
->get_expr_governor(exp_val
);
3365 return get_expr_governor_v1v2(exp_val
);
3366 case OPTYPE_COMP_MTC
:
3367 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3369 case OPTYPE_COMP_SYSTEM
:
3370 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3372 case OPTYPE_COMP_SELF
:
3374 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3375 if (t_ros
) return t_ros
->get_component_type();
3378 case OPTYPE_COMP_CREATE
:
3379 return chk_expr_operand_comptyperef_create();
3385 return Type::get_pooltype(get_expr_returntype(exp_val
));
3388 set_valuetype(V_ERROR
);
3392 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3394 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3395 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3397 if (v2_gov
) { // both have governors
3398 // return the type that is compatible with both (if there is no type mismatch)
3399 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3402 } else return v1_gov
;
3403 } else { // v1 has no governor
3404 if (v2_gov
) return v2_gov
;
3405 else return NULL
; // neither has governor
3409 Type
*Value::get_expr_governor_last()
3411 Value
*v_last
= get_value_refd_last();
3412 if (v_last
->valuetype
== V_ERROR
) return 0;
3413 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3415 return t
->get_type_refd_last();
3418 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3420 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3421 return u
.invoke
.v
->get_expr_governor(exp_val
);
3424 const char* Value::get_opname() const
3426 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3427 switch(u
.expr
.v_optype
) {
3428 case OPTYPE_RND
: // -
3430 case OPTYPE_COMP_NULL
:
3431 return "(component) null";
3432 case OPTYPE_COMP_MTC
:
3434 case OPTYPE_COMP_SYSTEM
:
3436 case OPTYPE_COMP_SELF
:
3438 case OPTYPE_COMP_RUNNING_ANY
:
3439 return "any component.running";
3440 case OPTYPE_COMP_RUNNING_ALL
:
3441 return "all component.running";
3442 case OPTYPE_COMP_ALIVE_ANY
:
3443 return "any component.alive";
3444 case OPTYPE_COMP_ALIVE_ALL
:
3445 return "all component.alive";
3446 case OPTYPE_TMR_RUNNING_ANY
:
3447 return "any timer.running";
3448 case OPTYPE_GETVERDICT
:
3449 return "getverdict()";
3450 case OPTYPE_TESTCASENAME
:
3451 return "testcasename()";
3452 case OPTYPE_CHECKSTATE_ANY
:
3454 return "port.checkstate()";
3456 return "any port.checkstate()";
3458 case OPTYPE_CHECKSTATE_ALL
:
3460 return "port.checkstate()";
3462 return "all port.checkstate()";
3464 case OPTYPE_UNARYPLUS
: // v1
3466 case OPTYPE_UNARYMINUS
:
3472 case OPTYPE_BIT2HEX
:
3474 case OPTYPE_BIT2INT
:
3476 case OPTYPE_BIT2OCT
:
3478 case OPTYPE_BIT2STR
:
3480 case OPTYPE_CHAR2INT
:
3481 return "char2int()";
3482 case OPTYPE_CHAR2OCT
:
3483 return "char2oct()";
3484 case OPTYPE_FLOAT2INT
:
3485 return "float2int()";
3486 case OPTYPE_FLOAT2STR
:
3487 return "float2str()";
3488 case OPTYPE_HEX2BIT
:
3490 case OPTYPE_HEX2INT
:
3492 case OPTYPE_HEX2OCT
:
3494 case OPTYPE_HEX2STR
:
3496 case OPTYPE_INT2CHAR
:
3497 return "int2char()";
3498 case OPTYPE_INT2FLOAT
:
3499 return "int2float()";
3500 case OPTYPE_INT2STR
:
3502 case OPTYPE_INT2UNICHAR
:
3503 return "int2unichar()";
3504 case OPTYPE_OCT2BIT
:
3506 case OPTYPE_OCT2CHAR
:
3507 return "oct2char()";
3508 case OPTYPE_OCT2HEX
:
3510 case OPTYPE_OCT2INT
:
3512 case OPTYPE_OCT2STR
:
3514 case OPTYPE_STR2BIT
:
3516 case OPTYPE_STR2FLOAT
:
3517 return "str2float()";
3518 case OPTYPE_STR2HEX
:
3520 case OPTYPE_STR2INT
:
3522 case OPTYPE_STR2OCT
:
3524 case OPTYPE_UNICHAR2INT
:
3525 return "unichar2int()";
3526 case OPTYPE_UNICHAR2CHAR
:
3527 return "unichar2char()";
3528 case OPTYPE_UNICHAR2OCT
:
3529 return "unichar2oct()";
3530 case OPTYPE_ENUM2INT
:
3531 return "enum2int()";
3532 case OPTYPE_LENGTHOF
:
3533 return "lengthof()";
3536 case OPTYPE_RNDWITHVAL
:
3537 return "rnd (seed)";
3539 return "encvalue()";
3541 return "decvalue()";
3542 case OPTYPE_GET_STRINGENCODING
:
3543 return "get_stringencoding()";
3544 case OPTYPE_REMOVE_BOM
:
3545 return "remove_bom()";
3546 case OPTYPE_ENCODE_BASE64
:
3547 return "encode_base64()";
3548 case OPTYPE_DECODE_BASE64
:
3549 return "decode_base64()";
3550 case OPTYPE_HOSTID
: // [v1]
3552 case OPTYPE_ADD
: // v1 v2
3554 case OPTYPE_SUBTRACT
:
3556 case OPTYPE_MULTIPLY
:
3598 case OPTYPE_INT2BIT
:
3600 case OPTYPE_INT2HEX
:
3602 case OPTYPE_INT2OCT
:
3604 case OPTYPE_OCT2UNICHAR
:
3605 return "oct2unichar()";
3606 case OPTYPE_ENCVALUE_UNICHAR
:
3607 return "encvalue_unichar()";
3608 case OPTYPE_DECVALUE_UNICHAR
:
3609 return "decvalue_unichar()";
3616 case OPTYPE_REPLACE
:
3618 case OPTYPE_VALUEOF
: // t1
3620 case OPTYPE_UNDEF_RUNNING
:
3621 return "<timer or component> running";
3622 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3624 case OPTYPE_COMP_RUNNING
: // v1
3625 return "component running";
3626 case OPTYPE_COMP_ALIVE
: // v1
3628 case OPTYPE_TMR_READ
:
3629 return "timer read";
3630 case OPTYPE_TMR_RUNNING
:
3631 return "timer running";
3632 case OPTYPE_ACTIVATE
:
3633 return "activate()";
3634 case OPTYPE_ACTIVATE_REFD
:
3635 return "activate()";
3636 case OPTYPE_EXECUTE
: // r1 [v2]
3637 case OPTYPE_EXECUTE_REFD
:
3639 case OPTYPE_MATCH
: // v1 t2
3641 case OPTYPE_ISPRESENT
:
3642 return "ispresent()";
3643 case OPTYPE_ISCHOSEN
:
3644 case OPTYPE_ISCHOSEN_V
:
3645 case OPTYPE_ISCHOSEN_T
:
3646 return "ischosen()";
3647 case OPTYPE_ISVALUE
:
3649 case OPTYPE_ISBOUND
:
3651 case OPTYPE_LOG2STR
:
3653 case OPTYPE_ANY2UNISTR
:
3654 return "any2unistr()";
3655 case OPTYPE_TTCN2STRING
:
3656 return "ttcn2string()";
3657 case OPTYPE_PROF_RUNNING
:
3658 return "@profiler.running";
3660 FATAL_ERROR("Value::get_opname()");
3664 void Value::chk_expr_ref_ischosen()
3666 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3667 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3668 Assignment
*ass
=tmpref
->get_refd_assignment();
3670 set_valuetype(V_ERROR
);
3673 // Now we know whether the argument of ischosen() is a value or template.
3674 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3675 // or template (OPTYPE_ISCHOSEN_T).
3676 switch (ass
->get_asstype()) {
3677 case Assignment::A_CONST
:
3678 case Assignment::A_EXT_CONST
:
3679 case Assignment::A_MODULEPAR
:
3680 case Assignment::A_VAR
:
3681 case Assignment::A_PAR_VAL_IN
:
3682 case Assignment::A_PAR_VAL_OUT
:
3683 case Assignment::A_PAR_VAL_INOUT
:
3684 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3685 u
.expr
.v1
->set_location(*tmpref
);
3686 u
.expr
.v1
->set_my_scope(get_my_scope());
3687 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3688 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3690 case Assignment::A_MODULEPAR_TEMP
:
3691 case Assignment::A_TEMPLATE
:
3692 case Assignment::A_VAR_TEMPLATE
:
3693 case Assignment::A_PAR_TEMPL_IN
:
3694 case Assignment::A_PAR_TEMPL_OUT
:
3695 case Assignment::A_PAR_TEMPL_INOUT
:
3696 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3697 u
.expr
.t1
->set_location(*tmpref
);
3698 u
.expr
.t1
->set_my_scope(get_my_scope());
3699 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3700 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3703 tmpref
->error("Reference to a value or template was expected instead of "
3704 "%s", ass
->get_description().c_str());
3705 set_valuetype(V_ERROR
);
3710 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3711 Type::expected_value_t exp_val
)
3713 v
->set_lowerid_to_ref(); // can only be reference to enum
3714 Type
*t
= v
->get_expr_governor(exp_val
);
3715 if (v
->valuetype
==V_ERROR
) return;
3717 v
->error("Please use reference to an enumerated value as the operand of "
3718 "operation `%s'", get_opname());
3719 set_valuetype(V_ERROR
);
3722 t
= t
->get_type_refd_last();
3723 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3724 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3725 set_valuetype(V_ERROR
);
3727 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3728 v
->error("The operand of operation `%s' cannot be omit", opname
);
3729 set_valuetype(V_ERROR
);
3733 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3736 const Location
*loc
)
3738 if(tt
==Type::T_BOOL
) return;
3739 if(tt
!=Type::T_ERROR
)
3740 loc
->error("%s operand of operation `%s' should be boolean value",
3742 set_valuetype(V_ERROR
);
3745 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3748 const Location
*loc
)
3750 if(tt
==Type::T_INT
) return;
3751 if(tt
!=Type::T_ERROR
)
3752 loc
->error("%s operand of operation `%s' should be integer value",
3754 set_valuetype(V_ERROR
);
3757 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3760 const Location
*loc
)
3762 if(tt
==Type::T_REAL
) return;
3763 else if(tt
==Type::T_INT
)
3764 loc
->error("%s operand of operation `%s' should be float value."
3765 " Perhaps you missed an int2float() conversion function"
3766 " or `.0' at the end of the number",
3768 else if(tt
!=Type::T_ERROR
)
3769 loc
->error("%s operand of operation `%s' should be float value",
3771 set_valuetype(V_ERROR
);
3774 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3777 const Location
*loc
)
3786 if(tt
!=Type::T_ERROR
)
3787 loc
->error("%s operand of operation `%s' should be integer"
3790 set_valuetype(V_ERROR
);
3793 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3796 const Location
*loc
)
3801 case Type::T_ENUM_T
:
3806 if(tt
!=Type::T_ERROR
)
3807 loc
->error("%s operand of operation `%s' should be integer, float"
3808 " or enumerated value", opnum
, opname
);
3809 set_valuetype(V_ERROR
);
3812 void Value::chk_expr_operandtype_list(Type
* t
,
3815 const Location
*loc
,
3818 if (valuetype
== V_ERROR
) return;
3819 if (t
->get_typetype() == Type::T_ERROR
) {
3820 set_valuetype(V_ERROR
);
3823 if (!t
->is_list_type(allow_array
)) {
3824 loc
->error("%s operand of operation `%s' should be a string, "
3825 "`record of'%s `set of'%s value", opnum
, opname
,
3826 allow_array
? "," : " or", allow_array
? " or array" : "");
3827 set_valuetype(V_ERROR
);
3830 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3831 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3834 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3835 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3836 if (info
.is_subtype_error()) {
3838 if (info
.needs_conversion()) set_needs_conversion();
3840 if (!info
.is_erroneous()) {
3841 error("%s operand of operation `%s' is of type `%s', but a value of "
3842 "type `%s' was expected here", opnum
, opname
,
3843 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3845 error("%s", info
.get_error_str_str().c_str());
3848 if (info
.needs_conversion())
3849 set_needs_conversion();
3853 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3856 const Location
*loc
)
3868 if(tt
!=Type::T_ERROR
)
3869 loc
->error("%s operand of operation `%s' should be string value",
3871 set_valuetype(V_ERROR
);
3874 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3877 const Location
*loc
)
3886 if(tt
!=Type::T_ERROR
)
3887 loc
->error("%s operand of operation `%s' should be (universal)"
3888 " charstring value",
3890 set_valuetype(V_ERROR
);
3893 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3896 const Location
*loc
)
3898 if(tt
==Type::T_CSTR
) return;
3899 if(tt
!=Type::T_ERROR
)
3900 loc
->error("%s operand of operation `%s' should be charstring value",
3902 set_valuetype(V_ERROR
);
3905 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3908 const Location
*loc
)
3918 if(tt
!=Type::T_ERROR
)
3919 loc
->error("%s operand of operation `%s' should be binary string value",
3921 set_valuetype(V_ERROR
);
3924 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3927 const Location
*loc
)
3929 if(tt
==Type::T_BSTR
) return;
3930 if(tt
!=Type::T_ERROR
)
3931 loc
->error("%s operand of operation `%s' should be bitstring value",
3933 set_valuetype(V_ERROR
);
3936 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3939 const Location
*loc
)
3941 if(tt
==Type::T_HSTR
) return;
3942 if(tt
!=Type::T_ERROR
)
3943 loc
->error("%s operand of operation `%s' should be hexstring value",
3945 set_valuetype(V_ERROR
);
3948 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3951 const Location
*loc
)
3953 if(tt
==Type::T_OSTR
) return;
3954 if(tt
!=Type::T_ERROR
)
3955 loc
->error("%s operand of operation `%s' should be octetstring value",
3957 set_valuetype(V_ERROR
);
3960 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3961 Type::typetype_t tt2
,
3964 if(valuetype
==V_ERROR
) return;
3965 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3966 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3967 set_valuetype(V_ERROR
);
3970 if(tt1
==tt2
) return;
3971 error("The operands of operation `%s' should be of same type", opname
);
3972 set_valuetype(V_ERROR
);
3975 /* For predefined functions. */
3976 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3977 Type::typetype_t tt2
,
3982 if(valuetype
==V_ERROR
) return;
3983 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3984 set_valuetype(V_ERROR
);
3987 if(tt1
==tt2
) return;
3988 error("The %s and %s operands of operation `%s' should be of same type",
3989 opnum1
, opnum2
, opname
);
3990 set_valuetype(V_ERROR
);
3993 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3994 Value
*v1
, Value
*v2
,
3999 if (valuetype
== V_ERROR
) return;
4000 // if (u.expr.state == EXPR_CHECKING_ERR) return;
4001 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
4002 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
4004 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
4005 set_valuetype(V_ERROR
);
4008 if (tt1
== Type::T_UNDEF
) {
4009 if (tt2
== Type::T_UNDEF
) {
4010 if (v1
->is_undef_lowerid()) {
4011 if (v2
->is_undef_lowerid()) {
4012 Scope
*scope
= get_my_scope();
4013 Module
*my_mod
= scope
->get_scope_mod();
4014 const Identifier
& id1
= v1
->get_undef_lowerid();
4015 if (scope
->has_ass_withId(id1
)
4016 || my_mod
->has_imported_ass_withId(id1
)) {
4017 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
4018 * should examine this situation better, but now I suppose
4019 * the first is ref, not enum. */
4020 v1
->set_lowerid_to_ref();
4023 const Identifier
& id2
= v2
->get_undef_lowerid();
4024 if (scope
->has_ass_withId(id2
)
4025 || my_mod
->has_imported_ass_withId(id2
)) {
4026 v2
->set_lowerid_to_ref();
4030 /* This is perhaps enum-enum, but it has no real
4031 * significance, so this should be an error. */
4033 v1
->set_lowerid_to_ref();
4036 } else if (v2
->is_undef_lowerid()) {
4037 v2
->set_lowerid_to_ref();
4040 error("Cannot determine the type of the operands in operation `%s'",
4042 set_valuetype(V_ERROR
);
4044 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
4045 v1
->set_lowerid_to_ref();
4048 /* v1 is something undefined, but not lowerid; v2 has
4049 * returntype (perhaps also governor) */
4051 } else if (tt2
== Type::T_UNDEF
) {
4052 /* but tt1 is not undef */
4053 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
4054 v2
->set_lowerid_to_ref();
4057 /* v2 is something undefined, but not lowerid; v1 has
4058 * returntype (perhaps also governor) */
4062 /* Now undef_lower_id's are converted to references, or the other
4063 * value has governor; let's see the governors, if they exist. */
4064 Type
*t1
= v1
->get_expr_governor(exp_val
);
4065 Type
*t2
= v2
->get_expr_governor(exp_val
);
4068 // Both value has governor. Are they compatible? According to 7.1.2
4069 // and C.34 it's required to have the same root types for
4070 // OPTYPE_{CONCAT,REPLACE}.
4071 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
4072 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4073 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
4074 u
.expr
.v_optype
== OPTYPE_REPLACE
);
4075 TypeChain l_chain1
, l_chain2
;
4076 TypeChain r_chain1
, r_chain2
;
4077 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
4078 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
4079 if (!compat_t1
&& !compat_t2
) {
4080 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
4081 // the subtypes don't need to be compatible here
4082 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
4083 error("The operands of operation `%s' should be of compatible "
4084 "types", get_opname());
4085 set_valuetype(V_ERROR
);
4087 if (info1
.needs_conversion() || info2
.needs_conversion()) {
4088 set_needs_conversion(); // Avoid folding.
4093 if (info1
.is_erroneous())
4094 v1
->error("%s", info1
.get_error_str_str().c_str());
4095 else if (info2
.is_erroneous())
4096 v2
->error("%s", info2
.get_error_str_str().c_str());
4097 set_valuetype(V_ERROR
);
4100 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
4101 set_needs_conversion(); // Avoid folding.
4106 v2
->set_my_governor(t1
);
4107 t1
->chk_this_value_ref(v2
);
4108 if (v2
->valuetype
== V_OMIT
) {
4109 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4111 v1
->chk_expr_omit_comparison(exp_val
);
4113 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4115 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4116 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4121 v1
->set_my_governor(t2
);
4122 t2
->chk_this_value_ref(v1
);
4123 if (v1
->valuetype
== V_OMIT
) {
4124 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
4126 v2
->chk_expr_omit_comparison(exp_val
);
4128 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
4130 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
4131 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
4135 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4136 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
4137 // Here, it cannot be that both are T_UNDEF.
4138 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4139 error("Please use reference as %s operand of operator `%s'",
4140 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
4141 set_valuetype(V_ERROR
);
4144 // Deny type compatibility if no governors found. The typetype_t must
4145 // be the same. TODO: How can this happen?
4146 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
4147 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
4148 error("The operands of operation `%s' should be of compatible types",
4150 set_valuetype(V_ERROR
);
4155 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
4156 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
4158 if(valuetype
==V_ERROR
) return;
4159 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4160 Assignment
*t_ass
= ref
->get_refd_assignment();
4161 if(!t_ass
) goto error
;
4162 switch(t_ass
->get_asstype()) {
4163 case Assignment::A_TIMER
:
4164 case Assignment::A_PAR_TIMER
:
4165 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
4166 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
4167 chk_expr_dynamic_part(exp_val
, true);
4169 case Assignment::A_CONST
:
4170 case Assignment::A_EXT_CONST
:
4171 case Assignment::A_MODULEPAR
:
4172 case Assignment::A_VAR
:
4173 case Assignment::A_FUNCTION_RVAL
:
4174 case Assignment::A_EXT_FUNCTION_RVAL
:
4175 case Assignment::A_PAR_VAL_IN
:
4176 case Assignment::A_PAR_VAL_OUT
:
4177 case Assignment::A_PAR_VAL_INOUT
: {
4178 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
4179 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
4180 val
->set_my_scope(my_scope
);
4181 val
->set_fullname(u
.expr
.r1
->get_fullname());
4182 val
->set_location(*u
.expr
.r1
);
4184 chk_expr_operand_compref(val
, opnum
, get_opname());
4185 chk_expr_dynamic_part(exp_val
, false);
4188 ref
->error("%s operand of operation `%s' should be timer or"
4189 " component reference instead of %s",
4190 opnum
, opname
, t_ass
->get_description().c_str());
4195 set_valuetype(V_ERROR
);
4198 Type
*Value::chk_expr_operand_comptyperef_create()
4200 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4201 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4202 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4203 if (!t_ass
) goto error
;
4204 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4205 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4206 Type::EXPECTED_DYNAMIC_VALUE
);
4207 if (!t_type
) goto error
;
4208 t_type
= t_type
->get_type_refd_last();
4209 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4211 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4212 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4213 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4214 u
.expr
.r1
->error("Incompatible component types: operation "
4215 "`create' should refer to `%s' instead of "
4217 my_governor_last
->get_typename().c_str(),
4218 t_type
->get_typename().c_str());
4224 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4225 "expected in operation `create' instead of `%s'",
4226 t_type
->get_typename().c_str());
4229 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4230 "instead of %s", t_ass
->get_description().c_str());
4233 set_valuetype(V_ERROR
);
4237 void Value::chk_expr_comptype_compat()
4239 if (valuetype
!= V_EXPR
)
4240 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4241 if (!my_governor
|| !my_scope
) return;
4242 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4243 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4245 switch (u
.expr
.v_optype
) {
4246 case OPTYPE_COMP_MTC
:
4247 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4249 case OPTYPE_COMP_SYSTEM
:
4250 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4252 case OPTYPE_COMP_SELF
: {
4253 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4254 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4257 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4262 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4263 error("Incompatible component types: a component reference of "
4264 "type `%s' was expected, but `%s' has type `%s'",
4265 my_governor_last
->get_typename().c_str(), get_opname(),
4266 t_comptype
->get_typename().c_str());
4267 set_valuetype(V_ERROR
);
4271 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4274 if(valuetype
== V_ERROR
) return;
4275 switch(val
->get_valuetype()) {
4277 Error_Context
cntxt(this, "In `%s' operation", opname
);
4278 Value
*v_last
= val
->get_value_refd_last();
4279 if(!v_last
) goto error
;
4280 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4282 t
= t
->get_type_refd_last();
4283 if(t
->get_typetype() != Type::T_COMPONENT
) {
4284 v_last
->error("%s operand of operation `%s': Type mismatch:"
4285 " component reference was expected instead of `%s'",
4286 opnum
, opname
, t
->get_typename().c_str());
4291 Reference
*ref
= val
->get_reference();
4292 Assignment
*t_ass
= ref
->get_refd_assignment();
4294 if (!t_ass
) goto error
;
4295 switch(t_ass
->get_asstype()) {
4296 case Assignment::A_CONST
:
4297 t_val
= t_ass
->get_Value();
4299 case Assignment::A_EXT_CONST
:
4300 case Assignment::A_MODULEPAR
:
4301 case Assignment::A_VAR
:
4302 case Assignment::A_FUNCTION_RVAL
:
4303 case Assignment::A_EXT_FUNCTION_RVAL
:
4304 case Assignment::A_PAR_VAL_IN
:
4305 case Assignment::A_PAR_VAL_OUT
:
4306 case Assignment::A_PAR_VAL_INOUT
: {
4307 Type
*t_type
=t_ass
->get_Type()
4308 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4309 if(!t_type
) goto error
;
4310 t_type
=t_type
->get_type_refd_last();
4311 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4312 ref
->error("%s operand of operation `%s': Type mismatch:"
4313 " component reference was expected instead of `%s'",
4314 opnum
, opname
, t_type
->get_typename().c_str());
4319 ref
->error("%s operand of operation `%s' should be"
4320 " component reference instead of %s",
4321 opnum
, opname
, t_ass
->get_description().c_str());
4325 ReferenceChain
refch(this, "While searching referenced value");
4326 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4328 t_val
= t_val
->get_value_refd_last();
4329 if (t_val
->valuetype
!= V_EXPR
) return;
4330 switch (t_val
->u
.expr
.v_optype
) {
4331 case OPTYPE_COMP_NULL
:
4332 ref
->error("%s operand of operation `%s' refers to `null' component "
4333 "reference", opnum
, opname
);
4335 case OPTYPE_COMP_MTC
:
4336 ref
->error("%s operand of operation `%s' refers to the component "
4337 "reference of the `mtc'", opnum
, opname
);
4339 case OPTYPE_COMP_SYSTEM
:
4340 ref
->error("%s operand of operation `%s' refers to the component "
4341 "reference of the `system'", opnum
, opname
);
4349 FATAL_ERROR("Value::chk_expr_operand_compref()");
4352 set_valuetype(V_ERROR
);
4355 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4359 if(valuetype
==V_ERROR
) return;
4360 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4361 Assignment
*t_ass
= ref
->get_refd_assignment();
4362 if(!t_ass
) goto error
;
4363 switch(t_ass
->get_asstype()) {
4364 case Assignment::A_TIMER
: {
4365 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4366 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4367 Type::EXPECTED_DYNAMIC_VALUE
);
4368 else if (ref
->get_subrefs()) {
4369 ref
->error("%s operand of operation `%s': "
4370 "Reference to single timer `%s' cannot have field or array "
4371 "sub-references", opnum
, opname
,
4372 t_ass
->get_id().get_dispname().c_str());
4376 case Assignment::A_PAR_TIMER
:
4377 if (ref
->get_subrefs()) {
4378 ref
->error("%s operand of operation `%s': "
4379 "Reference to %s cannot have field or array sub-references",
4380 opnum
, opname
, t_ass
->get_description().c_str());
4385 ref
->error("%s operand of operation `%s' should be timer"
4387 opnum
, opname
, t_ass
->get_description().c_str());
4392 set_valuetype(V_ERROR
);
4395 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4399 if(valuetype
==V_ERROR
) return;
4400 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4401 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4402 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4403 Error_Context
cntxt(this, "In `%s' operation", opname
);
4404 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4407 void Value::chk_expr_operand_activate_refd(Value
*val
,
4408 Ttcn::TemplateInstances
* t_list2
,
4409 Ttcn::ActualParList
*&parlist
,
4413 if(valuetype
==V_ERROR
) return;
4414 Error_Context
cntxt(this, "In `%s' operation", opname
);
4415 Type
*t
= val
->get_expr_governor_last();
4417 switch (t
->get_typetype()) {
4419 set_valuetype(V_ERROR
);
4421 case Type::T_ALTSTEP
: {
4422 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4423 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4427 set_valuetype(V_ERROR
);
4429 parlist
->set_fullname(get_fullname());
4430 parlist
->set_my_scope(get_my_scope());
4431 if (!fp_list
->chk_activate_argument(parlist
,
4432 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4436 error("Reference to an altstep was expected in the argument of "
4437 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4438 set_valuetype(V_ERROR
);
4441 } else set_valuetype(V_ERROR
);
4444 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4448 if(valuetype
==V_ERROR
) return;
4449 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4450 Error_Context
cntxt(this, "In `%s' operation", opname
);
4451 Assignment
*t_ass
= ref
->get_refd_assignment();
4452 bool error_flag
= false;
4454 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4455 ref
->error("Reference to a testcase was expected in the argument "
4456 "instead of %s", t_ass
->get_description().c_str());
4459 } else error_flag
= true;
4461 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4462 Value
*v_last
= val
->get_value_refd_last();
4463 switch (v_last
->valuetype
) {
4465 ttcn3float v_real
= v_last
->get_val_Real();
4467 val
->error("The testcase guard timer has negative value: `%s'",
4468 Real2string(v_real
).c_str());
4479 if (error_flag
) set_valuetype(V_ERROR
);
4482 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4483 Ttcn::TemplateInstances
* t_list2
,
4484 Ttcn::ActualParList
*&parlist
,
4489 if(valuetype
==V_ERROR
) return;
4490 Error_Context
cntxt(this, "In `%s' operation", opname
);
4491 Type
*t
= v1
->get_expr_governor_last();
4493 switch (t
->get_typetype()) {
4495 set_valuetype(V_ERROR
);
4497 case Type::T_TESTCASE
: {
4498 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4499 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4503 set_valuetype(V_ERROR
);
4505 parlist
->set_fullname(get_fullname());
4506 parlist
->set_my_scope(get_my_scope());
4510 v1
->error("Reference to a value of type testcase was expected in the "
4511 "argument of `derefers()' instead of `%s'",
4512 t
->get_typename().c_str());
4513 set_valuetype(V_ERROR
);
4516 } else set_valuetype(V_ERROR
);
4518 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4519 Value
*v_last
= v3
->get_value_refd_last();
4520 switch (v_last
->valuetype
) {
4522 ttcn3float v_real
= v_last
->get_val_Real();
4524 v3
->error("The testcase guard timer has negative value: `%s'",
4525 Real2string(v_real
).c_str());
4526 set_valuetype(V_ERROR
);
4530 set_valuetype(V_ERROR
);
4538 void Value::chk_invoke(Type::expected_value_t exp_val
)
4540 if(valuetype
== V_ERROR
) return;
4541 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4542 if(!u
.invoke
.t_list
) return; //already checked
4543 Error_Context
cntxt(this, "In `apply()' operation");
4544 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4546 set_valuetype(V_ERROR
);
4549 switch (t
->get_typetype()) {
4551 set_valuetype(V_ERROR
);
4553 case Type::T_FUNCTION
:
4556 u
.invoke
.v
->error("A value of type function was expected in the "
4557 "argument instead of `%s'", t
->get_typename().c_str());
4558 set_valuetype(V_ERROR
);
4561 my_scope
->chk_runs_on_clause(t
, *this, "call");
4562 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4563 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4564 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4565 delete u
.invoke
.t_list
;
4566 u
.invoke
.t_list
= 0;
4569 u
.invoke
.ap_list
= 0;
4571 parlist
->set_fullname(get_fullname());
4572 parlist
->set_my_scope(get_my_scope());
4573 u
.invoke
.ap_list
= parlist
;
4576 case Type::EXPECTED_CONSTANT
:
4577 error("An evaluable constant value was expected instead of operation "
4579 set_valuetype(V_ERROR
);
4581 case Type::EXPECTED_STATIC_VALUE
:
4582 error("A static value was expected instead of operation `apply()'");
4583 set_valuetype(V_ERROR
);
4590 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4591 ReferenceChain
*refch
,
4592 Type::expected_value_t exp_val
)
4594 bool self_ref
= false;
4595 if(valuetype
==V_ERROR
) return;
4596 // Commented out to report more errors :)
4597 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4598 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4599 switch(val
->get_valuetype()) {
4601 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4606 val
->get_value_refd_last(refch
, exp_val
);
4611 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4616 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4617 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4619 bool self_ref
= false;
4621 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4622 ti
->error("Reference to a %s value was expected instead of an in-line "
4623 "modified template",
4624 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4625 set_valuetype(V_ERROR
);
4628 Template
*templ
= ti
->get_Template();
4629 switch (templ
->get_templatetype()) {
4630 case Template::TEMPLATE_REFD
:
4632 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4633 templ
= templ
->get_template_refd_last(refch
);
4634 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4635 set_valuetype(V_ERROR
);
4637 ti
->error("Reference to a %s value was expected instead of %s",
4638 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4639 templ
->get_reference()->get_refd_assignment()
4640 ->get_description().c_str());
4641 set_valuetype(V_ERROR
);
4644 case Template::SPECIFIC_VALUE
: {
4645 Value
*val
= templ
->get_specific_value();
4646 switch (val
->get_valuetype()) {
4648 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4651 val
->get_value_refd_last(refch
, exp_val
);
4655 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4657 case Template::TEMPLATE_ERROR
:
4658 set_valuetype(V_ERROR
);
4667 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4670 if(valuetype
==V_ERROR
) return;
4671 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4672 if(val
->is_unfoldable()) return;
4673 if(*val
->get_val_Int()<0) {
4674 val
->error("%s operand of operation `%s' should not be negative",
4676 set_valuetype(V_ERROR
);
4680 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4683 if(valuetype
==V_ERROR
) return;
4684 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4685 if(val
->is_unfoldable()) return;
4686 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4687 val
->error("%s operand of operation `%s' should be in range 0..127",
4689 set_valuetype(V_ERROR
);
4693 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4696 if(valuetype
==V_ERROR
) return;
4697 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4698 if(val
->is_unfoldable()) return;
4699 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4700 val
->error("%s operand of operation `%s' should be in range"
4701 " 0..2147483647", opnum
, opname
);
4702 set_valuetype(V_ERROR
);
4706 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4709 if(valuetype
==V_ERROR
) return;
4710 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4711 if(val
->is_unfoldable()) return;
4712 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4714 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4716 val
->error("%s operand of operation `%s' should not be zero",
4718 set_valuetype(V_ERROR
);
4722 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4725 if (valuetype
== V_ERROR
) return;
4726 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4727 if (val
->get_expr_returntype() != Type::T_INT
) return;
4728 if (val
->is_unfoldable()) return;
4729 const int_val_t
*val_int
= val
->get_val_Int();
4730 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4731 val
->error("%s operand of operation `%s' should be less than `%d' "
4732 "instead of `%s'", opnum
, opname
, INT_MAX
,
4733 (val_int
->t_str()).c_str());
4734 set_valuetype(V_ERROR
);
4738 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4741 if(valuetype
==V_ERROR
) return;
4742 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4743 if(val
->is_unfoldable()) return;
4744 if(val
->get_val_strlen()!=1) {
4745 val
->error("%s operand of operation `%s' should be of length 1",
4747 set_valuetype(V_ERROR
);
4751 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4754 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4755 Value
*v_last
= val
->get_value_refd_last();
4756 if (v_last
->valuetype
== V_CSTR
) {
4757 size_t len
= v_last
->get_val_strlen();
4759 val
->error("%s operand of operation `%s' should contain even number "
4760 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4761 set_valuetype(V_ERROR
);
4763 } else if (v_last
->valuetype
== V_REFD
) {
4764 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4765 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4766 val
->error("%s operand of operation `%s' should contain even number "
4767 "of characters, but a string element contains 1", opnum
, opname
);
4768 set_valuetype(V_ERROR
);
4773 void Value::chk_expr_val_str_bindigits(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
=='1')) {
4783 val
->error("%s operand of operation `%s' can contain only"
4784 " binary digits (position %lu is `%c')",
4785 opnum
, opname
, (unsigned long) i
, c
);
4786 set_valuetype(V_ERROR
);
4792 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4795 if(valuetype
==V_ERROR
) return;
4796 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4797 if(val
->is_unfoldable()) return;
4798 const string
& s
=val
->get_val_str();
4799 for(size_t i
=0; i
<s
.size(); i
++) {
4801 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4802 val
->error("%s operand of operation `%s' can contain only valid "
4803 "hexadecimal digits (position %lu is `%c')",
4804 opnum
, opname
, (unsigned long) i
, c
);
4805 set_valuetype(V_ERROR
);
4811 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4814 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4815 Value
*v
= val
->get_value_refd_last();
4816 if (v
->valuetype
!= V_OSTR
) return;
4817 const string
& s
= val
->get_val_str();
4818 size_t n_octets
= s
.size() / 2;
4819 for (size_t i
= 0; i
< n_octets
; i
++) {
4821 if (!(c
>= '0' && c
<= '7')) {
4822 val
->error("%s operand of operation `%s' shall consist of octets "
4823 "within the range 00 .. 7F, but the string `%s'O contains octet "
4824 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4826 set_valuetype(V_ERROR
);
4832 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4835 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4836 Value
*v_last
= val
->get_value_refd_last();
4837 if (v_last
->valuetype
!= V_CSTR
) return;
4838 const string
& s
= v_last
->get_val_str();
4839 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4841 // state: expected characters
4842 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4843 // S_FIRST: first digit
4844 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4845 // S_END: trailing whitespace
4846 // S_ERR: error was found, stop
4847 for (size_t i
= 0; i
< s
.size(); i
++) {
4852 if (c
== '+' || c
== '-') state
= S_FIRST
;
4853 else if (c
== '0') state
= S_ZERO
;
4854 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4855 else if (string::is_whitespace(c
)) {
4856 if (state
== S_INITIAL
) {
4857 val
->warning("Leading whitespace was detected and ignored in the "
4858 "operand of operation `%s'", opname
);
4859 state
= S_INITIAL_WS
;
4861 } else state
= S_ERR
;
4864 if (c
== '0') state
= S_ZERO
;
4865 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4869 if (c
>= '0' && c
<= '9') {
4870 val
->warning("Leading zero digit was detected and ignored in the "
4871 "operand of operation `%s'", opname
);
4873 } else if (string::is_whitespace(c
)) state
= S_END
;
4877 if (c
>= '0' && c
<= '9') {}
4878 else if (string::is_whitespace(c
)) state
= S_END
;
4882 if (!string::is_whitespace(c
)) state
= S_ERR
;
4887 if (state
== S_ERR
) {
4888 if (string::is_printable(c
)) {
4889 val
->error("%s operand of operation `%s' should be a string "
4890 "containing a valid integer value, but invalid character `%c' "
4891 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4893 val
->error("%s operand of operation `%s' should be a string "
4894 "containing a valid integer value, but invalid character with "
4895 "character code %u was detected at index %lu", opnum
, opname
, c
,
4898 set_valuetype(V_ERROR
);
4905 val
->error("%s operand of operation `%s' should be a string containing a "
4906 "valid integer value instead of an empty string", opnum
, opname
);
4907 set_valuetype(V_ERROR
);
4910 val
->error("%s operand of operation `%s' should be a string containing a "
4911 "valid integer value, but only a sign character was detected", opnum
,
4913 set_valuetype(V_ERROR
);
4916 val
->warning("Trailing whitespace was detected and ignored in the "
4917 "operand of operation `%s'", opname
);
4924 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4927 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4928 Value
*v_last
= val
->get_value_refd_last();
4929 if (v_last
->valuetype
== V_REFD
) {
4930 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4931 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4932 val
->error("%s operand of operation `%s' should be a string containing "
4933 "a valid float value instead of a string element, which cannot "
4934 "represent a floating point number", opnum
, opname
);
4935 set_valuetype(V_ERROR
);
4938 } else if (v_last
->valuetype
!= V_CSTR
) return;
4939 const string
& s
= v_last
->get_val_str();
4940 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4941 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4943 // state: expected characters
4944 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4945 // leading whitespace
4946 // S_FIRST_M: first digit of integer part in mantissa
4947 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4948 // S_FIRST_F: first digit of fraction
4949 // S_MORE_F: more digits of fraction, E, trailing whitespace
4950 // S_INITIAL_E: +, -, first digit of exponent
4951 // S_FIRST_E: first digit of exponent
4952 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4953 // S_END: trailing whitespace
4954 // S_ERR: error was found, stop
4955 for (size_t i
= 0; i
< s
.size(); i
++) {
4960 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4961 else if (c
== '0') state
= S_ZERO_M
;
4962 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4963 else if (string::is_whitespace(c
)) {
4964 if (state
== S_INITIAL
) {
4965 val
->warning("Leading whitespace was detected and ignored in the "
4966 "operand of operation `%s'", opname
);
4967 state
= S_INITIAL_WS
;
4969 } else state
= S_ERR
;
4972 if (c
== '0') state
= S_ZERO_M
;
4973 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4977 if (c
== '.') state
= S_FIRST_F
;
4978 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4979 else if (c
>= '0' && c
<= '9') {
4980 val
->warning("Leading zero digit was detected and ignored in the "
4981 "mantissa of the operand of operation `%s'", opname
);
4983 } else state
= S_ERR
;
4986 if (c
== '.') state
= S_FIRST_F
;
4987 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4988 else if (c
>= '0' && c
<= '9') {}
4992 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4996 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4997 else if (c
>= '0' && c
<= '9') {}
4998 else if (string::is_whitespace(c
)) state
= S_END
;
5002 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
5003 else if (c
== '0') state
= S_ZERO_E
;
5004 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
5008 if (c
== '0') state
= S_ZERO_E
;
5009 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
5013 if (c
>= '0' && c
<= '9') {
5014 val
->warning("Leading zero digit was detected and ignored in the "
5015 "exponent of the operand of operation `%s'", opname
);
5017 } else if (string::is_whitespace(c
)) state
= S_END
;
5021 if (c
>= '0' && c
<= '9') {}
5022 else if (string::is_whitespace(c
)) state
= S_END
;
5026 if (!string::is_whitespace(c
)) state
= S_ERR
;
5031 if (state
== S_ERR
) {
5032 if (string::is_printable(c
)) {
5033 val
->error("%s operand of operation `%s' should be a string "
5034 "containing a valid float value, but invalid character `%c' "
5035 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
5037 val
->error("%s operand of operation `%s' should be a string "
5038 "containing a valid float value, but invalid character with "
5039 "character code %u was detected at index %lu", opnum
, opname
, c
,
5042 set_valuetype(V_ERROR
);
5049 val
->error("%s operand of operation `%s' should be a string containing a "
5050 "valid float value instead of an empty string", opnum
, opname
);
5051 set_valuetype(V_ERROR
);
5054 val
->error("%s operand of operation `%s' should be a string containing a "
5055 "valid float value, but only a sign character was detected", opnum
,
5057 set_valuetype(V_ERROR
);
5061 // HL67862: Missing decimal dot allowed for str2float
5064 // HL67862: Missing fraction part is allowed for str2float
5068 val
->error("%s operand of operation `%s' should be a string containing a "
5069 "valid float value, but the exponent is missing after the `E' sign",
5071 set_valuetype(V_ERROR
);
5074 val
->warning("Trailing whitespace was detected and ignored in the "
5075 "operand of operation `%s'", opname
);
5082 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
5085 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5086 Value
*v
= val
->get_value_refd_last();
5087 if (v
->valuetype
!= V_USTR
) return;
5088 const ustring
& us
= v
->get_val_ustr();
5089 for (size_t i
= 0; i
< us
.size(); i
++) {
5090 const ustring::universal_char
& uchar
= us
[i
];
5091 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
5093 val
->error("%s operand of operation `%s' shall consist of characters "
5094 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5095 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5096 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
5097 uchar
.row
, uchar
.cell
, (unsigned long) i
);
5098 set_valuetype(V_ERROR
);
5104 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
5107 if(valuetype
==V_ERROR
) return;
5108 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5109 if(val
->is_unfoldable()) return;
5110 const string
& bstr
=val
->get_val_str();
5111 // see also PredefFunc.cc::bit2int()
5112 size_t nof_bits
= bstr
.size();
5113 // skip the leading zeros
5114 size_t start_index
= 0;
5115 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
5116 // check whether the remaining bits fit in Int
5117 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
5118 val
->error("%s operand of operation `%s' is too large (maximum number"
5119 " of bits in integer is %lu)",
5120 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5121 set_valuetype(V_ERROR
);
5125 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
5128 if(valuetype
==V_ERROR
) return;
5129 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5130 if(val
->is_unfoldable()) return;
5131 const string
& hstr
=val
->get_val_str();
5132 // see also PredefFunc.cc::hex2int()
5133 size_t nof_digits
= hstr
.size();
5134 // skip the leading zeros
5135 size_t start_index
= 0;
5136 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
5137 // check whether the remaining hex digits fit in Int
5138 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
5139 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
5140 char_to_hexdigit(hstr
[start_index
]) > 7)) {
5141 val
->error("%s operand of operation `%s' is too large (maximum number"
5142 " of bits in integer is %lu)",
5143 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
5144 set_valuetype(V_ERROR
);
5148 void Value::chk_expr_operands_int2binstr()
5150 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5151 if (u
.expr
.v1
->is_unfoldable()) return;
5152 if (u
.expr
.v2
->is_unfoldable()) return;
5153 // It is already checked that i1 and i2 are non-negative.
5154 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5155 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
5156 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
5157 if (!i2
->is_native()) {
5158 u
.expr
.v2
->error("The length of the resulting string is too large for "
5159 "being represented in memory");
5160 set_valuetype(V_ERROR
);
5163 Int nof_bits
= i2
->get_val();
5164 if (u
.expr
.v1
->is_unfoldable()) return;
5165 switch (u
.expr
.v_optype
) {
5166 case OPTYPE_INT2BIT
:
5168 case OPTYPE_INT2HEX
:
5171 case OPTYPE_INT2OCT
:
5175 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5177 if (*i1
>> nof_bits
> 0) { // Expensive?
5178 u
.expr
.v1
->error("Value %s does not fit in length %s",
5179 i1
->t_str().c_str(), i2
->t_str().c_str());
5180 set_valuetype(V_ERROR
);
5184 void Value::chk_expr_operands_str_samelen()
5186 if(valuetype
==V_ERROR
) return;
5187 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5188 Value
*v1
=u
.expr
.v1
;
5189 if(v1
->is_unfoldable()) return;
5190 Value
*v2
=u
.expr
.v2
;
5191 if(v2
->is_unfoldable()) return;
5192 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5193 size_t i1
=v1
->get_val_strlen();
5194 size_t i2
=v2
->get_val_strlen();
5196 error("The operands should have the same length");
5197 set_valuetype(V_ERROR
);
5201 void Value::chk_expr_operands_replace()
5203 // The fourth operand doesn't need to be checked at all here.
5204 if(valuetype
==V_ERROR
) return;
5205 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5206 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5209 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5210 size_t list_len
= 0;
5211 bool list_len_known
= false;
5212 if (v1
->valuetype
== V_REFD
) {
5213 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5214 if (subrefs
&& subrefs
->refers_to_string_element()) {
5215 warning("Replacing a string element does not make any sense");
5217 list_len_known
= true;
5220 if (!v1
->is_unfoldable()) {
5221 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5222 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5223 list_len_known
= true;
5225 if (!list_len_known
) return;
5226 if (u
.expr
.v2
->is_unfoldable()) {
5227 if (!u
.expr
.v3
->is_unfoldable()) {
5228 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5229 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5230 error("Third operand `len' (%s) is greater than the length of "
5231 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5232 (unsigned long)list_len
);
5233 set_valuetype(V_ERROR
);
5237 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5238 if (u
.expr
.v3
->is_unfoldable()) {
5239 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5240 error("Second operand `index' (%s) is greater than the length of "
5241 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5242 (unsigned long)list_len
);
5243 set_valuetype(V_ERROR
);
5246 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5247 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5248 error("The sum of second operand `index' (%s) and third operand "
5249 "`len' (%s) is greater than the length of the first operand (%lu)",
5250 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5251 (unsigned long)list_len
);
5252 set_valuetype(V_ERROR
);
5258 void Value::chk_expr_operands_substr()
5260 if(valuetype
==V_ERROR
) return;
5261 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5262 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5265 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5266 size_t list_len
= 0;
5267 bool list_len_known
= false;
5268 if (v1
->valuetype
== V_REFD
) {
5269 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5270 if (subrefs
&& subrefs
->refers_to_string_element()) {
5271 warning("Taking the substring of a string element does not make any "
5274 list_len_known
= true;
5277 if (!list_len_known
&& !v1
->is_unfoldable()) {
5278 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5279 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5280 list_len_known
= true;
5282 // Do nothing if the length of the first operand is unknown.
5283 if (!list_len_known
) return;
5284 if (u
.expr
.v2
->is_unfoldable()) {
5285 if (!u
.expr
.v3
->is_unfoldable()) {
5286 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5287 // Only the third operand is known.
5288 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5289 error("Third operand `returncount' (%s) is greater than the "
5290 "length of the first operand (%lu)",
5291 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5292 set_valuetype(V_ERROR
);
5296 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5297 if (u
.expr
.v3
->is_unfoldable()) {
5298 // Only the second operand is known.
5299 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5300 error("Second operand `index' (%s) is greater than the length "
5301 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5302 (unsigned long)list_len
);
5303 set_valuetype(V_ERROR
);
5306 // Both second and third operands are known.
5307 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5308 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5309 error("The sum of second operand `index' (%s) and third operand "
5310 "`returncount' (%s) is greater than the length of the first operand "
5311 "(%lu)", (index_int_2
->t_str()).c_str(),
5312 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5313 set_valuetype(V_ERROR
);
5319 void Value::chk_expr_operands_regexp()
5321 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5322 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5323 Value
* v2
= u
.expr
.t2
->get_specific_value();
5324 if (!v1
|| !v2
) return;
5326 Error_Context
cntxt(this, "In operation `regexp()'");
5327 Value
* v1_last
= v1
->get_value_refd_last();
5328 if (v1_last
->valuetype
== V_CSTR
) {
5329 // the input string is available at compile time
5330 const string
& instr
= v1_last
->get_val_str();
5331 const char *input_str
= instr
.c_str();
5332 size_t instr_len
= strlen(input_str
);
5333 if (instr_len
< instr
.size()) {
5334 v1
->warning("The first operand of `regexp()' contains a "
5335 "character with character code zero at index %s. The rest of the "
5336 "string will be ignored during matching",
5337 Int2string(instr_len
).c_str());
5341 size_t nof_groups
= 0;
5342 Value
*v2_last
= v2
->get_value_refd_last();
5344 if (v2_last
->valuetype
== V_CSTR
) {
5345 // the pattern is available at compile time
5346 const string
& expression
= v2_last
->get_val_str();
5347 const char *pattern_str
= expression
.c_str();
5348 size_t pattern_len
= strlen(pattern_str
);
5349 if (pattern_len
< expression
.size()) {
5350 v2
->warning("The second operand of `regexp()' contains a "
5351 "character with character code zero at index %s. The rest of the "
5352 "string will be ignored during matching",
5353 Int2string(pattern_len
).c_str());
5357 Error_Context
cntxt2(v2
, "In character string pattern");
5358 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5360 if (posix_str
!= NULL
) {
5361 regex_t posix_regexp
;
5362 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5365 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5366 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5367 "regcomp() failed: %s", msg
);
5369 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5371 v2
->error("The character pattern in the second operand of "
5372 "`regexp()' does not contain any groups");
5373 set_valuetype(V_ERROR
);
5375 regfree(&posix_regexp
);
5378 // the pattern is faulty
5379 // the error has been reported by TTCN_pattern_to_regexp
5380 set_valuetype(V_ERROR
);
5383 if (nof_groups
> 0) {
5384 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5385 if (v3
->valuetype
== V_INT
) {
5386 // the group number is available at compile time
5387 const int_val_t
*groupno_int
= v3
->get_val_Int();
5388 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5389 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5390 "large: The requested group index is %s, but the pattern "
5391 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5392 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5393 set_valuetype(V_ERROR
);
5399 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5400 Type::expected_value_t exp_val
)
5402 const char *opname
= get_opname();
5403 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5405 const Location
*loc
;
5406 bool error_flag
= false;
5407 switch (u
.expr
.v_optype
) {
5408 case OPTYPE_ISCHOSEN_V
:
5409 // u.expr.v1 is always a referenced value
5410 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5412 u
.expr
.v1
->set_my_governor(t_governor
);
5413 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5414 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5415 } else error_flag
= true;
5418 case OPTYPE_ISCHOSEN_T
:
5419 // u.expr.t1 is always a referenced template
5420 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5421 exp_val
= Type::EXPECTED_TEMPLATE
;
5422 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5424 u
.expr
.t1
->set_my_governor(t_governor
);
5426 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5428 u
.expr
.t1
->get_template_refd_last(refch
);
5429 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5431 } else error_flag
= true;
5432 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5433 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5434 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5435 u
.expr
.t1
->get_reference()->get_refd_assignment()
5436 ->get_description().c_str());
5442 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5447 t_governor
= t_governor
->get_type_refd_last();
5448 switch (t_governor
->get_typetype()) {
5452 case Type::T_CHOICE_A
:
5453 case Type::T_CHOICE_T
:
5454 case Type::T_ANYTYPE
:
5455 case Type::T_OPENTYPE
:
5456 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5457 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5458 "%s does not have a field named `%s'" :
5459 "Union type `%s' does not have a field named `%s'",
5460 t_governor
->get_typename().c_str(),
5461 u
.expr
.i2
->get_dispname().c_str());
5466 loc
->error("The operand of operation `%s' should be a union value "
5467 "or template instead of `%s'", opname
,
5468 t_governor
->get_typename().c_str());
5473 if (error_flag
) set_valuetype(V_ERROR
);
5476 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5477 Type::expected_value_t exp_val
) {
5479 Error_Context
cntxt(this, "In the parameter of %s",
5480 u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
? "encvalue_unichar()" : "encvalue()");
5481 Type
t_chk(Type::T_ERROR
);
5484 Type::expected_value_t ti_exp_val
= exp_val
;
5485 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5486 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5488 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5490 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5491 if (valuetype
!=V_ERROR
)
5492 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5493 t_type
= t_type
->get_type_refd_last();
5495 error("Cannot determine type of value");
5500 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5501 error("Expecting a value of a type with coding attributes in first"
5502 "parameter of encvalue() which belongs to a generic type '%s'",
5503 t_type->get_typename().c_str());
5507 if(!disable_attribute_validation()) {
5508 t_type
->chk_coding(true);
5511 switch (t_type
->get_typetype()) {
5516 case Type::T_REFDSPEC
:
5517 case Type::T_SELTYPE
:
5518 case Type::T_VERDICT
:
5520 case Type::T_COMPONENT
:
5521 case Type::T_DEFAULT
:
5522 case Type::T_SIGNATURE
:
5523 case Type::T_FUNCTION
:
5524 case Type::T_ALTSTEP
:
5525 case Type::T_TESTCASE
:
5526 error("Type of parameter of encvalue() cannot be '%s'",
5527 t_type
->get_typename().c_str());
5534 set_valuetype(V_ERROR
);
5537 void Value::chk_expr_operands_decode(operationtype_t p_optype
)
5539 Error_Context
cntxt(this, "In the parameters of %s",
5540 p_optype
== OPTYPE_DECVALUE_UNICHAR
? "decvalue_unichar()" : "decvalue()");
5541 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5542 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5544 Assignment
* t_ass
= ref
->get_refd_assignment();
5547 error("Could not determine the assignment for first parameter");
5550 switch (t_ass
->get_asstype()) {
5551 case Assignment::A_PAR_VAL_IN
:
5552 t_ass
->use_as_lvalue(*this);
5554 case Assignment::A_CONST
:
5555 case Assignment::A_EXT_CONST
:
5556 case Assignment::A_MODULEPAR
:
5557 case Assignment::A_MODULEPAR_TEMP
:
5558 case Assignment::A_TEMPLATE
:
5559 ref
->error("Reference to '%s' cannot be used as the first operand of "
5560 "the 'decvalue' operation", t_ass
->get_assname());
5563 case Assignment::A_VAR
:
5564 case Assignment::A_PAR_VAL_OUT
:
5565 case Assignment::A_PAR_VAL_INOUT
:
5567 case Assignment::A_VAR_TEMPLATE
:
5568 case Assignment::A_PAR_TEMPL_IN
:
5569 case Assignment::A_PAR_TEMPL_OUT
:
5570 case Assignment::A_PAR_TEMPL_INOUT
: {
5571 Template
* t
= new Template(ref
->clone());
5572 t
->set_location(*ref
);
5573 t
->set_my_scope(get_my_scope());
5574 t
->set_fullname(get_fullname()+".<operand>");
5575 Template
* t_last
= t
->get_template_refd_last();
5576 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5578 ref
->error("Specific value template was expected instead of '%s'.",
5579 t
->get_template_refd_last()->get_templatetype_str());
5586 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5589 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5590 Type::EXPECTED_DYNAMIC_VALUE
);
5596 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5597 error("First parameter has to be a bitstring");
5601 case OPTYPE_DECVALUE_UNICHAR
:
5602 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_USTR
){
5603 error("First parameter has to be a universal charstring");
5608 FATAL_ERROR("Value::chk_expr_decode_operands()");
5613 t_subrefs
= ref
->get_subrefs();
5614 t_ass
= ref
->get_refd_assignment();
5617 error("Could not determine the assignment for second parameter");
5620 // Extra check for HM59355.
5621 switch (t_ass
->get_asstype()) {
5622 case Assignment::A_VAR
:
5623 case Assignment::A_PAR_VAL_IN
:
5624 case Assignment::A_PAR_VAL_OUT
:
5625 case Assignment::A_PAR_VAL_INOUT
:
5628 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5631 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5632 Type::EXPECTED_DYNAMIC_VALUE
);
5636 t_type
= t_type
->get_type_refd_last();
5637 switch (t_type
->get_typetype()) {
5642 case Type::T_REFDSPEC
:
5643 case Type::T_SELTYPE
:
5644 case Type::T_VERDICT
:
5646 case Type::T_COMPONENT
:
5647 case Type::T_DEFAULT
:
5648 case Type::T_SIGNATURE
:
5649 case Type::T_FUNCTION
:
5650 case Type::T_ALTSTEP
:
5651 case Type::T_TESTCASE
:
5652 error("Type of second parameter cannot be %s",
5653 t_type
->get_typename().c_str());
5659 if(!disable_attribute_validation()) {
5660 t_type
->chk_coding(false);
5665 set_valuetype(V_ERROR
);
5668 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5670 Ttcn::FieldOrArrayRefs
*subrefs
;
5671 Identifier
*field_id
= 0;
5674 if (valuetype
== V_ERROR
) return;
5675 else if (valuetype
!= V_REFD
) {
5676 error("Only a referenced value can be compared with `omit'");
5679 subrefs
= u
.ref
.ref
->get_subrefs();
5680 if (subrefs
) field_id
= subrefs
->remove_last_field();
5682 error("Only a reference pointing to an optional record or set field "
5683 "can be compared with `omit'");
5686 t_ass
= u
.ref
.ref
->get_refd_assignment();
5687 if (!t_ass
) goto error
;
5688 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5689 if (!t_type
) goto error
;
5690 t_type
= t_type
->get_type_refd_last();
5691 switch (t_type
->get_typetype()) {
5700 error("Only a reference pointing to an optional field of a record"
5701 " or set type can be compared with `omit'");
5704 if (!t_type
->has_comp_withName(*field_id
)) {
5705 error("Type `%s' does not have field named `%s'",
5706 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5708 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5709 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5710 "`omit'", field_id
->get_dispname().c_str(),
5711 t_type
->get_typename().c_str());
5714 // putting the last field_id back to subrefs
5715 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5718 set_valuetype(V_ERROR
);
5722 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5723 Type::expected_value_t exp_val
)
5725 if(valuetype
==V_ERROR
) return -1;
5726 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5727 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5728 exp_val
=Type::EXPECTED_TEMPLATE
;
5730 Error_Context
cntxt(this, "In the operand of"
5731 " operation `%s'", get_opname());
5734 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5737 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5740 t_templ
= t_templ
->get_template_refd_last(refch
);
5742 // Timer and port arrays are handled separately
5743 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5744 Value
* val
= t_templ
->get_specific_value();
5745 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5746 val
->set_lowerid_to_ref();
5748 if (val
&& val
->get_valuetype() == V_REFD
) {
5749 Reference
* ref
= val
->get_reference();
5750 Assignment
* t_ass
= ref
->get_refd_assignment();
5751 Common::Assignment::asstype_t asstype
=
5752 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5753 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5754 if (t_ass
->get_Dimensions()) {
5755 // here we have a timer or port array
5756 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5757 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5758 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5759 Type::EXPECTED_DYNAMIC_VALUE
);
5762 refd_dim
= t_subrefs
->get_nof_refs();
5763 size_t nof_dims
= t_dims
->get_nof_dims();
5764 if (refd_dim
>= nof_dims
) {
5765 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5766 t_ass
->get_assname());
5767 set_valuetype(V_ERROR
);
5770 } else refd_dim
= 0;
5771 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5773 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5774 t_ass
->get_description().c_str());
5775 set_valuetype(V_ERROR
);
5784 Assignment
* t_ass
= 0;
5786 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5787 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5789 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5790 t_type
= t_type
->get_type_refd_last();
5792 error("Cannot determine type of value");
5796 if(valuetype
==V_ERROR
) return -1;
5798 t_templ
= t_templ
->get_template_refd_last(refch
);
5799 switch(t_templ
->get_templatetype()) {
5800 case Template::TEMPLATE_ERROR
:
5802 case Template::INDEXED_TEMPLATE_LIST
:
5804 case Template::TEMPLATE_REFD
:
5805 case Template::TEMPLATE_LIST
:
5806 case Template::NAMED_TEMPLATE_LIST
:
5809 case Template::SPECIFIC_VALUE
:
5811 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5813 switch(t_val
->get_valuetype()) {
5823 ref
= t_val
->get_reference();
5824 t_ass
= ref
->get_refd_assignment();
5825 t_subrefs
= ref
->get_subrefs();
5829 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5830 t_val
->create_stringRepr().c_str());
5837 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5838 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5843 switch(t_ass
->get_asstype()) {
5844 case Assignment::A_ERROR
:
5846 case Assignment::A_CONST
:
5847 t_val
= t_ass
->get_Value();
5849 case Assignment::A_EXT_CONST
:
5850 case Assignment::A_MODULEPAR
:
5851 case Assignment::A_MODULEPAR_TEMP
:
5852 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5853 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5854 "expected instead of %s", t_ass
->get_description().c_str());
5858 case Assignment::A_VAR
:
5859 case Assignment::A_PAR_VAL_IN
:
5860 case Assignment::A_PAR_VAL_OUT
:
5861 case Assignment::A_PAR_VAL_INOUT
:
5863 case Type::EXPECTED_CONSTANT
:
5864 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5865 t_ass
->get_description().c_str());
5868 case Type::EXPECTED_STATIC_VALUE
:
5869 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5870 t_ass
->get_description().c_str());
5877 case Assignment::A_TEMPLATE
:
5878 t_templ
= t_ass
->get_Template();
5880 case Assignment::A_VAR_TEMPLATE
:
5881 case Assignment::A_PAR_TEMPL_IN
:
5882 case Assignment::A_PAR_TEMPL_OUT
:
5883 case Assignment::A_PAR_TEMPL_INOUT
:
5884 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5885 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5886 t_ass
->get_description().c_str());
5889 case Assignment::A_FUNCTION_RVAL
:
5890 case Assignment::A_EXT_FUNCTION_RVAL
:
5892 case Type::EXPECTED_CONSTANT
:
5893 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5894 "the return value of %s", t_ass
->get_description().c_str());
5897 case Type::EXPECTED_STATIC_VALUE
:
5898 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5899 "the return value of %s", t_ass
->get_description().c_str());
5906 case Assignment::A_FUNCTION_RTEMP
:
5907 case Assignment::A_EXT_FUNCTION_RTEMP
:
5908 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5909 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5910 " of %s, which returns a template",
5911 t_ass
->get_description().c_str());
5914 case Assignment::A_TIMER
:
5915 case Assignment::A_PORT
:
5916 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5917 // sizeof is applicable to timer and port arrays
5918 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5920 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5921 t_ass
->get_description().c_str());
5924 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5925 Type::EXPECTED_DYNAMIC_VALUE
);
5928 refd_dim
= t_subrefs
->get_nof_refs();
5929 size_t nof_dims
= t_dims
->get_nof_dims();
5930 if (refd_dim
> nof_dims
) goto error
;
5931 else if (refd_dim
== nof_dims
) {
5932 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5933 t_ass
->get_assname());
5936 } else refd_dim
= 0;
5937 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5941 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5942 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5943 t_ass
->get_description().c_str());
5947 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5948 if (!t_type
) goto error
;
5949 t_type
= t_type
->get_type_refd_last();
5951 switch(t_type
->get_typetype()) {
5968 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5969 " set, set of, objid or array was expected");
5974 // check for index overflows in subrefs if possible
5976 switch (t_val
->get_valuetype()) {
5980 if (t_val
->is_indexed()) {
5987 /* The reference points to a constant. */
5988 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5989 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5990 if (!t_val
) goto error
;
5991 t_val
=t_val
->get_value_refd_last(refch
);
5992 } else { t_val
= 0; }
5993 } else if (t_templ
) {
5994 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5995 time. Don't try to evaluate it at compile time. */
5996 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5998 /* The reference points to a static template. */
5999 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
6000 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
6001 if (!t_templ
) goto error
;
6002 t_templ
= t_templ
->get_template_refd_last(refch
);
6003 } else { t_templ
= 0; }
6006 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
6008 switch(t_templ
->get_templatetype()) {
6009 case Template::TEMPLATE_ERROR
:
6011 case Template::TEMPLATE_REFD
:
6015 case Template::SPECIFIC_VALUE
:
6016 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
6019 case Template::TEMPLATE_LIST
:
6020 case Template::NAMED_TEMPLATE_LIST
:
6023 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
6024 t_templ
->get_templatetype_str(),
6025 t_templ
->get_fullname().c_str());
6030 switch(t_val
->get_valuetype()) {
6041 // error is already reported
6050 if(t_type
->get_typetype()==Type::T_ARRAY
) {
6051 result
= t_type
->get_dimension()->get_size();
6053 else if(t_templ
) { // sizeof()
6054 switch(t_templ
->get_templatetype()) {
6055 case Template::TEMPLATE_LIST
:
6056 if(t_templ
->temps_contains_anyornone_symbol()) {
6057 if(t_templ
->is_length_restricted()) {
6058 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
6059 if (lr
->get_is_range()) {
6060 Value
*v_upper
= lr
->get_upper_value();
6062 if (v_upper
->valuetype
== V_INT
) {
6064 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
6065 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
6068 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
6069 "templates without exact size");
6074 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
6075 "templates containing `*' without upper boundary in the "
6076 "length restriction");
6080 Value
*v_single
= lr
->get_single_value();
6081 if (v_single
->valuetype
== V_INT
)
6082 result
= v_single
->u
.val_Int
->get_val();
6085 else { // not length restricted
6086 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
6087 " containing `*' without length restriction");
6091 else result
=t_templ
->get_nof_listitems();
6093 case Template::NAMED_TEMPLATE_LIST
:
6095 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
6096 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
6097 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
6100 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6104 switch(t_val
->get_valuetype()) {
6111 result
=t_val
->get_nof_comps();
6116 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
6117 if(t_val
->get_se_comp_byIndex(i
)->get_value()
6118 ->get_valuetype()!=V_OMIT
) result
++;
6122 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6128 set_valuetype(V_ERROR
);
6132 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
6134 Type
*governor
= ti
->get_expr_governor(exp_val
);
6136 ti
->get_Template()->set_lowerid_to_ref();
6137 governor
= ti
->get_expr_governor(exp_val
);
6141 ti
->append_stringRepr( str
);
6142 ti
->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6143 "If type is known, use valueof(<type>: %s) as argument.",
6144 str
.c_str(), get_opname(), str
.c_str());
6145 set_valuetype(V_ERROR
);
6150 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
6153 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
6154 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
6155 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
6156 Type::EXPECTED_TEMPLATE
: exp_val
);
6158 Template
*t_temp
= u
.expr
.t2
->get_Template();
6159 if (t_temp
->is_undef_lowerid()) {
6160 // We convert the template to reference first even if the value is also
6161 // an undef lowerid. The user can prevent this by explicit type
6163 t_temp
->set_lowerid_to_ref();
6165 } else if (u
.expr
.v1
->is_undef_lowerid()) {
6166 u
.expr
.v1
->set_lowerid_to_ref();
6171 error("Cannot determine the type of arguments in `match()' operation");
6172 set_valuetype(V_ERROR
);
6175 u
.expr
.v1
->set_my_governor(governor
);
6177 Error_Context
cntxt(this, "In the first argument of `match()'"
6179 governor
->chk_this_value_ref(u
.expr
.v1
);
6180 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
6181 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6184 Error_Context
cntxt(this, "In the second argument of `match()' "
6186 u
.expr
.t2
->chk(governor
);
6190 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
6191 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
6193 Ttcn::StatementBlock
*my_sb
;
6195 case Type::EXPECTED_CONSTANT
:
6196 error("An evaluable constant value was expected instead of operation "
6197 "`%s'", get_opname());
6199 case Type::EXPECTED_STATIC_VALUE
:
6200 error("A static value was expected instead of operation `%s'",
6206 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6207 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
6209 error("Operation `%s' is allowed only within statements",
6213 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6214 error("Operation `%s' is not allowed in the control part",
6218 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6219 error("Operation `%s' cannot be used in a definition that has "
6220 "`runs on' clause", get_opname());
6223 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6224 error("Operation `%s' can be used only in a definition that has "
6225 "`runs on' clause", get_opname());
6230 set_valuetype(V_ERROR
);
6233 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6235 if(valuetype
==V_ERROR
) return;
6236 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6237 if(v
->is_unfoldable()) return;
6238 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6239 ttcn3float r
= v
->get_val_Real();
6240 if (isSpecialFloatValue(r
)) {
6241 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6242 opnum
, opname
, Real2string(r
).c_str());
6243 set_valuetype(V_ERROR
);
6247 void Value::chk_expr_operands(ReferenceChain
*refch
,
6248 Type::expected_value_t exp_val
)
6250 const char *first
="First", *second
="Second", *third
="Third",
6251 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6252 Value
*v1
, *v2
, *v3
;
6253 Type::typetype_t tt1
, tt2
, tt3
;
6254 Type
t_chk(Type::T_ERROR
);
6256 const char *opname
=get_opname();
6258 // first classify the unchecked ischosen() operation
6259 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6261 switch (u
.expr
.v_optype
) {
6262 case OPTYPE_COMP_NULL
:
6263 case OPTYPE_TESTCASENAME
:
6264 case OPTYPE_PROF_RUNNING
:
6266 case OPTYPE_COMP_MTC
:
6267 case OPTYPE_COMP_SYSTEM
:
6268 chk_expr_comptype_compat();
6270 case OPTYPE_RND
: // -
6271 case OPTYPE_TMR_RUNNING_ANY
:
6272 chk_expr_dynamic_part(exp_val
, true);
6274 case OPTYPE_COMP_RUNNING_ANY
:
6275 case OPTYPE_COMP_RUNNING_ALL
:
6276 case OPTYPE_COMP_ALIVE_ANY
:
6277 case OPTYPE_COMP_ALIVE_ALL
:
6278 case OPTYPE_GETVERDICT
:
6279 chk_expr_dynamic_part(exp_val
, false);
6281 case OPTYPE_COMP_SELF
:
6282 chk_expr_comptype_compat();
6283 chk_expr_dynamic_part(exp_val
, false, true, false);
6285 case OPTYPE_UNARYPLUS
: // v1
6286 case OPTYPE_UNARYMINUS
:
6289 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6290 v1
->set_lowerid_to_ref();
6291 tt1
=v1
->get_expr_returntype(exp_val
);
6292 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6293 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6299 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6300 v1
->set_lowerid_to_ref();
6301 tt1
=v1
->get_expr_returntype(exp_val
);
6302 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6303 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6309 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6310 v1
->set_lowerid_to_ref();
6311 tt1
=v1
->get_expr_returntype(exp_val
);
6312 chk_expr_operandtype_binstr(tt1
, the
, opname
, v1
);
6313 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6316 case OPTYPE_BIT2HEX
:
6317 case OPTYPE_BIT2OCT
:
6318 case OPTYPE_BIT2STR
:
6321 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6322 v1
->set_lowerid_to_ref();
6323 tt1
=v1
->get_expr_returntype(exp_val
);
6324 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6325 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6328 case OPTYPE_BIT2INT
:
6331 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6332 v1
->set_lowerid_to_ref();
6333 tt1
=v1
->get_expr_returntype(exp_val
);
6334 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6335 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6336 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6339 case OPTYPE_CHAR2INT
:
6342 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6343 v1
->set_lowerid_to_ref();
6344 tt1
=v1
->get_expr_returntype(exp_val
);
6345 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6346 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6347 chk_expr_val_len1(v1
, the
, opname
);
6350 case OPTYPE_CHAR2OCT
:
6353 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6354 v1
->set_lowerid_to_ref();
6355 tt1
=v1
->get_expr_returntype(exp_val
);
6356 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6357 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6360 case OPTYPE_STR2INT
:
6363 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6364 v1
->set_lowerid_to_ref();
6365 tt1
=v1
->get_expr_returntype(exp_val
);
6366 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6367 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6368 chk_expr_val_str_int(v1
, the
, opname
);
6371 case OPTYPE_STR2FLOAT
:
6374 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6375 v1
->set_lowerid_to_ref();
6376 tt1
=v1
->get_expr_returntype(exp_val
);
6377 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6378 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6379 chk_expr_val_str_float(v1
, the
, opname
);
6382 case OPTYPE_STR2BIT
:
6385 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6386 v1
->set_lowerid_to_ref();
6387 tt1
=v1
->get_expr_returntype(exp_val
);
6388 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6389 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6390 chk_expr_val_str_bindigits(v1
, the
, opname
);
6393 case OPTYPE_STR2HEX
:
6396 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6397 v1
->set_lowerid_to_ref();
6398 tt1
=v1
->get_expr_returntype(exp_val
);
6399 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6400 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6401 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6404 case OPTYPE_STR2OCT
:
6407 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6408 v1
->set_lowerid_to_ref();
6409 tt1
=v1
->get_expr_returntype(exp_val
);
6410 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6411 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6412 chk_expr_val_str_len_even(v1
, the
, opname
);
6413 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6416 case OPTYPE_ENUM2INT
:
6419 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6420 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6421 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6425 chk_expr_operand_encode(refch
, exp_val
);
6427 case OPTYPE_FLOAT2INT
:
6428 case OPTYPE_FLOAT2STR
:
6431 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6432 v1
->set_lowerid_to_ref();
6433 tt1
=v1
->get_expr_returntype(exp_val
);
6434 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6435 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6436 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6437 chk_expr_operand_valid_float(v1
, the
, opname
);
6440 case OPTYPE_RNDWITHVAL
:
6443 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6444 v1
->set_lowerid_to_ref();
6445 tt1
=v1
->get_expr_returntype(exp_val
);
6446 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6447 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6448 chk_expr_operand_valid_float(v1
, the
, opname
);
6450 chk_expr_dynamic_part(exp_val
, true);
6452 case OPTYPE_HEX2BIT
:
6453 case OPTYPE_HEX2OCT
:
6454 case OPTYPE_HEX2STR
:
6457 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6458 v1
->set_lowerid_to_ref();
6459 tt1
=v1
->get_expr_returntype(exp_val
);
6460 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6461 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6464 case OPTYPE_HEX2INT
:
6467 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6468 v1
->set_lowerid_to_ref();
6469 tt1
=v1
->get_expr_returntype(exp_val
);
6470 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6471 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6472 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6475 case OPTYPE_INT2CHAR
:
6478 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6479 v1
->set_lowerid_to_ref();
6480 tt1
=v1
->get_expr_returntype(exp_val
);
6481 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6482 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6483 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6486 case OPTYPE_INT2UNICHAR
:
6489 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6490 v1
->set_lowerid_to_ref();
6491 tt1
=v1
->get_expr_returntype(exp_val
);
6492 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6493 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6494 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6497 case OPTYPE_INT2FLOAT
:
6498 case OPTYPE_INT2STR
:
6501 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6502 v1
->set_lowerid_to_ref();
6503 tt1
=v1
->get_expr_returntype(exp_val
);
6504 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6505 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6508 case OPTYPE_OCT2BIT
:
6509 case OPTYPE_OCT2HEX
:
6510 case OPTYPE_OCT2STR
:
6513 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6514 v1
->set_lowerid_to_ref();
6515 tt1
=v1
->get_expr_returntype(exp_val
);
6516 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6517 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6520 case OPTYPE_OCT2INT
:
6523 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6524 v1
->set_lowerid_to_ref();
6525 tt1
=v1
->get_expr_returntype(exp_val
);
6526 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6527 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6528 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6532 case OPTYPE_OCT2CHAR
:
6535 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6536 v1
->set_lowerid_to_ref();
6537 tt1
=v1
->get_expr_returntype(exp_val
);
6538 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6539 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6540 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6543 case OPTYPE_REMOVE_BOM
:
6546 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6547 v1
->set_lowerid_to_ref();
6548 tt1
=v1
->get_expr_returntype(exp_val
);
6549 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6550 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6553 case OPTYPE_GET_STRINGENCODING
:
6556 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6557 v1
->set_lowerid_to_ref();
6558 tt1
=v1
->get_expr_returntype(exp_val
);
6559 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6560 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6563 case OPTYPE_ENCODE_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_ostr(tt1
, the
, opname
, v1
);
6570 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6572 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6575 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6576 v2
->set_lowerid_to_ref();
6577 tt2
=v2
->get_expr_returntype(exp_val
);
6578 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6579 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6582 case OPTYPE_DECODE_BASE64
:
6585 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6586 v1
->set_lowerid_to_ref();
6587 tt1
=v1
->get_expr_returntype(exp_val
);
6588 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6589 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6592 case OPTYPE_UNICHAR2INT
:
6595 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6596 v1
->set_lowerid_to_ref();
6597 tt1
=v1
->get_expr_returntype(exp_val
);
6598 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6599 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6600 chk_expr_val_len1(v1
, the
, opname
);
6603 case OPTYPE_UNICHAR2CHAR
:
6606 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6607 v1
->set_lowerid_to_ref();
6608 tt1
=v1
->get_expr_returntype(exp_val
);
6609 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6610 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6611 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6615 v1
=u
.expr
.v1
? u
.expr
.v1
: 0;
6618 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6619 v1
->set_lowerid_to_ref();
6620 tt1
=v1
->get_expr_returntype(exp_val
);
6621 chk_expr_operandtype_cstr(tt1
, second
, opname
, v1
);
6622 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6625 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6628 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6629 v1
->set_lowerid_to_ref();
6630 tt1
=v1
->get_expr_returntype(exp_val
);
6631 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6632 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6634 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6637 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6638 v2
->set_lowerid_to_ref();
6639 tt2
=v2
->get_expr_returntype(exp_val
);
6640 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6641 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6644 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6647 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6648 v1
->set_lowerid_to_ref();
6649 tt1
=v1
->get_expr_returntype(exp_val
);
6650 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6651 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6653 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6656 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6657 v2
->set_lowerid_to_ref();
6658 tt2
=v2
->get_expr_returntype(exp_val
);
6659 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6660 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6663 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
6664 chk_expr_operand_encode(refch
, exp_val
);
6665 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6668 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6669 v2
->set_lowerid_to_ref();
6670 tt2
=v2
->get_expr_returntype(exp_val
);
6671 chk_expr_operandtype_charstr(tt2
, second
, opname
, v2
);
6672 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6675 case OPTYPE_DECVALUE_UNICHAR
:
6676 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR
);
6677 v3
=u
.expr
.v3
? u
.expr
.v3
: 0;
6680 Error_Context
cntxt(this, "In the thrid operand of operation `%s'", opname
);
6681 v3
->set_lowerid_to_ref();
6682 tt3
=v3
->get_expr_returntype(exp_val
);
6683 chk_expr_operandtype_charstr(tt3
, third
, opname
, v3
);
6684 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6687 case OPTYPE_ADD
: // v1 v2
6688 case OPTYPE_SUBTRACT
:
6689 case OPTYPE_MULTIPLY
:
6693 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6694 v1
->set_lowerid_to_ref();
6695 tt1
=v1
->get_expr_returntype(exp_val
);
6696 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6697 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6698 chk_expr_operand_valid_float(v1
, first
, opname
);
6702 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6703 v2
->set_lowerid_to_ref();
6704 tt2
=v2
->get_expr_returntype(exp_val
);
6705 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6706 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6707 chk_expr_operand_valid_float(v2
, second
, opname
);
6708 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6709 chk_expr_val_int_float_not0(v2
, second
, opname
);
6711 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6717 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6718 v1
->set_lowerid_to_ref();
6719 tt1
=v1
->get_expr_returntype(exp_val
);
6720 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6721 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6725 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6726 v2
->set_lowerid_to_ref();
6727 tt2
=v2
->get_expr_returntype(exp_val
);
6728 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6729 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6730 chk_expr_val_int_float_not0(v2
, right
, opname
);
6733 case OPTYPE_CONCAT
: {
6736 v1
->set_lowerid_to_ref();
6737 v2
->set_lowerid_to_ref();
6738 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6740 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6741 tt1
=v1
->get_expr_returntype(exp_val
);
6742 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6743 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6746 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6747 tt2
=v2
->get_expr_returntype(exp_val
);
6748 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6749 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6751 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6752 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6753 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6754 } else { // other list types
6755 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6756 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6758 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6759 set_valuetype(V_ERROR
);
6762 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6763 v1_gov
->chk_this_value_ref(v1
);
6764 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6765 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6766 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6770 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6771 set_valuetype(V_ERROR
);
6774 // for recof/setof literals set the type from v1
6776 v2
->set_my_governor(v1_gov
);
6779 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6781 v2_gov
->chk_this_value_ref(v2
);
6782 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6783 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6784 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6785 if (valuetype
== V_ERROR
) return;
6786 // 7.1.2 says that we shouldn't allow type compatibility.
6787 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6788 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6789 error("The operands of operation `%s' should be of compatible "
6790 "types", get_opname());
6799 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6801 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6803 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6806 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6808 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6809 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6810 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6811 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6812 * "a == not b" is not allowed. (HL69107)
6813 * The various *Expressions implement operator precedence in the std.
6814 * Titan's parser has only one Expression and relies on Bison
6815 * for operator precedence. The check below brings Titan in line
6816 * with the standard by explicitly making "a == not b" an error */
6817 if (v2
->get_valuetype() == V_EXPR
6818 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6819 error("The operation `%s' is not allowed to be "
6820 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6821 set_valuetype(V_ERROR
);
6831 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6833 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6835 tt1
=v1
->get_expr_returntype(exp_val
);
6836 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6837 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6840 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6842 tt2
=v2
->get_expr_returntype(exp_val
);
6843 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6844 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6852 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6854 v1
->set_lowerid_to_ref();
6855 tt1
=v1
->get_expr_returntype(exp_val
);
6856 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6857 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6861 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6863 v2
->set_lowerid_to_ref();
6864 tt2
=v2
->get_expr_returntype(exp_val
);
6865 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6866 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6874 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6876 v1
->set_lowerid_to_ref();
6877 tt1
=v1
->get_expr_returntype(exp_val
);
6878 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6879 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6883 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6885 v2
->set_lowerid_to_ref();
6886 tt2
=v2
->get_expr_returntype(exp_val
);
6887 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6888 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6890 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6891 chk_expr_operands_str_samelen();
6897 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6898 v1
->set_lowerid_to_ref();
6899 tt1
=v1
->get_expr_returntype(exp_val
);
6900 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6901 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6905 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6906 v2
->set_lowerid_to_ref();
6907 tt2
=v2
->get_expr_returntype(exp_val
);
6908 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6909 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6910 chk_expr_val_large_int(v2
, right
, opname
);
6916 v1
->set_lowerid_to_ref();
6917 if (v1
->is_string_type(exp_val
)) {
6918 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6919 tt1
=v1
->get_expr_returntype(exp_val
);
6920 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6921 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6922 } else { // other list types
6923 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6924 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6925 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6927 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6928 v1_gov
->chk_this_value_ref(v1
);
6929 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6930 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6931 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6936 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6937 v2
->set_lowerid_to_ref();
6938 tt2
=v2
->get_expr_returntype(exp_val
);
6939 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6940 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6941 chk_expr_val_large_int(v2
, right
, opname
);
6944 case OPTYPE_INT2BIT
:
6945 case OPTYPE_INT2HEX
:
6946 case OPTYPE_INT2OCT
:
6949 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6950 v1
->set_lowerid_to_ref();
6951 tt1
=v1
->get_expr_returntype(exp_val
);
6952 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6953 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6954 chk_expr_val_int_pos0(v1
, first
, opname
);
6958 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6959 v2
->set_lowerid_to_ref();
6960 tt2
=v2
->get_expr_returntype(exp_val
);
6961 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6962 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6963 chk_expr_val_int_pos0(v2
, second
, opname
);
6965 chk_expr_operands_int2binstr();
6968 chk_expr_operands_decode(OPTYPE_DECODE
);
6972 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
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
;
6975 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6976 if (!governor
) return;
6977 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6978 if (valuetype
!=V_ERROR
)
6979 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6980 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6984 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6985 v2
->set_lowerid_to_ref();
6986 tt2
=v2
->get_expr_returntype(exp_val
);
6987 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6988 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6989 chk_expr_val_int_pos0(v2
, second
, opname
);
6993 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6994 v3
->set_lowerid_to_ref();
6995 tt3
=v3
->get_expr_returntype(exp_val
);
6996 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6997 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6998 chk_expr_val_int_pos0(v3
, third
, opname
);
7000 chk_expr_operands_substr();
7002 case OPTYPE_REGEXP
: {
7003 Type::expected_value_t ti_exp_val
= exp_val
;
7004 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7006 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7007 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7008 if (!governor
) return;
7009 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7010 if (valuetype
!=V_ERROR
) {
7011 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7012 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
7013 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
7017 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
7018 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
7019 if (!governor
) return;
7020 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
7021 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
7022 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
7026 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
7027 v3
->set_lowerid_to_ref();
7028 tt3
=v3
->get_expr_returntype(exp_val
);
7029 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
7030 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7031 chk_expr_val_int_pos0(v3
, third
, opname
);
7033 chk_expr_operands_regexp();
7035 case OPTYPE_ISCHOSEN
:
7036 // do nothing: the operand is erroneous
7037 // the error was already reported in chk_expr_ref_ischosen()
7039 case OPTYPE_ISCHOSEN_V
: // v1 i2
7040 case OPTYPE_ISCHOSEN_T
: // t1 i2
7041 chk_expr_operands_ischosen(refch
, exp_val
);
7043 case OPTYPE_VALUEOF
: { // ti1
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
= my_governor
;
7048 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7049 if (!governor
) return;
7050 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7051 if (valuetype
== V_ERROR
) return;
7052 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7054 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
7055 case OPTYPE_ISBOUND
: {
7056 Template
*templ
= u
.expr
.ti1
->get_Template();
7057 switch (templ
->get_templatetype()) {
7058 case Template::TEMPLATE_REFD
:
7059 templ
->get_reference()->setUsedInIsbound();
7061 case Template::SPECIFIC_VALUE
: {
7062 Value
*value
= templ
->get_specific_value();
7063 if (Value::V_REFD
== value
->get_valuetype()) {
7064 value
->get_reference()->setUsedInIsbound();
7072 case OPTYPE_ISVALUE
: {// ti1
7073 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
7074 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7075 exp_val
= Type::EXPECTED_TEMPLATE
;
7076 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7077 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7078 if (!governor
) return;
7079 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
7080 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7082 case OPTYPE_SIZEOF
: // ti1
7083 /* this checking is too complex, do the checking during eval... */
7085 case OPTYPE_LENGTHOF
: { // ti1
7086 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7087 exp_val
= Type::EXPECTED_TEMPLATE
;
7088 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7089 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
7090 if (!governor
) return;
7091 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
7092 if (valuetype
== V_ERROR
) return;
7093 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
7095 case OPTYPE_MATCH
: // v1 t2
7096 chk_expr_operands_match(exp_val
);
7098 case OPTYPE_UNDEF_RUNNING
: // r1
7099 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
7101 case OPTYPE_COMP_ALIVE
:
7102 case OPTYPE_COMP_RUNNING
: //v1
7103 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
7104 chk_expr_dynamic_part(exp_val
, false);
7106 case OPTYPE_TMR_READ
: // r1
7107 case OPTYPE_TMR_RUNNING
: // r1
7108 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
7109 chk_expr_dynamic_part(exp_val
, true);
7111 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
7112 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
7113 chk_expr_dynamic_part(exp_val
, true, false, false);
7115 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7116 chk_expr_operand_comptyperef_create();
7119 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7120 v2
->set_lowerid_to_ref();
7121 tt2
=v2
->get_expr_returntype(exp_val
);
7122 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
7123 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7127 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
7128 v3
->set_lowerid_to_ref();
7129 tt3
=v3
->get_expr_returntype(exp_val
);
7130 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
7131 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7133 chk_expr_dynamic_part(exp_val
, false);
7135 case OPTYPE_ACTIVATE
: // r1 // altstep
7136 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
7137 chk_expr_dynamic_part(exp_val
, true);
7139 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
7140 case OPTYPE_CHECKSTATE_ALL
:
7141 chk_expr_dynamic_part(exp_val
, false);
7144 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
7145 v2
->set_lowerid_to_ref();
7146 tt2
=v2
->get_expr_returntype(exp_val
);
7147 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
7148 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7151 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
7152 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7153 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
7155 delete u
.expr
.t_list2
;
7156 u
.expr
.ap_list2
= parlist
;
7157 chk_expr_dynamic_part(exp_val
, true);
7159 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
7160 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
7161 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
7162 u
.expr
.v3
, the
, opname
);
7163 delete u
.expr
.t_list2
;
7164 u
.expr
.ap_list2
= parlist
;
7165 chk_expr_dynamic_part(exp_val
, true);
7168 error("Built-in function `%s' is not yet supported", opname
);
7169 set_valuetype(V_ERROR
);
7171 case OPTYPE_REPLACE
: {
7172 Type::expected_value_t ti_exp_val
= exp_val
;
7173 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
7174 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7176 Error_Context
cntxt(this, "In the first operand of operation `%s'",
7178 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7179 if (!governor
) return;
7180 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7181 if (valuetype
!= V_ERROR
)
7182 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
7183 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
7187 Error_Context
cntxt(this, "In the second operand of operation `%s'",
7189 v2
->set_lowerid_to_ref();
7190 tt2
= v2
->get_expr_returntype(exp_val
);
7191 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
7192 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
7193 chk_expr_val_int_pos0(v2
, second
, opname
);
7197 Error_Context
cntxt(this, "In the third operand of operation `%s'",
7199 v3
->set_lowerid_to_ref();
7200 tt3
= v3
->get_expr_returntype(exp_val
);
7201 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
7202 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
7203 chk_expr_val_int_pos0(v3
, third
, opname
);
7206 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
7208 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
7209 if (!governor
) return;
7210 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
7211 if (valuetype
!= V_ERROR
)
7212 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
7213 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
7215 chk_expr_operands_replace();
7217 case OPTYPE_LOG2STR
:
7218 case OPTYPE_ANY2UNISTR
: {
7219 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
7220 u
.expr
.logargs
->chk();
7221 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
7223 case OPTYPE_TTCN2STRING
: {
7224 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
7225 Type::expected_value_t ti_exp_val
= exp_val
;
7226 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7227 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7228 if (!governor
) return;
7229 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7232 FATAL_ERROR("chk_expr_operands()");
7236 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7237 // the result of evaluating the expression. E.g. V_BOOL for
7239 void Value::evaluate_value(ReferenceChain
*refch
,
7240 Type::expected_value_t exp_val
)
7242 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
7243 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
7245 u
.expr
.state
=EXPR_CHECKING
;
7247 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
7248 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
7249 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
7251 if(valuetype
==V_ERROR
) return;
7252 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
7253 u
.expr
.state
=EXPR_CHECKED
;
7254 set_valuetype(V_ERROR
);
7258 u
.expr
.state
=EXPR_CHECKED
;
7260 Value
*v1
, *v2
, *v3
, *v4
;
7261 switch(u
.expr
.v_optype
) {
7262 case OPTYPE_RND
: // -
7263 case OPTYPE_COMP_NULL
: // the only foldable in this group
7264 case OPTYPE_COMP_MTC
:
7265 case OPTYPE_COMP_SYSTEM
:
7266 case OPTYPE_COMP_SELF
:
7267 case OPTYPE_COMP_RUNNING_ANY
:
7268 case OPTYPE_COMP_RUNNING_ALL
:
7269 case OPTYPE_COMP_ALIVE_ANY
:
7270 case OPTYPE_COMP_ALIVE_ALL
:
7271 case OPTYPE_TMR_RUNNING_ANY
:
7272 case OPTYPE_GETVERDICT
:
7273 case OPTYPE_PROF_RUNNING
:
7274 case OPTYPE_RNDWITHVAL
: // v1
7275 case OPTYPE_COMP_RUNNING
: // v1
7276 case OPTYPE_COMP_ALIVE
:
7277 case OPTYPE_TMR_READ
:
7278 case OPTYPE_TMR_RUNNING
:
7279 case OPTYPE_ACTIVATE
:
7280 case OPTYPE_ACTIVATE_REFD
:
7281 case OPTYPE_EXECUTE
: // r1 [v2]
7282 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7283 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7284 case OPTYPE_MATCH
: // v1 t2
7285 case OPTYPE_ISCHOSEN_T
:
7286 case OPTYPE_LOG2STR
:
7287 case OPTYPE_ANY2UNISTR
:
7290 case OPTYPE_ISBOUND
:
7291 case OPTYPE_ISPRESENT
:
7292 case OPTYPE_TTCN2STRING
:
7293 case OPTYPE_UNICHAR2OCT
:
7294 case OPTYPE_OCT2UNICHAR
:
7295 case OPTYPE_ENCODE_BASE64
:
7296 case OPTYPE_DECODE_BASE64
:
7297 case OPTYPE_ENCVALUE_UNICHAR
:
7298 case OPTYPE_DECVALUE_UNICHAR
:
7299 case OPTYPE_CHECKSTATE_ANY
:
7300 case OPTYPE_CHECKSTATE_ALL
:
7303 case OPTYPE_TESTCASENAME
: { // -
7304 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7305 Ttcn::StatementBlock
*my_sb
=
7306 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7308 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7309 if (!my_def
) { // In control part.
7310 set_val_str(new string(""));
7312 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7313 set_val_str(new string(my_def
->get_id().get_dispname()));
7317 case OPTYPE_UNARYPLUS
: // v1
7320 copy_and_destroy(v1
);
7322 case OPTYPE_UNARYMINUS
:
7323 if (is_unfoldable()) break;
7324 v1
= u
.expr
.v1
->get_value_refd_last();
7325 switch (v1
->valuetype
) {
7327 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7328 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7334 ttcn3float r
= v1
->get_val_Real();
7340 FATAL_ERROR("Value::evaluate_value()");
7344 if(is_unfoldable()) break;
7345 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7350 case OPTYPE_NOT4B
: {
7351 if(is_unfoldable()) break;
7352 v1
=u
.expr
.v1
->get_value_refd_last();
7353 const string
& s
= v1
->get_val_str();
7354 valuetype_t vt
=v1
->valuetype
;
7357 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7359 case OPTYPE_BIT2HEX
: {
7360 if(is_unfoldable()) break;
7361 v1
=u
.expr
.v1
->get_value_refd_last();
7362 const string
& s
= v1
->get_val_str();
7365 set_val_str(bit2hex(s
));
7367 case OPTYPE_BIT2OCT
: {
7368 if(is_unfoldable()) break;
7369 v1
=u
.expr
.v1
->get_value_refd_last();
7370 const string
& s
= v1
->get_val_str();
7373 set_val_str(bit2oct(s
));
7375 case OPTYPE_BIT2STR
:
7376 case OPTYPE_HEX2STR
:
7377 case OPTYPE_OCT2STR
: {
7378 if(is_unfoldable()) break;
7379 v1
=u
.expr
.v1
->get_value_refd_last();
7380 const string
& s
= v1
->get_val_str();
7383 set_val_str(new string(s
));
7385 case OPTYPE_BIT2INT
: {
7386 if (is_unfoldable()) break;
7387 v1
= u
.expr
.v1
->get_value_refd_last();
7388 const string
& s
= v1
->get_val_str();
7391 u
.val_Int
= bit2int(s
);
7393 case OPTYPE_CHAR2INT
: {
7394 if (is_unfoldable()) break;
7395 v1
= u
.expr
.v1
->get_value_refd_last();
7396 char c
= v1
->get_val_str()[0];
7399 u
.val_Int
= new int_val_t((Int
)c
);
7401 case OPTYPE_CHAR2OCT
: {
7402 if(is_unfoldable()) break;
7403 v1
=u
.expr
.v1
->get_value_refd_last();
7404 const string
& s
= v1
->get_val_str();
7407 set_val_str(char2oct(s
));
7409 case OPTYPE_STR2INT
: {
7410 if (is_unfoldable()) break;
7411 v1
= u
.expr
.v1
->get_value_refd_last();
7412 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7416 /** \todo hiba eseten lenyeli... */
7418 case OPTYPE_STR2FLOAT
: {
7419 if(is_unfoldable()) break;
7420 v1
=u
.expr
.v1
->get_value_refd_last();
7421 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7425 /** \todo hiba eseten lenyeli... */
7427 case OPTYPE_STR2BIT
: {
7428 if(is_unfoldable()) break;
7429 v1
=u
.expr
.v1
->get_value_refd_last();
7430 const string
& s
= v1
->get_val_str();
7433 set_val_str(new string(s
));
7435 case OPTYPE_STR2HEX
:
7436 case OPTYPE_OCT2HEX
: {
7437 if(is_unfoldable()) break;
7438 v1
=u
.expr
.v1
->get_value_refd_last();
7439 const string
& s
= v1
->get_val_str();
7442 set_val_str(to_uppercase(s
));
7444 case OPTYPE_STR2OCT
: {
7445 if(is_unfoldable()) break;
7446 v1
=u
.expr
.v1
->get_value_refd_last();
7447 const string
& s
= v1
->get_val_str();
7450 set_val_str(to_uppercase(s
));
7452 case OPTYPE_FLOAT2INT
: {
7453 if (is_unfoldable()) break;
7454 v1
= u
.expr
.v1
->get_value_refd_last();
7455 ttcn3float r
= v1
->get_val_Real();
7458 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7460 case OPTYPE_FLOAT2STR
: {
7461 if(is_unfoldable()) break;
7462 v1
=u
.expr
.v1
->get_value_refd_last();
7463 ttcn3float r
=v1
->get_val_Real();
7466 set_val_str(float2str(r
));
7468 case OPTYPE_HEX2BIT
:
7469 case OPTYPE_OCT2BIT
: {
7470 if(is_unfoldable()) break;
7471 v1
=u
.expr
.v1
->get_value_refd_last();
7472 const string
& s
= v1
->get_val_str();
7475 set_val_str(hex2bit(s
));
7477 case OPTYPE_HEX2INT
:
7478 case OPTYPE_OCT2INT
: {
7479 if(is_unfoldable()) break;
7480 v1
=u
.expr
.v1
->get_value_refd_last();
7481 const string
& s
= v1
->get_val_str();
7484 u
.val_Int
=hex2int(s
);
7486 case OPTYPE_HEX2OCT
: {
7487 if(is_unfoldable()) break;
7488 v1
=u
.expr
.v1
->get_value_refd_last();
7489 const string
& s
= v1
->get_val_str();
7492 set_val_str(hex2oct(s
));
7494 case OPTYPE_INT2CHAR
: {
7495 if (is_unfoldable()) break;
7496 v1
= u
.expr
.v1
->get_value_refd_last();
7497 const int_val_t
*c_int
= v1
->get_val_Int();
7498 char c
= static_cast<char>(c_int
->get_val());
7501 set_val_str(new string(1, &c
));
7503 case OPTYPE_INT2UNICHAR
: {
7504 if (is_unfoldable()) break;
7505 v1
= u
.expr
.v1
->get_value_refd_last();
7506 const int_val_t
*i_int
= v1
->get_val_Int();
7507 Int i
= i_int
->get_val();
7510 set_val_ustr(int2unichar(i
));
7511 u
.ustr
.convert_str
= false;
7513 case OPTYPE_INT2FLOAT
: {
7514 if (is_unfoldable()) break;
7515 v1
= u
.expr
.v1
->get_value_refd_last();
7516 const int_val_t
*i_int
= v1
->get_val_Int();
7517 Real i_int_real
= i_int
->to_real();
7520 u
.val_Real
= i_int_real
;
7522 case OPTYPE_INT2STR
: {
7523 if (is_unfoldable()) break;
7524 v1
= u
.expr
.v1
->get_value_refd_last();
7525 const int_val_t
*i_int
= v1
->get_val_Int();
7526 string
*i_int_str
= new string(i_int
->t_str());
7529 set_val_str(i_int_str
);
7531 case OPTYPE_OCT2CHAR
: {
7532 if(is_unfoldable()) break;
7533 v1
=u
.expr
.v1
->get_value_refd_last();
7534 const string
& s
= v1
->get_val_str();
7537 set_val_str(oct2char(s
));
7539 case OPTYPE_GET_STRINGENCODING
: {
7540 if(is_unfoldable()) break;
7541 v1
= u
.expr
.v1
->get_value_refd_last();
7542 const string
& s1
= v1
->get_val_str();
7545 set_val_str(get_stringencoding(s1
));
7547 case OPTYPE_REMOVE_BOM
: {
7548 if(is_unfoldable()) break;
7549 v1
= u
.expr
.v1
->get_value_refd_last();
7550 const string
& s1
= v1
->get_val_str();
7553 set_val_str(remove_bom(s1
));
7555 case OPTYPE_ENUM2INT
: {
7556 if(is_unfoldable()) break;
7557 v1
=u
.expr
.v1
->get_value_refd_last();
7558 Type
* enum_type
= v1
->get_my_governor();
7559 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7562 u
.val_Int
= new int_val_t(enum_val
);
7564 case OPTYPE_UNICHAR2INT
:
7565 if (is_unfoldable()) {
7566 // replace the operation with char2int() if the operand is a charstring
7567 // value to avoid its unnecessary conversion to universal charstring
7568 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7569 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7571 v1
=u
.expr
.v1
->get_value_refd_last();
7572 const ustring
& s
= v1
->get_val_ustr();
7575 u
.val_Int
=new int_val_t(unichar2int(s
));
7578 case OPTYPE_UNICHAR2CHAR
:
7580 if (is_unfoldable()) {
7581 // replace the operation with its operand if it is a charstring
7582 // value to avoid its unnecessary conversion to universal charstring
7583 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7585 copy_and_destroy(v1
);
7588 v1
= v1
->get_value_refd_last();
7589 const ustring
& s
= v1
->get_val_ustr();
7592 set_val_str(new string(s
));
7595 case OPTYPE_MULTIPLY
: { // v1 v2
7596 if (!is_unfoldable()) goto eval_arithmetic
;
7597 v1
= u
.expr
.v1
->get_value_refd_last();
7598 v2
= u
.expr
.v2
->get_value_refd_last();
7599 if (v1
->is_unfoldable()) v1
= v2
;
7600 if (v1
->is_unfoldable()) break;
7601 switch(v1
->valuetype
) {
7603 if (*v1
->get_val_Int() != 0) break;
7606 u
.val_Int
= new int_val_t((Int
)0);
7609 if (v1
->get_val_Real() != 0.0) break;
7615 FATAL_ERROR("Value::evaluate_value()");
7618 case OPTYPE_ADD
: // v1 v2
7619 case OPTYPE_SUBTRACT
:
7624 if(is_unfoldable()) break;
7625 v1
=u
.expr
.v1
->get_value_refd_last();
7626 v2
=u
.expr
.v2
->get_value_refd_last();
7627 operationtype_t ot
=u
.expr
.v_optype
;
7628 switch (v1
->valuetype
) {
7630 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7631 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7636 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7638 case OPTYPE_SUBTRACT
:
7639 u
.val_Int
= new int_val_t(*i1
- *i2
);
7641 case OPTYPE_MULTIPLY
:
7642 u
.val_Int
= new int_val_t(*i1
* *i2
);
7645 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7648 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7651 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7654 FATAL_ERROR("Value::evaluate_value()");
7660 ttcn3float r1
=v1
->get_val_Real();
7661 ttcn3float r2
=v2
->get_val_Real();
7668 case OPTYPE_SUBTRACT
:
7671 case OPTYPE_MULTIPLY
:
7678 FATAL_ERROR("Value::evaluate_value()");
7682 FATAL_ERROR("Value::evaluate_value()");
7685 case OPTYPE_CONCAT
: {
7686 if(is_unfoldable()) break;
7687 v1
=u
.expr
.v1
->get_value_refd_last();
7688 v2
=u
.expr
.v2
->get_value_refd_last();
7689 valuetype_t vt
= v1
->valuetype
;
7690 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7691 const ustring
& s1
= v1
->get_val_ustr();
7692 const ustring
& s2
= v2
->get_val_ustr();
7695 set_val_ustr(new ustring(s1
+ s2
));
7696 u
.ustr
.convert_str
= false;
7698 const string
& s1
= v1
->get_val_str();
7699 const string
& s2
= v2
->get_val_str();
7702 set_val_str(new string(s1
+ s2
));
7706 if(is_unfoldable()) break;
7707 v1
=u
.expr
.v1
->get_value_refd_last();
7708 v2
=u
.expr
.v2
->get_value_refd_last();
7715 if(is_unfoldable()) break;
7716 v1
=u
.expr
.v1
->get_value_refd_last();
7717 v2
=u
.expr
.v2
->get_value_refd_last();
7724 if(is_unfoldable()) break;
7725 v1
=u
.expr
.v1
->get_value_refd_last();
7726 v2
=u
.expr
.v2
->get_value_refd_last();
7733 if(is_unfoldable()) break;
7734 v1
=u
.expr
.v1
->get_value_refd_last();
7735 v2
=u
.expr
.v2
->get_value_refd_last();
7742 if(is_unfoldable()) break;
7743 v1
=u
.expr
.v1
->get_value_refd_last();
7744 v2
=u
.expr
.v2
->get_value_refd_last();
7751 if(is_unfoldable()) break;
7752 v1
=u
.expr
.v1
->get_value_refd_last();
7753 v2
=u
.expr
.v2
->get_value_refd_last();
7760 v1
= u
.expr
.v1
->get_value_refd_last();
7761 if (v1
->valuetype
== V_BOOL
) {
7762 if (v1
->get_val_bool()) {
7763 // the left operand is a literal "true"
7764 // substitute the expression with the right operand
7767 copy_and_destroy(v2
);
7769 // the left operand is a literal "false"
7770 // the result must be false regardless the right operand
7771 // because of the short circuit evaluation rule
7777 // we must keep the left operand because of the potential side effects
7778 // the right operand can only be eliminated if it is a literal "true"
7779 v2
= u
.expr
.v2
->get_value_refd_last();
7780 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7783 copy_and_destroy(v1
);
7788 v1
= u
.expr
.v1
->get_value_refd_last();
7789 if (v1
->valuetype
== V_BOOL
) {
7790 if (v1
->get_val_bool()) {
7791 // the left operand is a literal "true"
7792 // the result must be true regardless the right operand
7793 // because of the short circuit evaluation rule
7798 // the left operand is a literal "false"
7799 // substitute the expression with the right operand
7802 copy_and_destroy(v2
);
7805 // we must keep the left operand because of the potential side effects
7806 // the right operand can only be eliminated if it is a literal "false"
7807 v2
= u
.expr
.v2
->get_value_refd_last();
7808 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7811 copy_and_destroy(v1
);
7816 if(is_unfoldable()) break;
7817 v1
=u
.expr
.v1
->get_value_refd_last();
7818 v2
=u
.expr
.v2
->get_value_refd_last();
7819 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7824 case OPTYPE_AND4B
: {
7825 if(is_unfoldable()) break;
7826 v1
=u
.expr
.v1
->get_value_refd_last();
7827 v2
=u
.expr
.v2
->get_value_refd_last();
7828 valuetype_t vt
=v1
->valuetype
;
7829 const string
& s1
= v1
->get_val_str();
7830 const string
& s2
= v2
->get_val_str();
7833 set_val_str(and4b(s1
, s2
));
7836 if(is_unfoldable()) break;
7837 v1
=u
.expr
.v1
->get_value_refd_last();
7838 v2
=u
.expr
.v2
->get_value_refd_last();
7839 valuetype_t vt
=v1
->valuetype
;
7840 const string
& s1
= v1
->get_val_str();
7841 const string
& s2
= v2
->get_val_str();
7844 set_val_str(or4b(s1
, s2
));
7846 case OPTYPE_XOR4B
: {
7847 if(is_unfoldable()) break;
7848 v1
=u
.expr
.v1
->get_value_refd_last();
7849 v2
=u
.expr
.v2
->get_value_refd_last();
7850 valuetype_t vt
=v1
->valuetype
;
7851 const string
& s1
= v1
->get_val_str();
7852 const string
& s2
= v2
->get_val_str();
7855 set_val_str(xor4b(s1
, s2
));
7858 if(is_unfoldable()) break;
7859 v1
=u
.expr
.v1
->get_value_refd_last();
7860 v2
=u
.expr
.v2
->get_value_refd_last();
7861 valuetype_t vt
=v1
->valuetype
;
7862 const string
& s
= v1
->get_val_str();
7863 const int_val_t
*i_int
= v2
->get_val_Int();
7864 Int i
=i_int
->get_val();
7865 if(vt
==V_OSTR
) i
*=2;
7868 set_val_str(shift_left(s
, i
));
7871 if(is_unfoldable()) break;
7872 v1
=u
.expr
.v1
->get_value_refd_last();
7873 v2
=u
.expr
.v2
->get_value_refd_last();
7874 valuetype_t vt
=v1
->valuetype
;
7875 const string
& s
= v1
->get_val_str();
7876 const int_val_t
*i_int
= v2
->get_val_Int();
7877 Int i
=i_int
->get_val();
7878 if(vt
==V_OSTR
) i
*=2;
7881 set_val_str(shift_right(s
, i
));
7884 if(is_unfoldable()) break;
7885 v1
=u
.expr
.v1
->get_value_refd_last();
7886 v2
=u
.expr
.v2
->get_value_refd_last();
7887 valuetype_t vt
=v1
->valuetype
;
7888 const int_val_t
*i_int
=v2
->get_val_Int();
7889 Int i
=i_int
->get_val();
7891 const ustring
& s
= v1
->get_val_ustr();
7894 set_val_ustr(rotate_left(s
, i
));
7895 u
.ustr
.convert_str
= false;
7898 if(vt
==V_OSTR
) i
*=2;
7899 const string
& s
= v1
->get_val_str();
7902 set_val_str(rotate_left(s
, i
));
7906 if(is_unfoldable()) break;
7907 v1
=u
.expr
.v1
->get_value_refd_last();
7908 v2
=u
.expr
.v2
->get_value_refd_last();
7909 valuetype_t vt
=v1
->valuetype
;
7910 const int_val_t
*i_int
=v2
->get_val_Int();
7911 Int i
=i_int
->get_val();
7913 const ustring
& s
= v1
->get_val_ustr();
7916 set_val_ustr(rotate_right(s
, i
));
7917 u
.ustr
.convert_str
= false;
7920 if(vt
==V_OSTR
) i
*=2;
7921 const string
& s
= v1
->get_val_str();
7924 set_val_str(rotate_right(s
, i
));
7927 case OPTYPE_INT2BIT
: {
7928 if (is_unfoldable()) break;
7929 v1
= u
.expr
.v1
->get_value_refd_last();
7930 v2
= u
.expr
.v2
->get_value_refd_last();
7931 const int_val_t
*i1_int
= v1
->get_val_Int();
7932 const int_val_t
*i2_int
= v2
->get_val_Int();
7933 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7938 case OPTYPE_INT2HEX
: {
7939 if (is_unfoldable()) break;
7940 v1
= u
.expr
.v1
->get_value_refd_last();
7941 v2
= u
.expr
.v2
->get_value_refd_last();
7942 const int_val_t
*i1_int
= v1
->get_val_Int();
7943 const int_val_t
*i2_int
= v2
->get_val_Int();
7944 // Do it before the `clean_up'. i2_int is already checked.
7945 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7950 case OPTYPE_INT2OCT
: {
7951 if (is_unfoldable()) break;
7952 v1
= u
.expr
.v1
->get_value_refd_last();
7953 v2
= u
.expr
.v2
->get_value_refd_last();
7954 const int_val_t
i1_int(*v1
->get_val_Int());
7955 // `v2' is a native integer.
7956 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7959 set_val_str(int2hex(i1_int
, i2_int
));
7961 case OPTYPE_SUBSTR
: {
7962 if(is_unfoldable()) break;
7963 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7964 v2
=u
.expr
.v2
->get_value_refd_last();
7965 v3
=u
.expr
.v3
->get_value_refd_last();
7966 valuetype_t vt
=v1
->valuetype
;
7967 const int_val_t
*i2_int
=v2
->get_val_Int();
7968 const int_val_t
*i3_int
=v3
->get_val_Int();
7969 Int i2
=i2_int
->get_val();
7970 Int i3
=i3_int
->get_val();
7972 const ustring
& s
= v1
->get_val_ustr();
7975 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7976 u
.ustr
.convert_str
= false;
7983 const string
& s
= v1
->get_val_str();
7986 set_val_str(new string(s
.substr(i2
, i3
)));
7989 case OPTYPE_REPLACE
: {
7990 if(is_unfoldable()) break;
7991 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7992 v2
=u
.expr
.v2
->get_value_refd_last();
7993 v3
=u
.expr
.v3
->get_value_refd_last();
7994 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7995 valuetype_t vt
=v1
->valuetype
;
7996 const int_val_t
*i2_int
=v2
->get_val_Int();
7997 const int_val_t
*i3_int
=v3
->get_val_Int();
7998 Int i2
=i2_int
->get_val();
7999 Int i3
=i3_int
->get_val();
8002 string
*s1
= new string(v1
->get_val_str());
8003 const string
& s2
= v4
->get_val_str();
8006 s1
->replace(i2
, i3
, s2
);
8010 string
*s1
= new string(v1
->get_val_str());
8011 const string
& s2
= v4
->get_val_str();
8014 s1
->replace(i2
, i3
, s2
);
8020 string
*s1
= new string(v1
->get_val_str());
8021 const string
& s2
= v4
->get_val_str();
8024 s1
->replace(i2
, i3
, s2
);
8028 string
*s1
= new string(v1
->get_val_str());
8029 const string
& s2
= v4
->get_val_str();
8032 s1
->replace(i2
, i3
, s2
);
8036 ustring
*s1
= new ustring(v1
->get_val_ustr());
8037 const ustring
& s2
= v4
->get_val_ustr();
8040 s1
->replace(i2
, i3
, s2
);
8042 u
.ustr
.convert_str
= false;
8045 FATAL_ERROR("Value::evaluate_value()");
8048 case OPTYPE_REGEXP
: {
8049 if (is_unfoldable()) break;
8050 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
8051 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
8052 v3
=u
.expr
.v3
->get_value_refd_last();
8053 const int_val_t
*i3_int
= v3
->get_val_Int();
8054 Int i3
= i3_int
->get_val();
8055 if (v1
->valuetype
== V_CSTR
) {
8056 const string
& s1
= v1
->get_val_str();
8057 const string
& s2
= v2
->get_val_str();
8058 string
*result
= regexp(s1
, s2
, i3
);
8061 set_val_str(result
);
8062 } if (v1
->valuetype
== V_USTR
) {
8063 const ustring
& s1
= v1
->get_val_ustr();
8064 const ustring
& s2
= v2
->get_val_ustr();
8065 ustring
*result
= regexp(s1
, s2
, i3
);
8068 set_val_ustr(result
);
8069 u
.ustr
.convert_str
= false;
8072 case OPTYPE_LENGTHOF
:{
8073 if(is_unfoldable()) break;
8074 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
8075 ->get_value_refd_last();
8077 if(v1
->is_string_type(exp_val
)) {
8078 i
=v1
->get_val_strlen();
8079 } else { // v1 is be seq/set of or array
8080 switch (v1
->valuetype
) {
8084 if(v1
->u
.val_vs
->is_indexed())
8085 { i
= v1
->u
.val_vs
->get_nof_ivs();}
8086 else { i
= v1
->u
.val_vs
->get_nof_vs();}
8089 FATAL_ERROR("Value::evaluate_value()");
8094 u
.val_Int
=new int_val_t(i
);
8096 case OPTYPE_SIZEOF
: {
8097 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
8101 u
.val_Int
=new int_val_t(i
);
8104 case OPTYPE_ISVALUE
: {
8105 if(is_unfoldable()) break;
8106 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
8107 && u
.expr
.ti1
->get_Template()->is_Value();
8109 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
8110 is_singleval
= other_val
->evaluate_isvalue(false);
8111 // is_singleval now contains the compile-time result of isvalue
8116 u
.val_bool
= is_singleval
;
8118 case OPTYPE_ISCHOSEN_V
: {
8119 if (is_unfoldable()) break;
8120 v1
= u
.expr
.v1
->get_value_refd_last();
8121 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
8126 case OPTYPE_VALUEOF
: // ti1
8127 if (!u
.expr
.ti1
->get_DerivedRef() &&
8128 u
.expr
.ti1
->get_Template()->is_Value() &&
8129 !u
.expr
.ti1
->get_Type()) {
8130 // FIXME actually if the template instance has a type
8131 // it might still be foldable.
8132 // the argument is a single specific value
8133 v1
= u
.expr
.ti1
->get_Template()->get_Value();
8134 Type
*governor
= my_governor
;
8135 if (governor
== NULL
) {
8136 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
8137 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
8139 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
8140 if (governor
== NULL
)
8141 FATAL_ERROR("Value::evaluate_value()");
8143 valuetype
= v1
->valuetype
;
8145 set_my_governor(governor
);
8146 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
8147 u
.ref
.refd_last
= this;
8148 v1
->valuetype
= V_ERROR
;
8152 case OPTYPE_UNDEF_RUNNING
:
8154 FATAL_ERROR("Value::evaluate_value()");
8158 bool Value::evaluate_isvalue(bool from_sequence
)
8160 switch (valuetype
) {
8162 // Omit is not a value unless a member of a sequence or set
8163 return from_sequence
;
8166 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8167 case V_BOOL
: /**< boolean */
8168 case V_NAMEDINT
: /**< integer / named number */
8169 case V_NAMEDBITS
: /**< named bits (identifiers) */
8170 case V_INT
: /**< integer */
8171 case V_REAL
: /**< real/float */
8172 case V_ENUM
: /**< enumerated */
8173 case V_BSTR
: /**< bitstring */
8174 case V_HSTR
: /**< hexstring */
8175 case V_OSTR
: /**< octetstring */
8176 case V_CSTR
: /**< charstring */
8177 case V_USTR
: /**< universal charstring */
8178 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
8179 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
8180 case V_OID
: /**< object identifier */
8181 case V_ROID
: /**< relative object identifier */
8182 case V_VERDICT
: /**< all verdicts */
8183 return true; // values of built-in types return true
8185 // Code below was adapted from is_unfoldable(), false returned early.
8187 return u
.choice
.alt_value
->evaluate_isvalue(false);
8192 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8193 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
8201 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8202 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8203 ->evaluate_isvalue(true)) return false;
8208 // alas, get_value_refd_last prevents this function from const
8209 return get_value_refd_last()->evaluate_isvalue(false);
8212 switch (u
.expr
.v_optype
) {
8213 // A constant null component reference is a corner case: it is foldable
8214 // but escapes unmodified from evaluate_value.
8215 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8216 // or is transformed into some other valuetype in evaluate_value.
8217 case OPTYPE_COMP_NULL
:
8220 break; // and fall through to the FATAL_ERROR
8224 FATAL_ERROR("Value::evaluate_isvalue()");
8230 void Value::evaluate_macro(Type::expected_value_t exp_val
)
8233 case MACRO_MODULEID
:
8235 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8236 set_val_str(new string(my_scope
->get_scope_mod()
8237 ->get_modid().get_dispname()));
8240 case MACRO_FILENAME
:
8241 case MACRO_BFILENAME
: {
8242 const char *t_filename
= get_filename();
8244 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8245 set_val_str(new string(t_filename
));
8248 case MACRO_FILEPATH
: {
8249 const char *t_filename
= get_filename();
8251 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8252 char *t_filepath
= canonize_input_file(t_filename
);
8254 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8255 set_val_str(new string(t_filepath
));
8259 case MACRO_LINENUMBER
: {
8260 int t_lineno
= get_first_line();
8262 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8263 set_val_str(new string(Int2string(t_lineno
)));
8266 case MACRO_LINENUMBER_C
: {
8267 int t_lineno
= get_first_line();
8269 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8270 u
.val_Int
= new int_val_t(t_lineno
);
8273 case MACRO_DEFINITIONID
: {
8274 // cut the second part from the fullname separated by dots
8275 const string
& t_fullname
= get_fullname();
8276 size_t first_char
= t_fullname
.find('.') + 1;
8277 if (first_char
>= t_fullname
.size())
8278 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8279 t_fullname
.c_str());
8280 set_val_str(new string(t_fullname
.substr(first_char
,
8281 t_fullname
.find('.', first_char
) - first_char
)));
8285 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8286 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8290 case MACRO_TESTCASEID
: {
8291 if (exp_val
== Type::EXPECTED_CONSTANT
||
8292 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8293 error("A %s value was expected instead of macro `%%testcaseId', "
8294 "which is evaluated at runtime",
8295 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8299 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8300 Ttcn::StatementBlock
*my_sb
=
8301 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8303 error("Usage of macro %%testcaseId is allowed only within the "
8304 "statement blocks of functions, altsteps and testcases");
8307 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8309 error("Macro %%testcaseId cannot be used in the control part. "
8310 "It is allowed only within the statement blocks of functions, "
8311 "altsteps and testcases");
8314 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8315 // folding is possible only within testcases
8316 set_val_str(new string(my_def
->get_id().get_dispname()));
8321 FATAL_ERROR("Value::evaluate_macro()");
8325 set_valuetype(V_ERROR
);
8328 void Value::add_id(Identifier
*p_id
)
8332 if(u
.ids
->has_key(p_id
->get_name())) {
8333 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8334 // The Value does not take ownership for the identifier,
8335 // so it must be deleted (add_is acts as a sink).
8338 else u
.ids
->add(p_id
->get_name(), p_id
);
8341 FATAL_ERROR("Value::add_id()");
8345 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8346 Type::expected_value_t exp_val
)
8348 set_lowerid_to_ref();
8349 switch (valuetype
) {
8351 // there might be a better place for this
8352 chk_invoke(exp_val
);
8355 // use the cache if available
8356 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8358 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8360 // the referred definition is not found
8361 set_valuetype(V_ERROR
);
8363 switch (ass
->get_asstype()) {
8364 case Assignment::A_OBJECT
:
8365 case Assignment::A_OS
: {
8366 // the referred definition is an ASN.1 object or object set
8367 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8368 if (!setting
|| setting
->get_st() == S_ERROR
) {
8369 // remain silent, the error has been already reported
8370 set_valuetype(V_ERROR
);
8372 } else if (setting
->get_st() != S_V
) {
8373 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8374 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8375 set_valuetype(V_ERROR
);
8380 refch
->mark_state();
8381 destroy_refch
= false;
8383 refch
= new ReferenceChain(this,
8384 "While searching referenced value");
8385 destroy_refch
= true;
8387 if (refch
->add(get_fullname())) {
8388 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8389 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8390 // in case of circular recursion the valuetype is already set
8391 // to V_ERROR, so don't set the cache
8392 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8394 // a circular recursion was detected
8395 set_valuetype(V_ERROR
);
8397 if (destroy_refch
) delete refch
;
8398 else refch
->prev_state();
8400 case Assignment::A_CONST
: {
8401 // the referred definition is a constant
8404 refch
->mark_state();
8405 destroy_refch
= false;
8407 refch
= new ReferenceChain(this,
8408 "While searching referenced value");
8409 destroy_refch
= true;
8411 if (refch
->add(get_fullname())) {
8412 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8413 Value
*v_refd
= ass
->get_Value()
8414 ->get_refd_sub_value(subrefs
, 0,
8415 u
.ref
.ref
->getUsedInIsbound(), refch
);
8417 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8418 // in case of circular recursion the valuetype is already set
8419 // to V_ERROR, so don't set the cache
8420 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8421 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8422 u
.ref
.refd_last
= this;
8423 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8424 u
.ref
.refd_last
= this;
8426 // the sub-reference points to a non-existent field
8427 set_valuetype(V_ERROR
);
8430 // a circular recursion was detected
8431 set_valuetype(V_ERROR
);
8433 if (destroy_refch
) delete refch
;
8434 else refch
->prev_state();
8436 case Assignment::A_EXT_CONST
:
8437 case Assignment::A_MODULEPAR
:
8438 case Assignment::A_VAR
:
8439 case Assignment::A_FUNCTION_RVAL
:
8440 case Assignment::A_EXT_FUNCTION_RVAL
:
8441 case Assignment::A_PAR_VAL_IN
:
8442 case Assignment::A_PAR_VAL_OUT
:
8443 case Assignment::A_PAR_VAL_INOUT
:
8444 // the referred definition is not a constant
8445 u
.ref
.refd_last
= this;
8447 case Assignment::A_FUNCTION
:
8448 case Assignment::A_EXT_FUNCTION
:
8449 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8450 "call of %s, which does not have return type",
8451 ass
->get_description().c_str());
8452 set_valuetype(V_ERROR
);
8454 case Assignment::A_FUNCTION_RTEMP
:
8455 case Assignment::A_EXT_FUNCTION_RTEMP
:
8456 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8457 "call of %s, which returns a template",
8458 ass
->get_description().c_str());
8459 set_valuetype(V_ERROR
);
8462 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8463 ass
->get_description().c_str());
8464 set_valuetype(V_ERROR
);
8467 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8471 // try to evaluate the expression
8474 refch
->mark_state();
8475 destroy_refch
=false;
8478 refch
=new ReferenceChain(this, "While evaluating expression");
8481 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8482 else set_valuetype(V_ERROR
);
8483 if(destroy_refch
) delete refch
;
8484 else refch
->prev_state();
8487 evaluate_macro(exp_val
);
8490 // return this for all other value types
8495 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8497 /* Note that the logic here needs to be in sync with evaluate_value,
8498 * and possibly others, i.e. if evaluate_value is called for a Value
8499 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8500 bool Value::is_unfoldable(ReferenceChain
*refch
,
8501 Type::expected_value_t exp_val
)
8503 if (UnfoldabilityCheck::is_running(this)) {
8504 // This function is already running on this value => infinite recursion
8508 UnfoldabilityCheck
checker(this);
8510 if (get_needs_conversion()) return true;
8511 switch (valuetype
) {
8515 case V_UNDEF_LOWERID
:
8519 // these value types are eliminated during semantic analysis
8520 FATAL_ERROR("Value::is_unfoldable()");
8525 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8529 if (!is_indexed()) {
8530 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8531 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8535 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8536 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8543 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8544 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8545 ->is_unfoldable(refch
, exp_val
)) return true;
8551 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8552 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8556 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8557 if(v_last
==this) return true; // there weren't any references to chase
8558 else return v_last
->is_unfoldable(refch
, exp_val
);
8561 // classify the unchecked ischosen() operation, if it was not done so far
8562 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8563 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8564 switch (u
.expr
.v_optype
) {
8565 case OPTYPE_RND
: // -
8566 case OPTYPE_COMP_MTC
:
8567 case OPTYPE_COMP_SYSTEM
:
8568 case OPTYPE_COMP_SELF
:
8569 case OPTYPE_COMP_RUNNING_ANY
:
8570 case OPTYPE_COMP_RUNNING_ALL
:
8571 case OPTYPE_COMP_ALIVE_ANY
:
8572 case OPTYPE_COMP_ALIVE_ALL
:
8573 case OPTYPE_TMR_RUNNING_ANY
:
8574 case OPTYPE_GETVERDICT
:
8575 case OPTYPE_TESTCASENAME
:
8576 case OPTYPE_PROF_RUNNING
:
8577 case OPTYPE_RNDWITHVAL
: // v1
8578 case OPTYPE_MATCH
: // v1 t2
8579 case OPTYPE_UNDEF_RUNNING
: // v1
8580 case OPTYPE_COMP_RUNNING
:
8581 case OPTYPE_COMP_ALIVE
:
8582 case OPTYPE_TMR_READ
:
8583 case OPTYPE_TMR_RUNNING
:
8584 case OPTYPE_ACTIVATE
:
8585 case OPTYPE_ACTIVATE_REFD
:
8586 case OPTYPE_EXECUTE
: // r1 [v2]
8587 case OPTYPE_EXECUTE_REFD
:
8588 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8589 case OPTYPE_ISCHOSEN
:
8590 case OPTYPE_ISCHOSEN_T
:
8591 case OPTYPE_SIZEOF
: // ti1
8594 case OPTYPE_OCT2UNICHAR
:
8595 case OPTYPE_UNICHAR2OCT
:
8596 case OPTYPE_ENCODE_BASE64
:
8597 case OPTYPE_DECODE_BASE64
:
8598 case OPTYPE_ENCVALUE_UNICHAR
:
8599 case OPTYPE_DECVALUE_UNICHAR
:
8600 case OPTYPE_CHECKSTATE_ANY
:
8601 case OPTYPE_CHECKSTATE_ALL
:
8604 case OPTYPE_COMP_NULL
: // -
8606 case OPTYPE_UNARYPLUS
: // v1
8607 case OPTYPE_UNARYMINUS
:
8610 case OPTYPE_BIT2HEX
:
8611 case OPTYPE_BIT2INT
:
8612 case OPTYPE_BIT2OCT
:
8613 case OPTYPE_BIT2STR
:
8614 case OPTYPE_CHAR2INT
:
8615 case OPTYPE_CHAR2OCT
:
8616 case OPTYPE_FLOAT2INT
:
8617 case OPTYPE_FLOAT2STR
:
8618 case OPTYPE_HEX2BIT
:
8619 case OPTYPE_HEX2INT
:
8620 case OPTYPE_HEX2OCT
:
8621 case OPTYPE_HEX2STR
:
8622 case OPTYPE_INT2CHAR
:
8623 case OPTYPE_INT2FLOAT
:
8624 case OPTYPE_INT2STR
:
8625 case OPTYPE_INT2UNICHAR
:
8626 case OPTYPE_OCT2BIT
:
8627 case OPTYPE_OCT2CHAR
:
8628 case OPTYPE_OCT2HEX
:
8629 case OPTYPE_OCT2INT
:
8630 case OPTYPE_OCT2STR
:
8631 case OPTYPE_STR2BIT
:
8632 case OPTYPE_STR2FLOAT
:
8633 case OPTYPE_STR2HEX
:
8634 case OPTYPE_STR2INT
:
8635 case OPTYPE_STR2OCT
:
8636 case OPTYPE_UNICHAR2INT
:
8637 case OPTYPE_UNICHAR2CHAR
:
8638 case OPTYPE_ENUM2INT
:
8639 case OPTYPE_GET_STRINGENCODING
:
8640 case OPTYPE_REMOVE_BOM
:
8641 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8642 case OPTYPE_ISBOUND
: /*{
8643 //TODO once we have the time for it make isbound foldable.
8644 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8645 Template* temp = u.expr.ti1->get_Template();
8646 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8647 Value* specificValue = temp->get_specific_value();
8648 if (specificValue->get_valuetype() == Value::V_REFD) {
8652 return specificValue->is_unfoldable(refch, exp_val);
8653 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8658 case OPTYPE_ISPRESENT
:
8659 // TODO: "if you have motivation"
8661 case OPTYPE_ISVALUE
: // ti1
8663 case OPTYPE_LENGTHOF
: // ti1
8664 return u
.expr
.ti1
->get_DerivedRef() != 0
8665 || u
.expr
.ti1
->get_Template()->get_templatetype()
8666 != Template::SPECIFIC_VALUE
8667 || u
.expr
.ti1
->get_Template()->get_specific_value()
8668 ->is_unfoldable(refch
, exp_val
);
8672 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8674 case OPTYPE_ADD
: // v1 v2
8675 case OPTYPE_SUBTRACT
:
8676 case OPTYPE_MULTIPLY
:
8692 case OPTYPE_INT2BIT
:
8693 case OPTYPE_INT2HEX
:
8694 case OPTYPE_INT2OCT
:
8695 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8696 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8697 case OPTYPE_AND
: // short-circuit evaluation
8698 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8699 || (u
.expr
.v1
->get_val_bool() &&
8700 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8701 case OPTYPE_OR
: // short-circuit evaluation
8702 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8703 || (!u
.expr
.v1
->get_val_bool() &&
8704 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8706 if (!u
.expr
.ti1
->get_specific_value()) return true;
8707 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8708 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8709 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8710 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8712 if (!u
.expr
.ti1
->get_specific_value() ||
8713 !u
.expr
.t2
->get_specific_value()) return true;
8714 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8715 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8716 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8718 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8719 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8720 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8721 case OPTYPE_REPLACE
: {
8722 if (!u
.expr
.ti1
->get_specific_value() ||
8723 !u
.expr
.ti4
->get_specific_value()) return true;
8724 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8725 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8726 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8727 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8728 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8730 case OPTYPE_VALUEOF
: // ti1
8731 /* \todo if you have motivation to implement the eval function
8734 case OPTYPE_ISCHOSEN_V
:
8735 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8736 case OPTYPE_LOG2STR
:
8737 case OPTYPE_ANY2UNISTR
:
8738 case OPTYPE_TTCN2STRING
:
8741 FATAL_ERROR("Value::is_unfoldable()");
8743 break; // should never get here
8746 case MACRO_TESTCASEID
:
8747 // this is known only at runtime
8753 // all literal values are foldable
8758 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8759 size_t start_i
, bool usedInIsbound
,
8760 ReferenceChain
*refch
)
8762 if (!subrefs
) return this;
8764 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8766 v
= v
->get_value_refd_last(refch
);
8767 switch(v
->valuetype
) {
8776 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8777 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8778 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8779 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8784 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8785 bool usedInIsbound
, const Location
& loc
)
8787 if (valuetype
== V_OMIT
) {
8788 loc
.error("Reference to field `%s' of omit value `%s'",
8789 field_id
.get_dispname().c_str(), get_fullname().c_str());
8792 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8793 Type
*t
= my_governor
->get_type_refd_last();
8794 switch (t
->get_typetype()) {
8798 case Type::T_CHOICE_A
:
8799 case Type::T_CHOICE_T
:
8800 case Type::T_OPENTYPE
:
8801 case Type::T_ANYTYPE
:
8802 if (!t
->has_comp_withName(field_id
)) {
8803 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8804 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8806 } else if (valuetype
!= V_CHOICE
) {
8807 // remain silent, the error is already reported
8809 } else if (*u
.choice
.alt_name
== field_id
) {
8811 return u
.choice
.alt_value
;
8813 if (!usedInIsbound
) {
8814 loc
.error("Reference to inactive field `%s' in a value of union type "
8815 "`%s'. The active field is `%s'",
8816 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8817 u
.choice
.alt_name
->get_dispname().c_str());
8823 if (!t
->has_comp_withName(field_id
)) {
8824 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8825 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8827 } else if (valuetype
!= V_SEQ
) {
8828 // remain silent, the error has been already reported
8833 if (!t
->has_comp_withName(field_id
)) {
8834 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8835 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8837 } else if (valuetype
!= V_SET
) {
8838 // remain silent, the error has been already reported
8842 loc
.error("Invalid field reference `%s': type `%s' "
8843 "does not have fields", field_id
.get_dispname().c_str(),
8844 t
->get_typename().c_str());
8847 // the common end for record & set types
8848 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8850 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8851 } else if (!is_asn1()) {
8852 if (!usedInIsbound
) {
8853 loc
.error("Reference to unbound field `%s'",
8854 field_id
.get_dispname().c_str());
8855 // this is an error in TTCN-3, which has been already reported
8859 CompField
*cf
= t
->get_comp_byName(field_id
);
8860 if (cf
->get_is_optional()) {
8861 // creating an explicit omit value
8862 Value
*v
= new Value(V_OMIT
);
8863 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8864 v
->set_my_scope(get_my_scope());
8865 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8867 } else if (cf
->has_default()) {
8868 // returning the component's default value
8869 return cf
->get_defval();
8871 // this is an error in ASN.1, which has been already reported
8877 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8878 ReferenceChain
*refch
)
8880 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8882 bool index_available
= false;
8883 if (!v_index
->is_unfoldable()) {
8884 if (v_index
->valuetype
== V_INT
) {
8885 index
= v_index
->get_val_Int()->get_val();
8886 index_available
= true;
8888 array_index
->error("An integer value was expected as index");
8891 if (valuetype
== V_OMIT
) {
8892 array_index
->error("Accessing an element with index of omit value `%s'",
8893 get_fullname().c_str());
8896 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8897 Type
*t
= my_governor
->get_type_refd_last();
8898 switch (t
->get_typetype()) {
8903 if (index_available
) {
8905 array_index
->error("A non-negative integer value was expected "
8906 "instead of %s for indexing a value of `record "
8907 "of' type `%s'", Int2string(index
).c_str(),
8908 t
->get_typename().c_str());
8911 switch (valuetype
) {
8913 if (!is_indexed()) {
8914 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8915 if (!usedInIsbound
) {
8916 array_index
->error("Index overflow in a value of `record of' "
8917 "type `%s': the index is %s, but the value "
8918 "has only %lu elements",
8919 t
->get_typename().c_str(),
8920 Int2string(index
).c_str(),
8921 (unsigned long)u
.val_vs
->get_nof_vs());
8925 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8926 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8927 temp
->error("Not used symbol is not allowed in this context");
8928 return u
.val_vs
->get_v_byIndex(index
);
8931 // Search the appropriate constant index.
8932 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8933 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8934 ->get_value_refd_last();
8935 if (iv_index
->get_valuetype() != V_INT
) continue;
8936 if (iv_index
->get_val_Int()->get_val() == index
)
8937 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8943 // remain silent, the error has been already reported
8947 // the error has been reported above
8951 if (index_available
) {
8953 array_index
->error("A non-negative integer value was expected "
8954 "instead of %s for indexing a value of `set of' type `%s'",
8955 Int2string(index
).c_str(), t
->get_typename().c_str());
8958 switch (valuetype
) {
8960 if (!is_indexed()) {
8961 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8962 if (!usedInIsbound
) {
8963 array_index
->error("Index overflow in a value of `set of' type "
8964 "`%s': the index is %s, but the value has "
8965 "only %lu elements",
8966 t
->get_typename().c_str(),
8967 Int2string(index
).c_str(),
8968 (unsigned long)u
.val_vs
->get_nof_vs());
8972 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8973 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8974 temp
->error("Not used symbol is not allowed in this context");
8978 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8979 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8980 ->get_value_refd_last();
8981 if (iv_index
->get_valuetype() != V_INT
) continue;
8982 if (iv_index
->get_val_Int()->get_val() == index
)
8983 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8989 // remain silent, the error has been already reported
8993 // the error has been reported above
8997 if (index_available
) {
8998 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8999 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
9000 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
9001 // perform the index transformation
9002 index
-= dim
->get_offset();
9003 if (!is_indexed()) {
9004 // check for index underflow/overflow or too few elements in the
9007 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
9009 else return u
.val_vs
->get_v_byIndex(index
);
9011 if (index
< 0) return 0;
9012 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
9013 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
9014 ->get_value_refd_last();
9015 if (iv_index
->get_valuetype() != V_INT
) continue;
9016 if (iv_index
->get_val_Int()->get_val() == index
)
9017 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
9022 // remain silent, the error has been already reported
9026 // the error has been reported above
9030 case Type::T_BSTR_A
:
9035 case Type::T_UTF8STRING
:
9036 case Type::T_NUMERICSTRING
:
9037 case Type::T_PRINTABLESTRING
:
9038 case Type::T_TELETEXSTRING
:
9039 case Type::T_VIDEOTEXSTRING
:
9040 case Type::T_IA5STRING
:
9041 case Type::T_GRAPHICSTRING
:
9042 case Type::T_VISIBLESTRING
:
9043 case Type::T_GENERALSTRING
:
9044 case Type::T_UNIVERSALSTRING
:
9045 case Type::T_BMPSTRING
:
9046 case Type::T_UTCTIME
:
9047 case Type::T_GENERALIZEDTIME
:
9048 case Type::T_OBJECTDESCRIPTOR
:
9049 if (index_available
) return get_string_element(index
, *array_index
);
9052 array_index
->error("Invalid array element reference: type `%s' cannot "
9053 "be indexed", t
->get_typename().c_str());
9058 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
9061 loc
.error("A non-negative integer value was expected instead of %s "
9062 "for indexing a string element", Int2string(index
).c_str());
9065 size_t string_length
;
9066 switch (valuetype
) {
9071 string_length
= u
.str
.val_str
->size();
9074 string_length
= u
.str
.val_str
->size() / 2;
9077 string_length
= u
.ustr
.val_ustr
->size();
9080 // remain silent, the error has been already reported
9083 if (index
>= static_cast<Int
>(string_length
)) {
9084 loc
.error("Index overflow when accessing a string element: "
9085 "the index is %s, but the string has only %lu elements",
9086 Int2string(index
).c_str(), (unsigned long) string_length
);
9089 switch (valuetype
) {
9094 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
9095 return (*u
.str
.str_elements
)[index
];
9097 Value
*t_val
= new Value(valuetype
,
9098 new string(u
.str
.val_str
->substr(index
, 1)));
9099 add_string_element(index
, t_val
, u
.str
.str_elements
);
9103 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
9104 return (*u
.str
.str_elements
)[index
];
9106 Value
*t_val
= new Value(V_OSTR
,
9107 new string(u
.str
.val_str
->substr(2 * index
, 2)));
9108 add_string_element(index
, t_val
, u
.str
.str_elements
);
9112 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
9113 return (*u
.ustr
.ustr_elements
)[index
];
9115 Value
*t_val
= new Value(V_USTR
,
9116 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
9117 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
9121 FATAL_ERROR("Value::get_string_element()");
9126 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
9127 Type::expected_value_t exp_val
)
9129 set_lowerid_to_ref();
9130 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
9131 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
9133 error("A value or expression of type %s was expected", type_name
);
9134 if (valuetype
== V_REFD
) {
9135 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
9136 t_chk
->chk_this_refd_value(this, 0, exp_val
);
9138 get_value_refd_last(0, exp_val
);
9139 if (error_flag
) set_valuetype(V_ERROR
);
9140 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
9143 int Value::is_parsed_infinity()
9145 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
9147 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
9148 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
9149 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
9154 bool Value::get_val_bool()
9157 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9159 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
9160 return v
->u
.val_bool
;
9163 int_val_t
* Value::get_val_Int()
9166 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9168 switch (v
->valuetype
) {
9171 case V_UNDEF_LOWERID
:
9172 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9173 "`%s'", (*u
.val_id
).get_dispname().c_str());
9175 FATAL_ERROR("Value::get_val_Int()");
9177 return v
->u
.val_Int
;
9180 const Identifier
* Value::get_val_id()
9185 case V_UNDEF_LOWERID
:
9188 FATAL_ERROR("Value::get_val_id()");
9193 const ttcn3float
& Value::get_val_Real()
9196 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9198 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
9199 return v
->u
.val_Real
;
9202 string
Value::get_val_str()
9204 Value
*v
= get_value_refd_last();
9205 switch (v
->valuetype
) {
9210 return *v
->u
.str
.val_str
;
9212 return v
->u
.char_syms
->get_string();
9214 error("Cannot use ISO-10646 string value in string context");
9217 error("Cannot use ISO-2022 string value in string context");
9222 error("Cannot use this value in charstring value context");
9227 ustring
Value::get_val_ustr()
9229 Value
*v
= get_value_refd_last();
9230 switch (v
->valuetype
) {
9232 return ustring(*v
->u
.str
.val_str
);
9234 return *v
->u
.ustr
.val_ustr
;
9236 return v
->u
.char_syms
->get_ustring();
9238 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9243 error("Cannot use this value in ISO-10646 string context");
9248 string
Value::get_val_iso2022str()
9250 Value
*v
= get_value_refd_last();
9251 switch (v
->valuetype
) {
9254 return *v
->u
.str
.val_str
;
9256 return v
->u
.char_syms
->get_iso2022string();
9258 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9263 error("Cannot use this value in ISO-2022 string context");
9268 size_t Value::get_val_strlen()
9270 Value
*v
= get_value_refd_last();
9271 switch (v
->valuetype
) {
9276 return v
->u
.str
.val_str
->size();
9278 return v
->u
.str
.val_str
->size()/2;
9280 return v
->u
.char_syms
->get_len();
9282 return v
->u
.ustr
.val_ustr
->size();
9286 error("Cannot use this value in string value context");
9291 Value::verdict_t
Value::get_val_verdict()
9297 FATAL_ERROR("Value::get_val_verdict()");
9302 size_t Value::get_nof_comps()
9304 switch (valuetype
) {
9308 return u
.oid_comps
->size();
9312 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9313 else return u
.val_vs
->get_nof_vs();
9316 return u
.val_nvs
->get_nof_nvs();
9321 return u
.str
.val_str
->size();
9323 return u
.str
.val_str
->size()/2;
9325 return u
.ustr
.val_ustr
->size();
9327 FATAL_ERROR("Value::get_nof_comps()");
9332 bool Value::is_indexed() const
9334 switch (valuetype
) {
9338 // Applicable only for list-types. Assigning a record/SEQUENCE or
9339 // set/SET with indexed notation is not supported.
9340 return u
.val_vs
->is_indexed();
9342 FATAL_ERROR("Value::is_indexed()");
9348 const Identifier
& Value::get_alt_name()
9350 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9351 return *u
.choice
.alt_name
;
9354 Value
*Value::get_alt_value()
9356 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9357 return u
.choice
.alt_value
;
9360 void Value::set_alt_name_to_lowercase()
9362 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9363 string new_name
= u
.choice
.alt_name
->get_name();
9364 if (isupper(new_name
[0])) {
9365 new_name
[0] = tolower(new_name
[0]);
9366 if (new_name
[new_name
.size() - 1] == '_') {
9367 // an underscore is inserted at the end of the alternative name if it's
9368 // a basic type's name (since it would conflict with the class generated
9370 // remove the underscore, it won't conflict with anything if its name
9371 // starts with a lowercase letter
9372 new_name
.replace(new_name
.size() - 1, 1, "");
9374 delete u
.choice
.alt_name
;
9375 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9379 bool Value::has_oid_error()
9382 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9384 switch (valuetype
) {
9387 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9388 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9395 bool Value::get_oid_comps(vector
<string
>& comps
)
9397 bool ret_val
= true;
9399 switch (valuetype
) {
9401 v
= get_value_refd_last();
9405 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9406 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9407 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9408 // not all components can be calculated in compile-time
9414 FATAL_ERROR("Value::get_oid_comps()");
9419 void Value::add_se_comp(NamedValue
* nv
) {
9420 switch (valuetype
) {
9424 u
.val_nvs
= new NamedValues();
9425 u
.val_nvs
->add_nv(nv
);
9428 FATAL_ERROR("Value::add_se_comp()");
9432 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9437 return u
.val_nvs
->get_nv_byIndex(n
);
9439 FATAL_ERROR("Value::get_se_comp_byIndex()");
9444 Value
*Value::get_comp_byIndex(size_t n
)
9446 switch (valuetype
) {
9450 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9451 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9453 FATAL_ERROR("Value::get_comp_byIndex()");
9458 Value
*Value::get_index_byIndex(size_t n
)
9460 switch (valuetype
) {
9464 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9465 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9467 FATAL_ERROR("Value::get_index_byIndex()");
9472 bool Value::has_comp_withName(const Identifier
& p_name
)
9477 return u
.val_nvs
->has_nv_withName(p_name
);
9479 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9481 FATAL_ERROR("Value::get_has_comp_withName()");
9486 bool Value::field_is_chosen(const Identifier
& p_name
)
9488 Value
*v
=get_value_refd_last();
9489 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9490 return *v
->u
.choice
.alt_name
==p_name
;
9493 bool Value::field_is_present(const Identifier
& p_name
)
9495 Value
*v
=get_value_refd_last();
9496 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9497 FATAL_ERROR("Value::field_is_present()");
9498 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9499 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9500 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9503 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9508 return u
.val_nvs
->get_nv_byName(p_name
);
9510 FATAL_ERROR("Value::get_se_comp_byName()");
9515 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9520 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9522 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9523 return u
.choice
.alt_value
;
9527 FATAL_ERROR("Value::get_se_comp_byName()");
9532 void Value::chk_dupl_id()
9537 u
.val_nvs
->chk_dupl_id();
9540 FATAL_ERROR("Value::chk_dupl_id()");
9544 size_t Value::get_nof_ids() const
9548 return u
.ids
->size();
9551 FATAL_ERROR("Value::get_nof_ids()");
9556 Identifier
* Value::get_id_byIndex(size_t p_i
)
9560 return u
.ids
->get_nth_elem(p_i
);
9563 FATAL_ERROR("Value::get_id_byIndex()");
9568 bool Value::has_id(const Identifier
& p_id
)
9572 return u
.ids
->has_key(p_id
.get_name());
9575 FATAL_ERROR("Value::has_id()");
9580 Reference
*Value::get_reference() const
9582 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9586 Reference
*Value::get_refered() const
9588 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9592 Common::Assignment
*Value::get_refd_fat() const
9600 FATAL_ERROR("Value::get_refd_fat()");
9604 Ttcn::Reference
* Value::steal_ttcn_ref()
9606 Ttcn::Reference
*ret_val
=
9607 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9608 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9612 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9614 Ttcn::Ref_base
*t_ref
;
9615 if(valuetype
==V_REFD
) {
9616 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9617 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9620 else if(valuetype
==V_UNDEF_LOWERID
) {
9621 t_ref
=new Ttcn::Reference(u
.val_id
);
9622 t_ref
->set_location(*this);
9623 t_ref
->set_fullname(get_fullname());
9624 t_ref
->set_my_scope(get_my_scope());
9628 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9631 set_valuetype(V_ERROR
);
9635 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9636 Ttcn::ActualParList
*& p_ap
)
9638 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9641 p_ti
= u
.invoke
.t_list
;
9642 u
.invoke
.t_list
= 0;
9643 p_ap
= u
.invoke
.ap_list
;
9644 u
.invoke
.ap_list
= 0;
9645 set_valuetype(V_ERROR
);
9648 Common::Assignment
* Value::get_refd_assignment()
9657 FATAL_ERROR("Value::get_refd_assignment()");
9667 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9672 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9681 void Value::chk_OID(ReferenceChain
& refch
)
9683 if (checked
) return;
9684 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9685 FATAL_ERROR("Value::chk_OID()");
9686 if (!refch
.add(get_fullname())) {
9690 OID_comp::oidstate_t state
= OID_comp::START
;
9691 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9693 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9696 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9697 error("An OBJECT IDENTIFIER value must have at least "
9698 "two components"); // X.680 (07/2002) 31.10
9701 void Value::chk_ROID(ReferenceChain
& refch
)
9703 if (checked
) return;
9704 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9705 FATAL_ERROR("Value::chk_ROID()");
9706 if (!refch
.add(get_fullname())) {
9710 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9712 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9717 void Value::chk_recursions(ReferenceChain
& refch
)
9719 if (recurs_checked
) return;
9720 Value
*v
= get_value_refd_last();
9721 if (refch
.add(v
->get_fullname())) {
9722 switch (v
->valuetype
) {
9724 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9729 if (!v
->is_indexed()) {
9730 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9732 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9736 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9738 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9739 ->chk_recursions(refch
);
9746 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9748 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9753 chk_recursions_expr(refch
);
9758 if (v
->err_descr
) { // FIXME: make this work
9759 v
->err_descr
->chk_recursions(refch
);
9762 recurs_checked
= true;
9765 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9767 // first classify the unchecked ischosen() operation
9768 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9769 switch (u
.expr
.v_optype
) {
9770 case OPTYPE_UNARYPLUS
: // v1
9771 case OPTYPE_UNARYMINUS
:
9774 case OPTYPE_BIT2HEX
:
9775 case OPTYPE_BIT2INT
:
9776 case OPTYPE_BIT2OCT
:
9777 case OPTYPE_BIT2STR
:
9778 case OPTYPE_CHAR2INT
:
9779 case OPTYPE_CHAR2OCT
:
9780 case OPTYPE_FLOAT2INT
:
9781 case OPTYPE_FLOAT2STR
:
9782 case OPTYPE_HEX2BIT
:
9783 case OPTYPE_HEX2INT
:
9784 case OPTYPE_HEX2OCT
:
9785 case OPTYPE_HEX2STR
:
9786 case OPTYPE_INT2CHAR
:
9787 case OPTYPE_INT2FLOAT
:
9788 case OPTYPE_INT2STR
:
9789 case OPTYPE_INT2UNICHAR
:
9790 case OPTYPE_OCT2BIT
:
9791 case OPTYPE_OCT2CHAR
:
9792 case OPTYPE_OCT2HEX
:
9793 case OPTYPE_OCT2INT
:
9794 case OPTYPE_OCT2STR
:
9795 case OPTYPE_STR2BIT
:
9796 case OPTYPE_STR2FLOAT
:
9797 case OPTYPE_STR2HEX
:
9798 case OPTYPE_STR2INT
:
9799 case OPTYPE_STR2OCT
:
9800 case OPTYPE_UNICHAR2INT
:
9801 case OPTYPE_ENUM2INT
:
9802 case OPTYPE_UNICHAR2CHAR
:
9803 case OPTYPE_RNDWITHVAL
:
9804 case OPTYPE_ISCHOSEN_V
:
9805 case OPTYPE_GET_STRINGENCODING
:
9806 case OPTYPE_REMOVE_BOM
:
9807 case OPTYPE_DECODE_BASE64
:
9809 u
.expr
.v1
->chk_recursions(refch
);
9812 case OPTYPE_ISCHOSEN_T
:
9814 u
.expr
.t1
->chk_recursions(refch
);
9817 case OPTYPE_HOSTID
: // [v1]
9820 u
.expr
.v1
->chk_recursions(refch
);
9824 case OPTYPE_ADD
: // v1 v2
9825 case OPTYPE_SUBTRACT
:
9826 case OPTYPE_MULTIPLY
:
9847 case OPTYPE_INT2BIT
:
9848 case OPTYPE_INT2HEX
:
9849 case OPTYPE_INT2OCT
:
9851 u
.expr
.v1
->chk_recursions(refch
);
9854 u
.expr
.v2
->chk_recursions(refch
);
9857 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9858 case OPTYPE_OCT2UNICHAR
:
9859 case OPTYPE_ENCODE_BASE64
:
9861 u
.expr
.v1
->chk_recursions(refch
);
9865 u
.expr
.v2
->chk_recursions(refch
);
9870 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9871 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9875 u
.expr
.ti1
->chk_recursions(refch
);
9878 u
.expr
.v2
->chk_recursions(refch
);
9881 u
.expr
.v3
->chk_recursions(refch
);
9886 u
.expr
.ti1
->chk_recursions(refch
);
9889 u
.expr
.t2
->chk_recursions(refch
);
9892 u
.expr
.v3
->chk_recursions(refch
);
9895 case OPTYPE_DECOMP
: // v1 v2 v3
9897 u
.expr
.v1
->chk_recursions(refch
);
9900 u
.expr
.v2
->chk_recursions(refch
);
9903 u
.expr
.v3
->chk_recursions(refch
);
9906 case OPTYPE_REPLACE
:
9908 u
.expr
.ti1
->chk_recursions(refch
);
9911 u
.expr
.v2
->chk_recursions(refch
);
9914 u
.expr
.v3
->chk_recursions(refch
);
9917 u
.expr
.ti4
->chk_recursions(refch
);
9920 case OPTYPE_LENGTHOF
: // ti1
9921 case OPTYPE_SIZEOF
: // ti1
9922 case OPTYPE_VALUEOF
: // ti1
9924 case OPTYPE_ISPRESENT
:
9925 case OPTYPE_TTCN2STRING
:
9927 u
.expr
.ti1
->chk_recursions(refch
);
9930 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
9932 u
.expr
.ti1
->chk_recursions(refch
);
9936 u
.expr
.v2
->chk_recursions(refch
);
9940 case OPTYPE_DECVALUE_UNICHAR
: // r1 r2 [v3]
9941 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9942 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9945 u
.expr
.v3
->chk_recursions(refch
);
9949 case OPTYPE_MATCH
: // v1 t2
9951 u
.expr
.v1
->chk_recursions(refch
);
9954 u
.expr
.t2
->chk_recursions(refch
);
9957 case OPTYPE_LOG2STR
:
9958 case OPTYPE_ANY2UNISTR
:
9959 u
.expr
.logargs
->chk_recursions(refch
);
9966 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9967 ReferenceChain
& refch
) {
9968 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9969 Assignment
*ass
= ref
->get_refd_assignment();
9971 set_valuetype(V_ERROR
);
9974 switch (ass
->get_asstype()) {
9975 case Assignment::A_CONST
:
9976 case Assignment::A_EXT_CONST
:
9977 case Assignment::A_MODULEPAR
:
9978 case Assignment::A_VAR
:
9979 case Assignment::A_PAR_VAL_IN
:
9980 case Assignment::A_PAR_VAL_OUT
:
9981 case Assignment::A_PAR_VAL_INOUT
: {
9982 Value
* v
= new Value(V_REFD
, ref
);
9983 v
->set_location(*ref
);
9984 v
->set_my_scope(get_my_scope());
9985 v
->set_fullname(get_fullname()+".<operand>");
9987 v
->chk_recursions(refch
);
9991 case Assignment::A_MODULEPAR_TEMP
:
9992 case Assignment::A_TEMPLATE
:
9993 case Assignment::A_VAR_TEMPLATE
:
9994 case Assignment::A_PAR_TEMPL_IN
:
9995 case Assignment::A_PAR_TEMPL_OUT
:
9996 case Assignment::A_PAR_TEMPL_INOUT
: {
9997 Template
* t
= new Template(ref
->clone());
9998 t
->set_location(*ref
);
9999 t
->set_my_scope(get_my_scope());
10000 t
->set_fullname(get_fullname()+".<operand>");
10001 refch
.mark_state();
10002 t
->chk_recursions(refch
);
10003 refch
.prev_state();
10007 // remain silent, the error has been already reported
10008 set_valuetype(V_ERROR
);
10013 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
10015 bool self_ref
= false;
10016 switch (t
->get_templatetype()) {
10017 case Ttcn::Template::SPECIFIC_VALUE
: {
10018 Value
*v
= t
->get_specific_value();
10019 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
10020 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
10021 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
10023 case Ttcn::Template::TEMPLATE_REFD
: {
10024 Ttcn::Ref_base
*refb
= t
->get_reference();
10025 Common::Assignment
*ass
= refb
->get_refd_assignment();
10026 self_ref
|= (ass
== lhs
);
10028 case Ttcn::Template::ALL_FROM
:
10029 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
10030 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
10032 case Ttcn::Template::TEMPLATE_LIST
:
10033 case Ttcn::Template::SUPERSET_MATCH
:
10034 case Ttcn::Template::SUBSET_MATCH
:
10035 case Ttcn::Template::PERMUTATION_MATCH
:
10036 case Ttcn::Template::COMPLEMENTED_LIST
:
10037 case Ttcn::Template::VALUE_LIST
: {
10038 size_t num
= t
->get_nof_comps();
10039 for (size_t i
= 0; i
< num
; ++i
) {
10040 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
10043 // not yet clear whether we should use this or the above for TEMPLATE_LIST
10044 // case Ttcn::Template::TEMPLATE_LIST: {
10045 // size_t num = t->get_nof_listitems();
10046 // for (size_t i=0; i < num; ++i) {
10047 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
10050 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
10051 size_t nnt
= t
->get_nof_comps();
10052 for (size_t i
=0; i
< nnt
; ++i
) {
10053 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
10054 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
10057 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
10058 size_t nnt
= t
->get_nof_comps();
10059 for (size_t i
=0; i
< nnt
; ++i
) {
10060 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
10061 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
10064 case Ttcn::Template::VALUE_RANGE
: {
10065 Ttcn::ValueRange
*vr
= t
->get_value_range();
10066 Common::Value
*v
= vr
->get_min_v();
10067 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
10068 v
= vr
->get_max_v();
10069 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
10071 case Ttcn::Template::CSTR_PATTERN
:
10072 case Ttcn::Template::USTR_PATTERN
: {
10073 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
10074 self_ref
|= ps
->chk_self_ref(lhs
);
10076 case Ttcn::Template::BSTR_PATTERN
:
10077 case Ttcn::Template::HSTR_PATTERN
:
10078 case Ttcn::Template::OSTR_PATTERN
: {
10079 // FIXME: cannot access u.pattern
10081 case Ttcn::Template::ANY_VALUE
:
10082 case Ttcn::Template::ANY_OR_OMIT
:
10083 case Ttcn::Template::OMIT_VALUE
:
10084 case Ttcn::Template::TEMPLATE_NOTUSED
:
10085 break; // self-ref can't happen
10086 case Ttcn::Template::TEMPLATE_INVOKE
:
10087 break; // assume self-ref can't happen
10088 case Ttcn::Template::TEMPLATE_ERROR
:
10089 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
10092 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
10093 // break; // and hope for the best
10098 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
10100 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
10101 namedbool is_str_elem
= NOT_STR_ELEM
;
10102 if (v
->valuetype
== V_REFD
) {
10103 Reference
*ref
= v
->get_reference();
10104 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
10105 if (subrefs
&& subrefs
->refers_to_string_element()) {
10106 is_str_elem
= IS_STR_ELEM
;
10109 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
10110 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
10114 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
10116 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
10117 if (!lhs
) FATAL_ERROR("no lhs!");
10118 bool self_ref
= false;
10119 switch (u
.expr
.v_optype
) {
10120 case OPTYPE_RND
: // -
10121 case OPTYPE_TESTCASENAME
: // -
10122 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
10123 case OPTYPE_COMP_MTC
: // -
10124 case OPTYPE_COMP_SYSTEM
: // -
10125 case OPTYPE_COMP_SELF
: // -
10126 case OPTYPE_COMP_RUNNING_ANY
: // -
10127 case OPTYPE_COMP_RUNNING_ALL
: // -
10128 case OPTYPE_COMP_ALIVE_ANY
: // -
10129 case OPTYPE_COMP_ALIVE_ALL
: // -
10130 case OPTYPE_TMR_RUNNING_ANY
: // -
10131 case OPTYPE_GETVERDICT
: // -
10132 case OPTYPE_PROF_RUNNING
: // -
10133 case OPTYPE_CHECKSTATE_ANY
:
10134 case OPTYPE_CHECKSTATE_ALL
:
10135 break; // nothing to do
10137 case OPTYPE_MATCH
: // v1 t2
10138 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10140 case OPTYPE_UNARYPLUS
: // v1
10141 case OPTYPE_UNARYMINUS
: // v1
10142 case OPTYPE_NOT
: // v1
10143 case OPTYPE_NOT4B
: // v1
10144 case OPTYPE_BIT2HEX
: // v1
10145 case OPTYPE_BIT2INT
: // v1
10146 case OPTYPE_BIT2OCT
: // v1
10147 case OPTYPE_BIT2STR
: // v1
10148 case OPTYPE_CHAR2INT
: // v1
10149 case OPTYPE_CHAR2OCT
: // v1
10150 case OPTYPE_FLOAT2INT
: // v1
10151 case OPTYPE_FLOAT2STR
: // v1
10152 case OPTYPE_HEX2BIT
: // v1
10153 case OPTYPE_HEX2INT
: // v1
10154 case OPTYPE_HEX2OCT
: // v1
10155 case OPTYPE_HEX2STR
: // v1
10156 case OPTYPE_INT2CHAR
: // v1
10157 case OPTYPE_INT2FLOAT
: // v1
10158 case OPTYPE_INT2STR
: // v1
10159 case OPTYPE_INT2UNICHAR
: // v1
10160 case OPTYPE_OCT2BIT
: // v1
10161 case OPTYPE_OCT2CHAR
: // v1
10162 case OPTYPE_OCT2HEX
: // v1
10163 case OPTYPE_OCT2INT
: // v1
10164 case OPTYPE_OCT2STR
: // v1
10165 case OPTYPE_STR2BIT
: // v1
10166 case OPTYPE_STR2FLOAT
: // v1
10167 case OPTYPE_STR2HEX
: // v1
10168 case OPTYPE_STR2INT
: // v1
10169 case OPTYPE_STR2OCT
: // v1
10170 case OPTYPE_UNICHAR2INT
: // v1
10171 case OPTYPE_UNICHAR2CHAR
: // v1
10172 case OPTYPE_ENUM2INT
: // v1
10173 case OPTYPE_RNDWITHVAL
: // v1
10174 case OPTYPE_COMP_RUNNING
: // v1
10175 case OPTYPE_COMP_ALIVE
: // v1
10176 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
10177 case OPTYPE_GET_STRINGENCODING
:
10178 case OPTYPE_DECODE_BASE64
:
10179 case OPTYPE_REMOVE_BOM
:
10180 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10182 case OPTYPE_HOSTID
: // [v1]
10183 if (u
.expr
.v1
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10185 case OPTYPE_ADD
: // v1 v2
10186 case OPTYPE_SUBTRACT
: // v1 v2
10187 case OPTYPE_MULTIPLY
: // v1 v2
10188 case OPTYPE_DIVIDE
: // v1 v2
10189 case OPTYPE_MOD
: // v1 v2
10190 case OPTYPE_REM
: // v1 v2
10191 case OPTYPE_CONCAT
: // v1 v2
10192 case OPTYPE_EQ
: // v1 v2
10193 case OPTYPE_LT
: // v1 v2
10194 case OPTYPE_GT
: // v1 v2
10195 case OPTYPE_NE
: // v1 v2
10196 case OPTYPE_GE
: // v1 v2
10197 case OPTYPE_LE
: // v1 v2
10198 case OPTYPE_AND
: // v1 v2
10199 case OPTYPE_OR
: // v1 v2
10200 case OPTYPE_XOR
: // v1 v2
10201 case OPTYPE_AND4B
: // v1 v2
10202 case OPTYPE_OR4B
: // v1 v2
10203 case OPTYPE_XOR4B
: // v1 v2
10204 case OPTYPE_SHL
: // v1 v2
10205 case OPTYPE_SHR
: // v1 v2
10206 case OPTYPE_ROTL
: // v1 v2
10207 case OPTYPE_ROTR
: // v1 v2
10208 case OPTYPE_INT2BIT
: // v1 v2
10209 case OPTYPE_INT2HEX
: // v1 v2
10210 case OPTYPE_INT2OCT
: // v1 v2
10211 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10212 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10214 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
10215 case OPTYPE_OCT2UNICHAR
:
10216 case OPTYPE_ENCODE_BASE64
:
10217 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10218 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10220 case OPTYPE_DECOMP
: // v1 v2 v3
10221 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10222 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10223 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10226 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
10227 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
10229 case OPTYPE_SUBSTR
: // ti1 v2 v3
10230 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10231 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
10232 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
10235 case OPTYPE_REGEXP
: // ti1 t2 v3
10236 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10237 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
10239 case OPTYPE_LENGTHOF
: // ti1
10240 case OPTYPE_SIZEOF
: // ti1
10241 case OPTYPE_VALUEOF
: // ti1
10242 case OPTYPE_ENCODE
: // ti1
10243 case OPTYPE_TTCN2STRING
:
10244 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10246 case OPTYPE_ENCVALUE_UNICHAR
: // ti1 [v2]
10247 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
10248 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10250 case OPTYPE_DECVALUE_UNICHAR
: { // r1 r2 [v3]
10251 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10252 self_ref
|= (ass
== lhs
);
10253 if (u
.expr
.v3
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10256 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
10257 // component.create -- assume no self-ref
10258 case OPTYPE_ACTIVATE
: // r1
10259 // defaultref := activate(altstep) -- assume no self-ref
10260 case OPTYPE_TMR_RUNNING
: // r1
10261 // boolvar := a_timer.running -- assume no self-ref
10265 case OPTYPE_ANY2UNISTR
:
10266 case OPTYPE_LOG2STR
: {// logargs
10267 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
10268 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
10269 switch (la
->get_type()) {
10270 case Ttcn::LogArgument::L_UNDEF
:
10271 case Ttcn::LogArgument::L_ERROR
:
10272 FATAL_ERROR("%s argument type",
10273 u
.expr
.v_optype
== OPTYPE_ANY2UNISTR
? "any2unistr" : "log2str");
10274 break; // not reached
10276 case Ttcn::LogArgument::L_MACRO
:
10277 case Ttcn::LogArgument::L_STR
:
10278 break; // self reference not possible
10280 case Ttcn::LogArgument::L_VAL
:
10281 case Ttcn::LogArgument::L_MATCH
:
10282 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
10285 case Ttcn::LogArgument::L_REF
: {
10286 Ttcn::Ref_base
*ref
= la
->get_ref();
10287 Common::Assignment
*ass
= ref
->get_refd_assignment();
10288 self_ref
|= (ass
== lhs
);
10291 case Ttcn::LogArgument::L_TI
: {
10292 Ttcn::TemplateInstance
*ti
= la
->get_ti();
10293 Ttcn::Template
*t
= ti
->get_Template();
10294 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10297 // no default please
10298 } // switch la->logargtype
10302 case OPTYPE_DECODE
: { // r1 r2
10303 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10304 self_ref
|= (ass
== lhs
);
10306 case OPTYPE_EXECUTE
: // r1 [v2]
10308 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10312 case OPTYPE_UNDEF_RUNNING
: // r1
10313 case OPTYPE_TMR_READ
: { // r1
10314 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
10315 self_ref
|= (ass
== lhs
);
10318 case OPTYPE_ISCHOSEN_T
: // t1 i2
10319 case OPTYPE_ISBOUND
: // ti1
10320 case OPTYPE_ISVALUE
: // ti1
10321 case OPTYPE_ISPRESENT
: { // ti1
10323 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10324 else t
= u
.expr
.ti1
->get_Template();
10325 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10328 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10330 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10333 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10334 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10338 case NUMBER_OF_OPTYPES
: // can never happen
10339 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10340 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10342 } // switch u.expr.v_optype
10347 string
Value::create_stringRepr()
10349 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10350 switch (valuetype
) {
10352 return string("<erroneous>");
10354 return string("NULL");
10356 if (!parse_only
&& is_asn1()) {
10357 if (u
.val_bool
) return string("TRUE");
10358 else return string("FALSE");
10361 if (u
.val_bool
) return string("true");
10362 else return string("false");
10365 return u
.val_Int
->t_str();
10367 return Real2string(u
.val_Real
);
10370 case V_UNDEF_LOWERID
:
10371 return u
.val_id
->get_name();
10372 case V_NAMEDBITS
: {
10373 string
ret_val("{ ");
10374 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10375 if (i
>0) ret_val
+= ' ';
10376 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10381 string
ret_val('\'');
10382 ret_val
+= *u
.str
.val_str
;
10386 string
ret_val('\'');
10387 ret_val
+= *u
.str
.val_str
;
10391 string
ret_val('\'');
10392 ret_val
+= *u
.str
.val_str
;
10397 return u
.str
.val_str
->get_stringRepr();
10399 return u
.ustr
.val_ustr
->get_stringRepr();
10401 /** \todo stringrepr of V_CHARSYMS */
10402 return string("<sorry, string representation of charsyms "
10403 "not implemented>");
10407 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10409 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10410 if (i
>0) ret_val
+= ' ';
10411 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10416 if (!parse_only
&& is_asn1()) {
10417 string
ret_val(u
.choice
.alt_name
->get_dispname());
10419 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10423 string
ret_val("{ ");
10424 ret_val
+= u
.choice
.alt_name
->get_dispname();
10426 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10433 string
ret_val("{ ");
10434 if (!is_indexed()) {
10435 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10436 if (i
> 0) ret_val
+= ", ";
10437 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10440 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10441 if (i
> 0) ret_val
+= ", ";
10442 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10449 string
ret_val("{ ");
10450 bool asn1_flag
= !parse_only
&& is_asn1();
10451 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10452 if (i
> 0) ret_val
+= ", ";
10453 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10454 ret_val
+= nv
->get_name().get_dispname();
10455 if (asn1_flag
) ret_val
+= ' ';
10456 else ret_val
+= " := ";
10457 ret_val
+= nv
->get_value()->get_stringRepr();
10462 // do not evaluate the reference if it is not done so far
10463 // (e.g. in parse-only mode)
10464 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10465 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10466 else return t_val
->get_stringRepr(); }
10468 return string("omit");
10470 switch (u
.verdict
) {
10472 return string("none");
10474 return string("pass");
10475 case Verdict_INCONC
:
10476 return string("inconc");
10478 return string("fail");
10479 case Verdict_ERROR
:
10480 return string("error");
10482 return string("<unknown verdict value>");
10484 case V_DEFAULT_NULL
:
10486 return string("null");
10488 switch (u
.expr
.v_optype
) {
10490 return string("rnd()");
10491 case OPTYPE_TESTCASENAME
:
10492 return string("testcasename()");
10493 case OPTYPE_UNARYPLUS
:
10494 return create_stringRepr_unary("+");
10495 case OPTYPE_UNARYMINUS
:
10496 return create_stringRepr_unary("-");
10498 return create_stringRepr_unary("not");
10500 return create_stringRepr_unary("not4b");
10501 case OPTYPE_BIT2HEX
:
10502 return create_stringRepr_predef1("bit2hex");
10503 case OPTYPE_BIT2INT
:
10504 return create_stringRepr_predef1("bit2int");
10505 case OPTYPE_BIT2OCT
:
10506 return create_stringRepr_predef1("bit2oct");
10507 case OPTYPE_BIT2STR
:
10508 return create_stringRepr_predef1("bit2str");
10509 case OPTYPE_CHAR2INT
:
10510 return create_stringRepr_predef1("char2int");
10511 case OPTYPE_CHAR2OCT
:
10512 return create_stringRepr_predef1("char2oct");
10513 case OPTYPE_FLOAT2INT
:
10514 return create_stringRepr_predef1("float2int");
10515 case OPTYPE_FLOAT2STR
:
10516 return create_stringRepr_predef1("float2str");
10517 case OPTYPE_HEX2BIT
:
10518 return create_stringRepr_predef1("hex2bit");
10519 case OPTYPE_HEX2INT
:
10520 return create_stringRepr_predef1("hex2int");
10521 case OPTYPE_HEX2OCT
:
10522 return create_stringRepr_predef1("hex2oct");
10523 case OPTYPE_HEX2STR
:
10524 return create_stringRepr_predef1("hex2str");
10525 case OPTYPE_INT2CHAR
:
10526 return create_stringRepr_predef1("int2char");
10527 case OPTYPE_INT2FLOAT
:
10528 return create_stringRepr_predef1("int2float");
10529 case OPTYPE_INT2STR
:
10530 return create_stringRepr_predef1("int2str");
10531 case OPTYPE_INT2UNICHAR
:
10532 return create_stringRepr_predef1("int2unichar");
10533 case OPTYPE_OCT2BIT
:
10534 return create_stringRepr_predef1("oct2bit");
10535 case OPTYPE_OCT2CHAR
:
10536 return create_stringRepr_predef1("oct2char");
10537 case OPTYPE_OCT2HEX
:
10538 return create_stringRepr_predef1("oct2hex");
10539 case OPTYPE_OCT2INT
:
10540 return create_stringRepr_predef1("oct2int");
10541 case OPTYPE_OCT2STR
:
10542 return create_stringRepr_predef1("oct2str");
10543 case OPTYPE_GET_STRINGENCODING
:
10544 return create_stringRepr_predef1("get_stringencoding");
10545 case OPTYPE_REMOVE_BOM
:
10546 return create_stringRepr_predef1("remove_bom");
10547 case OPTYPE_ENCODE_BASE64
: {
10548 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10549 else return create_stringRepr_predef1("encode_base64");
10551 case OPTYPE_DECODE_BASE64
:
10552 return create_stringRepr_predef1("decode_base64");
10553 case OPTYPE_OCT2UNICHAR
:{
10554 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10555 else return create_stringRepr_predef1("oct2unichar");
10557 case OPTYPE_UNICHAR2OCT
: {
10558 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10559 else return create_stringRepr_predef1("unichar2oct");
10561 case OPTYPE_ENCVALUE_UNICHAR
: {
10562 if (u
.expr
.v2
) return create_stringRepr_predef2("encvalue_unichar");
10563 else return create_stringRepr_predef1("encvalue_unichar");
10565 case OPTYPE_HOSTID
: {
10566 if (u
.expr
.v1
) return create_stringRepr_predef1("hostid");
10567 else return string("hostid()");
10569 case OPTYPE_DECVALUE_UNICHAR
: {
10571 string
ret_val("decvalue_unichar");
10573 ret_val
+= u
.expr
.v1
->get_stringRepr();
10575 ret_val
+= u
.expr
.v2
->get_stringRepr();
10577 ret_val
+= u
.expr
.v3
->get_stringRepr();
10581 else return create_stringRepr_predef2("decvalue_unichar");
10583 case OPTYPE_STR2BIT
:
10584 return create_stringRepr_predef1("str2bit");
10585 case OPTYPE_STR2FLOAT
:
10586 return create_stringRepr_predef1("str2float");
10587 case OPTYPE_STR2HEX
:
10588 return create_stringRepr_predef1("str2hex");
10589 case OPTYPE_STR2INT
:
10590 return create_stringRepr_predef1("str2int");
10591 case OPTYPE_STR2OCT
:
10592 return create_stringRepr_predef1("str2oct");
10593 case OPTYPE_UNICHAR2INT
:
10594 return create_stringRepr_predef1("unichar2int");
10595 case OPTYPE_UNICHAR2CHAR
:
10596 return create_stringRepr_predef1("unichar2char");
10597 case OPTYPE_ENUM2INT
:
10598 return create_stringRepr_predef1("enum2int");
10599 case OPTYPE_ENCODE
:
10600 return create_stringRepr_predef1("encvalue");
10601 case OPTYPE_DECODE
:
10602 return create_stringRepr_predef2("decvalue");
10603 case OPTYPE_RNDWITHVAL
:
10604 return create_stringRepr_predef1("rnd");
10606 return create_stringRepr_infix("+");
10607 case OPTYPE_SUBTRACT
:
10608 return create_stringRepr_infix("-");
10609 case OPTYPE_MULTIPLY
:
10610 return create_stringRepr_infix("*");
10611 case OPTYPE_DIVIDE
:
10612 return create_stringRepr_infix("/");
10614 return create_stringRepr_infix("mod");
10616 return create_stringRepr_infix("rem");
10617 case OPTYPE_CONCAT
:
10618 return create_stringRepr_infix("&");
10620 return create_stringRepr_infix("==");
10622 return create_stringRepr_infix("<");
10624 return create_stringRepr_infix(">");
10626 return create_stringRepr_infix("!=");
10628 return create_stringRepr_infix(">=");
10630 return create_stringRepr_infix("<=");
10632 return create_stringRepr_infix("and");
10634 return create_stringRepr_infix("or");
10636 return create_stringRepr_infix("xor");
10638 return create_stringRepr_infix("and4b");
10640 return create_stringRepr_infix("or4b");
10642 return create_stringRepr_infix("xor4b");
10644 return create_stringRepr_infix("<<");
10646 return create_stringRepr_infix(">>");
10648 return create_stringRepr_infix("<@");
10650 return create_stringRepr_infix("@>");
10651 case OPTYPE_INT2BIT
:
10652 return create_stringRepr_predef2("int2bit");
10653 case OPTYPE_INT2HEX
:
10654 return create_stringRepr_predef2("int2hex");
10655 case OPTYPE_INT2OCT
:
10656 return create_stringRepr_predef2("int2oct");
10657 case OPTYPE_SUBSTR
: {
10658 string
ret_val("substr(");
10659 u
.expr
.ti1
->append_stringRepr(ret_val
);
10661 ret_val
+= u
.expr
.v2
->get_stringRepr();
10663 ret_val
+= u
.expr
.v3
->get_stringRepr();
10667 case OPTYPE_REGEXP
: {
10668 string
ret_val("regexp(");
10669 u
.expr
.ti1
->append_stringRepr(ret_val
);
10671 u
.expr
.t2
->append_stringRepr(ret_val
);
10673 ret_val
+= u
.expr
.v3
->get_stringRepr();
10677 case OPTYPE_DECOMP
: {
10678 string
ret_val("decomp(");
10679 ret_val
+= u
.expr
.v1
->get_stringRepr();
10681 ret_val
+= u
.expr
.v2
->get_stringRepr();
10683 ret_val
+= u
.expr
.v3
->get_stringRepr();
10687 case OPTYPE_REPLACE
: {
10688 string
ret_val("replace(");
10689 u
.expr
.ti1
->append_stringRepr(ret_val
);
10691 ret_val
+= u
.expr
.v2
->get_stringRepr();
10693 ret_val
+= u
.expr
.v3
->get_stringRepr();
10695 u
.expr
.ti4
->append_stringRepr(ret_val
);
10699 case OPTYPE_ISPRESENT
: {
10700 string
ret_val("ispresent(");
10701 u
.expr
.ti1
->append_stringRepr(ret_val
);
10704 case OPTYPE_ISCHOSEN
: {
10705 string
ret_val("ischosen(");
10706 ret_val
+= u
.expr
.r1
->get_dispname();
10708 ret_val
+= u
.expr
.i2
->get_dispname();
10711 case OPTYPE_ISCHOSEN_V
: {
10712 string
ret_val("ischosen(");
10713 ret_val
+= u
.expr
.v1
->get_stringRepr();
10715 ret_val
+= u
.expr
.i2
->get_dispname();
10718 case OPTYPE_ISCHOSEN_T
: {
10719 string
ret_val("ischosen(");
10720 ret_val
+= u
.expr
.t1
->get_stringRepr();
10722 ret_val
+= u
.expr
.i2
->get_dispname();
10725 case OPTYPE_LENGTHOF
: {
10726 string
ret_val("lengthof(");
10727 u
.expr
.ti1
->append_stringRepr(ret_val
);
10730 case OPTYPE_SIZEOF
: {
10731 string
ret_val("sizeof(");
10732 u
.expr
.ti1
->append_stringRepr(ret_val
);
10735 case OPTYPE_ISVALUE
: {
10736 string
ret_val("isvalue(");
10737 u
.expr
.ti1
->append_stringRepr(ret_val
);
10740 case OPTYPE_VALUEOF
: {
10741 string
ret_val("valueof(");
10742 u
.expr
.ti1
->append_stringRepr(ret_val
);
10745 case OPTYPE_LOG2STR
:
10746 return string("log2str(...)");
10747 case OPTYPE_ANY2UNISTR
:
10748 return string("any2unistr(...)");
10749 case OPTYPE_MATCH
: {
10750 string
ret_val("match(");
10751 ret_val
+= u
.expr
.v1
->get_stringRepr();
10753 u
.expr
.t2
->append_stringRepr(ret_val
);
10756 case OPTYPE_TTCN2STRING
: {
10757 string
ret_val("ttcn2string(");
10758 u
.expr
.ti1
->append_stringRepr(ret_val
);
10762 case OPTYPE_UNDEF_RUNNING
:
10763 return u
.expr
.r1
->get_dispname() + ".running";
10764 case OPTYPE_COMP_NULL
:
10765 return string("null");
10766 case OPTYPE_COMP_MTC
:
10767 return string("mtc");
10768 case OPTYPE_COMP_SYSTEM
:
10769 return string("system");
10770 case OPTYPE_COMP_SELF
:
10771 return string("self");
10772 case OPTYPE_COMP_CREATE
: {
10773 string
ret_val(u
.expr
.r1
->get_dispname());
10774 ret_val
+= ".create";
10775 if (u
.expr
.v2
|| u
.expr
.v3
) {
10777 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10778 else ret_val
+= '-';
10781 ret_val
+= u
.expr
.v3
->get_stringRepr();
10785 if (u
.expr
.b4
) ret_val
+= " alive";
10787 case OPTYPE_COMP_RUNNING
:
10788 return u
.expr
.v1
->get_stringRepr() + ".running";
10789 case OPTYPE_COMP_RUNNING_ANY
:
10790 return string("any component.running");
10791 case OPTYPE_COMP_RUNNING_ALL
:
10792 return string("all component.running");
10793 case OPTYPE_COMP_ALIVE
:
10794 return u
.expr
.v1
->get_stringRepr() + ".alive";
10795 case OPTYPE_COMP_ALIVE_ANY
:
10796 return string("any component.alive");
10797 case OPTYPE_COMP_ALIVE_ALL
:
10798 return string("all component.alive");
10799 case OPTYPE_TMR_READ
:
10800 return u
.expr
.r1
->get_dispname() + ".read";
10801 case OPTYPE_TMR_RUNNING
:
10802 return u
.expr
.r1
->get_dispname() + ".running";
10803 case OPTYPE_TMR_RUNNING_ANY
:
10804 return string("any timer.running");
10805 case OPTYPE_CHECKSTATE_ANY
:
10806 case OPTYPE_CHECKSTATE_ALL
: {
10807 string
ret_val("");
10809 ret_val
+= u
.expr
.r1
->get_dispname();
10811 if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ANY
) {
10812 ret_val
+= "any port";
10813 } else if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ALL
) {
10814 ret_val
+= "all port";
10817 ret_val
+= "checkstate(";
10818 ret_val
+= u
.expr
.v2
->get_stringRepr();
10821 case OPTYPE_GETVERDICT
:
10822 return string("getverdict");
10823 case OPTYPE_ACTIVATE
: {
10824 string
ret_val("activate(");
10825 ret_val
+= u
.expr
.r1
->get_dispname();
10828 case OPTYPE_ACTIVATE_REFD
: {
10829 string
ret_val("activate(derefer(");
10830 ret_val
+= u
.expr
.v1
->get_stringRepr();
10832 if (u
.expr
.state
== EXPR_CHECKED
) {
10833 if (u
.expr
.ap_list2
) {
10834 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10835 for (size_t i
= 0; i
< nof_pars
; i
++) {
10836 if (i
> 0) ret_val
+= ", ";
10837 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10841 if (u
.expr
.t_list2
) {
10842 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10843 for (size_t i
= 0; i
< nof_pars
; i
++) {
10844 if (i
> 0) ret_val
+= ", ";
10845 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10851 case OPTYPE_EXECUTE
: {
10852 string
ret_val("execute(");
10853 ret_val
+= u
.expr
.r1
->get_dispname();
10856 ret_val
+= u
.expr
.v2
->get_stringRepr();
10860 case OPTYPE_EXECUTE_REFD
: {
10861 string
ret_val("execute(derefers(");
10862 ret_val
+= u
.expr
.v1
->get_stringRepr();
10864 if (u
.expr
.state
== EXPR_CHECKED
) {
10865 if (u
.expr
.ap_list2
) {
10866 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10867 for (size_t i
= 0; i
< nof_pars
; i
++) {
10868 if (i
> 0) ret_val
+= ", ";
10869 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10873 if (u
.expr
.t_list2
) {
10874 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10875 for (size_t i
= 0; i
< nof_pars
; i
++) {
10876 if (i
> 0) ret_val
+= ", ";
10877 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10884 ret_val
+= u
.expr
.v3
->get_stringRepr();
10888 case OPTYPE_PROF_RUNNING
:
10889 return string("@profiler.running");
10891 return string("<unsupported optype>");
10892 } // switch u.expr.v_optype
10895 case MACRO_MODULEID
:
10896 return string("%moduleId");
10897 case MACRO_FILENAME
:
10898 return string("%fileName");
10899 case MACRO_BFILENAME
:
10900 return string("__BFILE__");
10901 case MACRO_FILEPATH
:
10902 return string("__FILE__");
10903 case MACRO_LINENUMBER
:
10904 return string("%lineNumber");
10905 case MACRO_LINENUMBER_C
:
10906 return string("__LINE__");
10907 case MACRO_DEFINITIONID
:
10908 return string("%definitionId");
10910 return string("__SCOPE__");
10911 case MACRO_TESTCASEID
:
10912 return string("%testcaseId");
10914 return string("<unknown macro>");
10915 } // switch u.macro
10917 return string('-');
10921 string
ret_val("refers(");
10922 ret_val
+= u
.refd_fat
->get_assname();
10927 ret_val
+= u
.invoke
.v
->get_stringRepr();
10928 ret_val
+= ".apply(";
10929 if (u
.invoke
.ap_list
) {
10930 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10931 for (size_t i
= 0; i
< nof_pars
; i
++) {
10932 if (i
> 0) ret_val
+= ", ";
10933 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10935 } else if (u
.invoke
.t_list
) {
10936 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10937 for (size_t i
= 0; i
< nof_pars
; i
++) {
10938 if (i
> 0) ret_val
+= ", ";
10939 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10945 string
ret_val("refers(");
10946 ret_val
+= u
.refered
->get_dispname();
10950 return string("<unsupported valuetype>");
10951 } // switch valuetype
10954 string
Value::create_stringRepr_unary(const char *operator_str
)
10956 string
ret_val(operator_str
);
10958 ret_val
+= u
.expr
.v1
->get_stringRepr();
10963 string
Value::create_stringRepr_infix(const char *operator_str
)
10965 string
ret_val('(');
10966 ret_val
+= u
.expr
.v1
->get_stringRepr();
10968 ret_val
+= operator_str
;
10970 ret_val
+= u
.expr
.v2
->get_stringRepr();
10975 string
Value::create_stringRepr_predef1(const char *function_name
)
10977 string
ret_val(function_name
);
10979 if (u
.expr
.v_optype
== OPTYPE_ENCODE
|| u
.expr
.v_optype
== OPTYPE_ENCVALUE_UNICHAR
) { // ti1, not v1
10980 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10982 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10987 string
Value::create_stringRepr_predef2(const char *function_name
)
10989 string
ret_val(function_name
);
10991 ret_val
+= u
.expr
.v1
->get_stringRepr();
10993 ret_val
+= u
.expr
.v2
->get_stringRepr();
10998 bool Value::operator==(Value
& val
)
11000 Value
*left
= get_value_refd_last();
11001 Type
*left_governor
= left
->get_my_governor();
11002 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
11003 Value
*right
= val
.get_value_refd_last();
11004 Type
*right_governor
= right
->get_my_governor();
11005 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
11006 if (left_governor
&& right_governor
11007 && !left_governor
->is_compatible(right_governor
, NULL
)
11008 && !right_governor
->is_compatible(left_governor
, NULL
))
11009 FATAL_ERROR("Value::operator==");
11011 // Not-A-Value is not equal to anything (NaN analogy:)
11012 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
11015 switch (left
->valuetype
) {
11018 case V_DEFAULT_NULL
:
11021 return left
->valuetype
== right
->valuetype
;
11023 return right
->valuetype
== V_BOOL
&&
11024 left
->get_val_bool() == right
->get_val_bool();
11026 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
11027 == *right
->get_val_Int();
11029 return right
->valuetype
== V_REAL
&&
11030 left
->get_val_Real() == right
->get_val_Real();
11032 switch (right
->valuetype
) {
11034 return left
->get_val_str() == right
->get_val_str();
11036 return right
->get_val_ustr() == left
->get_val_str();
11038 return right
->get_val_iso2022str() == left
->get_val_str();
11045 return left
->valuetype
== right
->valuetype
&&
11046 left
->get_val_str() == right
->get_val_str();
11048 switch (right
->valuetype
) {
11050 return left
->get_val_ustr() == right
->get_val_str();
11052 return left
->get_val_ustr() == right
->get_val_ustr();
11054 return left
->get_val_ustr() == right
->get_val_iso2022str();
11059 switch (right
->valuetype
) {
11061 return left
->get_val_iso2022str() == right
->get_val_str();
11063 // The appropriate operator==() is missing. The operands are swapped,
11064 // but it shouldn't be a problem.
11065 return right
->get_val_ustr() == left
->get_val_iso2022str();
11067 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
11072 return right
->valuetype
== V_ENUM
&&
11073 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
11076 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
11077 vector
<string
> act
, other
;
11078 get_oid_comps(act
);
11079 val
.get_oid_comps(other
);
11080 size_t act_size
= act
.size(), other_size
= other
.size();
11082 if (act_size
== other_size
) {
11084 for (size_t i
= 0; i
< act_size
; i
++)
11085 if (*act
[i
] != *other
[i
]) {
11089 } else ret_val
= false;
11090 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
11092 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
11095 } else return false;
11097 return right
->valuetype
== V_CHOICE
&&
11098 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
11099 *(left
->get_alt_value()) == *(right
->get_alt_value());
11102 if (!left_governor
) FATAL_ERROR("Value::operator==");
11103 if (left
->valuetype
!= right
->valuetype
) return false;
11104 size_t nof_comps
= left_governor
->get_nof_comps();
11105 for (size_t i
= 0; i
< nof_comps
; i
++) {
11106 Value
*lval
= NULL
, *rval
= NULL
;
11107 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
11108 const Identifier
& field_name
= cfl
->get_name();
11109 if (left
->has_comp_withName(field_name
)) {
11110 lval
= left
->get_comp_value_byName(field_name
);
11111 if (right
->has_comp_withName(field_name
)) {
11112 rval
= right
->get_comp_value_byName(field_name
);
11113 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
11114 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
11116 else if (!(*lval
== *rval
))
11119 if (cfl
->has_default()) {
11120 if (!(*lval
== *cfl
->get_defval()))
11123 if (lval
->valuetype
!= V_OMIT
)
11128 if(right
->has_comp_withName(field_name
)) {
11129 rval
= right
->get_comp_value_byName(field_name
);
11130 if(cfl
->has_default()) {
11131 if(rval
->valuetype
==V_OMIT
) return false;
11133 lval
= cfl
->get_defval();
11134 if (!(*lval
==*rval
)) return false;
11143 if (left
->valuetype
!= right
->valuetype
) return false;
11144 size_t ncomps
= get_nof_comps();
11145 if (ncomps
!= right
->get_nof_comps()) return false;
11147 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
11148 bool found
= false;
11149 map
<IndexedValue
*, void> uncovered
;
11150 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
11151 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
11153 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
11155 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
11156 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
11157 *(right
->get_comp_byIndex(i
)) &&
11158 *(uncovered
.get_nth_key(j
)->get_index()) ==
11159 *(right
->get_index_byIndex(i
))) {
11161 uncovered
.erase(uncovered
.get_nth_key(j
));
11169 } else if (left
->is_indexed() || right
->is_indexed()) {
11170 Value
* indexed_one
= 0;
11171 Value
* not_indexed_one
= 0;
11173 if(left
->is_indexed()) { // left is indexed, right is not
11174 indexed_one
= left
;
11175 not_indexed_one
= right
;
11176 } else { // right indexed, left is not
11177 indexed_one
= right
;
11178 not_indexed_one
= left
;
11181 for(size_t i
= 0; i
< ncomps
; ++i
) {
11182 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
11183 if(!(ind
->valuetype
== V_INT
&&
11184 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
11185 *(indexed_one
->get_comp_byIndex(i
))))
11189 } else { // none of them is indexed
11190 for (size_t i
= 0; i
< ncomps
; i
++) {
11191 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
11198 if (right
->valuetype
!= V_SETOF
) return false;
11199 size_t ncomps
= get_nof_comps();
11200 if (ncomps
!= right
->get_nof_comps()) return false;
11201 if (ncomps
== 0) return true;
11202 map
<size_t, void> uncovered
;
11203 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
11204 for (size_t i
= 0; i
< ncomps
; i
++) {
11205 Value
*left_item
= left
->get_comp_byIndex(i
);
11206 bool pair_found
= false;
11207 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
11208 size_t right_index
= uncovered
.get_nth_key(j
);
11209 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
11210 uncovered
.erase(right_index
);
11222 return right
->valuetype
== V_VERDICT
&&
11223 left
->get_val_verdict() == right
->get_val_verdict();
11227 return left
->valuetype
== right
->valuetype
&&
11228 left
->get_refd_assignment() == right
->get_refd_assignment();
11230 FATAL_ERROR("Value::operator==");
11235 bool Value::operator<(Value
& val
)
11237 Value
*left
= get_value_refd_last();
11238 Type
*left_governor
= left
->get_my_governor();
11239 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
11240 Value
*right
= val
.get_value_refd_last();
11241 Type
*right_governor
= right
->get_my_governor();
11242 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
11243 if (left
->get_valuetype() != right
->get_valuetype())
11244 FATAL_ERROR("Value::operator<");
11247 return *left
->get_val_Int() < *right
->get_val_Int();
11249 return (left
->get_val_Real() < right
->get_val_Real());
11251 if(!left_governor
|| !right_governor
)
11252 FATAL_ERROR("Value::operator<");
11253 if(left_governor
!=right_governor
)
11254 FATAL_ERROR("Value::operator<");
11255 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
11256 right_governor
->get_enum_val_byId(*right
->get_val_id()));
11258 FATAL_ERROR("Value::operator<");
11263 bool Value::is_string_type(Type::expected_value_t exp_val
)
11265 switch (get_expr_returntype(exp_val
)) {
11277 void Value::generate_code_expr(expression_struct
*expr
)
11279 if (has_single_expr()) {
11280 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
11282 switch (valuetype
) {
11284 generate_code_expr_expr(expr
);
11292 const string
& tmp_id
= get_temporary_id();
11293 const char *tmp_id_str
= tmp_id
.c_str();
11294 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11295 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
11296 set_genname_recursive(tmp_id
);
11297 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11298 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11301 const string
& tmp_id
= get_temporary_id();
11302 const char *tmp_id_str
= tmp_id
.c_str();
11303 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
11305 set_genname_recursive(tmp_id
);
11306 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
11307 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11310 if (!get_needs_conversion()) {
11311 u
.ref
.ref
->generate_code_const_ref(expr
);
11313 Type
*my_gov
= get_expr_governor_last();
11314 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
11315 ->get_field_type(u
.ref
.ref
->get_subrefs(),
11316 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
11317 // Make sure that nothing goes wrong.
11318 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
11319 FATAL_ERROR("Value::generate_code_expr()");
11320 expression_struct expr_tmp
;
11321 Code::init_expr(&expr_tmp
);
11322 const string
& tmp_id1
= get_temporary_id();
11323 const char *tmp_id_str1
= tmp_id1
.c_str();
11324 const string
& tmp_id2
= get_temporary_id();
11325 const char *tmp_id_str2
= tmp_id2
.c_str();
11326 expr
->preamble
= mputprintf(expr
->preamble
,
11327 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
11329 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11330 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
11331 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11332 expr
->preamble
= mputprintf(expr
->preamble
,
11334 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11335 "and `%s' are not compatible at run-time\");\n",
11336 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11337 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
11338 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
11339 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
11340 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11344 generate_code_expr_invoke(expr
);
11347 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
11352 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
11354 generate_code_expr(expr
);
11355 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11356 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11359 bool Value::can_use_increment(Reference
*ref
) const
11361 if (valuetype
!= V_EXPR
) {
11364 switch (u
.expr
.v_optype
) {
11366 case OPTYPE_SUBTRACT
:
11371 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11372 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11373 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11374 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11375 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11376 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11382 char *Value::generate_code_init(char *str
, const char *name
)
11384 if (get_code_generated()) return str
;
11386 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11388 switch (valuetype
) {
11402 case V_DEFAULT_NULL
:
11407 // These values have a single string equivalent.
11408 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11411 if (u
.val_Int
->is_native_fit())
11412 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11414 // It's always an INTEGER.
11415 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11416 "}\n", get_single_expr().c_str(), name
);
11420 expression_struct expr
;
11421 Code::init_expr(&expr
);
11422 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11423 generate_code_expr(&expr
);
11424 str
= Code::merge_free_expr(str
, &expr
);
11427 str
= generate_code_init_choice(str
, name
);
11431 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11432 else str
= generate_code_init_indexed(str
, name
);
11435 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11436 else str
= generate_code_init_indexed(str
, name
);
11440 str
= generate_code_init_se(str
, name
);
11443 str
= generate_code_init_refd(str
, name
);
11447 case MACRO_TESTCASEID
:
11448 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11451 // all others must already be evaluated away
11452 FATAL_ERROR("Value::generate_code_init()");
11456 // unbound value, don't generate anything
11459 FATAL_ERROR("Value::generate_code_init()");
11462 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11464 set_code_generated();
11468 char *Value::rearrange_init_code(char *str
, Common::Module
* usage_mod
)
11470 switch (valuetype
) {
11472 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11474 str
= parlist
->rearrange_init_code(str
, usage_mod
);
11478 str
= u
.invoke
.v
->rearrange_init_code(str
, usage_mod
);
11479 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, usage_mod
);
11482 switch (u
.expr
.v_optype
) {
11483 case OPTYPE_UNARYPLUS
:
11484 case OPTYPE_UNARYMINUS
:
11487 case OPTYPE_BIT2HEX
:
11488 case OPTYPE_BIT2INT
:
11489 case OPTYPE_BIT2OCT
:
11490 case OPTYPE_BIT2STR
:
11491 case OPTYPE_CHAR2INT
:
11492 case OPTYPE_CHAR2OCT
:
11493 case OPTYPE_FLOAT2INT
:
11494 case OPTYPE_FLOAT2STR
:
11495 case OPTYPE_HEX2BIT
:
11496 case OPTYPE_HEX2INT
:
11497 case OPTYPE_HEX2OCT
:
11498 case OPTYPE_HEX2STR
:
11499 case OPTYPE_INT2CHAR
:
11500 case OPTYPE_INT2FLOAT
:
11501 case OPTYPE_INT2STR
:
11502 case OPTYPE_INT2UNICHAR
:
11503 case OPTYPE_OCT2BIT
:
11504 case OPTYPE_OCT2CHAR
:
11505 case OPTYPE_OCT2HEX
:
11506 case OPTYPE_OCT2INT
:
11507 case OPTYPE_OCT2STR
:
11508 case OPTYPE_STR2BIT
:
11509 case OPTYPE_STR2FLOAT
:
11510 case OPTYPE_STR2HEX
:
11511 case OPTYPE_STR2INT
:
11512 case OPTYPE_STR2OCT
:
11513 case OPTYPE_UNICHAR2INT
:
11514 case OPTYPE_UNICHAR2CHAR
:
11515 case OPTYPE_ENUM2INT
:
11516 case OPTYPE_ISCHOSEN_V
:
11517 case OPTYPE_GET_STRINGENCODING
:
11518 case OPTYPE_REMOVE_BOM
:
11519 case OPTYPE_DECODE_BASE64
:
11520 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11522 case OPTYPE_DECODE
: {
11523 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11524 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11526 parlist
= u
.expr
.r2
->get_parlist();
11527 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11529 case OPTYPE_HOSTID
:
11530 if (u
.expr
.v1
) str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11533 case OPTYPE_SUBTRACT
:
11534 case OPTYPE_MULTIPLY
:
11535 case OPTYPE_DIVIDE
:
11538 case OPTYPE_CONCAT
:
11555 case OPTYPE_INT2BIT
:
11556 case OPTYPE_INT2HEX
:
11557 case OPTYPE_INT2OCT
:
11558 //case OPTYPE_DECODE:
11559 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11560 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11562 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11563 case OPTYPE_OCT2UNICHAR
:
11564 case OPTYPE_ENCODE_BASE64
:
11565 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11566 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11568 case OPTYPE_SUBSTR
:
11569 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11570 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11571 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11573 case OPTYPE_REGEXP
:
11574 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11575 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11576 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11578 case OPTYPE_DECOMP
:
11579 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11580 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11581 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11583 case OPTYPE_REPLACE
:
11584 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11585 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11586 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11587 str
= u
.expr
.ti4
->rearrange_init_code(str
, usage_mod
);
11589 case OPTYPE_LENGTHOF
:
11590 case OPTYPE_SIZEOF
:
11591 case OPTYPE_VALUEOF
:
11592 case OPTYPE_ENCODE
:
11593 case OPTYPE_ISPRESENT
:
11594 case OPTYPE_TTCN2STRING
:
11595 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11597 case OPTYPE_ENCVALUE_UNICHAR
:
11598 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11599 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11601 case OPTYPE_DECVALUE_UNICHAR
: {
11602 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11603 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11604 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11606 parlist
= u
.expr
.r2
->get_parlist();
11607 ass
= u
.expr
.r2
->get_refd_assignment();
11608 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11609 if (u
.expr
.v3
) str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11611 case OPTYPE_ISCHOSEN_T
:
11612 str
= u
.expr
.t1
->rearrange_init_code(str
, usage_mod
);
11615 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11616 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11619 // other kinds of expressions cannot appear within templates
11629 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11630 size_t& blockcount
)
11632 char *s2
= memptystr();
11633 char *s1
= generate_code_tmp(NULL
, s2
);
11635 if (blockcount
== 0) {
11636 str
= mputstr(str
, "{\n");
11639 str
= mputstr(str
, s2
);
11642 str
=mputstr(str
, prefix
);
11643 str
=mputstr(str
, s1
);
11648 char *Value::generate_code_tmp(char *str
, char*& init
)
11650 expression_struct expr
;
11651 Code::init_expr(&expr
);
11652 generate_code_expr_mandatory(&expr
);
11653 if (expr
.preamble
|| expr
.postamble
) {
11654 if (valuetype
== V_EXPR
&&
11655 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11656 // a temporary variable is already introduced
11657 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11658 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11659 str
= mputstr(str
, expr
.expr
);
11661 const string
& tmp_id
= get_temporary_id();
11662 const char *tmp_id_str
= tmp_id
.c_str();
11663 init
= mputprintf(init
, "%s %s;\n"
11665 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11666 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11668 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11669 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11670 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11671 init
= mputstr(init
, "}\n");
11672 str
= mputstr(str
, tmp_id_str
);
11674 } else str
= mputstr(str
, expr
.expr
);
11675 Code::free_expr(&expr
);
11679 void Value::generate_code_log(expression_struct
*expr
)
11681 if (explicit_cast_needed()) {
11682 char *expr_backup
= expr
->expr
;
11684 generate_code_expr(expr
);
11685 const string
& tmp_id
= get_temporary_id();
11686 const char *tmp_id_str
= tmp_id
.c_str();
11687 // We have to create a temporary object, because the parser of GCC
11688 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11689 // constructor call that is, this does not work: type(...).log(); but
11690 // this works: type tmp(...); tmp.log();.
11691 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11692 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11695 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11697 generate_code_expr(expr
);
11699 expr
->expr
= mputstr(expr
->expr
, ".log()");
11702 void Value::generate_code_log_match(expression_struct
*expr
)
11704 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11705 FATAL_ERROR("Value::generate_code_log_match()");
11706 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11707 // compliance the whole code-generation should be checked. Standalone
11708 // constructs like: "A(a[0].f());" should be avoided. The current
11709 // solution for HK38721 uses an additional assignment to overcome the
11710 // issue. The generated code will be slower, but it's needed for old GCC
11711 // versions in specific circumstances.
11712 if (u
.expr
.t2
->needs_temp_ref()) {
11713 char *expr_backup
= expr
->expr
;
11715 u
.expr
.t2
->generate_code(expr
);
11716 const string
& tmp_id
= get_temporary_id();
11717 const char *tmp_id_str
= tmp_id
.c_str();
11718 expr
->preamble
= mputprintf(expr
->preamble
,
11719 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11720 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11722 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11724 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11725 // some reason "(A(NS::B)).a(C);" compiles fine.
11726 expr
->expr
= mputc(expr
->expr
, '(');
11727 u
.expr
.t2
->generate_code(expr
);
11728 expr
->expr
= mputc(expr
->expr
, ')');
11730 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11731 u
.expr
.v1
->generate_code_expr(expr
);
11732 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11735 void Value::generate_code_expr_expr(expression_struct
*expr
)
11737 switch (u
.expr
.v_optype
) {
11739 generate_code_expr_rnd(expr
, 0);
11741 case OPTYPE_UNARYPLUS
:
11742 // same as without the '+' operator
11743 u
.expr
.v1
->generate_code_expr(expr
);
11745 case OPTYPE_UNARYMINUS
:
11746 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11749 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11752 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11754 case OPTYPE_BIT2HEX
:
11755 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11757 case OPTYPE_BIT2INT
:
11758 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11760 case OPTYPE_BIT2OCT
:
11761 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11763 case OPTYPE_BIT2STR
:
11764 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11766 case OPTYPE_CHAR2INT
:
11767 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11769 case OPTYPE_CHAR2OCT
:
11770 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11772 case OPTYPE_FLOAT2INT
:
11773 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11775 case OPTYPE_FLOAT2STR
:
11776 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11778 case OPTYPE_HEX2BIT
:
11779 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11781 case OPTYPE_HEX2INT
:
11782 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11784 case OPTYPE_HEX2OCT
:
11785 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11787 case OPTYPE_HEX2STR
:
11788 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11790 case OPTYPE_INT2CHAR
:
11791 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11793 case OPTYPE_INT2FLOAT
:
11794 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11796 case OPTYPE_INT2STR
:
11797 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11799 case OPTYPE_INT2UNICHAR
:
11800 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11802 case OPTYPE_OCT2BIT
:
11803 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11805 case OPTYPE_OCT2CHAR
:
11806 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11808 case OPTYPE_GET_STRINGENCODING
:
11809 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11811 case OPTYPE_REMOVE_BOM
:
11812 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11814 case OPTYPE_ENCODE_BASE64
:
11816 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11818 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11820 case OPTYPE_DECODE_BASE64
:
11821 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11823 case OPTYPE_OCT2UNICHAR
:
11825 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11827 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11829 case OPTYPE_UNICHAR2OCT
:
11831 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11833 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11835 case OPTYPE_ENCVALUE_UNICHAR
:
11836 generate_code_expr_encvalue_unichar(expr
);
11838 case OPTYPE_DECVALUE_UNICHAR
:
11839 generate_code_expr_decvalue_unichar(expr
);
11841 case OPTYPE_HOSTID
:
11842 generate_code_expr_hostid(expr
);
11844 case OPTYPE_OCT2HEX
:
11845 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11847 case OPTYPE_OCT2INT
:
11848 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11850 case OPTYPE_OCT2STR
:
11851 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11853 case OPTYPE_STR2BIT
:
11854 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11856 case OPTYPE_STR2FLOAT
:
11857 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11859 case OPTYPE_STR2HEX
:
11860 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11862 case OPTYPE_STR2INT
:
11863 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11865 case OPTYPE_STR2OCT
:
11866 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11868 case OPTYPE_UNICHAR2INT
:
11869 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11871 case OPTYPE_UNICHAR2CHAR
:
11872 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11874 case OPTYPE_ENUM2INT
: {
11875 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11876 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11877 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11878 enum_type
->get_genname_value(my_scope
).c_str());
11879 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11880 expr
->expr
= mputc(expr
->expr
, ')');
11882 case OPTYPE_ENCODE
:
11883 generate_code_expr_encode(expr
);
11885 case OPTYPE_DECODE
:
11886 generate_code_expr_decode(expr
);
11888 case OPTYPE_RNDWITHVAL
:
11889 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11892 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11894 case OPTYPE_SUBTRACT
:
11895 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11897 case OPTYPE_MULTIPLY
:
11898 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11900 case OPTYPE_DIVIDE
:
11901 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11904 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11907 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11909 case OPTYPE_CONCAT
:
11910 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11913 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11916 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11919 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11922 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11925 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11928 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11932 generate_code_expr_and_or(expr
);
11935 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11938 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11941 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11944 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11947 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11950 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11953 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11956 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11958 case OPTYPE_INT2BIT
:
11959 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11961 case OPTYPE_INT2HEX
:
11962 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11964 case OPTYPE_INT2OCT
:
11965 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11967 case OPTYPE_SUBSTR
:
11968 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11969 else generate_code_expr_substr_replace_compat(expr
);
11971 case OPTYPE_REGEXP
:
11972 generate_code_expr_regexp(expr
);
11974 case OPTYPE_DECOMP
:
11975 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11977 case OPTYPE_REPLACE
:
11978 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11979 else generate_code_expr_substr_replace_compat(expr
);
11981 case OPTYPE_ISCHOSEN
: // r1 i2
11982 FATAL_ERROR("Value::generate_code_expr_expr()");
11984 case OPTYPE_ISCHOSEN_V
: // v1 i2
11985 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11986 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11987 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11988 u
.expr
.i2
->get_name().c_str());
11990 case OPTYPE_ISCHOSEN_T
: // t1 i2
11991 u
.expr
.t1
->generate_code_expr(expr
);
11992 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11993 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11994 u
.expr
.i2
->get_name().c_str());
11996 case OPTYPE_ISPRESENT
:
11997 case OPTYPE_ISBOUND
: {
11998 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11999 ->get_templatetype();
12000 if (temp
== Template::SPECIFIC_VALUE
) {
12001 Value
* specific_value
= u
.expr
.ti1
->get_Template()
12002 ->get_specific_value();
12003 if (specific_value
->get_valuetype() == Value::V_REFD
) {
12004 Ttcn::Reference
* reference
=
12005 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
12007 reference
->generate_code_ispresentbound(expr
, false,
12008 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
12012 } else if (temp
== Template::TEMPLATE_REFD
){
12013 Ttcn::Reference
* reference
=
12014 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
12015 ->get_reference());
12017 reference
->generate_code_ispresentbound(expr
, true,
12018 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
12024 case OPTYPE_LENGTHOF
: // ti1
12025 // fall through, separated later
12026 case OPTYPE_SIZEOF
: // ti1
12027 // fall through, separated later
12028 case OPTYPE_ISVALUE
: { // ti1
12029 if (u
.expr
.ti1
->is_only_specific_value()) {
12030 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
12031 bool cast_needed
= t_val
->explicit_cast_needed(
12032 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
12034 // the ambiguous C++ expression is converted to the value class
12035 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12036 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
12039 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
12040 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
12041 t_val
->generate_code_expr(expr
);
12043 t_val
->generate_code_expr_mandatory(expr
);
12046 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
12048 else u
.expr
.ti1
->generate_code(expr
);
12050 switch (u
.expr
.v_optype
) {
12051 case OPTYPE_ISBOUND
:
12052 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
12054 case OPTYPE_ISPRESENT
:
12055 expr
->expr
=mputprintf(expr
->expr
, ".is_present()");
12057 case OPTYPE_SIZEOF
:
12058 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
12060 case OPTYPE_LENGTHOF
:
12061 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
12063 case OPTYPE_ISVALUE
:
12064 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
12067 FATAL_ERROR("Value::generate_code_expr_expr()");
12070 case OPTYPE_VALUEOF
: // ti1
12071 u
.expr
.ti1
->generate_code(expr
);
12072 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
12074 case OPTYPE_MATCH
: // v1 t2
12075 u
.expr
.t2
->generate_code(expr
);
12076 expr
->expr
= mputstr(expr
->expr
, ".match(");
12077 u
.expr
.v1
->generate_code_expr(expr
);
12078 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
12080 case OPTYPE_UNDEF_RUNNING
:
12081 // it is resolved during semantic check
12082 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
12084 case OPTYPE_COMP_NULL
: // -
12085 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
12087 case OPTYPE_COMP_MTC
: // -
12088 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
12090 case OPTYPE_COMP_SYSTEM
: // -
12091 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
12093 case OPTYPE_COMP_SELF
: // -
12094 expr
->expr
=mputstr(expr
->expr
, "self");
12096 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
12097 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
12100 case OPTYPE_COMP_RUNNING
: // v1
12101 u
.expr
.v1
->generate_code_expr(expr
);
12102 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
12103 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
12104 expr
->expr
= mputstr(expr
->expr
, ".running()");
12106 case OPTYPE_COMP_RUNNING_ANY
: // -
12107 expr
->expr
=mputstr(expr
->expr
,
12108 "TTCN_Runtime::component_running(ANY_COMPREF)");
12110 case OPTYPE_COMP_RUNNING_ALL
: // -
12111 expr
->expr
=mputstr(expr
->expr
,
12112 "TTCN_Runtime::component_running(ALL_COMPREF)");
12114 case OPTYPE_COMP_ALIVE
: // v1
12115 u
.expr
.v1
->generate_code_expr(expr
);
12116 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
12117 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
12118 expr
->expr
= mputstr(expr
->expr
, ".alive()");
12120 case OPTYPE_COMP_ALIVE_ANY
: // -
12121 expr
->expr
= mputstr(expr
->expr
,
12122 "TTCN_Runtime::component_alive(ANY_COMPREF)");
12124 case OPTYPE_COMP_ALIVE_ALL
: // -
12125 expr
->expr
= mputstr(expr
->expr
,
12126 "TTCN_Runtime::component_alive(ALL_COMPREF)");
12128 case OPTYPE_TMR_READ
: // r1
12129 u
.expr
.r1
->generate_code(expr
);
12130 expr
->expr
= mputstr(expr
->expr
, ".read()");
12132 case OPTYPE_TMR_RUNNING
: // r1
12133 u
.expr
.r1
->generate_code(expr
);
12134 expr
->expr
= mputstr(expr
->expr
, ".running()");
12136 case OPTYPE_TMR_RUNNING_ANY
: // -
12137 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
12139 case OPTYPE_GETVERDICT
: // -
12140 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
12142 case OPTYPE_TESTCASENAME
: // -
12143 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
12145 case OPTYPE_ACTIVATE
: // r1
12146 generate_code_expr_activate(expr
);
12148 case OPTYPE_CHECKSTATE_ANY
: // [r1] v2
12149 case OPTYPE_CHECKSTATE_ALL
:
12150 generate_code_expr_checkstate(expr
);
12152 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
12153 generate_code_expr_activate_refd(expr
);
12155 case OPTYPE_EXECUTE
: // r1 [v2]
12156 generate_code_expr_execute(expr
);
12158 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
12159 generate_code_expr_execute_refd(expr
);
12161 case OPTYPE_LOG2STR
:
12162 case OPTYPE_ANY2UNISTR
:
12163 u
.expr
.logargs
->generate_code_expr(expr
);
12165 case OPTYPE_TTCN2STRING
: {
12166 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
12167 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
12168 param_governor
= param_governor
->get_type_refd_last();
12169 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
12170 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
12171 u
.expr
.ti1
->get_Template()->is_Value()) {
12172 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
12175 bool cast_needed
= v
->explicit_cast_needed();
12177 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
12179 v
->generate_code_expr(expr
);
12181 expr
->expr
= mputstr(expr
->expr
, ")");
12185 u
.expr
.ti1
->generate_code(expr
);
12187 expr
->expr
= mputstr(expr
->expr
, ")");
12189 case OPTYPE_PROF_RUNNING
:
12190 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
12193 FATAL_ERROR("Value::generate_code_expr_expr()");
12197 void Value::generate_code_expr_unary(expression_struct
*expr
,
12198 const char *operator_str
, Value
*v1
)
12200 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
12201 v1
->generate_code_expr_mandatory(expr
);
12202 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
12205 void Value::generate_code_expr_infix(expression_struct
*expr
,
12206 const char *operator_str
, Value
*v1
,
12207 Value
*v2
, bool optional_allowed
)
12209 if (!get_needs_conversion()) {
12210 expr
->expr
= mputc(expr
->expr
, '(');
12211 if (optional_allowed
) v1
->generate_code_expr(expr
);
12212 else v1
->generate_code_expr_mandatory(expr
);
12213 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
12214 if (optional_allowed
) v2
->generate_code_expr(expr
);
12215 else v2
->generate_code_expr_mandatory(expr
);
12216 expr
->expr
= mputc(expr
->expr
, ')');
12217 } else { // Temporary variable for the converted value.
12218 const string
& tmp_id1
= get_temporary_id();
12219 const char *tmp_id_str1
= tmp_id1
.c_str();
12220 expression_struct expr_tmp
;
12221 Code::init_expr(&expr_tmp
);
12222 switch (u
.expr
.v_optype
) {
12225 // Always "v1 -> v2".
12226 Type
*t1
= v1
->get_expr_governor_last();
12227 Type
*t2
= v2
->get_expr_governor_last();
12228 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
12229 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12230 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12231 if (expr_tmp
.preamble
)
12232 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12233 expr
->preamble
= mputprintf(expr
->preamble
,
12235 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12236 "and `%s' are not compatible at run-time\");\n",
12237 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
12238 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
12239 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
12240 t2
->get_typename().c_str(), t1
->get_typename().c_str());
12241 Code::free_expr(&expr_tmp
);
12242 if (optional_allowed
) v1
->generate_code_expr(expr
);
12243 else v1
->generate_code_expr_mandatory(expr
);
12244 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
12247 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12248 // functions. The governors of all operands must exist at this point.
12251 case OPTYPE_CONCAT
: {
12252 const string
& tmp_id2
= get_temporary_id();
12253 const char *tmp_id_str2
= tmp_id2
.c_str();
12254 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
12255 Type
*my_gov
= my_governor
->get_type_refd_last();
12256 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
12257 ->get_type_refd_last();
12258 if (!t1_gov
|| my_gov
== t1_gov
)
12259 FATAL_ERROR("Value::generate_code_expr_infix()");
12260 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
12261 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
12262 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
12263 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
12264 else v1
->generate_code_expr_mandatory(&expr_tmp
);
12265 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
12266 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
12267 else v2
->generate_code_expr_mandatory(&expr_tmp
);
12268 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
12269 expr
->preamble
= mputprintf(expr
->preamble
,
12271 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12272 "and `%s' are not compatible at run-time\");\n",
12273 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
12274 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
12275 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
12276 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
12277 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
12280 FATAL_ERROR("Value::generate_code_expr_infix()");
12286 void Value::generate_code_expr_and_or(expression_struct
*expr
)
12288 if (u
.expr
.v2
->needs_short_circuit()) {
12289 // introduce a temporary variable to store the result of the operation
12290 const string
& tmp_id
= get_temporary_id();
12291 const char *tmp_id_str
= tmp_id
.c_str();
12292 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
12293 expression_struct expr2
;
12294 // the left operand must be evaluated anyway
12295 Code::init_expr(&expr2
);
12296 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12297 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
12298 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12299 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
12300 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
12301 // evaluate the right operand only when necessary
12302 // in this case the final result will be the right operand
12303 Code::init_expr(&expr2
);
12304 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
12305 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
12306 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
12307 // the result is now in the temporary variable
12308 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
12310 // use the overloaded operator to get better error messages
12311 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
12312 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
12316 void Value::generate_code_expr_predef1(expression_struct
*expr
,
12317 const char *function_name
,
12320 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12321 v1
->generate_code_expr_mandatory(expr
);
12322 expr
->expr
= mputc(expr
->expr
, ')');
12325 void Value::generate_code_expr_predef2(expression_struct
*expr
,
12326 const char *function_name
,
12327 Value
*v1
, Value
*v2
)
12329 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12330 v1
->generate_code_expr_mandatory(expr
);
12331 expr
->expr
= mputstr(expr
->expr
, ", ");
12332 v2
->generate_code_expr_mandatory(expr
);
12333 expr
->expr
= mputc(expr
->expr
, ')');
12336 void Value::generate_code_expr_predef3(expression_struct
*expr
,
12337 const char *function_name
,
12338 Value
*v1
, Value
*v2
, Value
*v3
)
12340 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
12341 v1
->generate_code_expr_mandatory(expr
);
12342 expr
->expr
= mputstr(expr
->expr
, ", ");
12343 v2
->generate_code_expr_mandatory(expr
);
12344 expr
->expr
= mputstr(expr
->expr
, ", ");
12345 v3
->generate_code_expr_mandatory(expr
);
12346 expr
->expr
= mputc(expr
->expr
, ')');
12349 void Value::generate_code_expr_substr(expression_struct
*expr
)
12352 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12353 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12354 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12355 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
12356 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12357 else u
.expr
.ti1
->generate_code(expr
);
12358 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12359 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
12360 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12361 expr
->expr
= mputstr(expr
->expr
, "(int)");
12362 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12363 expr
->expr
= mputstr(expr
->expr
, ", ");
12364 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12365 expr
->expr
= mputstr(expr
->expr
, "(int)");
12366 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12367 expr
->expr
= mputc(expr
->expr
, ')');
12370 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
12372 expression_struct expr_tmp
;
12373 Code::init_expr(&expr_tmp
);
12374 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
12375 ->get_type_refd_last();
12376 if (!t1
|| t1
== my_governor
->get_type_refd_last())
12377 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12378 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
12379 generate_code_expr_substr(&expr_tmp
);
12380 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
12381 generate_code_expr_replace(&expr_tmp
);
12383 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12385 // Two temporaries to store the result of substr() or replace() and to
12386 // store the converted value.
12387 const string
& tmp_id1
= get_temporary_id();
12388 const char *tmp_id_str1
= tmp_id1
.c_str();
12389 const string
& tmp_id2
= get_temporary_id();
12390 const char *tmp_id_str2
= tmp_id2
.c_str();
12391 if (expr_tmp
.preamble
)
12392 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12393 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12394 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12395 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12396 if (expr_tmp
.postamble
)
12397 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12398 Code::free_expr(&expr_tmp
);
12399 expr
->preamble
= mputprintf(expr
->preamble
,
12400 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12401 "`%s' are not compatible at run-time\");\n",
12402 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12403 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12404 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12405 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12408 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12410 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12411 Value
* v2
= u
.expr
.t2
->get_specific_value();
12412 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12413 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12414 else u
.expr
.ti1
->generate_code(expr
);
12415 expr
->expr
= mputstr(expr
->expr
, ", ");
12416 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12417 else u
.expr
.t2
->generate_code(expr
);
12418 expr
->expr
= mputstr(expr
->expr
, ", ");
12419 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12420 expr
->expr
= mputc(expr
->expr
, ')');
12423 void Value::generate_code_expr_replace(expression_struct
*expr
)
12425 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12426 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12428 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12429 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12430 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12431 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12432 else u
.expr
.ti1
->generate_code(expr
);
12433 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12434 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12435 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12436 expr
->expr
= mputstr(expr
->expr
, "(int)");
12437 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12438 expr
->expr
= mputstr(expr
->expr
, ", ");
12439 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12440 expr
->expr
= mputstr(expr
->expr
, "(int)");
12441 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12442 expr
->expr
= mputstr(expr
->expr
, ", ");
12444 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12445 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12446 Value
* v4_last
= v4
->get_value_refd_last();
12447 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12448 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12449 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12451 v4
->generate_code_expr_mandatory(expr
);
12453 else u
.expr
.ti4
->generate_code(expr
);
12454 expr
->expr
= mputc(expr
->expr
, ')');
12457 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12460 if(!v1
) // simple random generation
12461 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12462 else { // random generation with seeding
12463 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12464 v1
->generate_code_expr_mandatory(expr
);
12465 expr
->expr
= mputc(expr
->expr
, ')');
12469 void Value::generate_code_expr_create(expression_struct
*expr
,
12470 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12472 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12473 // first two arguments: component type
12474 Assignment
*t_ass
= type
->get_refd_assignment();
12475 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12476 FATAL_ERROR("Value::generate_code_expr_create()");
12477 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12478 Type::EXPECTED_DYNAMIC_VALUE
);
12479 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12480 comptype
= comptype
->get_type_refd_last();
12481 expr
->expr
= comptype
->get_CompBody()
12482 ->generate_code_comptype_name(expr
->expr
);
12483 expr
->expr
= mputstr(expr
->expr
, ", ");
12484 // third argument: component name
12486 Value
*t_val
= name
->get_value_refd_last();
12487 if (t_val
->valuetype
== V_CSTR
) {
12488 // the argument is foldable to a string literal
12489 size_t str_len
= t_val
->u
.str
.val_str
->size();
12490 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12491 expr
->expr
= mputc(expr
->expr
, '"');
12492 for (size_t i
= 0; i
< str_len
; i
++)
12493 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12494 expr
->expr
= mputc(expr
->expr
, '"');
12495 } else name
->generate_code_expr_mandatory(expr
);
12496 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12497 expr
->expr
= mputstr(expr
->expr
, ", ");
12498 // fourth argument: location
12500 Value
*t_val
= location
->get_value_refd_last();
12501 if (t_val
->valuetype
== V_CSTR
) {
12502 // the argument is foldable to a string literal
12503 size_t str_len
= t_val
->u
.str
.val_str
->size();
12504 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12505 expr
->expr
= mputc(expr
->expr
, '"');
12506 for (size_t i
= 0; i
< str_len
; i
++)
12507 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12508 expr
->expr
= mputc(expr
->expr
, '"');
12509 } else location
->generate_code_expr_mandatory(expr
);
12510 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12511 // fifth argument: alive flag
12512 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12515 void Value::generate_code_expr_activate(expression_struct
*expr
)
12517 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12518 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12519 FATAL_ERROR("Value::generate_code_expr_activate()");
12520 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12521 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12522 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12523 expr
->expr
= mputc(expr
->expr
, ')');
12526 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12528 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12529 if (v_last
->valuetype
== V_ALTSTEP
) {
12530 // the referred altstep is known
12531 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12532 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12534 // the referred altstep is unknown
12535 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12536 expr
->expr
= mputstr(expr
->expr
,".activate(");
12538 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12539 expr
->expr
= mputc(expr
->expr
, ')');
12542 void Value::generate_code_expr_execute(expression_struct
*expr
)
12544 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12545 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12546 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12547 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12548 if (parlist
->get_nof_pars() > 0) {
12549 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12551 expr
->expr
= mputstr(expr
->expr
, ", ");
12554 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12555 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12556 expr
->expr
= mputc(expr
->expr
, ')');
12557 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12560 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12562 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12563 if (v_last
->valuetype
== V_TESTCASE
) {
12564 // the referred testcase is known
12565 Assignment
*testcase
= v_last
->get_refd_fat();
12566 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12567 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12568 u
.expr
.ap_list2
->generate_code_alias(expr
,
12569 testcase
->get_FormalParList(), 0, false);
12571 // the referred testcase is unknown
12572 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12573 expr
->expr
= mputstr(expr
->expr
,".execute(");
12574 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12576 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12577 expr
->expr
= mputstr(expr
->expr
, ", ");
12579 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12580 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12581 expr
->expr
= mputc(expr
->expr
, ')');
12582 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12585 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12587 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12588 if (last_v
->get_valuetype() == V_FUNCTION
) {
12589 // the referred function is known
12590 Assignment
*function
= last_v
->get_refd_fat();
12591 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12592 function
->get_genname_from_scope(my_scope
).c_str());
12593 u
.invoke
.ap_list
->generate_code_alias(expr
,
12594 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12596 // the referred function is unknown
12597 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12598 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12599 Type
* gov_last
= last_v
->get_expr_governor_last();
12600 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12601 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12603 expr
->expr
= mputc(expr
->expr
, ')');
12606 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12609 // if the referenced value points to an optional value field the
12610 // generated code has to be corrected at the end:
12611 // `fieldid()' => `fieldid()()'
12612 Assignment
*ass
= ref
->get_refd_assignment();
12613 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12614 switch (ass
->get_asstype()) {
12615 case Assignment::A_CONST
:
12616 case Assignment::A_EXT_CONST
:
12617 case Assignment::A_MODULEPAR
:
12618 case Assignment::A_VAR
:
12619 case Assignment::A_FUNCTION_RVAL
:
12620 case Assignment::A_EXT_FUNCTION_RVAL
:
12621 case Assignment::A_PAR_VAL_IN
:
12622 case Assignment::A_PAR_VAL_OUT
:
12623 case Assignment::A_PAR_VAL_INOUT
:
12624 // only these are mapped to value objects
12625 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12626 expr
->expr
= mputstr(expr
->expr
, "()");
12633 void Value::generate_code_expr_encode(expression_struct
*expr
)
12637 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12638 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12639 v1
= templ
->get_specific_value();
12640 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12642 expression_struct expr2
;
12643 Code::init_expr(&expr2
);
12645 bool is_templ
= false;
12646 switch (templ
->get_templatetype()) {
12647 case Template::SPECIFIC_VALUE
:
12648 v1
->generate_code_expr_mandatory(&expr2
);
12651 u
.expr
.ti1
->generate_code(&expr2
);
12656 if (!gov_last
->is_coding_by_function()) {
12657 const string
& tmp_id
= get_temporary_id();
12658 const string
& tmp_buf_id
= get_temporary_id();
12659 const string
& tmp_ref_id
= get_temporary_id();
12660 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12662 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12663 tmp_buf_id
.c_str());
12664 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12665 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12666 expr
->preamble
= mputc (expr
->preamble
, '\n');
12668 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12669 gov_last
->get_genname_typedescriptor(
12670 u
.expr
.ti1
->get_Template()->get_my_scope()
12672 tmp_ref_id
.c_str(),
12674 if (is_templ
) // make a value out of the template, if needed
12675 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12676 expr
->preamble
= mputprintf(expr
->preamble
,
12677 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12678 tmp_ref_id
.c_str(),
12679 gov_last
->get_genname_typedescriptor(
12680 u
.expr
.ti1
->get_Template()->get_my_scope()
12682 tmp_buf_id
.c_str(),
12683 gov_last
->get_coding(true).c_str()
12685 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12686 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12687 tmp_buf_id
.c_str(),
12690 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12691 if (expr2
.postamble
)
12692 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12694 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12695 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12696 is_templ
? ".valueof()" : "");
12697 Code::free_expr(&expr2
);
12700 void Value::generate_code_expr_decode(expression_struct
*expr
)
12702 expression_struct expr1
, expr2
;
12703 Code::init_expr(&expr1
);
12704 Code::init_expr(&expr2
);
12705 u
.expr
.r1
->generate_code(&expr1
);
12706 u
.expr
.r2
->generate_code(&expr2
);
12708 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12709 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12710 get_type_refd_last();
12712 if (expr1
.preamble
)
12713 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12714 if (expr2
.preamble
)
12715 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12717 if (!_type
->is_coding_by_function()) {
12718 const string
& tmp_id
= get_temporary_id();
12719 const string
& buffer_id
= get_temporary_id();
12720 const string
& retval_id
= get_temporary_id();
12721 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12722 field_is_optional(u
.expr
.r2
->get_subrefs());
12724 expr
->preamble
= mputprintf(expr
->preamble
,
12725 "TTCN_Buffer %s(bit2oct(%s));\n"
12727 "TTCN_EncDec::set_error_behavior("
12728 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12729 "TTCN_EncDec::clear_error();\n",
12734 expr
->preamble
= mputprintf(expr
->preamble
,
12735 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12737 optional
? "()" : "",
12738 _type
->get_genname_typedescriptor(
12739 u
.expr
.r2
->get_my_scope()
12742 _type
->get_coding(false).c_str()
12744 expr
->preamble
= mputprintf(expr
->preamble
,
12745 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12746 "case TTCN_EncDec::ET_NONE: {\n"
12748 "OCTETSTRING %s;\n"
12749 "%s.get_string(%s);\n"
12750 "%s = oct2bit(%s);\n"
12753 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12754 "case TTCN_EncDec::ET_LEN_ERR:\n"
12760 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12761 "TTCN_EncDec::EB_DEFAULT);\n"
12762 "TTCN_EncDec::clear_error();\n",
12773 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12775 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12776 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12777 if (expr1
.postamble
)
12778 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12779 if (expr2
.postamble
)
12780 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12781 Code::free_expr(&expr1
);
12782 Code::free_expr(&expr2
);
12785 void Value::generate_code_expr_encvalue_unichar(expression_struct
*expr
)
12789 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12790 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12791 v1
= templ
->get_specific_value();
12792 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12794 expression_struct expr2
;
12795 Code::init_expr(&expr2
);
12797 bool is_templ
= false;
12798 switch (templ
->get_templatetype()) {
12799 case Template::SPECIFIC_VALUE
:
12800 v1
->generate_code_expr_mandatory(&expr2
);
12803 u
.expr
.ti1
->generate_code(&expr2
);
12808 if (!gov_last
->is_coding_by_function()) {
12809 const string
& tmp_id
= get_temporary_id();
12810 const string
& tmp_buf_id
= get_temporary_id();
12811 const string
& tmp_ref_id
= get_temporary_id();
12812 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12814 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12815 tmp_buf_id
.c_str());
12816 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12817 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12818 expr
->preamble
= mputc (expr
->preamble
, '\n');
12820 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12821 gov_last
->get_genname_typedescriptor(
12822 u
.expr
.ti1
->get_Template()->get_my_scope()
12824 tmp_ref_id
.c_str(),
12826 if (is_templ
) // make a value out of the template, if needed
12827 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12828 expr
->preamble
= mputprintf(expr
->preamble
,
12829 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12830 tmp_ref_id
.c_str(),
12831 gov_last
->get_genname_typedescriptor(
12832 u
.expr
.ti1
->get_Template()->get_my_scope()
12834 tmp_buf_id
.c_str(),
12835 gov_last
->get_coding(true).c_str()
12837 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12838 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12839 tmp_buf_id
.c_str(),
12842 const char * v2_code
= NULL
;
12844 v2_code
= generate_code_char_coding_check(expr
, u
.expr
.v2
, "encvalue_unichar");
12846 expr
->expr
= mputprintf(expr
->expr
, "oct2unichar(%s", tmp_id
.c_str());
12848 expr
->expr
= mputprintf(expr
->expr
, ", %s", v2_code
);
12850 expr
->expr
= mputprintf(expr
->expr
, ", \"UTF-8\""); //default
12852 expr
->expr
= mputprintf(expr
->expr
, ")");
12853 if (expr2
.postamble
)
12854 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12856 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12857 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12858 is_templ
? ".valueof()" : "");
12859 Code::free_expr(&expr2
);
12862 void Value::generate_code_expr_decvalue_unichar(expression_struct
*expr
)
12864 expression_struct expr1
, expr2
;
12865 Code::init_expr(&expr1
);
12866 Code::init_expr(&expr2
);
12867 u
.expr
.r1
->generate_code(&expr1
);
12868 u
.expr
.r2
->generate_code(&expr2
);
12870 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12871 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12872 get_type_refd_last();
12874 if (expr1
.preamble
)
12875 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12876 if (expr2
.preamble
)
12877 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12879 if (!_type
->is_coding_by_function()) {
12880 const string
& tmp_id
= get_temporary_id();
12881 const string
& buffer_id
= get_temporary_id();
12882 const string
& retval_id
= get_temporary_id();
12883 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12884 field_is_optional(u
.expr
.r2
->get_subrefs());
12886 const char* v3_code
= NULL
;
12888 v3_code
= generate_code_char_coding_check(expr
, u
.expr
.v3
, "decvalue_unichar");
12890 expr
->preamble
= mputprintf(expr
->preamble
,
12891 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12893 "TTCN_EncDec::set_error_behavior("
12894 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12895 "TTCN_EncDec::clear_error();\n",
12898 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12901 expr
->preamble
= mputprintf(expr
->preamble
,
12902 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12904 optional
? "()" : "",
12905 _type
->get_genname_typedescriptor(
12906 u
.expr
.r2
->get_my_scope()
12909 _type
->get_coding(false).c_str()
12911 expr
->preamble
= mputprintf(expr
->preamble
,
12912 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12913 "case TTCN_EncDec::ET_NONE: {\n"
12915 "OCTETSTRING %s;\n"
12916 "%s.get_string(%s);\n"
12917 "%s = oct2unichar(%s, %s);\n"
12920 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12921 "case TTCN_EncDec::ET_LEN_ERR:\n"
12927 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12928 "TTCN_EncDec::EB_DEFAULT);\n"
12929 "TTCN_EncDec::clear_error();\n",
12936 u
.expr
.v3
? v3_code
: "\"UTF-8\"",
12941 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12943 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12944 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12945 if (expr1
.postamble
)
12946 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12947 if (expr2
.postamble
)
12948 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12949 Code::free_expr(&expr1
);
12950 Code::free_expr(&expr2
);
12953 void Value::generate_code_expr_checkstate(expression_struct
*expr
)
12956 // It is a port if r1 is not null
12957 u
.expr
.r1
->generate_code_const_ref(expr
);
12958 expr
->expr
= mputstr(expr
->expr
, ".");
12960 // it is an any or all port if r1 is null
12961 if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ANY
) {
12962 expr
->expr
= mputstr(expr
->expr
, "PORT::any_");
12963 } else if (u
.expr
.v_optype
== OPTYPE_CHECKSTATE_ALL
) {
12964 expr
->expr
= mputstr(expr
->expr
, "PORT::all_");
12966 FATAL_ERROR("Value::generate_code_expr_checkstate()");
12969 expr
->expr
= mputstr(expr
->expr
, "check_port_state(");
12970 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12971 expr
->expr
= mputstr(expr
->expr
, ")");
12974 void Value::generate_code_expr_hostid(expression_struct
*expr
)
12976 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_host_address(");
12977 if (u
.expr
.v1
) u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12978 else expr
->expr
= mputstr(expr
->expr
, "CHARSTRING(\"Ipv4orIpv6\")");
12979 expr
->expr
= mputstr(expr
->expr
, ")");
12982 char* Value::generate_code_char_coding_check(expression_struct
*expr
, Value
*v
, const char *name
)
12984 expression_struct expr2
;
12985 Code::init_expr(&expr2
);
12986 v
->generate_code_expr_mandatory(&expr2
);
12987 expr
->preamble
= mputprintf(expr
->preamble
,
12988 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12989 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12990 " \"UTF-32BE\" != %s) {\n"
12991 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12992 "}\n", //todo errorbehaviour?
13005 char *Value::generate_code_init_choice(char *str
, const char *name
)
13007 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
13008 // Safe as long as get_name() returns a const string&, not a temporary.
13009 const char *alt_prefix
=
13010 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
13012 if (u
.choice
.alt_value
->needs_temp_ref()) {
13013 const string
& tmp_id
= get_temporary_id();
13014 const char *tmp_id_str
= tmp_id
.c_str();
13015 str
= mputprintf(str
, "{\n"
13016 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
13017 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
13018 alt_prefix
, alt_name
);
13019 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
13020 str
= mputstr(str
, "}\n");
13022 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
13023 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
13024 Free(embedded_name
);
13029 char *Value::generate_code_init_seof(char *str
, const char *name
)
13031 size_t nof_vs
= u
.val_vs
->get_nof_vs();
13033 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
13034 const string
& embedded_type
=
13035 my_governor
->get_ofType()->get_genname_value(my_scope
);
13036 const char *embedded_type_str
= embedded_type
.c_str();
13037 for (size_t i
= 0; i
< nof_vs
; i
++) {
13038 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
13040 if (comp_v
->valuetype
== V_NOTUSED
) continue;
13041 else if (comp_v
->needs_temp_ref()) {
13042 const string
& tmp_id
= get_temporary_id();
13043 const char *tmp_id_str
= tmp_id
.c_str();
13044 str
= mputprintf(str
, "{\n"
13045 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
13046 (unsigned long) i
);
13047 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
13048 str
= mputstr(str
, "}\n");
13050 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
13051 str
= comp_v
->generate_code_init(str
, embedded_name
);
13052 Free(embedded_name
);
13056 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
13061 char *Value::generate_code_init_indexed(char *str
, const char *name
)
13063 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
13065 // Previous values can be truncated. The concept is similar to
13067 Type
*t_last
= my_governor
->get_type_refd_last();
13068 const string
& oftype_name
=
13069 t_last
->get_ofType()->get_genname_value(my_scope
);
13070 const char *oftype_name_str
= oftype_name
.c_str();
13071 for (size_t i
= 0; i
< nof_ivs
; i
++) {
13072 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
13073 const string
& tmp_id_1
= get_temporary_id();
13074 str
= mputstr(str
, "{\n");
13075 Value
*index
= iv
->get_index();
13076 if (index
->get_valuetype() != V_INT
) {
13077 const string
& tmp_id_2
= get_temporary_id();
13078 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
13079 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
13080 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
13081 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
13083 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
13084 tmp_id_1
.c_str(), name
,
13085 (index
->get_val_Int()->t_str()).c_str());
13087 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
13088 str
= mputstr(str
, "}\n");
13090 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
13094 char *Value::generate_code_init_array(char *str
, const char *name
)
13096 size_t nof_vs
= u
.val_vs
->get_nof_vs();
13097 Type
*t_last
= my_governor
->get_type_refd_last();
13098 Int index_offset
= t_last
->get_dimension()->get_offset();
13099 const string
& embedded_type
=
13100 t_last
->get_ofType()->get_genname_value(my_scope
);
13101 const char *embedded_type_str
= embedded_type
.c_str();
13102 for (size_t i
= 0; i
< nof_vs
; i
++) {
13103 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
13104 if (comp_v
->valuetype
== V_NOTUSED
) continue;
13105 else if (comp_v
->needs_temp_ref()) {
13106 const string
& tmp_id
= get_temporary_id();
13107 const char *tmp_id_str
= tmp_id
.c_str();
13108 str
= mputprintf(str
, "{\n"
13109 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
13110 Int2string(index_offset
+ i
).c_str());
13111 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
13112 str
= mputstr(str
, "}\n");
13114 char *embedded_name
= mprintf("%s[%s]", name
,
13115 Int2string(index_offset
+ i
).c_str());
13116 str
= comp_v
->generate_code_init(str
, embedded_name
);
13117 Free(embedded_name
);
13123 char *Value::generate_code_init_se(char *str
, const char *name
)
13125 Type
*type
= my_governor
->get_type_refd_last();
13126 size_t nof_comps
= type
->get_nof_comps();
13127 if (nof_comps
> 0) {
13128 for (size_t i
= 0; i
< nof_comps
; i
++) {
13129 CompField
*cf
= type
->get_comp_byIndex(i
);
13130 const Identifier
& field_id
= cf
->get_name();
13131 const char *field_name
= field_id
.get_name().c_str();
13133 if (u
.val_nvs
->has_nv_withName(field_id
)) {
13134 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
13135 if (field_v
->valuetype
== V_NOTUSED
) continue;
13136 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
13137 } else if (is_asn1()) {
13138 if (cf
->has_default()) {
13139 // handle like a referenced value
13140 Value
*defval
= cf
->get_defval();
13141 if (needs_init_precede(defval
)) {
13142 str
= defval
->generate_code_init(str
,
13143 defval
->get_lhs_name().c_str());
13145 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
13146 defval
->get_genname_own(my_scope
).c_str());
13149 if (!cf
->get_is_optional())
13150 FATAL_ERROR("Value::generate_code_init()");
13157 // the value is not omit
13158 if (field_v
->needs_temp_ref()) {
13159 const string
& tmp_id
= get_temporary_id();
13160 const char *tmp_id_str
= tmp_id
.c_str();
13161 str
= mputprintf(str
, "{\n"
13162 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
13163 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
13165 str
= field_v
->generate_code_init(str
, tmp_id_str
);
13166 str
= mputstr(str
, "}\n");
13168 char *embedded_name
= mprintf("%s.%s()", name
,
13170 if (cf
->get_is_optional() && field_v
->is_compound())
13171 embedded_name
= mputstr(embedded_name
, "()");
13172 str
= field_v
->generate_code_init(str
, embedded_name
);
13173 Free(embedded_name
);
13176 // the value is omit
13177 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
13182 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
13187 char *Value::generate_code_init_refd(char *str
, const char *name
)
13189 Value
*v
= get_value_refd_last();
13191 // the referred value is not available at compile time
13192 // the code generation is based on the reference
13193 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
13194 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
13196 expression_struct expr
;
13197 Code::init_expr(&expr
);
13198 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
13199 u
.ref
.ref
->generate_code_const_ref(&expr
);
13200 str
= Code::merge_free_expr(str
, &expr
);
13203 // the referred value is available at compile time
13204 // the code generation is based on the referred value
13205 if (v
->has_single_expr() &&
13206 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
13207 // simple substitution for in-line values within the same module
13208 str
= mputprintf(str
, "%s = %s;\n", name
,
13209 v
->get_single_expr().c_str());
13211 // use a simple reference to reduce code size
13212 if (needs_init_precede(v
)) {
13213 // the referred value must be initialized first
13214 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
13215 // temporary id should be introduced for the lhs
13216 const string
& tmp_id
= get_temporary_id();
13217 const char *tmp_id_str
= tmp_id
.c_str();
13218 str
= mputprintf(str
, "{\n"
13220 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13221 tmp_id_str
, v
->get_lhs_name().c_str());
13222 str
= v
->generate_code_init(str
, tmp_id_str
);
13223 str
= mputstr(str
, "}\n");
13225 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
13228 str
= mputprintf(str
, "%s = %s;\n", name
,
13229 v
->get_genname_own(my_scope
).c_str());
13235 void Value::generate_json_value(JSON_Tokenizer
& json
,
13236 bool allow_special_float
, /* = true */
13237 bool union_value_list
, /* = false */
13238 Ttcn::JsonOmitCombination
* omit_combo
/* = NULL */)
13240 switch (valuetype
) {
13242 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
13245 Real r
= get_val_Real();
13246 if (r
== REAL_INFINITY
) {
13247 if (allow_special_float
) {
13248 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
13251 else if (r
== -REAL_INFINITY
) {
13252 if (allow_special_float
) {
13253 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
13257 if (allow_special_float
) {
13258 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
13262 // true if decimal representation possible (use %f format)
13263 bool decimal_repr
= (r
== 0.0)
13264 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
13265 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
13266 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
13267 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
13272 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
13278 char* str
= convert_to_json_string(get_val_str().c_str());
13279 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13283 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13284 json
.put_next_token(JSON_TOKEN_STRING
, str
);
13289 json
.put_next_token(JSON_TOKEN_STRING
,
13290 (string('\"') + create_stringRepr() + string('\"')).c_str());
13294 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
13295 if (!u
.val_vs
->is_indexed()) {
13296 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
13297 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
, allow_special_float
,
13298 union_value_list
, omit_combo
);
13302 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
13303 // look for the entry with index equal to i
13304 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
13305 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
13306 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
,
13307 allow_special_float
, union_value_list
, omit_combo
);
13313 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
13317 // omitted fields have 2 possible JSON values (the field is absent, or it's
13318 // present with value 'null'), each combination of omitted values must be
13320 if (omit_combo
== NULL
) {
13321 FATAL_ERROR("Value::generate_json_value - no combo");
13323 size_t len
= get_nof_comps();
13324 // generate the JSON object from the present combination
13325 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13326 for (size_t i
= 0; i
< len
; ++i
) {
13327 Ttcn::JsonOmitCombination::omit_state_t state
= omit_combo
->get_state(this, i
);
13328 if (state
== Ttcn::JsonOmitCombination::OMITTED_ABSENT
) {
13329 // the field is absent, don't insert anything
13332 // use the field's alias, if it has one
13333 const char* alias
= NULL
;
13334 if (my_governor
!= NULL
) {
13335 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13336 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
13337 if (field_attrib
!= NULL
) {
13338 alias
= field_attrib
->alias
;
13341 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13342 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
13343 if (state
== Ttcn::JsonOmitCombination::OMITTED_NULL
) {
13344 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
13347 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
,
13348 allow_special_float
, union_value_list
, omit_combo
);
13351 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13354 bool as_value
= !union_value_list
&& my_governor
!= NULL
&&
13355 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
13356 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
13358 // no 'as value' coding instruction, insert an object with one field
13359 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
13360 // use the field's alias, if it has one
13361 const char* alias
= NULL
;
13362 if (my_governor
!= NULL
) {
13363 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
13364 get_alt_name())->get_type()->get_json_attributes();
13365 if (field_attrib
!= NULL
) {
13366 alias
= field_attrib
->alias
;
13369 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
13370 get_alt_name().get_ttcnname().c_str());
13372 get_alt_value()->generate_json_value(json
, allow_special_float
,
13373 union_value_list
, omit_combo
);
13375 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
13379 Value
* v
= get_value_refd_last();
13381 v
->generate_json_value(json
, allow_special_float
, union_value_list
, omit_combo
);
13386 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
13390 bool Value::explicit_cast_needed(bool forIsValue
)
13392 Value
*v_last
= get_value_refd_last();
13393 if (v_last
!= this) {
13394 // this is a foldable referenced value
13395 // if the reference points to an imported or compound value the code
13396 // generation will be based on the reference so cast is not needed
13397 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
13398 || !v_last
->has_single_expr()) return false;
13399 } else if (v_last
->valuetype
== V_REFD
) {
13400 // this is an unfoldable reference (v_last==this)
13401 // explicit cast is needed only for string element references
13402 if (forIsValue
) return false;
13403 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
13404 return t_subrefs
&& t_subrefs
->refers_to_string_element();
13406 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
13407 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
13408 switch (t_governor
->get_typetype()) {
13412 case Type::T_INT_A
:
13414 case Type::T_ENUM_A
:
13415 case Type::T_ENUM_T
:
13416 case Type::T_VERDICT
:
13417 case Type::T_COMPONENT
:
13418 // these are mapped to built-in C/C++ types
13420 case Type::T_SEQ_A
:
13421 case Type::T_SEQ_T
:
13422 case Type::T_SET_A
:
13423 case Type::T_SET_T
:
13424 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13425 return t_governor
->get_nof_comps() == 0;
13426 case Type::T_SEQOF
:
13427 case Type::T_SETOF
:
13428 // the C++ equivalent of value {} is ambiguous
13431 case Type::T_FUNCTION
:
13432 case Type::T_ALTSTEP
:
13433 case Type::T_TESTCASE
:
13440 bool Value::has_single_expr()
13442 if (get_needs_conversion()) return false;
13443 switch (valuetype
) {
13445 return has_single_expr_expr();
13448 // a union or array value cannot be represented as an in-line expression
13452 // only an empty record/set of value can be represented as an in-line
13454 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
13455 else return u
.val_vs
->get_nof_ivs() == 0;
13458 // only a value for an empty record/set type can be represented as an
13459 // in-line expression
13460 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
13461 Type
*type
= my_governor
->get_type_refd_last();
13462 return type
->get_nof_comps() == 0; }
13464 Value
*v_last
= get_value_refd_last();
13465 // If the above call hit an error and set_valuetype(V_ERROR),
13466 // then u.ref.ref has been freed. Avoid the segfault.
13467 if (valuetype
== V_ERROR
)
13469 if (v_last
!= this && v_last
->has_single_expr() &&
13470 v_last
->my_scope
->get_scope_mod_gen() ==
13471 my_scope
->get_scope_mod_gen()) return true;
13472 else return u
.ref
.ref
->has_single_expr(); }
13474 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
13478 case V_UNDEF_LOWERID
:
13479 case V_UNDEF_BLOCK
:
13481 // these values cannot occur during code generation
13482 FATAL_ERROR("Value::has_single_expr()");
13484 return u
.val_Int
->is_native_fit();
13486 // should only happen when generating code for an unbound record/set value
13489 // other value types (literal values) do not need temporary reference
13494 string
Value::get_single_expr()
13496 switch (valuetype
) {
13498 return string("ASN_NULL_VALUE");
13500 return string(u
.val_bool
? "TRUE" : "FALSE");
13502 if (u
.val_Int
->is_native_fit()) { // Be sure.
13503 return u
.val_Int
->t_str();
13505 // get_single_expr may be called only if has_single_expr() is true.
13506 // The only exception is V_INT, where get_single_expr may be called
13507 // even if is_native_fit (which is used to implement has_single_expr)
13509 string
ret_val('"');
13510 ret_val
+= u
.val_Int
->t_str();
13515 return Real2code(u
.val_Real
);
13517 return get_single_expr_enum();
13519 return get_my_scope()->get_scope_mod_gen()
13520 ->add_bitstring_literal(*u
.str
.val_str
);
13522 return get_my_scope()->get_scope_mod_gen()
13523 ->add_hexstring_literal(*u
.str
.val_str
);
13525 return get_my_scope()->get_scope_mod_gen()
13526 ->add_octetstring_literal(*u
.str
.val_str
);
13528 return get_my_scope()->get_scope_mod_gen()
13529 ->add_charstring_literal(*u
.str
.val_str
);
13531 if (u
.ustr
.convert_str
) {
13532 set_valuetype(V_CSTR
);
13533 return get_my_scope()->get_scope_mod_gen()
13534 ->add_charstring_literal(*u
.str
.val_str
);
13536 return get_my_scope()->get_scope_mod_gen()
13537 ->add_ustring_literal(*u
.ustr
.val_ustr
);
13539 return get_single_expr_iso2022str();
13542 vector
<string
> comps
;
13543 bool is_constant
= get_oid_comps(comps
);
13544 size_t nof_comps
= comps
.size();
13546 for (size_t i
= 0; i
< nof_comps
; i
++) {
13547 if (i
> 0) oi_str
+= ", ";
13548 oi_str
+= *(comps
[i
]);
13550 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
13553 // the objid only contains constants
13554 // => create a literal and return its name
13555 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
13557 // the objid contains at least one variable
13558 // => append the number of components before the component values in the string and return it
13559 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
13562 if (u
.val_vs
->get_nof_vs() > 0)
13563 FATAL_ERROR("Value::get_single_expr()");
13564 return string("NULL_VALUE");
13567 if (u
.val_nvs
->get_nof_nvs() > 0)
13568 FATAL_ERROR("Value::get_single_expr()");
13569 return string("NULL_VALUE");
13571 Value
*v_last
= get_value_refd_last();
13572 if (v_last
!= this && v_last
->has_single_expr() &&
13573 v_last
->my_scope
->get_scope_mod_gen() ==
13574 my_scope
->get_scope_mod_gen()) {
13575 // the reference points to another single value in the same module
13576 return v_last
->get_single_expr();
13578 // convert the reference to a single expression
13579 expression_struct expr
;
13580 Code::init_expr(&expr
);
13581 u
.ref
.ref
->generate_code_const_ref(&expr
);
13582 if (expr
.preamble
|| expr
.postamble
)
13583 FATAL_ERROR("Value::get_single_expr()");
13584 string
ret_val(expr
.expr
);
13585 Code::free_expr(&expr
);
13589 return string("OMIT_VALUE");
13591 switch (u
.verdict
) {
13593 return string("NONE");
13595 return string("PASS");
13596 case Verdict_INCONC
:
13597 return string("INCONC");
13599 return string("FAIL");
13600 case Verdict_ERROR
:
13601 return string("ERROR");
13603 FATAL_ERROR("Value::get_single_expr()");
13606 case V_DEFAULT_NULL
:
13607 return string("NULL_COMPREF");
13609 string
ret_val('(');
13610 ret_val
+= my_governor
->get_genname_value(my_scope
);
13611 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13615 expression_struct expr
;
13616 Code::init_expr(&expr
);
13617 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13618 else generate_code_expr_invoke(&expr
);
13619 if (expr
.preamble
|| expr
.postamble
)
13620 FATAL_ERROR("Value::get_single_expr()");
13621 string
ret_val(expr
.expr
);
13622 Code::free_expr(&expr
);
13626 case MACRO_TESTCASEID
:
13627 return string("TTCN_Runtime::get_testcase_id_macro()");
13629 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13635 return get_single_expr_fat();
13637 FATAL_ERROR("Value::get_single_expr()");
13642 bool Value::has_single_expr_expr()
13644 switch (u
.expr
.v_optype
) {
13645 case OPTYPE_RND
: // -
13646 case OPTYPE_COMP_NULL
:
13647 case OPTYPE_COMP_MTC
:
13648 case OPTYPE_COMP_SYSTEM
:
13649 case OPTYPE_COMP_SELF
:
13650 case OPTYPE_COMP_RUNNING_ANY
:
13651 case OPTYPE_COMP_RUNNING_ALL
:
13652 case OPTYPE_COMP_ALIVE_ANY
:
13653 case OPTYPE_COMP_ALIVE_ALL
:
13654 case OPTYPE_TMR_RUNNING_ANY
:
13655 case OPTYPE_GETVERDICT
:
13656 case OPTYPE_TESTCASENAME
:
13657 case OPTYPE_PROF_RUNNING
:
13658 case OPTYPE_CHECKSTATE_ANY
:
13659 case OPTYPE_CHECKSTATE_ALL
:
13660 case OPTYPE_HOSTID
:
13662 case OPTYPE_ENCODE
:
13663 case OPTYPE_DECODE
:
13664 case OPTYPE_ISBOUND
:
13665 case OPTYPE_ISPRESENT
:
13666 case OPTYPE_TTCN2STRING
:
13667 case OPTYPE_ENCVALUE_UNICHAR
:
13668 case OPTYPE_DECVALUE_UNICHAR
:
13670 case OPTYPE_UNARYPLUS
: // v1
13671 case OPTYPE_UNARYMINUS
:
13674 case OPTYPE_BIT2HEX
:
13675 case OPTYPE_BIT2INT
:
13676 case OPTYPE_BIT2OCT
:
13677 case OPTYPE_BIT2STR
:
13678 case OPTYPE_CHAR2INT
:
13679 case OPTYPE_CHAR2OCT
:
13680 case OPTYPE_FLOAT2INT
:
13681 case OPTYPE_FLOAT2STR
:
13682 case OPTYPE_HEX2BIT
:
13683 case OPTYPE_HEX2INT
:
13684 case OPTYPE_HEX2OCT
:
13685 case OPTYPE_HEX2STR
:
13686 case OPTYPE_INT2CHAR
:
13687 case OPTYPE_INT2FLOAT
:
13688 case OPTYPE_INT2STR
:
13689 case OPTYPE_INT2UNICHAR
:
13690 case OPTYPE_OCT2BIT
:
13691 case OPTYPE_OCT2CHAR
:
13692 case OPTYPE_OCT2HEX
:
13693 case OPTYPE_OCT2INT
:
13694 case OPTYPE_OCT2STR
:
13695 case OPTYPE_STR2BIT
:
13696 case OPTYPE_STR2FLOAT
:
13697 case OPTYPE_STR2HEX
:
13698 case OPTYPE_STR2INT
:
13699 case OPTYPE_STR2OCT
:
13700 case OPTYPE_UNICHAR2INT
:
13701 case OPTYPE_UNICHAR2CHAR
:
13702 case OPTYPE_ENUM2INT
:
13703 case OPTYPE_RNDWITHVAL
:
13704 case OPTYPE_ISCHOSEN_V
: // v1 i2
13705 case OPTYPE_COMP_RUNNING
:
13706 case OPTYPE_COMP_ALIVE
:
13707 case OPTYPE_GET_STRINGENCODING
:
13708 case OPTYPE_REMOVE_BOM
:
13709 case OPTYPE_DECODE_BASE64
:
13710 return u
.expr
.v1
->has_single_expr();
13711 case OPTYPE_ISCHOSEN_T
: // t1 i2
13712 return u
.expr
.t1
->has_single_expr();
13713 case OPTYPE_ADD
: // v1 v2
13714 case OPTYPE_SUBTRACT
:
13715 case OPTYPE_MULTIPLY
:
13716 case OPTYPE_DIVIDE
:
13719 case OPTYPE_CONCAT
:
13734 case OPTYPE_INT2BIT
:
13735 case OPTYPE_INT2HEX
:
13736 case OPTYPE_INT2OCT
:
13737 return u
.expr
.v1
->has_single_expr() &&
13738 u
.expr
.v2
->has_single_expr();
13739 case OPTYPE_UNICHAR2OCT
:
13740 case OPTYPE_OCT2UNICHAR
:
13741 case OPTYPE_ENCODE_BASE64
:
13742 return u
.expr
.v1
->has_single_expr() &&
13743 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13746 return u
.expr
.v1
->has_single_expr() &&
13747 u
.expr
.v2
->has_single_expr() &&
13748 !u
.expr
.v2
->needs_short_circuit();
13749 case OPTYPE_SUBSTR
:
13750 return u
.expr
.ti1
->has_single_expr() &&
13751 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13752 case OPTYPE_REGEXP
:
13753 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13754 u
.expr
.v3
->has_single_expr();
13755 case OPTYPE_DECOMP
: // v1 v2 v3
13756 return u
.expr
.v1
->has_single_expr() &&
13757 u
.expr
.v2
->has_single_expr() &&
13758 u
.expr
.v3
->has_single_expr();
13759 case OPTYPE_REPLACE
:
13760 return u
.expr
.ti1
->has_single_expr() &&
13761 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13762 u
.expr
.ti4
->has_single_expr();
13763 case OPTYPE_ISVALUE
: // ti1
13764 case OPTYPE_LENGTHOF
: // ti1
13765 case OPTYPE_SIZEOF
: // ti1
13766 case OPTYPE_VALUEOF
: // ti1
13767 return u
.expr
.ti1
->has_single_expr();
13768 case OPTYPE_LOG2STR
:
13769 case OPTYPE_ANY2UNISTR
:
13770 return u
.expr
.logargs
->has_single_expr();
13771 case OPTYPE_MATCH
: // v1 t2
13772 return u
.expr
.v1
->has_single_expr() &&
13773 u
.expr
.t2
->has_single_expr();
13774 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13775 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13776 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13777 case OPTYPE_TMR_READ
: // r1
13778 case OPTYPE_TMR_RUNNING
:
13779 case OPTYPE_ACTIVATE
:
13780 return u
.expr
.r1
->has_single_expr();
13781 case OPTYPE_EXECUTE
: // r1 [v2]
13782 return u
.expr
.r1
->has_single_expr() &&
13783 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13784 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13785 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13786 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13787 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13788 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13790 FATAL_ERROR("Value::has_single_expr_expr()");
13794 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13796 if (!v
->has_single_expr()) return false;
13797 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13798 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13802 string
Value::get_single_expr_enum()
13804 string
ret_val(my_governor
->get_genname_value(my_scope
));
13806 ret_val
+= u
.val_id
->get_name();
13810 string
Value::get_single_expr_iso2022str()
13813 Type
*type
= get_my_governor()->get_type_refd_last();
13814 switch (type
->get_typetype()) {
13815 case Type::T_TELETEXSTRING
:
13816 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13818 case Type::T_VIDEOTEXSTRING
:
13819 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13821 case Type::T_GRAPHICSTRING
:
13822 case Type::T_OBJECTDESCRIPTOR
:
13823 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13825 case Type::T_GENERALSTRING
:
13826 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13829 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13832 string
*ostr
= char2oct(*u
.str
.val_str
);
13833 ret_val
+= get_my_scope()->get_scope_mod_gen()
13834 ->add_octetstring_literal(*ostr
);
13840 string
Value::get_single_expr_fat()
13842 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13843 // the ampersand operator is not really necessary to obtain the function
13844 // pointer, but some older versions of GCC cannot instantiate the
13845 // appropriate operator=() member of class OPTIONAL when necessary
13846 // if only the function name is given
13847 string
ret_val('&');
13848 switch (valuetype
) {
13850 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13853 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13854 ret_val
+= "_instance";
13857 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13860 FATAL_ERROR("Value::get_single_expr_fat()");
13865 bool Value::is_compound()
13867 switch (valuetype
) {
13880 bool Value::needs_temp_ref()
13882 switch (valuetype
) {
13885 if (!is_indexed()) {
13886 // Temporary reference is needed if the value has at least one real
13887 // element (i.e. it is not empty or contains only not used symbols).
13888 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13889 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13892 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13893 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13894 ->valuetype
!= V_NOTUSED
)
13900 size_t nof_real_vs
= 0;
13901 if (!is_indexed()) {
13902 // Temporary reference is needed if the array value has at least two
13903 // real elements (excluding not used symbols).
13904 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13905 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13907 if (nof_real_vs
> 1) return true;
13911 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13912 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13913 ->valuetype
!= V_NOTUSED
) {
13915 if (nof_real_vs
> 1) return true;
13923 // it depends on the type since fields with omit or default value
13924 // may not be present
13925 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13927 // incomplete values are allowed in TTCN-3
13928 // we should check the number of value components
13929 return u
.val_nvs
->get_nof_nvs() > 1;
13934 case V_UNDEF_LOWERID
:
13935 case V_UNDEF_BLOCK
:
13937 // these values cannot occur during code generation
13938 FATAL_ERROR("Value::needs_temp_ref()");
13940 return !u
.val_Int
->is_native();
13942 // other value types (literal values) do not need temporary reference
13947 bool Value::needs_short_circuit()
13949 switch (valuetype
) {
13957 // sub-expressions should be evaluated only if necessary
13960 FATAL_ERROR("Value::needs_short_circuit()");
13962 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13963 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13964 switch (t_ass
->get_asstype()) {
13965 case Assignment::A_FUNCTION_RVAL
:
13966 case Assignment::A_EXT_FUNCTION_RVAL
:
13967 // avoid unnecessary call of a function
13969 case Assignment::A_CONST
:
13970 case Assignment::A_EXT_CONST
:
13971 case Assignment::A_MODULEPAR
:
13972 case Assignment::A_VAR
:
13973 case Assignment::A_PAR_VAL_IN
:
13974 case Assignment::A_PAR_VAL_OUT
:
13975 case Assignment::A_PAR_VAL_INOUT
:
13976 // depends on field/array sub-references, which is examined below
13979 FATAL_ERROR("Value::needs_short_circuit()");
13981 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13983 // the evaluation of the reference does not have side effects
13984 // (i.e. false shall be returned) only if all sub-references point to
13985 // mandatory fields of record/set types, and neither sub-reference points
13986 // to a field of a union type
13987 Type
*t_type
= t_ass
->get_Type();
13988 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13989 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13990 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13991 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13992 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13993 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13994 t_cf
->get_is_optional()) return true;
13995 t_type
= t_cf
->get_type();
13996 } else return true;
14002 void Value::dump(unsigned level
) const
14004 switch (valuetype
) {
14028 case V_DEFAULT_NULL
:
14036 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
14040 DEBUG(level
, "Value: reference");
14041 u
.ref
.ref
->dump(level
+ 1);
14043 case V_UNDEF_LOWERID
:
14044 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
14046 case V_UNDEF_BLOCK
:
14047 DEBUG(level
, "Value: {block}");
14050 DEBUG(level
, "Value: null");
14053 DEBUG(level
, "Value: invoke");
14054 u
.invoke
.v
->dump(level
+ 1);
14055 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
14056 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
14059 DEBUG(level
, "Value: unknown type: %d", valuetype
);
14063 void Value::add_string_element(size_t index
, Value
*v_element
,
14064 map
<size_t, Value
>*& string_elements
)
14066 v_element
->set_my_scope(get_my_scope());
14067 v_element
->set_my_governor(get_my_governor());
14068 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
14069 v_element
->set_location(*this);
14070 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
14071 string_elements
->add(index
, v_element
);
14074 ///////////////////////////////////////////////////////////////////////////////
14075 // class LazyParamData
14077 int LazyParamData::depth
= 0;
14078 bool LazyParamData::used_as_lvalue
= false;
14079 vector
<string
>* LazyParamData::type_vec
= NULL
;
14080 vector
<string
>* LazyParamData::refd_vec
= NULL
;
14082 void LazyParamData::init(bool p_used_as_lvalue
) {
14083 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
14085 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
14086 used_as_lvalue
= p_used_as_lvalue
;
14087 type_vec
= new vector
<string
>;
14088 refd_vec
= new vector
<string
>;
14093 void LazyParamData::clean() {
14094 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
14095 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
14098 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
14103 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
14111 bool LazyParamData::in_lazy() {
14112 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
14116 // returns a temporary id instead of the C++ reference to a definition
14117 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
14118 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
14119 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
14120 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
14121 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
14122 // store the type of the assignment
14123 string
* type_str
= new string
;
14124 switch (ass
->get_asstype()) {
14125 case Assignment::A_MODULEPAR_TEMP
:
14126 case Assignment::A_TEMPLATE
:
14127 case Assignment::A_VAR_TEMPLATE
:
14128 case Assignment::A_PAR_TEMPL_IN
:
14129 case Assignment::A_PAR_TEMPL_OUT
:
14130 case Assignment::A_PAR_TEMPL_INOUT
:
14131 *type_str
= ass
->get_Type()->get_genname_template(scope
);
14134 *type_str
= ass
->get_Type()->get_genname_value(scope
);
14136 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
14137 bool refd_ass_is_lazy_fpar
= false;
14138 switch (ass
->get_asstype()) {
14139 case Assignment::A_PAR_VAL
:
14140 case Assignment::A_PAR_VAL_IN
:
14141 case Assignment::A_PAR_TEMPL_IN
:
14142 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
14143 if (refd_ass_is_lazy_fpar
) {
14144 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
14150 // add the "const" part if the referenced assignment is a constant thing
14151 if (!refd_ass_is_lazy_fpar
) {
14152 switch (ass
->get_asstype()) {
14153 case Assignment::A_CONST
:
14154 case Assignment::A_OC
:
14155 case Assignment::A_OBJECT
:
14156 case Assignment::A_OS
:
14157 case Assignment::A_VS
:
14158 case Assignment::A_EXT_CONST
:
14159 case Assignment::A_MODULEPAR
:
14160 case Assignment::A_MODULEPAR_TEMP
:
14161 case Assignment::A_TEMPLATE
:
14162 case Assignment::A_PAR_VAL
:
14163 case Assignment::A_PAR_VAL_IN
:
14164 case Assignment::A_PAR_TEMPL_IN
:
14165 *type_str
= string("const ") + *type_str
;
14173 type_vec
->add(type_str
);
14174 // store the C++ reference string
14175 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
14176 if (refd_ass_is_lazy_fpar
) {
14177 Type
* refd_ass_type
= ass
->get_Type();
14178 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
);
14179 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
14181 return get_member_name(refd_vec
->size()-1);
14185 string
LazyParamData::get_member_name(size_t idx
) {
14186 return string("lpm_") + Int2string(idx
);
14189 string
LazyParamData::get_constr_param_name(size_t idx
) {
14190 return string("lpp_") + Int2string(idx
);
14193 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
14194 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14195 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
14196 const string
& tmp_id
= val
->get_temporary_id();
14197 const char *tmp_id_str
= tmp_id
.c_str();
14198 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14199 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
14201 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14203 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14205 val
->generate_code_expr(expr
);
14209 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
14210 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14211 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
14212 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
14213 const char *tmp_id_str
= tmp_id
.c_str();
14214 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
14215 temp
->get_Template()->get_my_governor()
14216 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
14217 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
14218 tmp_id_str
, temp
->get_Template());
14219 // Not incorporated into gen_conv_code() yet.
14220 if (gen_restriction_check
!= TR_NONE
)
14221 expr
->preamble
= Template::generate_restriction_check_code(
14222 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
14223 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
14224 } else temp
->generate_code(expr
, gen_restriction_check
);
14227 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14228 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14230 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14231 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14232 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14233 expression_struct value_expr
;
14234 Code::init_expr(&value_expr
);
14235 generate_code_for_value(&value_expr
, value
, scope
);
14236 // the id of the instance of Lazy_Param which will be used as the actual parameter
14237 const string
& lazy_param_id
= value
->get_temporary_id();
14238 if (value_expr
.preamble
) {
14239 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
14241 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14242 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14243 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
14244 Code::free_expr(&value_expr
);
14245 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14248 // only if the formal parameter is *not* used as lvalue
14249 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
14250 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
14252 bool refd_ass_is_lazy_fpar
= false;
14253 switch (refd_ass
->get_asstype()) {
14254 case Assignment::A_PAR_VAL
:
14255 case Assignment::A_PAR_VAL_IN
:
14256 case Assignment::A_PAR_TEMPL_IN
:
14257 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14262 if (refd_ass_is_lazy_fpar
) {
14263 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14268 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14269 expression_struct value_expr
;
14270 Code::init_expr(&value_expr
);
14271 generate_code_for_value(&value_expr
, value
, scope
);
14272 // the id of the instance of Lazy_Param which will be used as the actual parameter
14273 string lazy_param_id
= value
->get_temporary_id();
14274 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
14275 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
14278 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
14279 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
14281 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14282 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14283 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14284 expression_struct tmpl_expr
;
14285 Code::init_expr(&tmpl_expr
);
14286 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14287 // the id of the instance of Lazy_Param which will be used as the actual parameter
14288 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
14289 if (tmpl_expr
.preamble
) {
14290 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
14292 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14293 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14294 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
14295 Code::free_expr(&tmpl_expr
);
14296 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14299 // only if the formal parameter is *not* used as lvalue
14300 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
14301 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
14303 bool refd_ass_is_lazy_fpar
= false;
14304 switch (refd_ass
->get_asstype()) {
14305 case Assignment::A_PAR_VAL
:
14306 case Assignment::A_PAR_VAL_IN
:
14307 case Assignment::A_PAR_TEMPL_IN
:
14308 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
14313 if (refd_ass_is_lazy_fpar
) {
14314 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
14319 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14320 expression_struct tmpl_expr
;
14321 Code::init_expr(&tmpl_expr
);
14322 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
14323 // the id of the instance of Lazy_Param which will be used as the actual parameter
14324 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
14325 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
14326 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
14329 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
14330 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
14331 if (type_vec
->size()>0) {
14332 // private members of the local class will be const references to the objects referenced by the expression
14333 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14334 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
14336 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
14337 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
14338 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14339 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14340 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
14342 expr
->preamble
= mputstr(expr
->preamble
, "): ");
14343 for (size_t i
=0; i
<type_vec
->size(); i
++) {
14344 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14345 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
14347 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
14348 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
14350 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
14351 // use the temporary expr structure to fill the body of the eval_expr() function
14352 if (param_expr
.preamble
) {
14353 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
14355 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
14356 if (param_expr
.postamble
) {
14357 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
14359 Code::free_expr(¶m_expr
);
14360 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
14361 "};\n" // end of local class definition
14363 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
14364 if (type_vec
->size()>0) {
14365 expr
->preamble
= mputc(expr
->preamble
, '(');
14366 // paramteres of the constructor are references to the objects used in the expression
14367 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
14368 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
14369 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
14371 expr
->preamble
= mputc(expr
->preamble
, ')');
14373 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
14374 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14375 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
14378 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
14379 expression_struct ref_expr
;
14380 Code::init_expr(&ref_expr
);
14381 ref
->generate_code(&ref_expr
);
14382 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
14383 if (ref_expr
.preamble
) {
14384 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
14386 Assignment
* ass
= ref
->get_refd_assignment();
14387 // determine C++ type of the assignment
14389 switch (ass
->get_asstype()) {
14390 case Assignment::A_MODULEPAR_TEMP
:
14391 case Assignment::A_TEMPLATE
:
14392 case Assignment::A_VAR_TEMPLATE
:
14393 case Assignment::A_PAR_TEMPL_IN
:
14394 case Assignment::A_PAR_TEMPL_OUT
:
14395 case Assignment::A_PAR_TEMPL_INOUT
:
14396 type_str
= ass
->get_Type()->get_genname_template(scope
);
14399 type_str
= ass
->get_Type()->get_genname_value(scope
);
14401 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14402 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
14403 if (ref_expr
.postamble
) {
14404 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
14406 Code::free_expr(&ref_expr
);
14407 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14410 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
14411 const string
& lazy_param_id
= value
->get_temporary_id();
14412 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14413 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
14414 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
14415 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14418 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
14419 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
14420 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14421 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
14422 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
14423 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
14426 } // namespace Common