Sync with 5.3.0
[deliverable/titan.core.git] / compiler2 / Value.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "../common/dbgnew.hh"
9 #include "Value.hh"
10 #include "Identifier.hh"
11 #include "Valuestuff.hh"
12 #include "PredefFunc.hh"
13 #include "CompField.hh"
14 #include "CompType.hh"
15 #include "EnumItem.hh"
16 #include "TypeCompat.hh"
17 #include "asn1/Block.hh"
18 #include "asn1/TokenBuf.hh"
19 #include "Real.hh"
20 #include "Int.hh"
21 #include "main.hh"
22 #include "Setting.hh"
23 #include "Type.hh"
24 #include "ttcn3/TtcnTemplate.hh"
25 #include "ttcn3/ArrayDimensions.hh"
26 #include "ustring.hh"
27 #include "../common/pattern.hh"
28
29 #include "ttcn3/PatternString.hh"
30 #include "ttcn3/Statement.hh"
31
32 #include "ttcn3/Attributes.hh"
33
34 #include <math.h>
35 #include <regex.h>
36 #include <limits.h>
37
38 namespace Common {
39
40 static void clean_up_string_elements(map<size_t, Value>*& string_elements)
41 {
42 if (string_elements) {
43 for (size_t i = 0; i < string_elements->size(); i++)
44 delete string_elements->get_nth_elem(i);
45 string_elements->clear();
46 delete string_elements;
47 string_elements = 0;
48 }
49 }
50
51 // =================================
52 // ===== Value
53 // =================================
54
55 Value::Value(const Value& p)
56 : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
57 {
58 switch(valuetype) {
59 case V_ERROR:
60 case V_NULL:
61 case V_OMIT:
62 case V_TTCN3_NULL:
63 case V_DEFAULT_NULL:
64 case V_FAT_NULL:
65 case V_NOTUSED:
66 break;
67 case V_BOOL:
68 u.val_bool=p.u.val_bool;
69 break;
70 case V_INT:
71 u.val_Int=new int_val_t(*(p.u.val_Int));
72 break;
73 case V_NAMEDINT:
74 case V_ENUM:
75 case V_UNDEF_LOWERID:
76 u.val_id=p.u.val_id->clone();
77 break;
78 case V_REAL:
79 u.val_Real=p.u.val_Real;
80 break;
81 case V_BSTR:
82 case V_HSTR:
83 case V_OSTR:
84 case V_CSTR:
85 case V_ISO2022STR:
86 set_val_str(new string(*p.u.str.val_str));
87 break;
88 case V_USTR:
89 set_val_ustr(new ustring(*p.u.ustr.val_ustr));
90 u.ustr.convert_str = p.u.ustr.convert_str;
91 break;
92 case V_CHARSYMS:
93 u.char_syms = p.u.char_syms->clone();
94 break;
95 case V_OID:
96 case V_ROID:
97 u.oid_comps=new vector<OID_comp>;
98 for(size_t i=0; i<p.u.oid_comps->size(); i++)
99 add_oid_comp((*p.u.oid_comps)[i]->clone());
100 break;
101 case V_CHOICE:
102 u.choice.alt_name=p.u.choice.alt_name->clone();
103 u.choice.alt_value=p.u.choice.alt_value->clone();
104 break;
105 case V_SEQOF:
106 case V_SETOF:
107 case V_ARRAY:
108 u.val_vs=p.u.val_vs->clone();
109 break;
110 case V_SEQ:
111 case V_SET:
112 u.val_nvs=p.u.val_nvs->clone();
113 break;
114 case V_REFD:
115 u.ref.ref=p.u.ref.ref->clone();
116 u.ref.refd_last=0;
117 break;
118 case V_NAMEDBITS:
119 for(size_t i=0; i<p.u.ids->size(); i++) {
120 Identifier *id = p.u.ids->get_nth_elem(i);
121 u.ids->add(id->get_name(), id->clone());
122 }
123 break;
124 case V_UNDEF_BLOCK:
125 u.block=p.u.block->clone();
126 break;
127 case V_VERDICT:
128 u.verdict=p.u.verdict;
129 break;
130 case V_EXPR:
131 u.expr.v_optype = p.u.expr.v_optype;
132 u.expr.state = EXPR_NOT_CHECKED;
133 switch(u.expr.v_optype) {
134 case OPTYPE_RND: // -
135 case OPTYPE_COMP_NULL:
136 case OPTYPE_COMP_MTC:
137 case OPTYPE_COMP_SYSTEM:
138 case OPTYPE_COMP_SELF:
139 case OPTYPE_COMP_RUNNING_ANY:
140 case OPTYPE_COMP_RUNNING_ALL:
141 case OPTYPE_COMP_ALIVE_ANY:
142 case OPTYPE_COMP_ALIVE_ALL:
143 case OPTYPE_TMR_RUNNING_ANY:
144 case OPTYPE_GETVERDICT:
145 case OPTYPE_TESTCASENAME:
146 case OPTYPE_PROF_RUNNING:
147 break;
148 case OPTYPE_UNARYPLUS: // v1
149 case OPTYPE_UNARYMINUS:
150 case OPTYPE_NOT:
151 case OPTYPE_NOT4B:
152 case OPTYPE_BIT2HEX:
153 case OPTYPE_BIT2INT:
154 case OPTYPE_BIT2OCT:
155 case OPTYPE_BIT2STR:
156 case OPTYPE_CHAR2INT:
157 case OPTYPE_CHAR2OCT:
158 case OPTYPE_COMP_RUNNING:
159 case OPTYPE_COMP_ALIVE:
160 case OPTYPE_FLOAT2INT:
161 case OPTYPE_FLOAT2STR:
162 case OPTYPE_HEX2BIT:
163 case OPTYPE_HEX2INT:
164 case OPTYPE_HEX2OCT:
165 case OPTYPE_HEX2STR:
166 case OPTYPE_INT2CHAR:
167 case OPTYPE_INT2FLOAT:
168 case OPTYPE_INT2STR:
169 case OPTYPE_INT2UNICHAR:
170 case OPTYPE_OCT2BIT:
171 case OPTYPE_OCT2CHAR:
172 case OPTYPE_OCT2HEX:
173 case OPTYPE_OCT2INT:
174 case OPTYPE_OCT2STR:
175 case OPTYPE_STR2BIT:
176 case OPTYPE_STR2FLOAT:
177 case OPTYPE_STR2HEX:
178 case OPTYPE_STR2INT:
179 case OPTYPE_STR2OCT:
180 case OPTYPE_UNICHAR2INT:
181 case OPTYPE_UNICHAR2CHAR:
182 case OPTYPE_ENUM2INT:
183 case OPTYPE_RNDWITHVAL:
184 case OPTYPE_GET_STRINGENCODING:
185 case OPTYPE_DECODE_BASE64:
186 case OPTYPE_REMOVE_BOM:
187 u.expr.v1=p.u.expr.v1->clone();
188 break;
189 case OPTYPE_ADD: // v1 v2
190 case OPTYPE_SUBTRACT:
191 case OPTYPE_MULTIPLY:
192 case OPTYPE_DIVIDE:
193 case OPTYPE_MOD:
194 case OPTYPE_REM:
195 case OPTYPE_CONCAT:
196 case OPTYPE_EQ:
197 case OPTYPE_LT:
198 case OPTYPE_GT:
199 case OPTYPE_NE:
200 case OPTYPE_GE:
201 case OPTYPE_LE:
202 case OPTYPE_AND:
203 case OPTYPE_OR:
204 case OPTYPE_XOR:
205 case OPTYPE_AND4B:
206 case OPTYPE_OR4B:
207 case OPTYPE_XOR4B:
208 case OPTYPE_SHL:
209 case OPTYPE_SHR:
210 case OPTYPE_ROTL:
211 case OPTYPE_ROTR:
212 case OPTYPE_INT2BIT:
213 case OPTYPE_INT2HEX:
214 case OPTYPE_INT2OCT:
215 u.expr.v1=p.u.expr.v1->clone();
216 u.expr.v2=p.u.expr.v2->clone();
217 break;
218 case OPTYPE_UNICHAR2OCT: // v1 [v2]
219 case OPTYPE_OCT2UNICHAR:
220 case OPTYPE_ENCODE_BASE64:
221 u.expr.v1=p.u.expr.v1->clone();
222 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
223 break;
224 case OPTYPE_DECODE:
225 u.expr.r1=p.u.expr.r1->clone();
226 u.expr.r2=p.u.expr.r2->clone();
227 break;
228 case OPTYPE_SUBSTR:
229 u.expr.ti1=p.u.expr.ti1->clone();
230 u.expr.v2=p.u.expr.v2->clone();
231 u.expr.v3=p.u.expr.v3->clone();
232 break;
233 case OPTYPE_REGEXP:
234 u.expr.ti1=p.u.expr.ti1->clone();
235 u.expr.t2=p.u.expr.t2->clone();
236 u.expr.v3=p.u.expr.v3->clone();
237 break;
238 case OPTYPE_DECOMP: // v1 v2 v3
239 u.expr.v1=p.u.expr.v1->clone();
240 u.expr.v2=p.u.expr.v2->clone();
241 u.expr.v3=p.u.expr.v3->clone();
242 break;
243 case OPTYPE_REPLACE:
244 u.expr.ti1 = p.u.expr.ti1->clone();
245 u.expr.v2 = p.u.expr.v2->clone();
246 u.expr.v3 = p.u.expr.v3->clone();
247 u.expr.ti4 = p.u.expr.ti4->clone();
248 break;
249 case OPTYPE_LENGTHOF: // ti1
250 case OPTYPE_SIZEOF: // ti1
251 case OPTYPE_VALUEOF: // ti1
252 case OPTYPE_ENCODE:
253 case OPTYPE_ISPRESENT:
254 case OPTYPE_TTCN2STRING:
255 u.expr.ti1=p.u.expr.ti1->clone();
256 break;
257 case OPTYPE_UNDEF_RUNNING:
258 case OPTYPE_TMR_READ:
259 case OPTYPE_TMR_RUNNING:
260 case OPTYPE_ACTIVATE:
261 u.expr.r1=p.u.expr.r1->clone();
262 break;
263 case OPTYPE_EXECUTE: // r1 [v2]
264 u.expr.r1=p.u.expr.r1->clone();
265 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
266 break;
267 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
268 u.expr.r1=p.u.expr.r1->clone();
269 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
270 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
271 u.expr.b4 = p.u.expr.b4;
272 break;
273 case OPTYPE_MATCH: // v1 t2
274 u.expr.v1=p.u.expr.v1->clone();
275 u.expr.t2=p.u.expr.t2->clone();
276 break;
277 case OPTYPE_ISCHOSEN: // r1 i2
278 u.expr.r1=p.u.expr.r1->clone();
279 u.expr.i2=p.u.expr.i2->clone();
280 break;
281 case OPTYPE_ISCHOSEN_V: // v1 i2
282 u.expr.v1=p.u.expr.v1->clone();
283 u.expr.i2=p.u.expr.i2->clone();
284 break;
285 case OPTYPE_ISCHOSEN_T: // t1 i2
286 u.expr.t1=p.u.expr.t1->clone();
287 u.expr.i2=p.u.expr.i2->clone();
288 break;
289 case OPTYPE_ACTIVATE_REFD:
290 u.expr.v1 = p.u.expr.v1->clone();
291 if(p.u.expr.state!=EXPR_CHECKED)
292 u.expr.t_list2 = p.u.expr.t_list2->clone();
293 else {
294 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
295 u.expr.state = EXPR_CHECKED;
296 }
297 break;
298 case OPTYPE_EXECUTE_REFD:
299 u.expr.v1 = p.u.expr.v1->clone();
300 if(p.u.expr.state!=EXPR_CHECKED)
301 u.expr.t_list2 = p.u.expr.t_list2->clone();
302 else {
303 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
304 u.expr.state = EXPR_CHECKED;
305 }
306 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
307 break;
308 case OPTYPE_LOG2STR:
309 u.expr.logargs = p.u.expr.logargs->clone();
310 break;
311 default:
312 FATAL_ERROR("Value::Value()");
313 } // switch
314 break;
315 case V_MACRO:
316 u.macro = p.u.macro;
317 break;
318 case V_FUNCTION:
319 case V_ALTSTEP:
320 case V_TESTCASE:
321 u.refd_fat = p.u.refd_fat;
322 break;
323 case V_INVOKE:
324 u.invoke.v = p.u.invoke.v->clone();
325 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
326 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
327 break;
328 case V_REFER:
329 u.refered = p.u.refered->clone();
330 break;
331 default:
332 FATAL_ERROR("Value::Value()");
333 } // switch
334 }
335
336 void Value::clean_up()
337 {
338 switch (valuetype) {
339 case V_ERROR:
340 case V_NULL:
341 case V_BOOL:
342 case V_REAL:
343 case V_OMIT:
344 case V_VERDICT:
345 case V_TTCN3_NULL:
346 case V_DEFAULT_NULL:
347 case V_FAT_NULL:
348 case V_MACRO:
349 case V_NOTUSED:
350 case V_FUNCTION:
351 case V_ALTSTEP:
352 case V_TESTCASE:
353 break;
354 case V_INT:
355 delete u.val_Int;
356 break;
357 case V_NAMEDINT:
358 case V_ENUM:
359 case V_UNDEF_LOWERID:
360 delete u.val_id;
361 break;
362 case V_BSTR:
363 case V_HSTR:
364 case V_OSTR:
365 case V_CSTR:
366 case V_ISO2022STR:
367 delete u.str.val_str;
368 clean_up_string_elements(u.str.str_elements);
369 break;
370 case V_USTR:
371 delete u.ustr.val_ustr;
372 clean_up_string_elements(u.ustr.ustr_elements);
373 break;
374 case V_CHARSYMS:
375 delete u.char_syms;
376 break;
377 case V_OID:
378 case V_ROID:
379 if (u.oid_comps) {
380 for(size_t i=0; i<u.oid_comps->size(); i++)
381 delete (*u.oid_comps)[i];
382 u.oid_comps->clear();
383 delete u.oid_comps;
384 }
385 break;
386 case V_EXPR:
387 clean_up_expr();
388 break;
389 case V_CHOICE:
390 delete u.choice.alt_name;
391 delete u.choice.alt_value;
392 break;
393 case V_SEQOF:
394 case V_SETOF:
395 case V_ARRAY:
396 delete u.val_vs;
397 break;
398 case V_SEQ:
399 case V_SET:
400 delete u.val_nvs;
401 break;
402 case V_REFD:
403 delete u.ref.ref;
404 break;
405 case V_REFER:
406 delete u.refered;
407 break;
408 case V_INVOKE:
409 delete u.invoke.v;
410 delete u.invoke.t_list;
411 delete u.invoke.ap_list;
412 break;
413 case V_NAMEDBITS:
414 if(u.ids) {
415 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
416 u.ids->clear();
417 delete u.ids;
418 }
419 break;
420 case V_UNDEF_BLOCK:
421 delete u.block;
422 break;
423 default:
424 FATAL_ERROR("Value::clean_up()");
425 } // switch
426 }
427
428 void Value::clean_up_expr()
429 {
430 switch (u.expr.state) {
431 case EXPR_CHECKING:
432 case EXPR_CHECKING_ERR:
433 FATAL_ERROR("Value::clean_up_expr()");
434 default:
435 break;
436 }
437 switch (u.expr.v_optype) {
438 case OPTYPE_RND: // -
439 case OPTYPE_COMP_NULL:
440 case OPTYPE_COMP_MTC:
441 case OPTYPE_COMP_SYSTEM:
442 case OPTYPE_COMP_SELF:
443 case OPTYPE_COMP_RUNNING_ANY:
444 case OPTYPE_COMP_RUNNING_ALL:
445 case OPTYPE_COMP_ALIVE_ANY:
446 case OPTYPE_COMP_ALIVE_ALL:
447 case OPTYPE_TMR_RUNNING_ANY:
448 case OPTYPE_GETVERDICT:
449 case OPTYPE_TESTCASENAME:
450 case OPTYPE_PROF_RUNNING:
451 break;
452 case OPTYPE_UNARYPLUS: // v1
453 case OPTYPE_UNARYMINUS:
454 case OPTYPE_NOT:
455 case OPTYPE_NOT4B:
456 case OPTYPE_BIT2HEX:
457 case OPTYPE_BIT2INT:
458 case OPTYPE_BIT2OCT:
459 case OPTYPE_BIT2STR:
460 case OPTYPE_CHAR2INT:
461 case OPTYPE_CHAR2OCT:
462 case OPTYPE_COMP_RUNNING:
463 case OPTYPE_COMP_ALIVE:
464 case OPTYPE_FLOAT2INT:
465 case OPTYPE_FLOAT2STR:
466 case OPTYPE_HEX2BIT:
467 case OPTYPE_HEX2INT:
468 case OPTYPE_HEX2OCT:
469 case OPTYPE_HEX2STR:
470 case OPTYPE_INT2CHAR:
471 case OPTYPE_INT2FLOAT:
472 case OPTYPE_INT2STR:
473 case OPTYPE_INT2UNICHAR:
474 case OPTYPE_OCT2BIT:
475 case OPTYPE_OCT2CHAR:
476 case OPTYPE_OCT2HEX:
477 case OPTYPE_OCT2INT:
478 case OPTYPE_OCT2STR:
479 case OPTYPE_STR2BIT:
480 case OPTYPE_STR2FLOAT:
481 case OPTYPE_STR2HEX:
482 case OPTYPE_STR2INT:
483 case OPTYPE_STR2OCT:
484 case OPTYPE_UNICHAR2INT:
485 case OPTYPE_UNICHAR2CHAR:
486 case OPTYPE_ENUM2INT:
487 case OPTYPE_RNDWITHVAL:
488 case OPTYPE_REMOVE_BOM:
489 case OPTYPE_GET_STRINGENCODING:
490 case OPTYPE_DECODE_BASE64:
491 delete u.expr.v1;
492 break;
493 case OPTYPE_ADD: // v1 v2
494 case OPTYPE_SUBTRACT:
495 case OPTYPE_MULTIPLY:
496 case OPTYPE_DIVIDE:
497 case OPTYPE_MOD:
498 case OPTYPE_REM:
499 case OPTYPE_CONCAT:
500 case OPTYPE_EQ:
501 case OPTYPE_LT:
502 case OPTYPE_GT:
503 case OPTYPE_NE:
504 case OPTYPE_GE:
505 case OPTYPE_LE:
506 case OPTYPE_AND:
507 case OPTYPE_OR:
508 case OPTYPE_XOR:
509 case OPTYPE_AND4B:
510 case OPTYPE_OR4B:
511 case OPTYPE_XOR4B:
512 case OPTYPE_SHL:
513 case OPTYPE_SHR:
514 case OPTYPE_ROTL:
515 case OPTYPE_ROTR:
516 case OPTYPE_INT2BIT:
517 case OPTYPE_INT2HEX:
518 case OPTYPE_INT2OCT:
519 case OPTYPE_UNICHAR2OCT:
520 case OPTYPE_OCT2UNICHAR:
521 case OPTYPE_ENCODE_BASE64:
522 delete u.expr.v1;
523 delete u.expr.v2;
524 break;
525 case OPTYPE_DECODE:
526 delete u.expr.r1;
527 delete u.expr.r2;
528 break;
529 case OPTYPE_SUBSTR:
530 delete u.expr.ti1;
531 delete u.expr.v2;
532 delete u.expr.v3;
533 break;
534 case OPTYPE_REGEXP:
535 delete u.expr.ti1;
536 delete u.expr.t2;
537 delete u.expr.v3;
538 break;
539 case OPTYPE_DECOMP: // v1 v2 v3
540 delete u.expr.v1;
541 delete u.expr.v2;
542 delete u.expr.v3;
543 break;
544 case OPTYPE_REPLACE:
545 delete u.expr.ti1;
546 delete u.expr.v2;
547 delete u.expr.v3;
548 delete u.expr.ti4;
549 break;
550 case OPTYPE_LENGTHOF: // ti1
551 case OPTYPE_SIZEOF: // ti1
552 case OPTYPE_VALUEOF: // ti1
553 case OPTYPE_ISVALUE:
554 case OPTYPE_ISBOUND:
555 case OPTYPE_ENCODE:
556 case OPTYPE_ISPRESENT:
557 case OPTYPE_TTCN2STRING:
558 delete u.expr.ti1;
559 break;
560 case OPTYPE_UNDEF_RUNNING:
561 case OPTYPE_TMR_READ:
562 case OPTYPE_TMR_RUNNING:
563 case OPTYPE_ACTIVATE:
564 delete u.expr.r1;
565 break;
566 case OPTYPE_EXECUTE: // r1 [v2]
567 delete u.expr.r1;
568 delete u.expr.v2;
569 break;
570 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
571 delete u.expr.r1;
572 delete u.expr.v2;
573 delete u.expr.v3;
574 break;
575 case OPTYPE_MATCH: // v1 t2
576 delete u.expr.v1;
577 delete u.expr.t2;
578 break;
579 case OPTYPE_ISCHOSEN: // r1 i2
580 delete u.expr.r1;
581 delete u.expr.i2;
582 break;
583 case OPTYPE_ISCHOSEN_V: // v1 i2
584 delete u.expr.v1;
585 delete u.expr.i2;
586 break;
587 case OPTYPE_ISCHOSEN_T: // t1 i2
588 delete u.expr.t1;
589 delete u.expr.i2;
590 break;
591 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
592 delete u.expr.v1;
593 if(u.expr.state!=EXPR_CHECKED)
594 delete u.expr.t_list2;
595 else
596 delete u.expr.ap_list2;
597 break;
598 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
599 delete u.expr.v1;
600 if(u.expr.state!=EXPR_CHECKED)
601 delete u.expr.t_list2;
602 else
603 delete u.expr.ap_list2;
604 delete u.expr.v3;
605 break;
606 case OPTYPE_LOG2STR:
607 delete u.expr.logargs;
608 break;
609 default:
610 FATAL_ERROR("Value::clean_up_expr()");
611 } // switch
612 }
613
614 void Value::copy_and_destroy(Value *src)
615 {
616 clean_up();
617 valuetype = src->valuetype;
618 u = src->u;
619 // update the pointer used for caching if it points to the value itself
620 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
621 src->valuetype = V_ERROR;
622 delete src;
623 }
624
625 Value::Value(valuetype_t p_vt)
626 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
627 {
628 switch(valuetype) {
629 case V_NULL:
630 case V_TTCN3_NULL:
631 case V_OMIT:
632 case V_NOTUSED:
633 case V_ERROR:
634 break;
635 case V_OID:
636 case V_ROID:
637 u.oid_comps=new vector<OID_comp>();
638 break;
639 case V_NAMEDBITS:
640 u.ids=new map<string, Identifier>();
641 break;
642 default:
643 FATAL_ERROR("Value::Value()");
644 } // switch
645 }
646
647 Value::Value(valuetype_t p_vt, bool p_val_bool)
648 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
649 {
650 switch(valuetype) {
651 case V_BOOL:
652 u.val_bool=p_val_bool;
653 break;
654 default:
655 FATAL_ERROR("Value::Value()");
656 } // switch
657 }
658
659 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
660 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
661 {
662 switch(valuetype) {
663 case V_INT:
664 u.val_Int=new int_val_t(p_val_Int);
665 break;
666 default:
667 FATAL_ERROR("Value::Value()");
668 } // switch
669 }
670
671 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
672 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
673 {
674 switch(valuetype){
675 case V_INT:
676 u.val_Int=p_val_Int;
677 break;
678 default:
679 FATAL_ERROR("Value::Value()");
680 }
681 }
682
683 Value::Value(valuetype_t p_vt, string *p_val_str)
684 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
685 {
686 if(!p_val_str) FATAL_ERROR("NULL parameter");
687 switch(valuetype) {
688 case V_BSTR:
689 case V_HSTR:
690 case V_OSTR:
691 case V_CSTR:
692 case V_ISO2022STR:
693 set_val_str(p_val_str);
694 break;
695 default:
696 FATAL_ERROR("Value::Value()");
697 } // switch
698 }
699
700 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
701 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
702 {
703 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
704 set_val_ustr(p_val_ustr);
705 u.ustr.convert_str = false;
706 }
707
708 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
709 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
710 {
711 if (!p_char_syms) FATAL_ERROR("NULL parameter");
712 switch (valuetype) {
713 case V_CHARSYMS:
714 u.char_syms = p_char_syms;
715 break;
716 default:
717 FATAL_ERROR("Value::Value()");
718 } // switch
719 }
720
721 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
722 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
723 {
724 if(!p_val_id)
725 FATAL_ERROR("NULL parameter");
726 switch(valuetype) {
727 case V_NAMEDINT:
728 case V_ENUM:
729 case V_UNDEF_LOWERID:
730 u.val_id=p_val_id;
731 break;
732 default:
733 FATAL_ERROR("Value::Value()");
734 } // switch
735 }
736
737 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
738 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
739 {
740 if(!p_id || !p_val)
741 FATAL_ERROR("NULL parameter");
742 switch(valuetype) {
743 case V_CHOICE:
744 u.choice.alt_name=p_id;
745 u.choice.alt_value=p_val;
746 break;
747 default:
748 FATAL_ERROR("Value::Value()");
749 } // switch
750 }
751
752 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
753 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
754 {
755 switch(valuetype) {
756 case V_REAL:
757 u.val_Real=p_val_Real;
758 break;
759 default:
760 FATAL_ERROR("Value::Value()");
761 } // switch
762 }
763
764 Value::Value(valuetype_t p_vt, Values *p_vs)
765 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
766 {
767 if(!p_vs) FATAL_ERROR("NULL parameter");
768 switch(valuetype) {
769 case V_SEQOF:
770 case V_SETOF:
771 case V_ARRAY:
772 u.val_vs=p_vs;
773 break;
774 default:
775 FATAL_ERROR("Value::Value()");
776 } // switch
777 }
778
779 Value::Value(valuetype_t p_vt, Value *p_v,
780 Ttcn::ParsedActualParameters *p_t_list)
781 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
782 {
783 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
784 switch(valuetype) {
785 case V_INVOKE:
786 u.invoke.v = p_v;
787 u.invoke.t_list = p_t_list;
788 u.invoke.ap_list = 0;
789 break;
790 default:
791 FATAL_ERROR("Value::Value()");
792 }
793 }
794
795 // -
796 Value::Value(operationtype_t p_optype)
797 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
798 {
799 u.expr.v_optype = p_optype;
800 u.expr.state = EXPR_NOT_CHECKED;
801 switch(p_optype) {
802 case OPTYPE_RND:
803 case OPTYPE_COMP_NULL:
804 case OPTYPE_COMP_MTC:
805 case OPTYPE_COMP_SYSTEM:
806 case OPTYPE_COMP_SELF:
807 case OPTYPE_COMP_RUNNING_ANY:
808 case OPTYPE_COMP_RUNNING_ALL:
809 case OPTYPE_COMP_ALIVE_ANY:
810 case OPTYPE_COMP_ALIVE_ALL:
811 case OPTYPE_TMR_RUNNING_ANY:
812 case OPTYPE_GETVERDICT:
813 case OPTYPE_TESTCASENAME:
814 case OPTYPE_PROF_RUNNING:
815 break;
816 default:
817 FATAL_ERROR("Value::Value()");
818 } // switch
819 }
820
821 // v1
822 Value::Value(operationtype_t p_optype, Value *p_v1)
823 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
824 {
825 u.expr.v_optype = p_optype;
826 u.expr.state = EXPR_NOT_CHECKED;
827 switch(p_optype) {
828 case OPTYPE_UNARYPLUS:
829 case OPTYPE_UNARYMINUS:
830 case OPTYPE_NOT:
831 case OPTYPE_NOT4B:
832 case OPTYPE_BIT2HEX:
833 case OPTYPE_BIT2INT:
834 case OPTYPE_BIT2OCT:
835 case OPTYPE_BIT2STR:
836 case OPTYPE_CHAR2INT:
837 case OPTYPE_CHAR2OCT:
838 case OPTYPE_COMP_RUNNING:
839 case OPTYPE_COMP_ALIVE:
840 case OPTYPE_FLOAT2INT:
841 case OPTYPE_FLOAT2STR:
842 case OPTYPE_HEX2BIT:
843 case OPTYPE_HEX2INT:
844 case OPTYPE_HEX2OCT:
845 case OPTYPE_HEX2STR:
846 case OPTYPE_INT2CHAR:
847 case OPTYPE_INT2FLOAT:
848 case OPTYPE_INT2STR:
849 case OPTYPE_INT2UNICHAR:
850 case OPTYPE_OCT2BIT:
851 case OPTYPE_OCT2CHAR:
852 case OPTYPE_OCT2HEX:
853 case OPTYPE_OCT2INT:
854 case OPTYPE_OCT2STR:
855 case OPTYPE_STR2BIT:
856 case OPTYPE_STR2FLOAT:
857 case OPTYPE_STR2HEX:
858 case OPTYPE_STR2INT:
859 case OPTYPE_STR2OCT:
860 case OPTYPE_UNICHAR2INT:
861 case OPTYPE_UNICHAR2CHAR:
862 case OPTYPE_ENUM2INT:
863 case OPTYPE_RNDWITHVAL:
864 case OPTYPE_REMOVE_BOM:
865 case OPTYPE_GET_STRINGENCODING:
866 case OPTYPE_DECODE_BASE64:
867 if(!p_v1) FATAL_ERROR("Value::Value()");
868 u.expr.v1=p_v1;
869 break;
870 default:
871 FATAL_ERROR("Value::Value()");
872 } // switch
873 }
874
875 // ti1
876 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
877 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
878 {
879 u.expr.v_optype = p_optype;
880 u.expr.state = EXPR_NOT_CHECKED;
881 switch(p_optype) {
882 case OPTYPE_LENGTHOF:
883 case OPTYPE_SIZEOF:
884 case OPTYPE_VALUEOF:
885 case OPTYPE_ISVALUE:
886 case OPTYPE_ISBOUND:
887 case OPTYPE_ENCODE:
888 case OPTYPE_ISPRESENT:
889 case OPTYPE_TTCN2STRING:
890 if(!p_ti1) FATAL_ERROR("Value::Value()");
891 u.expr.ti1=p_ti1;
892 break;
893 default:
894 FATAL_ERROR("Value::Value()");
895 } // switch
896 }
897
898 // r1
899 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
900 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
901 {
902 u.expr.v_optype = p_optype;
903 u.expr.state = EXPR_NOT_CHECKED;
904 switch(p_optype) {
905 case OPTYPE_UNDEF_RUNNING:
906 case OPTYPE_TMR_READ:
907 case OPTYPE_TMR_RUNNING:
908 case OPTYPE_ACTIVATE:
909 if(!p_r1) FATAL_ERROR("Value::Value()");
910 u.expr.r1=p_r1;
911 break;
912 default:
913 FATAL_ERROR("Value::Value()");
914 } // switch
915 }
916
917 // v1 t_list2
918 Value::Value(operationtype_t p_optype, Value *p_v1,
919 Ttcn::ParsedActualParameters *p_ap_list)
920 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
921 {
922 u.expr.v_optype = p_optype;
923 u.expr.state = EXPR_NOT_CHECKED;
924 switch(p_optype) {
925 case OPTYPE_ACTIVATE_REFD:
926 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
927 u.expr.v1 = p_v1;
928 u.expr.t_list2 = p_ap_list;
929 break;
930 default:
931 FATAL_ERROR("Value::Value()");
932 }
933 }
934
935 //v1 t_list2 v3
936 Value::Value(operationtype_t p_optype, Value *p_v1,
937 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
938 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
939 {
940 u.expr.v_optype = p_optype;
941 u.expr.state = EXPR_NOT_CHECKED;
942 switch(p_optype) {
943 case OPTYPE_EXECUTE_REFD:
944 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
945 u.expr.v1 = p_v1;
946 u.expr.t_list2 = p_t_list2;
947 u.expr.v3 = p_v3;
948 break;
949 default:
950 FATAL_ERROR("Value::Value()");
951 }
952 }
953
954 // r1 [v2]
955 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
956 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
957 {
958 u.expr.v_optype = p_optype;
959 u.expr.state = EXPR_NOT_CHECKED;
960 switch(p_optype) {
961 case OPTYPE_EXECUTE:
962 if(!p_r1) FATAL_ERROR("Value::Value()");
963 u.expr.r1=p_r1;
964 u.expr.v2=p_v2;
965 break;
966 default:
967 FATAL_ERROR("Value::Value()");
968 } // switch
969 }
970
971 // r1 [v2] [v3] b4
972 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
973 Value *p_v2, Value *p_v3, bool p_b4)
974 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
975 {
976 u.expr.v_optype = p_optype;
977 u.expr.state = EXPR_NOT_CHECKED;
978 switch(p_optype) {
979 case OPTYPE_COMP_CREATE:
980 if(!p_r1) FATAL_ERROR("Value::Value()");
981 u.expr.r1=p_r1;
982 u.expr.v2=p_v2;
983 u.expr.v3=p_v3;
984 u.expr.b4=p_b4;
985 break;
986 default:
987 FATAL_ERROR("Value::Value()");
988 } // switch
989 }
990
991 // v1 v2
992 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
993 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
994 {
995 u.expr.v_optype = p_optype;
996 u.expr.state = EXPR_NOT_CHECKED;
997 switch(p_optype) {
998 case OPTYPE_ADD:
999 case OPTYPE_SUBTRACT:
1000 case OPTYPE_MULTIPLY:
1001 case OPTYPE_DIVIDE:
1002 case OPTYPE_MOD:
1003 case OPTYPE_REM:
1004 case OPTYPE_CONCAT:
1005 case OPTYPE_EQ:
1006 case OPTYPE_LT:
1007 case OPTYPE_GT:
1008 case OPTYPE_NE:
1009 case OPTYPE_GE:
1010 case OPTYPE_LE:
1011 case OPTYPE_AND:
1012 case OPTYPE_OR:
1013 case OPTYPE_XOR:
1014 case OPTYPE_AND4B:
1015 case OPTYPE_OR4B:
1016 case OPTYPE_XOR4B:
1017 case OPTYPE_SHL:
1018 case OPTYPE_SHR:
1019 case OPTYPE_ROTL:
1020 case OPTYPE_ROTR:
1021 case OPTYPE_INT2BIT:
1022 case OPTYPE_INT2HEX:
1023 case OPTYPE_INT2OCT:
1024 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1025 u.expr.v1=p_v1;
1026 u.expr.v2=p_v2;
1027 break;
1028 case OPTYPE_UNICHAR2OCT:
1029 case OPTYPE_OCT2UNICHAR:
1030 case OPTYPE_ENCODE_BASE64:
1031 if(!p_v1) FATAL_ERROR("Value::Value()");
1032 u.expr.v1=p_v1;
1033 // p_v2 may be NULL if there is no second param
1034 u.expr.v2=p_v2;
1035 break;
1036 default:
1037 FATAL_ERROR("Value::Value()");
1038 } // switch
1039 }
1040
1041 // ti1 v2 v3 ti4
1042 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1043 Value *p_v3, TemplateInstance *p_ti4) :
1044 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1045 {
1046 u.expr.v_optype = p_optype;
1047 u.expr.state = EXPR_NOT_CHECKED;
1048 switch (p_optype) {
1049 case OPTYPE_REPLACE:
1050 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1051 u.expr.ti1 = p_ti1;
1052 u.expr.v2 = p_v2;
1053 u.expr.v3 = p_v3;
1054 u.expr.ti4 = p_ti4;
1055 break;
1056 default:
1057 FATAL_ERROR("Value::Value()");
1058 } // switch
1059 }
1060
1061 // v1 v2 v3
1062 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1063 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1064 {
1065 u.expr.v_optype = p_optype;
1066 u.expr.state = EXPR_NOT_CHECKED;
1067 switch(p_optype) {
1068 case OPTYPE_DECOMP:
1069 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1070 u.expr.v1=p_v1;
1071 u.expr.v2=p_v2;
1072 u.expr.v3=p_v3;
1073 break;
1074 default:
1075 FATAL_ERROR("Value::Value()");
1076 } // switch
1077 }
1078
1079 // ti1 v2 v3
1080 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1081 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1082 {
1083 u.expr.v_optype=p_optype;
1084 u.expr.state=EXPR_NOT_CHECKED;
1085 switch(p_optype) {
1086 case OPTYPE_SUBSTR:
1087 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1088 u.expr.ti1 = p_ti1;
1089 u.expr.v2=p_v2;
1090 u.expr.v3=p_v3;
1091 break;
1092 default:
1093 FATAL_ERROR("Value::Value()");
1094 } // switch
1095 }
1096
1097 // ti1 t2 v3
1098 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1099 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1100 {
1101 u.expr.v_optype=p_optype;
1102 u.expr.state=EXPR_NOT_CHECKED;
1103 switch(p_optype) {
1104 case OPTYPE_REGEXP:
1105 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1106 u.expr.ti1 = p_ti1;
1107 u.expr.t2 = p_t2;
1108 u.expr.v3=p_v3;
1109 break;
1110 default:
1111 FATAL_ERROR("Value::Value()");
1112 } // switch
1113 }
1114
1115 // v1 t2
1116 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1117 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1118 {
1119 u.expr.v_optype = p_optype;
1120 u.expr.state = EXPR_NOT_CHECKED;
1121 switch(p_optype) {
1122 case OPTYPE_MATCH:
1123 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1124 u.expr.v1=p_v1;
1125 u.expr.t2=p_t2;
1126 break;
1127 default:
1128 FATAL_ERROR("Value::Value()");
1129 } // switch
1130 }
1131
1132 // r1 i2
1133 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1134 Identifier *p_i2)
1135 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1136 {
1137 u.expr.v_optype = p_optype;
1138 u.expr.state = EXPR_NOT_CHECKED;
1139 switch(p_optype) {
1140 case OPTYPE_ISCHOSEN:
1141 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1142 u.expr.r1=p_r1;
1143 u.expr.i2=p_i2;
1144 break;
1145 default:
1146 FATAL_ERROR("Value::Value()");
1147 } // switch
1148 }
1149
1150 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1151 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1152 {
1153 u.expr.v_optype = p_optype;
1154 u.expr.state = EXPR_NOT_CHECKED;
1155 switch(p_optype) {
1156 case OPTYPE_LOG2STR:
1157 if (!p_logargs) FATAL_ERROR("Value::Value()");
1158 u.expr.logargs = p_logargs;
1159 break;
1160 default:
1161 FATAL_ERROR("Value::Value()");
1162 } // switch
1163 }
1164
1165 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1166 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1167 {
1168 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1169 switch (p_macrotype) {
1170 case MACRO_MODULEID:
1171 case MACRO_FILENAME:
1172 case MACRO_BFILENAME:
1173 case MACRO_FILEPATH:
1174 case MACRO_LINENUMBER:
1175 case MACRO_LINENUMBER_C:
1176 case MACRO_DEFINITIONID:
1177 case MACRO_SCOPE:
1178 case MACRO_TESTCASEID:
1179 break;
1180 default:
1181 FATAL_ERROR("Value::Value()");
1182 }
1183 u.macro = p_macrotype;
1184 }
1185
1186 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1187 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1188 {
1189 if(!p_nvs) FATAL_ERROR("NULL parameter");
1190 switch(valuetype) {
1191 case V_SEQ:
1192 case V_SET:
1193 u.val_nvs=p_nvs;
1194 break;
1195 default:
1196 FATAL_ERROR("Value::Value()");
1197 } // switch
1198 }
1199
1200 Value::Value(valuetype_t p_vt, Reference *p_ref)
1201 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1202 {
1203 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1204 switch(p_vt) {
1205 case V_REFD:
1206 u.ref.ref = p_ref;
1207 u.ref.refd_last = 0;
1208 break;
1209 case V_REFER:
1210 u.refered = p_ref;
1211 break;
1212 default:
1213 FATAL_ERROR("Value::Value()");
1214 }
1215 }
1216
1217 Value::Value(valuetype_t p_vt, Block *p_block)
1218 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1219 {
1220 if(!p_block) FATAL_ERROR("NULL parameter");
1221 switch(valuetype) {
1222 case V_UNDEF_BLOCK:
1223 u.block=p_block;
1224 break;
1225 default:
1226 FATAL_ERROR("Value::Value()");
1227 } // switch
1228 }
1229
1230 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1231 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1232 {
1233 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1234 switch (p_verdict) {
1235 case Verdict_NONE:
1236 case Verdict_PASS:
1237 case Verdict_INCONC:
1238 case Verdict_FAIL:
1239 case Verdict_ERROR:
1240 break;
1241 default:
1242 FATAL_ERROR("Value::Value()");
1243 } // switch
1244 u.verdict = p_verdict;
1245 }
1246
1247 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1248 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1249 {
1250 u.expr.v_optype = p_optype;
1251 u.expr.state = EXPR_NOT_CHECKED;
1252 switch(p_optype) {
1253 case OPTYPE_DECODE:
1254 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1255 u.expr.r1=p_r1;
1256 u.expr.r2=p_r2;
1257 break;
1258 default:
1259 FATAL_ERROR("Value::Value()");
1260 } // switch
1261 }
1262
1263 Value::~Value()
1264 {
1265 clean_up();
1266 }
1267
1268 Value *Value::clone() const
1269 {
1270 return new Value(*this);
1271 }
1272
1273 Value::operationtype_t Value::get_optype() const
1274 {
1275 if(valuetype!=V_EXPR)
1276 FATAL_ERROR("Value::get_optype()");
1277 return u.expr.v_optype;
1278 }
1279
1280 void Value::set_my_governor(Type *p_gov)
1281 {
1282 if(!p_gov)
1283 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1284 my_governor=p_gov;
1285 }
1286
1287 Type *Value::get_my_governor() const
1288 {
1289 return my_governor;
1290 }
1291
1292 void Value::set_fullname(const string& p_fullname)
1293 {
1294 GovernedSimple::set_fullname(p_fullname);
1295 switch(valuetype) {
1296 case V_CHARSYMS:
1297 u.char_syms->set_fullname(p_fullname);
1298 break;
1299 case V_OID:
1300 case V_ROID:
1301 for(size_t i=0; i<u.oid_comps->size(); i++)
1302 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1303 break;
1304 case V_CHOICE:
1305 u.choice.alt_value->set_fullname(p_fullname + "." +
1306 u.choice.alt_name->get_dispname());
1307 break;
1308 case V_SEQOF:
1309 case V_SETOF:
1310 case V_ARRAY:
1311 u.val_vs->set_fullname(p_fullname);
1312 break;
1313 case V_SEQ:
1314 case V_SET:
1315 u.val_nvs->set_fullname(p_fullname);
1316 break;
1317 case V_REFD:
1318 u.ref.ref->set_fullname(p_fullname);
1319 break;
1320 case V_REFER:
1321 u.refered->set_fullname(p_fullname);
1322 break;
1323 case V_INVOKE:
1324 u.invoke.v->set_fullname(p_fullname);
1325 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1326 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1327 break;
1328 case V_EXPR:
1329 set_fullname_expr(p_fullname);
1330 break;
1331 default:
1332 break;
1333 } // switch
1334 }
1335
1336 void Value::set_my_scope(Scope *p_scope)
1337 {
1338 GovernedSimple::set_my_scope(p_scope);
1339 switch(valuetype) {
1340 case V_CHARSYMS:
1341 u.char_syms->set_my_scope(p_scope);
1342 break;
1343 case V_OID:
1344 case V_ROID:
1345 for(size_t i=0; i<u.oid_comps->size(); i++)
1346 (*u.oid_comps)[i]->set_my_scope(p_scope);
1347 break;
1348 case V_CHOICE:
1349 u.choice.alt_value->set_my_scope(p_scope);
1350 break;
1351 case V_SEQOF:
1352 case V_SETOF:
1353 case V_ARRAY:
1354 u.val_vs->set_my_scope(p_scope);
1355 break;
1356 case V_SEQ:
1357 case V_SET:
1358 u.val_nvs->set_my_scope(p_scope);
1359 break;
1360 case V_REFD:
1361 u.ref.ref->set_my_scope(p_scope);
1362 break;
1363 case V_REFER:
1364 u.refered->set_my_scope(p_scope);
1365 break;
1366 case V_INVOKE:
1367 u.invoke.v->set_my_scope(p_scope);
1368 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1369 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1370 break;
1371 case V_EXPR:
1372 set_my_scope_expr(p_scope);
1373 break;
1374 default:
1375 break;
1376 } // switch
1377 }
1378
1379 void Value::set_fullname_expr(const string& p_fullname)
1380 {
1381 switch (u.expr.v_optype) {
1382 case OPTYPE_RND: // -
1383 case OPTYPE_COMP_NULL:
1384 case OPTYPE_COMP_MTC:
1385 case OPTYPE_COMP_SYSTEM:
1386 case OPTYPE_COMP_SELF:
1387 case OPTYPE_COMP_RUNNING_ANY:
1388 case OPTYPE_COMP_RUNNING_ALL:
1389 case OPTYPE_COMP_ALIVE_ANY:
1390 case OPTYPE_COMP_ALIVE_ALL:
1391 case OPTYPE_TMR_RUNNING_ANY:
1392 case OPTYPE_GETVERDICT:
1393 case OPTYPE_TESTCASENAME:
1394 case OPTYPE_PROF_RUNNING:
1395 break;
1396 case OPTYPE_UNARYPLUS: // v1
1397 case OPTYPE_UNARYMINUS:
1398 case OPTYPE_NOT:
1399 case OPTYPE_NOT4B:
1400 case OPTYPE_BIT2HEX:
1401 case OPTYPE_BIT2INT:
1402 case OPTYPE_BIT2OCT:
1403 case OPTYPE_BIT2STR:
1404 case OPTYPE_CHAR2INT:
1405 case OPTYPE_CHAR2OCT:
1406 case OPTYPE_COMP_RUNNING:
1407 case OPTYPE_COMP_ALIVE:
1408 case OPTYPE_FLOAT2INT:
1409 case OPTYPE_FLOAT2STR:
1410 case OPTYPE_HEX2BIT:
1411 case OPTYPE_HEX2INT:
1412 case OPTYPE_HEX2OCT:
1413 case OPTYPE_HEX2STR:
1414 case OPTYPE_INT2CHAR:
1415 case OPTYPE_INT2FLOAT:
1416 case OPTYPE_INT2STR:
1417 case OPTYPE_INT2UNICHAR:
1418 case OPTYPE_OCT2BIT:
1419 case OPTYPE_OCT2CHAR:
1420 case OPTYPE_OCT2HEX:
1421 case OPTYPE_OCT2INT:
1422 case OPTYPE_OCT2STR:
1423 case OPTYPE_STR2BIT:
1424 case OPTYPE_STR2FLOAT:
1425 case OPTYPE_STR2HEX:
1426 case OPTYPE_STR2INT:
1427 case OPTYPE_STR2OCT:
1428 case OPTYPE_UNICHAR2INT:
1429 case OPTYPE_UNICHAR2CHAR:
1430 case OPTYPE_ENUM2INT:
1431 case OPTYPE_RNDWITHVAL:
1432 case OPTYPE_REMOVE_BOM:
1433 case OPTYPE_GET_STRINGENCODING:
1434 case OPTYPE_DECODE_BASE64:
1435 u.expr.v1->set_fullname(p_fullname+".<operand>");
1436 break;
1437 case OPTYPE_ADD: // v1 v2
1438 case OPTYPE_SUBTRACT:
1439 case OPTYPE_MULTIPLY:
1440 case OPTYPE_DIVIDE:
1441 case OPTYPE_MOD:
1442 case OPTYPE_REM:
1443 case OPTYPE_CONCAT:
1444 case OPTYPE_EQ:
1445 case OPTYPE_LT:
1446 case OPTYPE_GT:
1447 case OPTYPE_NE:
1448 case OPTYPE_GE:
1449 case OPTYPE_LE:
1450 case OPTYPE_AND:
1451 case OPTYPE_OR:
1452 case OPTYPE_XOR:
1453 case OPTYPE_AND4B:
1454 case OPTYPE_OR4B:
1455 case OPTYPE_XOR4B:
1456 case OPTYPE_SHL:
1457 case OPTYPE_SHR:
1458 case OPTYPE_ROTL:
1459 case OPTYPE_ROTR:
1460 case OPTYPE_INT2BIT:
1461 case OPTYPE_INT2HEX:
1462 case OPTYPE_INT2OCT:
1463 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1464 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1465 break;
1466 case OPTYPE_UNICHAR2OCT:
1467 case OPTYPE_OCT2UNICHAR:
1468 case OPTYPE_ENCODE_BASE64:
1469 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1470 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1471 break;
1472 case OPTYPE_DECODE:
1473 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1474 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1475 break;
1476 case OPTYPE_SUBSTR:
1477 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1478 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1479 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1480 break;
1481 case OPTYPE_REGEXP:
1482 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1483 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1484 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1485 break;
1486 case OPTYPE_DECOMP: // v1 v2 v3
1487 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1488 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1489 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1490 break;
1491 case OPTYPE_REPLACE:
1492 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1493 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1494 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1495 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1496 break;
1497 case OPTYPE_LENGTHOF: // ti1
1498 case OPTYPE_SIZEOF: // ti1
1499 case OPTYPE_VALUEOF: // ti1
1500 case OPTYPE_ISVALUE:
1501 case OPTYPE_ISBOUND:
1502 case OPTYPE_ENCODE:
1503 case OPTYPE_ISPRESENT:
1504 case OPTYPE_TTCN2STRING:
1505 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1506 break;
1507 case OPTYPE_UNDEF_RUNNING: // r1
1508 case OPTYPE_TMR_READ:
1509 case OPTYPE_TMR_RUNNING:
1510 case OPTYPE_ACTIVATE:
1511 u.expr.r1->set_fullname(p_fullname+".<operand>");
1512 break;
1513 case OPTYPE_EXECUTE: // r1 [v2]
1514 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1515 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1516 break;
1517 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1518 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1519 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1520 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1521 break;
1522 case OPTYPE_MATCH: // v1 t2
1523 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1524 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1525 break;
1526 case OPTYPE_ISCHOSEN: // r1 i2
1527 u.expr.r1->set_fullname(p_fullname+".<operand>");
1528 break;
1529 case OPTYPE_ISCHOSEN_V: // v1 i2
1530 u.expr.v1->set_fullname(p_fullname+".<operand>");
1531 break;
1532 case OPTYPE_ISCHOSEN_T: // t1 i2
1533 u.expr.t1->set_fullname(p_fullname+".<operand>");
1534 break;
1535 case OPTYPE_ACTIVATE_REFD:
1536 u.expr.v1->set_fullname(p_fullname+".<reference>");
1537 if(u.expr.state!=EXPR_CHECKED)
1538 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1539 else
1540 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1541 break;
1542 case OPTYPE_EXECUTE_REFD:
1543 u.expr.v1->set_fullname(p_fullname+".<reference>");
1544 if(u.expr.state!=EXPR_CHECKED)
1545 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1546 else
1547 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1548 if(u.expr.v3)
1549 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1550 break;
1551 case OPTYPE_LOG2STR:
1552 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1553 break;
1554 default:
1555 FATAL_ERROR("Value::set_fullname_expr()");
1556 } // switch
1557 }
1558
1559 void Value::set_my_scope_expr(Scope *p_scope)
1560 {
1561 switch (u.expr.v_optype) {
1562 case OPTYPE_RND: // -
1563 case OPTYPE_COMP_NULL:
1564 case OPTYPE_COMP_MTC:
1565 case OPTYPE_COMP_SYSTEM:
1566 case OPTYPE_COMP_SELF:
1567 case OPTYPE_COMP_RUNNING_ANY:
1568 case OPTYPE_COMP_RUNNING_ALL:
1569 case OPTYPE_COMP_ALIVE_ANY:
1570 case OPTYPE_COMP_ALIVE_ALL:
1571 case OPTYPE_TMR_RUNNING_ANY:
1572 case OPTYPE_GETVERDICT:
1573 case OPTYPE_TESTCASENAME:
1574 case OPTYPE_PROF_RUNNING:
1575 break;
1576 case OPTYPE_UNARYPLUS: // v1
1577 case OPTYPE_UNARYMINUS:
1578 case OPTYPE_NOT:
1579 case OPTYPE_NOT4B:
1580 case OPTYPE_BIT2HEX:
1581 case OPTYPE_BIT2INT:
1582 case OPTYPE_BIT2OCT:
1583 case OPTYPE_BIT2STR:
1584 case OPTYPE_CHAR2INT:
1585 case OPTYPE_CHAR2OCT:
1586 case OPTYPE_COMP_RUNNING:
1587 case OPTYPE_COMP_ALIVE:
1588 case OPTYPE_FLOAT2INT:
1589 case OPTYPE_FLOAT2STR:
1590 case OPTYPE_HEX2BIT:
1591 case OPTYPE_HEX2INT:
1592 case OPTYPE_HEX2OCT:
1593 case OPTYPE_HEX2STR:
1594 case OPTYPE_INT2CHAR:
1595 case OPTYPE_INT2FLOAT:
1596 case OPTYPE_INT2STR:
1597 case OPTYPE_INT2UNICHAR:
1598 case OPTYPE_OCT2BIT:
1599 case OPTYPE_OCT2CHAR:
1600 case OPTYPE_OCT2HEX:
1601 case OPTYPE_OCT2INT:
1602 case OPTYPE_OCT2STR:
1603 case OPTYPE_STR2BIT:
1604 case OPTYPE_STR2FLOAT:
1605 case OPTYPE_STR2HEX:
1606 case OPTYPE_STR2INT:
1607 case OPTYPE_STR2OCT:
1608 case OPTYPE_UNICHAR2INT:
1609 case OPTYPE_UNICHAR2CHAR:
1610 case OPTYPE_ENUM2INT:
1611 case OPTYPE_RNDWITHVAL:
1612 case OPTYPE_REMOVE_BOM:
1613 case OPTYPE_GET_STRINGENCODING:
1614 case OPTYPE_DECODE_BASE64:
1615 u.expr.v1->set_my_scope(p_scope);
1616 break;
1617 case OPTYPE_ADD: // v1 v2
1618 case OPTYPE_SUBTRACT:
1619 case OPTYPE_MULTIPLY:
1620 case OPTYPE_DIVIDE:
1621 case OPTYPE_MOD:
1622 case OPTYPE_REM:
1623 case OPTYPE_CONCAT:
1624 case OPTYPE_EQ:
1625 case OPTYPE_LT:
1626 case OPTYPE_GT:
1627 case OPTYPE_NE:
1628 case OPTYPE_GE:
1629 case OPTYPE_LE:
1630 case OPTYPE_AND:
1631 case OPTYPE_OR:
1632 case OPTYPE_XOR:
1633 case OPTYPE_AND4B:
1634 case OPTYPE_OR4B:
1635 case OPTYPE_XOR4B:
1636 case OPTYPE_SHL:
1637 case OPTYPE_SHR:
1638 case OPTYPE_ROTL:
1639 case OPTYPE_ROTR:
1640 case OPTYPE_INT2BIT:
1641 case OPTYPE_INT2HEX:
1642 case OPTYPE_INT2OCT:
1643 u.expr.v1->set_my_scope(p_scope);
1644 u.expr.v2->set_my_scope(p_scope);
1645 break;
1646 case OPTYPE_UNICHAR2OCT:
1647 case OPTYPE_OCT2UNICHAR:
1648 case OPTYPE_ENCODE_BASE64:
1649 u.expr.v1->set_my_scope(p_scope);
1650 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1651 break;
1652 case OPTYPE_DECODE:
1653 u.expr.r1->set_my_scope(p_scope);
1654 u.expr.r2->set_my_scope(p_scope);
1655 break;
1656 case OPTYPE_SUBSTR:
1657 u.expr.ti1->set_my_scope(p_scope);
1658 u.expr.v2->set_my_scope(p_scope);
1659 u.expr.v3->set_my_scope(p_scope);
1660 break;
1661 case OPTYPE_REGEXP:
1662 u.expr.ti1->set_my_scope(p_scope);
1663 u.expr.t2->set_my_scope(p_scope);
1664 u.expr.v3->set_my_scope(p_scope);
1665 break;
1666 case OPTYPE_DECOMP: // v1 v2 v3
1667 u.expr.v1->set_my_scope(p_scope);
1668 u.expr.v2->set_my_scope(p_scope);
1669 u.expr.v3->set_my_scope(p_scope);
1670 break;
1671 case OPTYPE_REPLACE:
1672 u.expr.ti1->set_my_scope(p_scope);
1673 u.expr.v2->set_my_scope(p_scope);
1674 u.expr.v3->set_my_scope(p_scope);
1675 u.expr.ti4->set_my_scope(p_scope);
1676 break;
1677 case OPTYPE_LENGTHOF: // ti1
1678 case OPTYPE_SIZEOF: // ti1
1679 case OPTYPE_VALUEOF: // ti1
1680 case OPTYPE_ISVALUE:
1681 case OPTYPE_ISBOUND:
1682 case OPTYPE_ENCODE:
1683 case OPTYPE_ISPRESENT:
1684 case OPTYPE_TTCN2STRING:
1685 u.expr.ti1->set_my_scope(p_scope);
1686 break;
1687 case OPTYPE_UNDEF_RUNNING: // r1
1688 case OPTYPE_TMR_READ:
1689 case OPTYPE_TMR_RUNNING:
1690 case OPTYPE_ACTIVATE:
1691 u.expr.r1->set_my_scope(p_scope);
1692 break;
1693 case OPTYPE_EXECUTE: // r1 [v2]
1694 u.expr.r1->set_my_scope(p_scope);
1695 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1696 break;
1697 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1698 u.expr.r1->set_my_scope(p_scope);
1699 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1700 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1701 break;
1702 case OPTYPE_MATCH: // v1 t2
1703 u.expr.v1->set_my_scope(p_scope);
1704 u.expr.t2->set_my_scope(p_scope);
1705 break;
1706 case OPTYPE_ISCHOSEN: // r1 i2
1707 u.expr.r1->set_my_scope(p_scope);
1708 break;
1709 case OPTYPE_ISCHOSEN_V: // v1 i2
1710 u.expr.v1->set_my_scope(p_scope);
1711 break;
1712 case OPTYPE_ISCHOSEN_T: // t1 i2
1713 u.expr.t1->set_my_scope(p_scope);
1714 break;
1715 case OPTYPE_ACTIVATE_REFD:
1716 u.expr.v1->set_my_scope(p_scope);
1717 if(u.expr.state!=EXPR_CHECKED) {
1718 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1719 else
1720 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1721 } break;
1722 case OPTYPE_EXECUTE_REFD:
1723 u.expr.v1->set_my_scope(p_scope);
1724 if(u.expr.state!=EXPR_CHECKED) {
1725 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1726 else
1727 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1728 }
1729 if(u.expr.v3)
1730 u.expr.v3->set_my_scope(p_scope);
1731 break;
1732 case OPTYPE_LOG2STR:
1733 u.expr.logargs->set_my_scope(p_scope);
1734 break;
1735 default:
1736 FATAL_ERROR("Value::set_my_scope_expr()");
1737 } // switch
1738 }
1739
1740 void Value::set_genname_recursive(const string& p_genname)
1741 {
1742 size_t genname_len = p_genname.size();
1743 if (genname_len >= 4 &&
1744 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1745 // if the genname ends with ()() (i.e. the value stands for an optional
1746 // field) then drop the last () from the own genname, but leave it for
1747 // the embedded values
1748 set_genname(p_genname.substr(0, genname_len - 2));
1749 } else set_genname(p_genname);
1750 switch(valuetype) {
1751 case V_CHOICE: {
1752 string embedded_genname(p_genname);
1753 embedded_genname += '.';
1754 // If this is a choice value for an anytype, prepend the AT_ prefix
1755 // to the name of the alternative. The genname is used later in
1756 // Common::Value::generate_code_init_se()
1757 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1758 embedded_genname += "AT_";
1759 embedded_genname += u.choice.alt_name->get_name();
1760 embedded_genname += "()";
1761 u.choice.alt_value->set_genname_recursive(embedded_genname);
1762 break; }
1763 case V_SEQOF:
1764 case V_SETOF: {
1765 if (!is_indexed()) {
1766 size_t nof_vs = u.val_vs->get_nof_vs();
1767 for (size_t i = 0; i < nof_vs; i++) {
1768 string embedded_genname(p_genname);
1769 embedded_genname += '[';
1770 embedded_genname += Int2string(i);
1771 embedded_genname += ']';
1772 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1773 }
1774 } else {
1775 size_t nof_ivs = u.val_vs->get_nof_ivs();
1776 for (size_t i = 0; i < nof_ivs; i++) {
1777 string embedded_genname(p_genname);
1778 embedded_genname += '[';
1779 embedded_genname += Int2string(i);
1780 embedded_genname += ']';
1781 u.val_vs->get_iv_byIndex(i)->get_value()
1782 ->set_genname_recursive(embedded_genname);
1783 }
1784 }
1785 break; }
1786 case V_ARRAY: {
1787 if (!my_governor) return; // error recovery
1788 Type *type = my_governor->get_type_refd_last();
1789 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1790 Int offset = type->get_dimension()->get_offset();
1791 if (!is_indexed()) {
1792 size_t nof_vs = u.val_vs->get_nof_vs();
1793 for (size_t i = 0; i < nof_vs; i++) {
1794 string embedded_genname(p_genname);
1795 embedded_genname += '[';
1796 embedded_genname += Int2string(offset + i);
1797 embedded_genname += ']';
1798 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1799 }
1800 } else {
1801 size_t nof_ivs = u.val_vs->get_nof_ivs();
1802 for (size_t i = 0; i < nof_ivs; i++) {
1803 string embedded_genname(p_genname);
1804 embedded_genname += '[';
1805 embedded_genname += Int2string(offset + i);
1806 embedded_genname += ']';
1807 u.val_vs->get_iv_byIndex(i)->get_value()
1808 ->set_genname_recursive(embedded_genname);
1809 }
1810 }
1811 break; }
1812 case V_SEQ:
1813 case V_SET: {
1814 if (!my_governor) return; // error recovery
1815 Type *t = my_governor->get_type_refd_last();
1816 if (!t->is_secho()) return; // error recovery
1817 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1818 for (size_t i = 0; i < nof_nvs; i++) {
1819 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1820 const Identifier& id = nv->get_name();
1821 if (!t->has_comp_withName(id)) return; // error recovery
1822 string embedded_genname(p_genname);
1823 embedded_genname += '.';
1824 embedded_genname += id.get_name();
1825 embedded_genname += "()";
1826 if (t->get_comp_byName(id)->get_is_optional())
1827 embedded_genname += "()";
1828 nv->get_value()->set_genname_recursive(embedded_genname);
1829 }
1830 break; }
1831 default:
1832 break;
1833 } // switch
1834 }
1835
1836 void Value::set_genname_prefix(const char *p_genname_prefix)
1837 {
1838 GovernedSimple::set_genname_prefix(p_genname_prefix);
1839 switch(valuetype) {
1840 case V_CHOICE:
1841 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1842 break;
1843 case V_SEQOF:
1844 case V_SETOF:
1845 case V_ARRAY:
1846 if (!is_indexed()) {
1847 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1848 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1849 } else {
1850 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1851 u.val_vs->get_iv_byIndex(i)->get_value()
1852 ->set_genname_prefix(p_genname_prefix);
1853 }
1854 break;
1855 case V_SEQ:
1856 case V_SET:
1857 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1858 u.val_nvs->get_nv_byIndex(i)->get_value()
1859 ->set_genname_prefix(p_genname_prefix);
1860 break;
1861 default:
1862 break;
1863 } // switch
1864 }
1865
1866 void Value::set_code_section(code_section_t p_code_section)
1867 {
1868 GovernedSimple::set_code_section(p_code_section);
1869 switch(valuetype) {
1870 case V_EXPR:
1871 switch (u.expr.v_optype) {
1872 case OPTYPE_RND: // -
1873 case OPTYPE_COMP_NULL:
1874 case OPTYPE_COMP_MTC:
1875 case OPTYPE_COMP_SYSTEM:
1876 case OPTYPE_COMP_SELF:
1877 case OPTYPE_COMP_RUNNING_ANY:
1878 case OPTYPE_COMP_RUNNING_ALL:
1879 case OPTYPE_COMP_ALIVE_ANY:
1880 case OPTYPE_COMP_ALIVE_ALL:
1881 case OPTYPE_TMR_RUNNING_ANY:
1882 case OPTYPE_GETVERDICT:
1883 case OPTYPE_TESTCASENAME:
1884 case OPTYPE_PROF_RUNNING:
1885 break;
1886 case OPTYPE_UNARYPLUS: // v1
1887 case OPTYPE_UNARYMINUS:
1888 case OPTYPE_NOT:
1889 case OPTYPE_NOT4B:
1890 case OPTYPE_BIT2HEX:
1891 case OPTYPE_BIT2INT:
1892 case OPTYPE_BIT2OCT:
1893 case OPTYPE_BIT2STR:
1894 case OPTYPE_CHAR2INT:
1895 case OPTYPE_CHAR2OCT:
1896 case OPTYPE_COMP_RUNNING:
1897 case OPTYPE_COMP_ALIVE:
1898 case OPTYPE_FLOAT2INT:
1899 case OPTYPE_FLOAT2STR:
1900 case OPTYPE_HEX2BIT:
1901 case OPTYPE_HEX2INT:
1902 case OPTYPE_HEX2OCT:
1903 case OPTYPE_HEX2STR:
1904 case OPTYPE_INT2CHAR:
1905 case OPTYPE_INT2FLOAT:
1906 case OPTYPE_INT2STR:
1907 case OPTYPE_INT2UNICHAR:
1908 case OPTYPE_OCT2BIT:
1909 case OPTYPE_OCT2CHAR:
1910 case OPTYPE_OCT2HEX:
1911 case OPTYPE_OCT2INT:
1912 case OPTYPE_OCT2STR:
1913 case OPTYPE_STR2BIT:
1914 case OPTYPE_STR2FLOAT:
1915 case OPTYPE_STR2HEX:
1916 case OPTYPE_STR2INT:
1917 case OPTYPE_STR2OCT:
1918 case OPTYPE_UNICHAR2INT:
1919 case OPTYPE_UNICHAR2CHAR:
1920 case OPTYPE_ENUM2INT:
1921 case OPTYPE_RNDWITHVAL:
1922 case OPTYPE_GET_STRINGENCODING:
1923 case OPTYPE_DECODE_BASE64:
1924 case OPTYPE_REMOVE_BOM:
1925 u.expr.v1->set_code_section(p_code_section);
1926 break;
1927 case OPTYPE_ADD: // v1 v2
1928 case OPTYPE_SUBTRACT:
1929 case OPTYPE_MULTIPLY:
1930 case OPTYPE_DIVIDE:
1931 case OPTYPE_MOD:
1932 case OPTYPE_REM:
1933 case OPTYPE_CONCAT:
1934 case OPTYPE_EQ:
1935 case OPTYPE_LT:
1936 case OPTYPE_GT:
1937 case OPTYPE_NE:
1938 case OPTYPE_GE:
1939 case OPTYPE_LE:
1940 case OPTYPE_AND:
1941 case OPTYPE_OR:
1942 case OPTYPE_XOR:
1943 case OPTYPE_AND4B:
1944 case OPTYPE_OR4B:
1945 case OPTYPE_XOR4B:
1946 case OPTYPE_SHL:
1947 case OPTYPE_SHR:
1948 case OPTYPE_ROTL:
1949 case OPTYPE_ROTR:
1950 case OPTYPE_INT2BIT:
1951 case OPTYPE_INT2HEX:
1952 case OPTYPE_INT2OCT:
1953 u.expr.v1->set_code_section(p_code_section);
1954 u.expr.v2->set_code_section(p_code_section);
1955 break;
1956 case OPTYPE_UNICHAR2OCT:
1957 case OPTYPE_OCT2UNICHAR:
1958 case OPTYPE_ENCODE_BASE64:
1959 u.expr.v1->set_code_section(p_code_section);
1960 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
1961 break;
1962 case OPTYPE_DECODE:
1963 u.expr.r1->set_code_section(p_code_section);
1964 u.expr.r2->set_code_section(p_code_section);
1965 break;
1966 case OPTYPE_SUBSTR:
1967 u.expr.ti1->set_code_section(p_code_section);
1968 u.expr.v2->set_code_section(p_code_section);
1969 u.expr.v3->set_code_section(p_code_section);
1970 break;
1971 case OPTYPE_REGEXP:
1972 u.expr.ti1->set_code_section(p_code_section);
1973 u.expr.t2->set_code_section(p_code_section);
1974 u.expr.v3->set_code_section(p_code_section);
1975 break;
1976 case OPTYPE_DECOMP: // v1 v2 v3
1977 u.expr.v1->set_code_section(p_code_section);
1978 u.expr.v2->set_code_section(p_code_section);
1979 u.expr.v3->set_code_section(p_code_section);
1980 break;
1981 case OPTYPE_REPLACE:
1982 u.expr.ti1->set_code_section(p_code_section);
1983 u.expr.v2->set_code_section(p_code_section);
1984 u.expr.v3->set_code_section(p_code_section);
1985 u.expr.ti4->set_code_section(p_code_section);
1986 break;
1987 case OPTYPE_LENGTHOF: // ti1
1988 case OPTYPE_SIZEOF: // ti1
1989 case OPTYPE_VALUEOF: // ti1
1990 case OPTYPE_ISVALUE:
1991 case OPTYPE_ISBOUND:
1992 case OPTYPE_ENCODE:
1993 case OPTYPE_ISPRESENT:
1994 case OPTYPE_TTCN2STRING:
1995 u.expr.ti1->set_code_section(p_code_section);
1996 break;
1997 case OPTYPE_UNDEF_RUNNING: // r1
1998 case OPTYPE_TMR_READ:
1999 case OPTYPE_TMR_RUNNING:
2000 case OPTYPE_ACTIVATE:
2001 u.expr.r1->set_code_section(p_code_section);
2002 break;
2003 case OPTYPE_EXECUTE: // r1 [v2]
2004 u.expr.r1->set_code_section(p_code_section);
2005 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2006 break;
2007 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2008 u.expr.r1->set_code_section(p_code_section);
2009 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2010 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2011 break;
2012 case OPTYPE_MATCH: // v1 t2
2013 u.expr.v1->set_code_section(p_code_section);
2014 u.expr.t2->set_code_section(p_code_section);
2015 break;
2016 case OPTYPE_ISCHOSEN: // r1 i2
2017 u.expr.r1->set_code_section(p_code_section);
2018 break;
2019 case OPTYPE_ISCHOSEN_V: // v1 i2
2020 u.expr.v1->set_code_section(p_code_section);
2021 break;
2022 case OPTYPE_ISCHOSEN_T: // t1 i2
2023 u.expr.t1->set_code_section(p_code_section);
2024 break;
2025 case OPTYPE_ACTIVATE_REFD:
2026 u.expr.v1->set_code_section(p_code_section);
2027 if(u.expr.state!=EXPR_CHECKED)
2028 u.expr.t_list2->set_code_section(p_code_section);
2029 else {
2030 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2031 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2032 u.expr.state = EXPR_CHECKED;
2033 }
2034 break;
2035 case OPTYPE_EXECUTE_REFD:
2036 u.expr.v1->set_code_section(p_code_section);
2037 if(u.expr.state!=EXPR_CHECKED)
2038 u.expr.t_list2->set_code_section(p_code_section);
2039 else {
2040 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2041 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2042 u.expr.state = EXPR_CHECKED;
2043 }
2044 if(u.expr.v3)
2045 u.expr.v3->set_code_section(p_code_section);
2046 break;
2047 case OPTYPE_LOG2STR:
2048 u.expr.logargs->set_code_section(p_code_section);
2049 break;
2050 default:
2051 FATAL_ERROR("Value::set_code_section()");
2052 } // switch
2053 break;
2054 case V_CHOICE:
2055 u.choice.alt_value->set_code_section(p_code_section);
2056 break;
2057 case V_SEQOF:
2058 case V_SETOF:
2059 case V_ARRAY:
2060 if (!is_indexed()) {
2061 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2062 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2063 } else {
2064 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2065 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2066 }
2067 break;
2068 case V_SEQ:
2069 case V_SET:
2070 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2071 u.val_nvs->get_nv_byIndex(i)->get_value()
2072 ->set_code_section(p_code_section);
2073 break;
2074 case V_REFD:
2075 u.ref.ref->set_code_section(p_code_section);
2076 break;
2077 case V_REFER:
2078 u.refered->set_code_section(p_code_section);
2079 break;
2080 case V_INVOKE:
2081 u.invoke.v->set_code_section(p_code_section);
2082 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2083 if(u.invoke.ap_list)
2084 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2085 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2086 break;
2087 default:
2088 break;
2089 } // switch
2090 }
2091
2092 void Value::change_sign()
2093 {
2094 switch(valuetype) {
2095 case V_INT:
2096 *u.val_Int=-*u.val_Int;
2097 break;
2098 case V_REAL:
2099 u.val_Real*=-1.0;
2100 break;
2101 case V_ERROR:
2102 break;
2103 default:
2104 FATAL_ERROR("Value::change_sign()");
2105 } // switch
2106 }
2107
2108 void Value::add_oid_comp(OID_comp* p_comp)
2109 {
2110 if(!p_comp)
2111 FATAL_ERROR("NULL parameter");
2112 u.oid_comps->add(p_comp);
2113 p_comp->set_fullname(get_fullname()+"."
2114 +Int2string(u.oid_comps->size()));
2115 p_comp->set_my_scope(my_scope);
2116 }
2117
2118 void Value::set_valuetype(valuetype_t p_valuetype)
2119 {
2120 if (valuetype == V_ERROR) return;
2121 else if (p_valuetype == V_ERROR) {
2122 if(valuetype==V_EXPR) {
2123 switch(u.expr.state) {
2124 case EXPR_CHECKING:
2125 u.expr.state=EXPR_CHECKING_ERR;
2126 // no break
2127 case EXPR_CHECKING_ERR:
2128 return;
2129 default:
2130 break;
2131 }
2132 }
2133 clean_up();
2134 valuetype = V_ERROR;
2135 return;
2136 }
2137 switch(valuetype) {
2138 case V_UNDEF_LOWERID:
2139 switch(p_valuetype) {
2140 case V_ENUM:
2141 case V_NAMEDINT:
2142 break;
2143 case V_REFD:
2144 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2145 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2146 u.ref.ref->set_my_scope(get_my_scope());
2147 u.ref.ref->set_fullname(get_fullname());
2148 u.ref.ref->set_location(*this);
2149 u.ref.refd_last = 0;
2150 break;
2151 default:
2152 FATAL_ERROR("Value::set_valuetype()");
2153 } // switch
2154 break;
2155 case V_UNDEF_BLOCK: {
2156 Block *t_block=u.block;
2157 Value *v=0;
2158 switch(p_valuetype) {
2159 case V_NAMEDBITS: {
2160 Node *node=t_block->parse(KW_Block_IdentifierList);
2161 v=dynamic_cast<Value*>(node);
2162 if(!v) {
2163 /* syntax error */
2164 u.ids=new map<string, Identifier>();
2165 }
2166 else {
2167 u.ids=v->u.ids; v->u.ids=0;
2168 }
2169 break;}
2170 case V_SEQOF: {
2171 Node *node=t_block->parse(KW_Block_SeqOfValue);
2172 v=dynamic_cast<Value*>(node);
2173 if(!v) {
2174 /* syntax error */
2175 u.val_vs=new Values();
2176 }
2177 else {
2178 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2179 }
2180 u.val_vs->set_my_scope(get_my_scope());
2181 u.val_vs->set_fullname(get_fullname());
2182 break;}
2183 case V_SETOF: {
2184 Node *node=t_block->parse(KW_Block_SetOfValue);
2185 v=dynamic_cast<Value*>(node);
2186 if(!v) {
2187 /* syntax error */
2188 u.val_vs=new Values();
2189 }
2190 else {
2191 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2192 }
2193 u.val_vs->set_my_scope(get_my_scope());
2194 u.val_vs->set_fullname(get_fullname());
2195 break;}
2196 case V_SEQ: {
2197 Node *node=t_block->parse(KW_Block_SequenceValue);
2198 v=dynamic_cast<Value*>(node);
2199 if(!v) {
2200 /* syntax error */
2201 u.val_nvs=new NamedValues();
2202 }
2203 else {
2204 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2205 }
2206 u.val_nvs->set_my_scope(get_my_scope());
2207 u.val_nvs->set_fullname(get_fullname());
2208 break;}
2209 case V_SET: {
2210 Node *node=t_block->parse(KW_Block_SetValue);
2211 v=dynamic_cast<Value*>(node);
2212 if(!v) {
2213 /* syntax error */
2214 u.val_nvs=new NamedValues();
2215 }
2216 else {
2217 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2218 }
2219 u.val_nvs->set_my_scope(get_my_scope());
2220 u.val_nvs->set_fullname(get_fullname());
2221 break;}
2222 case V_OID: {
2223 Node *node=t_block->parse(KW_Block_OIDValue);
2224 v=dynamic_cast<Value*>(node);
2225 if(!v) {
2226 /* syntax error */
2227 u.oid_comps=new vector<OID_comp>();
2228 }
2229 else {
2230 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2231 }
2232 for (size_t i = 0; i < u.oid_comps->size(); i++)
2233 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2234 break;}
2235 case V_ROID: {
2236 Node *node=t_block->parse(KW_Block_ROIDValue);
2237 v=dynamic_cast<Value*>(node);
2238 if(!v) {
2239 /* syntax error */
2240 u.oid_comps=new vector<OID_comp>();
2241 }
2242 else {
2243 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2244 }
2245 for (size_t i = 0; i < u.oid_comps->size(); i++)
2246 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2247 break;}
2248 case V_CHARSYMS: {
2249 Node *node=t_block->parse(KW_Block_CharStringValue);
2250 u.char_syms=dynamic_cast<CharSyms*>(node);
2251 if(!u.char_syms) {
2252 /* syntax error */
2253 u.char_syms=new CharSyms();
2254 }
2255 u.char_syms->set_my_scope(get_my_scope());
2256 u.char_syms->set_fullname(get_fullname());
2257 break;}
2258 default:
2259 FATAL_ERROR("Value::set_valuetype()");
2260 } // switch
2261 delete v;
2262 delete t_block;
2263 break;}
2264 case V_REFD:
2265 if (p_valuetype == V_USTR) {
2266 Value *v_last = get_value_refd_last();
2267 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2268 ustring *ustr = new ustring(*v_last->u.str.val_str);
2269 delete u.ref.ref;
2270 set_val_ustr(ustr);
2271 u.ustr.convert_str = true; // will be converted back to string
2272 } else FATAL_ERROR("Value::set_valuetype()");
2273 break;
2274 case V_CHARSYMS:
2275 switch(p_valuetype) {
2276 case V_CSTR: {
2277 const string& str = u.char_syms->get_string();
2278 delete u.char_syms;
2279 set_val_str(new string(str));
2280 break;}
2281 case V_USTR: {
2282 const ustring& ustr = u.char_syms->get_ustring();
2283 delete u.char_syms;
2284 set_val_ustr(new ustring(ustr));
2285 u.ustr.convert_str = false;
2286 break;}
2287 case V_ISO2022STR: {
2288 const string& str = u.char_syms->get_iso2022string();
2289 delete u.char_syms;
2290 set_val_str(new string(str));
2291 break;}
2292 default:
2293 FATAL_ERROR("Value::set_valuetype()");
2294 } // switch
2295 break;
2296 case V_INT: {
2297 Real val_Real;
2298 if (p_valuetype == V_REAL)
2299 val_Real = u.val_Int->to_real();
2300 else FATAL_ERROR("Value::set_valuetype()");
2301 clean_up();
2302 u.val_Real = val_Real;
2303 break; }
2304 case V_HSTR: {
2305 clean_up_string_elements(u.str.str_elements);
2306 string *old_str = u.str.val_str;
2307 switch(p_valuetype) {
2308 case V_BSTR:
2309 set_val_str(hex2bit(*old_str));
2310 break;
2311 case V_OSTR:
2312 set_val_str(asn_hex2oct(*old_str));
2313 break;
2314 default:
2315 FATAL_ERROR("Value::set_valuetype()");
2316 } // switch
2317 delete old_str;
2318 break;}
2319 case V_BSTR:
2320 clean_up_string_elements(u.str.str_elements);
2321 if (p_valuetype == V_OSTR) {
2322 string *old_str = u.str.val_str;
2323 set_val_str(asn_bit2oct(*old_str));
2324 delete old_str;
2325 } else FATAL_ERROR("Value::set_valuetype()");
2326 break;
2327 case V_CSTR:
2328 clean_up_string_elements(u.str.str_elements);
2329 switch(p_valuetype) {
2330 case V_USTR: {
2331 string *old_str = u.str.val_str;
2332 set_val_ustr(new ustring(*old_str));
2333 u.ustr.convert_str = true; // will be converted back to string
2334 delete old_str;
2335 break;}
2336 case V_ISO2022STR:
2337 // do nothing
2338 break;
2339 default:
2340 FATAL_ERROR("Value::set_valuetype()");
2341 } // switch p_valuetype
2342 break;
2343 case V_USTR:
2344 clean_up_string_elements(u.ustr.ustr_elements);
2345 switch(p_valuetype) {
2346 case V_CSTR: {
2347 ustring *old_str = u.ustr.val_ustr;
2348 size_t nof_chars = old_str->size();
2349 bool warning_flag = false;
2350 for (size_t i = 0; i < nof_chars; i++) {
2351 const ustring::universal_char& uchar = (*old_str)[i];
2352 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2353 error("This string value cannot contain multiple-byte characters, "
2354 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2355 uchar.group, uchar.plane, uchar.row, uchar.cell,
2356 (unsigned long) i);
2357 p_valuetype = V_ERROR;
2358 break;
2359 } else if (uchar.cell > 127 && !warning_flag) {
2360 warning("This string value may not contain characters with code "
2361 "higher than 127, but it has character with code %u (0x%02X) "
2362 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2363 warning_flag = true;
2364 }
2365 }
2366 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2367 delete old_str;
2368 break; }
2369 case V_ISO2022STR:
2370 error("ISO-10646 string value cannot be converted to "
2371 "ISO-2022 string");
2372 delete u.ustr.val_ustr;
2373 p_valuetype = V_ERROR;
2374 break;
2375 default:
2376 FATAL_ERROR("Value::set_valuetype()");
2377 } // switch p_valuetype
2378 break;
2379 case V_SEQ:
2380 switch (p_valuetype) {
2381 case V_CHOICE: {
2382 NamedValues *nvs = u.val_nvs;
2383 if (nvs->get_nof_nvs() < 1) {
2384 error("Union value must have one active field");
2385 delete nvs;
2386 valuetype = V_ERROR;
2387 return;
2388 } else if (nvs->get_nof_nvs() > 1) {
2389 error("Only one field was expected in union value instead of %lu",
2390 (unsigned long) nvs->get_nof_nvs());
2391 }
2392 NamedValue *nv = nvs->get_nv_byIndex(0);
2393 u.choice.alt_name = nv->get_name().clone();
2394 u.choice.alt_value = nv->steal_value();
2395 delete nvs;
2396 break;}
2397 case V_SET:
2398 // do nothing
2399 break;
2400 case V_REAL: {
2401 NamedValues *nvs = u.val_nvs;
2402 bool err = false;
2403 /* mantissa */
2404 Int i_mant = 0;
2405 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2406 if (nvs->has_nv_withName(id_mant)) {
2407 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2408 ->get_value_refd_last();
2409 if (v_tmp->get_valuetype() == V_INT) {
2410 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2411 if (*i_mant_int > INT_MAX) {
2412 error("Mantissa `%s' should be less than `%d'",
2413 (i_mant_int->t_str()).c_str(), INT_MAX);
2414 err = true;
2415 } else {
2416 i_mant = i_mant_int->get_val();
2417 }
2418 }
2419 else err = true;
2420 }
2421 else err = true;
2422 /* base */
2423 Int i_base = 0;
2424 Identifier id_base(Identifier::ID_ASN, string("base"));
2425 if (!err && nvs->has_nv_withName(id_base)) {
2426 Value *v = nvs->get_nv_byName(id_base)->get_value();
2427 Value *v_tmp = v->get_value_refd_last();
2428 if (v_tmp->get_valuetype() == V_INT) {
2429 const int_val_t *i_base_int = v_tmp->get_val_Int();
2430 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2431 v->error("Base of the REAL must be 2 or 10");
2432 err = true;
2433 } else {
2434 i_base = i_base_int->get_val();
2435 }
2436 }
2437 else err = true;
2438 }
2439 else err = true;
2440 /* exponent */
2441 Int i_exp = 0;
2442 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2443 if (!err && nvs->has_nv_withName(id_exp)) {
2444 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2445 ->get_value_refd_last();
2446 if (v_tmp->get_valuetype() == V_INT) {
2447 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2448 if (*i_exp_int > INT_MAX) {
2449 error("Exponent `%s' should be less than `%d'",
2450 (i_exp_int->t_str()).c_str(), INT_MAX);
2451 err = true;
2452 } else {
2453 i_exp = i_exp_int->get_val();
2454 }
2455 }
2456 else err = true;
2457 }
2458 else err = true;
2459 /* clean up */
2460 delete nvs;
2461 if (err) {
2462 valuetype = V_ERROR;
2463 return;
2464 }
2465 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2466 static_cast<double>(i_exp));
2467 break; }
2468 default:
2469 FATAL_ERROR("Value::set_valuetype()");
2470 } // switch
2471 break;
2472 case V_SEQOF:
2473 switch (p_valuetype) {
2474 case V_SEQ: {
2475 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2476 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2477 Type *t = my_governor->get_type_refd_last();
2478 switch (t->get_typetype()) {
2479 case Type::T_SEQ_T:
2480 case Type::T_SEQ_A:
2481 break;
2482 default:
2483 FATAL_ERROR("Value::set_valuetype()");
2484 }
2485 Values *vals = u.val_vs;
2486 size_t nof_vals = vals->get_nof_vs();
2487 size_t nof_comps = t->get_nof_comps();
2488 if (nof_vals > nof_comps) {
2489 error("Too many elements in value list notation for type `%s': "
2490 "%lu was expected instead of %lu",
2491 t->get_typename().c_str(),
2492 (unsigned long)nof_comps, (unsigned long)nof_vals);
2493 }
2494 size_t upper_limit;
2495 bool allnotused;
2496 if (nof_vals <= nof_comps) {
2497 upper_limit = nof_vals;
2498 allnotused = true;
2499 } else {
2500 upper_limit = nof_comps;
2501 allnotused = false;
2502 }
2503 u.val_nvs = new NamedValues;
2504 for (size_t i = 0; i < upper_limit; i++) {
2505 Value *v = vals->steal_v_byIndex(i);
2506 if (v->valuetype != V_NOTUSED) {
2507 allnotused = false;
2508 }
2509 NamedValue *nv =
2510 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2511 nv->set_location(*v);
2512 u.val_nvs->add_nv(nv);
2513 }
2514 u.val_nvs->set_my_scope(get_my_scope());
2515 u.val_nvs->set_fullname(get_fullname());
2516 delete vals;
2517 if (allnotused && nof_vals > 0)
2518 warning("All elements of value list notation for type `%s' are not "
2519 "used symbols (`-')", t->get_typename().c_str());
2520 break; }
2521 case V_SET:
2522 // { } -> empty set value
2523 if (u.val_vs->get_nof_vs() != 0)
2524 FATAL_ERROR("Value::set_valuetype()");
2525 delete u.val_vs;
2526 u.val_nvs = new NamedValues;
2527 break;
2528 case V_SETOF:
2529 case V_ARRAY:
2530 // SEQOF -> SETOF or ARRAY: trivial
2531 break;
2532 default:
2533 FATAL_ERROR("Value::set_valuetype()");
2534 }
2535 break;
2536 case V_TTCN3_NULL:
2537 switch (p_valuetype) {
2538 case V_DEFAULT_NULL:
2539 break;
2540 case V_FAT_NULL:
2541 break;
2542 default:
2543 FATAL_ERROR("Value::set_valuetype()");
2544 }
2545 break;
2546 case V_NOTUSED:
2547 if (V_OMIT != p_valuetype) { // in case of implicit omit
2548 FATAL_ERROR("Value::set_valuetype()");
2549 }
2550 break;
2551 default:
2552 FATAL_ERROR("Value::set_valuetype()");
2553 } // switch
2554 valuetype=p_valuetype;
2555 }
2556
2557 void Value::set_valuetype_COMP_NULL()
2558 {
2559 if(valuetype == V_ERROR) return;
2560 if(valuetype==V_TTCN3_NULL) {
2561 valuetype=V_EXPR;
2562 u.expr.v_optype=OPTYPE_COMP_NULL;
2563 // Nothing to check.
2564 u.expr.state=EXPR_CHECKED;
2565 }
2566 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2567 }
2568
2569 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2570 {
2571 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2572 delete u.val_id;
2573 u.val_Int = new int_val_t(p_val_int);
2574 valuetype = V_INT;
2575 } else FATAL_ERROR("Value::set_valuetype()");
2576 }
2577
2578 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2579 {
2580 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2581 clean_up();
2582 valuetype = V_BSTR;
2583 set_val_str(p_str);
2584 } else FATAL_ERROR("Value::set_valuetype()");
2585 }
2586
2587 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2588 {
2589 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2590 delete u.val_id;
2591 u.val_id = p_id;
2592 valuetype = V_ENUM;
2593 } else FATAL_ERROR("Value::set_valuetype()");
2594 }
2595
2596 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2597 {
2598 switch (p_valuetype) {
2599 case V_FUNCTION:
2600 case V_ALTSTEP:
2601 case V_TESTCASE:
2602 if (valuetype == V_REFER && p_ass) break;
2603 // no break
2604 default:
2605 FATAL_ERROR("Value::set_valuetype()");
2606 }
2607 delete u.refered;
2608 u.refd_fat = p_ass;
2609 valuetype = p_valuetype;
2610 }
2611
2612 bool Value::is_undef_lowerid()
2613 {
2614 switch (valuetype) {
2615 case V_UNDEF_LOWERID:
2616 return true;
2617 case V_EXPR:
2618 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2619 !u.expr.ti1->get_DerivedRef()) {
2620 return u.expr.ti1->get_Template()->is_undef_lowerid();
2621 }
2622 // no break
2623 default:
2624 return false;
2625 }
2626 }
2627
2628 const Identifier& Value::get_undef_lowerid()
2629 {
2630 switch (valuetype) {
2631 case V_UNDEF_LOWERID:
2632 return *u.val_id;
2633 case V_EXPR:
2634 if (u.expr.v_optype != OPTYPE_VALUEOF)
2635 FATAL_ERROR("Value::get_undef_lowerid()");
2636 return u.expr.ti1->get_Template()->get_specific_value()
2637 ->get_undef_lowerid();
2638 default:
2639 FATAL_ERROR("Value::get_undef_lowerid()");
2640 }
2641 const Identifier *dummy = 0;
2642 return *dummy;
2643 }
2644
2645 void Value::set_lowerid_to_ref()
2646 {
2647 switch (valuetype) {
2648 case V_UNDEF_LOWERID:
2649 set_valuetype(V_REFD);
2650 break;
2651 case V_EXPR:
2652 // if the governor of the expression is not known (in log(), etc...)
2653 // then the governor is taken from the reference (using
2654 // v1/ti1->get_expr_governor()), but that runs before the
2655 // params were checked, this smells like a workaround :)
2656 switch (u.expr.v_optype) {
2657 case OPTYPE_ROTL:
2658 case OPTYPE_ROTR:
2659 u.expr.v1->set_lowerid_to_ref();
2660 break;
2661 case OPTYPE_CONCAT:
2662 u.expr.v1->set_lowerid_to_ref();
2663 u.expr.v2->set_lowerid_to_ref();
2664 break;
2665 case OPTYPE_VALUEOF:
2666 case OPTYPE_ISVALUE:
2667 case OPTYPE_ISBOUND:
2668 case OPTYPE_ISPRESENT:
2669 case OPTYPE_SUBSTR:
2670 case OPTYPE_REGEXP:
2671 case OPTYPE_REPLACE:
2672 case OPTYPE_TTCN2STRING:
2673 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2674 Error_Context cntxt(u.expr.ti1->get_Template(),
2675 "In the operand of operation `%s'",
2676 get_opname());
2677 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2678 }
2679 if (u.expr.v_optype==OPTYPE_REGEXP) {
2680 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2681 Error_Context cntxt(u.expr.t2->get_Template(),
2682 "In the operand of operation `%s'",
2683 get_opname());
2684 u.expr.t2->get_Template()->set_lowerid_to_ref();
2685 }
2686 }
2687 if (u.expr.v_optype==OPTYPE_REPLACE) {
2688 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2689 Error_Context cntxt(u.expr.ti4->get_Template(),
2690 "In the operand of operation `%s'",
2691 get_opname());
2692 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2693 }
2694 }
2695 break;
2696 default:
2697 break;
2698 }
2699 break;
2700 default:
2701 break;
2702 }
2703 }
2704
2705 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2706 {
2707 switch (valuetype) {
2708 case V_CHARSYMS:
2709 case V_CHOICE:
2710 case V_SEQOF:
2711 case V_SETOF:
2712 case V_ARRAY:
2713 case V_SEQ:
2714 case V_SET:
2715 case V_UNDEF_LOWERID:
2716 case V_UNDEF_BLOCK:
2717 case V_OMIT:
2718 case V_TTCN3_NULL:
2719 case V_NOTUSED:
2720 case V_REFER:
2721 case V_FAT_NULL:
2722 return Type::T_UNDEF;
2723 case V_NAMEDINT:
2724 case V_NAMEDBITS:
2725 case V_OPENTYPE:
2726 FATAL_ERROR("Value::get_expr_returntype()");
2727 case V_ERROR:
2728 return Type::T_ERROR;
2729 case V_REFD:
2730 case V_INVOKE: {
2731 Type *t = get_expr_governor(exp_val);
2732 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2733 else return Type::T_ERROR; }
2734 case V_FUNCTION:
2735 return Type::T_FUNCTION;
2736 case V_ALTSTEP:
2737 return Type::T_ALTSTEP;
2738 case V_TESTCASE:
2739 return Type::T_TESTCASE;
2740 case V_EXPR:
2741 switch(u.expr.v_optype) {
2742 case OPTYPE_COMP_NULL:
2743 case OPTYPE_COMP_MTC:
2744 case OPTYPE_COMP_SYSTEM:
2745 case OPTYPE_COMP_SELF:
2746 case OPTYPE_COMP_CREATE:
2747 return Type::T_COMPONENT;
2748 case OPTYPE_UNDEF_RUNNING:
2749 case OPTYPE_COMP_RUNNING:
2750 case OPTYPE_COMP_RUNNING_ANY:
2751 case OPTYPE_COMP_RUNNING_ALL:
2752 case OPTYPE_COMP_ALIVE:
2753 case OPTYPE_COMP_ALIVE_ANY:
2754 case OPTYPE_COMP_ALIVE_ALL:
2755 case OPTYPE_TMR_RUNNING:
2756 case OPTYPE_TMR_RUNNING_ANY:
2757 case OPTYPE_MATCH:
2758 case OPTYPE_EQ:
2759 case OPTYPE_LT:
2760 case OPTYPE_GT:
2761 case OPTYPE_NE:
2762 case OPTYPE_GE:
2763 case OPTYPE_LE:
2764 case OPTYPE_NOT:
2765 case OPTYPE_AND:
2766 case OPTYPE_OR:
2767 case OPTYPE_XOR:
2768 case OPTYPE_ISPRESENT:
2769 case OPTYPE_ISCHOSEN:
2770 case OPTYPE_ISCHOSEN_V:
2771 case OPTYPE_ISCHOSEN_T:
2772 case OPTYPE_ISVALUE:
2773 case OPTYPE_ISBOUND:
2774 case OPTYPE_PROF_RUNNING:
2775 return Type::T_BOOL;
2776 case OPTYPE_GETVERDICT:
2777 return Type::T_VERDICT;
2778 case OPTYPE_VALUEOF: {
2779 Error_Context cntxt(this, "In the operand of operation `%s'",
2780 get_opname());
2781 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2782 case OPTYPE_TMR_READ:
2783 case OPTYPE_INT2FLOAT:
2784 case OPTYPE_STR2FLOAT:
2785 case OPTYPE_RND:
2786 case OPTYPE_RNDWITHVAL:
2787 return Type::T_REAL;
2788 case OPTYPE_ACTIVATE:
2789 return Type::T_DEFAULT;
2790 case OPTYPE_ACTIVATE_REFD:
2791 return Type::T_DEFAULT;
2792 case OPTYPE_EXECUTE:
2793 case OPTYPE_EXECUTE_REFD:
2794 return Type::T_VERDICT;
2795 case OPTYPE_UNARYPLUS: // v1
2796 case OPTYPE_UNARYMINUS: {
2797 Type::typetype_t tmp_tt;
2798 {
2799 Error_Context cntxt(this, "In the operand of operation `%s'",
2800 get_opname());
2801 u.expr.v1->set_lowerid_to_ref();
2802 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2803 }
2804 switch(tmp_tt) {
2805 case Type::T_INT:
2806 case Type::T_REAL:
2807 return tmp_tt;
2808 default:
2809 get_value_refd_last(); // to report the error
2810 return Type::T_ERROR;
2811 } // switch tmp_tt
2812 }
2813 case OPTYPE_ADD: // v1 v2
2814 case OPTYPE_SUBTRACT:
2815 case OPTYPE_MULTIPLY:
2816 case OPTYPE_DIVIDE: {
2817 Type::typetype_t tmp_tt;
2818 {
2819 Error_Context cntxt(this, "In the left operand of operation `%s'",
2820 get_opname());
2821 u.expr.v1->set_lowerid_to_ref();
2822 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2823 }
2824 switch(tmp_tt) {
2825 case Type::T_INT:
2826 case Type::T_REAL:
2827 return tmp_tt;
2828 default:
2829 if(u.expr.v_optype==OPTYPE_ADD) {
2830 Type::typetype_t tmp_tt2;
2831 {
2832 Error_Context cntxt(this, "In the right operand of operation `%s'",
2833 get_opname());
2834 u.expr.v2->set_lowerid_to_ref();
2835 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2836 }
2837 Type::typetype_t ret_val=Type::T_ERROR;
2838 bool maybeconcat=false;
2839 switch(tmp_tt) {
2840 case Type::T_BSTR:
2841 case Type::T_HSTR:
2842 case Type::T_OSTR:
2843 if(tmp_tt2==tmp_tt) {
2844 maybeconcat=true;
2845 ret_val=tmp_tt;
2846 }
2847 break;
2848 case Type::T_CSTR:
2849 case Type::T_USTR:
2850 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2851 maybeconcat=true;
2852 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2853 ret_val=Type::T_USTR;
2854 else ret_val=Type::T_CSTR;
2855 }
2856 break;
2857 default:
2858 break;
2859 }
2860 if(maybeconcat) {
2861 error("Did you mean the concat operation (`&') instead of"
2862 " addition operator (`+')?");
2863 u.expr.v_optype=OPTYPE_CONCAT;
2864 return ret_val;
2865 }
2866 }
2867 get_value_refd_last(); // to report the error
2868 return Type::T_ERROR;
2869 } // switch tmp_tt
2870 }
2871 case OPTYPE_NOT4B: // v1
2872 case OPTYPE_AND4B: // v1 v2
2873 case OPTYPE_OR4B:
2874 case OPTYPE_XOR4B:
2875 case OPTYPE_SHL:
2876 case OPTYPE_SHR: {
2877 Type::typetype_t tmp_tt;
2878 {
2879 Error_Context cntxt(this, "In the %soperand of operation `%s'",
2880 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
2881 get_opname());
2882 u.expr.v1->set_lowerid_to_ref();
2883 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2884 }
2885 switch(tmp_tt) {
2886 case Type::T_BSTR:
2887 case Type::T_HSTR:
2888 case Type::T_OSTR:
2889 return tmp_tt;
2890 default:
2891 get_value_refd_last(); // to report the error
2892 return Type::T_ERROR;
2893 } // switch tmp_tt
2894 }
2895 case OPTYPE_ROTL: // v1 v2
2896 case OPTYPE_ROTR: {
2897 Type::typetype_t tmp_tt;
2898 {
2899 Error_Context cntxt(this, "In the %s operand of operation `%s'",
2900 u.expr.v_optype==OPTYPE_ROTL
2901 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
2902 get_opname());
2903 u.expr.v1->set_lowerid_to_ref();
2904 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2905 }
2906 switch(tmp_tt) {
2907 case Type::T_BSTR:
2908 case Type::T_HSTR:
2909 case Type::T_OSTR:
2910 case Type::T_CSTR:
2911 case Type::T_USTR:
2912 case Type::T_SETOF:
2913 case Type::T_SEQOF:
2914 case Type::T_ARRAY:
2915 return tmp_tt;
2916 default:
2917 get_value_refd_last(); // to report the error
2918 return Type::T_ERROR;
2919 } // switch tmp_tt
2920 }
2921 case OPTYPE_SUBSTR:
2922 case OPTYPE_REPLACE: {
2923 Type::typetype_t tmp_tt;
2924 {
2925 Error_Context cntxt(this, "In the operand of operation `%s'",
2926 get_opname());
2927 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2928 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2929 }
2930 switch (tmp_tt) {
2931 case Type::T_BSTR:
2932 case Type::T_HSTR:
2933 case Type::T_OSTR:
2934 case Type::T_CSTR:
2935 case Type::T_USTR:
2936 case Type::T_SETOF:
2937 case Type::T_SEQOF:
2938 return tmp_tt;
2939 default:
2940 get_value_refd_last(); // to report the error
2941 return Type::T_ERROR;
2942 }
2943 }
2944 case OPTYPE_REGEXP: {
2945 Type::typetype_t tmp_tt;
2946 {
2947 Error_Context cntxt(this, "In the first operand of operation `%s'",
2948 get_opname());
2949 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2950 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2951 }
2952 switch(tmp_tt) {
2953 case Type::T_CSTR:
2954 case Type::T_USTR:
2955 return tmp_tt;
2956 default:
2957 get_value_refd_last(); // to report the error
2958 return Type::T_ERROR;
2959 } // switch tmp_tt
2960 }
2961 case OPTYPE_CONCAT: { // v1 v2
2962 Type::typetype_t tmp_tt;
2963 {
2964 Error_Context cntxt(this, "In the first operand of operation `%s'",
2965 get_opname());
2966 u.expr.v1->set_lowerid_to_ref();
2967 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2968 }
2969 switch(tmp_tt) {
2970 case Type::T_CSTR:
2971 case Type::T_USTR:
2972 case Type::T_BSTR:
2973 case Type::T_HSTR:
2974 case Type::T_OSTR:
2975 case Type::T_SETOF:
2976 case Type::T_SEQOF:
2977 return tmp_tt;
2978 default:
2979 get_value_refd_last(); // to report the error
2980 return Type::T_ERROR;
2981 } // switch tmp_tt
2982 }
2983 case OPTYPE_MOD:
2984 case OPTYPE_REM:
2985 case OPTYPE_CHAR2INT:
2986 case OPTYPE_UNICHAR2INT:
2987 case OPTYPE_BIT2INT:
2988 case OPTYPE_HEX2INT:
2989 case OPTYPE_OCT2INT:
2990 case OPTYPE_STR2INT:
2991 case OPTYPE_FLOAT2INT:
2992 case OPTYPE_LENGTHOF:
2993 case OPTYPE_SIZEOF:
2994 case OPTYPE_DECODE:
2995 case OPTYPE_ENUM2INT:
2996 return Type::T_INT;
2997 case OPTYPE_BIT2STR:
2998 case OPTYPE_FLOAT2STR:
2999 case OPTYPE_HEX2STR:
3000 case OPTYPE_INT2CHAR:
3001 case OPTYPE_INT2STR:
3002 case OPTYPE_OCT2CHAR:
3003 case OPTYPE_OCT2STR:
3004 case OPTYPE_UNICHAR2CHAR:
3005 case OPTYPE_LOG2STR:
3006 case OPTYPE_TESTCASENAME:
3007 case OPTYPE_TTCN2STRING:
3008 case OPTYPE_GET_STRINGENCODING:
3009 case OPTYPE_ENCODE_BASE64:
3010 return Type::T_CSTR;
3011 case OPTYPE_INT2UNICHAR:
3012 case OPTYPE_OCT2UNICHAR:
3013 return Type::T_USTR;
3014 case OPTYPE_INT2BIT:
3015 case OPTYPE_HEX2BIT:
3016 case OPTYPE_OCT2BIT:
3017 case OPTYPE_STR2BIT:
3018 case OPTYPE_ENCODE:
3019 return Type::T_BSTR;
3020 case OPTYPE_INT2HEX:
3021 case OPTYPE_BIT2HEX:
3022 case OPTYPE_OCT2HEX:
3023 case OPTYPE_STR2HEX:
3024 return Type::T_HSTR;
3025 case OPTYPE_INT2OCT:
3026 case OPTYPE_CHAR2OCT:
3027 case OPTYPE_HEX2OCT:
3028 case OPTYPE_BIT2OCT:
3029 case OPTYPE_STR2OCT:
3030 case OPTYPE_UNICHAR2OCT:
3031 case OPTYPE_REMOVE_BOM:
3032 case OPTYPE_DECODE_BASE64:
3033 return Type::T_OSTR;
3034 case OPTYPE_DECOMP:
3035 return Type::T_OID;
3036 default:
3037 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3038 // to avoid warning
3039 return Type::T_ERROR;
3040 } // switch optype
3041 case V_MACRO:
3042 switch (u.macro) {
3043 case MACRO_MODULEID:
3044 case MACRO_FILENAME:
3045 case MACRO_BFILENAME:
3046 case MACRO_FILEPATH:
3047 case MACRO_LINENUMBER:
3048 case MACRO_DEFINITIONID:
3049 case MACRO_SCOPE:
3050 case MACRO_TESTCASEID:
3051 return Type::T_CSTR;
3052 case MACRO_LINENUMBER_C:
3053 return Type::T_INT;
3054 default:
3055 return Type::T_ERROR;
3056 }
3057 case V_NULL:
3058 return Type::T_NULL;
3059 case V_BOOL:
3060 return Type::T_BOOL;
3061 case V_INT:
3062 return Type::T_INT;
3063 case V_REAL:
3064 return Type::T_REAL;
3065 case V_ENUM:
3066 return Type::T_ENUM_T;
3067 case V_BSTR:
3068 return Type::T_BSTR;
3069 case V_HSTR:
3070 return Type::T_HSTR;
3071 case V_OSTR:
3072 return Type::T_OSTR;
3073 case V_CSTR:
3074 return Type::T_CSTR;
3075 case V_USTR:
3076 return Type::T_USTR;
3077 case V_ISO2022STR:
3078 return Type::T_GENERALSTRING;
3079 case V_OID:
3080 return Type::T_OID;
3081 case V_ROID:
3082 return Type::T_ROID;
3083 case V_VERDICT:
3084 return Type::T_VERDICT;
3085 case V_DEFAULT_NULL:
3086 return Type::T_DEFAULT;
3087 default:
3088 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3089 // to avoid warning
3090 return Type::T_ERROR;
3091 } // switch
3092 }
3093
3094 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3095 {
3096 if(my_governor) return my_governor;
3097 switch (valuetype) {
3098 case V_INVOKE: {
3099 Type *t = u.invoke.v->get_expr_governor(exp_val);
3100 if(!t) {
3101 if(u.invoke.v->get_valuetype() != V_ERROR)
3102 u.invoke.v->error("A value of type function expected");
3103 goto error;
3104 }
3105 t = t->get_type_refd_last();
3106 switch(t->get_typetype()) {
3107 case Type::T_FUNCTION: {
3108 Type *t_return_type = t->get_function_return_type();
3109 if (!t_return_type) {
3110 error("Reference to a %s was expected instead of invocation "
3111 "of behavior type `%s' with no return type",
3112 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3113 t->get_fullname().c_str());
3114 goto error;
3115 }
3116 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3117 error("Reference to a value was expected, but functions of type "
3118 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3119 t_return_type->get_typename().c_str());
3120 goto error;
3121 }
3122 return t_return_type; }
3123 case Type::T_ALTSTEP:
3124 goto error;
3125 default:
3126 u.invoke.v->error("A value of type function expected instead of `%s'",
3127 t->get_typename().c_str());
3128 goto error;
3129 }
3130 break; }
3131 case V_REFD: {
3132 Assignment *ass=u.ref.ref->get_refd_assignment();
3133 Type *tmp_type=0;
3134 if (!ass) goto error;
3135 switch (ass->get_asstype()) {
3136 case Assignment::A_CONST:
3137 case Assignment::A_EXT_CONST:
3138 case Assignment::A_MODULEPAR:
3139 case Assignment::A_MODULEPAR_TEMP:
3140 case Assignment::A_TEMPLATE:
3141 case Assignment::A_VAR:
3142 case Assignment::A_VAR_TEMPLATE:
3143 case Assignment::A_FUNCTION_RVAL:
3144 case Assignment::A_FUNCTION_RTEMP:
3145 case Assignment::A_EXT_FUNCTION_RVAL:
3146 case Assignment::A_EXT_FUNCTION_RTEMP:
3147 case Assignment::A_PAR_VAL_IN:
3148 case Assignment::A_PAR_VAL_OUT:
3149 case Assignment::A_PAR_VAL_INOUT:
3150 case Assignment::A_PAR_TEMPL_IN:
3151 case Assignment::A_PAR_TEMPL_OUT:
3152 case Assignment::A_PAR_TEMPL_INOUT:
3153 tmp_type=ass->get_Type();
3154 break;
3155 case Assignment::A_FUNCTION:
3156 case Assignment::A_EXT_FUNCTION:
3157 error("Reference to a %s was expected instead of a call of %s, which "
3158 "does not have return type",
3159 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3160 ass->get_description().c_str());
3161 goto error;
3162 default:
3163 error("Reference to a %s was expected instead of %s",
3164 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3165 ass->get_description().c_str());
3166 goto error;
3167 } // end switch
3168 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3169 if(!tmp_type) goto error;
3170 return tmp_type; }
3171 case V_EXPR:
3172 switch (u.expr.v_optype) {
3173 case OPTYPE_VALUEOF:
3174 case OPTYPE_SUBSTR:
3175 case OPTYPE_REGEXP:
3176 case OPTYPE_REPLACE:{
3177 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3178 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3179 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3180 return tmp_type;
3181 }
3182 case OPTYPE_ROTL:
3183 case OPTYPE_ROTR:
3184 return u.expr.v1->get_expr_governor(exp_val);
3185 case OPTYPE_CONCAT:
3186 return get_expr_governor_v1v2(exp_val);
3187 case OPTYPE_COMP_MTC:
3188 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3189 else return 0;
3190 case OPTYPE_COMP_SYSTEM:
3191 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3192 else return 0;
3193 case OPTYPE_COMP_SELF:
3194 if (my_scope) {
3195 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3196 if (t_ros) return t_ros->get_component_type();
3197 else return 0;
3198 } else return 0;
3199 case OPTYPE_COMP_CREATE:
3200 return chk_expr_operand_comptyperef_create();
3201 default:
3202 break;
3203 }
3204 // no break
3205 default:
3206 return Type::get_pooltype(get_expr_returntype(exp_val));
3207 }
3208 error:
3209 set_valuetype(V_ERROR);
3210 return 0;
3211 }
3212
3213 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3214 {
3215 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3216 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3217 if (v1_gov) {
3218 if (v2_gov) { // both have governors
3219 // return the type that is compatible with both (if there is no type mismatch)
3220 if (v1_gov->is_compatible(v2_gov, NULL))
3221 return v1_gov;
3222 else return v2_gov;
3223 } else return v1_gov;
3224 } else { // v1 has no governor
3225 if (v2_gov) return v2_gov;
3226 else return NULL; // neither has governor
3227 }
3228 }
3229
3230 Type *Value::get_expr_governor_last()
3231 {
3232 Value *v_last = get_value_refd_last();
3233 if (v_last->valuetype == V_ERROR) return 0;
3234 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3235 if(!t) return 0;
3236 return t->get_type_refd_last();
3237 }
3238
3239 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3240 {
3241 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3242 return u.invoke.v->get_expr_governor(exp_val);
3243 }
3244
3245 const char* Value::get_opname() const
3246 {
3247 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3248 switch(u.expr.v_optype) {
3249 case OPTYPE_RND: // -
3250 return "rnd()";
3251 case OPTYPE_COMP_NULL:
3252 return "(component) null";
3253 case OPTYPE_COMP_MTC:
3254 return "mtc";
3255 case OPTYPE_COMP_SYSTEM:
3256 return "system";
3257 case OPTYPE_COMP_SELF:
3258 return "self";
3259 case OPTYPE_COMP_RUNNING_ANY:
3260 return "any component.running";
3261 case OPTYPE_COMP_RUNNING_ALL:
3262 return "all component.running";
3263 case OPTYPE_COMP_ALIVE_ANY:
3264 return "any component.alive";
3265 case OPTYPE_COMP_ALIVE_ALL:
3266 return "all component.alive";
3267 case OPTYPE_TMR_RUNNING_ANY:
3268 return "any timer.running";
3269 case OPTYPE_GETVERDICT:
3270 return "getverdict()";
3271 case OPTYPE_TESTCASENAME:
3272 return "testcasename()";
3273 case OPTYPE_UNARYPLUS: // v1
3274 return "unary +";
3275 case OPTYPE_UNARYMINUS:
3276 return "unary -";
3277 case OPTYPE_NOT:
3278 return "not";
3279 case OPTYPE_NOT4B:
3280 return "not4b";
3281 case OPTYPE_BIT2HEX:
3282 return "bit2hex()";
3283 case OPTYPE_BIT2INT:
3284 return "bit2int()";
3285 case OPTYPE_BIT2OCT:
3286 return "bit2oct()";
3287 case OPTYPE_BIT2STR:
3288 return "bit2str()";
3289 case OPTYPE_CHAR2INT:
3290 return "char2int()";
3291 case OPTYPE_CHAR2OCT:
3292 return "char2oct()";
3293 case OPTYPE_FLOAT2INT:
3294 return "float2int()";
3295 case OPTYPE_FLOAT2STR:
3296 return "float2str()";
3297 case OPTYPE_HEX2BIT:
3298 return "hex2bit()";
3299 case OPTYPE_HEX2INT:
3300 return "hex2int()";
3301 case OPTYPE_HEX2OCT:
3302 return "hex2oct()";
3303 case OPTYPE_HEX2STR:
3304 return "hex2str()";
3305 case OPTYPE_INT2CHAR:
3306 return "int2char()";
3307 case OPTYPE_INT2FLOAT:
3308 return "int2float()";
3309 case OPTYPE_INT2STR:
3310 return "int2str()";
3311 case OPTYPE_INT2UNICHAR:
3312 return "int2unichar()";
3313 case OPTYPE_OCT2BIT:
3314 return "oct2bit()";
3315 case OPTYPE_OCT2CHAR:
3316 return "oct2char()";
3317 case OPTYPE_OCT2HEX:
3318 return "oct2hex()";
3319 case OPTYPE_OCT2INT:
3320 return "oct2int()";
3321 case OPTYPE_OCT2STR:
3322 return "oct2str()";
3323 case OPTYPE_STR2BIT:
3324 return "str2bit()";
3325 case OPTYPE_STR2FLOAT:
3326 return "str2float()";
3327 case OPTYPE_STR2HEX:
3328 return "str2hex()";
3329 case OPTYPE_STR2INT:
3330 return "str2int()";
3331 case OPTYPE_STR2OCT:
3332 return "str2oct()";
3333 case OPTYPE_UNICHAR2INT:
3334 return "unichar2int()";
3335 case OPTYPE_UNICHAR2CHAR:
3336 return "unichar2char()";
3337 case OPTYPE_UNICHAR2OCT:
3338 return "unichar2oct()";
3339 case OPTYPE_ENUM2INT:
3340 return "enum2int()";
3341 case OPTYPE_LENGTHOF:
3342 return "lengthof()";
3343 case OPTYPE_SIZEOF:
3344 return "sizeof()";
3345 case OPTYPE_RNDWITHVAL:
3346 return "rnd (seed)";
3347 case OPTYPE_ENCODE:
3348 return "encvalue()";
3349 case OPTYPE_DECODE:
3350 return "decvalue()";
3351 case OPTYPE_GET_STRINGENCODING:
3352 return "get_stringencoding()";
3353 case OPTYPE_REMOVE_BOM:
3354 return "remove_bom()";
3355 case OPTYPE_ENCODE_BASE64:
3356 return "encode_base64()";
3357 case OPTYPE_DECODE_BASE64:
3358 return "decode_base64()";
3359 case OPTYPE_ADD: // v1 v2
3360 return "+";
3361 case OPTYPE_SUBTRACT:
3362 return "-";
3363 case OPTYPE_MULTIPLY:
3364 return "*";
3365 case OPTYPE_DIVIDE:
3366 return "/";
3367 case OPTYPE_MOD:
3368 return "mod";
3369 case OPTYPE_REM:
3370 return "rem";
3371 case OPTYPE_CONCAT:
3372 return "&";
3373 case OPTYPE_EQ:
3374 return "==";
3375 case OPTYPE_LT:
3376 return "<";
3377 case OPTYPE_GT:
3378 return ">";
3379 case OPTYPE_NE:
3380 return "!=";
3381 case OPTYPE_GE:
3382 return ">=";
3383 case OPTYPE_LE:
3384 return "<=";
3385 case OPTYPE_AND:
3386 return "and";
3387 case OPTYPE_OR:
3388 return "or";
3389 case OPTYPE_XOR:
3390 return "xor";
3391 case OPTYPE_AND4B:
3392 return "and4b";
3393 case OPTYPE_OR4B:
3394 return "or4b";
3395 case OPTYPE_XOR4B:
3396 return "xor4b";
3397 case OPTYPE_SHL:
3398 return "<<";
3399 case OPTYPE_SHR:
3400 return ">>";
3401 case OPTYPE_ROTL:
3402 return "<@";
3403 case OPTYPE_ROTR:
3404 return "@>";
3405 case OPTYPE_INT2BIT:
3406 return "int2bit()";
3407 case OPTYPE_INT2HEX:
3408 return "int2hex()";
3409 case OPTYPE_INT2OCT:
3410 return "int2oct()";
3411 case OPTYPE_OCT2UNICHAR:
3412 return "oct2unichar()";
3413 case OPTYPE_SUBSTR:
3414 return "substr()";
3415 case OPTYPE_REGEXP:
3416 return "regexp()";
3417 case OPTYPE_DECOMP:
3418 return "decomp()";
3419 case OPTYPE_REPLACE:
3420 return "replace()";
3421 case OPTYPE_VALUEOF: // t1
3422 return "valueof()";
3423 case OPTYPE_UNDEF_RUNNING:
3424 return "<timer or component> running";
3425 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3426 return "create()";
3427 case OPTYPE_COMP_RUNNING: // v1
3428 return "component running";
3429 case OPTYPE_COMP_ALIVE: // v1
3430 return "alive";
3431 case OPTYPE_TMR_READ:
3432 return "timer read";
3433 case OPTYPE_TMR_RUNNING:
3434 return "timer running";
3435 case OPTYPE_ACTIVATE:
3436 return "activate()";
3437 case OPTYPE_ACTIVATE_REFD:
3438 return "activate()";
3439 case OPTYPE_EXECUTE: // r1 [v2]
3440 case OPTYPE_EXECUTE_REFD:
3441 return "execute()";
3442 case OPTYPE_MATCH: // v1 t2
3443 return "match()";
3444 case OPTYPE_ISPRESENT:
3445 return "ispresent()";
3446 case OPTYPE_ISCHOSEN:
3447 case OPTYPE_ISCHOSEN_V:
3448 case OPTYPE_ISCHOSEN_T:
3449 return "ischosen()";
3450 case OPTYPE_ISVALUE:
3451 return "isvalue()";
3452 case OPTYPE_ISBOUND:
3453 return "isbound()";
3454 case OPTYPE_LOG2STR:
3455 return "log2str()";
3456 case OPTYPE_TTCN2STRING:
3457 return "ttcn2string()";
3458 case OPTYPE_PROF_RUNNING:
3459 return "@profiler.running";
3460 default:
3461 FATAL_ERROR("Value::get_opname()");
3462 } // switch
3463 }
3464
3465 void Value::chk_expr_ref_ischosen()
3466 {
3467 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3468 Ttcn::Ref_base *tmpref=u.expr.r1;
3469 Assignment *ass=tmpref->get_refd_assignment();
3470 if (!ass) {
3471 set_valuetype(V_ERROR);
3472 return;
3473 }
3474 // Now we know whether the argument of ischosen() is a value or template.
3475 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3476 // or template (OPTYPE_ISCHOSEN_T).
3477 switch (ass->get_asstype()) {
3478 case Assignment::A_CONST:
3479 case Assignment::A_EXT_CONST:
3480 case Assignment::A_MODULEPAR:
3481 case Assignment::A_VAR:
3482 case Assignment::A_PAR_VAL_IN:
3483 case Assignment::A_PAR_VAL_OUT:
3484 case Assignment::A_PAR_VAL_INOUT:
3485 u.expr.v1=new Value(V_REFD, tmpref);
3486 u.expr.v1->set_location(*tmpref);
3487 u.expr.v1->set_my_scope(get_my_scope());
3488 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3489 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3490 break;
3491 case Assignment::A_MODULEPAR_TEMP:
3492 case Assignment::A_TEMPLATE:
3493 case Assignment::A_VAR_TEMPLATE:
3494 case Assignment::A_PAR_TEMPL_IN:
3495 case Assignment::A_PAR_TEMPL_OUT:
3496 case Assignment::A_PAR_TEMPL_INOUT:
3497 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3498 u.expr.t1->set_location(*tmpref);
3499 u.expr.t1->set_my_scope(get_my_scope());
3500 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3501 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3502 break;
3503 default:
3504 tmpref->error("Reference to a value or template was expected instead of "
3505 "%s", ass->get_description().c_str());
3506 set_valuetype(V_ERROR);
3507 break;
3508 } // switch
3509 }
3510
3511 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3512 Type::expected_value_t exp_val)
3513 {
3514 v->set_lowerid_to_ref(); // can only be reference to enum
3515 Type *t = v->get_expr_governor(exp_val);
3516 if (v->valuetype==V_ERROR) return;
3517 if (!t) {
3518 v->error("Please use reference to an enumerated value as the operand of "
3519 "operation `%s'", get_opname());
3520 set_valuetype(V_ERROR);
3521 return;
3522 }
3523 t = t->get_type_refd_last();
3524 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3525 v->error("The operand of operation `%s' should be enumerated value", opname);
3526 set_valuetype(V_ERROR);
3527 }
3528 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3529 v->error("The operand of operation `%s' cannot be omit", opname);
3530 set_valuetype(V_ERROR);
3531 }
3532 }
3533
3534 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3535 const char *opnum,
3536 const char *opname,
3537 const Location *loc)
3538 {
3539 if(tt==Type::T_BOOL) return;
3540 if(tt!=Type::T_ERROR)
3541 loc->error("%s operand of operation `%s' should be boolean value",
3542 opnum, opname);
3543 set_valuetype(V_ERROR);
3544 }
3545
3546 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3547 const char *opnum,
3548 const char *opname,
3549 const Location *loc)
3550 {
3551 if(tt==Type::T_INT) return;
3552 if(tt!=Type::T_ERROR)
3553 loc->error("%s operand of operation `%s' should be integer value",
3554 opnum, opname);
3555 set_valuetype(V_ERROR);
3556 }
3557
3558 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3559 const char *opnum,
3560 const char *opname,
3561 const Location *loc)
3562 {
3563 if(tt==Type::T_REAL) return;
3564 else if(tt==Type::T_INT)
3565 loc->error("%s operand of operation `%s' should be float value."
3566 " Perhaps you missed an int2float() conversion function"
3567 " or `.0' at the end of the number",
3568 opnum, opname);
3569 else if(tt!=Type::T_ERROR)
3570 loc->error("%s operand of operation `%s' should be float value",
3571 opnum, opname);
3572 set_valuetype(V_ERROR);
3573 }
3574
3575 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3576 const char *opnum,
3577 const char *opname,
3578 const Location *loc)
3579 {
3580 switch(tt) {
3581 case Type::T_INT:
3582 case Type::T_REAL:
3583 return;
3584 default:
3585 break;
3586 }
3587 if(tt!=Type::T_ERROR)
3588 loc->error("%s operand of operation `%s' should be integer"
3589 " or float value",
3590 opnum, opname);
3591 set_valuetype(V_ERROR);
3592 }
3593
3594 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3595 const char *opnum,
3596 const char *opname,
3597 const Location *loc)
3598 {
3599 switch(tt) {
3600 case Type::T_INT:
3601 case Type::T_REAL:
3602 case Type::T_ENUM_T:
3603 return;
3604 default:
3605 break;
3606 }
3607 if(tt!=Type::T_ERROR)
3608 loc->error("%s operand of operation `%s' should be integer, float"
3609 " or enumerated value", opnum, opname);
3610 set_valuetype(V_ERROR);
3611 }
3612
3613 void Value::chk_expr_operandtype_list(Type* t,
3614 const char *opnum,
3615 const char *opname,
3616 const Location *loc,
3617 bool allow_array)
3618 {
3619 if (valuetype == V_ERROR) return;
3620 if (t->get_typetype() == Type::T_ERROR) {
3621 set_valuetype(V_ERROR);
3622 return;
3623 }
3624 if (!t->is_list_type(allow_array)) {
3625 loc->error("%s operand of operation `%s' should be a string, "
3626 "`record of'%s `set of'%s value", opnum, opname,
3627 allow_array ? "," : " or", allow_array ? " or array" : "");
3628 set_valuetype(V_ERROR);
3629 return;
3630 }
3631 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3632 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3633 TypeChain l_chain;
3634 TypeChain r_chain;
3635 if (my_governor && my_governor->is_list_type(allow_array)
3636 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3637 if (info.is_subtype_error()) {
3638 // this is ok.
3639 if (info.needs_conversion()) set_needs_conversion();
3640 } else
3641 if (!info.is_erroneous()) {
3642 error("%s operand of operation `%s' is of type `%s', but a value of "
3643 "type `%s' was expected here", opnum, opname,
3644 t->get_typename().c_str(), my_governor->get_typename().c_str());
3645 } else {
3646 error("%s", info.get_error_str_str().c_str());
3647 }
3648 } else {
3649 if (info.needs_conversion())
3650 set_needs_conversion();
3651 }
3652 }
3653
3654 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3655 const char *opnum,
3656 const char *opname,
3657 const Location *loc)
3658 {
3659 switch(tt) {
3660 case Type::T_CSTR:
3661 case Type::T_USTR:
3662 case Type::T_BSTR:
3663 case Type::T_HSTR:
3664 case Type::T_OSTR:
3665 return;
3666 default:
3667 break;
3668 }
3669 if(tt!=Type::T_ERROR)
3670 loc->error("%s operand of operation `%s' should be string value",
3671 opnum, opname);
3672 set_valuetype(V_ERROR);
3673 }
3674
3675 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3676 const char *opnum,
3677 const char *opname,
3678 const Location *loc)
3679 {
3680 switch(tt) {
3681 case Type::T_CSTR:
3682 case Type::T_USTR:
3683 return;
3684 default:
3685 break;
3686 }
3687 if(tt!=Type::T_ERROR)
3688 loc->error("%s operand of operation `%s' should be (universal)"
3689 " charstring value",
3690 opnum, opname);
3691 set_valuetype(V_ERROR);
3692 }
3693
3694 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3695 const char *opnum,
3696 const char *opname,
3697 const Location *loc)
3698 {
3699 if(tt==Type::T_CSTR) return;
3700 if(tt!=Type::T_ERROR)
3701 loc->error("%s operand of operation `%s' should be charstring value",
3702 opnum, opname);
3703 set_valuetype(V_ERROR);
3704 }
3705
3706 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3707 const char *opnum,
3708 const char *opname,
3709 const Location *loc)
3710 {
3711 switch(tt) {
3712 case Type::T_BSTR:
3713 case Type::T_HSTR:
3714 case Type::T_OSTR:
3715 return;
3716 default:
3717 break;
3718 }
3719 if(tt!=Type::T_ERROR)
3720 loc->error("%s operand of operation `%s' should be binary string value",
3721 opnum, opname);
3722 set_valuetype(V_ERROR);
3723 }
3724
3725 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3726 const char *opnum,
3727 const char *opname,
3728 const Location *loc)
3729 {
3730 if(tt==Type::T_BSTR) return;
3731 if(tt!=Type::T_ERROR)
3732 loc->error("%s operand of operation `%s' should be bitstring value",
3733 opnum, opname);
3734 set_valuetype(V_ERROR);
3735 }
3736
3737 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3738 const char *opnum,
3739 const char *opname,
3740 const Location *loc)
3741 {
3742 if(tt==Type::T_HSTR) return;
3743 if(tt!=Type::T_ERROR)
3744 loc->error("%s operand of operation `%s' should be hexstring value",
3745 opnum, opname);
3746 set_valuetype(V_ERROR);
3747 }
3748
3749 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3750 const char *opnum,
3751 const char *opname,
3752 const Location *loc)
3753 {
3754 if(tt==Type::T_OSTR) return;
3755 if(tt!=Type::T_ERROR)
3756 loc->error("%s operand of operation `%s' should be octetstring value",
3757 opnum, opname);
3758 set_valuetype(V_ERROR);
3759 }
3760
3761 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3762 Type::typetype_t tt2,
3763 const char *opname)
3764 {
3765 if(valuetype==V_ERROR) return;
3766 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3767 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3768 set_valuetype(V_ERROR);
3769 return;
3770 }
3771 if(tt1==tt2) return;
3772 error("The operands of operation `%s' should be of same type", opname);
3773 set_valuetype(V_ERROR);
3774 }
3775
3776 /* For predefined functions. */
3777 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3778 Type::typetype_t tt2,
3779 const char *opnum1,
3780 const char *opnum2,
3781 const char *opname)
3782 {
3783 if(valuetype==V_ERROR) return;
3784 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3785 set_valuetype(V_ERROR);
3786 return;
3787 }
3788 if(tt1==tt2) return;
3789 error("The %s and %s operands of operation `%s' should be of same type",
3790 opnum1, opnum2, opname);
3791 set_valuetype(V_ERROR);
3792 }
3793
3794 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3795 Value *v1, Value *v2,
3796 const char *opnum1,
3797 const char *opnum2)
3798 {
3799 start:
3800 if (valuetype == V_ERROR) return;
3801 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3802 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3803 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3804
3805 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3806 set_valuetype(V_ERROR);
3807 return;
3808 }
3809 if (tt1 == Type::T_UNDEF) {
3810 if (tt2 == Type::T_UNDEF) {
3811 if (v1->is_undef_lowerid()) {
3812 if (v2->is_undef_lowerid()) {
3813 Scope *scope = get_my_scope();
3814 Module *my_mod = scope->get_scope_mod();
3815 const Identifier& id1 = v1->get_undef_lowerid();
3816 if (scope->has_ass_withId(id1)
3817 || my_mod->has_imported_ass_withId(id1)) {
3818 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3819 * should examine this situation better, but now I suppose
3820 * the first is ref, not enum. */
3821 v1->set_lowerid_to_ref();
3822 goto start;
3823 } else {
3824 const Identifier& id2 = v2->get_undef_lowerid();
3825 if (scope->has_ass_withId(id2)
3826 || my_mod->has_imported_ass_withId(id2)) {
3827 v2->set_lowerid_to_ref();
3828 goto start;
3829 }
3830 }
3831 /* This is perhaps enum-enum, but it has no real
3832 * significance, so this should be an error. */
3833 } else {
3834 v1->set_lowerid_to_ref();
3835 goto start;
3836 }
3837 } else if (v2->is_undef_lowerid()) {
3838 v2->set_lowerid_to_ref();
3839 goto start;
3840 }
3841 error("Cannot determine the type of the operands in operation `%s'",
3842 get_opname());
3843 set_valuetype(V_ERROR);
3844 return;
3845 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3846 v1->set_lowerid_to_ref();
3847 goto start;
3848 } else {
3849 /* v1 is something undefined, but not lowerid; v2 has
3850 * returntype (perhaps also governor) */
3851 }
3852 } else if (tt2 == Type::T_UNDEF) {
3853 /* but tt1 is not undef */
3854 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3855 v2->set_lowerid_to_ref();
3856 goto start;
3857 } else {
3858 /* v2 is something undefined, but not lowerid; v1 has
3859 * returntype (perhaps also governor) */
3860 }
3861 }
3862
3863 /* Now undef_lower_id's are converted to references, or the other
3864 * value has governor; let's see the governors, if they exist. */
3865 Type *t1 = v1->get_expr_governor(exp_val);
3866 Type *t2 = v2->get_expr_governor(exp_val);
3867 if (t1) {
3868 if (t2) {
3869 // Both value has governor. Are they compatible? According to 7.1.2
3870 // and C.34 it's required to have the same root types for
3871 // OPTYPE_{CONCAT,REPLACE}.
3872 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3873 u.expr.v_optype == OPTYPE_REPLACE);
3874 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
3875 u.expr.v_optype == OPTYPE_REPLACE);
3876 TypeChain l_chain1, l_chain2;
3877 TypeChain r_chain1, r_chain2;
3878 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
3879 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
3880 if (!compat_t1 && !compat_t2) {
3881 if (!info1.is_erroneous() && !info2.is_erroneous()) {
3882 // the subtypes don't need to be compatible here
3883 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
3884 error("The operands of operation `%s' should be of compatible "
3885 "types", get_opname());
3886 set_valuetype(V_ERROR);
3887 } else {
3888 if (info1.needs_conversion() || info2.needs_conversion()) {
3889 set_needs_conversion(); // Avoid folding.
3890 return;
3891 }
3892 }
3893 } else {
3894 if (info1.is_erroneous())
3895 v1->error("%s", info1.get_error_str_str().c_str());
3896 else if (info2.is_erroneous())
3897 v2->error("%s", info2.get_error_str_str().c_str());
3898 set_valuetype(V_ERROR);
3899 }
3900 return;
3901 } else if (info1.needs_conversion() || info2.needs_conversion()) {
3902 set_needs_conversion(); // Avoid folding.
3903 return;
3904 }
3905 } else {
3906 // t1, no t2.
3907 v2->set_my_governor(t1);
3908 t1->chk_this_value_ref(v2);
3909 if (v2->valuetype == V_OMIT) {
3910 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3911 get_opname());
3912 v1->chk_expr_omit_comparison(exp_val);
3913 } else {
3914 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3915 get_opname());
3916 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3917 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3918 goto start;
3919 }
3920 }
3921 } else if (t2) {
3922 v1->set_my_governor(t2);
3923 t2->chk_this_value_ref(v1);
3924 if (v1->valuetype == V_OMIT) {
3925 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3926 get_opname());
3927 v2->chk_expr_omit_comparison(exp_val);
3928 } else {
3929 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3930 get_opname());
3931 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3932 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3933 goto start;
3934 }
3935 } else {
3936 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3937 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
3938 // Here, it cannot be that both are T_UNDEF.
3939 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3940 error("Please use reference as %s operand of operator `%s'",
3941 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
3942 set_valuetype(V_ERROR);
3943 return;
3944 }
3945 // Deny type compatibility if no governors found. The typetype_t must
3946 // be the same. TODO: How can this happen?
3947 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
3948 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
3949 error("The operands of operation `%s' should be of compatible types",
3950 get_opname());
3951 set_valuetype(V_ERROR);
3952 }
3953 }
3954 }
3955
3956 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
3957 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
3958 {
3959 if(valuetype==V_ERROR) return;
3960 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3961 Assignment *t_ass = ref->get_refd_assignment();
3962 if(!t_ass) goto error;
3963 switch(t_ass->get_asstype()) {
3964 case Assignment::A_TIMER:
3965 case Assignment::A_PAR_TIMER:
3966 u.expr.v_optype=OPTYPE_TMR_RUNNING;
3967 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
3968 chk_expr_dynamic_part(exp_val, true);
3969 break;
3970 case Assignment::A_CONST:
3971 case Assignment::A_EXT_CONST:
3972 case Assignment::A_MODULEPAR:
3973 case Assignment::A_VAR:
3974 case Assignment::A_FUNCTION_RVAL:
3975 case Assignment::A_EXT_FUNCTION_RVAL:
3976 case Assignment::A_PAR_VAL_IN:
3977 case Assignment::A_PAR_VAL_OUT:
3978 case Assignment::A_PAR_VAL_INOUT: {
3979 u.expr.v_optype = OPTYPE_COMP_RUNNING;
3980 Value* val = new Value(V_REFD, u.expr.r1);
3981 val->set_my_scope(my_scope);
3982 val->set_fullname(u.expr.r1->get_fullname());
3983 val->set_location(*u.expr.r1);
3984 u.expr.v1 = val;
3985 chk_expr_operand_compref(val, opnum, get_opname());
3986 chk_expr_dynamic_part(exp_val, false);
3987 break; }
3988 default:
3989 ref->error("%s operand of operation `%s' should be timer or"
3990 " component reference instead of %s",
3991 opnum, opname, t_ass->get_description().c_str());
3992 goto error;
3993 } // switch
3994 return;
3995 error:
3996 set_valuetype(V_ERROR);
3997 }
3998
3999 Type *Value::chk_expr_operand_comptyperef_create()
4000 {
4001 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4002 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4003 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4004 if (!t_ass) goto error;
4005 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4006 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4007 Type::EXPECTED_DYNAMIC_VALUE);
4008 if (!t_type) goto error;
4009 t_type = t_type->get_type_refd_last();
4010 if (t_type->get_typetype() == Type::T_COMPONENT) {
4011 if (my_governor) {
4012 Type *my_governor_last = my_governor->get_type_refd_last();
4013 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4014 !my_governor_last->is_compatible(t_type, NULL)) {
4015 u.expr.r1->error("Incompatible component types: operation "
4016 "`create' should refer to `%s' instead of "
4017 "`%s'",
4018 my_governor_last->get_typename().c_str(),
4019 t_type->get_typename().c_str());
4020 goto error;
4021 }
4022 }
4023 return t_type;
4024 } else {
4025 u.expr.r1->error("Type mismatch: reference to a component type was "
4026 "expected in operation `create' instead of `%s'",
4027 t_type->get_typename().c_str());
4028 }
4029 } else {
4030 u.expr.r1->error("Operation `create' should refer to a component type "
4031 "instead of %s", t_ass->get_description().c_str());
4032 }
4033 error:
4034 set_valuetype(V_ERROR);
4035 return NULL;
4036 }
4037
4038 void Value::chk_expr_comptype_compat()
4039 {
4040 if (valuetype != V_EXPR)
4041 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4042 if (!my_governor || !my_scope) return;
4043 Type *my_governor_last = my_governor->get_type_refd_last();
4044 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4045 Type *t_comptype;
4046 switch (u.expr.v_optype) {
4047 case OPTYPE_COMP_MTC:
4048 t_comptype = my_scope->get_mtc_system_comptype(false);
4049 break;
4050 case OPTYPE_COMP_SYSTEM:
4051 t_comptype = my_scope->get_mtc_system_comptype(true);
4052 break;
4053 case OPTYPE_COMP_SELF: {
4054 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4055 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4056 break; }
4057 default:
4058 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4059 t_comptype = 0;
4060 break;
4061 }
4062 if (t_comptype
4063 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4064 error("Incompatible component types: a component reference of "
4065 "type `%s' was expected, but `%s' has type `%s'",
4066 my_governor_last->get_typename().c_str(), get_opname(),
4067 t_comptype->get_typename().c_str());
4068 set_valuetype(V_ERROR);
4069 }
4070 }
4071
4072 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4073 const char *opname)
4074 {
4075 if(valuetype == V_ERROR) return;
4076 switch(val->get_valuetype()) {
4077 case V_INVOKE: {
4078 Error_Context cntxt(this, "In `%s' operation", opname);
4079 Value *v_last = val->get_value_refd_last();
4080 if(!v_last) goto error;
4081 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4082 if(!t) goto error;
4083 t = t->get_type_refd_last();
4084 if(t->get_typetype() != Type::T_COMPONENT) {
4085 v_last->error("%s operand of operation `%s': Type mismatch:"
4086 " component reference was expected instead of `%s'",
4087 opnum, opname, t->get_typename().c_str());
4088 goto error;
4089 }
4090 return; }
4091 case V_REFD: {
4092 Reference *ref = val->get_reference();
4093 Assignment *t_ass = ref->get_refd_assignment();
4094 Value *t_val = 0;
4095 if (!t_ass) goto error;
4096 switch(t_ass->get_asstype()) {
4097 case Assignment::A_CONST:
4098 t_val = t_ass->get_Value();
4099 // no break
4100 case Assignment::A_EXT_CONST:
4101 case Assignment::A_MODULEPAR:
4102 case Assignment::A_VAR:
4103 case Assignment::A_FUNCTION_RVAL:
4104 case Assignment::A_EXT_FUNCTION_RVAL:
4105 case Assignment::A_PAR_VAL_IN:
4106 case Assignment::A_PAR_VAL_OUT:
4107 case Assignment::A_PAR_VAL_INOUT: {
4108 Type *t_type=t_ass->get_Type()
4109 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4110 if(!t_type) goto error;
4111 t_type=t_type->get_type_refd_last();
4112 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4113 ref->error("%s operand of operation `%s': Type mismatch:"
4114 " component reference was expected instead of `%s'",
4115 opnum, opname, t_type->get_typename().c_str());
4116 goto error;
4117 }
4118 break;}
4119 default:
4120 ref->error("%s operand of operation `%s' should be"
4121 " component reference instead of %s",
4122 opnum, opname, t_ass->get_description().c_str());
4123 goto error;
4124 }
4125 if (t_val) {
4126 ReferenceChain refch(this, "While searching referenced value");
4127 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4128 if (!t_val) return;
4129 t_val = t_val->get_value_refd_last();
4130 if (t_val->valuetype != V_EXPR) return;
4131 switch (t_val->u.expr.v_optype) {
4132 case OPTYPE_COMP_NULL:
4133 ref->error("%s operand of operation `%s' refers to `null' component "
4134 "reference", opnum, opname);
4135 goto error;
4136 case OPTYPE_COMP_MTC:
4137 ref->error("%s operand of operation `%s' refers to the component "
4138 "reference of the `mtc'", opnum, opname);
4139 goto error;
4140 case OPTYPE_COMP_SYSTEM:
4141 ref->error("%s operand of operation `%s' refers to the component "
4142 "reference of the `system'", opnum, opname);
4143 goto error;
4144 default:
4145 break;
4146 }
4147 }
4148 return;}
4149 default:
4150 FATAL_ERROR("Value::chk_expr_operand_compref()");
4151 }
4152 error:
4153 set_valuetype(V_ERROR);
4154 }
4155
4156 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4157 const char *opnum,
4158 const char *opname)
4159 {
4160 if(valuetype==V_ERROR) return;
4161 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4162 Assignment *t_ass = ref->get_refd_assignment();
4163 if(!t_ass) goto error;
4164 switch(t_ass->get_asstype()) {
4165 case Assignment::A_TIMER: {
4166 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4167 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4168 Type::EXPECTED_DYNAMIC_VALUE);
4169 else if (ref->get_subrefs()) {
4170 ref->error("%s operand of operation `%s': "
4171 "Reference to single timer `%s' cannot have field or array "
4172 "sub-references", opnum, opname,
4173 t_ass->get_id().get_dispname().c_str());
4174 goto error;
4175 }
4176 break; }
4177 case Assignment::A_PAR_TIMER:
4178 if (ref->get_subrefs()) {
4179 ref->error("%s operand of operation `%s': "
4180 "Reference to %s cannot have field or array sub-references",
4181 opnum, opname, t_ass->get_description().c_str());
4182 goto error;
4183 }
4184 break;
4185 default:
4186 ref->error("%s operand of operation `%s' should be timer"
4187 " instead of %s",
4188 opnum, opname, t_ass->get_description().c_str());
4189 goto error;
4190 } // switch
4191 return;
4192 error:
4193 set_valuetype(V_ERROR);
4194 }
4195
4196 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4197 const char *,
4198 const char *opname)
4199 {
4200 if(valuetype==V_ERROR) return;
4201 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4202 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4203 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4204 Error_Context cntxt(this, "In `%s' operation", opname);
4205 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4206 }
4207
4208 void Value::chk_expr_operand_activate_refd(Value *val,
4209 Ttcn::TemplateInstances* t_list2,
4210 Ttcn::ActualParList *&parlist,
4211 const char *,
4212 const char *opname)
4213 {
4214 if(valuetype==V_ERROR) return;
4215 Error_Context cntxt(this, "In `%s' operation", opname);
4216 Type *t = val->get_expr_governor_last();
4217 if (t) {
4218 switch (t->get_typetype()) {
4219 case Type::T_ERROR:
4220 set_valuetype(V_ERROR);
4221 break;
4222 case Type::T_ALTSTEP: {
4223 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4224 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4225 if(is_erroneous) {
4226 delete parlist;
4227 parlist = 0;
4228 set_valuetype(V_ERROR);
4229 } else {
4230 parlist->set_fullname(get_fullname());
4231 parlist->set_my_scope(get_my_scope());
4232 if (!fp_list->chk_activate_argument(parlist,
4233 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4234 }
4235 break; }
4236 default:
4237 error("Reference to an altstep was expected in the argument of "
4238 "`derefers()' instead of `%s'", t->get_typename().c_str());
4239 set_valuetype(V_ERROR);
4240 break;
4241 }
4242 } else set_valuetype(V_ERROR);
4243 }
4244
4245 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4246 const char *,
4247 const char *opname)
4248 {
4249 if(valuetype==V_ERROR) return;
4250 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4251 Error_Context cntxt(this, "In `%s' operation", opname);
4252 Assignment *t_ass = ref->get_refd_assignment();
4253 bool error_flag = false;
4254 if (t_ass) {
4255 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4256 ref->error("Reference to a testcase was expected in the argument "
4257 "instead of %s", t_ass->get_description().c_str());
4258 error_flag = true;
4259 }
4260 } else error_flag = true;
4261 if (val) {
4262 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4263 Value *v_last = val->get_value_refd_last();
4264 switch (v_last->valuetype) {
4265 case V_REAL: {
4266 ttcn3float v_real = v_last->get_val_Real();
4267 if (v_real < 0.0) {
4268 val->error("The testcase guard timer has negative value: `%s'",
4269 Real2string(v_real).c_str());
4270 error_flag = true;
4271 }
4272 break; }
4273 case V_ERROR:
4274 error_flag = true;
4275 break;
4276 default:
4277 break;
4278 }
4279 }
4280 if (error_flag) set_valuetype(V_ERROR);
4281 }
4282
4283 void Value::chk_expr_operand_execute_refd(Value *v1,
4284 Ttcn::TemplateInstances* t_list2,
4285 Ttcn::ActualParList *&parlist,
4286 Value *v3,
4287 const char *,
4288 const char *opname)
4289 {
4290 if(valuetype==V_ERROR) return;
4291 Error_Context cntxt(this, "In `%s' operation", opname);
4292 Type *t = v1->get_expr_governor_last();
4293 if (t) {
4294 switch (t->get_typetype()) {
4295 case Type::T_ERROR:
4296 set_valuetype(V_ERROR);
4297 break;
4298 case Type::T_TESTCASE: {
4299 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4300 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4301 if(is_erroneous) {
4302 delete parlist;
4303 parlist = 0;
4304 set_valuetype(V_ERROR);
4305 } else {
4306 parlist->set_fullname(get_fullname());
4307 parlist->set_my_scope(get_my_scope());
4308 }
4309 break; }
4310 default:
4311 v1->error("Reference to a value of type testcase was expected in the "
4312 "argument of `derefers()' instead of `%s'",
4313 t->get_typename().c_str());
4314 set_valuetype(V_ERROR);
4315 break;
4316 }
4317 } else set_valuetype(V_ERROR);
4318 if (v3) {
4319 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4320 Value *v_last = v3->get_value_refd_last();
4321 switch (v_last->valuetype) {
4322 case V_REAL: {
4323 ttcn3float v_real = v_last->get_val_Real();
4324 if(v_real < 0.0) {
4325 v3->error("The testcase guard timer has negative value: `%s'",
4326 Real2string(v_real).c_str());
4327 set_valuetype(V_ERROR);
4328 }
4329 break; }
4330 case V_ERROR:
4331 set_valuetype(V_ERROR);
4332 break;
4333 default:
4334 break;
4335 }
4336 }
4337 }
4338
4339 void Value::chk_invoke(Type::expected_value_t exp_val)
4340 {
4341 if(valuetype == V_ERROR) return;
4342 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4343 if(!u.invoke.t_list) return; //already checked
4344 Error_Context cntxt(this, "In `apply()' operation");
4345 Type *t = u.invoke.v->get_expr_governor_last();
4346 if (!t) {
4347 set_valuetype(V_ERROR);
4348 return;
4349 }
4350 switch (t->get_typetype()) {
4351 case Type::T_ERROR:
4352 set_valuetype(V_ERROR);
4353 return;
4354 case Type::T_FUNCTION:
4355 break;
4356 default:
4357 u.invoke.v->error("A value of type function was expected in the "
4358 "argument instead of `%s'", t->get_typename().c_str());
4359 set_valuetype(V_ERROR);
4360 return;
4361 }
4362 my_scope->chk_runs_on_clause(t, *this, "call");
4363 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4364 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4365 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4366 delete u.invoke.t_list;
4367 u.invoke.t_list = 0;
4368 if(is_erroneous) {
4369 delete parlist;
4370 u.invoke.ap_list = 0;
4371 } else {
4372 parlist->set_fullname(get_fullname());
4373 parlist->set_my_scope(get_my_scope());
4374 u.invoke.ap_list = parlist;
4375 }
4376 switch (exp_val) {
4377 case Type::EXPECTED_CONSTANT:
4378 error("An evaluatable constant value was expected instead of operation "
4379 "`apply()'");
4380 set_valuetype(V_ERROR);
4381 break;
4382 case Type::EXPECTED_STATIC_VALUE:
4383 error("A static value was expected instead of operation `apply()'");
4384 set_valuetype(V_ERROR);
4385 break;
4386 default:
4387 break;
4388 } // switch
4389 }
4390
4391 void Value::chk_expr_eval_value(Value *val, Type &t,
4392 ReferenceChain *refch,
4393 Type::expected_value_t exp_val)
4394 {
4395 bool self_ref = false;
4396 if(valuetype==V_ERROR) return;
4397 // Commented out to report more errors :)
4398 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4399 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4400 switch(val->get_valuetype()) {
4401 case V_REFD:
4402 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4403 break;
4404 case V_EXPR:
4405 case V_MACRO:
4406 case V_INVOKE:
4407 val->get_value_refd_last(refch, exp_val);
4408 break;
4409 default:
4410 break;
4411 } // switch
4412 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4413
4414 (void)self_ref;
4415 }
4416
4417 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4418 ReferenceChain *refch, Type::expected_value_t exp_val)
4419 {
4420 bool self_ref = false;
4421 ti->chk(type);
4422 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4423 ti->error("Reference to a %s value was expected instead of an in-line "
4424 "modified template",
4425 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4426 set_valuetype(V_ERROR);
4427 return;
4428 }
4429 Template *templ = ti->get_Template();
4430 switch (templ->get_templatetype()) {
4431 case Template::TEMPLATE_REFD:
4432 // not foldable
4433 if (exp_val == Type::EXPECTED_TEMPLATE) {
4434 templ = templ->get_template_refd_last(refch);
4435 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4436 set_valuetype(V_ERROR);
4437 } else {
4438 ti->error("Reference to a %s value was expected instead of %s",
4439 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4440 templ->get_reference()->get_refd_assignment()
4441 ->get_description().c_str());
4442 set_valuetype(V_ERROR);
4443 }
4444 break;
4445 case Template::SPECIFIC_VALUE: {
4446 Value *val = templ->get_specific_value();
4447 switch (val->get_valuetype()) {
4448 case V_REFD:
4449 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4450 break;
4451 case V_EXPR:
4452 val->get_value_refd_last(refch, exp_val);
4453 default:
4454 break;
4455 } // switch
4456 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4457 break; }
4458 case Template::TEMPLATE_ERROR:
4459 set_valuetype(V_ERROR);
4460 break;
4461 default:
4462 break;
4463 } // switch
4464
4465 (void)self_ref;
4466 }
4467
4468 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4469 const char *opname)
4470 {
4471 if(valuetype==V_ERROR) return;
4472 if(u.expr.state==EXPR_CHECKING_ERR) return;
4473 if(val->is_unfoldable()) return;
4474 if(*val->get_val_Int()<0) {
4475 val->error("%s operand of operation `%s' should not be negative",
4476 opnum, opname);
4477 set_valuetype(V_ERROR);
4478 }
4479 }
4480
4481 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4482 const char *opname)
4483 {
4484 if(valuetype==V_ERROR) return;
4485 if(u.expr.state==EXPR_CHECKING_ERR) return;
4486 if(val->is_unfoldable()) return;
4487 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4488 val->error("%s operand of operation `%s' should be in range 0..127",
4489 opnum, opname);
4490 set_valuetype(V_ERROR);
4491 }
4492 }
4493
4494 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4495 const char *opname)
4496 {
4497 if(valuetype==V_ERROR) return;
4498 if(u.expr.state==EXPR_CHECKING_ERR) return;
4499 if(val->is_unfoldable()) return;
4500 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4501 val->error("%s operand of operation `%s' should be in range"
4502 " 0..2147483647", opnum, opname);
4503 set_valuetype(V_ERROR);
4504 }
4505 }
4506
4507 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4508 const char *opname)
4509 {
4510 if(valuetype==V_ERROR) return;
4511 if(u.expr.state==EXPR_CHECKING_ERR) return;
4512 if(val->is_unfoldable()) return;
4513 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4514 ||
4515 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4516 {
4517 val->error("%s operand of operation `%s' should not be zero",
4518 opnum, opname);
4519 set_valuetype(V_ERROR);
4520 }
4521 }
4522
4523 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4524 const char *opname)
4525 {
4526 if (valuetype == V_ERROR) return;
4527 if (u.expr.state == EXPR_CHECKING_ERR) return;
4528 if (val->get_expr_returntype() != Type::T_INT) return;
4529 if (val->is_unfoldable()) return;
4530 const int_val_t *val_int = val->get_val_Int();
4531 if (*val_int > static_cast<Int>(INT_MAX)) {
4532 val->error("%s operand of operation `%s' should be less than `%d' "
4533 "instead of `%s'", opnum, opname, INT_MAX,
4534 (val_int->t_str()).c_str());
4535 set_valuetype(V_ERROR);
4536 }
4537 }
4538
4539 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4540 const char *opname)
4541 {
4542 if(valuetype==V_ERROR) return;
4543 if(u.expr.state==EXPR_CHECKING_ERR) return;
4544 if(val->is_unfoldable()) return;
4545 if(val->get_val_strlen()!=1) {
4546 val->error("%s operand of operation `%s' should be of length 1",
4547 opnum, opname);
4548 set_valuetype(V_ERROR);
4549 }
4550 }
4551
4552 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4553 const char *opname)
4554 {
4555 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4556 Value *v_last = val->get_value_refd_last();
4557 if (v_last->valuetype == V_CSTR) {
4558 size_t len = v_last->get_val_strlen();
4559 if (len % 2) {
4560 val->error("%s operand of operation `%s' should contain even number "
4561 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4562 set_valuetype(V_ERROR);
4563 }
4564 } else if (v_last->valuetype == V_REFD) {
4565 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4566 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4567 val->error("%s operand of operation `%s' should contain even number "
4568 "of characters, but a string element contains 1", opnum, opname);
4569 set_valuetype(V_ERROR);
4570 }
4571 }
4572 }
4573
4574 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4575 const char *opname)
4576 {
4577 if(valuetype==V_ERROR) return;
4578 if(u.expr.state==EXPR_CHECKING_ERR) return;
4579 if(val->is_unfoldable()) return;
4580 const string& s=val->get_val_str();
4581 for(size_t i=0; i<s.size(); i++) {
4582 char c=s[i];
4583 if(!(c=='0' || c=='1')) {
4584 val->error("%s operand of operation `%s' can contain only"
4585 " binary digits (position %lu is `%c')",
4586 opnum, opname, (unsigned long) i, c);
4587 set_valuetype(V_ERROR);
4588 return;
4589 }
4590 }
4591 }
4592
4593 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4594 const char *opname)
4595 {
4596 if(valuetype==V_ERROR) return;
4597 if(u.expr.state==EXPR_CHECKING_ERR) return;
4598 if(val->is_unfoldable()) return;
4599 const string& s=val->get_val_str();
4600 for(size_t i=0; i<s.size(); i++) {
4601 char c=s[i];
4602 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4603 val->error("%s operand of operation `%s' can contain only valid "
4604 "hexadecimal digits (position %lu is `%c')",
4605 opnum, opname, (unsigned long) i, c);
4606 set_valuetype(V_ERROR);
4607 return;
4608 }
4609 }
4610 }
4611
4612 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4613 const char *opname)
4614 {
4615 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4616 Value *v = val->get_value_refd_last();
4617 if (v->valuetype != V_OSTR) return;
4618 const string& s = val->get_val_str();
4619 size_t n_octets = s.size() / 2;
4620 for (size_t i = 0; i < n_octets; i++) {
4621 char c = s[2 * i];
4622 if (!(c >= '0' && c <= '7')) {
4623 val->error("%s operand of operation `%s' shall consist of octets "
4624 "within the range 00 .. 7F, but the string `%s'O contains octet "
4625 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4626 (unsigned long) i);
4627 set_valuetype(V_ERROR);
4628 return;
4629 }
4630 }
4631 }
4632
4633 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4634 const char *opname)
4635 {
4636 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4637 Value *v_last = val->get_value_refd_last();
4638 if (v_last->valuetype != V_CSTR) return;
4639 const string& s = v_last->get_val_str();
4640 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4641 state = S_INITIAL;
4642 // state: expected characters
4643 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4644 // S_FIRST: first digit
4645 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4646 // S_END: trailing whitespace
4647 // S_ERR: error was found, stop
4648 for (size_t i = 0; i < s.size(); i++) {
4649 char c = s[i];
4650 switch (state) {
4651 case S_INITIAL:
4652 case S_INITIAL_WS:
4653 if (c == '+' || c == '-') state = S_FIRST;
4654 else if (c == '0') state = S_ZERO;
4655 else if (c >= '1' && c <= '9') state = S_MORE;
4656 else if (string::is_whitespace(c)) {
4657 if (state == S_INITIAL) {
4658 val->warning("Leading whitespace was detected and ignored in the "
4659 "operand of operation `%s'", opname);
4660 state = S_INITIAL_WS;
4661 }
4662 } else state = S_ERR;
4663 break;
4664 case S_FIRST:
4665 if (c == '0') state = S_ZERO;
4666 else if (c >= '1' && c <= '9') state = S_MORE;
4667 else state = S_ERR;
4668 break;
4669 case S_ZERO:
4670 if (c >= '0' && c <= '9') {
4671 val->warning("Leading zero digit was detected and ignored in the "
4672 "operand of operation `%s'", opname);
4673 state = S_MORE;
4674 } else if (string::is_whitespace(c)) state = S_END;
4675 else state = S_ERR;
4676 break;
4677 case S_MORE:
4678 if (c >= '0' && c <= '9') {}
4679 else if (string::is_whitespace(c)) state = S_END;
4680 else state = S_ERR;
4681 break;
4682 case S_END:
4683 if (!string::is_whitespace(c)) state = S_ERR;
4684 break;
4685 default:
4686 break;
4687 }
4688 if (state == S_ERR) {
4689 if (string::is_printable(c)) {
4690 val->error("%s operand of operation `%s' should be a string "
4691 "containing a valid integer value, but invalid character `%c' "
4692 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4693 } else {
4694 val->error("%s operand of operation `%s' should be a string "
4695 "containing a valid integer value, but invalid character with "
4696 "character code %u was detected at index %lu", opnum, opname, c,
4697 (unsigned long) i);
4698 }
4699 set_valuetype(V_ERROR);
4700 break;
4701 }
4702 }
4703 switch (state) {
4704 case S_INITIAL:
4705 case S_INITIAL_WS:
4706 val->error("%s operand of operation `%s' should be a string containing a "
4707 "valid integer value instead of an empty string", opnum, opname);
4708 set_valuetype(V_ERROR);
4709 break;
4710 case S_FIRST:
4711 val->error("%s operand of operation `%s' should be a string containing a "
4712 "valid integer value, but only a sign character was detected", opnum,
4713 opname);
4714 set_valuetype(V_ERROR);
4715 break;
4716 case S_END:
4717 val->warning("Trailing whitespace was detected and ignored in the "
4718 "operand of operation `%s'", opname);
4719 break;
4720 default:
4721 break;
4722 }
4723 }
4724
4725 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4726 const char *opname)
4727 {
4728 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4729 Value *v_last = val->get_value_refd_last();
4730 if (v_last->valuetype == V_REFD) {
4731 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4732 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4733 val->error("%s operand of operation `%s' should be a string containing "
4734 "a valid float value instead of a string element, which cannot "
4735 "represent a floating point number", opnum, opname);
4736 set_valuetype(V_ERROR);
4737 }
4738 return;
4739 } else if (v_last->valuetype != V_CSTR) return;
4740 const string& s = v_last->get_val_str();
4741 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4742 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4743 state = S_INITIAL;
4744 // state: expected characters
4745 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4746 // leading whitespace
4747 // S_FIRST_M: first digit of integer part in mantissa
4748 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4749 // S_FIRST_F: first digit of fraction
4750 // S_MORE_F: more digits of fraction, E, trailing whitespace
4751 // S_INITIAL_E: +, -, first digit of exponent
4752 // S_FIRST_E: first digit of exponent
4753 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4754 // S_END: trailing whitespace
4755 // S_ERR: error was found, stop
4756 for (size_t i = 0; i < s.size(); i++) {
4757 char c = s[i];
4758 switch (state) {
4759 case S_INITIAL:
4760 case S_INITIAL_WS:
4761 if (c == '+' || c == '-') state = S_FIRST_M;
4762 else if (c == '0') state = S_ZERO_M;
4763 else if (c >= '1' && c <= '9') state = S_MORE_M;
4764 else if (string::is_whitespace(c)) {
4765 if (state == S_INITIAL) {
4766 val->warning("Leading whitespace was detected and ignored in the "
4767 "operand of operation `%s'", opname);
4768 state = S_INITIAL_WS;
4769 }
4770 } else state = S_ERR;
4771 break;
4772 case S_FIRST_M:
4773 if (c == '0') state = S_ZERO_M;
4774 else if (c >= '1' && c <= '9') state = S_MORE_M;
4775 else state = S_ERR;
4776 break;
4777 case S_ZERO_M:
4778 if (c == '.') state = S_FIRST_F;
4779 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4780 else if (c >= '0' && c <= '9') {
4781 val->warning("Leading zero digit was detected and ignored in the "
4782 "mantissa of the operand of operation `%s'", opname);
4783 state = S_MORE_M;
4784 } else state = S_ERR;
4785 break;
4786 case S_MORE_M:
4787 if (c == '.') state = S_FIRST_F;
4788 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4789 else if (c >= '0' && c <= '9') {}
4790 else state = S_ERR;
4791 break;
4792 case S_FIRST_F:
4793 if (c >= '0' && c <= '9') state = S_MORE_F;
4794 else state = S_ERR;
4795 break;
4796 case S_MORE_F:
4797 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4798 else if (c >= '0' && c <= '9') {}
4799 else if (string::is_whitespace(c)) state = S_END;
4800 else state = S_ERR;
4801 break;
4802 case S_INITIAL_E:
4803 if (c == '+' || c == '-') state = S_FIRST_E;
4804 else if (c == '0') state = S_ZERO_E;
4805 else if (c >= '1' && c <= '9') state = S_MORE_E;
4806 else state = S_ERR;
4807 break;
4808 case S_FIRST_E:
4809 if (c == '0') state = S_ZERO_E;
4810 else if (c >= '1' && c <= '9') state = S_MORE_E;
4811 else state = S_ERR;
4812 break;
4813 case S_ZERO_E:
4814 if (c >= '0' && c <= '9') {
4815 val->warning("Leading zero digit was detected and ignored in the "
4816 "exponent of the operand of operation `%s'", opname);
4817 state = S_MORE_E;
4818 } else if (string::is_whitespace(c)) state = S_END;
4819 else state = S_ERR;
4820 break;
4821 case S_MORE_E:
4822 if (c >= '0' && c <= '9') {}
4823 else if (string::is_whitespace(c)) state = S_END;
4824 else state = S_ERR;
4825 break;
4826 case S_END:
4827 if (!string::is_whitespace(c)) state = S_ERR;
4828 break;
4829 default:
4830 break;
4831 }
4832 if (state == S_ERR) {
4833 if (string::is_printable(c)) {
4834 val->error("%s operand of operation `%s' should be a string "
4835 "containing a valid float value, but invalid character `%c' "
4836 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4837 } else {
4838 val->error("%s operand of operation `%s' should be a string "
4839 "containing a valid float value, but invalid character with "
4840 "character code %u was detected at index %lu", opnum, opname, c,
4841 (unsigned long) i);
4842 }
4843 set_valuetype(V_ERROR);
4844 break;
4845 }
4846 }
4847 switch (state) {
4848 case S_INITIAL:
4849 case S_INITIAL_WS:
4850 val->error("%s operand of operation `%s' should be a string containing a "
4851 "valid float value instead of an empty string", opnum, opname);
4852 set_valuetype(V_ERROR);
4853 break;
4854 case S_FIRST_M:
4855 val->error("%s operand of operation `%s' should be a string containing a "
4856 "valid float value, but only a sign character was detected", opnum,
4857 opname);
4858 set_valuetype(V_ERROR);
4859 break;
4860 case S_ZERO_M:
4861 case S_MORE_M:
4862 // HL67862: Missing decimal dot allowed for str2float
4863 break;
4864 case S_FIRST_F:
4865 // HL67862: Missing fraction part is allowed for str2float
4866 break;
4867 case S_INITIAL_E:
4868 case S_FIRST_E:
4869 val->error("%s operand of operation `%s' should be a string containing a "
4870 "valid float value, but the exponent is missing after the `E' sign",
4871 opnum, opname);
4872 set_valuetype(V_ERROR);
4873 break;
4874 case S_END:
4875 val->warning("Trailing whitespace was detected and ignored in the "
4876 "operand of operation `%s'", opname);
4877 break;
4878 default:
4879 break;
4880 }
4881 }
4882
4883 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
4884 const char *opname)
4885 {
4886 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4887 Value *v = val->get_value_refd_last();
4888 if (v->valuetype != V_USTR) return;
4889 const ustring& us = v->get_val_ustr();
4890 for (size_t i = 0; i < us.size(); i++) {
4891 const ustring::universal_char& uchar = us[i];
4892 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
4893 uchar.cell > 127) {
4894 val->error("%s operand of operation `%s' shall consist of characters "
4895 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4896 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4897 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
4898 uchar.row, uchar.cell, (unsigned long) i);
4899 set_valuetype(V_ERROR);
4900 return;
4901 }
4902 }
4903 }
4904
4905 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
4906 const char *opname)
4907 {
4908 if(valuetype==V_ERROR) return;
4909 if(u.expr.state==EXPR_CHECKING_ERR) return;
4910 if(val->is_unfoldable()) return;
4911 const string& bstr=val->get_val_str();
4912 // see also PredefFunc.cc::bit2int()
4913 size_t nof_bits = bstr.size();
4914 // skip the leading zeros
4915 size_t start_index = 0;
4916 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
4917 // check whether the remaining bits fit in Int
4918 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
4919 val->error("%s operand of operation `%s' is too large (maximum number"
4920 " of bits in integer is %lu)",
4921 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4922 set_valuetype(V_ERROR);
4923 }
4924 }
4925
4926 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
4927 const char *opname)
4928 {
4929 if(valuetype==V_ERROR) return;
4930 if(u.expr.state==EXPR_CHECKING_ERR) return;
4931 if(val->is_unfoldable()) return;
4932 const string& hstr=val->get_val_str();
4933 // see also PredefFunc.cc::hex2int()
4934 size_t nof_digits = hstr.size();
4935 // skip the leading zeros
4936 size_t start_index = 0;
4937 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
4938 // check whether the remaining hex digits fit in Int
4939 if (nof_digits - start_index > 2 * sizeof(Int) ||
4940 (nof_digits - start_index == 2 * sizeof(Int) &&
4941 char_to_hexdigit(hstr[start_index]) > 7)) {
4942 val->error("%s operand of operation `%s' is too large (maximum number"
4943 " of bits in integer is %lu)",
4944 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4945 set_valuetype(V_ERROR);
4946 }
4947 }
4948
4949 void Value::chk_expr_operands_int2binstr()
4950 {
4951 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4952 if (u.expr.v1->is_unfoldable()) return;
4953 if (u.expr.v2->is_unfoldable()) return;
4954 // It is already checked that i1 and i2 are non-negative.
4955 Error_Context cntxt(this, "In operation `%s'", get_opname());
4956 const int_val_t *i1 = u.expr.v1->get_val_Int();
4957 const int_val_t *i2 = u.expr.v2->get_val_Int();
4958 if (!i2->is_native()) {
4959 u.expr.v2->error("The length of the resulting string is too large for "
4960 "being represented in memory");
4961 set_valuetype(V_ERROR);
4962 return;
4963 }
4964 Int nof_bits = i2->get_val();
4965 if (u.expr.v1->is_unfoldable()) return;
4966 switch (u.expr.v_optype) {
4967 case OPTYPE_INT2BIT:
4968 break;
4969 case OPTYPE_INT2HEX:
4970 nof_bits *= 4;
4971 break;
4972 case OPTYPE_INT2OCT:
4973 nof_bits *= 8;
4974 break;
4975 default:
4976 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4977 }
4978 if (*i1 >> nof_bits > 0) { // Expensive?
4979 u.expr.v1->error("Value %s does not fit in length %s",
4980 i1->t_str().c_str(), i2->t_str().c_str());
4981 set_valuetype(V_ERROR);
4982 }
4983 }
4984
4985 void Value::chk_expr_operands_str_samelen()
4986 {
4987 if(valuetype==V_ERROR) return;
4988 if(u.expr.state==EXPR_CHECKING_ERR) return;
4989 Value *v1=u.expr.v1;
4990 if(v1->is_unfoldable()) return;
4991 Value *v2=u.expr.v2;
4992 if(v2->is_unfoldable()) return;
4993 Error_Context cntxt(this, "In operation `%s'", get_opname());
4994 size_t i1=v1->get_val_strlen();
4995 size_t i2=v2->get_val_strlen();
4996 if(i1!=i2) {
4997 error("The operands should have the same length");
4998 set_valuetype(V_ERROR);
4999 }
5000 }
5001
5002 void Value::chk_expr_operands_replace()
5003 {
5004 // The fourth operand doesn't need to be checked at all here.
5005 if(valuetype==V_ERROR) return;
5006 if(u.expr.state==EXPR_CHECKING_ERR) return;
5007 Value* v1 = u.expr.ti1->get_specific_value();
5008 if (!v1) return;
5009
5010 Error_Context cntxt(this, "In operation `%s'", get_opname());
5011 size_t list_len = 0;
5012 bool list_len_known = false;
5013 if (v1->valuetype == V_REFD) {
5014 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5015 if (subrefs && subrefs->refers_to_string_element()) {
5016 warning("Replacing a string element does not make any sense");
5017 list_len = 1;
5018 list_len_known = true;
5019 }
5020 }
5021 if (!v1->is_unfoldable()) {
5022 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5023 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5024 list_len_known = true;
5025 }
5026 if (!list_len_known) return;
5027 if (u.expr.v2->is_unfoldable()) {
5028 if (!u.expr.v3->is_unfoldable()) {
5029 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5030 if (*len_int_3 > static_cast<Int>(list_len)) {
5031 error("Third operand `len' (%s) is greater than the length of "
5032 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5033 (unsigned long)list_len);
5034 set_valuetype(V_ERROR);
5035 }
5036 }
5037 } else {
5038 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5039 if (u.expr.v3->is_unfoldable()) {
5040 if (*index_int_2 > static_cast<Int>(list_len)) {
5041 error("Second operand `index' (%s) is greater than the length of "
5042 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5043 (unsigned long)list_len);
5044 set_valuetype(V_ERROR);
5045 }
5046 } else {
5047 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5048 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5049 error("The sum of second operand `index' (%s) and third operand "
5050 "`len' (%s) is greater than the length of the first operand (%lu)",
5051 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5052 (unsigned long)list_len);
5053 set_valuetype(V_ERROR);
5054 }
5055 }
5056 }
5057 }
5058
5059 void Value::chk_expr_operands_substr()
5060 {
5061 if(valuetype==V_ERROR) return;
5062 if(u.expr.state==EXPR_CHECKING_ERR) return;
5063 Value* v1 = u.expr.ti1->get_specific_value();
5064 if (!v1) return;
5065
5066 Error_Context cntxt(this, "In operation `%s'", get_opname());
5067 size_t list_len = 0;
5068 bool list_len_known = false;
5069 if (v1->valuetype == V_REFD) {
5070 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5071 if (subrefs && subrefs->refers_to_string_element()) {
5072 warning("Taking the substring of a string element does not make any "
5073 "sense");
5074 list_len = 1;
5075 list_len_known = true;
5076 }
5077 }
5078 if (!list_len_known && !v1->is_unfoldable()) {
5079 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5080 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5081 list_len_known = true;
5082 }
5083 // Do nothing if the length of the first operand is unknown.
5084 if (!list_len_known) return;
5085 if (u.expr.v2->is_unfoldable()) {
5086 if (!u.expr.v3->is_unfoldable()) {
5087 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5088 // Only the third operand is known.
5089 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5090 error("Third operand `returncount' (%s) is greater than the "
5091 "length of the first operand (%lu)",
5092 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5093 set_valuetype(V_ERROR);
5094 }
5095 }
5096 } else {
5097 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5098 if (u.expr.v3->is_unfoldable()) {
5099 // Only the second operand is known.
5100 if (*index_int_2 > static_cast<Int>(list_len)) {
5101 error("Second operand `index' (%s) is greater than the length "
5102 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5103 (unsigned long)list_len);
5104 set_valuetype(V_ERROR);
5105 }
5106 } else {
5107 // Both second and third operands are known.
5108 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5109 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5110 error("The sum of second operand `index' (%s) and third operand "
5111 "`returncount' (%s) is greater than the length of the first operand "
5112 "(%lu)", (index_int_2->t_str()).c_str(),
5113 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5114 set_valuetype(V_ERROR);
5115 }
5116 }
5117 }
5118 }
5119
5120 void Value::chk_expr_operands_regexp()
5121 {
5122 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5123 Value* v1 = u.expr.ti1->get_specific_value();
5124 Value* v2 = u.expr.t2->get_specific_value();
5125 if (!v1 || !v2) return;
5126
5127 Error_Context cntxt(this, "In operation `regexp()'");
5128 Value* v1_last = v1->get_value_refd_last();
5129 if (v1_last->valuetype == V_CSTR) {
5130 // the input string is available at compile time
5131 const string& instr = v1_last->get_val_str();
5132 const char *input_str = instr.c_str();
5133 size_t instr_len = strlen(input_str);
5134 if (instr_len < instr.size()) {
5135 v1->warning("The first operand of `regexp()' contains a "
5136 "character with character code zero at index %s. The rest of the "
5137 "string will be ignored during matching",
5138 Int2string(instr_len).c_str());
5139 }
5140 }
5141
5142 size_t nof_groups = 0;
5143 Value *v2_last = v2->get_value_refd_last();
5144
5145 if (v2_last->valuetype == V_CSTR) {
5146 // the pattern is available at compile time
5147 const string& expression = v2_last->get_val_str();
5148 const char *pattern_str = expression.c_str();
5149 size_t pattern_len = strlen(pattern_str);
5150 if (pattern_len < expression.size()) {
5151 v2->warning("The second operand of `regexp()' contains a "
5152 "character with character code zero at index %s. The rest of the "
5153 "string will be ignored during matching",
5154 Int2string(pattern_len).c_str());
5155 }
5156 char *posix_str;
5157 {
5158 Error_Context cntxt2(v2, "In character string pattern");
5159 posix_str = TTCN_pattern_to_regexp(pattern_str);
5160 }
5161 if (posix_str != NULL) {
5162 regex_t posix_regexp;
5163 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5164 if (ret_val != 0) {
5165 char msg[512];
5166 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5167 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5168 "regcomp() failed: %s", msg);
5169 }
5170 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5171 else {
5172 v2->error("The character pattern in the second operand of "
5173 "`regexp()' does not contain any groups");
5174 set_valuetype(V_ERROR);
5175 }
5176 regfree(&posix_regexp);
5177 Free(posix_str);
5178 } else {
5179 // the pattern is faulty
5180 // the error has been reported by TTCN_pattern_to_regexp
5181 set_valuetype(V_ERROR);
5182 }
5183 }
5184 if (nof_groups > 0) {
5185 Value *v3 = u.expr.v3->get_value_refd_last();
5186 if (v3->valuetype == V_INT) {
5187 // the group number is available at compile time
5188 const int_val_t *groupno_int = v3->get_val_Int();
5189 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5190 u.expr.v3->error("The the third operand of `regexp()' is too "
5191 "large: The requested group index is %s, but the pattern "
5192 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5193 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5194 set_valuetype(V_ERROR);
5195 }
5196 }
5197 }
5198 }
5199
5200 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5201 Type::expected_value_t exp_val)
5202 {
5203 const char *opname = get_opname();
5204 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5205 Type *t_governor;
5206 const Location *loc;
5207 bool error_flag = false;
5208 switch (u.expr.v_optype) {
5209 case OPTYPE_ISCHOSEN_V:
5210 // u.expr.v1 is always a referenced value
5211 t_governor = u.expr.v1->get_expr_governor(exp_val);
5212 if (t_governor) {
5213 u.expr.v1->set_my_governor(t_governor);
5214 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5215 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5216 } else error_flag = true;
5217 loc = u.expr.v1;
5218 break;
5219 case OPTYPE_ISCHOSEN_T:
5220 // u.expr.t1 is always a referenced template
5221 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5222 exp_val = Type::EXPECTED_TEMPLATE;
5223 t_governor = u.expr.t1->get_expr_governor(exp_val);
5224 if (t_governor) {
5225 u.expr.t1->set_my_governor(t_governor);
5226 //
5227 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5228 //
5229 u.expr.t1->get_template_refd_last(refch);
5230 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5231 error_flag = true;
5232 } else error_flag = true;
5233 if (exp_val != Type::EXPECTED_TEMPLATE) {
5234 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5235 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5236 u.expr.t1->get_reference()->get_refd_assignment()
5237 ->get_description().c_str());
5238 error_flag = true;
5239 }
5240 loc = u.expr.t1;
5241 break;
5242 default:
5243 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5244 t_governor = 0;
5245 loc = 0;
5246 }
5247 if (t_governor) {
5248 t_governor = t_governor->get_type_refd_last();
5249 switch (t_governor->get_typetype()) {
5250 case Type::T_ERROR:
5251 error_flag = true;
5252 break;
5253 case Type::T_CHOICE_A:
5254 case Type::T_CHOICE_T:
5255 case Type::T_ANYTYPE:
5256 case Type::T_OPENTYPE:
5257 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5258 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5259 "%s does not have a field named `%s'" :
5260 "Union type `%s' does not have a field named `%s'",
5261 t_governor->get_typename().c_str(),
5262 u.expr.i2->get_dispname().c_str());
5263 error_flag = true;
5264 }
5265 break;
5266 default:
5267 loc->error("The operand of operation `%s' should be a union value "
5268 "or template instead of `%s'", opname,
5269 t_governor->get_typename().c_str());
5270 error_flag = true;
5271 break;
5272 }
5273 }
5274 if (error_flag) set_valuetype(V_ERROR);
5275 }
5276
5277 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5278 Type::expected_value_t exp_val) {
5279
5280 Error_Context cntxt(this, "In the parameter of encvalue()");
5281 Type t_chk(Type::T_ERROR);
5282 Type* t_type;
5283
5284 Type::expected_value_t ti_exp_val = exp_val;
5285 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5286 ti_exp_val = Type::EXPECTED_TEMPLATE;
5287
5288 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5289 if (t_type) {
5290 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5291 if (valuetype!=V_ERROR)
5292 u.expr.ti1->get_Template()->chk_specific_value(false);
5293 t_type = t_type->get_type_refd_last();
5294 } else {
5295 error("Cannot determine type of value");
5296 goto error;
5297 }
5298
5299 // todo: fix this
5300 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5301 error("Expecting a value of a type with coding attributes in first"
5302 "parameter of encvalue() which belongs to a generic type '%s'",
5303 t_type->get_typename().c_str());
5304 goto error;
5305 }*/
5306
5307 if(!disable_attribute_validation()) {
5308 t_type->chk_coding(true);
5309 }
5310
5311 switch (t_type->get_typetype()) {
5312 case Type::T_UNDEF:
5313 case Type::T_ERROR:
5314 case Type::T_NULL:
5315 case Type::T_REFD:
5316 case Type::T_REFDSPEC:
5317 case Type::T_SELTYPE:
5318 case Type::T_VERDICT:
5319 case Type::T_PORT:
5320 case Type::T_COMPONENT:
5321 case Type::T_DEFAULT:
5322 case Type::T_SIGNATURE:
5323 case Type::T_FUNCTION:
5324 case Type::T_ALTSTEP:
5325 case Type::T_TESTCASE:
5326 error("Type of parameter of encvalue() cannot be '%s'",
5327 t_type->get_typename().c_str());
5328 goto error;
5329 default:
5330 break;
5331 }
5332 return;
5333 error:
5334 set_valuetype(V_ERROR);
5335 }
5336
5337 void Value::chk_expr_operands_decode()
5338 {
5339 Error_Context cntxt(this, "In the parameters of decvalue()");
5340 Ttcn::Ref_base* ref = u.expr.r1;
5341 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5342 Type* t_type = 0;
5343 Assignment* t_ass = ref->get_refd_assignment();
5344
5345 if (!t_ass) {
5346 error("Could not determine the assignment for first parameter");
5347 goto error;
5348 }
5349 switch (t_ass->get_asstype()) {
5350 case Assignment::A_PAR_VAL_IN:
5351 t_ass->use_as_lvalue(*this);
5352 break;
5353 case Assignment::A_CONST:
5354 case Assignment::A_EXT_CONST:
5355 case Assignment::A_MODULEPAR:
5356 case Assignment::A_MODULEPAR_TEMP:
5357 case Assignment::A_TEMPLATE:
5358 ref->error("Reference to '%s' cannot be used as the first operand of "
5359 "the 'decvalue' operation", t_ass->get_assname());
5360 goto error;
5361 break;
5362 case Assignment::A_VAR:
5363 case Assignment::A_PAR_VAL_OUT:
5364 case Assignment::A_PAR_VAL_INOUT:
5365 break;
5366 case Assignment::A_VAR_TEMPLATE:
5367 case Assignment::A_PAR_TEMPL_IN:
5368 case Assignment::A_PAR_TEMPL_OUT:
5369 case Assignment::A_PAR_TEMPL_INOUT: {
5370 Template* t = new Template(ref->clone());
5371 t->set_location(*ref);
5372 t->set_my_scope(get_my_scope());
5373 t->set_fullname(get_fullname()+".<operand>");
5374 Template* t_last = t->get_template_refd_last();
5375 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5376 && t_last != t) {
5377 ref->error("Specific value template was expected instead of '%s'.",
5378 t->get_template_refd_last()->get_templatetype_str());
5379 delete t;
5380 goto error;
5381 }
5382 delete t;
5383 break; }
5384 default:
5385 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5386 goto error;
5387 }
5388 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5389 Type::EXPECTED_DYNAMIC_VALUE);
5390 if (!t_type) {
5391 goto error;
5392 }
5393 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5394 error("First parameter has to be a bitstring");
5395 goto error;
5396 }
5397
5398 ref = u.expr.r2;
5399 t_subrefs = ref->get_subrefs();
5400 t_ass = ref->get_refd_assignment();
5401
5402 if (!t_ass) {
5403 error("Could not determine the assignment for second parameter");
5404 goto error;
5405 }
5406 // Extra check for HM59355.
5407 switch (t_ass->get_asstype()) {
5408 case Assignment::A_VAR:
5409 case Assignment::A_PAR_VAL_IN:
5410 case Assignment::A_PAR_VAL_OUT:
5411 case Assignment::A_PAR_VAL_INOUT:
5412 break;
5413 default:
5414 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5415 goto error;
5416 }
5417 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5418 Type::EXPECTED_DYNAMIC_VALUE);
5419 if (!t_type) {
5420 goto error;
5421 }
5422 t_type = t_type->get_type_refd_last();
5423 switch (t_type->get_typetype()) {
5424 case Type::T_UNDEF:
5425 case Type::T_ERROR:
5426 case Type::T_NULL:
5427 case Type::T_REFD:
5428 case Type::T_REFDSPEC:
5429 case Type::T_SELTYPE:
5430 case Type::T_VERDICT:
5431 case Type::T_PORT:
5432 case Type::T_COMPONENT:
5433 case Type::T_DEFAULT:
5434 case Type::T_SIGNATURE:
5435 case Type::T_FUNCTION:
5436 case Type::T_ALTSTEP:
5437 case Type::T_TESTCASE:
5438 error("Type of second parameter cannot be %s",
5439 t_type->get_typename().c_str());
5440 goto error;
5441 default:
5442 break;
5443 }
5444
5445 if(!disable_attribute_validation()) {
5446 t_type->chk_coding(false);
5447 }
5448
5449 return;
5450 error:
5451 set_valuetype(V_ERROR);
5452 }
5453
5454 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5455 {
5456 Ttcn::FieldOrArrayRefs *subrefs;
5457 Identifier *field_id = 0;
5458 Assignment *t_ass;
5459 Type *t_type;
5460 if (valuetype == V_ERROR) return;
5461 else if (valuetype != V_REFD) {
5462 error("Only a referenced value can be compared with `omit'");
5463 goto error;
5464 }
5465 subrefs = u.ref.ref->get_subrefs();
5466 if (subrefs) field_id = subrefs->remove_last_field();
5467 if (!field_id) {
5468 error("Only a reference pointing to an optional record or set field "
5469 "can be compared with `omit'");
5470 goto error;
5471 }
5472 t_ass = u.ref.ref->get_refd_assignment();
5473 if (!t_ass) goto error;
5474 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5475 if (!t_type) goto error;
5476 t_type = t_type->get_type_refd_last();
5477 switch (t_type->get_typetype()) {
5478 case Type::T_ERROR:
5479 goto error;
5480 case Type::T_SEQ_A:
5481 case Type::T_SEQ_T:
5482 case Type::T_SET_A:
5483 case Type::T_SET_T:
5484 break;
5485 default:
5486 error("Only a reference pointing to an optional field of a record"
5487 " or set type can be compared with `omit'");
5488 goto error;
5489 }
5490 if (!t_type->has_comp_withName(*field_id)) {
5491 error("Type `%s' does not have field named `%s'",
5492 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5493 goto error;
5494 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5495 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5496 "`omit'", field_id->get_dispname().c_str(),
5497 t_type->get_typename().c_str());
5498 goto error;
5499 }
5500 // putting the last field_id back to subrefs
5501 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5502 return;
5503 error:
5504 set_valuetype(V_ERROR);
5505 delete field_id;
5506 }
5507
5508 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5509 Type::expected_value_t exp_val)
5510 {
5511 if(valuetype==V_ERROR) return -1;
5512 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5513 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5514 exp_val=Type::EXPECTED_TEMPLATE;
5515
5516 Error_Context cntxt(this, "In the operand of"
5517 " operation `%s'", get_opname());
5518
5519 Int result = -1;
5520 Template* t_templ = u.expr.ti1->get_Template();
5521
5522 if (!t_templ) {
5523 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5524 }
5525
5526 t_templ = t_templ->get_template_refd_last(refch);
5527
5528 // Timer and port arrays are handled separately
5529 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5530 Value* val = t_templ->get_specific_value();
5531 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5532 val->set_lowerid_to_ref();
5533 }
5534 if (val && val->get_valuetype() == V_REFD) {
5535 Reference* ref = val->get_reference();
5536 Assignment* t_ass = ref->get_refd_assignment();
5537 Common::Assignment::asstype_t asstype =
5538 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5539 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5540 if (t_ass->get_Dimensions()) {
5541 // here we have a timer or port array
5542 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5543 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5544 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5545 Type::EXPECTED_DYNAMIC_VALUE);
5546 size_t refd_dim;
5547 if (t_subrefs) {
5548 refd_dim = t_subrefs->get_nof_refs();
5549 size_t nof_dims = t_dims->get_nof_dims();
5550 if (refd_dim >= nof_dims) {
5551 u.expr.ti1->error("Operation is not applicable to a %s",
5552 t_ass->get_assname());
5553 set_valuetype(V_ERROR);
5554 return -1;
5555 }
5556 } else refd_dim = 0;
5557 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5558 } else {
5559 u.expr.ti1->error("Operation is not applicable to single `%s'",
5560 t_ass->get_description().c_str());
5561 set_valuetype(V_ERROR);
5562 return -1;
5563 }
5564 }
5565 }
5566 }
5567
5568 Value* t_val = 0;
5569 Type* t_type = 0;
5570 Assignment* t_ass = 0;
5571 Reference* ref = 0;
5572 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5573 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5574 if (t_type) {
5575 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5576 t_type = t_type->get_type_refd_last();
5577 } else {
5578 error("Cannot determine type of value");
5579 goto error;
5580 }
5581
5582 if(valuetype==V_ERROR) return -1;
5583
5584 t_templ = t_templ->get_template_refd_last(refch);
5585 switch(t_templ->get_templatetype()) {
5586 case Template::TEMPLATE_ERROR:
5587 goto error;
5588 case Template::INDEXED_TEMPLATE_LIST:
5589 return -1;
5590 case Template::TEMPLATE_REFD:
5591 case Template::TEMPLATE_LIST:
5592 case Template::NAMED_TEMPLATE_LIST:
5593 // computed later
5594 break;
5595 case Template::SPECIFIC_VALUE:
5596 {
5597 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5598 if(t_val) {
5599 switch(t_val->get_valuetype()) {
5600 case V_SEQOF:
5601 case V_SETOF:
5602 case V_ARRAY:
5603 case V_ROID:
5604 case V_OID:
5605 case V_SEQ:
5606 case V_SET:
5607 break;
5608 case V_REFD: {
5609 ref = t_val->get_reference();
5610 t_ass = ref->get_refd_assignment();
5611 t_subrefs = ref->get_subrefs();
5612 break;
5613 }
5614 default:
5615 u.expr.ti1->error("Operation is not applicable to `%s'",
5616 t_val->create_stringRepr().c_str());
5617 goto error;
5618 }
5619 }
5620 break;
5621 }
5622 default:
5623 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5624 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5625 goto error;
5626 } // switch
5627
5628 if (t_ass) {
5629 switch(t_ass->get_asstype()) {
5630 case Assignment::A_ERROR:
5631 goto error;
5632 case Assignment::A_CONST:
5633 t_val = t_ass->get_Value();
5634 break;
5635 case Assignment::A_EXT_CONST:
5636 case Assignment::A_MODULEPAR:
5637 case Assignment::A_MODULEPAR_TEMP:
5638 if(exp_val==Type::EXPECTED_CONSTANT) {
5639 u.expr.ti1->error("Reference to an (evaluatable) constant value was "
5640 "expected instead of %s", t_ass->get_description().c_str());
5641 goto error;
5642 }
5643 break;
5644 case Assignment::A_VAR:
5645 case Assignment::A_PAR_VAL_IN:
5646 case Assignment::A_PAR_VAL_OUT:
5647 case Assignment::A_PAR_VAL_INOUT:
5648 switch(exp_val) {
5649 case Type::EXPECTED_CONSTANT:
5650 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5651 t_ass->get_description().c_str());
5652 goto error;
5653 break;
5654 case Type::EXPECTED_STATIC_VALUE:
5655 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5656 t_ass->get_description().c_str());
5657 goto error;
5658 break;
5659 default:
5660 break;
5661 }
5662 break;
5663 case Assignment::A_TEMPLATE:
5664 t_templ = t_ass->get_Template();
5665 // no break
5666 case Assignment::A_VAR_TEMPLATE:
5667 case Assignment::A_PAR_TEMPL_IN:
5668 case Assignment::A_PAR_TEMPL_OUT:
5669 case Assignment::A_PAR_TEMPL_INOUT:
5670 if (exp_val!=Type::EXPECTED_TEMPLATE)
5671 u.expr.ti1->error("Reference to a value was expected instead of %s",
5672 t_ass->get_description().c_str());
5673 goto error;
5674 break;
5675 case Assignment::A_FUNCTION_RVAL:
5676 case Assignment::A_EXT_FUNCTION_RVAL:
5677 switch(exp_val) {
5678 case Type::EXPECTED_CONSTANT:
5679 u.expr.ti1->error("Reference to a constant value was expected instead of "
5680 "the return value of %s", t_ass->get_description().c_str());
5681 goto error;
5682 break;
5683 case Type::EXPECTED_STATIC_VALUE:
5684 u.expr.ti1->error("Reference to a static value was expected instead of "
5685 "the return value of %s", t_ass->get_description().c_str());
5686 goto error;
5687 break;
5688 default:
5689 break;
5690 }
5691 break;
5692 case Assignment::A_FUNCTION_RTEMP:
5693 case Assignment::A_EXT_FUNCTION_RTEMP:
5694 if(exp_val!=Type::EXPECTED_TEMPLATE)
5695 u.expr.ti1->error("Reference to a value was expected instead of a call"
5696 " of %s, which returns a template",
5697 t_ass->get_description().c_str());
5698 goto error;
5699 break;
5700 case Assignment::A_TIMER:
5701 case Assignment::A_PORT:
5702 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5703 // sizeof is applicable to timer and port arrays
5704 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5705 if (!t_dims) {
5706 u.expr.ti1->error("Operation is not applicable to single %s",
5707 t_ass->get_description().c_str());
5708 goto error;
5709 }
5710 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5711 Type::EXPECTED_DYNAMIC_VALUE);
5712 size_t refd_dim;
5713 if (t_subrefs) {
5714 refd_dim = t_subrefs->get_nof_refs();
5715 size_t nof_dims = t_dims->get_nof_dims();
5716 if (refd_dim > nof_dims) goto error;
5717 else if (refd_dim == nof_dims) {
5718 u.expr.ti1->error("Operation is not applicable to a %s",
5719 t_ass->get_assname());
5720 goto error;
5721 }
5722 } else refd_dim = 0;
5723 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5724 }
5725 // no break
5726 default:
5727 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5728 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5729 t_ass->get_description().c_str());
5730 goto error;
5731 } // end switch
5732
5733 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5734 if (!t_type) goto error;
5735 t_type = t_type->get_type_refd_last();
5736
5737 switch(t_type->get_typetype()) {
5738 case Type::T_ERROR:
5739 goto error;
5740 case Type::T_SEQOF:
5741 case Type::T_SETOF:
5742 // no break
5743 case Type::T_SEQ_T:
5744 case Type::T_SET_T:
5745 case Type::T_SEQ_A:
5746 case Type::T_SET_A:
5747 case Type::T_ARRAY:
5748 // ok
5749 break;
5750 case Type::T_OID:
5751 case Type::T_ROID:
5752 break;
5753 default:
5754 u.expr.ti1->error("Reference to value or template of type record, record of,"
5755 " set, set of, objid or array was expected");
5756 goto error;
5757 } // switch
5758 }
5759
5760 // check for index overflows in subrefs if possible
5761 if (t_val) {
5762 switch (t_val->get_valuetype()) {
5763 case V_SEQOF:
5764 case V_SETOF:
5765 case V_ARRAY:
5766 if (t_val->is_indexed()) {
5767 return -1;
5768 }
5769 break;
5770 default:
5771 break;
5772 }
5773 /* The reference points to a constant. */
5774 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5775 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5776 if (!t_val) goto error;
5777 t_val=t_val->get_value_refd_last(refch);
5778 } else { t_val = 0; }
5779 } else if (t_templ) {
5780 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5781 time. Don't try to evaluate it at compile time. */
5782 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5783 return -1;
5784 /* The reference points to a static template. */
5785 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5786 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5787 if (!t_templ) goto error;
5788 t_templ = t_templ->get_template_refd_last(refch);
5789 } else { t_templ = 0; }
5790 }
5791
5792 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5793 if(t_templ) {
5794 switch(t_templ->get_templatetype()) {
5795 case Template::TEMPLATE_ERROR:
5796 goto error;
5797 case Template::TEMPLATE_REFD:
5798 // not foldable
5799 t_templ=0;
5800 break;
5801 case Template::SPECIFIC_VALUE:
5802 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5803 t_templ=0;
5804 break;
5805 case Template::TEMPLATE_LIST:
5806 case Template::NAMED_TEMPLATE_LIST:
5807 break;
5808 default:
5809 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5810 t_templ->get_templatetype_str(),
5811 t_templ->get_fullname().c_str());
5812 goto error;
5813 } // switch
5814 }
5815 if(t_val) {
5816 switch(t_val->get_valuetype()) {
5817 case V_SEQOF:
5818 case V_SETOF:
5819 case V_ARRAY:
5820 case V_SEQ:
5821 case V_SET:
5822 case V_OID:
5823 case V_ROID:
5824 // ok
5825 break;
5826 default:
5827 // error is already reported
5828 t_val=0;
5829 break;
5830 } // switch
5831 }
5832 }
5833
5834 /* evaluation */
5835
5836 if(t_type->get_typetype()==Type::T_ARRAY) {
5837 result = t_type->get_dimension()->get_size();
5838 }
5839 else if(t_templ) { // sizeof()
5840 switch(t_templ->get_templatetype()) {
5841 case Template::TEMPLATE_LIST:
5842 if(t_templ->temps_contains_anyornone_symbol()) {
5843 if(t_templ->is_length_restricted()) {
5844 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5845 if (lr->get_is_range()) {
5846 Value *v_upper = lr->get_upper_value();
5847 if (v_upper) {
5848 if (v_upper->valuetype == V_INT) {
5849 Int nof_comps =
5850 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5851 if (v_upper->u.val_Int->get_val() == nof_comps)
5852 result = nof_comps;
5853 else {
5854 u.expr.ti1->error("`sizeof' operation is not applicable for "
5855 "templates without exact size");
5856 goto error;
5857 }
5858 }
5859 } else {
5860 u.expr.ti1->error("`sizeof' operation is not applicable for "
5861 "templates containing `*' without upper boundary in the "
5862 "length restriction");
5863 goto error;
5864 }
5865 } else {
5866 Value *v_single = lr->get_single_value();
5867 if (v_single->valuetype == V_INT)
5868 result = v_single->u.val_Int->get_val();
5869 }
5870 }
5871 else { // not length restricted
5872 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
5873 " containing `*' without length restriction");
5874 goto error;
5875 }
5876 }
5877 else result=t_templ->get_nof_listitems();
5878 break;
5879 case Template::NAMED_TEMPLATE_LIST:
5880 result=0;
5881 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
5882 if(t_templ->get_namedtemp_byIndex(i)->get_template()
5883 ->get_templatetype()!=Template::OMIT_VALUE) result++;
5884 return result;
5885 default:
5886 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5887 } // switch
5888 }
5889 else if(t_val) {
5890 switch(t_val->get_valuetype()) {
5891 case V_SEQOF:
5892 case V_SETOF:
5893 case V_ARRAY:
5894
5895 case V_OID:
5896 case V_ROID:
5897 result=t_val->get_nof_comps();
5898 break;
5899 case V_SEQ:
5900 case V_SET:
5901 result=0;
5902 for(size_t i=0; i<t_val->get_nof_comps(); i++)
5903 if(t_val->get_se_comp_byIndex(i)->get_value()
5904 ->get_valuetype()!=V_OMIT) result++;
5905 break;
5906
5907 default:
5908 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5909 } // switch
5910 }
5911
5912 return result;
5913 error:
5914 set_valuetype(V_ERROR);
5915 return -1;
5916 }
5917
5918 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
5919 {
5920 Type *governor = ti->get_expr_governor(exp_val);
5921 if (!governor) {
5922 ti->get_Template()->set_lowerid_to_ref();
5923 governor = ti->get_expr_governor(exp_val);
5924 }
5925 if (!governor) {
5926 string str;
5927 ti->append_stringRepr( str);
5928 ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5929 "If type is known, use valuof(<type>: %s) as argument.",
5930 str.c_str(), get_opname(), str.c_str());
5931 set_valuetype(V_ERROR);
5932 }
5933 return governor;
5934 }
5935
5936 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
5937 {
5938 start:
5939 Type *governor = u.expr.v1->get_expr_governor(exp_val);
5940 if (!governor) governor = u.expr.t2->get_expr_governor(
5941 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
5942 Type::EXPECTED_TEMPLATE : exp_val);
5943 if (!governor) {
5944 Template *t_temp = u.expr.t2->get_Template();
5945 if (t_temp->is_undef_lowerid()) {
5946 // We convert the template to reference first even if the value is also
5947 // an undef lowerid. The user can prevent this by explicit type
5948 // specification.
5949 t_temp->set_lowerid_to_ref();
5950 goto start;
5951 } else if (u.expr.v1->is_undef_lowerid()) {
5952 u.expr.v1->set_lowerid_to_ref();
5953 goto start;
5954 }
5955 }
5956 if (!governor) {
5957 error("Cannot determine the type of arguments in `match()' operation");
5958 set_valuetype(V_ERROR);
5959 return;
5960 }
5961 u.expr.v1->set_my_governor(governor);
5962 {
5963 Error_Context cntxt(this, "In the first argument of `match()'"
5964 " operation");
5965 governor->chk_this_value_ref(u.expr.v1);
5966 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
5967 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
5968 }
5969 {
5970 Error_Context cntxt(this, "In the second argument of `match()' "
5971 "operation");
5972 u.expr.t2->chk(governor);
5973 }
5974 }
5975
5976 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
5977 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
5978 {
5979 Ttcn::StatementBlock *my_sb;
5980 switch (exp_val) {
5981 case Type::EXPECTED_CONSTANT:
5982 error("An evaluatable constant value was expected instead of operation "
5983 "`%s'", get_opname());
5984 goto error;
5985 case Type::EXPECTED_STATIC_VALUE:
5986 error("A static value was expected instead of operation `%s'",
5987 get_opname());
5988 goto error;
5989 default:
5990 break;
5991 } // switch
5992 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5993 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
5994 if (!my_sb) {
5995 error("Operation `%s' is allowed only within statements",
5996 get_opname());
5997 goto error;
5998 }
5999 if (!allow_controlpart && !my_sb->get_my_def()) {
6000 error("Operation `%s' is not allowed in the control part",
6001 get_opname());
6002 goto error;
6003 }
6004 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6005 error("Operation `%s' cannot be used in a definition that has "
6006 "`runs on' clause", get_opname());
6007 goto error;
6008 }
6009 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6010 error("Operation `%s' can be used only in a definition that has "
6011 "`runs on' clause", get_opname());
6012 goto error;
6013 }
6014 return;
6015 error:
6016 set_valuetype(V_ERROR);
6017 }
6018
6019 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6020 {
6021 if(valuetype==V_ERROR) return;
6022 if(u.expr.state==EXPR_CHECKING_ERR) return;
6023 if(v->is_unfoldable()) return;
6024 if(v->get_expr_returntype()!=Type::T_REAL) return;
6025 ttcn3float r = v->get_val_Real();
6026 if (isSpecialFloatValue(r)) {
6027 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6028 opnum, opname, Real2string(r).c_str());
6029 set_valuetype(V_ERROR);
6030 }
6031 }
6032
6033 void Value::chk_expr_operands(ReferenceChain *refch,
6034 Type::expected_value_t exp_val)
6035 {
6036 const char *first="First", *second="Second", *third="Third",
6037 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6038 Value *v1, *v2, *v3;
6039 Type::typetype_t tt1, tt2, tt3;
6040 Type t_chk(Type::T_ERROR);
6041
6042 const char *opname=get_opname();
6043
6044 // first classify the unchecked ischosen() operation
6045 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6046
6047 switch (u.expr.v_optype) {
6048 case OPTYPE_COMP_NULL:
6049 case OPTYPE_TESTCASENAME:
6050 case OPTYPE_PROF_RUNNING:
6051 break;
6052 case OPTYPE_COMP_MTC:
6053 case OPTYPE_COMP_SYSTEM:
6054 chk_expr_comptype_compat();
6055 break;
6056 case OPTYPE_RND: // -
6057 case OPTYPE_TMR_RUNNING_ANY:
6058 chk_expr_dynamic_part(exp_val, true);
6059 break;
6060 case OPTYPE_COMP_RUNNING_ANY:
6061 case OPTYPE_COMP_RUNNING_ALL:
6062 case OPTYPE_COMP_ALIVE_ANY:
6063 case OPTYPE_COMP_ALIVE_ALL:
6064 case OPTYPE_GETVERDICT:
6065 chk_expr_dynamic_part(exp_val, false);
6066 break;
6067 case OPTYPE_COMP_SELF:
6068 chk_expr_comptype_compat();
6069 chk_expr_dynamic_part(exp_val, false, true, false);
6070 break;
6071 case OPTYPE_UNARYPLUS: // v1
6072 case OPTYPE_UNARYMINUS:
6073 v1=u.expr.v1;
6074 {
6075 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6076 v1->set_lowerid_to_ref();
6077 tt1=v1->get_expr_returntype(exp_val);
6078 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6079 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6080 }
6081 break;
6082 case OPTYPE_NOT:
6083 v1=u.expr.v1;
6084 {
6085 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6086 v1->set_lowerid_to_ref();
6087 tt1=v1->get_expr_returntype(exp_val);
6088 chk_expr_operandtype_bool(tt1, the, opname, v1);
6089 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6090 }
6091 break;
6092 case OPTYPE_NOT4B:
6093 v1=u.expr.v1;
6094 {
6095 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6096 v1->set_lowerid_to_ref();
6097 tt1=v1->get_expr_returntype(exp_val);
6098 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6099 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6100 }
6101 break;
6102 case OPTYPE_BIT2HEX:
6103 case OPTYPE_BIT2OCT:
6104 case OPTYPE_BIT2STR:
6105 v1=u.expr.v1;
6106 {
6107 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6108 v1->set_lowerid_to_ref();
6109 tt1=v1->get_expr_returntype(exp_val);
6110 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6111 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6112 }
6113 break;
6114 case OPTYPE_BIT2INT:
6115 v1=u.expr.v1;
6116 {
6117 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6118 v1->set_lowerid_to_ref();
6119 tt1=v1->get_expr_returntype(exp_val);
6120 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6121 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6122 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6123 }
6124 break;
6125 case OPTYPE_CHAR2INT:
6126 v1=u.expr.v1;
6127 {
6128 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6129 v1->set_lowerid_to_ref();
6130 tt1=v1->get_expr_returntype(exp_val);
6131 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6132 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6133 chk_expr_val_len1(v1, the, opname);
6134 }
6135 break;
6136 case OPTYPE_CHAR2OCT:
6137 v1=u.expr.v1;
6138 {
6139 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6140 v1->set_lowerid_to_ref();
6141 tt1=v1->get_expr_returntype(exp_val);
6142 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6143 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6144 }
6145 break;
6146 case OPTYPE_STR2INT:
6147 v1=u.expr.v1;
6148 {
6149 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6150 v1->set_lowerid_to_ref();
6151 tt1=v1->get_expr_returntype(exp_val);
6152 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6153 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6154 chk_expr_val_str_int(v1, the, opname);
6155 }
6156 break;
6157 case OPTYPE_STR2FLOAT:
6158 v1=u.expr.v1;
6159 {
6160 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6161 v1->set_lowerid_to_ref();
6162 tt1=v1->get_expr_returntype(exp_val);
6163 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6164 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6165 chk_expr_val_str_float(v1, the, opname);
6166 }
6167 break;
6168 case OPTYPE_STR2BIT:
6169 v1=u.expr.v1;
6170 {
6171 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6172 v1->set_lowerid_to_ref();
6173 tt1=v1->get_expr_returntype(exp_val);
6174 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6175 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6176 chk_expr_val_str_bindigits(v1, the, opname);
6177 }
6178 break;
6179 case OPTYPE_STR2HEX:
6180 v1=u.expr.v1;
6181 {
6182 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6183 v1->set_lowerid_to_ref();
6184 tt1=v1->get_expr_returntype(exp_val);
6185 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6186 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6187 chk_expr_val_str_hexdigits(v1, the, opname);
6188 }
6189 break;
6190 case OPTYPE_STR2OCT:
6191 v1=u.expr.v1;
6192 {
6193 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6194 v1->set_lowerid_to_ref();
6195 tt1=v1->get_expr_returntype(exp_val);
6196 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6197 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6198 chk_expr_val_str_len_even(v1, the, opname);
6199 chk_expr_val_str_hexdigits(v1, the, opname);
6200 }
6201 break;
6202 case OPTYPE_ENUM2INT:
6203 v1=u.expr.v1;
6204 {
6205 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6206 chk_expr_operandtype_enum(opname, v1, exp_val);
6207 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6208 }
6209 break;
6210 case OPTYPE_ENCODE:
6211 chk_expr_operand_encode(refch, exp_val);
6212 break;
6213 case OPTYPE_FLOAT2INT:
6214 case OPTYPE_FLOAT2STR:
6215 v1=u.expr.v1;
6216 {
6217 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6218 v1->set_lowerid_to_ref();
6219 tt1=v1->get_expr_returntype(exp_val);
6220 chk_expr_operandtype_float(tt1, the, opname, v1);
6221 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6222 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6223 chk_expr_operand_valid_float(v1, the, opname);
6224 }
6225 break;
6226 case OPTYPE_RNDWITHVAL:
6227 v1=u.expr.v1;
6228 {
6229 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6230 v1->set_lowerid_to_ref();
6231 tt1=v1->get_expr_returntype(exp_val);
6232 chk_expr_operandtype_float(tt1, the, opname, v1);
6233 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6234 chk_expr_operand_valid_float(v1, the, opname);
6235 }
6236 chk_expr_dynamic_part(exp_val, true);
6237 break;
6238 case OPTYPE_HEX2BIT:
6239 case OPTYPE_HEX2OCT:
6240 case OPTYPE_HEX2STR:
6241 v1=u.expr.v1;
6242 {
6243 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6244 v1->set_lowerid_to_ref();
6245 tt1=v1->get_expr_returntype(exp_val);
6246 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6247 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6248 }
6249 break;
6250 case OPTYPE_HEX2INT:
6251 v1=u.expr.v1;
6252 {
6253 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6254 v1->set_lowerid_to_ref();
6255 tt1=v1->get_expr_returntype(exp_val);
6256 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6257 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6258 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6259 }
6260 break;
6261 case OPTYPE_INT2CHAR:
6262 v1=u.expr.v1;
6263 {
6264 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6265 v1->set_lowerid_to_ref();
6266 tt1=v1->get_expr_returntype(exp_val);
6267 chk_expr_operandtype_int(tt1, the, opname, v1);
6268 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6269 chk_expr_val_int_pos7bit(v1, the, opname);
6270 }
6271 break;
6272 case OPTYPE_INT2UNICHAR:
6273 v1=u.expr.v1;
6274 {
6275 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6276 v1->set_lowerid_to_ref();
6277 tt1=v1->get_expr_returntype(exp_val);
6278 chk_expr_operandtype_int(tt1, the, opname, v1);
6279 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6280 chk_expr_val_int_pos31bit(v1, first, opname);
6281 }
6282 break;
6283 case OPTYPE_INT2FLOAT:
6284 case OPTYPE_INT2STR:
6285 v1=u.expr.v1;
6286 {
6287 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6288 v1->set_lowerid_to_ref();
6289 tt1=v1->get_expr_returntype(exp_val);
6290 chk_expr_operandtype_int(tt1, the, opname, v1);
6291 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6292 }
6293 break;
6294 case OPTYPE_OCT2BIT:
6295 case OPTYPE_OCT2HEX:
6296 case OPTYPE_OCT2STR:
6297 v1=u.expr.v1;
6298 {
6299 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6300 v1->set_lowerid_to_ref();
6301 tt1=v1->get_expr_returntype(exp_val);
6302 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6303 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6304 }
6305 break;
6306 case OPTYPE_OCT2INT:
6307 v1=u.expr.v1;
6308 {
6309 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6310 v1->set_lowerid_to_ref();
6311 tt1=v1->get_expr_returntype(exp_val);
6312 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6313 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6314 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6315 // now.
6316 }
6317 break;
6318 case OPTYPE_OCT2CHAR:
6319 v1=u.expr.v1;
6320 {
6321 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6322 v1->set_lowerid_to_ref();
6323 tt1=v1->get_expr_returntype(exp_val);
6324 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6325 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6326 chk_expr_val_str_7bitoctets(v1, the, opname);
6327 }
6328 break;
6329 case OPTYPE_REMOVE_BOM:
6330 v1=u.expr.v1;
6331 {
6332 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6333 v1->set_lowerid_to_ref();
6334 tt1=v1->get_expr_returntype(exp_val);
6335 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6336 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6337 }
6338 break;
6339 case OPTYPE_GET_STRINGENCODING:
6340 v1=u.expr.v1;
6341 {
6342 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6343 v1->set_lowerid_to_ref();
6344 tt1=v1->get_expr_returntype(exp_val);
6345 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6346 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6347 }
6348 break;
6349 case OPTYPE_ENCODE_BASE64:
6350 v1=u.expr.v1;
6351 {
6352 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6353 v1->set_lowerid_to_ref();
6354 tt1=v1->get_expr_returntype(exp_val);
6355 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6356 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6357 }
6358 v2=u.expr.v2 ? u.expr.v2 : 0;
6359 if (v2)
6360 {
6361 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6362 v2->set_lowerid_to_ref();
6363 tt2=v2->get_expr_returntype(exp_val);
6364 chk_expr_operandtype_bool(tt2, second, opname, v2);
6365 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6366 }
6367 break;
6368 case OPTYPE_DECODE_BASE64:
6369 v1=u.expr.v1;
6370 {
6371 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6372 v1->set_lowerid_to_ref();
6373 tt1=v1->get_expr_returntype(exp_val);
6374 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6375 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6376 }
6377 break;
6378 case OPTYPE_UNICHAR2INT:
6379 v1=u.expr.v1;
6380 {
6381 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6382 v1->set_lowerid_to_ref();
6383 tt1=v1->get_expr_returntype(exp_val);
6384 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6385 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6386 chk_expr_val_len1(v1, the, opname);
6387 }
6388 break;
6389 case OPTYPE_UNICHAR2CHAR:
6390 v1=u.expr.v1;
6391 {
6392 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6393 v1->set_lowerid_to_ref();
6394 tt1=v1->get_expr_returntype(exp_val);
6395 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6396 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6397 chk_expr_val_ustr_7bitchars(v1, the, opname);
6398 }
6399 break;
6400 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6401 v1=u.expr.v1;
6402 {
6403 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6404 v1->set_lowerid_to_ref();
6405 tt1=v1->get_expr_returntype(exp_val);
6406 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6407 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6408 }
6409 v2=u.expr.v2 ? u.expr.v2 : 0;
6410 if (v2)
6411 {
6412 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6413 v2->set_lowerid_to_ref();
6414 tt2=v2->get_expr_returntype(exp_val);
6415 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6416 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6417 }
6418 break;
6419 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6420 v1=u.expr.v1;
6421 {
6422 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6423 v1->set_lowerid_to_ref();
6424 tt1=v1->get_expr_returntype(exp_val);
6425 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6426 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6427 }
6428 v2=u.expr.v2 ? u.expr.v2 : 0;
6429 if (v2)
6430 {
6431 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6432 v2->set_lowerid_to_ref();
6433 tt2=v2->get_expr_returntype(exp_val);
6434 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6435 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6436 }
6437 break;
6438 case OPTYPE_ADD: // v1 v2
6439 case OPTYPE_SUBTRACT:
6440 case OPTYPE_MULTIPLY:
6441 case OPTYPE_DIVIDE:
6442 v1=u.expr.v1;
6443 {
6444 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6445 v1->set_lowerid_to_ref();
6446 tt1=v1->get_expr_returntype(exp_val);
6447 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6448 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6449 chk_expr_operand_valid_float(v1, first, opname);
6450 }
6451 v2=u.expr.v2;
6452 {
6453 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6454 v2->set_lowerid_to_ref();
6455 tt2=v2->get_expr_returntype(exp_val);
6456 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6457 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6458 chk_expr_operand_valid_float(v2, second, opname);
6459 if(u.expr.v_optype==OPTYPE_DIVIDE)
6460 chk_expr_val_int_float_not0(v2, second, opname);
6461 }
6462 chk_expr_operandtypes_same(tt1, tt2, opname);
6463 break;
6464 case OPTYPE_MOD:
6465 case OPTYPE_REM:
6466 v1=u.expr.v1;
6467 {
6468 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6469 v1->set_lowerid_to_ref();
6470 tt1=v1->get_expr_returntype(exp_val);
6471 chk_expr_operandtype_int(tt1, left, opname, v1);
6472 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6473 }
6474 v2=u.expr.v2;
6475 {
6476 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6477 v2->set_lowerid_to_ref();
6478 tt2=v2->get_expr_returntype(exp_val);
6479 chk_expr_operandtype_int(tt2, right, opname, v2);
6480 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6481 chk_expr_val_int_float_not0(v2, right, opname);
6482 }
6483 break;
6484 case OPTYPE_CONCAT: {
6485 v1=u.expr.v1;
6486 v2=u.expr.v2;
6487 v1->set_lowerid_to_ref();
6488 v2->set_lowerid_to_ref();
6489 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6490 {
6491 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6492 tt1=v1->get_expr_returntype(exp_val);
6493 chk_expr_operandtype_str(tt1, left, opname, v1);
6494 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6495 }
6496 {
6497 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6498 tt2=v2->get_expr_returntype(exp_val);
6499 chk_expr_operandtype_str(tt2, right, opname, v2);
6500 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6501 }
6502 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6503 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6504 chk_expr_operandtypes_same(tt1, tt2, opname);
6505 } else { // other list types
6506 Type* v1_gov = v1->get_expr_governor(exp_val);
6507 Type* v2_gov = v2->get_expr_governor(exp_val);
6508 if (!v1_gov) {
6509 error("Cannot determine the type of the left operand of `%s' operation", opname);
6510 set_valuetype(V_ERROR);
6511 return;
6512 } else {
6513 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6514 v1_gov->chk_this_value_ref(v1);
6515 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6516 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6517 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6518 }
6519 if (!v2_gov) {
6520 if (!v1_gov) {
6521 error("Cannot determine the type of the right operand of `%s' operation", opname);
6522 set_valuetype(V_ERROR);
6523 return;
6524 }
6525 // for recof/setof literals set the type from v1
6526 v2_gov = v1_gov;
6527 v2->set_my_governor(v1_gov);
6528 }
6529 {
6530 Error_Context cntxt(this, "In the right operand of operation `%s'",
6531 opname);
6532 v2_gov->chk_this_value_ref(v2);
6533 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6534 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6535 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6536 if (valuetype == V_ERROR) return;
6537 // 7.1.2 says that we shouldn't allow type compatibility.
6538 if (!v1_gov->is_compatible(v2_gov, NULL)
6539 && !v2_gov->is_compatible(v1_gov, NULL)) {
6540 error("The operands of operation `%s' should be of compatible "
6541 "types", get_opname());
6542 }
6543 }
6544 }
6545 break; }
6546 case OPTYPE_EQ:
6547 case OPTYPE_NE:
6548 v1 = u.expr.v1;
6549 v2 = u.expr.v2;
6550 chk_expr_operandtypes_compat(exp_val, v1, v2);
6551 {
6552 Error_Context cntxt(this, "In the left operand of operation `%s'",
6553 opname);
6554 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6555 }
6556 {
6557 Error_Context cntxt(this, "In the right operand of operation `%s'",
6558 opname);
6559 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6560 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6561 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6562 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6563 * "a == not b" is not allowed. (HL69107)
6564 * The various *Expressions implement operator precedence in the std.
6565 * Titan's parser has only one Expression and relies on Bison
6566 * for operator precedence. The check below brings Titan in line
6567 * with the standard by explicitly making "a == not b" an error */
6568 if (v2->get_valuetype() == V_EXPR
6569 && v2->u.expr.v_optype == OPTYPE_NOT) {
6570 error("The operation `%s' is not allowed to be "
6571 "the second operand of operation `%s'", v2->get_opname(), opname);
6572 set_valuetype(V_ERROR);
6573 }
6574 }
6575 break;
6576 case OPTYPE_LT:
6577 case OPTYPE_GT:
6578 case OPTYPE_GE:
6579 case OPTYPE_LE:
6580 v1=u.expr.v1;
6581 v2=u.expr.v2;
6582 chk_expr_operandtypes_compat(exp_val, v1, v2);
6583 {
6584 Error_Context cntxt(this, "In the left operand of operation `%s'",
6585 opname);
6586 tt1=v1->get_expr_returntype(exp_val);
6587 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6588 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6589 }
6590 {
6591 Error_Context cntxt(this, "In the right operand of operation `%s'",
6592 opname);
6593 tt2=v2->get_expr_returntype(exp_val);
6594 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6595 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6596 }
6597 break;
6598 case OPTYPE_AND:
6599 case OPTYPE_OR:
6600 case OPTYPE_XOR:
6601 v1=u.expr.v1;
6602 {
6603 Error_Context cntxt(this, "In the left operand of operation `%s'",
6604 opname);
6605 v1->set_lowerid_to_ref();
6606 tt1=v1->get_expr_returntype(exp_val);
6607 chk_expr_operandtype_bool(tt1, left, opname, v1);
6608 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6609 }
6610 v2=u.expr.v2;
6611 {
6612 Error_Context cntxt(this, "In the right operand of operation `%s'",
6613 opname);
6614 v2->set_lowerid_to_ref();
6615 tt2=v2->get_expr_returntype(exp_val);
6616 chk_expr_operandtype_bool(tt2, right, opname, v2);
6617 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6618 }
6619 break;
6620 case OPTYPE_AND4B:
6621 case OPTYPE_OR4B:
6622 case OPTYPE_XOR4B:
6623 v1=u.expr.v1;
6624 {
6625 Error_Context cntxt(this, "In the left operand of operation `%s'",
6626 opname);
6627 v1->set_lowerid_to_ref();
6628 tt1=v1->get_expr_returntype(exp_val);
6629 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6630 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6631 }
6632 v2=u.expr.v2;
6633 {
6634 Error_Context cntxt(this, "In the right operand of operation `%s'",
6635 opname);
6636 v2->set_lowerid_to_ref();
6637 tt2=v2->get_expr_returntype(exp_val);
6638 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6639 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6640 }
6641 chk_expr_operandtypes_same(tt1, tt2, opname);
6642 chk_expr_operands_str_samelen();
6643 break;
6644 case OPTYPE_SHL:
6645 case OPTYPE_SHR:
6646 v1=u.expr.v1;
6647 {
6648 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6649 v1->set_lowerid_to_ref();
6650 tt1=v1->get_expr_returntype(exp_val);
6651 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6652 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6653 }
6654 v2=u.expr.v2;
6655 {
6656 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6657 v2->set_lowerid_to_ref();
6658 tt2=v2->get_expr_returntype(exp_val);
6659 chk_expr_operandtype_int(tt2, right, opname, v2);
6660 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6661 chk_expr_val_large_int(v2, right, opname);
6662 }
6663 break;
6664 case OPTYPE_ROTL:
6665 case OPTYPE_ROTR:
6666 v1=u.expr.v1;
6667 v1->set_lowerid_to_ref();
6668 if (v1->is_string_type(exp_val)) {
6669 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6670 tt1=v1->get_expr_returntype(exp_val);
6671 chk_expr_operandtype_str(tt1, left, opname, v1);
6672 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6673 } else { // other list types
6674 Type* v1_gov = v1->get_expr_governor(exp_val);
6675 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6676 error("Cannot determine the type of the left operand of `%s' operation", opname);
6677 } else {
6678 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6679 v1_gov->chk_this_value_ref(v1);
6680 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6681 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6682 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6683 }
6684 }
6685 v2=u.expr.v2;
6686 {
6687 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6688 v2->set_lowerid_to_ref();
6689 tt2=v2->get_expr_returntype(exp_val);
6690 chk_expr_operandtype_int(tt2, right, opname, v2);
6691 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6692 chk_expr_val_large_int(v2, right, opname);
6693 }
6694 break;
6695 case OPTYPE_INT2BIT:
6696 case OPTYPE_INT2HEX:
6697 case OPTYPE_INT2OCT:
6698 v1=u.expr.v1;
6699 {
6700 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6701 v1->set_lowerid_to_ref();
6702 tt1=v1->get_expr_returntype(exp_val);
6703 chk_expr_operandtype_int(tt1, first, opname, v1);
6704 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6705 chk_expr_val_int_pos0(v1, first, opname);
6706 }
6707 v2=u.expr.v2;
6708 {
6709 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6710 v2->set_lowerid_to_ref();
6711 tt2=v2->get_expr_returntype(exp_val);
6712 chk_expr_operandtype_int(tt2, second, opname, v2);
6713 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6714 chk_expr_val_int_pos0(v2, second, opname);
6715 }
6716 chk_expr_operands_int2binstr();
6717 break;
6718 case OPTYPE_DECODE:
6719 chk_expr_operands_decode();
6720 break;
6721 case OPTYPE_SUBSTR:
6722 {
6723 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6724 Type::expected_value_t ti_exp_val = exp_val;
6725 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6726 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6727 if (!governor) return;
6728 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6729 if (valuetype!=V_ERROR)
6730 u.expr.ti1->get_Template()->chk_specific_value(false);
6731 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6732 }
6733 v2=u.expr.v2;
6734 {
6735 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6736 v2->set_lowerid_to_ref();
6737 tt2=v2->get_expr_returntype(exp_val);
6738 chk_expr_operandtype_int(tt2, second, opname, v2);
6739 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6740 chk_expr_val_int_pos0(v2, second, opname);
6741 }
6742 v3=u.expr.v3;
6743 {
6744 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6745 v3->set_lowerid_to_ref();
6746 tt3=v3->get_expr_returntype(exp_val);
6747 chk_expr_operandtype_int(tt3, third, opname, v3);
6748 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6749 chk_expr_val_int_pos0(v3, third, opname);
6750 }
6751 chk_expr_operands_substr();
6752 break;
6753 case OPTYPE_REGEXP: {
6754 Type::expected_value_t ti_exp_val = exp_val;
6755 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6756 {
6757 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6758 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6759 if (!governor) return;
6760 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6761 if (valuetype!=V_ERROR) {
6762 u.expr.ti1->get_Template()->chk_specific_value(false);
6763 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6764 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6765 }
6766 }
6767 {
6768 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6769 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6770 if (!governor) return;
6771 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6772 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6773 get_typetype_ttcn3(), second, opname, u.expr.t2);
6774 }
6775 v3=u.expr.v3;
6776 {
6777 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6778 v3->set_lowerid_to_ref();
6779 tt3=v3->get_expr_returntype(exp_val);
6780 chk_expr_operandtype_int(tt3, third, opname, v3);
6781 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6782 chk_expr_val_int_pos0(v3, third, opname);
6783 }
6784 chk_expr_operands_regexp();
6785 } break;
6786 case OPTYPE_ISCHOSEN:
6787 // do nothing: the operand is erroneous
6788 // the error was already reported in chk_expr_ref_ischosen()
6789 break;
6790 case OPTYPE_ISCHOSEN_V: // v1 i2
6791 case OPTYPE_ISCHOSEN_T: // t1 i2
6792 chk_expr_operands_ischosen(refch, exp_val);
6793 break;
6794 case OPTYPE_VALUEOF: { // ti1
6795 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6796 exp_val = Type::EXPECTED_TEMPLATE;
6797 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6798 Type *governor = my_governor;
6799 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6800 if (!governor) return;
6801 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6802 if (valuetype == V_ERROR) return;
6803 u.expr.ti1->get_Template()->chk_specific_value(false);
6804 break; }
6805 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6806 case OPTYPE_ISBOUND: {
6807 Template *templ = u.expr.ti1->get_Template();
6808 switch (templ->get_templatetype()) {
6809 case Template::TEMPLATE_REFD:
6810 templ->get_reference()->setUsedInIsbound();
6811 break;
6812 case Template::SPECIFIC_VALUE: {
6813 Value *value = templ->get_specific_value();
6814 if (Value::V_REFD == value->get_valuetype()) {
6815 value->get_reference()->setUsedInIsbound();
6816 }
6817 break; }
6818 default:
6819 break;
6820 }
6821 }
6822 // no break
6823 case OPTYPE_ISVALUE: {// ti1
6824 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6825 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6826 exp_val = Type::EXPECTED_TEMPLATE;
6827 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6828 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6829 if (!governor) return;
6830 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6831 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6832 break; }
6833 case OPTYPE_SIZEOF: // ti1
6834 /* this checking is too complex, do the checking during eval... */
6835 break;
6836 case OPTYPE_LENGTHOF: { // ti1
6837 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6838 exp_val = Type::EXPECTED_TEMPLATE;
6839 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6840 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6841 if (!governor) return;
6842 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
6843 if (valuetype == V_ERROR) return;
6844 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6845 break; }
6846 case OPTYPE_MATCH: // v1 t2
6847 chk_expr_operands_match(exp_val);
6848 break;
6849 case OPTYPE_UNDEF_RUNNING: // r1
6850 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
6851 break;
6852 case OPTYPE_COMP_ALIVE:
6853 case OPTYPE_COMP_RUNNING: //v1
6854 chk_expr_operand_compref(u.expr.v1, the, opname);
6855 chk_expr_dynamic_part(exp_val, false);
6856 break;
6857 case OPTYPE_TMR_READ: // r1
6858 case OPTYPE_TMR_RUNNING: // r1
6859 chk_expr_operand_tmrref(u.expr.r1, the, opname);
6860 chk_expr_dynamic_part(exp_val, true);
6861 break;
6862 case OPTYPE_EXECUTE: // r1 [v2] // testcase
6863 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
6864 chk_expr_dynamic_part(exp_val, true, false, false);
6865 break;
6866 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
6867 chk_expr_operand_comptyperef_create();
6868 v2=u.expr.v2;
6869 if(v2) {
6870 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6871 v2->set_lowerid_to_ref();
6872 tt2=v2->get_expr_returntype(exp_val);
6873 chk_expr_operandtype_cstr(tt2, first, opname, v2);
6874 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6875 }
6876 v3=u.expr.v3;
6877 if(v3) {
6878 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6879 v3->set_lowerid_to_ref();
6880 tt3=v3->get_expr_returntype(exp_val);
6881 chk_expr_operandtype_cstr(tt3, second, opname, v3);
6882 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6883 }
6884 chk_expr_dynamic_part(exp_val, false);
6885 break;
6886 case OPTYPE_ACTIVATE: // r1 // altstep
6887 chk_expr_operand_activate(u.expr.r1, the, opname);
6888 chk_expr_dynamic_part(exp_val, true);
6889 break;
6890 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
6891 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6892 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
6893 opname);
6894 delete u.expr.t_list2;
6895 u.expr.ap_list2 = parlist;
6896 chk_expr_dynamic_part(exp_val, true);
6897 break; }
6898 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
6899 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6900 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
6901 u.expr.v3, the, opname);
6902 delete u.expr.t_list2;
6903 u.expr.ap_list2 = parlist;
6904 chk_expr_dynamic_part(exp_val, true);
6905 break; }
6906 case OPTYPE_DECOMP:
6907 error("Built-in function `%s' is not yet supported", opname);
6908 set_valuetype(V_ERROR);
6909 break;
6910 case OPTYPE_REPLACE: {
6911 Type::expected_value_t ti_exp_val = exp_val;
6912 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6913 ti_exp_val = Type::EXPECTED_TEMPLATE;
6914 {
6915 Error_Context cntxt(this, "In the first operand of operation `%s'",
6916 opname);
6917 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6918 if (!governor) return;
6919 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6920 if (valuetype != V_ERROR)
6921 u.expr.ti1->get_Template()->chk_specific_value(false);
6922 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6923 }
6924 v2 = u.expr.v2;
6925 {
6926 Error_Context cntxt(this, "In the second operand of operation `%s'",
6927 opname);
6928 v2->set_lowerid_to_ref();
6929 tt2 = v2->get_expr_returntype(exp_val);
6930 chk_expr_operandtype_int(tt2, second, opname, v2);
6931 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6932 chk_expr_val_int_pos0(v2, second, opname);
6933 }
6934 v3 = u.expr.v3;
6935 {
6936 Error_Context cntxt(this, "In the third operand of operation `%s'",
6937 opname);
6938 v3->set_lowerid_to_ref();
6939 tt3 = v3->get_expr_returntype(exp_val);
6940 chk_expr_operandtype_int(tt3, third, opname, v3);
6941 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6942 chk_expr_val_int_pos0(v3, third, opname);
6943 }
6944 {
6945 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
6946 opname);
6947 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
6948 if (!governor) return;
6949 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
6950 if (valuetype != V_ERROR)
6951 u.expr.ti4->get_Template()->chk_specific_value(false);
6952 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
6953 }
6954 chk_expr_operands_replace();
6955 break; }
6956 case OPTYPE_LOG2STR: {
6957 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6958 u.expr.logargs->chk();
6959 if (!semantic_check_only) u.expr.logargs->join_strings();
6960 break; }
6961 case OPTYPE_TTCN2STRING: {
6962 Error_Context cntxt(this, "In the parameter of ttcn2string()");
6963 Type::expected_value_t ti_exp_val = exp_val;
6964 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6965 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6966 if (!governor) return;
6967 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6968 } break;
6969 default:
6970 FATAL_ERROR("chk_expr_operands()");
6971 } // switch optype
6972 }
6973
6974 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6975 // the result of evaluating the expression. E.g. V_BOOL for
6976 // OPTYPE_ISCHOSEN.
6977 void Value::evaluate_value(ReferenceChain *refch,
6978 Type::expected_value_t exp_val)
6979 {
6980 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
6981 if(u.expr.state!=EXPR_NOT_CHECKED) return;
6982
6983 u.expr.state=EXPR_CHECKING;
6984
6985 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
6986 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
6987 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
6988
6989 if(valuetype==V_ERROR) return;
6990 if(u.expr.state==EXPR_CHECKING_ERR) {
6991 u.expr.state=EXPR_CHECKED;
6992 set_valuetype(V_ERROR);
6993 return;
6994 }
6995
6996 u.expr.state=EXPR_CHECKED;
6997
6998 Value *v1, *v2, *v3, *v4;
6999 switch(u.expr.v_optype) {
7000 case OPTYPE_RND: // -
7001 case OPTYPE_COMP_NULL: // the only foldable in this group
7002 case OPTYPE_COMP_MTC:
7003 case OPTYPE_COMP_SYSTEM:
7004 case OPTYPE_COMP_SELF:
7005 case OPTYPE_COMP_RUNNING_ANY:
7006 case OPTYPE_COMP_RUNNING_ALL:
7007 case OPTYPE_COMP_ALIVE_ANY:
7008 case OPTYPE_COMP_ALIVE_ALL:
7009 case OPTYPE_TMR_RUNNING_ANY:
7010 case OPTYPE_GETVERDICT:
7011 case OPTYPE_PROF_RUNNING:
7012 case OPTYPE_RNDWITHVAL: // v1
7013 case OPTYPE_COMP_RUNNING: // v1
7014 case OPTYPE_COMP_ALIVE:
7015 case OPTYPE_TMR_READ:
7016 case OPTYPE_TMR_RUNNING:
7017 case OPTYPE_ACTIVATE:
7018 case OPTYPE_ACTIVATE_REFD:
7019 case OPTYPE_EXECUTE: // r1 [v2]
7020 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7021 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7022 case OPTYPE_MATCH: // v1 t2
7023 case OPTYPE_ISCHOSEN_T:
7024 case OPTYPE_LOG2STR:
7025 case OPTYPE_ENCODE:
7026 case OPTYPE_DECODE:
7027 case OPTYPE_ISBOUND:
7028 case OPTYPE_ISPRESENT:
7029 case OPTYPE_TTCN2STRING:
7030 case OPTYPE_UNICHAR2OCT:
7031 case OPTYPE_OCT2UNICHAR:
7032 case OPTYPE_ENCODE_BASE64:
7033 case OPTYPE_DECODE_BASE64:
7034 break;
7035 case OPTYPE_TESTCASENAME: { // -
7036 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7037 Ttcn::StatementBlock *my_sb =
7038 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7039 if (!my_sb) break;
7040 Ttcn::Definition *my_def = my_sb->get_my_def();
7041 if (!my_def) { // In control part.
7042 set_val_str(new string(""));
7043 valuetype = V_CSTR;
7044 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7045 set_val_str(new string(my_def->get_id().get_dispname()));
7046 valuetype = V_CSTR;
7047 }
7048 break; }
7049 case OPTYPE_UNARYPLUS: // v1
7050 v1=u.expr.v1;
7051 u.expr.v1=0;
7052 copy_and_destroy(v1);
7053 break;
7054 case OPTYPE_UNARYMINUS:
7055 if (is_unfoldable()) break;
7056 v1 = u.expr.v1->get_value_refd_last();
7057 switch (v1->valuetype) {
7058 case V_INT: {
7059 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7060 if (!i) FATAL_ERROR("Value::evaluate_value()");
7061 clean_up();
7062 valuetype = V_INT;
7063 u.val_Int = i;
7064 break; }
7065 case V_REAL: {
7066 ttcn3float r = v1->get_val_Real();
7067 clean_up();
7068 valuetype = V_REAL;
7069 u.val_Real = -r;
7070 break; }
7071 default:
7072 FATAL_ERROR("Value::evaluate_value()");
7073 }
7074 break;
7075 case OPTYPE_NOT: {
7076 if(is_unfoldable()) break;
7077 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7078 clean_up();
7079 valuetype=V_BOOL;
7080 u.val_bool=!b;
7081 break;}
7082 case OPTYPE_NOT4B: {
7083 if(is_unfoldable()) break;
7084 v1=u.expr.v1->get_value_refd_last();
7085 const string& s = v1->get_val_str();
7086 valuetype_t vt=v1->valuetype;
7087 clean_up();
7088 valuetype=vt;
7089 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7090 break;}
7091 case OPTYPE_BIT2HEX: {
7092 if(is_unfoldable()) break;
7093 v1=u.expr.v1->get_value_refd_last();
7094 const string& s = v1->get_val_str();
7095 clean_up();
7096 valuetype=V_HSTR;
7097 set_val_str(bit2hex(s));
7098 break;}
7099 case OPTYPE_BIT2OCT: {
7100 if(is_unfoldable()) break;
7101 v1=u.expr.v1->get_value_refd_last();
7102 const string& s = v1->get_val_str();
7103 clean_up();
7104 valuetype=V_OSTR;
7105 set_val_str(bit2oct(s));
7106 break;}
7107 case OPTYPE_BIT2STR:
7108 case OPTYPE_HEX2STR:
7109 case OPTYPE_OCT2STR: {
7110 if(is_unfoldable()) break;
7111 v1=u.expr.v1->get_value_refd_last();
7112 const string& s = v1->get_val_str();
7113 clean_up();
7114 valuetype=V_CSTR;
7115 set_val_str(new string(s));
7116 break;}
7117 case OPTYPE_BIT2INT: {
7118 if (is_unfoldable()) break;
7119 v1 = u.expr.v1->get_value_refd_last();
7120 const string& s = v1->get_val_str();
7121 clean_up();
7122 valuetype = V_INT;
7123 u.val_Int = bit2int(s);
7124 break; }
7125 case OPTYPE_CHAR2INT: {
7126 if (is_unfoldable()) break;
7127 v1 = u.expr.v1->get_value_refd_last();
7128 char c = v1->get_val_str()[0];
7129 clean_up();
7130 valuetype = V_INT;
7131 u.val_Int = new int_val_t((Int)c);
7132 break; }
7133 case OPTYPE_CHAR2OCT: {
7134 if(is_unfoldable()) break;
7135 v1=u.expr.v1->get_value_refd_last();
7136 const string& s = v1->get_val_str();
7137 clean_up();
7138 valuetype=V_OSTR;
7139 set_val_str(char2oct(s));
7140 break;}
7141 case OPTYPE_STR2INT: {
7142 if (is_unfoldable()) break;
7143 v1 = u.expr.v1->get_value_refd_last();
7144 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7145 clean_up();
7146 valuetype = V_INT;
7147 u.val_Int = i;
7148 /** \todo hiba eseten lenyeli... */
7149 break; }
7150 case OPTYPE_STR2FLOAT: {
7151 if(is_unfoldable()) break;
7152 v1=u.expr.v1->get_value_refd_last();
7153 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7154 clean_up();
7155 valuetype=V_REAL;
7156 u.val_Real=r;
7157 /** \todo hiba eseten lenyeli... */
7158 break;}
7159 case OPTYPE_STR2BIT: {
7160 if(is_unfoldable()) break;
7161 v1=u.expr.v1->get_value_refd_last();
7162 const string& s = v1->get_val_str();
7163 clean_up();
7164 valuetype=V_BSTR;
7165 set_val_str(new string(s));
7166 break;}
7167 case OPTYPE_STR2HEX:
7168 case OPTYPE_OCT2HEX: {
7169 if(is_unfoldable()) break;
7170 v1=u.expr.v1->get_value_refd_last();
7171 const string& s = v1->get_val_str();
7172 clean_up();
7173 valuetype=V_HSTR;
7174 set_val_str(to_uppercase(s));
7175 break;}
7176 case OPTYPE_STR2OCT: {
7177 if(is_unfoldable()) break;
7178 v1=u.expr.v1->get_value_refd_last();
7179 const string& s = v1->get_val_str();
7180 clean_up();
7181 valuetype=V_OSTR;
7182 set_val_str(to_uppercase(s));
7183 break;}
7184 case OPTYPE_FLOAT2INT: {
7185 if (is_unfoldable()) break;
7186 v1 = u.expr.v1->get_value_refd_last();
7187 ttcn3float r = v1->get_val_Real();
7188 clean_up();
7189 valuetype = V_INT;
7190 u.val_Int = float2int(r, *u.expr.v1);
7191 break;}
7192 case OPTYPE_FLOAT2STR: {
7193 if(is_unfoldable()) break;
7194 v1=u.expr.v1->get_value_refd_last();
7195 ttcn3float r=v1->get_val_Real();
7196 clean_up();
7197 valuetype=V_CSTR;
7198 set_val_str(float2str(r));
7199 break;}
7200 case OPTYPE_HEX2BIT:
7201 case OPTYPE_OCT2BIT: {
7202 if(is_unfoldable()) break;
7203 v1=u.expr.v1->get_value_refd_last();
7204 const string& s = v1->get_val_str();
7205 clean_up();
7206 valuetype=V_BSTR;
7207 set_val_str(hex2bit(s));
7208 break;}
7209 case OPTYPE_HEX2INT:
7210 case OPTYPE_OCT2INT: {
7211 if(is_unfoldable()) break;
7212 v1=u.expr.v1->get_value_refd_last();
7213 const string& s = v1->get_val_str();
7214 clean_up();
7215 valuetype=V_INT;
7216 u.val_Int=hex2int(s);
7217 break;}
7218 case OPTYPE_HEX2OCT: {
7219 if(is_unfoldable()) break;
7220 v1=u.expr.v1->get_value_refd_last();
7221 const string& s = v1->get_val_str();
7222 clean_up();
7223 valuetype=V_OSTR;
7224 set_val_str(hex2oct(s));
7225 break;}
7226 case OPTYPE_INT2CHAR: {
7227 if (is_unfoldable()) break;
7228 v1 = u.expr.v1->get_value_refd_last();
7229 const int_val_t *c_int = v1->get_val_Int();
7230 char c = static_cast<char>(c_int->get_val());
7231 clean_up();
7232 valuetype = V_CSTR;
7233 set_val_str(new string(1, &c));
7234 break; }
7235 case OPTYPE_INT2UNICHAR: {
7236 if (is_unfoldable()) break;
7237 v1 = u.expr.v1->get_value_refd_last();
7238 const int_val_t *i_int = v1->get_val_Int();
7239 Int i = i_int->get_val();
7240 clean_up();
7241 valuetype = V_USTR;
7242 set_val_ustr(int2unichar(i));
7243 u.ustr.convert_str = false;
7244 break; }
7245 case OPTYPE_INT2FLOAT: {
7246 if (is_unfoldable()) break;
7247 v1 = u.expr.v1->get_value_refd_last();
7248 const int_val_t *i_int = v1->get_val_Int();
7249 Real i_int_real = i_int->to_real();
7250 clean_up();
7251 valuetype = V_REAL;
7252 u.val_Real = i_int_real;
7253 break; }
7254 case OPTYPE_INT2STR: {
7255 if (is_unfoldable()) break;
7256 v1 = u.expr.v1->get_value_refd_last();
7257 const int_val_t *i_int = v1->get_val_Int();
7258 string *i_int_str = new string(i_int->t_str());
7259 clean_up();
7260 valuetype = V_CSTR;
7261 set_val_str(i_int_str);
7262 break; }
7263 case OPTYPE_OCT2CHAR: {
7264 if(is_unfoldable()) break;
7265 v1=u.expr.v1->get_value_refd_last();
7266 const string& s = v1->get_val_str();
7267 clean_up();
7268 valuetype=V_CSTR;
7269 set_val_str(oct2char(s));
7270 break;}
7271 case OPTYPE_GET_STRINGENCODING: {
7272 if(is_unfoldable()) break;
7273 v1 = u.expr.v1->get_value_refd_last();
7274 const string& s1 = v1->get_val_str();
7275 clean_up();
7276 valuetype = V_CSTR;
7277 set_val_str(get_stringencoding(s1));
7278 break;}
7279 case OPTYPE_REMOVE_BOM: {
7280 if(is_unfoldable()) break;
7281 v1 = u.expr.v1->get_value_refd_last();
7282 const string& s1 = v1->get_val_str();
7283 clean_up();
7284 valuetype = V_OSTR;
7285 set_val_str(remove_bom(s1));
7286 break;}
7287 case OPTYPE_ENUM2INT: {
7288 if(is_unfoldable()) break;
7289 v1=u.expr.v1->get_value_refd_last();
7290 Type* enum_type = v1->get_my_governor();
7291 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7292 clean_up();
7293 valuetype = V_INT;
7294 u.val_Int = new int_val_t(enum_val);
7295 break;}
7296 case OPTYPE_UNICHAR2INT:
7297 if (is_unfoldable()) {
7298 // replace the operation with char2int() if the operand is a charstring
7299 // value to avoid its unnecessary conversion to universal charstring
7300 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7301 u.expr.v_optype = OPTYPE_CHAR2INT;
7302 } else {
7303 v1=u.expr.v1->get_value_refd_last();
7304 const ustring& s = v1->get_val_ustr();
7305 clean_up();
7306 valuetype=V_INT;
7307 u.val_Int=new int_val_t(unichar2int(s));
7308 }
7309 break;
7310 case OPTYPE_UNICHAR2CHAR:
7311 v1 = u.expr.v1;
7312 if (is_unfoldable()) {
7313 // replace the operation with its operand if it is a charstring
7314 // value to avoid its unnecessary conversion to universal charstring
7315 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7316 u.expr.v1 = 0;
7317 copy_and_destroy(v1);
7318 }
7319 } else {
7320 v1 = v1->get_value_refd_last();
7321 const ustring& s = v1->get_val_ustr();
7322 clean_up();
7323 valuetype = V_CSTR;
7324 set_val_str(new string(s));
7325 }
7326 break;
7327 case OPTYPE_MULTIPLY: { // v1 v2
7328 if (!is_unfoldable()) goto eval_arithmetic;
7329 v1 = u.expr.v1->get_value_refd_last();
7330 v2 = u.expr.v2->get_value_refd_last();
7331 if (v1->is_unfoldable()) v1 = v2;
7332 if (v1->is_unfoldable()) break;
7333 switch(v1->valuetype) {
7334 case V_INT: {
7335 if (*v1->get_val_Int() != 0) break;
7336 clean_up();
7337 valuetype = V_INT;
7338 u.val_Int = new int_val_t((Int)0);
7339 break; }
7340 case V_REAL: {
7341 if (v1->get_val_Real() != 0.0) break;
7342 clean_up();
7343 valuetype = V_REAL;
7344 u.val_Real = 0.0;
7345 break; }
7346 default:
7347 FATAL_ERROR("Value::evaluate_value()");
7348 }
7349 break; }
7350 case OPTYPE_ADD: // v1 v2
7351 case OPTYPE_SUBTRACT:
7352 case OPTYPE_DIVIDE:
7353 case OPTYPE_MOD:
7354 case OPTYPE_REM: {
7355 eval_arithmetic:
7356 if(is_unfoldable()) break;
7357 v1=u.expr.v1->get_value_refd_last();
7358 v2=u.expr.v2->get_value_refd_last();
7359 operationtype_t ot=u.expr.v_optype;
7360 switch (v1->valuetype) {
7361 case V_INT: {
7362 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7363 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7364 clean_up();
7365 valuetype = V_INT;
7366 switch (ot) {
7367 case OPTYPE_ADD:
7368 u.val_Int = new int_val_t(*i1 + *i2);
7369 break;
7370 case OPTYPE_SUBTRACT:
7371 u.val_Int = new int_val_t(*i1 - *i2);
7372 break;
7373 case OPTYPE_MULTIPLY:
7374 u.val_Int = new int_val_t(*i1 * *i2);
7375 break;
7376 case OPTYPE_DIVIDE:
7377 u.val_Int = new int_val_t(*i1 / *i2);
7378 break;
7379 case OPTYPE_MOD:
7380 u.val_Int = new int_val_t(mod(*i1, *i2));
7381 break;
7382 case OPTYPE_REM:
7383 u.val_Int = new int_val_t(rem(*i1, *i2));
7384 break;
7385 default:
7386 FATAL_ERROR("Value::evaluate_value()");
7387 }
7388 delete i1;
7389 delete i2;
7390 break; }
7391 case V_REAL: {
7392 ttcn3float r1=v1->get_val_Real();
7393 ttcn3float r2=v2->get_val_Real();
7394 clean_up();
7395 valuetype=V_REAL;
7396 switch(ot) {
7397 case OPTYPE_ADD:
7398 u.val_Real=r1+r2;
7399 break;
7400 case OPTYPE_SUBTRACT:
7401 u.val_Real=r1-r2;
7402 break;
7403 case OPTYPE_MULTIPLY:
7404 u.val_Real=r1*r2;
7405 break;
7406 case OPTYPE_DIVIDE:
7407 u.val_Real=r1/r2;
7408 break;
7409 default:
7410 FATAL_ERROR("Value::evaluate_value()");
7411 }
7412 break;}
7413 default:
7414 FATAL_ERROR("Value::evaluate_value()");
7415 }
7416 break;}
7417 case OPTYPE_CONCAT: {
7418 if(is_unfoldable()) break;
7419 v1=u.expr.v1->get_value_refd_last();
7420 v2=u.expr.v2->get_value_refd_last();
7421 valuetype_t vt = v1->valuetype;
7422 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7423 const ustring& s1 = v1->get_val_ustr();
7424 const ustring& s2 = v2->get_val_ustr();
7425 clean_up();
7426 valuetype = V_USTR;
7427 set_val_ustr(new ustring(s1 + s2));
7428 u.ustr.convert_str = false;
7429 } else {
7430 const string& s1 = v1->get_val_str();
7431 const string& s2 = v2->get_val_str();
7432 clean_up();
7433 valuetype = vt;
7434 set_val_str(new string(s1 + s2));
7435 }
7436 break;}
7437 case OPTYPE_EQ: {
7438 if(is_unfoldable()) break;
7439 v1=u.expr.v1->get_value_refd_last();
7440 v2=u.expr.v2->get_value_refd_last();
7441 bool b=*v1==*v2;
7442 clean_up();
7443 valuetype=V_BOOL;
7444 u.val_bool=b;
7445 break;}
7446 case OPTYPE_NE: {
7447 if(is_unfoldable()) break;
7448 v1=u.expr.v1->get_value_refd_last();
7449 v2=u.expr.v2->get_value_refd_last();
7450 bool b=*v1==*v2;
7451 clean_up();
7452 valuetype=V_BOOL;
7453 u.val_bool=!b;
7454 break;}
7455 case OPTYPE_LT: {
7456 if(is_unfoldable()) break;
7457 v1=u.expr.v1->get_value_refd_last();
7458 v2=u.expr.v2->get_value_refd_last();
7459 bool b=*v1<*v2;
7460 clean_up();
7461 valuetype=V_BOOL;
7462 u.val_bool=b;
7463 break;}
7464 case OPTYPE_GT: {
7465 if(is_unfoldable()) break;
7466 v1=u.expr.v1->get_value_refd_last();
7467 v2=u.expr.v2->get_value_refd_last();
7468 bool b=*v2<*v1;
7469 clean_up();
7470 valuetype=V_BOOL;
7471 u.val_bool=b;
7472 break;}
7473 case OPTYPE_GE: {
7474 if(is_unfoldable()) break;
7475 v1=u.expr.v1->get_value_refd_last();
7476 v2=u.expr.v2->get_value_refd_last();
7477 bool b=*v1<*v2;
7478 clean_up();
7479 valuetype=V_BOOL;
7480 u.val_bool=!b;
7481 break;}
7482 case OPTYPE_LE: {
7483 if(is_unfoldable()) break;
7484 v1=u.expr.v1->get_value_refd_last();
7485 v2=u.expr.v2->get_value_refd_last();
7486 bool b=*v2<*v1;
7487 clean_up();
7488 valuetype=V_BOOL;
7489 u.val_bool=!b;
7490 break;}
7491 case OPTYPE_AND:
7492 v1 = u.expr.v1->get_value_refd_last();
7493 if (v1->valuetype == V_BOOL) {
7494 if (v1->get_val_bool()) {
7495 // the left operand is a literal "true"
7496 // substitute the expression with the right operand
7497 v2 = u.expr.v2;
7498 u.expr.v2 = 0;
7499 copy_and_destroy(v2);
7500 } else {
7501 // the left operand is a literal "false"
7502 // the result must be false regardless the right operand
7503 // because of the short circuit evaluation rule
7504 clean_up();
7505 valuetype = V_BOOL;
7506 u.val_bool = false;
7507 }
7508 } else {
7509 // we must keep the left operand because of the potential side effects
7510 // the right operand can only be eliminated if it is a literal "true"
7511 v2 = u.expr.v2->get_value_refd_last();
7512 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7513 v1 = u.expr.v1;
7514 u.expr.v1 = 0;
7515 copy_and_destroy(v1);
7516 }
7517 }
7518 break;
7519 case OPTYPE_OR:
7520 v1 = u.expr.v1->get_value_refd_last();
7521 if (v1->valuetype == V_BOOL) {
7522 if (v1->get_val_bool()) {
7523 // the left operand is a literal "true"
7524 // the result must be true regardless the right operand
7525 // because of the short circuit evaluation rule
7526 clean_up();
7527 valuetype = V_BOOL;
7528 u.val_bool = true;
7529 } else {
7530 // the left operand is a literal "false"
7531 // substitute the expression with the right operand
7532 v2 = u.expr.v2;
7533 u.expr.v2 = 0;
7534 copy_and_destroy(v2);
7535 }
7536 } else {
7537 // we must keep the left operand because of the potential side effects
7538 // the right operand can only be eliminated if it is a literal "false"
7539 v2 = u.expr.v2->get_value_refd_last();
7540 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7541 v1 = u.expr.v1;
7542 u.expr.v1 = 0;
7543 copy_and_destroy(v1);
7544 }
7545 }
7546 break;
7547 case OPTYPE_XOR: {
7548 if(is_unfoldable()) break;
7549 v1=u.expr.v1->get_value_refd_last();
7550 v2=u.expr.v2->get_value_refd_last();
7551 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7552 clean_up();
7553 valuetype=V_BOOL;
7554 u.val_bool=b;
7555 break;}
7556 case OPTYPE_AND4B: {
7557 if(is_unfoldable()) break;
7558 v1=u.expr.v1->get_value_refd_last();
7559 v2=u.expr.v2->get_value_refd_last();
7560 valuetype_t vt=v1->valuetype;
7561 const string& s1 = v1->get_val_str();
7562 const string& s2 = v2->get_val_str();
7563 clean_up();
7564 valuetype=vt;
7565 set_val_str(and4b(s1, s2));
7566 break;}
7567 case OPTYPE_OR4B: {
7568 if(is_unfoldable()) break;
7569 v1=u.expr.v1->get_value_refd_last();
7570 v2=u.expr.v2->get_value_refd_last();
7571 valuetype_t vt=v1->valuetype;
7572 const string& s1 = v1->get_val_str();
7573 const string& s2 = v2->get_val_str();
7574 clean_up();
7575 valuetype=vt;
7576 set_val_str(or4b(s1, s2));
7577 break;}
7578 case OPTYPE_XOR4B: {
7579 if(is_unfoldable()) break;
7580 v1=u.expr.v1->get_value_refd_last();
7581 v2=u.expr.v2->get_value_refd_last();
7582 valuetype_t vt=v1->valuetype;
7583 const string& s1 = v1->get_val_str();
7584 const string& s2 = v2->get_val_str();
7585 clean_up();
7586 valuetype=vt;
7587 set_val_str(xor4b(s1, s2));
7588 break;}
7589 case OPTYPE_SHL: {
7590 if(is_unfoldable()) break;
7591 v1=u.expr.v1->get_value_refd_last();
7592 v2=u.expr.v2->get_value_refd_last();
7593 valuetype_t vt=v1->valuetype;
7594 const string& s = v1->get_val_str();
7595 const int_val_t *i_int = v2->get_val_Int();
7596 Int i=i_int->get_val();
7597 if(vt==V_OSTR) i*=2;
7598 clean_up();
7599 valuetype=vt;
7600 set_val_str(shift_left(s, i));
7601 break;}
7602 case OPTYPE_SHR: {
7603 if(is_unfoldable()) break;
7604 v1=u.expr.v1->get_value_refd_last();
7605 v2=u.expr.v2->get_value_refd_last();
7606 valuetype_t vt=v1->valuetype;
7607 const string& s = v1->get_val_str();
7608 const int_val_t *i_int = v2->get_val_Int();
7609 Int i=i_int->get_val();
7610 if(vt==V_OSTR) i*=2;
7611 clean_up();
7612 valuetype=vt;
7613 set_val_str(shift_right(s, i));
7614 break;}
7615 case OPTYPE_ROTL: {
7616 if(is_unfoldable()) break;
7617 v1=u.expr.v1->get_value_refd_last();
7618 v2=u.expr.v2->get_value_refd_last();
7619 valuetype_t vt=v1->valuetype;
7620 const int_val_t *i_int=v2->get_val_Int();
7621 Int i=i_int->get_val();
7622 if(vt==V_USTR) {
7623 const ustring& s = v1->get_val_ustr();
7624 clean_up();
7625 valuetype=vt;
7626 set_val_ustr(rotate_left(s, i));
7627 u.ustr.convert_str = false;
7628 }
7629 else {
7630 if(vt==V_OSTR) i*=2;
7631 const string& s = v1->get_val_str();
7632 clean_up();
7633 valuetype=vt;
7634 set_val_str(rotate_left(s, i));
7635 }
7636 break;}
7637 case OPTYPE_ROTR: {
7638 if(is_unfoldable()) break;
7639 v1=u.expr.v1->get_value_refd_last();
7640 v2=u.expr.v2->get_value_refd_last();
7641 valuetype_t vt=v1->valuetype;
7642 const int_val_t *i_int=v2->get_val_Int();
7643 Int i=i_int->get_val();
7644 if(vt==V_USTR) {
7645 const ustring& s = v1->get_val_ustr();
7646 clean_up();
7647 valuetype=vt;
7648 set_val_ustr(rotate_right(s, i));
7649 u.ustr.convert_str = false;
7650 }
7651 else {
7652 if(vt==V_OSTR) i*=2;
7653 const string& s = v1->get_val_str();
7654 clean_up();
7655 valuetype=vt;
7656 set_val_str(rotate_right(s, i));
7657 }
7658 break;}
7659 case OPTYPE_INT2BIT: {
7660 if (is_unfoldable()) break;
7661 v1 = u.expr.v1->get_value_refd_last();
7662 v2 = u.expr.v2->get_value_refd_last();
7663 const int_val_t *i1_int = v1->get_val_Int();
7664 const int_val_t *i2_int = v2->get_val_Int();
7665 string *val = int2bit(*i1_int, i2_int->get_val());
7666 clean_up();
7667 valuetype = V_BSTR;
7668 set_val_str(val);
7669 break; }
7670 case OPTYPE_INT2HEX: {
7671 if (is_unfoldable()) break;
7672 v1 = u.expr.v1->get_value_refd_last();
7673 v2 = u.expr.v2->get_value_refd_last();
7674 const int_val_t *i1_int = v1->get_val_Int();
7675 const int_val_t *i2_int = v2->get_val_Int();
7676 // Do it before the `clean_up'. i2_int is already checked.
7677 string *val = int2hex(*i1_int, i2_int->get_val());
7678 clean_up();
7679 valuetype = V_HSTR;
7680 set_val_str(val);
7681 break; }
7682 case OPTYPE_INT2OCT: {
7683 if (is_unfoldable()) break;
7684 v1 = u.expr.v1->get_value_refd_last();
7685 v2 = u.expr.v2->get_value_refd_last();
7686 const int_val_t i1_int(*v1->get_val_Int());
7687 // `v2' is a native integer.
7688 Int i2_int = v2->get_val_Int()->get_val() * 2;
7689 clean_up();
7690 valuetype = V_OSTR;
7691 set_val_str(int2hex(i1_int, i2_int));
7692 break; }
7693 case OPTYPE_SUBSTR: {
7694 if(is_unfoldable()) break;
7695 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7696 v2=u.expr.v2->get_value_refd_last();
7697 v3=u.expr.v3->get_value_refd_last();
7698 valuetype_t vt=v1->valuetype;
7699 const int_val_t *i2_int=v2->get_val_Int();
7700 const int_val_t *i3_int=v3->get_val_Int();
7701 Int i2=i2_int->get_val();
7702 Int i3=i3_int->get_val();
7703 if(vt==V_USTR) {
7704 const ustring& s = v1->get_val_ustr();
7705 clean_up();
7706 valuetype=vt;
7707 set_val_ustr(new ustring(s.substr(i2, i3)));
7708 u.ustr.convert_str = false;
7709 }
7710 else {
7711 if(vt==V_OSTR) {
7712 i2*=2;
7713 i3*=2;
7714 }
7715 const string& s = v1->get_val_str();
7716 clean_up();
7717 valuetype=vt;
7718 set_val_str(new string(s.substr(i2, i3)));
7719 }
7720 break;}
7721 case OPTYPE_REPLACE: {
7722 if(is_unfoldable()) break;
7723 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7724 v2=u.expr.v2->get_value_refd_last();
7725 v3=u.expr.v3->get_value_refd_last();
7726 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7727 valuetype_t vt=v1->valuetype;
7728 const int_val_t *i2_int=v2->get_val_Int();
7729 const int_val_t *i3_int=v3->get_val_Int();
7730 Int i2=i2_int->get_val();
7731 Int i3=i3_int->get_val();
7732 switch(vt) {
7733 case V_BSTR: {
7734 string *s1 = new string(v1->get_val_str());
7735 const string& s2 = v4->get_val_str();
7736 clean_up();
7737 valuetype=vt;
7738 s1->replace(i2, i3, s2);
7739 set_val_str(s1);
7740 break;}
7741 case V_HSTR: {
7742 string *s1 = new string(v1->get_val_str());
7743 const string& s2 = v4->get_val_str();
7744 clean_up();
7745 valuetype=vt;
7746 s1->replace(i2, i3, s2);
7747 set_val_str(s1);
7748 break;}
7749 case V_OSTR: {
7750 i2*=2;
7751 i3*=2;
7752 string *s1 = new string(v1->get_val_str());
7753 const string& s2 = v4->get_val_str();
7754 clean_up();
7755 valuetype=vt;
7756 s1->replace(i2, i3, s2);
7757 set_val_str(s1);
7758 break;}
7759 case V_CSTR: {
7760 string *s1 = new string(v1->get_val_str());
7761 const string& s2 = v4->get_val_str();
7762 clean_up();
7763 valuetype=vt;
7764 s1->replace(i2, i3, s2);
7765 set_val_str(s1);
7766 break;}
7767 case V_USTR: {
7768 ustring *s1 = new ustring(v1->get_val_ustr());
7769 const ustring& s2 = v4->get_val_ustr();
7770 clean_up();
7771 valuetype=vt;
7772 s1->replace(i2, i3, s2);
7773 set_val_ustr(s1);
7774 u.ustr.convert_str = false;
7775 break;}
7776 default:
7777 FATAL_ERROR("Value::evaluate_value()");
7778 }
7779 break; }
7780 case OPTYPE_REGEXP: {
7781 if (is_unfoldable()) break;
7782 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7783 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7784 v3=u.expr.v3->get_value_refd_last();
7785 const int_val_t *i3_int = v3->get_val_Int();
7786 Int i3 = i3_int->get_val();
7787 if (v1->valuetype == V_CSTR) {
7788 const string& s1 = v1->get_val_str();
7789 const string& s2 = v2->get_val_str();
7790 string *result = regexp(s1, s2, i3);
7791 clean_up();
7792 valuetype = V_CSTR;
7793 set_val_str(result);
7794 } if (v1->valuetype == V_USTR) {
7795 const ustring& s1 = v1->get_val_ustr();
7796 const ustring& s2 = v2->get_val_ustr();
7797 ustring *result = regexp(s1, s2, i3);
7798 clean_up();
7799 valuetype = V_USTR;
7800 set_val_ustr(result);
7801 u.ustr.convert_str = false;
7802 }
7803 break; }
7804 case OPTYPE_LENGTHOF:{
7805 if(is_unfoldable()) break;
7806 v1=u.expr.ti1->get_Template()->get_specific_value()
7807 ->get_value_refd_last();
7808 size_t i;
7809 if(v1->is_string_type(exp_val)) {
7810 i=v1->get_val_strlen();
7811 } else { // v1 is be seq/set of or array
7812 switch (v1->valuetype) {
7813 case V_SEQOF:
7814 case V_SETOF:
7815 case V_ARRAY: {
7816 if(v1->u.val_vs->is_indexed())
7817 { i = v1->u.val_vs->get_nof_ivs();}
7818 else { i = v1->u.val_vs->get_nof_vs();}
7819 break; }
7820 default:
7821 FATAL_ERROR("Value::evaluate_value()");
7822 }
7823 }
7824 clean_up();
7825 valuetype=V_INT;
7826 u.val_Int=new int_val_t(i);
7827 break;}
7828 case OPTYPE_SIZEOF: {
7829 Int i=chk_eval_expr_sizeof(refch, exp_val);
7830 if(i!=-1) {
7831 clean_up();
7832 valuetype=V_INT;
7833 u.val_Int=new int_val_t(i);
7834 }
7835 break;}
7836 case OPTYPE_ISVALUE: {
7837 if(is_unfoldable()) break;
7838 bool is_singleval = !u.expr.ti1->get_DerivedRef()
7839 && u.expr.ti1->get_Template()->is_Value();
7840 if (is_singleval) {
7841 Value * other_val = u.expr.ti1->get_Template()->get_Value();
7842 is_singleval = other_val->evaluate_isvalue(false);
7843 // is_singleval now contains the compile-time result of isvalue
7844 delete other_val;
7845 }
7846 clean_up();
7847 valuetype = V_BOOL;
7848 u.val_bool = is_singleval;
7849 break;}
7850 case OPTYPE_ISCHOSEN_V: {
7851 if (is_unfoldable()) break;
7852 v1 = u.expr.v1->get_value_refd_last();
7853 bool b = v1->field_is_chosen(*u.expr.i2);
7854 clean_up();
7855 valuetype = V_BOOL;
7856 u.val_bool = b;
7857 break; }
7858 case OPTYPE_VALUEOF: // ti1
7859 if (!u.expr.ti1->get_DerivedRef() &&
7860 u.expr.ti1->get_Template()->is_Value() &&
7861 !u.expr.ti1->get_Type()) {
7862 // FIXME actually if the template instance has a type
7863 // it might still be foldable.
7864 // the argument is a single specific value
7865 v1 = u.expr.ti1->get_Template()->get_Value();
7866 Type *governor = my_governor;
7867 if (governor == NULL) {
7868 governor = u.expr.ti1->get_expr_governor(exp_val);
7869 if (governor != NULL) governor = governor->get_type_refd_last();
7870 }
7871 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
7872 if (governor == NULL)
7873 FATAL_ERROR("Value::evaluate_value()");
7874 clean_up();
7875 valuetype = v1->valuetype;
7876 u = v1->u;
7877 set_my_governor(governor);
7878 if (valuetype == V_REFD && u.ref.refd_last == v1)
7879 u.ref.refd_last = this;
7880 v1->valuetype = V_ERROR;
7881 delete v1;
7882 }
7883 break;
7884 case OPTYPE_UNDEF_RUNNING:
7885 default:
7886 FATAL_ERROR("Value::evaluate_value()");
7887 } // switch optype
7888 }
7889
7890 bool Value::evaluate_isvalue(bool from_sequence)
7891 {
7892 switch (valuetype) {
7893 case V_OMIT:
7894 // Omit is not a value unless a member of a sequence or set
7895 return from_sequence;
7896 case V_NOTUSED:
7897 return false;
7898 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7899 case V_BOOL: /**< boolean */
7900 case V_NAMEDINT: /**< integer / named number */
7901 case V_NAMEDBITS: /**< named bits (identifiers) */
7902 case V_INT: /**< integer */
7903 case V_REAL: /**< real/float */
7904 case V_ENUM: /**< enumerated */
7905 case V_BSTR: /**< bitstring */
7906 case V_HSTR: /**< hexstring */
7907 case V_OSTR: /**< octetstring */
7908 case V_CSTR: /**< charstring */
7909 case V_USTR: /**< universal charstring */
7910 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
7911 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
7912 case V_OID: /**< object identifier */
7913 case V_ROID: /**< relative object identifier */
7914 case V_VERDICT: /**< all verdicts */
7915 return true; // values of built-in types return true
7916
7917 // Code below was adapted from is_unfoldable(), false returned early.
7918 case V_CHOICE:
7919 return u.choice.alt_value->evaluate_isvalue(false);
7920
7921 case V_SEQOF:
7922 case V_SETOF:
7923 case V_ARRAY:
7924 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
7925 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
7926 return false;
7927 }
7928 }
7929 return true;
7930
7931 case V_SEQ:
7932 case V_SET:
7933 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
7934 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
7935 ->evaluate_isvalue(true)) return false;
7936 }
7937 return true;
7938
7939 case V_REFD:
7940 // alas, get_value_refd_last prevents this function from const
7941 return get_value_refd_last()->evaluate_isvalue(false);
7942
7943 case V_EXPR:
7944 switch (u.expr.v_optype) {
7945 // A constant null component reference is a corner case: it is foldable
7946 // but escapes unmodified from evaluate_value.
7947 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7948 // or is transformed into some other valuetype in evaluate_value.
7949 case OPTYPE_COMP_NULL:
7950 return false;
7951 default:
7952 break; // and fall through to the FATAL_ERROR
7953 }
7954 // no break
7955 default:
7956 FATAL_ERROR("Value::evaluate_isvalue()");
7957 break;
7958 }
7959 return true;
7960 }
7961
7962 void Value::evaluate_macro(Type::expected_value_t exp_val)
7963 {
7964 switch (u.macro) {
7965 case MACRO_MODULEID:
7966 if (!my_scope)
7967 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7968 set_val_str(new string(my_scope->get_scope_mod()
7969 ->get_modid().get_dispname()));
7970 valuetype = V_CSTR;
7971 break;
7972 case MACRO_FILENAME:
7973 case MACRO_BFILENAME: {
7974 const char *t_filename = get_filename();
7975 if (!t_filename)
7976 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7977 set_val_str(new string(t_filename));
7978 valuetype = V_CSTR;
7979 break; }
7980 case MACRO_FILEPATH: {
7981 const char *t_filename = get_filename();
7982 if (!t_filename)
7983 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7984 char *t_filepath = canonize_input_file(t_filename);
7985 if (!t_filepath)
7986 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7987 set_val_str(new string(t_filepath));
7988 valuetype = V_CSTR;
7989 Free(t_filepath);
7990 break; }
7991 case MACRO_LINENUMBER: {
7992 int t_lineno = get_first_line();
7993 if (t_lineno <= 0)
7994 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7995 set_val_str(new string(Int2string(t_lineno)));
7996 valuetype = V_CSTR;
7997 break; }
7998 case MACRO_LINENUMBER_C: {
7999 int t_lineno = get_first_line();
8000 if (t_lineno <= 0)
8001 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8002 u.val_Int = new int_val_t(t_lineno);
8003 valuetype = V_INT;
8004 break; }
8005 case MACRO_DEFINITIONID: {
8006 // cut the second part from the fullname separated by dots
8007 const string& t_fullname = get_fullname();
8008 size_t first_char = t_fullname.find('.') + 1;
8009 if (first_char >= t_fullname.size())
8010 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8011 t_fullname.c_str());
8012 set_val_str(new string(t_fullname.substr(first_char,
8013 t_fullname.find('.', first_char) - first_char)));
8014 valuetype = V_CSTR;
8015 break; }
8016 case MACRO_SCOPE: {
8017 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8018 set_val_str(new string(my_scope->get_scopeMacro_name()));
8019 valuetype = V_CSTR;
8020 break;
8021 }
8022 case MACRO_TESTCASEID: {
8023 if (exp_val == Type::EXPECTED_CONSTANT ||
8024 exp_val == Type::EXPECTED_STATIC_VALUE) {
8025 error("A %s value was expected instead of macro `%%testcaseId', "
8026 "which is evaluated at runtime",
8027 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8028 goto error;
8029 }
8030 if (!my_scope)
8031 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8032 Ttcn::StatementBlock *my_sb =
8033 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8034 if (!my_sb) {
8035 error("Usage of macro %%testcaseId is allowed only within the "
8036 "statement blocks of functions, altsteps and testcases");
8037 goto error;
8038 }
8039 Ttcn::Definition *my_def = my_sb->get_my_def();
8040 if (!my_def) {
8041 error("Macro %%testcaseId cannot be used in the control part. "
8042 "It is allowed only within the statement blocks of functions, "
8043 "altsteps and testcases");
8044 goto error;
8045 }
8046 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8047 // folding is possible only within testcases
8048 set_val_str(new string(my_def->get_id().get_dispname()));
8049 valuetype = V_CSTR;
8050 }
8051 break; }
8052 default:
8053 FATAL_ERROR("Value::evaluate_macro()");
8054 }
8055 return;
8056 error:
8057 set_valuetype(V_ERROR);
8058 }
8059
8060 void Value::add_id(Identifier *p_id)
8061 {
8062 switch(valuetype) {
8063 case V_NAMEDBITS:
8064 if(u.ids->has_key(p_id->get_name())) {
8065 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8066 // The Value does not take ownership for the identifier,
8067 // so it must be deleted (add_is acts as a sink).
8068 delete p_id;
8069 }
8070 else u.ids->add(p_id->get_name(), p_id);
8071 break;
8072 default:
8073 FATAL_ERROR("Value::add_id()");
8074 } // switch
8075 }
8076
8077 Value* Value::get_value_refd_last(ReferenceChain *refch,
8078 Type::expected_value_t exp_val)
8079 {
8080 set_lowerid_to_ref();
8081 switch (valuetype) {
8082 case V_INVOKE:
8083 // there might be a better place for this
8084 chk_invoke(exp_val);
8085 return this;
8086 case V_REFD:
8087 // use the cache if available
8088 if (u.ref.refd_last) return u.ref.refd_last;
8089 else {
8090 Assignment *ass = u.ref.ref->get_refd_assignment();
8091 if (!ass) {
8092 // the referred definition is not found
8093 set_valuetype(V_ERROR);
8094 } else {
8095 switch (ass->get_asstype()) {
8096 case Assignment::A_OBJECT:
8097 case Assignment::A_OS: {
8098 // the referred definition is an ASN.1 object or object set
8099 Setting *setting = u.ref.ref->get_refd_setting();
8100 if (!setting || setting->get_st() == S_ERROR) {
8101 // remain silent, the error has been already reported
8102 set_valuetype(V_ERROR);
8103 break;
8104 } else if (setting->get_st() != S_V) {
8105 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8106 " refer to a value", u.ref.ref->get_dispname().c_str());
8107 set_valuetype(V_ERROR);
8108 break;
8109 }
8110 bool destroy_refch;
8111 if (refch) {
8112 refch->mark_state();
8113 destroy_refch = false;
8114 } else {
8115 refch = new ReferenceChain(this,
8116 "While searching referenced value");
8117 destroy_refch = true;
8118 }
8119 if (refch->add(get_fullname())) {
8120 Value *v_refd = dynamic_cast<Value*>(setting);
8121 Value *v_last = v_refd->get_value_refd_last(refch);
8122 // in case of circular recursion the valuetype is already set
8123 // to V_ERROR, so don't set the cache
8124 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8125 } else {
8126 // a circular recursion was detected
8127 set_valuetype(V_ERROR);
8128 }
8129 if (destroy_refch) delete refch;
8130 else refch->prev_state();
8131 break; }
8132 case Assignment::A_CONST: {
8133 // the referred definition is a constant
8134 bool destroy_refch;
8135 if (refch) {
8136 refch->mark_state();
8137 destroy_refch = false;
8138 } else {
8139 refch = new ReferenceChain(this,
8140 "While searching referenced value");
8141 destroy_refch = true;
8142 }
8143 if (refch->add(get_fullname())) {
8144 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8145 Value *v_refd = ass->get_Value()
8146 ->get_refd_sub_value(subrefs, 0,
8147 u.ref.ref->getUsedInIsbound(), refch);
8148 if (v_refd) {
8149 Value *v_last = v_refd->get_value_refd_last(refch);
8150 // in case of circular recursion the valuetype is already set
8151 // to V_ERROR, so don't set the cache
8152 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8153 } else if (subrefs && subrefs->has_unfoldable_index()) {
8154 u.ref.refd_last = this;
8155 } else if (u.ref.ref->getUsedInIsbound()) {
8156 u.ref.refd_last = this;
8157 } else {
8158 // the sub-reference points to a non-existent field
8159 set_valuetype(V_ERROR);
8160 }
8161 } else {
8162 // a circular recursion was detected
8163 set_valuetype(V_ERROR);
8164 }
8165 if (destroy_refch) delete refch;
8166 else refch->prev_state();
8167 break; }
8168 case Assignment::A_EXT_CONST:
8169 case Assignment::A_MODULEPAR:
8170 case Assignment::A_VAR:
8171 case Assignment::A_FUNCTION_RVAL:
8172 case Assignment::A_EXT_FUNCTION_RVAL:
8173 case Assignment::A_PAR_VAL_IN:
8174 case Assignment::A_PAR_VAL_OUT:
8175 case Assignment::A_PAR_VAL_INOUT:
8176 // the referred definition is not a constant
8177 u.ref.refd_last = this;
8178 break;
8179 case Assignment::A_FUNCTION:
8180 case Assignment::A_EXT_FUNCTION:
8181 u.ref.ref->error("Reference to a value was expected instead of a "
8182 "call of %s, which does not have return type",
8183 ass->get_description().c_str());
8184 set_valuetype(V_ERROR);
8185 break;
8186 case Assignment::A_FUNCTION_RTEMP:
8187 case Assignment::A_EXT_FUNCTION_RTEMP:
8188 u.ref.ref->error("Reference to a value was expected instead of a "
8189 "call of %s, which returns a template",
8190 ass->get_description().c_str());
8191 set_valuetype(V_ERROR);
8192 break;
8193 default:
8194 u.ref.ref->error("Reference to a value was expected instead of %s",
8195 ass->get_description().c_str());
8196 set_valuetype(V_ERROR);
8197 } // switch asstype
8198 }
8199 if (valuetype == V_REFD) return u.ref.refd_last;
8200 else return this;
8201 }
8202 case V_EXPR: {
8203 // try to evaluate the expression
8204 bool destroy_refch;
8205 if(refch) {
8206 refch->mark_state();
8207 destroy_refch=false;
8208 }
8209 else {
8210 refch=new ReferenceChain(this, "While evaluating expression");
8211 destroy_refch=true;
8212 }
8213 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8214 else set_valuetype(V_ERROR);
8215 if(destroy_refch) delete refch;
8216 else refch->prev_state();
8217 return this; }
8218 case V_MACRO:
8219 evaluate_macro(exp_val);
8220 // no break
8221 default:
8222 // return this for all other value types
8223 return this;
8224 } // switch
8225 }
8226
8227 map<Value*, void> Value::UnfoldabilityCheck::running;
8228
8229 /* Note that the logic here needs to be in sync with evaluate_value,
8230 * and possibly others, i.e. if evaluate_value is called for a Value
8231 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8232 bool Value::is_unfoldable(ReferenceChain *refch,
8233 Type::expected_value_t exp_val)
8234 {
8235 if (UnfoldabilityCheck::is_running(this)) {
8236 // This function is already running on this value => infinite recursion
8237 return true;
8238 }
8239
8240 UnfoldabilityCheck checker(this);
8241
8242 if (get_needs_conversion()) return true;
8243 switch (valuetype) {
8244 case V_NAMEDINT:
8245 case V_NAMEDBITS:
8246 case V_OPENTYPE:
8247 case V_UNDEF_LOWERID:
8248 case V_UNDEF_BLOCK:
8249 case V_TTCN3_NULL:
8250 case V_REFER:
8251 // these value types are eliminated during semantic analysis
8252 FATAL_ERROR("Value::is_unfoldable()");
8253 case V_ERROR:
8254 case V_INVOKE:
8255 return true;
8256 case V_CHOICE:
8257 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8258 case V_SEQOF:
8259 case V_SETOF:
8260 case V_ARRAY:
8261 if (!is_indexed()) {
8262 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8263 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8264 return true;
8265 }
8266 } else {
8267 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8268 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8269 return true;
8270 }
8271 }
8272 return false;
8273 case V_SEQ:
8274 case V_SET:
8275 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8276 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8277 ->is_unfoldable(refch, exp_val)) return true;
8278 }
8279 return false;
8280 case V_OID:
8281 case V_ROID:
8282 chk();
8283 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8284 if ((*u.oid_comps)[i]->is_variable()) return true;
8285 }
8286 return false;
8287 case V_REFD: {
8288 Value *v_last=get_value_refd_last(refch, exp_val);
8289 if(v_last==this) return true; // there weren't any references to chase
8290 else return v_last->is_unfoldable(refch, exp_val);
8291 }
8292 case V_EXPR:
8293 // classify the unchecked ischosen() operation, if it was not done so far
8294 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8295 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8296 switch (u.expr.v_optype) {
8297 case OPTYPE_RND: // -
8298 case OPTYPE_COMP_MTC:
8299 case OPTYPE_COMP_SYSTEM:
8300 case OPTYPE_COMP_SELF:
8301 case OPTYPE_COMP_RUNNING_ANY:
8302 case OPTYPE_COMP_RUNNING_ALL:
8303 case OPTYPE_COMP_ALIVE_ANY:
8304 case OPTYPE_COMP_ALIVE_ALL:
8305 case OPTYPE_TMR_RUNNING_ANY:
8306 case OPTYPE_GETVERDICT:
8307 case OPTYPE_TESTCASENAME:
8308 case OPTYPE_PROF_RUNNING:
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 case OPTYPE_PROF_RUNNING: // -
9813 break; // nothing to do
9814
9815 case OPTYPE_MATCH: // v1 t2
9816 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
9817 // no break
9818 case OPTYPE_UNARYPLUS: // v1
9819 case OPTYPE_UNARYMINUS: // v1
9820 case OPTYPE_NOT: // v1
9821 case OPTYPE_NOT4B: // v1
9822 case OPTYPE_BIT2HEX: // v1
9823 case OPTYPE_BIT2INT: // v1
9824 case OPTYPE_BIT2OCT: // v1
9825 case OPTYPE_BIT2STR: // v1
9826 case OPTYPE_CHAR2INT: // v1
9827 case OPTYPE_CHAR2OCT: // v1
9828 case OPTYPE_FLOAT2INT: // v1
9829 case OPTYPE_FLOAT2STR: // v1
9830 case OPTYPE_HEX2BIT: // v1
9831 case OPTYPE_HEX2INT: // v1
9832 case OPTYPE_HEX2OCT: // v1
9833 case OPTYPE_HEX2STR: // v1
9834 case OPTYPE_INT2CHAR: // v1
9835 case OPTYPE_INT2FLOAT: // v1
9836 case OPTYPE_INT2STR: // v1
9837 case OPTYPE_INT2UNICHAR: // v1
9838 case OPTYPE_OCT2BIT: // v1
9839 case OPTYPE_OCT2CHAR: // v1
9840 case OPTYPE_OCT2HEX: // v1
9841 case OPTYPE_OCT2INT: // v1
9842 case OPTYPE_OCT2STR: // v1
9843 case OPTYPE_STR2BIT: // v1
9844 case OPTYPE_STR2FLOAT: // v1
9845 case OPTYPE_STR2HEX: // v1
9846 case OPTYPE_STR2INT: // v1
9847 case OPTYPE_STR2OCT: // v1
9848 case OPTYPE_UNICHAR2INT: // v1
9849 case OPTYPE_UNICHAR2CHAR: // v1
9850 case OPTYPE_ENUM2INT: // v1
9851 case OPTYPE_RNDWITHVAL: // v1
9852 case OPTYPE_COMP_RUNNING: // v1
9853 case OPTYPE_COMP_ALIVE: // v1
9854 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
9855 case OPTYPE_GET_STRINGENCODING:
9856 case OPTYPE_DECODE_BASE64:
9857 case OPTYPE_REMOVE_BOM:
9858 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9859 break;
9860 case OPTYPE_ADD: // v1 v2
9861 case OPTYPE_SUBTRACT: // v1 v2
9862 case OPTYPE_MULTIPLY: // v1 v2
9863 case OPTYPE_DIVIDE: // v1 v2
9864 case OPTYPE_MOD: // v1 v2
9865 case OPTYPE_REM: // v1 v2
9866 case OPTYPE_CONCAT: // v1 v2
9867 case OPTYPE_EQ: // v1 v2
9868 case OPTYPE_LT: // v1 v2
9869 case OPTYPE_GT: // v1 v2
9870 case OPTYPE_NE: // v1 v2
9871 case OPTYPE_GE: // v1 v2
9872 case OPTYPE_LE: // v1 v2
9873 case OPTYPE_AND: // v1 v2
9874 case OPTYPE_OR: // v1 v2
9875 case OPTYPE_XOR: // v1 v2
9876 case OPTYPE_AND4B: // v1 v2
9877 case OPTYPE_OR4B: // v1 v2
9878 case OPTYPE_XOR4B: // v1 v2
9879 case OPTYPE_SHL: // v1 v2
9880 case OPTYPE_SHR: // v1 v2
9881 case OPTYPE_ROTL: // v1 v2
9882 case OPTYPE_ROTR: // v1 v2
9883 case OPTYPE_INT2BIT: // v1 v2
9884 case OPTYPE_INT2HEX: // v1 v2
9885 case OPTYPE_INT2OCT: // v1 v2
9886 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9887 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9888 break;
9889 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9890 case OPTYPE_OCT2UNICHAR:
9891 case OPTYPE_ENCODE_BASE64:
9892 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9893 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9894 break;
9895 case OPTYPE_DECOMP: // v1 v2 v3
9896 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9897 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9898 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9899 break;
9900
9901 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
9902 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
9903 // no break
9904 case OPTYPE_SUBSTR: // ti1 v2 v3
9905 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9906 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
9907 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
9908 break;
9909
9910 case OPTYPE_REGEXP: // ti1 t2 v3
9911 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9912 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
9913 // no break
9914 case OPTYPE_LENGTHOF: // ti1
9915 case OPTYPE_SIZEOF: // ti1
9916 case OPTYPE_VALUEOF: // ti1
9917 case OPTYPE_ENCODE: // ti1
9918 case OPTYPE_TTCN2STRING:
9919 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9920 break;
9921
9922 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
9923 // component.create -- assume no self-ref
9924 case OPTYPE_ACTIVATE: // r1
9925 // defaultref := activate(altstep) -- assume no self-ref
9926 case OPTYPE_TMR_RUNNING: // r1
9927 // boolvar := a_timer.running -- assume no self-ref
9928 break;
9929 break;
9930
9931 case OPTYPE_LOG2STR: {// logargs
9932 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
9933 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
9934 switch (la->get_type()) {
9935 case Ttcn::LogArgument::L_UNDEF:
9936 case Ttcn::LogArgument::L_ERROR:
9937 FATAL_ERROR("log2str argument type");
9938 break; // not reached
9939
9940 case Ttcn::LogArgument::L_MACRO:
9941 case Ttcn::LogArgument::L_STR:
9942 break; // self reference not possible
9943
9944 case Ttcn::LogArgument::L_VAL:
9945 case Ttcn::LogArgument::L_MATCH:
9946 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
9947 break;
9948
9949 case Ttcn::LogArgument::L_REF: {
9950 Ttcn::Ref_base *ref = la->get_ref();
9951 Common::Assignment *ass = ref->get_refd_assignment();
9952 self_ref |= (ass == lhs);
9953 break; }
9954
9955 case Ttcn::LogArgument::L_TI: {
9956 Ttcn::TemplateInstance *ti = la->get_ti();
9957 Ttcn::Template *t = ti->get_Template();
9958 self_ref |= chk_expr_self_ref_templ(t, lhs);
9959 break; }
9960
9961 // no default please
9962 } // switch la->logargtype
9963 }
9964 break; }
9965
9966 case OPTYPE_DECODE: { // r1 r2
9967 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
9968 self_ref |= (ass == lhs);
9969 goto label_r1; }
9970 case OPTYPE_EXECUTE: // r1 [v2]
9971 if (u.expr.v2) {
9972 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9973 }
9974 label_r1:
9975 // no break
9976 case OPTYPE_UNDEF_RUNNING: // r1
9977 case OPTYPE_TMR_READ: { // r1
9978 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
9979 self_ref |= (ass == lhs);
9980 break; }
9981
9982 case OPTYPE_ISCHOSEN_T: // t1 i2
9983 case OPTYPE_ISBOUND: // ti1
9984 case OPTYPE_ISVALUE: // ti1
9985 case OPTYPE_ISPRESENT: { // ti1
9986 Ttcn::Template *t;
9987 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
9988 else t = u.expr.ti1->get_Template();
9989 self_ref |= chk_expr_self_ref_templ(t, lhs);
9990 break; }
9991
9992 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
9993 if (u.expr.v3) {
9994 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9995 }
9996 // no break
9997 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
9998 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9999 // TODO t_list2
10000 break;
10001
10002 case NUMBER_OF_OPTYPES: // can never happen
10003 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10004 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10005 break;
10006 } // switch u.expr.v_optype
10007 return self_ref;
10008 }
10009
10010
10011 string Value::create_stringRepr()
10012 {
10013 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10014 switch (valuetype) {
10015 case V_ERROR:
10016 return string("<erroneous>");
10017 case V_NULL:
10018 return string("NULL");
10019 case V_BOOL:
10020 if (!parse_only && is_asn1()) {
10021 if (u.val_bool) return string("TRUE");
10022 else return string("FALSE");
10023 }
10024 else {
10025 if (u.val_bool) return string("true");
10026 else return string("false");
10027 }
10028 case V_INT:
10029 return u.val_Int->t_str();
10030 case V_REAL:
10031 return Real2string(u.val_Real);
10032 case V_ENUM:
10033 case V_NAMEDINT:
10034 case V_UNDEF_LOWERID:
10035 return u.val_id->get_name();
10036 case V_NAMEDBITS: {
10037 string ret_val("{ ");
10038 for (size_t i = 0; i < u.ids->size(); i++) {
10039 if (i>0) ret_val += ' ';
10040 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10041 }
10042 ret_val += '}';
10043 return ret_val; }
10044 case V_BSTR: {
10045 string ret_val('\'');
10046 ret_val += *u.str.val_str;
10047 ret_val += "'B";
10048 return ret_val; }
10049 case V_HSTR: {
10050 string ret_val('\'');
10051 ret_val += *u.str.val_str;
10052 ret_val += "'H";
10053 return ret_val; }
10054 case V_OSTR: {
10055 string ret_val('\'');
10056 ret_val += *u.str.val_str;
10057 ret_val += "'O";
10058 return ret_val; }
10059 case V_CSTR:
10060 case V_ISO2022STR:
10061 return u.str.val_str->get_stringRepr();
10062 case V_USTR:
10063 return u.ustr.val_ustr->get_stringRepr();
10064 case V_CHARSYMS:
10065 /** \todo stringrepr of V_CHARSYMS */
10066 return string("<sorry, string representation of charsyms "
10067 "not implemented>");
10068 case V_OID:
10069 case V_ROID: {
10070 string ret_val;
10071 if (parse_only || !is_asn1()) ret_val += "objid ";
10072 ret_val += "{ ";
10073 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10074 if (i>0) ret_val += ' ';
10075 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10076 }
10077 ret_val += " }";
10078 return ret_val; }
10079 case V_CHOICE:
10080 if (!parse_only && is_asn1()) {
10081 string ret_val(u.choice.alt_name->get_dispname());
10082 ret_val += " : ";
10083 ret_val += u.choice.alt_value->get_stringRepr();
10084 return ret_val;
10085 }
10086 else {
10087 string ret_val("{ ");
10088 ret_val += u.choice.alt_name->get_dispname();
10089 ret_val += " := ";
10090 ret_val += u.choice.alt_value->get_stringRepr();
10091 ret_val += " }";
10092 return ret_val;
10093 }
10094 case V_SEQOF:
10095 case V_SETOF:
10096 case V_ARRAY: {
10097 string ret_val("{ ");
10098 if (!is_indexed()) {
10099 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10100 if (i > 0) ret_val += ", ";
10101 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10102 }
10103 } else {
10104 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10105 if (i > 0) ret_val += ", ";
10106 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10107 }
10108 }
10109 ret_val += " }";
10110 return ret_val; }
10111 case V_SEQ:
10112 case V_SET: {
10113 string ret_val("{ ");
10114 bool asn1_flag = !parse_only && is_asn1();
10115 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10116 if (i > 0) ret_val += ", ";
10117 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10118 ret_val += nv->get_name().get_dispname();
10119 if (asn1_flag) ret_val += ' ';
10120 else ret_val += " := ";
10121 ret_val += nv->get_value()->get_stringRepr();
10122 }
10123 ret_val += " }";
10124 return ret_val; }
10125 case V_REFD: {
10126 // do not evaluate the reference if it is not done so far
10127 // (e.g. in parse-only mode)
10128 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10129 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10130 else return t_val->get_stringRepr(); }
10131 case V_OMIT:
10132 return string("omit");
10133 case V_VERDICT:
10134 switch (u.verdict) {
10135 case Verdict_NONE:
10136 return string("none");
10137 case Verdict_PASS:
10138 return string("pass");
10139 case Verdict_INCONC:
10140 return string("inconc");
10141 case Verdict_FAIL:
10142 return string("fail");
10143 case Verdict_ERROR:
10144 return string("error");
10145 default:
10146 return string("<unknown verdict value>");
10147 }
10148 case V_DEFAULT_NULL:
10149 case V_FAT_NULL:
10150 return string("null");
10151 case V_EXPR:
10152 switch (u.expr.v_optype) {
10153 case OPTYPE_RND:
10154 return string("rnd()");
10155 case OPTYPE_TESTCASENAME:
10156 return string("testcasename()");
10157 case OPTYPE_UNARYPLUS:
10158 return create_stringRepr_unary("+");
10159 case OPTYPE_UNARYMINUS:
10160 return create_stringRepr_unary("-");
10161 case OPTYPE_NOT:
10162 return create_stringRepr_unary("not");
10163 case OPTYPE_NOT4B:
10164 return create_stringRepr_unary("not4b");
10165 case OPTYPE_BIT2HEX:
10166 return create_stringRepr_predef1("bit2hex");
10167 case OPTYPE_BIT2INT:
10168 return create_stringRepr_predef1("bit2int");
10169 case OPTYPE_BIT2OCT:
10170 return create_stringRepr_predef1("bit2oct");
10171 case OPTYPE_BIT2STR:
10172 return create_stringRepr_predef1("bit2str");
10173 case OPTYPE_CHAR2INT:
10174 return create_stringRepr_predef1("char2int");
10175 case OPTYPE_CHAR2OCT:
10176 return create_stringRepr_predef1("char2oct");
10177 case OPTYPE_FLOAT2INT:
10178 return create_stringRepr_predef1("float2int");
10179 case OPTYPE_FLOAT2STR:
10180 return create_stringRepr_predef1("float2str");
10181 case OPTYPE_HEX2BIT:
10182 return create_stringRepr_predef1("hex2bit");
10183 case OPTYPE_HEX2INT:
10184 return create_stringRepr_predef1("hex2int");
10185 case OPTYPE_HEX2OCT:
10186 return create_stringRepr_predef1("hex2oct");
10187 case OPTYPE_HEX2STR:
10188 return create_stringRepr_predef1("hex2str");
10189 case OPTYPE_INT2CHAR:
10190 return create_stringRepr_predef1("int2char");
10191 case OPTYPE_INT2FLOAT:
10192 return create_stringRepr_predef1("int2float");
10193 case OPTYPE_INT2STR:
10194 return create_stringRepr_predef1("int2str");
10195 case OPTYPE_INT2UNICHAR:
10196 return create_stringRepr_predef1("int2unichar");
10197 case OPTYPE_OCT2BIT:
10198 return create_stringRepr_predef1("oct2bit");
10199 case OPTYPE_OCT2CHAR:
10200 return create_stringRepr_predef1("oct2char");
10201 case OPTYPE_OCT2HEX:
10202 return create_stringRepr_predef1("oct2hex");
10203 case OPTYPE_OCT2INT:
10204 return create_stringRepr_predef1("oct2int");
10205 case OPTYPE_OCT2STR:
10206 return create_stringRepr_predef1("oct2str");
10207 case OPTYPE_GET_STRINGENCODING:
10208 return create_stringRepr_predef1("get_stringencoding");
10209 case OPTYPE_REMOVE_BOM:
10210 return create_stringRepr_predef1("remove_bom");
10211 case OPTYPE_ENCODE_BASE64: {
10212 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10213 else return create_stringRepr_predef1("encode_base64");
10214 }
10215 case OPTYPE_DECODE_BASE64:
10216 return create_stringRepr_predef1("decode_base64");
10217 case OPTYPE_OCT2UNICHAR:{
10218 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10219 else return create_stringRepr_predef1("oct2unichar");
10220 }
10221 case OPTYPE_UNICHAR2OCT: {
10222 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10223 else return create_stringRepr_predef1("unichar2oct");
10224 }
10225 case OPTYPE_STR2BIT:
10226 return create_stringRepr_predef1("str2bit");
10227 case OPTYPE_STR2FLOAT:
10228 return create_stringRepr_predef1("str2float");
10229 case OPTYPE_STR2HEX:
10230 return create_stringRepr_predef1("str2hex");
10231 case OPTYPE_STR2INT:
10232 return create_stringRepr_predef1("str2int");
10233 case OPTYPE_STR2OCT:
10234 return create_stringRepr_predef1("str2oct");
10235 case OPTYPE_UNICHAR2INT:
10236 return create_stringRepr_predef1("unichar2int");
10237 case OPTYPE_UNICHAR2CHAR:
10238 return create_stringRepr_predef1("unichar2char");
10239 case OPTYPE_ENUM2INT:
10240 return create_stringRepr_predef1("enum2int");
10241 case OPTYPE_ENCODE:
10242 return create_stringRepr_predef1("encvalue");
10243 case OPTYPE_DECODE:
10244 return create_stringRepr_predef2("decvalue");
10245 case OPTYPE_RNDWITHVAL:
10246 return create_stringRepr_predef1("rnd");
10247 case OPTYPE_ADD:
10248 return create_stringRepr_infix("+");
10249 case OPTYPE_SUBTRACT:
10250 return create_stringRepr_infix("-");
10251 case OPTYPE_MULTIPLY:
10252 return create_stringRepr_infix("*");
10253 case OPTYPE_DIVIDE:
10254 return create_stringRepr_infix("/");
10255 case OPTYPE_MOD:
10256 return create_stringRepr_infix("mod");
10257 case OPTYPE_REM:
10258 return create_stringRepr_infix("rem");
10259 case OPTYPE_CONCAT:
10260 return create_stringRepr_infix("&");
10261 case OPTYPE_EQ:
10262 return create_stringRepr_infix("==");
10263 case OPTYPE_LT:
10264 return create_stringRepr_infix("<");
10265 case OPTYPE_GT:
10266 return create_stringRepr_infix(">");
10267 case OPTYPE_NE:
10268 return create_stringRepr_infix("!=");
10269 case OPTYPE_GE:
10270 return create_stringRepr_infix(">=");
10271 case OPTYPE_LE:
10272 return create_stringRepr_infix("<=");
10273 case OPTYPE_AND:
10274 return create_stringRepr_infix("and");
10275 case OPTYPE_OR:
10276 return create_stringRepr_infix("or");
10277 case OPTYPE_XOR:
10278 return create_stringRepr_infix("xor");
10279 case OPTYPE_AND4B:
10280 return create_stringRepr_infix("and4b");
10281 case OPTYPE_OR4B:
10282 return create_stringRepr_infix("or4b");
10283 case OPTYPE_XOR4B:
10284 return create_stringRepr_infix("xor4b");
10285 case OPTYPE_SHL:
10286 return create_stringRepr_infix("<<");
10287 case OPTYPE_SHR:
10288 return create_stringRepr_infix(">>");
10289 case OPTYPE_ROTL:
10290 return create_stringRepr_infix("<@");
10291 case OPTYPE_ROTR:
10292 return create_stringRepr_infix("@>");
10293 case OPTYPE_INT2BIT:
10294 return create_stringRepr_predef2("int2bit");
10295 case OPTYPE_INT2HEX:
10296 return create_stringRepr_predef2("int2hex");
10297 case OPTYPE_INT2OCT:
10298 return create_stringRepr_predef2("int2oct");
10299 case OPTYPE_SUBSTR: {
10300 string ret_val("substr(");
10301 u.expr.ti1->append_stringRepr(ret_val);
10302 ret_val += ", ";
10303 ret_val += u.expr.v2->get_stringRepr();
10304 ret_val += ", ";
10305 ret_val += u.expr.v3->get_stringRepr();
10306 ret_val += ')';
10307 return ret_val;
10308 }
10309 case OPTYPE_REGEXP: {
10310 string ret_val("regexp(");
10311 u.expr.ti1->append_stringRepr(ret_val);
10312 ret_val += ", ";
10313 u.expr.t2->append_stringRepr(ret_val);
10314 ret_val += ", ";
10315 ret_val += u.expr.v3->get_stringRepr();
10316 ret_val += ')';
10317 return ret_val;
10318 }
10319 case OPTYPE_DECOMP: {
10320 string ret_val("decomp(");
10321 ret_val += u.expr.v1->get_stringRepr();
10322 ret_val += ", ";
10323 ret_val += u.expr.v2->get_stringRepr();
10324 ret_val += ", ";
10325 ret_val += u.expr.v3->get_stringRepr();
10326 ret_val += ')';
10327 return ret_val;
10328 }
10329 case OPTYPE_REPLACE: {
10330 string ret_val("replace(");
10331 u.expr.ti1->append_stringRepr(ret_val);
10332 ret_val += ", ";
10333 ret_val += u.expr.v2->get_stringRepr();
10334 ret_val += ", ";
10335 ret_val += u.expr.v3->get_stringRepr();
10336 ret_val += ", ";
10337 u.expr.ti4->append_stringRepr(ret_val);
10338 ret_val += ')';
10339 return ret_val;
10340 }
10341 case OPTYPE_ISPRESENT: {
10342 string ret_val("ispresent(");
10343 u.expr.ti1->append_stringRepr(ret_val);
10344 ret_val += ')';
10345 return ret_val; }
10346 case OPTYPE_ISCHOSEN: {
10347 string ret_val("ischosen(");
10348 ret_val += u.expr.r1->get_dispname();
10349 ret_val += '.';
10350 ret_val += u.expr.i2->get_dispname();
10351 ret_val += ')';
10352 return ret_val; }
10353 case OPTYPE_ISCHOSEN_V: {
10354 string ret_val("ischosen(");
10355 ret_val += u.expr.v1->get_stringRepr();
10356 ret_val += '.';
10357 ret_val += u.expr.i2->get_dispname();
10358 ret_val += ')';
10359 return ret_val; }
10360 case OPTYPE_ISCHOSEN_T: {
10361 string ret_val("ischosen(");
10362 ret_val += u.expr.t1->get_stringRepr();
10363 ret_val += '.';
10364 ret_val += u.expr.i2->get_dispname();
10365 ret_val += ')';
10366 return ret_val; }
10367 case OPTYPE_LENGTHOF: {
10368 string ret_val("lengthof(");
10369 u.expr.ti1->append_stringRepr(ret_val);
10370 ret_val += ')';
10371 return ret_val; }
10372 case OPTYPE_SIZEOF: {
10373 string ret_val("sizeof(");
10374 u.expr.ti1->append_stringRepr(ret_val);
10375 ret_val += ')';
10376 return ret_val; }
10377 case OPTYPE_ISVALUE: {
10378 string ret_val("isvalue(");
10379 u.expr.ti1->append_stringRepr(ret_val);
10380 ret_val += ')';
10381 return ret_val; }
10382 case OPTYPE_VALUEOF: {
10383 string ret_val("valueof(");
10384 u.expr.ti1->append_stringRepr(ret_val);
10385 ret_val += ')';
10386 return ret_val; }
10387 case OPTYPE_LOG2STR:
10388 return string("log2str(...)");
10389 case OPTYPE_MATCH: {
10390 string ret_val("match(");
10391 ret_val += u.expr.v1->get_stringRepr();
10392 ret_val += ", ";
10393 u.expr.t2->append_stringRepr(ret_val);
10394 ret_val += ')';
10395 return ret_val; }
10396 case OPTYPE_TTCN2STRING: {
10397 string ret_val("ttcn2string(");
10398 u.expr.ti1->append_stringRepr(ret_val);
10399 ret_val += ')';
10400 return ret_val;
10401 }
10402 case OPTYPE_UNDEF_RUNNING:
10403 return u.expr.r1->get_dispname() + ".running";
10404 case OPTYPE_COMP_NULL:
10405 return string("null");
10406 case OPTYPE_COMP_MTC:
10407 return string("mtc");
10408 case OPTYPE_COMP_SYSTEM:
10409 return string("system");
10410 case OPTYPE_COMP_SELF:
10411 return string("self");
10412 case OPTYPE_COMP_CREATE: {
10413 string ret_val(u.expr.r1->get_dispname());
10414 ret_val += ".create";
10415 if (u.expr.v2 || u.expr.v3) {
10416 ret_val += '(';
10417 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10418 else ret_val += '-';
10419 if (u.expr.v3) {
10420 ret_val += ", ";
10421 ret_val += u.expr.v3->get_stringRepr();
10422 }
10423 ret_val += ')';
10424 }
10425 if (u.expr.b4) ret_val += " alive";
10426 return ret_val; }
10427 case OPTYPE_COMP_RUNNING:
10428 return u.expr.v1->get_stringRepr() + ".running";
10429 case OPTYPE_COMP_RUNNING_ANY:
10430 return string("any component.running");
10431 case OPTYPE_COMP_RUNNING_ALL:
10432 return string("all component.running");
10433 case OPTYPE_COMP_ALIVE:
10434 return u.expr.v1->get_stringRepr() + ".alive";
10435 case OPTYPE_COMP_ALIVE_ANY:
10436 return string("any component.alive");
10437 case OPTYPE_COMP_ALIVE_ALL:
10438 return string("all component.alive");
10439 case OPTYPE_TMR_READ:
10440 return u.expr.r1->get_dispname() + ".read";
10441 case OPTYPE_TMR_RUNNING:
10442 return u.expr.r1->get_dispname() + ".running";
10443 case OPTYPE_TMR_RUNNING_ANY:
10444 return string("any timer.running");
10445 case OPTYPE_GETVERDICT:
10446 return string("getverdict");
10447 case OPTYPE_ACTIVATE: {
10448 string ret_val("activate(");
10449 ret_val += u.expr.r1->get_dispname();
10450 ret_val += ')';
10451 return ret_val; }
10452 case OPTYPE_ACTIVATE_REFD: {
10453 string ret_val("activate(derefer(");
10454 ret_val += u.expr.v1->get_stringRepr();
10455 ret_val += ")(";
10456 if (u.expr.state == EXPR_CHECKED) {
10457 if (u.expr.ap_list2) {
10458 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10459 for (size_t i = 0; i < nof_pars; i++) {
10460 if (i > 0) ret_val += ", ";
10461 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10462 }
10463 }
10464 } else {
10465 if (u.expr.t_list2) {
10466 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10467 for (size_t i = 0; i < nof_pars; i++) {
10468 if (i > 0) ret_val += ", ";
10469 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10470 }
10471 }
10472 }
10473 ret_val += "))";
10474 return ret_val; }
10475 case OPTYPE_EXECUTE: {
10476 string ret_val("execute(");
10477 ret_val += u.expr.r1->get_dispname();
10478 if (u.expr.v2) {
10479 ret_val += ", ";
10480 ret_val += u.expr.v2->get_stringRepr();
10481 }
10482 ret_val += ')';
10483 return ret_val; }
10484 case OPTYPE_EXECUTE_REFD: {
10485 string ret_val("execute(derefers(");
10486 ret_val += u.expr.v1->get_stringRepr();
10487 ret_val += ")(";
10488 if (u.expr.state == EXPR_CHECKED) {
10489 if (u.expr.ap_list2) {
10490 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10491 for (size_t i = 0; i < nof_pars; i++) {
10492 if (i > 0) ret_val += ", ";
10493 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10494 }
10495 }
10496 } else {
10497 if (u.expr.t_list2) {
10498 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10499 for (size_t i = 0; i < nof_pars; i++) {
10500 if (i > 0) ret_val += ", ";
10501 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10502 }
10503 }
10504 }
10505 ret_val += ')';
10506 if(u.expr.v3) {
10507 ret_val += ", ";
10508 ret_val += u.expr.v3->get_stringRepr();
10509 }
10510 ret_val += ')';
10511 return ret_val; }
10512 case OPTYPE_PROF_RUNNING:
10513 return string("@profiler.running");
10514 default:
10515 return string("<unsupported optype>");
10516 } // switch u.expr.v_optype
10517 case V_MACRO:
10518 switch (u.macro) {
10519 case MACRO_MODULEID:
10520 return string("%moduleId");
10521 case MACRO_FILENAME:
10522 return string("%fileName");
10523 case MACRO_BFILENAME:
10524 return string("__BFILE__");
10525 case MACRO_FILEPATH:
10526 return string("__FILE__");
10527 case MACRO_LINENUMBER:
10528 return string("%lineNumber");
10529 case MACRO_LINENUMBER_C:
10530 return string("__LINE__");
10531 case MACRO_DEFINITIONID:
10532 return string("%definitionId");
10533 case MACRO_SCOPE:
10534 return string("__SCOPE__");
10535 case MACRO_TESTCASEID:
10536 return string("%testcaseId");
10537 default:
10538 return string("<unknown macro>");
10539 } // switch u.macro
10540 case V_NOTUSED:
10541 return string('-');
10542 case V_FUNCTION:
10543 case V_ALTSTEP:
10544 case V_TESTCASE: {
10545 string ret_val("refers(");
10546 ret_val += u.refd_fat->get_assname();
10547 ret_val += ')';
10548 return ret_val; }
10549 case V_INVOKE: {
10550 string ret_val;
10551 ret_val += u.invoke.v->get_stringRepr();
10552 ret_val += ".apply(";
10553 if (u.invoke.ap_list) {
10554 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10555 for (size_t i = 0; i < nof_pars; i++) {
10556 if (i > 0) ret_val += ", ";
10557 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10558 }
10559 } else if (u.invoke.t_list) {
10560 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10561 for (size_t i = 0; i < nof_pars; i++) {
10562 if (i > 0) ret_val += ", ";
10563 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10564 }
10565 }
10566 ret_val += ')';
10567 return ret_val; }
10568 case V_REFER: {
10569 string ret_val("refers(");
10570 ret_val += u.refered->get_dispname();
10571 ret_val += ')';
10572 return ret_val; }
10573 default:
10574 return string("<unsupported valuetype>");
10575 } // switch valuetype
10576 }
10577
10578 string Value::create_stringRepr_unary(const char *operator_str)
10579 {
10580 string ret_val(operator_str);
10581 ret_val += '(';
10582 ret_val += u.expr.v1->get_stringRepr();
10583 ret_val += ')';
10584 return ret_val;
10585 }
10586
10587 string Value::create_stringRepr_infix(const char *operator_str)
10588 {
10589 string ret_val('(');
10590 ret_val += u.expr.v1->get_stringRepr();
10591 ret_val += ' ';
10592 ret_val += operator_str;
10593 ret_val += ' ';
10594 ret_val += u.expr.v2->get_stringRepr();
10595 ret_val += ')';
10596 return ret_val;
10597 }
10598
10599 string Value::create_stringRepr_predef1(const char *function_name)
10600 {
10601 string ret_val(function_name);
10602 ret_val += '(';
10603 if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
10604 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10605 }
10606 else ret_val += u.expr.v1->get_stringRepr();
10607 ret_val += ')';
10608 return ret_val;
10609 }
10610
10611 string Value::create_stringRepr_predef2(const char *function_name)
10612 {
10613 string ret_val(function_name);
10614 ret_val += '(';
10615 ret_val += u.expr.v1->get_stringRepr();
10616 ret_val += ", ";
10617 ret_val += u.expr.v2->get_stringRepr();
10618 ret_val += ')';
10619 return ret_val;
10620 }
10621
10622 bool Value::operator==(Value& val)
10623 {
10624 Value *left = get_value_refd_last();
10625 Type *left_governor = left->get_my_governor();
10626 if (left_governor) left_governor = left_governor->get_type_refd_last();
10627 Value *right = val.get_value_refd_last();
10628 Type *right_governor = right->get_my_governor();
10629 if (right_governor) right_governor = right_governor->get_type_refd_last();
10630 if (left_governor && right_governor
10631 && !left_governor->is_compatible(right_governor, NULL)
10632 && !right_governor->is_compatible(left_governor, NULL))
10633 FATAL_ERROR("Value::operator==");
10634
10635 // Not-A-Value is not equal to anything (NaN analogy:)
10636 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10637 return false;
10638
10639 switch (left->valuetype) {
10640 case V_NULL:
10641 case V_OMIT:
10642 case V_DEFAULT_NULL:
10643 case V_FAT_NULL:
10644 case V_NOTUSED:
10645 return left->valuetype == right->valuetype;
10646 case V_BOOL:
10647 return right->valuetype == V_BOOL &&
10648 left->get_val_bool() == right->get_val_bool();
10649 case V_INT:
10650 return right->valuetype == V_INT && *left->get_val_Int()
10651 == *right->get_val_Int();
10652 case V_REAL:
10653 return right->valuetype == V_REAL &&
10654 left->get_val_Real() == right->get_val_Real();
10655 case V_CSTR:
10656 switch (right->valuetype) {
10657 case V_CSTR:
10658 return left->get_val_str() == right->get_val_str();
10659 case V_USTR:
10660 return right->get_val_ustr() == left->get_val_str();
10661 case V_ISO2022STR:
10662 return right->get_val_iso2022str() == left->get_val_str();
10663 default:
10664 return false;
10665 }
10666 case V_BSTR:
10667 case V_HSTR:
10668 case V_OSTR:
10669 return left->valuetype == right->valuetype &&
10670 left->get_val_str() == right->get_val_str();
10671 case V_USTR:
10672 switch (right->valuetype) {
10673 case V_CSTR:
10674 return left->get_val_ustr() == right->get_val_str();
10675 case V_USTR:
10676 return left->get_val_ustr() == right->get_val_ustr();
10677 case V_ISO2022STR:
10678 return left->get_val_ustr() == right->get_val_iso2022str();
10679 default:
10680 return false;
10681 }
10682 case V_ISO2022STR:
10683 switch (right->valuetype) {
10684 case V_CSTR:
10685 return left->get_val_iso2022str() == right->get_val_str();
10686 case V_USTR:
10687 // The appropriate operator==() is missing. The operands are swapped,
10688 // but it shouldn't be a problem.
10689 return right->get_val_ustr() == left->get_val_iso2022str();
10690 case V_ISO2022STR:
10691 return left->get_val_iso2022str() == right->get_val_iso2022str();
10692 default:
10693 return false;
10694 }
10695 case V_ENUM:
10696 return right->valuetype == V_ENUM &&
10697 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10698 case V_OID:
10699 case V_ROID:
10700 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10701 vector<string> act, other;
10702 get_oid_comps(act);
10703 val.get_oid_comps(other);
10704 size_t act_size = act.size(), other_size = other.size();
10705 bool ret_val;
10706 if (act_size == other_size) {
10707 ret_val = true;
10708 for (size_t i = 0; i < act_size; i++)
10709 if (*act[i] != *other[i]) {
10710 ret_val = false;
10711 break;
10712 }
10713 } else ret_val = false;
10714 for (size_t i = 0; i < act_size; i++) delete act[i];
10715 act.clear();
10716 for (size_t i = 0; i < other_size; i++) delete other[i];
10717 other.clear();
10718 return ret_val;
10719 } else return false;
10720 case V_CHOICE:
10721 return right->valuetype == V_CHOICE &&
10722 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10723 *(left->get_alt_value()) == *(right->get_alt_value());
10724 case V_SEQ:
10725 case V_SET: {
10726 if (!left_governor) FATAL_ERROR("Value::operator==");
10727 if (left->valuetype != right->valuetype) return false;
10728 size_t nof_comps = left_governor->get_nof_comps();
10729 for (size_t i = 0; i < nof_comps; i++) {
10730 Value *lval = NULL, *rval = NULL;
10731 CompField* cfl = left_governor->get_comp_byIndex(i);
10732 const Identifier& field_name = cfl->get_name();
10733 if (left->has_comp_withName(field_name)) {
10734 lval = left->get_comp_value_byName(field_name);
10735 if (right->has_comp_withName(field_name)) {
10736 rval = right->get_comp_value_byName(field_name);
10737 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10738 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10739 return false;
10740 else if (!(*lval == *rval))
10741 return false;
10742 } else {
10743 if (cfl->has_default()) {
10744 if (!(*lval == *cfl->get_defval()))
10745 return false;
10746 } else {
10747 if (lval->valuetype != V_OMIT)
10748 return false;
10749 }
10750 }
10751 } else {
10752 if(right->has_comp_withName(field_name)) {
10753 rval = right->get_comp_value_byName(field_name);
10754 if(cfl->has_default()) {
10755 if(rval->valuetype==V_OMIT) return false;
10756 else {
10757 lval = cfl->get_defval();
10758 if (!(*lval==*rval)) return false;
10759 }
10760 }
10761 }
10762 }
10763 }
10764 return true; }
10765 case V_SEQOF:
10766 case V_ARRAY: {
10767 if (left->valuetype != right->valuetype) return false;
10768 size_t ncomps = get_nof_comps();
10769 if (ncomps != right->get_nof_comps()) return false;
10770
10771 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
10772 bool found = false;
10773 map<IndexedValue*, void> uncovered;
10774 for (size_t i = 0; i < left->get_nof_comps(); ++i)
10775 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
10776
10777 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
10778 found = false;
10779 for (size_t j = 0; j < uncovered.size(); ++j) {
10780 if (*(uncovered.get_nth_key(j)->get_value()) ==
10781 *(right->get_comp_byIndex(i)) &&
10782 *(uncovered.get_nth_key(j)->get_index()) ==
10783 *(right->get_index_byIndex(i))) {
10784 found = true;
10785 uncovered.erase(uncovered.get_nth_key(j));
10786 break;
10787 }
10788 }
10789 if (!found) break;
10790 }
10791 uncovered.clear();
10792 return found;
10793 } else if (left->is_indexed() || right->is_indexed()) {
10794 Value* indexed_one = 0;
10795 Value* not_indexed_one = 0;
10796
10797 if(left->is_indexed()) { // left is indexed, right is not
10798 indexed_one = left;
10799 not_indexed_one = right;
10800 } else { // right indexed, left is not
10801 indexed_one = right;
10802 not_indexed_one = left;
10803 }
10804
10805 for(size_t i = 0; i < ncomps; ++i) {
10806 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
10807 if(!(ind->valuetype == V_INT &&
10808 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
10809 *(indexed_one->get_comp_byIndex(i))))
10810 { return false; }
10811 }
10812 return true;
10813 } else { // none of them is indexed
10814 for (size_t i = 0; i < ncomps; i++) {
10815 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
10816 return false;
10817 }
10818 return true;
10819 }
10820 }
10821 case V_SETOF: {
10822 if (right->valuetype != V_SETOF) return false;
10823 size_t ncomps = get_nof_comps();
10824 if (ncomps != right->get_nof_comps()) return false;
10825 if (ncomps == 0) return true;
10826 map<size_t, void> uncovered;
10827 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
10828 for (size_t i = 0; i < ncomps; i++) {
10829 Value *left_item = left->get_comp_byIndex(i);
10830 bool pair_found = false;
10831 for (size_t j = 0; j < ncomps - i; j++) {
10832 size_t right_index = uncovered.get_nth_key(j);
10833 if (*left_item == *right->get_comp_byIndex(right_index)) {
10834 uncovered.erase(right_index);
10835 pair_found = true;
10836 break;
10837 }
10838 }
10839 if (!pair_found) {
10840 uncovered.clear();
10841 return false;
10842 }
10843 }
10844 return true; }
10845 case V_VERDICT:
10846 return right->valuetype == V_VERDICT &&
10847 left->get_val_verdict() == right->get_val_verdict();
10848 case V_FUNCTION:
10849 case V_ALTSTEP:
10850 case V_TESTCASE:
10851 return left->valuetype == right->valuetype &&
10852 left->get_refd_assignment() == right->get_refd_assignment();
10853 default:
10854 FATAL_ERROR("Value::operator==");
10855 }
10856 return true;
10857 }
10858
10859 bool Value::operator<(Value& val)
10860 {
10861 Value *left = get_value_refd_last();
10862 Type *left_governor = left->get_my_governor();
10863 if(left_governor) left_governor=left_governor->get_type_refd_last();
10864 Value *right = val.get_value_refd_last();
10865 Type *right_governor = right->get_my_governor();
10866 if(right_governor) right_governor=right_governor->get_type_refd_last();
10867 if (left->get_valuetype() != right->get_valuetype())
10868 FATAL_ERROR("Value::operator<");
10869 switch(valuetype){
10870 case V_INT:
10871 return *left->get_val_Int() < *right->get_val_Int();
10872 case V_REAL:
10873 return (left->get_val_Real() < right->get_val_Real());
10874 case V_ENUM:
10875 if(!left_governor || !right_governor)
10876 FATAL_ERROR("Value::operator<");
10877 if(left_governor!=right_governor)
10878 FATAL_ERROR("Value::operator<");
10879 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
10880 right_governor->get_enum_val_byId(*right->get_val_id()));
10881 default:
10882 FATAL_ERROR("Value::operator<");
10883 }
10884 return true;
10885 }
10886
10887 bool Value::is_string_type(Type::expected_value_t exp_val)
10888 {
10889 switch (get_expr_returntype(exp_val)) {
10890 case Type::T_CSTR:
10891 case Type::T_USTR:
10892 case Type::T_BSTR:
10893 case Type::T_HSTR:
10894 case Type::T_OSTR:
10895 return true;
10896 default:
10897 return false;
10898 }
10899 }
10900
10901 void Value::generate_code_expr(expression_struct *expr)
10902 {
10903 if (has_single_expr()) {
10904 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
10905 } else {
10906 switch (valuetype) {
10907 case V_EXPR:
10908 generate_code_expr_expr(expr);
10909 break;
10910 case V_CHOICE:
10911 case V_SEQOF:
10912 case V_SETOF:
10913 case V_ARRAY:
10914 case V_SEQ:
10915 case V_SET: {
10916 const string& tmp_id = get_temporary_id();
10917 const char *tmp_id_str = tmp_id.c_str();
10918 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
10919 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
10920 set_genname_recursive(tmp_id);
10921 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10922 expr->expr = mputstr(expr->expr, tmp_id_str);
10923 break; }
10924 case V_INT: {
10925 const string& tmp_id = get_temporary_id();
10926 const char *tmp_id_str = tmp_id.c_str();
10927 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
10928 tmp_id_str);
10929 set_genname_recursive(tmp_id);
10930 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10931 expr->expr = mputstr(expr->expr, tmp_id_str);
10932 break; }
10933 case V_REFD: {
10934 if (!get_needs_conversion()) {
10935 u.ref.ref->generate_code_const_ref(expr);
10936 } else {
10937 Type *my_gov = get_expr_governor_last();
10938 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
10939 ->get_field_type(u.ref.ref->get_subrefs(),
10940 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
10941 // Make sure that nothing goes wrong.
10942 if (!my_gov || !refd_gov || my_gov == refd_gov)
10943 FATAL_ERROR("Value::generate_code_expr()");
10944 expression_struct expr_tmp;
10945 Code::init_expr(&expr_tmp);
10946 const string& tmp_id1 = get_temporary_id();
10947 const char *tmp_id_str1 = tmp_id1.c_str();
10948 const string& tmp_id2 = get_temporary_id();
10949 const char *tmp_id_str2 = tmp_id2.c_str();
10950 expr->preamble = mputprintf(expr->preamble,
10951 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
10952 tmp_id_str1);
10953 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
10954 u.ref.ref->generate_code_const_ref(&expr_tmp);
10955 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
10956 expr->preamble = mputprintf(expr->preamble,
10957 "%s %s;\n"
10958 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10959 "and `%s' are not compatible at run-time\");\n",
10960 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
10961 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
10962 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
10963 ->get_typename().c_str(), refd_gov->get_typename().c_str());
10964 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
10965 }
10966 break; }
10967 case V_INVOKE:
10968 generate_code_expr_invoke(expr);
10969 break;
10970 default:
10971 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
10972 }
10973 }
10974 }
10975
10976 void Value::generate_code_expr_mandatory(expression_struct *expr)
10977 {
10978 generate_code_expr(expr);
10979 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
10980 generate_code_expr_optional_field_ref(expr, u.ref.ref);
10981 }
10982
10983 bool Value::can_use_increment(Reference *ref) const
10984 {
10985 if (valuetype != V_EXPR) {
10986 return false;
10987 }
10988 switch (u.expr.v_optype) {
10989 case OPTYPE_ADD:
10990 case OPTYPE_SUBTRACT:
10991 break;
10992 default:
10993 return false;
10994 }
10995 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
10996 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
10997 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
10998 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
10999 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11000 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11001 return true;
11002 }
11003 return false;
11004 }
11005
11006 char *Value::generate_code_init(char *str, const char *name)
11007 {
11008 if (get_code_generated()) return str;
11009 if (err_descr) {
11010 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11011 }
11012 switch (valuetype) {
11013 case V_NULL:
11014 case V_BOOL:
11015 case V_REAL:
11016 case V_ENUM:
11017 case V_BSTR:
11018 case V_HSTR:
11019 case V_OSTR:
11020 case V_CSTR:
11021 case V_USTR:
11022 case V_ISO2022STR:
11023 case V_OID:
11024 case V_ROID:
11025 case V_VERDICT:
11026 case V_DEFAULT_NULL:
11027 case V_FAT_NULL:
11028 case V_FUNCTION:
11029 case V_ALTSTEP:
11030 case V_TESTCASE:
11031 // These values have a single string equivalent.
11032 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11033 break;
11034 case V_INT:
11035 if (u.val_Int->is_native_fit())
11036 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11037 else
11038 // It's always an INTEGER.
11039 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11040 "}\n", get_single_expr().c_str(), name);
11041 break;
11042 case V_EXPR:
11043 case V_INVOKE: {
11044 expression_struct expr;
11045 Code::init_expr(&expr);
11046 expr.expr = mputprintf(expr.expr, "%s = ", name);
11047 generate_code_expr(&expr);
11048 str = Code::merge_free_expr(str, &expr);
11049 break; }
11050 case V_CHOICE:
11051 str = generate_code_init_choice(str, name);
11052 break;
11053 case V_SEQOF:
11054 case V_SETOF:
11055 if (!is_indexed()) str = generate_code_init_seof(str, name);
11056 else str = generate_code_init_indexed(str, name);
11057 break;
11058 case V_ARRAY:
11059 if (!is_indexed()) str = generate_code_init_array(str, name);
11060 else str = generate_code_init_indexed(str, name);
11061 break;
11062 case V_SEQ:
11063 case V_SET:
11064 str = generate_code_init_se(str, name);
11065 break;
11066 case V_REFD:
11067 str = generate_code_init_refd(str, name);
11068 break;
11069 case V_MACRO:
11070 switch (u.macro) {
11071 case MACRO_TESTCASEID:
11072 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11073 break;
11074 default:
11075 // all others must already be evaluated away
11076 FATAL_ERROR("Value::generate_code_init()");
11077 }
11078 break;
11079 default:
11080 FATAL_ERROR("Value::generate_code_init()");
11081 }
11082 if (err_descr) {
11083 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11084 }
11085 set_code_generated();
11086 return str;
11087 }
11088
11089 char *Value::rearrange_init_code(char *str)
11090 {
11091 switch (valuetype) {
11092 case V_REFD: {
11093 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11094 if (parlist) {
11095 str = parlist->rearrange_init_code(str,
11096 u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()
11097 == my_scope->get_scope_mod_gen());
11098 }
11099 break; }
11100 case V_INVOKE: {
11101 str = u.invoke.v->rearrange_init_code(str);
11102 bool type_is_local = u.invoke.v->get_expr_governor_last()->get_my_scope()
11103 ->get_scope_mod_gen() == my_scope->get_scope_mod_gen();
11104 str = u.invoke.ap_list->rearrange_init_code(str, type_is_local);
11105 break; }
11106 case V_EXPR:
11107 switch (u.expr.v_optype) {
11108 case OPTYPE_UNARYPLUS:
11109 case OPTYPE_UNARYMINUS:
11110 case OPTYPE_NOT:
11111 case OPTYPE_NOT4B:
11112 case OPTYPE_BIT2HEX:
11113 case OPTYPE_BIT2INT:
11114 case OPTYPE_BIT2OCT:
11115 case OPTYPE_BIT2STR:
11116 case OPTYPE_CHAR2INT:
11117 case OPTYPE_CHAR2OCT:
11118 case OPTYPE_FLOAT2INT:
11119 case OPTYPE_FLOAT2STR:
11120 case OPTYPE_HEX2BIT:
11121 case OPTYPE_HEX2INT:
11122 case OPTYPE_HEX2OCT:
11123 case OPTYPE_HEX2STR:
11124 case OPTYPE_INT2CHAR:
11125 case OPTYPE_INT2FLOAT:
11126 case OPTYPE_INT2STR:
11127 case OPTYPE_INT2UNICHAR:
11128 case OPTYPE_OCT2BIT:
11129 case OPTYPE_OCT2CHAR:
11130 case OPTYPE_OCT2HEX:
11131 case OPTYPE_OCT2INT:
11132 case OPTYPE_OCT2STR:
11133 case OPTYPE_STR2BIT:
11134 case OPTYPE_STR2FLOAT:
11135 case OPTYPE_STR2HEX:
11136 case OPTYPE_STR2INT:
11137 case OPTYPE_STR2OCT:
11138 case OPTYPE_UNICHAR2INT:
11139 case OPTYPE_UNICHAR2CHAR:
11140 case OPTYPE_ENUM2INT:
11141 case OPTYPE_ISCHOSEN_V:
11142 case OPTYPE_GET_STRINGENCODING:
11143 case OPTYPE_REMOVE_BOM:
11144 case OPTYPE_DECODE_BASE64:
11145 str = u.expr.v1->rearrange_init_code(str);
11146 break;
11147 case OPTYPE_DECODE: {
11148 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11149 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11150 bool rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11151 my_scope->get_scope_mod_gen());
11152 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11153
11154 parlist = u.expr.r2->get_parlist();
11155 ass = u.expr.r2->get_refd_assignment();
11156 rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11157 my_scope->get_scope_mod_gen());
11158 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11159 break; }
11160 case OPTYPE_ADD:
11161 case OPTYPE_SUBTRACT:
11162 case OPTYPE_MULTIPLY:
11163 case OPTYPE_DIVIDE:
11164 case OPTYPE_MOD:
11165 case OPTYPE_REM:
11166 case OPTYPE_CONCAT:
11167 case OPTYPE_EQ:
11168 case OPTYPE_LT:
11169 case OPTYPE_GT:
11170 case OPTYPE_NE:
11171 case OPTYPE_GE:
11172 case OPTYPE_LE:
11173 case OPTYPE_AND:
11174 case OPTYPE_OR:
11175 case OPTYPE_XOR:
11176 case OPTYPE_AND4B:
11177 case OPTYPE_OR4B:
11178 case OPTYPE_XOR4B:
11179 case OPTYPE_SHL:
11180 case OPTYPE_SHR:
11181 case OPTYPE_ROTL:
11182 case OPTYPE_ROTR:
11183 case OPTYPE_INT2BIT:
11184 case OPTYPE_INT2HEX:
11185 case OPTYPE_INT2OCT:
11186 //case OPTYPE_DECODE:
11187 str = u.expr.v1->rearrange_init_code(str);
11188 str = u.expr.v2->rearrange_init_code(str);
11189 break;
11190 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11191 case OPTYPE_OCT2UNICHAR:
11192 case OPTYPE_ENCODE_BASE64:
11193 str = u.expr.v1->rearrange_init_code(str);
11194 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str);
11195 break;
11196 case OPTYPE_SUBSTR:
11197 str = u.expr.ti1->rearrange_init_code(str);
11198 str = u.expr.v2->rearrange_init_code(str);
11199 str = u.expr.v3->rearrange_init_code(str);
11200 break;
11201 case OPTYPE_REGEXP:
11202 str = u.expr.ti1->rearrange_init_code(str);
11203 str = u.expr.t2->rearrange_init_code(str);
11204 str = u.expr.v3->rearrange_init_code(str);
11205 break;
11206 case OPTYPE_DECOMP:
11207 str = u.expr.v1->rearrange_init_code(str);
11208 str = u.expr.v2->rearrange_init_code(str);
11209 str = u.expr.v3->rearrange_init_code(str);
11210 break;
11211 case OPTYPE_REPLACE:
11212 str = u.expr.ti1->rearrange_init_code(str);
11213 str = u.expr.v2->rearrange_init_code(str);
11214 str = u.expr.v3->rearrange_init_code(str);
11215 str = u.expr.ti4->rearrange_init_code(str);
11216 break;
11217 case OPTYPE_LENGTHOF:
11218 case OPTYPE_SIZEOF:
11219 case OPTYPE_VALUEOF:
11220 case OPTYPE_ENCODE:
11221 case OPTYPE_ISPRESENT:
11222 case OPTYPE_TTCN2STRING:
11223 str = u.expr.ti1->rearrange_init_code(str);
11224 break;
11225 case OPTYPE_ISCHOSEN_T:
11226 str = u.expr.t1->rearrange_init_code(str);
11227 break;
11228 case OPTYPE_MATCH:
11229 str = u.expr.v1->rearrange_init_code(str);
11230 str = u.expr.t2->rearrange_init_code(str);
11231 break;
11232 default:
11233 // other kinds of expressions cannot appear within templates
11234 break;
11235 }
11236 break;
11237 default:
11238 break;
11239 }
11240 return str;
11241 }
11242
11243 char* Value::generate_code_tmp(char *str, const char *prefix,
11244 size_t& blockcount)
11245 {
11246 char *s2 = memptystr();
11247 char *s1 = generate_code_tmp(NULL, s2);
11248 if (s2[0]) {
11249 if (blockcount == 0) {
11250 str = mputstr(str, "{\n");
11251 blockcount++;
11252 }
11253 str = mputstr(str, s2);
11254 }
11255 Free(s2);
11256 str=mputstr(str, prefix);
11257 str=mputstr(str, s1);
11258 Free(s1);
11259 return str;
11260 }
11261
11262 char *Value::generate_code_tmp(char *str, char*& init)
11263 {
11264 expression_struct expr;
11265 Code::init_expr(&expr);
11266 generate_code_expr_mandatory(&expr);
11267 if (expr.preamble || expr.postamble) {
11268 if (valuetype == V_EXPR &&
11269 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11270 // a temporary variable is already introduced
11271 if (expr.preamble) init = mputstr(init, expr.preamble);
11272 if (expr.postamble) init = mputstr(init, expr.postamble);
11273 str = mputstr(str, expr.expr);
11274 } else {
11275 const string& tmp_id = get_temporary_id();
11276 const char *tmp_id_str = tmp_id.c_str();
11277 init = mputprintf(init, "%s %s;\n"
11278 "{\n",
11279 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11280 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11281 tmp_id_str);
11282 if (expr.preamble) init = mputstr(init, expr.preamble);
11283 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11284 if (expr.postamble) init = mputstr(init, expr.postamble);
11285 init = mputstr(init, "}\n");
11286 str = mputstr(str, tmp_id_str);
11287 }
11288 } else str = mputstr(str, expr.expr);
11289 Code::free_expr(&expr);
11290 return str;
11291 }
11292
11293 void Value::generate_code_log(expression_struct *expr)
11294 {
11295 if (explicit_cast_needed()) {
11296 char *expr_backup = expr->expr;
11297 expr->expr = NULL;
11298 generate_code_expr(expr);
11299 const string& tmp_id = get_temporary_id();
11300 const char *tmp_id_str = tmp_id.c_str();
11301 // We have to create a temporary object, because the parser of GCC
11302 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11303 // constructor call that is, this does not work: type(...).log(); but
11304 // this works: type tmp(...); tmp.log();.
11305 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11306 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11307 expr->expr);
11308 Free(expr->expr);
11309 expr->expr = mputstr(expr_backup, tmp_id_str);
11310 } else {
11311 generate_code_expr(expr);
11312 }
11313 expr->expr = mputstr(expr->expr, ".log()");
11314 }
11315
11316 void Value::generate_code_log_match(expression_struct *expr)
11317 {
11318 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11319 FATAL_ERROR("Value::generate_code_log_match()");
11320 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11321 // compliance the whole code-generation should be checked. Standalone
11322 // constructs like: "A(a[0].f());" should be avoided. The current
11323 // solution for HK38721 uses an additional assignment to overcome the
11324 // issue. The generated code will be slower, but it's needed for old GCC
11325 // versions in specific circumstances.
11326 if (u.expr.t2->needs_temp_ref()) {
11327 char *expr_backup = expr->expr;
11328 expr->expr = NULL;
11329 u.expr.t2->generate_code(expr);
11330 const string& tmp_id = get_temporary_id();
11331 const char *tmp_id_str = tmp_id.c_str();
11332 expr->preamble = mputprintf(expr->preamble,
11333 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11334 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11335 Free(expr->expr);
11336 expr->expr = mputstr(expr_backup, tmp_id_str);
11337 } else {
11338 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11339 // some reason "(A(NS::B)).a(C);" compiles fine.
11340 expr->expr = mputc(expr->expr, '(');
11341 u.expr.t2->generate_code(expr);
11342 expr->expr = mputc(expr->expr, ')');
11343 }
11344 expr->expr = mputstr(expr->expr, ".log_match(");
11345 u.expr.v1->generate_code_expr(expr);
11346 expr->expr = mputc(expr->expr, ')');
11347 }
11348
11349 void Value::generate_code_expr_expr(expression_struct *expr)
11350 {
11351 switch (u.expr.v_optype) {
11352 case OPTYPE_RND:
11353 generate_code_expr_rnd(expr, 0);
11354 break;
11355 case OPTYPE_UNARYPLUS:
11356 // same as without the '+' operator
11357 u.expr.v1->generate_code_expr(expr);
11358 break;
11359 case OPTYPE_UNARYMINUS:
11360 generate_code_expr_unary(expr, "-", u.expr.v1);
11361 break;
11362 case OPTYPE_NOT:
11363 generate_code_expr_unary(expr, "!", u.expr.v1);
11364 break;
11365 case OPTYPE_NOT4B:
11366 generate_code_expr_unary(expr, "~", u.expr.v1);
11367 break;
11368 case OPTYPE_BIT2HEX:
11369 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11370 break;
11371 case OPTYPE_BIT2INT:
11372 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11373 break;
11374 case OPTYPE_BIT2OCT:
11375 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11376 break;
11377 case OPTYPE_BIT2STR:
11378 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11379 break;
11380 case OPTYPE_CHAR2INT:
11381 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11382 break;
11383 case OPTYPE_CHAR2OCT:
11384 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11385 break;
11386 case OPTYPE_FLOAT2INT:
11387 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11388 break;
11389 case OPTYPE_FLOAT2STR:
11390 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11391 break;
11392 case OPTYPE_HEX2BIT:
11393 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11394 break;
11395 case OPTYPE_HEX2INT:
11396 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11397 break;
11398 case OPTYPE_HEX2OCT:
11399 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11400 break;
11401 case OPTYPE_HEX2STR:
11402 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11403 break;
11404 case OPTYPE_INT2CHAR:
11405 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11406 break;
11407 case OPTYPE_INT2FLOAT:
11408 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11409 break;
11410 case OPTYPE_INT2STR:
11411 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11412 break;
11413 case OPTYPE_INT2UNICHAR:
11414 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11415 break;
11416 case OPTYPE_OCT2BIT:
11417 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11418 break;
11419 case OPTYPE_OCT2CHAR:
11420 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11421 break;
11422 case OPTYPE_GET_STRINGENCODING:
11423 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11424 break;
11425 case OPTYPE_REMOVE_BOM:
11426 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11427 break;
11428 case OPTYPE_ENCODE_BASE64:
11429 if (u.expr.v2)
11430 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11431 else
11432 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11433 break;
11434 case OPTYPE_DECODE_BASE64:
11435 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11436 break;
11437 case OPTYPE_OCT2UNICHAR:
11438 if (u.expr.v2)
11439 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11440 else
11441 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11442 break;
11443 case OPTYPE_UNICHAR2OCT:
11444 if (u.expr.v2)
11445 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11446 else
11447 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11448 break;
11449 case OPTYPE_OCT2HEX:
11450 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11451 break;
11452 case OPTYPE_OCT2INT:
11453 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11454 break;
11455 case OPTYPE_OCT2STR:
11456 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11457 break;
11458 case OPTYPE_STR2BIT:
11459 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11460 break;
11461 case OPTYPE_STR2FLOAT:
11462 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11463 break;
11464 case OPTYPE_STR2HEX:
11465 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11466 break;
11467 case OPTYPE_STR2INT:
11468 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11469 break;
11470 case OPTYPE_STR2OCT:
11471 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11472 break;
11473 case OPTYPE_UNICHAR2INT:
11474 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11475 break;
11476 case OPTYPE_UNICHAR2CHAR:
11477 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11478 break;
11479 case OPTYPE_ENUM2INT: {
11480 Type* enum_type = u.expr.v1->get_expr_governor_last();
11481 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11482 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11483 enum_type->get_genname_value(my_scope).c_str());
11484 u.expr.v1->generate_code_expr_mandatory(expr);
11485 expr->expr = mputc(expr->expr, ')');
11486 break;}
11487 case OPTYPE_ENCODE:
11488 generate_code_expr_encode(expr);
11489 break;
11490 case OPTYPE_DECODE:
11491 generate_code_expr_decode(expr);
11492 break;
11493 case OPTYPE_RNDWITHVAL:
11494 generate_code_expr_rnd(expr, u.expr.v1);
11495 break;
11496 case OPTYPE_ADD:
11497 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11498 break;
11499 case OPTYPE_SUBTRACT:
11500 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11501 break;
11502 case OPTYPE_MULTIPLY:
11503 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11504 break;
11505 case OPTYPE_DIVIDE:
11506 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11507 break;
11508 case OPTYPE_MOD:
11509 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11510 break;
11511 case OPTYPE_REM:
11512 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11513 break;
11514 case OPTYPE_CONCAT:
11515 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11516 break;
11517 case OPTYPE_EQ:
11518 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11519 break;
11520 case OPTYPE_LT:
11521 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11522 break;
11523 case OPTYPE_GT:
11524 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11525 break;
11526 case OPTYPE_NE:
11527 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11528 break;
11529 case OPTYPE_GE:
11530 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11531 break;
11532 case OPTYPE_LE:
11533 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11534 break;
11535 case OPTYPE_AND:
11536 case OPTYPE_OR:
11537 generate_code_expr_and_or(expr);
11538 break;
11539 case OPTYPE_XOR:
11540 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11541 break;
11542 case OPTYPE_AND4B:
11543 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11544 break;
11545 case OPTYPE_OR4B:
11546 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11547 break;
11548 case OPTYPE_XOR4B:
11549 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11550 break;
11551 case OPTYPE_SHL:
11552 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11553 break;
11554 case OPTYPE_SHR:
11555 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11556 break;
11557 case OPTYPE_ROTL:
11558 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11559 break;
11560 case OPTYPE_ROTR:
11561 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11562 break;
11563 case OPTYPE_INT2BIT:
11564 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11565 break;
11566 case OPTYPE_INT2HEX:
11567 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11568 break;
11569 case OPTYPE_INT2OCT:
11570 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11571 break;
11572 case OPTYPE_SUBSTR:
11573 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11574 else generate_code_expr_substr_replace_compat(expr);
11575 break;
11576 case OPTYPE_REGEXP:
11577 generate_code_expr_regexp(expr);
11578 break;
11579 case OPTYPE_DECOMP:
11580 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11581 break;
11582 case OPTYPE_REPLACE:
11583 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11584 else generate_code_expr_substr_replace_compat(expr);
11585 break;
11586 case OPTYPE_ISCHOSEN: // r1 i2
11587 FATAL_ERROR("Value::generate_code_expr_expr()");
11588 break;
11589 case OPTYPE_ISCHOSEN_V: // v1 i2
11590 u.expr.v1->generate_code_expr_mandatory(expr);
11591 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11592 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11593 u.expr.i2->get_name().c_str());
11594 break;
11595 case OPTYPE_ISCHOSEN_T: // t1 i2
11596 u.expr.t1->generate_code_expr(expr);
11597 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11598 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11599 u.expr.i2->get_name().c_str());
11600 break;
11601 case OPTYPE_ISPRESENT:
11602 case OPTYPE_ISBOUND: {
11603 Template::templatetype_t temp = u.expr.ti1->get_Template()
11604 ->get_templatetype();
11605 if (temp == Template::SPECIFIC_VALUE) {
11606 Value* specific_value = u.expr.ti1->get_Template()
11607 ->get_specific_value();
11608 if (specific_value->get_valuetype() == Value::V_REFD) {
11609 Ttcn::Reference* reference =
11610 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11611 if (reference) {
11612 reference->generate_code_ispresentbound(expr, false,
11613 u.expr.v_optype==OPTYPE_ISBOUND);
11614 break;
11615 }
11616 }
11617 } else if (temp == Template::TEMPLATE_REFD){
11618 Ttcn::Reference* reference =
11619 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11620 ->get_reference());
11621 if (reference) {
11622 reference->generate_code_ispresentbound(expr, true,
11623 u.expr.v_optype==OPTYPE_ISBOUND);
11624 break;
11625 }
11626 }
11627 }
11628 // no break
11629 case OPTYPE_LENGTHOF: // ti1
11630 // fall through, separated later
11631 case OPTYPE_SIZEOF: // ti1
11632 // fall through, separated later
11633 case OPTYPE_ISVALUE: { // ti1
11634 if (u.expr.ti1->is_only_specific_value()) {
11635 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11636 bool cast_needed = t_val->explicit_cast_needed(
11637 u.expr.v_optype != OPTYPE_LENGTHOF);
11638 if(cast_needed) {
11639 // the ambiguous C++ expression is converted to the value class
11640 expr->expr = mputprintf(expr->expr, "%s(",
11641 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11642 }
11643
11644 if (u.expr.v_optype != OPTYPE_LENGTHOF
11645 && u.expr.v_optype != OPTYPE_SIZEOF) {
11646 t_val->generate_code_expr(expr);
11647 } else {
11648 t_val->generate_code_expr_mandatory(expr);
11649 }
11650
11651 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11652 }
11653 else u.expr.ti1->generate_code(expr);
11654
11655 switch (u.expr.v_optype) {
11656 case OPTYPE_ISBOUND:
11657 expr->expr=mputstr(expr->expr, ".is_bound()");
11658 break;
11659 case OPTYPE_ISPRESENT:
11660 expr->expr=mputstr(expr->expr, ".is_present()");
11661 break;
11662 case OPTYPE_SIZEOF:
11663 expr->expr=mputstr(expr->expr, ".size_of()");
11664 break;
11665 case OPTYPE_LENGTHOF:
11666 expr->expr=mputstr(expr->expr, ".lengthof()");
11667 break;
11668 case OPTYPE_ISVALUE:
11669 expr->expr=mputstr(expr->expr, ".is_value()");
11670 break;
11671 default:
11672 FATAL_ERROR("Value::generate_code_expr_expr()");
11673 }
11674 break; }
11675 case OPTYPE_VALUEOF: // ti1
11676 u.expr.ti1->generate_code(expr);
11677 expr->expr = mputstr(expr->expr, ".valueof()");
11678 break;
11679 case OPTYPE_MATCH: // v1 t2
11680 u.expr.t2->generate_code(expr);
11681 expr->expr = mputstr(expr->expr, ".match(");
11682 u.expr.v1->generate_code_expr(expr);
11683 expr->expr = mputc(expr->expr, ')');
11684 break;
11685 case OPTYPE_UNDEF_RUNNING:
11686 // it is resolved during semantic check
11687 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11688 break;
11689 case OPTYPE_COMP_NULL: // -
11690 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11691 break;
11692 case OPTYPE_COMP_MTC: // -
11693 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11694 break;
11695 case OPTYPE_COMP_SYSTEM: // -
11696 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11697 break;
11698 case OPTYPE_COMP_SELF: // -
11699 expr->expr=mputstr(expr->expr, "self");
11700 break;
11701 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11702 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11703 u.expr.b4);
11704 break;
11705 case OPTYPE_COMP_RUNNING: // v1
11706 u.expr.v1->generate_code_expr(expr);
11707 if(u.expr.v1->get_valuetype() == V_REFD)
11708 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11709 expr->expr = mputstr(expr->expr, ".running()");
11710 break;
11711 case OPTYPE_COMP_RUNNING_ANY: // -
11712 expr->expr=mputstr(expr->expr,
11713 "TTCN_Runtime::component_running(ANY_COMPREF)");
11714 break;
11715 case OPTYPE_COMP_RUNNING_ALL: // -
11716 expr->expr=mputstr(expr->expr,
11717 "TTCN_Runtime::component_running(ALL_COMPREF)");
11718 break;
11719 case OPTYPE_COMP_ALIVE: // v1
11720 u.expr.v1->generate_code_expr(expr);
11721 if(u.expr.v1->get_valuetype() == V_REFD)
11722 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11723 expr->expr = mputstr(expr->expr, ".alive()");
11724 break;
11725 case OPTYPE_COMP_ALIVE_ANY: // -
11726 expr->expr = mputstr(expr->expr,
11727 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11728 break;
11729 case OPTYPE_COMP_ALIVE_ALL: // -
11730 expr->expr = mputstr(expr->expr,
11731 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11732 break;
11733 case OPTYPE_TMR_READ: // r1
11734 u.expr.r1->generate_code(expr);
11735 expr->expr = mputstr(expr->expr, ".read()");
11736 break;
11737 case OPTYPE_TMR_RUNNING: // r1
11738 u.expr.r1->generate_code(expr);
11739 expr->expr = mputstr(expr->expr, ".running()");
11740 break;
11741 case OPTYPE_TMR_RUNNING_ANY: // -
11742 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11743 break;
11744 case OPTYPE_GETVERDICT: // -
11745 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11746 break;
11747 case OPTYPE_TESTCASENAME: // -
11748 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11749 break;
11750 case OPTYPE_ACTIVATE: // r1
11751 generate_code_expr_activate(expr);
11752 break;
11753 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
11754 generate_code_expr_activate_refd(expr);
11755 break;
11756 case OPTYPE_EXECUTE: // r1 [v2]
11757 generate_code_expr_execute(expr);
11758 break;
11759 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
11760 generate_code_expr_execute_refd(expr);
11761 break;
11762 case OPTYPE_LOG2STR:
11763 u.expr.logargs->generate_code_expr(expr);
11764 break;
11765 case OPTYPE_TTCN2STRING: {
11766 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
11767 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
11768 param_governor = param_governor->get_type_refd_last();
11769 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
11770 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
11771 u.expr.ti1->get_Template()->is_Value()) {
11772 Value* v = u.expr.ti1->get_Template()->get_Value();
11773 delete u.expr.ti1;
11774 u.expr.ti1 = NULL;
11775 bool cast_needed = v->explicit_cast_needed();
11776 if (cast_needed) {
11777 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
11778 }
11779 v->generate_code_expr(expr);
11780 if (cast_needed) {
11781 expr->expr = mputstr(expr->expr, ")");
11782 }
11783 delete v;
11784 } else {
11785 u.expr.ti1->generate_code(expr);
11786 }
11787 expr->expr = mputstr(expr->expr, ")");
11788 } break;
11789 case OPTYPE_PROF_RUNNING:
11790 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
11791 break;
11792 default:
11793 FATAL_ERROR("Value::generate_code_expr_expr()");
11794 }
11795 }
11796
11797 void Value::generate_code_expr_unary(expression_struct *expr,
11798 const char *operator_str, Value *v1)
11799 {
11800 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
11801 v1->generate_code_expr_mandatory(expr);
11802 expr->expr = mputstrn(expr->expr, "))", 2);
11803 }
11804
11805 void Value::generate_code_expr_infix(expression_struct *expr,
11806 const char *operator_str, Value *v1,
11807 Value *v2, bool optional_allowed)
11808 {
11809 if (!get_needs_conversion()) {
11810 expr->expr = mputc(expr->expr, '(');
11811 if (optional_allowed) v1->generate_code_expr(expr);
11812 else v1->generate_code_expr_mandatory(expr);
11813 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
11814 if (optional_allowed) v2->generate_code_expr(expr);
11815 else v2->generate_code_expr_mandatory(expr);
11816 expr->expr = mputc(expr->expr, ')');
11817 } else { // Temporary variable for the converted value.
11818 const string& tmp_id1 = get_temporary_id();
11819 const char *tmp_id_str1 = tmp_id1.c_str();
11820 expression_struct expr_tmp;
11821 Code::init_expr(&expr_tmp);
11822 switch (u.expr.v_optype) {
11823 case OPTYPE_EQ:
11824 case OPTYPE_NE: {
11825 // Always "v1 -> v2".
11826 Type *t1 = v1->get_expr_governor_last();
11827 Type *t2 = v2->get_expr_governor_last();
11828 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
11829 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11830 else v2->generate_code_expr_mandatory(&expr_tmp);
11831 if (expr_tmp.preamble)
11832 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11833 expr->preamble = mputprintf(expr->preamble,
11834 "%s %s;\n"
11835 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11836 "and `%s' are not compatible at run-time\");\n",
11837 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
11838 TypeConv::get_conv_func(t2, t1, get_my_scope()
11839 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
11840 t2->get_typename().c_str(), t1->get_typename().c_str());
11841 Code::free_expr(&expr_tmp);
11842 if (optional_allowed) v1->generate_code_expr(expr);
11843 else v1->generate_code_expr_mandatory(expr);
11844 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
11845 tmp_id_str1);
11846 break; }
11847 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11848 // functions. The governors of all operands must exist at this point.
11849 case OPTYPE_ROTL:
11850 case OPTYPE_ROTR:
11851 case OPTYPE_CONCAT: {
11852 const string& tmp_id2 = get_temporary_id();
11853 const char *tmp_id_str2 = tmp_id2.c_str();
11854 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
11855 Type *my_gov = my_governor->get_type_refd_last();
11856 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
11857 ->get_type_refd_last();
11858 if (!t1_gov || my_gov == t1_gov)
11859 FATAL_ERROR("Value::generate_code_expr_infix()");
11860 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11861 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
11862 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11863 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
11864 else v1->generate_code_expr_mandatory(&expr_tmp);
11865 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
11866 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11867 else v2->generate_code_expr_mandatory(&expr_tmp);
11868 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11869 expr->preamble = mputprintf(expr->preamble,
11870 "%s %s;\n"
11871 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11872 "and `%s' are not compatible at run-time\");\n",
11873 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11874 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
11875 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
11876 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
11877 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11878 break; }
11879 default:
11880 FATAL_ERROR("Value::generate_code_expr_infix()");
11881 break;
11882 }
11883 }
11884 }
11885
11886 void Value::generate_code_expr_and_or(expression_struct *expr)
11887 {
11888 if (u.expr.v2->needs_short_circuit()) {
11889 // introduce a temporary variable to store the result of the operation
11890 const string& tmp_id = get_temporary_id();
11891 const char *tmp_id_str = tmp_id.c_str();
11892 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
11893 expression_struct expr2;
11894 // the left operand must be evaluated anyway
11895 Code::init_expr(&expr2);
11896 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11897 u.expr.v1->generate_code_expr_mandatory(&expr2);
11898 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11899 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
11900 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
11901 // evaluate the right operand only when necessary
11902 // in this case the final result will be the right operand
11903 Code::init_expr(&expr2);
11904 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11905 u.expr.v2->generate_code_expr_mandatory(&expr2);
11906 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11907 // the result is now in the temporary variable
11908 expr->expr = mputstr(expr->expr, tmp_id_str);
11909 } else {
11910 // use the overloaded operator to get better error messages
11911 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
11912 "&&" : "||", u.expr.v1, u.expr.v2, false);
11913 }
11914 }
11915
11916 void Value::generate_code_expr_predef1(expression_struct *expr,
11917 const char *function_name,
11918 Value *v1)
11919 {
11920 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11921 v1->generate_code_expr_mandatory(expr);
11922 expr->expr = mputc(expr->expr, ')');
11923 }
11924
11925 void Value::generate_code_expr_predef2(expression_struct *expr,
11926 const char *function_name,
11927 Value *v1, Value *v2)
11928 {
11929 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11930 v1->generate_code_expr_mandatory(expr);
11931 expr->expr = mputstr(expr->expr, ", ");
11932 v2->generate_code_expr_mandatory(expr);
11933 expr->expr = mputc(expr->expr, ')');
11934 }
11935
11936 void Value::generate_code_expr_predef3(expression_struct *expr,
11937 const char *function_name,
11938 Value *v1, Value *v2, Value *v3)
11939 {
11940 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11941 v1->generate_code_expr_mandatory(expr);
11942 expr->expr = mputstr(expr->expr, ", ");
11943 v2->generate_code_expr_mandatory(expr);
11944 expr->expr = mputstr(expr->expr, ", ");
11945 v3->generate_code_expr_mandatory(expr);
11946 expr->expr = mputc(expr->expr, ')');
11947 }
11948
11949 void Value::generate_code_expr_substr(expression_struct *expr)
11950 {
11951 bool par1_is_str;
11952 Value* v1 = u.expr.ti1->get_specific_value();
11953 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
11954 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
11955 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
11956 if (v1) v1->generate_code_expr_mandatory(expr);
11957 else u.expr.ti1->generate_code(expr);
11958 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
11959 else expr->expr = mputstr(expr->expr, ".substr(");
11960 if (!par1_is_str && u.expr.v2->is_unfoldable())
11961 expr->expr = mputstr(expr->expr, "(int)");
11962 u.expr.v2->generate_code_expr_mandatory(expr);
11963 expr->expr = mputstr(expr->expr, ", ");
11964 if (!par1_is_str && u.expr.v3->is_unfoldable())
11965 expr->expr = mputstr(expr->expr, "(int)");
11966 u.expr.v3->generate_code_expr_mandatory(expr);
11967 expr->expr = mputc(expr->expr, ')');
11968 }
11969
11970 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
11971 {
11972 expression_struct expr_tmp;
11973 Code::init_expr(&expr_tmp);
11974 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
11975 ->get_type_refd_last();
11976 if (!t1 || t1 == my_governor->get_type_refd_last())
11977 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11978 if (u.expr.v_optype == OPTYPE_SUBSTR) {
11979 generate_code_expr_substr(&expr_tmp);
11980 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
11981 generate_code_expr_replace(&expr_tmp);
11982 } else {
11983 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11984 }
11985 // Two temporaries to store the result of substr() or replace() and to
11986 // store the converted value.
11987 const string& tmp_id1 = get_temporary_id();
11988 const char *tmp_id_str1 = tmp_id1.c_str();
11989 const string& tmp_id2 = get_temporary_id();
11990 const char *tmp_id_str2 = tmp_id2.c_str();
11991 if (expr_tmp.preamble)
11992 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11993 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
11994 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
11995 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
11996 if (expr_tmp.postamble)
11997 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
11998 Code::free_expr(&expr_tmp);
11999 expr->preamble = mputprintf(expr->preamble,
12000 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12001 "`%s' are not compatible at run-time\");\n",
12002 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12003 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12004 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12005 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12006 }
12007
12008 void Value::generate_code_expr_regexp(expression_struct *expr)
12009 {
12010 Value* v1 = u.expr.ti1->get_specific_value();
12011 Value* v2 = u.expr.t2->get_specific_value();
12012 expr->expr = mputstr(expr->expr, "regexp(");
12013 if (v1) v1->generate_code_expr_mandatory(expr);
12014 else u.expr.ti1->generate_code(expr);
12015 expr->expr = mputstr(expr->expr, ", ");
12016 if (v2) v2->generate_code_expr_mandatory(expr);
12017 else u.expr.t2->generate_code(expr);
12018 expr->expr = mputstr(expr->expr, ", ");
12019 u.expr.v3->generate_code_expr_mandatory(expr);
12020 expr->expr = mputc(expr->expr, ')');
12021 }
12022
12023 void Value::generate_code_expr_replace(expression_struct *expr)
12024 {
12025 Value* v1 = u.expr.ti1->get_specific_value();
12026 Value* v4 = u.expr.ti4->get_specific_value();
12027 bool par1_is_str;
12028 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12029 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12030 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12031 if (v1) v1->generate_code_expr_mandatory(expr);
12032 else u.expr.ti1->generate_code(expr);
12033 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12034 else expr->expr = mputstr(expr->expr, ".replace(");
12035 if (!par1_is_str && u.expr.v2->is_unfoldable())
12036 expr->expr = mputstr(expr->expr, "(int)");
12037 u.expr.v2->generate_code_expr_mandatory(expr);
12038 expr->expr = mputstr(expr->expr, ", ");
12039 if (!par1_is_str && u.expr.v3->is_unfoldable())
12040 expr->expr = mputstr(expr->expr, "(int)");
12041 u.expr.v3->generate_code_expr_mandatory(expr);
12042 expr->expr = mputstr(expr->expr, ", ");
12043 if (v4) {
12044 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12045 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12046 Value* v4_last = v4->get_value_refd_last();
12047 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12048 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12049 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_stringRepr().c_str());
12050 }
12051 v4->generate_code_expr_mandatory(expr);
12052 }
12053 else u.expr.ti4->generate_code(expr);
12054 expr->expr = mputc(expr->expr, ')');
12055 }
12056
12057 void Value::generate_code_expr_rnd(expression_struct *expr,
12058 Value *v1)
12059 {
12060 if(!v1) // simple random generation
12061 expr->expr = mputstr(expr->expr, "rnd()");
12062 else { // random generation with seeding
12063 expr->expr = mputstr(expr->expr, "rnd(");
12064 v1->generate_code_expr_mandatory(expr);
12065 expr->expr = mputc(expr->expr, ')');
12066 }
12067 }
12068
12069 void Value::generate_code_expr_create(expression_struct *expr,
12070 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12071 {
12072 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12073 // first two arguments: component type
12074 Assignment *t_ass = type->get_refd_assignment();
12075 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12076 FATAL_ERROR("Value::generate_code_expr_create()");
12077 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12078 Type::EXPECTED_DYNAMIC_VALUE);
12079 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12080 comptype = comptype->get_type_refd_last();
12081 expr->expr = comptype->get_CompBody()
12082 ->generate_code_comptype_name(expr->expr);
12083 expr->expr = mputstr(expr->expr, ", ");
12084 // third argument: component name
12085 if (name) {
12086 Value *t_val = name->get_value_refd_last();
12087 if (t_val->valuetype == V_CSTR) {
12088 // the argument is foldable to a string literal
12089 size_t str_len = t_val->u.str.val_str->size();
12090 const char *str_ptr = t_val->u.str.val_str->c_str();
12091 expr->expr = mputc(expr->expr, '"');
12092 for (size_t i = 0; i < str_len; i++)
12093 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12094 expr->expr = mputc(expr->expr, '"');
12095 } else name->generate_code_expr_mandatory(expr);
12096 } else expr->expr = mputstr(expr->expr, "NULL");
12097 expr->expr = mputstr(expr->expr, ", ");
12098 // fourth argument: location
12099 if (location) {
12100 Value *t_val = location->get_value_refd_last();
12101 if (t_val->valuetype == V_CSTR) {
12102 // the argument is foldable to a string literal
12103 size_t str_len = t_val->u.str.val_str->size();
12104 const char *str_ptr = t_val->u.str.val_str->c_str();
12105 expr->expr = mputc(expr->expr, '"');
12106 for (size_t i = 0; i < str_len; i++)
12107 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12108 expr->expr = mputc(expr->expr, '"');
12109 } else location->generate_code_expr_mandatory(expr);
12110 } else expr->expr = mputstr(expr->expr, "NULL");
12111 // fifth argument: alive flag
12112 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12113 }
12114
12115 void Value::generate_code_expr_activate(expression_struct *expr)
12116 {
12117 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12118 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12119 FATAL_ERROR("Value::generate_code_expr_activate()");
12120 expr->expr = mputprintf(expr->expr, "%s(",
12121 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12122 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12123 expr->expr = mputc(expr->expr, ')');
12124 }
12125
12126 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12127 {
12128 Value *v_last = u.expr.v1->get_value_refd_last();
12129 if (v_last->valuetype == V_ALTSTEP) {
12130 // the referred altstep is known
12131 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12132 ->get_genname_from_scope(my_scope, "activate_").c_str());
12133 } else {
12134 // the referred altstep is unknown
12135 u.expr.v1->generate_code_expr_mandatory(expr);
12136 expr->expr = mputstr(expr->expr,".activate(");
12137 }
12138 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12139 expr->expr = mputc(expr->expr, ')');
12140 }
12141
12142 void Value::generate_code_expr_execute(expression_struct *expr)
12143 {
12144 Assignment *testcase = u.expr.r1->get_refd_assignment();
12145 expr->expr = mputprintf(expr->expr, "%s(",
12146 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12147 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12148 if (parlist->get_nof_pars() > 0) {
12149 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12150 0, false);
12151 expr->expr = mputstr(expr->expr, ", ");
12152 }
12153 if (u.expr.v2) {
12154 expr->expr = mputstr(expr->expr, "TRUE, ");
12155 u.expr.v2->generate_code_expr_mandatory(expr);
12156 expr->expr = mputc(expr->expr, ')');
12157 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12158 }
12159
12160 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12161 {
12162 Value *v_last = u.expr.v1->get_value_refd_last();
12163 if (v_last->valuetype == V_TESTCASE) {
12164 // the referred testcase is known
12165 Assignment *testcase = v_last->get_refd_fat();
12166 expr->expr = mputprintf(expr->expr, "%s(",
12167 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12168 u.expr.ap_list2->generate_code_alias(expr,
12169 testcase->get_FormalParList(), 0, false);
12170 } else {
12171 // the referred testcase is unknown
12172 u.expr.v1->generate_code_expr_mandatory(expr);
12173 expr->expr = mputstr(expr->expr,".execute(");
12174 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12175 }
12176 if (u.expr.ap_list2->get_nof_pars() > 0)
12177 expr->expr = mputstr(expr->expr, ", ");
12178 if (u.expr.v3) {
12179 expr->expr = mputstr(expr->expr, "TRUE, ");
12180 u.expr.v3->generate_code_expr_mandatory(expr);
12181 expr->expr = mputc(expr->expr, ')');
12182 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12183 }
12184
12185 void Value::generate_code_expr_invoke(expression_struct *expr)
12186 {
12187 Value *last_v = u.invoke.v->get_value_refd_last();
12188 if (last_v->get_valuetype() == V_FUNCTION) {
12189 // the referred function is known
12190 Assignment *function = last_v->get_refd_fat();
12191 expr->expr = mputprintf(expr->expr, "%s(",
12192 function->get_genname_from_scope(my_scope).c_str());
12193 u.invoke.ap_list->generate_code_alias(expr,
12194 function->get_FormalParList(), function->get_RunsOnType(), false);
12195 } else {
12196 // the referred function is unknown
12197 u.invoke.v->generate_code_expr_mandatory(expr);
12198 expr->expr = mputstr(expr->expr, ".invoke(");
12199 Type* gov_last = last_v->get_expr_governor_last();
12200 u.invoke.ap_list->generate_code_alias(expr, 0,
12201 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12202 }
12203 expr->expr = mputc(expr->expr, ')');
12204 }
12205
12206 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12207 Reference *ref)
12208 {
12209 // if the referenced value points to an optional value field the
12210 // generated code has to be corrected at the end:
12211 // `fieldid()' => `fieldid()()'
12212 Assignment *ass = ref->get_refd_assignment();
12213 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12214 switch (ass->get_asstype()) {
12215 case Assignment::A_CONST:
12216 case Assignment::A_EXT_CONST:
12217 case Assignment::A_MODULEPAR:
12218 case Assignment::A_VAR:
12219 case Assignment::A_FUNCTION_RVAL:
12220 case Assignment::A_EXT_FUNCTION_RVAL:
12221 case Assignment::A_PAR_VAL_IN:
12222 case Assignment::A_PAR_VAL_OUT:
12223 case Assignment::A_PAR_VAL_INOUT:
12224 // only these are mapped to value objects
12225 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12226 expr->expr = mputstr(expr->expr, "()");
12227 break;
12228 default:
12229 break;
12230 }
12231 }
12232
12233 void Value::generate_code_expr_encode(expression_struct *expr)
12234 {
12235 Value* v1 = 0;
12236
12237 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12238 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12239 v1 = templ->get_specific_value();
12240 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12241
12242 expression_struct expr2;
12243 Code::init_expr(&expr2);
12244
12245 bool is_templ = false;
12246 switch (templ->get_templatetype()) {
12247 case Template::SPECIFIC_VALUE:
12248 v1->generate_code_expr_mandatory(&expr2);
12249 break;
12250 default:
12251 u.expr.ti1->generate_code(&expr2);
12252 is_templ = true;
12253 break;
12254 }
12255
12256 if (!gov_last->is_coding_by_function()) {
12257 const string& tmp_id = get_temporary_id();
12258 const string& tmp_buf_id = get_temporary_id();
12259 const string& tmp_ref_id = get_temporary_id();
12260 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12261 tmp_id.c_str());
12262 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12263 tmp_buf_id.c_str());
12264 if (expr2.preamble) { // copy preamble setting up the argument, if any
12265 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12266 expr->preamble = mputc (expr->preamble, '\n');
12267 }
12268 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12269 gov_last->get_genname_typedescriptor(
12270 u.expr.ti1->get_Template()->get_my_scope()
12271 ).c_str(),
12272 tmp_ref_id.c_str(),
12273 expr2.expr);
12274 if (is_templ) // make a value out of the template, if needed
12275 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12276 expr->preamble = mputprintf(expr->preamble,
12277 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12278 tmp_ref_id.c_str(),
12279 gov_last->get_genname_typedescriptor(
12280 u.expr.ti1->get_Template()->get_my_scope()
12281 ).c_str(),
12282 tmp_buf_id.c_str(),
12283 gov_last->get_coding(true).c_str()
12284 );
12285 expr->preamble = mputstr(expr->preamble, ");\n");
12286 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12287 tmp_buf_id.c_str(),
12288 tmp_id.c_str()
12289 );
12290 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12291 if (expr2.postamble)
12292 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12293 } else
12294 expr->expr = mputprintf(expr->expr, "%s(%s)",
12295 gov_last->get_coding(true).c_str(), expr2.expr);
12296 Code::free_expr(&expr2);
12297 }
12298
12299 void Value::generate_code_expr_decode(expression_struct *expr)
12300 {
12301 expression_struct expr1, expr2;
12302 Code::init_expr(&expr1);
12303 Code::init_expr(&expr2);
12304 u.expr.r1->generate_code(&expr1);
12305 u.expr.r2->generate_code(&expr2);
12306
12307 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12308 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12309 get_type_refd_last();
12310
12311 if (expr1.preamble)
12312 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12313 if (expr2.preamble)
12314 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12315
12316 if (!_type->is_coding_by_function()) {
12317 const string& tmp_id = get_temporary_id();
12318 const string& buffer_id = get_temporary_id();
12319 const string& retval_id = get_temporary_id();
12320 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12321 field_is_optional(u.expr.r2->get_subrefs());
12322
12323 expr->preamble = mputprintf(expr->preamble,
12324 "TTCN_Buffer %s(bit2oct(%s));\n"
12325 "INTEGER %s;\n"
12326 "TTCN_EncDec::set_error_behavior("
12327 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12328 "TTCN_EncDec::clear_error();\n",
12329 buffer_id.c_str(),
12330 expr1.expr,
12331 retval_id.c_str()
12332 );
12333 expr->preamble = mputprintf(expr->preamble,
12334 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12335 expr2.expr,
12336 optional ? "()" : "",
12337 _type->get_genname_typedescriptor(
12338 u.expr.r2->get_my_scope()
12339 ).c_str(),
12340 buffer_id.c_str(),
12341 _type->get_coding(false).c_str()
12342 );
12343 expr->preamble = mputprintf(expr->preamble,
12344 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12345 "case TTCN_EncDec::ET_NONE: {\n"
12346 "%s.cut();\n"
12347 "OCTETSTRING %s;\n"
12348 "%s.get_string(%s);\n"
12349 "%s = oct2bit(%s);\n"
12350 "%s = 0;\n"
12351 "}break;\n"
12352 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12353 "case TTCN_EncDec::ET_LEN_ERR:\n"
12354 "%s = 2;\n"
12355 "break;\n"
12356 "default:\n"
12357 "%s = 1;\n"
12358 "}\n"
12359 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12360 "TTCN_EncDec::EB_DEFAULT);\n"
12361 "TTCN_EncDec::clear_error();\n",
12362 buffer_id.c_str(),
12363 tmp_id.c_str(),
12364 buffer_id.c_str(),
12365 tmp_id.c_str(),
12366 expr1.expr,
12367 tmp_id.c_str(),
12368 retval_id.c_str(),
12369 retval_id.c_str(),
12370 retval_id.c_str()
12371 );
12372 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12373 } else
12374 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12375 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12376 if (expr1.postamble)
12377 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12378 if (expr2.postamble)
12379 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12380 Code::free_expr(&expr1);
12381 Code::free_expr(&expr2);
12382 }
12383
12384 char *Value::generate_code_init_choice(char *str, const char *name)
12385 {
12386 const char *alt_name = u.choice.alt_name->get_name().c_str();
12387 // Safe as long as get_name() returns a const string&, not a temporary.
12388 const char *alt_prefix =
12389 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12390 ? "AT_" : "";
12391 if (u.choice.alt_value->needs_temp_ref()) {
12392 const string& tmp_id = get_temporary_id();
12393 const char *tmp_id_str = tmp_id.c_str();
12394 str = mputprintf(str, "{\n"
12395 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12396 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12397 alt_prefix, alt_name);
12398 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12399 str = mputstr(str, "}\n");
12400 } else {
12401 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12402 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12403 Free(embedded_name);
12404 }
12405 return str;
12406 }
12407
12408 char *Value::generate_code_init_seof(char *str, const char *name)
12409 {
12410 size_t nof_vs = u.val_vs->get_nof_vs();
12411 if (nof_vs > 0) {
12412 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12413 const string& embedded_type =
12414 my_governor->get_ofType()->get_genname_value(my_scope);
12415 const char *embedded_type_str = embedded_type.c_str();
12416 for (size_t i = 0; i < nof_vs; i++) {
12417 Value *comp_v = u.val_vs->get_v_byIndex(i);
12418
12419 if (comp_v->valuetype == V_NOTUSED) continue;
12420 else if (comp_v->needs_temp_ref()) {
12421 const string& tmp_id = get_temporary_id();
12422 const char *tmp_id_str = tmp_id.c_str();
12423 str = mputprintf(str, "{\n"
12424 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12425 (unsigned long) i);
12426 str = comp_v->generate_code_init(str, tmp_id_str);
12427 str = mputstr(str, "}\n");
12428 } else {
12429 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12430 str = comp_v->generate_code_init(str, embedded_name);
12431 Free(embedded_name);
12432 }
12433 }
12434 } else {
12435 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12436 }
12437 return str;
12438 }
12439
12440 char *Value::generate_code_init_indexed(char *str, const char *name)
12441 {
12442 size_t nof_ivs = u.val_vs->get_nof_ivs();
12443 if (nof_ivs > 0) {
12444 // Previous values can be truncated. The concept is similar to
12445 // templates.
12446 Type *t_last = my_governor->get_type_refd_last();
12447 const string& oftype_name =
12448 t_last->get_ofType()->get_genname_value(my_scope);
12449 const char *oftype_name_str = oftype_name.c_str();
12450 for (size_t i = 0; i < nof_ivs; i++) {
12451 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12452 const string& tmp_id_1 = get_temporary_id();
12453 str = mputstr(str, "{\n");
12454 Value *index = iv->get_index();
12455 if (index->get_valuetype() != V_INT) {
12456 const string& tmp_id_2 = get_temporary_id();
12457 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12458 str = index->generate_code_init(str, tmp_id_2.c_str());
12459 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12460 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12461 } else {
12462 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12463 tmp_id_1.c_str(), name,
12464 (index->get_val_Int()->t_str()).c_str());
12465 }
12466 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12467 str = mputstr(str, "}\n");
12468 }
12469 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12470 return str;
12471 }
12472
12473 char *Value::generate_code_init_array(char *str, const char *name)
12474 {
12475 size_t nof_vs = u.val_vs->get_nof_vs();
12476 Type *t_last = my_governor->get_type_refd_last();
12477 Int index_offset = t_last->get_dimension()->get_offset();
12478 const string& embedded_type =
12479 t_last->get_ofType()->get_genname_value(my_scope);
12480 const char *embedded_type_str = embedded_type.c_str();
12481 for (size_t i = 0; i < nof_vs; i++) {
12482 Value *comp_v = u.val_vs->get_v_byIndex(i);
12483 if (comp_v->valuetype == V_NOTUSED) continue;
12484 else if (comp_v->needs_temp_ref()) {
12485 const string& tmp_id = get_temporary_id();
12486 const char *tmp_id_str = tmp_id.c_str();
12487 str = mputprintf(str, "{\n"
12488 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12489 Int2string(index_offset + i).c_str());
12490 str = comp_v->generate_code_init(str, tmp_id_str);
12491 str = mputstr(str, "}\n");
12492 } else {
12493 char *embedded_name = mprintf("%s[%s]", name,
12494 Int2string(index_offset + i).c_str());
12495 str = comp_v->generate_code_init(str, embedded_name);
12496 Free(embedded_name);
12497 }
12498 }
12499 return str;
12500 }
12501
12502 char *Value::generate_code_init_se(char *str, const char *name)
12503 {
12504 Type *type = my_governor->get_type_refd_last();
12505 size_t nof_comps = type->get_nof_comps();
12506 if (nof_comps > 0) {
12507 for (size_t i = 0; i < nof_comps; i++) {
12508 CompField *cf = type->get_comp_byIndex(i);
12509 const Identifier& field_id = cf->get_name();
12510 const char *field_name = field_id.get_name().c_str();
12511 Value *field_v;
12512 if (u.val_nvs->has_nv_withName(field_id)) {
12513 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12514 if (field_v->valuetype == V_NOTUSED) continue;
12515 if (field_v->valuetype == V_OMIT) field_v = 0;
12516 } else if (is_asn1()) {
12517 if (cf->has_default()) {
12518 // handle like a referenced value
12519 Value *defval = cf->get_defval();
12520 if (needs_init_precede(defval)) {
12521 str = defval->generate_code_init(str,
12522 defval->get_lhs_name().c_str());
12523 }
12524 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12525 defval->get_genname_own(my_scope).c_str());
12526 continue;
12527 } else {
12528 if (!cf->get_is_optional())
12529 FATAL_ERROR("Value::generate_code_init()");
12530 field_v = 0;
12531 }
12532 } else {
12533 continue;
12534 }
12535 if (field_v) {
12536 // the value is not omit
12537 if (field_v->needs_temp_ref()) {
12538 const string& tmp_id = get_temporary_id();
12539 const char *tmp_id_str = tmp_id.c_str();
12540 str = mputprintf(str, "{\n"
12541 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12542 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12543 field_name);
12544 str = field_v->generate_code_init(str, tmp_id_str);
12545 str = mputstr(str, "}\n");
12546 } else {
12547 char *embedded_name = mprintf("%s.%s()", name,
12548 field_name);
12549 if (cf->get_is_optional() && field_v->is_compound())
12550 embedded_name = mputstr(embedded_name, "()");
12551 str = field_v->generate_code_init(str, embedded_name);
12552 Free(embedded_name);
12553 }
12554 } else {
12555 // the value is omit
12556 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12557 name, field_name);
12558 }
12559 }
12560 } else {
12561 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12562 }
12563 return str;
12564 }
12565
12566 char *Value::generate_code_init_refd(char *str, const char *name)
12567 {
12568 Value *v = get_value_refd_last();
12569 if (v == this) {
12570 // the referred value is not available at compile time
12571 // the code generation is based on the reference
12572 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
12573 str = TypeConv::gen_conv_code_refd(str, name, v);
12574 } else {
12575 expression_struct expr;
12576 Code::init_expr(&expr);
12577 expr.expr = mputprintf(expr.expr, "%s = ", name);
12578 u.ref.ref->generate_code_const_ref(&expr);
12579 str = Code::merge_free_expr(str, &expr);
12580 }
12581 } else {
12582 // the referred value is available at compile time
12583 // the code generation is based on the referred value
12584 if (v->has_single_expr() &&
12585 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
12586 // simple substitution for in-line values within the same module
12587 str = mputprintf(str, "%s = %s;\n", name,
12588 v->get_single_expr().c_str());
12589 } else {
12590 // use a simple reference to reduce code size
12591 if (needs_init_precede(v)) {
12592 // the referred value must be initialized first
12593 if (!v->is_toplevel() && v->needs_temp_ref()) {
12594 // temporary id should be introduced for the lhs
12595 const string& tmp_id = get_temporary_id();
12596 const char *tmp_id_str = tmp_id.c_str();
12597 str = mputprintf(str, "{\n"
12598 "%s& %s = %s;\n",
12599 v->get_my_governor()->get_genname_value(my_scope).c_str(),
12600 tmp_id_str, v->get_lhs_name().c_str());
12601 str = v->generate_code_init(str, tmp_id_str);
12602 str = mputstr(str, "}\n");
12603 } else {
12604 str = v->generate_code_init(str, v->get_lhs_name().c_str());
12605 }
12606 }
12607 str = mputprintf(str, "%s = %s;\n", name,
12608 v->get_genname_own(my_scope).c_str());
12609 }
12610 }
12611 return str;
12612 }
12613
12614 bool Value::explicit_cast_needed(bool forIsValue)
12615 {
12616 Value *v_last = get_value_refd_last();
12617 if (v_last != this) {
12618 // this is a foldable referenced value
12619 // if the reference points to an imported or compound value the code
12620 // generation will be based on the reference so cast is not needed
12621 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
12622 || !v_last->has_single_expr()) return false;
12623 } else if (v_last->valuetype == V_REFD) {
12624 // this is an unfoldable reference (v_last==this)
12625 // explicit cast is needed only for string element references
12626 if (forIsValue) return false;
12627 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
12628 return t_subrefs && t_subrefs->refers_to_string_element();
12629 }
12630 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
12631 Type *t_governor = v_last->my_governor->get_type_refd_last();
12632 switch (t_governor->get_typetype()) {
12633 case Type::T_NULL:
12634 case Type::T_BOOL:
12635 case Type::T_INT:
12636 case Type::T_INT_A:
12637 case Type::T_REAL:
12638 case Type::T_ENUM_A:
12639 case Type::T_ENUM_T:
12640 case Type::T_VERDICT:
12641 case Type::T_COMPONENT:
12642 // these are mapped to built-in C/C++ types
12643 return true;
12644 case Type::T_SEQ_A:
12645 case Type::T_SEQ_T:
12646 case Type::T_SET_A:
12647 case Type::T_SET_T:
12648 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12649 return t_governor->get_nof_comps() == 0;
12650 case Type::T_SEQOF:
12651 case Type::T_SETOF:
12652 // the C++ equivalent of value {} is ambiguous
12653 // tr926
12654 return true;
12655 case Type::T_FUNCTION:
12656 case Type::T_ALTSTEP:
12657 case Type::T_TESTCASE:
12658 return true;
12659 default:
12660 return false;
12661 }
12662 }
12663
12664 bool Value::has_single_expr()
12665 {
12666 if (get_needs_conversion()) return false;
12667 switch (valuetype) {
12668 case V_EXPR:
12669 return has_single_expr_expr();
12670 case V_CHOICE:
12671 case V_ARRAY:
12672 // a union or array value cannot be represented as an in-line expression
12673 return false;
12674 case V_SEQOF:
12675 case V_SETOF:
12676 // only an empty record/set of value can be represented as an in-line
12677 // expression
12678 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
12679 else return u.val_vs->get_nof_ivs() == 0;
12680 case V_SEQ:
12681 case V_SET: {
12682 // only a value for an empty record/set type can be represented as an
12683 // in-line expression
12684 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
12685 Type *type = my_governor->get_type_refd_last();
12686 return type->get_nof_comps() == 0; }
12687 case V_REFD: {
12688 Value *v_last = get_value_refd_last();
12689 // If the above call hit an error and set_valuetype(V_ERROR),
12690 // then u.ref.ref has been freed. Avoid the segfault.
12691 if (valuetype == V_ERROR)
12692 return false;
12693 if (v_last != this && v_last->has_single_expr() &&
12694 v_last->my_scope->get_scope_mod_gen() ==
12695 my_scope->get_scope_mod_gen()) return true;
12696 else return u.ref.ref->has_single_expr(); }
12697 case V_INVOKE:
12698 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
12699 case V_ERROR:
12700 case V_NAMEDINT:
12701 case V_NAMEDBITS:
12702 case V_UNDEF_LOWERID:
12703 case V_UNDEF_BLOCK:
12704 case V_REFER:
12705 // these values cannot occur during code generation
12706 FATAL_ERROR("Value::has_single_expr()");
12707 case V_INT:
12708 return u.val_Int->is_native_fit();
12709 default:
12710 // other value types (literal values) do not need temporary reference
12711 return true;
12712 }
12713 }
12714
12715 string Value::get_single_expr()
12716 {
12717 switch (valuetype) {
12718 case V_NULL:
12719 return string("ASN_NULL_VALUE");
12720 case V_BOOL:
12721 return string(u.val_bool ? "TRUE" : "FALSE");
12722 case V_INT:
12723 if (u.val_Int->is_native_fit()) { // Be sure.
12724 return u.val_Int->t_str();
12725 } else {
12726 // get_single_expr may be called only if has_single_expr() is true.
12727 // The only exception is V_INT, where get_single_expr may be called
12728 // even if is_native_fit (which is used to implement has_single_expr)
12729 // returns false.
12730 string ret_val('"');
12731 ret_val += u.val_Int->t_str();
12732 ret_val += '"';
12733 return ret_val;
12734 }
12735 case V_REAL:
12736 return Real2code(u.val_Real);
12737 case V_ENUM:
12738 return get_single_expr_enum();
12739 case V_BSTR:
12740 return get_my_scope()->get_scope_mod_gen()
12741 ->add_bitstring_literal(*u.str.val_str);
12742 case V_HSTR:
12743 return get_my_scope()->get_scope_mod_gen()
12744 ->add_hexstring_literal(*u.str.val_str);
12745 case V_OSTR:
12746 return get_my_scope()->get_scope_mod_gen()
12747 ->add_octetstring_literal(*u.str.val_str);
12748 case V_CSTR:
12749 return get_my_scope()->get_scope_mod_gen()
12750 ->add_charstring_literal(*u.str.val_str);
12751 case V_USTR:
12752 if (u.ustr.convert_str) {
12753 set_valuetype(V_CSTR);
12754 return get_my_scope()->get_scope_mod_gen()
12755 ->add_charstring_literal(*u.str.val_str);
12756 } else
12757 return get_my_scope()->get_scope_mod_gen()
12758 ->add_ustring_literal(*u.ustr.val_ustr);
12759 case V_ISO2022STR:
12760 return get_single_expr_iso2022str();
12761 case V_OID:
12762 case V_ROID: {
12763 vector<string> comps;
12764 bool is_constant = get_oid_comps(comps);
12765 size_t nof_comps = comps.size();
12766 string oi_str;
12767 for (size_t i = 0; i < nof_comps; i++) {
12768 if (i > 0) oi_str += ", ";
12769 oi_str += *(comps[i]);
12770 }
12771 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
12772 comps.clear();
12773 if (is_constant) {
12774 // the objid only contains constants
12775 // => create a literal and return its name
12776 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
12777 }
12778 // the objid contains at least one variable
12779 // => append the number of components before the component values in the string and return it
12780 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
12781 case V_SEQOF:
12782 case V_SETOF:
12783 if (u.val_vs->get_nof_vs() > 0)
12784 FATAL_ERROR("Value::get_single_expr()");
12785 return string("NULL_VALUE");
12786 case V_SEQ:
12787 case V_SET:
12788 if (u.val_nvs->get_nof_nvs() > 0)
12789 FATAL_ERROR("Value::get_single_expr()");
12790 return string("NULL_VALUE");
12791 case V_REFD: {
12792 Value *v_last = get_value_refd_last();
12793 if (v_last != this && v_last->has_single_expr() &&
12794 v_last->my_scope->get_scope_mod_gen() ==
12795 my_scope->get_scope_mod_gen()) {
12796 // the reference points to another single value in the same module
12797 return v_last->get_single_expr();
12798 } else {
12799 // convert the reference to a single expression
12800 expression_struct expr;
12801 Code::init_expr(&expr);
12802 u.ref.ref->generate_code_const_ref(&expr);
12803 if (expr.preamble || expr.postamble)
12804 FATAL_ERROR("Value::get_single_expr()");
12805 string ret_val(expr.expr);
12806 Code::free_expr(&expr);
12807 return ret_val;
12808 } }
12809 case V_OMIT:
12810 return string("OMIT_VALUE");
12811 case V_VERDICT:
12812 switch (u.verdict) {
12813 case Verdict_NONE:
12814 return string("NONE");
12815 case Verdict_PASS:
12816 return string("PASS");
12817 case Verdict_INCONC:
12818 return string("INCONC");
12819 case Verdict_FAIL:
12820 return string("FAIL");
12821 case Verdict_ERROR:
12822 return string("ERROR");
12823 default:
12824 FATAL_ERROR("Value::get_single_expr()");
12825 return string();
12826 }
12827 case V_DEFAULT_NULL:
12828 return string("NULL_COMPREF");
12829 case V_FAT_NULL: {
12830 string ret_val('(');
12831 ret_val += my_governor->get_genname_value(my_scope);
12832 ret_val += "::function_pointer)Module_List::get_fat_null()";
12833 return ret_val; }
12834 case V_EXPR:
12835 case V_INVOKE: {
12836 expression_struct expr;
12837 Code::init_expr(&expr);
12838 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
12839 else generate_code_expr_invoke(&expr);
12840 if (expr.preamble || expr.postamble)
12841 FATAL_ERROR("Value::get_single_expr()");
12842 string ret_val(expr.expr);
12843 Code::free_expr(&expr);
12844 return ret_val; }
12845 case V_MACRO:
12846 switch (u.macro) {
12847 case MACRO_TESTCASEID:
12848 return string("TTCN_Runtime::get_testcase_id_macro()");
12849 default:
12850 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
12851 return string();
12852 }
12853 case V_FUNCTION:
12854 case V_ALTSTEP:
12855 case V_TESTCASE:
12856 return get_single_expr_fat();
12857 default:
12858 FATAL_ERROR("Value::get_single_expr()");
12859 return string();
12860 }
12861 }
12862
12863 bool Value::has_single_expr_expr()
12864 {
12865 switch (u.expr.v_optype) {
12866 case OPTYPE_RND: // -
12867 case OPTYPE_COMP_NULL:
12868 case OPTYPE_COMP_MTC:
12869 case OPTYPE_COMP_SYSTEM:
12870 case OPTYPE_COMP_SELF:
12871 case OPTYPE_COMP_RUNNING_ANY:
12872 case OPTYPE_COMP_RUNNING_ALL:
12873 case OPTYPE_COMP_ALIVE_ANY:
12874 case OPTYPE_COMP_ALIVE_ALL:
12875 case OPTYPE_TMR_RUNNING_ANY:
12876 case OPTYPE_GETVERDICT:
12877 case OPTYPE_TESTCASENAME:
12878 case OPTYPE_PROF_RUNNING:
12879 return true;
12880 case OPTYPE_ENCODE:
12881 case OPTYPE_DECODE:
12882 case OPTYPE_ISBOUND:
12883 case OPTYPE_ISPRESENT:
12884 case OPTYPE_TTCN2STRING:
12885 return false;
12886 case OPTYPE_UNARYPLUS: // v1
12887 case OPTYPE_UNARYMINUS:
12888 case OPTYPE_NOT:
12889 case OPTYPE_NOT4B:
12890 case OPTYPE_BIT2HEX:
12891 case OPTYPE_BIT2INT:
12892 case OPTYPE_BIT2OCT:
12893 case OPTYPE_BIT2STR:
12894 case OPTYPE_CHAR2INT:
12895 case OPTYPE_CHAR2OCT:
12896 case OPTYPE_FLOAT2INT:
12897 case OPTYPE_FLOAT2STR:
12898 case OPTYPE_HEX2BIT:
12899 case OPTYPE_HEX2INT:
12900 case OPTYPE_HEX2OCT:
12901 case OPTYPE_HEX2STR:
12902 case OPTYPE_INT2CHAR:
12903 case OPTYPE_INT2FLOAT:
12904 case OPTYPE_INT2STR:
12905 case OPTYPE_INT2UNICHAR:
12906 case OPTYPE_OCT2BIT:
12907 case OPTYPE_OCT2CHAR:
12908 case OPTYPE_OCT2HEX:
12909 case OPTYPE_OCT2INT:
12910 case OPTYPE_OCT2STR:
12911 case OPTYPE_STR2BIT:
12912 case OPTYPE_STR2FLOAT:
12913 case OPTYPE_STR2HEX:
12914 case OPTYPE_STR2INT:
12915 case OPTYPE_STR2OCT:
12916 case OPTYPE_UNICHAR2INT:
12917 case OPTYPE_UNICHAR2CHAR:
12918 case OPTYPE_ENUM2INT:
12919 case OPTYPE_RNDWITHVAL:
12920 case OPTYPE_ISCHOSEN_V: // v1 i2
12921 case OPTYPE_COMP_RUNNING:
12922 case OPTYPE_COMP_ALIVE:
12923 case OPTYPE_GET_STRINGENCODING:
12924 case OPTYPE_REMOVE_BOM:
12925 case OPTYPE_DECODE_BASE64:
12926 return u.expr.v1->has_single_expr();
12927 case OPTYPE_ISCHOSEN_T: // t1 i2
12928 return u.expr.t1->has_single_expr();
12929 case OPTYPE_ADD: // v1 v2
12930 case OPTYPE_SUBTRACT:
12931 case OPTYPE_MULTIPLY:
12932 case OPTYPE_DIVIDE:
12933 case OPTYPE_MOD:
12934 case OPTYPE_REM:
12935 case OPTYPE_CONCAT:
12936 case OPTYPE_EQ:
12937 case OPTYPE_LT:
12938 case OPTYPE_GT:
12939 case OPTYPE_NE:
12940 case OPTYPE_GE:
12941 case OPTYPE_LE:
12942 case OPTYPE_XOR:
12943 case OPTYPE_AND4B:
12944 case OPTYPE_OR4B:
12945 case OPTYPE_XOR4B:
12946 case OPTYPE_SHL:
12947 case OPTYPE_SHR:
12948 case OPTYPE_ROTL:
12949 case OPTYPE_ROTR:
12950 case OPTYPE_INT2BIT:
12951 case OPTYPE_INT2HEX:
12952 case OPTYPE_INT2OCT:
12953 return u.expr.v1->has_single_expr() &&
12954 u.expr.v2->has_single_expr();
12955 case OPTYPE_UNICHAR2OCT:
12956 case OPTYPE_OCT2UNICHAR:
12957 case OPTYPE_ENCODE_BASE64:
12958 return u.expr.v1->has_single_expr() &&
12959 (!u.expr.v2 || u.expr.v2->has_single_expr());
12960 case OPTYPE_AND:
12961 case OPTYPE_OR:
12962 return u.expr.v1->has_single_expr() &&
12963 u.expr.v2->has_single_expr() &&
12964 !u.expr.v2->needs_short_circuit();
12965 case OPTYPE_SUBSTR:
12966 return u.expr.ti1->has_single_expr() &&
12967 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
12968 case OPTYPE_REGEXP:
12969 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
12970 u.expr.v3->has_single_expr();
12971 case OPTYPE_DECOMP: // v1 v2 v3
12972 return u.expr.v1->has_single_expr() &&
12973 u.expr.v2->has_single_expr() &&
12974 u.expr.v3->has_single_expr();
12975 case OPTYPE_REPLACE:
12976 return u.expr.ti1->has_single_expr() &&
12977 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
12978 u.expr.ti4->has_single_expr();
12979 case OPTYPE_ISVALUE: // ti1
12980 case OPTYPE_LENGTHOF: // ti1
12981 case OPTYPE_SIZEOF: // ti1
12982 case OPTYPE_VALUEOF: // ti1
12983 return u.expr.ti1->has_single_expr();
12984 case OPTYPE_LOG2STR:
12985 return u.expr.logargs->has_single_expr();
12986 case OPTYPE_MATCH: // v1 t2
12987 return u.expr.v1->has_single_expr() &&
12988 u.expr.t2->has_single_expr();
12989 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
12990 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
12991 (!u.expr.v3 || u.expr.v3->has_single_expr());
12992 case OPTYPE_TMR_READ: // r1
12993 case OPTYPE_TMR_RUNNING:
12994 case OPTYPE_ACTIVATE:
12995 return u.expr.r1->has_single_expr();
12996 case OPTYPE_EXECUTE: // r1 [v2]
12997 return u.expr.r1->has_single_expr() &&
12998 (!u.expr.v2 || u.expr.v2->has_single_expr());
12999 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13000 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13001 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13002 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13003 (!u.expr.v3 || u.expr.v3->has_single_expr());
13004 default:
13005 FATAL_ERROR("Value::has_single_expr_expr()");
13006 } // switch
13007 }
13008
13009 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13010 {
13011 if (!v->has_single_expr()) return false;
13012 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13013 if (!ap_list->get_par(i)->has_single_expr()) return false;
13014 return true;
13015 }
13016
13017 string Value::get_single_expr_enum()
13018 {
13019 string ret_val(my_governor->get_genname_value(my_scope));
13020 ret_val += "::";
13021 ret_val += u.val_id->get_name();
13022 return ret_val;
13023 }
13024
13025 string Value::get_single_expr_iso2022str()
13026 {
13027 string ret_val;
13028 Type *type = get_my_governor()->get_type_refd_last();
13029 switch (type->get_typetype()) {
13030 case Type::T_TELETEXSTRING:
13031 ret_val += "TTCN_ISO2022_2_TeletexString";
13032 break;
13033 case Type::T_VIDEOTEXSTRING:
13034 ret_val += "TTCN_ISO2022_2_VideotexString";
13035 break;
13036 case Type::T_GRAPHICSTRING:
13037 case Type::T_OBJECTDESCRIPTOR:
13038 ret_val += "TTCN_ISO2022_2_GraphicString";
13039 break;
13040 case Type::T_GENERALSTRING:
13041 ret_val += "TTCN_ISO2022_2_GeneralString";
13042 break;
13043 default:
13044 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13045 } // switch
13046 ret_val += '(';
13047 string *ostr = char2oct(*u.str.val_str);
13048 ret_val += get_my_scope()->get_scope_mod_gen()
13049 ->add_octetstring_literal(*ostr);
13050 delete ostr;
13051 ret_val += ')';
13052 return ret_val;
13053 }
13054
13055 string Value::get_single_expr_fat()
13056 {
13057 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13058 // the ampersand operator is not really necessary to obtain the function
13059 // pointer, but some older versions of GCC cannot instantiate the
13060 // appropriate operator=() member of class OPTIONAL when necessary
13061 // if only the function name is given
13062 string ret_val('&');
13063 switch (valuetype) {
13064 case V_FUNCTION:
13065 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13066 break;
13067 case V_ALTSTEP:
13068 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13069 ret_val += "_instance";
13070 break;
13071 case V_TESTCASE:
13072 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13073 break;
13074 default:
13075 FATAL_ERROR("Value::get_single_expr_fat()");
13076 }
13077 return ret_val;
13078 }
13079
13080 bool Value::is_compound()
13081 {
13082 switch (valuetype) {
13083 case V_CHOICE:
13084 case V_SEQOF:
13085 case V_SETOF:
13086 case V_ARRAY:
13087 case V_SEQ:
13088 case V_SET:
13089 return true;
13090 default:
13091 return false;
13092 }
13093 }
13094
13095 bool Value::needs_temp_ref()
13096 {
13097 switch (valuetype) {
13098 case V_SEQOF:
13099 case V_SETOF:
13100 if (!is_indexed()) {
13101 // Temporary reference is needed if the value has at least one real
13102 // element (i.e. it is not empty or contains only not used symbols).
13103 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13104 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13105 }
13106 } else {
13107 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13108 if (u.val_vs->get_iv_byIndex(i)->get_value()
13109 ->valuetype != V_NOTUSED)
13110 return true;
13111 }
13112 }
13113 return false;
13114 case V_ARRAY: {
13115 size_t nof_real_vs = 0;
13116 if (!is_indexed()) {
13117 // Temporary reference is needed if the array value has at least two
13118 // real elements (excluding not used symbols).
13119 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13120 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13121 nof_real_vs++;
13122 if (nof_real_vs > 1) return true;
13123 }
13124 }
13125 } else {
13126 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13127 if (u.val_vs->get_iv_byIndex(i)->get_value()
13128 ->valuetype != V_NOTUSED) {
13129 nof_real_vs++;
13130 if (nof_real_vs > 1) return true;
13131 }
13132 }
13133 }
13134 return false; }
13135 case V_SEQ:
13136 case V_SET:
13137 if (is_asn1()) {
13138 // it depends on the type since fields with omit or default value
13139 // may not be present
13140 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13141 } else {
13142 // incomplete values are allowed in TTCN-3
13143 // we should check the number of value components
13144 return u.val_nvs->get_nof_nvs() > 1;
13145 }
13146 case V_ERROR:
13147 case V_NAMEDINT:
13148 case V_NAMEDBITS:
13149 case V_UNDEF_LOWERID:
13150 case V_UNDEF_BLOCK:
13151 case V_TTCN3_NULL:
13152 // these values cannot occur during code generation
13153 FATAL_ERROR("Value::needs_temp_ref()");
13154 case V_INT:
13155 return !u.val_Int->is_native();
13156 default:
13157 // other value types (literal values) do not need temporary reference
13158 return false;
13159 }
13160 }
13161
13162 bool Value::needs_short_circuit()
13163 {
13164 switch (valuetype) {
13165 case V_BOOL:
13166 return false;
13167 case V_REFD:
13168 // examined below
13169 break;
13170 case V_EXPR:
13171 case V_INVOKE:
13172 // sub-expressions should be evaluated only if necessary
13173 return true;
13174 default:
13175 FATAL_ERROR("Value::needs_short_circuit()");
13176 }
13177 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13178 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13179 switch (t_ass->get_asstype()) {
13180 case Assignment::A_FUNCTION_RVAL:
13181 case Assignment::A_EXT_FUNCTION_RVAL:
13182 // avoid unnecessary call of a function
13183 return true;
13184 case Assignment::A_CONST:
13185 case Assignment::A_EXT_CONST:
13186 case Assignment::A_MODULEPAR:
13187 case Assignment::A_VAR:
13188 case Assignment::A_PAR_VAL_IN:
13189 case Assignment::A_PAR_VAL_OUT:
13190 case Assignment::A_PAR_VAL_INOUT:
13191 // depends on field/array sub-references, which is examined below
13192 break;
13193 default:
13194 FATAL_ERROR("Value::needs_short_circuit()");
13195 }
13196 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13197 if (t_subrefs) {
13198 // the evaluation of the reference does not have side effects
13199 // (i.e. false shall be returned) only if all sub-references point to
13200 // mandatory fields of record/set types, and neither sub-reference points
13201 // to a field of a union type
13202 Type *t_type = t_ass->get_Type();
13203 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13204 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13205 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13206 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13207 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13208 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13209 t_cf->get_is_optional()) return true;
13210 t_type = t_cf->get_type();
13211 } else return true;
13212 }
13213 }
13214 return false;
13215 }
13216
13217 void Value::dump(unsigned level) const
13218 {
13219 switch (valuetype) {
13220 case V_ERROR:
13221 case V_NULL:
13222 case V_BOOL:
13223 case V_INT:
13224 case V_NAMEDINT:
13225 case V_NAMEDBITS:
13226 case V_REAL:
13227 case V_ENUM:
13228 case V_BSTR:
13229 case V_HSTR:
13230 case V_OSTR:
13231 case V_CSTR:
13232 case V_ISO2022STR:
13233 case V_OID:
13234 case V_ROID:
13235 case V_CHOICE:
13236 case V_SEQOF:
13237 case V_SETOF:
13238 case V_ARRAY:
13239 case V_SEQ:
13240 case V_SET:
13241 case V_OMIT:
13242 case V_VERDICT:
13243 case V_DEFAULT_NULL:
13244 case V_FAT_NULL:
13245 case V_EXPR:
13246 case V_MACRO:
13247 case V_NOTUSED:
13248 case V_FUNCTION:
13249 case V_ALTSTEP:
13250 case V_TESTCASE:
13251 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13252 break;
13253 case V_REFD:
13254 case V_REFER:
13255 DEBUG(level, "Value: reference");
13256 u.ref.ref->dump(level + 1);
13257 break;
13258 case V_UNDEF_LOWERID:
13259 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13260 break;
13261 case V_UNDEF_BLOCK:
13262 DEBUG(level, "Value: {block}");
13263 break;
13264 case V_TTCN3_NULL:
13265 DEBUG(level, "Value: null");
13266 break;
13267 case V_INVOKE:
13268 DEBUG(level, "Value: invoke");
13269 u.invoke.v->dump(level + 1);
13270 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13271 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13272 break;
13273 default:
13274 DEBUG(level, "Value: unknown type: %d", valuetype);
13275 } // switch
13276 }
13277
13278 void Value::add_string_element(size_t index, Value *v_element,
13279 map<size_t, Value>*& string_elements)
13280 {
13281 v_element->set_my_scope(get_my_scope());
13282 v_element->set_my_governor(get_my_governor());
13283 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13284 v_element->set_location(*this);
13285 if (!string_elements) string_elements = new map<size_t, Value>;
13286 string_elements->add(index, v_element);
13287 }
13288
13289 ///////////////////////////////////////////////////////////////////////////////
13290 // class LazyParamData
13291
13292 int LazyParamData::depth = 0;
13293 bool LazyParamData::used_as_lvalue = false;
13294 vector<string>* LazyParamData::type_vec = NULL;
13295 vector<string>* LazyParamData::refd_vec = NULL;
13296
13297 void LazyParamData::init(bool p_used_as_lvalue) {
13298 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13299 if (depth==0) {
13300 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13301 used_as_lvalue = p_used_as_lvalue;
13302 type_vec = new vector<string>;
13303 refd_vec = new vector<string>;
13304 }
13305 depth++;
13306 }
13307
13308 void LazyParamData::clean() {
13309 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13310 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13311 if (depth==1) {
13312 // type_vec
13313 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13314 type_vec->clear();
13315 delete type_vec;
13316 type_vec = NULL;
13317 // refd_vec
13318 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13319 refd_vec->clear();
13320 delete refd_vec;
13321 refd_vec = NULL;
13322 }
13323 depth--;
13324 }
13325
13326 bool LazyParamData::in_lazy() {
13327 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13328 return depth>0;
13329 }
13330
13331 // returns a temporary id instead of the C++ reference to a definition
13332 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13333 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13334 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13335 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13336 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13337 // store the type of the assignment
13338 string* type_str = new string;
13339 switch (ass->get_asstype()) {
13340 case Assignment::A_MODULEPAR_TEMP:
13341 case Assignment::A_TEMPLATE:
13342 case Assignment::A_VAR_TEMPLATE:
13343 case Assignment::A_PAR_TEMPL_IN:
13344 case Assignment::A_PAR_TEMPL_OUT:
13345 case Assignment::A_PAR_TEMPL_INOUT:
13346 *type_str = ass->get_Type()->get_genname_template(scope);
13347 break;
13348 default:
13349 *type_str = ass->get_Type()->get_genname_value(scope);
13350 }
13351 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13352 bool refd_ass_is_lazy_fpar = false;
13353 switch (ass->get_asstype()) {
13354 case Assignment::A_PAR_VAL:
13355 case Assignment::A_PAR_VAL_IN:
13356 case Assignment::A_PAR_TEMPL_IN:
13357 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13358 if (refd_ass_is_lazy_fpar) {
13359 *type_str = string("Lazy_Param<") + *type_str + string(">");
13360 }
13361 break;
13362 default:
13363 break;
13364 }
13365 // add the "const" part if the referenced assignment is a constant thing
13366 if (!refd_ass_is_lazy_fpar) {
13367 switch (ass->get_asstype()) {
13368 case Assignment::A_CONST:
13369 case Assignment::A_OC:
13370 case Assignment::A_OBJECT:
13371 case Assignment::A_OS:
13372 case Assignment::A_VS:
13373 case Assignment::A_EXT_CONST:
13374 case Assignment::A_MODULEPAR:
13375 case Assignment::A_MODULEPAR_TEMP:
13376 case Assignment::A_TEMPLATE:
13377 case Assignment::A_PAR_VAL:
13378 case Assignment::A_PAR_VAL_IN:
13379 case Assignment::A_PAR_TEMPL_IN:
13380 *type_str = string("const ") + *type_str;
13381 break;
13382 default:
13383 // nothing to do
13384 break;
13385 }
13386 }
13387 //
13388 type_vec->add(type_str);
13389 // store the C++ reference string
13390 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
13391 if (refd_ass_is_lazy_fpar) {
13392 Type* refd_ass_type = ass->get_Type();
13393 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);
13394 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13395 } else {
13396 return get_member_name(refd_vec->size()-1);
13397 }
13398 }
13399
13400 string LazyParamData::get_member_name(size_t idx) {
13401 return string("lpm_") + Int2string(idx);
13402 }
13403
13404 string LazyParamData::get_constr_param_name(size_t idx) {
13405 return string("lpp_") + Int2string(idx);
13406 }
13407
13408 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
13409 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13410 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
13411 const string& tmp_id = val->get_temporary_id();
13412 const char *tmp_id_str = tmp_id.c_str();
13413 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13414 val->get_my_governor()->get_genname_value(my_scope).c_str(),
13415 tmp_id_str);
13416 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13417 tmp_id_str, val);
13418 expr->expr = mputstr(expr->expr, tmp_id_str);
13419 } else {
13420 val->generate_code_expr(expr);
13421 }
13422 }
13423
13424 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
13425 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13426 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
13427 const string& tmp_id = temp->get_Template()->get_temporary_id();
13428 const char *tmp_id_str = tmp_id.c_str();
13429 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13430 temp->get_Template()->get_my_governor()
13431 ->get_genname_template(my_scope).c_str(), tmp_id_str);
13432 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13433 tmp_id_str, temp->get_Template());
13434 // Not incorporated into gen_conv_code() yet.
13435 if (gen_restriction_check != TR_NONE)
13436 expr->preamble = Template::generate_restriction_check_code(
13437 expr->preamble, tmp_id_str, gen_restriction_check);
13438 expr->expr = mputstr(expr->expr, tmp_id_str);
13439 } else temp->generate_code(expr, gen_restriction_check);
13440 }
13441
13442 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
13443 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13444 if (depth>1) {
13445 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13446 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13447 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13448 expression_struct value_expr;
13449 Code::init_expr(&value_expr);
13450 generate_code_for_value(&value_expr, value, scope);
13451 // the id of the instance of Lazy_Param which will be used as the actual parameter
13452 const string& lazy_param_id = value->get_temporary_id();
13453 if (value_expr.preamble) {
13454 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
13455 }
13456 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13457 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13458 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
13459 Code::free_expr(&value_expr);
13460 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13461 return;
13462 }
13463 // only if the formal parameter is *not* used as lvalue
13464 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
13465 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
13466 if (refd_ass) {
13467 bool refd_ass_is_lazy_fpar = false;
13468 switch (refd_ass->get_asstype()) {
13469 case Assignment::A_PAR_VAL:
13470 case Assignment::A_PAR_VAL_IN:
13471 case Assignment::A_PAR_TEMPL_IN:
13472 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13473 break;
13474 default:
13475 break;
13476 }
13477 if (refd_ass_is_lazy_fpar) {
13478 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13479 return;
13480 }
13481 }
13482 }
13483 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13484 expression_struct value_expr;
13485 Code::init_expr(&value_expr);
13486 generate_code_for_value(&value_expr, value, scope);
13487 // the id of the instance of Lazy_Param which will be used as the actual parameter
13488 string lazy_param_id = value->get_temporary_id();
13489 string type_name = value->get_my_governor()->get_genname_value(scope);
13490 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
13491 }
13492
13493 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
13494 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13495 if (depth>1) {
13496 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13497 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13498 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13499 expression_struct tmpl_expr;
13500 Code::init_expr(&tmpl_expr);
13501 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13502 // the id of the instance of Lazy_Param which will be used as the actual parameter
13503 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
13504 if (tmpl_expr.preamble) {
13505 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
13506 }
13507 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13508 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13509 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
13510 Code::free_expr(&tmpl_expr);
13511 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13512 return;
13513 }
13514 // only if the formal parameter is *not* used as lvalue
13515 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
13516 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
13517 if (refd_ass) {
13518 bool refd_ass_is_lazy_fpar = false;
13519 switch (refd_ass->get_asstype()) {
13520 case Assignment::A_PAR_VAL:
13521 case Assignment::A_PAR_VAL_IN:
13522 case Assignment::A_PAR_TEMPL_IN:
13523 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13524 break;
13525 default:
13526 break;
13527 }
13528 if (refd_ass_is_lazy_fpar) {
13529 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13530 return;
13531 }
13532 }
13533 }
13534 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13535 expression_struct tmpl_expr;
13536 Code::init_expr(&tmpl_expr);
13537 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13538 // the id of the instance of Lazy_Param which will be used as the actual parameter
13539 string lazy_param_id = temp->get_Template()->get_temporary_id();
13540 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
13541 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
13542 }
13543
13544 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
13545 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
13546 if (type_vec->size()>0) {
13547 // private members of the local class will be const references to the objects referenced by the expression
13548 for (size_t i=0; i<type_vec->size(); i++) {
13549 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
13550 }
13551 expr->preamble = mputstr(expr->preamble, "public:\n");
13552 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
13553 for (size_t i=0; i<type_vec->size(); i++) {
13554 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13555 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
13556 }
13557 expr->preamble = mputstr(expr->preamble, "): ");
13558 for (size_t i=0; i<type_vec->size(); i++) {
13559 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13560 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
13561 }
13562 expr->preamble = mputstr(expr->preamble, " {}\n");
13563 expr->preamble = mputstr(expr->preamble, "private:\n");
13564 }
13565 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
13566 // use the temporary expr structure to fill the body of the eval_expr() function
13567 if (param_expr.preamble) {
13568 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
13569 }
13570 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
13571 if (param_expr.postamble) {
13572 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
13573 }
13574 Code::free_expr(&param_expr);
13575 expr->preamble = mputstr(expr->preamble, "}\n"
13576 "};\n" // end of local class definition
13577 );
13578 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
13579 if (type_vec->size()>0) {
13580 expr->preamble = mputc(expr->preamble, '(');
13581 // paramteres of the constructor are references to the objects used in the expression
13582 for (size_t i=0; i<refd_vec->size(); i++) {
13583 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13584 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
13585 }
13586 expr->preamble = mputc(expr->preamble, ')');
13587 }
13588 expr->preamble = mputstr(expr->preamble, ";\n");
13589 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13590 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
13591 }
13592
13593 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
13594 expression_struct ref_expr;
13595 Code::init_expr(&ref_expr);
13596 ref->generate_code(&ref_expr);
13597 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
13598 if (ref_expr.preamble) {
13599 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
13600 }
13601 Assignment* ass = ref->get_refd_assignment();
13602 // determine C++ type of the assignment
13603 string type_str;
13604 switch (ass->get_asstype()) {
13605 case Assignment::A_MODULEPAR_TEMP:
13606 case Assignment::A_TEMPLATE:
13607 case Assignment::A_VAR_TEMPLATE:
13608 case Assignment::A_PAR_TEMPL_IN:
13609 case Assignment::A_PAR_TEMPL_OUT:
13610 case Assignment::A_PAR_TEMPL_INOUT:
13611 type_str = ass->get_Type()->get_genname_template(scope);
13612 break;
13613 default:
13614 type_str = ass->get_Type()->get_genname_value(scope);
13615 }
13616 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13617 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
13618 if (ref_expr.postamble) {
13619 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
13620 }
13621 Code::free_expr(&ref_expr);
13622 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13623 }
13624
13625 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
13626 const string& lazy_param_id = value->get_temporary_id();
13627 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13628 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13629 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
13630 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13631 }
13632
13633 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
13634 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
13635 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13636 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13637 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
13638 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13639 }
13640
13641 } // namespace Common
This page took 0.3164 seconds and 5 git commands to generate.