Sync with 5.4.2
[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 #include "ttcn3/Ttcn2Json.hh"
35
36 #include <math.h>
37 #include <regex.h>
38 #include <limits.h>
39
40 namespace Common {
41
42 static void clean_up_string_elements(map<size_t, Value>*& string_elements)
43 {
44 if (string_elements) {
45 for (size_t i = 0; i < string_elements->size(); i++)
46 delete string_elements->get_nth_elem(i);
47 string_elements->clear();
48 delete string_elements;
49 string_elements = 0;
50 }
51 }
52
53 // =================================
54 // ===== Value
55 // =================================
56
57 Value::Value(const Value& p)
58 : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
59 {
60 switch(valuetype) {
61 case V_ERROR:
62 case V_NULL:
63 case V_OMIT:
64 case V_TTCN3_NULL:
65 case V_DEFAULT_NULL:
66 case V_FAT_NULL:
67 case V_NOTUSED:
68 break;
69 case V_BOOL:
70 u.val_bool=p.u.val_bool;
71 break;
72 case V_INT:
73 u.val_Int=new int_val_t(*(p.u.val_Int));
74 break;
75 case V_NAMEDINT:
76 case V_ENUM:
77 case V_UNDEF_LOWERID:
78 u.val_id=p.u.val_id->clone();
79 break;
80 case V_REAL:
81 u.val_Real=p.u.val_Real;
82 break;
83 case V_BSTR:
84 case V_HSTR:
85 case V_OSTR:
86 case V_CSTR:
87 case V_ISO2022STR:
88 set_val_str(new string(*p.u.str.val_str));
89 break;
90 case V_USTR:
91 set_val_ustr(new ustring(*p.u.ustr.val_ustr));
92 u.ustr.convert_str = p.u.ustr.convert_str;
93 break;
94 case V_CHARSYMS:
95 u.char_syms = p.u.char_syms->clone();
96 break;
97 case V_OID:
98 case V_ROID:
99 u.oid_comps=new vector<OID_comp>;
100 for(size_t i=0; i<p.u.oid_comps->size(); i++)
101 add_oid_comp((*p.u.oid_comps)[i]->clone());
102 break;
103 case V_CHOICE:
104 u.choice.alt_name=p.u.choice.alt_name->clone();
105 u.choice.alt_value=p.u.choice.alt_value->clone();
106 break;
107 case V_SEQOF:
108 case V_SETOF:
109 case V_ARRAY:
110 u.val_vs=p.u.val_vs->clone();
111 break;
112 case V_SEQ:
113 case V_SET:
114 u.val_nvs=p.u.val_nvs->clone();
115 break;
116 case V_REFD:
117 u.ref.ref=p.u.ref.ref->clone();
118 u.ref.refd_last=0;
119 break;
120 case V_NAMEDBITS:
121 for(size_t i=0; i<p.u.ids->size(); i++) {
122 Identifier *id = p.u.ids->get_nth_elem(i);
123 u.ids->add(id->get_name(), id->clone());
124 }
125 break;
126 case V_UNDEF_BLOCK:
127 u.block=p.u.block->clone();
128 break;
129 case V_VERDICT:
130 u.verdict=p.u.verdict;
131 break;
132 case V_EXPR:
133 u.expr.v_optype = p.u.expr.v_optype;
134 u.expr.state = EXPR_NOT_CHECKED;
135 switch(u.expr.v_optype) {
136 case OPTYPE_RND: // -
137 case OPTYPE_COMP_NULL:
138 case OPTYPE_COMP_MTC:
139 case OPTYPE_COMP_SYSTEM:
140 case OPTYPE_COMP_SELF:
141 case OPTYPE_COMP_RUNNING_ANY:
142 case OPTYPE_COMP_RUNNING_ALL:
143 case OPTYPE_COMP_ALIVE_ANY:
144 case OPTYPE_COMP_ALIVE_ALL:
145 case OPTYPE_TMR_RUNNING_ANY:
146 case OPTYPE_GETVERDICT:
147 case OPTYPE_TESTCASENAME:
148 case OPTYPE_PROF_RUNNING:
149 break;
150 case OPTYPE_UNARYPLUS: // v1
151 case OPTYPE_UNARYMINUS:
152 case OPTYPE_NOT:
153 case OPTYPE_NOT4B:
154 case OPTYPE_BIT2HEX:
155 case OPTYPE_BIT2INT:
156 case OPTYPE_BIT2OCT:
157 case OPTYPE_BIT2STR:
158 case OPTYPE_CHAR2INT:
159 case OPTYPE_CHAR2OCT:
160 case OPTYPE_COMP_RUNNING:
161 case OPTYPE_COMP_ALIVE:
162 case OPTYPE_FLOAT2INT:
163 case OPTYPE_FLOAT2STR:
164 case OPTYPE_HEX2BIT:
165 case OPTYPE_HEX2INT:
166 case OPTYPE_HEX2OCT:
167 case OPTYPE_HEX2STR:
168 case OPTYPE_INT2CHAR:
169 case OPTYPE_INT2FLOAT:
170 case OPTYPE_INT2STR:
171 case OPTYPE_INT2UNICHAR:
172 case OPTYPE_OCT2BIT:
173 case OPTYPE_OCT2CHAR:
174 case OPTYPE_OCT2HEX:
175 case OPTYPE_OCT2INT:
176 case OPTYPE_OCT2STR:
177 case OPTYPE_STR2BIT:
178 case OPTYPE_STR2FLOAT:
179 case OPTYPE_STR2HEX:
180 case OPTYPE_STR2INT:
181 case OPTYPE_STR2OCT:
182 case OPTYPE_UNICHAR2INT:
183 case OPTYPE_UNICHAR2CHAR:
184 case OPTYPE_ENUM2INT:
185 case OPTYPE_RNDWITHVAL:
186 case OPTYPE_GET_STRINGENCODING:
187 case OPTYPE_DECODE_BASE64:
188 case OPTYPE_REMOVE_BOM:
189 u.expr.v1=p.u.expr.v1->clone();
190 break;
191 case OPTYPE_ADD: // v1 v2
192 case OPTYPE_SUBTRACT:
193 case OPTYPE_MULTIPLY:
194 case OPTYPE_DIVIDE:
195 case OPTYPE_MOD:
196 case OPTYPE_REM:
197 case OPTYPE_CONCAT:
198 case OPTYPE_EQ:
199 case OPTYPE_LT:
200 case OPTYPE_GT:
201 case OPTYPE_NE:
202 case OPTYPE_GE:
203 case OPTYPE_LE:
204 case OPTYPE_AND:
205 case OPTYPE_OR:
206 case OPTYPE_XOR:
207 case OPTYPE_AND4B:
208 case OPTYPE_OR4B:
209 case OPTYPE_XOR4B:
210 case OPTYPE_SHL:
211 case OPTYPE_SHR:
212 case OPTYPE_ROTL:
213 case OPTYPE_ROTR:
214 case OPTYPE_INT2BIT:
215 case OPTYPE_INT2HEX:
216 case OPTYPE_INT2OCT:
217 u.expr.v1=p.u.expr.v1->clone();
218 u.expr.v2=p.u.expr.v2->clone();
219 break;
220 case OPTYPE_UNICHAR2OCT: // v1 [v2]
221 case OPTYPE_OCT2UNICHAR:
222 case OPTYPE_ENCODE_BASE64:
223 u.expr.v1=p.u.expr.v1->clone();
224 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
225 break;
226 case OPTYPE_DECODE:
227 u.expr.r1=p.u.expr.r1->clone();
228 u.expr.r2=p.u.expr.r2->clone();
229 break;
230 case OPTYPE_SUBSTR:
231 u.expr.ti1=p.u.expr.ti1->clone();
232 u.expr.v2=p.u.expr.v2->clone();
233 u.expr.v3=p.u.expr.v3->clone();
234 break;
235 case OPTYPE_REGEXP:
236 u.expr.ti1=p.u.expr.ti1->clone();
237 u.expr.t2=p.u.expr.t2->clone();
238 u.expr.v3=p.u.expr.v3->clone();
239 break;
240 case OPTYPE_DECOMP: // v1 v2 v3
241 u.expr.v1=p.u.expr.v1->clone();
242 u.expr.v2=p.u.expr.v2->clone();
243 u.expr.v3=p.u.expr.v3->clone();
244 break;
245 case OPTYPE_REPLACE:
246 u.expr.ti1 = p.u.expr.ti1->clone();
247 u.expr.v2 = p.u.expr.v2->clone();
248 u.expr.v3 = p.u.expr.v3->clone();
249 u.expr.ti4 = p.u.expr.ti4->clone();
250 break;
251 case OPTYPE_LENGTHOF: // ti1
252 case OPTYPE_SIZEOF: // ti1
253 case OPTYPE_VALUEOF: // ti1
254 case OPTYPE_ENCODE:
255 case OPTYPE_ISPRESENT:
256 case OPTYPE_TTCN2STRING:
257 u.expr.ti1=p.u.expr.ti1->clone();
258 break;
259 case OPTYPE_UNDEF_RUNNING:
260 case OPTYPE_TMR_READ:
261 case OPTYPE_TMR_RUNNING:
262 case OPTYPE_ACTIVATE:
263 u.expr.r1=p.u.expr.r1->clone();
264 break;
265 case OPTYPE_EXECUTE: // r1 [v2]
266 u.expr.r1=p.u.expr.r1->clone();
267 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
268 break;
269 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
270 u.expr.r1=p.u.expr.r1->clone();
271 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
272 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
273 u.expr.b4 = p.u.expr.b4;
274 break;
275 case OPTYPE_MATCH: // v1 t2
276 u.expr.v1=p.u.expr.v1->clone();
277 u.expr.t2=p.u.expr.t2->clone();
278 break;
279 case OPTYPE_ISCHOSEN: // r1 i2
280 u.expr.r1=p.u.expr.r1->clone();
281 u.expr.i2=p.u.expr.i2->clone();
282 break;
283 case OPTYPE_ISCHOSEN_V: // v1 i2
284 u.expr.v1=p.u.expr.v1->clone();
285 u.expr.i2=p.u.expr.i2->clone();
286 break;
287 case OPTYPE_ISCHOSEN_T: // t1 i2
288 u.expr.t1=p.u.expr.t1->clone();
289 u.expr.i2=p.u.expr.i2->clone();
290 break;
291 case OPTYPE_ACTIVATE_REFD:
292 u.expr.v1 = p.u.expr.v1->clone();
293 if(p.u.expr.state!=EXPR_CHECKED)
294 u.expr.t_list2 = p.u.expr.t_list2->clone();
295 else {
296 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
297 u.expr.state = EXPR_CHECKED;
298 }
299 break;
300 case OPTYPE_EXECUTE_REFD:
301 u.expr.v1 = p.u.expr.v1->clone();
302 if(p.u.expr.state!=EXPR_CHECKED)
303 u.expr.t_list2 = p.u.expr.t_list2->clone();
304 else {
305 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
306 u.expr.state = EXPR_CHECKED;
307 }
308 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
309 break;
310 case OPTYPE_LOG2STR:
311 u.expr.logargs = p.u.expr.logargs->clone();
312 break;
313 default:
314 FATAL_ERROR("Value::Value()");
315 } // switch
316 break;
317 case V_MACRO:
318 u.macro = p.u.macro;
319 break;
320 case V_FUNCTION:
321 case V_ALTSTEP:
322 case V_TESTCASE:
323 u.refd_fat = p.u.refd_fat;
324 break;
325 case V_INVOKE:
326 u.invoke.v = p.u.invoke.v->clone();
327 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
328 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
329 break;
330 case V_REFER:
331 u.refered = p.u.refered->clone();
332 break;
333 default:
334 FATAL_ERROR("Value::Value()");
335 } // switch
336 }
337
338 void Value::clean_up()
339 {
340 switch (valuetype) {
341 case V_ERROR:
342 case V_NULL:
343 case V_BOOL:
344 case V_REAL:
345 case V_OMIT:
346 case V_VERDICT:
347 case V_TTCN3_NULL:
348 case V_DEFAULT_NULL:
349 case V_FAT_NULL:
350 case V_MACRO:
351 case V_NOTUSED:
352 case V_FUNCTION:
353 case V_ALTSTEP:
354 case V_TESTCASE:
355 break;
356 case V_INT:
357 delete u.val_Int;
358 break;
359 case V_NAMEDINT:
360 case V_ENUM:
361 case V_UNDEF_LOWERID:
362 delete u.val_id;
363 break;
364 case V_BSTR:
365 case V_HSTR:
366 case V_OSTR:
367 case V_CSTR:
368 case V_ISO2022STR:
369 delete u.str.val_str;
370 clean_up_string_elements(u.str.str_elements);
371 break;
372 case V_USTR:
373 delete u.ustr.val_ustr;
374 clean_up_string_elements(u.ustr.ustr_elements);
375 break;
376 case V_CHARSYMS:
377 delete u.char_syms;
378 break;
379 case V_OID:
380 case V_ROID:
381 if (u.oid_comps) {
382 for(size_t i=0; i<u.oid_comps->size(); i++)
383 delete (*u.oid_comps)[i];
384 u.oid_comps->clear();
385 delete u.oid_comps;
386 }
387 break;
388 case V_EXPR:
389 clean_up_expr();
390 break;
391 case V_CHOICE:
392 delete u.choice.alt_name;
393 delete u.choice.alt_value;
394 break;
395 case V_SEQOF:
396 case V_SETOF:
397 case V_ARRAY:
398 delete u.val_vs;
399 break;
400 case V_SEQ:
401 case V_SET:
402 delete u.val_nvs;
403 break;
404 case V_REFD:
405 delete u.ref.ref;
406 break;
407 case V_REFER:
408 delete u.refered;
409 break;
410 case V_INVOKE:
411 delete u.invoke.v;
412 delete u.invoke.t_list;
413 delete u.invoke.ap_list;
414 break;
415 case V_NAMEDBITS:
416 if(u.ids) {
417 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
418 u.ids->clear();
419 delete u.ids;
420 }
421 break;
422 case V_UNDEF_BLOCK:
423 delete u.block;
424 break;
425 default:
426 FATAL_ERROR("Value::clean_up()");
427 } // switch
428 }
429
430 void Value::clean_up_expr()
431 {
432 switch (u.expr.state) {
433 case EXPR_CHECKING:
434 case EXPR_CHECKING_ERR:
435 FATAL_ERROR("Value::clean_up_expr()");
436 default:
437 break;
438 }
439 switch (u.expr.v_optype) {
440 case OPTYPE_RND: // -
441 case OPTYPE_COMP_NULL:
442 case OPTYPE_COMP_MTC:
443 case OPTYPE_COMP_SYSTEM:
444 case OPTYPE_COMP_SELF:
445 case OPTYPE_COMP_RUNNING_ANY:
446 case OPTYPE_COMP_RUNNING_ALL:
447 case OPTYPE_COMP_ALIVE_ANY:
448 case OPTYPE_COMP_ALIVE_ALL:
449 case OPTYPE_TMR_RUNNING_ANY:
450 case OPTYPE_GETVERDICT:
451 case OPTYPE_TESTCASENAME:
452 case OPTYPE_PROF_RUNNING:
453 break;
454 case OPTYPE_UNARYPLUS: // v1
455 case OPTYPE_UNARYMINUS:
456 case OPTYPE_NOT:
457 case OPTYPE_NOT4B:
458 case OPTYPE_BIT2HEX:
459 case OPTYPE_BIT2INT:
460 case OPTYPE_BIT2OCT:
461 case OPTYPE_BIT2STR:
462 case OPTYPE_CHAR2INT:
463 case OPTYPE_CHAR2OCT:
464 case OPTYPE_COMP_RUNNING:
465 case OPTYPE_COMP_ALIVE:
466 case OPTYPE_FLOAT2INT:
467 case OPTYPE_FLOAT2STR:
468 case OPTYPE_HEX2BIT:
469 case OPTYPE_HEX2INT:
470 case OPTYPE_HEX2OCT:
471 case OPTYPE_HEX2STR:
472 case OPTYPE_INT2CHAR:
473 case OPTYPE_INT2FLOAT:
474 case OPTYPE_INT2STR:
475 case OPTYPE_INT2UNICHAR:
476 case OPTYPE_OCT2BIT:
477 case OPTYPE_OCT2CHAR:
478 case OPTYPE_OCT2HEX:
479 case OPTYPE_OCT2INT:
480 case OPTYPE_OCT2STR:
481 case OPTYPE_STR2BIT:
482 case OPTYPE_STR2FLOAT:
483 case OPTYPE_STR2HEX:
484 case OPTYPE_STR2INT:
485 case OPTYPE_STR2OCT:
486 case OPTYPE_UNICHAR2INT:
487 case OPTYPE_UNICHAR2CHAR:
488 case OPTYPE_ENUM2INT:
489 case OPTYPE_RNDWITHVAL:
490 case OPTYPE_REMOVE_BOM:
491 case OPTYPE_GET_STRINGENCODING:
492 case OPTYPE_DECODE_BASE64:
493 delete u.expr.v1;
494 break;
495 case OPTYPE_ADD: // v1 v2
496 case OPTYPE_SUBTRACT:
497 case OPTYPE_MULTIPLY:
498 case OPTYPE_DIVIDE:
499 case OPTYPE_MOD:
500 case OPTYPE_REM:
501 case OPTYPE_CONCAT:
502 case OPTYPE_EQ:
503 case OPTYPE_LT:
504 case OPTYPE_GT:
505 case OPTYPE_NE:
506 case OPTYPE_GE:
507 case OPTYPE_LE:
508 case OPTYPE_AND:
509 case OPTYPE_OR:
510 case OPTYPE_XOR:
511 case OPTYPE_AND4B:
512 case OPTYPE_OR4B:
513 case OPTYPE_XOR4B:
514 case OPTYPE_SHL:
515 case OPTYPE_SHR:
516 case OPTYPE_ROTL:
517 case OPTYPE_ROTR:
518 case OPTYPE_INT2BIT:
519 case OPTYPE_INT2HEX:
520 case OPTYPE_INT2OCT:
521 case OPTYPE_UNICHAR2OCT:
522 case OPTYPE_OCT2UNICHAR:
523 case OPTYPE_ENCODE_BASE64:
524 delete u.expr.v1;
525 delete u.expr.v2;
526 break;
527 case OPTYPE_DECODE:
528 delete u.expr.r1;
529 delete u.expr.r2;
530 break;
531 case OPTYPE_SUBSTR:
532 delete u.expr.ti1;
533 delete u.expr.v2;
534 delete u.expr.v3;
535 break;
536 case OPTYPE_REGEXP:
537 delete u.expr.ti1;
538 delete u.expr.t2;
539 delete u.expr.v3;
540 break;
541 case OPTYPE_DECOMP: // v1 v2 v3
542 delete u.expr.v1;
543 delete u.expr.v2;
544 delete u.expr.v3;
545 break;
546 case OPTYPE_REPLACE:
547 delete u.expr.ti1;
548 delete u.expr.v2;
549 delete u.expr.v3;
550 delete u.expr.ti4;
551 break;
552 case OPTYPE_LENGTHOF: // ti1
553 case OPTYPE_SIZEOF: // ti1
554 case OPTYPE_VALUEOF: // ti1
555 case OPTYPE_ISVALUE:
556 case OPTYPE_ISBOUND:
557 case OPTYPE_ENCODE:
558 case OPTYPE_ISPRESENT:
559 case OPTYPE_TTCN2STRING:
560 delete u.expr.ti1;
561 break;
562 case OPTYPE_UNDEF_RUNNING:
563 case OPTYPE_TMR_READ:
564 case OPTYPE_TMR_RUNNING:
565 case OPTYPE_ACTIVATE:
566 delete u.expr.r1;
567 break;
568 case OPTYPE_EXECUTE: // r1 [v2]
569 delete u.expr.r1;
570 delete u.expr.v2;
571 break;
572 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
573 delete u.expr.r1;
574 delete u.expr.v2;
575 delete u.expr.v3;
576 break;
577 case OPTYPE_MATCH: // v1 t2
578 delete u.expr.v1;
579 delete u.expr.t2;
580 break;
581 case OPTYPE_ISCHOSEN: // r1 i2
582 delete u.expr.r1;
583 delete u.expr.i2;
584 break;
585 case OPTYPE_ISCHOSEN_V: // v1 i2
586 delete u.expr.v1;
587 delete u.expr.i2;
588 break;
589 case OPTYPE_ISCHOSEN_T: // t1 i2
590 delete u.expr.t1;
591 delete u.expr.i2;
592 break;
593 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
594 delete u.expr.v1;
595 if(u.expr.state!=EXPR_CHECKED)
596 delete u.expr.t_list2;
597 else
598 delete u.expr.ap_list2;
599 break;
600 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
601 delete u.expr.v1;
602 if(u.expr.state!=EXPR_CHECKED)
603 delete u.expr.t_list2;
604 else
605 delete u.expr.ap_list2;
606 delete u.expr.v3;
607 break;
608 case OPTYPE_LOG2STR:
609 delete u.expr.logargs;
610 break;
611 default:
612 FATAL_ERROR("Value::clean_up_expr()");
613 } // switch
614 }
615
616 void Value::copy_and_destroy(Value *src)
617 {
618 clean_up();
619 valuetype = src->valuetype;
620 u = src->u;
621 // update the pointer used for caching if it points to the value itself
622 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
623 src->valuetype = V_ERROR;
624 delete src;
625 }
626
627 Value::Value(valuetype_t p_vt)
628 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
629 {
630 switch(valuetype) {
631 case V_NULL:
632 case V_TTCN3_NULL:
633 case V_OMIT:
634 case V_NOTUSED:
635 case V_ERROR:
636 break;
637 case V_OID:
638 case V_ROID:
639 u.oid_comps=new vector<OID_comp>();
640 break;
641 case V_NAMEDBITS:
642 u.ids=new map<string, Identifier>();
643 break;
644 default:
645 FATAL_ERROR("Value::Value()");
646 } // switch
647 }
648
649 Value::Value(valuetype_t p_vt, bool p_val_bool)
650 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
651 {
652 switch(valuetype) {
653 case V_BOOL:
654 u.val_bool=p_val_bool;
655 break;
656 default:
657 FATAL_ERROR("Value::Value()");
658 } // switch
659 }
660
661 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
662 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
663 {
664 switch(valuetype) {
665 case V_INT:
666 u.val_Int=new int_val_t(p_val_Int);
667 break;
668 default:
669 FATAL_ERROR("Value::Value()");
670 } // switch
671 }
672
673 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
674 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
675 {
676 switch(valuetype){
677 case V_INT:
678 u.val_Int=p_val_Int;
679 break;
680 default:
681 FATAL_ERROR("Value::Value()");
682 }
683 }
684
685 Value::Value(valuetype_t p_vt, string *p_val_str)
686 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
687 {
688 if(!p_val_str) FATAL_ERROR("NULL parameter");
689 switch(valuetype) {
690 case V_BSTR:
691 case V_HSTR:
692 case V_OSTR:
693 case V_CSTR:
694 case V_ISO2022STR:
695 set_val_str(p_val_str);
696 break;
697 default:
698 FATAL_ERROR("Value::Value()");
699 } // switch
700 }
701
702 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
703 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
704 {
705 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
706 set_val_ustr(p_val_ustr);
707 u.ustr.convert_str = false;
708 }
709
710 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
711 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
712 {
713 if (!p_char_syms) FATAL_ERROR("NULL parameter");
714 switch (valuetype) {
715 case V_CHARSYMS:
716 u.char_syms = p_char_syms;
717 break;
718 default:
719 FATAL_ERROR("Value::Value()");
720 } // switch
721 }
722
723 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
724 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
725 {
726 if(!p_val_id)
727 FATAL_ERROR("NULL parameter");
728 switch(valuetype) {
729 case V_NAMEDINT:
730 case V_ENUM:
731 case V_UNDEF_LOWERID:
732 u.val_id=p_val_id;
733 break;
734 default:
735 FATAL_ERROR("Value::Value()");
736 } // switch
737 }
738
739 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
740 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
741 {
742 if(!p_id || !p_val)
743 FATAL_ERROR("NULL parameter");
744 switch(valuetype) {
745 case V_CHOICE:
746 u.choice.alt_name=p_id;
747 u.choice.alt_value=p_val;
748 break;
749 default:
750 FATAL_ERROR("Value::Value()");
751 } // switch
752 }
753
754 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
755 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
756 {
757 switch(valuetype) {
758 case V_REAL:
759 u.val_Real=p_val_Real;
760 break;
761 default:
762 FATAL_ERROR("Value::Value()");
763 } // switch
764 }
765
766 Value::Value(valuetype_t p_vt, Values *p_vs)
767 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
768 {
769 if(!p_vs) FATAL_ERROR("NULL parameter");
770 switch(valuetype) {
771 case V_SEQOF:
772 case V_SETOF:
773 case V_ARRAY:
774 u.val_vs=p_vs;
775 break;
776 default:
777 FATAL_ERROR("Value::Value()");
778 } // switch
779 }
780
781 Value::Value(valuetype_t p_vt, Value *p_v,
782 Ttcn::ParsedActualParameters *p_t_list)
783 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
784 {
785 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
786 switch(valuetype) {
787 case V_INVOKE:
788 u.invoke.v = p_v;
789 u.invoke.t_list = p_t_list;
790 u.invoke.ap_list = 0;
791 break;
792 default:
793 FATAL_ERROR("Value::Value()");
794 }
795 }
796
797 // -
798 Value::Value(operationtype_t p_optype)
799 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
800 {
801 u.expr.v_optype = p_optype;
802 u.expr.state = EXPR_NOT_CHECKED;
803 switch(p_optype) {
804 case OPTYPE_RND:
805 case OPTYPE_COMP_NULL:
806 case OPTYPE_COMP_MTC:
807 case OPTYPE_COMP_SYSTEM:
808 case OPTYPE_COMP_SELF:
809 case OPTYPE_COMP_RUNNING_ANY:
810 case OPTYPE_COMP_RUNNING_ALL:
811 case OPTYPE_COMP_ALIVE_ANY:
812 case OPTYPE_COMP_ALIVE_ALL:
813 case OPTYPE_TMR_RUNNING_ANY:
814 case OPTYPE_GETVERDICT:
815 case OPTYPE_TESTCASENAME:
816 case OPTYPE_PROF_RUNNING:
817 break;
818 default:
819 FATAL_ERROR("Value::Value()");
820 } // switch
821 }
822
823 // v1
824 Value::Value(operationtype_t p_optype, Value *p_v1)
825 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
826 {
827 u.expr.v_optype = p_optype;
828 u.expr.state = EXPR_NOT_CHECKED;
829 switch(p_optype) {
830 case OPTYPE_UNARYPLUS:
831 case OPTYPE_UNARYMINUS:
832 case OPTYPE_NOT:
833 case OPTYPE_NOT4B:
834 case OPTYPE_BIT2HEX:
835 case OPTYPE_BIT2INT:
836 case OPTYPE_BIT2OCT:
837 case OPTYPE_BIT2STR:
838 case OPTYPE_CHAR2INT:
839 case OPTYPE_CHAR2OCT:
840 case OPTYPE_COMP_RUNNING:
841 case OPTYPE_COMP_ALIVE:
842 case OPTYPE_FLOAT2INT:
843 case OPTYPE_FLOAT2STR:
844 case OPTYPE_HEX2BIT:
845 case OPTYPE_HEX2INT:
846 case OPTYPE_HEX2OCT:
847 case OPTYPE_HEX2STR:
848 case OPTYPE_INT2CHAR:
849 case OPTYPE_INT2FLOAT:
850 case OPTYPE_INT2STR:
851 case OPTYPE_INT2UNICHAR:
852 case OPTYPE_OCT2BIT:
853 case OPTYPE_OCT2CHAR:
854 case OPTYPE_OCT2HEX:
855 case OPTYPE_OCT2INT:
856 case OPTYPE_OCT2STR:
857 case OPTYPE_STR2BIT:
858 case OPTYPE_STR2FLOAT:
859 case OPTYPE_STR2HEX:
860 case OPTYPE_STR2INT:
861 case OPTYPE_STR2OCT:
862 case OPTYPE_UNICHAR2INT:
863 case OPTYPE_UNICHAR2CHAR:
864 case OPTYPE_ENUM2INT:
865 case OPTYPE_RNDWITHVAL:
866 case OPTYPE_REMOVE_BOM:
867 case OPTYPE_GET_STRINGENCODING:
868 case OPTYPE_DECODE_BASE64:
869 if(!p_v1) FATAL_ERROR("Value::Value()");
870 u.expr.v1=p_v1;
871 break;
872 default:
873 FATAL_ERROR("Value::Value()");
874 } // switch
875 }
876
877 // ti1
878 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
879 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
880 {
881 u.expr.v_optype = p_optype;
882 u.expr.state = EXPR_NOT_CHECKED;
883 switch(p_optype) {
884 case OPTYPE_LENGTHOF:
885 case OPTYPE_SIZEOF:
886 case OPTYPE_VALUEOF:
887 case OPTYPE_ISVALUE:
888 case OPTYPE_ISBOUND:
889 case OPTYPE_ENCODE:
890 case OPTYPE_ISPRESENT:
891 case OPTYPE_TTCN2STRING:
892 if(!p_ti1) FATAL_ERROR("Value::Value()");
893 u.expr.ti1=p_ti1;
894 break;
895 default:
896 FATAL_ERROR("Value::Value()");
897 } // switch
898 }
899
900 // r1
901 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
902 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
903 {
904 u.expr.v_optype = p_optype;
905 u.expr.state = EXPR_NOT_CHECKED;
906 switch(p_optype) {
907 case OPTYPE_UNDEF_RUNNING:
908 case OPTYPE_TMR_READ:
909 case OPTYPE_TMR_RUNNING:
910 case OPTYPE_ACTIVATE:
911 if(!p_r1) FATAL_ERROR("Value::Value()");
912 u.expr.r1=p_r1;
913 break;
914 default:
915 FATAL_ERROR("Value::Value()");
916 } // switch
917 }
918
919 // v1 t_list2
920 Value::Value(operationtype_t p_optype, Value *p_v1,
921 Ttcn::ParsedActualParameters *p_ap_list)
922 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
923 {
924 u.expr.v_optype = p_optype;
925 u.expr.state = EXPR_NOT_CHECKED;
926 switch(p_optype) {
927 case OPTYPE_ACTIVATE_REFD:
928 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
929 u.expr.v1 = p_v1;
930 u.expr.t_list2 = p_ap_list;
931 break;
932 default:
933 FATAL_ERROR("Value::Value()");
934 }
935 }
936
937 //v1 t_list2 v3
938 Value::Value(operationtype_t p_optype, Value *p_v1,
939 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
940 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
941 {
942 u.expr.v_optype = p_optype;
943 u.expr.state = EXPR_NOT_CHECKED;
944 switch(p_optype) {
945 case OPTYPE_EXECUTE_REFD:
946 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
947 u.expr.v1 = p_v1;
948 u.expr.t_list2 = p_t_list2;
949 u.expr.v3 = p_v3;
950 break;
951 default:
952 FATAL_ERROR("Value::Value()");
953 }
954 }
955
956 // r1 [v2]
957 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
958 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
959 {
960 u.expr.v_optype = p_optype;
961 u.expr.state = EXPR_NOT_CHECKED;
962 switch(p_optype) {
963 case OPTYPE_EXECUTE:
964 if(!p_r1) FATAL_ERROR("Value::Value()");
965 u.expr.r1=p_r1;
966 u.expr.v2=p_v2;
967 break;
968 default:
969 FATAL_ERROR("Value::Value()");
970 } // switch
971 }
972
973 // r1 [v2] [v3] b4
974 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
975 Value *p_v2, Value *p_v3, bool p_b4)
976 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
977 {
978 u.expr.v_optype = p_optype;
979 u.expr.state = EXPR_NOT_CHECKED;
980 switch(p_optype) {
981 case OPTYPE_COMP_CREATE:
982 if(!p_r1) FATAL_ERROR("Value::Value()");
983 u.expr.r1=p_r1;
984 u.expr.v2=p_v2;
985 u.expr.v3=p_v3;
986 u.expr.b4=p_b4;
987 break;
988 default:
989 FATAL_ERROR("Value::Value()");
990 } // switch
991 }
992
993 // v1 v2
994 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
995 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
996 {
997 u.expr.v_optype = p_optype;
998 u.expr.state = EXPR_NOT_CHECKED;
999 switch(p_optype) {
1000 case OPTYPE_ADD:
1001 case OPTYPE_SUBTRACT:
1002 case OPTYPE_MULTIPLY:
1003 case OPTYPE_DIVIDE:
1004 case OPTYPE_MOD:
1005 case OPTYPE_REM:
1006 case OPTYPE_CONCAT:
1007 case OPTYPE_EQ:
1008 case OPTYPE_LT:
1009 case OPTYPE_GT:
1010 case OPTYPE_NE:
1011 case OPTYPE_GE:
1012 case OPTYPE_LE:
1013 case OPTYPE_AND:
1014 case OPTYPE_OR:
1015 case OPTYPE_XOR:
1016 case OPTYPE_AND4B:
1017 case OPTYPE_OR4B:
1018 case OPTYPE_XOR4B:
1019 case OPTYPE_SHL:
1020 case OPTYPE_SHR:
1021 case OPTYPE_ROTL:
1022 case OPTYPE_ROTR:
1023 case OPTYPE_INT2BIT:
1024 case OPTYPE_INT2HEX:
1025 case OPTYPE_INT2OCT:
1026 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1027 u.expr.v1=p_v1;
1028 u.expr.v2=p_v2;
1029 break;
1030 case OPTYPE_UNICHAR2OCT:
1031 case OPTYPE_OCT2UNICHAR:
1032 case OPTYPE_ENCODE_BASE64:
1033 if(!p_v1) FATAL_ERROR("Value::Value()");
1034 u.expr.v1=p_v1;
1035 // p_v2 may be NULL if there is no second param
1036 u.expr.v2=p_v2;
1037 break;
1038 default:
1039 FATAL_ERROR("Value::Value()");
1040 } // switch
1041 }
1042
1043 // ti1 v2 v3 ti4
1044 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1045 Value *p_v3, TemplateInstance *p_ti4) :
1046 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1047 {
1048 u.expr.v_optype = p_optype;
1049 u.expr.state = EXPR_NOT_CHECKED;
1050 switch (p_optype) {
1051 case OPTYPE_REPLACE:
1052 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1053 u.expr.ti1 = p_ti1;
1054 u.expr.v2 = p_v2;
1055 u.expr.v3 = p_v3;
1056 u.expr.ti4 = p_ti4;
1057 break;
1058 default:
1059 FATAL_ERROR("Value::Value()");
1060 } // switch
1061 }
1062
1063 // v1 v2 v3
1064 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1065 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1066 {
1067 u.expr.v_optype = p_optype;
1068 u.expr.state = EXPR_NOT_CHECKED;
1069 switch(p_optype) {
1070 case OPTYPE_DECOMP:
1071 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1072 u.expr.v1=p_v1;
1073 u.expr.v2=p_v2;
1074 u.expr.v3=p_v3;
1075 break;
1076 default:
1077 FATAL_ERROR("Value::Value()");
1078 } // switch
1079 }
1080
1081 // ti1 v2 v3
1082 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1083 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1084 {
1085 u.expr.v_optype=p_optype;
1086 u.expr.state=EXPR_NOT_CHECKED;
1087 switch(p_optype) {
1088 case OPTYPE_SUBSTR:
1089 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1090 u.expr.ti1 = p_ti1;
1091 u.expr.v2=p_v2;
1092 u.expr.v3=p_v3;
1093 break;
1094 default:
1095 FATAL_ERROR("Value::Value()");
1096 } // switch
1097 }
1098
1099 // ti1 t2 v3
1100 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1101 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1102 {
1103 u.expr.v_optype=p_optype;
1104 u.expr.state=EXPR_NOT_CHECKED;
1105 switch(p_optype) {
1106 case OPTYPE_REGEXP:
1107 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1108 u.expr.ti1 = p_ti1;
1109 u.expr.t2 = p_t2;
1110 u.expr.v3=p_v3;
1111 break;
1112 default:
1113 FATAL_ERROR("Value::Value()");
1114 } // switch
1115 }
1116
1117 // v1 t2
1118 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1119 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1120 {
1121 u.expr.v_optype = p_optype;
1122 u.expr.state = EXPR_NOT_CHECKED;
1123 switch(p_optype) {
1124 case OPTYPE_MATCH:
1125 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1126 u.expr.v1=p_v1;
1127 u.expr.t2=p_t2;
1128 break;
1129 default:
1130 FATAL_ERROR("Value::Value()");
1131 } // switch
1132 }
1133
1134 // r1 i2
1135 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1136 Identifier *p_i2)
1137 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1138 {
1139 u.expr.v_optype = p_optype;
1140 u.expr.state = EXPR_NOT_CHECKED;
1141 switch(p_optype) {
1142 case OPTYPE_ISCHOSEN:
1143 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1144 u.expr.r1=p_r1;
1145 u.expr.i2=p_i2;
1146 break;
1147 default:
1148 FATAL_ERROR("Value::Value()");
1149 } // switch
1150 }
1151
1152 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1153 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1154 {
1155 u.expr.v_optype = p_optype;
1156 u.expr.state = EXPR_NOT_CHECKED;
1157 switch(p_optype) {
1158 case OPTYPE_LOG2STR:
1159 if (!p_logargs) FATAL_ERROR("Value::Value()");
1160 u.expr.logargs = p_logargs;
1161 break;
1162 default:
1163 FATAL_ERROR("Value::Value()");
1164 } // switch
1165 }
1166
1167 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1168 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1169 {
1170 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1171 switch (p_macrotype) {
1172 case MACRO_MODULEID:
1173 case MACRO_FILENAME:
1174 case MACRO_BFILENAME:
1175 case MACRO_FILEPATH:
1176 case MACRO_LINENUMBER:
1177 case MACRO_LINENUMBER_C:
1178 case MACRO_DEFINITIONID:
1179 case MACRO_SCOPE:
1180 case MACRO_TESTCASEID:
1181 break;
1182 default:
1183 FATAL_ERROR("Value::Value()");
1184 }
1185 u.macro = p_macrotype;
1186 }
1187
1188 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1189 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1190 {
1191 if(!p_nvs) FATAL_ERROR("NULL parameter");
1192 switch(valuetype) {
1193 case V_SEQ:
1194 case V_SET:
1195 u.val_nvs=p_nvs;
1196 break;
1197 default:
1198 FATAL_ERROR("Value::Value()");
1199 } // switch
1200 }
1201
1202 Value::Value(valuetype_t p_vt, Reference *p_ref)
1203 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1204 {
1205 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1206 switch(p_vt) {
1207 case V_REFD:
1208 u.ref.ref = p_ref;
1209 u.ref.refd_last = 0;
1210 break;
1211 case V_REFER:
1212 u.refered = p_ref;
1213 break;
1214 default:
1215 FATAL_ERROR("Value::Value()");
1216 }
1217 }
1218
1219 Value::Value(valuetype_t p_vt, Block *p_block)
1220 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1221 {
1222 if(!p_block) FATAL_ERROR("NULL parameter");
1223 switch(valuetype) {
1224 case V_UNDEF_BLOCK:
1225 u.block=p_block;
1226 break;
1227 default:
1228 FATAL_ERROR("Value::Value()");
1229 } // switch
1230 }
1231
1232 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1233 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1234 {
1235 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1236 switch (p_verdict) {
1237 case Verdict_NONE:
1238 case Verdict_PASS:
1239 case Verdict_INCONC:
1240 case Verdict_FAIL:
1241 case Verdict_ERROR:
1242 break;
1243 default:
1244 FATAL_ERROR("Value::Value()");
1245 } // switch
1246 u.verdict = p_verdict;
1247 }
1248
1249 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1250 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1251 {
1252 u.expr.v_optype = p_optype;
1253 u.expr.state = EXPR_NOT_CHECKED;
1254 switch(p_optype) {
1255 case OPTYPE_DECODE:
1256 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1257 u.expr.r1=p_r1;
1258 u.expr.r2=p_r2;
1259 break;
1260 default:
1261 FATAL_ERROR("Value::Value()");
1262 } // switch
1263 }
1264
1265 Value::~Value()
1266 {
1267 clean_up();
1268 }
1269
1270 Value *Value::clone() const
1271 {
1272 return new Value(*this);
1273 }
1274
1275 Value::operationtype_t Value::get_optype() const
1276 {
1277 if(valuetype!=V_EXPR)
1278 FATAL_ERROR("Value::get_optype()");
1279 return u.expr.v_optype;
1280 }
1281
1282 void Value::set_my_governor(Type *p_gov)
1283 {
1284 if(!p_gov)
1285 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1286 my_governor=p_gov;
1287 }
1288
1289 Type *Value::get_my_governor() const
1290 {
1291 return my_governor;
1292 }
1293
1294 void Value::set_fullname(const string& p_fullname)
1295 {
1296 GovernedSimple::set_fullname(p_fullname);
1297 switch(valuetype) {
1298 case V_CHARSYMS:
1299 u.char_syms->set_fullname(p_fullname);
1300 break;
1301 case V_OID:
1302 case V_ROID:
1303 for(size_t i=0; i<u.oid_comps->size(); i++)
1304 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1305 break;
1306 case V_CHOICE:
1307 u.choice.alt_value->set_fullname(p_fullname + "." +
1308 u.choice.alt_name->get_dispname());
1309 break;
1310 case V_SEQOF:
1311 case V_SETOF:
1312 case V_ARRAY:
1313 u.val_vs->set_fullname(p_fullname);
1314 break;
1315 case V_SEQ:
1316 case V_SET:
1317 u.val_nvs->set_fullname(p_fullname);
1318 break;
1319 case V_REFD:
1320 u.ref.ref->set_fullname(p_fullname);
1321 break;
1322 case V_REFER:
1323 u.refered->set_fullname(p_fullname);
1324 break;
1325 case V_INVOKE:
1326 u.invoke.v->set_fullname(p_fullname);
1327 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1328 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1329 break;
1330 case V_EXPR:
1331 set_fullname_expr(p_fullname);
1332 break;
1333 default:
1334 break;
1335 } // switch
1336 }
1337
1338 void Value::set_my_scope(Scope *p_scope)
1339 {
1340 GovernedSimple::set_my_scope(p_scope);
1341 switch(valuetype) {
1342 case V_CHARSYMS:
1343 u.char_syms->set_my_scope(p_scope);
1344 break;
1345 case V_OID:
1346 case V_ROID:
1347 for(size_t i=0; i<u.oid_comps->size(); i++)
1348 (*u.oid_comps)[i]->set_my_scope(p_scope);
1349 break;
1350 case V_CHOICE:
1351 u.choice.alt_value->set_my_scope(p_scope);
1352 break;
1353 case V_SEQOF:
1354 case V_SETOF:
1355 case V_ARRAY:
1356 u.val_vs->set_my_scope(p_scope);
1357 break;
1358 case V_SEQ:
1359 case V_SET:
1360 u.val_nvs->set_my_scope(p_scope);
1361 break;
1362 case V_REFD:
1363 u.ref.ref->set_my_scope(p_scope);
1364 break;
1365 case V_REFER:
1366 u.refered->set_my_scope(p_scope);
1367 break;
1368 case V_INVOKE:
1369 u.invoke.v->set_my_scope(p_scope);
1370 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1371 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1372 break;
1373 case V_EXPR:
1374 set_my_scope_expr(p_scope);
1375 break;
1376 default:
1377 break;
1378 } // switch
1379 }
1380
1381 void Value::set_fullname_expr(const string& p_fullname)
1382 {
1383 switch (u.expr.v_optype) {
1384 case OPTYPE_RND: // -
1385 case OPTYPE_COMP_NULL:
1386 case OPTYPE_COMP_MTC:
1387 case OPTYPE_COMP_SYSTEM:
1388 case OPTYPE_COMP_SELF:
1389 case OPTYPE_COMP_RUNNING_ANY:
1390 case OPTYPE_COMP_RUNNING_ALL:
1391 case OPTYPE_COMP_ALIVE_ANY:
1392 case OPTYPE_COMP_ALIVE_ALL:
1393 case OPTYPE_TMR_RUNNING_ANY:
1394 case OPTYPE_GETVERDICT:
1395 case OPTYPE_TESTCASENAME:
1396 case OPTYPE_PROF_RUNNING:
1397 break;
1398 case OPTYPE_UNARYPLUS: // v1
1399 case OPTYPE_UNARYMINUS:
1400 case OPTYPE_NOT:
1401 case OPTYPE_NOT4B:
1402 case OPTYPE_BIT2HEX:
1403 case OPTYPE_BIT2INT:
1404 case OPTYPE_BIT2OCT:
1405 case OPTYPE_BIT2STR:
1406 case OPTYPE_CHAR2INT:
1407 case OPTYPE_CHAR2OCT:
1408 case OPTYPE_COMP_RUNNING:
1409 case OPTYPE_COMP_ALIVE:
1410 case OPTYPE_FLOAT2INT:
1411 case OPTYPE_FLOAT2STR:
1412 case OPTYPE_HEX2BIT:
1413 case OPTYPE_HEX2INT:
1414 case OPTYPE_HEX2OCT:
1415 case OPTYPE_HEX2STR:
1416 case OPTYPE_INT2CHAR:
1417 case OPTYPE_INT2FLOAT:
1418 case OPTYPE_INT2STR:
1419 case OPTYPE_INT2UNICHAR:
1420 case OPTYPE_OCT2BIT:
1421 case OPTYPE_OCT2CHAR:
1422 case OPTYPE_OCT2HEX:
1423 case OPTYPE_OCT2INT:
1424 case OPTYPE_OCT2STR:
1425 case OPTYPE_STR2BIT:
1426 case OPTYPE_STR2FLOAT:
1427 case OPTYPE_STR2HEX:
1428 case OPTYPE_STR2INT:
1429 case OPTYPE_STR2OCT:
1430 case OPTYPE_UNICHAR2INT:
1431 case OPTYPE_UNICHAR2CHAR:
1432 case OPTYPE_ENUM2INT:
1433 case OPTYPE_RNDWITHVAL:
1434 case OPTYPE_REMOVE_BOM:
1435 case OPTYPE_GET_STRINGENCODING:
1436 case OPTYPE_DECODE_BASE64:
1437 u.expr.v1->set_fullname(p_fullname+".<operand>");
1438 break;
1439 case OPTYPE_ADD: // v1 v2
1440 case OPTYPE_SUBTRACT:
1441 case OPTYPE_MULTIPLY:
1442 case OPTYPE_DIVIDE:
1443 case OPTYPE_MOD:
1444 case OPTYPE_REM:
1445 case OPTYPE_CONCAT:
1446 case OPTYPE_EQ:
1447 case OPTYPE_LT:
1448 case OPTYPE_GT:
1449 case OPTYPE_NE:
1450 case OPTYPE_GE:
1451 case OPTYPE_LE:
1452 case OPTYPE_AND:
1453 case OPTYPE_OR:
1454 case OPTYPE_XOR:
1455 case OPTYPE_AND4B:
1456 case OPTYPE_OR4B:
1457 case OPTYPE_XOR4B:
1458 case OPTYPE_SHL:
1459 case OPTYPE_SHR:
1460 case OPTYPE_ROTL:
1461 case OPTYPE_ROTR:
1462 case OPTYPE_INT2BIT:
1463 case OPTYPE_INT2HEX:
1464 case OPTYPE_INT2OCT:
1465 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1466 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1467 break;
1468 case OPTYPE_UNICHAR2OCT:
1469 case OPTYPE_OCT2UNICHAR:
1470 case OPTYPE_ENCODE_BASE64:
1471 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1472 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1473 break;
1474 case OPTYPE_DECODE:
1475 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1476 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1477 break;
1478 case OPTYPE_SUBSTR:
1479 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1480 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1481 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1482 break;
1483 case OPTYPE_REGEXP:
1484 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1485 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1486 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1487 break;
1488 case OPTYPE_DECOMP: // v1 v2 v3
1489 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1490 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1491 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1492 break;
1493 case OPTYPE_REPLACE:
1494 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1495 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1496 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1497 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1498 break;
1499 case OPTYPE_LENGTHOF: // ti1
1500 case OPTYPE_SIZEOF: // ti1
1501 case OPTYPE_VALUEOF: // ti1
1502 case OPTYPE_ISVALUE:
1503 case OPTYPE_ISBOUND:
1504 case OPTYPE_ENCODE:
1505 case OPTYPE_ISPRESENT:
1506 case OPTYPE_TTCN2STRING:
1507 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1508 break;
1509 case OPTYPE_UNDEF_RUNNING: // r1
1510 case OPTYPE_TMR_READ:
1511 case OPTYPE_TMR_RUNNING:
1512 case OPTYPE_ACTIVATE:
1513 u.expr.r1->set_fullname(p_fullname+".<operand>");
1514 break;
1515 case OPTYPE_EXECUTE: // r1 [v2]
1516 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1517 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1518 break;
1519 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1520 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1521 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1522 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1523 break;
1524 case OPTYPE_MATCH: // v1 t2
1525 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1526 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1527 break;
1528 case OPTYPE_ISCHOSEN: // r1 i2
1529 u.expr.r1->set_fullname(p_fullname+".<operand>");
1530 break;
1531 case OPTYPE_ISCHOSEN_V: // v1 i2
1532 u.expr.v1->set_fullname(p_fullname+".<operand>");
1533 break;
1534 case OPTYPE_ISCHOSEN_T: // t1 i2
1535 u.expr.t1->set_fullname(p_fullname+".<operand>");
1536 break;
1537 case OPTYPE_ACTIVATE_REFD:
1538 u.expr.v1->set_fullname(p_fullname+".<reference>");
1539 if(u.expr.state!=EXPR_CHECKED)
1540 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1541 else
1542 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1543 break;
1544 case OPTYPE_EXECUTE_REFD:
1545 u.expr.v1->set_fullname(p_fullname+".<reference>");
1546 if(u.expr.state!=EXPR_CHECKED)
1547 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1548 else
1549 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1550 if(u.expr.v3)
1551 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1552 break;
1553 case OPTYPE_LOG2STR:
1554 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1555 break;
1556 default:
1557 FATAL_ERROR("Value::set_fullname_expr()");
1558 } // switch
1559 }
1560
1561 void Value::set_my_scope_expr(Scope *p_scope)
1562 {
1563 switch (u.expr.v_optype) {
1564 case OPTYPE_RND: // -
1565 case OPTYPE_COMP_NULL:
1566 case OPTYPE_COMP_MTC:
1567 case OPTYPE_COMP_SYSTEM:
1568 case OPTYPE_COMP_SELF:
1569 case OPTYPE_COMP_RUNNING_ANY:
1570 case OPTYPE_COMP_RUNNING_ALL:
1571 case OPTYPE_COMP_ALIVE_ANY:
1572 case OPTYPE_COMP_ALIVE_ALL:
1573 case OPTYPE_TMR_RUNNING_ANY:
1574 case OPTYPE_GETVERDICT:
1575 case OPTYPE_TESTCASENAME:
1576 case OPTYPE_PROF_RUNNING:
1577 break;
1578 case OPTYPE_UNARYPLUS: // v1
1579 case OPTYPE_UNARYMINUS:
1580 case OPTYPE_NOT:
1581 case OPTYPE_NOT4B:
1582 case OPTYPE_BIT2HEX:
1583 case OPTYPE_BIT2INT:
1584 case OPTYPE_BIT2OCT:
1585 case OPTYPE_BIT2STR:
1586 case OPTYPE_CHAR2INT:
1587 case OPTYPE_CHAR2OCT:
1588 case OPTYPE_COMP_RUNNING:
1589 case OPTYPE_COMP_ALIVE:
1590 case OPTYPE_FLOAT2INT:
1591 case OPTYPE_FLOAT2STR:
1592 case OPTYPE_HEX2BIT:
1593 case OPTYPE_HEX2INT:
1594 case OPTYPE_HEX2OCT:
1595 case OPTYPE_HEX2STR:
1596 case OPTYPE_INT2CHAR:
1597 case OPTYPE_INT2FLOAT:
1598 case OPTYPE_INT2STR:
1599 case OPTYPE_INT2UNICHAR:
1600 case OPTYPE_OCT2BIT:
1601 case OPTYPE_OCT2CHAR:
1602 case OPTYPE_OCT2HEX:
1603 case OPTYPE_OCT2INT:
1604 case OPTYPE_OCT2STR:
1605 case OPTYPE_STR2BIT:
1606 case OPTYPE_STR2FLOAT:
1607 case OPTYPE_STR2HEX:
1608 case OPTYPE_STR2INT:
1609 case OPTYPE_STR2OCT:
1610 case OPTYPE_UNICHAR2INT:
1611 case OPTYPE_UNICHAR2CHAR:
1612 case OPTYPE_ENUM2INT:
1613 case OPTYPE_RNDWITHVAL:
1614 case OPTYPE_REMOVE_BOM:
1615 case OPTYPE_GET_STRINGENCODING:
1616 case OPTYPE_DECODE_BASE64:
1617 u.expr.v1->set_my_scope(p_scope);
1618 break;
1619 case OPTYPE_ADD: // v1 v2
1620 case OPTYPE_SUBTRACT:
1621 case OPTYPE_MULTIPLY:
1622 case OPTYPE_DIVIDE:
1623 case OPTYPE_MOD:
1624 case OPTYPE_REM:
1625 case OPTYPE_CONCAT:
1626 case OPTYPE_EQ:
1627 case OPTYPE_LT:
1628 case OPTYPE_GT:
1629 case OPTYPE_NE:
1630 case OPTYPE_GE:
1631 case OPTYPE_LE:
1632 case OPTYPE_AND:
1633 case OPTYPE_OR:
1634 case OPTYPE_XOR:
1635 case OPTYPE_AND4B:
1636 case OPTYPE_OR4B:
1637 case OPTYPE_XOR4B:
1638 case OPTYPE_SHL:
1639 case OPTYPE_SHR:
1640 case OPTYPE_ROTL:
1641 case OPTYPE_ROTR:
1642 case OPTYPE_INT2BIT:
1643 case OPTYPE_INT2HEX:
1644 case OPTYPE_INT2OCT:
1645 u.expr.v1->set_my_scope(p_scope);
1646 u.expr.v2->set_my_scope(p_scope);
1647 break;
1648 case OPTYPE_UNICHAR2OCT:
1649 case OPTYPE_OCT2UNICHAR:
1650 case OPTYPE_ENCODE_BASE64:
1651 u.expr.v1->set_my_scope(p_scope);
1652 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1653 break;
1654 case OPTYPE_DECODE:
1655 u.expr.r1->set_my_scope(p_scope);
1656 u.expr.r2->set_my_scope(p_scope);
1657 break;
1658 case OPTYPE_SUBSTR:
1659 u.expr.ti1->set_my_scope(p_scope);
1660 u.expr.v2->set_my_scope(p_scope);
1661 u.expr.v3->set_my_scope(p_scope);
1662 break;
1663 case OPTYPE_REGEXP:
1664 u.expr.ti1->set_my_scope(p_scope);
1665 u.expr.t2->set_my_scope(p_scope);
1666 u.expr.v3->set_my_scope(p_scope);
1667 break;
1668 case OPTYPE_DECOMP: // v1 v2 v3
1669 u.expr.v1->set_my_scope(p_scope);
1670 u.expr.v2->set_my_scope(p_scope);
1671 u.expr.v3->set_my_scope(p_scope);
1672 break;
1673 case OPTYPE_REPLACE:
1674 u.expr.ti1->set_my_scope(p_scope);
1675 u.expr.v2->set_my_scope(p_scope);
1676 u.expr.v3->set_my_scope(p_scope);
1677 u.expr.ti4->set_my_scope(p_scope);
1678 break;
1679 case OPTYPE_LENGTHOF: // ti1
1680 case OPTYPE_SIZEOF: // ti1
1681 case OPTYPE_VALUEOF: // ti1
1682 case OPTYPE_ISVALUE:
1683 case OPTYPE_ISBOUND:
1684 case OPTYPE_ENCODE:
1685 case OPTYPE_ISPRESENT:
1686 case OPTYPE_TTCN2STRING:
1687 u.expr.ti1->set_my_scope(p_scope);
1688 break;
1689 case OPTYPE_UNDEF_RUNNING: // r1
1690 case OPTYPE_TMR_READ:
1691 case OPTYPE_TMR_RUNNING:
1692 case OPTYPE_ACTIVATE:
1693 u.expr.r1->set_my_scope(p_scope);
1694 break;
1695 case OPTYPE_EXECUTE: // r1 [v2]
1696 u.expr.r1->set_my_scope(p_scope);
1697 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1698 break;
1699 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1700 u.expr.r1->set_my_scope(p_scope);
1701 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1702 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1703 break;
1704 case OPTYPE_MATCH: // v1 t2
1705 u.expr.v1->set_my_scope(p_scope);
1706 u.expr.t2->set_my_scope(p_scope);
1707 break;
1708 case OPTYPE_ISCHOSEN: // r1 i2
1709 u.expr.r1->set_my_scope(p_scope);
1710 break;
1711 case OPTYPE_ISCHOSEN_V: // v1 i2
1712 u.expr.v1->set_my_scope(p_scope);
1713 break;
1714 case OPTYPE_ISCHOSEN_T: // t1 i2
1715 u.expr.t1->set_my_scope(p_scope);
1716 break;
1717 case OPTYPE_ACTIVATE_REFD:
1718 u.expr.v1->set_my_scope(p_scope);
1719 if(u.expr.state!=EXPR_CHECKED) {
1720 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1721 else
1722 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1723 } break;
1724 case OPTYPE_EXECUTE_REFD:
1725 u.expr.v1->set_my_scope(p_scope);
1726 if(u.expr.state!=EXPR_CHECKED) {
1727 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1728 else
1729 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1730 }
1731 if(u.expr.v3)
1732 u.expr.v3->set_my_scope(p_scope);
1733 break;
1734 case OPTYPE_LOG2STR:
1735 u.expr.logargs->set_my_scope(p_scope);
1736 break;
1737 default:
1738 FATAL_ERROR("Value::set_my_scope_expr()");
1739 } // switch
1740 }
1741
1742 void Value::set_genname_recursive(const string& p_genname)
1743 {
1744 size_t genname_len = p_genname.size();
1745 if (genname_len >= 4 &&
1746 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1747 // if the genname ends with ()() (i.e. the value stands for an optional
1748 // field) then drop the last () from the own genname, but leave it for
1749 // the embedded values
1750 set_genname(p_genname.substr(0, genname_len - 2));
1751 } else set_genname(p_genname);
1752 switch(valuetype) {
1753 case V_CHOICE: {
1754 string embedded_genname(p_genname);
1755 embedded_genname += '.';
1756 // If this is a choice value for an anytype, prepend the AT_ prefix
1757 // to the name of the alternative. The genname is used later in
1758 // Common::Value::generate_code_init_se()
1759 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1760 embedded_genname += "AT_";
1761 embedded_genname += u.choice.alt_name->get_name();
1762 embedded_genname += "()";
1763 u.choice.alt_value->set_genname_recursive(embedded_genname);
1764 break; }
1765 case V_SEQOF:
1766 case V_SETOF: {
1767 if (!is_indexed()) {
1768 size_t nof_vs = u.val_vs->get_nof_vs();
1769 for (size_t i = 0; i < nof_vs; i++) {
1770 string embedded_genname(p_genname);
1771 embedded_genname += '[';
1772 embedded_genname += Int2string(i);
1773 embedded_genname += ']';
1774 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1775 }
1776 } else {
1777 size_t nof_ivs = u.val_vs->get_nof_ivs();
1778 for (size_t i = 0; i < nof_ivs; i++) {
1779 string embedded_genname(p_genname);
1780 embedded_genname += '[';
1781 embedded_genname += Int2string(i);
1782 embedded_genname += ']';
1783 u.val_vs->get_iv_byIndex(i)->get_value()
1784 ->set_genname_recursive(embedded_genname);
1785 }
1786 }
1787 break; }
1788 case V_ARRAY: {
1789 if (!my_governor) return; // error recovery
1790 Type *type = my_governor->get_type_refd_last();
1791 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1792 Int offset = type->get_dimension()->get_offset();
1793 if (!is_indexed()) {
1794 size_t nof_vs = u.val_vs->get_nof_vs();
1795 for (size_t i = 0; i < nof_vs; i++) {
1796 string embedded_genname(p_genname);
1797 embedded_genname += '[';
1798 embedded_genname += Int2string(offset + i);
1799 embedded_genname += ']';
1800 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1801 }
1802 } else {
1803 size_t nof_ivs = u.val_vs->get_nof_ivs();
1804 for (size_t i = 0; i < nof_ivs; i++) {
1805 string embedded_genname(p_genname);
1806 embedded_genname += '[';
1807 embedded_genname += Int2string(offset + i);
1808 embedded_genname += ']';
1809 u.val_vs->get_iv_byIndex(i)->get_value()
1810 ->set_genname_recursive(embedded_genname);
1811 }
1812 }
1813 break; }
1814 case V_SEQ:
1815 case V_SET: {
1816 if (!my_governor) return; // error recovery
1817 Type *t = my_governor->get_type_refd_last();
1818 if (!t->is_secho()) return; // error recovery
1819 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1820 for (size_t i = 0; i < nof_nvs; i++) {
1821 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1822 const Identifier& id = nv->get_name();
1823 if (!t->has_comp_withName(id)) return; // error recovery
1824 string embedded_genname(p_genname);
1825 embedded_genname += '.';
1826 embedded_genname += id.get_name();
1827 embedded_genname += "()";
1828 if (t->get_comp_byName(id)->get_is_optional())
1829 embedded_genname += "()";
1830 nv->get_value()->set_genname_recursive(embedded_genname);
1831 }
1832 break; }
1833 default:
1834 break;
1835 } // switch
1836 }
1837
1838 void Value::set_genname_prefix(const char *p_genname_prefix)
1839 {
1840 GovernedSimple::set_genname_prefix(p_genname_prefix);
1841 switch(valuetype) {
1842 case V_CHOICE:
1843 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1844 break;
1845 case V_SEQOF:
1846 case V_SETOF:
1847 case V_ARRAY:
1848 if (!is_indexed()) {
1849 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1850 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1851 } else {
1852 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1853 u.val_vs->get_iv_byIndex(i)->get_value()
1854 ->set_genname_prefix(p_genname_prefix);
1855 }
1856 break;
1857 case V_SEQ:
1858 case V_SET:
1859 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1860 u.val_nvs->get_nv_byIndex(i)->get_value()
1861 ->set_genname_prefix(p_genname_prefix);
1862 break;
1863 default:
1864 break;
1865 } // switch
1866 }
1867
1868 void Value::set_code_section(code_section_t p_code_section)
1869 {
1870 GovernedSimple::set_code_section(p_code_section);
1871 switch(valuetype) {
1872 case V_EXPR:
1873 switch (u.expr.v_optype) {
1874 case OPTYPE_RND: // -
1875 case OPTYPE_COMP_NULL:
1876 case OPTYPE_COMP_MTC:
1877 case OPTYPE_COMP_SYSTEM:
1878 case OPTYPE_COMP_SELF:
1879 case OPTYPE_COMP_RUNNING_ANY:
1880 case OPTYPE_COMP_RUNNING_ALL:
1881 case OPTYPE_COMP_ALIVE_ANY:
1882 case OPTYPE_COMP_ALIVE_ALL:
1883 case OPTYPE_TMR_RUNNING_ANY:
1884 case OPTYPE_GETVERDICT:
1885 case OPTYPE_TESTCASENAME:
1886 case OPTYPE_PROF_RUNNING:
1887 break;
1888 case OPTYPE_UNARYPLUS: // v1
1889 case OPTYPE_UNARYMINUS:
1890 case OPTYPE_NOT:
1891 case OPTYPE_NOT4B:
1892 case OPTYPE_BIT2HEX:
1893 case OPTYPE_BIT2INT:
1894 case OPTYPE_BIT2OCT:
1895 case OPTYPE_BIT2STR:
1896 case OPTYPE_CHAR2INT:
1897 case OPTYPE_CHAR2OCT:
1898 case OPTYPE_COMP_RUNNING:
1899 case OPTYPE_COMP_ALIVE:
1900 case OPTYPE_FLOAT2INT:
1901 case OPTYPE_FLOAT2STR:
1902 case OPTYPE_HEX2BIT:
1903 case OPTYPE_HEX2INT:
1904 case OPTYPE_HEX2OCT:
1905 case OPTYPE_HEX2STR:
1906 case OPTYPE_INT2CHAR:
1907 case OPTYPE_INT2FLOAT:
1908 case OPTYPE_INT2STR:
1909 case OPTYPE_INT2UNICHAR:
1910 case OPTYPE_OCT2BIT:
1911 case OPTYPE_OCT2CHAR:
1912 case OPTYPE_OCT2HEX:
1913 case OPTYPE_OCT2INT:
1914 case OPTYPE_OCT2STR:
1915 case OPTYPE_STR2BIT:
1916 case OPTYPE_STR2FLOAT:
1917 case OPTYPE_STR2HEX:
1918 case OPTYPE_STR2INT:
1919 case OPTYPE_STR2OCT:
1920 case OPTYPE_UNICHAR2INT:
1921 case OPTYPE_UNICHAR2CHAR:
1922 case OPTYPE_ENUM2INT:
1923 case OPTYPE_RNDWITHVAL:
1924 case OPTYPE_GET_STRINGENCODING:
1925 case OPTYPE_DECODE_BASE64:
1926 case OPTYPE_REMOVE_BOM:
1927 u.expr.v1->set_code_section(p_code_section);
1928 break;
1929 case OPTYPE_ADD: // v1 v2
1930 case OPTYPE_SUBTRACT:
1931 case OPTYPE_MULTIPLY:
1932 case OPTYPE_DIVIDE:
1933 case OPTYPE_MOD:
1934 case OPTYPE_REM:
1935 case OPTYPE_CONCAT:
1936 case OPTYPE_EQ:
1937 case OPTYPE_LT:
1938 case OPTYPE_GT:
1939 case OPTYPE_NE:
1940 case OPTYPE_GE:
1941 case OPTYPE_LE:
1942 case OPTYPE_AND:
1943 case OPTYPE_OR:
1944 case OPTYPE_XOR:
1945 case OPTYPE_AND4B:
1946 case OPTYPE_OR4B:
1947 case OPTYPE_XOR4B:
1948 case OPTYPE_SHL:
1949 case OPTYPE_SHR:
1950 case OPTYPE_ROTL:
1951 case OPTYPE_ROTR:
1952 case OPTYPE_INT2BIT:
1953 case OPTYPE_INT2HEX:
1954 case OPTYPE_INT2OCT:
1955 u.expr.v1->set_code_section(p_code_section);
1956 u.expr.v2->set_code_section(p_code_section);
1957 break;
1958 case OPTYPE_UNICHAR2OCT:
1959 case OPTYPE_OCT2UNICHAR:
1960 case OPTYPE_ENCODE_BASE64:
1961 u.expr.v1->set_code_section(p_code_section);
1962 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
1963 break;
1964 case OPTYPE_DECODE:
1965 u.expr.r1->set_code_section(p_code_section);
1966 u.expr.r2->set_code_section(p_code_section);
1967 break;
1968 case OPTYPE_SUBSTR:
1969 u.expr.ti1->set_code_section(p_code_section);
1970 u.expr.v2->set_code_section(p_code_section);
1971 u.expr.v3->set_code_section(p_code_section);
1972 break;
1973 case OPTYPE_REGEXP:
1974 u.expr.ti1->set_code_section(p_code_section);
1975 u.expr.t2->set_code_section(p_code_section);
1976 u.expr.v3->set_code_section(p_code_section);
1977 break;
1978 case OPTYPE_DECOMP: // v1 v2 v3
1979 u.expr.v1->set_code_section(p_code_section);
1980 u.expr.v2->set_code_section(p_code_section);
1981 u.expr.v3->set_code_section(p_code_section);
1982 break;
1983 case OPTYPE_REPLACE:
1984 u.expr.ti1->set_code_section(p_code_section);
1985 u.expr.v2->set_code_section(p_code_section);
1986 u.expr.v3->set_code_section(p_code_section);
1987 u.expr.ti4->set_code_section(p_code_section);
1988 break;
1989 case OPTYPE_LENGTHOF: // ti1
1990 case OPTYPE_SIZEOF: // ti1
1991 case OPTYPE_VALUEOF: // ti1
1992 case OPTYPE_ISVALUE:
1993 case OPTYPE_ISBOUND:
1994 case OPTYPE_ENCODE:
1995 case OPTYPE_ISPRESENT:
1996 case OPTYPE_TTCN2STRING:
1997 u.expr.ti1->set_code_section(p_code_section);
1998 break;
1999 case OPTYPE_UNDEF_RUNNING: // r1
2000 case OPTYPE_TMR_READ:
2001 case OPTYPE_TMR_RUNNING:
2002 case OPTYPE_ACTIVATE:
2003 u.expr.r1->set_code_section(p_code_section);
2004 break;
2005 case OPTYPE_EXECUTE: // r1 [v2]
2006 u.expr.r1->set_code_section(p_code_section);
2007 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2008 break;
2009 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2010 u.expr.r1->set_code_section(p_code_section);
2011 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2012 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2013 break;
2014 case OPTYPE_MATCH: // v1 t2
2015 u.expr.v1->set_code_section(p_code_section);
2016 u.expr.t2->set_code_section(p_code_section);
2017 break;
2018 case OPTYPE_ISCHOSEN: // r1 i2
2019 u.expr.r1->set_code_section(p_code_section);
2020 break;
2021 case OPTYPE_ISCHOSEN_V: // v1 i2
2022 u.expr.v1->set_code_section(p_code_section);
2023 break;
2024 case OPTYPE_ISCHOSEN_T: // t1 i2
2025 u.expr.t1->set_code_section(p_code_section);
2026 break;
2027 case OPTYPE_ACTIVATE_REFD:
2028 u.expr.v1->set_code_section(p_code_section);
2029 if(u.expr.state!=EXPR_CHECKED)
2030 u.expr.t_list2->set_code_section(p_code_section);
2031 else {
2032 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2033 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2034 u.expr.state = EXPR_CHECKED;
2035 }
2036 break;
2037 case OPTYPE_EXECUTE_REFD:
2038 u.expr.v1->set_code_section(p_code_section);
2039 if(u.expr.state!=EXPR_CHECKED)
2040 u.expr.t_list2->set_code_section(p_code_section);
2041 else {
2042 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2043 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2044 u.expr.state = EXPR_CHECKED;
2045 }
2046 if(u.expr.v3)
2047 u.expr.v3->set_code_section(p_code_section);
2048 break;
2049 case OPTYPE_LOG2STR:
2050 u.expr.logargs->set_code_section(p_code_section);
2051 break;
2052 default:
2053 FATAL_ERROR("Value::set_code_section()");
2054 } // switch
2055 break;
2056 case V_CHOICE:
2057 u.choice.alt_value->set_code_section(p_code_section);
2058 break;
2059 case V_SEQOF:
2060 case V_SETOF:
2061 case V_ARRAY:
2062 if (!is_indexed()) {
2063 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2064 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2065 } else {
2066 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2067 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2068 }
2069 break;
2070 case V_SEQ:
2071 case V_SET:
2072 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2073 u.val_nvs->get_nv_byIndex(i)->get_value()
2074 ->set_code_section(p_code_section);
2075 break;
2076 case V_REFD:
2077 u.ref.ref->set_code_section(p_code_section);
2078 break;
2079 case V_REFER:
2080 u.refered->set_code_section(p_code_section);
2081 break;
2082 case V_INVOKE:
2083 u.invoke.v->set_code_section(p_code_section);
2084 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2085 if(u.invoke.ap_list)
2086 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2087 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2088 break;
2089 default:
2090 break;
2091 } // switch
2092 }
2093
2094 void Value::change_sign()
2095 {
2096 switch(valuetype) {
2097 case V_INT:
2098 *u.val_Int=-*u.val_Int;
2099 break;
2100 case V_REAL:
2101 u.val_Real*=-1.0;
2102 break;
2103 case V_ERROR:
2104 break;
2105 default:
2106 FATAL_ERROR("Value::change_sign()");
2107 } // switch
2108 }
2109
2110 void Value::add_oid_comp(OID_comp* p_comp)
2111 {
2112 if(!p_comp)
2113 FATAL_ERROR("NULL parameter");
2114 u.oid_comps->add(p_comp);
2115 p_comp->set_fullname(get_fullname()+"."
2116 +Int2string(u.oid_comps->size()));
2117 p_comp->set_my_scope(my_scope);
2118 }
2119
2120 void Value::set_valuetype(valuetype_t p_valuetype)
2121 {
2122 if (valuetype == V_ERROR) return;
2123 else if (p_valuetype == V_ERROR) {
2124 if(valuetype==V_EXPR) {
2125 switch(u.expr.state) {
2126 case EXPR_CHECKING:
2127 u.expr.state=EXPR_CHECKING_ERR;
2128 // no break
2129 case EXPR_CHECKING_ERR:
2130 return;
2131 default:
2132 break;
2133 }
2134 }
2135 clean_up();
2136 valuetype = V_ERROR;
2137 return;
2138 }
2139 switch(valuetype) {
2140 case V_UNDEF_LOWERID:
2141 switch(p_valuetype) {
2142 case V_ENUM:
2143 case V_NAMEDINT:
2144 break;
2145 case V_REFD:
2146 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2147 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2148 u.ref.ref->set_my_scope(get_my_scope());
2149 u.ref.ref->set_fullname(get_fullname());
2150 u.ref.ref->set_location(*this);
2151 u.ref.refd_last = 0;
2152 break;
2153 default:
2154 FATAL_ERROR("Value::set_valuetype()");
2155 } // switch
2156 break;
2157 case V_UNDEF_BLOCK: {
2158 Block *t_block=u.block;
2159 Value *v=0;
2160 switch(p_valuetype) {
2161 case V_NAMEDBITS: {
2162 Node *node=t_block->parse(KW_Block_IdentifierList);
2163 v=dynamic_cast<Value*>(node);
2164 if(!v) {
2165 /* syntax error */
2166 u.ids=new map<string, Identifier>();
2167 }
2168 else {
2169 u.ids=v->u.ids; v->u.ids=0;
2170 }
2171 break;}
2172 case V_SEQOF: {
2173 Node *node=t_block->parse(KW_Block_SeqOfValue);
2174 v=dynamic_cast<Value*>(node);
2175 if(!v) {
2176 /* syntax error */
2177 u.val_vs=new Values();
2178 }
2179 else {
2180 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2181 }
2182 u.val_vs->set_my_scope(get_my_scope());
2183 u.val_vs->set_fullname(get_fullname());
2184 break;}
2185 case V_SETOF: {
2186 Node *node=t_block->parse(KW_Block_SetOfValue);
2187 v=dynamic_cast<Value*>(node);
2188 if(!v) {
2189 /* syntax error */
2190 u.val_vs=new Values();
2191 }
2192 else {
2193 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2194 }
2195 u.val_vs->set_my_scope(get_my_scope());
2196 u.val_vs->set_fullname(get_fullname());
2197 break;}
2198 case V_SEQ: {
2199 Node *node=t_block->parse(KW_Block_SequenceValue);
2200 v=dynamic_cast<Value*>(node);
2201 if(!v) {
2202 /* syntax error */
2203 u.val_nvs=new NamedValues();
2204 }
2205 else {
2206 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2207 }
2208 u.val_nvs->set_my_scope(get_my_scope());
2209 u.val_nvs->set_fullname(get_fullname());
2210 break;}
2211 case V_SET: {
2212 Node *node=t_block->parse(KW_Block_SetValue);
2213 v=dynamic_cast<Value*>(node);
2214 if(!v) {
2215 /* syntax error */
2216 u.val_nvs=new NamedValues();
2217 }
2218 else {
2219 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2220 }
2221 u.val_nvs->set_my_scope(get_my_scope());
2222 u.val_nvs->set_fullname(get_fullname());
2223 break;}
2224 case V_OID: {
2225 Node *node=t_block->parse(KW_Block_OIDValue);
2226 v=dynamic_cast<Value*>(node);
2227 if(!v) {
2228 /* syntax error */
2229 u.oid_comps=new vector<OID_comp>();
2230 }
2231 else {
2232 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2233 }
2234 for (size_t i = 0; i < u.oid_comps->size(); i++)
2235 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2236 break;}
2237 case V_ROID: {
2238 Node *node=t_block->parse(KW_Block_ROIDValue);
2239 v=dynamic_cast<Value*>(node);
2240 if(!v) {
2241 /* syntax error */
2242 u.oid_comps=new vector<OID_comp>();
2243 }
2244 else {
2245 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2246 }
2247 for (size_t i = 0; i < u.oid_comps->size(); i++)
2248 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2249 break;}
2250 case V_CHARSYMS: {
2251 Node *node=t_block->parse(KW_Block_CharStringValue);
2252 u.char_syms=dynamic_cast<CharSyms*>(node);
2253 if(!u.char_syms) {
2254 /* syntax error */
2255 u.char_syms=new CharSyms();
2256 }
2257 u.char_syms->set_my_scope(get_my_scope());
2258 u.char_syms->set_fullname(get_fullname());
2259 break;}
2260 default:
2261 FATAL_ERROR("Value::set_valuetype()");
2262 } // switch
2263 delete v;
2264 delete t_block;
2265 break;}
2266 case V_REFD:
2267 if (p_valuetype == V_USTR) {
2268 Value *v_last = get_value_refd_last();
2269 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2270 ustring *ustr = new ustring(*v_last->u.str.val_str);
2271 delete u.ref.ref;
2272 set_val_ustr(ustr);
2273 u.ustr.convert_str = true; // will be converted back to string
2274 } else FATAL_ERROR("Value::set_valuetype()");
2275 break;
2276 case V_CHARSYMS:
2277 switch(p_valuetype) {
2278 case V_CSTR: {
2279 const string& str = u.char_syms->get_string();
2280 delete u.char_syms;
2281 set_val_str(new string(str));
2282 break;}
2283 case V_USTR: {
2284 const ustring& ustr = u.char_syms->get_ustring();
2285 delete u.char_syms;
2286 set_val_ustr(new ustring(ustr));
2287 u.ustr.convert_str = false;
2288 break;}
2289 case V_ISO2022STR: {
2290 const string& str = u.char_syms->get_iso2022string();
2291 delete u.char_syms;
2292 set_val_str(new string(str));
2293 break;}
2294 default:
2295 FATAL_ERROR("Value::set_valuetype()");
2296 } // switch
2297 break;
2298 case V_INT: {
2299 Real val_Real;
2300 if (p_valuetype == V_REAL)
2301 val_Real = u.val_Int->to_real();
2302 else FATAL_ERROR("Value::set_valuetype()");
2303 clean_up();
2304 u.val_Real = val_Real;
2305 break; }
2306 case V_HSTR: {
2307 clean_up_string_elements(u.str.str_elements);
2308 string *old_str = u.str.val_str;
2309 switch(p_valuetype) {
2310 case V_BSTR:
2311 set_val_str(hex2bit(*old_str));
2312 break;
2313 case V_OSTR:
2314 set_val_str(asn_hex2oct(*old_str));
2315 break;
2316 default:
2317 FATAL_ERROR("Value::set_valuetype()");
2318 } // switch
2319 delete old_str;
2320 break;}
2321 case V_BSTR:
2322 clean_up_string_elements(u.str.str_elements);
2323 if (p_valuetype == V_OSTR) {
2324 string *old_str = u.str.val_str;
2325 set_val_str(asn_bit2oct(*old_str));
2326 delete old_str;
2327 } else FATAL_ERROR("Value::set_valuetype()");
2328 break;
2329 case V_CSTR:
2330 clean_up_string_elements(u.str.str_elements);
2331 switch(p_valuetype) {
2332 case V_USTR: {
2333 string *old_str = u.str.val_str;
2334 set_val_ustr(new ustring(*old_str));
2335 u.ustr.convert_str = true; // will be converted back to string
2336 delete old_str;
2337 break;}
2338 case V_ISO2022STR:
2339 // do nothing
2340 break;
2341 default:
2342 FATAL_ERROR("Value::set_valuetype()");
2343 } // switch p_valuetype
2344 break;
2345 case V_USTR:
2346 clean_up_string_elements(u.ustr.ustr_elements);
2347 switch(p_valuetype) {
2348 case V_CSTR: {
2349 ustring *old_str = u.ustr.val_ustr;
2350 size_t nof_chars = old_str->size();
2351 bool warning_flag = false;
2352 for (size_t i = 0; i < nof_chars; i++) {
2353 const ustring::universal_char& uchar = (*old_str)[i];
2354 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2355 error("This string value cannot contain multiple-byte characters, "
2356 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2357 uchar.group, uchar.plane, uchar.row, uchar.cell,
2358 (unsigned long) i);
2359 p_valuetype = V_ERROR;
2360 break;
2361 } else if (uchar.cell > 127 && !warning_flag) {
2362 warning("This string value may not contain characters with code "
2363 "higher than 127, but it has character with code %u (0x%02X) "
2364 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2365 warning_flag = true;
2366 }
2367 }
2368 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2369 delete old_str;
2370 break; }
2371 case V_ISO2022STR:
2372 error("ISO-10646 string value cannot be converted to "
2373 "ISO-2022 string");
2374 delete u.ustr.val_ustr;
2375 p_valuetype = V_ERROR;
2376 break;
2377 default:
2378 FATAL_ERROR("Value::set_valuetype()");
2379 } // switch p_valuetype
2380 break;
2381 case V_SEQ:
2382 switch (p_valuetype) {
2383 case V_CHOICE: {
2384 NamedValues *nvs = u.val_nvs;
2385 if (nvs->get_nof_nvs() < 1) {
2386 error("Union value must have one active field");
2387 delete nvs;
2388 valuetype = V_ERROR;
2389 return;
2390 } else if (nvs->get_nof_nvs() > 1) {
2391 error("Only one field was expected in union value instead of %lu",
2392 (unsigned long) nvs->get_nof_nvs());
2393 }
2394 NamedValue *nv = nvs->get_nv_byIndex(0);
2395 u.choice.alt_name = nv->get_name().clone();
2396 u.choice.alt_value = nv->steal_value();
2397 delete nvs;
2398 break;}
2399 case V_SET:
2400 // do nothing
2401 break;
2402 case V_REAL: {
2403 NamedValues *nvs = u.val_nvs;
2404 bool err = false;
2405 /* mantissa */
2406 Int i_mant = 0;
2407 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2408 if (nvs->has_nv_withName(id_mant)) {
2409 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2410 ->get_value_refd_last();
2411 if (v_tmp->get_valuetype() == V_INT) {
2412 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2413 if (*i_mant_int > INT_MAX) {
2414 error("Mantissa `%s' should be less than `%d'",
2415 (i_mant_int->t_str()).c_str(), INT_MAX);
2416 err = true;
2417 } else {
2418 i_mant = i_mant_int->get_val();
2419 }
2420 }
2421 else err = true;
2422 }
2423 else err = true;
2424 /* base */
2425 Int i_base = 0;
2426 Identifier id_base(Identifier::ID_ASN, string("base"));
2427 if (!err && nvs->has_nv_withName(id_base)) {
2428 Value *v = nvs->get_nv_byName(id_base)->get_value();
2429 Value *v_tmp = v->get_value_refd_last();
2430 if (v_tmp->get_valuetype() == V_INT) {
2431 const int_val_t *i_base_int = v_tmp->get_val_Int();
2432 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2433 v->error("Base of the REAL must be 2 or 10");
2434 err = true;
2435 } else {
2436 i_base = i_base_int->get_val();
2437 }
2438 }
2439 else err = true;
2440 }
2441 else err = true;
2442 /* exponent */
2443 Int i_exp = 0;
2444 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2445 if (!err && nvs->has_nv_withName(id_exp)) {
2446 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2447 ->get_value_refd_last();
2448 if (v_tmp->get_valuetype() == V_INT) {
2449 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2450 if (*i_exp_int > INT_MAX) {
2451 error("Exponent `%s' should be less than `%d'",
2452 (i_exp_int->t_str()).c_str(), INT_MAX);
2453 err = true;
2454 } else {
2455 i_exp = i_exp_int->get_val();
2456 }
2457 }
2458 else err = true;
2459 }
2460 else err = true;
2461 /* clean up */
2462 delete nvs;
2463 if (err) {
2464 valuetype = V_ERROR;
2465 return;
2466 }
2467 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2468 static_cast<double>(i_exp));
2469 break; }
2470 default:
2471 FATAL_ERROR("Value::set_valuetype()");
2472 } // switch
2473 break;
2474 case V_SEQOF:
2475 switch (p_valuetype) {
2476 case V_SEQ: {
2477 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2478 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2479 Type *t = my_governor->get_type_refd_last();
2480 switch (t->get_typetype()) {
2481 case Type::T_SEQ_T:
2482 case Type::T_SEQ_A:
2483 break;
2484 default:
2485 FATAL_ERROR("Value::set_valuetype()");
2486 }
2487 Values *vals = u.val_vs;
2488 size_t nof_vals = vals->get_nof_vs();
2489 size_t nof_comps = t->get_nof_comps();
2490 if (nof_vals > nof_comps) {
2491 error("Too many elements in value list notation for type `%s': "
2492 "%lu was expected instead of %lu",
2493 t->get_typename().c_str(),
2494 (unsigned long)nof_comps, (unsigned long)nof_vals);
2495 }
2496 size_t upper_limit;
2497 bool allnotused;
2498 if (nof_vals <= nof_comps) {
2499 upper_limit = nof_vals;
2500 allnotused = true;
2501 } else {
2502 upper_limit = nof_comps;
2503 allnotused = false;
2504 }
2505 u.val_nvs = new NamedValues;
2506 for (size_t i = 0; i < upper_limit; i++) {
2507 Value *v = vals->steal_v_byIndex(i);
2508 if (v->valuetype != V_NOTUSED) {
2509 allnotused = false;
2510 }
2511 NamedValue *nv =
2512 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2513 nv->set_location(*v);
2514 u.val_nvs->add_nv(nv);
2515 }
2516 u.val_nvs->set_my_scope(get_my_scope());
2517 u.val_nvs->set_fullname(get_fullname());
2518 delete vals;
2519 if (allnotused && nof_vals > 0)
2520 warning("All elements of value list notation for type `%s' are not "
2521 "used symbols (`-')", t->get_typename().c_str());
2522 break; }
2523 case V_SET:
2524 // { } -> empty set value
2525 if (u.val_vs->get_nof_vs() != 0)
2526 FATAL_ERROR("Value::set_valuetype()");
2527 delete u.val_vs;
2528 u.val_nvs = new NamedValues;
2529 break;
2530 case V_SETOF:
2531 case V_ARRAY:
2532 // SEQOF -> SETOF or ARRAY: trivial
2533 break;
2534 default:
2535 FATAL_ERROR("Value::set_valuetype()");
2536 }
2537 break;
2538 case V_TTCN3_NULL:
2539 switch (p_valuetype) {
2540 case V_DEFAULT_NULL:
2541 break;
2542 case V_FAT_NULL:
2543 break;
2544 default:
2545 FATAL_ERROR("Value::set_valuetype()");
2546 }
2547 break;
2548 case V_NOTUSED:
2549 if (V_OMIT != p_valuetype) { // in case of implicit omit
2550 FATAL_ERROR("Value::set_valuetype()");
2551 }
2552 break;
2553 default:
2554 FATAL_ERROR("Value::set_valuetype()");
2555 } // switch
2556 valuetype=p_valuetype;
2557 }
2558
2559 void Value::set_valuetype_COMP_NULL()
2560 {
2561 if(valuetype == V_ERROR) return;
2562 if(valuetype==V_TTCN3_NULL) {
2563 valuetype=V_EXPR;
2564 u.expr.v_optype=OPTYPE_COMP_NULL;
2565 // Nothing to check.
2566 u.expr.state=EXPR_CHECKED;
2567 }
2568 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2569 }
2570
2571 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2572 {
2573 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2574 delete u.val_id;
2575 u.val_Int = new int_val_t(p_val_int);
2576 valuetype = V_INT;
2577 } else FATAL_ERROR("Value::set_valuetype()");
2578 }
2579
2580 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2581 {
2582 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2583 clean_up();
2584 valuetype = V_BSTR;
2585 set_val_str(p_str);
2586 } else FATAL_ERROR("Value::set_valuetype()");
2587 }
2588
2589 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2590 {
2591 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2592 delete u.val_id;
2593 u.val_id = p_id;
2594 valuetype = V_ENUM;
2595 } else FATAL_ERROR("Value::set_valuetype()");
2596 }
2597
2598 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2599 {
2600 switch (p_valuetype) {
2601 case V_FUNCTION:
2602 case V_ALTSTEP:
2603 case V_TESTCASE:
2604 if (valuetype == V_REFER && p_ass) break;
2605 // no break
2606 default:
2607 FATAL_ERROR("Value::set_valuetype()");
2608 }
2609 delete u.refered;
2610 u.refd_fat = p_ass;
2611 valuetype = p_valuetype;
2612 }
2613
2614 bool Value::is_undef_lowerid()
2615 {
2616 switch (valuetype) {
2617 case V_UNDEF_LOWERID:
2618 return true;
2619 case V_EXPR:
2620 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2621 !u.expr.ti1->get_DerivedRef()) {
2622 return u.expr.ti1->get_Template()->is_undef_lowerid();
2623 }
2624 // no break
2625 default:
2626 return false;
2627 }
2628 }
2629
2630 const Identifier& Value::get_undef_lowerid()
2631 {
2632 switch (valuetype) {
2633 case V_UNDEF_LOWERID:
2634 return *u.val_id;
2635 case V_EXPR:
2636 if (u.expr.v_optype != OPTYPE_VALUEOF)
2637 FATAL_ERROR("Value::get_undef_lowerid()");
2638 return u.expr.ti1->get_Template()->get_specific_value()
2639 ->get_undef_lowerid();
2640 default:
2641 FATAL_ERROR("Value::get_undef_lowerid()");
2642 }
2643 const Identifier *dummy = 0;
2644 return *dummy;
2645 }
2646
2647 void Value::set_lowerid_to_ref()
2648 {
2649 switch (valuetype) {
2650 case V_UNDEF_LOWERID:
2651 set_valuetype(V_REFD);
2652 break;
2653 case V_EXPR:
2654 // if the governor of the expression is not known (in log(), etc...)
2655 // then the governor is taken from the reference (using
2656 // v1/ti1->get_expr_governor()), but that runs before the
2657 // params were checked, this smells like a workaround :)
2658 switch (u.expr.v_optype) {
2659 case OPTYPE_ROTL:
2660 case OPTYPE_ROTR:
2661 u.expr.v1->set_lowerid_to_ref();
2662 break;
2663 case OPTYPE_CONCAT:
2664 u.expr.v1->set_lowerid_to_ref();
2665 u.expr.v2->set_lowerid_to_ref();
2666 break;
2667 case OPTYPE_VALUEOF:
2668 case OPTYPE_ISVALUE:
2669 case OPTYPE_ISBOUND:
2670 case OPTYPE_ISPRESENT:
2671 case OPTYPE_SUBSTR:
2672 case OPTYPE_REGEXP:
2673 case OPTYPE_REPLACE:
2674 case OPTYPE_TTCN2STRING:
2675 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2676 Error_Context cntxt(u.expr.ti1->get_Template(),
2677 "In the operand of operation `%s'",
2678 get_opname());
2679 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2680 }
2681 if (u.expr.v_optype==OPTYPE_REGEXP) {
2682 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2683 Error_Context cntxt(u.expr.t2->get_Template(),
2684 "In the operand of operation `%s'",
2685 get_opname());
2686 u.expr.t2->get_Template()->set_lowerid_to_ref();
2687 }
2688 }
2689 if (u.expr.v_optype==OPTYPE_REPLACE) {
2690 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2691 Error_Context cntxt(u.expr.ti4->get_Template(),
2692 "In the operand of operation `%s'",
2693 get_opname());
2694 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2695 }
2696 }
2697 break;
2698 default:
2699 break;
2700 }
2701 break;
2702 default:
2703 break;
2704 }
2705 }
2706
2707 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2708 {
2709 switch (valuetype) {
2710 case V_CHARSYMS:
2711 case V_CHOICE:
2712 case V_SEQOF:
2713 case V_SETOF:
2714 case V_ARRAY:
2715 case V_SEQ:
2716 case V_SET:
2717 case V_UNDEF_LOWERID:
2718 case V_UNDEF_BLOCK:
2719 case V_OMIT:
2720 case V_TTCN3_NULL:
2721 case V_NOTUSED:
2722 case V_REFER:
2723 case V_FAT_NULL:
2724 return Type::T_UNDEF;
2725 case V_NAMEDINT:
2726 case V_NAMEDBITS:
2727 case V_OPENTYPE:
2728 FATAL_ERROR("Value::get_expr_returntype()");
2729 case V_ERROR:
2730 return Type::T_ERROR;
2731 case V_REFD:
2732 case V_INVOKE: {
2733 Type *t = get_expr_governor(exp_val);
2734 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2735 else return Type::T_ERROR; }
2736 case V_FUNCTION:
2737 return Type::T_FUNCTION;
2738 case V_ALTSTEP:
2739 return Type::T_ALTSTEP;
2740 case V_TESTCASE:
2741 return Type::T_TESTCASE;
2742 case V_EXPR:
2743 switch(u.expr.v_optype) {
2744 case OPTYPE_COMP_NULL:
2745 case OPTYPE_COMP_MTC:
2746 case OPTYPE_COMP_SYSTEM:
2747 case OPTYPE_COMP_SELF:
2748 case OPTYPE_COMP_CREATE:
2749 return Type::T_COMPONENT;
2750 case OPTYPE_UNDEF_RUNNING:
2751 case OPTYPE_COMP_RUNNING:
2752 case OPTYPE_COMP_RUNNING_ANY:
2753 case OPTYPE_COMP_RUNNING_ALL:
2754 case OPTYPE_COMP_ALIVE:
2755 case OPTYPE_COMP_ALIVE_ANY:
2756 case OPTYPE_COMP_ALIVE_ALL:
2757 case OPTYPE_TMR_RUNNING:
2758 case OPTYPE_TMR_RUNNING_ANY:
2759 case OPTYPE_MATCH:
2760 case OPTYPE_EQ:
2761 case OPTYPE_LT:
2762 case OPTYPE_GT:
2763 case OPTYPE_NE:
2764 case OPTYPE_GE:
2765 case OPTYPE_LE:
2766 case OPTYPE_NOT:
2767 case OPTYPE_AND:
2768 case OPTYPE_OR:
2769 case OPTYPE_XOR:
2770 case OPTYPE_ISPRESENT:
2771 case OPTYPE_ISCHOSEN:
2772 case OPTYPE_ISCHOSEN_V:
2773 case OPTYPE_ISCHOSEN_T:
2774 case OPTYPE_ISVALUE:
2775 case OPTYPE_ISBOUND:
2776 case OPTYPE_PROF_RUNNING:
2777 return Type::T_BOOL;
2778 case OPTYPE_GETVERDICT:
2779 return Type::T_VERDICT;
2780 case OPTYPE_VALUEOF: {
2781 Error_Context cntxt(this, "In the operand of operation `%s'",
2782 get_opname());
2783 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2784 case OPTYPE_TMR_READ:
2785 case OPTYPE_INT2FLOAT:
2786 case OPTYPE_STR2FLOAT:
2787 case OPTYPE_RND:
2788 case OPTYPE_RNDWITHVAL:
2789 return Type::T_REAL;
2790 case OPTYPE_ACTIVATE:
2791 return Type::T_DEFAULT;
2792 case OPTYPE_ACTIVATE_REFD:
2793 return Type::T_DEFAULT;
2794 case OPTYPE_EXECUTE:
2795 case OPTYPE_EXECUTE_REFD:
2796 return Type::T_VERDICT;
2797 case OPTYPE_UNARYPLUS: // v1
2798 case OPTYPE_UNARYMINUS: {
2799 Type::typetype_t tmp_tt;
2800 {
2801 Error_Context cntxt(this, "In the operand of operation `%s'",
2802 get_opname());
2803 u.expr.v1->set_lowerid_to_ref();
2804 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2805 }
2806 switch(tmp_tt) {
2807 case Type::T_INT:
2808 case Type::T_REAL:
2809 return tmp_tt;
2810 default:
2811 get_value_refd_last(); // to report the error
2812 return Type::T_ERROR;
2813 } // switch tmp_tt
2814 }
2815 case OPTYPE_ADD: // v1 v2
2816 case OPTYPE_SUBTRACT:
2817 case OPTYPE_MULTIPLY:
2818 case OPTYPE_DIVIDE: {
2819 Type::typetype_t tmp_tt;
2820 {
2821 Error_Context cntxt(this, "In the left operand of operation `%s'",
2822 get_opname());
2823 u.expr.v1->set_lowerid_to_ref();
2824 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2825 }
2826 switch(tmp_tt) {
2827 case Type::T_INT:
2828 case Type::T_REAL:
2829 return tmp_tt;
2830 default:
2831 if(u.expr.v_optype==OPTYPE_ADD) {
2832 Type::typetype_t tmp_tt2;
2833 {
2834 Error_Context cntxt(this, "In the right operand of operation `%s'",
2835 get_opname());
2836 u.expr.v2->set_lowerid_to_ref();
2837 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2838 }
2839 Type::typetype_t ret_val=Type::T_ERROR;
2840 bool maybeconcat=false;
2841 switch(tmp_tt) {
2842 case Type::T_BSTR:
2843 case Type::T_HSTR:
2844 case Type::T_OSTR:
2845 if(tmp_tt2==tmp_tt) {
2846 maybeconcat=true;
2847 ret_val=tmp_tt;
2848 }
2849 break;
2850 case Type::T_CSTR:
2851 case Type::T_USTR:
2852 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2853 maybeconcat=true;
2854 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2855 ret_val=Type::T_USTR;
2856 else ret_val=Type::T_CSTR;
2857 }
2858 break;
2859 default:
2860 break;
2861 }
2862 if(maybeconcat) {
2863 error("Did you mean the concat operation (`&') instead of"
2864 " addition operator (`+')?");
2865 u.expr.v_optype=OPTYPE_CONCAT;
2866 return ret_val;
2867 }
2868 }
2869 get_value_refd_last(); // to report the error
2870 return Type::T_ERROR;
2871 } // switch tmp_tt
2872 }
2873 case OPTYPE_NOT4B: // v1
2874 case OPTYPE_AND4B: // v1 v2
2875 case OPTYPE_OR4B:
2876 case OPTYPE_XOR4B:
2877 case OPTYPE_SHL:
2878 case OPTYPE_SHR: {
2879 Type::typetype_t tmp_tt;
2880 {
2881 Error_Context cntxt(this, "In the %soperand of operation `%s'",
2882 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
2883 get_opname());
2884 u.expr.v1->set_lowerid_to_ref();
2885 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2886 }
2887 switch(tmp_tt) {
2888 case Type::T_BSTR:
2889 case Type::T_HSTR:
2890 case Type::T_OSTR:
2891 return tmp_tt;
2892 default:
2893 get_value_refd_last(); // to report the error
2894 return Type::T_ERROR;
2895 } // switch tmp_tt
2896 }
2897 case OPTYPE_ROTL: // v1 v2
2898 case OPTYPE_ROTR: {
2899 Type::typetype_t tmp_tt;
2900 {
2901 Error_Context cntxt(this, "In the %s operand of operation `%s'",
2902 u.expr.v_optype==OPTYPE_ROTL
2903 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
2904 get_opname());
2905 u.expr.v1->set_lowerid_to_ref();
2906 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2907 }
2908 switch(tmp_tt) {
2909 case Type::T_BSTR:
2910 case Type::T_HSTR:
2911 case Type::T_OSTR:
2912 case Type::T_CSTR:
2913 case Type::T_USTR:
2914 case Type::T_SETOF:
2915 case Type::T_SEQOF:
2916 case Type::T_ARRAY:
2917 return tmp_tt;
2918 default:
2919 get_value_refd_last(); // to report the error
2920 return Type::T_ERROR;
2921 } // switch tmp_tt
2922 }
2923 case OPTYPE_SUBSTR:
2924 case OPTYPE_REPLACE: {
2925 Type::typetype_t tmp_tt;
2926 {
2927 Error_Context cntxt(this, "In the operand of operation `%s'",
2928 get_opname());
2929 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2930 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2931 }
2932 switch (tmp_tt) {
2933 case Type::T_BSTR:
2934 case Type::T_HSTR:
2935 case Type::T_OSTR:
2936 case Type::T_CSTR:
2937 case Type::T_USTR:
2938 case Type::T_SETOF:
2939 case Type::T_SEQOF:
2940 return tmp_tt;
2941 default:
2942 get_value_refd_last(); // to report the error
2943 return Type::T_ERROR;
2944 }
2945 }
2946 case OPTYPE_REGEXP: {
2947 Type::typetype_t tmp_tt;
2948 {
2949 Error_Context cntxt(this, "In the first operand of operation `%s'",
2950 get_opname());
2951 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2952 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2953 }
2954 switch(tmp_tt) {
2955 case Type::T_CSTR:
2956 case Type::T_USTR:
2957 return tmp_tt;
2958 default:
2959 get_value_refd_last(); // to report the error
2960 return Type::T_ERROR;
2961 } // switch tmp_tt
2962 }
2963 case OPTYPE_CONCAT: { // v1 v2
2964 Type::typetype_t tmp_tt;
2965 {
2966 Error_Context cntxt(this, "In the first operand of operation `%s'",
2967 get_opname());
2968 u.expr.v1->set_lowerid_to_ref();
2969 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2970 }
2971 switch(tmp_tt) {
2972 case Type::T_CSTR:
2973 case Type::T_USTR:
2974 case Type::T_BSTR:
2975 case Type::T_HSTR:
2976 case Type::T_OSTR:
2977 case Type::T_SETOF:
2978 case Type::T_SEQOF:
2979 return tmp_tt;
2980 default:
2981 get_value_refd_last(); // to report the error
2982 return Type::T_ERROR;
2983 } // switch tmp_tt
2984 }
2985 case OPTYPE_MOD:
2986 case OPTYPE_REM:
2987 case OPTYPE_CHAR2INT:
2988 case OPTYPE_UNICHAR2INT:
2989 case OPTYPE_BIT2INT:
2990 case OPTYPE_HEX2INT:
2991 case OPTYPE_OCT2INT:
2992 case OPTYPE_STR2INT:
2993 case OPTYPE_FLOAT2INT:
2994 case OPTYPE_LENGTHOF:
2995 case OPTYPE_SIZEOF:
2996 case OPTYPE_DECODE:
2997 case OPTYPE_ENUM2INT:
2998 return Type::T_INT;
2999 case OPTYPE_BIT2STR:
3000 case OPTYPE_FLOAT2STR:
3001 case OPTYPE_HEX2STR:
3002 case OPTYPE_INT2CHAR:
3003 case OPTYPE_INT2STR:
3004 case OPTYPE_OCT2CHAR:
3005 case OPTYPE_OCT2STR:
3006 case OPTYPE_UNICHAR2CHAR:
3007 case OPTYPE_LOG2STR:
3008 case OPTYPE_TESTCASENAME:
3009 case OPTYPE_TTCN2STRING:
3010 case OPTYPE_GET_STRINGENCODING:
3011 case OPTYPE_ENCODE_BASE64:
3012 return Type::T_CSTR;
3013 case OPTYPE_INT2UNICHAR:
3014 case OPTYPE_OCT2UNICHAR:
3015 return Type::T_USTR;
3016 case OPTYPE_INT2BIT:
3017 case OPTYPE_HEX2BIT:
3018 case OPTYPE_OCT2BIT:
3019 case OPTYPE_STR2BIT:
3020 case OPTYPE_ENCODE:
3021 return Type::T_BSTR;
3022 case OPTYPE_INT2HEX:
3023 case OPTYPE_BIT2HEX:
3024 case OPTYPE_OCT2HEX:
3025 case OPTYPE_STR2HEX:
3026 return Type::T_HSTR;
3027 case OPTYPE_INT2OCT:
3028 case OPTYPE_CHAR2OCT:
3029 case OPTYPE_HEX2OCT:
3030 case OPTYPE_BIT2OCT:
3031 case OPTYPE_STR2OCT:
3032 case OPTYPE_UNICHAR2OCT:
3033 case OPTYPE_REMOVE_BOM:
3034 case OPTYPE_DECODE_BASE64:
3035 return Type::T_OSTR;
3036 case OPTYPE_DECOMP:
3037 return Type::T_OID;
3038 default:
3039 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3040 // to avoid warning
3041 return Type::T_ERROR;
3042 } // switch optype
3043 case V_MACRO:
3044 switch (u.macro) {
3045 case MACRO_MODULEID:
3046 case MACRO_FILENAME:
3047 case MACRO_BFILENAME:
3048 case MACRO_FILEPATH:
3049 case MACRO_LINENUMBER:
3050 case MACRO_DEFINITIONID:
3051 case MACRO_SCOPE:
3052 case MACRO_TESTCASEID:
3053 return Type::T_CSTR;
3054 case MACRO_LINENUMBER_C:
3055 return Type::T_INT;
3056 default:
3057 return Type::T_ERROR;
3058 }
3059 case V_NULL:
3060 return Type::T_NULL;
3061 case V_BOOL:
3062 return Type::T_BOOL;
3063 case V_INT:
3064 return Type::T_INT;
3065 case V_REAL:
3066 return Type::T_REAL;
3067 case V_ENUM:
3068 return Type::T_ENUM_T;
3069 case V_BSTR:
3070 return Type::T_BSTR;
3071 case V_HSTR:
3072 return Type::T_HSTR;
3073 case V_OSTR:
3074 return Type::T_OSTR;
3075 case V_CSTR:
3076 return Type::T_CSTR;
3077 case V_USTR:
3078 return Type::T_USTR;
3079 case V_ISO2022STR:
3080 return Type::T_GENERALSTRING;
3081 case V_OID:
3082 return Type::T_OID;
3083 case V_ROID:
3084 return Type::T_ROID;
3085 case V_VERDICT:
3086 return Type::T_VERDICT;
3087 case V_DEFAULT_NULL:
3088 return Type::T_DEFAULT;
3089 default:
3090 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3091 // to avoid warning
3092 return Type::T_ERROR;
3093 } // switch
3094 }
3095
3096 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3097 {
3098 if(my_governor) return my_governor;
3099 switch (valuetype) {
3100 case V_INVOKE: {
3101 Type *t = u.invoke.v->get_expr_governor(exp_val);
3102 if(!t) {
3103 if(u.invoke.v->get_valuetype() != V_ERROR)
3104 u.invoke.v->error("A value of type function expected");
3105 goto error;
3106 }
3107 t = t->get_type_refd_last();
3108 switch(t->get_typetype()) {
3109 case Type::T_FUNCTION: {
3110 Type *t_return_type = t->get_function_return_type();
3111 if (!t_return_type) {
3112 error("Reference to a %s was expected instead of invocation "
3113 "of behavior type `%s' with no return type",
3114 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3115 t->get_fullname().c_str());
3116 goto error;
3117 }
3118 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3119 error("Reference to a value was expected, but functions of type "
3120 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3121 t_return_type->get_typename().c_str());
3122 goto error;
3123 }
3124 return t_return_type; }
3125 case Type::T_ALTSTEP:
3126 goto error;
3127 default:
3128 u.invoke.v->error("A value of type function expected instead of `%s'",
3129 t->get_typename().c_str());
3130 goto error;
3131 }
3132 break; }
3133 case V_REFD: {
3134 Assignment *ass=u.ref.ref->get_refd_assignment();
3135 Type *tmp_type=0;
3136 if (!ass) goto error;
3137 switch (ass->get_asstype()) {
3138 case Assignment::A_CONST:
3139 case Assignment::A_EXT_CONST:
3140 case Assignment::A_MODULEPAR:
3141 case Assignment::A_MODULEPAR_TEMP:
3142 case Assignment::A_TEMPLATE:
3143 case Assignment::A_VAR:
3144 case Assignment::A_VAR_TEMPLATE:
3145 case Assignment::A_FUNCTION_RVAL:
3146 case Assignment::A_FUNCTION_RTEMP:
3147 case Assignment::A_EXT_FUNCTION_RVAL:
3148 case Assignment::A_EXT_FUNCTION_RTEMP:
3149 case Assignment::A_PAR_VAL_IN:
3150 case Assignment::A_PAR_VAL_OUT:
3151 case Assignment::A_PAR_VAL_INOUT:
3152 case Assignment::A_PAR_TEMPL_IN:
3153 case Assignment::A_PAR_TEMPL_OUT:
3154 case Assignment::A_PAR_TEMPL_INOUT:
3155 tmp_type=ass->get_Type();
3156 break;
3157 case Assignment::A_FUNCTION:
3158 case Assignment::A_EXT_FUNCTION:
3159 error("Reference to a %s was expected instead of a call of %s, which "
3160 "does not have return type",
3161 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3162 ass->get_description().c_str());
3163 goto error;
3164 default:
3165 error("Reference to a %s was expected instead of %s",
3166 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3167 ass->get_description().c_str());
3168 goto error;
3169 } // end switch
3170 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3171 if(!tmp_type) goto error;
3172 return tmp_type; }
3173 case V_EXPR:
3174 switch (u.expr.v_optype) {
3175 case OPTYPE_VALUEOF:
3176 case OPTYPE_SUBSTR:
3177 case OPTYPE_REGEXP:
3178 case OPTYPE_REPLACE:{
3179 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3180 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3181 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3182 return tmp_type;
3183 }
3184 case OPTYPE_ROTL:
3185 case OPTYPE_ROTR:
3186 return u.expr.v1->get_expr_governor(exp_val);
3187 case OPTYPE_CONCAT:
3188 return get_expr_governor_v1v2(exp_val);
3189 case OPTYPE_COMP_MTC:
3190 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3191 else return 0;
3192 case OPTYPE_COMP_SYSTEM:
3193 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3194 else return 0;
3195 case OPTYPE_COMP_SELF:
3196 if (my_scope) {
3197 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3198 if (t_ros) return t_ros->get_component_type();
3199 else return 0;
3200 } else return 0;
3201 case OPTYPE_COMP_CREATE:
3202 return chk_expr_operand_comptyperef_create();
3203 default:
3204 break;
3205 }
3206 // no break
3207 default:
3208 return Type::get_pooltype(get_expr_returntype(exp_val));
3209 }
3210 error:
3211 set_valuetype(V_ERROR);
3212 return 0;
3213 }
3214
3215 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3216 {
3217 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3218 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3219 if (v1_gov) {
3220 if (v2_gov) { // both have governors
3221 // return the type that is compatible with both (if there is no type mismatch)
3222 if (v1_gov->is_compatible(v2_gov, NULL))
3223 return v1_gov;
3224 else return v2_gov;
3225 } else return v1_gov;
3226 } else { // v1 has no governor
3227 if (v2_gov) return v2_gov;
3228 else return NULL; // neither has governor
3229 }
3230 }
3231
3232 Type *Value::get_expr_governor_last()
3233 {
3234 Value *v_last = get_value_refd_last();
3235 if (v_last->valuetype == V_ERROR) return 0;
3236 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3237 if(!t) return 0;
3238 return t->get_type_refd_last();
3239 }
3240
3241 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3242 {
3243 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3244 return u.invoke.v->get_expr_governor(exp_val);
3245 }
3246
3247 const char* Value::get_opname() const
3248 {
3249 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3250 switch(u.expr.v_optype) {
3251 case OPTYPE_RND: // -
3252 return "rnd()";
3253 case OPTYPE_COMP_NULL:
3254 return "(component) null";
3255 case OPTYPE_COMP_MTC:
3256 return "mtc";
3257 case OPTYPE_COMP_SYSTEM:
3258 return "system";
3259 case OPTYPE_COMP_SELF:
3260 return "self";
3261 case OPTYPE_COMP_RUNNING_ANY:
3262 return "any component.running";
3263 case OPTYPE_COMP_RUNNING_ALL:
3264 return "all component.running";
3265 case OPTYPE_COMP_ALIVE_ANY:
3266 return "any component.alive";
3267 case OPTYPE_COMP_ALIVE_ALL:
3268 return "all component.alive";
3269 case OPTYPE_TMR_RUNNING_ANY:
3270 return "any timer.running";
3271 case OPTYPE_GETVERDICT:
3272 return "getverdict()";
3273 case OPTYPE_TESTCASENAME:
3274 return "testcasename()";
3275 case OPTYPE_UNARYPLUS: // v1
3276 return "unary +";
3277 case OPTYPE_UNARYMINUS:
3278 return "unary -";
3279 case OPTYPE_NOT:
3280 return "not";
3281 case OPTYPE_NOT4B:
3282 return "not4b";
3283 case OPTYPE_BIT2HEX:
3284 return "bit2hex()";
3285 case OPTYPE_BIT2INT:
3286 return "bit2int()";
3287 case OPTYPE_BIT2OCT:
3288 return "bit2oct()";
3289 case OPTYPE_BIT2STR:
3290 return "bit2str()";
3291 case OPTYPE_CHAR2INT:
3292 return "char2int()";
3293 case OPTYPE_CHAR2OCT:
3294 return "char2oct()";
3295 case OPTYPE_FLOAT2INT:
3296 return "float2int()";
3297 case OPTYPE_FLOAT2STR:
3298 return "float2str()";
3299 case OPTYPE_HEX2BIT:
3300 return "hex2bit()";
3301 case OPTYPE_HEX2INT:
3302 return "hex2int()";
3303 case OPTYPE_HEX2OCT:
3304 return "hex2oct()";
3305 case OPTYPE_HEX2STR:
3306 return "hex2str()";
3307 case OPTYPE_INT2CHAR:
3308 return "int2char()";
3309 case OPTYPE_INT2FLOAT:
3310 return "int2float()";
3311 case OPTYPE_INT2STR:
3312 return "int2str()";
3313 case OPTYPE_INT2UNICHAR:
3314 return "int2unichar()";
3315 case OPTYPE_OCT2BIT:
3316 return "oct2bit()";
3317 case OPTYPE_OCT2CHAR:
3318 return "oct2char()";
3319 case OPTYPE_OCT2HEX:
3320 return "oct2hex()";
3321 case OPTYPE_OCT2INT:
3322 return "oct2int()";
3323 case OPTYPE_OCT2STR:
3324 return "oct2str()";
3325 case OPTYPE_STR2BIT:
3326 return "str2bit()";
3327 case OPTYPE_STR2FLOAT:
3328 return "str2float()";
3329 case OPTYPE_STR2HEX:
3330 return "str2hex()";
3331 case OPTYPE_STR2INT:
3332 return "str2int()";
3333 case OPTYPE_STR2OCT:
3334 return "str2oct()";
3335 case OPTYPE_UNICHAR2INT:
3336 return "unichar2int()";
3337 case OPTYPE_UNICHAR2CHAR:
3338 return "unichar2char()";
3339 case OPTYPE_UNICHAR2OCT:
3340 return "unichar2oct()";
3341 case OPTYPE_ENUM2INT:
3342 return "enum2int()";
3343 case OPTYPE_LENGTHOF:
3344 return "lengthof()";
3345 case OPTYPE_SIZEOF:
3346 return "sizeof()";
3347 case OPTYPE_RNDWITHVAL:
3348 return "rnd (seed)";
3349 case OPTYPE_ENCODE:
3350 return "encvalue()";
3351 case OPTYPE_DECODE:
3352 return "decvalue()";
3353 case OPTYPE_GET_STRINGENCODING:
3354 return "get_stringencoding()";
3355 case OPTYPE_REMOVE_BOM:
3356 return "remove_bom()";
3357 case OPTYPE_ENCODE_BASE64:
3358 return "encode_base64()";
3359 case OPTYPE_DECODE_BASE64:
3360 return "decode_base64()";
3361 case OPTYPE_ADD: // v1 v2
3362 return "+";
3363 case OPTYPE_SUBTRACT:
3364 return "-";
3365 case OPTYPE_MULTIPLY:
3366 return "*";
3367 case OPTYPE_DIVIDE:
3368 return "/";
3369 case OPTYPE_MOD:
3370 return "mod";
3371 case OPTYPE_REM:
3372 return "rem";
3373 case OPTYPE_CONCAT:
3374 return "&";
3375 case OPTYPE_EQ:
3376 return "==";
3377 case OPTYPE_LT:
3378 return "<";
3379 case OPTYPE_GT:
3380 return ">";
3381 case OPTYPE_NE:
3382 return "!=";
3383 case OPTYPE_GE:
3384 return ">=";
3385 case OPTYPE_LE:
3386 return "<=";
3387 case OPTYPE_AND:
3388 return "and";
3389 case OPTYPE_OR:
3390 return "or";
3391 case OPTYPE_XOR:
3392 return "xor";
3393 case OPTYPE_AND4B:
3394 return "and4b";
3395 case OPTYPE_OR4B:
3396 return "or4b";
3397 case OPTYPE_XOR4B:
3398 return "xor4b";
3399 case OPTYPE_SHL:
3400 return "<<";
3401 case OPTYPE_SHR:
3402 return ">>";
3403 case OPTYPE_ROTL:
3404 return "<@";
3405 case OPTYPE_ROTR:
3406 return "@>";
3407 case OPTYPE_INT2BIT:
3408 return "int2bit()";
3409 case OPTYPE_INT2HEX:
3410 return "int2hex()";
3411 case OPTYPE_INT2OCT:
3412 return "int2oct()";
3413 case OPTYPE_OCT2UNICHAR:
3414 return "oct2unichar()";
3415 case OPTYPE_SUBSTR:
3416 return "substr()";
3417 case OPTYPE_REGEXP:
3418 return "regexp()";
3419 case OPTYPE_DECOMP:
3420 return "decomp()";
3421 case OPTYPE_REPLACE:
3422 return "replace()";
3423 case OPTYPE_VALUEOF: // t1
3424 return "valueof()";
3425 case OPTYPE_UNDEF_RUNNING:
3426 return "<timer or component> running";
3427 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3428 return "create()";
3429 case OPTYPE_COMP_RUNNING: // v1
3430 return "component running";
3431 case OPTYPE_COMP_ALIVE: // v1
3432 return "alive";
3433 case OPTYPE_TMR_READ:
3434 return "timer read";
3435 case OPTYPE_TMR_RUNNING:
3436 return "timer running";
3437 case OPTYPE_ACTIVATE:
3438 return "activate()";
3439 case OPTYPE_ACTIVATE_REFD:
3440 return "activate()";
3441 case OPTYPE_EXECUTE: // r1 [v2]
3442 case OPTYPE_EXECUTE_REFD:
3443 return "execute()";
3444 case OPTYPE_MATCH: // v1 t2
3445 return "match()";
3446 case OPTYPE_ISPRESENT:
3447 return "ispresent()";
3448 case OPTYPE_ISCHOSEN:
3449 case OPTYPE_ISCHOSEN_V:
3450 case OPTYPE_ISCHOSEN_T:
3451 return "ischosen()";
3452 case OPTYPE_ISVALUE:
3453 return "isvalue()";
3454 case OPTYPE_ISBOUND:
3455 return "isbound()";
3456 case OPTYPE_LOG2STR:
3457 return "log2str()";
3458 case OPTYPE_TTCN2STRING:
3459 return "ttcn2string()";
3460 case OPTYPE_PROF_RUNNING:
3461 return "@profiler.running";
3462 default:
3463 FATAL_ERROR("Value::get_opname()");
3464 } // switch
3465 }
3466
3467 void Value::chk_expr_ref_ischosen()
3468 {
3469 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3470 Ttcn::Ref_base *tmpref=u.expr.r1;
3471 Assignment *ass=tmpref->get_refd_assignment();
3472 if (!ass) {
3473 set_valuetype(V_ERROR);
3474 return;
3475 }
3476 // Now we know whether the argument of ischosen() is a value or template.
3477 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3478 // or template (OPTYPE_ISCHOSEN_T).
3479 switch (ass->get_asstype()) {
3480 case Assignment::A_CONST:
3481 case Assignment::A_EXT_CONST:
3482 case Assignment::A_MODULEPAR:
3483 case Assignment::A_VAR:
3484 case Assignment::A_PAR_VAL_IN:
3485 case Assignment::A_PAR_VAL_OUT:
3486 case Assignment::A_PAR_VAL_INOUT:
3487 u.expr.v1=new Value(V_REFD, tmpref);
3488 u.expr.v1->set_location(*tmpref);
3489 u.expr.v1->set_my_scope(get_my_scope());
3490 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3491 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3492 break;
3493 case Assignment::A_MODULEPAR_TEMP:
3494 case Assignment::A_TEMPLATE:
3495 case Assignment::A_VAR_TEMPLATE:
3496 case Assignment::A_PAR_TEMPL_IN:
3497 case Assignment::A_PAR_TEMPL_OUT:
3498 case Assignment::A_PAR_TEMPL_INOUT:
3499 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3500 u.expr.t1->set_location(*tmpref);
3501 u.expr.t1->set_my_scope(get_my_scope());
3502 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3503 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3504 break;
3505 default:
3506 tmpref->error("Reference to a value or template was expected instead of "
3507 "%s", ass->get_description().c_str());
3508 set_valuetype(V_ERROR);
3509 break;
3510 } // switch
3511 }
3512
3513 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3514 Type::expected_value_t exp_val)
3515 {
3516 v->set_lowerid_to_ref(); // can only be reference to enum
3517 Type *t = v->get_expr_governor(exp_val);
3518 if (v->valuetype==V_ERROR) return;
3519 if (!t) {
3520 v->error("Please use reference to an enumerated value as the operand of "
3521 "operation `%s'", get_opname());
3522 set_valuetype(V_ERROR);
3523 return;
3524 }
3525 t = t->get_type_refd_last();
3526 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3527 v->error("The operand of operation `%s' should be enumerated value", opname);
3528 set_valuetype(V_ERROR);
3529 }
3530 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3531 v->error("The operand of operation `%s' cannot be omit", opname);
3532 set_valuetype(V_ERROR);
3533 }
3534 }
3535
3536 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3537 const char *opnum,
3538 const char *opname,
3539 const Location *loc)
3540 {
3541 if(tt==Type::T_BOOL) return;
3542 if(tt!=Type::T_ERROR)
3543 loc->error("%s operand of operation `%s' should be boolean value",
3544 opnum, opname);
3545 set_valuetype(V_ERROR);
3546 }
3547
3548 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3549 const char *opnum,
3550 const char *opname,
3551 const Location *loc)
3552 {
3553 if(tt==Type::T_INT) return;
3554 if(tt!=Type::T_ERROR)
3555 loc->error("%s operand of operation `%s' should be integer value",
3556 opnum, opname);
3557 set_valuetype(V_ERROR);
3558 }
3559
3560 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3561 const char *opnum,
3562 const char *opname,
3563 const Location *loc)
3564 {
3565 if(tt==Type::T_REAL) return;
3566 else if(tt==Type::T_INT)
3567 loc->error("%s operand of operation `%s' should be float value."
3568 " Perhaps you missed an int2float() conversion function"
3569 " or `.0' at the end of the number",
3570 opnum, opname);
3571 else if(tt!=Type::T_ERROR)
3572 loc->error("%s operand of operation `%s' should be float value",
3573 opnum, opname);
3574 set_valuetype(V_ERROR);
3575 }
3576
3577 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3578 const char *opnum,
3579 const char *opname,
3580 const Location *loc)
3581 {
3582 switch(tt) {
3583 case Type::T_INT:
3584 case Type::T_REAL:
3585 return;
3586 default:
3587 break;
3588 }
3589 if(tt!=Type::T_ERROR)
3590 loc->error("%s operand of operation `%s' should be integer"
3591 " or float value",
3592 opnum, opname);
3593 set_valuetype(V_ERROR);
3594 }
3595
3596 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3597 const char *opnum,
3598 const char *opname,
3599 const Location *loc)
3600 {
3601 switch(tt) {
3602 case Type::T_INT:
3603 case Type::T_REAL:
3604 case Type::T_ENUM_T:
3605 return;
3606 default:
3607 break;
3608 }
3609 if(tt!=Type::T_ERROR)
3610 loc->error("%s operand of operation `%s' should be integer, float"
3611 " or enumerated value", opnum, opname);
3612 set_valuetype(V_ERROR);
3613 }
3614
3615 void Value::chk_expr_operandtype_list(Type* t,
3616 const char *opnum,
3617 const char *opname,
3618 const Location *loc,
3619 bool allow_array)
3620 {
3621 if (valuetype == V_ERROR) return;
3622 if (t->get_typetype() == Type::T_ERROR) {
3623 set_valuetype(V_ERROR);
3624 return;
3625 }
3626 if (!t->is_list_type(allow_array)) {
3627 loc->error("%s operand of operation `%s' should be a string, "
3628 "`record of'%s `set of'%s value", opnum, opname,
3629 allow_array ? "," : " or", allow_array ? " or array" : "");
3630 set_valuetype(V_ERROR);
3631 return;
3632 }
3633 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3634 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3635 TypeChain l_chain;
3636 TypeChain r_chain;
3637 if (my_governor && my_governor->is_list_type(allow_array)
3638 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3639 if (info.is_subtype_error()) {
3640 // this is ok.
3641 if (info.needs_conversion()) set_needs_conversion();
3642 } else
3643 if (!info.is_erroneous()) {
3644 error("%s operand of operation `%s' is of type `%s', but a value of "
3645 "type `%s' was expected here", opnum, opname,
3646 t->get_typename().c_str(), my_governor->get_typename().c_str());
3647 } else {
3648 error("%s", info.get_error_str_str().c_str());
3649 }
3650 } else {
3651 if (info.needs_conversion())
3652 set_needs_conversion();
3653 }
3654 }
3655
3656 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3657 const char *opnum,
3658 const char *opname,
3659 const Location *loc)
3660 {
3661 switch(tt) {
3662 case Type::T_CSTR:
3663 case Type::T_USTR:
3664 case Type::T_BSTR:
3665 case Type::T_HSTR:
3666 case Type::T_OSTR:
3667 return;
3668 default:
3669 break;
3670 }
3671 if(tt!=Type::T_ERROR)
3672 loc->error("%s operand of operation `%s' should be string value",
3673 opnum, opname);
3674 set_valuetype(V_ERROR);
3675 }
3676
3677 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3678 const char *opnum,
3679 const char *opname,
3680 const Location *loc)
3681 {
3682 switch(tt) {
3683 case Type::T_CSTR:
3684 case Type::T_USTR:
3685 return;
3686 default:
3687 break;
3688 }
3689 if(tt!=Type::T_ERROR)
3690 loc->error("%s operand of operation `%s' should be (universal)"
3691 " charstring value",
3692 opnum, opname);
3693 set_valuetype(V_ERROR);
3694 }
3695
3696 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3697 const char *opnum,
3698 const char *opname,
3699 const Location *loc)
3700 {
3701 if(tt==Type::T_CSTR) return;
3702 if(tt!=Type::T_ERROR)
3703 loc->error("%s operand of operation `%s' should be charstring value",
3704 opnum, opname);
3705 set_valuetype(V_ERROR);
3706 }
3707
3708 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3709 const char *opnum,
3710 const char *opname,
3711 const Location *loc)
3712 {
3713 switch(tt) {
3714 case Type::T_BSTR:
3715 case Type::T_HSTR:
3716 case Type::T_OSTR:
3717 return;
3718 default:
3719 break;
3720 }
3721 if(tt!=Type::T_ERROR)
3722 loc->error("%s operand of operation `%s' should be binary string value",
3723 opnum, opname);
3724 set_valuetype(V_ERROR);
3725 }
3726
3727 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3728 const char *opnum,
3729 const char *opname,
3730 const Location *loc)
3731 {
3732 if(tt==Type::T_BSTR) return;
3733 if(tt!=Type::T_ERROR)
3734 loc->error("%s operand of operation `%s' should be bitstring value",
3735 opnum, opname);
3736 set_valuetype(V_ERROR);
3737 }
3738
3739 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3740 const char *opnum,
3741 const char *opname,
3742 const Location *loc)
3743 {
3744 if(tt==Type::T_HSTR) return;
3745 if(tt!=Type::T_ERROR)
3746 loc->error("%s operand of operation `%s' should be hexstring value",
3747 opnum, opname);
3748 set_valuetype(V_ERROR);
3749 }
3750
3751 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3752 const char *opnum,
3753 const char *opname,
3754 const Location *loc)
3755 {
3756 if(tt==Type::T_OSTR) return;
3757 if(tt!=Type::T_ERROR)
3758 loc->error("%s operand of operation `%s' should be octetstring value",
3759 opnum, opname);
3760 set_valuetype(V_ERROR);
3761 }
3762
3763 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3764 Type::typetype_t tt2,
3765 const char *opname)
3766 {
3767 if(valuetype==V_ERROR) return;
3768 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3769 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3770 set_valuetype(V_ERROR);
3771 return;
3772 }
3773 if(tt1==tt2) return;
3774 error("The operands of operation `%s' should be of same type", opname);
3775 set_valuetype(V_ERROR);
3776 }
3777
3778 /* For predefined functions. */
3779 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3780 Type::typetype_t tt2,
3781 const char *opnum1,
3782 const char *opnum2,
3783 const char *opname)
3784 {
3785 if(valuetype==V_ERROR) return;
3786 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3787 set_valuetype(V_ERROR);
3788 return;
3789 }
3790 if(tt1==tt2) return;
3791 error("The %s and %s operands of operation `%s' should be of same type",
3792 opnum1, opnum2, opname);
3793 set_valuetype(V_ERROR);
3794 }
3795
3796 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3797 Value *v1, Value *v2,
3798 const char *opnum1,
3799 const char *opnum2)
3800 {
3801 start:
3802 if (valuetype == V_ERROR) return;
3803 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3804 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3805 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3806
3807 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3808 set_valuetype(V_ERROR);
3809 return;
3810 }
3811 if (tt1 == Type::T_UNDEF) {
3812 if (tt2 == Type::T_UNDEF) {
3813 if (v1->is_undef_lowerid()) {
3814 if (v2->is_undef_lowerid()) {
3815 Scope *scope = get_my_scope();
3816 Module *my_mod = scope->get_scope_mod();
3817 const Identifier& id1 = v1->get_undef_lowerid();
3818 if (scope->has_ass_withId(id1)
3819 || my_mod->has_imported_ass_withId(id1)) {
3820 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3821 * should examine this situation better, but now I suppose
3822 * the first is ref, not enum. */
3823 v1->set_lowerid_to_ref();
3824 goto start;
3825 } else {
3826 const Identifier& id2 = v2->get_undef_lowerid();
3827 if (scope->has_ass_withId(id2)
3828 || my_mod->has_imported_ass_withId(id2)) {
3829 v2->set_lowerid_to_ref();
3830 goto start;
3831 }
3832 }
3833 /* This is perhaps enum-enum, but it has no real
3834 * significance, so this should be an error. */
3835 } else {
3836 v1->set_lowerid_to_ref();
3837 goto start;
3838 }
3839 } else if (v2->is_undef_lowerid()) {
3840 v2->set_lowerid_to_ref();
3841 goto start;
3842 }
3843 error("Cannot determine the type of the operands in operation `%s'",
3844 get_opname());
3845 set_valuetype(V_ERROR);
3846 return;
3847 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3848 v1->set_lowerid_to_ref();
3849 goto start;
3850 } else {
3851 /* v1 is something undefined, but not lowerid; v2 has
3852 * returntype (perhaps also governor) */
3853 }
3854 } else if (tt2 == Type::T_UNDEF) {
3855 /* but tt1 is not undef */
3856 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3857 v2->set_lowerid_to_ref();
3858 goto start;
3859 } else {
3860 /* v2 is something undefined, but not lowerid; v1 has
3861 * returntype (perhaps also governor) */
3862 }
3863 }
3864
3865 /* Now undef_lower_id's are converted to references, or the other
3866 * value has governor; let's see the governors, if they exist. */
3867 Type *t1 = v1->get_expr_governor(exp_val);
3868 Type *t2 = v2->get_expr_governor(exp_val);
3869 if (t1) {
3870 if (t2) {
3871 // Both value has governor. Are they compatible? According to 7.1.2
3872 // and C.34 it's required to have the same root types for
3873 // OPTYPE_{CONCAT,REPLACE}.
3874 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3875 u.expr.v_optype == OPTYPE_REPLACE);
3876 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
3877 u.expr.v_optype == OPTYPE_REPLACE);
3878 TypeChain l_chain1, l_chain2;
3879 TypeChain r_chain1, r_chain2;
3880 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
3881 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
3882 if (!compat_t1 && !compat_t2) {
3883 if (!info1.is_erroneous() && !info2.is_erroneous()) {
3884 // the subtypes don't need to be compatible here
3885 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
3886 error("The operands of operation `%s' should be of compatible "
3887 "types", get_opname());
3888 set_valuetype(V_ERROR);
3889 } else {
3890 if (info1.needs_conversion() || info2.needs_conversion()) {
3891 set_needs_conversion(); // Avoid folding.
3892 return;
3893 }
3894 }
3895 } else {
3896 if (info1.is_erroneous())
3897 v1->error("%s", info1.get_error_str_str().c_str());
3898 else if (info2.is_erroneous())
3899 v2->error("%s", info2.get_error_str_str().c_str());
3900 set_valuetype(V_ERROR);
3901 }
3902 return;
3903 } else if (info1.needs_conversion() || info2.needs_conversion()) {
3904 set_needs_conversion(); // Avoid folding.
3905 return;
3906 }
3907 } else {
3908 // t1, no t2.
3909 v2->set_my_governor(t1);
3910 t1->chk_this_value_ref(v2);
3911 if (v2->valuetype == V_OMIT) {
3912 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3913 get_opname());
3914 v1->chk_expr_omit_comparison(exp_val);
3915 } else {
3916 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3917 get_opname());
3918 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3919 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3920 goto start;
3921 }
3922 }
3923 } else if (t2) {
3924 v1->set_my_governor(t2);
3925 t2->chk_this_value_ref(v1);
3926 if (v1->valuetype == V_OMIT) {
3927 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3928 get_opname());
3929 v2->chk_expr_omit_comparison(exp_val);
3930 } else {
3931 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3932 get_opname());
3933 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3934 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3935 goto start;
3936 }
3937 } else {
3938 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3939 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
3940 // Here, it cannot be that both are T_UNDEF.
3941 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3942 error("Please use reference as %s operand of operator `%s'",
3943 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
3944 set_valuetype(V_ERROR);
3945 return;
3946 }
3947 // Deny type compatibility if no governors found. The typetype_t must
3948 // be the same. TODO: How can this happen?
3949 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
3950 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
3951 error("The operands of operation `%s' should be of compatible types",
3952 get_opname());
3953 set_valuetype(V_ERROR);
3954 }
3955 }
3956 }
3957
3958 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
3959 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
3960 {
3961 if(valuetype==V_ERROR) return;
3962 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3963 Assignment *t_ass = ref->get_refd_assignment();
3964 if(!t_ass) goto error;
3965 switch(t_ass->get_asstype()) {
3966 case Assignment::A_TIMER:
3967 case Assignment::A_PAR_TIMER:
3968 u.expr.v_optype=OPTYPE_TMR_RUNNING;
3969 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
3970 chk_expr_dynamic_part(exp_val, true);
3971 break;
3972 case Assignment::A_CONST:
3973 case Assignment::A_EXT_CONST:
3974 case Assignment::A_MODULEPAR:
3975 case Assignment::A_VAR:
3976 case Assignment::A_FUNCTION_RVAL:
3977 case Assignment::A_EXT_FUNCTION_RVAL:
3978 case Assignment::A_PAR_VAL_IN:
3979 case Assignment::A_PAR_VAL_OUT:
3980 case Assignment::A_PAR_VAL_INOUT: {
3981 u.expr.v_optype = OPTYPE_COMP_RUNNING;
3982 Value* val = new Value(V_REFD, u.expr.r1);
3983 val->set_my_scope(my_scope);
3984 val->set_fullname(u.expr.r1->get_fullname());
3985 val->set_location(*u.expr.r1);
3986 u.expr.v1 = val;
3987 chk_expr_operand_compref(val, opnum, get_opname());
3988 chk_expr_dynamic_part(exp_val, false);
3989 break; }
3990 default:
3991 ref->error("%s operand of operation `%s' should be timer or"
3992 " component reference instead of %s",
3993 opnum, opname, t_ass->get_description().c_str());
3994 goto error;
3995 } // switch
3996 return;
3997 error:
3998 set_valuetype(V_ERROR);
3999 }
4000
4001 Type *Value::chk_expr_operand_comptyperef_create()
4002 {
4003 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4004 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4005 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4006 if (!t_ass) goto error;
4007 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4008 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4009 Type::EXPECTED_DYNAMIC_VALUE);
4010 if (!t_type) goto error;
4011 t_type = t_type->get_type_refd_last();
4012 if (t_type->get_typetype() == Type::T_COMPONENT) {
4013 if (my_governor) {
4014 Type *my_governor_last = my_governor->get_type_refd_last();
4015 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4016 !my_governor_last->is_compatible(t_type, NULL)) {
4017 u.expr.r1->error("Incompatible component types: operation "
4018 "`create' should refer to `%s' instead of "
4019 "`%s'",
4020 my_governor_last->get_typename().c_str(),
4021 t_type->get_typename().c_str());
4022 goto error;
4023 }
4024 }
4025 return t_type;
4026 } else {
4027 u.expr.r1->error("Type mismatch: reference to a component type was "
4028 "expected in operation `create' instead of `%s'",
4029 t_type->get_typename().c_str());
4030 }
4031 } else {
4032 u.expr.r1->error("Operation `create' should refer to a component type "
4033 "instead of %s", t_ass->get_description().c_str());
4034 }
4035 error:
4036 set_valuetype(V_ERROR);
4037 return NULL;
4038 }
4039
4040 void Value::chk_expr_comptype_compat()
4041 {
4042 if (valuetype != V_EXPR)
4043 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4044 if (!my_governor || !my_scope) return;
4045 Type *my_governor_last = my_governor->get_type_refd_last();
4046 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4047 Type *t_comptype;
4048 switch (u.expr.v_optype) {
4049 case OPTYPE_COMP_MTC:
4050 t_comptype = my_scope->get_mtc_system_comptype(false);
4051 break;
4052 case OPTYPE_COMP_SYSTEM:
4053 t_comptype = my_scope->get_mtc_system_comptype(true);
4054 break;
4055 case OPTYPE_COMP_SELF: {
4056 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4057 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4058 break; }
4059 default:
4060 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4061 t_comptype = 0;
4062 break;
4063 }
4064 if (t_comptype
4065 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4066 error("Incompatible component types: a component reference of "
4067 "type `%s' was expected, but `%s' has type `%s'",
4068 my_governor_last->get_typename().c_str(), get_opname(),
4069 t_comptype->get_typename().c_str());
4070 set_valuetype(V_ERROR);
4071 }
4072 }
4073
4074 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4075 const char *opname)
4076 {
4077 if(valuetype == V_ERROR) return;
4078 switch(val->get_valuetype()) {
4079 case V_INVOKE: {
4080 Error_Context cntxt(this, "In `%s' operation", opname);
4081 Value *v_last = val->get_value_refd_last();
4082 if(!v_last) goto error;
4083 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4084 if(!t) goto error;
4085 t = t->get_type_refd_last();
4086 if(t->get_typetype() != Type::T_COMPONENT) {
4087 v_last->error("%s operand of operation `%s': Type mismatch:"
4088 " component reference was expected instead of `%s'",
4089 opnum, opname, t->get_typename().c_str());
4090 goto error;
4091 }
4092 return; }
4093 case V_REFD: {
4094 Reference *ref = val->get_reference();
4095 Assignment *t_ass = ref->get_refd_assignment();
4096 Value *t_val = 0;
4097 if (!t_ass) goto error;
4098 switch(t_ass->get_asstype()) {
4099 case Assignment::A_CONST:
4100 t_val = t_ass->get_Value();
4101 // no break
4102 case Assignment::A_EXT_CONST:
4103 case Assignment::A_MODULEPAR:
4104 case Assignment::A_VAR:
4105 case Assignment::A_FUNCTION_RVAL:
4106 case Assignment::A_EXT_FUNCTION_RVAL:
4107 case Assignment::A_PAR_VAL_IN:
4108 case Assignment::A_PAR_VAL_OUT:
4109 case Assignment::A_PAR_VAL_INOUT: {
4110 Type *t_type=t_ass->get_Type()
4111 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4112 if(!t_type) goto error;
4113 t_type=t_type->get_type_refd_last();
4114 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4115 ref->error("%s operand of operation `%s': Type mismatch:"
4116 " component reference was expected instead of `%s'",
4117 opnum, opname, t_type->get_typename().c_str());
4118 goto error;
4119 }
4120 break;}
4121 default:
4122 ref->error("%s operand of operation `%s' should be"
4123 " component reference instead of %s",
4124 opnum, opname, t_ass->get_description().c_str());
4125 goto error;
4126 }
4127 if (t_val) {
4128 ReferenceChain refch(this, "While searching referenced value");
4129 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4130 if (!t_val) return;
4131 t_val = t_val->get_value_refd_last();
4132 if (t_val->valuetype != V_EXPR) return;
4133 switch (t_val->u.expr.v_optype) {
4134 case OPTYPE_COMP_NULL:
4135 ref->error("%s operand of operation `%s' refers to `null' component "
4136 "reference", opnum, opname);
4137 goto error;
4138 case OPTYPE_COMP_MTC:
4139 ref->error("%s operand of operation `%s' refers to the component "
4140 "reference of the `mtc'", opnum, opname);
4141 goto error;
4142 case OPTYPE_COMP_SYSTEM:
4143 ref->error("%s operand of operation `%s' refers to the component "
4144 "reference of the `system'", opnum, opname);
4145 goto error;
4146 default:
4147 break;
4148 }
4149 }
4150 return;}
4151 default:
4152 FATAL_ERROR("Value::chk_expr_operand_compref()");
4153 }
4154 error:
4155 set_valuetype(V_ERROR);
4156 }
4157
4158 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4159 const char *opnum,
4160 const char *opname)
4161 {
4162 if(valuetype==V_ERROR) return;
4163 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4164 Assignment *t_ass = ref->get_refd_assignment();
4165 if(!t_ass) goto error;
4166 switch(t_ass->get_asstype()) {
4167 case Assignment::A_TIMER: {
4168 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4169 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4170 Type::EXPECTED_DYNAMIC_VALUE);
4171 else if (ref->get_subrefs()) {
4172 ref->error("%s operand of operation `%s': "
4173 "Reference to single timer `%s' cannot have field or array "
4174 "sub-references", opnum, opname,
4175 t_ass->get_id().get_dispname().c_str());
4176 goto error;
4177 }
4178 break; }
4179 case Assignment::A_PAR_TIMER:
4180 if (ref->get_subrefs()) {
4181 ref->error("%s operand of operation `%s': "
4182 "Reference to %s cannot have field or array sub-references",
4183 opnum, opname, t_ass->get_description().c_str());
4184 goto error;
4185 }
4186 break;
4187 default:
4188 ref->error("%s operand of operation `%s' should be timer"
4189 " instead of %s",
4190 opnum, opname, t_ass->get_description().c_str());
4191 goto error;
4192 } // switch
4193 return;
4194 error:
4195 set_valuetype(V_ERROR);
4196 }
4197
4198 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4199 const char *,
4200 const char *opname)
4201 {
4202 if(valuetype==V_ERROR) return;
4203 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4204 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4205 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4206 Error_Context cntxt(this, "In `%s' operation", opname);
4207 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4208 }
4209
4210 void Value::chk_expr_operand_activate_refd(Value *val,
4211 Ttcn::TemplateInstances* t_list2,
4212 Ttcn::ActualParList *&parlist,
4213 const char *,
4214 const char *opname)
4215 {
4216 if(valuetype==V_ERROR) return;
4217 Error_Context cntxt(this, "In `%s' operation", opname);
4218 Type *t = val->get_expr_governor_last();
4219 if (t) {
4220 switch (t->get_typetype()) {
4221 case Type::T_ERROR:
4222 set_valuetype(V_ERROR);
4223 break;
4224 case Type::T_ALTSTEP: {
4225 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4226 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4227 if(is_erroneous) {
4228 delete parlist;
4229 parlist = 0;
4230 set_valuetype(V_ERROR);
4231 } else {
4232 parlist->set_fullname(get_fullname());
4233 parlist->set_my_scope(get_my_scope());
4234 if (!fp_list->chk_activate_argument(parlist,
4235 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4236 }
4237 break; }
4238 default:
4239 error("Reference to an altstep was expected in the argument of "
4240 "`derefers()' instead of `%s'", t->get_typename().c_str());
4241 set_valuetype(V_ERROR);
4242 break;
4243 }
4244 } else set_valuetype(V_ERROR);
4245 }
4246
4247 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4248 const char *,
4249 const char *opname)
4250 {
4251 if(valuetype==V_ERROR) return;
4252 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4253 Error_Context cntxt(this, "In `%s' operation", opname);
4254 Assignment *t_ass = ref->get_refd_assignment();
4255 bool error_flag = false;
4256 if (t_ass) {
4257 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4258 ref->error("Reference to a testcase was expected in the argument "
4259 "instead of %s", t_ass->get_description().c_str());
4260 error_flag = true;
4261 }
4262 } else error_flag = true;
4263 if (val) {
4264 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4265 Value *v_last = val->get_value_refd_last();
4266 switch (v_last->valuetype) {
4267 case V_REAL: {
4268 ttcn3float v_real = v_last->get_val_Real();
4269 if (v_real < 0.0) {
4270 val->error("The testcase guard timer has negative value: `%s'",
4271 Real2string(v_real).c_str());
4272 error_flag = true;
4273 }
4274 break; }
4275 case V_ERROR:
4276 error_flag = true;
4277 break;
4278 default:
4279 break;
4280 }
4281 }
4282 if (error_flag) set_valuetype(V_ERROR);
4283 }
4284
4285 void Value::chk_expr_operand_execute_refd(Value *v1,
4286 Ttcn::TemplateInstances* t_list2,
4287 Ttcn::ActualParList *&parlist,
4288 Value *v3,
4289 const char *,
4290 const char *opname)
4291 {
4292 if(valuetype==V_ERROR) return;
4293 Error_Context cntxt(this, "In `%s' operation", opname);
4294 Type *t = v1->get_expr_governor_last();
4295 if (t) {
4296 switch (t->get_typetype()) {
4297 case Type::T_ERROR:
4298 set_valuetype(V_ERROR);
4299 break;
4300 case Type::T_TESTCASE: {
4301 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4302 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4303 if(is_erroneous) {
4304 delete parlist;
4305 parlist = 0;
4306 set_valuetype(V_ERROR);
4307 } else {
4308 parlist->set_fullname(get_fullname());
4309 parlist->set_my_scope(get_my_scope());
4310 }
4311 break; }
4312 default:
4313 v1->error("Reference to a value of type testcase was expected in the "
4314 "argument of `derefers()' instead of `%s'",
4315 t->get_typename().c_str());
4316 set_valuetype(V_ERROR);
4317 break;
4318 }
4319 } else set_valuetype(V_ERROR);
4320 if (v3) {
4321 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4322 Value *v_last = v3->get_value_refd_last();
4323 switch (v_last->valuetype) {
4324 case V_REAL: {
4325 ttcn3float v_real = v_last->get_val_Real();
4326 if(v_real < 0.0) {
4327 v3->error("The testcase guard timer has negative value: `%s'",
4328 Real2string(v_real).c_str());
4329 set_valuetype(V_ERROR);
4330 }
4331 break; }
4332 case V_ERROR:
4333 set_valuetype(V_ERROR);
4334 break;
4335 default:
4336 break;
4337 }
4338 }
4339 }
4340
4341 void Value::chk_invoke(Type::expected_value_t exp_val)
4342 {
4343 if(valuetype == V_ERROR) return;
4344 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4345 if(!u.invoke.t_list) return; //already checked
4346 Error_Context cntxt(this, "In `apply()' operation");
4347 Type *t = u.invoke.v->get_expr_governor_last();
4348 if (!t) {
4349 set_valuetype(V_ERROR);
4350 return;
4351 }
4352 switch (t->get_typetype()) {
4353 case Type::T_ERROR:
4354 set_valuetype(V_ERROR);
4355 return;
4356 case Type::T_FUNCTION:
4357 break;
4358 default:
4359 u.invoke.v->error("A value of type function was expected in the "
4360 "argument instead of `%s'", t->get_typename().c_str());
4361 set_valuetype(V_ERROR);
4362 return;
4363 }
4364 my_scope->chk_runs_on_clause(t, *this, "call");
4365 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4366 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4367 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4368 delete u.invoke.t_list;
4369 u.invoke.t_list = 0;
4370 if(is_erroneous) {
4371 delete parlist;
4372 u.invoke.ap_list = 0;
4373 } else {
4374 parlist->set_fullname(get_fullname());
4375 parlist->set_my_scope(get_my_scope());
4376 u.invoke.ap_list = parlist;
4377 }
4378 switch (exp_val) {
4379 case Type::EXPECTED_CONSTANT:
4380 error("An evaluable constant value was expected instead of operation "
4381 "`apply()'");
4382 set_valuetype(V_ERROR);
4383 break;
4384 case Type::EXPECTED_STATIC_VALUE:
4385 error("A static value was expected instead of operation `apply()'");
4386 set_valuetype(V_ERROR);
4387 break;
4388 default:
4389 break;
4390 } // switch
4391 }
4392
4393 void Value::chk_expr_eval_value(Value *val, Type &t,
4394 ReferenceChain *refch,
4395 Type::expected_value_t exp_val)
4396 {
4397 bool self_ref = false;
4398 if(valuetype==V_ERROR) return;
4399 // Commented out to report more errors :)
4400 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4401 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4402 switch(val->get_valuetype()) {
4403 case V_REFD:
4404 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4405 break;
4406 case V_EXPR:
4407 case V_MACRO:
4408 case V_INVOKE:
4409 val->get_value_refd_last(refch, exp_val);
4410 break;
4411 default:
4412 break;
4413 } // switch
4414 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4415
4416 (void)self_ref;
4417 }
4418
4419 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4420 ReferenceChain *refch, Type::expected_value_t exp_val)
4421 {
4422 bool self_ref = false;
4423 ti->chk(type);
4424 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4425 ti->error("Reference to a %s value was expected instead of an in-line "
4426 "modified template",
4427 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4428 set_valuetype(V_ERROR);
4429 return;
4430 }
4431 Template *templ = ti->get_Template();
4432 switch (templ->get_templatetype()) {
4433 case Template::TEMPLATE_REFD:
4434 // not foldable
4435 if (exp_val == Type::EXPECTED_TEMPLATE) {
4436 templ = templ->get_template_refd_last(refch);
4437 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4438 set_valuetype(V_ERROR);
4439 } else {
4440 ti->error("Reference to a %s value was expected instead of %s",
4441 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4442 templ->get_reference()->get_refd_assignment()
4443 ->get_description().c_str());
4444 set_valuetype(V_ERROR);
4445 }
4446 break;
4447 case Template::SPECIFIC_VALUE: {
4448 Value *val = templ->get_specific_value();
4449 switch (val->get_valuetype()) {
4450 case V_REFD:
4451 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4452 break;
4453 case V_EXPR:
4454 val->get_value_refd_last(refch, exp_val);
4455 default:
4456 break;
4457 } // switch
4458 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4459 break; }
4460 case Template::TEMPLATE_ERROR:
4461 set_valuetype(V_ERROR);
4462 break;
4463 default:
4464 break;
4465 } // switch
4466
4467 (void)self_ref;
4468 }
4469
4470 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4471 const char *opname)
4472 {
4473 if(valuetype==V_ERROR) return;
4474 if(u.expr.state==EXPR_CHECKING_ERR) return;
4475 if(val->is_unfoldable()) return;
4476 if(*val->get_val_Int()<0) {
4477 val->error("%s operand of operation `%s' should not be negative",
4478 opnum, opname);
4479 set_valuetype(V_ERROR);
4480 }
4481 }
4482
4483 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4484 const char *opname)
4485 {
4486 if(valuetype==V_ERROR) return;
4487 if(u.expr.state==EXPR_CHECKING_ERR) return;
4488 if(val->is_unfoldable()) return;
4489 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4490 val->error("%s operand of operation `%s' should be in range 0..127",
4491 opnum, opname);
4492 set_valuetype(V_ERROR);
4493 }
4494 }
4495
4496 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4497 const char *opname)
4498 {
4499 if(valuetype==V_ERROR) return;
4500 if(u.expr.state==EXPR_CHECKING_ERR) return;
4501 if(val->is_unfoldable()) return;
4502 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4503 val->error("%s operand of operation `%s' should be in range"
4504 " 0..2147483647", opnum, opname);
4505 set_valuetype(V_ERROR);
4506 }
4507 }
4508
4509 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4510 const char *opname)
4511 {
4512 if(valuetype==V_ERROR) return;
4513 if(u.expr.state==EXPR_CHECKING_ERR) return;
4514 if(val->is_unfoldable()) return;
4515 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4516 ||
4517 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4518 {
4519 val->error("%s operand of operation `%s' should not be zero",
4520 opnum, opname);
4521 set_valuetype(V_ERROR);
4522 }
4523 }
4524
4525 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4526 const char *opname)
4527 {
4528 if (valuetype == V_ERROR) return;
4529 if (u.expr.state == EXPR_CHECKING_ERR) return;
4530 if (val->get_expr_returntype() != Type::T_INT) return;
4531 if (val->is_unfoldable()) return;
4532 const int_val_t *val_int = val->get_val_Int();
4533 if (*val_int > static_cast<Int>(INT_MAX)) {
4534 val->error("%s operand of operation `%s' should be less than `%d' "
4535 "instead of `%s'", opnum, opname, INT_MAX,
4536 (val_int->t_str()).c_str());
4537 set_valuetype(V_ERROR);
4538 }
4539 }
4540
4541 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4542 const char *opname)
4543 {
4544 if(valuetype==V_ERROR) return;
4545 if(u.expr.state==EXPR_CHECKING_ERR) return;
4546 if(val->is_unfoldable()) return;
4547 if(val->get_val_strlen()!=1) {
4548 val->error("%s operand of operation `%s' should be of length 1",
4549 opnum, opname);
4550 set_valuetype(V_ERROR);
4551 }
4552 }
4553
4554 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4555 const char *opname)
4556 {
4557 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4558 Value *v_last = val->get_value_refd_last();
4559 if (v_last->valuetype == V_CSTR) {
4560 size_t len = v_last->get_val_strlen();
4561 if (len % 2) {
4562 val->error("%s operand of operation `%s' should contain even number "
4563 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4564 set_valuetype(V_ERROR);
4565 }
4566 } else if (v_last->valuetype == V_REFD) {
4567 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4568 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4569 val->error("%s operand of operation `%s' should contain even number "
4570 "of characters, but a string element contains 1", opnum, opname);
4571 set_valuetype(V_ERROR);
4572 }
4573 }
4574 }
4575
4576 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4577 const char *opname)
4578 {
4579 if(valuetype==V_ERROR) return;
4580 if(u.expr.state==EXPR_CHECKING_ERR) return;
4581 if(val->is_unfoldable()) return;
4582 const string& s=val->get_val_str();
4583 for(size_t i=0; i<s.size(); i++) {
4584 char c=s[i];
4585 if(!(c=='0' || c=='1')) {
4586 val->error("%s operand of operation `%s' can contain only"
4587 " binary digits (position %lu is `%c')",
4588 opnum, opname, (unsigned long) i, c);
4589 set_valuetype(V_ERROR);
4590 return;
4591 }
4592 }
4593 }
4594
4595 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4596 const char *opname)
4597 {
4598 if(valuetype==V_ERROR) return;
4599 if(u.expr.state==EXPR_CHECKING_ERR) return;
4600 if(val->is_unfoldable()) return;
4601 const string& s=val->get_val_str();
4602 for(size_t i=0; i<s.size(); i++) {
4603 char c=s[i];
4604 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4605 val->error("%s operand of operation `%s' can contain only valid "
4606 "hexadecimal digits (position %lu is `%c')",
4607 opnum, opname, (unsigned long) i, c);
4608 set_valuetype(V_ERROR);
4609 return;
4610 }
4611 }
4612 }
4613
4614 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4615 const char *opname)
4616 {
4617 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4618 Value *v = val->get_value_refd_last();
4619 if (v->valuetype != V_OSTR) return;
4620 const string& s = val->get_val_str();
4621 size_t n_octets = s.size() / 2;
4622 for (size_t i = 0; i < n_octets; i++) {
4623 char c = s[2 * i];
4624 if (!(c >= '0' && c <= '7')) {
4625 val->error("%s operand of operation `%s' shall consist of octets "
4626 "within the range 00 .. 7F, but the string `%s'O contains octet "
4627 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4628 (unsigned long) i);
4629 set_valuetype(V_ERROR);
4630 return;
4631 }
4632 }
4633 }
4634
4635 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4636 const char *opname)
4637 {
4638 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4639 Value *v_last = val->get_value_refd_last();
4640 if (v_last->valuetype != V_CSTR) return;
4641 const string& s = v_last->get_val_str();
4642 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4643 state = S_INITIAL;
4644 // state: expected characters
4645 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4646 // S_FIRST: first digit
4647 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4648 // S_END: trailing whitespace
4649 // S_ERR: error was found, stop
4650 for (size_t i = 0; i < s.size(); i++) {
4651 char c = s[i];
4652 switch (state) {
4653 case S_INITIAL:
4654 case S_INITIAL_WS:
4655 if (c == '+' || c == '-') state = S_FIRST;
4656 else if (c == '0') state = S_ZERO;
4657 else if (c >= '1' && c <= '9') state = S_MORE;
4658 else if (string::is_whitespace(c)) {
4659 if (state == S_INITIAL) {
4660 val->warning("Leading whitespace was detected and ignored in the "
4661 "operand of operation `%s'", opname);
4662 state = S_INITIAL_WS;
4663 }
4664 } else state = S_ERR;
4665 break;
4666 case S_FIRST:
4667 if (c == '0') state = S_ZERO;
4668 else if (c >= '1' && c <= '9') state = S_MORE;
4669 else state = S_ERR;
4670 break;
4671 case S_ZERO:
4672 if (c >= '0' && c <= '9') {
4673 val->warning("Leading zero digit was detected and ignored in the "
4674 "operand of operation `%s'", opname);
4675 state = S_MORE;
4676 } else if (string::is_whitespace(c)) state = S_END;
4677 else state = S_ERR;
4678 break;
4679 case S_MORE:
4680 if (c >= '0' && c <= '9') {}
4681 else if (string::is_whitespace(c)) state = S_END;
4682 else state = S_ERR;
4683 break;
4684 case S_END:
4685 if (!string::is_whitespace(c)) state = S_ERR;
4686 break;
4687 default:
4688 break;
4689 }
4690 if (state == S_ERR) {
4691 if (string::is_printable(c)) {
4692 val->error("%s operand of operation `%s' should be a string "
4693 "containing a valid integer value, but invalid character `%c' "
4694 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4695 } else {
4696 val->error("%s operand of operation `%s' should be a string "
4697 "containing a valid integer value, but invalid character with "
4698 "character code %u was detected at index %lu", opnum, opname, c,
4699 (unsigned long) i);
4700 }
4701 set_valuetype(V_ERROR);
4702 break;
4703 }
4704 }
4705 switch (state) {
4706 case S_INITIAL:
4707 case S_INITIAL_WS:
4708 val->error("%s operand of operation `%s' should be a string containing a "
4709 "valid integer value instead of an empty string", opnum, opname);
4710 set_valuetype(V_ERROR);
4711 break;
4712 case S_FIRST:
4713 val->error("%s operand of operation `%s' should be a string containing a "
4714 "valid integer value, but only a sign character was detected", opnum,
4715 opname);
4716 set_valuetype(V_ERROR);
4717 break;
4718 case S_END:
4719 val->warning("Trailing whitespace was detected and ignored in the "
4720 "operand of operation `%s'", opname);
4721 break;
4722 default:
4723 break;
4724 }
4725 }
4726
4727 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4728 const char *opname)
4729 {
4730 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4731 Value *v_last = val->get_value_refd_last();
4732 if (v_last->valuetype == V_REFD) {
4733 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4734 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4735 val->error("%s operand of operation `%s' should be a string containing "
4736 "a valid float value instead of a string element, which cannot "
4737 "represent a floating point number", opnum, opname);
4738 set_valuetype(V_ERROR);
4739 }
4740 return;
4741 } else if (v_last->valuetype != V_CSTR) return;
4742 const string& s = v_last->get_val_str();
4743 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4744 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4745 state = S_INITIAL;
4746 // state: expected characters
4747 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4748 // leading whitespace
4749 // S_FIRST_M: first digit of integer part in mantissa
4750 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4751 // S_FIRST_F: first digit of fraction
4752 // S_MORE_F: more digits of fraction, E, trailing whitespace
4753 // S_INITIAL_E: +, -, first digit of exponent
4754 // S_FIRST_E: first digit of exponent
4755 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4756 // S_END: trailing whitespace
4757 // S_ERR: error was found, stop
4758 for (size_t i = 0; i < s.size(); i++) {
4759 char c = s[i];
4760 switch (state) {
4761 case S_INITIAL:
4762 case S_INITIAL_WS:
4763 if (c == '+' || c == '-') state = S_FIRST_M;
4764 else if (c == '0') state = S_ZERO_M;
4765 else if (c >= '1' && c <= '9') state = S_MORE_M;
4766 else if (string::is_whitespace(c)) {
4767 if (state == S_INITIAL) {
4768 val->warning("Leading whitespace was detected and ignored in the "
4769 "operand of operation `%s'", opname);
4770 state = S_INITIAL_WS;
4771 }
4772 } else state = S_ERR;
4773 break;
4774 case S_FIRST_M:
4775 if (c == '0') state = S_ZERO_M;
4776 else if (c >= '1' && c <= '9') state = S_MORE_M;
4777 else state = S_ERR;
4778 break;
4779 case S_ZERO_M:
4780 if (c == '.') state = S_FIRST_F;
4781 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4782 else if (c >= '0' && c <= '9') {
4783 val->warning("Leading zero digit was detected and ignored in the "
4784 "mantissa of the operand of operation `%s'", opname);
4785 state = S_MORE_M;
4786 } else state = S_ERR;
4787 break;
4788 case S_MORE_M:
4789 if (c == '.') state = S_FIRST_F;
4790 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4791 else if (c >= '0' && c <= '9') {}
4792 else state = S_ERR;
4793 break;
4794 case S_FIRST_F:
4795 if (c >= '0' && c <= '9') state = S_MORE_F;
4796 else state = S_ERR;
4797 break;
4798 case S_MORE_F:
4799 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4800 else if (c >= '0' && c <= '9') {}
4801 else if (string::is_whitespace(c)) state = S_END;
4802 else state = S_ERR;
4803 break;
4804 case S_INITIAL_E:
4805 if (c == '+' || c == '-') state = S_FIRST_E;
4806 else if (c == '0') state = S_ZERO_E;
4807 else if (c >= '1' && c <= '9') state = S_MORE_E;
4808 else state = S_ERR;
4809 break;
4810 case S_FIRST_E:
4811 if (c == '0') state = S_ZERO_E;
4812 else if (c >= '1' && c <= '9') state = S_MORE_E;
4813 else state = S_ERR;
4814 break;
4815 case S_ZERO_E:
4816 if (c >= '0' && c <= '9') {
4817 val->warning("Leading zero digit was detected and ignored in the "
4818 "exponent of the operand of operation `%s'", opname);
4819 state = S_MORE_E;
4820 } else if (string::is_whitespace(c)) state = S_END;
4821 else state = S_ERR;
4822 break;
4823 case S_MORE_E:
4824 if (c >= '0' && c <= '9') {}
4825 else if (string::is_whitespace(c)) state = S_END;
4826 else state = S_ERR;
4827 break;
4828 case S_END:
4829 if (!string::is_whitespace(c)) state = S_ERR;
4830 break;
4831 default:
4832 break;
4833 }
4834 if (state == S_ERR) {
4835 if (string::is_printable(c)) {
4836 val->error("%s operand of operation `%s' should be a string "
4837 "containing a valid float value, but invalid character `%c' "
4838 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4839 } else {
4840 val->error("%s operand of operation `%s' should be a string "
4841 "containing a valid float value, but invalid character with "
4842 "character code %u was detected at index %lu", opnum, opname, c,
4843 (unsigned long) i);
4844 }
4845 set_valuetype(V_ERROR);
4846 break;
4847 }
4848 }
4849 switch (state) {
4850 case S_INITIAL:
4851 case S_INITIAL_WS:
4852 val->error("%s operand of operation `%s' should be a string containing a "
4853 "valid float value instead of an empty string", opnum, opname);
4854 set_valuetype(V_ERROR);
4855 break;
4856 case S_FIRST_M:
4857 val->error("%s operand of operation `%s' should be a string containing a "
4858 "valid float value, but only a sign character was detected", opnum,
4859 opname);
4860 set_valuetype(V_ERROR);
4861 break;
4862 case S_ZERO_M:
4863 case S_MORE_M:
4864 // HL67862: Missing decimal dot allowed for str2float
4865 break;
4866 case S_FIRST_F:
4867 // HL67862: Missing fraction part is allowed for str2float
4868 break;
4869 case S_INITIAL_E:
4870 case S_FIRST_E:
4871 val->error("%s operand of operation `%s' should be a string containing a "
4872 "valid float value, but the exponent is missing after the `E' sign",
4873 opnum, opname);
4874 set_valuetype(V_ERROR);
4875 break;
4876 case S_END:
4877 val->warning("Trailing whitespace was detected and ignored in the "
4878 "operand of operation `%s'", opname);
4879 break;
4880 default:
4881 break;
4882 }
4883 }
4884
4885 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
4886 const char *opname)
4887 {
4888 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4889 Value *v = val->get_value_refd_last();
4890 if (v->valuetype != V_USTR) return;
4891 const ustring& us = v->get_val_ustr();
4892 for (size_t i = 0; i < us.size(); i++) {
4893 const ustring::universal_char& uchar = us[i];
4894 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
4895 uchar.cell > 127) {
4896 val->error("%s operand of operation `%s' shall consist of characters "
4897 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4898 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4899 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
4900 uchar.row, uchar.cell, (unsigned long) i);
4901 set_valuetype(V_ERROR);
4902 return;
4903 }
4904 }
4905 }
4906
4907 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
4908 const char *opname)
4909 {
4910 if(valuetype==V_ERROR) return;
4911 if(u.expr.state==EXPR_CHECKING_ERR) return;
4912 if(val->is_unfoldable()) return;
4913 const string& bstr=val->get_val_str();
4914 // see also PredefFunc.cc::bit2int()
4915 size_t nof_bits = bstr.size();
4916 // skip the leading zeros
4917 size_t start_index = 0;
4918 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
4919 // check whether the remaining bits fit in Int
4920 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
4921 val->error("%s operand of operation `%s' is too large (maximum number"
4922 " of bits in integer is %lu)",
4923 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4924 set_valuetype(V_ERROR);
4925 }
4926 }
4927
4928 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
4929 const char *opname)
4930 {
4931 if(valuetype==V_ERROR) return;
4932 if(u.expr.state==EXPR_CHECKING_ERR) return;
4933 if(val->is_unfoldable()) return;
4934 const string& hstr=val->get_val_str();
4935 // see also PredefFunc.cc::hex2int()
4936 size_t nof_digits = hstr.size();
4937 // skip the leading zeros
4938 size_t start_index = 0;
4939 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
4940 // check whether the remaining hex digits fit in Int
4941 if (nof_digits - start_index > 2 * sizeof(Int) ||
4942 (nof_digits - start_index == 2 * sizeof(Int) &&
4943 char_to_hexdigit(hstr[start_index]) > 7)) {
4944 val->error("%s operand of operation `%s' is too large (maximum number"
4945 " of bits in integer is %lu)",
4946 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4947 set_valuetype(V_ERROR);
4948 }
4949 }
4950
4951 void Value::chk_expr_operands_int2binstr()
4952 {
4953 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4954 if (u.expr.v1->is_unfoldable()) return;
4955 if (u.expr.v2->is_unfoldable()) return;
4956 // It is already checked that i1 and i2 are non-negative.
4957 Error_Context cntxt(this, "In operation `%s'", get_opname());
4958 const int_val_t *i1 = u.expr.v1->get_val_Int();
4959 const int_val_t *i2 = u.expr.v2->get_val_Int();
4960 if (!i2->is_native()) {
4961 u.expr.v2->error("The length of the resulting string is too large for "
4962 "being represented in memory");
4963 set_valuetype(V_ERROR);
4964 return;
4965 }
4966 Int nof_bits = i2->get_val();
4967 if (u.expr.v1->is_unfoldable()) return;
4968 switch (u.expr.v_optype) {
4969 case OPTYPE_INT2BIT:
4970 break;
4971 case OPTYPE_INT2HEX:
4972 nof_bits *= 4;
4973 break;
4974 case OPTYPE_INT2OCT:
4975 nof_bits *= 8;
4976 break;
4977 default:
4978 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
4979 }
4980 if (*i1 >> nof_bits > 0) { // Expensive?
4981 u.expr.v1->error("Value %s does not fit in length %s",
4982 i1->t_str().c_str(), i2->t_str().c_str());
4983 set_valuetype(V_ERROR);
4984 }
4985 }
4986
4987 void Value::chk_expr_operands_str_samelen()
4988 {
4989 if(valuetype==V_ERROR) return;
4990 if(u.expr.state==EXPR_CHECKING_ERR) return;
4991 Value *v1=u.expr.v1;
4992 if(v1->is_unfoldable()) return;
4993 Value *v2=u.expr.v2;
4994 if(v2->is_unfoldable()) return;
4995 Error_Context cntxt(this, "In operation `%s'", get_opname());
4996 size_t i1=v1->get_val_strlen();
4997 size_t i2=v2->get_val_strlen();
4998 if(i1!=i2) {
4999 error("The operands should have the same length");
5000 set_valuetype(V_ERROR);
5001 }
5002 }
5003
5004 void Value::chk_expr_operands_replace()
5005 {
5006 // The fourth operand doesn't need to be checked at all here.
5007 if(valuetype==V_ERROR) return;
5008 if(u.expr.state==EXPR_CHECKING_ERR) return;
5009 Value* v1 = u.expr.ti1->get_specific_value();
5010 if (!v1) return;
5011
5012 Error_Context cntxt(this, "In operation `%s'", get_opname());
5013 size_t list_len = 0;
5014 bool list_len_known = false;
5015 if (v1->valuetype == V_REFD) {
5016 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5017 if (subrefs && subrefs->refers_to_string_element()) {
5018 warning("Replacing a string element does not make any sense");
5019 list_len = 1;
5020 list_len_known = true;
5021 }
5022 }
5023 if (!v1->is_unfoldable()) {
5024 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5025 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5026 list_len_known = true;
5027 }
5028 if (!list_len_known) return;
5029 if (u.expr.v2->is_unfoldable()) {
5030 if (!u.expr.v3->is_unfoldable()) {
5031 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5032 if (*len_int_3 > static_cast<Int>(list_len)) {
5033 error("Third operand `len' (%s) is greater than the length of "
5034 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5035 (unsigned long)list_len);
5036 set_valuetype(V_ERROR);
5037 }
5038 }
5039 } else {
5040 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5041 if (u.expr.v3->is_unfoldable()) {
5042 if (*index_int_2 > static_cast<Int>(list_len)) {
5043 error("Second operand `index' (%s) is greater than the length of "
5044 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5045 (unsigned long)list_len);
5046 set_valuetype(V_ERROR);
5047 }
5048 } else {
5049 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5050 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5051 error("The sum of second operand `index' (%s) and third operand "
5052 "`len' (%s) is greater than the length of the first operand (%lu)",
5053 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5054 (unsigned long)list_len);
5055 set_valuetype(V_ERROR);
5056 }
5057 }
5058 }
5059 }
5060
5061 void Value::chk_expr_operands_substr()
5062 {
5063 if(valuetype==V_ERROR) return;
5064 if(u.expr.state==EXPR_CHECKING_ERR) return;
5065 Value* v1 = u.expr.ti1->get_specific_value();
5066 if (!v1) return;
5067
5068 Error_Context cntxt(this, "In operation `%s'", get_opname());
5069 size_t list_len = 0;
5070 bool list_len_known = false;
5071 if (v1->valuetype == V_REFD) {
5072 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5073 if (subrefs && subrefs->refers_to_string_element()) {
5074 warning("Taking the substring of a string element does not make any "
5075 "sense");
5076 list_len = 1;
5077 list_len_known = true;
5078 }
5079 }
5080 if (!list_len_known && !v1->is_unfoldable()) {
5081 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5082 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5083 list_len_known = true;
5084 }
5085 // Do nothing if the length of the first operand is unknown.
5086 if (!list_len_known) return;
5087 if (u.expr.v2->is_unfoldable()) {
5088 if (!u.expr.v3->is_unfoldable()) {
5089 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5090 // Only the third operand is known.
5091 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5092 error("Third operand `returncount' (%s) is greater than the "
5093 "length of the first operand (%lu)",
5094 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5095 set_valuetype(V_ERROR);
5096 }
5097 }
5098 } else {
5099 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5100 if (u.expr.v3->is_unfoldable()) {
5101 // Only the second operand is known.
5102 if (*index_int_2 > static_cast<Int>(list_len)) {
5103 error("Second operand `index' (%s) is greater than the length "
5104 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5105 (unsigned long)list_len);
5106 set_valuetype(V_ERROR);
5107 }
5108 } else {
5109 // Both second and third operands are known.
5110 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5111 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5112 error("The sum of second operand `index' (%s) and third operand "
5113 "`returncount' (%s) is greater than the length of the first operand "
5114 "(%lu)", (index_int_2->t_str()).c_str(),
5115 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5116 set_valuetype(V_ERROR);
5117 }
5118 }
5119 }
5120 }
5121
5122 void Value::chk_expr_operands_regexp()
5123 {
5124 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5125 Value* v1 = u.expr.ti1->get_specific_value();
5126 Value* v2 = u.expr.t2->get_specific_value();
5127 if (!v1 || !v2) return;
5128
5129 Error_Context cntxt(this, "In operation `regexp()'");
5130 Value* v1_last = v1->get_value_refd_last();
5131 if (v1_last->valuetype == V_CSTR) {
5132 // the input string is available at compile time
5133 const string& instr = v1_last->get_val_str();
5134 const char *input_str = instr.c_str();
5135 size_t instr_len = strlen(input_str);
5136 if (instr_len < instr.size()) {
5137 v1->warning("The first operand of `regexp()' contains a "
5138 "character with character code zero at index %s. The rest of the "
5139 "string will be ignored during matching",
5140 Int2string(instr_len).c_str());
5141 }
5142 }
5143
5144 size_t nof_groups = 0;
5145 Value *v2_last = v2->get_value_refd_last();
5146
5147 if (v2_last->valuetype == V_CSTR) {
5148 // the pattern is available at compile time
5149 const string& expression = v2_last->get_val_str();
5150 const char *pattern_str = expression.c_str();
5151 size_t pattern_len = strlen(pattern_str);
5152 if (pattern_len < expression.size()) {
5153 v2->warning("The second operand of `regexp()' contains a "
5154 "character with character code zero at index %s. The rest of the "
5155 "string will be ignored during matching",
5156 Int2string(pattern_len).c_str());
5157 }
5158 char *posix_str;
5159 {
5160 Error_Context cntxt2(v2, "In character string pattern");
5161 posix_str = TTCN_pattern_to_regexp(pattern_str);
5162 }
5163 if (posix_str != NULL) {
5164 regex_t posix_regexp;
5165 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5166 if (ret_val != 0) {
5167 char msg[512];
5168 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5169 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5170 "regcomp() failed: %s", msg);
5171 }
5172 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5173 else {
5174 v2->error("The character pattern in the second operand of "
5175 "`regexp()' does not contain any groups");
5176 set_valuetype(V_ERROR);
5177 }
5178 regfree(&posix_regexp);
5179 Free(posix_str);
5180 } else {
5181 // the pattern is faulty
5182 // the error has been reported by TTCN_pattern_to_regexp
5183 set_valuetype(V_ERROR);
5184 }
5185 }
5186 if (nof_groups > 0) {
5187 Value *v3 = u.expr.v3->get_value_refd_last();
5188 if (v3->valuetype == V_INT) {
5189 // the group number is available at compile time
5190 const int_val_t *groupno_int = v3->get_val_Int();
5191 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5192 u.expr.v3->error("The the third operand of `regexp()' is too "
5193 "large: The requested group index is %s, but the pattern "
5194 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5195 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5196 set_valuetype(V_ERROR);
5197 }
5198 }
5199 }
5200 }
5201
5202 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5203 Type::expected_value_t exp_val)
5204 {
5205 const char *opname = get_opname();
5206 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5207 Type *t_governor;
5208 const Location *loc;
5209 bool error_flag = false;
5210 switch (u.expr.v_optype) {
5211 case OPTYPE_ISCHOSEN_V:
5212 // u.expr.v1 is always a referenced value
5213 t_governor = u.expr.v1->get_expr_governor(exp_val);
5214 if (t_governor) {
5215 u.expr.v1->set_my_governor(t_governor);
5216 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5217 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5218 } else error_flag = true;
5219 loc = u.expr.v1;
5220 break;
5221 case OPTYPE_ISCHOSEN_T:
5222 // u.expr.t1 is always a referenced template
5223 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5224 exp_val = Type::EXPECTED_TEMPLATE;
5225 t_governor = u.expr.t1->get_expr_governor(exp_val);
5226 if (t_governor) {
5227 u.expr.t1->set_my_governor(t_governor);
5228 //
5229 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5230 //
5231 u.expr.t1->get_template_refd_last(refch);
5232 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5233 error_flag = true;
5234 } else error_flag = true;
5235 if (exp_val != Type::EXPECTED_TEMPLATE) {
5236 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5237 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5238 u.expr.t1->get_reference()->get_refd_assignment()
5239 ->get_description().c_str());
5240 error_flag = true;
5241 }
5242 loc = u.expr.t1;
5243 break;
5244 default:
5245 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5246 t_governor = 0;
5247 loc = 0;
5248 }
5249 if (t_governor) {
5250 t_governor = t_governor->get_type_refd_last();
5251 switch (t_governor->get_typetype()) {
5252 case Type::T_ERROR:
5253 error_flag = true;
5254 break;
5255 case Type::T_CHOICE_A:
5256 case Type::T_CHOICE_T:
5257 case Type::T_ANYTYPE:
5258 case Type::T_OPENTYPE:
5259 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5260 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5261 "%s does not have a field named `%s'" :
5262 "Union type `%s' does not have a field named `%s'",
5263 t_governor->get_typename().c_str(),
5264 u.expr.i2->get_dispname().c_str());
5265 error_flag = true;
5266 }
5267 break;
5268 default:
5269 loc->error("The operand of operation `%s' should be a union value "
5270 "or template instead of `%s'", opname,
5271 t_governor->get_typename().c_str());
5272 error_flag = true;
5273 break;
5274 }
5275 }
5276 if (error_flag) set_valuetype(V_ERROR);
5277 }
5278
5279 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5280 Type::expected_value_t exp_val) {
5281
5282 Error_Context cntxt(this, "In the parameter of encvalue()");
5283 Type t_chk(Type::T_ERROR);
5284 Type* t_type;
5285
5286 Type::expected_value_t ti_exp_val = exp_val;
5287 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5288 ti_exp_val = Type::EXPECTED_TEMPLATE;
5289
5290 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5291 if (t_type) {
5292 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5293 if (valuetype!=V_ERROR)
5294 u.expr.ti1->get_Template()->chk_specific_value(false);
5295 t_type = t_type->get_type_refd_last();
5296 } else {
5297 error("Cannot determine type of value");
5298 goto error;
5299 }
5300
5301 // todo: fix this
5302 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5303 error("Expecting a value of a type with coding attributes in first"
5304 "parameter of encvalue() which belongs to a generic type '%s'",
5305 t_type->get_typename().c_str());
5306 goto error;
5307 }*/
5308
5309 if(!disable_attribute_validation()) {
5310 t_type->chk_coding(true);
5311 }
5312
5313 switch (t_type->get_typetype()) {
5314 case Type::T_UNDEF:
5315 case Type::T_ERROR:
5316 case Type::T_NULL:
5317 case Type::T_REFD:
5318 case Type::T_REFDSPEC:
5319 case Type::T_SELTYPE:
5320 case Type::T_VERDICT:
5321 case Type::T_PORT:
5322 case Type::T_COMPONENT:
5323 case Type::T_DEFAULT:
5324 case Type::T_SIGNATURE:
5325 case Type::T_FUNCTION:
5326 case Type::T_ALTSTEP:
5327 case Type::T_TESTCASE:
5328 error("Type of parameter of encvalue() cannot be '%s'",
5329 t_type->get_typename().c_str());
5330 goto error;
5331 default:
5332 break;
5333 }
5334 return;
5335 error:
5336 set_valuetype(V_ERROR);
5337 }
5338
5339 void Value::chk_expr_operands_decode()
5340 {
5341 Error_Context cntxt(this, "In the parameters of decvalue()");
5342 Ttcn::Ref_base* ref = u.expr.r1;
5343 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5344 Type* t_type = 0;
5345 Assignment* t_ass = ref->get_refd_assignment();
5346
5347 if (!t_ass) {
5348 error("Could not determine the assignment for first parameter");
5349 goto error;
5350 }
5351 switch (t_ass->get_asstype()) {
5352 case Assignment::A_PAR_VAL_IN:
5353 t_ass->use_as_lvalue(*this);
5354 break;
5355 case Assignment::A_CONST:
5356 case Assignment::A_EXT_CONST:
5357 case Assignment::A_MODULEPAR:
5358 case Assignment::A_MODULEPAR_TEMP:
5359 case Assignment::A_TEMPLATE:
5360 ref->error("Reference to '%s' cannot be used as the first operand of "
5361 "the 'decvalue' operation", t_ass->get_assname());
5362 goto error;
5363 break;
5364 case Assignment::A_VAR:
5365 case Assignment::A_PAR_VAL_OUT:
5366 case Assignment::A_PAR_VAL_INOUT:
5367 break;
5368 case Assignment::A_VAR_TEMPLATE:
5369 case Assignment::A_PAR_TEMPL_IN:
5370 case Assignment::A_PAR_TEMPL_OUT:
5371 case Assignment::A_PAR_TEMPL_INOUT: {
5372 Template* t = new Template(ref->clone());
5373 t->set_location(*ref);
5374 t->set_my_scope(get_my_scope());
5375 t->set_fullname(get_fullname()+".<operand>");
5376 Template* t_last = t->get_template_refd_last();
5377 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5378 && t_last != t) {
5379 ref->error("Specific value template was expected instead of '%s'.",
5380 t->get_template_refd_last()->get_templatetype_str());
5381 delete t;
5382 goto error;
5383 }
5384 delete t;
5385 break; }
5386 default:
5387 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5388 goto error;
5389 }
5390 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5391 Type::EXPECTED_DYNAMIC_VALUE);
5392 if (!t_type) {
5393 goto error;
5394 }
5395 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5396 error("First parameter has to be a bitstring");
5397 goto error;
5398 }
5399
5400 ref = u.expr.r2;
5401 t_subrefs = ref->get_subrefs();
5402 t_ass = ref->get_refd_assignment();
5403
5404 if (!t_ass) {
5405 error("Could not determine the assignment for second parameter");
5406 goto error;
5407 }
5408 // Extra check for HM59355.
5409 switch (t_ass->get_asstype()) {
5410 case Assignment::A_VAR:
5411 case Assignment::A_PAR_VAL_IN:
5412 case Assignment::A_PAR_VAL_OUT:
5413 case Assignment::A_PAR_VAL_INOUT:
5414 break;
5415 default:
5416 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5417 goto error;
5418 }
5419 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5420 Type::EXPECTED_DYNAMIC_VALUE);
5421 if (!t_type) {
5422 goto error;
5423 }
5424 t_type = t_type->get_type_refd_last();
5425 switch (t_type->get_typetype()) {
5426 case Type::T_UNDEF:
5427 case Type::T_ERROR:
5428 case Type::T_NULL:
5429 case Type::T_REFD:
5430 case Type::T_REFDSPEC:
5431 case Type::T_SELTYPE:
5432 case Type::T_VERDICT:
5433 case Type::T_PORT:
5434 case Type::T_COMPONENT:
5435 case Type::T_DEFAULT:
5436 case Type::T_SIGNATURE:
5437 case Type::T_FUNCTION:
5438 case Type::T_ALTSTEP:
5439 case Type::T_TESTCASE:
5440 error("Type of second parameter cannot be %s",
5441 t_type->get_typename().c_str());
5442 goto error;
5443 default:
5444 break;
5445 }
5446
5447 if(!disable_attribute_validation()) {
5448 t_type->chk_coding(false);
5449 }
5450
5451 return;
5452 error:
5453 set_valuetype(V_ERROR);
5454 }
5455
5456 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5457 {
5458 Ttcn::FieldOrArrayRefs *subrefs;
5459 Identifier *field_id = 0;
5460 Assignment *t_ass;
5461 Type *t_type;
5462 if (valuetype == V_ERROR) return;
5463 else if (valuetype != V_REFD) {
5464 error("Only a referenced value can be compared with `omit'");
5465 goto error;
5466 }
5467 subrefs = u.ref.ref->get_subrefs();
5468 if (subrefs) field_id = subrefs->remove_last_field();
5469 if (!field_id) {
5470 error("Only a reference pointing to an optional record or set field "
5471 "can be compared with `omit'");
5472 goto error;
5473 }
5474 t_ass = u.ref.ref->get_refd_assignment();
5475 if (!t_ass) goto error;
5476 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5477 if (!t_type) goto error;
5478 t_type = t_type->get_type_refd_last();
5479 switch (t_type->get_typetype()) {
5480 case Type::T_ERROR:
5481 goto error;
5482 case Type::T_SEQ_A:
5483 case Type::T_SEQ_T:
5484 case Type::T_SET_A:
5485 case Type::T_SET_T:
5486 break;
5487 default:
5488 error("Only a reference pointing to an optional field of a record"
5489 " or set type can be compared with `omit'");
5490 goto error;
5491 }
5492 if (!t_type->has_comp_withName(*field_id)) {
5493 error("Type `%s' does not have field named `%s'",
5494 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5495 goto error;
5496 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5497 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5498 "`omit'", field_id->get_dispname().c_str(),
5499 t_type->get_typename().c_str());
5500 goto error;
5501 }
5502 // putting the last field_id back to subrefs
5503 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5504 return;
5505 error:
5506 set_valuetype(V_ERROR);
5507 delete field_id;
5508 }
5509
5510 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5511 Type::expected_value_t exp_val)
5512 {
5513 if(valuetype==V_ERROR) return -1;
5514 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5515 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5516 exp_val=Type::EXPECTED_TEMPLATE;
5517
5518 Error_Context cntxt(this, "In the operand of"
5519 " operation `%s'", get_opname());
5520
5521 Int result = -1;
5522 Template* t_templ = u.expr.ti1->get_Template();
5523
5524 if (!t_templ) {
5525 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5526 }
5527
5528 t_templ = t_templ->get_template_refd_last(refch);
5529
5530 // Timer and port arrays are handled separately
5531 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5532 Value* val = t_templ->get_specific_value();
5533 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5534 val->set_lowerid_to_ref();
5535 }
5536 if (val && val->get_valuetype() == V_REFD) {
5537 Reference* ref = val->get_reference();
5538 Assignment* t_ass = ref->get_refd_assignment();
5539 Common::Assignment::asstype_t asstype =
5540 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5541 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5542 if (t_ass->get_Dimensions()) {
5543 // here we have a timer or port array
5544 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5545 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5546 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5547 Type::EXPECTED_DYNAMIC_VALUE);
5548 size_t refd_dim;
5549 if (t_subrefs) {
5550 refd_dim = t_subrefs->get_nof_refs();
5551 size_t nof_dims = t_dims->get_nof_dims();
5552 if (refd_dim >= nof_dims) {
5553 u.expr.ti1->error("Operation is not applicable to a %s",
5554 t_ass->get_assname());
5555 set_valuetype(V_ERROR);
5556 return -1;
5557 }
5558 } else refd_dim = 0;
5559 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5560 } else {
5561 u.expr.ti1->error("Operation is not applicable to single `%s'",
5562 t_ass->get_description().c_str());
5563 set_valuetype(V_ERROR);
5564 return -1;
5565 }
5566 }
5567 }
5568 }
5569
5570 Value* t_val = 0;
5571 Type* t_type = 0;
5572 Assignment* t_ass = 0;
5573 Reference* ref = 0;
5574 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5575 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5576 if (t_type) {
5577 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5578 t_type = t_type->get_type_refd_last();
5579 } else {
5580 error("Cannot determine type of value");
5581 goto error;
5582 }
5583
5584 if(valuetype==V_ERROR) return -1;
5585
5586 t_templ = t_templ->get_template_refd_last(refch);
5587 switch(t_templ->get_templatetype()) {
5588 case Template::TEMPLATE_ERROR:
5589 goto error;
5590 case Template::INDEXED_TEMPLATE_LIST:
5591 return -1;
5592 case Template::TEMPLATE_REFD:
5593 case Template::TEMPLATE_LIST:
5594 case Template::NAMED_TEMPLATE_LIST:
5595 // computed later
5596 break;
5597 case Template::SPECIFIC_VALUE:
5598 {
5599 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5600 if(t_val) {
5601 switch(t_val->get_valuetype()) {
5602 case V_SEQOF:
5603 case V_SETOF:
5604 case V_ARRAY:
5605 case V_ROID:
5606 case V_OID:
5607 case V_SEQ:
5608 case V_SET:
5609 break;
5610 case V_REFD: {
5611 ref = t_val->get_reference();
5612 t_ass = ref->get_refd_assignment();
5613 t_subrefs = ref->get_subrefs();
5614 break;
5615 }
5616 default:
5617 u.expr.ti1->error("Operation is not applicable to `%s'",
5618 t_val->create_stringRepr().c_str());
5619 goto error;
5620 }
5621 }
5622 break;
5623 }
5624 default:
5625 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5626 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5627 goto error;
5628 } // switch
5629
5630 if (t_ass) {
5631 switch(t_ass->get_asstype()) {
5632 case Assignment::A_ERROR:
5633 goto error;
5634 case Assignment::A_CONST:
5635 t_val = t_ass->get_Value();
5636 break;
5637 case Assignment::A_EXT_CONST:
5638 case Assignment::A_MODULEPAR:
5639 case Assignment::A_MODULEPAR_TEMP:
5640 if(exp_val==Type::EXPECTED_CONSTANT) {
5641 u.expr.ti1->error("Reference to an (evaluable) constant value was "
5642 "expected instead of %s", t_ass->get_description().c_str());
5643 goto error;
5644 }
5645 break;
5646 case Assignment::A_VAR:
5647 case Assignment::A_PAR_VAL_IN:
5648 case Assignment::A_PAR_VAL_OUT:
5649 case Assignment::A_PAR_VAL_INOUT:
5650 switch(exp_val) {
5651 case Type::EXPECTED_CONSTANT:
5652 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5653 t_ass->get_description().c_str());
5654 goto error;
5655 break;
5656 case Type::EXPECTED_STATIC_VALUE:
5657 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5658 t_ass->get_description().c_str());
5659 goto error;
5660 break;
5661 default:
5662 break;
5663 }
5664 break;
5665 case Assignment::A_TEMPLATE:
5666 t_templ = t_ass->get_Template();
5667 // no break
5668 case Assignment::A_VAR_TEMPLATE:
5669 case Assignment::A_PAR_TEMPL_IN:
5670 case Assignment::A_PAR_TEMPL_OUT:
5671 case Assignment::A_PAR_TEMPL_INOUT:
5672 if (exp_val!=Type::EXPECTED_TEMPLATE)
5673 u.expr.ti1->error("Reference to a value was expected instead of %s",
5674 t_ass->get_description().c_str());
5675 goto error;
5676 break;
5677 case Assignment::A_FUNCTION_RVAL:
5678 case Assignment::A_EXT_FUNCTION_RVAL:
5679 switch(exp_val) {
5680 case Type::EXPECTED_CONSTANT:
5681 u.expr.ti1->error("Reference to a constant value was expected instead of "
5682 "the return value of %s", t_ass->get_description().c_str());
5683 goto error;
5684 break;
5685 case Type::EXPECTED_STATIC_VALUE:
5686 u.expr.ti1->error("Reference to a static value was expected instead of "
5687 "the return value of %s", t_ass->get_description().c_str());
5688 goto error;
5689 break;
5690 default:
5691 break;
5692 }
5693 break;
5694 case Assignment::A_FUNCTION_RTEMP:
5695 case Assignment::A_EXT_FUNCTION_RTEMP:
5696 if(exp_val!=Type::EXPECTED_TEMPLATE)
5697 u.expr.ti1->error("Reference to a value was expected instead of a call"
5698 " of %s, which returns a template",
5699 t_ass->get_description().c_str());
5700 goto error;
5701 break;
5702 case Assignment::A_TIMER:
5703 case Assignment::A_PORT:
5704 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5705 // sizeof is applicable to timer and port arrays
5706 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5707 if (!t_dims) {
5708 u.expr.ti1->error("Operation is not applicable to single %s",
5709 t_ass->get_description().c_str());
5710 goto error;
5711 }
5712 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5713 Type::EXPECTED_DYNAMIC_VALUE);
5714 size_t refd_dim;
5715 if (t_subrefs) {
5716 refd_dim = t_subrefs->get_nof_refs();
5717 size_t nof_dims = t_dims->get_nof_dims();
5718 if (refd_dim > nof_dims) goto error;
5719 else if (refd_dim == nof_dims) {
5720 u.expr.ti1->error("Operation is not applicable to a %s",
5721 t_ass->get_assname());
5722 goto error;
5723 }
5724 } else refd_dim = 0;
5725 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5726 }
5727 // no break
5728 default:
5729 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5730 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5731 t_ass->get_description().c_str());
5732 goto error;
5733 } // end switch
5734
5735 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5736 if (!t_type) goto error;
5737 t_type = t_type->get_type_refd_last();
5738
5739 switch(t_type->get_typetype()) {
5740 case Type::T_ERROR:
5741 goto error;
5742 case Type::T_SEQOF:
5743 case Type::T_SETOF:
5744 // no break
5745 case Type::T_SEQ_T:
5746 case Type::T_SET_T:
5747 case Type::T_SEQ_A:
5748 case Type::T_SET_A:
5749 case Type::T_ARRAY:
5750 // ok
5751 break;
5752 case Type::T_OID:
5753 case Type::T_ROID:
5754 break;
5755 default:
5756 u.expr.ti1->error("Reference to value or template of type record, record of,"
5757 " set, set of, objid or array was expected");
5758 goto error;
5759 } // switch
5760 }
5761
5762 // check for index overflows in subrefs if possible
5763 if (t_val) {
5764 switch (t_val->get_valuetype()) {
5765 case V_SEQOF:
5766 case V_SETOF:
5767 case V_ARRAY:
5768 if (t_val->is_indexed()) {
5769 return -1;
5770 }
5771 break;
5772 default:
5773 break;
5774 }
5775 /* The reference points to a constant. */
5776 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5777 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5778 if (!t_val) goto error;
5779 t_val=t_val->get_value_refd_last(refch);
5780 } else { t_val = 0; }
5781 } else if (t_templ) {
5782 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5783 time. Don't try to evaluate it at compile time. */
5784 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5785 return -1;
5786 /* The reference points to a static template. */
5787 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5788 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5789 if (!t_templ) goto error;
5790 t_templ = t_templ->get_template_refd_last(refch);
5791 } else { t_templ = 0; }
5792 }
5793
5794 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5795 if(t_templ) {
5796 switch(t_templ->get_templatetype()) {
5797 case Template::TEMPLATE_ERROR:
5798 goto error;
5799 case Template::TEMPLATE_REFD:
5800 // not foldable
5801 t_templ=0;
5802 break;
5803 case Template::SPECIFIC_VALUE:
5804 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5805 t_templ=0;
5806 break;
5807 case Template::TEMPLATE_LIST:
5808 case Template::NAMED_TEMPLATE_LIST:
5809 break;
5810 default:
5811 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5812 t_templ->get_templatetype_str(),
5813 t_templ->get_fullname().c_str());
5814 goto error;
5815 } // switch
5816 }
5817 if(t_val) {
5818 switch(t_val->get_valuetype()) {
5819 case V_SEQOF:
5820 case V_SETOF:
5821 case V_ARRAY:
5822 case V_SEQ:
5823 case V_SET:
5824 case V_OID:
5825 case V_ROID:
5826 // ok
5827 break;
5828 default:
5829 // error is already reported
5830 t_val=0;
5831 break;
5832 } // switch
5833 }
5834 }
5835
5836 /* evaluation */
5837
5838 if(t_type->get_typetype()==Type::T_ARRAY) {
5839 result = t_type->get_dimension()->get_size();
5840 }
5841 else if(t_templ) { // sizeof()
5842 switch(t_templ->get_templatetype()) {
5843 case Template::TEMPLATE_LIST:
5844 if(t_templ->temps_contains_anyornone_symbol()) {
5845 if(t_templ->is_length_restricted()) {
5846 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5847 if (lr->get_is_range()) {
5848 Value *v_upper = lr->get_upper_value();
5849 if (v_upper) {
5850 if (v_upper->valuetype == V_INT) {
5851 Int nof_comps =
5852 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5853 if (v_upper->u.val_Int->get_val() == nof_comps)
5854 result = nof_comps;
5855 else {
5856 u.expr.ti1->error("`sizeof' operation is not applicable for "
5857 "templates without exact size");
5858 goto error;
5859 }
5860 }
5861 } else {
5862 u.expr.ti1->error("`sizeof' operation is not applicable for "
5863 "templates containing `*' without upper boundary in the "
5864 "length restriction");
5865 goto error;
5866 }
5867 } else {
5868 Value *v_single = lr->get_single_value();
5869 if (v_single->valuetype == V_INT)
5870 result = v_single->u.val_Int->get_val();
5871 }
5872 }
5873 else { // not length restricted
5874 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
5875 " containing `*' without length restriction");
5876 goto error;
5877 }
5878 }
5879 else result=t_templ->get_nof_listitems();
5880 break;
5881 case Template::NAMED_TEMPLATE_LIST:
5882 result=0;
5883 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
5884 if(t_templ->get_namedtemp_byIndex(i)->get_template()
5885 ->get_templatetype()!=Template::OMIT_VALUE) result++;
5886 return result;
5887 default:
5888 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5889 } // switch
5890 }
5891 else if(t_val) {
5892 switch(t_val->get_valuetype()) {
5893 case V_SEQOF:
5894 case V_SETOF:
5895 case V_ARRAY:
5896
5897 case V_OID:
5898 case V_ROID:
5899 result=t_val->get_nof_comps();
5900 break;
5901 case V_SEQ:
5902 case V_SET:
5903 result=0;
5904 for(size_t i=0; i<t_val->get_nof_comps(); i++)
5905 if(t_val->get_se_comp_byIndex(i)->get_value()
5906 ->get_valuetype()!=V_OMIT) result++;
5907 break;
5908
5909 default:
5910 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5911 } // switch
5912 }
5913
5914 return result;
5915 error:
5916 set_valuetype(V_ERROR);
5917 return -1;
5918 }
5919
5920 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
5921 {
5922 Type *governor = ti->get_expr_governor(exp_val);
5923 if (!governor) {
5924 ti->get_Template()->set_lowerid_to_ref();
5925 governor = ti->get_expr_governor(exp_val);
5926 }
5927 if (!governor) {
5928 string str;
5929 ti->append_stringRepr( str);
5930 ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
5931 "If type is known, use valuof(<type>: %s) as argument.",
5932 str.c_str(), get_opname(), str.c_str());
5933 set_valuetype(V_ERROR);
5934 }
5935 return governor;
5936 }
5937
5938 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
5939 {
5940 start:
5941 Type *governor = u.expr.v1->get_expr_governor(exp_val);
5942 if (!governor) governor = u.expr.t2->get_expr_governor(
5943 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
5944 Type::EXPECTED_TEMPLATE : exp_val);
5945 if (!governor) {
5946 Template *t_temp = u.expr.t2->get_Template();
5947 if (t_temp->is_undef_lowerid()) {
5948 // We convert the template to reference first even if the value is also
5949 // an undef lowerid. The user can prevent this by explicit type
5950 // specification.
5951 t_temp->set_lowerid_to_ref();
5952 goto start;
5953 } else if (u.expr.v1->is_undef_lowerid()) {
5954 u.expr.v1->set_lowerid_to_ref();
5955 goto start;
5956 }
5957 }
5958 if (!governor) {
5959 error("Cannot determine the type of arguments in `match()' operation");
5960 set_valuetype(V_ERROR);
5961 return;
5962 }
5963 u.expr.v1->set_my_governor(governor);
5964 {
5965 Error_Context cntxt(this, "In the first argument of `match()'"
5966 " operation");
5967 governor->chk_this_value_ref(u.expr.v1);
5968 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
5969 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
5970 }
5971 {
5972 Error_Context cntxt(this, "In the second argument of `match()' "
5973 "operation");
5974 u.expr.t2->chk(governor);
5975 }
5976 }
5977
5978 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
5979 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
5980 {
5981 Ttcn::StatementBlock *my_sb;
5982 switch (exp_val) {
5983 case Type::EXPECTED_CONSTANT:
5984 error("An evaluable constant value was expected instead of operation "
5985 "`%s'", get_opname());
5986 goto error;
5987 case Type::EXPECTED_STATIC_VALUE:
5988 error("A static value was expected instead of operation `%s'",
5989 get_opname());
5990 goto error;
5991 default:
5992 break;
5993 } // switch
5994 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
5995 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
5996 if (!my_sb) {
5997 error("Operation `%s' is allowed only within statements",
5998 get_opname());
5999 goto error;
6000 }
6001 if (!allow_controlpart && !my_sb->get_my_def()) {
6002 error("Operation `%s' is not allowed in the control part",
6003 get_opname());
6004 goto error;
6005 }
6006 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6007 error("Operation `%s' cannot be used in a definition that has "
6008 "`runs on' clause", get_opname());
6009 goto error;
6010 }
6011 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6012 error("Operation `%s' can be used only in a definition that has "
6013 "`runs on' clause", get_opname());
6014 goto error;
6015 }
6016 return;
6017 error:
6018 set_valuetype(V_ERROR);
6019 }
6020
6021 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6022 {
6023 if(valuetype==V_ERROR) return;
6024 if(u.expr.state==EXPR_CHECKING_ERR) return;
6025 if(v->is_unfoldable()) return;
6026 if(v->get_expr_returntype()!=Type::T_REAL) return;
6027 ttcn3float r = v->get_val_Real();
6028 if (isSpecialFloatValue(r)) {
6029 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6030 opnum, opname, Real2string(r).c_str());
6031 set_valuetype(V_ERROR);
6032 }
6033 }
6034
6035 void Value::chk_expr_operands(ReferenceChain *refch,
6036 Type::expected_value_t exp_val)
6037 {
6038 const char *first="First", *second="Second", *third="Third",
6039 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6040 Value *v1, *v2, *v3;
6041 Type::typetype_t tt1, tt2, tt3;
6042 Type t_chk(Type::T_ERROR);
6043
6044 const char *opname=get_opname();
6045
6046 // first classify the unchecked ischosen() operation
6047 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6048
6049 switch (u.expr.v_optype) {
6050 case OPTYPE_COMP_NULL:
6051 case OPTYPE_TESTCASENAME:
6052 case OPTYPE_PROF_RUNNING:
6053 break;
6054 case OPTYPE_COMP_MTC:
6055 case OPTYPE_COMP_SYSTEM:
6056 chk_expr_comptype_compat();
6057 break;
6058 case OPTYPE_RND: // -
6059 case OPTYPE_TMR_RUNNING_ANY:
6060 chk_expr_dynamic_part(exp_val, true);
6061 break;
6062 case OPTYPE_COMP_RUNNING_ANY:
6063 case OPTYPE_COMP_RUNNING_ALL:
6064 case OPTYPE_COMP_ALIVE_ANY:
6065 case OPTYPE_COMP_ALIVE_ALL:
6066 case OPTYPE_GETVERDICT:
6067 chk_expr_dynamic_part(exp_val, false);
6068 break;
6069 case OPTYPE_COMP_SELF:
6070 chk_expr_comptype_compat();
6071 chk_expr_dynamic_part(exp_val, false, true, false);
6072 break;
6073 case OPTYPE_UNARYPLUS: // v1
6074 case OPTYPE_UNARYMINUS:
6075 v1=u.expr.v1;
6076 {
6077 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6078 v1->set_lowerid_to_ref();
6079 tt1=v1->get_expr_returntype(exp_val);
6080 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6081 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6082 }
6083 break;
6084 case OPTYPE_NOT:
6085 v1=u.expr.v1;
6086 {
6087 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6088 v1->set_lowerid_to_ref();
6089 tt1=v1->get_expr_returntype(exp_val);
6090 chk_expr_operandtype_bool(tt1, the, opname, v1);
6091 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6092 }
6093 break;
6094 case OPTYPE_NOT4B:
6095 v1=u.expr.v1;
6096 {
6097 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6098 v1->set_lowerid_to_ref();
6099 tt1=v1->get_expr_returntype(exp_val);
6100 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6101 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6102 }
6103 break;
6104 case OPTYPE_BIT2HEX:
6105 case OPTYPE_BIT2OCT:
6106 case OPTYPE_BIT2STR:
6107 v1=u.expr.v1;
6108 {
6109 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6110 v1->set_lowerid_to_ref();
6111 tt1=v1->get_expr_returntype(exp_val);
6112 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6113 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6114 }
6115 break;
6116 case OPTYPE_BIT2INT:
6117 v1=u.expr.v1;
6118 {
6119 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6120 v1->set_lowerid_to_ref();
6121 tt1=v1->get_expr_returntype(exp_val);
6122 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6123 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6124 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6125 }
6126 break;
6127 case OPTYPE_CHAR2INT:
6128 v1=u.expr.v1;
6129 {
6130 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6131 v1->set_lowerid_to_ref();
6132 tt1=v1->get_expr_returntype(exp_val);
6133 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6134 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6135 chk_expr_val_len1(v1, the, opname);
6136 }
6137 break;
6138 case OPTYPE_CHAR2OCT:
6139 v1=u.expr.v1;
6140 {
6141 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6142 v1->set_lowerid_to_ref();
6143 tt1=v1->get_expr_returntype(exp_val);
6144 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6145 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6146 }
6147 break;
6148 case OPTYPE_STR2INT:
6149 v1=u.expr.v1;
6150 {
6151 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6152 v1->set_lowerid_to_ref();
6153 tt1=v1->get_expr_returntype(exp_val);
6154 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6155 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6156 chk_expr_val_str_int(v1, the, opname);
6157 }
6158 break;
6159 case OPTYPE_STR2FLOAT:
6160 v1=u.expr.v1;
6161 {
6162 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6163 v1->set_lowerid_to_ref();
6164 tt1=v1->get_expr_returntype(exp_val);
6165 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6166 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6167 chk_expr_val_str_float(v1, the, opname);
6168 }
6169 break;
6170 case OPTYPE_STR2BIT:
6171 v1=u.expr.v1;
6172 {
6173 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6174 v1->set_lowerid_to_ref();
6175 tt1=v1->get_expr_returntype(exp_val);
6176 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6177 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6178 chk_expr_val_str_bindigits(v1, the, opname);
6179 }
6180 break;
6181 case OPTYPE_STR2HEX:
6182 v1=u.expr.v1;
6183 {
6184 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6185 v1->set_lowerid_to_ref();
6186 tt1=v1->get_expr_returntype(exp_val);
6187 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6188 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6189 chk_expr_val_str_hexdigits(v1, the, opname);
6190 }
6191 break;
6192 case OPTYPE_STR2OCT:
6193 v1=u.expr.v1;
6194 {
6195 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6196 v1->set_lowerid_to_ref();
6197 tt1=v1->get_expr_returntype(exp_val);
6198 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6199 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6200 chk_expr_val_str_len_even(v1, the, opname);
6201 chk_expr_val_str_hexdigits(v1, the, opname);
6202 }
6203 break;
6204 case OPTYPE_ENUM2INT:
6205 v1=u.expr.v1;
6206 {
6207 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6208 chk_expr_operandtype_enum(opname, v1, exp_val);
6209 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6210 }
6211 break;
6212 case OPTYPE_ENCODE:
6213 chk_expr_operand_encode(refch, exp_val);
6214 break;
6215 case OPTYPE_FLOAT2INT:
6216 case OPTYPE_FLOAT2STR:
6217 v1=u.expr.v1;
6218 {
6219 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6220 v1->set_lowerid_to_ref();
6221 tt1=v1->get_expr_returntype(exp_val);
6222 chk_expr_operandtype_float(tt1, the, opname, v1);
6223 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6224 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6225 chk_expr_operand_valid_float(v1, the, opname);
6226 }
6227 break;
6228 case OPTYPE_RNDWITHVAL:
6229 v1=u.expr.v1;
6230 {
6231 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6232 v1->set_lowerid_to_ref();
6233 tt1=v1->get_expr_returntype(exp_val);
6234 chk_expr_operandtype_float(tt1, the, opname, v1);
6235 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6236 chk_expr_operand_valid_float(v1, the, opname);
6237 }
6238 chk_expr_dynamic_part(exp_val, true);
6239 break;
6240 case OPTYPE_HEX2BIT:
6241 case OPTYPE_HEX2OCT:
6242 case OPTYPE_HEX2STR:
6243 v1=u.expr.v1;
6244 {
6245 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6246 v1->set_lowerid_to_ref();
6247 tt1=v1->get_expr_returntype(exp_val);
6248 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6249 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6250 }
6251 break;
6252 case OPTYPE_HEX2INT:
6253 v1=u.expr.v1;
6254 {
6255 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6256 v1->set_lowerid_to_ref();
6257 tt1=v1->get_expr_returntype(exp_val);
6258 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6259 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6260 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6261 }
6262 break;
6263 case OPTYPE_INT2CHAR:
6264 v1=u.expr.v1;
6265 {
6266 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6267 v1->set_lowerid_to_ref();
6268 tt1=v1->get_expr_returntype(exp_val);
6269 chk_expr_operandtype_int(tt1, the, opname, v1);
6270 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6271 chk_expr_val_int_pos7bit(v1, the, opname);
6272 }
6273 break;
6274 case OPTYPE_INT2UNICHAR:
6275 v1=u.expr.v1;
6276 {
6277 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6278 v1->set_lowerid_to_ref();
6279 tt1=v1->get_expr_returntype(exp_val);
6280 chk_expr_operandtype_int(tt1, the, opname, v1);
6281 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6282 chk_expr_val_int_pos31bit(v1, first, opname);
6283 }
6284 break;
6285 case OPTYPE_INT2FLOAT:
6286 case OPTYPE_INT2STR:
6287 v1=u.expr.v1;
6288 {
6289 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6290 v1->set_lowerid_to_ref();
6291 tt1=v1->get_expr_returntype(exp_val);
6292 chk_expr_operandtype_int(tt1, the, opname, v1);
6293 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6294 }
6295 break;
6296 case OPTYPE_OCT2BIT:
6297 case OPTYPE_OCT2HEX:
6298 case OPTYPE_OCT2STR:
6299 v1=u.expr.v1;
6300 {
6301 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6302 v1->set_lowerid_to_ref();
6303 tt1=v1->get_expr_returntype(exp_val);
6304 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6305 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6306 }
6307 break;
6308 case OPTYPE_OCT2INT:
6309 v1=u.expr.v1;
6310 {
6311 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6312 v1->set_lowerid_to_ref();
6313 tt1=v1->get_expr_returntype(exp_val);
6314 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6315 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6316 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6317 // now.
6318 }
6319 break;
6320 case OPTYPE_OCT2CHAR:
6321 v1=u.expr.v1;
6322 {
6323 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6324 v1->set_lowerid_to_ref();
6325 tt1=v1->get_expr_returntype(exp_val);
6326 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6327 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6328 chk_expr_val_str_7bitoctets(v1, the, opname);
6329 }
6330 break;
6331 case OPTYPE_REMOVE_BOM:
6332 v1=u.expr.v1;
6333 {
6334 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6335 v1->set_lowerid_to_ref();
6336 tt1=v1->get_expr_returntype(exp_val);
6337 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6338 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6339 }
6340 break;
6341 case OPTYPE_GET_STRINGENCODING:
6342 v1=u.expr.v1;
6343 {
6344 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6345 v1->set_lowerid_to_ref();
6346 tt1=v1->get_expr_returntype(exp_val);
6347 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6348 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6349 }
6350 break;
6351 case OPTYPE_ENCODE_BASE64:
6352 v1=u.expr.v1;
6353 {
6354 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6355 v1->set_lowerid_to_ref();
6356 tt1=v1->get_expr_returntype(exp_val);
6357 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6358 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6359 }
6360 v2=u.expr.v2 ? u.expr.v2 : 0;
6361 if (v2)
6362 {
6363 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6364 v2->set_lowerid_to_ref();
6365 tt2=v2->get_expr_returntype(exp_val);
6366 chk_expr_operandtype_bool(tt2, second, opname, v2);
6367 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6368 }
6369 break;
6370 case OPTYPE_DECODE_BASE64:
6371 v1=u.expr.v1;
6372 {
6373 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6374 v1->set_lowerid_to_ref();
6375 tt1=v1->get_expr_returntype(exp_val);
6376 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6377 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6378 }
6379 break;
6380 case OPTYPE_UNICHAR2INT:
6381 v1=u.expr.v1;
6382 {
6383 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6384 v1->set_lowerid_to_ref();
6385 tt1=v1->get_expr_returntype(exp_val);
6386 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6387 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6388 chk_expr_val_len1(v1, the, opname);
6389 }
6390 break;
6391 case OPTYPE_UNICHAR2CHAR:
6392 v1=u.expr.v1;
6393 {
6394 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6395 v1->set_lowerid_to_ref();
6396 tt1=v1->get_expr_returntype(exp_val);
6397 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6398 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6399 chk_expr_val_ustr_7bitchars(v1, the, opname);
6400 }
6401 break;
6402 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6403 v1=u.expr.v1;
6404 {
6405 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6406 v1->set_lowerid_to_ref();
6407 tt1=v1->get_expr_returntype(exp_val);
6408 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6409 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6410 }
6411 v2=u.expr.v2 ? u.expr.v2 : 0;
6412 if (v2)
6413 {
6414 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6415 v2->set_lowerid_to_ref();
6416 tt2=v2->get_expr_returntype(exp_val);
6417 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6418 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6419 }
6420 break;
6421 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6422 v1=u.expr.v1;
6423 {
6424 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6425 v1->set_lowerid_to_ref();
6426 tt1=v1->get_expr_returntype(exp_val);
6427 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6428 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6429 }
6430 v2=u.expr.v2 ? u.expr.v2 : 0;
6431 if (v2)
6432 {
6433 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6434 v2->set_lowerid_to_ref();
6435 tt2=v2->get_expr_returntype(exp_val);
6436 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6437 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6438 }
6439 break;
6440 case OPTYPE_ADD: // v1 v2
6441 case OPTYPE_SUBTRACT:
6442 case OPTYPE_MULTIPLY:
6443 case OPTYPE_DIVIDE:
6444 v1=u.expr.v1;
6445 {
6446 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6447 v1->set_lowerid_to_ref();
6448 tt1=v1->get_expr_returntype(exp_val);
6449 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6450 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6451 chk_expr_operand_valid_float(v1, first, opname);
6452 }
6453 v2=u.expr.v2;
6454 {
6455 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6456 v2->set_lowerid_to_ref();
6457 tt2=v2->get_expr_returntype(exp_val);
6458 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6459 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6460 chk_expr_operand_valid_float(v2, second, opname);
6461 if(u.expr.v_optype==OPTYPE_DIVIDE)
6462 chk_expr_val_int_float_not0(v2, second, opname);
6463 }
6464 chk_expr_operandtypes_same(tt1, tt2, opname);
6465 break;
6466 case OPTYPE_MOD:
6467 case OPTYPE_REM:
6468 v1=u.expr.v1;
6469 {
6470 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6471 v1->set_lowerid_to_ref();
6472 tt1=v1->get_expr_returntype(exp_val);
6473 chk_expr_operandtype_int(tt1, left, opname, v1);
6474 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6475 }
6476 v2=u.expr.v2;
6477 {
6478 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6479 v2->set_lowerid_to_ref();
6480 tt2=v2->get_expr_returntype(exp_val);
6481 chk_expr_operandtype_int(tt2, right, opname, v2);
6482 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6483 chk_expr_val_int_float_not0(v2, right, opname);
6484 }
6485 break;
6486 case OPTYPE_CONCAT: {
6487 v1=u.expr.v1;
6488 v2=u.expr.v2;
6489 v1->set_lowerid_to_ref();
6490 v2->set_lowerid_to_ref();
6491 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6492 {
6493 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6494 tt1=v1->get_expr_returntype(exp_val);
6495 chk_expr_operandtype_str(tt1, left, opname, v1);
6496 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6497 }
6498 {
6499 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6500 tt2=v2->get_expr_returntype(exp_val);
6501 chk_expr_operandtype_str(tt2, right, opname, v2);
6502 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6503 }
6504 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6505 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6506 chk_expr_operandtypes_same(tt1, tt2, opname);
6507 } else { // other list types
6508 Type* v1_gov = v1->get_expr_governor(exp_val);
6509 Type* v2_gov = v2->get_expr_governor(exp_val);
6510 if (!v1_gov) {
6511 error("Cannot determine the type of the left operand of `%s' operation", opname);
6512 set_valuetype(V_ERROR);
6513 return;
6514 } else {
6515 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6516 v1_gov->chk_this_value_ref(v1);
6517 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6518 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6519 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6520 }
6521 if (!v2_gov) {
6522 if (!v1_gov) {
6523 error("Cannot determine the type of the right operand of `%s' operation", opname);
6524 set_valuetype(V_ERROR);
6525 return;
6526 }
6527 // for recof/setof literals set the type from v1
6528 v2_gov = v1_gov;
6529 v2->set_my_governor(v1_gov);
6530 }
6531 {
6532 Error_Context cntxt(this, "In the right operand of operation `%s'",
6533 opname);
6534 v2_gov->chk_this_value_ref(v2);
6535 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6536 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6537 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6538 if (valuetype == V_ERROR) return;
6539 // 7.1.2 says that we shouldn't allow type compatibility.
6540 if (!v1_gov->is_compatible(v2_gov, NULL)
6541 && !v2_gov->is_compatible(v1_gov, NULL)) {
6542 error("The operands of operation `%s' should be of compatible "
6543 "types", get_opname());
6544 }
6545 }
6546 }
6547 break; }
6548 case OPTYPE_EQ:
6549 case OPTYPE_NE:
6550 v1 = u.expr.v1;
6551 v2 = u.expr.v2;
6552 chk_expr_operandtypes_compat(exp_val, v1, v2);
6553 {
6554 Error_Context cntxt(this, "In the left operand of operation `%s'",
6555 opname);
6556 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6557 }
6558 {
6559 Error_Context cntxt(this, "In the right operand of operation `%s'",
6560 opname);
6561 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6562 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6563 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6564 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6565 * "a == not b" is not allowed. (HL69107)
6566 * The various *Expressions implement operator precedence in the std.
6567 * Titan's parser has only one Expression and relies on Bison
6568 * for operator precedence. The check below brings Titan in line
6569 * with the standard by explicitly making "a == not b" an error */
6570 if (v2->get_valuetype() == V_EXPR
6571 && v2->u.expr.v_optype == OPTYPE_NOT) {
6572 error("The operation `%s' is not allowed to be "
6573 "the second operand of operation `%s'", v2->get_opname(), opname);
6574 set_valuetype(V_ERROR);
6575 }
6576 }
6577 break;
6578 case OPTYPE_LT:
6579 case OPTYPE_GT:
6580 case OPTYPE_GE:
6581 case OPTYPE_LE:
6582 v1=u.expr.v1;
6583 v2=u.expr.v2;
6584 chk_expr_operandtypes_compat(exp_val, v1, v2);
6585 {
6586 Error_Context cntxt(this, "In the left operand of operation `%s'",
6587 opname);
6588 tt1=v1->get_expr_returntype(exp_val);
6589 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6590 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6591 }
6592 {
6593 Error_Context cntxt(this, "In the right operand of operation `%s'",
6594 opname);
6595 tt2=v2->get_expr_returntype(exp_val);
6596 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6597 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6598 }
6599 break;
6600 case OPTYPE_AND:
6601 case OPTYPE_OR:
6602 case OPTYPE_XOR:
6603 v1=u.expr.v1;
6604 {
6605 Error_Context cntxt(this, "In the left operand of operation `%s'",
6606 opname);
6607 v1->set_lowerid_to_ref();
6608 tt1=v1->get_expr_returntype(exp_val);
6609 chk_expr_operandtype_bool(tt1, left, opname, v1);
6610 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6611 }
6612 v2=u.expr.v2;
6613 {
6614 Error_Context cntxt(this, "In the right operand of operation `%s'",
6615 opname);
6616 v2->set_lowerid_to_ref();
6617 tt2=v2->get_expr_returntype(exp_val);
6618 chk_expr_operandtype_bool(tt2, right, opname, v2);
6619 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6620 }
6621 break;
6622 case OPTYPE_AND4B:
6623 case OPTYPE_OR4B:
6624 case OPTYPE_XOR4B:
6625 v1=u.expr.v1;
6626 {
6627 Error_Context cntxt(this, "In the left operand of operation `%s'",
6628 opname);
6629 v1->set_lowerid_to_ref();
6630 tt1=v1->get_expr_returntype(exp_val);
6631 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6632 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6633 }
6634 v2=u.expr.v2;
6635 {
6636 Error_Context cntxt(this, "In the right operand of operation `%s'",
6637 opname);
6638 v2->set_lowerid_to_ref();
6639 tt2=v2->get_expr_returntype(exp_val);
6640 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6641 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6642 }
6643 chk_expr_operandtypes_same(tt1, tt2, opname);
6644 chk_expr_operands_str_samelen();
6645 break;
6646 case OPTYPE_SHL:
6647 case OPTYPE_SHR:
6648 v1=u.expr.v1;
6649 {
6650 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6651 v1->set_lowerid_to_ref();
6652 tt1=v1->get_expr_returntype(exp_val);
6653 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6654 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6655 }
6656 v2=u.expr.v2;
6657 {
6658 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6659 v2->set_lowerid_to_ref();
6660 tt2=v2->get_expr_returntype(exp_val);
6661 chk_expr_operandtype_int(tt2, right, opname, v2);
6662 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6663 chk_expr_val_large_int(v2, right, opname);
6664 }
6665 break;
6666 case OPTYPE_ROTL:
6667 case OPTYPE_ROTR:
6668 v1=u.expr.v1;
6669 v1->set_lowerid_to_ref();
6670 if (v1->is_string_type(exp_val)) {
6671 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6672 tt1=v1->get_expr_returntype(exp_val);
6673 chk_expr_operandtype_str(tt1, left, opname, v1);
6674 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6675 } else { // other list types
6676 Type* v1_gov = v1->get_expr_governor(exp_val);
6677 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6678 error("Cannot determine the type of the left operand of `%s' operation", opname);
6679 } else {
6680 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6681 v1_gov->chk_this_value_ref(v1);
6682 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6683 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6684 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6685 }
6686 }
6687 v2=u.expr.v2;
6688 {
6689 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6690 v2->set_lowerid_to_ref();
6691 tt2=v2->get_expr_returntype(exp_val);
6692 chk_expr_operandtype_int(tt2, right, opname, v2);
6693 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6694 chk_expr_val_large_int(v2, right, opname);
6695 }
6696 break;
6697 case OPTYPE_INT2BIT:
6698 case OPTYPE_INT2HEX:
6699 case OPTYPE_INT2OCT:
6700 v1=u.expr.v1;
6701 {
6702 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6703 v1->set_lowerid_to_ref();
6704 tt1=v1->get_expr_returntype(exp_val);
6705 chk_expr_operandtype_int(tt1, first, opname, v1);
6706 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6707 chk_expr_val_int_pos0(v1, first, opname);
6708 }
6709 v2=u.expr.v2;
6710 {
6711 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6712 v2->set_lowerid_to_ref();
6713 tt2=v2->get_expr_returntype(exp_val);
6714 chk_expr_operandtype_int(tt2, second, opname, v2);
6715 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6716 chk_expr_val_int_pos0(v2, second, opname);
6717 }
6718 chk_expr_operands_int2binstr();
6719 break;
6720 case OPTYPE_DECODE:
6721 chk_expr_operands_decode();
6722 break;
6723 case OPTYPE_SUBSTR:
6724 {
6725 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6726 Type::expected_value_t ti_exp_val = exp_val;
6727 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6728 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6729 if (!governor) return;
6730 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6731 if (valuetype!=V_ERROR)
6732 u.expr.ti1->get_Template()->chk_specific_value(false);
6733 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6734 }
6735 v2=u.expr.v2;
6736 {
6737 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6738 v2->set_lowerid_to_ref();
6739 tt2=v2->get_expr_returntype(exp_val);
6740 chk_expr_operandtype_int(tt2, second, opname, v2);
6741 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6742 chk_expr_val_int_pos0(v2, second, opname);
6743 }
6744 v3=u.expr.v3;
6745 {
6746 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6747 v3->set_lowerid_to_ref();
6748 tt3=v3->get_expr_returntype(exp_val);
6749 chk_expr_operandtype_int(tt3, third, opname, v3);
6750 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6751 chk_expr_val_int_pos0(v3, third, opname);
6752 }
6753 chk_expr_operands_substr();
6754 break;
6755 case OPTYPE_REGEXP: {
6756 Type::expected_value_t ti_exp_val = exp_val;
6757 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6758 {
6759 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6760 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6761 if (!governor) return;
6762 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6763 if (valuetype!=V_ERROR) {
6764 u.expr.ti1->get_Template()->chk_specific_value(false);
6765 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6766 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6767 }
6768 }
6769 {
6770 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6771 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6772 if (!governor) return;
6773 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6774 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6775 get_typetype_ttcn3(), second, opname, u.expr.t2);
6776 }
6777 v3=u.expr.v3;
6778 {
6779 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6780 v3->set_lowerid_to_ref();
6781 tt3=v3->get_expr_returntype(exp_val);
6782 chk_expr_operandtype_int(tt3, third, opname, v3);
6783 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6784 chk_expr_val_int_pos0(v3, third, opname);
6785 }
6786 chk_expr_operands_regexp();
6787 } break;
6788 case OPTYPE_ISCHOSEN:
6789 // do nothing: the operand is erroneous
6790 // the error was already reported in chk_expr_ref_ischosen()
6791 break;
6792 case OPTYPE_ISCHOSEN_V: // v1 i2
6793 case OPTYPE_ISCHOSEN_T: // t1 i2
6794 chk_expr_operands_ischosen(refch, exp_val);
6795 break;
6796 case OPTYPE_VALUEOF: { // ti1
6797 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6798 exp_val = Type::EXPECTED_TEMPLATE;
6799 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6800 Type *governor = my_governor;
6801 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6802 if (!governor) return;
6803 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6804 if (valuetype == V_ERROR) return;
6805 u.expr.ti1->get_Template()->chk_specific_value(false);
6806 break; }
6807 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6808 case OPTYPE_ISBOUND: {
6809 Template *templ = u.expr.ti1->get_Template();
6810 switch (templ->get_templatetype()) {
6811 case Template::TEMPLATE_REFD:
6812 templ->get_reference()->setUsedInIsbound();
6813 break;
6814 case Template::SPECIFIC_VALUE: {
6815 Value *value = templ->get_specific_value();
6816 if (Value::V_REFD == value->get_valuetype()) {
6817 value->get_reference()->setUsedInIsbound();
6818 }
6819 break; }
6820 default:
6821 break;
6822 }
6823 }
6824 // no break
6825 case OPTYPE_ISVALUE: {// ti1
6826 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6827 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6828 exp_val = Type::EXPECTED_TEMPLATE;
6829 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6830 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6831 if (!governor) return;
6832 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6833 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6834 break; }
6835 case OPTYPE_SIZEOF: // ti1
6836 /* this checking is too complex, do the checking during eval... */
6837 break;
6838 case OPTYPE_LENGTHOF: { // ti1
6839 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6840 exp_val = Type::EXPECTED_TEMPLATE;
6841 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6842 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6843 if (!governor) return;
6844 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
6845 if (valuetype == V_ERROR) return;
6846 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6847 break; }
6848 case OPTYPE_MATCH: // v1 t2
6849 chk_expr_operands_match(exp_val);
6850 break;
6851 case OPTYPE_UNDEF_RUNNING: // r1
6852 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
6853 break;
6854 case OPTYPE_COMP_ALIVE:
6855 case OPTYPE_COMP_RUNNING: //v1
6856 chk_expr_operand_compref(u.expr.v1, the, opname);
6857 chk_expr_dynamic_part(exp_val, false);
6858 break;
6859 case OPTYPE_TMR_READ: // r1
6860 case OPTYPE_TMR_RUNNING: // r1
6861 chk_expr_operand_tmrref(u.expr.r1, the, opname);
6862 chk_expr_dynamic_part(exp_val, true);
6863 break;
6864 case OPTYPE_EXECUTE: // r1 [v2] // testcase
6865 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
6866 chk_expr_dynamic_part(exp_val, true, false, false);
6867 break;
6868 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
6869 chk_expr_operand_comptyperef_create();
6870 v2=u.expr.v2;
6871 if(v2) {
6872 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6873 v2->set_lowerid_to_ref();
6874 tt2=v2->get_expr_returntype(exp_val);
6875 chk_expr_operandtype_cstr(tt2, first, opname, v2);
6876 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6877 }
6878 v3=u.expr.v3;
6879 if(v3) {
6880 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6881 v3->set_lowerid_to_ref();
6882 tt3=v3->get_expr_returntype(exp_val);
6883 chk_expr_operandtype_cstr(tt3, second, opname, v3);
6884 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6885 }
6886 chk_expr_dynamic_part(exp_val, false);
6887 break;
6888 case OPTYPE_ACTIVATE: // r1 // altstep
6889 chk_expr_operand_activate(u.expr.r1, the, opname);
6890 chk_expr_dynamic_part(exp_val, true);
6891 break;
6892 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
6893 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6894 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
6895 opname);
6896 delete u.expr.t_list2;
6897 u.expr.ap_list2 = parlist;
6898 chk_expr_dynamic_part(exp_val, true);
6899 break; }
6900 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
6901 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6902 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
6903 u.expr.v3, the, opname);
6904 delete u.expr.t_list2;
6905 u.expr.ap_list2 = parlist;
6906 chk_expr_dynamic_part(exp_val, true);
6907 break; }
6908 case OPTYPE_DECOMP:
6909 error("Built-in function `%s' is not yet supported", opname);
6910 set_valuetype(V_ERROR);
6911 break;
6912 case OPTYPE_REPLACE: {
6913 Type::expected_value_t ti_exp_val = exp_val;
6914 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6915 ti_exp_val = Type::EXPECTED_TEMPLATE;
6916 {
6917 Error_Context cntxt(this, "In the first operand of operation `%s'",
6918 opname);
6919 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6920 if (!governor) return;
6921 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6922 if (valuetype != V_ERROR)
6923 u.expr.ti1->get_Template()->chk_specific_value(false);
6924 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6925 }
6926 v2 = u.expr.v2;
6927 {
6928 Error_Context cntxt(this, "In the second operand of operation `%s'",
6929 opname);
6930 v2->set_lowerid_to_ref();
6931 tt2 = v2->get_expr_returntype(exp_val);
6932 chk_expr_operandtype_int(tt2, second, opname, v2);
6933 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6934 chk_expr_val_int_pos0(v2, second, opname);
6935 }
6936 v3 = u.expr.v3;
6937 {
6938 Error_Context cntxt(this, "In the third operand of operation `%s'",
6939 opname);
6940 v3->set_lowerid_to_ref();
6941 tt3 = v3->get_expr_returntype(exp_val);
6942 chk_expr_operandtype_int(tt3, third, opname, v3);
6943 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6944 chk_expr_val_int_pos0(v3, third, opname);
6945 }
6946 {
6947 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
6948 opname);
6949 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
6950 if (!governor) return;
6951 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
6952 if (valuetype != V_ERROR)
6953 u.expr.ti4->get_Template()->chk_specific_value(false);
6954 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
6955 }
6956 chk_expr_operands_replace();
6957 break; }
6958 case OPTYPE_LOG2STR: {
6959 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6960 u.expr.logargs->chk();
6961 if (!semantic_check_only) u.expr.logargs->join_strings();
6962 break; }
6963 case OPTYPE_TTCN2STRING: {
6964 Error_Context cntxt(this, "In the parameter of ttcn2string()");
6965 Type::expected_value_t ti_exp_val = exp_val;
6966 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6967 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6968 if (!governor) return;
6969 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6970 } break;
6971 default:
6972 FATAL_ERROR("chk_expr_operands()");
6973 } // switch optype
6974 }
6975
6976 // Compile-time evaluation. It may change the valuetype from V_EXPR to
6977 // the result of evaluating the expression. E.g. V_BOOL for
6978 // OPTYPE_ISCHOSEN.
6979 void Value::evaluate_value(ReferenceChain *refch,
6980 Type::expected_value_t exp_val)
6981 {
6982 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
6983 if(u.expr.state!=EXPR_NOT_CHECKED) return;
6984
6985 u.expr.state=EXPR_CHECKING;
6986
6987 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
6988 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
6989 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
6990
6991 if(valuetype==V_ERROR) return;
6992 if(u.expr.state==EXPR_CHECKING_ERR) {
6993 u.expr.state=EXPR_CHECKED;
6994 set_valuetype(V_ERROR);
6995 return;
6996 }
6997
6998 u.expr.state=EXPR_CHECKED;
6999
7000 Value *v1, *v2, *v3, *v4;
7001 switch(u.expr.v_optype) {
7002 case OPTYPE_RND: // -
7003 case OPTYPE_COMP_NULL: // the only foldable in this group
7004 case OPTYPE_COMP_MTC:
7005 case OPTYPE_COMP_SYSTEM:
7006 case OPTYPE_COMP_SELF:
7007 case OPTYPE_COMP_RUNNING_ANY:
7008 case OPTYPE_COMP_RUNNING_ALL:
7009 case OPTYPE_COMP_ALIVE_ANY:
7010 case OPTYPE_COMP_ALIVE_ALL:
7011 case OPTYPE_TMR_RUNNING_ANY:
7012 case OPTYPE_GETVERDICT:
7013 case OPTYPE_PROF_RUNNING:
7014 case OPTYPE_RNDWITHVAL: // v1
7015 case OPTYPE_COMP_RUNNING: // v1
7016 case OPTYPE_COMP_ALIVE:
7017 case OPTYPE_TMR_READ:
7018 case OPTYPE_TMR_RUNNING:
7019 case OPTYPE_ACTIVATE:
7020 case OPTYPE_ACTIVATE_REFD:
7021 case OPTYPE_EXECUTE: // r1 [v2]
7022 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7023 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7024 case OPTYPE_MATCH: // v1 t2
7025 case OPTYPE_ISCHOSEN_T:
7026 case OPTYPE_LOG2STR:
7027 case OPTYPE_ENCODE:
7028 case OPTYPE_DECODE:
7029 case OPTYPE_ISBOUND:
7030 case OPTYPE_ISPRESENT:
7031 case OPTYPE_TTCN2STRING:
7032 case OPTYPE_UNICHAR2OCT:
7033 case OPTYPE_OCT2UNICHAR:
7034 case OPTYPE_ENCODE_BASE64:
7035 case OPTYPE_DECODE_BASE64:
7036 break;
7037 case OPTYPE_TESTCASENAME: { // -
7038 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7039 Ttcn::StatementBlock *my_sb =
7040 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7041 if (!my_sb) break;
7042 Ttcn::Definition *my_def = my_sb->get_my_def();
7043 if (!my_def) { // In control part.
7044 set_val_str(new string(""));
7045 valuetype = V_CSTR;
7046 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7047 set_val_str(new string(my_def->get_id().get_dispname()));
7048 valuetype = V_CSTR;
7049 }
7050 break; }
7051 case OPTYPE_UNARYPLUS: // v1
7052 v1=u.expr.v1;
7053 u.expr.v1=0;
7054 copy_and_destroy(v1);
7055 break;
7056 case OPTYPE_UNARYMINUS:
7057 if (is_unfoldable()) break;
7058 v1 = u.expr.v1->get_value_refd_last();
7059 switch (v1->valuetype) {
7060 case V_INT: {
7061 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7062 if (!i) FATAL_ERROR("Value::evaluate_value()");
7063 clean_up();
7064 valuetype = V_INT;
7065 u.val_Int = i;
7066 break; }
7067 case V_REAL: {
7068 ttcn3float r = v1->get_val_Real();
7069 clean_up();
7070 valuetype = V_REAL;
7071 u.val_Real = -r;
7072 break; }
7073 default:
7074 FATAL_ERROR("Value::evaluate_value()");
7075 }
7076 break;
7077 case OPTYPE_NOT: {
7078 if(is_unfoldable()) break;
7079 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7080 clean_up();
7081 valuetype=V_BOOL;
7082 u.val_bool=!b;
7083 break;}
7084 case OPTYPE_NOT4B: {
7085 if(is_unfoldable()) break;
7086 v1=u.expr.v1->get_value_refd_last();
7087 const string& s = v1->get_val_str();
7088 valuetype_t vt=v1->valuetype;
7089 clean_up();
7090 valuetype=vt;
7091 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7092 break;}
7093 case OPTYPE_BIT2HEX: {
7094 if(is_unfoldable()) break;
7095 v1=u.expr.v1->get_value_refd_last();
7096 const string& s = v1->get_val_str();
7097 clean_up();
7098 valuetype=V_HSTR;
7099 set_val_str(bit2hex(s));
7100 break;}
7101 case OPTYPE_BIT2OCT: {
7102 if(is_unfoldable()) break;
7103 v1=u.expr.v1->get_value_refd_last();
7104 const string& s = v1->get_val_str();
7105 clean_up();
7106 valuetype=V_OSTR;
7107 set_val_str(bit2oct(s));
7108 break;}
7109 case OPTYPE_BIT2STR:
7110 case OPTYPE_HEX2STR:
7111 case OPTYPE_OCT2STR: {
7112 if(is_unfoldable()) break;
7113 v1=u.expr.v1->get_value_refd_last();
7114 const string& s = v1->get_val_str();
7115 clean_up();
7116 valuetype=V_CSTR;
7117 set_val_str(new string(s));
7118 break;}
7119 case OPTYPE_BIT2INT: {
7120 if (is_unfoldable()) break;
7121 v1 = u.expr.v1->get_value_refd_last();
7122 const string& s = v1->get_val_str();
7123 clean_up();
7124 valuetype = V_INT;
7125 u.val_Int = bit2int(s);
7126 break; }
7127 case OPTYPE_CHAR2INT: {
7128 if (is_unfoldable()) break;
7129 v1 = u.expr.v1->get_value_refd_last();
7130 char c = v1->get_val_str()[0];
7131 clean_up();
7132 valuetype = V_INT;
7133 u.val_Int = new int_val_t((Int)c);
7134 break; }
7135 case OPTYPE_CHAR2OCT: {
7136 if(is_unfoldable()) break;
7137 v1=u.expr.v1->get_value_refd_last();
7138 const string& s = v1->get_val_str();
7139 clean_up();
7140 valuetype=V_OSTR;
7141 set_val_str(char2oct(s));
7142 break;}
7143 case OPTYPE_STR2INT: {
7144 if (is_unfoldable()) break;
7145 v1 = u.expr.v1->get_value_refd_last();
7146 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7147 clean_up();
7148 valuetype = V_INT;
7149 u.val_Int = i;
7150 /** \todo hiba eseten lenyeli... */
7151 break; }
7152 case OPTYPE_STR2FLOAT: {
7153 if(is_unfoldable()) break;
7154 v1=u.expr.v1->get_value_refd_last();
7155 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7156 clean_up();
7157 valuetype=V_REAL;
7158 u.val_Real=r;
7159 /** \todo hiba eseten lenyeli... */
7160 break;}
7161 case OPTYPE_STR2BIT: {
7162 if(is_unfoldable()) break;
7163 v1=u.expr.v1->get_value_refd_last();
7164 const string& s = v1->get_val_str();
7165 clean_up();
7166 valuetype=V_BSTR;
7167 set_val_str(new string(s));
7168 break;}
7169 case OPTYPE_STR2HEX:
7170 case OPTYPE_OCT2HEX: {
7171 if(is_unfoldable()) break;
7172 v1=u.expr.v1->get_value_refd_last();
7173 const string& s = v1->get_val_str();
7174 clean_up();
7175 valuetype=V_HSTR;
7176 set_val_str(to_uppercase(s));
7177 break;}
7178 case OPTYPE_STR2OCT: {
7179 if(is_unfoldable()) break;
7180 v1=u.expr.v1->get_value_refd_last();
7181 const string& s = v1->get_val_str();
7182 clean_up();
7183 valuetype=V_OSTR;
7184 set_val_str(to_uppercase(s));
7185 break;}
7186 case OPTYPE_FLOAT2INT: {
7187 if (is_unfoldable()) break;
7188 v1 = u.expr.v1->get_value_refd_last();
7189 ttcn3float r = v1->get_val_Real();
7190 clean_up();
7191 valuetype = V_INT;
7192 u.val_Int = float2int(r, *u.expr.v1);
7193 break;}
7194 case OPTYPE_FLOAT2STR: {
7195 if(is_unfoldable()) break;
7196 v1=u.expr.v1->get_value_refd_last();
7197 ttcn3float r=v1->get_val_Real();
7198 clean_up();
7199 valuetype=V_CSTR;
7200 set_val_str(float2str(r));
7201 break;}
7202 case OPTYPE_HEX2BIT:
7203 case OPTYPE_OCT2BIT: {
7204 if(is_unfoldable()) break;
7205 v1=u.expr.v1->get_value_refd_last();
7206 const string& s = v1->get_val_str();
7207 clean_up();
7208 valuetype=V_BSTR;
7209 set_val_str(hex2bit(s));
7210 break;}
7211 case OPTYPE_HEX2INT:
7212 case OPTYPE_OCT2INT: {
7213 if(is_unfoldable()) break;
7214 v1=u.expr.v1->get_value_refd_last();
7215 const string& s = v1->get_val_str();
7216 clean_up();
7217 valuetype=V_INT;
7218 u.val_Int=hex2int(s);
7219 break;}
7220 case OPTYPE_HEX2OCT: {
7221 if(is_unfoldable()) break;
7222 v1=u.expr.v1->get_value_refd_last();
7223 const string& s = v1->get_val_str();
7224 clean_up();
7225 valuetype=V_OSTR;
7226 set_val_str(hex2oct(s));
7227 break;}
7228 case OPTYPE_INT2CHAR: {
7229 if (is_unfoldable()) break;
7230 v1 = u.expr.v1->get_value_refd_last();
7231 const int_val_t *c_int = v1->get_val_Int();
7232 char c = static_cast<char>(c_int->get_val());
7233 clean_up();
7234 valuetype = V_CSTR;
7235 set_val_str(new string(1, &c));
7236 break; }
7237 case OPTYPE_INT2UNICHAR: {
7238 if (is_unfoldable()) break;
7239 v1 = u.expr.v1->get_value_refd_last();
7240 const int_val_t *i_int = v1->get_val_Int();
7241 Int i = i_int->get_val();
7242 clean_up();
7243 valuetype = V_USTR;
7244 set_val_ustr(int2unichar(i));
7245 u.ustr.convert_str = false;
7246 break; }
7247 case OPTYPE_INT2FLOAT: {
7248 if (is_unfoldable()) break;
7249 v1 = u.expr.v1->get_value_refd_last();
7250 const int_val_t *i_int = v1->get_val_Int();
7251 Real i_int_real = i_int->to_real();
7252 clean_up();
7253 valuetype = V_REAL;
7254 u.val_Real = i_int_real;
7255 break; }
7256 case OPTYPE_INT2STR: {
7257 if (is_unfoldable()) break;
7258 v1 = u.expr.v1->get_value_refd_last();
7259 const int_val_t *i_int = v1->get_val_Int();
7260 string *i_int_str = new string(i_int->t_str());
7261 clean_up();
7262 valuetype = V_CSTR;
7263 set_val_str(i_int_str);
7264 break; }
7265 case OPTYPE_OCT2CHAR: {
7266 if(is_unfoldable()) break;
7267 v1=u.expr.v1->get_value_refd_last();
7268 const string& s = v1->get_val_str();
7269 clean_up();
7270 valuetype=V_CSTR;
7271 set_val_str(oct2char(s));
7272 break;}
7273 case OPTYPE_GET_STRINGENCODING: {
7274 if(is_unfoldable()) break;
7275 v1 = u.expr.v1->get_value_refd_last();
7276 const string& s1 = v1->get_val_str();
7277 clean_up();
7278 valuetype = V_CSTR;
7279 set_val_str(get_stringencoding(s1));
7280 break;}
7281 case OPTYPE_REMOVE_BOM: {
7282 if(is_unfoldable()) break;
7283 v1 = u.expr.v1->get_value_refd_last();
7284 const string& s1 = v1->get_val_str();
7285 clean_up();
7286 valuetype = V_OSTR;
7287 set_val_str(remove_bom(s1));
7288 break;}
7289 case OPTYPE_ENUM2INT: {
7290 if(is_unfoldable()) break;
7291 v1=u.expr.v1->get_value_refd_last();
7292 Type* enum_type = v1->get_my_governor();
7293 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7294 clean_up();
7295 valuetype = V_INT;
7296 u.val_Int = new int_val_t(enum_val);
7297 break;}
7298 case OPTYPE_UNICHAR2INT:
7299 if (is_unfoldable()) {
7300 // replace the operation with char2int() if the operand is a charstring
7301 // value to avoid its unnecessary conversion to universal charstring
7302 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7303 u.expr.v_optype = OPTYPE_CHAR2INT;
7304 } else {
7305 v1=u.expr.v1->get_value_refd_last();
7306 const ustring& s = v1->get_val_ustr();
7307 clean_up();
7308 valuetype=V_INT;
7309 u.val_Int=new int_val_t(unichar2int(s));
7310 }
7311 break;
7312 case OPTYPE_UNICHAR2CHAR:
7313 v1 = u.expr.v1;
7314 if (is_unfoldable()) {
7315 // replace the operation with its operand if it is a charstring
7316 // value to avoid its unnecessary conversion to universal charstring
7317 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7318 u.expr.v1 = 0;
7319 copy_and_destroy(v1);
7320 }
7321 } else {
7322 v1 = v1->get_value_refd_last();
7323 const ustring& s = v1->get_val_ustr();
7324 clean_up();
7325 valuetype = V_CSTR;
7326 set_val_str(new string(s));
7327 }
7328 break;
7329 case OPTYPE_MULTIPLY: { // v1 v2
7330 if (!is_unfoldable()) goto eval_arithmetic;
7331 v1 = u.expr.v1->get_value_refd_last();
7332 v2 = u.expr.v2->get_value_refd_last();
7333 if (v1->is_unfoldable()) v1 = v2;
7334 if (v1->is_unfoldable()) break;
7335 switch(v1->valuetype) {
7336 case V_INT: {
7337 if (*v1->get_val_Int() != 0) break;
7338 clean_up();
7339 valuetype = V_INT;
7340 u.val_Int = new int_val_t((Int)0);
7341 break; }
7342 case V_REAL: {
7343 if (v1->get_val_Real() != 0.0) break;
7344 clean_up();
7345 valuetype = V_REAL;
7346 u.val_Real = 0.0;
7347 break; }
7348 default:
7349 FATAL_ERROR("Value::evaluate_value()");
7350 }
7351 break; }
7352 case OPTYPE_ADD: // v1 v2
7353 case OPTYPE_SUBTRACT:
7354 case OPTYPE_DIVIDE:
7355 case OPTYPE_MOD:
7356 case OPTYPE_REM: {
7357 eval_arithmetic:
7358 if(is_unfoldable()) break;
7359 v1=u.expr.v1->get_value_refd_last();
7360 v2=u.expr.v2->get_value_refd_last();
7361 operationtype_t ot=u.expr.v_optype;
7362 switch (v1->valuetype) {
7363 case V_INT: {
7364 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7365 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7366 clean_up();
7367 valuetype = V_INT;
7368 switch (ot) {
7369 case OPTYPE_ADD:
7370 u.val_Int = new int_val_t(*i1 + *i2);
7371 break;
7372 case OPTYPE_SUBTRACT:
7373 u.val_Int = new int_val_t(*i1 - *i2);
7374 break;
7375 case OPTYPE_MULTIPLY:
7376 u.val_Int = new int_val_t(*i1 * *i2);
7377 break;
7378 case OPTYPE_DIVIDE:
7379 u.val_Int = new int_val_t(*i1 / *i2);
7380 break;
7381 case OPTYPE_MOD:
7382 u.val_Int = new int_val_t(mod(*i1, *i2));
7383 break;
7384 case OPTYPE_REM:
7385 u.val_Int = new int_val_t(rem(*i1, *i2));
7386 break;
7387 default:
7388 FATAL_ERROR("Value::evaluate_value()");
7389 }
7390 delete i1;
7391 delete i2;
7392 break; }
7393 case V_REAL: {
7394 ttcn3float r1=v1->get_val_Real();
7395 ttcn3float r2=v2->get_val_Real();
7396 clean_up();
7397 valuetype=V_REAL;
7398 switch(ot) {
7399 case OPTYPE_ADD:
7400 u.val_Real=r1+r2;
7401 break;
7402 case OPTYPE_SUBTRACT:
7403 u.val_Real=r1-r2;
7404 break;
7405 case OPTYPE_MULTIPLY:
7406 u.val_Real=r1*r2;
7407 break;
7408 case OPTYPE_DIVIDE:
7409 u.val_Real=r1/r2;
7410 break;
7411 default:
7412 FATAL_ERROR("Value::evaluate_value()");
7413 }
7414 break;}
7415 default:
7416 FATAL_ERROR("Value::evaluate_value()");
7417 }
7418 break;}
7419 case OPTYPE_CONCAT: {
7420 if(is_unfoldable()) break;
7421 v1=u.expr.v1->get_value_refd_last();
7422 v2=u.expr.v2->get_value_refd_last();
7423 valuetype_t vt = v1->valuetype;
7424 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7425 const ustring& s1 = v1->get_val_ustr();
7426 const ustring& s2 = v2->get_val_ustr();
7427 clean_up();
7428 valuetype = V_USTR;
7429 set_val_ustr(new ustring(s1 + s2));
7430 u.ustr.convert_str = false;
7431 } else {
7432 const string& s1 = v1->get_val_str();
7433 const string& s2 = v2->get_val_str();
7434 clean_up();
7435 valuetype = vt;
7436 set_val_str(new string(s1 + s2));
7437 }
7438 break;}
7439 case OPTYPE_EQ: {
7440 if(is_unfoldable()) break;
7441 v1=u.expr.v1->get_value_refd_last();
7442 v2=u.expr.v2->get_value_refd_last();
7443 bool b=*v1==*v2;
7444 clean_up();
7445 valuetype=V_BOOL;
7446 u.val_bool=b;
7447 break;}
7448 case OPTYPE_NE: {
7449 if(is_unfoldable()) break;
7450 v1=u.expr.v1->get_value_refd_last();
7451 v2=u.expr.v2->get_value_refd_last();
7452 bool b=*v1==*v2;
7453 clean_up();
7454 valuetype=V_BOOL;
7455 u.val_bool=!b;
7456 break;}
7457 case OPTYPE_LT: {
7458 if(is_unfoldable()) break;
7459 v1=u.expr.v1->get_value_refd_last();
7460 v2=u.expr.v2->get_value_refd_last();
7461 bool b=*v1<*v2;
7462 clean_up();
7463 valuetype=V_BOOL;
7464 u.val_bool=b;
7465 break;}
7466 case OPTYPE_GT: {
7467 if(is_unfoldable()) break;
7468 v1=u.expr.v1->get_value_refd_last();
7469 v2=u.expr.v2->get_value_refd_last();
7470 bool b=*v2<*v1;
7471 clean_up();
7472 valuetype=V_BOOL;
7473 u.val_bool=b;
7474 break;}
7475 case OPTYPE_GE: {
7476 if(is_unfoldable()) break;
7477 v1=u.expr.v1->get_value_refd_last();
7478 v2=u.expr.v2->get_value_refd_last();
7479 bool b=*v1<*v2;
7480 clean_up();
7481 valuetype=V_BOOL;
7482 u.val_bool=!b;
7483 break;}
7484 case OPTYPE_LE: {
7485 if(is_unfoldable()) break;
7486 v1=u.expr.v1->get_value_refd_last();
7487 v2=u.expr.v2->get_value_refd_last();
7488 bool b=*v2<*v1;
7489 clean_up();
7490 valuetype=V_BOOL;
7491 u.val_bool=!b;
7492 break;}
7493 case OPTYPE_AND:
7494 v1 = u.expr.v1->get_value_refd_last();
7495 if (v1->valuetype == V_BOOL) {
7496 if (v1->get_val_bool()) {
7497 // the left operand is a literal "true"
7498 // substitute the expression with the right operand
7499 v2 = u.expr.v2;
7500 u.expr.v2 = 0;
7501 copy_and_destroy(v2);
7502 } else {
7503 // the left operand is a literal "false"
7504 // the result must be false regardless the right operand
7505 // because of the short circuit evaluation rule
7506 clean_up();
7507 valuetype = V_BOOL;
7508 u.val_bool = false;
7509 }
7510 } else {
7511 // we must keep the left operand because of the potential side effects
7512 // the right operand can only be eliminated if it is a literal "true"
7513 v2 = u.expr.v2->get_value_refd_last();
7514 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7515 v1 = u.expr.v1;
7516 u.expr.v1 = 0;
7517 copy_and_destroy(v1);
7518 }
7519 }
7520 break;
7521 case OPTYPE_OR:
7522 v1 = u.expr.v1->get_value_refd_last();
7523 if (v1->valuetype == V_BOOL) {
7524 if (v1->get_val_bool()) {
7525 // the left operand is a literal "true"
7526 // the result must be true regardless the right operand
7527 // because of the short circuit evaluation rule
7528 clean_up();
7529 valuetype = V_BOOL;
7530 u.val_bool = true;
7531 } else {
7532 // the left operand is a literal "false"
7533 // substitute the expression with the right operand
7534 v2 = u.expr.v2;
7535 u.expr.v2 = 0;
7536 copy_and_destroy(v2);
7537 }
7538 } else {
7539 // we must keep the left operand because of the potential side effects
7540 // the right operand can only be eliminated if it is a literal "false"
7541 v2 = u.expr.v2->get_value_refd_last();
7542 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7543 v1 = u.expr.v1;
7544 u.expr.v1 = 0;
7545 copy_and_destroy(v1);
7546 }
7547 }
7548 break;
7549 case OPTYPE_XOR: {
7550 if(is_unfoldable()) break;
7551 v1=u.expr.v1->get_value_refd_last();
7552 v2=u.expr.v2->get_value_refd_last();
7553 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7554 clean_up();
7555 valuetype=V_BOOL;
7556 u.val_bool=b;
7557 break;}
7558 case OPTYPE_AND4B: {
7559 if(is_unfoldable()) break;
7560 v1=u.expr.v1->get_value_refd_last();
7561 v2=u.expr.v2->get_value_refd_last();
7562 valuetype_t vt=v1->valuetype;
7563 const string& s1 = v1->get_val_str();
7564 const string& s2 = v2->get_val_str();
7565 clean_up();
7566 valuetype=vt;
7567 set_val_str(and4b(s1, s2));
7568 break;}
7569 case OPTYPE_OR4B: {
7570 if(is_unfoldable()) break;
7571 v1=u.expr.v1->get_value_refd_last();
7572 v2=u.expr.v2->get_value_refd_last();
7573 valuetype_t vt=v1->valuetype;
7574 const string& s1 = v1->get_val_str();
7575 const string& s2 = v2->get_val_str();
7576 clean_up();
7577 valuetype=vt;
7578 set_val_str(or4b(s1, s2));
7579 break;}
7580 case OPTYPE_XOR4B: {
7581 if(is_unfoldable()) break;
7582 v1=u.expr.v1->get_value_refd_last();
7583 v2=u.expr.v2->get_value_refd_last();
7584 valuetype_t vt=v1->valuetype;
7585 const string& s1 = v1->get_val_str();
7586 const string& s2 = v2->get_val_str();
7587 clean_up();
7588 valuetype=vt;
7589 set_val_str(xor4b(s1, s2));
7590 break;}
7591 case OPTYPE_SHL: {
7592 if(is_unfoldable()) break;
7593 v1=u.expr.v1->get_value_refd_last();
7594 v2=u.expr.v2->get_value_refd_last();
7595 valuetype_t vt=v1->valuetype;
7596 const string& s = v1->get_val_str();
7597 const int_val_t *i_int = v2->get_val_Int();
7598 Int i=i_int->get_val();
7599 if(vt==V_OSTR) i*=2;
7600 clean_up();
7601 valuetype=vt;
7602 set_val_str(shift_left(s, i));
7603 break;}
7604 case OPTYPE_SHR: {
7605 if(is_unfoldable()) break;
7606 v1=u.expr.v1->get_value_refd_last();
7607 v2=u.expr.v2->get_value_refd_last();
7608 valuetype_t vt=v1->valuetype;
7609 const string& s = v1->get_val_str();
7610 const int_val_t *i_int = v2->get_val_Int();
7611 Int i=i_int->get_val();
7612 if(vt==V_OSTR) i*=2;
7613 clean_up();
7614 valuetype=vt;
7615 set_val_str(shift_right(s, i));
7616 break;}
7617 case OPTYPE_ROTL: {
7618 if(is_unfoldable()) break;
7619 v1=u.expr.v1->get_value_refd_last();
7620 v2=u.expr.v2->get_value_refd_last();
7621 valuetype_t vt=v1->valuetype;
7622 const int_val_t *i_int=v2->get_val_Int();
7623 Int i=i_int->get_val();
7624 if(vt==V_USTR) {
7625 const ustring& s = v1->get_val_ustr();
7626 clean_up();
7627 valuetype=vt;
7628 set_val_ustr(rotate_left(s, i));
7629 u.ustr.convert_str = false;
7630 }
7631 else {
7632 if(vt==V_OSTR) i*=2;
7633 const string& s = v1->get_val_str();
7634 clean_up();
7635 valuetype=vt;
7636 set_val_str(rotate_left(s, i));
7637 }
7638 break;}
7639 case OPTYPE_ROTR: {
7640 if(is_unfoldable()) break;
7641 v1=u.expr.v1->get_value_refd_last();
7642 v2=u.expr.v2->get_value_refd_last();
7643 valuetype_t vt=v1->valuetype;
7644 const int_val_t *i_int=v2->get_val_Int();
7645 Int i=i_int->get_val();
7646 if(vt==V_USTR) {
7647 const ustring& s = v1->get_val_ustr();
7648 clean_up();
7649 valuetype=vt;
7650 set_val_ustr(rotate_right(s, i));
7651 u.ustr.convert_str = false;
7652 }
7653 else {
7654 if(vt==V_OSTR) i*=2;
7655 const string& s = v1->get_val_str();
7656 clean_up();
7657 valuetype=vt;
7658 set_val_str(rotate_right(s, i));
7659 }
7660 break;}
7661 case OPTYPE_INT2BIT: {
7662 if (is_unfoldable()) break;
7663 v1 = u.expr.v1->get_value_refd_last();
7664 v2 = u.expr.v2->get_value_refd_last();
7665 const int_val_t *i1_int = v1->get_val_Int();
7666 const int_val_t *i2_int = v2->get_val_Int();
7667 string *val = int2bit(*i1_int, i2_int->get_val());
7668 clean_up();
7669 valuetype = V_BSTR;
7670 set_val_str(val);
7671 break; }
7672 case OPTYPE_INT2HEX: {
7673 if (is_unfoldable()) break;
7674 v1 = u.expr.v1->get_value_refd_last();
7675 v2 = u.expr.v2->get_value_refd_last();
7676 const int_val_t *i1_int = v1->get_val_Int();
7677 const int_val_t *i2_int = v2->get_val_Int();
7678 // Do it before the `clean_up'. i2_int is already checked.
7679 string *val = int2hex(*i1_int, i2_int->get_val());
7680 clean_up();
7681 valuetype = V_HSTR;
7682 set_val_str(val);
7683 break; }
7684 case OPTYPE_INT2OCT: {
7685 if (is_unfoldable()) break;
7686 v1 = u.expr.v1->get_value_refd_last();
7687 v2 = u.expr.v2->get_value_refd_last();
7688 const int_val_t i1_int(*v1->get_val_Int());
7689 // `v2' is a native integer.
7690 Int i2_int = v2->get_val_Int()->get_val() * 2;
7691 clean_up();
7692 valuetype = V_OSTR;
7693 set_val_str(int2hex(i1_int, i2_int));
7694 break; }
7695 case OPTYPE_SUBSTR: {
7696 if(is_unfoldable()) break;
7697 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7698 v2=u.expr.v2->get_value_refd_last();
7699 v3=u.expr.v3->get_value_refd_last();
7700 valuetype_t vt=v1->valuetype;
7701 const int_val_t *i2_int=v2->get_val_Int();
7702 const int_val_t *i3_int=v3->get_val_Int();
7703 Int i2=i2_int->get_val();
7704 Int i3=i3_int->get_val();
7705 if(vt==V_USTR) {
7706 const ustring& s = v1->get_val_ustr();
7707 clean_up();
7708 valuetype=vt;
7709 set_val_ustr(new ustring(s.substr(i2, i3)));
7710 u.ustr.convert_str = false;
7711 }
7712 else {
7713 if(vt==V_OSTR) {
7714 i2*=2;
7715 i3*=2;
7716 }
7717 const string& s = v1->get_val_str();
7718 clean_up();
7719 valuetype=vt;
7720 set_val_str(new string(s.substr(i2, i3)));
7721 }
7722 break;}
7723 case OPTYPE_REPLACE: {
7724 if(is_unfoldable()) break;
7725 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7726 v2=u.expr.v2->get_value_refd_last();
7727 v3=u.expr.v3->get_value_refd_last();
7728 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7729 valuetype_t vt=v1->valuetype;
7730 const int_val_t *i2_int=v2->get_val_Int();
7731 const int_val_t *i3_int=v3->get_val_Int();
7732 Int i2=i2_int->get_val();
7733 Int i3=i3_int->get_val();
7734 switch(vt) {
7735 case V_BSTR: {
7736 string *s1 = new string(v1->get_val_str());
7737 const string& s2 = v4->get_val_str();
7738 clean_up();
7739 valuetype=vt;
7740 s1->replace(i2, i3, s2);
7741 set_val_str(s1);
7742 break;}
7743 case V_HSTR: {
7744 string *s1 = new string(v1->get_val_str());
7745 const string& s2 = v4->get_val_str();
7746 clean_up();
7747 valuetype=vt;
7748 s1->replace(i2, i3, s2);
7749 set_val_str(s1);
7750 break;}
7751 case V_OSTR: {
7752 i2*=2;
7753 i3*=2;
7754 string *s1 = new string(v1->get_val_str());
7755 const string& s2 = v4->get_val_str();
7756 clean_up();
7757 valuetype=vt;
7758 s1->replace(i2, i3, s2);
7759 set_val_str(s1);
7760 break;}
7761 case V_CSTR: {
7762 string *s1 = new string(v1->get_val_str());
7763 const string& s2 = v4->get_val_str();
7764 clean_up();
7765 valuetype=vt;
7766 s1->replace(i2, i3, s2);
7767 set_val_str(s1);
7768 break;}
7769 case V_USTR: {
7770 ustring *s1 = new ustring(v1->get_val_ustr());
7771 const ustring& s2 = v4->get_val_ustr();
7772 clean_up();
7773 valuetype=vt;
7774 s1->replace(i2, i3, s2);
7775 set_val_ustr(s1);
7776 u.ustr.convert_str = false;
7777 break;}
7778 default:
7779 FATAL_ERROR("Value::evaluate_value()");
7780 }
7781 break; }
7782 case OPTYPE_REGEXP: {
7783 if (is_unfoldable()) break;
7784 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7785 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7786 v3=u.expr.v3->get_value_refd_last();
7787 const int_val_t *i3_int = v3->get_val_Int();
7788 Int i3 = i3_int->get_val();
7789 if (v1->valuetype == V_CSTR) {
7790 const string& s1 = v1->get_val_str();
7791 const string& s2 = v2->get_val_str();
7792 string *result = regexp(s1, s2, i3);
7793 clean_up();
7794 valuetype = V_CSTR;
7795 set_val_str(result);
7796 } if (v1->valuetype == V_USTR) {
7797 const ustring& s1 = v1->get_val_ustr();
7798 const ustring& s2 = v2->get_val_ustr();
7799 ustring *result = regexp(s1, s2, i3);
7800 clean_up();
7801 valuetype = V_USTR;
7802 set_val_ustr(result);
7803 u.ustr.convert_str = false;
7804 }
7805 break; }
7806 case OPTYPE_LENGTHOF:{
7807 if(is_unfoldable()) break;
7808 v1=u.expr.ti1->get_Template()->get_specific_value()
7809 ->get_value_refd_last();
7810 size_t i;
7811 if(v1->is_string_type(exp_val)) {
7812 i=v1->get_val_strlen();
7813 } else { // v1 is be seq/set of or array
7814 switch (v1->valuetype) {
7815 case V_SEQOF:
7816 case V_SETOF:
7817 case V_ARRAY: {
7818 if(v1->u.val_vs->is_indexed())
7819 { i = v1->u.val_vs->get_nof_ivs();}
7820 else { i = v1->u.val_vs->get_nof_vs();}
7821 break; }
7822 default:
7823 FATAL_ERROR("Value::evaluate_value()");
7824 }
7825 }
7826 clean_up();
7827 valuetype=V_INT;
7828 u.val_Int=new int_val_t(i);
7829 break;}
7830 case OPTYPE_SIZEOF: {
7831 Int i=chk_eval_expr_sizeof(refch, exp_val);
7832 if(i!=-1) {
7833 clean_up();
7834 valuetype=V_INT;
7835 u.val_Int=new int_val_t(i);
7836 }
7837 break;}
7838 case OPTYPE_ISVALUE: {
7839 if(is_unfoldable()) break;
7840 bool is_singleval = !u.expr.ti1->get_DerivedRef()
7841 && u.expr.ti1->get_Template()->is_Value();
7842 if (is_singleval) {
7843 Value * other_val = u.expr.ti1->get_Template()->get_Value();
7844 is_singleval = other_val->evaluate_isvalue(false);
7845 // is_singleval now contains the compile-time result of isvalue
7846 delete other_val;
7847 }
7848 clean_up();
7849 valuetype = V_BOOL;
7850 u.val_bool = is_singleval;
7851 break;}
7852 case OPTYPE_ISCHOSEN_V: {
7853 if (is_unfoldable()) break;
7854 v1 = u.expr.v1->get_value_refd_last();
7855 bool b = v1->field_is_chosen(*u.expr.i2);
7856 clean_up();
7857 valuetype = V_BOOL;
7858 u.val_bool = b;
7859 break; }
7860 case OPTYPE_VALUEOF: // ti1
7861 if (!u.expr.ti1->get_DerivedRef() &&
7862 u.expr.ti1->get_Template()->is_Value() &&
7863 !u.expr.ti1->get_Type()) {
7864 // FIXME actually if the template instance has a type
7865 // it might still be foldable.
7866 // the argument is a single specific value
7867 v1 = u.expr.ti1->get_Template()->get_Value();
7868 Type *governor = my_governor;
7869 if (governor == NULL) {
7870 governor = u.expr.ti1->get_expr_governor(exp_val);
7871 if (governor != NULL) governor = governor->get_type_refd_last();
7872 }
7873 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
7874 if (governor == NULL)
7875 FATAL_ERROR("Value::evaluate_value()");
7876 clean_up();
7877 valuetype = v1->valuetype;
7878 u = v1->u;
7879 set_my_governor(governor);
7880 if (valuetype == V_REFD && u.ref.refd_last == v1)
7881 u.ref.refd_last = this;
7882 v1->valuetype = V_ERROR;
7883 delete v1;
7884 }
7885 break;
7886 case OPTYPE_UNDEF_RUNNING:
7887 default:
7888 FATAL_ERROR("Value::evaluate_value()");
7889 } // switch optype
7890 }
7891
7892 bool Value::evaluate_isvalue(bool from_sequence)
7893 {
7894 switch (valuetype) {
7895 case V_OMIT:
7896 // Omit is not a value unless a member of a sequence or set
7897 return from_sequence;
7898 case V_NOTUSED:
7899 return false;
7900 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7901 case V_BOOL: /**< boolean */
7902 case V_NAMEDINT: /**< integer / named number */
7903 case V_NAMEDBITS: /**< named bits (identifiers) */
7904 case V_INT: /**< integer */
7905 case V_REAL: /**< real/float */
7906 case V_ENUM: /**< enumerated */
7907 case V_BSTR: /**< bitstring */
7908 case V_HSTR: /**< hexstring */
7909 case V_OSTR: /**< octetstring */
7910 case V_CSTR: /**< charstring */
7911 case V_USTR: /**< universal charstring */
7912 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
7913 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
7914 case V_OID: /**< object identifier */
7915 case V_ROID: /**< relative object identifier */
7916 case V_VERDICT: /**< all verdicts */
7917 return true; // values of built-in types return true
7918
7919 // Code below was adapted from is_unfoldable(), false returned early.
7920 case V_CHOICE:
7921 return u.choice.alt_value->evaluate_isvalue(false);
7922
7923 case V_SEQOF:
7924 case V_SETOF:
7925 case V_ARRAY:
7926 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
7927 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
7928 return false;
7929 }
7930 }
7931 return true;
7932
7933 case V_SEQ:
7934 case V_SET:
7935 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
7936 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
7937 ->evaluate_isvalue(true)) return false;
7938 }
7939 return true;
7940
7941 case V_REFD:
7942 // alas, get_value_refd_last prevents this function from const
7943 return get_value_refd_last()->evaluate_isvalue(false);
7944
7945 case V_EXPR:
7946 switch (u.expr.v_optype) {
7947 // A constant null component reference is a corner case: it is foldable
7948 // but escapes unmodified from evaluate_value.
7949 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7950 // or is transformed into some other valuetype in evaluate_value.
7951 case OPTYPE_COMP_NULL:
7952 return false;
7953 default:
7954 break; // and fall through to the FATAL_ERROR
7955 }
7956 // no break
7957 default:
7958 FATAL_ERROR("Value::evaluate_isvalue()");
7959 break;
7960 }
7961 return true;
7962 }
7963
7964 void Value::evaluate_macro(Type::expected_value_t exp_val)
7965 {
7966 switch (u.macro) {
7967 case MACRO_MODULEID:
7968 if (!my_scope)
7969 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
7970 set_val_str(new string(my_scope->get_scope_mod()
7971 ->get_modid().get_dispname()));
7972 valuetype = V_CSTR;
7973 break;
7974 case MACRO_FILENAME:
7975 case MACRO_BFILENAME: {
7976 const char *t_filename = get_filename();
7977 if (!t_filename)
7978 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7979 set_val_str(new string(t_filename));
7980 valuetype = V_CSTR;
7981 break; }
7982 case MACRO_FILEPATH: {
7983 const char *t_filename = get_filename();
7984 if (!t_filename)
7985 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
7986 char *t_filepath = canonize_input_file(t_filename);
7987 if (!t_filepath)
7988 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
7989 set_val_str(new string(t_filepath));
7990 valuetype = V_CSTR;
7991 Free(t_filepath);
7992 break; }
7993 case MACRO_LINENUMBER: {
7994 int t_lineno = get_first_line();
7995 if (t_lineno <= 0)
7996 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
7997 set_val_str(new string(Int2string(t_lineno)));
7998 valuetype = V_CSTR;
7999 break; }
8000 case MACRO_LINENUMBER_C: {
8001 int t_lineno = get_first_line();
8002 if (t_lineno <= 0)
8003 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8004 u.val_Int = new int_val_t(t_lineno);
8005 valuetype = V_INT;
8006 break; }
8007 case MACRO_DEFINITIONID: {
8008 // cut the second part from the fullname separated by dots
8009 const string& t_fullname = get_fullname();
8010 size_t first_char = t_fullname.find('.') + 1;
8011 if (first_char >= t_fullname.size())
8012 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8013 t_fullname.c_str());
8014 set_val_str(new string(t_fullname.substr(first_char,
8015 t_fullname.find('.', first_char) - first_char)));
8016 valuetype = V_CSTR;
8017 break; }
8018 case MACRO_SCOPE: {
8019 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8020 set_val_str(new string(my_scope->get_scopeMacro_name()));
8021 valuetype = V_CSTR;
8022 break;
8023 }
8024 case MACRO_TESTCASEID: {
8025 if (exp_val == Type::EXPECTED_CONSTANT ||
8026 exp_val == Type::EXPECTED_STATIC_VALUE) {
8027 error("A %s value was expected instead of macro `%%testcaseId', "
8028 "which is evaluated at runtime",
8029 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8030 goto error;
8031 }
8032 if (!my_scope)
8033 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8034 Ttcn::StatementBlock *my_sb =
8035 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8036 if (!my_sb) {
8037 error("Usage of macro %%testcaseId is allowed only within the "
8038 "statement blocks of functions, altsteps and testcases");
8039 goto error;
8040 }
8041 Ttcn::Definition *my_def = my_sb->get_my_def();
8042 if (!my_def) {
8043 error("Macro %%testcaseId cannot be used in the control part. "
8044 "It is allowed only within the statement blocks of functions, "
8045 "altsteps and testcases");
8046 goto error;
8047 }
8048 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8049 // folding is possible only within testcases
8050 set_val_str(new string(my_def->get_id().get_dispname()));
8051 valuetype = V_CSTR;
8052 }
8053 break; }
8054 default:
8055 FATAL_ERROR("Value::evaluate_macro()");
8056 }
8057 return;
8058 error:
8059 set_valuetype(V_ERROR);
8060 }
8061
8062 void Value::add_id(Identifier *p_id)
8063 {
8064 switch(valuetype) {
8065 case V_NAMEDBITS:
8066 if(u.ids->has_key(p_id->get_name())) {
8067 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8068 // The Value does not take ownership for the identifier,
8069 // so it must be deleted (add_is acts as a sink).
8070 delete p_id;
8071 }
8072 else u.ids->add(p_id->get_name(), p_id);
8073 break;
8074 default:
8075 FATAL_ERROR("Value::add_id()");
8076 } // switch
8077 }
8078
8079 Value* Value::get_value_refd_last(ReferenceChain *refch,
8080 Type::expected_value_t exp_val)
8081 {
8082 set_lowerid_to_ref();
8083 switch (valuetype) {
8084 case V_INVOKE:
8085 // there might be a better place for this
8086 chk_invoke(exp_val);
8087 return this;
8088 case V_REFD:
8089 // use the cache if available
8090 if (u.ref.refd_last) return u.ref.refd_last;
8091 else {
8092 Assignment *ass = u.ref.ref->get_refd_assignment();
8093 if (!ass) {
8094 // the referred definition is not found
8095 set_valuetype(V_ERROR);
8096 } else {
8097 switch (ass->get_asstype()) {
8098 case Assignment::A_OBJECT:
8099 case Assignment::A_OS: {
8100 // the referred definition is an ASN.1 object or object set
8101 Setting *setting = u.ref.ref->get_refd_setting();
8102 if (!setting || setting->get_st() == S_ERROR) {
8103 // remain silent, the error has been already reported
8104 set_valuetype(V_ERROR);
8105 break;
8106 } else if (setting->get_st() != S_V) {
8107 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8108 " refer to a value", u.ref.ref->get_dispname().c_str());
8109 set_valuetype(V_ERROR);
8110 break;
8111 }
8112 bool destroy_refch;
8113 if (refch) {
8114 refch->mark_state();
8115 destroy_refch = false;
8116 } else {
8117 refch = new ReferenceChain(this,
8118 "While searching referenced value");
8119 destroy_refch = true;
8120 }
8121 if (refch->add(get_fullname())) {
8122 Value *v_refd = dynamic_cast<Value*>(setting);
8123 Value *v_last = v_refd->get_value_refd_last(refch);
8124 // in case of circular recursion the valuetype is already set
8125 // to V_ERROR, so don't set the cache
8126 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8127 } else {
8128 // a circular recursion was detected
8129 set_valuetype(V_ERROR);
8130 }
8131 if (destroy_refch) delete refch;
8132 else refch->prev_state();
8133 break; }
8134 case Assignment::A_CONST: {
8135 // the referred definition is a constant
8136 bool destroy_refch;
8137 if (refch) {
8138 refch->mark_state();
8139 destroy_refch = false;
8140 } else {
8141 refch = new ReferenceChain(this,
8142 "While searching referenced value");
8143 destroy_refch = true;
8144 }
8145 if (refch->add(get_fullname())) {
8146 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8147 Value *v_refd = ass->get_Value()
8148 ->get_refd_sub_value(subrefs, 0,
8149 u.ref.ref->getUsedInIsbound(), refch);
8150 if (v_refd) {
8151 Value *v_last = v_refd->get_value_refd_last(refch);
8152 // in case of circular recursion the valuetype is already set
8153 // to V_ERROR, so don't set the cache
8154 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8155 } else if (subrefs && subrefs->has_unfoldable_index()) {
8156 u.ref.refd_last = this;
8157 } else if (u.ref.ref->getUsedInIsbound()) {
8158 u.ref.refd_last = this;
8159 } else {
8160 // the sub-reference points to a non-existent field
8161 set_valuetype(V_ERROR);
8162 }
8163 } else {
8164 // a circular recursion was detected
8165 set_valuetype(V_ERROR);
8166 }
8167 if (destroy_refch) delete refch;
8168 else refch->prev_state();
8169 break; }
8170 case Assignment::A_EXT_CONST:
8171 case Assignment::A_MODULEPAR:
8172 case Assignment::A_VAR:
8173 case Assignment::A_FUNCTION_RVAL:
8174 case Assignment::A_EXT_FUNCTION_RVAL:
8175 case Assignment::A_PAR_VAL_IN:
8176 case Assignment::A_PAR_VAL_OUT:
8177 case Assignment::A_PAR_VAL_INOUT:
8178 // the referred definition is not a constant
8179 u.ref.refd_last = this;
8180 break;
8181 case Assignment::A_FUNCTION:
8182 case Assignment::A_EXT_FUNCTION:
8183 u.ref.ref->error("Reference to a value was expected instead of a "
8184 "call of %s, which does not have return type",
8185 ass->get_description().c_str());
8186 set_valuetype(V_ERROR);
8187 break;
8188 case Assignment::A_FUNCTION_RTEMP:
8189 case Assignment::A_EXT_FUNCTION_RTEMP:
8190 u.ref.ref->error("Reference to a value was expected instead of a "
8191 "call of %s, which returns a template",
8192 ass->get_description().c_str());
8193 set_valuetype(V_ERROR);
8194 break;
8195 default:
8196 u.ref.ref->error("Reference to a value was expected instead of %s",
8197 ass->get_description().c_str());
8198 set_valuetype(V_ERROR);
8199 } // switch asstype
8200 }
8201 if (valuetype == V_REFD) return u.ref.refd_last;
8202 else return this;
8203 }
8204 case V_EXPR: {
8205 // try to evaluate the expression
8206 bool destroy_refch;
8207 if(refch) {
8208 refch->mark_state();
8209 destroy_refch=false;
8210 }
8211 else {
8212 refch=new ReferenceChain(this, "While evaluating expression");
8213 destroy_refch=true;
8214 }
8215 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8216 else set_valuetype(V_ERROR);
8217 if(destroy_refch) delete refch;
8218 else refch->prev_state();
8219 return this; }
8220 case V_MACRO:
8221 evaluate_macro(exp_val);
8222 // no break
8223 default:
8224 // return this for all other value types
8225 return this;
8226 } // switch
8227 }
8228
8229 map<Value*, void> Value::UnfoldabilityCheck::running;
8230
8231 /* Note that the logic here needs to be in sync with evaluate_value,
8232 * and possibly others, i.e. if evaluate_value is called for a Value
8233 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8234 bool Value::is_unfoldable(ReferenceChain *refch,
8235 Type::expected_value_t exp_val)
8236 {
8237 if (UnfoldabilityCheck::is_running(this)) {
8238 // This function is already running on this value => infinite recursion
8239 return true;
8240 }
8241
8242 UnfoldabilityCheck checker(this);
8243
8244 if (get_needs_conversion()) return true;
8245 switch (valuetype) {
8246 case V_NAMEDINT:
8247 case V_NAMEDBITS:
8248 case V_OPENTYPE:
8249 case V_UNDEF_LOWERID:
8250 case V_UNDEF_BLOCK:
8251 case V_TTCN3_NULL:
8252 case V_REFER:
8253 // these value types are eliminated during semantic analysis
8254 FATAL_ERROR("Value::is_unfoldable()");
8255 case V_ERROR:
8256 case V_INVOKE:
8257 return true;
8258 case V_CHOICE:
8259 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8260 case V_SEQOF:
8261 case V_SETOF:
8262 case V_ARRAY:
8263 if (!is_indexed()) {
8264 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8265 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8266 return true;
8267 }
8268 } else {
8269 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8270 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8271 return true;
8272 }
8273 }
8274 return false;
8275 case V_SEQ:
8276 case V_SET:
8277 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8278 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8279 ->is_unfoldable(refch, exp_val)) return true;
8280 }
8281 return false;
8282 case V_OID:
8283 case V_ROID:
8284 chk();
8285 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8286 if ((*u.oid_comps)[i]->is_variable()) return true;
8287 }
8288 return false;
8289 case V_REFD: {
8290 Value *v_last=get_value_refd_last(refch, exp_val);
8291 if(v_last==this) return true; // there weren't any references to chase
8292 else return v_last->is_unfoldable(refch, exp_val);
8293 }
8294 case V_EXPR:
8295 // classify the unchecked ischosen() operation, if it was not done so far
8296 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8297 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8298 switch (u.expr.v_optype) {
8299 case OPTYPE_RND: // -
8300 case OPTYPE_COMP_MTC:
8301 case OPTYPE_COMP_SYSTEM:
8302 case OPTYPE_COMP_SELF:
8303 case OPTYPE_COMP_RUNNING_ANY:
8304 case OPTYPE_COMP_RUNNING_ALL:
8305 case OPTYPE_COMP_ALIVE_ANY:
8306 case OPTYPE_COMP_ALIVE_ALL:
8307 case OPTYPE_TMR_RUNNING_ANY:
8308 case OPTYPE_GETVERDICT:
8309 case OPTYPE_TESTCASENAME:
8310 case OPTYPE_PROF_RUNNING:
8311 case OPTYPE_RNDWITHVAL: // v1
8312 case OPTYPE_MATCH: // v1 t2
8313 case OPTYPE_UNDEF_RUNNING: // v1
8314 case OPTYPE_COMP_RUNNING:
8315 case OPTYPE_COMP_ALIVE:
8316 case OPTYPE_TMR_READ:
8317 case OPTYPE_TMR_RUNNING:
8318 case OPTYPE_ACTIVATE:
8319 case OPTYPE_ACTIVATE_REFD:
8320 case OPTYPE_EXECUTE: // r1 [v2]
8321 case OPTYPE_EXECUTE_REFD:
8322 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8323 case OPTYPE_ISCHOSEN:
8324 case OPTYPE_ISCHOSEN_T:
8325 case OPTYPE_SIZEOF: // ti1
8326 case OPTYPE_DECODE:
8327 case OPTYPE_ENCODE:
8328 case OPTYPE_OCT2UNICHAR:
8329 case OPTYPE_UNICHAR2OCT:
8330 case OPTYPE_ENCODE_BASE64:
8331 case OPTYPE_DECODE_BASE64:
8332 return true;
8333 case OPTYPE_COMP_NULL: // -
8334 return false;
8335 case OPTYPE_UNARYPLUS: // v1
8336 case OPTYPE_UNARYMINUS:
8337 case OPTYPE_NOT:
8338 case OPTYPE_NOT4B:
8339 case OPTYPE_BIT2HEX:
8340 case OPTYPE_BIT2INT:
8341 case OPTYPE_BIT2OCT:
8342 case OPTYPE_BIT2STR:
8343 case OPTYPE_CHAR2INT:
8344 case OPTYPE_CHAR2OCT:
8345 case OPTYPE_FLOAT2INT:
8346 case OPTYPE_FLOAT2STR:
8347 case OPTYPE_HEX2BIT:
8348 case OPTYPE_HEX2INT:
8349 case OPTYPE_HEX2OCT:
8350 case OPTYPE_HEX2STR:
8351 case OPTYPE_INT2CHAR:
8352 case OPTYPE_INT2FLOAT:
8353 case OPTYPE_INT2STR:
8354 case OPTYPE_INT2UNICHAR:
8355 case OPTYPE_OCT2BIT:
8356 case OPTYPE_OCT2CHAR:
8357 case OPTYPE_OCT2HEX:
8358 case OPTYPE_OCT2INT:
8359 case OPTYPE_OCT2STR:
8360 case OPTYPE_STR2BIT:
8361 case OPTYPE_STR2FLOAT:
8362 case OPTYPE_STR2HEX:
8363 case OPTYPE_STR2INT:
8364 case OPTYPE_STR2OCT:
8365 case OPTYPE_UNICHAR2INT:
8366 case OPTYPE_UNICHAR2CHAR:
8367 case OPTYPE_ENUM2INT:
8368 case OPTYPE_GET_STRINGENCODING:
8369 case OPTYPE_REMOVE_BOM:
8370 return u.expr.v1->is_unfoldable(refch, exp_val);
8371 case OPTYPE_ISBOUND: /*{
8372 //TODO once we have the time for it make isbound foldable.
8373 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8374 Template* temp = u.expr.ti1->get_Template();
8375 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8376 Value* specificValue = temp->get_specific_value();
8377 if (specificValue->get_valuetype() == Value::V_REFD) {
8378 //FIXME implement
8379 }
8380
8381 return specificValue->is_unfoldable(refch, exp_val);
8382 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8383 //FIXME implement
8384 }
8385 }*/
8386 return true;
8387 case OPTYPE_ISPRESENT:
8388 // TODO: "if you have motivation"
8389 return true;
8390 case OPTYPE_ISVALUE: // ti1
8391 // fallthrough
8392 case OPTYPE_LENGTHOF: // ti1
8393 return u.expr.ti1->get_DerivedRef() != 0
8394 || u.expr.ti1->get_Template()->get_templatetype()
8395 != Template::SPECIFIC_VALUE
8396 || u.expr.ti1->get_Template()->get_specific_value()
8397 ->is_unfoldable(refch, exp_val);
8398 case OPTYPE_ROTL:
8399 case OPTYPE_ROTR:
8400 case OPTYPE_CONCAT:
8401 if (!u.expr.v1->is_string_type(exp_val)) return true;
8402 // no break
8403 case OPTYPE_ADD: // v1 v2
8404 case OPTYPE_SUBTRACT:
8405 case OPTYPE_MULTIPLY:
8406 case OPTYPE_DIVIDE:
8407 case OPTYPE_MOD:
8408 case OPTYPE_REM:
8409 case OPTYPE_EQ:
8410 case OPTYPE_LT:
8411 case OPTYPE_GT:
8412 case OPTYPE_NE:
8413 case OPTYPE_GE:
8414 case OPTYPE_LE:
8415 case OPTYPE_XOR:
8416 case OPTYPE_AND4B:
8417 case OPTYPE_OR4B:
8418 case OPTYPE_XOR4B:
8419 case OPTYPE_SHL:
8420 case OPTYPE_SHR:
8421 case OPTYPE_INT2BIT:
8422 case OPTYPE_INT2HEX:
8423 case OPTYPE_INT2OCT:
8424 return u.expr.v1->is_unfoldable(refch, exp_val)
8425 || u.expr.v2->is_unfoldable(refch, exp_val);
8426 case OPTYPE_AND: // short-circuit evaluation
8427 return u.expr.v1->is_unfoldable(refch, exp_val)
8428 || (u.expr.v1->get_val_bool() &&
8429 u.expr.v2->is_unfoldable(refch, exp_val));
8430 case OPTYPE_OR: // short-circuit evaluation
8431 return u.expr.v1->is_unfoldable(refch, exp_val)
8432 || (!u.expr.v1->get_val_bool() &&
8433 u.expr.v2->is_unfoldable(refch, exp_val));
8434 case OPTYPE_SUBSTR:
8435 if (!u.expr.ti1->get_specific_value()) return true;
8436 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8437 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8438 || u.expr.v2->is_unfoldable(refch, exp_val)
8439 || u.expr.v3->is_unfoldable(refch, exp_val);
8440 case OPTYPE_REGEXP:
8441 if (!u.expr.ti1->get_specific_value() ||
8442 !u.expr.t2->get_specific_value()) return true;
8443 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8444 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8445 || u.expr.v3->is_unfoldable(refch, exp_val);
8446 case OPTYPE_DECOMP:
8447 return u.expr.v1->is_unfoldable(refch, exp_val)
8448 || u.expr.v2->is_unfoldable(refch, exp_val)
8449 || u.expr.v3->is_unfoldable(refch, exp_val);
8450 case OPTYPE_REPLACE: {
8451 if (!u.expr.ti1->get_specific_value() ||
8452 !u.expr.ti4->get_specific_value()) return true;
8453 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8454 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8455 || u.expr.v2->is_unfoldable(refch, exp_val)
8456 || u.expr.v3->is_unfoldable(refch, exp_val)
8457 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8458 }
8459 case OPTYPE_VALUEOF: // ti1
8460 /* \todo if you have motivation to implement the eval function
8461 for valueof()... */
8462 return true;
8463 case OPTYPE_ISCHOSEN_V:
8464 return u.expr.v1->is_unfoldable(refch, exp_val);
8465 case OPTYPE_LOG2STR:
8466 case OPTYPE_TTCN2STRING:
8467 return true;
8468 default:
8469 FATAL_ERROR("Value::is_unfoldable()");
8470 } // switch
8471 break; // should never get here
8472 case V_MACRO:
8473 switch (u.macro) {
8474 case MACRO_TESTCASEID:
8475 // this is known only at runtime
8476 return true;
8477 default:
8478 return false;
8479 }
8480 default:
8481 // all literal values are foldable
8482 return false;
8483 }
8484 }
8485
8486 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8487 size_t start_i, bool usedInIsbound,
8488 ReferenceChain *refch)
8489 {
8490 if (!subrefs) return this;
8491 Value *v = this;
8492 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8493 if (!v) break;
8494 v = v->get_value_refd_last(refch);
8495 switch(v->valuetype) {
8496 case V_ERROR:
8497 return v;
8498 case V_REFD:
8499 // unfoldable stuff
8500 return this;
8501 default:
8502 break;
8503 } // switch
8504 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8505 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8506 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8507 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8508 }
8509 return v;
8510 }
8511
8512 Value *Value::get_refd_field_value(const Identifier& field_id,
8513 bool usedInIsbound, const Location& loc)
8514 {
8515 if (valuetype == V_OMIT) {
8516 loc.error("Reference to field `%s' of omit value `%s'",
8517 field_id.get_dispname().c_str(), get_fullname().c_str());
8518 return 0;
8519 }
8520 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8521 Type *t = my_governor->get_type_refd_last();
8522 switch (t->get_typetype()) {
8523 case Type::T_ERROR:
8524 // remain silent
8525 return 0;
8526 case Type::T_CHOICE_A:
8527 case Type::T_CHOICE_T:
8528 case Type::T_OPENTYPE:
8529 case Type::T_ANYTYPE:
8530 if (!t->has_comp_withName(field_id)) {
8531 loc.error("Reference to non-existent union field `%s' in type `%s'",
8532 field_id.get_dispname().c_str(), t->get_typename().c_str());
8533 return 0;
8534 } else if (valuetype != V_CHOICE) {
8535 // remain silent, the error is already reported
8536 return 0;
8537 } else if (*u.choice.alt_name == field_id) {
8538 // everything is OK
8539 return u.choice.alt_value;
8540 }else {
8541 if (!usedInIsbound) {
8542 loc.error("Reference to inactive field `%s' in a value of union type "
8543 "`%s'. The active field is `%s'",
8544 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8545 u.choice.alt_name->get_dispname().c_str());
8546 }
8547 return 0;
8548 }
8549 case Type::T_SEQ_A:
8550 case Type::T_SEQ_T:
8551 if (!t->has_comp_withName(field_id)) {
8552 loc.error("Reference to non-existent record field `%s' in type `%s'",
8553 field_id.get_dispname().c_str(), t->get_typename().c_str());
8554 return 0;
8555 } else if (valuetype != V_SEQ) {
8556 // remain silent, the error has been already reported
8557 return 0;
8558 } else break;
8559 case Type::T_SET_A:
8560 case Type::T_SET_T:
8561 if (!t->has_comp_withName(field_id)) {
8562 loc.error("Reference to non-existent set field `%s' in type `%s'",
8563 field_id.get_dispname().c_str(), t->get_typename().c_str());
8564 return 0;
8565 } else if (valuetype != V_SET) {
8566 // remain silent, the error has been already reported
8567 return 0;
8568 } else break;
8569 default:
8570 loc.error("Invalid field reference `%s': type `%s' "
8571 "does not have fields", field_id.get_dispname().c_str(),
8572 t->get_typename().c_str());
8573 return 0;
8574 }
8575 // the common end for record & set types
8576 if (u.val_nvs->has_nv_withName(field_id)) {
8577 // everything is OK
8578 return u.val_nvs->get_nv_byName(field_id)->get_value();
8579 } else if (!is_asn1()) {
8580 if (!usedInIsbound) {
8581 loc.error("Reference to unbound field `%s'",
8582 field_id.get_dispname().c_str());
8583 // this is an error in TTCN-3, which has been already reported
8584 }
8585 return 0;
8586 } else {
8587 CompField *cf = t->get_comp_byName(field_id);
8588 if (cf->get_is_optional()) {
8589 // creating an explicit omit value
8590 Value *v = new Value(V_OMIT);
8591 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8592 v->set_my_scope(get_my_scope());
8593 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8594 return v;
8595 } else if (cf->has_default()) {
8596 // returning the component's default value
8597 return cf->get_defval();
8598 } else {
8599 // this is an error in ASN.1, which has been already reported
8600 return 0;
8601 }
8602 }
8603 }
8604
8605 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8606 ReferenceChain *refch)
8607 {
8608 Value *v_index = array_index->get_value_refd_last(refch);
8609 Int index = 0;
8610 bool index_available = false;
8611 if (!v_index->is_unfoldable()) {
8612 if (v_index->valuetype == V_INT) {
8613 index = v_index->get_val_Int()->get_val();
8614 index_available = true;
8615 } else {
8616 array_index->error("An integer value was expected as index");
8617 }
8618 }
8619 if (valuetype == V_OMIT) {
8620 array_index->error("Accessing an element with index of omit value `%s'",
8621 get_fullname().c_str());
8622 return 0;
8623 }
8624 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8625 Type *t = my_governor->get_type_refd_last();
8626 switch (t->get_typetype()) {
8627 case Type::T_ERROR:
8628 // remain silent
8629 return 0;
8630 case Type::T_SEQOF:
8631 if (index_available) {
8632 if (index < 0) {
8633 array_index->error("A non-negative integer value was expected "
8634 "instead of %s for indexing a value of `record "
8635 "of' type `%s'", Int2string(index).c_str(),
8636 t->get_typename().c_str());
8637 return 0;
8638 }
8639 switch (valuetype) {
8640 case V_SEQOF:
8641 if (!is_indexed()) {
8642 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8643 if (!usedInIsbound) {
8644 array_index->error("Index overflow in a value of `record of' "
8645 "type `%s': the index is %s, but the value "
8646 "has only %lu elements",
8647 t->get_typename().c_str(),
8648 Int2string(index).c_str(),
8649 (unsigned long)u.val_vs->get_nof_vs());
8650 }
8651 return 0;
8652 } else {
8653 Value* temp = u.val_vs->get_v_byIndex(index);
8654 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8655 temp->error("Not used symbol is not allowed in this context");
8656 return u.val_vs->get_v_byIndex(index);
8657 }
8658 } else {
8659 // Search the appropriate constant index.
8660 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8661 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8662 ->get_value_refd_last();
8663 if (iv_index->get_valuetype() != V_INT) continue;
8664 if (iv_index->get_val_Int()->get_val() == index)
8665 return u.val_vs->get_iv_byIndex(i)->get_value();
8666 }
8667 return 0;
8668 }
8669 break;
8670 default:
8671 // remain silent, the error has been already reported
8672 return 0;
8673 }
8674 } else {
8675 // the error has been reported above
8676 return 0;
8677 }
8678 case Type::T_SETOF:
8679 if (index_available) {
8680 if (index < 0) {
8681 array_index->error("A non-negative integer value was expected "
8682 "instead of %s for indexing a value of `set of' type `%s'",
8683 Int2string(index).c_str(), t->get_typename().c_str());
8684 return 0;
8685 }
8686 switch (valuetype) {
8687 case V_SETOF:
8688 if (!is_indexed()) {
8689 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8690 if (!usedInIsbound) {
8691 array_index->error("Index overflow in a value of `set of' type "
8692 "`%s': the index is %s, but the value has "
8693 "only %lu elements",
8694 t->get_typename().c_str(),
8695 Int2string(index).c_str(),
8696 (unsigned long)u.val_vs->get_nof_vs());
8697 }
8698 return 0;
8699 } else {
8700 Value* temp = u.val_vs->get_v_byIndex(index);
8701 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8702 temp->error("Not used symbol is not allowed in this context");
8703 return temp;
8704 }
8705 } else {
8706 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8707 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8708 ->get_value_refd_last();
8709 if (iv_index->get_valuetype() != V_INT) continue;
8710 if (iv_index->get_val_Int()->get_val() == index)
8711 return u.val_vs->get_iv_byIndex(i)->get_value();
8712 }
8713 return 0;
8714 }
8715 break;
8716 default:
8717 // remain silent, the error has been already reported
8718 return 0;
8719 }
8720 } else {
8721 // the error has been reported above
8722 return 0;
8723 }
8724 case Type::T_ARRAY:
8725 if (index_available) {
8726 Ttcn::ArrayDimension *dim = t->get_dimension();
8727 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8728 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8729 // perform the index transformation
8730 index -= dim->get_offset();
8731 if (!is_indexed()) {
8732 // check for index underflow/overflow or too few elements in the
8733 // value
8734 if (index < 0 ||
8735 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8736 return 0;
8737 else return u.val_vs->get_v_byIndex(index);
8738 } else {
8739 if (index < 0) return 0;
8740 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8741 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8742 ->get_value_refd_last();
8743 if (iv_index->get_valuetype() != V_INT) continue;
8744 if (iv_index->get_val_Int()->get_val() == index)
8745 return u.val_vs->get_iv_byIndex(index)->get_value();
8746 }
8747 return 0;
8748 }
8749 } else {
8750 // remain silent, the error has been already reported
8751 return 0;
8752 }
8753 } else {
8754 // the error has been reported above
8755 return 0;
8756 }
8757 case Type::T_BSTR:
8758 case Type::T_BSTR_A:
8759 case Type::T_HSTR:
8760 case Type::T_OSTR:
8761 case Type::T_CSTR:
8762 case Type::T_USTR:
8763 case Type::T_UTF8STRING:
8764 case Type::T_NUMERICSTRING:
8765 case Type::T_PRINTABLESTRING:
8766 case Type::T_TELETEXSTRING:
8767 case Type::T_VIDEOTEXSTRING:
8768 case Type::T_IA5STRING:
8769 case Type::T_GRAPHICSTRING:
8770 case Type::T_VISIBLESTRING:
8771 case Type::T_GENERALSTRING:
8772 case Type::T_UNIVERSALSTRING:
8773 case Type::T_BMPSTRING:
8774 case Type::T_UTCTIME:
8775 case Type::T_GENERALIZEDTIME:
8776 case Type::T_OBJECTDESCRIPTOR:
8777 if (index_available) return get_string_element(index, *array_index);
8778 else return 0;
8779 default:
8780 array_index->error("Invalid array element reference: type `%s' cannot "
8781 "be indexed", t->get_typename().c_str());
8782 return 0;
8783 }
8784 }
8785
8786 Value *Value::get_string_element(const Int& index, const Location& loc)
8787 {
8788 if (index < 0) {
8789 loc.error("A non-negative integer value was expected instead of %s "
8790 "for indexing a string element", Int2string(index).c_str());
8791 return 0;
8792 }
8793 size_t string_length;
8794 switch (valuetype) {
8795 case V_BSTR:
8796 case V_HSTR:
8797 case V_CSTR:
8798 case V_ISO2022STR:
8799 string_length = u.str.val_str->size();
8800 break;
8801 case V_OSTR:
8802 string_length = u.str.val_str->size() / 2;
8803 break;
8804 case V_USTR:
8805 string_length = u.ustr.val_ustr->size();
8806 break;
8807 default:
8808 // remain silent, the error has been already reported
8809 return 0;
8810 }
8811 if (index >= static_cast<Int>(string_length)) {
8812 loc.error("Index overflow when accessing a string element: "
8813 "the index is %s, but the string has only %lu elements",
8814 Int2string(index).c_str(), (unsigned long) string_length);
8815 return 0;
8816 }
8817 switch (valuetype) {
8818 case V_BSTR:
8819 case V_HSTR:
8820 case V_CSTR:
8821 case V_ISO2022STR:
8822 if (u.str.str_elements && u.str.str_elements->has_key(index))
8823 return (*u.str.str_elements)[index];
8824 else {
8825 Value *t_val = new Value(valuetype,
8826 new string(u.str.val_str->substr(index, 1)));
8827 add_string_element(index, t_val, u.str.str_elements);
8828 return t_val;
8829 }
8830 case V_OSTR:
8831 if (u.str.str_elements && u.str.str_elements->has_key(index))
8832 return (*u.str.str_elements)[index];
8833 else {
8834 Value *t_val = new Value(V_OSTR,
8835 new string(u.str.val_str->substr(2 * index, 2)));
8836 add_string_element(index, t_val, u.str.str_elements);
8837 return t_val;
8838 }
8839 case V_USTR:
8840 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
8841 return (*u.ustr.ustr_elements)[index];
8842 else {
8843 Value *t_val = new Value(V_USTR,
8844 new ustring(u.ustr.val_ustr->substr(index, 1)));
8845 add_string_element(index, t_val, u.ustr.ustr_elements);
8846 return t_val;
8847 }
8848 default:
8849 FATAL_ERROR("Value::get_string_element()");
8850 return 0;
8851 }
8852 }
8853
8854 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
8855 Type::expected_value_t exp_val)
8856 {
8857 set_lowerid_to_ref();
8858 Type::typetype_t r_tt = get_expr_returntype(exp_val);
8859 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
8860 if (error_flag)
8861 error("A value or expression of type %s was expected", type_name);
8862 if (valuetype == V_REFD) {
8863 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
8864 t_chk->chk_this_refd_value(this, 0, exp_val);
8865 }
8866 get_value_refd_last(0, exp_val);
8867 if (error_flag) set_valuetype(V_ERROR);
8868 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
8869 }
8870
8871 int Value::is_parsed_infinity()
8872 {
8873 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
8874 return 1;
8875 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
8876 (u.expr.v1->get_valuetype()==V_REAL) &&
8877 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
8878 return -1;
8879 return 0;
8880 }
8881
8882 bool Value::get_val_bool()
8883 {
8884 Value *v;
8885 if (valuetype == V_REFD) v = get_value_refd_last();
8886 else v = this;
8887 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
8888 return v->u.val_bool;
8889 }
8890
8891 int_val_t* Value::get_val_Int()
8892 {
8893 Value *v;
8894 if (valuetype == V_REFD) v = get_value_refd_last();
8895 else v = this;
8896 switch (v->valuetype) {
8897 case V_INT:
8898 break;
8899 case V_UNDEF_LOWERID:
8900 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8901 "`%s'", (*u.val_id).get_dispname().c_str());
8902 default:
8903 FATAL_ERROR("Value::get_val_Int()");
8904 } // switch
8905 return v->u.val_Int;
8906 }
8907
8908 const Identifier* Value::get_val_id()
8909 {
8910 switch(valuetype) {
8911 case V_NAMEDINT:
8912 case V_ENUM:
8913 case V_UNDEF_LOWERID:
8914 return u.val_id;
8915 default:
8916 FATAL_ERROR("Value::get_val_id()");
8917 return 0;
8918 } // switch
8919 }
8920
8921 const ttcn3float& Value::get_val_Real()
8922 {
8923 Value *v;
8924 if (valuetype == V_REFD) v = get_value_refd_last();
8925 else v = this;
8926 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
8927 return v->u.val_Real;
8928 }
8929
8930 string Value::get_val_str()
8931 {
8932 Value *v = get_value_refd_last();
8933 switch (v->valuetype) {
8934 case V_BSTR:
8935 case V_HSTR:
8936 case V_OSTR:
8937 case V_CSTR:
8938 return *v->u.str.val_str;
8939 case V_CHARSYMS:
8940 return v->u.char_syms->get_string();
8941 case V_USTR:
8942 error("Cannot use ISO-10646 string value in string context");
8943 return string();
8944 case V_ISO2022STR:
8945 error("Cannot use ISO-2022 string value in string context");
8946 // no break
8947 case V_ERROR:
8948 return string();
8949 default:
8950 error("Cannot use this value in charstring value context");
8951 return string();
8952 } // switch
8953 }
8954
8955 ustring Value::get_val_ustr()
8956 {
8957 Value *v = get_value_refd_last();
8958 switch (v->valuetype) {
8959 case V_CSTR:
8960 return ustring(*v->u.str.val_str);
8961 case V_USTR:
8962 return *v->u.ustr.val_ustr;
8963 case V_CHARSYMS:
8964 return v->u.char_syms->get_ustring();
8965 case V_ISO2022STR:
8966 error("Cannot use ISO-2022 string value in ISO-10646 string context");
8967 // no break
8968 case V_ERROR:
8969 return ustring();
8970 default:
8971 error("Cannot use this value in ISO-10646 string context");
8972 return ustring();
8973 } // switch
8974 }
8975
8976 string Value::get_val_iso2022str()
8977 {
8978 Value *v = get_value_refd_last();
8979 switch (v->valuetype) {
8980 case V_CSTR:
8981 case V_ISO2022STR:
8982 return *v->u.str.val_str;
8983 case V_CHARSYMS:
8984 return v->u.char_syms->get_iso2022string();
8985 case V_USTR:
8986 error("Cannot use ISO-10646 string value in ISO-2022 string context");
8987 // no break
8988 case V_ERROR:
8989 return string();
8990 default:
8991 error("Cannot use this value in ISO-2022 string context");
8992 return string();
8993 } // switch
8994 }
8995
8996 size_t Value::get_val_strlen()
8997 {
8998 Value *v = get_value_refd_last();
8999 switch (v->valuetype) {
9000 case V_BSTR:
9001 case V_HSTR:
9002 case V_CSTR:
9003 case V_ISO2022STR:
9004 return v->u.str.val_str->size();
9005 case V_OSTR:
9006 return v->u.str.val_str->size()/2;
9007 case V_CHARSYMS:
9008 return v->u.char_syms->get_len();
9009 case V_USTR:
9010 return v->u.ustr.val_ustr->size();
9011 case V_ERROR:
9012 return 0;
9013 default:
9014 error("Cannot use this value in string value context");
9015 return 0;
9016 } // switch
9017 }
9018
9019 Value::verdict_t Value::get_val_verdict()
9020 {
9021 switch(valuetype) {
9022 case V_VERDICT:
9023 return u.verdict;
9024 default:
9025 FATAL_ERROR("Value::get_val_verdict()");
9026 return u.verdict;
9027 } // switch
9028 }
9029
9030 size_t Value::get_nof_comps()
9031 {
9032 switch (valuetype) {
9033 case V_OID:
9034 case V_ROID:
9035 chk();
9036 return u.oid_comps->size();
9037 case V_SEQOF:
9038 case V_SETOF:
9039 case V_ARRAY:
9040 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9041 else return u.val_vs->get_nof_vs();
9042 case V_SEQ:
9043 case V_SET:
9044 return u.val_nvs->get_nof_nvs();
9045 case V_BSTR:
9046 case V_HSTR:
9047 case V_CSTR:
9048 case V_ISO2022STR:
9049 return u.str.val_str->size();
9050 case V_OSTR:
9051 return u.str.val_str->size()/2;
9052 case V_USTR:
9053 return u.ustr.val_ustr->size();
9054 default:
9055 FATAL_ERROR("Value::get_nof_comps()");
9056 return 0;
9057 } // switch
9058 }
9059
9060 bool Value::is_indexed() const
9061 {
9062 switch (valuetype) {
9063 case V_SEQOF:
9064 case V_SETOF:
9065 case V_ARRAY:
9066 // Applicable only for list-types. Assigning a record/SEQUENCE or
9067 // set/SET with indexed notation is not supported.
9068 return u.val_vs->is_indexed();
9069 default:
9070 FATAL_ERROR("Value::is_indexed()");
9071 break;
9072 }
9073 return false;
9074 }
9075
9076 const Identifier& Value::get_alt_name()
9077 {
9078 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9079 return *u.choice.alt_name;
9080 }
9081
9082 Value *Value::get_alt_value()
9083 {
9084 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9085 return u.choice.alt_value;
9086 }
9087
9088 void Value::set_alt_name_to_lowercase()
9089 {
9090 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9091 string new_name = u.choice.alt_name->get_name();
9092 if (isupper(new_name[0])) {
9093 new_name[0] = tolower(new_name[0]);
9094 if (new_name[new_name.size() - 1] == '_') {
9095 // an underscore is inserted at the end of the alternative name if it's
9096 // a basic type's name (since it would conflict with the class generated
9097 // for that type)
9098 // remove the underscore, it won't conflict with anything if its name
9099 // starts with a lowercase letter
9100 new_name.replace(new_name.size() - 1, 1, "");
9101 }
9102 delete u.choice.alt_name;
9103 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9104 }
9105 }
9106
9107 bool Value::has_oid_error()
9108 {
9109 Value *v;
9110 if (valuetype == V_REFD) v = get_value_refd_last();
9111 else v = this;
9112 switch (valuetype) {
9113 case V_OID:
9114 case V_ROID:
9115 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9116 if ((*v->u.oid_comps)[i]->has_error()) return true;
9117 return false;
9118 default:
9119 return true;
9120 }
9121 }
9122
9123 bool Value::get_oid_comps(vector<string>& comps)
9124 {
9125 bool ret_val = true;
9126 Value *v = this;
9127 switch (valuetype) {
9128 case V_REFD:
9129 v = get_value_refd_last();
9130 // no break
9131 case V_OID:
9132 case V_ROID:
9133 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9134 (*v->u.oid_comps)[i]->get_comps(comps);
9135 if ((*v->u.oid_comps)[i]->is_variable()) {
9136 // not all components can be calculated in compile-time
9137 ret_val = false;
9138 }
9139 }
9140 break;
9141 default:
9142 FATAL_ERROR("Value::get_oid_comps()");
9143 }
9144 return ret_val;
9145 }
9146
9147 void Value::add_se_comp(NamedValue* nv) {
9148 switch (valuetype) {
9149 case V_SEQ:
9150 case V_SET:
9151 if (!u.val_nvs)
9152 u.val_nvs = new NamedValues();
9153 u.val_nvs->add_nv(nv);
9154 break;
9155 default:
9156 FATAL_ERROR("Value::add_se_comp()");
9157 }
9158 }
9159
9160 NamedValue* Value::get_se_comp_byIndex(size_t n)
9161 {
9162 switch(valuetype) {
9163 case V_SEQ:
9164 case V_SET:
9165 return u.val_nvs->get_nv_byIndex(n);
9166 default:
9167 FATAL_ERROR("Value::get_se_comp_byIndex()");
9168 return 0;
9169 } // switch
9170 }
9171
9172 Value *Value::get_comp_byIndex(size_t n)
9173 {
9174 switch (valuetype) {
9175 case V_SEQOF:
9176 case V_SETOF:
9177 case V_ARRAY:
9178 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9179 return u.val_vs->get_iv_byIndex(n)->get_value();
9180 default:
9181 FATAL_ERROR("Value::get_comp_byIndex()");
9182 return 0;
9183 } // switch
9184 }
9185
9186 Value *Value::get_index_byIndex(size_t n)
9187 {
9188 switch (valuetype) {
9189 case V_SEQOF:
9190 case V_SETOF:
9191 case V_ARRAY:
9192 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9193 return u.val_vs->get_iv_byIndex(n)->get_index();
9194 default:
9195 FATAL_ERROR("Value::get_index_byIndex()");
9196 return 0;
9197 } // switch
9198 }
9199
9200 bool Value::has_comp_withName(const Identifier& p_name)
9201 {
9202 switch(valuetype) {
9203 case V_SEQ:
9204 case V_SET:
9205 return u.val_nvs->has_nv_withName(p_name);
9206 case V_CHOICE:
9207 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9208 default:
9209 FATAL_ERROR("Value::get_has_comp_withName()");
9210 return false;
9211 } // switch
9212 }
9213
9214 bool Value::field_is_chosen(const Identifier& p_name)
9215 {
9216 Value *v=get_value_refd_last();
9217 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9218 return *v->u.choice.alt_name==p_name;
9219 }
9220
9221 bool Value::field_is_present(const Identifier& p_name)
9222 {
9223 Value *v=get_value_refd_last();
9224 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9225 FATAL_ERROR("Value::field_is_present()");
9226 return v->u.val_nvs->has_nv_withName(p_name)
9227 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9228 ->get_value_refd_last()->valuetype != V_OMIT;
9229 }
9230
9231 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9232 {
9233 switch(valuetype) {
9234 case V_SEQ:
9235 case V_SET:
9236 return u.val_nvs->get_nv_byName(p_name);
9237 default:
9238 FATAL_ERROR("Value::get_se_comp_byName()");
9239 return 0;
9240 } // switch
9241 }
9242
9243 Value* Value::get_comp_value_byName(const Identifier& p_name)
9244 {
9245 switch(valuetype) {
9246 case V_SEQ:
9247 case V_SET:
9248 return u.val_nvs->get_nv_byName(p_name)->get_value();
9249 case V_CHOICE:
9250 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9251 return u.choice.alt_value;
9252 else
9253 return NULL;
9254 default:
9255 FATAL_ERROR("Value::get_se_comp_byName()");
9256 return 0;
9257 } // switch
9258 }
9259
9260 void Value::chk_dupl_id()
9261 {
9262 switch(valuetype) {
9263 case V_SEQ:
9264 case V_SET:
9265 u.val_nvs->chk_dupl_id();
9266 break;
9267 default:
9268 FATAL_ERROR("Value::chk_dupl_id()");
9269 } // switch
9270 }
9271
9272 size_t Value::get_nof_ids() const
9273 {
9274 switch(valuetype) {
9275 case V_NAMEDBITS:
9276 return u.ids->size();
9277 break;
9278 default:
9279 FATAL_ERROR("Value::get_nof_ids()");
9280 return 0;
9281 } // switch
9282 }
9283
9284 Identifier* Value::get_id_byIndex(size_t p_i)
9285 {
9286 switch(valuetype) {
9287 case V_NAMEDBITS:
9288 return u.ids->get_nth_elem(p_i);
9289 break;
9290 default:
9291 FATAL_ERROR("Value::get_id_byIndex()");
9292 return 0;
9293 } // switch
9294 }
9295
9296 bool Value::has_id(const Identifier& p_id)
9297 {
9298 switch(valuetype) {
9299 case V_NAMEDBITS:
9300 return u.ids->has_key(p_id.get_name());
9301 break;
9302 default:
9303 FATAL_ERROR("Value::has_id()");
9304 return false;
9305 } // switch
9306 }
9307
9308 Reference *Value::get_reference() const
9309 {
9310 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9311 return u.ref.ref;
9312 }
9313
9314 Reference *Value::get_refered() const
9315 {
9316 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9317 return u.refered;
9318 }
9319
9320 Common::Assignment *Value::get_refd_fat() const
9321 {
9322 switch(valuetype){
9323 case V_FUNCTION:
9324 case V_ALTSTEP:
9325 case V_TESTCASE:
9326 return u.refd_fat;
9327 default:
9328 FATAL_ERROR("Value::get_refd_fat()");
9329 }
9330 }
9331
9332 Ttcn::Reference* Value::steal_ttcn_ref()
9333 {
9334 Ttcn::Reference *ret_val =
9335 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9336 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9337 return ret_val;
9338 }
9339
9340 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9341 {
9342 Ttcn::Ref_base *t_ref;
9343 if(valuetype==V_REFD) {
9344 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9345 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9346 u.ref.ref=0;
9347 }
9348 else if(valuetype==V_UNDEF_LOWERID) {
9349 t_ref=new Ttcn::Reference(u.val_id);
9350 t_ref->set_location(*this);
9351 t_ref->set_fullname(get_fullname());
9352 t_ref->set_my_scope(get_my_scope());
9353 u.val_id=0;
9354 }
9355 else {
9356 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9357 t_ref = 0;
9358 }
9359 set_valuetype(V_ERROR);
9360 return t_ref;
9361 }
9362
9363 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9364 Ttcn::ActualParList*& p_ap)
9365 {
9366 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9367 p_v = u.invoke.v;
9368 u.invoke.v = 0;
9369 p_ti = u.invoke.t_list;
9370 u.invoke.t_list = 0;
9371 p_ap = u.invoke.ap_list;
9372 u.invoke.ap_list = 0;
9373 set_valuetype(V_ERROR);
9374 }
9375
9376 Common::Assignment* Value::get_refd_assignment()
9377 {
9378 switch(valuetype) {
9379 case V_FUNCTION:
9380 case V_ALTSTEP:
9381 case V_TESTCASE:
9382 return u.refd_fat;
9383 break;
9384 default:
9385 FATAL_ERROR("Value::get_refd_assignment()");
9386 return 0;
9387 }
9388 }
9389
9390 void Value::chk()
9391 {
9392 if(checked) return;
9393 switch(valuetype) {
9394 case V_OID: {
9395 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9396 " components");
9397 chk_OID(refch);
9398 break; }
9399 case V_ROID: {
9400 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9401 chk_ROID(refch);
9402 break; }
9403 default:
9404 break;
9405 } // switch
9406 checked=true;
9407 }
9408
9409 void Value::chk_OID(ReferenceChain& refch)
9410 {
9411 if (checked) return;
9412 if (valuetype != V_OID || u.oid_comps->size() < 1)
9413 FATAL_ERROR("Value::chk_OID()");
9414 if (!refch.add(get_fullname())) {
9415 checked = true;
9416 return;
9417 }
9418 OID_comp::oidstate_t state = OID_comp::START;
9419 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9420 refch.mark_state();
9421 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9422 refch.prev_state();
9423 }
9424 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9425 error("An OBJECT IDENTIFIER value must have at least "
9426 "two components"); // X.680 (07/2002) 31.10
9427 }
9428
9429 void Value::chk_ROID(ReferenceChain& refch)
9430 {
9431 if (checked) return;
9432 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9433 FATAL_ERROR("Value::chk_ROID()");
9434 if (!refch.add(get_fullname())) {
9435 checked = true;
9436 return;
9437 }
9438 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9439 refch.mark_state();
9440 (*u.oid_comps)[i]->chk_ROID(refch, i);
9441 refch.prev_state();
9442 }
9443 }
9444
9445 void Value::chk_recursions(ReferenceChain& refch)
9446 {
9447 if (recurs_checked) return;
9448 Value *v = get_value_refd_last();
9449 if (refch.add(v->get_fullname())) {
9450 switch (v->valuetype) {
9451 case V_CHOICE:
9452 v->u.choice.alt_value->chk_recursions(refch);
9453 break;
9454 case V_SEQOF:
9455 case V_SETOF:
9456 case V_ARRAY:
9457 if (!v->is_indexed()) {
9458 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9459 refch.mark_state();
9460 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9461 refch.prev_state();
9462 }
9463 } else {
9464 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9465 refch.mark_state();
9466 v->u.val_vs->get_iv_byIndex(i)->get_value()
9467 ->chk_recursions(refch);
9468 refch.prev_state();
9469 }
9470 }
9471 break;
9472 case V_SEQ:
9473 case V_SET:
9474 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9475 refch.mark_state();
9476 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9477 refch.prev_state();
9478 }
9479 break;
9480 case V_EXPR:
9481 chk_recursions_expr(refch);
9482 break;
9483 default:
9484 break;
9485 }
9486 if (v->err_descr) { // FIXME: make this work
9487 v->err_descr->chk_recursions(refch);
9488 }
9489 }
9490 recurs_checked = true;
9491 }
9492
9493 void Value::chk_recursions_expr(ReferenceChain& refch)
9494 {
9495 // first classify the unchecked ischosen() operation
9496 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9497 switch (u.expr.v_optype) {
9498 case OPTYPE_UNARYPLUS: // v1
9499 case OPTYPE_UNARYMINUS:
9500 case OPTYPE_NOT:
9501 case OPTYPE_NOT4B:
9502 case OPTYPE_BIT2HEX:
9503 case OPTYPE_BIT2INT:
9504 case OPTYPE_BIT2OCT:
9505 case OPTYPE_BIT2STR:
9506 case OPTYPE_CHAR2INT:
9507 case OPTYPE_CHAR2OCT:
9508 case OPTYPE_FLOAT2INT:
9509 case OPTYPE_FLOAT2STR:
9510 case OPTYPE_HEX2BIT:
9511 case OPTYPE_HEX2INT:
9512 case OPTYPE_HEX2OCT:
9513 case OPTYPE_HEX2STR:
9514 case OPTYPE_INT2CHAR:
9515 case OPTYPE_INT2FLOAT:
9516 case OPTYPE_INT2STR:
9517 case OPTYPE_INT2UNICHAR:
9518 case OPTYPE_OCT2BIT:
9519 case OPTYPE_OCT2CHAR:
9520 case OPTYPE_OCT2HEX:
9521 case OPTYPE_OCT2INT:
9522 case OPTYPE_OCT2STR:
9523 case OPTYPE_STR2BIT:
9524 case OPTYPE_STR2FLOAT:
9525 case OPTYPE_STR2HEX:
9526 case OPTYPE_STR2INT:
9527 case OPTYPE_STR2OCT:
9528 case OPTYPE_UNICHAR2INT:
9529 case OPTYPE_ENUM2INT:
9530 case OPTYPE_UNICHAR2CHAR:
9531 case OPTYPE_RNDWITHVAL:
9532 case OPTYPE_ISCHOSEN_V:
9533 case OPTYPE_GET_STRINGENCODING:
9534 case OPTYPE_REMOVE_BOM:
9535 case OPTYPE_DECODE_BASE64:
9536 refch.mark_state();
9537 u.expr.v1->chk_recursions(refch);
9538 refch.prev_state();
9539 break;
9540 case OPTYPE_ISCHOSEN_T:
9541 refch.mark_state();
9542 u.expr.t1->chk_recursions(refch);
9543 refch.prev_state();
9544 break;
9545 case OPTYPE_ADD: // v1 v2
9546 case OPTYPE_SUBTRACT:
9547 case OPTYPE_MULTIPLY:
9548 case OPTYPE_DIVIDE:
9549 case OPTYPE_MOD:
9550 case OPTYPE_REM:
9551 case OPTYPE_CONCAT:
9552 case OPTYPE_EQ:
9553 case OPTYPE_LT:
9554 case OPTYPE_GT:
9555 case OPTYPE_NE:
9556 case OPTYPE_GE:
9557 case OPTYPE_LE:
9558 case OPTYPE_AND:
9559 case OPTYPE_OR:
9560 case OPTYPE_XOR:
9561 case OPTYPE_AND4B:
9562 case OPTYPE_OR4B:
9563 case OPTYPE_XOR4B:
9564 case OPTYPE_SHL:
9565 case OPTYPE_SHR:
9566 case OPTYPE_ROTL:
9567 case OPTYPE_ROTR:
9568 case OPTYPE_INT2BIT:
9569 case OPTYPE_INT2HEX:
9570 case OPTYPE_INT2OCT:
9571 refch.mark_state();
9572 u.expr.v1->chk_recursions(refch);
9573 refch.prev_state();
9574 refch.mark_state();
9575 u.expr.v2->chk_recursions(refch);
9576 refch.prev_state();
9577 break;
9578 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9579 case OPTYPE_OCT2UNICHAR:
9580 case OPTYPE_ENCODE_BASE64:
9581 refch.mark_state();
9582 u.expr.v1->chk_recursions(refch);
9583 refch.prev_state();
9584 if (u.expr.v2) {
9585 refch.mark_state();
9586 u.expr.v2->chk_recursions(refch);
9587 refch.prev_state();
9588 }
9589 break;
9590 case OPTYPE_DECODE:
9591 chk_recursions_expr_decode(u.expr.r1, refch);
9592 chk_recursions_expr_decode(u.expr.r2, refch);
9593 break;
9594 case OPTYPE_SUBSTR:
9595 refch.mark_state();
9596 u.expr.ti1->chk_recursions(refch);
9597 refch.prev_state();
9598 refch.mark_state();
9599 u.expr.v2->chk_recursions(refch);
9600 refch.prev_state();
9601 refch.mark_state();
9602 u.expr.v3->chk_recursions(refch);
9603 refch.prev_state();
9604 break;
9605 case OPTYPE_REGEXP:
9606 refch.mark_state();
9607 u.expr.ti1->chk_recursions(refch);
9608 refch.prev_state();
9609 refch.mark_state();
9610 u.expr.t2->chk_recursions(refch);
9611 refch.prev_state();
9612 refch.mark_state();
9613 u.expr.v3->chk_recursions(refch);
9614 refch.prev_state();
9615 break;
9616 case OPTYPE_DECOMP: // v1 v2 v3
9617 refch.mark_state();
9618 u.expr.v1->chk_recursions(refch);
9619 refch.prev_state();
9620 refch.mark_state();
9621 u.expr.v2->chk_recursions(refch);
9622 refch.prev_state();
9623 refch.mark_state();
9624 u.expr.v3->chk_recursions(refch);
9625 refch.prev_state();
9626 break;
9627 case OPTYPE_REPLACE:
9628 refch.mark_state();
9629 u.expr.ti1->chk_recursions(refch);
9630 refch.prev_state();
9631 refch.mark_state();
9632 u.expr.v2->chk_recursions(refch);
9633 refch.prev_state();
9634 refch.mark_state();
9635 u.expr.v3->chk_recursions(refch);
9636 refch.prev_state();
9637 refch.mark_state();
9638 u.expr.ti4->chk_recursions(refch);
9639 refch.prev_state();
9640 break;
9641 case OPTYPE_LENGTHOF: // ti1
9642 case OPTYPE_SIZEOF: // ti1
9643 case OPTYPE_VALUEOF: // ti1
9644 case OPTYPE_ENCODE:
9645 case OPTYPE_ISPRESENT:
9646 case OPTYPE_TTCN2STRING:
9647 refch.mark_state();
9648 u.expr.ti1->chk_recursions(refch);
9649 refch.prev_state();
9650 break;
9651 case OPTYPE_MATCH: // v1 t2
9652 refch.mark_state();
9653 u.expr.v1->chk_recursions(refch);
9654 refch.prev_state();
9655 refch.mark_state();
9656 u.expr.t2->chk_recursions(refch);
9657 refch.prev_state();
9658 break;
9659 case OPTYPE_LOG2STR:
9660 u.expr.logargs->chk_recursions(refch);
9661 break;
9662 default:
9663 break;
9664 } // switch
9665 }
9666
9667 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9668 ReferenceChain& refch) {
9669 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9670 Assignment *ass = ref->get_refd_assignment();
9671 if (!ass) {
9672 set_valuetype(V_ERROR);
9673 return;
9674 }
9675 switch (ass->get_asstype()) {
9676 case Assignment::A_CONST:
9677 case Assignment::A_EXT_CONST:
9678 case Assignment::A_MODULEPAR:
9679 case Assignment::A_VAR:
9680 case Assignment::A_PAR_VAL_IN:
9681 case Assignment::A_PAR_VAL_OUT:
9682 case Assignment::A_PAR_VAL_INOUT: {
9683 Value* v = new Value(V_REFD, ref);
9684 v->set_location(*ref);
9685 v->set_my_scope(get_my_scope());
9686 v->set_fullname(get_fullname()+".<operand>");
9687 refch.mark_state();
9688 v->chk_recursions(refch);
9689 refch.prev_state();
9690 delete v;
9691 break; }
9692 case Assignment::A_MODULEPAR_TEMP:
9693 case Assignment::A_TEMPLATE:
9694 case Assignment::A_VAR_TEMPLATE:
9695 case Assignment::A_PAR_TEMPL_IN:
9696 case Assignment::A_PAR_TEMPL_OUT:
9697 case Assignment::A_PAR_TEMPL_INOUT: {
9698 Template* t = new Template(ref->clone());
9699 t->set_location(*ref);
9700 t->set_my_scope(get_my_scope());
9701 t->set_fullname(get_fullname()+".<operand>");
9702 refch.mark_state();
9703 t->chk_recursions(refch);
9704 refch.prev_state();
9705 delete t;
9706 break; }
9707 default:
9708 // remain silent, the error has been already reported
9709 set_valuetype(V_ERROR);
9710 break;
9711 } // switch
9712 }
9713
9714 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9715 {
9716 bool self_ref = false;
9717 switch (t->get_templatetype()) {
9718 case Ttcn::Template::SPECIFIC_VALUE: {
9719 Value *v = t->get_specific_value();
9720 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9721 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9722 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9723 break; }
9724 case Ttcn::Template::TEMPLATE_REFD: {
9725 Ttcn::Ref_base *refb = t->get_reference();
9726 Common::Assignment *ass = refb->get_refd_assignment();
9727 self_ref |= (ass == lhs);
9728 break; }
9729 case Ttcn::Template::ALL_FROM:
9730 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9731 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9732 break;
9733 case Ttcn::Template::TEMPLATE_LIST:
9734 case Ttcn::Template::SUPERSET_MATCH:
9735 case Ttcn::Template::SUBSET_MATCH:
9736 case Ttcn::Template::PERMUTATION_MATCH:
9737 case Ttcn::Template::COMPLEMENTED_LIST:
9738 case Ttcn::Template::VALUE_LIST: {
9739 size_t num = t->get_nof_comps();
9740 for (size_t i = 0; i < num; ++i) {
9741 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9742 }
9743 break; }
9744 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9745 // case Ttcn::Template::TEMPLATE_LIST: {
9746 // size_t num = t->get_nof_listitems();
9747 // for (size_t i=0; i < num; ++i) {
9748 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9749 // }
9750 // break; }
9751 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9752 size_t nnt = t->get_nof_comps();
9753 for (size_t i=0; i < nnt; ++i) {
9754 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9755 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9756 }
9757 break; }
9758 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9759 size_t nnt = t->get_nof_comps();
9760 for (size_t i=0; i < nnt; ++i) {
9761 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9762 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9763 }
9764 break; }
9765 case Ttcn::Template::VALUE_RANGE: {
9766 Ttcn::ValueRange *vr = t->get_value_range();
9767 Common::Value *v = vr->get_min_v();
9768 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9769 v = vr->get_max_v();
9770 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9771 break; }
9772 case Ttcn::Template::CSTR_PATTERN:
9773 case Ttcn::Template::USTR_PATTERN: {
9774 Ttcn::PatternString *ps = t->get_cstr_pattern();
9775 self_ref |= ps->chk_self_ref(lhs);
9776 break; }
9777 case Ttcn::Template::BSTR_PATTERN:
9778 case Ttcn::Template::HSTR_PATTERN:
9779 case Ttcn::Template::OSTR_PATTERN: {
9780 // FIXME: cannot access u.pattern
9781 break; }
9782 case Ttcn::Template::ANY_VALUE:
9783 case Ttcn::Template::ANY_OR_OMIT:
9784 case Ttcn::Template::OMIT_VALUE:
9785 case Ttcn::Template::TEMPLATE_NOTUSED:
9786 break; // self-ref can't happen
9787 case Ttcn::Template::TEMPLATE_INVOKE:
9788 break; // assume self-ref can't happen
9789 case Ttcn::Template::TEMPLATE_ERROR:
9790 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9791 break;
9792 // default:
9793 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9794 // break; // and hope for the best
9795 }
9796 return self_ref;
9797 }
9798
9799 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
9800 {
9801 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
9802 namedbool is_str_elem = NOT_STR_ELEM;
9803 if (v->valuetype == V_REFD) {
9804 Reference *ref = v->get_reference();
9805 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
9806 if (subrefs && subrefs->refers_to_string_element()) {
9807 is_str_elem = IS_STR_ELEM;
9808 }
9809 }
9810 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9811 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
9812 is_str_elem);
9813 }
9814
9815 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
9816 {
9817 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
9818 if (!lhs) FATAL_ERROR("no lhs!");
9819 bool self_ref = false;
9820 switch (u.expr.v_optype) {
9821 case OPTYPE_RND: // -
9822 case OPTYPE_TESTCASENAME: // -
9823 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
9824 case OPTYPE_COMP_MTC: // -
9825 case OPTYPE_COMP_SYSTEM: // -
9826 case OPTYPE_COMP_SELF: // -
9827 case OPTYPE_COMP_RUNNING_ANY: // -
9828 case OPTYPE_COMP_RUNNING_ALL: // -
9829 case OPTYPE_COMP_ALIVE_ANY: // -
9830 case OPTYPE_COMP_ALIVE_ALL: // -
9831 case OPTYPE_TMR_RUNNING_ANY: // -
9832 case OPTYPE_GETVERDICT: // -
9833 case OPTYPE_PROF_RUNNING: // -
9834 break; // nothing to do
9835
9836 case OPTYPE_MATCH: // v1 t2
9837 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
9838 // no break
9839 case OPTYPE_UNARYPLUS: // v1
9840 case OPTYPE_UNARYMINUS: // v1
9841 case OPTYPE_NOT: // v1
9842 case OPTYPE_NOT4B: // v1
9843 case OPTYPE_BIT2HEX: // v1
9844 case OPTYPE_BIT2INT: // v1
9845 case OPTYPE_BIT2OCT: // v1
9846 case OPTYPE_BIT2STR: // v1
9847 case OPTYPE_CHAR2INT: // v1
9848 case OPTYPE_CHAR2OCT: // v1
9849 case OPTYPE_FLOAT2INT: // v1
9850 case OPTYPE_FLOAT2STR: // v1
9851 case OPTYPE_HEX2BIT: // v1
9852 case OPTYPE_HEX2INT: // v1
9853 case OPTYPE_HEX2OCT: // v1
9854 case OPTYPE_HEX2STR: // v1
9855 case OPTYPE_INT2CHAR: // v1
9856 case OPTYPE_INT2FLOAT: // v1
9857 case OPTYPE_INT2STR: // v1
9858 case OPTYPE_INT2UNICHAR: // v1
9859 case OPTYPE_OCT2BIT: // v1
9860 case OPTYPE_OCT2CHAR: // v1
9861 case OPTYPE_OCT2HEX: // v1
9862 case OPTYPE_OCT2INT: // v1
9863 case OPTYPE_OCT2STR: // v1
9864 case OPTYPE_STR2BIT: // v1
9865 case OPTYPE_STR2FLOAT: // v1
9866 case OPTYPE_STR2HEX: // v1
9867 case OPTYPE_STR2INT: // v1
9868 case OPTYPE_STR2OCT: // v1
9869 case OPTYPE_UNICHAR2INT: // v1
9870 case OPTYPE_UNICHAR2CHAR: // v1
9871 case OPTYPE_ENUM2INT: // v1
9872 case OPTYPE_RNDWITHVAL: // v1
9873 case OPTYPE_COMP_RUNNING: // v1
9874 case OPTYPE_COMP_ALIVE: // v1
9875 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
9876 case OPTYPE_GET_STRINGENCODING:
9877 case OPTYPE_DECODE_BASE64:
9878 case OPTYPE_REMOVE_BOM:
9879 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9880 break;
9881 case OPTYPE_ADD: // v1 v2
9882 case OPTYPE_SUBTRACT: // v1 v2
9883 case OPTYPE_MULTIPLY: // v1 v2
9884 case OPTYPE_DIVIDE: // v1 v2
9885 case OPTYPE_MOD: // v1 v2
9886 case OPTYPE_REM: // v1 v2
9887 case OPTYPE_CONCAT: // v1 v2
9888 case OPTYPE_EQ: // v1 v2
9889 case OPTYPE_LT: // v1 v2
9890 case OPTYPE_GT: // v1 v2
9891 case OPTYPE_NE: // v1 v2
9892 case OPTYPE_GE: // v1 v2
9893 case OPTYPE_LE: // v1 v2
9894 case OPTYPE_AND: // v1 v2
9895 case OPTYPE_OR: // v1 v2
9896 case OPTYPE_XOR: // v1 v2
9897 case OPTYPE_AND4B: // v1 v2
9898 case OPTYPE_OR4B: // v1 v2
9899 case OPTYPE_XOR4B: // v1 v2
9900 case OPTYPE_SHL: // v1 v2
9901 case OPTYPE_SHR: // v1 v2
9902 case OPTYPE_ROTL: // v1 v2
9903 case OPTYPE_ROTR: // v1 v2
9904 case OPTYPE_INT2BIT: // v1 v2
9905 case OPTYPE_INT2HEX: // v1 v2
9906 case OPTYPE_INT2OCT: // v1 v2
9907 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9908 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9909 break;
9910 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9911 case OPTYPE_OCT2UNICHAR:
9912 case OPTYPE_ENCODE_BASE64:
9913 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9914 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9915 break;
9916 case OPTYPE_DECOMP: // v1 v2 v3
9917 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9918 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9919 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9920 break;
9921
9922 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
9923 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
9924 // no break
9925 case OPTYPE_SUBSTR: // ti1 v2 v3
9926 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9927 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
9928 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
9929 break;
9930
9931 case OPTYPE_REGEXP: // ti1 t2 v3
9932 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9933 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
9934 // no break
9935 case OPTYPE_LENGTHOF: // ti1
9936 case OPTYPE_SIZEOF: // ti1
9937 case OPTYPE_VALUEOF: // ti1
9938 case OPTYPE_ENCODE: // ti1
9939 case OPTYPE_TTCN2STRING:
9940 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9941 break;
9942
9943 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
9944 // component.create -- assume no self-ref
9945 case OPTYPE_ACTIVATE: // r1
9946 // defaultref := activate(altstep) -- assume no self-ref
9947 case OPTYPE_TMR_RUNNING: // r1
9948 // boolvar := a_timer.running -- assume no self-ref
9949 break;
9950 break;
9951
9952 case OPTYPE_LOG2STR: {// logargs
9953 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
9954 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
9955 switch (la->get_type()) {
9956 case Ttcn::LogArgument::L_UNDEF:
9957 case Ttcn::LogArgument::L_ERROR:
9958 FATAL_ERROR("log2str argument type");
9959 break; // not reached
9960
9961 case Ttcn::LogArgument::L_MACRO:
9962 case Ttcn::LogArgument::L_STR:
9963 break; // self reference not possible
9964
9965 case Ttcn::LogArgument::L_VAL:
9966 case Ttcn::LogArgument::L_MATCH:
9967 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
9968 break;
9969
9970 case Ttcn::LogArgument::L_REF: {
9971 Ttcn::Ref_base *ref = la->get_ref();
9972 Common::Assignment *ass = ref->get_refd_assignment();
9973 self_ref |= (ass == lhs);
9974 break; }
9975
9976 case Ttcn::LogArgument::L_TI: {
9977 Ttcn::TemplateInstance *ti = la->get_ti();
9978 Ttcn::Template *t = ti->get_Template();
9979 self_ref |= chk_expr_self_ref_templ(t, lhs);
9980 break; }
9981
9982 // no default please
9983 } // switch la->logargtype
9984 }
9985 break; }
9986
9987 case OPTYPE_DECODE: { // r1 r2
9988 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
9989 self_ref |= (ass == lhs);
9990 goto label_r1; }
9991 case OPTYPE_EXECUTE: // r1 [v2]
9992 if (u.expr.v2) {
9993 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9994 }
9995 label_r1:
9996 // no break
9997 case OPTYPE_UNDEF_RUNNING: // r1
9998 case OPTYPE_TMR_READ: { // r1
9999 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
10000 self_ref |= (ass == lhs);
10001 break; }
10002
10003 case OPTYPE_ISCHOSEN_T: // t1 i2
10004 case OPTYPE_ISBOUND: // ti1
10005 case OPTYPE_ISVALUE: // ti1
10006 case OPTYPE_ISPRESENT: { // ti1
10007 Ttcn::Template *t;
10008 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10009 else t = u.expr.ti1->get_Template();
10010 self_ref |= chk_expr_self_ref_templ(t, lhs);
10011 break; }
10012
10013 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10014 if (u.expr.v3) {
10015 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10016 }
10017 // no break
10018 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10019 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10020 // TODO t_list2
10021 break;
10022
10023 case NUMBER_OF_OPTYPES: // can never happen
10024 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10025 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10026 break;
10027 } // switch u.expr.v_optype
10028 return self_ref;
10029 }
10030
10031
10032 string Value::create_stringRepr()
10033 {
10034 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10035 switch (valuetype) {
10036 case V_ERROR:
10037 return string("<erroneous>");
10038 case V_NULL:
10039 return string("NULL");
10040 case V_BOOL:
10041 if (!parse_only && is_asn1()) {
10042 if (u.val_bool) return string("TRUE");
10043 else return string("FALSE");
10044 }
10045 else {
10046 if (u.val_bool) return string("true");
10047 else return string("false");
10048 }
10049 case V_INT:
10050 return u.val_Int->t_str();
10051 case V_REAL:
10052 return Real2string(u.val_Real);
10053 case V_ENUM:
10054 case V_NAMEDINT:
10055 case V_UNDEF_LOWERID:
10056 return u.val_id->get_name();
10057 case V_NAMEDBITS: {
10058 string ret_val("{ ");
10059 for (size_t i = 0; i < u.ids->size(); i++) {
10060 if (i>0) ret_val += ' ';
10061 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10062 }
10063 ret_val += '}';
10064 return ret_val; }
10065 case V_BSTR: {
10066 string ret_val('\'');
10067 ret_val += *u.str.val_str;
10068 ret_val += "'B";
10069 return ret_val; }
10070 case V_HSTR: {
10071 string ret_val('\'');
10072 ret_val += *u.str.val_str;
10073 ret_val += "'H";
10074 return ret_val; }
10075 case V_OSTR: {
10076 string ret_val('\'');
10077 ret_val += *u.str.val_str;
10078 ret_val += "'O";
10079 return ret_val; }
10080 case V_CSTR:
10081 case V_ISO2022STR:
10082 return u.str.val_str->get_stringRepr();
10083 case V_USTR:
10084 return u.ustr.val_ustr->get_stringRepr();
10085 case V_CHARSYMS:
10086 /** \todo stringrepr of V_CHARSYMS */
10087 return string("<sorry, string representation of charsyms "
10088 "not implemented>");
10089 case V_OID:
10090 case V_ROID: {
10091 string ret_val;
10092 if (parse_only || !is_asn1()) ret_val += "objid ";
10093 ret_val += "{ ";
10094 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10095 if (i>0) ret_val += ' ';
10096 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10097 }
10098 ret_val += " }";
10099 return ret_val; }
10100 case V_CHOICE:
10101 if (!parse_only && is_asn1()) {
10102 string ret_val(u.choice.alt_name->get_dispname());
10103 ret_val += " : ";
10104 ret_val += u.choice.alt_value->get_stringRepr();
10105 return ret_val;
10106 }
10107 else {
10108 string ret_val("{ ");
10109 ret_val += u.choice.alt_name->get_dispname();
10110 ret_val += " := ";
10111 ret_val += u.choice.alt_value->get_stringRepr();
10112 ret_val += " }";
10113 return ret_val;
10114 }
10115 case V_SEQOF:
10116 case V_SETOF:
10117 case V_ARRAY: {
10118 string ret_val("{ ");
10119 if (!is_indexed()) {
10120 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10121 if (i > 0) ret_val += ", ";
10122 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10123 }
10124 } else {
10125 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10126 if (i > 0) ret_val += ", ";
10127 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10128 }
10129 }
10130 ret_val += " }";
10131 return ret_val; }
10132 case V_SEQ:
10133 case V_SET: {
10134 string ret_val("{ ");
10135 bool asn1_flag = !parse_only && is_asn1();
10136 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10137 if (i > 0) ret_val += ", ";
10138 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10139 ret_val += nv->get_name().get_dispname();
10140 if (asn1_flag) ret_val += ' ';
10141 else ret_val += " := ";
10142 ret_val += nv->get_value()->get_stringRepr();
10143 }
10144 ret_val += " }";
10145 return ret_val; }
10146 case V_REFD: {
10147 // do not evaluate the reference if it is not done so far
10148 // (e.g. in parse-only mode)
10149 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10150 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10151 else return t_val->get_stringRepr(); }
10152 case V_OMIT:
10153 return string("omit");
10154 case V_VERDICT:
10155 switch (u.verdict) {
10156 case Verdict_NONE:
10157 return string("none");
10158 case Verdict_PASS:
10159 return string("pass");
10160 case Verdict_INCONC:
10161 return string("inconc");
10162 case Verdict_FAIL:
10163 return string("fail");
10164 case Verdict_ERROR:
10165 return string("error");
10166 default:
10167 return string("<unknown verdict value>");
10168 }
10169 case V_DEFAULT_NULL:
10170 case V_FAT_NULL:
10171 return string("null");
10172 case V_EXPR:
10173 switch (u.expr.v_optype) {
10174 case OPTYPE_RND:
10175 return string("rnd()");
10176 case OPTYPE_TESTCASENAME:
10177 return string("testcasename()");
10178 case OPTYPE_UNARYPLUS:
10179 return create_stringRepr_unary("+");
10180 case OPTYPE_UNARYMINUS:
10181 return create_stringRepr_unary("-");
10182 case OPTYPE_NOT:
10183 return create_stringRepr_unary("not");
10184 case OPTYPE_NOT4B:
10185 return create_stringRepr_unary("not4b");
10186 case OPTYPE_BIT2HEX:
10187 return create_stringRepr_predef1("bit2hex");
10188 case OPTYPE_BIT2INT:
10189 return create_stringRepr_predef1("bit2int");
10190 case OPTYPE_BIT2OCT:
10191 return create_stringRepr_predef1("bit2oct");
10192 case OPTYPE_BIT2STR:
10193 return create_stringRepr_predef1("bit2str");
10194 case OPTYPE_CHAR2INT:
10195 return create_stringRepr_predef1("char2int");
10196 case OPTYPE_CHAR2OCT:
10197 return create_stringRepr_predef1("char2oct");
10198 case OPTYPE_FLOAT2INT:
10199 return create_stringRepr_predef1("float2int");
10200 case OPTYPE_FLOAT2STR:
10201 return create_stringRepr_predef1("float2str");
10202 case OPTYPE_HEX2BIT:
10203 return create_stringRepr_predef1("hex2bit");
10204 case OPTYPE_HEX2INT:
10205 return create_stringRepr_predef1("hex2int");
10206 case OPTYPE_HEX2OCT:
10207 return create_stringRepr_predef1("hex2oct");
10208 case OPTYPE_HEX2STR:
10209 return create_stringRepr_predef1("hex2str");
10210 case OPTYPE_INT2CHAR:
10211 return create_stringRepr_predef1("int2char");
10212 case OPTYPE_INT2FLOAT:
10213 return create_stringRepr_predef1("int2float");
10214 case OPTYPE_INT2STR:
10215 return create_stringRepr_predef1("int2str");
10216 case OPTYPE_INT2UNICHAR:
10217 return create_stringRepr_predef1("int2unichar");
10218 case OPTYPE_OCT2BIT:
10219 return create_stringRepr_predef1("oct2bit");
10220 case OPTYPE_OCT2CHAR:
10221 return create_stringRepr_predef1("oct2char");
10222 case OPTYPE_OCT2HEX:
10223 return create_stringRepr_predef1("oct2hex");
10224 case OPTYPE_OCT2INT:
10225 return create_stringRepr_predef1("oct2int");
10226 case OPTYPE_OCT2STR:
10227 return create_stringRepr_predef1("oct2str");
10228 case OPTYPE_GET_STRINGENCODING:
10229 return create_stringRepr_predef1("get_stringencoding");
10230 case OPTYPE_REMOVE_BOM:
10231 return create_stringRepr_predef1("remove_bom");
10232 case OPTYPE_ENCODE_BASE64: {
10233 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10234 else return create_stringRepr_predef1("encode_base64");
10235 }
10236 case OPTYPE_DECODE_BASE64:
10237 return create_stringRepr_predef1("decode_base64");
10238 case OPTYPE_OCT2UNICHAR:{
10239 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10240 else return create_stringRepr_predef1("oct2unichar");
10241 }
10242 case OPTYPE_UNICHAR2OCT: {
10243 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10244 else return create_stringRepr_predef1("unichar2oct");
10245 }
10246 case OPTYPE_STR2BIT:
10247 return create_stringRepr_predef1("str2bit");
10248 case OPTYPE_STR2FLOAT:
10249 return create_stringRepr_predef1("str2float");
10250 case OPTYPE_STR2HEX:
10251 return create_stringRepr_predef1("str2hex");
10252 case OPTYPE_STR2INT:
10253 return create_stringRepr_predef1("str2int");
10254 case OPTYPE_STR2OCT:
10255 return create_stringRepr_predef1("str2oct");
10256 case OPTYPE_UNICHAR2INT:
10257 return create_stringRepr_predef1("unichar2int");
10258 case OPTYPE_UNICHAR2CHAR:
10259 return create_stringRepr_predef1("unichar2char");
10260 case OPTYPE_ENUM2INT:
10261 return create_stringRepr_predef1("enum2int");
10262 case OPTYPE_ENCODE:
10263 return create_stringRepr_predef1("encvalue");
10264 case OPTYPE_DECODE:
10265 return create_stringRepr_predef2("decvalue");
10266 case OPTYPE_RNDWITHVAL:
10267 return create_stringRepr_predef1("rnd");
10268 case OPTYPE_ADD:
10269 return create_stringRepr_infix("+");
10270 case OPTYPE_SUBTRACT:
10271 return create_stringRepr_infix("-");
10272 case OPTYPE_MULTIPLY:
10273 return create_stringRepr_infix("*");
10274 case OPTYPE_DIVIDE:
10275 return create_stringRepr_infix("/");
10276 case OPTYPE_MOD:
10277 return create_stringRepr_infix("mod");
10278 case OPTYPE_REM:
10279 return create_stringRepr_infix("rem");
10280 case OPTYPE_CONCAT:
10281 return create_stringRepr_infix("&");
10282 case OPTYPE_EQ:
10283 return create_stringRepr_infix("==");
10284 case OPTYPE_LT:
10285 return create_stringRepr_infix("<");
10286 case OPTYPE_GT:
10287 return create_stringRepr_infix(">");
10288 case OPTYPE_NE:
10289 return create_stringRepr_infix("!=");
10290 case OPTYPE_GE:
10291 return create_stringRepr_infix(">=");
10292 case OPTYPE_LE:
10293 return create_stringRepr_infix("<=");
10294 case OPTYPE_AND:
10295 return create_stringRepr_infix("and");
10296 case OPTYPE_OR:
10297 return create_stringRepr_infix("or");
10298 case OPTYPE_XOR:
10299 return create_stringRepr_infix("xor");
10300 case OPTYPE_AND4B:
10301 return create_stringRepr_infix("and4b");
10302 case OPTYPE_OR4B:
10303 return create_stringRepr_infix("or4b");
10304 case OPTYPE_XOR4B:
10305 return create_stringRepr_infix("xor4b");
10306 case OPTYPE_SHL:
10307 return create_stringRepr_infix("<<");
10308 case OPTYPE_SHR:
10309 return create_stringRepr_infix(">>");
10310 case OPTYPE_ROTL:
10311 return create_stringRepr_infix("<@");
10312 case OPTYPE_ROTR:
10313 return create_stringRepr_infix("@>");
10314 case OPTYPE_INT2BIT:
10315 return create_stringRepr_predef2("int2bit");
10316 case OPTYPE_INT2HEX:
10317 return create_stringRepr_predef2("int2hex");
10318 case OPTYPE_INT2OCT:
10319 return create_stringRepr_predef2("int2oct");
10320 case OPTYPE_SUBSTR: {
10321 string ret_val("substr(");
10322 u.expr.ti1->append_stringRepr(ret_val);
10323 ret_val += ", ";
10324 ret_val += u.expr.v2->get_stringRepr();
10325 ret_val += ", ";
10326 ret_val += u.expr.v3->get_stringRepr();
10327 ret_val += ')';
10328 return ret_val;
10329 }
10330 case OPTYPE_REGEXP: {
10331 string ret_val("regexp(");
10332 u.expr.ti1->append_stringRepr(ret_val);
10333 ret_val += ", ";
10334 u.expr.t2->append_stringRepr(ret_val);
10335 ret_val += ", ";
10336 ret_val += u.expr.v3->get_stringRepr();
10337 ret_val += ')';
10338 return ret_val;
10339 }
10340 case OPTYPE_DECOMP: {
10341 string ret_val("decomp(");
10342 ret_val += u.expr.v1->get_stringRepr();
10343 ret_val += ", ";
10344 ret_val += u.expr.v2->get_stringRepr();
10345 ret_val += ", ";
10346 ret_val += u.expr.v3->get_stringRepr();
10347 ret_val += ')';
10348 return ret_val;
10349 }
10350 case OPTYPE_REPLACE: {
10351 string ret_val("replace(");
10352 u.expr.ti1->append_stringRepr(ret_val);
10353 ret_val += ", ";
10354 ret_val += u.expr.v2->get_stringRepr();
10355 ret_val += ", ";
10356 ret_val += u.expr.v3->get_stringRepr();
10357 ret_val += ", ";
10358 u.expr.ti4->append_stringRepr(ret_val);
10359 ret_val += ')';
10360 return ret_val;
10361 }
10362 case OPTYPE_ISPRESENT: {
10363 string ret_val("ispresent(");
10364 u.expr.ti1->append_stringRepr(ret_val);
10365 ret_val += ')';
10366 return ret_val; }
10367 case OPTYPE_ISCHOSEN: {
10368 string ret_val("ischosen(");
10369 ret_val += u.expr.r1->get_dispname();
10370 ret_val += '.';
10371 ret_val += u.expr.i2->get_dispname();
10372 ret_val += ')';
10373 return ret_val; }
10374 case OPTYPE_ISCHOSEN_V: {
10375 string ret_val("ischosen(");
10376 ret_val += u.expr.v1->get_stringRepr();
10377 ret_val += '.';
10378 ret_val += u.expr.i2->get_dispname();
10379 ret_val += ')';
10380 return ret_val; }
10381 case OPTYPE_ISCHOSEN_T: {
10382 string ret_val("ischosen(");
10383 ret_val += u.expr.t1->get_stringRepr();
10384 ret_val += '.';
10385 ret_val += u.expr.i2->get_dispname();
10386 ret_val += ')';
10387 return ret_val; }
10388 case OPTYPE_LENGTHOF: {
10389 string ret_val("lengthof(");
10390 u.expr.ti1->append_stringRepr(ret_val);
10391 ret_val += ')';
10392 return ret_val; }
10393 case OPTYPE_SIZEOF: {
10394 string ret_val("sizeof(");
10395 u.expr.ti1->append_stringRepr(ret_val);
10396 ret_val += ')';
10397 return ret_val; }
10398 case OPTYPE_ISVALUE: {
10399 string ret_val("isvalue(");
10400 u.expr.ti1->append_stringRepr(ret_val);
10401 ret_val += ')';
10402 return ret_val; }
10403 case OPTYPE_VALUEOF: {
10404 string ret_val("valueof(");
10405 u.expr.ti1->append_stringRepr(ret_val);
10406 ret_val += ')';
10407 return ret_val; }
10408 case OPTYPE_LOG2STR:
10409 return string("log2str(...)");
10410 case OPTYPE_MATCH: {
10411 string ret_val("match(");
10412 ret_val += u.expr.v1->get_stringRepr();
10413 ret_val += ", ";
10414 u.expr.t2->append_stringRepr(ret_val);
10415 ret_val += ')';
10416 return ret_val; }
10417 case OPTYPE_TTCN2STRING: {
10418 string ret_val("ttcn2string(");
10419 u.expr.ti1->append_stringRepr(ret_val);
10420 ret_val += ')';
10421 return ret_val;
10422 }
10423 case OPTYPE_UNDEF_RUNNING:
10424 return u.expr.r1->get_dispname() + ".running";
10425 case OPTYPE_COMP_NULL:
10426 return string("null");
10427 case OPTYPE_COMP_MTC:
10428 return string("mtc");
10429 case OPTYPE_COMP_SYSTEM:
10430 return string("system");
10431 case OPTYPE_COMP_SELF:
10432 return string("self");
10433 case OPTYPE_COMP_CREATE: {
10434 string ret_val(u.expr.r1->get_dispname());
10435 ret_val += ".create";
10436 if (u.expr.v2 || u.expr.v3) {
10437 ret_val += '(';
10438 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10439 else ret_val += '-';
10440 if (u.expr.v3) {
10441 ret_val += ", ";
10442 ret_val += u.expr.v3->get_stringRepr();
10443 }
10444 ret_val += ')';
10445 }
10446 if (u.expr.b4) ret_val += " alive";
10447 return ret_val; }
10448 case OPTYPE_COMP_RUNNING:
10449 return u.expr.v1->get_stringRepr() + ".running";
10450 case OPTYPE_COMP_RUNNING_ANY:
10451 return string("any component.running");
10452 case OPTYPE_COMP_RUNNING_ALL:
10453 return string("all component.running");
10454 case OPTYPE_COMP_ALIVE:
10455 return u.expr.v1->get_stringRepr() + ".alive";
10456 case OPTYPE_COMP_ALIVE_ANY:
10457 return string("any component.alive");
10458 case OPTYPE_COMP_ALIVE_ALL:
10459 return string("all component.alive");
10460 case OPTYPE_TMR_READ:
10461 return u.expr.r1->get_dispname() + ".read";
10462 case OPTYPE_TMR_RUNNING:
10463 return u.expr.r1->get_dispname() + ".running";
10464 case OPTYPE_TMR_RUNNING_ANY:
10465 return string("any timer.running");
10466 case OPTYPE_GETVERDICT:
10467 return string("getverdict");
10468 case OPTYPE_ACTIVATE: {
10469 string ret_val("activate(");
10470 ret_val += u.expr.r1->get_dispname();
10471 ret_val += ')';
10472 return ret_val; }
10473 case OPTYPE_ACTIVATE_REFD: {
10474 string ret_val("activate(derefer(");
10475 ret_val += u.expr.v1->get_stringRepr();
10476 ret_val += ")(";
10477 if (u.expr.state == EXPR_CHECKED) {
10478 if (u.expr.ap_list2) {
10479 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10480 for (size_t i = 0; i < nof_pars; i++) {
10481 if (i > 0) ret_val += ", ";
10482 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10483 }
10484 }
10485 } else {
10486 if (u.expr.t_list2) {
10487 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10488 for (size_t i = 0; i < nof_pars; i++) {
10489 if (i > 0) ret_val += ", ";
10490 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10491 }
10492 }
10493 }
10494 ret_val += "))";
10495 return ret_val; }
10496 case OPTYPE_EXECUTE: {
10497 string ret_val("execute(");
10498 ret_val += u.expr.r1->get_dispname();
10499 if (u.expr.v2) {
10500 ret_val += ", ";
10501 ret_val += u.expr.v2->get_stringRepr();
10502 }
10503 ret_val += ')';
10504 return ret_val; }
10505 case OPTYPE_EXECUTE_REFD: {
10506 string ret_val("execute(derefers(");
10507 ret_val += u.expr.v1->get_stringRepr();
10508 ret_val += ")(";
10509 if (u.expr.state == EXPR_CHECKED) {
10510 if (u.expr.ap_list2) {
10511 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10512 for (size_t i = 0; i < nof_pars; i++) {
10513 if (i > 0) ret_val += ", ";
10514 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10515 }
10516 }
10517 } else {
10518 if (u.expr.t_list2) {
10519 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10520 for (size_t i = 0; i < nof_pars; i++) {
10521 if (i > 0) ret_val += ", ";
10522 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10523 }
10524 }
10525 }
10526 ret_val += ')';
10527 if(u.expr.v3) {
10528 ret_val += ", ";
10529 ret_val += u.expr.v3->get_stringRepr();
10530 }
10531 ret_val += ')';
10532 return ret_val; }
10533 case OPTYPE_PROF_RUNNING:
10534 return string("@profiler.running");
10535 default:
10536 return string("<unsupported optype>");
10537 } // switch u.expr.v_optype
10538 case V_MACRO:
10539 switch (u.macro) {
10540 case MACRO_MODULEID:
10541 return string("%moduleId");
10542 case MACRO_FILENAME:
10543 return string("%fileName");
10544 case MACRO_BFILENAME:
10545 return string("__BFILE__");
10546 case MACRO_FILEPATH:
10547 return string("__FILE__");
10548 case MACRO_LINENUMBER:
10549 return string("%lineNumber");
10550 case MACRO_LINENUMBER_C:
10551 return string("__LINE__");
10552 case MACRO_DEFINITIONID:
10553 return string("%definitionId");
10554 case MACRO_SCOPE:
10555 return string("__SCOPE__");
10556 case MACRO_TESTCASEID:
10557 return string("%testcaseId");
10558 default:
10559 return string("<unknown macro>");
10560 } // switch u.macro
10561 case V_NOTUSED:
10562 return string('-');
10563 case V_FUNCTION:
10564 case V_ALTSTEP:
10565 case V_TESTCASE: {
10566 string ret_val("refers(");
10567 ret_val += u.refd_fat->get_assname();
10568 ret_val += ')';
10569 return ret_val; }
10570 case V_INVOKE: {
10571 string ret_val;
10572 ret_val += u.invoke.v->get_stringRepr();
10573 ret_val += ".apply(";
10574 if (u.invoke.ap_list) {
10575 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10576 for (size_t i = 0; i < nof_pars; i++) {
10577 if (i > 0) ret_val += ", ";
10578 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10579 }
10580 } else if (u.invoke.t_list) {
10581 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10582 for (size_t i = 0; i < nof_pars; i++) {
10583 if (i > 0) ret_val += ", ";
10584 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10585 }
10586 }
10587 ret_val += ')';
10588 return ret_val; }
10589 case V_REFER: {
10590 string ret_val("refers(");
10591 ret_val += u.refered->get_dispname();
10592 ret_val += ')';
10593 return ret_val; }
10594 default:
10595 return string("<unsupported valuetype>");
10596 } // switch valuetype
10597 }
10598
10599 string Value::create_stringRepr_unary(const char *operator_str)
10600 {
10601 string ret_val(operator_str);
10602 ret_val += '(';
10603 ret_val += u.expr.v1->get_stringRepr();
10604 ret_val += ')';
10605 return ret_val;
10606 }
10607
10608 string Value::create_stringRepr_infix(const char *operator_str)
10609 {
10610 string ret_val('(');
10611 ret_val += u.expr.v1->get_stringRepr();
10612 ret_val += ' ';
10613 ret_val += operator_str;
10614 ret_val += ' ';
10615 ret_val += u.expr.v2->get_stringRepr();
10616 ret_val += ')';
10617 return ret_val;
10618 }
10619
10620 string Value::create_stringRepr_predef1(const char *function_name)
10621 {
10622 string ret_val(function_name);
10623 ret_val += '(';
10624 if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
10625 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10626 }
10627 else ret_val += u.expr.v1->get_stringRepr();
10628 ret_val += ')';
10629 return ret_val;
10630 }
10631
10632 string Value::create_stringRepr_predef2(const char *function_name)
10633 {
10634 string ret_val(function_name);
10635 ret_val += '(';
10636 ret_val += u.expr.v1->get_stringRepr();
10637 ret_val += ", ";
10638 ret_val += u.expr.v2->get_stringRepr();
10639 ret_val += ')';
10640 return ret_val;
10641 }
10642
10643 bool Value::operator==(Value& val)
10644 {
10645 Value *left = get_value_refd_last();
10646 Type *left_governor = left->get_my_governor();
10647 if (left_governor) left_governor = left_governor->get_type_refd_last();
10648 Value *right = val.get_value_refd_last();
10649 Type *right_governor = right->get_my_governor();
10650 if (right_governor) right_governor = right_governor->get_type_refd_last();
10651 if (left_governor && right_governor
10652 && !left_governor->is_compatible(right_governor, NULL)
10653 && !right_governor->is_compatible(left_governor, NULL))
10654 FATAL_ERROR("Value::operator==");
10655
10656 // Not-A-Value is not equal to anything (NaN analogy:)
10657 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10658 return false;
10659
10660 switch (left->valuetype) {
10661 case V_NULL:
10662 case V_OMIT:
10663 case V_DEFAULT_NULL:
10664 case V_FAT_NULL:
10665 case V_NOTUSED:
10666 return left->valuetype == right->valuetype;
10667 case V_BOOL:
10668 return right->valuetype == V_BOOL &&
10669 left->get_val_bool() == right->get_val_bool();
10670 case V_INT:
10671 return right->valuetype == V_INT && *left->get_val_Int()
10672 == *right->get_val_Int();
10673 case V_REAL:
10674 return right->valuetype == V_REAL &&
10675 left->get_val_Real() == right->get_val_Real();
10676 case V_CSTR:
10677 switch (right->valuetype) {
10678 case V_CSTR:
10679 return left->get_val_str() == right->get_val_str();
10680 case V_USTR:
10681 return right->get_val_ustr() == left->get_val_str();
10682 case V_ISO2022STR:
10683 return right->get_val_iso2022str() == left->get_val_str();
10684 default:
10685 return false;
10686 }
10687 case V_BSTR:
10688 case V_HSTR:
10689 case V_OSTR:
10690 return left->valuetype == right->valuetype &&
10691 left->get_val_str() == right->get_val_str();
10692 case V_USTR:
10693 switch (right->valuetype) {
10694 case V_CSTR:
10695 return left->get_val_ustr() == right->get_val_str();
10696 case V_USTR:
10697 return left->get_val_ustr() == right->get_val_ustr();
10698 case V_ISO2022STR:
10699 return left->get_val_ustr() == right->get_val_iso2022str();
10700 default:
10701 return false;
10702 }
10703 case V_ISO2022STR:
10704 switch (right->valuetype) {
10705 case V_CSTR:
10706 return left->get_val_iso2022str() == right->get_val_str();
10707 case V_USTR:
10708 // The appropriate operator==() is missing. The operands are swapped,
10709 // but it shouldn't be a problem.
10710 return right->get_val_ustr() == left->get_val_iso2022str();
10711 case V_ISO2022STR:
10712 return left->get_val_iso2022str() == right->get_val_iso2022str();
10713 default:
10714 return false;
10715 }
10716 case V_ENUM:
10717 return right->valuetype == V_ENUM &&
10718 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10719 case V_OID:
10720 case V_ROID:
10721 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10722 vector<string> act, other;
10723 get_oid_comps(act);
10724 val.get_oid_comps(other);
10725 size_t act_size = act.size(), other_size = other.size();
10726 bool ret_val;
10727 if (act_size == other_size) {
10728 ret_val = true;
10729 for (size_t i = 0; i < act_size; i++)
10730 if (*act[i] != *other[i]) {
10731 ret_val = false;
10732 break;
10733 }
10734 } else ret_val = false;
10735 for (size_t i = 0; i < act_size; i++) delete act[i];
10736 act.clear();
10737 for (size_t i = 0; i < other_size; i++) delete other[i];
10738 other.clear();
10739 return ret_val;
10740 } else return false;
10741 case V_CHOICE:
10742 return right->valuetype == V_CHOICE &&
10743 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10744 *(left->get_alt_value()) == *(right->get_alt_value());
10745 case V_SEQ:
10746 case V_SET: {
10747 if (!left_governor) FATAL_ERROR("Value::operator==");
10748 if (left->valuetype != right->valuetype) return false;
10749 size_t nof_comps = left_governor->get_nof_comps();
10750 for (size_t i = 0; i < nof_comps; i++) {
10751 Value *lval = NULL, *rval = NULL;
10752 CompField* cfl = left_governor->get_comp_byIndex(i);
10753 const Identifier& field_name = cfl->get_name();
10754 if (left->has_comp_withName(field_name)) {
10755 lval = left->get_comp_value_byName(field_name);
10756 if (right->has_comp_withName(field_name)) {
10757 rval = right->get_comp_value_byName(field_name);
10758 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10759 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10760 return false;
10761 else if (!(*lval == *rval))
10762 return false;
10763 } else {
10764 if (cfl->has_default()) {
10765 if (!(*lval == *cfl->get_defval()))
10766 return false;
10767 } else {
10768 if (lval->valuetype != V_OMIT)
10769 return false;
10770 }
10771 }
10772 } else {
10773 if(right->has_comp_withName(field_name)) {
10774 rval = right->get_comp_value_byName(field_name);
10775 if(cfl->has_default()) {
10776 if(rval->valuetype==V_OMIT) return false;
10777 else {
10778 lval = cfl->get_defval();
10779 if (!(*lval==*rval)) return false;
10780 }
10781 }
10782 }
10783 }
10784 }
10785 return true; }
10786 case V_SEQOF:
10787 case V_ARRAY: {
10788 if (left->valuetype != right->valuetype) return false;
10789 size_t ncomps = get_nof_comps();
10790 if (ncomps != right->get_nof_comps()) return false;
10791
10792 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
10793 bool found = false;
10794 map<IndexedValue*, void> uncovered;
10795 for (size_t i = 0; i < left->get_nof_comps(); ++i)
10796 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
10797
10798 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
10799 found = false;
10800 for (size_t j = 0; j < uncovered.size(); ++j) {
10801 if (*(uncovered.get_nth_key(j)->get_value()) ==
10802 *(right->get_comp_byIndex(i)) &&
10803 *(uncovered.get_nth_key(j)->get_index()) ==
10804 *(right->get_index_byIndex(i))) {
10805 found = true;
10806 uncovered.erase(uncovered.get_nth_key(j));
10807 break;
10808 }
10809 }
10810 if (!found) break;
10811 }
10812 uncovered.clear();
10813 return found;
10814 } else if (left->is_indexed() || right->is_indexed()) {
10815 Value* indexed_one = 0;
10816 Value* not_indexed_one = 0;
10817
10818 if(left->is_indexed()) { // left is indexed, right is not
10819 indexed_one = left;
10820 not_indexed_one = right;
10821 } else { // right indexed, left is not
10822 indexed_one = right;
10823 not_indexed_one = left;
10824 }
10825
10826 for(size_t i = 0; i < ncomps; ++i) {
10827 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
10828 if(!(ind->valuetype == V_INT &&
10829 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
10830 *(indexed_one->get_comp_byIndex(i))))
10831 { return false; }
10832 }
10833 return true;
10834 } else { // none of them is indexed
10835 for (size_t i = 0; i < ncomps; i++) {
10836 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
10837 return false;
10838 }
10839 return true;
10840 }
10841 }
10842 case V_SETOF: {
10843 if (right->valuetype != V_SETOF) return false;
10844 size_t ncomps = get_nof_comps();
10845 if (ncomps != right->get_nof_comps()) return false;
10846 if (ncomps == 0) return true;
10847 map<size_t, void> uncovered;
10848 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
10849 for (size_t i = 0; i < ncomps; i++) {
10850 Value *left_item = left->get_comp_byIndex(i);
10851 bool pair_found = false;
10852 for (size_t j = 0; j < ncomps - i; j++) {
10853 size_t right_index = uncovered.get_nth_key(j);
10854 if (*left_item == *right->get_comp_byIndex(right_index)) {
10855 uncovered.erase(right_index);
10856 pair_found = true;
10857 break;
10858 }
10859 }
10860 if (!pair_found) {
10861 uncovered.clear();
10862 return false;
10863 }
10864 }
10865 return true; }
10866 case V_VERDICT:
10867 return right->valuetype == V_VERDICT &&
10868 left->get_val_verdict() == right->get_val_verdict();
10869 case V_FUNCTION:
10870 case V_ALTSTEP:
10871 case V_TESTCASE:
10872 return left->valuetype == right->valuetype &&
10873 left->get_refd_assignment() == right->get_refd_assignment();
10874 default:
10875 FATAL_ERROR("Value::operator==");
10876 }
10877 return true;
10878 }
10879
10880 bool Value::operator<(Value& val)
10881 {
10882 Value *left = get_value_refd_last();
10883 Type *left_governor = left->get_my_governor();
10884 if(left_governor) left_governor=left_governor->get_type_refd_last();
10885 Value *right = val.get_value_refd_last();
10886 Type *right_governor = right->get_my_governor();
10887 if(right_governor) right_governor=right_governor->get_type_refd_last();
10888 if (left->get_valuetype() != right->get_valuetype())
10889 FATAL_ERROR("Value::operator<");
10890 switch(valuetype){
10891 case V_INT:
10892 return *left->get_val_Int() < *right->get_val_Int();
10893 case V_REAL:
10894 return (left->get_val_Real() < right->get_val_Real());
10895 case V_ENUM:
10896 if(!left_governor || !right_governor)
10897 FATAL_ERROR("Value::operator<");
10898 if(left_governor!=right_governor)
10899 FATAL_ERROR("Value::operator<");
10900 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
10901 right_governor->get_enum_val_byId(*right->get_val_id()));
10902 default:
10903 FATAL_ERROR("Value::operator<");
10904 }
10905 return true;
10906 }
10907
10908 bool Value::is_string_type(Type::expected_value_t exp_val)
10909 {
10910 switch (get_expr_returntype(exp_val)) {
10911 case Type::T_CSTR:
10912 case Type::T_USTR:
10913 case Type::T_BSTR:
10914 case Type::T_HSTR:
10915 case Type::T_OSTR:
10916 return true;
10917 default:
10918 return false;
10919 }
10920 }
10921
10922 void Value::generate_code_expr(expression_struct *expr)
10923 {
10924 if (has_single_expr()) {
10925 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
10926 } else {
10927 switch (valuetype) {
10928 case V_EXPR:
10929 generate_code_expr_expr(expr);
10930 break;
10931 case V_CHOICE:
10932 case V_SEQOF:
10933 case V_SETOF:
10934 case V_ARRAY:
10935 case V_SEQ:
10936 case V_SET: {
10937 const string& tmp_id = get_temporary_id();
10938 const char *tmp_id_str = tmp_id.c_str();
10939 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
10940 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
10941 set_genname_recursive(tmp_id);
10942 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10943 expr->expr = mputstr(expr->expr, tmp_id_str);
10944 break; }
10945 case V_INT: {
10946 const string& tmp_id = get_temporary_id();
10947 const char *tmp_id_str = tmp_id.c_str();
10948 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
10949 tmp_id_str);
10950 set_genname_recursive(tmp_id);
10951 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10952 expr->expr = mputstr(expr->expr, tmp_id_str);
10953 break; }
10954 case V_REFD: {
10955 if (!get_needs_conversion()) {
10956 u.ref.ref->generate_code_const_ref(expr);
10957 } else {
10958 Type *my_gov = get_expr_governor_last();
10959 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
10960 ->get_field_type(u.ref.ref->get_subrefs(),
10961 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
10962 // Make sure that nothing goes wrong.
10963 if (!my_gov || !refd_gov || my_gov == refd_gov)
10964 FATAL_ERROR("Value::generate_code_expr()");
10965 expression_struct expr_tmp;
10966 Code::init_expr(&expr_tmp);
10967 const string& tmp_id1 = get_temporary_id();
10968 const char *tmp_id_str1 = tmp_id1.c_str();
10969 const string& tmp_id2 = get_temporary_id();
10970 const char *tmp_id_str2 = tmp_id2.c_str();
10971 expr->preamble = mputprintf(expr->preamble,
10972 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
10973 tmp_id_str1);
10974 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
10975 u.ref.ref->generate_code_const_ref(&expr_tmp);
10976 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
10977 expr->preamble = mputprintf(expr->preamble,
10978 "%s %s;\n"
10979 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
10980 "and `%s' are not compatible at run-time\");\n",
10981 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
10982 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
10983 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
10984 ->get_typename().c_str(), refd_gov->get_typename().c_str());
10985 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
10986 }
10987 break; }
10988 case V_INVOKE:
10989 generate_code_expr_invoke(expr);
10990 break;
10991 default:
10992 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
10993 }
10994 }
10995 }
10996
10997 void Value::generate_code_expr_mandatory(expression_struct *expr)
10998 {
10999 generate_code_expr(expr);
11000 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11001 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11002 }
11003
11004 bool Value::can_use_increment(Reference *ref) const
11005 {
11006 if (valuetype != V_EXPR) {
11007 return false;
11008 }
11009 switch (u.expr.v_optype) {
11010 case OPTYPE_ADD:
11011 case OPTYPE_SUBTRACT:
11012 break;
11013 default:
11014 return false;
11015 }
11016 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11017 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11018 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11019 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11020 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11021 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11022 return true;
11023 }
11024 return false;
11025 }
11026
11027 char *Value::generate_code_init(char *str, const char *name)
11028 {
11029 if (get_code_generated()) return str;
11030 if (err_descr) {
11031 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11032 }
11033 switch (valuetype) {
11034 case V_NULL:
11035 case V_BOOL:
11036 case V_REAL:
11037 case V_ENUM:
11038 case V_BSTR:
11039 case V_HSTR:
11040 case V_OSTR:
11041 case V_CSTR:
11042 case V_USTR:
11043 case V_ISO2022STR:
11044 case V_OID:
11045 case V_ROID:
11046 case V_VERDICT:
11047 case V_DEFAULT_NULL:
11048 case V_FAT_NULL:
11049 case V_FUNCTION:
11050 case V_ALTSTEP:
11051 case V_TESTCASE:
11052 // These values have a single string equivalent.
11053 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11054 break;
11055 case V_INT:
11056 if (u.val_Int->is_native_fit())
11057 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11058 else
11059 // It's always an INTEGER.
11060 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11061 "}\n", get_single_expr().c_str(), name);
11062 break;
11063 case V_EXPR:
11064 case V_INVOKE: {
11065 expression_struct expr;
11066 Code::init_expr(&expr);
11067 expr.expr = mputprintf(expr.expr, "%s = ", name);
11068 generate_code_expr(&expr);
11069 str = Code::merge_free_expr(str, &expr);
11070 break; }
11071 case V_CHOICE:
11072 str = generate_code_init_choice(str, name);
11073 break;
11074 case V_SEQOF:
11075 case V_SETOF:
11076 if (!is_indexed()) str = generate_code_init_seof(str, name);
11077 else str = generate_code_init_indexed(str, name);
11078 break;
11079 case V_ARRAY:
11080 if (!is_indexed()) str = generate_code_init_array(str, name);
11081 else str = generate_code_init_indexed(str, name);
11082 break;
11083 case V_SEQ:
11084 case V_SET:
11085 str = generate_code_init_se(str, name);
11086 break;
11087 case V_REFD:
11088 str = generate_code_init_refd(str, name);
11089 break;
11090 case V_MACRO:
11091 switch (u.macro) {
11092 case MACRO_TESTCASEID:
11093 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11094 break;
11095 default:
11096 // all others must already be evaluated away
11097 FATAL_ERROR("Value::generate_code_init()");
11098 }
11099 break;
11100 default:
11101 FATAL_ERROR("Value::generate_code_init()");
11102 }
11103 if (err_descr) {
11104 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11105 }
11106 set_code_generated();
11107 return str;
11108 }
11109
11110 char *Value::rearrange_init_code(char *str)
11111 {
11112 switch (valuetype) {
11113 case V_REFD: {
11114 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11115 if (parlist) {
11116 str = parlist->rearrange_init_code(str,
11117 u.ref.ref->get_refd_assignment()->get_my_scope()->get_scope_mod_gen());
11118 }
11119 break; }
11120 case V_INVOKE: {
11121 str = u.invoke.v->rearrange_init_code(str);
11122 str = u.invoke.ap_list->rearrange_init_code(str,
11123 u.invoke.v->get_expr_governor_last()->get_my_scope()->get_scope_mod_gen());
11124 break; }
11125 case V_EXPR:
11126 switch (u.expr.v_optype) {
11127 case OPTYPE_UNARYPLUS:
11128 case OPTYPE_UNARYMINUS:
11129 case OPTYPE_NOT:
11130 case OPTYPE_NOT4B:
11131 case OPTYPE_BIT2HEX:
11132 case OPTYPE_BIT2INT:
11133 case OPTYPE_BIT2OCT:
11134 case OPTYPE_BIT2STR:
11135 case OPTYPE_CHAR2INT:
11136 case OPTYPE_CHAR2OCT:
11137 case OPTYPE_FLOAT2INT:
11138 case OPTYPE_FLOAT2STR:
11139 case OPTYPE_HEX2BIT:
11140 case OPTYPE_HEX2INT:
11141 case OPTYPE_HEX2OCT:
11142 case OPTYPE_HEX2STR:
11143 case OPTYPE_INT2CHAR:
11144 case OPTYPE_INT2FLOAT:
11145 case OPTYPE_INT2STR:
11146 case OPTYPE_INT2UNICHAR:
11147 case OPTYPE_OCT2BIT:
11148 case OPTYPE_OCT2CHAR:
11149 case OPTYPE_OCT2HEX:
11150 case OPTYPE_OCT2INT:
11151 case OPTYPE_OCT2STR:
11152 case OPTYPE_STR2BIT:
11153 case OPTYPE_STR2FLOAT:
11154 case OPTYPE_STR2HEX:
11155 case OPTYPE_STR2INT:
11156 case OPTYPE_STR2OCT:
11157 case OPTYPE_UNICHAR2INT:
11158 case OPTYPE_UNICHAR2CHAR:
11159 case OPTYPE_ENUM2INT:
11160 case OPTYPE_ISCHOSEN_V:
11161 case OPTYPE_GET_STRINGENCODING:
11162 case OPTYPE_REMOVE_BOM:
11163 case OPTYPE_DECODE_BASE64:
11164 str = u.expr.v1->rearrange_init_code(str);
11165 break;
11166 case OPTYPE_DECODE: {
11167 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11168 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11169 if (parlist) str = parlist->rearrange_init_code(str, ass->get_my_scope()->get_scope_mod_gen());
11170
11171 parlist = u.expr.r2->get_parlist();
11172 ass = u.expr.r2->get_refd_assignment();
11173 if (parlist) str = parlist->rearrange_init_code(str, ass->get_my_scope()->get_scope_mod_gen());
11174 break; }
11175 case OPTYPE_ADD:
11176 case OPTYPE_SUBTRACT:
11177 case OPTYPE_MULTIPLY:
11178 case OPTYPE_DIVIDE:
11179 case OPTYPE_MOD:
11180 case OPTYPE_REM:
11181 case OPTYPE_CONCAT:
11182 case OPTYPE_EQ:
11183 case OPTYPE_LT:
11184 case OPTYPE_GT:
11185 case OPTYPE_NE:
11186 case OPTYPE_GE:
11187 case OPTYPE_LE:
11188 case OPTYPE_AND:
11189 case OPTYPE_OR:
11190 case OPTYPE_XOR:
11191 case OPTYPE_AND4B:
11192 case OPTYPE_OR4B:
11193 case OPTYPE_XOR4B:
11194 case OPTYPE_SHL:
11195 case OPTYPE_SHR:
11196 case OPTYPE_ROTL:
11197 case OPTYPE_ROTR:
11198 case OPTYPE_INT2BIT:
11199 case OPTYPE_INT2HEX:
11200 case OPTYPE_INT2OCT:
11201 //case OPTYPE_DECODE:
11202 str = u.expr.v1->rearrange_init_code(str);
11203 str = u.expr.v2->rearrange_init_code(str);
11204 break;
11205 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11206 case OPTYPE_OCT2UNICHAR:
11207 case OPTYPE_ENCODE_BASE64:
11208 str = u.expr.v1->rearrange_init_code(str);
11209 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str);
11210 break;
11211 case OPTYPE_SUBSTR:
11212 str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11213 str = u.expr.v2->rearrange_init_code(str);
11214 str = u.expr.v3->rearrange_init_code(str);
11215 break;
11216 case OPTYPE_REGEXP:
11217 str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11218 str = u.expr.t2->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11219 str = u.expr.v3->rearrange_init_code(str);
11220 break;
11221 case OPTYPE_DECOMP:
11222 str = u.expr.v1->rearrange_init_code(str);
11223 str = u.expr.v2->rearrange_init_code(str);
11224 str = u.expr.v3->rearrange_init_code(str);
11225 break;
11226 case OPTYPE_REPLACE:
11227 str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11228 str = u.expr.v2->rearrange_init_code(str);
11229 str = u.expr.v3->rearrange_init_code(str);
11230 str = u.expr.ti4->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11231 break;
11232 case OPTYPE_LENGTHOF:
11233 case OPTYPE_SIZEOF:
11234 case OPTYPE_VALUEOF:
11235 case OPTYPE_ENCODE:
11236 case OPTYPE_ISPRESENT:
11237 case OPTYPE_TTCN2STRING:
11238 str = u.expr.ti1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11239 break;
11240 case OPTYPE_ISCHOSEN_T:
11241 str = u.expr.t1->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11242 break;
11243 case OPTYPE_MATCH:
11244 str = u.expr.v1->rearrange_init_code(str);
11245 str = u.expr.t2->rearrange_init_code(str, my_scope->get_scope_mod_gen());
11246 break;
11247 default:
11248 // other kinds of expressions cannot appear within templates
11249 break;
11250 }
11251 break;
11252 default:
11253 break;
11254 }
11255 return str;
11256 }
11257
11258 char* Value::generate_code_tmp(char *str, const char *prefix,
11259 size_t& blockcount)
11260 {
11261 char *s2 = memptystr();
11262 char *s1 = generate_code_tmp(NULL, s2);
11263 if (s2[0]) {
11264 if (blockcount == 0) {
11265 str = mputstr(str, "{\n");
11266 blockcount++;
11267 }
11268 str = mputstr(str, s2);
11269 }
11270 Free(s2);
11271 str=mputstr(str, prefix);
11272 str=mputstr(str, s1);
11273 Free(s1);
11274 return str;
11275 }
11276
11277 char *Value::generate_code_tmp(char *str, char*& init)
11278 {
11279 expression_struct expr;
11280 Code::init_expr(&expr);
11281 generate_code_expr_mandatory(&expr);
11282 if (expr.preamble || expr.postamble) {
11283 if (valuetype == V_EXPR &&
11284 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11285 // a temporary variable is already introduced
11286 if (expr.preamble) init = mputstr(init, expr.preamble);
11287 if (expr.postamble) init = mputstr(init, expr.postamble);
11288 str = mputstr(str, expr.expr);
11289 } else {
11290 const string& tmp_id = get_temporary_id();
11291 const char *tmp_id_str = tmp_id.c_str();
11292 init = mputprintf(init, "%s %s;\n"
11293 "{\n",
11294 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11295 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11296 tmp_id_str);
11297 if (expr.preamble) init = mputstr(init, expr.preamble);
11298 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11299 if (expr.postamble) init = mputstr(init, expr.postamble);
11300 init = mputstr(init, "}\n");
11301 str = mputstr(str, tmp_id_str);
11302 }
11303 } else str = mputstr(str, expr.expr);
11304 Code::free_expr(&expr);
11305 return str;
11306 }
11307
11308 void Value::generate_code_log(expression_struct *expr)
11309 {
11310 if (explicit_cast_needed()) {
11311 char *expr_backup = expr->expr;
11312 expr->expr = NULL;
11313 generate_code_expr(expr);
11314 const string& tmp_id = get_temporary_id();
11315 const char *tmp_id_str = tmp_id.c_str();
11316 // We have to create a temporary object, because the parser of GCC
11317 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11318 // constructor call that is, this does not work: type(...).log(); but
11319 // this works: type tmp(...); tmp.log();.
11320 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11321 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11322 expr->expr);
11323 Free(expr->expr);
11324 expr->expr = mputstr(expr_backup, tmp_id_str);
11325 } else {
11326 generate_code_expr(expr);
11327 }
11328 expr->expr = mputstr(expr->expr, ".log()");
11329 }
11330
11331 void Value::generate_code_log_match(expression_struct *expr)
11332 {
11333 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11334 FATAL_ERROR("Value::generate_code_log_match()");
11335 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11336 // compliance the whole code-generation should be checked. Standalone
11337 // constructs like: "A(a[0].f());" should be avoided. The current
11338 // solution for HK38721 uses an additional assignment to overcome the
11339 // issue. The generated code will be slower, but it's needed for old GCC
11340 // versions in specific circumstances.
11341 if (u.expr.t2->needs_temp_ref()) {
11342 char *expr_backup = expr->expr;
11343 expr->expr = NULL;
11344 u.expr.t2->generate_code(expr);
11345 const string& tmp_id = get_temporary_id();
11346 const char *tmp_id_str = tmp_id.c_str();
11347 expr->preamble = mputprintf(expr->preamble,
11348 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11349 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11350 Free(expr->expr);
11351 expr->expr = mputstr(expr_backup, tmp_id_str);
11352 } else {
11353 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11354 // some reason "(A(NS::B)).a(C);" compiles fine.
11355 expr->expr = mputc(expr->expr, '(');
11356 u.expr.t2->generate_code(expr);
11357 expr->expr = mputc(expr->expr, ')');
11358 }
11359 expr->expr = mputstr(expr->expr, ".log_match(");
11360 u.expr.v1->generate_code_expr(expr);
11361 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11362 }
11363
11364 void Value::generate_code_expr_expr(expression_struct *expr)
11365 {
11366 switch (u.expr.v_optype) {
11367 case OPTYPE_RND:
11368 generate_code_expr_rnd(expr, 0);
11369 break;
11370 case OPTYPE_UNARYPLUS:
11371 // same as without the '+' operator
11372 u.expr.v1->generate_code_expr(expr);
11373 break;
11374 case OPTYPE_UNARYMINUS:
11375 generate_code_expr_unary(expr, "-", u.expr.v1);
11376 break;
11377 case OPTYPE_NOT:
11378 generate_code_expr_unary(expr, "!", u.expr.v1);
11379 break;
11380 case OPTYPE_NOT4B:
11381 generate_code_expr_unary(expr, "~", u.expr.v1);
11382 break;
11383 case OPTYPE_BIT2HEX:
11384 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11385 break;
11386 case OPTYPE_BIT2INT:
11387 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11388 break;
11389 case OPTYPE_BIT2OCT:
11390 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11391 break;
11392 case OPTYPE_BIT2STR:
11393 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11394 break;
11395 case OPTYPE_CHAR2INT:
11396 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11397 break;
11398 case OPTYPE_CHAR2OCT:
11399 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11400 break;
11401 case OPTYPE_FLOAT2INT:
11402 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11403 break;
11404 case OPTYPE_FLOAT2STR:
11405 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11406 break;
11407 case OPTYPE_HEX2BIT:
11408 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11409 break;
11410 case OPTYPE_HEX2INT:
11411 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11412 break;
11413 case OPTYPE_HEX2OCT:
11414 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11415 break;
11416 case OPTYPE_HEX2STR:
11417 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11418 break;
11419 case OPTYPE_INT2CHAR:
11420 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11421 break;
11422 case OPTYPE_INT2FLOAT:
11423 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11424 break;
11425 case OPTYPE_INT2STR:
11426 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11427 break;
11428 case OPTYPE_INT2UNICHAR:
11429 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11430 break;
11431 case OPTYPE_OCT2BIT:
11432 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11433 break;
11434 case OPTYPE_OCT2CHAR:
11435 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11436 break;
11437 case OPTYPE_GET_STRINGENCODING:
11438 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11439 break;
11440 case OPTYPE_REMOVE_BOM:
11441 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11442 break;
11443 case OPTYPE_ENCODE_BASE64:
11444 if (u.expr.v2)
11445 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11446 else
11447 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11448 break;
11449 case OPTYPE_DECODE_BASE64:
11450 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11451 break;
11452 case OPTYPE_OCT2UNICHAR:
11453 if (u.expr.v2)
11454 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11455 else
11456 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11457 break;
11458 case OPTYPE_UNICHAR2OCT:
11459 if (u.expr.v2)
11460 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11461 else
11462 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11463 break;
11464 case OPTYPE_OCT2HEX:
11465 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11466 break;
11467 case OPTYPE_OCT2INT:
11468 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11469 break;
11470 case OPTYPE_OCT2STR:
11471 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11472 break;
11473 case OPTYPE_STR2BIT:
11474 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11475 break;
11476 case OPTYPE_STR2FLOAT:
11477 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11478 break;
11479 case OPTYPE_STR2HEX:
11480 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11481 break;
11482 case OPTYPE_STR2INT:
11483 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11484 break;
11485 case OPTYPE_STR2OCT:
11486 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11487 break;
11488 case OPTYPE_UNICHAR2INT:
11489 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11490 break;
11491 case OPTYPE_UNICHAR2CHAR:
11492 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11493 break;
11494 case OPTYPE_ENUM2INT: {
11495 Type* enum_type = u.expr.v1->get_expr_governor_last();
11496 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11497 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11498 enum_type->get_genname_value(my_scope).c_str());
11499 u.expr.v1->generate_code_expr_mandatory(expr);
11500 expr->expr = mputc(expr->expr, ')');
11501 break;}
11502 case OPTYPE_ENCODE:
11503 generate_code_expr_encode(expr);
11504 break;
11505 case OPTYPE_DECODE:
11506 generate_code_expr_decode(expr);
11507 break;
11508 case OPTYPE_RNDWITHVAL:
11509 generate_code_expr_rnd(expr, u.expr.v1);
11510 break;
11511 case OPTYPE_ADD:
11512 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11513 break;
11514 case OPTYPE_SUBTRACT:
11515 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11516 break;
11517 case OPTYPE_MULTIPLY:
11518 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11519 break;
11520 case OPTYPE_DIVIDE:
11521 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11522 break;
11523 case OPTYPE_MOD:
11524 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11525 break;
11526 case OPTYPE_REM:
11527 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11528 break;
11529 case OPTYPE_CONCAT:
11530 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11531 break;
11532 case OPTYPE_EQ:
11533 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11534 break;
11535 case OPTYPE_LT:
11536 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11537 break;
11538 case OPTYPE_GT:
11539 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11540 break;
11541 case OPTYPE_NE:
11542 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11543 break;
11544 case OPTYPE_GE:
11545 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11546 break;
11547 case OPTYPE_LE:
11548 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11549 break;
11550 case OPTYPE_AND:
11551 case OPTYPE_OR:
11552 generate_code_expr_and_or(expr);
11553 break;
11554 case OPTYPE_XOR:
11555 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11556 break;
11557 case OPTYPE_AND4B:
11558 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11559 break;
11560 case OPTYPE_OR4B:
11561 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11562 break;
11563 case OPTYPE_XOR4B:
11564 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11565 break;
11566 case OPTYPE_SHL:
11567 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11568 break;
11569 case OPTYPE_SHR:
11570 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11571 break;
11572 case OPTYPE_ROTL:
11573 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11574 break;
11575 case OPTYPE_ROTR:
11576 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11577 break;
11578 case OPTYPE_INT2BIT:
11579 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11580 break;
11581 case OPTYPE_INT2HEX:
11582 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11583 break;
11584 case OPTYPE_INT2OCT:
11585 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11586 break;
11587 case OPTYPE_SUBSTR:
11588 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11589 else generate_code_expr_substr_replace_compat(expr);
11590 break;
11591 case OPTYPE_REGEXP:
11592 generate_code_expr_regexp(expr);
11593 break;
11594 case OPTYPE_DECOMP:
11595 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11596 break;
11597 case OPTYPE_REPLACE:
11598 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11599 else generate_code_expr_substr_replace_compat(expr);
11600 break;
11601 case OPTYPE_ISCHOSEN: // r1 i2
11602 FATAL_ERROR("Value::generate_code_expr_expr()");
11603 break;
11604 case OPTYPE_ISCHOSEN_V: // v1 i2
11605 u.expr.v1->generate_code_expr_mandatory(expr);
11606 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11607 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11608 u.expr.i2->get_name().c_str());
11609 break;
11610 case OPTYPE_ISCHOSEN_T: // t1 i2
11611 u.expr.t1->generate_code_expr(expr);
11612 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11613 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11614 u.expr.i2->get_name().c_str());
11615 break;
11616 case OPTYPE_ISPRESENT:
11617 case OPTYPE_ISBOUND: {
11618 Template::templatetype_t temp = u.expr.ti1->get_Template()
11619 ->get_templatetype();
11620 if (temp == Template::SPECIFIC_VALUE) {
11621 Value* specific_value = u.expr.ti1->get_Template()
11622 ->get_specific_value();
11623 if (specific_value->get_valuetype() == Value::V_REFD) {
11624 Ttcn::Reference* reference =
11625 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11626 if (reference) {
11627 reference->generate_code_ispresentbound(expr, false,
11628 u.expr.v_optype==OPTYPE_ISBOUND);
11629 break;
11630 }
11631 }
11632 } else if (temp == Template::TEMPLATE_REFD){
11633 Ttcn::Reference* reference =
11634 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11635 ->get_reference());
11636 if (reference) {
11637 reference->generate_code_ispresentbound(expr, true,
11638 u.expr.v_optype==OPTYPE_ISBOUND);
11639 break;
11640 }
11641 }
11642 }
11643 // no break
11644 case OPTYPE_LENGTHOF: // ti1
11645 // fall through, separated later
11646 case OPTYPE_SIZEOF: // ti1
11647 // fall through, separated later
11648 case OPTYPE_ISVALUE: { // ti1
11649 if (u.expr.ti1->is_only_specific_value()) {
11650 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11651 bool cast_needed = t_val->explicit_cast_needed(
11652 u.expr.v_optype != OPTYPE_LENGTHOF);
11653 if(cast_needed) {
11654 // the ambiguous C++ expression is converted to the value class
11655 expr->expr = mputprintf(expr->expr, "%s(",
11656 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11657 }
11658
11659 if (u.expr.v_optype != OPTYPE_LENGTHOF
11660 && u.expr.v_optype != OPTYPE_SIZEOF) {
11661 t_val->generate_code_expr(expr);
11662 } else {
11663 t_val->generate_code_expr_mandatory(expr);
11664 }
11665
11666 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11667 }
11668 else u.expr.ti1->generate_code(expr);
11669
11670 switch (u.expr.v_optype) {
11671 case OPTYPE_ISBOUND:
11672 expr->expr=mputstr(expr->expr, ".is_bound()");
11673 break;
11674 case OPTYPE_ISPRESENT:
11675 expr->expr=mputprintf(expr->expr, ".is_present(%s)",
11676 omit_in_value_list ? "TRUE" : "");
11677 break;
11678 case OPTYPE_SIZEOF:
11679 expr->expr=mputstr(expr->expr, ".size_of()");
11680 break;
11681 case OPTYPE_LENGTHOF:
11682 expr->expr=mputstr(expr->expr, ".lengthof()");
11683 break;
11684 case OPTYPE_ISVALUE:
11685 expr->expr=mputstr(expr->expr, ".is_value()");
11686 break;
11687 default:
11688 FATAL_ERROR("Value::generate_code_expr_expr()");
11689 }
11690 break; }
11691 case OPTYPE_VALUEOF: // ti1
11692 u.expr.ti1->generate_code(expr);
11693 expr->expr = mputstr(expr->expr, ".valueof()");
11694 break;
11695 case OPTYPE_MATCH: // v1 t2
11696 u.expr.t2->generate_code(expr);
11697 expr->expr = mputstr(expr->expr, ".match(");
11698 u.expr.v1->generate_code_expr(expr);
11699 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11700 break;
11701 case OPTYPE_UNDEF_RUNNING:
11702 // it is resolved during semantic check
11703 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11704 break;
11705 case OPTYPE_COMP_NULL: // -
11706 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11707 break;
11708 case OPTYPE_COMP_MTC: // -
11709 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11710 break;
11711 case OPTYPE_COMP_SYSTEM: // -
11712 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11713 break;
11714 case OPTYPE_COMP_SELF: // -
11715 expr->expr=mputstr(expr->expr, "self");
11716 break;
11717 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11718 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11719 u.expr.b4);
11720 break;
11721 case OPTYPE_COMP_RUNNING: // v1
11722 u.expr.v1->generate_code_expr(expr);
11723 if(u.expr.v1->get_valuetype() == V_REFD)
11724 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11725 expr->expr = mputstr(expr->expr, ".running()");
11726 break;
11727 case OPTYPE_COMP_RUNNING_ANY: // -
11728 expr->expr=mputstr(expr->expr,
11729 "TTCN_Runtime::component_running(ANY_COMPREF)");
11730 break;
11731 case OPTYPE_COMP_RUNNING_ALL: // -
11732 expr->expr=mputstr(expr->expr,
11733 "TTCN_Runtime::component_running(ALL_COMPREF)");
11734 break;
11735 case OPTYPE_COMP_ALIVE: // v1
11736 u.expr.v1->generate_code_expr(expr);
11737 if(u.expr.v1->get_valuetype() == V_REFD)
11738 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11739 expr->expr = mputstr(expr->expr, ".alive()");
11740 break;
11741 case OPTYPE_COMP_ALIVE_ANY: // -
11742 expr->expr = mputstr(expr->expr,
11743 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11744 break;
11745 case OPTYPE_COMP_ALIVE_ALL: // -
11746 expr->expr = mputstr(expr->expr,
11747 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11748 break;
11749 case OPTYPE_TMR_READ: // r1
11750 u.expr.r1->generate_code(expr);
11751 expr->expr = mputstr(expr->expr, ".read()");
11752 break;
11753 case OPTYPE_TMR_RUNNING: // r1
11754 u.expr.r1->generate_code(expr);
11755 expr->expr = mputstr(expr->expr, ".running()");
11756 break;
11757 case OPTYPE_TMR_RUNNING_ANY: // -
11758 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11759 break;
11760 case OPTYPE_GETVERDICT: // -
11761 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11762 break;
11763 case OPTYPE_TESTCASENAME: // -
11764 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11765 break;
11766 case OPTYPE_ACTIVATE: // r1
11767 generate_code_expr_activate(expr);
11768 break;
11769 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
11770 generate_code_expr_activate_refd(expr);
11771 break;
11772 case OPTYPE_EXECUTE: // r1 [v2]
11773 generate_code_expr_execute(expr);
11774 break;
11775 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
11776 generate_code_expr_execute_refd(expr);
11777 break;
11778 case OPTYPE_LOG2STR:
11779 u.expr.logargs->generate_code_expr(expr);
11780 break;
11781 case OPTYPE_TTCN2STRING: {
11782 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
11783 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
11784 param_governor = param_governor->get_type_refd_last();
11785 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
11786 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
11787 u.expr.ti1->get_Template()->is_Value()) {
11788 Value* v = u.expr.ti1->get_Template()->get_Value();
11789 delete u.expr.ti1;
11790 u.expr.ti1 = NULL;
11791 bool cast_needed = v->explicit_cast_needed();
11792 if (cast_needed) {
11793 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
11794 }
11795 v->generate_code_expr(expr);
11796 if (cast_needed) {
11797 expr->expr = mputstr(expr->expr, ")");
11798 }
11799 delete v;
11800 } else {
11801 u.expr.ti1->generate_code(expr);
11802 }
11803 expr->expr = mputstr(expr->expr, ")");
11804 } break;
11805 case OPTYPE_PROF_RUNNING:
11806 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
11807 break;
11808 default:
11809 FATAL_ERROR("Value::generate_code_expr_expr()");
11810 }
11811 }
11812
11813 void Value::generate_code_expr_unary(expression_struct *expr,
11814 const char *operator_str, Value *v1)
11815 {
11816 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
11817 v1->generate_code_expr_mandatory(expr);
11818 expr->expr = mputstrn(expr->expr, "))", 2);
11819 }
11820
11821 void Value::generate_code_expr_infix(expression_struct *expr,
11822 const char *operator_str, Value *v1,
11823 Value *v2, bool optional_allowed)
11824 {
11825 if (!get_needs_conversion()) {
11826 expr->expr = mputc(expr->expr, '(');
11827 if (optional_allowed) v1->generate_code_expr(expr);
11828 else v1->generate_code_expr_mandatory(expr);
11829 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
11830 if (optional_allowed) v2->generate_code_expr(expr);
11831 else v2->generate_code_expr_mandatory(expr);
11832 expr->expr = mputc(expr->expr, ')');
11833 } else { // Temporary variable for the converted value.
11834 const string& tmp_id1 = get_temporary_id();
11835 const char *tmp_id_str1 = tmp_id1.c_str();
11836 expression_struct expr_tmp;
11837 Code::init_expr(&expr_tmp);
11838 switch (u.expr.v_optype) {
11839 case OPTYPE_EQ:
11840 case OPTYPE_NE: {
11841 // Always "v1 -> v2".
11842 Type *t1 = v1->get_expr_governor_last();
11843 Type *t2 = v2->get_expr_governor_last();
11844 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
11845 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11846 else v2->generate_code_expr_mandatory(&expr_tmp);
11847 if (expr_tmp.preamble)
11848 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11849 expr->preamble = mputprintf(expr->preamble,
11850 "%s %s;\n"
11851 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11852 "and `%s' are not compatible at run-time\");\n",
11853 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
11854 TypeConv::get_conv_func(t2, t1, get_my_scope()
11855 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
11856 t2->get_typename().c_str(), t1->get_typename().c_str());
11857 Code::free_expr(&expr_tmp);
11858 if (optional_allowed) v1->generate_code_expr(expr);
11859 else v1->generate_code_expr_mandatory(expr);
11860 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
11861 tmp_id_str1);
11862 break; }
11863 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11864 // functions. The governors of all operands must exist at this point.
11865 case OPTYPE_ROTL:
11866 case OPTYPE_ROTR:
11867 case OPTYPE_CONCAT: {
11868 const string& tmp_id2 = get_temporary_id();
11869 const char *tmp_id_str2 = tmp_id2.c_str();
11870 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
11871 Type *my_gov = my_governor->get_type_refd_last();
11872 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
11873 ->get_type_refd_last();
11874 if (!t1_gov || my_gov == t1_gov)
11875 FATAL_ERROR("Value::generate_code_expr_infix()");
11876 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11877 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
11878 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11879 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
11880 else v1->generate_code_expr_mandatory(&expr_tmp);
11881 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
11882 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11883 else v2->generate_code_expr_mandatory(&expr_tmp);
11884 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11885 expr->preamble = mputprintf(expr->preamble,
11886 "%s %s;\n"
11887 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11888 "and `%s' are not compatible at run-time\");\n",
11889 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11890 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
11891 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
11892 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
11893 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11894 break; }
11895 default:
11896 FATAL_ERROR("Value::generate_code_expr_infix()");
11897 break;
11898 }
11899 }
11900 }
11901
11902 void Value::generate_code_expr_and_or(expression_struct *expr)
11903 {
11904 if (u.expr.v2->needs_short_circuit()) {
11905 // introduce a temporary variable to store the result of the operation
11906 const string& tmp_id = get_temporary_id();
11907 const char *tmp_id_str = tmp_id.c_str();
11908 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
11909 expression_struct expr2;
11910 // the left operand must be evaluated anyway
11911 Code::init_expr(&expr2);
11912 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11913 u.expr.v1->generate_code_expr_mandatory(&expr2);
11914 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11915 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
11916 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
11917 // evaluate the right operand only when necessary
11918 // in this case the final result will be the right operand
11919 Code::init_expr(&expr2);
11920 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11921 u.expr.v2->generate_code_expr_mandatory(&expr2);
11922 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11923 // the result is now in the temporary variable
11924 expr->expr = mputstr(expr->expr, tmp_id_str);
11925 } else {
11926 // use the overloaded operator to get better error messages
11927 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
11928 "&&" : "||", u.expr.v1, u.expr.v2, false);
11929 }
11930 }
11931
11932 void Value::generate_code_expr_predef1(expression_struct *expr,
11933 const char *function_name,
11934 Value *v1)
11935 {
11936 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11937 v1->generate_code_expr_mandatory(expr);
11938 expr->expr = mputc(expr->expr, ')');
11939 }
11940
11941 void Value::generate_code_expr_predef2(expression_struct *expr,
11942 const char *function_name,
11943 Value *v1, Value *v2)
11944 {
11945 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11946 v1->generate_code_expr_mandatory(expr);
11947 expr->expr = mputstr(expr->expr, ", ");
11948 v2->generate_code_expr_mandatory(expr);
11949 expr->expr = mputc(expr->expr, ')');
11950 }
11951
11952 void Value::generate_code_expr_predef3(expression_struct *expr,
11953 const char *function_name,
11954 Value *v1, Value *v2, Value *v3)
11955 {
11956 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11957 v1->generate_code_expr_mandatory(expr);
11958 expr->expr = mputstr(expr->expr, ", ");
11959 v2->generate_code_expr_mandatory(expr);
11960 expr->expr = mputstr(expr->expr, ", ");
11961 v3->generate_code_expr_mandatory(expr);
11962 expr->expr = mputc(expr->expr, ')');
11963 }
11964
11965 void Value::generate_code_expr_substr(expression_struct *expr)
11966 {
11967 bool par1_is_str;
11968 Value* v1 = u.expr.ti1->get_specific_value();
11969 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
11970 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
11971 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
11972 if (v1) v1->generate_code_expr_mandatory(expr);
11973 else u.expr.ti1->generate_code(expr);
11974 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
11975 else expr->expr = mputstr(expr->expr, ".substr(");
11976 if (!par1_is_str && u.expr.v2->is_unfoldable())
11977 expr->expr = mputstr(expr->expr, "(int)");
11978 u.expr.v2->generate_code_expr_mandatory(expr);
11979 expr->expr = mputstr(expr->expr, ", ");
11980 if (!par1_is_str && u.expr.v3->is_unfoldable())
11981 expr->expr = mputstr(expr->expr, "(int)");
11982 u.expr.v3->generate_code_expr_mandatory(expr);
11983 expr->expr = mputc(expr->expr, ')');
11984 }
11985
11986 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
11987 {
11988 expression_struct expr_tmp;
11989 Code::init_expr(&expr_tmp);
11990 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
11991 ->get_type_refd_last();
11992 if (!t1 || t1 == my_governor->get_type_refd_last())
11993 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
11994 if (u.expr.v_optype == OPTYPE_SUBSTR) {
11995 generate_code_expr_substr(&expr_tmp);
11996 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
11997 generate_code_expr_replace(&expr_tmp);
11998 } else {
11999 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12000 }
12001 // Two temporaries to store the result of substr() or replace() and to
12002 // store the converted value.
12003 const string& tmp_id1 = get_temporary_id();
12004 const char *tmp_id_str1 = tmp_id1.c_str();
12005 const string& tmp_id2 = get_temporary_id();
12006 const char *tmp_id_str2 = tmp_id2.c_str();
12007 if (expr_tmp.preamble)
12008 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12009 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12010 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12011 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12012 if (expr_tmp.postamble)
12013 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12014 Code::free_expr(&expr_tmp);
12015 expr->preamble = mputprintf(expr->preamble,
12016 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12017 "`%s' are not compatible at run-time\");\n",
12018 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12019 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12020 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12021 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12022 }
12023
12024 void Value::generate_code_expr_regexp(expression_struct *expr)
12025 {
12026 Value* v1 = u.expr.ti1->get_specific_value();
12027 Value* v2 = u.expr.t2->get_specific_value();
12028 expr->expr = mputstr(expr->expr, "regexp(");
12029 if (v1) v1->generate_code_expr_mandatory(expr);
12030 else u.expr.ti1->generate_code(expr);
12031 expr->expr = mputstr(expr->expr, ", ");
12032 if (v2) v2->generate_code_expr_mandatory(expr);
12033 else u.expr.t2->generate_code(expr);
12034 expr->expr = mputstr(expr->expr, ", ");
12035 u.expr.v3->generate_code_expr_mandatory(expr);
12036 expr->expr = mputc(expr->expr, ')');
12037 }
12038
12039 void Value::generate_code_expr_replace(expression_struct *expr)
12040 {
12041 Value* v1 = u.expr.ti1->get_specific_value();
12042 Value* v4 = u.expr.ti4->get_specific_value();
12043 bool par1_is_str;
12044 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12045 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12046 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12047 if (v1) v1->generate_code_expr_mandatory(expr);
12048 else u.expr.ti1->generate_code(expr);
12049 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12050 else expr->expr = mputstr(expr->expr, ".replace(");
12051 if (!par1_is_str && u.expr.v2->is_unfoldable())
12052 expr->expr = mputstr(expr->expr, "(int)");
12053 u.expr.v2->generate_code_expr_mandatory(expr);
12054 expr->expr = mputstr(expr->expr, ", ");
12055 if (!par1_is_str && u.expr.v3->is_unfoldable())
12056 expr->expr = mputstr(expr->expr, "(int)");
12057 u.expr.v3->generate_code_expr_mandatory(expr);
12058 expr->expr = mputstr(expr->expr, ", ");
12059 if (v4) {
12060 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12061 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12062 Value* v4_last = v4->get_value_refd_last();
12063 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12064 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12065 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
12066 }
12067 v4->generate_code_expr_mandatory(expr);
12068 }
12069 else u.expr.ti4->generate_code(expr);
12070 expr->expr = mputc(expr->expr, ')');
12071 }
12072
12073 void Value::generate_code_expr_rnd(expression_struct *expr,
12074 Value *v1)
12075 {
12076 if(!v1) // simple random generation
12077 expr->expr = mputstr(expr->expr, "rnd()");
12078 else { // random generation with seeding
12079 expr->expr = mputstr(expr->expr, "rnd(");
12080 v1->generate_code_expr_mandatory(expr);
12081 expr->expr = mputc(expr->expr, ')');
12082 }
12083 }
12084
12085 void Value::generate_code_expr_create(expression_struct *expr,
12086 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12087 {
12088 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12089 // first two arguments: component type
12090 Assignment *t_ass = type->get_refd_assignment();
12091 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12092 FATAL_ERROR("Value::generate_code_expr_create()");
12093 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12094 Type::EXPECTED_DYNAMIC_VALUE);
12095 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12096 comptype = comptype->get_type_refd_last();
12097 expr->expr = comptype->get_CompBody()
12098 ->generate_code_comptype_name(expr->expr);
12099 expr->expr = mputstr(expr->expr, ", ");
12100 // third argument: component name
12101 if (name) {
12102 Value *t_val = name->get_value_refd_last();
12103 if (t_val->valuetype == V_CSTR) {
12104 // the argument is foldable to a string literal
12105 size_t str_len = t_val->u.str.val_str->size();
12106 const char *str_ptr = t_val->u.str.val_str->c_str();
12107 expr->expr = mputc(expr->expr, '"');
12108 for (size_t i = 0; i < str_len; i++)
12109 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12110 expr->expr = mputc(expr->expr, '"');
12111 } else name->generate_code_expr_mandatory(expr);
12112 } else expr->expr = mputstr(expr->expr, "NULL");
12113 expr->expr = mputstr(expr->expr, ", ");
12114 // fourth argument: location
12115 if (location) {
12116 Value *t_val = location->get_value_refd_last();
12117 if (t_val->valuetype == V_CSTR) {
12118 // the argument is foldable to a string literal
12119 size_t str_len = t_val->u.str.val_str->size();
12120 const char *str_ptr = t_val->u.str.val_str->c_str();
12121 expr->expr = mputc(expr->expr, '"');
12122 for (size_t i = 0; i < str_len; i++)
12123 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12124 expr->expr = mputc(expr->expr, '"');
12125 } else location->generate_code_expr_mandatory(expr);
12126 } else expr->expr = mputstr(expr->expr, "NULL");
12127 // fifth argument: alive flag
12128 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12129 }
12130
12131 void Value::generate_code_expr_activate(expression_struct *expr)
12132 {
12133 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12134 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12135 FATAL_ERROR("Value::generate_code_expr_activate()");
12136 expr->expr = mputprintf(expr->expr, "%s(",
12137 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12138 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12139 expr->expr = mputc(expr->expr, ')');
12140 }
12141
12142 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12143 {
12144 Value *v_last = u.expr.v1->get_value_refd_last();
12145 if (v_last->valuetype == V_ALTSTEP) {
12146 // the referred altstep is known
12147 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12148 ->get_genname_from_scope(my_scope, "activate_").c_str());
12149 } else {
12150 // the referred altstep is unknown
12151 u.expr.v1->generate_code_expr_mandatory(expr);
12152 expr->expr = mputstr(expr->expr,".activate(");
12153 }
12154 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12155 expr->expr = mputc(expr->expr, ')');
12156 }
12157
12158 void Value::generate_code_expr_execute(expression_struct *expr)
12159 {
12160 Assignment *testcase = u.expr.r1->get_refd_assignment();
12161 expr->expr = mputprintf(expr->expr, "%s(",
12162 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12163 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12164 if (parlist->get_nof_pars() > 0) {
12165 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12166 0, false);
12167 expr->expr = mputstr(expr->expr, ", ");
12168 }
12169 if (u.expr.v2) {
12170 expr->expr = mputstr(expr->expr, "TRUE, ");
12171 u.expr.v2->generate_code_expr_mandatory(expr);
12172 expr->expr = mputc(expr->expr, ')');
12173 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12174 }
12175
12176 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12177 {
12178 Value *v_last = u.expr.v1->get_value_refd_last();
12179 if (v_last->valuetype == V_TESTCASE) {
12180 // the referred testcase is known
12181 Assignment *testcase = v_last->get_refd_fat();
12182 expr->expr = mputprintf(expr->expr, "%s(",
12183 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12184 u.expr.ap_list2->generate_code_alias(expr,
12185 testcase->get_FormalParList(), 0, false);
12186 } else {
12187 // the referred testcase is unknown
12188 u.expr.v1->generate_code_expr_mandatory(expr);
12189 expr->expr = mputstr(expr->expr,".execute(");
12190 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12191 }
12192 if (u.expr.ap_list2->get_nof_pars() > 0)
12193 expr->expr = mputstr(expr->expr, ", ");
12194 if (u.expr.v3) {
12195 expr->expr = mputstr(expr->expr, "TRUE, ");
12196 u.expr.v3->generate_code_expr_mandatory(expr);
12197 expr->expr = mputc(expr->expr, ')');
12198 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12199 }
12200
12201 void Value::generate_code_expr_invoke(expression_struct *expr)
12202 {
12203 Value *last_v = u.invoke.v->get_value_refd_last();
12204 if (last_v->get_valuetype() == V_FUNCTION) {
12205 // the referred function is known
12206 Assignment *function = last_v->get_refd_fat();
12207 expr->expr = mputprintf(expr->expr, "%s(",
12208 function->get_genname_from_scope(my_scope).c_str());
12209 u.invoke.ap_list->generate_code_alias(expr,
12210 function->get_FormalParList(), function->get_RunsOnType(), false);
12211 } else {
12212 // the referred function is unknown
12213 u.invoke.v->generate_code_expr_mandatory(expr);
12214 expr->expr = mputstr(expr->expr, ".invoke(");
12215 Type* gov_last = last_v->get_expr_governor_last();
12216 u.invoke.ap_list->generate_code_alias(expr, 0,
12217 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12218 }
12219 expr->expr = mputc(expr->expr, ')');
12220 }
12221
12222 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12223 Reference *ref)
12224 {
12225 // if the referenced value points to an optional value field the
12226 // generated code has to be corrected at the end:
12227 // `fieldid()' => `fieldid()()'
12228 Assignment *ass = ref->get_refd_assignment();
12229 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12230 switch (ass->get_asstype()) {
12231 case Assignment::A_CONST:
12232 case Assignment::A_EXT_CONST:
12233 case Assignment::A_MODULEPAR:
12234 case Assignment::A_VAR:
12235 case Assignment::A_FUNCTION_RVAL:
12236 case Assignment::A_EXT_FUNCTION_RVAL:
12237 case Assignment::A_PAR_VAL_IN:
12238 case Assignment::A_PAR_VAL_OUT:
12239 case Assignment::A_PAR_VAL_INOUT:
12240 // only these are mapped to value objects
12241 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12242 expr->expr = mputstr(expr->expr, "()");
12243 break;
12244 default:
12245 break;
12246 }
12247 }
12248
12249 void Value::generate_code_expr_encode(expression_struct *expr)
12250 {
12251 Value* v1 = 0;
12252
12253 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12254 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12255 v1 = templ->get_specific_value();
12256 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12257
12258 expression_struct expr2;
12259 Code::init_expr(&expr2);
12260
12261 bool is_templ = false;
12262 switch (templ->get_templatetype()) {
12263 case Template::SPECIFIC_VALUE:
12264 v1->generate_code_expr_mandatory(&expr2);
12265 break;
12266 default:
12267 u.expr.ti1->generate_code(&expr2);
12268 is_templ = true;
12269 break;
12270 }
12271
12272 if (!gov_last->is_coding_by_function()) {
12273 const string& tmp_id = get_temporary_id();
12274 const string& tmp_buf_id = get_temporary_id();
12275 const string& tmp_ref_id = get_temporary_id();
12276 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12277 tmp_id.c_str());
12278 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12279 tmp_buf_id.c_str());
12280 if (expr2.preamble) { // copy preamble setting up the argument, if any
12281 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12282 expr->preamble = mputc (expr->preamble, '\n');
12283 }
12284 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12285 gov_last->get_genname_typedescriptor(
12286 u.expr.ti1->get_Template()->get_my_scope()
12287 ).c_str(),
12288 tmp_ref_id.c_str(),
12289 expr2.expr);
12290 if (is_templ) // make a value out of the template, if needed
12291 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12292 expr->preamble = mputprintf(expr->preamble,
12293 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12294 tmp_ref_id.c_str(),
12295 gov_last->get_genname_typedescriptor(
12296 u.expr.ti1->get_Template()->get_my_scope()
12297 ).c_str(),
12298 tmp_buf_id.c_str(),
12299 gov_last->get_coding(true).c_str()
12300 );
12301 expr->preamble = mputstr(expr->preamble, ");\n");
12302 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12303 tmp_buf_id.c_str(),
12304 tmp_id.c_str()
12305 );
12306 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12307 if (expr2.postamble)
12308 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12309 } else
12310 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12311 gov_last->get_coding(true).c_str(), expr2.expr,
12312 is_templ ? ".valueof()" : "");
12313 Code::free_expr(&expr2);
12314 }
12315
12316 void Value::generate_code_expr_decode(expression_struct *expr)
12317 {
12318 expression_struct expr1, expr2;
12319 Code::init_expr(&expr1);
12320 Code::init_expr(&expr2);
12321 u.expr.r1->generate_code(&expr1);
12322 u.expr.r2->generate_code(&expr2);
12323
12324 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12325 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12326 get_type_refd_last();
12327
12328 if (expr1.preamble)
12329 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12330 if (expr2.preamble)
12331 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12332
12333 if (!_type->is_coding_by_function()) {
12334 const string& tmp_id = get_temporary_id();
12335 const string& buffer_id = get_temporary_id();
12336 const string& retval_id = get_temporary_id();
12337 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12338 field_is_optional(u.expr.r2->get_subrefs());
12339
12340 expr->preamble = mputprintf(expr->preamble,
12341 "TTCN_Buffer %s(bit2oct(%s));\n"
12342 "INTEGER %s;\n"
12343 "TTCN_EncDec::set_error_behavior("
12344 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12345 "TTCN_EncDec::clear_error();\n",
12346 buffer_id.c_str(),
12347 expr1.expr,
12348 retval_id.c_str()
12349 );
12350 expr->preamble = mputprintf(expr->preamble,
12351 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12352 expr2.expr,
12353 optional ? "()" : "",
12354 _type->get_genname_typedescriptor(
12355 u.expr.r2->get_my_scope()
12356 ).c_str(),
12357 buffer_id.c_str(),
12358 _type->get_coding(false).c_str()
12359 );
12360 expr->preamble = mputprintf(expr->preamble,
12361 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12362 "case TTCN_EncDec::ET_NONE: {\n"
12363 "%s.cut();\n"
12364 "OCTETSTRING %s;\n"
12365 "%s.get_string(%s);\n"
12366 "%s = oct2bit(%s);\n"
12367 "%s = 0;\n"
12368 "}break;\n"
12369 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12370 "case TTCN_EncDec::ET_LEN_ERR:\n"
12371 "%s = 2;\n"
12372 "break;\n"
12373 "default:\n"
12374 "%s = 1;\n"
12375 "}\n"
12376 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12377 "TTCN_EncDec::EB_DEFAULT);\n"
12378 "TTCN_EncDec::clear_error();\n",
12379 buffer_id.c_str(),
12380 tmp_id.c_str(),
12381 buffer_id.c_str(),
12382 tmp_id.c_str(),
12383 expr1.expr,
12384 tmp_id.c_str(),
12385 retval_id.c_str(),
12386 retval_id.c_str(),
12387 retval_id.c_str()
12388 );
12389 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12390 } else
12391 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12392 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12393 if (expr1.postamble)
12394 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12395 if (expr2.postamble)
12396 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12397 Code::free_expr(&expr1);
12398 Code::free_expr(&expr2);
12399 }
12400
12401 char *Value::generate_code_init_choice(char *str, const char *name)
12402 {
12403 const char *alt_name = u.choice.alt_name->get_name().c_str();
12404 // Safe as long as get_name() returns a const string&, not a temporary.
12405 const char *alt_prefix =
12406 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12407 ? "AT_" : "";
12408 if (u.choice.alt_value->needs_temp_ref()) {
12409 const string& tmp_id = get_temporary_id();
12410 const char *tmp_id_str = tmp_id.c_str();
12411 str = mputprintf(str, "{\n"
12412 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12413 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12414 alt_prefix, alt_name);
12415 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12416 str = mputstr(str, "}\n");
12417 } else {
12418 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12419 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12420 Free(embedded_name);
12421 }
12422 return str;
12423 }
12424
12425 char *Value::generate_code_init_seof(char *str, const char *name)
12426 {
12427 size_t nof_vs = u.val_vs->get_nof_vs();
12428 if (nof_vs > 0) {
12429 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12430 const string& embedded_type =
12431 my_governor->get_ofType()->get_genname_value(my_scope);
12432 const char *embedded_type_str = embedded_type.c_str();
12433 for (size_t i = 0; i < nof_vs; i++) {
12434 Value *comp_v = u.val_vs->get_v_byIndex(i);
12435
12436 if (comp_v->valuetype == V_NOTUSED) continue;
12437 else if (comp_v->needs_temp_ref()) {
12438 const string& tmp_id = get_temporary_id();
12439 const char *tmp_id_str = tmp_id.c_str();
12440 str = mputprintf(str, "{\n"
12441 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12442 (unsigned long) i);
12443 str = comp_v->generate_code_init(str, tmp_id_str);
12444 str = mputstr(str, "}\n");
12445 } else {
12446 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12447 str = comp_v->generate_code_init(str, embedded_name);
12448 Free(embedded_name);
12449 }
12450 }
12451 } else {
12452 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12453 }
12454 return str;
12455 }
12456
12457 char *Value::generate_code_init_indexed(char *str, const char *name)
12458 {
12459 size_t nof_ivs = u.val_vs->get_nof_ivs();
12460 if (nof_ivs > 0) {
12461 // Previous values can be truncated. The concept is similar to
12462 // templates.
12463 Type *t_last = my_governor->get_type_refd_last();
12464 const string& oftype_name =
12465 t_last->get_ofType()->get_genname_value(my_scope);
12466 const char *oftype_name_str = oftype_name.c_str();
12467 for (size_t i = 0; i < nof_ivs; i++) {
12468 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12469 const string& tmp_id_1 = get_temporary_id();
12470 str = mputstr(str, "{\n");
12471 Value *index = iv->get_index();
12472 if (index->get_valuetype() != V_INT) {
12473 const string& tmp_id_2 = get_temporary_id();
12474 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12475 str = index->generate_code_init(str, tmp_id_2.c_str());
12476 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12477 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12478 } else {
12479 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12480 tmp_id_1.c_str(), name,
12481 (index->get_val_Int()->t_str()).c_str());
12482 }
12483 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12484 str = mputstr(str, "}\n");
12485 }
12486 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12487 return str;
12488 }
12489
12490 char *Value::generate_code_init_array(char *str, const char *name)
12491 {
12492 size_t nof_vs = u.val_vs->get_nof_vs();
12493 Type *t_last = my_governor->get_type_refd_last();
12494 Int index_offset = t_last->get_dimension()->get_offset();
12495 const string& embedded_type =
12496 t_last->get_ofType()->get_genname_value(my_scope);
12497 const char *embedded_type_str = embedded_type.c_str();
12498 for (size_t i = 0; i < nof_vs; i++) {
12499 Value *comp_v = u.val_vs->get_v_byIndex(i);
12500 if (comp_v->valuetype == V_NOTUSED) continue;
12501 else if (comp_v->needs_temp_ref()) {
12502 const string& tmp_id = get_temporary_id();
12503 const char *tmp_id_str = tmp_id.c_str();
12504 str = mputprintf(str, "{\n"
12505 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12506 Int2string(index_offset + i).c_str());
12507 str = comp_v->generate_code_init(str, tmp_id_str);
12508 str = mputstr(str, "}\n");
12509 } else {
12510 char *embedded_name = mprintf("%s[%s]", name,
12511 Int2string(index_offset + i).c_str());
12512 str = comp_v->generate_code_init(str, embedded_name);
12513 Free(embedded_name);
12514 }
12515 }
12516 return str;
12517 }
12518
12519 char *Value::generate_code_init_se(char *str, const char *name)
12520 {
12521 Type *type = my_governor->get_type_refd_last();
12522 size_t nof_comps = type->get_nof_comps();
12523 if (nof_comps > 0) {
12524 for (size_t i = 0; i < nof_comps; i++) {
12525 CompField *cf = type->get_comp_byIndex(i);
12526 const Identifier& field_id = cf->get_name();
12527 const char *field_name = field_id.get_name().c_str();
12528 Value *field_v;
12529 if (u.val_nvs->has_nv_withName(field_id)) {
12530 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12531 if (field_v->valuetype == V_NOTUSED) continue;
12532 if (field_v->valuetype == V_OMIT) field_v = 0;
12533 } else if (is_asn1()) {
12534 if (cf->has_default()) {
12535 // handle like a referenced value
12536 Value *defval = cf->get_defval();
12537 if (needs_init_precede(defval)) {
12538 str = defval->generate_code_init(str,
12539 defval->get_lhs_name().c_str());
12540 }
12541 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12542 defval->get_genname_own(my_scope).c_str());
12543 continue;
12544 } else {
12545 if (!cf->get_is_optional())
12546 FATAL_ERROR("Value::generate_code_init()");
12547 field_v = 0;
12548 }
12549 } else {
12550 continue;
12551 }
12552 if (field_v) {
12553 // the value is not omit
12554 if (field_v->needs_temp_ref()) {
12555 const string& tmp_id = get_temporary_id();
12556 const char *tmp_id_str = tmp_id.c_str();
12557 str = mputprintf(str, "{\n"
12558 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12559 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12560 field_name);
12561 str = field_v->generate_code_init(str, tmp_id_str);
12562 str = mputstr(str, "}\n");
12563 } else {
12564 char *embedded_name = mprintf("%s.%s()", name,
12565 field_name);
12566 if (cf->get_is_optional() && field_v->is_compound())
12567 embedded_name = mputstr(embedded_name, "()");
12568 str = field_v->generate_code_init(str, embedded_name);
12569 Free(embedded_name);
12570 }
12571 } else {
12572 // the value is omit
12573 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12574 name, field_name);
12575 }
12576 }
12577 } else {
12578 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12579 }
12580 return str;
12581 }
12582
12583 char *Value::generate_code_init_refd(char *str, const char *name)
12584 {
12585 Value *v = get_value_refd_last();
12586 if (v == this) {
12587 // the referred value is not available at compile time
12588 // the code generation is based on the reference
12589 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
12590 str = TypeConv::gen_conv_code_refd(str, name, v);
12591 } else {
12592 expression_struct expr;
12593 Code::init_expr(&expr);
12594 expr.expr = mputprintf(expr.expr, "%s = ", name);
12595 u.ref.ref->generate_code_const_ref(&expr);
12596 str = Code::merge_free_expr(str, &expr);
12597 }
12598 } else {
12599 // the referred value is available at compile time
12600 // the code generation is based on the referred value
12601 if (v->has_single_expr() &&
12602 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
12603 // simple substitution for in-line values within the same module
12604 str = mputprintf(str, "%s = %s;\n", name,
12605 v->get_single_expr().c_str());
12606 } else {
12607 // use a simple reference to reduce code size
12608 if (needs_init_precede(v)) {
12609 // the referred value must be initialized first
12610 if (!v->is_toplevel() && v->needs_temp_ref()) {
12611 // temporary id should be introduced for the lhs
12612 const string& tmp_id = get_temporary_id();
12613 const char *tmp_id_str = tmp_id.c_str();
12614 str = mputprintf(str, "{\n"
12615 "%s& %s = %s;\n",
12616 v->get_my_governor()->get_genname_value(my_scope).c_str(),
12617 tmp_id_str, v->get_lhs_name().c_str());
12618 str = v->generate_code_init(str, tmp_id_str);
12619 str = mputstr(str, "}\n");
12620 } else {
12621 str = v->generate_code_init(str, v->get_lhs_name().c_str());
12622 }
12623 }
12624 str = mputprintf(str, "%s = %s;\n", name,
12625 v->get_genname_own(my_scope).c_str());
12626 }
12627 }
12628 return str;
12629 }
12630
12631 void Value::generate_json_value(JSON_Tokenizer& json,
12632 bool allow_special_float, /* = true */
12633 bool union_value_list, /* = false */
12634 Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
12635 {
12636 switch (valuetype) {
12637 case V_INT:
12638 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
12639 break;
12640 case V_REAL: {
12641 Real r = get_val_Real();
12642 if (r == REAL_INFINITY) {
12643 if (allow_special_float) {
12644 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
12645 }
12646 }
12647 else if (r == -REAL_INFINITY) {
12648 if (allow_special_float) {
12649 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
12650 }
12651 }
12652 else if (r != r) {
12653 if (allow_special_float) {
12654 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
12655 }
12656 }
12657 else {
12658 // true if decimal representation possible (use %f format)
12659 bool decimal_repr = (r == 0.0)
12660 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
12661 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
12662 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
12663 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
12664 Free(number_str);
12665 }
12666 break; }
12667 case V_BOOL:
12668 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
12669 break;
12670 case V_BSTR:
12671 case V_HSTR:
12672 case V_OSTR:
12673 case V_CSTR: {
12674 char* str = convert_to_json_string(get_val_str().c_str());
12675 json.put_next_token(JSON_TOKEN_STRING, str);
12676 Free(str);
12677 break; }
12678 case V_USTR: {
12679 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
12680 json.put_next_token(JSON_TOKEN_STRING, str);
12681 Free(str);
12682 break; }
12683 case V_VERDICT:
12684 case V_ENUM:
12685 json.put_next_token(JSON_TOKEN_STRING,
12686 (string('\"') + create_stringRepr() + string('\"')).c_str());
12687 break;
12688 case V_SEQOF:
12689 case V_SETOF:
12690 json.put_next_token(JSON_TOKEN_ARRAY_START);
12691 if (!u.val_vs->is_indexed()) {
12692 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
12693 u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
12694 union_value_list, omit_combo);
12695 }
12696 }
12697 else {
12698 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
12699 // look for the entry with index equal to i
12700 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
12701 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
12702 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
12703 allow_special_float, union_value_list, omit_combo);
12704 break;
12705 }
12706 }
12707 }
12708 }
12709 json.put_next_token(JSON_TOKEN_ARRAY_END);
12710 break;
12711 case V_SEQ:
12712 case V_SET: {
12713 // omitted fields have 2 possible JSON values (the field is absent, or it's
12714 // present with value 'null'), each combination of omitted values must be
12715 // generated
12716 if (omit_combo == NULL) {
12717 FATAL_ERROR("Value::generate_json_value - no combo");
12718 }
12719 size_t len = get_nof_comps();
12720 // generate the JSON object from the present combination
12721 json.put_next_token(JSON_TOKEN_OBJECT_START);
12722 for (size_t i = 0; i < len; ++i) {
12723 Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
12724 if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
12725 // the field is absent, don't insert anything
12726 continue;
12727 }
12728 // use the field's alias, if it has one
12729 const char* alias = NULL;
12730 if (my_governor != NULL) {
12731 JsonAST* field_attrib = my_governor->get_comp_byName(
12732 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
12733 if (field_attrib != NULL) {
12734 alias = field_attrib->alias;
12735 }
12736 }
12737 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
12738 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
12739 if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
12740 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
12741 }
12742 else {
12743 get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
12744 allow_special_float, union_value_list, omit_combo);
12745 }
12746 }
12747 json.put_next_token(JSON_TOKEN_OBJECT_END);
12748 break; }
12749 case V_CHOICE: {
12750 bool as_value = !union_value_list && my_governor != NULL &&
12751 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
12752 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
12753 if (!as_value) {
12754 // no 'as value' coding instruction, insert an object with one field
12755 json.put_next_token(JSON_TOKEN_OBJECT_START);
12756 // use the field's alias, if it has one
12757 const char* alias = NULL;
12758 if (my_governor != NULL) {
12759 JsonAST* field_attrib = my_governor->get_comp_byName(
12760 get_alt_name())->get_type()->get_json_attributes();
12761 if (field_attrib != NULL) {
12762 alias = field_attrib->alias;
12763 }
12764 }
12765 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
12766 get_alt_name().get_ttcnname().c_str());
12767 }
12768 get_alt_value()->generate_json_value(json, allow_special_float,
12769 union_value_list, omit_combo);
12770 if (!as_value) {
12771 json.put_next_token(JSON_TOKEN_OBJECT_END);
12772 }
12773 break; }
12774 case V_REFD: {
12775 Value* v = get_value_refd_last();
12776 if (this != v) {
12777 v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
12778 return;
12779 }
12780 } // no break
12781 default:
12782 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
12783 }
12784 }
12785
12786 bool Value::explicit_cast_needed(bool forIsValue)
12787 {
12788 Value *v_last = get_value_refd_last();
12789 if (v_last != this) {
12790 // this is a foldable referenced value
12791 // if the reference points to an imported or compound value the code
12792 // generation will be based on the reference so cast is not needed
12793 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
12794 || !v_last->has_single_expr()) return false;
12795 } else if (v_last->valuetype == V_REFD) {
12796 // this is an unfoldable reference (v_last==this)
12797 // explicit cast is needed only for string element references
12798 if (forIsValue) return false;
12799 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
12800 return t_subrefs && t_subrefs->refers_to_string_element();
12801 }
12802 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
12803 Type *t_governor = v_last->my_governor->get_type_refd_last();
12804 switch (t_governor->get_typetype()) {
12805 case Type::T_NULL:
12806 case Type::T_BOOL:
12807 case Type::T_INT:
12808 case Type::T_INT_A:
12809 case Type::T_REAL:
12810 case Type::T_ENUM_A:
12811 case Type::T_ENUM_T:
12812 case Type::T_VERDICT:
12813 case Type::T_COMPONENT:
12814 // these are mapped to built-in C/C++ types
12815 return true;
12816 case Type::T_SEQ_A:
12817 case Type::T_SEQ_T:
12818 case Type::T_SET_A:
12819 case Type::T_SET_T:
12820 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12821 return t_governor->get_nof_comps() == 0;
12822 case Type::T_SEQOF:
12823 case Type::T_SETOF:
12824 // the C++ equivalent of value {} is ambiguous
12825 // tr926
12826 return true;
12827 case Type::T_FUNCTION:
12828 case Type::T_ALTSTEP:
12829 case Type::T_TESTCASE:
12830 return true;
12831 default:
12832 return false;
12833 }
12834 }
12835
12836 bool Value::has_single_expr()
12837 {
12838 if (get_needs_conversion()) return false;
12839 switch (valuetype) {
12840 case V_EXPR:
12841 return has_single_expr_expr();
12842 case V_CHOICE:
12843 case V_ARRAY:
12844 // a union or array value cannot be represented as an in-line expression
12845 return false;
12846 case V_SEQOF:
12847 case V_SETOF:
12848 // only an empty record/set of value can be represented as an in-line
12849 // expression
12850 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
12851 else return u.val_vs->get_nof_ivs() == 0;
12852 case V_SEQ:
12853 case V_SET: {
12854 // only a value for an empty record/set type can be represented as an
12855 // in-line expression
12856 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
12857 Type *type = my_governor->get_type_refd_last();
12858 return type->get_nof_comps() == 0; }
12859 case V_REFD: {
12860 Value *v_last = get_value_refd_last();
12861 // If the above call hit an error and set_valuetype(V_ERROR),
12862 // then u.ref.ref has been freed. Avoid the segfault.
12863 if (valuetype == V_ERROR)
12864 return false;
12865 if (v_last != this && v_last->has_single_expr() &&
12866 v_last->my_scope->get_scope_mod_gen() ==
12867 my_scope->get_scope_mod_gen()) return true;
12868 else return u.ref.ref->has_single_expr(); }
12869 case V_INVOKE:
12870 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
12871 case V_ERROR:
12872 case V_NAMEDINT:
12873 case V_NAMEDBITS:
12874 case V_UNDEF_LOWERID:
12875 case V_UNDEF_BLOCK:
12876 case V_REFER:
12877 // these values cannot occur during code generation
12878 FATAL_ERROR("Value::has_single_expr()");
12879 case V_INT:
12880 return u.val_Int->is_native_fit();
12881 default:
12882 // other value types (literal values) do not need temporary reference
12883 return true;
12884 }
12885 }
12886
12887 string Value::get_single_expr()
12888 {
12889 switch (valuetype) {
12890 case V_NULL:
12891 return string("ASN_NULL_VALUE");
12892 case V_BOOL:
12893 return string(u.val_bool ? "TRUE" : "FALSE");
12894 case V_INT:
12895 if (u.val_Int->is_native_fit()) { // Be sure.
12896 return u.val_Int->t_str();
12897 } else {
12898 // get_single_expr may be called only if has_single_expr() is true.
12899 // The only exception is V_INT, where get_single_expr may be called
12900 // even if is_native_fit (which is used to implement has_single_expr)
12901 // returns false.
12902 string ret_val('"');
12903 ret_val += u.val_Int->t_str();
12904 ret_val += '"';
12905 return ret_val;
12906 }
12907 case V_REAL:
12908 return Real2code(u.val_Real);
12909 case V_ENUM:
12910 return get_single_expr_enum();
12911 case V_BSTR:
12912 return get_my_scope()->get_scope_mod_gen()
12913 ->add_bitstring_literal(*u.str.val_str);
12914 case V_HSTR:
12915 return get_my_scope()->get_scope_mod_gen()
12916 ->add_hexstring_literal(*u.str.val_str);
12917 case V_OSTR:
12918 return get_my_scope()->get_scope_mod_gen()
12919 ->add_octetstring_literal(*u.str.val_str);
12920 case V_CSTR:
12921 return get_my_scope()->get_scope_mod_gen()
12922 ->add_charstring_literal(*u.str.val_str);
12923 case V_USTR:
12924 if (u.ustr.convert_str) {
12925 set_valuetype(V_CSTR);
12926 return get_my_scope()->get_scope_mod_gen()
12927 ->add_charstring_literal(*u.str.val_str);
12928 } else
12929 return get_my_scope()->get_scope_mod_gen()
12930 ->add_ustring_literal(*u.ustr.val_ustr);
12931 case V_ISO2022STR:
12932 return get_single_expr_iso2022str();
12933 case V_OID:
12934 case V_ROID: {
12935 vector<string> comps;
12936 bool is_constant = get_oid_comps(comps);
12937 size_t nof_comps = comps.size();
12938 string oi_str;
12939 for (size_t i = 0; i < nof_comps; i++) {
12940 if (i > 0) oi_str += ", ";
12941 oi_str += *(comps[i]);
12942 }
12943 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
12944 comps.clear();
12945 if (is_constant) {
12946 // the objid only contains constants
12947 // => create a literal and return its name
12948 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
12949 }
12950 // the objid contains at least one variable
12951 // => append the number of components before the component values in the string and return it
12952 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
12953 case V_SEQOF:
12954 case V_SETOF:
12955 if (u.val_vs->get_nof_vs() > 0)
12956 FATAL_ERROR("Value::get_single_expr()");
12957 return string("NULL_VALUE");
12958 case V_SEQ:
12959 case V_SET:
12960 if (u.val_nvs->get_nof_nvs() > 0)
12961 FATAL_ERROR("Value::get_single_expr()");
12962 return string("NULL_VALUE");
12963 case V_REFD: {
12964 Value *v_last = get_value_refd_last();
12965 if (v_last != this && v_last->has_single_expr() &&
12966 v_last->my_scope->get_scope_mod_gen() ==
12967 my_scope->get_scope_mod_gen()) {
12968 // the reference points to another single value in the same module
12969 return v_last->get_single_expr();
12970 } else {
12971 // convert the reference to a single expression
12972 expression_struct expr;
12973 Code::init_expr(&expr);
12974 u.ref.ref->generate_code_const_ref(&expr);
12975 if (expr.preamble || expr.postamble)
12976 FATAL_ERROR("Value::get_single_expr()");
12977 string ret_val(expr.expr);
12978 Code::free_expr(&expr);
12979 return ret_val;
12980 } }
12981 case V_OMIT:
12982 return string("OMIT_VALUE");
12983 case V_VERDICT:
12984 switch (u.verdict) {
12985 case Verdict_NONE:
12986 return string("NONE");
12987 case Verdict_PASS:
12988 return string("PASS");
12989 case Verdict_INCONC:
12990 return string("INCONC");
12991 case Verdict_FAIL:
12992 return string("FAIL");
12993 case Verdict_ERROR:
12994 return string("ERROR");
12995 default:
12996 FATAL_ERROR("Value::get_single_expr()");
12997 return string();
12998 }
12999 case V_DEFAULT_NULL:
13000 return string("NULL_COMPREF");
13001 case V_FAT_NULL: {
13002 string ret_val('(');
13003 ret_val += my_governor->get_genname_value(my_scope);
13004 ret_val += "::function_pointer)Module_List::get_fat_null()";
13005 return ret_val; }
13006 case V_EXPR:
13007 case V_INVOKE: {
13008 expression_struct expr;
13009 Code::init_expr(&expr);
13010 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13011 else generate_code_expr_invoke(&expr);
13012 if (expr.preamble || expr.postamble)
13013 FATAL_ERROR("Value::get_single_expr()");
13014 string ret_val(expr.expr);
13015 Code::free_expr(&expr);
13016 return ret_val; }
13017 case V_MACRO:
13018 switch (u.macro) {
13019 case MACRO_TESTCASEID:
13020 return string("TTCN_Runtime::get_testcase_id_macro()");
13021 default:
13022 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13023 return string();
13024 }
13025 case V_FUNCTION:
13026 case V_ALTSTEP:
13027 case V_TESTCASE:
13028 return get_single_expr_fat();
13029 default:
13030 FATAL_ERROR("Value::get_single_expr()");
13031 return string();
13032 }
13033 }
13034
13035 bool Value::has_single_expr_expr()
13036 {
13037 switch (u.expr.v_optype) {
13038 case OPTYPE_RND: // -
13039 case OPTYPE_COMP_NULL:
13040 case OPTYPE_COMP_MTC:
13041 case OPTYPE_COMP_SYSTEM:
13042 case OPTYPE_COMP_SELF:
13043 case OPTYPE_COMP_RUNNING_ANY:
13044 case OPTYPE_COMP_RUNNING_ALL:
13045 case OPTYPE_COMP_ALIVE_ANY:
13046 case OPTYPE_COMP_ALIVE_ALL:
13047 case OPTYPE_TMR_RUNNING_ANY:
13048 case OPTYPE_GETVERDICT:
13049 case OPTYPE_TESTCASENAME:
13050 case OPTYPE_PROF_RUNNING:
13051 return true;
13052 case OPTYPE_ENCODE:
13053 case OPTYPE_DECODE:
13054 case OPTYPE_ISBOUND:
13055 case OPTYPE_ISPRESENT:
13056 case OPTYPE_TTCN2STRING:
13057 return false;
13058 case OPTYPE_UNARYPLUS: // v1
13059 case OPTYPE_UNARYMINUS:
13060 case OPTYPE_NOT:
13061 case OPTYPE_NOT4B:
13062 case OPTYPE_BIT2HEX:
13063 case OPTYPE_BIT2INT:
13064 case OPTYPE_BIT2OCT:
13065 case OPTYPE_BIT2STR:
13066 case OPTYPE_CHAR2INT:
13067 case OPTYPE_CHAR2OCT:
13068 case OPTYPE_FLOAT2INT:
13069 case OPTYPE_FLOAT2STR:
13070 case OPTYPE_HEX2BIT:
13071 case OPTYPE_HEX2INT:
13072 case OPTYPE_HEX2OCT:
13073 case OPTYPE_HEX2STR:
13074 case OPTYPE_INT2CHAR:
13075 case OPTYPE_INT2FLOAT:
13076 case OPTYPE_INT2STR:
13077 case OPTYPE_INT2UNICHAR:
13078 case OPTYPE_OCT2BIT:
13079 case OPTYPE_OCT2CHAR:
13080 case OPTYPE_OCT2HEX:
13081 case OPTYPE_OCT2INT:
13082 case OPTYPE_OCT2STR:
13083 case OPTYPE_STR2BIT:
13084 case OPTYPE_STR2FLOAT:
13085 case OPTYPE_STR2HEX:
13086 case OPTYPE_STR2INT:
13087 case OPTYPE_STR2OCT:
13088 case OPTYPE_UNICHAR2INT:
13089 case OPTYPE_UNICHAR2CHAR:
13090 case OPTYPE_ENUM2INT:
13091 case OPTYPE_RNDWITHVAL:
13092 case OPTYPE_ISCHOSEN_V: // v1 i2
13093 case OPTYPE_COMP_RUNNING:
13094 case OPTYPE_COMP_ALIVE:
13095 case OPTYPE_GET_STRINGENCODING:
13096 case OPTYPE_REMOVE_BOM:
13097 case OPTYPE_DECODE_BASE64:
13098 return u.expr.v1->has_single_expr();
13099 case OPTYPE_ISCHOSEN_T: // t1 i2
13100 return u.expr.t1->has_single_expr();
13101 case OPTYPE_ADD: // v1 v2
13102 case OPTYPE_SUBTRACT:
13103 case OPTYPE_MULTIPLY:
13104 case OPTYPE_DIVIDE:
13105 case OPTYPE_MOD:
13106 case OPTYPE_REM:
13107 case OPTYPE_CONCAT:
13108 case OPTYPE_EQ:
13109 case OPTYPE_LT:
13110 case OPTYPE_GT:
13111 case OPTYPE_NE:
13112 case OPTYPE_GE:
13113 case OPTYPE_LE:
13114 case OPTYPE_XOR:
13115 case OPTYPE_AND4B:
13116 case OPTYPE_OR4B:
13117 case OPTYPE_XOR4B:
13118 case OPTYPE_SHL:
13119 case OPTYPE_SHR:
13120 case OPTYPE_ROTL:
13121 case OPTYPE_ROTR:
13122 case OPTYPE_INT2BIT:
13123 case OPTYPE_INT2HEX:
13124 case OPTYPE_INT2OCT:
13125 return u.expr.v1->has_single_expr() &&
13126 u.expr.v2->has_single_expr();
13127 case OPTYPE_UNICHAR2OCT:
13128 case OPTYPE_OCT2UNICHAR:
13129 case OPTYPE_ENCODE_BASE64:
13130 return u.expr.v1->has_single_expr() &&
13131 (!u.expr.v2 || u.expr.v2->has_single_expr());
13132 case OPTYPE_AND:
13133 case OPTYPE_OR:
13134 return u.expr.v1->has_single_expr() &&
13135 u.expr.v2->has_single_expr() &&
13136 !u.expr.v2->needs_short_circuit();
13137 case OPTYPE_SUBSTR:
13138 return u.expr.ti1->has_single_expr() &&
13139 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13140 case OPTYPE_REGEXP:
13141 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13142 u.expr.v3->has_single_expr();
13143 case OPTYPE_DECOMP: // v1 v2 v3
13144 return u.expr.v1->has_single_expr() &&
13145 u.expr.v2->has_single_expr() &&
13146 u.expr.v3->has_single_expr();
13147 case OPTYPE_REPLACE:
13148 return u.expr.ti1->has_single_expr() &&
13149 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13150 u.expr.ti4->has_single_expr();
13151 case OPTYPE_ISVALUE: // ti1
13152 case OPTYPE_LENGTHOF: // ti1
13153 case OPTYPE_SIZEOF: // ti1
13154 case OPTYPE_VALUEOF: // ti1
13155 return u.expr.ti1->has_single_expr();
13156 case OPTYPE_LOG2STR:
13157 return u.expr.logargs->has_single_expr();
13158 case OPTYPE_MATCH: // v1 t2
13159 return u.expr.v1->has_single_expr() &&
13160 u.expr.t2->has_single_expr();
13161 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13162 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13163 (!u.expr.v3 || u.expr.v3->has_single_expr());
13164 case OPTYPE_TMR_READ: // r1
13165 case OPTYPE_TMR_RUNNING:
13166 case OPTYPE_ACTIVATE:
13167 return u.expr.r1->has_single_expr();
13168 case OPTYPE_EXECUTE: // r1 [v2]
13169 return u.expr.r1->has_single_expr() &&
13170 (!u.expr.v2 || u.expr.v2->has_single_expr());
13171 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13172 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13173 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13174 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13175 (!u.expr.v3 || u.expr.v3->has_single_expr());
13176 default:
13177 FATAL_ERROR("Value::has_single_expr_expr()");
13178 } // switch
13179 }
13180
13181 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13182 {
13183 if (!v->has_single_expr()) return false;
13184 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13185 if (!ap_list->get_par(i)->has_single_expr()) return false;
13186 return true;
13187 }
13188
13189 string Value::get_single_expr_enum()
13190 {
13191 string ret_val(my_governor->get_genname_value(my_scope));
13192 ret_val += "::";
13193 ret_val += u.val_id->get_name();
13194 return ret_val;
13195 }
13196
13197 string Value::get_single_expr_iso2022str()
13198 {
13199 string ret_val;
13200 Type *type = get_my_governor()->get_type_refd_last();
13201 switch (type->get_typetype()) {
13202 case Type::T_TELETEXSTRING:
13203 ret_val += "TTCN_ISO2022_2_TeletexString";
13204 break;
13205 case Type::T_VIDEOTEXSTRING:
13206 ret_val += "TTCN_ISO2022_2_VideotexString";
13207 break;
13208 case Type::T_GRAPHICSTRING:
13209 case Type::T_OBJECTDESCRIPTOR:
13210 ret_val += "TTCN_ISO2022_2_GraphicString";
13211 break;
13212 case Type::T_GENERALSTRING:
13213 ret_val += "TTCN_ISO2022_2_GeneralString";
13214 break;
13215 default:
13216 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13217 } // switch
13218 ret_val += '(';
13219 string *ostr = char2oct(*u.str.val_str);
13220 ret_val += get_my_scope()->get_scope_mod_gen()
13221 ->add_octetstring_literal(*ostr);
13222 delete ostr;
13223 ret_val += ')';
13224 return ret_val;
13225 }
13226
13227 string Value::get_single_expr_fat()
13228 {
13229 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13230 // the ampersand operator is not really necessary to obtain the function
13231 // pointer, but some older versions of GCC cannot instantiate the
13232 // appropriate operator=() member of class OPTIONAL when necessary
13233 // if only the function name is given
13234 string ret_val('&');
13235 switch (valuetype) {
13236 case V_FUNCTION:
13237 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13238 break;
13239 case V_ALTSTEP:
13240 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13241 ret_val += "_instance";
13242 break;
13243 case V_TESTCASE:
13244 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13245 break;
13246 default:
13247 FATAL_ERROR("Value::get_single_expr_fat()");
13248 }
13249 return ret_val;
13250 }
13251
13252 bool Value::is_compound()
13253 {
13254 switch (valuetype) {
13255 case V_CHOICE:
13256 case V_SEQOF:
13257 case V_SETOF:
13258 case V_ARRAY:
13259 case V_SEQ:
13260 case V_SET:
13261 return true;
13262 default:
13263 return false;
13264 }
13265 }
13266
13267 bool Value::needs_temp_ref()
13268 {
13269 switch (valuetype) {
13270 case V_SEQOF:
13271 case V_SETOF:
13272 if (!is_indexed()) {
13273 // Temporary reference is needed if the value has at least one real
13274 // element (i.e. it is not empty or contains only not used symbols).
13275 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13276 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13277 }
13278 } else {
13279 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13280 if (u.val_vs->get_iv_byIndex(i)->get_value()
13281 ->valuetype != V_NOTUSED)
13282 return true;
13283 }
13284 }
13285 return false;
13286 case V_ARRAY: {
13287 size_t nof_real_vs = 0;
13288 if (!is_indexed()) {
13289 // Temporary reference is needed if the array value has at least two
13290 // real elements (excluding not used symbols).
13291 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13292 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13293 nof_real_vs++;
13294 if (nof_real_vs > 1) return true;
13295 }
13296 }
13297 } else {
13298 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13299 if (u.val_vs->get_iv_byIndex(i)->get_value()
13300 ->valuetype != V_NOTUSED) {
13301 nof_real_vs++;
13302 if (nof_real_vs > 1) return true;
13303 }
13304 }
13305 }
13306 return false; }
13307 case V_SEQ:
13308 case V_SET:
13309 if (is_asn1()) {
13310 // it depends on the type since fields with omit or default value
13311 // may not be present
13312 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13313 } else {
13314 // incomplete values are allowed in TTCN-3
13315 // we should check the number of value components
13316 return u.val_nvs->get_nof_nvs() > 1;
13317 }
13318 case V_ERROR:
13319 case V_NAMEDINT:
13320 case V_NAMEDBITS:
13321 case V_UNDEF_LOWERID:
13322 case V_UNDEF_BLOCK:
13323 case V_TTCN3_NULL:
13324 // these values cannot occur during code generation
13325 FATAL_ERROR("Value::needs_temp_ref()");
13326 case V_INT:
13327 return !u.val_Int->is_native();
13328 default:
13329 // other value types (literal values) do not need temporary reference
13330 return false;
13331 }
13332 }
13333
13334 bool Value::needs_short_circuit()
13335 {
13336 switch (valuetype) {
13337 case V_BOOL:
13338 return false;
13339 case V_REFD:
13340 // examined below
13341 break;
13342 case V_EXPR:
13343 case V_INVOKE:
13344 // sub-expressions should be evaluated only if necessary
13345 return true;
13346 default:
13347 FATAL_ERROR("Value::needs_short_circuit()");
13348 }
13349 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13350 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13351 switch (t_ass->get_asstype()) {
13352 case Assignment::A_FUNCTION_RVAL:
13353 case Assignment::A_EXT_FUNCTION_RVAL:
13354 // avoid unnecessary call of a function
13355 return true;
13356 case Assignment::A_CONST:
13357 case Assignment::A_EXT_CONST:
13358 case Assignment::A_MODULEPAR:
13359 case Assignment::A_VAR:
13360 case Assignment::A_PAR_VAL_IN:
13361 case Assignment::A_PAR_VAL_OUT:
13362 case Assignment::A_PAR_VAL_INOUT:
13363 // depends on field/array sub-references, which is examined below
13364 break;
13365 default:
13366 FATAL_ERROR("Value::needs_short_circuit()");
13367 }
13368 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13369 if (t_subrefs) {
13370 // the evaluation of the reference does not have side effects
13371 // (i.e. false shall be returned) only if all sub-references point to
13372 // mandatory fields of record/set types, and neither sub-reference points
13373 // to a field of a union type
13374 Type *t_type = t_ass->get_Type();
13375 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13376 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13377 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13378 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13379 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13380 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13381 t_cf->get_is_optional()) return true;
13382 t_type = t_cf->get_type();
13383 } else return true;
13384 }
13385 }
13386 return false;
13387 }
13388
13389 void Value::dump(unsigned level) const
13390 {
13391 switch (valuetype) {
13392 case V_ERROR:
13393 case V_NULL:
13394 case V_BOOL:
13395 case V_INT:
13396 case V_NAMEDINT:
13397 case V_NAMEDBITS:
13398 case V_REAL:
13399 case V_ENUM:
13400 case V_BSTR:
13401 case V_HSTR:
13402 case V_OSTR:
13403 case V_CSTR:
13404 case V_ISO2022STR:
13405 case V_OID:
13406 case V_ROID:
13407 case V_CHOICE:
13408 case V_SEQOF:
13409 case V_SETOF:
13410 case V_ARRAY:
13411 case V_SEQ:
13412 case V_SET:
13413 case V_OMIT:
13414 case V_VERDICT:
13415 case V_DEFAULT_NULL:
13416 case V_FAT_NULL:
13417 case V_EXPR:
13418 case V_MACRO:
13419 case V_NOTUSED:
13420 case V_FUNCTION:
13421 case V_ALTSTEP:
13422 case V_TESTCASE:
13423 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13424 break;
13425 case V_REFD:
13426 case V_REFER:
13427 DEBUG(level, "Value: reference");
13428 u.ref.ref->dump(level + 1);
13429 break;
13430 case V_UNDEF_LOWERID:
13431 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13432 break;
13433 case V_UNDEF_BLOCK:
13434 DEBUG(level, "Value: {block}");
13435 break;
13436 case V_TTCN3_NULL:
13437 DEBUG(level, "Value: null");
13438 break;
13439 case V_INVOKE:
13440 DEBUG(level, "Value: invoke");
13441 u.invoke.v->dump(level + 1);
13442 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13443 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13444 break;
13445 default:
13446 DEBUG(level, "Value: unknown type: %d", valuetype);
13447 } // switch
13448 }
13449
13450 void Value::add_string_element(size_t index, Value *v_element,
13451 map<size_t, Value>*& string_elements)
13452 {
13453 v_element->set_my_scope(get_my_scope());
13454 v_element->set_my_governor(get_my_governor());
13455 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13456 v_element->set_location(*this);
13457 if (!string_elements) string_elements = new map<size_t, Value>;
13458 string_elements->add(index, v_element);
13459 }
13460
13461 ///////////////////////////////////////////////////////////////////////////////
13462 // class LazyParamData
13463
13464 int LazyParamData::depth = 0;
13465 bool LazyParamData::used_as_lvalue = false;
13466 vector<string>* LazyParamData::type_vec = NULL;
13467 vector<string>* LazyParamData::refd_vec = NULL;
13468
13469 void LazyParamData::init(bool p_used_as_lvalue) {
13470 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13471 if (depth==0) {
13472 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13473 used_as_lvalue = p_used_as_lvalue;
13474 type_vec = new vector<string>;
13475 refd_vec = new vector<string>;
13476 }
13477 depth++;
13478 }
13479
13480 void LazyParamData::clean() {
13481 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13482 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13483 if (depth==1) {
13484 // type_vec
13485 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13486 type_vec->clear();
13487 delete type_vec;
13488 type_vec = NULL;
13489 // refd_vec
13490 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13491 refd_vec->clear();
13492 delete refd_vec;
13493 refd_vec = NULL;
13494 }
13495 depth--;
13496 }
13497
13498 bool LazyParamData::in_lazy() {
13499 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13500 return depth>0;
13501 }
13502
13503 // returns a temporary id instead of the C++ reference to a definition
13504 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13505 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13506 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13507 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13508 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13509 // store the type of the assignment
13510 string* type_str = new string;
13511 switch (ass->get_asstype()) {
13512 case Assignment::A_MODULEPAR_TEMP:
13513 case Assignment::A_TEMPLATE:
13514 case Assignment::A_VAR_TEMPLATE:
13515 case Assignment::A_PAR_TEMPL_IN:
13516 case Assignment::A_PAR_TEMPL_OUT:
13517 case Assignment::A_PAR_TEMPL_INOUT:
13518 *type_str = ass->get_Type()->get_genname_template(scope);
13519 break;
13520 default:
13521 *type_str = ass->get_Type()->get_genname_value(scope);
13522 }
13523 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13524 bool refd_ass_is_lazy_fpar = false;
13525 switch (ass->get_asstype()) {
13526 case Assignment::A_PAR_VAL:
13527 case Assignment::A_PAR_VAL_IN:
13528 case Assignment::A_PAR_TEMPL_IN:
13529 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13530 if (refd_ass_is_lazy_fpar) {
13531 *type_str = string("Lazy_Param<") + *type_str + string(">");
13532 }
13533 break;
13534 default:
13535 break;
13536 }
13537 // add the "const" part if the referenced assignment is a constant thing
13538 if (!refd_ass_is_lazy_fpar) {
13539 switch (ass->get_asstype()) {
13540 case Assignment::A_CONST:
13541 case Assignment::A_OC:
13542 case Assignment::A_OBJECT:
13543 case Assignment::A_OS:
13544 case Assignment::A_VS:
13545 case Assignment::A_EXT_CONST:
13546 case Assignment::A_MODULEPAR:
13547 case Assignment::A_MODULEPAR_TEMP:
13548 case Assignment::A_TEMPLATE:
13549 case Assignment::A_PAR_VAL:
13550 case Assignment::A_PAR_VAL_IN:
13551 case Assignment::A_PAR_TEMPL_IN:
13552 *type_str = string("const ") + *type_str;
13553 break;
13554 default:
13555 // nothing to do
13556 break;
13557 }
13558 }
13559 //
13560 type_vec->add(type_str);
13561 // store the C++ reference string
13562 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
13563 if (refd_ass_is_lazy_fpar) {
13564 Type* refd_ass_type = ass->get_Type();
13565 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);
13566 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13567 } else {
13568 return get_member_name(refd_vec->size()-1);
13569 }
13570 }
13571
13572 string LazyParamData::get_member_name(size_t idx) {
13573 return string("lpm_") + Int2string(idx);
13574 }
13575
13576 string LazyParamData::get_constr_param_name(size_t idx) {
13577 return string("lpp_") + Int2string(idx);
13578 }
13579
13580 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
13581 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13582 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
13583 const string& tmp_id = val->get_temporary_id();
13584 const char *tmp_id_str = tmp_id.c_str();
13585 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13586 val->get_my_governor()->get_genname_value(my_scope).c_str(),
13587 tmp_id_str);
13588 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13589 tmp_id_str, val);
13590 expr->expr = mputstr(expr->expr, tmp_id_str);
13591 } else {
13592 val->generate_code_expr(expr);
13593 }
13594 }
13595
13596 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
13597 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13598 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
13599 const string& tmp_id = temp->get_Template()->get_temporary_id();
13600 const char *tmp_id_str = tmp_id.c_str();
13601 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13602 temp->get_Template()->get_my_governor()
13603 ->get_genname_template(my_scope).c_str(), tmp_id_str);
13604 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13605 tmp_id_str, temp->get_Template());
13606 // Not incorporated into gen_conv_code() yet.
13607 if (gen_restriction_check != TR_NONE)
13608 expr->preamble = Template::generate_restriction_check_code(
13609 expr->preamble, tmp_id_str, gen_restriction_check);
13610 expr->expr = mputstr(expr->expr, tmp_id_str);
13611 } else temp->generate_code(expr, gen_restriction_check);
13612 }
13613
13614 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
13615 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13616 if (depth>1) {
13617 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13618 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13619 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13620 expression_struct value_expr;
13621 Code::init_expr(&value_expr);
13622 generate_code_for_value(&value_expr, value, scope);
13623 // the id of the instance of Lazy_Param which will be used as the actual parameter
13624 const string& lazy_param_id = value->get_temporary_id();
13625 if (value_expr.preamble) {
13626 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
13627 }
13628 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13629 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13630 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
13631 Code::free_expr(&value_expr);
13632 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13633 return;
13634 }
13635 // only if the formal parameter is *not* used as lvalue
13636 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
13637 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
13638 if (refd_ass) {
13639 bool refd_ass_is_lazy_fpar = false;
13640 switch (refd_ass->get_asstype()) {
13641 case Assignment::A_PAR_VAL:
13642 case Assignment::A_PAR_VAL_IN:
13643 case Assignment::A_PAR_TEMPL_IN:
13644 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13645 break;
13646 default:
13647 break;
13648 }
13649 if (refd_ass_is_lazy_fpar) {
13650 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13651 return;
13652 }
13653 }
13654 }
13655 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13656 expression_struct value_expr;
13657 Code::init_expr(&value_expr);
13658 generate_code_for_value(&value_expr, value, scope);
13659 // the id of the instance of Lazy_Param which will be used as the actual parameter
13660 string lazy_param_id = value->get_temporary_id();
13661 string type_name = value->get_my_governor()->get_genname_value(scope);
13662 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
13663 }
13664
13665 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
13666 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13667 if (depth>1) {
13668 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13669 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13670 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13671 expression_struct tmpl_expr;
13672 Code::init_expr(&tmpl_expr);
13673 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13674 // the id of the instance of Lazy_Param which will be used as the actual parameter
13675 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
13676 if (tmpl_expr.preamble) {
13677 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
13678 }
13679 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13680 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13681 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
13682 Code::free_expr(&tmpl_expr);
13683 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13684 return;
13685 }
13686 // only if the formal parameter is *not* used as lvalue
13687 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
13688 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
13689 if (refd_ass) {
13690 bool refd_ass_is_lazy_fpar = false;
13691 switch (refd_ass->get_asstype()) {
13692 case Assignment::A_PAR_VAL:
13693 case Assignment::A_PAR_VAL_IN:
13694 case Assignment::A_PAR_TEMPL_IN:
13695 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13696 break;
13697 default:
13698 break;
13699 }
13700 if (refd_ass_is_lazy_fpar) {
13701 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13702 return;
13703 }
13704 }
13705 }
13706 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13707 expression_struct tmpl_expr;
13708 Code::init_expr(&tmpl_expr);
13709 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13710 // the id of the instance of Lazy_Param which will be used as the actual parameter
13711 string lazy_param_id = temp->get_Template()->get_temporary_id();
13712 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
13713 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
13714 }
13715
13716 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
13717 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
13718 if (type_vec->size()>0) {
13719 // private members of the local class will be const references to the objects referenced by the expression
13720 for (size_t i=0; i<type_vec->size(); i++) {
13721 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
13722 }
13723 expr->preamble = mputstr(expr->preamble, "public:\n");
13724 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
13725 for (size_t i=0; i<type_vec->size(); i++) {
13726 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13727 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
13728 }
13729 expr->preamble = mputstr(expr->preamble, "): ");
13730 for (size_t i=0; i<type_vec->size(); i++) {
13731 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13732 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
13733 }
13734 expr->preamble = mputstr(expr->preamble, " {}\n");
13735 expr->preamble = mputstr(expr->preamble, "private:\n");
13736 }
13737 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
13738 // use the temporary expr structure to fill the body of the eval_expr() function
13739 if (param_expr.preamble) {
13740 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
13741 }
13742 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
13743 if (param_expr.postamble) {
13744 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
13745 }
13746 Code::free_expr(&param_expr);
13747 expr->preamble = mputstr(expr->preamble, "}\n"
13748 "};\n" // end of local class definition
13749 );
13750 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
13751 if (type_vec->size()>0) {
13752 expr->preamble = mputc(expr->preamble, '(');
13753 // paramteres of the constructor are references to the objects used in the expression
13754 for (size_t i=0; i<refd_vec->size(); i++) {
13755 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13756 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
13757 }
13758 expr->preamble = mputc(expr->preamble, ')');
13759 }
13760 expr->preamble = mputstr(expr->preamble, ";\n");
13761 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13762 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
13763 }
13764
13765 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
13766 expression_struct ref_expr;
13767 Code::init_expr(&ref_expr);
13768 ref->generate_code(&ref_expr);
13769 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
13770 if (ref_expr.preamble) {
13771 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
13772 }
13773 Assignment* ass = ref->get_refd_assignment();
13774 // determine C++ type of the assignment
13775 string type_str;
13776 switch (ass->get_asstype()) {
13777 case Assignment::A_MODULEPAR_TEMP:
13778 case Assignment::A_TEMPLATE:
13779 case Assignment::A_VAR_TEMPLATE:
13780 case Assignment::A_PAR_TEMPL_IN:
13781 case Assignment::A_PAR_TEMPL_OUT:
13782 case Assignment::A_PAR_TEMPL_INOUT:
13783 type_str = ass->get_Type()->get_genname_template(scope);
13784 break;
13785 default:
13786 type_str = ass->get_Type()->get_genname_value(scope);
13787 }
13788 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13789 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
13790 if (ref_expr.postamble) {
13791 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
13792 }
13793 Code::free_expr(&ref_expr);
13794 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13795 }
13796
13797 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
13798 const string& lazy_param_id = value->get_temporary_id();
13799 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13800 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13801 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
13802 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13803 }
13804
13805 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
13806 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
13807 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13808 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13809 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
13810 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13811 }
13812
13813 } // namespace Common
This page took 0.329233 seconds and 6 git commands to generate.