Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / Value.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 #include "../common/JSON_Tokenizer.hh"
34
35 #include <math.h>
36 #include <regex.h>
37 #include <limits.h>
38
39 namespace Common {
40
41 static void clean_up_string_elements(map<size_t, Value>*& string_elements)
42 {
43 if (string_elements) {
44 for (size_t i = 0; i < string_elements->size(); i++)
45 delete string_elements->get_nth_elem(i);
46 string_elements->clear();
47 delete string_elements;
48 string_elements = 0;
49 }
50 }
51
52 // =================================
53 // ===== Value
54 // =================================
55
56 Value::Value(const Value& p)
57 : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
58 {
59 switch(valuetype) {
60 case V_ERROR:
61 case V_NULL:
62 case V_OMIT:
63 case V_TTCN3_NULL:
64 case V_DEFAULT_NULL:
65 case V_FAT_NULL:
66 case V_NOTUSED:
67 break;
68 case V_BOOL:
69 u.val_bool=p.u.val_bool;
70 break;
71 case V_INT:
72 u.val_Int=new int_val_t(*(p.u.val_Int));
73 break;
74 case V_NAMEDINT:
75 case V_ENUM:
76 case V_UNDEF_LOWERID:
77 u.val_id=p.u.val_id->clone();
78 break;
79 case V_REAL:
80 u.val_Real=p.u.val_Real;
81 break;
82 case V_BSTR:
83 case V_HSTR:
84 case V_OSTR:
85 case V_CSTR:
86 case V_ISO2022STR:
87 set_val_str(new string(*p.u.str.val_str));
88 break;
89 case V_USTR:
90 set_val_ustr(new ustring(*p.u.ustr.val_ustr));
91 u.ustr.convert_str = p.u.ustr.convert_str;
92 break;
93 case V_CHARSYMS:
94 u.char_syms = p.u.char_syms->clone();
95 break;
96 case V_OID:
97 case V_ROID:
98 u.oid_comps=new vector<OID_comp>;
99 for(size_t i=0; i<p.u.oid_comps->size(); i++)
100 add_oid_comp((*p.u.oid_comps)[i]->clone());
101 break;
102 case V_CHOICE:
103 u.choice.alt_name=p.u.choice.alt_name->clone();
104 u.choice.alt_value=p.u.choice.alt_value->clone();
105 break;
106 case V_SEQOF:
107 case V_SETOF:
108 case V_ARRAY:
109 u.val_vs=p.u.val_vs->clone();
110 break;
111 case V_SEQ:
112 case V_SET:
113 u.val_nvs=p.u.val_nvs->clone();
114 break;
115 case V_REFD:
116 u.ref.ref=p.u.ref.ref->clone();
117 u.ref.refd_last=0;
118 break;
119 case V_NAMEDBITS:
120 for(size_t i=0; i<p.u.ids->size(); i++) {
121 Identifier *id = p.u.ids->get_nth_elem(i);
122 u.ids->add(id->get_name(), id->clone());
123 }
124 break;
125 case V_UNDEF_BLOCK:
126 u.block=p.u.block->clone();
127 break;
128 case V_VERDICT:
129 u.verdict=p.u.verdict;
130 break;
131 case V_EXPR:
132 u.expr.v_optype = p.u.expr.v_optype;
133 u.expr.state = EXPR_NOT_CHECKED;
134 switch(u.expr.v_optype) {
135 case OPTYPE_RND: // -
136 case OPTYPE_COMP_NULL:
137 case OPTYPE_COMP_MTC:
138 case OPTYPE_COMP_SYSTEM:
139 case OPTYPE_COMP_SELF:
140 case OPTYPE_COMP_RUNNING_ANY:
141 case OPTYPE_COMP_RUNNING_ALL:
142 case OPTYPE_COMP_ALIVE_ANY:
143 case OPTYPE_COMP_ALIVE_ALL:
144 case OPTYPE_TMR_RUNNING_ANY:
145 case OPTYPE_GETVERDICT:
146 case OPTYPE_TESTCASENAME:
147 case OPTYPE_PROF_RUNNING:
148 break;
149 case OPTYPE_UNARYPLUS: // v1
150 case OPTYPE_UNARYMINUS:
151 case OPTYPE_NOT:
152 case OPTYPE_NOT4B:
153 case OPTYPE_BIT2HEX:
154 case OPTYPE_BIT2INT:
155 case OPTYPE_BIT2OCT:
156 case OPTYPE_BIT2STR:
157 case OPTYPE_CHAR2INT:
158 case OPTYPE_CHAR2OCT:
159 case OPTYPE_COMP_RUNNING:
160 case OPTYPE_COMP_ALIVE:
161 case OPTYPE_FLOAT2INT:
162 case OPTYPE_FLOAT2STR:
163 case OPTYPE_HEX2BIT:
164 case OPTYPE_HEX2INT:
165 case OPTYPE_HEX2OCT:
166 case OPTYPE_HEX2STR:
167 case OPTYPE_INT2CHAR:
168 case OPTYPE_INT2FLOAT:
169 case OPTYPE_INT2STR:
170 case OPTYPE_INT2UNICHAR:
171 case OPTYPE_OCT2BIT:
172 case OPTYPE_OCT2CHAR:
173 case OPTYPE_OCT2HEX:
174 case OPTYPE_OCT2INT:
175 case OPTYPE_OCT2STR:
176 case OPTYPE_STR2BIT:
177 case OPTYPE_STR2FLOAT:
178 case OPTYPE_STR2HEX:
179 case OPTYPE_STR2INT:
180 case OPTYPE_STR2OCT:
181 case OPTYPE_UNICHAR2INT:
182 case OPTYPE_UNICHAR2CHAR:
183 case OPTYPE_ENUM2INT:
184 case OPTYPE_RNDWITHVAL:
185 case OPTYPE_GET_STRINGENCODING:
186 case OPTYPE_DECODE_BASE64:
187 case OPTYPE_REMOVE_BOM:
188 u.expr.v1=p.u.expr.v1->clone();
189 break;
190 case OPTYPE_ADD: // v1 v2
191 case OPTYPE_SUBTRACT:
192 case OPTYPE_MULTIPLY:
193 case OPTYPE_DIVIDE:
194 case OPTYPE_MOD:
195 case OPTYPE_REM:
196 case OPTYPE_CONCAT:
197 case OPTYPE_EQ:
198 case OPTYPE_LT:
199 case OPTYPE_GT:
200 case OPTYPE_NE:
201 case OPTYPE_GE:
202 case OPTYPE_LE:
203 case OPTYPE_AND:
204 case OPTYPE_OR:
205 case OPTYPE_XOR:
206 case OPTYPE_AND4B:
207 case OPTYPE_OR4B:
208 case OPTYPE_XOR4B:
209 case OPTYPE_SHL:
210 case OPTYPE_SHR:
211 case OPTYPE_ROTL:
212 case OPTYPE_ROTR:
213 case OPTYPE_INT2BIT:
214 case OPTYPE_INT2HEX:
215 case OPTYPE_INT2OCT:
216 u.expr.v1=p.u.expr.v1->clone();
217 u.expr.v2=p.u.expr.v2->clone();
218 break;
219 case OPTYPE_UNICHAR2OCT: // v1 [v2]
220 case OPTYPE_OCT2UNICHAR:
221 case OPTYPE_ENCODE_BASE64:
222 u.expr.v1=p.u.expr.v1->clone();
223 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
224 break;
225 case OPTYPE_DECODE:
226 u.expr.r1=p.u.expr.r1->clone();
227 u.expr.r2=p.u.expr.r2->clone();
228 break;
229 case OPTYPE_SUBSTR:
230 u.expr.ti1=p.u.expr.ti1->clone();
231 u.expr.v2=p.u.expr.v2->clone();
232 u.expr.v3=p.u.expr.v3->clone();
233 break;
234 case OPTYPE_REGEXP:
235 u.expr.ti1=p.u.expr.ti1->clone();
236 u.expr.t2=p.u.expr.t2->clone();
237 u.expr.v3=p.u.expr.v3->clone();
238 break;
239 case OPTYPE_DECOMP: // v1 v2 v3
240 u.expr.v1=p.u.expr.v1->clone();
241 u.expr.v2=p.u.expr.v2->clone();
242 u.expr.v3=p.u.expr.v3->clone();
243 break;
244 case OPTYPE_REPLACE:
245 u.expr.ti1 = p.u.expr.ti1->clone();
246 u.expr.v2 = p.u.expr.v2->clone();
247 u.expr.v3 = p.u.expr.v3->clone();
248 u.expr.ti4 = p.u.expr.ti4->clone();
249 break;
250 case OPTYPE_LENGTHOF: // ti1
251 case OPTYPE_SIZEOF: // ti1
252 case OPTYPE_VALUEOF: // ti1
253 case OPTYPE_ENCODE:
254 case OPTYPE_ISPRESENT:
255 case OPTYPE_TTCN2STRING:
256 u.expr.ti1=p.u.expr.ti1->clone();
257 break;
258 case OPTYPE_UNDEF_RUNNING:
259 case OPTYPE_TMR_READ:
260 case OPTYPE_TMR_RUNNING:
261 case OPTYPE_ACTIVATE:
262 u.expr.r1=p.u.expr.r1->clone();
263 break;
264 case OPTYPE_EXECUTE: // r1 [v2]
265 u.expr.r1=p.u.expr.r1->clone();
266 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
267 break;
268 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
269 u.expr.r1=p.u.expr.r1->clone();
270 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
271 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
272 u.expr.b4 = p.u.expr.b4;
273 break;
274 case OPTYPE_MATCH: // v1 t2
275 u.expr.v1=p.u.expr.v1->clone();
276 u.expr.t2=p.u.expr.t2->clone();
277 break;
278 case OPTYPE_ISCHOSEN: // r1 i2
279 u.expr.r1=p.u.expr.r1->clone();
280 u.expr.i2=p.u.expr.i2->clone();
281 break;
282 case OPTYPE_ISCHOSEN_V: // v1 i2
283 u.expr.v1=p.u.expr.v1->clone();
284 u.expr.i2=p.u.expr.i2->clone();
285 break;
286 case OPTYPE_ISCHOSEN_T: // t1 i2
287 u.expr.t1=p.u.expr.t1->clone();
288 u.expr.i2=p.u.expr.i2->clone();
289 break;
290 case OPTYPE_ACTIVATE_REFD:
291 u.expr.v1 = p.u.expr.v1->clone();
292 if(p.u.expr.state!=EXPR_CHECKED)
293 u.expr.t_list2 = p.u.expr.t_list2->clone();
294 else {
295 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
296 u.expr.state = EXPR_CHECKED;
297 }
298 break;
299 case OPTYPE_EXECUTE_REFD:
300 u.expr.v1 = p.u.expr.v1->clone();
301 if(p.u.expr.state!=EXPR_CHECKED)
302 u.expr.t_list2 = p.u.expr.t_list2->clone();
303 else {
304 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
305 u.expr.state = EXPR_CHECKED;
306 }
307 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
308 break;
309 case OPTYPE_LOG2STR:
310 u.expr.logargs = p.u.expr.logargs->clone();
311 break;
312 default:
313 FATAL_ERROR("Value::Value()");
314 } // switch
315 break;
316 case V_MACRO:
317 u.macro = p.u.macro;
318 break;
319 case V_FUNCTION:
320 case V_ALTSTEP:
321 case V_TESTCASE:
322 u.refd_fat = p.u.refd_fat;
323 break;
324 case V_INVOKE:
325 u.invoke.v = p.u.invoke.v->clone();
326 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
327 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
328 break;
329 case V_REFER:
330 u.refered = p.u.refered->clone();
331 break;
332 default:
333 FATAL_ERROR("Value::Value()");
334 } // switch
335 }
336
337 void Value::clean_up()
338 {
339 switch (valuetype) {
340 case V_ERROR:
341 case V_NULL:
342 case V_BOOL:
343 case V_REAL:
344 case V_OMIT:
345 case V_VERDICT:
346 case V_TTCN3_NULL:
347 case V_DEFAULT_NULL:
348 case V_FAT_NULL:
349 case V_MACRO:
350 case V_NOTUSED:
351 case V_FUNCTION:
352 case V_ALTSTEP:
353 case V_TESTCASE:
354 break;
355 case V_INT:
356 delete u.val_Int;
357 break;
358 case V_NAMEDINT:
359 case V_ENUM:
360 case V_UNDEF_LOWERID:
361 delete u.val_id;
362 break;
363 case V_BSTR:
364 case V_HSTR:
365 case V_OSTR:
366 case V_CSTR:
367 case V_ISO2022STR:
368 delete u.str.val_str;
369 clean_up_string_elements(u.str.str_elements);
370 break;
371 case V_USTR:
372 delete u.ustr.val_ustr;
373 clean_up_string_elements(u.ustr.ustr_elements);
374 break;
375 case V_CHARSYMS:
376 delete u.char_syms;
377 break;
378 case V_OID:
379 case V_ROID:
380 if (u.oid_comps) {
381 for(size_t i=0; i<u.oid_comps->size(); i++)
382 delete (*u.oid_comps)[i];
383 u.oid_comps->clear();
384 delete u.oid_comps;
385 }
386 break;
387 case V_EXPR:
388 clean_up_expr();
389 break;
390 case V_CHOICE:
391 delete u.choice.alt_name;
392 delete u.choice.alt_value;
393 break;
394 case V_SEQOF:
395 case V_SETOF:
396 case V_ARRAY:
397 delete u.val_vs;
398 break;
399 case V_SEQ:
400 case V_SET:
401 delete u.val_nvs;
402 break;
403 case V_REFD:
404 delete u.ref.ref;
405 break;
406 case V_REFER:
407 delete u.refered;
408 break;
409 case V_INVOKE:
410 delete u.invoke.v;
411 delete u.invoke.t_list;
412 delete u.invoke.ap_list;
413 break;
414 case V_NAMEDBITS:
415 if(u.ids) {
416 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
417 u.ids->clear();
418 delete u.ids;
419 }
420 break;
421 case V_UNDEF_BLOCK:
422 delete u.block;
423 break;
424 default:
425 FATAL_ERROR("Value::clean_up()");
426 } // switch
427 }
428
429 void Value::clean_up_expr()
430 {
431 switch (u.expr.state) {
432 case EXPR_CHECKING:
433 case EXPR_CHECKING_ERR:
434 FATAL_ERROR("Value::clean_up_expr()");
435 default:
436 break;
437 }
438 switch (u.expr.v_optype) {
439 case OPTYPE_RND: // -
440 case OPTYPE_COMP_NULL:
441 case OPTYPE_COMP_MTC:
442 case OPTYPE_COMP_SYSTEM:
443 case OPTYPE_COMP_SELF:
444 case OPTYPE_COMP_RUNNING_ANY:
445 case OPTYPE_COMP_RUNNING_ALL:
446 case OPTYPE_COMP_ALIVE_ANY:
447 case OPTYPE_COMP_ALIVE_ALL:
448 case OPTYPE_TMR_RUNNING_ANY:
449 case OPTYPE_GETVERDICT:
450 case OPTYPE_TESTCASENAME:
451 case OPTYPE_PROF_RUNNING:
452 break;
453 case OPTYPE_UNARYPLUS: // v1
454 case OPTYPE_UNARYMINUS:
455 case OPTYPE_NOT:
456 case OPTYPE_NOT4B:
457 case OPTYPE_BIT2HEX:
458 case OPTYPE_BIT2INT:
459 case OPTYPE_BIT2OCT:
460 case OPTYPE_BIT2STR:
461 case OPTYPE_CHAR2INT:
462 case OPTYPE_CHAR2OCT:
463 case OPTYPE_COMP_RUNNING:
464 case OPTYPE_COMP_ALIVE:
465 case OPTYPE_FLOAT2INT:
466 case OPTYPE_FLOAT2STR:
467 case OPTYPE_HEX2BIT:
468 case OPTYPE_HEX2INT:
469 case OPTYPE_HEX2OCT:
470 case OPTYPE_HEX2STR:
471 case OPTYPE_INT2CHAR:
472 case OPTYPE_INT2FLOAT:
473 case OPTYPE_INT2STR:
474 case OPTYPE_INT2UNICHAR:
475 case OPTYPE_OCT2BIT:
476 case OPTYPE_OCT2CHAR:
477 case OPTYPE_OCT2HEX:
478 case OPTYPE_OCT2INT:
479 case OPTYPE_OCT2STR:
480 case OPTYPE_STR2BIT:
481 case OPTYPE_STR2FLOAT:
482 case OPTYPE_STR2HEX:
483 case OPTYPE_STR2INT:
484 case OPTYPE_STR2OCT:
485 case OPTYPE_UNICHAR2INT:
486 case OPTYPE_UNICHAR2CHAR:
487 case OPTYPE_ENUM2INT:
488 case OPTYPE_RNDWITHVAL:
489 case OPTYPE_REMOVE_BOM:
490 case OPTYPE_GET_STRINGENCODING:
491 case OPTYPE_DECODE_BASE64:
492 delete u.expr.v1;
493 break;
494 case OPTYPE_ADD: // v1 v2
495 case OPTYPE_SUBTRACT:
496 case OPTYPE_MULTIPLY:
497 case OPTYPE_DIVIDE:
498 case OPTYPE_MOD:
499 case OPTYPE_REM:
500 case OPTYPE_CONCAT:
501 case OPTYPE_EQ:
502 case OPTYPE_LT:
503 case OPTYPE_GT:
504 case OPTYPE_NE:
505 case OPTYPE_GE:
506 case OPTYPE_LE:
507 case OPTYPE_AND:
508 case OPTYPE_OR:
509 case OPTYPE_XOR:
510 case OPTYPE_AND4B:
511 case OPTYPE_OR4B:
512 case OPTYPE_XOR4B:
513 case OPTYPE_SHL:
514 case OPTYPE_SHR:
515 case OPTYPE_ROTL:
516 case OPTYPE_ROTR:
517 case OPTYPE_INT2BIT:
518 case OPTYPE_INT2HEX:
519 case OPTYPE_INT2OCT:
520 case OPTYPE_UNICHAR2OCT:
521 case OPTYPE_OCT2UNICHAR:
522 case OPTYPE_ENCODE_BASE64:
523 delete u.expr.v1;
524 delete u.expr.v2;
525 break;
526 case OPTYPE_DECODE:
527 delete u.expr.r1;
528 delete u.expr.r2;
529 break;
530 case OPTYPE_SUBSTR:
531 delete u.expr.ti1;
532 delete u.expr.v2;
533 delete u.expr.v3;
534 break;
535 case OPTYPE_REGEXP:
536 delete u.expr.ti1;
537 delete u.expr.t2;
538 delete u.expr.v3;
539 break;
540 case OPTYPE_DECOMP: // v1 v2 v3
541 delete u.expr.v1;
542 delete u.expr.v2;
543 delete u.expr.v3;
544 break;
545 case OPTYPE_REPLACE:
546 delete u.expr.ti1;
547 delete u.expr.v2;
548 delete u.expr.v3;
549 delete u.expr.ti4;
550 break;
551 case OPTYPE_LENGTHOF: // ti1
552 case OPTYPE_SIZEOF: // ti1
553 case OPTYPE_VALUEOF: // ti1
554 case OPTYPE_ISVALUE:
555 case OPTYPE_ISBOUND:
556 case OPTYPE_ENCODE:
557 case OPTYPE_ISPRESENT:
558 case OPTYPE_TTCN2STRING:
559 delete u.expr.ti1;
560 break;
561 case OPTYPE_UNDEF_RUNNING:
562 case OPTYPE_TMR_READ:
563 case OPTYPE_TMR_RUNNING:
564 case OPTYPE_ACTIVATE:
565 delete u.expr.r1;
566 break;
567 case OPTYPE_EXECUTE: // r1 [v2]
568 delete u.expr.r1;
569 delete u.expr.v2;
570 break;
571 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
572 delete u.expr.r1;
573 delete u.expr.v2;
574 delete u.expr.v3;
575 break;
576 case OPTYPE_MATCH: // v1 t2
577 delete u.expr.v1;
578 delete u.expr.t2;
579 break;
580 case OPTYPE_ISCHOSEN: // r1 i2
581 delete u.expr.r1;
582 delete u.expr.i2;
583 break;
584 case OPTYPE_ISCHOSEN_V: // v1 i2
585 delete u.expr.v1;
586 delete u.expr.i2;
587 break;
588 case OPTYPE_ISCHOSEN_T: // t1 i2
589 delete u.expr.t1;
590 delete u.expr.i2;
591 break;
592 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
593 delete u.expr.v1;
594 if(u.expr.state!=EXPR_CHECKED)
595 delete u.expr.t_list2;
596 else
597 delete u.expr.ap_list2;
598 break;
599 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
600 delete u.expr.v1;
601 if(u.expr.state!=EXPR_CHECKED)
602 delete u.expr.t_list2;
603 else
604 delete u.expr.ap_list2;
605 delete u.expr.v3;
606 break;
607 case OPTYPE_LOG2STR:
608 delete u.expr.logargs;
609 break;
610 default:
611 FATAL_ERROR("Value::clean_up_expr()");
612 } // switch
613 }
614
615 void Value::copy_and_destroy(Value *src)
616 {
617 clean_up();
618 valuetype = src->valuetype;
619 u = src->u;
620 // update the pointer used for caching if it points to the value itself
621 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
622 src->valuetype = V_ERROR;
623 delete src;
624 }
625
626 Value::Value(valuetype_t p_vt)
627 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
628 {
629 switch(valuetype) {
630 case V_NULL:
631 case V_TTCN3_NULL:
632 case V_OMIT:
633 case V_NOTUSED:
634 case V_ERROR:
635 break;
636 case V_OID:
637 case V_ROID:
638 u.oid_comps=new vector<OID_comp>();
639 break;
640 case V_NAMEDBITS:
641 u.ids=new map<string, Identifier>();
642 break;
643 default:
644 FATAL_ERROR("Value::Value()");
645 } // switch
646 }
647
648 Value::Value(valuetype_t p_vt, bool p_val_bool)
649 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
650 {
651 switch(valuetype) {
652 case V_BOOL:
653 u.val_bool=p_val_bool;
654 break;
655 default:
656 FATAL_ERROR("Value::Value()");
657 } // switch
658 }
659
660 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
661 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
662 {
663 switch(valuetype) {
664 case V_INT:
665 u.val_Int=new int_val_t(p_val_Int);
666 break;
667 default:
668 FATAL_ERROR("Value::Value()");
669 } // switch
670 }
671
672 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
673 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
674 {
675 switch(valuetype){
676 case V_INT:
677 u.val_Int=p_val_Int;
678 break;
679 default:
680 FATAL_ERROR("Value::Value()");
681 }
682 }
683
684 Value::Value(valuetype_t p_vt, string *p_val_str)
685 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
686 {
687 if(!p_val_str) FATAL_ERROR("NULL parameter");
688 switch(valuetype) {
689 case V_BSTR:
690 case V_HSTR:
691 case V_OSTR:
692 case V_CSTR:
693 case V_ISO2022STR:
694 set_val_str(p_val_str);
695 break;
696 default:
697 FATAL_ERROR("Value::Value()");
698 } // switch
699 }
700
701 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
702 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
703 {
704 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
705 set_val_ustr(p_val_ustr);
706 u.ustr.convert_str = false;
707 }
708
709 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
710 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
711 {
712 if (!p_char_syms) FATAL_ERROR("NULL parameter");
713 switch (valuetype) {
714 case V_CHARSYMS:
715 u.char_syms = p_char_syms;
716 break;
717 default:
718 FATAL_ERROR("Value::Value()");
719 } // switch
720 }
721
722 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
723 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
724 {
725 if(!p_val_id)
726 FATAL_ERROR("NULL parameter");
727 switch(valuetype) {
728 case V_NAMEDINT:
729 case V_ENUM:
730 case V_UNDEF_LOWERID:
731 u.val_id=p_val_id;
732 break;
733 default:
734 FATAL_ERROR("Value::Value()");
735 } // switch
736 }
737
738 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
739 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
740 {
741 if(!p_id || !p_val)
742 FATAL_ERROR("NULL parameter");
743 switch(valuetype) {
744 case V_CHOICE:
745 u.choice.alt_name=p_id;
746 u.choice.alt_value=p_val;
747 break;
748 default:
749 FATAL_ERROR("Value::Value()");
750 } // switch
751 }
752
753 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
754 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
755 {
756 switch(valuetype) {
757 case V_REAL:
758 u.val_Real=p_val_Real;
759 break;
760 default:
761 FATAL_ERROR("Value::Value()");
762 } // switch
763 }
764
765 Value::Value(valuetype_t p_vt, Values *p_vs)
766 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
767 {
768 if(!p_vs) FATAL_ERROR("NULL parameter");
769 switch(valuetype) {
770 case V_SEQOF:
771 case V_SETOF:
772 case V_ARRAY:
773 u.val_vs=p_vs;
774 break;
775 default:
776 FATAL_ERROR("Value::Value()");
777 } // switch
778 }
779
780 Value::Value(valuetype_t p_vt, Value *p_v,
781 Ttcn::ParsedActualParameters *p_t_list)
782 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
783 {
784 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
785 switch(valuetype) {
786 case V_INVOKE:
787 u.invoke.v = p_v;
788 u.invoke.t_list = p_t_list;
789 u.invoke.ap_list = 0;
790 break;
791 default:
792 FATAL_ERROR("Value::Value()");
793 }
794 }
795
796 // -
797 Value::Value(operationtype_t p_optype)
798 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
799 {
800 u.expr.v_optype = p_optype;
801 u.expr.state = EXPR_NOT_CHECKED;
802 switch(p_optype) {
803 case OPTYPE_RND:
804 case OPTYPE_COMP_NULL:
805 case OPTYPE_COMP_MTC:
806 case OPTYPE_COMP_SYSTEM:
807 case OPTYPE_COMP_SELF:
808 case OPTYPE_COMP_RUNNING_ANY:
809 case OPTYPE_COMP_RUNNING_ALL:
810 case OPTYPE_COMP_ALIVE_ANY:
811 case OPTYPE_COMP_ALIVE_ALL:
812 case OPTYPE_TMR_RUNNING_ANY:
813 case OPTYPE_GETVERDICT:
814 case OPTYPE_TESTCASENAME:
815 case OPTYPE_PROF_RUNNING:
816 break;
817 default:
818 FATAL_ERROR("Value::Value()");
819 } // switch
820 }
821
822 // v1
823 Value::Value(operationtype_t p_optype, Value *p_v1)
824 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
825 {
826 u.expr.v_optype = p_optype;
827 u.expr.state = EXPR_NOT_CHECKED;
828 switch(p_optype) {
829 case OPTYPE_UNARYPLUS:
830 case OPTYPE_UNARYMINUS:
831 case OPTYPE_NOT:
832 case OPTYPE_NOT4B:
833 case OPTYPE_BIT2HEX:
834 case OPTYPE_BIT2INT:
835 case OPTYPE_BIT2OCT:
836 case OPTYPE_BIT2STR:
837 case OPTYPE_CHAR2INT:
838 case OPTYPE_CHAR2OCT:
839 case OPTYPE_COMP_RUNNING:
840 case OPTYPE_COMP_ALIVE:
841 case OPTYPE_FLOAT2INT:
842 case OPTYPE_FLOAT2STR:
843 case OPTYPE_HEX2BIT:
844 case OPTYPE_HEX2INT:
845 case OPTYPE_HEX2OCT:
846 case OPTYPE_HEX2STR:
847 case OPTYPE_INT2CHAR:
848 case OPTYPE_INT2FLOAT:
849 case OPTYPE_INT2STR:
850 case OPTYPE_INT2UNICHAR:
851 case OPTYPE_OCT2BIT:
852 case OPTYPE_OCT2CHAR:
853 case OPTYPE_OCT2HEX:
854 case OPTYPE_OCT2INT:
855 case OPTYPE_OCT2STR:
856 case OPTYPE_STR2BIT:
857 case OPTYPE_STR2FLOAT:
858 case OPTYPE_STR2HEX:
859 case OPTYPE_STR2INT:
860 case OPTYPE_STR2OCT:
861 case OPTYPE_UNICHAR2INT:
862 case OPTYPE_UNICHAR2CHAR:
863 case OPTYPE_ENUM2INT:
864 case OPTYPE_RNDWITHVAL:
865 case OPTYPE_REMOVE_BOM:
866 case OPTYPE_GET_STRINGENCODING:
867 case OPTYPE_DECODE_BASE64:
868 if(!p_v1) FATAL_ERROR("Value::Value()");
869 u.expr.v1=p_v1;
870 break;
871 default:
872 FATAL_ERROR("Value::Value()");
873 } // switch
874 }
875
876 // ti1
877 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
878 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
879 {
880 u.expr.v_optype = p_optype;
881 u.expr.state = EXPR_NOT_CHECKED;
882 switch(p_optype) {
883 case OPTYPE_LENGTHOF:
884 case OPTYPE_SIZEOF:
885 case OPTYPE_VALUEOF:
886 case OPTYPE_ISVALUE:
887 case OPTYPE_ISBOUND:
888 case OPTYPE_ENCODE:
889 case OPTYPE_ISPRESENT:
890 case OPTYPE_TTCN2STRING:
891 if(!p_ti1) FATAL_ERROR("Value::Value()");
892 u.expr.ti1=p_ti1;
893 break;
894 default:
895 FATAL_ERROR("Value::Value()");
896 } // switch
897 }
898
899 // r1
900 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
901 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
902 {
903 u.expr.v_optype = p_optype;
904 u.expr.state = EXPR_NOT_CHECKED;
905 switch(p_optype) {
906 case OPTYPE_UNDEF_RUNNING:
907 case OPTYPE_TMR_READ:
908 case OPTYPE_TMR_RUNNING:
909 case OPTYPE_ACTIVATE:
910 if(!p_r1) FATAL_ERROR("Value::Value()");
911 u.expr.r1=p_r1;
912 break;
913 default:
914 FATAL_ERROR("Value::Value()");
915 } // switch
916 }
917
918 // v1 t_list2
919 Value::Value(operationtype_t p_optype, Value *p_v1,
920 Ttcn::ParsedActualParameters *p_ap_list)
921 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
922 {
923 u.expr.v_optype = p_optype;
924 u.expr.state = EXPR_NOT_CHECKED;
925 switch(p_optype) {
926 case OPTYPE_ACTIVATE_REFD:
927 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
928 u.expr.v1 = p_v1;
929 u.expr.t_list2 = p_ap_list;
930 break;
931 default:
932 FATAL_ERROR("Value::Value()");
933 }
934 }
935
936 //v1 t_list2 v3
937 Value::Value(operationtype_t p_optype, Value *p_v1,
938 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
939 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
940 {
941 u.expr.v_optype = p_optype;
942 u.expr.state = EXPR_NOT_CHECKED;
943 switch(p_optype) {
944 case OPTYPE_EXECUTE_REFD:
945 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
946 u.expr.v1 = p_v1;
947 u.expr.t_list2 = p_t_list2;
948 u.expr.v3 = p_v3;
949 break;
950 default:
951 FATAL_ERROR("Value::Value()");
952 }
953 }
954
955 // r1 [v2]
956 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
957 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
958 {
959 u.expr.v_optype = p_optype;
960 u.expr.state = EXPR_NOT_CHECKED;
961 switch(p_optype) {
962 case OPTYPE_EXECUTE:
963 if(!p_r1) FATAL_ERROR("Value::Value()");
964 u.expr.r1=p_r1;
965 u.expr.v2=p_v2;
966 break;
967 default:
968 FATAL_ERROR("Value::Value()");
969 } // switch
970 }
971
972 // r1 [v2] [v3] b4
973 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
974 Value *p_v2, Value *p_v3, bool p_b4)
975 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
976 {
977 u.expr.v_optype = p_optype;
978 u.expr.state = EXPR_NOT_CHECKED;
979 switch(p_optype) {
980 case OPTYPE_COMP_CREATE:
981 if(!p_r1) FATAL_ERROR("Value::Value()");
982 u.expr.r1=p_r1;
983 u.expr.v2=p_v2;
984 u.expr.v3=p_v3;
985 u.expr.b4=p_b4;
986 break;
987 default:
988 FATAL_ERROR("Value::Value()");
989 } // switch
990 }
991
992 // v1 v2
993 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
994 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
995 {
996 u.expr.v_optype = p_optype;
997 u.expr.state = EXPR_NOT_CHECKED;
998 switch(p_optype) {
999 case OPTYPE_ADD:
1000 case OPTYPE_SUBTRACT:
1001 case OPTYPE_MULTIPLY:
1002 case OPTYPE_DIVIDE:
1003 case OPTYPE_MOD:
1004 case OPTYPE_REM:
1005 case OPTYPE_CONCAT:
1006 case OPTYPE_EQ:
1007 case OPTYPE_LT:
1008 case OPTYPE_GT:
1009 case OPTYPE_NE:
1010 case OPTYPE_GE:
1011 case OPTYPE_LE:
1012 case OPTYPE_AND:
1013 case OPTYPE_OR:
1014 case OPTYPE_XOR:
1015 case OPTYPE_AND4B:
1016 case OPTYPE_OR4B:
1017 case OPTYPE_XOR4B:
1018 case OPTYPE_SHL:
1019 case OPTYPE_SHR:
1020 case OPTYPE_ROTL:
1021 case OPTYPE_ROTR:
1022 case OPTYPE_INT2BIT:
1023 case OPTYPE_INT2HEX:
1024 case OPTYPE_INT2OCT:
1025 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1026 u.expr.v1=p_v1;
1027 u.expr.v2=p_v2;
1028 break;
1029 case OPTYPE_UNICHAR2OCT:
1030 case OPTYPE_OCT2UNICHAR:
1031 case OPTYPE_ENCODE_BASE64:
1032 if(!p_v1) FATAL_ERROR("Value::Value()");
1033 u.expr.v1=p_v1;
1034 // p_v2 may be NULL if there is no second param
1035 u.expr.v2=p_v2;
1036 break;
1037 default:
1038 FATAL_ERROR("Value::Value()");
1039 } // switch
1040 }
1041
1042 // ti1 v2 v3 ti4
1043 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1044 Value *p_v3, TemplateInstance *p_ti4) :
1045 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1046 {
1047 u.expr.v_optype = p_optype;
1048 u.expr.state = EXPR_NOT_CHECKED;
1049 switch (p_optype) {
1050 case OPTYPE_REPLACE:
1051 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1052 u.expr.ti1 = p_ti1;
1053 u.expr.v2 = p_v2;
1054 u.expr.v3 = p_v3;
1055 u.expr.ti4 = p_ti4;
1056 break;
1057 default:
1058 FATAL_ERROR("Value::Value()");
1059 } // switch
1060 }
1061
1062 // v1 v2 v3
1063 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1064 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1065 {
1066 u.expr.v_optype = p_optype;
1067 u.expr.state = EXPR_NOT_CHECKED;
1068 switch(p_optype) {
1069 case OPTYPE_DECOMP:
1070 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1071 u.expr.v1=p_v1;
1072 u.expr.v2=p_v2;
1073 u.expr.v3=p_v3;
1074 break;
1075 default:
1076 FATAL_ERROR("Value::Value()");
1077 } // switch
1078 }
1079
1080 // ti1 v2 v3
1081 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1082 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1083 {
1084 u.expr.v_optype=p_optype;
1085 u.expr.state=EXPR_NOT_CHECKED;
1086 switch(p_optype) {
1087 case OPTYPE_SUBSTR:
1088 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1089 u.expr.ti1 = p_ti1;
1090 u.expr.v2=p_v2;
1091 u.expr.v3=p_v3;
1092 break;
1093 default:
1094 FATAL_ERROR("Value::Value()");
1095 } // switch
1096 }
1097
1098 // ti1 t2 v3
1099 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1100 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1101 {
1102 u.expr.v_optype=p_optype;
1103 u.expr.state=EXPR_NOT_CHECKED;
1104 switch(p_optype) {
1105 case OPTYPE_REGEXP:
1106 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1107 u.expr.ti1 = p_ti1;
1108 u.expr.t2 = p_t2;
1109 u.expr.v3=p_v3;
1110 break;
1111 default:
1112 FATAL_ERROR("Value::Value()");
1113 } // switch
1114 }
1115
1116 // v1 t2
1117 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1118 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1119 {
1120 u.expr.v_optype = p_optype;
1121 u.expr.state = EXPR_NOT_CHECKED;
1122 switch(p_optype) {
1123 case OPTYPE_MATCH:
1124 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1125 u.expr.v1=p_v1;
1126 u.expr.t2=p_t2;
1127 break;
1128 default:
1129 FATAL_ERROR("Value::Value()");
1130 } // switch
1131 }
1132
1133 // r1 i2
1134 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1135 Identifier *p_i2)
1136 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1137 {
1138 u.expr.v_optype = p_optype;
1139 u.expr.state = EXPR_NOT_CHECKED;
1140 switch(p_optype) {
1141 case OPTYPE_ISCHOSEN:
1142 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1143 u.expr.r1=p_r1;
1144 u.expr.i2=p_i2;
1145 break;
1146 default:
1147 FATAL_ERROR("Value::Value()");
1148 } // switch
1149 }
1150
1151 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1152 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1153 {
1154 u.expr.v_optype = p_optype;
1155 u.expr.state = EXPR_NOT_CHECKED;
1156 switch(p_optype) {
1157 case OPTYPE_LOG2STR:
1158 if (!p_logargs) FATAL_ERROR("Value::Value()");
1159 u.expr.logargs = p_logargs;
1160 break;
1161 default:
1162 FATAL_ERROR("Value::Value()");
1163 } // switch
1164 }
1165
1166 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1167 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1168 {
1169 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1170 switch (p_macrotype) {
1171 case MACRO_MODULEID:
1172 case MACRO_FILENAME:
1173 case MACRO_BFILENAME:
1174 case MACRO_FILEPATH:
1175 case MACRO_LINENUMBER:
1176 case MACRO_LINENUMBER_C:
1177 case MACRO_DEFINITIONID:
1178 case MACRO_SCOPE:
1179 case MACRO_TESTCASEID:
1180 break;
1181 default:
1182 FATAL_ERROR("Value::Value()");
1183 }
1184 u.macro = p_macrotype;
1185 }
1186
1187 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1188 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1189 {
1190 if(!p_nvs) FATAL_ERROR("NULL parameter");
1191 switch(valuetype) {
1192 case V_SEQ:
1193 case V_SET:
1194 u.val_nvs=p_nvs;
1195 break;
1196 default:
1197 FATAL_ERROR("Value::Value()");
1198 } // switch
1199 }
1200
1201 Value::Value(valuetype_t p_vt, Reference *p_ref)
1202 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1203 {
1204 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1205 switch(p_vt) {
1206 case V_REFD:
1207 u.ref.ref = p_ref;
1208 u.ref.refd_last = 0;
1209 break;
1210 case V_REFER:
1211 u.refered = p_ref;
1212 break;
1213 default:
1214 FATAL_ERROR("Value::Value()");
1215 }
1216 }
1217
1218 Value::Value(valuetype_t p_vt, Block *p_block)
1219 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1220 {
1221 if(!p_block) FATAL_ERROR("NULL parameter");
1222 switch(valuetype) {
1223 case V_UNDEF_BLOCK:
1224 u.block=p_block;
1225 break;
1226 default:
1227 FATAL_ERROR("Value::Value()");
1228 } // switch
1229 }
1230
1231 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1232 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1233 {
1234 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1235 switch (p_verdict) {
1236 case Verdict_NONE:
1237 case Verdict_PASS:
1238 case Verdict_INCONC:
1239 case Verdict_FAIL:
1240 case Verdict_ERROR:
1241 break;
1242 default:
1243 FATAL_ERROR("Value::Value()");
1244 } // switch
1245 u.verdict = p_verdict;
1246 }
1247
1248 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1249 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1250 {
1251 u.expr.v_optype = p_optype;
1252 u.expr.state = EXPR_NOT_CHECKED;
1253 switch(p_optype) {
1254 case OPTYPE_DECODE:
1255 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1256 u.expr.r1=p_r1;
1257 u.expr.r2=p_r2;
1258 break;
1259 default:
1260 FATAL_ERROR("Value::Value()");
1261 } // switch
1262 }
1263
1264 Value::~Value()
1265 {
1266 clean_up();
1267 }
1268
1269 Value *Value::clone() const
1270 {
1271 return new Value(*this);
1272 }
1273
1274 Value::operationtype_t Value::get_optype() const
1275 {
1276 if(valuetype!=V_EXPR)
1277 FATAL_ERROR("Value::get_optype()");
1278 return u.expr.v_optype;
1279 }
1280
1281 void Value::set_my_governor(Type *p_gov)
1282 {
1283 if(!p_gov)
1284 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1285 my_governor=p_gov;
1286 }
1287
1288 Type *Value::get_my_governor() const
1289 {
1290 return my_governor;
1291 }
1292
1293 void Value::set_fullname(const string& p_fullname)
1294 {
1295 GovernedSimple::set_fullname(p_fullname);
1296 switch(valuetype) {
1297 case V_CHARSYMS:
1298 u.char_syms->set_fullname(p_fullname);
1299 break;
1300 case V_OID:
1301 case V_ROID:
1302 for(size_t i=0; i<u.oid_comps->size(); i++)
1303 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1304 break;
1305 case V_CHOICE:
1306 u.choice.alt_value->set_fullname(p_fullname + "." +
1307 u.choice.alt_name->get_dispname());
1308 break;
1309 case V_SEQOF:
1310 case V_SETOF:
1311 case V_ARRAY:
1312 u.val_vs->set_fullname(p_fullname);
1313 break;
1314 case V_SEQ:
1315 case V_SET:
1316 u.val_nvs->set_fullname(p_fullname);
1317 break;
1318 case V_REFD:
1319 u.ref.ref->set_fullname(p_fullname);
1320 break;
1321 case V_REFER:
1322 u.refered->set_fullname(p_fullname);
1323 break;
1324 case V_INVOKE:
1325 u.invoke.v->set_fullname(p_fullname);
1326 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1327 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1328 break;
1329 case V_EXPR:
1330 set_fullname_expr(p_fullname);
1331 break;
1332 default:
1333 break;
1334 } // switch
1335 }
1336
1337 void Value::set_my_scope(Scope *p_scope)
1338 {
1339 GovernedSimple::set_my_scope(p_scope);
1340 switch(valuetype) {
1341 case V_CHARSYMS:
1342 u.char_syms->set_my_scope(p_scope);
1343 break;
1344 case V_OID:
1345 case V_ROID:
1346 for(size_t i=0; i<u.oid_comps->size(); i++)
1347 (*u.oid_comps)[i]->set_my_scope(p_scope);
1348 break;
1349 case V_CHOICE:
1350 u.choice.alt_value->set_my_scope(p_scope);
1351 break;
1352 case V_SEQOF:
1353 case V_SETOF:
1354 case V_ARRAY:
1355 u.val_vs->set_my_scope(p_scope);
1356 break;
1357 case V_SEQ:
1358 case V_SET:
1359 u.val_nvs->set_my_scope(p_scope);
1360 break;
1361 case V_REFD:
1362 u.ref.ref->set_my_scope(p_scope);
1363 break;
1364 case V_REFER:
1365 u.refered->set_my_scope(p_scope);
1366 break;
1367 case V_INVOKE:
1368 u.invoke.v->set_my_scope(p_scope);
1369 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1370 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1371 break;
1372 case V_EXPR:
1373 set_my_scope_expr(p_scope);
1374 break;
1375 default:
1376 break;
1377 } // switch
1378 }
1379
1380 void Value::set_fullname_expr(const string& p_fullname)
1381 {
1382 switch (u.expr.v_optype) {
1383 case OPTYPE_RND: // -
1384 case OPTYPE_COMP_NULL:
1385 case OPTYPE_COMP_MTC:
1386 case OPTYPE_COMP_SYSTEM:
1387 case OPTYPE_COMP_SELF:
1388 case OPTYPE_COMP_RUNNING_ANY:
1389 case OPTYPE_COMP_RUNNING_ALL:
1390 case OPTYPE_COMP_ALIVE_ANY:
1391 case OPTYPE_COMP_ALIVE_ALL:
1392 case OPTYPE_TMR_RUNNING_ANY:
1393 case OPTYPE_GETVERDICT:
1394 case OPTYPE_TESTCASENAME:
1395 case OPTYPE_PROF_RUNNING:
1396 break;
1397 case OPTYPE_UNARYPLUS: // v1
1398 case OPTYPE_UNARYMINUS:
1399 case OPTYPE_NOT:
1400 case OPTYPE_NOT4B:
1401 case OPTYPE_BIT2HEX:
1402 case OPTYPE_BIT2INT:
1403 case OPTYPE_BIT2OCT:
1404 case OPTYPE_BIT2STR:
1405 case OPTYPE_CHAR2INT:
1406 case OPTYPE_CHAR2OCT:
1407 case OPTYPE_COMP_RUNNING:
1408 case OPTYPE_COMP_ALIVE:
1409 case OPTYPE_FLOAT2INT:
1410 case OPTYPE_FLOAT2STR:
1411 case OPTYPE_HEX2BIT:
1412 case OPTYPE_HEX2INT:
1413 case OPTYPE_HEX2OCT:
1414 case OPTYPE_HEX2STR:
1415 case OPTYPE_INT2CHAR:
1416 case OPTYPE_INT2FLOAT:
1417 case OPTYPE_INT2STR:
1418 case OPTYPE_INT2UNICHAR:
1419 case OPTYPE_OCT2BIT:
1420 case OPTYPE_OCT2CHAR:
1421 case OPTYPE_OCT2HEX:
1422 case OPTYPE_OCT2INT:
1423 case OPTYPE_OCT2STR:
1424 case OPTYPE_STR2BIT:
1425 case OPTYPE_STR2FLOAT:
1426 case OPTYPE_STR2HEX:
1427 case OPTYPE_STR2INT:
1428 case OPTYPE_STR2OCT:
1429 case OPTYPE_UNICHAR2INT:
1430 case OPTYPE_UNICHAR2CHAR:
1431 case OPTYPE_ENUM2INT:
1432 case OPTYPE_RNDWITHVAL:
1433 case OPTYPE_REMOVE_BOM:
1434 case OPTYPE_GET_STRINGENCODING:
1435 case OPTYPE_DECODE_BASE64:
1436 u.expr.v1->set_fullname(p_fullname+".<operand>");
1437 break;
1438 case OPTYPE_ADD: // v1 v2
1439 case OPTYPE_SUBTRACT:
1440 case OPTYPE_MULTIPLY:
1441 case OPTYPE_DIVIDE:
1442 case OPTYPE_MOD:
1443 case OPTYPE_REM:
1444 case OPTYPE_CONCAT:
1445 case OPTYPE_EQ:
1446 case OPTYPE_LT:
1447 case OPTYPE_GT:
1448 case OPTYPE_NE:
1449 case OPTYPE_GE:
1450 case OPTYPE_LE:
1451 case OPTYPE_AND:
1452 case OPTYPE_OR:
1453 case OPTYPE_XOR:
1454 case OPTYPE_AND4B:
1455 case OPTYPE_OR4B:
1456 case OPTYPE_XOR4B:
1457 case OPTYPE_SHL:
1458 case OPTYPE_SHR:
1459 case OPTYPE_ROTL:
1460 case OPTYPE_ROTR:
1461 case OPTYPE_INT2BIT:
1462 case OPTYPE_INT2HEX:
1463 case OPTYPE_INT2OCT:
1464 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1465 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1466 break;
1467 case OPTYPE_UNICHAR2OCT:
1468 case OPTYPE_OCT2UNICHAR:
1469 case OPTYPE_ENCODE_BASE64:
1470 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1471 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1472 break;
1473 case OPTYPE_DECODE:
1474 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1475 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1476 break;
1477 case OPTYPE_SUBSTR:
1478 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1479 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1480 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1481 break;
1482 case OPTYPE_REGEXP:
1483 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1484 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1485 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1486 break;
1487 case OPTYPE_DECOMP: // v1 v2 v3
1488 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1489 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1490 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1491 break;
1492 case OPTYPE_REPLACE:
1493 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1494 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1495 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1496 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1497 break;
1498 case OPTYPE_LENGTHOF: // ti1
1499 case OPTYPE_SIZEOF: // ti1
1500 case OPTYPE_VALUEOF: // ti1
1501 case OPTYPE_ISVALUE:
1502 case OPTYPE_ISBOUND:
1503 case OPTYPE_ENCODE:
1504 case OPTYPE_ISPRESENT:
1505 case OPTYPE_TTCN2STRING:
1506 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1507 break;
1508 case OPTYPE_UNDEF_RUNNING: // r1
1509 case OPTYPE_TMR_READ:
1510 case OPTYPE_TMR_RUNNING:
1511 case OPTYPE_ACTIVATE:
1512 u.expr.r1->set_fullname(p_fullname+".<operand>");
1513 break;
1514 case OPTYPE_EXECUTE: // r1 [v2]
1515 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1516 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1517 break;
1518 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1519 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1520 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1521 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1522 break;
1523 case OPTYPE_MATCH: // v1 t2
1524 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1525 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1526 break;
1527 case OPTYPE_ISCHOSEN: // r1 i2
1528 u.expr.r1->set_fullname(p_fullname+".<operand>");
1529 break;
1530 case OPTYPE_ISCHOSEN_V: // v1 i2
1531 u.expr.v1->set_fullname(p_fullname+".<operand>");
1532 break;
1533 case OPTYPE_ISCHOSEN_T: // t1 i2
1534 u.expr.t1->set_fullname(p_fullname+".<operand>");
1535 break;
1536 case OPTYPE_ACTIVATE_REFD:
1537 u.expr.v1->set_fullname(p_fullname+".<reference>");
1538 if(u.expr.state!=EXPR_CHECKED)
1539 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1540 else
1541 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1542 break;
1543 case OPTYPE_EXECUTE_REFD:
1544 u.expr.v1->set_fullname(p_fullname+".<reference>");
1545 if(u.expr.state!=EXPR_CHECKED)
1546 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1547 else
1548 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1549 if(u.expr.v3)
1550 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1551 break;
1552 case OPTYPE_LOG2STR:
1553 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1554 break;
1555 default:
1556 FATAL_ERROR("Value::set_fullname_expr()");
1557 } // switch
1558 }
1559
1560 void Value::set_my_scope_expr(Scope *p_scope)
1561 {
1562 switch (u.expr.v_optype) {
1563 case OPTYPE_RND: // -
1564 case OPTYPE_COMP_NULL:
1565 case OPTYPE_COMP_MTC:
1566 case OPTYPE_COMP_SYSTEM:
1567 case OPTYPE_COMP_SELF:
1568 case OPTYPE_COMP_RUNNING_ANY:
1569 case OPTYPE_COMP_RUNNING_ALL:
1570 case OPTYPE_COMP_ALIVE_ANY:
1571 case OPTYPE_COMP_ALIVE_ALL:
1572 case OPTYPE_TMR_RUNNING_ANY:
1573 case OPTYPE_GETVERDICT:
1574 case OPTYPE_TESTCASENAME:
1575 case OPTYPE_PROF_RUNNING:
1576 break;
1577 case OPTYPE_UNARYPLUS: // v1
1578 case OPTYPE_UNARYMINUS:
1579 case OPTYPE_NOT:
1580 case OPTYPE_NOT4B:
1581 case OPTYPE_BIT2HEX:
1582 case OPTYPE_BIT2INT:
1583 case OPTYPE_BIT2OCT:
1584 case OPTYPE_BIT2STR:
1585 case OPTYPE_CHAR2INT:
1586 case OPTYPE_CHAR2OCT:
1587 case OPTYPE_COMP_RUNNING:
1588 case OPTYPE_COMP_ALIVE:
1589 case OPTYPE_FLOAT2INT:
1590 case OPTYPE_FLOAT2STR:
1591 case OPTYPE_HEX2BIT:
1592 case OPTYPE_HEX2INT:
1593 case OPTYPE_HEX2OCT:
1594 case OPTYPE_HEX2STR:
1595 case OPTYPE_INT2CHAR:
1596 case OPTYPE_INT2FLOAT:
1597 case OPTYPE_INT2STR:
1598 case OPTYPE_INT2UNICHAR:
1599 case OPTYPE_OCT2BIT:
1600 case OPTYPE_OCT2CHAR:
1601 case OPTYPE_OCT2HEX:
1602 case OPTYPE_OCT2INT:
1603 case OPTYPE_OCT2STR:
1604 case OPTYPE_STR2BIT:
1605 case OPTYPE_STR2FLOAT:
1606 case OPTYPE_STR2HEX:
1607 case OPTYPE_STR2INT:
1608 case OPTYPE_STR2OCT:
1609 case OPTYPE_UNICHAR2INT:
1610 case OPTYPE_UNICHAR2CHAR:
1611 case OPTYPE_ENUM2INT:
1612 case OPTYPE_RNDWITHVAL:
1613 case OPTYPE_REMOVE_BOM:
1614 case OPTYPE_GET_STRINGENCODING:
1615 case OPTYPE_DECODE_BASE64:
1616 u.expr.v1->set_my_scope(p_scope);
1617 break;
1618 case OPTYPE_ADD: // v1 v2
1619 case OPTYPE_SUBTRACT:
1620 case OPTYPE_MULTIPLY:
1621 case OPTYPE_DIVIDE:
1622 case OPTYPE_MOD:
1623 case OPTYPE_REM:
1624 case OPTYPE_CONCAT:
1625 case OPTYPE_EQ:
1626 case OPTYPE_LT:
1627 case OPTYPE_GT:
1628 case OPTYPE_NE:
1629 case OPTYPE_GE:
1630 case OPTYPE_LE:
1631 case OPTYPE_AND:
1632 case OPTYPE_OR:
1633 case OPTYPE_XOR:
1634 case OPTYPE_AND4B:
1635 case OPTYPE_OR4B:
1636 case OPTYPE_XOR4B:
1637 case OPTYPE_SHL:
1638 case OPTYPE_SHR:
1639 case OPTYPE_ROTL:
1640 case OPTYPE_ROTR:
1641 case OPTYPE_INT2BIT:
1642 case OPTYPE_INT2HEX:
1643 case OPTYPE_INT2OCT:
1644 u.expr.v1->set_my_scope(p_scope);
1645 u.expr.v2->set_my_scope(p_scope);
1646 break;
1647 case OPTYPE_UNICHAR2OCT:
1648 case OPTYPE_OCT2UNICHAR:
1649 case OPTYPE_ENCODE_BASE64:
1650 u.expr.v1->set_my_scope(p_scope);
1651 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1652 break;
1653 case OPTYPE_DECODE:
1654 u.expr.r1->set_my_scope(p_scope);
1655 u.expr.r2->set_my_scope(p_scope);
1656 break;
1657 case OPTYPE_SUBSTR:
1658 u.expr.ti1->set_my_scope(p_scope);
1659 u.expr.v2->set_my_scope(p_scope);
1660 u.expr.v3->set_my_scope(p_scope);
1661 break;
1662 case OPTYPE_REGEXP:
1663 u.expr.ti1->set_my_scope(p_scope);
1664 u.expr.t2->set_my_scope(p_scope);
1665 u.expr.v3->set_my_scope(p_scope);
1666 break;
1667 case OPTYPE_DECOMP: // v1 v2 v3
1668 u.expr.v1->set_my_scope(p_scope);
1669 u.expr.v2->set_my_scope(p_scope);
1670 u.expr.v3->set_my_scope(p_scope);
1671 break;
1672 case OPTYPE_REPLACE:
1673 u.expr.ti1->set_my_scope(p_scope);
1674 u.expr.v2->set_my_scope(p_scope);
1675 u.expr.v3->set_my_scope(p_scope);
1676 u.expr.ti4->set_my_scope(p_scope);
1677 break;
1678 case OPTYPE_LENGTHOF: // ti1
1679 case OPTYPE_SIZEOF: // ti1
1680 case OPTYPE_VALUEOF: // ti1
1681 case OPTYPE_ISVALUE:
1682 case OPTYPE_ISBOUND:
1683 case OPTYPE_ENCODE:
1684 case OPTYPE_ISPRESENT:
1685 case OPTYPE_TTCN2STRING:
1686 u.expr.ti1->set_my_scope(p_scope);
1687 break;
1688 case OPTYPE_UNDEF_RUNNING: // r1
1689 case OPTYPE_TMR_READ:
1690 case OPTYPE_TMR_RUNNING:
1691 case OPTYPE_ACTIVATE:
1692 u.expr.r1->set_my_scope(p_scope);
1693 break;
1694 case OPTYPE_EXECUTE: // r1 [v2]
1695 u.expr.r1->set_my_scope(p_scope);
1696 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1697 break;
1698 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1699 u.expr.r1->set_my_scope(p_scope);
1700 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1701 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1702 break;
1703 case OPTYPE_MATCH: // v1 t2
1704 u.expr.v1->set_my_scope(p_scope);
1705 u.expr.t2->set_my_scope(p_scope);
1706 break;
1707 case OPTYPE_ISCHOSEN: // r1 i2
1708 u.expr.r1->set_my_scope(p_scope);
1709 break;
1710 case OPTYPE_ISCHOSEN_V: // v1 i2
1711 u.expr.v1->set_my_scope(p_scope);
1712 break;
1713 case OPTYPE_ISCHOSEN_T: // t1 i2
1714 u.expr.t1->set_my_scope(p_scope);
1715 break;
1716 case OPTYPE_ACTIVATE_REFD:
1717 u.expr.v1->set_my_scope(p_scope);
1718 if(u.expr.state!=EXPR_CHECKED) {
1719 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1720 else
1721 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1722 } break;
1723 case OPTYPE_EXECUTE_REFD:
1724 u.expr.v1->set_my_scope(p_scope);
1725 if(u.expr.state!=EXPR_CHECKED) {
1726 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1727 else
1728 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1729 }
1730 if(u.expr.v3)
1731 u.expr.v3->set_my_scope(p_scope);
1732 break;
1733 case OPTYPE_LOG2STR:
1734 u.expr.logargs->set_my_scope(p_scope);
1735 break;
1736 default:
1737 FATAL_ERROR("Value::set_my_scope_expr()");
1738 } // switch
1739 }
1740
1741 void Value::set_genname_recursive(const string& p_genname)
1742 {
1743 size_t genname_len = p_genname.size();
1744 if (genname_len >= 4 &&
1745 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1746 // if the genname ends with ()() (i.e. the value stands for an optional
1747 // field) then drop the last () from the own genname, but leave it for
1748 // the embedded values
1749 set_genname(p_genname.substr(0, genname_len - 2));
1750 } else set_genname(p_genname);
1751 switch(valuetype) {
1752 case V_CHOICE: {
1753 string embedded_genname(p_genname);
1754 embedded_genname += '.';
1755 // If this is a choice value for an anytype, prepend the AT_ prefix
1756 // to the name of the alternative. The genname is used later in
1757 // Common::Value::generate_code_init_se()
1758 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1759 embedded_genname += "AT_";
1760 embedded_genname += u.choice.alt_name->get_name();
1761 embedded_genname += "()";
1762 u.choice.alt_value->set_genname_recursive(embedded_genname);
1763 break; }
1764 case V_SEQOF:
1765 case V_SETOF: {
1766 if (!is_indexed()) {
1767 size_t nof_vs = u.val_vs->get_nof_vs();
1768 for (size_t i = 0; i < nof_vs; i++) {
1769 string embedded_genname(p_genname);
1770 embedded_genname += '[';
1771 embedded_genname += Int2string(i);
1772 embedded_genname += ']';
1773 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1774 }
1775 } else {
1776 size_t nof_ivs = u.val_vs->get_nof_ivs();
1777 for (size_t i = 0; i < nof_ivs; i++) {
1778 string embedded_genname(p_genname);
1779 embedded_genname += '[';
1780 embedded_genname += Int2string(i);
1781 embedded_genname += ']';
1782 u.val_vs->get_iv_byIndex(i)->get_value()
1783 ->set_genname_recursive(embedded_genname);
1784 }
1785 }
1786 break; }
1787 case V_ARRAY: {
1788 if (!my_governor) return; // error recovery
1789 Type *type = my_governor->get_type_refd_last();
1790 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1791 Int offset = type->get_dimension()->get_offset();
1792 if (!is_indexed()) {
1793 size_t nof_vs = u.val_vs->get_nof_vs();
1794 for (size_t i = 0; i < nof_vs; i++) {
1795 string embedded_genname(p_genname);
1796 embedded_genname += '[';
1797 embedded_genname += Int2string(offset + i);
1798 embedded_genname += ']';
1799 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1800 }
1801 } else {
1802 size_t nof_ivs = u.val_vs->get_nof_ivs();
1803 for (size_t i = 0; i < nof_ivs; i++) {
1804 string embedded_genname(p_genname);
1805 embedded_genname += '[';
1806 embedded_genname += Int2string(offset + i);
1807 embedded_genname += ']';
1808 u.val_vs->get_iv_byIndex(i)->get_value()
1809 ->set_genname_recursive(embedded_genname);
1810 }
1811 }
1812 break; }
1813 case V_SEQ:
1814 case V_SET: {
1815 if (!my_governor) return; // error recovery
1816 Type *t = my_governor->get_type_refd_last();
1817 if (!t->is_secho()) return; // error recovery
1818 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1819 for (size_t i = 0; i < nof_nvs; i++) {
1820 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1821 const Identifier& id = nv->get_name();
1822 if (!t->has_comp_withName(id)) return; // error recovery
1823 string embedded_genname(p_genname);
1824 embedded_genname += '.';
1825 embedded_genname += id.get_name();
1826 embedded_genname += "()";
1827 if (t->get_comp_byName(id)->get_is_optional())
1828 embedded_genname += "()";
1829 nv->get_value()->set_genname_recursive(embedded_genname);
1830 }
1831 break; }
1832 default:
1833 break;
1834 } // switch
1835 }
1836
1837 void Value::set_genname_prefix(const char *p_genname_prefix)
1838 {
1839 GovernedSimple::set_genname_prefix(p_genname_prefix);
1840 switch(valuetype) {
1841 case V_CHOICE:
1842 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1843 break;
1844 case V_SEQOF:
1845 case V_SETOF:
1846 case V_ARRAY:
1847 if (!is_indexed()) {
1848 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1849 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1850 } else {
1851 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1852 u.val_vs->get_iv_byIndex(i)->get_value()
1853 ->set_genname_prefix(p_genname_prefix);
1854 }
1855 break;
1856 case V_SEQ:
1857 case V_SET:
1858 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1859 u.val_nvs->get_nv_byIndex(i)->get_value()
1860 ->set_genname_prefix(p_genname_prefix);
1861 break;
1862 default:
1863 break;
1864 } // switch
1865 }
1866
1867 void Value::set_code_section(code_section_t p_code_section)
1868 {
1869 GovernedSimple::set_code_section(p_code_section);
1870 switch(valuetype) {
1871 case V_EXPR:
1872 switch (u.expr.v_optype) {
1873 case OPTYPE_RND: // -
1874 case OPTYPE_COMP_NULL:
1875 case OPTYPE_COMP_MTC:
1876 case OPTYPE_COMP_SYSTEM:
1877 case OPTYPE_COMP_SELF:
1878 case OPTYPE_COMP_RUNNING_ANY:
1879 case OPTYPE_COMP_RUNNING_ALL:
1880 case OPTYPE_COMP_ALIVE_ANY:
1881 case OPTYPE_COMP_ALIVE_ALL:
1882 case OPTYPE_TMR_RUNNING_ANY:
1883 case OPTYPE_GETVERDICT:
1884 case OPTYPE_TESTCASENAME:
1885 case OPTYPE_PROF_RUNNING:
1886 break;
1887 case OPTYPE_UNARYPLUS: // v1
1888 case OPTYPE_UNARYMINUS:
1889 case OPTYPE_NOT:
1890 case OPTYPE_NOT4B:
1891 case OPTYPE_BIT2HEX:
1892 case OPTYPE_BIT2INT:
1893 case OPTYPE_BIT2OCT:
1894 case OPTYPE_BIT2STR:
1895 case OPTYPE_CHAR2INT:
1896 case OPTYPE_CHAR2OCT:
1897 case OPTYPE_COMP_RUNNING:
1898 case OPTYPE_COMP_ALIVE:
1899 case OPTYPE_FLOAT2INT:
1900 case OPTYPE_FLOAT2STR:
1901 case OPTYPE_HEX2BIT:
1902 case OPTYPE_HEX2INT:
1903 case OPTYPE_HEX2OCT:
1904 case OPTYPE_HEX2STR:
1905 case OPTYPE_INT2CHAR:
1906 case OPTYPE_INT2FLOAT:
1907 case OPTYPE_INT2STR:
1908 case OPTYPE_INT2UNICHAR:
1909 case OPTYPE_OCT2BIT:
1910 case OPTYPE_OCT2CHAR:
1911 case OPTYPE_OCT2HEX:
1912 case OPTYPE_OCT2INT:
1913 case OPTYPE_OCT2STR:
1914 case OPTYPE_STR2BIT:
1915 case OPTYPE_STR2FLOAT:
1916 case OPTYPE_STR2HEX:
1917 case OPTYPE_STR2INT:
1918 case OPTYPE_STR2OCT:
1919 case OPTYPE_UNICHAR2INT:
1920 case OPTYPE_UNICHAR2CHAR:
1921 case OPTYPE_ENUM2INT:
1922 case OPTYPE_RNDWITHVAL:
1923 case OPTYPE_GET_STRINGENCODING:
1924 case OPTYPE_DECODE_BASE64:
1925 case OPTYPE_REMOVE_BOM:
1926 u.expr.v1->set_code_section(p_code_section);
1927 break;
1928 case OPTYPE_ADD: // v1 v2
1929 case OPTYPE_SUBTRACT:
1930 case OPTYPE_MULTIPLY:
1931 case OPTYPE_DIVIDE:
1932 case OPTYPE_MOD:
1933 case OPTYPE_REM:
1934 case OPTYPE_CONCAT:
1935 case OPTYPE_EQ:
1936 case OPTYPE_LT:
1937 case OPTYPE_GT:
1938 case OPTYPE_NE:
1939 case OPTYPE_GE:
1940 case OPTYPE_LE:
1941 case OPTYPE_AND:
1942 case OPTYPE_OR:
1943 case OPTYPE_XOR:
1944 case OPTYPE_AND4B:
1945 case OPTYPE_OR4B:
1946 case OPTYPE_XOR4B:
1947 case OPTYPE_SHL:
1948 case OPTYPE_SHR:
1949 case OPTYPE_ROTL:
1950 case OPTYPE_ROTR:
1951 case OPTYPE_INT2BIT:
1952 case OPTYPE_INT2HEX:
1953 case OPTYPE_INT2OCT:
1954 u.expr.v1->set_code_section(p_code_section);
1955 u.expr.v2->set_code_section(p_code_section);
1956 break;
1957 case OPTYPE_UNICHAR2OCT:
1958 case OPTYPE_OCT2UNICHAR:
1959 case OPTYPE_ENCODE_BASE64:
1960 u.expr.v1->set_code_section(p_code_section);
1961 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
1962 break;
1963 case OPTYPE_DECODE:
1964 u.expr.r1->set_code_section(p_code_section);
1965 u.expr.r2->set_code_section(p_code_section);
1966 break;
1967 case OPTYPE_SUBSTR:
1968 u.expr.ti1->set_code_section(p_code_section);
1969 u.expr.v2->set_code_section(p_code_section);
1970 u.expr.v3->set_code_section(p_code_section);
1971 break;
1972 case OPTYPE_REGEXP:
1973 u.expr.ti1->set_code_section(p_code_section);
1974 u.expr.t2->set_code_section(p_code_section);
1975 u.expr.v3->set_code_section(p_code_section);
1976 break;
1977 case OPTYPE_DECOMP: // v1 v2 v3
1978 u.expr.v1->set_code_section(p_code_section);
1979 u.expr.v2->set_code_section(p_code_section);
1980 u.expr.v3->set_code_section(p_code_section);
1981 break;
1982 case OPTYPE_REPLACE:
1983 u.expr.ti1->set_code_section(p_code_section);
1984 u.expr.v2->set_code_section(p_code_section);
1985 u.expr.v3->set_code_section(p_code_section);
1986 u.expr.ti4->set_code_section(p_code_section);
1987 break;
1988 case OPTYPE_LENGTHOF: // ti1
1989 case OPTYPE_SIZEOF: // ti1
1990 case OPTYPE_VALUEOF: // ti1
1991 case OPTYPE_ISVALUE:
1992 case OPTYPE_ISBOUND:
1993 case OPTYPE_ENCODE:
1994 case OPTYPE_ISPRESENT:
1995 case OPTYPE_TTCN2STRING:
1996 u.expr.ti1->set_code_section(p_code_section);
1997 break;
1998 case OPTYPE_UNDEF_RUNNING: // r1
1999 case OPTYPE_TMR_READ:
2000 case OPTYPE_TMR_RUNNING:
2001 case OPTYPE_ACTIVATE:
2002 u.expr.r1->set_code_section(p_code_section);
2003 break;
2004 case OPTYPE_EXECUTE: // r1 [v2]
2005 u.expr.r1->set_code_section(p_code_section);
2006 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2007 break;
2008 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2009 u.expr.r1->set_code_section(p_code_section);
2010 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2011 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2012 break;
2013 case OPTYPE_MATCH: // v1 t2
2014 u.expr.v1->set_code_section(p_code_section);
2015 u.expr.t2->set_code_section(p_code_section);
2016 break;
2017 case OPTYPE_ISCHOSEN: // r1 i2
2018 u.expr.r1->set_code_section(p_code_section);
2019 break;
2020 case OPTYPE_ISCHOSEN_V: // v1 i2
2021 u.expr.v1->set_code_section(p_code_section);
2022 break;
2023 case OPTYPE_ISCHOSEN_T: // t1 i2
2024 u.expr.t1->set_code_section(p_code_section);
2025 break;
2026 case OPTYPE_ACTIVATE_REFD:
2027 u.expr.v1->set_code_section(p_code_section);
2028 if(u.expr.state!=EXPR_CHECKED)
2029 u.expr.t_list2->set_code_section(p_code_section);
2030 else {
2031 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2032 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2033 u.expr.state = EXPR_CHECKED;
2034 }
2035 break;
2036 case OPTYPE_EXECUTE_REFD:
2037 u.expr.v1->set_code_section(p_code_section);
2038 if(u.expr.state!=EXPR_CHECKED)
2039 u.expr.t_list2->set_code_section(p_code_section);
2040 else {
2041 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2042 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2043 u.expr.state = EXPR_CHECKED;
2044 }
2045 if(u.expr.v3)
2046 u.expr.v3->set_code_section(p_code_section);
2047 break;
2048 case OPTYPE_LOG2STR:
2049 u.expr.logargs->set_code_section(p_code_section);
2050 break;
2051 default:
2052 FATAL_ERROR("Value::set_code_section()");
2053 } // switch
2054 break;
2055 case V_CHOICE:
2056 u.choice.alt_value->set_code_section(p_code_section);
2057 break;
2058 case V_SEQOF:
2059 case V_SETOF:
2060 case V_ARRAY:
2061 if (!is_indexed()) {
2062 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2063 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2064 } else {
2065 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2066 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2067 }
2068 break;
2069 case V_SEQ:
2070 case V_SET:
2071 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2072 u.val_nvs->get_nv_byIndex(i)->get_value()
2073 ->set_code_section(p_code_section);
2074 break;
2075 case V_REFD:
2076 u.ref.ref->set_code_section(p_code_section);
2077 break;
2078 case V_REFER:
2079 u.refered->set_code_section(p_code_section);
2080 break;
2081 case V_INVOKE:
2082 u.invoke.v->set_code_section(p_code_section);
2083 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2084 if(u.invoke.ap_list)
2085 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2086 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2087 break;
2088 default:
2089 break;
2090 } // switch
2091 }
2092
2093 void Value::change_sign()
2094 {
2095 switch(valuetype) {
2096 case V_INT:
2097 *u.val_Int=-*u.val_Int;
2098 break;
2099 case V_REAL:
2100 u.val_Real*=-1.0;
2101 break;
2102 case V_ERROR:
2103 break;
2104 default:
2105 FATAL_ERROR("Value::change_sign()");
2106 } // switch
2107 }
2108
2109 void Value::add_oid_comp(OID_comp* p_comp)
2110 {
2111 if(!p_comp)
2112 FATAL_ERROR("NULL parameter");
2113 u.oid_comps->add(p_comp);
2114 p_comp->set_fullname(get_fullname()+"."
2115 +Int2string(u.oid_comps->size()));
2116 p_comp->set_my_scope(my_scope);
2117 }
2118
2119 void Value::set_valuetype(valuetype_t p_valuetype)
2120 {
2121 if (valuetype == V_ERROR) return;
2122 else if (p_valuetype == V_ERROR) {
2123 if(valuetype==V_EXPR) {
2124 switch(u.expr.state) {
2125 case EXPR_CHECKING:
2126 u.expr.state=EXPR_CHECKING_ERR;
2127 // no break
2128 case EXPR_CHECKING_ERR:
2129 return;
2130 default:
2131 break;
2132 }
2133 }
2134 clean_up();
2135 valuetype = V_ERROR;
2136 return;
2137 }
2138 switch(valuetype) {
2139 case V_UNDEF_LOWERID:
2140 switch(p_valuetype) {
2141 case V_ENUM:
2142 case V_NAMEDINT:
2143 break;
2144 case V_REFD:
2145 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2146 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2147 u.ref.ref->set_my_scope(get_my_scope());
2148 u.ref.ref->set_fullname(get_fullname());
2149 u.ref.ref->set_location(*this);
2150 u.ref.refd_last = 0;
2151 break;
2152 default:
2153 FATAL_ERROR("Value::set_valuetype()");
2154 } // switch
2155 break;
2156 case V_UNDEF_BLOCK: {
2157 Block *t_block=u.block;
2158 Value *v=0;
2159 switch(p_valuetype) {
2160 case V_NAMEDBITS: {
2161 Node *node=t_block->parse(KW_Block_IdentifierList);
2162 v=dynamic_cast<Value*>(node);
2163 if(!v) {
2164 /* syntax error */
2165 u.ids=new map<string, Identifier>();
2166 }
2167 else {
2168 u.ids=v->u.ids; v->u.ids=0;
2169 }
2170 break;}
2171 case V_SEQOF: {
2172 Node *node=t_block->parse(KW_Block_SeqOfValue);
2173 v=dynamic_cast<Value*>(node);
2174 if(!v) {
2175 /* syntax error */
2176 u.val_vs=new Values();
2177 }
2178 else {
2179 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2180 }
2181 u.val_vs->set_my_scope(get_my_scope());
2182 u.val_vs->set_fullname(get_fullname());
2183 break;}
2184 case V_SETOF: {
2185 Node *node=t_block->parse(KW_Block_SetOfValue);
2186 v=dynamic_cast<Value*>(node);
2187 if(!v) {
2188 /* syntax error */
2189 u.val_vs=new Values();
2190 }
2191 else {
2192 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2193 }
2194 u.val_vs->set_my_scope(get_my_scope());
2195 u.val_vs->set_fullname(get_fullname());
2196 break;}
2197 case V_SEQ: {
2198 Node *node=t_block->parse(KW_Block_SequenceValue);
2199 v=dynamic_cast<Value*>(node);
2200 if(!v) {
2201 /* syntax error */
2202 u.val_nvs=new NamedValues();
2203 }
2204 else {
2205 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2206 }
2207 u.val_nvs->set_my_scope(get_my_scope());
2208 u.val_nvs->set_fullname(get_fullname());
2209 break;}
2210 case V_SET: {
2211 Node *node=t_block->parse(KW_Block_SetValue);
2212 v=dynamic_cast<Value*>(node);
2213 if(!v) {
2214 /* syntax error */
2215 u.val_nvs=new NamedValues();
2216 }
2217 else {
2218 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2219 }
2220 u.val_nvs->set_my_scope(get_my_scope());
2221 u.val_nvs->set_fullname(get_fullname());
2222 break;}
2223 case V_OID: {
2224 Node *node=t_block->parse(KW_Block_OIDValue);
2225 v=dynamic_cast<Value*>(node);
2226 if(!v) {
2227 /* syntax error */
2228 u.oid_comps=new vector<OID_comp>();
2229 }
2230 else {
2231 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2232 }
2233 for (size_t i = 0; i < u.oid_comps->size(); i++)
2234 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2235 break;}
2236 case V_ROID: {
2237 Node *node=t_block->parse(KW_Block_ROIDValue);
2238 v=dynamic_cast<Value*>(node);
2239 if(!v) {
2240 /* syntax error */
2241 u.oid_comps=new vector<OID_comp>();
2242 }
2243 else {
2244 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2245 }
2246 for (size_t i = 0; i < u.oid_comps->size(); i++)
2247 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2248 break;}
2249 case V_CHARSYMS: {
2250 Node *node=t_block->parse(KW_Block_CharStringValue);
2251 u.char_syms=dynamic_cast<CharSyms*>(node);
2252 if(!u.char_syms) {
2253 /* syntax error */
2254 u.char_syms=new CharSyms();
2255 }
2256 u.char_syms->set_my_scope(get_my_scope());
2257 u.char_syms->set_fullname(get_fullname());
2258 break;}
2259 default:
2260 FATAL_ERROR("Value::set_valuetype()");
2261 } // switch
2262 delete v;
2263 delete t_block;
2264 break;}
2265 case V_REFD:
2266 if (p_valuetype == V_USTR) {
2267 Value *v_last = get_value_refd_last();
2268 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2269 ustring *ustr = new ustring(*v_last->u.str.val_str);
2270 delete u.ref.ref;
2271 set_val_ustr(ustr);
2272 u.ustr.convert_str = true; // will be converted back to string
2273 } else FATAL_ERROR("Value::set_valuetype()");
2274 break;
2275 case V_CHARSYMS:
2276 switch(p_valuetype) {
2277 case V_CSTR: {
2278 const string& str = u.char_syms->get_string();
2279 delete u.char_syms;
2280 set_val_str(new string(str));
2281 break;}
2282 case V_USTR: {
2283 const ustring& ustr = u.char_syms->get_ustring();
2284 delete u.char_syms;
2285 set_val_ustr(new ustring(ustr));
2286 u.ustr.convert_str = false;
2287 break;}
2288 case V_ISO2022STR: {
2289 const string& str = u.char_syms->get_iso2022string();
2290 delete u.char_syms;
2291 set_val_str(new string(str));
2292 break;}
2293 default:
2294 FATAL_ERROR("Value::set_valuetype()");
2295 } // switch
2296 break;
2297 case V_INT: {
2298 Real val_Real;
2299 if (p_valuetype == V_REAL)
2300 val_Real = u.val_Int->to_real();
2301 else FATAL_ERROR("Value::set_valuetype()");
2302 clean_up();
2303 u.val_Real = val_Real;
2304 break; }
2305 case V_HSTR: {
2306 clean_up_string_elements(u.str.str_elements);
2307 string *old_str = u.str.val_str;
2308 switch(p_valuetype) {
2309 case V_BSTR:
2310 set_val_str(hex2bit(*old_str));
2311 break;
2312 case V_OSTR:
2313 set_val_str(asn_hex2oct(*old_str));
2314 break;
2315 default:
2316 FATAL_ERROR("Value::set_valuetype()");
2317 } // switch
2318 delete old_str;
2319 break;}
2320 case V_BSTR:
2321 clean_up_string_elements(u.str.str_elements);
2322 if (p_valuetype == V_OSTR) {
2323 string *old_str = u.str.val_str;
2324 set_val_str(asn_bit2oct(*old_str));
2325 delete old_str;
2326 } else FATAL_ERROR("Value::set_valuetype()");
2327 break;
2328 case V_CSTR:
2329 clean_up_string_elements(u.str.str_elements);
2330 switch(p_valuetype) {
2331 case V_USTR: {
2332 string *old_str = u.str.val_str;
2333 set_val_ustr(new ustring(*old_str));
2334 u.ustr.convert_str = true; // will be converted back to string
2335 delete old_str;
2336 break;}
2337 case V_ISO2022STR:
2338 // do nothing
2339 break;
2340 default:
2341 FATAL_ERROR("Value::set_valuetype()");
2342 } // switch p_valuetype
2343 break;
2344 case V_USTR:
2345 clean_up_string_elements(u.ustr.ustr_elements);
2346 switch(p_valuetype) {
2347 case V_CSTR: {
2348 ustring *old_str = u.ustr.val_ustr;
2349 size_t nof_chars = old_str->size();
2350 bool warning_flag = false;
2351 for (size_t i = 0; i < nof_chars; i++) {
2352 const ustring::universal_char& uchar = (*old_str)[i];
2353 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2354 error("This string value cannot contain multiple-byte characters, "
2355 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2356 uchar.group, uchar.plane, uchar.row, uchar.cell,
2357 (unsigned long) i);
2358 p_valuetype = V_ERROR;
2359 break;
2360 } else if (uchar.cell > 127 && !warning_flag) {
2361 warning("This string value may not contain characters with code "
2362 "higher than 127, but it has character with code %u (0x%02X) "
2363 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2364 warning_flag = true;
2365 }
2366 }
2367 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2368 delete old_str;
2369 break; }
2370 case V_ISO2022STR:
2371 error("ISO-10646 string value cannot be converted to "
2372 "ISO-2022 string");
2373 delete u.ustr.val_ustr;
2374 p_valuetype = V_ERROR;
2375 break;
2376 default:
2377 FATAL_ERROR("Value::set_valuetype()");
2378 } // switch p_valuetype
2379 break;
2380 case V_SEQ:
2381 switch (p_valuetype) {
2382 case V_CHOICE: {
2383 NamedValues *nvs = u.val_nvs;
2384 if (nvs->get_nof_nvs() < 1) {
2385 error("Union value must have one active field");
2386 delete nvs;
2387 valuetype = V_ERROR;
2388 return;
2389 } else if (nvs->get_nof_nvs() > 1) {
2390 error("Only one field was expected in union value instead of %lu",
2391 (unsigned long) nvs->get_nof_nvs());
2392 }
2393 NamedValue *nv = nvs->get_nv_byIndex(0);
2394 u.choice.alt_name = nv->get_name().clone();
2395 u.choice.alt_value = nv->steal_value();
2396 delete nvs;
2397 break;}
2398 case V_SET:
2399 // do nothing
2400 break;
2401 case V_REAL: {
2402 NamedValues *nvs = u.val_nvs;
2403 bool err = false;
2404 /* mantissa */
2405 Int i_mant = 0;
2406 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2407 if (nvs->has_nv_withName(id_mant)) {
2408 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2409 ->get_value_refd_last();
2410 if (v_tmp->get_valuetype() == V_INT) {
2411 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2412 if (*i_mant_int > INT_MAX) {
2413 error("Mantissa `%s' should be less than `%d'",
2414 (i_mant_int->t_str()).c_str(), INT_MAX);
2415 err = true;
2416 } else {
2417 i_mant = i_mant_int->get_val();
2418 }
2419 }
2420 else err = true;
2421 }
2422 else err = true;
2423 /* base */
2424 Int i_base = 0;
2425 Identifier id_base(Identifier::ID_ASN, string("base"));
2426 if (!err && nvs->has_nv_withName(id_base)) {
2427 Value *v = nvs->get_nv_byName(id_base)->get_value();
2428 Value *v_tmp = v->get_value_refd_last();
2429 if (v_tmp->get_valuetype() == V_INT) {
2430 const int_val_t *i_base_int = v_tmp->get_val_Int();
2431 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2432 v->error("Base of the REAL must be 2 or 10");
2433 err = true;
2434 } else {
2435 i_base = i_base_int->get_val();
2436 }
2437 }
2438 else err = true;
2439 }
2440 else err = true;
2441 /* exponent */
2442 Int i_exp = 0;
2443 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2444 if (!err && nvs->has_nv_withName(id_exp)) {
2445 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2446 ->get_value_refd_last();
2447 if (v_tmp->get_valuetype() == V_INT) {
2448 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2449 if (*i_exp_int > INT_MAX) {
2450 error("Exponent `%s' should be less than `%d'",
2451 (i_exp_int->t_str()).c_str(), INT_MAX);
2452 err = true;
2453 } else {
2454 i_exp = i_exp_int->get_val();
2455 }
2456 }
2457 else err = true;
2458 }
2459 else err = true;
2460 /* clean up */
2461 delete nvs;
2462 if (err) {
2463 valuetype = V_ERROR;
2464 return;
2465 }
2466 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2467 static_cast<double>(i_exp));
2468 break; }
2469 default:
2470 FATAL_ERROR("Value::set_valuetype()");
2471 } // switch
2472 break;
2473 case V_SEQOF:
2474 switch (p_valuetype) {
2475 case V_SEQ: {
2476 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2477 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2478 Type *t = my_governor->get_type_refd_last();
2479 switch (t->get_typetype()) {
2480 case Type::T_SEQ_T:
2481 case Type::T_SEQ_A:
2482 break;
2483 default:
2484 FATAL_ERROR("Value::set_valuetype()");
2485 }
2486 Values *vals = u.val_vs;
2487 size_t nof_vals = vals->get_nof_vs();
2488 size_t nof_comps = t->get_nof_comps();
2489 if (nof_vals > nof_comps) {
2490 error("Too many elements in value list notation for type `%s': "
2491 "%lu was expected instead of %lu",
2492 t->get_typename().c_str(),
2493 (unsigned long)nof_comps, (unsigned long)nof_vals);
2494 }
2495 size_t upper_limit;
2496 bool allnotused;
2497 if (nof_vals <= nof_comps) {
2498 upper_limit = nof_vals;
2499 allnotused = true;
2500 } else {
2501 upper_limit = nof_comps;
2502 allnotused = false;
2503 }
2504 u.val_nvs = new NamedValues;
2505 for (size_t i = 0; i < upper_limit; i++) {
2506 Value *v = vals->steal_v_byIndex(i);
2507 if (v->valuetype != V_NOTUSED) {
2508 allnotused = false;
2509 }
2510 NamedValue *nv =
2511 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2512 nv->set_location(*v);
2513 u.val_nvs->add_nv(nv);
2514 }
2515 u.val_nvs->set_my_scope(get_my_scope());
2516 u.val_nvs->set_fullname(get_fullname());
2517 delete vals;
2518 if (allnotused && nof_vals > 0)
2519 warning("All elements of value list notation for type `%s' are not "
2520 "used symbols (`-')", t->get_typename().c_str());
2521 break; }
2522 case V_SET:
2523 // { } -> empty set value
2524 if (u.val_vs->get_nof_vs() != 0)
2525 FATAL_ERROR("Value::set_valuetype()");
2526 delete u.val_vs;
2527 u.val_nvs = new NamedValues;
2528 break;
2529 case V_SETOF:
2530 case V_ARRAY:
2531 // SEQOF -> SETOF or ARRAY: trivial
2532 break;
2533 default:
2534 FATAL_ERROR("Value::set_valuetype()");
2535 }
2536 break;
2537 case V_TTCN3_NULL:
2538 switch (p_valuetype) {
2539 case V_DEFAULT_NULL:
2540 break;
2541 case V_FAT_NULL:
2542 break;
2543 default:
2544 FATAL_ERROR("Value::set_valuetype()");
2545 }
2546 break;
2547 case V_NOTUSED:
2548 if (V_OMIT != p_valuetype) { // in case of implicit omit
2549 FATAL_ERROR("Value::set_valuetype()");
2550 }
2551 break;
2552 default:
2553 FATAL_ERROR("Value::set_valuetype()");
2554 } // switch
2555 valuetype=p_valuetype;
2556 }
2557
2558 void Value::set_valuetype_COMP_NULL()
2559 {
2560 if(valuetype == V_ERROR) return;
2561 if(valuetype==V_TTCN3_NULL) {
2562 valuetype=V_EXPR;
2563 u.expr.v_optype=OPTYPE_COMP_NULL;
2564 // Nothing to check.
2565 u.expr.state=EXPR_CHECKED;
2566 }
2567 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2568 }
2569
2570 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2571 {
2572 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2573 delete u.val_id;
2574 u.val_Int = new int_val_t(p_val_int);
2575 valuetype = V_INT;
2576 } else FATAL_ERROR("Value::set_valuetype()");
2577 }
2578
2579 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2580 {
2581 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2582 clean_up();
2583 valuetype = V_BSTR;
2584 set_val_str(p_str);
2585 } else FATAL_ERROR("Value::set_valuetype()");
2586 }
2587
2588 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2589 {
2590 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2591 delete u.val_id;
2592 u.val_id = p_id;
2593 valuetype = V_ENUM;
2594 } else FATAL_ERROR("Value::set_valuetype()");
2595 }
2596
2597 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2598 {
2599 switch (p_valuetype) {
2600 case V_FUNCTION:
2601 case V_ALTSTEP:
2602 case V_TESTCASE:
2603 if (valuetype == V_REFER && p_ass) break;
2604 // no break
2605 default:
2606 FATAL_ERROR("Value::set_valuetype()");
2607 }
2608 delete u.refered;
2609 u.refd_fat = p_ass;
2610 valuetype = p_valuetype;
2611 }
2612
2613 bool Value::is_undef_lowerid()
2614 {
2615 switch (valuetype) {
2616 case V_UNDEF_LOWERID:
2617 return true;
2618 case V_EXPR:
2619 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2620 !u.expr.ti1->get_DerivedRef()) {
2621 return u.expr.ti1->get_Template()->is_undef_lowerid();
2622 }
2623 // no break
2624 default:
2625 return false;
2626 }
2627 }
2628
2629 const Identifier& Value::get_undef_lowerid()
2630 {
2631 switch (valuetype) {
2632 case V_UNDEF_LOWERID:
2633 return *u.val_id;
2634 case V_EXPR:
2635 if (u.expr.v_optype != OPTYPE_VALUEOF)
2636 FATAL_ERROR("Value::get_undef_lowerid()");
2637 return u.expr.ti1->get_Template()->get_specific_value()
2638 ->get_undef_lowerid();
2639 default:
2640 FATAL_ERROR("Value::get_undef_lowerid()");
2641 }
2642 const Identifier *dummy = 0;
2643 return *dummy;
2644 }
2645
2646 void Value::set_lowerid_to_ref()
2647 {
2648 switch (valuetype) {
2649 case V_UNDEF_LOWERID:
2650 set_valuetype(V_REFD);
2651 break;
2652 case V_EXPR:
2653 // if the governor of the expression is not known (in log(), etc...)
2654 // then the governor is taken from the reference (using
2655 // v1/ti1->get_expr_governor()), but that runs before the
2656 // params were checked, this smells like a workaround :)
2657 switch (u.expr.v_optype) {
2658 case OPTYPE_ROTL:
2659 case OPTYPE_ROTR:
2660 u.expr.v1->set_lowerid_to_ref();
2661 break;
2662 case OPTYPE_CONCAT:
2663 u.expr.v1->set_lowerid_to_ref();
2664 u.expr.v2->set_lowerid_to_ref();
2665 break;
2666 case OPTYPE_VALUEOF:
2667 case OPTYPE_ISVALUE:
2668 case OPTYPE_ISBOUND:
2669 case OPTYPE_ISPRESENT:
2670 case OPTYPE_SUBSTR:
2671 case OPTYPE_REGEXP:
2672 case OPTYPE_REPLACE:
2673 case OPTYPE_TTCN2STRING:
2674 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2675 Error_Context cntxt(u.expr.ti1->get_Template(),
2676 "In the operand of operation `%s'",
2677 get_opname());
2678 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2679 }
2680 if (u.expr.v_optype==OPTYPE_REGEXP) {
2681 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2682 Error_Context cntxt(u.expr.t2->get_Template(),
2683 "In the operand of operation `%s'",
2684 get_opname());
2685 u.expr.t2->get_Template()->set_lowerid_to_ref();
2686 }
2687 }
2688 if (u.expr.v_optype==OPTYPE_REPLACE) {
2689 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2690 Error_Context cntxt(u.expr.ti4->get_Template(),
2691 "In the operand of operation `%s'",
2692 get_opname());
2693 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2694 }
2695 }
2696 break;
2697 default:
2698 break;
2699 }
2700 break;
2701 default:
2702 break;
2703 }
2704 }
2705
2706 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2707 {
2708 switch (valuetype) {
2709 case V_CHARSYMS:
2710 case V_CHOICE:
2711 case V_SEQOF:
2712 case V_SETOF:
2713 case V_ARRAY:
2714 case V_SEQ:
2715 case V_SET:
2716 case V_UNDEF_LOWERID:
2717 case V_UNDEF_BLOCK:
2718 case V_OMIT:
2719 case V_TTCN3_NULL:
2720 case V_NOTUSED:
2721 case V_REFER:
2722 case V_FAT_NULL:
2723 return Type::T_UNDEF;
2724 case V_NAMEDINT:
2725 case V_NAMEDBITS:
2726 case V_OPENTYPE:
2727 FATAL_ERROR("Value::get_expr_returntype()");
2728 case V_ERROR:
2729 return Type::T_ERROR;
2730 case V_REFD:
2731 case V_INVOKE: {
2732 Type *t = get_expr_governor(exp_val);
2733 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2734 else return Type::T_ERROR; }
2735 case V_FUNCTION:
2736 return Type::T_FUNCTION;
2737 case V_ALTSTEP:
2738 return Type::T_ALTSTEP;
2739 case V_TESTCASE:
2740 return Type::T_TESTCASE;
2741 case V_EXPR:
2742 switch(u.expr.v_optype) {
2743 case OPTYPE_COMP_NULL:
2744 case OPTYPE_COMP_MTC:
2745 case OPTYPE_COMP_SYSTEM:
2746 case OPTYPE_COMP_SELF:
2747 case OPTYPE_COMP_CREATE:
2748 return Type::T_COMPONENT;
2749 case OPTYPE_UNDEF_RUNNING:
2750 case OPTYPE_COMP_RUNNING:
2751 case OPTYPE_COMP_RUNNING_ANY:
2752 case OPTYPE_COMP_RUNNING_ALL:
2753 case OPTYPE_COMP_ALIVE:
2754 case OPTYPE_COMP_ALIVE_ANY:
2755 case OPTYPE_COMP_ALIVE_ALL:
2756 case OPTYPE_TMR_RUNNING:
2757 case OPTYPE_TMR_RUNNING_ANY:
2758 case OPTYPE_MATCH:
2759 case OPTYPE_EQ:
2760 case OPTYPE_LT:
2761 case OPTYPE_GT:
2762 case OPTYPE_NE:
2763 case OPTYPE_GE:
2764 case OPTYPE_LE:
2765 case OPTYPE_NOT:
2766 case OPTYPE_AND:
2767 case OPTYPE_OR:
2768 case OPTYPE_XOR:
2769 case OPTYPE_ISPRESENT:
2770 case OPTYPE_ISCHOSEN:
2771 case OPTYPE_ISCHOSEN_V:
2772 case OPTYPE_ISCHOSEN_T:
2773 case OPTYPE_ISVALUE:
2774 case OPTYPE_ISBOUND:
2775 case OPTYPE_PROF_RUNNING:
2776 return Type::T_BOOL;
2777 case OPTYPE_GETVERDICT:
2778 return Type::T_VERDICT;
2779 case OPTYPE_VALUEOF: {
2780 Error_Context cntxt(this, "In the operand of operation `%s'",
2781 get_opname());
2782 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2783 case OPTYPE_TMR_READ:
2784 case OPTYPE_INT2FLOAT:
2785 case OPTYPE_STR2FLOAT:
2786 case OPTYPE_RND:
2787 case OPTYPE_RNDWITHVAL:
2788 return Type::T_REAL;
2789 case OPTYPE_ACTIVATE:
2790 return Type::T_DEFAULT;
2791 case OPTYPE_ACTIVATE_REFD:
2792 return Type::T_DEFAULT;
2793 case OPTYPE_EXECUTE:
2794 case OPTYPE_EXECUTE_REFD:
2795 return Type::T_VERDICT;
2796 case OPTYPE_UNARYPLUS: // v1
2797 case OPTYPE_UNARYMINUS: {
2798 Type::typetype_t tmp_tt;
2799 {
2800 Error_Context cntxt(this, "In the operand of operation `%s'",
2801 get_opname());
2802 u.expr.v1->set_lowerid_to_ref();
2803 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2804 }
2805 switch(tmp_tt) {
2806 case Type::T_INT:
2807 case Type::T_REAL:
2808 return tmp_tt;
2809 default:
2810 get_value_refd_last(); // to report the error
2811 return Type::T_ERROR;
2812 } // switch tmp_tt
2813 }
2814 case OPTYPE_ADD: // v1 v2
2815 case OPTYPE_SUBTRACT:
2816 case OPTYPE_MULTIPLY:
2817 case OPTYPE_DIVIDE: {
2818 Type::typetype_t tmp_tt;
2819 {
2820 Error_Context cntxt(this, "In the left operand of operation `%s'",
2821 get_opname());
2822 u.expr.v1->set_lowerid_to_ref();
2823 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2824 }
2825 switch(tmp_tt) {
2826 case Type::T_INT:
2827 case Type::T_REAL:
2828 return tmp_tt;
2829 default:
2830 if(u.expr.v_optype==OPTYPE_ADD) {
2831 Type::typetype_t tmp_tt2;
2832 {
2833 Error_Context cntxt(this, "In the right operand of operation `%s'",
2834 get_opname());
2835 u.expr.v2->set_lowerid_to_ref();
2836 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2837 }
2838 Type::typetype_t ret_val=Type::T_ERROR;
2839 bool maybeconcat=false;
2840 switch(tmp_tt) {
2841 case Type::T_BSTR:
2842 case Type::T_HSTR:
2843 case Type::T_OSTR:
2844 if(tmp_tt2==tmp_tt) {
2845 maybeconcat=true;
2846 ret_val=tmp_tt;
2847 }
2848 break;
2849 case Type::T_CSTR:
2850 case Type::T_USTR:
2851 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2852 maybeconcat=true;
2853 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2854 ret_val=Type::T_USTR;
2855 else ret_val=Type::T_CSTR;
2856 }
2857 break;
2858 default:
2859 break;
2860 }
2861 if(maybeconcat) {
2862 error("Did you mean the concat operation (`&') instead of"
2863 " addition operator (`+')?");
2864 u.expr.v_optype=OPTYPE_CONCAT;
2865 return ret_val;
2866 }
2867 }
2868 get_value_refd_last(); // to report the error
2869 return Type::T_ERROR;
2870 } // switch tmp_tt
2871 }
2872 case OPTYPE_NOT4B: // v1
2873 case OPTYPE_AND4B: // v1 v2
2874 case OPTYPE_OR4B:
2875 case OPTYPE_XOR4B:
2876 case OPTYPE_SHL:
2877 case OPTYPE_SHR: {
2878 Type::typetype_t tmp_tt;
2879 {
2880 Error_Context cntxt(this, "In the %soperand of operation `%s'",
2881 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
2882 get_opname());
2883 u.expr.v1->set_lowerid_to_ref();
2884 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2885 }
2886 switch(tmp_tt) {
2887 case Type::T_BSTR:
2888 case Type::T_HSTR:
2889 case Type::T_OSTR:
2890 return tmp_tt;
2891 default:
2892 get_value_refd_last(); // to report the error
2893 return Type::T_ERROR;
2894 } // switch tmp_tt
2895 }
2896 case OPTYPE_ROTL: // v1 v2
2897 case OPTYPE_ROTR: {
2898 Type::typetype_t tmp_tt;
2899 {
2900 Error_Context cntxt(this, "In the %s operand of operation `%s'",
2901 u.expr.v_optype==OPTYPE_ROTL
2902 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
2903 get_opname());
2904 u.expr.v1->set_lowerid_to_ref();
2905 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2906 }
2907 switch(tmp_tt) {
2908 case Type::T_BSTR:
2909 case Type::T_HSTR:
2910 case Type::T_OSTR:
2911 case Type::T_CSTR:
2912 case Type::T_USTR:
2913 case Type::T_SETOF:
2914 case Type::T_SEQOF:
2915 case Type::T_ARRAY:
2916 return tmp_tt;
2917 default:
2918 get_value_refd_last(); // to report the error
2919 return Type::T_ERROR;
2920 } // switch tmp_tt
2921 }
2922 case OPTYPE_SUBSTR:
2923 case OPTYPE_REPLACE: {
2924 Type::typetype_t tmp_tt;
2925 {
2926 Error_Context cntxt(this, "In the operand of operation `%s'",
2927 get_opname());
2928 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2929 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2930 }
2931 switch (tmp_tt) {
2932 case Type::T_BSTR:
2933 case Type::T_HSTR:
2934 case Type::T_OSTR:
2935 case Type::T_CSTR:
2936 case Type::T_USTR:
2937 case Type::T_SETOF:
2938 case Type::T_SEQOF:
2939 return tmp_tt;
2940 default:
2941 get_value_refd_last(); // to report the error
2942 return Type::T_ERROR;
2943 }
2944 }
2945 case OPTYPE_REGEXP: {
2946 Type::typetype_t tmp_tt;
2947 {
2948 Error_Context cntxt(this, "In the first operand of operation `%s'",
2949 get_opname());
2950 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2951 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2952 }
2953 switch(tmp_tt) {
2954 case Type::T_CSTR:
2955 case Type::T_USTR:
2956 return tmp_tt;
2957 default:
2958 get_value_refd_last(); // to report the error
2959 return Type::T_ERROR;
2960 } // switch tmp_tt
2961 }
2962 case OPTYPE_CONCAT: { // v1 v2
2963 Type::typetype_t tmp_tt;
2964 {
2965 Error_Context cntxt(this, "In the first operand of operation `%s'",
2966 get_opname());
2967 u.expr.v1->set_lowerid_to_ref();
2968 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2969 }
2970 switch(tmp_tt) {
2971 case Type::T_CSTR:
2972 case Type::T_USTR:
2973 case Type::T_BSTR:
2974 case Type::T_HSTR:
2975 case Type::T_OSTR:
2976 case Type::T_SETOF:
2977 case Type::T_SEQOF:
2978 return tmp_tt;
2979 default:
2980 get_value_refd_last(); // to report the error
2981 return Type::T_ERROR;
2982 } // switch tmp_tt
2983 }
2984 case OPTYPE_MOD:
2985 case OPTYPE_REM:
2986 case OPTYPE_CHAR2INT:
2987 case OPTYPE_UNICHAR2INT:
2988 case OPTYPE_BIT2INT:
2989 case OPTYPE_HEX2INT:
2990 case OPTYPE_OCT2INT:
2991 case OPTYPE_STR2INT:
2992 case OPTYPE_FLOAT2INT:
2993 case OPTYPE_LENGTHOF:
2994 case OPTYPE_SIZEOF:
2995 case OPTYPE_DECODE:
2996 case OPTYPE_ENUM2INT:
2997 return Type::T_INT;
2998 case OPTYPE_BIT2STR:
2999 case OPTYPE_FLOAT2STR:
3000 case OPTYPE_HEX2STR:
3001 case OPTYPE_INT2CHAR:
3002 case OPTYPE_INT2STR:
3003 case OPTYPE_OCT2CHAR:
3004 case OPTYPE_OCT2STR:
3005 case OPTYPE_UNICHAR2CHAR:
3006 case OPTYPE_LOG2STR:
3007 case OPTYPE_TESTCASENAME:
3008 case OPTYPE_TTCN2STRING:
3009 case OPTYPE_GET_STRINGENCODING:
3010 case OPTYPE_ENCODE_BASE64:
3011 return Type::T_CSTR;
3012 case OPTYPE_INT2UNICHAR:
3013 case OPTYPE_OCT2UNICHAR:
3014 return Type::T_USTR;
3015 case OPTYPE_INT2BIT:
3016 case OPTYPE_HEX2BIT:
3017 case OPTYPE_OCT2BIT:
3018 case OPTYPE_STR2BIT:
3019 case OPTYPE_ENCODE:
3020 return Type::T_BSTR;
3021 case OPTYPE_INT2HEX:
3022 case OPTYPE_BIT2HEX:
3023 case OPTYPE_OCT2HEX:
3024 case OPTYPE_STR2HEX:
3025 return Type::T_HSTR;
3026 case OPTYPE_INT2OCT:
3027 case OPTYPE_CHAR2OCT:
3028 case OPTYPE_HEX2OCT:
3029 case OPTYPE_BIT2OCT:
3030 case OPTYPE_STR2OCT:
3031 case OPTYPE_UNICHAR2OCT:
3032 case OPTYPE_REMOVE_BOM:
3033 case OPTYPE_DECODE_BASE64:
3034 return Type::T_OSTR;
3035 case OPTYPE_DECOMP:
3036 return Type::T_OID;
3037 default:
3038 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3039 // to avoid warning
3040 return Type::T_ERROR;
3041 } // switch optype
3042 case V_MACRO:
3043 switch (u.macro) {
3044 case MACRO_MODULEID:
3045 case MACRO_FILENAME:
3046 case MACRO_BFILENAME:
3047 case MACRO_FILEPATH:
3048 case MACRO_LINENUMBER:
3049 case MACRO_DEFINITIONID:
3050 case MACRO_SCOPE:
3051 case MACRO_TESTCASEID:
3052 return Type::T_CSTR;
3053 case MACRO_LINENUMBER_C:
3054 return Type::T_INT;
3055 default:
3056 return Type::T_ERROR;
3057 }
3058 case V_NULL:
3059 return Type::T_NULL;
3060 case V_BOOL:
3061 return Type::T_BOOL;
3062 case V_INT:
3063 return Type::T_INT;
3064 case V_REAL:
3065 return Type::T_REAL;
3066 case V_ENUM:
3067 return Type::T_ENUM_T;
3068 case V_BSTR:
3069 return Type::T_BSTR;
3070 case V_HSTR:
3071 return Type::T_HSTR;
3072 case V_OSTR:
3073 return Type::T_OSTR;
3074 case V_CSTR:
3075 return Type::T_CSTR;
3076 case V_USTR:
3077 return Type::T_USTR;
3078 case V_ISO2022STR:
3079 return Type::T_GENERALSTRING;
3080 case V_OID:
3081 return Type::T_OID;
3082 case V_ROID:
3083 return Type::T_ROID;
3084 case V_VERDICT:
3085 return Type::T_VERDICT;
3086 case V_DEFAULT_NULL:
3087 return Type::T_DEFAULT;
3088 default:
3089 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3090 // to avoid warning
3091 return Type::T_ERROR;
3092 } // switch
3093 }
3094
3095 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3096 {
3097 if(my_governor) return my_governor;
3098 switch (valuetype) {
3099 case V_INVOKE: {
3100 Type *t = u.invoke.v->get_expr_governor(exp_val);
3101 if(!t) {
3102 if(u.invoke.v->get_valuetype() != V_ERROR)
3103 u.invoke.v->error("A value of type function expected");
3104 goto error;
3105 }
3106 t = t->get_type_refd_last();
3107 switch(t->get_typetype()) {
3108 case Type::T_FUNCTION: {
3109 Type *t_return_type = t->get_function_return_type();
3110 if (!t_return_type) {
3111 error("Reference to a %s was expected instead of invocation "
3112 "of behavior type `%s' with no return type",
3113 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3114 t->get_fullname().c_str());
3115 goto error;
3116 }
3117 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3118 error("Reference to a value was expected, but functions of type "
3119 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3120 t_return_type->get_typename().c_str());
3121 goto error;
3122 }
3123 return t_return_type; }
3124 case Type::T_ALTSTEP:
3125 goto error;
3126 default:
3127 u.invoke.v->error("A value of type function expected instead of `%s'",
3128 t->get_typename().c_str());
3129 goto error;
3130 }
3131 break; }
3132 case V_REFD: {
3133 Assignment *ass=u.ref.ref->get_refd_assignment();
3134 Type *tmp_type=0;
3135 if (!ass) goto error;
3136 switch (ass->get_asstype()) {
3137 case Assignment::A_CONST:
3138 case Assignment::A_EXT_CONST:
3139 case Assignment::A_MODULEPAR:
3140 case Assignment::A_MODULEPAR_TEMP:
3141 case Assignment::A_TEMPLATE:
3142 case Assignment::A_VAR:
3143 case Assignment::A_VAR_TEMPLATE:
3144 case Assignment::A_FUNCTION_RVAL:
3145 case Assignment::A_FUNCTION_RTEMP:
3146 case Assignment::A_EXT_FUNCTION_RVAL:
3147 case Assignment::A_EXT_FUNCTION_RTEMP:
3148 case Assignment::A_PAR_VAL_IN:
3149 case Assignment::A_PAR_VAL_OUT:
3150 case Assignment::A_PAR_VAL_INOUT:
3151 case Assignment::A_PAR_TEMPL_IN:
3152 case Assignment::A_PAR_TEMPL_OUT:
3153 case Assignment::A_PAR_TEMPL_INOUT:
3154 tmp_type=ass->get_Type();
3155 break;
3156 case Assignment::A_FUNCTION:
3157 case Assignment::A_EXT_FUNCTION:
3158 error("Reference to a %s was expected instead of a call of %s, which "
3159 "does not have return type",
3160 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3161 ass->get_description().c_str());
3162 goto error;
3163 default:
3164 error("Reference to a %s was expected instead of %s",
3165 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3166 ass->get_description().c_str());
3167 goto error;
3168 } // end switch
3169 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3170 if(!tmp_type) goto error;
3171 return tmp_type; }
3172 case V_EXPR:
3173 switch (u.expr.v_optype) {
3174 case OPTYPE_VALUEOF:
3175 case OPTYPE_SUBSTR:
3176 case OPTYPE_REGEXP:
3177 case OPTYPE_REPLACE:{
3178 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3179 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3180 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3181 return tmp_type;
3182 }
3183 case OPTYPE_ROTL:
3184 case OPTYPE_ROTR:
3185 return u.expr.v1->get_expr_governor(exp_val);
3186 case OPTYPE_CONCAT:
3187 return get_expr_governor_v1v2(exp_val);
3188 case OPTYPE_COMP_MTC:
3189 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3190 else return 0;
3191 case OPTYPE_COMP_SYSTEM:
3192 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3193 else return 0;
3194 case OPTYPE_COMP_SELF:
3195 if (my_scope) {
3196 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3197 if (t_ros) return t_ros->get_component_type();
3198 else return 0;
3199 } else return 0;
3200 case OPTYPE_COMP_CREATE:
3201 return chk_expr_operand_comptyperef_create();
3202 default:
3203 break;
3204 }
3205 // no break
3206 default:
3207 return Type::get_pooltype(get_expr_returntype(exp_val));
3208 }
3209 error:
3210 set_valuetype(V_ERROR);
3211 return 0;
3212 }
3213
3214 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3215 {
3216 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3217 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3218 if (v1_gov) {
3219 if (v2_gov) { // both have governors
3220 // return the type that is compatible with both (if there is no type mismatch)
3221 if (v1_gov->is_compatible(v2_gov, NULL))
3222 return v1_gov;
3223 else return v2_gov;
3224 } else return v1_gov;
3225 } else { // v1 has no governor
3226 if (v2_gov) return v2_gov;
3227 else return NULL; // neither has governor
3228 }
3229 }
3230
3231 Type *Value::get_expr_governor_last()
3232 {
3233 Value *v_last = get_value_refd_last();
3234 if (v_last->valuetype == V_ERROR) return 0;
3235 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3236 if(!t) return 0;
3237 return t->get_type_refd_last();
3238 }
3239
3240 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3241 {
3242 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3243 return u.invoke.v->get_expr_governor(exp_val);
3244 }
3245
3246 const char* Value::get_opname() const
3247 {
3248 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3249 switch(u.expr.v_optype) {
3250 case OPTYPE_RND: // -
3251 return "rnd()";
3252 case OPTYPE_COMP_NULL:
3253 return "(component) null";
3254 case OPTYPE_COMP_MTC:
3255 return "mtc";
3256 case OPTYPE_COMP_SYSTEM:
3257 return "system";
3258 case OPTYPE_COMP_SELF:
3259 return "self";
3260 case OPTYPE_COMP_RUNNING_ANY:
3261 return "any component.running";
3262 case OPTYPE_COMP_RUNNING_ALL:
3263 return "all component.running";
3264 case OPTYPE_COMP_ALIVE_ANY:
3265 return "any component.alive";
3266 case OPTYPE_COMP_ALIVE_ALL:
3267 return "all component.alive";
3268 case OPTYPE_TMR_RUNNING_ANY:
3269 return "any timer.running";
3270 case OPTYPE_GETVERDICT:
3271 return "getverdict()";
3272 case OPTYPE_TESTCASENAME:
3273 return "testcasename()";
3274 case OPTYPE_UNARYPLUS: // v1
3275 return "unary +";
3276 case OPTYPE_UNARYMINUS:
3277 return "unary -";
3278 case OPTYPE_NOT:
3279 return "not";
3280 case OPTYPE_NOT4B:
3281 return "not4b";
3282 case OPTYPE_BIT2HEX:
3283 return "bit2hex()";
3284 case OPTYPE_BIT2INT:
3285 return "bit2int()";
3286 case OPTYPE_BIT2OCT:
3287 return "bit2oct()";
3288 case OPTYPE_BIT2STR:
3289 return "bit2str()";
3290 case OPTYPE_CHAR2INT:
3291 return "char2int()";
3292 case OPTYPE_CHAR2OCT:
3293 return "char2oct()";
3294 case OPTYPE_FLOAT2INT:
3295 return "float2int()";
3296 case OPTYPE_FLOAT2STR:
3297 return "float2str()";
3298 case OPTYPE_HEX2BIT:
3299 return "hex2bit()";
3300 case OPTYPE_HEX2INT:
3301 return "hex2int()";
3302 case OPTYPE_HEX2OCT:
3303 return "hex2oct()";
3304 case OPTYPE_HEX2STR:
3305 return "hex2str()";
3306 case OPTYPE_INT2CHAR:
3307 return "int2char()";
3308 case OPTYPE_INT2FLOAT:
3309 return "int2float()";
3310 case OPTYPE_INT2STR:
3311 return "int2str()";
3312 case OPTYPE_INT2UNICHAR:
3313 return "int2unichar()";
3314 case OPTYPE_OCT2BIT:
3315 return "oct2bit()";
3316 case OPTYPE_OCT2CHAR:
3317 return "oct2char()";
3318 case OPTYPE_OCT2HEX:
3319 return "oct2hex()";
3320 case OPTYPE_OCT2INT:
3321 return "oct2int()";
3322 case OPTYPE_OCT2STR:
3323 return "oct2str()";
3324 case OPTYPE_STR2BIT:
3325 return "str2bit()";
3326 case OPTYPE_STR2FLOAT:
3327 return "str2float()";
3328 case OPTYPE_STR2HEX:
3329 return "str2hex()";
3330 case OPTYPE_STR2INT:
3331 return "str2int()";
3332 case OPTYPE_STR2OCT:
3333 return "str2oct()";
3334 case OPTYPE_UNICHAR2INT:
3335 return "unichar2int()";
3336 case OPTYPE_UNICHAR2CHAR:
3337 return "unichar2char()";
3338 case OPTYPE_UNICHAR2OCT:
3339 return "unichar2oct()";
3340 case OPTYPE_ENUM2INT:
3341 return "enum2int()";
3342 case OPTYPE_LENGTHOF:
3343 return "lengthof()";
3344 case OPTYPE_SIZEOF:
3345 return "sizeof()";
3346 case OPTYPE_RNDWITHVAL:
3347 return "rnd (seed)";
3348 case OPTYPE_ENCODE:
3349 return "encvalue()";
3350 case OPTYPE_DECODE:
3351 return "decvalue()";
3352 case OPTYPE_GET_STRINGENCODING:
3353 return "get_stringencoding()";
3354 case OPTYPE_REMOVE_BOM:
3355 return "remove_bom()";
3356 case OPTYPE_ENCODE_BASE64:
3357 return "encode_base64()";
3358 case OPTYPE_DECODE_BASE64:
3359 return "decode_base64()";
3360 case OPTYPE_ADD: // v1 v2
3361 return "+";
3362 case OPTYPE_SUBTRACT:
3363 return "-";
3364 case OPTYPE_MULTIPLY:
3365 return "*";
3366 case OPTYPE_DIVIDE:
3367 return "/";
3368 case OPTYPE_MOD:
3369 return "mod";
3370 case OPTYPE_REM:
3371 return "rem";
3372 case OPTYPE_CONCAT:
3373 return "&";
3374 case OPTYPE_EQ:
3375 return "==";
3376 case OPTYPE_LT:
3377 return "<";
3378 case OPTYPE_GT:
3379 return ">";
3380 case OPTYPE_NE:
3381 return "!=";
3382 case OPTYPE_GE:
3383 return ">=";
3384 case OPTYPE_LE:
3385 return "<=";
3386 case OPTYPE_AND:
3387 return "and";
3388 case OPTYPE_OR:
3389 return "or";
3390 case OPTYPE_XOR:
3391 return "xor";
3392 case OPTYPE_AND4B:
3393 return "and4b";
3394 case OPTYPE_OR4B:
3395 return "or4b";
3396 case OPTYPE_XOR4B:
3397 return "xor4b";
3398 case OPTYPE_SHL:
3399 return "<<";
3400 case OPTYPE_SHR:
3401 return ">>";
3402 case OPTYPE_ROTL:
3403 return "<@";
3404 case OPTYPE_ROTR:
3405 return "@>";
3406 case OPTYPE_INT2BIT:
3407 return "int2bit()";
3408 case OPTYPE_INT2HEX:
3409 return "int2hex()";
3410 case OPTYPE_INT2OCT:
3411 return "int2oct()";
3412 case OPTYPE_OCT2UNICHAR:
3413 return "oct2unichar()";
3414 case OPTYPE_SUBSTR:
3415 return "substr()";
3416 case OPTYPE_REGEXP:
3417 return "regexp()";
3418 case OPTYPE_DECOMP:
3419 return "decomp()";
3420 case OPTYPE_REPLACE:
3421 return "replace()";
3422 case OPTYPE_VALUEOF: // t1
3423 return "valueof()";
3424 case OPTYPE_UNDEF_RUNNING:
3425 return "<timer or component> running";
3426 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3427 return "create()";
3428 case OPTYPE_COMP_RUNNING: // v1
3429 return "component running";
3430 case OPTYPE_COMP_ALIVE: // v1
3431 return "alive";
3432 case OPTYPE_TMR_READ:
3433 return "timer read";
3434 case OPTYPE_TMR_RUNNING:
3435 return "timer running";
3436 case OPTYPE_ACTIVATE:
3437 return "activate()";
3438 case OPTYPE_ACTIVATE_REFD:
3439 return "activate()";
3440 case OPTYPE_EXECUTE: // r1 [v2]
3441 case OPTYPE_EXECUTE_REFD:
3442 return "execute()";
3443 case OPTYPE_MATCH: // v1 t2
3444 return "match()";
3445 case OPTYPE_ISPRESENT:
3446 return "ispresent()";
3447 case OPTYPE_ISCHOSEN:
3448 case OPTYPE_ISCHOSEN_V:
3449 case OPTYPE_ISCHOSEN_T:
3450 return "ischosen()";
3451 case OPTYPE_ISVALUE:
3452 return "isvalue()";
3453 case OPTYPE_ISBOUND:
3454 return "isbound()";
3455 case OPTYPE_LOG2STR:
3456 return "log2str()";
3457 case OPTYPE_TTCN2STRING:
3458 return "ttcn2string()";
3459 case OPTYPE_PROF_RUNNING:
3460 return "@profiler.running";
3461 default:
3462 FATAL_ERROR("Value::get_opname()");
3463 } // switch
3464 }
3465
3466 void Value::chk_expr_ref_ischosen()
3467 {
3468 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3469 Ttcn::Ref_base *tmpref=u.expr.r1;
3470 Assignment *ass=tmpref->get_refd_assignment();
3471 if (!ass) {
3472 set_valuetype(V_ERROR);
3473 return;
3474 }
3475 // Now we know whether the argument of ischosen() is a value or template.
3476 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3477 // or template (OPTYPE_ISCHOSEN_T).
3478 switch (ass->get_asstype()) {
3479 case Assignment::A_CONST:
3480 case Assignment::A_EXT_CONST:
3481 case Assignment::A_MODULEPAR:
3482 case Assignment::A_VAR:
3483 case Assignment::A_PAR_VAL_IN:
3484 case Assignment::A_PAR_VAL_OUT:
3485 case Assignment::A_PAR_VAL_INOUT:
3486 u.expr.v1=new Value(V_REFD, tmpref);
3487 u.expr.v1->set_location(*tmpref);
3488 u.expr.v1->set_my_scope(get_my_scope());
3489 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3490 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3491 break;
3492 case Assignment::A_MODULEPAR_TEMP:
3493 case Assignment::A_TEMPLATE:
3494 case Assignment::A_VAR_TEMPLATE:
3495 case Assignment::A_PAR_TEMPL_IN:
3496 case Assignment::A_PAR_TEMPL_OUT:
3497 case Assignment::A_PAR_TEMPL_INOUT:
3498 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3499 u.expr.t1->set_location(*tmpref);
3500 u.expr.t1->set_my_scope(get_my_scope());
3501 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3502 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3503 break;
3504 default:
3505 tmpref->error("Reference to a value or template was expected instead of "
3506 "%s", ass->get_description().c_str());
3507 set_valuetype(V_ERROR);
3508 break;
3509 } // switch
3510 }
3511
3512 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3513 Type::expected_value_t exp_val)
3514 {
3515 v->set_lowerid_to_ref(); // can only be reference to enum
3516 Type *t = v->get_expr_governor(exp_val);
3517 if (v->valuetype==V_ERROR) return;
3518 if (!t) {
3519 v->error("Please use reference to an enumerated value as the operand of "
3520 "operation `%s'", get_opname());
3521 set_valuetype(V_ERROR);
3522 return;
3523 }
3524 t = t->get_type_refd_last();
3525 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3526 v->error("The operand of operation `%s' should be enumerated value", opname);
3527 set_valuetype(V_ERROR);
3528 }
3529 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3530 v->error("The operand of operation `%s' cannot be omit", opname);
3531 set_valuetype(V_ERROR);
3532 }
3533 }
3534
3535 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3536 const char *opnum,
3537 const char *opname,
3538 const Location *loc)
3539 {
3540 if(tt==Type::T_BOOL) return;
3541 if(tt!=Type::T_ERROR)
3542 loc->error("%s operand of operation `%s' should be boolean value",
3543 opnum, opname);
3544 set_valuetype(V_ERROR);
3545 }
3546
3547 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3548 const char *opnum,
3549 const char *opname,
3550 const Location *loc)
3551 {
3552 if(tt==Type::T_INT) return;
3553 if(tt!=Type::T_ERROR)
3554 loc->error("%s operand of operation `%s' should be integer value",
3555 opnum, opname);
3556 set_valuetype(V_ERROR);
3557 }
3558
3559 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3560 const char *opnum,
3561 const char *opname,
3562 const Location *loc)
3563 {
3564 if(tt==Type::T_REAL) return;
3565 else if(tt==Type::T_INT)
3566 loc->error("%s operand of operation `%s' should be float value."
3567 " Perhaps you missed an int2float() conversion function"
3568 " or `.0' at the end of the number",
3569 opnum, opname);
3570 else if(tt!=Type::T_ERROR)
3571 loc->error("%s operand of operation `%s' should be float value",
3572 opnum, opname);
3573 set_valuetype(V_ERROR);
3574 }
3575
3576 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3577 const char *opnum,
3578 const char *opname,
3579 const Location *loc)
3580 {
3581 switch(tt) {
3582 case Type::T_INT:
3583 case Type::T_REAL:
3584 return;
3585 default:
3586 break;
3587 }
3588 if(tt!=Type::T_ERROR)
3589 loc->error("%s operand of operation `%s' should be integer"
3590 " or float value",
3591 opnum, opname);
3592 set_valuetype(V_ERROR);
3593 }
3594
3595 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3596 const char *opnum,
3597 const char *opname,
3598 const Location *loc)
3599 {
3600 switch(tt) {
3601 case Type::T_INT:
3602 case Type::T_REAL:
3603 case Type::T_ENUM_T:
3604 return;
3605 default:
3606 break;
3607 }
3608 if(tt!=Type::T_ERROR)
3609 loc->error("%s operand of operation `%s' should be integer, float"
3610 " or enumerated value", opnum, opname);
3611 set_valuetype(V_ERROR);
3612 }
3613
3614 void Value::chk_expr_operandtype_list(Type* t,
3615 const char *opnum,
3616 const char *opname,
3617 const Location *loc,
3618 bool allow_array)
3619 {
3620 if (valuetype == V_ERROR) return;
3621 if (t->get_typetype() == Type::T_ERROR) {
3622 set_valuetype(V_ERROR);
3623 return;
3624 }
3625 if (!t->is_list_type(allow_array)) {
3626 loc->error("%s operand of operation `%s' should be a string, "
3627 "`record of'%s `set of'%s value", opnum, opname,
3628 allow_array ? "," : " or", allow_array ? " or array" : "");
3629 set_valuetype(V_ERROR);
3630 return;
3631 }
3632 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3633 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3634 TypeChain l_chain;
3635 TypeChain r_chain;
3636 if (my_governor && my_governor->is_list_type(allow_array)
3637 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3638 if (info.is_subtype_error()) {
3639 // this is ok.
3640 if (info.needs_conversion()) set_needs_conversion();
3641 } else
3642 if (!info.is_erroneous()) {
3643 error("%s operand of operation `%s' is of type `%s', but a value of "
3644 "type `%s' was expected here", opnum, opname,
3645 t->get_typename().c_str(), my_governor->get_typename().c_str());
3646 } else {
3647 error("%s", info.get_error_str_str().c_str());
3648 }
3649 } else {
3650 if (info.needs_conversion())
3651 set_needs_conversion();
3652 }
3653 }
3654
3655 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3656 const char *opnum,
3657 const char *opname,
3658 const Location *loc)
3659 {
3660 switch(tt) {
3661 case Type::T_CSTR:
3662 case Type::T_USTR:
3663 case Type::T_BSTR:
3664 case Type::T_HSTR:
3665 case Type::T_OSTR:
3666 return;
3667 default:
3668 break;
3669 }
3670 if(tt!=Type::T_ERROR)
3671 loc->error("%s operand of operation `%s' should be string value",
3672 opnum, opname);
3673 set_valuetype(V_ERROR);
3674 }
3675
3676 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3677 const char *opnum,
3678 const char *opname,
3679 const Location *loc)
3680 {
3681 switch(tt) {
3682 case Type::T_CSTR:
3683 case Type::T_USTR:
3684 return;
3685 default:
3686 break;
3687 }
3688 if(tt!=Type::T_ERROR)
3689 loc->error("%s operand of operation `%s' should be (universal)"
3690 " charstring value",
3691 opnum, opname);
3692 set_valuetype(V_ERROR);
3693 }
3694
3695 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3696 const char *opnum,
3697 const char *opname,
3698 const Location *loc)
3699 {
3700 if(tt==Type::T_CSTR) return;
3701 if(tt!=Type::T_ERROR)
3702 loc->error("%s operand of operation `%s' should be charstring value",
3703 opnum, opname);
3704 set_valuetype(V_ERROR);
3705 }
3706
3707 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3708 const char *opnum,
3709 const char *opname,
3710 const Location *loc)
3711 {
3712 switch(tt) {
3713 case Type::T_BSTR:
3714 case Type::T_HSTR:
3715 case Type::T_OSTR:
3716 return;
3717 default:
3718 break;
3719 }
3720 if(tt!=Type::T_ERROR)
3721 loc->error("%s operand of operation `%s' should be binary string value",
3722 opnum, opname);
3723 set_valuetype(V_ERROR);
3724 }
3725
3726 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3727 const char *opnum,
3728 const char *opname,
3729 const Location *loc)
3730 {
3731 if(tt==Type::T_BSTR) return;
3732 if(tt!=Type::T_ERROR)
3733 loc->error("%s operand of operation `%s' should be bitstring value",
3734 opnum, opname);
3735 set_valuetype(V_ERROR);
3736 }
3737
3738 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3739 const char *opnum,
3740 const char *opname,
3741 const Location *loc)
3742 {
3743 if(tt==Type::T_HSTR) return;
3744 if(tt!=Type::T_ERROR)
3745 loc->error("%s operand of operation `%s' should be hexstring value",
3746 opnum, opname);
3747 set_valuetype(V_ERROR);
3748 }
3749
3750 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3751 const char *opnum,
3752 const char *opname,
3753 const Location *loc)
3754 {
3755 if(tt==Type::T_OSTR) return;
3756 if(tt!=Type::T_ERROR)
3757 loc->error("%s operand of operation `%s' should be octetstring value",
3758 opnum, opname);
3759 set_valuetype(V_ERROR);
3760 }
3761
3762 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3763 Type::typetype_t tt2,
3764 const char *opname)
3765 {
3766 if(valuetype==V_ERROR) return;
3767 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3768 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3769 set_valuetype(V_ERROR);
3770 return;
3771 }
3772 if(tt1==tt2) return;
3773 error("The operands of operation `%s' should be of same type", opname);
3774 set_valuetype(V_ERROR);
3775 }
3776
3777 /* For predefined functions. */
3778 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3779 Type::typetype_t tt2,
3780 const char *opnum1,
3781 const char *opnum2,
3782 const char *opname)
3783 {
3784 if(valuetype==V_ERROR) return;
3785 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3786 set_valuetype(V_ERROR);
3787 return;
3788 }
3789 if(tt1==tt2) return;
3790 error("The %s and %s operands of operation `%s' should be of same type",
3791 opnum1, opnum2, opname);
3792 set_valuetype(V_ERROR);
3793 }
3794
3795 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3796 Value *v1, Value *v2,
3797 const char *opnum1,
3798 const char *opnum2)
3799 {
3800 start:
3801 if (valuetype == V_ERROR) return;
3802 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3803 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3804 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3805
3806 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3807 set_valuetype(V_ERROR);
3808 return;
3809 }
3810 if (tt1 == Type::T_UNDEF) {
3811 if (tt2 == Type::T_UNDEF) {
3812 if (v1->is_undef_lowerid()) {
3813 if (v2->is_undef_lowerid()) {
3814 Scope *scope = get_my_scope();
3815 Module *my_mod = scope->get_scope_mod();
3816 const Identifier& id1 = v1->get_undef_lowerid();
3817 if (scope->has_ass_withId(id1)
3818 || my_mod->has_imported_ass_withId(id1)) {
3819 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3820 * should examine this situation better, but now I suppose
3821 * the first is ref, not enum. */
3822 v1->set_lowerid_to_ref();
3823 goto start;
3824 } else {
3825 const Identifier& id2 = v2->get_undef_lowerid();
3826 if (scope->has_ass_withId(id2)
3827 || my_mod->has_imported_ass_withId(id2)) {
3828 v2->set_lowerid_to_ref();
3829 goto start;
3830 }
3831 }
3832 /* This is perhaps enum-enum, but it has no real
3833 * significance, so this should be an error. */
3834 } else {
3835 v1->set_lowerid_to_ref();
3836 goto start;
3837 }
3838 } else if (v2->is_undef_lowerid()) {
3839 v2->set_lowerid_to_ref();
3840 goto start;
3841 }
3842 error("Cannot determine the type of the operands in operation `%s'",
3843 get_opname());
3844 set_valuetype(V_ERROR);
3845 return;
3846 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3847 v1->set_lowerid_to_ref();
3848 goto start;
3849 } else {
3850 /* v1 is something undefined, but not lowerid; v2 has
3851 * returntype (perhaps also governor) */
3852 }
3853 } else if (tt2 == Type::T_UNDEF) {
3854 /* but tt1 is not undef */
3855 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3856 v2->set_lowerid_to_ref();
3857 goto start;
3858 } else {
3859 /* v2 is something undefined, but not lowerid; v1 has
3860 * returntype (perhaps also governor) */
3861 }
3862 }
3863
3864 /* Now undef_lower_id's are converted to references, or the other
3865 * value has governor; let's see the governors, if they exist. */
3866 Type *t1 = v1->get_expr_governor(exp_val);
3867 Type *t2 = v2->get_expr_governor(exp_val);
3868 if (t1) {
3869 if (t2) {
3870 // Both value has governor. Are they compatible? According to 7.1.2
3871 // and C.34 it's required to have the same root types for
3872 // OPTYPE_{CONCAT,REPLACE}.
3873 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3874 u.expr.v_optype == OPTYPE_REPLACE);
3875 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
3876 u.expr.v_optype == OPTYPE_REPLACE);
3877 TypeChain l_chain1, l_chain2;
3878 TypeChain r_chain1, r_chain2;
3879 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
3880 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
3881 if (!compat_t1 && !compat_t2) {
3882 if (!info1.is_erroneous() && !info2.is_erroneous()) {
3883 // the subtypes don't need to be compatible here
3884 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
3885 error("The operands of operation `%s' should be of compatible "
3886 "types", get_opname());
3887 set_valuetype(V_ERROR);
3888 } else {
3889 if (info1.needs_conversion() || info2.needs_conversion()) {
3890 set_needs_conversion(); // Avoid folding.
3891 return;
3892 }
3893 }
3894 } else {
3895 if (info1.is_erroneous())
3896 v1->error("%s", info1.get_error_str_str().c_str());
3897 else if (info2.is_erroneous())
3898 v2->error("%s", info2.get_error_str_str().c_str());
3899 set_valuetype(V_ERROR);
3900 }
3901 return;
3902 } else if (info1.needs_conversion() || info2.needs_conversion()) {
3903 set_needs_conversion(); // Avoid folding.
3904 return;
3905 }
3906 } else {
3907 // t1, no t2.
3908 v2->set_my_governor(t1);
3909 t1->chk_this_value_ref(v2);
3910 if (v2->valuetype == V_OMIT) {
3911 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3912 get_opname());
3913 v1->chk_expr_omit_comparison(exp_val);
3914 } else {
3915 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3916 get_opname());
3917 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3918 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3919 goto start;
3920 }
3921 }
3922 } else if (t2) {
3923 v1->set_my_governor(t2);
3924 t2->chk_this_value_ref(v1);
3925 if (v1->valuetype == V_OMIT) {
3926 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3927 get_opname());
3928 v2->chk_expr_omit_comparison(exp_val);
3929 } else {
3930 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3931 get_opname());
3932 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3933 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3934 goto start;
3935 }
3936 } else {
3937 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3938 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
3939 // Here, it cannot be that both are T_UNDEF.
3940 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3941 error("Please use reference as %s operand of operator `%s'",
3942 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
3943 set_valuetype(V_ERROR);
3944 return;
3945 }
3946 // Deny type compatibility if no governors found. The typetype_t must
3947 // be the same. TODO: How can this happen?
3948 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
3949 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
3950 error("The operands of operation `%s' should be of compatible types",
3951 get_opname());
3952 set_valuetype(V_ERROR);
3953 }
3954 }
3955 }
3956
3957 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
3958 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
3959 {
3960 if(valuetype==V_ERROR) return;
3961 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3962 Assignment *t_ass = ref->get_refd_assignment();
3963 if(!t_ass) goto error;
3964 switch(t_ass->get_asstype()) {
3965 case Assignment::A_TIMER:
3966 case Assignment::A_PAR_TIMER:
3967 u.expr.v_optype=OPTYPE_TMR_RUNNING;
3968 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
3969 chk_expr_dynamic_part(exp_val, true);
3970 break;
3971 case Assignment::A_CONST:
3972 case Assignment::A_EXT_CONST:
3973 case Assignment::A_MODULEPAR:
3974 case Assignment::A_VAR:
3975 case Assignment::A_FUNCTION_RVAL:
3976 case Assignment::A_EXT_FUNCTION_RVAL:
3977 case Assignment::A_PAR_VAL_IN:
3978 case Assignment::A_PAR_VAL_OUT:
3979 case Assignment::A_PAR_VAL_INOUT: {
3980 u.expr.v_optype = OPTYPE_COMP_RUNNING;
3981 Value* val = new Value(V_REFD, u.expr.r1);
3982 val->set_my_scope(my_scope);
3983 val->set_fullname(u.expr.r1->get_fullname());
3984 val->set_location(*u.expr.r1);
3985 u.expr.v1 = val;
3986 chk_expr_operand_compref(val, opnum, get_opname());
3987 chk_expr_dynamic_part(exp_val, false);
3988 break; }
3989 default:
3990 ref->error("%s operand of operation `%s' should be timer or"
3991 " component reference instead of %s",
3992 opnum, opname, t_ass->get_description().c_str());
3993 goto error;
3994 } // switch
3995 return;
3996 error:
3997 set_valuetype(V_ERROR);
3998 }
3999
4000 Type *Value::chk_expr_operand_comptyperef_create()
4001 {
4002 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4003 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4004 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4005 if (!t_ass) goto error;
4006 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4007 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4008 Type::EXPECTED_DYNAMIC_VALUE);
4009 if (!t_type) goto error;
4010 t_type = t_type->get_type_refd_last();
4011 if (t_type->get_typetype() == Type::T_COMPONENT) {
4012 if (my_governor) {
4013 Type *my_governor_last = my_governor->get_type_refd_last();
4014 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4015 !my_governor_last->is_compatible(t_type, NULL)) {
4016 u.expr.r1->error("Incompatible component types: operation "
4017 "`create' should refer to `%s' instead of "
4018 "`%s'",
4019 my_governor_last->get_typename().c_str(),
4020 t_type->get_typename().c_str());
4021 goto error;
4022 }
4023 }
4024 return t_type;
4025 } else {
4026 u.expr.r1->error("Type mismatch: reference to a component type was "
4027 "expected in operation `create' instead of `%s'",
4028 t_type->get_typename().c_str());
4029 }
4030 } else {
4031 u.expr.r1->error("Operation `create' should refer to a component type "
4032 "instead of %s", t_ass->get_description().c_str());
4033 }
4034 error:
4035 set_valuetype(V_ERROR);
4036 return NULL;
4037 }
4038
4039 void Value::chk_expr_comptype_compat()
4040 {
4041 if (valuetype != V_EXPR)
4042 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4043 if (!my_governor || !my_scope) return;
4044 Type *my_governor_last = my_governor->get_type_refd_last();
4045 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4046 Type *t_comptype;
4047 switch (u.expr.v_optype) {
4048 case OPTYPE_COMP_MTC:
4049 t_comptype = my_scope->get_mtc_system_comptype(false);
4050 break;
4051 case OPTYPE_COMP_SYSTEM:
4052 t_comptype = my_scope->get_mtc_system_comptype(true);
4053 break;
4054 case OPTYPE_COMP_SELF: {
4055 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4056 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4057 break; }
4058 default:
4059 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4060 t_comptype = 0;
4061 break;
4062 }
4063 if (t_comptype
4064 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4065 error("Incompatible component types: a component reference of "
4066 "type `%s' was expected, but `%s' has type `%s'",
4067 my_governor_last->get_typename().c_str(), get_opname(),
4068 t_comptype->get_typename().c_str());
4069 set_valuetype(V_ERROR);
4070 }
4071 }
4072
4073 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4074 const char *opname)
4075 {
4076 if(valuetype == V_ERROR) return;
4077 switch(val->get_valuetype()) {
4078 case V_INVOKE: {
4079 Error_Context cntxt(this, "In `%s' operation", opname);
4080 Value *v_last = val->get_value_refd_last();
4081 if(!v_last) goto error;
4082 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4083 if(!t) goto error;
4084 t = t->get_type_refd_last();
4085 if(t->get_typetype() != Type::T_COMPONENT) {
4086 v_last->error("%s operand of operation `%s': Type mismatch:"
4087 " component reference was expected instead of `%s'",
4088 opnum, opname, t->get_typename().c_str());
4089 goto error;
4090 }
4091 return; }
4092 case V_REFD: {
4093 Reference *ref = val->get_reference();
4094 Assignment *t_ass = ref->get_refd_assignment();
4095 Value *t_val = 0;
4096 if (!t_ass) goto error;
4097 switch(t_ass->get_asstype()) {
4098 case Assignment::A_CONST:
4099 t_val = t_ass->get_Value();
4100 // no break
4101 case Assignment::A_EXT_CONST:
4102 case Assignment::A_MODULEPAR:
4103 case Assignment::A_VAR:
4104 case Assignment::A_FUNCTION_RVAL:
4105 case Assignment::A_EXT_FUNCTION_RVAL:
4106 case Assignment::A_PAR_VAL_IN:
4107 case Assignment::A_PAR_VAL_OUT:
4108 case Assignment::A_PAR_VAL_INOUT: {
4109 Type *t_type=t_ass->get_Type()
4110 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4111 if(!t_type) goto error;
4112 t_type=t_type->get_type_refd_last();
4113 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4114 ref->error("%s operand of operation `%s': Type mismatch:"
4115 " component reference was expected instead of `%s'",
4116 opnum, opname, t_type->get_typename().c_str());
4117 goto error;
4118 }
4119 break;}
4120 default:
4121 ref->error("%s operand of operation `%s' should be"
4122 " component reference instead of %s",
4123 opnum, opname, t_ass->get_description().c_str());
4124 goto error;
4125 }
4126 if (t_val) {
4127 ReferenceChain refch(this, "While searching referenced value");
4128 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4129 if (!t_val) return;
4130 t_val = t_val->get_value_refd_last();
4131 if (t_val->valuetype != V_EXPR) return;
4132 switch (t_val->u.expr.v_optype) {
4133 case OPTYPE_COMP_NULL:
4134 ref->error("%s operand of operation `%s' refers to `null' component "
4135 "reference", opnum, opname);
4136 goto error;
4137 case OPTYPE_COMP_MTC:
4138 ref->error("%s operand of operation `%s' refers to the component "
4139 "reference of the `mtc'", opnum, opname);
4140 goto error;
4141 case OPTYPE_COMP_SYSTEM:
4142 ref->error("%s operand of operation `%s' refers to the component "
4143 "reference of the `system'", opnum, opname);
4144 goto error;
4145 default:
4146 break;
4147 }
4148 }
4149 return;}
4150 default:
4151 FATAL_ERROR("Value::chk_expr_operand_compref()");
4152 }
4153 error:
4154 set_valuetype(V_ERROR);
4155 }
4156
4157 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4158 const char *opnum,
4159 const char *opname)
4160 {
4161 if(valuetype==V_ERROR) return;
4162 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4163 Assignment *t_ass = ref->get_refd_assignment();
4164 if(!t_ass) goto error;
4165 switch(t_ass->get_asstype()) {
4166 case Assignment::A_TIMER: {
4167 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4168 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4169 Type::EXPECTED_DYNAMIC_VALUE);
4170 else if (ref->get_subrefs()) {
4171 ref->error("%s operand of operation `%s': "
4172 "Reference to single timer `%s' cannot have field or array "
4173 "sub-references", opnum, opname,
4174 t_ass->get_id().get_dispname().c_str());
4175 goto error;
4176 }
4177 break; }
4178 case Assignment::A_PAR_TIMER:
4179 if (ref->get_subrefs()) {
4180 ref->error("%s operand of operation `%s': "
4181 "Reference to %s cannot have field or array sub-references",
4182 opnum, opname, t_ass->get_description().c_str());
4183 goto error;
4184 }
4185 break;
4186 default:
4187 ref->error("%s operand of operation `%s' should be timer"
4188 " instead of %s",
4189 opnum, opname, t_ass->get_description().c_str());
4190 goto error;
4191 } // switch
4192 return;
4193 error:
4194 set_valuetype(V_ERROR);
4195 }
4196
4197 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4198 const char *,
4199 const char *opname)
4200 {
4201 if(valuetype==V_ERROR) return;
4202 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4203 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4204 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4205 Error_Context cntxt(this, "In `%s' operation", opname);
4206 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4207 }
4208
4209 void Value::chk_expr_operand_activate_refd(Value *val,
4210 Ttcn::TemplateInstances* t_list2,
4211 Ttcn::ActualParList *&parlist,
4212 const char *,
4213 const char *opname)
4214 {
4215 if(valuetype==V_ERROR) return;
4216 Error_Context cntxt(this, "In `%s' operation", opname);
4217 Type *t = val->get_expr_governor_last();
4218 if (t) {
4219 switch (t->get_typetype()) {
4220 case Type::T_ERROR:
4221 set_valuetype(V_ERROR);
4222 break;
4223 case Type::T_ALTSTEP: {
4224 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4225 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4226 if(is_erroneous) {
4227 delete parlist;
4228 parlist = 0;
4229 set_valuetype(V_ERROR);
4230 } else {
4231 parlist->set_fullname(get_fullname());
4232 parlist->set_my_scope(get_my_scope());
4233 if (!fp_list->chk_activate_argument(parlist,
4234 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4235 }
4236 break; }
4237 default:
4238 error("Reference to an altstep was expected in the argument of "
4239 "`derefers()' instead of `%s'", t->get_typename().c_str());
4240 set_valuetype(V_ERROR);
4241 break;
4242 }
4243 } else set_valuetype(V_ERROR);
4244 }
4245
4246 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4247 const char *,
4248 const char *opname)
4249 {
4250 if(valuetype==V_ERROR) return;
4251 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4252 Error_Context cntxt(this, "In `%s' operation", opname);
4253 Assignment *t_ass = ref->get_refd_assignment();
4254 bool error_flag = false;
4255 if (t_ass) {
4256 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4257 ref->error("Reference to a testcase was expected in the argument "
4258 "instead of %s", t_ass->get_description().c_str());
4259 error_flag = true;
4260 }
4261 } else error_flag = true;
4262 if (val) {
4263 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4264 Value *v_last = val->get_value_refd_last();
4265 switch (v_last->valuetype) {
4266 case V_REAL: {
4267 ttcn3float v_real = v_last->get_val_Real();
4268 if (v_real < 0.0) {
4269 val->error("The testcase guard timer has negative value: `%s'",
4270 Real2string(v_real).c_str());
4271 error_flag = true;
4272 }
4273 break; }
4274 case V_ERROR:
4275 error_flag = true;
4276 break;
4277 default:
4278 break;
4279 }
4280 }
4281 if (error_flag) set_valuetype(V_ERROR);
4282 }
4283
4284 void Value::chk_expr_operand_execute_refd(Value *v1,
4285 Ttcn::TemplateInstances* t_list2,
4286 Ttcn::ActualParList *&parlist,
4287 Value *v3,
4288 const char *,
4289 const char *opname)
4290 {
4291 if(valuetype==V_ERROR) return;
4292 Error_Context cntxt(this, "In `%s' operation", opname);
4293 Type *t = v1->get_expr_governor_last();
4294 if (t) {
4295 switch (t->get_typetype()) {
4296 case Type::T_ERROR:
4297 set_valuetype(V_ERROR);
4298 break;
4299 case Type::T_TESTCASE: {
4300 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4301 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4302 if(is_erroneous) {
4303 delete parlist;
4304 parlist = 0;
4305 set_valuetype(V_ERROR);
4306 } else {
4307 parlist->set_fullname(get_fullname());
4308 parlist->set_my_scope(get_my_scope());
4309 }
4310 break; }
4311 default:
4312 v1->error("Reference to a value of type testcase was expected in the "
4313 "argument of `derefers()' instead of `%s'",
4314 t->get_typename().c_str());
4315 set_valuetype(V_ERROR);
4316 break;
4317 }
4318 } else set_valuetype(V_ERROR);
4319 if (v3) {
4320 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4321 Value *v_last = v3->get_value_refd_last();
4322 switch (v_last->valuetype) {
4323 case V_REAL: {
4324 ttcn3float v_real = v_last->get_val_Real();
4325 if(v_real < 0.0) {
4326 v3->error("The testcase guard timer has negative value: `%s'",
4327 Real2string(v_real).c_str());
4328 set_valuetype(V_ERROR);
4329 }
4330 break; }
4331 case V_ERROR:
4332 set_valuetype(V_ERROR);
4333 break;
4334 default:
4335 break;
4336 }
4337 }
4338 }
4339
4340 void Value::chk_invoke(Type::expected_value_t exp_val)
4341 {
4342 if(valuetype == V_ERROR) return;
4343 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4344 if(!u.invoke.t_list) return; //already checked
4345 Error_Context cntxt(this, "In `apply()' operation");
4346 Type *t = u.invoke.v->get_expr_governor_last();
4347 if (!t) {
4348 set_valuetype(V_ERROR);
4349 return;
4350 }
4351 switch (t->get_typetype()) {
4352 case Type::T_ERROR:
4353 set_valuetype(V_ERROR);
4354 return;
4355 case Type::T_FUNCTION:
4356 break;
4357 default:
4358 u.invoke.v->error("A value of type function was expected in the "
4359 "argument instead of `%s'", t->get_typename().c_str());
4360 set_valuetype(V_ERROR);
4361 return;
4362 }
4363 my_scope->chk_runs_on_clause(t, *this, "call");
4364 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4365 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4366 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4367 delete u.invoke.t_list;
4368 u.invoke.t_list = 0;
4369 if(is_erroneous) {
4370 delete parlist;
4371 u.invoke.ap_list = 0;
4372 } else {
4373 parlist->set_fullname(get_fullname());
4374 parlist->set_my_scope(get_my_scope());
4375 u.invoke.ap_list = parlist;
4376 }
4377 switch (exp_val) {
4378 case Type::EXPECTED_CONSTANT:
4379 error("An evaluatable constant value was expected instead of operation "
4380 "`apply()'");
4381 set_valuetype(V_ERROR);
4382 break;
4383 case Type::EXPECTED_STATIC_VALUE:
4384 error("A static value was expected instead of operation `apply()'");
4385 set_valuetype(V_ERROR);
4386 break;
4387 default:
4388 break;
4389 } // switch
4390 }
4391
4392 void Value::chk_expr_eval_value(Value *val, Type &t,
4393 ReferenceChain *refch,
4394 Type::expected_value_t exp_val)
4395 {
4396 bool self_ref = false;
4397 if(valuetype==V_ERROR) return;
4398 // Commented out to report more errors :)
4399 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4400 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4401 switch(val->get_valuetype()) {
4402 case V_REFD:
4403 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4404 break;
4405 case V_EXPR:
4406 case V_MACRO:
4407 case V_INVOKE:
4408 val->get_value_refd_last(refch, exp_val);
4409 break;
4410 default:
4411 break;
4412 } // switch
4413 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4414
4415 (void)self_ref;
4416 }
4417
4418 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4419 ReferenceChain *refch, Type::expected_value_t exp_val)
4420 {
4421 bool self_ref = false;
4422 ti->chk(type);
4423 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4424 ti->error("Reference to a %s value was expected instead of an in-line "
4425 "modified template",
4426 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4427 set_valuetype(V_ERROR);
4428 return;
4429 }
4430 Template *templ = ti->get_Template();
4431 switch (templ->get_templatetype()) {
4432 case Template::TEMPLATE_REFD:
4433 // not foldable
4434 if (exp_val == Type::EXPECTED_TEMPLATE) {
4435 templ = templ->get_template_refd_last(refch);
4436 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4437 set_valuetype(V_ERROR);
4438 } else {
4439 ti->error("Reference to a %s value was expected instead of %s",
4440 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4441 templ->get_reference()->get_refd_assignment()
4442 ->get_description().c_str());
4443 set_valuetype(V_ERROR);
4444 }
4445 break;
4446 case Template::SPECIFIC_VALUE: {
4447 Value *val = templ->get_specific_value();
4448 switch (val->get_valuetype()) {
4449 case V_REFD:
4450 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4451 break;
4452 case V_EXPR:
4453 val->get_value_refd_last(refch, exp_val);
4454 default:
4455 break;
4456 } // switch
4457 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4458 break; }
4459 case Template::TEMPLATE_ERROR:
4460 set_valuetype(V_ERROR);
4461 break;
4462 default:
4463 break;
4464 } // switch
4465
4466 (void)self_ref;
4467 }
4468
4469 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4470 const char *opname)
4471 {
4472 if(valuetype==V_ERROR) return;
4473 if(u.expr.state==EXPR_CHECKING_ERR) return;
4474 if(val->is_unfoldable()) return;
4475 if(*val->get_val_Int()<0) {
4476 val->error("%s operand of operation `%s' should not be negative",
4477 opnum, opname);
4478 set_valuetype(V_ERROR);
4479 }
4480 }
4481
4482 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4483 const char *opname)
4484 {
4485 if(valuetype==V_ERROR) return;
4486 if(u.expr.state==EXPR_CHECKING_ERR) return;
4487 if(val->is_unfoldable()) return;
4488 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4489 val->error("%s operand of operation `%s' should be in range 0..127",
4490 opnum, opname);
4491 set_valuetype(V_ERROR);
4492 }
4493 }
4494
4495 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4496 const char *opname)
4497 {
4498 if(valuetype==V_ERROR) return;
4499 if(u.expr.state==EXPR_CHECKING_ERR) return;
4500 if(val->is_unfoldable()) return;
4501 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4502 val->error("%s operand of operation `%s' should be in range"
4503 " 0..2147483647", opnum, opname);
4504 set_valuetype(V_ERROR);
4505 }
4506 }
4507
4508 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4509 const char *opname)
4510 {
4511 if(valuetype==V_ERROR) return;
4512 if(u.expr.state==EXPR_CHECKING_ERR) return;
4513 if(val->is_unfoldable()) return;
4514 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4515 ||
4516 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4517 {
4518 val->error("%s operand of operation `%s' should not be zero",
4519 opnum, opname);
4520 set_valuetype(V_ERROR);
4521 }
4522 }
4523
4524 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4525 const char *opname)
4526 {
4527 if (valuetype == V_ERROR) return;
4528 if (u.expr.state == EXPR_CHECKING_ERR) return;
4529 if (val->get_expr_returntype() != Type::T_INT) return;
4530 if (val->is_unfoldable()) return;
4531 const int_val_t *val_int = val->get_val_Int();
4532 if (*val_int > static_cast<Int>(INT_MAX)) {
4533 val->error("%s operand of operation `%s' should be less than `%d' "
4534 "instead of `%s'", opnum, opname, INT_MAX,
4535 (val_int->t_str()).c_str());
4536 set_valuetype(V_ERROR);
4537 }
4538 }
4539
4540 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4541 const char *opname)
4542 {
4543 if(valuetype==V_ERROR) return;
4544 if(u.expr.state==EXPR_CHECKING_ERR) return;
4545 if(val->is_unfoldable()) return;
4546 if(val->get_val_strlen()!=1) {
4547 val->error("%s operand of operation `%s' should be of length 1",
4548 opnum, opname);
4549 set_valuetype(V_ERROR);
4550 }
4551 }
4552
4553 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4554 const char *opname)
4555 {
4556 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4557 Value *v_last = val->get_value_refd_last();
4558 if (v_last->valuetype == V_CSTR) {
4559 size_t len = v_last->get_val_strlen();
4560 if (len % 2) {
4561 val->error("%s operand of operation `%s' should contain even number "
4562 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4563 set_valuetype(V_ERROR);
4564 }
4565 } else if (v_last->valuetype == V_REFD) {
4566 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4567 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4568 val->error("%s operand of operation `%s' should contain even number "
4569 "of characters, but a string element contains 1", opnum, opname);
4570 set_valuetype(V_ERROR);
4571 }
4572 }
4573 }
4574
4575 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4576 const char *opname)
4577 {
4578 if(valuetype==V_ERROR) return;
4579 if(u.expr.state==EXPR_CHECKING_ERR) return;
4580 if(val->is_unfoldable()) return;
4581 const string& s=val->get_val_str();
4582 for(size_t i=0; i<s.size(); i++) {
4583 char c=s[i];
4584 if(!(c=='0' || c=='1')) {
4585 val->error("%s operand of operation `%s' can contain only"
4586 " binary digits (position %lu is `%c')",
4587 opnum, opname, (unsigned long) i, c);
4588 set_valuetype(V_ERROR);
4589 return;
4590 }
4591 }
4592 }
4593
4594 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4595 const char *opname)
4596 {
4597 if(valuetype==V_ERROR) return;
4598 if(u.expr.state==EXPR_CHECKING_ERR) return;
4599 if(val->is_unfoldable()) return;
4600 const string& s=val->get_val_str();
4601 for(size_t i=0; i<s.size(); i++) {
4602 char c=s[i];
4603 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4604 val->error("%s operand of operation `%s' can contain only valid "
4605 "hexadecimal digits (position %lu is `%c')",
4606 opnum, opname, (unsigned long) i, c);
4607 set_valuetype(V_ERROR);
4608 return;
4609 }
4610 }
4611 }
4612
4613 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4614 const char *opname)
4615 {
4616 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4617 Value *v = val->get_value_refd_last();
4618 if (v->valuetype != V_OSTR) return;
4619 const string& s = val->get_val_str();
4620 size_t n_octets = s.size() / 2;
4621 for (size_t i = 0; i < n_octets; i++) {
4622 char c = s[2 * i];
4623 if (!(c >= '0' && c <= '7')) {
4624 val->error("%s operand of operation `%s' shall consist of octets "
4625 "within the range 00 .. 7F, but the string `%s'O contains octet "
4626 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4627 (unsigned long) i);
4628 set_valuetype(V_ERROR);
4629 return;
4630 }
4631 }
4632 }
4633
4634 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4635 const char *opname)
4636 {
4637 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4638 Value *v_last = val->get_value_refd_last();
4639 if (v_last->valuetype != V_CSTR) return;
4640 const string& s = v_last->get_val_str();
4641 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4642 state = S_INITIAL;
4643 // state: expected characters
4644 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4645 // S_FIRST: first digit
4646 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4647 // S_END: trailing whitespace
4648 // S_ERR: error was found, stop
4649 for (size_t i = 0; i < s.size(); i++) {
4650 char c = s[i];
4651 switch (state) {
4652 case S_INITIAL:
4653 case S_INITIAL_WS:
4654 if (c == '+' || c == '-') state = S_FIRST;
4655 else if (c == '0') state = S_ZERO;
4656 else if (c >= '1' && c <= '9') state = S_MORE;
4657 else if (string::is_whitespace(c)) {
4658 if (state == S_INITIAL) {
4659 val->warning("Leading whitespace was detected and ignored in the "
4660 "operand of operation `%s'", opname);
4661 state = S_INITIAL_WS;
4662 }
4663 } else state = S_ERR;
4664 break;
4665 case S_FIRST:
4666 if (c == '0') state = S_ZERO;
4667 else if (c >= '1' && c <= '9') state = S_MORE;
4668 else state = S_ERR;
4669 break;
4670 case S_ZERO:
4671 if (c >= '0' && c <= '9') {
4672 val->warning("Leading zero digit was detected and ignored in the "
4673 "operand of operation `%s'", opname);
4674 state = S_MORE;
4675 } else if (string::is_whitespace(c)) state = S_END;
4676 else state = S_ERR;
4677 break;
4678 case S_MORE:
4679 if (c >= '0' && c <= '9') {}
4680 else if (string::is_whitespace(c)) state = S_END;
4681 else state = S_ERR;
4682 break;
4683 case S_END:
4684 if (!string::is_whitespace(c)) state = S_ERR;
4685 break;
4686 default:
4687 break;
4688 }
4689 if (state == S_ERR) {
4690 if (string::is_printable(c)) {
4691 val->error("%s operand of operation `%s' should be a string "
4692 "containing a valid integer value, but invalid character `%c' "
4693 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4694 } else {
4695 val->error("%s operand of operation `%s' should be a string "
4696 "containing a valid integer value, but invalid character with "
4697 "character code %u was detected at index %lu", opnum, opname, c,
4698 (unsigned long) i);
4699 }
4700 set_valuetype(V_ERROR);
4701 break;
4702 }
4703 }
4704 switch (state) {
4705 case S_INITIAL:
4706 case S_INITIAL_WS:
4707 val->error("%s operand of operation `%s' should be a string containing a "
4708 "valid integer value instead of an empty string", opnum, opname);
4709 set_valuetype(V_ERROR);
4710 break;
4711 case S_FIRST:
4712 val->error("%s operand of operation `%s' should be a string containing a "
4713 "valid integer value, but only a sign character was detected", opnum,
4714 opname);
4715 set_valuetype(V_ERROR);
4716 break;
4717 case S_END:
4718 val->warning("Trailing whitespace was detected and ignored in the "
4719 "operand of operation `%s'", opname);
4720 break;
4721 default:
4722 break;
4723 }
4724 }
4725
4726 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4727 const char *opname)
4728 {
4729 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4730 Value *v_last = val->get_value_refd_last();
4731 if (v_last->valuetype == V_REFD) {
4732 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4733 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4734 val->error("%s operand of operation `%s' should be a string containing "
4735 "a valid float value instead of a string element, which cannot "
4736 "represent a floating point number", opnum, opname);
4737 set_valuetype(V_ERROR);
4738 }
4739 return;
4740 } else if (v_last->valuetype != V_CSTR) return;
4741 const string& s = v_last->get_val_str();
4742 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4743 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4744 state = S_INITIAL;
4745 // state: expected characters
4746 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4747 // leading whitespace
4748 // S_FIRST_M: first digit of integer part in mantissa
4749 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4750 // S_FIRST_F: first digit of fraction
4751 // S_MORE_F: more digits of fraction, E, trailing whitespace
4752 // S_INITIAL_E: +, -, first digit of exponent
4753 // S_FIRST_E: first digit of exponent
4754 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4755 // S_END: trailing whitespace
4756 // S_ERR: error was found, stop
4757 for (size_t i = 0; i < s.size(); i++) {
4758 char c = s[i];
4759 switch (state) {
4760 case S_INITIAL:
4761 case S_INITIAL_WS:
4762 if (c == '+' || c == '-') state = S_FIRST_M;
4763 else if (c == '0') state = S_ZERO_M;
4764 else if (c >= '1' && c <= '9') state = S_MORE_M;
4765 else if (string::is_whitespace(c)) {
4766 if (state == S_INITIAL) {
4767 val->warning("Leading whitespace was detected and ignored in the "
4768 "operand of operation `%s'", opname);
4769 state = S_INITIAL_WS;
4770 }
4771 } else state = S_ERR;
4772 break;
4773 case S_FIRST_M:
4774 if (c == '0') state = S_ZERO_M;
4775 else if (c >= '1' && c <= '9') state = S_MORE_M;
4776 else state = S_ERR;
4777 break;
4778 case S_ZERO_M:
4779 if (c == '.') state = S_FIRST_F;
4780 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4781 else if (c >= '0' && c <= '9') {
4782 val->warning("Leading zero digit was detected and ignored in the "
4783 "mantissa of the operand of operation `%s'", opname);
4784 state = S_MORE_M;
4785 } else state = S_ERR;
4786 break;
4787 case S_MORE_M:
4788 if (c == '.') state = S_FIRST_F;
4789 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4790 else if (c >= '0' && c <= '9') {}
4791 else state = S_ERR;
4792 break;
4793 case S_FIRST_F:
4794 if (c >= '0' && c <= '9') state = S_MORE_F;
4795 else state = S_ERR;
4796 break;
4797 case S_MORE_F:
4798 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4799 else if (c >= '0' && c <= '9') {}
4800 else if (string::is_whitespace(c)) state = S_END;
4801 else state = S_ERR;
4802 break;
4803 case S_INITIAL_E:
4804 if (c == '+' || c == '-') state = S_FIRST_E;
4805 else if (c == '0') state = S_ZERO_E;
4806 else if (c >= '1' && c <= '9') state = S_MORE_E;
4807 else state = S_ERR;
4808 break;
4809 case S_FIRST_E:
4810 if (c == '0') state = S_ZERO_E;
4811 else if (c >= '1' && c <= '9') state = S_MORE_E;
4812 else state = S_ERR;
4813 break;
4814 case S_ZERO_E:
4815 if (c >= '0' && c <= '9') {
4816 val->warning("Leading zero digit was detected and ignored in the "
4817 "exponent of the operand of operation `%s'", opname);
4818 state = S_MORE_E;
4819 } else if (string::is_whitespace(c)) state = S_END;
4820 else state = S_ERR;
4821 break;
4822 case S_MORE_E:
4823 if (c >= '0' && c <= '9') {}
4824 else if (string::is_whitespace(c)) state = S_END;
4825 else state = S_ERR;
4826 break;
4827 case S_END:
4828 if (!string::is_whitespace(c)) state = S_ERR;
4829 break;
4830 default:
4831 break;
4832 }
4833 if (state == S_ERR) {
4834 if (string::is_printable(c)) {
4835 val->error("%s operand of operation `%s' should be a string "
4836 "containing a valid float value, but invalid character `%c' "
4837 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4838 } else {
4839 val->error("%s operand of operation `%s' should be a string "
4840 "containing a valid float value, but invalid character with "
4841 "character code %u was detected at index %lu", opnum, opname, c,
4842 (unsigned long) i);
4843 }
4844 set_valuetype(V_ERROR);
4845 break;
4846 }
4847 }
4848 switch (state) {
4849 case S_INITIAL:
4850 case S_INITIAL_WS:
4851 val->error("%s operand of operation `%s' should be a string containing a "
4852 "valid float value instead of an empty string", opnum, opname);
4853 set_valuetype(V_ERROR);
4854 break;
4855 case S_FIRST_M:
4856 val->error("%s operand of operation `%s' should be a string containing a "
4857 "valid float value, but only a sign character was detected", opnum,
4858 opname);
4859 set_valuetype(V_ERROR);
4860 break;
4861 case S_ZERO_M:
4862 case S_MORE_M:
4863 // HL67862: Missing decimal dot allowed for str2float
4864 break;
4865 case S_FIRST_F:
4866 // HL67862: Missing fraction part is allowed for str2float
4867 break;
4868 case S_INITIAL_E:
4869 case S_FIRST_E:
4870 val->error("%s operand of operation `%s' should be a string containing a "
4871 "valid float value, but the exponent is missing after the `E' sign",
4872 opnum, opname);
4873 set_valuetype(V_ERROR);
4874 break;
4875 case S_END:
4876 val->warning("Trailing whitespace was detected and ignored in the "
4877 "operand of operation `%s'", opname);
4878 break;
4879 default:
4880 break;
4881 }
4882 }
4883
4884 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
4885 const char *opname)
4886 {
4887 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4888 Value *v = val->get_value_refd_last();
4889 if (v->valuetype != V_USTR) return;
4890 const ustring& us = v->get_val_ustr();
4891 for (size_t i = 0; i < us.size(); i++) {
4892 const ustring::universal_char& uchar = us[i];
4893 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
4894 uchar.cell > 127) {
4895 val->error("%s operand of operation `%s' shall consist of characters "
4896 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4897 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4898 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
4899 uchar.row, uchar.cell, (unsigned long) i);
4900 set_valuetype(V_ERROR);
4901 return;
4902 }
4903 }
4904 }
4905
4906 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
4907 const char *opname)
4908 {
4909 if(valuetype==V_ERROR) return;
4910 if(u.expr.state==EXPR_CHECKING_ERR) return;
4911 if(val->is_unfoldable()) return;
4912 const string& bstr=val->get_val_str();
4913 // see also PredefFunc.cc::bit2int()
4914 size_t nof_bits = bstr.size();
4915 // skip the leading zeros
4916 size_t start_index = 0;
4917 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
4918 // check whether the remaining bits fit in Int
4919 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
4920 val->error("%s operand of operation `%s' is too large (maximum number"
4921 " of bits in integer is %lu)",
4922 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4923 set_valuetype(V_ERROR);
4924 }
4925 }
4926
4927 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
4928 const char *opname)
4929 {
4930 if(valuetype==V_ERROR) return;
4931 if(u.expr.state==EXPR_CHECKING_ERR) return;
4932 if(val->is_unfoldable()) return;
4933 const string& hstr=val->get_val_str();
4934 // see also PredefFunc.cc::hex2int()
4935 size_t nof_digits = hstr.size();
4936 // skip the leading zeros
4937 size_t start_index = 0;
4938 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
4939 // check whether the remaining hex digits fit in Int
4940 if (nof_digits - start_index > 2 * sizeof(Int) ||
4941 (nof_digits - start_index == 2 * sizeof(Int) &&
4942 char_to_hexdigit(hstr[start_index]) > 7)) {
4943 val->error("%s operand of operation `%s' is too large (maximum number"
4944 " of bits in integer is %lu)",
4945 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4946 set_valuetype(V_ERROR);
4947 }
4948 }
4949
4950 void Value::chk_expr_operands_int2binstr()
4951 {
4952 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4953 if (u.expr.v1->is_unfoldable()) return;
4954 if (u.expr.v2->is_unfoldable()) return;
4955 // It is already checked that i1 and i2 are non-negative.
4956 Error_Context cntxt(this, "In operation `%s'", get_opname());
4957 const int_val_t *i1 = u.expr.v1->get_val_Int();
4958 const int_val_t *i2 = u.expr.v2->get_val_Int();
4959 if (!i2->is_native()) {
4960 u.expr.v2->error("The length of the resulting string is too large for "
4961 "being represented in memory");
4962 set_valuetype(V_ERROR);
4963 return;
4964 }
4965 Int nof_bits = i2->get_val();
4966 if (u.expr.v1->is_unfoldable()) return;
4967 switch (u.expr.v_optype) {
4968 case OPTYPE_INT2BIT:
4969 break;
4970 case OPTYPE_INT2HEX:
4971 nof_bits *= 4;
4972 break;
4973 case OPTYPE_INT2OCT:
4974 nof_bits *= 8;
4975 break;
4976 default:
4977 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4978 }
4979 if (*i1 >> nof_bits > 0) { // Expensive?
4980 u.expr.v1->error("Value %s does not fit in length %s",
4981 i1->t_str().c_str(), i2->t_str().c_str());
4982 set_valuetype(V_ERROR);
4983 }
4984 }
4985
4986 void Value::chk_expr_operands_str_samelen()
4987 {
4988 if(valuetype==V_ERROR) return;
4989 if(u.expr.state==EXPR_CHECKING_ERR) return;
4990 Value *v1=u.expr.v1;
4991 if(v1->is_unfoldable()) return;
4992 Value *v2=u.expr.v2;
4993 if(v2->is_unfoldable()) return;
4994 Error_Context cntxt(this, "In operation `%s'", get_opname());
4995 size_t i1=v1->get_val_strlen();
4996 size_t i2=v2->get_val_strlen();
4997 if(i1!=i2) {
4998 error("The operands should have the same length");
4999 set_valuetype(V_ERROR);
5000 }
5001 }
5002
5003 void Value::chk_expr_operands_replace()
5004 {
5005 // The fourth operand doesn't need to be checked at all here.
5006 if(valuetype==V_ERROR) return;
5007 if(u.expr.state==EXPR_CHECKING_ERR) return;
5008 Value* v1 = u.expr.ti1->get_specific_value();
5009 if (!v1) return;
5010
5011 Error_Context cntxt(this, "In operation `%s'", get_opname());
5012 size_t list_len = 0;
5013 bool list_len_known = false;
5014 if (v1->valuetype == V_REFD) {
5015 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5016 if (subrefs && subrefs->refers_to_string_element()) {
5017 warning("Replacing a string element does not make any sense");
5018 list_len = 1;
5019 list_len_known = true;
5020 }
5021 }
5022 if (!v1->is_unfoldable()) {
5023 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5024 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5025 list_len_known = true;
5026 }
5027 if (!list_len_known) return;
5028 if (u.expr.v2->is_unfoldable()) {
5029 if (!u.expr.v3->is_unfoldable()) {
5030 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5031 if (*len_int_3 > static_cast<Int>(list_len)) {
5032 error("Third operand `len' (%s) is greater than the length of "
5033 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5034 (unsigned long)list_len);
5035 set_valuetype(V_ERROR);
5036 }
5037 }
5038 } else {
5039 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5040 if (u.expr.v3->is_unfoldable()) {
5041 if (*index_int_2 > static_cast<Int>(list_len)) {
5042 error("Second operand `index' (%s) is greater than the length of "
5043 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5044 (unsigned long)list_len);
5045 set_valuetype(V_ERROR);
5046 }
5047 } else {
5048 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5049 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5050 error("The sum of second operand `index' (%s) and third operand "
5051 "`len' (%s) is greater than the length of the first operand (%lu)",
5052 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5053 (unsigned long)list_len);
5054 set_valuetype(V_ERROR);
5055 }
5056 }
5057 }
5058 }
5059
5060 void Value::chk_expr_operands_substr()
5061 {
5062 if(valuetype==V_ERROR) return;
5063 if(u.expr.state==EXPR_CHECKING_ERR) return;
5064 Value* v1 = u.expr.ti1->get_specific_value();
5065 if (!v1) return;
5066
5067 Error_Context cntxt(this, "In operation `%s'", get_opname());
5068 size_t list_len = 0;
5069 bool list_len_known = false;
5070 if (v1->valuetype == V_REFD) {
5071 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5072 if (subrefs && subrefs->refers_to_string_element()) {
5073 warning("Taking the substring of a string element does not make any "
5074 "sense");
5075 list_len = 1;
5076 list_len_known = true;
5077 }
5078 }
5079 if (!list_len_known && !v1->is_unfoldable()) {
5080 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5081 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5082 list_len_known = true;
5083 }
5084 // Do nothing if the length of the first operand is unknown.
5085 if (!list_len_known) return;
5086 if (u.expr.v2->is_unfoldable()) {
5087 if (!u.expr.v3->is_unfoldable()) {
5088 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5089 // Only the third operand is known.
5090 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5091 error("Third operand `returncount' (%s) is greater than the "
5092 "length of the first operand (%lu)",
5093 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5094 set_valuetype(V_ERROR);
5095 }
5096 }
5097 } else {
5098 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5099 if (u.expr.v3->is_unfoldable()) {
5100 // Only the second operand is known.
5101 if (*index_int_2 > static_cast<Int>(list_len)) {
5102 error("Second operand `index' (%s) is greater than the length "
5103 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5104 (unsigned long)list_len);
5105 set_valuetype(V_ERROR);
5106 }
5107 } else {
5108 // Both second and third operands are known.
5109 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5110 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5111 error("The sum of second operand `index' (%s) and third operand "
5112 "`returncount' (%s) is greater than the length of the first operand "
5113 "(%lu)", (index_int_2->t_str()).c_str(),
5114 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5115 set_valuetype(V_ERROR);
5116 }
5117 }
5118 }
5119 }
5120
5121 void Value::chk_expr_operands_regexp()
5122 {
5123 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5124 Value* v1 = u.expr.ti1->get_specific_value();
5125 Value* v2 = u.expr.t2->get_specific_value();
5126 if (!v1 || !v2) return;
5127
5128 Error_Context cntxt(this, "In operation `regexp()'");
5129 Value* v1_last = v1->get_value_refd_last();
5130 if (v1_last->valuetype == V_CSTR) {
5131 // the input string is available at compile time
5132 const string& instr = v1_last->get_val_str();
5133 const char *input_str = instr.c_str();
5134 size_t instr_len = strlen(input_str);
5135 if (instr_len < instr.size()) {
5136 v1->warning("The first operand of `regexp()' contains a "
5137 "character with character code zero at index %s. The rest of the "
5138 "string will be ignored during matching",
5139 Int2string(instr_len).c_str());
5140 }
5141 }
5142
5143 size_t nof_groups = 0;
5144 Value *v2_last = v2->get_value_refd_last();
5145
5146 if (v2_last->valuetype == V_CSTR) {
5147 // the pattern is available at compile time
5148 const string& expression = v2_last->get_val_str();
5149 const char *pattern_str = expression.c_str();
5150 size_t pattern_len = strlen(pattern_str);
5151 if (pattern_len < expression.size()) {
5152 v2->warning("The second operand of `regexp()' contains a "
5153 "character with character code zero at index %s. The rest of the "
5154 "string will be ignored during matching",
5155 Int2string(pattern_len).c_str());
5156 }
5157 char *posix_str;
5158 {
5159 Error_Context cntxt2(v2, "In character string pattern");
5160 posix_str = TTCN_pattern_to_regexp(pattern_str);
5161 }
5162 if (posix_str != NULL) {
5163 regex_t posix_regexp;
5164 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5165 if (ret_val != 0) {
5166 char msg[512];
5167 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5168 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5169 "regcomp() failed: %s", msg);
5170 }
5171 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5172 else {
5173 v2->error("The character pattern in the second operand of "
5174 "`regexp()' does not contain any groups");
5175 set_valuetype(V_ERROR);
5176 }
5177 regfree(&posix_regexp);
5178 Free(posix_str);
5179 } else {
5180 // the pattern is faulty
5181 // the error has been reported by TTCN_pattern_to_regexp
5182 set_valuetype(V_ERROR);
5183 }
5184 }
5185 if (nof_groups > 0) {
5186 Value *v3 = u.expr.v3->get_value_refd_last();
5187 if (v3->valuetype == V_INT) {
5188 // the group number is available at compile time
5189 const int_val_t *groupno_int = v3->get_val_Int();
5190 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5191 u.expr.v3->error("The the third operand of `regexp()' is too "
5192 "large: The requested group index is %s, but the pattern "
5193 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5194 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5195 set_valuetype(V_ERROR);
5196 }
5197 }
5198 }
5199 }
5200
5201 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5202 Type::expected_value_t exp_val)
5203 {
5204 const char *opname = get_opname();
5205 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5206 Type *t_governor;
5207 const Location *loc;
5208 bool error_flag = false;
5209 switch (u.expr.v_optype) {
5210 case OPTYPE_ISCHOSEN_V:
5211 // u.expr.v1 is always a referenced value
5212 t_governor = u.expr.v1->get_expr_governor(exp_val);
5213 if (t_governor) {
5214 u.expr.v1->set_my_governor(t_governor);
5215 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5216 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5217 } else error_flag = true;
5218 loc = u.expr.v1;
5219 break;
5220 case OPTYPE_ISCHOSEN_T:
5221 // u.expr.t1 is always a referenced template
5222 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5223 exp_val = Type::EXPECTED_TEMPLATE;
5224 t_governor = u.expr.t1->get_expr_governor(exp_val);
5225 if (t_governor) {
5226 u.expr.t1->set_my_governor(t_governor);
5227 //
5228 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5229 //
5230 u.expr.t1->get_template_refd_last(refch);
5231 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5232 error_flag = true;
5233 } else error_flag = true;
5234 if (exp_val != Type::EXPECTED_TEMPLATE) {
5235 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5236 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5237 u.expr.t1->get_reference()->get_refd_assignment()
5238 ->get_description().c_str());
5239 error_flag = true;
5240 }
5241 loc = u.expr.t1;
5242 break;
5243 default:
5244 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5245 t_governor = 0;
5246 loc = 0;
5247 }
5248 if (t_governor) {
5249 t_governor = t_governor->get_type_refd_last();
5250 switch (t_governor->get_typetype()) {
5251 case Type::T_ERROR:
5252 error_flag = true;
5253 break;
5254 case Type::T_CHOICE_A:
5255 case Type::T_CHOICE_T:
5256 case Type::T_ANYTYPE:
5257 case Type::T_OPENTYPE:
5258 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5259 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5260 "%s does not have a field named `%s'" :
5261 "Union type `%s' does not have a field named `%s'",
5262 t_governor->get_typename().c_str(),
5263 u.expr.i2->get_dispname().c_str());
5264 error_flag = true;
5265 }
5266 break;
5267 default:
5268 loc->error("The operand of operation `%s' should be a union value "
5269 "or template instead of `%s'", opname,
5270 t_governor->get_typename().c_str());
5271 error_flag = true;
5272 break;
5273 }
5274 }
5275 if (error_flag) set_valuetype(V_ERROR);
5276 }
5277
5278 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5279 Type::expected_value_t exp_val) {
5280
5281 Error_Context cntxt(this, "In the parameter of encvalue()");
5282 Type t_chk(Type::T_ERROR);
5283 Type* t_type;
5284
5285 Type::expected_value_t ti_exp_val = exp_val;
5286 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5287 ti_exp_val = Type::EXPECTED_TEMPLATE;
5288
5289 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5290 if (t_type) {
5291 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5292 if (valuetype!=V_ERROR)
5293 u.expr.ti1->get_Template()->chk_specific_value(false);
5294 t_type = t_type->get_type_refd_last();
5295 } else {
5296 error("Cannot determine type of value");
5297 goto error;
5298 }
5299
5300 // todo: fix this
5301 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5302 error("Expecting a value of a type with coding attributes in first"
5303 "parameter of encvalue() which belongs to a generic type '%s'",
5304 t_type->get_typename().c_str());
5305 goto error;
5306 }*/
5307
5308 if(!disable_attribute_validation()) {
5309 t_type->chk_coding(true);
5310 }
5311
5312 switch (t_type->get_typetype()) {
5313 case Type::T_UNDEF:
5314 case Type::T_ERROR:
5315 case Type::T_NULL:
5316 case Type::T_REFD:
5317 case Type::T_REFDSPEC:
5318 case Type::T_SELTYPE:
5319 case Type::T_VERDICT:
5320 case Type::T_PORT:
5321 case Type::T_COMPONENT:
5322 case Type::T_DEFAULT:
5323 case Type::T_SIGNATURE:
5324 case Type::T_FUNCTION:
5325 case Type::T_ALTSTEP:
5326 case Type::T_TESTCASE:
5327 error("Type of parameter of encvalue() cannot be '%s'",
5328 t_type->get_typename().c_str());
5329 goto error;
5330 default:
5331 break;
5332 }
5333 return;
5334 error:
5335 set_valuetype(V_ERROR);
5336 }
5337
5338 void Value::chk_expr_operands_decode()
5339 {
5340 Error_Context cntxt(this, "In the parameters of decvalue()");
5341 Ttcn::Ref_base* ref = u.expr.r1;
5342 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5343 Type* t_type = 0;
5344 Assignment* t_ass = ref->get_refd_assignment();
5345
5346 if (!t_ass) {
5347 error("Could not determine the assignment for first parameter");
5348 goto error;
5349 }
5350 switch (t_ass->get_asstype()) {
5351 case Assignment::A_PAR_VAL_IN:
5352 t_ass->use_as_lvalue(*this);
5353 break;
5354 case Assignment::A_CONST:
5355 case Assignment::A_EXT_CONST:
5356 case Assignment::A_MODULEPAR:
5357 case Assignment::A_MODULEPAR_TEMP:
5358 case Assignment::A_TEMPLATE:
5359 ref->error("Reference to '%s' cannot be used as the first operand of "
5360 "the 'decvalue' operation", t_ass->get_assname());
5361 goto error;
5362 break;
5363 case Assignment::A_VAR:
5364 case Assignment::A_PAR_VAL_OUT:
5365 case Assignment::A_PAR_VAL_INOUT:
5366 break;
5367 case Assignment::A_VAR_TEMPLATE:
5368 case Assignment::A_PAR_TEMPL_IN:
5369 case Assignment::A_PAR_TEMPL_OUT:
5370 case Assignment::A_PAR_TEMPL_INOUT: {
5371 Template* t = new Template(ref->clone());
5372 t->set_location(*ref);
5373 t->set_my_scope(get_my_scope());
5374 t->set_fullname(get_fullname()+".<operand>");
5375 Template* t_last = t->get_template_refd_last();
5376 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5377 && t_last != t) {
5378 ref->error("Specific value template was expected instead of '%s'.",
5379 t->get_template_refd_last()->get_templatetype_str());
5380 delete t;
5381 goto error;
5382 }
5383 delete t;
5384 break; }
5385 default:
5386 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5387 goto error;
5388 }
5389 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5390 Type::EXPECTED_DYNAMIC_VALUE);
5391 if (!t_type) {
5392 goto error;
5393 }
5394 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5395 error("First parameter has to be a bitstring");
5396 goto error;
5397 }
5398
5399 ref = u.expr.r2;
5400 t_subrefs = ref->get_subrefs();
5401 t_ass = ref->get_refd_assignment();
5402
5403 if (!t_ass) {
5404 error("Could not determine the assignment for second parameter");
5405 goto error;
5406 }
5407 // Extra check for HM59355.
5408 switch (t_ass->get_asstype()) {
5409 case Assignment::A_VAR:
5410 case Assignment::A_PAR_VAL_IN:
5411 case Assignment::A_PAR_VAL_OUT:
5412 case Assignment::A_PAR_VAL_INOUT:
5413 break;
5414 default:
5415 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5416 goto error;
5417 }
5418 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5419 Type::EXPECTED_DYNAMIC_VALUE);
5420 if (!t_type) {
5421 goto error;
5422 }
5423 t_type = t_type->get_type_refd_last();
5424 switch (t_type->get_typetype()) {
5425 case Type::T_UNDEF:
5426 case Type::T_ERROR:
5427 case Type::T_NULL:
5428 case Type::T_REFD:
5429 case Type::T_REFDSPEC:
5430 case Type::T_SELTYPE:
5431 case Type::T_VERDICT:
5432 case Type::T_PORT:
5433 case Type::T_COMPONENT:
5434 case Type::T_DEFAULT:
5435 case Type::T_SIGNATURE:
5436 case Type::T_FUNCTION:
5437 case Type::T_ALTSTEP:
5438 case Type::T_TESTCASE:
5439 error("Type of second parameter cannot be %s",
5440 t_type->get_typename().c_str());
5441 goto error;
5442 default:
5443 break;
5444 }
5445
5446 if(!disable_attribute_validation()) {
5447 t_type->chk_coding(false);
5448 }
5449
5450 return;
5451 error:
5452 set_valuetype(V_ERROR);
5453 }
5454
5455 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5456 {
5457 Ttcn::FieldOrArrayRefs *subrefs;
5458 Identifier *field_id = 0;
5459 Assignment *t_ass;
5460 Type *t_type;
5461 if (valuetype == V_ERROR) return;
5462 else if (valuetype != V_REFD) {
5463 error("Only a referenced value can be compared with `omit'");
5464 goto error;
5465 }
5466 subrefs = u.ref.ref->get_subrefs();
5467 if (subrefs) field_id = subrefs->remove_last_field();
5468 if (!field_id) {
5469 error("Only a reference pointing to an optional record or set field "
5470 "can be compared with `omit'");
5471 goto error;
5472 }
5473 t_ass = u.ref.ref->get_refd_assignment();
5474 if (!t_ass) goto error;
5475 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5476 if (!t_type) goto error;
5477 t_type = t_type->get_type_refd_last();
5478 switch (t_type->get_typetype()) {
5479 case Type::T_ERROR:
5480 goto error;
5481 case Type::T_SEQ_A:
5482 case Type::T_SEQ_T:
5483 case Type::T_SET_A:
5484 case Type::T_SET_T:
5485 break;
5486 default:
5487 error("Only a reference pointing to an optional field of a record"
5488 " or set type can be compared with `omit'");
5489 goto error;
5490 }
5491 if (!t_type->has_comp_withName(*field_id)) {
5492 error("Type `%s' does not have field named `%s'",
5493 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5494 goto error;
5495 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5496 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5497 "`omit'", field_id->get_dispname().c_str(),
5498 t_type->get_typename().c_str());
5499 goto error;
5500 }
5501 // putting the last field_id back to subrefs
5502 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5503 return;
5504 error:
5505 set_valuetype(V_ERROR);
5506 delete field_id;
5507 }
5508
5509 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5510 Type::expected_value_t exp_val)
5511 {
5512 if(valuetype==V_ERROR) return -1;
5513 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5514 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5515 exp_val=Type::EXPECTED_TEMPLATE;
5516
5517 Error_Context cntxt(this, "In the operand of"
5518 " operation `%s'", get_opname());
5519
5520 Int result = -1;
5521 Template* t_templ = u.expr.ti1->get_Template();
5522
5523 if (!t_templ) {
5524 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5525 }
5526
5527 t_templ = t_templ->get_template_refd_last(refch);
5528
5529 // Timer and port arrays are handled separately
5530 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5531 Value* val = t_templ->get_specific_value();
5532 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5533 val->set_lowerid_to_ref();
5534 }
5535 if (val && val->get_valuetype() == V_REFD) {
5536 Reference* ref = val->get_reference();
5537 Assignment* t_ass = ref->get_refd_assignment();
5538 Common::Assignment::asstype_t asstype =
5539 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5540 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5541 if (t_ass->get_Dimensions()) {
5542 // here we have a timer or port array
5543 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5544 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5545 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5546 Type::EXPECTED_DYNAMIC_VALUE);
5547 size_t refd_dim;
5548 if (t_subrefs) {
5549 refd_dim = t_subrefs->get_nof_refs();
5550 size_t nof_dims = t_dims->get_nof_dims();
5551 if (refd_dim >= nof_dims) {
5552 u.expr.ti1->error("Operation is not applicable to a %s",
5553 t_ass->get_assname());
5554 set_valuetype(V_ERROR);
5555 return -1;
5556 }
5557 } else refd_dim = 0;
5558 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5559 } else {
5560 u.expr.ti1->error("Operation is not applicable to single `%s'",
5561 t_ass->get_description().c_str());
5562 set_valuetype(V_ERROR);
5563 return -1;
5564 }
5565 }
5566 }
5567 }
5568
5569 Value* t_val = 0;
5570 Type* t_type = 0;
5571 Assignment* t_ass = 0;
5572 Reference* ref = 0;
5573 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5574 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5575 if (t_type) {
5576 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5577 t_type = t_type->get_type_refd_last();
5578 } else {
5579 error("Cannot determine type of value");
5580 goto error;
5581 }
5582
5583 if(valuetype==V_ERROR) return -1;
5584
5585 t_templ = t_templ->get_template_refd_last(refch);
5586 switch(t_templ->get_templatetype()) {
5587 case Template::TEMPLATE_ERROR:
5588 goto error;
5589 case Template::INDEXED_TEMPLATE_LIST:
5590 return -1;
5591 case Template::TEMPLATE_REFD:
5592 case Template::TEMPLATE_LIST:
5593 case Template::NAMED_TEMPLATE_LIST:
5594 // computed later
5595 break;
5596 case Template::SPECIFIC_VALUE:
5597 {
5598 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5599 if(t_val) {
5600 switch(t_val->get_valuetype()) {
5601 case V_SEQOF:
5602 case V_SETOF:
5603 case V_ARRAY:
5604 case V_ROID:
5605 case V_OID:
5606 case V_SEQ:
5607 case V_SET:
5608 break;
5609 case V_REFD: {
5610 ref = t_val->get_reference();
5611 t_ass = ref->get_refd_assignment();
5612 t_subrefs = ref->get_subrefs();
5613 break;
5614 }
5615 default:
5616 u.expr.ti1->error("Operation is not applicable to `%s'",
5617 t_val->create_stringRepr().c_str());
5618 goto error;
5619 }
5620 }
5621 break;
5622 }
5623 default:
5624 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5625 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5626 goto error;
5627 } // switch
5628
5629 if (t_ass) {
5630 switch(t_ass->get_asstype()) {
5631 case Assignment::A_ERROR:
5632 goto error;
5633 case Assignment::A_CONST:
5634 t_val = t_ass->get_Value();
5635 break;
5636 case Assignment::A_EXT_CONST:
5637 case Assignment::A_MODULEPAR:
5638 case Assignment::A_MODULEPAR_TEMP:
5639 if(exp_val==Type::EXPECTED_CONSTANT) {
5640 u.expr.ti1->error("Reference to an (evaluatable) constant value was "
5641 "expected instead of %s", t_ass->get_description().c_str());
5642 goto error;
5643 }
5644 break;
5645 case Assignment::A_VAR:
5646 case Assignment::A_PAR_VAL_IN:
5647 case Assignment::A_PAR_VAL_OUT:
5648 case Assignment::A_PAR_VAL_INOUT:
5649 switch(exp_val) {
5650 case Type::EXPECTED_CONSTANT:
5651 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5652 t_ass->get_description().c_str());
5653 goto error;
5654 break;
5655 case Type::EXPECTED_STATIC_VALUE:
5656 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5657 t_ass->get_description().c_str());
5658 goto error;
5659 break;
5660 default:
5661 break;
5662 }
5663 break;
5664 case Assignment::A_TEMPLATE:
5665 t_templ = t_ass->get_Template();
5666 // no break
5667 case Assignment::A_VAR_TEMPLATE:
5668 case Assignment::A_PAR_TEMPL_IN:
5669 case Assignment::A_PAR_TEMPL_OUT:
5670 case Assignment::A_PAR_TEMPL_INOUT:
5671 if (exp_val!=Type::EXPECTED_TEMPLATE)
5672 u.expr.ti1->error("Reference to a value was expected instead of %s",
5673 t_ass->get_description().c_str());
5674 goto error;
5675 break;
5676 case Assignment::A_FUNCTION_RVAL:
5677 case Assignment::A_EXT_FUNCTION_RVAL:
5678 switch(exp_val) {
5679 case Type::EXPECTED_CONSTANT:
5680 u.expr.ti1->error("Reference to a constant value was expected instead of "
5681 "the return value of %s", t_ass->get_description().c_str());
5682 goto error;
5683 break;
5684 case Type::EXPECTED_STATIC_VALUE:
5685 u.expr.ti1->error("Reference to a static value was expected instead of "
5686 "the return value of %s", t_ass->get_description().c_str());
5687 goto error;
5688 break;
5689 default:
5690 break;
5691 }
5692 break;
5693 case Assignment::A_FUNCTION_RTEMP:
5694 case Assignment::A_EXT_FUNCTION_RTEMP:
5695 if(exp_val!=Type::EXPECTED_TEMPLATE)
5696 u.expr.ti1->error("Reference to a value was expected instead of a call"
5697 " of %s, which returns a template",
5698 t_ass->get_description().c_str());
5699 goto error;
5700 break;
5701 case Assignment::A_TIMER:
5702 case Assignment::A_PORT:
5703 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5704 // sizeof is applicable to timer and port arrays
5705 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5706 if (!t_dims) {
5707 u.expr.ti1->error("Operation is not applicable to single %s",
5708 t_ass->get_description().c_str());
5709 goto error;
5710 }
5711 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5712 Type::EXPECTED_DYNAMIC_VALUE);
5713 size_t refd_dim;
5714 if (t_subrefs) {
5715 refd_dim = t_subrefs->get_nof_refs();
5716 size_t nof_dims = t_dims->get_nof_dims();
5717 if (refd_dim > nof_dims) goto error;
5718 else if (refd_dim == nof_dims) {
5719 u.expr.ti1->error("Operation is not applicable to a %s",
5720 t_ass->get_assname());
5721 goto error;
5722 }
5723 } else refd_dim = 0;
5724 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5725 }
5726 // no break
5727 default:
5728 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5729 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5730 t_ass->get_description().c_str());
5731 goto error;
5732 } // end switch
5733
5734 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5735 if (!t_type) goto error;
5736 t_type = t_type->get_type_refd_last();
5737
5738 switch(t_type->get_typetype()) {
5739 case Type::T_ERROR:
5740 goto error;
5741 case Type::T_SEQOF:
5742 case Type::T_SETOF:
5743 // no break
5744 case Type::T_SEQ_T:
5745 case Type::T_SET_T:
5746 case Type::T_SEQ_A:
5747 case Type::T_SET_A:
5748 case Type::T_ARRAY:
5749 // ok
5750 break;
5751 case Type::T_OID:
5752 case Type::T_ROID:
5753 break;
5754 default:
5755 u.expr.ti1->error("Reference to value or template of type record, record of,"
5756 " set, set of, objid or array was expected");
5757 goto error;
5758 } // switch
5759 }
5760
5761 // check for index overflows in subrefs if possible
5762 if (t_val) {
5763 switch (t_val->get_valuetype()) {
5764 case V_SEQOF:
5765 case V_SETOF:
5766 case V_ARRAY:
5767 if (t_val->is_indexed()) {
5768 return -1;
5769 }
5770 break;
5771 default:
5772 break;
5773 }
5774 /* The reference points to a constant. */
5775 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5776 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5777 if (!t_val) goto error;
5778 t_val=t_val->get_value_refd_last(refch);
5779 } else { t_val = 0; }
5780 } else if (t_templ) {
5781 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5782 time. Don't try to evaluate it at compile time. */
5783 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5784 return -1;
5785 /* The reference points to a static template. */
5786 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5787 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5788 if (!t_templ) goto error;
5789 t_templ = t_templ->get_template_refd_last(refch);
5790 } else { t_templ = 0; }
5791 }
5792
5793 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5794 if(t_templ) {
5795 switch(t_templ->get_templatetype()) {
5796 case Template::TEMPLATE_ERROR:
5797 goto error;
5798 case Template::TEMPLATE_REFD:
5799 // not foldable
5800 t_templ=0;
5801 break;
5802 case Template::SPECIFIC_VALUE:
5803 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5804 t_templ=0;
5805 break;
5806 case Template::TEMPLATE_LIST:
5807 case Template::NAMED_TEMPLATE_LIST:
5808 break;
5809 default:
5810 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5811 t_templ->get_templatetype_str(),
5812 t_templ->get_fullname().c_str());
5813 goto error;
5814 } // switch
5815 }
5816 if(t_val) {
5817 switch(t_val->get_valuetype()) {
5818 case V_SEQOF:
5819 case V_SETOF:
5820 case V_ARRAY:
5821 case V_SEQ:
5822 case V_SET:
5823 case V_OID:
5824 case V_ROID:
5825 // ok
5826 break;
5827 default:
5828 // error is already reported
5829 t_val=0;
5830 break;
5831 } // switch
5832 }
5833 }
5834
5835 /* evaluation */
5836
5837 if(t_type->get_typetype()==Type::T_ARRAY) {
5838 result = t_type->get_dimension()->get_size();
5839 }
5840 else if(t_templ) { // sizeof()
5841 switch(t_templ->get_templatetype()) {
5842 case Template::TEMPLATE_LIST:
5843 if(t_templ->temps_contains_anyornone_symbol()) {
5844 if(t_templ->is_length_restricted()) {
5845 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5846 if (lr->get_is_range()) {
5847 Value *v_upper = lr->get_upper_value();
5848 if (v_upper) {
5849 if (v_upper->valuetype == V_INT) {
5850 Int nof_comps =
5851 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5852 if (v_upper->u.val_Int->get_val() == nof_comps)
5853 result = nof_comps;
5854 else {
5855 u.expr.ti1->error("`sizeof' operation is not applicable for "
5856 "templates without exact size");
5857 goto error;
5858 }
5859 }
5860 } else {
5861 u.expr.ti1->error("`sizeof' operation is not applicable for "
5862 "templates containing `*' without upper boundary in the "
5863 "length restriction");
5864 goto error;
5865 }
5866 } else {
5867 Value *v_single = lr->get_single_value();
5868 if (v_single->valuetype == V_INT)
5869 result = v_single->u.val_Int->get_val();
5870 }
5871 }
5872 else { // not length restricted
5873 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
5874 " containing `*' without length restriction");
5875 goto error;
5876 }
5877 }
5878 else result=t_templ->get_nof_listitems();
5879 break;
5880 case Template::NAMED_TEMPLATE_LIST:
5881 result=0;
5882 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
5883 if(t_templ->get_namedtemp_byIndex(i)->get_template()
5884 ->get_templatetype()!=Template::OMIT_VALUE) result++;
5885 return result;
5886 default:
5887 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5888 } // switch
5889 }
5890 else if(t_val) {
5891 switch(t_val->get_valuetype()) {
5892 case V_SEQOF:
5893 case V_SETOF:
5894 case V_ARRAY:
5895
5896 case V_OID:
5897 case V_ROID:
5898 result=t_val->get_nof_comps();
5899 break;
5900 case V_SEQ:
5901 case V_SET:
5902 result=0;
5903 for(size_t i=0; i<t_val->get_nof_comps(); i++)
5904 if(t_val->get_se_comp_byIndex(i)->get_value()
5905 ->get_valuetype()!=V_OMIT) result++;
5906 break;
5907
5908 default:
5909 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5910 } // switch
5911 }
5912
5913 return result;
5914 error:
5915 set_valuetype(V_ERROR);
5916 return -1;
5917 }
5918
5919 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
5920 {
5921 Type *governor = ti->get_expr_governor(exp_val);
5922 if (!governor) {
5923 ti->get_Template()->set_lowerid_to_ref();
5924 governor = ti->get_expr_governor(exp_val);
5925 }
5926 if (!governor) {
5927 string str;
5928 ti->append_stringRepr( str);
5929 ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5930 "If type is known, use valuof(<type>: %s) as argument.",
5931 str.c_str(), get_opname(), str.c_str());
5932 set_valuetype(V_ERROR);
5933 }
5934 return governor;
5935 }
5936
5937 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
5938 {
5939 start:
5940 Type *governor = u.expr.v1->get_expr_governor(exp_val);
5941 if (!governor) governor = u.expr.t2->get_expr_governor(
5942 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
5943 Type::EXPECTED_TEMPLATE : exp_val);
5944 if (!governor) {
5945 Template *t_temp = u.expr.t2->get_Template();
5946 if (t_temp->is_undef_lowerid()) {
5947 // We convert the template to reference first even if the value is also
5948 // an undef lowerid. The user can prevent this by explicit type
5949 // specification.
5950 t_temp->set_lowerid_to_ref();
5951 goto start;
5952 } else if (u.expr.v1->is_undef_lowerid()) {
5953 u.expr.v1->set_lowerid_to_ref();
5954 goto start;
5955 }
5956 }
5957 if (!governor) {
5958 error("Cannot determine the type of arguments in `match()' operation");
5959 set_valuetype(V_ERROR);
5960 return;
5961 }
5962 u.expr.v1->set_my_governor(governor);
5963 {
5964 Error_Context cntxt(this, "In the first argument of `match()'"
5965 " operation");
5966 governor->chk_this_value_ref(u.expr.v1);
5967 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
5968 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
5969 }
5970 {
5971 Error_Context cntxt(this, "In the second argument of `match()' "
5972 "operation");
5973 u.expr.t2->chk(governor);
5974 }
5975 }
5976
5977 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
5978 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
5979 {
5980 Ttcn::StatementBlock *my_sb;
5981 switch (exp_val) {
5982 case Type::EXPECTED_CONSTANT:
5983 error("An evaluatable constant value was expected instead of operation "
5984 "`%s'", get_opname());
5985 goto error;
5986 case Type::EXPECTED_STATIC_VALUE:
5987 error("A static value was expected instead of operation `%s'",
5988 get_opname());
5989 goto error;
5990 default:
5991 break;
5992 } // switch
5993 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5994 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
5995 if (!my_sb) {
5996 error("Operation `%s' is allowed only within statements",
5997 get_opname());
5998 goto error;
5999 }
6000 if (!allow_controlpart && !my_sb->get_my_def()) {
6001 error("Operation `%s' is not allowed in the control part",
6002 get_opname());
6003 goto error;
6004 }
6005 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6006 error("Operation `%s' cannot be used in a definition that has "
6007 "`runs on' clause", get_opname());
6008 goto error;
6009 }
6010 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6011 error("Operation `%s' can be used only in a definition that has "
6012 "`runs on' clause", get_opname());
6013 goto error;
6014 }
6015 return;
6016 error:
6017 set_valuetype(V_ERROR);
6018 }
6019
6020 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6021 {
6022 if(valuetype==V_ERROR) return;
6023 if(u.expr.state==EXPR_CHECKING_ERR) return;
6024 if(v->is_unfoldable()) return;
6025 if(v->get_expr_returntype()!=Type::T_REAL) return;
6026 ttcn3float r = v->get_val_Real();
6027 if (isSpecialFloatValue(r)) {
6028 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6029 opnum, opname, Real2string(r).c_str());
6030 set_valuetype(V_ERROR);
6031 }
6032 }
6033
6034 void Value::chk_expr_operands(ReferenceChain *refch,
6035 Type::expected_value_t exp_val)
6036 {
6037 const char *first="First", *second="Second", *third="Third",
6038 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6039 Value *v1, *v2, *v3;
6040 Type::typetype_t tt1, tt2, tt3;
6041 Type t_chk(Type::T_ERROR);
6042
6043 const char *opname=get_opname();
6044
6045 // first classify the unchecked ischosen() operation
6046 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6047
6048 switch (u.expr.v_optype) {
6049 case OPTYPE_COMP_NULL:
6050 case OPTYPE_TESTCASENAME:
6051 case OPTYPE_PROF_RUNNING:
6052 break;
6053 case OPTYPE_COMP_MTC:
6054 case OPTYPE_COMP_SYSTEM:
6055 chk_expr_comptype_compat();
6056 break;
6057 case OPTYPE_RND: // -
6058 case OPTYPE_TMR_RUNNING_ANY:
6059 chk_expr_dynamic_part(exp_val, true);
6060 break;
6061 case OPTYPE_COMP_RUNNING_ANY:
6062 case OPTYPE_COMP_RUNNING_ALL:
6063 case OPTYPE_COMP_ALIVE_ANY:
6064 case OPTYPE_COMP_ALIVE_ALL:
6065 case OPTYPE_GETVERDICT:
6066 chk_expr_dynamic_part(exp_val, false);
6067 break;
6068 case OPTYPE_COMP_SELF:
6069 chk_expr_comptype_compat();
6070 chk_expr_dynamic_part(exp_val, false, true, false);
6071 break;
6072 case OPTYPE_UNARYPLUS: // v1
6073 case OPTYPE_UNARYMINUS:
6074 v1=u.expr.v1;
6075 {
6076 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6077 v1->set_lowerid_to_ref();
6078 tt1=v1->get_expr_returntype(exp_val);
6079 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6080 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6081 }
6082 break;
6083 case OPTYPE_NOT:
6084 v1=u.expr.v1;
6085 {
6086 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6087 v1->set_lowerid_to_ref();
6088 tt1=v1->get_expr_returntype(exp_val);
6089 chk_expr_operandtype_bool(tt1, the, opname, v1);
6090 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6091 }
6092 break;
6093 case OPTYPE_NOT4B:
6094 v1=u.expr.v1;
6095 {
6096 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6097 v1->set_lowerid_to_ref();
6098 tt1=v1->get_expr_returntype(exp_val);
6099 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6100 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6101 }
6102 break;
6103 case OPTYPE_BIT2HEX:
6104 case OPTYPE_BIT2OCT:
6105 case OPTYPE_BIT2STR:
6106 v1=u.expr.v1;
6107 {
6108 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6109 v1->set_lowerid_to_ref();
6110 tt1=v1->get_expr_returntype(exp_val);
6111 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6112 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6113 }
6114 break;
6115 case OPTYPE_BIT2INT:
6116 v1=u.expr.v1;
6117 {
6118 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6119 v1->set_lowerid_to_ref();
6120 tt1=v1->get_expr_returntype(exp_val);
6121 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6122 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6123 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6124 }
6125 break;
6126 case OPTYPE_CHAR2INT:
6127 v1=u.expr.v1;
6128 {
6129 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6130 v1->set_lowerid_to_ref();
6131 tt1=v1->get_expr_returntype(exp_val);
6132 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6133 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6134 chk_expr_val_len1(v1, the, opname);
6135 }
6136 break;
6137 case OPTYPE_CHAR2OCT:
6138 v1=u.expr.v1;
6139 {
6140 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6141 v1->set_lowerid_to_ref();
6142 tt1=v1->get_expr_returntype(exp_val);
6143 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6144 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6145 }
6146 break;
6147 case OPTYPE_STR2INT:
6148 v1=u.expr.v1;
6149 {
6150 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6151 v1->set_lowerid_to_ref();
6152 tt1=v1->get_expr_returntype(exp_val);
6153 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6154 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6155 chk_expr_val_str_int(v1, the, opname);
6156 }
6157 break;
6158 case OPTYPE_STR2FLOAT:
6159 v1=u.expr.v1;
6160 {
6161 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6162 v1->set_lowerid_to_ref();
6163 tt1=v1->get_expr_returntype(exp_val);
6164 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6165 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6166 chk_expr_val_str_float(v1, the, opname);
6167 }
6168 break;
6169 case OPTYPE_STR2BIT:
6170 v1=u.expr.v1;
6171 {
6172 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6173 v1->set_lowerid_to_ref();
6174 tt1=v1->get_expr_returntype(exp_val);
6175 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6176 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6177 chk_expr_val_str_bindigits(v1, the, opname);
6178 }
6179 break;
6180 case OPTYPE_STR2HEX:
6181 v1=u.expr.v1;
6182 {
6183 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6184 v1->set_lowerid_to_ref();
6185 tt1=v1->get_expr_returntype(exp_val);
6186 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6187 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6188 chk_expr_val_str_hexdigits(v1, the, opname);
6189 }
6190 break;
6191 case OPTYPE_STR2OCT:
6192 v1=u.expr.v1;
6193 {
6194 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6195 v1->set_lowerid_to_ref();
6196 tt1=v1->get_expr_returntype(exp_val);
6197 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6198 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6199 chk_expr_val_str_len_even(v1, the, opname);
6200 chk_expr_val_str_hexdigits(v1, the, opname);
6201 }
6202 break;
6203 case OPTYPE_ENUM2INT:
6204 v1=u.expr.v1;
6205 {
6206 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6207 chk_expr_operandtype_enum(opname, v1, exp_val);
6208 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6209 }
6210 break;
6211 case OPTYPE_ENCODE:
6212 chk_expr_operand_encode(refch, exp_val);
6213 break;
6214 case OPTYPE_FLOAT2INT:
6215 case OPTYPE_FLOAT2STR:
6216 v1=u.expr.v1;
6217 {
6218 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6219 v1->set_lowerid_to_ref();
6220 tt1=v1->get_expr_returntype(exp_val);
6221 chk_expr_operandtype_float(tt1, the, opname, v1);
6222 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6223 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6224 chk_expr_operand_valid_float(v1, the, opname);
6225 }
6226 break;
6227 case OPTYPE_RNDWITHVAL:
6228 v1=u.expr.v1;
6229 {
6230 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6231 v1->set_lowerid_to_ref();
6232 tt1=v1->get_expr_returntype(exp_val);
6233 chk_expr_operandtype_float(tt1, the, opname, v1);
6234 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6235 chk_expr_operand_valid_float(v1, the, opname);
6236 }
6237 chk_expr_dynamic_part(exp_val, true);
6238 break;
6239 case OPTYPE_HEX2BIT:
6240 case OPTYPE_HEX2OCT:
6241 case OPTYPE_HEX2STR:
6242 v1=u.expr.v1;
6243 {
6244 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6245 v1->set_lowerid_to_ref();
6246 tt1=v1->get_expr_returntype(exp_val);
6247 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6248 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6249 }
6250 break;
6251 case OPTYPE_HEX2INT:
6252 v1=u.expr.v1;
6253 {
6254 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6255 v1->set_lowerid_to_ref();
6256 tt1=v1->get_expr_returntype(exp_val);
6257 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6258 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6259 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6260 }
6261 break;
6262 case OPTYPE_INT2CHAR:
6263 v1=u.expr.v1;
6264 {
6265 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6266 v1->set_lowerid_to_ref();
6267 tt1=v1->get_expr_returntype(exp_val);
6268 chk_expr_operandtype_int(tt1, the, opname, v1);
6269 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6270 chk_expr_val_int_pos7bit(v1, the, opname);
6271 }
6272 break;
6273 case OPTYPE_INT2UNICHAR:
6274 v1=u.expr.v1;
6275 {
6276 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6277 v1->set_lowerid_to_ref();
6278 tt1=v1->get_expr_returntype(exp_val);
6279 chk_expr_operandtype_int(tt1, the, opname, v1);
6280 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6281 chk_expr_val_int_pos31bit(v1, first, opname);
6282 }
6283 break;
6284 case OPTYPE_INT2FLOAT:
6285 case OPTYPE_INT2STR:
6286 v1=u.expr.v1;
6287 {
6288 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6289 v1->set_lowerid_to_ref();
6290 tt1=v1->get_expr_returntype(exp_val);
6291 chk_expr_operandtype_int(tt1, the, opname, v1);
6292 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6293 }
6294 break;
6295 case OPTYPE_OCT2BIT:
6296 case OPTYPE_OCT2HEX:
6297 case OPTYPE_OCT2STR:
6298 v1=u.expr.v1;
6299 {
6300 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6301 v1->set_lowerid_to_ref();
6302 tt1=v1->get_expr_returntype(exp_val);
6303 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6304 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6305 }
6306 break;
6307 case OPTYPE_OCT2INT:
6308 v1=u.expr.v1;
6309 {
6310 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6311 v1->set_lowerid_to_ref();
6312 tt1=v1->get_expr_returntype(exp_val);
6313 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6314 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6315 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6316 // now.
6317 }
6318 break;
6319 case OPTYPE_OCT2CHAR:
6320 v1=u.expr.v1;
6321 {
6322 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6323 v1->set_lowerid_to_ref();
6324 tt1=v1->get_expr_returntype(exp_val);
6325 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6326 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6327 chk_expr_val_str_7bitoctets(v1, the, opname);
6328 }
6329 break;
6330 case OPTYPE_REMOVE_BOM:
6331 v1=u.expr.v1;
6332 {
6333 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6334 v1->set_lowerid_to_ref();
6335 tt1=v1->get_expr_returntype(exp_val);
6336 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6337 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6338 }
6339 break;
6340 case OPTYPE_GET_STRINGENCODING:
6341 v1=u.expr.v1;
6342 {
6343 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6344 v1->set_lowerid_to_ref();
6345 tt1=v1->get_expr_returntype(exp_val);
6346 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6347 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6348 }
6349 break;
6350 case OPTYPE_ENCODE_BASE64:
6351 v1=u.expr.v1;
6352 {
6353 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6354 v1->set_lowerid_to_ref();
6355 tt1=v1->get_expr_returntype(exp_val);
6356 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6357 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6358 }
6359 v2=u.expr.v2 ? u.expr.v2 : 0;
6360 if (v2)
6361 {
6362 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6363 v2->set_lowerid_to_ref();
6364 tt2=v2->get_expr_returntype(exp_val);
6365 chk_expr_operandtype_bool(tt2, second, opname, v2);
6366 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6367 }
6368 break;
6369 case OPTYPE_DECODE_BASE64:
6370 v1=u.expr.v1;
6371 {
6372 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6373 v1->set_lowerid_to_ref();
6374 tt1=v1->get_expr_returntype(exp_val);
6375 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6376 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6377 }
6378 break;
6379 case OPTYPE_UNICHAR2INT:
6380 v1=u.expr.v1;
6381 {
6382 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6383 v1->set_lowerid_to_ref();
6384 tt1=v1->get_expr_returntype(exp_val);
6385 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6386 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6387 chk_expr_val_len1(v1, the, opname);
6388 }
6389 break;
6390 case OPTYPE_UNICHAR2CHAR:
6391 v1=u.expr.v1;
6392 {
6393 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6394 v1->set_lowerid_to_ref();
6395 tt1=v1->get_expr_returntype(exp_val);
6396 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6397 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6398 chk_expr_val_ustr_7bitchars(v1, the, opname);
6399 }
6400 break;
6401 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6402 v1=u.expr.v1;
6403 {
6404 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6405 v1->set_lowerid_to_ref();
6406 tt1=v1->get_expr_returntype(exp_val);
6407 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6408 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6409 }
6410 v2=u.expr.v2 ? u.expr.v2 : 0;
6411 if (v2)
6412 {
6413 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6414 v2->set_lowerid_to_ref();
6415 tt2=v2->get_expr_returntype(exp_val);
6416 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6417 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6418 }
6419 break;
6420 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6421 v1=u.expr.v1;
6422 {
6423 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6424 v1->set_lowerid_to_ref();
6425 tt1=v1->get_expr_returntype(exp_val);
6426 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6427 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6428 }
6429 v2=u.expr.v2 ? u.expr.v2 : 0;
6430 if (v2)
6431 {
6432 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6433 v2->set_lowerid_to_ref();
6434 tt2=v2->get_expr_returntype(exp_val);
6435 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6436 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6437 }
6438 break;
6439 case OPTYPE_ADD: // v1 v2
6440 case OPTYPE_SUBTRACT:
6441 case OPTYPE_MULTIPLY:
6442 case OPTYPE_DIVIDE:
6443 v1=u.expr.v1;
6444 {
6445 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6446 v1->set_lowerid_to_ref();
6447 tt1=v1->get_expr_returntype(exp_val);
6448 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6449 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6450 chk_expr_operand_valid_float(v1, first, opname);
6451 }
6452 v2=u.expr.v2;
6453 {
6454 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6455 v2->set_lowerid_to_ref();
6456 tt2=v2->get_expr_returntype(exp_val);
6457 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6458 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6459 chk_expr_operand_valid_float(v2, second, opname);
6460 if(u.expr.v_optype==OPTYPE_DIVIDE)
6461 chk_expr_val_int_float_not0(v2, second, opname);
6462 }
6463 chk_expr_operandtypes_same(tt1, tt2, opname);
6464 break;
6465 case OPTYPE_MOD:
6466 case OPTYPE_REM:
6467 v1=u.expr.v1;
6468 {
6469 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6470 v1->set_lowerid_to_ref();
6471 tt1=v1->get_expr_returntype(exp_val);
6472 chk_expr_operandtype_int(tt1, left, opname, v1);
6473 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6474 }
6475 v2=u.expr.v2;
6476 {
6477 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6478 v2->set_lowerid_to_ref();
6479 tt2=v2->get_expr_returntype(exp_val);
6480 chk_expr_operandtype_int(tt2, right, opname, v2);
6481 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6482 chk_expr_val_int_float_not0(v2, right, opname);
6483 }
6484 break;
6485 case OPTYPE_CONCAT: {
6486 v1=u.expr.v1;
6487 v2=u.expr.v2;
6488 v1->set_lowerid_to_ref();
6489 v2->set_lowerid_to_ref();
6490 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6491 {
6492 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6493 tt1=v1->get_expr_returntype(exp_val);
6494 chk_expr_operandtype_str(tt1, left, opname, v1);
6495 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6496 }
6497 {
6498 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6499 tt2=v2->get_expr_returntype(exp_val);
6500 chk_expr_operandtype_str(tt2, right, opname, v2);
6501 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6502 }
6503 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6504 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6505 chk_expr_operandtypes_same(tt1, tt2, opname);
6506 } else { // other list types
6507 Type* v1_gov = v1->get_expr_governor(exp_val);
6508 Type* v2_gov = v2->get_expr_governor(exp_val);
6509 if (!v1_gov) {
6510 error("Cannot determine the type of the left operand of `%s' operation", opname);
6511 set_valuetype(V_ERROR);
6512 return;
6513 } else {
6514 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6515 v1_gov->chk_this_value_ref(v1);
6516 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6517 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6518 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6519 }
6520 if (!v2_gov) {
6521 if (!v1_gov) {
6522 error("Cannot determine the type of the right operand of `%s' operation", opname);
6523 set_valuetype(V_ERROR);
6524 return;
6525 }
6526 // for recof/setof literals set the type from v1
6527 v2_gov = v1_gov;
6528 v2->set_my_governor(v1_gov);
6529 }
6530 {
6531 Error_Context cntxt(this, "In the right operand of operation `%s'",
6532 opname);
6533 v2_gov->chk_this_value_ref(v2);
6534 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6535 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6536 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6537 if (valuetype == V_ERROR) return;
6538 // 7.1.2 says that we shouldn't allow type compatibility.
6539 if (!v1_gov->is_compatible(v2_gov, NULL)
6540 && !v2_gov->is_compatible(v1_gov, NULL)) {
6541 error("The operands of operation `%s' should be of compatible "
6542 "types", get_opname());
6543 }
6544 }
6545 }
6546 break; }
6547 case OPTYPE_EQ:
6548 case OPTYPE_NE:
6549 v1 = u.expr.v1;
6550 v2 = u.expr.v2;
6551 chk_expr_operandtypes_compat(exp_val, v1, v2);
6552 {
6553 Error_Context cntxt(this, "In the left operand of operation `%s'",
6554 opname);
6555 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6556 }
6557 {
6558 Error_Context cntxt(this, "In the right operand of operation `%s'",
6559 opname);
6560 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6561 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6562 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6563 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6564 * "a == not b" is not allowed. (HL69107)
6565 * The various *Expressions implement operator precedence in the std.
6566 * Titan's parser has only one Expression and relies on Bison
6567 * for operator precedence. The check below brings Titan in line
6568 * with the standard by explicitly making "a == not b" an error */
6569 if (v2->get_valuetype() == V_EXPR
6570 && v2->u.expr.v_optype == OPTYPE_NOT) {
6571 error("The operation `%s' is not allowed to be "
6572 "the second operand of operation `%s'", v2->get_opname(), opname);
6573 set_valuetype(V_ERROR);
6574 }
6575 }
6576 break;
6577 case OPTYPE_LT:
6578 case OPTYPE_GT:
6579 case OPTYPE_GE:
6580 case OPTYPE_LE:
6581 v1=u.expr.v1;
6582 v2=u.expr.v2;
6583 chk_expr_operandtypes_compat(exp_val, v1, v2);
6584 {
6585 Error_Context cntxt(this, "In the left operand of operation `%s'",
6586 opname);
6587 tt1=v1->get_expr_returntype(exp_val);
6588 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6589 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6590 }
6591 {
6592 Error_Context cntxt(this, "In the right operand of operation `%s'",
6593 opname);
6594 tt2=v2->get_expr_returntype(exp_val);
6595 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6596 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6597 }
6598 break;
6599 case OPTYPE_AND:
6600 case OPTYPE_OR:
6601 case OPTYPE_XOR:
6602 v1=u.expr.v1;
6603 {
6604 Error_Context cntxt(this, "In the left operand of operation `%s'",
6605 opname);
6606 v1->set_lowerid_to_ref();
6607 tt1=v1->get_expr_returntype(exp_val);
6608 chk_expr_operandtype_bool(tt1, left, opname, v1);
6609 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6610 }
6611 v2=u.expr.v2;
6612 {
6613 Error_Context cntxt(this, "In the right operand of operation `%s'",
6614 opname);
6615 v2->set_lowerid_to_ref();
6616 tt2=v2->get_expr_returntype(exp_val);
6617 chk_expr_operandtype_bool(tt2, right, opname, v2);
6618 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6619 }
6620 break;
6621 case OPTYPE_AND4B:
6622 case OPTYPE_OR4B:
6623 case OPTYPE_XOR4B:
6624 v1=u.expr.v1;
6625 {
6626 Error_Context cntxt(this, "In the left operand of operation `%s'",
6627 opname);
6628 v1->set_lowerid_to_ref();
6629 tt1=v1->get_expr_returntype(exp_val);
6630 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6631 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6632 }
6633 v2=u.expr.v2;
6634 {
6635 Error_Context cntxt(this, "In the right operand of operation `%s'",
6636 opname);
6637 v2->set_lowerid_to_ref();
6638 tt2=v2->get_expr_returntype(exp_val);
6639 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6640 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6641 }
6642 chk_expr_operandtypes_same(tt1, tt2, opname);
6643 chk_expr_operands_str_samelen();
6644 break;
6645 case OPTYPE_SHL:
6646 case OPTYPE_SHR:
6647 v1=u.expr.v1;
6648 {
6649 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6650 v1->set_lowerid_to_ref();
6651 tt1=v1->get_expr_returntype(exp_val);
6652 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6653 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6654 }
6655 v2=u.expr.v2;
6656 {
6657 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6658 v2->set_lowerid_to_ref();
6659 tt2=v2->get_expr_returntype(exp_val);
6660 chk_expr_operandtype_int(tt2, right, opname, v2);
6661 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6662 chk_expr_val_large_int(v2, right, opname);
6663 }
6664 break;
6665 case OPTYPE_ROTL:
6666 case OPTYPE_ROTR:
6667 v1=u.expr.v1;
6668 v1->set_lowerid_to_ref();
6669 if (v1->is_string_type(exp_val)) {
6670 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6671 tt1=v1->get_expr_returntype(exp_val);
6672 chk_expr_operandtype_str(tt1, left, opname, v1);
6673 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6674 } else { // other list types
6675 Type* v1_gov = v1->get_expr_governor(exp_val);
6676 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6677 error("Cannot determine the type of the left operand of `%s' operation", opname);
6678 } else {
6679 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6680 v1_gov->chk_this_value_ref(v1);
6681 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6682 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6683 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6684 }
6685 }
6686 v2=u.expr.v2;
6687 {
6688 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6689 v2->set_lowerid_to_ref();
6690 tt2=v2->get_expr_returntype(exp_val);
6691 chk_expr_operandtype_int(tt2, right, opname, v2);
6692 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6693 chk_expr_val_large_int(v2, right, opname);
6694 }
6695 break;
6696 case OPTYPE_INT2BIT:
6697 case OPTYPE_INT2HEX:
6698 case OPTYPE_INT2OCT:
6699 v1=u.expr.v1;
6700 {
6701 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6702 v1->set_lowerid_to_ref();
6703 tt1=v1->get_expr_returntype(exp_val);
6704 chk_expr_operandtype_int(tt1, first, opname, v1);
6705 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6706 chk_expr_val_int_pos0(v1, first, opname);
6707 }
6708 v2=u.expr.v2;
6709 {
6710 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6711 v2->set_lowerid_to_ref();
6712 tt2=v2->get_expr_returntype(exp_val);
6713 chk_expr_operandtype_int(tt2, second, opname, v2);
6714 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6715 chk_expr_val_int_pos0(v2, second, opname);
6716 }
6717 chk_expr_operands_int2binstr();
6718 break;
6719 case OPTYPE_DECODE:
6720 chk_expr_operands_decode();
6721 break;
6722 case OPTYPE_SUBSTR:
6723 {
6724 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6725 Type::expected_value_t ti_exp_val = exp_val;
6726 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6727 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6728 if (!governor) return;
6729 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6730 if (valuetype!=V_ERROR)
6731 u.expr.ti1->get_Template()->chk_specific_value(false);
6732 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6733 }
6734 v2=u.expr.v2;
6735 {
6736 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6737 v2->set_lowerid_to_ref();
6738 tt2=v2->get_expr_returntype(exp_val);
6739 chk_expr_operandtype_int(tt2, second, opname, v2);
6740 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6741 chk_expr_val_int_pos0(v2, second, opname);
6742 }
6743 v3=u.expr.v3;
6744 {
6745 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6746 v3->set_lowerid_to_ref();
6747 tt3=v3->get_expr_returntype(exp_val);
6748 chk_expr_operandtype_int(tt3, third, opname, v3);
6749 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6750 chk_expr_val_int_pos0(v3, third, opname);
6751 }
6752 chk_expr_operands_substr();
6753 break;
6754 case OPTYPE_REGEXP: {
6755 Type::expected_value_t ti_exp_val = exp_val;
6756 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6757 {
6758 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6759 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6760 if (!governor) return;
6761 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6762 if (valuetype!=V_ERROR) {
6763 u.expr.ti1->get_Template()->chk_specific_value(false);
6764 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6765 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6766 }
6767 }
6768 {
6769 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6770 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6771 if (!governor) return;
6772 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6773 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6774 get_typetype_ttcn3(), second, opname, u.expr.t2);
6775 }
6776 v3=u.expr.v3;
6777 {
6778 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6779 v3->set_lowerid_to_ref();
6780 tt3=v3->get_expr_returntype(exp_val);
6781 chk_expr_operandtype_int(tt3, third, opname, v3);
6782 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6783 chk_expr_val_int_pos0(v3, third, opname);
6784 }
6785 chk_expr_operands_regexp();
6786 } break;
6787 case OPTYPE_ISCHOSEN:
6788 // do nothing: the operand is erroneous
6789 // the error was already reported in chk_expr_ref_ischosen()
6790 break;
6791 case OPTYPE_ISCHOSEN_V: // v1 i2
6792 case OPTYPE_ISCHOSEN_T: // t1 i2
6793 chk_expr_operands_ischosen(refch, exp_val);
6794 break;
6795 case OPTYPE_VALUEOF: { // ti1
6796 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6797 exp_val = Type::EXPECTED_TEMPLATE;
6798 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6799 Type *governor = my_governor;
6800 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6801 if (!governor) return;
6802 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6803 if (valuetype == V_ERROR) return;
6804 u.expr.ti1->get_Template()->chk_specific_value(false);
6805 break; }
6806 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6807 case OPTYPE_ISBOUND: {
6808 Template *templ = u.expr.ti1->get_Template();
6809 switch (templ->get_templatetype()) {
6810 case Template::TEMPLATE_REFD:
6811 templ->get_reference()->setUsedInIsbound();
6812 break;
6813 case Template::SPECIFIC_VALUE: {
6814 Value *value = templ->get_specific_value();
6815 if (Value::V_REFD == value->get_valuetype()) {
6816 value->get_reference()->setUsedInIsbound();
6817 }
6818 break; }
6819 default:
6820 break;
6821 }
6822 }
6823 // no break
6824 case OPTYPE_ISVALUE: {// ti1
6825 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6826 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6827 exp_val = Type::EXPECTED_TEMPLATE;
6828 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6829 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6830 if (!governor) return;
6831 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6832 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6833 break; }
6834 case OPTYPE_SIZEOF: // ti1
6835 /* this checking is too complex, do the checking during eval... */
6836 break;
6837 case OPTYPE_LENGTHOF: { // ti1
6838 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6839 exp_val = Type::EXPECTED_TEMPLATE;
6840 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6841 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6842 if (!governor) return;
6843 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
6844 if (valuetype == V_ERROR) return;
6845 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6846 break; }
6847 case OPTYPE_MATCH: // v1 t2
6848 chk_expr_operands_match(exp_val);
6849 break;
6850 case OPTYPE_UNDEF_RUNNING: // r1
6851 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
6852 break;
6853 case OPTYPE_COMP_ALIVE:
6854 case OPTYPE_COMP_RUNNING: //v1
6855 chk_expr_operand_compref(u.expr.v1, the, opname);
6856 chk_expr_dynamic_part(exp_val, false);
6857 break;
6858 case OPTYPE_TMR_READ: // r1
6859 case OPTYPE_TMR_RUNNING: // r1
6860 chk_expr_operand_tmrref(u.expr.r1, the, opname);
6861 chk_expr_dynamic_part(exp_val, true);
6862 break;
6863 case OPTYPE_EXECUTE: // r1 [v2] // testcase
6864 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
6865 chk_expr_dynamic_part(exp_val, true, false, false);
6866 break;
6867 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
6868 chk_expr_operand_comptyperef_create();
6869 v2=u.expr.v2;
6870 if(v2) {
6871 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6872 v2->set_lowerid_to_ref();
6873 tt2=v2->get_expr_returntype(exp_val);
6874 chk_expr_operandtype_cstr(tt2, first, opname, v2);
6875 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6876 }
6877 v3=u.expr.v3;
6878 if(v3) {
6879 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6880 v3->set_lowerid_to_ref();
6881 tt3=v3->get_expr_returntype(exp_val);
6882 chk_expr_operandtype_cstr(tt3, second, opname, v3);
6883 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6884 }
6885 chk_expr_dynamic_part(exp_val, false);
6886 break;
6887 case OPTYPE_ACTIVATE: // r1 // altstep
6888 chk_expr_operand_activate(u.expr.r1, the, opname);
6889 chk_expr_dynamic_part(exp_val, true);
6890 break;
6891 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
6892 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6893 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
6894 opname);
6895 delete u.expr.t_list2;
6896 u.expr.ap_list2 = parlist;
6897 chk_expr_dynamic_part(exp_val, true);
6898 break; }
6899 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
6900 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6901 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
6902 u.expr.v3, the, opname);
6903 delete u.expr.t_list2;
6904 u.expr.ap_list2 = parlist;
6905 chk_expr_dynamic_part(exp_val, true);
6906 break; }
6907 case OPTYPE_DECOMP:
6908 error("Built-in function `%s' is not yet supported", opname);
6909 set_valuetype(V_ERROR);
6910 break;
6911 case OPTYPE_REPLACE: {
6912 Type::expected_value_t ti_exp_val = exp_val;
6913 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6914 ti_exp_val = Type::EXPECTED_TEMPLATE;
6915 {
6916 Error_Context cntxt(this, "In the first operand of operation `%s'",
6917 opname);
6918 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6919 if (!governor) return;
6920 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6921 if (valuetype != V_ERROR)
6922 u.expr.ti1->get_Template()->chk_specific_value(false);
6923 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6924 }
6925 v2 = u.expr.v2;
6926 {
6927 Error_Context cntxt(this, "In the second operand of operation `%s'",
6928 opname);
6929 v2->set_lowerid_to_ref();
6930 tt2 = v2->get_expr_returntype(exp_val);
6931 chk_expr_operandtype_int(tt2, second, opname, v2);
6932 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6933 chk_expr_val_int_pos0(v2, second, opname);
6934 }
6935 v3 = u.expr.v3;
6936 {
6937 Error_Context cntxt(this, "In the third operand of operation `%s'",
6938 opname);
6939 v3->set_lowerid_to_ref();
6940 tt3 = v3->get_expr_returntype(exp_val);
6941 chk_expr_operandtype_int(tt3, third, opname, v3);
6942 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6943 chk_expr_val_int_pos0(v3, third, opname);
6944 }
6945 {
6946 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
6947 opname);
6948 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
6949 if (!governor) return;
6950 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
6951 if (valuetype != V_ERROR)
6952 u.expr.ti4->get_Template()->chk_specific_value(false);
6953 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
6954 }
6955 chk_expr_operands_replace();
6956 break; }
6957 case OPTYPE_LOG2STR: {
6958 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6959 u.expr.logargs->chk();
6960 if (!semantic_check_only) u.expr.logargs->join_strings();
6961 break; }
6962 case OPTYPE_TTCN2STRING: {
6963 Error_Context cntxt(this, "In the parameter of ttcn2string()");
6964 Type::expected_value_t ti_exp_val = exp_val;
6965 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6966 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6967 if (!governor) return;
6968 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6969 } break;
6970 default:
6971 FATAL_ERROR("chk_expr_operands()");
6972 } // switch optype
6973 }
6974
6975 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6976 // the result of evaluating the expression. E.g. V_BOOL for
6977 // OPTYPE_ISCHOSEN.
6978 void Value::evaluate_value(ReferenceChain *refch,
6979 Type::expected_value_t exp_val)
6980 {
6981 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
6982 if(u.expr.state!=EXPR_NOT_CHECKED) return;
6983
6984 u.expr.state=EXPR_CHECKING;
6985
6986 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
6987 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
6988 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
6989
6990 if(valuetype==V_ERROR) return;
6991 if(u.expr.state==EXPR_CHECKING_ERR) {
6992 u.expr.state=EXPR_CHECKED;
6993 set_valuetype(V_ERROR);
6994 return;
6995 }
6996
6997 u.expr.state=EXPR_CHECKED;
6998
6999 Value *v1, *v2, *v3, *v4;
7000 switch(u.expr.v_optype) {
7001 case OPTYPE_RND: // -
7002 case OPTYPE_COMP_NULL: // the only foldable in this group
7003 case OPTYPE_COMP_MTC:
7004 case OPTYPE_COMP_SYSTEM:
7005 case OPTYPE_COMP_SELF:
7006 case OPTYPE_COMP_RUNNING_ANY:
7007 case OPTYPE_COMP_RUNNING_ALL:
7008 case OPTYPE_COMP_ALIVE_ANY:
7009 case OPTYPE_COMP_ALIVE_ALL:
7010 case OPTYPE_TMR_RUNNING_ANY:
7011 case OPTYPE_GETVERDICT:
7012 case OPTYPE_PROF_RUNNING:
7013 case OPTYPE_RNDWITHVAL: // v1
7014 case OPTYPE_COMP_RUNNING: // v1
7015 case OPTYPE_COMP_ALIVE:
7016 case OPTYPE_TMR_READ:
7017 case OPTYPE_TMR_RUNNING:
7018 case OPTYPE_ACTIVATE:
7019 case OPTYPE_ACTIVATE_REFD:
7020 case OPTYPE_EXECUTE: // r1 [v2]
7021 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7022 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7023 case OPTYPE_MATCH: // v1 t2
7024 case OPTYPE_ISCHOSEN_T:
7025 case OPTYPE_LOG2STR:
7026 case OPTYPE_ENCODE:
7027 case OPTYPE_DECODE:
7028 case OPTYPE_ISBOUND:
7029 case OPTYPE_ISPRESENT:
7030 case OPTYPE_TTCN2STRING:
7031 case OPTYPE_UNICHAR2OCT:
7032 case OPTYPE_OCT2UNICHAR:
7033 case OPTYPE_ENCODE_BASE64:
7034 case OPTYPE_DECODE_BASE64:
7035 break;
7036 case OPTYPE_TESTCASENAME: { // -
7037 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7038 Ttcn::StatementBlock *my_sb =
7039 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7040 if (!my_sb) break;
7041 Ttcn::Definition *my_def = my_sb->get_my_def();
7042 if (!my_def) { // In control part.
7043 set_val_str(new string(""));
7044 valuetype = V_CSTR;
7045 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7046 set_val_str(new string(my_def->get_id().get_dispname()));
7047 valuetype = V_CSTR;
7048 }
7049 break; }
7050 case OPTYPE_UNARYPLUS: // v1
7051 v1=u.expr.v1;
7052 u.expr.v1=0;
7053 copy_and_destroy(v1);
7054 break;
7055 case OPTYPE_UNARYMINUS:
7056 if (is_unfoldable()) break;
7057 v1 = u.expr.v1->get_value_refd_last();
7058 switch (v1->valuetype) {
7059 case V_INT: {
7060 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7061 if (!i) FATAL_ERROR("Value::evaluate_value()");
7062 clean_up();
7063 valuetype = V_INT;
7064 u.val_Int = i;
7065 break; }
7066 case V_REAL: {
7067 ttcn3float r = v1->get_val_Real();
7068 clean_up();
7069 valuetype = V_REAL;
7070 u.val_Real = -r;
7071 break; }
7072 default:
7073 FATAL_ERROR("Value::evaluate_value()");
7074 }
7075 break;
7076 case OPTYPE_NOT: {
7077 if(is_unfoldable()) break;
7078 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7079 clean_up();
7080 valuetype=V_BOOL;
7081 u.val_bool=!b;
7082 break;}
7083 case OPTYPE_NOT4B: {
7084 if(is_unfoldable()) break;
7085 v1=u.expr.v1->get_value_refd_last();
7086 const string& s = v1->get_val_str();
7087 valuetype_t vt=v1->valuetype;
7088 clean_up();
7089 valuetype=vt;
7090 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7091 break;}
7092 case OPTYPE_BIT2HEX: {
7093 if(is_unfoldable()) break;
7094 v1=u.expr.v1->get_value_refd_last();
7095 const string& s = v1->get_val_str();
7096 clean_up();
7097 valuetype=V_HSTR;
7098 set_val_str(bit2hex(s));
7099 break;}
7100 case OPTYPE_BIT2OCT: {
7101 if(is_unfoldable()) break;
7102 v1=u.expr.v1->get_value_refd_last();
7103 const string& s = v1->get_val_str();
7104 clean_up();
7105 valuetype=V_OSTR;
7106 set_val_str(bit2oct(s));
7107 break;}
7108 case OPTYPE_BIT2STR:
7109 case OPTYPE_HEX2STR:
7110 case OPTYPE_OCT2STR: {
7111 if(is_unfoldable()) break;
7112 v1=u.expr.v1->get_value_refd_last();
7113 const string& s = v1->get_val_str();
7114 clean_up();
7115 valuetype=V_CSTR;
7116 set_val_str(new string(s));
7117 break;}
7118 case OPTYPE_BIT2INT: {
7119 if (is_unfoldable()) break;
7120 v1 = u.expr.v1->get_value_refd_last();
7121 const string& s = v1->get_val_str();
7122 clean_up();
7123 valuetype = V_INT;
7124 u.val_Int = bit2int(s);
7125 break; }
7126 case OPTYPE_CHAR2INT: {
7127 if (is_unfoldable()) break;
7128 v1 = u.expr.v1->get_value_refd_last();
7129 char c = v1->get_val_str()[0];
7130 clean_up();
7131 valuetype = V_INT;
7132 u.val_Int = new int_val_t((Int)c);
7133 break; }
7134 case OPTYPE_CHAR2OCT: {
7135 if(is_unfoldable()) break;
7136 v1=u.expr.v1->get_value_refd_last();
7137 const string& s = v1->get_val_str();
7138 clean_up();
7139 valuetype=V_OSTR;
7140 set_val_str(char2oct(s));
7141 break;}
7142 case OPTYPE_STR2INT: {
7143 if (is_unfoldable()) break;
7144 v1 = u.expr.v1->get_value_refd_last();
7145 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7146 clean_up();
7147 valuetype = V_INT;
7148 u.val_Int = i;
7149 /** \todo hiba eseten lenyeli... */
7150 break; }
7151 case OPTYPE_STR2FLOAT: {
7152 if(is_unfoldable()) break;
7153 v1=u.expr.v1->get_value_refd_last();
7154 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7155 clean_up();
7156 valuetype=V_REAL;
7157 u.val_Real=r;
7158 /** \todo hiba eseten lenyeli... */
7159 break;}
7160 case OPTYPE_STR2BIT: {
7161 if(is_unfoldable()) break;
7162 v1=u.expr.v1->get_value_refd_last();
7163 const string& s = v1->get_val_str();
7164 clean_up();
7165 valuetype=V_BSTR;
7166 set_val_str(new string(s));
7167 break;}
7168 case OPTYPE_STR2HEX:
7169 case OPTYPE_OCT2HEX: {
7170 if(is_unfoldable()) break;
7171 v1=u.expr.v1->get_value_refd_last();
7172 const string& s = v1->get_val_str();
7173 clean_up();
7174 valuetype=V_HSTR;
7175 set_val_str(to_uppercase(s));
7176 break;}
7177 case OPTYPE_STR2OCT: {
7178 if(is_unfoldable()) break;
7179 v1=u.expr.v1->get_value_refd_last();
7180 const string& s = v1->get_val_str();
7181 clean_up();
7182 valuetype=V_OSTR;
7183 set_val_str(to_uppercase(s));
7184 break;}
7185 case OPTYPE_FLOAT2INT: {
7186 if (is_unfoldable()) break;
7187 v1 = u.expr.v1->get_value_refd_last();
7188 ttcn3float r = v1->get_val_Real();
7189 clean_up();
7190 valuetype = V_INT;
7191 u.val_Int = float2int(r, *u.expr.v1);
7192 break;}
7193 case OPTYPE_FLOAT2STR: {
7194 if(is_unfoldable()) break;
7195 v1=u.expr.v1->get_value_refd_last();
7196 ttcn3float r=v1->get_val_Real();
7197 clean_up();
7198 valuetype=V_CSTR;
7199 set_val_str(float2str(r));
7200 break;}
7201 case OPTYPE_HEX2BIT:
7202 case OPTYPE_OCT2BIT: {
7203 if(is_unfoldable()) break;
7204 v1=u.expr.v1->get_value_refd_last();
7205 const string& s = v1->get_val_str();
7206 clean_up();
7207 valuetype=V_BSTR;
7208 set_val_str(hex2bit(s));
7209 break;}
7210 case OPTYPE_HEX2INT:
7211 case OPTYPE_OCT2INT: {
7212 if(is_unfoldable()) break;
7213 v1=u.expr.v1->get_value_refd_last();
7214 const string& s = v1->get_val_str();
7215 clean_up();
7216 valuetype=V_INT;
7217 u.val_Int=hex2int(s);
7218 break;}
7219 case OPTYPE_HEX2OCT: {
7220 if(is_unfoldable()) break;
7221 v1=u.expr.v1->get_value_refd_last();
7222 const string& s = v1->get_val_str();
7223 clean_up();
7224 valuetype=V_OSTR;
7225 set_val_str(hex2oct(s));
7226 break;}
7227 case OPTYPE_INT2CHAR: {
7228 if (is_unfoldable()) break;
7229 v1 = u.expr.v1->get_value_refd_last();
7230 const int_val_t *c_int = v1->get_val_Int();
7231 char c = static_cast<char>(c_int->get_val());
7232 clean_up();
7233 valuetype = V_CSTR;
7234 set_val_str(new string(1, &c));
7235 break; }
7236 case OPTYPE_INT2UNICHAR: {
7237 if (is_unfoldable()) break;
7238 v1 = u.expr.v1->get_value_refd_last();
7239 const int_val_t *i_int = v1->get_val_Int();
7240 Int i = i_int->get_val();
7241 clean_up();
7242 valuetype = V_USTR;
7243 set_val_ustr(int2unichar(i));
7244 u.ustr.convert_str = false;
7245 break; }
7246 case OPTYPE_INT2FLOAT: {
7247 if (is_unfoldable()) break;
7248 v1 = u.expr.v1->get_value_refd_last();
7249 const int_val_t *i_int = v1->get_val_Int();
7250 Real i_int_real = i_int->to_real();
7251 clean_up();
7252 valuetype = V_REAL;
7253 u.val_Real = i_int_real;
7254 break; }
7255 case OPTYPE_INT2STR: {
7256 if (is_unfoldable()) break;
7257 v1 = u.expr.v1->get_value_refd_last();
7258 const int_val_t *i_int = v1->get_val_Int();
7259 string *i_int_str = new string(i_int->t_str());
7260 clean_up();
7261 valuetype = V_CSTR;
7262 set_val_str(i_int_str);
7263 break; }
7264 case OPTYPE_OCT2CHAR: {
7265 if(is_unfoldable()) break;
7266 v1=u.expr.v1->get_value_refd_last();
7267 const string& s = v1->get_val_str();
7268 clean_up();
7269 valuetype=V_CSTR;
7270 set_val_str(oct2char(s));
7271 break;}
7272 case OPTYPE_GET_STRINGENCODING: {
7273 if(is_unfoldable()) break;
7274 v1 = u.expr.v1->get_value_refd_last();
7275 const string& s1 = v1->get_val_str();
7276 clean_up();
7277 valuetype = V_CSTR;
7278 set_val_str(get_stringencoding(s1));
7279 break;}
7280 case OPTYPE_REMOVE_BOM: {
7281 if(is_unfoldable()) break;
7282 v1 = u.expr.v1->get_value_refd_last();
7283 const string& s1 = v1->get_val_str();
7284 clean_up();
7285 valuetype = V_OSTR;
7286 set_val_str(remove_bom(s1));
7287 break;}
7288 case OPTYPE_ENUM2INT: {
7289 if(is_unfoldable()) break;
7290 v1=u.expr.v1->get_value_refd_last();
7291 Type* enum_type = v1->get_my_governor();
7292 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7293 clean_up();
7294 valuetype = V_INT;
7295 u.val_Int = new int_val_t(enum_val);
7296 break;}
7297 case OPTYPE_UNICHAR2INT:
7298 if (is_unfoldable()) {
7299 // replace the operation with char2int() if the operand is a charstring
7300 // value to avoid its unnecessary conversion to universal charstring
7301 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7302 u.expr.v_optype = OPTYPE_CHAR2INT;
7303 } else {
7304 v1=u.expr.v1->get_value_refd_last();
7305 const ustring& s = v1->get_val_ustr();
7306 clean_up();
7307 valuetype=V_INT;
7308 u.val_Int=new int_val_t(unichar2int(s));
7309 }
7310 break;
7311 case OPTYPE_UNICHAR2CHAR:
7312 v1 = u.expr.v1;
7313 if (is_unfoldable()) {
7314 // replace the operation with its operand if it is a charstring
7315 // value to avoid its unnecessary conversion to universal charstring
7316 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7317 u.expr.v1 = 0;
7318 copy_and_destroy(v1);
7319 }
7320 } else {
7321 v1 = v1->get_value_refd_last();
7322 const ustring& s = v1->get_val_ustr();
7323 clean_up();
7324 valuetype = V_CSTR;
7325 set_val_str(new string(s));
7326 }
7327 break;
7328 case OPTYPE_MULTIPLY: { // v1 v2
7329 if (!is_unfoldable()) goto eval_arithmetic;
7330 v1 = u.expr.v1->get_value_refd_last();
7331 v2 = u.expr.v2->get_value_refd_last();
7332 if (v1->is_unfoldable()) v1 = v2;
7333 if (v1->is_unfoldable()) break;
7334 switch(v1->valuetype) {
7335 case V_INT: {
7336 if (*v1->get_val_Int() != 0) break;
7337 clean_up();
7338 valuetype = V_INT;
7339 u.val_Int = new int_val_t((Int)0);
7340 break; }
7341 case V_REAL: {
7342 if (v1->get_val_Real() != 0.0) break;
7343 clean_up();
7344 valuetype = V_REAL;
7345 u.val_Real = 0.0;
7346 break; }
7347 default:
7348 FATAL_ERROR("Value::evaluate_value()");
7349 }
7350 break; }
7351 case OPTYPE_ADD: // v1 v2
7352 case OPTYPE_SUBTRACT:
7353 case OPTYPE_DIVIDE:
7354 case OPTYPE_MOD:
7355 case OPTYPE_REM: {
7356 eval_arithmetic:
7357 if(is_unfoldable()) break;
7358 v1=u.expr.v1->get_value_refd_last();
7359 v2=u.expr.v2->get_value_refd_last();
7360 operationtype_t ot=u.expr.v_optype;
7361 switch (v1->valuetype) {
7362 case V_INT: {
7363 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7364 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7365 clean_up();
7366 valuetype = V_INT;
7367 switch (ot) {
7368 case OPTYPE_ADD:
7369 u.val_Int = new int_val_t(*i1 + *i2);
7370 break;
7371 case OPTYPE_SUBTRACT:
7372 u.val_Int = new int_val_t(*i1 - *i2);
7373 break;
7374 case OPTYPE_MULTIPLY:
7375 u.val_Int = new int_val_t(*i1 * *i2);
7376 break;
7377 case OPTYPE_DIVIDE:
7378 u.val_Int = new int_val_t(*i1 / *i2);
7379 break;
7380 case OPTYPE_MOD:
7381 u.val_Int = new int_val_t(mod(*i1, *i2));
7382 break;
7383 case OPTYPE_REM:
7384 u.val_Int = new int_val_t(rem(*i1, *i2));
7385 break;
7386 default:
7387 FATAL_ERROR("Value::evaluate_value()");
7388 }
7389 delete i1;
7390 delete i2;
7391 break; }
7392 case V_REAL: {
7393 ttcn3float r1=v1->get_val_Real();
7394 ttcn3float r2=v2->get_val_Real();
7395 clean_up();
7396 valuetype=V_REAL;
7397 switch(ot) {
7398 case OPTYPE_ADD:
7399 u.val_Real=r1+r2;
7400 break;
7401 case OPTYPE_SUBTRACT:
7402 u.val_Real=r1-r2;
7403 break;
7404 case OPTYPE_MULTIPLY:
7405 u.val_Real=r1*r2;
7406 break;
7407 case OPTYPE_DIVIDE:
7408 u.val_Real=r1/r2;
7409 break;
7410 default:
7411 FATAL_ERROR("Value::evaluate_value()");
7412 }
7413 break;}
7414 default:
7415 FATAL_ERROR("Value::evaluate_value()");
7416 }
7417 break;}
7418 case OPTYPE_CONCAT: {
7419 if(is_unfoldable()) break;
7420 v1=u.expr.v1->get_value_refd_last();
7421 v2=u.expr.v2->get_value_refd_last();
7422 valuetype_t vt = v1->valuetype;
7423 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7424 const ustring& s1 = v1->get_val_ustr();
7425 const ustring& s2 = v2->get_val_ustr();
7426 clean_up();
7427 valuetype = V_USTR;
7428 set_val_ustr(new ustring(s1 + s2));
7429 u.ustr.convert_str = false;
7430 } else {
7431 const string& s1 = v1->get_val_str();
7432 const string& s2 = v2->get_val_str();
7433 clean_up();
7434 valuetype = vt;
7435 set_val_str(new string(s1 + s2));
7436 }
7437 break;}
7438 case OPTYPE_EQ: {
7439 if(is_unfoldable()) break;
7440 v1=u.expr.v1->get_value_refd_last();
7441 v2=u.expr.v2->get_value_refd_last();
7442 bool b=*v1==*v2;
7443 clean_up();
7444 valuetype=V_BOOL;
7445 u.val_bool=b;
7446 break;}
7447 case OPTYPE_NE: {
7448 if(is_unfoldable()) break;
7449 v1=u.expr.v1->get_value_refd_last();
7450 v2=u.expr.v2->get_value_refd_last();
7451 bool b=*v1==*v2;
7452 clean_up();
7453 valuetype=V_BOOL;
7454 u.val_bool=!b;
7455 break;}
7456 case OPTYPE_LT: {
7457 if(is_unfoldable()) break;
7458 v1=u.expr.v1->get_value_refd_last();
7459 v2=u.expr.v2->get_value_refd_last();
7460 bool b=*v1<*v2;
7461 clean_up();
7462 valuetype=V_BOOL;
7463 u.val_bool=b;
7464 break;}
7465 case OPTYPE_GT: {
7466 if(is_unfoldable()) break;
7467 v1=u.expr.v1->get_value_refd_last();
7468 v2=u.expr.v2->get_value_refd_last();
7469 bool b=*v2<*v1;
7470 clean_up();
7471 valuetype=V_BOOL;
7472 u.val_bool=b;
7473 break;}
7474 case OPTYPE_GE: {
7475 if(is_unfoldable()) break;
7476 v1=u.expr.v1->get_value_refd_last();
7477 v2=u.expr.v2->get_value_refd_last();
7478 bool b=*v1<*v2;
7479 clean_up();
7480 valuetype=V_BOOL;
7481 u.val_bool=!b;
7482 break;}
7483 case OPTYPE_LE: {
7484 if(is_unfoldable()) break;
7485 v1=u.expr.v1->get_value_refd_last();
7486 v2=u.expr.v2->get_value_refd_last();
7487 bool b=*v2<*v1;
7488 clean_up();
7489 valuetype=V_BOOL;
7490 u.val_bool=!b;
7491 break;}
7492 case OPTYPE_AND:
7493 v1 = u.expr.v1->get_value_refd_last();
7494 if (v1->valuetype == V_BOOL) {
7495 if (v1->get_val_bool()) {
7496 // the left operand is a literal "true"
7497 // substitute the expression with the right operand
7498 v2 = u.expr.v2;
7499 u.expr.v2 = 0;
7500 copy_and_destroy(v2);
7501 } else {
7502 // the left operand is a literal "false"
7503 // the result must be false regardless the right operand
7504 // because of the short circuit evaluation rule
7505 clean_up();
7506 valuetype = V_BOOL;
7507 u.val_bool = false;
7508 }
7509 } else {
7510 // we must keep the left operand because of the potential side effects
7511 // the right operand can only be eliminated if it is a literal "true"
7512 v2 = u.expr.v2->get_value_refd_last();
7513 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7514 v1 = u.expr.v1;
7515 u.expr.v1 = 0;
7516 copy_and_destroy(v1);
7517 }
7518 }
7519 break;
7520 case OPTYPE_OR:
7521 v1 = u.expr.v1->get_value_refd_last();
7522 if (v1->valuetype == V_BOOL) {
7523 if (v1->get_val_bool()) {
7524 // the left operand is a literal "true"
7525 // the result must be true regardless the right operand
7526 // because of the short circuit evaluation rule
7527 clean_up();
7528 valuetype = V_BOOL;
7529 u.val_bool = true;
7530 } else {
7531 // the left operand is a literal "false"
7532 // substitute the expression with the right operand
7533 v2 = u.expr.v2;
7534 u.expr.v2 = 0;
7535 copy_and_destroy(v2);
7536 }
7537 } else {
7538 // we must keep the left operand because of the potential side effects
7539 // the right operand can only be eliminated if it is a literal "false"
7540 v2 = u.expr.v2->get_value_refd_last();
7541 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7542 v1 = u.expr.v1;
7543 u.expr.v1 = 0;
7544 copy_and_destroy(v1);
7545 }
7546 }
7547 break;
7548 case OPTYPE_XOR: {
7549 if(is_unfoldable()) break;
7550 v1=u.expr.v1->get_value_refd_last();
7551 v2=u.expr.v2->get_value_refd_last();
7552 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7553 clean_up();
7554 valuetype=V_BOOL;
7555 u.val_bool=b;
7556 break;}
7557 case OPTYPE_AND4B: {
7558 if(is_unfoldable()) break;
7559 v1=u.expr.v1->get_value_refd_last();
7560 v2=u.expr.v2->get_value_refd_last();
7561 valuetype_t vt=v1->valuetype;
7562 const string& s1 = v1->get_val_str();
7563 const string& s2 = v2->get_val_str();
7564 clean_up();
7565 valuetype=vt;
7566 set_val_str(and4b(s1, s2));
7567 break;}
7568 case OPTYPE_OR4B: {
7569 if(is_unfoldable()) break;
7570 v1=u.expr.v1->get_value_refd_last();
7571 v2=u.expr.v2->get_value_refd_last();
7572 valuetype_t vt=v1->valuetype;
7573 const string& s1 = v1->get_val_str();
7574 const string& s2 = v2->get_val_str();
7575 clean_up();
7576 valuetype=vt;
7577 set_val_str(or4b(s1, s2));
7578 break;}
7579 case OPTYPE_XOR4B: {
7580 if(is_unfoldable()) break;
7581 v1=u.expr.v1->get_value_refd_last();
7582 v2=u.expr.v2->get_value_refd_last();
7583 valuetype_t vt=v1->valuetype;
7584 const string& s1 = v1->get_val_str();
7585 const string& s2 = v2->get_val_str();
7586 clean_up();
7587 valuetype=vt;
7588 set_val_str(xor4b(s1, s2));
7589 break;}
7590 case OPTYPE_SHL: {
7591 if(is_unfoldable()) break;
7592 v1=u.expr.v1->get_value_refd_last();
7593 v2=u.expr.v2->get_value_refd_last();
7594 valuetype_t vt=v1->valuetype;
7595 const string& s = v1->get_val_str();
7596 const int_val_t *i_int = v2->get_val_Int();
7597 Int i=i_int->get_val();
7598 if(vt==V_OSTR) i*=2;
7599 clean_up();
7600 valuetype=vt;
7601 set_val_str(shift_left(s, i));
7602 break;}
7603 case OPTYPE_SHR: {
7604 if(is_unfoldable()) break;
7605 v1=u.expr.v1->get_value_refd_last();
7606 v2=u.expr.v2->get_value_refd_last();
7607 valuetype_t vt=v1->valuetype;
7608 const string& s = v1->get_val_str();
7609 const int_val_t *i_int = v2->get_val_Int();
7610 Int i=i_int->get_val();
7611 if(vt==V_OSTR) i*=2;
7612 clean_up();
7613 valuetype=vt;
7614 set_val_str(shift_right(s, i));
7615 break;}
7616 case OPTYPE_ROTL: {
7617 if(is_unfoldable()) break;
7618 v1=u.expr.v1->get_value_refd_last();
7619 v2=u.expr.v2->get_value_refd_last();
7620 valuetype_t vt=v1->valuetype;
7621 const int_val_t *i_int=v2->get_val_Int();
7622 Int i=i_int->get_val();
7623 if(vt==V_USTR) {
7624 const ustring& s = v1->get_val_ustr();
7625 clean_up();
7626 valuetype=vt;
7627 set_val_ustr(rotate_left(s, i));
7628 u.ustr.convert_str = false;
7629 }
7630 else {
7631 if(vt==V_OSTR) i*=2;
7632 const string& s = v1->get_val_str();
7633 clean_up();
7634 valuetype=vt;
7635 set_val_str(rotate_left(s, i));
7636 }
7637 break;}
7638 case OPTYPE_ROTR: {
7639 if(is_unfoldable()) break;
7640 v1=u.expr.v1->get_value_refd_last();
7641 v2=u.expr.v2->get_value_refd_last();
7642 valuetype_t vt=v1->valuetype;
7643 const int_val_t *i_int=v2->get_val_Int();
7644 Int i=i_int->get_val();
7645 if(vt==V_USTR) {
7646 const ustring& s = v1->get_val_ustr();
7647 clean_up();
7648 valuetype=vt;
7649 set_val_ustr(rotate_right(s, i));
7650 u.ustr.convert_str = false;
7651 }
7652 else {
7653 if(vt==V_OSTR) i*=2;
7654 const string& s = v1->get_val_str();
7655 clean_up();
7656 valuetype=vt;
7657 set_val_str(rotate_right(s, i));
7658 }
7659 break;}
7660 case OPTYPE_INT2BIT: {
7661 if (is_unfoldable()) break;
7662 v1 = u.expr.v1->get_value_refd_last();
7663 v2 = u.expr.v2->get_value_refd_last();
7664 const int_val_t *i1_int = v1->get_val_Int();
7665 const int_val_t *i2_int = v2->get_val_Int();
7666 string *val = int2bit(*i1_int, i2_int->get_val());
7667 clean_up();
7668 valuetype = V_BSTR;
7669 set_val_str(val);
7670 break; }
7671 case OPTYPE_INT2HEX: {
7672 if (is_unfoldable()) break;
7673 v1 = u.expr.v1->get_value_refd_last();
7674 v2 = u.expr.v2->get_value_refd_last();
7675 const int_val_t *i1_int = v1->get_val_Int();
7676 const int_val_t *i2_int = v2->get_val_Int();
7677 // Do it before the `clean_up'. i2_int is already checked.
7678 string *val = int2hex(*i1_int, i2_int->get_val());
7679 clean_up();
7680 valuetype = V_HSTR;
7681 set_val_str(val);
7682 break; }
7683 case OPTYPE_INT2OCT: {
7684 if (is_unfoldable()) break;
7685 v1 = u.expr.v1->get_value_refd_last();
7686 v2 = u.expr.v2->get_value_refd_last();
7687 const int_val_t i1_int(*v1->get_val_Int());
7688 // `v2' is a native integer.
7689 Int i2_int = v2->get_val_Int()->get_val() * 2;
7690 clean_up();
7691 valuetype = V_OSTR;
7692 set_val_str(int2hex(i1_int, i2_int));
7693 break; }
7694 case OPTYPE_SUBSTR: {
7695 if(is_unfoldable()) break;
7696 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7697 v2=u.expr.v2->get_value_refd_last();
7698 v3=u.expr.v3->get_value_refd_last();
7699 valuetype_t vt=v1->valuetype;
7700 const int_val_t *i2_int=v2->get_val_Int();
7701 const int_val_t *i3_int=v3->get_val_Int();
7702 Int i2=i2_int->get_val();
7703 Int i3=i3_int->get_val();
7704 if(vt==V_USTR) {
7705 const ustring& s = v1->get_val_ustr();
7706 clean_up();
7707 valuetype=vt;
7708 set_val_ustr(new ustring(s.substr(i2, i3)));
7709 u.ustr.convert_str = false;
7710 }
7711 else {
7712 if(vt==V_OSTR) {
7713 i2*=2;
7714 i3*=2;
7715 }
7716 const string& s = v1->get_val_str();
7717 clean_up();
7718 valuetype=vt;
7719 set_val_str(new string(s.substr(i2, i3)));
7720 }
7721 break;}
7722 case OPTYPE_REPLACE: {
7723 if(is_unfoldable()) break;
7724 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7725 v2=u.expr.v2->get_value_refd_last();
7726 v3=u.expr.v3->get_value_refd_last();
7727 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7728 valuetype_t vt=v1->valuetype;
7729 const int_val_t *i2_int=v2->get_val_Int();
7730 const int_val_t *i3_int=v3->get_val_Int();
7731 Int i2=i2_int->get_val();
7732 Int i3=i3_int->get_val();
7733 switch(vt) {
7734 case V_BSTR: {
7735 string *s1 = new string(v1->get_val_str());
7736 const string& s2 = v4->get_val_str();
7737 clean_up();
7738 valuetype=vt;
7739 s1->replace(i2, i3, s2);
7740 set_val_str(s1);
7741 break;}
7742 case V_HSTR: {
7743 string *s1 = new string(v1->get_val_str());
7744 const string& s2 = v4->get_val_str();
7745 clean_up();
7746 valuetype=vt;
7747 s1->replace(i2, i3, s2);
7748 set_val_str(s1);
7749 break;}
7750 case V_OSTR: {
7751 i2*=2;
7752 i3*=2;
7753 string *s1 = new string(v1->get_val_str());
7754 const string& s2 = v4->get_val_str();
7755 clean_up();
7756 valuetype=vt;
7757 s1->replace(i2, i3, s2);
7758 set_val_str(s1);
7759 break;}
7760 case V_CSTR: {
7761 string *s1 = new string(v1->get_val_str());
7762 const string& s2 = v4->get_val_str();
7763 clean_up();
7764 valuetype=vt;
7765 s1->replace(i2, i3, s2);
7766 set_val_str(s1);
7767 break;}
7768 case V_USTR: {
7769 ustring *s1 = new ustring(v1->get_val_ustr());
7770 const ustring& s2 = v4->get_val_ustr();
7771 clean_up();
7772 valuetype=vt;
7773 s1->replace(i2, i3, s2);
7774 set_val_ustr(s1);
7775 u.ustr.convert_str = false;
7776 break;}
7777 default:
7778 FATAL_ERROR("Value::evaluate_value()");
7779 }
7780 break; }
7781 case OPTYPE_REGEXP: {
7782 if (is_unfoldable()) break;
7783 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7784 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7785 v3=u.expr.v3->get_value_refd_last();
7786 const int_val_t *i3_int = v3->get_val_Int();
7787 Int i3 = i3_int->get_val();
7788 if (v1->valuetype == V_CSTR) {
7789 const string& s1 = v1->get_val_str();
7790 const string& s2 = v2->get_val_str();
7791 string *result = regexp(s1, s2, i3);
7792 clean_up();
7793 valuetype = V_CSTR;
7794 set_val_str(result);
7795 } if (v1->valuetype == V_USTR) {
7796 const ustring& s1 = v1->get_val_ustr();
7797 const ustring& s2 = v2->get_val_ustr();
7798 ustring *result = regexp(s1, s2, i3);
7799 clean_up();
7800 valuetype = V_USTR;
7801 set_val_ustr(result);
7802 u.ustr.convert_str = false;
7803 }
7804 break; }
7805 case OPTYPE_LENGTHOF:{
7806 if(is_unfoldable()) break;
7807 v1=u.expr.ti1->get_Template()->get_specific_value()
7808 ->get_value_refd_last();
7809 size_t i;
7810 if(v1->is_string_type(exp_val)) {
7811 i=v1->get_val_strlen();
7812 } else { // v1 is be seq/set of or array
7813 switch (v1->valuetype) {
7814 case V_SEQOF:
7815 case V_SETOF:
7816 case V_ARRAY: {
7817 if(v1->u.val_vs->is_indexed())
7818 { i = v1->u.val_vs->get_nof_ivs();}
7819 else { i = v1->u.val_vs->get_nof_vs();}
7820 break; }
7821 default:
7822 FATAL_ERROR("Value::evaluate_value()");
7823 }
7824 }
7825 clean_up();
7826 valuetype=V_INT;
7827 u.val_Int=new int_val_t(i);
7828 break;}
7829 case OPTYPE_SIZEOF: {
7830 Int i=chk_eval_expr_sizeof(refch, exp_val);
7831 if(i!=-1) {
7832 clean_up();
7833 valuetype=V_INT;
7834 u.val_Int=new int_val_t(i);
7835 }
7836 break;}
7837 case OPTYPE_ISVALUE: {
7838 if(is_unfoldable()) break;
7839 bool is_singleval = !u.expr.ti1->get_DerivedRef()
7840 && u.expr.ti1->get_Template()->is_Value();
7841 if (is_singleval) {
7842 Value * other_val = u.expr.ti1->get_Template()->get_Value();
7843 is_singleval = other_val->evaluate_isvalue(false);
7844 // is_singleval now contains the compile-time result of isvalue
7845 delete other_val;
7846 }
7847 clean_up();
7848 valuetype = V_BOOL;
7849 u.val_bool = is_singleval;
7850 break;}
7851 case OPTYPE_ISCHOSEN_V: {
7852 if (is_unfoldable()) break;
7853 v1 = u.expr.v1->get_value_refd_last();
7854 bool b = v1->field_is_chosen(*u.expr.i2);
7855 clean_up();
7856 valuetype = V_BOOL;
7857 u.val_bool = b;
7858 break; }
7859 case OPTYPE_VALUEOF: // ti1
7860 if (!u.expr.ti1->get_DerivedRef() &&
7861 u.expr.ti1->get_Template()->is_Value() &&
7862 !u.expr.ti1->get_Type()) {
7863 // FIXME actually if the template instance has a type
7864 // it might still be foldable.
7865 // the argument is a single specific value
7866 v1 = u.expr.ti1->get_Template()->get_Value();
7867 Type *governor = my_governor;
7868 if (governor == NULL) {
7869 governor = u.expr.ti1->get_expr_governor(exp_val);
7870 if (governor != NULL) governor = governor->get_type_refd_last();
7871 }
7872 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
7873 if (governor == NULL)
7874 FATAL_ERROR("Value::evaluate_value()");
7875 clean_up();
7876 valuetype = v1->valuetype;
7877 u = v1->u;
7878 set_my_governor(governor);
7879 if (valuetype == V_REFD && u.ref.refd_last == v1)
7880 u.ref.refd_last = this;
7881 v1->valuetype = V_ERROR;
7882 delete v1;
7883 }
7884 break;
7885 case OPTYPE_UNDEF_RUNNING:
7886 default:
7887 FATAL_ERROR("Value::evaluate_value()");
7888 } // switch optype
7889 }
7890
7891 bool Value::evaluate_isvalue(bool from_sequence)
7892 {
7893 switch (valuetype) {
7894 case V_OMIT:
7895 // Omit is not a value unless a member of a sequence or set
7896 return from_sequence;
7897 case V_NOTUSED:
7898 return false;
7899 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7900 case V_BOOL: /**< boolean */
7901 case V_NAMEDINT: /**< integer / named number */
7902 case V_NAMEDBITS: /**< named bits (identifiers) */
7903 case V_INT: /**< integer */
7904 case V_REAL: /**< real/float */
7905 case V_ENUM: /**< enumerated */
7906 case V_BSTR: /**< bitstring */
7907 case V_HSTR: /**< hexstring */
7908 case V_OSTR: /**< octetstring */
7909 case V_CSTR: /**< charstring */
7910 case V_USTR: /**< universal charstring */
7911 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
7912 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
7913 case V_OID: /**< object identifier */
7914 case V_ROID: /**< relative object identifier */
7915 case V_VERDICT: /**< all verdicts */
7916 return true; // values of built-in types return true
7917
7918 // Code below was adapted from is_unfoldable(), false returned early.
7919 case V_CHOICE:
7920 return u.choice.alt_value->evaluate_isvalue(false);
7921
7922 case V_SEQOF:
7923 case V_SETOF:
7924 case V_ARRAY:
7925 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
7926 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
7927 return false;
7928 }
7929 }
7930 return true;
7931
7932 case V_SEQ:
7933 case V_SET:
7934 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
7935 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
7936 ->evaluate_isvalue(true)) return false;
7937 }
7938 return true;
7939
7940 case V_REFD:
7941 // alas, get_value_refd_last prevents this function from const
7942 return get_value_refd_last()->evaluate_isvalue(false);
7943
7944 case V_EXPR:
7945 switch (u.expr.v_optype) {
7946 // A constant null component reference is a corner case: it is foldable
7947 // but escapes unmodified from evaluate_value.
7948 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7949 // or is transformed into some other valuetype in evaluate_value.
7950 case OPTYPE_COMP_NULL:
7951 return false;
7952 default:
7953 break; // and fall through to the FATAL_ERROR
7954 }
7955 // no break
7956 default:
7957 FATAL_ERROR("Value::evaluate_isvalue()");
7958 break;
7959 }
7960 return true;
7961 }
7962
7963 void Value::evaluate_macro(Type::expected_value_t exp_val)
7964 {
7965 switch (u.macro) {
7966 case MACRO_MODULEID:
7967 if (!my_scope)
7968 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7969 set_val_str(new string(my_scope->get_scope_mod()
7970 ->get_modid().get_dispname()));
7971 valuetype = V_CSTR;
7972 break;
7973 case MACRO_FILENAME:
7974 case MACRO_BFILENAME: {
7975 const char *t_filename = get_filename();
7976 if (!t_filename)
7977 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7978 set_val_str(new string(t_filename));
7979 valuetype = V_CSTR;
7980 break; }
7981 case MACRO_FILEPATH: {
7982 const char *t_filename = get_filename();
7983 if (!t_filename)
7984 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7985 char *t_filepath = canonize_input_file(t_filename);
7986 if (!t_filepath)
7987 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7988 set_val_str(new string(t_filepath));
7989 valuetype = V_CSTR;
7990 Free(t_filepath);
7991 break; }
7992 case MACRO_LINENUMBER: {
7993 int t_lineno = get_first_line();
7994 if (t_lineno <= 0)
7995 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7996 set_val_str(new string(Int2string(t_lineno)));
7997 valuetype = V_CSTR;
7998 break; }
7999 case MACRO_LINENUMBER_C: {
8000 int t_lineno = get_first_line();
8001 if (t_lineno <= 0)
8002 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8003 u.val_Int = new int_val_t(t_lineno);
8004 valuetype = V_INT;
8005 break; }
8006 case MACRO_DEFINITIONID: {
8007 // cut the second part from the fullname separated by dots
8008 const string& t_fullname = get_fullname();
8009 size_t first_char = t_fullname.find('.') + 1;
8010 if (first_char >= t_fullname.size())
8011 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8012 t_fullname.c_str());
8013 set_val_str(new string(t_fullname.substr(first_char,
8014 t_fullname.find('.', first_char) - first_char)));
8015 valuetype = V_CSTR;
8016 break; }
8017 case MACRO_SCOPE: {
8018 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8019 set_val_str(new string(my_scope->get_scopeMacro_name()));
8020 valuetype = V_CSTR;
8021 break;
8022 }
8023 case MACRO_TESTCASEID: {
8024 if (exp_val == Type::EXPECTED_CONSTANT ||
8025 exp_val == Type::EXPECTED_STATIC_VALUE) {
8026 error("A %s value was expected instead of macro `%%testcaseId', "
8027 "which is evaluated at runtime",
8028 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8029 goto error;
8030 }
8031 if (!my_scope)
8032 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8033 Ttcn::StatementBlock *my_sb =
8034 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8035 if (!my_sb) {
8036 error("Usage of macro %%testcaseId is allowed only within the "
8037 "statement blocks of functions, altsteps and testcases");
8038 goto error;
8039 }
8040 Ttcn::Definition *my_def = my_sb->get_my_def();
8041 if (!my_def) {
8042 error("Macro %%testcaseId cannot be used in the control part. "
8043 "It is allowed only within the statement blocks of functions, "
8044 "altsteps and testcases");
8045 goto error;
8046 }
8047 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8048 // folding is possible only within testcases
8049 set_val_str(new string(my_def->get_id().get_dispname()));
8050 valuetype = V_CSTR;
8051 }
8052 break; }
8053 default:
8054 FATAL_ERROR("Value::evaluate_macro()");
8055 }
8056 return;
8057 error:
8058 set_valuetype(V_ERROR);
8059 }
8060
8061 void Value::add_id(Identifier *p_id)
8062 {
8063 switch(valuetype) {
8064 case V_NAMEDBITS:
8065 if(u.ids->has_key(p_id->get_name())) {
8066 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8067 // The Value does not take ownership for the identifier,
8068 // so it must be deleted (add_is acts as a sink).
8069 delete p_id;
8070 }
8071 else u.ids->add(p_id->get_name(), p_id);
8072 break;
8073 default:
8074 FATAL_ERROR("Value::add_id()");
8075 } // switch
8076 }
8077
8078 Value* Value::get_value_refd_last(ReferenceChain *refch,
8079 Type::expected_value_t exp_val)
8080 {
8081 set_lowerid_to_ref();
8082 switch (valuetype) {
8083 case V_INVOKE:
8084 // there might be a better place for this
8085 chk_invoke(exp_val);
8086 return this;
8087 case V_REFD:
8088 // use the cache if available
8089 if (u.ref.refd_last) return u.ref.refd_last;
8090 else {
8091 Assignment *ass = u.ref.ref->get_refd_assignment();
8092 if (!ass) {
8093 // the referred definition is not found
8094 set_valuetype(V_ERROR);
8095 } else {
8096 switch (ass->get_asstype()) {
8097 case Assignment::A_OBJECT:
8098 case Assignment::A_OS: {
8099 // the referred definition is an ASN.1 object or object set
8100 Setting *setting = u.ref.ref->get_refd_setting();
8101 if (!setting || setting->get_st() == S_ERROR) {
8102 // remain silent, the error has been already reported
8103 set_valuetype(V_ERROR);
8104 break;
8105 } else if (setting->get_st() != S_V) {
8106 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8107 " refer to a value", u.ref.ref->get_dispname().c_str());
8108 set_valuetype(V_ERROR);
8109 break;
8110 }
8111 bool destroy_refch;
8112 if (refch) {
8113 refch->mark_state();
8114 destroy_refch = false;
8115 } else {
8116 refch = new ReferenceChain(this,
8117 "While searching referenced value");
8118 destroy_refch = true;
8119 }
8120 if (refch->add(get_fullname())) {
8121 Value *v_refd = dynamic_cast<Value*>(setting);
8122 Value *v_last = v_refd->get_value_refd_last(refch);
8123 // in case of circular recursion the valuetype is already set
8124 // to V_ERROR, so don't set the cache
8125 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8126 } else {
8127 // a circular recursion was detected
8128 set_valuetype(V_ERROR);
8129 }
8130 if (destroy_refch) delete refch;
8131 else refch->prev_state();
8132 break; }
8133 case Assignment::A_CONST: {
8134 // the referred definition is a constant
8135 bool destroy_refch;
8136 if (refch) {
8137 refch->mark_state();
8138 destroy_refch = false;
8139 } else {
8140 refch = new ReferenceChain(this,
8141 "While searching referenced value");
8142 destroy_refch = true;
8143 }
8144 if (refch->add(get_fullname())) {
8145 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8146 Value *v_refd = ass->get_Value()
8147 ->get_refd_sub_value(subrefs, 0,
8148 u.ref.ref->getUsedInIsbound(), refch);
8149 if (v_refd) {
8150 Value *v_last = v_refd->get_value_refd_last(refch);
8151 // in case of circular recursion the valuetype is already set
8152 // to V_ERROR, so don't set the cache
8153 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8154 } else if (subrefs && subrefs->has_unfoldable_index()) {
8155 u.ref.refd_last = this;
8156 } else if (u.ref.ref->getUsedInIsbound()) {
8157 u.ref.refd_last = this;
8158 } else {
8159 // the sub-reference points to a non-existent field
8160 set_valuetype(V_ERROR);
8161 }
8162 } else {
8163 // a circular recursion was detected
8164 set_valuetype(V_ERROR);
8165 }
8166 if (destroy_refch) delete refch;
8167 else refch->prev_state();
8168 break; }
8169 case Assignment::A_EXT_CONST:
8170 case Assignment::A_MODULEPAR:
8171 case Assignment::A_VAR:
8172 case Assignment::A_FUNCTION_RVAL:
8173 case Assignment::A_EXT_FUNCTION_RVAL:
8174 case Assignment::A_PAR_VAL_IN:
8175 case Assignment::A_PAR_VAL_OUT:
8176 case Assignment::A_PAR_VAL_INOUT:
8177 // the referred definition is not a constant
8178 u.ref.refd_last = this;
8179 break;
8180 case Assignment::A_FUNCTION:
8181 case Assignment::A_EXT_FUNCTION:
8182 u.ref.ref->error("Reference to a value was expected instead of a "
8183 "call of %s, which does not have return type",
8184 ass->get_description().c_str());
8185 set_valuetype(V_ERROR);
8186 break;
8187 case Assignment::A_FUNCTION_RTEMP:
8188 case Assignment::A_EXT_FUNCTION_RTEMP:
8189 u.ref.ref->error("Reference to a value was expected instead of a "
8190 "call of %s, which returns a template",
8191 ass->get_description().c_str());
8192 set_valuetype(V_ERROR);
8193 break;
8194 default:
8195 u.ref.ref->error("Reference to a value was expected instead of %s",
8196 ass->get_description().c_str());
8197 set_valuetype(V_ERROR);
8198 } // switch asstype
8199 }
8200 if (valuetype == V_REFD) return u.ref.refd_last;
8201 else return this;
8202 }
8203 case V_EXPR: {
8204 // try to evaluate the expression
8205 bool destroy_refch;
8206 if(refch) {
8207 refch->mark_state();
8208 destroy_refch=false;
8209 }
8210 else {
8211 refch=new ReferenceChain(this, "While evaluating expression");
8212 destroy_refch=true;
8213 }
8214 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8215 else set_valuetype(V_ERROR);
8216 if(destroy_refch) delete refch;
8217 else refch->prev_state();
8218 return this; }
8219 case V_MACRO:
8220 evaluate_macro(exp_val);
8221 // no break
8222 default:
8223 // return this for all other value types
8224 return this;
8225 } // switch
8226 }
8227
8228 map<Value*, void> Value::UnfoldabilityCheck::running;
8229
8230 /* Note that the logic here needs to be in sync with evaluate_value,
8231 * and possibly others, i.e. if evaluate_value is called for a Value
8232 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8233 bool Value::is_unfoldable(ReferenceChain *refch,
8234 Type::expected_value_t exp_val)
8235 {
8236 if (UnfoldabilityCheck::is_running(this)) {
8237 // This function is already running on this value => infinite recursion
8238 return true;
8239 }
8240
8241 UnfoldabilityCheck checker(this);
8242
8243 if (get_needs_conversion()) return true;
8244 switch (valuetype) {
8245 case V_NAMEDINT:
8246 case V_NAMEDBITS:
8247 case V_OPENTYPE:
8248 case V_UNDEF_LOWERID:
8249 case V_UNDEF_BLOCK:
8250 case V_TTCN3_NULL:
8251 case V_REFER:
8252 // these value types are eliminated during semantic analysis
8253 FATAL_ERROR("Value::is_unfoldable()");
8254 case V_ERROR:
8255 case V_INVOKE:
8256 return true;
8257 case V_CHOICE:
8258 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8259 case V_SEQOF:
8260 case V_SETOF:
8261 case V_ARRAY:
8262 if (!is_indexed()) {
8263 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8264 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8265 return true;
8266 }
8267 } else {
8268 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8269 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8270 return true;
8271 }
8272 }
8273 return false;
8274 case V_SEQ:
8275 case V_SET:
8276 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8277 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8278 ->is_unfoldable(refch, exp_val)) return true;
8279 }
8280 return false;
8281 case V_OID:
8282 case V_ROID:
8283 chk();
8284 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8285 if ((*u.oid_comps)[i]->is_variable()) return true;
8286 }
8287 return false;
8288 case V_REFD: {
8289 Value *v_last=get_value_refd_last(refch, exp_val);
8290 if(v_last==this) return true; // there weren't any references to chase
8291 else return v_last->is_unfoldable(refch, exp_val);
8292 }
8293 case V_EXPR:
8294 // classify the unchecked ischosen() operation, if it was not done so far
8295 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8296 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8297 switch (u.expr.v_optype) {
8298 case OPTYPE_RND: // -
8299 case OPTYPE_COMP_MTC:
8300 case OPTYPE_COMP_SYSTEM:
8301 case OPTYPE_COMP_SELF:
8302 case OPTYPE_COMP_RUNNING_ANY:
8303 case OPTYPE_COMP_RUNNING_ALL:
8304 case OPTYPE_COMP_ALIVE_ANY:
8305 case OPTYPE_COMP_ALIVE_ALL:
8306 case OPTYPE_TMR_RUNNING_ANY:
8307 case OPTYPE_GETVERDICT:
8308 case OPTYPE_TESTCASENAME:
8309 case OPTYPE_PROF_RUNNING:
8310 case OPTYPE_RNDWITHVAL: // v1
8311 case OPTYPE_MATCH: // v1 t2
8312 case OPTYPE_UNDEF_RUNNING: // v1
8313 case OPTYPE_COMP_RUNNING:
8314 case OPTYPE_COMP_ALIVE:
8315 case OPTYPE_TMR_READ:
8316 case OPTYPE_TMR_RUNNING:
8317 case OPTYPE_ACTIVATE:
8318 case OPTYPE_ACTIVATE_REFD:
8319 case OPTYPE_EXECUTE: // r1 [v2]
8320 case OPTYPE_EXECUTE_REFD:
8321 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8322 case OPTYPE_ISCHOSEN:
8323 case OPTYPE_ISCHOSEN_T:
8324 case OPTYPE_SIZEOF: // ti1
8325 case OPTYPE_DECODE:
8326 case OPTYPE_ENCODE:
8327 case OPTYPE_OCT2UNICHAR:
8328 case OPTYPE_UNICHAR2OCT:
8329 case OPTYPE_ENCODE_BASE64:
8330 case OPTYPE_DECODE_BASE64:
8331 return true;
8332 case OPTYPE_COMP_NULL: // -
8333 return false;
8334 case OPTYPE_UNARYPLUS: // v1
8335 case OPTYPE_UNARYMINUS:
8336 case OPTYPE_NOT:
8337 case OPTYPE_NOT4B:
8338 case OPTYPE_BIT2HEX:
8339 case OPTYPE_BIT2INT:
8340 case OPTYPE_BIT2OCT:
8341 case OPTYPE_BIT2STR:
8342 case OPTYPE_CHAR2INT:
8343 case OPTYPE_CHAR2OCT:
8344 case OPTYPE_FLOAT2INT:
8345 case OPTYPE_FLOAT2STR:
8346 case OPTYPE_HEX2BIT:
8347 case OPTYPE_HEX2INT:
8348 case OPTYPE_HEX2OCT:
8349 case OPTYPE_HEX2STR:
8350 case OPTYPE_INT2CHAR:
8351 case OPTYPE_INT2FLOAT:
8352 case OPTYPE_INT2STR:
8353 case OPTYPE_INT2UNICHAR:
8354 case OPTYPE_OCT2BIT:
8355 case OPTYPE_OCT2CHAR:
8356 case OPTYPE_OCT2HEX:
8357 case OPTYPE_OCT2INT:
8358 case OPTYPE_OCT2STR:
8359 case OPTYPE_STR2BIT:
8360 case OPTYPE_STR2FLOAT:
8361 case OPTYPE_STR2HEX:
8362 case OPTYPE_STR2INT:
8363 case OPTYPE_STR2OCT:
8364 case OPTYPE_UNICHAR2INT:
8365 case OPTYPE_UNICHAR2CHAR:
8366 case OPTYPE_ENUM2INT:
8367 case OPTYPE_GET_STRINGENCODING:
8368 case OPTYPE_REMOVE_BOM:
8369 return u.expr.v1->is_unfoldable(refch, exp_val);
8370 case OPTYPE_ISBOUND: /*{
8371 //TODO once we have the time for it make isbound foldable.
8372 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8373 Template* temp = u.expr.ti1->get_Template();
8374 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8375 Value* specificValue = temp->get_specific_value();
8376 if (specificValue->get_valuetype() == Value::V_REFD) {
8377 //FIXME implement
8378 }
8379
8380 return specificValue->is_unfoldable(refch, exp_val);
8381 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8382 //FIXME implement
8383 }
8384 }*/
8385 return true;
8386 case OPTYPE_ISPRESENT:
8387 // TODO: "if you have motivation"
8388 return true;
8389 case OPTYPE_ISVALUE: // ti1
8390 // fallthrough
8391 case OPTYPE_LENGTHOF: // ti1
8392 return u.expr.ti1->get_DerivedRef() != 0
8393 || u.expr.ti1->get_Template()->get_templatetype()
8394 != Template::SPECIFIC_VALUE
8395 || u.expr.ti1->get_Template()->get_specific_value()
8396 ->is_unfoldable(refch, exp_val);
8397 case OPTYPE_ROTL:
8398 case OPTYPE_ROTR:
8399 case OPTYPE_CONCAT:
8400 if (!u.expr.v1->is_string_type(exp_val)) return true;
8401 // no break
8402 case OPTYPE_ADD: // v1 v2
8403 case OPTYPE_SUBTRACT:
8404 case OPTYPE_MULTIPLY:
8405 case OPTYPE_DIVIDE:
8406 case OPTYPE_MOD:
8407 case OPTYPE_REM:
8408 case OPTYPE_EQ:
8409 case OPTYPE_LT:
8410 case OPTYPE_GT:
8411 case OPTYPE_NE:
8412 case OPTYPE_GE:
8413 case OPTYPE_LE:
8414 case OPTYPE_XOR:
8415 case OPTYPE_AND4B:
8416 case OPTYPE_OR4B:
8417 case OPTYPE_XOR4B:
8418 case OPTYPE_SHL:
8419 case OPTYPE_SHR:
8420 case OPTYPE_INT2BIT:
8421 case OPTYPE_INT2HEX:
8422 case OPTYPE_INT2OCT:
8423 return u.expr.v1->is_unfoldable(refch, exp_val)
8424 || u.expr.v2->is_unfoldable(refch, exp_val);
8425 case OPTYPE_AND: // short-circuit evaluation
8426 return u.expr.v1->is_unfoldable(refch, exp_val)
8427 || (u.expr.v1->get_val_bool() &&
8428 u.expr.v2->is_unfoldable(refch, exp_val));
8429 case OPTYPE_OR: // short-circuit evaluation
8430 return u.expr.v1->is_unfoldable(refch, exp_val)
8431 || (!u.expr.v1->get_val_bool() &&
8432 u.expr.v2->is_unfoldable(refch, exp_val));
8433 case OPTYPE_SUBSTR:
8434 if (!u.expr.ti1->get_specific_value()) return true;
8435 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8436 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8437 || u.expr.v2->is_unfoldable(refch, exp_val)
8438 || u.expr.v3->is_unfoldable(refch, exp_val);
8439 case OPTYPE_REGEXP:
8440 if (!u.expr.ti1->get_specific_value() ||
8441 !u.expr.t2->get_specific_value()) return true;
8442 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8443 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8444 || u.expr.v3->is_unfoldable(refch, exp_val);
8445 case OPTYPE_DECOMP:
8446 return u.expr.v1->is_unfoldable(refch, exp_val)
8447 || u.expr.v2->is_unfoldable(refch, exp_val)
8448 || u.expr.v3->is_unfoldable(refch, exp_val);
8449 case OPTYPE_REPLACE: {
8450 if (!u.expr.ti1->get_specific_value() ||
8451 !u.expr.ti4->get_specific_value()) return true;
8452 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8453 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8454 || u.expr.v2->is_unfoldable(refch, exp_val)
8455 || u.expr.v3->is_unfoldable(refch, exp_val)
8456 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8457 }
8458 case OPTYPE_VALUEOF: // ti1
8459 /* \todo if you have motivation to implement the eval function
8460 for valueof()... */
8461 return true;
8462 case OPTYPE_ISCHOSEN_V:
8463 return u.expr.v1->is_unfoldable(refch, exp_val);
8464 case OPTYPE_LOG2STR:
8465 case OPTYPE_TTCN2STRING:
8466 return true;
8467 default:
8468 FATAL_ERROR("Value::is_unfoldable()");
8469 } // switch
8470 break; // should never get here
8471 case V_MACRO:
8472 switch (u.macro) {
8473 case MACRO_TESTCASEID:
8474 // this is known only at runtime
8475 return true;
8476 default:
8477 return false;
8478 }
8479 default:
8480 // all literal values are foldable
8481 return false;
8482 }
8483 }
8484
8485 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8486 size_t start_i, bool usedInIsbound,
8487 ReferenceChain *refch)
8488 {
8489 if (!subrefs) return this;
8490 Value *v = this;
8491 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8492 if (!v) break;
8493 v = v->get_value_refd_last(refch);
8494 switch(v->valuetype) {
8495 case V_ERROR:
8496 return v;
8497 case V_REFD:
8498 // unfoldable stuff
8499 return this;
8500 default:
8501 break;
8502 } // switch
8503 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8504 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8505 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8506 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8507 }
8508 return v;
8509 }
8510
8511 Value *Value::get_refd_field_value(const Identifier& field_id,
8512 bool usedInIsbound, const Location& loc)
8513 {
8514 if (valuetype == V_OMIT) {
8515 loc.error("Reference to field `%s' of omit value `%s'",
8516 field_id.get_dispname().c_str(), get_fullname().c_str());
8517 return 0;
8518 }
8519 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8520 Type *t = my_governor->get_type_refd_last();
8521 switch (t->get_typetype()) {
8522 case Type::T_ERROR:
8523 // remain silent
8524 return 0;
8525 case Type::T_CHOICE_A:
8526 case Type::T_CHOICE_T:
8527 case Type::T_OPENTYPE:
8528 case Type::T_ANYTYPE:
8529 if (!t->has_comp_withName(field_id)) {
8530 loc.error("Reference to non-existent union field `%s' in type `%s'",
8531 field_id.get_dispname().c_str(), t->get_typename().c_str());
8532 return 0;
8533 } else if (valuetype != V_CHOICE) {
8534 // remain silent, the error is already reported
8535 return 0;
8536 } else if (*u.choice.alt_name == field_id) {
8537 // everything is OK
8538 return u.choice.alt_value;
8539 }else {
8540 if (!usedInIsbound) {
8541 loc.error("Reference to inactive field `%s' in a value of union type "
8542 "`%s'. The active field is `%s'",
8543 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8544 u.choice.alt_name->get_dispname().c_str());
8545 }
8546 return 0;
8547 }
8548 case Type::T_SEQ_A:
8549 case Type::T_SEQ_T:
8550 if (!t->has_comp_withName(field_id)) {
8551 loc.error("Reference to non-existent record field `%s' in type `%s'",
8552 field_id.get_dispname().c_str(), t->get_typename().c_str());
8553 return 0;
8554 } else if (valuetype != V_SEQ) {
8555 // remain silent, the error has been already reported
8556 return 0;
8557 } else break;
8558 case Type::T_SET_A:
8559 case Type::T_SET_T:
8560 if (!t->has_comp_withName(field_id)) {
8561 loc.error("Reference to non-existent set field `%s' in type `%s'",
8562 field_id.get_dispname().c_str(), t->get_typename().c_str());
8563 return 0;
8564 } else if (valuetype != V_SET) {
8565 // remain silent, the error has been already reported
8566 return 0;
8567 } else break;
8568 default:
8569 loc.error("Invalid field reference `%s': type `%s' "
8570 "does not have fields", field_id.get_dispname().c_str(),
8571 t->get_typename().c_str());
8572 return 0;
8573 }
8574 // the common end for record & set types
8575 if (u.val_nvs->has_nv_withName(field_id)) {
8576 // everything is OK
8577 return u.val_nvs->get_nv_byName(field_id)->get_value();
8578 } else if (!is_asn1()) {
8579 if (!usedInIsbound) {
8580 loc.error("Reference to unbound field `%s'",
8581 field_id.get_dispname().c_str());
8582 // this is an error in TTCN-3, which has been already reported
8583 }
8584 return 0;
8585 } else {
8586 CompField *cf = t->get_comp_byName(field_id);
8587 if (cf->get_is_optional()) {
8588 // creating an explicit omit value
8589 Value *v = new Value(V_OMIT);
8590 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8591 v->set_my_scope(get_my_scope());
8592 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8593 return v;
8594 } else if (cf->has_default()) {
8595 // returning the component's default value
8596 return cf->get_defval();
8597 } else {
8598 // this is an error in ASN.1, which has been already reported
8599 return 0;
8600 }
8601 }
8602 }
8603
8604 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8605 ReferenceChain *refch)
8606 {
8607 Value *v_index = array_index->get_value_refd_last(refch);
8608 Int index = 0;
8609 bool index_available = false;
8610 if (!v_index->is_unfoldable()) {
8611 if (v_index->valuetype == V_INT) {
8612 index = v_index->get_val_Int()->get_val();
8613 index_available = true;
8614 } else {
8615 array_index->error("An integer value was expected as index");
8616 }
8617 }
8618 if (valuetype == V_OMIT) {
8619 array_index->error("Accessing an element with index of omit value `%s'",
8620 get_fullname().c_str());
8621 return 0;
8622 }
8623 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8624 Type *t = my_governor->get_type_refd_last();
8625 switch (t->get_typetype()) {
8626 case Type::T_ERROR:
8627 // remain silent
8628 return 0;
8629 case Type::T_SEQOF:
8630 if (index_available) {
8631 if (index < 0) {
8632 array_index->error("A non-negative integer value was expected "
8633 "instead of %s for indexing a value of `record "
8634 "of' type `%s'", Int2string(index).c_str(),
8635 t->get_typename().c_str());
8636 return 0;
8637 }
8638 switch (valuetype) {
8639 case V_SEQOF:
8640 if (!is_indexed()) {
8641 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8642 if (!usedInIsbound) {
8643 array_index->error("Index overflow in a value of `record of' "
8644 "type `%s': the index is %s, but the value "
8645 "has only %lu elements",
8646 t->get_typename().c_str(),
8647 Int2string(index).c_str(),
8648 (unsigned long)u.val_vs->get_nof_vs());
8649 }
8650 return 0;
8651 } else {
8652 Value* temp = u.val_vs->get_v_byIndex(index);
8653 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8654 temp->error("Not used symbol is not allowed in this context");
8655 return u.val_vs->get_v_byIndex(index);
8656 }
8657 } else {
8658 // Search the appropriate constant index.
8659 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8660 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8661 ->get_value_refd_last();
8662 if (iv_index->get_valuetype() != V_INT) continue;
8663 if (iv_index->get_val_Int()->get_val() == index)
8664 return u.val_vs->get_iv_byIndex(i)->get_value();
8665 }
8666 return 0;
8667 }
8668 break;
8669 default:
8670 // remain silent, the error has been already reported
8671 return 0;
8672 }
8673 } else {
8674 // the error has been reported above
8675 return 0;
8676 }
8677 case Type::T_SETOF:
8678 if (index_available) {
8679 if (index < 0) {
8680 array_index->error("A non-negative integer value was expected "
8681 "instead of %s for indexing a value of `set of' type `%s'",
8682 Int2string(index).c_str(), t->get_typename().c_str());
8683 return 0;
8684 }
8685 switch (valuetype) {
8686 case V_SETOF:
8687 if (!is_indexed()) {
8688 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8689 if (!usedInIsbound) {
8690 array_index->error("Index overflow in a value of `set of' type "
8691 "`%s': the index is %s, but the value has "
8692 "only %lu elements",
8693 t->get_typename().c_str(),
8694 Int2string(index).c_str(),
8695 (unsigned long)u.val_vs->get_nof_vs());
8696 }
8697 return 0;
8698 } else {
8699 Value* temp = u.val_vs->get_v_byIndex(index);
8700 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8701 temp->error("Not used symbol is not allowed in this context");
8702 return temp;
8703 }
8704 } else {
8705 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8706 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8707 ->get_value_refd_last();
8708 if (iv_index->get_valuetype() != V_INT) continue;
8709 if (iv_index->get_val_Int()->get_val() == index)
8710 return u.val_vs->get_iv_byIndex(i)->get_value();
8711 }
8712 return 0;
8713 }
8714 break;
8715 default:
8716 // remain silent, the error has been already reported
8717 return 0;
8718 }
8719 } else {
8720 // the error has been reported above
8721 return 0;
8722 }
8723 case Type::T_ARRAY:
8724 if (index_available) {
8725 Ttcn::ArrayDimension *dim = t->get_dimension();
8726 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8727 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8728 // perform the index transformation
8729 index -= dim->get_offset();
8730 if (!is_indexed()) {
8731 // check for index underflow/overflow or too few elements in the
8732 // value
8733 if (index < 0 ||
8734 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8735 return 0;
8736 else return u.val_vs->get_v_byIndex(index);
8737 } else {
8738 if (index < 0) return 0;
8739 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8740 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8741 ->get_value_refd_last();
8742 if (iv_index->get_valuetype() != V_INT) continue;
8743 if (iv_index->get_val_Int()->get_val() == index)
8744 return u.val_vs->get_iv_byIndex(index)->get_value();
8745 }
8746 return 0;
8747 }
8748 } else {
8749 // remain silent, the error has been already reported
8750 return 0;
8751 }
8752 } else {
8753 // the error has been reported above
8754 return 0;
8755 }
8756 case Type::T_BSTR:
8757 case Type::T_BSTR_A:
8758 case Type::T_HSTR:
8759 case Type::T_OSTR:
8760 case Type::T_CSTR:
8761 case Type::T_USTR:
8762 case Type::T_UTF8STRING:
8763 case Type::T_NUMERICSTRING:
8764 case Type::T_PRINTABLESTRING:
8765 case Type::T_TELETEXSTRING:
8766 case Type::T_VIDEOTEXSTRING:
8767 case Type::T_IA5STRING:
8768 case Type::T_GRAPHICSTRING:
8769 case Type::T_VISIBLESTRING:
8770 case Type::T_GENERALSTRING:
8771 case Type::T_UNIVERSALSTRING:
8772 case Type::T_BMPSTRING:
8773 case Type::T_UTCTIME:
8774 case Type::T_GENERALIZEDTIME:
8775 case Type::T_OBJECTDESCRIPTOR:
8776 if (index_available) return get_string_element(index, *array_index);
8777 else return 0;
8778 default:
8779 array_index->error("Invalid array element reference: type `%s' cannot "
8780 "be indexed", t->get_typename().c_str());
8781 return 0;
8782 }
8783 }
8784
8785 Value *Value::get_string_element(const Int& index, const Location& loc)
8786 {
8787 if (index < 0) {
8788 loc.error("A non-negative integer value was expected instead of %s "
8789 "for indexing a string element", Int2string(index).c_str());
8790 return 0;
8791 }
8792 size_t string_length;
8793 switch (valuetype) {
8794 case V_BSTR:
8795 case V_HSTR:
8796 case V_CSTR:
8797 case V_ISO2022STR:
8798 string_length = u.str.val_str->size();
8799 break;
8800 case V_OSTR:
8801 string_length = u.str.val_str->size() / 2;
8802 break;
8803 case V_USTR:
8804 string_length = u.ustr.val_ustr->size();
8805 break;
8806 default:
8807 // remain silent, the error has been already reported
8808 return 0;
8809 }
8810 if (index >= static_cast<Int>(string_length)) {
8811 loc.error("Index overflow when accessing a string element: "
8812 "the index is %s, but the string has only %lu elements",
8813 Int2string(index).c_str(), (unsigned long) string_length);
8814 return 0;
8815 }
8816 switch (valuetype) {
8817 case V_BSTR:
8818 case V_HSTR:
8819 case V_CSTR:
8820 case V_ISO2022STR:
8821 if (u.str.str_elements && u.str.str_elements->has_key(index))
8822 return (*u.str.str_elements)[index];
8823 else {
8824 Value *t_val = new Value(valuetype,
8825 new string(u.str.val_str->substr(index, 1)));
8826 add_string_element(index, t_val, u.str.str_elements);
8827 return t_val;
8828 }
8829 case V_OSTR:
8830 if (u.str.str_elements && u.str.str_elements->has_key(index))
8831 return (*u.str.str_elements)[index];
8832 else {
8833 Value *t_val = new Value(V_OSTR,
8834 new string(u.str.val_str->substr(2 * index, 2)));
8835 add_string_element(index, t_val, u.str.str_elements);
8836 return t_val;
8837 }
8838 case V_USTR:
8839 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
8840 return (*u.ustr.ustr_elements)[index];
8841 else {
8842 Value *t_val = new Value(V_USTR,
8843 new ustring(u.ustr.val_ustr->substr(index, 1)));
8844 add_string_element(index, t_val, u.ustr.ustr_elements);
8845 return t_val;
8846 }
8847 default:
8848 FATAL_ERROR("Value::get_string_element()");
8849 return 0;
8850 }
8851 }
8852
8853 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
8854 Type::expected_value_t exp_val)
8855 {
8856 set_lowerid_to_ref();
8857 Type::typetype_t r_tt = get_expr_returntype(exp_val);
8858 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
8859 if (error_flag)
8860 error("A value or expression of type %s was expected", type_name);
8861 if (valuetype == V_REFD) {
8862 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
8863 t_chk->chk_this_refd_value(this, 0, exp_val);
8864 }
8865 get_value_refd_last(0, exp_val);
8866 if (error_flag) set_valuetype(V_ERROR);
8867 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
8868 }
8869
8870 int Value::is_parsed_infinity()
8871 {
8872 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
8873 return 1;
8874 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
8875 (u.expr.v1->get_valuetype()==V_REAL) &&
8876 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
8877 return -1;
8878 return 0;
8879 }
8880
8881 bool Value::get_val_bool()
8882 {
8883 Value *v;
8884 if (valuetype == V_REFD) v = get_value_refd_last();
8885 else v = this;
8886 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
8887 return v->u.val_bool;
8888 }
8889
8890 int_val_t* Value::get_val_Int()
8891 {
8892 Value *v;
8893 if (valuetype == V_REFD) v = get_value_refd_last();
8894 else v = this;
8895 switch (v->valuetype) {
8896 case V_INT:
8897 break;
8898 case V_UNDEF_LOWERID:
8899 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8900 "`%s'", (*u.val_id).get_dispname().c_str());
8901 default:
8902 FATAL_ERROR("Value::get_val_Int()");
8903 } // switch
8904 return v->u.val_Int;
8905 }
8906
8907 const Identifier* Value::get_val_id()
8908 {
8909 switch(valuetype) {
8910 case V_NAMEDINT:
8911 case V_ENUM:
8912 case V_UNDEF_LOWERID:
8913 return u.val_id;
8914 default:
8915 FATAL_ERROR("Value::get_val_id()");
8916 return 0;
8917 } // switch
8918 }
8919
8920 const ttcn3float& Value::get_val_Real()
8921 {
8922 Value *v;
8923 if (valuetype == V_REFD) v = get_value_refd_last();
8924 else v = this;
8925 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
8926 return v->u.val_Real;
8927 }
8928
8929 string Value::get_val_str()
8930 {
8931 Value *v = get_value_refd_last();
8932 switch (v->valuetype) {
8933 case V_BSTR:
8934 case V_HSTR:
8935 case V_OSTR:
8936 case V_CSTR:
8937 return *v->u.str.val_str;
8938 case V_CHARSYMS:
8939 return v->u.char_syms->get_string();
8940 case V_USTR:
8941 error("Cannot use ISO-10646 string value in string context");
8942 return string();
8943 case V_ISO2022STR:
8944 error("Cannot use ISO-2022 string value in string context");
8945 // no break
8946 case V_ERROR:
8947 return string();
8948 default:
8949 error("Cannot use this value in charstring value context");
8950 return string();
8951 } // switch
8952 }
8953
8954 ustring Value::get_val_ustr()
8955 {
8956 Value *v = get_value_refd_last();
8957 switch (v->valuetype) {
8958 case V_CSTR:
8959 return ustring(*v->u.str.val_str);
8960 case V_USTR:
8961 return *v->u.ustr.val_ustr;
8962 case V_CHARSYMS:
8963 return v->u.char_syms->get_ustring();
8964 case V_ISO2022STR:
8965 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8966 // no break
8967 case V_ERROR:
8968 return ustring();
8969 default:
8970 error("Cannot use this value in ISO-10646 string context");
8971 return ustring();
8972 } // switch
8973 }
8974
8975 string Value::get_val_iso2022str()
8976 {
8977 Value *v = get_value_refd_last();
8978 switch (v->valuetype) {
8979 case V_CSTR:
8980 case V_ISO2022STR:
8981 return *v->u.str.val_str;
8982 case V_CHARSYMS:
8983 return v->u.char_syms->get_iso2022string();
8984 case V_USTR:
8985 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8986 // no break
8987 case V_ERROR:
8988 return string();
8989 default:
8990 error("Cannot use this value in ISO-2022 string context");
8991 return string();
8992 } // switch
8993 }
8994
8995 size_t Value::get_val_strlen()
8996 {
8997 Value *v = get_value_refd_last();
8998 switch (v->valuetype) {
8999 case V_BSTR:
9000 case V_HSTR:
9001 case V_CSTR:
9002 case V_ISO2022STR:
9003 return v->u.str.val_str->size();
9004 case V_OSTR:
9005 return v->u.str.val_str->size()/2;
9006 case V_CHARSYMS:
9007 return v->u.char_syms->get_len();
9008 case V_USTR:
9009 return v->u.ustr.val_ustr->size();
9010 case V_ERROR:
9011 return 0;
9012 default:
9013 error("Cannot use this value in string value context");
9014 return 0;
9015 } // switch
9016 }
9017
9018 Value::verdict_t Value::get_val_verdict()
9019 {
9020 switch(valuetype) {
9021 case V_VERDICT:
9022 return u.verdict;
9023 default:
9024 FATAL_ERROR("Value::get_val_verdict()");
9025 return u.verdict;
9026 } // switch
9027 }
9028
9029 size_t Value::get_nof_comps()
9030 {
9031 switch (valuetype) {
9032 case V_OID:
9033 case V_ROID:
9034 chk();
9035 return u.oid_comps->size();
9036 case V_SEQOF:
9037 case V_SETOF:
9038 case V_ARRAY:
9039 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9040 else return u.val_vs->get_nof_vs();
9041 case V_SEQ:
9042 case V_SET:
9043 return u.val_nvs->get_nof_nvs();
9044 case V_BSTR:
9045 case V_HSTR:
9046 case V_CSTR:
9047 case V_ISO2022STR:
9048 return u.str.val_str->size();
9049 case V_OSTR:
9050 return u.str.val_str->size()/2;
9051 case V_USTR:
9052 return u.ustr.val_ustr->size();
9053 default:
9054 FATAL_ERROR("Value::get_nof_comps()");
9055 return 0;
9056 } // switch
9057 }
9058
9059 bool Value::is_indexed() const
9060 {
9061 switch (valuetype) {
9062 case V_SEQOF:
9063 case V_SETOF:
9064 case V_ARRAY:
9065 // Applicable only for list-types. Assigning a record/SEQUENCE or
9066 // set/SET with indexed notation is not supported.
9067 return u.val_vs->is_indexed();
9068 default:
9069 FATAL_ERROR("Value::is_indexed()");
9070 break;
9071 }
9072 return false;
9073 }
9074
9075 const Identifier& Value::get_alt_name()
9076 {
9077 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9078 return *u.choice.alt_name;
9079 }
9080
9081 Value *Value::get_alt_value()
9082 {
9083 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9084 return u.choice.alt_value;
9085 }
9086
9087 void Value::set_alt_name_to_lowercase()
9088 {
9089 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9090 string new_name = u.choice.alt_name->get_name();
9091 if (isupper(new_name[0])) {
9092 new_name[0] = tolower(new_name[0]);
9093 if (new_name[new_name.size() - 1] == '_') {
9094 // an underscore is inserted at the end of the alternative name if it's
9095 // a basic type's name (since it would conflict with the class generated
9096 // for that type)
9097 // remove the underscore, it won't conflict with anything if its name
9098 // starts with a lowercase letter
9099 new_name.replace(new_name.size() - 1, 1, "");
9100 }
9101 delete u.choice.alt_name;
9102 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9103 }
9104 }
9105
9106 bool Value::has_oid_error()
9107 {
9108 Value *v;
9109 if (valuetype == V_REFD) v = get_value_refd_last();
9110 else v = this;
9111 switch (valuetype) {
9112 case V_OID:
9113 case V_ROID:
9114 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9115 if ((*v->u.oid_comps)[i]->has_error()) return true;
9116 return false;
9117 default:
9118 return true;
9119 }
9120 }
9121
9122 bool Value::get_oid_comps(vector<string>& comps)
9123 {
9124 bool ret_val = true;
9125 Value *v = this;
9126 switch (valuetype) {
9127 case V_REFD:
9128 v = get_value_refd_last();
9129 // no break
9130 case V_OID:
9131 case V_ROID:
9132 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9133 (*v->u.oid_comps)[i]->get_comps(comps);
9134 if ((*v->u.oid_comps)[i]->is_variable()) {
9135 // not all components can be calculated in compile-time
9136 ret_val = false;
9137 }
9138 }
9139 break;
9140 default:
9141 FATAL_ERROR("Value::get_oid_comps()");
9142 }
9143 return ret_val;
9144 }
9145
9146 void Value::add_se_comp(NamedValue* nv) {
9147 switch (valuetype) {
9148 case V_SEQ:
9149 case V_SET:
9150 if (!u.val_nvs)
9151 u.val_nvs = new NamedValues();
9152 u.val_nvs->add_nv(nv);
9153 break;
9154 default:
9155 FATAL_ERROR("Value::add_se_comp()");
9156 }
9157 }
9158
9159 NamedValue* Value::get_se_comp_byIndex(size_t n)
9160 {
9161 switch(valuetype) {
9162 case V_SEQ:
9163 case V_SET:
9164 return u.val_nvs->get_nv_byIndex(n);
9165 default:
9166 FATAL_ERROR("Value::get_se_comp_byIndex()");
9167 return 0;
9168 } // switch
9169 }
9170
9171 Value *Value::get_comp_byIndex(size_t n)
9172 {
9173 switch (valuetype) {
9174 case V_SEQOF:
9175 case V_SETOF:
9176 case V_ARRAY:
9177 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9178 return u.val_vs->get_iv_byIndex(n)->get_value();
9179 default:
9180 FATAL_ERROR("Value::get_comp_byIndex()");
9181 return 0;
9182 } // switch
9183 }
9184
9185 Value *Value::get_index_byIndex(size_t n)
9186 {
9187 switch (valuetype) {
9188 case V_SEQOF:
9189 case V_SETOF:
9190 case V_ARRAY:
9191 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9192 return u.val_vs->get_iv_byIndex(n)->get_index();
9193 default:
9194 FATAL_ERROR("Value::get_index_byIndex()");
9195 return 0;
9196 } // switch
9197 }
9198
9199 bool Value::has_comp_withName(const Identifier& p_name)
9200 {
9201 switch(valuetype) {
9202 case V_SEQ:
9203 case V_SET:
9204 return u.val_nvs->has_nv_withName(p_name);
9205 case V_CHOICE:
9206 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9207 default:
9208 FATAL_ERROR("Value::get_has_comp_withName()");
9209 return false;
9210 } // switch
9211 }
9212
9213 bool Value::field_is_chosen(const Identifier& p_name)
9214 {
9215 Value *v=get_value_refd_last();
9216 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9217 return *v->u.choice.alt_name==p_name;
9218 }
9219
9220 bool Value::field_is_present(const Identifier& p_name)
9221 {
9222 Value *v=get_value_refd_last();
9223 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9224 FATAL_ERROR("Value::field_is_present()");
9225 return v->u.val_nvs->has_nv_withName(p_name)
9226 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9227 ->get_value_refd_last()->valuetype != V_OMIT;
9228 }
9229
9230 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9231 {
9232 switch(valuetype) {
9233 case V_SEQ:
9234 case V_SET:
9235 return u.val_nvs->get_nv_byName(p_name);
9236 default:
9237 FATAL_ERROR("Value::get_se_comp_byName()");
9238 return 0;
9239 } // switch
9240 }
9241
9242 Value* Value::get_comp_value_byName(const Identifier& p_name)
9243 {
9244 switch(valuetype) {
9245 case V_SEQ:
9246 case V_SET:
9247 return u.val_nvs->get_nv_byName(p_name)->get_value();
9248 case V_CHOICE:
9249 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9250 return u.choice.alt_value;
9251 else
9252 return NULL;
9253 default:
9254 FATAL_ERROR("Value::get_se_comp_byName()");
9255 return 0;
9256 } // switch
9257 }
9258
9259 void Value::chk_dupl_id()
9260 {
9261 switch(valuetype) {
9262 case V_SEQ:
9263 case V_SET:
9264 u.val_nvs->chk_dupl_id();
9265 break;
9266 default:
9267 FATAL_ERROR("Value::chk_dupl_id()");
9268 } // switch
9269 }
9270
9271 size_t Value::get_nof_ids() const
9272 {
9273 switch(valuetype) {
9274 case V_NAMEDBITS:
9275 return u.ids->size();
9276 break;
9277 default:
9278 FATAL_ERROR("Value::get_nof_ids()");
9279 return 0;
9280 } // switch
9281 }
9282
9283 Identifier* Value::get_id_byIndex(size_t p_i)
9284 {
9285 switch(valuetype) {
9286 case V_NAMEDBITS:
9287 return u.ids->get_nth_elem(p_i);
9288 break;
9289 default:
9290 FATAL_ERROR("Value::get_id_byIndex()");
9291 return 0;
9292 } // switch
9293 }
9294
9295 bool Value::has_id(const Identifier& p_id)
9296 {
9297 switch(valuetype) {
9298 case V_NAMEDBITS:
9299 return u.ids->has_key(p_id.get_name());
9300 break;
9301 default:
9302 FATAL_ERROR("Value::has_id()");
9303 return false;
9304 } // switch
9305 }
9306
9307 Reference *Value::get_reference() const
9308 {
9309 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9310 return u.ref.ref;
9311 }
9312
9313 Reference *Value::get_refered() const
9314 {
9315 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9316 return u.refered;
9317 }
9318
9319 Common::Assignment *Value::get_refd_fat() const
9320 {
9321 switch(valuetype){
9322 case V_FUNCTION:
9323 case V_ALTSTEP:
9324 case V_TESTCASE:
9325 return u.refd_fat;
9326 default:
9327 FATAL_ERROR("Value::get_refd_fat()");
9328 }
9329 }
9330
9331 Ttcn::Reference* Value::steal_ttcn_ref()
9332 {
9333 Ttcn::Reference *ret_val =
9334 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9335 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9336 return ret_val;
9337 }
9338
9339 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9340 {
9341 Ttcn::Ref_base *t_ref;
9342 if(valuetype==V_REFD) {
9343 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9344 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9345 u.ref.ref=0;
9346 }
9347 else if(valuetype==V_UNDEF_LOWERID) {
9348 t_ref=new Ttcn::Reference(u.val_id);
9349 t_ref->set_location(*this);
9350 t_ref->set_fullname(get_fullname());
9351 t_ref->set_my_scope(get_my_scope());
9352 u.val_id=0;
9353 }
9354 else {
9355 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9356 t_ref = 0;
9357 }
9358 set_valuetype(V_ERROR);
9359 return t_ref;
9360 }
9361
9362 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9363 Ttcn::ActualParList*& p_ap)
9364 {
9365 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9366 p_v = u.invoke.v;
9367 u.invoke.v = 0;
9368 p_ti = u.invoke.t_list;
9369 u.invoke.t_list = 0;
9370 p_ap = u.invoke.ap_list;
9371 u.invoke.ap_list = 0;
9372 set_valuetype(V_ERROR);
9373 }
9374
9375 Common::Assignment* Value::get_refd_assignment()
9376 {
9377 switch(valuetype) {
9378 case V_FUNCTION:
9379 case V_ALTSTEP:
9380 case V_TESTCASE:
9381 return u.refd_fat;
9382 break;
9383 default:
9384 FATAL_ERROR("Value::get_refd_assignment()");
9385 return 0;
9386 }
9387 }
9388
9389 void Value::chk()
9390 {
9391 if(checked) return;
9392 switch(valuetype) {
9393 case V_OID: {
9394 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9395 " components");
9396 chk_OID(refch);
9397 break; }
9398 case V_ROID: {
9399 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9400 chk_ROID(refch);
9401 break; }
9402 default:
9403 break;
9404 } // switch
9405 checked=true;
9406 }
9407
9408 void Value::chk_OID(ReferenceChain& refch)
9409 {
9410 if (checked) return;
9411 if (valuetype != V_OID || u.oid_comps->size() < 1)
9412 FATAL_ERROR("Value::chk_OID()");
9413 if (!refch.add(get_fullname())) {
9414 checked = true;
9415 return;
9416 }
9417 OID_comp::oidstate_t state = OID_comp::START;
9418 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9419 refch.mark_state();
9420 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9421 refch.prev_state();
9422 }
9423 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9424 error("An OBJECT IDENTIFIER value must have at least "
9425 "two components"); // X.680 (07/2002) 31.10
9426 }
9427
9428 void Value::chk_ROID(ReferenceChain& refch)
9429 {
9430 if (checked) return;
9431 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9432 FATAL_ERROR("Value::chk_ROID()");
9433 if (!refch.add(get_fullname())) {
9434 checked = true;
9435 return;
9436 }
9437 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9438 refch.mark_state();
9439 (*u.oid_comps)[i]->chk_ROID(refch, i);
9440 refch.prev_state();
9441 }
9442 }
9443
9444 void Value::chk_recursions(ReferenceChain& refch)
9445 {
9446 if (recurs_checked) return;
9447 Value *v = get_value_refd_last();
9448 if (refch.add(v->get_fullname())) {
9449 switch (v->valuetype) {
9450 case V_CHOICE:
9451 v->u.choice.alt_value->chk_recursions(refch);
9452 break;
9453 case V_SEQOF:
9454 case V_SETOF:
9455 case V_ARRAY:
9456 if (!v->is_indexed()) {
9457 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9458 refch.mark_state();
9459 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9460 refch.prev_state();
9461 }
9462 } else {
9463 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9464 refch.mark_state();
9465 v->u.val_vs->get_iv_byIndex(i)->get_value()
9466 ->chk_recursions(refch);
9467 refch.prev_state();
9468 }
9469 }
9470 break;
9471 case V_SEQ:
9472 case V_SET:
9473 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9474 refch.mark_state();
9475 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9476 refch.prev_state();
9477 }
9478 break;
9479 case V_EXPR:
9480 chk_recursions_expr(refch);
9481 break;
9482 default:
9483 break;
9484 }
9485 if (v->err_descr) { // FIXME: make this work
9486 v->err_descr->chk_recursions(refch);
9487 }
9488 }
9489 recurs_checked = true;
9490 }
9491
9492 void Value::chk_recursions_expr(ReferenceChain& refch)
9493 {
9494 // first classify the unchecked ischosen() operation
9495 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9496 switch (u.expr.v_optype) {
9497 case OPTYPE_UNARYPLUS: // v1
9498 case OPTYPE_UNARYMINUS:
9499 case OPTYPE_NOT:
9500 case OPTYPE_NOT4B:
9501 case OPTYPE_BIT2HEX:
9502 case OPTYPE_BIT2INT:
9503 case OPTYPE_BIT2OCT:
9504 case OPTYPE_BIT2STR:
9505 case OPTYPE_CHAR2INT:
9506 case OPTYPE_CHAR2OCT:
9507 case OPTYPE_FLOAT2INT:
9508 case OPTYPE_FLOAT2STR:
9509 case OPTYPE_HEX2BIT:
9510 case OPTYPE_HEX2INT:
9511 case OPTYPE_HEX2OCT:
9512 case OPTYPE_HEX2STR:
9513 case OPTYPE_INT2CHAR:
9514 case OPTYPE_INT2FLOAT:
9515 case OPTYPE_INT2STR:
9516 case OPTYPE_INT2UNICHAR:
9517 case OPTYPE_OCT2BIT:
9518 case OPTYPE_OCT2CHAR:
9519 case OPTYPE_OCT2HEX:
9520 case OPTYPE_OCT2INT:
9521 case OPTYPE_OCT2STR:
9522 case OPTYPE_STR2BIT:
9523 case OPTYPE_STR2FLOAT:
9524 case OPTYPE_STR2HEX:
9525 case OPTYPE_STR2INT:
9526 case OPTYPE_STR2OCT:
9527 case OPTYPE_UNICHAR2INT:
9528 case OPTYPE_ENUM2INT:
9529 case OPTYPE_UNICHAR2CHAR:
9530 case OPTYPE_RNDWITHVAL:
9531 case OPTYPE_ISCHOSEN_V:
9532 case OPTYPE_GET_STRINGENCODING:
9533 case OPTYPE_REMOVE_BOM:
9534 case OPTYPE_DECODE_BASE64:
9535 refch.mark_state();
9536 u.expr.v1->chk_recursions(refch);
9537 refch.prev_state();
9538 break;
9539 case OPTYPE_ISCHOSEN_T:
9540 refch.mark_state();
9541 u.expr.t1->chk_recursions(refch);
9542 refch.prev_state();
9543 break;
9544 case OPTYPE_ADD: // v1 v2
9545 case OPTYPE_SUBTRACT:
9546 case OPTYPE_MULTIPLY:
9547 case OPTYPE_DIVIDE:
9548 case OPTYPE_MOD:
9549 case OPTYPE_REM:
9550 case OPTYPE_CONCAT:
9551 case OPTYPE_EQ:
9552 case OPTYPE_LT:
9553 case OPTYPE_GT:
9554 case OPTYPE_NE:
9555 case OPTYPE_GE:
9556 case OPTYPE_LE:
9557 case OPTYPE_AND:
9558 case OPTYPE_OR:
9559 case OPTYPE_XOR:
9560 case OPTYPE_AND4B:
9561 case OPTYPE_OR4B:
9562 case OPTYPE_XOR4B:
9563 case OPTYPE_SHL:
9564 case OPTYPE_SHR:
9565 case OPTYPE_ROTL:
9566 case OPTYPE_ROTR:
9567 case OPTYPE_INT2BIT:
9568 case OPTYPE_INT2HEX:
9569 case OPTYPE_INT2OCT:
9570 refch.mark_state();
9571 u.expr.v1->chk_recursions(refch);
9572 refch.prev_state();
9573 refch.mark_state();
9574 u.expr.v2->chk_recursions(refch);
9575 refch.prev_state();
9576 break;
9577 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9578 case OPTYPE_OCT2UNICHAR:
9579 case OPTYPE_ENCODE_BASE64:
9580 refch.mark_state();
9581 u.expr.v1->chk_recursions(refch);
9582 refch.prev_state();
9583 if (u.expr.v2) {
9584 refch.mark_state();
9585 u.expr.v2->chk_recursions(refch);
9586 refch.prev_state();
9587 }
9588 break;
9589 case OPTYPE_DECODE:
9590 chk_recursions_expr_decode(u.expr.r1, refch);
9591 chk_recursions_expr_decode(u.expr.r2, refch);
9592 break;
9593 case OPTYPE_SUBSTR:
9594 refch.mark_state();
9595 u.expr.ti1->chk_recursions(refch);
9596 refch.prev_state();
9597 refch.mark_state();
9598 u.expr.v2->chk_recursions(refch);
9599 refch.prev_state();
9600 refch.mark_state();
9601 u.expr.v3->chk_recursions(refch);
9602 refch.prev_state();
9603 break;
9604 case OPTYPE_REGEXP:
9605 refch.mark_state();
9606 u.expr.ti1->chk_recursions(refch);
9607 refch.prev_state();
9608 refch.mark_state();
9609 u.expr.t2->chk_recursions(refch);
9610 refch.prev_state();
9611 refch.mark_state();
9612 u.expr.v3->chk_recursions(refch);
9613 refch.prev_state();
9614 break;
9615 case OPTYPE_DECOMP: // v1 v2 v3
9616 refch.mark_state();
9617 u.expr.v1->chk_recursions(refch);
9618 refch.prev_state();
9619 refch.mark_state();
9620 u.expr.v2->chk_recursions(refch);
9621 refch.prev_state();
9622 refch.mark_state();
9623 u.expr.v3->chk_recursions(refch);
9624 refch.prev_state();
9625 break;
9626 case OPTYPE_REPLACE:
9627 refch.mark_state();
9628 u.expr.ti1->chk_recursions(refch);
9629 refch.prev_state();
9630 refch.mark_state();
9631 u.expr.v2->chk_recursions(refch);
9632 refch.prev_state();
9633 refch.mark_state();
9634 u.expr.v3->chk_recursions(refch);
9635 refch.prev_state();
9636 refch.mark_state();
9637 u.expr.ti4->chk_recursions(refch);
9638 refch.prev_state();
9639 break;
9640 case OPTYPE_LENGTHOF: // ti1
9641 case OPTYPE_SIZEOF: // ti1
9642 case OPTYPE_VALUEOF: // ti1
9643 case OPTYPE_ENCODE:
9644 case OPTYPE_ISPRESENT:
9645 case OPTYPE_TTCN2STRING:
9646 refch.mark_state();
9647 u.expr.ti1->chk_recursions(refch);
9648 refch.prev_state();
9649 break;
9650 case OPTYPE_MATCH: // v1 t2
9651 refch.mark_state();
9652 u.expr.v1->chk_recursions(refch);
9653 refch.prev_state();
9654 refch.mark_state();
9655 u.expr.t2->chk_recursions(refch);
9656 refch.prev_state();
9657 break;
9658 case OPTYPE_LOG2STR:
9659 u.expr.logargs->chk_recursions(refch);
9660 break;
9661 default:
9662 break;
9663 } // switch
9664 }
9665
9666 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9667 ReferenceChain& refch) {
9668 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9669 Assignment *ass = ref->get_refd_assignment();
9670 if (!ass) {
9671 set_valuetype(V_ERROR);
9672 return;
9673 }
9674 switch (ass->get_asstype()) {
9675 case Assignment::A_CONST:
9676 case Assignment::A_EXT_CONST:
9677 case Assignment::A_MODULEPAR:
9678 case Assignment::A_VAR:
9679 case Assignment::A_PAR_VAL_IN:
9680 case Assignment::A_PAR_VAL_OUT:
9681 case Assignment::A_PAR_VAL_INOUT: {
9682 Value* v = new Value(V_REFD, ref);
9683 v->set_location(*ref);
9684 v->set_my_scope(get_my_scope());
9685 v->set_fullname(get_fullname()+".<operand>");
9686 refch.mark_state();
9687 v->chk_recursions(refch);
9688 refch.prev_state();
9689 delete v;
9690 break; }
9691 case Assignment::A_MODULEPAR_TEMP:
9692 case Assignment::A_TEMPLATE:
9693 case Assignment::A_VAR_TEMPLATE:
9694 case Assignment::A_PAR_TEMPL_IN:
9695 case Assignment::A_PAR_TEMPL_OUT:
9696 case Assignment::A_PAR_TEMPL_INOUT: {
9697 Template* t = new Template(ref->clone());
9698 t->set_location(*ref);
9699 t->set_my_scope(get_my_scope());
9700 t->set_fullname(get_fullname()+".<operand>");
9701 refch.mark_state();
9702 t->chk_recursions(refch);
9703 refch.prev_state();
9704 delete t;
9705 break; }
9706 default:
9707 // remain silent, the error has been already reported
9708 set_valuetype(V_ERROR);
9709 break;
9710 } // switch
9711 }
9712
9713 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9714 {
9715 bool self_ref = false;
9716 switch (t->get_templatetype()) {
9717 case Ttcn::Template::SPECIFIC_VALUE: {
9718 Value *v = t->get_specific_value();
9719 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9720 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9721 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9722 break; }
9723 case Ttcn::Template::TEMPLATE_REFD: {
9724 Ttcn::Ref_base *refb = t->get_reference();
9725 Common::Assignment *ass = refb->get_refd_assignment();
9726 self_ref |= (ass == lhs);
9727 break; }
9728 case Ttcn::Template::ALL_FROM:
9729 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9730 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9731 break;
9732 case Ttcn::Template::TEMPLATE_LIST:
9733 case Ttcn::Template::SUPERSET_MATCH:
9734 case Ttcn::Template::SUBSET_MATCH:
9735 case Ttcn::Template::PERMUTATION_MATCH:
9736 case Ttcn::Template::COMPLEMENTED_LIST:
9737 case Ttcn::Template::VALUE_LIST: {
9738 size_t num = t->get_nof_comps();
9739 for (size_t i = 0; i < num; ++i) {
9740 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9741 }
9742 break; }
9743 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9744 // case Ttcn::Template::TEMPLATE_LIST: {
9745 // size_t num = t->get_nof_listitems();
9746 // for (size_t i=0; i < num; ++i) {
9747 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9748 // }
9749 // break; }
9750 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9751 size_t nnt = t->get_nof_comps();
9752 for (size_t i=0; i < nnt; ++i) {
9753 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9754 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9755 }
9756 break; }
9757 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9758 size_t nnt = t->get_nof_comps();
9759 for (size_t i=0; i < nnt; ++i) {
9760 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9761 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9762 }
9763 break; }
9764 case Ttcn::Template::VALUE_RANGE: {
9765 Ttcn::ValueRange *vr = t->get_value_range();
9766 Common::Value *v = vr->get_min_v();
9767 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9768 v = vr->get_max_v();
9769 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9770 break; }
9771 case Ttcn::Template::CSTR_PATTERN:
9772 case Ttcn::Template::USTR_PATTERN: {
9773 Ttcn::PatternString *ps = t->get_cstr_pattern();
9774 self_ref |= ps->chk_self_ref(lhs);
9775 break; }
9776 case Ttcn::Template::BSTR_PATTERN:
9777 case Ttcn::Template::HSTR_PATTERN:
9778 case Ttcn::Template::OSTR_PATTERN: {
9779 // FIXME: cannot access u.pattern
9780 break; }
9781 case Ttcn::Template::ANY_VALUE:
9782 case Ttcn::Template::ANY_OR_OMIT:
9783 case Ttcn::Template::OMIT_VALUE:
9784 case Ttcn::Template::TEMPLATE_NOTUSED:
9785 break; // self-ref can't happen
9786 case Ttcn::Template::TEMPLATE_INVOKE:
9787 break; // assume self-ref can't happen
9788 case Ttcn::Template::TEMPLATE_ERROR:
9789 FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9790 break; // not reached
9791 // default:
9792 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9793 // break; // and hope for the best
9794 }
9795 return self_ref;
9796 }
9797
9798 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
9799 {
9800 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
9801 namedbool is_str_elem = NOT_STR_ELEM;
9802 if (v->valuetype == V_REFD) {
9803 Reference *ref = v->get_reference();
9804 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
9805 if (subrefs && subrefs->refers_to_string_element()) {
9806 is_str_elem = IS_STR_ELEM;
9807 }
9808 }
9809 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9810 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
9811 is_str_elem);
9812 }
9813
9814 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
9815 {
9816 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
9817 if (!lhs) FATAL_ERROR("no lhs!");
9818 bool self_ref = false;
9819 switch (u.expr.v_optype) {
9820 case OPTYPE_RND: // -
9821 case OPTYPE_TESTCASENAME: // -
9822 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
9823 case OPTYPE_COMP_MTC: // -
9824 case OPTYPE_COMP_SYSTEM: // -
9825 case OPTYPE_COMP_SELF: // -
9826 case OPTYPE_COMP_RUNNING_ANY: // -
9827 case OPTYPE_COMP_RUNNING_ALL: // -
9828 case OPTYPE_COMP_ALIVE_ANY: // -
9829 case OPTYPE_COMP_ALIVE_ALL: // -
9830 case OPTYPE_TMR_RUNNING_ANY: // -
9831 case OPTYPE_GETVERDICT: // -
9832 case OPTYPE_PROF_RUNNING: // -
9833 break; // nothing to do
9834
9835 case OPTYPE_MATCH: // v1 t2
9836 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
9837 // no break
9838 case OPTYPE_UNARYPLUS: // v1
9839 case OPTYPE_UNARYMINUS: // v1
9840 case OPTYPE_NOT: // v1
9841 case OPTYPE_NOT4B: // v1
9842 case OPTYPE_BIT2HEX: // v1
9843 case OPTYPE_BIT2INT: // v1
9844 case OPTYPE_BIT2OCT: // v1
9845 case OPTYPE_BIT2STR: // v1
9846 case OPTYPE_CHAR2INT: // v1
9847 case OPTYPE_CHAR2OCT: // v1
9848 case OPTYPE_FLOAT2INT: // v1
9849 case OPTYPE_FLOAT2STR: // v1
9850 case OPTYPE_HEX2BIT: // v1
9851 case OPTYPE_HEX2INT: // v1
9852 case OPTYPE_HEX2OCT: // v1
9853 case OPTYPE_HEX2STR: // v1
9854 case OPTYPE_INT2CHAR: // v1
9855 case OPTYPE_INT2FLOAT: // v1
9856 case OPTYPE_INT2STR: // v1
9857 case OPTYPE_INT2UNICHAR: // v1
9858 case OPTYPE_OCT2BIT: // v1
9859 case OPTYPE_OCT2CHAR: // v1
9860 case OPTYPE_OCT2HEX: // v1
9861 case OPTYPE_OCT2INT: // v1
9862 case OPTYPE_OCT2STR: // v1
9863 case OPTYPE_STR2BIT: // v1
9864 case OPTYPE_STR2FLOAT: // v1
9865 case OPTYPE_STR2HEX: // v1
9866 case OPTYPE_STR2INT: // v1
9867 case OPTYPE_STR2OCT: // v1
9868 case OPTYPE_UNICHAR2INT: // v1
9869 case OPTYPE_UNICHAR2CHAR: // v1
9870 case OPTYPE_ENUM2INT: // v1
9871 case OPTYPE_RNDWITHVAL: // v1
9872 case OPTYPE_COMP_RUNNING: // v1
9873 case OPTYPE_COMP_ALIVE: // v1
9874 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
9875 case OPTYPE_GET_STRINGENCODING:
9876 case OPTYPE_DECODE_BASE64:
9877 case OPTYPE_REMOVE_BOM:
9878 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9879 break;
9880 case OPTYPE_ADD: // v1 v2
9881 case OPTYPE_SUBTRACT: // v1 v2
9882 case OPTYPE_MULTIPLY: // v1 v2
9883 case OPTYPE_DIVIDE: // v1 v2
9884 case OPTYPE_MOD: // v1 v2
9885 case OPTYPE_REM: // v1 v2
9886 case OPTYPE_CONCAT: // v1 v2
9887 case OPTYPE_EQ: // v1 v2
9888 case OPTYPE_LT: // v1 v2
9889 case OPTYPE_GT: // v1 v2
9890 case OPTYPE_NE: // v1 v2
9891 case OPTYPE_GE: // v1 v2
9892 case OPTYPE_LE: // v1 v2
9893 case OPTYPE_AND: // v1 v2
9894 case OPTYPE_OR: // v1 v2
9895 case OPTYPE_XOR: // v1 v2
9896 case OPTYPE_AND4B: // v1 v2
9897 case OPTYPE_OR4B: // v1 v2
9898 case OPTYPE_XOR4B: // v1 v2
9899 case OPTYPE_SHL: // v1 v2
9900 case OPTYPE_SHR: // v1 v2
9901 case OPTYPE_ROTL: // v1 v2
9902 case OPTYPE_ROTR: // v1 v2
9903 case OPTYPE_INT2BIT: // v1 v2
9904 case OPTYPE_INT2HEX: // v1 v2
9905 case OPTYPE_INT2OCT: // v1 v2
9906 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9907 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9908 break;
9909 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9910 case OPTYPE_OCT2UNICHAR:
9911 case OPTYPE_ENCODE_BASE64:
9912 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9913 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9914 break;
9915 case OPTYPE_DECOMP: // v1 v2 v3
9916 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9917 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9918 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9919 break;
9920
9921 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
9922 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
9923 // no break
9924 case OPTYPE_SUBSTR: // ti1 v2 v3
9925 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9926 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
9927 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
9928 break;
9929
9930 case OPTYPE_REGEXP: // ti1 t2 v3
9931 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9932 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
9933 // no break
9934 case OPTYPE_LENGTHOF: // ti1
9935 case OPTYPE_SIZEOF: // ti1
9936 case OPTYPE_VALUEOF: // ti1
9937 case OPTYPE_ENCODE: // ti1
9938 case OPTYPE_TTCN2STRING:
9939 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9940 break;
9941
9942 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
9943 // component.create -- assume no self-ref
9944 case OPTYPE_ACTIVATE: // r1
9945 // defaultref := activate(altstep) -- assume no self-ref
9946 case OPTYPE_TMR_RUNNING: // r1
9947 // boolvar := a_timer.running -- assume no self-ref
9948 break;
9949 break;
9950
9951 case OPTYPE_LOG2STR: {// logargs
9952 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
9953 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
9954 switch (la->get_type()) {
9955 case Ttcn::LogArgument::L_UNDEF:
9956 case Ttcn::LogArgument::L_ERROR:
9957 FATAL_ERROR("log2str argument type");
9958 break; // not reached
9959
9960 case Ttcn::LogArgument::L_MACRO:
9961 case Ttcn::LogArgument::L_STR:
9962 break; // self reference not possible
9963
9964 case Ttcn::LogArgument::L_VAL:
9965 case Ttcn::LogArgument::L_MATCH:
9966 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
9967 break;
9968
9969 case Ttcn::LogArgument::L_REF: {
9970 Ttcn::Ref_base *ref = la->get_ref();
9971 Common::Assignment *ass = ref->get_refd_assignment();
9972 self_ref |= (ass == lhs);
9973 break; }
9974
9975 case Ttcn::LogArgument::L_TI: {
9976 Ttcn::TemplateInstance *ti = la->get_ti();
9977 Ttcn::Template *t = ti->get_Template();
9978 self_ref |= chk_expr_self_ref_templ(t, lhs);
9979 break; }
9980
9981 // no default please
9982 } // switch la->logargtype
9983 }
9984 break; }
9985
9986 case OPTYPE_DECODE: { // r1 r2
9987 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
9988 self_ref |= (ass == lhs);
9989 goto label_r1; }
9990 case OPTYPE_EXECUTE: // r1 [v2]
9991 if (u.expr.v2) {
9992 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9993 }
9994 label_r1:
9995 // no break
9996 case OPTYPE_UNDEF_RUNNING: // r1
9997 case OPTYPE_TMR_READ: { // r1
9998 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
9999 self_ref |= (ass == lhs);
10000 break; }
10001
10002 case OPTYPE_ISCHOSEN_T: // t1 i2
10003 case OPTYPE_ISBOUND: // ti1
10004 case OPTYPE_ISVALUE: // ti1
10005 case OPTYPE_ISPRESENT: { // ti1
10006 Ttcn::Template *t;
10007 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10008 else t = u.expr.ti1->get_Template();
10009 self_ref |= chk_expr_self_ref_templ(t, lhs);
10010 break; }
10011
10012 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10013 if (u.expr.v3) {
10014 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10015 }
10016 // no break
10017 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10018 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10019 // TODO t_list2
10020 break;
10021
10022 case NUMBER_OF_OPTYPES: // can never happen
10023 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10024 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10025 break;
10026 } // switch u.expr.v_optype
10027 return self_ref;
10028 }
10029
10030
10031 string Value::create_stringRepr()
10032 {
10033 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10034 switch (valuetype) {
10035 case V_ERROR:
10036 return string("<erroneous>");
10037 case V_NULL:
10038 return string("NULL");
10039 case V_BOOL:
10040 if (!parse_only && is_asn1()) {
10041 if (u.val_bool) return string("TRUE");
10042 else return string("FALSE");
10043 }
10044 else {
10045 if (u.val_bool) return string("true");
10046 else return string("false");
10047 }
10048 case V_INT:
10049 return u.val_Int->t_str();
10050 case V_REAL:
10051 return Real2string(u.val_Real);
10052 case V_ENUM:
10053 case V_NAMEDINT:
10054 case V_UNDEF_LOWERID:
10055 return u.val_id->get_name();
10056 case V_NAMEDBITS: {
10057 string ret_val("{ ");
10058 for (size_t i = 0; i < u.ids->size(); i++) {
10059 if (i>0) ret_val += ' ';
10060 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10061 }
10062 ret_val += '}';
10063 return ret_val; }
10064 case V_BSTR: {
10065 string ret_val('\'');
10066 ret_val += *u.str.val_str;
10067 ret_val += "'B";
10068 return ret_val; }
10069 case V_HSTR: {
10070 string ret_val('\'');
10071 ret_val += *u.str.val_str;
10072 ret_val += "'H";
10073 return ret_val; }
10074 case V_OSTR: {
10075 string ret_val('\'');
10076 ret_val += *u.str.val_str;
10077 ret_val += "'O";
10078 return ret_val; }
10079 case V_CSTR:
10080 case V_ISO2022STR:
10081 return u.str.val_str->get_stringRepr();
10082 case V_USTR:
10083 return u.ustr.val_ustr->get_stringRepr();
10084 case V_CHARSYMS:
10085 /** \todo stringrepr of V_CHARSYMS */
10086 return string("<sorry, string representation of charsyms "
10087 "not implemented>");
10088 case V_OID:
10089 case V_ROID: {
10090 string ret_val;
10091 if (parse_only || !is_asn1()) ret_val += "objid ";
10092 ret_val += "{ ";
10093 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10094 if (i>0) ret_val += ' ';
10095 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10096 }
10097 ret_val += " }";
10098 return ret_val; }
10099 case V_CHOICE:
10100 if (!parse_only && is_asn1()) {
10101 string ret_val(u.choice.alt_name->get_dispname());
10102 ret_val += " : ";
10103 ret_val += u.choice.alt_value->get_stringRepr();
10104 return ret_val;
10105 }
10106 else {
10107 string ret_val("{ ");
10108 ret_val += u.choice.alt_name->get_dispname();
10109 ret_val += " := ";
10110 ret_val += u.choice.alt_value->get_stringRepr();
10111 ret_val += " }";
10112 return ret_val;
10113 }
10114 case V_SEQOF:
10115 case V_SETOF:
10116 case V_ARRAY: {
10117 string ret_val("{ ");
10118 if (!is_indexed()) {
10119 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10120 if (i > 0) ret_val += ", ";
10121 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10122 }
10123 } else {
10124 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10125 if (i > 0) ret_val += ", ";
10126 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10127 }
10128 }
10129 ret_val += " }";
10130 return ret_val; }
10131 case V_SEQ:
10132 case V_SET: {
10133 string ret_val("{ ");
10134 bool asn1_flag = !parse_only && is_asn1();
10135 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10136 if (i > 0) ret_val += ", ";
10137 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10138 ret_val += nv->get_name().get_dispname();
10139 if (asn1_flag) ret_val += ' ';
10140 else ret_val += " := ";
10141 ret_val += nv->get_value()->get_stringRepr();
10142 }
10143 ret_val += " }";
10144 return ret_val; }
10145 case V_REFD: {
10146 // do not evaluate the reference if it is not done so far
10147 // (e.g. in parse-only mode)
10148 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10149 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10150 else return t_val->get_stringRepr(); }
10151 case V_OMIT:
10152 return string("omit");
10153 case V_VERDICT:
10154 switch (u.verdict) {
10155 case Verdict_NONE:
10156 return string("none");
10157 case Verdict_PASS:
10158 return string("pass");
10159 case Verdict_INCONC:
10160 return string("inconc");
10161 case Verdict_FAIL:
10162 return string("fail");
10163 case Verdict_ERROR:
10164 return string("error");
10165 default:
10166 return string("<unknown verdict value>");
10167 }
10168 case V_DEFAULT_NULL:
10169 case V_FAT_NULL:
10170 return string("null");
10171 case V_EXPR:
10172 switch (u.expr.v_optype) {
10173 case OPTYPE_RND:
10174 return string("rnd()");
10175 case OPTYPE_TESTCASENAME:
10176 return string("testcasename()");
10177 case OPTYPE_UNARYPLUS:
10178 return create_stringRepr_unary("+");
10179 case OPTYPE_UNARYMINUS:
10180 return create_stringRepr_unary("-");
10181 case OPTYPE_NOT:
10182 return create_stringRepr_unary("not");
10183 case OPTYPE_NOT4B:
10184 return create_stringRepr_unary("not4b");
10185 case OPTYPE_BIT2HEX:
10186 return create_stringRepr_predef1("bit2hex");
10187 case OPTYPE_BIT2INT:
10188 return create_stringRepr_predef1("bit2int");
10189 case OPTYPE_BIT2OCT:
10190 return create_stringRepr_predef1("bit2oct");
10191 case OPTYPE_BIT2STR:
10192 return create_stringRepr_predef1("bit2str");
10193 case OPTYPE_CHAR2INT:
10194 return create_stringRepr_predef1("char2int");
10195 case OPTYPE_CHAR2OCT:
10196 return create_stringRepr_predef1("char2oct");
10197 case OPTYPE_FLOAT2INT:
10198 return create_stringRepr_predef1("float2int");
10199 case OPTYPE_FLOAT2STR:
10200 return create_stringRepr_predef1("float2str");
10201 case OPTYPE_HEX2BIT:
10202 return create_stringRepr_predef1("hex2bit");
10203 case OPTYPE_HEX2INT:
10204 return create_stringRepr_predef1("hex2int");
10205 case OPTYPE_HEX2OCT:
10206 return create_stringRepr_predef1("hex2oct");
10207 case OPTYPE_HEX2STR:
10208 return create_stringRepr_predef1("hex2str");
10209 case OPTYPE_INT2CHAR:
10210 return create_stringRepr_predef1("int2char");
10211 case OPTYPE_INT2FLOAT:
10212 return create_stringRepr_predef1("int2float");
10213 case OPTYPE_INT2STR:
10214 return create_stringRepr_predef1("int2str");
10215 case OPTYPE_INT2UNICHAR:
10216 return create_stringRepr_predef1("int2unichar");
10217 case OPTYPE_OCT2BIT:
10218 return create_stringRepr_predef1("oct2bit");
10219 case OPTYPE_OCT2CHAR:
10220 return create_stringRepr_predef1("oct2char");
10221 case OPTYPE_OCT2HEX:
10222 return create_stringRepr_predef1("oct2hex");
10223 case OPTYPE_OCT2INT:
10224 return create_stringRepr_predef1("oct2int");
10225 case OPTYPE_OCT2STR:
10226 return create_stringRepr_predef1("oct2str");
10227 case OPTYPE_GET_STRINGENCODING:
10228 return create_stringRepr_predef1("get_stringencoding");
10229 case OPTYPE_REMOVE_BOM:
10230 return create_stringRepr_predef1("remove_bom");
10231 case OPTYPE_ENCODE_BASE64: {
10232 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10233 else return create_stringRepr_predef1("encode_base64");
10234 }
10235 case OPTYPE_DECODE_BASE64:
10236 return create_stringRepr_predef1("decode_base64");
10237 case OPTYPE_OCT2UNICHAR:{
10238 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10239 else return create_stringRepr_predef1("oct2unichar");
10240 }
10241 case OPTYPE_UNICHAR2OCT: {
10242 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10243 else return create_stringRepr_predef1("unichar2oct");
10244 }
10245 case OPTYPE_STR2BIT:
10246 return create_stringRepr_predef1("str2bit");
10247 case OPTYPE_STR2FLOAT:
10248 return create_stringRepr_predef1("str2float");
10249 case OPTYPE_STR2HEX:
10250 return create_stringRepr_predef1("str2hex");
10251 case OPTYPE_STR2INT:
10252 return create_stringRepr_predef1("str2int");
10253 case OPTYPE_STR2OCT:
10254 return create_stringRepr_predef1("str2oct");
10255 case OPTYPE_UNICHAR2INT:
10256 return create_stringRepr_predef1("unichar2int");
10257 case OPTYPE_UNICHAR2CHAR:
10258 return create_stringRepr_predef1("unichar2char");
10259 case OPTYPE_ENUM2INT:
10260 return create_stringRepr_predef1("enum2int");
10261 case OPTYPE_ENCODE:
10262 return create_stringRepr_predef1("encvalue");
10263 case OPTYPE_DECODE:
10264 return create_stringRepr_predef2("decvalue");
10265 case OPTYPE_RNDWITHVAL:
10266 return create_stringRepr_predef1("rnd");
10267 case OPTYPE_ADD:
10268 return create_stringRepr_infix("+");
10269 case OPTYPE_SUBTRACT:
10270 return create_stringRepr_infix("-");
10271 case OPTYPE_MULTIPLY:
10272 return create_stringRepr_infix("*");
10273 case OPTYPE_DIVIDE:
10274 return create_stringRepr_infix("/");
10275 case OPTYPE_MOD:
10276 return create_stringRepr_infix("mod");
10277 case OPTYPE_REM:
10278 return create_stringRepr_infix("rem");
10279 case OPTYPE_CONCAT:
10280 return create_stringRepr_infix("&");
10281 case OPTYPE_EQ:
10282 return create_stringRepr_infix("==");
10283 case OPTYPE_LT:
10284 return create_stringRepr_infix("<");
10285 case OPTYPE_GT:
10286 return create_stringRepr_infix(">");
10287 case OPTYPE_NE:
10288 return create_stringRepr_infix("!=");
10289 case OPTYPE_GE:
10290 return create_stringRepr_infix(">=");
10291 case OPTYPE_LE:
10292 return create_stringRepr_infix("<=");
10293 case OPTYPE_AND:
10294 return create_stringRepr_infix("and");
10295 case OPTYPE_OR:
10296 return create_stringRepr_infix("or");
10297 case OPTYPE_XOR:
10298 return create_stringRepr_infix("xor");
10299 case OPTYPE_AND4B:
10300 return create_stringRepr_infix("and4b");
10301 case OPTYPE_OR4B:
10302 return create_stringRepr_infix("or4b");
10303 case OPTYPE_XOR4B:
10304 return create_stringRepr_infix("xor4b");
10305 case OPTYPE_SHL:
10306 return create_stringRepr_infix("<<");
10307 case OPTYPE_SHR:
10308 return create_stringRepr_infix(">>");
10309 case OPTYPE_ROTL:
10310 return create_stringRepr_infix("<@");
10311 case OPTYPE_ROTR:
10312 return create_stringRepr_infix("@>");
10313 case OPTYPE_INT2BIT:
10314 return create_stringRepr_predef2("int2bit");
10315 case OPTYPE_INT2HEX:
10316 return create_stringRepr_predef2("int2hex");
10317 case OPTYPE_INT2OCT:
10318 return create_stringRepr_predef2("int2oct");
10319 case OPTYPE_SUBSTR: {
10320 string ret_val("substr(");
10321 u.expr.ti1->append_stringRepr(ret_val);
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_REGEXP: {
10330 string ret_val("regexp(");
10331 u.expr.ti1->append_stringRepr(ret_val);
10332 ret_val += ", ";
10333 u.expr.t2->append_stringRepr(ret_val);
10334 ret_val += ", ";
10335 ret_val += u.expr.v3->get_stringRepr();
10336 ret_val += ')';
10337 return ret_val;
10338 }
10339 case OPTYPE_DECOMP: {
10340 string ret_val("decomp(");
10341 ret_val += u.expr.v1->get_stringRepr();
10342 ret_val += ", ";
10343 ret_val += u.expr.v2->get_stringRepr();
10344 ret_val += ", ";
10345 ret_val += u.expr.v3->get_stringRepr();
10346 ret_val += ')';
10347 return ret_val;
10348 }
10349 case OPTYPE_REPLACE: {
10350 string ret_val("replace(");
10351 u.expr.ti1->append_stringRepr(ret_val);
10352 ret_val += ", ";
10353 ret_val += u.expr.v2->get_stringRepr();
10354 ret_val += ", ";
10355 ret_val += u.expr.v3->get_stringRepr();
10356 ret_val += ", ";
10357 u.expr.ti4->append_stringRepr(ret_val);
10358 ret_val += ')';
10359 return ret_val;
10360 }
10361 case OPTYPE_ISPRESENT: {
10362 string ret_val("ispresent(");
10363 u.expr.ti1->append_stringRepr(ret_val);
10364 ret_val += ')';
10365 return ret_val; }
10366 case OPTYPE_ISCHOSEN: {
10367 string ret_val("ischosen(");
10368 ret_val += u.expr.r1->get_dispname();
10369 ret_val += '.';
10370 ret_val += u.expr.i2->get_dispname();
10371 ret_val += ')';
10372 return ret_val; }
10373 case OPTYPE_ISCHOSEN_V: {
10374 string ret_val("ischosen(");
10375 ret_val += u.expr.v1->get_stringRepr();
10376 ret_val += '.';
10377 ret_val += u.expr.i2->get_dispname();
10378 ret_val += ')';
10379 return ret_val; }
10380 case OPTYPE_ISCHOSEN_T: {
10381 string ret_val("ischosen(");
10382 ret_val += u.expr.t1->get_stringRepr();
10383 ret_val += '.';
10384 ret_val += u.expr.i2->get_dispname();
10385 ret_val += ')';
10386 return ret_val; }
10387 case OPTYPE_LENGTHOF: {
10388 string ret_val("lengthof(");
10389 u.expr.ti1->append_stringRepr(ret_val);
10390 ret_val += ')';
10391 return ret_val; }
10392 case OPTYPE_SIZEOF: {
10393 string ret_val("sizeof(");
10394 u.expr.ti1->append_stringRepr(ret_val);
10395 ret_val += ')';
10396 return ret_val; }
10397 case OPTYPE_ISVALUE: {
10398 string ret_val("isvalue(");
10399 u.expr.ti1->append_stringRepr(ret_val);
10400 ret_val += ')';
10401 return ret_val; }
10402 case OPTYPE_VALUEOF: {
10403 string ret_val("valueof(");
10404 u.expr.ti1->append_stringRepr(ret_val);
10405 ret_val += ')';
10406 return ret_val; }
10407 case OPTYPE_LOG2STR:
10408 return string("log2str(...)");
10409 case OPTYPE_MATCH: {
10410 string ret_val("match(");
10411 ret_val += u.expr.v1->get_stringRepr();
10412 ret_val += ", ";
10413 u.expr.t2->append_stringRepr(ret_val);
10414 ret_val += ')';
10415 return ret_val; }
10416 case OPTYPE_TTCN2STRING: {
10417 string ret_val("ttcn2string(");
10418 u.expr.ti1->append_stringRepr(ret_val);
10419 ret_val += ')';
10420 return ret_val;
10421 }
10422 case OPTYPE_UNDEF_RUNNING:
10423 return u.expr.r1->get_dispname() + ".running";
10424 case OPTYPE_COMP_NULL:
10425 return string("null");
10426 case OPTYPE_COMP_MTC:
10427 return string("mtc");
10428 case OPTYPE_COMP_SYSTEM:
10429 return string("system");
10430 case OPTYPE_COMP_SELF:
10431 return string("self");
10432 case OPTYPE_COMP_CREATE: {
10433 string ret_val(u.expr.r1->get_dispname());
10434 ret_val += ".create";
10435 if (u.expr.v2 || u.expr.v3) {
10436 ret_val += '(';
10437 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10438 else ret_val += '-';
10439 if (u.expr.v3) {
10440 ret_val += ", ";
10441 ret_val += u.expr.v3->get_stringRepr();
10442 }
10443 ret_val += ')';
10444 }
10445 if (u.expr.b4) ret_val += " alive";
10446 return ret_val; }
10447 case OPTYPE_COMP_RUNNING:
10448 return u.expr.v1->get_stringRepr() + ".running";
10449 case OPTYPE_COMP_RUNNING_ANY:
10450 return string("any component.running");
10451 case OPTYPE_COMP_RUNNING_ALL:
10452 return string("all component.running");
10453 case OPTYPE_COMP_ALIVE:
10454 return u.expr.v1->get_stringRepr() + ".alive";
10455 case OPTYPE_COMP_ALIVE_ANY:
10456 return string("any component.alive");
10457 case OPTYPE_COMP_ALIVE_ALL:
10458 return string("all component.alive");
10459 case OPTYPE_TMR_READ:
10460 return u.expr.r1->get_dispname() + ".read";
10461 case OPTYPE_TMR_RUNNING:
10462 return u.expr.r1->get_dispname() + ".running";
10463 case OPTYPE_TMR_RUNNING_ANY:
10464 return string("any timer.running");
10465 case OPTYPE_GETVERDICT:
10466 return string("getverdict");
10467 case OPTYPE_ACTIVATE: {
10468 string ret_val("activate(");
10469 ret_val += u.expr.r1->get_dispname();
10470 ret_val += ')';
10471 return ret_val; }
10472 case OPTYPE_ACTIVATE_REFD: {
10473 string ret_val("activate(derefer(");
10474 ret_val += u.expr.v1->get_stringRepr();
10475 ret_val += ")(";
10476 if (u.expr.state == EXPR_CHECKED) {
10477 if (u.expr.ap_list2) {
10478 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10479 for (size_t i = 0; i < nof_pars; i++) {
10480 if (i > 0) ret_val += ", ";
10481 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10482 }
10483 }
10484 } else {
10485 if (u.expr.t_list2) {
10486 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10487 for (size_t i = 0; i < nof_pars; i++) {
10488 if (i > 0) ret_val += ", ";
10489 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10490 }
10491 }
10492 }
10493 ret_val += "))";
10494 return ret_val; }
10495 case OPTYPE_EXECUTE: {
10496 string ret_val("execute(");
10497 ret_val += u.expr.r1->get_dispname();
10498 if (u.expr.v2) {
10499 ret_val += ", ";
10500 ret_val += u.expr.v2->get_stringRepr();
10501 }
10502 ret_val += ')';
10503 return ret_val; }
10504 case OPTYPE_EXECUTE_REFD: {
10505 string ret_val("execute(derefers(");
10506 ret_val += u.expr.v1->get_stringRepr();
10507 ret_val += ")(";
10508 if (u.expr.state == EXPR_CHECKED) {
10509 if (u.expr.ap_list2) {
10510 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10511 for (size_t i = 0; i < nof_pars; i++) {
10512 if (i > 0) ret_val += ", ";
10513 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10514 }
10515 }
10516 } else {
10517 if (u.expr.t_list2) {
10518 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10519 for (size_t i = 0; i < nof_pars; i++) {
10520 if (i > 0) ret_val += ", ";
10521 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10522 }
10523 }
10524 }
10525 ret_val += ')';
10526 if(u.expr.v3) {
10527 ret_val += ", ";
10528 ret_val += u.expr.v3->get_stringRepr();
10529 }
10530 ret_val += ')';
10531 return ret_val; }
10532 case OPTYPE_PROF_RUNNING:
10533 return string("@profiler.running");
10534 default:
10535 return string("<unsupported optype>");
10536 } // switch u.expr.v_optype
10537 case V_MACRO:
10538 switch (u.macro) {
10539 case MACRO_MODULEID:
10540 return string("%moduleId");
10541 case MACRO_FILENAME:
10542 return string("%fileName");
10543 case MACRO_BFILENAME:
10544 return string("__BFILE__");
10545 case MACRO_FILEPATH:
10546 return string("__FILE__");
10547 case MACRO_LINENUMBER:
10548 return string("%lineNumber");
10549 case MACRO_LINENUMBER_C:
10550 return string("__LINE__");
10551 case MACRO_DEFINITIONID:
10552 return string("%definitionId");
10553 case MACRO_SCOPE:
10554 return string("__SCOPE__");
10555 case MACRO_TESTCASEID:
10556 return string("%testcaseId");
10557 default:
10558 return string("<unknown macro>");
10559 } // switch u.macro
10560 case V_NOTUSED:
10561 return string('-');
10562 case V_FUNCTION:
10563 case V_ALTSTEP:
10564 case V_TESTCASE: {
10565 string ret_val("refers(");
10566 ret_val += u.refd_fat->get_assname();
10567 ret_val += ')';
10568 return ret_val; }
10569 case V_INVOKE: {
10570 string ret_val;
10571 ret_val += u.invoke.v->get_stringRepr();
10572 ret_val += ".apply(";
10573 if (u.invoke.ap_list) {
10574 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10575 for (size_t i = 0; i < nof_pars; i++) {
10576 if (i > 0) ret_val += ", ";
10577 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10578 }
10579 } else if (u.invoke.t_list) {
10580 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10581 for (size_t i = 0; i < nof_pars; i++) {
10582 if (i > 0) ret_val += ", ";
10583 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10584 }
10585 }
10586 ret_val += ')';
10587 return ret_val; }
10588 case V_REFER: {
10589 string ret_val("refers(");
10590 ret_val += u.refered->get_dispname();
10591 ret_val += ')';
10592 return ret_val; }
10593 default:
10594 return string("<unsupported valuetype>");
10595 } // switch valuetype
10596 }
10597
10598 string Value::create_stringRepr_unary(const char *operator_str)
10599 {
10600 string ret_val(operator_str);
10601 ret_val += '(';
10602 ret_val += u.expr.v1->get_stringRepr();
10603 ret_val += ')';
10604 return ret_val;
10605 }
10606
10607 string Value::create_stringRepr_infix(const char *operator_str)
10608 {
10609 string ret_val('(');
10610 ret_val += u.expr.v1->get_stringRepr();
10611 ret_val += ' ';
10612 ret_val += operator_str;
10613 ret_val += ' ';
10614 ret_val += u.expr.v2->get_stringRepr();
10615 ret_val += ')';
10616 return ret_val;
10617 }
10618
10619 string Value::create_stringRepr_predef1(const char *function_name)
10620 {
10621 string ret_val(function_name);
10622 ret_val += '(';
10623 if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
10624 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10625 }
10626 else ret_val += u.expr.v1->get_stringRepr();
10627 ret_val += ')';
10628 return ret_val;
10629 }
10630
10631 string Value::create_stringRepr_predef2(const char *function_name)
10632 {
10633 string ret_val(function_name);
10634 ret_val += '(';
10635 ret_val += u.expr.v1->get_stringRepr();
10636 ret_val += ", ";
10637 ret_val += u.expr.v2->get_stringRepr();
10638 ret_val += ')';
10639 return ret_val;
10640 }
10641
10642 bool Value::operator==(Value& val)
10643 {
10644 Value *left = get_value_refd_last();
10645 Type *left_governor = left->get_my_governor();
10646 if (left_governor) left_governor = left_governor->get_type_refd_last();
10647 Value *right = val.get_value_refd_last();
10648 Type *right_governor = right->get_my_governor();
10649 if (right_governor) right_governor = right_governor->get_type_refd_last();
10650 if (left_governor && right_governor
10651 && !left_governor->is_compatible(right_governor, NULL)
10652 && !right_governor->is_compatible(left_governor, NULL))
10653 FATAL_ERROR("Value::operator==");
10654
10655 // Not-A-Value is not equal to anything (NaN analogy:)
10656 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10657 return false;
10658
10659 switch (left->valuetype) {
10660 case V_NULL:
10661 case V_OMIT:
10662 case V_DEFAULT_NULL:
10663 case V_FAT_NULL:
10664 case V_NOTUSED:
10665 return left->valuetype == right->valuetype;
10666 case V_BOOL:
10667 return right->valuetype == V_BOOL &&
10668 left->get_val_bool() == right->get_val_bool();
10669 case V_INT:
10670 return right->valuetype == V_INT && *left->get_val_Int()
10671 == *right->get_val_Int();
10672 case V_REAL:
10673 return right->valuetype == V_REAL &&
10674 left->get_val_Real() == right->get_val_Real();
10675 case V_CSTR:
10676 switch (right->valuetype) {
10677 case V_CSTR:
10678 return left->get_val_str() == right->get_val_str();
10679 case V_USTR:
10680 return right->get_val_ustr() == left->get_val_str();
10681 case V_ISO2022STR:
10682 return right->get_val_iso2022str() == left->get_val_str();
10683 default:
10684 return false;
10685 }
10686 case V_BSTR:
10687 case V_HSTR:
10688 case V_OSTR:
10689 return left->valuetype == right->valuetype &&
10690 left->get_val_str() == right->get_val_str();
10691 case V_USTR:
10692 switch (right->valuetype) {
10693 case V_CSTR:
10694 return left->get_val_ustr() == right->get_val_str();
10695 case V_USTR:
10696 return left->get_val_ustr() == right->get_val_ustr();
10697 case V_ISO2022STR:
10698 return left->get_val_ustr() == right->get_val_iso2022str();
10699 default:
10700 return false;
10701 }
10702 case V_ISO2022STR:
10703 switch (right->valuetype) {
10704 case V_CSTR:
10705 return left->get_val_iso2022str() == right->get_val_str();
10706 case V_USTR:
10707 // The appropriate operator==() is missing. The operands are swapped,
10708 // but it shouldn't be a problem.
10709 return right->get_val_ustr() == left->get_val_iso2022str();
10710 case V_ISO2022STR:
10711 return left->get_val_iso2022str() == right->get_val_iso2022str();
10712 default:
10713 return false;
10714 }
10715 case V_ENUM:
10716 return right->valuetype == V_ENUM &&
10717 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10718 case V_OID:
10719 case V_ROID:
10720 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10721 vector<string> act, other;
10722 get_oid_comps(act);
10723 val.get_oid_comps(other);
10724 size_t act_size = act.size(), other_size = other.size();
10725 bool ret_val;
10726 if (act_size == other_size) {
10727 ret_val = true;
10728 for (size_t i = 0; i < act_size; i++)
10729 if (*act[i] != *other[i]) {
10730 ret_val = false;
10731 break;
10732 }
10733 } else ret_val = false;
10734 for (size_t i = 0; i < act_size; i++) delete act[i];
10735 act.clear();
10736 for (size_t i = 0; i < other_size; i++) delete other[i];
10737 other.clear();
10738 return ret_val;
10739 } else return false;
10740 case V_CHOICE:
10741 return right->valuetype == V_CHOICE &&
10742 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10743 *(left->get_alt_value()) == *(right->get_alt_value());
10744 case V_SEQ:
10745 case V_SET: {
10746 if (!left_governor) FATAL_ERROR("Value::operator==");
10747 if (left->valuetype != right->valuetype) return false;
10748 size_t nof_comps = left_governor->get_nof_comps();
10749 for (size_t i = 0; i < nof_comps; i++) {
10750 Value *lval = NULL, *rval = NULL;
10751 CompField* cfl = left_governor->get_comp_byIndex(i);
10752 const Identifier& field_name = cfl->get_name();
10753 if (left->has_comp_withName(field_name)) {
10754 lval = left->get_comp_value_byName(field_name);
10755 if (right->has_comp_withName(field_name)) {
10756 rval = right->get_comp_value_byName(field_name);
10757 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10758 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10759 return false;
10760 else if (!(*lval == *rval))
10761 return false;
10762 } else {
10763 if (cfl->has_default()) {
10764 if (!(*lval == *cfl->get_defval()))
10765 return false;
10766 } else {
10767 if (lval->valuetype != V_OMIT)
10768 return false;
10769 }
10770 }
10771 } else {
10772 if(right->has_comp_withName(field_name)) {
10773 rval = right->get_comp_value_byName(field_name);
10774 if(cfl->has_default()) {
10775 if(rval->valuetype==V_OMIT) return false;
10776 else {
10777 lval = cfl->get_defval();
10778 if (!(*lval==*rval)) return false;
10779 }
10780 }
10781 }
10782 }
10783 }
10784 return true; }
10785 case V_SEQOF:
10786 case V_ARRAY: {
10787 if (left->valuetype != right->valuetype) return false;
10788 size_t ncomps = get_nof_comps();
10789 if (ncomps != right->get_nof_comps()) return false;
10790
10791 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
10792 bool found = false;
10793 map<IndexedValue*, void> uncovered;
10794 for (size_t i = 0; i < left->get_nof_comps(); ++i)
10795 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
10796
10797 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
10798 found = false;
10799 for (size_t j = 0; j < uncovered.size(); ++j) {
10800 if (*(uncovered.get_nth_key(j)->get_value()) ==
10801 *(right->get_comp_byIndex(i)) &&
10802 *(uncovered.get_nth_key(j)->get_index()) ==
10803 *(right->get_index_byIndex(i))) {
10804 found = true;
10805 uncovered.erase(uncovered.get_nth_key(j));
10806 break;
10807 }
10808 }
10809 if (!found) break;
10810 }
10811 uncovered.clear();
10812 return found;
10813 } else if (left->is_indexed() || right->is_indexed()) {
10814 Value* indexed_one = 0;
10815 Value* not_indexed_one = 0;
10816
10817 if(left->is_indexed()) { // left is indexed, right is not
10818 indexed_one = left;
10819 not_indexed_one = right;
10820 } else { // right indexed, left is not
10821 indexed_one = right;
10822 not_indexed_one = left;
10823 }
10824
10825 for(size_t i = 0; i < ncomps; ++i) {
10826 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
10827 if(!(ind->valuetype == V_INT &&
10828 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
10829 *(indexed_one->get_comp_byIndex(i))))
10830 { return false; }
10831 }
10832 return true;
10833 } else { // none of them is indexed
10834 for (size_t i = 0; i < ncomps; i++) {
10835 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
10836 return false;
10837 }
10838 return true;
10839 }
10840 }
10841 case V_SETOF: {
10842 if (right->valuetype != V_SETOF) return false;
10843 size_t ncomps = get_nof_comps();
10844 if (ncomps != right->get_nof_comps()) return false;
10845 if (ncomps == 0) return true;
10846 map<size_t, void> uncovered;
10847 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
10848 for (size_t i = 0; i < ncomps; i++) {
10849 Value *left_item = left->get_comp_byIndex(i);
10850 bool pair_found = false;
10851 for (size_t j = 0; j < ncomps - i; j++) {
10852 size_t right_index = uncovered.get_nth_key(j);
10853 if (*left_item == *right->get_comp_byIndex(right_index)) {
10854 uncovered.erase(right_index);
10855 pair_found = true;
10856 break;
10857 }
10858 }
10859 if (!pair_found) {
10860 uncovered.clear();
10861 return false;
10862 }
10863 }
10864 return true; }
10865 case V_VERDICT:
10866 return right->valuetype == V_VERDICT &&
10867 left->get_val_verdict() == right->get_val_verdict();
10868 case V_FUNCTION:
10869 case V_ALTSTEP:
10870 case V_TESTCASE:
10871 return left->valuetype == right->valuetype &&
10872 left->get_refd_assignment() == right->get_refd_assignment();
10873 default:
10874 FATAL_ERROR("Value::operator==");
10875 }
10876 return true;
10877 }
10878
10879 bool Value::operator<(Value& val)
10880 {
10881 Value *left = get_value_refd_last();
10882 Type *left_governor = left->get_my_governor();
10883 if(left_governor) left_governor=left_governor->get_type_refd_last();
10884 Value *right = val.get_value_refd_last();
10885 Type *right_governor = right->get_my_governor();
10886 if(right_governor) right_governor=right_governor->get_type_refd_last();
10887 if (left->get_valuetype() != right->get_valuetype())
10888 FATAL_ERROR("Value::operator<");
10889 switch(valuetype){
10890 case V_INT:
10891 return *left->get_val_Int() < *right->get_val_Int();
10892 case V_REAL:
10893 return (left->get_val_Real() < right->get_val_Real());
10894 case V_ENUM:
10895 if(!left_governor || !right_governor)
10896 FATAL_ERROR("Value::operator<");
10897 if(left_governor!=right_governor)
10898 FATAL_ERROR("Value::operator<");
10899 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
10900 right_governor->get_enum_val_byId(*right->get_val_id()));
10901 default:
10902 FATAL_ERROR("Value::operator<");
10903 }
10904 return true;
10905 }
10906
10907 bool Value::is_string_type(Type::expected_value_t exp_val)
10908 {
10909 switch (get_expr_returntype(exp_val)) {
10910 case Type::T_CSTR:
10911 case Type::T_USTR:
10912 case Type::T_BSTR:
10913 case Type::T_HSTR:
10914 case Type::T_OSTR:
10915 return true;
10916 default:
10917 return false;
10918 }
10919 }
10920
10921 void Value::generate_code_expr(expression_struct *expr)
10922 {
10923 if (has_single_expr()) {
10924 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
10925 } else {
10926 switch (valuetype) {
10927 case V_EXPR:
10928 generate_code_expr_expr(expr);
10929 break;
10930 case V_CHOICE:
10931 case V_SEQOF:
10932 case V_SETOF:
10933 case V_ARRAY:
10934 case V_SEQ:
10935 case V_SET: {
10936 const string& tmp_id = get_temporary_id();
10937 const char *tmp_id_str = tmp_id.c_str();
10938 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
10939 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
10940 set_genname_recursive(tmp_id);
10941 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10942 expr->expr = mputstr(expr->expr, tmp_id_str);
10943 break; }
10944 case V_INT: {
10945 const string& tmp_id = get_temporary_id();
10946 const char *tmp_id_str = tmp_id.c_str();
10947 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
10948 tmp_id_str);
10949 set_genname_recursive(tmp_id);
10950 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10951 expr->expr = mputstr(expr->expr, tmp_id_str);
10952 break; }
10953 case V_REFD: {
10954 if (!get_needs_conversion()) {
10955 u.ref.ref->generate_code_const_ref(expr);
10956 } else {
10957 Type *my_gov = get_expr_governor_last();
10958 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
10959 ->get_field_type(u.ref.ref->get_subrefs(),
10960 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
10961 // Make sure that nothing goes wrong.
10962 if (!my_gov || !refd_gov || my_gov == refd_gov)
10963 FATAL_ERROR("Value::generate_code_expr()");
10964 expression_struct expr_tmp;
10965 Code::init_expr(&expr_tmp);
10966 const string& tmp_id1 = get_temporary_id();
10967 const char *tmp_id_str1 = tmp_id1.c_str();
10968 const string& tmp_id2 = get_temporary_id();
10969 const char *tmp_id_str2 = tmp_id2.c_str();
10970 expr->preamble = mputprintf(expr->preamble,
10971 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
10972 tmp_id_str1);
10973 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
10974 u.ref.ref->generate_code_const_ref(&expr_tmp);
10975 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
10976 expr->preamble = mputprintf(expr->preamble,
10977 "%s %s;\n"
10978 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10979 "and `%s' are not compatible at run-time\");\n",
10980 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
10981 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
10982 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
10983 ->get_typename().c_str(), refd_gov->get_typename().c_str());
10984 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
10985 }
10986 break; }
10987 case V_INVOKE:
10988 generate_code_expr_invoke(expr);
10989 break;
10990 default:
10991 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
10992 }
10993 }
10994 }
10995
10996 void Value::generate_code_expr_mandatory(expression_struct *expr)
10997 {
10998 generate_code_expr(expr);
10999 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11000 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11001 }
11002
11003 bool Value::can_use_increment(Reference *ref) const
11004 {
11005 if (valuetype != V_EXPR) {
11006 return false;
11007 }
11008 switch (u.expr.v_optype) {
11009 case OPTYPE_ADD:
11010 case OPTYPE_SUBTRACT:
11011 break;
11012 default:
11013 return false;
11014 }
11015 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11016 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11017 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11018 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11019 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11020 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11021 return true;
11022 }
11023 return false;
11024 }
11025
11026 char *Value::generate_code_init(char *str, const char *name)
11027 {
11028 if (get_code_generated()) return str;
11029 if (err_descr) {
11030 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11031 }
11032 switch (valuetype) {
11033 case V_NULL:
11034 case V_BOOL:
11035 case V_REAL:
11036 case V_ENUM:
11037 case V_BSTR:
11038 case V_HSTR:
11039 case V_OSTR:
11040 case V_CSTR:
11041 case V_USTR:
11042 case V_ISO2022STR:
11043 case V_OID:
11044 case V_ROID:
11045 case V_VERDICT:
11046 case V_DEFAULT_NULL:
11047 case V_FAT_NULL:
11048 case V_FUNCTION:
11049 case V_ALTSTEP:
11050 case V_TESTCASE:
11051 // These values have a single string equivalent.
11052 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11053 break;
11054 case V_INT:
11055 if (u.val_Int->is_native_fit())
11056 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11057 else
11058 // It's always an INTEGER.
11059 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11060 "}\n", get_single_expr().c_str(), name);
11061 break;
11062 case V_EXPR:
11063 case V_INVOKE: {
11064 expression_struct expr;
11065 Code::init_expr(&expr);
11066 expr.expr = mputprintf(expr.expr, "%s = ", name);
11067 generate_code_expr(&expr);
11068 str = Code::merge_free_expr(str, &expr);
11069 break; }
11070 case V_CHOICE:
11071 str = generate_code_init_choice(str, name);
11072 break;
11073 case V_SEQOF:
11074 case V_SETOF:
11075 if (!is_indexed()) str = generate_code_init_seof(str, name);
11076 else str = generate_code_init_indexed(str, name);
11077 break;
11078 case V_ARRAY:
11079 if (!is_indexed()) str = generate_code_init_array(str, name);
11080 else str = generate_code_init_indexed(str, name);
11081 break;
11082 case V_SEQ:
11083 case V_SET:
11084 str = generate_code_init_se(str, name);
11085 break;
11086 case V_REFD:
11087 str = generate_code_init_refd(str, name);
11088 break;
11089 case V_MACRO:
11090 switch (u.macro) {
11091 case MACRO_TESTCASEID:
11092 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11093 break;
11094 default:
11095 // all others must already be evaluated away
11096 FATAL_ERROR("Value::generate_code_init()");
11097 }
11098 break;
11099 default:
11100 FATAL_ERROR("Value::generate_code_init()");
11101 }
11102 if (err_descr) {
11103 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11104 }
11105 set_code_generated();
11106 return str;
11107 }
11108
11109 char *Value::rearrange_init_code(char *str)
11110 {
11111 switch (valuetype) {
11112 case V_REFD: {
11113 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11114 if (parlist) {
11115 str = parlist->rearrange_init_code(str,
11116 u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen()
11117 == my_scope->get_scope_mod_gen());
11118 }
11119 break; }
11120 case V_INVOKE: {
11121 str = u.invoke.v->rearrange_init_code(str);
11122 bool type_is_local = u.invoke.v->get_expr_governor_last()->get_my_scope()
11123 ->get_scope_mod_gen() == my_scope->get_scope_mod_gen();
11124 str = u.invoke.ap_list->rearrange_init_code(str, type_is_local);
11125 break; }
11126 case V_EXPR:
11127 switch (u.expr.v_optype) {
11128 case OPTYPE_UNARYPLUS:
11129 case OPTYPE_UNARYMINUS:
11130 case OPTYPE_NOT:
11131 case OPTYPE_NOT4B:
11132 case OPTYPE_BIT2HEX:
11133 case OPTYPE_BIT2INT:
11134 case OPTYPE_BIT2OCT:
11135 case OPTYPE_BIT2STR:
11136 case OPTYPE_CHAR2INT:
11137 case OPTYPE_CHAR2OCT:
11138 case OPTYPE_FLOAT2INT:
11139 case OPTYPE_FLOAT2STR:
11140 case OPTYPE_HEX2BIT:
11141 case OPTYPE_HEX2INT:
11142 case OPTYPE_HEX2OCT:
11143 case OPTYPE_HEX2STR:
11144 case OPTYPE_INT2CHAR:
11145 case OPTYPE_INT2FLOAT:
11146 case OPTYPE_INT2STR:
11147 case OPTYPE_INT2UNICHAR:
11148 case OPTYPE_OCT2BIT:
11149 case OPTYPE_OCT2CHAR:
11150 case OPTYPE_OCT2HEX:
11151 case OPTYPE_OCT2INT:
11152 case OPTYPE_OCT2STR:
11153 case OPTYPE_STR2BIT:
11154 case OPTYPE_STR2FLOAT:
11155 case OPTYPE_STR2HEX:
11156 case OPTYPE_STR2INT:
11157 case OPTYPE_STR2OCT:
11158 case OPTYPE_UNICHAR2INT:
11159 case OPTYPE_UNICHAR2CHAR:
11160 case OPTYPE_ENUM2INT:
11161 case OPTYPE_ISCHOSEN_V:
11162 case OPTYPE_GET_STRINGENCODING:
11163 case OPTYPE_REMOVE_BOM:
11164 case OPTYPE_DECODE_BASE64:
11165 str = u.expr.v1->rearrange_init_code(str);
11166 break;
11167 case OPTYPE_DECODE: {
11168 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11169 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11170 bool rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11171 my_scope->get_scope_mod_gen());
11172 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11173
11174 parlist = u.expr.r2->get_parlist();
11175 ass = u.expr.r2->get_refd_assignment();
11176 rearrange = (ass->get_my_scope()->get_scope_mod_gen() ==
11177 my_scope->get_scope_mod_gen());
11178 if (parlist) str = parlist->rearrange_init_code(str, rearrange);
11179 break; }
11180 case OPTYPE_ADD:
11181 case OPTYPE_SUBTRACT:
11182 case OPTYPE_MULTIPLY:
11183 case OPTYPE_DIVIDE:
11184 case OPTYPE_MOD:
11185 case OPTYPE_REM:
11186 case OPTYPE_CONCAT:
11187 case OPTYPE_EQ:
11188 case OPTYPE_LT:
11189 case OPTYPE_GT:
11190 case OPTYPE_NE:
11191 case OPTYPE_GE:
11192 case OPTYPE_LE:
11193 case OPTYPE_AND:
11194 case OPTYPE_OR:
11195 case OPTYPE_XOR:
11196 case OPTYPE_AND4B:
11197 case OPTYPE_OR4B:
11198 case OPTYPE_XOR4B:
11199 case OPTYPE_SHL:
11200 case OPTYPE_SHR:
11201 case OPTYPE_ROTL:
11202 case OPTYPE_ROTR:
11203 case OPTYPE_INT2BIT:
11204 case OPTYPE_INT2HEX:
11205 case OPTYPE_INT2OCT:
11206 //case OPTYPE_DECODE:
11207 str = u.expr.v1->rearrange_init_code(str);
11208 str = u.expr.v2->rearrange_init_code(str);
11209 break;
11210 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11211 case OPTYPE_OCT2UNICHAR:
11212 case OPTYPE_ENCODE_BASE64:
11213 str = u.expr.v1->rearrange_init_code(str);
11214 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str);
11215 break;
11216 case OPTYPE_SUBSTR:
11217 str = u.expr.ti1->rearrange_init_code(str);
11218 str = u.expr.v2->rearrange_init_code(str);
11219 str = u.expr.v3->rearrange_init_code(str);
11220 break;
11221 case OPTYPE_REGEXP:
11222 str = u.expr.ti1->rearrange_init_code(str);
11223 str = u.expr.t2->rearrange_init_code(str);
11224 str = u.expr.v3->rearrange_init_code(str);
11225 break;
11226 case OPTYPE_DECOMP:
11227 str = u.expr.v1->rearrange_init_code(str);
11228 str = u.expr.v2->rearrange_init_code(str);
11229 str = u.expr.v3->rearrange_init_code(str);
11230 break;
11231 case OPTYPE_REPLACE:
11232 str = u.expr.ti1->rearrange_init_code(str);
11233 str = u.expr.v2->rearrange_init_code(str);
11234 str = u.expr.v3->rearrange_init_code(str);
11235 str = u.expr.ti4->rearrange_init_code(str);
11236 break;
11237 case OPTYPE_LENGTHOF:
11238 case OPTYPE_SIZEOF:
11239 case OPTYPE_VALUEOF:
11240 case OPTYPE_ENCODE:
11241 case OPTYPE_ISPRESENT:
11242 case OPTYPE_TTCN2STRING:
11243 str = u.expr.ti1->rearrange_init_code(str);
11244 break;
11245 case OPTYPE_ISCHOSEN_T:
11246 str = u.expr.t1->rearrange_init_code(str);
11247 break;
11248 case OPTYPE_MATCH:
11249 str = u.expr.v1->rearrange_init_code(str);
11250 str = u.expr.t2->rearrange_init_code(str);
11251 break;
11252 default:
11253 // other kinds of expressions cannot appear within templates
11254 break;
11255 }
11256 break;
11257 default:
11258 break;
11259 }
11260 return str;
11261 }
11262
11263 char* Value::generate_code_tmp(char *str, const char *prefix,
11264 size_t& blockcount)
11265 {
11266 char *s2 = memptystr();
11267 char *s1 = generate_code_tmp(NULL, s2);
11268 if (s2[0]) {
11269 if (blockcount == 0) {
11270 str = mputstr(str, "{\n");
11271 blockcount++;
11272 }
11273 str = mputstr(str, s2);
11274 }
11275 Free(s2);
11276 str=mputstr(str, prefix);
11277 str=mputstr(str, s1);
11278 Free(s1);
11279 return str;
11280 }
11281
11282 char *Value::generate_code_tmp(char *str, char*& init)
11283 {
11284 expression_struct expr;
11285 Code::init_expr(&expr);
11286 generate_code_expr_mandatory(&expr);
11287 if (expr.preamble || expr.postamble) {
11288 if (valuetype == V_EXPR &&
11289 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11290 // a temporary variable is already introduced
11291 if (expr.preamble) init = mputstr(init, expr.preamble);
11292 if (expr.postamble) init = mputstr(init, expr.postamble);
11293 str = mputstr(str, expr.expr);
11294 } else {
11295 const string& tmp_id = get_temporary_id();
11296 const char *tmp_id_str = tmp_id.c_str();
11297 init = mputprintf(init, "%s %s;\n"
11298 "{\n",
11299 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11300 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11301 tmp_id_str);
11302 if (expr.preamble) init = mputstr(init, expr.preamble);
11303 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11304 if (expr.postamble) init = mputstr(init, expr.postamble);
11305 init = mputstr(init, "}\n");
11306 str = mputstr(str, tmp_id_str);
11307 }
11308 } else str = mputstr(str, expr.expr);
11309 Code::free_expr(&expr);
11310 return str;
11311 }
11312
11313 void Value::generate_code_log(expression_struct *expr)
11314 {
11315 if (explicit_cast_needed()) {
11316 char *expr_backup = expr->expr;
11317 expr->expr = NULL;
11318 generate_code_expr(expr);
11319 const string& tmp_id = get_temporary_id();
11320 const char *tmp_id_str = tmp_id.c_str();
11321 // We have to create a temporary object, because the parser of GCC
11322 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11323 // constructor call that is, this does not work: type(...).log(); but
11324 // this works: type tmp(...); tmp.log();.
11325 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11326 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11327 expr->expr);
11328 Free(expr->expr);
11329 expr->expr = mputstr(expr_backup, tmp_id_str);
11330 } else {
11331 generate_code_expr(expr);
11332 }
11333 expr->expr = mputstr(expr->expr, ".log()");
11334 }
11335
11336 void Value::generate_code_log_match(expression_struct *expr)
11337 {
11338 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11339 FATAL_ERROR("Value::generate_code_log_match()");
11340 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11341 // compliance the whole code-generation should be checked. Standalone
11342 // constructs like: "A(a[0].f());" should be avoided. The current
11343 // solution for HK38721 uses an additional assignment to overcome the
11344 // issue. The generated code will be slower, but it's needed for old GCC
11345 // versions in specific circumstances.
11346 if (u.expr.t2->needs_temp_ref()) {
11347 char *expr_backup = expr->expr;
11348 expr->expr = NULL;
11349 u.expr.t2->generate_code(expr);
11350 const string& tmp_id = get_temporary_id();
11351 const char *tmp_id_str = tmp_id.c_str();
11352 expr->preamble = mputprintf(expr->preamble,
11353 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11354 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11355 Free(expr->expr);
11356 expr->expr = mputstr(expr_backup, tmp_id_str);
11357 } else {
11358 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11359 // some reason "(A(NS::B)).a(C);" compiles fine.
11360 expr->expr = mputc(expr->expr, '(');
11361 u.expr.t2->generate_code(expr);
11362 expr->expr = mputc(expr->expr, ')');
11363 }
11364 expr->expr = mputstr(expr->expr, ".log_match(");
11365 u.expr.v1->generate_code_expr(expr);
11366 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11367 }
11368
11369 void Value::generate_code_expr_expr(expression_struct *expr)
11370 {
11371 switch (u.expr.v_optype) {
11372 case OPTYPE_RND:
11373 generate_code_expr_rnd(expr, 0);
11374 break;
11375 case OPTYPE_UNARYPLUS:
11376 // same as without the '+' operator
11377 u.expr.v1->generate_code_expr(expr);
11378 break;
11379 case OPTYPE_UNARYMINUS:
11380 generate_code_expr_unary(expr, "-", u.expr.v1);
11381 break;
11382 case OPTYPE_NOT:
11383 generate_code_expr_unary(expr, "!", u.expr.v1);
11384 break;
11385 case OPTYPE_NOT4B:
11386 generate_code_expr_unary(expr, "~", u.expr.v1);
11387 break;
11388 case OPTYPE_BIT2HEX:
11389 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11390 break;
11391 case OPTYPE_BIT2INT:
11392 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11393 break;
11394 case OPTYPE_BIT2OCT:
11395 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11396 break;
11397 case OPTYPE_BIT2STR:
11398 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11399 break;
11400 case OPTYPE_CHAR2INT:
11401 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11402 break;
11403 case OPTYPE_CHAR2OCT:
11404 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11405 break;
11406 case OPTYPE_FLOAT2INT:
11407 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11408 break;
11409 case OPTYPE_FLOAT2STR:
11410 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11411 break;
11412 case OPTYPE_HEX2BIT:
11413 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11414 break;
11415 case OPTYPE_HEX2INT:
11416 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11417 break;
11418 case OPTYPE_HEX2OCT:
11419 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11420 break;
11421 case OPTYPE_HEX2STR:
11422 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11423 break;
11424 case OPTYPE_INT2CHAR:
11425 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11426 break;
11427 case OPTYPE_INT2FLOAT:
11428 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11429 break;
11430 case OPTYPE_INT2STR:
11431 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11432 break;
11433 case OPTYPE_INT2UNICHAR:
11434 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11435 break;
11436 case OPTYPE_OCT2BIT:
11437 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11438 break;
11439 case OPTYPE_OCT2CHAR:
11440 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11441 break;
11442 case OPTYPE_GET_STRINGENCODING:
11443 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11444 break;
11445 case OPTYPE_REMOVE_BOM:
11446 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11447 break;
11448 case OPTYPE_ENCODE_BASE64:
11449 if (u.expr.v2)
11450 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11451 else
11452 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11453 break;
11454 case OPTYPE_DECODE_BASE64:
11455 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11456 break;
11457 case OPTYPE_OCT2UNICHAR:
11458 if (u.expr.v2)
11459 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11460 else
11461 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11462 break;
11463 case OPTYPE_UNICHAR2OCT:
11464 if (u.expr.v2)
11465 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11466 else
11467 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11468 break;
11469 case OPTYPE_OCT2HEX:
11470 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11471 break;
11472 case OPTYPE_OCT2INT:
11473 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11474 break;
11475 case OPTYPE_OCT2STR:
11476 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11477 break;
11478 case OPTYPE_STR2BIT:
11479 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11480 break;
11481 case OPTYPE_STR2FLOAT:
11482 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11483 break;
11484 case OPTYPE_STR2HEX:
11485 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11486 break;
11487 case OPTYPE_STR2INT:
11488 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11489 break;
11490 case OPTYPE_STR2OCT:
11491 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11492 break;
11493 case OPTYPE_UNICHAR2INT:
11494 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11495 break;
11496 case OPTYPE_UNICHAR2CHAR:
11497 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11498 break;
11499 case OPTYPE_ENUM2INT: {
11500 Type* enum_type = u.expr.v1->get_expr_governor_last();
11501 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11502 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11503 enum_type->get_genname_value(my_scope).c_str());
11504 u.expr.v1->generate_code_expr_mandatory(expr);
11505 expr->expr = mputc(expr->expr, ')');
11506 break;}
11507 case OPTYPE_ENCODE:
11508 generate_code_expr_encode(expr);
11509 break;
11510 case OPTYPE_DECODE:
11511 generate_code_expr_decode(expr);
11512 break;
11513 case OPTYPE_RNDWITHVAL:
11514 generate_code_expr_rnd(expr, u.expr.v1);
11515 break;
11516 case OPTYPE_ADD:
11517 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11518 break;
11519 case OPTYPE_SUBTRACT:
11520 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11521 break;
11522 case OPTYPE_MULTIPLY:
11523 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11524 break;
11525 case OPTYPE_DIVIDE:
11526 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11527 break;
11528 case OPTYPE_MOD:
11529 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11530 break;
11531 case OPTYPE_REM:
11532 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11533 break;
11534 case OPTYPE_CONCAT:
11535 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11536 break;
11537 case OPTYPE_EQ:
11538 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11539 break;
11540 case OPTYPE_LT:
11541 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11542 break;
11543 case OPTYPE_GT:
11544 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11545 break;
11546 case OPTYPE_NE:
11547 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11548 break;
11549 case OPTYPE_GE:
11550 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11551 break;
11552 case OPTYPE_LE:
11553 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11554 break;
11555 case OPTYPE_AND:
11556 case OPTYPE_OR:
11557 generate_code_expr_and_or(expr);
11558 break;
11559 case OPTYPE_XOR:
11560 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11561 break;
11562 case OPTYPE_AND4B:
11563 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11564 break;
11565 case OPTYPE_OR4B:
11566 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11567 break;
11568 case OPTYPE_XOR4B:
11569 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11570 break;
11571 case OPTYPE_SHL:
11572 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11573 break;
11574 case OPTYPE_SHR:
11575 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11576 break;
11577 case OPTYPE_ROTL:
11578 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11579 break;
11580 case OPTYPE_ROTR:
11581 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11582 break;
11583 case OPTYPE_INT2BIT:
11584 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11585 break;
11586 case OPTYPE_INT2HEX:
11587 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11588 break;
11589 case OPTYPE_INT2OCT:
11590 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11591 break;
11592 case OPTYPE_SUBSTR:
11593 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11594 else generate_code_expr_substr_replace_compat(expr);
11595 break;
11596 case OPTYPE_REGEXP:
11597 generate_code_expr_regexp(expr);
11598 break;
11599 case OPTYPE_DECOMP:
11600 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11601 break;
11602 case OPTYPE_REPLACE:
11603 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11604 else generate_code_expr_substr_replace_compat(expr);
11605 break;
11606 case OPTYPE_ISCHOSEN: // r1 i2
11607 FATAL_ERROR("Value::generate_code_expr_expr()");
11608 break;
11609 case OPTYPE_ISCHOSEN_V: // v1 i2
11610 u.expr.v1->generate_code_expr_mandatory(expr);
11611 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11612 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11613 u.expr.i2->get_name().c_str());
11614 break;
11615 case OPTYPE_ISCHOSEN_T: // t1 i2
11616 u.expr.t1->generate_code_expr(expr);
11617 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11618 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11619 u.expr.i2->get_name().c_str());
11620 break;
11621 case OPTYPE_ISPRESENT:
11622 case OPTYPE_ISBOUND: {
11623 Template::templatetype_t temp = u.expr.ti1->get_Template()
11624 ->get_templatetype();
11625 if (temp == Template::SPECIFIC_VALUE) {
11626 Value* specific_value = u.expr.ti1->get_Template()
11627 ->get_specific_value();
11628 if (specific_value->get_valuetype() == Value::V_REFD) {
11629 Ttcn::Reference* reference =
11630 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11631 if (reference) {
11632 reference->generate_code_ispresentbound(expr, false,
11633 u.expr.v_optype==OPTYPE_ISBOUND);
11634 break;
11635 }
11636 }
11637 } else if (temp == Template::TEMPLATE_REFD){
11638 Ttcn::Reference* reference =
11639 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11640 ->get_reference());
11641 if (reference) {
11642 reference->generate_code_ispresentbound(expr, true,
11643 u.expr.v_optype==OPTYPE_ISBOUND);
11644 break;
11645 }
11646 }
11647 }
11648 // no break
11649 case OPTYPE_LENGTHOF: // ti1
11650 // fall through, separated later
11651 case OPTYPE_SIZEOF: // ti1
11652 // fall through, separated later
11653 case OPTYPE_ISVALUE: { // ti1
11654 if (u.expr.ti1->is_only_specific_value()) {
11655 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11656 bool cast_needed = t_val->explicit_cast_needed(
11657 u.expr.v_optype != OPTYPE_LENGTHOF);
11658 if(cast_needed) {
11659 // the ambiguous C++ expression is converted to the value class
11660 expr->expr = mputprintf(expr->expr, "%s(",
11661 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11662 }
11663
11664 if (u.expr.v_optype != OPTYPE_LENGTHOF
11665 && u.expr.v_optype != OPTYPE_SIZEOF) {
11666 t_val->generate_code_expr(expr);
11667 } else {
11668 t_val->generate_code_expr_mandatory(expr);
11669 }
11670
11671 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11672 }
11673 else u.expr.ti1->generate_code(expr);
11674
11675 switch (u.expr.v_optype) {
11676 case OPTYPE_ISBOUND:
11677 expr->expr=mputstr(expr->expr, ".is_bound()");
11678 break;
11679 case OPTYPE_ISPRESENT:
11680 expr->expr=mputprintf(expr->expr, ".is_present(%s)",
11681 omit_in_value_list ? "TRUE" : "");
11682 break;
11683 case OPTYPE_SIZEOF:
11684 expr->expr=mputstr(expr->expr, ".size_of()");
11685 break;
11686 case OPTYPE_LENGTHOF:
11687 expr->expr=mputstr(expr->expr, ".lengthof()");
11688 break;
11689 case OPTYPE_ISVALUE:
11690 expr->expr=mputstr(expr->expr, ".is_value()");
11691 break;
11692 default:
11693 FATAL_ERROR("Value::generate_code_expr_expr()");
11694 }
11695 break; }
11696 case OPTYPE_VALUEOF: // ti1
11697 u.expr.ti1->generate_code(expr);
11698 expr->expr = mputstr(expr->expr, ".valueof()");
11699 break;
11700 case OPTYPE_MATCH: // v1 t2
11701 u.expr.t2->generate_code(expr);
11702 expr->expr = mputstr(expr->expr, ".match(");
11703 u.expr.v1->generate_code_expr(expr);
11704 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11705 break;
11706 case OPTYPE_UNDEF_RUNNING:
11707 // it is resolved during semantic check
11708 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11709 break;
11710 case OPTYPE_COMP_NULL: // -
11711 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11712 break;
11713 case OPTYPE_COMP_MTC: // -
11714 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11715 break;
11716 case OPTYPE_COMP_SYSTEM: // -
11717 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11718 break;
11719 case OPTYPE_COMP_SELF: // -
11720 expr->expr=mputstr(expr->expr, "self");
11721 break;
11722 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11723 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11724 u.expr.b4);
11725 break;
11726 case OPTYPE_COMP_RUNNING: // v1
11727 u.expr.v1->generate_code_expr(expr);
11728 if(u.expr.v1->get_valuetype() == V_REFD)
11729 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11730 expr->expr = mputstr(expr->expr, ".running()");
11731 break;
11732 case OPTYPE_COMP_RUNNING_ANY: // -
11733 expr->expr=mputstr(expr->expr,
11734 "TTCN_Runtime::component_running(ANY_COMPREF)");
11735 break;
11736 case OPTYPE_COMP_RUNNING_ALL: // -
11737 expr->expr=mputstr(expr->expr,
11738 "TTCN_Runtime::component_running(ALL_COMPREF)");
11739 break;
11740 case OPTYPE_COMP_ALIVE: // v1
11741 u.expr.v1->generate_code_expr(expr);
11742 if(u.expr.v1->get_valuetype() == V_REFD)
11743 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11744 expr->expr = mputstr(expr->expr, ".alive()");
11745 break;
11746 case OPTYPE_COMP_ALIVE_ANY: // -
11747 expr->expr = mputstr(expr->expr,
11748 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11749 break;
11750 case OPTYPE_COMP_ALIVE_ALL: // -
11751 expr->expr = mputstr(expr->expr,
11752 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11753 break;
11754 case OPTYPE_TMR_READ: // r1
11755 u.expr.r1->generate_code(expr);
11756 expr->expr = mputstr(expr->expr, ".read()");
11757 break;
11758 case OPTYPE_TMR_RUNNING: // r1
11759 u.expr.r1->generate_code(expr);
11760 expr->expr = mputstr(expr->expr, ".running()");
11761 break;
11762 case OPTYPE_TMR_RUNNING_ANY: // -
11763 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11764 break;
11765 case OPTYPE_GETVERDICT: // -
11766 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11767 break;
11768 case OPTYPE_TESTCASENAME: // -
11769 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11770 break;
11771 case OPTYPE_ACTIVATE: // r1
11772 generate_code_expr_activate(expr);
11773 break;
11774 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
11775 generate_code_expr_activate_refd(expr);
11776 break;
11777 case OPTYPE_EXECUTE: // r1 [v2]
11778 generate_code_expr_execute(expr);
11779 break;
11780 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
11781 generate_code_expr_execute_refd(expr);
11782 break;
11783 case OPTYPE_LOG2STR:
11784 u.expr.logargs->generate_code_expr(expr);
11785 break;
11786 case OPTYPE_TTCN2STRING: {
11787 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
11788 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
11789 param_governor = param_governor->get_type_refd_last();
11790 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
11791 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
11792 u.expr.ti1->get_Template()->is_Value()) {
11793 Value* v = u.expr.ti1->get_Template()->get_Value();
11794 delete u.expr.ti1;
11795 u.expr.ti1 = NULL;
11796 bool cast_needed = v->explicit_cast_needed();
11797 if (cast_needed) {
11798 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
11799 }
11800 v->generate_code_expr(expr);
11801 if (cast_needed) {
11802 expr->expr = mputstr(expr->expr, ")");
11803 }
11804 delete v;
11805 } else {
11806 u.expr.ti1->generate_code(expr);
11807 }
11808 expr->expr = mputstr(expr->expr, ")");
11809 } break;
11810 case OPTYPE_PROF_RUNNING:
11811 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
11812 break;
11813 default:
11814 FATAL_ERROR("Value::generate_code_expr_expr()");
11815 }
11816 }
11817
11818 void Value::generate_code_expr_unary(expression_struct *expr,
11819 const char *operator_str, Value *v1)
11820 {
11821 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
11822 v1->generate_code_expr_mandatory(expr);
11823 expr->expr = mputstrn(expr->expr, "))", 2);
11824 }
11825
11826 void Value::generate_code_expr_infix(expression_struct *expr,
11827 const char *operator_str, Value *v1,
11828 Value *v2, bool optional_allowed)
11829 {
11830 if (!get_needs_conversion()) {
11831 expr->expr = mputc(expr->expr, '(');
11832 if (optional_allowed) v1->generate_code_expr(expr);
11833 else v1->generate_code_expr_mandatory(expr);
11834 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
11835 if (optional_allowed) v2->generate_code_expr(expr);
11836 else v2->generate_code_expr_mandatory(expr);
11837 expr->expr = mputc(expr->expr, ')');
11838 } else { // Temporary variable for the converted value.
11839 const string& tmp_id1 = get_temporary_id();
11840 const char *tmp_id_str1 = tmp_id1.c_str();
11841 expression_struct expr_tmp;
11842 Code::init_expr(&expr_tmp);
11843 switch (u.expr.v_optype) {
11844 case OPTYPE_EQ:
11845 case OPTYPE_NE: {
11846 // Always "v1 -> v2".
11847 Type *t1 = v1->get_expr_governor_last();
11848 Type *t2 = v2->get_expr_governor_last();
11849 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
11850 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11851 else v2->generate_code_expr_mandatory(&expr_tmp);
11852 if (expr_tmp.preamble)
11853 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11854 expr->preamble = mputprintf(expr->preamble,
11855 "%s %s;\n"
11856 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11857 "and `%s' are not compatible at run-time\");\n",
11858 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
11859 TypeConv::get_conv_func(t2, t1, get_my_scope()
11860 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
11861 t2->get_typename().c_str(), t1->get_typename().c_str());
11862 Code::free_expr(&expr_tmp);
11863 if (optional_allowed) v1->generate_code_expr(expr);
11864 else v1->generate_code_expr_mandatory(expr);
11865 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
11866 tmp_id_str1);
11867 break; }
11868 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11869 // functions. The governors of all operands must exist at this point.
11870 case OPTYPE_ROTL:
11871 case OPTYPE_ROTR:
11872 case OPTYPE_CONCAT: {
11873 const string& tmp_id2 = get_temporary_id();
11874 const char *tmp_id_str2 = tmp_id2.c_str();
11875 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
11876 Type *my_gov = my_governor->get_type_refd_last();
11877 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
11878 ->get_type_refd_last();
11879 if (!t1_gov || my_gov == t1_gov)
11880 FATAL_ERROR("Value::generate_code_expr_infix()");
11881 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11882 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
11883 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11884 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
11885 else v1->generate_code_expr_mandatory(&expr_tmp);
11886 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
11887 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11888 else v2->generate_code_expr_mandatory(&expr_tmp);
11889 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11890 expr->preamble = mputprintf(expr->preamble,
11891 "%s %s;\n"
11892 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11893 "and `%s' are not compatible at run-time\");\n",
11894 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11895 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
11896 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
11897 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
11898 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11899 break; }
11900 default:
11901 FATAL_ERROR("Value::generate_code_expr_infix()");
11902 break;
11903 }
11904 }
11905 }
11906
11907 void Value::generate_code_expr_and_or(expression_struct *expr)
11908 {
11909 if (u.expr.v2->needs_short_circuit()) {
11910 // introduce a temporary variable to store the result of the operation
11911 const string& tmp_id = get_temporary_id();
11912 const char *tmp_id_str = tmp_id.c_str();
11913 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
11914 expression_struct expr2;
11915 // the left operand must be evaluated anyway
11916 Code::init_expr(&expr2);
11917 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11918 u.expr.v1->generate_code_expr_mandatory(&expr2);
11919 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11920 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
11921 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
11922 // evaluate the right operand only when necessary
11923 // in this case the final result will be the right operand
11924 Code::init_expr(&expr2);
11925 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11926 u.expr.v2->generate_code_expr_mandatory(&expr2);
11927 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11928 // the result is now in the temporary variable
11929 expr->expr = mputstr(expr->expr, tmp_id_str);
11930 } else {
11931 // use the overloaded operator to get better error messages
11932 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
11933 "&&" : "||", u.expr.v1, u.expr.v2, false);
11934 }
11935 }
11936
11937 void Value::generate_code_expr_predef1(expression_struct *expr,
11938 const char *function_name,
11939 Value *v1)
11940 {
11941 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11942 v1->generate_code_expr_mandatory(expr);
11943 expr->expr = mputc(expr->expr, ')');
11944 }
11945
11946 void Value::generate_code_expr_predef2(expression_struct *expr,
11947 const char *function_name,
11948 Value *v1, Value *v2)
11949 {
11950 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11951 v1->generate_code_expr_mandatory(expr);
11952 expr->expr = mputstr(expr->expr, ", ");
11953 v2->generate_code_expr_mandatory(expr);
11954 expr->expr = mputc(expr->expr, ')');
11955 }
11956
11957 void Value::generate_code_expr_predef3(expression_struct *expr,
11958 const char *function_name,
11959 Value *v1, Value *v2, Value *v3)
11960 {
11961 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11962 v1->generate_code_expr_mandatory(expr);
11963 expr->expr = mputstr(expr->expr, ", ");
11964 v2->generate_code_expr_mandatory(expr);
11965 expr->expr = mputstr(expr->expr, ", ");
11966 v3->generate_code_expr_mandatory(expr);
11967 expr->expr = mputc(expr->expr, ')');
11968 }
11969
11970 void Value::generate_code_expr_substr(expression_struct *expr)
11971 {
11972 bool par1_is_str;
11973 Value* v1 = u.expr.ti1->get_specific_value();
11974 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
11975 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
11976 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
11977 if (v1) v1->generate_code_expr_mandatory(expr);
11978 else u.expr.ti1->generate_code(expr);
11979 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
11980 else expr->expr = mputstr(expr->expr, ".substr(");
11981 if (!par1_is_str && u.expr.v2->is_unfoldable())
11982 expr->expr = mputstr(expr->expr, "(int)");
11983 u.expr.v2->generate_code_expr_mandatory(expr);
11984 expr->expr = mputstr(expr->expr, ", ");
11985 if (!par1_is_str && u.expr.v3->is_unfoldable())
11986 expr->expr = mputstr(expr->expr, "(int)");
11987 u.expr.v3->generate_code_expr_mandatory(expr);
11988 expr->expr = mputc(expr->expr, ')');
11989 }
11990
11991 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
11992 {
11993 expression_struct expr_tmp;
11994 Code::init_expr(&expr_tmp);
11995 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
11996 ->get_type_refd_last();
11997 if (!t1 || t1 == my_governor->get_type_refd_last())
11998 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11999 if (u.expr.v_optype == OPTYPE_SUBSTR) {
12000 generate_code_expr_substr(&expr_tmp);
12001 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
12002 generate_code_expr_replace(&expr_tmp);
12003 } else {
12004 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12005 }
12006 // Two temporaries to store the result of substr() or replace() and to
12007 // store the converted value.
12008 const string& tmp_id1 = get_temporary_id();
12009 const char *tmp_id_str1 = tmp_id1.c_str();
12010 const string& tmp_id2 = get_temporary_id();
12011 const char *tmp_id_str2 = tmp_id2.c_str();
12012 if (expr_tmp.preamble)
12013 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12014 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12015 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12016 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12017 if (expr_tmp.postamble)
12018 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12019 Code::free_expr(&expr_tmp);
12020 expr->preamble = mputprintf(expr->preamble,
12021 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12022 "`%s' are not compatible at run-time\");\n",
12023 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12024 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12025 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12026 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12027 }
12028
12029 void Value::generate_code_expr_regexp(expression_struct *expr)
12030 {
12031 Value* v1 = u.expr.ti1->get_specific_value();
12032 Value* v2 = u.expr.t2->get_specific_value();
12033 expr->expr = mputstr(expr->expr, "regexp(");
12034 if (v1) v1->generate_code_expr_mandatory(expr);
12035 else u.expr.ti1->generate_code(expr);
12036 expr->expr = mputstr(expr->expr, ", ");
12037 if (v2) v2->generate_code_expr_mandatory(expr);
12038 else u.expr.t2->generate_code(expr);
12039 expr->expr = mputstr(expr->expr, ", ");
12040 u.expr.v3->generate_code_expr_mandatory(expr);
12041 expr->expr = mputc(expr->expr, ')');
12042 }
12043
12044 void Value::generate_code_expr_replace(expression_struct *expr)
12045 {
12046 Value* v1 = u.expr.ti1->get_specific_value();
12047 Value* v4 = u.expr.ti4->get_specific_value();
12048 bool par1_is_str;
12049 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12050 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12051 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12052 if (v1) v1->generate_code_expr_mandatory(expr);
12053 else u.expr.ti1->generate_code(expr);
12054 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12055 else expr->expr = mputstr(expr->expr, ".replace(");
12056 if (!par1_is_str && u.expr.v2->is_unfoldable())
12057 expr->expr = mputstr(expr->expr, "(int)");
12058 u.expr.v2->generate_code_expr_mandatory(expr);
12059 expr->expr = mputstr(expr->expr, ", ");
12060 if (!par1_is_str && u.expr.v3->is_unfoldable())
12061 expr->expr = mputstr(expr->expr, "(int)");
12062 u.expr.v3->generate_code_expr_mandatory(expr);
12063 expr->expr = mputstr(expr->expr, ", ");
12064 if (v4) {
12065 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12066 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12067 Value* v4_last = v4->get_value_refd_last();
12068 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12069 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12070 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
12071 }
12072 v4->generate_code_expr_mandatory(expr);
12073 }
12074 else u.expr.ti4->generate_code(expr);
12075 expr->expr = mputc(expr->expr, ')');
12076 }
12077
12078 void Value::generate_code_expr_rnd(expression_struct *expr,
12079 Value *v1)
12080 {
12081 if(!v1) // simple random generation
12082 expr->expr = mputstr(expr->expr, "rnd()");
12083 else { // random generation with seeding
12084 expr->expr = mputstr(expr->expr, "rnd(");
12085 v1->generate_code_expr_mandatory(expr);
12086 expr->expr = mputc(expr->expr, ')');
12087 }
12088 }
12089
12090 void Value::generate_code_expr_create(expression_struct *expr,
12091 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12092 {
12093 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12094 // first two arguments: component type
12095 Assignment *t_ass = type->get_refd_assignment();
12096 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12097 FATAL_ERROR("Value::generate_code_expr_create()");
12098 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12099 Type::EXPECTED_DYNAMIC_VALUE);
12100 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12101 comptype = comptype->get_type_refd_last();
12102 expr->expr = comptype->get_CompBody()
12103 ->generate_code_comptype_name(expr->expr);
12104 expr->expr = mputstr(expr->expr, ", ");
12105 // third argument: component name
12106 if (name) {
12107 Value *t_val = name->get_value_refd_last();
12108 if (t_val->valuetype == V_CSTR) {
12109 // the argument is foldable to a string literal
12110 size_t str_len = t_val->u.str.val_str->size();
12111 const char *str_ptr = t_val->u.str.val_str->c_str();
12112 expr->expr = mputc(expr->expr, '"');
12113 for (size_t i = 0; i < str_len; i++)
12114 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12115 expr->expr = mputc(expr->expr, '"');
12116 } else name->generate_code_expr_mandatory(expr);
12117 } else expr->expr = mputstr(expr->expr, "NULL");
12118 expr->expr = mputstr(expr->expr, ", ");
12119 // fourth argument: location
12120 if (location) {
12121 Value *t_val = location->get_value_refd_last();
12122 if (t_val->valuetype == V_CSTR) {
12123 // the argument is foldable to a string literal
12124 size_t str_len = t_val->u.str.val_str->size();
12125 const char *str_ptr = t_val->u.str.val_str->c_str();
12126 expr->expr = mputc(expr->expr, '"');
12127 for (size_t i = 0; i < str_len; i++)
12128 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12129 expr->expr = mputc(expr->expr, '"');
12130 } else location->generate_code_expr_mandatory(expr);
12131 } else expr->expr = mputstr(expr->expr, "NULL");
12132 // fifth argument: alive flag
12133 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12134 }
12135
12136 void Value::generate_code_expr_activate(expression_struct *expr)
12137 {
12138 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12139 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12140 FATAL_ERROR("Value::generate_code_expr_activate()");
12141 expr->expr = mputprintf(expr->expr, "%s(",
12142 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12143 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12144 expr->expr = mputc(expr->expr, ')');
12145 }
12146
12147 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12148 {
12149 Value *v_last = u.expr.v1->get_value_refd_last();
12150 if (v_last->valuetype == V_ALTSTEP) {
12151 // the referred altstep is known
12152 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12153 ->get_genname_from_scope(my_scope, "activate_").c_str());
12154 } else {
12155 // the referred altstep is unknown
12156 u.expr.v1->generate_code_expr_mandatory(expr);
12157 expr->expr = mputstr(expr->expr,".activate(");
12158 }
12159 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12160 expr->expr = mputc(expr->expr, ')');
12161 }
12162
12163 void Value::generate_code_expr_execute(expression_struct *expr)
12164 {
12165 Assignment *testcase = u.expr.r1->get_refd_assignment();
12166 expr->expr = mputprintf(expr->expr, "%s(",
12167 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12168 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12169 if (parlist->get_nof_pars() > 0) {
12170 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12171 0, false);
12172 expr->expr = mputstr(expr->expr, ", ");
12173 }
12174 if (u.expr.v2) {
12175 expr->expr = mputstr(expr->expr, "TRUE, ");
12176 u.expr.v2->generate_code_expr_mandatory(expr);
12177 expr->expr = mputc(expr->expr, ')');
12178 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12179 }
12180
12181 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12182 {
12183 Value *v_last = u.expr.v1->get_value_refd_last();
12184 if (v_last->valuetype == V_TESTCASE) {
12185 // the referred testcase is known
12186 Assignment *testcase = v_last->get_refd_fat();
12187 expr->expr = mputprintf(expr->expr, "%s(",
12188 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12189 u.expr.ap_list2->generate_code_alias(expr,
12190 testcase->get_FormalParList(), 0, false);
12191 } else {
12192 // the referred testcase is unknown
12193 u.expr.v1->generate_code_expr_mandatory(expr);
12194 expr->expr = mputstr(expr->expr,".execute(");
12195 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12196 }
12197 if (u.expr.ap_list2->get_nof_pars() > 0)
12198 expr->expr = mputstr(expr->expr, ", ");
12199 if (u.expr.v3) {
12200 expr->expr = mputstr(expr->expr, "TRUE, ");
12201 u.expr.v3->generate_code_expr_mandatory(expr);
12202 expr->expr = mputc(expr->expr, ')');
12203 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12204 }
12205
12206 void Value::generate_code_expr_invoke(expression_struct *expr)
12207 {
12208 Value *last_v = u.invoke.v->get_value_refd_last();
12209 if (last_v->get_valuetype() == V_FUNCTION) {
12210 // the referred function is known
12211 Assignment *function = last_v->get_refd_fat();
12212 expr->expr = mputprintf(expr->expr, "%s(",
12213 function->get_genname_from_scope(my_scope).c_str());
12214 u.invoke.ap_list->generate_code_alias(expr,
12215 function->get_FormalParList(), function->get_RunsOnType(), false);
12216 } else {
12217 // the referred function is unknown
12218 u.invoke.v->generate_code_expr_mandatory(expr);
12219 expr->expr = mputstr(expr->expr, ".invoke(");
12220 Type* gov_last = last_v->get_expr_governor_last();
12221 u.invoke.ap_list->generate_code_alias(expr, 0,
12222 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12223 }
12224 expr->expr = mputc(expr->expr, ')');
12225 }
12226
12227 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12228 Reference *ref)
12229 {
12230 // if the referenced value points to an optional value field the
12231 // generated code has to be corrected at the end:
12232 // `fieldid()' => `fieldid()()'
12233 Assignment *ass = ref->get_refd_assignment();
12234 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12235 switch (ass->get_asstype()) {
12236 case Assignment::A_CONST:
12237 case Assignment::A_EXT_CONST:
12238 case Assignment::A_MODULEPAR:
12239 case Assignment::A_VAR:
12240 case Assignment::A_FUNCTION_RVAL:
12241 case Assignment::A_EXT_FUNCTION_RVAL:
12242 case Assignment::A_PAR_VAL_IN:
12243 case Assignment::A_PAR_VAL_OUT:
12244 case Assignment::A_PAR_VAL_INOUT:
12245 // only these are mapped to value objects
12246 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12247 expr->expr = mputstr(expr->expr, "()");
12248 break;
12249 default:
12250 break;
12251 }
12252 }
12253
12254 void Value::generate_code_expr_encode(expression_struct *expr)
12255 {
12256 Value* v1 = 0;
12257
12258 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12259 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12260 v1 = templ->get_specific_value();
12261 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12262
12263 expression_struct expr2;
12264 Code::init_expr(&expr2);
12265
12266 bool is_templ = false;
12267 switch (templ->get_templatetype()) {
12268 case Template::SPECIFIC_VALUE:
12269 v1->generate_code_expr_mandatory(&expr2);
12270 break;
12271 default:
12272 u.expr.ti1->generate_code(&expr2);
12273 is_templ = true;
12274 break;
12275 }
12276
12277 if (!gov_last->is_coding_by_function()) {
12278 const string& tmp_id = get_temporary_id();
12279 const string& tmp_buf_id = get_temporary_id();
12280 const string& tmp_ref_id = get_temporary_id();
12281 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12282 tmp_id.c_str());
12283 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12284 tmp_buf_id.c_str());
12285 if (expr2.preamble) { // copy preamble setting up the argument, if any
12286 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12287 expr->preamble = mputc (expr->preamble, '\n');
12288 }
12289 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12290 gov_last->get_genname_typedescriptor(
12291 u.expr.ti1->get_Template()->get_my_scope()
12292 ).c_str(),
12293 tmp_ref_id.c_str(),
12294 expr2.expr);
12295 if (is_templ) // make a value out of the template, if needed
12296 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12297 expr->preamble = mputprintf(expr->preamble,
12298 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12299 tmp_ref_id.c_str(),
12300 gov_last->get_genname_typedescriptor(
12301 u.expr.ti1->get_Template()->get_my_scope()
12302 ).c_str(),
12303 tmp_buf_id.c_str(),
12304 gov_last->get_coding(true).c_str()
12305 );
12306 expr->preamble = mputstr(expr->preamble, ");\n");
12307 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12308 tmp_buf_id.c_str(),
12309 tmp_id.c_str()
12310 );
12311 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12312 if (expr2.postamble)
12313 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12314 } else
12315 expr->expr = mputprintf(expr->expr, "%s(%s)",
12316 gov_last->get_coding(true).c_str(), expr2.expr);
12317 Code::free_expr(&expr2);
12318 }
12319
12320 void Value::generate_code_expr_decode(expression_struct *expr)
12321 {
12322 expression_struct expr1, expr2;
12323 Code::init_expr(&expr1);
12324 Code::init_expr(&expr2);
12325 u.expr.r1->generate_code(&expr1);
12326 u.expr.r2->generate_code(&expr2);
12327
12328 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12329 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12330 get_type_refd_last();
12331
12332 if (expr1.preamble)
12333 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12334 if (expr2.preamble)
12335 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12336
12337 if (!_type->is_coding_by_function()) {
12338 const string& tmp_id = get_temporary_id();
12339 const string& buffer_id = get_temporary_id();
12340 const string& retval_id = get_temporary_id();
12341 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12342 field_is_optional(u.expr.r2->get_subrefs());
12343
12344 expr->preamble = mputprintf(expr->preamble,
12345 "TTCN_Buffer %s(bit2oct(%s));\n"
12346 "INTEGER %s;\n"
12347 "TTCN_EncDec::set_error_behavior("
12348 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12349 "TTCN_EncDec::clear_error();\n",
12350 buffer_id.c_str(),
12351 expr1.expr,
12352 retval_id.c_str()
12353 );
12354 expr->preamble = mputprintf(expr->preamble,
12355 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12356 expr2.expr,
12357 optional ? "()" : "",
12358 _type->get_genname_typedescriptor(
12359 u.expr.r2->get_my_scope()
12360 ).c_str(),
12361 buffer_id.c_str(),
12362 _type->get_coding(false).c_str()
12363 );
12364 expr->preamble = mputprintf(expr->preamble,
12365 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12366 "case TTCN_EncDec::ET_NONE: {\n"
12367 "%s.cut();\n"
12368 "OCTETSTRING %s;\n"
12369 "%s.get_string(%s);\n"
12370 "%s = oct2bit(%s);\n"
12371 "%s = 0;\n"
12372 "}break;\n"
12373 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12374 "case TTCN_EncDec::ET_LEN_ERR:\n"
12375 "%s = 2;\n"
12376 "break;\n"
12377 "default:\n"
12378 "%s = 1;\n"
12379 "}\n"
12380 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12381 "TTCN_EncDec::EB_DEFAULT);\n"
12382 "TTCN_EncDec::clear_error();\n",
12383 buffer_id.c_str(),
12384 tmp_id.c_str(),
12385 buffer_id.c_str(),
12386 tmp_id.c_str(),
12387 expr1.expr,
12388 tmp_id.c_str(),
12389 retval_id.c_str(),
12390 retval_id.c_str(),
12391 retval_id.c_str()
12392 );
12393 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12394 } else
12395 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12396 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12397 if (expr1.postamble)
12398 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12399 if (expr2.postamble)
12400 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12401 Code::free_expr(&expr1);
12402 Code::free_expr(&expr2);
12403 }
12404
12405 char *Value::generate_code_init_choice(char *str, const char *name)
12406 {
12407 const char *alt_name = u.choice.alt_name->get_name().c_str();
12408 // Safe as long as get_name() returns a const string&, not a temporary.
12409 const char *alt_prefix =
12410 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12411 ? "AT_" : "";
12412 if (u.choice.alt_value->needs_temp_ref()) {
12413 const string& tmp_id = get_temporary_id();
12414 const char *tmp_id_str = tmp_id.c_str();
12415 str = mputprintf(str, "{\n"
12416 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12417 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12418 alt_prefix, alt_name);
12419 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12420 str = mputstr(str, "}\n");
12421 } else {
12422 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12423 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12424 Free(embedded_name);
12425 }
12426 return str;
12427 }
12428
12429 char *Value::generate_code_init_seof(char *str, const char *name)
12430 {
12431 size_t nof_vs = u.val_vs->get_nof_vs();
12432 if (nof_vs > 0) {
12433 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12434 const string& embedded_type =
12435 my_governor->get_ofType()->get_genname_value(my_scope);
12436 const char *embedded_type_str = embedded_type.c_str();
12437 for (size_t i = 0; i < nof_vs; i++) {
12438 Value *comp_v = u.val_vs->get_v_byIndex(i);
12439
12440 if (comp_v->valuetype == V_NOTUSED) continue;
12441 else if (comp_v->needs_temp_ref()) {
12442 const string& tmp_id = get_temporary_id();
12443 const char *tmp_id_str = tmp_id.c_str();
12444 str = mputprintf(str, "{\n"
12445 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12446 (unsigned long) i);
12447 str = comp_v->generate_code_init(str, tmp_id_str);
12448 str = mputstr(str, "}\n");
12449 } else {
12450 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12451 str = comp_v->generate_code_init(str, embedded_name);
12452 Free(embedded_name);
12453 }
12454 }
12455 } else {
12456 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12457 }
12458 return str;
12459 }
12460
12461 char *Value::generate_code_init_indexed(char *str, const char *name)
12462 {
12463 size_t nof_ivs = u.val_vs->get_nof_ivs();
12464 if (nof_ivs > 0) {
12465 // Previous values can be truncated. The concept is similar to
12466 // templates.
12467 Type *t_last = my_governor->get_type_refd_last();
12468 const string& oftype_name =
12469 t_last->get_ofType()->get_genname_value(my_scope);
12470 const char *oftype_name_str = oftype_name.c_str();
12471 for (size_t i = 0; i < nof_ivs; i++) {
12472 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12473 const string& tmp_id_1 = get_temporary_id();
12474 str = mputstr(str, "{\n");
12475 Value *index = iv->get_index();
12476 if (index->get_valuetype() != V_INT) {
12477 const string& tmp_id_2 = get_temporary_id();
12478 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12479 str = index->generate_code_init(str, tmp_id_2.c_str());
12480 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12481 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12482 } else {
12483 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12484 tmp_id_1.c_str(), name,
12485 (index->get_val_Int()->t_str()).c_str());
12486 }
12487 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12488 str = mputstr(str, "}\n");
12489 }
12490 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12491 return str;
12492 }
12493
12494 char *Value::generate_code_init_array(char *str, const char *name)
12495 {
12496 size_t nof_vs = u.val_vs->get_nof_vs();
12497 Type *t_last = my_governor->get_type_refd_last();
12498 Int index_offset = t_last->get_dimension()->get_offset();
12499 const string& embedded_type =
12500 t_last->get_ofType()->get_genname_value(my_scope);
12501 const char *embedded_type_str = embedded_type.c_str();
12502 for (size_t i = 0; i < nof_vs; i++) {
12503 Value *comp_v = u.val_vs->get_v_byIndex(i);
12504 if (comp_v->valuetype == V_NOTUSED) continue;
12505 else if (comp_v->needs_temp_ref()) {
12506 const string& tmp_id = get_temporary_id();
12507 const char *tmp_id_str = tmp_id.c_str();
12508 str = mputprintf(str, "{\n"
12509 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12510 Int2string(index_offset + i).c_str());
12511 str = comp_v->generate_code_init(str, tmp_id_str);
12512 str = mputstr(str, "}\n");
12513 } else {
12514 char *embedded_name = mprintf("%s[%s]", name,
12515 Int2string(index_offset + i).c_str());
12516 str = comp_v->generate_code_init(str, embedded_name);
12517 Free(embedded_name);
12518 }
12519 }
12520 return str;
12521 }
12522
12523 char *Value::generate_code_init_se(char *str, const char *name)
12524 {
12525 Type *type = my_governor->get_type_refd_last();
12526 size_t nof_comps = type->get_nof_comps();
12527 if (nof_comps > 0) {
12528 for (size_t i = 0; i < nof_comps; i++) {
12529 CompField *cf = type->get_comp_byIndex(i);
12530 const Identifier& field_id = cf->get_name();
12531 const char *field_name = field_id.get_name().c_str();
12532 Value *field_v;
12533 if (u.val_nvs->has_nv_withName(field_id)) {
12534 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12535 if (field_v->valuetype == V_NOTUSED) continue;
12536 if (field_v->valuetype == V_OMIT) field_v = 0;
12537 } else if (is_asn1()) {
12538 if (cf->has_default()) {
12539 // handle like a referenced value
12540 Value *defval = cf->get_defval();
12541 if (needs_init_precede(defval)) {
12542 str = defval->generate_code_init(str,
12543 defval->get_lhs_name().c_str());
12544 }
12545 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12546 defval->get_genname_own(my_scope).c_str());
12547 continue;
12548 } else {
12549 if (!cf->get_is_optional())
12550 FATAL_ERROR("Value::generate_code_init()");
12551 field_v = 0;
12552 }
12553 } else {
12554 continue;
12555 }
12556 if (field_v) {
12557 // the value is not omit
12558 if (field_v->needs_temp_ref()) {
12559 const string& tmp_id = get_temporary_id();
12560 const char *tmp_id_str = tmp_id.c_str();
12561 str = mputprintf(str, "{\n"
12562 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12563 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12564 field_name);
12565 str = field_v->generate_code_init(str, tmp_id_str);
12566 str = mputstr(str, "}\n");
12567 } else {
12568 char *embedded_name = mprintf("%s.%s()", name,
12569 field_name);
12570 if (cf->get_is_optional() && field_v->is_compound())
12571 embedded_name = mputstr(embedded_name, "()");
12572 str = field_v->generate_code_init(str, embedded_name);
12573 Free(embedded_name);
12574 }
12575 } else {
12576 // the value is omit
12577 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12578 name, field_name);
12579 }
12580 }
12581 } else {
12582 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12583 }
12584 return str;
12585 }
12586
12587 char *Value::generate_code_init_refd(char *str, const char *name)
12588 {
12589 Value *v = get_value_refd_last();
12590 if (v == this) {
12591 // the referred value is not available at compile time
12592 // the code generation is based on the reference
12593 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
12594 str = TypeConv::gen_conv_code_refd(str, name, v);
12595 } else {
12596 expression_struct expr;
12597 Code::init_expr(&expr);
12598 expr.expr = mputprintf(expr.expr, "%s = ", name);
12599 u.ref.ref->generate_code_const_ref(&expr);
12600 str = Code::merge_free_expr(str, &expr);
12601 }
12602 } else {
12603 // the referred value is available at compile time
12604 // the code generation is based on the referred value
12605 if (v->has_single_expr() &&
12606 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
12607 // simple substitution for in-line values within the same module
12608 str = mputprintf(str, "%s = %s;\n", name,
12609 v->get_single_expr().c_str());
12610 } else {
12611 // use a simple reference to reduce code size
12612 if (needs_init_precede(v)) {
12613 // the referred value must be initialized first
12614 if (!v->is_toplevel() && v->needs_temp_ref()) {
12615 // temporary id should be introduced for the lhs
12616 const string& tmp_id = get_temporary_id();
12617 const char *tmp_id_str = tmp_id.c_str();
12618 str = mputprintf(str, "{\n"
12619 "%s& %s = %s;\n",
12620 v->get_my_governor()->get_genname_value(my_scope).c_str(),
12621 tmp_id_str, v->get_lhs_name().c_str());
12622 str = v->generate_code_init(str, tmp_id_str);
12623 str = mputstr(str, "}\n");
12624 } else {
12625 str = v->generate_code_init(str, v->get_lhs_name().c_str());
12626 }
12627 }
12628 str = mputprintf(str, "%s = %s;\n", name,
12629 v->get_genname_own(my_scope).c_str());
12630 }
12631 }
12632 return str;
12633 }
12634
12635 /** This type contains the JSON encoding type of an omitted optional field */
12636 enum omitted_json_value_t {
12637 NOT_OMITTED, // the field is not omitted
12638 OMITTED_ABSENT, // the omitted field is not present in the JSON object
12639 OMITTED_NULL // the omitted field is set to 'null' in the JSON object
12640 };
12641
12642 /** JSON code for omitted optional fields of can be generated in 2 ways:
12643 * - the field is not present in the JSON object or
12644 * - the field is present and its value is 'null'.
12645 * Because of this all record/set values containing omitted fields have 2^N
12646 * possible JSON encodings, where N is the number of omitted fields.
12647 *
12648 * This function helps go through all the possible encodings, by generating
12649 * the next combination from a previous one.
12650 *
12651 * The algorithm is basically adding 1 to a binary number (where OMITTED_ABSENT
12652 * is zero, OMITTED_NULL is one, all NOT_OMITTEDs are ignored and the first bit
12653 * is the least significant bit).
12654 *
12655 * Usage: generate the first combination, where all omitted fields are absent
12656 * (=all zeros), and keep calling this function until the last combination
12657 * (where all omitted fields are 'null', = all ones) is reached.
12658 *
12659 * @return true, if the next combination was successfully generated, or
12660 * false, when called with the last combination */
12661 static bool next_omitted_json_combo(int* omitted_fields, size_t len)
12662 {
12663 for (size_t i = 0; i < len; ++i) {
12664 if (omitted_fields[i] == OMITTED_ABSENT) {
12665 omitted_fields[i] = OMITTED_NULL;
12666 for (size_t j = 0; j < i; ++j) {
12667 if (omitted_fields[j] == OMITTED_NULL) {
12668 omitted_fields[j] = OMITTED_ABSENT;
12669 }
12670 }
12671 return true;
12672 }
12673 }
12674 return false;
12675 }
12676
12677 void Value::generate_json_value(JSON_Tokenizer& json, bool allow_special_float /* = true */)
12678 {
12679 switch (valuetype) {
12680 case V_INT:
12681 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
12682 break;
12683 case V_REAL: {
12684 Real r = get_val_Real();
12685 if (r == REAL_INFINITY) {
12686 if (allow_special_float) {
12687 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
12688 }
12689 }
12690 else if (r == -REAL_INFINITY) {
12691 if (allow_special_float) {
12692 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
12693 }
12694 }
12695 else if (r != r) {
12696 if (allow_special_float) {
12697 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
12698 }
12699 }
12700 else {
12701 // true if decimal representation possible (use %f format)
12702 bool decimal_repr = (r == 0.0)
12703 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
12704 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
12705 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
12706 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
12707 Free(number_str);
12708 }
12709 break; }
12710 case V_BOOL:
12711 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
12712 break;
12713 case V_BSTR:
12714 case V_HSTR:
12715 case V_OSTR:
12716 case V_CSTR: {
12717 char* str = convert_to_json_string(get_val_str().c_str());
12718 json.put_next_token(JSON_TOKEN_STRING, str);
12719 Free(str);
12720 break; }
12721 case V_USTR: {
12722 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
12723 json.put_next_token(JSON_TOKEN_STRING, str);
12724 Free(str);
12725 break; }
12726 case V_VERDICT:
12727 case V_ENUM:
12728 json.put_next_token(JSON_TOKEN_STRING,
12729 (string('\"') + create_stringRepr() + string('\"')).c_str());
12730 break;
12731 case V_SEQOF:
12732 case V_SETOF:
12733 json.put_next_token(JSON_TOKEN_ARRAY_START);
12734 if (!u.val_vs->is_indexed()) {
12735 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
12736 u.val_vs->get_v_byIndex(i)->generate_json_value(json);
12737 }
12738 }
12739 else {
12740 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
12741 // look for the entry with index equal to i
12742 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
12743 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
12744 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json);
12745 break;
12746 }
12747 }
12748 }
12749 }
12750 json.put_next_token(JSON_TOKEN_ARRAY_END);
12751 break;
12752 case V_SEQ:
12753 case V_SET: {
12754 // omitted fields have 2 possible JSON values (the field is absent, or it's
12755 // present with value 'null'), each combination of omitted values must be
12756 // generated
12757 size_t len = get_nof_comps();
12758 int* omitted_fields = new int[len]; // stores one combination
12759 for (size_t i = 0; i < len; ++i) {
12760 if (get_se_comp_byIndex(i)->get_value()->valuetype == V_OMIT) {
12761 // all omitted fields are absent in the first combination
12762 omitted_fields[i] = OMITTED_ABSENT;
12763 }
12764 else {
12765 omitted_fields[i] = NOT_OMITTED;
12766 }
12767 }
12768 do {
12769 // generate the JSON object from the present combination
12770 json.put_next_token(JSON_TOKEN_OBJECT_START);
12771 for (size_t i = 0; i < len; ++i) {
12772 if (omitted_fields[i] == OMITTED_ABSENT) {
12773 // the field is absent, don't insert anything
12774 continue;
12775 }
12776 // use the field's alias, if it has one
12777 const char* alias = NULL;
12778 if (my_governor != NULL) {
12779 JsonAST* field_attrib = my_governor->get_comp_byName(
12780 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
12781 if (field_attrib != NULL) {
12782 alias = field_attrib->alias;
12783 }
12784 }
12785 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
12786 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
12787 if (omitted_fields[i] == OMITTED_NULL) {
12788 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
12789 }
12790 else {
12791 get_se_comp_byIndex(i)->get_value()->generate_json_value(json);
12792 }
12793 }
12794 json.put_next_token(JSON_TOKEN_OBJECT_END);
12795 } // generate the next combination, until all combinations have been processed
12796 while (next_omitted_json_combo(omitted_fields, len));
12797 break; }
12798 case V_CHOICE: {
12799 bool as_value = my_governor != NULL &&
12800 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
12801 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
12802 if (!as_value) {
12803 // no 'as value' coding instruction, insert an object with one field
12804 json.put_next_token(JSON_TOKEN_OBJECT_START);
12805 // use the field's alias, if it has one
12806 const char* alias = NULL;
12807 if (my_governor != NULL) {
12808 JsonAST* field_attrib = my_governor->get_comp_byName(
12809 get_alt_name())->get_type()->get_json_attributes();
12810 if (field_attrib != NULL) {
12811 alias = field_attrib->alias;
12812 }
12813 }
12814 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
12815 get_alt_name().get_ttcnname().c_str());
12816 }
12817 get_alt_value()->generate_json_value(json);
12818 if (!as_value) {
12819 json.put_next_token(JSON_TOKEN_OBJECT_END);
12820 }
12821 break; }
12822 case V_REFD: {
12823 Value* v = get_value_refd_last();
12824 if (this != v) {
12825 v->generate_json_value(json);
12826 return;
12827 }
12828 } // no break
12829 default:
12830 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
12831 }
12832 }
12833
12834 bool Value::explicit_cast_needed(bool forIsValue)
12835 {
12836 Value *v_last = get_value_refd_last();
12837 if (v_last != this) {
12838 // this is a foldable referenced value
12839 // if the reference points to an imported or compound value the code
12840 // generation will be based on the reference so cast is not needed
12841 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
12842 || !v_last->has_single_expr()) return false;
12843 } else if (v_last->valuetype == V_REFD) {
12844 // this is an unfoldable reference (v_last==this)
12845 // explicit cast is needed only for string element references
12846 if (forIsValue) return false;
12847 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
12848 return t_subrefs && t_subrefs->refers_to_string_element();
12849 }
12850 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
12851 Type *t_governor = v_last->my_governor->get_type_refd_last();
12852 switch (t_governor->get_typetype()) {
12853 case Type::T_NULL:
12854 case Type::T_BOOL:
12855 case Type::T_INT:
12856 case Type::T_INT_A:
12857 case Type::T_REAL:
12858 case Type::T_ENUM_A:
12859 case Type::T_ENUM_T:
12860 case Type::T_VERDICT:
12861 case Type::T_COMPONENT:
12862 // these are mapped to built-in C/C++ types
12863 return true;
12864 case Type::T_SEQ_A:
12865 case Type::T_SEQ_T:
12866 case Type::T_SET_A:
12867 case Type::T_SET_T:
12868 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12869 return t_governor->get_nof_comps() == 0;
12870 case Type::T_SEQOF:
12871 case Type::T_SETOF:
12872 // the C++ equivalent of value {} is ambiguous
12873 // tr926
12874 return true;
12875 case Type::T_FUNCTION:
12876 case Type::T_ALTSTEP:
12877 case Type::T_TESTCASE:
12878 return true;
12879 default:
12880 return false;
12881 }
12882 }
12883
12884 bool Value::has_single_expr()
12885 {
12886 if (get_needs_conversion()) return false;
12887 switch (valuetype) {
12888 case V_EXPR:
12889 return has_single_expr_expr();
12890 case V_CHOICE:
12891 case V_ARRAY:
12892 // a union or array value cannot be represented as an in-line expression
12893 return false;
12894 case V_SEQOF:
12895 case V_SETOF:
12896 // only an empty record/set of value can be represented as an in-line
12897 // expression
12898 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
12899 else return u.val_vs->get_nof_ivs() == 0;
12900 case V_SEQ:
12901 case V_SET: {
12902 // only a value for an empty record/set type can be represented as an
12903 // in-line expression
12904 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
12905 Type *type = my_governor->get_type_refd_last();
12906 return type->get_nof_comps() == 0; }
12907 case V_REFD: {
12908 Value *v_last = get_value_refd_last();
12909 // If the above call hit an error and set_valuetype(V_ERROR),
12910 // then u.ref.ref has been freed. Avoid the segfault.
12911 if (valuetype == V_ERROR)
12912 return false;
12913 if (v_last != this && v_last->has_single_expr() &&
12914 v_last->my_scope->get_scope_mod_gen() ==
12915 my_scope->get_scope_mod_gen()) return true;
12916 else return u.ref.ref->has_single_expr(); }
12917 case V_INVOKE:
12918 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
12919 case V_ERROR:
12920 case V_NAMEDINT:
12921 case V_NAMEDBITS:
12922 case V_UNDEF_LOWERID:
12923 case V_UNDEF_BLOCK:
12924 case V_REFER:
12925 // these values cannot occur during code generation
12926 FATAL_ERROR("Value::has_single_expr()");
12927 case V_INT:
12928 return u.val_Int->is_native_fit();
12929 default:
12930 // other value types (literal values) do not need temporary reference
12931 return true;
12932 }
12933 }
12934
12935 string Value::get_single_expr()
12936 {
12937 switch (valuetype) {
12938 case V_NULL:
12939 return string("ASN_NULL_VALUE");
12940 case V_BOOL:
12941 return string(u.val_bool ? "TRUE" : "FALSE");
12942 case V_INT:
12943 if (u.val_Int->is_native_fit()) { // Be sure.
12944 return u.val_Int->t_str();
12945 } else {
12946 // get_single_expr may be called only if has_single_expr() is true.
12947 // The only exception is V_INT, where get_single_expr may be called
12948 // even if is_native_fit (which is used to implement has_single_expr)
12949 // returns false.
12950 string ret_val('"');
12951 ret_val += u.val_Int->t_str();
12952 ret_val += '"';
12953 return ret_val;
12954 }
12955 case V_REAL:
12956 return Real2code(u.val_Real);
12957 case V_ENUM:
12958 return get_single_expr_enum();
12959 case V_BSTR:
12960 return get_my_scope()->get_scope_mod_gen()
12961 ->add_bitstring_literal(*u.str.val_str);
12962 case V_HSTR:
12963 return get_my_scope()->get_scope_mod_gen()
12964 ->add_hexstring_literal(*u.str.val_str);
12965 case V_OSTR:
12966 return get_my_scope()->get_scope_mod_gen()
12967 ->add_octetstring_literal(*u.str.val_str);
12968 case V_CSTR:
12969 return get_my_scope()->get_scope_mod_gen()
12970 ->add_charstring_literal(*u.str.val_str);
12971 case V_USTR:
12972 if (u.ustr.convert_str) {
12973 set_valuetype(V_CSTR);
12974 return get_my_scope()->get_scope_mod_gen()
12975 ->add_charstring_literal(*u.str.val_str);
12976 } else
12977 return get_my_scope()->get_scope_mod_gen()
12978 ->add_ustring_literal(*u.ustr.val_ustr);
12979 case V_ISO2022STR:
12980 return get_single_expr_iso2022str();
12981 case V_OID:
12982 case V_ROID: {
12983 vector<string> comps;
12984 bool is_constant = get_oid_comps(comps);
12985 size_t nof_comps = comps.size();
12986 string oi_str;
12987 for (size_t i = 0; i < nof_comps; i++) {
12988 if (i > 0) oi_str += ", ";
12989 oi_str += *(comps[i]);
12990 }
12991 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
12992 comps.clear();
12993 if (is_constant) {
12994 // the objid only contains constants
12995 // => create a literal and return its name
12996 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
12997 }
12998 // the objid contains at least one variable
12999 // => append the number of components before the component values in the string and return it
13000 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
13001 case V_SEQOF:
13002 case V_SETOF:
13003 if (u.val_vs->get_nof_vs() > 0)
13004 FATAL_ERROR("Value::get_single_expr()");
13005 return string("NULL_VALUE");
13006 case V_SEQ:
13007 case V_SET:
13008 if (u.val_nvs->get_nof_nvs() > 0)
13009 FATAL_ERROR("Value::get_single_expr()");
13010 return string("NULL_VALUE");
13011 case V_REFD: {
13012 Value *v_last = get_value_refd_last();
13013 if (v_last != this && v_last->has_single_expr() &&
13014 v_last->my_scope->get_scope_mod_gen() ==
13015 my_scope->get_scope_mod_gen()) {
13016 // the reference points to another single value in the same module
13017 return v_last->get_single_expr();
13018 } else {
13019 // convert the reference to a single expression
13020 expression_struct expr;
13021 Code::init_expr(&expr);
13022 u.ref.ref->generate_code_const_ref(&expr);
13023 if (expr.preamble || expr.postamble)
13024 FATAL_ERROR("Value::get_single_expr()");
13025 string ret_val(expr.expr);
13026 Code::free_expr(&expr);
13027 return ret_val;
13028 } }
13029 case V_OMIT:
13030 return string("OMIT_VALUE");
13031 case V_VERDICT:
13032 switch (u.verdict) {
13033 case Verdict_NONE:
13034 return string("NONE");
13035 case Verdict_PASS:
13036 return string("PASS");
13037 case Verdict_INCONC:
13038 return string("INCONC");
13039 case Verdict_FAIL:
13040 return string("FAIL");
13041 case Verdict_ERROR:
13042 return string("ERROR");
13043 default:
13044 FATAL_ERROR("Value::get_single_expr()");
13045 return string();
13046 }
13047 case V_DEFAULT_NULL:
13048 return string("NULL_COMPREF");
13049 case V_FAT_NULL: {
13050 string ret_val('(');
13051 ret_val += my_governor->get_genname_value(my_scope);
13052 ret_val += "::function_pointer)Module_List::get_fat_null()";
13053 return ret_val; }
13054 case V_EXPR:
13055 case V_INVOKE: {
13056 expression_struct expr;
13057 Code::init_expr(&expr);
13058 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13059 else generate_code_expr_invoke(&expr);
13060 if (expr.preamble || expr.postamble)
13061 FATAL_ERROR("Value::get_single_expr()");
13062 string ret_val(expr.expr);
13063 Code::free_expr(&expr);
13064 return ret_val; }
13065 case V_MACRO:
13066 switch (u.macro) {
13067 case MACRO_TESTCASEID:
13068 return string("TTCN_Runtime::get_testcase_id_macro()");
13069 default:
13070 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13071 return string();
13072 }
13073 case V_FUNCTION:
13074 case V_ALTSTEP:
13075 case V_TESTCASE:
13076 return get_single_expr_fat();
13077 default:
13078 FATAL_ERROR("Value::get_single_expr()");
13079 return string();
13080 }
13081 }
13082
13083 bool Value::has_single_expr_expr()
13084 {
13085 switch (u.expr.v_optype) {
13086 case OPTYPE_RND: // -
13087 case OPTYPE_COMP_NULL:
13088 case OPTYPE_COMP_MTC:
13089 case OPTYPE_COMP_SYSTEM:
13090 case OPTYPE_COMP_SELF:
13091 case OPTYPE_COMP_RUNNING_ANY:
13092 case OPTYPE_COMP_RUNNING_ALL:
13093 case OPTYPE_COMP_ALIVE_ANY:
13094 case OPTYPE_COMP_ALIVE_ALL:
13095 case OPTYPE_TMR_RUNNING_ANY:
13096 case OPTYPE_GETVERDICT:
13097 case OPTYPE_TESTCASENAME:
13098 case OPTYPE_PROF_RUNNING:
13099 return true;
13100 case OPTYPE_ENCODE:
13101 case OPTYPE_DECODE:
13102 case OPTYPE_ISBOUND:
13103 case OPTYPE_ISPRESENT:
13104 case OPTYPE_TTCN2STRING:
13105 return false;
13106 case OPTYPE_UNARYPLUS: // v1
13107 case OPTYPE_UNARYMINUS:
13108 case OPTYPE_NOT:
13109 case OPTYPE_NOT4B:
13110 case OPTYPE_BIT2HEX:
13111 case OPTYPE_BIT2INT:
13112 case OPTYPE_BIT2OCT:
13113 case OPTYPE_BIT2STR:
13114 case OPTYPE_CHAR2INT:
13115 case OPTYPE_CHAR2OCT:
13116 case OPTYPE_FLOAT2INT:
13117 case OPTYPE_FLOAT2STR:
13118 case OPTYPE_HEX2BIT:
13119 case OPTYPE_HEX2INT:
13120 case OPTYPE_HEX2OCT:
13121 case OPTYPE_HEX2STR:
13122 case OPTYPE_INT2CHAR:
13123 case OPTYPE_INT2FLOAT:
13124 case OPTYPE_INT2STR:
13125 case OPTYPE_INT2UNICHAR:
13126 case OPTYPE_OCT2BIT:
13127 case OPTYPE_OCT2CHAR:
13128 case OPTYPE_OCT2HEX:
13129 case OPTYPE_OCT2INT:
13130 case OPTYPE_OCT2STR:
13131 case OPTYPE_STR2BIT:
13132 case OPTYPE_STR2FLOAT:
13133 case OPTYPE_STR2HEX:
13134 case OPTYPE_STR2INT:
13135 case OPTYPE_STR2OCT:
13136 case OPTYPE_UNICHAR2INT:
13137 case OPTYPE_UNICHAR2CHAR:
13138 case OPTYPE_ENUM2INT:
13139 case OPTYPE_RNDWITHVAL:
13140 case OPTYPE_ISCHOSEN_V: // v1 i2
13141 case OPTYPE_COMP_RUNNING:
13142 case OPTYPE_COMP_ALIVE:
13143 case OPTYPE_GET_STRINGENCODING:
13144 case OPTYPE_REMOVE_BOM:
13145 case OPTYPE_DECODE_BASE64:
13146 return u.expr.v1->has_single_expr();
13147 case OPTYPE_ISCHOSEN_T: // t1 i2
13148 return u.expr.t1->has_single_expr();
13149 case OPTYPE_ADD: // v1 v2
13150 case OPTYPE_SUBTRACT:
13151 case OPTYPE_MULTIPLY:
13152 case OPTYPE_DIVIDE:
13153 case OPTYPE_MOD:
13154 case OPTYPE_REM:
13155 case OPTYPE_CONCAT:
13156 case OPTYPE_EQ:
13157 case OPTYPE_LT:
13158 case OPTYPE_GT:
13159 case OPTYPE_NE:
13160 case OPTYPE_GE:
13161 case OPTYPE_LE:
13162 case OPTYPE_XOR:
13163 case OPTYPE_AND4B:
13164 case OPTYPE_OR4B:
13165 case OPTYPE_XOR4B:
13166 case OPTYPE_SHL:
13167 case OPTYPE_SHR:
13168 case OPTYPE_ROTL:
13169 case OPTYPE_ROTR:
13170 case OPTYPE_INT2BIT:
13171 case OPTYPE_INT2HEX:
13172 case OPTYPE_INT2OCT:
13173 return u.expr.v1->has_single_expr() &&
13174 u.expr.v2->has_single_expr();
13175 case OPTYPE_UNICHAR2OCT:
13176 case OPTYPE_OCT2UNICHAR:
13177 case OPTYPE_ENCODE_BASE64:
13178 return u.expr.v1->has_single_expr() &&
13179 (!u.expr.v2 || u.expr.v2->has_single_expr());
13180 case OPTYPE_AND:
13181 case OPTYPE_OR:
13182 return u.expr.v1->has_single_expr() &&
13183 u.expr.v2->has_single_expr() &&
13184 !u.expr.v2->needs_short_circuit();
13185 case OPTYPE_SUBSTR:
13186 return u.expr.ti1->has_single_expr() &&
13187 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13188 case OPTYPE_REGEXP:
13189 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13190 u.expr.v3->has_single_expr();
13191 case OPTYPE_DECOMP: // v1 v2 v3
13192 return u.expr.v1->has_single_expr() &&
13193 u.expr.v2->has_single_expr() &&
13194 u.expr.v3->has_single_expr();
13195 case OPTYPE_REPLACE:
13196 return u.expr.ti1->has_single_expr() &&
13197 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13198 u.expr.ti4->has_single_expr();
13199 case OPTYPE_ISVALUE: // ti1
13200 case OPTYPE_LENGTHOF: // ti1
13201 case OPTYPE_SIZEOF: // ti1
13202 case OPTYPE_VALUEOF: // ti1
13203 return u.expr.ti1->has_single_expr();
13204 case OPTYPE_LOG2STR:
13205 return u.expr.logargs->has_single_expr();
13206 case OPTYPE_MATCH: // v1 t2
13207 return u.expr.v1->has_single_expr() &&
13208 u.expr.t2->has_single_expr();
13209 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13210 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13211 (!u.expr.v3 || u.expr.v3->has_single_expr());
13212 case OPTYPE_TMR_READ: // r1
13213 case OPTYPE_TMR_RUNNING:
13214 case OPTYPE_ACTIVATE:
13215 return u.expr.r1->has_single_expr();
13216 case OPTYPE_EXECUTE: // r1 [v2]
13217 return u.expr.r1->has_single_expr() &&
13218 (!u.expr.v2 || u.expr.v2->has_single_expr());
13219 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13220 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13221 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13222 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13223 (!u.expr.v3 || u.expr.v3->has_single_expr());
13224 default:
13225 FATAL_ERROR("Value::has_single_expr_expr()");
13226 } // switch
13227 }
13228
13229 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13230 {
13231 if (!v->has_single_expr()) return false;
13232 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13233 if (!ap_list->get_par(i)->has_single_expr()) return false;
13234 return true;
13235 }
13236
13237 string Value::get_single_expr_enum()
13238 {
13239 string ret_val(my_governor->get_genname_value(my_scope));
13240 ret_val += "::";
13241 ret_val += u.val_id->get_name();
13242 return ret_val;
13243 }
13244
13245 string Value::get_single_expr_iso2022str()
13246 {
13247 string ret_val;
13248 Type *type = get_my_governor()->get_type_refd_last();
13249 switch (type->get_typetype()) {
13250 case Type::T_TELETEXSTRING:
13251 ret_val += "TTCN_ISO2022_2_TeletexString";
13252 break;
13253 case Type::T_VIDEOTEXSTRING:
13254 ret_val += "TTCN_ISO2022_2_VideotexString";
13255 break;
13256 case Type::T_GRAPHICSTRING:
13257 case Type::T_OBJECTDESCRIPTOR:
13258 ret_val += "TTCN_ISO2022_2_GraphicString";
13259 break;
13260 case Type::T_GENERALSTRING:
13261 ret_val += "TTCN_ISO2022_2_GeneralString";
13262 break;
13263 default:
13264 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13265 } // switch
13266 ret_val += '(';
13267 string *ostr = char2oct(*u.str.val_str);
13268 ret_val += get_my_scope()->get_scope_mod_gen()
13269 ->add_octetstring_literal(*ostr);
13270 delete ostr;
13271 ret_val += ')';
13272 return ret_val;
13273 }
13274
13275 string Value::get_single_expr_fat()
13276 {
13277 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13278 // the ampersand operator is not really necessary to obtain the function
13279 // pointer, but some older versions of GCC cannot instantiate the
13280 // appropriate operator=() member of class OPTIONAL when necessary
13281 // if only the function name is given
13282 string ret_val('&');
13283 switch (valuetype) {
13284 case V_FUNCTION:
13285 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13286 break;
13287 case V_ALTSTEP:
13288 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13289 ret_val += "_instance";
13290 break;
13291 case V_TESTCASE:
13292 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13293 break;
13294 default:
13295 FATAL_ERROR("Value::get_single_expr_fat()");
13296 }
13297 return ret_val;
13298 }
13299
13300 bool Value::is_compound()
13301 {
13302 switch (valuetype) {
13303 case V_CHOICE:
13304 case V_SEQOF:
13305 case V_SETOF:
13306 case V_ARRAY:
13307 case V_SEQ:
13308 case V_SET:
13309 return true;
13310 default:
13311 return false;
13312 }
13313 }
13314
13315 bool Value::needs_temp_ref()
13316 {
13317 switch (valuetype) {
13318 case V_SEQOF:
13319 case V_SETOF:
13320 if (!is_indexed()) {
13321 // Temporary reference is needed if the value has at least one real
13322 // element (i.e. it is not empty or contains only not used symbols).
13323 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13324 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13325 }
13326 } else {
13327 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13328 if (u.val_vs->get_iv_byIndex(i)->get_value()
13329 ->valuetype != V_NOTUSED)
13330 return true;
13331 }
13332 }
13333 return false;
13334 case V_ARRAY: {
13335 size_t nof_real_vs = 0;
13336 if (!is_indexed()) {
13337 // Temporary reference is needed if the array value has at least two
13338 // real elements (excluding not used symbols).
13339 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13340 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13341 nof_real_vs++;
13342 if (nof_real_vs > 1) return true;
13343 }
13344 }
13345 } else {
13346 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13347 if (u.val_vs->get_iv_byIndex(i)->get_value()
13348 ->valuetype != V_NOTUSED) {
13349 nof_real_vs++;
13350 if (nof_real_vs > 1) return true;
13351 }
13352 }
13353 }
13354 return false; }
13355 case V_SEQ:
13356 case V_SET:
13357 if (is_asn1()) {
13358 // it depends on the type since fields with omit or default value
13359 // may not be present
13360 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13361 } else {
13362 // incomplete values are allowed in TTCN-3
13363 // we should check the number of value components
13364 return u.val_nvs->get_nof_nvs() > 1;
13365 }
13366 case V_ERROR:
13367 case V_NAMEDINT:
13368 case V_NAMEDBITS:
13369 case V_UNDEF_LOWERID:
13370 case V_UNDEF_BLOCK:
13371 case V_TTCN3_NULL:
13372 // these values cannot occur during code generation
13373 FATAL_ERROR("Value::needs_temp_ref()");
13374 case V_INT:
13375 return !u.val_Int->is_native();
13376 default:
13377 // other value types (literal values) do not need temporary reference
13378 return false;
13379 }
13380 }
13381
13382 bool Value::needs_short_circuit()
13383 {
13384 switch (valuetype) {
13385 case V_BOOL:
13386 return false;
13387 case V_REFD:
13388 // examined below
13389 break;
13390 case V_EXPR:
13391 case V_INVOKE:
13392 // sub-expressions should be evaluated only if necessary
13393 return true;
13394 default:
13395 FATAL_ERROR("Value::needs_short_circuit()");
13396 }
13397 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13398 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13399 switch (t_ass->get_asstype()) {
13400 case Assignment::A_FUNCTION_RVAL:
13401 case Assignment::A_EXT_FUNCTION_RVAL:
13402 // avoid unnecessary call of a function
13403 return true;
13404 case Assignment::A_CONST:
13405 case Assignment::A_EXT_CONST:
13406 case Assignment::A_MODULEPAR:
13407 case Assignment::A_VAR:
13408 case Assignment::A_PAR_VAL_IN:
13409 case Assignment::A_PAR_VAL_OUT:
13410 case Assignment::A_PAR_VAL_INOUT:
13411 // depends on field/array sub-references, which is examined below
13412 break;
13413 default:
13414 FATAL_ERROR("Value::needs_short_circuit()");
13415 }
13416 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13417 if (t_subrefs) {
13418 // the evaluation of the reference does not have side effects
13419 // (i.e. false shall be returned) only if all sub-references point to
13420 // mandatory fields of record/set types, and neither sub-reference points
13421 // to a field of a union type
13422 Type *t_type = t_ass->get_Type();
13423 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13424 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13425 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13426 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13427 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13428 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13429 t_cf->get_is_optional()) return true;
13430 t_type = t_cf->get_type();
13431 } else return true;
13432 }
13433 }
13434 return false;
13435 }
13436
13437 void Value::dump(unsigned level) const
13438 {
13439 switch (valuetype) {
13440 case V_ERROR:
13441 case V_NULL:
13442 case V_BOOL:
13443 case V_INT:
13444 case V_NAMEDINT:
13445 case V_NAMEDBITS:
13446 case V_REAL:
13447 case V_ENUM:
13448 case V_BSTR:
13449 case V_HSTR:
13450 case V_OSTR:
13451 case V_CSTR:
13452 case V_ISO2022STR:
13453 case V_OID:
13454 case V_ROID:
13455 case V_CHOICE:
13456 case V_SEQOF:
13457 case V_SETOF:
13458 case V_ARRAY:
13459 case V_SEQ:
13460 case V_SET:
13461 case V_OMIT:
13462 case V_VERDICT:
13463 case V_DEFAULT_NULL:
13464 case V_FAT_NULL:
13465 case V_EXPR:
13466 case V_MACRO:
13467 case V_NOTUSED:
13468 case V_FUNCTION:
13469 case V_ALTSTEP:
13470 case V_TESTCASE:
13471 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13472 break;
13473 case V_REFD:
13474 case V_REFER:
13475 DEBUG(level, "Value: reference");
13476 u.ref.ref->dump(level + 1);
13477 break;
13478 case V_UNDEF_LOWERID:
13479 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13480 break;
13481 case V_UNDEF_BLOCK:
13482 DEBUG(level, "Value: {block}");
13483 break;
13484 case V_TTCN3_NULL:
13485 DEBUG(level, "Value: null");
13486 break;
13487 case V_INVOKE:
13488 DEBUG(level, "Value: invoke");
13489 u.invoke.v->dump(level + 1);
13490 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13491 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13492 break;
13493 default:
13494 DEBUG(level, "Value: unknown type: %d", valuetype);
13495 } // switch
13496 }
13497
13498 void Value::add_string_element(size_t index, Value *v_element,
13499 map<size_t, Value>*& string_elements)
13500 {
13501 v_element->set_my_scope(get_my_scope());
13502 v_element->set_my_governor(get_my_governor());
13503 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13504 v_element->set_location(*this);
13505 if (!string_elements) string_elements = new map<size_t, Value>;
13506 string_elements->add(index, v_element);
13507 }
13508
13509 ///////////////////////////////////////////////////////////////////////////////
13510 // class LazyParamData
13511
13512 int LazyParamData::depth = 0;
13513 bool LazyParamData::used_as_lvalue = false;
13514 vector<string>* LazyParamData::type_vec = NULL;
13515 vector<string>* LazyParamData::refd_vec = NULL;
13516
13517 void LazyParamData::init(bool p_used_as_lvalue) {
13518 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13519 if (depth==0) {
13520 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13521 used_as_lvalue = p_used_as_lvalue;
13522 type_vec = new vector<string>;
13523 refd_vec = new vector<string>;
13524 }
13525 depth++;
13526 }
13527
13528 void LazyParamData::clean() {
13529 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13530 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13531 if (depth==1) {
13532 // type_vec
13533 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13534 type_vec->clear();
13535 delete type_vec;
13536 type_vec = NULL;
13537 // refd_vec
13538 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13539 refd_vec->clear();
13540 delete refd_vec;
13541 refd_vec = NULL;
13542 }
13543 depth--;
13544 }
13545
13546 bool LazyParamData::in_lazy() {
13547 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13548 return depth>0;
13549 }
13550
13551 // returns a temporary id instead of the C++ reference to a definition
13552 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13553 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13554 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13555 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13556 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13557 // store the type of the assignment
13558 string* type_str = new string;
13559 switch (ass->get_asstype()) {
13560 case Assignment::A_MODULEPAR_TEMP:
13561 case Assignment::A_TEMPLATE:
13562 case Assignment::A_VAR_TEMPLATE:
13563 case Assignment::A_PAR_TEMPL_IN:
13564 case Assignment::A_PAR_TEMPL_OUT:
13565 case Assignment::A_PAR_TEMPL_INOUT:
13566 *type_str = ass->get_Type()->get_genname_template(scope);
13567 break;
13568 default:
13569 *type_str = ass->get_Type()->get_genname_value(scope);
13570 }
13571 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13572 bool refd_ass_is_lazy_fpar = false;
13573 switch (ass->get_asstype()) {
13574 case Assignment::A_PAR_VAL:
13575 case Assignment::A_PAR_VAL_IN:
13576 case Assignment::A_PAR_TEMPL_IN:
13577 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13578 if (refd_ass_is_lazy_fpar) {
13579 *type_str = string("Lazy_Param<") + *type_str + string(">");
13580 }
13581 break;
13582 default:
13583 break;
13584 }
13585 // add the "const" part if the referenced assignment is a constant thing
13586 if (!refd_ass_is_lazy_fpar) {
13587 switch (ass->get_asstype()) {
13588 case Assignment::A_CONST:
13589 case Assignment::A_OC:
13590 case Assignment::A_OBJECT:
13591 case Assignment::A_OS:
13592 case Assignment::A_VS:
13593 case Assignment::A_EXT_CONST:
13594 case Assignment::A_MODULEPAR:
13595 case Assignment::A_MODULEPAR_TEMP:
13596 case Assignment::A_TEMPLATE:
13597 case Assignment::A_PAR_VAL:
13598 case Assignment::A_PAR_VAL_IN:
13599 case Assignment::A_PAR_TEMPL_IN:
13600 *type_str = string("const ") + *type_str;
13601 break;
13602 default:
13603 // nothing to do
13604 break;
13605 }
13606 }
13607 //
13608 type_vec->add(type_str);
13609 // store the C++ reference string
13610 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
13611 if (refd_ass_is_lazy_fpar) {
13612 Type* refd_ass_type = ass->get_Type();
13613 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);
13614 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13615 } else {
13616 return get_member_name(refd_vec->size()-1);
13617 }
13618 }
13619
13620 string LazyParamData::get_member_name(size_t idx) {
13621 return string("lpm_") + Int2string(idx);
13622 }
13623
13624 string LazyParamData::get_constr_param_name(size_t idx) {
13625 return string("lpp_") + Int2string(idx);
13626 }
13627
13628 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
13629 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13630 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
13631 const string& tmp_id = val->get_temporary_id();
13632 const char *tmp_id_str = tmp_id.c_str();
13633 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13634 val->get_my_governor()->get_genname_value(my_scope).c_str(),
13635 tmp_id_str);
13636 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13637 tmp_id_str, val);
13638 expr->expr = mputstr(expr->expr, tmp_id_str);
13639 } else {
13640 val->generate_code_expr(expr);
13641 }
13642 }
13643
13644 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
13645 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13646 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
13647 const string& tmp_id = temp->get_Template()->get_temporary_id();
13648 const char *tmp_id_str = tmp_id.c_str();
13649 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13650 temp->get_Template()->get_my_governor()
13651 ->get_genname_template(my_scope).c_str(), tmp_id_str);
13652 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13653 tmp_id_str, temp->get_Template());
13654 // Not incorporated into gen_conv_code() yet.
13655 if (gen_restriction_check != TR_NONE)
13656 expr->preamble = Template::generate_restriction_check_code(
13657 expr->preamble, tmp_id_str, gen_restriction_check);
13658 expr->expr = mputstr(expr->expr, tmp_id_str);
13659 } else temp->generate_code(expr, gen_restriction_check);
13660 }
13661
13662 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
13663 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13664 if (depth>1) {
13665 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13666 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13667 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13668 expression_struct value_expr;
13669 Code::init_expr(&value_expr);
13670 generate_code_for_value(&value_expr, value, scope);
13671 // the id of the instance of Lazy_Param which will be used as the actual parameter
13672 const string& lazy_param_id = value->get_temporary_id();
13673 if (value_expr.preamble) {
13674 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
13675 }
13676 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13677 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13678 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
13679 Code::free_expr(&value_expr);
13680 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13681 return;
13682 }
13683 // only if the formal parameter is *not* used as lvalue
13684 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
13685 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
13686 if (refd_ass) {
13687 bool refd_ass_is_lazy_fpar = false;
13688 switch (refd_ass->get_asstype()) {
13689 case Assignment::A_PAR_VAL:
13690 case Assignment::A_PAR_VAL_IN:
13691 case Assignment::A_PAR_TEMPL_IN:
13692 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13693 break;
13694 default:
13695 break;
13696 }
13697 if (refd_ass_is_lazy_fpar) {
13698 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13699 return;
13700 }
13701 }
13702 }
13703 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13704 expression_struct value_expr;
13705 Code::init_expr(&value_expr);
13706 generate_code_for_value(&value_expr, value, scope);
13707 // the id of the instance of Lazy_Param which will be used as the actual parameter
13708 string lazy_param_id = value->get_temporary_id();
13709 string type_name = value->get_my_governor()->get_genname_value(scope);
13710 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
13711 }
13712
13713 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
13714 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13715 if (depth>1) {
13716 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13717 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13718 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13719 expression_struct tmpl_expr;
13720 Code::init_expr(&tmpl_expr);
13721 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13722 // the id of the instance of Lazy_Param which will be used as the actual parameter
13723 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
13724 if (tmpl_expr.preamble) {
13725 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
13726 }
13727 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13728 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13729 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
13730 Code::free_expr(&tmpl_expr);
13731 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13732 return;
13733 }
13734 // only if the formal parameter is *not* used as lvalue
13735 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
13736 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
13737 if (refd_ass) {
13738 bool refd_ass_is_lazy_fpar = false;
13739 switch (refd_ass->get_asstype()) {
13740 case Assignment::A_PAR_VAL:
13741 case Assignment::A_PAR_VAL_IN:
13742 case Assignment::A_PAR_TEMPL_IN:
13743 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13744 break;
13745 default:
13746 break;
13747 }
13748 if (refd_ass_is_lazy_fpar) {
13749 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13750 return;
13751 }
13752 }
13753 }
13754 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13755 expression_struct tmpl_expr;
13756 Code::init_expr(&tmpl_expr);
13757 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13758 // the id of the instance of Lazy_Param which will be used as the actual parameter
13759 string lazy_param_id = temp->get_Template()->get_temporary_id();
13760 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
13761 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
13762 }
13763
13764 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
13765 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
13766 if (type_vec->size()>0) {
13767 // private members of the local class will be const references to the objects referenced by the expression
13768 for (size_t i=0; i<type_vec->size(); i++) {
13769 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
13770 }
13771 expr->preamble = mputstr(expr->preamble, "public:\n");
13772 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
13773 for (size_t i=0; i<type_vec->size(); i++) {
13774 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13775 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
13776 }
13777 expr->preamble = mputstr(expr->preamble, "): ");
13778 for (size_t i=0; i<type_vec->size(); i++) {
13779 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13780 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
13781 }
13782 expr->preamble = mputstr(expr->preamble, " {}\n");
13783 expr->preamble = mputstr(expr->preamble, "private:\n");
13784 }
13785 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
13786 // use the temporary expr structure to fill the body of the eval_expr() function
13787 if (param_expr.preamble) {
13788 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
13789 }
13790 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
13791 if (param_expr.postamble) {
13792 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
13793 }
13794 Code::free_expr(&param_expr);
13795 expr->preamble = mputstr(expr->preamble, "}\n"
13796 "};\n" // end of local class definition
13797 );
13798 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
13799 if (type_vec->size()>0) {
13800 expr->preamble = mputc(expr->preamble, '(');
13801 // paramteres of the constructor are references to the objects used in the expression
13802 for (size_t i=0; i<refd_vec->size(); i++) {
13803 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13804 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
13805 }
13806 expr->preamble = mputc(expr->preamble, ')');
13807 }
13808 expr->preamble = mputstr(expr->preamble, ";\n");
13809 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13810 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
13811 }
13812
13813 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
13814 expression_struct ref_expr;
13815 Code::init_expr(&ref_expr);
13816 ref->generate_code(&ref_expr);
13817 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
13818 if (ref_expr.preamble) {
13819 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
13820 }
13821 Assignment* ass = ref->get_refd_assignment();
13822 // determine C++ type of the assignment
13823 string type_str;
13824 switch (ass->get_asstype()) {
13825 case Assignment::A_MODULEPAR_TEMP:
13826 case Assignment::A_TEMPLATE:
13827 case Assignment::A_VAR_TEMPLATE:
13828 case Assignment::A_PAR_TEMPL_IN:
13829 case Assignment::A_PAR_TEMPL_OUT:
13830 case Assignment::A_PAR_TEMPL_INOUT:
13831 type_str = ass->get_Type()->get_genname_template(scope);
13832 break;
13833 default:
13834 type_str = ass->get_Type()->get_genname_value(scope);
13835 }
13836 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13837 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
13838 if (ref_expr.postamble) {
13839 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
13840 }
13841 Code::free_expr(&ref_expr);
13842 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13843 }
13844
13845 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
13846 const string& lazy_param_id = value->get_temporary_id();
13847 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13848 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13849 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
13850 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13851 }
13852
13853 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
13854 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
13855 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13856 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13857 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
13858 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13859 }
13860
13861 } // namespace Common
This page took 0.549986 seconds and 6 git commands to generate.