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
24 * Szabo, Janos Zoltan – initial implementation
27 * Zalanyi, Balazs Andor
29 ******************************************************************************/
30 #include "../common/dbgnew.hh"
32 #include "Identifier.hh"
33 #include "Valuestuff.hh"
34 #include "PredefFunc.hh"
35 #include "CompField.hh"
36 #include "CompType.hh"
37 #include "EnumItem.hh"
38 #include "TypeCompat.hh"
39 #include "asn1/Block.hh"
40 #include "asn1/TokenBuf.hh"
46 #include "ttcn3/TtcnTemplate.hh"
47 #include "ttcn3/ArrayDimensions.hh"
49 #include "../common/pattern.hh"
51 #include "ttcn3/PatternString.hh"
52 #include "ttcn3/Statement.hh"
54 #include "ttcn3/Attributes.hh"
55 #include "../common/JSON_Tokenizer.hh"
56 #include "ttcn3/Ttcn2Json.hh"
64 static void clean_up_string_elements(map
<size_t, Value
>*& string_elements
)
66 if (string_elements
) {
67 for (size_t i
= 0; i
< string_elements
->size(); i
++)
68 delete string_elements
->get_nth_elem(i
);
69 string_elements
->clear();
70 delete string_elements
;
75 // =================================
77 // =================================
79 Value::Value(const Value
& p
)
80 : GovernedSimple(p
), valuetype(p
.valuetype
), my_governor(0)
92 u
.val_bool
=p
.u
.val_bool
;
95 u
.val_Int
=new int_val_t(*(p
.u
.val_Int
));
100 u
.val_id
=p
.u
.val_id
->clone();
103 u
.val_Real
=p
.u
.val_Real
;
110 set_val_str(new string(*p
.u
.str
.val_str
));
113 set_val_ustr(new ustring(*p
.u
.ustr
.val_ustr
));
114 u
.ustr
.convert_str
= p
.u
.ustr
.convert_str
;
117 u
.char_syms
= p
.u
.char_syms
->clone();
121 u
.oid_comps
=new vector
<OID_comp
>;
122 for(size_t i
=0; i
<p
.u
.oid_comps
->size(); i
++)
123 add_oid_comp((*p
.u
.oid_comps
)[i
]->clone());
126 u
.choice
.alt_name
=p
.u
.choice
.alt_name
->clone();
127 u
.choice
.alt_value
=p
.u
.choice
.alt_value
->clone();
132 u
.val_vs
=p
.u
.val_vs
->clone();
136 u
.val_nvs
=p
.u
.val_nvs
->clone();
139 u
.ref
.ref
=p
.u
.ref
.ref
->clone();
143 for(size_t i
=0; i
<p
.u
.ids
->size(); i
++) {
144 Identifier
*id
= p
.u
.ids
->get_nth_elem(i
);
145 u
.ids
->add(id
->get_name(), id
->clone());
149 u
.block
=p
.u
.block
->clone();
152 u
.verdict
=p
.u
.verdict
;
155 u
.expr
.v_optype
= p
.u
.expr
.v_optype
;
156 u
.expr
.state
= EXPR_NOT_CHECKED
;
157 switch(u
.expr
.v_optype
) {
158 case OPTYPE_RND
: // -
159 case OPTYPE_COMP_NULL
:
160 case OPTYPE_COMP_MTC
:
161 case OPTYPE_COMP_SYSTEM
:
162 case OPTYPE_COMP_SELF
:
163 case OPTYPE_COMP_RUNNING_ANY
:
164 case OPTYPE_COMP_RUNNING_ALL
:
165 case OPTYPE_COMP_ALIVE_ANY
:
166 case OPTYPE_COMP_ALIVE_ALL
:
167 case OPTYPE_TMR_RUNNING_ANY
:
168 case OPTYPE_GETVERDICT
:
169 case OPTYPE_TESTCASENAME
:
170 case OPTYPE_PROF_RUNNING
:
172 case OPTYPE_UNARYPLUS
: // v1
173 case OPTYPE_UNARYMINUS
:
180 case OPTYPE_CHAR2INT
:
181 case OPTYPE_CHAR2OCT
:
182 case OPTYPE_COMP_RUNNING
:
183 case OPTYPE_COMP_ALIVE
:
184 case OPTYPE_FLOAT2INT
:
185 case OPTYPE_FLOAT2STR
:
190 case OPTYPE_INT2CHAR
:
191 case OPTYPE_INT2FLOAT
:
193 case OPTYPE_INT2UNICHAR
:
195 case OPTYPE_OCT2CHAR
:
200 case OPTYPE_STR2FLOAT
:
204 case OPTYPE_UNICHAR2INT
:
205 case OPTYPE_UNICHAR2CHAR
:
206 case OPTYPE_ENUM2INT
:
207 case OPTYPE_RNDWITHVAL
:
208 case OPTYPE_GET_STRINGENCODING
:
209 case OPTYPE_DECODE_BASE64
:
210 case OPTYPE_REMOVE_BOM
:
211 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
213 case OPTYPE_ADD
: // v1 v2
214 case OPTYPE_SUBTRACT
:
215 case OPTYPE_MULTIPLY
:
239 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
240 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
242 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
243 case OPTYPE_OCT2UNICHAR
:
244 case OPTYPE_ENCODE_BASE64
:
245 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
246 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
249 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
250 u
.expr
.r2
=p
.u
.expr
.r2
->clone();
253 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
254 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
255 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
258 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
259 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
260 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
262 case OPTYPE_DECOMP
: // v1 v2 v3
263 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
264 u
.expr
.v2
=p
.u
.expr
.v2
->clone();
265 u
.expr
.v3
=p
.u
.expr
.v3
->clone();
268 u
.expr
.ti1
= p
.u
.expr
.ti1
->clone();
269 u
.expr
.v2
= p
.u
.expr
.v2
->clone();
270 u
.expr
.v3
= p
.u
.expr
.v3
->clone();
271 u
.expr
.ti4
= p
.u
.expr
.ti4
->clone();
273 case OPTYPE_LENGTHOF
: // ti1
274 case OPTYPE_SIZEOF
: // ti1
275 case OPTYPE_VALUEOF
: // ti1
277 case OPTYPE_ISPRESENT
:
278 case OPTYPE_TTCN2STRING
:
279 u
.expr
.ti1
=p
.u
.expr
.ti1
->clone();
281 case OPTYPE_UNDEF_RUNNING
:
282 case OPTYPE_TMR_READ
:
283 case OPTYPE_TMR_RUNNING
:
284 case OPTYPE_ACTIVATE
:
285 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
287 case OPTYPE_EXECUTE
: // r1 [v2]
288 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
289 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
291 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
292 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
293 u
.expr
.v2
=p
.u
.expr
.v2
?p
.u
.expr
.v2
->clone():0;
294 u
.expr
.v3
=p
.u
.expr
.v3
?p
.u
.expr
.v3
->clone():0;
295 u
.expr
.b4
= p
.u
.expr
.b4
;
297 case OPTYPE_MATCH
: // v1 t2
298 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
299 u
.expr
.t2
=p
.u
.expr
.t2
->clone();
301 case OPTYPE_ISCHOSEN
: // r1 i2
302 u
.expr
.r1
=p
.u
.expr
.r1
->clone();
303 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
305 case OPTYPE_ISCHOSEN_V
: // v1 i2
306 u
.expr
.v1
=p
.u
.expr
.v1
->clone();
307 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
309 case OPTYPE_ISCHOSEN_T
: // t1 i2
310 u
.expr
.t1
=p
.u
.expr
.t1
->clone();
311 u
.expr
.i2
=p
.u
.expr
.i2
->clone();
313 case OPTYPE_ACTIVATE_REFD
:
314 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
315 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
316 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
318 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
319 u
.expr
.state
= EXPR_CHECKED
;
322 case OPTYPE_EXECUTE_REFD
:
323 u
.expr
.v1
= p
.u
.expr
.v1
->clone();
324 if(p
.u
.expr
.state
!=EXPR_CHECKED
)
325 u
.expr
.t_list2
= p
.u
.expr
.t_list2
->clone();
327 u
.expr
.ap_list2
= p
.u
.expr
.ap_list2
->clone();
328 u
.expr
.state
= EXPR_CHECKED
;
330 u
.expr
.v3
= p
.u
.expr
.v3
? p
.u
.expr
.v3
->clone() : 0;
333 u
.expr
.logargs
= p
.u
.expr
.logargs
->clone();
336 FATAL_ERROR("Value::Value()");
345 u
.refd_fat
= p
.u
.refd_fat
;
348 u
.invoke
.v
= p
.u
.invoke
.v
->clone();
349 u
.invoke
.t_list
= p
.u
.invoke
.t_list
?p
.u
.invoke
.t_list
->clone():0;
350 u
.invoke
.ap_list
= p
.u
.invoke
.ap_list
?p
.u
.invoke
.ap_list
->clone():0;
353 u
.refered
= p
.u
.refered
->clone();
356 FATAL_ERROR("Value::Value()");
360 void Value::clean_up()
383 case V_UNDEF_LOWERID
:
391 delete u
.str
.val_str
;
392 clean_up_string_elements(u
.str
.str_elements
);
395 delete u
.ustr
.val_ustr
;
396 clean_up_string_elements(u
.ustr
.ustr_elements
);
404 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
405 delete (*u
.oid_comps
)[i
];
406 u
.oid_comps
->clear();
414 delete u
.choice
.alt_name
;
415 delete u
.choice
.alt_value
;
434 delete u
.invoke
.t_list
;
435 delete u
.invoke
.ap_list
;
439 for(size_t i
=0; i
<u
.ids
->size(); i
++) delete u
.ids
->get_nth_elem(i
);
448 FATAL_ERROR("Value::clean_up()");
452 void Value::clean_up_expr()
454 switch (u
.expr
.state
) {
456 case EXPR_CHECKING_ERR
:
457 FATAL_ERROR("Value::clean_up_expr()");
461 switch (u
.expr
.v_optype
) {
462 case OPTYPE_RND
: // -
463 case OPTYPE_COMP_NULL
:
464 case OPTYPE_COMP_MTC
:
465 case OPTYPE_COMP_SYSTEM
:
466 case OPTYPE_COMP_SELF
:
467 case OPTYPE_COMP_RUNNING_ANY
:
468 case OPTYPE_COMP_RUNNING_ALL
:
469 case OPTYPE_COMP_ALIVE_ANY
:
470 case OPTYPE_COMP_ALIVE_ALL
:
471 case OPTYPE_TMR_RUNNING_ANY
:
472 case OPTYPE_GETVERDICT
:
473 case OPTYPE_TESTCASENAME
:
474 case OPTYPE_PROF_RUNNING
:
476 case OPTYPE_UNARYPLUS
: // v1
477 case OPTYPE_UNARYMINUS
:
484 case OPTYPE_CHAR2INT
:
485 case OPTYPE_CHAR2OCT
:
486 case OPTYPE_COMP_RUNNING
:
487 case OPTYPE_COMP_ALIVE
:
488 case OPTYPE_FLOAT2INT
:
489 case OPTYPE_FLOAT2STR
:
494 case OPTYPE_INT2CHAR
:
495 case OPTYPE_INT2FLOAT
:
497 case OPTYPE_INT2UNICHAR
:
499 case OPTYPE_OCT2CHAR
:
504 case OPTYPE_STR2FLOAT
:
508 case OPTYPE_UNICHAR2INT
:
509 case OPTYPE_UNICHAR2CHAR
:
510 case OPTYPE_ENUM2INT
:
511 case OPTYPE_RNDWITHVAL
:
512 case OPTYPE_REMOVE_BOM
:
513 case OPTYPE_GET_STRINGENCODING
:
514 case OPTYPE_DECODE_BASE64
:
517 case OPTYPE_ADD
: // v1 v2
518 case OPTYPE_SUBTRACT
:
519 case OPTYPE_MULTIPLY
:
543 case OPTYPE_UNICHAR2OCT
:
544 case OPTYPE_OCT2UNICHAR
:
545 case OPTYPE_ENCODE_BASE64
:
563 case OPTYPE_DECOMP
: // v1 v2 v3
574 case OPTYPE_LENGTHOF
: // ti1
575 case OPTYPE_SIZEOF
: // ti1
576 case OPTYPE_VALUEOF
: // ti1
580 case OPTYPE_ISPRESENT
:
581 case OPTYPE_TTCN2STRING
:
584 case OPTYPE_UNDEF_RUNNING
:
585 case OPTYPE_TMR_READ
:
586 case OPTYPE_TMR_RUNNING
:
587 case OPTYPE_ACTIVATE
:
590 case OPTYPE_EXECUTE
: // r1 [v2]
594 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
599 case OPTYPE_MATCH
: // v1 t2
603 case OPTYPE_ISCHOSEN
: // r1 i2
607 case OPTYPE_ISCHOSEN_V
: // v1 i2
611 case OPTYPE_ISCHOSEN_T
: // t1 i2
615 case OPTYPE_ACTIVATE_REFD
: //v1 t_list2
617 if(u
.expr
.state
!=EXPR_CHECKED
)
618 delete u
.expr
.t_list2
;
620 delete u
.expr
.ap_list2
;
622 case OPTYPE_EXECUTE_REFD
: //v1 t_list2 [v3]
624 if(u
.expr
.state
!=EXPR_CHECKED
)
625 delete u
.expr
.t_list2
;
627 delete u
.expr
.ap_list2
;
631 delete u
.expr
.logargs
;
634 FATAL_ERROR("Value::clean_up_expr()");
638 void Value::copy_and_destroy(Value
*src
)
641 valuetype
= src
->valuetype
;
643 // update the pointer used for caching if it points to the value itself
644 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== src
) u
.ref
.refd_last
= this;
645 src
->valuetype
= V_ERROR
;
649 Value::Value(valuetype_t p_vt
)
650 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
661 u
.oid_comps
=new vector
<OID_comp
>();
664 u
.ids
=new map
<string
, Identifier
>();
667 FATAL_ERROR("Value::Value()");
671 Value::Value(valuetype_t p_vt
, bool p_val_bool
)
672 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
676 u
.val_bool
=p_val_bool
;
679 FATAL_ERROR("Value::Value()");
683 Value::Value(valuetype_t p_vt
, const Int
& p_val_Int
)
684 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
688 u
.val_Int
=new int_val_t(p_val_Int
);
691 FATAL_ERROR("Value::Value()");
695 Value::Value(valuetype_t p_vt
, int_val_t
*p_val_Int
)
696 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
703 FATAL_ERROR("Value::Value()");
707 Value::Value(valuetype_t p_vt
, string
*p_val_str
)
708 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
710 if(!p_val_str
) FATAL_ERROR("NULL parameter");
717 set_val_str(p_val_str
);
720 FATAL_ERROR("Value::Value()");
724 Value::Value(valuetype_t p_vt
, ustring
*p_val_ustr
)
725 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
727 if (p_vt
!= V_USTR
|| !p_val_ustr
) FATAL_ERROR("Value::Value()");
728 set_val_ustr(p_val_ustr
);
729 u
.ustr
.convert_str
= false;
732 Value::Value(valuetype_t p_vt
, CharSyms
*p_char_syms
)
733 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
735 if (!p_char_syms
) FATAL_ERROR("NULL parameter");
738 u
.char_syms
= p_char_syms
;
741 FATAL_ERROR("Value::Value()");
745 Value::Value(valuetype_t p_vt
, Identifier
*p_val_id
)
746 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
749 FATAL_ERROR("NULL parameter");
753 case V_UNDEF_LOWERID
:
757 FATAL_ERROR("Value::Value()");
761 Value::Value(valuetype_t p_vt
, Identifier
*p_id
, Value
*p_val
)
762 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
765 FATAL_ERROR("NULL parameter");
768 u
.choice
.alt_name
=p_id
;
769 u
.choice
.alt_value
=p_val
;
772 FATAL_ERROR("Value::Value()");
776 Value::Value(valuetype_t p_vt
, const Real
& p_val_Real
)
777 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
781 u
.val_Real
=p_val_Real
;
784 FATAL_ERROR("Value::Value()");
788 Value::Value(valuetype_t p_vt
, Values
*p_vs
)
789 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
791 if(!p_vs
) FATAL_ERROR("NULL parameter");
799 FATAL_ERROR("Value::Value()");
803 Value::Value(valuetype_t p_vt
, Value
*p_v
,
804 Ttcn::ParsedActualParameters
*p_t_list
)
805 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
807 if(!p_v
|| !p_t_list
) FATAL_ERROR("NULL parameter");
811 u
.invoke
.t_list
= p_t_list
;
812 u
.invoke
.ap_list
= 0;
815 FATAL_ERROR("Value::Value()");
820 Value::Value(operationtype_t p_optype
)
821 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
823 u
.expr
.v_optype
= p_optype
;
824 u
.expr
.state
= EXPR_NOT_CHECKED
;
827 case OPTYPE_COMP_NULL
:
828 case OPTYPE_COMP_MTC
:
829 case OPTYPE_COMP_SYSTEM
:
830 case OPTYPE_COMP_SELF
:
831 case OPTYPE_COMP_RUNNING_ANY
:
832 case OPTYPE_COMP_RUNNING_ALL
:
833 case OPTYPE_COMP_ALIVE_ANY
:
834 case OPTYPE_COMP_ALIVE_ALL
:
835 case OPTYPE_TMR_RUNNING_ANY
:
836 case OPTYPE_GETVERDICT
:
837 case OPTYPE_TESTCASENAME
:
838 case OPTYPE_PROF_RUNNING
:
841 FATAL_ERROR("Value::Value()");
846 Value::Value(operationtype_t p_optype
, Value
*p_v1
)
847 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
849 u
.expr
.v_optype
= p_optype
;
850 u
.expr
.state
= EXPR_NOT_CHECKED
;
852 case OPTYPE_UNARYPLUS
:
853 case OPTYPE_UNARYMINUS
:
860 case OPTYPE_CHAR2INT
:
861 case OPTYPE_CHAR2OCT
:
862 case OPTYPE_COMP_RUNNING
:
863 case OPTYPE_COMP_ALIVE
:
864 case OPTYPE_FLOAT2INT
:
865 case OPTYPE_FLOAT2STR
:
870 case OPTYPE_INT2CHAR
:
871 case OPTYPE_INT2FLOAT
:
873 case OPTYPE_INT2UNICHAR
:
875 case OPTYPE_OCT2CHAR
:
880 case OPTYPE_STR2FLOAT
:
884 case OPTYPE_UNICHAR2INT
:
885 case OPTYPE_UNICHAR2CHAR
:
886 case OPTYPE_ENUM2INT
:
887 case OPTYPE_RNDWITHVAL
:
888 case OPTYPE_REMOVE_BOM
:
889 case OPTYPE_GET_STRINGENCODING
:
890 case OPTYPE_DECODE_BASE64
:
891 if(!p_v1
) FATAL_ERROR("Value::Value()");
895 FATAL_ERROR("Value::Value()");
900 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
)
901 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
903 u
.expr
.v_optype
= p_optype
;
904 u
.expr
.state
= EXPR_NOT_CHECKED
;
906 case OPTYPE_LENGTHOF
:
912 case OPTYPE_ISPRESENT
:
913 case OPTYPE_TTCN2STRING
:
914 if(!p_ti1
) FATAL_ERROR("Value::Value()");
918 FATAL_ERROR("Value::Value()");
923 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
)
924 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
926 u
.expr
.v_optype
= p_optype
;
927 u
.expr
.state
= EXPR_NOT_CHECKED
;
929 case OPTYPE_UNDEF_RUNNING
:
930 case OPTYPE_TMR_READ
:
931 case OPTYPE_TMR_RUNNING
:
932 case OPTYPE_ACTIVATE
:
933 if(!p_r1
) FATAL_ERROR("Value::Value()");
937 FATAL_ERROR("Value::Value()");
942 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
943 Ttcn::ParsedActualParameters
*p_ap_list
)
944 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
946 u
.expr
.v_optype
= p_optype
;
947 u
.expr
.state
= EXPR_NOT_CHECKED
;
949 case OPTYPE_ACTIVATE_REFD
:
950 if(!p_v1
|| !p_ap_list
) FATAL_ERROR("Value::Value()");
952 u
.expr
.t_list2
= p_ap_list
;
955 FATAL_ERROR("Value::Value()");
960 Value::Value(operationtype_t p_optype
, Value
*p_v1
,
961 Ttcn::ParsedActualParameters
*p_t_list2
, Value
*p_v3
)
962 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
964 u
.expr
.v_optype
= p_optype
;
965 u
.expr
.state
= EXPR_NOT_CHECKED
;
967 case OPTYPE_EXECUTE_REFD
:
968 if(!p_v1
|| !p_t_list2
) FATAL_ERROR("Value::Value()");
970 u
.expr
.t_list2
= p_t_list2
;
974 FATAL_ERROR("Value::Value()");
979 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Value
*p_v2
)
980 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
982 u
.expr
.v_optype
= p_optype
;
983 u
.expr
.state
= EXPR_NOT_CHECKED
;
986 if(!p_r1
) FATAL_ERROR("Value::Value()");
991 FATAL_ERROR("Value::Value()");
996 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
,
997 Value
*p_v2
, Value
*p_v3
, bool p_b4
)
998 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1000 u
.expr
.v_optype
= p_optype
;
1001 u
.expr
.state
= EXPR_NOT_CHECKED
;
1003 case OPTYPE_COMP_CREATE
:
1004 if(!p_r1
) FATAL_ERROR("Value::Value()");
1011 FATAL_ERROR("Value::Value()");
1016 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
)
1017 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1019 u
.expr
.v_optype
= p_optype
;
1020 u
.expr
.state
= EXPR_NOT_CHECKED
;
1023 case OPTYPE_SUBTRACT
:
1024 case OPTYPE_MULTIPLY
:
1045 case OPTYPE_INT2BIT
:
1046 case OPTYPE_INT2HEX
:
1047 case OPTYPE_INT2OCT
:
1048 if(!p_v1
|| !p_v2
) FATAL_ERROR("Value::Value()");
1052 case OPTYPE_UNICHAR2OCT
:
1053 case OPTYPE_OCT2UNICHAR
:
1054 case OPTYPE_ENCODE_BASE64
:
1055 if(!p_v1
) FATAL_ERROR("Value::Value()");
1057 // p_v2 may be NULL if there is no second param
1061 FATAL_ERROR("Value::Value()");
1066 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
,
1067 Value
*p_v3
, TemplateInstance
*p_ti4
) :
1068 GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1070 u
.expr
.v_optype
= p_optype
;
1071 u
.expr
.state
= EXPR_NOT_CHECKED
;
1073 case OPTYPE_REPLACE
:
1074 if (!p_ti1
|| !p_v2
|| !p_v3
|| !p_ti4
) FATAL_ERROR("Value::Value()");
1081 FATAL_ERROR("Value::Value()");
1086 Value::Value(operationtype_t p_optype
, Value
*p_v1
, Value
*p_v2
, Value
*p_v3
)
1087 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1089 u
.expr
.v_optype
= p_optype
;
1090 u
.expr
.state
= EXPR_NOT_CHECKED
;
1093 if(!p_v1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1099 FATAL_ERROR("Value::Value()");
1104 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, Value
*p_v2
, Value
*p_v3
)
1105 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1107 u
.expr
.v_optype
=p_optype
;
1108 u
.expr
.state
=EXPR_NOT_CHECKED
;
1111 if(!p_ti1
|| !p_v2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1117 FATAL_ERROR("Value::Value()");
1122 Value::Value(operationtype_t p_optype
, TemplateInstance
*p_ti1
, TemplateInstance
*p_t2
, Value
*p_v3
)
1123 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1125 u
.expr
.v_optype
=p_optype
;
1126 u
.expr
.state
=EXPR_NOT_CHECKED
;
1129 if(!p_ti1
|| !p_t2
|| !p_v3
) FATAL_ERROR("Value::Value()");
1135 FATAL_ERROR("Value::Value()");
1140 Value::Value(operationtype_t p_optype
, Value
*p_v1
, TemplateInstance
*p_t2
)
1141 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1143 u
.expr
.v_optype
= p_optype
;
1144 u
.expr
.state
= EXPR_NOT_CHECKED
;
1147 if(!p_v1
|| !p_t2
) FATAL_ERROR("Value::Value()");
1152 FATAL_ERROR("Value::Value()");
1157 Value::Value(operationtype_t p_optype
, Ttcn::Reference
*p_r1
,
1159 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1161 u
.expr
.v_optype
= p_optype
;
1162 u
.expr
.state
= EXPR_NOT_CHECKED
;
1164 case OPTYPE_ISCHOSEN
:
1165 if(!p_r1
|| !p_i2
) FATAL_ERROR("Value::Value()");
1170 FATAL_ERROR("Value::Value()");
1174 Value::Value(operationtype_t p_optype
, LogArguments
*p_logargs
)
1175 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1177 u
.expr
.v_optype
= p_optype
;
1178 u
.expr
.state
= EXPR_NOT_CHECKED
;
1180 case OPTYPE_LOG2STR
:
1181 if (!p_logargs
) FATAL_ERROR("Value::Value()");
1182 u
.expr
.logargs
= p_logargs
;
1185 FATAL_ERROR("Value::Value()");
1189 Value::Value(valuetype_t p_vt
, macrotype_t p_macrotype
)
1190 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1192 if (p_vt
!= V_MACRO
) FATAL_ERROR("Value::Value()");
1193 switch (p_macrotype
) {
1194 case MACRO_MODULEID
:
1195 case MACRO_FILENAME
:
1196 case MACRO_BFILENAME
:
1197 case MACRO_FILEPATH
:
1198 case MACRO_LINENUMBER
:
1199 case MACRO_LINENUMBER_C
:
1200 case MACRO_DEFINITIONID
:
1202 case MACRO_TESTCASEID
:
1205 FATAL_ERROR("Value::Value()");
1207 u
.macro
= p_macrotype
;
1210 Value::Value(valuetype_t p_vt
, NamedValues
*p_nvs
)
1211 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1213 if(!p_nvs
) FATAL_ERROR("NULL parameter");
1220 FATAL_ERROR("Value::Value()");
1224 Value::Value(valuetype_t p_vt
, Reference
*p_ref
)
1225 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1227 if (!p_ref
) FATAL_ERROR("NULL parameter: Value::Value()");
1231 u
.ref
.refd_last
= 0;
1237 FATAL_ERROR("Value::Value()");
1241 Value::Value(valuetype_t p_vt
, Block
*p_block
)
1242 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1244 if(!p_block
) FATAL_ERROR("NULL parameter");
1250 FATAL_ERROR("Value::Value()");
1254 Value::Value(valuetype_t p_vt
, verdict_t p_verdict
)
1255 : GovernedSimple(S_V
), valuetype(p_vt
), my_governor(0)
1257 if (valuetype
!= V_VERDICT
) FATAL_ERROR("Value::Value()");
1258 switch (p_verdict
) {
1261 case Verdict_INCONC
:
1266 FATAL_ERROR("Value::Value()");
1268 u
.verdict
= p_verdict
;
1271 Value::Value(operationtype_t p_optype
, Ttcn::Ref_base
*p_r1
, Ttcn::Ref_base
*p_r2
)
1272 : GovernedSimple(S_V
), valuetype(V_EXPR
), my_governor(0)
1274 u
.expr
.v_optype
= p_optype
;
1275 u
.expr
.state
= EXPR_NOT_CHECKED
;
1278 if(!p_r1
|| !p_r2
) FATAL_ERROR("Value::Value()");
1283 FATAL_ERROR("Value::Value()");
1292 Value
*Value::clone() const
1294 return new Value(*this);
1297 Value::operationtype_t
Value::get_optype() const
1299 if(valuetype
!=V_EXPR
)
1300 FATAL_ERROR("Value::get_optype()");
1301 return u
.expr
.v_optype
;
1304 void Value::set_my_governor(Type
*p_gov
)
1307 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1311 Type
*Value::get_my_governor() const
1316 void Value::set_fullname(const string
& p_fullname
)
1318 GovernedSimple::set_fullname(p_fullname
);
1321 u
.char_syms
->set_fullname(p_fullname
);
1325 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1326 (*u
.oid_comps
)[i
]->set_fullname(p_fullname
+"."+Int2string(i
+1));
1329 u
.choice
.alt_value
->set_fullname(p_fullname
+ "." +
1330 u
.choice
.alt_name
->get_dispname());
1335 u
.val_vs
->set_fullname(p_fullname
);
1339 u
.val_nvs
->set_fullname(p_fullname
);
1342 u
.ref
.ref
->set_fullname(p_fullname
);
1345 u
.refered
->set_fullname(p_fullname
);
1348 u
.invoke
.v
->set_fullname(p_fullname
);
1349 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_fullname(p_fullname
);
1350 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_fullname(p_fullname
);
1353 set_fullname_expr(p_fullname
);
1360 void Value::set_my_scope(Scope
*p_scope
)
1362 GovernedSimple::set_my_scope(p_scope
);
1365 u
.char_syms
->set_my_scope(p_scope
);
1369 for(size_t i
=0; i
<u
.oid_comps
->size(); i
++)
1370 (*u
.oid_comps
)[i
]->set_my_scope(p_scope
);
1373 u
.choice
.alt_value
->set_my_scope(p_scope
);
1378 u
.val_vs
->set_my_scope(p_scope
);
1382 u
.val_nvs
->set_my_scope(p_scope
);
1385 u
.ref
.ref
->set_my_scope(p_scope
);
1388 u
.refered
->set_my_scope(p_scope
);
1391 u
.invoke
.v
->set_my_scope(p_scope
);
1392 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_my_scope(p_scope
);
1393 if(u
.invoke
.ap_list
) u
.invoke
.ap_list
->set_my_scope(p_scope
);
1396 set_my_scope_expr(p_scope
);
1403 void Value::set_fullname_expr(const string
& p_fullname
)
1405 switch (u
.expr
.v_optype
) {
1406 case OPTYPE_RND
: // -
1407 case OPTYPE_COMP_NULL
:
1408 case OPTYPE_COMP_MTC
:
1409 case OPTYPE_COMP_SYSTEM
:
1410 case OPTYPE_COMP_SELF
:
1411 case OPTYPE_COMP_RUNNING_ANY
:
1412 case OPTYPE_COMP_RUNNING_ALL
:
1413 case OPTYPE_COMP_ALIVE_ANY
:
1414 case OPTYPE_COMP_ALIVE_ALL
:
1415 case OPTYPE_TMR_RUNNING_ANY
:
1416 case OPTYPE_GETVERDICT
:
1417 case OPTYPE_TESTCASENAME
:
1418 case OPTYPE_PROF_RUNNING
:
1420 case OPTYPE_UNARYPLUS
: // v1
1421 case OPTYPE_UNARYMINUS
:
1424 case OPTYPE_BIT2HEX
:
1425 case OPTYPE_BIT2INT
:
1426 case OPTYPE_BIT2OCT
:
1427 case OPTYPE_BIT2STR
:
1428 case OPTYPE_CHAR2INT
:
1429 case OPTYPE_CHAR2OCT
:
1430 case OPTYPE_COMP_RUNNING
:
1431 case OPTYPE_COMP_ALIVE
:
1432 case OPTYPE_FLOAT2INT
:
1433 case OPTYPE_FLOAT2STR
:
1434 case OPTYPE_HEX2BIT
:
1435 case OPTYPE_HEX2INT
:
1436 case OPTYPE_HEX2OCT
:
1437 case OPTYPE_HEX2STR
:
1438 case OPTYPE_INT2CHAR
:
1439 case OPTYPE_INT2FLOAT
:
1440 case OPTYPE_INT2STR
:
1441 case OPTYPE_INT2UNICHAR
:
1442 case OPTYPE_OCT2BIT
:
1443 case OPTYPE_OCT2CHAR
:
1444 case OPTYPE_OCT2HEX
:
1445 case OPTYPE_OCT2INT
:
1446 case OPTYPE_OCT2STR
:
1447 case OPTYPE_STR2BIT
:
1448 case OPTYPE_STR2FLOAT
:
1449 case OPTYPE_STR2HEX
:
1450 case OPTYPE_STR2INT
:
1451 case OPTYPE_STR2OCT
:
1452 case OPTYPE_UNICHAR2INT
:
1453 case OPTYPE_UNICHAR2CHAR
:
1454 case OPTYPE_ENUM2INT
:
1455 case OPTYPE_RNDWITHVAL
:
1456 case OPTYPE_REMOVE_BOM
:
1457 case OPTYPE_GET_STRINGENCODING
:
1458 case OPTYPE_DECODE_BASE64
:
1459 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1461 case OPTYPE_ADD
: // v1 v2
1462 case OPTYPE_SUBTRACT
:
1463 case OPTYPE_MULTIPLY
:
1484 case OPTYPE_INT2BIT
:
1485 case OPTYPE_INT2HEX
:
1486 case OPTYPE_INT2OCT
:
1487 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1488 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1490 case OPTYPE_UNICHAR2OCT
:
1491 case OPTYPE_OCT2UNICHAR
:
1492 case OPTYPE_ENCODE_BASE64
:
1493 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1494 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1497 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1498 u
.expr
.r2
->set_fullname(p_fullname
+".<operand2>");
1501 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1502 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1503 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1506 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1507 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1508 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1510 case OPTYPE_DECOMP
: // v1 v2 v3
1511 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1512 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1513 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1515 case OPTYPE_REPLACE
:
1516 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand1>");
1517 u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1518 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1519 u
.expr
.ti4
->set_fullname(p_fullname
+".<operand4>");
1521 case OPTYPE_LENGTHOF
: // ti1
1522 case OPTYPE_SIZEOF
: // ti1
1523 case OPTYPE_VALUEOF
: // ti1
1524 case OPTYPE_ISVALUE
:
1525 case OPTYPE_ISBOUND
:
1527 case OPTYPE_ISPRESENT
:
1528 case OPTYPE_TTCN2STRING
:
1529 u
.expr
.ti1
->set_fullname(p_fullname
+".<operand>");
1531 case OPTYPE_UNDEF_RUNNING
: // r1
1532 case OPTYPE_TMR_READ
:
1533 case OPTYPE_TMR_RUNNING
:
1534 case OPTYPE_ACTIVATE
:
1535 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1537 case OPTYPE_EXECUTE
: // r1 [v2]
1538 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1539 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1541 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
1542 u
.expr
.r1
->set_fullname(p_fullname
+".<operand1>");
1543 if(u
.expr
.v2
) u
.expr
.v2
->set_fullname(p_fullname
+".<operand2>");
1544 if(u
.expr
.v3
) u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1546 case OPTYPE_MATCH
: // v1 t2
1547 u
.expr
.v1
->set_fullname(p_fullname
+".<operand1>");
1548 u
.expr
.t2
->set_fullname(p_fullname
+".<operand2>");
1550 case OPTYPE_ISCHOSEN
: // r1 i2
1551 u
.expr
.r1
->set_fullname(p_fullname
+".<operand>");
1553 case OPTYPE_ISCHOSEN_V
: // v1 i2
1554 u
.expr
.v1
->set_fullname(p_fullname
+".<operand>");
1556 case OPTYPE_ISCHOSEN_T
: // t1 i2
1557 u
.expr
.t1
->set_fullname(p_fullname
+".<operand>");
1559 case OPTYPE_ACTIVATE_REFD
:
1560 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1561 if(u
.expr
.state
!=EXPR_CHECKED
)
1562 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1564 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1566 case OPTYPE_EXECUTE_REFD
:
1567 u
.expr
.v1
->set_fullname(p_fullname
+".<reference>");
1568 if(u
.expr
.state
!=EXPR_CHECKED
)
1569 u
.expr
.t_list2
->set_fullname(p_fullname
+".<parameterlist>");
1571 u
.expr
.ap_list2
->set_fullname(p_fullname
+".<parameterlist>");
1573 u
.expr
.v3
->set_fullname(p_fullname
+".<operand3>");
1575 case OPTYPE_LOG2STR
:
1576 u
.expr
.logargs
->set_fullname(p_fullname
+".<logargs>");
1579 FATAL_ERROR("Value::set_fullname_expr()");
1583 void Value::set_my_scope_expr(Scope
*p_scope
)
1585 switch (u
.expr
.v_optype
) {
1586 case OPTYPE_RND
: // -
1587 case OPTYPE_COMP_NULL
:
1588 case OPTYPE_COMP_MTC
:
1589 case OPTYPE_COMP_SYSTEM
:
1590 case OPTYPE_COMP_SELF
:
1591 case OPTYPE_COMP_RUNNING_ANY
:
1592 case OPTYPE_COMP_RUNNING_ALL
:
1593 case OPTYPE_COMP_ALIVE_ANY
:
1594 case OPTYPE_COMP_ALIVE_ALL
:
1595 case OPTYPE_TMR_RUNNING_ANY
:
1596 case OPTYPE_GETVERDICT
:
1597 case OPTYPE_TESTCASENAME
:
1598 case OPTYPE_PROF_RUNNING
:
1600 case OPTYPE_UNARYPLUS
: // v1
1601 case OPTYPE_UNARYMINUS
:
1604 case OPTYPE_BIT2HEX
:
1605 case OPTYPE_BIT2INT
:
1606 case OPTYPE_BIT2OCT
:
1607 case OPTYPE_BIT2STR
:
1608 case OPTYPE_CHAR2INT
:
1609 case OPTYPE_CHAR2OCT
:
1610 case OPTYPE_COMP_RUNNING
:
1611 case OPTYPE_COMP_ALIVE
:
1612 case OPTYPE_FLOAT2INT
:
1613 case OPTYPE_FLOAT2STR
:
1614 case OPTYPE_HEX2BIT
:
1615 case OPTYPE_HEX2INT
:
1616 case OPTYPE_HEX2OCT
:
1617 case OPTYPE_HEX2STR
:
1618 case OPTYPE_INT2CHAR
:
1619 case OPTYPE_INT2FLOAT
:
1620 case OPTYPE_INT2STR
:
1621 case OPTYPE_INT2UNICHAR
:
1622 case OPTYPE_OCT2BIT
:
1623 case OPTYPE_OCT2CHAR
:
1624 case OPTYPE_OCT2HEX
:
1625 case OPTYPE_OCT2INT
:
1626 case OPTYPE_OCT2STR
:
1627 case OPTYPE_STR2BIT
:
1628 case OPTYPE_STR2FLOAT
:
1629 case OPTYPE_STR2HEX
:
1630 case OPTYPE_STR2INT
:
1631 case OPTYPE_STR2OCT
:
1632 case OPTYPE_UNICHAR2INT
:
1633 case OPTYPE_UNICHAR2CHAR
:
1634 case OPTYPE_ENUM2INT
:
1635 case OPTYPE_RNDWITHVAL
:
1636 case OPTYPE_REMOVE_BOM
:
1637 case OPTYPE_GET_STRINGENCODING
:
1638 case OPTYPE_DECODE_BASE64
:
1639 u
.expr
.v1
->set_my_scope(p_scope
);
1641 case OPTYPE_ADD
: // v1 v2
1642 case OPTYPE_SUBTRACT
:
1643 case OPTYPE_MULTIPLY
:
1664 case OPTYPE_INT2BIT
:
1665 case OPTYPE_INT2HEX
:
1666 case OPTYPE_INT2OCT
:
1667 u
.expr
.v1
->set_my_scope(p_scope
);
1668 u
.expr
.v2
->set_my_scope(p_scope
);
1670 case OPTYPE_UNICHAR2OCT
:
1671 case OPTYPE_OCT2UNICHAR
:
1672 case OPTYPE_ENCODE_BASE64
:
1673 u
.expr
.v1
->set_my_scope(p_scope
);
1674 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1677 u
.expr
.r1
->set_my_scope(p_scope
);
1678 u
.expr
.r2
->set_my_scope(p_scope
);
1681 u
.expr
.ti1
->set_my_scope(p_scope
);
1682 u
.expr
.v2
->set_my_scope(p_scope
);
1683 u
.expr
.v3
->set_my_scope(p_scope
);
1686 u
.expr
.ti1
->set_my_scope(p_scope
);
1687 u
.expr
.t2
->set_my_scope(p_scope
);
1688 u
.expr
.v3
->set_my_scope(p_scope
);
1690 case OPTYPE_DECOMP
: // v1 v2 v3
1691 u
.expr
.v1
->set_my_scope(p_scope
);
1692 u
.expr
.v2
->set_my_scope(p_scope
);
1693 u
.expr
.v3
->set_my_scope(p_scope
);
1695 case OPTYPE_REPLACE
:
1696 u
.expr
.ti1
->set_my_scope(p_scope
);
1697 u
.expr
.v2
->set_my_scope(p_scope
);
1698 u
.expr
.v3
->set_my_scope(p_scope
);
1699 u
.expr
.ti4
->set_my_scope(p_scope
);
1701 case OPTYPE_LENGTHOF
: // ti1
1702 case OPTYPE_SIZEOF
: // ti1
1703 case OPTYPE_VALUEOF
: // ti1
1704 case OPTYPE_ISVALUE
:
1705 case OPTYPE_ISBOUND
:
1707 case OPTYPE_ISPRESENT
:
1708 case OPTYPE_TTCN2STRING
:
1709 u
.expr
.ti1
->set_my_scope(p_scope
);
1711 case OPTYPE_UNDEF_RUNNING
: // r1
1712 case OPTYPE_TMR_READ
:
1713 case OPTYPE_TMR_RUNNING
:
1714 case OPTYPE_ACTIVATE
:
1715 u
.expr
.r1
->set_my_scope(p_scope
);
1717 case OPTYPE_EXECUTE
: // r1 [v2]
1718 u
.expr
.r1
->set_my_scope(p_scope
);
1719 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1721 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3]
1722 u
.expr
.r1
->set_my_scope(p_scope
);
1723 if(u
.expr
.v2
) u
.expr
.v2
->set_my_scope(p_scope
);
1724 if(u
.expr
.v3
) u
.expr
.v3
->set_my_scope(p_scope
);
1726 case OPTYPE_MATCH
: // v1 t2
1727 u
.expr
.v1
->set_my_scope(p_scope
);
1728 u
.expr
.t2
->set_my_scope(p_scope
);
1730 case OPTYPE_ISCHOSEN
: // r1 i2
1731 u
.expr
.r1
->set_my_scope(p_scope
);
1733 case OPTYPE_ISCHOSEN_V
: // v1 i2
1734 u
.expr
.v1
->set_my_scope(p_scope
);
1736 case OPTYPE_ISCHOSEN_T
: // t1 i2
1737 u
.expr
.t1
->set_my_scope(p_scope
);
1739 case OPTYPE_ACTIVATE_REFD
:
1740 u
.expr
.v1
->set_my_scope(p_scope
);
1741 if(u
.expr
.state
!=EXPR_CHECKED
) {
1742 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1744 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1746 case OPTYPE_EXECUTE_REFD
:
1747 u
.expr
.v1
->set_my_scope(p_scope
);
1748 if(u
.expr
.state
!=EXPR_CHECKED
) {
1749 if(u
.expr
.t_list2
) u
.expr
.t_list2
->set_my_scope(p_scope
);
1751 if(u
.expr
.ap_list2
) u
.expr
.ap_list2
->set_my_scope(p_scope
);
1754 u
.expr
.v3
->set_my_scope(p_scope
);
1756 case OPTYPE_LOG2STR
:
1757 u
.expr
.logargs
->set_my_scope(p_scope
);
1760 FATAL_ERROR("Value::set_my_scope_expr()");
1764 void Value::set_genname_recursive(const string
& p_genname
)
1766 size_t genname_len
= p_genname
.size();
1767 if (genname_len
>= 4 &&
1768 p_genname
.find("()()", genname_len
- 4) == genname_len
- 4) {
1769 // if the genname ends with ()() (i.e. the value stands for an optional
1770 // field) then drop the last () from the own genname, but leave it for
1771 // the embedded values
1772 set_genname(p_genname
.substr(0, genname_len
- 2));
1773 } else set_genname(p_genname
);
1776 string
embedded_genname(p_genname
);
1777 embedded_genname
+= '.';
1778 // If this is a choice value for an anytype, prepend the AT_ prefix
1779 // to the name of the alternative. The genname is used later in
1780 // Common::Value::generate_code_init_se()
1781 if (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
1782 embedded_genname
+= "AT_";
1783 embedded_genname
+= u
.choice
.alt_name
->get_name();
1784 embedded_genname
+= "()";
1785 u
.choice
.alt_value
->set_genname_recursive(embedded_genname
);
1789 if (!is_indexed()) {
1790 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1791 for (size_t i
= 0; i
< nof_vs
; i
++) {
1792 string
embedded_genname(p_genname
);
1793 embedded_genname
+= '[';
1794 embedded_genname
+= Int2string(i
);
1795 embedded_genname
+= ']';
1796 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1799 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1800 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1801 string
embedded_genname(p_genname
);
1802 embedded_genname
+= '[';
1803 embedded_genname
+= Int2string(i
);
1804 embedded_genname
+= ']';
1805 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1806 ->set_genname_recursive(embedded_genname
);
1811 if (!my_governor
) return; // error recovery
1812 Type
*type
= my_governor
->get_type_refd_last();
1813 if (type
->get_typetype() != Type::T_ARRAY
) return; // error recovery
1814 Int offset
= type
->get_dimension()->get_offset();
1815 if (!is_indexed()) {
1816 size_t nof_vs
= u
.val_vs
->get_nof_vs();
1817 for (size_t i
= 0; i
< nof_vs
; i
++) {
1818 string
embedded_genname(p_genname
);
1819 embedded_genname
+= '[';
1820 embedded_genname
+= Int2string(offset
+ i
);
1821 embedded_genname
+= ']';
1822 u
.val_vs
->get_v_byIndex(i
)->set_genname_recursive(embedded_genname
);
1825 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
1826 for (size_t i
= 0; i
< nof_ivs
; i
++) {
1827 string
embedded_genname(p_genname
);
1828 embedded_genname
+= '[';
1829 embedded_genname
+= Int2string(offset
+ i
);
1830 embedded_genname
+= ']';
1831 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1832 ->set_genname_recursive(embedded_genname
);
1838 if (!my_governor
) return; // error recovery
1839 Type
*t
= my_governor
->get_type_refd_last();
1840 if (!t
->is_secho()) return; // error recovery
1841 size_t nof_nvs
= u
.val_nvs
->get_nof_nvs();
1842 for (size_t i
= 0; i
< nof_nvs
; i
++) {
1843 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
1844 const Identifier
& id
= nv
->get_name();
1845 if (!t
->has_comp_withName(id
)) return; // error recovery
1846 string
embedded_genname(p_genname
);
1847 embedded_genname
+= '.';
1848 embedded_genname
+= id
.get_name();
1849 embedded_genname
+= "()";
1850 if (t
->get_comp_byName(id
)->get_is_optional())
1851 embedded_genname
+= "()";
1852 nv
->get_value()->set_genname_recursive(embedded_genname
);
1860 void Value::set_genname_prefix(const char *p_genname_prefix
)
1862 GovernedSimple::set_genname_prefix(p_genname_prefix
);
1865 u
.choice
.alt_value
->set_genname_prefix(p_genname_prefix
);
1870 if (!is_indexed()) {
1871 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
1872 u
.val_vs
->get_v_byIndex(i
)->set_genname_prefix(p_genname_prefix
);
1874 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
1875 u
.val_vs
->get_iv_byIndex(i
)->get_value()
1876 ->set_genname_prefix(p_genname_prefix
);
1881 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
1882 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
1883 ->set_genname_prefix(p_genname_prefix
);
1890 void Value::set_code_section(code_section_t p_code_section
)
1892 GovernedSimple::set_code_section(p_code_section
);
1895 switch (u
.expr
.v_optype
) {
1896 case OPTYPE_RND
: // -
1897 case OPTYPE_COMP_NULL
:
1898 case OPTYPE_COMP_MTC
:
1899 case OPTYPE_COMP_SYSTEM
:
1900 case OPTYPE_COMP_SELF
:
1901 case OPTYPE_COMP_RUNNING_ANY
:
1902 case OPTYPE_COMP_RUNNING_ALL
:
1903 case OPTYPE_COMP_ALIVE_ANY
:
1904 case OPTYPE_COMP_ALIVE_ALL
:
1905 case OPTYPE_TMR_RUNNING_ANY
:
1906 case OPTYPE_GETVERDICT
:
1907 case OPTYPE_TESTCASENAME
:
1908 case OPTYPE_PROF_RUNNING
:
1910 case OPTYPE_UNARYPLUS
: // v1
1911 case OPTYPE_UNARYMINUS
:
1914 case OPTYPE_BIT2HEX
:
1915 case OPTYPE_BIT2INT
:
1916 case OPTYPE_BIT2OCT
:
1917 case OPTYPE_BIT2STR
:
1918 case OPTYPE_CHAR2INT
:
1919 case OPTYPE_CHAR2OCT
:
1920 case OPTYPE_COMP_RUNNING
:
1921 case OPTYPE_COMP_ALIVE
:
1922 case OPTYPE_FLOAT2INT
:
1923 case OPTYPE_FLOAT2STR
:
1924 case OPTYPE_HEX2BIT
:
1925 case OPTYPE_HEX2INT
:
1926 case OPTYPE_HEX2OCT
:
1927 case OPTYPE_HEX2STR
:
1928 case OPTYPE_INT2CHAR
:
1929 case OPTYPE_INT2FLOAT
:
1930 case OPTYPE_INT2STR
:
1931 case OPTYPE_INT2UNICHAR
:
1932 case OPTYPE_OCT2BIT
:
1933 case OPTYPE_OCT2CHAR
:
1934 case OPTYPE_OCT2HEX
:
1935 case OPTYPE_OCT2INT
:
1936 case OPTYPE_OCT2STR
:
1937 case OPTYPE_STR2BIT
:
1938 case OPTYPE_STR2FLOAT
:
1939 case OPTYPE_STR2HEX
:
1940 case OPTYPE_STR2INT
:
1941 case OPTYPE_STR2OCT
:
1942 case OPTYPE_UNICHAR2INT
:
1943 case OPTYPE_UNICHAR2CHAR
:
1944 case OPTYPE_ENUM2INT
:
1945 case OPTYPE_RNDWITHVAL
:
1946 case OPTYPE_GET_STRINGENCODING
:
1947 case OPTYPE_DECODE_BASE64
:
1948 case OPTYPE_REMOVE_BOM
:
1949 u
.expr
.v1
->set_code_section(p_code_section
);
1951 case OPTYPE_ADD
: // v1 v2
1952 case OPTYPE_SUBTRACT
:
1953 case OPTYPE_MULTIPLY
:
1974 case OPTYPE_INT2BIT
:
1975 case OPTYPE_INT2HEX
:
1976 case OPTYPE_INT2OCT
:
1977 u
.expr
.v1
->set_code_section(p_code_section
);
1978 u
.expr
.v2
->set_code_section(p_code_section
);
1980 case OPTYPE_UNICHAR2OCT
:
1981 case OPTYPE_OCT2UNICHAR
:
1982 case OPTYPE_ENCODE_BASE64
:
1983 u
.expr
.v1
->set_code_section(p_code_section
);
1984 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
1987 u
.expr
.r1
->set_code_section(p_code_section
);
1988 u
.expr
.r2
->set_code_section(p_code_section
);
1991 u
.expr
.ti1
->set_code_section(p_code_section
);
1992 u
.expr
.v2
->set_code_section(p_code_section
);
1993 u
.expr
.v3
->set_code_section(p_code_section
);
1996 u
.expr
.ti1
->set_code_section(p_code_section
);
1997 u
.expr
.t2
->set_code_section(p_code_section
);
1998 u
.expr
.v3
->set_code_section(p_code_section
);
2000 case OPTYPE_DECOMP
: // v1 v2 v3
2001 u
.expr
.v1
->set_code_section(p_code_section
);
2002 u
.expr
.v2
->set_code_section(p_code_section
);
2003 u
.expr
.v3
->set_code_section(p_code_section
);
2005 case OPTYPE_REPLACE
:
2006 u
.expr
.ti1
->set_code_section(p_code_section
);
2007 u
.expr
.v2
->set_code_section(p_code_section
);
2008 u
.expr
.v3
->set_code_section(p_code_section
);
2009 u
.expr
.ti4
->set_code_section(p_code_section
);
2011 case OPTYPE_LENGTHOF
: // ti1
2012 case OPTYPE_SIZEOF
: // ti1
2013 case OPTYPE_VALUEOF
: // ti1
2014 case OPTYPE_ISVALUE
:
2015 case OPTYPE_ISBOUND
:
2017 case OPTYPE_ISPRESENT
:
2018 case OPTYPE_TTCN2STRING
:
2019 u
.expr
.ti1
->set_code_section(p_code_section
);
2021 case OPTYPE_UNDEF_RUNNING
: // r1
2022 case OPTYPE_TMR_READ
:
2023 case OPTYPE_TMR_RUNNING
:
2024 case OPTYPE_ACTIVATE
:
2025 u
.expr
.r1
->set_code_section(p_code_section
);
2027 case OPTYPE_EXECUTE
: // r1 [v2]
2028 u
.expr
.r1
->set_code_section(p_code_section
);
2029 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2031 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
2032 u
.expr
.r1
->set_code_section(p_code_section
);
2033 if(u
.expr
.v2
) u
.expr
.v2
->set_code_section(p_code_section
);
2034 if(u
.expr
.v3
) u
.expr
.v3
->set_code_section(p_code_section
);
2036 case OPTYPE_MATCH
: // v1 t2
2037 u
.expr
.v1
->set_code_section(p_code_section
);
2038 u
.expr
.t2
->set_code_section(p_code_section
);
2040 case OPTYPE_ISCHOSEN
: // r1 i2
2041 u
.expr
.r1
->set_code_section(p_code_section
);
2043 case OPTYPE_ISCHOSEN_V
: // v1 i2
2044 u
.expr
.v1
->set_code_section(p_code_section
);
2046 case OPTYPE_ISCHOSEN_T
: // t1 i2
2047 u
.expr
.t1
->set_code_section(p_code_section
);
2049 case OPTYPE_ACTIVATE_REFD
:
2050 u
.expr
.v1
->set_code_section(p_code_section
);
2051 if(u
.expr
.state
!=EXPR_CHECKED
)
2052 u
.expr
.t_list2
->set_code_section(p_code_section
);
2054 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2055 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2056 u
.expr
.state
= EXPR_CHECKED
;
2059 case OPTYPE_EXECUTE_REFD
:
2060 u
.expr
.v1
->set_code_section(p_code_section
);
2061 if(u
.expr
.state
!=EXPR_CHECKED
)
2062 u
.expr
.t_list2
->set_code_section(p_code_section
);
2064 for(size_t i
= 0; i
< u
.expr
.ap_list2
->get_nof_pars(); i
++)
2065 u
.expr
.ap_list2
->get_par(i
)->set_code_section(p_code_section
);
2066 u
.expr
.state
= EXPR_CHECKED
;
2069 u
.expr
.v3
->set_code_section(p_code_section
);
2071 case OPTYPE_LOG2STR
:
2072 u
.expr
.logargs
->set_code_section(p_code_section
);
2075 FATAL_ERROR("Value::set_code_section()");
2079 u
.choice
.alt_value
->set_code_section(p_code_section
);
2084 if (!is_indexed()) {
2085 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++)
2086 u
.val_vs
->get_v_byIndex(i
)->set_code_section(p_code_section
);
2088 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++)
2089 u
.val_vs
->get_iv_byIndex(i
)->set_code_section(p_code_section
);
2094 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++)
2095 u
.val_nvs
->get_nv_byIndex(i
)->get_value()
2096 ->set_code_section(p_code_section
);
2099 u
.ref
.ref
->set_code_section(p_code_section
);
2102 u
.refered
->set_code_section(p_code_section
);
2105 u
.invoke
.v
->set_code_section(p_code_section
);
2106 if(u
.invoke
.t_list
) u
.invoke
.t_list
->set_code_section(p_code_section
);
2107 if(u
.invoke
.ap_list
)
2108 for(size_t i
= 0; i
< u
.invoke
.ap_list
->get_nof_pars(); i
++)
2109 u
.invoke
.ap_list
->get_par(i
)->set_code_section(p_code_section
);
2116 void Value::change_sign()
2120 *u
.val_Int
=-*u
.val_Int
;
2128 FATAL_ERROR("Value::change_sign()");
2132 void Value::add_oid_comp(OID_comp
* p_comp
)
2135 FATAL_ERROR("NULL parameter");
2136 u
.oid_comps
->add(p_comp
);
2137 p_comp
->set_fullname(get_fullname()+"."
2138 +Int2string(u
.oid_comps
->size()));
2139 p_comp
->set_my_scope(my_scope
);
2142 void Value::set_valuetype(valuetype_t p_valuetype
)
2144 if (valuetype
== V_ERROR
) return;
2145 else if (p_valuetype
== V_ERROR
) {
2146 if(valuetype
==V_EXPR
) {
2147 switch(u
.expr
.state
) {
2149 u
.expr
.state
=EXPR_CHECKING_ERR
;
2151 case EXPR_CHECKING_ERR
:
2158 valuetype
= V_ERROR
;
2162 case V_UNDEF_LOWERID
:
2163 switch(p_valuetype
) {
2168 if (is_asn1()) u
.ref
.ref
= new Asn::Ref_defd_simple(0, u
.val_id
);
2169 else u
.ref
.ref
= new Ttcn::Reference(0, u
.val_id
);
2170 u
.ref
.ref
->set_my_scope(get_my_scope());
2171 u
.ref
.ref
->set_fullname(get_fullname());
2172 u
.ref
.ref
->set_location(*this);
2173 u
.ref
.refd_last
= 0;
2176 FATAL_ERROR("Value::set_valuetype()");
2179 case V_UNDEF_BLOCK
: {
2180 Block
*t_block
=u
.block
;
2182 switch(p_valuetype
) {
2184 Node
*node
=t_block
->parse(KW_Block_IdentifierList
);
2185 v
=dynamic_cast<Value
*>(node
);
2188 u
.ids
=new map
<string
, Identifier
>();
2191 u
.ids
=v
->u
.ids
; v
->u
.ids
=0;
2195 Node
*node
=t_block
->parse(KW_Block_SeqOfValue
);
2196 v
=dynamic_cast<Value
*>(node
);
2199 u
.val_vs
=new Values();
2202 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2204 u
.val_vs
->set_my_scope(get_my_scope());
2205 u
.val_vs
->set_fullname(get_fullname());
2208 Node
*node
=t_block
->parse(KW_Block_SetOfValue
);
2209 v
=dynamic_cast<Value
*>(node
);
2212 u
.val_vs
=new Values();
2215 u
.val_vs
=v
->u
.val_vs
; v
->u
.val_vs
=0;
2217 u
.val_vs
->set_my_scope(get_my_scope());
2218 u
.val_vs
->set_fullname(get_fullname());
2221 Node
*node
=t_block
->parse(KW_Block_SequenceValue
);
2222 v
=dynamic_cast<Value
*>(node
);
2225 u
.val_nvs
=new NamedValues();
2228 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2230 u
.val_nvs
->set_my_scope(get_my_scope());
2231 u
.val_nvs
->set_fullname(get_fullname());
2234 Node
*node
=t_block
->parse(KW_Block_SetValue
);
2235 v
=dynamic_cast<Value
*>(node
);
2238 u
.val_nvs
=new NamedValues();
2241 u
.val_nvs
=v
->u
.val_nvs
; v
->u
.val_nvs
=0;
2243 u
.val_nvs
->set_my_scope(get_my_scope());
2244 u
.val_nvs
->set_fullname(get_fullname());
2247 Node
*node
=t_block
->parse(KW_Block_OIDValue
);
2248 v
=dynamic_cast<Value
*>(node
);
2251 u
.oid_comps
=new vector
<OID_comp
>();
2254 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2256 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2257 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2260 Node
*node
=t_block
->parse(KW_Block_ROIDValue
);
2261 v
=dynamic_cast<Value
*>(node
);
2264 u
.oid_comps
=new vector
<OID_comp
>();
2267 u
.oid_comps
=v
->u
.oid_comps
; v
->u
.oid_comps
=0;
2269 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++)
2270 (*u
.oid_comps
)[i
]->set_my_scope(get_my_scope());
2273 Node
*node
=t_block
->parse(KW_Block_CharStringValue
);
2274 u
.char_syms
=dynamic_cast<CharSyms
*>(node
);
2277 u
.char_syms
=new CharSyms();
2279 u
.char_syms
->set_my_scope(get_my_scope());
2280 u
.char_syms
->set_fullname(get_fullname());
2283 FATAL_ERROR("Value::set_valuetype()");
2289 if (p_valuetype
== V_USTR
) {
2290 Value
*v_last
= get_value_refd_last();
2291 if (v_last
->valuetype
!= V_CSTR
) FATAL_ERROR("Value::set_valuetype()");
2292 ustring
*ustr
= new ustring(*v_last
->u
.str
.val_str
);
2295 u
.ustr
.convert_str
= true; // will be converted back to string
2296 } else FATAL_ERROR("Value::set_valuetype()");
2299 switch(p_valuetype
) {
2301 const string
& str
= u
.char_syms
->get_string();
2303 set_val_str(new string(str
));
2306 const ustring
& ustr
= u
.char_syms
->get_ustring();
2308 set_val_ustr(new ustring(ustr
));
2309 u
.ustr
.convert_str
= false;
2311 case V_ISO2022STR
: {
2312 const string
& str
= u
.char_syms
->get_iso2022string();
2314 set_val_str(new string(str
));
2317 FATAL_ERROR("Value::set_valuetype()");
2322 if (p_valuetype
== V_REAL
)
2323 val_Real
= u
.val_Int
->to_real();
2324 else FATAL_ERROR("Value::set_valuetype()");
2326 u
.val_Real
= val_Real
;
2329 clean_up_string_elements(u
.str
.str_elements
);
2330 string
*old_str
= u
.str
.val_str
;
2331 switch(p_valuetype
) {
2333 set_val_str(hex2bit(*old_str
));
2336 set_val_str(asn_hex2oct(*old_str
));
2339 FATAL_ERROR("Value::set_valuetype()");
2344 clean_up_string_elements(u
.str
.str_elements
);
2345 if (p_valuetype
== V_OSTR
) {
2346 string
*old_str
= u
.str
.val_str
;
2347 set_val_str(asn_bit2oct(*old_str
));
2349 } else FATAL_ERROR("Value::set_valuetype()");
2352 clean_up_string_elements(u
.str
.str_elements
);
2353 switch(p_valuetype
) {
2355 string
*old_str
= u
.str
.val_str
;
2356 set_val_ustr(new ustring(*old_str
));
2357 u
.ustr
.convert_str
= true; // will be converted back to string
2364 FATAL_ERROR("Value::set_valuetype()");
2365 } // switch p_valuetype
2368 clean_up_string_elements(u
.ustr
.ustr_elements
);
2369 switch(p_valuetype
) {
2371 ustring
*old_str
= u
.ustr
.val_ustr
;
2372 size_t nof_chars
= old_str
->size();
2373 bool warning_flag
= false;
2374 for (size_t i
= 0; i
< nof_chars
; i
++) {
2375 const ustring::universal_char
& uchar
= (*old_str
)[i
];
2376 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0) {
2377 error("This string value cannot contain multiple-byte characters, "
2378 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2379 uchar
.group
, uchar
.plane
, uchar
.row
, uchar
.cell
,
2381 p_valuetype
= V_ERROR
;
2383 } else if (uchar
.cell
> 127 && !warning_flag
) {
2384 warning("This string value may not contain characters with code "
2385 "higher than 127, but it has character with code %u (0x%02X) "
2386 "at index %lu", uchar
.cell
, uchar
.cell
, (unsigned long) i
);
2387 warning_flag
= true;
2390 if (p_valuetype
!= V_ERROR
) set_val_str(new string(*old_str
));
2394 error("ISO-10646 string value cannot be converted to "
2396 delete u
.ustr
.val_ustr
;
2397 p_valuetype
= V_ERROR
;
2400 FATAL_ERROR("Value::set_valuetype()");
2401 } // switch p_valuetype
2404 switch (p_valuetype
) {
2406 NamedValues
*nvs
= u
.val_nvs
;
2407 if (nvs
->get_nof_nvs() < 1) {
2408 error("Union value must have one active field");
2410 valuetype
= V_ERROR
;
2412 } else if (nvs
->get_nof_nvs() > 1) {
2413 error("Only one field was expected in union value instead of %lu",
2414 (unsigned long) nvs
->get_nof_nvs());
2416 NamedValue
*nv
= nvs
->get_nv_byIndex(0);
2417 u
.choice
.alt_name
= nv
->get_name().clone();
2418 u
.choice
.alt_value
= nv
->steal_value();
2425 NamedValues
*nvs
= u
.val_nvs
;
2429 Identifier
id_mant(Identifier::ID_ASN
, string("mantissa"));
2430 if (nvs
->has_nv_withName(id_mant
)) {
2431 Value
*v_tmp
= nvs
->get_nv_byName(id_mant
)->get_value()
2432 ->get_value_refd_last();
2433 if (v_tmp
->get_valuetype() == V_INT
) {
2434 const int_val_t
*i_mant_int
= v_tmp
->get_val_Int();
2435 if (*i_mant_int
> INT_MAX
) {
2436 error("Mantissa `%s' should be less than `%d'",
2437 (i_mant_int
->t_str()).c_str(), INT_MAX
);
2440 i_mant
= i_mant_int
->get_val();
2448 Identifier
id_base(Identifier::ID_ASN
, string("base"));
2449 if (!err
&& nvs
->has_nv_withName(id_base
)) {
2450 Value
*v
= nvs
->get_nv_byName(id_base
)->get_value();
2451 Value
*v_tmp
= v
->get_value_refd_last();
2452 if (v_tmp
->get_valuetype() == V_INT
) {
2453 const int_val_t
*i_base_int
= v_tmp
->get_val_Int();
2454 if (!err
&& *i_base_int
!= 10 && *i_base_int
!= 2) {
2455 v
->error("Base of the REAL must be 2 or 10");
2458 i_base
= i_base_int
->get_val();
2466 Identifier
id_exp(Identifier::ID_ASN
, string("exponent"));
2467 if (!err
&& nvs
->has_nv_withName(id_exp
)) {
2468 Value
*v_tmp
= nvs
->get_nv_byName(id_exp
)->get_value()
2469 ->get_value_refd_last();
2470 if (v_tmp
->get_valuetype() == V_INT
) {
2471 const int_val_t
*i_exp_int
= v_tmp
->get_val_Int();
2472 if (*i_exp_int
> INT_MAX
) {
2473 error("Exponent `%s' should be less than `%d'",
2474 (i_exp_int
->t_str()).c_str(), INT_MAX
);
2477 i_exp
= i_exp_int
->get_val();
2486 valuetype
= V_ERROR
;
2489 u
.val_Real
= i_mant
* pow(static_cast<double>(i_base
),
2490 static_cast<double>(i_exp
));
2496 FATAL_ERROR("Value::set_valuetype()");
2500 switch (p_valuetype
) {
2502 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2503 if (!my_governor
) FATAL_ERROR("Value::set_valuetype()");
2504 Type
*t
= my_governor
->get_type_refd_last();
2505 switch (t
->get_typetype()) {
2510 FATAL_ERROR("Value::set_valuetype()");
2512 Values
*vals
= u
.val_vs
;
2513 size_t nof_vals
= vals
->get_nof_vs();
2514 size_t nof_comps
= t
->get_nof_comps();
2515 if (nof_vals
> nof_comps
) {
2516 error("Too many elements in value list notation for type `%s': "
2517 "%lu was expected instead of %lu",
2518 t
->get_typename().c_str(),
2519 (unsigned long)nof_comps
, (unsigned long)nof_vals
);
2523 if (nof_vals
<= nof_comps
) {
2524 upper_limit
= nof_vals
;
2527 upper_limit
= nof_comps
;
2530 u
.val_nvs
= new NamedValues
;
2531 for (size_t i
= 0; i
< upper_limit
; i
++) {
2532 Value
*v
= vals
->steal_v_byIndex(i
);
2533 if (v
->valuetype
!= V_NOTUSED
) {
2537 new NamedValue(t
->get_comp_id_byIndex(i
).clone(), v
);
2538 nv
->set_location(*v
);
2539 u
.val_nvs
->add_nv(nv
);
2541 u
.val_nvs
->set_my_scope(get_my_scope());
2542 u
.val_nvs
->set_fullname(get_fullname());
2544 if (allnotused
&& nof_vals
> 0)
2545 warning("All elements of value list notation for type `%s' are not "
2546 "used symbols (`-')", t
->get_typename().c_str());
2549 // { } -> empty set value
2550 if (u
.val_vs
->get_nof_vs() != 0)
2551 FATAL_ERROR("Value::set_valuetype()");
2553 u
.val_nvs
= new NamedValues
;
2557 // SEQOF -> SETOF or ARRAY: trivial
2560 FATAL_ERROR("Value::set_valuetype()");
2565 if (p_valuetype
== V_NOTUSED
) {
2569 FATAL_ERROR("Value::set_valuetype()");
2573 switch (p_valuetype
) {
2574 case V_DEFAULT_NULL
:
2579 FATAL_ERROR("Value::set_valuetype()");
2583 if (V_OMIT
!= p_valuetype
) { // in case of implicit omit
2584 FATAL_ERROR("Value::set_valuetype()");
2588 FATAL_ERROR("Value::set_valuetype()");
2590 valuetype
=p_valuetype
;
2593 void Value::set_valuetype_COMP_NULL()
2595 if(valuetype
== V_ERROR
) return;
2596 if(valuetype
==V_TTCN3_NULL
) {
2598 u
.expr
.v_optype
=OPTYPE_COMP_NULL
;
2599 // Nothing to check.
2600 u
.expr
.state
=EXPR_CHECKED
;
2602 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2605 void Value::set_valuetype(valuetype_t p_valuetype
, const Int
& p_val_int
)
2607 if (valuetype
== V_NAMEDINT
&& p_valuetype
== V_INT
) {
2609 u
.val_Int
= new int_val_t(p_val_int
);
2611 } else FATAL_ERROR("Value::set_valuetype()");
2614 void Value::set_valuetype(valuetype_t p_valuetype
, string
*p_str
)
2616 if (p_str
&& valuetype
== V_NAMEDBITS
&& p_valuetype
== V_BSTR
) {
2620 } else FATAL_ERROR("Value::set_valuetype()");
2623 void Value::set_valuetype(valuetype_t p_valuetype
, Identifier
*p_id
)
2625 if (p_id
&& valuetype
== V_UNDEF_LOWERID
&& p_valuetype
== V_ENUM
) {
2629 } else FATAL_ERROR("Value::set_valuetype()");
2632 void Value::set_valuetype(valuetype_t p_valuetype
, Assignment
*p_ass
)
2634 switch (p_valuetype
) {
2638 if (valuetype
== V_REFER
&& p_ass
) break;
2641 FATAL_ERROR("Value::set_valuetype()");
2645 valuetype
= p_valuetype
;
2648 bool Value::is_undef_lowerid()
2650 switch (valuetype
) {
2651 case V_UNDEF_LOWERID
:
2654 if (u
.expr
.v_optype
== OPTYPE_VALUEOF
&& !u
.expr
.ti1
->get_Type() &&
2655 !u
.expr
.ti1
->get_DerivedRef()) {
2656 return u
.expr
.ti1
->get_Template()->is_undef_lowerid();
2664 const Identifier
& Value::get_undef_lowerid()
2666 switch (valuetype
) {
2667 case V_UNDEF_LOWERID
:
2670 if (u
.expr
.v_optype
!= OPTYPE_VALUEOF
)
2671 FATAL_ERROR("Value::get_undef_lowerid()");
2672 return u
.expr
.ti1
->get_Template()->get_specific_value()
2673 ->get_undef_lowerid();
2675 FATAL_ERROR("Value::get_undef_lowerid()");
2677 const Identifier
*dummy
= 0;
2681 void Value::set_lowerid_to_ref()
2683 switch (valuetype
) {
2684 case V_UNDEF_LOWERID
:
2685 set_valuetype(V_REFD
);
2688 // if the governor of the expression is not known (in log(), etc...)
2689 // then the governor is taken from the reference (using
2690 // v1/ti1->get_expr_governor()), but that runs before the
2691 // params were checked, this smells like a workaround :)
2692 switch (u
.expr
.v_optype
) {
2695 u
.expr
.v1
->set_lowerid_to_ref();
2698 u
.expr
.v1
->set_lowerid_to_ref();
2699 u
.expr
.v2
->set_lowerid_to_ref();
2701 case OPTYPE_VALUEOF
:
2702 case OPTYPE_ISVALUE
:
2703 case OPTYPE_ISBOUND
:
2704 case OPTYPE_ISPRESENT
:
2707 case OPTYPE_REPLACE
:
2708 case OPTYPE_TTCN2STRING
:
2709 if (!u
.expr
.ti1
->get_Type() && !u
.expr
.ti1
->get_DerivedRef()) {
2710 Error_Context
cntxt(u
.expr
.ti1
->get_Template(),
2711 "In the operand of operation `%s'",
2713 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2715 if (u
.expr
.v_optype
==OPTYPE_REGEXP
) {
2716 if (!u
.expr
.t2
->get_Type() && !u
.expr
.t2
->get_DerivedRef()) {
2717 Error_Context
cntxt(u
.expr
.t2
->get_Template(),
2718 "In the operand of operation `%s'",
2720 u
.expr
.t2
->get_Template()->set_lowerid_to_ref();
2723 if (u
.expr
.v_optype
==OPTYPE_REPLACE
) {
2724 if (!u
.expr
.ti4
->get_Type() && !u
.expr
.ti4
->get_DerivedRef()) {
2725 Error_Context
cntxt(u
.expr
.ti4
->get_Template(),
2726 "In the operand of operation `%s'",
2728 u
.expr
.ti4
->get_Template()->set_lowerid_to_ref();
2741 Type::typetype_t
Value::get_expr_returntype(Type::expected_value_t exp_val
)
2743 switch (valuetype
) {
2751 case V_UNDEF_LOWERID
:
2758 return Type::T_UNDEF
;
2762 FATAL_ERROR("Value::get_expr_returntype()");
2764 return Type::T_ERROR
;
2767 Type
*t
= get_expr_governor(exp_val
);
2768 if (t
) return t
->get_type_refd_last()->get_typetype_ttcn3();
2769 else return Type::T_ERROR
; }
2771 return Type::T_FUNCTION
;
2773 return Type::T_ALTSTEP
;
2775 return Type::T_TESTCASE
;
2777 switch(u
.expr
.v_optype
) {
2778 case OPTYPE_COMP_NULL
:
2779 case OPTYPE_COMP_MTC
:
2780 case OPTYPE_COMP_SYSTEM
:
2781 case OPTYPE_COMP_SELF
:
2782 case OPTYPE_COMP_CREATE
:
2783 return Type::T_COMPONENT
;
2784 case OPTYPE_UNDEF_RUNNING
:
2785 case OPTYPE_COMP_RUNNING
:
2786 case OPTYPE_COMP_RUNNING_ANY
:
2787 case OPTYPE_COMP_RUNNING_ALL
:
2788 case OPTYPE_COMP_ALIVE
:
2789 case OPTYPE_COMP_ALIVE_ANY
:
2790 case OPTYPE_COMP_ALIVE_ALL
:
2791 case OPTYPE_TMR_RUNNING
:
2792 case OPTYPE_TMR_RUNNING_ANY
:
2804 case OPTYPE_ISPRESENT
:
2805 case OPTYPE_ISCHOSEN
:
2806 case OPTYPE_ISCHOSEN_V
:
2807 case OPTYPE_ISCHOSEN_T
:
2808 case OPTYPE_ISVALUE
:
2809 case OPTYPE_ISBOUND
:
2810 case OPTYPE_PROF_RUNNING
:
2811 return Type::T_BOOL
;
2812 case OPTYPE_GETVERDICT
:
2813 return Type::T_VERDICT
;
2814 case OPTYPE_VALUEOF
: {
2815 Error_Context
cntxt(this, "In the operand of operation `%s'",
2817 return u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);}
2818 case OPTYPE_TMR_READ
:
2819 case OPTYPE_INT2FLOAT
:
2820 case OPTYPE_STR2FLOAT
:
2822 case OPTYPE_RNDWITHVAL
:
2823 return Type::T_REAL
;
2824 case OPTYPE_ACTIVATE
:
2825 return Type::T_DEFAULT
;
2826 case OPTYPE_ACTIVATE_REFD
:
2827 return Type::T_DEFAULT
;
2828 case OPTYPE_EXECUTE
:
2829 case OPTYPE_EXECUTE_REFD
:
2830 return Type::T_VERDICT
;
2831 case OPTYPE_UNARYPLUS
: // v1
2832 case OPTYPE_UNARYMINUS
: {
2833 Type::typetype_t tmp_tt
;
2835 Error_Context
cntxt(this, "In the operand of operation `%s'",
2837 u
.expr
.v1
->set_lowerid_to_ref();
2838 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2845 get_value_refd_last(); // to report the error
2846 return Type::T_ERROR
;
2849 case OPTYPE_ADD
: // v1 v2
2850 case OPTYPE_SUBTRACT
:
2851 case OPTYPE_MULTIPLY
:
2852 case OPTYPE_DIVIDE
: {
2853 Type::typetype_t tmp_tt
;
2855 Error_Context
cntxt(this, "In the left operand of operation `%s'",
2857 u
.expr
.v1
->set_lowerid_to_ref();
2858 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2865 if(u
.expr
.v_optype
==OPTYPE_ADD
) {
2866 Type::typetype_t tmp_tt2
;
2868 Error_Context
cntxt(this, "In the right operand of operation `%s'",
2870 u
.expr
.v2
->set_lowerid_to_ref();
2871 tmp_tt2
=u
.expr
.v2
->get_expr_returntype(exp_val
);
2873 Type::typetype_t ret_val
=Type::T_ERROR
;
2874 bool maybeconcat
=false;
2879 if(tmp_tt2
==tmp_tt
) {
2886 if(tmp_tt2
==Type::T_CSTR
|| tmp_tt2
==Type::T_USTR
) {
2888 if(tmp_tt
==Type::T_USTR
|| tmp_tt2
==Type::T_USTR
)
2889 ret_val
=Type::T_USTR
;
2890 else ret_val
=Type::T_CSTR
;
2897 error("Did you mean the concat operation (`&') instead of"
2898 " addition operator (`+')?");
2899 u
.expr
.v_optype
=OPTYPE_CONCAT
;
2903 get_value_refd_last(); // to report the error
2904 return Type::T_ERROR
;
2907 case OPTYPE_NOT4B
: // v1
2908 case OPTYPE_AND4B
: // v1 v2
2913 Type::typetype_t tmp_tt
;
2915 Error_Context
cntxt(this, "In the %soperand of operation `%s'",
2916 u
.expr
.v_optype
==OPTYPE_NOT4B
?"":"left ",
2918 u
.expr
.v1
->set_lowerid_to_ref();
2919 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2927 get_value_refd_last(); // to report the error
2928 return Type::T_ERROR
;
2931 case OPTYPE_ROTL
: // v1 v2
2933 Type::typetype_t tmp_tt
;
2935 Error_Context
cntxt(this, "In the %s operand of operation `%s'",
2936 u
.expr
.v_optype
==OPTYPE_ROTL
2937 || u
.expr
.v_optype
==OPTYPE_ROTR
?"left":"first",
2939 u
.expr
.v1
->set_lowerid_to_ref();
2940 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
2953 get_value_refd_last(); // to report the error
2954 return Type::T_ERROR
;
2958 case OPTYPE_REPLACE
: {
2959 Type::typetype_t tmp_tt
;
2961 Error_Context
cntxt(this, "In the operand of operation `%s'",
2963 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2964 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2976 get_value_refd_last(); // to report the error
2977 return Type::T_ERROR
;
2980 case OPTYPE_REGEXP
: {
2981 Type::typetype_t tmp_tt
;
2983 Error_Context
cntxt(this, "In the first operand of operation `%s'",
2985 u
.expr
.ti1
->get_Template()->set_lowerid_to_ref();
2986 tmp_tt
= u
.expr
.ti1
->get_expr_returntype(Type::EXPECTED_TEMPLATE
);
2993 get_value_refd_last(); // to report the error
2994 return Type::T_ERROR
;
2997 case OPTYPE_CONCAT
: { // v1 v2
2998 Type::typetype_t tmp_tt
;
3000 Error_Context
cntxt(this, "In the first operand of operation `%s'",
3002 u
.expr
.v1
->set_lowerid_to_ref();
3003 tmp_tt
=u
.expr
.v1
->get_expr_returntype(exp_val
);
3015 get_value_refd_last(); // to report the error
3016 return Type::T_ERROR
;
3021 case OPTYPE_CHAR2INT
:
3022 case OPTYPE_UNICHAR2INT
:
3023 case OPTYPE_BIT2INT
:
3024 case OPTYPE_HEX2INT
:
3025 case OPTYPE_OCT2INT
:
3026 case OPTYPE_STR2INT
:
3027 case OPTYPE_FLOAT2INT
:
3028 case OPTYPE_LENGTHOF
:
3031 case OPTYPE_ENUM2INT
:
3033 case OPTYPE_BIT2STR
:
3034 case OPTYPE_FLOAT2STR
:
3035 case OPTYPE_HEX2STR
:
3036 case OPTYPE_INT2CHAR
:
3037 case OPTYPE_INT2STR
:
3038 case OPTYPE_OCT2CHAR
:
3039 case OPTYPE_OCT2STR
:
3040 case OPTYPE_UNICHAR2CHAR
:
3041 case OPTYPE_LOG2STR
:
3042 case OPTYPE_TESTCASENAME
:
3043 case OPTYPE_TTCN2STRING
:
3044 case OPTYPE_GET_STRINGENCODING
:
3045 case OPTYPE_ENCODE_BASE64
:
3046 return Type::T_CSTR
;
3047 case OPTYPE_INT2UNICHAR
:
3048 case OPTYPE_OCT2UNICHAR
:
3049 return Type::T_USTR
;
3050 case OPTYPE_INT2BIT
:
3051 case OPTYPE_HEX2BIT
:
3052 case OPTYPE_OCT2BIT
:
3053 case OPTYPE_STR2BIT
:
3055 return Type::T_BSTR
;
3056 case OPTYPE_INT2HEX
:
3057 case OPTYPE_BIT2HEX
:
3058 case OPTYPE_OCT2HEX
:
3059 case OPTYPE_STR2HEX
:
3060 return Type::T_HSTR
;
3061 case OPTYPE_INT2OCT
:
3062 case OPTYPE_CHAR2OCT
:
3063 case OPTYPE_HEX2OCT
:
3064 case OPTYPE_BIT2OCT
:
3065 case OPTYPE_STR2OCT
:
3066 case OPTYPE_UNICHAR2OCT
:
3067 case OPTYPE_REMOVE_BOM
:
3068 case OPTYPE_DECODE_BASE64
:
3069 return Type::T_OSTR
;
3073 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3075 return Type::T_ERROR
;
3079 case MACRO_MODULEID
:
3080 case MACRO_FILENAME
:
3081 case MACRO_BFILENAME
:
3082 case MACRO_FILEPATH
:
3083 case MACRO_LINENUMBER
:
3084 case MACRO_DEFINITIONID
:
3086 case MACRO_TESTCASEID
:
3087 return Type::T_CSTR
;
3088 case MACRO_LINENUMBER_C
:
3091 return Type::T_ERROR
;
3094 return Type::T_NULL
;
3096 return Type::T_BOOL
;
3100 return Type::T_REAL
;
3102 return Type::T_ENUM_T
;
3104 return Type::T_BSTR
;
3106 return Type::T_HSTR
;
3108 return Type::T_OSTR
;
3110 return Type::T_CSTR
;
3112 return Type::T_USTR
;
3114 return Type::T_GENERALSTRING
;
3118 return Type::T_ROID
;
3120 return Type::T_VERDICT
;
3121 case V_DEFAULT_NULL
:
3122 return Type::T_DEFAULT
;
3124 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3126 return Type::T_ERROR
;
3130 Type
* Value::get_expr_governor(Type::expected_value_t exp_val
)
3132 if(my_governor
) return my_governor
;
3133 switch (valuetype
) {
3135 Type
*t
= u
.invoke
.v
->get_expr_governor(exp_val
);
3137 if(u
.invoke
.v
->get_valuetype() != V_ERROR
)
3138 u
.invoke
.v
->error("A value of type function expected");
3141 t
= t
->get_type_refd_last();
3142 switch(t
->get_typetype()) {
3143 case Type::T_FUNCTION
: {
3144 Type
*t_return_type
= t
->get_function_return_type();
3145 if (!t_return_type
) {
3146 error("Reference to a %s was expected instead of invocation "
3147 "of behavior type `%s' with no return type",
3148 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3149 t
->get_fullname().c_str());
3152 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& t
->get_returns_template()) {
3153 error("Reference to a value was expected, but functions of type "
3154 "`%s' return a template of type `%s'", t
->get_typename().c_str(),
3155 t_return_type
->get_typename().c_str());
3158 return t_return_type
; }
3159 case Type::T_ALTSTEP
:
3162 u
.invoke
.v
->error("A value of type function expected instead of `%s'",
3163 t
->get_typename().c_str());
3168 Assignment
*ass
=u
.ref
.ref
->get_refd_assignment();
3170 if (!ass
) goto error
;
3171 switch (ass
->get_asstype()) {
3172 case Assignment::A_CONST
:
3173 case Assignment::A_EXT_CONST
:
3174 case Assignment::A_MODULEPAR
:
3175 case Assignment::A_MODULEPAR_TEMP
:
3176 case Assignment::A_TEMPLATE
:
3177 case Assignment::A_VAR
:
3178 case Assignment::A_VAR_TEMPLATE
:
3179 case Assignment::A_FUNCTION_RVAL
:
3180 case Assignment::A_FUNCTION_RTEMP
:
3181 case Assignment::A_EXT_FUNCTION_RVAL
:
3182 case Assignment::A_EXT_FUNCTION_RTEMP
:
3183 case Assignment::A_PAR_VAL_IN
:
3184 case Assignment::A_PAR_VAL_OUT
:
3185 case Assignment::A_PAR_VAL_INOUT
:
3186 case Assignment::A_PAR_TEMPL_IN
:
3187 case Assignment::A_PAR_TEMPL_OUT
:
3188 case Assignment::A_PAR_TEMPL_INOUT
:
3189 tmp_type
=ass
->get_Type();
3191 case Assignment::A_FUNCTION
:
3192 case Assignment::A_EXT_FUNCTION
:
3193 error("Reference to a %s was expected instead of a call of %s, which "
3194 "does not have return type",
3195 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3196 ass
->get_description().c_str());
3199 error("Reference to a %s was expected instead of %s",
3200 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
3201 ass
->get_description().c_str());
3204 tmp_type
=tmp_type
->get_field_type(u
.ref
.ref
->get_subrefs(), exp_val
);
3205 if(!tmp_type
) goto error
;
3208 switch (u
.expr
.v_optype
) {
3209 case OPTYPE_VALUEOF
:
3212 case OPTYPE_REPLACE
:{
3213 Type
*tmp_type
= u
.expr
.ti1
->get_expr_governor(exp_val
==
3214 Type::EXPECTED_DYNAMIC_VALUE
? Type::EXPECTED_TEMPLATE
: exp_val
);
3215 if(tmp_type
) tmp_type
= tmp_type
->get_type_refd_last();
3220 return u
.expr
.v1
->get_expr_governor(exp_val
);
3222 return get_expr_governor_v1v2(exp_val
);
3223 case OPTYPE_COMP_MTC
:
3224 if (my_scope
) return my_scope
->get_mtc_system_comptype(false);
3226 case OPTYPE_COMP_SYSTEM
:
3227 if (my_scope
) return my_scope
->get_mtc_system_comptype(true);
3229 case OPTYPE_COMP_SELF
:
3231 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
3232 if (t_ros
) return t_ros
->get_component_type();
3235 case OPTYPE_COMP_CREATE
:
3236 return chk_expr_operand_comptyperef_create();
3242 return Type::get_pooltype(get_expr_returntype(exp_val
));
3245 set_valuetype(V_ERROR
);
3249 Type
* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val
)
3251 Type
* v1_gov
= u
.expr
.v1
->get_expr_governor(exp_val
);
3252 Type
* v2_gov
= u
.expr
.v2
->get_expr_governor(exp_val
);
3254 if (v2_gov
) { // both have governors
3255 // return the type that is compatible with both (if there is no type mismatch)
3256 if (v1_gov
->is_compatible(v2_gov
, NULL
))
3259 } else return v1_gov
;
3260 } else { // v1 has no governor
3261 if (v2_gov
) return v2_gov
;
3262 else return NULL
; // neither has governor
3266 Type
*Value::get_expr_governor_last()
3268 Value
*v_last
= get_value_refd_last();
3269 if (v_last
->valuetype
== V_ERROR
) return 0;
3270 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_TEMPLATE
);
3272 return t
->get_type_refd_last();
3275 Type
*Value::get_invoked_type(Type::expected_value_t exp_val
)
3277 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::get_invoked_type()");
3278 return u
.invoke
.v
->get_expr_governor(exp_val
);
3281 const char* Value::get_opname() const
3283 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::get_opname()");
3284 switch(u
.expr
.v_optype
) {
3285 case OPTYPE_RND
: // -
3287 case OPTYPE_COMP_NULL
:
3288 return "(component) null";
3289 case OPTYPE_COMP_MTC
:
3291 case OPTYPE_COMP_SYSTEM
:
3293 case OPTYPE_COMP_SELF
:
3295 case OPTYPE_COMP_RUNNING_ANY
:
3296 return "any component.running";
3297 case OPTYPE_COMP_RUNNING_ALL
:
3298 return "all component.running";
3299 case OPTYPE_COMP_ALIVE_ANY
:
3300 return "any component.alive";
3301 case OPTYPE_COMP_ALIVE_ALL
:
3302 return "all component.alive";
3303 case OPTYPE_TMR_RUNNING_ANY
:
3304 return "any timer.running";
3305 case OPTYPE_GETVERDICT
:
3306 return "getverdict()";
3307 case OPTYPE_TESTCASENAME
:
3308 return "testcasename()";
3309 case OPTYPE_UNARYPLUS
: // v1
3311 case OPTYPE_UNARYMINUS
:
3317 case OPTYPE_BIT2HEX
:
3319 case OPTYPE_BIT2INT
:
3321 case OPTYPE_BIT2OCT
:
3323 case OPTYPE_BIT2STR
:
3325 case OPTYPE_CHAR2INT
:
3326 return "char2int()";
3327 case OPTYPE_CHAR2OCT
:
3328 return "char2oct()";
3329 case OPTYPE_FLOAT2INT
:
3330 return "float2int()";
3331 case OPTYPE_FLOAT2STR
:
3332 return "float2str()";
3333 case OPTYPE_HEX2BIT
:
3335 case OPTYPE_HEX2INT
:
3337 case OPTYPE_HEX2OCT
:
3339 case OPTYPE_HEX2STR
:
3341 case OPTYPE_INT2CHAR
:
3342 return "int2char()";
3343 case OPTYPE_INT2FLOAT
:
3344 return "int2float()";
3345 case OPTYPE_INT2STR
:
3347 case OPTYPE_INT2UNICHAR
:
3348 return "int2unichar()";
3349 case OPTYPE_OCT2BIT
:
3351 case OPTYPE_OCT2CHAR
:
3352 return "oct2char()";
3353 case OPTYPE_OCT2HEX
:
3355 case OPTYPE_OCT2INT
:
3357 case OPTYPE_OCT2STR
:
3359 case OPTYPE_STR2BIT
:
3361 case OPTYPE_STR2FLOAT
:
3362 return "str2float()";
3363 case OPTYPE_STR2HEX
:
3365 case OPTYPE_STR2INT
:
3367 case OPTYPE_STR2OCT
:
3369 case OPTYPE_UNICHAR2INT
:
3370 return "unichar2int()";
3371 case OPTYPE_UNICHAR2CHAR
:
3372 return "unichar2char()";
3373 case OPTYPE_UNICHAR2OCT
:
3374 return "unichar2oct()";
3375 case OPTYPE_ENUM2INT
:
3376 return "enum2int()";
3377 case OPTYPE_LENGTHOF
:
3378 return "lengthof()";
3381 case OPTYPE_RNDWITHVAL
:
3382 return "rnd (seed)";
3384 return "encvalue()";
3386 return "decvalue()";
3387 case OPTYPE_GET_STRINGENCODING
:
3388 return "get_stringencoding()";
3389 case OPTYPE_REMOVE_BOM
:
3390 return "remove_bom()";
3391 case OPTYPE_ENCODE_BASE64
:
3392 return "encode_base64()";
3393 case OPTYPE_DECODE_BASE64
:
3394 return "decode_base64()";
3395 case OPTYPE_ADD
: // v1 v2
3397 case OPTYPE_SUBTRACT
:
3399 case OPTYPE_MULTIPLY
:
3441 case OPTYPE_INT2BIT
:
3443 case OPTYPE_INT2HEX
:
3445 case OPTYPE_INT2OCT
:
3447 case OPTYPE_OCT2UNICHAR
:
3448 return "oct2unichar()";
3455 case OPTYPE_REPLACE
:
3457 case OPTYPE_VALUEOF
: // t1
3459 case OPTYPE_UNDEF_RUNNING
:
3460 return "<timer or component> running";
3461 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
3463 case OPTYPE_COMP_RUNNING
: // v1
3464 return "component running";
3465 case OPTYPE_COMP_ALIVE
: // v1
3467 case OPTYPE_TMR_READ
:
3468 return "timer read";
3469 case OPTYPE_TMR_RUNNING
:
3470 return "timer running";
3471 case OPTYPE_ACTIVATE
:
3472 return "activate()";
3473 case OPTYPE_ACTIVATE_REFD
:
3474 return "activate()";
3475 case OPTYPE_EXECUTE
: // r1 [v2]
3476 case OPTYPE_EXECUTE_REFD
:
3478 case OPTYPE_MATCH
: // v1 t2
3480 case OPTYPE_ISPRESENT
:
3481 return "ispresent()";
3482 case OPTYPE_ISCHOSEN
:
3483 case OPTYPE_ISCHOSEN_V
:
3484 case OPTYPE_ISCHOSEN_T
:
3485 return "ischosen()";
3486 case OPTYPE_ISVALUE
:
3488 case OPTYPE_ISBOUND
:
3490 case OPTYPE_LOG2STR
:
3492 case OPTYPE_TTCN2STRING
:
3493 return "ttcn2string()";
3494 case OPTYPE_PROF_RUNNING
:
3495 return "@profiler.running";
3497 FATAL_ERROR("Value::get_opname()");
3501 void Value::chk_expr_ref_ischosen()
3503 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
3504 Ttcn::Ref_base
*tmpref
=u
.expr
.r1
;
3505 Assignment
*ass
=tmpref
->get_refd_assignment();
3507 set_valuetype(V_ERROR
);
3510 // Now we know whether the argument of ischosen() is a value or template.
3511 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3512 // or template (OPTYPE_ISCHOSEN_T).
3513 switch (ass
->get_asstype()) {
3514 case Assignment::A_CONST
:
3515 case Assignment::A_EXT_CONST
:
3516 case Assignment::A_MODULEPAR
:
3517 case Assignment::A_VAR
:
3518 case Assignment::A_PAR_VAL_IN
:
3519 case Assignment::A_PAR_VAL_OUT
:
3520 case Assignment::A_PAR_VAL_INOUT
:
3521 u
.expr
.v1
=new Value(V_REFD
, tmpref
);
3522 u
.expr
.v1
->set_location(*tmpref
);
3523 u
.expr
.v1
->set_my_scope(get_my_scope());
3524 u
.expr
.v1
->set_fullname(get_fullname()+".<operand>");
3525 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_V
;
3527 case Assignment::A_MODULEPAR_TEMP
:
3528 case Assignment::A_TEMPLATE
:
3529 case Assignment::A_VAR_TEMPLATE
:
3530 case Assignment::A_PAR_TEMPL_IN
:
3531 case Assignment::A_PAR_TEMPL_OUT
:
3532 case Assignment::A_PAR_TEMPL_INOUT
:
3533 u
.expr
.t1
=new Template(tmpref
); // TEMPLATE_REFD constructor
3534 u
.expr
.t1
->set_location(*tmpref
);
3535 u
.expr
.t1
->set_my_scope(get_my_scope());
3536 u
.expr
.t1
->set_fullname(get_fullname()+".<operand>");
3537 u
.expr
.v_optype
=OPTYPE_ISCHOSEN_T
;
3540 tmpref
->error("Reference to a value or template was expected instead of "
3541 "%s", ass
->get_description().c_str());
3542 set_valuetype(V_ERROR
);
3547 void Value::chk_expr_operandtype_enum(const char *opname
, Value
*v
,
3548 Type::expected_value_t exp_val
)
3550 v
->set_lowerid_to_ref(); // can only be reference to enum
3551 Type
*t
= v
->get_expr_governor(exp_val
);
3552 if (v
->valuetype
==V_ERROR
) return;
3554 v
->error("Please use reference to an enumerated value as the operand of "
3555 "operation `%s'", get_opname());
3556 set_valuetype(V_ERROR
);
3559 t
= t
->get_type_refd_last();
3560 if (t
->get_typetype()!=Type::T_ENUM_A
&& t
->get_typetype()!=Type::T_ENUM_T
) {
3561 v
->error("The operand of operation `%s' should be enumerated value", opname
);
3562 set_valuetype(V_ERROR
);
3564 if (v
->get_value_refd_last()->valuetype
==V_OMIT
) {
3565 v
->error("The operand of operation `%s' cannot be omit", opname
);
3566 set_valuetype(V_ERROR
);
3570 void Value::chk_expr_operandtype_bool(Type::typetype_t tt
,
3573 const Location
*loc
)
3575 if(tt
==Type::T_BOOL
) return;
3576 if(tt
!=Type::T_ERROR
)
3577 loc
->error("%s operand of operation `%s' should be boolean value",
3579 set_valuetype(V_ERROR
);
3582 void Value::chk_expr_operandtype_int(Type::typetype_t tt
,
3585 const Location
*loc
)
3587 if(tt
==Type::T_INT
) return;
3588 if(tt
!=Type::T_ERROR
)
3589 loc
->error("%s operand of operation `%s' should be integer value",
3591 set_valuetype(V_ERROR
);
3594 void Value::chk_expr_operandtype_float(Type::typetype_t tt
,
3597 const Location
*loc
)
3599 if(tt
==Type::T_REAL
) return;
3600 else if(tt
==Type::T_INT
)
3601 loc
->error("%s operand of operation `%s' should be float value."
3602 " Perhaps you missed an int2float() conversion function"
3603 " or `.0' at the end of the number",
3605 else if(tt
!=Type::T_ERROR
)
3606 loc
->error("%s operand of operation `%s' should be float value",
3608 set_valuetype(V_ERROR
);
3611 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt
,
3614 const Location
*loc
)
3623 if(tt
!=Type::T_ERROR
)
3624 loc
->error("%s operand of operation `%s' should be integer"
3627 set_valuetype(V_ERROR
);
3630 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt
,
3633 const Location
*loc
)
3638 case Type::T_ENUM_T
:
3643 if(tt
!=Type::T_ERROR
)
3644 loc
->error("%s operand of operation `%s' should be integer, float"
3645 " or enumerated value", opnum
, opname
);
3646 set_valuetype(V_ERROR
);
3649 void Value::chk_expr_operandtype_list(Type
* t
,
3652 const Location
*loc
,
3655 if (valuetype
== V_ERROR
) return;
3656 if (t
->get_typetype() == Type::T_ERROR
) {
3657 set_valuetype(V_ERROR
);
3660 if (!t
->is_list_type(allow_array
)) {
3661 loc
->error("%s operand of operation `%s' should be a string, "
3662 "`record of'%s `set of'%s value", opnum
, opname
,
3663 allow_array
? "," : " or", allow_array
? " or array" : "");
3664 set_valuetype(V_ERROR
);
3667 TypeCompatInfo
info(my_scope
->get_scope_mod(), my_governor
, t
, true,
3668 u
.expr
.v_optype
== OPTYPE_LENGTHOF
); // The only outsider.
3671 if (my_governor
&& my_governor
->is_list_type(allow_array
)
3672 && !my_governor
->is_compatible(t
, &info
, &l_chain
, &r_chain
)) {
3673 if (info
.is_subtype_error()) {
3675 if (info
.needs_conversion()) set_needs_conversion();
3677 if (!info
.is_erroneous()) {
3678 error("%s operand of operation `%s' is of type `%s', but a value of "
3679 "type `%s' was expected here", opnum
, opname
,
3680 t
->get_typename().c_str(), my_governor
->get_typename().c_str());
3682 error("%s", info
.get_error_str_str().c_str());
3685 if (info
.needs_conversion())
3686 set_needs_conversion();
3690 void Value::chk_expr_operandtype_str(Type::typetype_t tt
,
3693 const Location
*loc
)
3705 if(tt
!=Type::T_ERROR
)
3706 loc
->error("%s operand of operation `%s' should be string value",
3708 set_valuetype(V_ERROR
);
3711 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt
,
3714 const Location
*loc
)
3723 if(tt
!=Type::T_ERROR
)
3724 loc
->error("%s operand of operation `%s' should be (universal)"
3725 " charstring value",
3727 set_valuetype(V_ERROR
);
3730 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt
,
3733 const Location
*loc
)
3735 if(tt
==Type::T_CSTR
) return;
3736 if(tt
!=Type::T_ERROR
)
3737 loc
->error("%s operand of operation `%s' should be charstring value",
3739 set_valuetype(V_ERROR
);
3742 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt
,
3745 const Location
*loc
)
3755 if(tt
!=Type::T_ERROR
)
3756 loc
->error("%s operand of operation `%s' should be binary string value",
3758 set_valuetype(V_ERROR
);
3761 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt
,
3764 const Location
*loc
)
3766 if(tt
==Type::T_BSTR
) return;
3767 if(tt
!=Type::T_ERROR
)
3768 loc
->error("%s operand of operation `%s' should be bitstring value",
3770 set_valuetype(V_ERROR
);
3773 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt
,
3776 const Location
*loc
)
3778 if(tt
==Type::T_HSTR
) return;
3779 if(tt
!=Type::T_ERROR
)
3780 loc
->error("%s operand of operation `%s' should be hexstring value",
3782 set_valuetype(V_ERROR
);
3785 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt
,
3788 const Location
*loc
)
3790 if(tt
==Type::T_OSTR
) return;
3791 if(tt
!=Type::T_ERROR
)
3792 loc
->error("%s operand of operation `%s' should be octetstring value",
3794 set_valuetype(V_ERROR
);
3797 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1
,
3798 Type::typetype_t tt2
,
3801 if(valuetype
==V_ERROR
) return;
3802 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3803 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3804 set_valuetype(V_ERROR
);
3807 if(tt1
==tt2
) return;
3808 error("The operands of operation `%s' should be of same type", opname
);
3809 set_valuetype(V_ERROR
);
3812 /* For predefined functions. */
3813 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1
,
3814 Type::typetype_t tt2
,
3819 if(valuetype
==V_ERROR
) return;
3820 if(tt1
==Type::T_ERROR
|| tt2
==Type::T_ERROR
) {
3821 set_valuetype(V_ERROR
);
3824 if(tt1
==tt2
) return;
3825 error("The %s and %s operands of operation `%s' should be of same type",
3826 opnum1
, opnum2
, opname
);
3827 set_valuetype(V_ERROR
);
3830 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val
,
3831 Value
*v1
, Value
*v2
,
3836 if (valuetype
== V_ERROR
) return;
3837 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3838 Type::typetype_t tt1
= v1
->get_expr_returntype(exp_val
);
3839 Type::typetype_t tt2
= v2
->get_expr_returntype(exp_val
);
3841 if (tt1
== Type::T_ERROR
|| tt2
== Type::T_ERROR
) {
3842 set_valuetype(V_ERROR
);
3845 if (tt1
== Type::T_UNDEF
) {
3846 if (tt2
== Type::T_UNDEF
) {
3847 if (v1
->is_undef_lowerid()) {
3848 if (v2
->is_undef_lowerid()) {
3849 Scope
*scope
= get_my_scope();
3850 Module
*my_mod
= scope
->get_scope_mod();
3851 const Identifier
& id1
= v1
->get_undef_lowerid();
3852 if (scope
->has_ass_withId(id1
)
3853 || my_mod
->has_imported_ass_withId(id1
)) {
3854 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3855 * should examine this situation better, but now I suppose
3856 * the first is ref, not enum. */
3857 v1
->set_lowerid_to_ref();
3860 const Identifier
& id2
= v2
->get_undef_lowerid();
3861 if (scope
->has_ass_withId(id2
)
3862 || my_mod
->has_imported_ass_withId(id2
)) {
3863 v2
->set_lowerid_to_ref();
3867 /* This is perhaps enum-enum, but it has no real
3868 * significance, so this should be an error. */
3870 v1
->set_lowerid_to_ref();
3873 } else if (v2
->is_undef_lowerid()) {
3874 v2
->set_lowerid_to_ref();
3877 error("Cannot determine the type of the operands in operation `%s'",
3879 set_valuetype(V_ERROR
);
3881 } else if (v1
->is_undef_lowerid() && tt2
!= Type::T_ENUM_T
) {
3882 v1
->set_lowerid_to_ref();
3885 /* v1 is something undefined, but not lowerid; v2 has
3886 * returntype (perhaps also governor) */
3888 } else if (tt2
== Type::T_UNDEF
) {
3889 /* but tt1 is not undef */
3890 if (v2
->is_undef_lowerid() && tt1
!= Type::T_ENUM_T
) {
3891 v2
->set_lowerid_to_ref();
3894 /* v2 is something undefined, but not lowerid; v1 has
3895 * returntype (perhaps also governor) */
3899 /* Now undef_lower_id's are converted to references, or the other
3900 * value has governor; let's see the governors, if they exist. */
3901 Type
*t1
= v1
->get_expr_governor(exp_val
);
3902 Type
*t2
= v2
->get_expr_governor(exp_val
);
3905 // Both value has governor. Are they compatible? According to 7.1.2
3906 // and C.34 it's required to have the same root types for
3907 // OPTYPE_{CONCAT,REPLACE}.
3908 TypeCompatInfo
info1(my_scope
->get_scope_mod(), t1
, t2
, true,
3909 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3910 TypeCompatInfo
info2(my_scope
->get_scope_mod(), t2
, t1
, true,
3911 u
.expr
.v_optype
== OPTYPE_REPLACE
);
3912 TypeChain l_chain1
, l_chain2
;
3913 TypeChain r_chain1
, r_chain2
;
3914 bool compat_t1
= t1
->is_compatible(t2
, &info1
, &l_chain1
, &r_chain1
);
3915 bool compat_t2
= t2
->is_compatible(t1
, &info2
, &l_chain2
, &r_chain2
);
3916 if (!compat_t1
&& !compat_t2
) {
3917 if (!info1
.is_erroneous() && !info2
.is_erroneous()) {
3918 // the subtypes don't need to be compatible here
3919 if (!info1
.is_subtype_error() && !info2
.is_subtype_error()) {
3920 error("The operands of operation `%s' should be of compatible "
3921 "types", get_opname());
3922 set_valuetype(V_ERROR
);
3924 if (info1
.needs_conversion() || info2
.needs_conversion()) {
3925 set_needs_conversion(); // Avoid folding.
3930 if (info1
.is_erroneous())
3931 v1
->error("%s", info1
.get_error_str_str().c_str());
3932 else if (info2
.is_erroneous())
3933 v2
->error("%s", info2
.get_error_str_str().c_str());
3934 set_valuetype(V_ERROR
);
3937 } else if (info1
.needs_conversion() || info2
.needs_conversion()) {
3938 set_needs_conversion(); // Avoid folding.
3943 v2
->set_my_governor(t1
);
3944 t1
->chk_this_value_ref(v2
);
3945 if (v2
->valuetype
== V_OMIT
) {
3946 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3948 v1
->chk_expr_omit_comparison(exp_val
);
3950 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3952 (void)t1
->chk_this_value(v2
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3953 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3958 v1
->set_my_governor(t2
);
3959 t2
->chk_this_value_ref(v1
);
3960 if (v1
->valuetype
== V_OMIT
) {
3961 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum2
,
3963 v2
->chk_expr_omit_comparison(exp_val
);
3965 Error_Context
cntxt(this, "In %s operand of operation `%s'", opnum1
,
3967 (void)t2
->chk_this_value(v1
, 0, exp_val
, INCOMPLETE_NOT_ALLOWED
,
3968 OMIT_NOT_ALLOWED
, NO_SUB_CHK
);
3972 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3973 if (tt1
== Type::T_UNDEF
|| tt2
== Type::T_UNDEF
) {
3974 // Here, it cannot be that both are T_UNDEF.
3975 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3976 error("Please use reference as %s operand of operator `%s'",
3977 tt1
== Type::T_UNDEF
? opnum1
: opnum2
, get_opname());
3978 set_valuetype(V_ERROR
);
3981 // Deny type compatibility if no governors found. The typetype_t must
3982 // be the same. TODO: How can this happen?
3983 if (!Type::is_compatible_tt_tt(tt1
, tt2
, false, false)
3984 && !Type::is_compatible_tt_tt(tt2
, tt1
, false, false)) {
3985 error("The operands of operation `%s' should be of compatible types",
3987 set_valuetype(V_ERROR
);
3992 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val
,
3993 Ttcn::Ref_base
*ref
, const char *opnum
, const char *opname
)
3995 if(valuetype
==V_ERROR
) return;
3996 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3997 Assignment
*t_ass
= ref
->get_refd_assignment();
3998 if(!t_ass
) goto error
;
3999 switch(t_ass
->get_asstype()) {
4000 case Assignment::A_TIMER
:
4001 case Assignment::A_PAR_TIMER
:
4002 u
.expr
.v_optype
=OPTYPE_TMR_RUNNING
;
4003 chk_expr_operand_tmrref(u
.expr
.r1
, opnum
, get_opname());
4004 chk_expr_dynamic_part(exp_val
, true);
4006 case Assignment::A_CONST
:
4007 case Assignment::A_EXT_CONST
:
4008 case Assignment::A_MODULEPAR
:
4009 case Assignment::A_VAR
:
4010 case Assignment::A_FUNCTION_RVAL
:
4011 case Assignment::A_EXT_FUNCTION_RVAL
:
4012 case Assignment::A_PAR_VAL_IN
:
4013 case Assignment::A_PAR_VAL_OUT
:
4014 case Assignment::A_PAR_VAL_INOUT
: {
4015 u
.expr
.v_optype
= OPTYPE_COMP_RUNNING
;
4016 Value
* val
= new Value(V_REFD
, u
.expr
.r1
);
4017 val
->set_my_scope(my_scope
);
4018 val
->set_fullname(u
.expr
.r1
->get_fullname());
4019 val
->set_location(*u
.expr
.r1
);
4021 chk_expr_operand_compref(val
, opnum
, get_opname());
4022 chk_expr_dynamic_part(exp_val
, false);
4025 ref
->error("%s operand of operation `%s' should be timer or"
4026 " component reference instead of %s",
4027 opnum
, opname
, t_ass
->get_description().c_str());
4032 set_valuetype(V_ERROR
);
4035 Type
*Value::chk_expr_operand_comptyperef_create()
4037 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_COMP_CREATE
)
4038 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4039 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
4040 if (!t_ass
) goto error
;
4041 if (t_ass
->get_asstype() == Assignment::A_TYPE
) {
4042 Type
*t_type
= t_ass
->get_Type()->get_field_type(u
.expr
.r1
->get_subrefs(),
4043 Type::EXPECTED_DYNAMIC_VALUE
);
4044 if (!t_type
) goto error
;
4045 t_type
= t_type
->get_type_refd_last();
4046 if (t_type
->get_typetype() == Type::T_COMPONENT
) {
4048 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4049 if (my_governor_last
->get_typetype() == Type::T_COMPONENT
&&
4050 !my_governor_last
->is_compatible(t_type
, NULL
)) {
4051 u
.expr
.r1
->error("Incompatible component types: operation "
4052 "`create' should refer to `%s' instead of "
4054 my_governor_last
->get_typename().c_str(),
4055 t_type
->get_typename().c_str());
4061 u
.expr
.r1
->error("Type mismatch: reference to a component type was "
4062 "expected in operation `create' instead of `%s'",
4063 t_type
->get_typename().c_str());
4066 u
.expr
.r1
->error("Operation `create' should refer to a component type "
4067 "instead of %s", t_ass
->get_description().c_str());
4070 set_valuetype(V_ERROR
);
4074 void Value::chk_expr_comptype_compat()
4076 if (valuetype
!= V_EXPR
)
4077 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4078 if (!my_governor
|| !my_scope
) return;
4079 Type
*my_governor_last
= my_governor
->get_type_refd_last();
4080 if (my_governor_last
->get_typetype() != Type::T_COMPONENT
) return;
4082 switch (u
.expr
.v_optype
) {
4083 case OPTYPE_COMP_MTC
:
4084 t_comptype
= my_scope
->get_mtc_system_comptype(false);
4086 case OPTYPE_COMP_SYSTEM
:
4087 t_comptype
= my_scope
->get_mtc_system_comptype(true);
4089 case OPTYPE_COMP_SELF
: {
4090 Ttcn::RunsOnScope
*t_ros
= my_scope
->get_scope_runs_on();
4091 t_comptype
= t_ros
? t_ros
->get_component_type() : 0;
4094 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4099 && !my_governor_last
->is_compatible(t_comptype
, NULL
)) {
4100 error("Incompatible component types: a component reference of "
4101 "type `%s' was expected, but `%s' has type `%s'",
4102 my_governor_last
->get_typename().c_str(), get_opname(),
4103 t_comptype
->get_typename().c_str());
4104 set_valuetype(V_ERROR
);
4108 void Value::chk_expr_operand_compref(Value
*val
, const char *opnum
,
4111 if(valuetype
== V_ERROR
) return;
4112 switch(val
->get_valuetype()) {
4114 Error_Context
cntxt(this, "In `%s' operation", opname
);
4115 Value
*v_last
= val
->get_value_refd_last();
4116 if(!v_last
) goto error
;
4117 Type
*t
= v_last
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
4119 t
= t
->get_type_refd_last();
4120 if(t
->get_typetype() != Type::T_COMPONENT
) {
4121 v_last
->error("%s operand of operation `%s': Type mismatch:"
4122 " component reference was expected instead of `%s'",
4123 opnum
, opname
, t
->get_typename().c_str());
4128 Reference
*ref
= val
->get_reference();
4129 Assignment
*t_ass
= ref
->get_refd_assignment();
4131 if (!t_ass
) goto error
;
4132 switch(t_ass
->get_asstype()) {
4133 case Assignment::A_CONST
:
4134 t_val
= t_ass
->get_Value();
4136 case Assignment::A_EXT_CONST
:
4137 case Assignment::A_MODULEPAR
:
4138 case Assignment::A_VAR
:
4139 case Assignment::A_FUNCTION_RVAL
:
4140 case Assignment::A_EXT_FUNCTION_RVAL
:
4141 case Assignment::A_PAR_VAL_IN
:
4142 case Assignment::A_PAR_VAL_OUT
:
4143 case Assignment::A_PAR_VAL_INOUT
: {
4144 Type
*t_type
=t_ass
->get_Type()
4145 ->get_field_type(ref
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
);
4146 if(!t_type
) goto error
;
4147 t_type
=t_type
->get_type_refd_last();
4148 if(t_type
->get_typetype()!=Type::T_COMPONENT
) {
4149 ref
->error("%s operand of operation `%s': Type mismatch:"
4150 " component reference was expected instead of `%s'",
4151 opnum
, opname
, t_type
->get_typename().c_str());
4156 ref
->error("%s operand of operation `%s' should be"
4157 " component reference instead of %s",
4158 opnum
, opname
, t_ass
->get_description().c_str());
4162 ReferenceChain
refch(this, "While searching referenced value");
4163 t_val
= t_val
->get_refd_sub_value(ref
->get_subrefs(), 0, false, &refch
);
4165 t_val
= t_val
->get_value_refd_last();
4166 if (t_val
->valuetype
!= V_EXPR
) return;
4167 switch (t_val
->u
.expr
.v_optype
) {
4168 case OPTYPE_COMP_NULL
:
4169 ref
->error("%s operand of operation `%s' refers to `null' component "
4170 "reference", opnum
, opname
);
4172 case OPTYPE_COMP_MTC
:
4173 ref
->error("%s operand of operation `%s' refers to the component "
4174 "reference of the `mtc'", opnum
, opname
);
4176 case OPTYPE_COMP_SYSTEM
:
4177 ref
->error("%s operand of operation `%s' refers to the component "
4178 "reference of the `system'", opnum
, opname
);
4186 FATAL_ERROR("Value::chk_expr_operand_compref()");
4189 set_valuetype(V_ERROR
);
4192 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base
*ref
,
4196 if(valuetype
==V_ERROR
) return;
4197 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4198 Assignment
*t_ass
= ref
->get_refd_assignment();
4199 if(!t_ass
) goto error
;
4200 switch(t_ass
->get_asstype()) {
4201 case Assignment::A_TIMER
: {
4202 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
4203 if (t_dims
) t_dims
->chk_indices(ref
, "timer", false,
4204 Type::EXPECTED_DYNAMIC_VALUE
);
4205 else if (ref
->get_subrefs()) {
4206 ref
->error("%s operand of operation `%s': "
4207 "Reference to single timer `%s' cannot have field or array "
4208 "sub-references", opnum
, opname
,
4209 t_ass
->get_id().get_dispname().c_str());
4213 case Assignment::A_PAR_TIMER
:
4214 if (ref
->get_subrefs()) {
4215 ref
->error("%s operand of operation `%s': "
4216 "Reference to %s cannot have field or array sub-references",
4217 opnum
, opname
, t_ass
->get_description().c_str());
4222 ref
->error("%s operand of operation `%s' should be timer"
4224 opnum
, opname
, t_ass
->get_description().c_str());
4229 set_valuetype(V_ERROR
);
4232 void Value::chk_expr_operand_activate(Ttcn::Ref_base
*ref
,
4236 if(valuetype
==V_ERROR
) return;
4237 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4238 Ttcn::Ref_pard
*t_ref_pard
= dynamic_cast<Ttcn::Ref_pard
*>(ref
);
4239 if (!t_ref_pard
) FATAL_ERROR("Value::chk_expr_operand_activate()");
4240 Error_Context
cntxt(this, "In `%s' operation", opname
);
4241 if (!t_ref_pard
->chk_activate_argument()) set_valuetype(V_ERROR
);
4244 void Value::chk_expr_operand_activate_refd(Value
*val
,
4245 Ttcn::TemplateInstances
* t_list2
,
4246 Ttcn::ActualParList
*&parlist
,
4250 if(valuetype
==V_ERROR
) return;
4251 Error_Context
cntxt(this, "In `%s' operation", opname
);
4252 Type
*t
= val
->get_expr_governor_last();
4254 switch (t
->get_typetype()) {
4256 set_valuetype(V_ERROR
);
4258 case Type::T_ALTSTEP
: {
4259 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4260 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4264 set_valuetype(V_ERROR
);
4266 parlist
->set_fullname(get_fullname());
4267 parlist
->set_my_scope(get_my_scope());
4268 if (!fp_list
->chk_activate_argument(parlist
,
4269 get_stringRepr().c_str())) set_valuetype(V_ERROR
);
4273 error("Reference to an altstep was expected in the argument of "
4274 "`derefers()' instead of `%s'", t
->get_typename().c_str());
4275 set_valuetype(V_ERROR
);
4278 } else set_valuetype(V_ERROR
);
4281 void Value::chk_expr_operand_execute(Ttcn::Ref_base
*ref
, Value
*val
,
4285 if(valuetype
==V_ERROR
) return;
4286 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4287 Error_Context
cntxt(this, "In `%s' operation", opname
);
4288 Assignment
*t_ass
= ref
->get_refd_assignment();
4289 bool error_flag
= false;
4291 if (t_ass
->get_asstype() != Common::Assignment::A_TESTCASE
) {
4292 ref
->error("Reference to a testcase was expected in the argument "
4293 "instead of %s", t_ass
->get_description().c_str());
4296 } else error_flag
= true;
4298 val
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4299 Value
*v_last
= val
->get_value_refd_last();
4300 switch (v_last
->valuetype
) {
4302 ttcn3float v_real
= v_last
->get_val_Real();
4304 val
->error("The testcase guard timer has negative value: `%s'",
4305 Real2string(v_real
).c_str());
4316 if (error_flag
) set_valuetype(V_ERROR
);
4319 void Value::chk_expr_operand_execute_refd(Value
*v1
,
4320 Ttcn::TemplateInstances
* t_list2
,
4321 Ttcn::ActualParList
*&parlist
,
4326 if(valuetype
==V_ERROR
) return;
4327 Error_Context
cntxt(this, "In `%s' operation", opname
);
4328 Type
*t
= v1
->get_expr_governor_last();
4330 switch (t
->get_typetype()) {
4332 set_valuetype(V_ERROR
);
4334 case Type::T_TESTCASE
: {
4335 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4336 bool is_erroneous
= fp_list
->chk_actual_parlist(t_list2
, parlist
);
4340 set_valuetype(V_ERROR
);
4342 parlist
->set_fullname(get_fullname());
4343 parlist
->set_my_scope(get_my_scope());
4347 v1
->error("Reference to a value of type testcase was expected in the "
4348 "argument of `derefers()' instead of `%s'",
4349 t
->get_typename().c_str());
4350 set_valuetype(V_ERROR
);
4353 } else set_valuetype(V_ERROR
);
4355 v3
->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE
);
4356 Value
*v_last
= v3
->get_value_refd_last();
4357 switch (v_last
->valuetype
) {
4359 ttcn3float v_real
= v_last
->get_val_Real();
4361 v3
->error("The testcase guard timer has negative value: `%s'",
4362 Real2string(v_real
).c_str());
4363 set_valuetype(V_ERROR
);
4367 set_valuetype(V_ERROR
);
4375 void Value::chk_invoke(Type::expected_value_t exp_val
)
4377 if(valuetype
== V_ERROR
) return;
4378 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::chk_invoke()");
4379 if(!u
.invoke
.t_list
) return; //already checked
4380 Error_Context
cntxt(this, "In `apply()' operation");
4381 Type
*t
= u
.invoke
.v
->get_expr_governor_last();
4383 set_valuetype(V_ERROR
);
4386 switch (t
->get_typetype()) {
4388 set_valuetype(V_ERROR
);
4390 case Type::T_FUNCTION
:
4393 u
.invoke
.v
->error("A value of type function was expected in the "
4394 "argument instead of `%s'", t
->get_typename().c_str());
4395 set_valuetype(V_ERROR
);
4398 my_scope
->chk_runs_on_clause(t
, *this, "call");
4399 Ttcn::FormalParList
*fp_list
= t
->get_fat_parameters();
4400 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
4401 bool is_erroneous
= fp_list
->fold_named_and_chk(u
.invoke
.t_list
, parlist
);
4402 delete u
.invoke
.t_list
;
4403 u
.invoke
.t_list
= 0;
4406 u
.invoke
.ap_list
= 0;
4408 parlist
->set_fullname(get_fullname());
4409 parlist
->set_my_scope(get_my_scope());
4410 u
.invoke
.ap_list
= parlist
;
4413 case Type::EXPECTED_CONSTANT
:
4414 error("An evaluable constant value was expected instead of operation "
4416 set_valuetype(V_ERROR
);
4418 case Type::EXPECTED_STATIC_VALUE
:
4419 error("A static value was expected instead of operation `apply()'");
4420 set_valuetype(V_ERROR
);
4427 void Value::chk_expr_eval_value(Value
*val
, Type
&t
,
4428 ReferenceChain
*refch
,
4429 Type::expected_value_t exp_val
)
4431 bool self_ref
= false;
4432 if(valuetype
==V_ERROR
) return;
4433 // Commented out to report more errors :)
4434 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4435 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4436 switch(val
->get_valuetype()) {
4438 self_ref
= t
.chk_this_refd_value(val
, 0, exp_val
, refch
);
4443 val
->get_value_refd_last(refch
, exp_val
);
4448 if(val
->get_valuetype()==V_ERROR
) set_valuetype(V_ERROR
);
4453 void Value::chk_expr_eval_ti(TemplateInstance
*ti
, Type
*type
,
4454 ReferenceChain
*refch
, Type::expected_value_t exp_val
)
4456 bool self_ref
= false;
4458 if (exp_val
!= Type::EXPECTED_TEMPLATE
&& ti
->get_DerivedRef()) {
4459 ti
->error("Reference to a %s value was expected instead of an in-line "
4460 "modified template",
4461 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
4462 set_valuetype(V_ERROR
);
4465 Template
*templ
= ti
->get_Template();
4466 switch (templ
->get_templatetype()) {
4467 case Template::TEMPLATE_REFD
:
4469 if (exp_val
== Type::EXPECTED_TEMPLATE
) {
4470 templ
= templ
->get_template_refd_last(refch
);
4471 if (templ
->get_templatetype() == Template::TEMPLATE_ERROR
)
4472 set_valuetype(V_ERROR
);
4474 ti
->error("Reference to a %s value was expected instead of %s",
4475 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
4476 templ
->get_reference()->get_refd_assignment()
4477 ->get_description().c_str());
4478 set_valuetype(V_ERROR
);
4481 case Template::SPECIFIC_VALUE
: {
4482 Value
*val
= templ
->get_specific_value();
4483 switch (val
->get_valuetype()) {
4485 self_ref
= type
->chk_this_refd_value(val
, 0, exp_val
, refch
);
4488 val
->get_value_refd_last(refch
, exp_val
);
4492 if (val
->get_valuetype() == V_ERROR
) set_valuetype(V_ERROR
);
4494 case Template::TEMPLATE_ERROR
:
4495 set_valuetype(V_ERROR
);
4504 void Value::chk_expr_val_int_pos0(Value
*val
, const char *opnum
,
4507 if(valuetype
==V_ERROR
) return;
4508 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4509 if(val
->is_unfoldable()) return;
4510 if(*val
->get_val_Int()<0) {
4511 val
->error("%s operand of operation `%s' should not be negative",
4513 set_valuetype(V_ERROR
);
4517 void Value::chk_expr_val_int_pos7bit(Value
*val
, const char *opnum
,
4520 if(valuetype
==V_ERROR
) return;
4521 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4522 if(val
->is_unfoldable()) return;
4523 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>127) {
4524 val
->error("%s operand of operation `%s' should be in range 0..127",
4526 set_valuetype(V_ERROR
);
4530 void Value::chk_expr_val_int_pos31bit(Value
*val
, const char *opnum
,
4533 if(valuetype
==V_ERROR
) return;
4534 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4535 if(val
->is_unfoldable()) return;
4536 if(*val
->get_val_Int()<0 || *val
->get_val_Int()>2147483647) {
4537 val
->error("%s operand of operation `%s' should be in range"
4538 " 0..2147483647", opnum
, opname
);
4539 set_valuetype(V_ERROR
);
4543 void Value::chk_expr_val_int_float_not0(Value
*val
, const char *opnum
,
4546 if(valuetype
==V_ERROR
) return;
4547 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4548 if(val
->is_unfoldable()) return;
4549 if((val
->get_expr_returntype()==Type::T_INT
&& *val
->get_val_Int()==0)
4551 (val
->get_expr_returntype()==Type::T_REAL
&& val
->get_val_Real()==0.0))
4553 val
->error("%s operand of operation `%s' should not be zero",
4555 set_valuetype(V_ERROR
);
4559 void Value::chk_expr_val_large_int(Value
*val
, const char *opnum
,
4562 if (valuetype
== V_ERROR
) return;
4563 if (u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4564 if (val
->get_expr_returntype() != Type::T_INT
) return;
4565 if (val
->is_unfoldable()) return;
4566 const int_val_t
*val_int
= val
->get_val_Int();
4567 if (*val_int
> static_cast<Int
>(INT_MAX
)) {
4568 val
->error("%s operand of operation `%s' should be less than `%d' "
4569 "instead of `%s'", opnum
, opname
, INT_MAX
,
4570 (val_int
->t_str()).c_str());
4571 set_valuetype(V_ERROR
);
4575 void Value::chk_expr_val_len1(Value
*val
, const char *opnum
,
4578 if(valuetype
==V_ERROR
) return;
4579 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4580 if(val
->is_unfoldable()) return;
4581 if(val
->get_val_strlen()!=1) {
4582 val
->error("%s operand of operation `%s' should be of length 1",
4584 set_valuetype(V_ERROR
);
4588 void Value::chk_expr_val_str_len_even(Value
*val
, const char *opnum
,
4591 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4592 Value
*v_last
= val
->get_value_refd_last();
4593 if (v_last
->valuetype
== V_CSTR
) {
4594 size_t len
= v_last
->get_val_strlen();
4596 val
->error("%s operand of operation `%s' should contain even number "
4597 "of characters instead of %lu", opnum
, opname
, (unsigned long) len
);
4598 set_valuetype(V_ERROR
);
4600 } else if (v_last
->valuetype
== V_REFD
) {
4601 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4602 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4603 val
->error("%s operand of operation `%s' should contain even number "
4604 "of characters, but a string element contains 1", opnum
, opname
);
4605 set_valuetype(V_ERROR
);
4610 void Value::chk_expr_val_str_bindigits(Value
*val
, const char *opnum
,
4613 if(valuetype
==V_ERROR
) return;
4614 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4615 if(val
->is_unfoldable()) return;
4616 const string
& s
=val
->get_val_str();
4617 for(size_t i
=0; i
<s
.size(); i
++) {
4619 if(!(c
=='0' || c
=='1')) {
4620 val
->error("%s operand of operation `%s' can contain only"
4621 " binary digits (position %lu is `%c')",
4622 opnum
, opname
, (unsigned long) i
, c
);
4623 set_valuetype(V_ERROR
);
4629 void Value::chk_expr_val_str_hexdigits(Value
*val
, const char *opnum
,
4632 if(valuetype
==V_ERROR
) return;
4633 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4634 if(val
->is_unfoldable()) return;
4635 const string
& s
=val
->get_val_str();
4636 for(size_t i
=0; i
<s
.size(); i
++) {
4638 if(!((c
>='0' && c
<='9') || (c
>='A' && c
<='F') || (c
>='a' && c
<='f'))) {
4639 val
->error("%s operand of operation `%s' can contain only valid "
4640 "hexadecimal digits (position %lu is `%c')",
4641 opnum
, opname
, (unsigned long) i
, c
);
4642 set_valuetype(V_ERROR
);
4648 void Value::chk_expr_val_str_7bitoctets(Value
*val
, const char *opnum
,
4651 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4652 Value
*v
= val
->get_value_refd_last();
4653 if (v
->valuetype
!= V_OSTR
) return;
4654 const string
& s
= val
->get_val_str();
4655 size_t n_octets
= s
.size() / 2;
4656 for (size_t i
= 0; i
< n_octets
; i
++) {
4658 if (!(c
>= '0' && c
<= '7')) {
4659 val
->error("%s operand of operation `%s' shall consist of octets "
4660 "within the range 00 .. 7F, but the string `%s'O contains octet "
4661 "%c%c at index %lu", opnum
, opname
, s
.c_str(), c
, s
[2 * i
+ 1],
4663 set_valuetype(V_ERROR
);
4669 void Value::chk_expr_val_str_int(Value
*val
, const char *opnum
,
4672 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4673 Value
*v_last
= val
->get_value_refd_last();
4674 if (v_last
->valuetype
!= V_CSTR
) return;
4675 const string
& s
= v_last
->get_val_str();
4676 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST
, S_ZERO
, S_MORE
, S_END
, S_ERR
}
4678 // state: expected characters
4679 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4680 // S_FIRST: first digit
4681 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4682 // S_END: trailing whitespace
4683 // S_ERR: error was found, stop
4684 for (size_t i
= 0; i
< s
.size(); i
++) {
4689 if (c
== '+' || c
== '-') state
= S_FIRST
;
4690 else if (c
== '0') state
= S_ZERO
;
4691 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4692 else if (string::is_whitespace(c
)) {
4693 if (state
== S_INITIAL
) {
4694 val
->warning("Leading whitespace was detected and ignored in the "
4695 "operand of operation `%s'", opname
);
4696 state
= S_INITIAL_WS
;
4698 } else state
= S_ERR
;
4701 if (c
== '0') state
= S_ZERO
;
4702 else if (c
>= '1' && c
<= '9') state
= S_MORE
;
4706 if (c
>= '0' && c
<= '9') {
4707 val
->warning("Leading zero digit was detected and ignored in the "
4708 "operand of operation `%s'", opname
);
4710 } else if (string::is_whitespace(c
)) state
= S_END
;
4714 if (c
>= '0' && c
<= '9') {}
4715 else if (string::is_whitespace(c
)) state
= S_END
;
4719 if (!string::is_whitespace(c
)) state
= S_ERR
;
4724 if (state
== S_ERR
) {
4725 if (string::is_printable(c
)) {
4726 val
->error("%s operand of operation `%s' should be a string "
4727 "containing a valid integer value, but invalid character `%c' "
4728 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4730 val
->error("%s operand of operation `%s' should be a string "
4731 "containing a valid integer value, but invalid character with "
4732 "character code %u was detected at index %lu", opnum
, opname
, c
,
4735 set_valuetype(V_ERROR
);
4742 val
->error("%s operand of operation `%s' should be a string containing a "
4743 "valid integer value instead of an empty string", opnum
, opname
);
4744 set_valuetype(V_ERROR
);
4747 val
->error("%s operand of operation `%s' should be a string containing a "
4748 "valid integer value, but only a sign character was detected", opnum
,
4750 set_valuetype(V_ERROR
);
4753 val
->warning("Trailing whitespace was detected and ignored in the "
4754 "operand of operation `%s'", opname
);
4761 void Value::chk_expr_val_str_float(Value
*val
, const char *opnum
,
4764 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4765 Value
*v_last
= val
->get_value_refd_last();
4766 if (v_last
->valuetype
== V_REFD
) {
4767 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
4768 if (t_subrefs
&& t_subrefs
->refers_to_string_element()) {
4769 val
->error("%s operand of operation `%s' should be a string containing "
4770 "a valid float value instead of a string element, which cannot "
4771 "represent a floating point number", opnum
, opname
);
4772 set_valuetype(V_ERROR
);
4775 } else if (v_last
->valuetype
!= V_CSTR
) return;
4776 const string
& s
= v_last
->get_val_str();
4777 enum { S_INITIAL
, S_INITIAL_WS
, S_FIRST_M
, S_ZERO_M
, S_MORE_M
, S_FIRST_F
,
4778 S_MORE_F
, S_INITIAL_E
, S_FIRST_E
, S_ZERO_E
, S_MORE_E
, S_END
, S_ERR
}
4780 // state: expected characters
4781 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4782 // leading whitespace
4783 // S_FIRST_M: first digit of integer part in mantissa
4784 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4785 // S_FIRST_F: first digit of fraction
4786 // S_MORE_F: more digits of fraction, E, trailing whitespace
4787 // S_INITIAL_E: +, -, first digit of exponent
4788 // S_FIRST_E: first digit of exponent
4789 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4790 // S_END: trailing whitespace
4791 // S_ERR: error was found, stop
4792 for (size_t i
= 0; i
< s
.size(); i
++) {
4797 if (c
== '+' || c
== '-') state
= S_FIRST_M
;
4798 else if (c
== '0') state
= S_ZERO_M
;
4799 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4800 else if (string::is_whitespace(c
)) {
4801 if (state
== S_INITIAL
) {
4802 val
->warning("Leading whitespace was detected and ignored in the "
4803 "operand of operation `%s'", opname
);
4804 state
= S_INITIAL_WS
;
4806 } else state
= S_ERR
;
4809 if (c
== '0') state
= S_ZERO_M
;
4810 else if (c
>= '1' && c
<= '9') state
= S_MORE_M
;
4814 if (c
== '.') state
= S_FIRST_F
;
4815 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4816 else if (c
>= '0' && c
<= '9') {
4817 val
->warning("Leading zero digit was detected and ignored in the "
4818 "mantissa of the operand of operation `%s'", opname
);
4820 } else state
= S_ERR
;
4823 if (c
== '.') state
= S_FIRST_F
;
4824 else if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4825 else if (c
>= '0' && c
<= '9') {}
4829 if (c
>= '0' && c
<= '9') state
= S_MORE_F
;
4833 if (c
== 'E' || c
== 'e') state
= S_INITIAL_E
;
4834 else if (c
>= '0' && c
<= '9') {}
4835 else if (string::is_whitespace(c
)) state
= S_END
;
4839 if (c
== '+' || c
== '-') state
= S_FIRST_E
;
4840 else if (c
== '0') state
= S_ZERO_E
;
4841 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4845 if (c
== '0') state
= S_ZERO_E
;
4846 else if (c
>= '1' && c
<= '9') state
= S_MORE_E
;
4850 if (c
>= '0' && c
<= '9') {
4851 val
->warning("Leading zero digit was detected and ignored in the "
4852 "exponent of the operand of operation `%s'", opname
);
4854 } else if (string::is_whitespace(c
)) state
= S_END
;
4858 if (c
>= '0' && c
<= '9') {}
4859 else if (string::is_whitespace(c
)) state
= S_END
;
4863 if (!string::is_whitespace(c
)) state
= S_ERR
;
4868 if (state
== S_ERR
) {
4869 if (string::is_printable(c
)) {
4870 val
->error("%s operand of operation `%s' should be a string "
4871 "containing a valid float value, but invalid character `%c' "
4872 "was detected at index %lu", opnum
, opname
, c
, (unsigned long) i
);
4874 val
->error("%s operand of operation `%s' should be a string "
4875 "containing a valid float value, but invalid character with "
4876 "character code %u was detected at index %lu", opnum
, opname
, c
,
4879 set_valuetype(V_ERROR
);
4886 val
->error("%s operand of operation `%s' should be a string containing a "
4887 "valid float value instead of an empty string", opnum
, opname
);
4888 set_valuetype(V_ERROR
);
4891 val
->error("%s operand of operation `%s' should be a string containing a "
4892 "valid float value, but only a sign character was detected", opnum
,
4894 set_valuetype(V_ERROR
);
4898 // HL67862: Missing decimal dot allowed for str2float
4901 // HL67862: Missing fraction part is allowed for str2float
4905 val
->error("%s operand of operation `%s' should be a string containing a "
4906 "valid float value, but the exponent is missing after the `E' sign",
4908 set_valuetype(V_ERROR
);
4911 val
->warning("Trailing whitespace was detected and ignored in the "
4912 "operand of operation `%s'", opname
);
4919 void Value::chk_expr_val_ustr_7bitchars(Value
*val
, const char *opnum
,
4922 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4923 Value
*v
= val
->get_value_refd_last();
4924 if (v
->valuetype
!= V_USTR
) return;
4925 const ustring
& us
= v
->get_val_ustr();
4926 for (size_t i
= 0; i
< us
.size(); i
++) {
4927 const ustring::universal_char
& uchar
= us
[i
];
4928 if (uchar
.group
!= 0 || uchar
.plane
!= 0 || uchar
.row
!= 0 ||
4930 val
->error("%s operand of operation `%s' shall consist of characters "
4931 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4932 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4933 opnum
, opname
, us
.get_stringRepr().c_str(), uchar
.group
, uchar
.plane
,
4934 uchar
.row
, uchar
.cell
, (unsigned long) i
);
4935 set_valuetype(V_ERROR
);
4941 void Value::chk_expr_val_bitstr_intsize(Value
*val
, const char *opnum
,
4944 if(valuetype
==V_ERROR
) return;
4945 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4946 if(val
->is_unfoldable()) return;
4947 const string
& bstr
=val
->get_val_str();
4948 // see also PredefFunc.cc::bit2int()
4949 size_t nof_bits
= bstr
.size();
4950 // skip the leading zeros
4951 size_t start_index
= 0;
4952 while (start_index
< nof_bits
&& bstr
[start_index
] == '0') start_index
++;
4953 // check whether the remaining bits fit in Int
4954 if (nof_bits
- start_index
> 8 * sizeof(Int
) - 1) {
4955 val
->error("%s operand of operation `%s' is too large (maximum number"
4956 " of bits in integer is %lu)",
4957 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4958 set_valuetype(V_ERROR
);
4962 void Value::chk_expr_val_hexstr_intsize(Value
*val
, const char *opnum
,
4965 if(valuetype
==V_ERROR
) return;
4966 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
4967 if(val
->is_unfoldable()) return;
4968 const string
& hstr
=val
->get_val_str();
4969 // see also PredefFunc.cc::hex2int()
4970 size_t nof_digits
= hstr
.size();
4971 // skip the leading zeros
4972 size_t start_index
= 0;
4973 while (start_index
< nof_digits
&& hstr
[start_index
] == '0') start_index
++;
4974 // check whether the remaining hex digits fit in Int
4975 if (nof_digits
- start_index
> 2 * sizeof(Int
) ||
4976 (nof_digits
- start_index
== 2 * sizeof(Int
) &&
4977 char_to_hexdigit(hstr
[start_index
]) > 7)) {
4978 val
->error("%s operand of operation `%s' is too large (maximum number"
4979 " of bits in integer is %lu)",
4980 opnum
, opname
, (unsigned long) (8 * sizeof(Int
) - 1));
4981 set_valuetype(V_ERROR
);
4985 void Value::chk_expr_operands_int2binstr()
4987 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
4988 if (u
.expr
.v1
->is_unfoldable()) return;
4989 if (u
.expr
.v2
->is_unfoldable()) return;
4990 // It is already checked that i1 and i2 are non-negative.
4991 Error_Context
cntxt(this, "In operation `%s'", get_opname());
4992 const int_val_t
*i1
= u
.expr
.v1
->get_val_Int();
4993 const int_val_t
*i2
= u
.expr
.v2
->get_val_Int();
4994 if (!i2
->is_native()) {
4995 u
.expr
.v2
->error("The length of the resulting string is too large for "
4996 "being represented in memory");
4997 set_valuetype(V_ERROR
);
5000 Int nof_bits
= i2
->get_val();
5001 if (u
.expr
.v1
->is_unfoldable()) return;
5002 switch (u
.expr
.v_optype
) {
5003 case OPTYPE_INT2BIT
:
5005 case OPTYPE_INT2HEX
:
5008 case OPTYPE_INT2OCT
:
5012 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5014 if (*i1
>> nof_bits
> 0) { // Expensive?
5015 u
.expr
.v1
->error("Value %s does not fit in length %s",
5016 i1
->t_str().c_str(), i2
->t_str().c_str());
5017 set_valuetype(V_ERROR
);
5021 void Value::chk_expr_operands_str_samelen()
5023 if(valuetype
==V_ERROR
) return;
5024 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5025 Value
*v1
=u
.expr
.v1
;
5026 if(v1
->is_unfoldable()) return;
5027 Value
*v2
=u
.expr
.v2
;
5028 if(v2
->is_unfoldable()) return;
5029 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5030 size_t i1
=v1
->get_val_strlen();
5031 size_t i2
=v2
->get_val_strlen();
5033 error("The operands should have the same length");
5034 set_valuetype(V_ERROR
);
5038 void Value::chk_expr_operands_replace()
5040 // The fourth operand doesn't need to be checked at all here.
5041 if(valuetype
==V_ERROR
) return;
5042 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5043 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5046 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5047 size_t list_len
= 0;
5048 bool list_len_known
= false;
5049 if (v1
->valuetype
== V_REFD
) {
5050 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5051 if (subrefs
&& subrefs
->refers_to_string_element()) {
5052 warning("Replacing a string element does not make any sense");
5054 list_len_known
= true;
5057 if (!v1
->is_unfoldable()) {
5058 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5059 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5060 list_len_known
= true;
5062 if (!list_len_known
) return;
5063 if (u
.expr
.v2
->is_unfoldable()) {
5064 if (!u
.expr
.v3
->is_unfoldable()) {
5065 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5066 if (*len_int_3
> static_cast<Int
>(list_len
)) {
5067 error("Third operand `len' (%s) is greater than the length of "
5068 "the first operand (%lu)", (len_int_3
->t_str()).c_str(),
5069 (unsigned long)list_len
);
5070 set_valuetype(V_ERROR
);
5074 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5075 if (u
.expr
.v3
->is_unfoldable()) {
5076 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5077 error("Second operand `index' (%s) is greater than the length of "
5078 "the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5079 (unsigned long)list_len
);
5080 set_valuetype(V_ERROR
);
5083 const int_val_t
*len_int_3
= u
.expr
.v3
->get_val_Int();
5084 if (*index_int_2
+ *len_int_3
> static_cast<Int
>(list_len
)) {
5085 error("The sum of second operand `index' (%s) and third operand "
5086 "`len' (%s) is greater than the length of the first operand (%lu)",
5087 (index_int_2
->t_str()).c_str(), (len_int_3
->t_str()).c_str(),
5088 (unsigned long)list_len
);
5089 set_valuetype(V_ERROR
);
5095 void Value::chk_expr_operands_substr()
5097 if(valuetype
==V_ERROR
) return;
5098 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
5099 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5102 Error_Context
cntxt(this, "In operation `%s'", get_opname());
5103 size_t list_len
= 0;
5104 bool list_len_known
= false;
5105 if (v1
->valuetype
== V_REFD
) {
5106 Ttcn::FieldOrArrayRefs
*subrefs
= v1
->u
.ref
.ref
->get_subrefs();
5107 if (subrefs
&& subrefs
->refers_to_string_element()) {
5108 warning("Taking the substring of a string element does not make any "
5111 list_len_known
= true;
5114 if (!list_len_known
&& !v1
->is_unfoldable()) {
5115 list_len
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
) ?
5116 v1
->get_val_strlen() : v1
->get_value_refd_last()->get_nof_comps();
5117 list_len_known
= true;
5119 // Do nothing if the length of the first operand is unknown.
5120 if (!list_len_known
) return;
5121 if (u
.expr
.v2
->is_unfoldable()) {
5122 if (!u
.expr
.v3
->is_unfoldable()) {
5123 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5124 // Only the third operand is known.
5125 if (*returncount_int_3
> static_cast<Int
>(list_len
)) {
5126 error("Third operand `returncount' (%s) is greater than the "
5127 "length of the first operand (%lu)",
5128 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5129 set_valuetype(V_ERROR
);
5133 const int_val_t
*index_int_2
= u
.expr
.v2
->get_val_Int();
5134 if (u
.expr
.v3
->is_unfoldable()) {
5135 // Only the second operand is known.
5136 if (*index_int_2
> static_cast<Int
>(list_len
)) {
5137 error("Second operand `index' (%s) is greater than the length "
5138 "of the first operand (%lu)", (index_int_2
->t_str()).c_str(),
5139 (unsigned long)list_len
);
5140 set_valuetype(V_ERROR
);
5143 // Both second and third operands are known.
5144 const int_val_t
*returncount_int_3
= u
.expr
.v3
->get_val_Int();
5145 if (*index_int_2
+ *returncount_int_3
> static_cast<Int
>(list_len
)) {
5146 error("The sum of second operand `index' (%s) and third operand "
5147 "`returncount' (%s) is greater than the length of the first operand "
5148 "(%lu)", (index_int_2
->t_str()).c_str(),
5149 (returncount_int_3
->t_str()).c_str(), (unsigned long)list_len
);
5150 set_valuetype(V_ERROR
);
5156 void Value::chk_expr_operands_regexp()
5158 if (valuetype
== V_ERROR
|| u
.expr
.state
== EXPR_CHECKING_ERR
) return;
5159 Value
* v1
= u
.expr
.ti1
->get_specific_value();
5160 Value
* v2
= u
.expr
.t2
->get_specific_value();
5161 if (!v1
|| !v2
) return;
5163 Error_Context
cntxt(this, "In operation `regexp()'");
5164 Value
* v1_last
= v1
->get_value_refd_last();
5165 if (v1_last
->valuetype
== V_CSTR
) {
5166 // the input string is available at compile time
5167 const string
& instr
= v1_last
->get_val_str();
5168 const char *input_str
= instr
.c_str();
5169 size_t instr_len
= strlen(input_str
);
5170 if (instr_len
< instr
.size()) {
5171 v1
->warning("The first operand of `regexp()' contains a "
5172 "character with character code zero at index %s. The rest of the "
5173 "string will be ignored during matching",
5174 Int2string(instr_len
).c_str());
5178 size_t nof_groups
= 0;
5179 Value
*v2_last
= v2
->get_value_refd_last();
5181 if (v2_last
->valuetype
== V_CSTR
) {
5182 // the pattern is available at compile time
5183 const string
& expression
= v2_last
->get_val_str();
5184 const char *pattern_str
= expression
.c_str();
5185 size_t pattern_len
= strlen(pattern_str
);
5186 if (pattern_len
< expression
.size()) {
5187 v2
->warning("The second operand of `regexp()' contains a "
5188 "character with character code zero at index %s. The rest of the "
5189 "string will be ignored during matching",
5190 Int2string(pattern_len
).c_str());
5194 Error_Context
cntxt2(v2
, "In character string pattern");
5195 posix_str
= TTCN_pattern_to_regexp(pattern_str
);
5197 if (posix_str
!= NULL
) {
5198 regex_t posix_regexp
;
5199 int ret_val
= regcomp(&posix_regexp
, posix_str
, REG_EXTENDED
);
5202 regerror(ret_val
, &posix_regexp
, msg
, sizeof(msg
));
5203 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5204 "regcomp() failed: %s", msg
);
5206 if (posix_regexp
.re_nsub
> 0) nof_groups
= posix_regexp
.re_nsub
;
5208 v2
->error("The character pattern in the second operand of "
5209 "`regexp()' does not contain any groups");
5210 set_valuetype(V_ERROR
);
5212 regfree(&posix_regexp
);
5215 // the pattern is faulty
5216 // the error has been reported by TTCN_pattern_to_regexp
5217 set_valuetype(V_ERROR
);
5220 if (nof_groups
> 0) {
5221 Value
*v3
= u
.expr
.v3
->get_value_refd_last();
5222 if (v3
->valuetype
== V_INT
) {
5223 // the group number is available at compile time
5224 const int_val_t
*groupno_int
= v3
->get_val_Int();
5225 if (*groupno_int
>= static_cast<Int
>(nof_groups
)) {
5226 u
.expr
.v3
->error("The the third operand of `regexp()' is too "
5227 "large: The requested group index is %s, but the pattern "
5228 "contains only %s group%s", (groupno_int
->t_str()).c_str(),
5229 Int2string(nof_groups
).c_str(), nof_groups
> 1 ? "s" : "");
5230 set_valuetype(V_ERROR
);
5236 void Value::chk_expr_operands_ischosen(ReferenceChain
*refch
,
5237 Type::expected_value_t exp_val
)
5239 const char *opname
= get_opname();
5240 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
5242 const Location
*loc
;
5243 bool error_flag
= false;
5244 switch (u
.expr
.v_optype
) {
5245 case OPTYPE_ISCHOSEN_V
:
5246 // u.expr.v1 is always a referenced value
5247 t_governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5249 u
.expr
.v1
->set_my_governor(t_governor
);
5250 t_governor
->chk_this_refd_value(u
.expr
.v1
, 0, exp_val
, refch
);
5251 if (u
.expr
.v1
->valuetype
== V_ERROR
) error_flag
= true;
5252 } else error_flag
= true;
5255 case OPTYPE_ISCHOSEN_T
:
5256 // u.expr.t1 is always a referenced template
5257 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5258 exp_val
= Type::EXPECTED_TEMPLATE
;
5259 t_governor
= u
.expr
.t1
->get_expr_governor(exp_val
);
5261 u
.expr
.t1
->set_my_governor(t_governor
);
5263 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5265 u
.expr
.t1
->get_template_refd_last(refch
);
5266 if (u
.expr
.t1
->get_templatetype() == Template::TEMPLATE_ERROR
)
5268 } else error_flag
= true;
5269 if (exp_val
!= Type::EXPECTED_TEMPLATE
) {
5270 u
.expr
.t1
->error("Reference to a %s value was expected instead of %s",
5271 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static",
5272 u
.expr
.t1
->get_reference()->get_refd_assignment()
5273 ->get_description().c_str());
5279 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5284 t_governor
= t_governor
->get_type_refd_last();
5285 switch (t_governor
->get_typetype()) {
5289 case Type::T_CHOICE_A
:
5290 case Type::T_CHOICE_T
:
5291 case Type::T_ANYTYPE
:
5292 case Type::T_OPENTYPE
:
5293 if (!t_governor
->has_comp_withName(*u
.expr
.i2
)) {
5294 error(t_governor
->get_typetype()==Type::T_ANYTYPE
?
5295 "%s does not have a field named `%s'" :
5296 "Union type `%s' does not have a field named `%s'",
5297 t_governor
->get_typename().c_str(),
5298 u
.expr
.i2
->get_dispname().c_str());
5303 loc
->error("The operand of operation `%s' should be a union value "
5304 "or template instead of `%s'", opname
,
5305 t_governor
->get_typename().c_str());
5310 if (error_flag
) set_valuetype(V_ERROR
);
5313 void Value::chk_expr_operand_encode(ReferenceChain
*refch
,
5314 Type::expected_value_t exp_val
) {
5316 Error_Context
cntxt(this, "In the parameter of encvalue()");
5317 Type
t_chk(Type::T_ERROR
);
5320 Type::expected_value_t ti_exp_val
= exp_val
;
5321 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
5322 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
5324 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
5326 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, ti_exp_val
);
5327 if (valuetype
!=V_ERROR
)
5328 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
5329 t_type
= t_type
->get_type_refd_last();
5331 error("Cannot determine type of value");
5336 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5337 error("Expecting a value of a type with coding attributes in first"
5338 "parameter of encvalue() which belongs to a generic type '%s'",
5339 t_type->get_typename().c_str());
5343 if(!disable_attribute_validation()) {
5344 t_type
->chk_coding(true);
5347 switch (t_type
->get_typetype()) {
5352 case Type::T_REFDSPEC
:
5353 case Type::T_SELTYPE
:
5354 case Type::T_VERDICT
:
5356 case Type::T_COMPONENT
:
5357 case Type::T_DEFAULT
:
5358 case Type::T_SIGNATURE
:
5359 case Type::T_FUNCTION
:
5360 case Type::T_ALTSTEP
:
5361 case Type::T_TESTCASE
:
5362 error("Type of parameter of encvalue() cannot be '%s'",
5363 t_type
->get_typename().c_str());
5370 set_valuetype(V_ERROR
);
5373 void Value::chk_expr_operands_decode()
5375 Error_Context
cntxt(this, "In the parameters of decvalue()");
5376 Ttcn::Ref_base
* ref
= u
.expr
.r1
;
5377 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5379 Assignment
* t_ass
= ref
->get_refd_assignment();
5382 error("Could not determine the assignment for first parameter");
5385 switch (t_ass
->get_asstype()) {
5386 case Assignment::A_PAR_VAL_IN
:
5387 t_ass
->use_as_lvalue(*this);
5389 case Assignment::A_CONST
:
5390 case Assignment::A_EXT_CONST
:
5391 case Assignment::A_MODULEPAR
:
5392 case Assignment::A_MODULEPAR_TEMP
:
5393 case Assignment::A_TEMPLATE
:
5394 ref
->error("Reference to '%s' cannot be used as the first operand of "
5395 "the 'decvalue' operation", t_ass
->get_assname());
5398 case Assignment::A_VAR
:
5399 case Assignment::A_PAR_VAL_OUT
:
5400 case Assignment::A_PAR_VAL_INOUT
:
5402 case Assignment::A_VAR_TEMPLATE
:
5403 case Assignment::A_PAR_TEMPL_IN
:
5404 case Assignment::A_PAR_TEMPL_OUT
:
5405 case Assignment::A_PAR_TEMPL_INOUT
: {
5406 Template
* t
= new Template(ref
->clone());
5407 t
->set_location(*ref
);
5408 t
->set_my_scope(get_my_scope());
5409 t
->set_fullname(get_fullname()+".<operand>");
5410 Template
* t_last
= t
->get_template_refd_last();
5411 if (t_last
->get_templatetype() != Template::SPECIFIC_VALUE
5413 ref
->error("Specific value template was expected instead of '%s'.",
5414 t
->get_template_refd_last()->get_templatetype_str());
5421 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5424 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5425 Type::EXPECTED_DYNAMIC_VALUE
);
5429 if (t_type
->get_type_refd_last()->get_typetype() != Type::T_BSTR
){
5430 error("First parameter has to be a bitstring");
5435 t_subrefs
= ref
->get_subrefs();
5436 t_ass
= ref
->get_refd_assignment();
5439 error("Could not determine the assignment for second parameter");
5442 // Extra check for HM59355.
5443 switch (t_ass
->get_asstype()) {
5444 case Assignment::A_VAR
:
5445 case Assignment::A_PAR_VAL_IN
:
5446 case Assignment::A_PAR_VAL_OUT
:
5447 case Assignment::A_PAR_VAL_INOUT
:
5450 ref
->error("Reference to '%s' cannot be used.", t_ass
->get_assname());
5453 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
,
5454 Type::EXPECTED_DYNAMIC_VALUE
);
5458 t_type
= t_type
->get_type_refd_last();
5459 switch (t_type
->get_typetype()) {
5464 case Type::T_REFDSPEC
:
5465 case Type::T_SELTYPE
:
5466 case Type::T_VERDICT
:
5468 case Type::T_COMPONENT
:
5469 case Type::T_DEFAULT
:
5470 case Type::T_SIGNATURE
:
5471 case Type::T_FUNCTION
:
5472 case Type::T_ALTSTEP
:
5473 case Type::T_TESTCASE
:
5474 error("Type of second parameter cannot be %s",
5475 t_type
->get_typename().c_str());
5481 if(!disable_attribute_validation()) {
5482 t_type
->chk_coding(false);
5487 set_valuetype(V_ERROR
);
5490 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val
)
5492 Ttcn::FieldOrArrayRefs
*subrefs
;
5493 Identifier
*field_id
= 0;
5496 if (valuetype
== V_ERROR
) return;
5497 else if (valuetype
!= V_REFD
) {
5498 error("Only a referenced value can be compared with `omit'");
5501 subrefs
= u
.ref
.ref
->get_subrefs();
5502 if (subrefs
) field_id
= subrefs
->remove_last_field();
5504 error("Only a reference pointing to an optional record or set field "
5505 "can be compared with `omit'");
5508 t_ass
= u
.ref
.ref
->get_refd_assignment();
5509 if (!t_ass
) goto error
;
5510 t_type
= t_ass
->get_Type()->get_field_type(subrefs
, exp_val
);
5511 if (!t_type
) goto error
;
5512 t_type
= t_type
->get_type_refd_last();
5513 switch (t_type
->get_typetype()) {
5522 error("Only a reference pointing to an optional field of a record"
5523 " or set type can be compared with `omit'");
5526 if (!t_type
->has_comp_withName(*field_id
)) {
5527 error("Type `%s' does not have field named `%s'",
5528 t_type
->get_typename().c_str(), field_id
->get_dispname().c_str());
5530 } else if (!t_type
->get_comp_byName(*field_id
)->get_is_optional()) {
5531 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5532 "`omit'", field_id
->get_dispname().c_str(),
5533 t_type
->get_typename().c_str());
5536 // putting the last field_id back to subrefs
5537 subrefs
->add(new Ttcn::FieldOrArrayRef(field_id
));
5540 set_valuetype(V_ERROR
);
5544 Int
Value::chk_eval_expr_sizeof(ReferenceChain
*refch
,
5545 Type::expected_value_t exp_val
)
5547 if(valuetype
==V_ERROR
) return -1;
5548 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return -1;
5549 if(exp_val
==Type::EXPECTED_DYNAMIC_VALUE
)
5550 exp_val
=Type::EXPECTED_TEMPLATE
;
5552 Error_Context
cntxt(this, "In the operand of"
5553 " operation `%s'", get_opname());
5556 Template
* t_templ
= u
.expr
.ti1
->get_Template();
5559 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5562 t_templ
= t_templ
->get_template_refd_last(refch
);
5564 // Timer and port arrays are handled separately
5565 if (t_templ
->get_templatetype() == Template::SPECIFIC_VALUE
) {
5566 Value
* val
= t_templ
->get_specific_value();
5567 if (val
->get_valuetype() == V_UNDEF_LOWERID
) {
5568 val
->set_lowerid_to_ref();
5570 if (val
&& val
->get_valuetype() == V_REFD
) {
5571 Reference
* ref
= val
->get_reference();
5572 Assignment
* t_ass
= ref
->get_refd_assignment();
5573 Common::Assignment::asstype_t asstype
=
5574 t_ass
? t_ass
->get_asstype() : Assignment::A_ERROR
;
5575 if (asstype
== Assignment::A_PORT
|| asstype
== Assignment::A_TIMER
) {
5576 if (t_ass
->get_Dimensions()) {
5577 // here we have a timer or port array
5578 Ttcn::FieldOrArrayRefs
* t_subrefs
= ref
->get_subrefs();
5579 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5580 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5581 Type::EXPECTED_DYNAMIC_VALUE
);
5584 refd_dim
= t_subrefs
->get_nof_refs();
5585 size_t nof_dims
= t_dims
->get_nof_dims();
5586 if (refd_dim
>= nof_dims
) {
5587 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5588 t_ass
->get_assname());
5589 set_valuetype(V_ERROR
);
5592 } else refd_dim
= 0;
5593 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5595 u
.expr
.ti1
->error("Operation is not applicable to single `%s'",
5596 t_ass
->get_description().c_str());
5597 set_valuetype(V_ERROR
);
5606 Assignment
* t_ass
= 0;
5608 Ttcn::FieldOrArrayRefs
* t_subrefs
= 0;
5609 t_type
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
5611 chk_expr_eval_ti(u
.expr
.ti1
, t_type
, refch
, exp_val
);
5612 t_type
= t_type
->get_type_refd_last();
5614 error("Cannot determine type of value");
5618 if(valuetype
==V_ERROR
) return -1;
5620 t_templ
= t_templ
->get_template_refd_last(refch
);
5621 switch(t_templ
->get_templatetype()) {
5622 case Template::TEMPLATE_ERROR
:
5624 case Template::INDEXED_TEMPLATE_LIST
:
5626 case Template::TEMPLATE_REFD
:
5627 case Template::TEMPLATE_LIST
:
5628 case Template::NAMED_TEMPLATE_LIST
:
5631 case Template::SPECIFIC_VALUE
:
5633 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5635 switch(t_val
->get_valuetype()) {
5645 ref
= t_val
->get_reference();
5646 t_ass
= ref
->get_refd_assignment();
5647 t_subrefs
= ref
->get_subrefs();
5651 u
.expr
.ti1
->error("Operation is not applicable to `%s'",
5652 t_val
->create_stringRepr().c_str());
5659 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5660 t_templ
->get_templatetype_str(), t_templ
->get_fullname().c_str());
5665 switch(t_ass
->get_asstype()) {
5666 case Assignment::A_ERROR
:
5668 case Assignment::A_CONST
:
5669 t_val
= t_ass
->get_Value();
5671 case Assignment::A_EXT_CONST
:
5672 case Assignment::A_MODULEPAR
:
5673 case Assignment::A_MODULEPAR_TEMP
:
5674 if(exp_val
==Type::EXPECTED_CONSTANT
) {
5675 u
.expr
.ti1
->error("Reference to an (evaluable) constant value was "
5676 "expected instead of %s", t_ass
->get_description().c_str());
5680 case Assignment::A_VAR
:
5681 case Assignment::A_PAR_VAL_IN
:
5682 case Assignment::A_PAR_VAL_OUT
:
5683 case Assignment::A_PAR_VAL_INOUT
:
5685 case Type::EXPECTED_CONSTANT
:
5686 u
.expr
.ti1
->error("Reference to a constant value was expected instead of %s",
5687 t_ass
->get_description().c_str());
5690 case Type::EXPECTED_STATIC_VALUE
:
5691 u
.expr
.ti1
->error("Reference to a static value was expected instead of %s",
5692 t_ass
->get_description().c_str());
5699 case Assignment::A_TEMPLATE
:
5700 t_templ
= t_ass
->get_Template();
5702 case Assignment::A_VAR_TEMPLATE
:
5703 case Assignment::A_PAR_TEMPL_IN
:
5704 case Assignment::A_PAR_TEMPL_OUT
:
5705 case Assignment::A_PAR_TEMPL_INOUT
:
5706 if (exp_val
!=Type::EXPECTED_TEMPLATE
)
5707 u
.expr
.ti1
->error("Reference to a value was expected instead of %s",
5708 t_ass
->get_description().c_str());
5711 case Assignment::A_FUNCTION_RVAL
:
5712 case Assignment::A_EXT_FUNCTION_RVAL
:
5714 case Type::EXPECTED_CONSTANT
:
5715 u
.expr
.ti1
->error("Reference to a constant value was expected instead of "
5716 "the return value of %s", t_ass
->get_description().c_str());
5719 case Type::EXPECTED_STATIC_VALUE
:
5720 u
.expr
.ti1
->error("Reference to a static value was expected instead of "
5721 "the return value of %s", t_ass
->get_description().c_str());
5728 case Assignment::A_FUNCTION_RTEMP
:
5729 case Assignment::A_EXT_FUNCTION_RTEMP
:
5730 if(exp_val
!=Type::EXPECTED_TEMPLATE
)
5731 u
.expr
.ti1
->error("Reference to a value was expected instead of a call"
5732 " of %s, which returns a template",
5733 t_ass
->get_description().c_str());
5736 case Assignment::A_TIMER
:
5737 case Assignment::A_PORT
:
5738 if (u
.expr
.v_optype
== OPTYPE_SIZEOF
) {
5739 // sizeof is applicable to timer and port arrays
5740 Ttcn::ArrayDimensions
*t_dims
= t_ass
->get_Dimensions();
5742 u
.expr
.ti1
->error("Operation is not applicable to single %s",
5743 t_ass
->get_description().c_str());
5746 t_dims
->chk_indices(ref
, t_ass
->get_assname(), true,
5747 Type::EXPECTED_DYNAMIC_VALUE
);
5750 refd_dim
= t_subrefs
->get_nof_refs();
5751 size_t nof_dims
= t_dims
->get_nof_dims();
5752 if (refd_dim
> nof_dims
) goto error
;
5753 else if (refd_dim
== nof_dims
) {
5754 u
.expr
.ti1
->error("Operation is not applicable to a %s",
5755 t_ass
->get_assname());
5758 } else refd_dim
= 0;
5759 return t_dims
->get_dim_byIndex(refd_dim
)->get_size();
5763 u
.expr
.ti1
->error("Reference to a %s was expected instead of %s",
5764 exp_val
== Type::EXPECTED_TEMPLATE
? "value or template" : "value",
5765 t_ass
->get_description().c_str());
5769 t_type
= t_ass
->get_Type()->get_field_type(t_subrefs
, exp_val
);
5770 if (!t_type
) goto error
;
5771 t_type
= t_type
->get_type_refd_last();
5773 switch(t_type
->get_typetype()) {
5790 u
.expr
.ti1
->error("Reference to value or template of type record, record of,"
5791 " set, set of, objid or array was expected");
5796 // check for index overflows in subrefs if possible
5798 switch (t_val
->get_valuetype()) {
5802 if (t_val
->is_indexed()) {
5809 /* The reference points to a constant. */
5810 if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5811 t_val
= t_val
->get_refd_sub_value(t_subrefs
, 0, false, refch
);
5812 if (!t_val
) goto error
;
5813 t_val
=t_val
->get_value_refd_last(refch
);
5814 } else { t_val
= 0; }
5815 } else if (t_templ
) {
5816 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5817 time. Don't try to evaluate it at compile time. */
5818 if (t_templ
->get_templatetype() == Template::INDEXED_TEMPLATE_LIST
) {
5820 /* The reference points to a static template. */
5821 } else if (!t_subrefs
|| !t_subrefs
->has_unfoldable_index()) {
5822 t_templ
= t_templ
->get_refd_sub_template(t_subrefs
, ref
&& ref
->getUsedInIsbound(), refch
);
5823 if (!t_templ
) goto error
;
5824 t_templ
= t_templ
->get_template_refd_last(refch
);
5825 } else { t_templ
= 0; }
5828 if(u
.expr
.v_optype
==OPTYPE_SIZEOF
) {
5830 switch(t_templ
->get_templatetype()) {
5831 case Template::TEMPLATE_ERROR
:
5833 case Template::TEMPLATE_REFD
:
5837 case Template::SPECIFIC_VALUE
:
5838 t_val
=t_templ
->get_specific_value()->get_value_refd_last(refch
);
5841 case Template::TEMPLATE_LIST
:
5842 case Template::NAMED_TEMPLATE_LIST
:
5845 u
.expr
.ti1
->error("Operation is not applicable to %s `%s'",
5846 t_templ
->get_templatetype_str(),
5847 t_templ
->get_fullname().c_str());
5852 switch(t_val
->get_valuetype()) {
5863 // error is already reported
5872 if(t_type
->get_typetype()==Type::T_ARRAY
) {
5873 result
= t_type
->get_dimension()->get_size();
5875 else if(t_templ
) { // sizeof()
5876 switch(t_templ
->get_templatetype()) {
5877 case Template::TEMPLATE_LIST
:
5878 if(t_templ
->temps_contains_anyornone_symbol()) {
5879 if(t_templ
->is_length_restricted()) {
5880 Ttcn::LengthRestriction
*lr
= t_templ
->get_length_restriction();
5881 if (lr
->get_is_range()) {
5882 Value
*v_upper
= lr
->get_upper_value();
5884 if (v_upper
->valuetype
== V_INT
) {
5886 static_cast<Int
>(t_templ
->get_nof_comps_not_anyornone());
5887 if (v_upper
->u
.val_Int
->get_val() == nof_comps
)
5890 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5891 "templates without exact size");
5896 u
.expr
.ti1
->error("`sizeof' operation is not applicable for "
5897 "templates containing `*' without upper boundary in the "
5898 "length restriction");
5902 Value
*v_single
= lr
->get_single_value();
5903 if (v_single
->valuetype
== V_INT
)
5904 result
= v_single
->u
.val_Int
->get_val();
5907 else { // not length restricted
5908 u
.expr
.ti1
->error("`sizeof' operation is not applicable for templates"
5909 " containing `*' without length restriction");
5913 else result
=t_templ
->get_nof_listitems();
5915 case Template::NAMED_TEMPLATE_LIST
:
5917 for(size_t i
=0; i
<t_templ
->get_nof_comps(); i
++)
5918 if(t_templ
->get_namedtemp_byIndex(i
)->get_template()
5919 ->get_templatetype()!=Template::OMIT_VALUE
) result
++;
5922 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5926 switch(t_val
->get_valuetype()) {
5933 result
=t_val
->get_nof_comps();
5938 for(size_t i
=0; i
<t_val
->get_nof_comps(); i
++)
5939 if(t_val
->get_se_comp_byIndex(i
)->get_value()
5940 ->get_valuetype()!=V_OMIT
) result
++;
5944 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5950 set_valuetype(V_ERROR
);
5954 Type
*Value::chk_expr_operands_ti(TemplateInstance
* ti
, Type::expected_value_t exp_val
)
5956 Type
*governor
= ti
->get_expr_governor(exp_val
);
5958 ti
->get_Template()->set_lowerid_to_ref();
5959 governor
= ti
->get_expr_governor(exp_val
);
5963 ti
->append_stringRepr( str
);
5964 ti
->error("Cannot determine the argument type of %s in the `%s' operation.\n"
5965 "If type is known, use valueof(<type>: %s) as argument.",
5966 str
.c_str(), get_opname(), str
.c_str());
5967 set_valuetype(V_ERROR
);
5972 void Value::chk_expr_operands_match(Type::expected_value_t exp_val
)
5975 Type
*governor
= u
.expr
.v1
->get_expr_governor(exp_val
);
5976 if (!governor
) governor
= u
.expr
.t2
->get_expr_governor(
5977 exp_val
== Type::EXPECTED_DYNAMIC_VALUE
?
5978 Type::EXPECTED_TEMPLATE
: exp_val
);
5980 Template
*t_temp
= u
.expr
.t2
->get_Template();
5981 if (t_temp
->is_undef_lowerid()) {
5982 // We convert the template to reference first even if the value is also
5983 // an undef lowerid. The user can prevent this by explicit type
5985 t_temp
->set_lowerid_to_ref();
5987 } else if (u
.expr
.v1
->is_undef_lowerid()) {
5988 u
.expr
.v1
->set_lowerid_to_ref();
5993 error("Cannot determine the type of arguments in `match()' operation");
5994 set_valuetype(V_ERROR
);
5997 u
.expr
.v1
->set_my_governor(governor
);
5999 Error_Context
cntxt(this, "In the first argument of `match()'"
6001 governor
->chk_this_value_ref(u
.expr
.v1
);
6002 (void)governor
->chk_this_value(u
.expr
.v1
, 0, exp_val
,
6003 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6006 Error_Context
cntxt(this, "In the second argument of `match()' "
6008 u
.expr
.t2
->chk(governor
);
6012 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val
,
6013 bool allow_controlpart
, bool allow_runs_on
, bool require_runs_on
)
6015 Ttcn::StatementBlock
*my_sb
;
6017 case Type::EXPECTED_CONSTANT
:
6018 error("An evaluable constant value was expected instead of operation "
6019 "`%s'", get_opname());
6021 case Type::EXPECTED_STATIC_VALUE
:
6022 error("A static value was expected instead of operation `%s'",
6028 if (!my_scope
) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6029 my_sb
= dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
6031 error("Operation `%s' is allowed only within statements",
6035 if (!allow_controlpart
&& !my_sb
->get_my_def()) {
6036 error("Operation `%s' is not allowed in the control part",
6040 if (!allow_runs_on
&& my_scope
->get_scope_runs_on()) {
6041 error("Operation `%s' cannot be used in a definition that has "
6042 "`runs on' clause", get_opname());
6045 if (require_runs_on
&& !my_scope
->get_scope_runs_on()) {
6046 error("Operation `%s' can be used only in a definition that has "
6047 "`runs on' clause", get_opname());
6052 set_valuetype(V_ERROR
);
6055 void Value::chk_expr_operand_valid_float(Value
* v
, const char *opnum
, const char *opname
)
6057 if(valuetype
==V_ERROR
) return;
6058 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return;
6059 if(v
->is_unfoldable()) return;
6060 if(v
->get_expr_returntype()!=Type::T_REAL
) return;
6061 ttcn3float r
= v
->get_val_Real();
6062 if (isSpecialFloatValue(r
)) {
6063 v
->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6064 opnum
, opname
, Real2string(r
).c_str());
6065 set_valuetype(V_ERROR
);
6069 void Value::chk_expr_operands(ReferenceChain
*refch
,
6070 Type::expected_value_t exp_val
)
6072 const char *first
="First", *second
="Second", *third
="Third",
6073 *fourth
="Fourth", *the
="The", *left
="Left", *right
="Right";
6074 Value
*v1
, *v2
, *v3
;
6075 Type::typetype_t tt1
, tt2
, tt3
;
6076 Type
t_chk(Type::T_ERROR
);
6078 const char *opname
=get_opname();
6080 // first classify the unchecked ischosen() operation
6081 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
6083 switch (u
.expr
.v_optype
) {
6084 case OPTYPE_COMP_NULL
:
6085 case OPTYPE_TESTCASENAME
:
6086 case OPTYPE_PROF_RUNNING
:
6088 case OPTYPE_COMP_MTC
:
6089 case OPTYPE_COMP_SYSTEM
:
6090 chk_expr_comptype_compat();
6092 case OPTYPE_RND
: // -
6093 case OPTYPE_TMR_RUNNING_ANY
:
6094 chk_expr_dynamic_part(exp_val
, true);
6096 case OPTYPE_COMP_RUNNING_ANY
:
6097 case OPTYPE_COMP_RUNNING_ALL
:
6098 case OPTYPE_COMP_ALIVE_ANY
:
6099 case OPTYPE_COMP_ALIVE_ALL
:
6100 case OPTYPE_GETVERDICT
:
6101 chk_expr_dynamic_part(exp_val
, false);
6103 case OPTYPE_COMP_SELF
:
6104 chk_expr_comptype_compat();
6105 chk_expr_dynamic_part(exp_val
, false, true, false);
6107 case OPTYPE_UNARYPLUS
: // v1
6108 case OPTYPE_UNARYMINUS
:
6111 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6112 v1
->set_lowerid_to_ref();
6113 tt1
=v1
->get_expr_returntype(exp_val
);
6114 chk_expr_operandtype_int_float(tt1
, the
, opname
, v1
);
6115 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6121 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6122 v1
->set_lowerid_to_ref();
6123 tt1
=v1
->get_expr_returntype(exp_val
);
6124 chk_expr_operandtype_bool(tt1
, the
, opname
, v1
);
6125 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6131 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6132 v1
->set_lowerid_to_ref();
6133 tt1
=v1
->get_expr_returntype(exp_val
);
6134 chk_expr_operandtype_binstr(tt1
, the
, opname
, v1
);
6135 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6138 case OPTYPE_BIT2HEX
:
6139 case OPTYPE_BIT2OCT
:
6140 case OPTYPE_BIT2STR
:
6143 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6144 v1
->set_lowerid_to_ref();
6145 tt1
=v1
->get_expr_returntype(exp_val
);
6146 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6147 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6150 case OPTYPE_BIT2INT
:
6153 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6154 v1
->set_lowerid_to_ref();
6155 tt1
=v1
->get_expr_returntype(exp_val
);
6156 chk_expr_operandtype_bstr(tt1
, the
, opname
, v1
);
6157 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6158 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6161 case OPTYPE_CHAR2INT
:
6164 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6165 v1
->set_lowerid_to_ref();
6166 tt1
=v1
->get_expr_returntype(exp_val
);
6167 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6168 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6169 chk_expr_val_len1(v1
, the
, opname
);
6172 case OPTYPE_CHAR2OCT
:
6175 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6176 v1
->set_lowerid_to_ref();
6177 tt1
=v1
->get_expr_returntype(exp_val
);
6178 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6179 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6182 case OPTYPE_STR2INT
:
6185 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6186 v1
->set_lowerid_to_ref();
6187 tt1
=v1
->get_expr_returntype(exp_val
);
6188 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6189 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6190 chk_expr_val_str_int(v1
, the
, opname
);
6193 case OPTYPE_STR2FLOAT
:
6196 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6197 v1
->set_lowerid_to_ref();
6198 tt1
=v1
->get_expr_returntype(exp_val
);
6199 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6200 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6201 chk_expr_val_str_float(v1
, the
, opname
);
6204 case OPTYPE_STR2BIT
:
6207 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6208 v1
->set_lowerid_to_ref();
6209 tt1
=v1
->get_expr_returntype(exp_val
);
6210 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6211 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6212 chk_expr_val_str_bindigits(v1
, the
, opname
);
6215 case OPTYPE_STR2HEX
:
6218 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6219 v1
->set_lowerid_to_ref();
6220 tt1
=v1
->get_expr_returntype(exp_val
);
6221 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6222 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6223 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6226 case OPTYPE_STR2OCT
:
6229 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6230 v1
->set_lowerid_to_ref();
6231 tt1
=v1
->get_expr_returntype(exp_val
);
6232 chk_expr_operandtype_cstr(tt1
, the
, opname
, v1
);
6233 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6234 chk_expr_val_str_len_even(v1
, the
, opname
);
6235 chk_expr_val_str_hexdigits(v1
, the
, opname
);
6238 case OPTYPE_ENUM2INT
:
6241 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6242 chk_expr_operandtype_enum(opname
, v1
, exp_val
);
6243 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6247 chk_expr_operand_encode(refch
, exp_val
);
6249 case OPTYPE_FLOAT2INT
:
6250 case OPTYPE_FLOAT2STR
:
6253 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6254 v1
->set_lowerid_to_ref();
6255 tt1
=v1
->get_expr_returntype(exp_val
);
6256 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6257 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6258 if (u
.expr
.v_optype
==OPTYPE_FLOAT2INT
)
6259 chk_expr_operand_valid_float(v1
, the
, opname
);
6262 case OPTYPE_RNDWITHVAL
:
6265 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6266 v1
->set_lowerid_to_ref();
6267 tt1
=v1
->get_expr_returntype(exp_val
);
6268 chk_expr_operandtype_float(tt1
, the
, opname
, v1
);
6269 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6270 chk_expr_operand_valid_float(v1
, the
, opname
);
6272 chk_expr_dynamic_part(exp_val
, true);
6274 case OPTYPE_HEX2BIT
:
6275 case OPTYPE_HEX2OCT
:
6276 case OPTYPE_HEX2STR
:
6279 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6280 v1
->set_lowerid_to_ref();
6281 tt1
=v1
->get_expr_returntype(exp_val
);
6282 chk_expr_operandtype_hstr(tt1
, the
, opname
, v1
);
6283 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6286 case OPTYPE_HEX2INT
:
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_hstr(tt1
, the
, opname
, v1
);
6293 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6294 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6297 case OPTYPE_INT2CHAR
:
6300 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6301 v1
->set_lowerid_to_ref();
6302 tt1
=v1
->get_expr_returntype(exp_val
);
6303 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6304 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6305 chk_expr_val_int_pos7bit(v1
, the
, opname
);
6308 case OPTYPE_INT2UNICHAR
:
6311 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6312 v1
->set_lowerid_to_ref();
6313 tt1
=v1
->get_expr_returntype(exp_val
);
6314 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6315 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6316 chk_expr_val_int_pos31bit(v1
, first
, opname
);
6319 case OPTYPE_INT2FLOAT
:
6320 case OPTYPE_INT2STR
:
6323 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6324 v1
->set_lowerid_to_ref();
6325 tt1
=v1
->get_expr_returntype(exp_val
);
6326 chk_expr_operandtype_int(tt1
, the
, opname
, v1
);
6327 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6330 case OPTYPE_OCT2BIT
:
6331 case OPTYPE_OCT2HEX
:
6332 case OPTYPE_OCT2STR
:
6335 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6336 v1
->set_lowerid_to_ref();
6337 tt1
=v1
->get_expr_returntype(exp_val
);
6338 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6339 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6342 case OPTYPE_OCT2INT
:
6345 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6346 v1
->set_lowerid_to_ref();
6347 tt1
=v1
->get_expr_returntype(exp_val
);
6348 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6349 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6350 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6354 case OPTYPE_OCT2CHAR
:
6357 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6358 v1
->set_lowerid_to_ref();
6359 tt1
=v1
->get_expr_returntype(exp_val
);
6360 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6361 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6362 chk_expr_val_str_7bitoctets(v1
, the
, opname
);
6365 case OPTYPE_REMOVE_BOM
:
6368 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6369 v1
->set_lowerid_to_ref();
6370 tt1
=v1
->get_expr_returntype(exp_val
);
6371 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6372 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6375 case OPTYPE_GET_STRINGENCODING
:
6378 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6379 v1
->set_lowerid_to_ref();
6380 tt1
=v1
->get_expr_returntype(exp_val
);
6381 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6382 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6385 case OPTYPE_ENCODE_BASE64
:
6388 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6389 v1
->set_lowerid_to_ref();
6390 tt1
=v1
->get_expr_returntype(exp_val
);
6391 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6392 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6394 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6397 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6398 v2
->set_lowerid_to_ref();
6399 tt2
=v2
->get_expr_returntype(exp_val
);
6400 chk_expr_operandtype_bool(tt2
, second
, opname
, v2
);
6401 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6404 case OPTYPE_DECODE_BASE64
:
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
);
6414 case OPTYPE_UNICHAR2INT
:
6417 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6418 v1
->set_lowerid_to_ref();
6419 tt1
=v1
->get_expr_returntype(exp_val
);
6420 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6421 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6422 chk_expr_val_len1(v1
, the
, opname
);
6425 case OPTYPE_UNICHAR2CHAR
:
6428 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6429 v1
->set_lowerid_to_ref();
6430 tt1
=v1
->get_expr_returntype(exp_val
);
6431 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6432 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6433 chk_expr_val_ustr_7bitchars(v1
, the
, opname
);
6436 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
6439 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6440 v1
->set_lowerid_to_ref();
6441 tt1
=v1
->get_expr_returntype(exp_val
);
6442 chk_expr_operandtype_charstr(tt1
, the
, opname
, v1
);
6443 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6445 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6448 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6449 v2
->set_lowerid_to_ref();
6450 tt2
=v2
->get_expr_returntype(exp_val
);
6451 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6452 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6455 case OPTYPE_OCT2UNICHAR
: // v1 [v2]
6458 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6459 v1
->set_lowerid_to_ref();
6460 tt1
=v1
->get_expr_returntype(exp_val
);
6461 chk_expr_operandtype_ostr(tt1
, the
, opname
, v1
);
6462 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6464 v2
=u
.expr
.v2
? u
.expr
.v2
: 0;
6467 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6468 v2
->set_lowerid_to_ref();
6469 tt2
=v2
->get_expr_returntype(exp_val
);
6470 chk_expr_operandtype_cstr(tt2
, second
, opname
, v2
);
6471 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6474 case OPTYPE_ADD
: // v1 v2
6475 case OPTYPE_SUBTRACT
:
6476 case OPTYPE_MULTIPLY
:
6480 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6481 v1
->set_lowerid_to_ref();
6482 tt1
=v1
->get_expr_returntype(exp_val
);
6483 chk_expr_operandtype_int_float(tt1
, first
, opname
, v1
);
6484 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6485 chk_expr_operand_valid_float(v1
, first
, opname
);
6489 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6490 v2
->set_lowerid_to_ref();
6491 tt2
=v2
->get_expr_returntype(exp_val
);
6492 chk_expr_operandtype_int_float(tt2
, second
, opname
, v2
);
6493 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6494 chk_expr_operand_valid_float(v2
, second
, opname
);
6495 if(u
.expr
.v_optype
==OPTYPE_DIVIDE
)
6496 chk_expr_val_int_float_not0(v2
, second
, opname
);
6498 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6504 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6505 v1
->set_lowerid_to_ref();
6506 tt1
=v1
->get_expr_returntype(exp_val
);
6507 chk_expr_operandtype_int(tt1
, left
, opname
, v1
);
6508 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6512 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6513 v2
->set_lowerid_to_ref();
6514 tt2
=v2
->get_expr_returntype(exp_val
);
6515 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6516 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6517 chk_expr_val_int_float_not0(v2
, right
, opname
);
6520 case OPTYPE_CONCAT
: {
6523 v1
->set_lowerid_to_ref();
6524 v2
->set_lowerid_to_ref();
6525 if (v1
->is_string_type(exp_val
) || v2
->is_string_type(exp_val
)) {
6527 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6528 tt1
=v1
->get_expr_returntype(exp_val
);
6529 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6530 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6533 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6534 tt2
=v2
->get_expr_returntype(exp_val
);
6535 chk_expr_operandtype_str(tt2
, right
, opname
, v2
);
6536 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6538 if (!((tt1
==Type::T_CSTR
&& tt2
==Type::T_USTR
)
6539 || (tt2
==Type::T_CSTR
&& tt1
==Type::T_USTR
)))
6540 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6541 } else { // other list types
6542 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6543 Type
* v2_gov
= v2
->get_expr_governor(exp_val
);
6545 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6546 set_valuetype(V_ERROR
);
6549 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6550 v1_gov
->chk_this_value_ref(v1
);
6551 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6552 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6553 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, false);
6557 error("Cannot determine the type of the right operand of `%s' operation", opname
);
6558 set_valuetype(V_ERROR
);
6561 // for recof/setof literals set the type from v1
6563 v2
->set_my_governor(v1_gov
);
6566 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6568 v2_gov
->chk_this_value_ref(v2
);
6569 (void)v2_gov
->chk_this_value(v2
, 0, exp_val
,
6570 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6571 chk_expr_operandtype_list(v2_gov
, right
, opname
, v2
, false);
6572 if (valuetype
== V_ERROR
) return;
6573 // 7.1.2 says that we shouldn't allow type compatibility.
6574 if (!v1_gov
->is_compatible(v2_gov
, NULL
)
6575 && !v2_gov
->is_compatible(v1_gov
, NULL
)) {
6576 error("The operands of operation `%s' should be of compatible "
6577 "types", get_opname());
6586 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6588 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6590 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6593 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6595 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6596 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6597 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6598 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6599 * "a == not b" is not allowed. (HL69107)
6600 * The various *Expressions implement operator precedence in the std.
6601 * Titan's parser has only one Expression and relies on Bison
6602 * for operator precedence. The check below brings Titan in line
6603 * with the standard by explicitly making "a == not b" an error */
6604 if (v2
->get_valuetype() == V_EXPR
6605 && v2
->u
.expr
.v_optype
== OPTYPE_NOT
) {
6606 error("The operation `%s' is not allowed to be "
6607 "the second operand of operation `%s'", v2
->get_opname(), opname
);
6608 set_valuetype(V_ERROR
);
6618 chk_expr_operandtypes_compat(exp_val
, v1
, v2
);
6620 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6622 tt1
=v1
->get_expr_returntype(exp_val
);
6623 chk_expr_operandtype_int_float_enum(tt1
, left
, opname
, v1
);
6624 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6627 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6629 tt2
=v2
->get_expr_returntype(exp_val
);
6630 chk_expr_operandtype_int_float_enum(tt2
, right
, opname
, v2
);
6631 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6639 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6641 v1
->set_lowerid_to_ref();
6642 tt1
=v1
->get_expr_returntype(exp_val
);
6643 chk_expr_operandtype_bool(tt1
, left
, opname
, v1
);
6644 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6648 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6650 v2
->set_lowerid_to_ref();
6651 tt2
=v2
->get_expr_returntype(exp_val
);
6652 chk_expr_operandtype_bool(tt2
, right
, opname
, v2
);
6653 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6661 Error_Context
cntxt(this, "In the left operand of operation `%s'",
6663 v1
->set_lowerid_to_ref();
6664 tt1
=v1
->get_expr_returntype(exp_val
);
6665 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6666 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6670 Error_Context
cntxt(this, "In the right operand of operation `%s'",
6672 v2
->set_lowerid_to_ref();
6673 tt2
=v2
->get_expr_returntype(exp_val
);
6674 chk_expr_operandtype_binstr(tt2
, right
, opname
, v2
);
6675 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6677 chk_expr_operandtypes_same(tt1
, tt2
, opname
);
6678 chk_expr_operands_str_samelen();
6684 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6685 v1
->set_lowerid_to_ref();
6686 tt1
=v1
->get_expr_returntype(exp_val
);
6687 chk_expr_operandtype_binstr(tt1
, left
, opname
, v1
);
6688 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6692 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6693 v2
->set_lowerid_to_ref();
6694 tt2
=v2
->get_expr_returntype(exp_val
);
6695 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6696 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6697 chk_expr_val_large_int(v2
, right
, opname
);
6703 v1
->set_lowerid_to_ref();
6704 if (v1
->is_string_type(exp_val
)) {
6705 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6706 tt1
=v1
->get_expr_returntype(exp_val
);
6707 chk_expr_operandtype_str(tt1
, left
, opname
, v1
);
6708 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6709 } else { // other list types
6710 Type
* v1_gov
= v1
->get_expr_governor(exp_val
);
6711 if (!v1_gov
) { // a recof/setof literal would be a syntax error here
6712 error("Cannot determine the type of the left operand of `%s' operation", opname
);
6714 Error_Context
cntxt(this, "In the left operand of operation `%s'", opname
);
6715 v1_gov
->chk_this_value_ref(v1
);
6716 (void)v1_gov
->chk_this_value(v1
, 0, exp_val
,
6717 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
6718 chk_expr_operandtype_list(v1_gov
, left
, opname
, v1
, true);
6723 Error_Context
cntxt(this, "In the right operand of operation `%s'", opname
);
6724 v2
->set_lowerid_to_ref();
6725 tt2
=v2
->get_expr_returntype(exp_val
);
6726 chk_expr_operandtype_int(tt2
, right
, opname
, v2
);
6727 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6728 chk_expr_val_large_int(v2
, right
, opname
);
6731 case OPTYPE_INT2BIT
:
6732 case OPTYPE_INT2HEX
:
6733 case OPTYPE_INT2OCT
:
6736 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6737 v1
->set_lowerid_to_ref();
6738 tt1
=v1
->get_expr_returntype(exp_val
);
6739 chk_expr_operandtype_int(tt1
, first
, opname
, v1
);
6740 chk_expr_eval_value(v1
, t_chk
, refch
, exp_val
);
6741 chk_expr_val_int_pos0(v1
, first
, opname
);
6745 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6746 v2
->set_lowerid_to_ref();
6747 tt2
=v2
->get_expr_returntype(exp_val
);
6748 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6749 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6750 chk_expr_val_int_pos0(v2
, second
, opname
);
6752 chk_expr_operands_int2binstr();
6755 chk_expr_operands_decode();
6759 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6760 Type::expected_value_t ti_exp_val
= exp_val
;
6761 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6762 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6763 if (!governor
) return;
6764 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6765 if (valuetype
!=V_ERROR
)
6766 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6767 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6771 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6772 v2
->set_lowerid_to_ref();
6773 tt2
=v2
->get_expr_returntype(exp_val
);
6774 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6775 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6776 chk_expr_val_int_pos0(v2
, second
, opname
);
6780 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6781 v3
->set_lowerid_to_ref();
6782 tt3
=v3
->get_expr_returntype(exp_val
);
6783 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6784 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6785 chk_expr_val_int_pos0(v3
, third
, opname
);
6787 chk_expr_operands_substr();
6789 case OPTYPE_REGEXP
: {
6790 Type::expected_value_t ti_exp_val
= exp_val
;
6791 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6793 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6794 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6795 if (!governor
) return;
6796 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6797 if (valuetype
!=V_ERROR
) {
6798 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6799 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6800 get_typetype_ttcn3(), first
, opname
, u
.expr
.ti1
);
6804 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6805 Type
* governor
= chk_expr_operands_ti(u
.expr
.t2
, ti_exp_val
);
6806 if (!governor
) return;
6807 chk_expr_eval_ti(u
.expr
.t2
, governor
, refch
, ti_exp_val
);
6808 chk_expr_operandtype_charstr(governor
->get_type_refd_last()->
6809 get_typetype_ttcn3(), second
, opname
, u
.expr
.t2
);
6813 Error_Context
cntxt(this, "In the third operand of operation `%s'", opname
);
6814 v3
->set_lowerid_to_ref();
6815 tt3
=v3
->get_expr_returntype(exp_val
);
6816 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6817 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6818 chk_expr_val_int_pos0(v3
, third
, opname
);
6820 chk_expr_operands_regexp();
6822 case OPTYPE_ISCHOSEN
:
6823 // do nothing: the operand is erroneous
6824 // the error was already reported in chk_expr_ref_ischosen()
6826 case OPTYPE_ISCHOSEN_V
: // v1 i2
6827 case OPTYPE_ISCHOSEN_T
: // t1 i2
6828 chk_expr_operands_ischosen(refch
, exp_val
);
6830 case OPTYPE_VALUEOF
: { // ti1
6831 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6832 exp_val
= Type::EXPECTED_TEMPLATE
;
6833 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6834 Type
*governor
= my_governor
;
6835 if (!governor
) governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6836 if (!governor
) return;
6837 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6838 if (valuetype
== V_ERROR
) return;
6839 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6841 case OPTYPE_ISPRESENT
: // TODO: rename UsedInIsbound to better name
6842 case OPTYPE_ISBOUND
: {
6843 Template
*templ
= u
.expr
.ti1
->get_Template();
6844 switch (templ
->get_templatetype()) {
6845 case Template::TEMPLATE_REFD
:
6846 templ
->get_reference()->setUsedInIsbound();
6848 case Template::SPECIFIC_VALUE
: {
6849 Value
*value
= templ
->get_specific_value();
6850 if (Value::V_REFD
== value
->get_valuetype()) {
6851 value
->get_reference()->setUsedInIsbound();
6859 case OPTYPE_ISVALUE
: {// ti1
6860 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6861 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6862 exp_val
= Type::EXPECTED_TEMPLATE
;
6863 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6864 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6865 if (!governor
) return;
6866 tt1
= u
.expr
.ti1
->get_expr_returntype(exp_val
);
6867 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6869 case OPTYPE_SIZEOF
: // ti1
6870 /* this checking is too complex, do the checking during eval... */
6872 case OPTYPE_LENGTHOF
: { // ti1
6873 if (exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6874 exp_val
= Type::EXPECTED_TEMPLATE
;
6875 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6876 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, exp_val
);
6877 if (!governor
) return;
6878 chk_expr_operandtype_list(governor
, the
, opname
, u
.expr
.ti1
, true);
6879 if (valuetype
== V_ERROR
) return;
6880 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, exp_val
);
6882 case OPTYPE_MATCH
: // v1 t2
6883 chk_expr_operands_match(exp_val
);
6885 case OPTYPE_UNDEF_RUNNING
: // r1
6886 chk_expr_operand_undef_running(exp_val
, u
.expr
.r1
, the
, opname
);
6888 case OPTYPE_COMP_ALIVE
:
6889 case OPTYPE_COMP_RUNNING
: //v1
6890 chk_expr_operand_compref(u
.expr
.v1
, the
, opname
);
6891 chk_expr_dynamic_part(exp_val
, false);
6893 case OPTYPE_TMR_READ
: // r1
6894 case OPTYPE_TMR_RUNNING
: // r1
6895 chk_expr_operand_tmrref(u
.expr
.r1
, the
, opname
);
6896 chk_expr_dynamic_part(exp_val
, true);
6898 case OPTYPE_EXECUTE
: // r1 [v2] // testcase
6899 chk_expr_operand_execute(u
.expr
.r1
, u
.expr
.v2
, the
, opname
);
6900 chk_expr_dynamic_part(exp_val
, true, false, false);
6902 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
6903 chk_expr_operand_comptyperef_create();
6906 Error_Context
cntxt(this, "In the first operand of operation `%s'", opname
);
6907 v2
->set_lowerid_to_ref();
6908 tt2
=v2
->get_expr_returntype(exp_val
);
6909 chk_expr_operandtype_cstr(tt2
, first
, opname
, v2
);
6910 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6914 Error_Context
cntxt(this, "In the second operand of operation `%s'", opname
);
6915 v3
->set_lowerid_to_ref();
6916 tt3
=v3
->get_expr_returntype(exp_val
);
6917 chk_expr_operandtype_cstr(tt3
, second
, opname
, v3
);
6918 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6920 chk_expr_dynamic_part(exp_val
, false);
6922 case OPTYPE_ACTIVATE
: // r1 // altstep
6923 chk_expr_operand_activate(u
.expr
.r1
, the
, opname
);
6924 chk_expr_dynamic_part(exp_val
, true);
6926 case OPTYPE_ACTIVATE_REFD
:{ //v1 t_list2
6927 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6928 chk_expr_operand_activate_refd(u
.expr
.v1
,u
.expr
.t_list2
->get_tis(), parlist
, the
,
6930 delete u
.expr
.t_list2
;
6931 u
.expr
.ap_list2
= parlist
;
6932 chk_expr_dynamic_part(exp_val
, true);
6934 case OPTYPE_EXECUTE_REFD
: {// v1 t_list2 [v3]
6935 Ttcn::ActualParList
*parlist
= new Ttcn::ActualParList
;
6936 chk_expr_operand_execute_refd(u
.expr
.v1
, u
.expr
.t_list2
->get_tis(), parlist
,
6937 u
.expr
.v3
, the
, opname
);
6938 delete u
.expr
.t_list2
;
6939 u
.expr
.ap_list2
= parlist
;
6940 chk_expr_dynamic_part(exp_val
, true);
6943 error("Built-in function `%s' is not yet supported", opname
);
6944 set_valuetype(V_ERROR
);
6946 case OPTYPE_REPLACE
: {
6947 Type::expected_value_t ti_exp_val
= exp_val
;
6948 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
)
6949 ti_exp_val
= Type::EXPECTED_TEMPLATE
;
6951 Error_Context
cntxt(this, "In the first operand of operation `%s'",
6953 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
6954 if (!governor
) return;
6955 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
6956 if (valuetype
!= V_ERROR
)
6957 u
.expr
.ti1
->get_Template()->chk_specific_value(false);
6958 chk_expr_operandtype_list(governor
, first
, opname
, u
.expr
.ti1
, false);
6962 Error_Context
cntxt(this, "In the second operand of operation `%s'",
6964 v2
->set_lowerid_to_ref();
6965 tt2
= v2
->get_expr_returntype(exp_val
);
6966 chk_expr_operandtype_int(tt2
, second
, opname
, v2
);
6967 chk_expr_eval_value(v2
, t_chk
, refch
, exp_val
);
6968 chk_expr_val_int_pos0(v2
, second
, opname
);
6972 Error_Context
cntxt(this, "In the third operand of operation `%s'",
6974 v3
->set_lowerid_to_ref();
6975 tt3
= v3
->get_expr_returntype(exp_val
);
6976 chk_expr_operandtype_int(tt3
, third
, opname
, v3
);
6977 chk_expr_eval_value(v3
, t_chk
, refch
, exp_val
);
6978 chk_expr_val_int_pos0(v3
, third
, opname
);
6981 Error_Context
cntxt(this, "In the fourth operand of operation `%s'",
6983 Type
* governor
= chk_expr_operands_ti(u
.expr
.ti4
, ti_exp_val
);
6984 if (!governor
) return;
6985 chk_expr_eval_ti(u
.expr
.ti4
, governor
, refch
, ti_exp_val
);
6986 if (valuetype
!= V_ERROR
)
6987 u
.expr
.ti4
->get_Template()->chk_specific_value(false);
6988 chk_expr_operandtype_list(governor
, fourth
, opname
, u
.expr
.ti4
, false);
6990 chk_expr_operands_replace();
6992 case OPTYPE_LOG2STR
: {
6993 Error_Context
cntxt(this, "In the operand of operation `%s'", opname
);
6994 u
.expr
.logargs
->chk();
6995 if (!semantic_check_only
) u
.expr
.logargs
->join_strings();
6997 case OPTYPE_TTCN2STRING
: {
6998 Error_Context
cntxt(this, "In the parameter of ttcn2string()");
6999 Type::expected_value_t ti_exp_val
= exp_val
;
7000 if (ti_exp_val
== Type::EXPECTED_DYNAMIC_VALUE
) ti_exp_val
= Type::EXPECTED_TEMPLATE
;
7001 Type
*governor
= chk_expr_operands_ti(u
.expr
.ti1
, ti_exp_val
);
7002 if (!governor
) return;
7003 chk_expr_eval_ti(u
.expr
.ti1
, governor
, refch
, ti_exp_val
);
7006 FATAL_ERROR("chk_expr_operands()");
7010 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7011 // the result of evaluating the expression. E.g. V_BOOL for
7013 void Value::evaluate_value(ReferenceChain
*refch
,
7014 Type::expected_value_t exp_val
)
7016 if(valuetype
!=V_EXPR
) FATAL_ERROR("Value::evaluate_value()");
7017 if(u
.expr
.state
!=EXPR_NOT_CHECKED
) return;
7019 u
.expr
.state
=EXPR_CHECKING
;
7021 get_expr_returntype(exp_val
); // to report 'didyamean'-errors etc
7022 chk_expr_operands(refch
, exp_val
== Type::EXPECTED_TEMPLATE
?
7023 Type::EXPECTED_DYNAMIC_VALUE
: exp_val
);
7025 if(valuetype
==V_ERROR
) return;
7026 if(u
.expr
.state
==EXPR_CHECKING_ERR
) {
7027 u
.expr
.state
=EXPR_CHECKED
;
7028 set_valuetype(V_ERROR
);
7032 u
.expr
.state
=EXPR_CHECKED
;
7034 Value
*v1
, *v2
, *v3
, *v4
;
7035 switch(u
.expr
.v_optype
) {
7036 case OPTYPE_RND
: // -
7037 case OPTYPE_COMP_NULL
: // the only foldable in this group
7038 case OPTYPE_COMP_MTC
:
7039 case OPTYPE_COMP_SYSTEM
:
7040 case OPTYPE_COMP_SELF
:
7041 case OPTYPE_COMP_RUNNING_ANY
:
7042 case OPTYPE_COMP_RUNNING_ALL
:
7043 case OPTYPE_COMP_ALIVE_ANY
:
7044 case OPTYPE_COMP_ALIVE_ALL
:
7045 case OPTYPE_TMR_RUNNING_ANY
:
7046 case OPTYPE_GETVERDICT
:
7047 case OPTYPE_PROF_RUNNING
:
7048 case OPTYPE_RNDWITHVAL
: // v1
7049 case OPTYPE_COMP_RUNNING
: // v1
7050 case OPTYPE_COMP_ALIVE
:
7051 case OPTYPE_TMR_READ
:
7052 case OPTYPE_TMR_RUNNING
:
7053 case OPTYPE_ACTIVATE
:
7054 case OPTYPE_ACTIVATE_REFD
:
7055 case OPTYPE_EXECUTE
: // r1 [v2]
7056 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
7057 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
7058 case OPTYPE_MATCH
: // v1 t2
7059 case OPTYPE_ISCHOSEN_T
:
7060 case OPTYPE_LOG2STR
:
7063 case OPTYPE_ISBOUND
:
7064 case OPTYPE_ISPRESENT
:
7065 case OPTYPE_TTCN2STRING
:
7066 case OPTYPE_UNICHAR2OCT
:
7067 case OPTYPE_OCT2UNICHAR
:
7068 case OPTYPE_ENCODE_BASE64
:
7069 case OPTYPE_DECODE_BASE64
:
7071 case OPTYPE_TESTCASENAME
: { // -
7072 if (!my_scope
) FATAL_ERROR("Value::evaluate_value()");
7073 Ttcn::StatementBlock
*my_sb
=
7074 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
7076 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
7077 if (!my_def
) { // In control part.
7078 set_val_str(new string(""));
7080 } else if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
7081 set_val_str(new string(my_def
->get_id().get_dispname()));
7085 case OPTYPE_UNARYPLUS
: // v1
7088 copy_and_destroy(v1
);
7090 case OPTYPE_UNARYMINUS
:
7091 if (is_unfoldable()) break;
7092 v1
= u
.expr
.v1
->get_value_refd_last();
7093 switch (v1
->valuetype
) {
7095 int_val_t
*i
= new int_val_t(-*(v1
->get_val_Int()));
7096 if (!i
) FATAL_ERROR("Value::evaluate_value()");
7102 ttcn3float r
= v1
->get_val_Real();
7108 FATAL_ERROR("Value::evaluate_value()");
7112 if(is_unfoldable()) break;
7113 bool b
=u
.expr
.v1
->get_value_refd_last()->get_val_bool();
7118 case OPTYPE_NOT4B
: {
7119 if(is_unfoldable()) break;
7120 v1
=u
.expr
.v1
->get_value_refd_last();
7121 const string
& s
= v1
->get_val_str();
7122 valuetype_t vt
=v1
->valuetype
;
7125 set_val_str(vt
==V_BSTR
?not4b_bit(s
):not4b_hex(s
));
7127 case OPTYPE_BIT2HEX
: {
7128 if(is_unfoldable()) break;
7129 v1
=u
.expr
.v1
->get_value_refd_last();
7130 const string
& s
= v1
->get_val_str();
7133 set_val_str(bit2hex(s
));
7135 case OPTYPE_BIT2OCT
: {
7136 if(is_unfoldable()) break;
7137 v1
=u
.expr
.v1
->get_value_refd_last();
7138 const string
& s
= v1
->get_val_str();
7141 set_val_str(bit2oct(s
));
7143 case OPTYPE_BIT2STR
:
7144 case OPTYPE_HEX2STR
:
7145 case OPTYPE_OCT2STR
: {
7146 if(is_unfoldable()) break;
7147 v1
=u
.expr
.v1
->get_value_refd_last();
7148 const string
& s
= v1
->get_val_str();
7151 set_val_str(new string(s
));
7153 case OPTYPE_BIT2INT
: {
7154 if (is_unfoldable()) break;
7155 v1
= u
.expr
.v1
->get_value_refd_last();
7156 const string
& s
= v1
->get_val_str();
7159 u
.val_Int
= bit2int(s
);
7161 case OPTYPE_CHAR2INT
: {
7162 if (is_unfoldable()) break;
7163 v1
= u
.expr
.v1
->get_value_refd_last();
7164 char c
= v1
->get_val_str()[0];
7167 u
.val_Int
= new int_val_t((Int
)c
);
7169 case OPTYPE_CHAR2OCT
: {
7170 if(is_unfoldable()) break;
7171 v1
=u
.expr
.v1
->get_value_refd_last();
7172 const string
& s
= v1
->get_val_str();
7175 set_val_str(char2oct(s
));
7177 case OPTYPE_STR2INT
: {
7178 if (is_unfoldable()) break;
7179 v1
= u
.expr
.v1
->get_value_refd_last();
7180 int_val_t
*i
= new int_val_t((v1
->get_val_str()).c_str(), *u
.expr
.v1
);
7184 /** \todo hiba eseten lenyeli... */
7186 case OPTYPE_STR2FLOAT
: {
7187 if(is_unfoldable()) break;
7188 v1
=u
.expr
.v1
->get_value_refd_last();
7189 Real r
=string2Real(v1
->get_val_str(), *u
.expr
.v1
);
7193 /** \todo hiba eseten lenyeli... */
7195 case OPTYPE_STR2BIT
: {
7196 if(is_unfoldable()) break;
7197 v1
=u
.expr
.v1
->get_value_refd_last();
7198 const string
& s
= v1
->get_val_str();
7201 set_val_str(new string(s
));
7203 case OPTYPE_STR2HEX
:
7204 case OPTYPE_OCT2HEX
: {
7205 if(is_unfoldable()) break;
7206 v1
=u
.expr
.v1
->get_value_refd_last();
7207 const string
& s
= v1
->get_val_str();
7210 set_val_str(to_uppercase(s
));
7212 case OPTYPE_STR2OCT
: {
7213 if(is_unfoldable()) break;
7214 v1
=u
.expr
.v1
->get_value_refd_last();
7215 const string
& s
= v1
->get_val_str();
7218 set_val_str(to_uppercase(s
));
7220 case OPTYPE_FLOAT2INT
: {
7221 if (is_unfoldable()) break;
7222 v1
= u
.expr
.v1
->get_value_refd_last();
7223 ttcn3float r
= v1
->get_val_Real();
7226 u
.val_Int
= float2int(r
, *u
.expr
.v1
);
7228 case OPTYPE_FLOAT2STR
: {
7229 if(is_unfoldable()) break;
7230 v1
=u
.expr
.v1
->get_value_refd_last();
7231 ttcn3float r
=v1
->get_val_Real();
7234 set_val_str(float2str(r
));
7236 case OPTYPE_HEX2BIT
:
7237 case OPTYPE_OCT2BIT
: {
7238 if(is_unfoldable()) break;
7239 v1
=u
.expr
.v1
->get_value_refd_last();
7240 const string
& s
= v1
->get_val_str();
7243 set_val_str(hex2bit(s
));
7245 case OPTYPE_HEX2INT
:
7246 case OPTYPE_OCT2INT
: {
7247 if(is_unfoldable()) break;
7248 v1
=u
.expr
.v1
->get_value_refd_last();
7249 const string
& s
= v1
->get_val_str();
7252 u
.val_Int
=hex2int(s
);
7254 case OPTYPE_HEX2OCT
: {
7255 if(is_unfoldable()) break;
7256 v1
=u
.expr
.v1
->get_value_refd_last();
7257 const string
& s
= v1
->get_val_str();
7260 set_val_str(hex2oct(s
));
7262 case OPTYPE_INT2CHAR
: {
7263 if (is_unfoldable()) break;
7264 v1
= u
.expr
.v1
->get_value_refd_last();
7265 const int_val_t
*c_int
= v1
->get_val_Int();
7266 char c
= static_cast<char>(c_int
->get_val());
7269 set_val_str(new string(1, &c
));
7271 case OPTYPE_INT2UNICHAR
: {
7272 if (is_unfoldable()) break;
7273 v1
= u
.expr
.v1
->get_value_refd_last();
7274 const int_val_t
*i_int
= v1
->get_val_Int();
7275 Int i
= i_int
->get_val();
7278 set_val_ustr(int2unichar(i
));
7279 u
.ustr
.convert_str
= false;
7281 case OPTYPE_INT2FLOAT
: {
7282 if (is_unfoldable()) break;
7283 v1
= u
.expr
.v1
->get_value_refd_last();
7284 const int_val_t
*i_int
= v1
->get_val_Int();
7285 Real i_int_real
= i_int
->to_real();
7288 u
.val_Real
= i_int_real
;
7290 case OPTYPE_INT2STR
: {
7291 if (is_unfoldable()) break;
7292 v1
= u
.expr
.v1
->get_value_refd_last();
7293 const int_val_t
*i_int
= v1
->get_val_Int();
7294 string
*i_int_str
= new string(i_int
->t_str());
7297 set_val_str(i_int_str
);
7299 case OPTYPE_OCT2CHAR
: {
7300 if(is_unfoldable()) break;
7301 v1
=u
.expr
.v1
->get_value_refd_last();
7302 const string
& s
= v1
->get_val_str();
7305 set_val_str(oct2char(s
));
7307 case OPTYPE_GET_STRINGENCODING
: {
7308 if(is_unfoldable()) break;
7309 v1
= u
.expr
.v1
->get_value_refd_last();
7310 const string
& s1
= v1
->get_val_str();
7313 set_val_str(get_stringencoding(s1
));
7315 case OPTYPE_REMOVE_BOM
: {
7316 if(is_unfoldable()) break;
7317 v1
= u
.expr
.v1
->get_value_refd_last();
7318 const string
& s1
= v1
->get_val_str();
7321 set_val_str(remove_bom(s1
));
7323 case OPTYPE_ENUM2INT
: {
7324 if(is_unfoldable()) break;
7325 v1
=u
.expr
.v1
->get_value_refd_last();
7326 Type
* enum_type
= v1
->get_my_governor();
7327 const Int
& enum_val
= enum_type
->get_enum_val_byId(*(v1
->u
.val_id
));
7330 u
.val_Int
= new int_val_t(enum_val
);
7332 case OPTYPE_UNICHAR2INT
:
7333 if (is_unfoldable()) {
7334 // replace the operation with char2int() if the operand is a charstring
7335 // value to avoid its unnecessary conversion to universal charstring
7336 if (u
.expr
.v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
)
7337 u
.expr
.v_optype
= OPTYPE_CHAR2INT
;
7339 v1
=u
.expr
.v1
->get_value_refd_last();
7340 const ustring
& s
= v1
->get_val_ustr();
7343 u
.val_Int
=new int_val_t(unichar2int(s
));
7346 case OPTYPE_UNICHAR2CHAR
:
7348 if (is_unfoldable()) {
7349 // replace the operation with its operand if it is a charstring
7350 // value to avoid its unnecessary conversion to universal charstring
7351 if (v1
->get_expr_returntype(exp_val
) == Type::T_CSTR
) {
7353 copy_and_destroy(v1
);
7356 v1
= v1
->get_value_refd_last();
7357 const ustring
& s
= v1
->get_val_ustr();
7360 set_val_str(new string(s
));
7363 case OPTYPE_MULTIPLY
: { // v1 v2
7364 if (!is_unfoldable()) goto eval_arithmetic
;
7365 v1
= u
.expr
.v1
->get_value_refd_last();
7366 v2
= u
.expr
.v2
->get_value_refd_last();
7367 if (v1
->is_unfoldable()) v1
= v2
;
7368 if (v1
->is_unfoldable()) break;
7369 switch(v1
->valuetype
) {
7371 if (*v1
->get_val_Int() != 0) break;
7374 u
.val_Int
= new int_val_t((Int
)0);
7377 if (v1
->get_val_Real() != 0.0) break;
7383 FATAL_ERROR("Value::evaluate_value()");
7386 case OPTYPE_ADD
: // v1 v2
7387 case OPTYPE_SUBTRACT
:
7392 if(is_unfoldable()) break;
7393 v1
=u
.expr
.v1
->get_value_refd_last();
7394 v2
=u
.expr
.v2
->get_value_refd_last();
7395 operationtype_t ot
=u
.expr
.v_optype
;
7396 switch (v1
->valuetype
) {
7398 const int_val_t
*i1
= new int_val_t(*(v1
->get_val_Int()));
7399 const int_val_t
*i2
= new int_val_t(*(v2
->get_val_Int()));
7404 u
.val_Int
= new int_val_t(*i1
+ *i2
);
7406 case OPTYPE_SUBTRACT
:
7407 u
.val_Int
= new int_val_t(*i1
- *i2
);
7409 case OPTYPE_MULTIPLY
:
7410 u
.val_Int
= new int_val_t(*i1
* *i2
);
7413 u
.val_Int
= new int_val_t(*i1
/ *i2
);
7416 u
.val_Int
= new int_val_t(mod(*i1
, *i2
));
7419 u
.val_Int
= new int_val_t(rem(*i1
, *i2
));
7422 FATAL_ERROR("Value::evaluate_value()");
7428 ttcn3float r1
=v1
->get_val_Real();
7429 ttcn3float r2
=v2
->get_val_Real();
7436 case OPTYPE_SUBTRACT
:
7439 case OPTYPE_MULTIPLY
:
7446 FATAL_ERROR("Value::evaluate_value()");
7450 FATAL_ERROR("Value::evaluate_value()");
7453 case OPTYPE_CONCAT
: {
7454 if(is_unfoldable()) break;
7455 v1
=u
.expr
.v1
->get_value_refd_last();
7456 v2
=u
.expr
.v2
->get_value_refd_last();
7457 valuetype_t vt
= v1
->valuetype
;
7458 if (vt
== V_USTR
|| v2
->valuetype
== V_USTR
) { // V_USTR wins
7459 const ustring
& s1
= v1
->get_val_ustr();
7460 const ustring
& s2
= v2
->get_val_ustr();
7463 set_val_ustr(new ustring(s1
+ s2
));
7464 u
.ustr
.convert_str
= false;
7466 const string
& s1
= v1
->get_val_str();
7467 const string
& s2
= v2
->get_val_str();
7470 set_val_str(new string(s1
+ s2
));
7474 if(is_unfoldable()) break;
7475 v1
=u
.expr
.v1
->get_value_refd_last();
7476 v2
=u
.expr
.v2
->get_value_refd_last();
7483 if(is_unfoldable()) break;
7484 v1
=u
.expr
.v1
->get_value_refd_last();
7485 v2
=u
.expr
.v2
->get_value_refd_last();
7492 if(is_unfoldable()) break;
7493 v1
=u
.expr
.v1
->get_value_refd_last();
7494 v2
=u
.expr
.v2
->get_value_refd_last();
7501 if(is_unfoldable()) break;
7502 v1
=u
.expr
.v1
->get_value_refd_last();
7503 v2
=u
.expr
.v2
->get_value_refd_last();
7510 if(is_unfoldable()) break;
7511 v1
=u
.expr
.v1
->get_value_refd_last();
7512 v2
=u
.expr
.v2
->get_value_refd_last();
7519 if(is_unfoldable()) break;
7520 v1
=u
.expr
.v1
->get_value_refd_last();
7521 v2
=u
.expr
.v2
->get_value_refd_last();
7528 v1
= u
.expr
.v1
->get_value_refd_last();
7529 if (v1
->valuetype
== V_BOOL
) {
7530 if (v1
->get_val_bool()) {
7531 // the left operand is a literal "true"
7532 // substitute the expression with the right operand
7535 copy_and_destroy(v2
);
7537 // the left operand is a literal "false"
7538 // the result must be false regardless the right operand
7539 // because of the short circuit evaluation rule
7545 // we must keep the left operand because of the potential side effects
7546 // the right operand can only be eliminated if it is a literal "true"
7547 v2
= u
.expr
.v2
->get_value_refd_last();
7548 if (v2
->valuetype
== V_BOOL
&& v2
->get_val_bool()) {
7551 copy_and_destroy(v1
);
7556 v1
= u
.expr
.v1
->get_value_refd_last();
7557 if (v1
->valuetype
== V_BOOL
) {
7558 if (v1
->get_val_bool()) {
7559 // the left operand is a literal "true"
7560 // the result must be true regardless the right operand
7561 // because of the short circuit evaluation rule
7566 // the left operand is a literal "false"
7567 // substitute the expression with the right operand
7570 copy_and_destroy(v2
);
7573 // we must keep the left operand because of the potential side effects
7574 // the right operand can only be eliminated if it is a literal "false"
7575 v2
= u
.expr
.v2
->get_value_refd_last();
7576 if (v2
->valuetype
== V_BOOL
&& !v2
->get_val_bool()) {
7579 copy_and_destroy(v1
);
7584 if(is_unfoldable()) break;
7585 v1
=u
.expr
.v1
->get_value_refd_last();
7586 v2
=u
.expr
.v2
->get_value_refd_last();
7587 bool b
=v1
->get_val_bool() ^ v2
->get_val_bool();
7592 case OPTYPE_AND4B
: {
7593 if(is_unfoldable()) break;
7594 v1
=u
.expr
.v1
->get_value_refd_last();
7595 v2
=u
.expr
.v2
->get_value_refd_last();
7596 valuetype_t vt
=v1
->valuetype
;
7597 const string
& s1
= v1
->get_val_str();
7598 const string
& s2
= v2
->get_val_str();
7601 set_val_str(and4b(s1
, s2
));
7604 if(is_unfoldable()) break;
7605 v1
=u
.expr
.v1
->get_value_refd_last();
7606 v2
=u
.expr
.v2
->get_value_refd_last();
7607 valuetype_t vt
=v1
->valuetype
;
7608 const string
& s1
= v1
->get_val_str();
7609 const string
& s2
= v2
->get_val_str();
7612 set_val_str(or4b(s1
, s2
));
7614 case OPTYPE_XOR4B
: {
7615 if(is_unfoldable()) break;
7616 v1
=u
.expr
.v1
->get_value_refd_last();
7617 v2
=u
.expr
.v2
->get_value_refd_last();
7618 valuetype_t vt
=v1
->valuetype
;
7619 const string
& s1
= v1
->get_val_str();
7620 const string
& s2
= v2
->get_val_str();
7623 set_val_str(xor4b(s1
, s2
));
7626 if(is_unfoldable()) break;
7627 v1
=u
.expr
.v1
->get_value_refd_last();
7628 v2
=u
.expr
.v2
->get_value_refd_last();
7629 valuetype_t vt
=v1
->valuetype
;
7630 const string
& s
= v1
->get_val_str();
7631 const int_val_t
*i_int
= v2
->get_val_Int();
7632 Int i
=i_int
->get_val();
7633 if(vt
==V_OSTR
) i
*=2;
7636 set_val_str(shift_left(s
, i
));
7639 if(is_unfoldable()) break;
7640 v1
=u
.expr
.v1
->get_value_refd_last();
7641 v2
=u
.expr
.v2
->get_value_refd_last();
7642 valuetype_t vt
=v1
->valuetype
;
7643 const string
& s
= v1
->get_val_str();
7644 const int_val_t
*i_int
= v2
->get_val_Int();
7645 Int i
=i_int
->get_val();
7646 if(vt
==V_OSTR
) i
*=2;
7649 set_val_str(shift_right(s
, i
));
7652 if(is_unfoldable()) break;
7653 v1
=u
.expr
.v1
->get_value_refd_last();
7654 v2
=u
.expr
.v2
->get_value_refd_last();
7655 valuetype_t vt
=v1
->valuetype
;
7656 const int_val_t
*i_int
=v2
->get_val_Int();
7657 Int i
=i_int
->get_val();
7659 const ustring
& s
= v1
->get_val_ustr();
7662 set_val_ustr(rotate_left(s
, i
));
7663 u
.ustr
.convert_str
= false;
7666 if(vt
==V_OSTR
) i
*=2;
7667 const string
& s
= v1
->get_val_str();
7670 set_val_str(rotate_left(s
, i
));
7674 if(is_unfoldable()) break;
7675 v1
=u
.expr
.v1
->get_value_refd_last();
7676 v2
=u
.expr
.v2
->get_value_refd_last();
7677 valuetype_t vt
=v1
->valuetype
;
7678 const int_val_t
*i_int
=v2
->get_val_Int();
7679 Int i
=i_int
->get_val();
7681 const ustring
& s
= v1
->get_val_ustr();
7684 set_val_ustr(rotate_right(s
, i
));
7685 u
.ustr
.convert_str
= false;
7688 if(vt
==V_OSTR
) i
*=2;
7689 const string
& s
= v1
->get_val_str();
7692 set_val_str(rotate_right(s
, i
));
7695 case OPTYPE_INT2BIT
: {
7696 if (is_unfoldable()) break;
7697 v1
= u
.expr
.v1
->get_value_refd_last();
7698 v2
= u
.expr
.v2
->get_value_refd_last();
7699 const int_val_t
*i1_int
= v1
->get_val_Int();
7700 const int_val_t
*i2_int
= v2
->get_val_Int();
7701 string
*val
= int2bit(*i1_int
, i2_int
->get_val());
7706 case OPTYPE_INT2HEX
: {
7707 if (is_unfoldable()) break;
7708 v1
= u
.expr
.v1
->get_value_refd_last();
7709 v2
= u
.expr
.v2
->get_value_refd_last();
7710 const int_val_t
*i1_int
= v1
->get_val_Int();
7711 const int_val_t
*i2_int
= v2
->get_val_Int();
7712 // Do it before the `clean_up'. i2_int is already checked.
7713 string
*val
= int2hex(*i1_int
, i2_int
->get_val());
7718 case OPTYPE_INT2OCT
: {
7719 if (is_unfoldable()) break;
7720 v1
= u
.expr
.v1
->get_value_refd_last();
7721 v2
= u
.expr
.v2
->get_value_refd_last();
7722 const int_val_t
i1_int(*v1
->get_val_Int());
7723 // `v2' is a native integer.
7724 Int i2_int
= v2
->get_val_Int()->get_val() * 2;
7727 set_val_str(int2hex(i1_int
, i2_int
));
7729 case OPTYPE_SUBSTR
: {
7730 if(is_unfoldable()) break;
7731 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7732 v2
=u
.expr
.v2
->get_value_refd_last();
7733 v3
=u
.expr
.v3
->get_value_refd_last();
7734 valuetype_t vt
=v1
->valuetype
;
7735 const int_val_t
*i2_int
=v2
->get_val_Int();
7736 const int_val_t
*i3_int
=v3
->get_val_Int();
7737 Int i2
=i2_int
->get_val();
7738 Int i3
=i3_int
->get_val();
7740 const ustring
& s
= v1
->get_val_ustr();
7743 set_val_ustr(new ustring(s
.substr(i2
, i3
)));
7744 u
.ustr
.convert_str
= false;
7751 const string
& s
= v1
->get_val_str();
7754 set_val_str(new string(s
.substr(i2
, i3
)));
7757 case OPTYPE_REPLACE
: {
7758 if(is_unfoldable()) break;
7759 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7760 v2
=u
.expr
.v2
->get_value_refd_last();
7761 v3
=u
.expr
.v3
->get_value_refd_last();
7762 v4
=u
.expr
.ti4
->get_specific_value()->get_value_refd_last();
7763 valuetype_t vt
=v1
->valuetype
;
7764 const int_val_t
*i2_int
=v2
->get_val_Int();
7765 const int_val_t
*i3_int
=v3
->get_val_Int();
7766 Int i2
=i2_int
->get_val();
7767 Int i3
=i3_int
->get_val();
7770 string
*s1
= new string(v1
->get_val_str());
7771 const string
& s2
= v4
->get_val_str();
7774 s1
->replace(i2
, i3
, s2
);
7778 string
*s1
= new string(v1
->get_val_str());
7779 const string
& s2
= v4
->get_val_str();
7782 s1
->replace(i2
, i3
, s2
);
7788 string
*s1
= new string(v1
->get_val_str());
7789 const string
& s2
= v4
->get_val_str();
7792 s1
->replace(i2
, i3
, s2
);
7796 string
*s1
= new string(v1
->get_val_str());
7797 const string
& s2
= v4
->get_val_str();
7800 s1
->replace(i2
, i3
, s2
);
7804 ustring
*s1
= new ustring(v1
->get_val_ustr());
7805 const ustring
& s2
= v4
->get_val_ustr();
7808 s1
->replace(i2
, i3
, s2
);
7810 u
.ustr
.convert_str
= false;
7813 FATAL_ERROR("Value::evaluate_value()");
7816 case OPTYPE_REGEXP
: {
7817 if (is_unfoldable()) break;
7818 v1
=u
.expr
.ti1
->get_specific_value()->get_value_refd_last();
7819 v2
=u
.expr
.t2
->get_specific_value()->get_value_refd_last();
7820 v3
=u
.expr
.v3
->get_value_refd_last();
7821 const int_val_t
*i3_int
= v3
->get_val_Int();
7822 Int i3
= i3_int
->get_val();
7823 if (v1
->valuetype
== V_CSTR
) {
7824 const string
& s1
= v1
->get_val_str();
7825 const string
& s2
= v2
->get_val_str();
7826 string
*result
= regexp(s1
, s2
, i3
);
7829 set_val_str(result
);
7830 } if (v1
->valuetype
== V_USTR
) {
7831 const ustring
& s1
= v1
->get_val_ustr();
7832 const ustring
& s2
= v2
->get_val_ustr();
7833 ustring
*result
= regexp(s1
, s2
, i3
);
7836 set_val_ustr(result
);
7837 u
.ustr
.convert_str
= false;
7840 case OPTYPE_LENGTHOF
:{
7841 if(is_unfoldable()) break;
7842 v1
=u
.expr
.ti1
->get_Template()->get_specific_value()
7843 ->get_value_refd_last();
7845 if(v1
->is_string_type(exp_val
)) {
7846 i
=v1
->get_val_strlen();
7847 } else { // v1 is be seq/set of or array
7848 switch (v1
->valuetype
) {
7852 if(v1
->u
.val_vs
->is_indexed())
7853 { i
= v1
->u
.val_vs
->get_nof_ivs();}
7854 else { i
= v1
->u
.val_vs
->get_nof_vs();}
7857 FATAL_ERROR("Value::evaluate_value()");
7862 u
.val_Int
=new int_val_t(i
);
7864 case OPTYPE_SIZEOF
: {
7865 Int i
=chk_eval_expr_sizeof(refch
, exp_val
);
7869 u
.val_Int
=new int_val_t(i
);
7872 case OPTYPE_ISVALUE
: {
7873 if(is_unfoldable()) break;
7874 bool is_singleval
= !u
.expr
.ti1
->get_DerivedRef()
7875 && u
.expr
.ti1
->get_Template()->is_Value();
7877 Value
* other_val
= u
.expr
.ti1
->get_Template()->get_Value();
7878 is_singleval
= other_val
->evaluate_isvalue(false);
7879 // is_singleval now contains the compile-time result of isvalue
7884 u
.val_bool
= is_singleval
;
7886 case OPTYPE_ISCHOSEN_V
: {
7887 if (is_unfoldable()) break;
7888 v1
= u
.expr
.v1
->get_value_refd_last();
7889 bool b
= v1
->field_is_chosen(*u
.expr
.i2
);
7894 case OPTYPE_VALUEOF
: // ti1
7895 if (!u
.expr
.ti1
->get_DerivedRef() &&
7896 u
.expr
.ti1
->get_Template()->is_Value() &&
7897 !u
.expr
.ti1
->get_Type()) {
7898 // FIXME actually if the template instance has a type
7899 // it might still be foldable.
7900 // the argument is a single specific value
7901 v1
= u
.expr
.ti1
->get_Template()->get_Value();
7902 Type
*governor
= my_governor
;
7903 if (governor
== NULL
) {
7904 governor
= u
.expr
.ti1
->get_expr_governor(exp_val
);
7905 if (governor
!= NULL
) governor
= governor
->get_type_refd_last();
7907 if (governor
== NULL
) governor
= v1
->get_my_governor()->get_type_refd_last();
7908 if (governor
== NULL
)
7909 FATAL_ERROR("Value::evaluate_value()");
7911 valuetype
= v1
->valuetype
;
7913 set_my_governor(governor
);
7914 if (valuetype
== V_REFD
&& u
.ref
.refd_last
== v1
)
7915 u
.ref
.refd_last
= this;
7916 v1
->valuetype
= V_ERROR
;
7920 case OPTYPE_UNDEF_RUNNING
:
7922 FATAL_ERROR("Value::evaluate_value()");
7926 bool Value::evaluate_isvalue(bool from_sequence
)
7928 switch (valuetype
) {
7930 // Omit is not a value unless a member of a sequence or set
7931 return from_sequence
;
7934 case V_NULL
: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7935 case V_BOOL
: /**< boolean */
7936 case V_NAMEDINT
: /**< integer / named number */
7937 case V_NAMEDBITS
: /**< named bits (identifiers) */
7938 case V_INT
: /**< integer */
7939 case V_REAL
: /**< real/float */
7940 case V_ENUM
: /**< enumerated */
7941 case V_BSTR
: /**< bitstring */
7942 case V_HSTR
: /**< hexstring */
7943 case V_OSTR
: /**< octetstring */
7944 case V_CSTR
: /**< charstring */
7945 case V_USTR
: /**< universal charstring */
7946 case V_ISO2022STR
: /**< ISO-2022 string (treat as octetstring) */
7947 case V_CHARSYMS
: /**< parsed ASN.1 universal string notation */
7948 case V_OID
: /**< object identifier */
7949 case V_ROID
: /**< relative object identifier */
7950 case V_VERDICT
: /**< all verdicts */
7951 return true; // values of built-in types return true
7953 // Code below was adapted from is_unfoldable(), false returned early.
7955 return u
.choice
.alt_value
->evaluate_isvalue(false);
7960 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
7961 if (!u
.val_vs
->get_v_byIndex(i
)->evaluate_isvalue(false)) {
7969 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
7970 if (!u
.val_nvs
->get_nv_byIndex(i
)->get_value()
7971 ->evaluate_isvalue(true)) return false;
7976 // alas, get_value_refd_last prevents this function from const
7977 return get_value_refd_last()->evaluate_isvalue(false);
7980 switch (u
.expr
.v_optype
) {
7981 // A constant null component reference is a corner case: it is foldable
7982 // but escapes unmodified from evaluate_value.
7983 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7984 // or is transformed into some other valuetype in evaluate_value.
7985 case OPTYPE_COMP_NULL
:
7988 break; // and fall through to the FATAL_ERROR
7992 FATAL_ERROR("Value::evaluate_isvalue()");
7998 void Value::evaluate_macro(Type::expected_value_t exp_val
)
8001 case MACRO_MODULEID
:
8003 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8004 set_val_str(new string(my_scope
->get_scope_mod()
8005 ->get_modid().get_dispname()));
8008 case MACRO_FILENAME
:
8009 case MACRO_BFILENAME
: {
8010 const char *t_filename
= get_filename();
8012 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8013 set_val_str(new string(t_filename
));
8016 case MACRO_FILEPATH
: {
8017 const char *t_filename
= get_filename();
8019 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8020 char *t_filepath
= canonize_input_file(t_filename
);
8022 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8023 set_val_str(new string(t_filepath
));
8027 case MACRO_LINENUMBER
: {
8028 int t_lineno
= get_first_line();
8030 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8031 set_val_str(new string(Int2string(t_lineno
)));
8034 case MACRO_LINENUMBER_C
: {
8035 int t_lineno
= get_first_line();
8037 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8038 u
.val_Int
= new int_val_t(t_lineno
);
8041 case MACRO_DEFINITIONID
: {
8042 // cut the second part from the fullname separated by dots
8043 const string
& t_fullname
= get_fullname();
8044 size_t first_char
= t_fullname
.find('.') + 1;
8045 if (first_char
>= t_fullname
.size())
8046 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8047 t_fullname
.c_str());
8048 set_val_str(new string(t_fullname
.substr(first_char
,
8049 t_fullname
.find('.', first_char
) - first_char
)));
8053 if (!my_scope
) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8054 set_val_str(new string(my_scope
->get_scopeMacro_name()));
8058 case MACRO_TESTCASEID
: {
8059 if (exp_val
== Type::EXPECTED_CONSTANT
||
8060 exp_val
== Type::EXPECTED_STATIC_VALUE
) {
8061 error("A %s value was expected instead of macro `%%testcaseId', "
8062 "which is evaluated at runtime",
8063 exp_val
== Type::EXPECTED_CONSTANT
? "constant" : "static");
8067 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8068 Ttcn::StatementBlock
*my_sb
=
8069 dynamic_cast<Ttcn::StatementBlock
*>(my_scope
);
8071 error("Usage of macro %%testcaseId is allowed only within the "
8072 "statement blocks of functions, altsteps and testcases");
8075 Ttcn::Definition
*my_def
= my_sb
->get_my_def();
8077 error("Macro %%testcaseId cannot be used in the control part. "
8078 "It is allowed only within the statement blocks of functions, "
8079 "altsteps and testcases");
8082 if (my_def
->get_asstype() == Assignment::A_TESTCASE
) {
8083 // folding is possible only within testcases
8084 set_val_str(new string(my_def
->get_id().get_dispname()));
8089 FATAL_ERROR("Value::evaluate_macro()");
8093 set_valuetype(V_ERROR
);
8096 void Value::add_id(Identifier
*p_id
)
8100 if(u
.ids
->has_key(p_id
->get_name())) {
8101 error("Duplicate named bit `%s'", p_id
->get_dispname().c_str());
8102 // The Value does not take ownership for the identifier,
8103 // so it must be deleted (add_is acts as a sink).
8106 else u
.ids
->add(p_id
->get_name(), p_id
);
8109 FATAL_ERROR("Value::add_id()");
8113 Value
* Value::get_value_refd_last(ReferenceChain
*refch
,
8114 Type::expected_value_t exp_val
)
8116 set_lowerid_to_ref();
8117 switch (valuetype
) {
8119 // there might be a better place for this
8120 chk_invoke(exp_val
);
8123 // use the cache if available
8124 if (u
.ref
.refd_last
) return u
.ref
.refd_last
;
8126 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
8128 // the referred definition is not found
8129 set_valuetype(V_ERROR
);
8131 switch (ass
->get_asstype()) {
8132 case Assignment::A_OBJECT
:
8133 case Assignment::A_OS
: {
8134 // the referred definition is an ASN.1 object or object set
8135 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
8136 if (!setting
|| setting
->get_st() == S_ERROR
) {
8137 // remain silent, the error has been already reported
8138 set_valuetype(V_ERROR
);
8140 } else if (setting
->get_st() != S_V
) {
8141 u
.ref
.ref
->error("InformationFromObjects construct `%s' does not"
8142 " refer to a value", u
.ref
.ref
->get_dispname().c_str());
8143 set_valuetype(V_ERROR
);
8148 refch
->mark_state();
8149 destroy_refch
= false;
8151 refch
= new ReferenceChain(this,
8152 "While searching referenced value");
8153 destroy_refch
= true;
8155 if (refch
->add(get_fullname())) {
8156 Value
*v_refd
= dynamic_cast<Value
*>(setting
);
8157 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8158 // in case of circular recursion the valuetype is already set
8159 // to V_ERROR, so don't set the cache
8160 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8162 // a circular recursion was detected
8163 set_valuetype(V_ERROR
);
8165 if (destroy_refch
) delete refch
;
8166 else refch
->prev_state();
8168 case Assignment::A_CONST
: {
8169 // the referred definition is a constant
8172 refch
->mark_state();
8173 destroy_refch
= false;
8175 refch
= new ReferenceChain(this,
8176 "While searching referenced value");
8177 destroy_refch
= true;
8179 if (refch
->add(get_fullname())) {
8180 Ttcn::FieldOrArrayRefs
*subrefs
= u
.ref
.ref
->get_subrefs();
8181 Value
*v_refd
= ass
->get_Value()
8182 ->get_refd_sub_value(subrefs
, 0,
8183 u
.ref
.ref
->getUsedInIsbound(), refch
);
8185 Value
*v_last
= v_refd
->get_value_refd_last(refch
);
8186 // in case of circular recursion the valuetype is already set
8187 // to V_ERROR, so don't set the cache
8188 if (valuetype
== V_REFD
) u
.ref
.refd_last
= v_last
;
8189 } else if (subrefs
&& subrefs
->has_unfoldable_index()) {
8190 u
.ref
.refd_last
= this;
8191 } else if (u
.ref
.ref
->getUsedInIsbound()) {
8192 u
.ref
.refd_last
= this;
8194 // the sub-reference points to a non-existent field
8195 set_valuetype(V_ERROR
);
8198 // a circular recursion was detected
8199 set_valuetype(V_ERROR
);
8201 if (destroy_refch
) delete refch
;
8202 else refch
->prev_state();
8204 case Assignment::A_EXT_CONST
:
8205 case Assignment::A_MODULEPAR
:
8206 case Assignment::A_VAR
:
8207 case Assignment::A_FUNCTION_RVAL
:
8208 case Assignment::A_EXT_FUNCTION_RVAL
:
8209 case Assignment::A_PAR_VAL_IN
:
8210 case Assignment::A_PAR_VAL_OUT
:
8211 case Assignment::A_PAR_VAL_INOUT
:
8212 // the referred definition is not a constant
8213 u
.ref
.refd_last
= this;
8215 case Assignment::A_FUNCTION
:
8216 case Assignment::A_EXT_FUNCTION
:
8217 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8218 "call of %s, which does not have return type",
8219 ass
->get_description().c_str());
8220 set_valuetype(V_ERROR
);
8222 case Assignment::A_FUNCTION_RTEMP
:
8223 case Assignment::A_EXT_FUNCTION_RTEMP
:
8224 u
.ref
.ref
->error("Reference to a value was expected instead of a "
8225 "call of %s, which returns a template",
8226 ass
->get_description().c_str());
8227 set_valuetype(V_ERROR
);
8230 u
.ref
.ref
->error("Reference to a value was expected instead of %s",
8231 ass
->get_description().c_str());
8232 set_valuetype(V_ERROR
);
8235 if (valuetype
== V_REFD
) return u
.ref
.refd_last
;
8239 // try to evaluate the expression
8242 refch
->mark_state();
8243 destroy_refch
=false;
8246 refch
=new ReferenceChain(this, "While evaluating expression");
8249 if(refch
->add(get_fullname())) evaluate_value(refch
, exp_val
);
8250 else set_valuetype(V_ERROR
);
8251 if(destroy_refch
) delete refch
;
8252 else refch
->prev_state();
8255 evaluate_macro(exp_val
);
8258 // return this for all other value types
8263 map
<Value
*, void> Value::UnfoldabilityCheck::running
;
8265 /* Note that the logic here needs to be in sync with evaluate_value,
8266 * and possibly others, i.e. if evaluate_value is called for a Value
8267 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8268 bool Value::is_unfoldable(ReferenceChain
*refch
,
8269 Type::expected_value_t exp_val
)
8271 if (UnfoldabilityCheck::is_running(this)) {
8272 // This function is already running on this value => infinite recursion
8276 UnfoldabilityCheck
checker(this);
8278 if (get_needs_conversion()) return true;
8279 switch (valuetype
) {
8283 case V_UNDEF_LOWERID
:
8287 // these value types are eliminated during semantic analysis
8288 FATAL_ERROR("Value::is_unfoldable()");
8293 return u
.choice
.alt_value
->is_unfoldable(refch
, exp_val
);
8297 if (!is_indexed()) {
8298 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
8299 if (u
.val_vs
->get_v_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8303 for(size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
8304 if (u
.val_vs
->get_iv_byIndex(i
)->is_unfoldable(refch
, exp_val
))
8311 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
8312 if (u
.val_nvs
->get_nv_byIndex(i
)->get_value()
8313 ->is_unfoldable(refch
, exp_val
)) return true;
8319 for (size_t i
= 0; i
< u
.oid_comps
->size(); ++i
) {
8320 if ((*u
.oid_comps
)[i
]->is_variable()) return true;
8324 Value
*v_last
=get_value_refd_last(refch
, exp_val
);
8325 if(v_last
==this) return true; // there weren't any references to chase
8326 else return v_last
->is_unfoldable(refch
, exp_val
);
8329 // classify the unchecked ischosen() operation, if it was not done so far
8330 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
8331 if(u
.expr
.state
==EXPR_CHECKING_ERR
) return true;
8332 switch (u
.expr
.v_optype
) {
8333 case OPTYPE_RND
: // -
8334 case OPTYPE_COMP_MTC
:
8335 case OPTYPE_COMP_SYSTEM
:
8336 case OPTYPE_COMP_SELF
:
8337 case OPTYPE_COMP_RUNNING_ANY
:
8338 case OPTYPE_COMP_RUNNING_ALL
:
8339 case OPTYPE_COMP_ALIVE_ANY
:
8340 case OPTYPE_COMP_ALIVE_ALL
:
8341 case OPTYPE_TMR_RUNNING_ANY
:
8342 case OPTYPE_GETVERDICT
:
8343 case OPTYPE_TESTCASENAME
:
8344 case OPTYPE_PROF_RUNNING
:
8345 case OPTYPE_RNDWITHVAL
: // v1
8346 case OPTYPE_MATCH
: // v1 t2
8347 case OPTYPE_UNDEF_RUNNING
: // v1
8348 case OPTYPE_COMP_RUNNING
:
8349 case OPTYPE_COMP_ALIVE
:
8350 case OPTYPE_TMR_READ
:
8351 case OPTYPE_TMR_RUNNING
:
8352 case OPTYPE_ACTIVATE
:
8353 case OPTYPE_ACTIVATE_REFD
:
8354 case OPTYPE_EXECUTE
: // r1 [v2]
8355 case OPTYPE_EXECUTE_REFD
:
8356 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
8357 case OPTYPE_ISCHOSEN
:
8358 case OPTYPE_ISCHOSEN_T
:
8359 case OPTYPE_SIZEOF
: // ti1
8362 case OPTYPE_OCT2UNICHAR
:
8363 case OPTYPE_UNICHAR2OCT
:
8364 case OPTYPE_ENCODE_BASE64
:
8365 case OPTYPE_DECODE_BASE64
:
8367 case OPTYPE_COMP_NULL
: // -
8369 case OPTYPE_UNARYPLUS
: // v1
8370 case OPTYPE_UNARYMINUS
:
8373 case OPTYPE_BIT2HEX
:
8374 case OPTYPE_BIT2INT
:
8375 case OPTYPE_BIT2OCT
:
8376 case OPTYPE_BIT2STR
:
8377 case OPTYPE_CHAR2INT
:
8378 case OPTYPE_CHAR2OCT
:
8379 case OPTYPE_FLOAT2INT
:
8380 case OPTYPE_FLOAT2STR
:
8381 case OPTYPE_HEX2BIT
:
8382 case OPTYPE_HEX2INT
:
8383 case OPTYPE_HEX2OCT
:
8384 case OPTYPE_HEX2STR
:
8385 case OPTYPE_INT2CHAR
:
8386 case OPTYPE_INT2FLOAT
:
8387 case OPTYPE_INT2STR
:
8388 case OPTYPE_INT2UNICHAR
:
8389 case OPTYPE_OCT2BIT
:
8390 case OPTYPE_OCT2CHAR
:
8391 case OPTYPE_OCT2HEX
:
8392 case OPTYPE_OCT2INT
:
8393 case OPTYPE_OCT2STR
:
8394 case OPTYPE_STR2BIT
:
8395 case OPTYPE_STR2FLOAT
:
8396 case OPTYPE_STR2HEX
:
8397 case OPTYPE_STR2INT
:
8398 case OPTYPE_STR2OCT
:
8399 case OPTYPE_UNICHAR2INT
:
8400 case OPTYPE_UNICHAR2CHAR
:
8401 case OPTYPE_ENUM2INT
:
8402 case OPTYPE_GET_STRINGENCODING
:
8403 case OPTYPE_REMOVE_BOM
:
8404 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8405 case OPTYPE_ISBOUND
: /*{
8406 //TODO once we have the time for it make isbound foldable.
8407 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8408 Template* temp = u.expr.ti1->get_Template();
8409 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8410 Value* specificValue = temp->get_specific_value();
8411 if (specificValue->get_valuetype() == Value::V_REFD) {
8415 return specificValue->is_unfoldable(refch, exp_val);
8416 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8421 case OPTYPE_ISPRESENT
:
8422 // TODO: "if you have motivation"
8424 case OPTYPE_ISVALUE
: // ti1
8426 case OPTYPE_LENGTHOF
: // ti1
8427 return u
.expr
.ti1
->get_DerivedRef() != 0
8428 || u
.expr
.ti1
->get_Template()->get_templatetype()
8429 != Template::SPECIFIC_VALUE
8430 || u
.expr
.ti1
->get_Template()->get_specific_value()
8431 ->is_unfoldable(refch
, exp_val
);
8435 if (!u
.expr
.v1
->is_string_type(exp_val
)) return true;
8437 case OPTYPE_ADD
: // v1 v2
8438 case OPTYPE_SUBTRACT
:
8439 case OPTYPE_MULTIPLY
:
8455 case OPTYPE_INT2BIT
:
8456 case OPTYPE_INT2HEX
:
8457 case OPTYPE_INT2OCT
:
8458 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8459 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
);
8460 case OPTYPE_AND
: // short-circuit evaluation
8461 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8462 || (u
.expr
.v1
->get_val_bool() &&
8463 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8464 case OPTYPE_OR
: // short-circuit evaluation
8465 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8466 || (!u
.expr
.v1
->get_val_bool() &&
8467 u
.expr
.v2
->is_unfoldable(refch
, exp_val
));
8469 if (!u
.expr
.ti1
->get_specific_value()) return true;
8470 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8471 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8472 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8473 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8475 if (!u
.expr
.ti1
->get_specific_value() ||
8476 !u
.expr
.t2
->get_specific_value()) return true;
8477 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8478 || u
.expr
.t2
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8479 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8481 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
)
8482 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8483 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
);
8484 case OPTYPE_REPLACE
: {
8485 if (!u
.expr
.ti1
->get_specific_value() ||
8486 !u
.expr
.ti4
->get_specific_value()) return true;
8487 if (!u
.expr
.ti1
->is_string_type(exp_val
)) return true;
8488 return u
.expr
.ti1
->get_specific_value()->is_unfoldable(refch
, exp_val
)
8489 || u
.expr
.v2
->is_unfoldable(refch
, exp_val
)
8490 || u
.expr
.v3
->is_unfoldable(refch
, exp_val
)
8491 || u
.expr
.ti4
->get_specific_value()->is_unfoldable(refch
, exp_val
);
8493 case OPTYPE_VALUEOF
: // ti1
8494 /* \todo if you have motivation to implement the eval function
8497 case OPTYPE_ISCHOSEN_V
:
8498 return u
.expr
.v1
->is_unfoldable(refch
, exp_val
);
8499 case OPTYPE_LOG2STR
:
8500 case OPTYPE_TTCN2STRING
:
8503 FATAL_ERROR("Value::is_unfoldable()");
8505 break; // should never get here
8508 case MACRO_TESTCASEID
:
8509 // this is known only at runtime
8515 // all literal values are foldable
8520 Value
* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs
*subrefs
,
8521 size_t start_i
, bool usedInIsbound
,
8522 ReferenceChain
*refch
)
8524 if (!subrefs
) return this;
8526 for (size_t i
= start_i
; i
< subrefs
->get_nof_refs(); i
++) {
8528 v
= v
->get_value_refd_last(refch
);
8529 switch(v
->valuetype
) {
8538 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
8539 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
8540 v
= v
->get_refd_field_value(*ref
->get_id(), usedInIsbound
, *ref
);
8541 else v
= v
->get_refd_array_value(ref
->get_val(), usedInIsbound
, refch
);
8546 Value
*Value::get_refd_field_value(const Identifier
& field_id
,
8547 bool usedInIsbound
, const Location
& loc
)
8549 if (valuetype
== V_OMIT
) {
8550 loc
.error("Reference to field `%s' of omit value `%s'",
8551 field_id
.get_dispname().c_str(), get_fullname().c_str());
8554 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8555 Type
*t
= my_governor
->get_type_refd_last();
8556 switch (t
->get_typetype()) {
8560 case Type::T_CHOICE_A
:
8561 case Type::T_CHOICE_T
:
8562 case Type::T_OPENTYPE
:
8563 case Type::T_ANYTYPE
:
8564 if (!t
->has_comp_withName(field_id
)) {
8565 loc
.error("Reference to non-existent union field `%s' in type `%s'",
8566 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8568 } else if (valuetype
!= V_CHOICE
) {
8569 // remain silent, the error is already reported
8571 } else if (*u
.choice
.alt_name
== field_id
) {
8573 return u
.choice
.alt_value
;
8575 if (!usedInIsbound
) {
8576 loc
.error("Reference to inactive field `%s' in a value of union type "
8577 "`%s'. The active field is `%s'",
8578 field_id
.get_dispname().c_str(), t
->get_typename().c_str(),
8579 u
.choice
.alt_name
->get_dispname().c_str());
8585 if (!t
->has_comp_withName(field_id
)) {
8586 loc
.error("Reference to non-existent record field `%s' in type `%s'",
8587 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8589 } else if (valuetype
!= V_SEQ
) {
8590 // remain silent, the error has been already reported
8595 if (!t
->has_comp_withName(field_id
)) {
8596 loc
.error("Reference to non-existent set field `%s' in type `%s'",
8597 field_id
.get_dispname().c_str(), t
->get_typename().c_str());
8599 } else if (valuetype
!= V_SET
) {
8600 // remain silent, the error has been already reported
8604 loc
.error("Invalid field reference `%s': type `%s' "
8605 "does not have fields", field_id
.get_dispname().c_str(),
8606 t
->get_typename().c_str());
8609 // the common end for record & set types
8610 if (u
.val_nvs
->has_nv_withName(field_id
)) {
8612 return u
.val_nvs
->get_nv_byName(field_id
)->get_value();
8613 } else if (!is_asn1()) {
8614 if (!usedInIsbound
) {
8615 loc
.error("Reference to unbound field `%s'",
8616 field_id
.get_dispname().c_str());
8617 // this is an error in TTCN-3, which has been already reported
8621 CompField
*cf
= t
->get_comp_byName(field_id
);
8622 if (cf
->get_is_optional()) {
8623 // creating an explicit omit value
8624 Value
*v
= new Value(V_OMIT
);
8625 v
->set_fullname(get_fullname() + "." + field_id
.get_dispname());
8626 v
->set_my_scope(get_my_scope());
8627 u
.val_nvs
->add_nv(new NamedValue(field_id
.clone(), v
));
8629 } else if (cf
->has_default()) {
8630 // returning the component's default value
8631 return cf
->get_defval();
8633 // this is an error in ASN.1, which has been already reported
8639 Value
*Value::get_refd_array_value(Value
*array_index
, bool usedInIsbound
,
8640 ReferenceChain
*refch
)
8642 Value
*v_index
= array_index
->get_value_refd_last(refch
);
8644 bool index_available
= false;
8645 if (!v_index
->is_unfoldable()) {
8646 if (v_index
->valuetype
== V_INT
) {
8647 index
= v_index
->get_val_Int()->get_val();
8648 index_available
= true;
8650 array_index
->error("An integer value was expected as index");
8653 if (valuetype
== V_OMIT
) {
8654 array_index
->error("Accessing an element with index of omit value `%s'",
8655 get_fullname().c_str());
8658 if (!my_governor
) FATAL_ERROR("Value::get_refd_field_value()");
8659 Type
*t
= my_governor
->get_type_refd_last();
8660 switch (t
->get_typetype()) {
8665 if (index_available
) {
8667 array_index
->error("A non-negative integer value was expected "
8668 "instead of %s for indexing a value of `record "
8669 "of' type `%s'", Int2string(index
).c_str(),
8670 t
->get_typename().c_str());
8673 switch (valuetype
) {
8675 if (!is_indexed()) {
8676 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8677 if (!usedInIsbound
) {
8678 array_index
->error("Index overflow in a value of `record of' "
8679 "type `%s': the index is %s, but the value "
8680 "has only %lu elements",
8681 t
->get_typename().c_str(),
8682 Int2string(index
).c_str(),
8683 (unsigned long)u
.val_vs
->get_nof_vs());
8687 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8688 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8689 temp
->error("Not used symbol is not allowed in this context");
8690 return u
.val_vs
->get_v_byIndex(index
);
8693 // Search the appropriate constant index.
8694 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8695 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8696 ->get_value_refd_last();
8697 if (iv_index
->get_valuetype() != V_INT
) continue;
8698 if (iv_index
->get_val_Int()->get_val() == index
)
8699 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8705 // remain silent, the error has been already reported
8709 // the error has been reported above
8713 if (index_available
) {
8715 array_index
->error("A non-negative integer value was expected "
8716 "instead of %s for indexing a value of `set of' type `%s'",
8717 Int2string(index
).c_str(), t
->get_typename().c_str());
8720 switch (valuetype
) {
8722 if (!is_indexed()) {
8723 if (index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs())) {
8724 if (!usedInIsbound
) {
8725 array_index
->error("Index overflow in a value of `set of' type "
8726 "`%s': the index is %s, but the value has "
8727 "only %lu elements",
8728 t
->get_typename().c_str(),
8729 Int2string(index
).c_str(),
8730 (unsigned long)u
.val_vs
->get_nof_vs());
8734 Value
* temp
= u
.val_vs
->get_v_byIndex(index
);
8735 if(temp
->get_value_refd_last()->get_valuetype() == V_NOTUSED
)
8736 temp
->error("Not used symbol is not allowed in this context");
8740 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8741 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8742 ->get_value_refd_last();
8743 if (iv_index
->get_valuetype() != V_INT
) continue;
8744 if (iv_index
->get_val_Int()->get_val() == index
)
8745 return u
.val_vs
->get_iv_byIndex(i
)->get_value();
8751 // remain silent, the error has been already reported
8755 // the error has been reported above
8759 if (index_available
) {
8760 Ttcn::ArrayDimension
*dim
= t
->get_dimension();
8761 dim
->chk_index(v_index
, Type::EXPECTED_CONSTANT
);
8762 if (valuetype
== V_ARRAY
&& !dim
->get_has_error()) {
8763 // perform the index transformation
8764 index
-= dim
->get_offset();
8765 if (!is_indexed()) {
8766 // check for index underflow/overflow or too few elements in the
8769 index
>= static_cast<Int
>(u
.val_vs
->get_nof_vs()))
8771 else return u
.val_vs
->get_v_byIndex(index
);
8773 if (index
< 0) return 0;
8774 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
8775 Value
*iv_index
= u
.val_vs
->get_iv_byIndex(i
)->get_index()
8776 ->get_value_refd_last();
8777 if (iv_index
->get_valuetype() != V_INT
) continue;
8778 if (iv_index
->get_val_Int()->get_val() == index
)
8779 return u
.val_vs
->get_iv_byIndex(index
)->get_value();
8784 // remain silent, the error has been already reported
8788 // the error has been reported above
8792 case Type::T_BSTR_A
:
8797 case Type::T_UTF8STRING
:
8798 case Type::T_NUMERICSTRING
:
8799 case Type::T_PRINTABLESTRING
:
8800 case Type::T_TELETEXSTRING
:
8801 case Type::T_VIDEOTEXSTRING
:
8802 case Type::T_IA5STRING
:
8803 case Type::T_GRAPHICSTRING
:
8804 case Type::T_VISIBLESTRING
:
8805 case Type::T_GENERALSTRING
:
8806 case Type::T_UNIVERSALSTRING
:
8807 case Type::T_BMPSTRING
:
8808 case Type::T_UTCTIME
:
8809 case Type::T_GENERALIZEDTIME
:
8810 case Type::T_OBJECTDESCRIPTOR
:
8811 if (index_available
) return get_string_element(index
, *array_index
);
8814 array_index
->error("Invalid array element reference: type `%s' cannot "
8815 "be indexed", t
->get_typename().c_str());
8820 Value
*Value::get_string_element(const Int
& index
, const Location
& loc
)
8823 loc
.error("A non-negative integer value was expected instead of %s "
8824 "for indexing a string element", Int2string(index
).c_str());
8827 size_t string_length
;
8828 switch (valuetype
) {
8833 string_length
= u
.str
.val_str
->size();
8836 string_length
= u
.str
.val_str
->size() / 2;
8839 string_length
= u
.ustr
.val_ustr
->size();
8842 // remain silent, the error has been already reported
8845 if (index
>= static_cast<Int
>(string_length
)) {
8846 loc
.error("Index overflow when accessing a string element: "
8847 "the index is %s, but the string has only %lu elements",
8848 Int2string(index
).c_str(), (unsigned long) string_length
);
8851 switch (valuetype
) {
8856 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8857 return (*u
.str
.str_elements
)[index
];
8859 Value
*t_val
= new Value(valuetype
,
8860 new string(u
.str
.val_str
->substr(index
, 1)));
8861 add_string_element(index
, t_val
, u
.str
.str_elements
);
8865 if (u
.str
.str_elements
&& u
.str
.str_elements
->has_key(index
))
8866 return (*u
.str
.str_elements
)[index
];
8868 Value
*t_val
= new Value(V_OSTR
,
8869 new string(u
.str
.val_str
->substr(2 * index
, 2)));
8870 add_string_element(index
, t_val
, u
.str
.str_elements
);
8874 if (u
.ustr
.ustr_elements
&& u
.ustr
.ustr_elements
->has_key(index
))
8875 return (*u
.ustr
.ustr_elements
)[index
];
8877 Value
*t_val
= new Value(V_USTR
,
8878 new ustring(u
.ustr
.val_ustr
->substr(index
, 1)));
8879 add_string_element(index
, t_val
, u
.ustr
.ustr_elements
);
8883 FATAL_ERROR("Value::get_string_element()");
8888 void Value::chk_expr_type(Type::typetype_t p_tt
, const char *type_name
,
8889 Type::expected_value_t exp_val
)
8891 set_lowerid_to_ref();
8892 Type::typetype_t r_tt
= get_expr_returntype(exp_val
);
8893 bool error_flag
= r_tt
!= Type::T_ERROR
&& r_tt
!= p_tt
;
8895 error("A value or expression of type %s was expected", type_name
);
8896 if (valuetype
== V_REFD
) {
8897 Type
*t_chk
= Type::get_pooltype(Type::T_ERROR
);
8898 t_chk
->chk_this_refd_value(this, 0, exp_val
);
8900 get_value_refd_last(0, exp_val
);
8901 if (error_flag
) set_valuetype(V_ERROR
);
8902 else if (!my_governor
) set_my_governor(Type::get_pooltype(p_tt
));
8905 int Value::is_parsed_infinity()
8907 if ( (get_valuetype()==V_REAL
) && (get_val_Real()==REAL_INFINITY
) )
8909 if ( (get_valuetype()==V_EXPR
) && (get_optype()==OPTYPE_UNARYMINUS
) &&
8910 (u
.expr
.v1
->get_valuetype()==V_REAL
) &&
8911 (u
.expr
.v1
->get_val_Real()==REAL_INFINITY
) )
8916 bool Value::get_val_bool()
8919 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8921 if (v
->valuetype
!= V_BOOL
) FATAL_ERROR("Value::get_val_bool()");
8922 return v
->u
.val_bool
;
8925 int_val_t
* Value::get_val_Int()
8928 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8930 switch (v
->valuetype
) {
8933 case V_UNDEF_LOWERID
:
8934 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8935 "`%s'", (*u
.val_id
).get_dispname().c_str());
8937 FATAL_ERROR("Value::get_val_Int()");
8939 return v
->u
.val_Int
;
8942 const Identifier
* Value::get_val_id()
8947 case V_UNDEF_LOWERID
:
8950 FATAL_ERROR("Value::get_val_id()");
8955 const ttcn3float
& Value::get_val_Real()
8958 if (valuetype
== V_REFD
) v
= get_value_refd_last();
8960 if (v
->valuetype
!= V_REAL
) FATAL_ERROR("Value::get_val_Real()");
8961 return v
->u
.val_Real
;
8964 string
Value::get_val_str()
8966 Value
*v
= get_value_refd_last();
8967 switch (v
->valuetype
) {
8972 return *v
->u
.str
.val_str
;
8974 return v
->u
.char_syms
->get_string();
8976 error("Cannot use ISO-10646 string value in string context");
8979 error("Cannot use ISO-2022 string value in string context");
8984 error("Cannot use this value in charstring value context");
8989 ustring
Value::get_val_ustr()
8991 Value
*v
= get_value_refd_last();
8992 switch (v
->valuetype
) {
8994 return ustring(*v
->u
.str
.val_str
);
8996 return *v
->u
.ustr
.val_ustr
;
8998 return v
->u
.char_syms
->get_ustring();
9000 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9005 error("Cannot use this value in ISO-10646 string context");
9010 string
Value::get_val_iso2022str()
9012 Value
*v
= get_value_refd_last();
9013 switch (v
->valuetype
) {
9016 return *v
->u
.str
.val_str
;
9018 return v
->u
.char_syms
->get_iso2022string();
9020 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9025 error("Cannot use this value in ISO-2022 string context");
9030 size_t Value::get_val_strlen()
9032 Value
*v
= get_value_refd_last();
9033 switch (v
->valuetype
) {
9038 return v
->u
.str
.val_str
->size();
9040 return v
->u
.str
.val_str
->size()/2;
9042 return v
->u
.char_syms
->get_len();
9044 return v
->u
.ustr
.val_ustr
->size();
9048 error("Cannot use this value in string value context");
9053 Value::verdict_t
Value::get_val_verdict()
9059 FATAL_ERROR("Value::get_val_verdict()");
9064 size_t Value::get_nof_comps()
9066 switch (valuetype
) {
9070 return u
.oid_comps
->size();
9074 if (u
.val_vs
->is_indexed()) return u
.val_vs
->get_nof_ivs();
9075 else return u
.val_vs
->get_nof_vs();
9078 return u
.val_nvs
->get_nof_nvs();
9083 return u
.str
.val_str
->size();
9085 return u
.str
.val_str
->size()/2;
9087 return u
.ustr
.val_ustr
->size();
9089 FATAL_ERROR("Value::get_nof_comps()");
9094 bool Value::is_indexed() const
9096 switch (valuetype
) {
9100 // Applicable only for list-types. Assigning a record/SEQUENCE or
9101 // set/SET with indexed notation is not supported.
9102 return u
.val_vs
->is_indexed();
9104 FATAL_ERROR("Value::is_indexed()");
9110 const Identifier
& Value::get_alt_name()
9112 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_name()");
9113 return *u
.choice
.alt_name
;
9116 Value
*Value::get_alt_value()
9118 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::get_alt_value()");
9119 return u
.choice
.alt_value
;
9122 void Value::set_alt_name_to_lowercase()
9124 if (valuetype
!= V_CHOICE
) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9125 string new_name
= u
.choice
.alt_name
->get_name();
9126 if (isupper(new_name
[0])) {
9127 new_name
[0] = tolower(new_name
[0]);
9128 if (new_name
[new_name
.size() - 1] == '_') {
9129 // an underscore is inserted at the end of the alternative name if it's
9130 // a basic type's name (since it would conflict with the class generated
9132 // remove the underscore, it won't conflict with anything if its name
9133 // starts with a lowercase letter
9134 new_name
.replace(new_name
.size() - 1, 1, "");
9136 delete u
.choice
.alt_name
;
9137 u
.choice
.alt_name
= new Identifier(Identifier::ID_NAME
, new_name
);
9141 bool Value::has_oid_error()
9144 if (valuetype
== V_REFD
) v
= get_value_refd_last();
9146 switch (valuetype
) {
9149 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++)
9150 if ((*v
->u
.oid_comps
)[i
]->has_error()) return true;
9157 bool Value::get_oid_comps(vector
<string
>& comps
)
9159 bool ret_val
= true;
9161 switch (valuetype
) {
9163 v
= get_value_refd_last();
9167 for (size_t i
= 0; i
< v
->u
.oid_comps
->size(); i
++) {
9168 (*v
->u
.oid_comps
)[i
]->get_comps(comps
);
9169 if ((*v
->u
.oid_comps
)[i
]->is_variable()) {
9170 // not all components can be calculated in compile-time
9176 FATAL_ERROR("Value::get_oid_comps()");
9181 void Value::add_se_comp(NamedValue
* nv
) {
9182 switch (valuetype
) {
9186 u
.val_nvs
= new NamedValues();
9187 u
.val_nvs
->add_nv(nv
);
9190 FATAL_ERROR("Value::add_se_comp()");
9194 NamedValue
* Value::get_se_comp_byIndex(size_t n
)
9199 return u
.val_nvs
->get_nv_byIndex(n
);
9201 FATAL_ERROR("Value::get_se_comp_byIndex()");
9206 Value
*Value::get_comp_byIndex(size_t n
)
9208 switch (valuetype
) {
9212 if (!is_indexed()) return u
.val_vs
->get_v_byIndex(n
);
9213 return u
.val_vs
->get_iv_byIndex(n
)->get_value();
9215 FATAL_ERROR("Value::get_comp_byIndex()");
9220 Value
*Value::get_index_byIndex(size_t n
)
9222 switch (valuetype
) {
9226 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9227 return u
.val_vs
->get_iv_byIndex(n
)->get_index();
9229 FATAL_ERROR("Value::get_index_byIndex()");
9234 bool Value::has_comp_withName(const Identifier
& p_name
)
9239 return u
.val_nvs
->has_nv_withName(p_name
);
9241 return u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname();
9243 FATAL_ERROR("Value::get_has_comp_withName()");
9248 bool Value::field_is_chosen(const Identifier
& p_name
)
9250 Value
*v
=get_value_refd_last();
9251 if(v
->valuetype
!=V_CHOICE
) FATAL_ERROR("Value::field_is_chosen()");
9252 return *v
->u
.choice
.alt_name
==p_name
;
9255 bool Value::field_is_present(const Identifier
& p_name
)
9257 Value
*v
=get_value_refd_last();
9258 if(!(v
->valuetype
==V_SEQ
|| v
->valuetype
==V_SET
))
9259 FATAL_ERROR("Value::field_is_present()");
9260 return v
->u
.val_nvs
->has_nv_withName(p_name
)
9261 && v
->u
.val_nvs
->get_nv_byName(p_name
)->get_value()
9262 ->get_value_refd_last()->valuetype
!= V_OMIT
;
9265 NamedValue
* Value::get_se_comp_byName(const Identifier
& p_name
)
9270 return u
.val_nvs
->get_nv_byName(p_name
);
9272 FATAL_ERROR("Value::get_se_comp_byName()");
9277 Value
* Value::get_comp_value_byName(const Identifier
& p_name
)
9282 return u
.val_nvs
->get_nv_byName(p_name
)->get_value();
9284 if(u
.choice
.alt_name
->get_dispname() == p_name
.get_dispname())
9285 return u
.choice
.alt_value
;
9289 FATAL_ERROR("Value::get_se_comp_byName()");
9294 void Value::chk_dupl_id()
9299 u
.val_nvs
->chk_dupl_id();
9302 FATAL_ERROR("Value::chk_dupl_id()");
9306 size_t Value::get_nof_ids() const
9310 return u
.ids
->size();
9313 FATAL_ERROR("Value::get_nof_ids()");
9318 Identifier
* Value::get_id_byIndex(size_t p_i
)
9322 return u
.ids
->get_nth_elem(p_i
);
9325 FATAL_ERROR("Value::get_id_byIndex()");
9330 bool Value::has_id(const Identifier
& p_id
)
9334 return u
.ids
->has_key(p_id
.get_name());
9337 FATAL_ERROR("Value::has_id()");
9342 Reference
*Value::get_reference() const
9344 if (valuetype
!= V_REFD
) FATAL_ERROR("Value::get_reference()");
9348 Reference
*Value::get_refered() const
9350 if (valuetype
!= V_REFER
) FATAL_ERROR("Value::get_referred()");
9354 Common::Assignment
*Value::get_refd_fat() const
9362 FATAL_ERROR("Value::get_refd_fat()");
9366 Ttcn::Reference
* Value::steal_ttcn_ref()
9368 Ttcn::Reference
*ret_val
=
9369 dynamic_cast<Ttcn::Reference
*>(steal_ttcn_ref_base());
9370 if(!ret_val
) FATAL_ERROR("Value::steal_ttcn_ref()");
9374 Ttcn::Ref_base
* Value::steal_ttcn_ref_base()
9376 Ttcn::Ref_base
*t_ref
;
9377 if(valuetype
==V_REFD
) {
9378 t_ref
=dynamic_cast<Ttcn::Ref_base
*>(u
.ref
.ref
);
9379 if(!t_ref
) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9382 else if(valuetype
==V_UNDEF_LOWERID
) {
9383 t_ref
=new Ttcn::Reference(u
.val_id
);
9384 t_ref
->set_location(*this);
9385 t_ref
->set_fullname(get_fullname());
9386 t_ref
->set_my_scope(get_my_scope());
9390 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9393 set_valuetype(V_ERROR
);
9397 void Value::steal_invoke_data(Value
*& p_v
, Ttcn::ParsedActualParameters
*& p_ti
,
9398 Ttcn::ActualParList
*& p_ap
)
9400 if(valuetype
!= V_INVOKE
) FATAL_ERROR("Value::steal_invoke_data()");
9403 p_ti
= u
.invoke
.t_list
;
9404 u
.invoke
.t_list
= 0;
9405 p_ap
= u
.invoke
.ap_list
;
9406 u
.invoke
.ap_list
= 0;
9407 set_valuetype(V_ERROR
);
9410 Common::Assignment
* Value::get_refd_assignment()
9419 FATAL_ERROR("Value::get_refd_assignment()");
9429 ReferenceChain
refch(this, "While checking OBJECT IDENTIFIER"
9434 ReferenceChain
refch(this, "While checking RELATIVE-OID components");
9443 void Value::chk_OID(ReferenceChain
& refch
)
9445 if (checked
) return;
9446 if (valuetype
!= V_OID
|| u
.oid_comps
->size() < 1)
9447 FATAL_ERROR("Value::chk_OID()");
9448 if (!refch
.add(get_fullname())) {
9452 OID_comp::oidstate_t state
= OID_comp::START
;
9453 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9455 (*u
.oid_comps
)[i
]->chk_OID(refch
, this, i
, state
);
9458 if (state
!= OID_comp::LATER
&& state
!= OID_comp::ITU_REC
)
9459 error("An OBJECT IDENTIFIER value must have at least "
9460 "two components"); // X.680 (07/2002) 31.10
9463 void Value::chk_ROID(ReferenceChain
& refch
)
9465 if (checked
) return;
9466 if (valuetype
!= V_ROID
|| u
.oid_comps
->size() < 1)
9467 FATAL_ERROR("Value::chk_ROID()");
9468 if (!refch
.add(get_fullname())) {
9472 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
9474 (*u
.oid_comps
)[i
]->chk_ROID(refch
, i
);
9479 void Value::chk_recursions(ReferenceChain
& refch
)
9481 if (recurs_checked
) return;
9482 Value
*v
= get_value_refd_last();
9483 if (refch
.add(v
->get_fullname())) {
9484 switch (v
->valuetype
) {
9486 v
->u
.choice
.alt_value
->chk_recursions(refch
);
9491 if (!v
->is_indexed()) {
9492 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_vs(); i
++) {
9494 v
->u
.val_vs
->get_v_byIndex(i
)->chk_recursions(refch
);
9498 for (size_t i
= 0; i
< v
->u
.val_vs
->get_nof_ivs(); i
++) {
9500 v
->u
.val_vs
->get_iv_byIndex(i
)->get_value()
9501 ->chk_recursions(refch
);
9508 for (size_t i
= 0; i
< v
->u
.val_nvs
->get_nof_nvs(); i
++) {
9510 v
->u
.val_nvs
->get_nv_byIndex(i
)->get_value()->chk_recursions(refch
);
9515 chk_recursions_expr(refch
);
9520 if (v
->err_descr
) { // FIXME: make this work
9521 v
->err_descr
->chk_recursions(refch
);
9524 recurs_checked
= true;
9527 void Value::chk_recursions_expr(ReferenceChain
& refch
)
9529 // first classify the unchecked ischosen() operation
9530 if (u
.expr
.v_optype
==OPTYPE_ISCHOSEN
) chk_expr_ref_ischosen();
9531 switch (u
.expr
.v_optype
) {
9532 case OPTYPE_UNARYPLUS
: // v1
9533 case OPTYPE_UNARYMINUS
:
9536 case OPTYPE_BIT2HEX
:
9537 case OPTYPE_BIT2INT
:
9538 case OPTYPE_BIT2OCT
:
9539 case OPTYPE_BIT2STR
:
9540 case OPTYPE_CHAR2INT
:
9541 case OPTYPE_CHAR2OCT
:
9542 case OPTYPE_FLOAT2INT
:
9543 case OPTYPE_FLOAT2STR
:
9544 case OPTYPE_HEX2BIT
:
9545 case OPTYPE_HEX2INT
:
9546 case OPTYPE_HEX2OCT
:
9547 case OPTYPE_HEX2STR
:
9548 case OPTYPE_INT2CHAR
:
9549 case OPTYPE_INT2FLOAT
:
9550 case OPTYPE_INT2STR
:
9551 case OPTYPE_INT2UNICHAR
:
9552 case OPTYPE_OCT2BIT
:
9553 case OPTYPE_OCT2CHAR
:
9554 case OPTYPE_OCT2HEX
:
9555 case OPTYPE_OCT2INT
:
9556 case OPTYPE_OCT2STR
:
9557 case OPTYPE_STR2BIT
:
9558 case OPTYPE_STR2FLOAT
:
9559 case OPTYPE_STR2HEX
:
9560 case OPTYPE_STR2INT
:
9561 case OPTYPE_STR2OCT
:
9562 case OPTYPE_UNICHAR2INT
:
9563 case OPTYPE_ENUM2INT
:
9564 case OPTYPE_UNICHAR2CHAR
:
9565 case OPTYPE_RNDWITHVAL
:
9566 case OPTYPE_ISCHOSEN_V
:
9567 case OPTYPE_GET_STRINGENCODING
:
9568 case OPTYPE_REMOVE_BOM
:
9569 case OPTYPE_DECODE_BASE64
:
9571 u
.expr
.v1
->chk_recursions(refch
);
9574 case OPTYPE_ISCHOSEN_T
:
9576 u
.expr
.t1
->chk_recursions(refch
);
9579 case OPTYPE_ADD
: // v1 v2
9580 case OPTYPE_SUBTRACT
:
9581 case OPTYPE_MULTIPLY
:
9602 case OPTYPE_INT2BIT
:
9603 case OPTYPE_INT2HEX
:
9604 case OPTYPE_INT2OCT
:
9606 u
.expr
.v1
->chk_recursions(refch
);
9609 u
.expr
.v2
->chk_recursions(refch
);
9612 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9613 case OPTYPE_OCT2UNICHAR
:
9614 case OPTYPE_ENCODE_BASE64
:
9616 u
.expr
.v1
->chk_recursions(refch
);
9620 u
.expr
.v2
->chk_recursions(refch
);
9625 chk_recursions_expr_decode(u
.expr
.r1
, refch
);
9626 chk_recursions_expr_decode(u
.expr
.r2
, refch
);
9630 u
.expr
.ti1
->chk_recursions(refch
);
9633 u
.expr
.v2
->chk_recursions(refch
);
9636 u
.expr
.v3
->chk_recursions(refch
);
9641 u
.expr
.ti1
->chk_recursions(refch
);
9644 u
.expr
.t2
->chk_recursions(refch
);
9647 u
.expr
.v3
->chk_recursions(refch
);
9650 case OPTYPE_DECOMP
: // v1 v2 v3
9652 u
.expr
.v1
->chk_recursions(refch
);
9655 u
.expr
.v2
->chk_recursions(refch
);
9658 u
.expr
.v3
->chk_recursions(refch
);
9661 case OPTYPE_REPLACE
:
9663 u
.expr
.ti1
->chk_recursions(refch
);
9666 u
.expr
.v2
->chk_recursions(refch
);
9669 u
.expr
.v3
->chk_recursions(refch
);
9672 u
.expr
.ti4
->chk_recursions(refch
);
9675 case OPTYPE_LENGTHOF
: // ti1
9676 case OPTYPE_SIZEOF
: // ti1
9677 case OPTYPE_VALUEOF
: // ti1
9679 case OPTYPE_ISPRESENT
:
9680 case OPTYPE_TTCN2STRING
:
9682 u
.expr
.ti1
->chk_recursions(refch
);
9685 case OPTYPE_MATCH
: // v1 t2
9687 u
.expr
.v1
->chk_recursions(refch
);
9690 u
.expr
.t2
->chk_recursions(refch
);
9693 case OPTYPE_LOG2STR
:
9694 u
.expr
.logargs
->chk_recursions(refch
);
9701 void Value::chk_recursions_expr_decode(Ttcn::Ref_base
* ref
,
9702 ReferenceChain
& refch
) {
9703 Error_Context
cntxt(this, "In the operand of operation `%s'", get_opname());
9704 Assignment
*ass
= ref
->get_refd_assignment();
9706 set_valuetype(V_ERROR
);
9709 switch (ass
->get_asstype()) {
9710 case Assignment::A_CONST
:
9711 case Assignment::A_EXT_CONST
:
9712 case Assignment::A_MODULEPAR
:
9713 case Assignment::A_VAR
:
9714 case Assignment::A_PAR_VAL_IN
:
9715 case Assignment::A_PAR_VAL_OUT
:
9716 case Assignment::A_PAR_VAL_INOUT
: {
9717 Value
* v
= new Value(V_REFD
, ref
);
9718 v
->set_location(*ref
);
9719 v
->set_my_scope(get_my_scope());
9720 v
->set_fullname(get_fullname()+".<operand>");
9722 v
->chk_recursions(refch
);
9726 case Assignment::A_MODULEPAR_TEMP
:
9727 case Assignment::A_TEMPLATE
:
9728 case Assignment::A_VAR_TEMPLATE
:
9729 case Assignment::A_PAR_TEMPL_IN
:
9730 case Assignment::A_PAR_TEMPL_OUT
:
9731 case Assignment::A_PAR_TEMPL_INOUT
: {
9732 Template
* t
= new Template(ref
->clone());
9733 t
->set_location(*ref
);
9734 t
->set_my_scope(get_my_scope());
9735 t
->set_fullname(get_fullname()+".<operand>");
9737 t
->chk_recursions(refch
);
9742 // remain silent, the error has been already reported
9743 set_valuetype(V_ERROR
);
9748 bool Value::chk_expr_self_ref_templ(Ttcn::Template
*t
, Common::Assignment
*lhs
)
9750 bool self_ref
= false;
9751 switch (t
->get_templatetype()) {
9752 case Ttcn::Template::SPECIFIC_VALUE
: {
9753 Value
*v
= t
->get_specific_value();
9754 self_ref
|= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
9755 ->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9756 INCOMPLETE_NOT_ALLOWED
, OMIT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
, NOT_STR_ELEM
);
9758 case Ttcn::Template::TEMPLATE_REFD
: {
9759 Ttcn::Ref_base
*refb
= t
->get_reference();
9760 Common::Assignment
*ass
= refb
->get_refd_assignment();
9761 self_ref
|= (ass
== lhs
);
9763 case Ttcn::Template::ALL_FROM
:
9764 case Ttcn::Template::VALUE_LIST_ALL_FROM
:
9765 self_ref
|= chk_expr_self_ref_templ(t
->get_all_from(), lhs
);
9767 case Ttcn::Template::TEMPLATE_LIST
:
9768 case Ttcn::Template::SUPERSET_MATCH
:
9769 case Ttcn::Template::SUBSET_MATCH
:
9770 case Ttcn::Template::PERMUTATION_MATCH
:
9771 case Ttcn::Template::COMPLEMENTED_LIST
:
9772 case Ttcn::Template::VALUE_LIST
: {
9773 size_t num
= t
->get_nof_comps();
9774 for (size_t i
= 0; i
< num
; ++i
) {
9775 self_ref
|= chk_expr_self_ref_templ(t
->get_temp_byIndex(i
), lhs
);
9778 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9779 // case Ttcn::Template::TEMPLATE_LIST: {
9780 // size_t num = t->get_nof_listitems();
9781 // for (size_t i=0; i < num; ++i) {
9782 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9785 case Ttcn::Template::NAMED_TEMPLATE_LIST
: {
9786 size_t nnt
= t
->get_nof_comps();
9787 for (size_t i
=0; i
< nnt
; ++i
) {
9788 Ttcn::NamedTemplate
*nt
= t
->get_namedtemp_byIndex(i
);
9789 self_ref
|= chk_expr_self_ref_templ(nt
->get_template(), lhs
);
9792 case Ttcn::Template::INDEXED_TEMPLATE_LIST
: {
9793 size_t nnt
= t
->get_nof_comps();
9794 for (size_t i
=0; i
< nnt
; ++i
) {
9795 Ttcn::IndexedTemplate
*it
= t
->get_indexedtemp_byIndex(i
);
9796 self_ref
|= chk_expr_self_ref_templ(it
->get_template(), lhs
);
9799 case Ttcn::Template::VALUE_RANGE
: {
9800 Ttcn::ValueRange
*vr
= t
->get_value_range();
9801 Common::Value
*v
= vr
->get_min_v();
9802 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9803 v
= vr
->get_max_v();
9804 if (v
) self_ref
|= chk_expr_self_ref_val(v
, lhs
);
9806 case Ttcn::Template::CSTR_PATTERN
:
9807 case Ttcn::Template::USTR_PATTERN
: {
9808 Ttcn::PatternString
*ps
= t
->get_cstr_pattern();
9809 self_ref
|= ps
->chk_self_ref(lhs
);
9811 case Ttcn::Template::BSTR_PATTERN
:
9812 case Ttcn::Template::HSTR_PATTERN
:
9813 case Ttcn::Template::OSTR_PATTERN
: {
9814 // FIXME: cannot access u.pattern
9816 case Ttcn::Template::ANY_VALUE
:
9817 case Ttcn::Template::ANY_OR_OMIT
:
9818 case Ttcn::Template::OMIT_VALUE
:
9819 case Ttcn::Template::TEMPLATE_NOTUSED
:
9820 break; // self-ref can't happen
9821 case Ttcn::Template::TEMPLATE_INVOKE
:
9822 break; // assume self-ref can't happen
9823 case Ttcn::Template::TEMPLATE_ERROR
:
9824 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9827 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9828 // break; // and hope for the best
9833 bool Value::chk_expr_self_ref_val(Common::Value
*v
, Common::Assignment
*lhs
)
9835 Common::Type
*gov
= v
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
);
9836 namedbool is_str_elem
= NOT_STR_ELEM
;
9837 if (v
->valuetype
== V_REFD
) {
9838 Reference
*ref
= v
->get_reference();
9839 Ttcn::FieldOrArrayRefs
*subrefs
= ref
->get_subrefs();
9840 if (subrefs
&& subrefs
->refers_to_string_element()) {
9841 is_str_elem
= IS_STR_ELEM
;
9844 return gov
->chk_this_value(v
, lhs
, Type::EXPECTED_DYNAMIC_VALUE
,
9845 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, NO_SUB_CHK
, NOT_IMPLICIT_OMIT
,
9849 bool Value::chk_expr_self_ref(Common::Assignment
*lhs
)
9851 if (valuetype
!= V_EXPR
) FATAL_ERROR("Value::chk_expr_self_ref");
9852 if (!lhs
) FATAL_ERROR("no lhs!");
9853 bool self_ref
= false;
9854 switch (u
.expr
.v_optype
) {
9855 case OPTYPE_RND
: // -
9856 case OPTYPE_TESTCASENAME
: // -
9857 case OPTYPE_COMP_NULL
: // - (from V_TTCN3_NULL)
9858 case OPTYPE_COMP_MTC
: // -
9859 case OPTYPE_COMP_SYSTEM
: // -
9860 case OPTYPE_COMP_SELF
: // -
9861 case OPTYPE_COMP_RUNNING_ANY
: // -
9862 case OPTYPE_COMP_RUNNING_ALL
: // -
9863 case OPTYPE_COMP_ALIVE_ANY
: // -
9864 case OPTYPE_COMP_ALIVE_ALL
: // -
9865 case OPTYPE_TMR_RUNNING_ANY
: // -
9866 case OPTYPE_GETVERDICT
: // -
9867 case OPTYPE_PROF_RUNNING
: // -
9868 break; // nothing to do
9870 case OPTYPE_MATCH
: // v1 t2
9871 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9873 case OPTYPE_UNARYPLUS
: // v1
9874 case OPTYPE_UNARYMINUS
: // v1
9875 case OPTYPE_NOT
: // v1
9876 case OPTYPE_NOT4B
: // v1
9877 case OPTYPE_BIT2HEX
: // v1
9878 case OPTYPE_BIT2INT
: // v1
9879 case OPTYPE_BIT2OCT
: // v1
9880 case OPTYPE_BIT2STR
: // v1
9881 case OPTYPE_CHAR2INT
: // v1
9882 case OPTYPE_CHAR2OCT
: // v1
9883 case OPTYPE_FLOAT2INT
: // v1
9884 case OPTYPE_FLOAT2STR
: // v1
9885 case OPTYPE_HEX2BIT
: // v1
9886 case OPTYPE_HEX2INT
: // v1
9887 case OPTYPE_HEX2OCT
: // v1
9888 case OPTYPE_HEX2STR
: // v1
9889 case OPTYPE_INT2CHAR
: // v1
9890 case OPTYPE_INT2FLOAT
: // v1
9891 case OPTYPE_INT2STR
: // v1
9892 case OPTYPE_INT2UNICHAR
: // v1
9893 case OPTYPE_OCT2BIT
: // v1
9894 case OPTYPE_OCT2CHAR
: // v1
9895 case OPTYPE_OCT2HEX
: // v1
9896 case OPTYPE_OCT2INT
: // v1
9897 case OPTYPE_OCT2STR
: // v1
9898 case OPTYPE_STR2BIT
: // v1
9899 case OPTYPE_STR2FLOAT
: // v1
9900 case OPTYPE_STR2HEX
: // v1
9901 case OPTYPE_STR2INT
: // v1
9902 case OPTYPE_STR2OCT
: // v1
9903 case OPTYPE_UNICHAR2INT
: // v1
9904 case OPTYPE_UNICHAR2CHAR
: // v1
9905 case OPTYPE_ENUM2INT
: // v1
9906 case OPTYPE_RNDWITHVAL
: // v1
9907 case OPTYPE_COMP_RUNNING
: // v1
9908 case OPTYPE_COMP_ALIVE
: // v1
9909 case OPTYPE_ISCHOSEN_V
: // v1 i2; ignore the identifier
9910 case OPTYPE_GET_STRINGENCODING
:
9911 case OPTYPE_DECODE_BASE64
:
9912 case OPTYPE_REMOVE_BOM
:
9913 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9915 case OPTYPE_ADD
: // v1 v2
9916 case OPTYPE_SUBTRACT
: // v1 v2
9917 case OPTYPE_MULTIPLY
: // v1 v2
9918 case OPTYPE_DIVIDE
: // v1 v2
9919 case OPTYPE_MOD
: // v1 v2
9920 case OPTYPE_REM
: // v1 v2
9921 case OPTYPE_CONCAT
: // v1 v2
9922 case OPTYPE_EQ
: // v1 v2
9923 case OPTYPE_LT
: // v1 v2
9924 case OPTYPE_GT
: // v1 v2
9925 case OPTYPE_NE
: // v1 v2
9926 case OPTYPE_GE
: // v1 v2
9927 case OPTYPE_LE
: // v1 v2
9928 case OPTYPE_AND
: // v1 v2
9929 case OPTYPE_OR
: // v1 v2
9930 case OPTYPE_XOR
: // v1 v2
9931 case OPTYPE_AND4B
: // v1 v2
9932 case OPTYPE_OR4B
: // v1 v2
9933 case OPTYPE_XOR4B
: // v1 v2
9934 case OPTYPE_SHL
: // v1 v2
9935 case OPTYPE_SHR
: // v1 v2
9936 case OPTYPE_ROTL
: // v1 v2
9937 case OPTYPE_ROTR
: // v1 v2
9938 case OPTYPE_INT2BIT
: // v1 v2
9939 case OPTYPE_INT2HEX
: // v1 v2
9940 case OPTYPE_INT2OCT
: // v1 v2
9941 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9942 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9944 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
9945 case OPTYPE_OCT2UNICHAR
:
9946 case OPTYPE_ENCODE_BASE64
:
9947 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9948 if (u
.expr
.v2
) self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9950 case OPTYPE_DECOMP
: // v1 v2 v3
9951 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
9952 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
9953 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
9956 case OPTYPE_REPLACE
: // ti1 v2 v3 ti4
9957 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti4
->get_Template(), lhs
);
9959 case OPTYPE_SUBSTR
: // ti1 v2 v3
9960 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9961 self_ref
|= chk_expr_self_ref_val (u
.expr
.v2
, lhs
);
9962 self_ref
|= chk_expr_self_ref_val (u
.expr
.v3
, lhs
);
9965 case OPTYPE_REGEXP
: // ti1 t2 v3
9966 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9967 self_ref
|= chk_expr_self_ref_templ(u
.expr
.t2
->get_Template(), lhs
);
9969 case OPTYPE_LENGTHOF
: // ti1
9970 case OPTYPE_SIZEOF
: // ti1
9971 case OPTYPE_VALUEOF
: // ti1
9972 case OPTYPE_ENCODE
: // ti1
9973 case OPTYPE_TTCN2STRING
:
9974 self_ref
|= chk_expr_self_ref_templ(u
.expr
.ti1
->get_Template(), lhs
);
9977 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
9978 // component.create -- assume no self-ref
9979 case OPTYPE_ACTIVATE
: // r1
9980 // defaultref := activate(altstep) -- assume no self-ref
9981 case OPTYPE_TMR_RUNNING
: // r1
9982 // boolvar := a_timer.running -- assume no self-ref
9986 case OPTYPE_LOG2STR
: {// logargs
9987 for (size_t i
= 0, e
= u
.expr
.logargs
->get_nof_logargs(); i
< e
; ++i
) {
9988 const Ttcn::LogArgument
*la
= u
.expr
.logargs
->get_logarg_byIndex(i
);
9989 switch (la
->get_type()) {
9990 case Ttcn::LogArgument::L_UNDEF
:
9991 case Ttcn::LogArgument::L_ERROR
:
9992 FATAL_ERROR("log2str argument type");
9993 break; // not reached
9995 case Ttcn::LogArgument::L_MACRO
:
9996 case Ttcn::LogArgument::L_STR
:
9997 break; // self reference not possible
9999 case Ttcn::LogArgument::L_VAL
:
10000 case Ttcn::LogArgument::L_MATCH
:
10001 self_ref
|= chk_expr_self_ref_val(la
->get_val(), lhs
);
10004 case Ttcn::LogArgument::L_REF
: {
10005 Ttcn::Ref_base
*ref
= la
->get_ref();
10006 Common::Assignment
*ass
= ref
->get_refd_assignment();
10007 self_ref
|= (ass
== lhs
);
10010 case Ttcn::LogArgument::L_TI
: {
10011 Ttcn::TemplateInstance
*ti
= la
->get_ti();
10012 Ttcn::Template
*t
= ti
->get_Template();
10013 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10016 // no default please
10017 } // switch la->logargtype
10021 case OPTYPE_DECODE
: { // r1 r2
10022 Common::Assignment
*ass
= u
.expr
.r2
->get_refd_assignment();
10023 self_ref
|= (ass
== lhs
);
10025 case OPTYPE_EXECUTE
: // r1 [v2]
10027 self_ref
|= chk_expr_self_ref_val(u
.expr
.v2
, lhs
);
10031 case OPTYPE_UNDEF_RUNNING
: // r1
10032 case OPTYPE_TMR_READ
: { // r1
10033 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
10034 self_ref
|= (ass
== lhs
);
10037 case OPTYPE_ISCHOSEN_T
: // t1 i2
10038 case OPTYPE_ISBOUND
: // ti1
10039 case OPTYPE_ISVALUE
: // ti1
10040 case OPTYPE_ISPRESENT
: { // ti1
10042 if (u
.expr
.v_optype
== OPTYPE_ISCHOSEN_T
) t
= u
.expr
.t1
;
10043 else t
= u
.expr
.ti1
->get_Template();
10044 self_ref
|= chk_expr_self_ref_templ(t
, lhs
);
10047 case OPTYPE_EXECUTE_REFD
: // v1 t_list2 [v3]
10049 self_ref
|= chk_expr_self_ref_val(u
.expr
.v3
, lhs
);
10052 case OPTYPE_ACTIVATE_REFD
: // v1 t_list2
10053 self_ref
|= chk_expr_self_ref_val(u
.expr
.v1
, lhs
);
10057 case NUMBER_OF_OPTYPES
: // can never happen
10058 case OPTYPE_ISCHOSEN
: // r1 i2, should have been classified as _T or _V
10059 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u
.expr
.v_optype
);
10061 } // switch u.expr.v_optype
10066 string
Value::create_stringRepr()
10068 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10069 switch (valuetype
) {
10071 return string("<erroneous>");
10073 return string("NULL");
10075 if (!parse_only
&& is_asn1()) {
10076 if (u
.val_bool
) return string("TRUE");
10077 else return string("FALSE");
10080 if (u
.val_bool
) return string("true");
10081 else return string("false");
10084 return u
.val_Int
->t_str();
10086 return Real2string(u
.val_Real
);
10089 case V_UNDEF_LOWERID
:
10090 return u
.val_id
->get_name();
10091 case V_NAMEDBITS
: {
10092 string
ret_val("{ ");
10093 for (size_t i
= 0; i
< u
.ids
->size(); i
++) {
10094 if (i
>0) ret_val
+= ' ';
10095 ret_val
+= u
.ids
->get_nth_elem(i
)->get_dispname();
10100 string
ret_val('\'');
10101 ret_val
+= *u
.str
.val_str
;
10105 string
ret_val('\'');
10106 ret_val
+= *u
.str
.val_str
;
10110 string
ret_val('\'');
10111 ret_val
+= *u
.str
.val_str
;
10116 return u
.str
.val_str
->get_stringRepr();
10118 return u
.ustr
.val_ustr
->get_stringRepr();
10120 /** \todo stringrepr of V_CHARSYMS */
10121 return string("<sorry, string representation of charsyms "
10122 "not implemented>");
10126 if (parse_only
|| !is_asn1()) ret_val
+= "objid ";
10128 for (size_t i
= 0; i
< u
.oid_comps
->size(); i
++) {
10129 if (i
>0) ret_val
+= ' ';
10130 (*u
.oid_comps
)[i
]->append_stringRepr(ret_val
);
10135 if (!parse_only
&& is_asn1()) {
10136 string
ret_val(u
.choice
.alt_name
->get_dispname());
10138 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10142 string
ret_val("{ ");
10143 ret_val
+= u
.choice
.alt_name
->get_dispname();
10145 ret_val
+= u
.choice
.alt_value
->get_stringRepr();
10152 string
ret_val("{ ");
10153 if (!is_indexed()) {
10154 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
10155 if (i
> 0) ret_val
+= ", ";
10156 ret_val
+= u
.val_vs
->get_v_byIndex(i
)->get_stringRepr();
10159 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
10160 if (i
> 0) ret_val
+= ", ";
10161 ret_val
+= u
.val_vs
->get_iv_byIndex(i
)->get_value()->get_stringRepr();
10168 string
ret_val("{ ");
10169 bool asn1_flag
= !parse_only
&& is_asn1();
10170 for (size_t i
= 0; i
< u
.val_nvs
->get_nof_nvs(); i
++) {
10171 if (i
> 0) ret_val
+= ", ";
10172 NamedValue
*nv
= u
.val_nvs
->get_nv_byIndex(i
);
10173 ret_val
+= nv
->get_name().get_dispname();
10174 if (asn1_flag
) ret_val
+= ' ';
10175 else ret_val
+= " := ";
10176 ret_val
+= nv
->get_value()->get_stringRepr();
10181 // do not evaluate the reference if it is not done so far
10182 // (e.g. in parse-only mode)
10183 Value
*t_val
= u
.ref
.refd_last
? u
.ref
.refd_last
: this;
10184 if (t_val
->valuetype
== V_REFD
) return t_val
->u
.ref
.ref
->get_dispname();
10185 else return t_val
->get_stringRepr(); }
10187 return string("omit");
10189 switch (u
.verdict
) {
10191 return string("none");
10193 return string("pass");
10194 case Verdict_INCONC
:
10195 return string("inconc");
10197 return string("fail");
10198 case Verdict_ERROR
:
10199 return string("error");
10201 return string("<unknown verdict value>");
10203 case V_DEFAULT_NULL
:
10205 return string("null");
10207 switch (u
.expr
.v_optype
) {
10209 return string("rnd()");
10210 case OPTYPE_TESTCASENAME
:
10211 return string("testcasename()");
10212 case OPTYPE_UNARYPLUS
:
10213 return create_stringRepr_unary("+");
10214 case OPTYPE_UNARYMINUS
:
10215 return create_stringRepr_unary("-");
10217 return create_stringRepr_unary("not");
10219 return create_stringRepr_unary("not4b");
10220 case OPTYPE_BIT2HEX
:
10221 return create_stringRepr_predef1("bit2hex");
10222 case OPTYPE_BIT2INT
:
10223 return create_stringRepr_predef1("bit2int");
10224 case OPTYPE_BIT2OCT
:
10225 return create_stringRepr_predef1("bit2oct");
10226 case OPTYPE_BIT2STR
:
10227 return create_stringRepr_predef1("bit2str");
10228 case OPTYPE_CHAR2INT
:
10229 return create_stringRepr_predef1("char2int");
10230 case OPTYPE_CHAR2OCT
:
10231 return create_stringRepr_predef1("char2oct");
10232 case OPTYPE_FLOAT2INT
:
10233 return create_stringRepr_predef1("float2int");
10234 case OPTYPE_FLOAT2STR
:
10235 return create_stringRepr_predef1("float2str");
10236 case OPTYPE_HEX2BIT
:
10237 return create_stringRepr_predef1("hex2bit");
10238 case OPTYPE_HEX2INT
:
10239 return create_stringRepr_predef1("hex2int");
10240 case OPTYPE_HEX2OCT
:
10241 return create_stringRepr_predef1("hex2oct");
10242 case OPTYPE_HEX2STR
:
10243 return create_stringRepr_predef1("hex2str");
10244 case OPTYPE_INT2CHAR
:
10245 return create_stringRepr_predef1("int2char");
10246 case OPTYPE_INT2FLOAT
:
10247 return create_stringRepr_predef1("int2float");
10248 case OPTYPE_INT2STR
:
10249 return create_stringRepr_predef1("int2str");
10250 case OPTYPE_INT2UNICHAR
:
10251 return create_stringRepr_predef1("int2unichar");
10252 case OPTYPE_OCT2BIT
:
10253 return create_stringRepr_predef1("oct2bit");
10254 case OPTYPE_OCT2CHAR
:
10255 return create_stringRepr_predef1("oct2char");
10256 case OPTYPE_OCT2HEX
:
10257 return create_stringRepr_predef1("oct2hex");
10258 case OPTYPE_OCT2INT
:
10259 return create_stringRepr_predef1("oct2int");
10260 case OPTYPE_OCT2STR
:
10261 return create_stringRepr_predef1("oct2str");
10262 case OPTYPE_GET_STRINGENCODING
:
10263 return create_stringRepr_predef1("get_stringencoding");
10264 case OPTYPE_REMOVE_BOM
:
10265 return create_stringRepr_predef1("remove_bom");
10266 case OPTYPE_ENCODE_BASE64
: {
10267 if (u
.expr
.v2
) return create_stringRepr_predef2("encode_base64");
10268 else return create_stringRepr_predef1("encode_base64");
10270 case OPTYPE_DECODE_BASE64
:
10271 return create_stringRepr_predef1("decode_base64");
10272 case OPTYPE_OCT2UNICHAR
:{
10273 if (u
.expr
.v2
) return create_stringRepr_predef2("oct2unichar");
10274 else return create_stringRepr_predef1("oct2unichar");
10276 case OPTYPE_UNICHAR2OCT
: {
10277 if (u
.expr
.v2
) return create_stringRepr_predef2("unichar2oct");
10278 else return create_stringRepr_predef1("unichar2oct");
10280 case OPTYPE_STR2BIT
:
10281 return create_stringRepr_predef1("str2bit");
10282 case OPTYPE_STR2FLOAT
:
10283 return create_stringRepr_predef1("str2float");
10284 case OPTYPE_STR2HEX
:
10285 return create_stringRepr_predef1("str2hex");
10286 case OPTYPE_STR2INT
:
10287 return create_stringRepr_predef1("str2int");
10288 case OPTYPE_STR2OCT
:
10289 return create_stringRepr_predef1("str2oct");
10290 case OPTYPE_UNICHAR2INT
:
10291 return create_stringRepr_predef1("unichar2int");
10292 case OPTYPE_UNICHAR2CHAR
:
10293 return create_stringRepr_predef1("unichar2char");
10294 case OPTYPE_ENUM2INT
:
10295 return create_stringRepr_predef1("enum2int");
10296 case OPTYPE_ENCODE
:
10297 return create_stringRepr_predef1("encvalue");
10298 case OPTYPE_DECODE
:
10299 return create_stringRepr_predef2("decvalue");
10300 case OPTYPE_RNDWITHVAL
:
10301 return create_stringRepr_predef1("rnd");
10303 return create_stringRepr_infix("+");
10304 case OPTYPE_SUBTRACT
:
10305 return create_stringRepr_infix("-");
10306 case OPTYPE_MULTIPLY
:
10307 return create_stringRepr_infix("*");
10308 case OPTYPE_DIVIDE
:
10309 return create_stringRepr_infix("/");
10311 return create_stringRepr_infix("mod");
10313 return create_stringRepr_infix("rem");
10314 case OPTYPE_CONCAT
:
10315 return create_stringRepr_infix("&");
10317 return create_stringRepr_infix("==");
10319 return create_stringRepr_infix("<");
10321 return create_stringRepr_infix(">");
10323 return create_stringRepr_infix("!=");
10325 return create_stringRepr_infix(">=");
10327 return create_stringRepr_infix("<=");
10329 return create_stringRepr_infix("and");
10331 return create_stringRepr_infix("or");
10333 return create_stringRepr_infix("xor");
10335 return create_stringRepr_infix("and4b");
10337 return create_stringRepr_infix("or4b");
10339 return create_stringRepr_infix("xor4b");
10341 return create_stringRepr_infix("<<");
10343 return create_stringRepr_infix(">>");
10345 return create_stringRepr_infix("<@");
10347 return create_stringRepr_infix("@>");
10348 case OPTYPE_INT2BIT
:
10349 return create_stringRepr_predef2("int2bit");
10350 case OPTYPE_INT2HEX
:
10351 return create_stringRepr_predef2("int2hex");
10352 case OPTYPE_INT2OCT
:
10353 return create_stringRepr_predef2("int2oct");
10354 case OPTYPE_SUBSTR
: {
10355 string
ret_val("substr(");
10356 u
.expr
.ti1
->append_stringRepr(ret_val
);
10358 ret_val
+= u
.expr
.v2
->get_stringRepr();
10360 ret_val
+= u
.expr
.v3
->get_stringRepr();
10364 case OPTYPE_REGEXP
: {
10365 string
ret_val("regexp(");
10366 u
.expr
.ti1
->append_stringRepr(ret_val
);
10368 u
.expr
.t2
->append_stringRepr(ret_val
);
10370 ret_val
+= u
.expr
.v3
->get_stringRepr();
10374 case OPTYPE_DECOMP
: {
10375 string
ret_val("decomp(");
10376 ret_val
+= u
.expr
.v1
->get_stringRepr();
10378 ret_val
+= u
.expr
.v2
->get_stringRepr();
10380 ret_val
+= u
.expr
.v3
->get_stringRepr();
10384 case OPTYPE_REPLACE
: {
10385 string
ret_val("replace(");
10386 u
.expr
.ti1
->append_stringRepr(ret_val
);
10388 ret_val
+= u
.expr
.v2
->get_stringRepr();
10390 ret_val
+= u
.expr
.v3
->get_stringRepr();
10392 u
.expr
.ti4
->append_stringRepr(ret_val
);
10396 case OPTYPE_ISPRESENT
: {
10397 string
ret_val("ispresent(");
10398 u
.expr
.ti1
->append_stringRepr(ret_val
);
10401 case OPTYPE_ISCHOSEN
: {
10402 string
ret_val("ischosen(");
10403 ret_val
+= u
.expr
.r1
->get_dispname();
10405 ret_val
+= u
.expr
.i2
->get_dispname();
10408 case OPTYPE_ISCHOSEN_V
: {
10409 string
ret_val("ischosen(");
10410 ret_val
+= u
.expr
.v1
->get_stringRepr();
10412 ret_val
+= u
.expr
.i2
->get_dispname();
10415 case OPTYPE_ISCHOSEN_T
: {
10416 string
ret_val("ischosen(");
10417 ret_val
+= u
.expr
.t1
->get_stringRepr();
10419 ret_val
+= u
.expr
.i2
->get_dispname();
10422 case OPTYPE_LENGTHOF
: {
10423 string
ret_val("lengthof(");
10424 u
.expr
.ti1
->append_stringRepr(ret_val
);
10427 case OPTYPE_SIZEOF
: {
10428 string
ret_val("sizeof(");
10429 u
.expr
.ti1
->append_stringRepr(ret_val
);
10432 case OPTYPE_ISVALUE
: {
10433 string
ret_val("isvalue(");
10434 u
.expr
.ti1
->append_stringRepr(ret_val
);
10437 case OPTYPE_VALUEOF
: {
10438 string
ret_val("valueof(");
10439 u
.expr
.ti1
->append_stringRepr(ret_val
);
10442 case OPTYPE_LOG2STR
:
10443 return string("log2str(...)");
10444 case OPTYPE_MATCH
: {
10445 string
ret_val("match(");
10446 ret_val
+= u
.expr
.v1
->get_stringRepr();
10448 u
.expr
.t2
->append_stringRepr(ret_val
);
10451 case OPTYPE_TTCN2STRING
: {
10452 string
ret_val("ttcn2string(");
10453 u
.expr
.ti1
->append_stringRepr(ret_val
);
10457 case OPTYPE_UNDEF_RUNNING
:
10458 return u
.expr
.r1
->get_dispname() + ".running";
10459 case OPTYPE_COMP_NULL
:
10460 return string("null");
10461 case OPTYPE_COMP_MTC
:
10462 return string("mtc");
10463 case OPTYPE_COMP_SYSTEM
:
10464 return string("system");
10465 case OPTYPE_COMP_SELF
:
10466 return string("self");
10467 case OPTYPE_COMP_CREATE
: {
10468 string
ret_val(u
.expr
.r1
->get_dispname());
10469 ret_val
+= ".create";
10470 if (u
.expr
.v2
|| u
.expr
.v3
) {
10472 if (u
.expr
.v2
) ret_val
+= u
.expr
.v2
->get_stringRepr();
10473 else ret_val
+= '-';
10476 ret_val
+= u
.expr
.v3
->get_stringRepr();
10480 if (u
.expr
.b4
) ret_val
+= " alive";
10482 case OPTYPE_COMP_RUNNING
:
10483 return u
.expr
.v1
->get_stringRepr() + ".running";
10484 case OPTYPE_COMP_RUNNING_ANY
:
10485 return string("any component.running");
10486 case OPTYPE_COMP_RUNNING_ALL
:
10487 return string("all component.running");
10488 case OPTYPE_COMP_ALIVE
:
10489 return u
.expr
.v1
->get_stringRepr() + ".alive";
10490 case OPTYPE_COMP_ALIVE_ANY
:
10491 return string("any component.alive");
10492 case OPTYPE_COMP_ALIVE_ALL
:
10493 return string("all component.alive");
10494 case OPTYPE_TMR_READ
:
10495 return u
.expr
.r1
->get_dispname() + ".read";
10496 case OPTYPE_TMR_RUNNING
:
10497 return u
.expr
.r1
->get_dispname() + ".running";
10498 case OPTYPE_TMR_RUNNING_ANY
:
10499 return string("any timer.running");
10500 case OPTYPE_GETVERDICT
:
10501 return string("getverdict");
10502 case OPTYPE_ACTIVATE
: {
10503 string
ret_val("activate(");
10504 ret_val
+= u
.expr
.r1
->get_dispname();
10507 case OPTYPE_ACTIVATE_REFD
: {
10508 string
ret_val("activate(derefer(");
10509 ret_val
+= u
.expr
.v1
->get_stringRepr();
10511 if (u
.expr
.state
== EXPR_CHECKED
) {
10512 if (u
.expr
.ap_list2
) {
10513 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10514 for (size_t i
= 0; i
< nof_pars
; i
++) {
10515 if (i
> 0) ret_val
+= ", ";
10516 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10520 if (u
.expr
.t_list2
) {
10521 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10522 for (size_t i
= 0; i
< nof_pars
; i
++) {
10523 if (i
> 0) ret_val
+= ", ";
10524 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10530 case OPTYPE_EXECUTE
: {
10531 string
ret_val("execute(");
10532 ret_val
+= u
.expr
.r1
->get_dispname();
10535 ret_val
+= u
.expr
.v2
->get_stringRepr();
10539 case OPTYPE_EXECUTE_REFD
: {
10540 string
ret_val("execute(derefers(");
10541 ret_val
+= u
.expr
.v1
->get_stringRepr();
10543 if (u
.expr
.state
== EXPR_CHECKED
) {
10544 if (u
.expr
.ap_list2
) {
10545 size_t nof_pars
= u
.expr
.ap_list2
->get_nof_pars();
10546 for (size_t i
= 0; i
< nof_pars
; i
++) {
10547 if (i
> 0) ret_val
+= ", ";
10548 u
.expr
.ap_list2
->get_par(i
)->append_stringRepr(ret_val
);
10552 if (u
.expr
.t_list2
) {
10553 size_t nof_pars
= u
.expr
.t_list2
->get_nof_tis();
10554 for (size_t i
= 0; i
< nof_pars
; i
++) {
10555 if (i
> 0) ret_val
+= ", ";
10556 u
.expr
.t_list2
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10563 ret_val
+= u
.expr
.v3
->get_stringRepr();
10567 case OPTYPE_PROF_RUNNING
:
10568 return string("@profiler.running");
10570 return string("<unsupported optype>");
10571 } // switch u.expr.v_optype
10574 case MACRO_MODULEID
:
10575 return string("%moduleId");
10576 case MACRO_FILENAME
:
10577 return string("%fileName");
10578 case MACRO_BFILENAME
:
10579 return string("__BFILE__");
10580 case MACRO_FILEPATH
:
10581 return string("__FILE__");
10582 case MACRO_LINENUMBER
:
10583 return string("%lineNumber");
10584 case MACRO_LINENUMBER_C
:
10585 return string("__LINE__");
10586 case MACRO_DEFINITIONID
:
10587 return string("%definitionId");
10589 return string("__SCOPE__");
10590 case MACRO_TESTCASEID
:
10591 return string("%testcaseId");
10593 return string("<unknown macro>");
10594 } // switch u.macro
10596 return string('-');
10600 string
ret_val("refers(");
10601 ret_val
+= u
.refd_fat
->get_assname();
10606 ret_val
+= u
.invoke
.v
->get_stringRepr();
10607 ret_val
+= ".apply(";
10608 if (u
.invoke
.ap_list
) {
10609 size_t nof_pars
= u
.invoke
.ap_list
->get_nof_pars();
10610 for (size_t i
= 0; i
< nof_pars
; i
++) {
10611 if (i
> 0) ret_val
+= ", ";
10612 u
.invoke
.ap_list
->get_par(i
)->append_stringRepr(ret_val
);
10614 } else if (u
.invoke
.t_list
) {
10615 size_t nof_pars
= u
.invoke
.t_list
->get_nof_tis();
10616 for (size_t i
= 0; i
< nof_pars
; i
++) {
10617 if (i
> 0) ret_val
+= ", ";
10618 u
.invoke
.t_list
->get_ti_byIndex(i
)->append_stringRepr(ret_val
);
10624 string
ret_val("refers(");
10625 ret_val
+= u
.refered
->get_dispname();
10629 return string("<unsupported valuetype>");
10630 } // switch valuetype
10633 string
Value::create_stringRepr_unary(const char *operator_str
)
10635 string
ret_val(operator_str
);
10637 ret_val
+= u
.expr
.v1
->get_stringRepr();
10642 string
Value::create_stringRepr_infix(const char *operator_str
)
10644 string
ret_val('(');
10645 ret_val
+= u
.expr
.v1
->get_stringRepr();
10647 ret_val
+= operator_str
;
10649 ret_val
+= u
.expr
.v2
->get_stringRepr();
10654 string
Value::create_stringRepr_predef1(const char *function_name
)
10656 string
ret_val(function_name
);
10658 if (u
.expr
.v_optype
== OPTYPE_ENCODE
) { // ti1, not v1
10659 ret_val
+= u
.expr
.ti1
->get_specific_value()->get_stringRepr();
10661 else ret_val
+= u
.expr
.v1
->get_stringRepr();
10666 string
Value::create_stringRepr_predef2(const char *function_name
)
10668 string
ret_val(function_name
);
10670 ret_val
+= u
.expr
.v1
->get_stringRepr();
10672 ret_val
+= u
.expr
.v2
->get_stringRepr();
10677 bool Value::operator==(Value
& val
)
10679 Value
*left
= get_value_refd_last();
10680 Type
*left_governor
= left
->get_my_governor();
10681 if (left_governor
) left_governor
= left_governor
->get_type_refd_last();
10682 Value
*right
= val
.get_value_refd_last();
10683 Type
*right_governor
= right
->get_my_governor();
10684 if (right_governor
) right_governor
= right_governor
->get_type_refd_last();
10685 if (left_governor
&& right_governor
10686 && !left_governor
->is_compatible(right_governor
, NULL
)
10687 && !right_governor
->is_compatible(left_governor
, NULL
))
10688 FATAL_ERROR("Value::operator==");
10690 // Not-A-Value is not equal to anything (NaN analogy:)
10691 if ( (left
->valuetype
==V_ERROR
) || (right
->valuetype
==V_ERROR
) )
10694 switch (left
->valuetype
) {
10697 case V_DEFAULT_NULL
:
10700 return left
->valuetype
== right
->valuetype
;
10702 return right
->valuetype
== V_BOOL
&&
10703 left
->get_val_bool() == right
->get_val_bool();
10705 return right
->valuetype
== V_INT
&& *left
->get_val_Int()
10706 == *right
->get_val_Int();
10708 return right
->valuetype
== V_REAL
&&
10709 left
->get_val_Real() == right
->get_val_Real();
10711 switch (right
->valuetype
) {
10713 return left
->get_val_str() == right
->get_val_str();
10715 return right
->get_val_ustr() == left
->get_val_str();
10717 return right
->get_val_iso2022str() == left
->get_val_str();
10724 return left
->valuetype
== right
->valuetype
&&
10725 left
->get_val_str() == right
->get_val_str();
10727 switch (right
->valuetype
) {
10729 return left
->get_val_ustr() == right
->get_val_str();
10731 return left
->get_val_ustr() == right
->get_val_ustr();
10733 return left
->get_val_ustr() == right
->get_val_iso2022str();
10738 switch (right
->valuetype
) {
10740 return left
->get_val_iso2022str() == right
->get_val_str();
10742 // The appropriate operator==() is missing. The operands are swapped,
10743 // but it shouldn't be a problem.
10744 return right
->get_val_ustr() == left
->get_val_iso2022str();
10746 return left
->get_val_iso2022str() == right
->get_val_iso2022str();
10751 return right
->valuetype
== V_ENUM
&&
10752 left
->get_val_id()->get_name() == right
->get_val_id()->get_name();
10755 if (right
->valuetype
== V_OID
|| right
->valuetype
== V_ROID
) {
10756 vector
<string
> act
, other
;
10757 get_oid_comps(act
);
10758 val
.get_oid_comps(other
);
10759 size_t act_size
= act
.size(), other_size
= other
.size();
10761 if (act_size
== other_size
) {
10763 for (size_t i
= 0; i
< act_size
; i
++)
10764 if (*act
[i
] != *other
[i
]) {
10768 } else ret_val
= false;
10769 for (size_t i
= 0; i
< act_size
; i
++) delete act
[i
];
10771 for (size_t i
= 0; i
< other_size
; i
++) delete other
[i
];
10774 } else return false;
10776 return right
->valuetype
== V_CHOICE
&&
10777 left
->get_alt_name().get_name() == right
->get_alt_name().get_name() &&
10778 *(left
->get_alt_value()) == *(right
->get_alt_value());
10781 if (!left_governor
) FATAL_ERROR("Value::operator==");
10782 if (left
->valuetype
!= right
->valuetype
) return false;
10783 size_t nof_comps
= left_governor
->get_nof_comps();
10784 for (size_t i
= 0; i
< nof_comps
; i
++) {
10785 Value
*lval
= NULL
, *rval
= NULL
;
10786 CompField
* cfl
= left_governor
->get_comp_byIndex(i
);
10787 const Identifier
& field_name
= cfl
->get_name();
10788 if (left
->has_comp_withName(field_name
)) {
10789 lval
= left
->get_comp_value_byName(field_name
);
10790 if (right
->has_comp_withName(field_name
)) {
10791 rval
= right
->get_comp_value_byName(field_name
);
10792 if ((lval
->valuetype
== V_OMIT
&& rval
->valuetype
!= V_OMIT
)
10793 || (rval
->valuetype
== V_OMIT
&& lval
->valuetype
!=V_OMIT
))
10795 else if (!(*lval
== *rval
))
10798 if (cfl
->has_default()) {
10799 if (!(*lval
== *cfl
->get_defval()))
10802 if (lval
->valuetype
!= V_OMIT
)
10807 if(right
->has_comp_withName(field_name
)) {
10808 rval
= right
->get_comp_value_byName(field_name
);
10809 if(cfl
->has_default()) {
10810 if(rval
->valuetype
==V_OMIT
) return false;
10812 lval
= cfl
->get_defval();
10813 if (!(*lval
==*rval
)) return false;
10822 if (left
->valuetype
!= right
->valuetype
) return false;
10823 size_t ncomps
= get_nof_comps();
10824 if (ncomps
!= right
->get_nof_comps()) return false;
10826 if (left
->is_indexed() && right
->is_indexed()) { //both of them are indexed
10827 bool found
= false;
10828 map
<IndexedValue
*, void> uncovered
;
10829 for (size_t i
= 0; i
< left
->get_nof_comps(); ++i
)
10830 uncovered
.add(left
->u
.val_vs
->get_iv_byIndex(i
),0);
10832 for (size_t i
= 0; i
< right
->get_nof_comps(); ++i
) {
10834 for (size_t j
= 0; j
< uncovered
.size(); ++j
) {
10835 if (*(uncovered
.get_nth_key(j
)->get_value()) ==
10836 *(right
->get_comp_byIndex(i
)) &&
10837 *(uncovered
.get_nth_key(j
)->get_index()) ==
10838 *(right
->get_index_byIndex(i
))) {
10840 uncovered
.erase(uncovered
.get_nth_key(j
));
10848 } else if (left
->is_indexed() || right
->is_indexed()) {
10849 Value
* indexed_one
= 0;
10850 Value
* not_indexed_one
= 0;
10852 if(left
->is_indexed()) { // left is indexed, right is not
10853 indexed_one
= left
;
10854 not_indexed_one
= right
;
10855 } else { // right indexed, left is not
10856 indexed_one
= right
;
10857 not_indexed_one
= left
;
10860 for(size_t i
= 0; i
< ncomps
; ++i
) {
10861 Value
* ind
= indexed_one
->get_index_byIndex(i
)->get_value_refd_last();
10862 if(!(ind
->valuetype
== V_INT
&&
10863 *(not_indexed_one
->get_comp_byIndex(ind
->u
.val_Int
->get_val())) ==
10864 *(indexed_one
->get_comp_byIndex(i
))))
10868 } else { // none of them is indexed
10869 for (size_t i
= 0; i
< ncomps
; i
++) {
10870 if (!(*(left
->get_comp_byIndex(i
)) == *(right
->get_comp_byIndex(i
))))
10877 if (right
->valuetype
!= V_SETOF
) return false;
10878 size_t ncomps
= get_nof_comps();
10879 if (ncomps
!= right
->get_nof_comps()) return false;
10880 if (ncomps
== 0) return true;
10881 map
<size_t, void> uncovered
;
10882 for (size_t i
= 0; i
< ncomps
; i
++) uncovered
.add(i
, 0);
10883 for (size_t i
= 0; i
< ncomps
; i
++) {
10884 Value
*left_item
= left
->get_comp_byIndex(i
);
10885 bool pair_found
= false;
10886 for (size_t j
= 0; j
< ncomps
- i
; j
++) {
10887 size_t right_index
= uncovered
.get_nth_key(j
);
10888 if (*left_item
== *right
->get_comp_byIndex(right_index
)) {
10889 uncovered
.erase(right_index
);
10901 return right
->valuetype
== V_VERDICT
&&
10902 left
->get_val_verdict() == right
->get_val_verdict();
10906 return left
->valuetype
== right
->valuetype
&&
10907 left
->get_refd_assignment() == right
->get_refd_assignment();
10909 FATAL_ERROR("Value::operator==");
10914 bool Value::operator<(Value
& val
)
10916 Value
*left
= get_value_refd_last();
10917 Type
*left_governor
= left
->get_my_governor();
10918 if(left_governor
) left_governor
=left_governor
->get_type_refd_last();
10919 Value
*right
= val
.get_value_refd_last();
10920 Type
*right_governor
= right
->get_my_governor();
10921 if(right_governor
) right_governor
=right_governor
->get_type_refd_last();
10922 if (left
->get_valuetype() != right
->get_valuetype())
10923 FATAL_ERROR("Value::operator<");
10926 return *left
->get_val_Int() < *right
->get_val_Int();
10928 return (left
->get_val_Real() < right
->get_val_Real());
10930 if(!left_governor
|| !right_governor
)
10931 FATAL_ERROR("Value::operator<");
10932 if(left_governor
!=right_governor
)
10933 FATAL_ERROR("Value::operator<");
10934 return (left_governor
->get_enum_val_byId(*left
->get_val_id()) <
10935 right_governor
->get_enum_val_byId(*right
->get_val_id()));
10937 FATAL_ERROR("Value::operator<");
10942 bool Value::is_string_type(Type::expected_value_t exp_val
)
10944 switch (get_expr_returntype(exp_val
)) {
10956 void Value::generate_code_expr(expression_struct
*expr
)
10958 if (has_single_expr()) {
10959 expr
->expr
= mputstr(expr
->expr
, get_single_expr().c_str());
10961 switch (valuetype
) {
10963 generate_code_expr_expr(expr
);
10971 const string
& tmp_id
= get_temporary_id();
10972 const char *tmp_id_str
= tmp_id
.c_str();
10973 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
10974 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
);
10975 set_genname_recursive(tmp_id
);
10976 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10977 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10980 const string
& tmp_id
= get_temporary_id();
10981 const char *tmp_id_str
= tmp_id
.c_str();
10982 expr
->preamble
= mputprintf(expr
->preamble
, "INTEGER %s;\n",
10984 set_genname_recursive(tmp_id
);
10985 expr
->preamble
= generate_code_init(expr
->preamble
, tmp_id_str
);
10986 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
10989 if (!get_needs_conversion()) {
10990 u
.ref
.ref
->generate_code_const_ref(expr
);
10992 Type
*my_gov
= get_expr_governor_last();
10993 Type
*refd_gov
= u
.ref
.ref
->get_refd_assignment()->get_Type()
10994 ->get_field_type(u
.ref
.ref
->get_subrefs(),
10995 Type::EXPECTED_DYNAMIC_VALUE
)->get_type_refd_last();
10996 // Make sure that nothing goes wrong.
10997 if (!my_gov
|| !refd_gov
|| my_gov
== refd_gov
)
10998 FATAL_ERROR("Value::generate_code_expr()");
10999 expression_struct expr_tmp
;
11000 Code::init_expr(&expr_tmp
);
11001 const string
& tmp_id1
= get_temporary_id();
11002 const char *tmp_id_str1
= tmp_id1
.c_str();
11003 const string
& tmp_id2
= get_temporary_id();
11004 const char *tmp_id_str2
= tmp_id2
.c_str();
11005 expr
->preamble
= mputprintf(expr
->preamble
,
11006 "%s %s;\n", refd_gov
->get_genname_value(my_scope
).c_str(),
11008 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11009 u
.ref
.ref
->generate_code_const_ref(&expr_tmp
);
11010 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11011 expr
->preamble
= mputprintf(expr
->preamble
,
11013 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11014 "and `%s' are not compatible at run-time\");\n",
11015 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11016 TypeConv::get_conv_func(refd_gov
, my_gov
, get_my_scope()
11017 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
, my_gov
11018 ->get_typename().c_str(), refd_gov
->get_typename().c_str());
11019 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11023 generate_code_expr_invoke(expr
);
11026 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype
);
11031 void Value::generate_code_expr_mandatory(expression_struct
*expr
)
11033 generate_code_expr(expr
);
11034 if (valuetype
== V_REFD
&& get_value_refd_last()->valuetype
== V_REFD
)
11035 generate_code_expr_optional_field_ref(expr
, u
.ref
.ref
);
11038 bool Value::can_use_increment(Reference
*ref
) const
11040 if (valuetype
!= V_EXPR
) {
11043 switch (u
.expr
.v_optype
) {
11045 case OPTYPE_SUBTRACT
:
11050 bool v1_one
= u
.expr
.v1
->get_valuetype() == V_INT
&& *u
.expr
.v1
->get_val_Int() == 1;
11051 bool v2_one
= u
.expr
.v2
->get_valuetype() == V_INT
&& *u
.expr
.v2
->get_val_Int() == 1;
11052 if ((v1_one
&& u
.expr
.v2
->get_valuetype() == V_REFD
&&
11053 u
.expr
.v2
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id()) ||
11054 (v2_one
&& u
.expr
.v1
->get_valuetype() == V_REFD
&&
11055 u
.expr
.v1
->get_reference()->get_refd_assignment()->get_id() == ref
->get_refd_assignment()->get_id())) {
11061 char *Value::generate_code_init(char *str
, const char *name
)
11063 if (get_code_generated()) return str
;
11065 str
= err_descr
->generate_code_init_str(str
, string(name
) + "_err_descr");
11067 switch (valuetype
) {
11081 case V_DEFAULT_NULL
:
11086 // These values have a single string equivalent.
11087 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11090 if (u
.val_Int
->is_native_fit())
11091 str
= mputprintf(str
, "%s = %s;\n", name
, get_single_expr().c_str());
11093 // It's always an INTEGER.
11094 str
= mputprintf(str
, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11095 "}\n", get_single_expr().c_str(), name
);
11099 expression_struct expr
;
11100 Code::init_expr(&expr
);
11101 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
11102 generate_code_expr(&expr
);
11103 str
= Code::merge_free_expr(str
, &expr
);
11106 str
= generate_code_init_choice(str
, name
);
11110 if (!is_indexed()) str
= generate_code_init_seof(str
, name
);
11111 else str
= generate_code_init_indexed(str
, name
);
11114 if (!is_indexed()) str
= generate_code_init_array(str
, name
);
11115 else str
= generate_code_init_indexed(str
, name
);
11119 str
= generate_code_init_se(str
, name
);
11122 str
= generate_code_init_refd(str
, name
);
11126 case MACRO_TESTCASEID
:
11127 str
= mputprintf(str
, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name
);
11130 // all others must already be evaluated away
11131 FATAL_ERROR("Value::generate_code_init()");
11135 // unbound value, don't generate anything
11138 FATAL_ERROR("Value::generate_code_init()");
11141 str
= mputprintf(str
, "%s.set_err_descr(&%s_err_descr);\n", name
, name
);
11143 set_code_generated();
11147 char *Value::rearrange_init_code(char *str
, Common::Module
* usage_mod
)
11149 switch (valuetype
) {
11151 Ttcn::ActualParList
*parlist
= u
.ref
.ref
->get_parlist();
11153 str
= parlist
->rearrange_init_code(str
, usage_mod
);
11157 str
= u
.invoke
.v
->rearrange_init_code(str
, usage_mod
);
11158 str
= u
.invoke
.ap_list
->rearrange_init_code(str
, usage_mod
);
11161 switch (u
.expr
.v_optype
) {
11162 case OPTYPE_UNARYPLUS
:
11163 case OPTYPE_UNARYMINUS
:
11166 case OPTYPE_BIT2HEX
:
11167 case OPTYPE_BIT2INT
:
11168 case OPTYPE_BIT2OCT
:
11169 case OPTYPE_BIT2STR
:
11170 case OPTYPE_CHAR2INT
:
11171 case OPTYPE_CHAR2OCT
:
11172 case OPTYPE_FLOAT2INT
:
11173 case OPTYPE_FLOAT2STR
:
11174 case OPTYPE_HEX2BIT
:
11175 case OPTYPE_HEX2INT
:
11176 case OPTYPE_HEX2OCT
:
11177 case OPTYPE_HEX2STR
:
11178 case OPTYPE_INT2CHAR
:
11179 case OPTYPE_INT2FLOAT
:
11180 case OPTYPE_INT2STR
:
11181 case OPTYPE_INT2UNICHAR
:
11182 case OPTYPE_OCT2BIT
:
11183 case OPTYPE_OCT2CHAR
:
11184 case OPTYPE_OCT2HEX
:
11185 case OPTYPE_OCT2INT
:
11186 case OPTYPE_OCT2STR
:
11187 case OPTYPE_STR2BIT
:
11188 case OPTYPE_STR2FLOAT
:
11189 case OPTYPE_STR2HEX
:
11190 case OPTYPE_STR2INT
:
11191 case OPTYPE_STR2OCT
:
11192 case OPTYPE_UNICHAR2INT
:
11193 case OPTYPE_UNICHAR2CHAR
:
11194 case OPTYPE_ENUM2INT
:
11195 case OPTYPE_ISCHOSEN_V
:
11196 case OPTYPE_GET_STRINGENCODING
:
11197 case OPTYPE_REMOVE_BOM
:
11198 case OPTYPE_DECODE_BASE64
:
11199 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11201 case OPTYPE_DECODE
: {
11202 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
11203 Common::Assignment
*ass
= u
.expr
.r1
->get_refd_assignment();
11204 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11206 parlist
= u
.expr
.r2
->get_parlist();
11207 ass
= u
.expr
.r2
->get_refd_assignment();
11208 if (parlist
) str
= parlist
->rearrange_init_code(str
, usage_mod
);
11211 case OPTYPE_SUBTRACT
:
11212 case OPTYPE_MULTIPLY
:
11213 case OPTYPE_DIVIDE
:
11216 case OPTYPE_CONCAT
:
11233 case OPTYPE_INT2BIT
:
11234 case OPTYPE_INT2HEX
:
11235 case OPTYPE_INT2OCT
:
11236 //case OPTYPE_DECODE:
11237 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11238 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11240 case OPTYPE_UNICHAR2OCT
: // v1 [v2]
11241 case OPTYPE_OCT2UNICHAR
:
11242 case OPTYPE_ENCODE_BASE64
:
11243 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11244 if (u
.expr
.v2
) str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11246 case OPTYPE_SUBSTR
:
11247 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11248 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11249 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11251 case OPTYPE_REGEXP
:
11252 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11253 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11254 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11256 case OPTYPE_DECOMP
:
11257 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11258 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11259 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11261 case OPTYPE_REPLACE
:
11262 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11263 str
= u
.expr
.v2
->rearrange_init_code(str
, usage_mod
);
11264 str
= u
.expr
.v3
->rearrange_init_code(str
, usage_mod
);
11265 str
= u
.expr
.ti4
->rearrange_init_code(str
, usage_mod
);
11267 case OPTYPE_LENGTHOF
:
11268 case OPTYPE_SIZEOF
:
11269 case OPTYPE_VALUEOF
:
11270 case OPTYPE_ENCODE
:
11271 case OPTYPE_ISPRESENT
:
11272 case OPTYPE_TTCN2STRING
:
11273 str
= u
.expr
.ti1
->rearrange_init_code(str
, usage_mod
);
11275 case OPTYPE_ISCHOSEN_T
:
11276 str
= u
.expr
.t1
->rearrange_init_code(str
, usage_mod
);
11279 str
= u
.expr
.v1
->rearrange_init_code(str
, usage_mod
);
11280 str
= u
.expr
.t2
->rearrange_init_code(str
, usage_mod
);
11283 // other kinds of expressions cannot appear within templates
11293 char* Value::generate_code_tmp(char *str
, const char *prefix
,
11294 size_t& blockcount
)
11296 char *s2
= memptystr();
11297 char *s1
= generate_code_tmp(NULL
, s2
);
11299 if (blockcount
== 0) {
11300 str
= mputstr(str
, "{\n");
11303 str
= mputstr(str
, s2
);
11306 str
=mputstr(str
, prefix
);
11307 str
=mputstr(str
, s1
);
11312 char *Value::generate_code_tmp(char *str
, char*& init
)
11314 expression_struct expr
;
11315 Code::init_expr(&expr
);
11316 generate_code_expr_mandatory(&expr
);
11317 if (expr
.preamble
|| expr
.postamble
) {
11318 if (valuetype
== V_EXPR
&&
11319 (u
.expr
.v_optype
== OPTYPE_AND
|| u
.expr
.v_optype
== OPTYPE_OR
)) {
11320 // a temporary variable is already introduced
11321 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11322 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11323 str
= mputstr(str
, expr
.expr
);
11325 const string
& tmp_id
= get_temporary_id();
11326 const char *tmp_id_str
= tmp_id
.c_str();
11327 init
= mputprintf(init
, "%s %s;\n"
11329 my_governor
->get_type_refd_last()->get_typetype() == Type::T_BOOL
?
11330 "boolean" : my_governor
->get_genname_value(my_scope
).c_str(),
11332 if (expr
.preamble
) init
= mputstr(init
, expr
.preamble
);
11333 init
= mputprintf(init
, "%s = %s;\n", tmp_id_str
, expr
.expr
);
11334 if (expr
.postamble
) init
= mputstr(init
, expr
.postamble
);
11335 init
= mputstr(init
, "}\n");
11336 str
= mputstr(str
, tmp_id_str
);
11338 } else str
= mputstr(str
, expr
.expr
);
11339 Code::free_expr(&expr
);
11343 void Value::generate_code_log(expression_struct
*expr
)
11345 if (explicit_cast_needed()) {
11346 char *expr_backup
= expr
->expr
;
11348 generate_code_expr(expr
);
11349 const string
& tmp_id
= get_temporary_id();
11350 const char *tmp_id_str
= tmp_id
.c_str();
11351 // We have to create a temporary object, because the parser of GCC
11352 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11353 // constructor call that is, this does not work: type(...).log(); but
11354 // this works: type tmp(...); tmp.log();.
11355 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s(%s);\n",
11356 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str
,
11359 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11361 generate_code_expr(expr
);
11363 expr
->expr
= mputstr(expr
->expr
, ".log()");
11366 void Value::generate_code_log_match(expression_struct
*expr
)
11368 if (valuetype
!= V_EXPR
|| u
.expr
.v_optype
!= OPTYPE_MATCH
)
11369 FATAL_ERROR("Value::generate_code_log_match()");
11370 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11371 // compliance the whole code-generation should be checked. Standalone
11372 // constructs like: "A(a[0].f());" should be avoided. The current
11373 // solution for HK38721 uses an additional assignment to overcome the
11374 // issue. The generated code will be slower, but it's needed for old GCC
11375 // versions in specific circumstances.
11376 if (u
.expr
.t2
->needs_temp_ref()) {
11377 char *expr_backup
= expr
->expr
;
11379 u
.expr
.t2
->generate_code(expr
);
11380 const string
& tmp_id
= get_temporary_id();
11381 const char *tmp_id_str
= tmp_id
.c_str();
11382 expr
->preamble
= mputprintf(expr
->preamble
,
11383 "%s %s = %s;\n", u
.expr
.t2
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
11384 ->get_genname_template(my_scope
).c_str(), tmp_id_str
, expr
->expr
);
11386 expr
->expr
= mputstr(expr_backup
, tmp_id_str
);
11388 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11389 // some reason "(A(NS::B)).a(C);" compiles fine.
11390 expr
->expr
= mputc(expr
->expr
, '(');
11391 u
.expr
.t2
->generate_code(expr
);
11392 expr
->expr
= mputc(expr
->expr
, ')');
11394 expr
->expr
= mputstr(expr
->expr
, ".log_match(");
11395 u
.expr
.v1
->generate_code_expr(expr
);
11396 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11399 void Value::generate_code_expr_expr(expression_struct
*expr
)
11401 switch (u
.expr
.v_optype
) {
11403 generate_code_expr_rnd(expr
, 0);
11405 case OPTYPE_UNARYPLUS
:
11406 // same as without the '+' operator
11407 u
.expr
.v1
->generate_code_expr(expr
);
11409 case OPTYPE_UNARYMINUS
:
11410 generate_code_expr_unary(expr
, "-", u
.expr
.v1
);
11413 generate_code_expr_unary(expr
, "!", u
.expr
.v1
);
11416 generate_code_expr_unary(expr
, "~", u
.expr
.v1
);
11418 case OPTYPE_BIT2HEX
:
11419 generate_code_expr_predef1(expr
, "bit2hex", u
.expr
.v1
);
11421 case OPTYPE_BIT2INT
:
11422 generate_code_expr_predef1(expr
, "bit2int", u
.expr
.v1
);
11424 case OPTYPE_BIT2OCT
:
11425 generate_code_expr_predef1(expr
, "bit2oct", u
.expr
.v1
);
11427 case OPTYPE_BIT2STR
:
11428 generate_code_expr_predef1(expr
, "bit2str", u
.expr
.v1
);
11430 case OPTYPE_CHAR2INT
:
11431 generate_code_expr_predef1(expr
, "char2int", u
.expr
.v1
);
11433 case OPTYPE_CHAR2OCT
:
11434 generate_code_expr_predef1(expr
, "char2oct", u
.expr
.v1
);
11436 case OPTYPE_FLOAT2INT
:
11437 generate_code_expr_predef1(expr
, "float2int", u
.expr
.v1
);
11439 case OPTYPE_FLOAT2STR
:
11440 generate_code_expr_predef1(expr
, "float2str", u
.expr
.v1
);
11442 case OPTYPE_HEX2BIT
:
11443 generate_code_expr_predef1(expr
, "hex2bit", u
.expr
.v1
);
11445 case OPTYPE_HEX2INT
:
11446 generate_code_expr_predef1(expr
, "hex2int", u
.expr
.v1
);
11448 case OPTYPE_HEX2OCT
:
11449 generate_code_expr_predef1(expr
, "hex2oct", u
.expr
.v1
);
11451 case OPTYPE_HEX2STR
:
11452 generate_code_expr_predef1(expr
, "hex2str", u
.expr
.v1
);
11454 case OPTYPE_INT2CHAR
:
11455 generate_code_expr_predef1(expr
, "int2char", u
.expr
.v1
);
11457 case OPTYPE_INT2FLOAT
:
11458 generate_code_expr_predef1(expr
, "int2float", u
.expr
.v1
);
11460 case OPTYPE_INT2STR
:
11461 generate_code_expr_predef1(expr
, "int2str", u
.expr
.v1
);
11463 case OPTYPE_INT2UNICHAR
:
11464 generate_code_expr_predef1(expr
, "int2unichar", u
.expr
.v1
);
11466 case OPTYPE_OCT2BIT
:
11467 generate_code_expr_predef1(expr
, "oct2bit", u
.expr
.v1
);
11469 case OPTYPE_OCT2CHAR
:
11470 generate_code_expr_predef1(expr
, "oct2char", u
.expr
.v1
);
11472 case OPTYPE_GET_STRINGENCODING
:
11473 generate_code_expr_predef1(expr
, "get_stringencoding", u
.expr
.v1
);
11475 case OPTYPE_REMOVE_BOM
:
11476 generate_code_expr_predef1(expr
, "remove_bom", u
.expr
.v1
);
11478 case OPTYPE_ENCODE_BASE64
:
11480 generate_code_expr_predef2(expr
, "encode_base64", u
.expr
.v1
, u
.expr
.v2
);
11482 generate_code_expr_predef1(expr
, "encode_base64", u
.expr
.v1
);
11484 case OPTYPE_DECODE_BASE64
:
11485 generate_code_expr_predef1(expr
, "decode_base64", u
.expr
.v1
);
11487 case OPTYPE_OCT2UNICHAR
:
11489 generate_code_expr_predef2(expr
, "oct2unichar", u
.expr
.v1
, u
.expr
.v2
);
11491 generate_code_expr_predef1(expr
, "oct2unichar", u
.expr
.v1
);
11493 case OPTYPE_UNICHAR2OCT
:
11495 generate_code_expr_predef2(expr
, "unichar2oct", u
.expr
.v1
, u
.expr
.v2
);
11497 generate_code_expr_predef1(expr
, "unichar2oct", u
.expr
.v1
);
11499 case OPTYPE_OCT2HEX
:
11500 generate_code_expr_predef1(expr
, "oct2hex", u
.expr
.v1
);
11502 case OPTYPE_OCT2INT
:
11503 generate_code_expr_predef1(expr
, "oct2int", u
.expr
.v1
);
11505 case OPTYPE_OCT2STR
:
11506 generate_code_expr_predef1(expr
, "oct2str", u
.expr
.v1
);
11508 case OPTYPE_STR2BIT
:
11509 generate_code_expr_predef1(expr
, "str2bit", u
.expr
.v1
);
11511 case OPTYPE_STR2FLOAT
:
11512 generate_code_expr_predef1(expr
, "str2float", u
.expr
.v1
);
11514 case OPTYPE_STR2HEX
:
11515 generate_code_expr_predef1(expr
, "str2hex", u
.expr
.v1
);
11517 case OPTYPE_STR2INT
:
11518 generate_code_expr_predef1(expr
, "str2int", u
.expr
.v1
);
11520 case OPTYPE_STR2OCT
:
11521 generate_code_expr_predef1(expr
, "str2oct", u
.expr
.v1
);
11523 case OPTYPE_UNICHAR2INT
:
11524 generate_code_expr_predef1(expr
, "unichar2int", u
.expr
.v1
);
11526 case OPTYPE_UNICHAR2CHAR
:
11527 generate_code_expr_predef1(expr
, "unichar2char", u
.expr
.v1
);
11529 case OPTYPE_ENUM2INT
: {
11530 Type
* enum_type
= u
.expr
.v1
->get_expr_governor_last();
11531 if (!enum_type
) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11532 expr
->expr
= mputprintf(expr
->expr
, "%s::enum2int(",
11533 enum_type
->get_genname_value(my_scope
).c_str());
11534 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11535 expr
->expr
= mputc(expr
->expr
, ')');
11537 case OPTYPE_ENCODE
:
11538 generate_code_expr_encode(expr
);
11540 case OPTYPE_DECODE
:
11541 generate_code_expr_decode(expr
);
11543 case OPTYPE_RNDWITHVAL
:
11544 generate_code_expr_rnd(expr
, u
.expr
.v1
);
11547 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11549 case OPTYPE_SUBTRACT
:
11550 generate_code_expr_infix(expr
, "-", u
.expr
.v1
, u
.expr
.v2
, false);
11552 case OPTYPE_MULTIPLY
:
11553 generate_code_expr_infix(expr
, "*", u
.expr
.v1
, u
.expr
.v2
, false);
11555 case OPTYPE_DIVIDE
:
11556 generate_code_expr_infix(expr
, "/", u
.expr
.v1
, u
.expr
.v2
, false);
11559 generate_code_expr_predef2(expr
, "mod", u
.expr
.v1
, u
.expr
.v2
);
11562 generate_code_expr_predef2(expr
, "rem", u
.expr
.v1
, u
.expr
.v2
);
11564 case OPTYPE_CONCAT
:
11565 generate_code_expr_infix(expr
, "+", u
.expr
.v1
, u
.expr
.v2
, false);
11568 generate_code_expr_infix(expr
, "==", u
.expr
.v1
, u
.expr
.v2
, true);
11571 generate_code_expr_infix(expr
, "<", u
.expr
.v1
, u
.expr
.v2
, false);
11574 generate_code_expr_infix(expr
, ">", u
.expr
.v1
, u
.expr
.v2
, false);
11577 generate_code_expr_infix(expr
, "!=", u
.expr
.v1
, u
.expr
.v2
, true);
11580 generate_code_expr_infix(expr
, ">=", u
.expr
.v1
, u
.expr
.v2
, false);
11583 generate_code_expr_infix(expr
, "<=", u
.expr
.v1
, u
.expr
.v2
, false);
11587 generate_code_expr_and_or(expr
);
11590 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11593 generate_code_expr_infix(expr
, "&", u
.expr
.v1
, u
.expr
.v2
, false);
11596 generate_code_expr_infix(expr
, "|", u
.expr
.v1
, u
.expr
.v2
, false);
11599 generate_code_expr_infix(expr
, "^", u
.expr
.v1
, u
.expr
.v2
, false);
11602 generate_code_expr_infix(expr
, "<<", u
.expr
.v1
, u
.expr
.v2
, false);
11605 generate_code_expr_infix(expr
, ">>", u
.expr
.v1
, u
.expr
.v2
, false);
11608 generate_code_expr_infix(expr
, "<<=", u
.expr
.v1
, u
.expr
.v2
, false);
11611 generate_code_expr_infix(expr
, ">>=", u
.expr
.v1
, u
.expr
.v2
, false);
11613 case OPTYPE_INT2BIT
:
11614 generate_code_expr_predef2(expr
, "int2bit", u
.expr
.v1
, u
.expr
.v2
);
11616 case OPTYPE_INT2HEX
:
11617 generate_code_expr_predef2(expr
, "int2hex", u
.expr
.v1
, u
.expr
.v2
);
11619 case OPTYPE_INT2OCT
:
11620 generate_code_expr_predef2(expr
, "int2oct", u
.expr
.v1
, u
.expr
.v2
);
11622 case OPTYPE_SUBSTR
:
11623 if (!get_needs_conversion()) generate_code_expr_substr(expr
);
11624 else generate_code_expr_substr_replace_compat(expr
);
11626 case OPTYPE_REGEXP
:
11627 generate_code_expr_regexp(expr
);
11629 case OPTYPE_DECOMP
:
11630 generate_code_expr_predef3(expr
, "decomp", u
.expr
.v1
, u
.expr
.v2
, u
.expr
.v3
);
11632 case OPTYPE_REPLACE
:
11633 if (!get_needs_conversion()) generate_code_expr_replace(expr
);
11634 else generate_code_expr_substr_replace_compat(expr
);
11636 case OPTYPE_ISCHOSEN
: // r1 i2
11637 FATAL_ERROR("Value::generate_code_expr_expr()");
11639 case OPTYPE_ISCHOSEN_V
: // v1 i2
11640 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
11641 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11642 u
.expr
.v1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11643 u
.expr
.i2
->get_name().c_str());
11645 case OPTYPE_ISCHOSEN_T
: // t1 i2
11646 u
.expr
.t1
->generate_code_expr(expr
);
11647 expr
->expr
= mputprintf(expr
->expr
, ".ischosen(%s::ALT_%s)",
11648 u
.expr
.t1
->get_my_governor()->get_genname_value(my_scope
).c_str(),
11649 u
.expr
.i2
->get_name().c_str());
11651 case OPTYPE_ISPRESENT
:
11652 case OPTYPE_ISBOUND
: {
11653 Template::templatetype_t temp
= u
.expr
.ti1
->get_Template()
11654 ->get_templatetype();
11655 if (temp
== Template::SPECIFIC_VALUE
) {
11656 Value
* specific_value
= u
.expr
.ti1
->get_Template()
11657 ->get_specific_value();
11658 if (specific_value
->get_valuetype() == Value::V_REFD
) {
11659 Ttcn::Reference
* reference
=
11660 dynamic_cast<Ttcn::Reference
*>(specific_value
->get_reference());
11662 reference
->generate_code_ispresentbound(expr
, false,
11663 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11667 } else if (temp
== Template::TEMPLATE_REFD
){
11668 Ttcn::Reference
* reference
=
11669 dynamic_cast<Ttcn::Reference
*>(u
.expr
.ti1
->get_Template()
11670 ->get_reference());
11672 reference
->generate_code_ispresentbound(expr
, true,
11673 u
.expr
.v_optype
==OPTYPE_ISBOUND
);
11679 case OPTYPE_LENGTHOF
: // ti1
11680 // fall through, separated later
11681 case OPTYPE_SIZEOF
: // ti1
11682 // fall through, separated later
11683 case OPTYPE_ISVALUE
: { // ti1
11684 if (u
.expr
.ti1
->is_only_specific_value()) {
11685 Value
*t_val
=u
.expr
.ti1
->get_Template()->get_specific_value();
11686 bool cast_needed
= t_val
->explicit_cast_needed(
11687 u
.expr
.v_optype
!= OPTYPE_LENGTHOF
);
11689 // the ambiguous C++ expression is converted to the value class
11690 expr
->expr
= mputprintf(expr
->expr
, "%s(",
11691 t_val
->get_my_governor()->get_genname_value(my_scope
).c_str());
11694 if (u
.expr
.v_optype
!= OPTYPE_LENGTHOF
11695 && u
.expr
.v_optype
!= OPTYPE_SIZEOF
) {
11696 t_val
->generate_code_expr(expr
);
11698 t_val
->generate_code_expr_mandatory(expr
);
11701 if(cast_needed
) expr
->expr
=mputc(expr
->expr
, ')');
11703 else u
.expr
.ti1
->generate_code(expr
);
11705 switch (u
.expr
.v_optype
) {
11706 case OPTYPE_ISBOUND
:
11707 expr
->expr
=mputstr(expr
->expr
, ".is_bound()");
11709 case OPTYPE_ISPRESENT
:
11710 expr
->expr
=mputprintf(expr
->expr
, ".is_present()");
11712 case OPTYPE_SIZEOF
:
11713 expr
->expr
=mputstr(expr
->expr
, ".size_of()");
11715 case OPTYPE_LENGTHOF
:
11716 expr
->expr
=mputstr(expr
->expr
, ".lengthof()");
11718 case OPTYPE_ISVALUE
:
11719 expr
->expr
=mputstr(expr
->expr
, ".is_value()");
11722 FATAL_ERROR("Value::generate_code_expr_expr()");
11725 case OPTYPE_VALUEOF
: // ti1
11726 u
.expr
.ti1
->generate_code(expr
);
11727 expr
->expr
= mputstr(expr
->expr
, ".valueof()");
11729 case OPTYPE_MATCH
: // v1 t2
11730 u
.expr
.t2
->generate_code(expr
);
11731 expr
->expr
= mputstr(expr
->expr
, ".match(");
11732 u
.expr
.v1
->generate_code_expr(expr
);
11733 expr
->expr
= mputprintf(expr
->expr
, "%s)", omit_in_value_list
? ", TRUE" : "");
11735 case OPTYPE_UNDEF_RUNNING
:
11736 // it is resolved during semantic check
11737 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11739 case OPTYPE_COMP_NULL
: // -
11740 expr
->expr
=mputstr(expr
->expr
, "NULL_COMPREF");
11742 case OPTYPE_COMP_MTC
: // -
11743 expr
->expr
=mputstr(expr
->expr
, "MTC_COMPREF");
11745 case OPTYPE_COMP_SYSTEM
: // -
11746 expr
->expr
=mputstr(expr
->expr
, "SYSTEM_COMPREF");
11748 case OPTYPE_COMP_SELF
: // -
11749 expr
->expr
=mputstr(expr
->expr
, "self");
11751 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
11752 generate_code_expr_create(expr
, u
.expr
.r1
, u
.expr
.v2
, u
.expr
.v3
,
11755 case OPTYPE_COMP_RUNNING
: // v1
11756 u
.expr
.v1
->generate_code_expr(expr
);
11757 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11758 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11759 expr
->expr
= mputstr(expr
->expr
, ".running()");
11761 case OPTYPE_COMP_RUNNING_ANY
: // -
11762 expr
->expr
=mputstr(expr
->expr
,
11763 "TTCN_Runtime::component_running(ANY_COMPREF)");
11765 case OPTYPE_COMP_RUNNING_ALL
: // -
11766 expr
->expr
=mputstr(expr
->expr
,
11767 "TTCN_Runtime::component_running(ALL_COMPREF)");
11769 case OPTYPE_COMP_ALIVE
: // v1
11770 u
.expr
.v1
->generate_code_expr(expr
);
11771 if(u
.expr
.v1
->get_valuetype() == V_REFD
)
11772 generate_code_expr_optional_field_ref(expr
, u
.expr
.v1
->get_reference());
11773 expr
->expr
= mputstr(expr
->expr
, ".alive()");
11775 case OPTYPE_COMP_ALIVE_ANY
: // -
11776 expr
->expr
= mputstr(expr
->expr
,
11777 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11779 case OPTYPE_COMP_ALIVE_ALL
: // -
11780 expr
->expr
= mputstr(expr
->expr
,
11781 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11783 case OPTYPE_TMR_READ
: // r1
11784 u
.expr
.r1
->generate_code(expr
);
11785 expr
->expr
= mputstr(expr
->expr
, ".read()");
11787 case OPTYPE_TMR_RUNNING
: // r1
11788 u
.expr
.r1
->generate_code(expr
);
11789 expr
->expr
= mputstr(expr
->expr
, ".running()");
11791 case OPTYPE_TMR_RUNNING_ANY
: // -
11792 expr
->expr
=mputstr(expr
->expr
, "TIMER::any_running()");
11794 case OPTYPE_GETVERDICT
: // -
11795 expr
->expr
=mputstr(expr
->expr
, "TTCN_Runtime::getverdict()");
11797 case OPTYPE_TESTCASENAME
: // -
11798 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::get_testcasename()");
11800 case OPTYPE_ACTIVATE
: // r1
11801 generate_code_expr_activate(expr
);
11803 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
11804 generate_code_expr_activate_refd(expr
);
11806 case OPTYPE_EXECUTE
: // r1 [v2]
11807 generate_code_expr_execute(expr
);
11809 case OPTYPE_EXECUTE_REFD
: //v1 ap_list2 [v3]
11810 generate_code_expr_execute_refd(expr
);
11812 case OPTYPE_LOG2STR
:
11813 u
.expr
.logargs
->generate_code_expr(expr
);
11815 case OPTYPE_TTCN2STRING
: {
11816 Type
* param_governor
= u
.expr
.ti1
->get_Template()->get_template_refd_last()->get_my_governor();
11817 if (param_governor
==NULL
) FATAL_ERROR("Value::generate_code_expr_expr()");
11818 param_governor
= param_governor
->get_type_refd_last();
11819 expr
->expr
= mputstr(expr
->expr
, "ttcn_to_string(");
11820 if (!u
.expr
.ti1
->get_DerivedRef() && !u
.expr
.ti1
->get_Type() &&
11821 u
.expr
.ti1
->get_Template()->is_Value()) {
11822 Value
* v
= u
.expr
.ti1
->get_Template()->get_Value();
11825 bool cast_needed
= v
->explicit_cast_needed();
11827 expr
->expr
= mputprintf(expr
->expr
, "%s(", param_governor
->get_genname_value(my_scope
).c_str());
11829 v
->generate_code_expr(expr
);
11831 expr
->expr
= mputstr(expr
->expr
, ")");
11835 u
.expr
.ti1
->generate_code(expr
);
11837 expr
->expr
= mputstr(expr
->expr
, ")");
11839 case OPTYPE_PROF_RUNNING
:
11840 expr
->expr
= mputstr(expr
->expr
, "ttcn3_prof.is_running()");
11843 FATAL_ERROR("Value::generate_code_expr_expr()");
11847 void Value::generate_code_expr_unary(expression_struct
*expr
,
11848 const char *operator_str
, Value
*v1
)
11850 expr
->expr
= mputprintf(expr
->expr
, "(%s(", operator_str
);
11851 v1
->generate_code_expr_mandatory(expr
);
11852 expr
->expr
= mputstrn(expr
->expr
, "))", 2);
11855 void Value::generate_code_expr_infix(expression_struct
*expr
,
11856 const char *operator_str
, Value
*v1
,
11857 Value
*v2
, bool optional_allowed
)
11859 if (!get_needs_conversion()) {
11860 expr
->expr
= mputc(expr
->expr
, '(');
11861 if (optional_allowed
) v1
->generate_code_expr(expr
);
11862 else v1
->generate_code_expr_mandatory(expr
);
11863 expr
->expr
= mputprintf(expr
->expr
, " %s ", operator_str
);
11864 if (optional_allowed
) v2
->generate_code_expr(expr
);
11865 else v2
->generate_code_expr_mandatory(expr
);
11866 expr
->expr
= mputc(expr
->expr
, ')');
11867 } else { // Temporary variable for the converted value.
11868 const string
& tmp_id1
= get_temporary_id();
11869 const char *tmp_id_str1
= tmp_id1
.c_str();
11870 expression_struct expr_tmp
;
11871 Code::init_expr(&expr_tmp
);
11872 switch (u
.expr
.v_optype
) {
11875 // Always "v1 -> v2".
11876 Type
*t1
= v1
->get_expr_governor_last();
11877 Type
*t2
= v2
->get_expr_governor_last();
11878 if (t1
== t2
) FATAL_ERROR("Value::generate_code_expr_infix()");
11879 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11880 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11881 if (expr_tmp
.preamble
)
11882 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
11883 expr
->preamble
= mputprintf(expr
->preamble
,
11885 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11886 "and `%s' are not compatible at run-time\");\n",
11887 t1
->get_genname_value(v1
->get_my_scope()).c_str(), tmp_id_str1
,
11888 TypeConv::get_conv_func(t2
, t1
, get_my_scope()
11889 ->get_scope_mod()).c_str(), tmp_id_str1
, expr_tmp
.expr
,
11890 t2
->get_typename().c_str(), t1
->get_typename().c_str());
11891 Code::free_expr(&expr_tmp
);
11892 if (optional_allowed
) v1
->generate_code_expr(expr
);
11893 else v1
->generate_code_expr_mandatory(expr
);
11894 expr
->expr
= mputprintf(expr
->expr
, " %s %s", operator_str
,
11897 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11898 // functions. The governors of all operands must exist at this point.
11901 case OPTYPE_CONCAT
: {
11902 const string
& tmp_id2
= get_temporary_id();
11903 const char *tmp_id_str2
= tmp_id2
.c_str();
11904 if (!my_governor
) FATAL_ERROR("Value::generate_code_expr_infix()");
11905 Type
*my_gov
= my_governor
->get_type_refd_last();
11906 Type
*t1_gov
= v1
->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE
)
11907 ->get_type_refd_last();
11908 if (!t1_gov
|| my_gov
== t1_gov
)
11909 FATAL_ERROR("Value::generate_code_expr_infix()");
11910 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
11911 t1_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str1
);
11912 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, "%s = ", tmp_id_str1
);
11913 if (optional_allowed
) v1
->generate_code_expr(&expr_tmp
);
11914 else v1
->generate_code_expr_mandatory(&expr_tmp
);
11915 expr_tmp
.expr
= mputprintf(expr_tmp
.expr
, " %s ", operator_str
);
11916 if (optional_allowed
) v2
->generate_code_expr(&expr_tmp
);
11917 else v2
->generate_code_expr_mandatory(&expr_tmp
);
11918 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr_tmp
);
11919 expr
->preamble
= mputprintf(expr
->preamble
,
11921 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11922 "and `%s' are not compatible at run-time\");\n",
11923 my_gov
->get_genname_value(my_scope
).c_str(), tmp_id_str2
,
11924 TypeConv::get_conv_func(t1_gov
, my_gov
, get_my_scope()
11925 ->get_scope_mod()).c_str(), tmp_id_str2
, tmp_id_str1
,
11926 my_gov
->get_typename().c_str(), t1_gov
->get_typename().c_str());
11927 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str2
);
11930 FATAL_ERROR("Value::generate_code_expr_infix()");
11936 void Value::generate_code_expr_and_or(expression_struct
*expr
)
11938 if (u
.expr
.v2
->needs_short_circuit()) {
11939 // introduce a temporary variable to store the result of the operation
11940 const string
& tmp_id
= get_temporary_id();
11941 const char *tmp_id_str
= tmp_id
.c_str();
11942 expr
->preamble
= mputprintf(expr
->preamble
, "boolean %s;\n", tmp_id_str
);
11943 expression_struct expr2
;
11944 // the left operand must be evaluated anyway
11945 Code::init_expr(&expr2
);
11946 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11947 u
.expr
.v1
->generate_code_expr_mandatory(&expr2
);
11948 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11949 expr
->preamble
= mputprintf(expr
->preamble
, "if (%s%s) ",
11950 u
.expr
.v_optype
== OPTYPE_AND
? "" : "!", tmp_id_str
);
11951 // evaluate the right operand only when necessary
11952 // in this case the final result will be the right operand
11953 Code::init_expr(&expr2
);
11954 expr2
.expr
= mputprintf(expr2
.expr
, "%s = ", tmp_id_str
);
11955 u
.expr
.v2
->generate_code_expr_mandatory(&expr2
);
11956 expr
->preamble
= Code::merge_free_expr(expr
->preamble
, &expr2
);
11957 // the result is now in the temporary variable
11958 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
11960 // use the overloaded operator to get better error messages
11961 generate_code_expr_infix(expr
, u
.expr
.v_optype
== OPTYPE_AND
?
11962 "&&" : "||", u
.expr
.v1
, u
.expr
.v2
, false);
11966 void Value::generate_code_expr_predef1(expression_struct
*expr
,
11967 const char *function_name
,
11970 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11971 v1
->generate_code_expr_mandatory(expr
);
11972 expr
->expr
= mputc(expr
->expr
, ')');
11975 void Value::generate_code_expr_predef2(expression_struct
*expr
,
11976 const char *function_name
,
11977 Value
*v1
, Value
*v2
)
11979 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11980 v1
->generate_code_expr_mandatory(expr
);
11981 expr
->expr
= mputstr(expr
->expr
, ", ");
11982 v2
->generate_code_expr_mandatory(expr
);
11983 expr
->expr
= mputc(expr
->expr
, ')');
11986 void Value::generate_code_expr_predef3(expression_struct
*expr
,
11987 const char *function_name
,
11988 Value
*v1
, Value
*v2
, Value
*v3
)
11990 expr
->expr
= mputprintf(expr
->expr
, "%s(", function_name
);
11991 v1
->generate_code_expr_mandatory(expr
);
11992 expr
->expr
= mputstr(expr
->expr
, ", ");
11993 v2
->generate_code_expr_mandatory(expr
);
11994 expr
->expr
= mputstr(expr
->expr
, ", ");
11995 v3
->generate_code_expr_mandatory(expr
);
11996 expr
->expr
= mputc(expr
->expr
, ')');
11999 void Value::generate_code_expr_substr(expression_struct
*expr
)
12002 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12003 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12004 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12005 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "substr(");
12006 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12007 else u
.expr
.ti1
->generate_code(expr
);
12008 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12009 else expr
->expr
= mputstr(expr
->expr
, ".substr(");
12010 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12011 expr
->expr
= mputstr(expr
->expr
, "(int)");
12012 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12013 expr
->expr
= mputstr(expr
->expr
, ", ");
12014 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12015 expr
->expr
= mputstr(expr
->expr
, "(int)");
12016 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12017 expr
->expr
= mputc(expr
->expr
, ')');
12020 void Value::generate_code_expr_substr_replace_compat(expression_struct
*expr
)
12022 expression_struct expr_tmp
;
12023 Code::init_expr(&expr_tmp
);
12024 Type
*t1
= u
.expr
.ti1
->get_expr_governor(Type::EXPECTED_TEMPLATE
)
12025 ->get_type_refd_last();
12026 if (!t1
|| t1
== my_governor
->get_type_refd_last())
12027 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12028 if (u
.expr
.v_optype
== OPTYPE_SUBSTR
) {
12029 generate_code_expr_substr(&expr_tmp
);
12030 } else if (u
.expr
.v_optype
== OPTYPE_REPLACE
) {
12031 generate_code_expr_replace(&expr_tmp
);
12033 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12035 // Two temporaries to store the result of substr() or replace() and to
12036 // store the converted value.
12037 const string
& tmp_id1
= get_temporary_id();
12038 const char *tmp_id_str1
= tmp_id1
.c_str();
12039 const string
& tmp_id2
= get_temporary_id();
12040 const char *tmp_id_str2
= tmp_id2
.c_str();
12041 if (expr_tmp
.preamble
)
12042 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.preamble
);
12043 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n%s %s = %s;\n",
12044 my_governor
->get_genname_value(my_scope
).c_str(), tmp_id_str1
,
12045 t1
->get_genname_value(my_scope
).c_str(), tmp_id_str2
, expr_tmp
.expr
);
12046 if (expr_tmp
.postamble
)
12047 expr
->preamble
= mputstr(expr
->preamble
, expr_tmp
.postamble
);
12048 Code::free_expr(&expr_tmp
);
12049 expr
->preamble
= mputprintf(expr
->preamble
,
12050 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12051 "`%s' are not compatible at run-time\");\n",
12052 TypeConv::get_conv_func(t1
, my_governor
->get_type_refd_last(),
12053 my_scope
->get_scope_mod()).c_str(), tmp_id_str1
, tmp_id_str2
,
12054 my_governor
->get_typename().c_str(), t1
->get_typename().c_str());
12055 expr
->expr
= mputprintf(expr
->expr
, "%s", tmp_id_str1
);
12058 void Value::generate_code_expr_regexp(expression_struct
*expr
)
12060 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12061 Value
* v2
= u
.expr
.t2
->get_specific_value();
12062 expr
->expr
= mputstr(expr
->expr
, "regexp(");
12063 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12064 else u
.expr
.ti1
->generate_code(expr
);
12065 expr
->expr
= mputstr(expr
->expr
, ", ");
12066 if (v2
) v2
->generate_code_expr_mandatory(expr
);
12067 else u
.expr
.t2
->generate_code(expr
);
12068 expr
->expr
= mputstr(expr
->expr
, ", ");
12069 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12070 expr
->expr
= mputc(expr
->expr
, ')');
12073 void Value::generate_code_expr_replace(expression_struct
*expr
)
12075 Value
* v1
= u
.expr
.ti1
->get_specific_value();
12076 Value
* v4
= u
.expr
.ti4
->get_specific_value();
12078 if (v1
) par1_is_str
= v1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12079 else par1_is_str
= u
.expr
.ti1
->is_string_type(Type::EXPECTED_TEMPLATE
);
12080 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, "replace(");
12081 if (v1
) v1
->generate_code_expr_mandatory(expr
);
12082 else u
.expr
.ti1
->generate_code(expr
);
12083 if (par1_is_str
) expr
->expr
= mputstr(expr
->expr
, ", ");
12084 else expr
->expr
= mputstr(expr
->expr
, ".replace(");
12085 if (!par1_is_str
&& u
.expr
.v2
->is_unfoldable())
12086 expr
->expr
= mputstr(expr
->expr
, "(int)");
12087 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12088 expr
->expr
= mputstr(expr
->expr
, ", ");
12089 if (!par1_is_str
&& u
.expr
.v3
->is_unfoldable())
12090 expr
->expr
= mputstr(expr
->expr
, "(int)");
12091 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12092 expr
->expr
= mputstr(expr
->expr
, ", ");
12094 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12095 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12096 Value
* v4_last
= v4
->get_value_refd_last();
12097 if ((v4_last
->valuetype
== V_SEQOF
|| v4_last
->valuetype
== V_SETOF
)
12098 && !v4_last
->u
.val_vs
->is_indexed() && v4_last
->u
.val_vs
->get_nof_vs() == 0) {
12099 expr
->expr
= mputprintf(expr
->expr
, "(%s)", v4
->my_governor
->get_genname_value(my_scope
).c_str());
12101 v4
->generate_code_expr_mandatory(expr
);
12103 else u
.expr
.ti4
->generate_code(expr
);
12104 expr
->expr
= mputc(expr
->expr
, ')');
12107 void Value::generate_code_expr_rnd(expression_struct
*expr
,
12110 if(!v1
) // simple random generation
12111 expr
->expr
= mputstr(expr
->expr
, "rnd()");
12112 else { // random generation with seeding
12113 expr
->expr
= mputstr(expr
->expr
, "rnd(");
12114 v1
->generate_code_expr_mandatory(expr
);
12115 expr
->expr
= mputc(expr
->expr
, ')');
12119 void Value::generate_code_expr_create(expression_struct
*expr
,
12120 Ttcn::Ref_base
*type
, Value
*name
, Value
*location
, bool alive
)
12122 expr
->expr
= mputstr(expr
->expr
, "TTCN_Runtime::create_component(");
12123 // first two arguments: component type
12124 Assignment
*t_ass
= type
->get_refd_assignment();
12125 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_TYPE
)
12126 FATAL_ERROR("Value::generate_code_expr_create()");
12127 Type
*comptype
= t_ass
->get_Type()->get_field_type(type
->get_subrefs(),
12128 Type::EXPECTED_DYNAMIC_VALUE
);
12129 if (!comptype
) FATAL_ERROR("Value::generate_code_expr_create()");
12130 comptype
= comptype
->get_type_refd_last();
12131 expr
->expr
= comptype
->get_CompBody()
12132 ->generate_code_comptype_name(expr
->expr
);
12133 expr
->expr
= mputstr(expr
->expr
, ", ");
12134 // third argument: component name
12136 Value
*t_val
= name
->get_value_refd_last();
12137 if (t_val
->valuetype
== V_CSTR
) {
12138 // the argument is foldable to a string literal
12139 size_t str_len
= t_val
->u
.str
.val_str
->size();
12140 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12141 expr
->expr
= mputc(expr
->expr
, '"');
12142 for (size_t i
= 0; i
< str_len
; i
++)
12143 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12144 expr
->expr
= mputc(expr
->expr
, '"');
12145 } else name
->generate_code_expr_mandatory(expr
);
12146 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12147 expr
->expr
= mputstr(expr
->expr
, ", ");
12148 // fourth argument: location
12150 Value
*t_val
= location
->get_value_refd_last();
12151 if (t_val
->valuetype
== V_CSTR
) {
12152 // the argument is foldable to a string literal
12153 size_t str_len
= t_val
->u
.str
.val_str
->size();
12154 const char *str_ptr
= t_val
->u
.str
.val_str
->c_str();
12155 expr
->expr
= mputc(expr
->expr
, '"');
12156 for (size_t i
= 0; i
< str_len
; i
++)
12157 expr
->expr
= Code::translate_character(expr
->expr
, str_ptr
[i
], true);
12158 expr
->expr
= mputc(expr
->expr
, '"');
12159 } else location
->generate_code_expr_mandatory(expr
);
12160 } else expr
->expr
= mputstr(expr
->expr
, "NULL");
12161 // fifth argument: alive flag
12162 expr
->expr
= mputprintf(expr
->expr
, ", %s)", alive
? "TRUE" : "FALSE");
12165 void Value::generate_code_expr_activate(expression_struct
*expr
)
12167 Assignment
*t_ass
= u
.expr
.r1
->get_refd_assignment();
12168 if (!t_ass
|| t_ass
->get_asstype() != Assignment::A_ALTSTEP
)
12169 FATAL_ERROR("Value::generate_code_expr_activate()");
12170 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12171 t_ass
->get_genname_from_scope(my_scope
, "activate_").c_str());
12172 u
.expr
.r1
->get_parlist()->generate_code_noalias(expr
, t_ass
->get_FormalParList());
12173 expr
->expr
= mputc(expr
->expr
, ')');
12176 void Value::generate_code_expr_activate_refd(expression_struct
*expr
)
12178 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12179 if (v_last
->valuetype
== V_ALTSTEP
) {
12180 // the referred altstep is known
12181 expr
->expr
= mputprintf(expr
->expr
, "%s(", v_last
->get_refd_fat()
12182 ->get_genname_from_scope(my_scope
, "activate_").c_str());
12184 // the referred altstep is unknown
12185 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12186 expr
->expr
= mputstr(expr
->expr
,".activate(");
12188 u
.expr
.ap_list2
->generate_code_noalias(expr
, NULL
);
12189 expr
->expr
= mputc(expr
->expr
, ')');
12192 void Value::generate_code_expr_execute(expression_struct
*expr
)
12194 Assignment
*testcase
= u
.expr
.r1
->get_refd_assignment();
12195 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12196 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12197 Ttcn::ActualParList
*parlist
= u
.expr
.r1
->get_parlist();
12198 if (parlist
->get_nof_pars() > 0) {
12199 parlist
->generate_code_alias(expr
, testcase
->get_FormalParList(),
12201 expr
->expr
= mputstr(expr
->expr
, ", ");
12204 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12205 u
.expr
.v2
->generate_code_expr_mandatory(expr
);
12206 expr
->expr
= mputc(expr
->expr
, ')');
12207 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12210 void Value::generate_code_expr_execute_refd(expression_struct
*expr
)
12212 Value
*v_last
= u
.expr
.v1
->get_value_refd_last();
12213 if (v_last
->valuetype
== V_TESTCASE
) {
12214 // the referred testcase is known
12215 Assignment
*testcase
= v_last
->get_refd_fat();
12216 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12217 testcase
->get_genname_from_scope(my_scope
, "testcase_").c_str());
12218 u
.expr
.ap_list2
->generate_code_alias(expr
,
12219 testcase
->get_FormalParList(), 0, false);
12221 // the referred testcase is unknown
12222 u
.expr
.v1
->generate_code_expr_mandatory(expr
);
12223 expr
->expr
= mputstr(expr
->expr
,".execute(");
12224 u
.expr
.ap_list2
->generate_code_alias(expr
, 0, 0, false);
12226 if (u
.expr
.ap_list2
->get_nof_pars() > 0)
12227 expr
->expr
= mputstr(expr
->expr
, ", ");
12229 expr
->expr
= mputstr(expr
->expr
, "TRUE, ");
12230 u
.expr
.v3
->generate_code_expr_mandatory(expr
);
12231 expr
->expr
= mputc(expr
->expr
, ')');
12232 } else expr
->expr
= mputstr(expr
->expr
, "FALSE, 0.0)");
12235 void Value::generate_code_expr_invoke(expression_struct
*expr
)
12237 Value
*last_v
= u
.invoke
.v
->get_value_refd_last();
12238 if (last_v
->get_valuetype() == V_FUNCTION
) {
12239 // the referred function is known
12240 Assignment
*function
= last_v
->get_refd_fat();
12241 expr
->expr
= mputprintf(expr
->expr
, "%s(",
12242 function
->get_genname_from_scope(my_scope
).c_str());
12243 u
.invoke
.ap_list
->generate_code_alias(expr
,
12244 function
->get_FormalParList(), function
->get_RunsOnType(), false);
12246 // the referred function is unknown
12247 u
.invoke
.v
->generate_code_expr_mandatory(expr
);
12248 expr
->expr
= mputstr(expr
->expr
, ".invoke(");
12249 Type
* gov_last
= last_v
->get_expr_governor_last();
12250 u
.invoke
.ap_list
->generate_code_alias(expr
, 0,
12251 gov_last
->get_fat_runs_on_type(), gov_last
->get_fat_runs_on_self());
12253 expr
->expr
= mputc(expr
->expr
, ')');
12256 void Value::generate_code_expr_optional_field_ref(expression_struct
*expr
,
12259 // if the referenced value points to an optional value field the
12260 // generated code has to be corrected at the end:
12261 // `fieldid()' => `fieldid()()'
12262 Assignment
*ass
= ref
->get_refd_assignment();
12263 if (!ass
) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12264 switch (ass
->get_asstype()) {
12265 case Assignment::A_CONST
:
12266 case Assignment::A_EXT_CONST
:
12267 case Assignment::A_MODULEPAR
:
12268 case Assignment::A_VAR
:
12269 case Assignment::A_FUNCTION_RVAL
:
12270 case Assignment::A_EXT_FUNCTION_RVAL
:
12271 case Assignment::A_PAR_VAL_IN
:
12272 case Assignment::A_PAR_VAL_OUT
:
12273 case Assignment::A_PAR_VAL_INOUT
:
12274 // only these are mapped to value objects
12275 if (ass
->get_Type()->field_is_optional(ref
->get_subrefs()))
12276 expr
->expr
= mputstr(expr
->expr
, "()");
12283 void Value::generate_code_expr_encode(expression_struct
*expr
)
12287 Template
* templ
= u
.expr
.ti1
->get_Template()->get_template_refd_last();
12288 if (templ
->get_templatetype() == Template::SPECIFIC_VALUE
)
12289 v1
= templ
->get_specific_value();
12290 Type
* gov_last
= templ
->get_my_governor()->get_type_refd_last();
12292 expression_struct expr2
;
12293 Code::init_expr(&expr2
);
12295 bool is_templ
= false;
12296 switch (templ
->get_templatetype()) {
12297 case Template::SPECIFIC_VALUE
:
12298 v1
->generate_code_expr_mandatory(&expr2
);
12301 u
.expr
.ti1
->generate_code(&expr2
);
12306 if (!gov_last
->is_coding_by_function()) {
12307 const string
& tmp_id
= get_temporary_id();
12308 const string
& tmp_buf_id
= get_temporary_id();
12309 const string
& tmp_ref_id
= get_temporary_id();
12310 expr
->preamble
= mputprintf(expr
->preamble
, "OCTETSTRING %s;\n",
12312 expr
->preamble
= mputprintf(expr
->preamble
, "TTCN_Buffer %s;\n",
12313 tmp_buf_id
.c_str());
12314 if (expr2
.preamble
) { // copy preamble setting up the argument, if any
12315 expr
->preamble
= mputstr(expr
->preamble
, expr2
.preamble
);
12316 expr
->preamble
= mputc (expr
->preamble
, '\n');
12318 expr
->preamble
= mputprintf(expr
->preamble
, "%s const& %s = %s",
12319 gov_last
->get_genname_typedescriptor(
12320 u
.expr
.ti1
->get_Template()->get_my_scope()
12322 tmp_ref_id
.c_str(),
12324 if (is_templ
) // make a value out of the template, if needed
12325 expr
->preamble
= mputprintf(expr
->preamble
, ".valueof()");
12326 expr
->preamble
= mputprintf(expr
->preamble
,
12327 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12328 tmp_ref_id
.c_str(),
12329 gov_last
->get_genname_typedescriptor(
12330 u
.expr
.ti1
->get_Template()->get_my_scope()
12332 tmp_buf_id
.c_str(),
12333 gov_last
->get_coding(true).c_str()
12335 expr
->preamble
= mputstr(expr
->preamble
, ");\n");
12336 expr
->preamble
= mputprintf(expr
->preamble
, "%s.get_string(%s);\n",
12337 tmp_buf_id
.c_str(),
12340 expr
->expr
= mputprintf(expr
->expr
, "oct2bit(%s)", tmp_id
.c_str());
12341 if (expr2
.postamble
)
12342 expr
->postamble
= mputstr(expr
->postamble
, expr2
.postamble
);
12344 expr
->expr
= mputprintf(expr
->expr
, "%s(%s%s)",
12345 gov_last
->get_coding(true).c_str(), expr2
.expr
,
12346 is_templ
? ".valueof()" : "");
12347 Code::free_expr(&expr2
);
12350 void Value::generate_code_expr_decode(expression_struct
*expr
)
12352 expression_struct expr1
, expr2
;
12353 Code::init_expr(&expr1
);
12354 Code::init_expr(&expr2
);
12355 u
.expr
.r1
->generate_code(&expr1
);
12356 u
.expr
.r2
->generate_code(&expr2
);
12358 Type
* _type
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12359 get_field_type(u
.expr
.r2
->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE
)->
12360 get_type_refd_last();
12362 if (expr1
.preamble
)
12363 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr1
.preamble
);
12364 if (expr2
.preamble
)
12365 expr
->preamble
= mputprintf(expr
->preamble
, "%s", expr2
.preamble
);
12367 if (!_type
->is_coding_by_function()) {
12368 const string
& tmp_id
= get_temporary_id();
12369 const string
& buffer_id
= get_temporary_id();
12370 const string
& retval_id
= get_temporary_id();
12371 const bool optional
= u
.expr
.r2
->get_refd_assignment()->get_Type()->
12372 field_is_optional(u
.expr
.r2
->get_subrefs());
12374 expr
->preamble
= mputprintf(expr
->preamble
,
12375 "TTCN_Buffer %s(bit2oct(%s));\n"
12377 "TTCN_EncDec::set_error_behavior("
12378 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12379 "TTCN_EncDec::clear_error();\n",
12384 expr
->preamble
= mputprintf(expr
->preamble
,
12385 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12387 optional
? "()" : "",
12388 _type
->get_genname_typedescriptor(
12389 u
.expr
.r2
->get_my_scope()
12392 _type
->get_coding(false).c_str()
12394 expr
->preamble
= mputprintf(expr
->preamble
,
12395 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12396 "case TTCN_EncDec::ET_NONE: {\n"
12398 "OCTETSTRING %s;\n"
12399 "%s.get_string(%s);\n"
12400 "%s = oct2bit(%s);\n"
12403 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12404 "case TTCN_EncDec::ET_LEN_ERR:\n"
12410 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12411 "TTCN_EncDec::EB_DEFAULT);\n"
12412 "TTCN_EncDec::clear_error();\n",
12423 expr
->expr
= mputprintf(expr
->expr
, "%s", retval_id
.c_str());
12425 expr
->expr
= mputprintf(expr
->expr
, "%s(%s, %s)",
12426 _type
->get_coding(false).c_str(), expr1
.expr
, expr2
.expr
);
12427 if (expr1
.postamble
)
12428 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr1
.postamble
);
12429 if (expr2
.postamble
)
12430 expr
->postamble
= mputprintf(expr
->postamble
, "%s", expr2
.postamble
);
12431 Code::free_expr(&expr1
);
12432 Code::free_expr(&expr2
);
12435 char *Value::generate_code_init_choice(char *str
, const char *name
)
12437 const char *alt_name
= u
.choice
.alt_name
->get_name().c_str();
12438 // Safe as long as get_name() returns a const string&, not a temporary.
12439 const char *alt_prefix
=
12440 (my_governor
->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE
)
12442 if (u
.choice
.alt_value
->needs_temp_ref()) {
12443 const string
& tmp_id
= get_temporary_id();
12444 const char *tmp_id_str
= tmp_id
.c_str();
12445 str
= mputprintf(str
, "{\n"
12446 "%s& %s = %s.%s%s();\n", my_governor
->get_comp_byName(*u
.choice
.alt_name
)
12447 ->get_type()->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12448 alt_prefix
, alt_name
);
12449 str
= u
.choice
.alt_value
->generate_code_init(str
, tmp_id_str
);
12450 str
= mputstr(str
, "}\n");
12452 char *embedded_name
= mprintf("%s.%s%s()", name
, alt_prefix
, alt_name
);
12453 str
= u
.choice
.alt_value
->generate_code_init(str
, embedded_name
);
12454 Free(embedded_name
);
12459 char *Value::generate_code_init_seof(char *str
, const char *name
)
12461 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12463 str
= mputprintf(str
, "%s.set_size(%lu);\n", name
, (unsigned long)nof_vs
);
12464 const string
& embedded_type
=
12465 my_governor
->get_ofType()->get_genname_value(my_scope
);
12466 const char *embedded_type_str
= embedded_type
.c_str();
12467 for (size_t i
= 0; i
< nof_vs
; i
++) {
12468 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12470 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12471 else if (comp_v
->needs_temp_ref()) {
12472 const string
& tmp_id
= get_temporary_id();
12473 const char *tmp_id_str
= tmp_id
.c_str();
12474 str
= mputprintf(str
, "{\n"
12475 "%s& %s = %s[%lu];\n", embedded_type_str
, tmp_id_str
, name
,
12476 (unsigned long) i
);
12477 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12478 str
= mputstr(str
, "}\n");
12480 char *embedded_name
= mprintf("%s[%lu]", name
, (unsigned long) i
);
12481 str
= comp_v
->generate_code_init(str
, embedded_name
);
12482 Free(embedded_name
);
12486 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12491 char *Value::generate_code_init_indexed(char *str
, const char *name
)
12493 size_t nof_ivs
= u
.val_vs
->get_nof_ivs();
12495 // Previous values can be truncated. The concept is similar to
12497 Type
*t_last
= my_governor
->get_type_refd_last();
12498 const string
& oftype_name
=
12499 t_last
->get_ofType()->get_genname_value(my_scope
);
12500 const char *oftype_name_str
= oftype_name
.c_str();
12501 for (size_t i
= 0; i
< nof_ivs
; i
++) {
12502 IndexedValue
*iv
= u
.val_vs
->get_iv_byIndex(i
);
12503 const string
& tmp_id_1
= get_temporary_id();
12504 str
= mputstr(str
, "{\n");
12505 Value
*index
= iv
->get_index();
12506 if (index
->get_valuetype() != V_INT
) {
12507 const string
& tmp_id_2
= get_temporary_id();
12508 str
= mputprintf(str
, "int %s;\n", tmp_id_2
.c_str());
12509 str
= index
->generate_code_init(str
, tmp_id_2
.c_str());
12510 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12511 tmp_id_1
.c_str(), name
, tmp_id_2
.c_str());
12513 str
= mputprintf(str
, "%s& %s = %s[%s];\n", oftype_name_str
,
12514 tmp_id_1
.c_str(), name
,
12515 (index
->get_val_Int()->t_str()).c_str());
12517 str
= iv
->get_value()->generate_code_init(str
, tmp_id_1
.c_str());
12518 str
= mputstr(str
, "}\n");
12520 } else { str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
); }
12524 char *Value::generate_code_init_array(char *str
, const char *name
)
12526 size_t nof_vs
= u
.val_vs
->get_nof_vs();
12527 Type
*t_last
= my_governor
->get_type_refd_last();
12528 Int index_offset
= t_last
->get_dimension()->get_offset();
12529 const string
& embedded_type
=
12530 t_last
->get_ofType()->get_genname_value(my_scope
);
12531 const char *embedded_type_str
= embedded_type
.c_str();
12532 for (size_t i
= 0; i
< nof_vs
; i
++) {
12533 Value
*comp_v
= u
.val_vs
->get_v_byIndex(i
);
12534 if (comp_v
->valuetype
== V_NOTUSED
) continue;
12535 else if (comp_v
->needs_temp_ref()) {
12536 const string
& tmp_id
= get_temporary_id();
12537 const char *tmp_id_str
= tmp_id
.c_str();
12538 str
= mputprintf(str
, "{\n"
12539 "%s& %s = %s[%s];\n", embedded_type_str
, tmp_id_str
, name
,
12540 Int2string(index_offset
+ i
).c_str());
12541 str
= comp_v
->generate_code_init(str
, tmp_id_str
);
12542 str
= mputstr(str
, "}\n");
12544 char *embedded_name
= mprintf("%s[%s]", name
,
12545 Int2string(index_offset
+ i
).c_str());
12546 str
= comp_v
->generate_code_init(str
, embedded_name
);
12547 Free(embedded_name
);
12553 char *Value::generate_code_init_se(char *str
, const char *name
)
12555 Type
*type
= my_governor
->get_type_refd_last();
12556 size_t nof_comps
= type
->get_nof_comps();
12557 if (nof_comps
> 0) {
12558 for (size_t i
= 0; i
< nof_comps
; i
++) {
12559 CompField
*cf
= type
->get_comp_byIndex(i
);
12560 const Identifier
& field_id
= cf
->get_name();
12561 const char *field_name
= field_id
.get_name().c_str();
12563 if (u
.val_nvs
->has_nv_withName(field_id
)) {
12564 field_v
= u
.val_nvs
->get_nv_byName(field_id
)->get_value();
12565 if (field_v
->valuetype
== V_NOTUSED
) continue;
12566 if (field_v
->valuetype
== V_OMIT
) field_v
= 0;
12567 } else if (is_asn1()) {
12568 if (cf
->has_default()) {
12569 // handle like a referenced value
12570 Value
*defval
= cf
->get_defval();
12571 if (needs_init_precede(defval
)) {
12572 str
= defval
->generate_code_init(str
,
12573 defval
->get_lhs_name().c_str());
12575 str
= mputprintf(str
, "%s.%s() = %s;\n", name
, field_name
,
12576 defval
->get_genname_own(my_scope
).c_str());
12579 if (!cf
->get_is_optional())
12580 FATAL_ERROR("Value::generate_code_init()");
12587 // the value is not omit
12588 if (field_v
->needs_temp_ref()) {
12589 const string
& tmp_id
= get_temporary_id();
12590 const char *tmp_id_str
= tmp_id
.c_str();
12591 str
= mputprintf(str
, "{\n"
12592 "%s& %s = %s.%s();\n", type
->get_comp_byName(field_id
)->get_type()
12593 ->get_genname_value(my_scope
).c_str(), tmp_id_str
, name
,
12595 str
= field_v
->generate_code_init(str
, tmp_id_str
);
12596 str
= mputstr(str
, "}\n");
12598 char *embedded_name
= mprintf("%s.%s()", name
,
12600 if (cf
->get_is_optional() && field_v
->is_compound())
12601 embedded_name
= mputstr(embedded_name
, "()");
12602 str
= field_v
->generate_code_init(str
, embedded_name
);
12603 Free(embedded_name
);
12606 // the value is omit
12607 str
= mputprintf(str
, "%s.%s() = OMIT_VALUE;\n",
12612 str
= mputprintf(str
, "%s = NULL_VALUE;\n", name
);
12617 char *Value::generate_code_init_refd(char *str
, const char *name
)
12619 Value
*v
= get_value_refd_last();
12621 // the referred value is not available at compile time
12622 // the code generation is based on the reference
12623 if (use_runtime_2
&& TypeConv::needs_conv_refd(v
)) {
12624 str
= TypeConv::gen_conv_code_refd(str
, name
, v
);
12626 expression_struct expr
;
12627 Code::init_expr(&expr
);
12628 expr
.expr
= mputprintf(expr
.expr
, "%s = ", name
);
12629 u
.ref
.ref
->generate_code_const_ref(&expr
);
12630 str
= Code::merge_free_expr(str
, &expr
);
12633 // the referred value is available at compile time
12634 // the code generation is based on the referred value
12635 if (v
->has_single_expr() &&
12636 my_scope
->get_scope_mod_gen() == v
->my_scope
->get_scope_mod_gen()) {
12637 // simple substitution for in-line values within the same module
12638 str
= mputprintf(str
, "%s = %s;\n", name
,
12639 v
->get_single_expr().c_str());
12641 // use a simple reference to reduce code size
12642 if (needs_init_precede(v
)) {
12643 // the referred value must be initialized first
12644 if (!v
->is_toplevel() && v
->needs_temp_ref()) {
12645 // temporary id should be introduced for the lhs
12646 const string
& tmp_id
= get_temporary_id();
12647 const char *tmp_id_str
= tmp_id
.c_str();
12648 str
= mputprintf(str
, "{\n"
12650 v
->get_my_governor()->get_genname_value(my_scope
).c_str(),
12651 tmp_id_str
, v
->get_lhs_name().c_str());
12652 str
= v
->generate_code_init(str
, tmp_id_str
);
12653 str
= mputstr(str
, "}\n");
12655 str
= v
->generate_code_init(str
, v
->get_lhs_name().c_str());
12658 str
= mputprintf(str
, "%s = %s;\n", name
,
12659 v
->get_genname_own(my_scope
).c_str());
12665 void Value::generate_json_value(JSON_Tokenizer
& json
,
12666 bool allow_special_float
, /* = true */
12667 bool union_value_list
, /* = false */
12668 Ttcn::JsonOmitCombination
* omit_combo
/* = NULL */)
12670 switch (valuetype
) {
12672 json
.put_next_token(JSON_TOKEN_NUMBER
, get_val_Int()->t_str().c_str());
12675 Real r
= get_val_Real();
12676 if (r
== REAL_INFINITY
) {
12677 if (allow_special_float
) {
12678 json
.put_next_token(JSON_TOKEN_STRING
, "\"infinity\"");
12681 else if (r
== -REAL_INFINITY
) {
12682 if (allow_special_float
) {
12683 json
.put_next_token(JSON_TOKEN_STRING
, "\"-infinity\"");
12687 if (allow_special_float
) {
12688 json
.put_next_token(JSON_TOKEN_STRING
, "\"not_a_number\"");
12692 // true if decimal representation possible (use %f format)
12693 bool decimal_repr
= (r
== 0.0)
12694 || (r
> -MAX_DECIMAL_FLOAT
&& r
<= -MIN_DECIMAL_FLOAT
)
12695 || (r
>= MIN_DECIMAL_FLOAT
&& r
< MAX_DECIMAL_FLOAT
);
12696 char* number_str
= mprintf(decimal_repr
? "%f" : "%e", r
);
12697 json
.put_next_token(JSON_TOKEN_NUMBER
, number_str
);
12702 json
.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE
: JSON_TOKEN_LITERAL_FALSE
);
12708 char* str
= convert_to_json_string(get_val_str().c_str());
12709 json
.put_next_token(JSON_TOKEN_STRING
, str
);
12713 char* str
= convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
12714 json
.put_next_token(JSON_TOKEN_STRING
, str
);
12719 json
.put_next_token(JSON_TOKEN_STRING
,
12720 (string('\"') + create_stringRepr() + string('\"')).c_str());
12724 json
.put_next_token(JSON_TOKEN_ARRAY_START
);
12725 if (!u
.val_vs
->is_indexed()) {
12726 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); ++i
) {
12727 u
.val_vs
->get_v_byIndex(i
)->generate_json_value(json
, allow_special_float
,
12728 union_value_list
, omit_combo
);
12732 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); ++i
) {
12733 // look for the entry with index equal to i
12734 for (size_t j
= 0; j
< u
.val_vs
->get_nof_ivs(); ++j
) {
12735 if (u
.val_vs
->get_iv_byIndex(j
)->get_index()->get_val_Int()->get_val() == (Int
)i
) {
12736 u
.val_vs
->get_iv_byIndex(j
)->get_value()->generate_json_value(json
,
12737 allow_special_float
, union_value_list
, omit_combo
);
12743 json
.put_next_token(JSON_TOKEN_ARRAY_END
);
12747 // omitted fields have 2 possible JSON values (the field is absent, or it's
12748 // present with value 'null'), each combination of omitted values must be
12750 if (omit_combo
== NULL
) {
12751 FATAL_ERROR("Value::generate_json_value - no combo");
12753 size_t len
= get_nof_comps();
12754 // generate the JSON object from the present combination
12755 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
12756 for (size_t i
= 0; i
< len
; ++i
) {
12757 Ttcn::JsonOmitCombination::omit_state_t state
= omit_combo
->get_state(this, i
);
12758 if (state
== Ttcn::JsonOmitCombination::OMITTED_ABSENT
) {
12759 // the field is absent, don't insert anything
12762 // use the field's alias, if it has one
12763 const char* alias
= NULL
;
12764 if (my_governor
!= NULL
) {
12765 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
12766 get_se_comp_byIndex(i
)->get_name())->get_type()->get_json_attributes();
12767 if (field_attrib
!= NULL
) {
12768 alias
= field_attrib
->alias
;
12771 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
12772 get_se_comp_byIndex(i
)->get_name().get_ttcnname().c_str());
12773 if (state
== Ttcn::JsonOmitCombination::OMITTED_NULL
) {
12774 json
.put_next_token(JSON_TOKEN_LITERAL_NULL
);
12777 get_se_comp_byIndex(i
)->get_value()->generate_json_value(json
,
12778 allow_special_float
, union_value_list
, omit_combo
);
12781 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
12784 bool as_value
= !union_value_list
&& my_governor
!= NULL
&&
12785 my_governor
->get_type_refd_last()->get_json_attributes() != NULL
&&
12786 my_governor
->get_type_refd_last()->get_json_attributes()->as_value
;
12788 // no 'as value' coding instruction, insert an object with one field
12789 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
12790 // use the field's alias, if it has one
12791 const char* alias
= NULL
;
12792 if (my_governor
!= NULL
) {
12793 JsonAST
* field_attrib
= my_governor
->get_comp_byName(
12794 get_alt_name())->get_type()->get_json_attributes();
12795 if (field_attrib
!= NULL
) {
12796 alias
= field_attrib
->alias
;
12799 json
.put_next_token(JSON_TOKEN_NAME
, (alias
!= NULL
) ? alias
:
12800 get_alt_name().get_ttcnname().c_str());
12802 get_alt_value()->generate_json_value(json
, allow_special_float
,
12803 union_value_list
, omit_combo
);
12805 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
12809 Value
* v
= get_value_refd_last();
12811 v
->generate_json_value(json
, allow_special_float
, union_value_list
, omit_combo
);
12816 FATAL_ERROR("Value::generate_json_value - %d", valuetype
);
12820 bool Value::explicit_cast_needed(bool forIsValue
)
12822 Value
*v_last
= get_value_refd_last();
12823 if (v_last
!= this) {
12824 // this is a foldable referenced value
12825 // if the reference points to an imported or compound value the code
12826 // generation will be based on the reference so cast is not needed
12827 if (v_last
->my_scope
->get_scope_mod_gen() != my_scope
->get_scope_mod_gen()
12828 || !v_last
->has_single_expr()) return false;
12829 } else if (v_last
->valuetype
== V_REFD
) {
12830 // this is an unfoldable reference (v_last==this)
12831 // explicit cast is needed only for string element references
12832 if (forIsValue
) return false;
12833 Ttcn::FieldOrArrayRefs
*t_subrefs
= v_last
->u
.ref
.ref
->get_subrefs();
12834 return t_subrefs
&& t_subrefs
->refers_to_string_element();
12836 if (!v_last
->my_governor
) FATAL_ERROR("Value::explicit_cast_needed()");
12837 Type
*t_governor
= v_last
->my_governor
->get_type_refd_last();
12838 switch (t_governor
->get_typetype()) {
12842 case Type::T_INT_A
:
12844 case Type::T_ENUM_A
:
12845 case Type::T_ENUM_T
:
12846 case Type::T_VERDICT
:
12847 case Type::T_COMPONENT
:
12848 // these are mapped to built-in C/C++ types
12850 case Type::T_SEQ_A
:
12851 case Type::T_SEQ_T
:
12852 case Type::T_SET_A
:
12853 case Type::T_SET_T
:
12854 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12855 return t_governor
->get_nof_comps() == 0;
12856 case Type::T_SEQOF
:
12857 case Type::T_SETOF
:
12858 // the C++ equivalent of value {} is ambiguous
12861 case Type::T_FUNCTION
:
12862 case Type::T_ALTSTEP
:
12863 case Type::T_TESTCASE
:
12870 bool Value::has_single_expr()
12872 if (get_needs_conversion()) return false;
12873 switch (valuetype
) {
12875 return has_single_expr_expr();
12878 // a union or array value cannot be represented as an in-line expression
12882 // only an empty record/set of value can be represented as an in-line
12884 if (!is_indexed()) return u
.val_vs
->get_nof_vs() == 0;
12885 else return u
.val_vs
->get_nof_ivs() == 0;
12888 // only a value for an empty record/set type can be represented as an
12889 // in-line expression
12890 if (!my_governor
) FATAL_ERROR("Value::has_single_expr()");
12891 Type
*type
= my_governor
->get_type_refd_last();
12892 return type
->get_nof_comps() == 0; }
12894 Value
*v_last
= get_value_refd_last();
12895 // If the above call hit an error and set_valuetype(V_ERROR),
12896 // then u.ref.ref has been freed. Avoid the segfault.
12897 if (valuetype
== V_ERROR
)
12899 if (v_last
!= this && v_last
->has_single_expr() &&
12900 v_last
->my_scope
->get_scope_mod_gen() ==
12901 my_scope
->get_scope_mod_gen()) return true;
12902 else return u
.ref
.ref
->has_single_expr(); }
12904 return has_single_expr_invoke(u
.invoke
.v
, u
.invoke
.ap_list
);
12908 case V_UNDEF_LOWERID
:
12909 case V_UNDEF_BLOCK
:
12911 // these values cannot occur during code generation
12912 FATAL_ERROR("Value::has_single_expr()");
12914 return u
.val_Int
->is_native_fit();
12916 // should only happen when generating code for an unbound record/set value
12919 // other value types (literal values) do not need temporary reference
12924 string
Value::get_single_expr()
12926 switch (valuetype
) {
12928 return string("ASN_NULL_VALUE");
12930 return string(u
.val_bool
? "TRUE" : "FALSE");
12932 if (u
.val_Int
->is_native_fit()) { // Be sure.
12933 return u
.val_Int
->t_str();
12935 // get_single_expr may be called only if has_single_expr() is true.
12936 // The only exception is V_INT, where get_single_expr may be called
12937 // even if is_native_fit (which is used to implement has_single_expr)
12939 string
ret_val('"');
12940 ret_val
+= u
.val_Int
->t_str();
12945 return Real2code(u
.val_Real
);
12947 return get_single_expr_enum();
12949 return get_my_scope()->get_scope_mod_gen()
12950 ->add_bitstring_literal(*u
.str
.val_str
);
12952 return get_my_scope()->get_scope_mod_gen()
12953 ->add_hexstring_literal(*u
.str
.val_str
);
12955 return get_my_scope()->get_scope_mod_gen()
12956 ->add_octetstring_literal(*u
.str
.val_str
);
12958 return get_my_scope()->get_scope_mod_gen()
12959 ->add_charstring_literal(*u
.str
.val_str
);
12961 if (u
.ustr
.convert_str
) {
12962 set_valuetype(V_CSTR
);
12963 return get_my_scope()->get_scope_mod_gen()
12964 ->add_charstring_literal(*u
.str
.val_str
);
12966 return get_my_scope()->get_scope_mod_gen()
12967 ->add_ustring_literal(*u
.ustr
.val_ustr
);
12969 return get_single_expr_iso2022str();
12972 vector
<string
> comps
;
12973 bool is_constant
= get_oid_comps(comps
);
12974 size_t nof_comps
= comps
.size();
12976 for (size_t i
= 0; i
< nof_comps
; i
++) {
12977 if (i
> 0) oi_str
+= ", ";
12978 oi_str
+= *(comps
[i
]);
12980 for (size_t i
= 0; i
< nof_comps
; i
++) delete comps
[i
];
12983 // the objid only contains constants
12984 // => create a literal and return its name
12985 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str
, nof_comps
);
12987 // the objid contains at least one variable
12988 // => append the number of components before the component values in the string and return it
12989 return "OBJID(" + Int2string(nof_comps
) + ", " + oi_str
+ ")"; }
12992 if (u
.val_vs
->get_nof_vs() > 0)
12993 FATAL_ERROR("Value::get_single_expr()");
12994 return string("NULL_VALUE");
12997 if (u
.val_nvs
->get_nof_nvs() > 0)
12998 FATAL_ERROR("Value::get_single_expr()");
12999 return string("NULL_VALUE");
13001 Value
*v_last
= get_value_refd_last();
13002 if (v_last
!= this && v_last
->has_single_expr() &&
13003 v_last
->my_scope
->get_scope_mod_gen() ==
13004 my_scope
->get_scope_mod_gen()) {
13005 // the reference points to another single value in the same module
13006 return v_last
->get_single_expr();
13008 // convert the reference to a single expression
13009 expression_struct expr
;
13010 Code::init_expr(&expr
);
13011 u
.ref
.ref
->generate_code_const_ref(&expr
);
13012 if (expr
.preamble
|| expr
.postamble
)
13013 FATAL_ERROR("Value::get_single_expr()");
13014 string
ret_val(expr
.expr
);
13015 Code::free_expr(&expr
);
13019 return string("OMIT_VALUE");
13021 switch (u
.verdict
) {
13023 return string("NONE");
13025 return string("PASS");
13026 case Verdict_INCONC
:
13027 return string("INCONC");
13029 return string("FAIL");
13030 case Verdict_ERROR
:
13031 return string("ERROR");
13033 FATAL_ERROR("Value::get_single_expr()");
13036 case V_DEFAULT_NULL
:
13037 return string("NULL_COMPREF");
13039 string
ret_val('(');
13040 ret_val
+= my_governor
->get_genname_value(my_scope
);
13041 ret_val
+= "::function_pointer)Module_List::get_fat_null()";
13045 expression_struct expr
;
13046 Code::init_expr(&expr
);
13047 if (valuetype
== V_EXPR
) generate_code_expr_expr(&expr
);
13048 else generate_code_expr_invoke(&expr
);
13049 if (expr
.preamble
|| expr
.postamble
)
13050 FATAL_ERROR("Value::get_single_expr()");
13051 string
ret_val(expr
.expr
);
13052 Code::free_expr(&expr
);
13056 case MACRO_TESTCASEID
:
13057 return string("TTCN_Runtime::get_testcase_id_macro()");
13059 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13065 return get_single_expr_fat();
13067 FATAL_ERROR("Value::get_single_expr()");
13072 bool Value::has_single_expr_expr()
13074 switch (u
.expr
.v_optype
) {
13075 case OPTYPE_RND
: // -
13076 case OPTYPE_COMP_NULL
:
13077 case OPTYPE_COMP_MTC
:
13078 case OPTYPE_COMP_SYSTEM
:
13079 case OPTYPE_COMP_SELF
:
13080 case OPTYPE_COMP_RUNNING_ANY
:
13081 case OPTYPE_COMP_RUNNING_ALL
:
13082 case OPTYPE_COMP_ALIVE_ANY
:
13083 case OPTYPE_COMP_ALIVE_ALL
:
13084 case OPTYPE_TMR_RUNNING_ANY
:
13085 case OPTYPE_GETVERDICT
:
13086 case OPTYPE_TESTCASENAME
:
13087 case OPTYPE_PROF_RUNNING
:
13089 case OPTYPE_ENCODE
:
13090 case OPTYPE_DECODE
:
13091 case OPTYPE_ISBOUND
:
13092 case OPTYPE_ISPRESENT
:
13093 case OPTYPE_TTCN2STRING
:
13095 case OPTYPE_UNARYPLUS
: // v1
13096 case OPTYPE_UNARYMINUS
:
13099 case OPTYPE_BIT2HEX
:
13100 case OPTYPE_BIT2INT
:
13101 case OPTYPE_BIT2OCT
:
13102 case OPTYPE_BIT2STR
:
13103 case OPTYPE_CHAR2INT
:
13104 case OPTYPE_CHAR2OCT
:
13105 case OPTYPE_FLOAT2INT
:
13106 case OPTYPE_FLOAT2STR
:
13107 case OPTYPE_HEX2BIT
:
13108 case OPTYPE_HEX2INT
:
13109 case OPTYPE_HEX2OCT
:
13110 case OPTYPE_HEX2STR
:
13111 case OPTYPE_INT2CHAR
:
13112 case OPTYPE_INT2FLOAT
:
13113 case OPTYPE_INT2STR
:
13114 case OPTYPE_INT2UNICHAR
:
13115 case OPTYPE_OCT2BIT
:
13116 case OPTYPE_OCT2CHAR
:
13117 case OPTYPE_OCT2HEX
:
13118 case OPTYPE_OCT2INT
:
13119 case OPTYPE_OCT2STR
:
13120 case OPTYPE_STR2BIT
:
13121 case OPTYPE_STR2FLOAT
:
13122 case OPTYPE_STR2HEX
:
13123 case OPTYPE_STR2INT
:
13124 case OPTYPE_STR2OCT
:
13125 case OPTYPE_UNICHAR2INT
:
13126 case OPTYPE_UNICHAR2CHAR
:
13127 case OPTYPE_ENUM2INT
:
13128 case OPTYPE_RNDWITHVAL
:
13129 case OPTYPE_ISCHOSEN_V
: // v1 i2
13130 case OPTYPE_COMP_RUNNING
:
13131 case OPTYPE_COMP_ALIVE
:
13132 case OPTYPE_GET_STRINGENCODING
:
13133 case OPTYPE_REMOVE_BOM
:
13134 case OPTYPE_DECODE_BASE64
:
13135 return u
.expr
.v1
->has_single_expr();
13136 case OPTYPE_ISCHOSEN_T
: // t1 i2
13137 return u
.expr
.t1
->has_single_expr();
13138 case OPTYPE_ADD
: // v1 v2
13139 case OPTYPE_SUBTRACT
:
13140 case OPTYPE_MULTIPLY
:
13141 case OPTYPE_DIVIDE
:
13144 case OPTYPE_CONCAT
:
13159 case OPTYPE_INT2BIT
:
13160 case OPTYPE_INT2HEX
:
13161 case OPTYPE_INT2OCT
:
13162 return u
.expr
.v1
->has_single_expr() &&
13163 u
.expr
.v2
->has_single_expr();
13164 case OPTYPE_UNICHAR2OCT
:
13165 case OPTYPE_OCT2UNICHAR
:
13166 case OPTYPE_ENCODE_BASE64
:
13167 return u
.expr
.v1
->has_single_expr() &&
13168 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13171 return u
.expr
.v1
->has_single_expr() &&
13172 u
.expr
.v2
->has_single_expr() &&
13173 !u
.expr
.v2
->needs_short_circuit();
13174 case OPTYPE_SUBSTR
:
13175 return u
.expr
.ti1
->has_single_expr() &&
13176 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr();
13177 case OPTYPE_REGEXP
:
13178 return u
.expr
.ti1
->has_single_expr() && u
.expr
.t2
->has_single_expr() &&
13179 u
.expr
.v3
->has_single_expr();
13180 case OPTYPE_DECOMP
: // v1 v2 v3
13181 return u
.expr
.v1
->has_single_expr() &&
13182 u
.expr
.v2
->has_single_expr() &&
13183 u
.expr
.v3
->has_single_expr();
13184 case OPTYPE_REPLACE
:
13185 return u
.expr
.ti1
->has_single_expr() &&
13186 u
.expr
.v2
->has_single_expr() && u
.expr
.v3
->has_single_expr() &&
13187 u
.expr
.ti4
->has_single_expr();
13188 case OPTYPE_ISVALUE
: // ti1
13189 case OPTYPE_LENGTHOF
: // ti1
13190 case OPTYPE_SIZEOF
: // ti1
13191 case OPTYPE_VALUEOF
: // ti1
13192 return u
.expr
.ti1
->has_single_expr();
13193 case OPTYPE_LOG2STR
:
13194 return u
.expr
.logargs
->has_single_expr();
13195 case OPTYPE_MATCH
: // v1 t2
13196 return u
.expr
.v1
->has_single_expr() &&
13197 u
.expr
.t2
->has_single_expr();
13198 case OPTYPE_COMP_CREATE
: // r1 [v2] [v3] b4
13199 return (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr()) &&
13200 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13201 case OPTYPE_TMR_READ
: // r1
13202 case OPTYPE_TMR_RUNNING
:
13203 case OPTYPE_ACTIVATE
:
13204 return u
.expr
.r1
->has_single_expr();
13205 case OPTYPE_EXECUTE
: // r1 [v2]
13206 return u
.expr
.r1
->has_single_expr() &&
13207 (!u
.expr
.v2
|| u
.expr
.v2
->has_single_expr());
13208 case OPTYPE_ACTIVATE_REFD
: // v1 ap_list2
13209 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
);
13210 case OPTYPE_EXECUTE_REFD
: // v1 ap_list2 [v3]
13211 return has_single_expr_invoke(u
.expr
.v1
, u
.expr
.ap_list2
) &&
13212 (!u
.expr
.v3
|| u
.expr
.v3
->has_single_expr());
13214 FATAL_ERROR("Value::has_single_expr_expr()");
13218 bool Value::has_single_expr_invoke(Value
*v
, Ttcn::ActualParList
*ap_list
)
13220 if (!v
->has_single_expr()) return false;
13221 for (size_t i
= 0; i
< ap_list
->get_nof_pars(); i
++)
13222 if (!ap_list
->get_par(i
)->has_single_expr()) return false;
13226 string
Value::get_single_expr_enum()
13228 string
ret_val(my_governor
->get_genname_value(my_scope
));
13230 ret_val
+= u
.val_id
->get_name();
13234 string
Value::get_single_expr_iso2022str()
13237 Type
*type
= get_my_governor()->get_type_refd_last();
13238 switch (type
->get_typetype()) {
13239 case Type::T_TELETEXSTRING
:
13240 ret_val
+= "TTCN_ISO2022_2_TeletexString";
13242 case Type::T_VIDEOTEXSTRING
:
13243 ret_val
+= "TTCN_ISO2022_2_VideotexString";
13245 case Type::T_GRAPHICSTRING
:
13246 case Type::T_OBJECTDESCRIPTOR
:
13247 ret_val
+= "TTCN_ISO2022_2_GraphicString";
13249 case Type::T_GENERALSTRING
:
13250 ret_val
+= "TTCN_ISO2022_2_GeneralString";
13253 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13256 string
*ostr
= char2oct(*u
.str
.val_str
);
13257 ret_val
+= get_my_scope()->get_scope_mod_gen()
13258 ->add_octetstring_literal(*ostr
);
13264 string
Value::get_single_expr_fat()
13266 if (!my_governor
) FATAL_ERROR("Value::get_single_expr_fat()");
13267 // the ampersand operator is not really necessary to obtain the function
13268 // pointer, but some older versions of GCC cannot instantiate the
13269 // appropriate operator=() member of class OPTIONAL when necessary
13270 // if only the function name is given
13271 string
ret_val('&');
13272 switch (valuetype
) {
13274 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13277 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
);
13278 ret_val
+= "_instance";
13281 ret_val
+= u
.refd_fat
->get_genname_from_scope(my_scope
, "testcase_");
13284 FATAL_ERROR("Value::get_single_expr_fat()");
13289 bool Value::is_compound()
13291 switch (valuetype
) {
13304 bool Value::needs_temp_ref()
13306 switch (valuetype
) {
13309 if (!is_indexed()) {
13310 // Temporary reference is needed if the value has at least one real
13311 // element (i.e. it is not empty or contains only not used symbols).
13312 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13313 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) return true;
13316 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13317 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13318 ->valuetype
!= V_NOTUSED
)
13324 size_t nof_real_vs
= 0;
13325 if (!is_indexed()) {
13326 // Temporary reference is needed if the array value has at least two
13327 // real elements (excluding not used symbols).
13328 for (size_t i
= 0; i
< u
.val_vs
->get_nof_vs(); i
++) {
13329 if (u
.val_vs
->get_v_byIndex(i
)->valuetype
!= V_NOTUSED
) {
13331 if (nof_real_vs
> 1) return true;
13335 for (size_t i
= 0; i
< u
.val_vs
->get_nof_ivs(); i
++) {
13336 if (u
.val_vs
->get_iv_byIndex(i
)->get_value()
13337 ->valuetype
!= V_NOTUSED
) {
13339 if (nof_real_vs
> 1) return true;
13347 // it depends on the type since fields with omit or default value
13348 // may not be present
13349 return my_governor
->get_type_refd_last()->get_nof_comps() > 1;
13351 // incomplete values are allowed in TTCN-3
13352 // we should check the number of value components
13353 return u
.val_nvs
->get_nof_nvs() > 1;
13358 case V_UNDEF_LOWERID
:
13359 case V_UNDEF_BLOCK
:
13361 // these values cannot occur during code generation
13362 FATAL_ERROR("Value::needs_temp_ref()");
13364 return !u
.val_Int
->is_native();
13366 // other value types (literal values) do not need temporary reference
13371 bool Value::needs_short_circuit()
13373 switch (valuetype
) {
13381 // sub-expressions should be evaluated only if necessary
13384 FATAL_ERROR("Value::needs_short_circuit()");
13386 Assignment
*t_ass
= u
.ref
.ref
->get_refd_assignment();
13387 if (!t_ass
) FATAL_ERROR("Value::needs_short_circuit()");
13388 switch (t_ass
->get_asstype()) {
13389 case Assignment::A_FUNCTION_RVAL
:
13390 case Assignment::A_EXT_FUNCTION_RVAL
:
13391 // avoid unnecessary call of a function
13393 case Assignment::A_CONST
:
13394 case Assignment::A_EXT_CONST
:
13395 case Assignment::A_MODULEPAR
:
13396 case Assignment::A_VAR
:
13397 case Assignment::A_PAR_VAL_IN
:
13398 case Assignment::A_PAR_VAL_OUT
:
13399 case Assignment::A_PAR_VAL_INOUT
:
13400 // depends on field/array sub-references, which is examined below
13403 FATAL_ERROR("Value::needs_short_circuit()");
13405 Ttcn::FieldOrArrayRefs
*t_subrefs
= u
.ref
.ref
->get_subrefs();
13407 // the evaluation of the reference does not have side effects
13408 // (i.e. false shall be returned) only if all sub-references point to
13409 // mandatory fields of record/set types, and neither sub-reference points
13410 // to a field of a union type
13411 Type
*t_type
= t_ass
->get_Type();
13412 for (size_t i
= 0; i
< t_subrefs
->get_nof_refs(); i
++) {
13413 Ttcn::FieldOrArrayRef
*t_fieldref
= t_subrefs
->get_ref(i
);
13414 if (t_fieldref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
) {
13415 CompField
*t_cf
= t_type
->get_comp_byName(*t_fieldref
->get_id());
13416 if (Type::T_CHOICE_T
== t_type
->get_type_refd_last()->get_typetype() ||
13417 Type::T_CHOICE_A
== t_type
->get_type_refd_last()->get_typetype() ||
13418 t_cf
->get_is_optional()) return true;
13419 t_type
= t_cf
->get_type();
13420 } else return true;
13426 void Value::dump(unsigned level
) const
13428 switch (valuetype
) {
13452 case V_DEFAULT_NULL
:
13460 DEBUG(level
, "Value: %s", const_cast<Value
*>(this)->get_stringRepr().c_str());
13464 DEBUG(level
, "Value: reference");
13465 u
.ref
.ref
->dump(level
+ 1);
13467 case V_UNDEF_LOWERID
:
13468 DEBUG(level
, "Value: identifier: %s", u
.val_id
->get_dispname().c_str());
13470 case V_UNDEF_BLOCK
:
13471 DEBUG(level
, "Value: {block}");
13474 DEBUG(level
, "Value: null");
13477 DEBUG(level
, "Value: invoke");
13478 u
.invoke
.v
->dump(level
+ 1);
13479 if (u
.invoke
.ap_list
) u
.invoke
.ap_list
->dump(level
+ 1);
13480 else if (u
.invoke
.t_list
) u
.invoke
.t_list
->dump(level
+ 1);
13483 DEBUG(level
, "Value: unknown type: %d", valuetype
);
13487 void Value::add_string_element(size_t index
, Value
*v_element
,
13488 map
<size_t, Value
>*& string_elements
)
13490 v_element
->set_my_scope(get_my_scope());
13491 v_element
->set_my_governor(get_my_governor());
13492 v_element
->set_fullname(get_fullname() + "[" + Int2string(index
) + "]");
13493 v_element
->set_location(*this);
13494 if (!string_elements
) string_elements
= new map
<size_t, Value
>;
13495 string_elements
->add(index
, v_element
);
13498 ///////////////////////////////////////////////////////////////////////////////
13499 // class LazyParamData
13501 int LazyParamData::depth
= 0;
13502 bool LazyParamData::used_as_lvalue
= false;
13503 vector
<string
>* LazyParamData::type_vec
= NULL
;
13504 vector
<string
>* LazyParamData::refd_vec
= NULL
;
13506 void LazyParamData::init(bool p_used_as_lvalue
) {
13507 if (depth
<0) FATAL_ERROR("LazyParamData::init()");
13509 if (type_vec
|| refd_vec
) FATAL_ERROR("LazyParamData::init()");
13510 used_as_lvalue
= p_used_as_lvalue
;
13511 type_vec
= new vector
<string
>;
13512 refd_vec
= new vector
<string
>;
13517 void LazyParamData::clean() {
13518 if (depth
<=0) FATAL_ERROR("LazyParamData::clean()");
13519 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::clean()");
13522 for (size_t i
=0; i
<type_vec
->size(); i
++) delete (*type_vec
)[i
];
13527 for (size_t i
=0; i
<refd_vec
->size(); i
++) delete (*refd_vec
)[i
];
13535 bool LazyParamData::in_lazy() {
13536 if (depth
<0) FATAL_ERROR("LazyParamData::in_lazy()");
13540 // returns a temporary id instead of the C++ reference to a definition
13541 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13542 string
LazyParamData::add_ref_genname(Assignment
* ass
, Scope
* scope
) {
13543 if (!ass
|| !scope
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13544 if (!type_vec
|| !refd_vec
) FATAL_ERROR("LazyParamData::add_ref_genname()");
13545 if (type_vec
->size()!=refd_vec
->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13546 // store the type of the assignment
13547 string
* type_str
= new string
;
13548 switch (ass
->get_asstype()) {
13549 case Assignment::A_MODULEPAR_TEMP
:
13550 case Assignment::A_TEMPLATE
:
13551 case Assignment::A_VAR_TEMPLATE
:
13552 case Assignment::A_PAR_TEMPL_IN
:
13553 case Assignment::A_PAR_TEMPL_OUT
:
13554 case Assignment::A_PAR_TEMPL_INOUT
:
13555 *type_str
= ass
->get_Type()->get_genname_template(scope
);
13558 *type_str
= ass
->get_Type()->get_genname_value(scope
);
13560 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13561 bool refd_ass_is_lazy_fpar
= false;
13562 switch (ass
->get_asstype()) {
13563 case Assignment::A_PAR_VAL
:
13564 case Assignment::A_PAR_VAL_IN
:
13565 case Assignment::A_PAR_TEMPL_IN
:
13566 refd_ass_is_lazy_fpar
= ass
->get_lazy_eval();
13567 if (refd_ass_is_lazy_fpar
) {
13568 *type_str
= string("Lazy_Param<") + *type_str
+ string(">");
13574 // add the "const" part if the referenced assignment is a constant thing
13575 if (!refd_ass_is_lazy_fpar
) {
13576 switch (ass
->get_asstype()) {
13577 case Assignment::A_CONST
:
13578 case Assignment::A_OC
:
13579 case Assignment::A_OBJECT
:
13580 case Assignment::A_OS
:
13581 case Assignment::A_VS
:
13582 case Assignment::A_EXT_CONST
:
13583 case Assignment::A_MODULEPAR
:
13584 case Assignment::A_MODULEPAR_TEMP
:
13585 case Assignment::A_TEMPLATE
:
13586 case Assignment::A_PAR_VAL
:
13587 case Assignment::A_PAR_VAL_IN
:
13588 case Assignment::A_PAR_TEMPL_IN
:
13589 *type_str
= string("const ") + *type_str
;
13597 type_vec
->add(type_str
);
13598 // store the C++ reference string
13599 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
13600 if (refd_ass_is_lazy_fpar
) {
13601 Type
* refd_ass_type
= ass
->get_Type();
13602 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
);
13603 return string("((") + refd_ass_type_genname
+ string("&)") + get_member_name(refd_vec
->size()-1) + string(")");
13605 return get_member_name(refd_vec
->size()-1);
13609 string
LazyParamData::get_member_name(size_t idx
) {
13610 return string("lpm_") + Int2string(idx
);
13613 string
LazyParamData::get_constr_param_name(size_t idx
) {
13614 return string("lpp_") + Int2string(idx
);
13617 void LazyParamData::generate_code_for_value(expression_struct
* expr
, Value
* val
, Scope
* my_scope
) {
13618 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13619 if (use_runtime_2
&& TypeConv::needs_conv_refd(val
)) {
13620 const string
& tmp_id
= val
->get_temporary_id();
13621 const char *tmp_id_str
= tmp_id
.c_str();
13622 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13623 val
->get_my_governor()->get_genname_value(my_scope
).c_str(),
13625 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13627 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13629 val
->generate_code_expr(expr
);
13633 void LazyParamData::generate_code_for_template(expression_struct
* expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* my_scope
) {
13634 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13635 if (use_runtime_2
&& TypeConv::needs_conv_refd(temp
->get_Template())) {
13636 const string
& tmp_id
= temp
->get_Template()->get_temporary_id();
13637 const char *tmp_id_str
= tmp_id
.c_str();
13638 expr
->preamble
= mputprintf(expr
->preamble
, "%s %s;\n",
13639 temp
->get_Template()->get_my_governor()
13640 ->get_genname_template(my_scope
).c_str(), tmp_id_str
);
13641 expr
->preamble
= TypeConv::gen_conv_code_refd(expr
->preamble
,
13642 tmp_id_str
, temp
->get_Template());
13643 // Not incorporated into gen_conv_code() yet.
13644 if (gen_restriction_check
!= TR_NONE
)
13645 expr
->preamble
= Template::generate_restriction_check_code(
13646 expr
->preamble
, tmp_id_str
, gen_restriction_check
);
13647 expr
->expr
= mputstr(expr
->expr
, tmp_id_str
);
13648 } else temp
->generate_code(expr
, gen_restriction_check
);
13651 void LazyParamData::generate_code(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13652 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13654 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13655 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13656 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13657 expression_struct value_expr
;
13658 Code::init_expr(&value_expr
);
13659 generate_code_for_value(&value_expr
, value
, scope
);
13660 // the id of the instance of Lazy_Param which will be used as the actual parameter
13661 const string
& lazy_param_id
= value
->get_temporary_id();
13662 if (value_expr
.preamble
) {
13663 expr
->preamble
= mputstr(expr
->preamble
, value_expr
.preamble
);
13665 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13666 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13667 value
->get_my_governor()->get_genname_value(scope
).c_str(), value_expr
.expr
);
13668 Code::free_expr(&value_expr
);
13669 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13672 // only if the formal parameter is *not* used as lvalue
13673 if (!used_as_lvalue
&& value
->get_valuetype()==Value::V_REFD
&& value
->get_reference()->get_subrefs()==NULL
) {
13674 Assignment
* refd_ass
= value
->get_reference()->get_refd_assignment();
13676 bool refd_ass_is_lazy_fpar
= false;
13677 switch (refd_ass
->get_asstype()) {
13678 case Assignment::A_PAR_VAL
:
13679 case Assignment::A_PAR_VAL_IN
:
13680 case Assignment::A_PAR_TEMPL_IN
:
13681 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13686 if (refd_ass_is_lazy_fpar
) {
13687 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13692 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13693 expression_struct value_expr
;
13694 Code::init_expr(&value_expr
);
13695 generate_code_for_value(&value_expr
, value
, scope
);
13696 // the id of the instance of Lazy_Param which will be used as the actual parameter
13697 string lazy_param_id
= value
->get_temporary_id();
13698 string type_name
= value
->get_my_governor()->get_genname_value(scope
);
13699 generate_code_lazyparam_class(expr
, value_expr
, lazy_param_id
, type_name
);
13702 void LazyParamData::generate_code(expression_struct
*expr
, TemplateInstance
* temp
, template_restriction_t gen_restriction_check
, Scope
* scope
) {
13703 if (depth
<=0) FATAL_ERROR("LazyParamData::generate_code()");
13705 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13706 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13707 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13708 expression_struct tmpl_expr
;
13709 Code::init_expr(&tmpl_expr
);
13710 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13711 // the id of the instance of Lazy_Param which will be used as the actual parameter
13712 const string
& lazy_param_id
= temp
->get_Template()->get_temporary_id();
13713 if (tmpl_expr
.preamble
) {
13714 expr
->preamble
= mputstr(expr
->preamble
, tmpl_expr
.preamble
);
13716 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13717 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13718 temp
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), tmpl_expr
.expr
);
13719 Code::free_expr(&tmpl_expr
);
13720 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13723 // only if the formal parameter is *not* used as lvalue
13724 if (!used_as_lvalue
&& temp
->get_Template()->get_templatetype()==Template::TEMPLATE_REFD
&& temp
->get_Template()->get_reference()->get_subrefs()==NULL
) {
13725 Assignment
* refd_ass
= temp
->get_Template()->get_reference()->get_refd_assignment();
13727 bool refd_ass_is_lazy_fpar
= false;
13728 switch (refd_ass
->get_asstype()) {
13729 case Assignment::A_PAR_VAL
:
13730 case Assignment::A_PAR_VAL_IN
:
13731 case Assignment::A_PAR_TEMPL_IN
:
13732 refd_ass_is_lazy_fpar
= refd_ass
->get_lazy_eval();
13737 if (refd_ass_is_lazy_fpar
) {
13738 expr
->expr
= mputprintf(expr
->expr
, "%s", refd_ass
->get_genname_from_scope(scope
,"").c_str());
13743 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13744 expression_struct tmpl_expr
;
13745 Code::init_expr(&tmpl_expr
);
13746 generate_code_for_template(&tmpl_expr
, temp
, gen_restriction_check
, scope
);
13747 // the id of the instance of Lazy_Param which will be used as the actual parameter
13748 string lazy_param_id
= temp
->get_Template()->get_temporary_id();
13749 string type_name
= temp
->get_Template()->get_my_governor()->get_genname_template(scope
);
13750 generate_code_lazyparam_class(expr
, tmpl_expr
, lazy_param_id
, type_name
);
13753 void LazyParamData::generate_code_lazyparam_class(expression_struct
*expr
, expression_struct
& param_expr
, const string
& lazy_param_id
, const string
& type_name
) {
13754 expr
->preamble
= mputprintf(expr
->preamble
, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id
.c_str(), type_name
.c_str());
13755 if (type_vec
->size()>0) {
13756 // private members of the local class will be const references to the objects referenced by the expression
13757 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13758 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s;\n", (*type_vec
)[i
]->c_str(), get_member_name(i
).c_str());
13760 expr
->preamble
= mputstr(expr
->preamble
, "public:\n");
13761 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s(", lazy_param_id
.c_str());
13762 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13763 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13764 expr
->preamble
= mputprintf(expr
->preamble
, "%s& %s", (*type_vec
)[i
]->c_str(), get_constr_param_name(i
).c_str());
13766 expr
->preamble
= mputstr(expr
->preamble
, "): ");
13767 for (size_t i
=0; i
<type_vec
->size(); i
++) {
13768 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13769 expr
->preamble
= mputprintf(expr
->preamble
, "%s(%s)", get_member_name(i
).c_str(), get_constr_param_name(i
).c_str());
13771 expr
->preamble
= mputstr(expr
->preamble
, " {}\n");
13772 expr
->preamble
= mputstr(expr
->preamble
, "private:\n");
13774 expr
->preamble
= mputstr(expr
->preamble
, "virtual void eval_expr() {\n");
13775 // use the temporary expr structure to fill the body of the eval_expr() function
13776 if (param_expr
.preamble
) {
13777 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.preamble
);
13779 expr
->preamble
= mputprintf(expr
->preamble
, "expr_cache = %s;\n", param_expr
.expr
);
13780 if (param_expr
.postamble
) {
13781 expr
->preamble
= mputstr(expr
->preamble
, param_expr
.postamble
);
13783 Code::free_expr(¶m_expr
);
13784 expr
->preamble
= mputstr(expr
->preamble
, "}\n"
13785 "};\n" // end of local class definition
13787 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param_%s %s", lazy_param_id
.c_str(), lazy_param_id
.c_str());
13788 if (type_vec
->size()>0) {
13789 expr
->preamble
= mputc(expr
->preamble
, '(');
13790 // paramteres of the constructor are references to the objects used in the expression
13791 for (size_t i
=0; i
<refd_vec
->size(); i
++) {
13792 if (i
>0) expr
->preamble
= mputstr(expr
->preamble
, ", ");
13793 expr
->preamble
= mputprintf(expr
->preamble
, "%s", (*refd_vec
)[i
]->c_str());
13795 expr
->preamble
= mputc(expr
->preamble
, ')');
13797 expr
->preamble
= mputstr(expr
->preamble
, ";\n");
13798 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13799 expr
->expr
= mputprintf(expr
->expr
, "%s", lazy_param_id
.c_str());
13802 void LazyParamData::generate_code_ap_default_ref(expression_struct
*expr
, Ttcn::Ref_base
* ref
, Scope
* scope
) {
13803 expression_struct ref_expr
;
13804 Code::init_expr(&ref_expr
);
13805 ref
->generate_code(&ref_expr
);
13806 const string
& lazy_param_id
= scope
->get_scope_mod_gen()->get_temporary_id();
13807 if (ref_expr
.preamble
) {
13808 expr
->preamble
= mputstr(expr
->preamble
, ref_expr
.preamble
);
13810 Assignment
* ass
= ref
->get_refd_assignment();
13811 // determine C++ type of the assignment
13813 switch (ass
->get_asstype()) {
13814 case Assignment::A_MODULEPAR_TEMP
:
13815 case Assignment::A_TEMPLATE
:
13816 case Assignment::A_VAR_TEMPLATE
:
13817 case Assignment::A_PAR_TEMPL_IN
:
13818 case Assignment::A_PAR_TEMPL_OUT
:
13819 case Assignment::A_PAR_TEMPL_INOUT
:
13820 type_str
= ass
->get_Type()->get_genname_template(scope
);
13823 type_str
= ass
->get_Type()->get_genname_value(scope
);
13825 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13826 type_str
.c_str(), lazy_param_id
.c_str(), type_str
.c_str(), ref_expr
.expr
);
13827 if (ref_expr
.postamble
) {
13828 expr
->postamble
= mputstr(expr
->postamble
, ref_expr
.postamble
);
13830 Code::free_expr(&ref_expr
);
13831 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13834 void LazyParamData::generate_code_ap_default_value(expression_struct
*expr
, Value
* value
, Scope
* scope
) {
13835 const string
& lazy_param_id
= value
->get_temporary_id();
13836 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13837 value
->get_my_governor()->get_genname_value(scope
).c_str(), lazy_param_id
.c_str(),
13838 value
->get_my_governor()->get_genname_value(scope
).c_str(), value
->get_genname_own(scope
).c_str());
13839 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13842 void LazyParamData::generate_code_ap_default_ti(expression_struct
*expr
, TemplateInstance
* ti
, Scope
* scope
) {
13843 const string
& lazy_param_id
= ti
->get_Template()->get_temporary_id();
13844 expr
->preamble
= mputprintf(expr
->preamble
, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13845 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), lazy_param_id
.c_str(),
13846 ti
->get_Template()->get_my_governor()->get_genname_template(scope
).c_str(), ti
->get_Template()->get_genname_own(scope
).c_str());
13847 expr
->expr
= mputstr(expr
->expr
, lazy_param_id
.c_str());
13850 } // namespace Common