Merge pull request #29 from BotondBaranyi/master
[deliverable/titan.core.git] / compiler2 / Value.cc
1 /******************************************************************************
2 * Copyright (c) 2000-2016 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 * Contributors:
9 * Baji, Laszlo
10 * Balasko, Jeno
11 * Baranyi, Botond
12 * Beres, Szabolcs
13 * Bibo, Zoltan
14 * Cserveni, Akos
15 * Delic, Adam
16 * Dimitrov, Peter
17 * Feher, Csaba
18 * Forstner, Matyas
19 * Gecse, Roland
20 * Kovacs, Ferenc
21 * Ormandi, Matyas
22 * Raduly, Csaba
23 * Szabados, Kristof
24 * Szabo, Janos Zoltan – initial implementation
25 * Szalai, Gabor
26 * Tatarka, Gabor
27 * Zalanyi, Balazs Andor
28 *
29 ******************************************************************************/
30 #include "../common/dbgnew.hh"
31 #include "Value.hh"
32 #include "Identifier.hh"
33 #include "Valuestuff.hh"
34 #include "PredefFunc.hh"
35 #include "CompField.hh"
36 #include "CompType.hh"
37 #include "EnumItem.hh"
38 #include "TypeCompat.hh"
39 #include "asn1/Block.hh"
40 #include "asn1/TokenBuf.hh"
41 #include "Real.hh"
42 #include "Int.hh"
43 #include "main.hh"
44 #include "Setting.hh"
45 #include "Type.hh"
46 #include "ttcn3/TtcnTemplate.hh"
47 #include "ttcn3/ArrayDimensions.hh"
48 #include "ustring.hh"
49 #include "../common/pattern.hh"
50
51 #include "ttcn3/PatternString.hh"
52 #include "ttcn3/Statement.hh"
53
54 #include "ttcn3/Attributes.hh"
55 #include "../common/JSON_Tokenizer.hh"
56 #include "ttcn3/Ttcn2Json.hh"
57
58 #include <math.h>
59 #include <regex.h>
60 #include <limits.h>
61
62 namespace Common {
63
64 static void clean_up_string_elements(map<size_t, Value>*& string_elements)
65 {
66 if (string_elements) {
67 for (size_t i = 0; i < string_elements->size(); i++)
68 delete string_elements->get_nth_elem(i);
69 string_elements->clear();
70 delete string_elements;
71 string_elements = 0;
72 }
73 }
74
75 // =================================
76 // ===== Value
77 // =================================
78
79 Value::Value(const Value& p)
80 : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
81 {
82 switch(valuetype) {
83 case V_ERROR:
84 case V_NULL:
85 case V_OMIT:
86 case V_TTCN3_NULL:
87 case V_DEFAULT_NULL:
88 case V_FAT_NULL:
89 case V_NOTUSED:
90 break;
91 case V_BOOL:
92 u.val_bool=p.u.val_bool;
93 break;
94 case V_INT:
95 u.val_Int=new int_val_t(*(p.u.val_Int));
96 break;
97 case V_NAMEDINT:
98 case V_ENUM:
99 case V_UNDEF_LOWERID:
100 u.val_id=p.u.val_id->clone();
101 break;
102 case V_REAL:
103 u.val_Real=p.u.val_Real;
104 break;
105 case V_BSTR:
106 case V_HSTR:
107 case V_OSTR:
108 case V_CSTR:
109 case V_ISO2022STR:
110 set_val_str(new string(*p.u.str.val_str));
111 break;
112 case V_USTR:
113 set_val_ustr(new ustring(*p.u.ustr.val_ustr));
114 u.ustr.convert_str = p.u.ustr.convert_str;
115 break;
116 case V_CHARSYMS:
117 u.char_syms = p.u.char_syms->clone();
118 break;
119 case V_OID:
120 case V_ROID:
121 u.oid_comps=new vector<OID_comp>;
122 for(size_t i=0; i<p.u.oid_comps->size(); i++)
123 add_oid_comp((*p.u.oid_comps)[i]->clone());
124 break;
125 case V_CHOICE:
126 u.choice.alt_name=p.u.choice.alt_name->clone();
127 u.choice.alt_value=p.u.choice.alt_value->clone();
128 break;
129 case V_SEQOF:
130 case V_SETOF:
131 case V_ARRAY:
132 u.val_vs=p.u.val_vs->clone();
133 break;
134 case V_SEQ:
135 case V_SET:
136 u.val_nvs=p.u.val_nvs->clone();
137 break;
138 case V_REFD:
139 u.ref.ref=p.u.ref.ref->clone();
140 u.ref.refd_last=0;
141 break;
142 case V_NAMEDBITS:
143 for(size_t i=0; i<p.u.ids->size(); i++) {
144 Identifier *id = p.u.ids->get_nth_elem(i);
145 u.ids->add(id->get_name(), id->clone());
146 }
147 break;
148 case V_UNDEF_BLOCK:
149 u.block=p.u.block->clone();
150 break;
151 case V_VERDICT:
152 u.verdict=p.u.verdict;
153 break;
154 case V_EXPR:
155 u.expr.v_optype = p.u.expr.v_optype;
156 u.expr.state = EXPR_NOT_CHECKED;
157 switch(u.expr.v_optype) {
158 case OPTYPE_RND: // -
159 case OPTYPE_COMP_NULL:
160 case OPTYPE_COMP_MTC:
161 case OPTYPE_COMP_SYSTEM:
162 case OPTYPE_COMP_SELF:
163 case OPTYPE_COMP_RUNNING_ANY:
164 case OPTYPE_COMP_RUNNING_ALL:
165 case OPTYPE_COMP_ALIVE_ANY:
166 case OPTYPE_COMP_ALIVE_ALL:
167 case OPTYPE_TMR_RUNNING_ANY:
168 case OPTYPE_GETVERDICT:
169 case OPTYPE_TESTCASENAME:
170 case OPTYPE_PROF_RUNNING:
171 break;
172 case OPTYPE_UNARYPLUS: // v1
173 case OPTYPE_UNARYMINUS:
174 case OPTYPE_NOT:
175 case OPTYPE_NOT4B:
176 case OPTYPE_BIT2HEX:
177 case OPTYPE_BIT2INT:
178 case OPTYPE_BIT2OCT:
179 case OPTYPE_BIT2STR:
180 case OPTYPE_CHAR2INT:
181 case OPTYPE_CHAR2OCT:
182 case OPTYPE_COMP_RUNNING:
183 case OPTYPE_COMP_ALIVE:
184 case OPTYPE_FLOAT2INT:
185 case OPTYPE_FLOAT2STR:
186 case OPTYPE_HEX2BIT:
187 case OPTYPE_HEX2INT:
188 case OPTYPE_HEX2OCT:
189 case OPTYPE_HEX2STR:
190 case OPTYPE_INT2CHAR:
191 case OPTYPE_INT2FLOAT:
192 case OPTYPE_INT2STR:
193 case OPTYPE_INT2UNICHAR:
194 case OPTYPE_OCT2BIT:
195 case OPTYPE_OCT2CHAR:
196 case OPTYPE_OCT2HEX:
197 case OPTYPE_OCT2INT:
198 case OPTYPE_OCT2STR:
199 case OPTYPE_STR2BIT:
200 case OPTYPE_STR2FLOAT:
201 case OPTYPE_STR2HEX:
202 case OPTYPE_STR2INT:
203 case OPTYPE_STR2OCT:
204 case OPTYPE_UNICHAR2INT:
205 case OPTYPE_UNICHAR2CHAR:
206 case OPTYPE_ENUM2INT:
207 case OPTYPE_RNDWITHVAL:
208 case OPTYPE_GET_STRINGENCODING:
209 case OPTYPE_DECODE_BASE64:
210 case OPTYPE_REMOVE_BOM:
211 u.expr.v1=p.u.expr.v1->clone();
212 break;
213 case OPTYPE_ADD: // v1 v2
214 case OPTYPE_SUBTRACT:
215 case OPTYPE_MULTIPLY:
216 case OPTYPE_DIVIDE:
217 case OPTYPE_MOD:
218 case OPTYPE_REM:
219 case OPTYPE_CONCAT:
220 case OPTYPE_EQ:
221 case OPTYPE_LT:
222 case OPTYPE_GT:
223 case OPTYPE_NE:
224 case OPTYPE_GE:
225 case OPTYPE_LE:
226 case OPTYPE_AND:
227 case OPTYPE_OR:
228 case OPTYPE_XOR:
229 case OPTYPE_AND4B:
230 case OPTYPE_OR4B:
231 case OPTYPE_XOR4B:
232 case OPTYPE_SHL:
233 case OPTYPE_SHR:
234 case OPTYPE_ROTL:
235 case OPTYPE_ROTR:
236 case OPTYPE_INT2BIT:
237 case OPTYPE_INT2HEX:
238 case OPTYPE_INT2OCT:
239 u.expr.v1=p.u.expr.v1->clone();
240 u.expr.v2=p.u.expr.v2->clone();
241 break;
242 case OPTYPE_UNICHAR2OCT: // v1 [v2]
243 case OPTYPE_OCT2UNICHAR:
244 case OPTYPE_ENCODE_BASE64:
245 u.expr.v1=p.u.expr.v1->clone();
246 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
247 break;
248 case OPTYPE_DECODE:
249 u.expr.r1=p.u.expr.r1->clone();
250 u.expr.r2=p.u.expr.r2->clone();
251 break;
252 case OPTYPE_SUBSTR:
253 u.expr.ti1=p.u.expr.ti1->clone();
254 u.expr.v2=p.u.expr.v2->clone();
255 u.expr.v3=p.u.expr.v3->clone();
256 break;
257 case OPTYPE_REGEXP:
258 u.expr.ti1=p.u.expr.ti1->clone();
259 u.expr.t2=p.u.expr.t2->clone();
260 u.expr.v3=p.u.expr.v3->clone();
261 break;
262 case OPTYPE_DECOMP: // v1 v2 v3
263 u.expr.v1=p.u.expr.v1->clone();
264 u.expr.v2=p.u.expr.v2->clone();
265 u.expr.v3=p.u.expr.v3->clone();
266 break;
267 case OPTYPE_REPLACE:
268 u.expr.ti1 = p.u.expr.ti1->clone();
269 u.expr.v2 = p.u.expr.v2->clone();
270 u.expr.v3 = p.u.expr.v3->clone();
271 u.expr.ti4 = p.u.expr.ti4->clone();
272 break;
273 case OPTYPE_LENGTHOF: // ti1
274 case OPTYPE_SIZEOF: // ti1
275 case OPTYPE_VALUEOF: // ti1
276 case OPTYPE_ENCODE:
277 case OPTYPE_ISPRESENT:
278 case OPTYPE_TTCN2STRING:
279 u.expr.ti1=p.u.expr.ti1->clone();
280 break;
281 case OPTYPE_UNDEF_RUNNING:
282 case OPTYPE_TMR_READ:
283 case OPTYPE_TMR_RUNNING:
284 case OPTYPE_ACTIVATE:
285 u.expr.r1=p.u.expr.r1->clone();
286 break;
287 case OPTYPE_EXECUTE: // r1 [v2]
288 u.expr.r1=p.u.expr.r1->clone();
289 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
290 break;
291 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
292 u.expr.r1=p.u.expr.r1->clone();
293 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
294 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
295 u.expr.b4 = p.u.expr.b4;
296 break;
297 case OPTYPE_MATCH: // v1 t2
298 u.expr.v1=p.u.expr.v1->clone();
299 u.expr.t2=p.u.expr.t2->clone();
300 break;
301 case OPTYPE_ISCHOSEN: // r1 i2
302 u.expr.r1=p.u.expr.r1->clone();
303 u.expr.i2=p.u.expr.i2->clone();
304 break;
305 case OPTYPE_ISCHOSEN_V: // v1 i2
306 u.expr.v1=p.u.expr.v1->clone();
307 u.expr.i2=p.u.expr.i2->clone();
308 break;
309 case OPTYPE_ISCHOSEN_T: // t1 i2
310 u.expr.t1=p.u.expr.t1->clone();
311 u.expr.i2=p.u.expr.i2->clone();
312 break;
313 case OPTYPE_ACTIVATE_REFD:
314 u.expr.v1 = p.u.expr.v1->clone();
315 if(p.u.expr.state!=EXPR_CHECKED)
316 u.expr.t_list2 = p.u.expr.t_list2->clone();
317 else {
318 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
319 u.expr.state = EXPR_CHECKED;
320 }
321 break;
322 case OPTYPE_EXECUTE_REFD:
323 u.expr.v1 = p.u.expr.v1->clone();
324 if(p.u.expr.state!=EXPR_CHECKED)
325 u.expr.t_list2 = p.u.expr.t_list2->clone();
326 else {
327 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
328 u.expr.state = EXPR_CHECKED;
329 }
330 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
331 break;
332 case OPTYPE_LOG2STR:
333 u.expr.logargs = p.u.expr.logargs->clone();
334 break;
335 default:
336 FATAL_ERROR("Value::Value()");
337 } // switch
338 break;
339 case V_MACRO:
340 u.macro = p.u.macro;
341 break;
342 case V_FUNCTION:
343 case V_ALTSTEP:
344 case V_TESTCASE:
345 u.refd_fat = p.u.refd_fat;
346 break;
347 case V_INVOKE:
348 u.invoke.v = p.u.invoke.v->clone();
349 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
350 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
351 break;
352 case V_REFER:
353 u.refered = p.u.refered->clone();
354 break;
355 default:
356 FATAL_ERROR("Value::Value()");
357 } // switch
358 }
359
360 void Value::clean_up()
361 {
362 switch (valuetype) {
363 case V_ERROR:
364 case V_NULL:
365 case V_BOOL:
366 case V_REAL:
367 case V_OMIT:
368 case V_VERDICT:
369 case V_TTCN3_NULL:
370 case V_DEFAULT_NULL:
371 case V_FAT_NULL:
372 case V_MACRO:
373 case V_NOTUSED:
374 case V_FUNCTION:
375 case V_ALTSTEP:
376 case V_TESTCASE:
377 break;
378 case V_INT:
379 delete u.val_Int;
380 break;
381 case V_NAMEDINT:
382 case V_ENUM:
383 case V_UNDEF_LOWERID:
384 delete u.val_id;
385 break;
386 case V_BSTR:
387 case V_HSTR:
388 case V_OSTR:
389 case V_CSTR:
390 case V_ISO2022STR:
391 delete u.str.val_str;
392 clean_up_string_elements(u.str.str_elements);
393 break;
394 case V_USTR:
395 delete u.ustr.val_ustr;
396 clean_up_string_elements(u.ustr.ustr_elements);
397 break;
398 case V_CHARSYMS:
399 delete u.char_syms;
400 break;
401 case V_OID:
402 case V_ROID:
403 if (u.oid_comps) {
404 for(size_t i=0; i<u.oid_comps->size(); i++)
405 delete (*u.oid_comps)[i];
406 u.oid_comps->clear();
407 delete u.oid_comps;
408 }
409 break;
410 case V_EXPR:
411 clean_up_expr();
412 break;
413 case V_CHOICE:
414 delete u.choice.alt_name;
415 delete u.choice.alt_value;
416 break;
417 case V_SEQOF:
418 case V_SETOF:
419 case V_ARRAY:
420 delete u.val_vs;
421 break;
422 case V_SEQ:
423 case V_SET:
424 delete u.val_nvs;
425 break;
426 case V_REFD:
427 delete u.ref.ref;
428 break;
429 case V_REFER:
430 delete u.refered;
431 break;
432 case V_INVOKE:
433 delete u.invoke.v;
434 delete u.invoke.t_list;
435 delete u.invoke.ap_list;
436 break;
437 case V_NAMEDBITS:
438 if(u.ids) {
439 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
440 u.ids->clear();
441 delete u.ids;
442 }
443 break;
444 case V_UNDEF_BLOCK:
445 delete u.block;
446 break;
447 default:
448 FATAL_ERROR("Value::clean_up()");
449 } // switch
450 }
451
452 void Value::clean_up_expr()
453 {
454 switch (u.expr.state) {
455 case EXPR_CHECKING:
456 case EXPR_CHECKING_ERR:
457 FATAL_ERROR("Value::clean_up_expr()");
458 default:
459 break;
460 }
461 switch (u.expr.v_optype) {
462 case OPTYPE_RND: // -
463 case OPTYPE_COMP_NULL:
464 case OPTYPE_COMP_MTC:
465 case OPTYPE_COMP_SYSTEM:
466 case OPTYPE_COMP_SELF:
467 case OPTYPE_COMP_RUNNING_ANY:
468 case OPTYPE_COMP_RUNNING_ALL:
469 case OPTYPE_COMP_ALIVE_ANY:
470 case OPTYPE_COMP_ALIVE_ALL:
471 case OPTYPE_TMR_RUNNING_ANY:
472 case OPTYPE_GETVERDICT:
473 case OPTYPE_TESTCASENAME:
474 case OPTYPE_PROF_RUNNING:
475 break;
476 case OPTYPE_UNARYPLUS: // v1
477 case OPTYPE_UNARYMINUS:
478 case OPTYPE_NOT:
479 case OPTYPE_NOT4B:
480 case OPTYPE_BIT2HEX:
481 case OPTYPE_BIT2INT:
482 case OPTYPE_BIT2OCT:
483 case OPTYPE_BIT2STR:
484 case OPTYPE_CHAR2INT:
485 case OPTYPE_CHAR2OCT:
486 case OPTYPE_COMP_RUNNING:
487 case OPTYPE_COMP_ALIVE:
488 case OPTYPE_FLOAT2INT:
489 case OPTYPE_FLOAT2STR:
490 case OPTYPE_HEX2BIT:
491 case OPTYPE_HEX2INT:
492 case OPTYPE_HEX2OCT:
493 case OPTYPE_HEX2STR:
494 case OPTYPE_INT2CHAR:
495 case OPTYPE_INT2FLOAT:
496 case OPTYPE_INT2STR:
497 case OPTYPE_INT2UNICHAR:
498 case OPTYPE_OCT2BIT:
499 case OPTYPE_OCT2CHAR:
500 case OPTYPE_OCT2HEX:
501 case OPTYPE_OCT2INT:
502 case OPTYPE_OCT2STR:
503 case OPTYPE_STR2BIT:
504 case OPTYPE_STR2FLOAT:
505 case OPTYPE_STR2HEX:
506 case OPTYPE_STR2INT:
507 case OPTYPE_STR2OCT:
508 case OPTYPE_UNICHAR2INT:
509 case OPTYPE_UNICHAR2CHAR:
510 case OPTYPE_ENUM2INT:
511 case OPTYPE_RNDWITHVAL:
512 case OPTYPE_REMOVE_BOM:
513 case OPTYPE_GET_STRINGENCODING:
514 case OPTYPE_DECODE_BASE64:
515 delete u.expr.v1;
516 break;
517 case OPTYPE_ADD: // v1 v2
518 case OPTYPE_SUBTRACT:
519 case OPTYPE_MULTIPLY:
520 case OPTYPE_DIVIDE:
521 case OPTYPE_MOD:
522 case OPTYPE_REM:
523 case OPTYPE_CONCAT:
524 case OPTYPE_EQ:
525 case OPTYPE_LT:
526 case OPTYPE_GT:
527 case OPTYPE_NE:
528 case OPTYPE_GE:
529 case OPTYPE_LE:
530 case OPTYPE_AND:
531 case OPTYPE_OR:
532 case OPTYPE_XOR:
533 case OPTYPE_AND4B:
534 case OPTYPE_OR4B:
535 case OPTYPE_XOR4B:
536 case OPTYPE_SHL:
537 case OPTYPE_SHR:
538 case OPTYPE_ROTL:
539 case OPTYPE_ROTR:
540 case OPTYPE_INT2BIT:
541 case OPTYPE_INT2HEX:
542 case OPTYPE_INT2OCT:
543 case OPTYPE_UNICHAR2OCT:
544 case OPTYPE_OCT2UNICHAR:
545 case OPTYPE_ENCODE_BASE64:
546 delete u.expr.v1;
547 delete u.expr.v2;
548 break;
549 case OPTYPE_DECODE:
550 delete u.expr.r1;
551 delete u.expr.r2;
552 break;
553 case OPTYPE_SUBSTR:
554 delete u.expr.ti1;
555 delete u.expr.v2;
556 delete u.expr.v3;
557 break;
558 case OPTYPE_REGEXP:
559 delete u.expr.ti1;
560 delete u.expr.t2;
561 delete u.expr.v3;
562 break;
563 case OPTYPE_DECOMP: // v1 v2 v3
564 delete u.expr.v1;
565 delete u.expr.v2;
566 delete u.expr.v3;
567 break;
568 case OPTYPE_REPLACE:
569 delete u.expr.ti1;
570 delete u.expr.v2;
571 delete u.expr.v3;
572 delete u.expr.ti4;
573 break;
574 case OPTYPE_LENGTHOF: // ti1
575 case OPTYPE_SIZEOF: // ti1
576 case OPTYPE_VALUEOF: // ti1
577 case OPTYPE_ISVALUE:
578 case OPTYPE_ISBOUND:
579 case OPTYPE_ENCODE:
580 case OPTYPE_ISPRESENT:
581 case OPTYPE_TTCN2STRING:
582 delete u.expr.ti1;
583 break;
584 case OPTYPE_UNDEF_RUNNING:
585 case OPTYPE_TMR_READ:
586 case OPTYPE_TMR_RUNNING:
587 case OPTYPE_ACTIVATE:
588 delete u.expr.r1;
589 break;
590 case OPTYPE_EXECUTE: // r1 [v2]
591 delete u.expr.r1;
592 delete u.expr.v2;
593 break;
594 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
595 delete u.expr.r1;
596 delete u.expr.v2;
597 delete u.expr.v3;
598 break;
599 case OPTYPE_MATCH: // v1 t2
600 delete u.expr.v1;
601 delete u.expr.t2;
602 break;
603 case OPTYPE_ISCHOSEN: // r1 i2
604 delete u.expr.r1;
605 delete u.expr.i2;
606 break;
607 case OPTYPE_ISCHOSEN_V: // v1 i2
608 delete u.expr.v1;
609 delete u.expr.i2;
610 break;
611 case OPTYPE_ISCHOSEN_T: // t1 i2
612 delete u.expr.t1;
613 delete u.expr.i2;
614 break;
615 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
616 delete u.expr.v1;
617 if(u.expr.state!=EXPR_CHECKED)
618 delete u.expr.t_list2;
619 else
620 delete u.expr.ap_list2;
621 break;
622 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
623 delete u.expr.v1;
624 if(u.expr.state!=EXPR_CHECKED)
625 delete u.expr.t_list2;
626 else
627 delete u.expr.ap_list2;
628 delete u.expr.v3;
629 break;
630 case OPTYPE_LOG2STR:
631 delete u.expr.logargs;
632 break;
633 default:
634 FATAL_ERROR("Value::clean_up_expr()");
635 } // switch
636 }
637
638 void Value::copy_and_destroy(Value *src)
639 {
640 clean_up();
641 valuetype = src->valuetype;
642 u = src->u;
643 // update the pointer used for caching if it points to the value itself
644 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
645 src->valuetype = V_ERROR;
646 delete src;
647 }
648
649 Value::Value(valuetype_t p_vt)
650 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
651 {
652 switch(valuetype) {
653 case V_NULL:
654 case V_TTCN3_NULL:
655 case V_OMIT:
656 case V_NOTUSED:
657 case V_ERROR:
658 break;
659 case V_OID:
660 case V_ROID:
661 u.oid_comps=new vector<OID_comp>();
662 break;
663 case V_NAMEDBITS:
664 u.ids=new map<string, Identifier>();
665 break;
666 default:
667 FATAL_ERROR("Value::Value()");
668 } // switch
669 }
670
671 Value::Value(valuetype_t p_vt, bool p_val_bool)
672 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
673 {
674 switch(valuetype) {
675 case V_BOOL:
676 u.val_bool=p_val_bool;
677 break;
678 default:
679 FATAL_ERROR("Value::Value()");
680 } // switch
681 }
682
683 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
684 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
685 {
686 switch(valuetype) {
687 case V_INT:
688 u.val_Int=new int_val_t(p_val_Int);
689 break;
690 default:
691 FATAL_ERROR("Value::Value()");
692 } // switch
693 }
694
695 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
696 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
697 {
698 switch(valuetype){
699 case V_INT:
700 u.val_Int=p_val_Int;
701 break;
702 default:
703 FATAL_ERROR("Value::Value()");
704 }
705 }
706
707 Value::Value(valuetype_t p_vt, string *p_val_str)
708 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
709 {
710 if(!p_val_str) FATAL_ERROR("NULL parameter");
711 switch(valuetype) {
712 case V_BSTR:
713 case V_HSTR:
714 case V_OSTR:
715 case V_CSTR:
716 case V_ISO2022STR:
717 set_val_str(p_val_str);
718 break;
719 default:
720 FATAL_ERROR("Value::Value()");
721 } // switch
722 }
723
724 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
725 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
726 {
727 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
728 set_val_ustr(p_val_ustr);
729 u.ustr.convert_str = false;
730 }
731
732 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
733 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
734 {
735 if (!p_char_syms) FATAL_ERROR("NULL parameter");
736 switch (valuetype) {
737 case V_CHARSYMS:
738 u.char_syms = p_char_syms;
739 break;
740 default:
741 FATAL_ERROR("Value::Value()");
742 } // switch
743 }
744
745 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
746 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
747 {
748 if(!p_val_id)
749 FATAL_ERROR("NULL parameter");
750 switch(valuetype) {
751 case V_NAMEDINT:
752 case V_ENUM:
753 case V_UNDEF_LOWERID:
754 u.val_id=p_val_id;
755 break;
756 default:
757 FATAL_ERROR("Value::Value()");
758 } // switch
759 }
760
761 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
762 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
763 {
764 if(!p_id || !p_val)
765 FATAL_ERROR("NULL parameter");
766 switch(valuetype) {
767 case V_CHOICE:
768 u.choice.alt_name=p_id;
769 u.choice.alt_value=p_val;
770 break;
771 default:
772 FATAL_ERROR("Value::Value()");
773 } // switch
774 }
775
776 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
777 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
778 {
779 switch(valuetype) {
780 case V_REAL:
781 u.val_Real=p_val_Real;
782 break;
783 default:
784 FATAL_ERROR("Value::Value()");
785 } // switch
786 }
787
788 Value::Value(valuetype_t p_vt, Values *p_vs)
789 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
790 {
791 if(!p_vs) FATAL_ERROR("NULL parameter");
792 switch(valuetype) {
793 case V_SEQOF:
794 case V_SETOF:
795 case V_ARRAY:
796 u.val_vs=p_vs;
797 break;
798 default:
799 FATAL_ERROR("Value::Value()");
800 } // switch
801 }
802
803 Value::Value(valuetype_t p_vt, Value *p_v,
804 Ttcn::ParsedActualParameters *p_t_list)
805 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
806 {
807 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
808 switch(valuetype) {
809 case V_INVOKE:
810 u.invoke.v = p_v;
811 u.invoke.t_list = p_t_list;
812 u.invoke.ap_list = 0;
813 break;
814 default:
815 FATAL_ERROR("Value::Value()");
816 }
817 }
818
819 // -
820 Value::Value(operationtype_t p_optype)
821 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
822 {
823 u.expr.v_optype = p_optype;
824 u.expr.state = EXPR_NOT_CHECKED;
825 switch(p_optype) {
826 case OPTYPE_RND:
827 case OPTYPE_COMP_NULL:
828 case OPTYPE_COMP_MTC:
829 case OPTYPE_COMP_SYSTEM:
830 case OPTYPE_COMP_SELF:
831 case OPTYPE_COMP_RUNNING_ANY:
832 case OPTYPE_COMP_RUNNING_ALL:
833 case OPTYPE_COMP_ALIVE_ANY:
834 case OPTYPE_COMP_ALIVE_ALL:
835 case OPTYPE_TMR_RUNNING_ANY:
836 case OPTYPE_GETVERDICT:
837 case OPTYPE_TESTCASENAME:
838 case OPTYPE_PROF_RUNNING:
839 break;
840 default:
841 FATAL_ERROR("Value::Value()");
842 } // switch
843 }
844
845 // v1
846 Value::Value(operationtype_t p_optype, Value *p_v1)
847 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
848 {
849 u.expr.v_optype = p_optype;
850 u.expr.state = EXPR_NOT_CHECKED;
851 switch(p_optype) {
852 case OPTYPE_UNARYPLUS:
853 case OPTYPE_UNARYMINUS:
854 case OPTYPE_NOT:
855 case OPTYPE_NOT4B:
856 case OPTYPE_BIT2HEX:
857 case OPTYPE_BIT2INT:
858 case OPTYPE_BIT2OCT:
859 case OPTYPE_BIT2STR:
860 case OPTYPE_CHAR2INT:
861 case OPTYPE_CHAR2OCT:
862 case OPTYPE_COMP_RUNNING:
863 case OPTYPE_COMP_ALIVE:
864 case OPTYPE_FLOAT2INT:
865 case OPTYPE_FLOAT2STR:
866 case OPTYPE_HEX2BIT:
867 case OPTYPE_HEX2INT:
868 case OPTYPE_HEX2OCT:
869 case OPTYPE_HEX2STR:
870 case OPTYPE_INT2CHAR:
871 case OPTYPE_INT2FLOAT:
872 case OPTYPE_INT2STR:
873 case OPTYPE_INT2UNICHAR:
874 case OPTYPE_OCT2BIT:
875 case OPTYPE_OCT2CHAR:
876 case OPTYPE_OCT2HEX:
877 case OPTYPE_OCT2INT:
878 case OPTYPE_OCT2STR:
879 case OPTYPE_STR2BIT:
880 case OPTYPE_STR2FLOAT:
881 case OPTYPE_STR2HEX:
882 case OPTYPE_STR2INT:
883 case OPTYPE_STR2OCT:
884 case OPTYPE_UNICHAR2INT:
885 case OPTYPE_UNICHAR2CHAR:
886 case OPTYPE_ENUM2INT:
887 case OPTYPE_RNDWITHVAL:
888 case OPTYPE_REMOVE_BOM:
889 case OPTYPE_GET_STRINGENCODING:
890 case OPTYPE_DECODE_BASE64:
891 if(!p_v1) FATAL_ERROR("Value::Value()");
892 u.expr.v1=p_v1;
893 break;
894 default:
895 FATAL_ERROR("Value::Value()");
896 } // switch
897 }
898
899 // ti1
900 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
901 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
902 {
903 u.expr.v_optype = p_optype;
904 u.expr.state = EXPR_NOT_CHECKED;
905 switch(p_optype) {
906 case OPTYPE_LENGTHOF:
907 case OPTYPE_SIZEOF:
908 case OPTYPE_VALUEOF:
909 case OPTYPE_ISVALUE:
910 case OPTYPE_ISBOUND:
911 case OPTYPE_ENCODE:
912 case OPTYPE_ISPRESENT:
913 case OPTYPE_TTCN2STRING:
914 if(!p_ti1) FATAL_ERROR("Value::Value()");
915 u.expr.ti1=p_ti1;
916 break;
917 default:
918 FATAL_ERROR("Value::Value()");
919 } // switch
920 }
921
922 // r1
923 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
924 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
925 {
926 u.expr.v_optype = p_optype;
927 u.expr.state = EXPR_NOT_CHECKED;
928 switch(p_optype) {
929 case OPTYPE_UNDEF_RUNNING:
930 case OPTYPE_TMR_READ:
931 case OPTYPE_TMR_RUNNING:
932 case OPTYPE_ACTIVATE:
933 if(!p_r1) FATAL_ERROR("Value::Value()");
934 u.expr.r1=p_r1;
935 break;
936 default:
937 FATAL_ERROR("Value::Value()");
938 } // switch
939 }
940
941 // v1 t_list2
942 Value::Value(operationtype_t p_optype, Value *p_v1,
943 Ttcn::ParsedActualParameters *p_ap_list)
944 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
945 {
946 u.expr.v_optype = p_optype;
947 u.expr.state = EXPR_NOT_CHECKED;
948 switch(p_optype) {
949 case OPTYPE_ACTIVATE_REFD:
950 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
951 u.expr.v1 = p_v1;
952 u.expr.t_list2 = p_ap_list;
953 break;
954 default:
955 FATAL_ERROR("Value::Value()");
956 }
957 }
958
959 //v1 t_list2 v3
960 Value::Value(operationtype_t p_optype, Value *p_v1,
961 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
962 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
963 {
964 u.expr.v_optype = p_optype;
965 u.expr.state = EXPR_NOT_CHECKED;
966 switch(p_optype) {
967 case OPTYPE_EXECUTE_REFD:
968 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
969 u.expr.v1 = p_v1;
970 u.expr.t_list2 = p_t_list2;
971 u.expr.v3 = p_v3;
972 break;
973 default:
974 FATAL_ERROR("Value::Value()");
975 }
976 }
977
978 // r1 [v2]
979 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
980 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
981 {
982 u.expr.v_optype = p_optype;
983 u.expr.state = EXPR_NOT_CHECKED;
984 switch(p_optype) {
985 case OPTYPE_EXECUTE:
986 if(!p_r1) FATAL_ERROR("Value::Value()");
987 u.expr.r1=p_r1;
988 u.expr.v2=p_v2;
989 break;
990 default:
991 FATAL_ERROR("Value::Value()");
992 } // switch
993 }
994
995 // r1 [v2] [v3] b4
996 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
997 Value *p_v2, Value *p_v3, bool p_b4)
998 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
999 {
1000 u.expr.v_optype = p_optype;
1001 u.expr.state = EXPR_NOT_CHECKED;
1002 switch(p_optype) {
1003 case OPTYPE_COMP_CREATE:
1004 if(!p_r1) FATAL_ERROR("Value::Value()");
1005 u.expr.r1=p_r1;
1006 u.expr.v2=p_v2;
1007 u.expr.v3=p_v3;
1008 u.expr.b4=p_b4;
1009 break;
1010 default:
1011 FATAL_ERROR("Value::Value()");
1012 } // switch
1013 }
1014
1015 // v1 v2
1016 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
1017 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1018 {
1019 u.expr.v_optype = p_optype;
1020 u.expr.state = EXPR_NOT_CHECKED;
1021 switch(p_optype) {
1022 case OPTYPE_ADD:
1023 case OPTYPE_SUBTRACT:
1024 case OPTYPE_MULTIPLY:
1025 case OPTYPE_DIVIDE:
1026 case OPTYPE_MOD:
1027 case OPTYPE_REM:
1028 case OPTYPE_CONCAT:
1029 case OPTYPE_EQ:
1030 case OPTYPE_LT:
1031 case OPTYPE_GT:
1032 case OPTYPE_NE:
1033 case OPTYPE_GE:
1034 case OPTYPE_LE:
1035 case OPTYPE_AND:
1036 case OPTYPE_OR:
1037 case OPTYPE_XOR:
1038 case OPTYPE_AND4B:
1039 case OPTYPE_OR4B:
1040 case OPTYPE_XOR4B:
1041 case OPTYPE_SHL:
1042 case OPTYPE_SHR:
1043 case OPTYPE_ROTL:
1044 case OPTYPE_ROTR:
1045 case OPTYPE_INT2BIT:
1046 case OPTYPE_INT2HEX:
1047 case OPTYPE_INT2OCT:
1048 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1049 u.expr.v1=p_v1;
1050 u.expr.v2=p_v2;
1051 break;
1052 case OPTYPE_UNICHAR2OCT:
1053 case OPTYPE_OCT2UNICHAR:
1054 case OPTYPE_ENCODE_BASE64:
1055 if(!p_v1) FATAL_ERROR("Value::Value()");
1056 u.expr.v1=p_v1;
1057 // p_v2 may be NULL if there is no second param
1058 u.expr.v2=p_v2;
1059 break;
1060 default:
1061 FATAL_ERROR("Value::Value()");
1062 } // switch
1063 }
1064
1065 // ti1 v2 v3 ti4
1066 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1067 Value *p_v3, TemplateInstance *p_ti4) :
1068 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1069 {
1070 u.expr.v_optype = p_optype;
1071 u.expr.state = EXPR_NOT_CHECKED;
1072 switch (p_optype) {
1073 case OPTYPE_REPLACE:
1074 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1075 u.expr.ti1 = p_ti1;
1076 u.expr.v2 = p_v2;
1077 u.expr.v3 = p_v3;
1078 u.expr.ti4 = p_ti4;
1079 break;
1080 default:
1081 FATAL_ERROR("Value::Value()");
1082 } // switch
1083 }
1084
1085 // v1 v2 v3
1086 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1087 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1088 {
1089 u.expr.v_optype = p_optype;
1090 u.expr.state = EXPR_NOT_CHECKED;
1091 switch(p_optype) {
1092 case OPTYPE_DECOMP:
1093 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1094 u.expr.v1=p_v1;
1095 u.expr.v2=p_v2;
1096 u.expr.v3=p_v3;
1097 break;
1098 default:
1099 FATAL_ERROR("Value::Value()");
1100 } // switch
1101 }
1102
1103 // ti1 v2 v3
1104 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1105 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1106 {
1107 u.expr.v_optype=p_optype;
1108 u.expr.state=EXPR_NOT_CHECKED;
1109 switch(p_optype) {
1110 case OPTYPE_SUBSTR:
1111 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1112 u.expr.ti1 = p_ti1;
1113 u.expr.v2=p_v2;
1114 u.expr.v3=p_v3;
1115 break;
1116 default:
1117 FATAL_ERROR("Value::Value()");
1118 } // switch
1119 }
1120
1121 // ti1 t2 v3
1122 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1123 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1124 {
1125 u.expr.v_optype=p_optype;
1126 u.expr.state=EXPR_NOT_CHECKED;
1127 switch(p_optype) {
1128 case OPTYPE_REGEXP:
1129 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1130 u.expr.ti1 = p_ti1;
1131 u.expr.t2 = p_t2;
1132 u.expr.v3=p_v3;
1133 break;
1134 default:
1135 FATAL_ERROR("Value::Value()");
1136 } // switch
1137 }
1138
1139 // v1 t2
1140 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1141 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1142 {
1143 u.expr.v_optype = p_optype;
1144 u.expr.state = EXPR_NOT_CHECKED;
1145 switch(p_optype) {
1146 case OPTYPE_MATCH:
1147 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1148 u.expr.v1=p_v1;
1149 u.expr.t2=p_t2;
1150 break;
1151 default:
1152 FATAL_ERROR("Value::Value()");
1153 } // switch
1154 }
1155
1156 // r1 i2
1157 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1158 Identifier *p_i2)
1159 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1160 {
1161 u.expr.v_optype = p_optype;
1162 u.expr.state = EXPR_NOT_CHECKED;
1163 switch(p_optype) {
1164 case OPTYPE_ISCHOSEN:
1165 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1166 u.expr.r1=p_r1;
1167 u.expr.i2=p_i2;
1168 break;
1169 default:
1170 FATAL_ERROR("Value::Value()");
1171 } // switch
1172 }
1173
1174 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1175 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1176 {
1177 u.expr.v_optype = p_optype;
1178 u.expr.state = EXPR_NOT_CHECKED;
1179 switch(p_optype) {
1180 case OPTYPE_LOG2STR:
1181 if (!p_logargs) FATAL_ERROR("Value::Value()");
1182 u.expr.logargs = p_logargs;
1183 break;
1184 default:
1185 FATAL_ERROR("Value::Value()");
1186 } // switch
1187 }
1188
1189 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1190 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1191 {
1192 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1193 switch (p_macrotype) {
1194 case MACRO_MODULEID:
1195 case MACRO_FILENAME:
1196 case MACRO_BFILENAME:
1197 case MACRO_FILEPATH:
1198 case MACRO_LINENUMBER:
1199 case MACRO_LINENUMBER_C:
1200 case MACRO_DEFINITIONID:
1201 case MACRO_SCOPE:
1202 case MACRO_TESTCASEID:
1203 break;
1204 default:
1205 FATAL_ERROR("Value::Value()");
1206 }
1207 u.macro = p_macrotype;
1208 }
1209
1210 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1211 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1212 {
1213 if(!p_nvs) FATAL_ERROR("NULL parameter");
1214 switch(valuetype) {
1215 case V_SEQ:
1216 case V_SET:
1217 u.val_nvs=p_nvs;
1218 break;
1219 default:
1220 FATAL_ERROR("Value::Value()");
1221 } // switch
1222 }
1223
1224 Value::Value(valuetype_t p_vt, Reference *p_ref)
1225 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1226 {
1227 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1228 switch(p_vt) {
1229 case V_REFD:
1230 u.ref.ref = p_ref;
1231 u.ref.refd_last = 0;
1232 break;
1233 case V_REFER:
1234 u.refered = p_ref;
1235 break;
1236 default:
1237 FATAL_ERROR("Value::Value()");
1238 }
1239 }
1240
1241 Value::Value(valuetype_t p_vt, Block *p_block)
1242 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1243 {
1244 if(!p_block) FATAL_ERROR("NULL parameter");
1245 switch(valuetype) {
1246 case V_UNDEF_BLOCK:
1247 u.block=p_block;
1248 break;
1249 default:
1250 FATAL_ERROR("Value::Value()");
1251 } // switch
1252 }
1253
1254 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1255 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1256 {
1257 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1258 switch (p_verdict) {
1259 case Verdict_NONE:
1260 case Verdict_PASS:
1261 case Verdict_INCONC:
1262 case Verdict_FAIL:
1263 case Verdict_ERROR:
1264 break;
1265 default:
1266 FATAL_ERROR("Value::Value()");
1267 } // switch
1268 u.verdict = p_verdict;
1269 }
1270
1271 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1272 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1273 {
1274 u.expr.v_optype = p_optype;
1275 u.expr.state = EXPR_NOT_CHECKED;
1276 switch(p_optype) {
1277 case OPTYPE_DECODE:
1278 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1279 u.expr.r1=p_r1;
1280 u.expr.r2=p_r2;
1281 break;
1282 default:
1283 FATAL_ERROR("Value::Value()");
1284 } // switch
1285 }
1286
1287 Value::~Value()
1288 {
1289 clean_up();
1290 }
1291
1292 Value *Value::clone() const
1293 {
1294 return new Value(*this);
1295 }
1296
1297 Value::operationtype_t Value::get_optype() const
1298 {
1299 if(valuetype!=V_EXPR)
1300 FATAL_ERROR("Value::get_optype()");
1301 return u.expr.v_optype;
1302 }
1303
1304 void Value::set_my_governor(Type *p_gov)
1305 {
1306 if(!p_gov)
1307 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1308 my_governor=p_gov;
1309 }
1310
1311 Type *Value::get_my_governor() const
1312 {
1313 return my_governor;
1314 }
1315
1316 void Value::set_fullname(const string& p_fullname)
1317 {
1318 GovernedSimple::set_fullname(p_fullname);
1319 switch(valuetype) {
1320 case V_CHARSYMS:
1321 u.char_syms->set_fullname(p_fullname);
1322 break;
1323 case V_OID:
1324 case V_ROID:
1325 for(size_t i=0; i<u.oid_comps->size(); i++)
1326 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1327 break;
1328 case V_CHOICE:
1329 u.choice.alt_value->set_fullname(p_fullname + "." +
1330 u.choice.alt_name->get_dispname());
1331 break;
1332 case V_SEQOF:
1333 case V_SETOF:
1334 case V_ARRAY:
1335 u.val_vs->set_fullname(p_fullname);
1336 break;
1337 case V_SEQ:
1338 case V_SET:
1339 u.val_nvs->set_fullname(p_fullname);
1340 break;
1341 case V_REFD:
1342 u.ref.ref->set_fullname(p_fullname);
1343 break;
1344 case V_REFER:
1345 u.refered->set_fullname(p_fullname);
1346 break;
1347 case V_INVOKE:
1348 u.invoke.v->set_fullname(p_fullname);
1349 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1350 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1351 break;
1352 case V_EXPR:
1353 set_fullname_expr(p_fullname);
1354 break;
1355 default:
1356 break;
1357 } // switch
1358 }
1359
1360 void Value::set_my_scope(Scope *p_scope)
1361 {
1362 GovernedSimple::set_my_scope(p_scope);
1363 switch(valuetype) {
1364 case V_CHARSYMS:
1365 u.char_syms->set_my_scope(p_scope);
1366 break;
1367 case V_OID:
1368 case V_ROID:
1369 for(size_t i=0; i<u.oid_comps->size(); i++)
1370 (*u.oid_comps)[i]->set_my_scope(p_scope);
1371 break;
1372 case V_CHOICE:
1373 u.choice.alt_value->set_my_scope(p_scope);
1374 break;
1375 case V_SEQOF:
1376 case V_SETOF:
1377 case V_ARRAY:
1378 u.val_vs->set_my_scope(p_scope);
1379 break;
1380 case V_SEQ:
1381 case V_SET:
1382 u.val_nvs->set_my_scope(p_scope);
1383 break;
1384 case V_REFD:
1385 u.ref.ref->set_my_scope(p_scope);
1386 break;
1387 case V_REFER:
1388 u.refered->set_my_scope(p_scope);
1389 break;
1390 case V_INVOKE:
1391 u.invoke.v->set_my_scope(p_scope);
1392 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1393 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1394 break;
1395 case V_EXPR:
1396 set_my_scope_expr(p_scope);
1397 break;
1398 default:
1399 break;
1400 } // switch
1401 }
1402
1403 void Value::set_fullname_expr(const string& p_fullname)
1404 {
1405 switch (u.expr.v_optype) {
1406 case OPTYPE_RND: // -
1407 case OPTYPE_COMP_NULL:
1408 case OPTYPE_COMP_MTC:
1409 case OPTYPE_COMP_SYSTEM:
1410 case OPTYPE_COMP_SELF:
1411 case OPTYPE_COMP_RUNNING_ANY:
1412 case OPTYPE_COMP_RUNNING_ALL:
1413 case OPTYPE_COMP_ALIVE_ANY:
1414 case OPTYPE_COMP_ALIVE_ALL:
1415 case OPTYPE_TMR_RUNNING_ANY:
1416 case OPTYPE_GETVERDICT:
1417 case OPTYPE_TESTCASENAME:
1418 case OPTYPE_PROF_RUNNING:
1419 break;
1420 case OPTYPE_UNARYPLUS: // v1
1421 case OPTYPE_UNARYMINUS:
1422 case OPTYPE_NOT:
1423 case OPTYPE_NOT4B:
1424 case OPTYPE_BIT2HEX:
1425 case OPTYPE_BIT2INT:
1426 case OPTYPE_BIT2OCT:
1427 case OPTYPE_BIT2STR:
1428 case OPTYPE_CHAR2INT:
1429 case OPTYPE_CHAR2OCT:
1430 case OPTYPE_COMP_RUNNING:
1431 case OPTYPE_COMP_ALIVE:
1432 case OPTYPE_FLOAT2INT:
1433 case OPTYPE_FLOAT2STR:
1434 case OPTYPE_HEX2BIT:
1435 case OPTYPE_HEX2INT:
1436 case OPTYPE_HEX2OCT:
1437 case OPTYPE_HEX2STR:
1438 case OPTYPE_INT2CHAR:
1439 case OPTYPE_INT2FLOAT:
1440 case OPTYPE_INT2STR:
1441 case OPTYPE_INT2UNICHAR:
1442 case OPTYPE_OCT2BIT:
1443 case OPTYPE_OCT2CHAR:
1444 case OPTYPE_OCT2HEX:
1445 case OPTYPE_OCT2INT:
1446 case OPTYPE_OCT2STR:
1447 case OPTYPE_STR2BIT:
1448 case OPTYPE_STR2FLOAT:
1449 case OPTYPE_STR2HEX:
1450 case OPTYPE_STR2INT:
1451 case OPTYPE_STR2OCT:
1452 case OPTYPE_UNICHAR2INT:
1453 case OPTYPE_UNICHAR2CHAR:
1454 case OPTYPE_ENUM2INT:
1455 case OPTYPE_RNDWITHVAL:
1456 case OPTYPE_REMOVE_BOM:
1457 case OPTYPE_GET_STRINGENCODING:
1458 case OPTYPE_DECODE_BASE64:
1459 u.expr.v1->set_fullname(p_fullname+".<operand>");
1460 break;
1461 case OPTYPE_ADD: // v1 v2
1462 case OPTYPE_SUBTRACT:
1463 case OPTYPE_MULTIPLY:
1464 case OPTYPE_DIVIDE:
1465 case OPTYPE_MOD:
1466 case OPTYPE_REM:
1467 case OPTYPE_CONCAT:
1468 case OPTYPE_EQ:
1469 case OPTYPE_LT:
1470 case OPTYPE_GT:
1471 case OPTYPE_NE:
1472 case OPTYPE_GE:
1473 case OPTYPE_LE:
1474 case OPTYPE_AND:
1475 case OPTYPE_OR:
1476 case OPTYPE_XOR:
1477 case OPTYPE_AND4B:
1478 case OPTYPE_OR4B:
1479 case OPTYPE_XOR4B:
1480 case OPTYPE_SHL:
1481 case OPTYPE_SHR:
1482 case OPTYPE_ROTL:
1483 case OPTYPE_ROTR:
1484 case OPTYPE_INT2BIT:
1485 case OPTYPE_INT2HEX:
1486 case OPTYPE_INT2OCT:
1487 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1488 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1489 break;
1490 case OPTYPE_UNICHAR2OCT:
1491 case OPTYPE_OCT2UNICHAR:
1492 case OPTYPE_ENCODE_BASE64:
1493 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1494 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1495 break;
1496 case OPTYPE_DECODE:
1497 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1498 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1499 break;
1500 case OPTYPE_SUBSTR:
1501 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1502 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1503 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1504 break;
1505 case OPTYPE_REGEXP:
1506 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1507 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1508 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1509 break;
1510 case OPTYPE_DECOMP: // v1 v2 v3
1511 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1512 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1513 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1514 break;
1515 case OPTYPE_REPLACE:
1516 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1517 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1518 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1519 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1520 break;
1521 case OPTYPE_LENGTHOF: // ti1
1522 case OPTYPE_SIZEOF: // ti1
1523 case OPTYPE_VALUEOF: // ti1
1524 case OPTYPE_ISVALUE:
1525 case OPTYPE_ISBOUND:
1526 case OPTYPE_ENCODE:
1527 case OPTYPE_ISPRESENT:
1528 case OPTYPE_TTCN2STRING:
1529 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1530 break;
1531 case OPTYPE_UNDEF_RUNNING: // r1
1532 case OPTYPE_TMR_READ:
1533 case OPTYPE_TMR_RUNNING:
1534 case OPTYPE_ACTIVATE:
1535 u.expr.r1->set_fullname(p_fullname+".<operand>");
1536 break;
1537 case OPTYPE_EXECUTE: // r1 [v2]
1538 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1539 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1540 break;
1541 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1542 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1543 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1544 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1545 break;
1546 case OPTYPE_MATCH: // v1 t2
1547 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1548 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1549 break;
1550 case OPTYPE_ISCHOSEN: // r1 i2
1551 u.expr.r1->set_fullname(p_fullname+".<operand>");
1552 break;
1553 case OPTYPE_ISCHOSEN_V: // v1 i2
1554 u.expr.v1->set_fullname(p_fullname+".<operand>");
1555 break;
1556 case OPTYPE_ISCHOSEN_T: // t1 i2
1557 u.expr.t1->set_fullname(p_fullname+".<operand>");
1558 break;
1559 case OPTYPE_ACTIVATE_REFD:
1560 u.expr.v1->set_fullname(p_fullname+".<reference>");
1561 if(u.expr.state!=EXPR_CHECKED)
1562 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1563 else
1564 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1565 break;
1566 case OPTYPE_EXECUTE_REFD:
1567 u.expr.v1->set_fullname(p_fullname+".<reference>");
1568 if(u.expr.state!=EXPR_CHECKED)
1569 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1570 else
1571 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1572 if(u.expr.v3)
1573 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1574 break;
1575 case OPTYPE_LOG2STR:
1576 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1577 break;
1578 default:
1579 FATAL_ERROR("Value::set_fullname_expr()");
1580 } // switch
1581 }
1582
1583 void Value::set_my_scope_expr(Scope *p_scope)
1584 {
1585 switch (u.expr.v_optype) {
1586 case OPTYPE_RND: // -
1587 case OPTYPE_COMP_NULL:
1588 case OPTYPE_COMP_MTC:
1589 case OPTYPE_COMP_SYSTEM:
1590 case OPTYPE_COMP_SELF:
1591 case OPTYPE_COMP_RUNNING_ANY:
1592 case OPTYPE_COMP_RUNNING_ALL:
1593 case OPTYPE_COMP_ALIVE_ANY:
1594 case OPTYPE_COMP_ALIVE_ALL:
1595 case OPTYPE_TMR_RUNNING_ANY:
1596 case OPTYPE_GETVERDICT:
1597 case OPTYPE_TESTCASENAME:
1598 case OPTYPE_PROF_RUNNING:
1599 break;
1600 case OPTYPE_UNARYPLUS: // v1
1601 case OPTYPE_UNARYMINUS:
1602 case OPTYPE_NOT:
1603 case OPTYPE_NOT4B:
1604 case OPTYPE_BIT2HEX:
1605 case OPTYPE_BIT2INT:
1606 case OPTYPE_BIT2OCT:
1607 case OPTYPE_BIT2STR:
1608 case OPTYPE_CHAR2INT:
1609 case OPTYPE_CHAR2OCT:
1610 case OPTYPE_COMP_RUNNING:
1611 case OPTYPE_COMP_ALIVE:
1612 case OPTYPE_FLOAT2INT:
1613 case OPTYPE_FLOAT2STR:
1614 case OPTYPE_HEX2BIT:
1615 case OPTYPE_HEX2INT:
1616 case OPTYPE_HEX2OCT:
1617 case OPTYPE_HEX2STR:
1618 case OPTYPE_INT2CHAR:
1619 case OPTYPE_INT2FLOAT:
1620 case OPTYPE_INT2STR:
1621 case OPTYPE_INT2UNICHAR:
1622 case OPTYPE_OCT2BIT:
1623 case OPTYPE_OCT2CHAR:
1624 case OPTYPE_OCT2HEX:
1625 case OPTYPE_OCT2INT:
1626 case OPTYPE_OCT2STR:
1627 case OPTYPE_STR2BIT:
1628 case OPTYPE_STR2FLOAT:
1629 case OPTYPE_STR2HEX:
1630 case OPTYPE_STR2INT:
1631 case OPTYPE_STR2OCT:
1632 case OPTYPE_UNICHAR2INT:
1633 case OPTYPE_UNICHAR2CHAR:
1634 case OPTYPE_ENUM2INT:
1635 case OPTYPE_RNDWITHVAL:
1636 case OPTYPE_REMOVE_BOM:
1637 case OPTYPE_GET_STRINGENCODING:
1638 case OPTYPE_DECODE_BASE64:
1639 u.expr.v1->set_my_scope(p_scope);
1640 break;
1641 case OPTYPE_ADD: // v1 v2
1642 case OPTYPE_SUBTRACT:
1643 case OPTYPE_MULTIPLY:
1644 case OPTYPE_DIVIDE:
1645 case OPTYPE_MOD:
1646 case OPTYPE_REM:
1647 case OPTYPE_CONCAT:
1648 case OPTYPE_EQ:
1649 case OPTYPE_LT:
1650 case OPTYPE_GT:
1651 case OPTYPE_NE:
1652 case OPTYPE_GE:
1653 case OPTYPE_LE:
1654 case OPTYPE_AND:
1655 case OPTYPE_OR:
1656 case OPTYPE_XOR:
1657 case OPTYPE_AND4B:
1658 case OPTYPE_OR4B:
1659 case OPTYPE_XOR4B:
1660 case OPTYPE_SHL:
1661 case OPTYPE_SHR:
1662 case OPTYPE_ROTL:
1663 case OPTYPE_ROTR:
1664 case OPTYPE_INT2BIT:
1665 case OPTYPE_INT2HEX:
1666 case OPTYPE_INT2OCT:
1667 u.expr.v1->set_my_scope(p_scope);
1668 u.expr.v2->set_my_scope(p_scope);
1669 break;
1670 case OPTYPE_UNICHAR2OCT:
1671 case OPTYPE_OCT2UNICHAR:
1672 case OPTYPE_ENCODE_BASE64:
1673 u.expr.v1->set_my_scope(p_scope);
1674 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1675 break;
1676 case OPTYPE_DECODE:
1677 u.expr.r1->set_my_scope(p_scope);
1678 u.expr.r2->set_my_scope(p_scope);
1679 break;
1680 case OPTYPE_SUBSTR:
1681 u.expr.ti1->set_my_scope(p_scope);
1682 u.expr.v2->set_my_scope(p_scope);
1683 u.expr.v3->set_my_scope(p_scope);
1684 break;
1685 case OPTYPE_REGEXP:
1686 u.expr.ti1->set_my_scope(p_scope);
1687 u.expr.t2->set_my_scope(p_scope);
1688 u.expr.v3->set_my_scope(p_scope);
1689 break;
1690 case OPTYPE_DECOMP: // v1 v2 v3
1691 u.expr.v1->set_my_scope(p_scope);
1692 u.expr.v2->set_my_scope(p_scope);
1693 u.expr.v3->set_my_scope(p_scope);
1694 break;
1695 case OPTYPE_REPLACE:
1696 u.expr.ti1->set_my_scope(p_scope);
1697 u.expr.v2->set_my_scope(p_scope);
1698 u.expr.v3->set_my_scope(p_scope);
1699 u.expr.ti4->set_my_scope(p_scope);
1700 break;
1701 case OPTYPE_LENGTHOF: // ti1
1702 case OPTYPE_SIZEOF: // ti1
1703 case OPTYPE_VALUEOF: // ti1
1704 case OPTYPE_ISVALUE:
1705 case OPTYPE_ISBOUND:
1706 case OPTYPE_ENCODE:
1707 case OPTYPE_ISPRESENT:
1708 case OPTYPE_TTCN2STRING:
1709 u.expr.ti1->set_my_scope(p_scope);
1710 break;
1711 case OPTYPE_UNDEF_RUNNING: // r1
1712 case OPTYPE_TMR_READ:
1713 case OPTYPE_TMR_RUNNING:
1714 case OPTYPE_ACTIVATE:
1715 u.expr.r1->set_my_scope(p_scope);
1716 break;
1717 case OPTYPE_EXECUTE: // r1 [v2]
1718 u.expr.r1->set_my_scope(p_scope);
1719 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1720 break;
1721 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1722 u.expr.r1->set_my_scope(p_scope);
1723 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1724 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1725 break;
1726 case OPTYPE_MATCH: // v1 t2
1727 u.expr.v1->set_my_scope(p_scope);
1728 u.expr.t2->set_my_scope(p_scope);
1729 break;
1730 case OPTYPE_ISCHOSEN: // r1 i2
1731 u.expr.r1->set_my_scope(p_scope);
1732 break;
1733 case OPTYPE_ISCHOSEN_V: // v1 i2
1734 u.expr.v1->set_my_scope(p_scope);
1735 break;
1736 case OPTYPE_ISCHOSEN_T: // t1 i2
1737 u.expr.t1->set_my_scope(p_scope);
1738 break;
1739 case OPTYPE_ACTIVATE_REFD:
1740 u.expr.v1->set_my_scope(p_scope);
1741 if(u.expr.state!=EXPR_CHECKED) {
1742 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1743 else
1744 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1745 } break;
1746 case OPTYPE_EXECUTE_REFD:
1747 u.expr.v1->set_my_scope(p_scope);
1748 if(u.expr.state!=EXPR_CHECKED) {
1749 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1750 else
1751 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1752 }
1753 if(u.expr.v3)
1754 u.expr.v3->set_my_scope(p_scope);
1755 break;
1756 case OPTYPE_LOG2STR:
1757 u.expr.logargs->set_my_scope(p_scope);
1758 break;
1759 default:
1760 FATAL_ERROR("Value::set_my_scope_expr()");
1761 } // switch
1762 }
1763
1764 void Value::set_genname_recursive(const string& p_genname)
1765 {
1766 size_t genname_len = p_genname.size();
1767 if (genname_len >= 4 &&
1768 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1769 // if the genname ends with ()() (i.e. the value stands for an optional
1770 // field) then drop the last () from the own genname, but leave it for
1771 // the embedded values
1772 set_genname(p_genname.substr(0, genname_len - 2));
1773 } else set_genname(p_genname);
1774 switch(valuetype) {
1775 case V_CHOICE: {
1776 string embedded_genname(p_genname);
1777 embedded_genname += '.';
1778 // If this is a choice value for an anytype, prepend the AT_ prefix
1779 // to the name of the alternative. The genname is used later in
1780 // Common::Value::generate_code_init_se()
1781 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1782 embedded_genname += "AT_";
1783 embedded_genname += u.choice.alt_name->get_name();
1784 embedded_genname += "()";
1785 u.choice.alt_value->set_genname_recursive(embedded_genname);
1786 break; }
1787 case V_SEQOF:
1788 case V_SETOF: {
1789 if (!is_indexed()) {
1790 size_t nof_vs = u.val_vs->get_nof_vs();
1791 for (size_t i = 0; i < nof_vs; i++) {
1792 string embedded_genname(p_genname);
1793 embedded_genname += '[';
1794 embedded_genname += Int2string(i);
1795 embedded_genname += ']';
1796 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1797 }
1798 } else {
1799 size_t nof_ivs = u.val_vs->get_nof_ivs();
1800 for (size_t i = 0; i < nof_ivs; i++) {
1801 string embedded_genname(p_genname);
1802 embedded_genname += '[';
1803 embedded_genname += Int2string(i);
1804 embedded_genname += ']';
1805 u.val_vs->get_iv_byIndex(i)->get_value()
1806 ->set_genname_recursive(embedded_genname);
1807 }
1808 }
1809 break; }
1810 case V_ARRAY: {
1811 if (!my_governor) return; // error recovery
1812 Type *type = my_governor->get_type_refd_last();
1813 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1814 Int offset = type->get_dimension()->get_offset();
1815 if (!is_indexed()) {
1816 size_t nof_vs = u.val_vs->get_nof_vs();
1817 for (size_t i = 0; i < nof_vs; i++) {
1818 string embedded_genname(p_genname);
1819 embedded_genname += '[';
1820 embedded_genname += Int2string(offset + i);
1821 embedded_genname += ']';
1822 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1823 }
1824 } else {
1825 size_t nof_ivs = u.val_vs->get_nof_ivs();
1826 for (size_t i = 0; i < nof_ivs; i++) {
1827 string embedded_genname(p_genname);
1828 embedded_genname += '[';
1829 embedded_genname += Int2string(offset + i);
1830 embedded_genname += ']';
1831 u.val_vs->get_iv_byIndex(i)->get_value()
1832 ->set_genname_recursive(embedded_genname);
1833 }
1834 }
1835 break; }
1836 case V_SEQ:
1837 case V_SET: {
1838 if (!my_governor) return; // error recovery
1839 Type *t = my_governor->get_type_refd_last();
1840 if (!t->is_secho()) return; // error recovery
1841 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1842 for (size_t i = 0; i < nof_nvs; i++) {
1843 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1844 const Identifier& id = nv->get_name();
1845 if (!t->has_comp_withName(id)) return; // error recovery
1846 string embedded_genname(p_genname);
1847 embedded_genname += '.';
1848 embedded_genname += id.get_name();
1849 embedded_genname += "()";
1850 if (t->get_comp_byName(id)->get_is_optional())
1851 embedded_genname += "()";
1852 nv->get_value()->set_genname_recursive(embedded_genname);
1853 }
1854 break; }
1855 default:
1856 break;
1857 } // switch
1858 }
1859
1860 void Value::set_genname_prefix(const char *p_genname_prefix)
1861 {
1862 GovernedSimple::set_genname_prefix(p_genname_prefix);
1863 switch(valuetype) {
1864 case V_CHOICE:
1865 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1866 break;
1867 case V_SEQOF:
1868 case V_SETOF:
1869 case V_ARRAY:
1870 if (!is_indexed()) {
1871 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1872 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1873 } else {
1874 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1875 u.val_vs->get_iv_byIndex(i)->get_value()
1876 ->set_genname_prefix(p_genname_prefix);
1877 }
1878 break;
1879 case V_SEQ:
1880 case V_SET:
1881 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1882 u.val_nvs->get_nv_byIndex(i)->get_value()
1883 ->set_genname_prefix(p_genname_prefix);
1884 break;
1885 default:
1886 break;
1887 } // switch
1888 }
1889
1890 void Value::set_code_section(code_section_t p_code_section)
1891 {
1892 GovernedSimple::set_code_section(p_code_section);
1893 switch(valuetype) {
1894 case V_EXPR:
1895 switch (u.expr.v_optype) {
1896 case OPTYPE_RND: // -
1897 case OPTYPE_COMP_NULL:
1898 case OPTYPE_COMP_MTC:
1899 case OPTYPE_COMP_SYSTEM:
1900 case OPTYPE_COMP_SELF:
1901 case OPTYPE_COMP_RUNNING_ANY:
1902 case OPTYPE_COMP_RUNNING_ALL:
1903 case OPTYPE_COMP_ALIVE_ANY:
1904 case OPTYPE_COMP_ALIVE_ALL:
1905 case OPTYPE_TMR_RUNNING_ANY:
1906 case OPTYPE_GETVERDICT:
1907 case OPTYPE_TESTCASENAME:
1908 case OPTYPE_PROF_RUNNING:
1909 break;
1910 case OPTYPE_UNARYPLUS: // v1
1911 case OPTYPE_UNARYMINUS:
1912 case OPTYPE_NOT:
1913 case OPTYPE_NOT4B:
1914 case OPTYPE_BIT2HEX:
1915 case OPTYPE_BIT2INT:
1916 case OPTYPE_BIT2OCT:
1917 case OPTYPE_BIT2STR:
1918 case OPTYPE_CHAR2INT:
1919 case OPTYPE_CHAR2OCT:
1920 case OPTYPE_COMP_RUNNING:
1921 case OPTYPE_COMP_ALIVE:
1922 case OPTYPE_FLOAT2INT:
1923 case OPTYPE_FLOAT2STR:
1924 case OPTYPE_HEX2BIT:
1925 case OPTYPE_HEX2INT:
1926 case OPTYPE_HEX2OCT:
1927 case OPTYPE_HEX2STR:
1928 case OPTYPE_INT2CHAR:
1929 case OPTYPE_INT2FLOAT:
1930 case OPTYPE_INT2STR:
1931 case OPTYPE_INT2UNICHAR:
1932 case OPTYPE_OCT2BIT:
1933 case OPTYPE_OCT2CHAR:
1934 case OPTYPE_OCT2HEX:
1935 case OPTYPE_OCT2INT:
1936 case OPTYPE_OCT2STR:
1937 case OPTYPE_STR2BIT:
1938 case OPTYPE_STR2FLOAT:
1939 case OPTYPE_STR2HEX:
1940 case OPTYPE_STR2INT:
1941 case OPTYPE_STR2OCT:
1942 case OPTYPE_UNICHAR2INT:
1943 case OPTYPE_UNICHAR2CHAR:
1944 case OPTYPE_ENUM2INT:
1945 case OPTYPE_RNDWITHVAL:
1946 case OPTYPE_GET_STRINGENCODING:
1947 case OPTYPE_DECODE_BASE64:
1948 case OPTYPE_REMOVE_BOM:
1949 u.expr.v1->set_code_section(p_code_section);
1950 break;
1951 case OPTYPE_ADD: // v1 v2
1952 case OPTYPE_SUBTRACT:
1953 case OPTYPE_MULTIPLY:
1954 case OPTYPE_DIVIDE:
1955 case OPTYPE_MOD:
1956 case OPTYPE_REM:
1957 case OPTYPE_CONCAT:
1958 case OPTYPE_EQ:
1959 case OPTYPE_LT:
1960 case OPTYPE_GT:
1961 case OPTYPE_NE:
1962 case OPTYPE_GE:
1963 case OPTYPE_LE:
1964 case OPTYPE_AND:
1965 case OPTYPE_OR:
1966 case OPTYPE_XOR:
1967 case OPTYPE_AND4B:
1968 case OPTYPE_OR4B:
1969 case OPTYPE_XOR4B:
1970 case OPTYPE_SHL:
1971 case OPTYPE_SHR:
1972 case OPTYPE_ROTL:
1973 case OPTYPE_ROTR:
1974 case OPTYPE_INT2BIT:
1975 case OPTYPE_INT2HEX:
1976 case OPTYPE_INT2OCT:
1977 u.expr.v1->set_code_section(p_code_section);
1978 u.expr.v2->set_code_section(p_code_section);
1979 break;
1980 case OPTYPE_UNICHAR2OCT:
1981 case OPTYPE_OCT2UNICHAR:
1982 case OPTYPE_ENCODE_BASE64:
1983 u.expr.v1->set_code_section(p_code_section);
1984 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
1985 break;
1986 case OPTYPE_DECODE:
1987 u.expr.r1->set_code_section(p_code_section);
1988 u.expr.r2->set_code_section(p_code_section);
1989 break;
1990 case OPTYPE_SUBSTR:
1991 u.expr.ti1->set_code_section(p_code_section);
1992 u.expr.v2->set_code_section(p_code_section);
1993 u.expr.v3->set_code_section(p_code_section);
1994 break;
1995 case OPTYPE_REGEXP:
1996 u.expr.ti1->set_code_section(p_code_section);
1997 u.expr.t2->set_code_section(p_code_section);
1998 u.expr.v3->set_code_section(p_code_section);
1999 break;
2000 case OPTYPE_DECOMP: // v1 v2 v3
2001 u.expr.v1->set_code_section(p_code_section);
2002 u.expr.v2->set_code_section(p_code_section);
2003 u.expr.v3->set_code_section(p_code_section);
2004 break;
2005 case OPTYPE_REPLACE:
2006 u.expr.ti1->set_code_section(p_code_section);
2007 u.expr.v2->set_code_section(p_code_section);
2008 u.expr.v3->set_code_section(p_code_section);
2009 u.expr.ti4->set_code_section(p_code_section);
2010 break;
2011 case OPTYPE_LENGTHOF: // ti1
2012 case OPTYPE_SIZEOF: // ti1
2013 case OPTYPE_VALUEOF: // ti1
2014 case OPTYPE_ISVALUE:
2015 case OPTYPE_ISBOUND:
2016 case OPTYPE_ENCODE:
2017 case OPTYPE_ISPRESENT:
2018 case OPTYPE_TTCN2STRING:
2019 u.expr.ti1->set_code_section(p_code_section);
2020 break;
2021 case OPTYPE_UNDEF_RUNNING: // r1
2022 case OPTYPE_TMR_READ:
2023 case OPTYPE_TMR_RUNNING:
2024 case OPTYPE_ACTIVATE:
2025 u.expr.r1->set_code_section(p_code_section);
2026 break;
2027 case OPTYPE_EXECUTE: // r1 [v2]
2028 u.expr.r1->set_code_section(p_code_section);
2029 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2030 break;
2031 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2032 u.expr.r1->set_code_section(p_code_section);
2033 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2034 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2035 break;
2036 case OPTYPE_MATCH: // v1 t2
2037 u.expr.v1->set_code_section(p_code_section);
2038 u.expr.t2->set_code_section(p_code_section);
2039 break;
2040 case OPTYPE_ISCHOSEN: // r1 i2
2041 u.expr.r1->set_code_section(p_code_section);
2042 break;
2043 case OPTYPE_ISCHOSEN_V: // v1 i2
2044 u.expr.v1->set_code_section(p_code_section);
2045 break;
2046 case OPTYPE_ISCHOSEN_T: // t1 i2
2047 u.expr.t1->set_code_section(p_code_section);
2048 break;
2049 case OPTYPE_ACTIVATE_REFD:
2050 u.expr.v1->set_code_section(p_code_section);
2051 if(u.expr.state!=EXPR_CHECKED)
2052 u.expr.t_list2->set_code_section(p_code_section);
2053 else {
2054 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2055 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2056 u.expr.state = EXPR_CHECKED;
2057 }
2058 break;
2059 case OPTYPE_EXECUTE_REFD:
2060 u.expr.v1->set_code_section(p_code_section);
2061 if(u.expr.state!=EXPR_CHECKED)
2062 u.expr.t_list2->set_code_section(p_code_section);
2063 else {
2064 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2065 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2066 u.expr.state = EXPR_CHECKED;
2067 }
2068 if(u.expr.v3)
2069 u.expr.v3->set_code_section(p_code_section);
2070 break;
2071 case OPTYPE_LOG2STR:
2072 u.expr.logargs->set_code_section(p_code_section);
2073 break;
2074 default:
2075 FATAL_ERROR("Value::set_code_section()");
2076 } // switch
2077 break;
2078 case V_CHOICE:
2079 u.choice.alt_value->set_code_section(p_code_section);
2080 break;
2081 case V_SEQOF:
2082 case V_SETOF:
2083 case V_ARRAY:
2084 if (!is_indexed()) {
2085 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2086 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2087 } else {
2088 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2089 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2090 }
2091 break;
2092 case V_SEQ:
2093 case V_SET:
2094 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2095 u.val_nvs->get_nv_byIndex(i)->get_value()
2096 ->set_code_section(p_code_section);
2097 break;
2098 case V_REFD:
2099 u.ref.ref->set_code_section(p_code_section);
2100 break;
2101 case V_REFER:
2102 u.refered->set_code_section(p_code_section);
2103 break;
2104 case V_INVOKE:
2105 u.invoke.v->set_code_section(p_code_section);
2106 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2107 if(u.invoke.ap_list)
2108 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2109 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2110 break;
2111 default:
2112 break;
2113 } // switch
2114 }
2115
2116 void Value::change_sign()
2117 {
2118 switch(valuetype) {
2119 case V_INT:
2120 *u.val_Int=-*u.val_Int;
2121 break;
2122 case V_REAL:
2123 u.val_Real*=-1.0;
2124 break;
2125 case V_ERROR:
2126 break;
2127 default:
2128 FATAL_ERROR("Value::change_sign()");
2129 } // switch
2130 }
2131
2132 void Value::add_oid_comp(OID_comp* p_comp)
2133 {
2134 if(!p_comp)
2135 FATAL_ERROR("NULL parameter");
2136 u.oid_comps->add(p_comp);
2137 p_comp->set_fullname(get_fullname()+"."
2138 +Int2string(u.oid_comps->size()));
2139 p_comp->set_my_scope(my_scope);
2140 }
2141
2142 void Value::set_valuetype(valuetype_t p_valuetype)
2143 {
2144 if (valuetype == V_ERROR) return;
2145 else if (p_valuetype == V_ERROR) {
2146 if(valuetype==V_EXPR) {
2147 switch(u.expr.state) {
2148 case EXPR_CHECKING:
2149 u.expr.state=EXPR_CHECKING_ERR;
2150 // no break
2151 case EXPR_CHECKING_ERR:
2152 return;
2153 default:
2154 break;
2155 }
2156 }
2157 clean_up();
2158 valuetype = V_ERROR;
2159 return;
2160 }
2161 switch(valuetype) {
2162 case V_UNDEF_LOWERID:
2163 switch(p_valuetype) {
2164 case V_ENUM:
2165 case V_NAMEDINT:
2166 break;
2167 case V_REFD:
2168 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2169 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2170 u.ref.ref->set_my_scope(get_my_scope());
2171 u.ref.ref->set_fullname(get_fullname());
2172 u.ref.ref->set_location(*this);
2173 u.ref.refd_last = 0;
2174 break;
2175 default:
2176 FATAL_ERROR("Value::set_valuetype()");
2177 } // switch
2178 break;
2179 case V_UNDEF_BLOCK: {
2180 Block *t_block=u.block;
2181 Value *v=0;
2182 switch(p_valuetype) {
2183 case V_NAMEDBITS: {
2184 Node *node=t_block->parse(KW_Block_IdentifierList);
2185 v=dynamic_cast<Value*>(node);
2186 if(!v) {
2187 /* syntax error */
2188 u.ids=new map<string, Identifier>();
2189 }
2190 else {
2191 u.ids=v->u.ids; v->u.ids=0;
2192 }
2193 break;}
2194 case V_SEQOF: {
2195 Node *node=t_block->parse(KW_Block_SeqOfValue);
2196 v=dynamic_cast<Value*>(node);
2197 if(!v) {
2198 /* syntax error */
2199 u.val_vs=new Values();
2200 }
2201 else {
2202 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2203 }
2204 u.val_vs->set_my_scope(get_my_scope());
2205 u.val_vs->set_fullname(get_fullname());
2206 break;}
2207 case V_SETOF: {
2208 Node *node=t_block->parse(KW_Block_SetOfValue);
2209 v=dynamic_cast<Value*>(node);
2210 if(!v) {
2211 /* syntax error */
2212 u.val_vs=new Values();
2213 }
2214 else {
2215 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2216 }
2217 u.val_vs->set_my_scope(get_my_scope());
2218 u.val_vs->set_fullname(get_fullname());
2219 break;}
2220 case V_SEQ: {
2221 Node *node=t_block->parse(KW_Block_SequenceValue);
2222 v=dynamic_cast<Value*>(node);
2223 if(!v) {
2224 /* syntax error */
2225 u.val_nvs=new NamedValues();
2226 }
2227 else {
2228 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2229 }
2230 u.val_nvs->set_my_scope(get_my_scope());
2231 u.val_nvs->set_fullname(get_fullname());
2232 break;}
2233 case V_SET: {
2234 Node *node=t_block->parse(KW_Block_SetValue);
2235 v=dynamic_cast<Value*>(node);
2236 if(!v) {
2237 /* syntax error */
2238 u.val_nvs=new NamedValues();
2239 }
2240 else {
2241 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2242 }
2243 u.val_nvs->set_my_scope(get_my_scope());
2244 u.val_nvs->set_fullname(get_fullname());
2245 break;}
2246 case V_OID: {
2247 Node *node=t_block->parse(KW_Block_OIDValue);
2248 v=dynamic_cast<Value*>(node);
2249 if(!v) {
2250 /* syntax error */
2251 u.oid_comps=new vector<OID_comp>();
2252 }
2253 else {
2254 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2255 }
2256 for (size_t i = 0; i < u.oid_comps->size(); i++)
2257 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2258 break;}
2259 case V_ROID: {
2260 Node *node=t_block->parse(KW_Block_ROIDValue);
2261 v=dynamic_cast<Value*>(node);
2262 if(!v) {
2263 /* syntax error */
2264 u.oid_comps=new vector<OID_comp>();
2265 }
2266 else {
2267 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2268 }
2269 for (size_t i = 0; i < u.oid_comps->size(); i++)
2270 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2271 break;}
2272 case V_CHARSYMS: {
2273 Node *node=t_block->parse(KW_Block_CharStringValue);
2274 u.char_syms=dynamic_cast<CharSyms*>(node);
2275 if(!u.char_syms) {
2276 /* syntax error */
2277 u.char_syms=new CharSyms();
2278 }
2279 u.char_syms->set_my_scope(get_my_scope());
2280 u.char_syms->set_fullname(get_fullname());
2281 break;}
2282 default:
2283 FATAL_ERROR("Value::set_valuetype()");
2284 } // switch
2285 delete v;
2286 delete t_block;
2287 break;}
2288 case V_REFD:
2289 if (p_valuetype == V_USTR) {
2290 Value *v_last = get_value_refd_last();
2291 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2292 ustring *ustr = new ustring(*v_last->u.str.val_str);
2293 delete u.ref.ref;
2294 set_val_ustr(ustr);
2295 u.ustr.convert_str = true; // will be converted back to string
2296 } else FATAL_ERROR("Value::set_valuetype()");
2297 break;
2298 case V_CHARSYMS:
2299 switch(p_valuetype) {
2300 case V_CSTR: {
2301 const string& str = u.char_syms->get_string();
2302 delete u.char_syms;
2303 set_val_str(new string(str));
2304 break;}
2305 case V_USTR: {
2306 const ustring& ustr = u.char_syms->get_ustring();
2307 delete u.char_syms;
2308 set_val_ustr(new ustring(ustr));
2309 u.ustr.convert_str = false;
2310 break;}
2311 case V_ISO2022STR: {
2312 const string& str = u.char_syms->get_iso2022string();
2313 delete u.char_syms;
2314 set_val_str(new string(str));
2315 break;}
2316 default:
2317 FATAL_ERROR("Value::set_valuetype()");
2318 } // switch
2319 break;
2320 case V_INT: {
2321 Real val_Real;
2322 if (p_valuetype == V_REAL)
2323 val_Real = u.val_Int->to_real();
2324 else FATAL_ERROR("Value::set_valuetype()");
2325 clean_up();
2326 u.val_Real = val_Real;
2327 break; }
2328 case V_HSTR: {
2329 clean_up_string_elements(u.str.str_elements);
2330 string *old_str = u.str.val_str;
2331 switch(p_valuetype) {
2332 case V_BSTR:
2333 set_val_str(hex2bit(*old_str));
2334 break;
2335 case V_OSTR:
2336 set_val_str(asn_hex2oct(*old_str));
2337 break;
2338 default:
2339 FATAL_ERROR("Value::set_valuetype()");
2340 } // switch
2341 delete old_str;
2342 break;}
2343 case V_BSTR:
2344 clean_up_string_elements(u.str.str_elements);
2345 if (p_valuetype == V_OSTR) {
2346 string *old_str = u.str.val_str;
2347 set_val_str(asn_bit2oct(*old_str));
2348 delete old_str;
2349 } else FATAL_ERROR("Value::set_valuetype()");
2350 break;
2351 case V_CSTR:
2352 clean_up_string_elements(u.str.str_elements);
2353 switch(p_valuetype) {
2354 case V_USTR: {
2355 string *old_str = u.str.val_str;
2356 set_val_ustr(new ustring(*old_str));
2357 u.ustr.convert_str = true; // will be converted back to string
2358 delete old_str;
2359 break;}
2360 case V_ISO2022STR:
2361 // do nothing
2362 break;
2363 default:
2364 FATAL_ERROR("Value::set_valuetype()");
2365 } // switch p_valuetype
2366 break;
2367 case V_USTR:
2368 clean_up_string_elements(u.ustr.ustr_elements);
2369 switch(p_valuetype) {
2370 case V_CSTR: {
2371 ustring *old_str = u.ustr.val_ustr;
2372 size_t nof_chars = old_str->size();
2373 bool warning_flag = false;
2374 for (size_t i = 0; i < nof_chars; i++) {
2375 const ustring::universal_char& uchar = (*old_str)[i];
2376 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2377 error("This string value cannot contain multiple-byte characters, "
2378 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2379 uchar.group, uchar.plane, uchar.row, uchar.cell,
2380 (unsigned long) i);
2381 p_valuetype = V_ERROR;
2382 break;
2383 } else if (uchar.cell > 127 && !warning_flag) {
2384 warning("This string value may not contain characters with code "
2385 "higher than 127, but it has character with code %u (0x%02X) "
2386 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2387 warning_flag = true;
2388 }
2389 }
2390 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2391 delete old_str;
2392 break; }
2393 case V_ISO2022STR:
2394 error("ISO-10646 string value cannot be converted to "
2395 "ISO-2022 string");
2396 delete u.ustr.val_ustr;
2397 p_valuetype = V_ERROR;
2398 break;
2399 default:
2400 FATAL_ERROR("Value::set_valuetype()");
2401 } // switch p_valuetype
2402 break;
2403 case V_SEQ:
2404 switch (p_valuetype) {
2405 case V_CHOICE: {
2406 NamedValues *nvs = u.val_nvs;
2407 if (nvs->get_nof_nvs() < 1) {
2408 error("Union value must have one active field");
2409 delete nvs;
2410 valuetype = V_ERROR;
2411 return;
2412 } else if (nvs->get_nof_nvs() > 1) {
2413 error("Only one field was expected in union value instead of %lu",
2414 (unsigned long) nvs->get_nof_nvs());
2415 }
2416 NamedValue *nv = nvs->get_nv_byIndex(0);
2417 u.choice.alt_name = nv->get_name().clone();
2418 u.choice.alt_value = nv->steal_value();
2419 delete nvs;
2420 break;}
2421 case V_SET:
2422 // do nothing
2423 break;
2424 case V_REAL: {
2425 NamedValues *nvs = u.val_nvs;
2426 bool err = false;
2427 /* mantissa */
2428 Int i_mant = 0;
2429 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2430 if (nvs->has_nv_withName(id_mant)) {
2431 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2432 ->get_value_refd_last();
2433 if (v_tmp->get_valuetype() == V_INT) {
2434 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2435 if (*i_mant_int > INT_MAX) {
2436 error("Mantissa `%s' should be less than `%d'",
2437 (i_mant_int->t_str()).c_str(), INT_MAX);
2438 err = true;
2439 } else {
2440 i_mant = i_mant_int->get_val();
2441 }
2442 }
2443 else err = true;
2444 }
2445 else err = true;
2446 /* base */
2447 Int i_base = 0;
2448 Identifier id_base(Identifier::ID_ASN, string("base"));
2449 if (!err && nvs->has_nv_withName(id_base)) {
2450 Value *v = nvs->get_nv_byName(id_base)->get_value();
2451 Value *v_tmp = v->get_value_refd_last();
2452 if (v_tmp->get_valuetype() == V_INT) {
2453 const int_val_t *i_base_int = v_tmp->get_val_Int();
2454 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2455 v->error("Base of the REAL must be 2 or 10");
2456 err = true;
2457 } else {
2458 i_base = i_base_int->get_val();
2459 }
2460 }
2461 else err = true;
2462 }
2463 else err = true;
2464 /* exponent */
2465 Int i_exp = 0;
2466 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2467 if (!err && nvs->has_nv_withName(id_exp)) {
2468 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2469 ->get_value_refd_last();
2470 if (v_tmp->get_valuetype() == V_INT) {
2471 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2472 if (*i_exp_int > INT_MAX) {
2473 error("Exponent `%s' should be less than `%d'",
2474 (i_exp_int->t_str()).c_str(), INT_MAX);
2475 err = true;
2476 } else {
2477 i_exp = i_exp_int->get_val();
2478 }
2479 }
2480 else err = true;
2481 }
2482 else err = true;
2483 /* clean up */
2484 delete nvs;
2485 if (err) {
2486 valuetype = V_ERROR;
2487 return;
2488 }
2489 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2490 static_cast<double>(i_exp));
2491 break; }
2492 case V_NOTUSED:
2493 clean_up();
2494 break;
2495 default:
2496 FATAL_ERROR("Value::set_valuetype()");
2497 } // switch
2498 break;
2499 case V_SEQOF:
2500 switch (p_valuetype) {
2501 case V_SEQ: {
2502 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2503 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2504 Type *t = my_governor->get_type_refd_last();
2505 switch (t->get_typetype()) {
2506 case Type::T_SEQ_T:
2507 case Type::T_SEQ_A:
2508 break;
2509 default:
2510 FATAL_ERROR("Value::set_valuetype()");
2511 }
2512 Values *vals = u.val_vs;
2513 size_t nof_vals = vals->get_nof_vs();
2514 size_t nof_comps = t->get_nof_comps();
2515 if (nof_vals > nof_comps) {
2516 error("Too many elements in value list notation for type `%s': "
2517 "%lu was expected instead of %lu",
2518 t->get_typename().c_str(),
2519 (unsigned long)nof_comps, (unsigned long)nof_vals);
2520 }
2521 size_t upper_limit;
2522 bool allnotused;
2523 if (nof_vals <= nof_comps) {
2524 upper_limit = nof_vals;
2525 allnotused = true;
2526 } else {
2527 upper_limit = nof_comps;
2528 allnotused = false;
2529 }
2530 u.val_nvs = new NamedValues;
2531 for (size_t i = 0; i < upper_limit; i++) {
2532 Value *v = vals->steal_v_byIndex(i);
2533 if (v->valuetype != V_NOTUSED) {
2534 allnotused = false;
2535 }
2536 NamedValue *nv =
2537 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2538 nv->set_location(*v);
2539 u.val_nvs->add_nv(nv);
2540 }
2541 u.val_nvs->set_my_scope(get_my_scope());
2542 u.val_nvs->set_fullname(get_fullname());
2543 delete vals;
2544 if (allnotused && nof_vals > 0)
2545 warning("All elements of value list notation for type `%s' are not "
2546 "used symbols (`-')", t->get_typename().c_str());
2547 break; }
2548 case V_SET:
2549 // { } -> empty set value
2550 if (u.val_vs->get_nof_vs() != 0)
2551 FATAL_ERROR("Value::set_valuetype()");
2552 delete u.val_vs;
2553 u.val_nvs = new NamedValues;
2554 break;
2555 case V_SETOF:
2556 case V_ARRAY:
2557 // SEQOF -> SETOF or ARRAY: trivial
2558 break;
2559 default:
2560 FATAL_ERROR("Value::set_valuetype()");
2561 }
2562 break;
2563 case V_SET:
2564 case V_CHOICE:
2565 if (p_valuetype == V_NOTUSED) {
2566 clean_up();
2567 }
2568 else {
2569 FATAL_ERROR("Value::set_valuetype()");
2570 }
2571 break;
2572 case V_TTCN3_NULL:
2573 switch (p_valuetype) {
2574 case V_DEFAULT_NULL:
2575 break;
2576 case V_FAT_NULL:
2577 break;
2578 default:
2579 FATAL_ERROR("Value::set_valuetype()");
2580 }
2581 break;
2582 case V_NOTUSED:
2583 if (V_OMIT != p_valuetype) { // in case of implicit omit
2584 FATAL_ERROR("Value::set_valuetype()");
2585 }
2586 break;
2587 default:
2588 FATAL_ERROR("Value::set_valuetype()");
2589 } // switch
2590 valuetype=p_valuetype;
2591 }
2592
2593 void Value::set_valuetype_COMP_NULL()
2594 {
2595 if(valuetype == V_ERROR) return;
2596 if(valuetype==V_TTCN3_NULL) {
2597 valuetype=V_EXPR;
2598 u.expr.v_optype=OPTYPE_COMP_NULL;
2599 // Nothing to check.
2600 u.expr.state=EXPR_CHECKED;
2601 }
2602 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2603 }
2604
2605 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2606 {
2607 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2608 delete u.val_id;
2609 u.val_Int = new int_val_t(p_val_int);
2610 valuetype = V_INT;
2611 } else FATAL_ERROR("Value::set_valuetype()");
2612 }
2613
2614 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2615 {
2616 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2617 clean_up();
2618 valuetype = V_BSTR;
2619 set_val_str(p_str);
2620 } else FATAL_ERROR("Value::set_valuetype()");
2621 }
2622
2623 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2624 {
2625 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2626 delete u.val_id;
2627 u.val_id = p_id;
2628 valuetype = V_ENUM;
2629 } else FATAL_ERROR("Value::set_valuetype()");
2630 }
2631
2632 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2633 {
2634 switch (p_valuetype) {
2635 case V_FUNCTION:
2636 case V_ALTSTEP:
2637 case V_TESTCASE:
2638 if (valuetype == V_REFER && p_ass) break;
2639 // no break
2640 default:
2641 FATAL_ERROR("Value::set_valuetype()");
2642 }
2643 delete u.refered;
2644 u.refd_fat = p_ass;
2645 valuetype = p_valuetype;
2646 }
2647
2648 bool Value::is_undef_lowerid()
2649 {
2650 switch (valuetype) {
2651 case V_UNDEF_LOWERID:
2652 return true;
2653 case V_EXPR:
2654 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2655 !u.expr.ti1->get_DerivedRef()) {
2656 return u.expr.ti1->get_Template()->is_undef_lowerid();
2657 }
2658 // no break
2659 default:
2660 return false;
2661 }
2662 }
2663
2664 const Identifier& Value::get_undef_lowerid()
2665 {
2666 switch (valuetype) {
2667 case V_UNDEF_LOWERID:
2668 return *u.val_id;
2669 case V_EXPR:
2670 if (u.expr.v_optype != OPTYPE_VALUEOF)
2671 FATAL_ERROR("Value::get_undef_lowerid()");
2672 return u.expr.ti1->get_Template()->get_specific_value()
2673 ->get_undef_lowerid();
2674 default:
2675 FATAL_ERROR("Value::get_undef_lowerid()");
2676 }
2677 const Identifier *dummy = 0;
2678 return *dummy;
2679 }
2680
2681 void Value::set_lowerid_to_ref()
2682 {
2683 switch (valuetype) {
2684 case V_UNDEF_LOWERID:
2685 set_valuetype(V_REFD);
2686 break;
2687 case V_EXPR:
2688 // if the governor of the expression is not known (in log(), etc...)
2689 // then the governor is taken from the reference (using
2690 // v1/ti1->get_expr_governor()), but that runs before the
2691 // params were checked, this smells like a workaround :)
2692 switch (u.expr.v_optype) {
2693 case OPTYPE_ROTL:
2694 case OPTYPE_ROTR:
2695 u.expr.v1->set_lowerid_to_ref();
2696 break;
2697 case OPTYPE_CONCAT:
2698 u.expr.v1->set_lowerid_to_ref();
2699 u.expr.v2->set_lowerid_to_ref();
2700 break;
2701 case OPTYPE_VALUEOF:
2702 case OPTYPE_ISVALUE:
2703 case OPTYPE_ISBOUND:
2704 case OPTYPE_ISPRESENT:
2705 case OPTYPE_SUBSTR:
2706 case OPTYPE_REGEXP:
2707 case OPTYPE_REPLACE:
2708 case OPTYPE_TTCN2STRING:
2709 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2710 Error_Context cntxt(u.expr.ti1->get_Template(),
2711 "In the operand of operation `%s'",
2712 get_opname());
2713 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2714 }
2715 if (u.expr.v_optype==OPTYPE_REGEXP) {
2716 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2717 Error_Context cntxt(u.expr.t2->get_Template(),
2718 "In the operand of operation `%s'",
2719 get_opname());
2720 u.expr.t2->get_Template()->set_lowerid_to_ref();
2721 }
2722 }
2723 if (u.expr.v_optype==OPTYPE_REPLACE) {
2724 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2725 Error_Context cntxt(u.expr.ti4->get_Template(),
2726 "In the operand of operation `%s'",
2727 get_opname());
2728 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2729 }
2730 }
2731 break;
2732 default:
2733 break;
2734 }
2735 break;
2736 default:
2737 break;
2738 }
2739 }
2740
2741 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2742 {
2743 switch (valuetype) {
2744 case V_CHARSYMS:
2745 case V_CHOICE:
2746 case V_SEQOF:
2747 case V_SETOF:
2748 case V_ARRAY:
2749 case V_SEQ:
2750 case V_SET:
2751 case V_UNDEF_LOWERID:
2752 case V_UNDEF_BLOCK:
2753 case V_OMIT:
2754 case V_TTCN3_NULL:
2755 case V_NOTUSED:
2756 case V_REFER:
2757 case V_FAT_NULL:
2758 return Type::T_UNDEF;
2759 case V_NAMEDINT:
2760 case V_NAMEDBITS:
2761 case V_OPENTYPE:
2762 FATAL_ERROR("Value::get_expr_returntype()");
2763 case V_ERROR:
2764 return Type::T_ERROR;
2765 case V_REFD:
2766 case V_INVOKE: {
2767 Type *t = get_expr_governor(exp_val);
2768 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2769 else return Type::T_ERROR; }
2770 case V_FUNCTION:
2771 return Type::T_FUNCTION;
2772 case V_ALTSTEP:
2773 return Type::T_ALTSTEP;
2774 case V_TESTCASE:
2775 return Type::T_TESTCASE;
2776 case V_EXPR:
2777 switch(u.expr.v_optype) {
2778 case OPTYPE_COMP_NULL:
2779 case OPTYPE_COMP_MTC:
2780 case OPTYPE_COMP_SYSTEM:
2781 case OPTYPE_COMP_SELF:
2782 case OPTYPE_COMP_CREATE:
2783 return Type::T_COMPONENT;
2784 case OPTYPE_UNDEF_RUNNING:
2785 case OPTYPE_COMP_RUNNING:
2786 case OPTYPE_COMP_RUNNING_ANY:
2787 case OPTYPE_COMP_RUNNING_ALL:
2788 case OPTYPE_COMP_ALIVE:
2789 case OPTYPE_COMP_ALIVE_ANY:
2790 case OPTYPE_COMP_ALIVE_ALL:
2791 case OPTYPE_TMR_RUNNING:
2792 case OPTYPE_TMR_RUNNING_ANY:
2793 case OPTYPE_MATCH:
2794 case OPTYPE_EQ:
2795 case OPTYPE_LT:
2796 case OPTYPE_GT:
2797 case OPTYPE_NE:
2798 case OPTYPE_GE:
2799 case OPTYPE_LE:
2800 case OPTYPE_NOT:
2801 case OPTYPE_AND:
2802 case OPTYPE_OR:
2803 case OPTYPE_XOR:
2804 case OPTYPE_ISPRESENT:
2805 case OPTYPE_ISCHOSEN:
2806 case OPTYPE_ISCHOSEN_V:
2807 case OPTYPE_ISCHOSEN_T:
2808 case OPTYPE_ISVALUE:
2809 case OPTYPE_ISBOUND:
2810 case OPTYPE_PROF_RUNNING:
2811 return Type::T_BOOL;
2812 case OPTYPE_GETVERDICT:
2813 return Type::T_VERDICT;
2814 case OPTYPE_VALUEOF: {
2815 Error_Context cntxt(this, "In the operand of operation `%s'",
2816 get_opname());
2817 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2818 case OPTYPE_TMR_READ:
2819 case OPTYPE_INT2FLOAT:
2820 case OPTYPE_STR2FLOAT:
2821 case OPTYPE_RND:
2822 case OPTYPE_RNDWITHVAL:
2823 return Type::T_REAL;
2824 case OPTYPE_ACTIVATE:
2825 return Type::T_DEFAULT;
2826 case OPTYPE_ACTIVATE_REFD:
2827 return Type::T_DEFAULT;
2828 case OPTYPE_EXECUTE:
2829 case OPTYPE_EXECUTE_REFD:
2830 return Type::T_VERDICT;
2831 case OPTYPE_UNARYPLUS: // v1
2832 case OPTYPE_UNARYMINUS: {
2833 Type::typetype_t tmp_tt;
2834 {
2835 Error_Context cntxt(this, "In the operand of operation `%s'",
2836 get_opname());
2837 u.expr.v1->set_lowerid_to_ref();
2838 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2839 }
2840 switch(tmp_tt) {
2841 case Type::T_INT:
2842 case Type::T_REAL:
2843 return tmp_tt;
2844 default:
2845 get_value_refd_last(); // to report the error
2846 return Type::T_ERROR;
2847 } // switch tmp_tt
2848 }
2849 case OPTYPE_ADD: // v1 v2
2850 case OPTYPE_SUBTRACT:
2851 case OPTYPE_MULTIPLY:
2852 case OPTYPE_DIVIDE: {
2853 Type::typetype_t tmp_tt;
2854 {
2855 Error_Context cntxt(this, "In the left operand of operation `%s'",
2856 get_opname());
2857 u.expr.v1->set_lowerid_to_ref();
2858 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2859 }
2860 switch(tmp_tt) {
2861 case Type::T_INT:
2862 case Type::T_REAL:
2863 return tmp_tt;
2864 default:
2865 if(u.expr.v_optype==OPTYPE_ADD) {
2866 Type::typetype_t tmp_tt2;
2867 {
2868 Error_Context cntxt(this, "In the right operand of operation `%s'",
2869 get_opname());
2870 u.expr.v2->set_lowerid_to_ref();
2871 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2872 }
2873 Type::typetype_t ret_val=Type::T_ERROR;
2874 bool maybeconcat=false;
2875 switch(tmp_tt) {
2876 case Type::T_BSTR:
2877 case Type::T_HSTR:
2878 case Type::T_OSTR:
2879 if(tmp_tt2==tmp_tt) {
2880 maybeconcat=true;
2881 ret_val=tmp_tt;
2882 }
2883 break;
2884 case Type::T_CSTR:
2885 case Type::T_USTR:
2886 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2887 maybeconcat=true;
2888 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2889 ret_val=Type::T_USTR;
2890 else ret_val=Type::T_CSTR;
2891 }
2892 break;
2893 default:
2894 break;
2895 }
2896 if(maybeconcat) {
2897 error("Did you mean the concat operation (`&') instead of"
2898 " addition operator (`+')?");
2899 u.expr.v_optype=OPTYPE_CONCAT;
2900 return ret_val;
2901 }
2902 }
2903 get_value_refd_last(); // to report the error
2904 return Type::T_ERROR;
2905 } // switch tmp_tt
2906 }
2907 case OPTYPE_NOT4B: // v1
2908 case OPTYPE_AND4B: // v1 v2
2909 case OPTYPE_OR4B:
2910 case OPTYPE_XOR4B:
2911 case OPTYPE_SHL:
2912 case OPTYPE_SHR: {
2913 Type::typetype_t tmp_tt;
2914 {
2915 Error_Context cntxt(this, "In the %soperand of operation `%s'",
2916 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
2917 get_opname());
2918 u.expr.v1->set_lowerid_to_ref();
2919 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2920 }
2921 switch(tmp_tt) {
2922 case Type::T_BSTR:
2923 case Type::T_HSTR:
2924 case Type::T_OSTR:
2925 return tmp_tt;
2926 default:
2927 get_value_refd_last(); // to report the error
2928 return Type::T_ERROR;
2929 } // switch tmp_tt
2930 }
2931 case OPTYPE_ROTL: // v1 v2
2932 case OPTYPE_ROTR: {
2933 Type::typetype_t tmp_tt;
2934 {
2935 Error_Context cntxt(this, "In the %s operand of operation `%s'",
2936 u.expr.v_optype==OPTYPE_ROTL
2937 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
2938 get_opname());
2939 u.expr.v1->set_lowerid_to_ref();
2940 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2941 }
2942 switch(tmp_tt) {
2943 case Type::T_BSTR:
2944 case Type::T_HSTR:
2945 case Type::T_OSTR:
2946 case Type::T_CSTR:
2947 case Type::T_USTR:
2948 case Type::T_SETOF:
2949 case Type::T_SEQOF:
2950 case Type::T_ARRAY:
2951 return tmp_tt;
2952 default:
2953 get_value_refd_last(); // to report the error
2954 return Type::T_ERROR;
2955 } // switch tmp_tt
2956 }
2957 case OPTYPE_SUBSTR:
2958 case OPTYPE_REPLACE: {
2959 Type::typetype_t tmp_tt;
2960 {
2961 Error_Context cntxt(this, "In the operand of operation `%s'",
2962 get_opname());
2963 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2964 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2965 }
2966 switch (tmp_tt) {
2967 case Type::T_BSTR:
2968 case Type::T_HSTR:
2969 case Type::T_OSTR:
2970 case Type::T_CSTR:
2971 case Type::T_USTR:
2972 case Type::T_SETOF:
2973 case Type::T_SEQOF:
2974 return tmp_tt;
2975 default:
2976 get_value_refd_last(); // to report the error
2977 return Type::T_ERROR;
2978 }
2979 }
2980 case OPTYPE_REGEXP: {
2981 Type::typetype_t tmp_tt;
2982 {
2983 Error_Context cntxt(this, "In the first operand of operation `%s'",
2984 get_opname());
2985 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2986 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
2987 }
2988 switch(tmp_tt) {
2989 case Type::T_CSTR:
2990 case Type::T_USTR:
2991 return tmp_tt;
2992 default:
2993 get_value_refd_last(); // to report the error
2994 return Type::T_ERROR;
2995 } // switch tmp_tt
2996 }
2997 case OPTYPE_CONCAT: { // v1 v2
2998 Type::typetype_t tmp_tt;
2999 {
3000 Error_Context cntxt(this, "In the first operand of operation `%s'",
3001 get_opname());
3002 u.expr.v1->set_lowerid_to_ref();
3003 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3004 }
3005 switch(tmp_tt) {
3006 case Type::T_CSTR:
3007 case Type::T_USTR:
3008 case Type::T_BSTR:
3009 case Type::T_HSTR:
3010 case Type::T_OSTR:
3011 case Type::T_SETOF:
3012 case Type::T_SEQOF:
3013 return tmp_tt;
3014 default:
3015 get_value_refd_last(); // to report the error
3016 return Type::T_ERROR;
3017 } // switch tmp_tt
3018 }
3019 case OPTYPE_MOD:
3020 case OPTYPE_REM:
3021 case OPTYPE_CHAR2INT:
3022 case OPTYPE_UNICHAR2INT:
3023 case OPTYPE_BIT2INT:
3024 case OPTYPE_HEX2INT:
3025 case OPTYPE_OCT2INT:
3026 case OPTYPE_STR2INT:
3027 case OPTYPE_FLOAT2INT:
3028 case OPTYPE_LENGTHOF:
3029 case OPTYPE_SIZEOF:
3030 case OPTYPE_DECODE:
3031 case OPTYPE_ENUM2INT:
3032 return Type::T_INT;
3033 case OPTYPE_BIT2STR:
3034 case OPTYPE_FLOAT2STR:
3035 case OPTYPE_HEX2STR:
3036 case OPTYPE_INT2CHAR:
3037 case OPTYPE_INT2STR:
3038 case OPTYPE_OCT2CHAR:
3039 case OPTYPE_OCT2STR:
3040 case OPTYPE_UNICHAR2CHAR:
3041 case OPTYPE_LOG2STR:
3042 case OPTYPE_TESTCASENAME:
3043 case OPTYPE_TTCN2STRING:
3044 case OPTYPE_GET_STRINGENCODING:
3045 case OPTYPE_ENCODE_BASE64:
3046 return Type::T_CSTR;
3047 case OPTYPE_INT2UNICHAR:
3048 case OPTYPE_OCT2UNICHAR:
3049 return Type::T_USTR;
3050 case OPTYPE_INT2BIT:
3051 case OPTYPE_HEX2BIT:
3052 case OPTYPE_OCT2BIT:
3053 case OPTYPE_STR2BIT:
3054 case OPTYPE_ENCODE:
3055 return Type::T_BSTR;
3056 case OPTYPE_INT2HEX:
3057 case OPTYPE_BIT2HEX:
3058 case OPTYPE_OCT2HEX:
3059 case OPTYPE_STR2HEX:
3060 return Type::T_HSTR;
3061 case OPTYPE_INT2OCT:
3062 case OPTYPE_CHAR2OCT:
3063 case OPTYPE_HEX2OCT:
3064 case OPTYPE_BIT2OCT:
3065 case OPTYPE_STR2OCT:
3066 case OPTYPE_UNICHAR2OCT:
3067 case OPTYPE_REMOVE_BOM:
3068 case OPTYPE_DECODE_BASE64:
3069 return Type::T_OSTR;
3070 case OPTYPE_DECOMP:
3071 return Type::T_OID;
3072 default:
3073 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3074 // to avoid warning
3075 return Type::T_ERROR;
3076 } // switch optype
3077 case V_MACRO:
3078 switch (u.macro) {
3079 case MACRO_MODULEID:
3080 case MACRO_FILENAME:
3081 case MACRO_BFILENAME:
3082 case MACRO_FILEPATH:
3083 case MACRO_LINENUMBER:
3084 case MACRO_DEFINITIONID:
3085 case MACRO_SCOPE:
3086 case MACRO_TESTCASEID:
3087 return Type::T_CSTR;
3088 case MACRO_LINENUMBER_C:
3089 return Type::T_INT;
3090 default:
3091 return Type::T_ERROR;
3092 }
3093 case V_NULL:
3094 return Type::T_NULL;
3095 case V_BOOL:
3096 return Type::T_BOOL;
3097 case V_INT:
3098 return Type::T_INT;
3099 case V_REAL:
3100 return Type::T_REAL;
3101 case V_ENUM:
3102 return Type::T_ENUM_T;
3103 case V_BSTR:
3104 return Type::T_BSTR;
3105 case V_HSTR:
3106 return Type::T_HSTR;
3107 case V_OSTR:
3108 return Type::T_OSTR;
3109 case V_CSTR:
3110 return Type::T_CSTR;
3111 case V_USTR:
3112 return Type::T_USTR;
3113 case V_ISO2022STR:
3114 return Type::T_GENERALSTRING;
3115 case V_OID:
3116 return Type::T_OID;
3117 case V_ROID:
3118 return Type::T_ROID;
3119 case V_VERDICT:
3120 return Type::T_VERDICT;
3121 case V_DEFAULT_NULL:
3122 return Type::T_DEFAULT;
3123 default:
3124 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3125 // to avoid warning
3126 return Type::T_ERROR;
3127 } // switch
3128 }
3129
3130 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3131 {
3132 if(my_governor) return my_governor;
3133 switch (valuetype) {
3134 case V_INVOKE: {
3135 Type *t = u.invoke.v->get_expr_governor(exp_val);
3136 if(!t) {
3137 if(u.invoke.v->get_valuetype() != V_ERROR)
3138 u.invoke.v->error("A value of type function expected");
3139 goto error;
3140 }
3141 t = t->get_type_refd_last();
3142 switch(t->get_typetype()) {
3143 case Type::T_FUNCTION: {
3144 Type *t_return_type = t->get_function_return_type();
3145 if (!t_return_type) {
3146 error("Reference to a %s was expected instead of invocation "
3147 "of behavior type `%s' with no return type",
3148 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3149 t->get_fullname().c_str());
3150 goto error;
3151 }
3152 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3153 error("Reference to a value was expected, but functions of type "
3154 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3155 t_return_type->get_typename().c_str());
3156 goto error;
3157 }
3158 return t_return_type; }
3159 case Type::T_ALTSTEP:
3160 goto error;
3161 default:
3162 u.invoke.v->error("A value of type function expected instead of `%s'",
3163 t->get_typename().c_str());
3164 goto error;
3165 }
3166 break; }
3167 case V_REFD: {
3168 Assignment *ass=u.ref.ref->get_refd_assignment();
3169 Type *tmp_type=0;
3170 if (!ass) goto error;
3171 switch (ass->get_asstype()) {
3172 case Assignment::A_CONST:
3173 case Assignment::A_EXT_CONST:
3174 case Assignment::A_MODULEPAR:
3175 case Assignment::A_MODULEPAR_TEMP:
3176 case Assignment::A_TEMPLATE:
3177 case Assignment::A_VAR:
3178 case Assignment::A_VAR_TEMPLATE:
3179 case Assignment::A_FUNCTION_RVAL:
3180 case Assignment::A_FUNCTION_RTEMP:
3181 case Assignment::A_EXT_FUNCTION_RVAL:
3182 case Assignment::A_EXT_FUNCTION_RTEMP:
3183 case Assignment::A_PAR_VAL_IN:
3184 case Assignment::A_PAR_VAL_OUT:
3185 case Assignment::A_PAR_VAL_INOUT:
3186 case Assignment::A_PAR_TEMPL_IN:
3187 case Assignment::A_PAR_TEMPL_OUT:
3188 case Assignment::A_PAR_TEMPL_INOUT:
3189 tmp_type=ass->get_Type();
3190 break;
3191 case Assignment::A_FUNCTION:
3192 case Assignment::A_EXT_FUNCTION:
3193 error("Reference to a %s was expected instead of a call of %s, which "
3194 "does not have return type",
3195 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3196 ass->get_description().c_str());
3197 goto error;
3198 default:
3199 error("Reference to a %s was expected instead of %s",
3200 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3201 ass->get_description().c_str());
3202 goto error;
3203 } // end switch
3204 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3205 if(!tmp_type) goto error;
3206 return tmp_type; }
3207 case V_EXPR:
3208 switch (u.expr.v_optype) {
3209 case OPTYPE_VALUEOF:
3210 case OPTYPE_SUBSTR:
3211 case OPTYPE_REGEXP:
3212 case OPTYPE_REPLACE:{
3213 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3214 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3215 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3216 return tmp_type;
3217 }
3218 case OPTYPE_ROTL:
3219 case OPTYPE_ROTR:
3220 return u.expr.v1->get_expr_governor(exp_val);
3221 case OPTYPE_CONCAT:
3222 return get_expr_governor_v1v2(exp_val);
3223 case OPTYPE_COMP_MTC:
3224 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3225 else return 0;
3226 case OPTYPE_COMP_SYSTEM:
3227 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3228 else return 0;
3229 case OPTYPE_COMP_SELF:
3230 if (my_scope) {
3231 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3232 if (t_ros) return t_ros->get_component_type();
3233 else return 0;
3234 } else return 0;
3235 case OPTYPE_COMP_CREATE:
3236 return chk_expr_operand_comptyperef_create();
3237 default:
3238 break;
3239 }
3240 // no break
3241 default:
3242 return Type::get_pooltype(get_expr_returntype(exp_val));
3243 }
3244 error:
3245 set_valuetype(V_ERROR);
3246 return 0;
3247 }
3248
3249 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3250 {
3251 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3252 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3253 if (v1_gov) {
3254 if (v2_gov) { // both have governors
3255 // return the type that is compatible with both (if there is no type mismatch)
3256 if (v1_gov->is_compatible(v2_gov, NULL))
3257 return v1_gov;
3258 else return v2_gov;
3259 } else return v1_gov;
3260 } else { // v1 has no governor
3261 if (v2_gov) return v2_gov;
3262 else return NULL; // neither has governor
3263 }
3264 }
3265
3266 Type *Value::get_expr_governor_last()
3267 {
3268 Value *v_last = get_value_refd_last();
3269 if (v_last->valuetype == V_ERROR) return 0;
3270 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3271 if(!t) return 0;
3272 return t->get_type_refd_last();
3273 }
3274
3275 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3276 {
3277 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3278 return u.invoke.v->get_expr_governor(exp_val);
3279 }
3280
3281 const char* Value::get_opname() const
3282 {
3283 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3284 switch(u.expr.v_optype) {
3285 case OPTYPE_RND: // -
3286 return "rnd()";
3287 case OPTYPE_COMP_NULL:
3288 return "(component) null";
3289 case OPTYPE_COMP_MTC:
3290 return "mtc";
3291 case OPTYPE_COMP_SYSTEM:
3292 return "system";
3293 case OPTYPE_COMP_SELF:
3294 return "self";
3295 case OPTYPE_COMP_RUNNING_ANY:
3296 return "any component.running";
3297 case OPTYPE_COMP_RUNNING_ALL:
3298 return "all component.running";
3299 case OPTYPE_COMP_ALIVE_ANY:
3300 return "any component.alive";
3301 case OPTYPE_COMP_ALIVE_ALL:
3302 return "all component.alive";
3303 case OPTYPE_TMR_RUNNING_ANY:
3304 return "any timer.running";
3305 case OPTYPE_GETVERDICT:
3306 return "getverdict()";
3307 case OPTYPE_TESTCASENAME:
3308 return "testcasename()";
3309 case OPTYPE_UNARYPLUS: // v1
3310 return "unary +";
3311 case OPTYPE_UNARYMINUS:
3312 return "unary -";
3313 case OPTYPE_NOT:
3314 return "not";
3315 case OPTYPE_NOT4B:
3316 return "not4b";
3317 case OPTYPE_BIT2HEX:
3318 return "bit2hex()";
3319 case OPTYPE_BIT2INT:
3320 return "bit2int()";
3321 case OPTYPE_BIT2OCT:
3322 return "bit2oct()";
3323 case OPTYPE_BIT2STR:
3324 return "bit2str()";
3325 case OPTYPE_CHAR2INT:
3326 return "char2int()";
3327 case OPTYPE_CHAR2OCT:
3328 return "char2oct()";
3329 case OPTYPE_FLOAT2INT:
3330 return "float2int()";
3331 case OPTYPE_FLOAT2STR:
3332 return "float2str()";
3333 case OPTYPE_HEX2BIT:
3334 return "hex2bit()";
3335 case OPTYPE_HEX2INT:
3336 return "hex2int()";
3337 case OPTYPE_HEX2OCT:
3338 return "hex2oct()";
3339 case OPTYPE_HEX2STR:
3340 return "hex2str()";
3341 case OPTYPE_INT2CHAR:
3342 return "int2char()";
3343 case OPTYPE_INT2FLOAT:
3344 return "int2float()";
3345 case OPTYPE_INT2STR:
3346 return "int2str()";
3347 case OPTYPE_INT2UNICHAR:
3348 return "int2unichar()";
3349 case OPTYPE_OCT2BIT:
3350 return "oct2bit()";
3351 case OPTYPE_OCT2CHAR:
3352 return "oct2char()";
3353 case OPTYPE_OCT2HEX:
3354 return "oct2hex()";
3355 case OPTYPE_OCT2INT:
3356 return "oct2int()";
3357 case OPTYPE_OCT2STR:
3358 return "oct2str()";
3359 case OPTYPE_STR2BIT:
3360 return "str2bit()";
3361 case OPTYPE_STR2FLOAT:
3362 return "str2float()";
3363 case OPTYPE_STR2HEX:
3364 return "str2hex()";
3365 case OPTYPE_STR2INT:
3366 return "str2int()";
3367 case OPTYPE_STR2OCT:
3368 return "str2oct()";
3369 case OPTYPE_UNICHAR2INT:
3370 return "unichar2int()";
3371 case OPTYPE_UNICHAR2CHAR:
3372 return "unichar2char()";
3373 case OPTYPE_UNICHAR2OCT:
3374 return "unichar2oct()";
3375 case OPTYPE_ENUM2INT:
3376 return "enum2int()";
3377 case OPTYPE_LENGTHOF:
3378 return "lengthof()";
3379 case OPTYPE_SIZEOF:
3380 return "sizeof()";
3381 case OPTYPE_RNDWITHVAL:
3382 return "rnd (seed)";
3383 case OPTYPE_ENCODE:
3384 return "encvalue()";
3385 case OPTYPE_DECODE:
3386 return "decvalue()";
3387 case OPTYPE_GET_STRINGENCODING:
3388 return "get_stringencoding()";
3389 case OPTYPE_REMOVE_BOM:
3390 return "remove_bom()";
3391 case OPTYPE_ENCODE_BASE64:
3392 return "encode_base64()";
3393 case OPTYPE_DECODE_BASE64:
3394 return "decode_base64()";
3395 case OPTYPE_ADD: // v1 v2
3396 return "+";
3397 case OPTYPE_SUBTRACT:
3398 return "-";
3399 case OPTYPE_MULTIPLY:
3400 return "*";
3401 case OPTYPE_DIVIDE:
3402 return "/";
3403 case OPTYPE_MOD:
3404 return "mod";
3405 case OPTYPE_REM:
3406 return "rem";
3407 case OPTYPE_CONCAT:
3408 return "&";
3409 case OPTYPE_EQ:
3410 return "==";
3411 case OPTYPE_LT:
3412 return "<";
3413 case OPTYPE_GT:
3414 return ">";
3415 case OPTYPE_NE:
3416 return "!=";
3417 case OPTYPE_GE:
3418 return ">=";
3419 case OPTYPE_LE:
3420 return "<=";
3421 case OPTYPE_AND:
3422 return "and";
3423 case OPTYPE_OR:
3424 return "or";
3425 case OPTYPE_XOR:
3426 return "xor";
3427 case OPTYPE_AND4B:
3428 return "and4b";
3429 case OPTYPE_OR4B:
3430 return "or4b";
3431 case OPTYPE_XOR4B:
3432 return "xor4b";
3433 case OPTYPE_SHL:
3434 return "<<";
3435 case OPTYPE_SHR:
3436 return ">>";
3437 case OPTYPE_ROTL:
3438 return "<@";
3439 case OPTYPE_ROTR:
3440 return "@>";
3441 case OPTYPE_INT2BIT:
3442 return "int2bit()";
3443 case OPTYPE_INT2HEX:
3444 return "int2hex()";
3445 case OPTYPE_INT2OCT:
3446 return "int2oct()";
3447 case OPTYPE_OCT2UNICHAR:
3448 return "oct2unichar()";
3449 case OPTYPE_SUBSTR:
3450 return "substr()";
3451 case OPTYPE_REGEXP:
3452 return "regexp()";
3453 case OPTYPE_DECOMP:
3454 return "decomp()";
3455 case OPTYPE_REPLACE:
3456 return "replace()";
3457 case OPTYPE_VALUEOF: // t1
3458 return "valueof()";
3459 case OPTYPE_UNDEF_RUNNING:
3460 return "<timer or component> running";
3461 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3462 return "create()";
3463 case OPTYPE_COMP_RUNNING: // v1
3464 return "component running";
3465 case OPTYPE_COMP_ALIVE: // v1
3466 return "alive";
3467 case OPTYPE_TMR_READ:
3468 return "timer read";
3469 case OPTYPE_TMR_RUNNING:
3470 return "timer running";
3471 case OPTYPE_ACTIVATE:
3472 return "activate()";
3473 case OPTYPE_ACTIVATE_REFD:
3474 return "activate()";
3475 case OPTYPE_EXECUTE: // r1 [v2]
3476 case OPTYPE_EXECUTE_REFD:
3477 return "execute()";
3478 case OPTYPE_MATCH: // v1 t2
3479 return "match()";
3480 case OPTYPE_ISPRESENT:
3481 return "ispresent()";
3482 case OPTYPE_ISCHOSEN:
3483 case OPTYPE_ISCHOSEN_V:
3484 case OPTYPE_ISCHOSEN_T:
3485 return "ischosen()";
3486 case OPTYPE_ISVALUE:
3487 return "isvalue()";
3488 case OPTYPE_ISBOUND:
3489 return "isbound()";
3490 case OPTYPE_LOG2STR:
3491 return "log2str()";
3492 case OPTYPE_TTCN2STRING:
3493 return "ttcn2string()";
3494 case OPTYPE_PROF_RUNNING:
3495 return "@profiler.running";
3496 default:
3497 FATAL_ERROR("Value::get_opname()");
3498 } // switch
3499 }
3500
3501 void Value::chk_expr_ref_ischosen()
3502 {
3503 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3504 Ttcn::Ref_base *tmpref=u.expr.r1;
3505 Assignment *ass=tmpref->get_refd_assignment();
3506 if (!ass) {
3507 set_valuetype(V_ERROR);
3508 return;
3509 }
3510 // Now we know whether the argument of ischosen() is a value or template.
3511 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3512 // or template (OPTYPE_ISCHOSEN_T).
3513 switch (ass->get_asstype()) {
3514 case Assignment::A_CONST:
3515 case Assignment::A_EXT_CONST:
3516 case Assignment::A_MODULEPAR:
3517 case Assignment::A_VAR:
3518 case Assignment::A_PAR_VAL_IN:
3519 case Assignment::A_PAR_VAL_OUT:
3520 case Assignment::A_PAR_VAL_INOUT:
3521 u.expr.v1=new Value(V_REFD, tmpref);
3522 u.expr.v1->set_location(*tmpref);
3523 u.expr.v1->set_my_scope(get_my_scope());
3524 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3525 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3526 break;
3527 case Assignment::A_MODULEPAR_TEMP:
3528 case Assignment::A_TEMPLATE:
3529 case Assignment::A_VAR_TEMPLATE:
3530 case Assignment::A_PAR_TEMPL_IN:
3531 case Assignment::A_PAR_TEMPL_OUT:
3532 case Assignment::A_PAR_TEMPL_INOUT:
3533 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3534 u.expr.t1->set_location(*tmpref);
3535 u.expr.t1->set_my_scope(get_my_scope());
3536 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3537 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3538 break;
3539 default:
3540 tmpref->error("Reference to a value or template was expected instead of "
3541 "%s", ass->get_description().c_str());
3542 set_valuetype(V_ERROR);
3543 break;
3544 } // switch
3545 }
3546
3547 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3548 Type::expected_value_t exp_val)
3549 {
3550 v->set_lowerid_to_ref(); // can only be reference to enum
3551 Type *t = v->get_expr_governor(exp_val);
3552 if (v->valuetype==V_ERROR) return;
3553 if (!t) {
3554 v->error("Please use reference to an enumerated value as the operand of "
3555 "operation `%s'", get_opname());
3556 set_valuetype(V_ERROR);
3557 return;
3558 }
3559 t = t->get_type_refd_last();
3560 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3561 v->error("The operand of operation `%s' should be enumerated value", opname);
3562 set_valuetype(V_ERROR);
3563 }
3564 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3565 v->error("The operand of operation `%s' cannot be omit", opname);
3566 set_valuetype(V_ERROR);
3567 }
3568 }
3569
3570 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3571 const char *opnum,
3572 const char *opname,
3573 const Location *loc)
3574 {
3575 if(tt==Type::T_BOOL) return;
3576 if(tt!=Type::T_ERROR)
3577 loc->error("%s operand of operation `%s' should be boolean value",
3578 opnum, opname);
3579 set_valuetype(V_ERROR);
3580 }
3581
3582 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3583 const char *opnum,
3584 const char *opname,
3585 const Location *loc)
3586 {
3587 if(tt==Type::T_INT) return;
3588 if(tt!=Type::T_ERROR)
3589 loc->error("%s operand of operation `%s' should be integer value",
3590 opnum, opname);
3591 set_valuetype(V_ERROR);
3592 }
3593
3594 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3595 const char *opnum,
3596 const char *opname,
3597 const Location *loc)
3598 {
3599 if(tt==Type::T_REAL) return;
3600 else if(tt==Type::T_INT)
3601 loc->error("%s operand of operation `%s' should be float value."
3602 " Perhaps you missed an int2float() conversion function"
3603 " or `.0' at the end of the number",
3604 opnum, opname);
3605 else if(tt!=Type::T_ERROR)
3606 loc->error("%s operand of operation `%s' should be float value",
3607 opnum, opname);
3608 set_valuetype(V_ERROR);
3609 }
3610
3611 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3612 const char *opnum,
3613 const char *opname,
3614 const Location *loc)
3615 {
3616 switch(tt) {
3617 case Type::T_INT:
3618 case Type::T_REAL:
3619 return;
3620 default:
3621 break;
3622 }
3623 if(tt!=Type::T_ERROR)
3624 loc->error("%s operand of operation `%s' should be integer"
3625 " or float value",
3626 opnum, opname);
3627 set_valuetype(V_ERROR);
3628 }
3629
3630 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3631 const char *opnum,
3632 const char *opname,
3633 const Location *loc)
3634 {
3635 switch(tt) {
3636 case Type::T_INT:
3637 case Type::T_REAL:
3638 case Type::T_ENUM_T:
3639 return;
3640 default:
3641 break;
3642 }
3643 if(tt!=Type::T_ERROR)
3644 loc->error("%s operand of operation `%s' should be integer, float"
3645 " or enumerated value", opnum, opname);
3646 set_valuetype(V_ERROR);
3647 }
3648
3649 void Value::chk_expr_operandtype_list(Type* t,
3650 const char *opnum,
3651 const char *opname,
3652 const Location *loc,
3653 bool allow_array)
3654 {
3655 if (valuetype == V_ERROR) return;
3656 if (t->get_typetype() == Type::T_ERROR) {
3657 set_valuetype(V_ERROR);
3658 return;
3659 }
3660 if (!t->is_list_type(allow_array)) {
3661 loc->error("%s operand of operation `%s' should be a string, "
3662 "`record of'%s `set of'%s value", opnum, opname,
3663 allow_array ? "," : " or", allow_array ? " or array" : "");
3664 set_valuetype(V_ERROR);
3665 return;
3666 }
3667 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3668 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3669 TypeChain l_chain;
3670 TypeChain r_chain;
3671 if (my_governor && my_governor->is_list_type(allow_array)
3672 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3673 if (info.is_subtype_error()) {
3674 // this is ok.
3675 if (info.needs_conversion()) set_needs_conversion();
3676 } else
3677 if (!info.is_erroneous()) {
3678 error("%s operand of operation `%s' is of type `%s', but a value of "
3679 "type `%s' was expected here", opnum, opname,
3680 t->get_typename().c_str(), my_governor->get_typename().c_str());
3681 } else {
3682 error("%s", info.get_error_str_str().c_str());
3683 }
3684 } else {
3685 if (info.needs_conversion())
3686 set_needs_conversion();
3687 }
3688 }
3689
3690 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3691 const char *opnum,
3692 const char *opname,
3693 const Location *loc)
3694 {
3695 switch(tt) {
3696 case Type::T_CSTR:
3697 case Type::T_USTR:
3698 case Type::T_BSTR:
3699 case Type::T_HSTR:
3700 case Type::T_OSTR:
3701 return;
3702 default:
3703 break;
3704 }
3705 if(tt!=Type::T_ERROR)
3706 loc->error("%s operand of operation `%s' should be string value",
3707 opnum, opname);
3708 set_valuetype(V_ERROR);
3709 }
3710
3711 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3712 const char *opnum,
3713 const char *opname,
3714 const Location *loc)
3715 {
3716 switch(tt) {
3717 case Type::T_CSTR:
3718 case Type::T_USTR:
3719 return;
3720 default:
3721 break;
3722 }
3723 if(tt!=Type::T_ERROR)
3724 loc->error("%s operand of operation `%s' should be (universal)"
3725 " charstring value",
3726 opnum, opname);
3727 set_valuetype(V_ERROR);
3728 }
3729
3730 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3731 const char *opnum,
3732 const char *opname,
3733 const Location *loc)
3734 {
3735 if(tt==Type::T_CSTR) return;
3736 if(tt!=Type::T_ERROR)
3737 loc->error("%s operand of operation `%s' should be charstring value",
3738 opnum, opname);
3739 set_valuetype(V_ERROR);
3740 }
3741
3742 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3743 const char *opnum,
3744 const char *opname,
3745 const Location *loc)
3746 {
3747 switch(tt) {
3748 case Type::T_BSTR:
3749 case Type::T_HSTR:
3750 case Type::T_OSTR:
3751 return;
3752 default:
3753 break;
3754 }
3755 if(tt!=Type::T_ERROR)
3756 loc->error("%s operand of operation `%s' should be binary string value",
3757 opnum, opname);
3758 set_valuetype(V_ERROR);
3759 }
3760
3761 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3762 const char *opnum,
3763 const char *opname,
3764 const Location *loc)
3765 {
3766 if(tt==Type::T_BSTR) return;
3767 if(tt!=Type::T_ERROR)
3768 loc->error("%s operand of operation `%s' should be bitstring value",
3769 opnum, opname);
3770 set_valuetype(V_ERROR);
3771 }
3772
3773 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3774 const char *opnum,
3775 const char *opname,
3776 const Location *loc)
3777 {
3778 if(tt==Type::T_HSTR) return;
3779 if(tt!=Type::T_ERROR)
3780 loc->error("%s operand of operation `%s' should be hexstring value",
3781 opnum, opname);
3782 set_valuetype(V_ERROR);
3783 }
3784
3785 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3786 const char *opnum,
3787 const char *opname,
3788 const Location *loc)
3789 {
3790 if(tt==Type::T_OSTR) return;
3791 if(tt!=Type::T_ERROR)
3792 loc->error("%s operand of operation `%s' should be octetstring value",
3793 opnum, opname);
3794 set_valuetype(V_ERROR);
3795 }
3796
3797 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3798 Type::typetype_t tt2,
3799 const char *opname)
3800 {
3801 if(valuetype==V_ERROR) return;
3802 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3803 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3804 set_valuetype(V_ERROR);
3805 return;
3806 }
3807 if(tt1==tt2) return;
3808 error("The operands of operation `%s' should be of same type", opname);
3809 set_valuetype(V_ERROR);
3810 }
3811
3812 /* For predefined functions. */
3813 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3814 Type::typetype_t tt2,
3815 const char *opnum1,
3816 const char *opnum2,
3817 const char *opname)
3818 {
3819 if(valuetype==V_ERROR) return;
3820 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3821 set_valuetype(V_ERROR);
3822 return;
3823 }
3824 if(tt1==tt2) return;
3825 error("The %s and %s operands of operation `%s' should be of same type",
3826 opnum1, opnum2, opname);
3827 set_valuetype(V_ERROR);
3828 }
3829
3830 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3831 Value *v1, Value *v2,
3832 const char *opnum1,
3833 const char *opnum2)
3834 {
3835 start:
3836 if (valuetype == V_ERROR) return;
3837 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3838 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3839 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3840
3841 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3842 set_valuetype(V_ERROR);
3843 return;
3844 }
3845 if (tt1 == Type::T_UNDEF) {
3846 if (tt2 == Type::T_UNDEF) {
3847 if (v1->is_undef_lowerid()) {
3848 if (v2->is_undef_lowerid()) {
3849 Scope *scope = get_my_scope();
3850 Module *my_mod = scope->get_scope_mod();
3851 const Identifier& id1 = v1->get_undef_lowerid();
3852 if (scope->has_ass_withId(id1)
3853 || my_mod->has_imported_ass_withId(id1)) {
3854 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3855 * should examine this situation better, but now I suppose
3856 * the first is ref, not enum. */
3857 v1->set_lowerid_to_ref();
3858 goto start;
3859 } else {
3860 const Identifier& id2 = v2->get_undef_lowerid();
3861 if (scope->has_ass_withId(id2)
3862 || my_mod->has_imported_ass_withId(id2)) {
3863 v2->set_lowerid_to_ref();
3864 goto start;
3865 }
3866 }
3867 /* This is perhaps enum-enum, but it has no real
3868 * significance, so this should be an error. */
3869 } else {
3870 v1->set_lowerid_to_ref();
3871 goto start;
3872 }
3873 } else if (v2->is_undef_lowerid()) {
3874 v2->set_lowerid_to_ref();
3875 goto start;
3876 }
3877 error("Cannot determine the type of the operands in operation `%s'",
3878 get_opname());
3879 set_valuetype(V_ERROR);
3880 return;
3881 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3882 v1->set_lowerid_to_ref();
3883 goto start;
3884 } else {
3885 /* v1 is something undefined, but not lowerid; v2 has
3886 * returntype (perhaps also governor) */
3887 }
3888 } else if (tt2 == Type::T_UNDEF) {
3889 /* but tt1 is not undef */
3890 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3891 v2->set_lowerid_to_ref();
3892 goto start;
3893 } else {
3894 /* v2 is something undefined, but not lowerid; v1 has
3895 * returntype (perhaps also governor) */
3896 }
3897 }
3898
3899 /* Now undef_lower_id's are converted to references, or the other
3900 * value has governor; let's see the governors, if they exist. */
3901 Type *t1 = v1->get_expr_governor(exp_val);
3902 Type *t2 = v2->get_expr_governor(exp_val);
3903 if (t1) {
3904 if (t2) {
3905 // Both value has governor. Are they compatible? According to 7.1.2
3906 // and C.34 it's required to have the same root types for
3907 // OPTYPE_{CONCAT,REPLACE}.
3908 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3909 u.expr.v_optype == OPTYPE_REPLACE);
3910 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
3911 u.expr.v_optype == OPTYPE_REPLACE);
3912 TypeChain l_chain1, l_chain2;
3913 TypeChain r_chain1, r_chain2;
3914 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
3915 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
3916 if (!compat_t1 && !compat_t2) {
3917 if (!info1.is_erroneous() && !info2.is_erroneous()) {
3918 // the subtypes don't need to be compatible here
3919 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
3920 error("The operands of operation `%s' should be of compatible "
3921 "types", get_opname());
3922 set_valuetype(V_ERROR);
3923 } else {
3924 if (info1.needs_conversion() || info2.needs_conversion()) {
3925 set_needs_conversion(); // Avoid folding.
3926 return;
3927 }
3928 }
3929 } else {
3930 if (info1.is_erroneous())
3931 v1->error("%s", info1.get_error_str_str().c_str());
3932 else if (info2.is_erroneous())
3933 v2->error("%s", info2.get_error_str_str().c_str());
3934 set_valuetype(V_ERROR);
3935 }
3936 return;
3937 } else if (info1.needs_conversion() || info2.needs_conversion()) {
3938 set_needs_conversion(); // Avoid folding.
3939 return;
3940 }
3941 } else {
3942 // t1, no t2.
3943 v2->set_my_governor(t1);
3944 t1->chk_this_value_ref(v2);
3945 if (v2->valuetype == V_OMIT) {
3946 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3947 get_opname());
3948 v1->chk_expr_omit_comparison(exp_val);
3949 } else {
3950 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3951 get_opname());
3952 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3953 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3954 goto start;
3955 }
3956 }
3957 } else if (t2) {
3958 v1->set_my_governor(t2);
3959 t2->chk_this_value_ref(v1);
3960 if (v1->valuetype == V_OMIT) {
3961 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
3962 get_opname());
3963 v2->chk_expr_omit_comparison(exp_val);
3964 } else {
3965 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
3966 get_opname());
3967 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
3968 OMIT_NOT_ALLOWED, NO_SUB_CHK);
3969 goto start;
3970 }
3971 } else {
3972 // Neither v1 nor v2 has a governor. Let's see the returntypes.
3973 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
3974 // Here, it cannot be that both are T_UNDEF.
3975 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
3976 error("Please use reference as %s operand of operator `%s'",
3977 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
3978 set_valuetype(V_ERROR);
3979 return;
3980 }
3981 // Deny type compatibility if no governors found. The typetype_t must
3982 // be the same. TODO: How can this happen?
3983 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
3984 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
3985 error("The operands of operation `%s' should be of compatible types",
3986 get_opname());
3987 set_valuetype(V_ERROR);
3988 }
3989 }
3990 }
3991
3992 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
3993 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
3994 {
3995 if(valuetype==V_ERROR) return;
3996 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3997 Assignment *t_ass = ref->get_refd_assignment();
3998 if(!t_ass) goto error;
3999 switch(t_ass->get_asstype()) {
4000 case Assignment::A_TIMER:
4001 case Assignment::A_PAR_TIMER:
4002 u.expr.v_optype=OPTYPE_TMR_RUNNING;
4003 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
4004 chk_expr_dynamic_part(exp_val, true);
4005 break;
4006 case Assignment::A_CONST:
4007 case Assignment::A_EXT_CONST:
4008 case Assignment::A_MODULEPAR:
4009 case Assignment::A_VAR:
4010 case Assignment::A_FUNCTION_RVAL:
4011 case Assignment::A_EXT_FUNCTION_RVAL:
4012 case Assignment::A_PAR_VAL_IN:
4013 case Assignment::A_PAR_VAL_OUT:
4014 case Assignment::A_PAR_VAL_INOUT: {
4015 u.expr.v_optype = OPTYPE_COMP_RUNNING;
4016 Value* val = new Value(V_REFD, u.expr.r1);
4017 val->set_my_scope(my_scope);
4018 val->set_fullname(u.expr.r1->get_fullname());
4019 val->set_location(*u.expr.r1);
4020 u.expr.v1 = val;
4021 chk_expr_operand_compref(val, opnum, get_opname());
4022 chk_expr_dynamic_part(exp_val, false);
4023 break; }
4024 default:
4025 ref->error("%s operand of operation `%s' should be timer or"
4026 " component reference instead of %s",
4027 opnum, opname, t_ass->get_description().c_str());
4028 goto error;
4029 } // switch
4030 return;
4031 error:
4032 set_valuetype(V_ERROR);
4033 }
4034
4035 Type *Value::chk_expr_operand_comptyperef_create()
4036 {
4037 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4038 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4039 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4040 if (!t_ass) goto error;
4041 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4042 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4043 Type::EXPECTED_DYNAMIC_VALUE);
4044 if (!t_type) goto error;
4045 t_type = t_type->get_type_refd_last();
4046 if (t_type->get_typetype() == Type::T_COMPONENT) {
4047 if (my_governor) {
4048 Type *my_governor_last = my_governor->get_type_refd_last();
4049 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4050 !my_governor_last->is_compatible(t_type, NULL)) {
4051 u.expr.r1->error("Incompatible component types: operation "
4052 "`create' should refer to `%s' instead of "
4053 "`%s'",
4054 my_governor_last->get_typename().c_str(),
4055 t_type->get_typename().c_str());
4056 goto error;
4057 }
4058 }
4059 return t_type;
4060 } else {
4061 u.expr.r1->error("Type mismatch: reference to a component type was "
4062 "expected in operation `create' instead of `%s'",
4063 t_type->get_typename().c_str());
4064 }
4065 } else {
4066 u.expr.r1->error("Operation `create' should refer to a component type "
4067 "instead of %s", t_ass->get_description().c_str());
4068 }
4069 error:
4070 set_valuetype(V_ERROR);
4071 return NULL;
4072 }
4073
4074 void Value::chk_expr_comptype_compat()
4075 {
4076 if (valuetype != V_EXPR)
4077 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4078 if (!my_governor || !my_scope) return;
4079 Type *my_governor_last = my_governor->get_type_refd_last();
4080 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4081 Type *t_comptype;
4082 switch (u.expr.v_optype) {
4083 case OPTYPE_COMP_MTC:
4084 t_comptype = my_scope->get_mtc_system_comptype(false);
4085 break;
4086 case OPTYPE_COMP_SYSTEM:
4087 t_comptype = my_scope->get_mtc_system_comptype(true);
4088 break;
4089 case OPTYPE_COMP_SELF: {
4090 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4091 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4092 break; }
4093 default:
4094 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4095 t_comptype = 0;
4096 break;
4097 }
4098 if (t_comptype
4099 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4100 error("Incompatible component types: a component reference of "
4101 "type `%s' was expected, but `%s' has type `%s'",
4102 my_governor_last->get_typename().c_str(), get_opname(),
4103 t_comptype->get_typename().c_str());
4104 set_valuetype(V_ERROR);
4105 }
4106 }
4107
4108 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4109 const char *opname)
4110 {
4111 if(valuetype == V_ERROR) return;
4112 switch(val->get_valuetype()) {
4113 case V_INVOKE: {
4114 Error_Context cntxt(this, "In `%s' operation", opname);
4115 Value *v_last = val->get_value_refd_last();
4116 if(!v_last) goto error;
4117 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4118 if(!t) goto error;
4119 t = t->get_type_refd_last();
4120 if(t->get_typetype() != Type::T_COMPONENT) {
4121 v_last->error("%s operand of operation `%s': Type mismatch:"
4122 " component reference was expected instead of `%s'",
4123 opnum, opname, t->get_typename().c_str());
4124 goto error;
4125 }
4126 return; }
4127 case V_REFD: {
4128 Reference *ref = val->get_reference();
4129 Assignment *t_ass = ref->get_refd_assignment();
4130 Value *t_val = 0;
4131 if (!t_ass) goto error;
4132 switch(t_ass->get_asstype()) {
4133 case Assignment::A_CONST:
4134 t_val = t_ass->get_Value();
4135 // no break
4136 case Assignment::A_EXT_CONST:
4137 case Assignment::A_MODULEPAR:
4138 case Assignment::A_VAR:
4139 case Assignment::A_FUNCTION_RVAL:
4140 case Assignment::A_EXT_FUNCTION_RVAL:
4141 case Assignment::A_PAR_VAL_IN:
4142 case Assignment::A_PAR_VAL_OUT:
4143 case Assignment::A_PAR_VAL_INOUT: {
4144 Type *t_type=t_ass->get_Type()
4145 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4146 if(!t_type) goto error;
4147 t_type=t_type->get_type_refd_last();
4148 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4149 ref->error("%s operand of operation `%s': Type mismatch:"
4150 " component reference was expected instead of `%s'",
4151 opnum, opname, t_type->get_typename().c_str());
4152 goto error;
4153 }
4154 break;}
4155 default:
4156 ref->error("%s operand of operation `%s' should be"
4157 " component reference instead of %s",
4158 opnum, opname, t_ass->get_description().c_str());
4159 goto error;
4160 }
4161 if (t_val) {
4162 ReferenceChain refch(this, "While searching referenced value");
4163 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4164 if (!t_val) return;
4165 t_val = t_val->get_value_refd_last();
4166 if (t_val->valuetype != V_EXPR) return;
4167 switch (t_val->u.expr.v_optype) {
4168 case OPTYPE_COMP_NULL:
4169 ref->error("%s operand of operation `%s' refers to `null' component "
4170 "reference", opnum, opname);
4171 goto error;
4172 case OPTYPE_COMP_MTC:
4173 ref->error("%s operand of operation `%s' refers to the component "
4174 "reference of the `mtc'", opnum, opname);
4175 goto error;
4176 case OPTYPE_COMP_SYSTEM:
4177 ref->error("%s operand of operation `%s' refers to the component "
4178 "reference of the `system'", opnum, opname);
4179 goto error;
4180 default:
4181 break;
4182 }
4183 }
4184 return;}
4185 default:
4186 FATAL_ERROR("Value::chk_expr_operand_compref()");
4187 }
4188 error:
4189 set_valuetype(V_ERROR);
4190 }
4191
4192 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4193 const char *opnum,
4194 const char *opname)
4195 {
4196 if(valuetype==V_ERROR) return;
4197 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4198 Assignment *t_ass = ref->get_refd_assignment();
4199 if(!t_ass) goto error;
4200 switch(t_ass->get_asstype()) {
4201 case Assignment::A_TIMER: {
4202 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4203 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4204 Type::EXPECTED_DYNAMIC_VALUE);
4205 else if (ref->get_subrefs()) {
4206 ref->error("%s operand of operation `%s': "
4207 "Reference to single timer `%s' cannot have field or array "
4208 "sub-references", opnum, opname,
4209 t_ass->get_id().get_dispname().c_str());
4210 goto error;
4211 }
4212 break; }
4213 case Assignment::A_PAR_TIMER:
4214 if (ref->get_subrefs()) {
4215 ref->error("%s operand of operation `%s': "
4216 "Reference to %s cannot have field or array sub-references",
4217 opnum, opname, t_ass->get_description().c_str());
4218 goto error;
4219 }
4220 break;
4221 default:
4222 ref->error("%s operand of operation `%s' should be timer"
4223 " instead of %s",
4224 opnum, opname, t_ass->get_description().c_str());
4225 goto error;
4226 } // switch
4227 return;
4228 error:
4229 set_valuetype(V_ERROR);
4230 }
4231
4232 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4233 const char *,
4234 const char *opname)
4235 {
4236 if(valuetype==V_ERROR) return;
4237 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4238 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4239 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4240 Error_Context cntxt(this, "In `%s' operation", opname);
4241 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4242 }
4243
4244 void Value::chk_expr_operand_activate_refd(Value *val,
4245 Ttcn::TemplateInstances* t_list2,
4246 Ttcn::ActualParList *&parlist,
4247 const char *,
4248 const char *opname)
4249 {
4250 if(valuetype==V_ERROR) return;
4251 Error_Context cntxt(this, "In `%s' operation", opname);
4252 Type *t = val->get_expr_governor_last();
4253 if (t) {
4254 switch (t->get_typetype()) {
4255 case Type::T_ERROR:
4256 set_valuetype(V_ERROR);
4257 break;
4258 case Type::T_ALTSTEP: {
4259 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4260 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4261 if(is_erroneous) {
4262 delete parlist;
4263 parlist = 0;
4264 set_valuetype(V_ERROR);
4265 } else {
4266 parlist->set_fullname(get_fullname());
4267 parlist->set_my_scope(get_my_scope());
4268 if (!fp_list->chk_activate_argument(parlist,
4269 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4270 }
4271 break; }
4272 default:
4273 error("Reference to an altstep was expected in the argument of "
4274 "`derefers()' instead of `%s'", t->get_typename().c_str());
4275 set_valuetype(V_ERROR);
4276 break;
4277 }
4278 } else set_valuetype(V_ERROR);
4279 }
4280
4281 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4282 const char *,
4283 const char *opname)
4284 {
4285 if(valuetype==V_ERROR) return;
4286 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4287 Error_Context cntxt(this, "In `%s' operation", opname);
4288 Assignment *t_ass = ref->get_refd_assignment();
4289 bool error_flag = false;
4290 if (t_ass) {
4291 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4292 ref->error("Reference to a testcase was expected in the argument "
4293 "instead of %s", t_ass->get_description().c_str());
4294 error_flag = true;
4295 }
4296 } else error_flag = true;
4297 if (val) {
4298 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4299 Value *v_last = val->get_value_refd_last();
4300 switch (v_last->valuetype) {
4301 case V_REAL: {
4302 ttcn3float v_real = v_last->get_val_Real();
4303 if (v_real < 0.0) {
4304 val->error("The testcase guard timer has negative value: `%s'",
4305 Real2string(v_real).c_str());
4306 error_flag = true;
4307 }
4308 break; }
4309 case V_ERROR:
4310 error_flag = true;
4311 break;
4312 default:
4313 break;
4314 }
4315 }
4316 if (error_flag) set_valuetype(V_ERROR);
4317 }
4318
4319 void Value::chk_expr_operand_execute_refd(Value *v1,
4320 Ttcn::TemplateInstances* t_list2,
4321 Ttcn::ActualParList *&parlist,
4322 Value *v3,
4323 const char *,
4324 const char *opname)
4325 {
4326 if(valuetype==V_ERROR) return;
4327 Error_Context cntxt(this, "In `%s' operation", opname);
4328 Type *t = v1->get_expr_governor_last();
4329 if (t) {
4330 switch (t->get_typetype()) {
4331 case Type::T_ERROR:
4332 set_valuetype(V_ERROR);
4333 break;
4334 case Type::T_TESTCASE: {
4335 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4336 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4337 if(is_erroneous) {
4338 delete parlist;
4339 parlist = 0;
4340 set_valuetype(V_ERROR);
4341 } else {
4342 parlist->set_fullname(get_fullname());
4343 parlist->set_my_scope(get_my_scope());
4344 }
4345 break; }
4346 default:
4347 v1->error("Reference to a value of type testcase was expected in the "
4348 "argument of `derefers()' instead of `%s'",
4349 t->get_typename().c_str());
4350 set_valuetype(V_ERROR);
4351 break;
4352 }
4353 } else set_valuetype(V_ERROR);
4354 if (v3) {
4355 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4356 Value *v_last = v3->get_value_refd_last();
4357 switch (v_last->valuetype) {
4358 case V_REAL: {
4359 ttcn3float v_real = v_last->get_val_Real();
4360 if(v_real < 0.0) {
4361 v3->error("The testcase guard timer has negative value: `%s'",
4362 Real2string(v_real).c_str());
4363 set_valuetype(V_ERROR);
4364 }
4365 break; }
4366 case V_ERROR:
4367 set_valuetype(V_ERROR);
4368 break;
4369 default:
4370 break;
4371 }
4372 }
4373 }
4374
4375 void Value::chk_invoke(Type::expected_value_t exp_val)
4376 {
4377 if(valuetype == V_ERROR) return;
4378 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4379 if(!u.invoke.t_list) return; //already checked
4380 Error_Context cntxt(this, "In `apply()' operation");
4381 Type *t = u.invoke.v->get_expr_governor_last();
4382 if (!t) {
4383 set_valuetype(V_ERROR);
4384 return;
4385 }
4386 switch (t->get_typetype()) {
4387 case Type::T_ERROR:
4388 set_valuetype(V_ERROR);
4389 return;
4390 case Type::T_FUNCTION:
4391 break;
4392 default:
4393 u.invoke.v->error("A value of type function was expected in the "
4394 "argument instead of `%s'", t->get_typename().c_str());
4395 set_valuetype(V_ERROR);
4396 return;
4397 }
4398 my_scope->chk_runs_on_clause(t, *this, "call");
4399 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4400 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4401 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4402 delete u.invoke.t_list;
4403 u.invoke.t_list = 0;
4404 if(is_erroneous) {
4405 delete parlist;
4406 u.invoke.ap_list = 0;
4407 } else {
4408 parlist->set_fullname(get_fullname());
4409 parlist->set_my_scope(get_my_scope());
4410 u.invoke.ap_list = parlist;
4411 }
4412 switch (exp_val) {
4413 case Type::EXPECTED_CONSTANT:
4414 error("An evaluable constant value was expected instead of operation "
4415 "`apply()'");
4416 set_valuetype(V_ERROR);
4417 break;
4418 case Type::EXPECTED_STATIC_VALUE:
4419 error("A static value was expected instead of operation `apply()'");
4420 set_valuetype(V_ERROR);
4421 break;
4422 default:
4423 break;
4424 } // switch
4425 }
4426
4427 void Value::chk_expr_eval_value(Value *val, Type &t,
4428 ReferenceChain *refch,
4429 Type::expected_value_t exp_val)
4430 {
4431 bool self_ref = false;
4432 if(valuetype==V_ERROR) return;
4433 // Commented out to report more errors :)
4434 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4435 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4436 switch(val->get_valuetype()) {
4437 case V_REFD:
4438 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4439 break;
4440 case V_EXPR:
4441 case V_MACRO:
4442 case V_INVOKE:
4443 val->get_value_refd_last(refch, exp_val);
4444 break;
4445 default:
4446 break;
4447 } // switch
4448 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4449
4450 (void)self_ref;
4451 }
4452
4453 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4454 ReferenceChain *refch, Type::expected_value_t exp_val)
4455 {
4456 bool self_ref = false;
4457 ti->chk(type);
4458 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4459 ti->error("Reference to a %s value was expected instead of an in-line "
4460 "modified template",
4461 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4462 set_valuetype(V_ERROR);
4463 return;
4464 }
4465 Template *templ = ti->get_Template();
4466 switch (templ->get_templatetype()) {
4467 case Template::TEMPLATE_REFD:
4468 // not foldable
4469 if (exp_val == Type::EXPECTED_TEMPLATE) {
4470 templ = templ->get_template_refd_last(refch);
4471 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4472 set_valuetype(V_ERROR);
4473 } else {
4474 ti->error("Reference to a %s value was expected instead of %s",
4475 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4476 templ->get_reference()->get_refd_assignment()
4477 ->get_description().c_str());
4478 set_valuetype(V_ERROR);
4479 }
4480 break;
4481 case Template::SPECIFIC_VALUE: {
4482 Value *val = templ->get_specific_value();
4483 switch (val->get_valuetype()) {
4484 case V_REFD:
4485 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4486 break;
4487 case V_EXPR:
4488 val->get_value_refd_last(refch, exp_val);
4489 default:
4490 break;
4491 } // switch
4492 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4493 break; }
4494 case Template::TEMPLATE_ERROR:
4495 set_valuetype(V_ERROR);
4496 break;
4497 default:
4498 break;
4499 } // switch
4500
4501 (void)self_ref;
4502 }
4503
4504 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4505 const char *opname)
4506 {
4507 if(valuetype==V_ERROR) return;
4508 if(u.expr.state==EXPR_CHECKING_ERR) return;
4509 if(val->is_unfoldable()) return;
4510 if(*val->get_val_Int()<0) {
4511 val->error("%s operand of operation `%s' should not be negative",
4512 opnum, opname);
4513 set_valuetype(V_ERROR);
4514 }
4515 }
4516
4517 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4518 const char *opname)
4519 {
4520 if(valuetype==V_ERROR) return;
4521 if(u.expr.state==EXPR_CHECKING_ERR) return;
4522 if(val->is_unfoldable()) return;
4523 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4524 val->error("%s operand of operation `%s' should be in range 0..127",
4525 opnum, opname);
4526 set_valuetype(V_ERROR);
4527 }
4528 }
4529
4530 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4531 const char *opname)
4532 {
4533 if(valuetype==V_ERROR) return;
4534 if(u.expr.state==EXPR_CHECKING_ERR) return;
4535 if(val->is_unfoldable()) return;
4536 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4537 val->error("%s operand of operation `%s' should be in range"
4538 " 0..2147483647", opnum, opname);
4539 set_valuetype(V_ERROR);
4540 }
4541 }
4542
4543 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4544 const char *opname)
4545 {
4546 if(valuetype==V_ERROR) return;
4547 if(u.expr.state==EXPR_CHECKING_ERR) return;
4548 if(val->is_unfoldable()) return;
4549 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4550 ||
4551 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4552 {
4553 val->error("%s operand of operation `%s' should not be zero",
4554 opnum, opname);
4555 set_valuetype(V_ERROR);
4556 }
4557 }
4558
4559 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4560 const char *opname)
4561 {
4562 if (valuetype == V_ERROR) return;
4563 if (u.expr.state == EXPR_CHECKING_ERR) return;
4564 if (val->get_expr_returntype() != Type::T_INT) return;
4565 if (val->is_unfoldable()) return;
4566 const int_val_t *val_int = val->get_val_Int();
4567 if (*val_int > static_cast<Int>(INT_MAX)) {
4568 val->error("%s operand of operation `%s' should be less than `%d' "
4569 "instead of `%s'", opnum, opname, INT_MAX,
4570 (val_int->t_str()).c_str());
4571 set_valuetype(V_ERROR);
4572 }
4573 }
4574
4575 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4576 const char *opname)
4577 {
4578 if(valuetype==V_ERROR) return;
4579 if(u.expr.state==EXPR_CHECKING_ERR) return;
4580 if(val->is_unfoldable()) return;
4581 if(val->get_val_strlen()!=1) {
4582 val->error("%s operand of operation `%s' should be of length 1",
4583 opnum, opname);
4584 set_valuetype(V_ERROR);
4585 }
4586 }
4587
4588 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4589 const char *opname)
4590 {
4591 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4592 Value *v_last = val->get_value_refd_last();
4593 if (v_last->valuetype == V_CSTR) {
4594 size_t len = v_last->get_val_strlen();
4595 if (len % 2) {
4596 val->error("%s operand of operation `%s' should contain even number "
4597 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4598 set_valuetype(V_ERROR);
4599 }
4600 } else if (v_last->valuetype == V_REFD) {
4601 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4602 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4603 val->error("%s operand of operation `%s' should contain even number "
4604 "of characters, but a string element contains 1", opnum, opname);
4605 set_valuetype(V_ERROR);
4606 }
4607 }
4608 }
4609
4610 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4611 const char *opname)
4612 {
4613 if(valuetype==V_ERROR) return;
4614 if(u.expr.state==EXPR_CHECKING_ERR) return;
4615 if(val->is_unfoldable()) return;
4616 const string& s=val->get_val_str();
4617 for(size_t i=0; i<s.size(); i++) {
4618 char c=s[i];
4619 if(!(c=='0' || c=='1')) {
4620 val->error("%s operand of operation `%s' can contain only"
4621 " binary digits (position %lu is `%c')",
4622 opnum, opname, (unsigned long) i, c);
4623 set_valuetype(V_ERROR);
4624 return;
4625 }
4626 }
4627 }
4628
4629 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4630 const char *opname)
4631 {
4632 if(valuetype==V_ERROR) return;
4633 if(u.expr.state==EXPR_CHECKING_ERR) return;
4634 if(val->is_unfoldable()) return;
4635 const string& s=val->get_val_str();
4636 for(size_t i=0; i<s.size(); i++) {
4637 char c=s[i];
4638 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4639 val->error("%s operand of operation `%s' can contain only valid "
4640 "hexadecimal digits (position %lu is `%c')",
4641 opnum, opname, (unsigned long) i, c);
4642 set_valuetype(V_ERROR);
4643 return;
4644 }
4645 }
4646 }
4647
4648 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4649 const char *opname)
4650 {
4651 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4652 Value *v = val->get_value_refd_last();
4653 if (v->valuetype != V_OSTR) return;
4654 const string& s = val->get_val_str();
4655 size_t n_octets = s.size() / 2;
4656 for (size_t i = 0; i < n_octets; i++) {
4657 char c = s[2 * i];
4658 if (!(c >= '0' && c <= '7')) {
4659 val->error("%s operand of operation `%s' shall consist of octets "
4660 "within the range 00 .. 7F, but the string `%s'O contains octet "
4661 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4662 (unsigned long) i);
4663 set_valuetype(V_ERROR);
4664 return;
4665 }
4666 }
4667 }
4668
4669 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4670 const char *opname)
4671 {
4672 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4673 Value *v_last = val->get_value_refd_last();
4674 if (v_last->valuetype != V_CSTR) return;
4675 const string& s = v_last->get_val_str();
4676 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4677 state = S_INITIAL;
4678 // state: expected characters
4679 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4680 // S_FIRST: first digit
4681 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4682 // S_END: trailing whitespace
4683 // S_ERR: error was found, stop
4684 for (size_t i = 0; i < s.size(); i++) {
4685 char c = s[i];
4686 switch (state) {
4687 case S_INITIAL:
4688 case S_INITIAL_WS:
4689 if (c == '+' || c == '-') state = S_FIRST;
4690 else if (c == '0') state = S_ZERO;
4691 else if (c >= '1' && c <= '9') state = S_MORE;
4692 else if (string::is_whitespace(c)) {
4693 if (state == S_INITIAL) {
4694 val->warning("Leading whitespace was detected and ignored in the "
4695 "operand of operation `%s'", opname);
4696 state = S_INITIAL_WS;
4697 }
4698 } else state = S_ERR;
4699 break;
4700 case S_FIRST:
4701 if (c == '0') state = S_ZERO;
4702 else if (c >= '1' && c <= '9') state = S_MORE;
4703 else state = S_ERR;
4704 break;
4705 case S_ZERO:
4706 if (c >= '0' && c <= '9') {
4707 val->warning("Leading zero digit was detected and ignored in the "
4708 "operand of operation `%s'", opname);
4709 state = S_MORE;
4710 } else if (string::is_whitespace(c)) state = S_END;
4711 else state = S_ERR;
4712 break;
4713 case S_MORE:
4714 if (c >= '0' && c <= '9') {}
4715 else if (string::is_whitespace(c)) state = S_END;
4716 else state = S_ERR;
4717 break;
4718 case S_END:
4719 if (!string::is_whitespace(c)) state = S_ERR;
4720 break;
4721 default:
4722 break;
4723 }
4724 if (state == S_ERR) {
4725 if (string::is_printable(c)) {
4726 val->error("%s operand of operation `%s' should be a string "
4727 "containing a valid integer value, but invalid character `%c' "
4728 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4729 } else {
4730 val->error("%s operand of operation `%s' should be a string "
4731 "containing a valid integer value, but invalid character with "
4732 "character code %u was detected at index %lu", opnum, opname, c,
4733 (unsigned long) i);
4734 }
4735 set_valuetype(V_ERROR);
4736 break;
4737 }
4738 }
4739 switch (state) {
4740 case S_INITIAL:
4741 case S_INITIAL_WS:
4742 val->error("%s operand of operation `%s' should be a string containing a "
4743 "valid integer value instead of an empty string", opnum, opname);
4744 set_valuetype(V_ERROR);
4745 break;
4746 case S_FIRST:
4747 val->error("%s operand of operation `%s' should be a string containing a "
4748 "valid integer value, but only a sign character was detected", opnum,
4749 opname);
4750 set_valuetype(V_ERROR);
4751 break;
4752 case S_END:
4753 val->warning("Trailing whitespace was detected and ignored in the "
4754 "operand of operation `%s'", opname);
4755 break;
4756 default:
4757 break;
4758 }
4759 }
4760
4761 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4762 const char *opname)
4763 {
4764 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4765 Value *v_last = val->get_value_refd_last();
4766 if (v_last->valuetype == V_REFD) {
4767 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4768 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4769 val->error("%s operand of operation `%s' should be a string containing "
4770 "a valid float value instead of a string element, which cannot "
4771 "represent a floating point number", opnum, opname);
4772 set_valuetype(V_ERROR);
4773 }
4774 return;
4775 } else if (v_last->valuetype != V_CSTR) return;
4776 const string& s = v_last->get_val_str();
4777 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4778 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4779 state = S_INITIAL;
4780 // state: expected characters
4781 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4782 // leading whitespace
4783 // S_FIRST_M: first digit of integer part in mantissa
4784 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4785 // S_FIRST_F: first digit of fraction
4786 // S_MORE_F: more digits of fraction, E, trailing whitespace
4787 // S_INITIAL_E: +, -, first digit of exponent
4788 // S_FIRST_E: first digit of exponent
4789 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4790 // S_END: trailing whitespace
4791 // S_ERR: error was found, stop
4792 for (size_t i = 0; i < s.size(); i++) {
4793 char c = s[i];
4794 switch (state) {
4795 case S_INITIAL:
4796 case S_INITIAL_WS:
4797 if (c == '+' || c == '-') state = S_FIRST_M;
4798 else if (c == '0') state = S_ZERO_M;
4799 else if (c >= '1' && c <= '9') state = S_MORE_M;
4800 else if (string::is_whitespace(c)) {
4801 if (state == S_INITIAL) {
4802 val->warning("Leading whitespace was detected and ignored in the "
4803 "operand of operation `%s'", opname);
4804 state = S_INITIAL_WS;
4805 }
4806 } else state = S_ERR;
4807 break;
4808 case S_FIRST_M:
4809 if (c == '0') state = S_ZERO_M;
4810 else if (c >= '1' && c <= '9') state = S_MORE_M;
4811 else state = S_ERR;
4812 break;
4813 case S_ZERO_M:
4814 if (c == '.') state = S_FIRST_F;
4815 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4816 else if (c >= '0' && c <= '9') {
4817 val->warning("Leading zero digit was detected and ignored in the "
4818 "mantissa of the operand of operation `%s'", opname);
4819 state = S_MORE_M;
4820 } else state = S_ERR;
4821 break;
4822 case S_MORE_M:
4823 if (c == '.') state = S_FIRST_F;
4824 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4825 else if (c >= '0' && c <= '9') {}
4826 else state = S_ERR;
4827 break;
4828 case S_FIRST_F:
4829 if (c >= '0' && c <= '9') state = S_MORE_F;
4830 else state = S_ERR;
4831 break;
4832 case S_MORE_F:
4833 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4834 else if (c >= '0' && c <= '9') {}
4835 else if (string::is_whitespace(c)) state = S_END;
4836 else state = S_ERR;
4837 break;
4838 case S_INITIAL_E:
4839 if (c == '+' || c == '-') state = S_FIRST_E;
4840 else if (c == '0') state = S_ZERO_E;
4841 else if (c >= '1' && c <= '9') state = S_MORE_E;
4842 else state = S_ERR;
4843 break;
4844 case S_FIRST_E:
4845 if (c == '0') state = S_ZERO_E;
4846 else if (c >= '1' && c <= '9') state = S_MORE_E;
4847 else state = S_ERR;
4848 break;
4849 case S_ZERO_E:
4850 if (c >= '0' && c <= '9') {
4851 val->warning("Leading zero digit was detected and ignored in the "
4852 "exponent of the operand of operation `%s'", opname);
4853 state = S_MORE_E;
4854 } else if (string::is_whitespace(c)) state = S_END;
4855 else state = S_ERR;
4856 break;
4857 case S_MORE_E:
4858 if (c >= '0' && c <= '9') {}
4859 else if (string::is_whitespace(c)) state = S_END;
4860 else state = S_ERR;
4861 break;
4862 case S_END:
4863 if (!string::is_whitespace(c)) state = S_ERR;
4864 break;
4865 default:
4866 break;
4867 }
4868 if (state == S_ERR) {
4869 if (string::is_printable(c)) {
4870 val->error("%s operand of operation `%s' should be a string "
4871 "containing a valid float value, but invalid character `%c' "
4872 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4873 } else {
4874 val->error("%s operand of operation `%s' should be a string "
4875 "containing a valid float value, but invalid character with "
4876 "character code %u was detected at index %lu", opnum, opname, c,
4877 (unsigned long) i);
4878 }
4879 set_valuetype(V_ERROR);
4880 break;
4881 }
4882 }
4883 switch (state) {
4884 case S_INITIAL:
4885 case S_INITIAL_WS:
4886 val->error("%s operand of operation `%s' should be a string containing a "
4887 "valid float value instead of an empty string", opnum, opname);
4888 set_valuetype(V_ERROR);
4889 break;
4890 case S_FIRST_M:
4891 val->error("%s operand of operation `%s' should be a string containing a "
4892 "valid float value, but only a sign character was detected", opnum,
4893 opname);
4894 set_valuetype(V_ERROR);
4895 break;
4896 case S_ZERO_M:
4897 case S_MORE_M:
4898 // HL67862: Missing decimal dot allowed for str2float
4899 break;
4900 case S_FIRST_F:
4901 // HL67862: Missing fraction part is allowed for str2float
4902 break;
4903 case S_INITIAL_E:
4904 case S_FIRST_E:
4905 val->error("%s operand of operation `%s' should be a string containing a "
4906 "valid float value, but the exponent is missing after the `E' sign",
4907 opnum, opname);
4908 set_valuetype(V_ERROR);
4909 break;
4910 case S_END:
4911 val->warning("Trailing whitespace was detected and ignored in the "
4912 "operand of operation `%s'", opname);
4913 break;
4914 default:
4915 break;
4916 }
4917 }
4918
4919 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
4920 const char *opname)
4921 {
4922 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4923 Value *v = val->get_value_refd_last();
4924 if (v->valuetype != V_USTR) return;
4925 const ustring& us = v->get_val_ustr();
4926 for (size_t i = 0; i < us.size(); i++) {
4927 const ustring::universal_char& uchar = us[i];
4928 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
4929 uchar.cell > 127) {
4930 val->error("%s operand of operation `%s' shall consist of characters "
4931 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
4932 "string %s contains character char(%u, %u, %u, %u) at index %lu",
4933 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
4934 uchar.row, uchar.cell, (unsigned long) i);
4935 set_valuetype(V_ERROR);
4936 return;
4937 }
4938 }
4939 }
4940
4941 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
4942 const char *opname)
4943 {
4944 if(valuetype==V_ERROR) return;
4945 if(u.expr.state==EXPR_CHECKING_ERR) return;
4946 if(val->is_unfoldable()) return;
4947 const string& bstr=val->get_val_str();
4948 // see also PredefFunc.cc::bit2int()
4949 size_t nof_bits = bstr.size();
4950 // skip the leading zeros
4951 size_t start_index = 0;
4952 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
4953 // check whether the remaining bits fit in Int
4954 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
4955 val->error("%s operand of operation `%s' is too large (maximum number"
4956 " of bits in integer is %lu)",
4957 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4958 set_valuetype(V_ERROR);
4959 }
4960 }
4961
4962 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
4963 const char *opname)
4964 {
4965 if(valuetype==V_ERROR) return;
4966 if(u.expr.state==EXPR_CHECKING_ERR) return;
4967 if(val->is_unfoldable()) return;
4968 const string& hstr=val->get_val_str();
4969 // see also PredefFunc.cc::hex2int()
4970 size_t nof_digits = hstr.size();
4971 // skip the leading zeros
4972 size_t start_index = 0;
4973 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
4974 // check whether the remaining hex digits fit in Int
4975 if (nof_digits - start_index > 2 * sizeof(Int) ||
4976 (nof_digits - start_index == 2 * sizeof(Int) &&
4977 char_to_hexdigit(hstr[start_index]) > 7)) {
4978 val->error("%s operand of operation `%s' is too large (maximum number"
4979 " of bits in integer is %lu)",
4980 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
4981 set_valuetype(V_ERROR);
4982 }
4983 }
4984
4985 void Value::chk_expr_operands_int2binstr()
4986 {
4987 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4988 if (u.expr.v1->is_unfoldable()) return;
4989 if (u.expr.v2->is_unfoldable()) return;
4990 // It is already checked that i1 and i2 are non-negative.
4991 Error_Context cntxt(this, "In operation `%s'", get_opname());
4992 const int_val_t *i1 = u.expr.v1->get_val_Int();
4993 const int_val_t *i2 = u.expr.v2->get_val_Int();
4994 if (!i2->is_native()) {
4995 u.expr.v2->error("The length of the resulting string is too large for "
4996 "being represented in memory");
4997 set_valuetype(V_ERROR);
4998 return;
4999 }
5000 Int nof_bits = i2->get_val();
5001 if (u.expr.v1->is_unfoldable()) return;
5002 switch (u.expr.v_optype) {
5003 case OPTYPE_INT2BIT:
5004 break;
5005 case OPTYPE_INT2HEX:
5006 nof_bits *= 4;
5007 break;
5008 case OPTYPE_INT2OCT:
5009 nof_bits *= 8;
5010 break;
5011 default:
5012 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5013 }
5014 if (*i1 >> nof_bits > 0) { // Expensive?
5015 u.expr.v1->error("Value %s does not fit in length %s",
5016 i1->t_str().c_str(), i2->t_str().c_str());
5017 set_valuetype(V_ERROR);
5018 }
5019 }
5020
5021 void Value::chk_expr_operands_str_samelen()
5022 {
5023 if(valuetype==V_ERROR) return;
5024 if(u.expr.state==EXPR_CHECKING_ERR) return;
5025 Value *v1=u.expr.v1;
5026 if(v1->is_unfoldable()) return;
5027 Value *v2=u.expr.v2;
5028 if(v2->is_unfoldable()) return;
5029 Error_Context cntxt(this, "In operation `%s'", get_opname());
5030 size_t i1=v1->get_val_strlen();
5031 size_t i2=v2->get_val_strlen();
5032 if(i1!=i2) {
5033 error("The operands should have the same length");
5034 set_valuetype(V_ERROR);
5035 }
5036 }
5037
5038 void Value::chk_expr_operands_replace()
5039 {
5040 // The fourth operand doesn't need to be checked at all here.
5041 if(valuetype==V_ERROR) return;
5042 if(u.expr.state==EXPR_CHECKING_ERR) return;
5043 Value* v1 = u.expr.ti1->get_specific_value();
5044 if (!v1) return;
5045
5046 Error_Context cntxt(this, "In operation `%s'", get_opname());
5047 size_t list_len = 0;
5048 bool list_len_known = false;
5049 if (v1->valuetype == V_REFD) {
5050 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5051 if (subrefs && subrefs->refers_to_string_element()) {
5052 warning("Replacing a string element does not make any sense");
5053 list_len = 1;
5054 list_len_known = true;
5055 }
5056 }
5057 if (!v1->is_unfoldable()) {
5058 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5059 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5060 list_len_known = true;
5061 }
5062 if (!list_len_known) return;
5063 if (u.expr.v2->is_unfoldable()) {
5064 if (!u.expr.v3->is_unfoldable()) {
5065 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5066 if (*len_int_3 > static_cast<Int>(list_len)) {
5067 error("Third operand `len' (%s) is greater than the length of "
5068 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5069 (unsigned long)list_len);
5070 set_valuetype(V_ERROR);
5071 }
5072 }
5073 } else {
5074 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5075 if (u.expr.v3->is_unfoldable()) {
5076 if (*index_int_2 > static_cast<Int>(list_len)) {
5077 error("Second operand `index' (%s) is greater than the length of "
5078 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5079 (unsigned long)list_len);
5080 set_valuetype(V_ERROR);
5081 }
5082 } else {
5083 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5084 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5085 error("The sum of second operand `index' (%s) and third operand "
5086 "`len' (%s) is greater than the length of the first operand (%lu)",
5087 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5088 (unsigned long)list_len);
5089 set_valuetype(V_ERROR);
5090 }
5091 }
5092 }
5093 }
5094
5095 void Value::chk_expr_operands_substr()
5096 {
5097 if(valuetype==V_ERROR) return;
5098 if(u.expr.state==EXPR_CHECKING_ERR) return;
5099 Value* v1 = u.expr.ti1->get_specific_value();
5100 if (!v1) return;
5101
5102 Error_Context cntxt(this, "In operation `%s'", get_opname());
5103 size_t list_len = 0;
5104 bool list_len_known = false;
5105 if (v1->valuetype == V_REFD) {
5106 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5107 if (subrefs && subrefs->refers_to_string_element()) {
5108 warning("Taking the substring of a string element does not make any "
5109 "sense");
5110 list_len = 1;
5111 list_len_known = true;
5112 }
5113 }
5114 if (!list_len_known && !v1->is_unfoldable()) {
5115 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5116 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5117 list_len_known = true;
5118 }
5119 // Do nothing if the length of the first operand is unknown.
5120 if (!list_len_known) return;
5121 if (u.expr.v2->is_unfoldable()) {
5122 if (!u.expr.v3->is_unfoldable()) {
5123 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5124 // Only the third operand is known.
5125 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5126 error("Third operand `returncount' (%s) is greater than the "
5127 "length of the first operand (%lu)",
5128 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5129 set_valuetype(V_ERROR);
5130 }
5131 }
5132 } else {
5133 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5134 if (u.expr.v3->is_unfoldable()) {
5135 // Only the second operand is known.
5136 if (*index_int_2 > static_cast<Int>(list_len)) {
5137 error("Second operand `index' (%s) is greater than the length "
5138 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5139 (unsigned long)list_len);
5140 set_valuetype(V_ERROR);
5141 }
5142 } else {
5143 // Both second and third operands are known.
5144 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5145 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5146 error("The sum of second operand `index' (%s) and third operand "
5147 "`returncount' (%s) is greater than the length of the first operand "
5148 "(%lu)", (index_int_2->t_str()).c_str(),
5149 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5150 set_valuetype(V_ERROR);
5151 }
5152 }
5153 }
5154 }
5155
5156 void Value::chk_expr_operands_regexp()
5157 {
5158 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5159 Value* v1 = u.expr.ti1->get_specific_value();
5160 Value* v2 = u.expr.t2->get_specific_value();
5161 if (!v1 || !v2) return;
5162
5163 Error_Context cntxt(this, "In operation `regexp()'");
5164 Value* v1_last = v1->get_value_refd_last();
5165 if (v1_last->valuetype == V_CSTR) {
5166 // the input string is available at compile time
5167 const string& instr = v1_last->get_val_str();
5168 const char *input_str = instr.c_str();
5169 size_t instr_len = strlen(input_str);
5170 if (instr_len < instr.size()) {
5171 v1->warning("The first operand of `regexp()' contains a "
5172 "character with character code zero at index %s. The rest of the "
5173 "string will be ignored during matching",
5174 Int2string(instr_len).c_str());
5175 }
5176 }
5177
5178 size_t nof_groups = 0;
5179 Value *v2_last = v2->get_value_refd_last();
5180
5181 if (v2_last->valuetype == V_CSTR) {
5182 // the pattern is available at compile time
5183 const string& expression = v2_last->get_val_str();
5184 const char *pattern_str = expression.c_str();
5185 size_t pattern_len = strlen(pattern_str);
5186 if (pattern_len < expression.size()) {
5187 v2->warning("The second operand of `regexp()' contains a "
5188 "character with character code zero at index %s. The rest of the "
5189 "string will be ignored during matching",
5190 Int2string(pattern_len).c_str());
5191 }
5192 char *posix_str;
5193 {
5194 Error_Context cntxt2(v2, "In character string pattern");
5195 posix_str = TTCN_pattern_to_regexp(pattern_str);
5196 }
5197 if (posix_str != NULL) {
5198 regex_t posix_regexp;
5199 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5200 if (ret_val != 0) {
5201 char msg[512];
5202 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5203 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5204 "regcomp() failed: %s", msg);
5205 }
5206 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5207 else {
5208 v2->error("The character pattern in the second operand of "
5209 "`regexp()' does not contain any groups");
5210 set_valuetype(V_ERROR);
5211 }
5212 regfree(&posix_regexp);
5213 Free(posix_str);
5214 } else {
5215 // the pattern is faulty
5216 // the error has been reported by TTCN_pattern_to_regexp
5217 set_valuetype(V_ERROR);
5218 }
5219 }
5220 if (nof_groups > 0) {
5221 Value *v3 = u.expr.v3->get_value_refd_last();
5222 if (v3->valuetype == V_INT) {
5223 // the group number is available at compile time
5224 const int_val_t *groupno_int = v3->get_val_Int();
5225 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5226 u.expr.v3->error("The the third operand of `regexp()' is too "
5227 "large: The requested group index is %s, but the pattern "
5228 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5229 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5230 set_valuetype(V_ERROR);
5231 }
5232 }
5233 }
5234 }
5235
5236 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5237 Type::expected_value_t exp_val)
5238 {
5239 const char *opname = get_opname();
5240 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5241 Type *t_governor;
5242 const Location *loc;
5243 bool error_flag = false;
5244 switch (u.expr.v_optype) {
5245 case OPTYPE_ISCHOSEN_V:
5246 // u.expr.v1 is always a referenced value
5247 t_governor = u.expr.v1->get_expr_governor(exp_val);
5248 if (t_governor) {
5249 u.expr.v1->set_my_governor(t_governor);
5250 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5251 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5252 } else error_flag = true;
5253 loc = u.expr.v1;
5254 break;
5255 case OPTYPE_ISCHOSEN_T:
5256 // u.expr.t1 is always a referenced template
5257 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5258 exp_val = Type::EXPECTED_TEMPLATE;
5259 t_governor = u.expr.t1->get_expr_governor(exp_val);
5260 if (t_governor) {
5261 u.expr.t1->set_my_governor(t_governor);
5262 //
5263 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5264 //
5265 u.expr.t1->get_template_refd_last(refch);
5266 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5267 error_flag = true;
5268 } else error_flag = true;
5269 if (exp_val != Type::EXPECTED_TEMPLATE) {
5270 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5271 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5272 u.expr.t1->get_reference()->get_refd_assignment()
5273 ->get_description().c_str());
5274 error_flag = true;
5275 }
5276 loc = u.expr.t1;
5277 break;
5278 default:
5279 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5280 t_governor = 0;
5281 loc = 0;
5282 }
5283 if (t_governor) {
5284 t_governor = t_governor->get_type_refd_last();
5285 switch (t_governor->get_typetype()) {
5286 case Type::T_ERROR:
5287 error_flag = true;
5288 break;
5289 case Type::T_CHOICE_A:
5290 case Type::T_CHOICE_T:
5291 case Type::T_ANYTYPE:
5292 case Type::T_OPENTYPE:
5293 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5294 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5295 "%s does not have a field named `%s'" :
5296 "Union type `%s' does not have a field named `%s'",
5297 t_governor->get_typename().c_str(),
5298 u.expr.i2->get_dispname().c_str());
5299 error_flag = true;
5300 }
5301 break;
5302 default:
5303 loc->error("The operand of operation `%s' should be a union value "
5304 "or template instead of `%s'", opname,
5305 t_governor->get_typename().c_str());
5306 error_flag = true;
5307 break;
5308 }
5309 }
5310 if (error_flag) set_valuetype(V_ERROR);
5311 }
5312
5313 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5314 Type::expected_value_t exp_val) {
5315
5316 Error_Context cntxt(this, "In the parameter of encvalue()");
5317 Type t_chk(Type::T_ERROR);
5318 Type* t_type;
5319
5320 Type::expected_value_t ti_exp_val = exp_val;
5321 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5322 ti_exp_val = Type::EXPECTED_TEMPLATE;
5323
5324 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5325 if (t_type) {
5326 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5327 if (valuetype!=V_ERROR)
5328 u.expr.ti1->get_Template()->chk_specific_value(false);
5329 t_type = t_type->get_type_refd_last();
5330 } else {
5331 error("Cannot determine type of value");
5332 goto error;
5333 }
5334
5335 // todo: fix this
5336 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5337 error("Expecting a value of a type with coding attributes in first"
5338 "parameter of encvalue() which belongs to a generic type '%s'",
5339 t_type->get_typename().c_str());
5340 goto error;
5341 }*/
5342
5343 if(!disable_attribute_validation()) {
5344 t_type->chk_coding(true);
5345 }
5346
5347 switch (t_type->get_typetype()) {
5348 case Type::T_UNDEF:
5349 case Type::T_ERROR:
5350 case Type::T_NULL:
5351 case Type::T_REFD:
5352 case Type::T_REFDSPEC:
5353 case Type::T_SELTYPE:
5354 case Type::T_VERDICT:
5355 case Type::T_PORT:
5356 case Type::T_COMPONENT:
5357 case Type::T_DEFAULT:
5358 case Type::T_SIGNATURE:
5359 case Type::T_FUNCTION:
5360 case Type::T_ALTSTEP:
5361 case Type::T_TESTCASE:
5362 error("Type of parameter of encvalue() cannot be '%s'",
5363 t_type->get_typename().c_str());
5364 goto error;
5365 default:
5366 break;
5367 }
5368 return;
5369 error:
5370 set_valuetype(V_ERROR);
5371 }
5372
5373 void Value::chk_expr_operands_decode()
5374 {
5375 Error_Context cntxt(this, "In the parameters of decvalue()");
5376 Ttcn::Ref_base* ref = u.expr.r1;
5377 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5378 Type* t_type = 0;
5379 Assignment* t_ass = ref->get_refd_assignment();
5380
5381 if (!t_ass) {
5382 error("Could not determine the assignment for first parameter");
5383 goto error;
5384 }
5385 switch (t_ass->get_asstype()) {
5386 case Assignment::A_PAR_VAL_IN:
5387 t_ass->use_as_lvalue(*this);
5388 break;
5389 case Assignment::A_CONST:
5390 case Assignment::A_EXT_CONST:
5391 case Assignment::A_MODULEPAR:
5392 case Assignment::A_MODULEPAR_TEMP:
5393 case Assignment::A_TEMPLATE:
5394 ref->error("Reference to '%s' cannot be used as the first operand of "
5395 "the 'decvalue' operation", t_ass->get_assname());
5396 goto error;
5397 break;
5398 case Assignment::A_VAR:
5399 case Assignment::A_PAR_VAL_OUT:
5400 case Assignment::A_PAR_VAL_INOUT:
5401 break;
5402 case Assignment::A_VAR_TEMPLATE:
5403 case Assignment::A_PAR_TEMPL_IN:
5404 case Assignment::A_PAR_TEMPL_OUT:
5405 case Assignment::A_PAR_TEMPL_INOUT: {
5406 Template* t = new Template(ref->clone());
5407 t->set_location(*ref);
5408 t->set_my_scope(get_my_scope());
5409 t->set_fullname(get_fullname()+".<operand>");
5410 Template* t_last = t->get_template_refd_last();
5411 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5412 && t_last != t) {
5413 ref->error("Specific value template was expected instead of '%s'.",
5414 t->get_template_refd_last()->get_templatetype_str());
5415 delete t;
5416 goto error;
5417 }
5418 delete t;
5419 break; }
5420 default:
5421 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5422 goto error;
5423 }
5424 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5425 Type::EXPECTED_DYNAMIC_VALUE);
5426 if (!t_type) {
5427 goto error;
5428 }
5429 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5430 error("First parameter has to be a bitstring");
5431 goto error;
5432 }
5433
5434 ref = u.expr.r2;
5435 t_subrefs = ref->get_subrefs();
5436 t_ass = ref->get_refd_assignment();
5437
5438 if (!t_ass) {
5439 error("Could not determine the assignment for second parameter");
5440 goto error;
5441 }
5442 // Extra check for HM59355.
5443 switch (t_ass->get_asstype()) {
5444 case Assignment::A_VAR:
5445 case Assignment::A_PAR_VAL_IN:
5446 case Assignment::A_PAR_VAL_OUT:
5447 case Assignment::A_PAR_VAL_INOUT:
5448 break;
5449 default:
5450 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5451 goto error;
5452 }
5453 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5454 Type::EXPECTED_DYNAMIC_VALUE);
5455 if (!t_type) {
5456 goto error;
5457 }
5458 t_type = t_type->get_type_refd_last();
5459 switch (t_type->get_typetype()) {
5460 case Type::T_UNDEF:
5461 case Type::T_ERROR:
5462 case Type::T_NULL:
5463 case Type::T_REFD:
5464 case Type::T_REFDSPEC:
5465 case Type::T_SELTYPE:
5466 case Type::T_VERDICT:
5467 case Type::T_PORT:
5468 case Type::T_COMPONENT:
5469 case Type::T_DEFAULT:
5470 case Type::T_SIGNATURE:
5471 case Type::T_FUNCTION:
5472 case Type::T_ALTSTEP:
5473 case Type::T_TESTCASE:
5474 error("Type of second parameter cannot be %s",
5475 t_type->get_typename().c_str());
5476 goto error;
5477 default:
5478 break;
5479 }
5480
5481 if(!disable_attribute_validation()) {
5482 t_type->chk_coding(false);
5483 }
5484
5485 return;
5486 error:
5487 set_valuetype(V_ERROR);
5488 }
5489
5490 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5491 {
5492 Ttcn::FieldOrArrayRefs *subrefs;
5493 Identifier *field_id = 0;
5494 Assignment *t_ass;
5495 Type *t_type;
5496 if (valuetype == V_ERROR) return;
5497 else if (valuetype != V_REFD) {
5498 error("Only a referenced value can be compared with `omit'");
5499 goto error;
5500 }
5501 subrefs = u.ref.ref->get_subrefs();
5502 if (subrefs) field_id = subrefs->remove_last_field();
5503 if (!field_id) {
5504 error("Only a reference pointing to an optional record or set field "
5505 "can be compared with `omit'");
5506 goto error;
5507 }
5508 t_ass = u.ref.ref->get_refd_assignment();
5509 if (!t_ass) goto error;
5510 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5511 if (!t_type) goto error;
5512 t_type = t_type->get_type_refd_last();
5513 switch (t_type->get_typetype()) {
5514 case Type::T_ERROR:
5515 goto error;
5516 case Type::T_SEQ_A:
5517 case Type::T_SEQ_T:
5518 case Type::T_SET_A:
5519 case Type::T_SET_T:
5520 break;
5521 default:
5522 error("Only a reference pointing to an optional field of a record"
5523 " or set type can be compared with `omit'");
5524 goto error;
5525 }
5526 if (!t_type->has_comp_withName(*field_id)) {
5527 error("Type `%s' does not have field named `%s'",
5528 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5529 goto error;
5530 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5531 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5532 "`omit'", field_id->get_dispname().c_str(),
5533 t_type->get_typename().c_str());
5534 goto error;
5535 }
5536 // putting the last field_id back to subrefs
5537 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5538 return;
5539 error:
5540 set_valuetype(V_ERROR);
5541 delete field_id;
5542 }
5543
5544 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5545 Type::expected_value_t exp_val)
5546 {
5547 if(valuetype==V_ERROR) return -1;
5548 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5549 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5550 exp_val=Type::EXPECTED_TEMPLATE;
5551
5552 Error_Context cntxt(this, "In the operand of"
5553 " operation `%s'", get_opname());
5554
5555 Int result = -1;
5556 Template* t_templ = u.expr.ti1->get_Template();
5557
5558 if (!t_templ) {
5559 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5560 }
5561
5562 t_templ = t_templ->get_template_refd_last(refch);
5563
5564 // Timer and port arrays are handled separately
5565 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5566 Value* val = t_templ->get_specific_value();
5567 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5568 val->set_lowerid_to_ref();
5569 }
5570 if (val && val->get_valuetype() == V_REFD) {
5571 Reference* ref = val->get_reference();
5572 Assignment* t_ass = ref->get_refd_assignment();
5573 Common::Assignment::asstype_t asstype =
5574 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5575 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5576 if (t_ass->get_Dimensions()) {
5577 // here we have a timer or port array
5578 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5579 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5580 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5581 Type::EXPECTED_DYNAMIC_VALUE);
5582 size_t refd_dim;
5583 if (t_subrefs) {
5584 refd_dim = t_subrefs->get_nof_refs();
5585 size_t nof_dims = t_dims->get_nof_dims();
5586 if (refd_dim >= nof_dims) {
5587 u.expr.ti1->error("Operation is not applicable to a %s",
5588 t_ass->get_assname());
5589 set_valuetype(V_ERROR);
5590 return -1;
5591 }
5592 } else refd_dim = 0;
5593 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5594 } else {
5595 u.expr.ti1->error("Operation is not applicable to single `%s'",
5596 t_ass->get_description().c_str());
5597 set_valuetype(V_ERROR);
5598 return -1;
5599 }
5600 }
5601 }
5602 }
5603
5604 Value* t_val = 0;
5605 Type* t_type = 0;
5606 Assignment* t_ass = 0;
5607 Reference* ref = 0;
5608 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5609 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5610 if (t_type) {
5611 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5612 t_type = t_type->get_type_refd_last();
5613 } else {
5614 error("Cannot determine type of value");
5615 goto error;
5616 }
5617
5618 if(valuetype==V_ERROR) return -1;
5619
5620 t_templ = t_templ->get_template_refd_last(refch);
5621 switch(t_templ->get_templatetype()) {
5622 case Template::TEMPLATE_ERROR:
5623 goto error;
5624 case Template::INDEXED_TEMPLATE_LIST:
5625 return -1;
5626 case Template::TEMPLATE_REFD:
5627 case Template::TEMPLATE_LIST:
5628 case Template::NAMED_TEMPLATE_LIST:
5629 // computed later
5630 break;
5631 case Template::SPECIFIC_VALUE:
5632 {
5633 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5634 if(t_val) {
5635 switch(t_val->get_valuetype()) {
5636 case V_SEQOF:
5637 case V_SETOF:
5638 case V_ARRAY:
5639 case V_ROID:
5640 case V_OID:
5641 case V_SEQ:
5642 case V_SET:
5643 break;
5644 case V_REFD: {
5645 ref = t_val->get_reference();
5646 t_ass = ref->get_refd_assignment();
5647 t_subrefs = ref->get_subrefs();
5648 break;
5649 }
5650 default:
5651 u.expr.ti1->error("Operation is not applicable to `%s'",
5652 t_val->create_stringRepr().c_str());
5653 goto error;
5654 }
5655 }
5656 break;
5657 }
5658 default:
5659 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5660 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5661 goto error;
5662 } // switch
5663
5664 if (t_ass) {
5665 switch(t_ass->get_asstype()) {
5666 case Assignment::A_ERROR:
5667 goto error;
5668 case Assignment::A_CONST:
5669 t_val = t_ass->get_Value();
5670 break;
5671 case Assignment::A_EXT_CONST:
5672 case Assignment::A_MODULEPAR:
5673 case Assignment::A_MODULEPAR_TEMP:
5674 if(exp_val==Type::EXPECTED_CONSTANT) {
5675 u.expr.ti1->error("Reference to an (evaluable) constant value was "
5676 "expected instead of %s", t_ass->get_description().c_str());
5677 goto error;
5678 }
5679 break;
5680 case Assignment::A_VAR:
5681 case Assignment::A_PAR_VAL_IN:
5682 case Assignment::A_PAR_VAL_OUT:
5683 case Assignment::A_PAR_VAL_INOUT:
5684 switch(exp_val) {
5685 case Type::EXPECTED_CONSTANT:
5686 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5687 t_ass->get_description().c_str());
5688 goto error;
5689 break;
5690 case Type::EXPECTED_STATIC_VALUE:
5691 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5692 t_ass->get_description().c_str());
5693 goto error;
5694 break;
5695 default:
5696 break;
5697 }
5698 break;
5699 case Assignment::A_TEMPLATE:
5700 t_templ = t_ass->get_Template();
5701 // no break
5702 case Assignment::A_VAR_TEMPLATE:
5703 case Assignment::A_PAR_TEMPL_IN:
5704 case Assignment::A_PAR_TEMPL_OUT:
5705 case Assignment::A_PAR_TEMPL_INOUT:
5706 if (exp_val!=Type::EXPECTED_TEMPLATE)
5707 u.expr.ti1->error("Reference to a value was expected instead of %s",
5708 t_ass->get_description().c_str());
5709 goto error;
5710 break;
5711 case Assignment::A_FUNCTION_RVAL:
5712 case Assignment::A_EXT_FUNCTION_RVAL:
5713 switch(exp_val) {
5714 case Type::EXPECTED_CONSTANT:
5715 u.expr.ti1->error("Reference to a constant value was expected instead of "
5716 "the return value of %s", t_ass->get_description().c_str());
5717 goto error;
5718 break;
5719 case Type::EXPECTED_STATIC_VALUE:
5720 u.expr.ti1->error("Reference to a static value was expected instead of "
5721 "the return value of %s", t_ass->get_description().c_str());
5722 goto error;
5723 break;
5724 default:
5725 break;
5726 }
5727 break;
5728 case Assignment::A_FUNCTION_RTEMP:
5729 case Assignment::A_EXT_FUNCTION_RTEMP:
5730 if(exp_val!=Type::EXPECTED_TEMPLATE)
5731 u.expr.ti1->error("Reference to a value was expected instead of a call"
5732 " of %s, which returns a template",
5733 t_ass->get_description().c_str());
5734 goto error;
5735 break;
5736 case Assignment::A_TIMER:
5737 case Assignment::A_PORT:
5738 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5739 // sizeof is applicable to timer and port arrays
5740 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5741 if (!t_dims) {
5742 u.expr.ti1->error("Operation is not applicable to single %s",
5743 t_ass->get_description().c_str());
5744 goto error;
5745 }
5746 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5747 Type::EXPECTED_DYNAMIC_VALUE);
5748 size_t refd_dim;
5749 if (t_subrefs) {
5750 refd_dim = t_subrefs->get_nof_refs();
5751 size_t nof_dims = t_dims->get_nof_dims();
5752 if (refd_dim > nof_dims) goto error;
5753 else if (refd_dim == nof_dims) {
5754 u.expr.ti1->error("Operation is not applicable to a %s",
5755 t_ass->get_assname());
5756 goto error;
5757 }
5758 } else refd_dim = 0;
5759 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5760 }
5761 // no break
5762 default:
5763 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5764 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5765 t_ass->get_description().c_str());
5766 goto error;
5767 } // end switch
5768
5769 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5770 if (!t_type) goto error;
5771 t_type = t_type->get_type_refd_last();
5772
5773 switch(t_type->get_typetype()) {
5774 case Type::T_ERROR:
5775 goto error;
5776 case Type::T_SEQOF:
5777 case Type::T_SETOF:
5778 // no break
5779 case Type::T_SEQ_T:
5780 case Type::T_SET_T:
5781 case Type::T_SEQ_A:
5782 case Type::T_SET_A:
5783 case Type::T_ARRAY:
5784 // ok
5785 break;
5786 case Type::T_OID:
5787 case Type::T_ROID:
5788 break;
5789 default:
5790 u.expr.ti1->error("Reference to value or template of type record, record of,"
5791 " set, set of, objid or array was expected");
5792 goto error;
5793 } // switch
5794 }
5795
5796 // check for index overflows in subrefs if possible
5797 if (t_val) {
5798 switch (t_val->get_valuetype()) {
5799 case V_SEQOF:
5800 case V_SETOF:
5801 case V_ARRAY:
5802 if (t_val->is_indexed()) {
5803 return -1;
5804 }
5805 break;
5806 default:
5807 break;
5808 }
5809 /* The reference points to a constant. */
5810 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5811 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5812 if (!t_val) goto error;
5813 t_val=t_val->get_value_refd_last(refch);
5814 } else { t_val = 0; }
5815 } else if (t_templ) {
5816 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5817 time. Don't try to evaluate it at compile time. */
5818 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5819 return -1;
5820 /* The reference points to a static template. */
5821 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5822 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5823 if (!t_templ) goto error;
5824 t_templ = t_templ->get_template_refd_last(refch);
5825 } else { t_templ = 0; }
5826 }
5827
5828 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5829 if(t_templ) {
5830 switch(t_templ->get_templatetype()) {
5831 case Template::TEMPLATE_ERROR:
5832 goto error;
5833 case Template::TEMPLATE_REFD:
5834 // not foldable
5835 t_templ=0;
5836 break;
5837 case Template::SPECIFIC_VALUE:
5838 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5839 t_templ=0;
5840 break;
5841 case Template::TEMPLATE_LIST:
5842 case Template::NAMED_TEMPLATE_LIST:
5843 break;
5844 default:
5845 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5846 t_templ->get_templatetype_str(),
5847 t_templ->get_fullname().c_str());
5848 goto error;
5849 } // switch
5850 }
5851 if(t_val) {
5852 switch(t_val->get_valuetype()) {
5853 case V_SEQOF:
5854 case V_SETOF:
5855 case V_ARRAY:
5856 case V_SEQ:
5857 case V_SET:
5858 case V_OID:
5859 case V_ROID:
5860 // ok
5861 break;
5862 default:
5863 // error is already reported
5864 t_val=0;
5865 break;
5866 } // switch
5867 }
5868 }
5869
5870 /* evaluation */
5871
5872 if(t_type->get_typetype()==Type::T_ARRAY) {
5873 result = t_type->get_dimension()->get_size();
5874 }
5875 else if(t_templ) { // sizeof()
5876 switch(t_templ->get_templatetype()) {
5877 case Template::TEMPLATE_LIST:
5878 if(t_templ->temps_contains_anyornone_symbol()) {
5879 if(t_templ->is_length_restricted()) {
5880 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5881 if (lr->get_is_range()) {
5882 Value *v_upper = lr->get_upper_value();
5883 if (v_upper) {
5884 if (v_upper->valuetype == V_INT) {
5885 Int nof_comps =
5886 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5887 if (v_upper->u.val_Int->get_val() == nof_comps)
5888 result = nof_comps;
5889 else {
5890 u.expr.ti1->error("`sizeof' operation is not applicable for "
5891 "templates without exact size");
5892 goto error;
5893 }
5894 }
5895 } else {
5896 u.expr.ti1->error("`sizeof' operation is not applicable for "
5897 "templates containing `*' without upper boundary in the "
5898 "length restriction");
5899 goto error;
5900 }
5901 } else {
5902 Value *v_single = lr->get_single_value();
5903 if (v_single->valuetype == V_INT)
5904 result = v_single->u.val_Int->get_val();
5905 }
5906 }
5907 else { // not length restricted
5908 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
5909 " containing `*' without length restriction");
5910 goto error;
5911 }
5912 }
5913 else result=t_templ->get_nof_listitems();
5914 break;
5915 case Template::NAMED_TEMPLATE_LIST:
5916 result=0;
5917 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
5918 if(t_templ->get_namedtemp_byIndex(i)->get_template()
5919 ->get_templatetype()!=Template::OMIT_VALUE) result++;
5920 return result;
5921 default:
5922 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5923 } // switch
5924 }
5925 else if(t_val) {
5926 switch(t_val->get_valuetype()) {
5927 case V_SEQOF:
5928 case V_SETOF:
5929 case V_ARRAY:
5930
5931 case V_OID:
5932 case V_ROID:
5933 result=t_val->get_nof_comps();
5934 break;
5935 case V_SEQ:
5936 case V_SET:
5937 result=0;
5938 for(size_t i=0; i<t_val->get_nof_comps(); i++)
5939 if(t_val->get_se_comp_byIndex(i)->get_value()
5940 ->get_valuetype()!=V_OMIT) result++;
5941 break;
5942
5943 default:
5944 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
5945 } // switch
5946 }
5947
5948 return result;
5949 error:
5950 set_valuetype(V_ERROR);
5951 return -1;
5952 }
5953
5954 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
5955 {
5956 Type *governor = ti->get_expr_governor(exp_val);
5957 if (!governor) {
5958 ti->get_Template()->set_lowerid_to_ref();
5959 governor = ti->get_expr_governor(exp_val);
5960 }
5961 if (!governor) {
5962 string str;
5963 ti->append_stringRepr( str);
5964 ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
5965 "If type is known, use valueof(<type>: %s) as argument.",
5966 str.c_str(), get_opname(), str.c_str());
5967 set_valuetype(V_ERROR);
5968 }
5969 return governor;
5970 }
5971
5972 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
5973 {
5974 start:
5975 Type *governor = u.expr.v1->get_expr_governor(exp_val);
5976 if (!governor) governor = u.expr.t2->get_expr_governor(
5977 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
5978 Type::EXPECTED_TEMPLATE : exp_val);
5979 if (!governor) {
5980 Template *t_temp = u.expr.t2->get_Template();
5981 if (t_temp->is_undef_lowerid()) {
5982 // We convert the template to reference first even if the value is also
5983 // an undef lowerid. The user can prevent this by explicit type
5984 // specification.
5985 t_temp->set_lowerid_to_ref();
5986 goto start;
5987 } else if (u.expr.v1->is_undef_lowerid()) {
5988 u.expr.v1->set_lowerid_to_ref();
5989 goto start;
5990 }
5991 }
5992 if (!governor) {
5993 error("Cannot determine the type of arguments in `match()' operation");
5994 set_valuetype(V_ERROR);
5995 return;
5996 }
5997 u.expr.v1->set_my_governor(governor);
5998 {
5999 Error_Context cntxt(this, "In the first argument of `match()'"
6000 " operation");
6001 governor->chk_this_value_ref(u.expr.v1);
6002 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
6003 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6004 }
6005 {
6006 Error_Context cntxt(this, "In the second argument of `match()' "
6007 "operation");
6008 u.expr.t2->chk(governor);
6009 }
6010 }
6011
6012 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
6013 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
6014 {
6015 Ttcn::StatementBlock *my_sb;
6016 switch (exp_val) {
6017 case Type::EXPECTED_CONSTANT:
6018 error("An evaluable constant value was expected instead of operation "
6019 "`%s'", get_opname());
6020 goto error;
6021 case Type::EXPECTED_STATIC_VALUE:
6022 error("A static value was expected instead of operation `%s'",
6023 get_opname());
6024 goto error;
6025 default:
6026 break;
6027 } // switch
6028 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6029 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
6030 if (!my_sb) {
6031 error("Operation `%s' is allowed only within statements",
6032 get_opname());
6033 goto error;
6034 }
6035 if (!allow_controlpart && !my_sb->get_my_def()) {
6036 error("Operation `%s' is not allowed in the control part",
6037 get_opname());
6038 goto error;
6039 }
6040 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6041 error("Operation `%s' cannot be used in a definition that has "
6042 "`runs on' clause", get_opname());
6043 goto error;
6044 }
6045 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6046 error("Operation `%s' can be used only in a definition that has "
6047 "`runs on' clause", get_opname());
6048 goto error;
6049 }
6050 return;
6051 error:
6052 set_valuetype(V_ERROR);
6053 }
6054
6055 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6056 {
6057 if(valuetype==V_ERROR) return;
6058 if(u.expr.state==EXPR_CHECKING_ERR) return;
6059 if(v->is_unfoldable()) return;
6060 if(v->get_expr_returntype()!=Type::T_REAL) return;
6061 ttcn3float r = v->get_val_Real();
6062 if (isSpecialFloatValue(r)) {
6063 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6064 opnum, opname, Real2string(r).c_str());
6065 set_valuetype(V_ERROR);
6066 }
6067 }
6068
6069 void Value::chk_expr_operands(ReferenceChain *refch,
6070 Type::expected_value_t exp_val)
6071 {
6072 const char *first="First", *second="Second", *third="Third",
6073 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6074 Value *v1, *v2, *v3;
6075 Type::typetype_t tt1, tt2, tt3;
6076 Type t_chk(Type::T_ERROR);
6077
6078 const char *opname=get_opname();
6079
6080 // first classify the unchecked ischosen() operation
6081 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6082
6083 switch (u.expr.v_optype) {
6084 case OPTYPE_COMP_NULL:
6085 case OPTYPE_TESTCASENAME:
6086 case OPTYPE_PROF_RUNNING:
6087 break;
6088 case OPTYPE_COMP_MTC:
6089 case OPTYPE_COMP_SYSTEM:
6090 chk_expr_comptype_compat();
6091 break;
6092 case OPTYPE_RND: // -
6093 case OPTYPE_TMR_RUNNING_ANY:
6094 chk_expr_dynamic_part(exp_val, true);
6095 break;
6096 case OPTYPE_COMP_RUNNING_ANY:
6097 case OPTYPE_COMP_RUNNING_ALL:
6098 case OPTYPE_COMP_ALIVE_ANY:
6099 case OPTYPE_COMP_ALIVE_ALL:
6100 case OPTYPE_GETVERDICT:
6101 chk_expr_dynamic_part(exp_val, false);
6102 break;
6103 case OPTYPE_COMP_SELF:
6104 chk_expr_comptype_compat();
6105 chk_expr_dynamic_part(exp_val, false, true, false);
6106 break;
6107 case OPTYPE_UNARYPLUS: // v1
6108 case OPTYPE_UNARYMINUS:
6109 v1=u.expr.v1;
6110 {
6111 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6112 v1->set_lowerid_to_ref();
6113 tt1=v1->get_expr_returntype(exp_val);
6114 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6115 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6116 }
6117 break;
6118 case OPTYPE_NOT:
6119 v1=u.expr.v1;
6120 {
6121 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6122 v1->set_lowerid_to_ref();
6123 tt1=v1->get_expr_returntype(exp_val);
6124 chk_expr_operandtype_bool(tt1, the, opname, v1);
6125 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6126 }
6127 break;
6128 case OPTYPE_NOT4B:
6129 v1=u.expr.v1;
6130 {
6131 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6132 v1->set_lowerid_to_ref();
6133 tt1=v1->get_expr_returntype(exp_val);
6134 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6135 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6136 }
6137 break;
6138 case OPTYPE_BIT2HEX:
6139 case OPTYPE_BIT2OCT:
6140 case OPTYPE_BIT2STR:
6141 v1=u.expr.v1;
6142 {
6143 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6144 v1->set_lowerid_to_ref();
6145 tt1=v1->get_expr_returntype(exp_val);
6146 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6147 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6148 }
6149 break;
6150 case OPTYPE_BIT2INT:
6151 v1=u.expr.v1;
6152 {
6153 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6154 v1->set_lowerid_to_ref();
6155 tt1=v1->get_expr_returntype(exp_val);
6156 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6157 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6158 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6159 }
6160 break;
6161 case OPTYPE_CHAR2INT:
6162 v1=u.expr.v1;
6163 {
6164 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6165 v1->set_lowerid_to_ref();
6166 tt1=v1->get_expr_returntype(exp_val);
6167 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6168 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6169 chk_expr_val_len1(v1, the, opname);
6170 }
6171 break;
6172 case OPTYPE_CHAR2OCT:
6173 v1=u.expr.v1;
6174 {
6175 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6176 v1->set_lowerid_to_ref();
6177 tt1=v1->get_expr_returntype(exp_val);
6178 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6179 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6180 }
6181 break;
6182 case OPTYPE_STR2INT:
6183 v1=u.expr.v1;
6184 {
6185 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6186 v1->set_lowerid_to_ref();
6187 tt1=v1->get_expr_returntype(exp_val);
6188 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6189 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6190 chk_expr_val_str_int(v1, the, opname);
6191 }
6192 break;
6193 case OPTYPE_STR2FLOAT:
6194 v1=u.expr.v1;
6195 {
6196 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6197 v1->set_lowerid_to_ref();
6198 tt1=v1->get_expr_returntype(exp_val);
6199 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6200 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6201 chk_expr_val_str_float(v1, the, opname);
6202 }
6203 break;
6204 case OPTYPE_STR2BIT:
6205 v1=u.expr.v1;
6206 {
6207 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6208 v1->set_lowerid_to_ref();
6209 tt1=v1->get_expr_returntype(exp_val);
6210 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6211 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6212 chk_expr_val_str_bindigits(v1, the, opname);
6213 }
6214 break;
6215 case OPTYPE_STR2HEX:
6216 v1=u.expr.v1;
6217 {
6218 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6219 v1->set_lowerid_to_ref();
6220 tt1=v1->get_expr_returntype(exp_val);
6221 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6222 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6223 chk_expr_val_str_hexdigits(v1, the, opname);
6224 }
6225 break;
6226 case OPTYPE_STR2OCT:
6227 v1=u.expr.v1;
6228 {
6229 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6230 v1->set_lowerid_to_ref();
6231 tt1=v1->get_expr_returntype(exp_val);
6232 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6233 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6234 chk_expr_val_str_len_even(v1, the, opname);
6235 chk_expr_val_str_hexdigits(v1, the, opname);
6236 }
6237 break;
6238 case OPTYPE_ENUM2INT:
6239 v1=u.expr.v1;
6240 {
6241 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6242 chk_expr_operandtype_enum(opname, v1, exp_val);
6243 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6244 }
6245 break;
6246 case OPTYPE_ENCODE:
6247 chk_expr_operand_encode(refch, exp_val);
6248 break;
6249 case OPTYPE_FLOAT2INT:
6250 case OPTYPE_FLOAT2STR:
6251 v1=u.expr.v1;
6252 {
6253 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6254 v1->set_lowerid_to_ref();
6255 tt1=v1->get_expr_returntype(exp_val);
6256 chk_expr_operandtype_float(tt1, the, opname, v1);
6257 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6258 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6259 chk_expr_operand_valid_float(v1, the, opname);
6260 }
6261 break;
6262 case OPTYPE_RNDWITHVAL:
6263 v1=u.expr.v1;
6264 {
6265 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6266 v1->set_lowerid_to_ref();
6267 tt1=v1->get_expr_returntype(exp_val);
6268 chk_expr_operandtype_float(tt1, the, opname, v1);
6269 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6270 chk_expr_operand_valid_float(v1, the, opname);
6271 }
6272 chk_expr_dynamic_part(exp_val, true);
6273 break;
6274 case OPTYPE_HEX2BIT:
6275 case OPTYPE_HEX2OCT:
6276 case OPTYPE_HEX2STR:
6277 v1=u.expr.v1;
6278 {
6279 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6280 v1->set_lowerid_to_ref();
6281 tt1=v1->get_expr_returntype(exp_val);
6282 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6283 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6284 }
6285 break;
6286 case OPTYPE_HEX2INT:
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_hstr(tt1, the, opname, v1);
6293 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6294 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6295 }
6296 break;
6297 case OPTYPE_INT2CHAR:
6298 v1=u.expr.v1;
6299 {
6300 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6301 v1->set_lowerid_to_ref();
6302 tt1=v1->get_expr_returntype(exp_val);
6303 chk_expr_operandtype_int(tt1, the, opname, v1);
6304 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6305 chk_expr_val_int_pos7bit(v1, the, opname);
6306 }
6307 break;
6308 case OPTYPE_INT2UNICHAR:
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_int(tt1, the, opname, v1);
6315 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6316 chk_expr_val_int_pos31bit(v1, first, opname);
6317 }
6318 break;
6319 case OPTYPE_INT2FLOAT:
6320 case OPTYPE_INT2STR:
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_int(tt1, the, opname, v1);
6327 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6328 }
6329 break;
6330 case OPTYPE_OCT2BIT:
6331 case OPTYPE_OCT2HEX:
6332 case OPTYPE_OCT2STR:
6333 v1=u.expr.v1;
6334 {
6335 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6336 v1->set_lowerid_to_ref();
6337 tt1=v1->get_expr_returntype(exp_val);
6338 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6339 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6340 }
6341 break;
6342 case OPTYPE_OCT2INT:
6343 v1=u.expr.v1;
6344 {
6345 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6346 v1->set_lowerid_to_ref();
6347 tt1=v1->get_expr_returntype(exp_val);
6348 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6349 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6350 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6351 // now.
6352 }
6353 break;
6354 case OPTYPE_OCT2CHAR:
6355 v1=u.expr.v1;
6356 {
6357 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6358 v1->set_lowerid_to_ref();
6359 tt1=v1->get_expr_returntype(exp_val);
6360 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6361 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6362 chk_expr_val_str_7bitoctets(v1, the, opname);
6363 }
6364 break;
6365 case OPTYPE_REMOVE_BOM:
6366 v1=u.expr.v1;
6367 {
6368 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6369 v1->set_lowerid_to_ref();
6370 tt1=v1->get_expr_returntype(exp_val);
6371 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6372 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6373 }
6374 break;
6375 case OPTYPE_GET_STRINGENCODING:
6376 v1=u.expr.v1;
6377 {
6378 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6379 v1->set_lowerid_to_ref();
6380 tt1=v1->get_expr_returntype(exp_val);
6381 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6382 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6383 }
6384 break;
6385 case OPTYPE_ENCODE_BASE64:
6386 v1=u.expr.v1;
6387 {
6388 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6389 v1->set_lowerid_to_ref();
6390 tt1=v1->get_expr_returntype(exp_val);
6391 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6392 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6393 }
6394 v2=u.expr.v2 ? u.expr.v2 : 0;
6395 if (v2)
6396 {
6397 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6398 v2->set_lowerid_to_ref();
6399 tt2=v2->get_expr_returntype(exp_val);
6400 chk_expr_operandtype_bool(tt2, second, opname, v2);
6401 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6402 }
6403 break;
6404 case OPTYPE_DECODE_BASE64:
6405 v1=u.expr.v1;
6406 {
6407 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6408 v1->set_lowerid_to_ref();
6409 tt1=v1->get_expr_returntype(exp_val);
6410 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6411 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6412 }
6413 break;
6414 case OPTYPE_UNICHAR2INT:
6415 v1=u.expr.v1;
6416 {
6417 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6418 v1->set_lowerid_to_ref();
6419 tt1=v1->get_expr_returntype(exp_val);
6420 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6421 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6422 chk_expr_val_len1(v1, the, opname);
6423 }
6424 break;
6425 case OPTYPE_UNICHAR2CHAR:
6426 v1=u.expr.v1;
6427 {
6428 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6429 v1->set_lowerid_to_ref();
6430 tt1=v1->get_expr_returntype(exp_val);
6431 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6432 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6433 chk_expr_val_ustr_7bitchars(v1, the, opname);
6434 }
6435 break;
6436 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6437 v1=u.expr.v1;
6438 {
6439 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6440 v1->set_lowerid_to_ref();
6441 tt1=v1->get_expr_returntype(exp_val);
6442 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6443 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6444 }
6445 v2=u.expr.v2 ? u.expr.v2 : 0;
6446 if (v2)
6447 {
6448 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6449 v2->set_lowerid_to_ref();
6450 tt2=v2->get_expr_returntype(exp_val);
6451 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6452 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6453 }
6454 break;
6455 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6456 v1=u.expr.v1;
6457 {
6458 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6459 v1->set_lowerid_to_ref();
6460 tt1=v1->get_expr_returntype(exp_val);
6461 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6462 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6463 }
6464 v2=u.expr.v2 ? u.expr.v2 : 0;
6465 if (v2)
6466 {
6467 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6468 v2->set_lowerid_to_ref();
6469 tt2=v2->get_expr_returntype(exp_val);
6470 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6471 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6472 }
6473 break;
6474 case OPTYPE_ADD: // v1 v2
6475 case OPTYPE_SUBTRACT:
6476 case OPTYPE_MULTIPLY:
6477 case OPTYPE_DIVIDE:
6478 v1=u.expr.v1;
6479 {
6480 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6481 v1->set_lowerid_to_ref();
6482 tt1=v1->get_expr_returntype(exp_val);
6483 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6484 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6485 chk_expr_operand_valid_float(v1, first, opname);
6486 }
6487 v2=u.expr.v2;
6488 {
6489 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6490 v2->set_lowerid_to_ref();
6491 tt2=v2->get_expr_returntype(exp_val);
6492 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6493 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6494 chk_expr_operand_valid_float(v2, second, opname);
6495 if(u.expr.v_optype==OPTYPE_DIVIDE)
6496 chk_expr_val_int_float_not0(v2, second, opname);
6497 }
6498 chk_expr_operandtypes_same(tt1, tt2, opname);
6499 break;
6500 case OPTYPE_MOD:
6501 case OPTYPE_REM:
6502 v1=u.expr.v1;
6503 {
6504 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6505 v1->set_lowerid_to_ref();
6506 tt1=v1->get_expr_returntype(exp_val);
6507 chk_expr_operandtype_int(tt1, left, opname, v1);
6508 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6509 }
6510 v2=u.expr.v2;
6511 {
6512 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6513 v2->set_lowerid_to_ref();
6514 tt2=v2->get_expr_returntype(exp_val);
6515 chk_expr_operandtype_int(tt2, right, opname, v2);
6516 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6517 chk_expr_val_int_float_not0(v2, right, opname);
6518 }
6519 break;
6520 case OPTYPE_CONCAT: {
6521 v1=u.expr.v1;
6522 v2=u.expr.v2;
6523 v1->set_lowerid_to_ref();
6524 v2->set_lowerid_to_ref();
6525 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6526 {
6527 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6528 tt1=v1->get_expr_returntype(exp_val);
6529 chk_expr_operandtype_str(tt1, left, opname, v1);
6530 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6531 }
6532 {
6533 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6534 tt2=v2->get_expr_returntype(exp_val);
6535 chk_expr_operandtype_str(tt2, right, opname, v2);
6536 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6537 }
6538 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6539 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6540 chk_expr_operandtypes_same(tt1, tt2, opname);
6541 } else { // other list types
6542 Type* v1_gov = v1->get_expr_governor(exp_val);
6543 Type* v2_gov = v2->get_expr_governor(exp_val);
6544 if (!v1_gov) {
6545 error("Cannot determine the type of the left operand of `%s' operation", opname);
6546 set_valuetype(V_ERROR);
6547 return;
6548 } else {
6549 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6550 v1_gov->chk_this_value_ref(v1);
6551 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6552 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6553 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6554 }
6555 if (!v2_gov) {
6556 if (!v1_gov) {
6557 error("Cannot determine the type of the right operand of `%s' operation", opname);
6558 set_valuetype(V_ERROR);
6559 return;
6560 }
6561 // for recof/setof literals set the type from v1
6562 v2_gov = v1_gov;
6563 v2->set_my_governor(v1_gov);
6564 }
6565 {
6566 Error_Context cntxt(this, "In the right operand of operation `%s'",
6567 opname);
6568 v2_gov->chk_this_value_ref(v2);
6569 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6570 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6571 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6572 if (valuetype == V_ERROR) return;
6573 // 7.1.2 says that we shouldn't allow type compatibility.
6574 if (!v1_gov->is_compatible(v2_gov, NULL)
6575 && !v2_gov->is_compatible(v1_gov, NULL)) {
6576 error("The operands of operation `%s' should be of compatible "
6577 "types", get_opname());
6578 }
6579 }
6580 }
6581 break; }
6582 case OPTYPE_EQ:
6583 case OPTYPE_NE:
6584 v1 = u.expr.v1;
6585 v2 = u.expr.v2;
6586 chk_expr_operandtypes_compat(exp_val, v1, v2);
6587 {
6588 Error_Context cntxt(this, "In the left operand of operation `%s'",
6589 opname);
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 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6596 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6597 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6598 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6599 * "a == not b" is not allowed. (HL69107)
6600 * The various *Expressions implement operator precedence in the std.
6601 * Titan's parser has only one Expression and relies on Bison
6602 * for operator precedence. The check below brings Titan in line
6603 * with the standard by explicitly making "a == not b" an error */
6604 if (v2->get_valuetype() == V_EXPR
6605 && v2->u.expr.v_optype == OPTYPE_NOT) {
6606 error("The operation `%s' is not allowed to be "
6607 "the second operand of operation `%s'", v2->get_opname(), opname);
6608 set_valuetype(V_ERROR);
6609 }
6610 }
6611 break;
6612 case OPTYPE_LT:
6613 case OPTYPE_GT:
6614 case OPTYPE_GE:
6615 case OPTYPE_LE:
6616 v1=u.expr.v1;
6617 v2=u.expr.v2;
6618 chk_expr_operandtypes_compat(exp_val, v1, v2);
6619 {
6620 Error_Context cntxt(this, "In the left operand of operation `%s'",
6621 opname);
6622 tt1=v1->get_expr_returntype(exp_val);
6623 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6624 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6625 }
6626 {
6627 Error_Context cntxt(this, "In the right operand of operation `%s'",
6628 opname);
6629 tt2=v2->get_expr_returntype(exp_val);
6630 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6631 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6632 }
6633 break;
6634 case OPTYPE_AND:
6635 case OPTYPE_OR:
6636 case OPTYPE_XOR:
6637 v1=u.expr.v1;
6638 {
6639 Error_Context cntxt(this, "In the left operand of operation `%s'",
6640 opname);
6641 v1->set_lowerid_to_ref();
6642 tt1=v1->get_expr_returntype(exp_val);
6643 chk_expr_operandtype_bool(tt1, left, opname, v1);
6644 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6645 }
6646 v2=u.expr.v2;
6647 {
6648 Error_Context cntxt(this, "In the right operand of operation `%s'",
6649 opname);
6650 v2->set_lowerid_to_ref();
6651 tt2=v2->get_expr_returntype(exp_val);
6652 chk_expr_operandtype_bool(tt2, right, opname, v2);
6653 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6654 }
6655 break;
6656 case OPTYPE_AND4B:
6657 case OPTYPE_OR4B:
6658 case OPTYPE_XOR4B:
6659 v1=u.expr.v1;
6660 {
6661 Error_Context cntxt(this, "In the left operand of operation `%s'",
6662 opname);
6663 v1->set_lowerid_to_ref();
6664 tt1=v1->get_expr_returntype(exp_val);
6665 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6666 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6667 }
6668 v2=u.expr.v2;
6669 {
6670 Error_Context cntxt(this, "In the right operand of operation `%s'",
6671 opname);
6672 v2->set_lowerid_to_ref();
6673 tt2=v2->get_expr_returntype(exp_val);
6674 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6675 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6676 }
6677 chk_expr_operandtypes_same(tt1, tt2, opname);
6678 chk_expr_operands_str_samelen();
6679 break;
6680 case OPTYPE_SHL:
6681 case OPTYPE_SHR:
6682 v1=u.expr.v1;
6683 {
6684 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6685 v1->set_lowerid_to_ref();
6686 tt1=v1->get_expr_returntype(exp_val);
6687 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6688 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6689 }
6690 v2=u.expr.v2;
6691 {
6692 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6693 v2->set_lowerid_to_ref();
6694 tt2=v2->get_expr_returntype(exp_val);
6695 chk_expr_operandtype_int(tt2, right, opname, v2);
6696 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6697 chk_expr_val_large_int(v2, right, opname);
6698 }
6699 break;
6700 case OPTYPE_ROTL:
6701 case OPTYPE_ROTR:
6702 v1=u.expr.v1;
6703 v1->set_lowerid_to_ref();
6704 if (v1->is_string_type(exp_val)) {
6705 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6706 tt1=v1->get_expr_returntype(exp_val);
6707 chk_expr_operandtype_str(tt1, left, opname, v1);
6708 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6709 } else { // other list types
6710 Type* v1_gov = v1->get_expr_governor(exp_val);
6711 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6712 error("Cannot determine the type of the left operand of `%s' operation", opname);
6713 } else {
6714 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6715 v1_gov->chk_this_value_ref(v1);
6716 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6717 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6718 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6719 }
6720 }
6721 v2=u.expr.v2;
6722 {
6723 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6724 v2->set_lowerid_to_ref();
6725 tt2=v2->get_expr_returntype(exp_val);
6726 chk_expr_operandtype_int(tt2, right, opname, v2);
6727 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6728 chk_expr_val_large_int(v2, right, opname);
6729 }
6730 break;
6731 case OPTYPE_INT2BIT:
6732 case OPTYPE_INT2HEX:
6733 case OPTYPE_INT2OCT:
6734 v1=u.expr.v1;
6735 {
6736 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6737 v1->set_lowerid_to_ref();
6738 tt1=v1->get_expr_returntype(exp_val);
6739 chk_expr_operandtype_int(tt1, first, opname, v1);
6740 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6741 chk_expr_val_int_pos0(v1, first, opname);
6742 }
6743 v2=u.expr.v2;
6744 {
6745 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6746 v2->set_lowerid_to_ref();
6747 tt2=v2->get_expr_returntype(exp_val);
6748 chk_expr_operandtype_int(tt2, second, opname, v2);
6749 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6750 chk_expr_val_int_pos0(v2, second, opname);
6751 }
6752 chk_expr_operands_int2binstr();
6753 break;
6754 case OPTYPE_DECODE:
6755 chk_expr_operands_decode();
6756 break;
6757 case OPTYPE_SUBSTR:
6758 {
6759 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6760 Type::expected_value_t ti_exp_val = exp_val;
6761 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6762 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6763 if (!governor) return;
6764 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6765 if (valuetype!=V_ERROR)
6766 u.expr.ti1->get_Template()->chk_specific_value(false);
6767 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6768 }
6769 v2=u.expr.v2;
6770 {
6771 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6772 v2->set_lowerid_to_ref();
6773 tt2=v2->get_expr_returntype(exp_val);
6774 chk_expr_operandtype_int(tt2, second, opname, v2);
6775 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6776 chk_expr_val_int_pos0(v2, second, opname);
6777 }
6778 v3=u.expr.v3;
6779 {
6780 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6781 v3->set_lowerid_to_ref();
6782 tt3=v3->get_expr_returntype(exp_val);
6783 chk_expr_operandtype_int(tt3, third, opname, v3);
6784 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6785 chk_expr_val_int_pos0(v3, third, opname);
6786 }
6787 chk_expr_operands_substr();
6788 break;
6789 case OPTYPE_REGEXP: {
6790 Type::expected_value_t ti_exp_val = exp_val;
6791 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6792 {
6793 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6794 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6795 if (!governor) return;
6796 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6797 if (valuetype!=V_ERROR) {
6798 u.expr.ti1->get_Template()->chk_specific_value(false);
6799 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6800 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6801 }
6802 }
6803 {
6804 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6805 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6806 if (!governor) return;
6807 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6808 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6809 get_typetype_ttcn3(), second, opname, u.expr.t2);
6810 }
6811 v3=u.expr.v3;
6812 {
6813 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6814 v3->set_lowerid_to_ref();
6815 tt3=v3->get_expr_returntype(exp_val);
6816 chk_expr_operandtype_int(tt3, third, opname, v3);
6817 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6818 chk_expr_val_int_pos0(v3, third, opname);
6819 }
6820 chk_expr_operands_regexp();
6821 } break;
6822 case OPTYPE_ISCHOSEN:
6823 // do nothing: the operand is erroneous
6824 // the error was already reported in chk_expr_ref_ischosen()
6825 break;
6826 case OPTYPE_ISCHOSEN_V: // v1 i2
6827 case OPTYPE_ISCHOSEN_T: // t1 i2
6828 chk_expr_operands_ischosen(refch, exp_val);
6829 break;
6830 case OPTYPE_VALUEOF: { // ti1
6831 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6832 exp_val = Type::EXPECTED_TEMPLATE;
6833 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6834 Type *governor = my_governor;
6835 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6836 if (!governor) return;
6837 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6838 if (valuetype == V_ERROR) return;
6839 u.expr.ti1->get_Template()->chk_specific_value(false);
6840 break; }
6841 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6842 case OPTYPE_ISBOUND: {
6843 Template *templ = u.expr.ti1->get_Template();
6844 switch (templ->get_templatetype()) {
6845 case Template::TEMPLATE_REFD:
6846 templ->get_reference()->setUsedInIsbound();
6847 break;
6848 case Template::SPECIFIC_VALUE: {
6849 Value *value = templ->get_specific_value();
6850 if (Value::V_REFD == value->get_valuetype()) {
6851 value->get_reference()->setUsedInIsbound();
6852 }
6853 break; }
6854 default:
6855 break;
6856 }
6857 }
6858 // no break
6859 case OPTYPE_ISVALUE: {// ti1
6860 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6861 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6862 exp_val = Type::EXPECTED_TEMPLATE;
6863 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6864 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6865 if (!governor) return;
6866 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6867 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6868 break; }
6869 case OPTYPE_SIZEOF: // ti1
6870 /* this checking is too complex, do the checking during eval... */
6871 break;
6872 case OPTYPE_LENGTHOF: { // ti1
6873 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6874 exp_val = Type::EXPECTED_TEMPLATE;
6875 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6876 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6877 if (!governor) return;
6878 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
6879 if (valuetype == V_ERROR) return;
6880 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6881 break; }
6882 case OPTYPE_MATCH: // v1 t2
6883 chk_expr_operands_match(exp_val);
6884 break;
6885 case OPTYPE_UNDEF_RUNNING: // r1
6886 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
6887 break;
6888 case OPTYPE_COMP_ALIVE:
6889 case OPTYPE_COMP_RUNNING: //v1
6890 chk_expr_operand_compref(u.expr.v1, the, opname);
6891 chk_expr_dynamic_part(exp_val, false);
6892 break;
6893 case OPTYPE_TMR_READ: // r1
6894 case OPTYPE_TMR_RUNNING: // r1
6895 chk_expr_operand_tmrref(u.expr.r1, the, opname);
6896 chk_expr_dynamic_part(exp_val, true);
6897 break;
6898 case OPTYPE_EXECUTE: // r1 [v2] // testcase
6899 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
6900 chk_expr_dynamic_part(exp_val, true, false, false);
6901 break;
6902 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
6903 chk_expr_operand_comptyperef_create();
6904 v2=u.expr.v2;
6905 if(v2) {
6906 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6907 v2->set_lowerid_to_ref();
6908 tt2=v2->get_expr_returntype(exp_val);
6909 chk_expr_operandtype_cstr(tt2, first, opname, v2);
6910 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6911 }
6912 v3=u.expr.v3;
6913 if(v3) {
6914 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6915 v3->set_lowerid_to_ref();
6916 tt3=v3->get_expr_returntype(exp_val);
6917 chk_expr_operandtype_cstr(tt3, second, opname, v3);
6918 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6919 }
6920 chk_expr_dynamic_part(exp_val, false);
6921 break;
6922 case OPTYPE_ACTIVATE: // r1 // altstep
6923 chk_expr_operand_activate(u.expr.r1, the, opname);
6924 chk_expr_dynamic_part(exp_val, true);
6925 break;
6926 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
6927 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6928 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
6929 opname);
6930 delete u.expr.t_list2;
6931 u.expr.ap_list2 = parlist;
6932 chk_expr_dynamic_part(exp_val, true);
6933 break; }
6934 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
6935 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
6936 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
6937 u.expr.v3, the, opname);
6938 delete u.expr.t_list2;
6939 u.expr.ap_list2 = parlist;
6940 chk_expr_dynamic_part(exp_val, true);
6941 break; }
6942 case OPTYPE_DECOMP:
6943 error("Built-in function `%s' is not yet supported", opname);
6944 set_valuetype(V_ERROR);
6945 break;
6946 case OPTYPE_REPLACE: {
6947 Type::expected_value_t ti_exp_val = exp_val;
6948 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6949 ti_exp_val = Type::EXPECTED_TEMPLATE;
6950 {
6951 Error_Context cntxt(this, "In the first operand of operation `%s'",
6952 opname);
6953 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6954 if (!governor) return;
6955 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6956 if (valuetype != V_ERROR)
6957 u.expr.ti1->get_Template()->chk_specific_value(false);
6958 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6959 }
6960 v2 = u.expr.v2;
6961 {
6962 Error_Context cntxt(this, "In the second operand of operation `%s'",
6963 opname);
6964 v2->set_lowerid_to_ref();
6965 tt2 = v2->get_expr_returntype(exp_val);
6966 chk_expr_operandtype_int(tt2, second, opname, v2);
6967 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6968 chk_expr_val_int_pos0(v2, second, opname);
6969 }
6970 v3 = u.expr.v3;
6971 {
6972 Error_Context cntxt(this, "In the third operand of operation `%s'",
6973 opname);
6974 v3->set_lowerid_to_ref();
6975 tt3 = v3->get_expr_returntype(exp_val);
6976 chk_expr_operandtype_int(tt3, third, opname, v3);
6977 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6978 chk_expr_val_int_pos0(v3, third, opname);
6979 }
6980 {
6981 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
6982 opname);
6983 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
6984 if (!governor) return;
6985 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
6986 if (valuetype != V_ERROR)
6987 u.expr.ti4->get_Template()->chk_specific_value(false);
6988 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
6989 }
6990 chk_expr_operands_replace();
6991 break; }
6992 case OPTYPE_LOG2STR: {
6993 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6994 u.expr.logargs->chk();
6995 if (!semantic_check_only) u.expr.logargs->join_strings();
6996 break; }
6997 case OPTYPE_TTCN2STRING: {
6998 Error_Context cntxt(this, "In the parameter of ttcn2string()");
6999 Type::expected_value_t ti_exp_val = exp_val;
7000 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
7001 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7002 if (!governor) return;
7003 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7004 } break;
7005 default:
7006 FATAL_ERROR("chk_expr_operands()");
7007 } // switch optype
7008 }
7009
7010 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7011 // the result of evaluating the expression. E.g. V_BOOL for
7012 // OPTYPE_ISCHOSEN.
7013 void Value::evaluate_value(ReferenceChain *refch,
7014 Type::expected_value_t exp_val)
7015 {
7016 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
7017 if(u.expr.state!=EXPR_NOT_CHECKED) return;
7018
7019 u.expr.state=EXPR_CHECKING;
7020
7021 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
7022 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
7023 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
7024
7025 if(valuetype==V_ERROR) return;
7026 if(u.expr.state==EXPR_CHECKING_ERR) {
7027 u.expr.state=EXPR_CHECKED;
7028 set_valuetype(V_ERROR);
7029 return;
7030 }
7031
7032 u.expr.state=EXPR_CHECKED;
7033
7034 Value *v1, *v2, *v3, *v4;
7035 switch(u.expr.v_optype) {
7036 case OPTYPE_RND: // -
7037 case OPTYPE_COMP_NULL: // the only foldable in this group
7038 case OPTYPE_COMP_MTC:
7039 case OPTYPE_COMP_SYSTEM:
7040 case OPTYPE_COMP_SELF:
7041 case OPTYPE_COMP_RUNNING_ANY:
7042 case OPTYPE_COMP_RUNNING_ALL:
7043 case OPTYPE_COMP_ALIVE_ANY:
7044 case OPTYPE_COMP_ALIVE_ALL:
7045 case OPTYPE_TMR_RUNNING_ANY:
7046 case OPTYPE_GETVERDICT:
7047 case OPTYPE_PROF_RUNNING:
7048 case OPTYPE_RNDWITHVAL: // v1
7049 case OPTYPE_COMP_RUNNING: // v1
7050 case OPTYPE_COMP_ALIVE:
7051 case OPTYPE_TMR_READ:
7052 case OPTYPE_TMR_RUNNING:
7053 case OPTYPE_ACTIVATE:
7054 case OPTYPE_ACTIVATE_REFD:
7055 case OPTYPE_EXECUTE: // r1 [v2]
7056 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7057 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7058 case OPTYPE_MATCH: // v1 t2
7059 case OPTYPE_ISCHOSEN_T:
7060 case OPTYPE_LOG2STR:
7061 case OPTYPE_ENCODE:
7062 case OPTYPE_DECODE:
7063 case OPTYPE_ISBOUND:
7064 case OPTYPE_ISPRESENT:
7065 case OPTYPE_TTCN2STRING:
7066 case OPTYPE_UNICHAR2OCT:
7067 case OPTYPE_OCT2UNICHAR:
7068 case OPTYPE_ENCODE_BASE64:
7069 case OPTYPE_DECODE_BASE64:
7070 break;
7071 case OPTYPE_TESTCASENAME: { // -
7072 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7073 Ttcn::StatementBlock *my_sb =
7074 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7075 if (!my_sb) break;
7076 Ttcn::Definition *my_def = my_sb->get_my_def();
7077 if (!my_def) { // In control part.
7078 set_val_str(new string(""));
7079 valuetype = V_CSTR;
7080 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7081 set_val_str(new string(my_def->get_id().get_dispname()));
7082 valuetype = V_CSTR;
7083 }
7084 break; }
7085 case OPTYPE_UNARYPLUS: // v1
7086 v1=u.expr.v1;
7087 u.expr.v1=0;
7088 copy_and_destroy(v1);
7089 break;
7090 case OPTYPE_UNARYMINUS:
7091 if (is_unfoldable()) break;
7092 v1 = u.expr.v1->get_value_refd_last();
7093 switch (v1->valuetype) {
7094 case V_INT: {
7095 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7096 if (!i) FATAL_ERROR("Value::evaluate_value()");
7097 clean_up();
7098 valuetype = V_INT;
7099 u.val_Int = i;
7100 break; }
7101 case V_REAL: {
7102 ttcn3float r = v1->get_val_Real();
7103 clean_up();
7104 valuetype = V_REAL;
7105 u.val_Real = -r;
7106 break; }
7107 default:
7108 FATAL_ERROR("Value::evaluate_value()");
7109 }
7110 break;
7111 case OPTYPE_NOT: {
7112 if(is_unfoldable()) break;
7113 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7114 clean_up();
7115 valuetype=V_BOOL;
7116 u.val_bool=!b;
7117 break;}
7118 case OPTYPE_NOT4B: {
7119 if(is_unfoldable()) break;
7120 v1=u.expr.v1->get_value_refd_last();
7121 const string& s = v1->get_val_str();
7122 valuetype_t vt=v1->valuetype;
7123 clean_up();
7124 valuetype=vt;
7125 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7126 break;}
7127 case OPTYPE_BIT2HEX: {
7128 if(is_unfoldable()) break;
7129 v1=u.expr.v1->get_value_refd_last();
7130 const string& s = v1->get_val_str();
7131 clean_up();
7132 valuetype=V_HSTR;
7133 set_val_str(bit2hex(s));
7134 break;}
7135 case OPTYPE_BIT2OCT: {
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(bit2oct(s));
7142 break;}
7143 case OPTYPE_BIT2STR:
7144 case OPTYPE_HEX2STR:
7145 case OPTYPE_OCT2STR: {
7146 if(is_unfoldable()) break;
7147 v1=u.expr.v1->get_value_refd_last();
7148 const string& s = v1->get_val_str();
7149 clean_up();
7150 valuetype=V_CSTR;
7151 set_val_str(new string(s));
7152 break;}
7153 case OPTYPE_BIT2INT: {
7154 if (is_unfoldable()) break;
7155 v1 = u.expr.v1->get_value_refd_last();
7156 const string& s = v1->get_val_str();
7157 clean_up();
7158 valuetype = V_INT;
7159 u.val_Int = bit2int(s);
7160 break; }
7161 case OPTYPE_CHAR2INT: {
7162 if (is_unfoldable()) break;
7163 v1 = u.expr.v1->get_value_refd_last();
7164 char c = v1->get_val_str()[0];
7165 clean_up();
7166 valuetype = V_INT;
7167 u.val_Int = new int_val_t((Int)c);
7168 break; }
7169 case OPTYPE_CHAR2OCT: {
7170 if(is_unfoldable()) break;
7171 v1=u.expr.v1->get_value_refd_last();
7172 const string& s = v1->get_val_str();
7173 clean_up();
7174 valuetype=V_OSTR;
7175 set_val_str(char2oct(s));
7176 break;}
7177 case OPTYPE_STR2INT: {
7178 if (is_unfoldable()) break;
7179 v1 = u.expr.v1->get_value_refd_last();
7180 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7181 clean_up();
7182 valuetype = V_INT;
7183 u.val_Int = i;
7184 /** \todo hiba eseten lenyeli... */
7185 break; }
7186 case OPTYPE_STR2FLOAT: {
7187 if(is_unfoldable()) break;
7188 v1=u.expr.v1->get_value_refd_last();
7189 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7190 clean_up();
7191 valuetype=V_REAL;
7192 u.val_Real=r;
7193 /** \todo hiba eseten lenyeli... */
7194 break;}
7195 case OPTYPE_STR2BIT: {
7196 if(is_unfoldable()) break;
7197 v1=u.expr.v1->get_value_refd_last();
7198 const string& s = v1->get_val_str();
7199 clean_up();
7200 valuetype=V_BSTR;
7201 set_val_str(new string(s));
7202 break;}
7203 case OPTYPE_STR2HEX:
7204 case OPTYPE_OCT2HEX: {
7205 if(is_unfoldable()) break;
7206 v1=u.expr.v1->get_value_refd_last();
7207 const string& s = v1->get_val_str();
7208 clean_up();
7209 valuetype=V_HSTR;
7210 set_val_str(to_uppercase(s));
7211 break;}
7212 case OPTYPE_STR2OCT: {
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_OSTR;
7218 set_val_str(to_uppercase(s));
7219 break;}
7220 case OPTYPE_FLOAT2INT: {
7221 if (is_unfoldable()) break;
7222 v1 = u.expr.v1->get_value_refd_last();
7223 ttcn3float r = v1->get_val_Real();
7224 clean_up();
7225 valuetype = V_INT;
7226 u.val_Int = float2int(r, *u.expr.v1);
7227 break;}
7228 case OPTYPE_FLOAT2STR: {
7229 if(is_unfoldable()) break;
7230 v1=u.expr.v1->get_value_refd_last();
7231 ttcn3float r=v1->get_val_Real();
7232 clean_up();
7233 valuetype=V_CSTR;
7234 set_val_str(float2str(r));
7235 break;}
7236 case OPTYPE_HEX2BIT:
7237 case OPTYPE_OCT2BIT: {
7238 if(is_unfoldable()) break;
7239 v1=u.expr.v1->get_value_refd_last();
7240 const string& s = v1->get_val_str();
7241 clean_up();
7242 valuetype=V_BSTR;
7243 set_val_str(hex2bit(s));
7244 break;}
7245 case OPTYPE_HEX2INT:
7246 case OPTYPE_OCT2INT: {
7247 if(is_unfoldable()) break;
7248 v1=u.expr.v1->get_value_refd_last();
7249 const string& s = v1->get_val_str();
7250 clean_up();
7251 valuetype=V_INT;
7252 u.val_Int=hex2int(s);
7253 break;}
7254 case OPTYPE_HEX2OCT: {
7255 if(is_unfoldable()) break;
7256 v1=u.expr.v1->get_value_refd_last();
7257 const string& s = v1->get_val_str();
7258 clean_up();
7259 valuetype=V_OSTR;
7260 set_val_str(hex2oct(s));
7261 break;}
7262 case OPTYPE_INT2CHAR: {
7263 if (is_unfoldable()) break;
7264 v1 = u.expr.v1->get_value_refd_last();
7265 const int_val_t *c_int = v1->get_val_Int();
7266 char c = static_cast<char>(c_int->get_val());
7267 clean_up();
7268 valuetype = V_CSTR;
7269 set_val_str(new string(1, &c));
7270 break; }
7271 case OPTYPE_INT2UNICHAR: {
7272 if (is_unfoldable()) break;
7273 v1 = u.expr.v1->get_value_refd_last();
7274 const int_val_t *i_int = v1->get_val_Int();
7275 Int i = i_int->get_val();
7276 clean_up();
7277 valuetype = V_USTR;
7278 set_val_ustr(int2unichar(i));
7279 u.ustr.convert_str = false;
7280 break; }
7281 case OPTYPE_INT2FLOAT: {
7282 if (is_unfoldable()) break;
7283 v1 = u.expr.v1->get_value_refd_last();
7284 const int_val_t *i_int = v1->get_val_Int();
7285 Real i_int_real = i_int->to_real();
7286 clean_up();
7287 valuetype = V_REAL;
7288 u.val_Real = i_int_real;
7289 break; }
7290 case OPTYPE_INT2STR: {
7291 if (is_unfoldable()) break;
7292 v1 = u.expr.v1->get_value_refd_last();
7293 const int_val_t *i_int = v1->get_val_Int();
7294 string *i_int_str = new string(i_int->t_str());
7295 clean_up();
7296 valuetype = V_CSTR;
7297 set_val_str(i_int_str);
7298 break; }
7299 case OPTYPE_OCT2CHAR: {
7300 if(is_unfoldable()) break;
7301 v1=u.expr.v1->get_value_refd_last();
7302 const string& s = v1->get_val_str();
7303 clean_up();
7304 valuetype=V_CSTR;
7305 set_val_str(oct2char(s));
7306 break;}
7307 case OPTYPE_GET_STRINGENCODING: {
7308 if(is_unfoldable()) break;
7309 v1 = u.expr.v1->get_value_refd_last();
7310 const string& s1 = v1->get_val_str();
7311 clean_up();
7312 valuetype = V_CSTR;
7313 set_val_str(get_stringencoding(s1));
7314 break;}
7315 case OPTYPE_REMOVE_BOM: {
7316 if(is_unfoldable()) break;
7317 v1 = u.expr.v1->get_value_refd_last();
7318 const string& s1 = v1->get_val_str();
7319 clean_up();
7320 valuetype = V_OSTR;
7321 set_val_str(remove_bom(s1));
7322 break;}
7323 case OPTYPE_ENUM2INT: {
7324 if(is_unfoldable()) break;
7325 v1=u.expr.v1->get_value_refd_last();
7326 Type* enum_type = v1->get_my_governor();
7327 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7328 clean_up();
7329 valuetype = V_INT;
7330 u.val_Int = new int_val_t(enum_val);
7331 break;}
7332 case OPTYPE_UNICHAR2INT:
7333 if (is_unfoldable()) {
7334 // replace the operation with char2int() if the operand is a charstring
7335 // value to avoid its unnecessary conversion to universal charstring
7336 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7337 u.expr.v_optype = OPTYPE_CHAR2INT;
7338 } else {
7339 v1=u.expr.v1->get_value_refd_last();
7340 const ustring& s = v1->get_val_ustr();
7341 clean_up();
7342 valuetype=V_INT;
7343 u.val_Int=new int_val_t(unichar2int(s));
7344 }
7345 break;
7346 case OPTYPE_UNICHAR2CHAR:
7347 v1 = u.expr.v1;
7348 if (is_unfoldable()) {
7349 // replace the operation with its operand if it is a charstring
7350 // value to avoid its unnecessary conversion to universal charstring
7351 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7352 u.expr.v1 = 0;
7353 copy_and_destroy(v1);
7354 }
7355 } else {
7356 v1 = v1->get_value_refd_last();
7357 const ustring& s = v1->get_val_ustr();
7358 clean_up();
7359 valuetype = V_CSTR;
7360 set_val_str(new string(s));
7361 }
7362 break;
7363 case OPTYPE_MULTIPLY: { // v1 v2
7364 if (!is_unfoldable()) goto eval_arithmetic;
7365 v1 = u.expr.v1->get_value_refd_last();
7366 v2 = u.expr.v2->get_value_refd_last();
7367 if (v1->is_unfoldable()) v1 = v2;
7368 if (v1->is_unfoldable()) break;
7369 switch(v1->valuetype) {
7370 case V_INT: {
7371 if (*v1->get_val_Int() != 0) break;
7372 clean_up();
7373 valuetype = V_INT;
7374 u.val_Int = new int_val_t((Int)0);
7375 break; }
7376 case V_REAL: {
7377 if (v1->get_val_Real() != 0.0) break;
7378 clean_up();
7379 valuetype = V_REAL;
7380 u.val_Real = 0.0;
7381 break; }
7382 default:
7383 FATAL_ERROR("Value::evaluate_value()");
7384 }
7385 break; }
7386 case OPTYPE_ADD: // v1 v2
7387 case OPTYPE_SUBTRACT:
7388 case OPTYPE_DIVIDE:
7389 case OPTYPE_MOD:
7390 case OPTYPE_REM: {
7391 eval_arithmetic:
7392 if(is_unfoldable()) break;
7393 v1=u.expr.v1->get_value_refd_last();
7394 v2=u.expr.v2->get_value_refd_last();
7395 operationtype_t ot=u.expr.v_optype;
7396 switch (v1->valuetype) {
7397 case V_INT: {
7398 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7399 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7400 clean_up();
7401 valuetype = V_INT;
7402 switch (ot) {
7403 case OPTYPE_ADD:
7404 u.val_Int = new int_val_t(*i1 + *i2);
7405 break;
7406 case OPTYPE_SUBTRACT:
7407 u.val_Int = new int_val_t(*i1 - *i2);
7408 break;
7409 case OPTYPE_MULTIPLY:
7410 u.val_Int = new int_val_t(*i1 * *i2);
7411 break;
7412 case OPTYPE_DIVIDE:
7413 u.val_Int = new int_val_t(*i1 / *i2);
7414 break;
7415 case OPTYPE_MOD:
7416 u.val_Int = new int_val_t(mod(*i1, *i2));
7417 break;
7418 case OPTYPE_REM:
7419 u.val_Int = new int_val_t(rem(*i1, *i2));
7420 break;
7421 default:
7422 FATAL_ERROR("Value::evaluate_value()");
7423 }
7424 delete i1;
7425 delete i2;
7426 break; }
7427 case V_REAL: {
7428 ttcn3float r1=v1->get_val_Real();
7429 ttcn3float r2=v2->get_val_Real();
7430 clean_up();
7431 valuetype=V_REAL;
7432 switch(ot) {
7433 case OPTYPE_ADD:
7434 u.val_Real=r1+r2;
7435 break;
7436 case OPTYPE_SUBTRACT:
7437 u.val_Real=r1-r2;
7438 break;
7439 case OPTYPE_MULTIPLY:
7440 u.val_Real=r1*r2;
7441 break;
7442 case OPTYPE_DIVIDE:
7443 u.val_Real=r1/r2;
7444 break;
7445 default:
7446 FATAL_ERROR("Value::evaluate_value()");
7447 }
7448 break;}
7449 default:
7450 FATAL_ERROR("Value::evaluate_value()");
7451 }
7452 break;}
7453 case OPTYPE_CONCAT: {
7454 if(is_unfoldable()) break;
7455 v1=u.expr.v1->get_value_refd_last();
7456 v2=u.expr.v2->get_value_refd_last();
7457 valuetype_t vt = v1->valuetype;
7458 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7459 const ustring& s1 = v1->get_val_ustr();
7460 const ustring& s2 = v2->get_val_ustr();
7461 clean_up();
7462 valuetype = V_USTR;
7463 set_val_ustr(new ustring(s1 + s2));
7464 u.ustr.convert_str = false;
7465 } else {
7466 const string& s1 = v1->get_val_str();
7467 const string& s2 = v2->get_val_str();
7468 clean_up();
7469 valuetype = vt;
7470 set_val_str(new string(s1 + s2));
7471 }
7472 break;}
7473 case OPTYPE_EQ: {
7474 if(is_unfoldable()) break;
7475 v1=u.expr.v1->get_value_refd_last();
7476 v2=u.expr.v2->get_value_refd_last();
7477 bool b=*v1==*v2;
7478 clean_up();
7479 valuetype=V_BOOL;
7480 u.val_bool=b;
7481 break;}
7482 case OPTYPE_NE: {
7483 if(is_unfoldable()) break;
7484 v1=u.expr.v1->get_value_refd_last();
7485 v2=u.expr.v2->get_value_refd_last();
7486 bool b=*v1==*v2;
7487 clean_up();
7488 valuetype=V_BOOL;
7489 u.val_bool=!b;
7490 break;}
7491 case OPTYPE_LT: {
7492 if(is_unfoldable()) break;
7493 v1=u.expr.v1->get_value_refd_last();
7494 v2=u.expr.v2->get_value_refd_last();
7495 bool b=*v1<*v2;
7496 clean_up();
7497 valuetype=V_BOOL;
7498 u.val_bool=b;
7499 break;}
7500 case OPTYPE_GT: {
7501 if(is_unfoldable()) break;
7502 v1=u.expr.v1->get_value_refd_last();
7503 v2=u.expr.v2->get_value_refd_last();
7504 bool b=*v2<*v1;
7505 clean_up();
7506 valuetype=V_BOOL;
7507 u.val_bool=b;
7508 break;}
7509 case OPTYPE_GE: {
7510 if(is_unfoldable()) break;
7511 v1=u.expr.v1->get_value_refd_last();
7512 v2=u.expr.v2->get_value_refd_last();
7513 bool b=*v1<*v2;
7514 clean_up();
7515 valuetype=V_BOOL;
7516 u.val_bool=!b;
7517 break;}
7518 case OPTYPE_LE: {
7519 if(is_unfoldable()) break;
7520 v1=u.expr.v1->get_value_refd_last();
7521 v2=u.expr.v2->get_value_refd_last();
7522 bool b=*v2<*v1;
7523 clean_up();
7524 valuetype=V_BOOL;
7525 u.val_bool=!b;
7526 break;}
7527 case OPTYPE_AND:
7528 v1 = u.expr.v1->get_value_refd_last();
7529 if (v1->valuetype == V_BOOL) {
7530 if (v1->get_val_bool()) {
7531 // the left operand is a literal "true"
7532 // substitute the expression with the right operand
7533 v2 = u.expr.v2;
7534 u.expr.v2 = 0;
7535 copy_and_destroy(v2);
7536 } else {
7537 // the left operand is a literal "false"
7538 // the result must be false regardless the right operand
7539 // because of the short circuit evaluation rule
7540 clean_up();
7541 valuetype = V_BOOL;
7542 u.val_bool = false;
7543 }
7544 } else {
7545 // we must keep the left operand because of the potential side effects
7546 // the right operand can only be eliminated if it is a literal "true"
7547 v2 = u.expr.v2->get_value_refd_last();
7548 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7549 v1 = u.expr.v1;
7550 u.expr.v1 = 0;
7551 copy_and_destroy(v1);
7552 }
7553 }
7554 break;
7555 case OPTYPE_OR:
7556 v1 = u.expr.v1->get_value_refd_last();
7557 if (v1->valuetype == V_BOOL) {
7558 if (v1->get_val_bool()) {
7559 // the left operand is a literal "true"
7560 // the result must be true regardless the right operand
7561 // because of the short circuit evaluation rule
7562 clean_up();
7563 valuetype = V_BOOL;
7564 u.val_bool = true;
7565 } else {
7566 // the left operand is a literal "false"
7567 // substitute the expression with the right operand
7568 v2 = u.expr.v2;
7569 u.expr.v2 = 0;
7570 copy_and_destroy(v2);
7571 }
7572 } else {
7573 // we must keep the left operand because of the potential side effects
7574 // the right operand can only be eliminated if it is a literal "false"
7575 v2 = u.expr.v2->get_value_refd_last();
7576 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7577 v1 = u.expr.v1;
7578 u.expr.v1 = 0;
7579 copy_and_destroy(v1);
7580 }
7581 }
7582 break;
7583 case OPTYPE_XOR: {
7584 if(is_unfoldable()) break;
7585 v1=u.expr.v1->get_value_refd_last();
7586 v2=u.expr.v2->get_value_refd_last();
7587 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7588 clean_up();
7589 valuetype=V_BOOL;
7590 u.val_bool=b;
7591 break;}
7592 case OPTYPE_AND4B: {
7593 if(is_unfoldable()) break;
7594 v1=u.expr.v1->get_value_refd_last();
7595 v2=u.expr.v2->get_value_refd_last();
7596 valuetype_t vt=v1->valuetype;
7597 const string& s1 = v1->get_val_str();
7598 const string& s2 = v2->get_val_str();
7599 clean_up();
7600 valuetype=vt;
7601 set_val_str(and4b(s1, s2));
7602 break;}
7603 case OPTYPE_OR4B: {
7604 if(is_unfoldable()) break;
7605 v1=u.expr.v1->get_value_refd_last();
7606 v2=u.expr.v2->get_value_refd_last();
7607 valuetype_t vt=v1->valuetype;
7608 const string& s1 = v1->get_val_str();
7609 const string& s2 = v2->get_val_str();
7610 clean_up();
7611 valuetype=vt;
7612 set_val_str(or4b(s1, s2));
7613 break;}
7614 case OPTYPE_XOR4B: {
7615 if(is_unfoldable()) break;
7616 v1=u.expr.v1->get_value_refd_last();
7617 v2=u.expr.v2->get_value_refd_last();
7618 valuetype_t vt=v1->valuetype;
7619 const string& s1 = v1->get_val_str();
7620 const string& s2 = v2->get_val_str();
7621 clean_up();
7622 valuetype=vt;
7623 set_val_str(xor4b(s1, s2));
7624 break;}
7625 case OPTYPE_SHL: {
7626 if(is_unfoldable()) break;
7627 v1=u.expr.v1->get_value_refd_last();
7628 v2=u.expr.v2->get_value_refd_last();
7629 valuetype_t vt=v1->valuetype;
7630 const string& s = v1->get_val_str();
7631 const int_val_t *i_int = v2->get_val_Int();
7632 Int i=i_int->get_val();
7633 if(vt==V_OSTR) i*=2;
7634 clean_up();
7635 valuetype=vt;
7636 set_val_str(shift_left(s, i));
7637 break;}
7638 case OPTYPE_SHR: {
7639 if(is_unfoldable()) break;
7640 v1=u.expr.v1->get_value_refd_last();
7641 v2=u.expr.v2->get_value_refd_last();
7642 valuetype_t vt=v1->valuetype;
7643 const string& s = v1->get_val_str();
7644 const int_val_t *i_int = v2->get_val_Int();
7645 Int i=i_int->get_val();
7646 if(vt==V_OSTR) i*=2;
7647 clean_up();
7648 valuetype=vt;
7649 set_val_str(shift_right(s, i));
7650 break;}
7651 case OPTYPE_ROTL: {
7652 if(is_unfoldable()) break;
7653 v1=u.expr.v1->get_value_refd_last();
7654 v2=u.expr.v2->get_value_refd_last();
7655 valuetype_t vt=v1->valuetype;
7656 const int_val_t *i_int=v2->get_val_Int();
7657 Int i=i_int->get_val();
7658 if(vt==V_USTR) {
7659 const ustring& s = v1->get_val_ustr();
7660 clean_up();
7661 valuetype=vt;
7662 set_val_ustr(rotate_left(s, i));
7663 u.ustr.convert_str = false;
7664 }
7665 else {
7666 if(vt==V_OSTR) i*=2;
7667 const string& s = v1->get_val_str();
7668 clean_up();
7669 valuetype=vt;
7670 set_val_str(rotate_left(s, i));
7671 }
7672 break;}
7673 case OPTYPE_ROTR: {
7674 if(is_unfoldable()) break;
7675 v1=u.expr.v1->get_value_refd_last();
7676 v2=u.expr.v2->get_value_refd_last();
7677 valuetype_t vt=v1->valuetype;
7678 const int_val_t *i_int=v2->get_val_Int();
7679 Int i=i_int->get_val();
7680 if(vt==V_USTR) {
7681 const ustring& s = v1->get_val_ustr();
7682 clean_up();
7683 valuetype=vt;
7684 set_val_ustr(rotate_right(s, i));
7685 u.ustr.convert_str = false;
7686 }
7687 else {
7688 if(vt==V_OSTR) i*=2;
7689 const string& s = v1->get_val_str();
7690 clean_up();
7691 valuetype=vt;
7692 set_val_str(rotate_right(s, i));
7693 }
7694 break;}
7695 case OPTYPE_INT2BIT: {
7696 if (is_unfoldable()) break;
7697 v1 = u.expr.v1->get_value_refd_last();
7698 v2 = u.expr.v2->get_value_refd_last();
7699 const int_val_t *i1_int = v1->get_val_Int();
7700 const int_val_t *i2_int = v2->get_val_Int();
7701 string *val = int2bit(*i1_int, i2_int->get_val());
7702 clean_up();
7703 valuetype = V_BSTR;
7704 set_val_str(val);
7705 break; }
7706 case OPTYPE_INT2HEX: {
7707 if (is_unfoldable()) break;
7708 v1 = u.expr.v1->get_value_refd_last();
7709 v2 = u.expr.v2->get_value_refd_last();
7710 const int_val_t *i1_int = v1->get_val_Int();
7711 const int_val_t *i2_int = v2->get_val_Int();
7712 // Do it before the `clean_up'. i2_int is already checked.
7713 string *val = int2hex(*i1_int, i2_int->get_val());
7714 clean_up();
7715 valuetype = V_HSTR;
7716 set_val_str(val);
7717 break; }
7718 case OPTYPE_INT2OCT: {
7719 if (is_unfoldable()) break;
7720 v1 = u.expr.v1->get_value_refd_last();
7721 v2 = u.expr.v2->get_value_refd_last();
7722 const int_val_t i1_int(*v1->get_val_Int());
7723 // `v2' is a native integer.
7724 Int i2_int = v2->get_val_Int()->get_val() * 2;
7725 clean_up();
7726 valuetype = V_OSTR;
7727 set_val_str(int2hex(i1_int, i2_int));
7728 break; }
7729 case OPTYPE_SUBSTR: {
7730 if(is_unfoldable()) break;
7731 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7732 v2=u.expr.v2->get_value_refd_last();
7733 v3=u.expr.v3->get_value_refd_last();
7734 valuetype_t vt=v1->valuetype;
7735 const int_val_t *i2_int=v2->get_val_Int();
7736 const int_val_t *i3_int=v3->get_val_Int();
7737 Int i2=i2_int->get_val();
7738 Int i3=i3_int->get_val();
7739 if(vt==V_USTR) {
7740 const ustring& s = v1->get_val_ustr();
7741 clean_up();
7742 valuetype=vt;
7743 set_val_ustr(new ustring(s.substr(i2, i3)));
7744 u.ustr.convert_str = false;
7745 }
7746 else {
7747 if(vt==V_OSTR) {
7748 i2*=2;
7749 i3*=2;
7750 }
7751 const string& s = v1->get_val_str();
7752 clean_up();
7753 valuetype=vt;
7754 set_val_str(new string(s.substr(i2, i3)));
7755 }
7756 break;}
7757 case OPTYPE_REPLACE: {
7758 if(is_unfoldable()) break;
7759 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7760 v2=u.expr.v2->get_value_refd_last();
7761 v3=u.expr.v3->get_value_refd_last();
7762 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7763 valuetype_t vt=v1->valuetype;
7764 const int_val_t *i2_int=v2->get_val_Int();
7765 const int_val_t *i3_int=v3->get_val_Int();
7766 Int i2=i2_int->get_val();
7767 Int i3=i3_int->get_val();
7768 switch(vt) {
7769 case V_BSTR: {
7770 string *s1 = new string(v1->get_val_str());
7771 const string& s2 = v4->get_val_str();
7772 clean_up();
7773 valuetype=vt;
7774 s1->replace(i2, i3, s2);
7775 set_val_str(s1);
7776 break;}
7777 case V_HSTR: {
7778 string *s1 = new string(v1->get_val_str());
7779 const string& s2 = v4->get_val_str();
7780 clean_up();
7781 valuetype=vt;
7782 s1->replace(i2, i3, s2);
7783 set_val_str(s1);
7784 break;}
7785 case V_OSTR: {
7786 i2*=2;
7787 i3*=2;
7788 string *s1 = new string(v1->get_val_str());
7789 const string& s2 = v4->get_val_str();
7790 clean_up();
7791 valuetype=vt;
7792 s1->replace(i2, i3, s2);
7793 set_val_str(s1);
7794 break;}
7795 case V_CSTR: {
7796 string *s1 = new string(v1->get_val_str());
7797 const string& s2 = v4->get_val_str();
7798 clean_up();
7799 valuetype=vt;
7800 s1->replace(i2, i3, s2);
7801 set_val_str(s1);
7802 break;}
7803 case V_USTR: {
7804 ustring *s1 = new ustring(v1->get_val_ustr());
7805 const ustring& s2 = v4->get_val_ustr();
7806 clean_up();
7807 valuetype=vt;
7808 s1->replace(i2, i3, s2);
7809 set_val_ustr(s1);
7810 u.ustr.convert_str = false;
7811 break;}
7812 default:
7813 FATAL_ERROR("Value::evaluate_value()");
7814 }
7815 break; }
7816 case OPTYPE_REGEXP: {
7817 if (is_unfoldable()) break;
7818 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7819 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7820 v3=u.expr.v3->get_value_refd_last();
7821 const int_val_t *i3_int = v3->get_val_Int();
7822 Int i3 = i3_int->get_val();
7823 if (v1->valuetype == V_CSTR) {
7824 const string& s1 = v1->get_val_str();
7825 const string& s2 = v2->get_val_str();
7826 string *result = regexp(s1, s2, i3);
7827 clean_up();
7828 valuetype = V_CSTR;
7829 set_val_str(result);
7830 } if (v1->valuetype == V_USTR) {
7831 const ustring& s1 = v1->get_val_ustr();
7832 const ustring& s2 = v2->get_val_ustr();
7833 ustring *result = regexp(s1, s2, i3);
7834 clean_up();
7835 valuetype = V_USTR;
7836 set_val_ustr(result);
7837 u.ustr.convert_str = false;
7838 }
7839 break; }
7840 case OPTYPE_LENGTHOF:{
7841 if(is_unfoldable()) break;
7842 v1=u.expr.ti1->get_Template()->get_specific_value()
7843 ->get_value_refd_last();
7844 size_t i;
7845 if(v1->is_string_type(exp_val)) {
7846 i=v1->get_val_strlen();
7847 } else { // v1 is be seq/set of or array
7848 switch (v1->valuetype) {
7849 case V_SEQOF:
7850 case V_SETOF:
7851 case V_ARRAY: {
7852 if(v1->u.val_vs->is_indexed())
7853 { i = v1->u.val_vs->get_nof_ivs();}
7854 else { i = v1->u.val_vs->get_nof_vs();}
7855 break; }
7856 default:
7857 FATAL_ERROR("Value::evaluate_value()");
7858 }
7859 }
7860 clean_up();
7861 valuetype=V_INT;
7862 u.val_Int=new int_val_t(i);
7863 break;}
7864 case OPTYPE_SIZEOF: {
7865 Int i=chk_eval_expr_sizeof(refch, exp_val);
7866 if(i!=-1) {
7867 clean_up();
7868 valuetype=V_INT;
7869 u.val_Int=new int_val_t(i);
7870 }
7871 break;}
7872 case OPTYPE_ISVALUE: {
7873 if(is_unfoldable()) break;
7874 bool is_singleval = !u.expr.ti1->get_DerivedRef()
7875 && u.expr.ti1->get_Template()->is_Value();
7876 if (is_singleval) {
7877 Value * other_val = u.expr.ti1->get_Template()->get_Value();
7878 is_singleval = other_val->evaluate_isvalue(false);
7879 // is_singleval now contains the compile-time result of isvalue
7880 delete other_val;
7881 }
7882 clean_up();
7883 valuetype = V_BOOL;
7884 u.val_bool = is_singleval;
7885 break;}
7886 case OPTYPE_ISCHOSEN_V: {
7887 if (is_unfoldable()) break;
7888 v1 = u.expr.v1->get_value_refd_last();
7889 bool b = v1->field_is_chosen(*u.expr.i2);
7890 clean_up();
7891 valuetype = V_BOOL;
7892 u.val_bool = b;
7893 break; }
7894 case OPTYPE_VALUEOF: // ti1
7895 if (!u.expr.ti1->get_DerivedRef() &&
7896 u.expr.ti1->get_Template()->is_Value() &&
7897 !u.expr.ti1->get_Type()) {
7898 // FIXME actually if the template instance has a type
7899 // it might still be foldable.
7900 // the argument is a single specific value
7901 v1 = u.expr.ti1->get_Template()->get_Value();
7902 Type *governor = my_governor;
7903 if (governor == NULL) {
7904 governor = u.expr.ti1->get_expr_governor(exp_val);
7905 if (governor != NULL) governor = governor->get_type_refd_last();
7906 }
7907 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
7908 if (governor == NULL)
7909 FATAL_ERROR("Value::evaluate_value()");
7910 clean_up();
7911 valuetype = v1->valuetype;
7912 u = v1->u;
7913 set_my_governor(governor);
7914 if (valuetype == V_REFD && u.ref.refd_last == v1)
7915 u.ref.refd_last = this;
7916 v1->valuetype = V_ERROR;
7917 delete v1;
7918 }
7919 break;
7920 case OPTYPE_UNDEF_RUNNING:
7921 default:
7922 FATAL_ERROR("Value::evaluate_value()");
7923 } // switch optype
7924 }
7925
7926 bool Value::evaluate_isvalue(bool from_sequence)
7927 {
7928 switch (valuetype) {
7929 case V_OMIT:
7930 // Omit is not a value unless a member of a sequence or set
7931 return from_sequence;
7932 case V_NOTUSED:
7933 return false;
7934 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
7935 case V_BOOL: /**< boolean */
7936 case V_NAMEDINT: /**< integer / named number */
7937 case V_NAMEDBITS: /**< named bits (identifiers) */
7938 case V_INT: /**< integer */
7939 case V_REAL: /**< real/float */
7940 case V_ENUM: /**< enumerated */
7941 case V_BSTR: /**< bitstring */
7942 case V_HSTR: /**< hexstring */
7943 case V_OSTR: /**< octetstring */
7944 case V_CSTR: /**< charstring */
7945 case V_USTR: /**< universal charstring */
7946 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
7947 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
7948 case V_OID: /**< object identifier */
7949 case V_ROID: /**< relative object identifier */
7950 case V_VERDICT: /**< all verdicts */
7951 return true; // values of built-in types return true
7952
7953 // Code below was adapted from is_unfoldable(), false returned early.
7954 case V_CHOICE:
7955 return u.choice.alt_value->evaluate_isvalue(false);
7956
7957 case V_SEQOF:
7958 case V_SETOF:
7959 case V_ARRAY:
7960 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
7961 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
7962 return false;
7963 }
7964 }
7965 return true;
7966
7967 case V_SEQ:
7968 case V_SET:
7969 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
7970 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
7971 ->evaluate_isvalue(true)) return false;
7972 }
7973 return true;
7974
7975 case V_REFD:
7976 // alas, get_value_refd_last prevents this function from const
7977 return get_value_refd_last()->evaluate_isvalue(false);
7978
7979 case V_EXPR:
7980 switch (u.expr.v_optype) {
7981 // A constant null component reference is a corner case: it is foldable
7982 // but escapes unmodified from evaluate_value.
7983 // A V_EXPR with any other OPTYPE_ is either unfoldable,
7984 // or is transformed into some other valuetype in evaluate_value.
7985 case OPTYPE_COMP_NULL:
7986 return false;
7987 default:
7988 break; // and fall through to the FATAL_ERROR
7989 }
7990 // no break
7991 default:
7992 FATAL_ERROR("Value::evaluate_isvalue()");
7993 break;
7994 }
7995 return true;
7996 }
7997
7998 void Value::evaluate_macro(Type::expected_value_t exp_val)
7999 {
8000 switch (u.macro) {
8001 case MACRO_MODULEID:
8002 if (!my_scope)
8003 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8004 set_val_str(new string(my_scope->get_scope_mod()
8005 ->get_modid().get_dispname()));
8006 valuetype = V_CSTR;
8007 break;
8008 case MACRO_FILENAME:
8009 case MACRO_BFILENAME: {
8010 const char *t_filename = get_filename();
8011 if (!t_filename)
8012 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8013 set_val_str(new string(t_filename));
8014 valuetype = V_CSTR;
8015 break; }
8016 case MACRO_FILEPATH: {
8017 const char *t_filename = get_filename();
8018 if (!t_filename)
8019 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8020 char *t_filepath = canonize_input_file(t_filename);
8021 if (!t_filepath)
8022 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8023 set_val_str(new string(t_filepath));
8024 valuetype = V_CSTR;
8025 Free(t_filepath);
8026 break; }
8027 case MACRO_LINENUMBER: {
8028 int t_lineno = get_first_line();
8029 if (t_lineno <= 0)
8030 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8031 set_val_str(new string(Int2string(t_lineno)));
8032 valuetype = V_CSTR;
8033 break; }
8034 case MACRO_LINENUMBER_C: {
8035 int t_lineno = get_first_line();
8036 if (t_lineno <= 0)
8037 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8038 u.val_Int = new int_val_t(t_lineno);
8039 valuetype = V_INT;
8040 break; }
8041 case MACRO_DEFINITIONID: {
8042 // cut the second part from the fullname separated by dots
8043 const string& t_fullname = get_fullname();
8044 size_t first_char = t_fullname.find('.') + 1;
8045 if (first_char >= t_fullname.size())
8046 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8047 t_fullname.c_str());
8048 set_val_str(new string(t_fullname.substr(first_char,
8049 t_fullname.find('.', first_char) - first_char)));
8050 valuetype = V_CSTR;
8051 break; }
8052 case MACRO_SCOPE: {
8053 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8054 set_val_str(new string(my_scope->get_scopeMacro_name()));
8055 valuetype = V_CSTR;
8056 break;
8057 }
8058 case MACRO_TESTCASEID: {
8059 if (exp_val == Type::EXPECTED_CONSTANT ||
8060 exp_val == Type::EXPECTED_STATIC_VALUE) {
8061 error("A %s value was expected instead of macro `%%testcaseId', "
8062 "which is evaluated at runtime",
8063 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8064 goto error;
8065 }
8066 if (!my_scope)
8067 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8068 Ttcn::StatementBlock *my_sb =
8069 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8070 if (!my_sb) {
8071 error("Usage of macro %%testcaseId is allowed only within the "
8072 "statement blocks of functions, altsteps and testcases");
8073 goto error;
8074 }
8075 Ttcn::Definition *my_def = my_sb->get_my_def();
8076 if (!my_def) {
8077 error("Macro %%testcaseId cannot be used in the control part. "
8078 "It is allowed only within the statement blocks of functions, "
8079 "altsteps and testcases");
8080 goto error;
8081 }
8082 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8083 // folding is possible only within testcases
8084 set_val_str(new string(my_def->get_id().get_dispname()));
8085 valuetype = V_CSTR;
8086 }
8087 break; }
8088 default:
8089 FATAL_ERROR("Value::evaluate_macro()");
8090 }
8091 return;
8092 error:
8093 set_valuetype(V_ERROR);
8094 }
8095
8096 void Value::add_id(Identifier *p_id)
8097 {
8098 switch(valuetype) {
8099 case V_NAMEDBITS:
8100 if(u.ids->has_key(p_id->get_name())) {
8101 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8102 // The Value does not take ownership for the identifier,
8103 // so it must be deleted (add_is acts as a sink).
8104 delete p_id;
8105 }
8106 else u.ids->add(p_id->get_name(), p_id);
8107 break;
8108 default:
8109 FATAL_ERROR("Value::add_id()");
8110 } // switch
8111 }
8112
8113 Value* Value::get_value_refd_last(ReferenceChain *refch,
8114 Type::expected_value_t exp_val)
8115 {
8116 set_lowerid_to_ref();
8117 switch (valuetype) {
8118 case V_INVOKE:
8119 // there might be a better place for this
8120 chk_invoke(exp_val);
8121 return this;
8122 case V_REFD:
8123 // use the cache if available
8124 if (u.ref.refd_last) return u.ref.refd_last;
8125 else {
8126 Assignment *ass = u.ref.ref->get_refd_assignment();
8127 if (!ass) {
8128 // the referred definition is not found
8129 set_valuetype(V_ERROR);
8130 } else {
8131 switch (ass->get_asstype()) {
8132 case Assignment::A_OBJECT:
8133 case Assignment::A_OS: {
8134 // the referred definition is an ASN.1 object or object set
8135 Setting *setting = u.ref.ref->get_refd_setting();
8136 if (!setting || setting->get_st() == S_ERROR) {
8137 // remain silent, the error has been already reported
8138 set_valuetype(V_ERROR);
8139 break;
8140 } else if (setting->get_st() != S_V) {
8141 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8142 " refer to a value", u.ref.ref->get_dispname().c_str());
8143 set_valuetype(V_ERROR);
8144 break;
8145 }
8146 bool destroy_refch;
8147 if (refch) {
8148 refch->mark_state();
8149 destroy_refch = false;
8150 } else {
8151 refch = new ReferenceChain(this,
8152 "While searching referenced value");
8153 destroy_refch = true;
8154 }
8155 if (refch->add(get_fullname())) {
8156 Value *v_refd = dynamic_cast<Value*>(setting);
8157 Value *v_last = v_refd->get_value_refd_last(refch);
8158 // in case of circular recursion the valuetype is already set
8159 // to V_ERROR, so don't set the cache
8160 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8161 } else {
8162 // a circular recursion was detected
8163 set_valuetype(V_ERROR);
8164 }
8165 if (destroy_refch) delete refch;
8166 else refch->prev_state();
8167 break; }
8168 case Assignment::A_CONST: {
8169 // the referred definition is a constant
8170 bool destroy_refch;
8171 if (refch) {
8172 refch->mark_state();
8173 destroy_refch = false;
8174 } else {
8175 refch = new ReferenceChain(this,
8176 "While searching referenced value");
8177 destroy_refch = true;
8178 }
8179 if (refch->add(get_fullname())) {
8180 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8181 Value *v_refd = ass->get_Value()
8182 ->get_refd_sub_value(subrefs, 0,
8183 u.ref.ref->getUsedInIsbound(), refch);
8184 if (v_refd) {
8185 Value *v_last = v_refd->get_value_refd_last(refch);
8186 // in case of circular recursion the valuetype is already set
8187 // to V_ERROR, so don't set the cache
8188 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8189 } else if (subrefs && subrefs->has_unfoldable_index()) {
8190 u.ref.refd_last = this;
8191 } else if (u.ref.ref->getUsedInIsbound()) {
8192 u.ref.refd_last = this;
8193 } else {
8194 // the sub-reference points to a non-existent field
8195 set_valuetype(V_ERROR);
8196 }
8197 } else {
8198 // a circular recursion was detected
8199 set_valuetype(V_ERROR);
8200 }
8201 if (destroy_refch) delete refch;
8202 else refch->prev_state();
8203 break; }
8204 case Assignment::A_EXT_CONST:
8205 case Assignment::A_MODULEPAR:
8206 case Assignment::A_VAR:
8207 case Assignment::A_FUNCTION_RVAL:
8208 case Assignment::A_EXT_FUNCTION_RVAL:
8209 case Assignment::A_PAR_VAL_IN:
8210 case Assignment::A_PAR_VAL_OUT:
8211 case Assignment::A_PAR_VAL_INOUT:
8212 // the referred definition is not a constant
8213 u.ref.refd_last = this;
8214 break;
8215 case Assignment::A_FUNCTION:
8216 case Assignment::A_EXT_FUNCTION:
8217 u.ref.ref->error("Reference to a value was expected instead of a "
8218 "call of %s, which does not have return type",
8219 ass->get_description().c_str());
8220 set_valuetype(V_ERROR);
8221 break;
8222 case Assignment::A_FUNCTION_RTEMP:
8223 case Assignment::A_EXT_FUNCTION_RTEMP:
8224 u.ref.ref->error("Reference to a value was expected instead of a "
8225 "call of %s, which returns a template",
8226 ass->get_description().c_str());
8227 set_valuetype(V_ERROR);
8228 break;
8229 default:
8230 u.ref.ref->error("Reference to a value was expected instead of %s",
8231 ass->get_description().c_str());
8232 set_valuetype(V_ERROR);
8233 } // switch asstype
8234 }
8235 if (valuetype == V_REFD) return u.ref.refd_last;
8236 else return this;
8237 }
8238 case V_EXPR: {
8239 // try to evaluate the expression
8240 bool destroy_refch;
8241 if(refch) {
8242 refch->mark_state();
8243 destroy_refch=false;
8244 }
8245 else {
8246 refch=new ReferenceChain(this, "While evaluating expression");
8247 destroy_refch=true;
8248 }
8249 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8250 else set_valuetype(V_ERROR);
8251 if(destroy_refch) delete refch;
8252 else refch->prev_state();
8253 return this; }
8254 case V_MACRO:
8255 evaluate_macro(exp_val);
8256 // no break
8257 default:
8258 // return this for all other value types
8259 return this;
8260 } // switch
8261 }
8262
8263 map<Value*, void> Value::UnfoldabilityCheck::running;
8264
8265 /* Note that the logic here needs to be in sync with evaluate_value,
8266 * and possibly others, i.e. if evaluate_value is called for a Value
8267 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8268 bool Value::is_unfoldable(ReferenceChain *refch,
8269 Type::expected_value_t exp_val)
8270 {
8271 if (UnfoldabilityCheck::is_running(this)) {
8272 // This function is already running on this value => infinite recursion
8273 return true;
8274 }
8275
8276 UnfoldabilityCheck checker(this);
8277
8278 if (get_needs_conversion()) return true;
8279 switch (valuetype) {
8280 case V_NAMEDINT:
8281 case V_NAMEDBITS:
8282 case V_OPENTYPE:
8283 case V_UNDEF_LOWERID:
8284 case V_UNDEF_BLOCK:
8285 case V_TTCN3_NULL:
8286 case V_REFER:
8287 // these value types are eliminated during semantic analysis
8288 FATAL_ERROR("Value::is_unfoldable()");
8289 case V_ERROR:
8290 case V_INVOKE:
8291 return true;
8292 case V_CHOICE:
8293 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8294 case V_SEQOF:
8295 case V_SETOF:
8296 case V_ARRAY:
8297 if (!is_indexed()) {
8298 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8299 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8300 return true;
8301 }
8302 } else {
8303 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8304 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8305 return true;
8306 }
8307 }
8308 return false;
8309 case V_SEQ:
8310 case V_SET:
8311 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8312 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8313 ->is_unfoldable(refch, exp_val)) return true;
8314 }
8315 return false;
8316 case V_OID:
8317 case V_ROID:
8318 chk();
8319 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8320 if ((*u.oid_comps)[i]->is_variable()) return true;
8321 }
8322 return false;
8323 case V_REFD: {
8324 Value *v_last=get_value_refd_last(refch, exp_val);
8325 if(v_last==this) return true; // there weren't any references to chase
8326 else return v_last->is_unfoldable(refch, exp_val);
8327 }
8328 case V_EXPR:
8329 // classify the unchecked ischosen() operation, if it was not done so far
8330 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8331 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8332 switch (u.expr.v_optype) {
8333 case OPTYPE_RND: // -
8334 case OPTYPE_COMP_MTC:
8335 case OPTYPE_COMP_SYSTEM:
8336 case OPTYPE_COMP_SELF:
8337 case OPTYPE_COMP_RUNNING_ANY:
8338 case OPTYPE_COMP_RUNNING_ALL:
8339 case OPTYPE_COMP_ALIVE_ANY:
8340 case OPTYPE_COMP_ALIVE_ALL:
8341 case OPTYPE_TMR_RUNNING_ANY:
8342 case OPTYPE_GETVERDICT:
8343 case OPTYPE_TESTCASENAME:
8344 case OPTYPE_PROF_RUNNING:
8345 case OPTYPE_RNDWITHVAL: // v1
8346 case OPTYPE_MATCH: // v1 t2
8347 case OPTYPE_UNDEF_RUNNING: // v1
8348 case OPTYPE_COMP_RUNNING:
8349 case OPTYPE_COMP_ALIVE:
8350 case OPTYPE_TMR_READ:
8351 case OPTYPE_TMR_RUNNING:
8352 case OPTYPE_ACTIVATE:
8353 case OPTYPE_ACTIVATE_REFD:
8354 case OPTYPE_EXECUTE: // r1 [v2]
8355 case OPTYPE_EXECUTE_REFD:
8356 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8357 case OPTYPE_ISCHOSEN:
8358 case OPTYPE_ISCHOSEN_T:
8359 case OPTYPE_SIZEOF: // ti1
8360 case OPTYPE_DECODE:
8361 case OPTYPE_ENCODE:
8362 case OPTYPE_OCT2UNICHAR:
8363 case OPTYPE_UNICHAR2OCT:
8364 case OPTYPE_ENCODE_BASE64:
8365 case OPTYPE_DECODE_BASE64:
8366 return true;
8367 case OPTYPE_COMP_NULL: // -
8368 return false;
8369 case OPTYPE_UNARYPLUS: // v1
8370 case OPTYPE_UNARYMINUS:
8371 case OPTYPE_NOT:
8372 case OPTYPE_NOT4B:
8373 case OPTYPE_BIT2HEX:
8374 case OPTYPE_BIT2INT:
8375 case OPTYPE_BIT2OCT:
8376 case OPTYPE_BIT2STR:
8377 case OPTYPE_CHAR2INT:
8378 case OPTYPE_CHAR2OCT:
8379 case OPTYPE_FLOAT2INT:
8380 case OPTYPE_FLOAT2STR:
8381 case OPTYPE_HEX2BIT:
8382 case OPTYPE_HEX2INT:
8383 case OPTYPE_HEX2OCT:
8384 case OPTYPE_HEX2STR:
8385 case OPTYPE_INT2CHAR:
8386 case OPTYPE_INT2FLOAT:
8387 case OPTYPE_INT2STR:
8388 case OPTYPE_INT2UNICHAR:
8389 case OPTYPE_OCT2BIT:
8390 case OPTYPE_OCT2CHAR:
8391 case OPTYPE_OCT2HEX:
8392 case OPTYPE_OCT2INT:
8393 case OPTYPE_OCT2STR:
8394 case OPTYPE_STR2BIT:
8395 case OPTYPE_STR2FLOAT:
8396 case OPTYPE_STR2HEX:
8397 case OPTYPE_STR2INT:
8398 case OPTYPE_STR2OCT:
8399 case OPTYPE_UNICHAR2INT:
8400 case OPTYPE_UNICHAR2CHAR:
8401 case OPTYPE_ENUM2INT:
8402 case OPTYPE_GET_STRINGENCODING:
8403 case OPTYPE_REMOVE_BOM:
8404 return u.expr.v1->is_unfoldable(refch, exp_val);
8405 case OPTYPE_ISBOUND: /*{
8406 //TODO once we have the time for it make isbound foldable.
8407 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8408 Template* temp = u.expr.ti1->get_Template();
8409 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8410 Value* specificValue = temp->get_specific_value();
8411 if (specificValue->get_valuetype() == Value::V_REFD) {
8412 //FIXME implement
8413 }
8414
8415 return specificValue->is_unfoldable(refch, exp_val);
8416 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8417 //FIXME implement
8418 }
8419 }*/
8420 return true;
8421 case OPTYPE_ISPRESENT:
8422 // TODO: "if you have motivation"
8423 return true;
8424 case OPTYPE_ISVALUE: // ti1
8425 // fallthrough
8426 case OPTYPE_LENGTHOF: // ti1
8427 return u.expr.ti1->get_DerivedRef() != 0
8428 || u.expr.ti1->get_Template()->get_templatetype()
8429 != Template::SPECIFIC_VALUE
8430 || u.expr.ti1->get_Template()->get_specific_value()
8431 ->is_unfoldable(refch, exp_val);
8432 case OPTYPE_ROTL:
8433 case OPTYPE_ROTR:
8434 case OPTYPE_CONCAT:
8435 if (!u.expr.v1->is_string_type(exp_val)) return true;
8436 // no break
8437 case OPTYPE_ADD: // v1 v2
8438 case OPTYPE_SUBTRACT:
8439 case OPTYPE_MULTIPLY:
8440 case OPTYPE_DIVIDE:
8441 case OPTYPE_MOD:
8442 case OPTYPE_REM:
8443 case OPTYPE_EQ:
8444 case OPTYPE_LT:
8445 case OPTYPE_GT:
8446 case OPTYPE_NE:
8447 case OPTYPE_GE:
8448 case OPTYPE_LE:
8449 case OPTYPE_XOR:
8450 case OPTYPE_AND4B:
8451 case OPTYPE_OR4B:
8452 case OPTYPE_XOR4B:
8453 case OPTYPE_SHL:
8454 case OPTYPE_SHR:
8455 case OPTYPE_INT2BIT:
8456 case OPTYPE_INT2HEX:
8457 case OPTYPE_INT2OCT:
8458 return u.expr.v1->is_unfoldable(refch, exp_val)
8459 || u.expr.v2->is_unfoldable(refch, exp_val);
8460 case OPTYPE_AND: // short-circuit evaluation
8461 return u.expr.v1->is_unfoldable(refch, exp_val)
8462 || (u.expr.v1->get_val_bool() &&
8463 u.expr.v2->is_unfoldable(refch, exp_val));
8464 case OPTYPE_OR: // short-circuit evaluation
8465 return u.expr.v1->is_unfoldable(refch, exp_val)
8466 || (!u.expr.v1->get_val_bool() &&
8467 u.expr.v2->is_unfoldable(refch, exp_val));
8468 case OPTYPE_SUBSTR:
8469 if (!u.expr.ti1->get_specific_value()) return true;
8470 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8471 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8472 || u.expr.v2->is_unfoldable(refch, exp_val)
8473 || u.expr.v3->is_unfoldable(refch, exp_val);
8474 case OPTYPE_REGEXP:
8475 if (!u.expr.ti1->get_specific_value() ||
8476 !u.expr.t2->get_specific_value()) return true;
8477 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8478 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8479 || u.expr.v3->is_unfoldable(refch, exp_val);
8480 case OPTYPE_DECOMP:
8481 return u.expr.v1->is_unfoldable(refch, exp_val)
8482 || u.expr.v2->is_unfoldable(refch, exp_val)
8483 || u.expr.v3->is_unfoldable(refch, exp_val);
8484 case OPTYPE_REPLACE: {
8485 if (!u.expr.ti1->get_specific_value() ||
8486 !u.expr.ti4->get_specific_value()) return true;
8487 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8488 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8489 || u.expr.v2->is_unfoldable(refch, exp_val)
8490 || u.expr.v3->is_unfoldable(refch, exp_val)
8491 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8492 }
8493 case OPTYPE_VALUEOF: // ti1
8494 /* \todo if you have motivation to implement the eval function
8495 for valueof()... */
8496 return true;
8497 case OPTYPE_ISCHOSEN_V:
8498 return u.expr.v1->is_unfoldable(refch, exp_val);
8499 case OPTYPE_LOG2STR:
8500 case OPTYPE_TTCN2STRING:
8501 return true;
8502 default:
8503 FATAL_ERROR("Value::is_unfoldable()");
8504 } // switch
8505 break; // should never get here
8506 case V_MACRO:
8507 switch (u.macro) {
8508 case MACRO_TESTCASEID:
8509 // this is known only at runtime
8510 return true;
8511 default:
8512 return false;
8513 }
8514 default:
8515 // all literal values are foldable
8516 return false;
8517 }
8518 }
8519
8520 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8521 size_t start_i, bool usedInIsbound,
8522 ReferenceChain *refch)
8523 {
8524 if (!subrefs) return this;
8525 Value *v = this;
8526 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8527 if (!v) break;
8528 v = v->get_value_refd_last(refch);
8529 switch(v->valuetype) {
8530 case V_ERROR:
8531 return v;
8532 case V_REFD:
8533 // unfoldable stuff
8534 return this;
8535 default:
8536 break;
8537 } // switch
8538 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8539 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8540 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8541 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8542 }
8543 return v;
8544 }
8545
8546 Value *Value::get_refd_field_value(const Identifier& field_id,
8547 bool usedInIsbound, const Location& loc)
8548 {
8549 if (valuetype == V_OMIT) {
8550 loc.error("Reference to field `%s' of omit value `%s'",
8551 field_id.get_dispname().c_str(), get_fullname().c_str());
8552 return 0;
8553 }
8554 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8555 Type *t = my_governor->get_type_refd_last();
8556 switch (t->get_typetype()) {
8557 case Type::T_ERROR:
8558 // remain silent
8559 return 0;
8560 case Type::T_CHOICE_A:
8561 case Type::T_CHOICE_T:
8562 case Type::T_OPENTYPE:
8563 case Type::T_ANYTYPE:
8564 if (!t->has_comp_withName(field_id)) {
8565 loc.error("Reference to non-existent union field `%s' in type `%s'",
8566 field_id.get_dispname().c_str(), t->get_typename().c_str());
8567 return 0;
8568 } else if (valuetype != V_CHOICE) {
8569 // remain silent, the error is already reported
8570 return 0;
8571 } else if (*u.choice.alt_name == field_id) {
8572 // everything is OK
8573 return u.choice.alt_value;
8574 }else {
8575 if (!usedInIsbound) {
8576 loc.error("Reference to inactive field `%s' in a value of union type "
8577 "`%s'. The active field is `%s'",
8578 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8579 u.choice.alt_name->get_dispname().c_str());
8580 }
8581 return 0;
8582 }
8583 case Type::T_SEQ_A:
8584 case Type::T_SEQ_T:
8585 if (!t->has_comp_withName(field_id)) {
8586 loc.error("Reference to non-existent record field `%s' in type `%s'",
8587 field_id.get_dispname().c_str(), t->get_typename().c_str());
8588 return 0;
8589 } else if (valuetype != V_SEQ) {
8590 // remain silent, the error has been already reported
8591 return 0;
8592 } else break;
8593 case Type::T_SET_A:
8594 case Type::T_SET_T:
8595 if (!t->has_comp_withName(field_id)) {
8596 loc.error("Reference to non-existent set field `%s' in type `%s'",
8597 field_id.get_dispname().c_str(), t->get_typename().c_str());
8598 return 0;
8599 } else if (valuetype != V_SET) {
8600 // remain silent, the error has been already reported
8601 return 0;
8602 } else break;
8603 default:
8604 loc.error("Invalid field reference `%s': type `%s' "
8605 "does not have fields", field_id.get_dispname().c_str(),
8606 t->get_typename().c_str());
8607 return 0;
8608 }
8609 // the common end for record & set types
8610 if (u.val_nvs->has_nv_withName(field_id)) {
8611 // everything is OK
8612 return u.val_nvs->get_nv_byName(field_id)->get_value();
8613 } else if (!is_asn1()) {
8614 if (!usedInIsbound) {
8615 loc.error("Reference to unbound field `%s'",
8616 field_id.get_dispname().c_str());
8617 // this is an error in TTCN-3, which has been already reported
8618 }
8619 return 0;
8620 } else {
8621 CompField *cf = t->get_comp_byName(field_id);
8622 if (cf->get_is_optional()) {
8623 // creating an explicit omit value
8624 Value *v = new Value(V_OMIT);
8625 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8626 v->set_my_scope(get_my_scope());
8627 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8628 return v;
8629 } else if (cf->has_default()) {
8630 // returning the component's default value
8631 return cf->get_defval();
8632 } else {
8633 // this is an error in ASN.1, which has been already reported
8634 return 0;
8635 }
8636 }
8637 }
8638
8639 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8640 ReferenceChain *refch)
8641 {
8642 Value *v_index = array_index->get_value_refd_last(refch);
8643 Int index = 0;
8644 bool index_available = false;
8645 if (!v_index->is_unfoldable()) {
8646 if (v_index->valuetype == V_INT) {
8647 index = v_index->get_val_Int()->get_val();
8648 index_available = true;
8649 } else {
8650 array_index->error("An integer value was expected as index");
8651 }
8652 }
8653 if (valuetype == V_OMIT) {
8654 array_index->error("Accessing an element with index of omit value `%s'",
8655 get_fullname().c_str());
8656 return 0;
8657 }
8658 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8659 Type *t = my_governor->get_type_refd_last();
8660 switch (t->get_typetype()) {
8661 case Type::T_ERROR:
8662 // remain silent
8663 return 0;
8664 case Type::T_SEQOF:
8665 if (index_available) {
8666 if (index < 0) {
8667 array_index->error("A non-negative integer value was expected "
8668 "instead of %s for indexing a value of `record "
8669 "of' type `%s'", Int2string(index).c_str(),
8670 t->get_typename().c_str());
8671 return 0;
8672 }
8673 switch (valuetype) {
8674 case V_SEQOF:
8675 if (!is_indexed()) {
8676 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8677 if (!usedInIsbound) {
8678 array_index->error("Index overflow in a value of `record of' "
8679 "type `%s': the index is %s, but the value "
8680 "has only %lu elements",
8681 t->get_typename().c_str(),
8682 Int2string(index).c_str(),
8683 (unsigned long)u.val_vs->get_nof_vs());
8684 }
8685 return 0;
8686 } else {
8687 Value* temp = u.val_vs->get_v_byIndex(index);
8688 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8689 temp->error("Not used symbol is not allowed in this context");
8690 return u.val_vs->get_v_byIndex(index);
8691 }
8692 } else {
8693 // Search the appropriate constant index.
8694 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8695 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8696 ->get_value_refd_last();
8697 if (iv_index->get_valuetype() != V_INT) continue;
8698 if (iv_index->get_val_Int()->get_val() == index)
8699 return u.val_vs->get_iv_byIndex(i)->get_value();
8700 }
8701 return 0;
8702 }
8703 break;
8704 default:
8705 // remain silent, the error has been already reported
8706 return 0;
8707 }
8708 } else {
8709 // the error has been reported above
8710 return 0;
8711 }
8712 case Type::T_SETOF:
8713 if (index_available) {
8714 if (index < 0) {
8715 array_index->error("A non-negative integer value was expected "
8716 "instead of %s for indexing a value of `set of' type `%s'",
8717 Int2string(index).c_str(), t->get_typename().c_str());
8718 return 0;
8719 }
8720 switch (valuetype) {
8721 case V_SETOF:
8722 if (!is_indexed()) {
8723 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8724 if (!usedInIsbound) {
8725 array_index->error("Index overflow in a value of `set of' type "
8726 "`%s': the index is %s, but the value has "
8727 "only %lu elements",
8728 t->get_typename().c_str(),
8729 Int2string(index).c_str(),
8730 (unsigned long)u.val_vs->get_nof_vs());
8731 }
8732 return 0;
8733 } else {
8734 Value* temp = u.val_vs->get_v_byIndex(index);
8735 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8736 temp->error("Not used symbol is not allowed in this context");
8737 return temp;
8738 }
8739 } else {
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(i)->get_value();
8746 }
8747 return 0;
8748 }
8749 break;
8750 default:
8751 // remain silent, the error has been already reported
8752 return 0;
8753 }
8754 } else {
8755 // the error has been reported above
8756 return 0;
8757 }
8758 case Type::T_ARRAY:
8759 if (index_available) {
8760 Ttcn::ArrayDimension *dim = t->get_dimension();
8761 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8762 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8763 // perform the index transformation
8764 index -= dim->get_offset();
8765 if (!is_indexed()) {
8766 // check for index underflow/overflow or too few elements in the
8767 // value
8768 if (index < 0 ||
8769 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8770 return 0;
8771 else return u.val_vs->get_v_byIndex(index);
8772 } else {
8773 if (index < 0) return 0;
8774 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8775 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8776 ->get_value_refd_last();
8777 if (iv_index->get_valuetype() != V_INT) continue;
8778 if (iv_index->get_val_Int()->get_val() == index)
8779 return u.val_vs->get_iv_byIndex(index)->get_value();
8780 }
8781 return 0;
8782 }
8783 } else {
8784 // remain silent, the error has been already reported
8785 return 0;
8786 }
8787 } else {
8788 // the error has been reported above
8789 return 0;
8790 }
8791 case Type::T_BSTR:
8792 case Type::T_BSTR_A:
8793 case Type::T_HSTR:
8794 case Type::T_OSTR:
8795 case Type::T_CSTR:
8796 case Type::T_USTR:
8797 case Type::T_UTF8STRING:
8798 case Type::T_NUMERICSTRING:
8799 case Type::T_PRINTABLESTRING:
8800 case Type::T_TELETEXSTRING:
8801 case Type::T_VIDEOTEXSTRING:
8802 case Type::T_IA5STRING:
8803 case Type::T_GRAPHICSTRING:
8804 case Type::T_VISIBLESTRING:
8805 case Type::T_GENERALSTRING:
8806 case Type::T_UNIVERSALSTRING:
8807 case Type::T_BMPSTRING:
8808 case Type::T_UTCTIME:
8809 case Type::T_GENERALIZEDTIME:
8810 case Type::T_OBJECTDESCRIPTOR:
8811 if (index_available) return get_string_element(index, *array_index);
8812 else return 0;
8813 default:
8814 array_index->error("Invalid array element reference: type `%s' cannot "
8815 "be indexed", t->get_typename().c_str());
8816 return 0;
8817 }
8818 }
8819
8820 Value *Value::get_string_element(const Int& index, const Location& loc)
8821 {
8822 if (index < 0) {
8823 loc.error("A non-negative integer value was expected instead of %s "
8824 "for indexing a string element", Int2string(index).c_str());
8825 return 0;
8826 }
8827 size_t string_length;
8828 switch (valuetype) {
8829 case V_BSTR:
8830 case V_HSTR:
8831 case V_CSTR:
8832 case V_ISO2022STR:
8833 string_length = u.str.val_str->size();
8834 break;
8835 case V_OSTR:
8836 string_length = u.str.val_str->size() / 2;
8837 break;
8838 case V_USTR:
8839 string_length = u.ustr.val_ustr->size();
8840 break;
8841 default:
8842 // remain silent, the error has been already reported
8843 return 0;
8844 }
8845 if (index >= static_cast<Int>(string_length)) {
8846 loc.error("Index overflow when accessing a string element: "
8847 "the index is %s, but the string has only %lu elements",
8848 Int2string(index).c_str(), (unsigned long) string_length);
8849 return 0;
8850 }
8851 switch (valuetype) {
8852 case V_BSTR:
8853 case V_HSTR:
8854 case V_CSTR:
8855 case V_ISO2022STR:
8856 if (u.str.str_elements && u.str.str_elements->has_key(index))
8857 return (*u.str.str_elements)[index];
8858 else {
8859 Value *t_val = new Value(valuetype,
8860 new string(u.str.val_str->substr(index, 1)));
8861 add_string_element(index, t_val, u.str.str_elements);
8862 return t_val;
8863 }
8864 case V_OSTR:
8865 if (u.str.str_elements && u.str.str_elements->has_key(index))
8866 return (*u.str.str_elements)[index];
8867 else {
8868 Value *t_val = new Value(V_OSTR,
8869 new string(u.str.val_str->substr(2 * index, 2)));
8870 add_string_element(index, t_val, u.str.str_elements);
8871 return t_val;
8872 }
8873 case V_USTR:
8874 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
8875 return (*u.ustr.ustr_elements)[index];
8876 else {
8877 Value *t_val = new Value(V_USTR,
8878 new ustring(u.ustr.val_ustr->substr(index, 1)));
8879 add_string_element(index, t_val, u.ustr.ustr_elements);
8880 return t_val;
8881 }
8882 default:
8883 FATAL_ERROR("Value::get_string_element()");
8884 return 0;
8885 }
8886 }
8887
8888 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
8889 Type::expected_value_t exp_val)
8890 {
8891 set_lowerid_to_ref();
8892 Type::typetype_t r_tt = get_expr_returntype(exp_val);
8893 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
8894 if (error_flag)
8895 error("A value or expression of type %s was expected", type_name);
8896 if (valuetype == V_REFD) {
8897 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
8898 t_chk->chk_this_refd_value(this, 0, exp_val);
8899 }
8900 get_value_refd_last(0, exp_val);
8901 if (error_flag) set_valuetype(V_ERROR);
8902 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
8903 }
8904
8905 int Value::is_parsed_infinity()
8906 {
8907 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
8908 return 1;
8909 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
8910 (u.expr.v1->get_valuetype()==V_REAL) &&
8911 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
8912 return -1;
8913 return 0;
8914 }
8915
8916 bool Value::get_val_bool()
8917 {
8918 Value *v;
8919 if (valuetype == V_REFD) v = get_value_refd_last();
8920 else v = this;
8921 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
8922 return v->u.val_bool;
8923 }
8924
8925 int_val_t* Value::get_val_Int()
8926 {
8927 Value *v;
8928 if (valuetype == V_REFD) v = get_value_refd_last();
8929 else v = this;
8930 switch (v->valuetype) {
8931 case V_INT:
8932 break;
8933 case V_UNDEF_LOWERID:
8934 FATAL_ERROR("Cannot use this value (here) as an integer: " \
8935 "`%s'", (*u.val_id).get_dispname().c_str());
8936 default:
8937 FATAL_ERROR("Value::get_val_Int()");
8938 } // switch
8939 return v->u.val_Int;
8940 }
8941
8942 const Identifier* Value::get_val_id()
8943 {
8944 switch(valuetype) {
8945 case V_NAMEDINT:
8946 case V_ENUM:
8947 case V_UNDEF_LOWERID:
8948 return u.val_id;
8949 default:
8950 FATAL_ERROR("Value::get_val_id()");
8951 return 0;
8952 } // switch
8953 }
8954
8955 const ttcn3float& Value::get_val_Real()
8956 {
8957 Value *v;
8958 if (valuetype == V_REFD) v = get_value_refd_last();
8959 else v = this;
8960 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
8961 return v->u.val_Real;
8962 }
8963
8964 string Value::get_val_str()
8965 {
8966 Value *v = get_value_refd_last();
8967 switch (v->valuetype) {
8968 case V_BSTR:
8969 case V_HSTR:
8970 case V_OSTR:
8971 case V_CSTR:
8972 return *v->u.str.val_str;
8973 case V_CHARSYMS:
8974 return v->u.char_syms->get_string();
8975 case V_USTR:
8976 error("Cannot use ISO-10646 string value in string context");
8977 return string();
8978 case V_ISO2022STR:
8979 error("Cannot use ISO-2022 string value in string context");
8980 // no break
8981 case V_ERROR:
8982 return string();
8983 default:
8984 error("Cannot use this value in charstring value context");
8985 return string();
8986 } // switch
8987 }
8988
8989 ustring Value::get_val_ustr()
8990 {
8991 Value *v = get_value_refd_last();
8992 switch (v->valuetype) {
8993 case V_CSTR:
8994 return ustring(*v->u.str.val_str);
8995 case V_USTR:
8996 return *v->u.ustr.val_ustr;
8997 case V_CHARSYMS:
8998 return v->u.char_syms->get_ustring();
8999 case V_ISO2022STR:
9000 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9001 // no break
9002 case V_ERROR:
9003 return ustring();
9004 default:
9005 error("Cannot use this value in ISO-10646 string context");
9006 return ustring();
9007 } // switch
9008 }
9009
9010 string Value::get_val_iso2022str()
9011 {
9012 Value *v = get_value_refd_last();
9013 switch (v->valuetype) {
9014 case V_CSTR:
9015 case V_ISO2022STR:
9016 return *v->u.str.val_str;
9017 case V_CHARSYMS:
9018 return v->u.char_syms->get_iso2022string();
9019 case V_USTR:
9020 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9021 // no break
9022 case V_ERROR:
9023 return string();
9024 default:
9025 error("Cannot use this value in ISO-2022 string context");
9026 return string();
9027 } // switch
9028 }
9029
9030 size_t Value::get_val_strlen()
9031 {
9032 Value *v = get_value_refd_last();
9033 switch (v->valuetype) {
9034 case V_BSTR:
9035 case V_HSTR:
9036 case V_CSTR:
9037 case V_ISO2022STR:
9038 return v->u.str.val_str->size();
9039 case V_OSTR:
9040 return v->u.str.val_str->size()/2;
9041 case V_CHARSYMS:
9042 return v->u.char_syms->get_len();
9043 case V_USTR:
9044 return v->u.ustr.val_ustr->size();
9045 case V_ERROR:
9046 return 0;
9047 default:
9048 error("Cannot use this value in string value context");
9049 return 0;
9050 } // switch
9051 }
9052
9053 Value::verdict_t Value::get_val_verdict()
9054 {
9055 switch(valuetype) {
9056 case V_VERDICT:
9057 return u.verdict;
9058 default:
9059 FATAL_ERROR("Value::get_val_verdict()");
9060 return u.verdict;
9061 } // switch
9062 }
9063
9064 size_t Value::get_nof_comps()
9065 {
9066 switch (valuetype) {
9067 case V_OID:
9068 case V_ROID:
9069 chk();
9070 return u.oid_comps->size();
9071 case V_SEQOF:
9072 case V_SETOF:
9073 case V_ARRAY:
9074 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9075 else return u.val_vs->get_nof_vs();
9076 case V_SEQ:
9077 case V_SET:
9078 return u.val_nvs->get_nof_nvs();
9079 case V_BSTR:
9080 case V_HSTR:
9081 case V_CSTR:
9082 case V_ISO2022STR:
9083 return u.str.val_str->size();
9084 case V_OSTR:
9085 return u.str.val_str->size()/2;
9086 case V_USTR:
9087 return u.ustr.val_ustr->size();
9088 default:
9089 FATAL_ERROR("Value::get_nof_comps()");
9090 return 0;
9091 } // switch
9092 }
9093
9094 bool Value::is_indexed() const
9095 {
9096 switch (valuetype) {
9097 case V_SEQOF:
9098 case V_SETOF:
9099 case V_ARRAY:
9100 // Applicable only for list-types. Assigning a record/SEQUENCE or
9101 // set/SET with indexed notation is not supported.
9102 return u.val_vs->is_indexed();
9103 default:
9104 FATAL_ERROR("Value::is_indexed()");
9105 break;
9106 }
9107 return false;
9108 }
9109
9110 const Identifier& Value::get_alt_name()
9111 {
9112 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9113 return *u.choice.alt_name;
9114 }
9115
9116 Value *Value::get_alt_value()
9117 {
9118 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9119 return u.choice.alt_value;
9120 }
9121
9122 void Value::set_alt_name_to_lowercase()
9123 {
9124 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9125 string new_name = u.choice.alt_name->get_name();
9126 if (isupper(new_name[0])) {
9127 new_name[0] = tolower(new_name[0]);
9128 if (new_name[new_name.size() - 1] == '_') {
9129 // an underscore is inserted at the end of the alternative name if it's
9130 // a basic type's name (since it would conflict with the class generated
9131 // for that type)
9132 // remove the underscore, it won't conflict with anything if its name
9133 // starts with a lowercase letter
9134 new_name.replace(new_name.size() - 1, 1, "");
9135 }
9136 delete u.choice.alt_name;
9137 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9138 }
9139 }
9140
9141 bool Value::has_oid_error()
9142 {
9143 Value *v;
9144 if (valuetype == V_REFD) v = get_value_refd_last();
9145 else v = this;
9146 switch (valuetype) {
9147 case V_OID:
9148 case V_ROID:
9149 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9150 if ((*v->u.oid_comps)[i]->has_error()) return true;
9151 return false;
9152 default:
9153 return true;
9154 }
9155 }
9156
9157 bool Value::get_oid_comps(vector<string>& comps)
9158 {
9159 bool ret_val = true;
9160 Value *v = this;
9161 switch (valuetype) {
9162 case V_REFD:
9163 v = get_value_refd_last();
9164 // no break
9165 case V_OID:
9166 case V_ROID:
9167 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9168 (*v->u.oid_comps)[i]->get_comps(comps);
9169 if ((*v->u.oid_comps)[i]->is_variable()) {
9170 // not all components can be calculated in compile-time
9171 ret_val = false;
9172 }
9173 }
9174 break;
9175 default:
9176 FATAL_ERROR("Value::get_oid_comps()");
9177 }
9178 return ret_val;
9179 }
9180
9181 void Value::add_se_comp(NamedValue* nv) {
9182 switch (valuetype) {
9183 case V_SEQ:
9184 case V_SET:
9185 if (!u.val_nvs)
9186 u.val_nvs = new NamedValues();
9187 u.val_nvs->add_nv(nv);
9188 break;
9189 default:
9190 FATAL_ERROR("Value::add_se_comp()");
9191 }
9192 }
9193
9194 NamedValue* Value::get_se_comp_byIndex(size_t n)
9195 {
9196 switch(valuetype) {
9197 case V_SEQ:
9198 case V_SET:
9199 return u.val_nvs->get_nv_byIndex(n);
9200 default:
9201 FATAL_ERROR("Value::get_se_comp_byIndex()");
9202 return 0;
9203 } // switch
9204 }
9205
9206 Value *Value::get_comp_byIndex(size_t n)
9207 {
9208 switch (valuetype) {
9209 case V_SEQOF:
9210 case V_SETOF:
9211 case V_ARRAY:
9212 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9213 return u.val_vs->get_iv_byIndex(n)->get_value();
9214 default:
9215 FATAL_ERROR("Value::get_comp_byIndex()");
9216 return 0;
9217 } // switch
9218 }
9219
9220 Value *Value::get_index_byIndex(size_t n)
9221 {
9222 switch (valuetype) {
9223 case V_SEQOF:
9224 case V_SETOF:
9225 case V_ARRAY:
9226 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9227 return u.val_vs->get_iv_byIndex(n)->get_index();
9228 default:
9229 FATAL_ERROR("Value::get_index_byIndex()");
9230 return 0;
9231 } // switch
9232 }
9233
9234 bool Value::has_comp_withName(const Identifier& p_name)
9235 {
9236 switch(valuetype) {
9237 case V_SEQ:
9238 case V_SET:
9239 return u.val_nvs->has_nv_withName(p_name);
9240 case V_CHOICE:
9241 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9242 default:
9243 FATAL_ERROR("Value::get_has_comp_withName()");
9244 return false;
9245 } // switch
9246 }
9247
9248 bool Value::field_is_chosen(const Identifier& p_name)
9249 {
9250 Value *v=get_value_refd_last();
9251 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9252 return *v->u.choice.alt_name==p_name;
9253 }
9254
9255 bool Value::field_is_present(const Identifier& p_name)
9256 {
9257 Value *v=get_value_refd_last();
9258 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9259 FATAL_ERROR("Value::field_is_present()");
9260 return v->u.val_nvs->has_nv_withName(p_name)
9261 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9262 ->get_value_refd_last()->valuetype != V_OMIT;
9263 }
9264
9265 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9266 {
9267 switch(valuetype) {
9268 case V_SEQ:
9269 case V_SET:
9270 return u.val_nvs->get_nv_byName(p_name);
9271 default:
9272 FATAL_ERROR("Value::get_se_comp_byName()");
9273 return 0;
9274 } // switch
9275 }
9276
9277 Value* Value::get_comp_value_byName(const Identifier& p_name)
9278 {
9279 switch(valuetype) {
9280 case V_SEQ:
9281 case V_SET:
9282 return u.val_nvs->get_nv_byName(p_name)->get_value();
9283 case V_CHOICE:
9284 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9285 return u.choice.alt_value;
9286 else
9287 return NULL;
9288 default:
9289 FATAL_ERROR("Value::get_se_comp_byName()");
9290 return 0;
9291 } // switch
9292 }
9293
9294 void Value::chk_dupl_id()
9295 {
9296 switch(valuetype) {
9297 case V_SEQ:
9298 case V_SET:
9299 u.val_nvs->chk_dupl_id();
9300 break;
9301 default:
9302 FATAL_ERROR("Value::chk_dupl_id()");
9303 } // switch
9304 }
9305
9306 size_t Value::get_nof_ids() const
9307 {
9308 switch(valuetype) {
9309 case V_NAMEDBITS:
9310 return u.ids->size();
9311 break;
9312 default:
9313 FATAL_ERROR("Value::get_nof_ids()");
9314 return 0;
9315 } // switch
9316 }
9317
9318 Identifier* Value::get_id_byIndex(size_t p_i)
9319 {
9320 switch(valuetype) {
9321 case V_NAMEDBITS:
9322 return u.ids->get_nth_elem(p_i);
9323 break;
9324 default:
9325 FATAL_ERROR("Value::get_id_byIndex()");
9326 return 0;
9327 } // switch
9328 }
9329
9330 bool Value::has_id(const Identifier& p_id)
9331 {
9332 switch(valuetype) {
9333 case V_NAMEDBITS:
9334 return u.ids->has_key(p_id.get_name());
9335 break;
9336 default:
9337 FATAL_ERROR("Value::has_id()");
9338 return false;
9339 } // switch
9340 }
9341
9342 Reference *Value::get_reference() const
9343 {
9344 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9345 return u.ref.ref;
9346 }
9347
9348 Reference *Value::get_refered() const
9349 {
9350 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9351 return u.refered;
9352 }
9353
9354 Common::Assignment *Value::get_refd_fat() const
9355 {
9356 switch(valuetype){
9357 case V_FUNCTION:
9358 case V_ALTSTEP:
9359 case V_TESTCASE:
9360 return u.refd_fat;
9361 default:
9362 FATAL_ERROR("Value::get_refd_fat()");
9363 }
9364 }
9365
9366 Ttcn::Reference* Value::steal_ttcn_ref()
9367 {
9368 Ttcn::Reference *ret_val =
9369 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9370 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9371 return ret_val;
9372 }
9373
9374 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9375 {
9376 Ttcn::Ref_base *t_ref;
9377 if(valuetype==V_REFD) {
9378 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9379 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9380 u.ref.ref=0;
9381 }
9382 else if(valuetype==V_UNDEF_LOWERID) {
9383 t_ref=new Ttcn::Reference(u.val_id);
9384 t_ref->set_location(*this);
9385 t_ref->set_fullname(get_fullname());
9386 t_ref->set_my_scope(get_my_scope());
9387 u.val_id=0;
9388 }
9389 else {
9390 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9391 t_ref = 0;
9392 }
9393 set_valuetype(V_ERROR);
9394 return t_ref;
9395 }
9396
9397 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9398 Ttcn::ActualParList*& p_ap)
9399 {
9400 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9401 p_v = u.invoke.v;
9402 u.invoke.v = 0;
9403 p_ti = u.invoke.t_list;
9404 u.invoke.t_list = 0;
9405 p_ap = u.invoke.ap_list;
9406 u.invoke.ap_list = 0;
9407 set_valuetype(V_ERROR);
9408 }
9409
9410 Common::Assignment* Value::get_refd_assignment()
9411 {
9412 switch(valuetype) {
9413 case V_FUNCTION:
9414 case V_ALTSTEP:
9415 case V_TESTCASE:
9416 return u.refd_fat;
9417 break;
9418 default:
9419 FATAL_ERROR("Value::get_refd_assignment()");
9420 return 0;
9421 }
9422 }
9423
9424 void Value::chk()
9425 {
9426 if(checked) return;
9427 switch(valuetype) {
9428 case V_OID: {
9429 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9430 " components");
9431 chk_OID(refch);
9432 break; }
9433 case V_ROID: {
9434 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9435 chk_ROID(refch);
9436 break; }
9437 default:
9438 break;
9439 } // switch
9440 checked=true;
9441 }
9442
9443 void Value::chk_OID(ReferenceChain& refch)
9444 {
9445 if (checked) return;
9446 if (valuetype != V_OID || u.oid_comps->size() < 1)
9447 FATAL_ERROR("Value::chk_OID()");
9448 if (!refch.add(get_fullname())) {
9449 checked = true;
9450 return;
9451 }
9452 OID_comp::oidstate_t state = OID_comp::START;
9453 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9454 refch.mark_state();
9455 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9456 refch.prev_state();
9457 }
9458 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9459 error("An OBJECT IDENTIFIER value must have at least "
9460 "two components"); // X.680 (07/2002) 31.10
9461 }
9462
9463 void Value::chk_ROID(ReferenceChain& refch)
9464 {
9465 if (checked) return;
9466 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9467 FATAL_ERROR("Value::chk_ROID()");
9468 if (!refch.add(get_fullname())) {
9469 checked = true;
9470 return;
9471 }
9472 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9473 refch.mark_state();
9474 (*u.oid_comps)[i]->chk_ROID(refch, i);
9475 refch.prev_state();
9476 }
9477 }
9478
9479 void Value::chk_recursions(ReferenceChain& refch)
9480 {
9481 if (recurs_checked) return;
9482 Value *v = get_value_refd_last();
9483 if (refch.add(v->get_fullname())) {
9484 switch (v->valuetype) {
9485 case V_CHOICE:
9486 v->u.choice.alt_value->chk_recursions(refch);
9487 break;
9488 case V_SEQOF:
9489 case V_SETOF:
9490 case V_ARRAY:
9491 if (!v->is_indexed()) {
9492 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9493 refch.mark_state();
9494 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9495 refch.prev_state();
9496 }
9497 } else {
9498 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9499 refch.mark_state();
9500 v->u.val_vs->get_iv_byIndex(i)->get_value()
9501 ->chk_recursions(refch);
9502 refch.prev_state();
9503 }
9504 }
9505 break;
9506 case V_SEQ:
9507 case V_SET:
9508 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9509 refch.mark_state();
9510 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9511 refch.prev_state();
9512 }
9513 break;
9514 case V_EXPR:
9515 chk_recursions_expr(refch);
9516 break;
9517 default:
9518 break;
9519 }
9520 if (v->err_descr) { // FIXME: make this work
9521 v->err_descr->chk_recursions(refch);
9522 }
9523 }
9524 recurs_checked = true;
9525 }
9526
9527 void Value::chk_recursions_expr(ReferenceChain& refch)
9528 {
9529 // first classify the unchecked ischosen() operation
9530 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9531 switch (u.expr.v_optype) {
9532 case OPTYPE_UNARYPLUS: // v1
9533 case OPTYPE_UNARYMINUS:
9534 case OPTYPE_NOT:
9535 case OPTYPE_NOT4B:
9536 case OPTYPE_BIT2HEX:
9537 case OPTYPE_BIT2INT:
9538 case OPTYPE_BIT2OCT:
9539 case OPTYPE_BIT2STR:
9540 case OPTYPE_CHAR2INT:
9541 case OPTYPE_CHAR2OCT:
9542 case OPTYPE_FLOAT2INT:
9543 case OPTYPE_FLOAT2STR:
9544 case OPTYPE_HEX2BIT:
9545 case OPTYPE_HEX2INT:
9546 case OPTYPE_HEX2OCT:
9547 case OPTYPE_HEX2STR:
9548 case OPTYPE_INT2CHAR:
9549 case OPTYPE_INT2FLOAT:
9550 case OPTYPE_INT2STR:
9551 case OPTYPE_INT2UNICHAR:
9552 case OPTYPE_OCT2BIT:
9553 case OPTYPE_OCT2CHAR:
9554 case OPTYPE_OCT2HEX:
9555 case OPTYPE_OCT2INT:
9556 case OPTYPE_OCT2STR:
9557 case OPTYPE_STR2BIT:
9558 case OPTYPE_STR2FLOAT:
9559 case OPTYPE_STR2HEX:
9560 case OPTYPE_STR2INT:
9561 case OPTYPE_STR2OCT:
9562 case OPTYPE_UNICHAR2INT:
9563 case OPTYPE_ENUM2INT:
9564 case OPTYPE_UNICHAR2CHAR:
9565 case OPTYPE_RNDWITHVAL:
9566 case OPTYPE_ISCHOSEN_V:
9567 case OPTYPE_GET_STRINGENCODING:
9568 case OPTYPE_REMOVE_BOM:
9569 case OPTYPE_DECODE_BASE64:
9570 refch.mark_state();
9571 u.expr.v1->chk_recursions(refch);
9572 refch.prev_state();
9573 break;
9574 case OPTYPE_ISCHOSEN_T:
9575 refch.mark_state();
9576 u.expr.t1->chk_recursions(refch);
9577 refch.prev_state();
9578 break;
9579 case OPTYPE_ADD: // v1 v2
9580 case OPTYPE_SUBTRACT:
9581 case OPTYPE_MULTIPLY:
9582 case OPTYPE_DIVIDE:
9583 case OPTYPE_MOD:
9584 case OPTYPE_REM:
9585 case OPTYPE_CONCAT:
9586 case OPTYPE_EQ:
9587 case OPTYPE_LT:
9588 case OPTYPE_GT:
9589 case OPTYPE_NE:
9590 case OPTYPE_GE:
9591 case OPTYPE_LE:
9592 case OPTYPE_AND:
9593 case OPTYPE_OR:
9594 case OPTYPE_XOR:
9595 case OPTYPE_AND4B:
9596 case OPTYPE_OR4B:
9597 case OPTYPE_XOR4B:
9598 case OPTYPE_SHL:
9599 case OPTYPE_SHR:
9600 case OPTYPE_ROTL:
9601 case OPTYPE_ROTR:
9602 case OPTYPE_INT2BIT:
9603 case OPTYPE_INT2HEX:
9604 case OPTYPE_INT2OCT:
9605 refch.mark_state();
9606 u.expr.v1->chk_recursions(refch);
9607 refch.prev_state();
9608 refch.mark_state();
9609 u.expr.v2->chk_recursions(refch);
9610 refch.prev_state();
9611 break;
9612 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9613 case OPTYPE_OCT2UNICHAR:
9614 case OPTYPE_ENCODE_BASE64:
9615 refch.mark_state();
9616 u.expr.v1->chk_recursions(refch);
9617 refch.prev_state();
9618 if (u.expr.v2) {
9619 refch.mark_state();
9620 u.expr.v2->chk_recursions(refch);
9621 refch.prev_state();
9622 }
9623 break;
9624 case OPTYPE_DECODE:
9625 chk_recursions_expr_decode(u.expr.r1, refch);
9626 chk_recursions_expr_decode(u.expr.r2, refch);
9627 break;
9628 case OPTYPE_SUBSTR:
9629 refch.mark_state();
9630 u.expr.ti1->chk_recursions(refch);
9631 refch.prev_state();
9632 refch.mark_state();
9633 u.expr.v2->chk_recursions(refch);
9634 refch.prev_state();
9635 refch.mark_state();
9636 u.expr.v3->chk_recursions(refch);
9637 refch.prev_state();
9638 break;
9639 case OPTYPE_REGEXP:
9640 refch.mark_state();
9641 u.expr.ti1->chk_recursions(refch);
9642 refch.prev_state();
9643 refch.mark_state();
9644 u.expr.t2->chk_recursions(refch);
9645 refch.prev_state();
9646 refch.mark_state();
9647 u.expr.v3->chk_recursions(refch);
9648 refch.prev_state();
9649 break;
9650 case OPTYPE_DECOMP: // v1 v2 v3
9651 refch.mark_state();
9652 u.expr.v1->chk_recursions(refch);
9653 refch.prev_state();
9654 refch.mark_state();
9655 u.expr.v2->chk_recursions(refch);
9656 refch.prev_state();
9657 refch.mark_state();
9658 u.expr.v3->chk_recursions(refch);
9659 refch.prev_state();
9660 break;
9661 case OPTYPE_REPLACE:
9662 refch.mark_state();
9663 u.expr.ti1->chk_recursions(refch);
9664 refch.prev_state();
9665 refch.mark_state();
9666 u.expr.v2->chk_recursions(refch);
9667 refch.prev_state();
9668 refch.mark_state();
9669 u.expr.v3->chk_recursions(refch);
9670 refch.prev_state();
9671 refch.mark_state();
9672 u.expr.ti4->chk_recursions(refch);
9673 refch.prev_state();
9674 break;
9675 case OPTYPE_LENGTHOF: // ti1
9676 case OPTYPE_SIZEOF: // ti1
9677 case OPTYPE_VALUEOF: // ti1
9678 case OPTYPE_ENCODE:
9679 case OPTYPE_ISPRESENT:
9680 case OPTYPE_TTCN2STRING:
9681 refch.mark_state();
9682 u.expr.ti1->chk_recursions(refch);
9683 refch.prev_state();
9684 break;
9685 case OPTYPE_MATCH: // v1 t2
9686 refch.mark_state();
9687 u.expr.v1->chk_recursions(refch);
9688 refch.prev_state();
9689 refch.mark_state();
9690 u.expr.t2->chk_recursions(refch);
9691 refch.prev_state();
9692 break;
9693 case OPTYPE_LOG2STR:
9694 u.expr.logargs->chk_recursions(refch);
9695 break;
9696 default:
9697 break;
9698 } // switch
9699 }
9700
9701 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9702 ReferenceChain& refch) {
9703 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9704 Assignment *ass = ref->get_refd_assignment();
9705 if (!ass) {
9706 set_valuetype(V_ERROR);
9707 return;
9708 }
9709 switch (ass->get_asstype()) {
9710 case Assignment::A_CONST:
9711 case Assignment::A_EXT_CONST:
9712 case Assignment::A_MODULEPAR:
9713 case Assignment::A_VAR:
9714 case Assignment::A_PAR_VAL_IN:
9715 case Assignment::A_PAR_VAL_OUT:
9716 case Assignment::A_PAR_VAL_INOUT: {
9717 Value* v = new Value(V_REFD, ref);
9718 v->set_location(*ref);
9719 v->set_my_scope(get_my_scope());
9720 v->set_fullname(get_fullname()+".<operand>");
9721 refch.mark_state();
9722 v->chk_recursions(refch);
9723 refch.prev_state();
9724 delete v;
9725 break; }
9726 case Assignment::A_MODULEPAR_TEMP:
9727 case Assignment::A_TEMPLATE:
9728 case Assignment::A_VAR_TEMPLATE:
9729 case Assignment::A_PAR_TEMPL_IN:
9730 case Assignment::A_PAR_TEMPL_OUT:
9731 case Assignment::A_PAR_TEMPL_INOUT: {
9732 Template* t = new Template(ref->clone());
9733 t->set_location(*ref);
9734 t->set_my_scope(get_my_scope());
9735 t->set_fullname(get_fullname()+".<operand>");
9736 refch.mark_state();
9737 t->chk_recursions(refch);
9738 refch.prev_state();
9739 delete t;
9740 break; }
9741 default:
9742 // remain silent, the error has been already reported
9743 set_valuetype(V_ERROR);
9744 break;
9745 } // switch
9746 }
9747
9748 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9749 {
9750 bool self_ref = false;
9751 switch (t->get_templatetype()) {
9752 case Ttcn::Template::SPECIFIC_VALUE: {
9753 Value *v = t->get_specific_value();
9754 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9755 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9756 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9757 break; }
9758 case Ttcn::Template::TEMPLATE_REFD: {
9759 Ttcn::Ref_base *refb = t->get_reference();
9760 Common::Assignment *ass = refb->get_refd_assignment();
9761 self_ref |= (ass == lhs);
9762 break; }
9763 case Ttcn::Template::ALL_FROM:
9764 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9765 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9766 break;
9767 case Ttcn::Template::TEMPLATE_LIST:
9768 case Ttcn::Template::SUPERSET_MATCH:
9769 case Ttcn::Template::SUBSET_MATCH:
9770 case Ttcn::Template::PERMUTATION_MATCH:
9771 case Ttcn::Template::COMPLEMENTED_LIST:
9772 case Ttcn::Template::VALUE_LIST: {
9773 size_t num = t->get_nof_comps();
9774 for (size_t i = 0; i < num; ++i) {
9775 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9776 }
9777 break; }
9778 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9779 // case Ttcn::Template::TEMPLATE_LIST: {
9780 // size_t num = t->get_nof_listitems();
9781 // for (size_t i=0; i < num; ++i) {
9782 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9783 // }
9784 // break; }
9785 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9786 size_t nnt = t->get_nof_comps();
9787 for (size_t i=0; i < nnt; ++i) {
9788 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9789 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9790 }
9791 break; }
9792 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9793 size_t nnt = t->get_nof_comps();
9794 for (size_t i=0; i < nnt; ++i) {
9795 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9796 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9797 }
9798 break; }
9799 case Ttcn::Template::VALUE_RANGE: {
9800 Ttcn::ValueRange *vr = t->get_value_range();
9801 Common::Value *v = vr->get_min_v();
9802 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9803 v = vr->get_max_v();
9804 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9805 break; }
9806 case Ttcn::Template::CSTR_PATTERN:
9807 case Ttcn::Template::USTR_PATTERN: {
9808 Ttcn::PatternString *ps = t->get_cstr_pattern();
9809 self_ref |= ps->chk_self_ref(lhs);
9810 break; }
9811 case Ttcn::Template::BSTR_PATTERN:
9812 case Ttcn::Template::HSTR_PATTERN:
9813 case Ttcn::Template::OSTR_PATTERN: {
9814 // FIXME: cannot access u.pattern
9815 break; }
9816 case Ttcn::Template::ANY_VALUE:
9817 case Ttcn::Template::ANY_OR_OMIT:
9818 case Ttcn::Template::OMIT_VALUE:
9819 case Ttcn::Template::TEMPLATE_NOTUSED:
9820 break; // self-ref can't happen
9821 case Ttcn::Template::TEMPLATE_INVOKE:
9822 break; // assume self-ref can't happen
9823 case Ttcn::Template::TEMPLATE_ERROR:
9824 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9825 break;
9826 // default:
9827 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9828 // break; // and hope for the best
9829 }
9830 return self_ref;
9831 }
9832
9833 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
9834 {
9835 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
9836 namedbool is_str_elem = NOT_STR_ELEM;
9837 if (v->valuetype == V_REFD) {
9838 Reference *ref = v->get_reference();
9839 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
9840 if (subrefs && subrefs->refers_to_string_element()) {
9841 is_str_elem = IS_STR_ELEM;
9842 }
9843 }
9844 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9845 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
9846 is_str_elem);
9847 }
9848
9849 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
9850 {
9851 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
9852 if (!lhs) FATAL_ERROR("no lhs!");
9853 bool self_ref = false;
9854 switch (u.expr.v_optype) {
9855 case OPTYPE_RND: // -
9856 case OPTYPE_TESTCASENAME: // -
9857 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
9858 case OPTYPE_COMP_MTC: // -
9859 case OPTYPE_COMP_SYSTEM: // -
9860 case OPTYPE_COMP_SELF: // -
9861 case OPTYPE_COMP_RUNNING_ANY: // -
9862 case OPTYPE_COMP_RUNNING_ALL: // -
9863 case OPTYPE_COMP_ALIVE_ANY: // -
9864 case OPTYPE_COMP_ALIVE_ALL: // -
9865 case OPTYPE_TMR_RUNNING_ANY: // -
9866 case OPTYPE_GETVERDICT: // -
9867 case OPTYPE_PROF_RUNNING: // -
9868 break; // nothing to do
9869
9870 case OPTYPE_MATCH: // v1 t2
9871 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
9872 // no break
9873 case OPTYPE_UNARYPLUS: // v1
9874 case OPTYPE_UNARYMINUS: // v1
9875 case OPTYPE_NOT: // v1
9876 case OPTYPE_NOT4B: // v1
9877 case OPTYPE_BIT2HEX: // v1
9878 case OPTYPE_BIT2INT: // v1
9879 case OPTYPE_BIT2OCT: // v1
9880 case OPTYPE_BIT2STR: // v1
9881 case OPTYPE_CHAR2INT: // v1
9882 case OPTYPE_CHAR2OCT: // v1
9883 case OPTYPE_FLOAT2INT: // v1
9884 case OPTYPE_FLOAT2STR: // v1
9885 case OPTYPE_HEX2BIT: // v1
9886 case OPTYPE_HEX2INT: // v1
9887 case OPTYPE_HEX2OCT: // v1
9888 case OPTYPE_HEX2STR: // v1
9889 case OPTYPE_INT2CHAR: // v1
9890 case OPTYPE_INT2FLOAT: // v1
9891 case OPTYPE_INT2STR: // v1
9892 case OPTYPE_INT2UNICHAR: // v1
9893 case OPTYPE_OCT2BIT: // v1
9894 case OPTYPE_OCT2CHAR: // v1
9895 case OPTYPE_OCT2HEX: // v1
9896 case OPTYPE_OCT2INT: // v1
9897 case OPTYPE_OCT2STR: // v1
9898 case OPTYPE_STR2BIT: // v1
9899 case OPTYPE_STR2FLOAT: // v1
9900 case OPTYPE_STR2HEX: // v1
9901 case OPTYPE_STR2INT: // v1
9902 case OPTYPE_STR2OCT: // v1
9903 case OPTYPE_UNICHAR2INT: // v1
9904 case OPTYPE_UNICHAR2CHAR: // v1
9905 case OPTYPE_ENUM2INT: // v1
9906 case OPTYPE_RNDWITHVAL: // v1
9907 case OPTYPE_COMP_RUNNING: // v1
9908 case OPTYPE_COMP_ALIVE: // v1
9909 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
9910 case OPTYPE_GET_STRINGENCODING:
9911 case OPTYPE_DECODE_BASE64:
9912 case OPTYPE_REMOVE_BOM:
9913 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9914 break;
9915 case OPTYPE_ADD: // v1 v2
9916 case OPTYPE_SUBTRACT: // v1 v2
9917 case OPTYPE_MULTIPLY: // v1 v2
9918 case OPTYPE_DIVIDE: // v1 v2
9919 case OPTYPE_MOD: // v1 v2
9920 case OPTYPE_REM: // v1 v2
9921 case OPTYPE_CONCAT: // v1 v2
9922 case OPTYPE_EQ: // v1 v2
9923 case OPTYPE_LT: // v1 v2
9924 case OPTYPE_GT: // v1 v2
9925 case OPTYPE_NE: // v1 v2
9926 case OPTYPE_GE: // v1 v2
9927 case OPTYPE_LE: // v1 v2
9928 case OPTYPE_AND: // v1 v2
9929 case OPTYPE_OR: // v1 v2
9930 case OPTYPE_XOR: // v1 v2
9931 case OPTYPE_AND4B: // v1 v2
9932 case OPTYPE_OR4B: // v1 v2
9933 case OPTYPE_XOR4B: // v1 v2
9934 case OPTYPE_SHL: // v1 v2
9935 case OPTYPE_SHR: // v1 v2
9936 case OPTYPE_ROTL: // v1 v2
9937 case OPTYPE_ROTR: // v1 v2
9938 case OPTYPE_INT2BIT: // v1 v2
9939 case OPTYPE_INT2HEX: // v1 v2
9940 case OPTYPE_INT2OCT: // v1 v2
9941 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9942 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9943 break;
9944 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9945 case OPTYPE_OCT2UNICHAR:
9946 case OPTYPE_ENCODE_BASE64:
9947 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9948 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9949 break;
9950 case OPTYPE_DECOMP: // v1 v2 v3
9951 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
9952 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
9953 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
9954 break;
9955
9956 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
9957 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
9958 // no break
9959 case OPTYPE_SUBSTR: // ti1 v2 v3
9960 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9961 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
9962 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
9963 break;
9964
9965 case OPTYPE_REGEXP: // ti1 t2 v3
9966 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9967 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
9968 // no break
9969 case OPTYPE_LENGTHOF: // ti1
9970 case OPTYPE_SIZEOF: // ti1
9971 case OPTYPE_VALUEOF: // ti1
9972 case OPTYPE_ENCODE: // ti1
9973 case OPTYPE_TTCN2STRING:
9974 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
9975 break;
9976
9977 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
9978 // component.create -- assume no self-ref
9979 case OPTYPE_ACTIVATE: // r1
9980 // defaultref := activate(altstep) -- assume no self-ref
9981 case OPTYPE_TMR_RUNNING: // r1
9982 // boolvar := a_timer.running -- assume no self-ref
9983 break;
9984 break;
9985
9986 case OPTYPE_LOG2STR: {// logargs
9987 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
9988 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
9989 switch (la->get_type()) {
9990 case Ttcn::LogArgument::L_UNDEF:
9991 case Ttcn::LogArgument::L_ERROR:
9992 FATAL_ERROR("log2str argument type");
9993 break; // not reached
9994
9995 case Ttcn::LogArgument::L_MACRO:
9996 case Ttcn::LogArgument::L_STR:
9997 break; // self reference not possible
9998
9999 case Ttcn::LogArgument::L_VAL:
10000 case Ttcn::LogArgument::L_MATCH:
10001 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
10002 break;
10003
10004 case Ttcn::LogArgument::L_REF: {
10005 Ttcn::Ref_base *ref = la->get_ref();
10006 Common::Assignment *ass = ref->get_refd_assignment();
10007 self_ref |= (ass == lhs);
10008 break; }
10009
10010 case Ttcn::LogArgument::L_TI: {
10011 Ttcn::TemplateInstance *ti = la->get_ti();
10012 Ttcn::Template *t = ti->get_Template();
10013 self_ref |= chk_expr_self_ref_templ(t, lhs);
10014 break; }
10015
10016 // no default please
10017 } // switch la->logargtype
10018 }
10019 break; }
10020
10021 case OPTYPE_DECODE: { // r1 r2
10022 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10023 self_ref |= (ass == lhs);
10024 goto label_r1; }
10025 case OPTYPE_EXECUTE: // r1 [v2]
10026 if (u.expr.v2) {
10027 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10028 }
10029 label_r1:
10030 // no break
10031 case OPTYPE_UNDEF_RUNNING: // r1
10032 case OPTYPE_TMR_READ: { // r1
10033 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
10034 self_ref |= (ass == lhs);
10035 break; }
10036
10037 case OPTYPE_ISCHOSEN_T: // t1 i2
10038 case OPTYPE_ISBOUND: // ti1
10039 case OPTYPE_ISVALUE: // ti1
10040 case OPTYPE_ISPRESENT: { // ti1
10041 Ttcn::Template *t;
10042 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10043 else t = u.expr.ti1->get_Template();
10044 self_ref |= chk_expr_self_ref_templ(t, lhs);
10045 break; }
10046
10047 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10048 if (u.expr.v3) {
10049 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10050 }
10051 // no break
10052 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10053 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10054 // TODO t_list2
10055 break;
10056
10057 case NUMBER_OF_OPTYPES: // can never happen
10058 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10059 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10060 break;
10061 } // switch u.expr.v_optype
10062 return self_ref;
10063 }
10064
10065
10066 string Value::create_stringRepr()
10067 {
10068 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10069 switch (valuetype) {
10070 case V_ERROR:
10071 return string("<erroneous>");
10072 case V_NULL:
10073 return string("NULL");
10074 case V_BOOL:
10075 if (!parse_only && is_asn1()) {
10076 if (u.val_bool) return string("TRUE");
10077 else return string("FALSE");
10078 }
10079 else {
10080 if (u.val_bool) return string("true");
10081 else return string("false");
10082 }
10083 case V_INT:
10084 return u.val_Int->t_str();
10085 case V_REAL:
10086 return Real2string(u.val_Real);
10087 case V_ENUM:
10088 case V_NAMEDINT:
10089 case V_UNDEF_LOWERID:
10090 return u.val_id->get_name();
10091 case V_NAMEDBITS: {
10092 string ret_val("{ ");
10093 for (size_t i = 0; i < u.ids->size(); i++) {
10094 if (i>0) ret_val += ' ';
10095 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10096 }
10097 ret_val += '}';
10098 return ret_val; }
10099 case V_BSTR: {
10100 string ret_val('\'');
10101 ret_val += *u.str.val_str;
10102 ret_val += "'B";
10103 return ret_val; }
10104 case V_HSTR: {
10105 string ret_val('\'');
10106 ret_val += *u.str.val_str;
10107 ret_val += "'H";
10108 return ret_val; }
10109 case V_OSTR: {
10110 string ret_val('\'');
10111 ret_val += *u.str.val_str;
10112 ret_val += "'O";
10113 return ret_val; }
10114 case V_CSTR:
10115 case V_ISO2022STR:
10116 return u.str.val_str->get_stringRepr();
10117 case V_USTR:
10118 return u.ustr.val_ustr->get_stringRepr();
10119 case V_CHARSYMS:
10120 /** \todo stringrepr of V_CHARSYMS */
10121 return string("<sorry, string representation of charsyms "
10122 "not implemented>");
10123 case V_OID:
10124 case V_ROID: {
10125 string ret_val;
10126 if (parse_only || !is_asn1()) ret_val += "objid ";
10127 ret_val += "{ ";
10128 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10129 if (i>0) ret_val += ' ';
10130 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10131 }
10132 ret_val += " }";
10133 return ret_val; }
10134 case V_CHOICE:
10135 if (!parse_only && is_asn1()) {
10136 string ret_val(u.choice.alt_name->get_dispname());
10137 ret_val += " : ";
10138 ret_val += u.choice.alt_value->get_stringRepr();
10139 return ret_val;
10140 }
10141 else {
10142 string ret_val("{ ");
10143 ret_val += u.choice.alt_name->get_dispname();
10144 ret_val += " := ";
10145 ret_val += u.choice.alt_value->get_stringRepr();
10146 ret_val += " }";
10147 return ret_val;
10148 }
10149 case V_SEQOF:
10150 case V_SETOF:
10151 case V_ARRAY: {
10152 string ret_val("{ ");
10153 if (!is_indexed()) {
10154 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10155 if (i > 0) ret_val += ", ";
10156 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10157 }
10158 } else {
10159 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10160 if (i > 0) ret_val += ", ";
10161 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10162 }
10163 }
10164 ret_val += " }";
10165 return ret_val; }
10166 case V_SEQ:
10167 case V_SET: {
10168 string ret_val("{ ");
10169 bool asn1_flag = !parse_only && is_asn1();
10170 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10171 if (i > 0) ret_val += ", ";
10172 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10173 ret_val += nv->get_name().get_dispname();
10174 if (asn1_flag) ret_val += ' ';
10175 else ret_val += " := ";
10176 ret_val += nv->get_value()->get_stringRepr();
10177 }
10178 ret_val += " }";
10179 return ret_val; }
10180 case V_REFD: {
10181 // do not evaluate the reference if it is not done so far
10182 // (e.g. in parse-only mode)
10183 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10184 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10185 else return t_val->get_stringRepr(); }
10186 case V_OMIT:
10187 return string("omit");
10188 case V_VERDICT:
10189 switch (u.verdict) {
10190 case Verdict_NONE:
10191 return string("none");
10192 case Verdict_PASS:
10193 return string("pass");
10194 case Verdict_INCONC:
10195 return string("inconc");
10196 case Verdict_FAIL:
10197 return string("fail");
10198 case Verdict_ERROR:
10199 return string("error");
10200 default:
10201 return string("<unknown verdict value>");
10202 }
10203 case V_DEFAULT_NULL:
10204 case V_FAT_NULL:
10205 return string("null");
10206 case V_EXPR:
10207 switch (u.expr.v_optype) {
10208 case OPTYPE_RND:
10209 return string("rnd()");
10210 case OPTYPE_TESTCASENAME:
10211 return string("testcasename()");
10212 case OPTYPE_UNARYPLUS:
10213 return create_stringRepr_unary("+");
10214 case OPTYPE_UNARYMINUS:
10215 return create_stringRepr_unary("-");
10216 case OPTYPE_NOT:
10217 return create_stringRepr_unary("not");
10218 case OPTYPE_NOT4B:
10219 return create_stringRepr_unary("not4b");
10220 case OPTYPE_BIT2HEX:
10221 return create_stringRepr_predef1("bit2hex");
10222 case OPTYPE_BIT2INT:
10223 return create_stringRepr_predef1("bit2int");
10224 case OPTYPE_BIT2OCT:
10225 return create_stringRepr_predef1("bit2oct");
10226 case OPTYPE_BIT2STR:
10227 return create_stringRepr_predef1("bit2str");
10228 case OPTYPE_CHAR2INT:
10229 return create_stringRepr_predef1("char2int");
10230 case OPTYPE_CHAR2OCT:
10231 return create_stringRepr_predef1("char2oct");
10232 case OPTYPE_FLOAT2INT:
10233 return create_stringRepr_predef1("float2int");
10234 case OPTYPE_FLOAT2STR:
10235 return create_stringRepr_predef1("float2str");
10236 case OPTYPE_HEX2BIT:
10237 return create_stringRepr_predef1("hex2bit");
10238 case OPTYPE_HEX2INT:
10239 return create_stringRepr_predef1("hex2int");
10240 case OPTYPE_HEX2OCT:
10241 return create_stringRepr_predef1("hex2oct");
10242 case OPTYPE_HEX2STR:
10243 return create_stringRepr_predef1("hex2str");
10244 case OPTYPE_INT2CHAR:
10245 return create_stringRepr_predef1("int2char");
10246 case OPTYPE_INT2FLOAT:
10247 return create_stringRepr_predef1("int2float");
10248 case OPTYPE_INT2STR:
10249 return create_stringRepr_predef1("int2str");
10250 case OPTYPE_INT2UNICHAR:
10251 return create_stringRepr_predef1("int2unichar");
10252 case OPTYPE_OCT2BIT:
10253 return create_stringRepr_predef1("oct2bit");
10254 case OPTYPE_OCT2CHAR:
10255 return create_stringRepr_predef1("oct2char");
10256 case OPTYPE_OCT2HEX:
10257 return create_stringRepr_predef1("oct2hex");
10258 case OPTYPE_OCT2INT:
10259 return create_stringRepr_predef1("oct2int");
10260 case OPTYPE_OCT2STR:
10261 return create_stringRepr_predef1("oct2str");
10262 case OPTYPE_GET_STRINGENCODING:
10263 return create_stringRepr_predef1("get_stringencoding");
10264 case OPTYPE_REMOVE_BOM:
10265 return create_stringRepr_predef1("remove_bom");
10266 case OPTYPE_ENCODE_BASE64: {
10267 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10268 else return create_stringRepr_predef1("encode_base64");
10269 }
10270 case OPTYPE_DECODE_BASE64:
10271 return create_stringRepr_predef1("decode_base64");
10272 case OPTYPE_OCT2UNICHAR:{
10273 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10274 else return create_stringRepr_predef1("oct2unichar");
10275 }
10276 case OPTYPE_UNICHAR2OCT: {
10277 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10278 else return create_stringRepr_predef1("unichar2oct");
10279 }
10280 case OPTYPE_STR2BIT:
10281 return create_stringRepr_predef1("str2bit");
10282 case OPTYPE_STR2FLOAT:
10283 return create_stringRepr_predef1("str2float");
10284 case OPTYPE_STR2HEX:
10285 return create_stringRepr_predef1("str2hex");
10286 case OPTYPE_STR2INT:
10287 return create_stringRepr_predef1("str2int");
10288 case OPTYPE_STR2OCT:
10289 return create_stringRepr_predef1("str2oct");
10290 case OPTYPE_UNICHAR2INT:
10291 return create_stringRepr_predef1("unichar2int");
10292 case OPTYPE_UNICHAR2CHAR:
10293 return create_stringRepr_predef1("unichar2char");
10294 case OPTYPE_ENUM2INT:
10295 return create_stringRepr_predef1("enum2int");
10296 case OPTYPE_ENCODE:
10297 return create_stringRepr_predef1("encvalue");
10298 case OPTYPE_DECODE:
10299 return create_stringRepr_predef2("decvalue");
10300 case OPTYPE_RNDWITHVAL:
10301 return create_stringRepr_predef1("rnd");
10302 case OPTYPE_ADD:
10303 return create_stringRepr_infix("+");
10304 case OPTYPE_SUBTRACT:
10305 return create_stringRepr_infix("-");
10306 case OPTYPE_MULTIPLY:
10307 return create_stringRepr_infix("*");
10308 case OPTYPE_DIVIDE:
10309 return create_stringRepr_infix("/");
10310 case OPTYPE_MOD:
10311 return create_stringRepr_infix("mod");
10312 case OPTYPE_REM:
10313 return create_stringRepr_infix("rem");
10314 case OPTYPE_CONCAT:
10315 return create_stringRepr_infix("&");
10316 case OPTYPE_EQ:
10317 return create_stringRepr_infix("==");
10318 case OPTYPE_LT:
10319 return create_stringRepr_infix("<");
10320 case OPTYPE_GT:
10321 return create_stringRepr_infix(">");
10322 case OPTYPE_NE:
10323 return create_stringRepr_infix("!=");
10324 case OPTYPE_GE:
10325 return create_stringRepr_infix(">=");
10326 case OPTYPE_LE:
10327 return create_stringRepr_infix("<=");
10328 case OPTYPE_AND:
10329 return create_stringRepr_infix("and");
10330 case OPTYPE_OR:
10331 return create_stringRepr_infix("or");
10332 case OPTYPE_XOR:
10333 return create_stringRepr_infix("xor");
10334 case OPTYPE_AND4B:
10335 return create_stringRepr_infix("and4b");
10336 case OPTYPE_OR4B:
10337 return create_stringRepr_infix("or4b");
10338 case OPTYPE_XOR4B:
10339 return create_stringRepr_infix("xor4b");
10340 case OPTYPE_SHL:
10341 return create_stringRepr_infix("<<");
10342 case OPTYPE_SHR:
10343 return create_stringRepr_infix(">>");
10344 case OPTYPE_ROTL:
10345 return create_stringRepr_infix("<@");
10346 case OPTYPE_ROTR:
10347 return create_stringRepr_infix("@>");
10348 case OPTYPE_INT2BIT:
10349 return create_stringRepr_predef2("int2bit");
10350 case OPTYPE_INT2HEX:
10351 return create_stringRepr_predef2("int2hex");
10352 case OPTYPE_INT2OCT:
10353 return create_stringRepr_predef2("int2oct");
10354 case OPTYPE_SUBSTR: {
10355 string ret_val("substr(");
10356 u.expr.ti1->append_stringRepr(ret_val);
10357 ret_val += ", ";
10358 ret_val += u.expr.v2->get_stringRepr();
10359 ret_val += ", ";
10360 ret_val += u.expr.v3->get_stringRepr();
10361 ret_val += ')';
10362 return ret_val;
10363 }
10364 case OPTYPE_REGEXP: {
10365 string ret_val("regexp(");
10366 u.expr.ti1->append_stringRepr(ret_val);
10367 ret_val += ", ";
10368 u.expr.t2->append_stringRepr(ret_val);
10369 ret_val += ", ";
10370 ret_val += u.expr.v3->get_stringRepr();
10371 ret_val += ')';
10372 return ret_val;
10373 }
10374 case OPTYPE_DECOMP: {
10375 string ret_val("decomp(");
10376 ret_val += u.expr.v1->get_stringRepr();
10377 ret_val += ", ";
10378 ret_val += u.expr.v2->get_stringRepr();
10379 ret_val += ", ";
10380 ret_val += u.expr.v3->get_stringRepr();
10381 ret_val += ')';
10382 return ret_val;
10383 }
10384 case OPTYPE_REPLACE: {
10385 string ret_val("replace(");
10386 u.expr.ti1->append_stringRepr(ret_val);
10387 ret_val += ", ";
10388 ret_val += u.expr.v2->get_stringRepr();
10389 ret_val += ", ";
10390 ret_val += u.expr.v3->get_stringRepr();
10391 ret_val += ", ";
10392 u.expr.ti4->append_stringRepr(ret_val);
10393 ret_val += ')';
10394 return ret_val;
10395 }
10396 case OPTYPE_ISPRESENT: {
10397 string ret_val("ispresent(");
10398 u.expr.ti1->append_stringRepr(ret_val);
10399 ret_val += ')';
10400 return ret_val; }
10401 case OPTYPE_ISCHOSEN: {
10402 string ret_val("ischosen(");
10403 ret_val += u.expr.r1->get_dispname();
10404 ret_val += '.';
10405 ret_val += u.expr.i2->get_dispname();
10406 ret_val += ')';
10407 return ret_val; }
10408 case OPTYPE_ISCHOSEN_V: {
10409 string ret_val("ischosen(");
10410 ret_val += u.expr.v1->get_stringRepr();
10411 ret_val += '.';
10412 ret_val += u.expr.i2->get_dispname();
10413 ret_val += ')';
10414 return ret_val; }
10415 case OPTYPE_ISCHOSEN_T: {
10416 string ret_val("ischosen(");
10417 ret_val += u.expr.t1->get_stringRepr();
10418 ret_val += '.';
10419 ret_val += u.expr.i2->get_dispname();
10420 ret_val += ')';
10421 return ret_val; }
10422 case OPTYPE_LENGTHOF: {
10423 string ret_val("lengthof(");
10424 u.expr.ti1->append_stringRepr(ret_val);
10425 ret_val += ')';
10426 return ret_val; }
10427 case OPTYPE_SIZEOF: {
10428 string ret_val("sizeof(");
10429 u.expr.ti1->append_stringRepr(ret_val);
10430 ret_val += ')';
10431 return ret_val; }
10432 case OPTYPE_ISVALUE: {
10433 string ret_val("isvalue(");
10434 u.expr.ti1->append_stringRepr(ret_val);
10435 ret_val += ')';
10436 return ret_val; }
10437 case OPTYPE_VALUEOF: {
10438 string ret_val("valueof(");
10439 u.expr.ti1->append_stringRepr(ret_val);
10440 ret_val += ')';
10441 return ret_val; }
10442 case OPTYPE_LOG2STR:
10443 return string("log2str(...)");
10444 case OPTYPE_MATCH: {
10445 string ret_val("match(");
10446 ret_val += u.expr.v1->get_stringRepr();
10447 ret_val += ", ";
10448 u.expr.t2->append_stringRepr(ret_val);
10449 ret_val += ')';
10450 return ret_val; }
10451 case OPTYPE_TTCN2STRING: {
10452 string ret_val("ttcn2string(");
10453 u.expr.ti1->append_stringRepr(ret_val);
10454 ret_val += ')';
10455 return ret_val;
10456 }
10457 case OPTYPE_UNDEF_RUNNING:
10458 return u.expr.r1->get_dispname() + ".running";
10459 case OPTYPE_COMP_NULL:
10460 return string("null");
10461 case OPTYPE_COMP_MTC:
10462 return string("mtc");
10463 case OPTYPE_COMP_SYSTEM:
10464 return string("system");
10465 case OPTYPE_COMP_SELF:
10466 return string("self");
10467 case OPTYPE_COMP_CREATE: {
10468 string ret_val(u.expr.r1->get_dispname());
10469 ret_val += ".create";
10470 if (u.expr.v2 || u.expr.v3) {
10471 ret_val += '(';
10472 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10473 else ret_val += '-';
10474 if (u.expr.v3) {
10475 ret_val += ", ";
10476 ret_val += u.expr.v3->get_stringRepr();
10477 }
10478 ret_val += ')';
10479 }
10480 if (u.expr.b4) ret_val += " alive";
10481 return ret_val; }
10482 case OPTYPE_COMP_RUNNING:
10483 return u.expr.v1->get_stringRepr() + ".running";
10484 case OPTYPE_COMP_RUNNING_ANY:
10485 return string("any component.running");
10486 case OPTYPE_COMP_RUNNING_ALL:
10487 return string("all component.running");
10488 case OPTYPE_COMP_ALIVE:
10489 return u.expr.v1->get_stringRepr() + ".alive";
10490 case OPTYPE_COMP_ALIVE_ANY:
10491 return string("any component.alive");
10492 case OPTYPE_COMP_ALIVE_ALL:
10493 return string("all component.alive");
10494 case OPTYPE_TMR_READ:
10495 return u.expr.r1->get_dispname() + ".read";
10496 case OPTYPE_TMR_RUNNING:
10497 return u.expr.r1->get_dispname() + ".running";
10498 case OPTYPE_TMR_RUNNING_ANY:
10499 return string("any timer.running");
10500 case OPTYPE_GETVERDICT:
10501 return string("getverdict");
10502 case OPTYPE_ACTIVATE: {
10503 string ret_val("activate(");
10504 ret_val += u.expr.r1->get_dispname();
10505 ret_val += ')';
10506 return ret_val; }
10507 case OPTYPE_ACTIVATE_REFD: {
10508 string ret_val("activate(derefer(");
10509 ret_val += u.expr.v1->get_stringRepr();
10510 ret_val += ")(";
10511 if (u.expr.state == EXPR_CHECKED) {
10512 if (u.expr.ap_list2) {
10513 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10514 for (size_t i = 0; i < nof_pars; i++) {
10515 if (i > 0) ret_val += ", ";
10516 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10517 }
10518 }
10519 } else {
10520 if (u.expr.t_list2) {
10521 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10522 for (size_t i = 0; i < nof_pars; i++) {
10523 if (i > 0) ret_val += ", ";
10524 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10525 }
10526 }
10527 }
10528 ret_val += "))";
10529 return ret_val; }
10530 case OPTYPE_EXECUTE: {
10531 string ret_val("execute(");
10532 ret_val += u.expr.r1->get_dispname();
10533 if (u.expr.v2) {
10534 ret_val += ", ";
10535 ret_val += u.expr.v2->get_stringRepr();
10536 }
10537 ret_val += ')';
10538 return ret_val; }
10539 case OPTYPE_EXECUTE_REFD: {
10540 string ret_val("execute(derefers(");
10541 ret_val += u.expr.v1->get_stringRepr();
10542 ret_val += ")(";
10543 if (u.expr.state == EXPR_CHECKED) {
10544 if (u.expr.ap_list2) {
10545 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10546 for (size_t i = 0; i < nof_pars; i++) {
10547 if (i > 0) ret_val += ", ";
10548 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10549 }
10550 }
10551 } else {
10552 if (u.expr.t_list2) {
10553 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10554 for (size_t i = 0; i < nof_pars; i++) {
10555 if (i > 0) ret_val += ", ";
10556 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10557 }
10558 }
10559 }
10560 ret_val += ')';
10561 if(u.expr.v3) {
10562 ret_val += ", ";
10563 ret_val += u.expr.v3->get_stringRepr();
10564 }
10565 ret_val += ')';
10566 return ret_val; }
10567 case OPTYPE_PROF_RUNNING:
10568 return string("@profiler.running");
10569 default:
10570 return string("<unsupported optype>");
10571 } // switch u.expr.v_optype
10572 case V_MACRO:
10573 switch (u.macro) {
10574 case MACRO_MODULEID:
10575 return string("%moduleId");
10576 case MACRO_FILENAME:
10577 return string("%fileName");
10578 case MACRO_BFILENAME:
10579 return string("__BFILE__");
10580 case MACRO_FILEPATH:
10581 return string("__FILE__");
10582 case MACRO_LINENUMBER:
10583 return string("%lineNumber");
10584 case MACRO_LINENUMBER_C:
10585 return string("__LINE__");
10586 case MACRO_DEFINITIONID:
10587 return string("%definitionId");
10588 case MACRO_SCOPE:
10589 return string("__SCOPE__");
10590 case MACRO_TESTCASEID:
10591 return string("%testcaseId");
10592 default:
10593 return string("<unknown macro>");
10594 } // switch u.macro
10595 case V_NOTUSED:
10596 return string('-');
10597 case V_FUNCTION:
10598 case V_ALTSTEP:
10599 case V_TESTCASE: {
10600 string ret_val("refers(");
10601 ret_val += u.refd_fat->get_assname();
10602 ret_val += ')';
10603 return ret_val; }
10604 case V_INVOKE: {
10605 string ret_val;
10606 ret_val += u.invoke.v->get_stringRepr();
10607 ret_val += ".apply(";
10608 if (u.invoke.ap_list) {
10609 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10610 for (size_t i = 0; i < nof_pars; i++) {
10611 if (i > 0) ret_val += ", ";
10612 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10613 }
10614 } else if (u.invoke.t_list) {
10615 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10616 for (size_t i = 0; i < nof_pars; i++) {
10617 if (i > 0) ret_val += ", ";
10618 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10619 }
10620 }
10621 ret_val += ')';
10622 return ret_val; }
10623 case V_REFER: {
10624 string ret_val("refers(");
10625 ret_val += u.refered->get_dispname();
10626 ret_val += ')';
10627 return ret_val; }
10628 default:
10629 return string("<unsupported valuetype>");
10630 } // switch valuetype
10631 }
10632
10633 string Value::create_stringRepr_unary(const char *operator_str)
10634 {
10635 string ret_val(operator_str);
10636 ret_val += '(';
10637 ret_val += u.expr.v1->get_stringRepr();
10638 ret_val += ')';
10639 return ret_val;
10640 }
10641
10642 string Value::create_stringRepr_infix(const char *operator_str)
10643 {
10644 string ret_val('(');
10645 ret_val += u.expr.v1->get_stringRepr();
10646 ret_val += ' ';
10647 ret_val += operator_str;
10648 ret_val += ' ';
10649 ret_val += u.expr.v2->get_stringRepr();
10650 ret_val += ')';
10651 return ret_val;
10652 }
10653
10654 string Value::create_stringRepr_predef1(const char *function_name)
10655 {
10656 string ret_val(function_name);
10657 ret_val += '(';
10658 if (u.expr.v_optype == OPTYPE_ENCODE) { // ti1, not v1
10659 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10660 }
10661 else ret_val += u.expr.v1->get_stringRepr();
10662 ret_val += ')';
10663 return ret_val;
10664 }
10665
10666 string Value::create_stringRepr_predef2(const char *function_name)
10667 {
10668 string ret_val(function_name);
10669 ret_val += '(';
10670 ret_val += u.expr.v1->get_stringRepr();
10671 ret_val += ", ";
10672 ret_val += u.expr.v2->get_stringRepr();
10673 ret_val += ')';
10674 return ret_val;
10675 }
10676
10677 bool Value::operator==(Value& val)
10678 {
10679 Value *left = get_value_refd_last();
10680 Type *left_governor = left->get_my_governor();
10681 if (left_governor) left_governor = left_governor->get_type_refd_last();
10682 Value *right = val.get_value_refd_last();
10683 Type *right_governor = right->get_my_governor();
10684 if (right_governor) right_governor = right_governor->get_type_refd_last();
10685 if (left_governor && right_governor
10686 && !left_governor->is_compatible(right_governor, NULL)
10687 && !right_governor->is_compatible(left_governor, NULL))
10688 FATAL_ERROR("Value::operator==");
10689
10690 // Not-A-Value is not equal to anything (NaN analogy:)
10691 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10692 return false;
10693
10694 switch (left->valuetype) {
10695 case V_NULL:
10696 case V_OMIT:
10697 case V_DEFAULT_NULL:
10698 case V_FAT_NULL:
10699 case V_NOTUSED:
10700 return left->valuetype == right->valuetype;
10701 case V_BOOL:
10702 return right->valuetype == V_BOOL &&
10703 left->get_val_bool() == right->get_val_bool();
10704 case V_INT:
10705 return right->valuetype == V_INT && *left->get_val_Int()
10706 == *right->get_val_Int();
10707 case V_REAL:
10708 return right->valuetype == V_REAL &&
10709 left->get_val_Real() == right->get_val_Real();
10710 case V_CSTR:
10711 switch (right->valuetype) {
10712 case V_CSTR:
10713 return left->get_val_str() == right->get_val_str();
10714 case V_USTR:
10715 return right->get_val_ustr() == left->get_val_str();
10716 case V_ISO2022STR:
10717 return right->get_val_iso2022str() == left->get_val_str();
10718 default:
10719 return false;
10720 }
10721 case V_BSTR:
10722 case V_HSTR:
10723 case V_OSTR:
10724 return left->valuetype == right->valuetype &&
10725 left->get_val_str() == right->get_val_str();
10726 case V_USTR:
10727 switch (right->valuetype) {
10728 case V_CSTR:
10729 return left->get_val_ustr() == right->get_val_str();
10730 case V_USTR:
10731 return left->get_val_ustr() == right->get_val_ustr();
10732 case V_ISO2022STR:
10733 return left->get_val_ustr() == right->get_val_iso2022str();
10734 default:
10735 return false;
10736 }
10737 case V_ISO2022STR:
10738 switch (right->valuetype) {
10739 case V_CSTR:
10740 return left->get_val_iso2022str() == right->get_val_str();
10741 case V_USTR:
10742 // The appropriate operator==() is missing. The operands are swapped,
10743 // but it shouldn't be a problem.
10744 return right->get_val_ustr() == left->get_val_iso2022str();
10745 case V_ISO2022STR:
10746 return left->get_val_iso2022str() == right->get_val_iso2022str();
10747 default:
10748 return false;
10749 }
10750 case V_ENUM:
10751 return right->valuetype == V_ENUM &&
10752 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10753 case V_OID:
10754 case V_ROID:
10755 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10756 vector<string> act, other;
10757 get_oid_comps(act);
10758 val.get_oid_comps(other);
10759 size_t act_size = act.size(), other_size = other.size();
10760 bool ret_val;
10761 if (act_size == other_size) {
10762 ret_val = true;
10763 for (size_t i = 0; i < act_size; i++)
10764 if (*act[i] != *other[i]) {
10765 ret_val = false;
10766 break;
10767 }
10768 } else ret_val = false;
10769 for (size_t i = 0; i < act_size; i++) delete act[i];
10770 act.clear();
10771 for (size_t i = 0; i < other_size; i++) delete other[i];
10772 other.clear();
10773 return ret_val;
10774 } else return false;
10775 case V_CHOICE:
10776 return right->valuetype == V_CHOICE &&
10777 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10778 *(left->get_alt_value()) == *(right->get_alt_value());
10779 case V_SEQ:
10780 case V_SET: {
10781 if (!left_governor) FATAL_ERROR("Value::operator==");
10782 if (left->valuetype != right->valuetype) return false;
10783 size_t nof_comps = left_governor->get_nof_comps();
10784 for (size_t i = 0; i < nof_comps; i++) {
10785 Value *lval = NULL, *rval = NULL;
10786 CompField* cfl = left_governor->get_comp_byIndex(i);
10787 const Identifier& field_name = cfl->get_name();
10788 if (left->has_comp_withName(field_name)) {
10789 lval = left->get_comp_value_byName(field_name);
10790 if (right->has_comp_withName(field_name)) {
10791 rval = right->get_comp_value_byName(field_name);
10792 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10793 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10794 return false;
10795 else if (!(*lval == *rval))
10796 return false;
10797 } else {
10798 if (cfl->has_default()) {
10799 if (!(*lval == *cfl->get_defval()))
10800 return false;
10801 } else {
10802 if (lval->valuetype != V_OMIT)
10803 return false;
10804 }
10805 }
10806 } else {
10807 if(right->has_comp_withName(field_name)) {
10808 rval = right->get_comp_value_byName(field_name);
10809 if(cfl->has_default()) {
10810 if(rval->valuetype==V_OMIT) return false;
10811 else {
10812 lval = cfl->get_defval();
10813 if (!(*lval==*rval)) return false;
10814 }
10815 }
10816 }
10817 }
10818 }
10819 return true; }
10820 case V_SEQOF:
10821 case V_ARRAY: {
10822 if (left->valuetype != right->valuetype) return false;
10823 size_t ncomps = get_nof_comps();
10824 if (ncomps != right->get_nof_comps()) return false;
10825
10826 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
10827 bool found = false;
10828 map<IndexedValue*, void> uncovered;
10829 for (size_t i = 0; i < left->get_nof_comps(); ++i)
10830 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
10831
10832 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
10833 found = false;
10834 for (size_t j = 0; j < uncovered.size(); ++j) {
10835 if (*(uncovered.get_nth_key(j)->get_value()) ==
10836 *(right->get_comp_byIndex(i)) &&
10837 *(uncovered.get_nth_key(j)->get_index()) ==
10838 *(right->get_index_byIndex(i))) {
10839 found = true;
10840 uncovered.erase(uncovered.get_nth_key(j));
10841 break;
10842 }
10843 }
10844 if (!found) break;
10845 }
10846 uncovered.clear();
10847 return found;
10848 } else if (left->is_indexed() || right->is_indexed()) {
10849 Value* indexed_one = 0;
10850 Value* not_indexed_one = 0;
10851
10852 if(left->is_indexed()) { // left is indexed, right is not
10853 indexed_one = left;
10854 not_indexed_one = right;
10855 } else { // right indexed, left is not
10856 indexed_one = right;
10857 not_indexed_one = left;
10858 }
10859
10860 for(size_t i = 0; i < ncomps; ++i) {
10861 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
10862 if(!(ind->valuetype == V_INT &&
10863 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
10864 *(indexed_one->get_comp_byIndex(i))))
10865 { return false; }
10866 }
10867 return true;
10868 } else { // none of them is indexed
10869 for (size_t i = 0; i < ncomps; i++) {
10870 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
10871 return false;
10872 }
10873 return true;
10874 }
10875 }
10876 case V_SETOF: {
10877 if (right->valuetype != V_SETOF) return false;
10878 size_t ncomps = get_nof_comps();
10879 if (ncomps != right->get_nof_comps()) return false;
10880 if (ncomps == 0) return true;
10881 map<size_t, void> uncovered;
10882 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
10883 for (size_t i = 0; i < ncomps; i++) {
10884 Value *left_item = left->get_comp_byIndex(i);
10885 bool pair_found = false;
10886 for (size_t j = 0; j < ncomps - i; j++) {
10887 size_t right_index = uncovered.get_nth_key(j);
10888 if (*left_item == *right->get_comp_byIndex(right_index)) {
10889 uncovered.erase(right_index);
10890 pair_found = true;
10891 break;
10892 }
10893 }
10894 if (!pair_found) {
10895 uncovered.clear();
10896 return false;
10897 }
10898 }
10899 return true; }
10900 case V_VERDICT:
10901 return right->valuetype == V_VERDICT &&
10902 left->get_val_verdict() == right->get_val_verdict();
10903 case V_FUNCTION:
10904 case V_ALTSTEP:
10905 case V_TESTCASE:
10906 return left->valuetype == right->valuetype &&
10907 left->get_refd_assignment() == right->get_refd_assignment();
10908 default:
10909 FATAL_ERROR("Value::operator==");
10910 }
10911 return true;
10912 }
10913
10914 bool Value::operator<(Value& val)
10915 {
10916 Value *left = get_value_refd_last();
10917 Type *left_governor = left->get_my_governor();
10918 if(left_governor) left_governor=left_governor->get_type_refd_last();
10919 Value *right = val.get_value_refd_last();
10920 Type *right_governor = right->get_my_governor();
10921 if(right_governor) right_governor=right_governor->get_type_refd_last();
10922 if (left->get_valuetype() != right->get_valuetype())
10923 FATAL_ERROR("Value::operator<");
10924 switch(valuetype){
10925 case V_INT:
10926 return *left->get_val_Int() < *right->get_val_Int();
10927 case V_REAL:
10928 return (left->get_val_Real() < right->get_val_Real());
10929 case V_ENUM:
10930 if(!left_governor || !right_governor)
10931 FATAL_ERROR("Value::operator<");
10932 if(left_governor!=right_governor)
10933 FATAL_ERROR("Value::operator<");
10934 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
10935 right_governor->get_enum_val_byId(*right->get_val_id()));
10936 default:
10937 FATAL_ERROR("Value::operator<");
10938 }
10939 return true;
10940 }
10941
10942 bool Value::is_string_type(Type::expected_value_t exp_val)
10943 {
10944 switch (get_expr_returntype(exp_val)) {
10945 case Type::T_CSTR:
10946 case Type::T_USTR:
10947 case Type::T_BSTR:
10948 case Type::T_HSTR:
10949 case Type::T_OSTR:
10950 return true;
10951 default:
10952 return false;
10953 }
10954 }
10955
10956 void Value::generate_code_expr(expression_struct *expr)
10957 {
10958 if (has_single_expr()) {
10959 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
10960 } else {
10961 switch (valuetype) {
10962 case V_EXPR:
10963 generate_code_expr_expr(expr);
10964 break;
10965 case V_CHOICE:
10966 case V_SEQOF:
10967 case V_SETOF:
10968 case V_ARRAY:
10969 case V_SEQ:
10970 case V_SET: {
10971 const string& tmp_id = get_temporary_id();
10972 const char *tmp_id_str = tmp_id.c_str();
10973 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
10974 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
10975 set_genname_recursive(tmp_id);
10976 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10977 expr->expr = mputstr(expr->expr, tmp_id_str);
10978 break; }
10979 case V_INT: {
10980 const string& tmp_id = get_temporary_id();
10981 const char *tmp_id_str = tmp_id.c_str();
10982 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
10983 tmp_id_str);
10984 set_genname_recursive(tmp_id);
10985 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
10986 expr->expr = mputstr(expr->expr, tmp_id_str);
10987 break; }
10988 case V_REFD: {
10989 if (!get_needs_conversion()) {
10990 u.ref.ref->generate_code_const_ref(expr);
10991 } else {
10992 Type *my_gov = get_expr_governor_last();
10993 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
10994 ->get_field_type(u.ref.ref->get_subrefs(),
10995 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
10996 // Make sure that nothing goes wrong.
10997 if (!my_gov || !refd_gov || my_gov == refd_gov)
10998 FATAL_ERROR("Value::generate_code_expr()");
10999 expression_struct expr_tmp;
11000 Code::init_expr(&expr_tmp);
11001 const string& tmp_id1 = get_temporary_id();
11002 const char *tmp_id_str1 = tmp_id1.c_str();
11003 const string& tmp_id2 = get_temporary_id();
11004 const char *tmp_id_str2 = tmp_id2.c_str();
11005 expr->preamble = mputprintf(expr->preamble,
11006 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
11007 tmp_id_str1);
11008 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11009 u.ref.ref->generate_code_const_ref(&expr_tmp);
11010 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11011 expr->preamble = mputprintf(expr->preamble,
11012 "%s %s;\n"
11013 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11014 "and `%s' are not compatible at run-time\");\n",
11015 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11016 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
11017 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
11018 ->get_typename().c_str(), refd_gov->get_typename().c_str());
11019 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11020 }
11021 break; }
11022 case V_INVOKE:
11023 generate_code_expr_invoke(expr);
11024 break;
11025 default:
11026 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
11027 }
11028 }
11029 }
11030
11031 void Value::generate_code_expr_mandatory(expression_struct *expr)
11032 {
11033 generate_code_expr(expr);
11034 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11035 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11036 }
11037
11038 bool Value::can_use_increment(Reference *ref) const
11039 {
11040 if (valuetype != V_EXPR) {
11041 return false;
11042 }
11043 switch (u.expr.v_optype) {
11044 case OPTYPE_ADD:
11045 case OPTYPE_SUBTRACT:
11046 break;
11047 default:
11048 return false;
11049 }
11050 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11051 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11052 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11053 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11054 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11055 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11056 return true;
11057 }
11058 return false;
11059 }
11060
11061 char *Value::generate_code_init(char *str, const char *name)
11062 {
11063 if (get_code_generated()) return str;
11064 if (err_descr) {
11065 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11066 }
11067 switch (valuetype) {
11068 case V_NULL:
11069 case V_BOOL:
11070 case V_REAL:
11071 case V_ENUM:
11072 case V_BSTR:
11073 case V_HSTR:
11074 case V_OSTR:
11075 case V_CSTR:
11076 case V_USTR:
11077 case V_ISO2022STR:
11078 case V_OID:
11079 case V_ROID:
11080 case V_VERDICT:
11081 case V_DEFAULT_NULL:
11082 case V_FAT_NULL:
11083 case V_FUNCTION:
11084 case V_ALTSTEP:
11085 case V_TESTCASE:
11086 // These values have a single string equivalent.
11087 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11088 break;
11089 case V_INT:
11090 if (u.val_Int->is_native_fit())
11091 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11092 else
11093 // It's always an INTEGER.
11094 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11095 "}\n", get_single_expr().c_str(), name);
11096 break;
11097 case V_EXPR:
11098 case V_INVOKE: {
11099 expression_struct expr;
11100 Code::init_expr(&expr);
11101 expr.expr = mputprintf(expr.expr, "%s = ", name);
11102 generate_code_expr(&expr);
11103 str = Code::merge_free_expr(str, &expr);
11104 break; }
11105 case V_CHOICE:
11106 str = generate_code_init_choice(str, name);
11107 break;
11108 case V_SEQOF:
11109 case V_SETOF:
11110 if (!is_indexed()) str = generate_code_init_seof(str, name);
11111 else str = generate_code_init_indexed(str, name);
11112 break;
11113 case V_ARRAY:
11114 if (!is_indexed()) str = generate_code_init_array(str, name);
11115 else str = generate_code_init_indexed(str, name);
11116 break;
11117 case V_SEQ:
11118 case V_SET:
11119 str = generate_code_init_se(str, name);
11120 break;
11121 case V_REFD:
11122 str = generate_code_init_refd(str, name);
11123 break;
11124 case V_MACRO:
11125 switch (u.macro) {
11126 case MACRO_TESTCASEID:
11127 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11128 break;
11129 default:
11130 // all others must already be evaluated away
11131 FATAL_ERROR("Value::generate_code_init()");
11132 }
11133 break;
11134 case V_NOTUSED:
11135 // unbound value, don't generate anything
11136 break;
11137 default:
11138 FATAL_ERROR("Value::generate_code_init()");
11139 }
11140 if (err_descr) {
11141 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11142 }
11143 set_code_generated();
11144 return str;
11145 }
11146
11147 char *Value::rearrange_init_code(char *str, Common::Module* usage_mod)
11148 {
11149 switch (valuetype) {
11150 case V_REFD: {
11151 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11152 if (parlist) {
11153 str = parlist->rearrange_init_code(str, usage_mod);
11154 }
11155 break; }
11156 case V_INVOKE: {
11157 str = u.invoke.v->rearrange_init_code(str, usage_mod);
11158 str = u.invoke.ap_list->rearrange_init_code(str, usage_mod);
11159 break; }
11160 case V_EXPR:
11161 switch (u.expr.v_optype) {
11162 case OPTYPE_UNARYPLUS:
11163 case OPTYPE_UNARYMINUS:
11164 case OPTYPE_NOT:
11165 case OPTYPE_NOT4B:
11166 case OPTYPE_BIT2HEX:
11167 case OPTYPE_BIT2INT:
11168 case OPTYPE_BIT2OCT:
11169 case OPTYPE_BIT2STR:
11170 case OPTYPE_CHAR2INT:
11171 case OPTYPE_CHAR2OCT:
11172 case OPTYPE_FLOAT2INT:
11173 case OPTYPE_FLOAT2STR:
11174 case OPTYPE_HEX2BIT:
11175 case OPTYPE_HEX2INT:
11176 case OPTYPE_HEX2OCT:
11177 case OPTYPE_HEX2STR:
11178 case OPTYPE_INT2CHAR:
11179 case OPTYPE_INT2FLOAT:
11180 case OPTYPE_INT2STR:
11181 case OPTYPE_INT2UNICHAR:
11182 case OPTYPE_OCT2BIT:
11183 case OPTYPE_OCT2CHAR:
11184 case OPTYPE_OCT2HEX:
11185 case OPTYPE_OCT2INT:
11186 case OPTYPE_OCT2STR:
11187 case OPTYPE_STR2BIT:
11188 case OPTYPE_STR2FLOAT:
11189 case OPTYPE_STR2HEX:
11190 case OPTYPE_STR2INT:
11191 case OPTYPE_STR2OCT:
11192 case OPTYPE_UNICHAR2INT:
11193 case OPTYPE_UNICHAR2CHAR:
11194 case OPTYPE_ENUM2INT:
11195 case OPTYPE_ISCHOSEN_V:
11196 case OPTYPE_GET_STRINGENCODING:
11197 case OPTYPE_REMOVE_BOM:
11198 case OPTYPE_DECODE_BASE64:
11199 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11200 break;
11201 case OPTYPE_DECODE: {
11202 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11203 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11204 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11205
11206 parlist = u.expr.r2->get_parlist();
11207 ass = u.expr.r2->get_refd_assignment();
11208 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11209 break; }
11210 case OPTYPE_ADD:
11211 case OPTYPE_SUBTRACT:
11212 case OPTYPE_MULTIPLY:
11213 case OPTYPE_DIVIDE:
11214 case OPTYPE_MOD:
11215 case OPTYPE_REM:
11216 case OPTYPE_CONCAT:
11217 case OPTYPE_EQ:
11218 case OPTYPE_LT:
11219 case OPTYPE_GT:
11220 case OPTYPE_NE:
11221 case OPTYPE_GE:
11222 case OPTYPE_LE:
11223 case OPTYPE_AND:
11224 case OPTYPE_OR:
11225 case OPTYPE_XOR:
11226 case OPTYPE_AND4B:
11227 case OPTYPE_OR4B:
11228 case OPTYPE_XOR4B:
11229 case OPTYPE_SHL:
11230 case OPTYPE_SHR:
11231 case OPTYPE_ROTL:
11232 case OPTYPE_ROTR:
11233 case OPTYPE_INT2BIT:
11234 case OPTYPE_INT2HEX:
11235 case OPTYPE_INT2OCT:
11236 //case OPTYPE_DECODE:
11237 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11238 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11239 break;
11240 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11241 case OPTYPE_OCT2UNICHAR:
11242 case OPTYPE_ENCODE_BASE64:
11243 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11244 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11245 break;
11246 case OPTYPE_SUBSTR:
11247 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11248 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11249 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11250 break;
11251 case OPTYPE_REGEXP:
11252 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11253 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11254 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11255 break;
11256 case OPTYPE_DECOMP:
11257 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11258 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11259 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11260 break;
11261 case OPTYPE_REPLACE:
11262 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11263 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11264 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11265 str = u.expr.ti4->rearrange_init_code(str, usage_mod);
11266 break;
11267 case OPTYPE_LENGTHOF:
11268 case OPTYPE_SIZEOF:
11269 case OPTYPE_VALUEOF:
11270 case OPTYPE_ENCODE:
11271 case OPTYPE_ISPRESENT:
11272 case OPTYPE_TTCN2STRING:
11273 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11274 break;
11275 case OPTYPE_ISCHOSEN_T:
11276 str = u.expr.t1->rearrange_init_code(str, usage_mod);
11277 break;
11278 case OPTYPE_MATCH:
11279 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11280 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11281 break;
11282 default:
11283 // other kinds of expressions cannot appear within templates
11284 break;
11285 }
11286 break;
11287 default:
11288 break;
11289 }
11290 return str;
11291 }
11292
11293 char* Value::generate_code_tmp(char *str, const char *prefix,
11294 size_t& blockcount)
11295 {
11296 char *s2 = memptystr();
11297 char *s1 = generate_code_tmp(NULL, s2);
11298 if (s2[0]) {
11299 if (blockcount == 0) {
11300 str = mputstr(str, "{\n");
11301 blockcount++;
11302 }
11303 str = mputstr(str, s2);
11304 }
11305 Free(s2);
11306 str=mputstr(str, prefix);
11307 str=mputstr(str, s1);
11308 Free(s1);
11309 return str;
11310 }
11311
11312 char *Value::generate_code_tmp(char *str, char*& init)
11313 {
11314 expression_struct expr;
11315 Code::init_expr(&expr);
11316 generate_code_expr_mandatory(&expr);
11317 if (expr.preamble || expr.postamble) {
11318 if (valuetype == V_EXPR &&
11319 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11320 // a temporary variable is already introduced
11321 if (expr.preamble) init = mputstr(init, expr.preamble);
11322 if (expr.postamble) init = mputstr(init, expr.postamble);
11323 str = mputstr(str, expr.expr);
11324 } else {
11325 const string& tmp_id = get_temporary_id();
11326 const char *tmp_id_str = tmp_id.c_str();
11327 init = mputprintf(init, "%s %s;\n"
11328 "{\n",
11329 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11330 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11331 tmp_id_str);
11332 if (expr.preamble) init = mputstr(init, expr.preamble);
11333 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11334 if (expr.postamble) init = mputstr(init, expr.postamble);
11335 init = mputstr(init, "}\n");
11336 str = mputstr(str, tmp_id_str);
11337 }
11338 } else str = mputstr(str, expr.expr);
11339 Code::free_expr(&expr);
11340 return str;
11341 }
11342
11343 void Value::generate_code_log(expression_struct *expr)
11344 {
11345 if (explicit_cast_needed()) {
11346 char *expr_backup = expr->expr;
11347 expr->expr = NULL;
11348 generate_code_expr(expr);
11349 const string& tmp_id = get_temporary_id();
11350 const char *tmp_id_str = tmp_id.c_str();
11351 // We have to create a temporary object, because the parser of GCC
11352 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11353 // constructor call that is, this does not work: type(...).log(); but
11354 // this works: type tmp(...); tmp.log();.
11355 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11356 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11357 expr->expr);
11358 Free(expr->expr);
11359 expr->expr = mputstr(expr_backup, tmp_id_str);
11360 } else {
11361 generate_code_expr(expr);
11362 }
11363 expr->expr = mputstr(expr->expr, ".log()");
11364 }
11365
11366 void Value::generate_code_log_match(expression_struct *expr)
11367 {
11368 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11369 FATAL_ERROR("Value::generate_code_log_match()");
11370 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11371 // compliance the whole code-generation should be checked. Standalone
11372 // constructs like: "A(a[0].f());" should be avoided. The current
11373 // solution for HK38721 uses an additional assignment to overcome the
11374 // issue. The generated code will be slower, but it's needed for old GCC
11375 // versions in specific circumstances.
11376 if (u.expr.t2->needs_temp_ref()) {
11377 char *expr_backup = expr->expr;
11378 expr->expr = NULL;
11379 u.expr.t2->generate_code(expr);
11380 const string& tmp_id = get_temporary_id();
11381 const char *tmp_id_str = tmp_id.c_str();
11382 expr->preamble = mputprintf(expr->preamble,
11383 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11384 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11385 Free(expr->expr);
11386 expr->expr = mputstr(expr_backup, tmp_id_str);
11387 } else {
11388 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11389 // some reason "(A(NS::B)).a(C);" compiles fine.
11390 expr->expr = mputc(expr->expr, '(');
11391 u.expr.t2->generate_code(expr);
11392 expr->expr = mputc(expr->expr, ')');
11393 }
11394 expr->expr = mputstr(expr->expr, ".log_match(");
11395 u.expr.v1->generate_code_expr(expr);
11396 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11397 }
11398
11399 void Value::generate_code_expr_expr(expression_struct *expr)
11400 {
11401 switch (u.expr.v_optype) {
11402 case OPTYPE_RND:
11403 generate_code_expr_rnd(expr, 0);
11404 break;
11405 case OPTYPE_UNARYPLUS:
11406 // same as without the '+' operator
11407 u.expr.v1->generate_code_expr(expr);
11408 break;
11409 case OPTYPE_UNARYMINUS:
11410 generate_code_expr_unary(expr, "-", u.expr.v1);
11411 break;
11412 case OPTYPE_NOT:
11413 generate_code_expr_unary(expr, "!", u.expr.v1);
11414 break;
11415 case OPTYPE_NOT4B:
11416 generate_code_expr_unary(expr, "~", u.expr.v1);
11417 break;
11418 case OPTYPE_BIT2HEX:
11419 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11420 break;
11421 case OPTYPE_BIT2INT:
11422 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11423 break;
11424 case OPTYPE_BIT2OCT:
11425 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11426 break;
11427 case OPTYPE_BIT2STR:
11428 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11429 break;
11430 case OPTYPE_CHAR2INT:
11431 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11432 break;
11433 case OPTYPE_CHAR2OCT:
11434 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11435 break;
11436 case OPTYPE_FLOAT2INT:
11437 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11438 break;
11439 case OPTYPE_FLOAT2STR:
11440 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11441 break;
11442 case OPTYPE_HEX2BIT:
11443 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11444 break;
11445 case OPTYPE_HEX2INT:
11446 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11447 break;
11448 case OPTYPE_HEX2OCT:
11449 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11450 break;
11451 case OPTYPE_HEX2STR:
11452 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11453 break;
11454 case OPTYPE_INT2CHAR:
11455 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11456 break;
11457 case OPTYPE_INT2FLOAT:
11458 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11459 break;
11460 case OPTYPE_INT2STR:
11461 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11462 break;
11463 case OPTYPE_INT2UNICHAR:
11464 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11465 break;
11466 case OPTYPE_OCT2BIT:
11467 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11468 break;
11469 case OPTYPE_OCT2CHAR:
11470 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11471 break;
11472 case OPTYPE_GET_STRINGENCODING:
11473 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11474 break;
11475 case OPTYPE_REMOVE_BOM:
11476 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11477 break;
11478 case OPTYPE_ENCODE_BASE64:
11479 if (u.expr.v2)
11480 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11481 else
11482 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11483 break;
11484 case OPTYPE_DECODE_BASE64:
11485 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11486 break;
11487 case OPTYPE_OCT2UNICHAR:
11488 if (u.expr.v2)
11489 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11490 else
11491 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11492 break;
11493 case OPTYPE_UNICHAR2OCT:
11494 if (u.expr.v2)
11495 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11496 else
11497 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11498 break;
11499 case OPTYPE_OCT2HEX:
11500 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11501 break;
11502 case OPTYPE_OCT2INT:
11503 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11504 break;
11505 case OPTYPE_OCT2STR:
11506 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11507 break;
11508 case OPTYPE_STR2BIT:
11509 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11510 break;
11511 case OPTYPE_STR2FLOAT:
11512 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11513 break;
11514 case OPTYPE_STR2HEX:
11515 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11516 break;
11517 case OPTYPE_STR2INT:
11518 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11519 break;
11520 case OPTYPE_STR2OCT:
11521 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11522 break;
11523 case OPTYPE_UNICHAR2INT:
11524 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11525 break;
11526 case OPTYPE_UNICHAR2CHAR:
11527 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11528 break;
11529 case OPTYPE_ENUM2INT: {
11530 Type* enum_type = u.expr.v1->get_expr_governor_last();
11531 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11532 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11533 enum_type->get_genname_value(my_scope).c_str());
11534 u.expr.v1->generate_code_expr_mandatory(expr);
11535 expr->expr = mputc(expr->expr, ')');
11536 break;}
11537 case OPTYPE_ENCODE:
11538 generate_code_expr_encode(expr);
11539 break;
11540 case OPTYPE_DECODE:
11541 generate_code_expr_decode(expr);
11542 break;
11543 case OPTYPE_RNDWITHVAL:
11544 generate_code_expr_rnd(expr, u.expr.v1);
11545 break;
11546 case OPTYPE_ADD:
11547 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11548 break;
11549 case OPTYPE_SUBTRACT:
11550 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11551 break;
11552 case OPTYPE_MULTIPLY:
11553 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11554 break;
11555 case OPTYPE_DIVIDE:
11556 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11557 break;
11558 case OPTYPE_MOD:
11559 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11560 break;
11561 case OPTYPE_REM:
11562 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11563 break;
11564 case OPTYPE_CONCAT:
11565 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11566 break;
11567 case OPTYPE_EQ:
11568 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11569 break;
11570 case OPTYPE_LT:
11571 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11572 break;
11573 case OPTYPE_GT:
11574 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11575 break;
11576 case OPTYPE_NE:
11577 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11578 break;
11579 case OPTYPE_GE:
11580 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11581 break;
11582 case OPTYPE_LE:
11583 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11584 break;
11585 case OPTYPE_AND:
11586 case OPTYPE_OR:
11587 generate_code_expr_and_or(expr);
11588 break;
11589 case OPTYPE_XOR:
11590 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11591 break;
11592 case OPTYPE_AND4B:
11593 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11594 break;
11595 case OPTYPE_OR4B:
11596 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11597 break;
11598 case OPTYPE_XOR4B:
11599 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11600 break;
11601 case OPTYPE_SHL:
11602 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11603 break;
11604 case OPTYPE_SHR:
11605 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11606 break;
11607 case OPTYPE_ROTL:
11608 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11609 break;
11610 case OPTYPE_ROTR:
11611 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11612 break;
11613 case OPTYPE_INT2BIT:
11614 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11615 break;
11616 case OPTYPE_INT2HEX:
11617 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11618 break;
11619 case OPTYPE_INT2OCT:
11620 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11621 break;
11622 case OPTYPE_SUBSTR:
11623 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11624 else generate_code_expr_substr_replace_compat(expr);
11625 break;
11626 case OPTYPE_REGEXP:
11627 generate_code_expr_regexp(expr);
11628 break;
11629 case OPTYPE_DECOMP:
11630 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11631 break;
11632 case OPTYPE_REPLACE:
11633 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11634 else generate_code_expr_substr_replace_compat(expr);
11635 break;
11636 case OPTYPE_ISCHOSEN: // r1 i2
11637 FATAL_ERROR("Value::generate_code_expr_expr()");
11638 break;
11639 case OPTYPE_ISCHOSEN_V: // v1 i2
11640 u.expr.v1->generate_code_expr_mandatory(expr);
11641 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11642 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11643 u.expr.i2->get_name().c_str());
11644 break;
11645 case OPTYPE_ISCHOSEN_T: // t1 i2
11646 u.expr.t1->generate_code_expr(expr);
11647 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11648 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11649 u.expr.i2->get_name().c_str());
11650 break;
11651 case OPTYPE_ISPRESENT:
11652 case OPTYPE_ISBOUND: {
11653 Template::templatetype_t temp = u.expr.ti1->get_Template()
11654 ->get_templatetype();
11655 if (temp == Template::SPECIFIC_VALUE) {
11656 Value* specific_value = u.expr.ti1->get_Template()
11657 ->get_specific_value();
11658 if (specific_value->get_valuetype() == Value::V_REFD) {
11659 Ttcn::Reference* reference =
11660 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11661 if (reference) {
11662 reference->generate_code_ispresentbound(expr, false,
11663 u.expr.v_optype==OPTYPE_ISBOUND);
11664 break;
11665 }
11666 }
11667 } else if (temp == Template::TEMPLATE_REFD){
11668 Ttcn::Reference* reference =
11669 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11670 ->get_reference());
11671 if (reference) {
11672 reference->generate_code_ispresentbound(expr, true,
11673 u.expr.v_optype==OPTYPE_ISBOUND);
11674 break;
11675 }
11676 }
11677 }
11678 // no break
11679 case OPTYPE_LENGTHOF: // ti1
11680 // fall through, separated later
11681 case OPTYPE_SIZEOF: // ti1
11682 // fall through, separated later
11683 case OPTYPE_ISVALUE: { // ti1
11684 if (u.expr.ti1->is_only_specific_value()) {
11685 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11686 bool cast_needed = t_val->explicit_cast_needed(
11687 u.expr.v_optype != OPTYPE_LENGTHOF);
11688 if(cast_needed) {
11689 // the ambiguous C++ expression is converted to the value class
11690 expr->expr = mputprintf(expr->expr, "%s(",
11691 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11692 }
11693
11694 if (u.expr.v_optype != OPTYPE_LENGTHOF
11695 && u.expr.v_optype != OPTYPE_SIZEOF) {
11696 t_val->generate_code_expr(expr);
11697 } else {
11698 t_val->generate_code_expr_mandatory(expr);
11699 }
11700
11701 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11702 }
11703 else u.expr.ti1->generate_code(expr);
11704
11705 switch (u.expr.v_optype) {
11706 case OPTYPE_ISBOUND:
11707 expr->expr=mputstr(expr->expr, ".is_bound()");
11708 break;
11709 case OPTYPE_ISPRESENT:
11710 expr->expr=mputprintf(expr->expr, ".is_present()");
11711 break;
11712 case OPTYPE_SIZEOF:
11713 expr->expr=mputstr(expr->expr, ".size_of()");
11714 break;
11715 case OPTYPE_LENGTHOF:
11716 expr->expr=mputstr(expr->expr, ".lengthof()");
11717 break;
11718 case OPTYPE_ISVALUE:
11719 expr->expr=mputstr(expr->expr, ".is_value()");
11720 break;
11721 default:
11722 FATAL_ERROR("Value::generate_code_expr_expr()");
11723 }
11724 break; }
11725 case OPTYPE_VALUEOF: // ti1
11726 u.expr.ti1->generate_code(expr);
11727 expr->expr = mputstr(expr->expr, ".valueof()");
11728 break;
11729 case OPTYPE_MATCH: // v1 t2
11730 u.expr.t2->generate_code(expr);
11731 expr->expr = mputstr(expr->expr, ".match(");
11732 u.expr.v1->generate_code_expr(expr);
11733 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11734 break;
11735 case OPTYPE_UNDEF_RUNNING:
11736 // it is resolved during semantic check
11737 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11738 break;
11739 case OPTYPE_COMP_NULL: // -
11740 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11741 break;
11742 case OPTYPE_COMP_MTC: // -
11743 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11744 break;
11745 case OPTYPE_COMP_SYSTEM: // -
11746 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11747 break;
11748 case OPTYPE_COMP_SELF: // -
11749 expr->expr=mputstr(expr->expr, "self");
11750 break;
11751 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11752 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11753 u.expr.b4);
11754 break;
11755 case OPTYPE_COMP_RUNNING: // v1
11756 u.expr.v1->generate_code_expr(expr);
11757 if(u.expr.v1->get_valuetype() == V_REFD)
11758 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11759 expr->expr = mputstr(expr->expr, ".running()");
11760 break;
11761 case OPTYPE_COMP_RUNNING_ANY: // -
11762 expr->expr=mputstr(expr->expr,
11763 "TTCN_Runtime::component_running(ANY_COMPREF)");
11764 break;
11765 case OPTYPE_COMP_RUNNING_ALL: // -
11766 expr->expr=mputstr(expr->expr,
11767 "TTCN_Runtime::component_running(ALL_COMPREF)");
11768 break;
11769 case OPTYPE_COMP_ALIVE: // v1
11770 u.expr.v1->generate_code_expr(expr);
11771 if(u.expr.v1->get_valuetype() == V_REFD)
11772 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11773 expr->expr = mputstr(expr->expr, ".alive()");
11774 break;
11775 case OPTYPE_COMP_ALIVE_ANY: // -
11776 expr->expr = mputstr(expr->expr,
11777 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11778 break;
11779 case OPTYPE_COMP_ALIVE_ALL: // -
11780 expr->expr = mputstr(expr->expr,
11781 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11782 break;
11783 case OPTYPE_TMR_READ: // r1
11784 u.expr.r1->generate_code(expr);
11785 expr->expr = mputstr(expr->expr, ".read()");
11786 break;
11787 case OPTYPE_TMR_RUNNING: // r1
11788 u.expr.r1->generate_code(expr);
11789 expr->expr = mputstr(expr->expr, ".running()");
11790 break;
11791 case OPTYPE_TMR_RUNNING_ANY: // -
11792 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11793 break;
11794 case OPTYPE_GETVERDICT: // -
11795 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11796 break;
11797 case OPTYPE_TESTCASENAME: // -
11798 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11799 break;
11800 case OPTYPE_ACTIVATE: // r1
11801 generate_code_expr_activate(expr);
11802 break;
11803 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
11804 generate_code_expr_activate_refd(expr);
11805 break;
11806 case OPTYPE_EXECUTE: // r1 [v2]
11807 generate_code_expr_execute(expr);
11808 break;
11809 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
11810 generate_code_expr_execute_refd(expr);
11811 break;
11812 case OPTYPE_LOG2STR:
11813 u.expr.logargs->generate_code_expr(expr);
11814 break;
11815 case OPTYPE_TTCN2STRING: {
11816 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
11817 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
11818 param_governor = param_governor->get_type_refd_last();
11819 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
11820 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
11821 u.expr.ti1->get_Template()->is_Value()) {
11822 Value* v = u.expr.ti1->get_Template()->get_Value();
11823 delete u.expr.ti1;
11824 u.expr.ti1 = NULL;
11825 bool cast_needed = v->explicit_cast_needed();
11826 if (cast_needed) {
11827 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
11828 }
11829 v->generate_code_expr(expr);
11830 if (cast_needed) {
11831 expr->expr = mputstr(expr->expr, ")");
11832 }
11833 delete v;
11834 } else {
11835 u.expr.ti1->generate_code(expr);
11836 }
11837 expr->expr = mputstr(expr->expr, ")");
11838 } break;
11839 case OPTYPE_PROF_RUNNING:
11840 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
11841 break;
11842 default:
11843 FATAL_ERROR("Value::generate_code_expr_expr()");
11844 }
11845 }
11846
11847 void Value::generate_code_expr_unary(expression_struct *expr,
11848 const char *operator_str, Value *v1)
11849 {
11850 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
11851 v1->generate_code_expr_mandatory(expr);
11852 expr->expr = mputstrn(expr->expr, "))", 2);
11853 }
11854
11855 void Value::generate_code_expr_infix(expression_struct *expr,
11856 const char *operator_str, Value *v1,
11857 Value *v2, bool optional_allowed)
11858 {
11859 if (!get_needs_conversion()) {
11860 expr->expr = mputc(expr->expr, '(');
11861 if (optional_allowed) v1->generate_code_expr(expr);
11862 else v1->generate_code_expr_mandatory(expr);
11863 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
11864 if (optional_allowed) v2->generate_code_expr(expr);
11865 else v2->generate_code_expr_mandatory(expr);
11866 expr->expr = mputc(expr->expr, ')');
11867 } else { // Temporary variable for the converted value.
11868 const string& tmp_id1 = get_temporary_id();
11869 const char *tmp_id_str1 = tmp_id1.c_str();
11870 expression_struct expr_tmp;
11871 Code::init_expr(&expr_tmp);
11872 switch (u.expr.v_optype) {
11873 case OPTYPE_EQ:
11874 case OPTYPE_NE: {
11875 // Always "v1 -> v2".
11876 Type *t1 = v1->get_expr_governor_last();
11877 Type *t2 = v2->get_expr_governor_last();
11878 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
11879 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11880 else v2->generate_code_expr_mandatory(&expr_tmp);
11881 if (expr_tmp.preamble)
11882 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
11883 expr->preamble = mputprintf(expr->preamble,
11884 "%s %s;\n"
11885 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11886 "and `%s' are not compatible at run-time\");\n",
11887 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
11888 TypeConv::get_conv_func(t2, t1, get_my_scope()
11889 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
11890 t2->get_typename().c_str(), t1->get_typename().c_str());
11891 Code::free_expr(&expr_tmp);
11892 if (optional_allowed) v1->generate_code_expr(expr);
11893 else v1->generate_code_expr_mandatory(expr);
11894 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
11895 tmp_id_str1);
11896 break; }
11897 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
11898 // functions. The governors of all operands must exist at this point.
11899 case OPTYPE_ROTL:
11900 case OPTYPE_ROTR:
11901 case OPTYPE_CONCAT: {
11902 const string& tmp_id2 = get_temporary_id();
11903 const char *tmp_id_str2 = tmp_id2.c_str();
11904 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
11905 Type *my_gov = my_governor->get_type_refd_last();
11906 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
11907 ->get_type_refd_last();
11908 if (!t1_gov || my_gov == t1_gov)
11909 FATAL_ERROR("Value::generate_code_expr_infix()");
11910 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11911 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
11912 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11913 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
11914 else v1->generate_code_expr_mandatory(&expr_tmp);
11915 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
11916 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
11917 else v2->generate_code_expr_mandatory(&expr_tmp);
11918 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11919 expr->preamble = mputprintf(expr->preamble,
11920 "%s %s;\n"
11921 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11922 "and `%s' are not compatible at run-time\");\n",
11923 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11924 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
11925 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
11926 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
11927 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11928 break; }
11929 default:
11930 FATAL_ERROR("Value::generate_code_expr_infix()");
11931 break;
11932 }
11933 }
11934 }
11935
11936 void Value::generate_code_expr_and_or(expression_struct *expr)
11937 {
11938 if (u.expr.v2->needs_short_circuit()) {
11939 // introduce a temporary variable to store the result of the operation
11940 const string& tmp_id = get_temporary_id();
11941 const char *tmp_id_str = tmp_id.c_str();
11942 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
11943 expression_struct expr2;
11944 // the left operand must be evaluated anyway
11945 Code::init_expr(&expr2);
11946 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11947 u.expr.v1->generate_code_expr_mandatory(&expr2);
11948 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11949 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
11950 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
11951 // evaluate the right operand only when necessary
11952 // in this case the final result will be the right operand
11953 Code::init_expr(&expr2);
11954 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
11955 u.expr.v2->generate_code_expr_mandatory(&expr2);
11956 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
11957 // the result is now in the temporary variable
11958 expr->expr = mputstr(expr->expr, tmp_id_str);
11959 } else {
11960 // use the overloaded operator to get better error messages
11961 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
11962 "&&" : "||", u.expr.v1, u.expr.v2, false);
11963 }
11964 }
11965
11966 void Value::generate_code_expr_predef1(expression_struct *expr,
11967 const char *function_name,
11968 Value *v1)
11969 {
11970 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11971 v1->generate_code_expr_mandatory(expr);
11972 expr->expr = mputc(expr->expr, ')');
11973 }
11974
11975 void Value::generate_code_expr_predef2(expression_struct *expr,
11976 const char *function_name,
11977 Value *v1, Value *v2)
11978 {
11979 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11980 v1->generate_code_expr_mandatory(expr);
11981 expr->expr = mputstr(expr->expr, ", ");
11982 v2->generate_code_expr_mandatory(expr);
11983 expr->expr = mputc(expr->expr, ')');
11984 }
11985
11986 void Value::generate_code_expr_predef3(expression_struct *expr,
11987 const char *function_name,
11988 Value *v1, Value *v2, Value *v3)
11989 {
11990 expr->expr = mputprintf(expr->expr, "%s(", function_name);
11991 v1->generate_code_expr_mandatory(expr);
11992 expr->expr = mputstr(expr->expr, ", ");
11993 v2->generate_code_expr_mandatory(expr);
11994 expr->expr = mputstr(expr->expr, ", ");
11995 v3->generate_code_expr_mandatory(expr);
11996 expr->expr = mputc(expr->expr, ')');
11997 }
11998
11999 void Value::generate_code_expr_substr(expression_struct *expr)
12000 {
12001 bool par1_is_str;
12002 Value* v1 = u.expr.ti1->get_specific_value();
12003 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12004 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12005 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
12006 if (v1) v1->generate_code_expr_mandatory(expr);
12007 else u.expr.ti1->generate_code(expr);
12008 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12009 else expr->expr = mputstr(expr->expr, ".substr(");
12010 if (!par1_is_str && u.expr.v2->is_unfoldable())
12011 expr->expr = mputstr(expr->expr, "(int)");
12012 u.expr.v2->generate_code_expr_mandatory(expr);
12013 expr->expr = mputstr(expr->expr, ", ");
12014 if (!par1_is_str && u.expr.v3->is_unfoldable())
12015 expr->expr = mputstr(expr->expr, "(int)");
12016 u.expr.v3->generate_code_expr_mandatory(expr);
12017 expr->expr = mputc(expr->expr, ')');
12018 }
12019
12020 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
12021 {
12022 expression_struct expr_tmp;
12023 Code::init_expr(&expr_tmp);
12024 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
12025 ->get_type_refd_last();
12026 if (!t1 || t1 == my_governor->get_type_refd_last())
12027 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12028 if (u.expr.v_optype == OPTYPE_SUBSTR) {
12029 generate_code_expr_substr(&expr_tmp);
12030 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
12031 generate_code_expr_replace(&expr_tmp);
12032 } else {
12033 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12034 }
12035 // Two temporaries to store the result of substr() or replace() and to
12036 // store the converted value.
12037 const string& tmp_id1 = get_temporary_id();
12038 const char *tmp_id_str1 = tmp_id1.c_str();
12039 const string& tmp_id2 = get_temporary_id();
12040 const char *tmp_id_str2 = tmp_id2.c_str();
12041 if (expr_tmp.preamble)
12042 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12043 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12044 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12045 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12046 if (expr_tmp.postamble)
12047 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12048 Code::free_expr(&expr_tmp);
12049 expr->preamble = mputprintf(expr->preamble,
12050 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12051 "`%s' are not compatible at run-time\");\n",
12052 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12053 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12054 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12055 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12056 }
12057
12058 void Value::generate_code_expr_regexp(expression_struct *expr)
12059 {
12060 Value* v1 = u.expr.ti1->get_specific_value();
12061 Value* v2 = u.expr.t2->get_specific_value();
12062 expr->expr = mputstr(expr->expr, "regexp(");
12063 if (v1) v1->generate_code_expr_mandatory(expr);
12064 else u.expr.ti1->generate_code(expr);
12065 expr->expr = mputstr(expr->expr, ", ");
12066 if (v2) v2->generate_code_expr_mandatory(expr);
12067 else u.expr.t2->generate_code(expr);
12068 expr->expr = mputstr(expr->expr, ", ");
12069 u.expr.v3->generate_code_expr_mandatory(expr);
12070 expr->expr = mputc(expr->expr, ')');
12071 }
12072
12073 void Value::generate_code_expr_replace(expression_struct *expr)
12074 {
12075 Value* v1 = u.expr.ti1->get_specific_value();
12076 Value* v4 = u.expr.ti4->get_specific_value();
12077 bool par1_is_str;
12078 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12079 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12080 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12081 if (v1) v1->generate_code_expr_mandatory(expr);
12082 else u.expr.ti1->generate_code(expr);
12083 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12084 else expr->expr = mputstr(expr->expr, ".replace(");
12085 if (!par1_is_str && u.expr.v2->is_unfoldable())
12086 expr->expr = mputstr(expr->expr, "(int)");
12087 u.expr.v2->generate_code_expr_mandatory(expr);
12088 expr->expr = mputstr(expr->expr, ", ");
12089 if (!par1_is_str && u.expr.v3->is_unfoldable())
12090 expr->expr = mputstr(expr->expr, "(int)");
12091 u.expr.v3->generate_code_expr_mandatory(expr);
12092 expr->expr = mputstr(expr->expr, ", ");
12093 if (v4) {
12094 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12095 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12096 Value* v4_last = v4->get_value_refd_last();
12097 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12098 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12099 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
12100 }
12101 v4->generate_code_expr_mandatory(expr);
12102 }
12103 else u.expr.ti4->generate_code(expr);
12104 expr->expr = mputc(expr->expr, ')');
12105 }
12106
12107 void Value::generate_code_expr_rnd(expression_struct *expr,
12108 Value *v1)
12109 {
12110 if(!v1) // simple random generation
12111 expr->expr = mputstr(expr->expr, "rnd()");
12112 else { // random generation with seeding
12113 expr->expr = mputstr(expr->expr, "rnd(");
12114 v1->generate_code_expr_mandatory(expr);
12115 expr->expr = mputc(expr->expr, ')');
12116 }
12117 }
12118
12119 void Value::generate_code_expr_create(expression_struct *expr,
12120 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12121 {
12122 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12123 // first two arguments: component type
12124 Assignment *t_ass = type->get_refd_assignment();
12125 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12126 FATAL_ERROR("Value::generate_code_expr_create()");
12127 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12128 Type::EXPECTED_DYNAMIC_VALUE);
12129 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12130 comptype = comptype->get_type_refd_last();
12131 expr->expr = comptype->get_CompBody()
12132 ->generate_code_comptype_name(expr->expr);
12133 expr->expr = mputstr(expr->expr, ", ");
12134 // third argument: component name
12135 if (name) {
12136 Value *t_val = name->get_value_refd_last();
12137 if (t_val->valuetype == V_CSTR) {
12138 // the argument is foldable to a string literal
12139 size_t str_len = t_val->u.str.val_str->size();
12140 const char *str_ptr = t_val->u.str.val_str->c_str();
12141 expr->expr = mputc(expr->expr, '"');
12142 for (size_t i = 0; i < str_len; i++)
12143 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12144 expr->expr = mputc(expr->expr, '"');
12145 } else name->generate_code_expr_mandatory(expr);
12146 } else expr->expr = mputstr(expr->expr, "NULL");
12147 expr->expr = mputstr(expr->expr, ", ");
12148 // fourth argument: location
12149 if (location) {
12150 Value *t_val = location->get_value_refd_last();
12151 if (t_val->valuetype == V_CSTR) {
12152 // the argument is foldable to a string literal
12153 size_t str_len = t_val->u.str.val_str->size();
12154 const char *str_ptr = t_val->u.str.val_str->c_str();
12155 expr->expr = mputc(expr->expr, '"');
12156 for (size_t i = 0; i < str_len; i++)
12157 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12158 expr->expr = mputc(expr->expr, '"');
12159 } else location->generate_code_expr_mandatory(expr);
12160 } else expr->expr = mputstr(expr->expr, "NULL");
12161 // fifth argument: alive flag
12162 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12163 }
12164
12165 void Value::generate_code_expr_activate(expression_struct *expr)
12166 {
12167 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12168 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12169 FATAL_ERROR("Value::generate_code_expr_activate()");
12170 expr->expr = mputprintf(expr->expr, "%s(",
12171 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12172 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12173 expr->expr = mputc(expr->expr, ')');
12174 }
12175
12176 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12177 {
12178 Value *v_last = u.expr.v1->get_value_refd_last();
12179 if (v_last->valuetype == V_ALTSTEP) {
12180 // the referred altstep is known
12181 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12182 ->get_genname_from_scope(my_scope, "activate_").c_str());
12183 } else {
12184 // the referred altstep is unknown
12185 u.expr.v1->generate_code_expr_mandatory(expr);
12186 expr->expr = mputstr(expr->expr,".activate(");
12187 }
12188 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12189 expr->expr = mputc(expr->expr, ')');
12190 }
12191
12192 void Value::generate_code_expr_execute(expression_struct *expr)
12193 {
12194 Assignment *testcase = u.expr.r1->get_refd_assignment();
12195 expr->expr = mputprintf(expr->expr, "%s(",
12196 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12197 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12198 if (parlist->get_nof_pars() > 0) {
12199 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12200 0, false);
12201 expr->expr = mputstr(expr->expr, ", ");
12202 }
12203 if (u.expr.v2) {
12204 expr->expr = mputstr(expr->expr, "TRUE, ");
12205 u.expr.v2->generate_code_expr_mandatory(expr);
12206 expr->expr = mputc(expr->expr, ')');
12207 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12208 }
12209
12210 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12211 {
12212 Value *v_last = u.expr.v1->get_value_refd_last();
12213 if (v_last->valuetype == V_TESTCASE) {
12214 // the referred testcase is known
12215 Assignment *testcase = v_last->get_refd_fat();
12216 expr->expr = mputprintf(expr->expr, "%s(",
12217 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12218 u.expr.ap_list2->generate_code_alias(expr,
12219 testcase->get_FormalParList(), 0, false);
12220 } else {
12221 // the referred testcase is unknown
12222 u.expr.v1->generate_code_expr_mandatory(expr);
12223 expr->expr = mputstr(expr->expr,".execute(");
12224 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12225 }
12226 if (u.expr.ap_list2->get_nof_pars() > 0)
12227 expr->expr = mputstr(expr->expr, ", ");
12228 if (u.expr.v3) {
12229 expr->expr = mputstr(expr->expr, "TRUE, ");
12230 u.expr.v3->generate_code_expr_mandatory(expr);
12231 expr->expr = mputc(expr->expr, ')');
12232 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12233 }
12234
12235 void Value::generate_code_expr_invoke(expression_struct *expr)
12236 {
12237 Value *last_v = u.invoke.v->get_value_refd_last();
12238 if (last_v->get_valuetype() == V_FUNCTION) {
12239 // the referred function is known
12240 Assignment *function = last_v->get_refd_fat();
12241 expr->expr = mputprintf(expr->expr, "%s(",
12242 function->get_genname_from_scope(my_scope).c_str());
12243 u.invoke.ap_list->generate_code_alias(expr,
12244 function->get_FormalParList(), function->get_RunsOnType(), false);
12245 } else {
12246 // the referred function is unknown
12247 u.invoke.v->generate_code_expr_mandatory(expr);
12248 expr->expr = mputstr(expr->expr, ".invoke(");
12249 Type* gov_last = last_v->get_expr_governor_last();
12250 u.invoke.ap_list->generate_code_alias(expr, 0,
12251 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12252 }
12253 expr->expr = mputc(expr->expr, ')');
12254 }
12255
12256 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12257 Reference *ref)
12258 {
12259 // if the referenced value points to an optional value field the
12260 // generated code has to be corrected at the end:
12261 // `fieldid()' => `fieldid()()'
12262 Assignment *ass = ref->get_refd_assignment();
12263 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12264 switch (ass->get_asstype()) {
12265 case Assignment::A_CONST:
12266 case Assignment::A_EXT_CONST:
12267 case Assignment::A_MODULEPAR:
12268 case Assignment::A_VAR:
12269 case Assignment::A_FUNCTION_RVAL:
12270 case Assignment::A_EXT_FUNCTION_RVAL:
12271 case Assignment::A_PAR_VAL_IN:
12272 case Assignment::A_PAR_VAL_OUT:
12273 case Assignment::A_PAR_VAL_INOUT:
12274 // only these are mapped to value objects
12275 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12276 expr->expr = mputstr(expr->expr, "()");
12277 break;
12278 default:
12279 break;
12280 }
12281 }
12282
12283 void Value::generate_code_expr_encode(expression_struct *expr)
12284 {
12285 Value* v1 = 0;
12286
12287 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12288 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12289 v1 = templ->get_specific_value();
12290 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12291
12292 expression_struct expr2;
12293 Code::init_expr(&expr2);
12294
12295 bool is_templ = false;
12296 switch (templ->get_templatetype()) {
12297 case Template::SPECIFIC_VALUE:
12298 v1->generate_code_expr_mandatory(&expr2);
12299 break;
12300 default:
12301 u.expr.ti1->generate_code(&expr2);
12302 is_templ = true;
12303 break;
12304 }
12305
12306 if (!gov_last->is_coding_by_function()) {
12307 const string& tmp_id = get_temporary_id();
12308 const string& tmp_buf_id = get_temporary_id();
12309 const string& tmp_ref_id = get_temporary_id();
12310 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12311 tmp_id.c_str());
12312 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12313 tmp_buf_id.c_str());
12314 if (expr2.preamble) { // copy preamble setting up the argument, if any
12315 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12316 expr->preamble = mputc (expr->preamble, '\n');
12317 }
12318 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12319 gov_last->get_genname_typedescriptor(
12320 u.expr.ti1->get_Template()->get_my_scope()
12321 ).c_str(),
12322 tmp_ref_id.c_str(),
12323 expr2.expr);
12324 if (is_templ) // make a value out of the template, if needed
12325 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12326 expr->preamble = mputprintf(expr->preamble,
12327 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12328 tmp_ref_id.c_str(),
12329 gov_last->get_genname_typedescriptor(
12330 u.expr.ti1->get_Template()->get_my_scope()
12331 ).c_str(),
12332 tmp_buf_id.c_str(),
12333 gov_last->get_coding(true).c_str()
12334 );
12335 expr->preamble = mputstr(expr->preamble, ");\n");
12336 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12337 tmp_buf_id.c_str(),
12338 tmp_id.c_str()
12339 );
12340 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12341 if (expr2.postamble)
12342 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12343 } else
12344 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12345 gov_last->get_coding(true).c_str(), expr2.expr,
12346 is_templ ? ".valueof()" : "");
12347 Code::free_expr(&expr2);
12348 }
12349
12350 void Value::generate_code_expr_decode(expression_struct *expr)
12351 {
12352 expression_struct expr1, expr2;
12353 Code::init_expr(&expr1);
12354 Code::init_expr(&expr2);
12355 u.expr.r1->generate_code(&expr1);
12356 u.expr.r2->generate_code(&expr2);
12357
12358 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12359 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12360 get_type_refd_last();
12361
12362 if (expr1.preamble)
12363 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12364 if (expr2.preamble)
12365 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12366
12367 if (!_type->is_coding_by_function()) {
12368 const string& tmp_id = get_temporary_id();
12369 const string& buffer_id = get_temporary_id();
12370 const string& retval_id = get_temporary_id();
12371 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12372 field_is_optional(u.expr.r2->get_subrefs());
12373
12374 expr->preamble = mputprintf(expr->preamble,
12375 "TTCN_Buffer %s(bit2oct(%s));\n"
12376 "INTEGER %s;\n"
12377 "TTCN_EncDec::set_error_behavior("
12378 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12379 "TTCN_EncDec::clear_error();\n",
12380 buffer_id.c_str(),
12381 expr1.expr,
12382 retval_id.c_str()
12383 );
12384 expr->preamble = mputprintf(expr->preamble,
12385 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12386 expr2.expr,
12387 optional ? "()" : "",
12388 _type->get_genname_typedescriptor(
12389 u.expr.r2->get_my_scope()
12390 ).c_str(),
12391 buffer_id.c_str(),
12392 _type->get_coding(false).c_str()
12393 );
12394 expr->preamble = mputprintf(expr->preamble,
12395 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12396 "case TTCN_EncDec::ET_NONE: {\n"
12397 "%s.cut();\n"
12398 "OCTETSTRING %s;\n"
12399 "%s.get_string(%s);\n"
12400 "%s = oct2bit(%s);\n"
12401 "%s = 0;\n"
12402 "}break;\n"
12403 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12404 "case TTCN_EncDec::ET_LEN_ERR:\n"
12405 "%s = 2;\n"
12406 "break;\n"
12407 "default:\n"
12408 "%s = 1;\n"
12409 "}\n"
12410 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12411 "TTCN_EncDec::EB_DEFAULT);\n"
12412 "TTCN_EncDec::clear_error();\n",
12413 buffer_id.c_str(),
12414 tmp_id.c_str(),
12415 buffer_id.c_str(),
12416 tmp_id.c_str(),
12417 expr1.expr,
12418 tmp_id.c_str(),
12419 retval_id.c_str(),
12420 retval_id.c_str(),
12421 retval_id.c_str()
12422 );
12423 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12424 } else
12425 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12426 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12427 if (expr1.postamble)
12428 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12429 if (expr2.postamble)
12430 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12431 Code::free_expr(&expr1);
12432 Code::free_expr(&expr2);
12433 }
12434
12435 char *Value::generate_code_init_choice(char *str, const char *name)
12436 {
12437 const char *alt_name = u.choice.alt_name->get_name().c_str();
12438 // Safe as long as get_name() returns a const string&, not a temporary.
12439 const char *alt_prefix =
12440 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12441 ? "AT_" : "";
12442 if (u.choice.alt_value->needs_temp_ref()) {
12443 const string& tmp_id = get_temporary_id();
12444 const char *tmp_id_str = tmp_id.c_str();
12445 str = mputprintf(str, "{\n"
12446 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12447 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12448 alt_prefix, alt_name);
12449 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12450 str = mputstr(str, "}\n");
12451 } else {
12452 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12453 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12454 Free(embedded_name);
12455 }
12456 return str;
12457 }
12458
12459 char *Value::generate_code_init_seof(char *str, const char *name)
12460 {
12461 size_t nof_vs = u.val_vs->get_nof_vs();
12462 if (nof_vs > 0) {
12463 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12464 const string& embedded_type =
12465 my_governor->get_ofType()->get_genname_value(my_scope);
12466 const char *embedded_type_str = embedded_type.c_str();
12467 for (size_t i = 0; i < nof_vs; i++) {
12468 Value *comp_v = u.val_vs->get_v_byIndex(i);
12469
12470 if (comp_v->valuetype == V_NOTUSED) continue;
12471 else if (comp_v->needs_temp_ref()) {
12472 const string& tmp_id = get_temporary_id();
12473 const char *tmp_id_str = tmp_id.c_str();
12474 str = mputprintf(str, "{\n"
12475 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12476 (unsigned long) i);
12477 str = comp_v->generate_code_init(str, tmp_id_str);
12478 str = mputstr(str, "}\n");
12479 } else {
12480 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12481 str = comp_v->generate_code_init(str, embedded_name);
12482 Free(embedded_name);
12483 }
12484 }
12485 } else {
12486 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12487 }
12488 return str;
12489 }
12490
12491 char *Value::generate_code_init_indexed(char *str, const char *name)
12492 {
12493 size_t nof_ivs = u.val_vs->get_nof_ivs();
12494 if (nof_ivs > 0) {
12495 // Previous values can be truncated. The concept is similar to
12496 // templates.
12497 Type *t_last = my_governor->get_type_refd_last();
12498 const string& oftype_name =
12499 t_last->get_ofType()->get_genname_value(my_scope);
12500 const char *oftype_name_str = oftype_name.c_str();
12501 for (size_t i = 0; i < nof_ivs; i++) {
12502 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12503 const string& tmp_id_1 = get_temporary_id();
12504 str = mputstr(str, "{\n");
12505 Value *index = iv->get_index();
12506 if (index->get_valuetype() != V_INT) {
12507 const string& tmp_id_2 = get_temporary_id();
12508 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12509 str = index->generate_code_init(str, tmp_id_2.c_str());
12510 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12511 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12512 } else {
12513 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12514 tmp_id_1.c_str(), name,
12515 (index->get_val_Int()->t_str()).c_str());
12516 }
12517 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12518 str = mputstr(str, "}\n");
12519 }
12520 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12521 return str;
12522 }
12523
12524 char *Value::generate_code_init_array(char *str, const char *name)
12525 {
12526 size_t nof_vs = u.val_vs->get_nof_vs();
12527 Type *t_last = my_governor->get_type_refd_last();
12528 Int index_offset = t_last->get_dimension()->get_offset();
12529 const string& embedded_type =
12530 t_last->get_ofType()->get_genname_value(my_scope);
12531 const char *embedded_type_str = embedded_type.c_str();
12532 for (size_t i = 0; i < nof_vs; i++) {
12533 Value *comp_v = u.val_vs->get_v_byIndex(i);
12534 if (comp_v->valuetype == V_NOTUSED) continue;
12535 else if (comp_v->needs_temp_ref()) {
12536 const string& tmp_id = get_temporary_id();
12537 const char *tmp_id_str = tmp_id.c_str();
12538 str = mputprintf(str, "{\n"
12539 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12540 Int2string(index_offset + i).c_str());
12541 str = comp_v->generate_code_init(str, tmp_id_str);
12542 str = mputstr(str, "}\n");
12543 } else {
12544 char *embedded_name = mprintf("%s[%s]", name,
12545 Int2string(index_offset + i).c_str());
12546 str = comp_v->generate_code_init(str, embedded_name);
12547 Free(embedded_name);
12548 }
12549 }
12550 return str;
12551 }
12552
12553 char *Value::generate_code_init_se(char *str, const char *name)
12554 {
12555 Type *type = my_governor->get_type_refd_last();
12556 size_t nof_comps = type->get_nof_comps();
12557 if (nof_comps > 0) {
12558 for (size_t i = 0; i < nof_comps; i++) {
12559 CompField *cf = type->get_comp_byIndex(i);
12560 const Identifier& field_id = cf->get_name();
12561 const char *field_name = field_id.get_name().c_str();
12562 Value *field_v;
12563 if (u.val_nvs->has_nv_withName(field_id)) {
12564 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12565 if (field_v->valuetype == V_NOTUSED) continue;
12566 if (field_v->valuetype == V_OMIT) field_v = 0;
12567 } else if (is_asn1()) {
12568 if (cf->has_default()) {
12569 // handle like a referenced value
12570 Value *defval = cf->get_defval();
12571 if (needs_init_precede(defval)) {
12572 str = defval->generate_code_init(str,
12573 defval->get_lhs_name().c_str());
12574 }
12575 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12576 defval->get_genname_own(my_scope).c_str());
12577 continue;
12578 } else {
12579 if (!cf->get_is_optional())
12580 FATAL_ERROR("Value::generate_code_init()");
12581 field_v = 0;
12582 }
12583 } else {
12584 continue;
12585 }
12586 if (field_v) {
12587 // the value is not omit
12588 if (field_v->needs_temp_ref()) {
12589 const string& tmp_id = get_temporary_id();
12590 const char *tmp_id_str = tmp_id.c_str();
12591 str = mputprintf(str, "{\n"
12592 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12593 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12594 field_name);
12595 str = field_v->generate_code_init(str, tmp_id_str);
12596 str = mputstr(str, "}\n");
12597 } else {
12598 char *embedded_name = mprintf("%s.%s()", name,
12599 field_name);
12600 if (cf->get_is_optional() && field_v->is_compound())
12601 embedded_name = mputstr(embedded_name, "()");
12602 str = field_v->generate_code_init(str, embedded_name);
12603 Free(embedded_name);
12604 }
12605 } else {
12606 // the value is omit
12607 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12608 name, field_name);
12609 }
12610 }
12611 } else {
12612 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12613 }
12614 return str;
12615 }
12616
12617 char *Value::generate_code_init_refd(char *str, const char *name)
12618 {
12619 Value *v = get_value_refd_last();
12620 if (v == this) {
12621 // the referred value is not available at compile time
12622 // the code generation is based on the reference
12623 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
12624 str = TypeConv::gen_conv_code_refd(str, name, v);
12625 } else {
12626 expression_struct expr;
12627 Code::init_expr(&expr);
12628 expr.expr = mputprintf(expr.expr, "%s = ", name);
12629 u.ref.ref->generate_code_const_ref(&expr);
12630 str = Code::merge_free_expr(str, &expr);
12631 }
12632 } else {
12633 // the referred value is available at compile time
12634 // the code generation is based on the referred value
12635 if (v->has_single_expr() &&
12636 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
12637 // simple substitution for in-line values within the same module
12638 str = mputprintf(str, "%s = %s;\n", name,
12639 v->get_single_expr().c_str());
12640 } else {
12641 // use a simple reference to reduce code size
12642 if (needs_init_precede(v)) {
12643 // the referred value must be initialized first
12644 if (!v->is_toplevel() && v->needs_temp_ref()) {
12645 // temporary id should be introduced for the lhs
12646 const string& tmp_id = get_temporary_id();
12647 const char *tmp_id_str = tmp_id.c_str();
12648 str = mputprintf(str, "{\n"
12649 "%s& %s = %s;\n",
12650 v->get_my_governor()->get_genname_value(my_scope).c_str(),
12651 tmp_id_str, v->get_lhs_name().c_str());
12652 str = v->generate_code_init(str, tmp_id_str);
12653 str = mputstr(str, "}\n");
12654 } else {
12655 str = v->generate_code_init(str, v->get_lhs_name().c_str());
12656 }
12657 }
12658 str = mputprintf(str, "%s = %s;\n", name,
12659 v->get_genname_own(my_scope).c_str());
12660 }
12661 }
12662 return str;
12663 }
12664
12665 void Value::generate_json_value(JSON_Tokenizer& json,
12666 bool allow_special_float, /* = true */
12667 bool union_value_list, /* = false */
12668 Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
12669 {
12670 switch (valuetype) {
12671 case V_INT:
12672 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
12673 break;
12674 case V_REAL: {
12675 Real r = get_val_Real();
12676 if (r == REAL_INFINITY) {
12677 if (allow_special_float) {
12678 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
12679 }
12680 }
12681 else if (r == -REAL_INFINITY) {
12682 if (allow_special_float) {
12683 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
12684 }
12685 }
12686 else if (r != r) {
12687 if (allow_special_float) {
12688 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
12689 }
12690 }
12691 else {
12692 // true if decimal representation possible (use %f format)
12693 bool decimal_repr = (r == 0.0)
12694 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
12695 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
12696 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
12697 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
12698 Free(number_str);
12699 }
12700 break; }
12701 case V_BOOL:
12702 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
12703 break;
12704 case V_BSTR:
12705 case V_HSTR:
12706 case V_OSTR:
12707 case V_CSTR: {
12708 char* str = convert_to_json_string(get_val_str().c_str());
12709 json.put_next_token(JSON_TOKEN_STRING, str);
12710 Free(str);
12711 break; }
12712 case V_USTR: {
12713 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
12714 json.put_next_token(JSON_TOKEN_STRING, str);
12715 Free(str);
12716 break; }
12717 case V_VERDICT:
12718 case V_ENUM:
12719 json.put_next_token(JSON_TOKEN_STRING,
12720 (string('\"') + create_stringRepr() + string('\"')).c_str());
12721 break;
12722 case V_SEQOF:
12723 case V_SETOF:
12724 json.put_next_token(JSON_TOKEN_ARRAY_START);
12725 if (!u.val_vs->is_indexed()) {
12726 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
12727 u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
12728 union_value_list, omit_combo);
12729 }
12730 }
12731 else {
12732 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
12733 // look for the entry with index equal to i
12734 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
12735 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
12736 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
12737 allow_special_float, union_value_list, omit_combo);
12738 break;
12739 }
12740 }
12741 }
12742 }
12743 json.put_next_token(JSON_TOKEN_ARRAY_END);
12744 break;
12745 case V_SEQ:
12746 case V_SET: {
12747 // omitted fields have 2 possible JSON values (the field is absent, or it's
12748 // present with value 'null'), each combination of omitted values must be
12749 // generated
12750 if (omit_combo == NULL) {
12751 FATAL_ERROR("Value::generate_json_value - no combo");
12752 }
12753 size_t len = get_nof_comps();
12754 // generate the JSON object from the present combination
12755 json.put_next_token(JSON_TOKEN_OBJECT_START);
12756 for (size_t i = 0; i < len; ++i) {
12757 Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
12758 if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
12759 // the field is absent, don't insert anything
12760 continue;
12761 }
12762 // use the field's alias, if it has one
12763 const char* alias = NULL;
12764 if (my_governor != NULL) {
12765 JsonAST* field_attrib = my_governor->get_comp_byName(
12766 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
12767 if (field_attrib != NULL) {
12768 alias = field_attrib->alias;
12769 }
12770 }
12771 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
12772 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
12773 if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
12774 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
12775 }
12776 else {
12777 get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
12778 allow_special_float, union_value_list, omit_combo);
12779 }
12780 }
12781 json.put_next_token(JSON_TOKEN_OBJECT_END);
12782 break; }
12783 case V_CHOICE: {
12784 bool as_value = !union_value_list && my_governor != NULL &&
12785 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
12786 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
12787 if (!as_value) {
12788 // no 'as value' coding instruction, insert an object with one field
12789 json.put_next_token(JSON_TOKEN_OBJECT_START);
12790 // use the field's alias, if it has one
12791 const char* alias = NULL;
12792 if (my_governor != NULL) {
12793 JsonAST* field_attrib = my_governor->get_comp_byName(
12794 get_alt_name())->get_type()->get_json_attributes();
12795 if (field_attrib != NULL) {
12796 alias = field_attrib->alias;
12797 }
12798 }
12799 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
12800 get_alt_name().get_ttcnname().c_str());
12801 }
12802 get_alt_value()->generate_json_value(json, allow_special_float,
12803 union_value_list, omit_combo);
12804 if (!as_value) {
12805 json.put_next_token(JSON_TOKEN_OBJECT_END);
12806 }
12807 break; }
12808 case V_REFD: {
12809 Value* v = get_value_refd_last();
12810 if (this != v) {
12811 v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
12812 return;
12813 }
12814 } // no break
12815 default:
12816 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
12817 }
12818 }
12819
12820 bool Value::explicit_cast_needed(bool forIsValue)
12821 {
12822 Value *v_last = get_value_refd_last();
12823 if (v_last != this) {
12824 // this is a foldable referenced value
12825 // if the reference points to an imported or compound value the code
12826 // generation will be based on the reference so cast is not needed
12827 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
12828 || !v_last->has_single_expr()) return false;
12829 } else if (v_last->valuetype == V_REFD) {
12830 // this is an unfoldable reference (v_last==this)
12831 // explicit cast is needed only for string element references
12832 if (forIsValue) return false;
12833 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
12834 return t_subrefs && t_subrefs->refers_to_string_element();
12835 }
12836 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
12837 Type *t_governor = v_last->my_governor->get_type_refd_last();
12838 switch (t_governor->get_typetype()) {
12839 case Type::T_NULL:
12840 case Type::T_BOOL:
12841 case Type::T_INT:
12842 case Type::T_INT_A:
12843 case Type::T_REAL:
12844 case Type::T_ENUM_A:
12845 case Type::T_ENUM_T:
12846 case Type::T_VERDICT:
12847 case Type::T_COMPONENT:
12848 // these are mapped to built-in C/C++ types
12849 return true;
12850 case Type::T_SEQ_A:
12851 case Type::T_SEQ_T:
12852 case Type::T_SET_A:
12853 case Type::T_SET_T:
12854 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
12855 return t_governor->get_nof_comps() == 0;
12856 case Type::T_SEQOF:
12857 case Type::T_SETOF:
12858 // the C++ equivalent of value {} is ambiguous
12859 // tr926
12860 return true;
12861 case Type::T_FUNCTION:
12862 case Type::T_ALTSTEP:
12863 case Type::T_TESTCASE:
12864 return true;
12865 default:
12866 return false;
12867 }
12868 }
12869
12870 bool Value::has_single_expr()
12871 {
12872 if (get_needs_conversion()) return false;
12873 switch (valuetype) {
12874 case V_EXPR:
12875 return has_single_expr_expr();
12876 case V_CHOICE:
12877 case V_ARRAY:
12878 // a union or array value cannot be represented as an in-line expression
12879 return false;
12880 case V_SEQOF:
12881 case V_SETOF:
12882 // only an empty record/set of value can be represented as an in-line
12883 // expression
12884 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
12885 else return u.val_vs->get_nof_ivs() == 0;
12886 case V_SEQ:
12887 case V_SET: {
12888 // only a value for an empty record/set type can be represented as an
12889 // in-line expression
12890 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
12891 Type *type = my_governor->get_type_refd_last();
12892 return type->get_nof_comps() == 0; }
12893 case V_REFD: {
12894 Value *v_last = get_value_refd_last();
12895 // If the above call hit an error and set_valuetype(V_ERROR),
12896 // then u.ref.ref has been freed. Avoid the segfault.
12897 if (valuetype == V_ERROR)
12898 return false;
12899 if (v_last != this && v_last->has_single_expr() &&
12900 v_last->my_scope->get_scope_mod_gen() ==
12901 my_scope->get_scope_mod_gen()) return true;
12902 else return u.ref.ref->has_single_expr(); }
12903 case V_INVOKE:
12904 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
12905 case V_ERROR:
12906 case V_NAMEDINT:
12907 case V_NAMEDBITS:
12908 case V_UNDEF_LOWERID:
12909 case V_UNDEF_BLOCK:
12910 case V_REFER:
12911 // these values cannot occur during code generation
12912 FATAL_ERROR("Value::has_single_expr()");
12913 case V_INT:
12914 return u.val_Int->is_native_fit();
12915 case V_NOTUSED:
12916 // should only happen when generating code for an unbound record/set value
12917 return false;
12918 default:
12919 // other value types (literal values) do not need temporary reference
12920 return true;
12921 }
12922 }
12923
12924 string Value::get_single_expr()
12925 {
12926 switch (valuetype) {
12927 case V_NULL:
12928 return string("ASN_NULL_VALUE");
12929 case V_BOOL:
12930 return string(u.val_bool ? "TRUE" : "FALSE");
12931 case V_INT:
12932 if (u.val_Int->is_native_fit()) { // Be sure.
12933 return u.val_Int->t_str();
12934 } else {
12935 // get_single_expr may be called only if has_single_expr() is true.
12936 // The only exception is V_INT, where get_single_expr may be called
12937 // even if is_native_fit (which is used to implement has_single_expr)
12938 // returns false.
12939 string ret_val('"');
12940 ret_val += u.val_Int->t_str();
12941 ret_val += '"';
12942 return ret_val;
12943 }
12944 case V_REAL:
12945 return Real2code(u.val_Real);
12946 case V_ENUM:
12947 return get_single_expr_enum();
12948 case V_BSTR:
12949 return get_my_scope()->get_scope_mod_gen()
12950 ->add_bitstring_literal(*u.str.val_str);
12951 case V_HSTR:
12952 return get_my_scope()->get_scope_mod_gen()
12953 ->add_hexstring_literal(*u.str.val_str);
12954 case V_OSTR:
12955 return get_my_scope()->get_scope_mod_gen()
12956 ->add_octetstring_literal(*u.str.val_str);
12957 case V_CSTR:
12958 return get_my_scope()->get_scope_mod_gen()
12959 ->add_charstring_literal(*u.str.val_str);
12960 case V_USTR:
12961 if (u.ustr.convert_str) {
12962 set_valuetype(V_CSTR);
12963 return get_my_scope()->get_scope_mod_gen()
12964 ->add_charstring_literal(*u.str.val_str);
12965 } else
12966 return get_my_scope()->get_scope_mod_gen()
12967 ->add_ustring_literal(*u.ustr.val_ustr);
12968 case V_ISO2022STR:
12969 return get_single_expr_iso2022str();
12970 case V_OID:
12971 case V_ROID: {
12972 vector<string> comps;
12973 bool is_constant = get_oid_comps(comps);
12974 size_t nof_comps = comps.size();
12975 string oi_str;
12976 for (size_t i = 0; i < nof_comps; i++) {
12977 if (i > 0) oi_str += ", ";
12978 oi_str += *(comps[i]);
12979 }
12980 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
12981 comps.clear();
12982 if (is_constant) {
12983 // the objid only contains constants
12984 // => create a literal and return its name
12985 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
12986 }
12987 // the objid contains at least one variable
12988 // => append the number of components before the component values in the string and return it
12989 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
12990 case V_SEQOF:
12991 case V_SETOF:
12992 if (u.val_vs->get_nof_vs() > 0)
12993 FATAL_ERROR("Value::get_single_expr()");
12994 return string("NULL_VALUE");
12995 case V_SEQ:
12996 case V_SET:
12997 if (u.val_nvs->get_nof_nvs() > 0)
12998 FATAL_ERROR("Value::get_single_expr()");
12999 return string("NULL_VALUE");
13000 case V_REFD: {
13001 Value *v_last = get_value_refd_last();
13002 if (v_last != this && v_last->has_single_expr() &&
13003 v_last->my_scope->get_scope_mod_gen() ==
13004 my_scope->get_scope_mod_gen()) {
13005 // the reference points to another single value in the same module
13006 return v_last->get_single_expr();
13007 } else {
13008 // convert the reference to a single expression
13009 expression_struct expr;
13010 Code::init_expr(&expr);
13011 u.ref.ref->generate_code_const_ref(&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 } }
13018 case V_OMIT:
13019 return string("OMIT_VALUE");
13020 case V_VERDICT:
13021 switch (u.verdict) {
13022 case Verdict_NONE:
13023 return string("NONE");
13024 case Verdict_PASS:
13025 return string("PASS");
13026 case Verdict_INCONC:
13027 return string("INCONC");
13028 case Verdict_FAIL:
13029 return string("FAIL");
13030 case Verdict_ERROR:
13031 return string("ERROR");
13032 default:
13033 FATAL_ERROR("Value::get_single_expr()");
13034 return string();
13035 }
13036 case V_DEFAULT_NULL:
13037 return string("NULL_COMPREF");
13038 case V_FAT_NULL: {
13039 string ret_val('(');
13040 ret_val += my_governor->get_genname_value(my_scope);
13041 ret_val += "::function_pointer)Module_List::get_fat_null()";
13042 return ret_val; }
13043 case V_EXPR:
13044 case V_INVOKE: {
13045 expression_struct expr;
13046 Code::init_expr(&expr);
13047 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13048 else generate_code_expr_invoke(&expr);
13049 if (expr.preamble || expr.postamble)
13050 FATAL_ERROR("Value::get_single_expr()");
13051 string ret_val(expr.expr);
13052 Code::free_expr(&expr);
13053 return ret_val; }
13054 case V_MACRO:
13055 switch (u.macro) {
13056 case MACRO_TESTCASEID:
13057 return string("TTCN_Runtime::get_testcase_id_macro()");
13058 default:
13059 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13060 return string();
13061 }
13062 case V_FUNCTION:
13063 case V_ALTSTEP:
13064 case V_TESTCASE:
13065 return get_single_expr_fat();
13066 default:
13067 FATAL_ERROR("Value::get_single_expr()");
13068 return string();
13069 }
13070 }
13071
13072 bool Value::has_single_expr_expr()
13073 {
13074 switch (u.expr.v_optype) {
13075 case OPTYPE_RND: // -
13076 case OPTYPE_COMP_NULL:
13077 case OPTYPE_COMP_MTC:
13078 case OPTYPE_COMP_SYSTEM:
13079 case OPTYPE_COMP_SELF:
13080 case OPTYPE_COMP_RUNNING_ANY:
13081 case OPTYPE_COMP_RUNNING_ALL:
13082 case OPTYPE_COMP_ALIVE_ANY:
13083 case OPTYPE_COMP_ALIVE_ALL:
13084 case OPTYPE_TMR_RUNNING_ANY:
13085 case OPTYPE_GETVERDICT:
13086 case OPTYPE_TESTCASENAME:
13087 case OPTYPE_PROF_RUNNING:
13088 return true;
13089 case OPTYPE_ENCODE:
13090 case OPTYPE_DECODE:
13091 case OPTYPE_ISBOUND:
13092 case OPTYPE_ISPRESENT:
13093 case OPTYPE_TTCN2STRING:
13094 return false;
13095 case OPTYPE_UNARYPLUS: // v1
13096 case OPTYPE_UNARYMINUS:
13097 case OPTYPE_NOT:
13098 case OPTYPE_NOT4B:
13099 case OPTYPE_BIT2HEX:
13100 case OPTYPE_BIT2INT:
13101 case OPTYPE_BIT2OCT:
13102 case OPTYPE_BIT2STR:
13103 case OPTYPE_CHAR2INT:
13104 case OPTYPE_CHAR2OCT:
13105 case OPTYPE_FLOAT2INT:
13106 case OPTYPE_FLOAT2STR:
13107 case OPTYPE_HEX2BIT:
13108 case OPTYPE_HEX2INT:
13109 case OPTYPE_HEX2OCT:
13110 case OPTYPE_HEX2STR:
13111 case OPTYPE_INT2CHAR:
13112 case OPTYPE_INT2FLOAT:
13113 case OPTYPE_INT2STR:
13114 case OPTYPE_INT2UNICHAR:
13115 case OPTYPE_OCT2BIT:
13116 case OPTYPE_OCT2CHAR:
13117 case OPTYPE_OCT2HEX:
13118 case OPTYPE_OCT2INT:
13119 case OPTYPE_OCT2STR:
13120 case OPTYPE_STR2BIT:
13121 case OPTYPE_STR2FLOAT:
13122 case OPTYPE_STR2HEX:
13123 case OPTYPE_STR2INT:
13124 case OPTYPE_STR2OCT:
13125 case OPTYPE_UNICHAR2INT:
13126 case OPTYPE_UNICHAR2CHAR:
13127 case OPTYPE_ENUM2INT:
13128 case OPTYPE_RNDWITHVAL:
13129 case OPTYPE_ISCHOSEN_V: // v1 i2
13130 case OPTYPE_COMP_RUNNING:
13131 case OPTYPE_COMP_ALIVE:
13132 case OPTYPE_GET_STRINGENCODING:
13133 case OPTYPE_REMOVE_BOM:
13134 case OPTYPE_DECODE_BASE64:
13135 return u.expr.v1->has_single_expr();
13136 case OPTYPE_ISCHOSEN_T: // t1 i2
13137 return u.expr.t1->has_single_expr();
13138 case OPTYPE_ADD: // v1 v2
13139 case OPTYPE_SUBTRACT:
13140 case OPTYPE_MULTIPLY:
13141 case OPTYPE_DIVIDE:
13142 case OPTYPE_MOD:
13143 case OPTYPE_REM:
13144 case OPTYPE_CONCAT:
13145 case OPTYPE_EQ:
13146 case OPTYPE_LT:
13147 case OPTYPE_GT:
13148 case OPTYPE_NE:
13149 case OPTYPE_GE:
13150 case OPTYPE_LE:
13151 case OPTYPE_XOR:
13152 case OPTYPE_AND4B:
13153 case OPTYPE_OR4B:
13154 case OPTYPE_XOR4B:
13155 case OPTYPE_SHL:
13156 case OPTYPE_SHR:
13157 case OPTYPE_ROTL:
13158 case OPTYPE_ROTR:
13159 case OPTYPE_INT2BIT:
13160 case OPTYPE_INT2HEX:
13161 case OPTYPE_INT2OCT:
13162 return u.expr.v1->has_single_expr() &&
13163 u.expr.v2->has_single_expr();
13164 case OPTYPE_UNICHAR2OCT:
13165 case OPTYPE_OCT2UNICHAR:
13166 case OPTYPE_ENCODE_BASE64:
13167 return u.expr.v1->has_single_expr() &&
13168 (!u.expr.v2 || u.expr.v2->has_single_expr());
13169 case OPTYPE_AND:
13170 case OPTYPE_OR:
13171 return u.expr.v1->has_single_expr() &&
13172 u.expr.v2->has_single_expr() &&
13173 !u.expr.v2->needs_short_circuit();
13174 case OPTYPE_SUBSTR:
13175 return u.expr.ti1->has_single_expr() &&
13176 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13177 case OPTYPE_REGEXP:
13178 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13179 u.expr.v3->has_single_expr();
13180 case OPTYPE_DECOMP: // v1 v2 v3
13181 return u.expr.v1->has_single_expr() &&
13182 u.expr.v2->has_single_expr() &&
13183 u.expr.v3->has_single_expr();
13184 case OPTYPE_REPLACE:
13185 return u.expr.ti1->has_single_expr() &&
13186 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13187 u.expr.ti4->has_single_expr();
13188 case OPTYPE_ISVALUE: // ti1
13189 case OPTYPE_LENGTHOF: // ti1
13190 case OPTYPE_SIZEOF: // ti1
13191 case OPTYPE_VALUEOF: // ti1
13192 return u.expr.ti1->has_single_expr();
13193 case OPTYPE_LOG2STR:
13194 return u.expr.logargs->has_single_expr();
13195 case OPTYPE_MATCH: // v1 t2
13196 return u.expr.v1->has_single_expr() &&
13197 u.expr.t2->has_single_expr();
13198 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13199 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13200 (!u.expr.v3 || u.expr.v3->has_single_expr());
13201 case OPTYPE_TMR_READ: // r1
13202 case OPTYPE_TMR_RUNNING:
13203 case OPTYPE_ACTIVATE:
13204 return u.expr.r1->has_single_expr();
13205 case OPTYPE_EXECUTE: // r1 [v2]
13206 return u.expr.r1->has_single_expr() &&
13207 (!u.expr.v2 || u.expr.v2->has_single_expr());
13208 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13209 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13210 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13211 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13212 (!u.expr.v3 || u.expr.v3->has_single_expr());
13213 default:
13214 FATAL_ERROR("Value::has_single_expr_expr()");
13215 } // switch
13216 }
13217
13218 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13219 {
13220 if (!v->has_single_expr()) return false;
13221 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13222 if (!ap_list->get_par(i)->has_single_expr()) return false;
13223 return true;
13224 }
13225
13226 string Value::get_single_expr_enum()
13227 {
13228 string ret_val(my_governor->get_genname_value(my_scope));
13229 ret_val += "::";
13230 ret_val += u.val_id->get_name();
13231 return ret_val;
13232 }
13233
13234 string Value::get_single_expr_iso2022str()
13235 {
13236 string ret_val;
13237 Type *type = get_my_governor()->get_type_refd_last();
13238 switch (type->get_typetype()) {
13239 case Type::T_TELETEXSTRING:
13240 ret_val += "TTCN_ISO2022_2_TeletexString";
13241 break;
13242 case Type::T_VIDEOTEXSTRING:
13243 ret_val += "TTCN_ISO2022_2_VideotexString";
13244 break;
13245 case Type::T_GRAPHICSTRING:
13246 case Type::T_OBJECTDESCRIPTOR:
13247 ret_val += "TTCN_ISO2022_2_GraphicString";
13248 break;
13249 case Type::T_GENERALSTRING:
13250 ret_val += "TTCN_ISO2022_2_GeneralString";
13251 break;
13252 default:
13253 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13254 } // switch
13255 ret_val += '(';
13256 string *ostr = char2oct(*u.str.val_str);
13257 ret_val += get_my_scope()->get_scope_mod_gen()
13258 ->add_octetstring_literal(*ostr);
13259 delete ostr;
13260 ret_val += ')';
13261 return ret_val;
13262 }
13263
13264 string Value::get_single_expr_fat()
13265 {
13266 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13267 // the ampersand operator is not really necessary to obtain the function
13268 // pointer, but some older versions of GCC cannot instantiate the
13269 // appropriate operator=() member of class OPTIONAL when necessary
13270 // if only the function name is given
13271 string ret_val('&');
13272 switch (valuetype) {
13273 case V_FUNCTION:
13274 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13275 break;
13276 case V_ALTSTEP:
13277 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13278 ret_val += "_instance";
13279 break;
13280 case V_TESTCASE:
13281 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13282 break;
13283 default:
13284 FATAL_ERROR("Value::get_single_expr_fat()");
13285 }
13286 return ret_val;
13287 }
13288
13289 bool Value::is_compound()
13290 {
13291 switch (valuetype) {
13292 case V_CHOICE:
13293 case V_SEQOF:
13294 case V_SETOF:
13295 case V_ARRAY:
13296 case V_SEQ:
13297 case V_SET:
13298 return true;
13299 default:
13300 return false;
13301 }
13302 }
13303
13304 bool Value::needs_temp_ref()
13305 {
13306 switch (valuetype) {
13307 case V_SEQOF:
13308 case V_SETOF:
13309 if (!is_indexed()) {
13310 // Temporary reference is needed if the value has at least one real
13311 // element (i.e. it is not empty or contains only not used symbols).
13312 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13313 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13314 }
13315 } else {
13316 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13317 if (u.val_vs->get_iv_byIndex(i)->get_value()
13318 ->valuetype != V_NOTUSED)
13319 return true;
13320 }
13321 }
13322 return false;
13323 case V_ARRAY: {
13324 size_t nof_real_vs = 0;
13325 if (!is_indexed()) {
13326 // Temporary reference is needed if the array value has at least two
13327 // real elements (excluding not used symbols).
13328 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13329 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13330 nof_real_vs++;
13331 if (nof_real_vs > 1) return true;
13332 }
13333 }
13334 } else {
13335 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13336 if (u.val_vs->get_iv_byIndex(i)->get_value()
13337 ->valuetype != V_NOTUSED) {
13338 nof_real_vs++;
13339 if (nof_real_vs > 1) return true;
13340 }
13341 }
13342 }
13343 return false; }
13344 case V_SEQ:
13345 case V_SET:
13346 if (is_asn1()) {
13347 // it depends on the type since fields with omit or default value
13348 // may not be present
13349 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13350 } else {
13351 // incomplete values are allowed in TTCN-3
13352 // we should check the number of value components
13353 return u.val_nvs->get_nof_nvs() > 1;
13354 }
13355 case V_ERROR:
13356 case V_NAMEDINT:
13357 case V_NAMEDBITS:
13358 case V_UNDEF_LOWERID:
13359 case V_UNDEF_BLOCK:
13360 case V_TTCN3_NULL:
13361 // these values cannot occur during code generation
13362 FATAL_ERROR("Value::needs_temp_ref()");
13363 case V_INT:
13364 return !u.val_Int->is_native();
13365 default:
13366 // other value types (literal values) do not need temporary reference
13367 return false;
13368 }
13369 }
13370
13371 bool Value::needs_short_circuit()
13372 {
13373 switch (valuetype) {
13374 case V_BOOL:
13375 return false;
13376 case V_REFD:
13377 // examined below
13378 break;
13379 case V_EXPR:
13380 case V_INVOKE:
13381 // sub-expressions should be evaluated only if necessary
13382 return true;
13383 default:
13384 FATAL_ERROR("Value::needs_short_circuit()");
13385 }
13386 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13387 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13388 switch (t_ass->get_asstype()) {
13389 case Assignment::A_FUNCTION_RVAL:
13390 case Assignment::A_EXT_FUNCTION_RVAL:
13391 // avoid unnecessary call of a function
13392 return true;
13393 case Assignment::A_CONST:
13394 case Assignment::A_EXT_CONST:
13395 case Assignment::A_MODULEPAR:
13396 case Assignment::A_VAR:
13397 case Assignment::A_PAR_VAL_IN:
13398 case Assignment::A_PAR_VAL_OUT:
13399 case Assignment::A_PAR_VAL_INOUT:
13400 // depends on field/array sub-references, which is examined below
13401 break;
13402 default:
13403 FATAL_ERROR("Value::needs_short_circuit()");
13404 }
13405 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13406 if (t_subrefs) {
13407 // the evaluation of the reference does not have side effects
13408 // (i.e. false shall be returned) only if all sub-references point to
13409 // mandatory fields of record/set types, and neither sub-reference points
13410 // to a field of a union type
13411 Type *t_type = t_ass->get_Type();
13412 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13413 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13414 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13415 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13416 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13417 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13418 t_cf->get_is_optional()) return true;
13419 t_type = t_cf->get_type();
13420 } else return true;
13421 }
13422 }
13423 return false;
13424 }
13425
13426 void Value::dump(unsigned level) const
13427 {
13428 switch (valuetype) {
13429 case V_ERROR:
13430 case V_NULL:
13431 case V_BOOL:
13432 case V_INT:
13433 case V_NAMEDINT:
13434 case V_NAMEDBITS:
13435 case V_REAL:
13436 case V_ENUM:
13437 case V_BSTR:
13438 case V_HSTR:
13439 case V_OSTR:
13440 case V_CSTR:
13441 case V_ISO2022STR:
13442 case V_OID:
13443 case V_ROID:
13444 case V_CHOICE:
13445 case V_SEQOF:
13446 case V_SETOF:
13447 case V_ARRAY:
13448 case V_SEQ:
13449 case V_SET:
13450 case V_OMIT:
13451 case V_VERDICT:
13452 case V_DEFAULT_NULL:
13453 case V_FAT_NULL:
13454 case V_EXPR:
13455 case V_MACRO:
13456 case V_NOTUSED:
13457 case V_FUNCTION:
13458 case V_ALTSTEP:
13459 case V_TESTCASE:
13460 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13461 break;
13462 case V_REFD:
13463 case V_REFER:
13464 DEBUG(level, "Value: reference");
13465 u.ref.ref->dump(level + 1);
13466 break;
13467 case V_UNDEF_LOWERID:
13468 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13469 break;
13470 case V_UNDEF_BLOCK:
13471 DEBUG(level, "Value: {block}");
13472 break;
13473 case V_TTCN3_NULL:
13474 DEBUG(level, "Value: null");
13475 break;
13476 case V_INVOKE:
13477 DEBUG(level, "Value: invoke");
13478 u.invoke.v->dump(level + 1);
13479 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13480 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13481 break;
13482 default:
13483 DEBUG(level, "Value: unknown type: %d", valuetype);
13484 } // switch
13485 }
13486
13487 void Value::add_string_element(size_t index, Value *v_element,
13488 map<size_t, Value>*& string_elements)
13489 {
13490 v_element->set_my_scope(get_my_scope());
13491 v_element->set_my_governor(get_my_governor());
13492 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13493 v_element->set_location(*this);
13494 if (!string_elements) string_elements = new map<size_t, Value>;
13495 string_elements->add(index, v_element);
13496 }
13497
13498 ///////////////////////////////////////////////////////////////////////////////
13499 // class LazyParamData
13500
13501 int LazyParamData::depth = 0;
13502 bool LazyParamData::used_as_lvalue = false;
13503 vector<string>* LazyParamData::type_vec = NULL;
13504 vector<string>* LazyParamData::refd_vec = NULL;
13505
13506 void LazyParamData::init(bool p_used_as_lvalue) {
13507 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13508 if (depth==0) {
13509 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13510 used_as_lvalue = p_used_as_lvalue;
13511 type_vec = new vector<string>;
13512 refd_vec = new vector<string>;
13513 }
13514 depth++;
13515 }
13516
13517 void LazyParamData::clean() {
13518 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13519 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13520 if (depth==1) {
13521 // type_vec
13522 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13523 type_vec->clear();
13524 delete type_vec;
13525 type_vec = NULL;
13526 // refd_vec
13527 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13528 refd_vec->clear();
13529 delete refd_vec;
13530 refd_vec = NULL;
13531 }
13532 depth--;
13533 }
13534
13535 bool LazyParamData::in_lazy() {
13536 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13537 return depth>0;
13538 }
13539
13540 // returns a temporary id instead of the C++ reference to a definition
13541 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13542 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13543 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13544 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13545 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13546 // store the type of the assignment
13547 string* type_str = new string;
13548 switch (ass->get_asstype()) {
13549 case Assignment::A_MODULEPAR_TEMP:
13550 case Assignment::A_TEMPLATE:
13551 case Assignment::A_VAR_TEMPLATE:
13552 case Assignment::A_PAR_TEMPL_IN:
13553 case Assignment::A_PAR_TEMPL_OUT:
13554 case Assignment::A_PAR_TEMPL_INOUT:
13555 *type_str = ass->get_Type()->get_genname_template(scope);
13556 break;
13557 default:
13558 *type_str = ass->get_Type()->get_genname_value(scope);
13559 }
13560 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13561 bool refd_ass_is_lazy_fpar = false;
13562 switch (ass->get_asstype()) {
13563 case Assignment::A_PAR_VAL:
13564 case Assignment::A_PAR_VAL_IN:
13565 case Assignment::A_PAR_TEMPL_IN:
13566 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13567 if (refd_ass_is_lazy_fpar) {
13568 *type_str = string("Lazy_Param<") + *type_str + string(">");
13569 }
13570 break;
13571 default:
13572 break;
13573 }
13574 // add the "const" part if the referenced assignment is a constant thing
13575 if (!refd_ass_is_lazy_fpar) {
13576 switch (ass->get_asstype()) {
13577 case Assignment::A_CONST:
13578 case Assignment::A_OC:
13579 case Assignment::A_OBJECT:
13580 case Assignment::A_OS:
13581 case Assignment::A_VS:
13582 case Assignment::A_EXT_CONST:
13583 case Assignment::A_MODULEPAR:
13584 case Assignment::A_MODULEPAR_TEMP:
13585 case Assignment::A_TEMPLATE:
13586 case Assignment::A_PAR_VAL:
13587 case Assignment::A_PAR_VAL_IN:
13588 case Assignment::A_PAR_TEMPL_IN:
13589 *type_str = string("const ") + *type_str;
13590 break;
13591 default:
13592 // nothing to do
13593 break;
13594 }
13595 }
13596 //
13597 type_vec->add(type_str);
13598 // store the C++ reference string
13599 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
13600 if (refd_ass_is_lazy_fpar) {
13601 Type* refd_ass_type = ass->get_Type();
13602 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);
13603 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13604 } else {
13605 return get_member_name(refd_vec->size()-1);
13606 }
13607 }
13608
13609 string LazyParamData::get_member_name(size_t idx) {
13610 return string("lpm_") + Int2string(idx);
13611 }
13612
13613 string LazyParamData::get_constr_param_name(size_t idx) {
13614 return string("lpp_") + Int2string(idx);
13615 }
13616
13617 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
13618 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13619 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
13620 const string& tmp_id = val->get_temporary_id();
13621 const char *tmp_id_str = tmp_id.c_str();
13622 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13623 val->get_my_governor()->get_genname_value(my_scope).c_str(),
13624 tmp_id_str);
13625 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13626 tmp_id_str, val);
13627 expr->expr = mputstr(expr->expr, tmp_id_str);
13628 } else {
13629 val->generate_code_expr(expr);
13630 }
13631 }
13632
13633 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
13634 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
13635 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
13636 const string& tmp_id = temp->get_Template()->get_temporary_id();
13637 const char *tmp_id_str = tmp_id.c_str();
13638 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
13639 temp->get_Template()->get_my_governor()
13640 ->get_genname_template(my_scope).c_str(), tmp_id_str);
13641 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
13642 tmp_id_str, temp->get_Template());
13643 // Not incorporated into gen_conv_code() yet.
13644 if (gen_restriction_check != TR_NONE)
13645 expr->preamble = Template::generate_restriction_check_code(
13646 expr->preamble, tmp_id_str, gen_restriction_check);
13647 expr->expr = mputstr(expr->expr, tmp_id_str);
13648 } else temp->generate_code(expr, gen_restriction_check);
13649 }
13650
13651 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
13652 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13653 if (depth>1) {
13654 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13655 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13656 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13657 expression_struct value_expr;
13658 Code::init_expr(&value_expr);
13659 generate_code_for_value(&value_expr, value, scope);
13660 // the id of the instance of Lazy_Param which will be used as the actual parameter
13661 const string& lazy_param_id = value->get_temporary_id();
13662 if (value_expr.preamble) {
13663 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
13664 }
13665 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13666 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13667 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
13668 Code::free_expr(&value_expr);
13669 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13670 return;
13671 }
13672 // only if the formal parameter is *not* used as lvalue
13673 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
13674 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
13675 if (refd_ass) {
13676 bool refd_ass_is_lazy_fpar = false;
13677 switch (refd_ass->get_asstype()) {
13678 case Assignment::A_PAR_VAL:
13679 case Assignment::A_PAR_VAL_IN:
13680 case Assignment::A_PAR_TEMPL_IN:
13681 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13682 break;
13683 default:
13684 break;
13685 }
13686 if (refd_ass_is_lazy_fpar) {
13687 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13688 return;
13689 }
13690 }
13691 }
13692 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
13693 expression_struct value_expr;
13694 Code::init_expr(&value_expr);
13695 generate_code_for_value(&value_expr, value, scope);
13696 // the id of the instance of Lazy_Param which will be used as the actual parameter
13697 string lazy_param_id = value->get_temporary_id();
13698 string type_name = value->get_my_governor()->get_genname_value(scope);
13699 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
13700 }
13701
13702 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
13703 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
13704 if (depth>1) {
13705 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
13706 // lazy parameter inside a lazy parameter, call the funcion as a normal call
13707 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
13708 expression_struct tmpl_expr;
13709 Code::init_expr(&tmpl_expr);
13710 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13711 // the id of the instance of Lazy_Param which will be used as the actual parameter
13712 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
13713 if (tmpl_expr.preamble) {
13714 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
13715 }
13716 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13717 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13718 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
13719 Code::free_expr(&tmpl_expr);
13720 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13721 return;
13722 }
13723 // only if the formal parameter is *not* used as lvalue
13724 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
13725 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
13726 if (refd_ass) {
13727 bool refd_ass_is_lazy_fpar = false;
13728 switch (refd_ass->get_asstype()) {
13729 case Assignment::A_PAR_VAL:
13730 case Assignment::A_PAR_VAL_IN:
13731 case Assignment::A_PAR_TEMPL_IN:
13732 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
13733 break;
13734 default:
13735 break;
13736 }
13737 if (refd_ass_is_lazy_fpar) {
13738 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
13739 return;
13740 }
13741 }
13742 }
13743 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
13744 expression_struct tmpl_expr;
13745 Code::init_expr(&tmpl_expr);
13746 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
13747 // the id of the instance of Lazy_Param which will be used as the actual parameter
13748 string lazy_param_id = temp->get_Template()->get_temporary_id();
13749 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
13750 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
13751 }
13752
13753 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
13754 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
13755 if (type_vec->size()>0) {
13756 // private members of the local class will be const references to the objects referenced by the expression
13757 for (size_t i=0; i<type_vec->size(); i++) {
13758 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
13759 }
13760 expr->preamble = mputstr(expr->preamble, "public:\n");
13761 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
13762 for (size_t i=0; i<type_vec->size(); i++) {
13763 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13764 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
13765 }
13766 expr->preamble = mputstr(expr->preamble, "): ");
13767 for (size_t i=0; i<type_vec->size(); i++) {
13768 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13769 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
13770 }
13771 expr->preamble = mputstr(expr->preamble, " {}\n");
13772 expr->preamble = mputstr(expr->preamble, "private:\n");
13773 }
13774 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
13775 // use the temporary expr structure to fill the body of the eval_expr() function
13776 if (param_expr.preamble) {
13777 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
13778 }
13779 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
13780 if (param_expr.postamble) {
13781 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
13782 }
13783 Code::free_expr(&param_expr);
13784 expr->preamble = mputstr(expr->preamble, "}\n"
13785 "};\n" // end of local class definition
13786 );
13787 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
13788 if (type_vec->size()>0) {
13789 expr->preamble = mputc(expr->preamble, '(');
13790 // paramteres of the constructor are references to the objects used in the expression
13791 for (size_t i=0; i<refd_vec->size(); i++) {
13792 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
13793 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
13794 }
13795 expr->preamble = mputc(expr->preamble, ')');
13796 }
13797 expr->preamble = mputstr(expr->preamble, ";\n");
13798 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
13799 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
13800 }
13801
13802 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
13803 expression_struct ref_expr;
13804 Code::init_expr(&ref_expr);
13805 ref->generate_code(&ref_expr);
13806 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
13807 if (ref_expr.preamble) {
13808 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
13809 }
13810 Assignment* ass = ref->get_refd_assignment();
13811 // determine C++ type of the assignment
13812 string type_str;
13813 switch (ass->get_asstype()) {
13814 case Assignment::A_MODULEPAR_TEMP:
13815 case Assignment::A_TEMPLATE:
13816 case Assignment::A_VAR_TEMPLATE:
13817 case Assignment::A_PAR_TEMPL_IN:
13818 case Assignment::A_PAR_TEMPL_OUT:
13819 case Assignment::A_PAR_TEMPL_INOUT:
13820 type_str = ass->get_Type()->get_genname_template(scope);
13821 break;
13822 default:
13823 type_str = ass->get_Type()->get_genname_value(scope);
13824 }
13825 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13826 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
13827 if (ref_expr.postamble) {
13828 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
13829 }
13830 Code::free_expr(&ref_expr);
13831 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13832 }
13833
13834 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
13835 const string& lazy_param_id = value->get_temporary_id();
13836 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13837 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
13838 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
13839 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13840 }
13841
13842 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
13843 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
13844 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
13845 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
13846 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
13847 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
13848 }
13849
13850 } // namespace Common
This page took 0.421134 seconds and 5 git commands to generate.