Sync with 5.2.0
[deliverable/titan.core.git] / compiler2 / Value.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "../common/dbgnew.hh"
9 #include "Value.hh"
10 #include "Identifier.hh"
11 #include "Valuestuff.hh"
12 #include "PredefFunc.hh"
13 #include "CompField.hh"
14 #include "CompType.hh"
15 #include "EnumItem.hh"
16 #include "TypeCompat.hh"
17 #include "asn1/Block.hh"
18 #include "asn1/TokenBuf.hh"
19 #include "Real.hh"
20 #include "Int.hh"
21 #include "main.hh"
22 #include "Setting.hh"
23 #include "Type.hh"
24 #include "ttcn3/TtcnTemplate.hh"
25 #include "ttcn3/ArrayDimensions.hh"
26 #include "ustring.hh"
27 #include "../common/pattern.hh"
28
29 #include "ttcn3/PatternString.hh"
30 #include "ttcn3/Statement.hh"
31
32 #include "ttcn3/Attributes.hh"
33
34 #include <math.h>
35 #include <regex.h>
36 #include <limits.h>
37
38 namespace Common {
39
40 static void clean_up_string_elements(map<size_t, Value>*& string_elements)
41 {
42 if (string_elements) {
43 for (size_t i = 0; i < string_elements->size(); i++)
44 delete string_elements->get_nth_elem(i);
45 string_elements->clear();
46 delete string_elements;
47 string_elements = 0;
48 }
49 }
50
51 // =================================
52 // ===== Value
53 // =================================
54
55 Value::Value(const Value& p)
56 : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
57 {
58 switch(valuetype) {
59 case V_ERROR:
60 case V_NULL:
61 case V_OMIT:
62 case V_TTCN3_NULL:
63 case V_DEFAULT_NULL:
64 case V_FAT_NULL:
65 case V_NOTUSED:
66 break;
67 case V_BOOL:
68 u.val_bool=p.u.val_bool;
69 break;
70 case V_INT:
71 u.val_Int=new int_val_t(*(p.u.val_Int));
72 break;
73 case V_NAMEDINT:
74 case V_ENUM:
75 case V_UNDEF_LOWERID:
76 u.val_id=p.u.val_id->clone();
77 break;
78 case V_REAL:
79 u.val_Real=p.u.val_Real;
80 break;
81 case V_BSTR:
82 case V_HSTR:
83 case V_OSTR:
84 case V_CSTR:
85 case V_ISO2022STR:
86 set_val_str(new string(*p.u.str.val_str));
87 break;
88 case V_USTR:
89 set_val_ustr(new ustring(*p.u.ustr.val_ustr));
90 u.ustr.convert_str = p.u.ustr.convert_str;
91 break;
92 case V_CHARSYMS:
93 u.char_syms = p.u.char_syms->clone();
94 break;
95 case V_OID:
96 case V_ROID:
97 u.oid_comps=new vector<OID_comp>;
98 for(size_t i=0; i<p.u.oid_comps->size(); i++)
99 add_oid_comp((*p.u.oid_comps)[i]->clone());
100 break;
101 case V_CHOICE:
102 u.choice.alt_name=p.u.choice.alt_name->clone();
103 u.choice.alt_value=p.u.choice.alt_value->clone();
104 break;
105 case V_SEQOF:
106 case V_SETOF:
107 case V_ARRAY:
108 u.val_vs=p.u.val_vs->clone();
109 break;
110 case V_SEQ:
111 case V_SET:
112 u.val_nvs=p.u.val_nvs->clone();
113 break;
114 case V_REFD:
115 u.ref.ref=p.u.ref.ref->clone();
116 u.ref.refd_last=0;
117 break;
118 case V_NAMEDBITS:
119 for(size_t i=0; i<p.u.ids->size(); i++) {
120 Identifier *id = p.u.ids->get_nth_elem(i);
121 u.ids->add(id->get_name(), id->clone());
122 }
123 break;
124 case V_UNDEF_BLOCK:
125 u.block=p.u.block->clone();
126 break;
127 case V_VERDICT:
128 u.verdict=p.u.verdict;
129 break;
130 case V_EXPR:
131 u.expr.v_optype = p.u.expr.v_optype;
132 u.expr.state = EXPR_NOT_CHECKED;
133 switch(u.expr.v_optype) {
134 case OPTYPE_RND: // -
135 case OPTYPE_COMP_NULL:
136 case OPTYPE_COMP_MTC:
137 case OPTYPE_COMP_SYSTEM:
138 case OPTYPE_COMP_SELF:
139 case OPTYPE_COMP_RUNNING_ANY:
140 case OPTYPE_COMP_RUNNING_ALL:
141 case OPTYPE_COMP_ALIVE_ANY:
142 case OPTYPE_COMP_ALIVE_ALL:
143 case OPTYPE_TMR_RUNNING_ANY:
144 case OPTYPE_GETVERDICT:
145 case OPTYPE_TESTCASENAME:
146 break;
147 case OPTYPE_UNARYPLUS: // v1
148 case OPTYPE_UNARYMINUS:
149 case OPTYPE_NOT:
150 case OPTYPE_NOT4B:
151 case OPTYPE_BIT2HEX:
152 case OPTYPE_BIT2INT:
153 case OPTYPE_BIT2OCT:
154 case OPTYPE_BIT2STR:
155 case OPTYPE_CHAR2INT:
156 case OPTYPE_CHAR2OCT:
157 case OPTYPE_COMP_RUNNING:
158 case OPTYPE_COMP_ALIVE:
159 case OPTYPE_FLOAT2INT:
160 case OPTYPE_FLOAT2STR:
161 case OPTYPE_HEX2BIT:
162 case OPTYPE_HEX2INT:
163 case OPTYPE_HEX2OCT:
164 case OPTYPE_HEX2STR:
165 case OPTYPE_INT2CHAR:
166 case OPTYPE_INT2FLOAT:
167 case OPTYPE_INT2STR:
168 case OPTYPE_INT2UNICHAR:
169 case OPTYPE_OCT2BIT:
170 case OPTYPE_OCT2CHAR:
171 case OPTYPE_OCT2HEX:
172 case OPTYPE_OCT2INT:
173 case OPTYPE_OCT2STR:
174 case OPTYPE_STR2BIT:
175 case OPTYPE_STR2FLOAT:
176 case OPTYPE_STR2HEX:
177 case OPTYPE_STR2INT:
178 case OPTYPE_STR2OCT:
179 case OPTYPE_UNICHAR2INT:
180 case OPTYPE_UNICHAR2CHAR:
181 case OPTYPE_ENUM2INT:
182 case OPTYPE_RNDWITHVAL:
183 case OPTYPE_GET_STRINGENCODING:
184 case OPTYPE_DECODE_BASE64:
185 case OPTYPE_REMOVE_BOM:
186 u.expr.v1=p.u.expr.v1->clone();
187 break;
188 case OPTYPE_ADD: // v1 v2
189 case OPTYPE_SUBTRACT:
190 case OPTYPE_MULTIPLY:
191 case OPTYPE_DIVIDE:
192 case OPTYPE_MOD:
193 case OPTYPE_REM:
194 case OPTYPE_CONCAT:
195 case OPTYPE_EQ:
196 case OPTYPE_LT:
197 case OPTYPE_GT:
198 case OPTYPE_NE:
199 case OPTYPE_GE:
200 case OPTYPE_LE:
201 case OPTYPE_AND:
202 case OPTYPE_OR:
203 case OPTYPE_XOR:
204 case OPTYPE_AND4B:
205 case OPTYPE_OR4B:
206 case OPTYPE_XOR4B:
207 case OPTYPE_SHL:
208 case OPTYPE_SHR:
209 case OPTYPE_ROTL:
210 case OPTYPE_ROTR:
211 case OPTYPE_INT2BIT:
212 case OPTYPE_INT2HEX:
213 case OPTYPE_INT2OCT:
214 u.expr.v1=p.u.expr.v1->clone();
215 u.expr.v2=p.u.expr.v2->clone();
216 break;
217 case OPTYPE_UNICHAR2OCT: // v1 [v2]
218 case OPTYPE_OCT2UNICHAR:
219 case OPTYPE_ENCODE_BASE64:
220 u.expr.v1=p.u.expr.v1->clone();
221 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
222 break;
223 case OPTYPE_DECODE:
224 u.expr.r1=p.u.expr.r1->clone();
225 u.expr.r2=p.u.expr.r2->clone();
226 break;
227 case OPTYPE_SUBSTR:
228 u.expr.ti1=p.u.expr.ti1->clone();
229 u.expr.v2=p.u.expr.v2->clone();
230 u.expr.v3=p.u.expr.v3->clone();
231 break;
232 case OPTYPE_REGEXP:
233 u.expr.ti1=p.u.expr.ti1->clone();
234 u.expr.t2=p.u.expr.t2->clone();
235 u.expr.v3=p.u.expr.v3->clone();
236 break;
237 case OPTYPE_DECOMP: // v1 v2 v3
238 u.expr.v1=p.u.expr.v1->clone();
239 u.expr.v2=p.u.expr.v2->clone();
240 u.expr.v3=p.u.expr.v3->clone();
241 break;
242 case OPTYPE_REPLACE:
243 u.expr.ti1 = p.u.expr.ti1->clone();
244 u.expr.v2 = p.u.expr.v2->clone();
245 u.expr.v3 = p.u.expr.v3->clone();
246 u.expr.ti4 = p.u.expr.ti4->clone();
247 break;
248 case OPTYPE_LENGTHOF: // ti1
249 case OPTYPE_SIZEOF: // ti1
250 case OPTYPE_VALUEOF: // ti1
251 case OPTYPE_ENCODE:
252 case OPTYPE_ISPRESENT:
253 case OPTYPE_TTCN2STRING:
254 u.expr.ti1=p.u.expr.ti1->clone();
255 break;
256 case OPTYPE_UNDEF_RUNNING:
257 case OPTYPE_TMR_READ:
258 case OPTYPE_TMR_RUNNING:
259 case OPTYPE_ACTIVATE:
260 u.expr.r1=p.u.expr.r1->clone();
261 break;
262 case OPTYPE_EXECUTE: // r1 [v2]
263 u.expr.r1=p.u.expr.r1->clone();
264 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
265 break;
266 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
267 u.expr.r1=p.u.expr.r1->clone();
268 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
269 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
270 u.expr.b4 = p.u.expr.b4;
271 break;
272 case OPTYPE_MATCH: // v1 t2
273 u.expr.v1=p.u.expr.v1->clone();
274 u.expr.t2=p.u.expr.t2->clone();
275 break;
276 case OPTYPE_ISCHOSEN: // r1 i2
277 u.expr.r1=p.u.expr.r1->clone();
278 u.expr.i2=p.u.expr.i2->clone();
279 break;
280 case OPTYPE_ISCHOSEN_V: // v1 i2
281 u.expr.v1=p.u.expr.v1->clone();
282 u.expr.i2=p.u.expr.i2->clone();
283 break;
284 case OPTYPE_ISCHOSEN_T: // t1 i2
285 u.expr.t1=p.u.expr.t1->clone();
286 u.expr.i2=p.u.expr.i2->clone();
287 break;
288 case OPTYPE_ACTIVATE_REFD:
289 u.expr.v1 = p.u.expr.v1->clone();
290 if(p.u.expr.state!=EXPR_CHECKED)
291 u.expr.t_list2 = p.u.expr.t_list2->clone();
292 else {
293 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
294 u.expr.state = EXPR_CHECKED;
295 }
296 break;
297 case OPTYPE_EXECUTE_REFD:
298 u.expr.v1 = p.u.expr.v1->clone();
299 if(p.u.expr.state!=EXPR_CHECKED)
300 u.expr.t_list2 = p.u.expr.t_list2->clone();
301 else {
302 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
303 u.expr.state = EXPR_CHECKED;
304 }
305 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
306 break;
307 case OPTYPE_LOG2STR:
308 u.expr.logargs = p.u.expr.logargs->clone();
309 break;
310 default:
311 FATAL_ERROR("Value::Value()");
312 } // switch
313 break;
314 case V_MACRO:
315 u.macro = p.u.macro;
316 break;
317 case V_FUNCTION:
318 case V_ALTSTEP:
319 case V_TESTCASE:
320 u.refd_fat = p.u.refd_fat;
321 break;
322 case V_INVOKE:
323 u.invoke.v = p.u.invoke.v->clone();
324 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
325 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
326 break;
327 case V_REFER:
328 u.refered = p.u.refered->clone();
329 break;
330 default:
331 FATAL_ERROR("Value::Value()");
332 } // switch
333 }
334
335 void Value::clean_up()
336 {
337 switch (valuetype) {
338 case V_ERROR:
339 case V_NULL:
340 case V_BOOL:
341 case V_REAL:
342 case V_OMIT:
343 case V_VERDICT:
344 case V_TTCN3_NULL:
345 case V_DEFAULT_NULL:
346 case V_FAT_NULL:
347 case V_MACRO:
348 case V_NOTUSED:
349 case V_FUNCTION:
350 case V_ALTSTEP:
351 case V_TESTCASE:
352 break;
353 case V_INT:
354 delete u.val_Int;
355 break;
356 case V_NAMEDINT:
357 case V_ENUM:
358 case V_UNDEF_LOWERID:
359 delete u.val_id;
360 break;
361 case V_BSTR:
362 case V_HSTR:
363 case V_OSTR:
364 case V_CSTR:
365 case V_ISO2022STR:
366 delete u.str.val_str;
367 clean_up_string_elements(u.str.str_elements);
368 break;
369 case V_USTR:
370 delete u.ustr.val_ustr;
371 clean_up_string_elements(u.ustr.ustr_elements);
372 break;
373 case V_CHARSYMS:
374 delete u.char_syms;
375 break;
376 case V_OID:
377 case V_ROID:
378 if (u.oid_comps) {
379 for(size_t i=0; i<u.oid_comps->size(); i++)
380 delete (*u.oid_comps)[i];
381 u.oid_comps->clear();
382 delete u.oid_comps;
383 }
384 break;
385 case V_EXPR:
386 clean_up_expr();
387 break;
388 case V_CHOICE:
389 delete u.choice.alt_name;
390 delete u.choice.alt_value;
391 break;
392 case V_SEQOF:
393 case V_SETOF:
394 case V_ARRAY:
395 delete u.val_vs;
396 break;
397 case V_SEQ:
398 case V_SET:
399 delete u.val_nvs;
400 break;
401 case V_REFD:
402 delete u.ref.ref;
403 break;
404 case V_REFER:
405 delete u.refered;
406 break;
407 case V_INVOKE:
408 delete u.invoke.v;
409 delete u.invoke.t_list;
410 delete u.invoke.ap_list;
411 break;
412 case V_NAMEDBITS:
413 if(u.ids) {
414 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
415 u.ids->clear();
416 delete u.ids;
417 }
418 break;
419 case V_UNDEF_BLOCK:
420 delete u.block;
421 break;
422 default:
423 FATAL_ERROR("Value::clean_up()");
424 } // switch
425 }
426
427 void Value::clean_up_expr()
428 {
429 switch (u.expr.state) {
430 case EXPR_CHECKING:
431 case EXPR_CHECKING_ERR:
432 FATAL_ERROR("Value::clean_up_expr()");
433 default:
434 break;
435 }
436 switch (u.expr.v_optype) {
437 case OPTYPE_RND: // -
438 case OPTYPE_COMP_NULL:
439 case OPTYPE_COMP_MTC:
440 case OPTYPE_COMP_SYSTEM:
441 case OPTYPE_COMP_SELF:
442 case OPTYPE_COMP_RUNNING_ANY:
443 case OPTYPE_COMP_RUNNING_ALL:
444 case OPTYPE_COMP_ALIVE_ANY:
445 case OPTYPE_COMP_ALIVE_ALL:
446 case OPTYPE_TMR_RUNNING_ANY:
447 case OPTYPE_GETVERDICT:
448 case OPTYPE_TESTCASENAME:
449 break;
450 case OPTYPE_UNARYPLUS: // v1
451 case OPTYPE_UNARYMINUS:
452 case OPTYPE_NOT:
453 case OPTYPE_NOT4B:
454 case OPTYPE_BIT2HEX:
455 case OPTYPE_BIT2INT:
456 case OPTYPE_BIT2OCT:
457 case OPTYPE_BIT2STR:
458 case OPTYPE_CHAR2INT:
459 case OPTYPE_CHAR2OCT:
460 case OPTYPE_COMP_RUNNING:
461 case OPTYPE_COMP_ALIVE:
462 case OPTYPE_FLOAT2INT:
463 case OPTYPE_FLOAT2STR:
464 case OPTYPE_HEX2BIT:
465 case OPTYPE_HEX2INT:
466 case OPTYPE_HEX2OCT:
467 case OPTYPE_HEX2STR:
468 case OPTYPE_INT2CHAR:
469 case OPTYPE_INT2FLOAT:
470 case OPTYPE_INT2STR:
471 case OPTYPE_INT2UNICHAR:
472 case OPTYPE_OCT2BIT:
473 case OPTYPE_OCT2CHAR:
474 case OPTYPE_OCT2HEX:
475 case OPTYPE_OCT2INT:
476 case OPTYPE_OCT2STR:
477 case OPTYPE_STR2BIT:
478 case OPTYPE_STR2FLOAT:
479 case OPTYPE_STR2HEX:
480 case OPTYPE_STR2INT:
481 case OPTYPE_STR2OCT:
482 case OPTYPE_UNICHAR2INT:
483 case OPTYPE_UNICHAR2CHAR:
484 case OPTYPE_ENUM2INT:
485 case OPTYPE_RNDWITHVAL:
486 case OPTYPE_REMOVE_BOM:
487 case OPTYPE_GET_STRINGENCODING:
488 case OPTYPE_DECODE_BASE64:
489 delete u.expr.v1;
490 break;
491 case OPTYPE_ADD: // v1 v2
492 case OPTYPE_SUBTRACT:
493 case OPTYPE_MULTIPLY:
494 case OPTYPE_DIVIDE:
495 case OPTYPE_MOD:
496 case OPTYPE_REM:
497 case OPTYPE_CONCAT:
498 case OPTYPE_EQ:
499 case OPTYPE_LT:
500 case OPTYPE_GT:
501 case OPTYPE_NE:
502 case OPTYPE_GE:
503 case OPTYPE_LE:
504 case OPTYPE_AND:
505 case OPTYPE_OR:
506 case OPTYPE_XOR:
507 case OPTYPE_AND4B:
508 case OPTYPE_OR4B:
509 case OPTYPE_XOR4B:
510 case OPTYPE_SHL:
511 case OPTYPE_SHR:
512 case OPTYPE_ROTL:
513 case OPTYPE_ROTR:
514 case OPTYPE_INT2BIT:
515 case OPTYPE_INT2HEX:
516 case OPTYPE_INT2OCT:
517 case OPTYPE_UNICHAR2OCT:
518 case OPTYPE_OCT2UNICHAR:
519 case OPTYPE_ENCODE_BASE64:
520 delete u.expr.v1;
521 delete u.expr.v2;
522 break;
523 case OPTYPE_DECODE:
524 delete u.expr.r1;
525 delete u.expr.r2;
526 break;
527 case OPTYPE_SUBSTR:
528 delete u.expr.ti1;
529 delete u.expr.v2;
530 delete u.expr.v3;
531 break;
532 case OPTYPE_REGEXP:
533 delete u.expr.ti1;
534 delete u.expr.t2;
535 delete u.expr.v3;
536 break;
537 case OPTYPE_DECOMP: // v1 v2 v3
538 delete u.expr.v1;
539 delete u.expr.v2;
540 delete u.expr.v3;
541 break;
542 case OPTYPE_REPLACE:
543 delete u.expr.ti1;
544 delete u.expr.v2;
545 delete u.expr.v3;
546 delete u.expr.ti4;
547 break;
548 case OPTYPE_LENGTHOF: // ti1
549 case OPTYPE_SIZEOF: // ti1
550 case OPTYPE_VALUEOF: // ti1
551 case OPTYPE_ISVALUE:
552 case OPTYPE_ISBOUND:
553 case OPTYPE_ENCODE:
554 case OPTYPE_ISPRESENT:
555 case OPTYPE_TTCN2STRING:
556 delete u.expr.ti1;
557 break;
558 case OPTYPE_UNDEF_RUNNING:
559 case OPTYPE_TMR_READ:
560 case OPTYPE_TMR_RUNNING:
561 case OPTYPE_ACTIVATE:
562 delete u.expr.r1;
563 break;
564 case OPTYPE_EXECUTE: // r1 [v2]
565 delete u.expr.r1;
566 delete u.expr.v2;
567 break;
568 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
569 delete u.expr.r1;
570 delete u.expr.v2;
571 delete u.expr.v3;
572 break;
573 case OPTYPE_MATCH: // v1 t2
574 delete u.expr.v1;
575 delete u.expr.t2;
576 break;
577 case OPTYPE_ISCHOSEN: // r1 i2
578 delete u.expr.r1;
579 delete u.expr.i2;
580 break;
581 case OPTYPE_ISCHOSEN_V: // v1 i2
582 delete u.expr.v1;
583 delete u.expr.i2;
584 break;
585 case OPTYPE_ISCHOSEN_T: // t1 i2
586 delete u.expr.t1;
587 delete u.expr.i2;
588 break;
589 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
590 delete u.expr.v1;
591 if(u.expr.state!=EXPR_CHECKED)
592 delete u.expr.t_list2;
593 else
594 delete u.expr.ap_list2;
595 break;
596 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
597 delete u.expr.v1;
598 if(u.expr.state!=EXPR_CHECKED)
599 delete u.expr.t_list2;
600 else
601 delete u.expr.ap_list2;
602 delete u.expr.v3;
603 break;
604 case OPTYPE_LOG2STR:
605 delete u.expr.logargs;
606 break;
607 default:
608 FATAL_ERROR("Value::clean_up_expr()");
609 } // switch
610 }
611
612 void Value::copy_and_destroy(Value *src)
613 {
614 clean_up();
615 valuetype = src->valuetype;
616 u = src->u;
617 // update the pointer used for caching if it points to the value itself
618 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
619 src->valuetype = V_ERROR;
620 delete src;
621 }
622
623 Value::Value(valuetype_t p_vt)
624 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
625 {
626 switch(valuetype) {
627 case V_NULL:
628 case V_TTCN3_NULL:
629 case V_OMIT:
630 case V_NOTUSED:
631 case V_ERROR:
632 break;
633 case V_OID:
634 case V_ROID:
635 u.oid_comps=new vector<OID_comp>();
636 break;
637 case V_NAMEDBITS:
638 u.ids=new map<string, Identifier>();
639 break;
640 default:
641 FATAL_ERROR("Value::Value()");
642 } // switch
643 }
644
645 Value::Value(valuetype_t p_vt, bool p_val_bool)
646 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
647 {
648 switch(valuetype) {
649 case V_BOOL:
650 u.val_bool=p_val_bool;
651 break;
652 default:
653 FATAL_ERROR("Value::Value()");
654 } // switch
655 }
656
657 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
658 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
659 {
660 switch(valuetype) {
661 case V_INT:
662 u.val_Int=new int_val_t(p_val_Int);
663 break;
664 default:
665 FATAL_ERROR("Value::Value()");
666 } // switch
667 }
668
669 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
670 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
671 {
672 switch(valuetype){
673 case V_INT:
674 u.val_Int=p_val_Int;
675 break;
676 default:
677 FATAL_ERROR("Value::Value()");
678 }
679 }
680
681 Value::Value(valuetype_t p_vt, string *p_val_str)
682 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
683 {
684 if(!p_val_str) FATAL_ERROR("NULL parameter");
685 switch(valuetype) {
686 case V_BSTR:
687 case V_HSTR:
688 case V_OSTR:
689 case V_CSTR:
690 case V_ISO2022STR:
691 set_val_str(p_val_str);
692 break;
693 default:
694 FATAL_ERROR("Value::Value()");
695 } // switch
696 }
697
698 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
699 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
700 {
701 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
702 set_val_ustr(p_val_ustr);
703 u.ustr.convert_str = false;
704 }
705
706 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
707 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
708 {
709 if (!p_char_syms) FATAL_ERROR("NULL parameter");
710 switch (valuetype) {
711 case V_CHARSYMS:
712 u.char_syms = p_char_syms;
713 break;
714 default:
715 FATAL_ERROR("Value::Value()");
716 } // switch
717 }
718
719 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
720 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
721 {
722 if(!p_val_id)
723 FATAL_ERROR("NULL parameter");
724 switch(valuetype) {
725 case V_NAMEDINT:
726 case V_ENUM:
727 case V_UNDEF_LOWERID:
728 u.val_id=p_val_id;
729 break;
730 default:
731 FATAL_ERROR("Value::Value()");
732 } // switch
733 }
734
735 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
736 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
737 {
738 if(!p_id || !p_val)
739 FATAL_ERROR("NULL parameter");
740 switch(valuetype) {
741 case V_CHOICE:
742 u.choice.alt_name=p_id;
743 u.choice.alt_value=p_val;
744 break;
745 default:
746 FATAL_ERROR("Value::Value()");
747 } // switch
748 }
749
750 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
751 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
752 {
753 switch(valuetype) {
754 case V_REAL:
755 u.val_Real=p_val_Real;
756 break;
757 default:
758 FATAL_ERROR("Value::Value()");
759 } // switch
760 }
761
762 Value::Value(valuetype_t p_vt, Values *p_vs)
763 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
764 {
765 if(!p_vs) FATAL_ERROR("NULL parameter");
766 switch(valuetype) {
767 case V_SEQOF:
768 case V_SETOF:
769 case V_ARRAY:
770 u.val_vs=p_vs;
771 break;
772 default:
773 FATAL_ERROR("Value::Value()");
774 } // switch
775 }
776
777 Value::Value(valuetype_t p_vt, Value *p_v,
778 Ttcn::ParsedActualParameters *p_t_list)
779 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
780 {
781 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
782 switch(valuetype) {
783 case V_INVOKE:
784 u.invoke.v = p_v;
785 u.invoke.t_list = p_t_list;
786 u.invoke.ap_list = 0;
787 break;
788 default:
789 FATAL_ERROR("Value::Value()");
790 }
791 }
792
793 // -
794 Value::Value(operationtype_t p_optype)
795 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
796 {
797 u.expr.v_optype = p_optype;
798 u.expr.state = EXPR_NOT_CHECKED;
799 switch(p_optype) {
800 case OPTYPE_RND:
801 case OPTYPE_COMP_NULL:
802 case OPTYPE_COMP_MTC:
803 case OPTYPE_COMP_SYSTEM:
804 case OPTYPE_COMP_SELF:
805 case OPTYPE_COMP_RUNNING_ANY:
806 case OPTYPE_COMP_RUNNING_ALL:
807 case OPTYPE_COMP_ALIVE_ANY:
808 case OPTYPE_COMP_ALIVE_ALL:
809 case OPTYPE_TMR_RUNNING_ANY:
810 case OPTYPE_GETVERDICT:
811 case OPTYPE_TESTCASENAME:
812 break;
813 default:
814 FATAL_ERROR("Value::Value()");
815 } // switch
816 }
817
818 // v1
819 Value::Value(operationtype_t p_optype, Value *p_v1)
820 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
821 {
822 u.expr.v_optype = p_optype;
823 u.expr.state = EXPR_NOT_CHECKED;
824 switch(p_optype) {
825 case OPTYPE_UNARYPLUS:
826 case OPTYPE_UNARYMINUS:
827 case OPTYPE_NOT:
828 case OPTYPE_NOT4B:
829 case OPTYPE_BIT2HEX:
830 case OPTYPE_BIT2INT:
831 case OPTYPE_BIT2OCT:
832 case OPTYPE_BIT2STR:
833 case OPTYPE_CHAR2INT:
834 case OPTYPE_CHAR2OCT:
835 case OPTYPE_COMP_RUNNING:
836 case OPTYPE_COMP_ALIVE:
837 case OPTYPE_FLOAT2INT:
838 case OPTYPE_FLOAT2STR:
839 case OPTYPE_HEX2BIT:
840 case OPTYPE_HEX2INT:
841 case OPTYPE_HEX2OCT:
842 case OPTYPE_HEX2STR:
843 case OPTYPE_INT2CHAR:
844 case OPTYPE_INT2FLOAT:
845 case OPTYPE_INT2STR:
846 case OPTYPE_INT2UNICHAR:
847 case OPTYPE_OCT2BIT:
848 case OPTYPE_OCT2CHAR:
849 case OPTYPE_OCT2HEX:
850 case OPTYPE_OCT2INT:
851 case OPTYPE_OCT2STR:
852 case OPTYPE_STR2BIT:
853 case OPTYPE_STR2FLOAT:
854 case OPTYPE_STR2HEX:
855 case OPTYPE_STR2INT:
856 case OPTYPE_STR2OCT:
857 case OPTYPE_UNICHAR2INT:
858 case OPTYPE_UNICHAR2CHAR:
859 case OPTYPE_ENUM2INT:
860 case OPTYPE_RNDWITHVAL:
861 case OPTYPE_REMOVE_BOM:
862 case OPTYPE_GET_STRINGENCODING:
863 case OPTYPE_DECODE_BASE64:
864 if(!p_v1) FATAL_ERROR("Value::Value()");
865 u.expr.v1=p_v1;
866 break;
867 default:
868 FATAL_ERROR("Value::Value()");
869 } // switch
870 }
871
872 // ti1
873 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
874 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
875 {
876 u.expr.v_optype = p_optype;
877 u.expr.state = EXPR_NOT_CHECKED;
878 switch(p_optype) {
879 case OPTYPE_LENGTHOF:
880 case OPTYPE_SIZEOF:
881 case OPTYPE_VALUEOF:
882 case OPTYPE_ISVALUE:
883 case OPTYPE_ISBOUND:
884 case OPTYPE_ENCODE:
885 case OPTYPE_ISPRESENT:
886 case OPTYPE_TTCN2STRING:
887 if(!p_ti1) FATAL_ERROR("Value::Value()");
888 u.expr.ti1=p_ti1;
889 break;
890 default:
891 FATAL_ERROR("Value::Value()");
892 } // switch
893 }
894
895 // r1
896 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
897 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
898 {
899 u.expr.v_optype = p_optype;
900 u.expr.state = EXPR_NOT_CHECKED;
901 switch(p_optype) {
902 case OPTYPE_UNDEF_RUNNING:
903 case OPTYPE_TMR_READ:
904 case OPTYPE_TMR_RUNNING:
905 case OPTYPE_ACTIVATE:
906 if(!p_r1) FATAL_ERROR("Value::Value()");
907 u.expr.r1=p_r1;
908 break;
909 default:
910 FATAL_ERROR("Value::Value()");
911 } // switch
912 }
913
914 // v1 t_list2
915 Value::Value(operationtype_t p_optype, Value *p_v1,
916 Ttcn::ParsedActualParameters *p_ap_list)
917 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
918 {
919 u.expr.v_optype = p_optype;
920 u.expr.state = EXPR_NOT_CHECKED;
921 switch(p_optype) {
922 case OPTYPE_ACTIVATE_REFD:
923 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
924 u.expr.v1 = p_v1;
925 u.expr.t_list2 = p_ap_list;
926 break;
927 default:
928 FATAL_ERROR("Value::Value()");
929 }
930 }
931
932 //v1 t_list2 v3
933 Value::Value(operationtype_t p_optype, Value *p_v1,
934 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
935 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
936 {
937 u.expr.v_optype = p_optype;
938 u.expr.state = EXPR_NOT_CHECKED;
939 switch(p_optype) {
940 case OPTYPE_EXECUTE_REFD:
941 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
942 u.expr.v1 = p_v1;
943 u.expr.t_list2 = p_t_list2;
944 u.expr.v3 = p_v3;
945 break;
946 default:
947 FATAL_ERROR("Value::Value()");
948 }
949 }
950
951 // r1 [v2]
952 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
953 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
954 {
955 u.expr.v_optype = p_optype;
956 u.expr.state = EXPR_NOT_CHECKED;
957 switch(p_optype) {
958 case OPTYPE_EXECUTE:
959 if(!p_r1) FATAL_ERROR("Value::Value()");
960 u.expr.r1=p_r1;
961 u.expr.v2=p_v2;
962 break;
963 default:
964 FATAL_ERROR("Value::Value()");
965 } // switch
966 }
967
968 // r1 [v2] [v3] b4
969 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
970 Value *p_v2, Value *p_v3, bool p_b4)
971 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
972 {
973 u.expr.v_optype = p_optype;
974 u.expr.state = EXPR_NOT_CHECKED;
975 switch(p_optype) {
976 case OPTYPE_COMP_CREATE:
977 if(!p_r1) FATAL_ERROR("Value::Value()");
978 u.expr.r1=p_r1;
979 u.expr.v2=p_v2;
980 u.expr.v3=p_v3;
981 u.expr.b4=p_b4;
982 break;
983 default:
984 FATAL_ERROR("Value::Value()");
985 } // switch
986 }
987
988 // v1 v2
989 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
990 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
991 {
992 u.expr.v_optype = p_optype;
993 u.expr.state = EXPR_NOT_CHECKED;
994 switch(p_optype) {
995 case OPTYPE_ADD:
996 case OPTYPE_SUBTRACT:
997 case OPTYPE_MULTIPLY:
998 case OPTYPE_DIVIDE:
999 case OPTYPE_MOD:
1000 case OPTYPE_REM:
1001 case OPTYPE_CONCAT:
1002 case OPTYPE_EQ:
1003 case OPTYPE_LT:
1004 case OPTYPE_GT:
1005 case OPTYPE_NE:
1006 case OPTYPE_GE:
1007 case OPTYPE_LE:
1008 case OPTYPE_AND:
1009 case OPTYPE_OR:
1010 case OPTYPE_XOR:
1011 case OPTYPE_AND4B:
1012 case OPTYPE_OR4B:
1013 case OPTYPE_XOR4B:
1014 case OPTYPE_SHL:
1015 case OPTYPE_SHR:
1016 case OPTYPE_ROTL:
1017 case OPTYPE_ROTR:
1018 case OPTYPE_INT2BIT:
1019 case OPTYPE_INT2HEX:
1020 case OPTYPE_INT2OCT:
1021 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1022 u.expr.v1=p_v1;
1023 u.expr.v2=p_v2;
1024 break;
1025 case OPTYPE_UNICHAR2OCT:
1026 case OPTYPE_OCT2UNICHAR:
1027 case OPTYPE_ENCODE_BASE64:
1028 if(!p_v1) FATAL_ERROR("Value::Value()");
1029 u.expr.v1=p_v1;
1030 // p_v2 may be NULL if there is no second param
1031 u.expr.v2=p_v2;
1032 break;
1033 default:
1034 FATAL_ERROR("Value::Value()");
1035 } // switch
1036 }
1037
1038 // ti1 v2 v3 ti4
1039 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1040 Value *p_v3, TemplateInstance *p_ti4) :
1041 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1042 {
1043 u.expr.v_optype = p_optype;
1044 u.expr.state = EXPR_NOT_CHECKED;
1045 switch (p_optype) {
1046 case OPTYPE_REPLACE:
1047 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1048 u.expr.ti1 = p_ti1;
1049 u.expr.v2 = p_v2;
1050 u.expr.v3 = p_v3;
1051 u.expr.ti4 = p_ti4;
1052 break;
1053 default:
1054 FATAL_ERROR("Value::Value()");
1055 } // switch
1056 }
1057
1058 // v1 v2 v3
1059 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1060 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1061 {
1062 u.expr.v_optype = p_optype;
1063 u.expr.state = EXPR_NOT_CHECKED;
1064 switch(p_optype) {
1065 case OPTYPE_DECOMP:
1066 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1067 u.expr.v1=p_v1;
1068 u.expr.v2=p_v2;
1069 u.expr.v3=p_v3;
1070 break;
1071 default:
1072 FATAL_ERROR("Value::Value()");
1073 } // switch
1074 }
1075
1076 // ti1 v2 v3
1077 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1078 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1079 {
1080 u.expr.v_optype=p_optype;
1081 u.expr.state=EXPR_NOT_CHECKED;
1082 switch(p_optype) {
1083 case OPTYPE_SUBSTR:
1084 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1085 u.expr.ti1 = p_ti1;
1086 u.expr.v2=p_v2;
1087 u.expr.v3=p_v3;
1088 break;
1089 default:
1090 FATAL_ERROR("Value::Value()");
1091 } // switch
1092 }
1093
1094 // ti1 t2 v3
1095 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1096 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1097 {
1098 u.expr.v_optype=p_optype;
1099 u.expr.state=EXPR_NOT_CHECKED;
1100 switch(p_optype) {
1101 case OPTYPE_REGEXP:
1102 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1103 u.expr.ti1 = p_ti1;
1104 u.expr.t2 = p_t2;
1105 u.expr.v3=p_v3;
1106 break;
1107 default:
1108 FATAL_ERROR("Value::Value()");
1109 } // switch
1110 }
1111
1112 // v1 t2
1113 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1114 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1115 {
1116 u.expr.v_optype = p_optype;
1117 u.expr.state = EXPR_NOT_CHECKED;
1118 switch(p_optype) {
1119 case OPTYPE_MATCH:
1120 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1121 u.expr.v1=p_v1;
1122 u.expr.t2=p_t2;
1123 break;
1124 default:
1125 FATAL_ERROR("Value::Value()");
1126 } // switch
1127 }
1128
1129 // r1 i2
1130 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1131 Identifier *p_i2)
1132 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1133 {
1134 u.expr.v_optype = p_optype;
1135 u.expr.state = EXPR_NOT_CHECKED;
1136 switch(p_optype) {
1137 case OPTYPE_ISCHOSEN:
1138 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1139 u.expr.r1=p_r1;
1140 u.expr.i2=p_i2;
1141 break;
1142 default:
1143 FATAL_ERROR("Value::Value()");
1144 } // switch
1145 }
1146
1147 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1148 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1149 {
1150 u.expr.v_optype = p_optype;
1151 u.expr.state = EXPR_NOT_CHECKED;
1152 switch(p_optype) {
1153 case OPTYPE_LOG2STR:
1154 if (!p_logargs) FATAL_ERROR("Value::Value()");
1155 u.expr.logargs = p_logargs;
1156 break;
1157 default:
1158 FATAL_ERROR("Value::Value()");
1159 } // switch
1160 }
1161
1162 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1163 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1164 {
1165 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1166 switch (p_macrotype) {
1167 case MACRO_MODULEID:
1168 case MACRO_FILENAME:
1169 case MACRO_BFILENAME:
1170 case MACRO_FILEPATH:
1171 case MACRO_LINENUMBER:
1172 case MACRO_LINENUMBER_C:
1173 case MACRO_DEFINITIONID:
1174 case MACRO_SCOPE:
1175 case MACRO_TESTCASEID:
1176 break;
1177 default:
1178 FATAL_ERROR("Value::Value()");
1179 }
1180 u.macro = p_macrotype;
1181 }
1182
1183 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1184 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1185 {
1186 if(!p_nvs) FATAL_ERROR("NULL parameter");
1187 switch(valuetype) {
1188 case V_SEQ:
1189 case V_SET:
1190 u.val_nvs=p_nvs;
1191 break;
1192 default:
1193 FATAL_ERROR("Value::Value()");
1194 } // switch
1195 }
1196
1197 Value::Value(valuetype_t p_vt, Reference *p_ref)
1198 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1199 {
1200 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1201 switch(p_vt) {
1202 case V_REFD:
1203 u.ref.ref = p_ref;
1204 u.ref.refd_last = 0;
1205 break;
1206 case V_REFER:
1207 u.refered = p_ref;
1208 break;
1209 default:
1210 FATAL_ERROR("Value::Value()");
1211 }
1212 }
1213
1214 Value::Value(valuetype_t p_vt, Block *p_block)
1215 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1216 {
1217 if(!p_block) FATAL_ERROR("NULL parameter");
1218 switch(valuetype) {
1219 case V_UNDEF_BLOCK:
1220 u.block=p_block;
1221 break;
1222 default:
1223 FATAL_ERROR("Value::Value()");
1224 } // switch
1225 }
1226
1227 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1228 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1229 {
1230 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1231 switch (p_verdict) {
1232 case Verdict_NONE:
1233 case Verdict_PASS:
1234 case Verdict_INCONC:
1235 case Verdict_FAIL:
1236 case Verdict_ERROR:
1237 break;
1238 default:
1239 FATAL_ERROR("Value::Value()");
1240 } // switch
1241 u.verdict = p_verdict;
1242 }
1243
1244 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1245 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1246 {
1247 u.expr.v_optype = p_optype;
1248 u.expr.state = EXPR_NOT_CHECKED;
1249 switch(p_optype) {
1250 case OPTYPE_DECODE:
1251 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1252 u.expr.r1=p_r1;
1253 u.expr.r2=p_r2;
1254 break;
1255 default:
1256 FATAL_ERROR("Value::Value()");
1257 } // switch
1258 }
1259
1260 Value::~Value()
1261 {
1262 clean_up();
1263 }
1264
1265 Value *Value::clone() const
1266 {
1267 return new Value(*this);
1268 }
1269
1270 Value::operationtype_t Value::get_optype() const
1271 {
1272 if(valuetype!=V_EXPR)
1273 FATAL_ERROR("Value::get_optype()");
1274 return u.expr.v_optype;
1275 }
1276
1277 void Value::set_my_governor(Type *p_gov)
1278 {
1279 if(!p_gov)
1280 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1281 my_governor=p_gov;
1282 }
1283
1284 Type *Value::get_my_governor() const
1285 {
1286 return my_governor;
1287 }
1288
1289 void Value::set_fullname(const string& p_fullname)
1290 {
1291 GovernedSimple::set_fullname(p_fullname);
1292 switch(valuetype) {
1293 case V_CHARSYMS:
1294 u.char_syms->set_fullname(p_fullname);
1295 break;
1296 case V_OID:
1297 case V_ROID:
1298 for(size_t i=0; i<u.oid_comps->size(); i++)
1299 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1300 break;
1301 case V_CHOICE:
1302 u.choice.alt_value->set_fullname(p_fullname + "." +
1303 u.choice.alt_name->get_dispname());
1304 break;
1305 case V_SEQOF:
1306 case V_SETOF:
1307 case V_ARRAY:
1308 u.val_vs->set_fullname(p_fullname);
1309 break;
1310 case V_SEQ:
1311 case V_SET:
1312 u.val_nvs->set_fullname(p_fullname);
1313 break;
1314 case V_REFD:
1315 u.ref.ref->set_fullname(p_fullname);
1316 break;
1317 case V_REFER:
1318 u.refered->set_fullname(p_fullname);
1319 break;
1320 case V_INVOKE:
1321 u.invoke.v->set_fullname(p_fullname);
1322 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1323 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1324 break;
1325 case V_EXPR:
1326 set_fullname_expr(p_fullname);
1327 break;
1328 default:
1329 break;
1330 } // switch
1331 }
1332
1333 void Value::set_my_scope(Scope *p_scope)
1334 {
1335 GovernedSimple::set_my_scope(p_scope);
1336 switch(valuetype) {
1337 case V_CHARSYMS:
1338 u.char_syms->set_my_scope(p_scope);
1339 break;
1340 case V_OID:
1341 case V_ROID:
1342 for(size_t i=0; i<u.oid_comps->size(); i++)
1343 (*u.oid_comps)[i]->set_my_scope(p_scope);
1344 break;
1345 case V_CHOICE:
1346 u.choice.alt_value->set_my_scope(p_scope);
1347 break;
1348 case V_SEQOF:
1349 case V_SETOF:
1350 case V_ARRAY:
1351 u.val_vs->set_my_scope(p_scope);
1352 break;
1353 case V_SEQ:
1354 case V_SET:
1355 u.val_nvs->set_my_scope(p_scope);
1356 break;
1357 case V_REFD:
1358 u.ref.ref->set_my_scope(p_scope);
1359 break;
1360 case V_REFER:
1361 u.refered->set_my_scope(p_scope);
1362 break;
1363 case V_INVOKE:
1364 u.invoke.v->set_my_scope(p_scope);
1365 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1366 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1367 break;
1368 case V_EXPR:
1369 set_my_scope_expr(p_scope);
1370 break;
1371 default:
1372 break;
1373 } // switch
1374 }
1375
1376 void Value::set_fullname_expr(const string& p_fullname)
1377 {
1378 switch (u.expr.v_optype) {
1379 case OPTYPE_RND: // -
1380 case OPTYPE_COMP_NULL:
1381 case OPTYPE_COMP_MTC:
1382 case OPTYPE_COMP_SYSTEM:
1383 case OPTYPE_COMP_SELF:
1384 case OPTYPE_COMP_RUNNING_ANY:
1385 case OPTYPE_COMP_RUNNING_ALL:
1386 case OPTYPE_COMP_ALIVE_ANY:
1387 case OPTYPE_COMP_ALIVE_ALL:
1388 case OPTYPE_TMR_RUNNING_ANY:
1389 case OPTYPE_GETVERDICT:
1390 case OPTYPE_TESTCASENAME:
1391 break;
1392 case OPTYPE_UNARYPLUS: // v1
1393 case OPTYPE_UNARYMINUS:
1394 case OPTYPE_NOT:
1395 case OPTYPE_NOT4B:
1396 case OPTYPE_BIT2HEX:
1397 case OPTYPE_BIT2INT:
1398 case OPTYPE_BIT2OCT:
1399 case OPTYPE_BIT2STR:
1400 case OPTYPE_CHAR2INT:
1401 case OPTYPE_CHAR2OCT:
1402 case OPTYPE_COMP_RUNNING:
1403 case OPTYPE_COMP_ALIVE:
1404 case OPTYPE_FLOAT2INT:
1405 case OPTYPE_FLOAT2STR:
1406 case OPTYPE_HEX2BIT:
1407 case OPTYPE_HEX2INT:
1408 case OPTYPE_HEX2OCT:
1409 case OPTYPE_HEX2STR:
1410 case OPTYPE_INT2CHAR:
1411 case OPTYPE_INT2FLOAT:
1412 case OPTYPE_INT2STR:
1413 case OPTYPE_INT2UNICHAR:
1414 case OPTYPE_OCT2BIT:
1415 case OPTYPE_OCT2CHAR:
1416 case OPTYPE_OCT2HEX:
1417 case OPTYPE_OCT2INT:
1418 case OPTYPE_OCT2STR:
1419 case OPTYPE_STR2BIT:
1420 case OPTYPE_STR2FLOAT:
1421 case OPTYPE_STR2HEX:
1422 case OPTYPE_STR2INT:
1423 case OPTYPE_STR2OCT:
1424 case OPTYPE_UNICHAR2INT:
1425 case OPTYPE_UNICHAR2CHAR:
1426 case OPTYPE_ENUM2INT:
1427 case OPTYPE_RNDWITHVAL:
1428 case OPTYPE_REMOVE_BOM:
1429 case OPTYPE_GET_STRINGENCODING:
1430 case OPTYPE_DECODE_BASE64:
1431 u.expr.v1->set_fullname(p_fullname+".<operand>");
1432 break;
1433 case OPTYPE_ADD: // v1 v2
1434 case OPTYPE_SUBTRACT:
1435 case OPTYPE_MULTIPLY:
1436 case OPTYPE_DIVIDE:
1437 case OPTYPE_MOD:
1438 case OPTYPE_REM:
1439 case OPTYPE_CONCAT:
1440 case OPTYPE_EQ:
1441 case OPTYPE_LT:
1442 case OPTYPE_GT:
1443 case OPTYPE_NE:
1444 case OPTYPE_GE:
1445 case OPTYPE_LE:
1446 case OPTYPE_AND:
1447 case OPTYPE_OR:
1448 case OPTYPE_XOR:
1449 case OPTYPE_AND4B:
1450 case OPTYPE_OR4B:
1451 case OPTYPE_XOR4B:
1452 case OPTYPE_SHL:
1453 case OPTYPE_SHR:
1454 case OPTYPE_ROTL:
1455 case OPTYPE_ROTR:
1456 case OPTYPE_INT2BIT:
1457 case OPTYPE_INT2HEX:
1458 case OPTYPE_INT2OCT:
1459 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1460 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1461 break;
1462 case OPTYPE_UNICHAR2OCT:
1463 case OPTYPE_OCT2UNICHAR:
1464 case OPTYPE_ENCODE_BASE64:
1465 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1466 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1467 break;
1468 case OPTYPE_DECODE:
1469 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1470 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1471 break;
1472 case OPTYPE_SUBSTR:
1473 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1474 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1475 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1476 break;
1477 case OPTYPE_REGEXP:
1478 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1479 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1480 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1481 break;
1482 case OPTYPE_DECOMP: // v1 v2 v3
1483 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1484 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1485 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1486 break;
1487 case OPTYPE_REPLACE:
1488 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1489 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1490 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1491 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1492 break;
1493 case OPTYPE_LENGTHOF: // ti1
1494 case OPTYPE_SIZEOF: // ti1
1495 case OPTYPE_VALUEOF: // ti1
1496 case OPTYPE_ISVALUE:
1497 case OPTYPE_ISBOUND:
1498 case OPTYPE_ENCODE:
1499 case OPTYPE_ISPRESENT:
1500 case OPTYPE_TTCN2STRING:
1501 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1502 break;
1503 case OPTYPE_UNDEF_RUNNING: // r1
1504 case OPTYPE_TMR_READ:
1505 case OPTYPE_TMR_RUNNING:
1506 case OPTYPE_ACTIVATE:
1507 u.expr.r1->set_fullname(p_fullname+".<operand>");
1508 break;
1509 case OPTYPE_EXECUTE: // r1 [v2]
1510 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1511 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1512 break;
1513 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1514 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1515 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1516 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1517 break;
1518 case OPTYPE_MATCH: // v1 t2
1519 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1520 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1521 break;
1522 case OPTYPE_ISCHOSEN: // r1 i2
1523 u.expr.r1->set_fullname(p_fullname+".<operand>");
1524 break;
1525 case OPTYPE_ISCHOSEN_V: // v1 i2
1526 u.expr.v1->set_fullname(p_fullname+".<operand>");
1527 break;
1528 case OPTYPE_ISCHOSEN_T: // t1 i2
1529 u.expr.t1->set_fullname(p_fullname+".<operand>");
1530 break;
1531 case OPTYPE_ACTIVATE_REFD:
1532 u.expr.v1->set_fullname(p_fullname+".<reference>");
1533 if(u.expr.state!=EXPR_CHECKED)
1534 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1535 else
1536 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1537 break;
1538 case OPTYPE_EXECUTE_REFD:
1539 u.expr.v1->set_fullname(p_fullname+".<reference>");
1540 if(u.expr.state!=EXPR_CHECKED)
1541 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1542 else
1543 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1544 if(u.expr.v3)
1545 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1546 break;
1547 case OPTYPE_LOG2STR:
1548 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1549 break;
1550 default:
1551 FATAL_ERROR("Value::set_fullname_expr()");
1552 } // switch
1553 }
1554
1555 void Value::set_my_scope_expr(Scope *p_scope)
1556 {
1557 switch (u.expr.v_optype) {
1558 case OPTYPE_RND: // -
1559 case OPTYPE_COMP_NULL:
1560 case OPTYPE_COMP_MTC:
1561 case OPTYPE_COMP_SYSTEM:
1562 case OPTYPE_COMP_SELF:
1563 case OPTYPE_COMP_RUNNING_ANY:
1564 case OPTYPE_COMP_RUNNING_ALL:
1565 case OPTYPE_COMP_ALIVE_ANY:
1566 case OPTYPE_COMP_ALIVE_ALL:
1567 case OPTYPE_TMR_RUNNING_ANY:
1568 case OPTYPE_GETVERDICT:
1569 case OPTYPE_TESTCASENAME:
1570 break;
1571 case OPTYPE_UNARYPLUS: // v1
1572 case OPTYPE_UNARYMINUS:
1573 case OPTYPE_NOT:
1574 case OPTYPE_NOT4B:
1575 case OPTYPE_BIT2HEX:
1576 case OPTYPE_BIT2INT:
1577 case OPTYPE_BIT2OCT:
1578 case OPTYPE_BIT2STR:
1579 case OPTYPE_CHAR2INT:
1580 case OPTYPE_CHAR2OCT:
1581 case OPTYPE_COMP_RUNNING:
1582 case OPTYPE_COMP_ALIVE:
1583 case OPTYPE_FLOAT2INT:
1584 case OPTYPE_FLOAT2STR:
1585 case OPTYPE_HEX2BIT:
1586 case OPTYPE_HEX2INT:
1587 case OPTYPE_HEX2OCT:
1588 case OPTYPE_HEX2STR:
1589 case OPTYPE_INT2CHAR:
1590 case OPTYPE_INT2FLOAT:
1591 case OPTYPE_INT2STR:
1592 case OPTYPE_INT2UNICHAR:
1593 case OPTYPE_OCT2BIT:
1594 case OPTYPE_OCT2CHAR:
1595 case OPTYPE_OCT2HEX:
1596 case OPTYPE_OCT2INT:
1597 case OPTYPE_OCT2STR:
1598 case OPTYPE_STR2BIT:
1599 case OPTYPE_STR2FLOAT:
1600 case OPTYPE_STR2HEX:
1601 case OPTYPE_STR2INT:
1602 case OPTYPE_STR2OCT:
1603 case OPTYPE_UNICHAR2INT:
1604 case OPTYPE_UNICHAR2CHAR:
1605 case OPTYPE_ENUM2INT:
1606 case OPTYPE_RNDWITHVAL:
1607 case OPTYPE_REMOVE_BOM:
1608 case OPTYPE_GET_STRINGENCODING:
1609 case OPTYPE_DECODE_BASE64:
1610 u.expr.v1->set_my_scope(p_scope);
1611 break;
1612 case OPTYPE_ADD: // v1 v2
1613 case OPTYPE_SUBTRACT:
1614 case OPTYPE_MULTIPLY:
1615 case OPTYPE_DIVIDE:
1616 case OPTYPE_MOD:
1617 case OPTYPE_REM:
1618 case OPTYPE_CONCAT:
1619 case OPTYPE_EQ:
1620 case OPTYPE_LT:
1621 case OPTYPE_GT:
1622 case OPTYPE_NE:
1623 case OPTYPE_GE:
1624 case OPTYPE_LE:
1625 case OPTYPE_AND:
1626 case OPTYPE_OR:
1627 case OPTYPE_XOR:
1628 case OPTYPE_AND4B:
1629 case OPTYPE_OR4B:
1630 case OPTYPE_XOR4B:
1631 case OPTYPE_SHL:
1632 case OPTYPE_SHR:
1633 case OPTYPE_ROTL:
1634 case OPTYPE_ROTR:
1635 case OPTYPE_INT2BIT:
1636 case OPTYPE_INT2HEX:
1637 case OPTYPE_INT2OCT:
1638 u.expr.v1->set_my_scope(p_scope);
1639 u.expr.v2->set_my_scope(p_scope);
1640 break;
1641 case OPTYPE_UNICHAR2OCT:
1642 case OPTYPE_OCT2UNICHAR:
1643 case OPTYPE_ENCODE_BASE64:
1644 u.expr.v1->set_my_scope(p_scope);
1645 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1646 break;
1647 case OPTYPE_DECODE:
1648 u.expr.r1->set_my_scope(p_scope);
1649 u.expr.r2->set_my_scope(p_scope);
1650 break;
1651 case OPTYPE_SUBSTR:
1652 u.expr.ti1->set_my_scope(p_scope);
1653 u.expr.v2->set_my_scope(p_scope);
1654 u.expr.v3->set_my_scope(p_scope);
1655 break;
1656 case OPTYPE_REGEXP:
1657 u.expr.ti1->set_my_scope(p_scope);
1658 u.expr.t2->set_my_scope(p_scope);
1659 u.expr.v3->set_my_scope(p_scope);
1660 break;
1661 case OPTYPE_DECOMP: // v1 v2 v3
1662 u.expr.v1->set_my_scope(p_scope);
1663 u.expr.v2->set_my_scope(p_scope);
1664 u.expr.v3->set_my_scope(p_scope);
1665 break;
1666 case OPTYPE_REPLACE:
1667 u.expr.ti1->set_my_scope(p_scope);
1668 u.expr.v2->set_my_scope(p_scope);
1669 u.expr.v3->set_my_scope(p_scope);
1670 u.expr.ti4->set_my_scope(p_scope);
1671 break;
1672 case OPTYPE_LENGTHOF: // ti1
1673 case OPTYPE_SIZEOF: // ti1
1674 case OPTYPE_VALUEOF: // ti1
1675 case OPTYPE_ISVALUE:
1676 case OPTYPE_ISBOUND:
1677 case OPTYPE_ENCODE:
1678 case OPTYPE_ISPRESENT:
1679 case OPTYPE_TTCN2STRING:
1680 u.expr.ti1->set_my_scope(p_scope);
1681 break;
1682 case OPTYPE_UNDEF_RUNNING: // r1
1683 case OPTYPE_TMR_READ:
1684 case OPTYPE_TMR_RUNNING:
1685 case OPTYPE_ACTIVATE:
1686 u.expr.r1->set_my_scope(p_scope);
1687 break;
1688 case OPTYPE_EXECUTE: // r1 [v2]
1689 u.expr.r1->set_my_scope(p_scope);
1690 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1691 break;
1692 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1693 u.expr.r1->set_my_scope(p_scope);
1694 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1695 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1696 break;
1697 case OPTYPE_MATCH: // v1 t2
1698 u.expr.v1->set_my_scope(p_scope);
1699 u.expr.t2->set_my_scope(p_scope);
1700 break;
1701 case OPTYPE_ISCHOSEN: // r1 i2
1702 u.expr.r1->set_my_scope(p_scope);
1703 break;
1704 case OPTYPE_ISCHOSEN_V: // v1 i2
1705 u.expr.v1->set_my_scope(p_scope);
1706 break;
1707 case OPTYPE_ISCHOSEN_T: // t1 i2
1708 u.expr.t1->set_my_scope(p_scope);
1709 break;
1710 case OPTYPE_ACTIVATE_REFD:
1711 u.expr.v1->set_my_scope(p_scope);
1712 if(u.expr.state!=EXPR_CHECKED) {
1713 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1714 else
1715 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1716 } break;
1717 case OPTYPE_EXECUTE_REFD:
1718 u.expr.v1->set_my_scope(p_scope);
1719 if(u.expr.state!=EXPR_CHECKED) {
1720 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1721 else
1722 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1723 }
1724 if(u.expr.v3)
1725 u.expr.v3->set_my_scope(p_scope);
1726 break;
1727 case OPTYPE_LOG2STR:
1728 u.expr.logargs->set_my_scope(p_scope);
1729 break;
1730 default:
1731 FATAL_ERROR("Value::set_my_scope_expr()");
1732 } // switch
1733 }
1734
1735 void Value::set_genname_recursive(const string& p_genname)
1736 {
1737 size_t genname_len = p_genname.size();
1738 if (genname_len >= 4 &&
1739 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1740 // if the genname ends with ()() (i.e. the value stands for an optional
1741 // field) then drop the last () from the own genname, but leave it for
1742 // the embedded values
1743 set_genname(p_genname.substr(0, genname_len - 2));
1744 } else set_genname(p_genname);
1745 switch(valuetype) {
1746 case V_CHOICE: {
1747 string embedded_genname(p_genname);
1748 embedded_genname += '.';
1749 // If this is a choice value for an anytype, prepend the AT_ prefix
1750 // to the name of the alternative. The genname is used later in
1751 // Common::Value::generate_code_init_se()
1752 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1753 embedded_genname += "AT_";
1754 embedded_genname += u.choice.alt_name->get_name();
1755 embedded_genname += "()";
1756 u.choice.alt_value->set_genname_recursive(embedded_genname);
1757 break; }
1758 case V_SEQOF:
1759 case V_SETOF: {
1760 if (!is_indexed()) {
1761 size_t nof_vs = u.val_vs->get_nof_vs();
1762 for (size_t i = 0; i < nof_vs; i++) {
1763 string embedded_genname(p_genname);
1764 embedded_genname += '[';
1765 embedded_genname += Int2string(i);
1766 embedded_genname += ']';
1767 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1768 }
1769 } else {
1770 size_t nof_ivs = u.val_vs->get_nof_ivs();
1771 for (size_t i = 0; i < nof_ivs; i++) {
1772 string embedded_genname(p_genname);
1773 embedded_genname += '[';
1774 embedded_genname += Int2string(i);
1775 embedded_genname += ']';
1776 u.val_vs->get_iv_byIndex(i)->get_value()
1777 ->set_genname_recursive(embedded_genname);
1778 }
1779 }
1780 break; }
1781 case V_ARRAY: {
1782 if (!my_governor) return; // error recovery
1783 Type *type = my_governor->get_type_refd_last();
1784 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1785 Int offset = type->get_dimension()->get_offset();
1786 if (!is_indexed()) {
1787 size_t nof_vs = u.val_vs->get_nof_vs();
1788 for (size_t i = 0; i < nof_vs; i++) {
1789 string embedded_genname(p_genname);
1790 embedded_genname += '[';
1791 embedded_genname += Int2string(offset + i);
1792 embedded_genname += ']';
1793 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1794 }
1795 } else {
1796 size_t nof_ivs = u.val_vs->get_nof_ivs();
1797 for (size_t i = 0; i < nof_ivs; i++) {
1798 string embedded_genname(p_genname);
1799 embedded_genname += '[';
1800 embedded_genname += Int2string(offset + i);
1801 embedded_genname += ']';
1802 u.val_vs->get_iv_byIndex(i)->get_value()
1803 ->set_genname_recursive(embedded_genname);
1804 }
1805 }
1806 break; }
1807 case V_SEQ:
1808 case V_SET: {
1809 if (!my_governor) return; // error recovery
1810 Type *t = my_governor->get_type_refd_last();
1811 if (!t->is_secho()) return; // error recovery
1812 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1813 for (size_t i = 0; i < nof_nvs; i++) {
1814 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1815 const Identifier& id = nv->get_name();
1816 if (!t->has_comp_withName(id)) return; // error recovery
1817 string embedded_genname(p_genname);
1818 embedded_genname += '.';
1819 embedded_genname += id.get_name();
1820 embedded_genname += "()";
1821 if (t->get_comp_byName(id)->get_is_optional())
1822 embedded_genname += "()";
1823 nv->get_value()->set_genname_recursive(embedded_genname);
1824 }
1825 break; }
1826 default:
1827 break;
1828 } // switch
1829 }
1830
1831 void Value::set_genname_prefix(const char *p_genname_prefix)
1832 {
1833 GovernedSimple::set_genname_prefix(p_genname_prefix);
1834 switch(valuetype) {
1835 case V_CHOICE:
1836 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1837 break;
1838 case V_SEQOF:
1839 case V_SETOF:
1840 case V_ARRAY:
1841 if (!is_indexed()) {
1842 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1843 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1844 } else {
1845 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1846 u.val_vs->get_iv_byIndex(i)->get_value()
1847 ->set_genname_prefix(p_genname_prefix);
1848 }
1849 break;
1850 case V_SEQ:
1851 case V_SET:
1852 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1853 u.val_nvs->get_nv_byIndex(i)->get_value()
1854 ->set_genname_prefix(p_genname_prefix);
1855 break;
1856 default:
1857 break;
1858 } // switch
1859 }
1860
1861 void Value::set_code_section(code_section_t p_code_section)
1862 {
1863 GovernedSimple::set_code_section(p_code_section);
1864 switch(valuetype) {
1865 case V_EXPR:
1866 switch (u.expr.v_optype) {
1867 case OPTYPE_RND: // -
1868 case OPTYPE_COMP_NULL:
1869 case OPTYPE_COMP_MTC:
1870 case OPTYPE_COMP_SYSTEM:
1871 case OPTYPE_COMP_SELF:
1872 case OPTYPE_COMP_RUNNING_ANY:
1873 case OPTYPE_COMP_RUNNING_ALL:
1874 case OPTYPE_COMP_ALIVE_ANY:
1875 case OPTYPE_COMP_ALIVE_ALL:
1876 case OPTYPE_TMR_RUNNING_ANY:
1877 case OPTYPE_GETVERDICT:
1878 case OPTYPE_TESTCASENAME:
1879 break;
1880 case OPTYPE_UNARYPLUS: // v1
1881 case OPTYPE_UNARYMINUS:
1882 case OPTYPE_NOT:
1883 case OPTYPE_NOT4B:
1884 case OPTYPE_BIT2HEX:
1885 case OPTYPE_BIT2INT:
1886 case OPTYPE_BIT2OCT:
1887 case OPTYPE_BIT2STR:
1888 case OPTYPE_CHAR2INT:
1889 case OPTYPE_CHAR2OCT:
1890 case OPTYPE_COMP_RUNNING:
1891 case OPTYPE_COMP_ALIVE:
1892 case OPTYPE_FLOAT2INT:
1893 case OPTYPE_FLOAT2STR:
1894 case OPTYPE_HEX2BIT:
1895 case OPTYPE_HEX2INT:
1896 case OPTYPE_HEX2OCT:
1897 case OPTYPE_HEX2STR:
1898 case OPTYPE_INT2CHAR:
1899 case OPTYPE_INT2FLOAT:
1900 case OPTYPE_INT2STR:
1901 case OPTYPE_INT2UNICHAR:
1902 case OPTYPE_OCT2BIT:
1903 case OPTYPE_OCT2CHAR:
1904 case OPTYPE_OCT2HEX:
1905 case OPTYPE_OCT2INT:
1906 case OPTYPE_OCT2STR:
1907 case OPTYPE_STR2BIT:
1908 case OPTYPE_STR2FLOAT:
1909 case OPTYPE_STR2HEX:
1910 case OPTYPE_STR2INT:
1911 case OPTYPE_STR2OCT:
1912 case OPTYPE_UNICHAR2INT:
1913 case OPTYPE_UNICHAR2CHAR:
1914 case OPTYPE_ENUM2INT:
1915 case OPTYPE_RNDWITHVAL:
1916 case OPTYPE_GET_STRINGENCODING:
1917 case OPTYPE_DECODE_BASE64:
1918 case OPTYPE_REMOVE_BOM:
1919 u.expr.v1->set_code_section(p_code_section);
1920 break;
1921 case OPTYPE_ADD: // v1 v2
1922 case OPTYPE_SUBTRACT:
1923 case OPTYPE_MULTIPLY:
1924 case OPTYPE_DIVIDE:
1925 case OPTYPE_MOD:
1926 case OPTYPE_REM:
1927 case OPTYPE_CONCAT:
1928 case OPTYPE_EQ:
1929 case OPTYPE_LT:
1930 case OPTYPE_GT:
1931 case OPTYPE_NE:
1932 case OPTYPE_GE:
1933 case OPTYPE_LE:
1934 case OPTYPE_AND:
1935 case OPTYPE_OR:
1936 case OPTYPE_XOR:
1937 case OPTYPE_AND4B:
1938 case OPTYPE_OR4B:
1939 case OPTYPE_XOR4B:
1940 case OPTYPE_SHL:
1941 case OPTYPE_SHR:
1942 case OPTYPE_ROTL:
1943 case OPTYPE_ROTR:
1944 case OPTYPE_INT2BIT:
1945 case OPTYPE_INT2HEX:
1946 case OPTYPE_INT2OCT:
1947 u.expr.v1->set_code_section(p_code_section);
1948 u.expr.v2->set_code_section(p_code_section);
1949 break;
1950 case OPTYPE_UNICHAR2OCT:
1951 case OPTYPE_OCT2UNICHAR:
1952 case OPTYPE_ENCODE_BASE64:
1953 u.expr.v1->set_code_section(p_code_section);
1954 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
1955 break;
1956 case OPTYPE_DECODE:
1957 u.expr.r1->set_code_section(p_code_section);
1958 u.expr.r2->set_code_section(p_code_section);
1959 break;
1960 case OPTYPE_SUBSTR:
1961 u.expr.ti1->set_code_section(p_code_section);
1962 u.expr.v2->set_code_section(p_code_section);
1963 u.expr.v3->set_code_section(p_code_section);
1964 break;
1965 case OPTYPE_REGEXP:
1966 u.expr.ti1->set_code_section(p_code_section);
1967 u.expr.t2->set_code_section(p_code_section);
1968 u.expr.v3->set_code_section(p_code_section);
1969 break;
1970 case OPTYPE_DECOMP: // v1 v2 v3
1971 u.expr.v1->set_code_section(p_code_section);
1972 u.expr.v2->set_code_section(p_code_section);
1973 u.expr.v3->set_code_section(p_code_section);
1974 break;
1975 case OPTYPE_REPLACE:
1976 u.expr.ti1->set_code_section(p_code_section);
1977 u.expr.v2->set_code_section(p_code_section);
1978 u.expr.v3->set_code_section(p_code_section);
1979 u.expr.ti4->set_code_section(p_code_section);
1980 break;
1981 case OPTYPE_LENGTHOF: // ti1
1982 case OPTYPE_SIZEOF: // ti1
1983 case OPTYPE_VALUEOF: // ti1
1984 case OPTYPE_ISVALUE:
1985 case OPTYPE_ISBOUND:
1986 case OPTYPE_ENCODE:
1987 case OPTYPE_ISPRESENT:
1988 case OPTYPE_TTCN2STRING:
1989 u.expr.ti1->set_code_section(p_code_section);
1990 break;
1991 case OPTYPE_UNDEF_RUNNING: // r1
1992 case OPTYPE_TMR_READ:
1993 case OPTYPE_TMR_RUNNING:
1994 case OPTYPE_ACTIVATE:
1995 u.expr.r1->set_code_section(p_code_section);
1996 break;
1997 case OPTYPE_EXECUTE: // r1 [v2]
1998 u.expr.r1->set_code_section(p_code_section);
1999 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2000 break;
2001 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2002 u.expr.r1->set_code_section(p_code_section);
2003 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2004 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2005 break;
2006 case OPTYPE_MATCH: // v1 t2
2007 u.expr.v1->set_code_section(p_code_section);
2008 u.expr.t2->set_code_section(p_code_section);
2009 break;
2010 case OPTYPE_ISCHOSEN: // r1 i2
2011 u.expr.r1->set_code_section(p_code_section);
2012 break;
2013 case OPTYPE_ISCHOSEN_V: // v1 i2
2014 u.expr.v1->set_code_section(p_code_section);
2015 break;
2016 case OPTYPE_ISCHOSEN_T: // t1 i2
2017 u.expr.t1->set_code_section(p_code_section);
2018 break;
2019 case OPTYPE_ACTIVATE_REFD:
2020 u.expr.v1->set_code_section(p_code_section);
2021 if(u.expr.state!=EXPR_CHECKED)
2022 u.expr.t_list2->set_code_section(p_code_section);
2023 else {
2024 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2025 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2026 u.expr.state = EXPR_CHECKED;
2027 }
2028 break;
2029 case OPTYPE_EXECUTE_REFD:
2030 u.expr.v1->set_code_section(p_code_section);
2031 if(u.expr.state!=EXPR_CHECKED)
2032 u.expr.t_list2->set_code_section(p_code_section);
2033 else {
2034 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2035 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2036 u.expr.state = EXPR_CHECKED;
2037 }
2038 if(u.expr.v3)
2039 u.expr.v3->set_code_section(p_code_section);
2040 break;
2041 case OPTYPE_LOG2STR:
2042 u.expr.logargs->set_code_section(p_code_section);
2043 break;
2044 default:
2045 FATAL_ERROR("Value::set_code_section()");
2046 } // switch
2047 break;
2048 case V_CHOICE:
2049 u.choice.alt_value->set_code_section(p_code_section);
2050 break;
2051 case V_SEQOF:
2052 case V_SETOF:
2053 case V_ARRAY:
2054 if (!is_indexed()) {
2055 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2056 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2057 } else {
2058 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2059 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2060 }
2061 break;
2062 case V_SEQ:
2063 case V_SET:
2064 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2065 u.val_nvs->get_nv_byIndex(i)->get_value()
2066 ->set_code_section(p_code_section);
2067 break;
2068 case V_REFD:
2069 u.ref.ref->set_code_section(p_code_section);
2070 break;
2071 case V_REFER:
2072 u.refered->set_code_section(p_code_section);
2073 break;
2074 case V_INVOKE:
2075 u.invoke.v->set_code_section(p_code_section);
2076 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2077 if(u.invoke.ap_list)
2078 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2079 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2080 break;
2081 default:
2082 break;
2083 } // switch
2084 }
2085
2086 void Value::change_sign()
2087 {
2088 switch(valuetype) {
2089 case V_INT:
2090 *u.val_Int=-*u.val_Int;
2091 break;
2092 case V_REAL:
2093 u.val_Real*=-1.0;
2094 break;
2095 case V_ERROR:
2096 break;
2097 default:
2098 FATAL_ERROR("Value::change_sign()");
2099 } // switch
2100 }
2101
2102 void Value::add_oid_comp(OID_comp* p_comp)
2103 {
2104 if(!p_comp)
2105 FATAL_ERROR("NULL parameter");
2106 u.oid_comps->add(p_comp);
2107 p_comp->set_fullname(get_fullname()+"."
2108 +Int2string(u.oid_comps->size()));
2109 p_comp->set_my_scope(my_scope);
2110 }
2111
2112 void Value::set_valuetype(valuetype_t p_valuetype)
2113 {
2114 if (valuetype == V_ERROR) return;
2115 else if (p_valuetype == V_ERROR) {
2116 if(valuetype==V_EXPR) {
2117 switch(u.expr.state) {
2118 case EXPR_CHECKING:
2119 u.expr.state=EXPR_CHECKING_ERR;
2120 // no break
2121 case EXPR_CHECKING_ERR:
2122 return;
2123 default:
2124 break;
2125 }
2126 }
2127 clean_up();
2128 valuetype = V_ERROR;
2129 return;
2130 }
2131 switch(valuetype) {
2132 case V_UNDEF_LOWERID:
2133 switch(p_valuetype) {
2134 case V_ENUM:
2135 case V_NAMEDINT:
2136 break;
2137 case V_REFD:
2138 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2139 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2140 u.ref.ref->set_my_scope(get_my_scope());
2141 u.ref.ref->set_fullname(get_fullname());
2142 u.ref.ref->set_location(*this);
2143 u.ref.refd_last = 0;
2144 break;
2145 default:
2146 FATAL_ERROR("Value::set_valuetype()");
2147 } // switch
2148 break;
2149 case V_UNDEF_BLOCK: {
2150 Block *t_block=u.block;
2151 Value *v=0;
2152 switch(p_valuetype) {
2153 case V_NAMEDBITS: {
2154 Node *node=t_block->parse(KW_Block_IdentifierList);
2155 v=dynamic_cast<Value*>(node);
2156 if(!v) {
2157 /* syntax error */
2158 u.ids=new map<string, Identifier>();
2159 }
2160 else {
2161 u.ids=v->u.ids; v->u.ids=0;
2162 }
2163 break;}
2164 case V_SEQOF: {
2165 Node *node=t_block->parse(KW_Block_SeqOfValue);
2166 v=dynamic_cast<Value*>(node);
2167 if(!v) {
2168 /* syntax error */
2169 u.val_vs=new Values();
2170 }
2171 else {
2172 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2173 }
2174 u.val_vs->set_my_scope(get_my_scope());
2175 u.val_vs->set_fullname(get_fullname());
2176 break;}
2177 case V_SETOF: {
2178 Node *node=t_block->parse(KW_Block_SetOfValue);
2179 v=dynamic_cast<Value*>(node);
2180 if(!v) {
2181 /* syntax error */
2182 u.val_vs=new Values();
2183 }
2184 else {
2185 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2186 }
2187 u.val_vs->set_my_scope(get_my_scope());
2188 u.val_vs->set_fullname(get_fullname());
2189 break;}
2190 case V_SEQ: {
2191 Node *node=t_block->parse(KW_Block_SequenceValue);
2192 v=dynamic_cast<Value*>(node);
2193 if(!v) {
2194 /* syntax error */
2195 u.val_nvs=new NamedValues();
2196 }
2197 else {
2198 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2199 }
2200 u.val_nvs->set_my_scope(get_my_scope());
2201 u.val_nvs->set_fullname(get_fullname());
2202 break;}
2203 case V_SET: {
2204 Node *node=t_block->parse(KW_Block_SetValue);
2205 v=dynamic_cast<Value*>(node);
2206 if(!v) {
2207 /* syntax error */
2208 u.val_nvs=new NamedValues();
2209 }
2210 else {
2211 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2212 }
2213 u.val_nvs->set_my_scope(get_my_scope());
2214 u.val_nvs->set_fullname(get_fullname());
2215 break;}
2216 case V_OID: {
2217 Node *node=t_block->parse(KW_Block_OIDValue);
2218 v=dynamic_cast<Value*>(node);
2219 if(!v) {
2220 /* syntax error */
2221 u.oid_comps=new vector<OID_comp>();
2222 }
2223 else {
2224 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2225 }
2226 for (size_t i = 0; i < u.oid_comps->size(); i++)
2227 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2228 break;}
2229 case V_ROID: {
2230 Node *node=t_block->parse(KW_Block_ROIDValue);
2231 v=dynamic_cast<Value*>(node);
2232 if(!v) {
2233 /* syntax error */
2234 u.oid_comps=new vector<OID_comp>();
2235 }
2236 else {
2237 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2238 }
2239 for (size_t i = 0; i < u.oid_comps->size(); i++)
2240 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2241 break;}
2242 case V_CHARSYMS: {
2243 Node *node=t_block->parse(KW_Block_CharStringValue);
2244 u.char_syms=dynamic_cast<CharSyms*>(node);
2245 if(!u.char_syms) {
2246 /* syntax error */
2247 u.char_syms=new CharSyms();
2248 }
2249 u.char_syms->set_my_scope(get_my_scope());
2250 u.char_syms->set_fullname(get_fullname());
2251 break;}
2252 default:
2253 FATAL_ERROR("Value::set_valuetype()");
2254 } // switch
2255 delete v;
2256 delete t_block;
2257 break;}
2258 case V_REFD:
2259 if (p_valuetype == V_USTR) {
2260 Value *v_last = get_value_refd_last();
2261 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2262 ustring *ustr = new ustring(*v_last->u.str.val_str);
2263 delete u.ref.ref;
2264 set_val_ustr(ustr);
2265 u.ustr.convert_str = true; // will be converted back to string
2266 } else FATAL_ERROR("Value::set_valuetype()");
2267 break;
2268 case V_CHARSYMS:
2269 switch(p_valuetype) {
2270 case V_CSTR: {
2271 const string& str = u.char_syms->get_string();
2272 delete u.char_syms;
2273 set_val_str(new string(str));
2274 break;}
2275 case V_USTR: {
2276 const ustring& ustr = u.char_syms->get_ustring();
2277 delete u.char_syms;
2278 set_val_ustr(new ustring(ustr));
2279 u.ustr.convert_str = false;
2280 break;}
2281 case V_ISO2022STR: {
2282 const string& str = u.char_syms->get_iso2022string();
2283 delete u.char_syms;
2284 set_val_str(new string(str));
2285 break;}
2286 default:
2287 FATAL_ERROR("Value::set_valuetype()");
2288 } // switch
2289 break;
2290 case V_INT: {
2291 Real val_Real;
2292 if (p_valuetype == V_REAL)
2293 val_Real = u.val_Int->to_real();
2294 else FATAL_ERROR("Value::set_valuetype()");
2295 clean_up();
2296 u.val_Real = val_Real;
2297 break; }
2298 case V_HSTR: {
2299 clean_up_string_elements(u.str.str_elements);
2300 string *old_str = u.str.val_str;
2301 switch(p_valuetype) {
2302 case V_BSTR:
2303 set_val_str(hex2bit(*old_str));
2304 break;
2305 case V_OSTR:
2306 set_val_str(asn_hex2oct(*old_str));
2307 break;
2308 default:
2309 FATAL_ERROR("Value::set_valuetype()");
2310 } // switch
2311 delete old_str;
2312 break;}
2313 case V_BSTR:
2314 clean_up_string_elements(u.str.str_elements);
2315 if (p_valuetype == V_OSTR) {
2316 string *old_str = u.str.val_str;
2317 set_val_str(asn_bit2oct(*old_str));
2318 delete old_str;
2319 } else FATAL_ERROR("Value::set_valuetype()");
2320 break;
2321 case V_CSTR:
2322 clean_up_string_elements(u.str.str_elements);
2323 switch(p_valuetype) {
2324 case V_USTR: {
2325 string *old_str = u.str.val_str;
2326 set_val_ustr(new ustring(*old_str));
2327 u.ustr.convert_str = true; // will be converted back to string
2328 delete old_str;
2329 break;}
2330 case V_ISO2022STR:
2331 // do nothing
2332 break;
2333 default:
2334 FATAL_ERROR("Value::set_valuetype()");
2335 } // switch p_valuetype
2336 break;
2337 case V_USTR:
2338 clean_up_string_elements(u.ustr.ustr_elements);
2339 switch(p_valuetype) {
2340 case V_CSTR: {
2341 ustring *old_str = u.ustr.val_ustr;
2342 size_t nof_chars = old_str->size();
2343 bool warning_flag = false;
2344 for (size_t i = 0; i < nof_chars; i++) {
2345 const ustring::universal_char& uchar = (*old_str)[i];
2346 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2347 error("This string value cannot contain multiple-byte characters, "
2348 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2349 uchar.group, uchar.plane, uchar.row, uchar.cell,
2350 (unsigned long) i);
2351 p_valuetype = V_ERROR;
2352 break;
2353 } else if (uchar.cell > 127 && !warning_flag) {
2354 warning("This string value may not contain characters with code "
2355 "higher than 127, but it has character with code %u (0x%02X) "
2356 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2357 warning_flag = true;
2358 }
2359 }
2360 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2361 delete old_str;
2362 break; }
2363 case V_ISO2022STR:
2364 error("ISO-10646 string value cannot be converted to "
2365 "ISO-2022 string");
2366 delete u.ustr.val_ustr;
2367 p_valuetype = V_ERROR;
2368 break;
2369 default:
2370 FATAL_ERROR("Value::set_valuetype()");
2371 } // switch p_valuetype
2372 break;
2373 case V_SEQ:
2374 switch (p_valuetype) {
2375 case V_CHOICE: {
2376 NamedValues *nvs = u.val_nvs;
2377 if (nvs->get_nof_nvs() < 1) {
2378 error("Union value must have one active field");
2379 delete nvs;
2380 valuetype = V_ERROR;
2381 return;
2382 } else if (nvs->get_nof_nvs() > 1) {
2383 error("Only one field was expected in union value instead of %lu",
2384 (unsigned long) nvs->get_nof_nvs());
2385 }
2386 NamedValue *nv = nvs->get_nv_byIndex(0);
2387 u.choice.alt_name = nv->get_name().clone();
2388 u.choice.alt_value = nv->steal_value();
2389 delete nvs;
2390 break;}
2391 case V_SET:
2392 // do nothing
2393 break;
2394 case V_REAL: {
2395 NamedValues *nvs = u.val_nvs;
2396 bool err = false;
2397 /* mantissa */
2398 Int i_mant = 0;
2399 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2400 if (nvs->has_nv_withName(id_mant)) {
2401 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2402 ->get_value_refd_last();
2403 if (v_tmp->get_valuetype() == V_INT) {
2404 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2405 if (*i_mant_int > INT_MAX) {
2406 error("Mantissa `%s' should be less than `%d'",
2407 (i_mant_int->t_str()).c_str(), INT_MAX);
2408 err = true;
2409 } else {
2410 i_mant = i_mant_int->get_val();
2411 }
2412 }
2413 else err = true;
2414 }
2415 else err = true;
2416 /* base */
2417 Int i_base = 0;
2418 Identifier id_base(Identifier::ID_ASN, string("base"));
2419 if (!err && nvs->has_nv_withName(id_base)) {
2420 Value *v = nvs->get_nv_byName(id_base)->get_value();
2421 Value *v_tmp = v->get_value_refd_last();
2422 if (v_tmp->get_valuetype() == V_INT) {
2423 const int_val_t *i_base_int = v_tmp->get_val_Int();
2424 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2425 v->error("Base of the REAL must be 2 or 10");
2426 err = true;
2427 } else {
2428 i_base = i_base_int->get_val();
2429 }
2430 }
2431 else err = true;
2432 }
2433 else err = true;
2434 /* exponent */
2435 Int i_exp = 0;
2436 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2437 if (!err && nvs->has_nv_withName(id_exp)) {
2438 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2439 ->get_value_refd_last();
2440 if (v_tmp->get_valuetype() == V_INT) {
2441 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2442 if (*i_exp_int > INT_MAX) {
2443 error("Exponent `%s' should be less than `%d'",
2444 (i_exp_int->t_str()).c_str(), INT_MAX);
2445 err = true;
2446 } else {
2447 i_exp = i_exp_int->get_val();
2448 }
2449 }
2450 else err = true;
2451 }
2452 else err = true;
2453 /* clean up */
2454 delete nvs;
2455 if (err) {
2456 valuetype = V_ERROR;
2457 return;
2458 }
2459 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2460 static_cast<double>(i_exp));
2461 break; }
2462 default:
2463 FATAL_ERROR("Value::set_valuetype()");
2464 } // switch
2465 break;
2466 case V_SEQOF:
2467 switch (p_valuetype) {
2468 case V_SEQ: {
2469 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2470 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2471 Type *t = my_governor->get_type_refd_last();
2472 switch (t->get_typetype()) {
2473 case Type::T_SEQ_T:
2474 case Type::T_SEQ_A:
2475 break;
2476 default:
2477 FATAL_ERROR("Value::set_valuetype()");
2478 }
2479 Values *vals = u.val_vs;
2480 size_t nof_vals = vals->get_nof_vs();
2481 size_t nof_comps = t->get_nof_comps();
2482 if (nof_vals > nof_comps) {
2483 error("Too many elements in value list notation for type `%s': "
2484 "%lu was expected instead of %lu",
2485 t->get_typename().c_str(),
2486 (unsigned long)nof_comps, (unsigned long)nof_vals);
2487 }
2488 size_t upper_limit;
2489 bool allnotused;
2490 if (nof_vals <= nof_comps) {
2491 upper_limit = nof_vals;
2492 allnotused = true;
2493 } else {
2494 upper_limit = nof_comps;
2495 allnotused = false;
2496 }
2497 u.val_nvs = new NamedValues;
2498 for (size_t i = 0; i < upper_limit; i++) {
2499 Value *v = vals->steal_v_byIndex(i);
2500 if (v->valuetype != V_NOTUSED) {
2501 allnotused = false;
2502 }
2503 NamedValue *nv =
2504 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2505 nv->set_location(*v);
2506 u.val_nvs->add_nv(nv);
2507 }
2508 u.val_nvs->set_my_scope(get_my_scope());
2509 u.val_nvs->set_fullname(get_fullname());
2510 delete vals;
2511 if (allnotused && nof_vals > 0)
2512 warning("All elements of value list notation for type `%s' are not "
2513 "used symbols (`-')", t->get_typename().c_str());
2514 break; }
2515 case V_SET:
2516 // { } -> empty set value
2517 if (u.val_vs->get_nof_vs() != 0)
2518 FATAL_ERROR("Value::set_valuetype()");
2519 delete u.val_vs;
2520 u.val_nvs = new NamedValues;
2521 break;
2522 case V_SETOF:
2523 case V_ARRAY:
2524 // SEQOF -> SETOF or ARRAY: trivial
2525 break;
2526 default:
2527 FATAL_ERROR("Value::set_valuetype()");
2528 }
2529 break;
2530 case V_TTCN3_NULL:
2531 switch (p_valuetype) {
2532 case V_DEFAULT_NULL:
2533 break;
2534 case V_FAT_NULL:
2535 break;
2536 default:
2537 FATAL_ERROR("Value::set_valuetype()");
2538 }
2539 break;
2540 case V_NOTUSED:
2541 if (V_OMIT != p_valuetype) { // in case of implicit omit
2542 FATAL_ERROR("Value::set_valuetype()");
2543 }
2544 break;
2545 default:
2546 FATAL_ERROR("Value::set_valuetype()");
2547 } // switch
2548 valuetype=p_valuetype;
2549 }
2550
2551 void Value::set_valuetype_COMP_NULL()
2552 {
2553 if(valuetype == V_ERROR) return;
2554 if(valuetype==V_TTCN3_NULL) {
2555 valuetype=V_EXPR;
2556 u.expr.v_optype=OPTYPE_COMP_NULL;
2557 // Nothing to check.
2558 u.expr.state=EXPR_CHECKED;
2559 }
2560 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2561 }
2562
2563 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2564 {
2565 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2566 delete u.val_id;
2567 u.val_Int = new int_val_t(p_val_int);
2568 valuetype = V_INT;
2569 } else FATAL_ERROR("Value::set_valuetype()");
2570 }
2571
2572 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2573 {
2574 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2575 clean_up();
2576 valuetype = V_BSTR;
2577 set_val_str(p_str);
2578 } else FATAL_ERROR("Value::set_valuetype()");
2579 }
2580
2581 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2582 {
2583 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2584 delete u.val_id;
2585 u.val_id = p_id;
2586 valuetype = V_ENUM;
2587 } else FATAL_ERROR("Value::set_valuetype()");
2588 }
2589
2590 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2591 {
2592 switch (p_valuetype) {
2593 case V_FUNCTION:
2594 case V_ALTSTEP:
2595 case V_TESTCASE:
2596 if (valuetype == V_REFER && p_ass) break;
2597 // no break
2598 default:
2599 FATAL_ERROR("Value::set_valuetype()");
2600 }
2601 delete u.refered;
2602 u.refd_fat = p_ass;
2603 valuetype = p_valuetype;
2604 }
2605
2606 bool Value::is_undef_lowerid()
2607 {
2608 switch (valuetype) {
2609 case V_UNDEF_LOWERID:
2610 return true;
2611 case V_EXPR:
2612 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2613 !u.expr.ti1->get_DerivedRef()) {
2614 return u.expr.ti1->get_Template()->is_undef_lowerid();
2615 }
2616 // no break
2617 default:
2618 return false;
2619 }
2620 }
2621
2622 const Identifier& Value::get_undef_lowerid()
2623 {
2624 switch (valuetype) {
2625 case V_UNDEF_LOWERID:
2626 return *u.val_id;
2627 case V_EXPR:
2628 if (u.expr.v_optype != OPTYPE_VALUEOF)
2629 FATAL_ERROR("Value::get_undef_lowerid()");
2630 return u.expr.ti1->get_Template()->get_specific_value()
2631 ->get_undef_lowerid();
2632 default:
2633 FATAL_ERROR("Value::get_undef_lowerid()");
2634 }
2635 const Identifier *dummy = 0;
2636 return *dummy;
2637 }
2638
2639 void Value::set_lowerid_to_ref()
2640 {
2641 switch (valuetype) {
2642 case V_UNDEF_LOWERID:
2643 set_valuetype(V_REFD);
2644 break;
2645 case V_EXPR:
2646 // if the governor of the expression is not known (in log(), etc...)
2647 // then the governor is taken from the reference (using
2648 // v1/ti1->get_expr_governor()), but that runs before the
2649 // params were checked, this smells like a workaround :)
2650 switch (u.expr.v_optype) {
2651 case OPTYPE_ROTL:
2652 case OPTYPE_ROTR:
2653 u.expr.v1->set_lowerid_to_ref();
2654 break;
2655 case OPTYPE_CONCAT:
2656 u.expr.v1->set_lowerid_to_ref();
2657 u.expr.v2->set_lowerid_to_ref();
2658 break;
2659 case OPTYPE_VALUEOF:
2660 case OPTYPE_ISVALUE:
2661 case OPTYPE_ISBOUND:
2662 case OPTYPE_ISPRESENT:
2663 case OPTYPE_SUBSTR:
2664 case OPTYPE_REGEXP:
2665 case OPTYPE_REPLACE:
2666 case OPTYPE_TTCN2STRING:
2667 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2668 Error_Context cntxt(u.expr.ti1->get_Template(),
2669 "In the operand of operation `%s'",
2670 get_opname());
2671 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2672 }
2673 if (u.expr.v_optype==OPTYPE_REGEXP) {
2674 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2675 Error_Context cntxt(u.expr.t2->get_Template(),
2676 "In the operand of operation `%s'",
2677 get_opname());
2678 u.expr.t2->get_Template()->set_lowerid_to_ref();
2679 }
2680 }
2681 if (u.expr.v_optype==OPTYPE_REPLACE) {
2682 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2683 Error_Context cntxt(u.expr.ti4->get_Template(),
2684 "In the operand of operation `%s'",
2685 get_opname());
2686 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2687 }
2688 }
2689 break;
2690 default:
2691 break;
2692 }
2693 break;
2694 default:
2695 break;
2696 }
2697 }
2698
2699 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2700 {
2701 switch (valuetype) {
2702 case V_CHARSYMS:
2703 case V_CHOICE:
2704 case V_SEQOF:
2705 case V_SETOF:
2706 case V_ARRAY:
2707 case V_SEQ:
2708 case V_SET:
2709 case V_UNDEF_LOWERID:
2710 case V_UNDEF_BLOCK:
2711 case V_OMIT:
2712 case V_TTCN3_NULL:
2713 case V_NOTUSED:
2714 case V_REFER:
2715 case V_FAT_NULL:
2716 return Type::T_UNDEF;
2717 case V_NAMEDINT:
2718 case V_NAMEDBITS:
2719 case V_OPENTYPE:
2720 FATAL_ERROR("Value::get_expr_returntype()");
2721 case V_ERROR:
2722 return Type::T_ERROR;
2723 case V_REFD:
2724 case V_INVOKE: {
2725 Type *t = get_expr_governor(exp_val);
2726 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2727 else return Type::T_ERROR; }
2728 case V_FUNCTION:
2729 return Type::T_FUNCTION;
2730 case V_ALTSTEP:
2731 return Type::T_ALTSTEP;
2732 case V_TESTCASE:
2733 return Type::T_TESTCASE;
2734 case V_EXPR:
2735 switch(u.expr.v_optype) {
2736 case OPTYPE_COMP_NULL:
2737 case OPTYPE_COMP_MTC:
2738 case OPTYPE_COMP_SYSTEM:
2739 case OPTYPE_COMP_SELF:
2740 case OPTYPE_COMP_CREATE:
2741 return Type::T_COMPONENT;
2742 case OPTYPE_UNDEF_RUNNING:
2743 case OPTYPE_COMP_RUNNING:
2744 case OPTYPE_COMP_RUNNING_ANY:
2745 case OPTYPE_COMP_RUNNING_ALL:
2746 case OPTYPE_COMP_ALIVE:
2747 case OPTYPE_COMP_ALIVE_ANY:
2748 case OPTYPE_COMP_ALIVE_ALL:
2749 case OPTYPE_TMR_RUNNING:
2750 case OPTYPE_TMR_RUNNING_ANY:
2751 case OPTYPE_MATCH:
2752 case OPTYPE_EQ:
2753 case OPTYPE_LT:
2754 case OPTYPE_GT:
2755 case OPTYPE_NE:
2756 case OPTYPE_GE:
2757 case OPTYPE_LE:
2758 case OPTYPE_NOT:
2759 case OPTYPE_AND:
2760 case OPTYPE_OR:
2761 case OPTYPE_XOR:
2762 case OPTYPE_ISPRESENT:
2763 case OPTYPE_ISCHOSEN:
2764 case OPTYPE_ISCHOSEN_V:
2765 case OPTYPE_ISCHOSEN_T:
2766 case OPTYPE_ISVALUE:
2767 case OPTYPE_ISBOUND:
2768 return Type::T_BOOL;
2769 case OPTYPE_GETVERDICT:
2770 return Type::T_VERDICT;
2771 case OPTYPE_VALUEOF: {
2772 Error_Context cntxt(this, "In the operand of operation `%s'",
2773 get_opname());
2774 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2775 case OPTYPE_TMR_READ:
2776 case OPTYPE_INT2FLOAT:
2777 case OPTYPE_STR2FLOAT:
2778 case OPTYPE_RND:
2779 case OPTYPE_RNDWITHVAL:
2780 return Type::T_REAL;
2781 case OPTYPE_ACTIVATE:
2782 return Type::T_DEFAULT;
2783 case OPTYPE_ACTIVATE_REFD:
2784 return Type::T_DEFAULT;
2785 case OPTYPE_EXECUTE:
2786 case OPTYPE_EXECUTE_REFD:
2787 return Type::T_VERDICT;
2788 case OPTYPE_UNARYPLUS: // v1
2789 case OPTYPE_UNARYMINUS: {
2790 Type::typetype_t tmp_tt;
2791 {
2792 Error_Context cntxt(this, "In the operand of operation `%s'",
2793 get_opname());
2794 u.expr.v1->set_lowerid_to_ref();
2795 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2796 }
2797 switch(tmp_tt) {
2798 case Type::T_INT:
2799 case Type::T_REAL:
2800 return tmp_tt;
2801 default:
2802 get_value_refd_last(); // to report the error
2803 return Type::T_ERROR;
2804 } // switch tmp_tt
2805 }
2806 case OPTYPE_ADD: // v1 v2
2807 case OPTYPE_SUBTRACT:
2808 case OPTYPE_MULTIPLY:
2809 case OPTYPE_DIVIDE: {
2810 Type::typetype_t tmp_tt;
2811 {
2812 Error_Context cntxt(this, "In the left operand of operation `%s'",
2813 get_opname());
2814 u.expr.v1->set_lowerid_to_ref();
2815 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2816 }
2817 switch(tmp_tt) {
2818 case Type::T_INT:
2819 case Type::T_REAL:
2820 return tmp_tt;
2821 default:
2822 if(u.expr.v_optype==OPTYPE_ADD) {
2823 Type::typetype_t tmp_tt2;
2824 {
2825 Error_Context cntxt(this, "In the right operand of operation `%s'",
2826 get_opname());
2827 u.expr.v2->set_lowerid_to_ref();
2828 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2829 }
2830 Type::typetype_t ret_val=Type::T_ERROR;
2831 bool maybeconcat=false;
2832 switch(tmp_tt) {
2833 case Type::T_BSTR:
2834 case Type::T_HSTR:
2835 case Type::T_OSTR:
2836 if(tmp_tt2==tmp_tt) {
2837 maybeconcat=true;
2838 ret_val=tmp_tt;
2839 }
2840 break;
2841 case Type::T_CSTR:
2842 case Type::T_USTR:
2843 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2844 maybeconcat=true;
2845 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2846 ret_val=Type::T_USTR;
2847 else ret_val=Type::T_CSTR;
2848 }
2849 break;
2850 default:
2851 break;
2852 }
2853 if(maybeconcat) {
2854 error("Did you mean the concat operation (`&') instead of"
2855 " addition operator (`+')?");
2856 u.expr.v_optype=OPTYPE_CONCAT;
2857 return ret_val;
2858 }
2859 }
2860 get_value_refd_last(); // to report the error
2861 return Type::T_ERROR;
2862 } // switch tmp_tt
2863 }
2864 case OPTYPE_NOT4B: // v1
2865 case OPTYPE_AND4B: // v1 v2
2866 case OPTYPE_OR4B:
2867 case OPTYPE_XOR4B:
2868 case OPTYPE_SHL:
2869 case OPTYPE_SHR: {
2870 Type::typetype_t tmp_tt;
2871 {
2872 Error_Context cntxt(this, "In the %soperand of operation `%s'",
2873 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
2874 get_opname());
2875 u.expr.v1->set_lowerid_to_ref();
2876 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2877 }
2878 switch(tmp_tt) {
2879 case Type::T_BSTR:
2880 case Type::T_HSTR:
2881 case Type::T_OSTR:
2882 return tmp_tt;
2883 default:
2884 get_value_refd_last(); // to report the error
2885 return Type::T_ERROR;
2886 } // switch tmp_tt
2887 }
2888 case OPTYPE_ROTL: // v1 v2
2889 case OPTYPE_ROTR: {
2890 Type::typetype_t tmp_tt;
2891 {
2892 Error_Context cntxt(this, "In the %s operand of operation `%s'",
2893 u.expr.v_optype==OPTYPE_ROTL
2894 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
2895 get_opname());
2896 u.expr.v1->set_lowerid_to_ref();
2897 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2898 }
2899 switch(tmp_tt) {
2900 case Type::T_BSTR:
2901 case Type::T_HSTR:
2902 case Type::T_OSTR:
2903 case Type::T_CSTR:
2904 case Type::T_USTR:
2905 case Type::T_SETOF:
2906 case Type::T_SEQOF:
2907 case Type::T_ARRAY:
2908 return tmp_tt;
2909 default:
2910 get_value_refd_last(); // to report the error
2911 return Type::T_ERROR;
2912 } // switch tmp_tt
2913 }
2914 case OPTYPE_SUBSTR:
2915 case OPTYPE_REPLACE: {
2916 Type::typetype_t tmp_tt;
2917 {
2918 Error_Context cntxt(this, "In the operand of operation `%s'",
2919 get_opname());
2920 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2921 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2922 }
2923 switch (tmp_tt) {
2924 case Type::T_BSTR:
2925 case Type::T_HSTR:
2926 case Type::T_OSTR:
2927 case Type::T_CSTR:
2928 case Type::T_USTR:
2929 case Type::T_SETOF:
2930 case Type::T_SEQOF:
2931 return tmp_tt;
2932 default:
2933 get_value_refd_last(); // to report the error
2934 return Type::T_ERROR;
2935 }
2936 }
2937 case OPTYPE_REGEXP: {
2938 Type::typetype_t tmp_tt;
2939 {
2940 Error_Context cntxt(this, "In the first operand of operation `%s'",
2941 get_opname());
2942 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2943 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2944 }
2945 switch(tmp_tt) {
2946 case Type::T_CSTR:
2947 case Type::T_USTR:
2948 return tmp_tt;
2949 default:
2950 get_value_refd_last(); // to report the error
2951 return Type::T_ERROR;
2952 } // switch tmp_tt
2953 }
2954 case OPTYPE_CONCAT: { // v1 v2
2955 Type::typetype_t tmp_tt;
2956 {
2957 Error_Context cntxt(this, "In the first operand of operation `%s'",
2958 get_opname());
2959 u.expr.v1->set_lowerid_to_ref();
2960 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2961 }
2962 switch(tmp_tt) {
2963 case Type::T_CSTR:
2964 case Type::T_USTR:
2965 case Type::T_BSTR:
2966 case Type::T_HSTR:
2967 case Type::T_OSTR:
2968 case Type::T_SETOF:
2969 case Type::T_SEQOF:
2970 return tmp_tt;
2971 default:
2972 get_value_refd_last(); // to report the error
2973 return Type::T_ERROR;
2974 } // switch tmp_tt
2975 }
2976 case OPTYPE_MOD:
2977 case OPTYPE_REM:
2978 case OPTYPE_CHAR2INT:
2979 case OPTYPE_UNICHAR2INT:
2980 case OPTYPE_BIT2INT:
2981 case OPTYPE_HEX2INT:
2982 case OPTYPE_OCT2INT:
2983 case OPTYPE_STR2INT:
2984 case OPTYPE_FLOAT2INT:
2985 case OPTYPE_LENGTHOF:
2986 case OPTYPE_SIZEOF:
2987 case OPTYPE_DECODE:
2988 case OPTYPE_ENUM2INT:
2989 return Type::T_INT;
2990 case OPTYPE_BIT2STR:
2991 case OPTYPE_FLOAT2STR:
2992 case OPTYPE_HEX2STR:
2993 case OPTYPE_INT2CHAR:
2994 case OPTYPE_INT2STR:
2995 case OPTYPE_OCT2CHAR:
2996 case OPTYPE_OCT2STR:
2997 case OPTYPE_UNICHAR2CHAR:
2998 case OPTYPE_LOG2STR:
2999 case OPTYPE_TESTCASENAME:
3000 case OPTYPE_TTCN2STRING:
3001 case OPTYPE_GET_STRINGENCODING:
3002 case OPTYPE_ENCODE_BASE64:
3003 return Type::T_CSTR;
3004 case OPTYPE_INT2UNICHAR:
3005 case OPTYPE_OCT2UNICHAR:
3006 return Type::T_USTR;
3007 case OPTYPE_INT2BIT:
3008 case OPTYPE_HEX2BIT:
3009 case OPTYPE_OCT2BIT:
3010 case OPTYPE_STR2BIT:
3011 case OPTYPE_ENCODE:
3012 return Type::T_BSTR;
3013 case OPTYPE_INT2HEX:
3014 case OPTYPE_BIT2HEX:
3015 case OPTYPE_OCT2HEX:
3016 case OPTYPE_STR2HEX:
3017 return Type::T_HSTR;
3018 case OPTYPE_INT2OCT:
3019 case OPTYPE_CHAR2OCT:
3020 case OPTYPE_HEX2OCT:
3021 case OPTYPE_BIT2OCT:
3022 case OPTYPE_STR2OCT:
3023 case OPTYPE_UNICHAR2OCT:
3024 case OPTYPE_REMOVE_BOM:
3025 case OPTYPE_DECODE_BASE64:
3026 return Type::T_OSTR;
3027 case OPTYPE_DECOMP:
3028 return Type::T_OID;
3029 default:
3030 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3031 // to avoid warning
3032 return Type::T_ERROR;
3033 } // switch optype
3034 case V_MACRO:
3035 switch (u.macro) {
3036 case MACRO_MODULEID:
3037 case MACRO_FILENAME:
3038 case MACRO_BFILENAME:
3039 case MACRO_FILEPATH:
3040 case MACRO_LINENUMBER:
3041 case MACRO_DEFINITIONID:
3042 case MACRO_SCOPE:
3043 case MACRO_TESTCASEID:
3044 return Type::T_CSTR;
3045 case MACRO_LINENUMBER_C:
3046 return Type::T_INT;
3047 default:
3048 return Type::T_ERROR;
3049 }
3050 case V_NULL:
3051 return Type::T_NULL;
3052 case V_BOOL:
3053 return Type::T_BOOL;
3054 case V_INT:
3055 return Type::T_INT;
3056 case V_REAL:
3057 return Type::T_REAL;
3058 case V_ENUM:
3059 return Type::T_ENUM_T;
3060 case V_BSTR:
3061 return Type::T_BSTR;
3062 case V_HSTR:
3063 return Type::T_HSTR;
3064 case V_OSTR:
3065 return Type::T_OSTR;
3066 case V_CSTR:
3067 return Type::T_CSTR;
3068 case V_USTR:
3069 return Type::T_USTR;
3070 case V_ISO2022STR:
3071 return Type::T_GENERALSTRING;
3072 case V_OID:
3073 return Type::T_OID;
3074 case V_ROID:
3075 return Type::T_ROID;
3076 case V_VERDICT:
3077 return Type::T_VERDICT;
3078 case V_DEFAULT_NULL:
3079 return Type::T_DEFAULT;
3080 default:
3081 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3082 // to avoid warning
3083 return Type::T_ERROR;
3084 } // switch
3085 }
3086
3087 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3088 {
3089 if(my_governor) return my_governor;
3090 switch (valuetype) {
3091 case V_INVOKE: {
3092 Type *t = u.invoke.v->get_expr_governor(exp_val);
3093 if(!t) {
3094 if(u.invoke.v->get_valuetype() != V_ERROR)
3095 u.invoke.v->error("A value of type function expected");
3096 goto error;
3097 }
3098 t = t->get_type_refd_last();
3099 switch(t->get_typetype()) {
3100 case Type::T_FUNCTION: {
3101 Type *t_return_type = t->get_function_return_type();
3102 if (!t_return_type) {
3103 error("Reference to a %s was expected instead of invocation "
3104 "of behavior type `%s' with no return type",
3105 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3106 t->get_fullname().c_str());
3107 goto error;
3108 }
3109 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3110 error("Reference to a value was expected, but functions of type "
3111 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3112 t_return_type->get_typename().c_str());
3113 goto error;
3114 }
3115 return t_return_type; }
3116 case Type::T_ALTSTEP:
3117 goto error;
3118 default:
3119 u.invoke.v->error("A value of type function expected instead of `%s'",
3120 t->get_typename().c_str());
3121 goto error;
3122 }
3123 break; }
3124 case V_REFD: {
3125 Assignment *ass=u.ref.ref->get_refd_assignment();
3126 Type *tmp_type=0;
3127 if (!ass) goto error;
3128 switch (ass->get_asstype()) {
3129 case Assignment::A_CONST:
3130 case Assignment::A_EXT_CONST:
3131 case Assignment::A_MODULEPAR:
3132 case Assignment::A_MODULEPAR_TEMP:
3133 case Assignment::A_TEMPLATE:
3134 case Assignment::A_VAR:
3135 case Assignment::A_VAR_TEMPLATE:
3136 case Assignment::A_FUNCTION_RVAL:
3137 case Assignment::A_FUNCTION_RTEMP:
3138 case Assignment::A_EXT_FUNCTION_RVAL:
3139 case Assignment::A_EXT_FUNCTION_RTEMP:
3140 case Assignment::A_PAR_VAL_IN:
3141 case Assignment::A_PAR_VAL_OUT:
3142 case Assignment::A_PAR_VAL_INOUT:
3143 case Assignment::A_PAR_TEMPL_IN:
3144 case Assignment::A_PAR_TEMPL_OUT:
3145 case Assignment::A_PAR_TEMPL_INOUT:
3146 tmp_type=ass->get_Type();
3147 break;
3148 case Assignment::A_FUNCTION:
3149 case Assignment::A_EXT_FUNCTION:
3150 error("Reference to a %s was expected instead of a call of %s, which "
3151 "does not have return type",
3152 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3153 ass->get_description().c_str());
3154 goto error;
3155 default:
3156 error("Reference to a %s was expected instead of %s",
3157 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3158 ass->get_description().c_str());
3159 goto error;
3160 } // end switch
3161 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3162 if(!tmp_type) goto error;
3163 return tmp_type; }
3164 case V_EXPR:
3165 switch (u.expr.v_optype) {
3166 case OPTYPE_VALUEOF:
3167 case OPTYPE_SUBSTR:
3168 case OPTYPE_REGEXP:
3169 case OPTYPE_REPLACE:{
3170 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3171 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3172 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3173 return tmp_type;
3174 }
3175 case OPTYPE_ROTL:
3176 case OPTYPE_ROTR:
3177 return u.expr.v1->get_expr_governor(exp_val);
3178 case OPTYPE_CONCAT:
3179 return get_expr_governor_v1v2(exp_val);
3180 case OPTYPE_COMP_MTC:
3181 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3182 else return 0;
3183 case OPTYPE_COMP_SYSTEM:
3184 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3185 else return 0;
3186 case OPTYPE_COMP_SELF:
3187 if (my_scope) {
3188 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3189 if (t_ros) return t_ros->get_component_type();
3190 else return 0;
3191 } else return 0;
3192 case OPTYPE_COMP_CREATE:
3193 return chk_expr_operand_comptyperef_create();
3194 default:
3195 break;
3196 }
3197 // no break
3198 default:
3199 return Type::get_pooltype(get_expr_returntype(exp_val));
3200 }
3201 error:
3202 set_valuetype(V_ERROR);
3203 return 0;
3204 }
3205
3206 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3207 {
3208 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3209 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3210 if (v1_gov) {
3211 if (v2_gov) { // both have governors
3212 // return the type that is compatible with both (if there is no type mismatch)
3213 if (v1_gov->is_compatible(v2_gov, NULL))
3214 return v1_gov;
3215 else return v2_gov;
3216 } else return v1_gov;
3217 } else { // v1 has no governor
3218 if (v2_gov) return v2_gov;
3219 else return NULL; // neither has governor
3220 }
3221 }
3222
3223 Type *Value::get_expr_governor_last()
3224 {
3225 Value *v_last = get_value_refd_last();
3226 if (v_last->valuetype == V_ERROR) return 0;
3227 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3228 if(!t) return 0;
3229 return t->get_type_refd_last();
3230 }
3231
3232 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3233 {
3234 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3235 return u.invoke.v->get_expr_governor(exp_val);
3236 }
3237
3238 const char* Value::get_opname() const
3239 {
3240 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3241 switch(u.expr.v_optype) {
3242 case OPTYPE_RND: // -
3243 return "rnd()";
3244 case OPTYPE_COMP_NULL:
3245 return "(component) null";
3246 case OPTYPE_COMP_MTC:
3247 return "mtc";
3248 case OPTYPE_COMP_SYSTEM:
3249 return "system";
3250 case OPTYPE_COMP_SELF:
3251 return "self";
3252 case OPTYPE_COMP_RUNNING_ANY:
3253 return "any component.running";
3254 case OPTYPE_COMP_RUNNING_ALL:
3255 return "all component.running";
3256 case OPTYPE_COMP_ALIVE_ANY:
3257 return "any component.alive";
3258 case OPTYPE_COMP_ALIVE_ALL:
3259 return "all component.alive";
3260 case OPTYPE_TMR_RUNNING_ANY:
3261 return "any timer.running";
3262 case OPTYPE_GETVERDICT:
3263 return "getverdict()";
3264 case OPTYPE_TESTCASENAME:
3265 return "testcasename()";
3266 case OPTYPE_UNARYPLUS: // v1
3267 return "unary +";
3268 case OPTYPE_UNARYMINUS:
3269 return "unary -";
3270 case OPTYPE_NOT:
3271 return "not";
3272 case OPTYPE_NOT4B:
3273 return "not4b";
3274 case OPTYPE_BIT2HEX:
3275 return "bit2hex()";
3276 case OPTYPE_BIT2INT:
3277 return "bit2int()";
3278 case OPTYPE_BIT2OCT:
3279 return "bit2oct()";
3280 case OPTYPE_BIT2STR:
3281 return "bit2str()";
3282 case OPTYPE_CHAR2INT:
3283 return "char2int()";
3284 case OPTYPE_CHAR2OCT:
3285 return "char2oct()";
3286 case OPTYPE_FLOAT2INT:
3287 return "float2int()";
3288 case OPTYPE_FLOAT2STR:
3289 return "float2str()";
3290 case OPTYPE_HEX2BIT:
3291 return "hex2bit()";
3292 case OPTYPE_HEX2INT:
3293 return "hex2int()";
3294 case OPTYPE_HEX2OCT:
3295 return "hex2oct()";
3296 case OPTYPE_HEX2STR:
3297 return "hex2str()";
3298 case OPTYPE_INT2CHAR:
3299 return "int2char()";
3300 case OPTYPE_INT2FLOAT:
3301 return "int2float()";
3302 case OPTYPE_INT2STR:
3303 return "int2str()";
3304 case OPTYPE_INT2UNICHAR:
3305 return "int2unichar()";
3306 case OPTYPE_OCT2BIT:
3307 return "oct2bit()";
3308 case OPTYPE_OCT2CHAR:
3309 return "oct2char()";
3310 case OPTYPE_OCT2HEX:
3311 return "oct2hex()";
3312 case OPTYPE_OCT2INT:
3313 return "oct2int()";
3314 case OPTYPE_OCT2STR:
3315 return "oct2str()";
3316 case OPTYPE_STR2BIT:
3317 return "str2bit()";
3318 case OPTYPE_STR2FLOAT:
3319 return "str2float()";
3320 case OPTYPE_STR2HEX:
3321 return "str2hex()";
3322 case OPTYPE_STR2INT:
3323 return "str2int()";
3324 case OPTYPE_STR2OCT:
3325 return "str2oct()";
3326 case OPTYPE_UNICHAR2INT:
3327 return "unichar2int()";
3328 case OPTYPE_UNICHAR2CHAR:
3329 return "unichar2char()";
3330 case OPTYPE_UNICHAR2OCT:
3331 return "unichar2oct()";
3332 case OPTYPE_ENUM2INT:
3333 return "enum2int()";
3334 case OPTYPE_LENGTHOF:
3335 return "lengthof()";
3336 case OPTYPE_SIZEOF:
3337 return "sizeof()";
3338 case OPTYPE_RNDWITHVAL:
3339 return "rnd (seed)";
3340 case OPTYPE_ENCODE:
3341 return "encvalue()";
3342 case OPTYPE_DECODE:
3343 return "decvalue()";
3344 case OPTYPE_GET_STRINGENCODING:
3345 return "get_stringencoding()";
3346 case OPTYPE_REMOVE_BOM:
3347 return "remove_bom()";
3348 case OPTYPE_ENCODE_BASE64:
3349 return "encode_base64()";
3350 case OPTYPE_DECODE_BASE64:
3351 return "decode_base64()";
3352 case OPTYPE_ADD: // v1 v2
3353 return "+";
3354 case OPTYPE_SUBTRACT:
3355 return "-";
3356 case OPTYPE_MULTIPLY:
3357 return "*";
3358 case OPTYPE_DIVIDE:
3359 return "/";
3360 case OPTYPE_MOD:
3361 return "mod";
3362 case OPTYPE_REM:
3363 return "rem";
3364 case OPTYPE_CONCAT:
3365 return "&";
3366 case OPTYPE_EQ:
3367 return "==";
3368 case OPTYPE_LT:
3369 return "<";
3370 case OPTYPE_GT:
3371 return ">";
3372 case OPTYPE_NE:
3373 return "!=";
3374 case OPTYPE_GE:
3375 return ">=";
3376 case OPTYPE_LE:
3377 return "<=";
3378 case OPTYPE_AND:
3379 return "and";
3380 case OPTYPE_OR:
3381 return "or";
3382 case OPTYPE_XOR:
3383 return "xor";
3384 case OPTYPE_AND4B:
3385 return "and4b";
3386 case OPTYPE_OR4B:
3387 return "or4b";
3388 case OPTYPE_XOR4B:
3389 return "xor4b";
3390 case OPTYPE_SHL:
3391 return "<<";
3392 case OPTYPE_SHR:
3393 return ">>";
3394 case OPTYPE_ROTL:
3395 return "<@";
3396 case OPTYPE_ROTR:
3397 return "@>";
3398 case OPTYPE_INT2BIT:
3399 return "int2bit()";
3400 case OPTYPE_INT2HEX:
3401 return "int2hex()";
3402 case OPTYPE_INT2OCT:
3403 return "int2oct()";
3404 case OPTYPE_OCT2UNICHAR:
3405 return "oct2unichar()";
3406 case OPTYPE_SUBSTR:
3407 return "substr()";
3408 case OPTYPE_REGEXP:
3409 return "regexp()";
3410 case OPTYPE_DECOMP:
3411 return "decomp()";
3412 case OPTYPE_REPLACE:
3413 return "replace()";
3414 case OPTYPE_VALUEOF: // t1
3415 return "valueof()";
3416 case OPTYPE_UNDEF_RUNNING:
3417 return "<timer or component> running";
3418 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3419 return "create()";
3420 case OPTYPE_COMP_RUNNING: // v1
3421 return "component running";
3422 case OPTYPE_COMP_ALIVE: // v1
3423 return "alive";
3424 case OPTYPE_TMR_READ:
3425 return "timer read";
3426 case OPTYPE_TMR_RUNNING:
3427 return "timer running";
3428 case OPTYPE_ACTIVATE:
3429 return "activate()";
3430 case OPTYPE_ACTIVATE_REFD:
3431 return "activate()";
3432 case OPTYPE_EXECUTE: // r1 [v2]
3433 case OPTYPE_EXECUTE_REFD:
3434 return "execute()";
3435 case OPTYPE_MATCH: // v1 t2
3436 return "match()";
3437 case OPTYPE_ISPRESENT:
3438 return "ispresent()";
3439 case OPTYPE_ISCHOSEN:
3440 case OPTYPE_ISCHOSEN_V:
3441 case OPTYPE_ISCHOSEN_T:
3442 return "ischosen()";
3443 case OPTYPE_ISVALUE:
3444 return "isvalue()";
3445 case OPTYPE_ISBOUND:
3446 return "isbound()";
3447 case OPTYPE_LOG2STR:
3448 return "log2str()";
3449 case OPTYPE_TTCN2STRING:
3450 return "ttcn2string()";
3451 default:
3452 FATAL_ERROR("Value::get_opname()");
3453 } // switch
3454 }
3455
3456 void Value::chk_expr_ref_ischosen()
3457 {
3458 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3459 Ttcn::Ref_base *tmpref=u.expr.r1;
3460 Assignment *ass=tmpref->get_refd_assignment();
3461 if (!ass) {
3462 set_valuetype(V_ERROR);
3463 return;
3464 }
3465 // Now we know whether the argument of ischosen() is a value or template.
3466 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3467 // or template (OPTYPE_ISCHOSEN_T).
3468 switch (ass->get_asstype()) {
3469 case Assignment::A_CONST:
3470 case Assignment::A_EXT_CONST:
3471 case Assignment::A_MODULEPAR:
3472 case Assignment::A_VAR:
3473 case Assignment::A_PAR_VAL_IN:
3474 case Assignment::A_PAR_VAL_OUT:
3475 case Assignment::A_PAR_VAL_INOUT:
3476 u.expr.v1=new Value(V_REFD, tmpref);
3477 u.expr.v1->set_location(*tmpref);
3478 u.expr.v1->set_my_scope(get_my_scope());
3479 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3480 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3481 break;
3482 case Assignment::A_MODULEPAR_TEMP:
3483 case Assignment::A_TEMPLATE:
3484 case Assignment::A_VAR_TEMPLATE:
3485 case Assignment::A_PAR_TEMPL_IN:
3486 case Assignment::A_PAR_TEMPL_OUT:
3487 case Assignment::A_PAR_TEMPL_INOUT:
3488 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3489 u.expr.t1->set_location(*tmpref);
3490 u.expr.t1->set_my_scope(get_my_scope());
3491 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3492 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3493 break;
3494 default:
3495 tmpref->error("Reference to a value or template was expected instead of "
3496 "%s", ass->get_description().c_str());
3497 set_valuetype(V_ERROR);
3498 break;
3499 } // switch
3500 }
3501
3502 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3503 Type::expected_value_t exp_val)
3504 {
3505 v->set_lowerid_to_ref(); // can only be reference to enum
3506 Type *t = v->get_expr_governor(exp_val);
3507 if (v->valuetype==V_ERROR) return;
3508 if (!t) {
3509 v->error("Please use reference to an enumerated value as the operand of "
3510 "operation `%s'", get_opname());
3511 set_valuetype(V_ERROR);
3512 return;
3513 }
3514 t = t->get_type_refd_last();
3515 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3516 v->error("The operand of operation `%s' should be enumerated value", opname);
3517 set_valuetype(V_ERROR);
3518 }
3519 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3520 v->error("The operand of operation `%s' cannot be omit", opname);
3521 set_valuetype(V_ERROR);
3522 }
3523 }
3524
3525 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3526 const char *opnum,
3527 const char *opname,
3528 const Location *loc)
3529 {
3530 if(tt==Type::T_BOOL) return;
3531 if(tt!=Type::T_ERROR)
3532 loc->error("%s operand of operation `%s' should be boolean value",
3533 opnum, opname);
3534 set_valuetype(V_ERROR);
3535 }
3536
3537 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3538 const char *opnum,
3539 const char *opname,
3540 const Location *loc)
3541 {
3542 if(tt==Type::T_INT) return;
3543 if(tt!=Type::T_ERROR)
3544 loc->error("%s operand of operation `%s' should be integer value",
3545 opnum, opname);
3546 set_valuetype(V_ERROR);
3547 }
3548
3549 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3550 const char *opnum,
3551 const char *opname,
3552 const Location *loc)
3553 {
3554 if(tt==Type::T_REAL) return;
3555 else if(tt==Type::T_INT)
3556 loc->error("%s operand of operation `%s' should be float value."
3557 " Perhaps you missed an int2float() conversion function"
3558 " or `.0' at the end of the number",
3559 opnum, opname);
3560 else if(tt!=Type::T_ERROR)
3561 loc->error("%s operand of operation `%s' should be float value",
3562 opnum, opname);
3563 set_valuetype(V_ERROR);
3564 }
3565
3566 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3567 const char *opnum,
3568 const char *opname,
3569 const Location *loc)
3570 {
3571 switch(tt) {
3572 case Type::T_INT:
3573 case Type::T_REAL:
3574 return;
3575 default:
3576 break;
3577 }
3578 if(tt!=Type::T_ERROR)
3579 loc->error("%s operand of operation `%s' should be integer"
3580 " or float value",
3581 opnum, opname);
3582 set_valuetype(V_ERROR);
3583 }
3584
3585 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3586 const char *opnum,
3587 const char *opname,
3588 const Location *loc)
3589 {
3590 switch(tt) {
3591 case Type::T_INT:
3592 case Type::T_REAL:
3593 case Type::T_ENUM_T:
3594 return;
3595 default:
3596 break;
3597 }
3598 if(tt!=Type::T_ERROR)
3599 loc->error("%s operand of operation `%s' should be integer, float"
3600 " or enumerated value", opnum, opname);
3601 set_valuetype(V_ERROR);
3602 }
3603
3604 void Value::chk_expr_operandtype_list(Type* t,
3605 const char *opnum,
3606 const char *opname,
3607 const Location *loc,
3608 bool allow_array)
3609 {
3610 if (valuetype == V_ERROR) return;
3611 if (t->get_typetype() == Type::T_ERROR) {
3612 set_valuetype(V_ERROR);
3613 return;
3614 }
3615 if (!t->is_list_type(allow_array)) {
3616 loc->error("%s operand of operation `%s' should be a string, "
3617 "`record of'%s `set of'%s value", opnum, opname,
3618 allow_array ? "," : " or", allow_array ? " or array" : "");
3619 set_valuetype(V_ERROR);
3620 return;
3621 }
3622 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3623 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3624 TypeChain l_chain;
3625 TypeChain r_chain;
3626 if (my_governor && my_governor->is_list_type(allow_array)
3627 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3628 if (info.is_subtype_error()) {
3629 // this is ok.
3630 if (info.needs_conversion()) set_needs_conversion();
3631 } else
3632 if (!info.is_erroneous()) {
3633 error("%s operand of operation `%s' is of type `%s', but a value of "
3634 "type `%s' was expected here", opnum, opname,
3635 t->get_typename().c_str(), my_governor->get_typename().c_str());
3636 } else {
3637 error("%s", info.get_error_str_str().c_str());
3638 }
3639 } else {
3640 if (info.needs_conversion())
3641 set_needs_conversion();
3642 }
3643 }
3644
3645 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3646 const char *opnum,
3647 const char *opname,
3648 const Location *loc)
3649 {
3650 switch(tt) {
3651 case Type::T_CSTR:
3652 case Type::T_USTR:
3653 case Type::T_BSTR:
3654 case Type::T_HSTR:
3655 case Type::T_OSTR:
3656 return;
3657 default:
3658 break;
3659 }
3660 if(tt!=Type::T_ERROR)
3661 loc->error("%s operand of operation `%s' should be string value",
3662 opnum, opname);
3663 set_valuetype(V_ERROR);
3664 }
3665
3666 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3667 const char *opnum,
3668 const char *opname,
3669 const Location *loc)
3670 {
3671 switch(tt) {
3672 case Type::T_CSTR:
3673 case Type::T_USTR:
3674 return;
3675 default:
3676 break;
3677 }
3678 if(tt!=Type::T_ERROR)
3679 loc->error("%s operand of operation `%s' should be (universal)"
3680 " charstring value",
3681 opnum, opname);
3682 set_valuetype(V_ERROR);
3683 }
3684
3685 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3686 const char *opnum,
3687 const char *opname,
3688 const Location *loc)
3689 {
3690 if(tt==Type::T_CSTR) return;
3691 if(tt!=Type::T_ERROR)
3692 loc->error("%s operand of operation `%s' should be charstring value",
3693 opnum, opname);
3694 set_valuetype(V_ERROR);
3695 }
3696
3697 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3698 const char *opnum,
3699 const char *opname,
3700 const Location *loc)
3701 {
3702 switch(tt) {
3703 case Type::T_BSTR:
3704 case Type::T_HSTR:
3705 case Type::T_OSTR:
3706 return;
3707 default:
3708 break;
3709 }
3710 if(tt!=Type::T_ERROR)
3711 loc->error("%s operand of operation `%s' should be binary string value",
3712 opnum, opname);
3713 set_valuetype(V_ERROR);
3714 }
3715
3716 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3717 const char *opnum,
3718 const char *opname,
3719 const Location *loc)
3720 {
3721 if(tt==Type::T_BSTR) return;
3722 if(tt!=Type::T_ERROR)
3723 loc->error("%s operand of operation `%s' should be bitstring value",
3724 opnum, opname);
3725 set_valuetype(V_ERROR);
3726 }
3727
3728 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3729 const char *opnum,
3730 const char *opname,
3731 const Location *loc)
3732 {
3733 if(tt==Type::T_HSTR) return;
3734 if(tt!=Type::T_ERROR)
3735 loc->error("%s operand of operation `%s' should be hexstring value",
3736 opnum, opname);
3737 set_valuetype(V_ERROR);
3738 }
3739
3740 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3741 const char *opnum,
3742 const char *opname,
3743 const Location *loc)
3744 {
3745 if(tt==Type::T_OSTR) return;
3746 if(tt!=Type::T_ERROR)
3747 loc->error("%s operand of operation `%s' should be octetstring value",
3748 opnum, opname);
3749 set_valuetype(V_ERROR);
3750 }
3751
3752 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3753 Type::typetype_t tt2,
3754 const char *opname)
3755 {
3756 if(valuetype==V_ERROR) return;
3757 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3758 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3759 set_valuetype(V_ERROR);
3760 return;
3761 }
3762 if(tt1==tt2) return;
3763 error("The operands of operation `%s' should be of same type", opname);
3764 set_valuetype(V_ERROR);
3765 }
3766
3767 /* For predefined functions. */
3768 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3769 Type::typetype_t tt2,
3770 const char *opnum1,
3771 const char *opnum2,
3772 const char *opname)
3773 {
3774 if(valuetype==V_ERROR) return;
3775 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3776 set_valuetype(V_ERROR);
3777 return;
3778 }
3779 if(tt1==tt2) return;
3780 error("The %s and %s operands of operation `%s' should be of same type",
3781 opnum1, opnum2, opname);
3782 set_valuetype(V_ERROR);
3783 }
3784
3785 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3786 Value *v1, Value *v2,
3787 const char *opnum1,
3788 const char *opnum2)
3789 {
3790 start:
3791 if (valuetype == V_ERROR) return;
3792 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3793 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3794 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3795
3796 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3797 set_valuetype(V_ERROR);
3798 return;
3799 }
3800 if (tt1 == Type::T_UNDEF) {
3801 if (tt2 == Type::T_UNDEF) {
3802 if (v1->is_undef_lowerid()) {
3803 if (v2->is_undef_lowerid()) {
3804 Scope *scope = get_my_scope();
3805 Module *my_mod = scope->get_scope_mod();
3806 const Identifier& id1 = v1->get_undef_lowerid();
3807 if (scope->has_ass_withId(id1)
3808 || my_mod->has_imported_ass_withId(id1)) {
3809 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3810 * should examine this situation better, but now I suppose
3811 * the first is ref, not enum. */
3812 v1->set_lowerid_to_ref();
3813 goto start;
3814 } else {
3815 const Identifier& id2 = v2->get_undef_lowerid();
3816 if (scope->has_ass_withId(id2)
3817 || my_mod->has_imported_ass_withId(id2)) {
3818 v2->set_lowerid_to_ref();
3819 goto start;
3820 }
3821 }
3822 /* This is perhaps enum-enum, but it has no real
3823 * significance, so this should be an error. */
3824 } else {
3825 v1->set_lowerid_to_ref();
3826 goto start;
3827 }
3828 } else if (v2->is_undef_lowerid()) {
3829 v2->set_lowerid_to_ref();
3830 goto start;
3831 }
3832 error("Cannot determine the type of the operands in operation `%s'",
3833 get_opname());
3834 set_valuetype(V_ERROR);
3835 return;
3836 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3837 v1->set_lowerid_to_ref();
3838 goto start;
3839 } else {
3840 /* v1 is something undefined, but not lowerid; v2 has
3841 * returntype (perhaps also governor) */
3842 }
3843 } else if (tt2 == Type::T_UNDEF) {
3844 /* but tt1 is not undef */
3845 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3846 v2->set_lowerid_to_ref();
3847 goto start;
3848 } else {
3849 /* v2 is something undefined, but not lowerid; v1 has
3850 * returntype (perhaps also governor) */
3851 }
3852 }
3853
3854 /* Now undef_lower_id's are converted to references, or the other
3855 * value has governor; let's see the governors, if they exist. */
3856 Type *t1 = v1->get_expr_governor(exp_val);
3857 Type *t2 = v2->get_expr_governor(exp_val);
3858 if (t1) {
3859 if (t2) {
3860 // Both value has governor. Are they compatible? According to 7.1.2
3861 // and C.34 it's required to have the same root types for
3862 // OPTYPE_{CONCAT,REPLACE}.
3863 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3864 u.expr.v_optype == OPTYPE_REPLACE);
3865 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
3866 u.expr.v_optype == OPTYPE_REPLACE);
3867 TypeChain l_chain1, l_chain2;
3868 TypeChain r_chain1, r_chain2;
3869 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
3870 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
3871 if (!compat_t1 && !compat_t2) {
3872 if (!info1.is_erroneous() && !info2.is_erroneous()) {
3873 // the subtypes don't need to be compatible here
3874 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
3875 error("The operands of operation `%s' should be of compatible "
3876 "types", get_opname());
3877 set_valuetype(V_ERROR);
3878 } else {
3879 if (info1.needs_conversion() || info2.needs_conversion()) {
3880 set_needs_conversion(); // Avoid folding.
3881 return;
3882 }
3883 }
3884 } else {
3885 if (info1.is_erroneous())
3886 v1->error("%s", info1.get_error_str_str().c_str());
3887 else if (info2.is_erroneous())
3888 v2->error("%s", info2.get_error_str_str().c_str());
3889 set_valuetype(V_ERROR);
3890 }
3891 return;
3892 } else if (info1.needs_conversion() || info2.needs_conversion()) {
3893 set_needs_conversion(); // Avoid folding.
3894 return;
3895 }
3896 } else {
3897 // t1, no t2.
3898 v2->set_my_governor(t1);
3899 t1->chk_this_value_ref(v2);
3900 if (v2->valuetype == V_OMIT) {
3901 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3902 get_opname());
3903 v1->chk_expr_omit_comparison(exp_val);
3904 } else {
3905 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3906 get_opname());
3907 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3908 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3909 goto start;
3910 }
3911 }
3912 } else if (t2) {
3913 v1->set_my_governor(t2);
3914 t2->chk_this_value_ref(v1);
3915 if (v1->valuetype == V_OMIT) {
3916 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3917 get_opname());
3918 v2->chk_expr_omit_comparison(exp_val);
3919 } else {
3920 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3921 get_opname());
3922 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3923 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3924 goto start;
3925 }
3926 } else {
3927 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3928 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
3929 // Here, it cannot be that both are T_UNDEF.
3930 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3931 error("Please use reference as %s operand of operator `%s'",
3932 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
3933 set_valuetype(V_ERROR);
3934 return;
3935 }
3936 // Deny type compatibility if no governors found. The typetype_t must
3937 // be the same. TODO: How can this happen?
3938 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
3939 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
3940 error("The operands of operation `%s' should be of compatible types",
3941 get_opname());
3942 set_valuetype(V_ERROR);
3943 }
3944 }
3945 }
3946
3947 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
3948 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
3949 {
3950 if(valuetype==V_ERROR) return;
3951 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3952 Assignment *t_ass = ref->get_refd_assignment();
3953 if(!t_ass) goto error;
3954 switch(t_ass->get_asstype()) {
3955 case Assignment::A_TIMER:
3956 case Assignment::A_PAR_TIMER:
3957 u.expr.v_optype=OPTYPE_TMR_RUNNING;
3958 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
3959 chk_expr_dynamic_part(exp_val, true);
3960 break;
3961 case Assignment::A_CONST:
3962 case Assignment::A_EXT_CONST:
3963 case Assignment::A_MODULEPAR:
3964 case Assignment::A_VAR:
3965 case Assignment::A_FUNCTION_RVAL:
3966 case Assignment::A_EXT_FUNCTION_RVAL:
3967 case Assignment::A_PAR_VAL_IN:
3968 case Assignment::A_PAR_VAL_OUT:
3969 case Assignment::A_PAR_VAL_INOUT: {
3970 u.expr.v_optype = OPTYPE_COMP_RUNNING;
3971 Value* val = new Value(V_REFD, u.expr.r1);
3972 val->set_my_scope(my_scope);
3973 val->set_fullname(u.expr.r1->get_fullname());
3974 val->set_location(*u.expr.r1);
3975 u.expr.v1 = val;
3976 chk_expr_operand_compref(val, opnum, get_opname());
3977 chk_expr_dynamic_part(exp_val, false);
3978 break; }
3979 default:
3980 ref->error("%s operand of operation `%s' should be timer or"
3981 " component reference instead of %s",
3982 opnum, opname, t_ass->get_description().c_str());
3983 goto error;
3984 } // switch
3985 return;
3986 error:
3987 set_valuetype(V_ERROR);
3988 }
3989
3990 Type *Value::chk_expr_operand_comptyperef_create()
3991 {
3992 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
3993 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
3994 Assignment *t_ass = u.expr.r1->get_refd_assignment();
3995 if (!t_ass) goto error;
3996 if (t_ass->get_asstype() == Assignment::A_TYPE) {
3997 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
3998 Type::EXPECTED_DYNAMIC_VALUE);
3999 if (!t_type) goto error;
4000 t_type = t_type->get_type_refd_last();
4001 if (t_type->get_typetype() == Type::T_COMPONENT) {
4002 if (my_governor) {
4003 Type *my_governor_last = my_governor->get_type_refd_last();
4004 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4005 !my_governor_last->is_compatible(t_type, NULL)) {
4006 u.expr.r1->error("Incompatible component types: operation "
4007 "`create' should refer to `%s' instead of "
4008 "`%s'",
4009 my_governor_last->get_typename().c_str(),
4010 t_type->get_typename().c_str());
4011 goto error;
4012 }
4013 }
4014 return t_type;
4015 } else {
4016 u.expr.r1->error("Type mismatch: reference to a component type was "
4017 "expected in operation `create' instead of `%s'",
4018 t_type->get_typename().c_str());
4019 }
4020 } else {
4021 u.expr.r1->error("Operation `create' should refer to a component type "
4022 "instead of %s", t_ass->get_description().c_str());
4023 }
4024 error:
4025 set_valuetype(V_ERROR);
4026 return NULL;
4027 }
4028
4029 void Value::chk_expr_comptype_compat()
4030 {
4031 if (valuetype != V_EXPR)
4032 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4033 if (!my_governor || !my_scope) return;
4034 Type *my_governor_last = my_governor->get_type_refd_last();
4035 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4036 Type *t_comptype;
4037 switch (u.expr.v_optype) {
4038 case OPTYPE_COMP_MTC:
4039 t_comptype = my_scope->get_mtc_system_comptype(false);
4040 break;
4041 case OPTYPE_COMP_SYSTEM:
4042 t_comptype = my_scope->get_mtc_system_comptype(true);
4043 break;
4044 case OPTYPE_COMP_SELF: {
4045 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4046 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4047 break; }
4048 default:
4049 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4050 t_comptype = 0;
4051 break;
4052 }
4053 if (t_comptype
4054 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4055 error("Incompatible component types: a component reference of "
4056 "type `%s' was expected, but `%s' has type `%s'",
4057 my_governor_last->get_typename().c_str(), get_opname(),
4058 t_comptype->get_typename().c_str());
4059 set_valuetype(V_ERROR);
4060 }
4061 }
4062
4063 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4064 const char *opname)
4065 {
4066 if(valuetype == V_ERROR) return;
4067 switch(val->get_valuetype()) {
4068 case V_INVOKE: {
4069 Error_Context cntxt(this, "In `%s' operation", opname);
4070 Value *v_last = val->get_value_refd_last();
4071 if(!v_last) goto error;
4072 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4073 if(!t) goto error;
4074 t = t->get_type_refd_last();
4075 if(t->get_typetype() != Type::T_COMPONENT) {
4076 v_last->error("%s operand of operation `%s': Type mismatch:"
4077 " component reference was expected instead of `%s'",
4078 opnum, opname, t->get_typename().c_str());
4079 goto error;
4080 }
4081 return; }
4082 case V_REFD: {
4083 Reference *ref = val->get_reference();
4084 Assignment *t_ass = ref->get_refd_assignment();
4085 Value *t_val = 0;
4086 if (!t_ass) goto error;
4087 switch(t_ass->get_asstype()) {
4088 case Assignment::A_CONST:
4089 t_val = t_ass->get_Value();
4090 // no break
4091 case Assignment::A_EXT_CONST:
4092 case Assignment::A_MODULEPAR:
4093 case Assignment::A_VAR:
4094 case Assignment::A_FUNCTION_RVAL:
4095 case Assignment::A_EXT_FUNCTION_RVAL:
4096 case Assignment::A_PAR_VAL_IN:
4097 case Assignment::A_PAR_VAL_OUT:
4098 case Assignment::A_PAR_VAL_INOUT: {
4099 Type *t_type=t_ass->get_Type()
4100 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4101 if(!t_type) goto error;
4102 t_type=t_type->get_type_refd_last();
4103 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4104 ref->error("%s operand of operation `%s': Type mismatch:"
4105 " component reference was expected instead of `%s'",
4106 opnum, opname, t_type->get_typename().c_str());
4107 goto error;
4108 }
4109 break;}
4110 default:
4111 ref->error("%s operand of operation `%s' should be"
4112 " component reference instead of %s",
4113 opnum, opname, t_ass->get_description().c_str());
4114 goto error;
4115 }
4116 if (t_val) {
4117 ReferenceChain refch(this, "While searching referenced value");
4118 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4119 if (!t_val) return;
4120 t_val = t_val->get_value_refd_last();
4121 if (t_val->valuetype != V_EXPR) return;
4122 switch (t_val->u.expr.v_optype) {
4123 case OPTYPE_COMP_NULL:
4124 ref->error("%s operand of operation `%s' refers to `null' component "
4125 "reference", opnum, opname);
4126 goto error;
4127 case OPTYPE_COMP_MTC:
4128 ref->error("%s operand of operation `%s' refers to the component "
4129 "reference of the `mtc'", opnum, opname);
4130 goto error;
4131 case OPTYPE_COMP_SYSTEM:
4132 ref->error("%s operand of operation `%s' refers to the component "
4133 "reference of the `system'", opnum, opname);
4134 goto error;
4135 default:
4136 break;
4137 }
4138 }
4139 return;}
4140 default:
4141 FATAL_ERROR("Value::chk_expr_operand_compref()");
4142 }
4143 error:
4144 set_valuetype(V_ERROR);
4145 }
4146
4147 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4148 const char *opnum,
4149 const char *opname)
4150 {
4151 if(valuetype==V_ERROR) return;
4152 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4153 Assignment *t_ass = ref->get_refd_assignment();
4154 if(!t_ass) goto error;
4155 switch(t_ass->get_asstype()) {
4156 case Assignment::A_TIMER: {
4157 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4158 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4159 Type::EXPECTED_DYNAMIC_VALUE);
4160 else if (ref->get_subrefs()) {
4161 ref->error("%s operand of operation `%s': "
4162 "Reference to single timer `%s' cannot have field or array "
4163 "sub-references", opnum, opname,
4164 t_ass->get_id().get_dispname().c_str());
4165 goto error;
4166 }
4167 break; }
4168 case Assignment::A_PAR_TIMER:
4169 if (ref->get_subrefs()) {
4170 ref->error("%s operand of operation `%s': "
4171 "Reference to %s cannot have field or array sub-references",
4172 opnum, opname, t_ass->get_description().c_str());
4173 goto error;
4174 }
4175 break;
4176 default:
4177 ref->error("%s operand of operation `%s' should be timer"
4178 " instead of %s",
4179 opnum, opname, t_ass->get_description().c_str());
4180 goto error;
4181 } // switch
4182 return;
4183 error:
4184 set_valuetype(V_ERROR);
4185 }
4186
4187 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4188 const char *,
4189 const char *opname)
4190 {
4191 if(valuetype==V_ERROR) return;
4192 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4193 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4194 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4195 Error_Context cntxt(this, "In `%s' operation", opname);
4196 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4197 }
4198
4199 void Value::chk_expr_operand_activate_refd(Value *val,
4200 Ttcn::TemplateInstances* t_list2,
4201 Ttcn::ActualParList *&parlist,
4202 const char *,
4203 const char *opname)
4204 {
4205 if(valuetype==V_ERROR) return;
4206 Error_Context cntxt(this, "In `%s' operation", opname);
4207 Type *t = val->get_expr_governor_last();
4208 if (t) {
4209 switch (t->get_typetype()) {
4210 case Type::T_ERROR:
4211 set_valuetype(V_ERROR);
4212 break;
4213 case Type::T_ALTSTEP: {
4214 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4215 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4216 if(is_erroneous) {
4217 delete parlist;
4218 parlist = 0;
4219 set_valuetype(V_ERROR);
4220 } else {
4221 parlist->set_fullname(get_fullname());
4222 parlist->set_my_scope(get_my_scope());
4223 if (!fp_list->chk_activate_argument(parlist,
4224 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4225 }
4226 break; }
4227 default:
4228 error("Reference to an altstep was expected in the argument of "
4229 "`derefers()' instead of `%s'", t->get_typename().c_str());
4230 set_valuetype(V_ERROR);
4231 break;
4232 }
4233 } else set_valuetype(V_ERROR);
4234 }
4235
4236 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4237 const char *,
4238 const char *opname)
4239 {
4240 if(valuetype==V_ERROR) return;
4241 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4242 Error_Context cntxt(this, "In `%s' operation", opname);
4243 Assignment *t_ass = ref->get_refd_assignment();
4244 bool error_flag = false;
4245 if (t_ass) {
4246 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4247 ref->error("Reference to a testcase was expected in the argument "
4248 "instead of %s", t_ass->get_description().c_str());
4249 error_flag = true;
4250 }
4251 } else error_flag = true;
4252 if (val) {
4253 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4254 Value *v_last = val->get_value_refd_last();
4255 switch (v_last->valuetype) {
4256 case V_REAL: {
4257 ttcn3float v_real = v_last->get_val_Real();
4258 if (v_real < 0.0) {
4259 val->error("The testcase guard timer has negative value: `%s'",
4260 Real2string(v_real).c_str());
4261 error_flag = true;
4262 }
4263 break; }
4264 case V_ERROR:
4265 error_flag = true;
4266 break;
4267 default:
4268 break;
4269 }
4270 }
4271 if (error_flag) set_valuetype(V_ERROR);
4272 }
4273
4274 void Value::chk_expr_operand_execute_refd(Value *v1,
4275 Ttcn::TemplateInstances* t_list2,
4276 Ttcn::ActualParList *&parlist,
4277 Value *v3,
4278 const char *,
4279 const char *opname)
4280 {
4281 if(valuetype==V_ERROR) return;
4282 Error_Context cntxt(this, "In `%s' operation", opname);
4283 Type *t = v1->get_expr_governor_last();
4284 if (t) {
4285 switch (t->get_typetype()) {
4286 case Type::T_ERROR:
4287 set_valuetype(V_ERROR);
4288 break;
4289 case Type::T_TESTCASE: {
4290 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4291 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4292 if(is_erroneous) {
4293 delete parlist;
4294 parlist = 0;
4295 set_valuetype(V_ERROR);
4296 } else {
4297 parlist->set_fullname(get_fullname());
4298 parlist->set_my_scope(get_my_scope());
4299 }
4300 break; }
4301 default:
4302 v1->error("Reference to a value of type testcase was expected in the "
4303 "argument of `derefers()' instead of `%s'",
4304 t->get_typename().c_str());
4305 set_valuetype(V_ERROR);
4306 break;
4307 }
4308 } else set_valuetype(V_ERROR);
4309 if (v3) {
4310 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4311 Value *v_last = v3->get_value_refd_last();
4312 switch (v_last->valuetype) {
4313 case V_REAL: {
4314 ttcn3float v_real = v_last->get_val_Real();
4315 if(v_real < 0.0) {
4316 v3->error("The testcase guard timer has negative value: `%s'",
4317 Real2string(v_real).c_str());
4318 set_valuetype(V_ERROR);
4319 }
4320 break; }
4321 case V_ERROR:
4322 set_valuetype(V_ERROR);
4323 break;
4324 default:
4325 break;
4326 }
4327 }
4328 }
4329
4330 void Value::chk_invoke(Type::expected_value_t exp_val)
4331 {
4332 if(valuetype == V_ERROR) return;
4333 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4334 if(!u.invoke.t_list) return; //already checked
4335 Error_Context cntxt(this, "In `apply()' operation");
4336 Type *t = u.invoke.v->get_expr_governor_last();
4337 if (!t) {
4338 set_valuetype(V_ERROR);
4339 return;
4340 }
4341 switch (t->get_typetype()) {
4342 case Type::T_ERROR:
4343 set_valuetype(V_ERROR);
4344 return;
4345 case Type::T_FUNCTION:
4346 break;
4347 default:
4348 u.invoke.v->error("A value of type function was expected in the "
4349 "argument instead of `%s'", t->get_typename().c_str());
4350 set_valuetype(V_ERROR);
4351 return;
4352 }
4353 my_scope->chk_runs_on_clause(t, *this, "call");
4354 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4355 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4356 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4357 delete u.invoke.t_list;
4358 u.invoke.t_list = 0;
4359 if(is_erroneous) {
4360 delete parlist;
4361 u.invoke.ap_list = 0;
4362 } else {
4363 parlist->set_fullname(get_fullname());
4364 parlist->set_my_scope(get_my_scope());
4365 u.invoke.ap_list = parlist;
4366 }
4367 switch (exp_val) {
4368 case Type::EXPECTED_CONSTANT:
4369 error("An evaluatable constant value was expected instead of operation "
4370 "`apply()'");
4371 set_valuetype(V_ERROR);
4372 break;
4373 case Type::EXPECTED_STATIC_VALUE:
4374 error("A static value was expected instead of operation `apply()'");
4375 set_valuetype(V_ERROR);
4376 break;
4377 default:
4378 break;
4379 } // switch
4380 }
4381
4382 void Value::chk_expr_eval_value(Value *val, Type &t,
4383 ReferenceChain *refch,
4384 Type::expected_value_t exp_val)
4385 {
4386 bool self_ref = false;
4387 if(valuetype==V_ERROR) return;
4388 // Commented out to report more errors :)
4389 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4390 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4391 switch(val->get_valuetype()) {
4392 case V_REFD:
4393 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4394 break;
4395 case V_EXPR:
4396 case V_MACRO:
4397 case V_INVOKE:
4398 val->get_value_refd_last(refch, exp_val);
4399 break;
4400 default:
4401 break;
4402 } // switch
4403 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4404
4405 (void)self_ref;
4406 }
4407
4408 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4409 ReferenceChain *refch, Type::expected_value_t exp_val)
4410 {
4411 bool self_ref = false;
4412 ti->chk(type);
4413 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4414 ti->error("Reference to a %s value was expected instead of an in-line "
4415 "modified template",
4416 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4417 set_valuetype(V_ERROR);
4418 return;
4419 }
4420 Template *templ = ti->get_Template();
4421 switch (templ->get_templatetype()) {
4422 case Template::TEMPLATE_REFD:
4423 // not foldable
4424 if (exp_val == Type::EXPECTED_TEMPLATE) {
4425 templ = templ->get_template_refd_last(refch);
4426 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4427 set_valuetype(V_ERROR);
4428 } else {
4429 ti->error("Reference to a %s value was expected instead of %s",
4430 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4431 templ->get_reference()->get_refd_assignment()
4432 ->get_description().c_str());
4433 set_valuetype(V_ERROR);
4434 }
4435 break;
4436 case Template::SPECIFIC_VALUE: {
4437 Value *val = templ->get_specific_value();
4438 switch (val->get_valuetype()) {
4439 case V_REFD:
4440 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4441 break;
4442 case V_EXPR:
4443 val->get_value_refd_last(refch, exp_val);
4444 default:
4445 break;
4446 } // switch
4447 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4448 break; }
4449 case Template::TEMPLATE_ERROR:
4450 set_valuetype(V_ERROR);
4451 break;
4452 default:
4453 break;
4454 } // switch
4455
4456 (void)self_ref;
4457 }
4458
4459 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4460 const char *opname)
4461 {
4462 if(valuetype==V_ERROR) return;
4463 if(u.expr.state==EXPR_CHECKING_ERR) return;
4464 if(val->is_unfoldable()) return;
4465 if(*val->get_val_Int()<0) {
4466 val->error("%s operand of operation `%s' should not be negative",
4467 opnum, opname);
4468 set_valuetype(V_ERROR);
4469 }
4470 }
4471
4472 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4473 const char *opname)
4474 {
4475 if(valuetype==V_ERROR) return;
4476 if(u.expr.state==EXPR_CHECKING_ERR) return;
4477 if(val->is_unfoldable()) return;
4478 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4479 val->error("%s operand of operation `%s' should be in range 0..127",
4480 opnum, opname);
4481 set_valuetype(V_ERROR);
4482 }
4483 }
4484
4485 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4486 const char *opname)
4487 {
4488 if(valuetype==V_ERROR) return;
4489 if(u.expr.state==EXPR_CHECKING_ERR) return;
4490 if(val->is_unfoldable()) return;
4491 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4492 val->error("%s operand of operation `%s' should be in range"
4493 " 0..2147483647", opnum, opname);
4494 set_valuetype(V_ERROR);
4495 }
4496 }
4497
4498 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4499 const char *opname)
4500 {
4501 if(valuetype==V_ERROR) return;
4502 if(u.expr.state==EXPR_CHECKING_ERR) return;
4503 if(val->is_unfoldable()) return;
4504 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4505 ||
4506 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4507 {
4508 val->error("%s operand of operation `%s' should not be zero",
4509 opnum, opname);
4510 set_valuetype(V_ERROR);
4511 }
4512 }
4513
4514 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4515 const char *opname)
4516 {
4517 if (valuetype == V_ERROR) return;
4518 if (u.expr.state == EXPR_CHECKING_ERR) return;
4519 if (val->get_expr_returntype() != Type::T_INT) return;
4520 if (val->is_unfoldable()) return;
4521 const int_val_t *val_int = val->get_val_Int();
4522 if (*val_int > static_cast<Int>(INT_MAX)) {
4523 val->error("%s operand of operation `%s' should be less than `%d' "
4524 "instead of `%s'", opnum, opname, INT_MAX,
4525 (val_int->t_str()).c_str());
4526 set_valuetype(V_ERROR);
4527 }
4528 }
4529
4530 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4531 const char *opname)
4532 {
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_strlen()!=1) {
4537 val->error("%s operand of operation `%s' should be of length 1",
4538 opnum, opname);
4539 set_valuetype(V_ERROR);
4540 }
4541 }
4542
4543 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4544 const char *opname)
4545 {
4546 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4547 Value *v_last = val->get_value_refd_last();
4548 if (v_last->valuetype == V_CSTR) {
4549 size_t len = v_last->get_val_strlen();
4550 if (len % 2) {
4551 val->error("%s operand of operation `%s' should contain even number "
4552 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4553 set_valuetype(V_ERROR);
4554 }
4555 } else if (v_last->valuetype == V_REFD) {
4556 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4557 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4558 val->error("%s operand of operation `%s' should contain even number "
4559 "of characters, but a string element contains 1", opnum, opname);
4560 set_valuetype(V_ERROR);
4561 }
4562 }
4563 }
4564
4565 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4566 const char *opname)
4567 {
4568 if(valuetype==V_ERROR) return;
4569 if(u.expr.state==EXPR_CHECKING_ERR) return;
4570 if(val->is_unfoldable()) return;
4571 const string& s=val->get_val_str();
4572 for(size_t i=0; i<s.size(); i++) {
4573 char c=s[i];
4574 if(!(c=='0' || c=='1')) {
4575 val->error("%s operand of operation `%s' can contain only"
4576 " binary digits (position %lu is `%c')",
4577 opnum, opname, (unsigned long) i, c);
4578 set_valuetype(V_ERROR);
4579 return;
4580 }
4581 }
4582 }
4583
4584 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4585 const char *opname)
4586 {
4587 if(valuetype==V_ERROR) return;
4588 if(u.expr.state==EXPR_CHECKING_ERR) return;
4589 if(val->is_unfoldable()) return;
4590 const string& s=val->get_val_str();
4591 for(size_t i=0; i<s.size(); i++) {
4592 char c=s[i];
4593 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4594 val->error("%s operand of operation `%s' can contain only valid "
4595 "hexadecimal digits (position %lu is `%c')",
4596 opnum, opname, (unsigned long) i, c);
4597 set_valuetype(V_ERROR);
4598 return;
4599 }
4600 }
4601 }
4602
4603 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4604 const char *opname)
4605 {
4606 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4607 Value *v = val->get_value_refd_last();
4608 if (v->valuetype != V_OSTR) return;
4609 const string& s = val->get_val_str();
4610 size_t n_octets = s.size() / 2;
4611 for (size_t i = 0; i < n_octets; i++) {
4612 char c = s[2 * i];
4613 if (!(c >= '0' && c <= '7')) {
4614 val->error("%s operand of operation `%s' shall consist of octets "
4615 "within the range 00 .. 7F, but the string `%s'O contains octet "
4616 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4617 (unsigned long) i);
4618 set_valuetype(V_ERROR);
4619 return;
4620 }
4621 }
4622 }
4623
4624 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4625 const char *opname)
4626 {
4627 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4628 Value *v_last = val->get_value_refd_last();
4629 if (v_last->valuetype != V_CSTR) return;
4630 const string& s = v_last->get_val_str();
4631 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4632 state = S_INITIAL;
4633 // state: expected characters
4634 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4635 // S_FIRST: first digit
4636 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4637 // S_END: trailing whitespace
4638 // S_ERR: error was found, stop
4639 for (size_t i = 0; i < s.size(); i++) {
4640 char c = s[i];
4641 switch (state) {
4642 case S_INITIAL:
4643 case S_INITIAL_WS:
4644 if (c == '+' || c == '-') state = S_FIRST;
4645 else if (c == '0') state = S_ZERO;
4646 else if (c >= '1' && c <= '9') state = S_MORE;
4647 else if (string::is_whitespace(c)) {
4648 if (state == S_INITIAL) {
4649 val->warning("Leading whitespace was detected and ignored in the "
4650 "operand of operation `%s'", opname);
4651 state = S_INITIAL_WS;
4652 }
4653 } else state = S_ERR;
4654 break;
4655 case S_FIRST:
4656 if (c == '0') state = S_ZERO;
4657 else if (c >= '1' && c <= '9') state = S_MORE;
4658 else state = S_ERR;
4659 break;
4660 case S_ZERO:
4661 if (c >= '0' && c <= '9') {
4662 val->warning("Leading zero digit was detected and ignored in the "
4663 "operand of operation `%s'", opname);
4664 state = S_MORE;
4665 } else if (string::is_whitespace(c)) state = S_END;
4666 else state = S_ERR;
4667 break;
4668 case S_MORE:
4669 if (c >= '0' && c <= '9') {}
4670 else if (string::is_whitespace(c)) state = S_END;
4671 else state = S_ERR;
4672 break;
4673 case S_END:
4674 if (!string::is_whitespace(c)) state = S_ERR;
4675 break;
4676 default:
4677 break;
4678 }
4679 if (state == S_ERR) {
4680 if (string::is_printable(c)) {
4681 val->error("%s operand of operation `%s' should be a string "
4682 "containing a valid integer value, but invalid character `%c' "
4683 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4684 } else {
4685 val->error("%s operand of operation `%s' should be a string "
4686 "containing a valid integer value, but invalid character with "
4687 "character code %u was detected at index %lu", opnum, opname, c,
4688 (unsigned long) i);
4689 }
4690 set_valuetype(V_ERROR);
4691 break;
4692 }
4693 }
4694 switch (state) {
4695 case S_INITIAL:
4696 case S_INITIAL_WS:
4697 val->error("%s operand of operation `%s' should be a string containing a "
4698 "valid integer value instead of an empty string", opnum, opname);
4699 set_valuetype(V_ERROR);
4700 break;
4701 case S_FIRST:
4702 val->error("%s operand of operation `%s' should be a string containing a "
4703 "valid integer value, but only a sign character was detected", opnum,
4704 opname);
4705 set_valuetype(V_ERROR);
4706 break;
4707 case S_END:
4708 val->warning("Trailing whitespace was detected and ignored in the "
4709 "operand of operation `%s'", opname);
4710 break;
4711 default:
4712 break;
4713 }
4714 }
4715
4716 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4717 const char *opname)
4718 {
4719 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4720 Value *v_last = val->get_value_refd_last();
4721 if (v_last->valuetype == V_REFD) {
4722 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4723 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4724 val->error("%s operand of operation `%s' should be a string containing "
4725 "a valid float value instead of a string element, which cannot "
4726 "represent a floating point number", opnum, opname);
4727 set_valuetype(V_ERROR);
4728 }
4729 return;
4730 } else if (v_last->valuetype != V_CSTR) return;
4731 const string& s = v_last->get_val_str();
4732 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4733 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4734 state = S_INITIAL;
4735 // state: expected characters
4736 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4737 // leading whitespace
4738 // S_FIRST_M: first digit of integer part in mantissa
4739 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4740 // S_FIRST_F: first digit of fraction
4741 // S_MORE_F: more digits of fraction, E, trailing whitespace
4742 // S_INITIAL_E: +, -, first digit of exponent
4743 // S_FIRST_E: first digit of exponent
4744 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4745 // S_END: trailing whitespace
4746 // S_ERR: error was found, stop
4747 for (size_t i = 0; i < s.size(); i++) {
4748 char c = s[i];
4749 switch (state) {
4750 case S_INITIAL:
4751 case S_INITIAL_WS:
4752 if (c == '+' || c == '-') state = S_FIRST_M;
4753 else if (c == '0') state = S_ZERO_M;
4754 else if (c >= '1' && c <= '9') state = S_MORE_M;
4755 else if (string::is_whitespace(c)) {
4756 if (state == S_INITIAL) {
4757 val->warning("Leading whitespace was detected and ignored in the "
4758 "operand of operation `%s'", opname);
4759 state = S_INITIAL_WS;
4760 }
4761 } else state = S_ERR;
4762 break;
4763 case S_FIRST_M:
4764 if (c == '0') state = S_ZERO_M;
4765 else if (c >= '1' && c <= '9') state = S_MORE_M;
4766 else state = S_ERR;
4767 break;
4768 case S_ZERO_M:
4769 if (c == '.') state = S_FIRST_F;
4770 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4771 else if (c >= '0' && c <= '9') {
4772 val->warning("Leading zero digit was detected and ignored in the "
4773 "mantissa of the operand of operation `%s'", opname);
4774 state = S_MORE_M;
4775 } else state = S_ERR;
4776 break;
4777 case S_MORE_M:
4778 if (c == '.') state = S_FIRST_F;
4779 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4780 else if (c >= '0' && c <= '9') {}
4781 else state = S_ERR;
4782 break;
4783 case S_FIRST_F:
4784 if (c >= '0' && c <= '9') state = S_MORE_F;
4785 else state = S_ERR;
4786 break;
4787 case S_MORE_F:
4788 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4789 else if (c >= '0' && c <= '9') {}
4790 else if (string::is_whitespace(c)) state = S_END;
4791 else state = S_ERR;
4792 break;
4793 case S_INITIAL_E:
4794 if (c == '+' || c == '-') state = S_FIRST_E;
4795 else if (c == '0') state = S_ZERO_E;
4796 else if (c >= '1' && c <= '9') state = S_MORE_E;
4797 else state = S_ERR;
4798 break;
4799 case S_FIRST_E:
4800 if (c == '0') state = S_ZERO_E;
4801 else if (c >= '1' && c <= '9') state = S_MORE_E;
4802 else state = S_ERR;
4803 break;
4804 case S_ZERO_E:
4805 if (c >= '0' && c <= '9') {
4806 val->warning("Leading zero digit was detected and ignored in the "
4807 "exponent of the operand of operation `%s'", opname);
4808 state = S_MORE_E;
4809 } else if (string::is_whitespace(c)) state = S_END;
4810 else state = S_ERR;
4811 break;
4812 case S_MORE_E:
4813 if (c >= '0' && c <= '9') {}
4814 else if (string::is_whitespace(c)) state = S_END;
4815 else state = S_ERR;
4816 break;
4817 case S_END:
4818 if (!string::is_whitespace(c)) state = S_ERR;
4819 break;
4820 default:
4821 break;
4822 }
4823 if (state == S_ERR) {
4824 if (string::is_printable(c)) {
4825 val->error("%s operand of operation `%s' should be a string "
4826 "containing a valid float value, but invalid character `%c' "
4827 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4828 } else {
4829 val->error("%s operand of operation `%s' should be a string "
4830 "containing a valid float value, but invalid character with "
4831 "character code %u was detected at index %lu", opnum, opname, c,
4832 (unsigned long) i);
4833 }
4834 set_valuetype(V_ERROR);
4835 break;
4836 }
4837 }
4838 switch (state) {
4839 case S_INITIAL:
4840 case S_INITIAL_WS:
4841 val->error("%s operand of operation `%s' should be a string containing a "
4842 "valid float value instead of an empty string", opnum, opname);
4843 set_valuetype(V_ERROR);
4844 break;
4845 case S_FIRST_M:
4846 val->error("%s operand of operation `%s' should be a string containing a "
4847 "valid float value, but only a sign character was detected", opnum,
4848 opname);
4849 set_valuetype(V_ERROR);
4850 break;
4851 case S_ZERO_M:
4852 case S_MORE_M:
4853 // HL67862: Missing decimal dot allowed for str2float
4854 break;
4855 case S_FIRST_F:
4856 // HL67862: Missing fraction part is allowed for str2float
4857 break;
4858 case S_INITIAL_E:
4859 case S_FIRST_E:
4860 val->error("%s operand of operation `%s' should be a string containing a "
4861 "valid float value, but the exponent is missing after the `E' sign",
4862 opnum, opname);
4863 set_valuetype(V_ERROR);
4864 break;
4865 case S_END:
4866 val->warning("Trailing whitespace was detected and ignored in the "
4867 "operand of operation `%s'", opname);
4868 break;
4869 default:
4870 break;
4871 }
4872 }
4873
4874 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
4875 const char *opname)
4876 {
4877 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4878 Value *v = val->get_value_refd_last();
4879 if (v->valuetype != V_USTR) return;
4880 const ustring& us = v->get_val_ustr();
4881 for (size_t i = 0; i < us.size(); i++) {
4882 const ustring::universal_char& uchar = us[i];
4883 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
4884 uchar.cell > 127) {
4885 val->error("%s operand of operation `%s' shall consist of characters "
4886 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4887 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4888 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
4889 uchar.row, uchar.cell, (unsigned long) i);
4890 set_valuetype(V_ERROR);
4891 return;
4892 }
4893 }
4894 }
4895
4896 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
4897 const char *opname)
4898 {
4899 if(valuetype==V_ERROR) return;
4900 if(u.expr.state==EXPR_CHECKING_ERR) return;
4901 if(val->is_unfoldable()) return;
4902 const string& bstr=val->get_val_str();
4903 // see also PredefFunc.cc::bit2int()
4904 size_t nof_bits = bstr.size();
4905 // skip the leading zeros
4906 size_t start_index = 0;
4907 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
4908 // check whether the remaining bits fit in Int
4909 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
4910 val->error("%s operand of operation `%s' is too large (maximum number"
4911 " of bits in integer is %lu)",
4912 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4913 set_valuetype(V_ERROR);
4914 }
4915 }
4916
4917 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
4918 const char *opname)
4919 {
4920 if(valuetype==V_ERROR) return;
4921 if(u.expr.state==EXPR_CHECKING_ERR) return;
4922 if(val->is_unfoldable()) return;
4923 const string& hstr=val->get_val_str();
4924 // see also PredefFunc.cc::hex2int()
4925 size_t nof_digits = hstr.size();
4926 // skip the leading zeros
4927 size_t start_index = 0;
4928 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
4929 // check whether the remaining hex digits fit in Int
4930 if (nof_digits - start_index > 2 * sizeof(Int) ||
4931 (nof_digits - start_index == 2 * sizeof(Int) &&
4932 char_to_hexdigit(hstr[start_index]) > 7)) {
4933 val->error("%s operand of operation `%s' is too large (maximum number"
4934 " of bits in integer is %lu)",
4935 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4936 set_valuetype(V_ERROR);
4937 }
4938 }
4939
4940 void Value::chk_expr_operands_int2binstr()
4941 {
4942 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4943 if (u.expr.v1->is_unfoldable()) return;
4944 if (u.expr.v2->is_unfoldable()) return;
4945 // It is already checked that i1 and i2 are non-negative.
4946 Error_Context cntxt(this, "In operation `%s'", get_opname());
4947 const int_val_t *i1 = u.expr.v1->get_val_Int();
4948 const int_val_t *i2 = u.expr.v2->get_val_Int();
4949 if (!i2->is_native()) {
4950 u.expr.v2->error("The length of the resulting string is too large for "
4951 "being represented in memory");
4952 set_valuetype(V_ERROR);
4953 return;
4954 }
4955 Int nof_bits = i2->get_val();
4956 if (u.expr.v1->is_unfoldable()) return;
4957 switch (u.expr.v_optype) {
4958 case OPTYPE_INT2BIT:
4959 break;
4960 case OPTYPE_INT2HEX:
4961 nof_bits *= 4;
4962 break;
4963 case OPTYPE_INT2OCT:
4964 nof_bits *= 8;
4965 break;
4966 default:
4967 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4968 }
4969 if (*i1 >> nof_bits > 0) { // Expensive?
4970 u.expr.v1->error("Value %s does not fit in length %s",
4971 i1->t_str().c_str(), i2->t_str().c_str());
4972 set_valuetype(V_ERROR);
4973 }
4974 }
4975
4976 void Value::chk_expr_operands_str_samelen()
4977 {
4978 if(valuetype==V_ERROR) return;
4979 if(u.expr.state==EXPR_CHECKING_ERR) return;
4980 Value *v1=u.expr.v1;
4981 if(v1->is_unfoldable()) return;
4982 Value *v2=u.expr.v2;
4983 if(v2->is_unfoldable()) return;
4984 Error_Context cntxt(this, "In operation `%s'", get_opname());
4985 size_t i1=v1->get_val_strlen();
4986 size_t i2=v2->get_val_strlen();
4987 if(i1!=i2) {
4988 error("The operands should have the same length");
4989 set_valuetype(V_ERROR);
4990 }
4991 }
4992
4993 void Value::chk_expr_operands_replace()
4994 {
4995 // The fourth operand doesn't need to be checked at all here.
4996 if(valuetype==V_ERROR) return;
4997 if(u.expr.state==EXPR_CHECKING_ERR) return;
4998 Value* v1 = u.expr.ti1->get_specific_value();
4999 if (!v1) return;
5000
5001 Error_Context cntxt(this, "In operation `%s'", get_opname());
5002 size_t list_len = 0;
5003 bool list_len_known = false;
5004 if (v1->valuetype == V_REFD) {
5005 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5006 if (subrefs && subrefs->refers_to_string_element()) {
5007 warning("Replacing a string element does not make any sense");
5008 list_len = 1;
5009 list_len_known = true;
5010 }
5011 }
5012 if (!v1->is_unfoldable()) {
5013 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5014 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5015 list_len_known = true;
5016 }
5017 if (!list_len_known) return;
5018 if (u.expr.v2->is_unfoldable()) {
5019 if (!u.expr.v3->is_unfoldable()) {
5020 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5021 if (*len_int_3 > static_cast<Int>(list_len)) {
5022 error("Third operand `len' (%s) is greater than the length of "
5023 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5024 (unsigned long)list_len);
5025 set_valuetype(V_ERROR);
5026 }
5027 }
5028 } else {
5029 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5030 if (u.expr.v3->is_unfoldable()) {
5031 if (*index_int_2 > static_cast<Int>(list_len)) {
5032 error("Second operand `index' (%s) is greater than the length of "
5033 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5034 (unsigned long)list_len);
5035 set_valuetype(V_ERROR);
5036 }
5037 } else {
5038 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5039 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5040 error("The sum of second operand `index' (%s) and third operand "
5041 "`len' (%s) is greater than the length of the first operand (%lu)",
5042 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5043 (unsigned long)list_len);
5044 set_valuetype(V_ERROR);
5045 }
5046 }
5047 }
5048 }
5049
5050 void Value::chk_expr_operands_substr()
5051 {
5052 if(valuetype==V_ERROR) return;
5053 if(u.expr.state==EXPR_CHECKING_ERR) return;
5054 Value* v1 = u.expr.ti1->get_specific_value();
5055 if (!v1) return;
5056
5057 Error_Context cntxt(this, "In operation `%s'", get_opname());
5058 size_t list_len = 0;
5059 bool list_len_known = false;
5060 if (v1->valuetype == V_REFD) {
5061 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5062 if (subrefs && subrefs->refers_to_string_element()) {
5063 warning("Taking the substring of a string element does not make any "
5064 "sense");
5065 list_len = 1;
5066 list_len_known = true;
5067 }
5068 }
5069 if (!list_len_known && !v1->is_unfoldable()) {
5070 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5071 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5072 list_len_known = true;
5073 }
5074 // Do nothing if the length of the first operand is unknown.
5075 if (!list_len_known) return;
5076 if (u.expr.v2->is_unfoldable()) {
5077 if (!u.expr.v3->is_unfoldable()) {
5078 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5079 // Only the third operand is known.
5080 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5081 error("Third operand `returncount' (%s) is greater than the "
5082 "length of the first operand (%lu)",
5083 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5084 set_valuetype(V_ERROR);
5085 }
5086 }
5087 } else {
5088 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5089 if (u.expr.v3->is_unfoldable()) {
5090 // Only the second operand is known.
5091 if (*index_int_2 > static_cast<Int>(list_len)) {
5092 error("Second operand `index' (%s) is greater than the length "
5093 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5094 (unsigned long)list_len);
5095 set_valuetype(V_ERROR);
5096 }
5097 } else {
5098 // Both second and third operands are known.
5099 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5100 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5101 error("The sum of second operand `index' (%s) and third operand "
5102 "`returncount' (%s) is greater than the length of the first operand "
5103 "(%lu)", (index_int_2->t_str()).c_str(),
5104 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5105 set_valuetype(V_ERROR);
5106 }
5107 }
5108 }
5109 }
5110
5111 void Value::chk_expr_operands_regexp()
5112 {
5113 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5114 Value* v1 = u.expr.ti1->get_specific_value();
5115 Value* v2 = u.expr.t2->get_specific_value();
5116 if (!v1 || !v2) return;
5117
5118 Error_Context cntxt(this, "In operation `regexp()'");
5119 Value* v1_last = v1->get_value_refd_last();
5120 if (v1_last->valuetype == V_CSTR) {
5121 // the input string is available at compile time
5122 const string& instr = v1_last->get_val_str();
5123 const char *input_str = instr.c_str();
5124 size_t instr_len = strlen(input_str);
5125 if (instr_len < instr.size()) {
5126 v1->warning("The first operand of `regexp()' contains a "
5127 "character with character code zero at index %s. The rest of the "
5128 "string will be ignored during matching",
5129 Int2string(instr_len).c_str());
5130 }
5131 }
5132
5133 size_t nof_groups = 0;
5134 Value *v2_last = v2->get_value_refd_last();
5135
5136 if (v2_last->valuetype == V_CSTR) {
5137 // the pattern is available at compile time
5138 const string& expression = v2_last->get_val_str();
5139 const char *pattern_str = expression.c_str();
5140 size_t pattern_len = strlen(pattern_str);
5141 if (pattern_len < expression.size()) {
5142 v2->warning("The second operand of `regexp()' contains a "
5143 "character with character code zero at index %s. The rest of the "
5144 "string will be ignored during matching",
5145 Int2string(pattern_len).c_str());
5146 }
5147 char *posix_str;
5148 {
5149 Error_Context cntxt2(v2, "In character string pattern");
5150 posix_str = TTCN_pattern_to_regexp(pattern_str);
5151 }
5152 if (posix_str != NULL) {
5153 regex_t posix_regexp;
5154 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5155 if (ret_val != 0) {
5156 char msg[512];
5157 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5158 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5159 "regcomp() failed: %s", msg);
5160 }
5161 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5162 else {
5163 v2->error("The character pattern in the second operand of "
5164 "`regexp()' does not contain any groups");
5165 set_valuetype(V_ERROR);
5166 }
5167 regfree(&posix_regexp);
5168 Free(posix_str);
5169 } else {
5170 // the pattern is faulty
5171 // the error has been reported by TTCN_pattern_to_regexp
5172 set_valuetype(V_ERROR);
5173 }
5174 }
5175 if (nof_groups > 0) {
5176 Value *v3 = u.expr.v3->get_value_refd_last();
5177 if (v3->valuetype == V_INT) {
5178 // the group number is available at compile time
5179 const int_val_t *groupno_int = v3->get_val_Int();
5180 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5181 u.expr.v3->error("The the third operand of `regexp()' is too "
5182 "large: The requested group index is %s, but the pattern "
5183 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5184 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5185 set_valuetype(V_ERROR);
5186 }
5187 }
5188 }
5189 }
5190
5191 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5192 Type::expected_value_t exp_val)
5193 {
5194 const char *opname = get_opname();
5195 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5196 Type *t_governor;
5197 const Location *loc;
5198 bool error_flag = false;
5199 switch (u.expr.v_optype) {
5200 case OPTYPE_ISCHOSEN_V:
5201 // u.expr.v1 is always a referenced value
5202 t_governor = u.expr.v1->get_expr_governor(exp_val);
5203 if (t_governor) {
5204 u.expr.v1->set_my_governor(t_governor);
5205 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5206 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5207 } else error_flag = true;
5208 loc = u.expr.v1;
5209 break;
5210 case OPTYPE_ISCHOSEN_T:
5211 // u.expr.t1 is always a referenced template
5212 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5213 exp_val = Type::EXPECTED_TEMPLATE;
5214 t_governor = u.expr.t1->get_expr_governor(exp_val);
5215 if (t_governor) {
5216 u.expr.t1->set_my_governor(t_governor);
5217 //
5218 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5219 //
5220 u.expr.t1->get_template_refd_last(refch);
5221 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5222 error_flag = true;
5223 } else error_flag = true;
5224 if (exp_val != Type::EXPECTED_TEMPLATE) {
5225 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5226 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5227 u.expr.t1->get_reference()->get_refd_assignment()
5228 ->get_description().c_str());
5229 error_flag = true;
5230 }
5231 loc = u.expr.t1;
5232 break;
5233 default:
5234 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5235 t_governor = 0;
5236 loc = 0;
5237 }
5238 if (t_governor) {
5239 t_governor = t_governor->get_type_refd_last();
5240 switch (t_governor->get_typetype()) {
5241 case Type::T_ERROR:
5242 error_flag = true;
5243 break;
5244 case Type::T_CHOICE_A:
5245 case Type::T_CHOICE_T:
5246 case Type::T_ANYTYPE:
5247 case Type::T_OPENTYPE:
5248 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5249 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5250 "%s does not have a field named `%s'" :
5251 "Union type `%s' does not have a field named `%s'",
5252 t_governor->get_typename().c_str(),
5253 u.expr.i2->get_dispname().c_str());
5254 error_flag = true;
5255 }
5256 break;
5257 default:
5258 loc->error("The operand of operation `%s' should be a union value "
5259 "or template instead of `%s'", opname,
5260 t_governor->get_typename().c_str());
5261 error_flag = true;
5262 break;
5263 }
5264 }
5265 if (error_flag) set_valuetype(V_ERROR);
5266 }
5267
5268 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5269 Type::expected_value_t exp_val) {
5270
5271 Error_Context cntxt(this, "In the parameter of encvalue()");
5272 Type t_chk(Type::T_ERROR);
5273 Type* t_type;
5274
5275 Type::expected_value_t ti_exp_val = exp_val;
5276 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5277 ti_exp_val = Type::EXPECTED_TEMPLATE;
5278
5279 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5280 if (t_type) {
5281 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5282 if (valuetype!=V_ERROR)
5283 u.expr.ti1->get_Template()->chk_specific_value(false);
5284 t_type = t_type->get_type_refd_last();
5285 } else {
5286 error("Cannot determine type of value");
5287 goto error;
5288 }
5289
5290 // todo: fix this
5291 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5292 error("Expecting a value of a type with coding attributes in first"
5293 "parameter of encvalue() which belongs to a generic type '%s'",
5294 t_type->get_typename().c_str());
5295 goto error;
5296 }*/
5297
5298 if(!disable_attribute_validation()) {
5299 t_type->chk_coding(true);
5300 }
5301
5302 switch (t_type->get_typetype()) {
5303 case Type::T_UNDEF:
5304 case Type::T_ERROR:
5305 case Type::T_NULL:
5306 case Type::T_REFD:
5307 case Type::T_REFDSPEC:
5308 case Type::T_SELTYPE:
5309 case Type::T_VERDICT:
5310 case Type::T_PORT:
5311 case Type::T_COMPONENT:
5312 case Type::T_DEFAULT:
5313 case Type::T_SIGNATURE:
5314 case Type::T_FUNCTION:
5315 case Type::T_ALTSTEP:
5316 case Type::T_TESTCASE:
5317 error("Type of parameter of encvalue() cannot be '%s'",
5318 t_type->get_typename().c_str());
5319 goto error;
5320 default:
5321 break;
5322 }
5323 return;
5324 error:
5325 set_valuetype(V_ERROR);
5326 }
5327
5328 void Value::chk_expr_operands_decode()
5329 {
5330 Error_Context cntxt(this, "In the parameters of decvalue()");
5331 Ttcn::Ref_base* ref = u.expr.r1;
5332 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5333 Type* t_type = 0;
5334 Assignment* t_ass = ref->get_refd_assignment();
5335
5336 if (!t_ass) {
5337 error("Could not determine the assignment for first parameter");
5338 goto error;
5339 }
5340 switch (t_ass->get_asstype()) {
5341 case Assignment::A_PAR_VAL_IN:
5342 t_ass->use_as_lvalue(*this);
5343 break;
5344 case Assignment::A_CONST:
5345 case Assignment::A_EXT_CONST:
5346 case Assignment::A_MODULEPAR:
5347 case Assignment::A_MODULEPAR_TEMP:
5348 case Assignment::A_TEMPLATE:
5349 ref->error("Reference to '%s' cannot be used as the first operand of "
5350 "the 'decvalue' operation", t_ass->get_assname());
5351 goto error;
5352 break;
5353 case Assignment::A_VAR:
5354 case Assignment::A_PAR_VAL_OUT:
5355 case Assignment::A_PAR_VAL_INOUT:
5356 break;
5357 case Assignment::A_VAR_TEMPLATE:
5358 case Assignment::A_PAR_TEMPL_IN:
5359 case Assignment::A_PAR_TEMPL_OUT:
5360 case Assignment::A_PAR_TEMPL_INOUT: {
5361 Template* t = new Template(ref->clone());
5362 t->set_location(*ref);
5363 t->set_my_scope(get_my_scope());
5364 t->set_fullname(get_fullname()+".<operand>");
5365 Template* t_last = t->get_template_refd_last();
5366 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5367 && t_last != t) {
5368 ref->error("Specific value template was expected instead of '%s'.",
5369 t->get_template_refd_last()->get_templatetype_str());
5370 delete t;
5371 goto error;
5372 }
5373 delete t;
5374 break; }
5375 default:
5376 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5377 goto error;
5378 }
5379 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5380 Type::EXPECTED_DYNAMIC_VALUE);
5381 if (!t_type) {
5382 goto error;
5383 }
5384 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5385 error("First parameter has to be a bitstring");
5386 goto error;
5387 }
5388
5389 ref = u.expr.r2;
5390 t_subrefs = ref->get_subrefs();
5391 t_ass = ref->get_refd_assignment();
5392
5393 if (!t_ass) {
5394 error("Could not determine the assignment for second parameter");
5395 goto error;
5396 }
5397 // Extra check for HM59355.
5398 switch (t_ass->get_asstype()) {
5399 case Assignment::A_VAR:
5400 case Assignment::A_PAR_VAL_IN:
5401 case Assignment::A_PAR_VAL_OUT:
5402 case Assignment::A_PAR_VAL_INOUT:
5403 break;
5404 default:
5405 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5406 goto error;
5407 }
5408 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5409 Type::EXPECTED_DYNAMIC_VALUE);
5410 if (!t_type) {
5411 goto error;
5412 }
5413 t_type = t_type->get_type_refd_last();
5414 switch (t_type->get_typetype()) {
5415 case Type::T_UNDEF:
5416 case Type::T_ERROR:
5417 case Type::T_NULL:
5418 case Type::T_REFD:
5419 case Type::T_REFDSPEC:
5420 case Type::T_SELTYPE:
5421 case Type::T_VERDICT:
5422 case Type::T_PORT:
5423 case Type::T_COMPONENT:
5424 case Type::T_DEFAULT:
5425 case Type::T_SIGNATURE:
5426 case Type::T_FUNCTION:
5427 case Type::T_ALTSTEP:
5428 case Type::T_TESTCASE:
5429 error("Type of second parameter cannot be %s",
5430 t_type->get_typename().c_str());
5431 goto error;
5432 default:
5433 break;
5434 }
5435
5436 if(!disable_attribute_validation()) {
5437 t_type->chk_coding(false);
5438 }
5439
5440 return;
5441 error:
5442 set_valuetype(V_ERROR);
5443 }
5444
5445 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5446 {
5447 Ttcn::FieldOrArrayRefs *subrefs;
5448 Identifier *field_id = 0;
5449 Assignment *t_ass;
5450 Type *t_type;
5451 if (valuetype == V_ERROR) return;
5452 else if (valuetype != V_REFD) {
5453 error("Only a referenced value can be compared with `omit'");
5454 goto error;
5455 }
5456 subrefs = u.ref.ref->get_subrefs();
5457 if (subrefs) field_id = subrefs->remove_last_field();
5458 if (!field_id) {
5459 error("Only a reference pointing to an optional record or set field "
5460 "can be compared with `omit'");
5461 goto error;
5462 }
5463 t_ass = u.ref.ref->get_refd_assignment();
5464 if (!t_ass) goto error;
5465 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5466 if (!t_type) goto error;
5467 t_type = t_type->get_type_refd_last();
5468 switch (t_type->get_typetype()) {
5469 case Type::T_ERROR:
5470 goto error;
5471 case Type::T_SEQ_A:
5472 case Type::T_SEQ_T:
5473 case Type::T_SET_A:
5474 case Type::T_SET_T:
5475 break;
5476 default:
5477 error("Only a reference pointing to an optional field of a record"
5478 " or set type can be compared with `omit'");
5479 goto error;
5480 }
5481 if (!t_type->has_comp_withName(*field_id)) {
5482 error("Type `%s' does not have field named `%s'",
5483 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5484 goto error;
5485 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5486 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5487 "`omit'", field_id->get_dispname().c_str(),
5488 t_type->get_typename().c_str());
5489 goto error;
5490 }
5491 // putting the last field_id back to subrefs
5492 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5493 return;
5494 error:
5495 set_valuetype(V_ERROR);
5496 delete field_id;
5497 }
5498
5499 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5500 Type::expected_value_t exp_val)
5501 {
5502 if(valuetype==V_ERROR) return -1;
5503 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5504 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5505 exp_val=Type::EXPECTED_TEMPLATE;
5506
5507 Error_Context cntxt(this, "In the operand of"
5508 " operation `%s'", get_opname());
5509
5510 Int result = -1;
5511 Template* t_templ = u.expr.ti1->get_Template();
5512
5513 if (!t_templ) {
5514 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5515 }
5516
5517 t_templ = t_templ->get_template_refd_last(refch);
5518
5519 // Timer and port arrays are handled separately
5520 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5521 Value* val = t_templ->get_specific_value();
5522 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5523 val->set_lowerid_to_ref();
5524 }
5525 if (val && val->get_valuetype() == V_REFD) {
5526 Reference* ref = val->get_reference();
5527 Assignment* t_ass = ref->get_refd_assignment();
5528 Common::Assignment::asstype_t asstype =
5529 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5530 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5531 if (t_ass->get_Dimensions()) {
5532 // here we have a timer or port array
5533 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5534 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5535 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5536 Type::EXPECTED_DYNAMIC_VALUE);
5537 size_t refd_dim;
5538 if (t_subrefs) {
5539 refd_dim = t_subrefs->get_nof_refs();
5540 size_t nof_dims = t_dims->get_nof_dims();
5541 if (refd_dim >= nof_dims) {
5542 u.expr.ti1->error("Operation is not applicable to a %s",
5543 t_ass->get_assname());
5544 set_valuetype(V_ERROR);
5545 return -1;
5546 }
5547 } else refd_dim = 0;
5548 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5549 } else {
5550 u.expr.ti1->error("Operation is not applicable to single `%s'",
5551 t_ass->get_description().c_str());
5552 set_valuetype(V_ERROR);
5553 return -1;
5554 }
5555 }
5556 }
5557 }
5558
5559 Value* t_val = 0;
5560 Type* t_type = 0;
5561 Assignment* t_ass = 0;
5562 Reference* ref = 0;
5563 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5564 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5565 if (t_type) {
5566 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5567 t_type = t_type->get_type_refd_last();
5568 } else {
5569 error("Cannot determine type of value");
5570 goto error;
5571 }
5572
5573 if(valuetype==V_ERROR) return -1;
5574
5575 t_templ = t_templ->get_template_refd_last(refch);
5576 switch(t_templ->get_templatetype()) {
5577 case Template::TEMPLATE_ERROR:
5578 goto error;
5579 case Template::INDEXED_TEMPLATE_LIST:
5580 return -1;
5581 case Template::TEMPLATE_REFD:
5582 case Template::TEMPLATE_LIST:
5583 case Template::NAMED_TEMPLATE_LIST:
5584 // computed later
5585 break;
5586 case Template::SPECIFIC_VALUE:
5587 {
5588 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5589 if(t_val) {
5590 switch(t_val->get_valuetype()) {
5591 case V_SEQOF:
5592 case V_SETOF:
5593 case V_ARRAY:
5594 case V_ROID:
5595 case V_OID:
5596 case V_SEQ:
5597 case V_SET:
5598 break;
5599 case V_REFD: {
5600 ref = t_val->get_reference();
5601 t_ass = ref->get_refd_assignment();
5602 t_subrefs = ref->get_subrefs();
5603 break;
5604 }
5605 default:
5606 u.expr.ti1->error("Operation is not applicable to `%s'",
5607 t_val->create_stringRepr().c_str());
5608 goto error;
5609 }
5610 }
5611 break;
5612 }
5613 default:
5614 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5615 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5616 goto error;
5617 } // switch
5618
5619 if (t_ass) {
5620 switch(t_ass->get_asstype()) {
5621 case Assignment::A_ERROR:
5622 goto error;
5623 case Assignment::A_CONST:
5624 t_val = t_ass->get_Value();
5625 break;
5626 case Assignment::A_EXT_CONST:
5627 case Assignment::A_MODULEPAR:
5628 case Assignment::A_MODULEPAR_TEMP:
5629 if(exp_val==Type::EXPECTED_CONSTANT) {
5630 u.expr.ti1->error("Reference to an (evaluatable) constant value was "
5631 "expected instead of %s", t_ass->get_description().c_str());
5632 goto error;
5633 }
5634 break;
5635 case Assignment::A_VAR:
5636 case Assignment::A_PAR_VAL_IN:
5637 case Assignment::A_PAR_VAL_OUT:
5638 case Assignment::A_PAR_VAL_INOUT:
5639 switch(exp_val) {
5640 case Type::EXPECTED_CONSTANT:
5641 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5642 t_ass->get_description().c_str());
5643 goto error;
5644 break;
5645 case Type::EXPECTED_STATIC_VALUE:
5646 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5647 t_ass->get_description().c_str());
5648 goto error;
5649 break;
5650 default:
5651 break;
5652 }
5653 break;
5654 case Assignment::A_TEMPLATE:
5655 t_templ = t_ass->get_Template();
5656 // no break
5657 case Assignment::A_VAR_TEMPLATE:
5658 case Assignment::A_PAR_TEMPL_IN:
5659 case Assignment::A_PAR_TEMPL_OUT:
5660 case Assignment::A_PAR_TEMPL_INOUT:
5661 if (exp_val!=Type::EXPECTED_TEMPLATE)
5662 u.expr.ti1->error("Reference to a value was expected instead of %s",
5663 t_ass->get_description().c_str());
5664 goto error;
5665 break;
5666 case Assignment::A_FUNCTION_RVAL:
5667 case Assignment::A_EXT_FUNCTION_RVAL:
5668 switch(exp_val) {
5669 case Type::EXPECTED_CONSTANT:
5670 u.expr.ti1->error("Reference to a constant value was expected instead of "
5671 "the return value of %s", t_ass->get_description().c_str());
5672 goto error;
5673 break;
5674 case Type::EXPECTED_STATIC_VALUE:
5675 u.expr.ti1->error("Reference to a static value was expected instead of "
5676 "the return value of %s", t_ass->get_description().c_str());
5677 goto error;
5678 break;
5679 default:
5680 break;
5681 }
5682 break;
5683 case Assignment::A_FUNCTION_RTEMP:
5684 case Assignment::A_EXT_FUNCTION_RTEMP:
5685 if(exp_val!=Type::EXPECTED_TEMPLATE)
5686 u.expr.ti1->error("Reference to a value was expected instead of a call"
5687 " of %s, which returns a template",
5688 t_ass->get_description().c_str());
5689 goto error;
5690 break;
5691 case Assignment::A_TIMER:
5692 case Assignment::A_PORT:
5693 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5694 // sizeof is applicable to timer and port arrays
5695 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5696 if (!t_dims) {
5697 u.expr.ti1->error("Operation is not applicable to single %s",
5698 t_ass->get_description().c_str());
5699 goto error;
5700 }
5701 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5702 Type::EXPECTED_DYNAMIC_VALUE);
5703 size_t refd_dim;
5704 if (t_subrefs) {
5705 refd_dim = t_subrefs->get_nof_refs();
5706 size_t nof_dims = t_dims->get_nof_dims();
5707 if (refd_dim > nof_dims) goto error;
5708 else if (refd_dim == nof_dims) {
5709 u.expr.ti1->error("Operation is not applicable to a %s",
5710 t_ass->get_assname());
5711 goto error;
5712 }
5713 } else refd_dim = 0;
5714 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5715 }
5716 // no break
5717 default:
5718 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5719 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5720 t_ass->get_description().c_str());
5721 goto error;
5722 } // end switch
5723
5724 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5725 if (!t_type) goto error;
5726 t_type = t_type->get_type_refd_last();
5727
5728 switch(t_type->get_typetype()) {
5729 case Type::T_ERROR:
5730 goto error;
5731 case Type::T_SEQOF:
5732 case Type::T_SETOF:
5733 // no break
5734 case Type::T_SEQ_T:
5735 case Type::T_SET_T:
5736 case Type::T_SEQ_A:
5737 case Type::T_SET_A:
5738 case Type::T_ARRAY:
5739 // ok
5740 break;
5741 case Type::T_OID:
5742 case Type::T_ROID:
5743 break;
5744 default:
5745 u.expr.ti1->error("Reference to value or template of type record, record of,"
5746 " set, set of, objid or array was expected");
5747 goto error;
5748 } // switch
5749 }
5750
5751 // check for index overflows in subrefs if possible
5752 if (t_val) {
5753 switch (t_val->get_valuetype()) {
5754 case V_SEQOF:
5755 case V_SETOF:
5756 case V_ARRAY:
5757 if (t_val->is_indexed()) {
5758 return -1;
5759 }
5760 break;
5761 default:
5762 break;
5763 }
5764 /* The reference points to a constant. */
5765 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5766 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5767 if (!t_val) goto error;
5768 t_val=t_val->get_value_refd_last(refch);
5769 } else { t_val = 0; }
5770 } else if (t_templ) {
5771 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5772 time. Don't try to evaluate it at compile time. */
5773 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5774 return -1;
5775 /* The reference points to a static template. */
5776 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5777 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5778 if (!t_templ) goto error;
5779 t_templ = t_templ->get_template_refd_last(refch);
5780 } else { t_templ = 0; }
5781 }
5782
5783 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5784 if(t_templ) {
5785 switch(t_templ->get_templatetype()) {
5786 case Template::TEMPLATE_ERROR:
5787 goto error;
5788 case Template::TEMPLATE_REFD:
5789 // not foldable
5790 t_templ=0;
5791 break;
5792 case Template::SPECIFIC_VALUE:
5793 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5794 t_templ=0;
5795 break;
5796 case Template::TEMPLATE_LIST:
5797 case Template::NAMED_TEMPLATE_LIST:
5798 break;
5799 default:
5800 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5801 t_templ->get_templatetype_str(),
5802 t_templ->get_fullname().c_str());
5803 goto error;
5804 } // switch
5805 }
5806 if(t_val) {
5807 switch(t_val->get_valuetype()) {
5808 case V_SEQOF:
5809 case V_SETOF:
5810 case V_ARRAY:
5811 case V_SEQ:
5812 case V_SET:
5813 case V_OID:
5814 case V_ROID:
5815 // ok
5816 break;
5817 default:
5818 // error is already reported
5819 t_val=0;
5820 break;
5821 } // switch
5822 }
5823 }
5824
5825 /* evaluation */
5826
5827 if(t_type->get_typetype()==Type::T_ARRAY) {
5828 result = t_type->get_dimension()->get_size();
5829 }
5830 else if(t_templ) { // sizeof()
5831 switch(t_templ->get_templatetype()) {
5832 case Template::TEMPLATE_LIST:
5833 if(t_templ->temps_contains_anyornone_symbol()) {
5834 if(t_templ->is_length_restricted()) {
5835 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5836 if (lr->get_is_range()) {
5837 Value *v_upper = lr->get_upper_value();
5838 if (v_upper) {
5839 if (v_upper->valuetype == V_INT) {
5840 Int nof_comps =
5841 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5842 if (v_upper->u.val_Int->get_val() == nof_comps)
5843 result = nof_comps;
5844 else {
5845 u.expr.ti1->error("`sizeof' operation is not applicable for "
5846 "templates without exact size");
5847 goto error;
5848 }
5849 }
5850 } else {
5851 u.expr.ti1->error("`sizeof' operation is not applicable for "
5852 "templates containing `*' without upper boundary in the "
5853 "length restriction");
5854 goto error;
5855 }
5856 } else {
5857 Value *v_single = lr->get_single_value();
5858 if (v_single->valuetype == V_INT)
5859 result = v_single->u.val_Int->get_val();
5860 }
5861 }
5862 else { // not length restricted
5863 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
5864 " containing `*' without length restriction");
5865 goto error;
5866 }
5867 }
5868 else result=t_templ->get_nof_listitems();
5869 break;
5870 case Template::NAMED_TEMPLATE_LIST:
5871 result=0;
5872 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
5873 if(t_templ->get_namedtemp_byIndex(i)->get_template()
5874 ->get_templatetype()!=Template::OMIT_VALUE) result++;
5875 return result;
5876 default:
5877 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5878 } // switch
5879 }
5880 else if(t_val) {
5881 switch(t_val->get_valuetype()) {
5882 case V_SEQOF:
5883 case V_SETOF:
5884 case V_ARRAY:
5885
5886 case V_OID:
5887 case V_ROID:
5888 result=t_val->get_nof_comps();
5889 break;
5890 case V_SEQ:
5891 case V_SET:
5892 result=0;
5893 for(size_t i=0; i<t_val->get_nof_comps(); i++)
5894 if(t_val->get_se_comp_byIndex(i)->get_value()
5895 ->get_valuetype()!=V_OMIT) result++;
5896 break;
5897
5898 default:
5899 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5900 } // switch
5901 }
5902
5903 return result;
5904 error:
5905 set_valuetype(V_ERROR);
5906 return -1;
5907 }
5908
5909 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
5910 {
5911 Type *governor = ti->get_expr_governor(exp_val);
5912 if (!governor) {
5913 ti->get_Template()->set_lowerid_to_ref();
5914 governor = ti->get_expr_governor(exp_val);
5915 }
5916 if (!governor) {
5917 string str;
5918 ti->append_stringRepr( str);
5919 ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5920 "If type is known, use valuof(<type>: %s) as argument.",
5921 str.c_str(), get_opname(), str.c_str());
5922 set_valuetype(V_ERROR);
5923 }
5924 return governor;
5925 }
5926
5927 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
5928 {
5929 start:
5930 Type *governor = u.expr.v1->get_expr_governor(exp_val);
5931 if (!governor) governor = u.expr.t2->get_expr_governor(
5932 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
5933 Type::EXPECTED_TEMPLATE : exp_val);
5934 if (!governor) {
5935 Template *t_temp = u.expr.t2->get_Template();
5936 if (t_temp->is_undef_lowerid()) {
5937 // We convert the template to reference first even if the value is also
5938 // an undef lowerid. The user can prevent this by explicit type
5939 // specification.
5940 t_temp->set_lowerid_to_ref();
5941 goto start;
5942 } else if (u.expr.v1->is_undef_lowerid()) {
5943 u.expr.v1->set_lowerid_to_ref();
5944 goto start;
5945 }
5946 }
5947 if (!governor) {
5948 error("Cannot determine the type of arguments in `match()' operation");
5949 set_valuetype(V_ERROR);
5950 return;
5951 }
5952 u.expr.v1->set_my_governor(governor);
5953 {
5954 Error_Context cntxt(this, "In the first argument of `match()'"
5955 " operation");
5956 governor->chk_this_value_ref(u.expr.v1);
5957 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
5958 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
5959 }
5960 {
5961 Error_Context cntxt(this, "In the second argument of `match()' "
5962 "operation");
5963 u.expr.t2->chk(governor);
5964 }
5965 }
5966
5967 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
5968 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
5969 {
5970 Ttcn::StatementBlock *my_sb;
5971 switch (exp_val) {
5972 case Type::EXPECTED_CONSTANT:
5973 error("An evaluatable constant value was expected instead of operation "
5974 "`%s'", get_opname());
5975 goto error;
5976 case Type::EXPECTED_STATIC_VALUE:
5977 error("A static value was expected instead of operation `%s'",
5978 get_opname());
5979 goto error;
5980 default:
5981 break;
5982 } // switch
5983 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5984 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
5985 if (!my_sb) {
5986 error("Operation `%s' is allowed only within statements",
5987 get_opname());
5988 goto error;
5989 }
5990 if (!allow_controlpart && !my_sb->get_my_def()) {
5991 error("Operation `%s' is not allowed in the control part",
5992 get_opname());
5993 goto error;
5994 }
5995 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
5996 error("Operation `%s' cannot be used in a definition that has "
5997 "`runs on' clause", get_opname());
5998 goto error;
5999 }
6000 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6001 error("Operation `%s' can be used only in a definition that has "
6002 "`runs on' clause", get_opname());
6003 goto error;
6004 }
6005 return;
6006 error:
6007 set_valuetype(V_ERROR);
6008 }
6009
6010 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6011 {
6012 if(valuetype==V_ERROR) return;
6013 if(u.expr.state==EXPR_CHECKING_ERR) return;
6014 if(v->is_unfoldable()) return;
6015 if(v->get_expr_returntype()!=Type::T_REAL) return;
6016 ttcn3float r = v->get_val_Real();
6017 if (isSpecialFloatValue(r)) {
6018 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6019 opnum, opname, Real2string(r).c_str());
6020 set_valuetype(V_ERROR);
6021 }
6022 }
6023
6024 void Value::chk_expr_operands(ReferenceChain *refch,
6025 Type::expected_value_t exp_val)
6026 {
6027 const char *first="First", *second="Second", *third="Third",
6028 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6029 Value *v1, *v2, *v3;
6030 Type::typetype_t tt1, tt2, tt3;
6031 Type t_chk(Type::T_ERROR);
6032
6033 const char *opname=get_opname();
6034
6035 // first classify the unchecked ischosen() operation
6036 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6037
6038 switch (u.expr.v_optype) {
6039 case OPTYPE_COMP_NULL:
6040 case OPTYPE_TESTCASENAME:
6041 break;
6042 case OPTYPE_COMP_MTC:
6043 case OPTYPE_COMP_SYSTEM:
6044 chk_expr_comptype_compat();
6045 break;
6046 case OPTYPE_RND: // -
6047 case OPTYPE_TMR_RUNNING_ANY:
6048 chk_expr_dynamic_part(exp_val, true);
6049 break;
6050 case OPTYPE_COMP_RUNNING_ANY:
6051 case OPTYPE_COMP_RUNNING_ALL:
6052 case OPTYPE_COMP_ALIVE_ANY:
6053 case OPTYPE_COMP_ALIVE_ALL:
6054 case OPTYPE_GETVERDICT:
6055 chk_expr_dynamic_part(exp_val, false);
6056 break;
6057 case OPTYPE_COMP_SELF:
6058 chk_expr_comptype_compat();
6059 chk_expr_dynamic_part(exp_val, false, true, false);
6060 break;
6061 case OPTYPE_UNARYPLUS: // v1
6062 case OPTYPE_UNARYMINUS:
6063 v1=u.expr.v1;
6064 {
6065 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6066 v1->set_lowerid_to_ref();
6067 tt1=v1->get_expr_returntype(exp_val);
6068 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6069 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6070 }
6071 break;
6072 case OPTYPE_NOT:
6073 v1=u.expr.v1;
6074 {
6075 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6076 v1->set_lowerid_to_ref();
6077 tt1=v1->get_expr_returntype(exp_val);
6078 chk_expr_operandtype_bool(tt1, the, opname, v1);
6079 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6080 }
6081 break;
6082 case OPTYPE_NOT4B:
6083 v1=u.expr.v1;
6084 {
6085 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6086 v1->set_lowerid_to_ref();
6087 tt1=v1->get_expr_returntype(exp_val);
6088 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6089 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6090 }
6091 break;
6092 case OPTYPE_BIT2HEX:
6093 case OPTYPE_BIT2OCT:
6094 case OPTYPE_BIT2STR:
6095 v1=u.expr.v1;
6096 {
6097 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6098 v1->set_lowerid_to_ref();
6099 tt1=v1->get_expr_returntype(exp_val);
6100 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6101 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6102 }
6103 break;
6104 case OPTYPE_BIT2INT:
6105 v1=u.expr.v1;
6106 {
6107 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6108 v1->set_lowerid_to_ref();
6109 tt1=v1->get_expr_returntype(exp_val);
6110 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6111 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6112 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6113 }
6114 break;
6115 case OPTYPE_CHAR2INT:
6116 v1=u.expr.v1;
6117 {
6118 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6119 v1->set_lowerid_to_ref();
6120 tt1=v1->get_expr_returntype(exp_val);
6121 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6122 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6123 chk_expr_val_len1(v1, the, opname);
6124 }
6125 break;
6126 case OPTYPE_CHAR2OCT:
6127 v1=u.expr.v1;
6128 {
6129 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6130 v1->set_lowerid_to_ref();
6131 tt1=v1->get_expr_returntype(exp_val);
6132 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6133 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6134 }
6135 break;
6136 case OPTYPE_STR2INT:
6137 v1=u.expr.v1;
6138 {
6139 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6140 v1->set_lowerid_to_ref();
6141 tt1=v1->get_expr_returntype(exp_val);
6142 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6143 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6144 chk_expr_val_str_int(v1, the, opname);
6145 }
6146 break;
6147 case OPTYPE_STR2FLOAT:
6148 v1=u.expr.v1;
6149 {
6150 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6151 v1->set_lowerid_to_ref();
6152 tt1=v1->get_expr_returntype(exp_val);
6153 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6154 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6155 chk_expr_val_str_float(v1, the, opname);
6156 }
6157 break;
6158 case OPTYPE_STR2BIT:
6159 v1=u.expr.v1;
6160 {
6161 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6162 v1->set_lowerid_to_ref();
6163 tt1=v1->get_expr_returntype(exp_val);
6164 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6165 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6166 chk_expr_val_str_bindigits(v1, the, opname);
6167 }
6168 break;
6169 case OPTYPE_STR2HEX:
6170 v1=u.expr.v1;
6171 {
6172 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6173 v1->set_lowerid_to_ref();
6174 tt1=v1->get_expr_returntype(exp_val);
6175 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6176 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6177 chk_expr_val_str_hexdigits(v1, the, opname);
6178 }
6179 break;
6180 case OPTYPE_STR2OCT:
6181 v1=u.expr.v1;
6182 {
6183 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6184 v1->set_lowerid_to_ref();
6185 tt1=v1->get_expr_returntype(exp_val);
6186 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6187 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6188 chk_expr_val_str_len_even(v1, the, opname);
6189 chk_expr_val_str_hexdigits(v1, the, opname);
6190 }
6191 break;
6192 case OPTYPE_ENUM2INT:
6193 v1=u.expr.v1;
6194 {
6195 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6196 chk_expr_operandtype_enum(opname, v1, exp_val);
6197 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6198 }
6199 break;
6200 case OPTYPE_ENCODE:
6201 chk_expr_operand_encode(refch, exp_val);
6202 break;
6203 case OPTYPE_FLOAT2INT:
6204 case OPTYPE_FLOAT2STR:
6205 v1=u.expr.v1;
6206 {
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_float(tt1, the, opname, v1);
6211 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6212 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6213 chk_expr_operand_valid_float(v1, the, opname);
6214 }
6215 break;
6216 case OPTYPE_RNDWITHVAL:
6217 v1=u.expr.v1;
6218 {
6219 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6220 v1->set_lowerid_to_ref();
6221 tt1=v1->get_expr_returntype(exp_val);
6222 chk_expr_operandtype_float(tt1, the, opname, v1);
6223 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6224 chk_expr_operand_valid_float(v1, the, opname);
6225 }
6226 chk_expr_dynamic_part(exp_val, true);
6227 break;
6228 case OPTYPE_HEX2BIT:
6229 case OPTYPE_HEX2OCT:
6230 case OPTYPE_HEX2STR:
6231 v1=u.expr.v1;
6232 {
6233 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6234 v1->set_lowerid_to_ref();
6235 tt1=v1->get_expr_returntype(exp_val);
6236 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6237 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6238 }
6239 break;
6240 case OPTYPE_HEX2INT:
6241 v1=u.expr.v1;
6242 {
6243 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6244 v1->set_lowerid_to_ref();
6245 tt1=v1->get_expr_returntype(exp_val);
6246 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6247 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6248 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6249 }
6250 break;
6251 case OPTYPE_INT2CHAR:
6252 v1=u.expr.v1;
6253 {
6254 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6255 v1->set_lowerid_to_ref();
6256 tt1=v1->get_expr_returntype(exp_val);
6257 chk_expr_operandtype_int(tt1, the, opname, v1);
6258 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6259 chk_expr_val_int_pos7bit(v1, the, opname);
6260 }
6261 break;
6262 case OPTYPE_INT2UNICHAR:
6263 v1=u.expr.v1;
6264 {
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_int(tt1, the, opname, v1);
6269 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6270 chk_expr_val_int_pos31bit(v1, first, opname);
6271 }
6272 break;
6273 case OPTYPE_INT2FLOAT:
6274 case OPTYPE_INT2STR:
6275 v1=u.expr.v1;
6276 {
6277 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6278 v1->set_lowerid_to_ref();
6279 tt1=v1->get_expr_returntype(exp_val);
6280 chk_expr_operandtype_int(tt1, the, opname, v1);
6281 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6282 }
6283 break;
6284 case OPTYPE_OCT2BIT:
6285 case OPTYPE_OCT2HEX:
6286 case OPTYPE_OCT2STR:
6287 v1=u.expr.v1;
6288 {
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_ostr(tt1, the, opname, v1);
6293 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6294 }
6295 break;
6296 case OPTYPE_OCT2INT:
6297 v1=u.expr.v1;
6298 {
6299 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6300 v1->set_lowerid_to_ref();
6301 tt1=v1->get_expr_returntype(exp_val);
6302 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6303 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6304 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6305 // now.
6306 }
6307 break;
6308 case OPTYPE_OCT2CHAR:
6309 v1=u.expr.v1;
6310 {
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_ostr(tt1, the, opname, v1);
6315 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6316 chk_expr_val_str_7bitoctets(v1, the, opname);
6317 }
6318 break;
6319 case OPTYPE_REMOVE_BOM:
6320 v1=u.expr.v1;
6321 {
6322 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6323 v1->set_lowerid_to_ref();
6324 tt1=v1->get_expr_returntype(exp_val);
6325 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6326 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6327 }
6328 break;
6329 case OPTYPE_GET_STRINGENCODING:
6330 v1=u.expr.v1;
6331 {
6332 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6333 v1->set_lowerid_to_ref();
6334 tt1=v1->get_expr_returntype(exp_val);
6335 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6336 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6337 }
6338 break;
6339 case OPTYPE_ENCODE_BASE64:
6340 v1=u.expr.v1;
6341 {
6342 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6343 v1->set_lowerid_to_ref();
6344 tt1=v1->get_expr_returntype(exp_val);
6345 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6346 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6347 }
6348 v2=u.expr.v2 ? u.expr.v2 : 0;
6349 if (v2)
6350 {
6351 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6352 v2->set_lowerid_to_ref();
6353 tt2=v2->get_expr_returntype(exp_val);
6354 chk_expr_operandtype_bool(tt2, second, opname, v2);
6355 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6356 }
6357 break;
6358 case OPTYPE_DECODE_BASE64:
6359 v1=u.expr.v1;
6360 {
6361 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6362 v1->set_lowerid_to_ref();
6363 tt1=v1->get_expr_returntype(exp_val);
6364 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6365 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6366 }
6367 break;
6368 case OPTYPE_UNICHAR2INT:
6369 v1=u.expr.v1;
6370 {
6371 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6372 v1->set_lowerid_to_ref();
6373 tt1=v1->get_expr_returntype(exp_val);
6374 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6375 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6376 chk_expr_val_len1(v1, the, opname);
6377 }
6378 break;
6379 case OPTYPE_UNICHAR2CHAR:
6380 v1=u.expr.v1;
6381 {
6382 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6383 v1->set_lowerid_to_ref();
6384 tt1=v1->get_expr_returntype(exp_val);
6385 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6386 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6387 chk_expr_val_ustr_7bitchars(v1, the, opname);
6388 }
6389 break;
6390 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6391 v1=u.expr.v1;
6392 {
6393 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6394 v1->set_lowerid_to_ref();
6395 tt1=v1->get_expr_returntype(exp_val);
6396 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6397 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6398 }
6399 v2=u.expr.v2 ? u.expr.v2 : 0;
6400 if (v2)
6401 {
6402 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6403 v2->set_lowerid_to_ref();
6404 tt2=v2->get_expr_returntype(exp_val);
6405 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6406 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6407 }
6408 break;
6409 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6410 v1=u.expr.v1;
6411 {
6412 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6413 v1->set_lowerid_to_ref();
6414 tt1=v1->get_expr_returntype(exp_val);
6415 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6416 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6417 }
6418 v2=u.expr.v2 ? u.expr.v2 : 0;
6419 if (v2)
6420 {
6421 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6422 v2->set_lowerid_to_ref();
6423 tt2=v2->get_expr_returntype(exp_val);
6424 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6425 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6426 }
6427 break;
6428 case OPTYPE_ADD: // v1 v2
6429 case OPTYPE_SUBTRACT:
6430 case OPTYPE_MULTIPLY:
6431 case OPTYPE_DIVIDE:
6432 v1=u.expr.v1;
6433 {
6434 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6435 v1->set_lowerid_to_ref();
6436 tt1=v1->get_expr_returntype(exp_val);
6437 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6438 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6439 chk_expr_operand_valid_float(v1, first, opname);
6440 }
6441 v2=u.expr.v2;
6442 {
6443 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6444 v2->set_lowerid_to_ref();
6445 tt2=v2->get_expr_returntype(exp_val);
6446 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6447 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6448 chk_expr_operand_valid_float(v2, second, opname);
6449 if(u.expr.v_optype==OPTYPE_DIVIDE)
6450 chk_expr_val_int_float_not0(v2, second, opname);
6451 }
6452 chk_expr_operandtypes_same(tt1, tt2, opname);
6453 break;
6454 case OPTYPE_MOD:
6455 case OPTYPE_REM:
6456 v1=u.expr.v1;
6457 {
6458 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6459 v1->set_lowerid_to_ref();
6460 tt1=v1->get_expr_returntype(exp_val);
6461 chk_expr_operandtype_int(tt1, left, opname, v1);
6462 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6463 }
6464 v2=u.expr.v2;
6465 {
6466 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6467 v2->set_lowerid_to_ref();
6468 tt2=v2->get_expr_returntype(exp_val);
6469 chk_expr_operandtype_int(tt2, right, opname, v2);
6470 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6471 chk_expr_val_int_float_not0(v2, right, opname);
6472 }
6473 break;
6474 case OPTYPE_CONCAT: {
6475 v1=u.expr.v1;
6476 v2=u.expr.v2;
6477 v1->set_lowerid_to_ref();
6478 v2->set_lowerid_to_ref();
6479 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6480 {
6481 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6482 tt1=v1->get_expr_returntype(exp_val);
6483 chk_expr_operandtype_str(tt1, left, opname, v1);
6484 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6485 }
6486 {
6487 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6488 tt2=v2->get_expr_returntype(exp_val);
6489 chk_expr_operandtype_str(tt2, right, opname, v2);
6490 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6491 }
6492 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6493 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6494 chk_expr_operandtypes_same(tt1, tt2, opname);
6495 } else { // other list types
6496 Type* v1_gov = v1->get_expr_governor(exp_val);
6497 Type* v2_gov = v2->get_expr_governor(exp_val);
6498 if (!v1_gov) {
6499 error("Cannot determine the type of the left operand of `%s' operation", opname);
6500 set_valuetype(V_ERROR);
6501 return;
6502 } else {
6503 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6504 v1_gov->chk_this_value_ref(v1);
6505 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6506 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6507 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6508 }
6509 if (!v2_gov) {
6510 if (!v1_gov) {
6511 error("Cannot determine the type of the right operand of `%s' operation", opname);
6512 set_valuetype(V_ERROR);
6513 return;
6514 }
6515 // for recof/setof literals set the type from v1
6516 v2_gov = v1_gov;
6517 v2->set_my_governor(v1_gov);
6518 }
6519 {
6520 Error_Context cntxt(this, "In the right operand of operation `%s'",
6521 opname);
6522 v2_gov->chk_this_value_ref(v2);
6523 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6524 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6525 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6526 if (valuetype == V_ERROR) return;
6527 // 7.1.2 says that we shouldn't allow type compatibility.
6528 if (!v1_gov->is_compatible(v2_gov, NULL)
6529 && !v2_gov->is_compatible(v1_gov, NULL)) {
6530 error("The operands of operation `%s' should be of compatible "
6531 "types", get_opname());
6532 }
6533 }
6534 }
6535 break; }
6536 case OPTYPE_EQ:
6537 case OPTYPE_NE:
6538 v1 = u.expr.v1;
6539 v2 = u.expr.v2;
6540 chk_expr_operandtypes_compat(exp_val, v1, v2);
6541 {
6542 Error_Context cntxt(this, "In the left operand of operation `%s'",
6543 opname);
6544 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6545 }
6546 {
6547 Error_Context cntxt(this, "In the right operand of operation `%s'",
6548 opname);
6549 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6550 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6551 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6552 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6553 * "a == not b" is not allowed. (HL69107)
6554 * The various *Expressions implement operator precedence in the std.
6555 * Titan's parser has only one Expression and relies on Bison
6556 * for operator precedence. The check below brings Titan in line
6557 * with the standard by explicitly making "a == not b" an error */
6558 if (v2->get_valuetype() == V_EXPR
6559 && v2->u.expr.v_optype == OPTYPE_NOT) {
6560 error("The operation `%s' is not allowed to be "
6561 "the second operand of operation `%s'", v2->get_opname(), opname);
6562 set_valuetype(V_ERROR);
6563 }
6564 }
6565 break;
6566 case OPTYPE_LT:
6567 case OPTYPE_GT:
6568 case OPTYPE_GE:
6569 case OPTYPE_LE:
6570 v1=u.expr.v1;
6571 v2=u.expr.v2;
6572 chk_expr_operandtypes_compat(exp_val, v1, v2);
6573 {
6574 Error_Context cntxt(this, "In the left operand of operation `%s'",
6575 opname);
6576 tt1=v1->get_expr_returntype(exp_val);
6577 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6578 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6579 }
6580 {
6581 Error_Context cntxt(this, "In the right operand of operation `%s'",
6582 opname);
6583 tt2=v2->get_expr_returntype(exp_val);
6584 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6585 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6586 }
6587 break;
6588 case OPTYPE_AND:
6589 case OPTYPE_OR:
6590 case OPTYPE_XOR:
6591 v1=u.expr.v1;
6592 {
6593 Error_Context cntxt(this, "In the left operand of operation `%s'",
6594 opname);
6595 v1->set_lowerid_to_ref();
6596 tt1=v1->get_expr_returntype(exp_val);
6597 chk_expr_operandtype_bool(tt1, left, opname, v1);
6598 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6599 }
6600 v2=u.expr.v2;
6601 {
6602 Error_Context cntxt(this, "In the right operand of operation `%s'",
6603 opname);
6604 v2->set_lowerid_to_ref();
6605 tt2=v2->get_expr_returntype(exp_val);
6606 chk_expr_operandtype_bool(tt2, right, opname, v2);
6607 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6608 }
6609 break;
6610 case OPTYPE_AND4B:
6611 case OPTYPE_OR4B:
6612 case OPTYPE_XOR4B:
6613 v1=u.expr.v1;
6614 {
6615 Error_Context cntxt(this, "In the left operand of operation `%s'",
6616 opname);
6617 v1->set_lowerid_to_ref();
6618 tt1=v1->get_expr_returntype(exp_val);
6619 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6620 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6621 }
6622 v2=u.expr.v2;
6623 {
6624 Error_Context cntxt(this, "In the right operand of operation `%s'",
6625 opname);
6626 v2->set_lowerid_to_ref();
6627 tt2=v2->get_expr_returntype(exp_val);
6628 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6629 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6630 }
6631 chk_expr_operandtypes_same(tt1, tt2, opname);
6632 chk_expr_operands_str_samelen();
6633 break;
6634 case OPTYPE_SHL:
6635 case OPTYPE_SHR:
6636 v1=u.expr.v1;
6637 {
6638 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6639 v1->set_lowerid_to_ref();
6640 tt1=v1->get_expr_returntype(exp_val);
6641 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6642 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6643 }
6644 v2=u.expr.v2;
6645 {
6646 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6647 v2->set_lowerid_to_ref();
6648 tt2=v2->get_expr_returntype(exp_val);
6649 chk_expr_operandtype_int(tt2, right, opname, v2);
6650 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6651 chk_expr_val_large_int(v2, right, opname);
6652 }
6653 break;
6654 case OPTYPE_ROTL:
6655 case OPTYPE_ROTR:
6656 v1=u.expr.v1;
6657 v1->set_lowerid_to_ref();
6658 if (v1->is_string_type(exp_val)) {
6659 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6660 tt1=v1->get_expr_returntype(exp_val);
6661 chk_expr_operandtype_str(tt1, left, opname, v1);
6662 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6663 } else { // other list types
6664 Type* v1_gov = v1->get_expr_governor(exp_val);
6665 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6666 error("Cannot determine the type of the left operand of `%s' operation", opname);
6667 } else {
6668 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6669 v1_gov->chk_this_value_ref(v1);
6670 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6671 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6672 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6673 }
6674 }
6675 v2=u.expr.v2;
6676 {
6677 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6678 v2->set_lowerid_to_ref();
6679 tt2=v2->get_expr_returntype(exp_val);
6680 chk_expr_operandtype_int(tt2, right, opname, v2);
6681 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6682 chk_expr_val_large_int(v2, right, opname);
6683 }
6684 break;
6685 case OPTYPE_INT2BIT:
6686 case OPTYPE_INT2HEX:
6687 case OPTYPE_INT2OCT:
6688 v1=u.expr.v1;
6689 {
6690 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6691 v1->set_lowerid_to_ref();
6692 tt1=v1->get_expr_returntype(exp_val);
6693 chk_expr_operandtype_int(tt1, first, opname, v1);
6694 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6695 chk_expr_val_int_pos0(v1, first, opname);
6696 }
6697 v2=u.expr.v2;
6698 {
6699 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6700 v2->set_lowerid_to_ref();
6701 tt2=v2->get_expr_returntype(exp_val);
6702 chk_expr_operandtype_int(tt2, second, opname, v2);
6703 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6704 chk_expr_val_int_pos0(v2, second, opname);
6705 }
6706 chk_expr_operands_int2binstr();
6707 break;
6708 case OPTYPE_DECODE:
6709 chk_expr_operands_decode();
6710 break;
6711 case OPTYPE_SUBSTR:
6712 {
6713 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6714 Type::expected_value_t ti_exp_val = exp_val;
6715 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6716 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6717 if (!governor) return;
6718 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6719 if (valuetype!=V_ERROR)
6720 u.expr.ti1->get_Template()->chk_specific_value(false);
6721 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6722 }
6723 v2=u.expr.v2;
6724 {
6725 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6726 v2->set_lowerid_to_ref();
6727 tt2=v2->get_expr_returntype(exp_val);
6728 chk_expr_operandtype_int(tt2, second, opname, v2);
6729 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6730 chk_expr_val_int_pos0(v2, second, opname);
6731 }
6732 v3=u.expr.v3;
6733 {
6734 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6735 v3->set_lowerid_to_ref();
6736 tt3=v3->get_expr_returntype(exp_val);
6737 chk_expr_operandtype_int(tt3, third, opname, v3);
6738 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6739 chk_expr_val_int_pos0(v3, third, opname);
6740 }
6741 chk_expr_operands_substr();
6742 break;
6743 case OPTYPE_REGEXP: {
6744 Type::expected_value_t ti_exp_val = exp_val;
6745 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6746 {
6747 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6748 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6749 if (!governor) return;
6750 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6751 if (valuetype!=V_ERROR) {
6752 u.expr.ti1->get_Template()->chk_specific_value(false);
6753 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6754 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6755 }
6756 }
6757 {
6758 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6759 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6760 if (!governor) return;
6761 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6762 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6763 get_typetype_ttcn3(), second, opname, u.expr.t2);
6764 }
6765 v3=u.expr.v3;
6766 {
6767 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6768 v3->set_lowerid_to_ref();
6769 tt3=v3->get_expr_returntype(exp_val);
6770 chk_expr_operandtype_int(tt3, third, opname, v3);
6771 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6772 chk_expr_val_int_pos0(v3, third, opname);
6773 }
6774 chk_expr_operands_regexp();
6775 } break;
6776 case OPTYPE_ISCHOSEN:
6777 // do nothing: the operand is erroneous
6778 // the error was already reported in chk_expr_ref_ischosen()
6779 break;
6780 case OPTYPE_ISCHOSEN_V: // v1 i2
6781 case OPTYPE_ISCHOSEN_T: // t1 i2
6782 chk_expr_operands_ischosen(refch, exp_val);
6783 break;
6784 case OPTYPE_VALUEOF: { // ti1
6785 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6786 exp_val = Type::EXPECTED_TEMPLATE;
6787 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6788 Type *governor = my_governor;
6789 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6790 if (!governor) return;
6791 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6792 if (valuetype == V_ERROR) return;
6793 u.expr.ti1->get_Template()->chk_specific_value(false);
6794 break; }
6795 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6796 case OPTYPE_ISBOUND: {
6797 Template *templ = u.expr.ti1->get_Template();
6798 switch (templ->get_templatetype()) {
6799 case Template::TEMPLATE_REFD:
6800 templ->get_reference()->setUsedInIsbound();
6801 break;
6802 case Template::SPECIFIC_VALUE: {
6803 Value *value = templ->get_specific_value();
6804 if (Value::V_REFD == value->get_valuetype()) {
6805 value->get_reference()->setUsedInIsbound();
6806 }
6807 break; }
6808 default:
6809 break;
6810 }
6811 }
6812 // no break
6813 case OPTYPE_ISVALUE: {// ti1
6814 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6815 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6816 exp_val = Type::EXPECTED_TEMPLATE;
6817 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6818 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6819 if (!governor) return;
6820 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6821 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6822 break; }
6823 case OPTYPE_SIZEOF: // ti1
6824 /* this checking is too complex, do the checking during eval... */
6825 break;
6826 case OPTYPE_LENGTHOF: { // ti1
6827 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6828 exp_val = Type::EXPECTED_TEMPLATE;
6829 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6830 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6831 if (!governor) return;
6832 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
6833 if (valuetype == V_ERROR) return;
6834 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6835 break; }
6836 case OPTYPE_MATCH: // v1 t2
6837 chk_expr_operands_match(exp_val);
6838 break;
6839 case OPTYPE_UNDEF_RUNNING: // r1
6840 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
6841 break;
6842 case OPTYPE_COMP_ALIVE:
6843 case OPTYPE_COMP_RUNNING: //v1
6844 chk_expr_operand_compref(u.expr.v1, the, opname);
6845 chk_expr_dynamic_part(exp_val, false);
6846 break;
6847 case OPTYPE_TMR_READ: // r1
6848 case OPTYPE_TMR_RUNNING: // r1
6849 chk_expr_operand_tmrref(u.expr.r1, the, opname);
6850 chk_expr_dynamic_part(exp_val, true);
6851 break;
6852 case OPTYPE_EXECUTE: // r1 [v2] // testcase
6853 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
6854 chk_expr_dynamic_part(exp_val, true, false, false);
6855 break;
6856 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
6857 chk_expr_operand_comptyperef_create();
6858 v2=u.expr.v2;
6859 if(v2) {
6860 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6861 v2->set_lowerid_to_ref();
6862 tt2=v2->get_expr_returntype(exp_val);
6863 chk_expr_operandtype_cstr(tt2, first, opname, v2);
6864 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6865 }
6866 v3=u.expr.v3;
6867 if(v3) {
6868 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6869 v3->set_lowerid_to_ref();
6870 tt3=v3->get_expr_returntype(exp_val);
6871 chk_expr_operandtype_cstr(tt3, second, opname, v3);
6872 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6873 }
6874 chk_expr_dynamic_part(exp_val, false);
6875 break;
6876 case OPTYPE_ACTIVATE: // r1 // altstep
6877 chk_expr_operand_activate(u.expr.r1, the, opname);
6878 chk_expr_dynamic_part(exp_val, true);
6879 break;
6880 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
6881 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6882 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
6883 opname);
6884 delete u.expr.t_list2;
6885 u.expr.ap_list2 = parlist;
6886 chk_expr_dynamic_part(exp_val, true);
6887 break; }
6888 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
6889 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6890 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
6891 u.expr.v3, the, opname);
6892 delete u.expr.t_list2;
6893 u.expr.ap_list2 = parlist;
6894 chk_expr_dynamic_part(exp_val, true);
6895 break; }
6896 case OPTYPE_DECOMP:
6897 error("Built-in function `%s' is not yet supported", opname);
6898 set_valuetype(V_ERROR);
6899 break;
6900 case OPTYPE_REPLACE: {
6901 Type::expected_value_t ti_exp_val = exp_val;
6902 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6903 ti_exp_val = Type::EXPECTED_TEMPLATE;
6904 {
6905 Error_Context cntxt(this, "In the first operand of operation `%s'",
6906 opname);
6907 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6908 if (!governor) return;
6909 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6910 if (valuetype != V_ERROR)
6911 u.expr.ti1->get_Template()->chk_specific_value(false);
6912 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6913 }
6914 v2 = u.expr.v2;
6915 {
6916 Error_Context cntxt(this, "In the second operand of operation `%s'",
6917 opname);
6918 v2->set_lowerid_to_ref();
6919 tt2 = v2->get_expr_returntype(exp_val);
6920 chk_expr_operandtype_int(tt2, second, opname, v2);
6921 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6922 chk_expr_val_int_pos0(v2, second, opname);
6923 }
6924 v3 = u.expr.v3;
6925 {
6926 Error_Context cntxt(this, "In the third operand of operation `%s'",
6927 opname);
6928 v3->set_lowerid_to_ref();
6929 tt3 = v3->get_expr_returntype(exp_val);
6930 chk_expr_operandtype_int(tt3, third, opname, v3);
6931 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6932 chk_expr_val_int_pos0(v3, third, opname);
6933 }
6934 {
6935 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
6936 opname);
6937 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
6938 if (!governor) return;
6939 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
6940 if (valuetype != V_ERROR)
6941 u.expr.ti4->get_Template()->chk_specific_value(false);
6942 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
6943 }
6944 chk_expr_operands_replace();
6945 break; }
6946 case OPTYPE_LOG2STR: {
6947 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6948 u.expr.logargs->chk();
6949 if (!semantic_check_only) u.expr.logargs->join_strings();
6950 break; }
6951 case OPTYPE_TTCN2STRING: {
6952 Error_Context cntxt(this, "In the parameter of ttcn2string()");
6953 Type::expected_value_t ti_exp_val = exp_val;
6954 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6955 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6956 if (!governor) return;
6957 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6958 } break;
6959 default:
6960 FATAL_ERROR("chk_expr_operands()");
6961 } // switch optype
6962 }
6963
6964 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6965 // the result of evaluating the expression. E.g. V_BOOL for
6966 // OPTYPE_ISCHOSEN.
6967 void Value::evaluate_value(ReferenceChain *refch,
6968 Type::expected_value_t exp_val)
6969 {
6970 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
6971 if(u.expr.state!=EXPR_NOT_CHECKED) return;
6972
6973 u.expr.state=EXPR_CHECKING;
6974
6975 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
6976 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
6977 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
6978
6979 if(valuetype==V_ERROR) return;
6980 if(u.expr.state==EXPR_CHECKING_ERR) {
6981 u.expr.state=EXPR_CHECKED;
6982 set_valuetype(V_ERROR);
6983 return;
6984 }
6985
6986 u.expr.state=EXPR_CHECKED;
6987
6988 Value *v1, *v2, *v3, *v4;
6989 switch(u.expr.v_optype) {
6990 case OPTYPE_RND: // -
6991 case OPTYPE_COMP_NULL: // the only foldable in this group
6992 case OPTYPE_COMP_MTC:
6993 case OPTYPE_COMP_SYSTEM:
6994 case OPTYPE_COMP_SELF:
6995 case OPTYPE_COMP_RUNNING_ANY:
6996 case OPTYPE_COMP_RUNNING_ALL:
6997 case OPTYPE_COMP_ALIVE_ANY:
6998 case OPTYPE_COMP_ALIVE_ALL:
6999 case OPTYPE_TMR_RUNNING_ANY:
7000 case OPTYPE_GETVERDICT:
7001 case OPTYPE_RNDWITHVAL: // v1
7002 case OPTYPE_COMP_RUNNING: // v1
7003 case OPTYPE_COMP_ALIVE:
7004 case OPTYPE_TMR_READ:
7005 case OPTYPE_TMR_RUNNING:
7006 case OPTYPE_ACTIVATE:
7007 case OPTYPE_ACTIVATE_REFD:
7008 case OPTYPE_EXECUTE: // r1 [v2]
7009 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7010 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7011 case OPTYPE_MATCH: // v1 t2
7012 case OPTYPE_ISCHOSEN_T:
7013 case OPTYPE_LOG2STR:
7014 case OPTYPE_ENCODE:
7015 case OPTYPE_DECODE:
7016 case OPTYPE_ISBOUND:
7017 case OPTYPE_ISPRESENT:
7018 case OPTYPE_TTCN2STRING:
7019 case OPTYPE_UNICHAR2OCT:
7020 case OPTYPE_OCT2UNICHAR:
7021 case OPTYPE_ENCODE_BASE64:
7022 case OPTYPE_DECODE_BASE64:
7023 break;
7024 case OPTYPE_TESTCASENAME: { // -
7025 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7026 Ttcn::StatementBlock *my_sb =
7027 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7028 if (!my_sb) break;
7029 Ttcn::Definition *my_def = my_sb->get_my_def();
7030 if (!my_def) { // In control part.
7031 set_val_str(new string(""));
7032 valuetype = V_CSTR;
7033 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7034 set_val_str(new string(my_def->get_id().get_dispname()));
7035 valuetype = V_CSTR;
7036 }
7037 break; }
7038 case OPTYPE_UNARYPLUS: // v1
7039 v1=u.expr.v1;
7040 u.expr.v1=0;
7041 copy_and_destroy(v1);
7042 break;
7043 case OPTYPE_UNARYMINUS:
7044 if (is_unfoldable()) break;
7045 v1 = u.expr.v1->get_value_refd_last();
7046 switch (v1->valuetype) {
7047 case V_INT: {
7048 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7049 if (!i) FATAL_ERROR("Value::evaluate_value()");
7050 clean_up();
7051 valuetype = V_INT;
7052 u.val_Int = i;
7053 break; }
7054 case V_REAL: {
7055 ttcn3float r = v1->get_val_Real();
7056 clean_up();
7057 valuetype = V_REAL;
7058 u.val_Real = -r;
7059 break; }
7060 default:
7061 FATAL_ERROR("Value::evaluate_value()");
7062 }
7063 break;
7064 case OPTYPE_NOT: {
7065 if(is_unfoldable()) break;
7066 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7067 clean_up();
7068 valuetype=V_BOOL;
7069 u.val_bool=!b;
7070 break;}
7071 case OPTYPE_NOT4B: {
7072 if(is_unfoldable()) break;
7073 v1=u.expr.v1->get_value_refd_last();
7074 const string& s = v1->get_val_str();
7075 valuetype_t vt=v1->valuetype;
7076 clean_up();
7077 valuetype=vt;
7078 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7079 break;}
7080 case OPTYPE_BIT2HEX: {
7081 if(is_unfoldable()) break;
7082 v1=u.expr.v1->get_value_refd_last();
7083 const string& s = v1->get_val_str();
7084 clean_up();
7085 valuetype=V_HSTR;
7086 set_val_str(bit2hex(s));
7087 break;}
7088 case OPTYPE_BIT2OCT: {
7089 if(is_unfoldable()) break;
7090 v1=u.expr.v1->get_value_refd_last();
7091 const string& s = v1->get_val_str();
7092 clean_up();
7093 valuetype=V_OSTR;
7094 set_val_str(bit2oct(s));
7095 break;}
7096 case OPTYPE_BIT2STR:
7097 case OPTYPE_HEX2STR:
7098 case OPTYPE_OCT2STR: {
7099 if(is_unfoldable()) break;
7100 v1=u.expr.v1->get_value_refd_last();
7101 const string& s = v1->get_val_str();
7102 clean_up();
7103 valuetype=V_CSTR;
7104 set_val_str(new string(s));
7105 break;}
7106 case OPTYPE_BIT2INT: {
7107 if (is_unfoldable()) break;
7108 v1 = u.expr.v1->get_value_refd_last();
7109 const string& s = v1->get_val_str();
7110 clean_up();
7111 valuetype = V_INT;
7112 u.val_Int = bit2int(s);
7113 break; }
7114 case OPTYPE_CHAR2INT: {
7115 if (is_unfoldable()) break;
7116 v1 = u.expr.v1->get_value_refd_last();
7117 char c = v1->get_val_str()[0];
7118 clean_up();
7119 valuetype = V_INT;
7120 u.val_Int = new int_val_t((Int)c);
7121 break; }
7122 case OPTYPE_CHAR2OCT: {
7123 if(is_unfoldable()) break;
7124 v1=u.expr.v1->get_value_refd_last();
7125 const string& s = v1->get_val_str();
7126 clean_up();
7127 valuetype=V_OSTR;
7128 set_val_str(char2oct(s));
7129 break;}
7130 case OPTYPE_STR2INT: {
7131 if (is_unfoldable()) break;
7132 v1 = u.expr.v1->get_value_refd_last();
7133 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7134 clean_up();
7135 valuetype = V_INT;
7136 u.val_Int = i;
7137 /** \todo hiba eseten lenyeli... */
7138 break; }
7139 case OPTYPE_STR2FLOAT: {
7140 if(is_unfoldable()) break;
7141 v1=u.expr.v1->get_value_refd_last();
7142 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7143 clean_up();
7144 valuetype=V_REAL;
7145 u.val_Real=r;
7146 /** \todo hiba eseten lenyeli... */
7147 break;}
7148 case OPTYPE_STR2BIT: {
7149 if(is_unfoldable()) break;
7150 v1=u.expr.v1->get_value_refd_last();
7151 const string& s = v1->get_val_str();
7152 clean_up();
7153 valuetype=V_BSTR;
7154 set_val_str(new string(s));
7155 break;}
7156 case OPTYPE_STR2HEX:
7157 case OPTYPE_OCT2HEX: {
7158 if(is_unfoldable()) break;
7159 v1=u.expr.v1->get_value_refd_last();
7160 const string& s = v1->get_val_str();
7161 clean_up();
7162 valuetype=V_HSTR;
7163 set_val_str(to_uppercase(s));
7164 break;}
7165 case OPTYPE_STR2OCT: {
7166 if(is_unfoldable()) break;
7167 v1=u.expr.v1->get_value_refd_last();
7168 const string& s = v1->get_val_str();
7169 clean_up();
7170 valuetype=V_OSTR;
7171 set_val_str(to_uppercase(s));
7172 break;}
7173 case OPTYPE_FLOAT2INT: {
7174 if (is_unfoldable()) break;
7175 v1 = u.expr.v1->get_value_refd_last();
7176 ttcn3float r = v1->get_val_Real();
7177 clean_up();
7178 valuetype = V_INT;
7179 u.val_Int = float2int(r, *u.expr.v1);
7180 break;}
7181 case OPTYPE_FLOAT2STR: {
7182 if(is_unfoldable()) break;
7183 v1=u.expr.v1->get_value_refd_last();
7184 ttcn3float r=v1->get_val_Real();
7185 clean_up();
7186 valuetype=V_CSTR;
7187 set_val_str(float2str(r));
7188 break;}
7189 case OPTYPE_HEX2BIT:
7190 case OPTYPE_OCT2BIT: {
7191 if(is_unfoldable()) break;
7192 v1=u.expr.v1->get_value_refd_last();
7193 const string& s = v1->get_val_str();
7194 clean_up();
7195 valuetype=V_BSTR;
7196 set_val_str(hex2bit(s));
7197 break;}
7198 case OPTYPE_HEX2INT:
7199 case OPTYPE_OCT2INT: {
7200 if(is_unfoldable()) break;
7201 v1=u.expr.v1->get_value_refd_last();
7202 const string& s = v1->get_val_str();
7203 clean_up();
7204 valuetype=V_INT;
7205 u.val_Int=hex2int(s);
7206 break;}
7207 case OPTYPE_HEX2OCT: {
7208 if(is_unfoldable()) break;
7209 v1=u.expr.v1->get_value_refd_last();
7210 const string& s = v1->get_val_str();
7211 clean_up();
7212 valuetype=V_OSTR;
7213 set_val_str(hex2oct(s));
7214 break;}
7215 case OPTYPE_INT2CHAR: {
7216 if (is_unfoldable()) break;
7217 v1 = u.expr.v1->get_value_refd_last();
7218 const int_val_t *c_int = v1->get_val_Int();
7219 char c = static_cast<char>(c_int->get_val());
7220 clean_up();
7221 valuetype = V_CSTR;
7222 set_val_str(new string(1, &c));
7223 break; }
7224 case OPTYPE_INT2UNICHAR: {
7225 if (is_unfoldable()) break;
7226 v1 = u.expr.v1->get_value_refd_last();
7227 const int_val_t *i_int = v1->get_val_Int();
7228 Int i = i_int->get_val();
7229 clean_up();
7230 valuetype = V_USTR;
7231 set_val_ustr(int2unichar(i));
7232 u.ustr.convert_str = false;
7233 break; }
7234 case OPTYPE_INT2FLOAT: {
7235 if (is_unfoldable()) break;
7236 v1 = u.expr.v1->get_value_refd_last();
7237 const int_val_t *i_int = v1->get_val_Int();
7238 Real i_int_real = i_int->to_real();
7239 clean_up();
7240 valuetype = V_REAL;
7241 u.val_Real = i_int_real;
7242 break; }
7243 case OPTYPE_INT2STR: {
7244 if (is_unfoldable()) break;
7245 v1 = u.expr.v1->get_value_refd_last();
7246 const int_val_t *i_int = v1->get_val_Int();
7247 string *i_int_str = new string(i_int->t_str());
7248 clean_up();
7249 valuetype = V_CSTR;
7250 set_val_str(i_int_str);
7251 break; }
7252 case OPTYPE_OCT2CHAR: {
7253 if(is_unfoldable()) break;
7254 v1=u.expr.v1->get_value_refd_last();
7255 const string& s = v1->get_val_str();
7256 clean_up();
7257 valuetype=V_CSTR;
7258 set_val_str(oct2char(s));
7259 break;}
7260 case OPTYPE_GET_STRINGENCODING: {
7261 if(is_unfoldable()) break;
7262 v1 = u.expr.v1->get_value_refd_last();
7263 const string& s1 = v1->get_val_str();
7264 clean_up();
7265 valuetype = V_CSTR;
7266 set_val_str(get_stringencoding(s1));
7267 break;}
7268 case OPTYPE_REMOVE_BOM: {
7269 if(is_unfoldable()) break;
7270 v1 = u.expr.v1->get_value_refd_last();
7271 const string& s1 = v1->get_val_str();
7272 clean_up();
7273 valuetype = V_OSTR;
7274 set_val_str(remove_bom(s1));
7275 break;}
7276 case OPTYPE_ENUM2INT: {
7277 if(is_unfoldable()) break;
7278 v1=u.expr.v1->get_value_refd_last();
7279 Type* enum_type = v1->get_my_governor();
7280 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7281 clean_up();
7282 valuetype = V_INT;
7283 u.val_Int = new int_val_t(enum_val);
7284 break;}
7285 case OPTYPE_UNICHAR2INT:
7286 if (is_unfoldable()) {
7287 // replace the operation with char2int() if the operand is a charstring
7288 // value to avoid its unnecessary conversion to universal charstring
7289 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7290 u.expr.v_optype = OPTYPE_CHAR2INT;
7291 } else {
7292 v1=u.expr.v1->get_value_refd_last();
7293 const ustring& s = v1->get_val_ustr();
7294 clean_up();
7295 valuetype=V_INT;
7296 u.val_Int=new int_val_t(unichar2int(s));
7297 }
7298 break;
7299 case OPTYPE_UNICHAR2CHAR:
7300 v1 = u.expr.v1;
7301 if (is_unfoldable()) {
7302 // replace the operation with its operand if it is a charstring
7303 // value to avoid its unnecessary conversion to universal charstring
7304 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7305 u.expr.v1 = 0;
7306 copy_and_destroy(v1);
7307 }
7308 } else {
7309 v1 = v1->get_value_refd_last();
7310 const ustring& s = v1->get_val_ustr();
7311 clean_up();
7312 valuetype = V_CSTR;
7313 set_val_str(new string(s));
7314 }
7315 break;
7316 case OPTYPE_MULTIPLY: { // v1 v2
7317 if (!is_unfoldable()) goto eval_arithmetic;
7318 v1 = u.expr.v1->get_value_refd_last();
7319 v2 = u.expr.v2->get_value_refd_last();
7320 if (v1->is_unfoldable()) v1 = v2;
7321 if (v1->is_unfoldable()) break;
7322 switch(v1->valuetype) {
7323 case V_INT: {
7324 if (*v1->get_val_Int() != 0) break;
7325 clean_up();
7326 valuetype = V_INT;
7327 u.val_Int = new int_val_t((Int)0);
7328 break; }
7329 case V_REAL: {
7330 if (v1->get_val_Real() != 0.0) break;
7331 clean_up();
7332 valuetype = V_REAL;
7333 u.val_Real = 0.0;
7334 break; }
7335 default:
7336 FATAL_ERROR("Value::evaluate_value()");
7337 }
7338 break; }
7339 case OPTYPE_ADD: // v1 v2
7340 case OPTYPE_SUBTRACT:
7341 case OPTYPE_DIVIDE:
7342 case OPTYPE_MOD:
7343 case OPTYPE_REM: {
7344 eval_arithmetic:
7345 if(is_unfoldable()) break;
7346 v1=u.expr.v1->get_value_refd_last();
7347 v2=u.expr.v2->get_value_refd_last();
7348 operationtype_t ot=u.expr.v_optype;
7349 switch (v1->valuetype) {
7350 case V_INT: {
7351 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7352 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7353 clean_up();
7354 valuetype = V_INT;
7355 switch (ot) {
7356 case OPTYPE_ADD:
7357 u.val_Int = new int_val_t(*i1 + *i2);
7358 break;
7359 case OPTYPE_SUBTRACT:
7360 u.val_Int = new int_val_t(*i1 - *i2);
7361 break;
7362 case OPTYPE_MULTIPLY:
7363 u.val_Int = new int_val_t(*i1 * *i2);
7364 break;
7365 case OPTYPE_DIVIDE:
7366 u.val_Int = new int_val_t(*i1 / *i2);
7367 break;
7368 case OPTYPE_MOD:
7369 u.val_Int = new int_val_t(mod(*i1, *i2));
7370 break;
7371 case OPTYPE_REM:
7372 u.val_Int = new int_val_t(rem(*i1, *i2));
7373 break;
7374 default:
7375 FATAL_ERROR("Value::evaluate_value()");
7376 }
7377 delete i1;
7378 delete i2;
7379 break; }
7380 case V_REAL: {
7381 ttcn3float r1=v1->get_val_Real();
7382 ttcn3float r2=v2->get_val_Real();
7383 clean_up();
7384 valuetype=V_REAL;
7385 switch(ot) {
7386 case OPTYPE_ADD:
7387 u.val_Real=r1+r2;
7388 break;
7389 case OPTYPE_SUBTRACT:
7390 u.val_Real=r1-r2;
7391 break;
7392 case OPTYPE_MULTIPLY:
7393 u.val_Real=r1*r2;
7394 break;
7395 case OPTYPE_DIVIDE:
7396 u.val_Real=r1/r2;
7397 break;
7398 default:
7399 FATAL_ERROR("Value::evaluate_value()");
7400 }
7401 break;}
7402 default:
7403 FATAL_ERROR("Value::evaluate_value()");
7404 }
7405 break;}
7406 case OPTYPE_CONCAT: {
7407 if(is_unfoldable()) break;
7408 v1=u.expr.v1->get_value_refd_last();
7409 v2=u.expr.v2->get_value_refd_last();
7410 valuetype_t vt = v1->valuetype;
7411 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7412 const ustring& s1 = v1->get_val_ustr();
7413 const ustring& s2 = v2->get_val_ustr();
7414 clean_up();
7415 valuetype = V_USTR;
7416 set_val_ustr(new ustring(s1 + s2));
7417 u.ustr.convert_str = false;
7418 } else {
7419 const string& s1 = v1->get_val_str();
7420 const string& s2 = v2->get_val_str();
7421 clean_up();
7422 valuetype = vt;
7423 set_val_str(new string(s1 + s2));
7424 }
7425 break;}
7426 case OPTYPE_EQ: {
7427 if(is_unfoldable()) break;
7428 v1=u.expr.v1->get_value_refd_last();
7429 v2=u.expr.v2->get_value_refd_last();
7430 bool b=*v1==*v2;
7431 clean_up();
7432 valuetype=V_BOOL;
7433 u.val_bool=b;
7434 break;}
7435 case OPTYPE_NE: {
7436 if(is_unfoldable()) break;
7437 v1=u.expr.v1->get_value_refd_last();
7438 v2=u.expr.v2->get_value_refd_last();
7439 bool b=*v1==*v2;
7440 clean_up();
7441 valuetype=V_BOOL;
7442 u.val_bool=!b;
7443 break;}
7444 case OPTYPE_LT: {
7445 if(is_unfoldable()) break;
7446 v1=u.expr.v1->get_value_refd_last();
7447 v2=u.expr.v2->get_value_refd_last();
7448 bool b=*v1<*v2;
7449 clean_up();
7450 valuetype=V_BOOL;
7451 u.val_bool=b;
7452 break;}
7453 case OPTYPE_GT: {
7454 if(is_unfoldable()) break;
7455 v1=u.expr.v1->get_value_refd_last();
7456 v2=u.expr.v2->get_value_refd_last();
7457 bool b=*v2<*v1;
7458 clean_up();
7459 valuetype=V_BOOL;
7460 u.val_bool=b;
7461 break;}
7462 case OPTYPE_GE: {
7463 if(is_unfoldable()) break;
7464 v1=u.expr.v1->get_value_refd_last();
7465 v2=u.expr.v2->get_value_refd_last();
7466 bool b=*v1<*v2;
7467 clean_up();
7468 valuetype=V_BOOL;
7469 u.val_bool=!b;
7470 break;}
7471 case OPTYPE_LE: {
7472 if(is_unfoldable()) break;
7473 v1=u.expr.v1->get_value_refd_last();
7474 v2=u.expr.v2->get_value_refd_last();
7475 bool b=*v2<*v1;
7476 clean_up();
7477 valuetype=V_BOOL;
7478 u.val_bool=!b;
7479 break;}
7480 case OPTYPE_AND:
7481 v1 = u.expr.v1->get_value_refd_last();
7482 if (v1->valuetype == V_BOOL) {
7483 if (v1->get_val_bool()) {
7484 // the left operand is a literal "true"
7485 // substitute the expression with the right operand
7486 v2 = u.expr.v2;
7487 u.expr.v2 = 0;
7488 copy_and_destroy(v2);
7489 } else {
7490 // the left operand is a literal "false"
7491 // the result must be false regardless the right operand
7492 // because of the short circuit evaluation rule
7493 clean_up();
7494 valuetype = V_BOOL;
7495 u.val_bool = false;
7496 }
7497 } else {
7498 // we must keep the left operand because of the potential side effects
7499 // the right operand can only be eliminated if it is a literal "true"
7500 v2 = u.expr.v2->get_value_refd_last();
7501 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7502 v1 = u.expr.v1;
7503 u.expr.v1 = 0;
7504 copy_and_destroy(v1);
7505 }
7506 }
7507 break;
7508 case OPTYPE_OR:
7509 v1 = u.expr.v1->get_value_refd_last();
7510 if (v1->valuetype == V_BOOL) {
7511 if (v1->get_val_bool()) {
7512 // the left operand is a literal "true"
7513 // the result must be true regardless the right operand
7514 // because of the short circuit evaluation rule
7515 clean_up();
7516 valuetype = V_BOOL;
7517 u.val_bool = true;
7518 } else {
7519 // the left operand is a literal "false"
7520 // substitute the expression with the right operand
7521 v2 = u.expr.v2;
7522 u.expr.v2 = 0;
7523 copy_and_destroy(v2);
7524 }
7525 } else {
7526 // we must keep the left operand because of the potential side effects
7527 // the right operand can only be eliminated if it is a literal "false"
7528 v2 = u.expr.v2->get_value_refd_last();
7529 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7530 v1 = u.expr.v1;
7531 u.expr.v1 = 0;
7532 copy_and_destroy(v1);
7533 }
7534 }
7535 break;
7536 case OPTYPE_XOR: {
7537 if(is_unfoldable()) break;
7538 v1=u.expr.v1->get_value_refd_last();
7539 v2=u.expr.v2->get_value_refd_last();
7540 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7541 clean_up();
7542 valuetype=V_BOOL;
7543 u.val_bool=b;
7544 break;}
7545 case OPTYPE_AND4B: {
7546 if(is_unfoldable()) break;
7547 v1=u.expr.v1->get_value_refd_last();
7548 v2=u.expr.v2->get_value_refd_last();
7549 valuetype_t vt=v1->valuetype;
7550 const string& s1 = v1->get_val_str();
7551 const string& s2 = v2->get_val_str();
7552 clean_up();
7553 valuetype=vt;
7554 set_val_str(and4b(s1, s2));
7555 break;}
7556 case OPTYPE_OR4B: {
7557 if(is_unfoldable()) break;
7558 v1=u.expr.v1->get_value_refd_last();
7559 v2=u.expr.v2->get_value_refd_last();
7560 valuetype_t vt=v1->valuetype;
7561 const string& s1 = v1->get_val_str();
7562 const string& s2 = v2->get_val_str();
7563 clean_up();
7564 valuetype=vt;
7565 set_val_str(or4b(s1, s2));
7566 break;}
7567 case OPTYPE_XOR4B: {
7568 if(is_unfoldable()) break;
7569 v1=u.expr.v1->get_value_refd_last();
7570 v2=u.expr.v2->get_value_refd_last();
7571 valuetype_t vt=v1->valuetype;
7572 const string& s1 = v1->get_val_str();
7573 const string& s2 = v2->get_val_str();
7574 clean_up();
7575 valuetype=vt;
7576 set_val_str(xor4b(s1, s2));
7577 break;}
7578 case OPTYPE_SHL: {
7579 if(is_unfoldable()) break;
7580 v1=u.expr.v1->get_value_refd_last();
7581 v2=u.expr.v2->get_value_refd_last();
7582 valuetype_t vt=v1->valuetype;
7583 const string& s = v1->get_val_str();
7584 const int_val_t *i_int = v2->get_val_Int();
7585 Int i=i_int->get_val();
7586 if(vt==V_OSTR) i*=2;
7587 clean_up();
7588 valuetype=vt;
7589 set_val_str(shift_left(s, i));
7590 break;}
7591 case OPTYPE_SHR: {
7592 if(is_unfoldable()) break;
7593 v1=u.expr.v1->get_value_refd_last();
7594 v2=u.expr.v2->get_value_refd_last();
7595 valuetype_t vt=v1->valuetype;
7596 const string& s = v1->get_val_str();
7597 const int_val_t *i_int = v2->get_val_Int();
7598 Int i=i_int->get_val();
7599 if(vt==V_OSTR) i*=2;
7600 clean_up();
7601 valuetype=vt;
7602 set_val_str(shift_right(s, i));
7603 break;}
7604 case OPTYPE_ROTL: {
7605 if(is_unfoldable()) break;
7606 v1=u.expr.v1->get_value_refd_last();
7607 v2=u.expr.v2->get_value_refd_last();
7608 valuetype_t vt=v1->valuetype;
7609 const int_val_t *i_int=v2->get_val_Int();
7610 Int i=i_int->get_val();
7611 if(vt==V_USTR) {
7612 const ustring& s = v1->get_val_ustr();
7613 clean_up();
7614 valuetype=vt;
7615 set_val_ustr(rotate_left(s, i));
7616 u.ustr.convert_str = false;
7617 }
7618 else {
7619 if(vt==V_OSTR) i*=2;
7620 const string& s = v1->get_val_str();
7621 clean_up();
7622 valuetype=vt;
7623 set_val_str(rotate_left(s, i));
7624 }
7625 break;}
7626 case OPTYPE_ROTR: {
7627 if(is_unfoldable()) break;
7628 v1=u.expr.v1->get_value_refd_last();
7629 v2=u.expr.v2->get_value_refd_last();
7630 valuetype_t vt=v1->valuetype;
7631 const int_val_t *i_int=v2->get_val_Int();
7632 Int i=i_int->get_val();
7633 if(vt==V_USTR) {
7634 const ustring& s = v1->get_val_ustr();
7635 clean_up();
7636 valuetype=vt;
7637 set_val_ustr(rotate_right(s, i));
7638 u.ustr.convert_str = false;
7639 }
7640 else {
7641 if(vt==V_OSTR) i*=2;
7642 const string& s = v1->get_val_str();
7643 clean_up();
7644 valuetype=vt;
7645 set_val_str(rotate_right(s, i));
7646 }
7647 break;}
7648 case OPTYPE_INT2BIT: {
7649 if (is_unfoldable()) break;
7650 v1 = u.expr.v1->get_value_refd_last();
7651 v2 = u.expr.v2->get_value_refd_last();
7652 const int_val_t *i1_int = v1->get_val_Int();
7653 const int_val_t *i2_int = v2->get_val_Int();
7654 string *val = int2bit(*i1_int, i2_int->get_val());
7655 clean_up();
7656 valuetype = V_BSTR;
7657 set_val_str(val);
7658 break; }
7659 case OPTYPE_INT2HEX: {
7660 if (is_unfoldable()) break;
7661 v1 = u.expr.v1->get_value_refd_last();
7662 v2 = u.expr.v2->get_value_refd_last();
7663 const int_val_t *i1_int = v1->get_val_Int();
7664 const int_val_t *i2_int = v2->get_val_Int();
7665 // Do it before the `clean_up'. i2_int is already checked.
7666 string *val = int2hex(*i1_int, i2_int->get_val());
7667 clean_up();
7668 valuetype = V_HSTR;
7669 set_val_str(val);
7670 break; }
7671 case OPTYPE_INT2OCT: {
7672 if (is_unfoldable()) break;
7673 v1 = u.expr.v1->get_value_refd_last();
7674 v2 = u.expr.v2->get_value_refd_last();
7675 const int_val_t i1_int(*v1->get_val_Int());
7676 // `v2' is a native integer.
7677 Int i2_int = v2->get_val_Int()->get_val() * 2;
7678 clean_up();
7679 valuetype = V_OSTR;
7680 set_val_str(int2hex(i1_int, i2_int));
7681 break; }
7682 case OPTYPE_SUBSTR: {
7683 if(is_unfoldable()) break;
7684 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7685 v2=u.expr.v2->get_value_refd_last();
7686 v3=u.expr.v3->get_value_refd_last();
7687 valuetype_t vt=v1->valuetype;
7688 const int_val_t *i2_int=v2->get_val_Int();
7689 const int_val_t *i3_int=v3->get_val_Int();
7690 Int i2=i2_int->get_val();
7691 Int i3=i3_int->get_val();
7692 if(vt==V_USTR) {
7693 const ustring& s = v1->get_val_ustr();
7694 clean_up();
7695 valuetype=vt;
7696 set_val_ustr(new ustring(s.substr(i2, i3)));
7697 u.ustr.convert_str = false;
7698 }
7699 else {
7700 if(vt==V_OSTR) {
7701 i2*=2;
7702 i3*=2;
7703 }
7704 const string& s = v1->get_val_str();
7705 clean_up();
7706 valuetype=vt;
7707 set_val_str(new string(s.substr(i2, i3)));
7708 }
7709 break;}
7710 case OPTYPE_REPLACE: {
7711 if(is_unfoldable()) break;
7712 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7713 v2=u.expr.v2->get_value_refd_last();
7714 v3=u.expr.v3->get_value_refd_last();
7715 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7716 valuetype_t vt=v1->valuetype;
7717 const int_val_t *i2_int=v2->get_val_Int();
7718 const int_val_t *i3_int=v3->get_val_Int();
7719 Int i2=i2_int->get_val();
7720 Int i3=i3_int->get_val();
7721 switch(vt) {
7722 case V_BSTR: {
7723 string *s1 = new string(v1->get_val_str());
7724 const string& s2 = v4->get_val_str();
7725 clean_up();
7726 valuetype=vt;
7727 s1->replace(i2, i3, s2);
7728 set_val_str(s1);
7729 break;}
7730 case V_HSTR: {
7731 string *s1 = new string(v1->get_val_str());
7732 const string& s2 = v4->get_val_str();
7733 clean_up();
7734 valuetype=vt;
7735 s1->replace(i2, i3, s2);
7736 set_val_str(s1);
7737 break;}
7738 case V_OSTR: {
7739 i2*=2;
7740 i3*=2;
7741 string *s1 = new string(v1->get_val_str());
7742 const string& s2 = v4->get_val_str();
7743 clean_up();
7744 valuetype=vt;
7745 s1->replace(i2, i3, s2);
7746 set_val_str(s1);
7747 break;}
7748 case V_CSTR: {
7749 string *s1 = new string(v1->get_val_str());
7750 const string& s2 = v4->get_val_str();
7751 clean_up();
7752 valuetype=vt;
7753 s1->replace(i2, i3, s2);
7754 set_val_str(s1);
7755 break;}
7756 case V_USTR: {
7757 ustring *s1 = new ustring(v1->get_val_ustr());
7758 const ustring& s2 = v4->get_val_ustr();
7759 clean_up();
7760 valuetype=vt;
7761 s1->replace(i2, i3, s2);
7762 set_val_ustr(s1);
7763 u.ustr.convert_str = false;
7764 break;}
7765 default:
7766 FATAL_ERROR("Value::evaluate_value()");
7767 }
7768 break; }
7769 case OPTYPE_REGEXP: {
7770 if (is_unfoldable()) break;
7771 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7772 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7773 v3=u.expr.v3->get_value_refd_last();
7774 const int_val_t *i3_int = v3->get_val_Int();
7775 Int i3 = i3_int->get_val();
7776 if (v1->valuetype == V_CSTR) {
7777 const string& s1 = v1->get_val_str();
7778 const string& s2 = v2->get_val_str();
7779 string *result = regexp(s1, s2, i3);
7780 clean_up();
7781 valuetype = V_CSTR;
7782 set_val_str(result);
7783 } if (v1->valuetype == V_USTR) {
7784 const ustring& s1 = v1->get_val_ustr();
7785 const ustring& s2 = v2->get_val_ustr();
7786 ustring *result = regexp(s1, s2, i3);
7787 clean_up();
7788 valuetype = V_USTR;
7789 set_val_ustr(result);
7790 u.ustr.convert_str = false;
7791 }
7792 break; }
7793 case OPTYPE_LENGTHOF:{
7794 if(is_unfoldable()) break;
7795 v1=u.expr.ti1->get_Template()->get_specific_value()
7796 ->get_value_refd_last();
7797 size_t i;
7798 if(v1->is_string_type(exp_val)) {
7799 i=v1->get_val_strlen();
7800 } else { // v1 is be seq/set of or array
7801 switch (v1->valuetype) {
7802 case V_SEQOF:
7803 case V_SETOF:
7804 case V_ARRAY: {
7805 if(v1->u.val_vs->is_indexed())
7806 { i = v1->u.val_vs->get_nof_ivs();}
7807 else { i = v1->u.val_vs->get_nof_vs();}
7808 break; }
7809 default:
7810 FATAL_ERROR("Value::evaluate_value()");
7811 }
7812 }
7813 clean_up();
7814 valuetype=V_INT;
7815 u.val_Int=new int_val_t(i);
7816 break;}
7817 case OPTYPE_SIZEOF: {
7818 Int i=chk_eval_expr_sizeof(refch, exp_val);
7819 if(i!=-1) {
7820 clean_up();
7821 valuetype=V_INT;
7822 u.val_Int=new int_val_t(i);
7823 }
7824 break;}
7825 case OPTYPE_ISVALUE: {
7826 if(is_unfoldable()) break;
7827 bool is_singleval = !u.expr.ti1->get_DerivedRef()
7828 && u.expr.ti1->get_Template()->is_Value();
7829 if (is_singleval) {
7830 Value * other_val = u.expr.ti1->get_Template()->get_Value();
7831 is_singleval = other_val->evaluate_isvalue(false);
7832 // is_singleval now contains the compile-time result of isvalue
7833 delete other_val;
7834 }
7835 clean_up();
7836 valuetype = V_BOOL;
7837 u.val_bool = is_singleval;
7838 break;}
7839 case OPTYPE_ISCHOSEN_V: {
7840 if (is_unfoldable()) break;
7841 v1 = u.expr.v1->get_value_refd_last();
7842 bool b = v1->field_is_chosen(*u.expr.i2);
7843 clean_up();
7844 valuetype = V_BOOL;
7845 u.val_bool = b;
7846 break; }
7847 case OPTYPE_VALUEOF: // ti1
7848 if (!u.expr.ti1->get_DerivedRef() &&
7849 u.expr.ti1->get_Template()->is_Value() &&
7850 !u.expr.ti1->get_Type()) {
7851 // FIXME actually if the template instance has a type
7852 // it might still be foldable.
7853 // the argument is a single specific value
7854 v1 = u.expr.ti1->get_Template()->get_Value();
7855 Type *governor = my_governor;
7856 if (governor == NULL) {
7857 governor = u.expr.ti1->get_expr_governor(exp_val);
7858 if (governor != NULL) governor = governor->get_type_refd_last();
7859 }
7860 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
7861 if (governor == NULL)
7862 FATAL_ERROR("Value::evaluate_value()");
7863 clean_up();
7864 valuetype = v1->valuetype;
7865 u = v1->u;
7866 set_my_governor(governor);
7867 if (valuetype == V_REFD && u.ref.refd_last == v1)
7868 u.ref.refd_last = this;
7869 v1->valuetype = V_ERROR;
7870 delete v1;
7871 }
7872 break;
7873 case OPTYPE_UNDEF_RUNNING:
7874 default:
7875 FATAL_ERROR("Value::evaluate_value()");
7876 } // switch optype
7877 }
7878
7879 bool Value::evaluate_isvalue(bool from_sequence)
7880 {
7881 switch (valuetype) {
7882 case V_OMIT:
7883 // Omit is not a value unless a member of a sequence or set
7884 return from_sequence;
7885 case V_NOTUSED:
7886 return false;
7887 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7888 case V_BOOL: /**< boolean */
7889 case V_NAMEDINT: /**< integer / named number */
7890 case V_NAMEDBITS: /**< named bits (identifiers) */
7891 case V_INT: /**< integer */
7892 case V_REAL: /**< real/float */
7893 case V_ENUM: /**< enumerated */
7894 case V_BSTR: /**< bitstring */
7895 case V_HSTR: /**< hexstring */
7896 case V_OSTR: /**< octetstring */
7897 case V_CSTR: /**< charstring */
7898 case V_USTR: /**< universal charstring */
7899 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
7900 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
7901 case V_OID: /**< object identifier */
7902 case V_ROID: /**< relative object identifier */
7903 case V_VERDICT: /**< all verdicts */
7904 return true; // values of built-in types return true
7905
7906 // Code below was adapted from is_unfoldable(), false returned early.
7907 case V_CHOICE:
7908 return u.choice.alt_value->evaluate_isvalue(false);
7909
7910 case V_SEQOF:
7911 case V_SETOF:
7912 case V_ARRAY:
7913 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
7914 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
7915 return false;
7916 }
7917 }
7918 return true;
7919
7920 case V_SEQ:
7921 case V_SET:
7922 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
7923 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
7924 ->evaluate_isvalue(true)) return false;
7925 }
7926 return true;
7927
7928 case V_REFD:
7929 // alas, get_value_refd_last prevents this function from const
7930 return get_value_refd_last()->evaluate_isvalue(false);
7931
7932 case V_EXPR:
7933 switch (u.expr.v_optype) {
7934 // A constant null component reference is a corner case: it is foldable
7935 // but escapes unmodified from evaluate_value.
7936 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7937 // or is transformed into some other valuetype in evaluate_value.
7938 case OPTYPE_COMP_NULL:
7939 return false;
7940 default:
7941 break; // and fall through to the FATAL_ERROR
7942 }
7943 // no break
7944 default:
7945 FATAL_ERROR("Value::evaluate_isvalue()");
7946 break;
7947 }
7948 return true;
7949 }
7950
7951 void Value::evaluate_macro(Type::expected_value_t exp_val)
7952 {
7953 switch (u.macro) {
7954 case MACRO_MODULEID:
7955 if (!my_scope)
7956 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7957 set_val_str(new string(my_scope->get_scope_mod()
7958 ->get_modid().get_dispname()));
7959 valuetype = V_CSTR;
7960 break;
7961 case MACRO_FILENAME:
7962 case MACRO_BFILENAME: {
7963 const char *t_filename = get_filename();
7964 if (!t_filename)
7965 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7966 set_val_str(new string(t_filename));
7967 valuetype = V_CSTR;
7968 break; }
7969 case MACRO_FILEPATH: {
7970 const char *t_filename = get_filename();
7971 if (!t_filename)
7972 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7973 char *t_filepath = canonize_input_file(t_filename);
7974 if (!t_filepath)
7975 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7976 set_val_str(new string(t_filepath));
7977 valuetype = V_CSTR;
7978 Free(t_filepath);
7979 break; }
7980 case MACRO_LINENUMBER: {
7981 int t_lineno = get_first_line();
7982 if (t_lineno <= 0)
7983 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7984 set_val_str(new string(Int2string(t_lineno)));
7985 valuetype = V_CSTR;
7986 break; }
7987 case MACRO_LINENUMBER_C: {
7988 int t_lineno = get_first_line();
7989 if (t_lineno <= 0)
7990 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7991 u.val_Int = new int_val_t(t_lineno);
7992 valuetype = V_INT;
7993 break; }
7994 case MACRO_DEFINITIONID: {
7995 // cut the second part from the fullname separated by dots
7996 const string& t_fullname = get_fullname();
7997 size_t first_char = t_fullname.find('.') + 1;
7998 if (first_char >= t_fullname.size())
7999 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8000 t_fullname.c_str());
8001 set_val_str(new string(t_fullname.substr(first_char,
8002 t_fullname.find('.', first_char) - first_char)));
8003 valuetype = V_CSTR;
8004 break; }
8005 case MACRO_SCOPE: {
8006 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8007 set_val_str(new string(my_scope->get_scopeMacro_name()));
8008 valuetype = V_CSTR;
8009 break;
8010 }
8011 case MACRO_TESTCASEID: {
8012 if (exp_val == Type::EXPECTED_CONSTANT ||
8013 exp_val == Type::EXPECTED_STATIC_VALUE) {
8014 error("A %s value was expected instead of macro `%%testcaseId', "
8015 "which is evaluated at runtime",
8016 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8017 goto error;
8018 }
8019 if (!my_scope)
8020 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8021 Ttcn::StatementBlock *my_sb =
8022 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8023 if (!my_sb) {
8024 error("Usage of macro %%testcaseId is allowed only within the "
8025 "statement blocks of functions, altsteps and testcases");
8026 goto error;
8027 }
8028 Ttcn::Definition *my_def = my_sb->get_my_def();
8029 if (!my_def) {
8030 error("Macro %%testcaseId cannot be used in the control part. "
8031 "It is allowed only within the statement blocks of functions, "
8032 "altsteps and testcases");
8033 goto error;
8034 }
8035 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8036 // folding is possible only within testcases
8037 set_val_str(new string(my_def->get_id().get_dispname()));
8038 valuetype = V_CSTR;
8039 }
8040 break; }
8041 default:
8042 FATAL_ERROR("Value::evaluate_macro()");
8043 }
8044 return;
8045 error:
8046 set_valuetype(V_ERROR);
8047 }
8048
8049 void Value::add_id(Identifier *p_id)
8050 {
8051 switch(valuetype) {
8052 case V_NAMEDBITS:
8053 if(u.ids->has_key(p_id->get_name())) {
8054 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8055 // The Value does not take ownership for the identifier,
8056 // so it must be deleted (add_is acts as a sink).
8057 delete p_id;
8058 }
8059 else u.ids->add(p_id->get_name(), p_id);
8060 break;
8061 default:
8062 FATAL_ERROR("Value::add_id()");
8063 } // switch
8064 }
8065
8066 Value* Value::get_value_refd_last(ReferenceChain *refch,
8067 Type::expected_value_t exp_val)
8068 {
8069 set_lowerid_to_ref();
8070 switch (valuetype) {
8071 case V_INVOKE:
8072 // there might be a better place for this
8073 chk_invoke(exp_val);
8074 return this;
8075 case V_REFD:
8076 // use the cache if available
8077 if (u.ref.refd_last) return u.ref.refd_last;
8078 else {
8079 Assignment *ass = u.ref.ref->get_refd_assignment();
8080 if (!ass) {
8081 // the referred definition is not found
8082 set_valuetype(V_ERROR);
8083 } else {
8084 switch (ass->get_asstype()) {
8085 case Assignment::A_OBJECT:
8086 case Assignment::A_OS: {
8087 // the referred definition is an ASN.1 object or object set
8088 Setting *setting = u.ref.ref->get_refd_setting();
8089 if (!setting || setting->get_st() == S_ERROR) {
8090 // remain silent, the error has been already reported
8091 set_valuetype(V_ERROR);
8092 break;
8093 } else if (setting->get_st() != S_V) {
8094 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8095 " refer to a value", u.ref.ref->get_dispname().c_str());
8096 set_valuetype(V_ERROR);
8097 break;
8098 }
8099 bool destroy_refch;
8100 if (refch) {
8101 refch->mark_state();
8102 destroy_refch = false;
8103 } else {
8104 refch = new ReferenceChain(this,
8105 "While searching referenced value");
8106 destroy_refch = true;
8107 }
8108 if (refch->add(get_fullname())) {
8109 Value *v_refd = dynamic_cast<Value*>(setting);
8110 Value *v_last = v_refd->get_value_refd_last(refch);
8111 // in case of circular recursion the valuetype is already set
8112 // to V_ERROR, so don't set the cache
8113 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8114 } else {
8115 // a circular recursion was detected
8116 set_valuetype(V_ERROR);
8117 }
8118 if (destroy_refch) delete refch;
8119 else refch->prev_state();
8120 break; }
8121 case Assignment::A_CONST: {
8122 // the referred definition is a constant
8123 bool destroy_refch;
8124 if (refch) {
8125 refch->mark_state();
8126 destroy_refch = false;
8127 } else {
8128 refch = new ReferenceChain(this,
8129 "While searching referenced value");
8130 destroy_refch = true;
8131 }
8132 if (refch->add(get_fullname())) {
8133 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8134 Value *v_refd = ass->get_Value()
8135 ->get_refd_sub_value(subrefs, 0,
8136 u.ref.ref->getUsedInIsbound(), refch);
8137 if (v_refd) {
8138 Value *v_last = v_refd->get_value_refd_last(refch);
8139 // in case of circular recursion the valuetype is already set
8140 // to V_ERROR, so don't set the cache
8141 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8142 } else if (subrefs && subrefs->has_unfoldable_index()) {
8143 u.ref.refd_last = this;
8144 } else if (u.ref.ref->getUsedInIsbound()) {
8145 u.ref.refd_last = this;
8146 } else {
8147 // the sub-reference points to a non-existent field
8148 set_valuetype(V_ERROR);
8149 }
8150 } else {
8151 // a circular recursion was detected
8152 set_valuetype(V_ERROR);
8153 }
8154 if (destroy_refch) delete refch;
8155 else refch->prev_state();
8156 break; }
8157 case Assignment::A_EXT_CONST:
8158 case Assignment::A_MODULEPAR:
8159 case Assignment::A_VAR:
8160 case Assignment::A_FUNCTION_RVAL:
8161 case Assignment::A_EXT_FUNCTION_RVAL:
8162 case Assignment::A_PAR_VAL_IN:
8163 case Assignment::A_PAR_VAL_OUT:
8164 case Assignment::A_PAR_VAL_INOUT:
8165 // the referred definition is not a constant
8166 u.ref.refd_last = this;
8167 break;
8168 case Assignment::A_FUNCTION:
8169 case Assignment::A_EXT_FUNCTION:
8170 u.ref.ref->error("Reference to a value was expected instead of a "
8171 "call of %s, which does not have return type",
8172 ass->get_description().c_str());
8173 set_valuetype(V_ERROR);
8174 break;
8175 case Assignment::A_FUNCTION_RTEMP:
8176 case Assignment::A_EXT_FUNCTION_RTEMP:
8177 u.ref.ref->error("Reference to a value was expected instead of a "
8178 "call of %s, which returns a template",
8179 ass->get_description().c_str());
8180 set_valuetype(V_ERROR);
8181 break;
8182 default:
8183 u.ref.ref->error("Reference to a value was expected instead of %s",
8184 ass->get_description().c_str());
8185 set_valuetype(V_ERROR);
8186 } // switch asstype
8187 }
8188 if (valuetype == V_REFD) return u.ref.refd_last;
8189 else return this;
8190 }
8191 case V_EXPR: {
8192 // try to evaluate the expression
8193 bool destroy_refch;
8194 if(refch) {
8195 refch->mark_state();
8196 destroy_refch=false;
8197 }
8198 else {
8199 refch=new ReferenceChain(this, "While evaluating expression");
8200 destroy_refch=true;
8201 }
8202 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8203 else set_valuetype(V_ERROR);
8204 if(destroy_refch) delete refch;
8205 else refch->prev_state();
8206 return this; }
8207 case V_MACRO:
8208 evaluate_macro(exp_val);
8209 // no break
8210 default:
8211 // return this for all other value types
8212 return this;
8213 } // switch
8214 }
8215
8216 map<Value*, void> Value::UnfoldabilityCheck::running;
8217
8218 /* Note that the logic here needs to be in sync with evaluate_value,
8219 * and possibly others, i.e. if evaluate_value is called for a Value
8220 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8221 bool Value::is_unfoldable(ReferenceChain *refch,
8222 Type::expected_value_t exp_val)
8223 {
8224 if (UnfoldabilityCheck::is_running(this)) {
8225 // This function is already running on this value => infinite recursion
8226 return true;
8227 }
8228
8229 UnfoldabilityCheck checker(this);
8230
8231 if (get_needs_conversion()) return true;
8232 switch (valuetype) {
8233 case V_NAMEDINT:
8234 case V_NAMEDBITS:
8235 case V_OPENTYPE:
8236 case V_UNDEF_LOWERID:
8237 case V_UNDEF_BLOCK:
8238 case V_TTCN3_NULL:
8239 case V_REFER:
8240 // these value types are eliminated during semantic analysis
8241 FATAL_ERROR("Value::is_unfoldable()");
8242 case V_ERROR:
8243 case V_INVOKE:
8244 return true;
8245 case V_CHOICE:
8246 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8247 case V_SEQOF:
8248 case V_SETOF:
8249 case V_ARRAY:
8250 if (!is_indexed()) {
8251 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8252 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8253 return true;
8254 }
8255 } else {
8256 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8257 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8258 return true;
8259 }
8260 }
8261 return false;
8262 case V_SEQ:
8263 case V_SET:
8264 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8265 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8266 ->is_unfoldable(refch, exp_val)) return true;
8267 }
8268 return false;
8269 case V_OID:
8270 case V_ROID:
8271 chk();
8272 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8273 if ((*u.oid_comps)[i]->is_variable()) return true;
8274 }
8275 return false;
8276 case V_REFD: {
8277 Value *v_last=get_value_refd_last(refch, exp_val);
8278 if(v_last==this) return true; // there weren't any references to chase
8279 else return v_last->is_unfoldable(refch, exp_val);
8280 }
8281 case V_EXPR:
8282 // classify the unchecked ischosen() operation, if it was not done so far
8283 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8284 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8285 switch (u.expr.v_optype) {
8286 case OPTYPE_RND: // -
8287 case OPTYPE_COMP_MTC:
8288 case OPTYPE_COMP_SYSTEM:
8289 case OPTYPE_COMP_SELF:
8290 case OPTYPE_COMP_RUNNING_ANY:
8291 case OPTYPE_COMP_RUNNING_ALL:
8292 case OPTYPE_COMP_ALIVE_ANY:
8293 case OPTYPE_COMP_ALIVE_ALL:
8294 case OPTYPE_TMR_RUNNING_ANY:
8295 case OPTYPE_GETVERDICT:
8296 case OPTYPE_TESTCASENAME:
8297 case OPTYPE_RNDWITHVAL: // v1
8298 case OPTYPE_MATCH: // v1 t2
8299 case OPTYPE_UNDEF_RUNNING: // v1
8300 case OPTYPE_COMP_RUNNING:
8301 case OPTYPE_COMP_ALIVE:
8302 case OPTYPE_TMR_READ:
8303 case OPTYPE_TMR_RUNNING:
8304 case OPTYPE_ACTIVATE:
8305 case OPTYPE_ACTIVATE_REFD:
8306 case OPTYPE_EXECUTE: // r1 [v2]
8307 case OPTYPE_EXECUTE_REFD:
8308 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8309 case OPTYPE_ISCHOSEN:
8310 case OPTYPE_ISCHOSEN_T:
8311 case OPTYPE_SIZEOF: // ti1
8312 case OPTYPE_DECODE:
8313 case OPTYPE_ENCODE:
8314 case OPTYPE_OCT2UNICHAR:
8315 case OPTYPE_UNICHAR2OCT:
8316 case OPTYPE_ENCODE_BASE64:
8317 case OPTYPE_DECODE_BASE64:
8318 return true;
8319 case OPTYPE_COMP_NULL: // -
8320 return false;
8321 case OPTYPE_UNARYPLUS: // v1
8322 case OPTYPE_UNARYMINUS:
8323 case OPTYPE_NOT:
8324 case OPTYPE_NOT4B:
8325 case OPTYPE_BIT2HEX:
8326 case OPTYPE_BIT2INT:
8327 case OPTYPE_BIT2OCT:
8328 case OPTYPE_BIT2STR:
8329 case OPTYPE_CHAR2INT:
8330 case OPTYPE_CHAR2OCT:
8331 case OPTYPE_FLOAT2INT:
8332 case OPTYPE_FLOAT2STR:
8333 case OPTYPE_HEX2BIT:
8334 case OPTYPE_HEX2INT:
8335 case OPTYPE_HEX2OCT:
8336 case OPTYPE_HEX2STR:
8337 case OPTYPE_INT2CHAR:
8338 case OPTYPE_INT2FLOAT:
8339 case OPTYPE_INT2STR:
8340 case OPTYPE_INT2UNICHAR:
8341 case OPTYPE_OCT2BIT:
8342 case OPTYPE_OCT2CHAR:
8343 case OPTYPE_OCT2HEX:
8344 case OPTYPE_OCT2INT:
8345 case OPTYPE_OCT2STR:
8346 case OPTYPE_STR2BIT:
8347 case OPTYPE_STR2FLOAT:
8348 case OPTYPE_STR2HEX:
8349 case OPTYPE_STR2INT:
8350 case OPTYPE_STR2OCT:
8351 case OPTYPE_UNICHAR2INT:
8352 case OPTYPE_UNICHAR2CHAR:
8353 case OPTYPE_ENUM2INT:
8354 case OPTYPE_GET_STRINGENCODING:
8355 case OPTYPE_REMOVE_BOM:
8356 return u.expr.v1->is_unfoldable(refch, exp_val);
8357 case OPTYPE_ISBOUND: /*{
8358 //TODO once we have the time for it make isbound foldable.
8359 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8360 Template* temp = u.expr.ti1->get_Template();
8361 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8362 Value* specificValue = temp->get_specific_value();
8363 if (specificValue->get_valuetype() == Value::V_REFD) {
8364 //FIXME implement
8365 }
8366
8367 return specificValue->is_unfoldable(refch, exp_val);
8368 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8369 //FIXME implement
8370 }
8371 }*/
8372 return true;
8373 case OPTYPE_ISPRESENT:
8374 // TODO: "if you have motivation"
8375 return true;
8376 case OPTYPE_ISVALUE: // ti1
8377 // fallthrough
8378 case OPTYPE_LENGTHOF: // ti1
8379 return u.expr.ti1->get_DerivedRef() != 0
8380 || u.expr.ti1->get_Template()->get_templatetype()
8381 != Template::SPECIFIC_VALUE
8382 || u.expr.ti1->get_Template()->get_specific_value()
8383 ->is_unfoldable(refch, exp_val);
8384 case OPTYPE_ROTL:
8385 case OPTYPE_ROTR:
8386 case OPTYPE_CONCAT:
8387 if (!u.expr.v1->is_string_type(exp_val)) return true;
8388 // no break
8389 case OPTYPE_ADD: // v1 v2
8390 case OPTYPE_SUBTRACT:
8391 case OPTYPE_MULTIPLY:
8392 case OPTYPE_DIVIDE:
8393 case OPTYPE_MOD:
8394 case OPTYPE_REM:
8395 case OPTYPE_EQ:
8396 case OPTYPE_LT:
8397 case OPTYPE_GT:
8398 case OPTYPE_NE:
8399 case OPTYPE_GE:
8400 case OPTYPE_LE:
8401 case OPTYPE_XOR:
8402 case OPTYPE_AND4B:
8403 case OPTYPE_OR4B:
8404 case OPTYPE_XOR4B:
8405 case OPTYPE_SHL:
8406 case OPTYPE_SHR:
8407 case OPTYPE_INT2BIT:
8408 case OPTYPE_INT2HEX:
8409 case OPTYPE_INT2OCT:
8410 return u.expr.v1->is_unfoldable(refch, exp_val)
8411 || u.expr.v2->is_unfoldable(refch, exp_val);
8412 case OPTYPE_AND: // short-circuit evaluation
8413 return u.expr.v1->is_unfoldable(refch, exp_val)
8414 || (u.expr.v1->get_val_bool() &&
8415 u.expr.v2->is_unfoldable(refch, exp_val));
8416 case OPTYPE_OR: // short-circuit evaluation
8417 return u.expr.v1->is_unfoldable(refch, exp_val)
8418 || (!u.expr.v1->get_val_bool() &&
8419 u.expr.v2->is_unfoldable(refch, exp_val));
8420 case OPTYPE_SUBSTR:
8421 if (!u.expr.ti1->get_specific_value()) return true;
8422 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8423 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8424 || u.expr.v2->is_unfoldable(refch, exp_val)
8425 || u.expr.v3->is_unfoldable(refch, exp_val);
8426 case OPTYPE_REGEXP:
8427 if (!u.expr.ti1->get_specific_value() ||
8428 !u.expr.t2->get_specific_value()) return true;
8429 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8430 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8431 || u.expr.v3->is_unfoldable(refch, exp_val);
8432 case OPTYPE_DECOMP:
8433 return u.expr.v1->is_unfoldable(refch, exp_val)
8434 || u.expr.v2->is_unfoldable(refch, exp_val)
8435 || u.expr.v3->is_unfoldable(refch, exp_val);
8436 case OPTYPE_REPLACE: {
8437 if (!u.expr.ti1->get_specific_value() ||
8438 !u.expr.ti4->get_specific_value()) return true;
8439 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8440 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8441 || u.expr.v2->is_unfoldable(refch, exp_val)
8442 || u.expr.v3->is_unfoldable(refch, exp_val)
8443 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8444 }
8445 case OPTYPE_VALUEOF: // ti1
8446 /* \todo if you have motivation to implement the eval function
8447 for valueof()... */
8448 return true;
8449 case OPTYPE_ISCHOSEN_V:
8450 return u.expr.v1->is_unfoldable(refch, exp_val);
8451 case OPTYPE_LOG2STR:
8452 case OPTYPE_TTCN2STRING:
8453 return true;
8454 default:
8455 FATAL_ERROR("Value::is_unfoldable()");
8456 } // switch
8457 break; // should never get here
8458 case V_MACRO:
8459 switch (u.macro) {
8460 case MACRO_TESTCASEID:
8461 // this is known only at runtime
8462 return true;
8463 default:
8464 return false;
8465 }
8466 default:
8467 // all literal values are foldable
8468 return false;
8469 }
8470 }
8471
8472 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8473 size_t start_i, bool usedInIsbound,
8474 ReferenceChain *refch)
8475 {
8476 if (!subrefs) return this;
8477 Value *v = this;
8478 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8479 if (!v) break;
8480 v = v->get_value_refd_last(refch);
8481 switch(v->valuetype) {
8482 case V_ERROR:
8483 return v;
8484 case V_REFD:
8485 // unfoldable stuff
8486 return this;
8487 default:
8488 break;
8489 } // switch
8490 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8491 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8492 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8493 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8494 }
8495 return v;
8496 }
8497
8498 Value *Value::get_refd_field_value(const Identifier& field_id,
8499 bool usedInIsbound, const Location& loc)
8500 {
8501 if (valuetype == V_OMIT) {
8502 loc.error("Reference to field `%s' of omit value `%s'",
8503 field_id.get_dispname().c_str(), get_fullname().c_str());
8504 return 0;
8505 }
8506 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8507 Type *t = my_governor->get_type_refd_last();
8508 switch (t->get_typetype()) {
8509 case Type::T_ERROR:
8510 // remain silent
8511 return 0;
8512 case Type::T_CHOICE_A:
8513 case Type::T_CHOICE_T:
8514 case Type::T_OPENTYPE:
8515 case Type::T_ANYTYPE:
8516 if (!t->has_comp_withName(field_id)) {
8517 loc.error("Reference to non-existent union field `%s' in type `%s'",
8518 field_id.get_dispname().c_str(), t->get_typename().c_str());
8519 return 0;
8520 } else if (valuetype != V_CHOICE) {
8521 // remain silent, the error is already reported
8522 return 0;
8523 } else if (*u.choice.alt_name == field_id) {
8524 // everything is OK
8525 return u.choice.alt_value;
8526 }else {
8527 if (!usedInIsbound) {
8528 loc.error("Reference to inactive field `%s' in a value of union type "
8529 "`%s'. The active field is `%s'",
8530 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8531 u.choice.alt_name->get_dispname().c_str());
8532 }
8533 return 0;
8534 }
8535 case Type::T_SEQ_A:
8536 case Type::T_SEQ_T:
8537 if (!t->has_comp_withName(field_id)) {
8538 loc.error("Reference to non-existent record field `%s' in type `%s'",
8539 field_id.get_dispname().c_str(), t->get_typename().c_str());
8540 return 0;
8541 } else if (valuetype != V_SEQ) {
8542 // remain silent, the error has been already reported
8543 return 0;
8544 } else break;
8545 case Type::T_SET_A:
8546 case Type::T_SET_T:
8547 if (!t->has_comp_withName(field_id)) {
8548 loc.error("Reference to non-existent set field `%s' in type `%s'",
8549 field_id.get_dispname().c_str(), t->get_typename().c_str());
8550 return 0;
8551 } else if (valuetype != V_SET) {
8552 // remain silent, the error has been already reported
8553 return 0;
8554 } else break;
8555 default:
8556 loc.error("Invalid field reference `%s': type `%s' "
8557 "does not have fields", field_id.get_dispname().c_str(),
8558 t->get_typename().c_str());
8559 return 0;
8560 }
8561 // the common end for record & set types
8562 if (u.val_nvs->has_nv_withName(field_id)) {
8563 // everything is OK
8564 return u.val_nvs->get_nv_byName(field_id)->get_value();
8565 } else if (!is_asn1()) {
8566 if (!usedInIsbound) {
8567 loc.error("Reference to unbound field `%s'",
8568 field_id.get_dispname().c_str());
8569 // this is an error in TTCN-3, which has been already reported
8570 }
8571 return 0;
8572 } else {
8573 CompField *cf = t->get_comp_byName(field_id);
8574 if (cf->get_is_optional()) {
8575 // creating an explicit omit value
8576 Value *v = new Value(V_OMIT);
8577 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8578 v->set_my_scope(get_my_scope());
8579 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8580 return v;
8581 } else if (cf->has_default()) {
8582 // returning the component's default value
8583 return cf->get_defval();
8584 } else {
8585 // this is an error in ASN.1, which has been already reported
8586 return 0;
8587 }
8588 }
8589 }
8590
8591 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8592 ReferenceChain *refch)
8593 {
8594 Value *v_index = array_index->get_value_refd_last(refch);
8595 Int index = 0;
8596 bool index_available = false;
8597 if (!v_index->is_unfoldable()) {
8598 if (v_index->valuetype == V_INT) {
8599 index = v_index->get_val_Int()->get_val();
8600 index_available = true;
8601 } else {
8602 array_index->error("An integer value was expected as index");
8603 }
8604 }
8605 if (valuetype == V_OMIT) {
8606 array_index->error("Accessing an element with index of omit value `%s'",
8607 get_fullname().c_str());
8608 return 0;
8609 }
8610 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8611 Type *t = my_governor->get_type_refd_last();
8612 switch (t->get_typetype()) {
8613 case Type::T_ERROR:
8614 // remain silent
8615 return 0;
8616 case Type::T_SEQOF:
8617 if (index_available) {
8618 if (index < 0) {
8619 array_index->error("A non-negative integer value was expected "
8620 "instead of %s for indexing a value of `record "
8621 "of' type `%s'", Int2string(index).c_str(),
8622 t->get_typename().c_str());
8623 return 0;
8624 }
8625 switch (valuetype) {
8626 case V_SEQOF:
8627 if (!is_indexed()) {
8628 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8629 if (!usedInIsbound) {
8630 array_index->error("Index overflow in a value of `record of' "
8631 "type `%s': the index is %s, but the value "
8632 "has only %lu elements",
8633 t->get_typename().c_str(),
8634 Int2string(index).c_str(),
8635 (unsigned long)u.val_vs->get_nof_vs());
8636 }
8637 return 0;
8638 } else {
8639 Value* temp = u.val_vs->get_v_byIndex(index);
8640 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8641 temp->error("Not used symbol is not allowed in this context");
8642 return u.val_vs->get_v_byIndex(index);
8643 }
8644 } else {
8645 // Search the appropriate constant index.
8646 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8647 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8648 ->get_value_refd_last();
8649 if (iv_index->get_valuetype() != V_INT) continue;
8650 if (iv_index->get_val_Int()->get_val() == index)
8651 return u.val_vs->get_iv_byIndex(i)->get_value();
8652 }
8653 return 0;
8654 }
8655 break;
8656 default:
8657 // remain silent, the error has been already reported
8658 return 0;
8659 }
8660 } else {
8661 // the error has been reported above
8662 return 0;
8663 }
8664 case Type::T_SETOF:
8665 if (index_available) {
8666 if (index < 0) {
8667 array_index->error("A non-negative integer value was expected "
8668 "instead of %s for indexing a value of `set of' type `%s'",
8669 Int2string(index).c_str(), t->get_typename().c_str());
8670 return 0;
8671 }
8672 switch (valuetype) {
8673 case V_SETOF:
8674 if (!is_indexed()) {
8675 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8676 if (!usedInIsbound) {
8677 array_index->error("Index overflow in a value of `set of' type "
8678 "`%s': the index is %s, but the value has "
8679 "only %lu elements",
8680 t->get_typename().c_str(),
8681 Int2string(index).c_str(),
8682 (unsigned long)u.val_vs->get_nof_vs());
8683 }
8684 return 0;
8685 } else {
8686 Value* temp = u.val_vs->get_v_byIndex(index);
8687 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8688 temp->error("Not used symbol is not allowed in this context");
8689 return temp;
8690 }
8691 } else {
8692 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8693 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8694 ->get_value_refd_last();
8695 if (iv_index->get_valuetype() != V_INT) continue;
8696 if (iv_index->get_val_Int()->get_val() == index)
8697 return u.val_vs->get_iv_byIndex(i)->get_value();
8698 }
8699 return 0;
8700 }
8701 break;
8702 default:
8703 // remain silent, the error has been already reported
8704 return 0;
8705 }
8706 } else {
8707 // the error has been reported above
8708 return 0;
8709 }
8710 case Type::T_ARRAY:
8711 if (index_available) {
8712 Ttcn::ArrayDimension *dim = t->get_dimension();
8713 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8714 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8715 // perform the index transformation
8716 index -= dim->get_offset();
8717 if (!is_indexed()) {
8718 // check for index underflow/overflow or too few elements in the
8719 // value
8720 if (index < 0 ||
8721 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8722 return 0;
8723 else return u.val_vs->get_v_byIndex(index);
8724 } else {
8725 if (index < 0) return 0;
8726 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8727 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8728 ->get_value_refd_last();
8729 if (iv_index->get_valuetype() != V_INT) continue;
8730 if (iv_index->get_val_Int()->get_val() == index)
8731 return u.val_vs->get_iv_byIndex(index)->get_value();
8732 }
8733 return 0;
8734 }
8735 } else {
8736 // remain silent, the error has been already reported
8737 return 0;
8738 }
8739 } else {
8740 // the error has been reported above
8741 return 0;
8742 }
8743 case Type::T_BSTR:
8744 case Type::T_BSTR_A:
8745 case Type::T_HSTR:
8746 case Type::T_OSTR:
8747 case Type::T_CSTR:
8748 case Type::T_USTR:
8749 case Type::T_UTF8STRING:
8750 case Type::T_NUMERICSTRING:
8751 case Type::T_PRINTABLESTRING:
8752 case Type::T_TELETEXSTRING:
8753 case Type::T_VIDEOTEXSTRING:
8754 case Type::T_IA5STRING:
8755 case Type::T_GRAPHICSTRING:
8756 case Type::T_VISIBLESTRING:
8757 case Type::T_GENERALSTRING:
8758 case Type::T_UNIVERSALSTRING:
8759 case Type::T_BMPSTRING:
8760 case Type::T_UTCTIME:
8761 case Type::T_GENERALIZEDTIME:
8762 case Type::T_OBJECTDESCRIPTOR:
8763 if (index_available) return get_string_element(index, *array_index);
8764 else return 0;
8765 default:
8766 array_index->error("Invalid array element reference: type `%s' cannot "
8767 "be indexed", t->get_typename().c_str());
8768 return 0;
8769 }
8770 }
8771
8772 Value *Value::get_string_element(const Int& index, const Location& loc)
8773 {
8774 if (index < 0) {
8775 loc.error("A non-negative integer value was expected instead of %s "
8776 "for indexing a string element", Int2string(index).c_str());
8777 return 0;
8778 }
8779 size_t string_length;
8780 switch (valuetype) {
8781 case V_BSTR:
8782 case V_HSTR:
8783 case V_CSTR:
8784 case V_ISO2022STR:
8785 string_length = u.str.val_str->size();
8786 break;
8787 case V_OSTR:
8788 string_length = u.str.val_str->size() / 2;
8789 break;
8790 case V_USTR:
8791 string_length = u.ustr.val_ustr->size();
8792 break;
8793 default:
8794 // remain silent, the error has been already reported
8795 return 0;
8796 }
8797 if (index >= static_cast<Int>(string_length)) {
8798 loc.error("Index overflow when accessing a string element: "
8799 "the index is %s, but the string has only %lu elements",
8800 Int2string(index).c_str(), (unsigned long) string_length);
8801 return 0;
8802 }
8803 switch (valuetype) {
8804 case V_BSTR:
8805 case V_HSTR:
8806 case V_CSTR:
8807 case V_ISO2022STR:
8808 if (u.str.str_elements && u.str.str_elements->has_key(index))
8809 return (*u.str.str_elements)[index];
8810 else {
8811 Value *t_val = new Value(valuetype,
8812 new string(u.str.val_str->substr(index, 1)));
8813 add_string_element(index, t_val, u.str.str_elements);
8814 return t_val;
8815 }
8816 case V_OSTR:
8817 if (u.str.str_elements && u.str.str_elements->has_key(index))
8818 return (*u.str.str_elements)[index];
8819 else {
8820 Value *t_val = new Value(V_OSTR,
8821 new string(u.str.val_str->substr(2 * index, 2)));
8822 add_string_element(index, t_val, u.str.str_elements);
8823 return t_val;
8824 }
8825 case V_USTR:
8826 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
8827 return (*u.ustr.ustr_elements)[index];
8828 else {
8829 Value *t_val = new Value(V_USTR,
8830 new ustring(u.ustr.val_ustr->substr(index, 1)));
8831 add_string_element(index, t_val, u.ustr.ustr_elements);
8832 return t_val;
8833 }
8834 default:
8835 FATAL_ERROR("Value::get_string_element()");
8836 return 0;
8837 }
8838 }
8839
8840 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
8841 Type::expected_value_t exp_val)
8842 {
8843 set_lowerid_to_ref();
8844 Type::typetype_t r_tt = get_expr_returntype(exp_val);
8845 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
8846 if (error_flag)
8847 error("A value or expression of type %s was expected", type_name);
8848 if (valuetype == V_REFD) {
8849 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
8850 t_chk->chk_this_refd_value(this, 0, exp_val);
8851 }
8852 get_value_refd_last(0, exp_val);
8853 if (error_flag) set_valuetype(V_ERROR);
8854 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
8855 }
8856
8857 int Value::is_parsed_infinity()
8858 {
8859 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
8860 return 1;
8861 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
8862 (u.expr.v1->get_valuetype()==V_REAL) &&
8863 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
8864 return -1;
8865 return 0;
8866 }
8867
8868 bool Value::get_val_bool()
8869 {
8870 Value *v;
8871 if (valuetype == V_REFD) v = get_value_refd_last();
8872 else v = this;
8873 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
8874 return v->u.val_bool;
8875 }
8876
8877 int_val_t* Value::get_val_Int()
8878 {
8879 Value *v;
8880 if (valuetype == V_REFD) v = get_value_refd_last();
8881 else v = this;
8882 switch (v->valuetype) {
8883 case V_INT:
8884 break;
8885 case V_UNDEF_LOWERID:
8886 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8887 "`%s'", (*u.val_id).get_dispname().c_str());
8888 default:
8889 FATAL_ERROR("Value::get_val_Int()");
8890 } // switch
8891 return v->u.val_Int;
8892 }
8893
8894 const Identifier* Value::get_val_id()
8895 {
8896 switch(valuetype) {
8897 case V_NAMEDINT:
8898 case V_ENUM:
8899 case V_UNDEF_LOWERID:
8900 return u.val_id;
8901 default:
8902 FATAL_ERROR("Value::get_val_id()");
8903 return 0;
8904 } // switch
8905 }
8906
8907 const ttcn3float& Value::get_val_Real()
8908 {
8909 Value *v;
8910 if (valuetype == V_REFD) v = get_value_refd_last();
8911 else v = this;
8912 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
8913 return v->u.val_Real;
8914 }
8915
8916 string Value::get_val_str()
8917 {
8918 Value *v = get_value_refd_last();
8919 switch (v->valuetype) {
8920 case V_BSTR:
8921 case V_HSTR:
8922 case V_OSTR:
8923 case V_CSTR:
8924 return *v->u.str.val_str;
8925 case V_CHARSYMS:
8926 return v->u.char_syms->get_string();
8927 case V_USTR:
8928 error("Cannot use ISO-10646 string value in string context");
8929 return string();
8930 case V_ISO2022STR:
8931 error("Cannot use ISO-2022 string value in string context");
8932 // no break
8933 case V_ERROR:
8934 return string();
8935 default:
8936 error("Cannot use this value in charstring value context");
8937 return string();
8938 } // switch
8939 }
8940
8941 ustring Value::get_val_ustr()
8942 {
8943 Value *v = get_value_refd_last();
8944 switch (v->valuetype) {
8945 case V_CSTR:
8946 return ustring(*v->u.str.val_str);
8947 case V_USTR:
8948 return *v->u.ustr.val_ustr;
8949 case V_CHARSYMS:
8950 return v->u.char_syms->get_ustring();
8951 case V_ISO2022STR:
8952 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8953 // no break
8954 case V_ERROR:
8955 return ustring();
8956 default:
8957 error("Cannot use this value in ISO-10646 string context");
8958 return ustring();
8959 } // switch
8960 }
8961
8962 string Value::get_val_iso2022str()
8963 {
8964 Value *v = get_value_refd_last();
8965 switch (v->valuetype) {
8966 case V_CSTR:
8967 case V_ISO2022STR:
8968 return *v->u.str.val_str;
8969 case V_CHARSYMS:
8970 return v->u.char_syms->get_iso2022string();
8971 case V_USTR:
8972 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8973 // no break
8974 case V_ERROR:
8975 return string();
8976 default:
8977 error("Cannot use this value in ISO-2022 string context");
8978 return string();
8979 } // switch
8980 }
8981
8982 size_t Value::get_val_strlen()
8983 {
8984 Value *v = get_value_refd_last();
8985 switch (v->valuetype) {
8986 case V_BSTR:
8987 case V_HSTR:
8988 case V_CSTR:
8989 case V_ISO2022STR:
8990 return v->u.str.val_str->size();
8991 case V_OSTR:
8992 return v->u.str.val_str->size()/2;
8993 case V_CHARSYMS:
8994 return v->u.char_syms->get_len();
8995 case V_USTR:
8996 return v->u.ustr.val_ustr->size();
8997 case V_ERROR:
8998 return 0;
8999 default:
9000 error("Cannot use this value in string value context");
9001 return 0;
9002 } // switch
9003 }
9004
9005 Value::verdict_t Value::get_val_verdict()
9006 {
9007 switch(valuetype) {
9008 case V_VERDICT:
9009 return u.verdict;
9010 default:
9011 FATAL_ERROR("Value::get_val_verdict()");
9012 return u.verdict;
9013 } // switch
9014 }
9015
9016 size_t Value::get_nof_comps()
9017 {
9018 switch (valuetype) {
9019 case V_OID:
9020 case V_ROID:
9021 chk();
9022 return u.oid_comps->size();
9023 case V_SEQOF:
9024 case V_SETOF:
9025 case V_ARRAY:
9026 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9027 else return u.val_vs->get_nof_vs();
9028 case V_SEQ:
9029 case V_SET:
9030 return u.val_nvs->get_nof_nvs();
9031 case V_BSTR:
9032 case V_HSTR:
9033 case V_CSTR:
9034 case V_ISO2022STR:
9035 return u.str.val_str->size();
9036 case V_OSTR:
9037 return u.str.val_str->size()/2;
9038 case V_USTR:
9039 return u.ustr.val_ustr->size();
9040 default:
9041 FATAL_ERROR("Value::get_nof_comps()");
9042 return 0;
9043 } // switch
9044 }
9045
9046 bool Value::is_indexed() const
9047 {
9048 switch (valuetype) {
9049 case V_SEQOF:
9050 case V_SETOF:
9051 case V_ARRAY:
9052 // Applicable only for list-types. Assigning a record/SEQUENCE or
9053 // set/SET with indexed notation is not supported.
9054 return u.val_vs->is_indexed();
9055 default:
9056 FATAL_ERROR("Value::is_indexed()");
9057 break;
9058 }
9059 return false;
9060 }
9061
9062 const Identifier& Value::get_alt_name()
9063 {
9064 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9065 return *u.choice.alt_name;
9066 }
9067
9068 Value *Value::get_alt_value()
9069 {
9070 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9071 return u.choice.alt_value;
9072 }
9073
9074 bool Value::has_oid_error()
9075 {
9076 Value *v;
9077 if (valuetype == V_REFD) v = get_value_refd_last();
9078 else v = this;
9079 switch (valuetype) {
9080 case V_OID:
9081 case V_ROID:
9082 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9083 if ((*v->u.oid_comps)[i]->has_error()) return true;
9084 return false;
9085 default:
9086 return true;
9087 }
9088 }
9089
9090 bool Value::get_oid_comps(vector<string>& comps)
9091 {
9092 bool ret_val = true;
9093 Value *v = this;
9094 switch (valuetype) {
9095 case V_REFD:
9096 v = get_value_refd_last();
9097 // no break
9098 case V_OID:
9099 case V_ROID:
9100 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9101 (*v->u.oid_comps)[i]->get_comps(comps);
9102 if ((*v->u.oid_comps)[i]->is_variable()) {
9103 // not all components can be calculated in compile-time
9104 ret_val = false;
9105 }
9106 }
9107 break;
9108 default:
9109 FATAL_ERROR("Value::get_oid_comps()");
9110 }
9111 return ret_val;
9112 }
9113
9114 void Value::add_se_comp(NamedValue* nv) {
9115 switch (valuetype) {
9116 case V_SEQ:
9117 case V_SET:
9118 if (!u.val_nvs)
9119 u.val_nvs = new NamedValues();
9120 u.val_nvs->add_nv(nv);
9121 break;
9122 default:
9123 FATAL_ERROR("Value::add_se_comp()");
9124 }
9125 }
9126
9127 NamedValue* Value::get_se_comp_byIndex(size_t n)
9128 {
9129 switch(valuetype) {
9130 case V_SEQ:
9131 case V_SET:
9132 return u.val_nvs->get_nv_byIndex(n);
9133 default:
9134 FATAL_ERROR("Value::get_se_comp_byIndex()");
9135 return 0;
9136 } // switch
9137 }
9138
9139 Value *Value::get_comp_byIndex(size_t n)
9140 {
9141 switch (valuetype) {
9142 case V_SEQOF:
9143 case V_SETOF:
9144 case V_ARRAY:
9145 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9146 return u.val_vs->get_iv_byIndex(n)->get_value();
9147 default:
9148 FATAL_ERROR("Value::get_comp_byIndex()");
9149 return 0;
9150 } // switch
9151 }
9152
9153 Value *Value::get_index_byIndex(size_t n)
9154 {
9155 switch (valuetype) {
9156 case V_SEQOF:
9157 case V_SETOF:
9158 case V_ARRAY:
9159 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9160 return u.val_vs->get_iv_byIndex(n)->get_index();
9161 default:
9162 FATAL_ERROR("Value::get_index_byIndex()");
9163 return 0;
9164 } // switch
9165 }
9166
9167 bool Value::has_comp_withName(const Identifier& p_name)
9168 {
9169 switch(valuetype) {
9170 case V_SEQ:
9171 case V_SET:
9172 return u.val_nvs->has_nv_withName(p_name);
9173 case V_CHOICE:
9174 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9175 default:
9176 FATAL_ERROR("Value::get_has_comp_withName()");
9177 return false;
9178 } // switch
9179 }
9180
9181 bool Value::field_is_chosen(const Identifier& p_name)
9182 {
9183 Value *v=get_value_refd_last();
9184 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9185 return *v->u.choice.alt_name==p_name;
9186 }
9187
9188 bool Value::field_is_present(const Identifier& p_name)
9189 {
9190 Value *v=get_value_refd_last();
9191 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9192 FATAL_ERROR("Value::field_is_present()");
9193 return v->u.val_nvs->has_nv_withName(p_name)
9194 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9195 ->get_value_refd_last()->valuetype != V_OMIT;
9196 }
9197
9198 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9199 {
9200 switch(valuetype) {
9201 case V_SEQ:
9202 case V_SET:
9203 return u.val_nvs->get_nv_byName(p_name);
9204 default:
9205 FATAL_ERROR("Value::get_se_comp_byName()");
9206 return 0;
9207 } // switch
9208 }
9209
9210 Value* Value::get_comp_value_byName(const Identifier& p_name)
9211 {
9212 switch(valuetype) {
9213 case V_SEQ:
9214 case V_SET:
9215 return u.val_nvs->get_nv_byName(p_name)->get_value();
9216 case V_CHOICE:
9217 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9218 return u.choice.alt_value;
9219 else
9220 return NULL;
9221 default:
9222 FATAL_ERROR("Value::get_se_comp_byName()");
9223 return 0;
9224 } // switch
9225 }
9226
9227 void Value::chk_dupl_id()
9228 {
9229 switch(valuetype) {
9230 case V_SEQ:
9231 case V_SET:
9232 u.val_nvs->chk_dupl_id();
9233 break;
9234 default:
9235 FATAL_ERROR("Value::chk_dupl_id()");
9236 } // switch
9237 }
9238
9239 size_t Value::get_nof_ids() const
9240 {
9241 switch(valuetype) {
9242 case V_NAMEDBITS:
9243 return u.ids->size();
9244 break;
9245 default:
9246 FATAL_ERROR("Value::get_nof_ids()");
9247 return 0;
9248 } // switch
9249 }
9250
9251 Identifier* Value::get_id_byIndex(size_t p_i)
9252 {
9253 switch(valuetype) {
9254 case V_NAMEDBITS:
9255 return u.ids->get_nth_elem(p_i);
9256 break;
9257 default:
9258 FATAL_ERROR("Value::get_id_byIndex()");
9259 return 0;
9260 } // switch
9261 }
9262
9263 bool Value::has_id(const Identifier& p_id)
9264 {
9265 switch(valuetype) {
9266 case V_NAMEDBITS:
9267 return u.ids->has_key(p_id.get_name());
9268 break;
9269 default:
9270 FATAL_ERROR("Value::has_id()");
9271 return false;
9272 } // switch
9273 }
9274
9275 Reference *Value::get_reference() const
9276 {
9277 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9278 return u.ref.ref;
9279 }
9280
9281 Reference *Value::get_refered() const
9282 {
9283 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9284 return u.refered;
9285 }
9286
9287 Common::Assignment *Value::get_refd_fat() const
9288 {
9289 switch(valuetype){
9290 case V_FUNCTION:
9291 case V_ALTSTEP:
9292 case V_TESTCASE:
9293 return u.refd_fat;
9294 default:
9295 FATAL_ERROR("Value::get_refd_fat()");
9296 }
9297 }
9298
9299 Ttcn::Reference* Value::steal_ttcn_ref()
9300 {
9301 Ttcn::Reference *ret_val =
9302 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9303 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9304 return ret_val;
9305 }
9306
9307 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9308 {
9309 Ttcn::Ref_base *t_ref;
9310 if(valuetype==V_REFD) {
9311 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9312 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9313 u.ref.ref=0;
9314 }
9315 else if(valuetype==V_UNDEF_LOWERID) {
9316 t_ref=new Ttcn::Reference(u.val_id);
9317 t_ref->set_location(*this);
9318 t_ref->set_fullname(get_fullname());
9319 t_ref->set_my_scope(get_my_scope());
9320 u.val_id=0;
9321 }
9322 else {
9323 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9324 t_ref = 0;
9325 }
9326 set_valuetype(V_ERROR);
9327 return t_ref;
9328 }
9329
9330 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9331 Ttcn::ActualParList*& p_ap)
9332 {
9333 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9334 p_v = u.invoke.v;
9335 u.invoke.v = 0;
9336 p_ti = u.invoke.t_list;
9337 u.invoke.t_list = 0;
9338 p_ap = u.invoke.ap_list;
9339 u.invoke.ap_list = 0;
9340 set_valuetype(V_ERROR);
9341 }
9342
9343 Common::Assignment* Value::get_refd_assignment()
9344 {
9345 switch(valuetype) {
9346 case V_FUNCTION:
9347 case V_ALTSTEP:
9348 case V_TESTCASE:
9349 return u.refd_fat;
9350 break;
9351 default:
9352 FATAL_ERROR("Value::get_refd_assignment()");
9353 return 0;
9354 }
9355 }
9356
9357 void Value::chk()
9358 {
9359 if(checked) return;
9360 switch(valuetype) {
9361 case V_OID: {
9362 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9363 " components");
9364 chk_OID(refch);
9365 break; }
9366 case V_ROID: {
9367 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9368 chk_ROID(refch);
9369 break; }
9370 default:
9371 break;
9372 } // switch
9373 checked=true;
9374 }
9375
9376 void Value::chk_OID(ReferenceChain& refch)
9377 {
9378 if (checked) return;
9379 if (valuetype != V_OID || u.oid_comps->size() < 1)
9380 FATAL_ERROR("Value::chk_OID()");
9381 if (!refch.add(get_fullname())) {
9382 checked = true;
9383 return;
9384 }
9385 OID_comp::oidstate_t state = OID_comp::START;
9386 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9387 refch.mark_state();
9388 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9389 refch.prev_state();
9390 }
9391 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9392 error("An OBJECT IDENTIFIER value must have at least "
9393 "two components"); // X.680 (07/2002) 31.10
9394 }
9395
9396 void Value::chk_ROID(ReferenceChain& refch)
9397 {
9398 if (checked) return;
9399 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9400 FATAL_ERROR("Value::chk_ROID()");
9401 if (!refch.add(get_fullname())) {
9402 checked = true;
9403 return;
9404 }
9405 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9406 refch.mark_state();
9407 (*u.oid_comps)[i]->chk_ROID(refch, i);
9408 refch.prev_state();
9409 }
9410 }
9411
9412 void Value::chk_recursions(ReferenceChain& refch)
9413 {
9414 if (recurs_checked) return;
9415 Value *v = get_value_refd_last();
9416 if (refch.add(v->get_fullname())) {
9417 switch (v->valuetype) {
9418 case V_CHOICE:
9419 v->u.choice.alt_value->chk_recursions(refch);
9420 break;
9421 case V_SEQOF:
9422 case V_SETOF:
9423 case V_ARRAY:
9424 if (!v->is_indexed()) {
9425 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9426 refch.mark_state();
9427 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9428 refch.prev_state();
9429 }
9430 } else {
9431 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9432 refch.mark_state();
9433 v->u.val_vs->get_iv_byIndex(i)->get_value()
9434 ->chk_recursions(refch);
9435 refch.prev_state();
9436 }
9437 }
9438 break;
9439 case V_SEQ:
9440 case V_SET:
9441 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9442 refch.mark_state();
9443 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9444 refch.prev_state();
9445 }
9446 break;
9447 case V_EXPR:
9448 chk_recursions_expr(refch);
9449 break;
9450 default:
9451 break;
9452 }
9453 if (v->err_descr) { // FIXME: make this work
9454 v->err_descr->chk_recursions(refch);
9455 }
9456 }
9457 recurs_checked = true;
9458 }
9459
9460 void Value::chk_recursions_expr(ReferenceChain& refch)
9461 {
9462 // first classify the unchecked ischosen() operation
9463 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9464 switch (u.expr.v_optype) {
9465 case OPTYPE_UNARYPLUS: // v1
9466 case OPTYPE_UNARYMINUS:
9467 case OPTYPE_NOT:
9468 case OPTYPE_NOT4B:
9469 case OPTYPE_BIT2HEX:
9470 case OPTYPE_BIT2INT:
9471 case OPTYPE_BIT2OCT:
9472 case OPTYPE_BIT2STR:
9473 case OPTYPE_CHAR2INT:
9474 case OPTYPE_CHAR2OCT:
9475 case OPTYPE_FLOAT2INT:
9476 case OPTYPE_FLOAT2STR:
9477 case OPTYPE_HEX2BIT:
9478 case OPTYPE_HEX2INT:
9479 case OPTYPE_HEX2OCT:
9480 case OPTYPE_HEX2STR:
9481 case OPTYPE_INT2CHAR:
9482 case OPTYPE_INT2FLOAT:
9483 case OPTYPE_INT2STR:
9484 case OPTYPE_INT2UNICHAR:
9485 case OPTYPE_OCT2BIT:
9486 case OPTYPE_OCT2CHAR:
9487 case OPTYPE_OCT2HEX:
9488 case OPTYPE_OCT2INT:
9489 case OPTYPE_OCT2STR:
9490 case OPTYPE_STR2BIT:
9491 case OPTYPE_STR2FLOAT:
9492 case OPTYPE_STR2HEX:
9493 case OPTYPE_STR2INT:
9494 case OPTYPE_STR2OCT:
9495 case OPTYPE_UNICHAR2INT:
9496 case OPTYPE_ENUM2INT:
9497 case OPTYPE_UNICHAR2CHAR:
9498 case OPTYPE_RNDWITHVAL:
9499 case OPTYPE_ISCHOSEN_V:
9500 case OPTYPE_GET_STRINGENCODING:
9501 case OPTYPE_REMOVE_BOM:
9502 case OPTYPE_DECODE_BASE64:
9503 refch.mark_state();
9504 u.expr.v1->chk_recursions(refch);
9505 refch.prev_state();
9506 break;
9507 case OPTYPE_ISCHOSEN_T:
9508 refch.mark_state();
9509 u.expr.t1->chk_recursions(refch);
9510 refch.prev_state();
9511 break;
9512 case OPTYPE_ADD: // v1 v2
9513 case OPTYPE_SUBTRACT:
9514 case OPTYPE_MULTIPLY:
9515 case OPTYPE_DIVIDE:
9516 case OPTYPE_MOD:
9517 case OPTYPE_REM:
9518 case OPTYPE_CONCAT:
9519 case OPTYPE_EQ:
9520 case OPTYPE_LT:
9521 case OPTYPE_GT:
9522 case OPTYPE_NE:
9523 case OPTYPE_GE:
9524 case OPTYPE_LE:
9525 case OPTYPE_AND:
9526 case OPTYPE_OR:
9527 case OPTYPE_XOR:
9528 case OPTYPE_AND4B:
9529 case OPTYPE_OR4B:
9530 case OPTYPE_XOR4B:
9531 case OPTYPE_SHL:
9532 case OPTYPE_SHR:
9533 case OPTYPE_ROTL:
9534 case OPTYPE_ROTR:
9535 case OPTYPE_INT2BIT:
9536 case OPTYPE_INT2HEX:
9537 case OPTYPE_INT2OCT:
9538 refch.mark_state();
9539 u.expr.v1->chk_recursions(refch);
9540 refch.prev_state();
9541 refch.mark_state();
9542 u.expr.v2->chk_recursions(refch);
9543 refch.prev_state();
9544 break;
9545 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9546 case OPTYPE_OCT2UNICHAR:
9547 case OPTYPE_ENCODE_BASE64:
9548 refch.mark_state();
9549 u.expr.v1->chk_recursions(refch);
9550 refch.prev_state();
9551 if (u.expr.v2) {
9552 refch.mark_state();
9553 u.expr.v2->chk_recursions(refch);
9554 refch.prev_state();
9555 }
9556 break;
9557 case OPTYPE_DECODE:
9558 chk_recursions_expr_decode(u.expr.r1, refch);
9559 chk_recursions_expr_decode(u.expr.r2, refch);
9560 break;
9561 case OPTYPE_SUBSTR:
9562 refch.mark_state();
9563 u.expr.ti1->chk_recursions(refch);
9564 refch.prev_state();
9565 refch.mark_state();
9566 u.expr.v2->chk_recursions(refch);
9567 refch.prev_state();
9568 refch.mark_state();
9569 u.expr.v3->chk_recursions(refch);
9570 refch.prev_state();
9571 break;
9572 case OPTYPE_REGEXP:
9573 refch.mark_state();
9574 u.expr.ti1->chk_recursions(refch);
9575 refch.prev_state();
9576 refch.mark_state();
9577 u.expr.t2->chk_recursions(refch);
9578 refch.prev_state();
9579 refch.mark_state();
9580 u.expr.v3->chk_recursions(refch);
9581 refch.prev_state();
9582 break;
9583 case OPTYPE_DECOMP: // v1 v2 v3
9584 refch.mark_state();
9585 u.expr.v1->chk_recursions(refch);
9586 refch.prev_state();
9587 refch.mark_state();
9588 u.expr.v2->chk_recursions(refch);
9589 refch.prev_state();
9590 refch.mark_state();
9591 u.expr.v3->chk_recursions(refch);
9592 refch.prev_state();
9593 break;
9594 case OPTYPE_REPLACE:
9595 refch.mark_state();
9596 u.expr.ti1->chk_recursions(refch);
9597 refch.prev_state();
9598 refch.mark_state();
9599 u.expr.v2->chk_recursions(refch);
9600 refch.prev_state();
9601 refch.mark_state();
9602 u.expr.v3->chk_recursions(refch);
9603 refch.prev_state();
9604 refch.mark_state();
9605 u.expr.ti4->chk_recursions(refch);
9606 refch.prev_state();
9607 break;
9608 case OPTYPE_LENGTHOF: // ti1
9609 case OPTYPE_SIZEOF: // ti1
9610 case OPTYPE_VALUEOF: // ti1
9611 case OPTYPE_ENCODE:
9612 case OPTYPE_ISPRESENT:
9613 case OPTYPE_TTCN2STRING:
9614 refch.mark_state();
9615 u.expr.ti1->chk_recursions(refch);
9616 refch.prev_state();
9617 break;
9618 case OPTYPE_MATCH: // v1 t2
9619 refch.mark_state();
9620 u.expr.v1->chk_recursions(refch);
9621 refch.prev_state();
9622 refch.mark_state();
9623 u.expr.t2->chk_recursions(refch);
9624 refch.prev_state();
9625 break;
9626 case OPTYPE_LOG2STR:
9627 u.expr.logargs->chk_recursions(refch);
9628 break;
9629 default:
9630 break;
9631 } // switch
9632 }
9633
9634 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9635 ReferenceChain& refch) {
9636 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9637 Assignment *ass = ref->get_refd_assignment();
9638 if (!ass) {
9639 set_valuetype(V_ERROR);
9640 return;
9641 }
9642 switch (ass->get_asstype()) {
9643 case Assignment::A_CONST:
9644 case Assignment::A_EXT_CONST:
9645 case Assignment::A_MODULEPAR:
9646 case Assignment::A_VAR:
9647 case Assignment::A_PAR_VAL_IN:
9648 case Assignment::A_PAR_VAL_OUT:
9649 case Assignment::A_PAR_VAL_INOUT: {
9650 Value* v = new Value(V_REFD, ref);
9651 v->set_location(*ref);
9652 v->set_my_scope(get_my_scope());
9653 v->set_fullname(get_fullname()+".<operand>");
9654 refch.mark_state();
9655 v->chk_recursions(refch);
9656 refch.prev_state();
9657 delete v;
9658 break; }
9659 case Assignment::A_MODULEPAR_TEMP:
9660 case Assignment::A_TEMPLATE:
9661 case Assignment::A_VAR_TEMPLATE:
9662 case Assignment::A_PAR_TEMPL_IN:
9663 case Assignment::A_PAR_TEMPL_OUT:
9664 case Assignment::A_PAR_TEMPL_INOUT: {
9665 Template* t = new Template(ref->clone());
9666 t->set_location(*ref);
9667 t->set_my_scope(get_my_scope());
9668 t->set_fullname(get_fullname()+".<operand>");
9669 refch.mark_state();
9670 t->chk_recursions(refch);
9671 refch.prev_state();
9672 delete t;
9673 break; }
9674 default:
9675 // remain silent, the error has been already reported
9676 set_valuetype(V_ERROR);
9677 break;
9678 } // switch
9679 }
9680
9681 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9682 {
9683 bool self_ref = false;
9684 switch (t->get_templatetype()) {
9685 case Ttcn::Template::SPECIFIC_VALUE: {
9686 Value *v = t->get_specific_value();
9687 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9688 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9689 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9690 break; }
9691 case Ttcn::Template::TEMPLATE_REFD: {
9692 Ttcn::Ref_base *refb = t->get_reference();
9693 Common::Assignment *ass = refb->get_refd_assignment();
9694 self_ref |= (ass == lhs);
9695 break; }
9696 case Ttcn::Template::ALL_FROM:
9697 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9698 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9699 break;
9700 case Ttcn::Template::TEMPLATE_LIST:
9701 case Ttcn::Template::SUPERSET_MATCH:
9702 case Ttcn::Template::SUBSET_MATCH:
9703 case Ttcn::Template::PERMUTATION_MATCH:
9704 case Ttcn::Template::COMPLEMENTED_LIST:
9705 case Ttcn::Template::VALUE_LIST: {
9706 size_t num = t->get_nof_comps();
9707 for (size_t i = 0; i < num; ++i) {
9708 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9709 }
9710 break; }
9711 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9712 // case Ttcn::Template::TEMPLATE_LIST: {
9713 // size_t num = t->get_nof_listitems();
9714 // for (size_t i=0; i < num; ++i) {
9715 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9716 // }
9717 // break; }
9718 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9719 size_t nnt = t->get_nof_comps();
9720 for (size_t i=0; i < nnt; ++i) {
9721 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9722 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9723 }
9724 break; }
9725 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9726 size_t nnt = t->get_nof_comps();
9727 for (size_t i=0; i < nnt; ++i) {
9728 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9729 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9730 }
9731 break; }
9732 case Ttcn::Template::VALUE_RANGE: {
9733 Ttcn::ValueRange *vr = t->get_value_range();
9734 Common::Value *v = vr->get_min_v();
9735 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9736 v = vr->get_max_v();
9737 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9738 break; }
9739 case Ttcn::Template::CSTR_PATTERN:
9740 case Ttcn::Template::USTR_PATTERN: {
9741 Ttcn::PatternString *ps = t->get_cstr_pattern();
9742 self_ref |= ps->chk_self_ref(lhs);
9743 break; }
9744 case Ttcn::Template::BSTR_PATTERN:
9745 case Ttcn::Template::HSTR_PATTERN:
9746 case Ttcn::Template::OSTR_PATTERN: {
9747 // FIXME: cannot access u.pattern
9748 break; }
9749 case Ttcn::Template::ANY_VALUE:
9750 case Ttcn::Template::ANY_OR_OMIT:
9751 case Ttcn::Template::OMIT_VALUE:
9752 case Ttcn::Template::TEMPLATE_NOTUSED:
9753 break; // self-ref can't happen
9754 case Ttcn::Template::TEMPLATE_INVOKE:
9755 break; // assume self-ref can't happen
9756 case Ttcn::Template::TEMPLATE_ERROR:
9757 FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9758 break; // not reached
9759 // default:
9760 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9761 // break; // and hope for the best
9762 }
9763 return self_ref;
9764 }
9765
9766 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
9767 {
9768 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
9769 namedbool is_str_elem = NOT_STR_ELEM;
9770 if (v->valuetype == V_REFD) {
9771 Reference *ref = v->get_reference();
9772 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
9773 if (subrefs && subrefs->refers_to_string_element()) {
9774 is_str_elem = IS_STR_ELEM;
9775 }
9776 }
9777 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9778 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
9779 is_str_elem);
9780 }
9781
9782 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
9783 {
9784 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
9785 if (!lhs) FATAL_ERROR("no lhs!");
9786 bool self_ref = false;
9787 switch (u.expr.v_optype) {
9788 case OPTYPE_RND: // -
9789 case OPTYPE_TESTCASENAME: // -
9790 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
9791 case OPTYPE_COMP_MTC: // -
9792 case OPTYPE_COMP_SYSTEM: // -
9793 case OPTYPE_COMP_SELF: // -
9794 case OPTYPE_COMP_RUNNING_ANY: // -
9795 case OPTYPE_COMP_RUNNING_ALL: // -
9796 case OPTYPE_COMP_ALIVE_ANY: // -
9797 case OPTYPE_COMP_ALIVE_ALL: // -
9798 case OPTYPE_TMR_RUNNING_ANY: // -
9799 case OPTYPE_GETVERDICT: // -
9800 break; // nothing to do
9801
9802 case OPTYPE_MATCH: // v1 t2
9803 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
9804 // no break
9805 case OPTYPE_UNARYPLUS: // v1
9806 case OPTYPE_UNARYMINUS: // v1
9807 case OPTYPE_NOT: // v1
9808 case OPTYPE_NOT4B: // v1
9809 case OPTYPE_BIT2HEX: // v1
9810 case OPTYPE_BIT2INT: // v1
9811 case OPTYPE_BIT2OCT: // v1
9812 case OPTYPE_BIT2STR: // v1
9813 case OPTYPE_CHAR2INT: // v1
9814 case OPTYPE_CHAR2OCT: // v1
9815 case OPTYPE_FLOAT2INT: // v1
9816 case OPTYPE_FLOAT2STR: // v1
9817 case OPTYPE_HEX2BIT: // v1
9818 case OPTYPE_HEX2INT: // v1
9819 case OPTYPE_HEX2OCT: // v1
9820 case OPTYPE_HEX2STR: // v1
9821 case OPTYPE_INT2CHAR: // v1
9822 case OPTYPE_INT2FLOAT: // v1
9823 case OPTYPE_INT2STR: // v1
9824 case OPTYPE_INT2UNICHAR: // v1
9825 case OPTYPE_OCT2BIT: // v1
9826 case OPTYPE_OCT2CHAR: // v1
9827 case OPTYPE_OCT2HEX: // v1
9828 case OPTYPE_OCT2INT: // v1
9829 case OPTYPE_OCT2STR: // v1
9830 case OPTYPE_STR2BIT: // v1
9831 case OPTYPE_STR2FLOAT: // v1
9832 case OPTYPE_STR2HEX: // v1
9833 case OPTYPE_STR2INT: // v1
9834 case OPTYPE_STR2OCT: // v1
9835 case OPTYPE_UNICHAR2INT: // v1
9836 case OPTYPE_UNICHAR2CHAR: // v1
9837 case OPTYPE_ENUM2INT: // v1
9838 case OPTYPE_RNDWITHVAL: // v1
9839 case OPTYPE_COMP_RUNNING: // v1
9840 case OPTYPE_COMP_ALIVE: // v1
9841 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
9842 case OPTYPE_GET_STRINGENCODING:
9843 case OPTYPE_DECODE_BASE64:
9844 case OPTYPE_REMOVE_BOM:
9845 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9846 break;
9847 case OPTYPE_ADD: // v1 v2
9848 case OPTYPE_SUBTRACT: // v1 v2
9849 case OPTYPE_MULTIPLY: // v1 v2
9850 case OPTYPE_DIVIDE: // v1 v2
9851 case OPTYPE_MOD: // v1 v2
9852 case OPTYPE_REM: // v1 v2
9853 case OPTYPE_CONCAT: // v1 v2
9854 case OPTYPE_EQ: // v1 v2
9855 case OPTYPE_LT: // v1 v2
9856 case OPTYPE_GT: // v1 v2
9857 case OPTYPE_NE: // v1 v2
9858 case OPTYPE_GE: // v1 v2
9859 case OPTYPE_LE: // v1 v2
9860 case OPTYPE_AND: // v1 v2
9861 case OPTYPE_OR: // v1 v2
9862 case OPTYPE_XOR: // v1 v2
9863 case OPTYPE_AND4B: // v1 v2
9864 case OPTYPE_OR4B: // v1 v2
9865 case OPTYPE_XOR4B: // v1 v2
9866 case OPTYPE_SHL: // v1 v2
9867 case OPTYPE_SHR: // v1 v2
9868 case OPTYPE_ROTL: // v1 v2
9869 case OPTYPE_ROTR: // v1 v2
9870 case OPTYPE_INT2BIT: // v1 v2
9871 case OPTYPE_INT2HEX: // v1 v2
9872 case OPTYPE_INT2OCT: // v1 v2
9873 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9874 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9875 break;
9876 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9877 case OPTYPE_OCT2UNICHAR:
9878 case OPTYPE_ENCODE_BASE64:
9879 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9880 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9881 break;
9882 case OPTYPE_DECOMP: // v1 v2 v3
9883 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9884 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9885 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9886 break;
9887
9888 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
9889 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
9890 // no break
9891 case OPTYPE_SUBSTR: // ti1 v2 v3
9892 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9893 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
9894 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
9895 break;
9896
9897 case OPTYPE_REGEXP: // ti1 t2 v3
9898 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9899 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
9900 // no break
9901 case OPTYPE_LENGTHOF: // ti1
9902 case OPTYPE_SIZEOF: // ti1
9903 case OPTYPE_VALUEOF: // ti1
9904 case OPTYPE_ENCODE: // ti1
9905 case OPTYPE_TTCN2STRING:
9906 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9907 break;
9908
9909 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
9910 // component.create -- assume no self-ref
9911 case OPTYPE_ACTIVATE: // r1
9912 // defaultref := activate(altstep) -- assume no self-ref
9913 case OPTYPE_TMR_RUNNING: // r1
9914 // boolvar := a_timer.running -- assume no self-ref
9915 break;
9916 break;
9917
9918 case OPTYPE_LOG2STR: {// logargs
9919 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
9920 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
9921 switch (la->get_type()) {
9922 case Ttcn::LogArgument::L_UNDEF:
9923 case Ttcn::LogArgument::L_ERROR:
9924 FATAL_ERROR("log2str argument type");
9925 break; // not reached
9926
9927 case Ttcn::LogArgument::L_MACRO:
9928 case Ttcn::LogArgument::L_STR:
9929 break; // self reference not possible
9930
9931 case Ttcn::LogArgument::L_VAL:
9932 case Ttcn::LogArgument::L_MATCH:
9933 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
9934 break;
9935
9936 case Ttcn::LogArgument::L_REF: {
9937 Ttcn::Ref_base *ref = la->get_ref();
9938 Common::Assignment *ass = ref->get_refd_assignment();
9939 self_ref |= (ass == lhs);
9940 break; }
9941
9942 case Ttcn::LogArgument::L_TI: {
9943 Ttcn::TemplateInstance *ti = la->get_ti();
9944 Ttcn::Template *t = ti->get_Template();
9945 self_ref |= chk_expr_self_ref_templ(t, lhs);
9946 break; }
9947
9948 // no default please
9949 } // switch la->logargtype
9950 }
9951 break; }
9952
9953 case OPTYPE_DECODE: { // r1 r2
9954 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
9955 self_ref |= (ass == lhs);
9956 goto label_r1; }
9957 case OPTYPE_EXECUTE: // r1 [v2]
9958 if (u.expr.v2) {
9959 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9960 }
9961 label_r1:
9962 // no break
9963 case OPTYPE_UNDEF_RUNNING: // r1
9964 case OPTYPE_TMR_READ: { // r1
9965 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
9966 self_ref |= (ass == lhs);
9967 break; }
9968
9969 case OPTYPE_ISCHOSEN_T: // t1 i2
9970 case OPTYPE_ISBOUND: // ti1
9971 case OPTYPE_ISVALUE: // ti1
9972 case OPTYPE_ISPRESENT: { // ti1
9973 Ttcn::Template *t;
9974 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
9975 else t = u.expr.ti1->get_Template();
9976 self_ref |= chk_expr_self_ref_templ(t, lhs);
9977 break; }
9978
9979 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
9980 if (u.expr.v3) {
9981 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9982 }
9983 // no break
9984 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
9985 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9986 // TODO t_list2
9987 break;
9988
9989 case NUMBER_OF_OPTYPES: // can never happen
9990 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
9991 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
9992 break;
9993 } // switch u.expr.v_optype
9994 return self_ref;
9995 }
9996
9997
9998 string Value::create_stringRepr()
9999 {
10000 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10001 switch (valuetype) {
10002 case V_ERROR:
10003 return string("<erroneous>");
10004 case V_NULL:
10005 return string("NULL");
10006 case V_BOOL:
10007 if (!parse_only && is_asn1()) {
10008 if (u.val_bool) return string("TRUE");
10009 else return string("FALSE");
10010 }
10011 else {
10012 if (u.val_bool) return string("true");
10013 else return string("false");
10014 }
10015 case V_INT:
10016 return u.val_Int->t_str();
10017 case V_REAL:
10018 return Real2string(u.val_Real);
10019 case V_ENUM:
10020 case V_NAMEDINT:
10021 case V_UNDEF_LOWERID:
10022 return u.val_id->get_name();
10023 case V_NAMEDBITS: {
10024 string ret_val("{ ");
10025 for (size_t i = 0; i < u.ids->size(); i++) {
10026 if (i>0) ret_val += ' ';
10027 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10028 }
10029 ret_val += '}';
10030 return ret_val; }
10031 case V_BSTR: {
10032 string ret_val('\'');
10033 ret_val += *u.str.val_str;
10034 ret_val += "'B";
10035 return ret_val; }
10036 case V_HSTR: {
10037 string ret_val('\'');
10038 ret_val += *u.str.val_str;
10039 ret_val += "'H";
10040 return ret_val; }
10041 case V_OSTR: {
10042 string ret_val('\'');
10043 ret_val += *u.str.val_str;
10044 ret_val += "'O";
10045 return ret_val; }
10046 case V_CSTR:
10047 case V_ISO2022STR:
10048 return u.str.val_str->get_stringRepr();
10049 case V_USTR:
10050 return u.ustr.val_ustr->get_stringRepr();
10051 case V_CHARSYMS:
10052 /** \todo stringrepr of V_CHARSYMS */
10053 return string("<sorry, string representation of charsyms "
10054 "not implemented>");
10055 case V_OID:
10056 case V_ROID: {
10057 string ret_val;
10058 if (parse_only || !is_asn1()) ret_val += "objid ";
10059 ret_val += "{ ";
10060 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10061 if (i>0) ret_val += ' ';
10062 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10063 }
10064 ret_val += " }";
10065 return ret_val; }
10066 case V_CHOICE:
10067 if (!parse_only && is_asn1()) {
10068 string ret_val(u.choice.alt_name->get_dispname());
10069 ret_val += " : ";
10070 ret_val += u.choice.alt_value->get_stringRepr();
10071 return ret_val;
10072 }
10073 else {
10074 string ret_val("{ ");
10075 ret_val += u.choice.alt_name->get_dispname();
10076 ret_val += " := ";
10077 ret_val += u.choice.alt_value->get_stringRepr();
10078 ret_val += " }";
10079 return ret_val;
10080 }
10081 case V_SEQOF:
10082 case V_SETOF:
10083 case V_ARRAY: {
10084 string ret_val("{ ");
10085 if (!is_indexed()) {
10086 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10087 if (i > 0) ret_val += ", ";
10088 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10089 }
10090 } else {
10091 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10092 if (i > 0) ret_val += ", ";
10093 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10094 }
10095 }
10096 ret_val += " }";
10097 return ret_val; }
10098 case V_SEQ:
10099 case V_SET: {
10100 string ret_val("{ ");
10101 bool asn1_flag = !parse_only && is_asn1();
10102 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10103 if (i > 0) ret_val += ", ";
10104 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10105 ret_val += nv->get_name().get_dispname();
10106 if (asn1_flag) ret_val += ' ';
10107 else ret_val += " := ";
10108 ret_val += nv->get_value()->get_stringRepr();
10109 }
10110 ret_val += " }";
10111 return ret_val; }
10112 case V_REFD: {
10113 // do not evaluate the reference if it is not done so far
10114 // (e.g. in parse-only mode)
10115 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10116 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10117 else return t_val->get_stringRepr(); }
10118 case V_OMIT:
10119 return string("omit");
10120 case V_VERDICT:
10121 switch (u.verdict) {
10122 case Verdict_NONE:
10123 return string("none");
10124 case Verdict_PASS:
10125 return string("pass");
10126 case Verdict_INCONC:
10127 return string("inconc");
10128 case Verdict_FAIL:
10129 return string("fail");
10130 case Verdict_ERROR:
10131 return string("error");
10132 default:
10133 return string("<unknown verdict value>");
10134 }
10135 case V_DEFAULT_NULL:
10136 case V_FAT_NULL:
10137 return string("null");
10138 case V_EXPR:
10139 switch (u.expr.v_optype) {
10140 case OPTYPE_RND:
10141 return string("rnd()");
10142 case OPTYPE_TESTCASENAME:
10143 return string("testcasename()");
10144 case OPTYPE_UNARYPLUS:
10145 return create_stringRepr_unary("+");
10146 case OPTYPE_UNARYMINUS:
10147 return create_stringRepr_unary("-");
10148 case OPTYPE_NOT:
10149 return create_stringRepr_unary("not");
10150 case OPTYPE_NOT4B:
10151 return create_stringRepr_unary("not4b");
10152 case OPTYPE_BIT2HEX:
10153 return create_stringRepr_predef1("bit2hex");
10154 case OPTYPE_BIT2INT:
10155 return create_stringRepr_predef1("bit2int");
10156 case OPTYPE_BIT2OCT:
10157 return create_stringRepr_predef1("bit2oct");
10158 case OPTYPE_BIT2STR:
10159 return create_stringRepr_predef1("bit2str");
10160 case OPTYPE_CHAR2INT:
10161 return create_stringRepr_predef1("char2int");
10162 case OPTYPE_CHAR2OCT:
10163 return create_stringRepr_predef1("char2oct");
10164 case OPTYPE_FLOAT2INT:
10165 return create_stringRepr_predef1("float2int");
10166 case OPTYPE_FLOAT2STR:
10167 return create_stringRepr_predef1("float2str");
10168 case OPTYPE_HEX2BIT:
10169 return create_stringRepr_predef1("hex2bit");
10170 case OPTYPE_HEX2INT:
10171 return create_stringRepr_predef1("hex2int");
10172 case OPTYPE_HEX2OCT:
10173 return create_stringRepr_predef1("hex2oct");
10174 case OPTYPE_HEX2STR:
10175 return create_stringRepr_predef1("hex2str");
10176 case OPTYPE_INT2CHAR:
10177 return create_stringRepr_predef1("int2char");
10178 case OPTYPE_INT2FLOAT:
10179 return create_stringRepr_predef1("int2float");
10180 case OPTYPE_INT2STR:
10181 return create_stringRepr_predef1("int2str");
10182 case OPTYPE_INT2UNICHAR:
10183 return create_stringRepr_predef1("int2unichar");
10184 case OPTYPE_OCT2BIT:
10185 return create_stringRepr_predef1("oct2bit");
10186 case OPTYPE_OCT2CHAR:
10187 return create_stringRepr_predef1("oct2char");
10188 case OPTYPE_OCT2HEX:
10189 return create_stringRepr_predef1("oct2hex");
10190 case OPTYPE_OCT2INT:
10191 return create_stringRepr_predef1("oct2int");
10192 case OPTYPE_OCT2STR:
10193 return create_stringRepr_predef1("oct2str");
10194 case OPTYPE_GET_STRINGENCODING:
10195 return create_stringRepr_predef1("get_stringencoding");
10196 case OPTYPE_REMOVE_BOM:
10197 return create_stringRepr_predef1("remove_bom");
10198 case OPTYPE_ENCODE_BASE64: {
10199 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10200 else return create_stringRepr_predef1("encode_base64");
10201 }
10202 case OPTYPE_DECODE_BASE64:
10203 return create_stringRepr_predef1("decode_base64");
10204 case OPTYPE_OCT2UNICHAR:{
10205 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10206 else return create_stringRepr_predef1("oct2unichar");
10207 }
10208 case OPTYPE_UNICHAR2OCT: {
10209 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10210 else return create_stringRepr_predef1("unichar2oct");
10211 }
10212 case OPTYPE_STR2BIT:
10213 return create_stringRepr_predef1("str2bit");
10214 case OPTYPE_STR2FLOAT:
10215 return create_stringRepr_predef1("str2float");
10216 case OPTYPE_STR2HEX:
10217 return create_stringRepr_predef1("str2hex");
10218 case OPTYPE_STR2INT:
10219 return create_stringRepr_predef1("str2int");
10220 case OPTYPE_STR2OCT:
10221 return create_stringRepr_predef1("str2oct");
10222 case OPTYPE_UNICHAR2INT:
10223 return create_stringRepr_predef1("unichar2int");
10224 case OPTYPE_UNICHAR2CHAR:
10225 return create_stringRepr_predef1("unichar2char");
10226 case OPTYPE_ENUM2INT:
10227 return create_stringRepr_predef1("enum2int");
10228 case OPTYPE_ENCODE:
10229 return create_stringRepr_predef1("encvalue");
10230 case OPTYPE_DECODE:
10231 return create_stringRepr_predef2("decvalue");
10232 case OPTYPE_RNDWITHVAL:
10233 return create_stringRepr_predef1("rnd");
10234 case OPTYPE_ADD:
10235 return create_stringRepr_infix("+");
10236 case OPTYPE_SUBTRACT:
10237 return create_stringRepr_infix("-");
10238 case OPTYPE_MULTIPLY:
10239 return create_stringRepr_infix("*");
10240 case OPTYPE_DIVIDE:
10241 return create_stringRepr_infix("/");
10242 case OPTYPE_MOD:
10243 return create_stringRepr_infix("mod");
10244 case OPTYPE_REM:
10245 return create_stringRepr_infix("rem");
10246 case OPTYPE_CONCAT:
10247 return create_stringRepr_infix("&");
10248 case OPTYPE_EQ:
10249 return create_stringRepr_infix("==");
10250 case OPTYPE_LT:
10251 return create_stringRepr_infix("<");
10252 case OPTYPE_GT:
10253 return create_stringRepr_infix(">");
10254 case OPTYPE_NE:
10255 return create_stringRepr_infix("!=");
10256 case OPTYPE_GE:
10257 return create_stringRepr_infix(">=");
10258 case OPTYPE_LE:
10259 return create_stringRepr_infix("<=");
10260 case OPTYPE_AND:
10261 return create_stringRepr_infix("and");
10262 case OPTYPE_OR:
10263 return create_stringRepr_infix("or");
10264 case OPTYPE_XOR:
10265 return create_stringRepr_infix("xor");
10266 case OPTYPE_AND4B:
10267 return create_stringRepr_infix("and4b");
10268 case OPTYPE_OR4B:
10269 return create_stringRepr_infix("or4b");
10270 case OPTYPE_XOR4B:
10271 return create_stringRepr_infix("xor4b");
10272 case OPTYPE_SHL:
10273 return create_stringRepr_infix("<<");
10274 case OPTYPE_SHR:
10275 return create_stringRepr_infix(">>");
10276 case OPTYPE_ROTL:
10277 return create_stringRepr_infix("<@");
10278 case OPTYPE_ROTR:
10279 return create_stringRepr_infix("@>");
10280 case OPTYPE_INT2BIT:
10281 return create_stringRepr_predef2("int2bit");
10282 case OPTYPE_INT2HEX:
10283 return create_stringRepr_predef2("int2hex");
10284 case OPTYPE_INT2OCT:
10285 return create_stringRepr_predef2("int2oct");
10286 case OPTYPE_SUBSTR: {
10287 string ret_val("substr(");
10288 u.expr.ti1->append_stringRepr(ret_val);
10289 ret_val += ", ";
10290 ret_val += u.expr.v2->get_stringRepr();
10291 ret_val += ", ";
10292 ret_val += u.expr.v3->get_stringRepr();
10293 ret_val += ')';
10294 return ret_val;
10295 }
10296 case OPTYPE_REGEXP: {
10297 string ret_val("regexp(");
10298 u.expr.ti1->append_stringRepr(ret_val);
10299 ret_val += ", ";
10300 u.expr.t2->append_stringRepr(ret_val);
10301 ret_val += ", ";
10302 ret_val += u.expr.v3->get_stringRepr();
10303 ret_val += ')';
10304 return ret_val;
10305 }
10306 case OPTYPE_DECOMP: {
10307 string ret_val("decomp(");
10308 ret_val += u.expr.v1->get_stringRepr();
10309 ret_val += ", ";
10310 ret_val += u.expr.v2->get_stringRepr();
10311 ret_val += ", ";
10312 ret_val += u.expr.v3->get_stringRepr();
10313 ret_val += ')';
10314 return ret_val;
10315 }
10316 case OPTYPE_REPLACE: {
10317 string ret_val("replace(");
10318 u.expr.ti1->append_stringRepr(ret_val);
10319 ret_val += ", ";
10320 ret_val += u.expr.v2->get_stringRepr();
10321 ret_val += ", ";
10322 ret_val += u.expr.v3->get_stringRepr();
10323 ret_val += ", ";
10324 u.expr.ti4->append_stringRepr(ret_val);
10325 ret_val += ')';
10326 return ret_val;
10327 }
10328 case OPTYPE_ISPRESENT: {
10329 string ret_val("ispresent(");
10330 u.expr.ti1->append_stringRepr(ret_val);
10331 ret_val += ')';
10332 return ret_val; }
10333 case OPTYPE_ISCHOSEN: {
10334 string ret_val("ischosen(");
10335 ret_val += u.expr.r1->get_dispname();
10336 ret_val += '.';
10337 ret_val += u.expr.i2->get_dispname();
10338 ret_val += ')';
10339 return ret_val; }
10340 case OPTYPE_ISCHOSEN_V: {
10341 string ret_val("ischosen(");
10342 ret_val += u.expr.v1->get_stringRepr();
10343 ret_val += '.';
10344 ret_val += u.expr.i2->get_dispname();
10345 ret_val += ')';
10346 return ret_val; }
10347 case OPTYPE_ISCHOSEN_T: {
10348 string ret_val("ischosen(");
10349 ret_val += u.expr.t1->get_stringRepr();
10350 ret_val += '.';
10351 ret_val += u.expr.i2->get_dispname();
10352 ret_val += ')';
10353 return ret_val; }
10354 case OPTYPE_LENGTHOF: {
10355 string ret_val("lengthof(");
10356 u.expr.ti1->append_stringRepr(ret_val);
10357 ret_val += ')';
10358 return ret_val; }
10359 case OPTYPE_SIZEOF: {
10360 string ret_val("sizeof(");
10361 u.expr.ti1->append_stringRepr(ret_val);
10362 ret_val += ')';
10363 return ret_val; }
10364 case OPTYPE_ISVALUE: {
10365 string ret_val("isvalue(");
10366 u.expr.ti1->append_stringRepr(ret_val);
10367 ret_val += ')';
10368 return ret_val; }
10369 case OPTYPE_VALUEOF: {
10370 string ret_val("valueof(");
10371 u.expr.ti1->append_stringRepr(ret_val);
10372 ret_val += ')';
10373 return ret_val; }
10374 case OPTYPE_LOG2STR:
10375 return string("log2str(...)");
10376 case OPTYPE_MATCH: {
10377 string ret_val("match(");
10378 ret_val += u.expr.v1->get_stringRepr();
10379 ret_val += ", ";
10380 u.expr.t2->append_stringRepr(ret_val);
10381 ret_val += ')';
10382 return ret_val; }
10383 case OPTYPE_TTCN2STRING: {
10384 string ret_val("ttcn2string(");
10385 u.expr.ti1->append_stringRepr(ret_val);
10386 ret_val += ')';
10387 return ret_val;
10388 }
10389 case OPTYPE_UNDEF_RUNNING:
10390 return u.expr.r1->get_dispname() + ".running";
10391 case OPTYPE_COMP_NULL:
10392 return string("null");
10393 case OPTYPE_COMP_MTC:
10394 return string("mtc");
10395 case OPTYPE_COMP_SYSTEM:
10396 return string("system");
10397 case OPTYPE_COMP_SELF:
10398 return string("self");
10399 case OPTYPE_COMP_CREATE: {
10400 string ret_val(u.expr.r1->get_dispname());
10401 ret_val += ".create";
10402 if (u.expr.v2 || u.expr.v3) {
10403 ret_val += '(';
10404 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10405 else ret_val += '-';
10406 if (u.expr.v3) {
10407 ret_val += ", ";
10408 ret_val += u.expr.v3->get_stringRepr();
10409 }
10410 ret_val += ')';
10411 }
10412 if (u.expr.b4) ret_val += " alive";
10413 return ret_val; }
10414 case OPTYPE_COMP_RUNNING:
10415 return u.expr.v1->get_stringRepr() + ".running";
10416 case OPTYPE_COMP_RUNNING_ANY:
10417 return string("any component.running");
10418 case OPTYPE_COMP_RUNNING_ALL:
10419 return string("all component.running");
10420 case OPTYPE_COMP_ALIVE:
10421 return u.expr.v1->get_stringRepr() + ".alive";
10422 case OPTYPE_COMP_ALIVE_ANY:
10423 return string("any component.alive");
10424 case OPTYPE_COMP_ALIVE_ALL:
10425 return string("all component.alive");
10426 case OPTYPE_TMR_READ:
10427 return u.expr.r1->get_dispname() + ".read";
10428 case OPTYPE_TMR_RUNNING:
10429 return u.expr.r1->get_dispname() + ".running";
10430 case OPTYPE_TMR_RUNNING_ANY:
10431 return string("any timer.running");
10432 case OPTYPE_GETVERDICT:
10433 return string("getverdict");
10434 case OPTYPE_ACTIVATE: {
10435 string ret_val("activate(");
10436 ret_val += u.expr.r1->get_dispname();
10437 ret_val += ')';
10438 return ret_val; }
10439 case OPTYPE_ACTIVATE_REFD: {
10440 string ret_val("activate(derefer(");
10441 ret_val += u.expr.v1->get_stringRepr();
10442 ret_val += ")(";
10443 if (u.expr.state == EXPR_CHECKED) {
10444 if (u.expr.ap_list2) {
10445 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10446 for (size_t i = 0; i < nof_pars; i++) {
10447 if (i > 0) ret_val += ", ";
10448 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10449 }
10450 }
10451 } else {
10452 if (u.expr.t_list2) {
10453 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10454 for (size_t i = 0; i < nof_pars; i++) {
10455 if (i > 0) ret_val += ", ";
10456 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10457 }
10458 }
10459 }
10460 ret_val += "))";
10461 return ret_val; }
10462 case OPTYPE_EXECUTE: {
10463 string ret_val("execute(");
10464 ret_val += u.expr.r1->get_dispname();
10465 if (u.expr.v2) {
10466 ret_val += ", ";
10467 ret_val += u.expr.v2->get_stringRepr();
10468 }
10469 ret_val += ')';
10470 return ret_val; }
10471 case OPTYPE_EXECUTE_REFD: {
10472 string ret_val("execute(derefers(");
10473 ret_val += u.expr.v1->get_stringRepr();
10474 ret_val += ")(";
10475 if (u.expr.state == EXPR_CHECKED) {
10476 if (u.expr.ap_list2) {
10477 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10478 for (size_t i = 0; i < nof_pars; i++) {
10479 if (i > 0) ret_val += ", ";
10480 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10481 }
10482 }
10483 } else {
10484 if (u.expr.t_list2) {
10485 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10486 for (size_t i = 0; i < nof_pars; i++) {
10487 if (i > 0) ret_val += ", ";
10488 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10489 }
10490 }
10491 }
10492 ret_val += ')';
10493 if(u.expr.v3) {
10494 ret_val += ", ";
10495 ret_val += u.expr.v3->get_stringRepr();
10496 }
10497 ret_val += ')';
10498 return ret_val; }
10499 default:
10500 return string("<unsupported optype>");
10501 } // switch u.expr.v_optype
10502 case V_MACRO:
10503 switch (u.macro) {
10504 case MACRO_MODULEID:
10505 return string("%moduleId");
10506 case MACRO_FILENAME:
10507 return string("%fileName");
10508 case MACRO_BFILENAME:
10509 return string("__BFILE__");
10510 case MACRO_FILEPATH:
10511 return string("__FILE__");
10512 case MACRO_LINENUMBER:
10513 return string("%lineNumber");
10514 case MACRO_LINENUMBER_C:
10515 return string("__LINE__");
10516 case MACRO_DEFINITIONID:
10517 return string("%definitionId");
10518 case MACRO_SCOPE:
10519 return string("__SCOPE__");
10520 case MACRO_TESTCASEID:
10521 return string("%testcaseId");
10522 default:
10523 return string("<unknown macro>");
10524 } // switch u.macro
10525 case V_NOTUSED:
10526 return string('-');
10527 case V_FUNCTION:
10528 case V_ALTSTEP:
10529 case V_TESTCASE: {
10530 string ret_val("refers(");
10531 ret_val += u.refd_fat->get_assname();
10532 ret_val += ')';
10533 return ret_val; }
10534 case V_INVOKE: {
10535 string ret_val;
10536 ret_val += u.invoke.v->get_stringRepr();
10537 ret_val += ".apply(";
10538 if (u.invoke.ap_list) {
10539 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10540 for (size_t i = 0; i < nof_pars; i++) {
10541 if (i > 0) ret_val += ", ";
10542 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10543 }
10544 } else if (u.invoke.t_list) {
10545 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10546 for (size_t i = 0; i < nof_pars; i++) {
10547 if (i > 0) ret_val += ", ";
10548 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10549 }
10550 }
10551 ret_val += ')';
10552 return ret_val; }
10553 case V_REFER: {
10554 string ret_val("refers(");
10555 ret_val += u.refered->get_dispname();
10556 ret_val += ')';
10557 return ret_val; }
10558 default:
10559 return string("<unsupported valuetype>");
10560 } // switch valuetype
10561 }
10562
10563 string Value::create_stringRepr_unary(const char *operator_str)
10564 {
10565 string ret_val(operator_str);
10566 ret_val += '(';
10567 ret_val += u.expr.v1->get_stringRepr();
10568 ret_val += ')';
10569 return ret_val;
10570 }
10571
10572 string Value::create_stringRepr_infix(const char *operator_str)
10573 {
10574 string ret_val('(');
10575 ret_val += u.expr.v1->get_stringRepr();
10576 ret_val += ' ';
10577 ret_val += operator_str;
10578 ret_val += ' ';
10579 ret_val += u.expr.v2->get_stringRepr();
10580 ret_val += ')';
10581 return ret_val;
10582 }
10583
10584 string Value::create_stringRepr_predef1(const char *function_name)
10585 {
10586 string ret_val(function_name);
10587 ret_val += '(';
10588 if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
10589 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10590 }
10591 else ret_val += u.expr.v1->get_stringRepr();
10592 ret_val += ')';
10593 return ret_val;
10594 }
10595
10596 string Value::create_stringRepr_predef2(const char *function_name)
10597 {
10598 string ret_val(function_name);
10599 ret_val += '(';
10600 ret_val += u.expr.v1->get_stringRepr();
10601 ret_val += ", ";
10602 ret_val += u.expr.v2->get_stringRepr();
10603 ret_val += ')';
10604 return ret_val;
10605 }
10606
10607 bool Value::operator==(Value& val)
10608 {
10609 Value *left = get_value_refd_last();
10610 Type *left_governor = left->get_my_governor();
10611 if (left_governor) left_governor = left_governor->get_type_refd_last();
10612 Value *right = val.get_value_refd_last();
10613 Type *right_governor = right->get_my_governor();
10614 if (right_governor) right_governor = right_governor->get_type_refd_last();
10615 if (left_governor && right_governor
10616 && !left_governor->is_compatible(right_governor, NULL)
10617 && !right_governor->is_compatible(left_governor, NULL))
10618 FATAL_ERROR("Value::operator==");
10619
10620 // Not-A-Value is not equal to anything (NaN analogy:)
10621 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10622 return false;
10623
10624 switch (left->valuetype) {
10625 case V_NULL:
10626 case V_OMIT:
10627 case V_DEFAULT_NULL:
10628 case V_FAT_NULL:
10629 case V_NOTUSED:
10630 return left->valuetype == right->valuetype;
10631 case V_BOOL:
10632 return right->valuetype == V_BOOL &&
10633 left->get_val_bool() == right->get_val_bool();
10634 case V_INT:
10635 return right->valuetype == V_INT && *left->get_val_Int()
10636 == *right->get_val_Int();
10637 case V_REAL:
10638 return right->valuetype == V_REAL &&
10639 left->get_val_Real() == right->get_val_Real();
10640 case V_CSTR:
10641 switch (right->valuetype) {
10642 case V_CSTR:
10643 return left->get_val_str() == right->get_val_str();
10644 case V_USTR:
10645 return right->get_val_ustr() == left->get_val_str();
10646 case V_ISO2022STR:
10647 return right->get_val_iso2022str() == left->get_val_str();
10648 default:
10649 return false;
10650 }
10651 case V_BSTR:
10652 case V_HSTR:
10653 case V_OSTR:
10654 return left->valuetype == right->valuetype &&
10655 left->get_val_str() == right->get_val_str();
10656 case V_USTR:
10657 switch (right->valuetype) {
10658 case V_CSTR:
10659 return left->get_val_ustr() == right->get_val_str();
10660 case V_USTR:
10661 return left->get_val_ustr() == right->get_val_ustr();
10662 case V_ISO2022STR:
10663 return left->get_val_ustr() == right->get_val_iso2022str();
10664 default:
10665 return false;
10666 }
10667 case V_ISO2022STR:
10668 switch (right->valuetype) {
10669 case V_CSTR:
10670 return left->get_val_iso2022str() == right->get_val_str();
10671 case V_USTR:
10672 // The appropriate operator==() is missing. The operands are swapped,
10673 // but it shouldn't be a problem.
10674 return right->get_val_ustr() == left->get_val_iso2022str();
10675 case V_ISO2022STR:
10676 return left->get_val_iso2022str() == right->get_val_iso2022str();
10677 default:
10678 return false;
10679 }
10680 case V_ENUM:
10681 return right->valuetype == V_ENUM &&
10682 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10683 case V_OID:
10684 case V_ROID:
10685 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10686 vector<string> act, other;
10687 get_oid_comps(act);
10688 val.get_oid_comps(other);
10689 size_t act_size = act.size(), other_size = other.size();
10690 bool ret_val;
10691 if (act_size == other_size) {
10692 ret_val = true;
10693 for (size_t i = 0; i < act_size; i++)
10694 if (*act[i] != *other[i]) {
10695 ret_val = false;
10696 break;
10697 }
10698 } else ret_val = false;
10699 for (size_t i = 0; i < act_size; i++) delete act[i];
10700 act.clear();
10701 for (size_t i = 0; i < other_size; i++) delete other[i];
10702 other.clear();
10703 return ret_val;
10704 } else return false;
10705 case V_CHOICE:
10706 return right->valuetype == V_CHOICE &&
10707 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10708 *(left->get_alt_value()) == *(right->get_alt_value());
10709 case V_SEQ:
10710 case V_SET: {
10711 if (!left_governor) FATAL_ERROR("Value::operator==");
10712 if (left->valuetype != right->valuetype) return false;
10713 size_t nof_comps = left_governor->get_nof_comps();
10714 for (size_t i = 0; i < nof_comps; i++) {
10715 Value *lval = NULL, *rval = NULL;
10716 CompField* cfl = left_governor->get_comp_byIndex(i);
10717 const Identifier& field_name = cfl->get_name();
10718 if (left->has_comp_withName(field_name)) {
10719 lval = left->get_comp_value_byName(field_name);
10720 if (right->has_comp_withName(field_name)) {
10721 rval = right->get_comp_value_byName(field_name);
10722 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10723 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10724 return false;
10725 else if (!(*lval == *rval))
10726 return false;
10727 } else {
10728 if (cfl->has_default()) {
10729 if (!(*lval == *cfl->get_defval()))
10730 return false;
10731 } else {
10732 if (lval->valuetype != V_OMIT)
10733 return false;
10734 }
10735 }
10736 } else {
10737 if(right->has_comp_withName(field_name)) {
10738 rval = right->get_comp_value_byName(field_name);
10739 if(cfl->has_default()) {
10740 if(rval->valuetype==V_OMIT) return false;
10741 else {
10742 lval = cfl->get_defval();
10743 if (!(*lval==*rval)) return false;
10744 }
10745 }
10746 }
10747 }
10748 }
10749 return true; }
10750 case V_SEQOF:
10751 case V_ARRAY: {
10752 if (left->valuetype != right->valuetype) return false;
10753 size_t ncomps = get_nof_comps();
10754 if (ncomps != right->get_nof_comps()) return false;
10755
10756 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
10757 bool found = false;
10758 map<IndexedValue*, void> uncovered;
10759 for (size_t i = 0; i < left->get_nof_comps(); ++i)
10760 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
10761
10762 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
10763 found = false;
10764 for (size_t j = 0; j < uncovered.size(); ++j) {
10765 if (*(uncovered.get_nth_key(j)->get_value()) ==
10766 *(right->get_comp_byIndex(i)) &&
10767 *(uncovered.get_nth_key(j)->get_index()) ==
10768 *(right->get_index_byIndex(i))) {
10769 found = true;
10770 uncovered.erase(uncovered.get_nth_key(j));
10771 break;
10772 }
10773 }
10774 if (!found) break;
10775 }
10776 uncovered.clear();
10777 return found;
10778 } else if (left->is_indexed() || right->is_indexed()) {
10779 Value* indexed_one = 0;
10780 Value* not_indexed_one = 0;
10781
10782 if(left->is_indexed()) { // left is indexed, right is not
10783 indexed_one = left;
10784 not_indexed_one = right;
10785 } else { // right indexed, left is not
10786 indexed_one = right;
10787 not_indexed_one = left;
10788 }
10789
10790 for(size_t i = 0; i < ncomps; ++i) {
10791 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
10792 if(!(ind->valuetype == V_INT &&
10793 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
10794 *(indexed_one->get_comp_byIndex(i))))
10795 { return false; }
10796 }
10797 return true;
10798 } else { // none of them is indexed
10799 for (size_t i = 0; i < ncomps; i++) {
10800 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
10801 return false;
10802 }
10803 return true;
10804 }
10805 }
10806 case V_SETOF: {
10807 if (right->valuetype != V_SETOF) return false;
10808 size_t ncomps = get_nof_comps();
10809 if (ncomps != right->get_nof_comps()) return false;
10810 if (ncomps == 0) return true;
10811 map<size_t, void> uncovered;
10812 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
10813 for (size_t i = 0; i < ncomps; i++) {
10814 Value *left_item = left->get_comp_byIndex(i);
10815 bool pair_found = false;
10816 for (size_t j = 0; j < ncomps - i; j++) {
10817 size_t right_index = uncovered.get_nth_key(j);
10818 if (*left_item == *right->get_comp_byIndex(right_index)) {
10819 uncovered.erase(right_index);
10820 pair_found = true;
10821 break;
10822 }
10823 }
10824 if (!pair_found) {
10825 uncovered.clear();
10826 return false;
10827 }
10828 }
10829 return true; }
10830 case V_VERDICT:
10831 return right->valuetype == V_VERDICT &&
10832 left->get_val_verdict() == right->get_val_verdict();
10833 case V_FUNCTION:
10834 case V_ALTSTEP:
10835 case V_TESTCASE:
10836 return left->valuetype == right->valuetype &&
10837 left->get_refd_assignment() == right->get_refd_assignment();
10838 default:
10839 FATAL_ERROR("Value::operator==");
10840 }
10841 return true;
10842 }
10843
10844 bool Value::operator<(Value& val)
10845 {
10846 Value *left = get_value_refd_last();
10847 Type *left_governor = left->get_my_governor();
10848 if(left_governor) left_governor=left_governor->get_type_refd_last();
10849 Value *right = val.get_value_refd_last();
10850 Type *right_governor = right->get_my_governor();
10851 if(right_governor) right_governor=right_governor->get_type_refd_last();
10852 if (left->get_valuetype() != right->get_valuetype())
10853 FATAL_ERROR("Value::operator<");
10854 switch(valuetype){
10855 case V_INT:
10856 return *left->get_val_Int() < *right->get_val_Int();
10857 case V_REAL:
10858 return (left->get_val_Real() < right->get_val_Real());
10859 case V_ENUM:
10860 if(!left_governor || !right_governor)
10861 FATAL_ERROR("Value::operator<");
10862 if(left_governor!=right_governor)
10863 FATAL_ERROR("Value::operator<");
10864 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
10865 right_governor->get_enum_val_byId(*right->get_val_id()));
10866 default:
10867 FATAL_ERROR("Value::operator<");
10868 }
10869 return true;
10870 }
10871
10872 bool Value::is_string_type(Type::expected_value_t exp_val)
10873 {
10874 switch (get_expr_returntype(exp_val)) {
10875 case Type::T_CSTR:
10876 case Type::T_USTR:
10877 case Type::T_BSTR:
10878 case Type::T_HSTR:
10879 case Type::T_OSTR:
10880 return true;
10881 default:
10882 return false;
10883 }
10884 }
10885
10886 void Value::generate_code_expr(expression_struct *expr)
10887 {
10888 if (has_single_expr()) {
10889 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
10890 } else {
10891 switch (valuetype) {
10892 case V_EXPR:
10893 generate_code_expr_expr(expr);
10894 break;
10895 case V_CHOICE:
10896 case V_SEQOF:
10897 case V_SETOF:
10898 case V_ARRAY:
10899 case V_SEQ:
10900 case V_SET: {
10901 const string& tmp_id = get_temporary_id();
10902 const char *tmp_id_str = tmp_id.c_str();
10903 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
10904 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
10905 set_genname_recursive(tmp_id);
10906 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10907 expr->expr = mputstr(expr->expr, tmp_id_str);
10908 break; }
10909 case V_INT: {
10910 const string& tmp_id = get_temporary_id();
10911 const char *tmp_id_str = tmp_id.c_str();
10912 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
10913 tmp_id_str);
10914 set_genname_recursive(tmp_id);
10915 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10916 expr->expr = mputstr(expr->expr, tmp_id_str);
10917 break; }
10918 case V_REFD: {
10919 if (!get_needs_conversion()) {
10920 u.ref.ref->generate_code_const_ref(expr);
10921 } else {
10922 Type *my_gov = get_expr_governor_last();
10923 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
10924 ->get_field_type(u.ref.ref->get_subrefs(),
10925 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
10926 // Make sure that nothing goes wrong.
10927 if (!my_gov || !refd_gov || my_gov == refd_gov)
10928 FATAL_ERROR("Value::generate_code_expr()");
10929 expression_struct expr_tmp;
10930 Code::init_expr(&expr_tmp);
10931 const string& tmp_id1 = get_temporary_id();
10932 const char *tmp_id_str1 = tmp_id1.c_str();
10933 const string& tmp_id2 = get_temporary_id();
10934 const char *tmp_id_str2 = tmp_id2.c_str();
10935 expr->preamble = mputprintf(expr->preamble,
10936 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
10937 tmp_id_str1);
10938 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
10939 u.ref.ref->generate_code_const_ref(&expr_tmp);
10940 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
10941 expr->preamble = mputprintf(expr->preamble,
10942 "%s %s;\n"
10943 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10944 "and `%s' are not compatible at run-time\");\n",
10945 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
10946 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
10947 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
10948 ->get_typename().c_str(), refd_gov->get_typename().c_str());
10949 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
10950 }
10951 break; }
10952 case V_INVOKE:
10953 generate_code_expr_invoke(expr);
10954 break;
10955 default:
10956 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
10957 }
10958 }
10959 }
10960
10961 void Value::generate_code_expr_mandatory(expression_struct *expr)
10962 {
10963 generate_code_expr(expr);
10964 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
10965 generate_code_expr_optional_field_ref(expr, u.ref.ref);
10966 }
10967
10968 bool Value::can_use_increment(Reference *ref) const
10969 {
10970 if (valuetype != V_EXPR) {
10971 return false;
10972 }
10973 switch (u.expr.v_optype) {
10974 case OPTYPE_ADD:
10975 case OPTYPE_SUBTRACT:
10976 break;
10977 default:
10978 return false;
10979 }
10980 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
10981 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
10982 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
10983 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
10984 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
10985 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
10986 return true;
10987 }
10988 return false;
10989 }
10990
10991 char *Value::generate_code_init(char *str, const char *name)
10992 {
10993 if (get_code_generated()) return str;
10994 if (err_descr) {
10995 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
10996 }
10997 switch (valuetype) {
10998 case V_NULL:
10999 case V_BOOL:
11000 case V_REAL:
11001 case V_ENUM:
11002 case V_BSTR:
11003 case V_HSTR:
11004 case V_OSTR:
11005 case V_CSTR:
11006 case V_USTR:
11007 case V_ISO2022STR:
11008 case V_OID:
11009 case V_ROID:
11010 case V_VERDICT:
11011 case V_DEFAULT_NULL:
11012 case V_FAT_NULL:
11013 case V_FUNCTION:
11014 case V_ALTSTEP:
11015 case V_TESTCASE:
11016 // These values have a single string equivalent.
11017 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11018 break;
11019 case V_INT:
11020 if (u.val_Int->is_native_fit())
11021 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11022 else
11023 // It's always an INTEGER.
11024 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11025 "}\n", get_single_expr().c_str(), name);
11026 break;
11027 case V_EXPR:
11028 case V_INVOKE: {
11029 expression_struct expr;
11030 Code::init_expr(&expr);
11031 expr.expr = mputprintf(expr.expr, "%s = ", name);
11032 generate_code_expr(&expr);
11033 str = Code::merge_free_expr(str, &expr);
11034 break; }
11035 case V_CHOICE:
11036 str = generate_code_init_choice(str, name);
11037 break;
11038 case V_SEQOF:
11039 case V_SETOF:
11040 if (!is_indexed()) str = generate_code_init_seof(str, name);
11041 else str = generate_code_init_indexed(str, name);
11042 break;
11043 case V_ARRAY:
11044 if (!is_indexed()) str = generate_code_init_array(str, name);
11045 else str = generate_code_init_indexed(str, name);
11046 break;
11047 case V_SEQ:
11048 case V_SET:
11049 str = generate_code_init_se(str, name);
11050 break;
11051 case V_REFD:
11052 str = generate_code_init_refd(str, name);
11053 break;
11054 case V_MACRO:
11055 switch (u.macro) {
11056 case MACRO_TESTCASEID:
11057 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11058 break;
11059 default:
11060 // all others must already be evaluated away
11061 FATAL_ERROR("Value::generate_code_init()");
11062 }
11063 break;
11064 default:
11065 FATAL_ERROR("Value::generate_code_init()");
11066 }
11067 if (err_descr) {
11068 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11069 }
11070 set_code_generated();
11071 return str;
11072 }
11073
11074 char *Value::rearrange_init_code(char *str)
11075 {
11076 switch (valuetype) {
11077 case V_REFD: {
11078 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11079 if (parlist) {
11080 str = parlist->rearrange_init_code(str,
11081 u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()
11082 == my_scope->get_scope_mod_gen());
11083 }
11084 break; }
11085 case V_INVOKE: {
11086 str = u.invoke.v->rearrange_init_code(str);
11087 bool type_is_local = u.invoke.v->get_expr_governor_last()->get_my_scope()
11088 ->get_scope_mod_gen() == my_scope->get_scope_mod_gen();
11089 str = u.invoke.ap_list->rearrange_init_code(str, type_is_local);
11090 break; }
11091 case V_EXPR:
11092 switch (u.expr.v_optype) {
11093 case OPTYPE_UNARYPLUS:
11094 case OPTYPE_UNARYMINUS:
11095 case OPTYPE_NOT:
11096 case OPTYPE_NOT4B:
11097 case OPTYPE_BIT2HEX:
11098 case OPTYPE_BIT2INT:
11099 case OPTYPE_BIT2OCT:
11100 case OPTYPE_BIT2STR:
11101 case OPTYPE_CHAR2INT:
11102 case OPTYPE_CHAR2OCT:
11103 case OPTYPE_FLOAT2INT:
11104 case OPTYPE_FLOAT2STR:
11105 case OPTYPE_HEX2BIT:
11106 case OPTYPE_HEX2INT:
11107 case OPTYPE_HEX2OCT:
11108 case OPTYPE_HEX2STR:
11109 case OPTYPE_INT2CHAR:
11110 case OPTYPE_INT2FLOAT:
11111 case OPTYPE_INT2STR:
11112 case OPTYPE_INT2UNICHAR:
11113 case OPTYPE_OCT2BIT:
11114 case OPTYPE_OCT2CHAR:
11115 case OPTYPE_OCT2HEX:
11116 case OPTYPE_OCT2INT:
11117 case OPTYPE_OCT2STR:
11118 case OPTYPE_STR2BIT:
11119 case OPTYPE_STR2FLOAT:
11120 case OPTYPE_STR2HEX:
11121 case OPTYPE_STR2INT:
11122 case OPTYPE_STR2OCT:
11123 case OPTYPE_UNICHAR2INT:
11124 case OPTYPE_UNICHAR2CHAR:
11125 case OPTYPE_ENUM2INT:
11126 case OPTYPE_ISCHOSEN_V:
11127 case OPTYPE_GET_STRINGENCODING:
11128 case OPTYPE_REMOVE_BOM:
11129 case OPTYPE_DECODE_BASE64:
11130 str = u.expr.v1->rearrange_init_code(str);
11131 break;
11132 case OPTYPE_DECODE: {
11133 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11134 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11135 bool rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11136 my_scope->get_scope_mod_gen());
11137 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11138
11139 parlist = u.expr.r2->get_parlist();
11140 ass = u.expr.r2->get_refd_assignment();
11141 rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11142 my_scope->get_scope_mod_gen());
11143 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11144 break; }
11145 case OPTYPE_ADD:
11146 case OPTYPE_SUBTRACT:
11147 case OPTYPE_MULTIPLY:
11148 case OPTYPE_DIVIDE:
11149 case OPTYPE_MOD:
11150 case OPTYPE_REM:
11151 case OPTYPE_CONCAT:
11152 case OPTYPE_EQ:
11153 case OPTYPE_LT:
11154 case OPTYPE_GT:
11155 case OPTYPE_NE:
11156 case OPTYPE_GE:
11157 case OPTYPE_LE:
11158 case OPTYPE_AND:
11159 case OPTYPE_OR:
11160 case OPTYPE_XOR:
11161 case OPTYPE_AND4B:
11162 case OPTYPE_OR4B:
11163 case OPTYPE_XOR4B:
11164 case OPTYPE_SHL:
11165 case OPTYPE_SHR:
11166 case OPTYPE_ROTL:
11167 case OPTYPE_ROTR:
11168 case OPTYPE_INT2BIT:
11169 case OPTYPE_INT2HEX:
11170 case OPTYPE_INT2OCT:
11171 //case OPTYPE_DECODE:
11172 str = u.expr.v1->rearrange_init_code(str);
11173 str = u.expr.v2->rearrange_init_code(str);
11174 break;
11175 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11176 case OPTYPE_OCT2UNICHAR:
11177 case OPTYPE_ENCODE_BASE64:
11178 str = u.expr.v1->rearrange_init_code(str);
11179 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str);
11180 break;
11181 case OPTYPE_SUBSTR:
11182 str = u.expr.ti1->rearrange_init_code(str);
11183 str = u.expr.v2->rearrange_init_code(str);
11184 str = u.expr.v3->rearrange_init_code(str);
11185 break;
11186 case OPTYPE_REGEXP:
11187 str = u.expr.ti1->rearrange_init_code(str);
11188 str = u.expr.t2->rearrange_init_code(str);
11189 str = u.expr.v3->rearrange_init_code(str);
11190 break;
11191 case OPTYPE_DECOMP:
11192 str = u.expr.v1->rearrange_init_code(str);
11193 str = u.expr.v2->rearrange_init_code(str);
11194 str = u.expr.v3->rearrange_init_code(str);
11195 break;
11196 case OPTYPE_REPLACE:
11197 str = u.expr.ti1->rearrange_init_code(str);
11198 str = u.expr.v2->rearrange_init_code(str);
11199 str = u.expr.v3->rearrange_init_code(str);
11200 str = u.expr.ti4->rearrange_init_code(str);
11201 break;
11202 case OPTYPE_LENGTHOF:
11203 case OPTYPE_SIZEOF:
11204 case OPTYPE_VALUEOF:
11205 case OPTYPE_ENCODE:
11206 case OPTYPE_ISPRESENT:
11207 case OPTYPE_TTCN2STRING:
11208 str = u.expr.ti1->rearrange_init_code(str);
11209 break;
11210 case OPTYPE_ISCHOSEN_T:
11211 str = u.expr.t1->rearrange_init_code(str);
11212 break;
11213 case OPTYPE_MATCH:
11214 str = u.expr.v1->rearrange_init_code(str);
11215 str = u.expr.t2->rearrange_init_code(str);
11216 break;
11217 default:
11218 // other kinds of expressions cannot appear within templates
11219 break;
11220 }
11221 break;
11222 default:
11223 break;
11224 }
11225 return str;
11226 }
11227
11228 char* Value::generate_code_tmp(char *str, const char *prefix,
11229 size_t& blockcount)
11230 {
11231 char *s2 = memptystr();
11232 char *s1 = generate_code_tmp(NULL, s2);
11233 if (s2[0]) {
11234 if (blockcount == 0) {
11235 str = mputstr(str, "{\n");
11236 blockcount++;
11237 }
11238 str = mputstr(str, s2);
11239 }
11240 Free(s2);
11241 str=mputstr(str, prefix);
11242 str=mputstr(str, s1);
11243 Free(s1);
11244 return str;
11245 }
11246
11247 char *Value::generate_code_tmp(char *str, char*& init)
11248 {
11249 expression_struct expr;
11250 Code::init_expr(&expr);
11251 generate_code_expr_mandatory(&expr);
11252 if (expr.preamble || expr.postamble) {
11253 if (valuetype == V_EXPR &&
11254 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11255 // a temporary variable is already introduced
11256 if (expr.preamble) init = mputstr(init, expr.preamble);
11257 if (expr.postamble) init = mputstr(init, expr.postamble);
11258 str = mputstr(str, expr.expr);
11259 } else {
11260 const string& tmp_id = get_temporary_id();
11261 const char *tmp_id_str = tmp_id.c_str();
11262 init = mputprintf(init, "%s %s;\n"
11263 "{\n",
11264 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11265 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11266 tmp_id_str);
11267 if (expr.preamble) init = mputstr(init, expr.preamble);
11268 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11269 if (expr.postamble) init = mputstr(init, expr.postamble);
11270 init = mputstr(init, "}\n");
11271 str = mputstr(str, tmp_id_str);
11272 }
11273 } else str = mputstr(str, expr.expr);
11274 Code::free_expr(&expr);
11275 return str;
11276 }
11277
11278 void Value::generate_code_log(expression_struct *expr)
11279 {
11280 if (explicit_cast_needed()) {
11281 char *expr_backup = expr->expr;
11282 expr->expr = NULL;
11283 generate_code_expr(expr);
11284 const string& tmp_id = get_temporary_id();
11285 const char *tmp_id_str = tmp_id.c_str();
11286 // We have to create a temporary object, because the parser of GCC
11287 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11288 // constructor call that is, this does not work: type(...).log(); but
11289 // this works: type tmp(...); tmp.log();.
11290 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11291 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11292 expr->expr);
11293 Free(expr->expr);
11294 expr->expr = mputstr(expr_backup, tmp_id_str);
11295 } else {
11296 generate_code_expr(expr);
11297 }
11298 expr->expr = mputstr(expr->expr, ".log()");
11299 }
11300
11301 void Value::generate_code_log_match(expression_struct *expr)
11302 {
11303 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11304 FATAL_ERROR("Value::generate_code_log_match()");
11305 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11306 // compliance the whole code-generation should be checked. Standalone
11307 // constructs like: "A(a[0].f());" should be avoided. The current
11308 // solution for HK38721 uses an additional assignment to overcome the
11309 // issue. The generated code will be slower, but it's needed for old GCC
11310 // versions in specific circumstances.
11311 if (u.expr.t2->needs_temp_ref()) {
11312 char *expr_backup = expr->expr;
11313 expr->expr = NULL;
11314 u.expr.t2->generate_code(expr);
11315 const string& tmp_id = get_temporary_id();
11316 const char *tmp_id_str = tmp_id.c_str();
11317 expr->preamble = mputprintf(expr->preamble,
11318 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11319 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11320 Free(expr->expr);
11321 expr->expr = mputstr(expr_backup, tmp_id_str);
11322 } else {
11323 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11324 // some reason "(A(NS::B)).a(C);" compiles fine.
11325 expr->expr = mputc(expr->expr, '(');
11326 u.expr.t2->generate_code(expr);
11327 expr->expr = mputc(expr->expr, ')');
11328 }
11329 expr->expr = mputstr(expr->expr, ".log_match(");
11330 u.expr.v1->generate_code_expr(expr);
11331 expr->expr = mputc(expr->expr, ')');
11332 }
11333
11334 void Value::generate_code_expr_expr(expression_struct *expr)
11335 {
11336 switch (u.expr.v_optype) {
11337 case OPTYPE_RND:
11338 generate_code_expr_rnd(expr, 0);
11339 break;
11340 case OPTYPE_UNARYPLUS:
11341 // same as without the '+' operator
11342 u.expr.v1->generate_code_expr(expr);
11343 break;
11344 case OPTYPE_UNARYMINUS:
11345 generate_code_expr_unary(expr, "-", u.expr.v1);
11346 break;
11347 case OPTYPE_NOT:
11348 generate_code_expr_unary(expr, "!", u.expr.v1);
11349 break;
11350 case OPTYPE_NOT4B:
11351 generate_code_expr_unary(expr, "~", u.expr.v1);
11352 break;
11353 case OPTYPE_BIT2HEX:
11354 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11355 break;
11356 case OPTYPE_BIT2INT:
11357 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11358 break;
11359 case OPTYPE_BIT2OCT:
11360 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11361 break;
11362 case OPTYPE_BIT2STR:
11363 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11364 break;
11365 case OPTYPE_CHAR2INT:
11366 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11367 break;
11368 case OPTYPE_CHAR2OCT:
11369 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11370 break;
11371 case OPTYPE_FLOAT2INT:
11372 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11373 break;
11374 case OPTYPE_FLOAT2STR:
11375 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11376 break;
11377 case OPTYPE_HEX2BIT:
11378 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11379 break;
11380 case OPTYPE_HEX2INT:
11381 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11382 break;
11383 case OPTYPE_HEX2OCT:
11384 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11385 break;
11386 case OPTYPE_HEX2STR:
11387 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11388 break;
11389 case OPTYPE_INT2CHAR:
11390 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11391 break;
11392 case OPTYPE_INT2FLOAT:
11393 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11394 break;
11395 case OPTYPE_INT2STR:
11396 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11397 break;
11398 case OPTYPE_INT2UNICHAR:
11399 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11400 break;
11401 case OPTYPE_OCT2BIT:
11402 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11403 break;
11404 case OPTYPE_OCT2CHAR:
11405 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11406 break;
11407 case OPTYPE_GET_STRINGENCODING:
11408 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11409 break;
11410 case OPTYPE_REMOVE_BOM:
11411 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11412 break;
11413 case OPTYPE_ENCODE_BASE64:
11414 if (u.expr.v2)
11415 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11416 else
11417 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11418 break;
11419 case OPTYPE_DECODE_BASE64:
11420 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11421 break;
11422 case OPTYPE_OCT2UNICHAR:
11423 if (u.expr.v2)
11424 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11425 else
11426 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11427 break;
11428 case OPTYPE_UNICHAR2OCT:
11429 if (u.expr.v2)
11430 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11431 else
11432 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11433 break;
11434 case OPTYPE_OCT2HEX:
11435 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11436 break;
11437 case OPTYPE_OCT2INT:
11438 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11439 break;
11440 case OPTYPE_OCT2STR:
11441 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11442 break;
11443 case OPTYPE_STR2BIT:
11444 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11445 break;
11446 case OPTYPE_STR2FLOAT:
11447 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11448 break;
11449 case OPTYPE_STR2HEX:
11450 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11451 break;
11452 case OPTYPE_STR2INT:
11453 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11454 break;
11455 case OPTYPE_STR2OCT:
11456 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11457 break;
11458 case OPTYPE_UNICHAR2INT:
11459 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11460 break;
11461 case OPTYPE_UNICHAR2CHAR:
11462 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11463 break;
11464 case OPTYPE_ENUM2INT: {
11465 Type* enum_type = u.expr.v1->get_expr_governor_last();
11466 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11467 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11468 enum_type->get_genname_value(my_scope).c_str());
11469 u.expr.v1->generate_code_expr_mandatory(expr);
11470 expr->expr = mputc(expr->expr, ')');
11471 break;}
11472 case OPTYPE_ENCODE:
11473 generate_code_expr_encode(expr);
11474 break;
11475 case OPTYPE_DECODE:
11476 generate_code_expr_decode(expr);
11477 break;
11478 case OPTYPE_RNDWITHVAL:
11479 generate_code_expr_rnd(expr, u.expr.v1);
11480 break;
11481 case OPTYPE_ADD:
11482 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11483 break;
11484 case OPTYPE_SUBTRACT:
11485 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11486 break;
11487 case OPTYPE_MULTIPLY:
11488 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11489 break;
11490 case OPTYPE_DIVIDE:
11491 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11492 break;
11493 case OPTYPE_MOD:
11494 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11495 break;
11496 case OPTYPE_REM:
11497 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11498 break;
11499 case OPTYPE_CONCAT:
11500 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11501 break;
11502 case OPTYPE_EQ:
11503 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11504 break;
11505 case OPTYPE_LT:
11506 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11507 break;
11508 case OPTYPE_GT:
11509 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11510 break;
11511 case OPTYPE_NE:
11512 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11513 break;
11514 case OPTYPE_GE:
11515 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11516 break;
11517 case OPTYPE_LE:
11518 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11519 break;
11520 case OPTYPE_AND:
11521 case OPTYPE_OR:
11522 generate_code_expr_and_or(expr);
11523 break;
11524 case OPTYPE_XOR:
11525 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11526 break;
11527 case OPTYPE_AND4B:
11528 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11529 break;
11530 case OPTYPE_OR4B:
11531 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11532 break;
11533 case OPTYPE_XOR4B:
11534 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11535 break;
11536 case OPTYPE_SHL:
11537 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11538 break;
11539 case OPTYPE_SHR:
11540 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11541 break;
11542 case OPTYPE_ROTL:
11543 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11544 break;
11545 case OPTYPE_ROTR:
11546 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11547 break;
11548 case OPTYPE_INT2BIT:
11549 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11550 break;
11551 case OPTYPE_INT2HEX:
11552 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11553 break;
11554 case OPTYPE_INT2OCT:
11555 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11556 break;
11557 case OPTYPE_SUBSTR:
11558 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11559 else generate_code_expr_substr_replace_compat(expr);
11560 break;
11561 case OPTYPE_REGEXP:
11562 generate_code_expr_regexp(expr);
11563 break;
11564 case OPTYPE_DECOMP:
11565 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11566 break;
11567 case OPTYPE_REPLACE:
11568 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11569 else generate_code_expr_substr_replace_compat(expr);
11570 break;
11571 case OPTYPE_ISCHOSEN: // r1 i2
11572 FATAL_ERROR("Value::generate_code_expr_expr()");
11573 break;
11574 case OPTYPE_ISCHOSEN_V: // v1 i2
11575 u.expr.v1->generate_code_expr_mandatory(expr);
11576 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11577 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11578 u.expr.i2->get_name().c_str());
11579 break;
11580 case OPTYPE_ISCHOSEN_T: // t1 i2
11581 u.expr.t1->generate_code_expr(expr);
11582 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11583 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11584 u.expr.i2->get_name().c_str());
11585 break;
11586 case OPTYPE_ISPRESENT:
11587 case OPTYPE_ISBOUND: {
11588 Template::templatetype_t temp = u.expr.ti1->get_Template()
11589 ->get_templatetype();
11590 if (temp == Template::SPECIFIC_VALUE) {
11591 Value* specific_value = u.expr.ti1->get_Template()
11592 ->get_specific_value();
11593 if (specific_value->get_valuetype() == Value::V_REFD) {
11594 Ttcn::Reference* reference =
11595 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11596 if (reference) {
11597 reference->generate_code_ispresentbound(expr, false,
11598 u.expr.v_optype==OPTYPE_ISBOUND);
11599 break;
11600 }
11601 }
11602 } else if (temp == Template::TEMPLATE_REFD){
11603 Ttcn::Reference* reference =
11604 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11605 ->get_reference());
11606 if (reference) {
11607 reference->generate_code_ispresentbound(expr, true,
11608 u.expr.v_optype==OPTYPE_ISBOUND);
11609 break;
11610 }
11611 }
11612 }
11613 // no break
11614 case OPTYPE_LENGTHOF: // ti1
11615 // fall through, separated later
11616 case OPTYPE_SIZEOF: // ti1
11617 // fall through, separated later
11618 case OPTYPE_ISVALUE: { // ti1
11619 if (u.expr.ti1->is_only_specific_value()) {
11620 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11621 bool cast_needed = t_val->explicit_cast_needed(
11622 u.expr.v_optype != OPTYPE_LENGTHOF);
11623 if(cast_needed) {
11624 // the ambiguous C++ expression is converted to the value class
11625 expr->expr = mputprintf(expr->expr, "%s(",
11626 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11627 }
11628
11629 if (u.expr.v_optype != OPTYPE_LENGTHOF
11630 && u.expr.v_optype != OPTYPE_SIZEOF) {
11631 t_val->generate_code_expr(expr);
11632 } else {
11633 t_val->generate_code_expr_mandatory(expr);
11634 }
11635
11636 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11637 }
11638 else u.expr.ti1->generate_code(expr);
11639
11640 switch (u.expr.v_optype) {
11641 case OPTYPE_ISBOUND:
11642 expr->expr=mputstr(expr->expr, ".is_bound()");
11643 break;
11644 case OPTYPE_ISPRESENT:
11645 expr->expr=mputstr(expr->expr, ".is_present()");
11646 break;
11647 case OPTYPE_SIZEOF:
11648 expr->expr=mputstr(expr->expr, ".size_of()");
11649 break;
11650 case OPTYPE_LENGTHOF:
11651 expr->expr=mputstr(expr->expr, ".lengthof()");
11652 break;
11653 case OPTYPE_ISVALUE:
11654 expr->expr=mputstr(expr->expr, ".is_value()");
11655 break;
11656 default:
11657 FATAL_ERROR("Value::generate_code_expr_expr()");
11658 }
11659 break; }
11660 case OPTYPE_VALUEOF: // ti1
11661 u.expr.ti1->generate_code(expr);
11662 expr->expr = mputstr(expr->expr, ".valueof()");
11663 break;
11664 case OPTYPE_MATCH: // v1 t2
11665 u.expr.t2->generate_code(expr);
11666 expr->expr = mputstr(expr->expr, ".match(");
11667 u.expr.v1->generate_code_expr(expr);
11668 expr->expr = mputc(expr->expr, ')');
11669 break;
11670 case OPTYPE_UNDEF_RUNNING:
11671 // it is resolved during semantic check
11672 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11673 break;
11674 case OPTYPE_COMP_NULL: // -
11675 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11676 break;
11677 case OPTYPE_COMP_MTC: // -
11678 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11679 break;
11680 case OPTYPE_COMP_SYSTEM: // -
11681 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11682 break;
11683 case OPTYPE_COMP_SELF: // -
11684 expr->expr=mputstr(expr->expr, "self");
11685 break;
11686 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11687 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11688 u.expr.b4);
11689 break;
11690 case OPTYPE_COMP_RUNNING: // v1
11691 u.expr.v1->generate_code_expr(expr);
11692 if(u.expr.v1->get_valuetype() == V_REFD)
11693 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11694 expr->expr = mputstr(expr->expr, ".running()");
11695 break;
11696 case OPTYPE_COMP_RUNNING_ANY: // -
11697 expr->expr=mputstr(expr->expr,
11698 "TTCN_Runtime::component_running(ANY_COMPREF)");
11699 break;
11700 case OPTYPE_COMP_RUNNING_ALL: // -
11701 expr->expr=mputstr(expr->expr,
11702 "TTCN_Runtime::component_running(ALL_COMPREF)");
11703 break;
11704 case OPTYPE_COMP_ALIVE: // v1
11705 u.expr.v1->generate_code_expr(expr);
11706 if(u.expr.v1->get_valuetype() == V_REFD)
11707 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11708 expr->expr = mputstr(expr->expr, ".alive()");
11709 break;
11710 case OPTYPE_COMP_ALIVE_ANY: // -
11711 expr->expr = mputstr(expr->expr,
11712 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11713 break;
11714 case OPTYPE_COMP_ALIVE_ALL: // -
11715 expr->expr = mputstr(expr->expr,
11716 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11717 break;
11718 case OPTYPE_TMR_READ: // r1
11719 u.expr.r1->generate_code(expr);
11720 expr->expr = mputstr(expr->expr, ".read()");
11721 break;
11722 case OPTYPE_TMR_RUNNING: // r1
11723 u.expr.r1->generate_code(expr);
11724 expr->expr = mputstr(expr->expr, ".running()");
11725 break;
11726 case OPTYPE_TMR_RUNNING_ANY: // -
11727 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11728 break;
11729 case OPTYPE_GETVERDICT: // -
11730 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11731 break;
11732 case OPTYPE_TESTCASENAME: // -
11733 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11734 break;
11735 case OPTYPE_ACTIVATE: // r1
11736 generate_code_expr_activate(expr);
11737 break;
11738 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
11739 generate_code_expr_activate_refd(expr);
11740 break;
11741 case OPTYPE_EXECUTE: // r1 [v2]
11742 generate_code_expr_execute(expr);
11743 break;
11744 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
11745 generate_code_expr_execute_refd(expr);
11746 break;
11747 case OPTYPE_LOG2STR:
11748 u.expr.logargs->generate_code_expr(expr);
11749 break;
11750 case OPTYPE_TTCN2STRING: {
11751 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
11752 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
11753 param_governor = param_governor->get_type_refd_last();
11754 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
11755 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
11756 u.expr.ti1->get_Template()->is_Value()) {
11757 Value* v = u.expr.ti1->get_Template()->get_Value();
11758 delete u.expr.ti1;
11759 u.expr.ti1 = NULL;
11760 bool cast_needed = v->explicit_cast_needed();
11761 if (cast_needed) {
11762 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
11763 }
11764 v->generate_code_expr(expr);
11765 if (cast_needed) {
11766 expr->expr = mputstr(expr->expr, ")");
11767 }
11768 delete v;
11769 } else {
11770 u.expr.ti1->generate_code(expr);
11771 }
11772 expr->expr = mputstr(expr->expr, ")");
11773 } break;
11774 default:
11775 FATAL_ERROR("Value::generate_code_expr_expr()");
11776 }
11777 }
11778
11779 void Value::generate_code_expr_unary(expression_struct *expr,
11780 const char *operator_str, Value *v1)
11781 {
11782 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
11783 v1->generate_code_expr_mandatory(expr);
11784 expr->expr = mputstrn(expr->expr, "))", 2);
11785 }
11786
11787 void Value::generate_code_expr_infix(expression_struct *expr,
11788 const char *operator_str, Value *v1,
11789 Value *v2, bool optional_allowed)
11790 {
11791 if (!get_needs_conversion()) {
11792 expr->expr = mputc(expr->expr, '(');
11793 if (optional_allowed) v1->generate_code_expr(expr);
11794 else v1->generate_code_expr_mandatory(expr);
11795 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
11796 if (optional_allowed) v2->generate_code_expr(expr);
11797 else v2->generate_code_expr_mandatory(expr);
11798 expr->expr = mputc(expr->expr, ')');
11799 } else { // Temporary variable for the converted value.
11800 const string& tmp_id1 = get_temporary_id();
11801 const char *tmp_id_str1 = tmp_id1.c_str();
11802 expression_struct expr_tmp;
11803 Code::init_expr(&expr_tmp);
11804 switch (u.expr.v_optype) {
11805 case OPTYPE_EQ:
11806 case OPTYPE_NE: {
11807 // Always "v1 -> v2".
11808 Type *t1 = v1->get_expr_governor_last();
11809 Type *t2 = v2->get_expr_governor_last();
11810 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
11811 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11812 else v2->generate_code_expr_mandatory(&expr_tmp);
11813 if (expr_tmp.preamble)
11814 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11815 expr->preamble = mputprintf(expr->preamble,
11816 "%s %s;\n"
11817 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11818 "and `%s' are not compatible at run-time\");\n",
11819 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
11820 TypeConv::get_conv_func(t2, t1, get_my_scope()
11821 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
11822 t2->get_typename().c_str(), t1->get_typename().c_str());
11823 Code::free_expr(&expr_tmp);
11824 if (optional_allowed) v1->generate_code_expr(expr);
11825 else v1->generate_code_expr_mandatory(expr);
11826 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
11827 tmp_id_str1);
11828 break; }
11829 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11830 // functions. The governors of all operands must exist at this point.
11831 case OPTYPE_ROTL:
11832 case OPTYPE_ROTR:
11833 case OPTYPE_CONCAT: {
11834 const string& tmp_id2 = get_temporary_id();
11835 const char *tmp_id_str2 = tmp_id2.c_str();
11836 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
11837 Type *my_gov = my_governor->get_type_refd_last();
11838 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
11839 ->get_type_refd_last();
11840 if (!t1_gov || my_gov == t1_gov)
11841 FATAL_ERROR("Value::generate_code_expr_infix()");
11842 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11843 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
11844 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11845 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
11846 else v1->generate_code_expr_mandatory(&expr_tmp);
11847 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
11848 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11849 else v2->generate_code_expr_mandatory(&expr_tmp);
11850 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11851 expr->preamble = mputprintf(expr->preamble,
11852 "%s %s;\n"
11853 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11854 "and `%s' are not compatible at run-time\");\n",
11855 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11856 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
11857 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
11858 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
11859 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11860 break; }
11861 default:
11862 FATAL_ERROR("Value::generate_code_expr_infix()");
11863 break;
11864 }
11865 }
11866 }
11867
11868 void Value::generate_code_expr_and_or(expression_struct *expr)
11869 {
11870 if (u.expr.v2->needs_short_circuit()) {
11871 // introduce a temporary variable to store the result of the operation
11872 const string& tmp_id = get_temporary_id();
11873 const char *tmp_id_str = tmp_id.c_str();
11874 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
11875 expression_struct expr2;
11876 // the left operand must be evaluated anyway
11877 Code::init_expr(&expr2);
11878 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11879 u.expr.v1->generate_code_expr_mandatory(&expr2);
11880 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11881 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
11882 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
11883 // evaluate the right operand only when necessary
11884 // in this case the final result will be the right operand
11885 Code::init_expr(&expr2);
11886 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11887 u.expr.v2->generate_code_expr_mandatory(&expr2);
11888 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11889 // the result is now in the temporary variable
11890 expr->expr = mputstr(expr->expr, tmp_id_str);
11891 } else {
11892 // use the overloaded operator to get better error messages
11893 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
11894 "&&" : "||", u.expr.v1, u.expr.v2, false);
11895 }
11896 }
11897
11898 void Value::generate_code_expr_predef1(expression_struct *expr,
11899 const char *function_name,
11900 Value *v1)
11901 {
11902 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11903 v1->generate_code_expr_mandatory(expr);
11904 expr->expr = mputc(expr->expr, ')');
11905 }
11906
11907 void Value::generate_code_expr_predef2(expression_struct *expr,
11908 const char *function_name,
11909 Value *v1, Value *v2)
11910 {
11911 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11912 v1->generate_code_expr_mandatory(expr);
11913 expr->expr = mputstr(expr->expr, ", ");
11914 v2->generate_code_expr_mandatory(expr);
11915 expr->expr = mputc(expr->expr, ')');
11916 }
11917
11918 void Value::generate_code_expr_predef3(expression_struct *expr,
11919 const char *function_name,
11920 Value *v1, Value *v2, Value *v3)
11921 {
11922 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11923 v1->generate_code_expr_mandatory(expr);
11924 expr->expr = mputstr(expr->expr, ", ");
11925 v2->generate_code_expr_mandatory(expr);
11926 expr->expr = mputstr(expr->expr, ", ");
11927 v3->generate_code_expr_mandatory(expr);
11928 expr->expr = mputc(expr->expr, ')');
11929 }
11930
11931 void Value::generate_code_expr_substr(expression_struct *expr)
11932 {
11933 bool par1_is_str;
11934 Value* v1 = u.expr.ti1->get_specific_value();
11935 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
11936 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
11937 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
11938 if (v1) v1->generate_code_expr_mandatory(expr);
11939 else u.expr.ti1->generate_code(expr);
11940 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
11941 else expr->expr = mputstr(expr->expr, ".substr(");
11942 if (!par1_is_str && u.expr.v2->is_unfoldable())
11943 expr->expr = mputstr(expr->expr, "(int)");
11944 u.expr.v2->generate_code_expr_mandatory(expr);
11945 expr->expr = mputstr(expr->expr, ", ");
11946 if (!par1_is_str && u.expr.v3->is_unfoldable())
11947 expr->expr = mputstr(expr->expr, "(int)");
11948 u.expr.v3->generate_code_expr_mandatory(expr);
11949 expr->expr = mputc(expr->expr, ')');
11950 }
11951
11952 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
11953 {
11954 expression_struct expr_tmp;
11955 Code::init_expr(&expr_tmp);
11956 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
11957 ->get_type_refd_last();
11958 if (!t1 || t1 == my_governor->get_type_refd_last())
11959 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11960 if (u.expr.v_optype == OPTYPE_SUBSTR) {
11961 generate_code_expr_substr(&expr_tmp);
11962 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
11963 generate_code_expr_replace(&expr_tmp);
11964 } else {
11965 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11966 }
11967 // Two temporaries to store the result of substr() or replace() and to
11968 // store the converted value.
11969 const string& tmp_id1 = get_temporary_id();
11970 const char *tmp_id_str1 = tmp_id1.c_str();
11971 const string& tmp_id2 = get_temporary_id();
11972 const char *tmp_id_str2 = tmp_id2.c_str();
11973 if (expr_tmp.preamble)
11974 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11975 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
11976 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
11977 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
11978 if (expr_tmp.postamble)
11979 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
11980 Code::free_expr(&expr_tmp);
11981 expr->preamble = mputprintf(expr->preamble,
11982 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
11983 "`%s' are not compatible at run-time\");\n",
11984 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
11985 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
11986 my_governor->get_typename().c_str(), t1->get_typename().c_str());
11987 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
11988 }
11989
11990 void Value::generate_code_expr_regexp(expression_struct *expr)
11991 {
11992 Value* v1 = u.expr.ti1->get_specific_value();
11993 Value* v2 = u.expr.t2->get_specific_value();
11994 expr->expr = mputstr(expr->expr, "regexp(");
11995 if (v1) v1->generate_code_expr_mandatory(expr);
11996 else u.expr.ti1->generate_code(expr);
11997 expr->expr = mputstr(expr->expr, ", ");
11998 if (v2) v2->generate_code_expr_mandatory(expr);
11999 else u.expr.t2->generate_code(expr);
12000 expr->expr = mputstr(expr->expr, ", ");
12001 u.expr.v3->generate_code_expr_mandatory(expr);
12002 expr->expr = mputc(expr->expr, ')');
12003 }
12004
12005 void Value::generate_code_expr_replace(expression_struct *expr)
12006 {
12007 Value* v1 = u.expr.ti1->get_specific_value();
12008 Value* v4 = u.expr.ti4->get_specific_value();
12009 bool par1_is_str;
12010 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12011 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12012 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12013 if (v1) v1->generate_code_expr_mandatory(expr);
12014 else u.expr.ti1->generate_code(expr);
12015 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12016 else expr->expr = mputstr(expr->expr, ".replace(");
12017 if (!par1_is_str && u.expr.v2->is_unfoldable())
12018 expr->expr = mputstr(expr->expr, "(int)");
12019 u.expr.v2->generate_code_expr_mandatory(expr);
12020 expr->expr = mputstr(expr->expr, ", ");
12021 if (!par1_is_str && u.expr.v3->is_unfoldable())
12022 expr->expr = mputstr(expr->expr, "(int)");
12023 u.expr.v3->generate_code_expr_mandatory(expr);
12024 expr->expr = mputstr(expr->expr, ", ");
12025 if (v4) {
12026 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12027 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12028 Value* v4_last = v4->get_value_refd_last();
12029 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12030 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12031 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_stringRepr().c_str());
12032 }
12033 v4->generate_code_expr_mandatory(expr);
12034 }
12035 else u.expr.ti4->generate_code(expr);
12036 expr->expr = mputc(expr->expr, ')');
12037 }
12038
12039 void Value::generate_code_expr_rnd(expression_struct *expr,
12040 Value *v1)
12041 {
12042 if(!v1) // simple random generation
12043 expr->expr = mputstr(expr->expr, "rnd()");
12044 else { // random generation with seeding
12045 expr->expr = mputstr(expr->expr, "rnd(");
12046 v1->generate_code_expr_mandatory(expr);
12047 expr->expr = mputc(expr->expr, ')');
12048 }
12049 }
12050
12051 void Value::generate_code_expr_create(expression_struct *expr,
12052 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12053 {
12054 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12055 // first two arguments: component type
12056 Assignment *t_ass = type->get_refd_assignment();
12057 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12058 FATAL_ERROR("Value::generate_code_expr_create()");
12059 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12060 Type::EXPECTED_DYNAMIC_VALUE);
12061 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12062 comptype = comptype->get_type_refd_last();
12063 expr->expr = comptype->get_CompBody()
12064 ->generate_code_comptype_name(expr->expr);
12065 expr->expr = mputstr(expr->expr, ", ");
12066 // third argument: component name
12067 if (name) {
12068 Value *t_val = name->get_value_refd_last();
12069 if (t_val->valuetype == V_CSTR) {
12070 // the argument is foldable to a string literal
12071 size_t str_len = t_val->u.str.val_str->size();
12072 const char *str_ptr = t_val->u.str.val_str->c_str();
12073 expr->expr = mputc(expr->expr, '"');
12074 for (size_t i = 0; i < str_len; i++)
12075 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12076 expr->expr = mputc(expr->expr, '"');
12077 } else name->generate_code_expr_mandatory(expr);
12078 } else expr->expr = mputstr(expr->expr, "NULL");
12079 expr->expr = mputstr(expr->expr, ", ");
12080 // fourth argument: location
12081 if (location) {
12082 Value *t_val = location->get_value_refd_last();
12083 if (t_val->valuetype == V_CSTR) {
12084 // the argument is foldable to a string literal
12085 size_t str_len = t_val->u.str.val_str->size();
12086 const char *str_ptr = t_val->u.str.val_str->c_str();
12087 expr->expr = mputc(expr->expr, '"');
12088 for (size_t i = 0; i < str_len; i++)
12089 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12090 expr->expr = mputc(expr->expr, '"');
12091 } else location->generate_code_expr_mandatory(expr);
12092 } else expr->expr = mputstr(expr->expr, "NULL");
12093 // fifth argument: alive flag
12094 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12095 }
12096
12097 void Value::generate_code_expr_activate(expression_struct *expr)
12098 {
12099 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12100 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12101 FATAL_ERROR("Value::generate_code_expr_activate()");
12102 expr->expr = mputprintf(expr->expr, "%s(",
12103 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12104 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12105 expr->expr = mputc(expr->expr, ')');
12106 }
12107
12108 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12109 {
12110 Value *v_last = u.expr.v1->get_value_refd_last();
12111 if (v_last->valuetype == V_ALTSTEP) {
12112 // the referred altstep is known
12113 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12114 ->get_genname_from_scope(my_scope, "activate_").c_str());
12115 } else {
12116 // the referred altstep is unknown
12117 u.expr.v1->generate_code_expr_mandatory(expr);
12118 expr->expr = mputstr(expr->expr,".activate(");
12119 }
12120 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12121 expr->expr = mputc(expr->expr, ')');
12122 }
12123
12124 void Value::generate_code_expr_execute(expression_struct *expr)
12125 {
12126 Assignment *testcase = u.expr.r1->get_refd_assignment();
12127 expr->expr = mputprintf(expr->expr, "%s(",
12128 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12129 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12130 if (parlist->get_nof_pars() > 0) {
12131 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12132 0, false);
12133 expr->expr = mputstr(expr->expr, ", ");
12134 }
12135 if (u.expr.v2) {
12136 expr->expr = mputstr(expr->expr, "TRUE, ");
12137 u.expr.v2->generate_code_expr_mandatory(expr);
12138 expr->expr = mputc(expr->expr, ')');
12139 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12140 }
12141
12142 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12143 {
12144 Value *v_last = u.expr.v1->get_value_refd_last();
12145 if (v_last->valuetype == V_TESTCASE) {
12146 // the referred testcase is known
12147 Assignment *testcase = v_last->get_refd_fat();
12148 expr->expr = mputprintf(expr->expr, "%s(",
12149 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12150 u.expr.ap_list2->generate_code_alias(expr,
12151 testcase->get_FormalParList(), 0, false);
12152 } else {
12153 // the referred testcase is unknown
12154 u.expr.v1->generate_code_expr_mandatory(expr);
12155 expr->expr = mputstr(expr->expr,".execute(");
12156 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12157 }
12158 if (u.expr.ap_list2->get_nof_pars() > 0)
12159 expr->expr = mputstr(expr->expr, ", ");
12160 if (u.expr.v3) {
12161 expr->expr = mputstr(expr->expr, "TRUE, ");
12162 u.expr.v3->generate_code_expr_mandatory(expr);
12163 expr->expr = mputc(expr->expr, ')');
12164 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12165 }
12166
12167 void Value::generate_code_expr_invoke(expression_struct *expr)
12168 {
12169 Value *last_v = u.invoke.v->get_value_refd_last();
12170 if (last_v->get_valuetype() == V_FUNCTION) {
12171 // the referred function is known
12172 Assignment *function = last_v->get_refd_fat();
12173 expr->expr = mputprintf(expr->expr, "%s(",
12174 function->get_genname_from_scope(my_scope).c_str());
12175 u.invoke.ap_list->generate_code_alias(expr,
12176 function->get_FormalParList(), function->get_RunsOnType(), false);
12177 } else {
12178 // the referred function is unknown
12179 u.invoke.v->generate_code_expr_mandatory(expr);
12180 expr->expr = mputstr(expr->expr, ".invoke(");
12181 Type* gov_last = last_v->get_expr_governor_last();
12182 u.invoke.ap_list->generate_code_alias(expr, 0,
12183 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12184 }
12185 expr->expr = mputc(expr->expr, ')');
12186 }
12187
12188 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12189 Reference *ref)
12190 {
12191 // if the referenced value points to an optional value field the
12192 // generated code has to be corrected at the end:
12193 // `fieldid()' => `fieldid()()'
12194 Assignment *ass = ref->get_refd_assignment();
12195 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12196 switch (ass->get_asstype()) {
12197 case Assignment::A_CONST:
12198 case Assignment::A_EXT_CONST:
12199 case Assignment::A_MODULEPAR:
12200 case Assignment::A_VAR:
12201 case Assignment::A_FUNCTION_RVAL:
12202 case Assignment::A_EXT_FUNCTION_RVAL:
12203 case Assignment::A_PAR_VAL_IN:
12204 case Assignment::A_PAR_VAL_OUT:
12205 case Assignment::A_PAR_VAL_INOUT:
12206 // only these are mapped to value objects
12207 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12208 expr->expr = mputstr(expr->expr, "()");
12209 break;
12210 default:
12211 break;
12212 }
12213 }
12214
12215 void Value::generate_code_expr_encode(expression_struct *expr)
12216 {
12217 Value* v1 = 0;
12218
12219 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12220 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12221 v1 = templ->get_specific_value();
12222 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12223
12224 expression_struct expr2;
12225 Code::init_expr(&expr2);
12226
12227 bool is_templ = false;
12228 switch (templ->get_templatetype()) {
12229 case Template::SPECIFIC_VALUE:
12230 v1->generate_code_expr_mandatory(&expr2);
12231 break;
12232 default:
12233 u.expr.ti1->generate_code(&expr2);
12234 is_templ = true;
12235 break;
12236 }
12237
12238 if (!gov_last->is_coding_by_function()) {
12239 const string& tmp_id = get_temporary_id();
12240 const string& tmp_buf_id = get_temporary_id();
12241 const string& tmp_ref_id = get_temporary_id();
12242 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12243 tmp_id.c_str());
12244 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12245 tmp_buf_id.c_str());
12246 if (expr2.preamble) { // copy preamble setting up the argument, if any
12247 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12248 expr->preamble = mputc (expr->preamble, '\n');
12249 }
12250 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12251 gov_last->get_genname_typedescriptor(
12252 u.expr.ti1->get_Template()->get_my_scope()
12253 ).c_str(),
12254 tmp_ref_id.c_str(),
12255 expr2.expr);
12256 if (is_templ) // make a value out of the template, if needed
12257 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12258 expr->preamble = mputprintf(expr->preamble,
12259 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12260 tmp_ref_id.c_str(),
12261 gov_last->get_genname_typedescriptor(
12262 u.expr.ti1->get_Template()->get_my_scope()
12263 ).c_str(),
12264 tmp_buf_id.c_str(),
12265 gov_last->get_coding(true).c_str()
12266 );
12267 expr->preamble = mputstr(expr->preamble, ");\n");
12268 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12269 tmp_buf_id.c_str(),
12270 tmp_id.c_str()
12271 );
12272 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12273 if (expr2.postamble)
12274 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12275 } else
12276 expr->expr = mputprintf(expr->expr, "%s(%s)",
12277 gov_last->get_coding(true).c_str(), expr2.expr);
12278 Code::free_expr(&expr2);
12279 }
12280
12281 void Value::generate_code_expr_decode(expression_struct *expr)
12282 {
12283 expression_struct expr1, expr2;
12284 Code::init_expr(&expr1);
12285 Code::init_expr(&expr2);
12286 u.expr.r1->generate_code(&expr1);
12287 u.expr.r2->generate_code(&expr2);
12288
12289 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12290 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12291 get_type_refd_last();
12292
12293 if (expr1.preamble)
12294 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12295 if (expr2.preamble)
12296 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12297
12298 if (!_type->is_coding_by_function()) {
12299 const string& tmp_id = get_temporary_id();
12300 const string& buffer_id = get_temporary_id();
12301 const string& retval_id = get_temporary_id();
12302 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12303 field_is_optional(u.expr.r2->get_subrefs());
12304
12305 expr->preamble = mputprintf(expr->preamble,
12306 "TTCN_Buffer %s(bit2oct(%s));\n"
12307 "INTEGER %s;\n"
12308 "TTCN_EncDec::set_error_behavior("
12309 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12310 "TTCN_EncDec::clear_error();\n",
12311 buffer_id.c_str(),
12312 expr1.expr,
12313 retval_id.c_str()
12314 );
12315 expr->preamble = mputprintf(expr->preamble,
12316 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12317 expr2.expr,
12318 optional ? "()" : "",
12319 _type->get_genname_typedescriptor(
12320 u.expr.r2->get_my_scope()
12321 ).c_str(),
12322 buffer_id.c_str(),
12323 _type->get_coding(false).c_str()
12324 );
12325 expr->preamble = mputprintf(expr->preamble,
12326 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12327 "case TTCN_EncDec::ET_NONE: {\n"
12328 "%s.cut();\n"
12329 "OCTETSTRING %s;\n"
12330 "%s.get_string(%s);\n"
12331 "%s = oct2bit(%s);\n"
12332 "%s = 0;\n"
12333 "}break;\n"
12334 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12335 "case TTCN_EncDec::ET_LEN_ERR:\n"
12336 "%s = 2;\n"
12337 "break;\n"
12338 "default:\n"
12339 "%s = 1;\n"
12340 "}\n"
12341 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12342 "TTCN_EncDec::EB_DEFAULT);\n"
12343 "TTCN_EncDec::clear_error();\n",
12344 buffer_id.c_str(),
12345 tmp_id.c_str(),
12346 buffer_id.c_str(),
12347 tmp_id.c_str(),
12348 expr1.expr,
12349 tmp_id.c_str(),
12350 retval_id.c_str(),
12351 retval_id.c_str(),
12352 retval_id.c_str()
12353 );
12354 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12355 } else
12356 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12357 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12358 if (expr1.postamble)
12359 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12360 if (expr2.postamble)
12361 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12362 Code::free_expr(&expr1);
12363 Code::free_expr(&expr2);
12364 }
12365
12366 char *Value::generate_code_init_choice(char *str, const char *name)
12367 {
12368 const char *alt_name = u.choice.alt_name->get_name().c_str();
12369 // Safe as long as get_name() returns a const string&, not a temporary.
12370 const char *alt_prefix =
12371 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12372 ? "AT_" : "";
12373 if (u.choice.alt_value->needs_temp_ref()) {
12374 const string& tmp_id = get_temporary_id();
12375 const char *tmp_id_str = tmp_id.c_str();
12376 str = mputprintf(str, "{\n"
12377 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12378 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12379 alt_prefix, alt_name);
12380 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12381 str = mputstr(str, "}\n");
12382 } else {
12383 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12384 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12385 Free(embedded_name);
12386 }
12387 return str;
12388 }
12389
12390 char *Value::generate_code_init_seof(char *str, const char *name)
12391 {
12392 size_t nof_vs = u.val_vs->get_nof_vs();
12393 if (nof_vs > 0) {
12394 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12395 const string& embedded_type =
12396 my_governor->get_ofType()->get_genname_value(my_scope);
12397 const char *embedded_type_str = embedded_type.c_str();
12398 for (size_t i = 0; i < nof_vs; i++) {
12399 Value *comp_v = u.val_vs->get_v_byIndex(i);
12400
12401 if (comp_v->valuetype == V_NOTUSED) continue;
12402 else if (comp_v->needs_temp_ref()) {
12403 const string& tmp_id = get_temporary_id();
12404 const char *tmp_id_str = tmp_id.c_str();
12405 str = mputprintf(str, "{\n"
12406 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12407 (unsigned long) i);
12408 str = comp_v->generate_code_init(str, tmp_id_str);
12409 str = mputstr(str, "}\n");
12410 } else {
12411 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12412 str = comp_v->generate_code_init(str, embedded_name);
12413 Free(embedded_name);
12414 }
12415 }
12416 } else {
12417 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12418 }
12419 return str;
12420 }
12421
12422 char *Value::generate_code_init_indexed(char *str, const char *name)
12423 {
12424 size_t nof_ivs = u.val_vs->get_nof_ivs();
12425 if (nof_ivs > 0) {
12426 // Previous values can be truncated. The concept is similar to
12427 // templates.
12428 Type *t_last = my_governor->get_type_refd_last();
12429 const string& oftype_name =
12430 t_last->get_ofType()->get_genname_value(my_scope);
12431 const char *oftype_name_str = oftype_name.c_str();
12432 for (size_t i = 0; i < nof_ivs; i++) {
12433 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12434 const string& tmp_id_1 = get_temporary_id();
12435 str = mputstr(str, "{\n");
12436 Value *index = iv->get_index();
12437 if (index->get_valuetype() != V_INT) {
12438 const string& tmp_id_2 = get_temporary_id();
12439 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12440 str = index->generate_code_init(str, tmp_id_2.c_str());
12441 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12442 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12443 } else {
12444 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12445 tmp_id_1.c_str(), name,
12446 (index->get_val_Int()->t_str()).c_str());
12447 }
12448 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12449 str = mputstr(str, "}\n");
12450 }
12451 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12452 return str;
12453 }
12454
12455 char *Value::generate_code_init_array(char *str, const char *name)
12456 {
12457 size_t nof_vs = u.val_vs->get_nof_vs();
12458 Type *t_last = my_governor->get_type_refd_last();
12459 Int index_offset = t_last->get_dimension()->get_offset();
12460 const string& embedded_type =
12461 t_last->get_ofType()->get_genname_value(my_scope);
12462 const char *embedded_type_str = embedded_type.c_str();
12463 for (size_t i = 0; i < nof_vs; i++) {
12464 Value *comp_v = u.val_vs->get_v_byIndex(i);
12465 if (comp_v->valuetype == V_NOTUSED) continue;
12466 else if (comp_v->needs_temp_ref()) {
12467 const string& tmp_id = get_temporary_id();
12468 const char *tmp_id_str = tmp_id.c_str();
12469 str = mputprintf(str, "{\n"
12470 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12471 Int2string(index_offset + i).c_str());
12472 str = comp_v->generate_code_init(str, tmp_id_str);
12473 str = mputstr(str, "}\n");
12474 } else {
12475 char *embedded_name = mprintf("%s[%s]", name,
12476 Int2string(index_offset + i).c_str());
12477 str = comp_v->generate_code_init(str, embedded_name);
12478 Free(embedded_name);
12479 }
12480 }
12481 return str;
12482 }
12483
12484 char *Value::generate_code_init_se(char *str, const char *name)
12485 {
12486 Type *type = my_governor->get_type_refd_last();
12487 size_t nof_comps = type->get_nof_comps();
12488 if (nof_comps > 0) {
12489 for (size_t i = 0; i < nof_comps; i++) {
12490 CompField *cf = type->get_comp_byIndex(i);
12491 const Identifier& field_id = cf->get_name();
12492 const char *field_name = field_id.get_name().c_str();
12493 Value *field_v;
12494 if (u.val_nvs->has_nv_withName(field_id)) {
12495 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12496 if (field_v->valuetype == V_NOTUSED) continue;
12497 if (field_v->valuetype == V_OMIT) field_v = 0;
12498 } else if (is_asn1()) {
12499 if (cf->has_default()) {
12500 // handle like a referenced value
12501 Value *defval = cf->get_defval();
12502 if (needs_init_precede(defval)) {
12503 str = defval->generate_code_init(str,
12504 defval->get_lhs_name().c_str());
12505 }
12506 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12507 defval->get_genname_own(my_scope).c_str());
12508 continue;
12509 } else {
12510 if (!cf->get_is_optional())
12511 FATAL_ERROR("Value::generate_code_init()");
12512 field_v = 0;
12513 }
12514 } else {
12515 continue;
12516 }
12517 if (field_v) {
12518 // the value is not omit
12519 if (field_v->needs_temp_ref()) {
12520 const string& tmp_id = get_temporary_id();
12521 const char *tmp_id_str = tmp_id.c_str();
12522 str = mputprintf(str, "{\n"
12523 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12524 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12525 field_name);
12526 str = field_v->generate_code_init(str, tmp_id_str);
12527 str = mputstr(str, "}\n");
12528 } else {
12529 char *embedded_name = mprintf("%s.%s()", name,
12530 field_name);
12531 if (cf->get_is_optional() && field_v->is_compound())
12532 embedded_name = mputstr(embedded_name, "()");
12533 str = field_v->generate_code_init(str, embedded_name);
12534 Free(embedded_name);
12535 }
12536 } else {
12537 // the value is omit
12538 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12539 name, field_name);
12540 }
12541 }
12542 } else {
12543 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12544 }
12545 return str;
12546 }
12547
12548 char *Value::generate_code_init_refd(char *str, const char *name)
12549 {
12550 Value *v = get_value_refd_last();
12551 if (v == this) {
12552 // the referred value is not available at compile time
12553 // the code generation is based on the reference
12554 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
12555 str = TypeConv::gen_conv_code_refd(str, name, v);
12556 } else {
12557 expression_struct expr;
12558 Code::init_expr(&expr);
12559 expr.expr = mputprintf(expr.expr, "%s = ", name);
12560 u.ref.ref->generate_code_const_ref(&expr);
12561 str = Code::merge_free_expr(str, &expr);
12562 }
12563 } else {
12564 // the referred value is available at compile time
12565 // the code generation is based on the referred value
12566 if (v->has_single_expr() &&
12567 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
12568 // simple substitution for in-line values within the same module
12569 str = mputprintf(str, "%s = %s;\n", name,
12570 v->get_single_expr().c_str());
12571 } else {
12572 // use a simple reference to reduce code size
12573 if (needs_init_precede(v)) {
12574 // the referred value must be initialized first
12575 if (!v->is_toplevel() && v->needs_temp_ref()) {
12576 // temporary id should be introduced for the lhs
12577 const string& tmp_id = get_temporary_id();
12578 const char *tmp_id_str = tmp_id.c_str();
12579 str = mputprintf(str, "{\n"
12580 "%s& %s = %s;\n",
12581 v->get_my_governor()->get_genname_value(my_scope).c_str(),
12582 tmp_id_str, v->get_lhs_name().c_str());
12583 str = v->generate_code_init(str, tmp_id_str);
12584 str = mputstr(str, "}\n");
12585 } else {
12586 str = v->generate_code_init(str, v->get_lhs_name().c_str());
12587 }
12588 }
12589 str = mputprintf(str, "%s = %s;\n", name,
12590 v->get_genname_own(my_scope).c_str());
12591 }
12592 }
12593 return str;
12594 }
12595
12596 bool Value::explicit_cast_needed(bool forIsValue)
12597 {
12598 Value *v_last = get_value_refd_last();
12599 if (v_last != this) {
12600 // this is a foldable referenced value
12601 // if the reference points to an imported or compound value the code
12602 // generation will be based on the reference so cast is not needed
12603 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
12604 || !v_last->has_single_expr()) return false;
12605 } else if (v_last->valuetype == V_REFD) {
12606 // this is an unfoldable reference (v_last==this)
12607 // explicit cast is needed only for string element references
12608 if (forIsValue) return false;
12609 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
12610 return t_subrefs && t_subrefs->refers_to_string_element();
12611 }
12612 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
12613 Type *t_governor = v_last->my_governor->get_type_refd_last();
12614 switch (t_governor->get_typetype()) {
12615 case Type::T_NULL:
12616 case Type::T_BOOL:
12617 case Type::T_INT:
12618 case Type::T_INT_A:
12619 case Type::T_REAL:
12620 case Type::T_ENUM_A:
12621 case Type::T_ENUM_T:
12622 case Type::T_VERDICT:
12623 case Type::T_COMPONENT:
12624 // these are mapped to built-in C/C++ types
12625 return true;
12626 case Type::T_SEQ_A:
12627 case Type::T_SEQ_T:
12628 case Type::T_SET_A:
12629 case Type::T_SET_T:
12630 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12631 return t_governor->get_nof_comps() == 0;
12632 case Type::T_SEQOF:
12633 case Type::T_SETOF:
12634 // the C++ equivalent of value {} is ambiguous
12635 // tr926
12636 return true;
12637 case Type::T_FUNCTION:
12638 case Type::T_ALTSTEP:
12639 case Type::T_TESTCASE:
12640 return true;
12641 default:
12642 return false;
12643 }
12644 }
12645
12646 bool Value::has_single_expr()
12647 {
12648 if (get_needs_conversion()) return false;
12649 switch (valuetype) {
12650 case V_EXPR:
12651 return has_single_expr_expr();
12652 case V_CHOICE:
12653 case V_ARRAY:
12654 // a union or array value cannot be represented as an in-line expression
12655 return false;
12656 case V_SEQOF:
12657 case V_SETOF:
12658 // only an empty record/set of value can be represented as an in-line
12659 // expression
12660 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
12661 else return u.val_vs->get_nof_ivs() == 0;
12662 case V_SEQ:
12663 case V_SET: {
12664 // only a value for an empty record/set type can be represented as an
12665 // in-line expression
12666 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
12667 Type *type = my_governor->get_type_refd_last();
12668 return type->get_nof_comps() == 0; }
12669 case V_REFD: {
12670 Value *v_last = get_value_refd_last();
12671 // If the above call hit an error and set_valuetype(V_ERROR),
12672 // then u.ref.ref has been freed. Avoid the segfault.
12673 if (valuetype == V_ERROR)
12674 return false;
12675 if (v_last != this && v_last->has_single_expr() &&
12676 v_last->my_scope->get_scope_mod_gen() ==
12677 my_scope->get_scope_mod_gen()) return true;
12678 else return u.ref.ref->has_single_expr(); }
12679 case V_INVOKE:
12680 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
12681 case V_ERROR:
12682 case V_NAMEDINT:
12683 case V_NAMEDBITS:
12684 case V_UNDEF_LOWERID:
12685 case V_UNDEF_BLOCK:
12686 case V_REFER:
12687 // these values cannot occur during code generation
12688 FATAL_ERROR("Value::has_single_expr()");
12689 case V_INT:
12690 return u.val_Int->is_native_fit();
12691 default:
12692 // other value types (literal values) do not need temporary reference
12693 return true;
12694 }
12695 }
12696
12697 string Value::get_single_expr()
12698 {
12699 switch (valuetype) {
12700 case V_NULL:
12701 return string("ASN_NULL_VALUE");
12702 case V_BOOL:
12703 return string(u.val_bool ? "TRUE" : "FALSE");
12704 case V_INT:
12705 if (u.val_Int->is_native_fit()) { // Be sure.
12706 return u.val_Int->t_str();
12707 } else {
12708 // get_single_expr may be called only if has_single_expr() is true.
12709 // The only exception is V_INT, where get_single_expr may be called
12710 // even if is_native_fit (which is used to implement has_single_expr)
12711 // returns false.
12712 string ret_val('"');
12713 ret_val += u.val_Int->t_str();
12714 ret_val += '"';
12715 return ret_val;
12716 }
12717 case V_REAL:
12718 return Real2code(u.val_Real);
12719 case V_ENUM:
12720 return get_single_expr_enum();
12721 case V_BSTR:
12722 return get_my_scope()->get_scope_mod_gen()
12723 ->add_bitstring_literal(*u.str.val_str);
12724 case V_HSTR:
12725 return get_my_scope()->get_scope_mod_gen()
12726 ->add_hexstring_literal(*u.str.val_str);
12727 case V_OSTR:
12728 return get_my_scope()->get_scope_mod_gen()
12729 ->add_octetstring_literal(*u.str.val_str);
12730 case V_CSTR:
12731 return get_my_scope()->get_scope_mod_gen()
12732 ->add_charstring_literal(*u.str.val_str);
12733 case V_USTR:
12734 if (u.ustr.convert_str) {
12735 set_valuetype(V_CSTR);
12736 return get_my_scope()->get_scope_mod_gen()
12737 ->add_charstring_literal(*u.str.val_str);
12738 } else
12739 return get_my_scope()->get_scope_mod_gen()
12740 ->add_ustring_literal(*u.ustr.val_ustr);
12741 case V_ISO2022STR:
12742 return get_single_expr_iso2022str();
12743 case V_OID:
12744 case V_ROID: {
12745 vector<string> comps;
12746 bool is_constant = get_oid_comps(comps);
12747 size_t nof_comps = comps.size();
12748 string oi_str;
12749 for (size_t i = 0; i < nof_comps; i++) {
12750 if (i > 0) oi_str += ", ";
12751 oi_str += *(comps[i]);
12752 }
12753 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
12754 comps.clear();
12755 if (is_constant) {
12756 // the objid only contains constants
12757 // => create a literal and return its name
12758 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
12759 }
12760 // the objid contains at least one variable
12761 // => append the number of components before the component values in the string and return it
12762 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
12763 case V_SEQOF:
12764 case V_SETOF:
12765 if (u.val_vs->get_nof_vs() > 0)
12766 FATAL_ERROR("Value::get_single_expr()");
12767 return string("NULL_VALUE");
12768 case V_SEQ:
12769 case V_SET:
12770 if (u.val_nvs->get_nof_nvs() > 0)
12771 FATAL_ERROR("Value::get_single_expr()");
12772 return string("NULL_VALUE");
12773 case V_REFD: {
12774 Value *v_last = get_value_refd_last();
12775 if (v_last != this && v_last->has_single_expr() &&
12776 v_last->my_scope->get_scope_mod_gen() ==
12777 my_scope->get_scope_mod_gen()) {
12778 // the reference points to another single value in the same module
12779 return v_last->get_single_expr();
12780 } else {
12781 // convert the reference to a single expression
12782 expression_struct expr;
12783 Code::init_expr(&expr);
12784 u.ref.ref->generate_code_const_ref(&expr);
12785 if (expr.preamble || expr.postamble)
12786 FATAL_ERROR("Value::get_single_expr()");
12787 string ret_val(expr.expr);
12788 Code::free_expr(&expr);
12789 return ret_val;
12790 } }
12791 case V_OMIT:
12792 return string("OMIT_VALUE");
12793 case V_VERDICT:
12794 switch (u.verdict) {
12795 case Verdict_NONE:
12796 return string("NONE");
12797 case Verdict_PASS:
12798 return string("PASS");
12799 case Verdict_INCONC:
12800 return string("INCONC");
12801 case Verdict_FAIL:
12802 return string("FAIL");
12803 case Verdict_ERROR:
12804 return string("ERROR");
12805 default:
12806 FATAL_ERROR("Value::get_single_expr()");
12807 return string();
12808 }
12809 case V_DEFAULT_NULL:
12810 return string("NULL_COMPREF");
12811 case V_FAT_NULL: {
12812 string ret_val('(');
12813 ret_val += my_governor->get_genname_value(my_scope);
12814 ret_val += "::function_pointer)Module_List::get_fat_null()";
12815 return ret_val; }
12816 case V_EXPR:
12817 case V_INVOKE: {
12818 expression_struct expr;
12819 Code::init_expr(&expr);
12820 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
12821 else generate_code_expr_invoke(&expr);
12822 if (expr.preamble || expr.postamble)
12823 FATAL_ERROR("Value::get_single_expr()");
12824 string ret_val(expr.expr);
12825 Code::free_expr(&expr);
12826 return ret_val; }
12827 case V_MACRO:
12828 switch (u.macro) {
12829 case MACRO_TESTCASEID:
12830 return string("TTCN_Runtime::get_testcase_id_macro()");
12831 default:
12832 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
12833 return string();
12834 }
12835 case V_FUNCTION:
12836 case V_ALTSTEP:
12837 case V_TESTCASE:
12838 return get_single_expr_fat();
12839 default:
12840 FATAL_ERROR("Value::get_single_expr()");
12841 return string();
12842 }
12843 }
12844
12845 bool Value::has_single_expr_expr()
12846 {
12847 switch (u.expr.v_optype) {
12848 case OPTYPE_RND: // -
12849 case OPTYPE_COMP_NULL:
12850 case OPTYPE_COMP_MTC:
12851 case OPTYPE_COMP_SYSTEM:
12852 case OPTYPE_COMP_SELF:
12853 case OPTYPE_COMP_RUNNING_ANY:
12854 case OPTYPE_COMP_RUNNING_ALL:
12855 case OPTYPE_COMP_ALIVE_ANY:
12856 case OPTYPE_COMP_ALIVE_ALL:
12857 case OPTYPE_TMR_RUNNING_ANY:
12858 case OPTYPE_GETVERDICT:
12859 case OPTYPE_TESTCASENAME:
12860 return true;
12861 case OPTYPE_ENCODE:
12862 case OPTYPE_DECODE:
12863 case OPTYPE_ISBOUND:
12864 case OPTYPE_ISPRESENT:
12865 case OPTYPE_TTCN2STRING:
12866 return false;
12867 case OPTYPE_UNARYPLUS: // v1
12868 case OPTYPE_UNARYMINUS:
12869 case OPTYPE_NOT:
12870 case OPTYPE_NOT4B:
12871 case OPTYPE_BIT2HEX:
12872 case OPTYPE_BIT2INT:
12873 case OPTYPE_BIT2OCT:
12874 case OPTYPE_BIT2STR:
12875 case OPTYPE_CHAR2INT:
12876 case OPTYPE_CHAR2OCT:
12877 case OPTYPE_FLOAT2INT:
12878 case OPTYPE_FLOAT2STR:
12879 case OPTYPE_HEX2BIT:
12880 case OPTYPE_HEX2INT:
12881 case OPTYPE_HEX2OCT:
12882 case OPTYPE_HEX2STR:
12883 case OPTYPE_INT2CHAR:
12884 case OPTYPE_INT2FLOAT:
12885 case OPTYPE_INT2STR:
12886 case OPTYPE_INT2UNICHAR:
12887 case OPTYPE_OCT2BIT:
12888 case OPTYPE_OCT2CHAR:
12889 case OPTYPE_OCT2HEX:
12890 case OPTYPE_OCT2INT:
12891 case OPTYPE_OCT2STR:
12892 case OPTYPE_STR2BIT:
12893 case OPTYPE_STR2FLOAT:
12894 case OPTYPE_STR2HEX:
12895 case OPTYPE_STR2INT:
12896 case OPTYPE_STR2OCT:
12897 case OPTYPE_UNICHAR2INT:
12898 case OPTYPE_UNICHAR2CHAR:
12899 case OPTYPE_ENUM2INT:
12900 case OPTYPE_RNDWITHVAL:
12901 case OPTYPE_ISCHOSEN_V: // v1 i2
12902 case OPTYPE_COMP_RUNNING:
12903 case OPTYPE_COMP_ALIVE:
12904 case OPTYPE_GET_STRINGENCODING:
12905 case OPTYPE_REMOVE_BOM:
12906 case OPTYPE_DECODE_BASE64:
12907 return u.expr.v1->has_single_expr();
12908 case OPTYPE_ISCHOSEN_T: // t1 i2
12909 return u.expr.t1->has_single_expr();
12910 case OPTYPE_ADD: // v1 v2
12911 case OPTYPE_SUBTRACT:
12912 case OPTYPE_MULTIPLY:
12913 case OPTYPE_DIVIDE:
12914 case OPTYPE_MOD:
12915 case OPTYPE_REM:
12916 case OPTYPE_CONCAT:
12917 case OPTYPE_EQ:
12918 case OPTYPE_LT:
12919 case OPTYPE_GT:
12920 case OPTYPE_NE:
12921 case OPTYPE_GE:
12922 case OPTYPE_LE:
12923 case OPTYPE_XOR:
12924 case OPTYPE_AND4B:
12925 case OPTYPE_OR4B:
12926 case OPTYPE_XOR4B:
12927 case OPTYPE_SHL:
12928 case OPTYPE_SHR:
12929 case OPTYPE_ROTL:
12930 case OPTYPE_ROTR:
12931 case OPTYPE_INT2BIT:
12932 case OPTYPE_INT2HEX:
12933 case OPTYPE_INT2OCT:
12934 return u.expr.v1->has_single_expr() &&
12935 u.expr.v2->has_single_expr();
12936 case OPTYPE_UNICHAR2OCT:
12937 case OPTYPE_OCT2UNICHAR:
12938 case OPTYPE_ENCODE_BASE64:
12939 return u.expr.v1->has_single_expr() &&
12940 (!u.expr.v2 || u.expr.v2->has_single_expr());
12941 case OPTYPE_AND:
12942 case OPTYPE_OR:
12943 return u.expr.v1->has_single_expr() &&
12944 u.expr.v2->has_single_expr() &&
12945 !u.expr.v2->needs_short_circuit();
12946 case OPTYPE_SUBSTR:
12947 return u.expr.ti1->has_single_expr() &&
12948 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
12949 case OPTYPE_REGEXP:
12950 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
12951 u.expr.v3->has_single_expr();
12952 case OPTYPE_DECOMP: // v1 v2 v3
12953 return u.expr.v1->has_single_expr() &&
12954 u.expr.v2->has_single_expr() &&
12955 u.expr.v3->has_single_expr();
12956 case OPTYPE_REPLACE:
12957 return u.expr.ti1->has_single_expr() &&
12958 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
12959 u.expr.ti4->has_single_expr();
12960 case OPTYPE_ISVALUE: // ti1
12961 case OPTYPE_LENGTHOF: // ti1
12962 case OPTYPE_SIZEOF: // ti1
12963 case OPTYPE_VALUEOF: // ti1
12964 return u.expr.ti1->has_single_expr();
12965 case OPTYPE_LOG2STR:
12966 return u.expr.logargs->has_single_expr();
12967 case OPTYPE_MATCH: // v1 t2
12968 return u.expr.v1->has_single_expr() &&
12969 u.expr.t2->has_single_expr();
12970 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
12971 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
12972 (!u.expr.v3 || u.expr.v3->has_single_expr());
12973 case OPTYPE_TMR_READ: // r1
12974 case OPTYPE_TMR_RUNNING:
12975 case OPTYPE_ACTIVATE:
12976 return u.expr.r1->has_single_expr();
12977 case OPTYPE_EXECUTE: // r1 [v2]
12978 return u.expr.r1->has_single_expr() &&
12979 (!u.expr.v2 || u.expr.v2->has_single_expr());
12980 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
12981 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
12982 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
12983 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
12984 (!u.expr.v3 || u.expr.v3->has_single_expr());
12985 default:
12986 FATAL_ERROR("Value::has_single_expr_expr()");
12987 } // switch
12988 }
12989
12990 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
12991 {
12992 if (!v->has_single_expr()) return false;
12993 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
12994 if (!ap_list->get_par(i)->has_single_expr()) return false;
12995 return true;
12996 }
12997
12998 string Value::get_single_expr_enum()
12999 {
13000 string ret_val(my_governor->get_genname_value(my_scope));
13001 ret_val += "::";
13002 ret_val += u.val_id->get_name();
13003 return ret_val;
13004 }
13005
13006 string Value::get_single_expr_iso2022str()
13007 {
13008 string ret_val;
13009 Type *type = get_my_governor()->get_type_refd_last();
13010 switch (type->get_typetype()) {
13011 case Type::T_TELETEXSTRING:
13012 ret_val += "TTCN_ISO2022_2_TeletexString";
13013 break;
13014 case Type::T_VIDEOTEXSTRING:
13015 ret_val += "TTCN_ISO2022_2_VideotexString";
13016 break;
13017 case Type::T_GRAPHICSTRING:
13018 case Type::T_OBJECTDESCRIPTOR:
13019 ret_val += "TTCN_ISO2022_2_GraphicString";
13020 break;
13021 case Type::T_GENERALSTRING:
13022 ret_val += "TTCN_ISO2022_2_GeneralString";
13023 break;
13024 default:
13025 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13026 } // switch
13027 ret_val += '(';
13028 string *ostr = char2oct(*u.str.val_str);
13029 ret_val += get_my_scope()->get_scope_mod_gen()
13030 ->add_octetstring_literal(*ostr);
13031 delete ostr;
13032 ret_val += ')';
13033 return ret_val;
13034 }
13035
13036 string Value::get_single_expr_fat()
13037 {
13038 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13039 // the ampersand operator is not really necessary to obtain the function
13040 // pointer, but some older versions of GCC cannot instantiate the
13041 // appropriate operator=() member of class OPTIONAL when necessary
13042 // if only the function name is given
13043 string ret_val('&');
13044 switch (valuetype) {
13045 case V_FUNCTION:
13046 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13047 break;
13048 case V_ALTSTEP:
13049 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13050 ret_val += "_instance";
13051 break;
13052 case V_TESTCASE:
13053 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13054 break;
13055 default:
13056 FATAL_ERROR("Value::get_single_expr_fat()");
13057 }
13058 return ret_val;
13059 }
13060
13061 bool Value::is_compound()
13062 {
13063 switch (valuetype) {
13064 case V_CHOICE:
13065 case V_SEQOF:
13066 case V_SETOF:
13067 case V_ARRAY:
13068 case V_SEQ:
13069 case V_SET:
13070 return true;
13071 default:
13072 return false;
13073 }
13074 }
13075
13076 bool Value::needs_temp_ref()
13077 {
13078 switch (valuetype) {
13079 case V_SEQOF:
13080 case V_SETOF:
13081 if (!is_indexed()) {
13082 // Temporary reference is needed if the value has at least one real
13083 // element (i.e. it is not empty or contains only not used symbols).
13084 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13085 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13086 }
13087 } else {
13088 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13089 if (u.val_vs->get_iv_byIndex(i)->get_value()
13090 ->valuetype != V_NOTUSED)
13091 return true;
13092 }
13093 }
13094 return false;
13095 case V_ARRAY: {
13096 size_t nof_real_vs = 0;
13097 if (!is_indexed()) {
13098 // Temporary reference is needed if the array value has at least two
13099 // real elements (excluding not used symbols).
13100 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13101 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13102 nof_real_vs++;
13103 if (nof_real_vs > 1) return true;
13104 }
13105 }
13106 } else {
13107 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13108 if (u.val_vs->get_iv_byIndex(i)->get_value()
13109 ->valuetype != V_NOTUSED) {
13110 nof_real_vs++;
13111 if (nof_real_vs > 1) return true;
13112 }
13113 }
13114 }
13115 return false; }
13116 case V_SEQ:
13117 case V_SET:
13118 if (is_asn1()) {
13119 // it depends on the type since fields with omit or default value
13120 // may not be present
13121 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13122 } else {
13123 // incomplete values are allowed in TTCN-3
13124 // we should check the number of value components
13125 return u.val_nvs->get_nof_nvs() > 1;
13126 }
13127 case V_ERROR:
13128 case V_NAMEDINT:
13129 case V_NAMEDBITS:
13130 case V_UNDEF_LOWERID:
13131 case V_UNDEF_BLOCK:
13132 case V_TTCN3_NULL:
13133 // these values cannot occur during code generation
13134 FATAL_ERROR("Value::needs_temp_ref()");
13135 case V_INT:
13136 return !u.val_Int->is_native();
13137 default:
13138 // other value types (literal values) do not need temporary reference
13139 return false;
13140 }
13141 }
13142
13143 bool Value::needs_short_circuit()
13144 {
13145 switch (valuetype) {
13146 case V_BOOL:
13147 return false;
13148 case V_REFD:
13149 // examined below
13150 break;
13151 case V_EXPR:
13152 case V_INVOKE:
13153 // sub-expressions should be evaluated only if necessary
13154 return true;
13155 default:
13156 FATAL_ERROR("Value::needs_short_circuit()");
13157 }
13158 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13159 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13160 switch (t_ass->get_asstype()) {
13161 case Assignment::A_FUNCTION_RVAL:
13162 case Assignment::A_EXT_FUNCTION_RVAL:
13163 // avoid unnecessary call of a function
13164 return true;
13165 case Assignment::A_CONST:
13166 case Assignment::A_EXT_CONST:
13167 case Assignment::A_MODULEPAR:
13168 case Assignment::A_VAR:
13169 case Assignment::A_PAR_VAL_IN:
13170 case Assignment::A_PAR_VAL_OUT:
13171 case Assignment::A_PAR_VAL_INOUT:
13172 // depends on field/array sub-references, which is examined below
13173 break;
13174 default:
13175 FATAL_ERROR("Value::needs_short_circuit()");
13176 }
13177 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13178 if (t_subrefs) {
13179 // the evaluation of the reference does not have side effects
13180 // (i.e. false shall be returned) only if all sub-references point to
13181 // mandatory fields of record/set types
13182 Type *t_type = t_ass->get_Type();
13183 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13184 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13185 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13186 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13187 if (t_cf->get_is_optional()) return true;
13188 t_type = t_cf->get_type();
13189 } else return true;
13190 }
13191 }
13192 return false;
13193 }
13194
13195 void Value::dump(unsigned level) const
13196 {
13197 switch (valuetype) {
13198 case V_ERROR:
13199 case V_NULL:
13200 case V_BOOL:
13201 case V_INT:
13202 case V_NAMEDINT:
13203 case V_NAMEDBITS:
13204 case V_REAL:
13205 case V_ENUM:
13206 case V_BSTR:
13207 case V_HSTR:
13208 case V_OSTR:
13209 case V_CSTR:
13210 case V_ISO2022STR:
13211 case V_OID:
13212 case V_ROID:
13213 case V_CHOICE:
13214 case V_SEQOF:
13215 case V_SETOF:
13216 case V_ARRAY:
13217 case V_SEQ:
13218 case V_SET:
13219 case V_OMIT:
13220 case V_VERDICT:
13221 case V_DEFAULT_NULL:
13222 case V_FAT_NULL:
13223 case V_EXPR:
13224 case V_MACRO:
13225 case V_NOTUSED:
13226 case V_FUNCTION:
13227 case V_ALTSTEP:
13228 case V_TESTCASE:
13229 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13230 break;
13231 case V_REFD:
13232 case V_REFER:
13233 DEBUG(level, "Value: reference");
13234 u.ref.ref->dump(level + 1);
13235 break;
13236 case V_UNDEF_LOWERID:
13237 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13238 break;
13239 case V_UNDEF_BLOCK:
13240 DEBUG(level, "Value: {block}");
13241 break;
13242 case V_TTCN3_NULL:
13243 DEBUG(level, "Value: null");
13244 break;
13245 case V_INVOKE:
13246 DEBUG(level, "Value: invoke");
13247 u.invoke.v->dump(level + 1);
13248 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13249 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13250 break;
13251 default:
13252 DEBUG(level, "Value: unknown type: %d", valuetype);
13253 } // switch
13254 }
13255
13256 void Value::add_string_element(size_t index, Value *v_element,
13257 map<size_t, Value>*& string_elements)
13258 {
13259 v_element->set_my_scope(get_my_scope());
13260 v_element->set_my_governor(get_my_governor());
13261 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13262 v_element->set_location(*this);
13263 if (!string_elements) string_elements = new map<size_t, Value>;
13264 string_elements->add(index, v_element);
13265 }
13266
13267 ///////////////////////////////////////////////////////////////////////////////
13268 // class LazyParamData
13269
13270 int LazyParamData::depth = 0;
13271 bool LazyParamData::used_as_lvalue = false;
13272 vector<string>* LazyParamData::type_vec = NULL;
13273 vector<string>* LazyParamData::refd_vec = NULL;
13274
13275 void LazyParamData::init(bool p_used_as_lvalue) {
13276 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13277 if (depth==0) {
13278 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13279 used_as_lvalue = p_used_as_lvalue;
13280 type_vec = new vector<string>;
13281 refd_vec = new vector<string>;
13282 }
13283 depth++;
13284 }
13285
13286 void LazyParamData::clean() {
13287 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13288 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13289 if (depth==1) {
13290 // type_vec
13291 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13292 type_vec->clear();
13293 delete type_vec;
13294 type_vec = NULL;
13295 // refd_vec
13296 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13297 refd_vec->clear();
13298 delete refd_vec;
13299 refd_vec = NULL;
13300 }
13301 depth--;
13302 }
13303
13304 bool LazyParamData::in_lazy() {
13305 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13306 return depth>0;
13307 }
13308
13309 // returns a temporary id instead of the C++ reference to a definition
13310 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13311 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13312 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13313 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13314 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13315 // store the type of the assignment
13316 string* type_str = new string;
13317 switch (ass->get_asstype()) {
13318 case Assignment::A_MODULEPAR_TEMP:
13319 case Assignment::A_TEMPLATE:
13320 case Assignment::A_VAR_TEMPLATE:
13321 case Assignment::A_PAR_TEMPL_IN:
13322 case Assignment::A_PAR_TEMPL_OUT:
13323 case Assignment::A_PAR_TEMPL_INOUT:
13324 *type_str = ass->get_Type()->get_genname_template(scope);
13325 break;
13326 default:
13327 *type_str = ass->get_Type()->get_genname_value(scope);
13328 }
13329 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13330 bool refd_ass_is_lazy_fpar = false;
13331 switch (ass->get_asstype()) {
13332 case Assignment::A_PAR_VAL:
13333 case Assignment::A_PAR_VAL_IN:
13334 case Assignment::A_PAR_TEMPL_IN:
13335 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13336 if (refd_ass_is_lazy_fpar) {
13337 *type_str = string("Lazy_Param<") + *type_str + string(">");
13338 }
13339 break;
13340 default:
13341 break;
13342 }
13343 // add the "const" part if the referenced assignment is a constant thing
13344 if (!refd_ass_is_lazy_fpar) {
13345 switch (ass->get_asstype()) {
13346 case Assignment::A_CONST:
13347 case Assignment::A_OC:
13348 case Assignment::A_OBJECT:
13349 case Assignment::A_OS:
13350 case Assignment::A_VS:
13351 case Assignment::A_EXT_CONST:
13352 case Assignment::A_MODULEPAR:
13353 case Assignment::A_MODULEPAR_TEMP:
13354 case Assignment::A_TEMPLATE:
13355 case Assignment::A_PAR_VAL:
13356 case Assignment::A_PAR_VAL_IN:
13357 case Assignment::A_PAR_TEMPL_IN:
13358 *type_str = string("const ") + *type_str;
13359 break;
13360 default:
13361 // nothing to do
13362 break;
13363 }
13364 }
13365 //
13366 type_vec->add(type_str);
13367 // store the C++ reference string
13368 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
13369 if (refd_ass_is_lazy_fpar) {
13370 Type* refd_ass_type = ass->get_Type();
13371 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);
13372 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13373 } else {
13374 return get_member_name(refd_vec->size()-1);
13375 }
13376 }
13377
13378 string LazyParamData::get_member_name(size_t idx) {
13379 return string("lpm_") + Int2string(idx);
13380 }
13381
13382 string LazyParamData::get_constr_param_name(size_t idx) {
13383 return string("lpp_") + Int2string(idx);
13384 }
13385
13386 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
13387 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13388 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
13389 const string& tmp_id = val->get_temporary_id();
13390 const char *tmp_id_str = tmp_id.c_str();
13391 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13392 val->get_my_governor()->get_genname_value(my_scope).c_str(),
13393 tmp_id_str);
13394 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13395 tmp_id_str, val);
13396 expr->expr = mputstr(expr->expr, tmp_id_str);
13397 } else {
13398 val->generate_code_expr(expr);
13399 }
13400 }
13401
13402 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
13403 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13404 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
13405 const string& tmp_id = temp->get_Template()->get_temporary_id();
13406 const char *tmp_id_str = tmp_id.c_str();
13407 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13408 temp->get_Template()->get_my_governor()
13409 ->get_genname_template(my_scope).c_str(), tmp_id_str);
13410 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13411 tmp_id_str, temp->get_Template());
13412 // Not incorporated into gen_conv_code() yet.
13413 if (gen_restriction_check != TR_NONE)
13414 expr->preamble = Template::generate_restriction_check_code(
13415 expr->preamble, tmp_id_str, gen_restriction_check);
13416 expr->expr = mputstr(expr->expr, tmp_id_str);
13417 } else temp->generate_code(expr, gen_restriction_check);
13418 }
13419
13420 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
13421 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13422 if (depth>1) {
13423 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13424 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13425 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13426 expression_struct value_expr;
13427 Code::init_expr(&value_expr);
13428 generate_code_for_value(&value_expr, value, scope);
13429 // the id of the instance of Lazy_Param which will be used as the actual parameter
13430 const string& lazy_param_id = value->get_temporary_id();
13431 if (value_expr.preamble) {
13432 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
13433 }
13434 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13435 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13436 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
13437 Code::free_expr(&value_expr);
13438 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13439 return;
13440 }
13441 // only if the formal parameter is *not* used as lvalue
13442 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
13443 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
13444 if (refd_ass) {
13445 bool refd_ass_is_lazy_fpar = false;
13446 switch (refd_ass->get_asstype()) {
13447 case Assignment::A_PAR_VAL:
13448 case Assignment::A_PAR_VAL_IN:
13449 case Assignment::A_PAR_TEMPL_IN:
13450 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13451 break;
13452 default:
13453 break;
13454 }
13455 if (refd_ass_is_lazy_fpar) {
13456 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13457 return;
13458 }
13459 }
13460 }
13461 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13462 expression_struct value_expr;
13463 Code::init_expr(&value_expr);
13464 generate_code_for_value(&value_expr, value, scope);
13465 // the id of the instance of Lazy_Param which will be used as the actual parameter
13466 string lazy_param_id = value->get_temporary_id();
13467 string type_name = value->get_my_governor()->get_genname_value(scope);
13468 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
13469 }
13470
13471 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
13472 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13473 if (depth>1) {
13474 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13475 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13476 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13477 expression_struct tmpl_expr;
13478 Code::init_expr(&tmpl_expr);
13479 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13480 // the id of the instance of Lazy_Param which will be used as the actual parameter
13481 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
13482 if (tmpl_expr.preamble) {
13483 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
13484 }
13485 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13486 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13487 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
13488 Code::free_expr(&tmpl_expr);
13489 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13490 return;
13491 }
13492 // only if the formal parameter is *not* used as lvalue
13493 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
13494 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
13495 if (refd_ass) {
13496 bool refd_ass_is_lazy_fpar = false;
13497 switch (refd_ass->get_asstype()) {
13498 case Assignment::A_PAR_VAL:
13499 case Assignment::A_PAR_VAL_IN:
13500 case Assignment::A_PAR_TEMPL_IN:
13501 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13502 break;
13503 default:
13504 break;
13505 }
13506 if (refd_ass_is_lazy_fpar) {
13507 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13508 return;
13509 }
13510 }
13511 }
13512 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13513 expression_struct tmpl_expr;
13514 Code::init_expr(&tmpl_expr);
13515 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13516 // the id of the instance of Lazy_Param which will be used as the actual parameter
13517 string lazy_param_id = temp->get_Template()->get_temporary_id();
13518 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
13519 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
13520 }
13521
13522 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
13523 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
13524 if (type_vec->size()>0) {
13525 // private members of the local class will be const references to the objects referenced by the expression
13526 for (size_t i=0; i<type_vec->size(); i++) {
13527 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
13528 }
13529 expr->preamble = mputstr(expr->preamble, "public:\n");
13530 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
13531 for (size_t i=0; i<type_vec->size(); i++) {
13532 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13533 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
13534 }
13535 expr->preamble = mputstr(expr->preamble, "): ");
13536 for (size_t i=0; i<type_vec->size(); i++) {
13537 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13538 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
13539 }
13540 expr->preamble = mputstr(expr->preamble, " {}\n");
13541 expr->preamble = mputstr(expr->preamble, "private:\n");
13542 }
13543 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
13544 // use the temporary expr structure to fill the body of the eval_expr() function
13545 if (param_expr.preamble) {
13546 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
13547 }
13548 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
13549 if (param_expr.postamble) {
13550 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
13551 }
13552 Code::free_expr(&param_expr);
13553 expr->preamble = mputstr(expr->preamble, "}\n"
13554 "};\n" // end of local class definition
13555 );
13556 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
13557 if (type_vec->size()>0) {
13558 expr->preamble = mputc(expr->preamble, '(');
13559 // paramteres of the constructor are references to the objects used in the expression
13560 for (size_t i=0; i<refd_vec->size(); i++) {
13561 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13562 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
13563 }
13564 expr->preamble = mputc(expr->preamble, ')');
13565 }
13566 expr->preamble = mputstr(expr->preamble, ";\n");
13567 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13568 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
13569 }
13570
13571 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
13572 expression_struct ref_expr;
13573 Code::init_expr(&ref_expr);
13574 ref->generate_code(&ref_expr);
13575 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
13576 if (ref_expr.preamble) {
13577 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
13578 }
13579 Assignment* ass = ref->get_refd_assignment();
13580 // determine C++ type of the assignment
13581 string type_str;
13582 switch (ass->get_asstype()) {
13583 case Assignment::A_MODULEPAR_TEMP:
13584 case Assignment::A_TEMPLATE:
13585 case Assignment::A_VAR_TEMPLATE:
13586 case Assignment::A_PAR_TEMPL_IN:
13587 case Assignment::A_PAR_TEMPL_OUT:
13588 case Assignment::A_PAR_TEMPL_INOUT:
13589 type_str = ass->get_Type()->get_genname_template(scope);
13590 break;
13591 default:
13592 type_str = ass->get_Type()->get_genname_value(scope);
13593 }
13594 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13595 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
13596 if (ref_expr.postamble) {
13597 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
13598 }
13599 Code::free_expr(&ref_expr);
13600 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13601 }
13602
13603 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
13604 const string& lazy_param_id = value->get_temporary_id();
13605 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13606 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13607 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
13608 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13609 }
13610
13611 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
13612 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
13613 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13614 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13615 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
13616 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13617 }
13618
13619 } // namespace Common
This page took 0.506899 seconds and 6 git commands to generate.