Titan Core Initial Contribution
[deliverable/titan.core.git] / compiler2 / Value.cc
CommitLineData
970ed795
EL
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
38namespace 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, false);
3182 else return 0;
3183 case OPTYPE_COMP_SYSTEM:
3184 if (my_scope) return my_scope->get_mtc_system_comptype(true, false);
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 Type* Value::get_component_governor()
3239 {
3240 if (V_EXPR == valuetype && OPTYPE_COMP_MTC == u.expr.v_optype) {
3241 if (my_scope) {
3242 return my_scope->get_mtc_system_comptype(false, true);
3243 } else {
3244 return 0;
3245 }
3246 }
3247 return get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
3248 }
3249
3250 const char* Value::get_opname() const
3251 {
3252 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3253 switch(u.expr.v_optype) {
3254 case OPTYPE_RND: // -
3255 return "rnd()";
3256 case OPTYPE_COMP_NULL:
3257 return "(component) null";
3258 case OPTYPE_COMP_MTC:
3259 return "mtc";
3260 case OPTYPE_COMP_SYSTEM:
3261 return "system";
3262 case OPTYPE_COMP_SELF:
3263 return "self";
3264 case OPTYPE_COMP_RUNNING_ANY:
3265 return "any component.running";
3266 case OPTYPE_COMP_RUNNING_ALL:
3267 return "all component.running";
3268 case OPTYPE_COMP_ALIVE_ANY:
3269 return "any component.alive";
3270 case OPTYPE_COMP_ALIVE_ALL:
3271 return "all component.alive";
3272 case OPTYPE_TMR_RUNNING_ANY:
3273 return "any timer.running";
3274 case OPTYPE_GETVERDICT:
3275 return "getverdict()";
3276 case OPTYPE_TESTCASENAME:
3277 return "testcasename()";
3278 case OPTYPE_UNARYPLUS: // v1
3279 return "unary +";
3280 case OPTYPE_UNARYMINUS:
3281 return "unary -";
3282 case OPTYPE_NOT:
3283 return "not";
3284 case OPTYPE_NOT4B:
3285 return "not4b";
3286 case OPTYPE_BIT2HEX:
3287 return "bit2hex()";
3288 case OPTYPE_BIT2INT:
3289 return "bit2int()";
3290 case OPTYPE_BIT2OCT:
3291 return "bit2oct()";
3292 case OPTYPE_BIT2STR:
3293 return "bit2str()";
3294 case OPTYPE_CHAR2INT:
3295 return "char2int()";
3296 case OPTYPE_CHAR2OCT:
3297 return "char2oct()";
3298 case OPTYPE_FLOAT2INT:
3299 return "float2int()";
3300 case OPTYPE_FLOAT2STR:
3301 return "float2str()";
3302 case OPTYPE_HEX2BIT:
3303 return "hex2bit()";
3304 case OPTYPE_HEX2INT:
3305 return "hex2int()";
3306 case OPTYPE_HEX2OCT:
3307 return "hex2oct()";
3308 case OPTYPE_HEX2STR:
3309 return "hex2str()";
3310 case OPTYPE_INT2CHAR:
3311 return "int2char()";
3312 case OPTYPE_INT2FLOAT:
3313 return "int2float()";
3314 case OPTYPE_INT2STR:
3315 return "int2str()";
3316 case OPTYPE_INT2UNICHAR:
3317 return "int2unichar()";
3318 case OPTYPE_OCT2BIT:
3319 return "oct2bit()";
3320 case OPTYPE_OCT2CHAR:
3321 return "oct2char()";
3322 case OPTYPE_OCT2HEX:
3323 return "oct2hex()";
3324 case OPTYPE_OCT2INT:
3325 return "oct2int()";
3326 case OPTYPE_OCT2STR:
3327 return "oct2str()";
3328 case OPTYPE_STR2BIT:
3329 return "str2bit()";
3330 case OPTYPE_STR2FLOAT:
3331 return "str2float()";
3332 case OPTYPE_STR2HEX:
3333 return "str2hex()";
3334 case OPTYPE_STR2INT:
3335 return "str2int()";
3336 case OPTYPE_STR2OCT:
3337 return "str2oct()";
3338 case OPTYPE_UNICHAR2INT:
3339 return "unichar2int()";
3340 case OPTYPE_UNICHAR2CHAR:
3341 return "unichar2char()";
3342 case OPTYPE_UNICHAR2OCT:
3343 return "unichar2oct()";
3344 case OPTYPE_ENUM2INT:
3345 return "enum2int()";
3346 case OPTYPE_LENGTHOF:
3347 return "lengthof()";
3348 case OPTYPE_SIZEOF:
3349 return "sizeof()";
3350 case OPTYPE_RNDWITHVAL:
3351 return "rnd (seed)";
3352 case OPTYPE_ENCODE:
3353 return "encvalue()";
3354 case OPTYPE_DECODE:
3355 return "decvalue()";
3356 case OPTYPE_GET_STRINGENCODING:
3357 return "get_stringencoding()";
3358 case OPTYPE_REMOVE_BOM:
3359 return "remove_bom()";
3360 case OPTYPE_ENCODE_BASE64:
3361 return "encode_base64()";
3362 case OPTYPE_DECODE_BASE64:
3363 return "decode_base64()";
3364 case OPTYPE_ADD: // v1 v2
3365 return "+";
3366 case OPTYPE_SUBTRACT:
3367 return "-";
3368 case OPTYPE_MULTIPLY:
3369 return "*";
3370 case OPTYPE_DIVIDE:
3371 return "/";
3372 case OPTYPE_MOD:
3373 return "mod";
3374 case OPTYPE_REM:
3375 return "rem";
3376 case OPTYPE_CONCAT:
3377 return "&";
3378 case OPTYPE_EQ:
3379 return "==";
3380 case OPTYPE_LT:
3381 return "<";
3382 case OPTYPE_GT:
3383 return ">";
3384 case OPTYPE_NE:
3385 return "!=";
3386 case OPTYPE_GE:
3387 return ">=";
3388 case OPTYPE_LE:
3389 return "<=";
3390 case OPTYPE_AND:
3391 return "and";
3392 case OPTYPE_OR:
3393 return "or";
3394 case OPTYPE_XOR:
3395 return "xor";
3396 case OPTYPE_AND4B:
3397 return "and4b";
3398 case OPTYPE_OR4B:
3399 return "or4b";
3400 case OPTYPE_XOR4B:
3401 return "xor4b";
3402 case OPTYPE_SHL:
3403 return "<<";
3404 case OPTYPE_SHR:
3405 return ">>";
3406 case OPTYPE_ROTL:
3407 return "<@";
3408 case OPTYPE_ROTR:
3409 return "@>";
3410 case OPTYPE_INT2BIT:
3411 return "int2bit()";
3412 case OPTYPE_INT2HEX:
3413 return "int2hex()";
3414 case OPTYPE_INT2OCT:
3415 return "int2oct()";
3416 case OPTYPE_OCT2UNICHAR:
3417 return "oct2unichar()";
3418 case OPTYPE_SUBSTR:
3419 return "substr()";
3420 case OPTYPE_REGEXP:
3421 return "regexp()";
3422 case OPTYPE_DECOMP:
3423 return "decomp()";
3424 case OPTYPE_REPLACE:
3425 return "replace()";
3426 case OPTYPE_VALUEOF: // t1
3427 return "valueof()";
3428 case OPTYPE_UNDEF_RUNNING:
3429 return "<timer or component> running";
3430 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3431 return "create()";
3432 case OPTYPE_COMP_RUNNING: // v1
3433 return "component running";
3434 case OPTYPE_COMP_ALIVE: // v1
3435 return "alive";
3436 case OPTYPE_TMR_READ:
3437 return "timer read";
3438 case OPTYPE_TMR_RUNNING:
3439 return "timer running";
3440 case OPTYPE_ACTIVATE:
3441 return "activate()";
3442 case OPTYPE_ACTIVATE_REFD:
3443 return "activate()";
3444 case OPTYPE_EXECUTE: // r1 [v2]
3445 case OPTYPE_EXECUTE_REFD:
3446 return "execute()";
3447 case OPTYPE_MATCH: // v1 t2
3448 return "match()";
3449 case OPTYPE_ISPRESENT:
3450 return "ispresent()";
3451 case OPTYPE_ISCHOSEN:
3452 case OPTYPE_ISCHOSEN_V:
3453 case OPTYPE_ISCHOSEN_T:
3454 return "ischosen()";
3455 case OPTYPE_ISVALUE:
3456 return "isvalue()";
3457 case OPTYPE_ISBOUND:
3458 return "isbound()";
3459 case OPTYPE_LOG2STR:
3460 return "log2str()";
3461 case OPTYPE_TTCN2STRING:
3462 return "ttcn2string()";
3463 default:
3464 FATAL_ERROR("Value::get_opname()");
3465 } // switch
3466 }
3467
3468 void Value::chk_expr_ref_ischosen()
3469 {
3470 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3471 Ttcn::Ref_base *tmpref=u.expr.r1;
3472 Assignment *ass=tmpref->get_refd_assignment();
3473 if (!ass) {
3474 set_valuetype(V_ERROR);
3475 return;
3476 }
3477 // Now we know whether the argument of ischosen() is a value or template.
3478 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3479 // or template (OPTYPE_ISCHOSEN_T).
3480 switch (ass->get_asstype()) {
3481 case Assignment::A_CONST:
3482 case Assignment::A_EXT_CONST:
3483 case Assignment::A_MODULEPAR:
3484 case Assignment::A_VAR:
3485 case Assignment::A_PAR_VAL_IN:
3486 case Assignment::A_PAR_VAL_OUT:
3487 case Assignment::A_PAR_VAL_INOUT:
3488 u.expr.v1=new Value(V_REFD, tmpref);
3489 u.expr.v1->set_location(*tmpref);
3490 u.expr.v1->set_my_scope(get_my_scope());
3491 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3492 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3493 break;
3494 case Assignment::A_MODULEPAR_TEMP:
3495 case Assignment::A_TEMPLATE:
3496 case Assignment::A_VAR_TEMPLATE:
3497 case Assignment::A_PAR_TEMPL_IN:
3498 case Assignment::A_PAR_TEMPL_OUT:
3499 case Assignment::A_PAR_TEMPL_INOUT:
3500 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3501 u.expr.t1->set_location(*tmpref);
3502 u.expr.t1->set_my_scope(get_my_scope());
3503 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3504 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3505 break;
3506 default:
3507 tmpref->error("Reference to a value or template was expected instead of "
3508 "%s", ass->get_description().c_str());
3509 set_valuetype(V_ERROR);
3510 break;
3511 } // switch
3512 }
3513
3514 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3515 Type::expected_value_t exp_val)
3516 {
3517 v->set_lowerid_to_ref(); // can only be reference to enum
3518 Type *t = v->get_expr_governor(exp_val);
3519 if (v->valuetype==V_ERROR) return;
3520 if (!t) {
3521 v->error("Please use reference to an enumerated value as the operand of "
3522 "operation `%s'", get_opname());
3523 set_valuetype(V_ERROR);
3524 return;
3525 }
3526 t = t->get_type_refd_last();
3527 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3528 v->error("The operand of operation `%s' should be enumerated value", opname);
3529 set_valuetype(V_ERROR);
3530 }
3531 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3532 v->error("The operand of operation `%s' cannot be omit", opname);
3533 set_valuetype(V_ERROR);
3534 }
3535 }
3536
3537 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3538 const char *opnum,
3539 const char *opname,
3540 const Location *loc)
3541 {
3542 if(tt==Type::T_BOOL) return;
3543 if(tt!=Type::T_ERROR)
3544 loc->error("%s operand of operation `%s' should be boolean value",
3545 opnum, opname);
3546 set_valuetype(V_ERROR);
3547 }
3548
3549 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3550 const char *opnum,
3551 const char *opname,
3552 const Location *loc)
3553 {
3554 if(tt==Type::T_INT) return;
3555 if(tt!=Type::T_ERROR)
3556 loc->error("%s operand of operation `%s' should be integer value",
3557 opnum, opname);
3558 set_valuetype(V_ERROR);
3559 }
3560
3561 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3562 const char *opnum,
3563 const char *opname,
3564 const Location *loc)
3565 {
3566 if(tt==Type::T_REAL) return;
3567 else if(tt==Type::T_INT)
3568 loc->error("%s operand of operation `%s' should be float value."
3569 " Perhaps you missed an int2float() conversion function"
3570 " or `.0' at the end of the number",
3571 opnum, opname);
3572 else if(tt!=Type::T_ERROR)
3573 loc->error("%s operand of operation `%s' should be float value",
3574 opnum, opname);
3575 set_valuetype(V_ERROR);
3576 }
3577
3578 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3579 const char *opnum,
3580 const char *opname,
3581 const Location *loc)
3582 {
3583 switch(tt) {
3584 case Type::T_INT:
3585 case Type::T_REAL:
3586 return;
3587 default:
3588 break;
3589 }
3590 if(tt!=Type::T_ERROR)
3591 loc->error("%s operand of operation `%s' should be integer"
3592 " or float value",
3593 opnum, opname);
3594 set_valuetype(V_ERROR);
3595 }
3596
3597 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3598 const char *opnum,
3599 const char *opname,
3600 const Location *loc)
3601 {
3602 switch(tt) {
3603 case Type::T_INT:
3604 case Type::T_REAL:
3605 case Type::T_ENUM_T:
3606 return;
3607 default:
3608 break;
3609 }
3610 if(tt!=Type::T_ERROR)
3611 loc->error("%s operand of operation `%s' should be integer, float"
3612 " or enumerated value", opnum, opname);
3613 set_valuetype(V_ERROR);
3614 }
3615
3616 void Value::chk_expr_operandtype_list(Type* t,
3617 const char *opnum,
3618 const char *opname,
3619 const Location *loc,
3620 bool allow_array)
3621 {
3622 if (valuetype == V_ERROR) return;
3623 if (t->get_typetype() == Type::T_ERROR) {
3624 set_valuetype(V_ERROR);
3625 return;
3626 }
3627 if (!t->is_list_type(allow_array)) {
3628 loc->error("%s operand of operation `%s' should be a string, "
3629 "`record of'%s `set of'%s value", opnum, opname,
3630 allow_array ? "," : " or", allow_array ? " or array" : "");
3631 set_valuetype(V_ERROR);
3632 return;
3633 }
3634 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3635 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3636 TypeChain l_chain;
3637 TypeChain r_chain;
3638 if (my_governor && my_governor->is_list_type(allow_array)
3639 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3640 if (info.is_subtype_error()) {
3641 // this is ok.
3642 if (info.needs_conversion()) set_needs_conversion();
3643 } else
3644 if (!info.is_erroneous()) {
3645 error("%s operand of operation `%s' is of type `%s', but a value of "
3646 "type `%s' was expected here", opnum, opname,
3647 t->get_typename().c_str(), my_governor->get_typename().c_str());
3648 } else {
3649 error("%s", info.get_error_str_str().c_str());
3650 }
3651 } else {
3652 if (info.needs_conversion())
3653 set_needs_conversion();
3654 }
3655 }
3656
3657 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3658 const char *opnum,
3659 const char *opname,
3660 const Location *loc)
3661 {
3662 switch(tt) {
3663 case Type::T_CSTR:
3664 case Type::T_USTR:
3665 case Type::T_BSTR:
3666 case Type::T_HSTR:
3667 case Type::T_OSTR:
3668 return;
3669 default:
3670 break;
3671 }
3672 if(tt!=Type::T_ERROR)
3673 loc->error("%s operand of operation `%s' should be string value",
3674 opnum, opname);
3675 set_valuetype(V_ERROR);
3676 }
3677
3678 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3679 const char *opnum,
3680 const char *opname,
3681 const Location *loc)
3682 {
3683 switch(tt) {
3684 case Type::T_CSTR:
3685 case Type::T_USTR:
3686 return;
3687 default:
3688 break;
3689 }
3690 if(tt!=Type::T_ERROR)
3691 loc->error("%s operand of operation `%s' should be (universal)"
3692 " charstring value",
3693 opnum, opname);
3694 set_valuetype(V_ERROR);
3695 }
3696
3697 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3698 const char *opnum,
3699 const char *opname,
3700 const Location *loc)
3701 {
3702 if(tt==Type::T_CSTR) return;
3703 if(tt!=Type::T_ERROR)
3704 loc->error("%s operand of operation `%s' should be charstring value",
3705 opnum, opname);
3706 set_valuetype(V_ERROR);
3707 }
3708
3709 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3710 const char *opnum,
3711 const char *opname,
3712 const Location *loc)
3713 {
3714 switch(tt) {
3715 case Type::T_BSTR:
3716 case Type::T_HSTR:
3717 case Type::T_OSTR:
3718 return;
3719 default:
3720 break;
3721 }
3722 if(tt!=Type::T_ERROR)
3723 loc->error("%s operand of operation `%s' should be binary string value",
3724 opnum, opname);
3725 set_valuetype(V_ERROR);
3726 }
3727
3728 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3729 const char *opnum,
3730 const char *opname,
3731 const Location *loc)
3732 {
3733 if(tt==Type::T_BSTR) return;
3734 if(tt!=Type::T_ERROR)
3735 loc->error("%s operand of operation `%s' should be bitstring value",
3736 opnum, opname);
3737 set_valuetype(V_ERROR);
3738 }
3739
3740 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3741 const char *opnum,
3742 const char *opname,
3743 const Location *loc)
3744 {
3745 if(tt==Type::T_HSTR) return;
3746 if(tt!=Type::T_ERROR)
3747 loc->error("%s operand of operation `%s' should be hexstring value",
3748 opnum, opname);
3749 set_valuetype(V_ERROR);
3750 }
3751
3752 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3753 const char *opnum,
3754 const char *opname,
3755 const Location *loc)
3756 {
3757 if(tt==Type::T_OSTR) return;
3758 if(tt!=Type::T_ERROR)
3759 loc->error("%s operand of operation `%s' should be octetstring value",
3760 opnum, opname);
3761 set_valuetype(V_ERROR);
3762 }
3763
3764 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3765 Type::typetype_t tt2,
3766 const char *opname)
3767 {
3768 if(valuetype==V_ERROR) return;
3769 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3770 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3771 set_valuetype(V_ERROR);
3772 return;
3773 }
3774 if(tt1==tt2) return;
3775 error("The operands of operation `%s' should be of same type", opname);
3776 set_valuetype(V_ERROR);
3777 }
3778
3779 /* For predefined functions. */
3780 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3781 Type::typetype_t tt2,
3782 const char *opnum1,
3783 const char *opnum2,
3784 const char *opname)
3785 {
3786 if(valuetype==V_ERROR) return;
3787 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3788 set_valuetype(V_ERROR);
3789 return;
3790 }
3791 if(tt1==tt2) return;
3792 error("The %s and %s operands of operation `%s' should be of same type",
3793 opnum1, opnum2, opname);
3794 set_valuetype(V_ERROR);
3795 }
3796
3797 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3798 Value *v1, Value *v2,
3799 const char *opnum1,
3800 const char *opnum2)
3801 {
3802 start:
3803 if (valuetype == V_ERROR) return;
3804 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3805 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3806 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3807
3808 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3809 set_valuetype(V_ERROR);
3810 return;
3811 }
3812 if (tt1 == Type::T_UNDEF) {
3813 if (tt2 == Type::T_UNDEF) {
3814 if (v1->is_undef_lowerid()) {
3815 if (v2->is_undef_lowerid()) {
3816 Scope *scope = get_my_scope();
3817 Module *my_mod = scope->get_scope_mod();
3818 const Identifier& id1 = v1->get_undef_lowerid();
3819 if (scope->has_ass_withId(id1)
3820 || my_mod->has_imported_ass_withId(id1)) {
3821 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3822 * should examine this situation better, but now I suppose
3823 * the first is ref, not enum. */
3824 v1->set_lowerid_to_ref();
3825 goto start;
3826 } else {
3827 const Identifier& id2 = v2->get_undef_lowerid();
3828 if (scope->has_ass_withId(id2)
3829 || my_mod->has_imported_ass_withId(id2)) {
3830 v2->set_lowerid_to_ref();
3831 goto start;
3832 }
3833 }
3834 /* This is perhaps enum-enum, but it has no real
3835 * significance, so this should be an error. */
3836 } else {
3837 v1->set_lowerid_to_ref();
3838 goto start;
3839 }
3840 } else if (v2->is_undef_lowerid()) {
3841 v2->set_lowerid_to_ref();
3842 goto start;
3843 }
3844 error("Cannot determine the type of the operands in operation `%s'",
3845 get_opname());
3846 set_valuetype(V_ERROR);
3847 return;
3848 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3849 v1->set_lowerid_to_ref();
3850 goto start;
3851 } else {
3852 /* v1 is something undefined, but not lowerid; v2 has
3853 * returntype (perhaps also governor) */
3854 }
3855 } else if (tt2 == Type::T_UNDEF) {
3856 /* but tt1 is not undef */
3857 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3858 v2->set_lowerid_to_ref();
3859 goto start;
3860 } else {
3861 /* v2 is something undefined, but not lowerid; v1 has
3862 * returntype (perhaps also governor) */
3863 }
3864 }
3865
3866 /* Now undef_lower_id's are converted to references, or the other
3867 * value has governor; let's see the governors, if they exist. */
3868 Type *t1 = v1->get_expr_governor(exp_val);
3869 Type *t2 = v2->get_expr_governor(exp_val);
3870 if (t1) {
3871 if (t2) {
3872 // Both value has governor. Are they compatible? According to 7.1.2
3873 // and C.34 it's required to have the same root types for
3874 // OPTYPE_{CONCAT,REPLACE}.
3875 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3876 u.expr.v_optype == OPTYPE_REPLACE);
3877 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
3878 u.expr.v_optype == OPTYPE_REPLACE);
3879 TypeChain l_chain1, l_chain2;
3880 TypeChain r_chain1, r_chain2;
3881 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
3882 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
3883 if (!compat_t1 && !compat_t2) {
3884 if (!info1.is_erroneous() && !info2.is_erroneous()) {
3885 // the subtypes don't need to be compatible here
3886 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
3887 error("The operands of operation `%s' should be of compatible "
3888 "types", get_opname());
3889 set_valuetype(V_ERROR);
3890 } else {
3891 if (info1.needs_conversion() || info2.needs_conversion()) {
3892 set_needs_conversion(); // Avoid folding.
3893 return;
3894 }
3895 }
3896 } else {
3897 if (info1.is_erroneous())
3898 v1->error("%s", info1.get_error_str_str().c_str());
3899 else if (info2.is_erroneous())
3900 v2->error("%s", info2.get_error_str_str().c_str());
3901 set_valuetype(V_ERROR);
3902 }
3903 return;
3904 } else if (info1.needs_conversion() || info2.needs_conversion()) {
3905 set_needs_conversion(); // Avoid folding.
3906 return;
3907 }
3908 } else {
3909 // t1, no t2.
3910 v2->set_my_governor(t1);
3911 t1->chk_this_value_ref(v2);
3912 if (v2->valuetype == V_OMIT) {
3913 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3914 get_opname());
3915 v1->chk_expr_omit_comparison(exp_val);
3916 } else {
3917 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3918 get_opname());
3919 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3920 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3921 goto start;
3922 }
3923 }
3924 } else if (t2) {
3925 v1->set_my_governor(t2);
3926 t2->chk_this_value_ref(v1);
3927 if (v1->valuetype == V_OMIT) {
3928 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3929 get_opname());
3930 v2->chk_expr_omit_comparison(exp_val);
3931 } else {
3932 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3933 get_opname());
3934 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3935 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3936 goto start;
3937 }
3938 } else {
3939 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3940 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
3941 // Here, it cannot be that both are T_UNDEF.
3942 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3943 error("Please use reference as %s operand of operator `%s'",
3944 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
3945 set_valuetype(V_ERROR);
3946 return;
3947 }
3948 // Deny type compatibility if no governors found. The typetype_t must
3949 // be the same. TODO: How can this happen?
3950 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
3951 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
3952 error("The operands of operation `%s' should be of compatible types",
3953 get_opname());
3954 set_valuetype(V_ERROR);
3955 }
3956 }
3957 }
3958
3959 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
3960 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
3961 {
3962 if(valuetype==V_ERROR) return;
3963 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3964 Assignment *t_ass = ref->get_refd_assignment();
3965 if(!t_ass) goto error;
3966 switch(t_ass->get_asstype()) {
3967 case Assignment::A_TIMER:
3968 case Assignment::A_PAR_TIMER:
3969 u.expr.v_optype=OPTYPE_TMR_RUNNING;
3970 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
3971 chk_expr_dynamic_part(exp_val, true);
3972 break;
3973 case Assignment::A_CONST:
3974 case Assignment::A_EXT_CONST:
3975 case Assignment::A_MODULEPAR:
3976 case Assignment::A_VAR:
3977 case Assignment::A_FUNCTION_RVAL:
3978 case Assignment::A_EXT_FUNCTION_RVAL:
3979 case Assignment::A_PAR_VAL_IN:
3980 case Assignment::A_PAR_VAL_OUT:
3981 case Assignment::A_PAR_VAL_INOUT: {
3982 u.expr.v_optype = OPTYPE_COMP_RUNNING;
3983 Value* val = new Value(V_REFD, u.expr.r1);
3984 val->set_my_scope(my_scope);
3985 val->set_fullname(u.expr.r1->get_fullname());
3986 val->set_location(*u.expr.r1);
3987 u.expr.v1 = val;
3988 chk_expr_operand_compref(val, opnum, get_opname());
3989 chk_expr_dynamic_part(exp_val, false);
3990 break; }
3991 default:
3992 ref->error("%s operand of operation `%s' should be timer or"
3993 " component reference instead of %s",
3994 opnum, opname, t_ass->get_description().c_str());
3995 goto error;
3996 } // switch
3997 return;
3998 error:
3999 set_valuetype(V_ERROR);
4000 }
4001
4002 Type *Value::chk_expr_operand_comptyperef_create()
4003 {
4004 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4005 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4006 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4007 if (!t_ass) goto error;
4008 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4009 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4010 Type::EXPECTED_DYNAMIC_VALUE);
4011 if (!t_type) goto error;
4012 t_type = t_type->get_type_refd_last();
4013 if (t_type->get_typetype() == Type::T_COMPONENT) {
4014 if (my_governor) {
4015 Type *my_governor_last = my_governor->get_type_refd_last();
4016 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4017 !my_governor_last->is_compatible(t_type, NULL)) {
4018 u.expr.r1->error("Incompatible component types: operation "
4019 "`create' should refer to `%s' instead of "
4020 "`%s'",
4021 my_governor_last->get_typename().c_str(),
4022 t_type->get_typename().c_str());
4023 goto error;
4024 }
4025 }
4026 return t_type;
4027 } else {
4028 u.expr.r1->error("Type mismatch: reference to a component type was "
4029 "expected in operation `create' instead of `%s'",
4030 t_type->get_typename().c_str());
4031 }
4032 } else {
4033 u.expr.r1->error("Operation `create' should refer to a component type "
4034 "instead of %s", t_ass->get_description().c_str());
4035 }
4036 error:
4037 set_valuetype(V_ERROR);
4038 return NULL;
4039 }
4040
4041 void Value::chk_expr_comptype_compat()
4042 {
4043 if (valuetype != V_EXPR)
4044 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4045 if (!my_governor || !my_scope) return;
4046 Type *my_governor_last = my_governor->get_type_refd_last();
4047 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4048 Type *t_comptype;
4049 switch (u.expr.v_optype) {
4050 case OPTYPE_COMP_MTC:
4051 t_comptype = my_scope->get_mtc_system_comptype(false, false);
4052 break;
4053 case OPTYPE_COMP_SYSTEM:
4054 t_comptype = my_scope->get_mtc_system_comptype(true, false);
4055 break;
4056 case OPTYPE_COMP_SELF: {
4057 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4058 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4059 break; }
4060 default:
4061 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4062 t_comptype = 0;
4063 break;
4064 }
4065 if (t_comptype
4066 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4067 error("Incompatible component types: a component reference of "
4068 "type `%s' was expected, but `%s' has type `%s'",
4069 my_governor_last->get_typename().c_str(), get_opname(),
4070 t_comptype->get_typename().c_str());
4071 set_valuetype(V_ERROR);
4072 }
4073 }
4074
4075 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4076 const char *opname)
4077 {
4078 if(valuetype == V_ERROR) return;
4079 switch(val->get_valuetype()) {
4080 case V_INVOKE: {
4081 Error_Context cntxt(this, "In `%s' operation", opname);
4082 Value *v_last = val->get_value_refd_last();
4083 if(!v_last) goto error;
4084 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4085 if(!t) goto error;
4086 t = t->get_type_refd_last();
4087 if(t->get_typetype() != Type::T_COMPONENT) {
4088 v_last->error("%s operand of operation `%s': Type mismatch:"
4089 " component reference was expected instead of `%s'",
4090 opnum, opname, t->get_typename().c_str());
4091 goto error;
4092 }
4093 return; }
4094 case V_REFD: {
4095 Reference *ref = val->get_reference();
4096 Assignment *t_ass = ref->get_refd_assignment();
4097 Value *t_val = 0;
4098 if (!t_ass) goto error;
4099 switch(t_ass->get_asstype()) {
4100 case Assignment::A_CONST:
4101 t_val = t_ass->get_Value();
4102 // no break
4103 case Assignment::A_EXT_CONST:
4104 case Assignment::A_MODULEPAR:
4105 case Assignment::A_VAR:
4106 case Assignment::A_FUNCTION_RVAL:
4107 case Assignment::A_EXT_FUNCTION_RVAL:
4108 case Assignment::A_PAR_VAL_IN:
4109 case Assignment::A_PAR_VAL_OUT:
4110 case Assignment::A_PAR_VAL_INOUT: {
4111 Type *t_type=t_ass->get_Type()
4112 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4113 if(!t_type) goto error;
4114 t_type=t_type->get_type_refd_last();
4115 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4116 ref->error("%s operand of operation `%s': Type mismatch:"
4117 " component reference was expected instead of `%s'",
4118 opnum, opname, t_type->get_typename().c_str());
4119 goto error;
4120 }
4121 break;}
4122 default:
4123 ref->error("%s operand of operation `%s' should be"
4124 " component reference instead of %s",
4125 opnum, opname, t_ass->get_description().c_str());
4126 goto error;
4127 }
4128 if (t_val) {
4129 ReferenceChain refch(this, "While searching referenced value");
4130 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4131 if (!t_val) return;
4132 t_val = t_val->get_value_refd_last();
4133 if (t_val->valuetype != V_EXPR) return;
4134 switch (t_val->u.expr.v_optype) {
4135 case OPTYPE_COMP_NULL:
4136 ref->error("%s operand of operation `%s' refers to `null' component "
4137 "reference", opnum, opname);
4138 goto error;
4139 case OPTYPE_COMP_MTC:
4140 ref->error("%s operand of operation `%s' refers to the component "
4141 "reference of the `mtc'", opnum, opname);
4142 goto error;
4143 case OPTYPE_COMP_SYSTEM:
4144 ref->error("%s operand of operation `%s' refers to the component "
4145 "reference of the `system'", opnum, opname);
4146 goto error;
4147 default:
4148 break;
4149 }
4150 }
4151 return;}
4152 default:
4153 FATAL_ERROR("Value::chk_expr_operand_compref()");
4154 }
4155 error:
4156 set_valuetype(V_ERROR);
4157 }
4158
4159 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4160 const char *opnum,
4161 const char *opname)
4162 {
4163 if(valuetype==V_ERROR) return;
4164 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4165 Assignment *t_ass = ref->get_refd_assignment();
4166 if(!t_ass) goto error;
4167 switch(t_ass->get_asstype()) {
4168 case Assignment::A_TIMER: {
4169 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4170 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4171 Type::EXPECTED_DYNAMIC_VALUE);
4172 else if (ref->get_subrefs()) {
4173 ref->error("%s operand of operation `%s': "
4174 "Reference to single timer `%s' cannot have field or array "
4175 "sub-references", opnum, opname,
4176 t_ass->get_id().get_dispname().c_str());
4177 goto error;
4178 }
4179 break; }
4180 case Assignment::A_PAR_TIMER:
4181 if (ref->get_subrefs()) {
4182 ref->error("%s operand of operation `%s': "
4183 "Reference to %s cannot have field or array sub-references",
4184 opnum, opname, t_ass->get_description().c_str());
4185 goto error;
4186 }
4187 break;
4188 default:
4189 ref->error("%s operand of operation `%s' should be timer"
4190 " instead of %s",
4191 opnum, opname, t_ass->get_description().c_str());
4192 goto error;
4193 } // switch
4194 return;
4195 error:
4196 set_valuetype(V_ERROR);
4197 }
4198
4199 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4200 const char *,
4201 const char *opname)
4202 {
4203 if(valuetype==V_ERROR) return;
4204 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4205 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4206 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4207 Error_Context cntxt(this, "In `%s' operation", opname);
4208 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4209 }
4210
4211 void Value::chk_expr_operand_activate_refd(Value *val,
4212 Ttcn::TemplateInstances* t_list2,
4213 Ttcn::ActualParList *&parlist,
4214 const char *,
4215 const char *opname)
4216 {
4217 if(valuetype==V_ERROR) return;
4218 Error_Context cntxt(this, "In `%s' operation", opname);
4219 Type *t = val->get_expr_governor_last();
4220 if (t) {
4221 switch (t->get_typetype()) {
4222 case Type::T_ERROR:
4223 set_valuetype(V_ERROR);
4224 break;
4225 case Type::T_ALTSTEP: {
4226 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4227 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4228 if(is_erroneous) {
4229 delete parlist;
4230 parlist = 0;
4231 set_valuetype(V_ERROR);
4232 } else {
4233 parlist->set_fullname(get_fullname());
4234 parlist->set_my_scope(get_my_scope());
4235 if (!fp_list->chk_activate_argument(parlist,
4236 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4237 }
4238 break; }
4239 default:
4240 error("Reference to an altstep was expected in the argument of "
4241 "`derefers()' instead of `%s'", t->get_typename().c_str());
4242 set_valuetype(V_ERROR);
4243 break;
4244 }
4245 } else set_valuetype(V_ERROR);
4246 }
4247
4248 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4249 const char *,
4250 const char *opname)
4251 {
4252 if(valuetype==V_ERROR) return;
4253 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4254 Error_Context cntxt(this, "In `%s' operation", opname);
4255 Assignment *t_ass = ref->get_refd_assignment();
4256 bool error_flag = false;
4257 if (t_ass) {
4258 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4259 ref->error("Reference to a testcase was expected in the argument "
4260 "instead of %s", t_ass->get_description().c_str());
4261 error_flag = true;
4262 }
4263 } else error_flag = true;
4264 if (val) {
4265 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4266 Value *v_last = val->get_value_refd_last();
4267 switch (v_last->valuetype) {
4268 case V_REAL: {
4269 ttcn3float v_real = v_last->get_val_Real();
4270 if (v_real < 0.0) {
4271 val->error("The testcase guard timer has negative value: `%s'",
4272 Real2string(v_real).c_str());
4273 error_flag = true;
4274 }
4275 break; }
4276 case V_ERROR:
4277 error_flag = true;
4278 break;
4279 default:
4280 break;
4281 }
4282 }
4283 if (error_flag) set_valuetype(V_ERROR);
4284 }
4285
4286void Value::chk_expr_operand_execute_refd(Value *v1,
4287 Ttcn::TemplateInstances* t_list2,
4288 Ttcn::ActualParList *&parlist,
4289 Value *v3,
4290 const char *,
4291 const char *opname)
4292 {
4293 if(valuetype==V_ERROR) return;
4294 Error_Context cntxt(this, "In `%s' operation", opname);
4295 Type *t = v1->get_expr_governor_last();
4296 if (t) {
4297 switch (t->get_typetype()) {
4298 case Type::T_ERROR:
4299 set_valuetype(V_ERROR);
4300 break;
4301 case Type::T_TESTCASE: {
4302 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4303 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4304 if(is_erroneous) {
4305 delete parlist;
4306 parlist = 0;
4307 set_valuetype(V_ERROR);
4308 } else {
4309 parlist->set_fullname(get_fullname());
4310 parlist->set_my_scope(get_my_scope());
4311 }
4312 break; }
4313 default:
4314 v1->error("Reference to a value of type testcase was expected in the "
4315 "argument of `derefers()' instead of `%s'",
4316 t->get_typename().c_str());
4317 set_valuetype(V_ERROR);
4318 break;
4319 }
4320 } else set_valuetype(V_ERROR);
4321 if (v3) {
4322 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4323 Value *v_last = v3->get_value_refd_last();
4324 switch (v_last->valuetype) {
4325 case V_REAL: {
4326 ttcn3float v_real = v_last->get_val_Real();
4327 if(v_real < 0.0) {
4328 v3->error("The testcase guard timer has negative value: `%s'",
4329 Real2string(v_real).c_str());
4330 set_valuetype(V_ERROR);
4331 }
4332 break; }
4333 case V_ERROR:
4334 set_valuetype(V_ERROR);
4335 break;
4336 default:
4337 break;
4338 }
4339 }
4340 }
4341
4342 void Value::chk_invoke(Type::expected_value_t exp_val)
4343 {
4344 if(valuetype == V_ERROR) return;
4345 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4346 if(!u.invoke.t_list) return; //already checked
4347 Error_Context cntxt(this, "In `apply()' operation");
4348 Type *t = u.invoke.v->get_expr_governor_last();
4349 if (!t) {
4350 set_valuetype(V_ERROR);
4351 return;
4352 }
4353 switch (t->get_typetype()) {
4354 case Type::T_ERROR:
4355 set_valuetype(V_ERROR);
4356 return;
4357 case Type::T_FUNCTION:
4358 break;
4359 default:
4360 u.invoke.v->error("A value of type function was expected in the "
4361 "argument instead of `%s'", t->get_typename().c_str());
4362 set_valuetype(V_ERROR);
4363 return;
4364 }
4365 my_scope->chk_runs_on_clause(t, *this, "call");
4366 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4367 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4368 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4369 delete u.invoke.t_list;
4370 u.invoke.t_list = 0;
4371 if(is_erroneous) {
4372 delete parlist;
4373 u.invoke.ap_list = 0;
4374 } else {
4375 parlist->set_fullname(get_fullname());
4376 parlist->set_my_scope(get_my_scope());
4377 u.invoke.ap_list = parlist;
4378 }
4379 switch (exp_val) {
4380 case Type::EXPECTED_CONSTANT:
4381 error("An evaluatable constant value was expected instead of operation "
4382 "`apply()'");
4383 set_valuetype(V_ERROR);
4384 break;
4385 case Type::EXPECTED_STATIC_VALUE:
4386 error("A static value was expected instead of operation `apply()'");
4387 set_valuetype(V_ERROR);
4388 break;
4389 default:
4390 break;
4391 } // switch
4392 }
4393
4394 void Value::chk_expr_eval_value(Value *val, Type &t,
4395 ReferenceChain *refch,
4396 Type::expected_value_t exp_val)
4397 {
4398 bool self_ref = false;
4399 if(valuetype==V_ERROR) return;
4400 // Commented out to report more errors :)
4401 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4402 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4403 switch(val->get_valuetype()) {
4404 case V_REFD:
4405 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4406 break;
4407 case V_EXPR:
4408 case V_MACRO:
4409 case V_INVOKE:
4410 val->get_value_refd_last(refch, exp_val);
4411 break;
4412 default:
4413 break;
4414 } // switch
4415 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4416
4417 (void)self_ref;
4418 }
4419
4420 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4421 ReferenceChain *refch, Type::expected_value_t exp_val)
4422 {
4423 bool self_ref = false;
4424 ti->chk(type);
4425 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4426 ti->error("Reference to a %s value was expected instead of an in-line "
4427 "modified template",
4428 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4429 set_valuetype(V_ERROR);
4430 return;
4431 }
4432 Template *templ = ti->get_Template();
4433 switch (templ->get_templatetype()) {
4434 case Template::TEMPLATE_REFD:
4435 // not foldable
4436 if (exp_val == Type::EXPECTED_TEMPLATE) {
4437 templ = templ->get_template_refd_last(refch);
4438 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4439 set_valuetype(V_ERROR);
4440 } else {
4441 ti->error("Reference to a %s value was expected instead of %s",
4442 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4443 templ->get_reference()->get_refd_assignment()
4444 ->get_description().c_str());
4445 set_valuetype(V_ERROR);
4446 }
4447 break;
4448 case Template::SPECIFIC_VALUE: {
4449 Value *val = templ->get_specific_value();
4450 switch (val->get_valuetype()) {
4451 case V_REFD:
4452 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4453 break;
4454 case V_EXPR:
4455 val->get_value_refd_last(refch, exp_val);
4456 default:
4457 break;
4458 } // switch
4459 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4460 break; }
4461 case Template::TEMPLATE_ERROR:
4462 set_valuetype(V_ERROR);
4463 break;
4464 default:
4465 break;
4466 } // switch
4467
4468 (void)self_ref;
4469 }
4470
4471 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4472 const char *opname)
4473 {
4474 if(valuetype==V_ERROR) return;
4475 if(u.expr.state==EXPR_CHECKING_ERR) return;
4476 if(val->is_unfoldable()) return;
4477 if(*val->get_val_Int()<0) {
4478 val->error("%s operand of operation `%s' should not be negative",
4479 opnum, opname);
4480 set_valuetype(V_ERROR);
4481 }
4482 }
4483
4484 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4485 const char *opname)
4486 {
4487 if(valuetype==V_ERROR) return;
4488 if(u.expr.state==EXPR_CHECKING_ERR) return;
4489 if(val->is_unfoldable()) return;
4490 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4491 val->error("%s operand of operation `%s' should be in range 0..127",
4492 opnum, opname);
4493 set_valuetype(V_ERROR);
4494 }
4495 }
4496
4497 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4498 const char *opname)
4499 {
4500 if(valuetype==V_ERROR) return;
4501 if(u.expr.state==EXPR_CHECKING_ERR) return;
4502 if(val->is_unfoldable()) return;
4503 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4504 val->error("%s operand of operation `%s' should be in range"
4505 " 0..2147483647", opnum, opname);
4506 set_valuetype(V_ERROR);
4507 }
4508 }
4509
4510 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4511 const char *opname)
4512 {
4513 if(valuetype==V_ERROR) return;
4514 if(u.expr.state==EXPR_CHECKING_ERR) return;
4515 if(val->is_unfoldable()) return;
4516 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4517 ||
4518 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4519 {
4520 val->error("%s operand of operation `%s' should not be zero",
4521 opnum, opname);
4522 set_valuetype(V_ERROR);
4523 }
4524 }
4525
4526 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4527 const char *opname)
4528 {
4529 if (valuetype == V_ERROR) return;
4530 if (u.expr.state == EXPR_CHECKING_ERR) return;
4531 if (val->get_expr_returntype() != Type::T_INT) return;
4532 if (val->is_unfoldable()) return;
4533 const int_val_t *val_int = val->get_val_Int();
4534 if (*val_int > static_cast<Int>(INT_MAX)) {
4535 val->error("%s operand of operation `%s' should be less than `%d' "
4536 "instead of `%s'", opnum, opname, INT_MAX,
4537 (val_int->t_str()).c_str());
4538 set_valuetype(V_ERROR);
4539 }
4540 }
4541
4542 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4543 const char *opname)
4544 {
4545 if(valuetype==V_ERROR) return;
4546 if(u.expr.state==EXPR_CHECKING_ERR) return;
4547 if(val->is_unfoldable()) return;
4548 if(val->get_val_strlen()!=1) {
4549 val->error("%s operand of operation `%s' should be of length 1",
4550 opnum, opname);
4551 set_valuetype(V_ERROR);
4552 }
4553 }
4554
4555 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4556 const char *opname)
4557 {
4558 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4559 Value *v_last = val->get_value_refd_last();
4560 if (v_last->valuetype == V_CSTR) {
4561 size_t len = v_last->get_val_strlen();
4562 if (len % 2) {
4563 val->error("%s operand of operation `%s' should contain even number "
4564 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4565 set_valuetype(V_ERROR);
4566 }
4567 } else if (v_last->valuetype == V_REFD) {
4568 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4569 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4570 val->error("%s operand of operation `%s' should contain even number "
4571 "of characters, but a string element contains 1", opnum, opname);
4572 set_valuetype(V_ERROR);
4573 }
4574 }
4575 }
4576
4577 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4578 const char *opname)
4579 {
4580 if(valuetype==V_ERROR) return;
4581 if(u.expr.state==EXPR_CHECKING_ERR) return;
4582 if(val->is_unfoldable()) return;
4583 const string& s=val->get_val_str();
4584 for(size_t i=0; i<s.size(); i++) {
4585 char c=s[i];
4586 if(!(c=='0' || c=='1')) {
4587 val->error("%s operand of operation `%s' can contain only"
4588 " binary digits (position %lu is `%c')",
4589 opnum, opname, (unsigned long) i, c);
4590 set_valuetype(V_ERROR);
4591 return;
4592 }
4593 }
4594 }
4595
4596 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4597 const char *opname)
4598 {
4599 if(valuetype==V_ERROR) return;
4600 if(u.expr.state==EXPR_CHECKING_ERR) return;
4601 if(val->is_unfoldable()) return;
4602 const string& s=val->get_val_str();
4603 for(size_t i=0; i<s.size(); i++) {
4604 char c=s[i];
4605 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4606 val->error("%s operand of operation `%s' can contain only valid "
4607 "hexadecimal digits (position %lu is `%c')",
4608 opnum, opname, (unsigned long) i, c);
4609 set_valuetype(V_ERROR);
4610 return;
4611 }
4612 }
4613 }
4614
4615 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4616 const char *opname)
4617 {
4618 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4619 Value *v = val->get_value_refd_last();
4620 if (v->valuetype != V_OSTR) return;
4621 const string& s = val->get_val_str();
4622 size_t n_octets = s.size() / 2;
4623 for (size_t i = 0; i < n_octets; i++) {
4624 char c = s[2 * i];
4625 if (!(c >= '0' && c <= '7')) {
4626 val->error("%s operand of operation `%s' shall consist of octets "
4627 "within the range 00 .. 7F, but the string `%s'O contains octet "
4628 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4629 (unsigned long) i);
4630 set_valuetype(V_ERROR);
4631 return;
4632 }
4633 }
4634 }
4635
4636 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4637 const char *opname)
4638 {
4639 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4640 Value *v_last = val->get_value_refd_last();
4641 if (v_last->valuetype != V_CSTR) return;
4642 const string& s = v_last->get_val_str();
4643 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4644 state = S_INITIAL;
4645 // state: expected characters
4646 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4647 // S_FIRST: first digit
4648 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4649 // S_END: trailing whitespace
4650 // S_ERR: error was found, stop
4651 for (size_t i = 0; i < s.size(); i++) {
4652 char c = s[i];
4653 switch (state) {
4654 case S_INITIAL:
4655 case S_INITIAL_WS:
4656 if (c == '+' || c == '-') state = S_FIRST;
4657 else if (c == '0') state = S_ZERO;
4658 else if (c >= '1' && c <= '9') state = S_MORE;
4659 else if (string::is_whitespace(c)) {
4660 if (state == S_INITIAL) {
4661 val->warning("Leading whitespace was detected and ignored in the "
4662 "operand of operation `%s'", opname);
4663 state = S_INITIAL_WS;
4664 }
4665 } else state = S_ERR;
4666 break;
4667 case S_FIRST:
4668 if (c == '0') state = S_ZERO;
4669 else if (c >= '1' && c <= '9') state = S_MORE;
4670 else state = S_ERR;
4671 break;
4672 case S_ZERO:
4673 if (c >= '0' && c <= '9') {
4674 val->warning("Leading zero digit was detected and ignored in the "
4675 "operand of operation `%s'", opname);
4676 state = S_MORE;
4677 } else if (string::is_whitespace(c)) state = S_END;
4678 else state = S_ERR;
4679 break;
4680 case S_MORE:
4681 if (c >= '0' && c <= '9') {}
4682 else if (string::is_whitespace(c)) state = S_END;
4683 else state = S_ERR;
4684 break;
4685 case S_END:
4686 if (!string::is_whitespace(c)) state = S_ERR;
4687 break;
4688 default:
4689 break;
4690 }
4691 if (state == S_ERR) {
4692 if (string::is_printable(c)) {
4693 val->error("%s operand of operation `%s' should be a string "
4694 "containing a valid integer value, but invalid character `%c' "
4695 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4696 } else {
4697 val->error("%s operand of operation `%s' should be a string "
4698 "containing a valid integer value, but invalid character with "
4699 "character code %u was detected at index %lu", opnum, opname, c,
4700 (unsigned long) i);
4701 }
4702 set_valuetype(V_ERROR);
4703 break;
4704 }
4705 }
4706 switch (state) {
4707 case S_INITIAL:
4708 case S_INITIAL_WS:
4709 val->error("%s operand of operation `%s' should be a string containing a "
4710 "valid integer value instead of an empty string", opnum, opname);
4711 set_valuetype(V_ERROR);
4712 break;
4713 case S_FIRST:
4714 val->error("%s operand of operation `%s' should be a string containing a "
4715 "valid integer value, but only a sign character was detected", opnum,
4716 opname);
4717 set_valuetype(V_ERROR);
4718 break;
4719 case S_END:
4720 val->warning("Trailing whitespace was detected and ignored in the "
4721 "operand of operation `%s'", opname);
4722 break;
4723 default:
4724 break;
4725 }
4726 }
4727
4728 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4729 const char *opname)
4730 {
4731 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4732 Value *v_last = val->get_value_refd_last();
4733 if (v_last->valuetype == V_REFD) {
4734 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4735 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4736 val->error("%s operand of operation `%s' should be a string containing "
4737 "a valid float value instead of a string element, which cannot "
4738 "represent a floating point number", opnum, opname);
4739 set_valuetype(V_ERROR);
4740 }
4741 return;
4742 } else if (v_last->valuetype != V_CSTR) return;
4743 const string& s = v_last->get_val_str();
4744 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4745 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4746 state = S_INITIAL;
4747 // state: expected characters
4748 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4749 // leading whitespace
4750 // S_FIRST_M: first digit of integer part in mantissa
4751 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4752 // S_FIRST_F: first digit of fraction
4753 // S_MORE_F: more digits of fraction, E, trailing whitespace
4754 // S_INITIAL_E: +, -, first digit of exponent
4755 // S_FIRST_E: first digit of exponent
4756 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4757 // S_END: trailing whitespace
4758 // S_ERR: error was found, stop
4759 for (size_t i = 0; i < s.size(); i++) {
4760 char c = s[i];
4761 switch (state) {
4762 case S_INITIAL:
4763 case S_INITIAL_WS:
4764 if (c == '+' || c == '-') state = S_FIRST_M;
4765 else if (c == '0') state = S_ZERO_M;
4766 else if (c >= '1' && c <= '9') state = S_MORE_M;
4767 else if (string::is_whitespace(c)) {
4768 if (state == S_INITIAL) {
4769 val->warning("Leading whitespace was detected and ignored in the "
4770 "operand of operation `%s'", opname);
4771 state = S_INITIAL_WS;
4772 }
4773 } else state = S_ERR;
4774 break;
4775 case S_FIRST_M:
4776 if (c == '0') state = S_ZERO_M;
4777 else if (c >= '1' && c <= '9') state = S_MORE_M;
4778 else state = S_ERR;
4779 break;
4780 case S_ZERO_M:
4781 if (c == '.') state = S_FIRST_F;
4782 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4783 else if (c >= '0' && c <= '9') {
4784 val->warning("Leading zero digit was detected and ignored in the "
4785 "mantissa of the operand of operation `%s'", opname);
4786 state = S_MORE_M;
4787 } else state = S_ERR;
4788 break;
4789 case S_MORE_M:
4790 if (c == '.') state = S_FIRST_F;
4791 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4792 else if (c >= '0' && c <= '9') {}
4793 else state = S_ERR;
4794 break;
4795 case S_FIRST_F:
4796 if (c >= '0' && c <= '9') state = S_MORE_F;
4797 else state = S_ERR;
4798 break;
4799 case S_MORE_F:
4800 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4801 else if (c >= '0' && c <= '9') {}
4802 else if (string::is_whitespace(c)) state = S_END;
4803 else state = S_ERR;
4804 break;
4805 case S_INITIAL_E:
4806 if (c == '+' || c == '-') state = S_FIRST_E;
4807 else if (c == '0') state = S_ZERO_E;
4808 else if (c >= '1' && c <= '9') state = S_MORE_E;
4809 else state = S_ERR;
4810 break;
4811 case S_FIRST_E:
4812 if (c == '0') state = S_ZERO_E;
4813 else if (c >= '1' && c <= '9') state = S_MORE_E;
4814 else state = S_ERR;
4815 break;
4816 case S_ZERO_E:
4817 if (c >= '0' && c <= '9') {
4818 val->warning("Leading zero digit was detected and ignored in the "
4819 "exponent of the operand of operation `%s'", opname);
4820 state = S_MORE_E;
4821 } else if (string::is_whitespace(c)) state = S_END;
4822 else state = S_ERR;
4823 break;
4824 case S_MORE_E:
4825 if (c >= '0' && c <= '9') {}
4826 else if (string::is_whitespace(c)) state = S_END;
4827 else state = S_ERR;
4828 break;
4829 case S_END:
4830 if (!string::is_whitespace(c)) state = S_ERR;
4831 break;
4832 default:
4833 break;
4834 }
4835 if (state == S_ERR) {
4836 if (string::is_printable(c)) {
4837 val->error("%s operand of operation `%s' should be a string "
4838 "containing a valid float value, but invalid character `%c' "
4839 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4840 } else {
4841 val->error("%s operand of operation `%s' should be a string "
4842 "containing a valid float value, but invalid character with "
4843 "character code %u was detected at index %lu", opnum, opname, c,
4844 (unsigned long) i);
4845 }
4846 set_valuetype(V_ERROR);
4847 break;
4848 }
4849 }
4850 switch (state) {
4851 case S_INITIAL:
4852 case S_INITIAL_WS:
4853 val->error("%s operand of operation `%s' should be a string containing a "
4854 "valid float value instead of an empty string", opnum, opname);
4855 set_valuetype(V_ERROR);
4856 break;
4857 case S_FIRST_M:
4858 val->error("%s operand of operation `%s' should be a string containing a "
4859 "valid float value, but only a sign character was detected", opnum,
4860 opname);
4861 set_valuetype(V_ERROR);
4862 break;
4863 case S_ZERO_M:
4864 case S_MORE_M:
4865 // HL67862: Missing decimal dot allowed for str2float
4866 break;
4867 case S_FIRST_F:
4868 // HL67862: Missing fraction part is allowed for str2float
4869 break;
4870 case S_INITIAL_E:
4871 case S_FIRST_E:
4872 val->error("%s operand of operation `%s' should be a string containing a "
4873 "valid float value, but the exponent is missing after the `E' sign",
4874 opnum, opname);
4875 set_valuetype(V_ERROR);
4876 break;
4877 case S_END:
4878 val->warning("Trailing whitespace was detected and ignored in the "
4879 "operand of operation `%s'", opname);
4880 break;
4881 default:
4882 break;
4883 }
4884 }
4885
4886 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
4887 const char *opname)
4888 {
4889 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4890 Value *v = val->get_value_refd_last();
4891 if (v->valuetype != V_USTR) return;
4892 const ustring& us = v->get_val_ustr();
4893 for (size_t i = 0; i < us.size(); i++) {
4894 const ustring::universal_char& uchar = us[i];
4895 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
4896 uchar.cell > 127) {
4897 val->error("%s operand of operation `%s' shall consist of characters "
4898 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4899 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4900 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
4901 uchar.row, uchar.cell, (unsigned long) i);
4902 set_valuetype(V_ERROR);
4903 return;
4904 }
4905 }
4906 }
4907
4908 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
4909 const char *opname)
4910 {
4911 if(valuetype==V_ERROR) return;
4912 if(u.expr.state==EXPR_CHECKING_ERR) return;
4913 if(val->is_unfoldable()) return;
4914 const string& bstr=val->get_val_str();
4915 // see also PredefFunc.cc::bit2int()
4916 size_t nof_bits = bstr.size();
4917 // skip the leading zeros
4918 size_t start_index = 0;
4919 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
4920 // check whether the remaining bits fit in Int
4921 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
4922 val->error("%s operand of operation `%s' is too large (maximum number"
4923 " of bits in integer is %lu)",
4924 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4925 set_valuetype(V_ERROR);
4926 }
4927 }
4928
4929 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
4930 const char *opname)
4931 {
4932 if(valuetype==V_ERROR) return;
4933 if(u.expr.state==EXPR_CHECKING_ERR) return;
4934 if(val->is_unfoldable()) return;
4935 const string& hstr=val->get_val_str();
4936 // see also PredefFunc.cc::hex2int()
4937 size_t nof_digits = hstr.size();
4938 // skip the leading zeros
4939 size_t start_index = 0;
4940 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
4941 // check whether the remaining hex digits fit in Int
4942 if (nof_digits - start_index > 2 * sizeof(Int) ||
4943 (nof_digits - start_index == 2 * sizeof(Int) &&
4944 char_to_hexdigit(hstr[start_index]) > 7)) {
4945 val->error("%s operand of operation `%s' is too large (maximum number"
4946 " of bits in integer is %lu)",
4947 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4948 set_valuetype(V_ERROR);
4949 }
4950 }
4951
4952 void Value::chk_expr_operands_int2binstr()
4953 {
4954 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4955 if (u.expr.v1->is_unfoldable()) return;
4956 if (u.expr.v2->is_unfoldable()) return;
4957 // It is already checked that i1 and i2 are non-negative.
4958 Error_Context cntxt(this, "In operation `%s'", get_opname());
4959 const int_val_t *i1 = u.expr.v1->get_val_Int();
4960 const int_val_t *i2 = u.expr.v2->get_val_Int();
4961 if (!i2->is_native()) {
4962 u.expr.v2->error("The length of the resulting string is too large for "
4963 "being represented in memory");
4964 set_valuetype(V_ERROR);
4965 return;
4966 }
4967 Int nof_bits = i2->get_val();
4968 if (u.expr.v1->is_unfoldable()) return;
4969 switch (u.expr.v_optype) {
4970 case OPTYPE_INT2BIT:
4971 break;
4972 case OPTYPE_INT2HEX:
4973 nof_bits *= 4;
4974 break;
4975 case OPTYPE_INT2OCT:
4976 nof_bits *= 8;
4977 break;
4978 default:
4979 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4980 }
4981 if (*i1 >> nof_bits > 0) { // Expensive?
4982 u.expr.v1->error("Value %s does not fit in length %s",
4983 i1->t_str().c_str(), i2->t_str().c_str());
4984 set_valuetype(V_ERROR);
4985 }
4986 }
4987
4988 void Value::chk_expr_operands_str_samelen()
4989 {
4990 if(valuetype==V_ERROR) return;
4991 if(u.expr.state==EXPR_CHECKING_ERR) return;
4992 Value *v1=u.expr.v1;
4993 if(v1->is_unfoldable()) return;
4994 Value *v2=u.expr.v2;
4995 if(v2->is_unfoldable()) return;
4996 Error_Context cntxt(this, "In operation `%s'", get_opname());
4997 size_t i1=v1->get_val_strlen();
4998 size_t i2=v2->get_val_strlen();
4999 if(i1!=i2) {
5000 error("The operands should have the same length");
5001 set_valuetype(V_ERROR);
5002 }
5003 }
5004
5005 void Value::chk_expr_operands_replace()
5006 {
5007 // The fourth operand doesn't need to be checked at all here.
5008 if(valuetype==V_ERROR) return;
5009 if(u.expr.state==EXPR_CHECKING_ERR) return;
5010 Value* v1 = u.expr.ti1->get_specific_value();
5011 if (!v1) return;
5012
5013 Error_Context cntxt(this, "In operation `%s'", get_opname());
5014 size_t list_len = 0;
5015 bool list_len_known = false;
5016 if (v1->valuetype == V_REFD) {
5017 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5018 if (subrefs && subrefs->refers_to_string_element()) {
5019 warning("Replacing a string element does not make any sense");
5020 list_len = 1;
5021 list_len_known = true;
5022 }
5023 }
5024 if (!v1->is_unfoldable()) {
5025 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5026 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5027 list_len_known = true;
5028 }
5029 if (!list_len_known) return;
5030 if (u.expr.v2->is_unfoldable()) {
5031 if (!u.expr.v3->is_unfoldable()) {
5032 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5033 if (*len_int_3 > static_cast<Int>(list_len)) {
5034 error("Third operand `len' (%s) is greater than the length of "
5035 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5036 (unsigned long)list_len);
5037 set_valuetype(V_ERROR);
5038 }
5039 }
5040 } else {
5041 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5042 if (u.expr.v3->is_unfoldable()) {
5043 if (*index_int_2 > static_cast<Int>(list_len)) {
5044 error("Second operand `index' (%s) is greater than the length of "
5045 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5046 (unsigned long)list_len);
5047 set_valuetype(V_ERROR);
5048 }
5049 } else {
5050 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5051 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5052 error("The sum of second operand `index' (%s) and third operand "
5053 "`len' (%s) is greater than the length of the first operand (%lu)",
5054 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5055 (unsigned long)list_len);
5056 set_valuetype(V_ERROR);
5057 }
5058 }
5059 }
5060 }
5061
5062 void Value::chk_expr_operands_substr()
5063 {
5064 if(valuetype==V_ERROR) return;
5065 if(u.expr.state==EXPR_CHECKING_ERR) return;
5066 Value* v1 = u.expr.ti1->get_specific_value();
5067 if (!v1) return;
5068
5069 Error_Context cntxt(this, "In operation `%s'", get_opname());
5070 size_t list_len = 0;
5071 bool list_len_known = false;
5072 if (v1->valuetype == V_REFD) {
5073 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5074 if (subrefs && subrefs->refers_to_string_element()) {
5075 warning("Taking the substring of a string element does not make any "
5076 "sense");
5077 list_len = 1;
5078 list_len_known = true;
5079 }
5080 }
5081 if (!list_len_known && !v1->is_unfoldable()) {
5082 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5083 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5084 list_len_known = true;
5085 }
5086 // Do nothing if the length of the first operand is unknown.
5087 if (!list_len_known) return;
5088 if (u.expr.v2->is_unfoldable()) {
5089 if (!u.expr.v3->is_unfoldable()) {
5090 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5091 // Only the third operand is known.
5092 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5093 error("Third operand `returncount' (%s) is greater than the "
5094 "length of the first operand (%lu)",
5095 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5096 set_valuetype(V_ERROR);
5097 }
5098 }
5099 } else {
5100 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5101 if (u.expr.v3->is_unfoldable()) {
5102 // Only the second operand is known.
5103 if (*index_int_2 > static_cast<Int>(list_len)) {
5104 error("Second operand `index' (%s) is greater than the length "
5105 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5106 (unsigned long)list_len);
5107 set_valuetype(V_ERROR);
5108 }
5109 } else {
5110 // Both second and third operands are known.
5111 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5112 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5113 error("The sum of second operand `index' (%s) and third operand "
5114 "`returncount' (%s) is greater than the length of the first operand "
5115 "(%lu)", (index_int_2->t_str()).c_str(),
5116 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5117 set_valuetype(V_ERROR);
5118 }
5119 }
5120 }
5121 }
5122
5123 void Value::chk_expr_operands_regexp()
5124 {
5125 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5126 Value* v1 = u.expr.ti1->get_specific_value();
5127 Value* v2 = u.expr.t2->get_specific_value();
5128 if (!v1 || !v2) return;
5129
5130 Error_Context cntxt(this, "In operation `regexp()'");
5131 Value* v1_last = v1->get_value_refd_last();
5132 if (v1_last->valuetype == V_CSTR) {
5133 // the input string is available at compile time
5134 const string& instr = v1_last->get_val_str();
5135 const char *input_str = instr.c_str();
5136 size_t instr_len = strlen(input_str);
5137 if (instr_len < instr.size()) {
5138 v1->warning("The first operand of `regexp()' contains a "
5139 "character with character code zero at index %s. The rest of the "
5140 "string will be ignored during matching",
5141 Int2string(instr_len).c_str());
5142 }
5143 }
5144
5145 size_t nof_groups = 0;
5146 Value *v2_last = v2->get_value_refd_last();
5147
5148 if (v2_last->valuetype == V_CSTR) {
5149 // the pattern is available at compile time
5150 const string& expression = v2_last->get_val_str();
5151 const char *pattern_str = expression.c_str();
5152 size_t pattern_len = strlen(pattern_str);
5153 if (pattern_len < expression.size()) {
5154 v2->warning("The second operand of `regexp()' contains a "
5155 "character with character code zero at index %s. The rest of the "
5156 "string will be ignored during matching",
5157 Int2string(pattern_len).c_str());
5158 }
5159 char *posix_str;
5160 {
5161 Error_Context cntxt2(v2, "In character string pattern");
5162 posix_str = TTCN_pattern_to_regexp(pattern_str);
5163 }
5164 if (posix_str != NULL) {
5165 regex_t posix_regexp;
5166 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5167 if (ret_val != 0) {
5168 char msg[512];
5169 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5170 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5171 "regcomp() failed: %s", msg);
5172 }
5173 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5174 else {
5175 v2->error("The character pattern in the second operand of "
5176 "`regexp()' does not contain any groups");
5177 set_valuetype(V_ERROR);
5178 }
5179 regfree(&posix_regexp);
5180 Free(posix_str);
5181 } else {
5182 // the pattern is faulty
5183 // the error has been reported by TTCN_pattern_to_regexp
5184 set_valuetype(V_ERROR);
5185 }
5186 }
5187 if (nof_groups > 0) {
5188 Value *v3 = u.expr.v3->get_value_refd_last();
5189 if (v3->valuetype == V_INT) {
5190 // the group number is available at compile time
5191 const int_val_t *groupno_int = v3->get_val_Int();
5192 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5193 u.expr.v3->error("The the third operand of `regexp()' is too "
5194 "large: The requested group index is %s, but the pattern "
5195 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5196 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5197 set_valuetype(V_ERROR);
5198 }
5199 }
5200 }
5201 }
5202
5203 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5204 Type::expected_value_t exp_val)
5205 {
5206 const char *opname = get_opname();
5207 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5208 Type *t_governor;
5209 const Location *loc;
5210 bool error_flag = false;
5211 switch (u.expr.v_optype) {
5212 case OPTYPE_ISCHOSEN_V:
5213 // u.expr.v1 is always a referenced value
5214 t_governor = u.expr.v1->get_expr_governor(exp_val);
5215 if (t_governor) {
5216 u.expr.v1->set_my_governor(t_governor);
5217 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5218 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5219 } else error_flag = true;
5220 loc = u.expr.v1;
5221 break;
5222 case OPTYPE_ISCHOSEN_T:
5223 // u.expr.t1 is always a referenced template
5224 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5225 exp_val = Type::EXPECTED_TEMPLATE;
5226 t_governor = u.expr.t1->get_expr_governor(exp_val);
5227 if (t_governor) {
5228 u.expr.t1->set_my_governor(t_governor);
5229 //
5230 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5231 //
5232 u.expr.t1->get_template_refd_last(refch);
5233 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5234 error_flag = true;
5235 } else error_flag = true;
5236 if (exp_val != Type::EXPECTED_TEMPLATE) {
5237 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5238 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5239 u.expr.t1->get_reference()->get_refd_assignment()
5240 ->get_description().c_str());
5241 error_flag = true;
5242 }
5243 loc = u.expr.t1;
5244 break;
5245 default:
5246 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5247 t_governor = 0;
5248 loc = 0;
5249 }
5250 if (t_governor) {
5251 t_governor = t_governor->get_type_refd_last();
5252 switch (t_governor->get_typetype()) {
5253 case Type::T_ERROR:
5254 error_flag = true;
5255 break;
5256 case Type::T_CHOICE_A:
5257 case Type::T_CHOICE_T:
5258 case Type::T_ANYTYPE:
5259 case Type::T_OPENTYPE:
5260 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5261 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5262 "%s does not have a field named `%s'" :
5263 "Union type `%s' does not have a field named `%s'",
5264 t_governor->get_typename().c_str(),
5265 u.expr.i2->get_dispname().c_str());
5266 error_flag = true;
5267 }
5268 break;
5269 default:
5270 loc->error("The operand of operation `%s' should be a union value "
5271 "or template instead of `%s'", opname,
5272 t_governor->get_typename().c_str());
5273 error_flag = true;
5274 break;
5275 }
5276 }
5277 if (error_flag) set_valuetype(V_ERROR);
5278 }
5279
5280 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5281 Type::expected_value_t exp_val) {
5282
5283 Error_Context cntxt(this, "In the parameter of encvalue()");
5284 Type t_chk(Type::T_ERROR);
5285 Type* t_type;
5286
5287 Type::expected_value_t ti_exp_val = exp_val;
5288 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5289 ti_exp_val = Type::EXPECTED_TEMPLATE;
5290
5291 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5292 if (t_type) {
5293 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5294 if (valuetype!=V_ERROR)
5295 u.expr.ti1->get_Template()->chk_specific_value(false);
5296 t_type = t_type->get_type_refd_last();
5297 } else {
5298 error("Cannot determine type of value");
5299 goto error;
5300 }
5301
5302 // todo: fix this
5303 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5304 error("Expecting a value of a type with coding attributes in first"
5305 "parameter of encvalue() which belongs to a generic type '%s'",
5306 t_type->get_typename().c_str());
5307 goto error;
5308 }*/
5309
5310 if(!disable_attribute_validation()) {
5311 t_type->chk_coding(true);
5312 }
5313
5314 switch (t_type->get_typetype()) {
5315 case Type::T_UNDEF:
5316 case Type::T_ERROR:
5317 case Type::T_NULL:
5318 case Type::T_REFD:
5319 case Type::T_REFDSPEC:
5320 case Type::T_SELTYPE:
5321 case Type::T_VERDICT:
5322 case Type::T_PORT:
5323 case Type::T_COMPONENT:
5324 case Type::T_DEFAULT:
5325 case Type::T_SIGNATURE:
5326 case Type::T_FUNCTION:
5327 case Type::T_ALTSTEP:
5328 case Type::T_TESTCASE:
5329 error("Type of parameter of encvalue() cannot be '%s'",
5330 t_type->get_typename().c_str());
5331 goto error;
5332 default:
5333 break;
5334 }
5335 return;
5336error:
5337 set_valuetype(V_ERROR);
5338 }
5339
5340 void Value::chk_expr_operands_decode()
5341 {
5342 Error_Context cntxt(this, "In the parameters of decvalue()");
5343 Ttcn::Ref_base* ref = u.expr.r1;
5344 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5345 Type* t_type = 0;
5346 Assignment* t_ass = ref->get_refd_assignment();
5347
5348 if (!t_ass) {
5349 error("Could not determine the assignment for first parameter");
5350 goto error;
5351 }
5352 switch (t_ass->get_asstype()) {
5353 case Assignment::A_PAR_VAL_IN:
5354 t_ass->use_as_lvalue(*this);
5355 break;
5356 case Assignment::A_CONST:
5357 case Assignment::A_EXT_CONST:
5358 case Assignment::A_MODULEPAR:
5359 case Assignment::A_MODULEPAR_TEMP:
5360 case Assignment::A_TEMPLATE:
5361 ref->error("Reference to '%s' cannot be used as the first operand of "
5362 "the 'decvalue' operation", t_ass->get_assname());
5363 goto error;
5364 break;
5365 case Assignment::A_VAR:
5366 case Assignment::A_PAR_VAL_OUT:
5367 case Assignment::A_PAR_VAL_INOUT:
5368 break;
5369 case Assignment::A_VAR_TEMPLATE:
5370 case Assignment::A_PAR_TEMPL_IN:
5371 case Assignment::A_PAR_TEMPL_OUT:
5372 case Assignment::A_PAR_TEMPL_INOUT: {
5373 Template* t = new Template(ref->clone());
5374 t->set_location(*ref);
5375 t->set_my_scope(get_my_scope());
5376 t->set_fullname(get_fullname()+".<operand>");
5377 Template* t_last = t->get_template_refd_last();
5378 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5379 && t_last != t) {
5380 ref->error("Specific value template was expected instead of '%s'.",
5381 t->get_template_refd_last()->get_templatetype_str());
5382 delete t;
5383 goto error;
5384 }
5385 delete t;
5386 break; }
5387 default:
5388 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5389 goto error;
5390 }
5391 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5392 Type::EXPECTED_DYNAMIC_VALUE);
5393 if (!t_type) {
5394 goto error;
5395 }
5396 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5397 error("First parameter has to be a bitstring");
5398 goto error;
5399 }
5400
5401 ref = u.expr.r2;
5402 t_subrefs = ref->get_subrefs();
5403 t_ass = ref->get_refd_assignment();
5404
5405 if (!t_ass) {
5406 error("Could not determine the assignment for second parameter");
5407 goto error;
5408 }
5409 // Extra check for HM59355.
5410 switch (t_ass->get_asstype()) {
5411 case Assignment::A_VAR:
5412 case Assignment::A_PAR_VAL_IN:
5413 case Assignment::A_PAR_VAL_OUT:
5414 case Assignment::A_PAR_VAL_INOUT:
5415 break;
5416 default:
5417 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5418 goto error;
5419 }
5420 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5421 Type::EXPECTED_DYNAMIC_VALUE);
5422 if (!t_type) {
5423 goto error;
5424 }
5425 t_type = t_type->get_type_refd_last();
5426 switch (t_type->get_typetype()) {
5427 case Type::T_UNDEF:
5428 case Type::T_ERROR:
5429 case Type::T_NULL:
5430 case Type::T_REFD:
5431 case Type::T_REFDSPEC:
5432 case Type::T_SELTYPE:
5433 case Type::T_VERDICT:
5434 case Type::T_PORT:
5435 case Type::T_COMPONENT:
5436 case Type::T_DEFAULT:
5437 case Type::T_SIGNATURE:
5438 case Type::T_FUNCTION:
5439 case Type::T_ALTSTEP:
5440 case Type::T_TESTCASE:
5441 error("Type of second parameter cannot be %s",
5442 t_type->get_typename().c_str());
5443 goto error;
5444 default:
5445 break;
5446 }
5447
5448 if(!disable_attribute_validation()) {
5449 t_type->chk_coding(false);
5450 }
5451
5452 return;
5453 error:
5454 set_valuetype(V_ERROR);
5455 }
5456
5457 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5458 {
5459 Ttcn::FieldOrArrayRefs *subrefs;
5460 Identifier *field_id = 0;
5461 Assignment *t_ass;
5462 Type *t_type;
5463 if (valuetype == V_ERROR) return;
5464 else if (valuetype != V_REFD) {
5465 error("Only a referenced value can be compared with `omit'");
5466 goto error;
5467 }
5468 subrefs = u.ref.ref->get_subrefs();
5469 if (subrefs) field_id = subrefs->remove_last_field();
5470 if (!field_id) {
5471 error("Only a reference pointing to an optional record or set field "
5472 "can be compared with `omit'");
5473 goto error;
5474 }
5475 t_ass = u.ref.ref->get_refd_assignment();
5476 if (!t_ass) goto error;
5477 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5478 if (!t_type) goto error;
5479 t_type = t_type->get_type_refd_last();
5480 switch (t_type->get_typetype()) {
5481 case Type::T_ERROR:
5482 goto error;
5483 case Type::T_SEQ_A:
5484 case Type::T_SEQ_T:
5485 case Type::T_SET_A:
5486 case Type::T_SET_T:
5487 break;
5488 default:
5489 error("Only a reference pointing to an optional field of a record"
5490 " or set type can be compared with `omit'");
5491 goto error;
5492 }
5493 if (!t_type->has_comp_withName(*field_id)) {
5494 error("Type `%s' does not have field named `%s'",
5495 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5496 goto error;
5497 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5498 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5499 "`omit'", field_id->get_dispname().c_str(),
5500 t_type->get_typename().c_str());
5501 goto error;
5502 }
5503 // putting the last field_id back to subrefs
5504 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5505 return;
5506 error:
5507 set_valuetype(V_ERROR);
5508 delete field_id;
5509 }
5510
5511 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5512 Type::expected_value_t exp_val)
5513 {
5514 if(valuetype==V_ERROR) return -1;
5515 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5516 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5517 exp_val=Type::EXPECTED_TEMPLATE;
5518
5519 Error_Context cntxt(this, "In the operand of"
5520 " operation `%s'", get_opname());
5521
5522 Int result = -1;
5523 Template* t_templ = u.expr.ti1->get_Template();
5524
5525 if (!t_templ) {
5526 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5527 }
5528
5529 t_templ = t_templ->get_template_refd_last(refch);
5530
5531 // Timer and port arrays are handled separately
5532 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5533 Value* val = t_templ->get_specific_value();
5534 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5535 val->set_lowerid_to_ref();
5536 }
5537 if (val && val->get_valuetype() == V_REFD) {
5538 Reference* ref = val->get_reference();
5539 Assignment* t_ass = ref->get_refd_assignment();
5540 Common::Assignment::asstype_t asstype =
5541 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5542 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5543 if (t_ass->get_Dimensions()) {
5544 // here we have a timer or port array
5545 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5546 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5547 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5548 Type::EXPECTED_DYNAMIC_VALUE);
5549 size_t refd_dim;
5550 if (t_subrefs) {
5551 refd_dim = t_subrefs->get_nof_refs();
5552 size_t nof_dims = t_dims->get_nof_dims();
5553 if (refd_dim >= nof_dims) {
5554 u.expr.ti1->error("Operation is not applicable to a %s",
5555 t_ass->get_assname());
5556 set_valuetype(V_ERROR);
5557 return -1;
5558 }
5559 } else refd_dim = 0;
5560 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5561 } else {
5562 u.expr.ti1->error("Operation is not applicable to single `%s'",
5563 t_ass->get_description().c_str());
5564 set_valuetype(V_ERROR);
5565 return -1;
5566 }
5567 }
5568 }
5569 }
5570
5571 Value* t_val = 0;
5572 Type* t_type = 0;
5573 Assignment* t_ass = 0;
5574 Reference* ref = 0;
5575 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5576 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5577 if (t_type) {
5578 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5579 t_type = t_type->get_type_refd_last();
5580 } else {
5581 error("Cannot determine type of value");
5582 goto error;
5583 }
5584
5585 if(valuetype==V_ERROR) return -1;
5586
5587 t_templ = t_templ->get_template_refd_last(refch);
5588 switch(t_templ->get_templatetype()) {
5589 case Template::TEMPLATE_ERROR:
5590 goto error;
5591 case Template::INDEXED_TEMPLATE_LIST:
5592 return -1;
5593 case Template::TEMPLATE_REFD:
5594 case Template::TEMPLATE_LIST:
5595 case Template::NAMED_TEMPLATE_LIST:
5596 // computed later
5597 break;
5598 case Template::SPECIFIC_VALUE:
5599 {
5600 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5601 if(t_val) {
5602 switch(t_val->get_valuetype()) {
5603 case V_SEQOF:
5604 case V_SETOF:
5605 case V_ARRAY:
5606 case V_ROID:
5607 case V_OID:
5608 case V_SEQ:
5609 case V_SET:
5610 break;
5611 case V_REFD: {
5612 ref = t_val->get_reference();
5613 t_ass = ref->get_refd_assignment();
5614 t_subrefs = ref->get_subrefs();
5615 break;
5616 }
5617 default:
5618 u.expr.ti1->error("Operation is not applicable to `%s'",
5619 t_val->create_stringRepr().c_str());
5620 goto error;
5621 }
5622 }
5623 break;
5624 }
5625 default:
5626 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5627 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5628 goto error;
5629 } // switch
5630
5631 if (t_ass) {
5632 switch(t_ass->get_asstype()) {
5633 case Assignment::A_ERROR:
5634 goto error;
5635 case Assignment::A_CONST:
5636 t_val = t_ass->get_Value();
5637 break;
5638 case Assignment::A_EXT_CONST:
5639 case Assignment::A_MODULEPAR:
5640 case Assignment::A_MODULEPAR_TEMP:
5641 if(exp_val==Type::EXPECTED_CONSTANT) {
5642 u.expr.ti1->error("Reference to an (evaluatable) constant value was "
5643 "expected instead of %s", t_ass->get_description().c_str());
5644 goto error;
5645 }
5646 break;
5647 case Assignment::A_VAR:
5648 case Assignment::A_PAR_VAL_IN:
5649 case Assignment::A_PAR_VAL_OUT:
5650 case Assignment::A_PAR_VAL_INOUT:
5651 switch(exp_val) {
5652 case Type::EXPECTED_CONSTANT:
5653 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5654 t_ass->get_description().c_str());
5655 goto error;
5656 break;
5657 case Type::EXPECTED_STATIC_VALUE:
5658 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5659 t_ass->get_description().c_str());
5660 goto error;
5661 break;
5662 default:
5663 break;
5664 }
5665 break;
5666 case Assignment::A_TEMPLATE:
5667 t_templ = t_ass->get_Template();
5668 // no break
5669 case Assignment::A_VAR_TEMPLATE:
5670 case Assignment::A_PAR_TEMPL_IN:
5671 case Assignment::A_PAR_TEMPL_OUT:
5672 case Assignment::A_PAR_TEMPL_INOUT:
5673 if (exp_val!=Type::EXPECTED_TEMPLATE)
5674 u.expr.ti1->error("Reference to a value was expected instead of %s",
5675 t_ass->get_description().c_str());
5676 goto error;
5677 break;
5678 case Assignment::A_FUNCTION_RVAL:
5679 case Assignment::A_EXT_FUNCTION_RVAL:
5680 switch(exp_val) {
5681 case Type::EXPECTED_CONSTANT:
5682 u.expr.ti1->error("Reference to a constant value was expected instead of "
5683 "the return value of %s", t_ass->get_description().c_str());
5684 goto error;
5685 break;
5686 case Type::EXPECTED_STATIC_VALUE:
5687 u.expr.ti1->error("Reference to a static value was expected instead of "
5688 "the return value of %s", t_ass->get_description().c_str());
5689 goto error;
5690 break;
5691 default:
5692 break;
5693 }
5694 break;
5695 case Assignment::A_FUNCTION_RTEMP:
5696 case Assignment::A_EXT_FUNCTION_RTEMP:
5697 if(exp_val!=Type::EXPECTED_TEMPLATE)
5698 u.expr.ti1->error("Reference to a value was expected instead of a call"
5699 " of %s, which returns a template",
5700 t_ass->get_description().c_str());
5701 goto error;
5702 break;
5703 case Assignment::A_TIMER:
5704 case Assignment::A_PORT:
5705 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5706 // sizeof is applicable to timer and port arrays
5707 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5708 if (!t_dims) {
5709 u.expr.ti1->error("Operation is not applicable to single %s",
5710 t_ass->get_description().c_str());
5711 goto error;
5712 }
5713 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5714 Type::EXPECTED_DYNAMIC_VALUE);
5715 size_t refd_dim;
5716 if (t_subrefs) {
5717 refd_dim = t_subrefs->get_nof_refs();
5718 size_t nof_dims = t_dims->get_nof_dims();
5719 if (refd_dim > nof_dims) goto error;
5720 else if (refd_dim == nof_dims) {
5721 u.expr.ti1->error("Operation is not applicable to a %s",
5722 t_ass->get_assname());
5723 goto error;
5724 }
5725 } else refd_dim = 0;
5726 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5727 }
5728 // no break
5729 default:
5730 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5731 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5732 t_ass->get_description().c_str());
5733 goto error;
5734 } // end switch
5735
5736 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5737 if (!t_type) goto error;
5738 t_type = t_type->get_type_refd_last();
5739
5740 switch(t_type->get_typetype()) {
5741 case Type::T_ERROR:
5742 goto error;
5743 case Type::T_SEQOF:
5744 case Type::T_SETOF:
5745 // no break
5746 case Type::T_SEQ_T:
5747 case Type::T_SET_T:
5748 case Type::T_SEQ_A:
5749 case Type::T_SET_A:
5750 case Type::T_ARRAY:
5751 // ok
5752 break;
5753 case Type::T_OID:
5754 case Type::T_ROID:
5755 break;
5756 default:
5757 u.expr.ti1->error("Reference to value or template of type record, record of,"
5758 " set, set of, objid or array was expected");
5759 goto error;
5760 } // switch
5761 }
5762
5763 // check for index overflows in subrefs if possible
5764 if (t_val) {
5765 switch (t_val->get_valuetype()) {
5766 case V_SEQOF:
5767 case V_SETOF:
5768 case V_ARRAY:
5769 if (t_val->is_indexed()) {
5770 return -1;
5771 }
5772 break;
5773 default:
5774 break;
5775 }
5776 /* The reference points to a constant. */
5777 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5778 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5779 if (!t_val) goto error;
5780 t_val=t_val->get_value_refd_last(refch);
5781 } else { t_val = 0; }
5782 } else if (t_templ) {
5783 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5784 time. Don't try to evaluate it at compile time. */
5785 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5786 return -1;
5787 /* The reference points to a static template. */
5788 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5789 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5790 if (!t_templ) goto error;
5791 t_templ = t_templ->get_template_refd_last(refch);
5792 } else { t_templ = 0; }
5793 }
5794
5795 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5796 if(t_templ) {
5797 switch(t_templ->get_templatetype()) {
5798 case Template::TEMPLATE_ERROR:
5799 goto error;
5800 case Template::TEMPLATE_REFD:
5801 // not foldable
5802 t_templ=0;
5803 break;
5804 case Template::SPECIFIC_VALUE:
5805 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5806 t_templ=0;
5807 break;
5808 case Template::TEMPLATE_LIST:
5809 case Template::NAMED_TEMPLATE_LIST:
5810 break;
5811 default:
5812 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5813 t_templ->get_templatetype_str(),
5814 t_templ->get_fullname().c_str());
5815 goto error;
5816 } // switch
5817 }
5818 if(t_val) {
5819 switch(t_val->get_valuetype()) {
5820 case V_SEQOF:
5821 case V_SETOF:
5822 case V_ARRAY:
5823 case V_SEQ:
5824 case V_SET:
5825 case V_OID:
5826 case V_ROID:
5827 // ok
5828 break;
5829 default:
5830 // error is already reported
5831 t_val=0;
5832 break;
5833 } // switch
5834 }
5835 }
5836
5837 /* evaluation */
5838
5839 if(t_type->get_typetype()==Type::T_ARRAY) {
5840 result = t_type->get_dimension()->get_size();
5841 }
5842 else if(t_templ) { // sizeof()
5843 switch(t_templ->get_templatetype()) {
5844 case Template::TEMPLATE_LIST:
5845 if(t_templ->temps_contains_anyornone_symbol()) {
5846 if(t_templ->is_length_restricted()) {
5847 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5848 if (lr->get_is_range()) {
5849 Value *v_upper = lr->get_upper_value();
5850 if (v_upper) {
5851 if (v_upper->valuetype == V_INT) {
5852 Int nof_comps =
5853 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5854 if (v_upper->u.val_Int->get_val() == nof_comps)
5855 result = nof_comps;
5856 else {
5857 u.expr.ti1->error("`sizeof' operation is not applicable for "
5858 "templates without exact size");
5859 goto error;
5860 }
5861 }
5862 } else {
5863 u.expr.ti1->error("`sizeof' operation is not applicable for "
5864 "templates containing `*' without upper boundary in the "
5865 "length restriction");
5866 goto error;
5867 }
5868 } else {
5869 Value *v_single = lr->get_single_value();
5870 if (v_single->valuetype == V_INT)
5871 result = v_single->u.val_Int->get_val();
5872 }
5873 }
5874 else { // not length restricted
5875 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
5876 " containing `*' without length restriction");
5877 goto error;
5878 }
5879 }
5880 else result=t_templ->get_nof_listitems();
5881 break;
5882 case Template::NAMED_TEMPLATE_LIST:
5883 result=0;
5884 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
5885 if(t_templ->get_namedtemp_byIndex(i)->get_template()
5886 ->get_templatetype()!=Template::OMIT_VALUE) result++;
5887 return result;
5888 default:
5889 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5890 } // switch
5891 }
5892 else if(t_val) {
5893 switch(t_val->get_valuetype()) {
5894 case V_SEQOF:
5895 case V_SETOF:
5896 case V_ARRAY:
5897
5898 case V_OID:
5899 case V_ROID:
5900 result=t_val->get_nof_comps();
5901 break;
5902 case V_SEQ:
5903 case V_SET:
5904 result=0;
5905 for(size_t i=0; i<t_val->get_nof_comps(); i++)
5906 if(t_val->get_se_comp_byIndex(i)->get_value()
5907 ->get_valuetype()!=V_OMIT) result++;
5908 break;
5909
5910 default:
5911 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5912 } // switch
5913 }
5914
5915 return result;
5916 error:
5917 set_valuetype(V_ERROR);
5918 return -1;
5919 }
5920
5921 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
5922 {
5923 Type *governor = ti->get_expr_governor(exp_val);
5924 if (!governor) {
5925 ti->get_Template()->set_lowerid_to_ref();
5926 governor = ti->get_expr_governor(exp_val);
5927 }
5928 if (!governor) {
5929 string str;
5930 ti->append_stringRepr( str);
5931 ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5932 "If type is known, use valuof(<type>: %s) as argument.",
5933 str.c_str(), get_opname(), str.c_str());
5934 set_valuetype(V_ERROR);
5935 }
5936 return governor;
5937 }
5938
5939 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
5940 {
5941 start:
5942 Type *governor = u.expr.v1->get_expr_governor(exp_val);
5943 if (!governor) governor = u.expr.t2->get_expr_governor(
5944 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
5945 Type::EXPECTED_TEMPLATE : exp_val);
5946 if (!governor) {
5947 Template *t_temp = u.expr.t2->get_Template();
5948 if (t_temp->is_undef_lowerid()) {
5949 // We convert the template to reference first even if the value is also
5950 // an undef lowerid. The user can prevent this by explicit type
5951 // specification.
5952 t_temp->set_lowerid_to_ref();
5953 goto start;
5954 } else if (u.expr.v1->is_undef_lowerid()) {
5955 u.expr.v1->set_lowerid_to_ref();
5956 goto start;
5957 }
5958 }
5959 if (!governor) {
5960 error("Cannot determine the type of arguments in `match()' operation");
5961 set_valuetype(V_ERROR);
5962 return;
5963 }
5964 u.expr.v1->set_my_governor(governor);
5965 {
5966 Error_Context cntxt(this, "In the first argument of `match()'"
5967 " operation");
5968 governor->chk_this_value_ref(u.expr.v1);
5969 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
5970 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
5971 }
5972 {
5973 Error_Context cntxt(this, "In the second argument of `match()' "
5974 "operation");
5975 u.expr.t2->chk(governor);
5976 }
5977 }
5978
5979 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
5980 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
5981 {
5982 Ttcn::StatementBlock *my_sb;
5983 switch (exp_val) {
5984 case Type::EXPECTED_CONSTANT:
5985 error("An evaluatable constant value was expected instead of operation "
5986 "`%s'", get_opname());
5987 goto error;
5988 case Type::EXPECTED_STATIC_VALUE:
5989 error("A static value was expected instead of operation `%s'",
5990 get_opname());
5991 goto error;
5992 default:
5993 break;
5994 } // switch
5995 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5996 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
5997 if (!my_sb) {
5998 error("Operation `%s' is allowed only within statements",
5999 get_opname());
6000 goto error;
6001 }
6002 if (!allow_controlpart && !my_sb->get_my_def()) {
6003 error("Operation `%s' is not allowed in the control part",
6004 get_opname());
6005 goto error;
6006 }
6007 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6008 error("Operation `%s' cannot be used in a definition that has "
6009 "`runs on' clause", get_opname());
6010 goto error;
6011 }
6012 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6013 error("Operation `%s' can be used only in a definition that has "
6014 "`runs on' clause", get_opname());
6015 goto error;
6016 }
6017 return;
6018 error:
6019 set_valuetype(V_ERROR);
6020 }
6021
6022 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6023 {
6024 if(valuetype==V_ERROR) return;
6025 if(u.expr.state==EXPR_CHECKING_ERR) return;
6026 if(v->is_unfoldable()) return;
6027 if(v->get_expr_returntype()!=Type::T_REAL) return;
6028 ttcn3float r = v->get_val_Real();
6029 if (isSpecialFloatValue(r)) {
6030 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6031 opnum, opname, Real2string(r).c_str());
6032 set_valuetype(V_ERROR);
6033 }
6034 }
6035
6036 void Value::chk_expr_operands(ReferenceChain *refch,
6037 Type::expected_value_t exp_val)
6038 {
6039 const char *first="First", *second="Second", *third="Third",
6040 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6041 Value *v1, *v2, *v3;
6042 Type::typetype_t tt1, tt2, tt3;
6043 Type t_chk(Type::T_ERROR);
6044
6045 const char *opname=get_opname();
6046
6047 // first classify the unchecked ischosen() operation
6048 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6049
6050 switch (u.expr.v_optype) {
6051 case OPTYPE_COMP_NULL:
6052 case OPTYPE_TESTCASENAME:
6053 break;
6054 case OPTYPE_COMP_MTC:
6055 case OPTYPE_COMP_SYSTEM:
6056 chk_expr_comptype_compat();
6057 break;
6058 case OPTYPE_RND: // -
6059 case OPTYPE_TMR_RUNNING_ANY:
6060 chk_expr_dynamic_part(exp_val, true);
6061 break;
6062 case OPTYPE_COMP_RUNNING_ANY:
6063 case OPTYPE_COMP_RUNNING_ALL:
6064 case OPTYPE_COMP_ALIVE_ANY:
6065 case OPTYPE_COMP_ALIVE_ALL:
6066 case OPTYPE_GETVERDICT:
6067 chk_expr_dynamic_part(exp_val, false);
6068 break;
6069 case OPTYPE_COMP_SELF:
6070 chk_expr_comptype_compat();
6071 chk_expr_dynamic_part(exp_val, false, true, false);
6072 break;
6073 case OPTYPE_UNARYPLUS: // v1
6074 case OPTYPE_UNARYMINUS:
6075 v1=u.expr.v1;
6076 {
6077 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6078 v1->set_lowerid_to_ref();
6079 tt1=v1->get_expr_returntype(exp_val);
6080 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6081 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6082 }
6083 break;
6084 case OPTYPE_NOT:
6085 v1=u.expr.v1;
6086 {
6087 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6088 v1->set_lowerid_to_ref();
6089 tt1=v1->get_expr_returntype(exp_val);
6090 chk_expr_operandtype_bool(tt1, the, opname, v1);
6091 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6092 }
6093 break;
6094 case OPTYPE_NOT4B:
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_binstr(tt1, the, opname, v1);
6101 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6102 }
6103 break;
6104 case OPTYPE_BIT2HEX:
6105 case OPTYPE_BIT2OCT:
6106 case OPTYPE_BIT2STR:
6107 v1=u.expr.v1;
6108 {
6109 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6110 v1->set_lowerid_to_ref();
6111 tt1=v1->get_expr_returntype(exp_val);
6112 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6113 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6114 }
6115 break;
6116 case OPTYPE_BIT2INT:
6117 v1=u.expr.v1;
6118 {
6119 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6120 v1->set_lowerid_to_ref();
6121 tt1=v1->get_expr_returntype(exp_val);
6122 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6123 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6124 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6125 }
6126 break;
6127 case OPTYPE_CHAR2INT:
6128 v1=u.expr.v1;
6129 {
6130 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6131 v1->set_lowerid_to_ref();
6132 tt1=v1->get_expr_returntype(exp_val);
6133 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6134 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6135 chk_expr_val_len1(v1, the, opname);
6136 }
6137 break;
6138 case OPTYPE_CHAR2OCT:
6139 v1=u.expr.v1;
6140 {
6141 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6142 v1->set_lowerid_to_ref();
6143 tt1=v1->get_expr_returntype(exp_val);
6144 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6145 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6146 }
6147 break;
6148 case OPTYPE_STR2INT:
6149 v1=u.expr.v1;
6150 {
6151 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6152 v1->set_lowerid_to_ref();
6153 tt1=v1->get_expr_returntype(exp_val);
6154 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6155 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6156 chk_expr_val_str_int(v1, the, opname);
6157 }
6158 break;
6159 case OPTYPE_STR2FLOAT:
6160 v1=u.expr.v1;
6161 {
6162 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6163 v1->set_lowerid_to_ref();
6164 tt1=v1->get_expr_returntype(exp_val);
6165 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6166 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6167 chk_expr_val_str_float(v1, the, opname);
6168 }
6169 break;
6170 case OPTYPE_STR2BIT:
6171 v1=u.expr.v1;
6172 {
6173 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6174 v1->set_lowerid_to_ref();
6175 tt1=v1->get_expr_returntype(exp_val);
6176 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6177 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6178 chk_expr_val_str_bindigits(v1, the, opname);
6179 }
6180 break;
6181 case OPTYPE_STR2HEX:
6182 v1=u.expr.v1;
6183 {
6184 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6185 v1->set_lowerid_to_ref();
6186 tt1=v1->get_expr_returntype(exp_val);
6187 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6188 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6189 chk_expr_val_str_hexdigits(v1, the, opname);
6190 }
6191 break;
6192 case OPTYPE_STR2OCT:
6193 v1=u.expr.v1;
6194 {
6195 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6196 v1->set_lowerid_to_ref();
6197 tt1=v1->get_expr_returntype(exp_val);
6198 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6199 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6200 chk_expr_val_str_len_even(v1, the, opname);
6201 chk_expr_val_str_hexdigits(v1, the, opname);
6202 }
6203 break;
6204 case OPTYPE_ENUM2INT:
6205 v1=u.expr.v1;
6206 {
6207 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6208 chk_expr_operandtype_enum(opname, v1, exp_val);
6209 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6210 }
6211 break;
6212 case OPTYPE_ENCODE:
6213 chk_expr_operand_encode(refch, exp_val);
6214 break;
6215 case OPTYPE_FLOAT2INT:
6216 case OPTYPE_FLOAT2STR:
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 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6225 chk_expr_operand_valid_float(v1, the, opname);
6226 }
6227 break;
6228 case OPTYPE_RNDWITHVAL:
6229 v1=u.expr.v1;
6230 {
6231 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6232 v1->set_lowerid_to_ref();
6233 tt1=v1->get_expr_returntype(exp_val);
6234 chk_expr_operandtype_float(tt1, the, opname, v1);
6235 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6236 chk_expr_operand_valid_float(v1, the, opname);
6237 }
6238 chk_expr_dynamic_part(exp_val, true);
6239 break;
6240 case OPTYPE_HEX2BIT:
6241 case OPTYPE_HEX2OCT:
6242 case OPTYPE_HEX2STR:
6243 v1=u.expr.v1;
6244 {
6245 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6246 v1->set_lowerid_to_ref();
6247 tt1=v1->get_expr_returntype(exp_val);
6248 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6249 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6250 }
6251 break;
6252 case OPTYPE_HEX2INT:
6253 v1=u.expr.v1;
6254 {
6255 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6256 v1->set_lowerid_to_ref();
6257 tt1=v1->get_expr_returntype(exp_val);
6258 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6259 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6260 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6261 }
6262 break;
6263 case OPTYPE_INT2CHAR:
6264 v1=u.expr.v1;
6265 {
6266 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6267 v1->set_lowerid_to_ref();
6268 tt1=v1->get_expr_returntype(exp_val);
6269 chk_expr_operandtype_int(tt1, the, opname, v1);
6270 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6271 chk_expr_val_int_pos7bit(v1, the, opname);
6272 }
6273 break;
6274 case OPTYPE_INT2UNICHAR:
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 chk_expr_val_int_pos31bit(v1, first, opname);
6283 }
6284 break;
6285 case OPTYPE_INT2FLOAT:
6286 case OPTYPE_INT2STR:
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_int(tt1, the, opname, v1);
6293 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6294 }
6295 break;
6296 case OPTYPE_OCT2BIT:
6297 case OPTYPE_OCT2HEX:
6298 case OPTYPE_OCT2STR:
6299 v1=u.expr.v1;
6300 {
6301 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6302 v1->set_lowerid_to_ref();
6303 tt1=v1->get_expr_returntype(exp_val);
6304 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6305 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6306 }
6307 break;
6308 case OPTYPE_OCT2INT:
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 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6317 // now.
6318 }
6319 break;
6320 case OPTYPE_OCT2CHAR:
6321 v1=u.expr.v1;
6322 {
6323 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6324 v1->set_lowerid_to_ref();
6325 tt1=v1->get_expr_returntype(exp_val);
6326 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6327 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6328 chk_expr_val_str_7bitoctets(v1, the, opname);
6329 }
6330 break;
6331 case OPTYPE_REMOVE_BOM:
6332 v1=u.expr.v1;
6333 {
6334 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6335 v1->set_lowerid_to_ref();
6336 tt1=v1->get_expr_returntype(exp_val);
6337 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6338 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6339 }
6340 break;
6341 case OPTYPE_GET_STRINGENCODING:
6342 v1=u.expr.v1;
6343 {
6344 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6345 v1->set_lowerid_to_ref();
6346 tt1=v1->get_expr_returntype(exp_val);
6347 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6348 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6349 }
6350 break;
6351 case OPTYPE_ENCODE_BASE64:
6352 v1=u.expr.v1;
6353 {
6354 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6355 v1->set_lowerid_to_ref();
6356 tt1=v1->get_expr_returntype(exp_val);
6357 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6358 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6359 }
6360 v2=u.expr.v2 ? u.expr.v2 : 0;
6361 if (v2)
6362 {
6363 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6364 v2->set_lowerid_to_ref();
6365 tt2=v2->get_expr_returntype(exp_val);
6366 chk_expr_operandtype_bool(tt2, second, opname, v2);
6367 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6368 }
6369 break;
6370 case OPTYPE_DECODE_BASE64:
6371 v1=u.expr.v1;
6372 {
6373 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6374 v1->set_lowerid_to_ref();
6375 tt1=v1->get_expr_returntype(exp_val);
6376 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6377 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6378 }
6379 break;
6380 case OPTYPE_UNICHAR2INT:
6381 v1=u.expr.v1;
6382 {
6383 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6384 v1->set_lowerid_to_ref();
6385 tt1=v1->get_expr_returntype(exp_val);
6386 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6387 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6388 chk_expr_val_len1(v1, the, opname);
6389 }
6390 break;
6391 case OPTYPE_UNICHAR2CHAR:
6392 v1=u.expr.v1;
6393 {
6394 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6395 v1->set_lowerid_to_ref();
6396 tt1=v1->get_expr_returntype(exp_val);
6397 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6398 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6399 chk_expr_val_ustr_7bitchars(v1, the, opname);
6400 }
6401 break;
6402 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6403 v1=u.expr.v1;
6404 {
6405 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6406 v1->set_lowerid_to_ref();
6407 tt1=v1->get_expr_returntype(exp_val);
6408 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6409 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6410 }
6411 v2=u.expr.v2 ? u.expr.v2 : 0;
6412 if (v2)
6413 {
6414 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6415 v2->set_lowerid_to_ref();
6416 tt2=v2->get_expr_returntype(exp_val);
6417 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6418 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6419 }
6420 break;
6421 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6422 v1=u.expr.v1;
6423 {
6424 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6425 v1->set_lowerid_to_ref();
6426 tt1=v1->get_expr_returntype(exp_val);
6427 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6428 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6429 }
6430 v2=u.expr.v2 ? u.expr.v2 : 0;
6431 if (v2)
6432 {
6433 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6434 v2->set_lowerid_to_ref();
6435 tt2=v2->get_expr_returntype(exp_val);
6436 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6437 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6438 }
6439 break;
6440 case OPTYPE_ADD: // v1 v2
6441 case OPTYPE_SUBTRACT:
6442 case OPTYPE_MULTIPLY:
6443 case OPTYPE_DIVIDE:
6444 v1=u.expr.v1;
6445 {
6446 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6447 v1->set_lowerid_to_ref();
6448 tt1=v1->get_expr_returntype(exp_val);
6449 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6450 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6451 chk_expr_operand_valid_float(v1, first, opname);
6452 }
6453 v2=u.expr.v2;
6454 {
6455 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6456 v2->set_lowerid_to_ref();
6457 tt2=v2->get_expr_returntype(exp_val);
6458 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6459 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6460 chk_expr_operand_valid_float(v2, second, opname);
6461 if(u.expr.v_optype==OPTYPE_DIVIDE)
6462 chk_expr_val_int_float_not0(v2, second, opname);
6463 }
6464 chk_expr_operandtypes_same(tt1, tt2, opname);
6465 break;
6466 case OPTYPE_MOD:
6467 case OPTYPE_REM:
6468 v1=u.expr.v1;
6469 {
6470 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6471 v1->set_lowerid_to_ref();
6472 tt1=v1->get_expr_returntype(exp_val);
6473 chk_expr_operandtype_int(tt1, left, opname, v1);
6474 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6475 }
6476 v2=u.expr.v2;
6477 {
6478 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6479 v2->set_lowerid_to_ref();
6480 tt2=v2->get_expr_returntype(exp_val);
6481 chk_expr_operandtype_int(tt2, right, opname, v2);
6482 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6483 chk_expr_val_int_float_not0(v2, right, opname);
6484 }
6485 break;
6486 case OPTYPE_CONCAT: {
6487 v1=u.expr.v1;
6488 v2=u.expr.v2;
6489 v1->set_lowerid_to_ref();
6490 v2->set_lowerid_to_ref();
6491 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6492 {
6493 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6494 tt1=v1->get_expr_returntype(exp_val);
6495 chk_expr_operandtype_str(tt1, left, opname, v1);
6496 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6497 }
6498 {
6499 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6500 tt2=v2->get_expr_returntype(exp_val);
6501 chk_expr_operandtype_str(tt2, right, opname, v2);
6502 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6503 }
6504 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6505 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6506 chk_expr_operandtypes_same(tt1, tt2, opname);
6507 } else { // other list types
6508 Type* v1_gov = v1->get_expr_governor(exp_val);
6509 Type* v2_gov = v2->get_expr_governor(exp_val);
6510 if (!v1_gov) {
6511 error("Cannot determine the type of the left operand of `%s' operation", opname);
6512 set_valuetype(V_ERROR);
6513 return;
6514 } else {
6515 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6516 v1_gov->chk_this_value_ref(v1);
6517 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6518 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6519 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6520 }
6521 if (!v2_gov) {
6522 if (!v1_gov) {
6523 error("Cannot determine the type of the right operand of `%s' operation", opname);
6524 set_valuetype(V_ERROR);
6525 return;
6526 }
6527 // for recof/setof literals set the type from v1
6528 v2_gov = v1_gov;
6529 v2->set_my_governor(v1_gov);
6530 }
6531 {
6532 Error_Context cntxt(this, "In the right operand of operation `%s'",
6533 opname);
6534 v2_gov->chk_this_value_ref(v2);
6535 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6536 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6537 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6538 if (valuetype == V_ERROR) return;
6539 // 7.1.2 says that we shouldn't allow type compatibility.
6540 if (!v1_gov->is_compatible(v2_gov, NULL)
6541 && !v2_gov->is_compatible(v1_gov, NULL)) {
6542 error("The operands of operation `%s' should be of compatible "
6543 "types", get_opname());
6544 }
6545 }
6546 }
6547 break; }
6548 case OPTYPE_EQ:
6549 case OPTYPE_NE:
6550 v1 = u.expr.v1;
6551 v2 = u.expr.v2;
6552 chk_expr_operandtypes_compat(exp_val, v1, v2);
6553 {
6554 Error_Context cntxt(this, "In the left operand of operation `%s'",
6555 opname);
6556 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6557 }
6558 {
6559 Error_Context cntxt(this, "In the right operand of operation `%s'",
6560 opname);
6561 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6562 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6563 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6564 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6565 * "a == not b" is not allowed. (HL69107)
6566 * The various *Expressions implement operator precedence in the std.
6567 * Titan's parser has only one Expression and relies on Bison
6568 * for operator precedence. The check below brings Titan in line
6569 * with the standard by explicitly making "a == not b" an error */
6570 if (v2->get_valuetype() == V_EXPR
6571 && v2->u.expr.v_optype == OPTYPE_NOT) {
6572 error("The operation `%s' is not allowed to be "
6573 "the second operand of operation `%s'", v2->get_opname(), opname);
6574 set_valuetype(V_ERROR);
6575 }
6576 }
6577 break;
6578 case OPTYPE_LT:
6579 case OPTYPE_GT:
6580 case OPTYPE_GE:
6581 case OPTYPE_LE:
6582 v1=u.expr.v1;
6583 v2=u.expr.v2;
6584 chk_expr_operandtypes_compat(exp_val, v1, v2);
6585 {
6586 Error_Context cntxt(this, "In the left operand of operation `%s'",
6587 opname);
6588 tt1=v1->get_expr_returntype(exp_val);
6589 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6590 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6591 }
6592 {
6593 Error_Context cntxt(this, "In the right operand of operation `%s'",
6594 opname);
6595 tt2=v2->get_expr_returntype(exp_val);
6596 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6597 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6598 }
6599 break;
6600 case OPTYPE_AND:
6601 case OPTYPE_OR:
6602 case OPTYPE_XOR:
6603 v1=u.expr.v1;
6604 {
6605 Error_Context cntxt(this, "In the left operand of operation `%s'",
6606 opname);
6607 v1->set_lowerid_to_ref();
6608 tt1=v1->get_expr_returntype(exp_val);
6609 chk_expr_operandtype_bool(tt1, left, opname, v1);
6610 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6611 }
6612 v2=u.expr.v2;
6613 {
6614 Error_Context cntxt(this, "In the right operand of operation `%s'",
6615 opname);
6616 v2->set_lowerid_to_ref();
6617 tt2=v2->get_expr_returntype(exp_val);
6618 chk_expr_operandtype_bool(tt2, right, opname, v2);
6619 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6620 }
6621 break;
6622 case OPTYPE_AND4B:
6623 case OPTYPE_OR4B:
6624 case OPTYPE_XOR4B:
6625 v1=u.expr.v1;
6626 {
6627 Error_Context cntxt(this, "In the left operand of operation `%s'",
6628 opname);
6629 v1->set_lowerid_to_ref();
6630 tt1=v1->get_expr_returntype(exp_val);
6631 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6632 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6633 }
6634 v2=u.expr.v2;
6635 {
6636 Error_Context cntxt(this, "In the right operand of operation `%s'",
6637 opname);
6638 v2->set_lowerid_to_ref();
6639 tt2=v2->get_expr_returntype(exp_val);
6640 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6641 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6642 }
6643 chk_expr_operandtypes_same(tt1, tt2, opname);
6644 chk_expr_operands_str_samelen();
6645 break;
6646 case OPTYPE_SHL:
6647 case OPTYPE_SHR:
6648 v1=u.expr.v1;
6649 {
6650 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6651 v1->set_lowerid_to_ref();
6652 tt1=v1->get_expr_returntype(exp_val);
6653 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6654 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6655 }
6656 v2=u.expr.v2;
6657 {
6658 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6659 v2->set_lowerid_to_ref();
6660 tt2=v2->get_expr_returntype(exp_val);
6661 chk_expr_operandtype_int(tt2, right, opname, v2);
6662 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6663 chk_expr_val_large_int(v2, right, opname);
6664 }
6665 break;
6666 case OPTYPE_ROTL:
6667 case OPTYPE_ROTR:
6668 v1=u.expr.v1;
6669 v1->set_lowerid_to_ref();
6670 if (v1->is_string_type(exp_val)) {
6671 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6672 tt1=v1->get_expr_returntype(exp_val);
6673 chk_expr_operandtype_str(tt1, left, opname, v1);
6674 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6675 } else { // other list types
6676 Type* v1_gov = v1->get_expr_governor(exp_val);
6677 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6678 error("Cannot determine the type of the left operand of `%s' operation", opname);
6679 } else {
6680 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6681 v1_gov->chk_this_value_ref(v1);
6682 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6683 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6684 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6685 }
6686 }
6687 v2=u.expr.v2;
6688 {
6689 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6690 v2->set_lowerid_to_ref();
6691 tt2=v2->get_expr_returntype(exp_val);
6692 chk_expr_operandtype_int(tt2, right, opname, v2);
6693 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6694 chk_expr_val_large_int(v2, right, opname);
6695 }
6696 break;
6697 case OPTYPE_INT2BIT:
6698 case OPTYPE_INT2HEX:
6699 case OPTYPE_INT2OCT:
6700 v1=u.expr.v1;
6701 {
6702 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6703 v1->set_lowerid_to_ref();
6704 tt1=v1->get_expr_returntype(exp_val);
6705 chk_expr_operandtype_int(tt1, first, opname, v1);
6706 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6707 chk_expr_val_int_pos0(v1, first, opname);
6708 }
6709 v2=u.expr.v2;
6710 {
6711 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6712 v2->set_lowerid_to_ref();
6713 tt2=v2->get_expr_returntype(exp_val);
6714 chk_expr_operandtype_int(tt2, second, opname, v2);
6715 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6716 chk_expr_val_int_pos0(v2, second, opname);
6717 }
6718 chk_expr_operands_int2binstr();
6719 break;
6720 case OPTYPE_DECODE:
6721 chk_expr_operands_decode();
6722 break;
6723 case OPTYPE_SUBSTR:
6724 {
6725 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6726 Type::expected_value_t ti_exp_val = exp_val;
6727 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6728 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6729 if (!governor) return;
6730 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6731 if (valuetype!=V_ERROR)
6732 u.expr.ti1->get_Template()->chk_specific_value(false);
6733 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6734 }
6735 v2=u.expr.v2;
6736 {
6737 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6738 v2->set_lowerid_to_ref();
6739 tt2=v2->get_expr_returntype(exp_val);
6740 chk_expr_operandtype_int(tt2, second, opname, v2);
6741 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6742 chk_expr_val_int_pos0(v2, second, opname);
6743 }
6744 v3=u.expr.v3;
6745 {
6746 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6747 v3->set_lowerid_to_ref();
6748 tt3=v3->get_expr_returntype(exp_val);
6749 chk_expr_operandtype_int(tt3, third, opname, v3);
6750 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6751 chk_expr_val_int_pos0(v3, third, opname);
6752 }
6753 chk_expr_operands_substr();
6754 break;
6755 case OPTYPE_REGEXP: {
6756 Type::expected_value_t ti_exp_val = exp_val;
6757 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6758 {
6759 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6760 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6761 if (!governor) return;
6762 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6763 if (valuetype!=V_ERROR) {
6764 u.expr.ti1->get_Template()->chk_specific_value(false);
6765 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6766 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6767 }
6768 }
6769 {
6770 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6771 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6772 if (!governor) return;
6773 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6774 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6775 get_typetype_ttcn3(), second, opname, u.expr.t2);
6776 }
6777 v3=u.expr.v3;
6778 {
6779 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6780 v3->set_lowerid_to_ref();
6781 tt3=v3->get_expr_returntype(exp_val);
6782 chk_expr_operandtype_int(tt3, third, opname, v3);
6783 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6784 chk_expr_val_int_pos0(v3, third, opname);
6785 }
6786 chk_expr_operands_regexp();
6787 } break;
6788 case OPTYPE_ISCHOSEN:
6789 // do nothing: the operand is erroneous
6790 // the error was already reported in chk_expr_ref_ischosen()
6791 break;
6792 case OPTYPE_ISCHOSEN_V: // v1 i2
6793 case OPTYPE_ISCHOSEN_T: // t1 i2
6794 chk_expr_operands_ischosen(refch, exp_val);
6795 break;
6796 case OPTYPE_VALUEOF: { // ti1
6797 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6798 exp_val = Type::EXPECTED_TEMPLATE;
6799 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6800 Type *governor = my_governor;
6801 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6802 if (!governor) return;
6803 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6804 if (valuetype == V_ERROR) return;
6805 u.expr.ti1->get_Template()->chk_specific_value(false);
6806 break; }
6807 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6808 case OPTYPE_ISBOUND: {
6809 Template *templ = u.expr.ti1->get_Template();
6810 switch (templ->get_templatetype()) {
6811 case Template::TEMPLATE_REFD:
6812 templ->get_reference()->setUsedInIsbound();
6813 break;
6814 case Template::SPECIFIC_VALUE: {
6815 Value *value = templ->get_specific_value();
6816 if (Value::V_REFD == value->get_valuetype()) {
6817 value->get_reference()->setUsedInIsbound();
6818 }
6819 break; }
6820 default:
6821 break;
6822 }
6823 }
6824 // no break
6825 case OPTYPE_ISVALUE: {// ti1
6826 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
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 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6833 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6834 break; }
6835 case OPTYPE_SIZEOF: // ti1
6836 /* this checking is too complex, do the checking during eval... */
6837 break;
6838 case OPTYPE_LENGTHOF: { // ti1
6839 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6840 exp_val = Type::EXPECTED_TEMPLATE;
6841 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6842 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6843 if (!governor) return;
6844 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
6845 if (valuetype == V_ERROR) return;
6846 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6847 break; }
6848 case OPTYPE_MATCH: // v1 t2
6849 chk_expr_operands_match(exp_val);
6850 break;
6851 case OPTYPE_UNDEF_RUNNING: // r1
6852 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
6853 break;
6854 case OPTYPE_COMP_ALIVE:
6855 case OPTYPE_COMP_RUNNING: //v1
6856 chk_expr_operand_compref(u.expr.v1, the, opname);
6857 chk_expr_dynamic_part(exp_val, false);
6858 break;
6859 case OPTYPE_TMR_READ: // r1
6860 case OPTYPE_TMR_RUNNING: // r1
6861 chk_expr_operand_tmrref(u.expr.r1, the, opname);
6862 chk_expr_dynamic_part(exp_val, true);
6863 break;
6864 case OPTYPE_EXECUTE: // r1 [v2] // testcase
6865 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
6866 chk_expr_dynamic_part(exp_val, true, false, false);
6867 break;
6868 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
6869 chk_expr_operand_comptyperef_create();
6870 v2=u.expr.v2;
6871 if(v2) {
6872 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6873 v2->set_lowerid_to_ref();
6874 tt2=v2->get_expr_returntype(exp_val);
6875 chk_expr_operandtype_cstr(tt2, first, opname, v2);
6876 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6877 }
6878 v3=u.expr.v3;
6879 if(v3) {
6880 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6881 v3->set_lowerid_to_ref();
6882 tt3=v3->get_expr_returntype(exp_val);
6883 chk_expr_operandtype_cstr(tt3, second, opname, v3);
6884 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6885 }
6886 chk_expr_dynamic_part(exp_val, false);
6887 break;
6888 case OPTYPE_ACTIVATE: // r1 // altstep
6889 chk_expr_operand_activate(u.expr.r1, the, opname);
6890 chk_expr_dynamic_part(exp_val, true);
6891 break;
6892 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
6893 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6894 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
6895 opname);
6896 delete u.expr.t_list2;
6897 u.expr.ap_list2 = parlist;
6898 chk_expr_dynamic_part(exp_val, true);
6899 break; }
6900 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
6901 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6902 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
6903 u.expr.v3, the, opname);
6904 delete u.expr.t_list2;
6905 u.expr.ap_list2 = parlist;
6906 chk_expr_dynamic_part(exp_val, true);
6907 break; }
6908 case OPTYPE_DECOMP:
6909 error("Built-in function `%s' is not yet supported", opname);
6910 set_valuetype(V_ERROR);
6911 break;
6912 case OPTYPE_REPLACE: {
6913 Type::expected_value_t ti_exp_val = exp_val;
6914 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6915 ti_exp_val = Type::EXPECTED_TEMPLATE;
6916 {
6917 Error_Context cntxt(this, "In the first operand of operation `%s'",
6918 opname);
6919 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6920 if (!governor) return;
6921 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6922 if (valuetype != V_ERROR)
6923 u.expr.ti1->get_Template()->chk_specific_value(false);
6924 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6925 }
6926 v2 = u.expr.v2;
6927 {
6928 Error_Context cntxt(this, "In the second operand of operation `%s'",
6929 opname);
6930 v2->set_lowerid_to_ref();
6931 tt2 = v2->get_expr_returntype(exp_val);
6932 chk_expr_operandtype_int(tt2, second, opname, v2);
6933 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6934 chk_expr_val_int_pos0(v2, second, opname);
6935 }
6936 v3 = u.expr.v3;
6937 {
6938 Error_Context cntxt(this, "In the third operand of operation `%s'",
6939 opname);
6940 v3->set_lowerid_to_ref();
6941 tt3 = v3->get_expr_returntype(exp_val);
6942 chk_expr_operandtype_int(tt3, third, opname, v3);
6943 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6944 chk_expr_val_int_pos0(v3, third, opname);
6945 }
6946 {
6947 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
6948 opname);
6949 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
6950 if (!governor) return;
6951 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
6952 if (valuetype != V_ERROR)
6953 u.expr.ti4->get_Template()->chk_specific_value(false);
6954 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
6955 }
6956 chk_expr_operands_replace();
6957 break; }
6958 case OPTYPE_LOG2STR: {
6959 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6960 u.expr.logargs->chk();
6961 if (!semantic_check_only) u.expr.logargs->join_strings();
6962 break; }
6963 case OPTYPE_TTCN2STRING: {
6964 Error_Context cntxt(this, "In the parameter of ttcn2string()");
6965 Type::expected_value_t ti_exp_val = exp_val;
6966 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6967 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6968 if (!governor) return;
6969 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6970 } break;
6971 default:
6972 FATAL_ERROR("chk_expr_operands()");
6973 } // switch optype
6974 }
6975
6976 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6977 // the result of evaluating the expression. E.g. V_BOOL for
6978 // OPTYPE_ISCHOSEN.
6979 void Value::evaluate_value(ReferenceChain *refch,
6980 Type::expected_value_t exp_val)
6981 {
6982 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
6983 if(u.expr.state!=EXPR_NOT_CHECKED) return;
6984
6985 u.expr.state=EXPR_CHECKING;
6986
6987 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
6988 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
6989 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
6990
6991 if(valuetype==V_ERROR) return;
6992 if(u.expr.state==EXPR_CHECKING_ERR) {
6993 u.expr.state=EXPR_CHECKED;
6994 set_valuetype(V_ERROR);
6995 return;
6996 }
6997
6998 u.expr.state=EXPR_CHECKED;
6999
7000 Value *v1, *v2, *v3, *v4;
7001 switch(u.expr.v_optype) {
7002 case OPTYPE_RND: // -
7003 case OPTYPE_COMP_NULL: // the only foldable in this group
7004 case OPTYPE_COMP_MTC:
7005 case OPTYPE_COMP_SYSTEM:
7006 case OPTYPE_COMP_SELF:
7007 case OPTYPE_COMP_RUNNING_ANY:
7008 case OPTYPE_COMP_RUNNING_ALL:
7009 case OPTYPE_COMP_ALIVE_ANY:
7010 case OPTYPE_COMP_ALIVE_ALL:
7011 case OPTYPE_TMR_RUNNING_ANY:
7012 case OPTYPE_GETVERDICT:
7013 case OPTYPE_RNDWITHVAL: // v1
7014 case OPTYPE_COMP_RUNNING: // v1
7015 case OPTYPE_COMP_ALIVE:
7016 case OPTYPE_TMR_READ:
7017 case OPTYPE_TMR_RUNNING:
7018 case OPTYPE_ACTIVATE:
7019 case OPTYPE_ACTIVATE_REFD:
7020 case OPTYPE_EXECUTE: // r1 [v2]
7021 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7022 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7023 case OPTYPE_MATCH: // v1 t2
7024 case OPTYPE_ISCHOSEN_T:
7025 case OPTYPE_LOG2STR:
7026 case OPTYPE_ENCODE:
7027 case OPTYPE_DECODE:
7028 case OPTYPE_ISBOUND:
7029 case OPTYPE_ISPRESENT:
7030 case OPTYPE_TTCN2STRING:
7031 case OPTYPE_UNICHAR2OCT:
7032 case OPTYPE_OCT2UNICHAR:
7033 case OPTYPE_ENCODE_BASE64:
7034 case OPTYPE_DECODE_BASE64:
7035 break;
7036 case OPTYPE_TESTCASENAME: { // -
7037 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7038 Ttcn::StatementBlock *my_sb =
7039 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7040 if (!my_sb) break;
7041 Ttcn::Definition *my_def = my_sb->get_my_def();
7042 if (!my_def) { // In control part.
7043 set_val_str(new string(""));
7044 valuetype = V_CSTR;
7045 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7046 set_val_str(new string(my_def->get_id().get_dispname()));
7047 valuetype = V_CSTR;
7048 }
7049 break; }
7050 case OPTYPE_UNARYPLUS: // v1
7051 v1=u.expr.v1;
7052 u.expr.v1=0;
7053 copy_and_destroy(v1);
7054 break;
7055 case OPTYPE_UNARYMINUS:
7056 if (is_unfoldable()) break;
7057 v1 = u.expr.v1->get_value_refd_last();
7058 switch (v1->valuetype) {
7059 case V_INT: {
7060 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7061 if (!i) FATAL_ERROR("Value::evaluate_value()");
7062 clean_up();
7063 valuetype = V_INT;
7064 u.val_Int = i;
7065 break; }
7066 case V_REAL: {
7067 ttcn3float r = v1->get_val_Real();
7068 clean_up();
7069 valuetype = V_REAL;
7070 u.val_Real = -r;
7071 break; }
7072 default:
7073 FATAL_ERROR("Value::evaluate_value()");
7074 }
7075 break;
7076 case OPTYPE_NOT: {
7077 if(is_unfoldable()) break;
7078 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7079 clean_up();
7080 valuetype=V_BOOL;
7081 u.val_bool=!b;
7082 break;}
7083 case OPTYPE_NOT4B: {
7084 if(is_unfoldable()) break;
7085 v1=u.expr.v1->get_value_refd_last();
7086 const string& s = v1->get_val_str();
7087 valuetype_t vt=v1->valuetype;
7088 clean_up();
7089 valuetype=vt;
7090 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7091 break;}
7092 case OPTYPE_BIT2HEX: {
7093 if(is_unfoldable()) break;
7094 v1=u.expr.v1->get_value_refd_last();
7095 const string& s = v1->get_val_str();
7096 clean_up();
7097 valuetype=V_HSTR;
7098 set_val_str(bit2hex(s));
7099 break;}
7100 case OPTYPE_BIT2OCT: {
7101 if(is_unfoldable()) break;
7102 v1=u.expr.v1->get_value_refd_last();
7103 const string& s = v1->get_val_str();
7104 clean_up();
7105 valuetype=V_OSTR;
7106 set_val_str(bit2oct(s));
7107 break;}
7108 case OPTYPE_BIT2STR:
7109 case OPTYPE_HEX2STR:
7110 case OPTYPE_OCT2STR: {
7111 if(is_unfoldable()) break;
7112 v1=u.expr.v1->get_value_refd_last();
7113 const string& s = v1->get_val_str();
7114 clean_up();
7115 valuetype=V_CSTR;
7116 set_val_str(new string(s));
7117 break;}
7118 case OPTYPE_BIT2INT: {
7119 if (is_unfoldable()) break;
7120 v1 = u.expr.v1->get_value_refd_last();
7121 const string& s = v1->get_val_str();
7122 clean_up();
7123 valuetype = V_INT;
7124 u.val_Int = bit2int(s);
7125 break; }
7126 case OPTYPE_CHAR2INT: {
7127 if (is_unfoldable()) break;
7128 v1 = u.expr.v1->get_value_refd_last();
7129 char c = v1->get_val_str()[0];
7130 clean_up();
7131 valuetype = V_INT;
7132 u.val_Int = new int_val_t((Int)c);
7133 break; }
7134 case OPTYPE_CHAR2OCT: {
7135 if(is_unfoldable()) break;
7136 v1=u.expr.v1->get_value_refd_last();
7137 const string& s = v1->get_val_str();
7138 clean_up();
7139 valuetype=V_OSTR;
7140 set_val_str(char2oct(s));
7141 break;}
7142 case OPTYPE_STR2INT: {
7143 if (is_unfoldable()) break;
7144 v1 = u.expr.v1->get_value_refd_last();
7145 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7146 clean_up();
7147 valuetype = V_INT;
7148 u.val_Int = i;
7149 /** \todo hiba eseten lenyeli... */
7150 break; }
7151 case OPTYPE_STR2FLOAT: {
7152 if(is_unfoldable()) break;
7153 v1=u.expr.v1->get_value_refd_last();
7154 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7155 clean_up();
7156 valuetype=V_REAL;
7157 u.val_Real=r;
7158 /** \todo hiba eseten lenyeli... */
7159 break;}
7160 case OPTYPE_STR2BIT: {
7161 if(is_unfoldable()) break;
7162 v1=u.expr.v1->get_value_refd_last();
7163 const string& s = v1->get_val_str();
7164 clean_up();
7165 valuetype=V_BSTR;
7166 set_val_str(new string(s));
7167 break;}
7168 case OPTYPE_STR2HEX:
7169 case OPTYPE_OCT2HEX: {
7170 if(is_unfoldable()) break;
7171 v1=u.expr.v1->get_value_refd_last();
7172 const string& s = v1->get_val_str();
7173 clean_up();
7174 valuetype=V_HSTR;
7175 set_val_str(to_uppercase(s));
7176 break;}
7177 case OPTYPE_STR2OCT: {
7178 if(is_unfoldable()) break;
7179 v1=u.expr.v1->get_value_refd_last();
7180 const string& s = v1->get_val_str();
7181 clean_up();
7182 valuetype=V_OSTR;
7183 set_val_str(to_uppercase(s));
7184 break;}
7185 case OPTYPE_FLOAT2INT: {
7186 if (is_unfoldable()) break;
7187 v1 = u.expr.v1->get_value_refd_last();
7188 ttcn3float r = v1->get_val_Real();
7189 clean_up();
7190 valuetype = V_INT;
7191 u.val_Int = float2int(r, *u.expr.v1);
7192 break;}
7193 case OPTYPE_FLOAT2STR: {
7194 if(is_unfoldable()) break;
7195 v1=u.expr.v1->get_value_refd_last();
7196 ttcn3float r=v1->get_val_Real();
7197 clean_up();
7198 valuetype=V_CSTR;
7199 set_val_str(float2str(r));
7200 break;}
7201 case OPTYPE_HEX2BIT:
7202 case OPTYPE_OCT2BIT: {
7203 if(is_unfoldable()) break;
7204 v1=u.expr.v1->get_value_refd_last();
7205 const string& s = v1->get_val_str();
7206 clean_up();
7207 valuetype=V_BSTR;
7208 set_val_str(hex2bit(s));
7209 break;}
7210 case OPTYPE_HEX2INT:
7211 case OPTYPE_OCT2INT: {
7212 if(is_unfoldable()) break;
7213 v1=u.expr.v1->get_value_refd_last();
7214 const string& s = v1->get_val_str();
7215 clean_up();
7216 valuetype=V_INT;
7217 u.val_Int=hex2int(s);
7218 break;}
7219 case OPTYPE_HEX2OCT: {
7220 if(is_unfoldable()) break;
7221 v1=u.expr.v1->get_value_refd_last();
7222 const string& s = v1->get_val_str();
7223 clean_up();
7224 valuetype=V_OSTR;
7225 set_val_str(hex2oct(s));
7226 break;}
7227 case OPTYPE_INT2CHAR: {
7228 if (is_unfoldable()) break;
7229 v1 = u.expr.v1->get_value_refd_last();
7230 const int_val_t *c_int = v1->get_val_Int();
7231 char c = static_cast<char>(c_int->get_val());
7232 clean_up();
7233 valuetype = V_CSTR;
7234 set_val_str(new string(1, &c));
7235 break; }
7236 case OPTYPE_INT2UNICHAR: {
7237 if (is_unfoldable()) break;
7238 v1 = u.expr.v1->get_value_refd_last();
7239 const int_val_t *i_int = v1->get_val_Int();
7240 Int i = i_int->get_val();
7241 clean_up();
7242 valuetype = V_USTR;
7243 set_val_ustr(int2unichar(i));
7244 u.ustr.convert_str = false;
7245 break; }
7246 case OPTYPE_INT2FLOAT: {
7247 if (is_unfoldable()) break;
7248 v1 = u.expr.v1->get_value_refd_last();
7249 const int_val_t *i_int = v1->get_val_Int();
7250 Real i_int_real = i_int->to_real();
7251 clean_up();
7252 valuetype = V_REAL;
7253 u.val_Real = i_int_real;
7254 break; }
7255 case OPTYPE_INT2STR: {
7256 if (is_unfoldable()) break;
7257 v1 = u.expr.v1->get_value_refd_last();
7258 const int_val_t *i_int = v1->get_val_Int();
7259 string *i_int_str = new string(i_int->t_str());
7260 clean_up();
7261 valuetype = V_CSTR;
7262 set_val_str(i_int_str);
7263 break; }
7264 case OPTYPE_OCT2CHAR: {
7265 if(is_unfoldable()) break;
7266 v1=u.expr.v1->get_value_refd_last();
7267 const string& s = v1->get_val_str();
7268 clean_up();
7269 valuetype=V_CSTR;
7270 set_val_str(oct2char(s));
7271 break;}
7272 case OPTYPE_GET_STRINGENCODING: {
7273 if(is_unfoldable()) break;
7274 v1 = u.expr.v1->get_value_refd_last();
7275 const string& s1 = v1->get_val_str();
7276 clean_up();
7277 valuetype = V_CSTR;
7278 set_val_str(get_stringencoding(s1));
7279 break;}
7280 case OPTYPE_REMOVE_BOM: {
7281 if(is_unfoldable()) break;
7282 v1 = u.expr.v1->get_value_refd_last();
7283 const string& s1 = v1->get_val_str();
7284 clean_up();
7285 valuetype = V_OSTR;
7286 set_val_str(remove_bom(s1));
7287 break;}
7288 case OPTYPE_ENUM2INT: {
7289 if(is_unfoldable()) break;
7290 v1=u.expr.v1->get_value_refd_last();
7291 Type* enum_type = v1->get_my_governor();
7292 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7293 clean_up();
7294 valuetype = V_INT;
7295 u.val_Int = new int_val_t(enum_val);
7296 break;}
7297 case OPTYPE_UNICHAR2INT:
7298 if (is_unfoldable()) {
7299 // replace the operation with char2int() if the operand is a charstring
7300 // value to avoid its unnecessary conversion to universal charstring
7301 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7302 u.expr.v_optype = OPTYPE_CHAR2INT;
7303 } else {
7304 v1=u.expr.v1->get_value_refd_last();
7305 const ustring& s = v1->get_val_ustr();
7306 clean_up();
7307 valuetype=V_INT;
7308 u.val_Int=new int_val_t(unichar2int(s));
7309 }
7310 break;
7311 case OPTYPE_UNICHAR2CHAR:
7312 v1 = u.expr.v1;
7313 if (is_unfoldable()) {
7314 // replace the operation with its operand if it is a charstring
7315 // value to avoid its unnecessary conversion to universal charstring
7316 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7317 u.expr.v1 = 0;
7318 copy_and_destroy(v1);
7319 }
7320 } else {
7321 v1 = v1->get_value_refd_last();
7322 const ustring& s = v1->get_val_ustr();
7323 clean_up();
7324 valuetype = V_CSTR;
7325 set_val_str(new string(s));
7326 }
7327 break;
7328 case OPTYPE_MULTIPLY: { // v1 v2
7329 if (!is_unfoldable()) goto eval_arithmetic;
7330 v1 = u.expr.v1->get_value_refd_last();
7331 v2 = u.expr.v2->get_value_refd_last();
7332 if (v1->is_unfoldable()) v1 = v2;
7333 if (v1->is_unfoldable()) break;
7334 switch(v1->valuetype) {
7335 case V_INT: {
7336 if (*v1->get_val_Int() != 0) break;
7337 clean_up();
7338 valuetype = V_INT;
7339 u.val_Int = new int_val_t((Int)0);
7340 break; }
7341 case V_REAL: {
7342 if (v1->get_val_Real() != 0.0) break;
7343 clean_up();
7344 valuetype = V_REAL;
7345 u.val_Real = 0.0;
7346 break; }
7347 default:
7348 FATAL_ERROR("Value::evaluate_value()");
7349 }
7350 break; }
7351 case OPTYPE_ADD: // v1 v2
7352 case OPTYPE_SUBTRACT:
7353 case OPTYPE_DIVIDE:
7354 case OPTYPE_MOD:
7355 case OPTYPE_REM: {
7356 eval_arithmetic:
7357 if(is_unfoldable()) break;
7358 v1=u.expr.v1->get_value_refd_last();
7359 v2=u.expr.v2->get_value_refd_last();
7360 operationtype_t ot=u.expr.v_optype;
7361 switch (v1->valuetype) {
7362 case V_INT: {
7363 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7364 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7365 clean_up();
7366 valuetype = V_INT;
7367 switch (ot) {
7368 case OPTYPE_ADD:
7369 u.val_Int = new int_val_t(*i1 + *i2);
7370 break;
7371 case OPTYPE_SUBTRACT:
7372 u.val_Int = new int_val_t(*i1 - *i2);
7373 break;
7374 case OPTYPE_MULTIPLY:
7375 u.val_Int = new int_val_t(*i1 * *i2);
7376 break;
7377 case OPTYPE_DIVIDE:
7378 u.val_Int = new int_val_t(*i1 / *i2);
7379 break;
7380 case OPTYPE_MOD:
7381 u.val_Int = new int_val_t(mod(*i1, *i2));
7382 break;
7383 case OPTYPE_REM:
7384 u.val_Int = new int_val_t(rem(*i1, *i2));
7385 break;
7386 default:
7387 FATAL_ERROR("Value::evaluate_value()");
7388 }
7389 delete i1;
7390 delete i2;
7391 break; }
7392 case V_REAL: {
7393 ttcn3float r1=v1->get_val_Real();
7394 ttcn3float r2=v2->get_val_Real();
7395 clean_up();
7396 valuetype=V_REAL;
7397 switch(ot) {
7398 case OPTYPE_ADD:
7399 u.val_Real=r1+r2;
7400 break;
7401 case OPTYPE_SUBTRACT:
7402 u.val_Real=r1-r2;
7403 break;
7404 case OPTYPE_MULTIPLY:
7405 u.val_Real=r1*r2;
7406 break;
7407 case OPTYPE_DIVIDE:
7408 u.val_Real=r1/r2;
7409 break;
7410 default:
7411 FATAL_ERROR("Value::evaluate_value()");
7412 }
7413 break;}
7414 default:
7415 FATAL_ERROR("Value::evaluate_value()");
7416 }
7417 break;}
7418 case OPTYPE_CONCAT: {
7419 if(is_unfoldable()) break;
7420 v1=u.expr.v1->get_value_refd_last();
7421 v2=u.expr.v2->get_value_refd_last();
7422 valuetype_t vt = v1->valuetype;
7423 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7424 const ustring& s1 = v1->get_val_ustr();
7425 const ustring& s2 = v2->get_val_ustr();
7426 clean_up();
7427 valuetype = V_USTR;
7428 set_val_ustr(new ustring(s1 + s2));
7429 u.ustr.convert_str = false;
7430 } else {
7431 const string& s1 = v1->get_val_str();
7432 const string& s2 = v2->get_val_str();
7433 clean_up();
7434 valuetype = vt;
7435 set_val_str(new string(s1 + s2));
7436 }
7437 break;}
7438 case OPTYPE_EQ: {
7439 if(is_unfoldable()) break;
7440 v1=u.expr.v1->get_value_refd_last();
7441 v2=u.expr.v2->get_value_refd_last();
7442 bool b=*v1==*v2;
7443 clean_up();
7444 valuetype=V_BOOL;
7445 u.val_bool=b;
7446 break;}
7447 case OPTYPE_NE: {
7448 if(is_unfoldable()) break;
7449 v1=u.expr.v1->get_value_refd_last();
7450 v2=u.expr.v2->get_value_refd_last();
7451 bool b=*v1==*v2;
7452 clean_up();
7453 valuetype=V_BOOL;
7454 u.val_bool=!b;
7455 break;}
7456 case OPTYPE_LT: {
7457 if(is_unfoldable()) break;
7458 v1=u.expr.v1->get_value_refd_last();
7459 v2=u.expr.v2->get_value_refd_last();
7460 bool b=*v1<*v2;
7461 clean_up();
7462 valuetype=V_BOOL;
7463 u.val_bool=b;
7464 break;}
7465 case OPTYPE_GT: {
7466 if(is_unfoldable()) break;
7467 v1=u.expr.v1->get_value_refd_last();
7468 v2=u.expr.v2->get_value_refd_last();
7469 bool b=*v2<*v1;
7470 clean_up();
7471 valuetype=V_BOOL;
7472 u.val_bool=b;
7473 break;}
7474 case OPTYPE_GE: {
7475 if(is_unfoldable()) break;
7476 v1=u.expr.v1->get_value_refd_last();
7477 v2=u.expr.v2->get_value_refd_last();
7478 bool b=*v1<*v2;
7479 clean_up();
7480 valuetype=V_BOOL;
7481 u.val_bool=!b;
7482 break;}
7483 case OPTYPE_LE: {
7484 if(is_unfoldable()) break;
7485 v1=u.expr.v1->get_value_refd_last();
7486 v2=u.expr.v2->get_value_refd_last();
7487 bool b=*v2<*v1;
7488 clean_up();
7489 valuetype=V_BOOL;
7490 u.val_bool=!b;
7491 break;}
7492 case OPTYPE_AND:
7493 v1 = u.expr.v1->get_value_refd_last();
7494 if (v1->valuetype == V_BOOL) {
7495 if (v1->get_val_bool()) {
7496 // the left operand is a literal "true"
7497 // substitute the expression with the right operand
7498 v2 = u.expr.v2;
7499 u.expr.v2 = 0;
7500 copy_and_destroy(v2);
7501 } else {
7502 // the left operand is a literal "false"
7503 // the result must be false regardless the right operand
7504 // because of the short circuit evaluation rule
7505 clean_up();
7506 valuetype = V_BOOL;
7507 u.val_bool = false;
7508 }
7509 } else {
7510 // we must keep the left operand because of the potential side effects
7511 // the right operand can only be eliminated if it is a literal "true"
7512 v2 = u.expr.v2->get_value_refd_last();
7513 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7514 v1 = u.expr.v1;
7515 u.expr.v1 = 0;
7516 copy_and_destroy(v1);
7517 }
7518 }
7519 break;
7520 case OPTYPE_OR:
7521 v1 = u.expr.v1->get_value_refd_last();
7522 if (v1->valuetype == V_BOOL) {
7523 if (v1->get_val_bool()) {
7524 // the left operand is a literal "true"
7525 // the result must be true regardless the right operand
7526 // because of the short circuit evaluation rule
7527 clean_up();
7528 valuetype = V_BOOL;
7529 u.val_bool = true;
7530 } else {
7531 // the left operand is a literal "false"
7532 // substitute the expression with the right operand
7533 v2 = u.expr.v2;
7534 u.expr.v2 = 0;
7535 copy_and_destroy(v2);
7536 }
7537 } else {
7538 // we must keep the left operand because of the potential side effects
7539 // the right operand can only be eliminated if it is a literal "false"
7540 v2 = u.expr.v2->get_value_refd_last();
7541 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7542 v1 = u.expr.v1;
7543 u.expr.v1 = 0;
7544 copy_and_destroy(v1);
7545 }
7546 }
7547 break;
7548 case OPTYPE_XOR: {
7549 if(is_unfoldable()) break;
7550 v1=u.expr.v1->get_value_refd_last();
7551 v2=u.expr.v2->get_value_refd_last();
7552 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7553 clean_up();
7554 valuetype=V_BOOL;
7555 u.val_bool=b;
7556 break;}
7557 case OPTYPE_AND4B: {
7558 if(is_unfoldable()) break;
7559 v1=u.expr.v1->get_value_refd_last();
7560 v2=u.expr.v2->get_value_refd_last();
7561 valuetype_t vt=v1->valuetype;
7562 const string& s1 = v1->get_val_str();
7563 const string& s2 = v2->get_val_str();
7564 clean_up();
7565 valuetype=vt;
7566 set_val_str(and4b(s1, s2));
7567 break;}
7568 case OPTYPE_OR4B: {
7569 if(is_unfoldable()) break;
7570 v1=u.expr.v1->get_value_refd_last();
7571 v2=u.expr.v2->get_value_refd_last();
7572 valuetype_t vt=v1->valuetype;
7573 const string& s1 = v1->get_val_str();
7574 const string& s2 = v2->get_val_str();
7575 clean_up();
7576 valuetype=vt;
7577 set_val_str(or4b(s1, s2));
7578 break;}
7579 case OPTYPE_XOR4B: {
7580 if(is_unfoldable()) break;
7581 v1=u.expr.v1->get_value_refd_last();
7582 v2=u.expr.v2->get_value_refd_last();
7583 valuetype_t vt=v1->valuetype;
7584 const string& s1 = v1->get_val_str();
7585 const string& s2 = v2->get_val_str();
7586 clean_up();
7587 valuetype=vt;
7588 set_val_str(xor4b(s1, s2));
7589 break;}
7590 case OPTYPE_SHL: {
7591 if(is_unfoldable()) break;
7592 v1=u.expr.v1->get_value_refd_last();
7593 v2=u.expr.v2->get_value_refd_last();
7594 valuetype_t vt=v1->valuetype;
7595 const string& s = v1->get_val_str();
7596 const int_val_t *i_int = v2->get_val_Int();
7597 Int i=i_int->get_val();
7598 if(vt==V_OSTR) i*=2;
7599 clean_up();
7600 valuetype=vt;
7601 set_val_str(shift_left(s, i));
7602 break;}
7603 case OPTYPE_SHR: {
7604 if(is_unfoldable()) break;
7605 v1=u.expr.v1->get_value_refd_last();
7606 v2=u.expr.v2->get_value_refd_last();
7607 valuetype_t vt=v1->valuetype;
7608 const string& s = v1->get_val_str();
7609 const int_val_t *i_int = v2->get_val_Int();
7610 Int i=i_int->get_val();
7611 if(vt==V_OSTR) i*=2;
7612 clean_up();
7613 valuetype=vt;
7614 set_val_str(shift_right(s, i));
7615 break;}
7616 case OPTYPE_ROTL: {
7617 if(is_unfoldable()) break;
7618 v1=u.expr.v1->get_value_refd_last();
7619 v2=u.expr.v2->get_value_refd_last();
7620 valuetype_t vt=v1->valuetype;
7621 const int_val_t *i_int=v2->get_val_Int();
7622 Int i=i_int->get_val();
7623 if(vt==V_USTR) {
7624 const ustring& s = v1->get_val_ustr();
7625 clean_up();
7626 valuetype=vt;
7627 set_val_ustr(rotate_left(s, i));
7628 u.ustr.convert_str = false;
7629 }
7630 else {
7631 if(vt==V_OSTR) i*=2;
7632 const string& s = v1->get_val_str();
7633 clean_up();
7634 valuetype=vt;
7635 set_val_str(rotate_left(s, i));
7636 }
7637 break;}
7638 case OPTYPE_ROTR: {
7639 if(is_unfoldable()) break;
7640 v1=u.expr.v1->get_value_refd_last();
7641 v2=u.expr.v2->get_value_refd_last();
7642 valuetype_t vt=v1->valuetype;
7643 const int_val_t *i_int=v2->get_val_Int();
7644 Int i=i_int->get_val();
7645 if(vt==V_USTR) {
7646 const ustring& s = v1->get_val_ustr();
7647 clean_up();
7648 valuetype=vt;
7649 set_val_ustr(rotate_right(s, i));
7650 u.ustr.convert_str = false;
7651 }
7652 else {
7653 if(vt==V_OSTR) i*=2;
7654 const string& s = v1->get_val_str();
7655 clean_up();
7656 valuetype=vt;
7657 set_val_str(rotate_right(s, i));
7658 }
7659 break;}
7660 case OPTYPE_INT2BIT: {
7661 if (is_unfoldable()) break;
7662 v1 = u.expr.v1->get_value_refd_last();
7663 v2 = u.expr.v2->get_value_refd_last();
7664 const int_val_t *i1_int = v1->get_val_Int();
7665 const int_val_t *i2_int = v2->get_val_Int();
7666 string *val = int2bit(*i1_int, i2_int->get_val());
7667 clean_up();
7668 valuetype = V_BSTR;
7669 set_val_str(val);
7670 break; }
7671 case OPTYPE_INT2HEX: {
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 const int_val_t *i2_int = v2->get_val_Int();
7677 // Do it before the `clean_up'. i2_int is already checked.
7678 string *val = int2hex(*i1_int, i2_int->get_val());
7679 clean_up();
7680 valuetype = V_HSTR;
7681 set_val_str(val);
7682 break; }
7683 case OPTYPE_INT2OCT: {
7684 if (is_unfoldable()) break;
7685 v1 = u.expr.v1->get_value_refd_last();
7686 v2 = u.expr.v2->get_value_refd_last();
7687 const int_val_t i1_int(*v1->get_val_Int());
7688 // `v2' is a native integer.
7689 Int i2_int = v2->get_val_Int()->get_val() * 2;
7690 clean_up();
7691 valuetype = V_OSTR;
7692 set_val_str(int2hex(i1_int, i2_int));
7693 break; }
7694 case OPTYPE_SUBSTR: {
7695 if(is_unfoldable()) break;
7696 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7697 v2=u.expr.v2->get_value_refd_last();
7698 v3=u.expr.v3->get_value_refd_last();
7699 valuetype_t vt=v1->valuetype;
7700 const int_val_t *i2_int=v2->get_val_Int();
7701 const int_val_t *i3_int=v3->get_val_Int();
7702 Int i2=i2_int->get_val();
7703 Int i3=i3_int->get_val();
7704 if(vt==V_USTR) {
7705 const ustring& s = v1->get_val_ustr();
7706 clean_up();
7707 valuetype=vt;
7708 set_val_ustr(new ustring(s.substr(i2, i3)));
7709 u.ustr.convert_str = false;
7710 }
7711 else {
7712 if(vt==V_OSTR) {
7713 i2*=2;
7714 i3*=2;
7715 }
7716 const string& s = v1->get_val_str();
7717 clean_up();
7718 valuetype=vt;
7719 set_val_str(new string(s.substr(i2, i3)));
7720 }
7721 break;}
7722 case OPTYPE_REPLACE: {
7723 if(is_unfoldable()) break;
7724 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7725 v2=u.expr.v2->get_value_refd_last();
7726 v3=u.expr.v3->get_value_refd_last();
7727 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7728 valuetype_t vt=v1->valuetype;
7729 const int_val_t *i2_int=v2->get_val_Int();
7730 const int_val_t *i3_int=v3->get_val_Int();
7731 Int i2=i2_int->get_val();
7732 Int i3=i3_int->get_val();
7733 switch(vt) {
7734 case V_BSTR: {
7735 string *s1 = new string(v1->get_val_str());
7736 const string& s2 = v4->get_val_str();
7737 clean_up();
7738 valuetype=vt;
7739 s1->replace(i2, i3, s2);
7740 set_val_str(s1);
7741 break;}
7742 case V_HSTR: {
7743 string *s1 = new string(v1->get_val_str());
7744 const string& s2 = v4->get_val_str();
7745 clean_up();
7746 valuetype=vt;
7747 s1->replace(i2, i3, s2);
7748 set_val_str(s1);
7749 break;}
7750 case V_OSTR: {
7751 i2*=2;
7752 i3*=2;
7753 string *s1 = new string(v1->get_val_str());
7754 const string& s2 = v4->get_val_str();
7755 clean_up();
7756 valuetype=vt;
7757 s1->replace(i2, i3, s2);
7758 set_val_str(s1);
7759 break;}
7760 case V_CSTR: {
7761 string *s1 = new string(v1->get_val_str());
7762 const string& s2 = v4->get_val_str();
7763 clean_up();
7764 valuetype=vt;
7765 s1->replace(i2, i3, s2);
7766 set_val_str(s1);
7767 break;}
7768 case V_USTR: {
7769 ustring *s1 = new ustring(v1->get_val_ustr());
7770 const ustring& s2 = v4->get_val_ustr();
7771 clean_up();
7772 valuetype=vt;
7773 s1->replace(i2, i3, s2);
7774 set_val_ustr(s1);
7775 u.ustr.convert_str = false;
7776 break;}
7777 default:
7778 FATAL_ERROR("Value::evaluate_value()");
7779 }
7780 break; }
7781 case OPTYPE_REGEXP: {
7782 if (is_unfoldable()) break;
7783 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7784 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7785 v3=u.expr.v3->get_value_refd_last();
7786 const int_val_t *i3_int = v3->get_val_Int();
7787 Int i3 = i3_int->get_val();
7788 if (v1->valuetype == V_CSTR) {
7789 const string& s1 = v1->get_val_str();
7790 const string& s2 = v2->get_val_str();
7791 string *result = regexp(s1, s2, i3);
7792 clean_up();
7793 valuetype = V_CSTR;
7794 set_val_str(result);
7795 } if (v1->valuetype == V_USTR) {
7796 const ustring& s1 = v1->get_val_ustr();
7797 const ustring& s2 = v2->get_val_ustr();
7798 ustring *result = regexp(s1, s2, i3);
7799 clean_up();
7800 valuetype = V_USTR;
7801 set_val_ustr(result);
7802 u.ustr.convert_str = false;
7803 }
7804 break; }
7805 case OPTYPE_LENGTHOF:{
7806 if(is_unfoldable()) break;
7807 v1=u.expr.ti1->get_Template()->get_specific_value()
7808 ->get_value_refd_last();
7809 size_t i;
7810 if(v1->is_string_type(exp_val)) {
7811 i=v1->get_val_strlen();
7812 } else { // v1 is be seq/set of or array
7813 switch (v1->valuetype) {
7814 case V_SEQOF:
7815 case V_SETOF:
7816 case V_ARRAY: {
7817 if(v1->u.val_vs->is_indexed())
7818 { i = v1->u.val_vs->get_nof_ivs();}
7819 else { i = v1->u.val_vs->get_nof_vs();}
7820 break; }
7821 default:
7822 FATAL_ERROR("Value::evaluate_value()");
7823 }
7824 }
7825 clean_up();
7826 valuetype=V_INT;
7827 u.val_Int=new int_val_t(i);
7828 break;}
7829 case OPTYPE_SIZEOF: {
7830 Int i=chk_eval_expr_sizeof(refch, exp_val);
7831 if(i!=-1) {
7832 clean_up();
7833 valuetype=V_INT;
7834 u.val_Int=new int_val_t(i);
7835 }
7836 break;}
7837 case OPTYPE_ISVALUE: {
7838 if(is_unfoldable()) break;
7839 bool is_singleval = !u.expr.ti1->get_DerivedRef()
7840 && u.expr.ti1->get_Template()->is_Value();
7841 if (is_singleval) {
7842 Value * other_val = u.expr.ti1->get_Template()->get_Value();
7843 is_singleval = other_val->evaluate_isvalue(false);
7844 // is_singleval now contains the compile-time result of isvalue
7845 delete other_val;
7846 }
7847 clean_up();
7848 valuetype = V_BOOL;
7849 u.val_bool = is_singleval;
7850 break;}
7851 case OPTYPE_ISCHOSEN_V: {
7852 if (is_unfoldable()) break;
7853 v1 = u.expr.v1->get_value_refd_last();
7854 bool b = v1->field_is_chosen(*u.expr.i2);
7855 clean_up();
7856 valuetype = V_BOOL;
7857 u.val_bool = b;
7858 break; }
7859 case OPTYPE_VALUEOF: // ti1
7860 if (!u.expr.ti1->get_DerivedRef() &&
7861 u.expr.ti1->get_Template()->is_Value() &&
7862 !u.expr.ti1->get_Type()) {
7863 // FIXME actually if the template instance has a type
7864 // it might still be foldable.
7865 // the argument is a single specific value
7866 v1 = u.expr.ti1->get_Template()->get_Value();
7867 Type *governor = my_governor;
7868 if (governor == NULL) {
7869 governor = u.expr.ti1->get_expr_governor(exp_val);
7870 if (governor != NULL) governor = governor->get_type_refd_last();
7871 }
7872 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
7873 if (governor == NULL)
7874 FATAL_ERROR("Value::evaluate_value()");
7875 clean_up();
7876 valuetype = v1->valuetype;
7877 u = v1->u;
7878 set_my_governor(governor);
7879 if (valuetype == V_REFD && u.ref.refd_last == v1)
7880 u.ref.refd_last = this;
7881 v1->valuetype = V_ERROR;
7882 delete v1;
7883 }
7884 break;
7885 case OPTYPE_UNDEF_RUNNING:
7886 default:
7887 FATAL_ERROR("Value::evaluate_value()");
7888 } // switch optype
7889 }
7890
7891 bool Value::evaluate_isvalue(bool from_sequence)
7892 {
7893 switch (valuetype) {
7894 case V_OMIT:
7895 // Omit is not a value unless a member of a sequence or set
7896 return from_sequence;
7897 case V_NOTUSED:
7898 return false;
7899 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7900 case V_BOOL: /**< boolean */
7901 case V_NAMEDINT: /**< integer / named number */
7902 case V_NAMEDBITS: /**< named bits (identifiers) */
7903 case V_INT: /**< integer */
7904 case V_REAL: /**< real/float */
7905 case V_ENUM: /**< enumerated */
7906 case V_BSTR: /**< bitstring */
7907 case V_HSTR: /**< hexstring */
7908 case V_OSTR: /**< octetstring */
7909 case V_CSTR: /**< charstring */
7910 case V_USTR: /**< universal charstring */
7911 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
7912 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
7913 case V_OID: /**< object identifier */
7914 case V_ROID: /**< relative object identifier */
7915 case V_VERDICT: /**< all verdicts */
7916 return true; // values of built-in types return true
7917
7918 // Code below was adapted from is_unfoldable(), false returned early.
7919 case V_CHOICE:
7920 return u.choice.alt_value->evaluate_isvalue(false);
7921
7922 case V_SEQOF:
7923 case V_SETOF:
7924 case V_ARRAY:
7925 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
7926 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
7927 return false;
7928 }
7929 }
7930 return true;
7931
7932 case V_SEQ:
7933 case V_SET:
7934 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
7935 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
7936 ->evaluate_isvalue(true)) return false;
7937 }
7938 return true;
7939
7940 case V_REFD:
7941 // alas, get_value_refd_last prevents this function from const
7942 return get_value_refd_last()->evaluate_isvalue(false);
7943
7944 case V_EXPR:
7945 switch (u.expr.v_optype) {
7946 // A constant null component reference is a corner case: it is foldable
7947 // but escapes unmodified from evaluate_value.
7948 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7949 // or is transformed into some other valuetype in evaluate_value.
7950 case OPTYPE_COMP_NULL:
7951 return false;
7952 default:
7953 break; // and fall through to the FATAL_ERROR
7954 }
7955 // no break
7956 default:
7957 FATAL_ERROR("Value::evaluate_isvalue()");
7958 break;
7959 }
7960 return true;
7961 }
7962
7963 void Value::evaluate_macro(Type::expected_value_t exp_val)
7964 {
7965 switch (u.macro) {
7966 case MACRO_MODULEID:
7967 if (!my_scope)
7968 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7969 set_val_str(new string(my_scope->get_scope_mod()
7970 ->get_modid().get_dispname()));
7971 valuetype = V_CSTR;
7972 break;
7973 case MACRO_FILENAME:
7974 case MACRO_BFILENAME: {
7975 const char *t_filename = get_filename();
7976 if (!t_filename)
7977 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7978 set_val_str(new string(t_filename));
7979 valuetype = V_CSTR;
7980 break; }
7981 case MACRO_FILEPATH: {
7982 const char *t_filename = get_filename();
7983 if (!t_filename)
7984 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7985 char *t_filepath = canonize_input_file(t_filename);
7986 if (!t_filepath)
7987 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7988 set_val_str(new string(t_filepath));
7989 valuetype = V_CSTR;
7990 Free(t_filepath);
7991 break; }
7992 case MACRO_LINENUMBER: {
7993 int t_lineno = get_first_line();
7994 if (t_lineno <= 0)
7995 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7996 set_val_str(new string(Int2string(t_lineno)));
7997 valuetype = V_CSTR;
7998 break; }
7999 case MACRO_LINENUMBER_C: {
8000 int t_lineno = get_first_line();
8001 if (t_lineno <= 0)
8002 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8003 u.val_Int = new int_val_t(t_lineno);
8004 valuetype = V_INT;
8005 break; }
8006 case MACRO_DEFINITIONID: {
8007 // cut the second part from the fullname separated by dots
8008 const string& t_fullname = get_fullname();
8009 size_t first_char = t_fullname.find('.') + 1;
8010 if (first_char >= t_fullname.size())
8011 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8012 t_fullname.c_str());
8013 set_val_str(new string(t_fullname.substr(first_char,
8014 t_fullname.find('.', first_char) - first_char)));
8015 valuetype = V_CSTR;
8016 break; }
8017 case MACRO_SCOPE: {
8018 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8019 set_val_str(new string(my_scope->get_scopeMacro_name()));
8020 valuetype = V_CSTR;
8021 break;
8022 }
8023 case MACRO_TESTCASEID: {
8024 if (exp_val == Type::EXPECTED_CONSTANT ||
8025 exp_val == Type::EXPECTED_STATIC_VALUE) {
8026 error("A %s value was expected instead of macro `%%testcaseId', "
8027 "which is evaluated at runtime",
8028 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8029 goto error;
8030 }
8031 if (!my_scope)
8032 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8033 Ttcn::StatementBlock *my_sb =
8034 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8035 if (!my_sb) {
8036 error("Usage of macro %%testcaseId is allowed only within the "
8037 "statement blocks of functions, altsteps and testcases");
8038 goto error;
8039 }
8040 Ttcn::Definition *my_def = my_sb->get_my_def();
8041 if (!my_def) {
8042 error("Macro %%testcaseId cannot be used in the control part. "
8043 "It is allowed only within the statement blocks of functions, "
8044 "altsteps and testcases");
8045 goto error;
8046 }
8047 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8048 // folding is possible only within testcases
8049 set_val_str(new string(my_def->get_id().get_dispname()));
8050 valuetype = V_CSTR;
8051 }
8052 break; }
8053 default:
8054 FATAL_ERROR("Value::evaluate_macro()");
8055 }
8056 return;
8057 error:
8058 set_valuetype(V_ERROR);
8059 }
8060
8061 void Value::add_id(Identifier *p_id)
8062 {
8063 switch(valuetype) {
8064 case V_NAMEDBITS:
8065 if(u.ids->has_key(p_id->get_name())) {
8066 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8067 // The Value does not take ownership for the identifier,
8068 // so it must be deleted (add_is acts as a sink).
8069 delete p_id;
8070 }
8071 else u.ids->add(p_id->get_name(), p_id);
8072 break;
8073 default:
8074 FATAL_ERROR("Value::add_id()");
8075 } // switch
8076 }
8077
8078 Value* Value::get_value_refd_last(ReferenceChain *refch,
8079 Type::expected_value_t exp_val)
8080 {
8081 set_lowerid_to_ref();
8082 switch (valuetype) {
8083 case V_INVOKE:
8084 // there might be a better place for this
8085 chk_invoke(exp_val);
8086 return this;
8087 case V_REFD:
8088 // use the cache if available
8089 if (u.ref.refd_last) return u.ref.refd_last;
8090 else {
8091 Assignment *ass = u.ref.ref->get_refd_assignment();
8092 if (!ass) {
8093 // the referred definition is not found
8094 set_valuetype(V_ERROR);
8095 } else {
8096 switch (ass->get_asstype()) {
8097 case Assignment::A_OBJECT:
8098 case Assignment::A_OS: {
8099 // the referred definition is an ASN.1 object or object set
8100 Setting *setting = u.ref.ref->get_refd_setting();
8101 if (!setting || setting->get_st() == S_ERROR) {
8102 // remain silent, the error has been already reported
8103 set_valuetype(V_ERROR);
8104 break;
8105 } else if (setting->get_st() != S_V) {
8106 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8107 " refer to a value", u.ref.ref->get_dispname().c_str());
8108 set_valuetype(V_ERROR);
8109 break;
8110 }
8111 bool destroy_refch;
8112 if (refch) {
8113 refch->mark_state();
8114 destroy_refch = false;
8115 } else {
8116 refch = new ReferenceChain(this,
8117 "While searching referenced value");
8118 destroy_refch = true;
8119 }
8120 if (refch->add(get_fullname())) {
8121 Value *v_refd = dynamic_cast<Value*>(setting);
8122 Value *v_last = v_refd->get_value_refd_last(refch);
8123 // in case of circular recursion the valuetype is already set
8124 // to V_ERROR, so don't set the cache
8125 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8126 } else {
8127 // a circular recursion was detected
8128 set_valuetype(V_ERROR);
8129 }
8130 if (destroy_refch) delete refch;
8131 else refch->prev_state();
8132 break; }
8133 case Assignment::A_CONST: {
8134 // the referred definition is a constant
8135 bool destroy_refch;
8136 if (refch) {
8137 refch->mark_state();
8138 destroy_refch = false;
8139 } else {
8140 refch = new ReferenceChain(this,
8141 "While searching referenced value");
8142 destroy_refch = true;
8143 }
8144 if (refch->add(get_fullname())) {
8145 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8146 Value *v_refd = ass->get_Value()
8147 ->get_refd_sub_value(subrefs, 0,
8148 u.ref.ref->getUsedInIsbound(), refch);
8149 if (v_refd) {
8150 Value *v_last = v_refd->get_value_refd_last(refch);
8151 // in case of circular recursion the valuetype is already set
8152 // to V_ERROR, so don't set the cache
8153 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8154 } else if (subrefs && subrefs->has_unfoldable_index()) {
8155 u.ref.refd_last = this;
8156 } else if (u.ref.ref->getUsedInIsbound()) {
8157 u.ref.refd_last = this;
8158 } else {
8159 // the sub-reference points to a non-existent field
8160 set_valuetype(V_ERROR);
8161 }
8162 } else {
8163 // a circular recursion was detected
8164 set_valuetype(V_ERROR);
8165 }
8166 if (destroy_refch) delete refch;
8167 else refch->prev_state();
8168 break; }
8169 case Assignment::A_EXT_CONST:
8170 case Assignment::A_MODULEPAR:
8171 case Assignment::A_VAR:
8172 case Assignment::A_FUNCTION_RVAL:
8173 case Assignment::A_EXT_FUNCTION_RVAL:
8174 case Assignment::A_PAR_VAL_IN:
8175 case Assignment::A_PAR_VAL_OUT:
8176 case Assignment::A_PAR_VAL_INOUT:
8177 // the referred definition is not a constant
8178 u.ref.refd_last = this;
8179 break;
8180 case Assignment::A_FUNCTION:
8181 case Assignment::A_EXT_FUNCTION:
8182 u.ref.ref->error("Reference to a value was expected instead of a "
8183 "call of %s, which does not have return type",
8184 ass->get_description().c_str());
8185 set_valuetype(V_ERROR);
8186 break;
8187 case Assignment::A_FUNCTION_RTEMP:
8188 case Assignment::A_EXT_FUNCTION_RTEMP:
8189 u.ref.ref->error("Reference to a value was expected instead of a "
8190 "call of %s, which returns a template",
8191 ass->get_description().c_str());
8192 set_valuetype(V_ERROR);
8193 break;
8194 default:
8195 u.ref.ref->error("Reference to a value was expected instead of %s",
8196 ass->get_description().c_str());
8197 set_valuetype(V_ERROR);
8198 } // switch asstype
8199 }
8200 if (valuetype == V_REFD) return u.ref.refd_last;
8201 else return this;
8202 }
8203 case V_EXPR: {
8204 // try to evaluate the expression
8205 bool destroy_refch;
8206 if(refch) {
8207 refch->mark_state();
8208 destroy_refch=false;
8209 }
8210 else {
8211 refch=new ReferenceChain(this, "While evaluating expression");
8212 destroy_refch=true;
8213 }
8214 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8215 else set_valuetype(V_ERROR);
8216 if(destroy_refch) delete refch;
8217 else refch->prev_state();
8218 return this; }
8219 case V_MACRO:
8220 evaluate_macro(exp_val);
8221 // no break
8222 default:
8223 // return this for all other value types
8224 return this;
8225 } // switch
8226 }
8227
8228 map<Value*, void> Value::UnfoldabilityCheck::running;
8229
8230 /* Note that the logic here needs to be in sync with evaluate_value,
8231 * and possibly others, i.e. if evaluate_value is called for a Value
8232 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8233 bool Value::is_unfoldable(ReferenceChain *refch,
8234 Type::expected_value_t exp_val)
8235 {
8236 if (UnfoldabilityCheck::is_running(this)) {
8237 // This function is already running on this value => infinite recursion
8238 return true;
8239 }
8240
8241 UnfoldabilityCheck checker(this);
8242
8243 if (get_needs_conversion()) return true;
8244 switch (valuetype) {
8245 case V_NAMEDINT:
8246 case V_NAMEDBITS:
8247 case V_OPENTYPE:
8248 case V_UNDEF_LOWERID:
8249 case V_UNDEF_BLOCK:
8250 case V_TTCN3_NULL:
8251 case V_REFER:
8252 // these value types are eliminated during semantic analysis
8253 FATAL_ERROR("Value::is_unfoldable()");
8254 case V_ERROR:
8255 case V_INVOKE:
8256 return true;
8257 case V_CHOICE:
8258 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8259 case V_SEQOF:
8260 case V_SETOF:
8261 case V_ARRAY:
8262 if (!is_indexed()) {
8263 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8264 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8265 return true;
8266 }
8267 } else {
8268 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8269 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8270 return true;
8271 }
8272 }
8273 return false;
8274 case V_SEQ:
8275 case V_SET:
8276 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8277 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8278 ->is_unfoldable(refch, exp_val)) return true;
8279 }
8280 return false;
8281 case V_OID:
8282 case V_ROID:
8283 chk();
8284 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8285 if ((*u.oid_comps)[i]->is_variable()) return true;
8286 }
8287 return false;
8288 case V_REFD: {
8289 Value *v_last=get_value_refd_last(refch, exp_val);
8290 if(v_last==this) return true; // there weren't any references to chase
8291 else return v_last->is_unfoldable(refch, exp_val);
8292 }
8293 case V_EXPR:
8294 // classify the unchecked ischosen() operation, if it was not done so far
8295 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8296 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8297 switch (u.expr.v_optype) {
8298 case OPTYPE_RND: // -
8299 case OPTYPE_COMP_MTC:
8300 case OPTYPE_COMP_SYSTEM:
8301 case OPTYPE_COMP_SELF:
8302 case OPTYPE_COMP_RUNNING_ANY:
8303 case OPTYPE_COMP_RUNNING_ALL:
8304 case OPTYPE_COMP_ALIVE_ANY:
8305 case OPTYPE_COMP_ALIVE_ALL:
8306 case OPTYPE_TMR_RUNNING_ANY:
8307 case OPTYPE_GETVERDICT:
8308 case OPTYPE_TESTCASENAME:
8309 case OPTYPE_RNDWITHVAL: // v1
8310 case OPTYPE_MATCH: // v1 t2
8311 case OPTYPE_UNDEF_RUNNING: // v1
8312 case OPTYPE_COMP_RUNNING:
8313 case OPTYPE_COMP_ALIVE:
8314 case OPTYPE_TMR_READ:
8315 case OPTYPE_TMR_RUNNING:
8316 case OPTYPE_ACTIVATE:
8317 case OPTYPE_ACTIVATE_REFD:
8318 case OPTYPE_EXECUTE: // r1 [v2]
8319 case OPTYPE_EXECUTE_REFD:
8320 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8321 case OPTYPE_ISCHOSEN:
8322 case OPTYPE_ISCHOSEN_T:
8323 case OPTYPE_SIZEOF: // ti1
8324 case OPTYPE_DECODE:
8325 case OPTYPE_ENCODE:
8326 case OPTYPE_OCT2UNICHAR:
8327 case OPTYPE_UNICHAR2OCT:
8328 case OPTYPE_ENCODE_BASE64:
8329 case OPTYPE_DECODE_BASE64:
8330 return true;
8331 case OPTYPE_COMP_NULL: // -
8332 return false;
8333 case OPTYPE_UNARYPLUS: // v1
8334 case OPTYPE_UNARYMINUS:
8335 case OPTYPE_NOT:
8336 case OPTYPE_NOT4B:
8337 case OPTYPE_BIT2HEX:
8338 case OPTYPE_BIT2INT:
8339 case OPTYPE_BIT2OCT:
8340 case OPTYPE_BIT2STR:
8341 case OPTYPE_CHAR2INT:
8342 case OPTYPE_CHAR2OCT:
8343 case OPTYPE_FLOAT2INT:
8344 case OPTYPE_FLOAT2STR:
8345 case OPTYPE_HEX2BIT:
8346 case OPTYPE_HEX2INT:
8347 case OPTYPE_HEX2OCT:
8348 case OPTYPE_HEX2STR:
8349 case OPTYPE_INT2CHAR:
8350 case OPTYPE_INT2FLOAT:
8351 case OPTYPE_INT2STR:
8352 case OPTYPE_INT2UNICHAR:
8353 case OPTYPE_OCT2BIT:
8354 case OPTYPE_OCT2CHAR:
8355 case OPTYPE_OCT2HEX:
8356 case OPTYPE_OCT2INT:
8357 case OPTYPE_OCT2STR:
8358 case OPTYPE_STR2BIT:
8359 case OPTYPE_STR2FLOAT:
8360 case OPTYPE_STR2HEX:
8361 case OPTYPE_STR2INT:
8362 case OPTYPE_STR2OCT:
8363 case OPTYPE_UNICHAR2INT:
8364 case OPTYPE_UNICHAR2CHAR:
8365 case OPTYPE_ENUM2INT:
8366 case OPTYPE_GET_STRINGENCODING:
8367 case OPTYPE_REMOVE_BOM:
8368 return u.expr.v1->is_unfoldable(refch, exp_val);
8369 case OPTYPE_ISBOUND: /*{
8370 //TODO once we have the time for it make isbound foldable.
8371 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8372 Template* temp = u.expr.ti1->get_Template();
8373 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8374 Value* specificValue = temp->get_specific_value();
8375 if (specificValue->get_valuetype() == Value::V_REFD) {
8376 //FIXME implement
8377 }
8378
8379 return specificValue->is_unfoldable(refch, exp_val);
8380 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8381 //FIXME implement
8382 }
8383 }*/
8384 return true;
8385 case OPTYPE_ISPRESENT:
8386 // TODO: "if you have motivation"
8387 return true;
8388 case OPTYPE_ISVALUE: // ti1
8389 // fallthrough
8390 case OPTYPE_LENGTHOF: // ti1
8391 return u.expr.ti1->get_DerivedRef() != 0
8392 || u.expr.ti1->get_Template()->get_templatetype()
8393 != Template::SPECIFIC_VALUE
8394 || u.expr.ti1->get_Template()->get_specific_value()
8395 ->is_unfoldable(refch, exp_val);
8396 case OPTYPE_ROTL:
8397 case OPTYPE_ROTR:
8398 case OPTYPE_CONCAT:
8399 if (!u.expr.v1->is_string_type(exp_val)) return true;
8400 // no break
8401 case OPTYPE_ADD: // v1 v2
8402 case OPTYPE_SUBTRACT:
8403 case OPTYPE_MULTIPLY:
8404 case OPTYPE_DIVIDE:
8405 case OPTYPE_MOD:
8406 case OPTYPE_REM:
8407 case OPTYPE_EQ:
8408 case OPTYPE_LT:
8409 case OPTYPE_GT:
8410 case OPTYPE_NE:
8411 case OPTYPE_GE:
8412 case OPTYPE_LE:
8413 case OPTYPE_XOR:
8414 case OPTYPE_AND4B:
8415 case OPTYPE_OR4B:
8416 case OPTYPE_XOR4B:
8417 case OPTYPE_SHL:
8418 case OPTYPE_SHR:
8419 case OPTYPE_INT2BIT:
8420 case OPTYPE_INT2HEX:
8421 case OPTYPE_INT2OCT:
8422 return u.expr.v1->is_unfoldable(refch, exp_val)
8423 || u.expr.v2->is_unfoldable(refch, exp_val);
8424 case OPTYPE_AND: // short-circuit evaluation
8425 return u.expr.v1->is_unfoldable(refch, exp_val)
8426 || (u.expr.v1->get_val_bool() &&
8427 u.expr.v2->is_unfoldable(refch, exp_val));
8428 case OPTYPE_OR: // short-circuit evaluation
8429 return u.expr.v1->is_unfoldable(refch, exp_val)
8430 || (!u.expr.v1->get_val_bool() &&
8431 u.expr.v2->is_unfoldable(refch, exp_val));
8432 case OPTYPE_SUBSTR:
8433 if (!u.expr.ti1->get_specific_value()) return true;
8434 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8435 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8436 || u.expr.v2->is_unfoldable(refch, exp_val)
8437 || u.expr.v3->is_unfoldable(refch, exp_val);
8438 case OPTYPE_REGEXP:
8439 if (!u.expr.ti1->get_specific_value() ||
8440 !u.expr.t2->get_specific_value()) return true;
8441 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8442 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8443 || u.expr.v3->is_unfoldable(refch, exp_val);
8444 case OPTYPE_DECOMP:
8445 return u.expr.v1->is_unfoldable(refch, exp_val)
8446 || u.expr.v2->is_unfoldable(refch, exp_val)
8447 || u.expr.v3->is_unfoldable(refch, exp_val);
8448 case OPTYPE_REPLACE: {
8449 if (!u.expr.ti1->get_specific_value() ||
8450 !u.expr.ti4->get_specific_value()) return true;
8451 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8452 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8453 || u.expr.v2->is_unfoldable(refch, exp_val)
8454 || u.expr.v3->is_unfoldable(refch, exp_val)
8455 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8456 }
8457 case OPTYPE_VALUEOF: // ti1
8458 /* \todo if you have motivation to implement the eval function
8459 for valueof()... */
8460 return true;
8461 case OPTYPE_ISCHOSEN_V:
8462 return u.expr.v1->is_unfoldable(refch, exp_val);
8463 case OPTYPE_LOG2STR:
8464 case OPTYPE_TTCN2STRING:
8465 return true;
8466 default:
8467 FATAL_ERROR("Value::is_unfoldable()");
8468 } // switch
8469 break; // should never get here
8470 case V_MACRO:
8471 switch (u.macro) {
8472 case MACRO_TESTCASEID:
8473 // this is known only at runtime
8474 return true;
8475 default:
8476 return false;
8477 }
8478 default:
8479 // all literal values are foldable
8480 return false;
8481 }
8482 }
8483
8484 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8485 size_t start_i, bool usedInIsbound,
8486 ReferenceChain *refch)
8487 {
8488 if (!subrefs) return this;
8489 Value *v = this;
8490 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8491 if (!v) break;
8492 v = v->get_value_refd_last(refch);
8493 switch(v->valuetype) {
8494 case V_ERROR:
8495 return v;
8496 case V_REFD:
8497 // unfoldable stuff
8498 return this;
8499 default:
8500 break;
8501 } // switch
8502 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8503 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8504 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8505 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8506 }
8507 return v;
8508 }
8509
8510 Value *Value::get_refd_field_value(const Identifier& field_id,
8511 bool usedInIsbound, const Location& loc)
8512 {
8513 if (valuetype == V_OMIT) {
8514 loc.error("Reference to field `%s' of omit value `%s'",
8515 field_id.get_dispname().c_str(), get_fullname().c_str());
8516 return 0;
8517 }
8518 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8519 Type *t = my_governor->get_type_refd_last();
8520 switch (t->get_typetype()) {
8521 case Type::T_ERROR:
8522 // remain silent
8523 return 0;
8524 case Type::T_CHOICE_A:
8525 case Type::T_CHOICE_T:
8526 case Type::T_OPENTYPE:
8527 case Type::T_ANYTYPE:
8528 if (!t->has_comp_withName(field_id)) {
8529 loc.error("Reference to non-existent union field `%s' in type `%s'",
8530 field_id.get_dispname().c_str(), t->get_typename().c_str());
8531 return 0;
8532 } else if (valuetype != V_CHOICE) {
8533 // remain silent, the error is already reported
8534 return 0;
8535 } else if (*u.choice.alt_name == field_id) {
8536 // everything is OK
8537 return u.choice.alt_value;
8538 }else {
8539 if (!usedInIsbound) {
8540 loc.error("Reference to inactive field `%s' in a value of union type "
8541 "`%s'. The active field is `%s'",
8542 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8543 u.choice.alt_name->get_dispname().c_str());
8544 }
8545 return 0;
8546 }
8547 case Type::T_SEQ_A:
8548 case Type::T_SEQ_T:
8549 if (!t->has_comp_withName(field_id)) {
8550 loc.error("Reference to non-existent record field `%s' in type `%s'",
8551 field_id.get_dispname().c_str(), t->get_typename().c_str());
8552 return 0;
8553 } else if (valuetype != V_SEQ) {
8554 // remain silent, the error has been already reported
8555 return 0;
8556 } else break;
8557 case Type::T_SET_A:
8558 case Type::T_SET_T:
8559 if (!t->has_comp_withName(field_id)) {
8560 loc.error("Reference to non-existent set field `%s' in type `%s'",
8561 field_id.get_dispname().c_str(), t->get_typename().c_str());
8562 return 0;
8563 } else if (valuetype != V_SET) {
8564 // remain silent, the error has been already reported
8565 return 0;
8566 } else break;
8567 default:
8568 loc.error("Invalid field reference `%s': type `%s' "
8569 "does not have fields", field_id.get_dispname().c_str(),
8570 t->get_typename().c_str());
8571 return 0;
8572 }
8573 // the common end for record & set types
8574 if (u.val_nvs->has_nv_withName(field_id)) {
8575 // everything is OK
8576 return u.val_nvs->get_nv_byName(field_id)->get_value();
8577 } else if (!is_asn1()) {
8578 if (!usedInIsbound) {
8579 loc.error("Reference to unbound field `%s'",
8580 field_id.get_dispname().c_str());
8581 // this is an error in TTCN-3, which has been already reported
8582 }
8583 return 0;
8584 } else {
8585 CompField *cf = t->get_comp_byName(field_id);
8586 if (cf->get_is_optional()) {
8587 // creating an explicit omit value
8588 Value *v = new Value(V_OMIT);
8589 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8590 v->set_my_scope(get_my_scope());
8591 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8592 return v;
8593 } else if (cf->has_default()) {
8594 // returning the component's default value
8595 return cf->get_defval();
8596 } else {
8597 // this is an error in ASN.1, which has been already reported
8598 return 0;
8599 }
8600 }
8601 }
8602
8603 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8604 ReferenceChain *refch)
8605 {
8606 Value *v_index = array_index->get_value_refd_last(refch);
8607 Int index = 0;
8608 bool index_available = false;
8609 if (!v_index->is_unfoldable()) {
8610 if (v_index->valuetype == V_INT) {
8611 index = v_index->get_val_Int()->get_val();
8612 index_available = true;
8613 } else {
8614 array_index->error("An integer value was expected as index");
8615 }
8616 }
8617 if (valuetype == V_OMIT) {
8618 array_index->error("Accessing an element with index of omit value `%s'",
8619 get_fullname().c_str());
8620 return 0;
8621 }
8622 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8623 Type *t = my_governor->get_type_refd_last();
8624 switch (t->get_typetype()) {
8625 case Type::T_ERROR:
8626 // remain silent
8627 return 0;
8628 case Type::T_SEQOF:
8629 if (index_available) {
8630 if (index < 0) {
8631 array_index->error("A non-negative integer value was expected "
8632 "instead of %s for indexing a value of `record "
8633 "of' type `%s'", Int2string(index).c_str(),
8634 t->get_typename().c_str());
8635 return 0;
8636 }
8637 switch (valuetype) {
8638 case V_SEQOF:
8639 if (!is_indexed()) {
8640 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8641 if (!usedInIsbound) {
8642 array_index->error("Index overflow in a value of `record of' "
8643 "type `%s': the index is %s, but the value "
8644 "has only %lu elements",
8645 t->get_typename().c_str(),
8646 Int2string(index).c_str(),
8647 (unsigned long)u.val_vs->get_nof_vs());
8648 }
8649 return 0;
8650 } else {
8651 Value* temp = u.val_vs->get_v_byIndex(index);
8652 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8653 temp->error("Not used symbol is not allowed in this context");
8654 return u.val_vs->get_v_byIndex(index);
8655 }
8656 } else {
8657 // Search the appropriate constant index.
8658 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8659 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8660 ->get_value_refd_last();
8661 if (iv_index->get_valuetype() != V_INT) continue;
8662 if (iv_index->get_val_Int()->get_val() == index)
8663 return u.val_vs->get_iv_byIndex(i)->get_value();
8664 }
8665 return 0;
8666 }
8667 break;
8668 default:
8669 // remain silent, the error has been already reported
8670 return 0;
8671 }
8672 } else {
8673 // the error has been reported above
8674 return 0;
8675 }
8676 case Type::T_SETOF:
8677 if (index_available) {
8678 if (index < 0) {
8679 array_index->error("A non-negative integer value was expected "
8680 "instead of %s for indexing a value of `set of' type `%s'",
8681 Int2string(index).c_str(), t->get_typename().c_str());
8682 return 0;
8683 }
8684 switch (valuetype) {
8685 case V_SETOF:
8686 if (!is_indexed()) {
8687 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8688 if (!usedInIsbound) {
8689 array_index->error("Index overflow in a value of `set of' type "
8690 "`%s': the index is %s, but the value has "
8691 "only %lu elements",
8692 t->get_typename().c_str(),
8693 Int2string(index).c_str(),
8694 (unsigned long)u.val_vs->get_nof_vs());
8695 }
8696 return 0;
8697 } else {
8698 Value* temp = u.val_vs->get_v_byIndex(index);
8699 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8700 temp->error("Not used symbol is not allowed in this context");
8701 return temp;
8702 }
8703 } else {
8704 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8705 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8706 ->get_value_refd_last();
8707 if (iv_index->get_valuetype() != V_INT) continue;
8708 if (iv_index->get_val_Int()->get_val() == index)
8709 return u.val_vs->get_iv_byIndex(i)->get_value();
8710 }
8711 return 0;
8712 }
8713 break;
8714 default:
8715 // remain silent, the error has been already reported
8716 return 0;
8717 }
8718 } else {
8719 // the error has been reported above
8720 return 0;
8721 }
8722 case Type::T_ARRAY:
8723 if (index_available) {
8724 Ttcn::ArrayDimension *dim = t->get_dimension();
8725 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8726 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8727 // perform the index transformation
8728 index -= dim->get_offset();
8729 if (!is_indexed()) {
8730 // check for index underflow/overflow or too few elements in the
8731 // value
8732 if (index < 0 ||
8733 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8734 return 0;
8735 else return u.val_vs->get_v_byIndex(index);
8736 } else {
8737 if (index < 0) return 0;
8738 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8739 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8740 ->get_value_refd_last();
8741 if (iv_index->get_valuetype() != V_INT) continue;
8742 if (iv_index->get_val_Int()->get_val() == index)
8743 return u.val_vs->get_iv_byIndex(index)->get_value();
8744 }
8745 return 0;
8746 }
8747 } else {
8748 // remain silent, the error has been already reported
8749 return 0;
8750 }
8751 } else {
8752 // the error has been reported above
8753 return 0;
8754 }
8755 case Type::T_BSTR:
8756 case Type::T_BSTR_A:
8757 case Type::T_HSTR:
8758 case Type::T_OSTR:
8759 case Type::T_CSTR:
8760 case Type::T_USTR:
8761 case Type::T_UTF8STRING:
8762 case Type::T_NUMERICSTRING:
8763 case Type::T_PRINTABLESTRING:
8764 case Type::T_TELETEXSTRING:
8765 case Type::T_VIDEOTEXSTRING:
8766 case Type::T_IA5STRING:
8767 case Type::T_GRAPHICSTRING:
8768 case Type::T_VISIBLESTRING:
8769 case Type::T_GENERALSTRING:
8770 case Type::T_UNIVERSALSTRING:
8771 case Type::T_BMPSTRING:
8772 case Type::T_UTCTIME:
8773 case Type::T_GENERALIZEDTIME:
8774 case Type::T_OBJECTDESCRIPTOR:
8775 if (index_available) return get_string_element(index, *array_index);
8776 else return 0;
8777 default:
8778 array_index->error("Invalid array element reference: type `%s' cannot "
8779 "be indexed", t->get_typename().c_str());
8780 return 0;
8781 }
8782 }
8783
8784 Value *Value::get_string_element(const Int& index, const Location& loc)
8785 {
8786 if (index < 0) {
8787 loc.error("A non-negative integer value was expected instead of %s "
8788 "for indexing a string element", Int2string(index).c_str());
8789 return 0;
8790 }
8791 size_t string_length;
8792 switch (valuetype) {
8793 case V_BSTR:
8794 case V_HSTR:
8795 case V_CSTR:
8796 case V_ISO2022STR:
8797 string_length = u.str.val_str->size();
8798 break;
8799 case V_OSTR:
8800 string_length = u.str.val_str->size() / 2;
8801 break;
8802 case V_USTR:
8803 string_length = u.ustr.val_ustr->size();
8804 break;
8805 default:
8806 // remain silent, the error has been already reported
8807 return 0;
8808 }
8809 if (index >= static_cast<Int>(string_length)) {
8810 loc.error("Index overflow when accessing a string element: "
8811 "the index is %s, but the string has only %lu elements",
8812 Int2string(index).c_str(), (unsigned long) string_length);
8813 return 0;
8814 }
8815 switch (valuetype) {
8816 case V_BSTR:
8817 case V_HSTR:
8818 case V_CSTR:
8819 case V_ISO2022STR:
8820 if (u.str.str_elements && u.str.str_elements->has_key(index))
8821 return (*u.str.str_elements)[index];
8822 else {
8823 Value *t_val = new Value(valuetype,
8824 new string(u.str.val_str->substr(index, 1)));
8825 add_string_element(index, t_val, u.str.str_elements);
8826 return t_val;
8827 }
8828 case V_OSTR:
8829 if (u.str.str_elements && u.str.str_elements->has_key(index))
8830 return (*u.str.str_elements)[index];
8831 else {
8832 Value *t_val = new Value(V_OSTR,
8833 new string(u.str.val_str->substr(2 * index, 2)));
8834 add_string_element(index, t_val, u.str.str_elements);
8835 return t_val;
8836 }
8837 case V_USTR:
8838 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
8839 return (*u.ustr.ustr_elements)[index];
8840 else {
8841 Value *t_val = new Value(V_USTR,
8842 new ustring(u.ustr.val_ustr->substr(index, 1)));
8843 add_string_element(index, t_val, u.ustr.ustr_elements);
8844 return t_val;
8845 }
8846 default:
8847 FATAL_ERROR("Value::get_string_element()");
8848 return 0;
8849 }
8850 }
8851
8852 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
8853 Type::expected_value_t exp_val)
8854 {
8855 set_lowerid_to_ref();
8856 Type::typetype_t r_tt = get_expr_returntype(exp_val);
8857 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
8858 if (error_flag)
8859 error("A value or expression of type %s was expected", type_name);
8860 if (valuetype == V_REFD) {
8861 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
8862 t_chk->chk_this_refd_value(this, 0, exp_val);
8863 }
8864 get_value_refd_last(0, exp_val);
8865 if (error_flag) set_valuetype(V_ERROR);
8866 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
8867 }
8868
8869 int Value::is_parsed_infinity()
8870 {
8871 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
8872 return 1;
8873 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
8874 (u.expr.v1->get_valuetype()==V_REAL) &&
8875 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
8876 return -1;
8877 return 0;
8878 }
8879
8880 bool Value::get_val_bool()
8881 {
8882 Value *v;
8883 if (valuetype == V_REFD) v = get_value_refd_last();
8884 else v = this;
8885 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
8886 return v->u.val_bool;
8887 }
8888
8889 int_val_t* Value::get_val_Int()
8890 {
8891 Value *v;
8892 if (valuetype == V_REFD) v = get_value_refd_last();
8893 else v = this;
8894 switch (v->valuetype) {
8895 case V_INT:
8896 break;
8897 case V_UNDEF_LOWERID:
8898 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8899 "`%s'", (*u.val_id).get_dispname().c_str());
8900 default:
8901 FATAL_ERROR("Value::get_val_Int()");
8902 } // switch
8903 return v->u.val_Int;
8904 }
8905
8906 const Identifier* Value::get_val_id()
8907 {
8908 switch(valuetype) {
8909 case V_NAMEDINT:
8910 case V_ENUM:
8911 case V_UNDEF_LOWERID:
8912 return u.val_id;
8913 default:
8914 FATAL_ERROR("Value::get_val_id()");
8915 return 0;
8916 } // switch
8917 }
8918
8919 const ttcn3float& Value::get_val_Real()
8920 {
8921 Value *v;
8922 if (valuetype == V_REFD) v = get_value_refd_last();
8923 else v = this;
8924 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
8925 return v->u.val_Real;
8926 }
8927
8928 string Value::get_val_str()
8929 {
8930 Value *v = get_value_refd_last();
8931 switch (v->valuetype) {
8932 case V_BSTR:
8933 case V_HSTR:
8934 case V_OSTR:
8935 case V_CSTR:
8936 return *v->u.str.val_str;
8937 case V_CHARSYMS:
8938 return v->u.char_syms->get_string();
8939 case V_USTR:
8940 error("Cannot use ISO-10646 string value in string context");
8941 return string();
8942 case V_ISO2022STR:
8943 error("Cannot use ISO-2022 string value in string context");
8944 // no break
8945 case V_ERROR:
8946 return string();
8947 default:
8948 error("Cannot use this value in charstring value context");
8949 return string();
8950 } // switch
8951 }
8952
8953 ustring Value::get_val_ustr()
8954 {
8955 Value *v = get_value_refd_last();
8956 switch (v->valuetype) {
8957 case V_CSTR:
8958 return ustring(*v->u.str.val_str);
8959 case V_USTR:
8960 return *v->u.ustr.val_ustr;
8961 case V_CHARSYMS:
8962 return v->u.char_syms->get_ustring();
8963 case V_ISO2022STR:
8964 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8965 // no break
8966 case V_ERROR:
8967 return ustring();
8968 default:
8969 error("Cannot use this value in ISO-10646 string context");
8970 return ustring();
8971 } // switch
8972 }
8973
8974 string Value::get_val_iso2022str()
8975 {
8976 Value *v = get_value_refd_last();
8977 switch (v->valuetype) {
8978 case V_CSTR:
8979 case V_ISO2022STR:
8980 return *v->u.str.val_str;
8981 case V_CHARSYMS:
8982 return v->u.char_syms->get_iso2022string();
8983 case V_USTR:
8984 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8985 // no break
8986 case V_ERROR:
8987 return string();
8988 default:
8989 error("Cannot use this value in ISO-2022 string context");
8990 return string();
8991 } // switch
8992 }
8993
8994 size_t Value::get_val_strlen()
8995 {
8996 Value *v = get_value_refd_last();
8997 switch (v->valuetype) {
8998 case V_BSTR:
8999 case V_HSTR:
9000 case V_CSTR:
9001 case V_ISO2022STR:
9002 return v->u.str.val_str->size();
9003 case V_OSTR:
9004 return v->u.str.val_str->size()/2;
9005 case V_CHARSYMS:
9006 return v->u.char_syms->get_len();
9007 case V_USTR:
9008 return v->u.ustr.val_ustr->size();
9009 case V_ERROR:
9010 return 0;
9011 default:
9012 error("Cannot use this value in string value context");
9013 return 0;
9014 } // switch
9015 }
9016
9017 Value::verdict_t Value::get_val_verdict()
9018 {
9019 switch(valuetype) {
9020 case V_VERDICT:
9021 return u.verdict;
9022 default:
9023 FATAL_ERROR("Value::get_val_verdict()");
9024 return u.verdict;
9025 } // switch
9026 }
9027
9028 size_t Value::get_nof_comps()
9029 {
9030 switch (valuetype) {
9031 case V_OID:
9032 case V_ROID:
9033 chk();
9034 return u.oid_comps->size();
9035 case V_SEQOF:
9036 case V_SETOF:
9037 case V_ARRAY:
9038 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9039 else return u.val_vs->get_nof_vs();
9040 case V_SEQ:
9041 case V_SET:
9042 return u.val_nvs->get_nof_nvs();
9043 case V_BSTR:
9044 case V_HSTR:
9045 case V_CSTR:
9046 case V_ISO2022STR:
9047 return u.str.val_str->size();
9048 case V_OSTR:
9049 return u.str.val_str->size()/2;
9050 case V_USTR:
9051 return u.ustr.val_ustr->size();
9052 default:
9053 FATAL_ERROR("Value::get_nof_comps()");
9054 return 0;
9055 } // switch
9056 }
9057
9058 bool Value::is_indexed() const
9059 {
9060 switch (valuetype) {
9061 case V_SEQOF:
9062 case V_SETOF:
9063 case V_ARRAY:
9064 // Applicable only for list-types. Assigning a record/SEQUENCE or
9065 // set/SET with indexed notation is not supported.
9066 return u.val_vs->is_indexed();
9067 default:
9068 FATAL_ERROR("Value::is_indexed()");
9069 break;
9070 }
9071 return false;
9072 }
9073
9074 const Identifier& Value::get_alt_name()
9075 {
9076 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9077 return *u.choice.alt_name;
9078 }
9079
9080 Value *Value::get_alt_value()
9081 {
9082 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9083 return u.choice.alt_value;
9084 }
9085
9086 bool Value::has_oid_error()
9087 {
9088 Value *v;
9089 if (valuetype == V_REFD) v = get_value_refd_last();
9090 else v = this;
9091 switch (valuetype) {
9092 case V_OID:
9093 case V_ROID:
9094 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9095 if ((*v->u.oid_comps)[i]->has_error()) return true;
9096 return false;
9097 default:
9098 return true;
9099 }
9100 }
9101
9102 bool Value::get_oid_comps(vector<string>& comps)
9103 {
9104 bool ret_val = true;
9105 Value *v = this;
9106 switch (valuetype) {
9107 case V_REFD:
9108 v = get_value_refd_last();
9109 // no break
9110 case V_OID:
9111 case V_ROID:
9112 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9113 (*v->u.oid_comps)[i]->get_comps(comps);
9114 if ((*v->u.oid_comps)[i]->is_variable()) {
9115 // not all components can be calculated in compile-time
9116 ret_val = false;
9117 }
9118 }
9119 break;
9120 default:
9121 FATAL_ERROR("Value::get_oid_comps()");
9122 }
9123 return ret_val;
9124 }
9125
9126 void Value::add_se_comp(NamedValue* nv) {
9127 switch (valuetype) {
9128 case V_SEQ:
9129 case V_SET:
9130 if (!u.val_nvs)
9131 u.val_nvs = new NamedValues();
9132 u.val_nvs->add_nv(nv);
9133 break;
9134 default:
9135 FATAL_ERROR("Value::add_se_comp()");
9136 }
9137 }
9138
9139 NamedValue* Value::get_se_comp_byIndex(size_t n)
9140 {
9141 switch(valuetype) {
9142 case V_SEQ:
9143 case V_SET:
9144 return u.val_nvs->get_nv_byIndex(n);
9145 default:
9146 FATAL_ERROR("Value::get_se_comp_byIndex()");
9147 return 0;
9148 } // switch
9149 }
9150
9151 Value *Value::get_comp_byIndex(size_t n)
9152 {
9153 switch (valuetype) {
9154 case V_SEQOF:
9155 case V_SETOF:
9156 case V_ARRAY:
9157 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9158 return u.val_vs->get_iv_byIndex(n)->get_value();
9159 default:
9160 FATAL_ERROR("Value::get_comp_byIndex()");
9161 return 0;
9162 } // switch
9163 }
9164
9165 Value *Value::get_index_byIndex(size_t n)
9166 {
9167 switch (valuetype) {
9168 case V_SEQOF:
9169 case V_SETOF:
9170 case V_ARRAY:
9171 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9172 return u.val_vs->get_iv_byIndex(n)->get_index();
9173 default:
9174 FATAL_ERROR("Value::get_index_byIndex()");
9175 return 0;
9176 } // switch
9177 }
9178
9179 bool Value::has_comp_withName(const Identifier& p_name)
9180 {
9181 switch(valuetype) {
9182 case V_SEQ:
9183 case V_SET:
9184 return u.val_nvs->has_nv_withName(p_name);
9185 case V_CHOICE:
9186 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9187 default:
9188 FATAL_ERROR("Value::get_has_comp_withName()");
9189 return false;
9190 } // switch
9191 }
9192
9193 bool Value::field_is_chosen(const Identifier& p_name)
9194 {
9195 Value *v=get_value_refd_last();
9196 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9197 return *v->u.choice.alt_name==p_name;
9198 }
9199
9200 bool Value::field_is_present(const Identifier& p_name)
9201 {
9202 Value *v=get_value_refd_last();
9203 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9204 FATAL_ERROR("Value::field_is_present()");
9205 return v->u.val_nvs->has_nv_withName(p_name)
9206 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9207 ->get_value_refd_last()->valuetype != V_OMIT;
9208 }
9209
9210 NamedValue* Value::get_se_comp_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);
9216 default:
9217 FATAL_ERROR("Value::get_se_comp_byName()");
9218 return 0;
9219 } // switch
9220 }
9221
9222 Value* Value::get_comp_value_byName(const Identifier& p_name)
9223 {
9224 switch(valuetype) {
9225 case V_SEQ:
9226 case V_SET:
9227 return u.val_nvs->get_nv_byName(p_name)->get_value();
9228 case V_CHOICE:
9229 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9230 return u.choice.alt_value;
9231 else
9232 return NULL;
9233 default:
9234 FATAL_ERROR("Value::get_se_comp_byName()");
9235 return 0;
9236 } // switch
9237 }
9238
9239 void Value::chk_dupl_id()
9240 {
9241 switch(valuetype) {
9242 case V_SEQ:
9243 case V_SET:
9244 u.val_nvs->chk_dupl_id();
9245 break;
9246 default:
9247 FATAL_ERROR("Value::chk_dupl_id()");
9248 } // switch
9249 }
9250
9251 size_t Value::get_nof_ids() const
9252 {
9253 switch(valuetype) {
9254 case V_NAMEDBITS:
9255 return u.ids->size();
9256 break;
9257 default:
9258 FATAL_ERROR("Value::get_nof_ids()");
9259 return 0;
9260 } // switch
9261 }
9262
9263 Identifier* Value::get_id_byIndex(size_t p_i)
9264 {
9265 switch(valuetype) {
9266 case V_NAMEDBITS:
9267 return u.ids->get_nth_elem(p_i);
9268 break;
9269 default:
9270 FATAL_ERROR("Value::get_id_byIndex()");
9271 return 0;
9272 } // switch
9273 }
9274
9275 bool Value::has_id(const Identifier& p_id)
9276 {
9277 switch(valuetype) {
9278 case V_NAMEDBITS:
9279 return u.ids->has_key(p_id.get_name());
9280 break;
9281 default:
9282 FATAL_ERROR("Value::has_id()");
9283 return false;
9284 } // switch
9285 }
9286
9287 Reference *Value::get_reference() const
9288 {
9289 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9290 return u.ref.ref;
9291 }
9292
9293 Reference *Value::get_refered() const
9294 {
9295 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9296 return u.refered;
9297 }
9298
9299 Common::Assignment *Value::get_refd_fat() const
9300 {
9301 switch(valuetype){
9302 case V_FUNCTION:
9303 case V_ALTSTEP:
9304 case V_TESTCASE:
9305 return u.refd_fat;
9306 default:
9307 FATAL_ERROR("Value::get_refd_fat()");
9308 }
9309 }
9310
9311 Ttcn::Reference* Value::steal_ttcn_ref()
9312 {
9313 Ttcn::Reference *ret_val =
9314 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9315 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9316 return ret_val;
9317 }
9318
9319 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9320 {
9321 Ttcn::Ref_base *t_ref;
9322 if(valuetype==V_REFD) {
9323 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9324 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9325 u.ref.ref=0;
9326 }
9327 else if(valuetype==V_UNDEF_LOWERID) {
9328 t_ref=new Ttcn::Reference(u.val_id);
9329 t_ref->set_location(*this);
9330 t_ref->set_fullname(get_fullname());
9331 t_ref->set_my_scope(get_my_scope());
9332 u.val_id=0;
9333 }
9334 else {
9335 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9336 t_ref = 0;
9337 }
9338 set_valuetype(V_ERROR);
9339 return t_ref;
9340 }
9341
9342 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9343 Ttcn::ActualParList*& p_ap)
9344 {
9345 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9346 p_v = u.invoke.v;
9347 u.invoke.v = 0;
9348 p_ti = u.invoke.t_list;
9349 u.invoke.t_list = 0;
9350 p_ap = u.invoke.ap_list;
9351 u.invoke.ap_list = 0;
9352 set_valuetype(V_ERROR);
9353 }
9354
9355 Common::Assignment* Value::get_refd_assignment()
9356 {
9357 switch(valuetype) {
9358 case V_FUNCTION:
9359 case V_ALTSTEP:
9360 case V_TESTCASE:
9361 return u.refd_fat;
9362 break;
9363 default:
9364 FATAL_ERROR("Value::get_refd_assignment()");
9365 return 0;
9366 }
9367 }
9368
9369 void Value::chk()
9370 {
9371 if(checked) return;
9372 switch(valuetype) {
9373 case V_OID: {
9374 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9375 " components");
9376 chk_OID(refch);
9377 break; }
9378 case V_ROID: {
9379 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9380 chk_ROID(refch);
9381 break; }
9382 default:
9383 break;
9384 } // switch
9385 checked=true;
9386 }
9387
9388 void Value::chk_OID(ReferenceChain& refch)
9389 {
9390 if (checked) return;
9391 if (valuetype != V_OID || u.oid_comps->size() < 1)
9392 FATAL_ERROR("Value::chk_OID()");
9393 if (!refch.add(get_fullname())) {
9394 checked = true;
9395 return;
9396 }
9397 OID_comp::oidstate_t state = OID_comp::START;
9398 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9399 refch.mark_state();
9400 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9401 refch.prev_state();
9402 }
9403 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9404 error("An OBJECT IDENTIFIER value must have at least "
9405 "two components"); // X.680 (07/2002) 31.10
9406 }
9407
9408 void Value::chk_ROID(ReferenceChain& refch)
9409 {
9410 if (checked) return;
9411 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9412 FATAL_ERROR("Value::chk_ROID()");
9413 if (!refch.add(get_fullname())) {
9414 checked = true;
9415 return;
9416 }
9417 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9418 refch.mark_state();
9419 (*u.oid_comps)[i]->chk_ROID(refch, i);
9420 refch.prev_state();
9421 }
9422 }
9423
9424 void Value::chk_recursions(ReferenceChain& refch)
9425 {
9426 if (recurs_checked) return;
9427 Value *v = get_value_refd_last();
9428 if (refch.add(v->get_fullname())) {
9429 switch (v->valuetype) {
9430 case V_CHOICE:
9431 v->u.choice.alt_value->chk_recursions(refch);
9432 break;
9433 case V_SEQOF:
9434 case V_SETOF:
9435 case V_ARRAY:
9436 if (!v->is_indexed()) {
9437 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9438 refch.mark_state();
9439 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9440 refch.prev_state();
9441 }
9442 } else {
9443 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9444 refch.mark_state();
9445 v->u.val_vs->get_iv_byIndex(i)->get_value()
9446 ->chk_recursions(refch);
9447 refch.prev_state();
9448 }
9449 }
9450 break;
9451 case V_SEQ:
9452 case V_SET:
9453 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9454 refch.mark_state();
9455 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9456 refch.prev_state();
9457 }
9458 break;
9459 case V_EXPR:
9460 chk_recursions_expr(refch);
9461 break;
9462 default:
9463 break;
9464 }
9465 if (v->err_descr) { // FIXME: make this work
9466 v->err_descr->chk_recursions(refch);
9467 }
9468 }
9469 recurs_checked = true;
9470 }
9471
9472 void Value::chk_recursions_expr(ReferenceChain& refch)
9473 {
9474 // first classify the unchecked ischosen() operation
9475 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9476 switch (u.expr.v_optype) {
9477 case OPTYPE_UNARYPLUS: // v1
9478 case OPTYPE_UNARYMINUS:
9479 case OPTYPE_NOT:
9480 case OPTYPE_NOT4B:
9481 case OPTYPE_BIT2HEX:
9482 case OPTYPE_BIT2INT:
9483 case OPTYPE_BIT2OCT:
9484 case OPTYPE_BIT2STR:
9485 case OPTYPE_CHAR2INT:
9486 case OPTYPE_CHAR2OCT:
9487 case OPTYPE_FLOAT2INT:
9488 case OPTYPE_FLOAT2STR:
9489 case OPTYPE_HEX2BIT:
9490 case OPTYPE_HEX2INT:
9491 case OPTYPE_HEX2OCT:
9492 case OPTYPE_HEX2STR:
9493 case OPTYPE_INT2CHAR:
9494 case OPTYPE_INT2FLOAT:
9495 case OPTYPE_INT2STR:
9496 case OPTYPE_INT2UNICHAR:
9497 case OPTYPE_OCT2BIT:
9498 case OPTYPE_OCT2CHAR:
9499 case OPTYPE_OCT2HEX:
9500 case OPTYPE_OCT2INT:
9501 case OPTYPE_OCT2STR:
9502 case OPTYPE_STR2BIT:
9503 case OPTYPE_STR2FLOAT:
9504 case OPTYPE_STR2HEX:
9505 case OPTYPE_STR2INT:
9506 case OPTYPE_STR2OCT:
9507 case OPTYPE_UNICHAR2INT:
9508 case OPTYPE_ENUM2INT:
9509 case OPTYPE_UNICHAR2CHAR:
9510 case OPTYPE_RNDWITHVAL:
9511 case OPTYPE_ISCHOSEN_V:
9512 case OPTYPE_GET_STRINGENCODING:
9513 case OPTYPE_REMOVE_BOM:
9514 case OPTYPE_DECODE_BASE64:
9515 refch.mark_state();
9516 u.expr.v1->chk_recursions(refch);
9517 refch.prev_state();
9518 break;
9519 case OPTYPE_ISCHOSEN_T:
9520 refch.mark_state();
9521 u.expr.t1->chk_recursions(refch);
9522 refch.prev_state();
9523 break;
9524 case OPTYPE_ADD: // v1 v2
9525 case OPTYPE_SUBTRACT:
9526 case OPTYPE_MULTIPLY:
9527 case OPTYPE_DIVIDE:
9528 case OPTYPE_MOD:
9529 case OPTYPE_REM:
9530 case OPTYPE_CONCAT:
9531 case OPTYPE_EQ:
9532 case OPTYPE_LT:
9533 case OPTYPE_GT:
9534 case OPTYPE_NE:
9535 case OPTYPE_GE:
9536 case OPTYPE_LE:
9537 case OPTYPE_AND:
9538 case OPTYPE_OR:
9539 case OPTYPE_XOR:
9540 case OPTYPE_AND4B:
9541 case OPTYPE_OR4B:
9542 case OPTYPE_XOR4B:
9543 case OPTYPE_SHL:
9544 case OPTYPE_SHR:
9545 case OPTYPE_ROTL:
9546 case OPTYPE_ROTR:
9547 case OPTYPE_INT2BIT:
9548 case OPTYPE_INT2HEX:
9549 case OPTYPE_INT2OCT:
9550 refch.mark_state();
9551 u.expr.v1->chk_recursions(refch);
9552 refch.prev_state();
9553 refch.mark_state();
9554 u.expr.v2->chk_recursions(refch);
9555 refch.prev_state();
9556 break;
9557 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9558 case OPTYPE_OCT2UNICHAR:
9559 case OPTYPE_ENCODE_BASE64:
9560 refch.mark_state();
9561 u.expr.v1->chk_recursions(refch);
9562 refch.prev_state();
9563 if (u.expr.v2) {
9564 refch.mark_state();
9565 u.expr.v2->chk_recursions(refch);
9566 refch.prev_state();
9567 }
9568 break;
9569 case OPTYPE_DECODE:
9570 chk_recursions_expr_decode(u.expr.r1, refch);
9571 chk_recursions_expr_decode(u.expr.r2, refch);
9572 break;
9573 case OPTYPE_SUBSTR:
9574 refch.mark_state();
9575 u.expr.ti1->chk_recursions(refch);
9576 refch.prev_state();
9577 refch.mark_state();
9578 u.expr.v2->chk_recursions(refch);
9579 refch.prev_state();
9580 refch.mark_state();
9581 u.expr.v3->chk_recursions(refch);
9582 refch.prev_state();
9583 break;
9584 case OPTYPE_REGEXP:
9585 refch.mark_state();
9586 u.expr.ti1->chk_recursions(refch);
9587 refch.prev_state();
9588 refch.mark_state();
9589 u.expr.t2->chk_recursions(refch);
9590 refch.prev_state();
9591 refch.mark_state();
9592 u.expr.v3->chk_recursions(refch);
9593 refch.prev_state();
9594 break;
9595 case OPTYPE_DECOMP: // v1 v2 v3
9596 refch.mark_state();
9597 u.expr.v1->chk_recursions(refch);
9598 refch.prev_state();
9599 refch.mark_state();
9600 u.expr.v2->chk_recursions(refch);
9601 refch.prev_state();
9602 refch.mark_state();
9603 u.expr.v3->chk_recursions(refch);
9604 refch.prev_state();
9605 break;
9606 case OPTYPE_REPLACE:
9607 refch.mark_state();
9608 u.expr.ti1->chk_recursions(refch);
9609 refch.prev_state();
9610 refch.mark_state();
9611 u.expr.v2->chk_recursions(refch);
9612 refch.prev_state();
9613 refch.mark_state();
9614 u.expr.v3->chk_recursions(refch);
9615 refch.prev_state();
9616 refch.mark_state();
9617 u.expr.ti4->chk_recursions(refch);
9618 refch.prev_state();
9619 break;
9620 case OPTYPE_LENGTHOF: // ti1
9621 case OPTYPE_SIZEOF: // ti1
9622 case OPTYPE_VALUEOF: // ti1
9623 case OPTYPE_ENCODE:
9624 case OPTYPE_ISPRESENT:
9625 case OPTYPE_TTCN2STRING:
9626 refch.mark_state();
9627 u.expr.ti1->chk_recursions(refch);
9628 refch.prev_state();
9629 break;
9630 case OPTYPE_MATCH: // v1 t2
9631 refch.mark_state();
9632 u.expr.v1->chk_recursions(refch);
9633 refch.prev_state();
9634 refch.mark_state();
9635 u.expr.t2->chk_recursions(refch);
9636 refch.prev_state();
9637 break;
9638 case OPTYPE_LOG2STR:
9639 u.expr.logargs->chk_recursions(refch);
9640 break;
9641 default:
9642 break;
9643 } // switch
9644 }
9645
9646 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9647 ReferenceChain& refch) {
9648 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9649 Assignment *ass = ref->get_refd_assignment();
9650 if (!ass) {
9651 set_valuetype(V_ERROR);
9652 return;
9653 }
9654 switch (ass->get_asstype()) {
9655 case Assignment::A_CONST:
9656 case Assignment::A_EXT_CONST:
9657 case Assignment::A_MODULEPAR:
9658 case Assignment::A_VAR:
9659 case Assignment::A_PAR_VAL_IN:
9660 case Assignment::A_PAR_VAL_OUT:
9661 case Assignment::A_PAR_VAL_INOUT: {
9662 Value* v = new Value(V_REFD, ref);
9663 v->set_location(*ref);
9664 v->set_my_scope(get_my_scope());
9665 v->set_fullname(get_fullname()+".<operand>");
9666 refch.mark_state();
9667 v->chk_recursions(refch);
9668 refch.prev_state();
9669 delete v;
9670 break; }
9671 case Assignment::A_MODULEPAR_TEMP:
9672 case Assignment::A_TEMPLATE:
9673 case Assignment::A_VAR_TEMPLATE:
9674 case Assignment::A_PAR_TEMPL_IN:
9675 case Assignment::A_PAR_TEMPL_OUT:
9676 case Assignment::A_PAR_TEMPL_INOUT: {
9677 Template* t = new Template(ref->clone());
9678 t->set_location(*ref);
9679 t->set_my_scope(get_my_scope());
9680 t->set_fullname(get_fullname()+".<operand>");
9681 refch.mark_state();
9682 t->chk_recursions(refch);
9683 refch.prev_state();
9684 delete t;
9685 break; }
9686 default:
9687 // remain silent, the error has been already reported
9688 set_valuetype(V_ERROR);
9689 break;
9690 } // switch
9691 }
9692
9693 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9694 {
9695 bool self_ref = false;
9696 switch (t->get_templatetype()) {
9697 case Ttcn::Template::SPECIFIC_VALUE: {
9698 Value *v = t->get_specific_value();
9699 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9700 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9701 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9702 break; }
9703 case Ttcn::Template::TEMPLATE_REFD: {
9704 Ttcn::Ref_base *refb = t->get_reference();
9705 Common::Assignment *ass = refb->get_refd_assignment();
9706 self_ref |= (ass == lhs);
9707 break; }
9708 case Ttcn::Template::ALL_FROM:
9709 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9710 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9711 break;
9712 case Ttcn::Template::TEMPLATE_LIST:
9713 case Ttcn::Template::SUPERSET_MATCH:
9714 case Ttcn::Template::SUBSET_MATCH:
9715 case Ttcn::Template::PERMUTATION_MATCH:
9716 case Ttcn::Template::COMPLEMENTED_LIST:
9717 case Ttcn::Template::VALUE_LIST: {
9718 size_t num = t->get_nof_comps();
9719 for (size_t i = 0; i < num; ++i) {
9720 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9721 }
9722 break; }
9723// not yet clear whether we should use this or the above for TEMPLATE_LIST
9724// case Ttcn::Template::TEMPLATE_LIST: {
9725// size_t num = t->get_nof_listitems();
9726// for (size_t i=0; i < num; ++i) {
9727// self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9728// }
9729// break; }
9730 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9731 size_t nnt = t->get_nof_comps();
9732 for (size_t i=0; i < nnt; ++i) {
9733 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9734 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9735 }
9736 break; }
9737 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9738 size_t nnt = t->get_nof_comps();
9739 for (size_t i=0; i < nnt; ++i) {
9740 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9741 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9742 }
9743 break; }
9744 case Ttcn::Template::VALUE_RANGE: {
9745 Ttcn::ValueRange *vr = t->get_value_range();
9746 Common::Value *v = vr->get_min_v();
9747 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9748 v = vr->get_max_v();
9749 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9750 break; }
9751 case Ttcn::Template::CSTR_PATTERN:
9752 case Ttcn::Template::USTR_PATTERN: {
9753 Ttcn::PatternString *ps = t->get_cstr_pattern();
9754 self_ref |= ps->chk_self_ref(lhs);
9755 break; }
9756 case Ttcn::Template::BSTR_PATTERN:
9757 case Ttcn::Template::HSTR_PATTERN:
9758 case Ttcn::Template::OSTR_PATTERN: {
9759 // FIXME: cannot access u.pattern
9760 break; }
9761 case Ttcn::Template::ANY_VALUE:
9762 case Ttcn::Template::ANY_OR_OMIT:
9763 case Ttcn::Template::OMIT_VALUE:
9764 case Ttcn::Template::TEMPLATE_NOTUSED:
9765 break; // self-ref can't happen
9766 case Ttcn::Template::TEMPLATE_INVOKE:
9767 break; // assume self-ref can't happen
9768 case Ttcn::Template::TEMPLATE_ERROR:
9769 FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9770 break; // not reached
9771// default:
9772// FATAL_ERROR("todo ttype %d", t->get_templatetype());
9773// break; // and hope for the best
9774 }
9775 return self_ref;
9776 }
9777
9778 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
9779 {
9780 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
9781 namedbool is_str_elem = NOT_STR_ELEM;
9782 if (v->valuetype == V_REFD) {
9783 Reference *ref = v->get_reference();
9784 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
9785 if (subrefs && subrefs->refers_to_string_element()) {
9786 is_str_elem = IS_STR_ELEM;
9787 }
9788 }
9789 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9790 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
9791 is_str_elem);
9792 }
9793
9794 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
9795 {
9796 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
9797 if (!lhs) FATAL_ERROR("no lhs!");
9798 bool self_ref = false;
9799 switch (u.expr.v_optype) {
9800 case OPTYPE_RND: // -
9801 case OPTYPE_TESTCASENAME: // -
9802 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
9803 case OPTYPE_COMP_MTC: // -
9804 case OPTYPE_COMP_SYSTEM: // -
9805 case OPTYPE_COMP_SELF: // -
9806 case OPTYPE_COMP_RUNNING_ANY: // -
9807 case OPTYPE_COMP_RUNNING_ALL: // -
9808 case OPTYPE_COMP_ALIVE_ANY: // -
9809 case OPTYPE_COMP_ALIVE_ALL: // -
9810 case OPTYPE_TMR_RUNNING_ANY: // -
9811 case OPTYPE_GETVERDICT: // -
9812 break; // nothing to do
9813
9814 case OPTYPE_MATCH: // v1 t2
9815 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
9816 // no break
9817 case OPTYPE_UNARYPLUS: // v1
9818 case OPTYPE_UNARYMINUS: // v1
9819 case OPTYPE_NOT: // v1
9820 case OPTYPE_NOT4B: // v1
9821 case OPTYPE_BIT2HEX: // v1
9822 case OPTYPE_BIT2INT: // v1
9823 case OPTYPE_BIT2OCT: // v1
9824 case OPTYPE_BIT2STR: // v1
9825 case OPTYPE_CHAR2INT: // v1
9826 case OPTYPE_CHAR2OCT: // v1
9827 case OPTYPE_FLOAT2INT: // v1
9828 case OPTYPE_FLOAT2STR: // v1
9829 case OPTYPE_HEX2BIT: // v1
9830 case OPTYPE_HEX2INT: // v1
9831 case OPTYPE_HEX2OCT: // v1
9832 case OPTYPE_HEX2STR: // v1
9833 case OPTYPE_INT2CHAR: // v1
9834 case OPTYPE_INT2FLOAT: // v1
9835 case OPTYPE_INT2STR: // v1
9836 case OPTYPE_INT2UNICHAR: // v1
9837 case OPTYPE_OCT2BIT: // v1
9838 case OPTYPE_OCT2CHAR: // v1
9839 case OPTYPE_OCT2HEX: // v1
9840 case OPTYPE_OCT2INT: // v1
9841 case OPTYPE_OCT2STR: // v1
9842 case OPTYPE_STR2BIT: // v1
9843 case OPTYPE_STR2FLOAT: // v1
9844 case OPTYPE_STR2HEX: // v1
9845 case OPTYPE_STR2INT: // v1
9846 case OPTYPE_STR2OCT: // v1
9847 case OPTYPE_UNICHAR2INT: // v1
9848 case OPTYPE_UNICHAR2CHAR: // v1
9849 case OPTYPE_ENUM2INT: // v1
9850 case OPTYPE_RNDWITHVAL: // v1
9851 case OPTYPE_COMP_RUNNING: // v1
9852 case OPTYPE_COMP_ALIVE: // v1
9853 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
9854 case OPTYPE_GET_STRINGENCODING:
9855 case OPTYPE_DECODE_BASE64:
9856 case OPTYPE_REMOVE_BOM:
9857 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9858 break;
9859 case OPTYPE_ADD: // v1 v2
9860 case OPTYPE_SUBTRACT: // v1 v2
9861 case OPTYPE_MULTIPLY: // v1 v2
9862 case OPTYPE_DIVIDE: // v1 v2
9863 case OPTYPE_MOD: // v1 v2
9864 case OPTYPE_REM: // v1 v2
9865 case OPTYPE_CONCAT: // v1 v2
9866 case OPTYPE_EQ: // v1 v2
9867 case OPTYPE_LT: // v1 v2
9868 case OPTYPE_GT: // v1 v2
9869 case OPTYPE_NE: // v1 v2
9870 case OPTYPE_GE: // v1 v2
9871 case OPTYPE_LE: // v1 v2
9872 case OPTYPE_AND: // v1 v2
9873 case OPTYPE_OR: // v1 v2
9874 case OPTYPE_XOR: // v1 v2
9875 case OPTYPE_AND4B: // v1 v2
9876 case OPTYPE_OR4B: // v1 v2
9877 case OPTYPE_XOR4B: // v1 v2
9878 case OPTYPE_SHL: // v1 v2
9879 case OPTYPE_SHR: // v1 v2
9880 case OPTYPE_ROTL: // v1 v2
9881 case OPTYPE_ROTR: // v1 v2
9882 case OPTYPE_INT2BIT: // v1 v2
9883 case OPTYPE_INT2HEX: // v1 v2
9884 case OPTYPE_INT2OCT: // v1 v2
9885 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9886 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9887 break;
9888 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9889 case OPTYPE_OCT2UNICHAR:
9890 case OPTYPE_ENCODE_BASE64:
9891 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9892 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9893 break;
9894 case OPTYPE_DECOMP: // v1 v2 v3
9895 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9896 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9897 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9898 break;
9899
9900 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
9901 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
9902 // no break
9903 case OPTYPE_SUBSTR: // ti1 v2 v3
9904 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9905 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
9906 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
9907 break;
9908
9909 case OPTYPE_REGEXP: // ti1 t2 v3
9910 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9911 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
9912 // no break
9913 case OPTYPE_LENGTHOF: // ti1
9914 case OPTYPE_SIZEOF: // ti1
9915 case OPTYPE_VALUEOF: // ti1
9916 case OPTYPE_ENCODE: // ti1
9917 case OPTYPE_TTCN2STRING:
9918 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9919 break;
9920
9921 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
9922 // component.create -- assume no self-ref
9923 case OPTYPE_ACTIVATE: // r1
9924 // defaultref := activate(altstep) -- assume no self-ref
9925 case OPTYPE_TMR_RUNNING: // r1
9926 // boolvar := a_timer.running -- assume no self-ref
9927 break;
9928 break;
9929
9930 case OPTYPE_LOG2STR: {// logargs
9931 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
9932 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
9933 switch (la->get_type()) {
9934 case Ttcn::LogArgument::L_UNDEF:
9935 case Ttcn::LogArgument::L_ERROR:
9936 FATAL_ERROR("log2str argument type");
9937 break; // not reached
9938
9939 case Ttcn::LogArgument::L_MACRO:
9940 case Ttcn::LogArgument::L_STR:
9941 break; // self reference not possible
9942
9943 case Ttcn::LogArgument::L_VAL:
9944 case Ttcn::LogArgument::L_MATCH:
9945 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
9946 break;
9947
9948 case Ttcn::LogArgument::L_REF: {
9949 Ttcn::Ref_base *ref = la->get_ref();
9950 Common::Assignment *ass = ref->get_refd_assignment();
9951 self_ref |= (ass == lhs);
9952 break; }
9953
9954 case Ttcn::LogArgument::L_TI: {
9955 Ttcn::TemplateInstance *ti = la->get_ti();
9956 Ttcn::Template *t = ti->get_Template();
9957 self_ref |= chk_expr_self_ref_templ(t, lhs);
9958 break; }
9959
9960 // no default please
9961 } // switch la->logargtype
9962 }
9963 break; }
9964
9965 case OPTYPE_DECODE: { // r1 r2
9966 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
9967 self_ref |= (ass == lhs);
9968 goto label_r1; }
9969 case OPTYPE_EXECUTE: // r1 [v2]
9970 if (u.expr.v2) {
9971 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9972 }
9973 label_r1:
9974 // no break
9975 case OPTYPE_UNDEF_RUNNING: // r1
9976 case OPTYPE_TMR_READ: { // r1
9977 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
9978 self_ref |= (ass == lhs);
9979 break; }
9980
9981 case OPTYPE_ISCHOSEN_T: // t1 i2
9982 case OPTYPE_ISBOUND: // ti1
9983 case OPTYPE_ISVALUE: // ti1
9984 case OPTYPE_ISPRESENT: { // ti1
9985 Ttcn::Template *t;
9986 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
9987 else t = u.expr.ti1->get_Template();
9988 self_ref |= chk_expr_self_ref_templ(t, lhs);
9989 break; }
9990
9991 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
9992 if (u.expr.v3) {
9993 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9994 }
9995 // no break
9996 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
9997 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9998 // TODO t_list2
9999 break;
10000
10001 case NUMBER_OF_OPTYPES: // can never happen
10002 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10003 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10004 break;
10005 } // switch u.expr.v_optype
10006 return self_ref;
10007 }
10008
10009
10010 string Value::create_stringRepr()
10011 {
10012 switch (valuetype) {
10013 case V_ERROR:
10014 return string("<erroneous>");
10015 case V_NULL:
10016 return string("NULL");
10017 case V_BOOL:
10018 if (is_asn1()) {
10019 if (u.val_bool) return string("TRUE");
10020 else return string("FALSE");
10021 }
10022 else {
10023 if (u.val_bool) return string("true");
10024 else return string("false");
10025 }
10026 case V_INT:
10027 return u.val_Int->t_str();
10028 case V_REAL:
10029 return Real2string(u.val_Real);
10030 case V_ENUM:
10031 case V_NAMEDINT:
10032 case V_UNDEF_LOWERID:
10033 return u.val_id->get_name();
10034 case V_NAMEDBITS: {
10035 string ret_val("{ ");
10036 for (size_t i = 0; i < u.ids->size(); i++) {
10037 if (i>0) ret_val += ' ';
10038 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10039 }
10040 ret_val += '}';
10041 return ret_val; }
10042 case V_BSTR: {
10043 string ret_val('\'');
10044 ret_val += *u.str.val_str;
10045 ret_val += "'B";
10046 return ret_val; }
10047 case V_HSTR: {
10048 string ret_val('\'');
10049 ret_val += *u.str.val_str;
10050 ret_val += "'H";
10051 return ret_val; }
10052 case V_OSTR: {
10053 string ret_val('\'');
10054 ret_val += *u.str.val_str;
10055 ret_val += "'O";
10056 return ret_val; }
10057 case V_CSTR:
10058 case V_ISO2022STR:
10059 return u.str.val_str->get_stringRepr();
10060 case V_USTR:
10061 return u.ustr.val_ustr->get_stringRepr();
10062 case V_CHARSYMS:
10063 /** \todo stringrepr of V_CHARSYMS */
10064 return string("<sorry, string representation of charsyms "
10065 "not implemented>");
10066 case V_OID:
10067 case V_ROID: {
10068 string ret_val;
10069 if (!is_asn1()) ret_val += "objid ";
10070 ret_val += "{ ";
10071 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10072 if (i>0) ret_val += ' ';
10073 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10074 }
10075 ret_val += " }";
10076 return ret_val; }
10077 case V_CHOICE:
10078 if (is_asn1()) {
10079 string ret_val(u.choice.alt_name->get_dispname());
10080 ret_val += " : ";
10081 ret_val += u.choice.alt_value->get_stringRepr();
10082 return ret_val;
10083 }
10084 else {
10085 string ret_val("{ ");
10086 ret_val += u.choice.alt_name->get_dispname();
10087 ret_val += " := ";
10088 ret_val += u.choice.alt_value->get_stringRepr();
10089 ret_val += " }";
10090 return ret_val;
10091 }
10092 case V_SEQOF:
10093 case V_SETOF:
10094 case V_ARRAY: {
10095 string ret_val("{ ");
10096 if (!is_indexed()) {
10097 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10098 if (i > 0) ret_val += ", ";
10099 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10100 }
10101 } else {
10102 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10103 if (i > 0) ret_val += ", ";
10104 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10105 }
10106 }
10107 ret_val += " }";
10108 return ret_val; }
10109 case V_SEQ:
10110 case V_SET: {
10111 string ret_val("{ ");
10112 bool asn1_flag = is_asn1();
10113 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10114 if (i > 0) ret_val += ", ";
10115 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10116 ret_val += nv->get_name().get_dispname();
10117 if (asn1_flag) ret_val += ' ';
10118 else ret_val += " := ";
10119 ret_val += nv->get_value()->get_stringRepr();
10120 }
10121 ret_val += " }";
10122 return ret_val; }
10123 case V_REFD: {
10124 // do not evaluate the reference if it is not done so far
10125 // (e.g. in parse-only mode)
10126 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10127 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10128 else return t_val->get_stringRepr(); }
10129 case V_OMIT:
10130 return string("omit");
10131 case V_VERDICT:
10132 switch (u.verdict) {
10133 case Verdict_NONE:
10134 return string("none");
10135 case Verdict_PASS:
10136 return string("pass");
10137 case Verdict_INCONC:
10138 return string("inconc");
10139 case Verdict_FAIL:
10140 return string("fail");
10141 case Verdict_ERROR:
10142 return string("error");
10143 default:
10144 return string("<unknown verdict value>");
10145 }
10146 case V_DEFAULT_NULL:
10147 case V_FAT_NULL:
10148 return string("null");
10149 case V_EXPR:
10150 switch (u.expr.v_optype) {
10151 case OPTYPE_RND:
10152 return string("rnd()");
10153 case OPTYPE_TESTCASENAME:
10154 return string("testcasename()");
10155 case OPTYPE_UNARYPLUS:
10156 return create_stringRepr_unary("+");
10157 case OPTYPE_UNARYMINUS:
10158 return create_stringRepr_unary("-");
10159 case OPTYPE_NOT:
10160 return create_stringRepr_unary("not");
10161 case OPTYPE_NOT4B:
10162 return create_stringRepr_unary("not4b");
10163 case OPTYPE_BIT2HEX:
10164 return create_stringRepr_predef1("bit2hex");
10165 case OPTYPE_BIT2INT:
10166 return create_stringRepr_predef1("bit2int");
10167 case OPTYPE_BIT2OCT:
10168 return create_stringRepr_predef1("bit2oct");
10169 case OPTYPE_BIT2STR:
10170 return create_stringRepr_predef1("bit2str");
10171 case OPTYPE_CHAR2INT:
10172 return create_stringRepr_predef1("char2int");
10173 case OPTYPE_CHAR2OCT:
10174 return create_stringRepr_predef1("char2oct");
10175 case OPTYPE_FLOAT2INT:
10176 return create_stringRepr_predef1("float2int");
10177 case OPTYPE_FLOAT2STR:
10178 return create_stringRepr_predef1("float2str");
10179 case OPTYPE_HEX2BIT:
10180 return create_stringRepr_predef1("hex2bit");
10181 case OPTYPE_HEX2INT:
10182 return create_stringRepr_predef1("hex2int");
10183 case OPTYPE_HEX2OCT:
10184 return create_stringRepr_predef1("hex2oct");
10185 case OPTYPE_HEX2STR:
10186 return create_stringRepr_predef1("hex2str");
10187 case OPTYPE_INT2CHAR:
10188 return create_stringRepr_predef1("int2char");
10189 case OPTYPE_INT2FLOAT:
10190 return create_stringRepr_predef1("int2float");
10191 case OPTYPE_INT2STR:
10192 return create_stringRepr_predef1("int2str");
10193 case OPTYPE_INT2UNICHAR:
10194 return create_stringRepr_predef1("int2unichar");
10195 case OPTYPE_OCT2BIT:
10196 return create_stringRepr_predef1("oct2bit");
10197 case OPTYPE_OCT2CHAR:
10198 return create_stringRepr_predef1("oct2char");
10199 case OPTYPE_OCT2HEX:
10200 return create_stringRepr_predef1("oct2hex");
10201 case OPTYPE_OCT2INT:
10202 return create_stringRepr_predef1("oct2int");
10203 case OPTYPE_OCT2STR:
10204 return create_stringRepr_predef1("oct2str");
10205 case OPTYPE_GET_STRINGENCODING:
10206 return create_stringRepr_predef1("get_stringencoding");
10207 case OPTYPE_REMOVE_BOM:
10208 return create_stringRepr_predef1("remove_bom");
10209 case OPTYPE_ENCODE_BASE64: {
10210 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10211 else return create_stringRepr_predef1("encode_base64");
10212 }
10213 case OPTYPE_DECODE_BASE64:
10214 return create_stringRepr_predef1("decode_base64");
10215 case OPTYPE_OCT2UNICHAR:{
10216 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10217 else return create_stringRepr_predef1("oct2unichar");
10218 }
10219 case OPTYPE_UNICHAR2OCT: {
10220 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10221 else return create_stringRepr_predef1("unichar2oct");
10222 }
10223 case OPTYPE_STR2BIT:
10224 return create_stringRepr_predef1("str2bit");
10225 case OPTYPE_STR2FLOAT:
10226 return create_stringRepr_predef1("str2float");
10227 case OPTYPE_STR2HEX:
10228 return create_stringRepr_predef1("str2hex");
10229 case OPTYPE_STR2INT:
10230 return create_stringRepr_predef1("str2int");
10231 case OPTYPE_STR2OCT:
10232 return create_stringRepr_predef1("str2oct");
10233 case OPTYPE_UNICHAR2INT:
10234 return create_stringRepr_predef1("unichar2int");
10235 case OPTYPE_UNICHAR2CHAR:
10236 return create_stringRepr_predef1("unichar2char");
10237 case OPTYPE_ENUM2INT:
10238 return create_stringRepr_predef1("enum2int");
10239 case OPTYPE_ENCODE:
10240 return create_stringRepr_predef1("encvalue");
10241 case OPTYPE_DECODE:
10242 return create_stringRepr_predef2("decvalue");
10243 case OPTYPE_RNDWITHVAL:
10244 return create_stringRepr_predef1("rnd");
10245 case OPTYPE_ADD:
10246 return create_stringRepr_infix("+");
10247 case OPTYPE_SUBTRACT:
10248 return create_stringRepr_infix("-");
10249 case OPTYPE_MULTIPLY:
10250 return create_stringRepr_infix("*");
10251 case OPTYPE_DIVIDE:
10252 return create_stringRepr_infix("/");
10253 case OPTYPE_MOD:
10254 return create_stringRepr_infix("mod");
10255 case OPTYPE_REM:
10256 return create_stringRepr_infix("rem");
10257 case OPTYPE_CONCAT:
10258 return create_stringRepr_infix("&");
10259 case OPTYPE_EQ:
10260 return create_stringRepr_infix("==");
10261 case OPTYPE_LT:
10262 return create_stringRepr_infix("<");
10263 case OPTYPE_GT:
10264 return create_stringRepr_infix(">");
10265 case OPTYPE_NE:
10266 return create_stringRepr_infix("!=");
10267 case OPTYPE_GE:
10268 return create_stringRepr_infix(">=");
10269 case OPTYPE_LE:
10270 return create_stringRepr_infix("<=");
10271 case OPTYPE_AND:
10272 return create_stringRepr_infix("and");
10273 case OPTYPE_OR:
10274 return create_stringRepr_infix("or");
10275 case OPTYPE_XOR:
10276 return create_stringRepr_infix("xor");
10277 case OPTYPE_AND4B:
10278 return create_stringRepr_infix("and4b");
10279 case OPTYPE_OR4B:
10280 return create_stringRepr_infix("or4b");
10281 case OPTYPE_XOR4B:
10282 return create_stringRepr_infix("xor4b");
10283 case OPTYPE_SHL:
10284 return create_stringRepr_infix("<<");
10285 case OPTYPE_SHR:
10286 return create_stringRepr_infix(">>");
10287 case OPTYPE_ROTL:
10288 return create_stringRepr_infix("<@");
10289 case OPTYPE_ROTR:
10290 return create_stringRepr_infix("@>");
10291 case OPTYPE_INT2BIT:
10292 return create_stringRepr_predef2("int2bit");
10293 case OPTYPE_INT2HEX:
10294 return create_stringRepr_predef2("int2hex");
10295 case OPTYPE_INT2OCT:
10296 return create_stringRepr_predef2("int2oct");
10297 case OPTYPE_SUBSTR: {
10298 string ret_val("substr(");
10299 u.expr.ti1->append_stringRepr(ret_val);
10300 ret_val += ", ";
10301 ret_val += u.expr.v2->get_stringRepr();
10302 ret_val += ", ";
10303 ret_val += u.expr.v3->get_stringRepr();
10304 ret_val += ')';
10305 return ret_val;
10306 }
10307 case OPTYPE_REGEXP: {
10308 string ret_val("regexp(");
10309 u.expr.ti1->append_stringRepr(ret_val);
10310 ret_val += ", ";
10311 u.expr.t2->append_stringRepr(ret_val);
10312 ret_val += ", ";
10313 ret_val += u.expr.v3->get_stringRepr();
10314 ret_val += ')';
10315 return ret_val;
10316 }
10317 case OPTYPE_DECOMP: {
10318 string ret_val("decomp(");
10319 ret_val += u.expr.v1->get_stringRepr();
10320 ret_val += ", ";
10321 ret_val += u.expr.v2->get_stringRepr();
10322 ret_val += ", ";
10323 ret_val += u.expr.v3->get_stringRepr();
10324 ret_val += ')';
10325 return ret_val;
10326 }
10327 case OPTYPE_REPLACE: {
10328 string ret_val("replace(");
10329 u.expr.ti1->append_stringRepr(ret_val);
10330 ret_val += ", ";
10331 ret_val += u.expr.v2->get_stringRepr();
10332 ret_val += ", ";
10333 ret_val += u.expr.v3->get_stringRepr();
10334 ret_val += ", ";
10335 u.expr.ti4->append_stringRepr(ret_val);
10336 ret_val += ')';
10337 return ret_val;
10338 }
10339 case OPTYPE_ISPRESENT: {
10340 string ret_val("ispresent(");
10341 u.expr.ti1->append_stringRepr(ret_val);
10342 ret_val += ')';
10343 return ret_val; }
10344 case OPTYPE_ISCHOSEN: {
10345 string ret_val("ischosen(");
10346 ret_val += u.expr.r1->get_dispname();
10347 ret_val += '.';
10348 ret_val += u.expr.i2->get_dispname();
10349 ret_val += ')';
10350 return ret_val; }
10351 case OPTYPE_ISCHOSEN_V: {
10352 string ret_val("ischosen(");
10353 ret_val += u.expr.v1->get_stringRepr();
10354 ret_val += '.';
10355 ret_val += u.expr.i2->get_dispname();
10356 ret_val += ')';
10357 return ret_val; }
10358 case OPTYPE_ISCHOSEN_T: {
10359 string ret_val("ischosen(");
10360 ret_val += u.expr.t1->get_stringRepr();
10361 ret_val += '.';
10362 ret_val += u.expr.i2->get_dispname();
10363 ret_val += ')';
10364 return ret_val; }
10365 case OPTYPE_LENGTHOF: {
10366 string ret_val("lengthof(");
10367 u.expr.ti1->append_stringRepr(ret_val);
10368 ret_val += ')';
10369 return ret_val; }
10370 case OPTYPE_SIZEOF: {
10371 string ret_val("sizeof(");
10372 u.expr.ti1->append_stringRepr(ret_val);
10373 ret_val += ')';
10374 return ret_val; }
10375 case OPTYPE_ISVALUE: {
10376 string ret_val("isvalue(");
10377 u.expr.ti1->append_stringRepr(ret_val);
10378 ret_val += ')';
10379 return ret_val; }
10380 case OPTYPE_VALUEOF: {
10381 string ret_val("valueof(");
10382 u.expr.ti1->append_stringRepr(ret_val);
10383 ret_val += ')';
10384 return ret_val; }
10385 case OPTYPE_LOG2STR:
10386 return string("log2str(...)");
10387 case OPTYPE_MATCH: {
10388 string ret_val("match(");
10389 ret_val += u.expr.v1->get_stringRepr();
10390 ret_val += ", ";
10391 u.expr.t2->append_stringRepr(ret_val);
10392 ret_val += ')';
10393 return ret_val; }
10394 case OPTYPE_TTCN2STRING: {
10395 string ret_val("ttcn2string(");
10396 u.expr.ti1->append_stringRepr(ret_val);
10397 ret_val += ')';
10398 return ret_val;
10399 }
10400 case OPTYPE_UNDEF_RUNNING:
10401 return u.expr.r1->get_dispname() + ".running";
10402 case OPTYPE_COMP_NULL:
10403 return string("null");
10404 case OPTYPE_COMP_MTC:
10405 return string("mtc");
10406 case OPTYPE_COMP_SYSTEM:
10407 return string("system");
10408 case OPTYPE_COMP_SELF:
10409 return string("self");
10410 case OPTYPE_COMP_CREATE: {
10411 string ret_val(u.expr.r1->get_dispname());
10412 ret_val += ".create";
10413 if (u.expr.v2 || u.expr.v3) {
10414 ret_val += '(';
10415 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10416 else ret_val += '-';
10417 if (u.expr.v3) {
10418 ret_val += ", ";
10419 ret_val += u.expr.v3->get_stringRepr();
10420 }
10421 ret_val += ')';
10422 }
10423 if (u.expr.b4) ret_val += " alive";
10424 return ret_val; }
10425 case OPTYPE_COMP_RUNNING:
10426 return u.expr.v1->get_stringRepr() + ".running";
10427 case OPTYPE_COMP_RUNNING_ANY:
10428 return string("any component.running");
10429 case OPTYPE_COMP_RUNNING_ALL:
10430 return string("all component.running");
10431 case OPTYPE_COMP_ALIVE:
10432 return u.expr.v1->get_stringRepr() + ".alive";
10433 case OPTYPE_COMP_ALIVE_ANY:
10434 return string("any component.alive");
10435 case OPTYPE_COMP_ALIVE_ALL:
10436 return string("all component.alive");
10437 case OPTYPE_TMR_READ:
10438 return u.expr.r1->get_dispname() + ".read";
10439 case OPTYPE_TMR_RUNNING:
10440 return u.expr.r1->get_dispname() + ".running";
10441 case OPTYPE_TMR_RUNNING_ANY:
10442 return string("any timer.running");
10443 case OPTYPE_GETVERDICT:
10444 return string("getverdict");
10445 case OPTYPE_ACTIVATE: {
10446 string ret_val("activate(");
10447 ret_val += u.expr.r1->get_dispname();
10448 ret_val += ')';
10449 return ret_val; }
10450 case OPTYPE_ACTIVATE_REFD: {
10451 string ret_val("activate(derefer(");
10452 ret_val += u.expr.v1->get_stringRepr();
10453 ret_val += ")(";
10454 if (u.expr.state == EXPR_CHECKED) {
10455 if (u.expr.ap_list2) {
10456 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10457 for (size_t i = 0; i < nof_pars; i++) {
10458 if (i > 0) ret_val += ", ";
10459 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10460 }
10461 }
10462 } else {
10463 if (u.expr.t_list2) {
10464 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10465 for (size_t i = 0; i < nof_pars; i++) {
10466 if (i > 0) ret_val += ", ";
10467 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10468 }
10469 }
10470 }
10471 ret_val += "))";
10472 return ret_val; }
10473 case OPTYPE_EXECUTE: {
10474 string ret_val("execute(");
10475 ret_val += u.expr.r1->get_dispname();
10476 if (u.expr.v2) {
10477 ret_val += ", ";
10478 ret_val += u.expr.v2->get_stringRepr();
10479 }
10480 ret_val += ')';
10481 return ret_val; }
10482 case OPTYPE_EXECUTE_REFD: {
10483 string ret_val("execute(derefers(");
10484 ret_val += u.expr.v1->get_stringRepr();
10485 ret_val += ")(";
10486 if (u.expr.state == EXPR_CHECKED) {
10487 if (u.expr.ap_list2) {
10488 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10489 for (size_t i = 0; i < nof_pars; i++) {
10490 if (i > 0) ret_val += ", ";
10491 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10492 }
10493 }
10494 } else {
10495 if (u.expr.t_list2) {
10496 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10497 for (size_t i = 0; i < nof_pars; i++) {
10498 if (i > 0) ret_val += ", ";
10499 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10500 }
10501 }
10502 }
10503 ret_val += ')';
10504 if(u.expr.v3) {
10505 ret_val += ", ";
10506 ret_val += u.expr.v3->get_stringRepr();
10507 }
10508 ret_val += ')';
10509 return ret_val; }
10510 default:
10511 return string("<unsupported optype>");
10512 } // switch u.expr.v_optype
10513 case V_MACRO:
10514 switch (u.macro) {
10515 case MACRO_MODULEID:
10516 return string("%moduleId");
10517 case MACRO_FILENAME:
10518 return string("%fileName");
10519 case MACRO_BFILENAME:
10520 return string("__BFILE__");
10521 case MACRO_FILEPATH:
10522 return string("__FILE__");
10523 case MACRO_LINENUMBER:
10524 return string("%lineNumber");
10525 case MACRO_LINENUMBER_C:
10526 return string("__LINE__");
10527 case MACRO_DEFINITIONID:
10528 return string("%definitionId");
10529 case MACRO_SCOPE:
10530 return string("__SCOPE__");
10531 case MACRO_TESTCASEID:
10532 return string("%testcaseId");
10533 default:
10534 return string("<unknown macro>");
10535 } // switch u.macro
10536 case V_NOTUSED:
10537 return string('-');
10538 case V_FUNCTION:
10539 case V_ALTSTEP:
10540 case V_TESTCASE: {
10541 string ret_val("refers(");
10542 ret_val += u.refd_fat->get_assname();
10543 ret_val += ')';
10544 return ret_val; }
10545 case V_INVOKE: {
10546 string ret_val;
10547 ret_val += u.invoke.v->get_stringRepr();
10548 ret_val += ".apply(";
10549 if (u.invoke.ap_list) {
10550 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10551 for (size_t i = 0; i < nof_pars; i++) {
10552 if (i > 0) ret_val += ", ";
10553 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10554 }
10555 } else if (u.invoke.t_list) {
10556 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10557 for (size_t i = 0; i < nof_pars; i++) {
10558 if (i > 0) ret_val += ", ";
10559 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10560 }
10561 }
10562 ret_val += ')';
10563 return ret_val; }
10564 case V_REFER: {
10565 string ret_val("refers(");
10566 ret_val += u.refered->get_dispname();
10567 ret_val += ')';
10568 return ret_val; }
10569 default:
10570 return string("<unsupported valuetype>");
10571 } // switch valuetype
10572 }
10573
10574 string Value::create_stringRepr_unary(const char *operator_str)
10575 {
10576 string ret_val(operator_str);
10577 ret_val += '(';
10578 ret_val += u.expr.v1->get_stringRepr();
10579 ret_val += ')';
10580 return ret_val;
10581 }
10582
10583 string Value::create_stringRepr_infix(const char *operator_str)
10584 {
10585 string ret_val('(');
10586 ret_val += u.expr.v1->get_stringRepr();
10587 ret_val += ' ';
10588 ret_val += operator_str;
10589 ret_val += ' ';
10590 ret_val += u.expr.v2->get_stringRepr();
10591 ret_val += ')';
10592 return ret_val;
10593 }
10594
10595 string Value::create_stringRepr_predef1(const char *function_name)
10596 {
10597 string ret_val(function_name);
10598 ret_val += '(';
10599 if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
10600 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10601 }
10602 else ret_val += u.expr.v1->get_stringRepr();
10603 ret_val += ')';
10604 return ret_val;
10605 }
10606
10607 string Value::create_stringRepr_predef2(const char *function_name)
10608 {
10609 string ret_val(function_name);
10610 ret_val += '(';
10611 ret_val += u.expr.v1->get_stringRepr();
10612 ret_val += ", ";
10613 ret_val += u.expr.v2->get_stringRepr();
10614 ret_val += ')';
10615 return ret_val;
10616 }
10617
10618 bool Value::operator==(Value& val)
10619 {
10620 Value *left = get_value_refd_last();
10621 Type *left_governor = left->get_my_governor();
10622 if (left_governor) left_governor = left_governor->get_type_refd_last();
10623 Value *right = val.get_value_refd_last();
10624 Type *right_governor = right->get_my_governor();
10625 if (right_governor) right_governor = right_governor->get_type_refd_last();
10626 if (left_governor && right_governor
10627 && !left_governor->is_compatible(right_governor, NULL)
10628 && !right_governor->is_compatible(left_governor, NULL))
10629 FATAL_ERROR("Value::operator==");
10630
10631 // Not-A-Value is not equal to anything (NaN analogy:)
10632 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10633 return false;
10634
10635 switch (left->valuetype) {
10636 case V_NULL:
10637 case V_OMIT:
10638 case V_DEFAULT_NULL:
10639 case V_FAT_NULL:
10640 case V_NOTUSED:
10641 return left->valuetype == right->valuetype;
10642 case V_BOOL:
10643 return right->valuetype == V_BOOL &&
10644 left->get_val_bool() == right->get_val_bool();
10645 case V_INT:
10646 return right->valuetype == V_INT && *left->get_val_Int()
10647 == *right->get_val_Int();
10648 case V_REAL:
10649 return right->valuetype == V_REAL &&
10650 left->get_val_Real() == right->get_val_Real();
10651 case V_CSTR:
10652 switch (right->valuetype) {
10653 case V_CSTR:
10654 return left->get_val_str() == right->get_val_str();
10655 case V_USTR:
10656 return right->get_val_ustr() == left->get_val_str();
10657 case V_ISO2022STR:
10658 return right->get_val_iso2022str() == left->get_val_str();
10659 default:
10660 return false;
10661 }
10662 case V_BSTR:
10663 case V_HSTR:
10664 case V_OSTR:
10665 return left->valuetype == right->valuetype &&
10666 left->get_val_str() == right->get_val_str();
10667 case V_USTR:
10668 switch (right->valuetype) {
10669 case V_CSTR:
10670 return left->get_val_ustr() == right->get_val_str();
10671 case V_USTR:
10672 return left->get_val_ustr() == right->get_val_ustr();
10673 case V_ISO2022STR:
10674 return left->get_val_ustr() == right->get_val_iso2022str();
10675 default:
10676 return false;
10677 }
10678 case V_ISO2022STR:
10679 switch (right->valuetype) {
10680 case V_CSTR:
10681 return left->get_val_iso2022str() == right->get_val_str();
10682 case V_USTR:
10683 // The appropriate operator==() is missing. The operands are swapped,
10684 // but it shouldn't be a problem.
10685 return right->get_val_ustr() == left->get_val_iso2022str();
10686 case V_ISO2022STR:
10687 return left->get_val_iso2022str() == right->get_val_iso2022str();
10688 default:
10689 return false;
10690 }
10691 case V_ENUM:
10692 return right->valuetype == V_ENUM &&
10693 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10694 case V_OID:
10695 case V_ROID:
10696 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10697 vector<string> act, other;
10698 get_oid_comps(act);
10699 val.get_oid_comps(other);
10700 size_t act_size = act.size(), other_size = other.size();
10701 bool ret_val;
10702 if (act_size == other_size) {
10703 ret_val = true;
10704 for (size_t i = 0; i < act_size; i++)
10705 if (*act[i] != *other[i]) {
10706 ret_val = false;
10707 break;
10708 }
10709 } else ret_val = false;
10710 for (size_t i = 0; i < act_size; i++) delete act[i];
10711 act.clear();
10712 for (size_t i = 0; i < other_size; i++) delete other[i];
10713 other.clear();
10714 return ret_val;
10715 } else return false;
10716 case V_CHOICE:
10717 return right->valuetype == V_CHOICE &&
10718 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10719 *(left->get_alt_value()) == *(right->get_alt_value());
10720 case V_SEQ:
10721 case V_SET: {
10722 if (!left_governor) FATAL_ERROR("Value::operator==");
10723 if (left->valuetype != right->valuetype) return false;
10724 size_t nof_comps = left_governor->get_nof_comps();
10725 for (size_t i = 0; i < nof_comps; i++) {
10726 Value *lval = NULL, *rval = NULL;
10727 CompField* cfl = left_governor->get_comp_byIndex(i);
10728 const Identifier& field_name = cfl->get_name();
10729 if (left->has_comp_withName(field_name)) {
10730 lval = left->get_comp_value_byName(field_name);
10731 if (right->has_comp_withName(field_name)) {
10732 rval = right->get_comp_value_byName(field_name);
10733 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10734 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10735 return false;
10736 else if (!(*lval == *rval))
10737 return false;
10738 } else {
10739 if (cfl->has_default()) {
10740 if (!(*lval == *cfl->get_defval()))
10741 return false;
10742 } else {
10743 if (lval->valuetype != V_OMIT)
10744 return false;
10745 }
10746 }
10747 } else {
10748 if(right->has_comp_withName(field_name)) {
10749 rval = right->get_comp_value_byName(field_name);
10750 if(cfl->has_default()) {
10751 if(rval->valuetype==V_OMIT) return false;
10752 else {
10753 lval = cfl->get_defval();
10754 if (!(*lval==*rval)) return false;
10755 }
10756 }
10757 }
10758 }
10759 }
10760 return true; }
10761 case V_SEQOF:
10762 case V_ARRAY: {
10763 if (left->valuetype != right->valuetype) return false;
10764 size_t ncomps = get_nof_comps();
10765 if (ncomps != right->get_nof_comps()) return false;
10766
10767 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
10768 bool found = false;
10769 map<IndexedValue*, void> uncovered;
10770 for (size_t i = 0; i < left->get_nof_comps(); ++i)
10771 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
10772
10773 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
10774 found = false;
10775 for (size_t j = 0; j < uncovered.size(); ++j) {
10776 if (*(uncovered.get_nth_key(j)->get_value()) ==
10777 *(right->get_comp_byIndex(i)) &&
10778 *(uncovered.get_nth_key(j)->get_index()) ==
10779 *(right->get_index_byIndex(i))) {
10780 found = true;
10781 uncovered.erase(uncovered.get_nth_key(j));
10782 break;
10783 }
10784 }
10785 if (!found) break;
10786 }
10787 uncovered.clear();
10788 return found;
10789 } else if (left->is_indexed() || right->is_indexed()) {
10790 Value* indexed_one = 0;
10791 Value* not_indexed_one = 0;
10792
10793 if(left->is_indexed()) { // left is indexed, right is not
10794 indexed_one = left;
10795 not_indexed_one = right;
10796 } else { // right indexed, left is not
10797 indexed_one = right;
10798 not_indexed_one = left;
10799 }
10800
10801 for(size_t i = 0; i < ncomps; ++i) {
10802 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
10803 if(!(ind->valuetype == V_INT &&
10804 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
10805 *(indexed_one->get_comp_byIndex(i))))
10806 { return false; }
10807 }
10808 return true;
10809 } else { // none of them is indexed
10810 for (size_t i = 0; i < ncomps; i++) {
10811 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
10812 return false;
10813 }
10814 return true;
10815 }
10816 }
10817 case V_SETOF: {
10818 if (right->valuetype != V_SETOF) return false;
10819 size_t ncomps = get_nof_comps();
10820 if (ncomps != right->get_nof_comps()) return false;
10821 if (ncomps == 0) return true;
10822 map<size_t, void> uncovered;
10823 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
10824 for (size_t i = 0; i < ncomps; i++) {
10825 Value *left_item = left->get_comp_byIndex(i);
10826 bool pair_found = false;
10827 for (size_t j = 0; j < ncomps - i; j++) {
10828 size_t right_index = uncovered.get_nth_key(j);
10829 if (*left_item == *right->get_comp_byIndex(right_index)) {
10830 uncovered.erase(right_index);
10831 pair_found = true;
10832 break;
10833 }
10834 }
10835 if (!pair_found) {
10836 uncovered.clear();
10837 return false;
10838 }
10839 }
10840 return true; }
10841 case V_VERDICT:
10842 return right->valuetype == V_VERDICT &&
10843 left->get_val_verdict() == right->get_val_verdict();
10844 case V_FUNCTION:
10845 case V_ALTSTEP:
10846 case V_TESTCASE:
10847 return left->valuetype == right->valuetype &&
10848 left->get_refd_assignment() == right->get_refd_assignment();
10849 default:
10850 FATAL_ERROR("Value::operator==");
10851 }
10852 return true;
10853 }
10854
10855 bool Value::operator<(Value& val)
10856 {
10857 Value *left = get_value_refd_last();
10858 Type *left_governor = left->get_my_governor();
10859 if(left_governor) left_governor=left_governor->get_type_refd_last();
10860 Value *right = val.get_value_refd_last();
10861 Type *right_governor = right->get_my_governor();
10862 if(right_governor) right_governor=right_governor->get_type_refd_last();
10863 if (left->get_valuetype() != right->get_valuetype())
10864 FATAL_ERROR("Value::operator<");
10865 switch(valuetype){
10866 case V_INT:
10867 return *left->get_val_Int() < *right->get_val_Int();
10868 case V_REAL:
10869 return (left->get_val_Real() < right->get_val_Real());
10870 case V_ENUM:
10871 if(!left_governor || !right_governor)
10872 FATAL_ERROR("Value::operator<");
10873 if(left_governor!=right_governor)
10874 FATAL_ERROR("Value::operator<");
10875 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
10876 right_governor->get_enum_val_byId(*right->get_val_id()));
10877 default:
10878 FATAL_ERROR("Value::operator<");
10879 }
10880 return true;
10881 }
10882
10883 bool Value::is_string_type(Type::expected_value_t exp_val)
10884 {
10885 switch (get_expr_returntype(exp_val)) {
10886 case Type::T_CSTR:
10887 case Type::T_USTR:
10888 case Type::T_BSTR:
10889 case Type::T_HSTR:
10890 case Type::T_OSTR:
10891 return true;
10892 default:
10893 return false;
10894 }
10895 }
10896
10897 void Value::generate_code_expr(expression_struct *expr)
10898 {
10899 if (has_single_expr()) {
10900 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
10901 } else {
10902 switch (valuetype) {
10903 case V_EXPR:
10904 generate_code_expr_expr(expr);
10905 break;
10906 case V_CHOICE:
10907 case V_SEQOF:
10908 case V_SETOF:
10909 case V_ARRAY:
10910 case V_SEQ:
10911 case V_SET: {
10912 const string& tmp_id = get_temporary_id();
10913 const char *tmp_id_str = tmp_id.c_str();
10914 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
10915 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
10916 set_genname_recursive(tmp_id);
10917 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10918 expr->expr = mputstr(expr->expr, tmp_id_str);
10919 break; }
10920 case V_INT: {
10921 const string& tmp_id = get_temporary_id();
10922 const char *tmp_id_str = tmp_id.c_str();
10923 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
10924 tmp_id_str);
10925 set_genname_recursive(tmp_id);
10926 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10927 expr->expr = mputstr(expr->expr, tmp_id_str);
10928 break; }
10929 case V_REFD: {
10930 if (!get_needs_conversion()) {
10931 u.ref.ref->generate_code_const_ref(expr);
10932 } else {
10933 Type *my_gov = get_expr_governor_last();
10934 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
10935 ->get_field_type(u.ref.ref->get_subrefs(),
10936 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
10937 // Make sure that nothing goes wrong.
10938 if (!my_gov || !refd_gov || my_gov == refd_gov)
10939 FATAL_ERROR("Value::generate_code_expr()");
10940 expression_struct expr_tmp;
10941 Code::init_expr(&expr_tmp);
10942 const string& tmp_id1 = get_temporary_id();
10943 const char *tmp_id_str1 = tmp_id1.c_str();
10944 const string& tmp_id2 = get_temporary_id();
10945 const char *tmp_id_str2 = tmp_id2.c_str();
10946 expr->preamble = mputprintf(expr->preamble,
10947 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
10948 tmp_id_str1);
10949 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
10950 u.ref.ref->generate_code_const_ref(&expr_tmp);
10951 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
10952 expr->preamble = mputprintf(expr->preamble,
10953 "%s %s;\n"
10954 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10955 "and `%s' are not compatible at run-time\");\n",
10956 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
10957 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
10958 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
10959 ->get_typename().c_str(), refd_gov->get_typename().c_str());
10960 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
10961 }
10962 break; }
10963 case V_INVOKE:
10964 generate_code_expr_invoke(expr);
10965 break;
10966 default:
10967 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
10968 }
10969 }
10970 }
10971
10972 void Value::generate_code_expr_mandatory(expression_struct *expr)
10973 {
10974 generate_code_expr(expr);
10975 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
10976 generate_code_expr_optional_field_ref(expr, u.ref.ref);
10977 }
10978
10979 bool Value::can_use_increment(Reference *ref) const
10980 {
10981 if (valuetype != V_EXPR) {
10982 return false;
10983 }
10984 switch (u.expr.v_optype) {
10985 case OPTYPE_ADD:
10986 case OPTYPE_SUBTRACT:
10987 break;
10988 default:
10989 return false;
10990 }
10991 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
10992 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
10993 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
10994 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
10995 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
10996 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
10997 return true;
10998 }
10999 return false;
11000 }
11001
11002 char *Value::generate_code_init(char *str, const char *name)
11003 {
11004 if (get_code_generated()) return str;
11005 if (err_descr) {
11006 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11007 }
11008 switch (valuetype) {
11009 case V_NULL:
11010 case V_BOOL:
11011 case V_REAL:
11012 case V_ENUM:
11013 case V_BSTR:
11014 case V_HSTR:
11015 case V_OSTR:
11016 case V_CSTR:
11017 case V_USTR:
11018 case V_ISO2022STR:
11019 case V_OID:
11020 case V_ROID:
11021 case V_VERDICT:
11022 case V_DEFAULT_NULL:
11023 case V_FAT_NULL:
11024 case V_FUNCTION:
11025 case V_ALTSTEP:
11026 case V_TESTCASE:
11027 // These values have a single string equivalent.
11028 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11029 break;
11030 case V_INT:
11031 if (u.val_Int->is_native_fit())
11032 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11033 else
11034 // It's always an INTEGER.
11035 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11036 "}\n", get_single_expr().c_str(), name);
11037 break;
11038 case V_EXPR:
11039 case V_INVOKE: {
11040 expression_struct expr;
11041 Code::init_expr(&expr);
11042 expr.expr = mputprintf(expr.expr, "%s = ", name);
11043 generate_code_expr(&expr);
11044 str = Code::merge_free_expr(str, &expr);
11045 break; }
11046 case V_CHOICE:
11047 str = generate_code_init_choice(str, name);
11048 break;
11049 case V_SEQOF:
11050 case V_SETOF:
11051 if (!is_indexed()) str = generate_code_init_seof(str, name);
11052 else str = generate_code_init_indexed(str, name);
11053 break;
11054 case V_ARRAY:
11055 if (!is_indexed()) str = generate_code_init_array(str, name);
11056 else str = generate_code_init_indexed(str, name);
11057 break;
11058 case V_SEQ:
11059 case V_SET:
11060 str = generate_code_init_se(str, name);
11061 break;
11062 case V_REFD:
11063 str = generate_code_init_refd(str, name);
11064 break;
11065 case V_MACRO:
11066 switch (u.macro) {
11067 case MACRO_TESTCASEID:
11068 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11069 break;
11070 default:
11071 // all others must already be evaluated away
11072 FATAL_ERROR("Value::generate_code_init()");
11073 }
11074 break;
11075 default:
11076 FATAL_ERROR("Value::generate_code_init()");
11077 }
11078 if (err_descr) {
11079 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11080 }
11081 set_code_generated();
11082 return str;
11083 }
11084
11085 char *Value::rearrange_init_code(char *str)
11086 {
11087 switch (valuetype) {
11088 case V_REFD: {
11089 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11090 if (parlist) {
11091 str = parlist->rearrange_init_code(str,
11092 u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()
11093 == my_scope->get_scope_mod_gen());
11094 }
11095 break; }
11096 case V_INVOKE: {
11097 str = u.invoke.v->rearrange_init_code(str);
11098 bool type_is_local = u.invoke.v->get_expr_governor_last()->get_my_scope()
11099 ->get_scope_mod_gen() == my_scope->get_scope_mod_gen();
11100 str = u.invoke.ap_list->rearrange_init_code(str, type_is_local);
11101 break; }
11102 case V_EXPR:
11103 switch (u.expr.v_optype) {
11104 case OPTYPE_UNARYPLUS:
11105 case OPTYPE_UNARYMINUS:
11106 case OPTYPE_NOT:
11107 case OPTYPE_NOT4B:
11108 case OPTYPE_BIT2HEX:
11109 case OPTYPE_BIT2INT:
11110 case OPTYPE_BIT2OCT:
11111 case OPTYPE_BIT2STR:
11112 case OPTYPE_CHAR2INT:
11113 case OPTYPE_CHAR2OCT:
11114 case OPTYPE_FLOAT2INT:
11115 case OPTYPE_FLOAT2STR:
11116 case OPTYPE_HEX2BIT:
11117 case OPTYPE_HEX2INT:
11118 case OPTYPE_HEX2OCT:
11119 case OPTYPE_HEX2STR:
11120 case OPTYPE_INT2CHAR:
11121 case OPTYPE_INT2FLOAT:
11122 case OPTYPE_INT2STR:
11123 case OPTYPE_INT2UNICHAR:
11124 case OPTYPE_OCT2BIT:
11125 case OPTYPE_OCT2CHAR:
11126 case OPTYPE_OCT2HEX:
11127 case OPTYPE_OCT2INT:
11128 case OPTYPE_OCT2STR:
11129 case OPTYPE_STR2BIT:
11130 case OPTYPE_STR2FLOAT:
11131 case OPTYPE_STR2HEX:
11132 case OPTYPE_STR2INT:
11133 case OPTYPE_STR2OCT:
11134 case OPTYPE_UNICHAR2INT:
11135 case OPTYPE_UNICHAR2CHAR:
11136 case OPTYPE_ENUM2INT:
11137 case OPTYPE_ISCHOSEN_V:
11138 case OPTYPE_GET_STRINGENCODING:
11139 case OPTYPE_REMOVE_BOM:
11140 case OPTYPE_DECODE_BASE64:
11141 str = u.expr.v1->rearrange_init_code(str);
11142 break;
11143 case OPTYPE_DECODE: {
11144 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11145 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11146 bool rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11147 my_scope->get_scope_mod_gen());
11148 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11149
11150 parlist = u.expr.r2->get_parlist();
11151 ass = u.expr.r2->get_refd_assignment();
11152 rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11153 my_scope->get_scope_mod_gen());
11154 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11155 break; }
11156 case OPTYPE_ADD:
11157 case OPTYPE_SUBTRACT:
11158 case OPTYPE_MULTIPLY:
11159 case OPTYPE_DIVIDE:
11160 case OPTYPE_MOD:
11161 case OPTYPE_REM:
11162 case OPTYPE_CONCAT:
11163 case OPTYPE_EQ:
11164 case OPTYPE_LT:
11165 case OPTYPE_GT:
11166 case OPTYPE_NE:
11167 case OPTYPE_GE:
11168 case OPTYPE_LE:
11169 case OPTYPE_AND:
11170 case OPTYPE_OR:
11171 case OPTYPE_XOR:
11172 case OPTYPE_AND4B:
11173 case OPTYPE_OR4B:
11174 case OPTYPE_XOR4B:
11175 case OPTYPE_SHL:
11176 case OPTYPE_SHR:
11177 case OPTYPE_ROTL:
11178 case OPTYPE_ROTR:
11179 case OPTYPE_INT2BIT:
11180 case OPTYPE_INT2HEX:
11181 case OPTYPE_INT2OCT:
11182 //case OPTYPE_DECODE:
11183 str = u.expr.v1->rearrange_init_code(str);
11184 str = u.expr.v2->rearrange_init_code(str);
11185 break;
11186 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11187 case OPTYPE_OCT2UNICHAR:
11188 case OPTYPE_ENCODE_BASE64:
11189 str = u.expr.v1->rearrange_init_code(str);
11190 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str);
11191 break;
11192 case OPTYPE_SUBSTR:
11193 str = u.expr.ti1->rearrange_init_code(str);
11194 str = u.expr.v2->rearrange_init_code(str);
11195 str = u.expr.v3->rearrange_init_code(str);
11196 break;
11197 case OPTYPE_REGEXP:
11198 str = u.expr.ti1->rearrange_init_code(str);
11199 str = u.expr.t2->rearrange_init_code(str);
11200 str = u.expr.v3->rearrange_init_code(str);
11201 break;
11202 case OPTYPE_DECOMP:
11203 str = u.expr.v1->rearrange_init_code(str);
11204 str = u.expr.v2->rearrange_init_code(str);
11205 str = u.expr.v3->rearrange_init_code(str);
11206 break;
11207 case OPTYPE_REPLACE:
11208 str = u.expr.ti1->rearrange_init_code(str);
11209 str = u.expr.v2->rearrange_init_code(str);
11210 str = u.expr.v3->rearrange_init_code(str);
11211 str = u.expr.ti4->rearrange_init_code(str);
11212 break;
11213 case OPTYPE_LENGTHOF:
11214 case OPTYPE_SIZEOF:
11215 case OPTYPE_VALUEOF:
11216 case OPTYPE_ENCODE:
11217 case OPTYPE_ISPRESENT:
11218 case OPTYPE_TTCN2STRING:
11219 str = u.expr.ti1->rearrange_init_code(str);
11220 break;
11221 case OPTYPE_ISCHOSEN_T:
11222 str = u.expr.t1->rearrange_init_code(str);
11223 break;
11224 case OPTYPE_MATCH:
11225 str = u.expr.v1->rearrange_init_code(str);
11226 str = u.expr.t2->rearrange_init_code(str);
11227 break;
11228 default:
11229 // other kinds of expressions cannot appear within templates
11230 break;
11231 }
11232 break;
11233 default:
11234 break;
11235 }
11236 return str;
11237 }
11238
11239 char* Value::generate_code_tmp(char *str, const char *prefix,
11240 size_t& blockcount)
11241 {
11242 char *s2 = memptystr();
11243 char *s1 = generate_code_tmp(NULL, s2);
11244 if (s2[0]) {
11245 if (blockcount == 0) {
11246 str = mputstr(str, "{\n");
11247 blockcount++;
11248 }
11249 str = mputstr(str, s2);
11250 }
11251 Free(s2);
11252 str=mputstr(str, prefix);
11253 str=mputstr(str, s1);
11254 Free(s1);
11255 return str;
11256 }
11257
11258 char *Value::generate_code_tmp(char *str, char*& init)
11259 {
11260 expression_struct expr;
11261 Code::init_expr(&expr);
11262 generate_code_expr_mandatory(&expr);
11263 if (expr.preamble || expr.postamble) {
11264 if (valuetype == V_EXPR &&
11265 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11266 // a temporary variable is already introduced
11267 if (expr.preamble) init = mputstr(init, expr.preamble);
11268 if (expr.postamble) init = mputstr(init, expr.postamble);
11269 str = mputstr(str, expr.expr);
11270 } else {
11271 const string& tmp_id = get_temporary_id();
11272 const char *tmp_id_str = tmp_id.c_str();
11273 init = mputprintf(init, "%s %s;\n"
11274 "{\n",
11275 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11276 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11277 tmp_id_str);
11278 if (expr.preamble) init = mputstr(init, expr.preamble);
11279 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11280 if (expr.postamble) init = mputstr(init, expr.postamble);
11281 init = mputstr(init, "}\n");
11282 str = mputstr(str, tmp_id_str);
11283 }
11284 } else str = mputstr(str, expr.expr);
11285 Code::free_expr(&expr);
11286 return str;
11287 }
11288
11289 void Value::generate_code_log(expression_struct *expr)
11290 {
11291 if (explicit_cast_needed()) {
11292 char *expr_backup = expr->expr;
11293 expr->expr = NULL;
11294 generate_code_expr(expr);
11295 const string& tmp_id = get_temporary_id();
11296 const char *tmp_id_str = tmp_id.c_str();
11297 // We have to create a temporary object, because the parser of GCC
11298 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11299 // constructor call that is, this does not work: type(...).log(); but
11300 // this works: type tmp(...); tmp.log();.
11301 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11302 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11303 expr->expr);
11304 Free(expr->expr);
11305 expr->expr = mputstr(expr_backup, tmp_id_str);
11306 } else {
11307 generate_code_expr(expr);
11308 }
11309 expr->expr = mputstr(expr->expr, ".log()");
11310 }
11311
11312 void Value::generate_code_log_match(expression_struct *expr)
11313 {
11314 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11315 FATAL_ERROR("Value::generate_code_log_match()");
11316 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11317 // compliance the whole code-generation should be checked. Standalone
11318 // constructs like: "A(a[0].f());" should be avoided. The current
11319 // solution for HK38721 uses an additional assignment to overcome the
11320 // issue. The generated code will be slower, but it's needed for old GCC
11321 // versions in specific circumstances.
11322 if (u.expr.t2->needs_temp_ref()) {
11323 char *expr_backup = expr->expr;
11324 expr->expr = NULL;
11325 u.expr.t2->generate_code(expr);
11326 const string& tmp_id = get_temporary_id();
11327 const char *tmp_id_str = tmp_id.c_str();
11328 expr->preamble = mputprintf(expr->preamble,
11329 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11330 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11331 Free(expr->expr);
11332 expr->expr = mputstr(expr_backup, tmp_id_str);
11333 } else {
11334 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11335 // some reason "(A(NS::B)).a(C);" compiles fine.
11336 expr->expr = mputc(expr->expr, '(');
11337 u.expr.t2->generate_code(expr);
11338 expr->expr = mputc(expr->expr, ')');
11339 }
11340 expr->expr = mputstr(expr->expr, ".log_match(");
11341 u.expr.v1->generate_code_expr(expr);
11342 expr->expr = mputc(expr->expr, ')');
11343 }
11344
11345 void Value::generate_code_expr_expr(expression_struct *expr)
11346 {
11347 switch (u.expr.v_optype) {
11348 case OPTYPE_RND:
11349 generate_code_expr_rnd(expr, 0);
11350 break;
11351 case OPTYPE_UNARYPLUS:
11352 // same as without the '+' operator
11353 u.expr.v1->generate_code_expr(expr);
11354 break;
11355 case OPTYPE_UNARYMINUS:
11356 generate_code_expr_unary(expr, "-", u.expr.v1);
11357 break;
11358 case OPTYPE_NOT:
11359 generate_code_expr_unary(expr, "!", u.expr.v1);
11360 break;
11361 case OPTYPE_NOT4B:
11362 generate_code_expr_unary(expr, "~", u.expr.v1);
11363 break;
11364 case OPTYPE_BIT2HEX:
11365 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11366 break;
11367 case OPTYPE_BIT2INT:
11368 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11369 break;
11370 case OPTYPE_BIT2OCT:
11371 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11372 break;
11373 case OPTYPE_BIT2STR:
11374 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11375 break;
11376 case OPTYPE_CHAR2INT:
11377 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11378 break;
11379 case OPTYPE_CHAR2OCT:
11380 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11381 break;
11382 case OPTYPE_FLOAT2INT:
11383 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11384 break;
11385 case OPTYPE_FLOAT2STR:
11386 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11387 break;
11388 case OPTYPE_HEX2BIT:
11389 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11390 break;
11391 case OPTYPE_HEX2INT:
11392 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11393 break;
11394 case OPTYPE_HEX2OCT:
11395 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11396 break;
11397 case OPTYPE_HEX2STR:
11398 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11399 break;
11400 case OPTYPE_INT2CHAR:
11401 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11402 break;
11403 case OPTYPE_INT2FLOAT:
11404 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11405 break;
11406 case OPTYPE_INT2STR:
11407 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11408 break;
11409 case OPTYPE_INT2UNICHAR:
11410 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11411 break;
11412 case OPTYPE_OCT2BIT:
11413 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11414 break;
11415 case OPTYPE_OCT2CHAR:
11416 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11417 break;
11418 case OPTYPE_GET_STRINGENCODING:
11419 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11420 break;
11421 case OPTYPE_REMOVE_BOM:
11422 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11423 break;
11424 case OPTYPE_ENCODE_BASE64:
11425 if (u.expr.v2)
11426 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11427 else
11428 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11429 break;
11430 case OPTYPE_DECODE_BASE64:
11431 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11432 break;
11433 case OPTYPE_OCT2UNICHAR:
11434 if (u.expr.v2)
11435 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11436 else
11437 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11438 break;
11439 case OPTYPE_UNICHAR2OCT:
11440 if (u.expr.v2)
11441 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11442 else
11443 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11444 break;
11445 case OPTYPE_OCT2HEX:
11446 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11447 break;
11448 case OPTYPE_OCT2INT:
11449 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11450 break;
11451 case OPTYPE_OCT2STR:
11452 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11453 break;
11454 case OPTYPE_STR2BIT:
11455 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11456 break;
11457 case OPTYPE_STR2FLOAT:
11458 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11459 break;
11460 case OPTYPE_STR2HEX:
11461 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11462 break;
11463 case OPTYPE_STR2INT:
11464 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11465 break;
11466 case OPTYPE_STR2OCT:
11467 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11468 break;
11469 case OPTYPE_UNICHAR2INT:
11470 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11471 break;
11472 case OPTYPE_UNICHAR2CHAR:
11473 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11474 break;
11475 case OPTYPE_ENUM2INT: {
11476 Type* enum_type = u.expr.v1->get_expr_governor_last();
11477 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11478 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11479 enum_type->get_genname_value(my_scope).c_str());
11480 u.expr.v1->generate_code_expr_mandatory(expr);
11481 expr->expr = mputc(expr->expr, ')');
11482 break;}
11483 case OPTYPE_ENCODE:
11484 generate_code_expr_encode(expr);
11485 break;
11486 case OPTYPE_DECODE:
11487 generate_code_expr_decode(expr);
11488 break;
11489 case OPTYPE_RNDWITHVAL:
11490 generate_code_expr_rnd(expr, u.expr.v1);
11491 break;
11492 case OPTYPE_ADD:
11493 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11494 break;
11495 case OPTYPE_SUBTRACT:
11496 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11497 break;
11498 case OPTYPE_MULTIPLY:
11499 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11500 break;
11501 case OPTYPE_DIVIDE:
11502 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11503 break;
11504 case OPTYPE_MOD:
11505 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11506 break;
11507 case OPTYPE_REM:
11508 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11509 break;
11510 case OPTYPE_CONCAT:
11511 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11512 break;
11513 case OPTYPE_EQ:
11514 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11515 break;
11516 case OPTYPE_LT:
11517 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11518 break;
11519 case OPTYPE_GT:
11520 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11521 break;
11522 case OPTYPE_NE:
11523 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11524 break;
11525 case OPTYPE_GE:
11526 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11527 break;
11528 case OPTYPE_LE:
11529 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11530 break;
11531 case OPTYPE_AND:
11532 case OPTYPE_OR:
11533 generate_code_expr_and_or(expr);
11534 break;
11535 case OPTYPE_XOR:
11536 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11537 break;
11538 case OPTYPE_AND4B:
11539 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11540 break;
11541 case OPTYPE_OR4B:
11542 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11543 break;
11544 case OPTYPE_XOR4B:
11545 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11546 break;
11547 case OPTYPE_SHL:
11548 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11549 break;
11550 case OPTYPE_SHR:
11551 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11552 break;
11553 case OPTYPE_ROTL:
11554 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11555 break;
11556 case OPTYPE_ROTR:
11557 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11558 break;
11559 case OPTYPE_INT2BIT:
11560 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11561 break;
11562 case OPTYPE_INT2HEX:
11563 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11564 break;
11565 case OPTYPE_INT2OCT:
11566 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11567 break;
11568 case OPTYPE_SUBSTR:
11569 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11570 else generate_code_expr_substr_replace_compat(expr);
11571 break;
11572 case OPTYPE_REGEXP:
11573 generate_code_expr_regexp(expr);
11574 break;
11575 case OPTYPE_DECOMP:
11576 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11577 break;
11578 case OPTYPE_REPLACE:
11579 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11580 else generate_code_expr_substr_replace_compat(expr);
11581 break;
11582 case OPTYPE_ISCHOSEN: // r1 i2
11583 FATAL_ERROR("Value::generate_code_expr_expr()");
11584 break;
11585 case OPTYPE_ISCHOSEN_V: // v1 i2
11586 u.expr.v1->generate_code_expr_mandatory(expr);
11587 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11588 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11589 u.expr.i2->get_name().c_str());
11590 break;
11591 case OPTYPE_ISCHOSEN_T: // t1 i2
11592 u.expr.t1->generate_code_expr(expr);
11593 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11594 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11595 u.expr.i2->get_name().c_str());
11596 break;
11597 case OPTYPE_ISPRESENT:
11598 case OPTYPE_ISBOUND: {
11599 Template::templatetype_t temp = u.expr.ti1->get_Template()
11600 ->get_templatetype();
11601 if (temp == Template::SPECIFIC_VALUE) {
11602 Value* specific_value = u.expr.ti1->get_Template()
11603 ->get_specific_value();
11604 if (specific_value->get_valuetype() == Value::V_REFD) {
11605 Ttcn::Reference* reference =
11606 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11607 if (reference) {
11608 reference->generate_code_ispresentbound(expr, false,
11609 u.expr.v_optype==OPTYPE_ISBOUND);
11610 break;
11611 }
11612 }
11613 } else if (temp == Template::TEMPLATE_REFD){
11614 Ttcn::Reference* reference =
11615 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11616 ->get_reference());
11617 if (reference) {
11618 reference->generate_code_ispresentbound(expr, true,
11619 u.expr.v_optype==OPTYPE_ISBOUND);
11620 break;
11621 }
11622 }
11623 }
11624 // no break
11625 case OPTYPE_LENGTHOF: // ti1
11626 // fall through, separated later
11627 case OPTYPE_SIZEOF: // ti1
11628 // fall through, separated later
11629 case OPTYPE_ISVALUE: { // ti1
11630 if (u.expr.ti1->is_only_specific_value()) {
11631 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11632 bool cast_needed = t_val->explicit_cast_needed(
11633 u.expr.v_optype != OPTYPE_LENGTHOF);
11634 if(cast_needed) {
11635 // the ambiguous C++ expression is converted to the value class
11636 expr->expr = mputprintf(expr->expr, "%s(",
11637 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11638 }
11639
11640 if (u.expr.v_optype != OPTYPE_LENGTHOF
11641 && u.expr.v_optype != OPTYPE_SIZEOF) {
11642 t_val->generate_code_expr(expr);
11643 } else {
11644 t_val->generate_code_expr_mandatory(expr);
11645 }
11646
11647 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11648 }
11649 else u.expr.ti1->generate_code(expr);
11650
11651 switch (u.expr.v_optype) {
11652 case OPTYPE_ISBOUND:
11653 expr->expr=mputstr(expr->expr, ".is_bound()");
11654 break;
11655 case OPTYPE_ISPRESENT:
11656 expr->expr=mputstr(expr->expr, ".is_present()");
11657 break;
11658 case OPTYPE_SIZEOF:
11659 expr->expr=mputstr(expr->expr, ".size_of()");
11660 break;
11661 case OPTYPE_LENGTHOF:
11662 expr->expr=mputstr(expr->expr, ".lengthof()");
11663 break;
11664 case OPTYPE_ISVALUE:
11665 expr->expr=mputstr(expr->expr, ".is_value()");
11666 break;
11667 default:
11668 FATAL_ERROR("Value::generate_code_expr_expr()");
11669 }
11670 break; }
11671 case OPTYPE_VALUEOF: // ti1
11672 u.expr.ti1->generate_code(expr);
11673 expr->expr = mputstr(expr->expr, ".valueof()");
11674 break;
11675 case OPTYPE_MATCH: // v1 t2
11676 u.expr.t2->generate_code(expr);
11677 expr->expr = mputstr(expr->expr, ".match(");
11678 u.expr.v1->generate_code_expr(expr);
11679 expr->expr = mputc(expr->expr, ')');
11680 break;
11681 case OPTYPE_UNDEF_RUNNING:
11682 // it is resolved during semantic check
11683 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11684 break;
11685 case OPTYPE_COMP_NULL: // -
11686 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11687 break;
11688 case OPTYPE_COMP_MTC: // -
11689 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11690 break;
11691 case OPTYPE_COMP_SYSTEM: // -
11692 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11693 break;
11694 case OPTYPE_COMP_SELF: // -
11695 expr->expr=mputstr(expr->expr, "self");
11696 break;
11697 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11698 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11699 u.expr.b4);
11700 break;
11701 case OPTYPE_COMP_RUNNING: // v1
11702 u.expr.v1->generate_code_expr(expr);
11703 if(u.expr.v1->get_valuetype() == V_REFD)
11704 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11705 expr->expr = mputstr(expr->expr, ".running()");
11706 break;
11707 case OPTYPE_COMP_RUNNING_ANY: // -
11708 expr->expr=mputstr(expr->expr,
11709 "TTCN_Runtime::component_running(ANY_COMPREF)");
11710 break;
11711 case OPTYPE_COMP_RUNNING_ALL: // -
11712 expr->expr=mputstr(expr->expr,
11713 "TTCN_Runtime::component_running(ALL_COMPREF)");
11714 break;
11715 case OPTYPE_COMP_ALIVE: // v1
11716 u.expr.v1->generate_code_expr(expr);
11717 if(u.expr.v1->get_valuetype() == V_REFD)
11718 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11719 expr->expr = mputstr(expr->expr, ".alive()");
11720 break;
11721 case OPTYPE_COMP_ALIVE_ANY: // -
11722 expr->expr = mputstr(expr->expr,
11723 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11724 break;
11725 case OPTYPE_COMP_ALIVE_ALL: // -
11726 expr->expr = mputstr(expr->expr,
11727 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11728 break;
11729 case OPTYPE_TMR_READ: // r1
11730 u.expr.r1->generate_code(expr);
11731 expr->expr = mputstr(expr->expr, ".read()");
11732 break;
11733 case OPTYPE_TMR_RUNNING: // r1
11734 u.expr.r1->generate_code(expr);
11735 expr->expr = mputstr(expr->expr, ".running()");
11736 break;
11737 case OPTYPE_TMR_RUNNING_ANY: // -
11738 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11739 break;
11740 case OPTYPE_GETVERDICT: // -
11741 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11742 break;
11743 case OPTYPE_TESTCASENAME: // -
11744 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11745 break;
11746 case OPTYPE_ACTIVATE: // r1
11747 generate_code_expr_activate(expr);
11748 break;
11749 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
11750 generate_code_expr_activate_refd(expr);
11751 break;
11752 case OPTYPE_EXECUTE: // r1 [v2]
11753 generate_code_expr_execute(expr);
11754 break;
11755 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
11756 generate_code_expr_execute_refd(expr);
11757 break;
11758 case OPTYPE_LOG2STR:
11759 u.expr.logargs->generate_code_expr(expr);
11760 break;
11761 case OPTYPE_TTCN2STRING: {
11762 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
11763 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
11764 param_governor = param_governor->get_type_refd_last();
11765 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
11766 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
11767 u.expr.ti1->get_Template()->is_Value()) {
11768 Value* v = u.expr.ti1->get_Template()->get_Value();
11769 delete u.expr.ti1;
11770 u.expr.ti1 = NULL;
11771 bool cast_needed = v->explicit_cast_needed();
11772 if (cast_needed) {
11773 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
11774 }
11775 v->generate_code_expr(expr);
11776 if (cast_needed) {
11777 expr->expr = mputstr(expr->expr, ")");
11778 }
11779 delete v;
11780 } else {
11781 u.expr.ti1->generate_code(expr);
11782 }
11783 expr->expr = mputstr(expr->expr, ")");
11784 } break;
11785 default:
11786 FATAL_ERROR("Value::generate_code_expr_expr()");
11787 }
11788 }
11789
11790 void Value::generate_code_expr_unary(expression_struct *expr,
11791 const char *operator_str, Value *v1)
11792 {
11793 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
11794 v1->generate_code_expr_mandatory(expr);
11795 expr->expr = mputstrn(expr->expr, "))", 2);
11796 }
11797
11798 void Value::generate_code_expr_infix(expression_struct *expr,
11799 const char *operator_str, Value *v1,
11800 Value *v2, bool optional_allowed)
11801 {
11802 if (!get_needs_conversion()) {
11803 expr->expr = mputc(expr->expr, '(');
11804 if (optional_allowed) v1->generate_code_expr(expr);
11805 else v1->generate_code_expr_mandatory(expr);
11806 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
11807 if (optional_allowed) v2->generate_code_expr(expr);
11808 else v2->generate_code_expr_mandatory(expr);
11809 expr->expr = mputc(expr->expr, ')');
11810 } else { // Temporary variable for the converted value.
11811 const string& tmp_id1 = get_temporary_id();
11812 const char *tmp_id_str1 = tmp_id1.c_str();
11813 expression_struct expr_tmp;
11814 Code::init_expr(&expr_tmp);
11815 switch (u.expr.v_optype) {
11816 case OPTYPE_EQ:
11817 case OPTYPE_NE: {
11818 // Always "v1 -> v2".
11819 Type *t1 = v1->get_expr_governor_last();
11820 Type *t2 = v2->get_expr_governor_last();
11821 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
11822 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11823 else v2->generate_code_expr_mandatory(&expr_tmp);
11824 if (expr_tmp.preamble)
11825 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11826 expr->preamble = mputprintf(expr->preamble,
11827 "%s %s;\n"
11828 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11829 "and `%s' are not compatible at run-time\");\n",
11830 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
11831 TypeConv::get_conv_func(t2, t1, get_my_scope()
11832 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
11833 t2->get_typename().c_str(), t1->get_typename().c_str());
11834 Code::free_expr(&expr_tmp);
11835 if (optional_allowed) v1->generate_code_expr(expr);
11836 else v1->generate_code_expr_mandatory(expr);
11837 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
11838 tmp_id_str1);
11839 break; }
11840 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11841 // functions. The governors of all operands must exist at this point.
11842 case OPTYPE_ROTL:
11843 case OPTYPE_ROTR:
11844 case OPTYPE_CONCAT: {
11845 const string& tmp_id2 = get_temporary_id();
11846 const char *tmp_id_str2 = tmp_id2.c_str();
11847 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
11848 Type *my_gov = my_governor->get_type_refd_last();
11849 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
11850 ->get_type_refd_last();
11851 if (!t1_gov || my_gov == t1_gov)
11852 FATAL_ERROR("Value::generate_code_expr_infix()");
11853 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11854 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
11855 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11856 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
11857 else v1->generate_code_expr_mandatory(&expr_tmp);
11858 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
11859 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11860 else v2->generate_code_expr_mandatory(&expr_tmp);
11861 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11862 expr->preamble = mputprintf(expr->preamble,
11863 "%s %s;\n"
11864 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11865 "and `%s' are not compatible at run-time\");\n",
11866 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11867 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
11868 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
11869 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
11870 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11871 break; }
11872 default:
11873 FATAL_ERROR("Value::generate_code_expr_infix()");
11874 break;
11875 }
11876 }
11877 }
11878
11879 void Value::generate_code_expr_and_or(expression_struct *expr)
11880 {
11881 if (u.expr.v2->needs_short_circuit()) {
11882 // introduce a temporary variable to store the result of the operation
11883 const string& tmp_id = get_temporary_id();
11884 const char *tmp_id_str = tmp_id.c_str();
11885 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
11886 expression_struct expr2;
11887 // the left operand must be evaluated anyway
11888 Code::init_expr(&expr2);
11889 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11890 u.expr.v1->generate_code_expr_mandatory(&expr2);
11891 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11892 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
11893 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
11894 // evaluate the right operand only when necessary
11895 // in this case the final result will be the right operand
11896 Code::init_expr(&expr2);
11897 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11898 u.expr.v2->generate_code_expr_mandatory(&expr2);
11899 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11900 // the result is now in the temporary variable
11901 expr->expr = mputstr(expr->expr, tmp_id_str);
11902 } else {
11903 // use the overloaded operator to get better error messages
11904 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
11905 "&&" : "||", u.expr.v1, u.expr.v2, false);
11906 }
11907 }
11908
11909 void Value::generate_code_expr_predef1(expression_struct *expr,
11910 const char *function_name,
11911 Value *v1)
11912 {
11913 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11914 v1->generate_code_expr_mandatory(expr);
11915 expr->expr = mputc(expr->expr, ')');
11916 }
11917
11918 void Value::generate_code_expr_predef2(expression_struct *expr,
11919 const char *function_name,
11920 Value *v1, Value *v2)
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 = mputc(expr->expr, ')');
11927 }
11928
11929 void Value::generate_code_expr_predef3(expression_struct *expr,
11930 const char *function_name,
11931 Value *v1, Value *v2, Value *v3)
11932 {
11933 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11934 v1->generate_code_expr_mandatory(expr);
11935 expr->expr = mputstr(expr->expr, ", ");
11936 v2->generate_code_expr_mandatory(expr);
11937 expr->expr = mputstr(expr->expr, ", ");
11938 v3->generate_code_expr_mandatory(expr);
11939 expr->expr = mputc(expr->expr, ')');
11940 }
11941
11942 void Value::generate_code_expr_substr(expression_struct *expr)
11943 {
11944 bool par1_is_str;
11945 Value* v1 = u.expr.ti1->get_specific_value();
11946 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
11947 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
11948 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
11949 if (v1) v1->generate_code_expr_mandatory(expr);
11950 else u.expr.ti1->generate_code(expr);
11951 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
11952 else expr->expr = mputstr(expr->expr, ".substr(");
11953 if (!par1_is_str && u.expr.v2->is_unfoldable())
11954 expr->expr = mputstr(expr->expr, "(int)");
11955 u.expr.v2->generate_code_expr_mandatory(expr);
11956 expr->expr = mputstr(expr->expr, ", ");
11957 if (!par1_is_str && u.expr.v3->is_unfoldable())
11958 expr->expr = mputstr(expr->expr, "(int)");
11959 u.expr.v3->generate_code_expr_mandatory(expr);
11960 expr->expr = mputc(expr->expr, ')');
11961 }
11962
11963 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
11964 {
11965 expression_struct expr_tmp;
11966 Code::init_expr(&expr_tmp);
11967 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
11968 ->get_type_refd_last();
11969 if (!t1 || t1 == my_governor->get_type_refd_last())
11970 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11971 if (u.expr.v_optype == OPTYPE_SUBSTR) {
11972 generate_code_expr_substr(&expr_tmp);
11973 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
11974 generate_code_expr_replace(&expr_tmp);
11975 } else {
11976 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11977 }
11978 // Two temporaries to store the result of substr() or replace() and to
11979 // store the converted value.
11980 const string& tmp_id1 = get_temporary_id();
11981 const char *tmp_id_str1 = tmp_id1.c_str();
11982 const string& tmp_id2 = get_temporary_id();
11983 const char *tmp_id_str2 = tmp_id2.c_str();
11984 if (expr_tmp.preamble)
11985 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11986 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
11987 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
11988 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
11989 if (expr_tmp.postamble)
11990 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
11991 Code::free_expr(&expr_tmp);
11992 expr->preamble = mputprintf(expr->preamble,
11993 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
11994 "`%s' are not compatible at run-time\");\n",
11995 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
11996 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
11997 my_governor->get_typename().c_str(), t1->get_typename().c_str());
11998 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
11999 }
12000
12001 void Value::generate_code_expr_regexp(expression_struct *expr)
12002 {
12003 Value* v1 = u.expr.ti1->get_specific_value();
12004 Value* v2 = u.expr.t2->get_specific_value();
12005 expr->expr = mputstr(expr->expr, "regexp(");
12006 if (v1) v1->generate_code_expr_mandatory(expr);
12007 else u.expr.ti1->generate_code(expr);
12008 expr->expr = mputstr(expr->expr, ", ");
12009 if (v2) v2->generate_code_expr_mandatory(expr);
12010 else u.expr.t2->generate_code(expr);
12011 expr->expr = mputstr(expr->expr, ", ");
12012 u.expr.v3->generate_code_expr_mandatory(expr);
12013 expr->expr = mputc(expr->expr, ')');
12014 }
12015
12016 void Value::generate_code_expr_replace(expression_struct *expr)
12017 {
12018 Value* v1 = u.expr.ti1->get_specific_value();
12019 Value* v4 = u.expr.ti4->get_specific_value();
12020 bool par1_is_str;
12021 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12022 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12023 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12024 if (v1) v1->generate_code_expr_mandatory(expr);
12025 else u.expr.ti1->generate_code(expr);
12026 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12027 else expr->expr = mputstr(expr->expr, ".replace(");
12028 if (!par1_is_str && u.expr.v2->is_unfoldable())
12029 expr->expr = mputstr(expr->expr, "(int)");
12030 u.expr.v2->generate_code_expr_mandatory(expr);
12031 expr->expr = mputstr(expr->expr, ", ");
12032 if (!par1_is_str && u.expr.v3->is_unfoldable())
12033 expr->expr = mputstr(expr->expr, "(int)");
12034 u.expr.v3->generate_code_expr_mandatory(expr);
12035 expr->expr = mputstr(expr->expr, ", ");
12036 if (v4) {
12037 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12038 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12039 Value* v4_last = v4->get_value_refd_last();
12040 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12041 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12042 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_stringRepr().c_str());
12043 }
12044 v4->generate_code_expr_mandatory(expr);
12045 }
12046 else u.expr.ti4->generate_code(expr);
12047 expr->expr = mputc(expr->expr, ')');
12048 }
12049
12050 void Value::generate_code_expr_rnd(expression_struct *expr,
12051 Value *v1)
12052 {
12053 if(!v1) // simple random generation
12054 expr->expr = mputstr(expr->expr, "rnd()");
12055 else { // random generation with seeding
12056 expr->expr = mputstr(expr->expr, "rnd(");
12057 v1->generate_code_expr_mandatory(expr);
12058 expr->expr = mputc(expr->expr, ')');
12059 }
12060 }
12061
12062 void Value::generate_code_expr_create(expression_struct *expr,
12063 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12064 {
12065 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12066 // first two arguments: component type
12067 Assignment *t_ass = type->get_refd_assignment();
12068 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12069 FATAL_ERROR("Value::generate_code_expr_create()");
12070 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12071 Type::EXPECTED_DYNAMIC_VALUE);
12072 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12073 comptype = comptype->get_type_refd_last();
12074 expr->expr = comptype->get_CompBody()
12075 ->generate_code_comptype_name(expr->expr);
12076 expr->expr = mputstr(expr->expr, ", ");
12077 // third argument: component name
12078 if (name) {
12079 Value *t_val = name->get_value_refd_last();
12080 if (t_val->valuetype == V_CSTR) {
12081 // the argument is foldable to a string literal
12082 size_t str_len = t_val->u.str.val_str->size();
12083 const char *str_ptr = t_val->u.str.val_str->c_str();
12084 expr->expr = mputc(expr->expr, '"');
12085 for (size_t i = 0; i < str_len; i++)
12086 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12087 expr->expr = mputc(expr->expr, '"');
12088 } else name->generate_code_expr_mandatory(expr);
12089 } else expr->expr = mputstr(expr->expr, "NULL");
12090 expr->expr = mputstr(expr->expr, ", ");
12091 // fourth argument: location
12092 if (location) {
12093 Value *t_val = location->get_value_refd_last();
12094 if (t_val->valuetype == V_CSTR) {
12095 // the argument is foldable to a string literal
12096 size_t str_len = t_val->u.str.val_str->size();
12097 const char *str_ptr = t_val->u.str.val_str->c_str();
12098 expr->expr = mputc(expr->expr, '"');
12099 for (size_t i = 0; i < str_len; i++)
12100 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12101 expr->expr = mputc(expr->expr, '"');
12102 } else location->generate_code_expr_mandatory(expr);
12103 } else expr->expr = mputstr(expr->expr, "NULL");
12104 // fifth argument: alive flag
12105 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12106 }
12107
12108 void Value::generate_code_expr_activate(expression_struct *expr)
12109 {
12110 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12111 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12112 FATAL_ERROR("Value::generate_code_expr_activate()");
12113 expr->expr = mputprintf(expr->expr, "%s(",
12114 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12115 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12116 expr->expr = mputc(expr->expr, ')');
12117 }
12118
12119 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12120 {
12121 Value *v_last = u.expr.v1->get_value_refd_last();
12122 if (v_last->valuetype == V_ALTSTEP) {
12123 // the referred altstep is known
12124 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12125 ->get_genname_from_scope(my_scope, "activate_").c_str());
12126 } else {
12127 // the referred altstep is unknown
12128 u.expr.v1->generate_code_expr_mandatory(expr);
12129 expr->expr = mputstr(expr->expr,".activate(");
12130 }
12131 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12132 expr->expr = mputc(expr->expr, ')');
12133 }
12134
12135 void Value::generate_code_expr_execute(expression_struct *expr)
12136 {
12137 Assignment *testcase = u.expr.r1->get_refd_assignment();
12138 expr->expr = mputprintf(expr->expr, "%s(",
12139 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12140 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12141 if (parlist->get_nof_pars() > 0) {
12142 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12143 0, false);
12144 expr->expr = mputstr(expr->expr, ", ");
12145 }
12146 if (u.expr.v2) {
12147 expr->expr = mputstr(expr->expr, "TRUE, ");
12148 u.expr.v2->generate_code_expr_mandatory(expr);
12149 expr->expr = mputc(expr->expr, ')');
12150 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12151 }
12152
12153 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12154 {
12155 Value *v_last = u.expr.v1->get_value_refd_last();
12156 if (v_last->valuetype == V_TESTCASE) {
12157 // the referred testcase is known
12158 Assignment *testcase = v_last->get_refd_fat();
12159 expr->expr = mputprintf(expr->expr, "%s(",
12160 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12161 u.expr.ap_list2->generate_code_alias(expr,
12162 testcase->get_FormalParList(), 0, false);
12163 } else {
12164 // the referred testcase is unknown
12165 u.expr.v1->generate_code_expr_mandatory(expr);
12166 expr->expr = mputstr(expr->expr,".execute(");
12167 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12168 }
12169 if (u.expr.ap_list2->get_nof_pars() > 0)
12170 expr->expr = mputstr(expr->expr, ", ");
12171 if (u.expr.v3) {
12172 expr->expr = mputstr(expr->expr, "TRUE, ");
12173 u.expr.v3->generate_code_expr_mandatory(expr);
12174 expr->expr = mputc(expr->expr, ')');
12175 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12176 }
12177
12178 void Value::generate_code_expr_invoke(expression_struct *expr)
12179 {
12180 Value *last_v = u.invoke.v->get_value_refd_last();
12181 if (last_v->get_valuetype() == V_FUNCTION) {
12182 // the referred function is known
12183 Assignment *function = last_v->get_refd_fat();
12184 expr->expr = mputprintf(expr->expr, "%s(",
12185 function->get_genname_from_scope(my_scope).c_str());
12186 u.invoke.ap_list->generate_code_alias(expr,
12187 function->get_FormalParList(), function->get_RunsOnType(), false);
12188 } else {
12189 // the referred function is unknown
12190 u.invoke.v->generate_code_expr_mandatory(expr);
12191 expr->expr = mputstr(expr->expr, ".invoke(");
12192 Type* gov_last = last_v->get_expr_governor_last();
12193 u.invoke.ap_list->generate_code_alias(expr, 0,
12194 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12195 }
12196 expr->expr = mputc(expr->expr, ')');
12197 }
12198
12199 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12200 Reference *ref)
12201 {
12202 // if the referenced value points to an optional value field the
12203 // generated code has to be corrected at the end:
12204 // `fieldid()' => `fieldid()()'
12205 Assignment *ass = ref->get_refd_assignment();
12206 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12207 switch (ass->get_asstype()) {
12208 case Assignment::A_CONST:
12209 case Assignment::A_EXT_CONST:
12210 case Assignment::A_MODULEPAR:
12211 case Assignment::A_VAR:
12212 case Assignment::A_FUNCTION_RVAL:
12213 case Assignment::A_EXT_FUNCTION_RVAL:
12214 case Assignment::A_PAR_VAL_IN:
12215 case Assignment::A_PAR_VAL_OUT:
12216 case Assignment::A_PAR_VAL_INOUT:
12217 // only these are mapped to value objects
12218 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12219 expr->expr = mputstr(expr->expr, "()");
12220 break;
12221 default:
12222 break;
12223 }
12224 }
12225
12226 void Value::generate_code_expr_encode(expression_struct *expr)
12227 {
12228 Value* v1 = 0;
12229
12230 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12231 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12232 v1 = templ->get_specific_value();
12233 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12234
12235 expression_struct expr2;
12236 Code::init_expr(&expr2);
12237
12238 bool is_templ = false;
12239 switch (templ->get_templatetype()) {
12240 case Template::SPECIFIC_VALUE:
12241 v1->generate_code_expr_mandatory(&expr2);
12242 break;
12243 default:
12244 u.expr.ti1->generate_code(&expr2);
12245 is_templ = true;
12246 break;
12247 }
12248
12249 if (!gov_last->is_coding_by_function()) {
12250 const string& tmp_id = get_temporary_id();
12251 const string& tmp_buf_id = get_temporary_id();
12252 const string& tmp_ref_id = get_temporary_id();
12253 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12254 tmp_id.c_str());
12255 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12256 tmp_buf_id.c_str());
12257 if (expr2.preamble) { // copy preamble setting up the argument, if any
12258 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12259 expr->preamble = mputc (expr->preamble, '\n');
12260 }
12261 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12262 gov_last->get_genname_typedescriptor(
12263 u.expr.ti1->get_Template()->get_my_scope()
12264 ).c_str(),
12265 tmp_ref_id.c_str(),
12266 expr2.expr);
12267 if (is_templ) // make a value out of the template, if needed
12268 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12269 expr->preamble = mputprintf(expr->preamble,
12270 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12271 tmp_ref_id.c_str(),
12272 gov_last->get_genname_typedescriptor(
12273 u.expr.ti1->get_Template()->get_my_scope()
12274 ).c_str(),
12275 tmp_buf_id.c_str(),
12276 gov_last->get_coding(true).c_str()
12277 );
12278 expr->preamble = mputstr(expr->preamble, ");\n");
12279 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12280 tmp_buf_id.c_str(),
12281 tmp_id.c_str()
12282 );
12283 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12284 if (expr2.postamble)
12285 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12286 } else
12287 expr->expr = mputprintf(expr->expr, "%s(%s)",
12288 gov_last->get_coding(true).c_str(), expr2.expr);
12289 Code::free_expr(&expr2);
12290 }
12291
12292 void Value::generate_code_expr_decode(expression_struct *expr)
12293 {
12294 expression_struct expr1, expr2;
12295 Code::init_expr(&expr1);
12296 Code::init_expr(&expr2);
12297 u.expr.r1->generate_code(&expr1);
12298 u.expr.r2->generate_code(&expr2);
12299
12300 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12301 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12302 get_type_refd_last();
12303
12304 if (expr1.preamble)
12305 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12306 if (expr2.preamble)
12307 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12308
12309 if (!_type->is_coding_by_function()) {
12310 const string& tmp_id = get_temporary_id();
12311 const string& buffer_id = get_temporary_id();
12312 const string& retval_id = get_temporary_id();
12313 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12314 field_is_optional(u.expr.r2->get_subrefs());
12315
12316 expr->preamble = mputprintf(expr->preamble,
12317 "TTCN_Buffer %s(bit2oct(%s));\n"
12318 "INTEGER %s;\n"
12319 "TTCN_EncDec::set_error_behavior("
12320 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12321 "TTCN_EncDec::clear_error();\n",
12322 buffer_id.c_str(),
12323 expr1.expr,
12324 retval_id.c_str()
12325 );
12326 expr->preamble = mputprintf(expr->preamble,
12327 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12328 expr2.expr,
12329 optional ? "()" : "",
12330 _type->get_genname_typedescriptor(
12331 u.expr.r2->get_my_scope()
12332 ).c_str(),
12333 buffer_id.c_str(),
12334 _type->get_coding(false).c_str()
12335 );
12336 expr->preamble = mputprintf(expr->preamble,
12337 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12338 "case TTCN_EncDec::ET_NONE: {\n"
12339 "%s.cut();\n"
12340 "OCTETSTRING %s;\n"
12341 "%s.get_string(%s);\n"
12342 "%s = oct2bit(%s);\n"
12343 "%s = 0;\n"
12344 "}break;\n"
12345 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12346 "case TTCN_EncDec::ET_LEN_ERR:\n"
12347 "%s = 2;\n"
12348 "break;\n"
12349 "default:\n"
12350 "%s = 1;\n"
12351 "}\n"
12352 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12353 "TTCN_EncDec::EB_DEFAULT);\n"
12354 "TTCN_EncDec::clear_error();\n",
12355 buffer_id.c_str(),
12356 tmp_id.c_str(),
12357 buffer_id.c_str(),
12358 tmp_id.c_str(),
12359 expr1.expr,
12360 tmp_id.c_str(),
12361 retval_id.c_str(),
12362 retval_id.c_str(),
12363 retval_id.c_str()
12364 );
12365 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12366 } else
12367 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12368 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12369 if (expr1.postamble)
12370 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12371 if (expr2.postamble)
12372 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12373 Code::free_expr(&expr1);
12374 Code::free_expr(&expr2);
12375 }
12376
12377 char *Value::generate_code_init_choice(char *str, const char *name)
12378 {
12379 const char *alt_name = u.choice.alt_name->get_name().c_str();
12380 // Safe as long as get_name() returns a const string&, not a temporary.
12381 const char *alt_prefix =
12382 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12383 ? "AT_" : "";
12384 if (u.choice.alt_value->needs_temp_ref()) {
12385 const string& tmp_id = get_temporary_id();
12386 const char *tmp_id_str = tmp_id.c_str();
12387 str = mputprintf(str, "{\n"
12388 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12389 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12390 alt_prefix, alt_name);
12391 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12392 str = mputstr(str, "}\n");
12393 } else {
12394 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12395 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12396 Free(embedded_name);
12397 }
12398 return str;
12399 }
12400
12401 char *Value::generate_code_init_seof(char *str, const char *name)
12402 {
12403 size_t nof_vs = u.val_vs->get_nof_vs();
12404 if (nof_vs > 0) {
12405 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12406 const string& embedded_type =
12407 my_governor->get_ofType()->get_genname_value(my_scope);
12408 const char *embedded_type_str = embedded_type.c_str();
12409 for (size_t i = 0; i < nof_vs; i++) {
12410 Value *comp_v = u.val_vs->get_v_byIndex(i);
12411
12412 if (comp_v->valuetype == V_NOTUSED) continue;
12413 else if (comp_v->needs_temp_ref()) {
12414 const string& tmp_id = get_temporary_id();
12415 const char *tmp_id_str = tmp_id.c_str();
12416 str = mputprintf(str, "{\n"
12417 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12418 (unsigned long) i);
12419 str = comp_v->generate_code_init(str, tmp_id_str);
12420 str = mputstr(str, "}\n");
12421 } else {
12422 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12423 str = comp_v->generate_code_init(str, embedded_name);
12424 Free(embedded_name);
12425 }
12426 }
12427 } else {
12428 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12429 }
12430 return str;
12431 }
12432
12433 char *Value::generate_code_init_indexed(char *str, const char *name)
12434 {
12435 size_t nof_ivs = u.val_vs->get_nof_ivs();
12436 if (nof_ivs > 0) {
12437 // Previous values can be truncated. The concept is similar to
12438 // templates.
12439 Type *t_last = my_governor->get_type_refd_last();
12440 const string& oftype_name =
12441 t_last->get_ofType()->get_genname_value(my_scope);
12442 const char *oftype_name_str = oftype_name.c_str();
12443 for (size_t i = 0; i < nof_ivs; i++) {
12444 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12445 const string& tmp_id_1 = get_temporary_id();
12446 str = mputstr(str, "{\n");
12447 Value *index = iv->get_index();
12448 if (index->get_valuetype() != V_INT) {
12449 const string& tmp_id_2 = get_temporary_id();
12450 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12451 str = index->generate_code_init(str, tmp_id_2.c_str());
12452 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12453 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12454 } else {
12455 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12456 tmp_id_1.c_str(), name,
12457 (index->get_val_Int()->t_str()).c_str());
12458 }
12459 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12460 str = mputstr(str, "}\n");
12461 }
12462 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12463 return str;
12464 }
12465
12466 char *Value::generate_code_init_array(char *str, const char *name)
12467 {
12468 size_t nof_vs = u.val_vs->get_nof_vs();
12469 Type *t_last = my_governor->get_type_refd_last();
12470 Int index_offset = t_last->get_dimension()->get_offset();
12471 const string& embedded_type =
12472 t_last->get_ofType()->get_genname_value(my_scope);
12473 const char *embedded_type_str = embedded_type.c_str();
12474 for (size_t i = 0; i < nof_vs; i++) {
12475 Value *comp_v = u.val_vs->get_v_byIndex(i);
12476 if (comp_v->valuetype == V_NOTUSED) continue;
12477 else if (comp_v->needs_temp_ref()) {
12478 const string& tmp_id = get_temporary_id();
12479 const char *tmp_id_str = tmp_id.c_str();
12480 str = mputprintf(str, "{\n"
12481 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12482 Int2string(index_offset + i).c_str());
12483 str = comp_v->generate_code_init(str, tmp_id_str);
12484 str = mputstr(str, "}\n");
12485 } else {
12486 char *embedded_name = mprintf("%s[%s]", name,
12487 Int2string(index_offset + i).c_str());
12488 str = comp_v->generate_code_init(str, embedded_name);
12489 Free(embedded_name);
12490 }
12491 }
12492 return str;
12493 }
12494
12495 char *Value::generate_code_init_se(char *str, const char *name)
12496 {
12497 Type *type = my_governor->get_type_refd_last();
12498 size_t nof_comps = type->get_nof_comps();
12499 if (nof_comps > 0) {
12500 for (size_t i = 0; i < nof_comps; i++) {
12501 CompField *cf = type->get_comp_byIndex(i);
12502 const Identifier& field_id = cf->get_name();
12503 const char *field_name = field_id.get_name().c_str();
12504 Value *field_v;
12505 if (u.val_nvs->has_nv_withName(field_id)) {
12506 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12507 if (field_v->valuetype == V_NOTUSED) continue;
12508 if (field_v->valuetype == V_OMIT) field_v = 0;
12509 } else if (is_asn1()) {
12510 if (cf->has_default()) {
12511 // handle like a referenced value
12512 Value *defval = cf->get_defval();
12513 if (needs_init_precede(defval)) {
12514 str = defval->generate_code_init(str,
12515 defval->get_lhs_name().c_str());
12516 }
12517 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12518 defval->get_genname_own(my_scope).c_str());
12519 continue;
12520 } else {
12521 if (!cf->get_is_optional())
12522 FATAL_ERROR("Value::generate_code_init()");
12523 field_v = 0;
12524 }
12525 } else {
12526 continue;
12527 }
12528 if (field_v) {
12529 // the value is not omit
12530 if (field_v->needs_temp_ref()) {
12531 const string& tmp_id = get_temporary_id();
12532 const char *tmp_id_str = tmp_id.c_str();
12533 str = mputprintf(str, "{\n"
12534 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12535 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12536 field_name);
12537 str = field_v->generate_code_init(str, tmp_id_str);
12538 str = mputstr(str, "}\n");
12539 } else {
12540 char *embedded_name = mprintf("%s.%s()", name,
12541 field_name);
12542 if (cf->get_is_optional() && field_v->is_compound())
12543 embedded_name = mputstr(embedded_name, "()");
12544 str = field_v->generate_code_init(str, embedded_name);
12545 Free(embedded_name);
12546 }
12547 } else {
12548 // the value is omit
12549 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12550 name, field_name);
12551 }
12552 }
12553 } else {
12554 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12555 }
12556 return str;
12557 }
12558
12559 char *Value::generate_code_init_refd(char *str, const char *name)
12560 {
12561 Value *v = get_value_refd_last();
12562 if (v == this) {
12563 // the referred value is not available at compile time
12564 // the code generation is based on the reference
12565 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
12566 str = TypeConv::gen_conv_code_refd(str, name, v);
12567 } else {
12568 expression_struct expr;
12569 Code::init_expr(&expr);
12570 expr.expr = mputprintf(expr.expr, "%s = ", name);
12571 u.ref.ref->generate_code_const_ref(&expr);
12572 str = Code::merge_free_expr(str, &expr);
12573 }
12574 } else {
12575 // the referred value is available at compile time
12576 // the code generation is based on the referred value
12577 if (v->has_single_expr() &&
12578 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
12579 // simple substitution for in-line values within the same module
12580 str = mputprintf(str, "%s = %s;\n", name,
12581 v->get_single_expr().c_str());
12582 } else {
12583 // use a simple reference to reduce code size
12584 if (needs_init_precede(v)) {
12585 // the referred value must be initialized first
12586 if (!v->is_toplevel() && v->needs_temp_ref()) {
12587 // temporary id should be introduced for the lhs
12588 const string& tmp_id = get_temporary_id();
12589 const char *tmp_id_str = tmp_id.c_str();
12590 str = mputprintf(str, "{\n"
12591 "%s& %s = %s;\n",
12592 v->get_my_governor()->get_genname_value(my_scope).c_str(),
12593 tmp_id_str, v->get_lhs_name().c_str());
12594 str = v->generate_code_init(str, tmp_id_str);
12595 str = mputstr(str, "}\n");
12596 } else {
12597 str = v->generate_code_init(str, v->get_lhs_name().c_str());
12598 }
12599 }
12600 str = mputprintf(str, "%s = %s;\n", name,
12601 v->get_genname_own(my_scope).c_str());
12602 }
12603 }
12604 return str;
12605 }
12606
12607 bool Value::explicit_cast_needed(bool forIsValue)
12608 {
12609 Value *v_last = get_value_refd_last();
12610 if (v_last != this) {
12611 // this is a foldable referenced value
12612 // if the reference points to an imported or compound value the code
12613 // generation will be based on the reference so cast is not needed
12614 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
12615 || !v_last->has_single_expr()) return false;
12616 } else if (v_last->valuetype == V_REFD) {
12617 // this is an unfoldable reference (v_last==this)
12618 // explicit cast is needed only for string element references
12619 if (forIsValue) return false;
12620 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
12621 return t_subrefs && t_subrefs->refers_to_string_element();
12622 }
12623 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
12624 Type *t_governor = v_last->my_governor->get_type_refd_last();
12625 switch (t_governor->get_typetype()) {
12626 case Type::T_NULL:
12627 case Type::T_BOOL:
12628 case Type::T_INT:
12629 case Type::T_INT_A:
12630 case Type::T_REAL:
12631 case Type::T_ENUM_A:
12632 case Type::T_ENUM_T:
12633 case Type::T_VERDICT:
12634 case Type::T_COMPONENT:
12635 // these are mapped to built-in C/C++ types
12636 return true;
12637 case Type::T_SEQ_A:
12638 case Type::T_SEQ_T:
12639 case Type::T_SET_A:
12640 case Type::T_SET_T:
12641 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12642 return t_governor->get_nof_comps() == 0;
12643 case Type::T_SEQOF:
12644 case Type::T_SETOF:
12645 // the C++ equivalent of value {} is ambiguous
12646 // tr926
12647 return true;
12648 case Type::T_FUNCTION:
12649 case Type::T_ALTSTEP:
12650 case Type::T_TESTCASE:
12651 return true;
12652 default:
12653 return false;
12654 }
12655 }
12656
12657 bool Value::has_single_expr()
12658 {
12659 if (get_needs_conversion()) return false;
12660 switch (valuetype) {
12661 case V_EXPR:
12662 return has_single_expr_expr();
12663 case V_CHOICE:
12664 case V_ARRAY:
12665 // a union or array value cannot be represented as an in-line expression
12666 return false;
12667 case V_SEQOF:
12668 case V_SETOF:
12669 // only an empty record/set of value can be represented as an in-line
12670 // expression
12671 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
12672 else return u.val_vs->get_nof_ivs() == 0;
12673 case V_SEQ:
12674 case V_SET: {
12675 // only a value for an empty record/set type can be represented as an
12676 // in-line expression
12677 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
12678 Type *type = my_governor->get_type_refd_last();
12679 return type->get_nof_comps() == 0; }
12680 case V_REFD: {
12681 Value *v_last = get_value_refd_last();
12682 // If the above call hit an error and set_valuetype(V_ERROR),
12683 // then u.ref.ref has been freed. Avoid the segfault.
12684 if (valuetype == V_ERROR)
12685 return false;
12686 if (v_last != this && v_last->has_single_expr() &&
12687 v_last->my_scope->get_scope_mod_gen() ==
12688 my_scope->get_scope_mod_gen()) return true;
12689 else return u.ref.ref->has_single_expr(); }
12690 case V_INVOKE:
12691 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
12692 case V_ERROR:
12693 case V_NAMEDINT:
12694 case V_NAMEDBITS:
12695 case V_UNDEF_LOWERID:
12696 case V_UNDEF_BLOCK:
12697 case V_REFER:
12698 // these values cannot occur during code generation
12699 FATAL_ERROR("Value::has_single_expr()");
12700 case V_INT:
12701 return u.val_Int->is_native_fit();
12702 default:
12703 // other value types (literal values) do not need temporary reference
12704 return true;
12705 }
12706 }
12707
12708 string Value::get_single_expr()
12709 {
12710 switch (valuetype) {
12711 case V_NULL:
12712 return string("ASN_NULL_VALUE");
12713 case V_BOOL:
12714 return string(u.val_bool ? "TRUE" : "FALSE");
12715 case V_INT:
12716 if (u.val_Int->is_native_fit()) { // Be sure.
12717 return u.val_Int->t_str();
12718 } else {
12719 // get_single_expr may be called only if has_single_expr() is true.
12720 // The only exception is V_INT, where get_single_expr may be called
12721 // even if is_native_fit (which is used to implement has_single_expr)
12722 // returns false.
12723 string ret_val('"');
12724 ret_val += u.val_Int->t_str();
12725 ret_val += '"';
12726 return ret_val;
12727 }
12728 case V_REAL:
12729 return Real2code(u.val_Real);
12730 case V_ENUM:
12731 return get_single_expr_enum();
12732 case V_BSTR:
12733 return get_my_scope()->get_scope_mod_gen()
12734 ->add_bitstring_literal(*u.str.val_str);
12735 case V_HSTR:
12736 return get_my_scope()->get_scope_mod_gen()
12737 ->add_hexstring_literal(*u.str.val_str);
12738 case V_OSTR:
12739 return get_my_scope()->get_scope_mod_gen()
12740 ->add_octetstring_literal(*u.str.val_str);
12741 case V_CSTR:
12742 return get_my_scope()->get_scope_mod_gen()
12743 ->add_charstring_literal(*u.str.val_str);
12744 case V_USTR:
12745 if (u.ustr.convert_str) {
12746 set_valuetype(V_CSTR);
12747 return get_my_scope()->get_scope_mod_gen()
12748 ->add_charstring_literal(*u.str.val_str);
12749 } else
12750 return get_my_scope()->get_scope_mod_gen()
12751 ->add_ustring_literal(*u.ustr.val_ustr);
12752 case V_ISO2022STR:
12753 return get_single_expr_iso2022str();
12754 case V_OID:
12755 case V_ROID: {
12756 vector<string> comps;
12757 bool is_constant = get_oid_comps(comps);
12758 size_t nof_comps = comps.size();
12759 string oi_str;
12760 for (size_t i = 0; i < nof_comps; i++) {
12761 if (i > 0) oi_str += ", ";
12762 oi_str += *(comps[i]);
12763 }
12764 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
12765 comps.clear();
12766 if (is_constant) {
12767 // the objid only contains constants
12768 // => create a literal and return its name
12769 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
12770 }
12771 // the objid contains at least one variable
12772 // => append the number of components before the component values in the string and return it
12773 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
12774 case V_SEQOF:
12775 case V_SETOF:
12776 if (u.val_vs->get_nof_vs() > 0)
12777 FATAL_ERROR("Value::get_single_expr()");
12778 return string("NULL_VALUE");
12779 case V_SEQ:
12780 case V_SET:
12781 if (u.val_nvs->get_nof_nvs() > 0)
12782 FATAL_ERROR("Value::get_single_expr()");
12783 return string("NULL_VALUE");
12784 case V_REFD: {
12785 Value *v_last = get_value_refd_last();
12786 if (v_last != this && v_last->has_single_expr() &&
12787 v_last->my_scope->get_scope_mod_gen() ==
12788 my_scope->get_scope_mod_gen()) {
12789 // the reference points to another single value in the same module
12790 return v_last->get_single_expr();
12791 } else {
12792 // convert the reference to a single expression
12793 expression_struct expr;
12794 Code::init_expr(&expr);
12795 u.ref.ref->generate_code_const_ref(&expr);
12796 if (expr.preamble || expr.postamble)
12797 FATAL_ERROR("Value::get_single_expr()");
12798 string ret_val(expr.expr);
12799 Code::free_expr(&expr);
12800 return ret_val;
12801 } }
12802 case V_OMIT:
12803 return string("OMIT_VALUE");
12804 case V_VERDICT:
12805 switch (u.verdict) {
12806 case Verdict_NONE:
12807 return string("NONE");
12808 case Verdict_PASS:
12809 return string("PASS");
12810 case Verdict_INCONC:
12811 return string("INCONC");
12812 case Verdict_FAIL:
12813 return string("FAIL");
12814 case Verdict_ERROR:
12815 return string("ERROR");
12816 default:
12817 FATAL_ERROR("Value::get_single_expr()");
12818 return string();
12819 }
12820 case V_DEFAULT_NULL:
12821 return string("NULL_COMPREF");
12822 case V_FAT_NULL: {
12823 string ret_val('(');
12824 ret_val += my_governor->get_genname_value(my_scope);
12825 ret_val += "::function_pointer)Module_List::get_fat_null()";
12826 return ret_val; }
12827 case V_EXPR:
12828 case V_INVOKE: {
12829 expression_struct expr;
12830 Code::init_expr(&expr);
12831 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
12832 else generate_code_expr_invoke(&expr);
12833 if (expr.preamble || expr.postamble)
12834 FATAL_ERROR("Value::get_single_expr()");
12835 string ret_val(expr.expr);
12836 Code::free_expr(&expr);
12837 return ret_val; }
12838 case V_MACRO:
12839 switch (u.macro) {
12840 case MACRO_TESTCASEID:
12841 return string("TTCN_Runtime::get_testcase_id_macro()");
12842 default:
12843 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
12844 return string();
12845 }
12846 case V_FUNCTION:
12847 case V_ALTSTEP:
12848 case V_TESTCASE:
12849 return get_single_expr_fat();
12850 default:
12851 FATAL_ERROR("Value::get_single_expr()");
12852 return string();
12853 }
12854 }
12855
12856 bool Value::has_single_expr_expr()
12857 {
12858 switch (u.expr.v_optype) {
12859 case OPTYPE_RND: // -
12860 case OPTYPE_COMP_NULL:
12861 case OPTYPE_COMP_MTC:
12862 case OPTYPE_COMP_SYSTEM:
12863 case OPTYPE_COMP_SELF:
12864 case OPTYPE_COMP_RUNNING_ANY:
12865 case OPTYPE_COMP_RUNNING_ALL:
12866 case OPTYPE_COMP_ALIVE_ANY:
12867 case OPTYPE_COMP_ALIVE_ALL:
12868 case OPTYPE_TMR_RUNNING_ANY:
12869 case OPTYPE_GETVERDICT:
12870 case OPTYPE_TESTCASENAME:
12871 return true;
12872 case OPTYPE_ENCODE:
12873 case OPTYPE_DECODE:
12874 case OPTYPE_ISBOUND:
12875 case OPTYPE_ISPRESENT:
12876 case OPTYPE_TTCN2STRING:
12877 return false;
12878 case OPTYPE_UNARYPLUS: // v1
12879 case OPTYPE_UNARYMINUS:
12880 case OPTYPE_NOT:
12881 case OPTYPE_NOT4B:
12882 case OPTYPE_BIT2HEX:
12883 case OPTYPE_BIT2INT:
12884 case OPTYPE_BIT2OCT:
12885 case OPTYPE_BIT2STR:
12886 case OPTYPE_CHAR2INT:
12887 case OPTYPE_CHAR2OCT:
12888 case OPTYPE_FLOAT2INT:
12889 case OPTYPE_FLOAT2STR:
12890 case OPTYPE_HEX2BIT:
12891 case OPTYPE_HEX2INT:
12892 case OPTYPE_HEX2OCT:
12893 case OPTYPE_HEX2STR:
12894 case OPTYPE_INT2CHAR:
12895 case OPTYPE_INT2FLOAT:
12896 case OPTYPE_INT2STR:
12897 case OPTYPE_INT2UNICHAR:
12898 case OPTYPE_OCT2BIT:
12899 case OPTYPE_OCT2CHAR:
12900 case OPTYPE_OCT2HEX:
12901 case OPTYPE_OCT2INT:
12902 case OPTYPE_OCT2STR:
12903 case OPTYPE_STR2BIT:
12904 case OPTYPE_STR2FLOAT:
12905 case OPTYPE_STR2HEX:
12906 case OPTYPE_STR2INT:
12907 case OPTYPE_STR2OCT:
12908 case OPTYPE_UNICHAR2INT:
12909 case OPTYPE_UNICHAR2CHAR:
12910 case OPTYPE_ENUM2INT:
12911 case OPTYPE_RNDWITHVAL:
12912 case OPTYPE_ISCHOSEN_V: // v1 i2
12913 case OPTYPE_COMP_RUNNING:
12914 case OPTYPE_COMP_ALIVE:
12915 case OPTYPE_GET_STRINGENCODING:
12916 case OPTYPE_REMOVE_BOM:
12917 case OPTYPE_DECODE_BASE64:
12918 return u.expr.v1->has_single_expr();
12919 case OPTYPE_ISCHOSEN_T: // t1 i2
12920 return u.expr.t1->has_single_expr();
12921 case OPTYPE_ADD: // v1 v2
12922 case OPTYPE_SUBTRACT:
12923 case OPTYPE_MULTIPLY:
12924 case OPTYPE_DIVIDE:
12925 case OPTYPE_MOD:
12926 case OPTYPE_REM:
12927 case OPTYPE_CONCAT:
12928 case OPTYPE_EQ:
12929 case OPTYPE_LT:
12930 case OPTYPE_GT:
12931 case OPTYPE_NE:
12932 case OPTYPE_GE:
12933 case OPTYPE_LE:
12934 case OPTYPE_XOR:
12935 case OPTYPE_AND4B:
12936 case OPTYPE_OR4B:
12937 case OPTYPE_XOR4B:
12938 case OPTYPE_SHL:
12939 case OPTYPE_SHR:
12940 case OPTYPE_ROTL:
12941 case OPTYPE_ROTR:
12942 case OPTYPE_INT2BIT:
12943 case OPTYPE_INT2HEX:
12944 case OPTYPE_INT2OCT:
12945 return u.expr.v1->has_single_expr() &&
12946 u.expr.v2->has_single_expr();
12947 case OPTYPE_UNICHAR2OCT:
12948 case OPTYPE_OCT2UNICHAR:
12949 case OPTYPE_ENCODE_BASE64:
12950 return u.expr.v1->has_single_expr() &&
12951 (!u.expr.v2 || u.expr.v2->has_single_expr());
12952 case OPTYPE_AND:
12953 case OPTYPE_OR:
12954 return u.expr.v1->has_single_expr() &&
12955 u.expr.v2->has_single_expr() &&
12956 !u.expr.v2->needs_short_circuit();
12957 case OPTYPE_SUBSTR:
12958 return u.expr.ti1->has_single_expr() &&
12959 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
12960 case OPTYPE_REGEXP:
12961 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
12962 u.expr.v3->has_single_expr();
12963 case OPTYPE_DECOMP: // v1 v2 v3
12964 return u.expr.v1->has_single_expr() &&
12965 u.expr.v2->has_single_expr() &&
12966 u.expr.v3->has_single_expr();
12967 case OPTYPE_REPLACE:
12968 return u.expr.ti1->has_single_expr() &&
12969 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
12970 u.expr.ti4->has_single_expr();
12971 case OPTYPE_ISVALUE: // ti1
12972 case OPTYPE_LENGTHOF: // ti1
12973 case OPTYPE_SIZEOF: // ti1
12974 case OPTYPE_VALUEOF: // ti1
12975 return u.expr.ti1->has_single_expr();
12976 case OPTYPE_LOG2STR:
12977 return u.expr.logargs->has_single_expr();
12978 case OPTYPE_MATCH: // v1 t2
12979 return u.expr.v1->has_single_expr() &&
12980 u.expr.t2->has_single_expr();
12981 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
12982 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
12983 (!u.expr.v3 || u.expr.v3->has_single_expr());
12984 case OPTYPE_TMR_READ: // r1
12985 case OPTYPE_TMR_RUNNING:
12986 case OPTYPE_ACTIVATE:
12987 return u.expr.r1->has_single_expr();
12988 case OPTYPE_EXECUTE: // r1 [v2]
12989 return u.expr.r1->has_single_expr() &&
12990 (!u.expr.v2 || u.expr.v2->has_single_expr());
12991 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
12992 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
12993 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
12994 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
12995 (!u.expr.v3 || u.expr.v3->has_single_expr());
12996 default:
12997 FATAL_ERROR("Value::has_single_expr_expr()");
12998 } // switch
12999 }
13000
13001 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13002 {
13003 if (!v->has_single_expr()) return false;
13004 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13005 if (!ap_list->get_par(i)->has_single_expr()) return false;
13006 return true;
13007 }
13008
13009 string Value::get_single_expr_enum()
13010 {
13011 string ret_val(my_governor->get_genname_value(my_scope));
13012 ret_val += "::";
13013 ret_val += u.val_id->get_name();
13014 return ret_val;
13015 }
13016
13017 string Value::get_single_expr_iso2022str()
13018 {
13019 string ret_val;
13020 Type *type = get_my_governor()->get_type_refd_last();
13021 switch (type->get_typetype()) {
13022 case Type::T_TELETEXSTRING:
13023 ret_val += "TTCN_ISO2022_2_TeletexString";
13024 break;
13025 case Type::T_VIDEOTEXSTRING:
13026 ret_val += "TTCN_ISO2022_2_VideotexString";
13027 break;
13028 case Type::T_GRAPHICSTRING:
13029 case Type::T_OBJECTDESCRIPTOR:
13030 ret_val += "TTCN_ISO2022_2_GraphicString";
13031 break;
13032 case Type::T_GENERALSTRING:
13033 ret_val += "TTCN_ISO2022_2_GeneralString";
13034 break;
13035 default:
13036 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13037 } // switch
13038 ret_val += '(';
13039 string *ostr = char2oct(*u.str.val_str);
13040 ret_val += get_my_scope()->get_scope_mod_gen()
13041 ->add_octetstring_literal(*ostr);
13042 delete ostr;
13043 ret_val += ')';
13044 return ret_val;
13045 }
13046
13047 string Value::get_single_expr_fat()
13048 {
13049 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13050 // the ampersand operator is not really necessary to obtain the function
13051 // pointer, but some older versions of GCC cannot instantiate the
13052 // appropriate operator=() member of class OPTIONAL when necessary
13053 // if only the function name is given
13054 string ret_val('&');
13055 switch (valuetype) {
13056 case V_FUNCTION:
13057 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13058 break;
13059 case V_ALTSTEP:
13060 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13061 ret_val += "_instance";
13062 break;
13063 case V_TESTCASE:
13064 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13065 break;
13066 default:
13067 FATAL_ERROR("Value::get_single_expr_fat()");
13068 }
13069 return ret_val;
13070 }
13071
13072 bool Value::is_compound()
13073 {
13074 switch (valuetype) {
13075 case V_CHOICE:
13076 case V_SEQOF:
13077 case V_SETOF:
13078 case V_ARRAY:
13079 case V_SEQ:
13080 case V_SET:
13081 return true;
13082 default:
13083 return false;
13084 }
13085 }
13086
13087 bool Value::needs_temp_ref()
13088 {
13089 switch (valuetype) {
13090 case V_SEQOF:
13091 case V_SETOF:
13092 if (!is_indexed()) {
13093 // Temporary reference is needed if the value has at least one real
13094 // element (i.e. it is not empty or contains only not used symbols).
13095 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13096 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13097 }
13098 } else {
13099 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13100 if (u.val_vs->get_iv_byIndex(i)->get_value()
13101 ->valuetype != V_NOTUSED)
13102 return true;
13103 }
13104 }
13105 return false;
13106 case V_ARRAY: {
13107 size_t nof_real_vs = 0;
13108 if (!is_indexed()) {
13109 // Temporary reference is needed if the array value has at least two
13110 // real elements (excluding not used symbols).
13111 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13112 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13113 nof_real_vs++;
13114 if (nof_real_vs > 1) return true;
13115 }
13116 }
13117 } else {
13118 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13119 if (u.val_vs->get_iv_byIndex(i)->get_value()
13120 ->valuetype != V_NOTUSED) {
13121 nof_real_vs++;
13122 if (nof_real_vs > 1) return true;
13123 }
13124 }
13125 }
13126 return false; }
13127 case V_SEQ:
13128 case V_SET:
13129 if (is_asn1()) {
13130 // it depends on the type since fields with omit or default value
13131 // may not be present
13132 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13133 } else {
13134 // incomplete values are allowed in TTCN-3
13135 // we should check the number of value components
13136 return u.val_nvs->get_nof_nvs() > 1;
13137 }
13138 case V_ERROR:
13139 case V_NAMEDINT:
13140 case V_NAMEDBITS:
13141 case V_UNDEF_LOWERID:
13142 case V_UNDEF_BLOCK:
13143 case V_TTCN3_NULL:
13144 // these values cannot occur during code generation
13145 FATAL_ERROR("Value::needs_temp_ref()");
13146 case V_INT:
13147 return !u.val_Int->is_native();
13148 default:
13149 // other value types (literal values) do not need temporary reference
13150 return false;
13151 }
13152 }
13153
13154 bool Value::needs_short_circuit()
13155 {
13156 switch (valuetype) {
13157 case V_BOOL:
13158 return false;
13159 case V_REFD:
13160 // examined below
13161 break;
13162 case V_EXPR:
13163 case V_INVOKE:
13164 // sub-expressions should be evaluated only if necessary
13165 return true;
13166 default:
13167 FATAL_ERROR("Value::needs_short_circuit()");
13168 }
13169 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13170 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13171 switch (t_ass->get_asstype()) {
13172 case Assignment::A_FUNCTION_RVAL:
13173 case Assignment::A_EXT_FUNCTION_RVAL:
13174 // avoid unnecessary call of a function
13175 return true;
13176 case Assignment::A_CONST:
13177 case Assignment::A_EXT_CONST:
13178 case Assignment::A_MODULEPAR:
13179 case Assignment::A_VAR:
13180 case Assignment::A_PAR_VAL_IN:
13181 case Assignment::A_PAR_VAL_OUT:
13182 case Assignment::A_PAR_VAL_INOUT:
13183 // depends on field/array sub-references, which is examined below
13184 break;
13185 default:
13186 FATAL_ERROR("Value::needs_short_circuit()");
13187 }
13188 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13189 if (t_subrefs) {
13190 // the evaluation of the reference does not have side effects
13191 // (i.e. false shall be returned) only if all sub-references point to
13192 // mandatory fields of record/set types
13193 Type *t_type = t_ass->get_Type();
13194 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13195 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13196 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13197 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13198 if (t_cf->get_is_optional()) return true;
13199 t_type = t_cf->get_type();
13200 } else return true;
13201 }
13202 }
13203 return false;
13204 }
13205
13206 void Value::dump(unsigned level) const
13207 {
13208 switch (valuetype) {
13209 case V_ERROR:
13210 case V_NULL:
13211 case V_BOOL:
13212 case V_INT:
13213 case V_NAMEDINT:
13214 case V_NAMEDBITS:
13215 case V_REAL:
13216 case V_ENUM:
13217 case V_BSTR:
13218 case V_HSTR:
13219 case V_OSTR:
13220 case V_CSTR:
13221 case V_ISO2022STR:
13222 case V_OID:
13223 case V_ROID:
13224 case V_CHOICE:
13225 case V_SEQOF:
13226 case V_SETOF:
13227 case V_ARRAY:
13228 case V_SEQ:
13229 case V_SET:
13230 case V_OMIT:
13231 case V_VERDICT:
13232 case V_DEFAULT_NULL:
13233 case V_FAT_NULL:
13234 case V_EXPR:
13235 case V_MACRO:
13236 case V_NOTUSED:
13237 case V_FUNCTION:
13238 case V_ALTSTEP:
13239 case V_TESTCASE:
13240 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13241 break;
13242 case V_REFD:
13243 case V_REFER:
13244 DEBUG(level, "Value: reference");
13245 u.ref.ref->dump(level + 1);
13246 break;
13247 case V_UNDEF_LOWERID:
13248 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13249 break;
13250 case V_UNDEF_BLOCK:
13251 DEBUG(level, "Value: {block}");
13252 break;
13253 case V_TTCN3_NULL:
13254 DEBUG(level, "Value: null");
13255 break;
13256 case V_INVOKE:
13257 DEBUG(level, "Value: invoke");
13258 u.invoke.v->dump(level + 1);
13259 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13260 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13261 break;
13262 default:
13263 DEBUG(level, "Value: unknown type: %d", valuetype);
13264 } // switch
13265 }
13266
13267 void Value::add_string_element(size_t index, Value *v_element,
13268 map<size_t, Value>*& string_elements)
13269 {
13270 v_element->set_my_scope(get_my_scope());
13271 v_element->set_my_governor(get_my_governor());
13272 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13273 v_element->set_location(*this);
13274 if (!string_elements) string_elements = new map<size_t, Value>;
13275 string_elements->add(index, v_element);
13276 }
13277
13278///////////////////////////////////////////////////////////////////////////////
13279// class LazyParamData
13280
13281 int LazyParamData::depth = 0;
13282 bool LazyParamData::used_as_lvalue = false;
13283 vector<string>* LazyParamData::type_vec = NULL;
13284 vector<string>* LazyParamData::refd_vec = NULL;
13285
13286 void LazyParamData::init(bool p_used_as_lvalue) {
13287 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13288 if (depth==0) {
13289 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13290 used_as_lvalue = p_used_as_lvalue;
13291 type_vec = new vector<string>;
13292 refd_vec = new vector<string>;
13293 }
13294 depth++;
13295 }
13296
13297 void LazyParamData::clean() {
13298 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13299 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13300 if (depth==1) {
13301 // type_vec
13302 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13303 type_vec->clear();
13304 delete type_vec;
13305 type_vec = NULL;
13306 // refd_vec
13307 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13308 refd_vec->clear();
13309 delete refd_vec;
13310 refd_vec = NULL;
13311 }
13312 depth--;
13313 }
13314
13315 bool LazyParamData::in_lazy() {
13316 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13317 return depth>0;
13318 }
13319
13320 // returns a temporary id instead of the C++ reference to a definition
13321 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13322 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13323 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13324 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13325 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13326 // store the type of the assignment
13327 string* type_str = new string;
13328 switch (ass->get_asstype()) {
13329 case Assignment::A_MODULEPAR_TEMP:
13330 case Assignment::A_TEMPLATE:
13331 case Assignment::A_VAR_TEMPLATE:
13332 case Assignment::A_PAR_TEMPL_IN:
13333 case Assignment::A_PAR_TEMPL_OUT:
13334 case Assignment::A_PAR_TEMPL_INOUT:
13335 *type_str = ass->get_Type()->get_genname_template(scope);
13336 break;
13337 default:
13338 *type_str = ass->get_Type()->get_genname_value(scope);
13339 }
13340 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13341 bool refd_ass_is_lazy_fpar = false;
13342 switch (ass->get_asstype()) {
13343 case Assignment::A_PAR_VAL:
13344 case Assignment::A_PAR_VAL_IN:
13345 case Assignment::A_PAR_TEMPL_IN:
13346 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13347 if (refd_ass_is_lazy_fpar) {
13348 *type_str = string("Lazy_Param<") + *type_str + string(">");
13349 }
13350 break;
13351 default:
13352 break;
13353 }
13354 // add the "const" part if the referenced assignment is a constant thing
13355 if (!refd_ass_is_lazy_fpar) {
13356 switch (ass->get_asstype()) {
13357 case Assignment::A_CONST:
13358 case Assignment::A_OC:
13359 case Assignment::A_OBJECT:
13360 case Assignment::A_OS:
13361 case Assignment::A_VS:
13362 case Assignment::A_EXT_CONST:
13363 case Assignment::A_MODULEPAR:
13364 case Assignment::A_MODULEPAR_TEMP:
13365 case Assignment::A_TEMPLATE:
13366 case Assignment::A_PAR_VAL:
13367 case Assignment::A_PAR_VAL_IN:
13368 case Assignment::A_PAR_TEMPL_IN:
13369 *type_str = string("const ") + *type_str;
13370 break;
13371 default:
13372 // nothing to do
13373 break;
13374 }
13375 }
13376 //
13377 type_vec->add(type_str);
13378 // store the C++ reference string
13379 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
13380 if (refd_ass_is_lazy_fpar) {
13381 Type* refd_ass_type = ass->get_Type();
13382 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);
13383 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13384 } else {
13385 return get_member_name(refd_vec->size()-1);
13386 }
13387 }
13388
13389 string LazyParamData::get_member_name(size_t idx) {
13390 return string("lpm_") + Int2string(idx);
13391 }
13392
13393 string LazyParamData::get_constr_param_name(size_t idx) {
13394 return string("lpp_") + Int2string(idx);
13395 }
13396
13397 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
13398 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13399 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
13400 const string& tmp_id = val->get_temporary_id();
13401 const char *tmp_id_str = tmp_id.c_str();
13402 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13403 val->get_my_governor()->get_genname_value(my_scope).c_str(),
13404 tmp_id_str);
13405 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13406 tmp_id_str, val);
13407 expr->expr = mputstr(expr->expr, tmp_id_str);
13408 } else {
13409 val->generate_code_expr(expr);
13410 }
13411 }
13412
13413 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
13414 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13415 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
13416 const string& tmp_id = temp->get_Template()->get_temporary_id();
13417 const char *tmp_id_str = tmp_id.c_str();
13418 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13419 temp->get_Template()->get_my_governor()
13420 ->get_genname_template(my_scope).c_str(), tmp_id_str);
13421 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13422 tmp_id_str, temp->get_Template());
13423 // Not incorporated into gen_conv_code() yet.
13424 if (gen_restriction_check != TR_NONE)
13425 expr->preamble = Template::generate_restriction_check_code(
13426 expr->preamble, tmp_id_str, gen_restriction_check);
13427 expr->expr = mputstr(expr->expr, tmp_id_str);
13428 } else temp->generate_code(expr, gen_restriction_check);
13429 }
13430
13431 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
13432 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13433 if (depth>1) {
13434 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13435 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13436 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13437 expression_struct value_expr;
13438 Code::init_expr(&value_expr);
13439 generate_code_for_value(&value_expr, value, scope);
13440 // the id of the instance of Lazy_Param which will be used as the actual parameter
13441 const string& lazy_param_id = value->get_temporary_id();
13442 if (value_expr.preamble) {
13443 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
13444 }
13445 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13446 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13447 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
13448 Code::free_expr(&value_expr);
13449 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13450 return;
13451 }
13452 // only if the formal parameter is *not* used as lvalue
13453 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
13454 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
13455 if (refd_ass) {
13456 bool refd_ass_is_lazy_fpar = false;
13457 switch (refd_ass->get_asstype()) {
13458 case Assignment::A_PAR_VAL:
13459 case Assignment::A_PAR_VAL_IN:
13460 case Assignment::A_PAR_TEMPL_IN:
13461 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13462 break;
13463 default:
13464 break;
13465 }
13466 if (refd_ass_is_lazy_fpar) {
13467 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13468 return;
13469 }
13470 }
13471 }
13472 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13473 expression_struct value_expr;
13474 Code::init_expr(&value_expr);
13475 generate_code_for_value(&value_expr, value, scope);
13476 // the id of the instance of Lazy_Param which will be used as the actual parameter
13477 string lazy_param_id = value->get_temporary_id();
13478 string type_name = value->get_my_governor()->get_genname_value(scope);
13479 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
13480 }
13481
13482 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
13483 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13484 if (depth>1) {
13485 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13486 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13487 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13488 expression_struct tmpl_expr;
13489 Code::init_expr(&tmpl_expr);
13490 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13491 // the id of the instance of Lazy_Param which will be used as the actual parameter
13492 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
13493 if (tmpl_expr.preamble) {
13494 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
13495 }
13496 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13497 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13498 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
13499 Code::free_expr(&tmpl_expr);
13500 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13501 return;
13502 }
13503 // only if the formal parameter is *not* used as lvalue
13504 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
13505 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
13506 if (refd_ass) {
13507 bool refd_ass_is_lazy_fpar = false;
13508 switch (refd_ass->get_asstype()) {
13509 case Assignment::A_PAR_VAL:
13510 case Assignment::A_PAR_VAL_IN:
13511 case Assignment::A_PAR_TEMPL_IN:
13512 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13513 break;
13514 default:
13515 break;
13516 }
13517 if (refd_ass_is_lazy_fpar) {
13518 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13519 return;
13520 }
13521 }
13522 }
13523 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13524 expression_struct tmpl_expr;
13525 Code::init_expr(&tmpl_expr);
13526 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13527 // the id of the instance of Lazy_Param which will be used as the actual parameter
13528 string lazy_param_id = temp->get_Template()->get_temporary_id();
13529 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
13530 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
13531 }
13532
13533 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
13534 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
13535 if (type_vec->size()>0) {
13536 // private members of the local class will be const references to the objects referenced by the expression
13537 for (size_t i=0; i<type_vec->size(); i++) {
13538 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
13539 }
13540 expr->preamble = mputstr(expr->preamble, "public:\n");
13541 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
13542 for (size_t i=0; i<type_vec->size(); i++) {
13543 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13544 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
13545 }
13546 expr->preamble = mputstr(expr->preamble, "): ");
13547 for (size_t i=0; i<type_vec->size(); i++) {
13548 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13549 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
13550 }
13551 expr->preamble = mputstr(expr->preamble, " {}\n");
13552 expr->preamble = mputstr(expr->preamble, "private:\n");
13553 }
13554 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
13555 // use the temporary expr structure to fill the body of the eval_expr() function
13556 if (param_expr.preamble) {
13557 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
13558 }
13559 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
13560 if (param_expr.postamble) {
13561 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
13562 }
13563 Code::free_expr(&param_expr);
13564 expr->preamble = mputstr(expr->preamble, "}\n"
13565 "};\n" // end of local class definition
13566 );
13567 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
13568 if (type_vec->size()>0) {
13569 expr->preamble = mputc(expr->preamble, '(');
13570 // paramteres of the constructor are references to the objects used in the expression
13571 for (size_t i=0; i<refd_vec->size(); i++) {
13572 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13573 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
13574 }
13575 expr->preamble = mputc(expr->preamble, ')');
13576 }
13577 expr->preamble = mputstr(expr->preamble, ";\n");
13578 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13579 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
13580 }
13581
13582 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
13583 expression_struct ref_expr;
13584 Code::init_expr(&ref_expr);
13585 ref->generate_code(&ref_expr);
13586 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
13587 if (ref_expr.preamble) {
13588 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
13589 }
13590 Assignment* ass = ref->get_refd_assignment();
13591 // determine C++ type of the assignment
13592 string type_str;
13593 switch (ass->get_asstype()) {
13594 case Assignment::A_MODULEPAR_TEMP:
13595 case Assignment::A_TEMPLATE:
13596 case Assignment::A_VAR_TEMPLATE:
13597 case Assignment::A_PAR_TEMPL_IN:
13598 case Assignment::A_PAR_TEMPL_OUT:
13599 case Assignment::A_PAR_TEMPL_INOUT:
13600 type_str = ass->get_Type()->get_genname_template(scope);
13601 break;
13602 default:
13603 type_str = ass->get_Type()->get_genname_value(scope);
13604 }
13605 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13606 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
13607 if (ref_expr.postamble) {
13608 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
13609 }
13610 Code::free_expr(&ref_expr);
13611 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13612 }
13613
13614 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
13615 const string& lazy_param_id = value->get_temporary_id();
13616 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13617 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13618 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
13619 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13620 }
13621
13622 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
13623 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
13624 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13625 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13626 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
13627 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13628 }
13629
13630} // namespace Common
This page took 0.534158 seconds and 5 git commands to generate.