added any2unistr predefined function (artf724008)
[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, Bence Janos
25 * Szabo, Janos Zoltan – initial implementation
26 * Szalai, Gabor
27 * Tatarka, Gabor
28 * Zalanyi, Balazs Andor
29 *
30 ******************************************************************************/
31 #include "../common/dbgnew.hh"
32 #include "Value.hh"
33 #include "Identifier.hh"
34 #include "Valuestuff.hh"
35 #include "PredefFunc.hh"
36 #include "CompField.hh"
37 #include "CompType.hh"
38 #include "EnumItem.hh"
39 #include "TypeCompat.hh"
40 #include "asn1/Block.hh"
41 #include "asn1/TokenBuf.hh"
42 #include "Real.hh"
43 #include "Int.hh"
44 #include "main.hh"
45 #include "Setting.hh"
46 #include "Type.hh"
47 #include "ttcn3/TtcnTemplate.hh"
48 #include "ttcn3/ArrayDimensions.hh"
49 #include "ustring.hh"
50 #include "../common/pattern.hh"
51
52 #include "ttcn3/PatternString.hh"
53 #include "ttcn3/Statement.hh"
54
55 #include "ttcn3/Attributes.hh"
56 #include "../common/JSON_Tokenizer.hh"
57 #include "ttcn3/Ttcn2Json.hh"
58
59 #include <math.h>
60 #include <regex.h>
61 #include <limits.h>
62
63 namespace Common {
64
65 static void clean_up_string_elements(map<size_t, Value>*& string_elements)
66 {
67 if (string_elements) {
68 for (size_t i = 0; i < string_elements->size(); i++)
69 delete string_elements->get_nth_elem(i);
70 string_elements->clear();
71 delete string_elements;
72 string_elements = 0;
73 }
74 }
75
76 // =================================
77 // ===== Value
78 // =================================
79
80 Value::Value(const Value& p)
81 : GovernedSimple(p), valuetype(p.valuetype), my_governor(0)
82 {
83 switch(valuetype) {
84 case V_ERROR:
85 case V_NULL:
86 case V_OMIT:
87 case V_TTCN3_NULL:
88 case V_DEFAULT_NULL:
89 case V_FAT_NULL:
90 case V_NOTUSED:
91 break;
92 case V_BOOL:
93 u.val_bool=p.u.val_bool;
94 break;
95 case V_INT:
96 u.val_Int=new int_val_t(*(p.u.val_Int));
97 break;
98 case V_NAMEDINT:
99 case V_ENUM:
100 case V_UNDEF_LOWERID:
101 u.val_id=p.u.val_id->clone();
102 break;
103 case V_REAL:
104 u.val_Real=p.u.val_Real;
105 break;
106 case V_BSTR:
107 case V_HSTR:
108 case V_OSTR:
109 case V_CSTR:
110 case V_ISO2022STR:
111 set_val_str(new string(*p.u.str.val_str));
112 break;
113 case V_USTR:
114 set_val_ustr(new ustring(*p.u.ustr.val_ustr));
115 u.ustr.convert_str = p.u.ustr.convert_str;
116 break;
117 case V_CHARSYMS:
118 u.char_syms = p.u.char_syms->clone();
119 break;
120 case V_OID:
121 case V_ROID:
122 u.oid_comps=new vector<OID_comp>;
123 for(size_t i=0; i<p.u.oid_comps->size(); i++)
124 add_oid_comp((*p.u.oid_comps)[i]->clone());
125 break;
126 case V_CHOICE:
127 u.choice.alt_name=p.u.choice.alt_name->clone();
128 u.choice.alt_value=p.u.choice.alt_value->clone();
129 break;
130 case V_SEQOF:
131 case V_SETOF:
132 case V_ARRAY:
133 u.val_vs=p.u.val_vs->clone();
134 break;
135 case V_SEQ:
136 case V_SET:
137 u.val_nvs=p.u.val_nvs->clone();
138 break;
139 case V_REFD:
140 u.ref.ref=p.u.ref.ref->clone();
141 u.ref.refd_last=0;
142 break;
143 case V_NAMEDBITS:
144 for(size_t i=0; i<p.u.ids->size(); i++) {
145 Identifier *id = p.u.ids->get_nth_elem(i);
146 u.ids->add(id->get_name(), id->clone());
147 }
148 break;
149 case V_UNDEF_BLOCK:
150 u.block=p.u.block->clone();
151 break;
152 case V_VERDICT:
153 u.verdict=p.u.verdict;
154 break;
155 case V_EXPR:
156 u.expr.v_optype = p.u.expr.v_optype;
157 u.expr.state = EXPR_NOT_CHECKED;
158 switch(u.expr.v_optype) {
159 case OPTYPE_RND: // -
160 case OPTYPE_COMP_NULL:
161 case OPTYPE_COMP_MTC:
162 case OPTYPE_COMP_SYSTEM:
163 case OPTYPE_COMP_SELF:
164 case OPTYPE_COMP_RUNNING_ANY:
165 case OPTYPE_COMP_RUNNING_ALL:
166 case OPTYPE_COMP_ALIVE_ANY:
167 case OPTYPE_COMP_ALIVE_ALL:
168 case OPTYPE_TMR_RUNNING_ANY:
169 case OPTYPE_GETVERDICT:
170 case OPTYPE_TESTCASENAME:
171 case OPTYPE_PROF_RUNNING:
172 break;
173 case OPTYPE_UNARYPLUS: // v1
174 case OPTYPE_UNARYMINUS:
175 case OPTYPE_NOT:
176 case OPTYPE_NOT4B:
177 case OPTYPE_BIT2HEX:
178 case OPTYPE_BIT2INT:
179 case OPTYPE_BIT2OCT:
180 case OPTYPE_BIT2STR:
181 case OPTYPE_CHAR2INT:
182 case OPTYPE_CHAR2OCT:
183 case OPTYPE_COMP_RUNNING:
184 case OPTYPE_COMP_ALIVE:
185 case OPTYPE_FLOAT2INT:
186 case OPTYPE_FLOAT2STR:
187 case OPTYPE_HEX2BIT:
188 case OPTYPE_HEX2INT:
189 case OPTYPE_HEX2OCT:
190 case OPTYPE_HEX2STR:
191 case OPTYPE_INT2CHAR:
192 case OPTYPE_INT2FLOAT:
193 case OPTYPE_INT2STR:
194 case OPTYPE_INT2UNICHAR:
195 case OPTYPE_OCT2BIT:
196 case OPTYPE_OCT2CHAR:
197 case OPTYPE_OCT2HEX:
198 case OPTYPE_OCT2INT:
199 case OPTYPE_OCT2STR:
200 case OPTYPE_STR2BIT:
201 case OPTYPE_STR2FLOAT:
202 case OPTYPE_STR2HEX:
203 case OPTYPE_STR2INT:
204 case OPTYPE_STR2OCT:
205 case OPTYPE_UNICHAR2INT:
206 case OPTYPE_UNICHAR2CHAR:
207 case OPTYPE_ENUM2INT:
208 case OPTYPE_RNDWITHVAL:
209 case OPTYPE_GET_STRINGENCODING:
210 case OPTYPE_DECODE_BASE64:
211 case OPTYPE_REMOVE_BOM:
212 u.expr.v1=p.u.expr.v1->clone();
213 break;
214 case OPTYPE_ADD: // v1 v2
215 case OPTYPE_SUBTRACT:
216 case OPTYPE_MULTIPLY:
217 case OPTYPE_DIVIDE:
218 case OPTYPE_MOD:
219 case OPTYPE_REM:
220 case OPTYPE_CONCAT:
221 case OPTYPE_EQ:
222 case OPTYPE_LT:
223 case OPTYPE_GT:
224 case OPTYPE_NE:
225 case OPTYPE_GE:
226 case OPTYPE_LE:
227 case OPTYPE_AND:
228 case OPTYPE_OR:
229 case OPTYPE_XOR:
230 case OPTYPE_AND4B:
231 case OPTYPE_OR4B:
232 case OPTYPE_XOR4B:
233 case OPTYPE_SHL:
234 case OPTYPE_SHR:
235 case OPTYPE_ROTL:
236 case OPTYPE_ROTR:
237 case OPTYPE_INT2BIT:
238 case OPTYPE_INT2HEX:
239 case OPTYPE_INT2OCT:
240 u.expr.v1=p.u.expr.v1->clone();
241 u.expr.v2=p.u.expr.v2->clone();
242 break;
243 case OPTYPE_UNICHAR2OCT: // v1 [v2]
244 case OPTYPE_OCT2UNICHAR:
245 case OPTYPE_ENCODE_BASE64:
246 u.expr.v1=p.u.expr.v1->clone();
247 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
248 break;
249 case OPTYPE_DECODE:
250 u.expr.r1=p.u.expr.r1->clone();
251 u.expr.r2=p.u.expr.r2->clone();
252 break;
253 case OPTYPE_SUBSTR:
254 u.expr.ti1=p.u.expr.ti1->clone();
255 u.expr.v2=p.u.expr.v2->clone();
256 u.expr.v3=p.u.expr.v3->clone();
257 break;
258 case OPTYPE_REGEXP:
259 u.expr.ti1=p.u.expr.ti1->clone();
260 u.expr.t2=p.u.expr.t2->clone();
261 u.expr.v3=p.u.expr.v3->clone();
262 break;
263 case OPTYPE_DECOMP: // v1 v2 v3
264 u.expr.v1=p.u.expr.v1->clone();
265 u.expr.v2=p.u.expr.v2->clone();
266 u.expr.v3=p.u.expr.v3->clone();
267 break;
268 case OPTYPE_REPLACE:
269 u.expr.ti1 = p.u.expr.ti1->clone();
270 u.expr.v2 = p.u.expr.v2->clone();
271 u.expr.v3 = p.u.expr.v3->clone();
272 u.expr.ti4 = p.u.expr.ti4->clone();
273 break;
274 case OPTYPE_LENGTHOF: // ti1
275 case OPTYPE_SIZEOF: // ti1
276 case OPTYPE_VALUEOF: // ti1
277 case OPTYPE_ENCODE:
278 case OPTYPE_ISPRESENT:
279 case OPTYPE_TTCN2STRING:
280 u.expr.ti1=p.u.expr.ti1->clone();
281 break;
282 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
283 u.expr.ti1=p.u.expr.ti1->clone();
284 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
285 break;
286 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
287 u.expr.r1 = p.u.expr.r1->clone();
288 u.expr.r2 = p.u.expr.r2->clone();
289 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
290 break;
291 case OPTYPE_UNDEF_RUNNING:
292 case OPTYPE_TMR_READ:
293 case OPTYPE_TMR_RUNNING:
294 case OPTYPE_ACTIVATE:
295 u.expr.r1=p.u.expr.r1->clone();
296 break;
297 case OPTYPE_EXECUTE: // r1 [v2]
298 u.expr.r1=p.u.expr.r1->clone();
299 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
300 break;
301 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
302 u.expr.r1=p.u.expr.r1->clone();
303 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
304 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
305 u.expr.b4 = p.u.expr.b4;
306 break;
307 case OPTYPE_MATCH: // v1 t2
308 u.expr.v1=p.u.expr.v1->clone();
309 u.expr.t2=p.u.expr.t2->clone();
310 break;
311 case OPTYPE_ISCHOSEN: // r1 i2
312 u.expr.r1=p.u.expr.r1->clone();
313 u.expr.i2=p.u.expr.i2->clone();
314 break;
315 case OPTYPE_ISCHOSEN_V: // v1 i2
316 u.expr.v1=p.u.expr.v1->clone();
317 u.expr.i2=p.u.expr.i2->clone();
318 break;
319 case OPTYPE_ISCHOSEN_T: // t1 i2
320 u.expr.t1=p.u.expr.t1->clone();
321 u.expr.i2=p.u.expr.i2->clone();
322 break;
323 case OPTYPE_ACTIVATE_REFD:
324 u.expr.v1 = p.u.expr.v1->clone();
325 if(p.u.expr.state!=EXPR_CHECKED)
326 u.expr.t_list2 = p.u.expr.t_list2->clone();
327 else {
328 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
329 u.expr.state = EXPR_CHECKED;
330 }
331 break;
332 case OPTYPE_EXECUTE_REFD:
333 u.expr.v1 = p.u.expr.v1->clone();
334 if(p.u.expr.state!=EXPR_CHECKED)
335 u.expr.t_list2 = p.u.expr.t_list2->clone();
336 else {
337 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
338 u.expr.state = EXPR_CHECKED;
339 }
340 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
341 break;
342 case OPTYPE_LOG2STR:
343 case OPTYPE_ANY2UNISTR:
344 u.expr.logargs = p.u.expr.logargs->clone();
345 break;
346 default:
347 FATAL_ERROR("Value::Value()");
348 } // switch
349 break;
350 case V_MACRO:
351 u.macro = p.u.macro;
352 break;
353 case V_FUNCTION:
354 case V_ALTSTEP:
355 case V_TESTCASE:
356 u.refd_fat = p.u.refd_fat;
357 break;
358 case V_INVOKE:
359 u.invoke.v = p.u.invoke.v->clone();
360 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
361 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
362 break;
363 case V_REFER:
364 u.refered = p.u.refered->clone();
365 break;
366 default:
367 FATAL_ERROR("Value::Value()");
368 } // switch
369 }
370
371 void Value::clean_up()
372 {
373 switch (valuetype) {
374 case V_ERROR:
375 case V_NULL:
376 case V_BOOL:
377 case V_REAL:
378 case V_OMIT:
379 case V_VERDICT:
380 case V_TTCN3_NULL:
381 case V_DEFAULT_NULL:
382 case V_FAT_NULL:
383 case V_MACRO:
384 case V_NOTUSED:
385 case V_FUNCTION:
386 case V_ALTSTEP:
387 case V_TESTCASE:
388 break;
389 case V_INT:
390 delete u.val_Int;
391 break;
392 case V_NAMEDINT:
393 case V_ENUM:
394 case V_UNDEF_LOWERID:
395 delete u.val_id;
396 break;
397 case V_BSTR:
398 case V_HSTR:
399 case V_OSTR:
400 case V_CSTR:
401 case V_ISO2022STR:
402 delete u.str.val_str;
403 clean_up_string_elements(u.str.str_elements);
404 break;
405 case V_USTR:
406 delete u.ustr.val_ustr;
407 clean_up_string_elements(u.ustr.ustr_elements);
408 break;
409 case V_CHARSYMS:
410 delete u.char_syms;
411 break;
412 case V_OID:
413 case V_ROID:
414 if (u.oid_comps) {
415 for(size_t i=0; i<u.oid_comps->size(); i++)
416 delete (*u.oid_comps)[i];
417 u.oid_comps->clear();
418 delete u.oid_comps;
419 }
420 break;
421 case V_EXPR:
422 clean_up_expr();
423 break;
424 case V_CHOICE:
425 delete u.choice.alt_name;
426 delete u.choice.alt_value;
427 break;
428 case V_SEQOF:
429 case V_SETOF:
430 case V_ARRAY:
431 delete u.val_vs;
432 break;
433 case V_SEQ:
434 case V_SET:
435 delete u.val_nvs;
436 break;
437 case V_REFD:
438 delete u.ref.ref;
439 break;
440 case V_REFER:
441 delete u.refered;
442 break;
443 case V_INVOKE:
444 delete u.invoke.v;
445 delete u.invoke.t_list;
446 delete u.invoke.ap_list;
447 break;
448 case V_NAMEDBITS:
449 if(u.ids) {
450 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
451 u.ids->clear();
452 delete u.ids;
453 }
454 break;
455 case V_UNDEF_BLOCK:
456 delete u.block;
457 break;
458 default:
459 FATAL_ERROR("Value::clean_up()");
460 } // switch
461 }
462
463 void Value::clean_up_expr()
464 {
465 switch (u.expr.state) {
466 case EXPR_CHECKING:
467 case EXPR_CHECKING_ERR:
468 FATAL_ERROR("Value::clean_up_expr()");
469 default:
470 break;
471 }
472 switch (u.expr.v_optype) {
473 case OPTYPE_RND: // -
474 case OPTYPE_COMP_NULL:
475 case OPTYPE_COMP_MTC:
476 case OPTYPE_COMP_SYSTEM:
477 case OPTYPE_COMP_SELF:
478 case OPTYPE_COMP_RUNNING_ANY:
479 case OPTYPE_COMP_RUNNING_ALL:
480 case OPTYPE_COMP_ALIVE_ANY:
481 case OPTYPE_COMP_ALIVE_ALL:
482 case OPTYPE_TMR_RUNNING_ANY:
483 case OPTYPE_GETVERDICT:
484 case OPTYPE_TESTCASENAME:
485 case OPTYPE_PROF_RUNNING:
486 break;
487 case OPTYPE_UNARYPLUS: // v1
488 case OPTYPE_UNARYMINUS:
489 case OPTYPE_NOT:
490 case OPTYPE_NOT4B:
491 case OPTYPE_BIT2HEX:
492 case OPTYPE_BIT2INT:
493 case OPTYPE_BIT2OCT:
494 case OPTYPE_BIT2STR:
495 case OPTYPE_CHAR2INT:
496 case OPTYPE_CHAR2OCT:
497 case OPTYPE_COMP_RUNNING:
498 case OPTYPE_COMP_ALIVE:
499 case OPTYPE_FLOAT2INT:
500 case OPTYPE_FLOAT2STR:
501 case OPTYPE_HEX2BIT:
502 case OPTYPE_HEX2INT:
503 case OPTYPE_HEX2OCT:
504 case OPTYPE_HEX2STR:
505 case OPTYPE_INT2CHAR:
506 case OPTYPE_INT2FLOAT:
507 case OPTYPE_INT2STR:
508 case OPTYPE_INT2UNICHAR:
509 case OPTYPE_OCT2BIT:
510 case OPTYPE_OCT2CHAR:
511 case OPTYPE_OCT2HEX:
512 case OPTYPE_OCT2INT:
513 case OPTYPE_OCT2STR:
514 case OPTYPE_STR2BIT:
515 case OPTYPE_STR2FLOAT:
516 case OPTYPE_STR2HEX:
517 case OPTYPE_STR2INT:
518 case OPTYPE_STR2OCT:
519 case OPTYPE_UNICHAR2INT:
520 case OPTYPE_UNICHAR2CHAR:
521 case OPTYPE_ENUM2INT:
522 case OPTYPE_RNDWITHVAL:
523 case OPTYPE_REMOVE_BOM:
524 case OPTYPE_GET_STRINGENCODING:
525 case OPTYPE_DECODE_BASE64:
526 delete u.expr.v1;
527 break;
528 case OPTYPE_ADD: // v1 v2
529 case OPTYPE_SUBTRACT:
530 case OPTYPE_MULTIPLY:
531 case OPTYPE_DIVIDE:
532 case OPTYPE_MOD:
533 case OPTYPE_REM:
534 case OPTYPE_CONCAT:
535 case OPTYPE_EQ:
536 case OPTYPE_LT:
537 case OPTYPE_GT:
538 case OPTYPE_NE:
539 case OPTYPE_GE:
540 case OPTYPE_LE:
541 case OPTYPE_AND:
542 case OPTYPE_OR:
543 case OPTYPE_XOR:
544 case OPTYPE_AND4B:
545 case OPTYPE_OR4B:
546 case OPTYPE_XOR4B:
547 case OPTYPE_SHL:
548 case OPTYPE_SHR:
549 case OPTYPE_ROTL:
550 case OPTYPE_ROTR:
551 case OPTYPE_INT2BIT:
552 case OPTYPE_INT2HEX:
553 case OPTYPE_INT2OCT:
554 case OPTYPE_UNICHAR2OCT:
555 case OPTYPE_OCT2UNICHAR:
556 case OPTYPE_ENCODE_BASE64:
557 delete u.expr.v1;
558 delete u.expr.v2;
559 break;
560 case OPTYPE_DECODE:
561 delete u.expr.r1;
562 delete u.expr.r2;
563 break;
564 case OPTYPE_SUBSTR:
565 delete u.expr.ti1;
566 delete u.expr.v2;
567 delete u.expr.v3;
568 break;
569 case OPTYPE_REGEXP:
570 delete u.expr.ti1;
571 delete u.expr.t2;
572 delete u.expr.v3;
573 break;
574 case OPTYPE_DECOMP: // v1 v2 v3
575 delete u.expr.v1;
576 delete u.expr.v2;
577 delete u.expr.v3;
578 break;
579 case OPTYPE_REPLACE:
580 delete u.expr.ti1;
581 delete u.expr.v2;
582 delete u.expr.v3;
583 delete u.expr.ti4;
584 break;
585 case OPTYPE_LENGTHOF: // ti1
586 case OPTYPE_SIZEOF: // ti1
587 case OPTYPE_VALUEOF: // ti1
588 case OPTYPE_ISVALUE:
589 case OPTYPE_ISBOUND:
590 case OPTYPE_ENCODE:
591 case OPTYPE_ISPRESENT:
592 case OPTYPE_TTCN2STRING:
593 delete u.expr.ti1;
594 break;
595 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
596 delete u.expr.ti1;
597 delete u.expr.v2;
598 break;
599 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
600 delete u.expr.r1;
601 delete u.expr.r2;
602 delete u.expr.v3;
603 break;
604 case OPTYPE_UNDEF_RUNNING:
605 case OPTYPE_TMR_READ:
606 case OPTYPE_TMR_RUNNING:
607 case OPTYPE_ACTIVATE:
608 delete u.expr.r1;
609 break;
610 case OPTYPE_EXECUTE: // r1 [v2]
611 delete u.expr.r1;
612 delete u.expr.v2;
613 break;
614 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
615 delete u.expr.r1;
616 delete u.expr.v2;
617 delete u.expr.v3;
618 break;
619 case OPTYPE_MATCH: // v1 t2
620 delete u.expr.v1;
621 delete u.expr.t2;
622 break;
623 case OPTYPE_ISCHOSEN: // r1 i2
624 delete u.expr.r1;
625 delete u.expr.i2;
626 break;
627 case OPTYPE_ISCHOSEN_V: // v1 i2
628 delete u.expr.v1;
629 delete u.expr.i2;
630 break;
631 case OPTYPE_ISCHOSEN_T: // t1 i2
632 delete u.expr.t1;
633 delete u.expr.i2;
634 break;
635 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
636 delete u.expr.v1;
637 if(u.expr.state!=EXPR_CHECKED)
638 delete u.expr.t_list2;
639 else
640 delete u.expr.ap_list2;
641 break;
642 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
643 delete u.expr.v1;
644 if(u.expr.state!=EXPR_CHECKED)
645 delete u.expr.t_list2;
646 else
647 delete u.expr.ap_list2;
648 delete u.expr.v3;
649 break;
650 case OPTYPE_LOG2STR:
651 case OPTYPE_ANY2UNISTR:
652 delete u.expr.logargs;
653 break;
654 default:
655 FATAL_ERROR("Value::clean_up_expr()");
656 } // switch
657 }
658
659 void Value::copy_and_destroy(Value *src)
660 {
661 clean_up();
662 valuetype = src->valuetype;
663 u = src->u;
664 // update the pointer used for caching if it points to the value itself
665 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
666 src->valuetype = V_ERROR;
667 delete src;
668 }
669
670 Value::Value(valuetype_t p_vt)
671 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
672 {
673 switch(valuetype) {
674 case V_NULL:
675 case V_TTCN3_NULL:
676 case V_OMIT:
677 case V_NOTUSED:
678 case V_ERROR:
679 break;
680 case V_OID:
681 case V_ROID:
682 u.oid_comps=new vector<OID_comp>();
683 break;
684 case V_NAMEDBITS:
685 u.ids=new map<string, Identifier>();
686 break;
687 default:
688 FATAL_ERROR("Value::Value()");
689 } // switch
690 }
691
692 Value::Value(valuetype_t p_vt, bool p_val_bool)
693 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
694 {
695 switch(valuetype) {
696 case V_BOOL:
697 u.val_bool=p_val_bool;
698 break;
699 default:
700 FATAL_ERROR("Value::Value()");
701 } // switch
702 }
703
704 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
705 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
706 {
707 switch(valuetype) {
708 case V_INT:
709 u.val_Int=new int_val_t(p_val_Int);
710 break;
711 default:
712 FATAL_ERROR("Value::Value()");
713 } // switch
714 }
715
716 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
717 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
718 {
719 switch(valuetype){
720 case V_INT:
721 u.val_Int=p_val_Int;
722 break;
723 default:
724 FATAL_ERROR("Value::Value()");
725 }
726 }
727
728 Value::Value(valuetype_t p_vt, string *p_val_str)
729 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
730 {
731 if(!p_val_str) FATAL_ERROR("NULL parameter");
732 switch(valuetype) {
733 case V_BSTR:
734 case V_HSTR:
735 case V_OSTR:
736 case V_CSTR:
737 case V_ISO2022STR:
738 set_val_str(p_val_str);
739 break;
740 default:
741 FATAL_ERROR("Value::Value()");
742 } // switch
743 }
744
745 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
746 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
747 {
748 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
749 set_val_ustr(p_val_ustr);
750 u.ustr.convert_str = false;
751 }
752
753 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
754 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
755 {
756 if (!p_char_syms) FATAL_ERROR("NULL parameter");
757 switch (valuetype) {
758 case V_CHARSYMS:
759 u.char_syms = p_char_syms;
760 break;
761 default:
762 FATAL_ERROR("Value::Value()");
763 } // switch
764 }
765
766 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
767 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
768 {
769 if(!p_val_id)
770 FATAL_ERROR("NULL parameter");
771 switch(valuetype) {
772 case V_NAMEDINT:
773 case V_ENUM:
774 case V_UNDEF_LOWERID:
775 u.val_id=p_val_id;
776 break;
777 default:
778 FATAL_ERROR("Value::Value()");
779 } // switch
780 }
781
782 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
783 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
784 {
785 if(!p_id || !p_val)
786 FATAL_ERROR("NULL parameter");
787 switch(valuetype) {
788 case V_CHOICE:
789 u.choice.alt_name=p_id;
790 u.choice.alt_value=p_val;
791 break;
792 default:
793 FATAL_ERROR("Value::Value()");
794 } // switch
795 }
796
797 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
798 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
799 {
800 switch(valuetype) {
801 case V_REAL:
802 u.val_Real=p_val_Real;
803 break;
804 default:
805 FATAL_ERROR("Value::Value()");
806 } // switch
807 }
808
809 Value::Value(valuetype_t p_vt, Values *p_vs)
810 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
811 {
812 if(!p_vs) FATAL_ERROR("NULL parameter");
813 switch(valuetype) {
814 case V_SEQOF:
815 case V_SETOF:
816 case V_ARRAY:
817 u.val_vs=p_vs;
818 break;
819 default:
820 FATAL_ERROR("Value::Value()");
821 } // switch
822 }
823
824 Value::Value(valuetype_t p_vt, Value *p_v,
825 Ttcn::ParsedActualParameters *p_t_list)
826 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
827 {
828 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
829 switch(valuetype) {
830 case V_INVOKE:
831 u.invoke.v = p_v;
832 u.invoke.t_list = p_t_list;
833 u.invoke.ap_list = 0;
834 break;
835 default:
836 FATAL_ERROR("Value::Value()");
837 }
838 }
839
840 // -
841 Value::Value(operationtype_t p_optype)
842 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
843 {
844 u.expr.v_optype = p_optype;
845 u.expr.state = EXPR_NOT_CHECKED;
846 switch(p_optype) {
847 case OPTYPE_RND:
848 case OPTYPE_COMP_NULL:
849 case OPTYPE_COMP_MTC:
850 case OPTYPE_COMP_SYSTEM:
851 case OPTYPE_COMP_SELF:
852 case OPTYPE_COMP_RUNNING_ANY:
853 case OPTYPE_COMP_RUNNING_ALL:
854 case OPTYPE_COMP_ALIVE_ANY:
855 case OPTYPE_COMP_ALIVE_ALL:
856 case OPTYPE_TMR_RUNNING_ANY:
857 case OPTYPE_GETVERDICT:
858 case OPTYPE_TESTCASENAME:
859 case OPTYPE_PROF_RUNNING:
860 break;
861 default:
862 FATAL_ERROR("Value::Value()");
863 } // switch
864 }
865
866 // v1
867 Value::Value(operationtype_t p_optype, Value *p_v1)
868 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
869 {
870 u.expr.v_optype = p_optype;
871 u.expr.state = EXPR_NOT_CHECKED;
872 switch(p_optype) {
873 case OPTYPE_UNARYPLUS:
874 case OPTYPE_UNARYMINUS:
875 case OPTYPE_NOT:
876 case OPTYPE_NOT4B:
877 case OPTYPE_BIT2HEX:
878 case OPTYPE_BIT2INT:
879 case OPTYPE_BIT2OCT:
880 case OPTYPE_BIT2STR:
881 case OPTYPE_CHAR2INT:
882 case OPTYPE_CHAR2OCT:
883 case OPTYPE_COMP_RUNNING:
884 case OPTYPE_COMP_ALIVE:
885 case OPTYPE_FLOAT2INT:
886 case OPTYPE_FLOAT2STR:
887 case OPTYPE_HEX2BIT:
888 case OPTYPE_HEX2INT:
889 case OPTYPE_HEX2OCT:
890 case OPTYPE_HEX2STR:
891 case OPTYPE_INT2CHAR:
892 case OPTYPE_INT2FLOAT:
893 case OPTYPE_INT2STR:
894 case OPTYPE_INT2UNICHAR:
895 case OPTYPE_OCT2BIT:
896 case OPTYPE_OCT2CHAR:
897 case OPTYPE_OCT2HEX:
898 case OPTYPE_OCT2INT:
899 case OPTYPE_OCT2STR:
900 case OPTYPE_STR2BIT:
901 case OPTYPE_STR2FLOAT:
902 case OPTYPE_STR2HEX:
903 case OPTYPE_STR2INT:
904 case OPTYPE_STR2OCT:
905 case OPTYPE_UNICHAR2INT:
906 case OPTYPE_UNICHAR2CHAR:
907 case OPTYPE_ENUM2INT:
908 case OPTYPE_RNDWITHVAL:
909 case OPTYPE_REMOVE_BOM:
910 case OPTYPE_GET_STRINGENCODING:
911 case OPTYPE_DECODE_BASE64:
912 if(!p_v1) FATAL_ERROR("Value::Value()");
913 u.expr.v1=p_v1;
914 break;
915 default:
916 FATAL_ERROR("Value::Value()");
917 } // switch
918 }
919
920 // ti1
921 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
922 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
923 {
924 u.expr.v_optype = p_optype;
925 u.expr.state = EXPR_NOT_CHECKED;
926 switch(p_optype) {
927 case OPTYPE_LENGTHOF:
928 case OPTYPE_SIZEOF:
929 case OPTYPE_VALUEOF:
930 case OPTYPE_ISVALUE:
931 case OPTYPE_ISBOUND:
932 case OPTYPE_ENCODE:
933 case OPTYPE_ENCVALUE_UNICHAR:
934 case OPTYPE_ISPRESENT:
935 case OPTYPE_TTCN2STRING:
936 if(!p_ti1) FATAL_ERROR("Value::Value()");
937 u.expr.ti1=p_ti1;
938 break;
939 default:
940 FATAL_ERROR("Value::Value()");
941 } // switch
942 }
943
944 // r1
945 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
946 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
947 {
948 u.expr.v_optype = p_optype;
949 u.expr.state = EXPR_NOT_CHECKED;
950 switch(p_optype) {
951 case OPTYPE_UNDEF_RUNNING:
952 case OPTYPE_TMR_READ:
953 case OPTYPE_TMR_RUNNING:
954 case OPTYPE_ACTIVATE:
955 if(!p_r1) FATAL_ERROR("Value::Value()");
956 u.expr.r1=p_r1;
957 break;
958 default:
959 FATAL_ERROR("Value::Value()");
960 } // switch
961 }
962
963 // v1 t_list2
964 Value::Value(operationtype_t p_optype, Value *p_v1,
965 Ttcn::ParsedActualParameters *p_ap_list)
966 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
967 {
968 u.expr.v_optype = p_optype;
969 u.expr.state = EXPR_NOT_CHECKED;
970 switch(p_optype) {
971 case OPTYPE_ACTIVATE_REFD:
972 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
973 u.expr.v1 = p_v1;
974 u.expr.t_list2 = p_ap_list;
975 break;
976 default:
977 FATAL_ERROR("Value::Value()");
978 }
979 }
980
981 //v1 t_list2 v3
982 Value::Value(operationtype_t p_optype, Value *p_v1,
983 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
984 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
985 {
986 u.expr.v_optype = p_optype;
987 u.expr.state = EXPR_NOT_CHECKED;
988 switch(p_optype) {
989 case OPTYPE_EXECUTE_REFD:
990 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
991 u.expr.v1 = p_v1;
992 u.expr.t_list2 = p_t_list2;
993 u.expr.v3 = p_v3;
994 break;
995 default:
996 FATAL_ERROR("Value::Value()");
997 }
998 }
999
1000 // r1 [v2]
1001 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
1002 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1003 {
1004 u.expr.v_optype = p_optype;
1005 u.expr.state = EXPR_NOT_CHECKED;
1006 switch(p_optype) {
1007 case OPTYPE_EXECUTE:
1008 if(!p_r1) FATAL_ERROR("Value::Value()");
1009 u.expr.r1=p_r1;
1010 u.expr.v2=p_v2;
1011 break;
1012 default:
1013 FATAL_ERROR("Value::Value()");
1014 } // switch
1015 }
1016
1017 // r1 [v2] [v3] b4
1018 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
1019 Value *p_v2, Value *p_v3, bool p_b4)
1020 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1021 {
1022 u.expr.v_optype = p_optype;
1023 u.expr.state = EXPR_NOT_CHECKED;
1024 switch(p_optype) {
1025 case OPTYPE_COMP_CREATE:
1026 if(!p_r1) FATAL_ERROR("Value::Value()");
1027 u.expr.r1=p_r1;
1028 u.expr.v2=p_v2;
1029 u.expr.v3=p_v3;
1030 u.expr.b4=p_b4;
1031 break;
1032 default:
1033 FATAL_ERROR("Value::Value()");
1034 } // switch
1035 }
1036
1037 // v1 v2
1038 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
1039 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1040 {
1041 u.expr.v_optype = p_optype;
1042 u.expr.state = EXPR_NOT_CHECKED;
1043 switch(p_optype) {
1044 case OPTYPE_ADD:
1045 case OPTYPE_SUBTRACT:
1046 case OPTYPE_MULTIPLY:
1047 case OPTYPE_DIVIDE:
1048 case OPTYPE_MOD:
1049 case OPTYPE_REM:
1050 case OPTYPE_CONCAT:
1051 case OPTYPE_EQ:
1052 case OPTYPE_LT:
1053 case OPTYPE_GT:
1054 case OPTYPE_NE:
1055 case OPTYPE_GE:
1056 case OPTYPE_LE:
1057 case OPTYPE_AND:
1058 case OPTYPE_OR:
1059 case OPTYPE_XOR:
1060 case OPTYPE_AND4B:
1061 case OPTYPE_OR4B:
1062 case OPTYPE_XOR4B:
1063 case OPTYPE_SHL:
1064 case OPTYPE_SHR:
1065 case OPTYPE_ROTL:
1066 case OPTYPE_ROTR:
1067 case OPTYPE_INT2BIT:
1068 case OPTYPE_INT2HEX:
1069 case OPTYPE_INT2OCT:
1070 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1071 u.expr.v1=p_v1;
1072 u.expr.v2=p_v2;
1073 break;
1074 case OPTYPE_UNICHAR2OCT:
1075 case OPTYPE_OCT2UNICHAR:
1076 case OPTYPE_ENCODE_BASE64:
1077 if(!p_v1) FATAL_ERROR("Value::Value()");
1078 u.expr.v1=p_v1;
1079 // p_v2 may be NULL if there is no second param
1080 u.expr.v2=p_v2;
1081 break;
1082 default:
1083 FATAL_ERROR("Value::Value()");
1084 } // switch
1085 }
1086
1087 // ti1 v2 v3 ti4
1088 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1089 Value *p_v3, TemplateInstance *p_ti4) :
1090 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1091 {
1092 u.expr.v_optype = p_optype;
1093 u.expr.state = EXPR_NOT_CHECKED;
1094 switch (p_optype) {
1095 case OPTYPE_REPLACE:
1096 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1097 u.expr.ti1 = p_ti1;
1098 u.expr.v2 = p_v2;
1099 u.expr.v3 = p_v3;
1100 u.expr.ti4 = p_ti4;
1101 break;
1102 default:
1103 FATAL_ERROR("Value::Value()");
1104 } // switch
1105 }
1106
1107 // v1 v2 v3
1108 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1109 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1110 {
1111 u.expr.v_optype = p_optype;
1112 u.expr.state = EXPR_NOT_CHECKED;
1113 switch(p_optype) {
1114 case OPTYPE_DECOMP:
1115 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1116 u.expr.v1=p_v1;
1117 u.expr.v2=p_v2;
1118 u.expr.v3=p_v3;
1119 break;
1120 default:
1121 FATAL_ERROR("Value::Value()");
1122 } // switch
1123 }
1124
1125 // ti1 [v2]
1126 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2)
1127 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1128 {
1129 u.expr.v_optype = p_optype;
1130 u.expr.state = EXPR_NOT_CHECKED;
1131 switch(p_optype) {
1132 case OPTYPE_ENCVALUE_UNICHAR:
1133 if(!p_ti1 || !p_v2) FATAL_ERROR("Value::Value()");
1134 u.expr.ti1=p_ti1;
1135 u.expr.v2=p_v2;
1136 break;
1137 default:
1138 FATAL_ERROR("Value::Value()");
1139 } // switch
1140 }
1141
1142 // ti1 v2 v3
1143 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1144 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1145 {
1146 u.expr.v_optype=p_optype;
1147 u.expr.state=EXPR_NOT_CHECKED;
1148 switch(p_optype) {
1149 case OPTYPE_SUBSTR:
1150 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1151 u.expr.ti1 = p_ti1;
1152 u.expr.v2=p_v2;
1153 u.expr.v3=p_v3;
1154 break;
1155 default:
1156 FATAL_ERROR("Value::Value()");
1157 } // switch
1158 }
1159
1160 // ti1 t2 v3
1161 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1162 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1163 {
1164 u.expr.v_optype=p_optype;
1165 u.expr.state=EXPR_NOT_CHECKED;
1166 switch(p_optype) {
1167 case OPTYPE_REGEXP:
1168 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1169 u.expr.ti1 = p_ti1;
1170 u.expr.t2 = p_t2;
1171 u.expr.v3=p_v3;
1172 break;
1173 default:
1174 FATAL_ERROR("Value::Value()");
1175 } // switch
1176 }
1177
1178 // v1 t2
1179 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1180 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1181 {
1182 u.expr.v_optype = p_optype;
1183 u.expr.state = EXPR_NOT_CHECKED;
1184 switch(p_optype) {
1185 case OPTYPE_MATCH:
1186 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1187 u.expr.v1=p_v1;
1188 u.expr.t2=p_t2;
1189 break;
1190 default:
1191 FATAL_ERROR("Value::Value()");
1192 } // switch
1193 }
1194
1195 // r1 i2
1196 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1197 Identifier *p_i2)
1198 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1199 {
1200 u.expr.v_optype = p_optype;
1201 u.expr.state = EXPR_NOT_CHECKED;
1202 switch(p_optype) {
1203 case OPTYPE_ISCHOSEN:
1204 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1205 u.expr.r1=p_r1;
1206 u.expr.i2=p_i2;
1207 break;
1208 default:
1209 FATAL_ERROR("Value::Value()");
1210 } // switch
1211 }
1212
1213 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1214 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1215 {
1216 u.expr.v_optype = p_optype;
1217 u.expr.state = EXPR_NOT_CHECKED;
1218 switch(p_optype) {
1219 case OPTYPE_LOG2STR:
1220 case OPTYPE_ANY2UNISTR:
1221 if (!p_logargs) FATAL_ERROR("Value::Value()");
1222 u.expr.logargs = p_logargs;
1223 break;
1224 default:
1225 FATAL_ERROR("Value::Value()");
1226 } // switch
1227 }
1228
1229 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1230 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1231 {
1232 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1233 switch (p_macrotype) {
1234 case MACRO_MODULEID:
1235 case MACRO_FILENAME:
1236 case MACRO_BFILENAME:
1237 case MACRO_FILEPATH:
1238 case MACRO_LINENUMBER:
1239 case MACRO_LINENUMBER_C:
1240 case MACRO_DEFINITIONID:
1241 case MACRO_SCOPE:
1242 case MACRO_TESTCASEID:
1243 break;
1244 default:
1245 FATAL_ERROR("Value::Value()");
1246 }
1247 u.macro = p_macrotype;
1248 }
1249
1250 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1251 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1252 {
1253 if(!p_nvs) FATAL_ERROR("NULL parameter");
1254 switch(valuetype) {
1255 case V_SEQ:
1256 case V_SET:
1257 u.val_nvs=p_nvs;
1258 break;
1259 default:
1260 FATAL_ERROR("Value::Value()");
1261 } // switch
1262 }
1263
1264 Value::Value(valuetype_t p_vt, Reference *p_ref)
1265 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1266 {
1267 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1268 switch(p_vt) {
1269 case V_REFD:
1270 u.ref.ref = p_ref;
1271 u.ref.refd_last = 0;
1272 break;
1273 case V_REFER:
1274 u.refered = p_ref;
1275 break;
1276 default:
1277 FATAL_ERROR("Value::Value()");
1278 }
1279 }
1280
1281 Value::Value(valuetype_t p_vt, Block *p_block)
1282 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1283 {
1284 if(!p_block) FATAL_ERROR("NULL parameter");
1285 switch(valuetype) {
1286 case V_UNDEF_BLOCK:
1287 u.block=p_block;
1288 break;
1289 default:
1290 FATAL_ERROR("Value::Value()");
1291 } // switch
1292 }
1293
1294 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1295 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1296 {
1297 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1298 switch (p_verdict) {
1299 case Verdict_NONE:
1300 case Verdict_PASS:
1301 case Verdict_INCONC:
1302 case Verdict_FAIL:
1303 case Verdict_ERROR:
1304 break;
1305 default:
1306 FATAL_ERROR("Value::Value()");
1307 } // switch
1308 u.verdict = p_verdict;
1309 }
1310
1311 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1312 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1313 {
1314 u.expr.v_optype = p_optype;
1315 u.expr.state = EXPR_NOT_CHECKED;
1316 switch(p_optype) {
1317 case OPTYPE_DECODE:
1318 case OPTYPE_DECVALUE_UNICHAR:
1319 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1320 u.expr.r1=p_r1;
1321 u.expr.r2=p_r2;
1322 break;
1323 default:
1324 FATAL_ERROR("Value::Value()");
1325 } // switch
1326 }
1327
1328 // r1 r2 [v3]
1329 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2,
1330 Value *p_v3)
1331 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1332 {
1333 u.expr.v_optype = p_optype;
1334 u.expr.state = EXPR_NOT_CHECKED;
1335 switch(p_optype) {
1336 case OPTYPE_DECVALUE_UNICHAR:
1337 if(!p_r1 || !p_r2 || !p_v3) FATAL_ERROR("Value::Value()");
1338 u.expr.r1=p_r1;
1339 u.expr.r2=p_r2;
1340 u.expr.v3=p_v3;
1341 break;
1342 default:
1343 FATAL_ERROR("Value::Value()");
1344 } // switch
1345 }
1346
1347 Value::~Value()
1348 {
1349 clean_up();
1350 }
1351
1352 Value *Value::clone() const
1353 {
1354 return new Value(*this);
1355 }
1356
1357 Value::operationtype_t Value::get_optype() const
1358 {
1359 if(valuetype!=V_EXPR)
1360 FATAL_ERROR("Value::get_optype()");
1361 return u.expr.v_optype;
1362 }
1363
1364 void Value::set_my_governor(Type *p_gov)
1365 {
1366 if(!p_gov)
1367 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1368 my_governor=p_gov;
1369 }
1370
1371 Type *Value::get_my_governor() const
1372 {
1373 return my_governor;
1374 }
1375
1376 void Value::set_fullname(const string& p_fullname)
1377 {
1378 GovernedSimple::set_fullname(p_fullname);
1379 switch(valuetype) {
1380 case V_CHARSYMS:
1381 u.char_syms->set_fullname(p_fullname);
1382 break;
1383 case V_OID:
1384 case V_ROID:
1385 for(size_t i=0; i<u.oid_comps->size(); i++)
1386 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1387 break;
1388 case V_CHOICE:
1389 u.choice.alt_value->set_fullname(p_fullname + "." +
1390 u.choice.alt_name->get_dispname());
1391 break;
1392 case V_SEQOF:
1393 case V_SETOF:
1394 case V_ARRAY:
1395 u.val_vs->set_fullname(p_fullname);
1396 break;
1397 case V_SEQ:
1398 case V_SET:
1399 u.val_nvs->set_fullname(p_fullname);
1400 break;
1401 case V_REFD:
1402 u.ref.ref->set_fullname(p_fullname);
1403 break;
1404 case V_REFER:
1405 u.refered->set_fullname(p_fullname);
1406 break;
1407 case V_INVOKE:
1408 u.invoke.v->set_fullname(p_fullname);
1409 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1410 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1411 break;
1412 case V_EXPR:
1413 set_fullname_expr(p_fullname);
1414 break;
1415 default:
1416 break;
1417 } // switch
1418 }
1419
1420 void Value::set_my_scope(Scope *p_scope)
1421 {
1422 GovernedSimple::set_my_scope(p_scope);
1423 switch(valuetype) {
1424 case V_CHARSYMS:
1425 u.char_syms->set_my_scope(p_scope);
1426 break;
1427 case V_OID:
1428 case V_ROID:
1429 for(size_t i=0; i<u.oid_comps->size(); i++)
1430 (*u.oid_comps)[i]->set_my_scope(p_scope);
1431 break;
1432 case V_CHOICE:
1433 u.choice.alt_value->set_my_scope(p_scope);
1434 break;
1435 case V_SEQOF:
1436 case V_SETOF:
1437 case V_ARRAY:
1438 u.val_vs->set_my_scope(p_scope);
1439 break;
1440 case V_SEQ:
1441 case V_SET:
1442 u.val_nvs->set_my_scope(p_scope);
1443 break;
1444 case V_REFD:
1445 u.ref.ref->set_my_scope(p_scope);
1446 break;
1447 case V_REFER:
1448 u.refered->set_my_scope(p_scope);
1449 break;
1450 case V_INVOKE:
1451 u.invoke.v->set_my_scope(p_scope);
1452 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1453 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1454 break;
1455 case V_EXPR:
1456 set_my_scope_expr(p_scope);
1457 break;
1458 default:
1459 break;
1460 } // switch
1461 }
1462
1463 void Value::set_fullname_expr(const string& p_fullname)
1464 {
1465 switch (u.expr.v_optype) {
1466 case OPTYPE_RND: // -
1467 case OPTYPE_COMP_NULL:
1468 case OPTYPE_COMP_MTC:
1469 case OPTYPE_COMP_SYSTEM:
1470 case OPTYPE_COMP_SELF:
1471 case OPTYPE_COMP_RUNNING_ANY:
1472 case OPTYPE_COMP_RUNNING_ALL:
1473 case OPTYPE_COMP_ALIVE_ANY:
1474 case OPTYPE_COMP_ALIVE_ALL:
1475 case OPTYPE_TMR_RUNNING_ANY:
1476 case OPTYPE_GETVERDICT:
1477 case OPTYPE_TESTCASENAME:
1478 case OPTYPE_PROF_RUNNING:
1479 break;
1480 case OPTYPE_UNARYPLUS: // v1
1481 case OPTYPE_UNARYMINUS:
1482 case OPTYPE_NOT:
1483 case OPTYPE_NOT4B:
1484 case OPTYPE_BIT2HEX:
1485 case OPTYPE_BIT2INT:
1486 case OPTYPE_BIT2OCT:
1487 case OPTYPE_BIT2STR:
1488 case OPTYPE_CHAR2INT:
1489 case OPTYPE_CHAR2OCT:
1490 case OPTYPE_COMP_RUNNING:
1491 case OPTYPE_COMP_ALIVE:
1492 case OPTYPE_FLOAT2INT:
1493 case OPTYPE_FLOAT2STR:
1494 case OPTYPE_HEX2BIT:
1495 case OPTYPE_HEX2INT:
1496 case OPTYPE_HEX2OCT:
1497 case OPTYPE_HEX2STR:
1498 case OPTYPE_INT2CHAR:
1499 case OPTYPE_INT2FLOAT:
1500 case OPTYPE_INT2STR:
1501 case OPTYPE_INT2UNICHAR:
1502 case OPTYPE_OCT2BIT:
1503 case OPTYPE_OCT2CHAR:
1504 case OPTYPE_OCT2HEX:
1505 case OPTYPE_OCT2INT:
1506 case OPTYPE_OCT2STR:
1507 case OPTYPE_STR2BIT:
1508 case OPTYPE_STR2FLOAT:
1509 case OPTYPE_STR2HEX:
1510 case OPTYPE_STR2INT:
1511 case OPTYPE_STR2OCT:
1512 case OPTYPE_UNICHAR2INT:
1513 case OPTYPE_UNICHAR2CHAR:
1514 case OPTYPE_ENUM2INT:
1515 case OPTYPE_RNDWITHVAL:
1516 case OPTYPE_REMOVE_BOM:
1517 case OPTYPE_GET_STRINGENCODING:
1518 case OPTYPE_DECODE_BASE64:
1519 u.expr.v1->set_fullname(p_fullname+".<operand>");
1520 break;
1521 case OPTYPE_ADD: // v1 v2
1522 case OPTYPE_SUBTRACT:
1523 case OPTYPE_MULTIPLY:
1524 case OPTYPE_DIVIDE:
1525 case OPTYPE_MOD:
1526 case OPTYPE_REM:
1527 case OPTYPE_CONCAT:
1528 case OPTYPE_EQ:
1529 case OPTYPE_LT:
1530 case OPTYPE_GT:
1531 case OPTYPE_NE:
1532 case OPTYPE_GE:
1533 case OPTYPE_LE:
1534 case OPTYPE_AND:
1535 case OPTYPE_OR:
1536 case OPTYPE_XOR:
1537 case OPTYPE_AND4B:
1538 case OPTYPE_OR4B:
1539 case OPTYPE_XOR4B:
1540 case OPTYPE_SHL:
1541 case OPTYPE_SHR:
1542 case OPTYPE_ROTL:
1543 case OPTYPE_ROTR:
1544 case OPTYPE_INT2BIT:
1545 case OPTYPE_INT2HEX:
1546 case OPTYPE_INT2OCT:
1547 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1548 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1549 break;
1550 case OPTYPE_UNICHAR2OCT:
1551 case OPTYPE_OCT2UNICHAR:
1552 case OPTYPE_ENCODE_BASE64:
1553 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1554 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1555 break;
1556 case OPTYPE_DECODE:
1557 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1558 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1559 break;
1560 case OPTYPE_SUBSTR:
1561 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1562 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1563 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1564 break;
1565 case OPTYPE_REGEXP:
1566 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1567 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1568 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1569 break;
1570 case OPTYPE_DECOMP: // v1 v2 v3
1571 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1572 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1573 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1574 break;
1575 case OPTYPE_REPLACE:
1576 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1577 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1578 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1579 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1580 break;
1581 case OPTYPE_LENGTHOF: // ti1
1582 case OPTYPE_SIZEOF: // ti1
1583 case OPTYPE_VALUEOF: // ti1
1584 case OPTYPE_ISVALUE:
1585 case OPTYPE_ISBOUND:
1586 case OPTYPE_ENCODE:
1587 case OPTYPE_ISPRESENT:
1588 case OPTYPE_TTCN2STRING:
1589 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1590 break;
1591 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
1592 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1593 if (u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1594 break;
1595 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1596 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1597 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1598 if (u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1599 case OPTYPE_UNDEF_RUNNING: // r1
1600 case OPTYPE_TMR_READ:
1601 case OPTYPE_TMR_RUNNING:
1602 case OPTYPE_ACTIVATE:
1603 u.expr.r1->set_fullname(p_fullname+".<operand>");
1604 break;
1605 case OPTYPE_EXECUTE: // r1 [v2]
1606 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1607 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1608 break;
1609 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1610 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1611 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1612 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1613 break;
1614 case OPTYPE_MATCH: // v1 t2
1615 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1616 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1617 break;
1618 case OPTYPE_ISCHOSEN: // r1 i2
1619 u.expr.r1->set_fullname(p_fullname+".<operand>");
1620 break;
1621 case OPTYPE_ISCHOSEN_V: // v1 i2
1622 u.expr.v1->set_fullname(p_fullname+".<operand>");
1623 break;
1624 case OPTYPE_ISCHOSEN_T: // t1 i2
1625 u.expr.t1->set_fullname(p_fullname+".<operand>");
1626 break;
1627 case OPTYPE_ACTIVATE_REFD:
1628 u.expr.v1->set_fullname(p_fullname+".<reference>");
1629 if(u.expr.state!=EXPR_CHECKED)
1630 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1631 else
1632 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1633 break;
1634 case OPTYPE_EXECUTE_REFD:
1635 u.expr.v1->set_fullname(p_fullname+".<reference>");
1636 if(u.expr.state!=EXPR_CHECKED)
1637 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1638 else
1639 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1640 if(u.expr.v3)
1641 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1642 break;
1643 case OPTYPE_LOG2STR:
1644 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1645 break;
1646 case OPTYPE_ANY2UNISTR:
1647 u.expr.logargs->set_fullname(p_fullname+".<logarg>");
1648 break;
1649 default:
1650 FATAL_ERROR("Value::set_fullname_expr()");
1651 } // switch
1652 }
1653
1654 void Value::set_my_scope_expr(Scope *p_scope)
1655 {
1656 switch (u.expr.v_optype) {
1657 case OPTYPE_RND: // -
1658 case OPTYPE_COMP_NULL:
1659 case OPTYPE_COMP_MTC:
1660 case OPTYPE_COMP_SYSTEM:
1661 case OPTYPE_COMP_SELF:
1662 case OPTYPE_COMP_RUNNING_ANY:
1663 case OPTYPE_COMP_RUNNING_ALL:
1664 case OPTYPE_COMP_ALIVE_ANY:
1665 case OPTYPE_COMP_ALIVE_ALL:
1666 case OPTYPE_TMR_RUNNING_ANY:
1667 case OPTYPE_GETVERDICT:
1668 case OPTYPE_TESTCASENAME:
1669 case OPTYPE_PROF_RUNNING:
1670 break;
1671 case OPTYPE_UNARYPLUS: // v1
1672 case OPTYPE_UNARYMINUS:
1673 case OPTYPE_NOT:
1674 case OPTYPE_NOT4B:
1675 case OPTYPE_BIT2HEX:
1676 case OPTYPE_BIT2INT:
1677 case OPTYPE_BIT2OCT:
1678 case OPTYPE_BIT2STR:
1679 case OPTYPE_CHAR2INT:
1680 case OPTYPE_CHAR2OCT:
1681 case OPTYPE_COMP_RUNNING:
1682 case OPTYPE_COMP_ALIVE:
1683 case OPTYPE_FLOAT2INT:
1684 case OPTYPE_FLOAT2STR:
1685 case OPTYPE_HEX2BIT:
1686 case OPTYPE_HEX2INT:
1687 case OPTYPE_HEX2OCT:
1688 case OPTYPE_HEX2STR:
1689 case OPTYPE_INT2CHAR:
1690 case OPTYPE_INT2FLOAT:
1691 case OPTYPE_INT2STR:
1692 case OPTYPE_INT2UNICHAR:
1693 case OPTYPE_OCT2BIT:
1694 case OPTYPE_OCT2CHAR:
1695 case OPTYPE_OCT2HEX:
1696 case OPTYPE_OCT2INT:
1697 case OPTYPE_OCT2STR:
1698 case OPTYPE_STR2BIT:
1699 case OPTYPE_STR2FLOAT:
1700 case OPTYPE_STR2HEX:
1701 case OPTYPE_STR2INT:
1702 case OPTYPE_STR2OCT:
1703 case OPTYPE_UNICHAR2INT:
1704 case OPTYPE_UNICHAR2CHAR:
1705 case OPTYPE_ENUM2INT:
1706 case OPTYPE_RNDWITHVAL:
1707 case OPTYPE_REMOVE_BOM:
1708 case OPTYPE_GET_STRINGENCODING:
1709 case OPTYPE_DECODE_BASE64:
1710 u.expr.v1->set_my_scope(p_scope);
1711 break;
1712 case OPTYPE_ADD: // v1 v2
1713 case OPTYPE_SUBTRACT:
1714 case OPTYPE_MULTIPLY:
1715 case OPTYPE_DIVIDE:
1716 case OPTYPE_MOD:
1717 case OPTYPE_REM:
1718 case OPTYPE_CONCAT:
1719 case OPTYPE_EQ:
1720 case OPTYPE_LT:
1721 case OPTYPE_GT:
1722 case OPTYPE_NE:
1723 case OPTYPE_GE:
1724 case OPTYPE_LE:
1725 case OPTYPE_AND:
1726 case OPTYPE_OR:
1727 case OPTYPE_XOR:
1728 case OPTYPE_AND4B:
1729 case OPTYPE_OR4B:
1730 case OPTYPE_XOR4B:
1731 case OPTYPE_SHL:
1732 case OPTYPE_SHR:
1733 case OPTYPE_ROTL:
1734 case OPTYPE_ROTR:
1735 case OPTYPE_INT2BIT:
1736 case OPTYPE_INT2HEX:
1737 case OPTYPE_INT2OCT:
1738 u.expr.v1->set_my_scope(p_scope);
1739 u.expr.v2->set_my_scope(p_scope);
1740 break;
1741 case OPTYPE_UNICHAR2OCT:
1742 case OPTYPE_OCT2UNICHAR:
1743 case OPTYPE_ENCODE_BASE64:
1744 u.expr.v1->set_my_scope(p_scope);
1745 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1746 break;
1747 case OPTYPE_DECODE:
1748 u.expr.r1->set_my_scope(p_scope);
1749 u.expr.r2->set_my_scope(p_scope);
1750 break;
1751 case OPTYPE_SUBSTR:
1752 u.expr.ti1->set_my_scope(p_scope);
1753 u.expr.v2->set_my_scope(p_scope);
1754 u.expr.v3->set_my_scope(p_scope);
1755 break;
1756 case OPTYPE_REGEXP:
1757 u.expr.ti1->set_my_scope(p_scope);
1758 u.expr.t2->set_my_scope(p_scope);
1759 u.expr.v3->set_my_scope(p_scope);
1760 break;
1761 case OPTYPE_DECOMP: // v1 v2 v3
1762 u.expr.v1->set_my_scope(p_scope);
1763 u.expr.v2->set_my_scope(p_scope);
1764 u.expr.v3->set_my_scope(p_scope);
1765 break;
1766 case OPTYPE_REPLACE:
1767 u.expr.ti1->set_my_scope(p_scope);
1768 u.expr.v2->set_my_scope(p_scope);
1769 u.expr.v3->set_my_scope(p_scope);
1770 u.expr.ti4->set_my_scope(p_scope);
1771 break;
1772 case OPTYPE_LENGTHOF: // ti1
1773 case OPTYPE_SIZEOF: // ti1
1774 case OPTYPE_VALUEOF: // ti1
1775 case OPTYPE_ISVALUE:
1776 case OPTYPE_ISBOUND:
1777 case OPTYPE_ENCODE:
1778 case OPTYPE_ISPRESENT:
1779 case OPTYPE_TTCN2STRING:
1780 u.expr.ti1->set_my_scope(p_scope);
1781 break;
1782 case OPTYPE_ENCVALUE_UNICHAR: //ti1 [v2]
1783 u.expr.ti1->set_my_scope(p_scope);
1784 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1785 break;
1786 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1787 u.expr.r1->set_my_scope(p_scope);
1788 u.expr.r2->set_my_scope(p_scope);
1789 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1790 break;
1791 case OPTYPE_UNDEF_RUNNING: // r1
1792 case OPTYPE_TMR_READ:
1793 case OPTYPE_TMR_RUNNING:
1794 case OPTYPE_ACTIVATE:
1795 u.expr.r1->set_my_scope(p_scope);
1796 break;
1797 case OPTYPE_EXECUTE: // r1 [v2]
1798 u.expr.r1->set_my_scope(p_scope);
1799 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1800 break;
1801 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1802 u.expr.r1->set_my_scope(p_scope);
1803 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1804 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1805 break;
1806 case OPTYPE_MATCH: // v1 t2
1807 u.expr.v1->set_my_scope(p_scope);
1808 u.expr.t2->set_my_scope(p_scope);
1809 break;
1810 case OPTYPE_ISCHOSEN: // r1 i2
1811 u.expr.r1->set_my_scope(p_scope);
1812 break;
1813 case OPTYPE_ISCHOSEN_V: // v1 i2
1814 u.expr.v1->set_my_scope(p_scope);
1815 break;
1816 case OPTYPE_ISCHOSEN_T: // t1 i2
1817 u.expr.t1->set_my_scope(p_scope);
1818 break;
1819 case OPTYPE_ACTIVATE_REFD:
1820 u.expr.v1->set_my_scope(p_scope);
1821 if(u.expr.state!=EXPR_CHECKED) {
1822 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1823 else
1824 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1825 } break;
1826 case OPTYPE_EXECUTE_REFD:
1827 u.expr.v1->set_my_scope(p_scope);
1828 if(u.expr.state!=EXPR_CHECKED) {
1829 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1830 else
1831 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1832 }
1833 if(u.expr.v3)
1834 u.expr.v3->set_my_scope(p_scope);
1835 break;
1836 case OPTYPE_LOG2STR:
1837 case OPTYPE_ANY2UNISTR:
1838 u.expr.logargs->set_my_scope(p_scope);
1839 break;
1840 default:
1841 FATAL_ERROR("Value::set_my_scope_expr()");
1842 } // switch
1843 }
1844
1845 void Value::set_genname_recursive(const string& p_genname)
1846 {
1847 size_t genname_len = p_genname.size();
1848 if (genname_len >= 4 &&
1849 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1850 // if the genname ends with ()() (i.e. the value stands for an optional
1851 // field) then drop the last () from the own genname, but leave it for
1852 // the embedded values
1853 set_genname(p_genname.substr(0, genname_len - 2));
1854 } else set_genname(p_genname);
1855 switch(valuetype) {
1856 case V_CHOICE: {
1857 string embedded_genname(p_genname);
1858 embedded_genname += '.';
1859 // If this is a choice value for an anytype, prepend the AT_ prefix
1860 // to the name of the alternative. The genname is used later in
1861 // Common::Value::generate_code_init_se()
1862 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1863 embedded_genname += "AT_";
1864 embedded_genname += u.choice.alt_name->get_name();
1865 embedded_genname += "()";
1866 u.choice.alt_value->set_genname_recursive(embedded_genname);
1867 break; }
1868 case V_SEQOF:
1869 case V_SETOF: {
1870 if (!is_indexed()) {
1871 size_t nof_vs = u.val_vs->get_nof_vs();
1872 for (size_t i = 0; i < nof_vs; i++) {
1873 string embedded_genname(p_genname);
1874 embedded_genname += '[';
1875 embedded_genname += Int2string(i);
1876 embedded_genname += ']';
1877 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1878 }
1879 } else {
1880 size_t nof_ivs = u.val_vs->get_nof_ivs();
1881 for (size_t i = 0; i < nof_ivs; i++) {
1882 string embedded_genname(p_genname);
1883 embedded_genname += '[';
1884 embedded_genname += Int2string(i);
1885 embedded_genname += ']';
1886 u.val_vs->get_iv_byIndex(i)->get_value()
1887 ->set_genname_recursive(embedded_genname);
1888 }
1889 }
1890 break; }
1891 case V_ARRAY: {
1892 if (!my_governor) return; // error recovery
1893 Type *type = my_governor->get_type_refd_last();
1894 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1895 Int offset = type->get_dimension()->get_offset();
1896 if (!is_indexed()) {
1897 size_t nof_vs = u.val_vs->get_nof_vs();
1898 for (size_t i = 0; i < nof_vs; i++) {
1899 string embedded_genname(p_genname);
1900 embedded_genname += '[';
1901 embedded_genname += Int2string(offset + i);
1902 embedded_genname += ']';
1903 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1904 }
1905 } else {
1906 size_t nof_ivs = u.val_vs->get_nof_ivs();
1907 for (size_t i = 0; i < nof_ivs; i++) {
1908 string embedded_genname(p_genname);
1909 embedded_genname += '[';
1910 embedded_genname += Int2string(offset + i);
1911 embedded_genname += ']';
1912 u.val_vs->get_iv_byIndex(i)->get_value()
1913 ->set_genname_recursive(embedded_genname);
1914 }
1915 }
1916 break; }
1917 case V_SEQ:
1918 case V_SET: {
1919 if (!my_governor) return; // error recovery
1920 Type *t = my_governor->get_type_refd_last();
1921 if (!t->is_secho()) return; // error recovery
1922 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1923 for (size_t i = 0; i < nof_nvs; i++) {
1924 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1925 const Identifier& id = nv->get_name();
1926 if (!t->has_comp_withName(id)) return; // error recovery
1927 string embedded_genname(p_genname);
1928 embedded_genname += '.';
1929 embedded_genname += id.get_name();
1930 embedded_genname += "()";
1931 if (t->get_comp_byName(id)->get_is_optional())
1932 embedded_genname += "()";
1933 nv->get_value()->set_genname_recursive(embedded_genname);
1934 }
1935 break; }
1936 default:
1937 break;
1938 } // switch
1939 }
1940
1941 void Value::set_genname_prefix(const char *p_genname_prefix)
1942 {
1943 GovernedSimple::set_genname_prefix(p_genname_prefix);
1944 switch(valuetype) {
1945 case V_CHOICE:
1946 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1947 break;
1948 case V_SEQOF:
1949 case V_SETOF:
1950 case V_ARRAY:
1951 if (!is_indexed()) {
1952 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1953 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1954 } else {
1955 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1956 u.val_vs->get_iv_byIndex(i)->get_value()
1957 ->set_genname_prefix(p_genname_prefix);
1958 }
1959 break;
1960 case V_SEQ:
1961 case V_SET:
1962 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1963 u.val_nvs->get_nv_byIndex(i)->get_value()
1964 ->set_genname_prefix(p_genname_prefix);
1965 break;
1966 default:
1967 break;
1968 } // switch
1969 }
1970
1971 void Value::set_code_section(code_section_t p_code_section)
1972 {
1973 GovernedSimple::set_code_section(p_code_section);
1974 switch(valuetype) {
1975 case V_EXPR:
1976 switch (u.expr.v_optype) {
1977 case OPTYPE_RND: // -
1978 case OPTYPE_COMP_NULL:
1979 case OPTYPE_COMP_MTC:
1980 case OPTYPE_COMP_SYSTEM:
1981 case OPTYPE_COMP_SELF:
1982 case OPTYPE_COMP_RUNNING_ANY:
1983 case OPTYPE_COMP_RUNNING_ALL:
1984 case OPTYPE_COMP_ALIVE_ANY:
1985 case OPTYPE_COMP_ALIVE_ALL:
1986 case OPTYPE_TMR_RUNNING_ANY:
1987 case OPTYPE_GETVERDICT:
1988 case OPTYPE_TESTCASENAME:
1989 case OPTYPE_PROF_RUNNING:
1990 break;
1991 case OPTYPE_UNARYPLUS: // v1
1992 case OPTYPE_UNARYMINUS:
1993 case OPTYPE_NOT:
1994 case OPTYPE_NOT4B:
1995 case OPTYPE_BIT2HEX:
1996 case OPTYPE_BIT2INT:
1997 case OPTYPE_BIT2OCT:
1998 case OPTYPE_BIT2STR:
1999 case OPTYPE_CHAR2INT:
2000 case OPTYPE_CHAR2OCT:
2001 case OPTYPE_COMP_RUNNING:
2002 case OPTYPE_COMP_ALIVE:
2003 case OPTYPE_FLOAT2INT:
2004 case OPTYPE_FLOAT2STR:
2005 case OPTYPE_HEX2BIT:
2006 case OPTYPE_HEX2INT:
2007 case OPTYPE_HEX2OCT:
2008 case OPTYPE_HEX2STR:
2009 case OPTYPE_INT2CHAR:
2010 case OPTYPE_INT2FLOAT:
2011 case OPTYPE_INT2STR:
2012 case OPTYPE_INT2UNICHAR:
2013 case OPTYPE_OCT2BIT:
2014 case OPTYPE_OCT2CHAR:
2015 case OPTYPE_OCT2HEX:
2016 case OPTYPE_OCT2INT:
2017 case OPTYPE_OCT2STR:
2018 case OPTYPE_STR2BIT:
2019 case OPTYPE_STR2FLOAT:
2020 case OPTYPE_STR2HEX:
2021 case OPTYPE_STR2INT:
2022 case OPTYPE_STR2OCT:
2023 case OPTYPE_UNICHAR2INT:
2024 case OPTYPE_UNICHAR2CHAR:
2025 case OPTYPE_ENUM2INT:
2026 case OPTYPE_RNDWITHVAL:
2027 case OPTYPE_GET_STRINGENCODING:
2028 case OPTYPE_DECODE_BASE64:
2029 case OPTYPE_REMOVE_BOM:
2030 u.expr.v1->set_code_section(p_code_section);
2031 break;
2032 case OPTYPE_ADD: // v1 v2
2033 case OPTYPE_SUBTRACT:
2034 case OPTYPE_MULTIPLY:
2035 case OPTYPE_DIVIDE:
2036 case OPTYPE_MOD:
2037 case OPTYPE_REM:
2038 case OPTYPE_CONCAT:
2039 case OPTYPE_EQ:
2040 case OPTYPE_LT:
2041 case OPTYPE_GT:
2042 case OPTYPE_NE:
2043 case OPTYPE_GE:
2044 case OPTYPE_LE:
2045 case OPTYPE_AND:
2046 case OPTYPE_OR:
2047 case OPTYPE_XOR:
2048 case OPTYPE_AND4B:
2049 case OPTYPE_OR4B:
2050 case OPTYPE_XOR4B:
2051 case OPTYPE_SHL:
2052 case OPTYPE_SHR:
2053 case OPTYPE_ROTL:
2054 case OPTYPE_ROTR:
2055 case OPTYPE_INT2BIT:
2056 case OPTYPE_INT2HEX:
2057 case OPTYPE_INT2OCT:
2058 u.expr.v1->set_code_section(p_code_section);
2059 u.expr.v2->set_code_section(p_code_section);
2060 break;
2061 case OPTYPE_UNICHAR2OCT:
2062 case OPTYPE_OCT2UNICHAR:
2063 case OPTYPE_ENCODE_BASE64:
2064 u.expr.v1->set_code_section(p_code_section);
2065 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2066 break;
2067 case OPTYPE_DECODE:
2068 u.expr.r1->set_code_section(p_code_section);
2069 u.expr.r2->set_code_section(p_code_section);
2070 break;
2071 case OPTYPE_SUBSTR:
2072 u.expr.ti1->set_code_section(p_code_section);
2073 u.expr.v2->set_code_section(p_code_section);
2074 u.expr.v3->set_code_section(p_code_section);
2075 break;
2076 case OPTYPE_REGEXP:
2077 u.expr.ti1->set_code_section(p_code_section);
2078 u.expr.t2->set_code_section(p_code_section);
2079 u.expr.v3->set_code_section(p_code_section);
2080 break;
2081 case OPTYPE_DECOMP: // v1 v2 v3
2082 u.expr.v1->set_code_section(p_code_section);
2083 u.expr.v2->set_code_section(p_code_section);
2084 u.expr.v3->set_code_section(p_code_section);
2085 break;
2086 case OPTYPE_REPLACE:
2087 u.expr.ti1->set_code_section(p_code_section);
2088 u.expr.v2->set_code_section(p_code_section);
2089 u.expr.v3->set_code_section(p_code_section);
2090 u.expr.ti4->set_code_section(p_code_section);
2091 break;
2092 case OPTYPE_LENGTHOF: // ti1
2093 case OPTYPE_SIZEOF: // ti1
2094 case OPTYPE_VALUEOF: // ti1
2095 case OPTYPE_ISVALUE:
2096 case OPTYPE_ISBOUND:
2097 case OPTYPE_ENCODE:
2098 case OPTYPE_ISPRESENT:
2099 case OPTYPE_TTCN2STRING:
2100 u.expr.ti1->set_code_section(p_code_section);
2101 break;
2102 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
2103 u.expr.ti1->set_code_section(p_code_section);
2104 if (u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2105 break;
2106 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
2107 u.expr.r1->set_code_section(p_code_section);
2108 u.expr.r2->set_code_section(p_code_section);
2109 if (u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2110 break;
2111 case OPTYPE_UNDEF_RUNNING: // r1
2112 case OPTYPE_TMR_READ:
2113 case OPTYPE_TMR_RUNNING:
2114 case OPTYPE_ACTIVATE:
2115 u.expr.r1->set_code_section(p_code_section);
2116 break;
2117 case OPTYPE_EXECUTE: // r1 [v2]
2118 u.expr.r1->set_code_section(p_code_section);
2119 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2120 break;
2121 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2122 u.expr.r1->set_code_section(p_code_section);
2123 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2124 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2125 break;
2126 case OPTYPE_MATCH: // v1 t2
2127 u.expr.v1->set_code_section(p_code_section);
2128 u.expr.t2->set_code_section(p_code_section);
2129 break;
2130 case OPTYPE_ISCHOSEN: // r1 i2
2131 u.expr.r1->set_code_section(p_code_section);
2132 break;
2133 case OPTYPE_ISCHOSEN_V: // v1 i2
2134 u.expr.v1->set_code_section(p_code_section);
2135 break;
2136 case OPTYPE_ISCHOSEN_T: // t1 i2
2137 u.expr.t1->set_code_section(p_code_section);
2138 break;
2139 case OPTYPE_ACTIVATE_REFD:
2140 u.expr.v1->set_code_section(p_code_section);
2141 if(u.expr.state!=EXPR_CHECKED)
2142 u.expr.t_list2->set_code_section(p_code_section);
2143 else {
2144 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2145 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2146 u.expr.state = EXPR_CHECKED;
2147 }
2148 break;
2149 case OPTYPE_EXECUTE_REFD:
2150 u.expr.v1->set_code_section(p_code_section);
2151 if(u.expr.state!=EXPR_CHECKED)
2152 u.expr.t_list2->set_code_section(p_code_section);
2153 else {
2154 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2155 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2156 u.expr.state = EXPR_CHECKED;
2157 }
2158 if(u.expr.v3)
2159 u.expr.v3->set_code_section(p_code_section);
2160 break;
2161 case OPTYPE_LOG2STR:
2162 case OPTYPE_ANY2UNISTR:
2163 u.expr.logargs->set_code_section(p_code_section);
2164 break;
2165 default:
2166 FATAL_ERROR("Value::set_code_section()");
2167 } // switch
2168 break;
2169 case V_CHOICE:
2170 u.choice.alt_value->set_code_section(p_code_section);
2171 break;
2172 case V_SEQOF:
2173 case V_SETOF:
2174 case V_ARRAY:
2175 if (!is_indexed()) {
2176 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2177 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2178 } else {
2179 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2180 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2181 }
2182 break;
2183 case V_SEQ:
2184 case V_SET:
2185 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2186 u.val_nvs->get_nv_byIndex(i)->get_value()
2187 ->set_code_section(p_code_section);
2188 break;
2189 case V_REFD:
2190 u.ref.ref->set_code_section(p_code_section);
2191 break;
2192 case V_REFER:
2193 u.refered->set_code_section(p_code_section);
2194 break;
2195 case V_INVOKE:
2196 u.invoke.v->set_code_section(p_code_section);
2197 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2198 if(u.invoke.ap_list)
2199 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2200 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2201 break;
2202 default:
2203 break;
2204 } // switch
2205 }
2206
2207 void Value::change_sign()
2208 {
2209 switch(valuetype) {
2210 case V_INT:
2211 *u.val_Int=-*u.val_Int;
2212 break;
2213 case V_REAL:
2214 u.val_Real*=-1.0;
2215 break;
2216 case V_ERROR:
2217 break;
2218 default:
2219 FATAL_ERROR("Value::change_sign()");
2220 } // switch
2221 }
2222
2223 void Value::add_oid_comp(OID_comp* p_comp)
2224 {
2225 if(!p_comp)
2226 FATAL_ERROR("NULL parameter");
2227 u.oid_comps->add(p_comp);
2228 p_comp->set_fullname(get_fullname()+"."
2229 +Int2string(u.oid_comps->size()));
2230 p_comp->set_my_scope(my_scope);
2231 }
2232
2233 void Value::set_valuetype(valuetype_t p_valuetype)
2234 {
2235 if (valuetype == V_ERROR) return;
2236 else if (p_valuetype == V_ERROR) {
2237 if(valuetype==V_EXPR) {
2238 switch(u.expr.state) {
2239 case EXPR_CHECKING:
2240 u.expr.state=EXPR_CHECKING_ERR;
2241 // no break
2242 case EXPR_CHECKING_ERR:
2243 return;
2244 default:
2245 break;
2246 }
2247 }
2248 clean_up();
2249 valuetype = V_ERROR;
2250 return;
2251 }
2252 switch(valuetype) {
2253 case V_UNDEF_LOWERID:
2254 switch(p_valuetype) {
2255 case V_ENUM:
2256 case V_NAMEDINT:
2257 break;
2258 case V_REFD:
2259 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2260 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2261 u.ref.ref->set_my_scope(get_my_scope());
2262 u.ref.ref->set_fullname(get_fullname());
2263 u.ref.ref->set_location(*this);
2264 u.ref.refd_last = 0;
2265 break;
2266 default:
2267 FATAL_ERROR("Value::set_valuetype()");
2268 } // switch
2269 break;
2270 case V_UNDEF_BLOCK: {
2271 Block *t_block=u.block;
2272 Value *v=0;
2273 switch(p_valuetype) {
2274 case V_NAMEDBITS: {
2275 Node *node=t_block->parse(KW_Block_IdentifierList);
2276 v=dynamic_cast<Value*>(node);
2277 if(!v) {
2278 /* syntax error */
2279 u.ids=new map<string, Identifier>();
2280 }
2281 else {
2282 u.ids=v->u.ids; v->u.ids=0;
2283 }
2284 break;}
2285 case V_SEQOF: {
2286 Node *node=t_block->parse(KW_Block_SeqOfValue);
2287 v=dynamic_cast<Value*>(node);
2288 if(!v) {
2289 /* syntax error */
2290 u.val_vs=new Values();
2291 }
2292 else {
2293 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2294 }
2295 u.val_vs->set_my_scope(get_my_scope());
2296 u.val_vs->set_fullname(get_fullname());
2297 break;}
2298 case V_SETOF: {
2299 Node *node=t_block->parse(KW_Block_SetOfValue);
2300 v=dynamic_cast<Value*>(node);
2301 if(!v) {
2302 /* syntax error */
2303 u.val_vs=new Values();
2304 }
2305 else {
2306 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2307 }
2308 u.val_vs->set_my_scope(get_my_scope());
2309 u.val_vs->set_fullname(get_fullname());
2310 break;}
2311 case V_SEQ: {
2312 Node *node=t_block->parse(KW_Block_SequenceValue);
2313 v=dynamic_cast<Value*>(node);
2314 if(!v) {
2315 /* syntax error */
2316 u.val_nvs=new NamedValues();
2317 }
2318 else {
2319 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2320 }
2321 u.val_nvs->set_my_scope(get_my_scope());
2322 u.val_nvs->set_fullname(get_fullname());
2323 break;}
2324 case V_SET: {
2325 Node *node=t_block->parse(KW_Block_SetValue);
2326 v=dynamic_cast<Value*>(node);
2327 if(!v) {
2328 /* syntax error */
2329 u.val_nvs=new NamedValues();
2330 }
2331 else {
2332 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2333 }
2334 u.val_nvs->set_my_scope(get_my_scope());
2335 u.val_nvs->set_fullname(get_fullname());
2336 break;}
2337 case V_OID: {
2338 Node *node=t_block->parse(KW_Block_OIDValue);
2339 v=dynamic_cast<Value*>(node);
2340 if(!v) {
2341 /* syntax error */
2342 u.oid_comps=new vector<OID_comp>();
2343 }
2344 else {
2345 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2346 }
2347 for (size_t i = 0; i < u.oid_comps->size(); i++)
2348 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2349 break;}
2350 case V_ROID: {
2351 Node *node=t_block->parse(KW_Block_ROIDValue);
2352 v=dynamic_cast<Value*>(node);
2353 if(!v) {
2354 /* syntax error */
2355 u.oid_comps=new vector<OID_comp>();
2356 }
2357 else {
2358 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2359 }
2360 for (size_t i = 0; i < u.oid_comps->size(); i++)
2361 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2362 break;}
2363 case V_CHARSYMS: {
2364 Node *node=t_block->parse(KW_Block_CharStringValue);
2365 u.char_syms=dynamic_cast<CharSyms*>(node);
2366 if(!u.char_syms) {
2367 /* syntax error */
2368 u.char_syms=new CharSyms();
2369 }
2370 u.char_syms->set_my_scope(get_my_scope());
2371 u.char_syms->set_fullname(get_fullname());
2372 break;}
2373 default:
2374 FATAL_ERROR("Value::set_valuetype()");
2375 } // switch
2376 delete v;
2377 delete t_block;
2378 break;}
2379 case V_REFD:
2380 if (p_valuetype == V_USTR) {
2381 Value *v_last = get_value_refd_last();
2382 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2383 ustring *ustr = new ustring(*v_last->u.str.val_str);
2384 delete u.ref.ref;
2385 set_val_ustr(ustr);
2386 u.ustr.convert_str = true; // will be converted back to string
2387 } else FATAL_ERROR("Value::set_valuetype()");
2388 break;
2389 case V_CHARSYMS:
2390 switch(p_valuetype) {
2391 case V_CSTR: {
2392 const string& str = u.char_syms->get_string();
2393 delete u.char_syms;
2394 set_val_str(new string(str));
2395 break;}
2396 case V_USTR: {
2397 const ustring& ustr = u.char_syms->get_ustring();
2398 delete u.char_syms;
2399 set_val_ustr(new ustring(ustr));
2400 u.ustr.convert_str = false;
2401 break;}
2402 case V_ISO2022STR: {
2403 const string& str = u.char_syms->get_iso2022string();
2404 delete u.char_syms;
2405 set_val_str(new string(str));
2406 break;}
2407 default:
2408 FATAL_ERROR("Value::set_valuetype()");
2409 } // switch
2410 break;
2411 case V_INT: {
2412 Real val_Real;
2413 if (p_valuetype == V_REAL)
2414 val_Real = u.val_Int->to_real();
2415 else FATAL_ERROR("Value::set_valuetype()");
2416 clean_up();
2417 u.val_Real = val_Real;
2418 break; }
2419 case V_HSTR: {
2420 clean_up_string_elements(u.str.str_elements);
2421 string *old_str = u.str.val_str;
2422 switch(p_valuetype) {
2423 case V_BSTR:
2424 set_val_str(hex2bit(*old_str));
2425 break;
2426 case V_OSTR:
2427 set_val_str(asn_hex2oct(*old_str));
2428 break;
2429 default:
2430 FATAL_ERROR("Value::set_valuetype()");
2431 } // switch
2432 delete old_str;
2433 break;}
2434 case V_BSTR:
2435 clean_up_string_elements(u.str.str_elements);
2436 if (p_valuetype == V_OSTR) {
2437 string *old_str = u.str.val_str;
2438 set_val_str(asn_bit2oct(*old_str));
2439 delete old_str;
2440 } else FATAL_ERROR("Value::set_valuetype()");
2441 break;
2442 case V_CSTR:
2443 clean_up_string_elements(u.str.str_elements);
2444 switch(p_valuetype) {
2445 case V_USTR: {
2446 string *old_str = u.str.val_str;
2447 set_val_ustr(new ustring(*old_str));
2448 u.ustr.convert_str = true; // will be converted back to string
2449 delete old_str;
2450 break;}
2451 case V_ISO2022STR:
2452 // do nothing
2453 break;
2454 default:
2455 FATAL_ERROR("Value::set_valuetype()");
2456 } // switch p_valuetype
2457 break;
2458 case V_USTR:
2459 clean_up_string_elements(u.ustr.ustr_elements);
2460 switch(p_valuetype) {
2461 case V_CSTR: {
2462 ustring *old_str = u.ustr.val_ustr;
2463 size_t nof_chars = old_str->size();
2464 bool warning_flag = false;
2465 for (size_t i = 0; i < nof_chars; i++) {
2466 const ustring::universal_char& uchar = (*old_str)[i];
2467 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2468 error("This string value cannot contain multiple-byte characters, "
2469 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2470 uchar.group, uchar.plane, uchar.row, uchar.cell,
2471 (unsigned long) i);
2472 p_valuetype = V_ERROR;
2473 break;
2474 } else if (uchar.cell > 127 && !warning_flag) {
2475 warning("This string value may not contain characters with code "
2476 "higher than 127, but it has character with code %u (0x%02X) "
2477 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2478 warning_flag = true;
2479 }
2480 }
2481 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2482 delete old_str;
2483 break; }
2484 case V_ISO2022STR:
2485 error("ISO-10646 string value cannot be converted to "
2486 "ISO-2022 string");
2487 delete u.ustr.val_ustr;
2488 p_valuetype = V_ERROR;
2489 break;
2490 default:
2491 FATAL_ERROR("Value::set_valuetype()");
2492 } // switch p_valuetype
2493 break;
2494 case V_SEQ:
2495 switch (p_valuetype) {
2496 case V_CHOICE: {
2497 NamedValues *nvs = u.val_nvs;
2498 if (nvs->get_nof_nvs() < 1) {
2499 error("Union value must have one active field");
2500 delete nvs;
2501 valuetype = V_ERROR;
2502 return;
2503 } else if (nvs->get_nof_nvs() > 1) {
2504 error("Only one field was expected in union value instead of %lu",
2505 (unsigned long) nvs->get_nof_nvs());
2506 }
2507 NamedValue *nv = nvs->get_nv_byIndex(0);
2508 u.choice.alt_name = nv->get_name().clone();
2509 u.choice.alt_value = nv->steal_value();
2510 delete nvs;
2511 break;}
2512 case V_SET:
2513 // do nothing
2514 break;
2515 case V_REAL: {
2516 NamedValues *nvs = u.val_nvs;
2517 bool err = false;
2518 /* mantissa */
2519 Int i_mant = 0;
2520 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2521 if (nvs->has_nv_withName(id_mant)) {
2522 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2523 ->get_value_refd_last();
2524 if (v_tmp->get_valuetype() == V_INT) {
2525 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2526 if (*i_mant_int > INT_MAX) {
2527 error("Mantissa `%s' should be less than `%d'",
2528 (i_mant_int->t_str()).c_str(), INT_MAX);
2529 err = true;
2530 } else {
2531 i_mant = i_mant_int->get_val();
2532 }
2533 }
2534 else err = true;
2535 }
2536 else err = true;
2537 /* base */
2538 Int i_base = 0;
2539 Identifier id_base(Identifier::ID_ASN, string("base"));
2540 if (!err && nvs->has_nv_withName(id_base)) {
2541 Value *v = nvs->get_nv_byName(id_base)->get_value();
2542 Value *v_tmp = v->get_value_refd_last();
2543 if (v_tmp->get_valuetype() == V_INT) {
2544 const int_val_t *i_base_int = v_tmp->get_val_Int();
2545 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2546 v->error("Base of the REAL must be 2 or 10");
2547 err = true;
2548 } else {
2549 i_base = i_base_int->get_val();
2550 }
2551 }
2552 else err = true;
2553 }
2554 else err = true;
2555 /* exponent */
2556 Int i_exp = 0;
2557 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2558 if (!err && nvs->has_nv_withName(id_exp)) {
2559 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2560 ->get_value_refd_last();
2561 if (v_tmp->get_valuetype() == V_INT) {
2562 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2563 if (*i_exp_int > INT_MAX) {
2564 error("Exponent `%s' should be less than `%d'",
2565 (i_exp_int->t_str()).c_str(), INT_MAX);
2566 err = true;
2567 } else {
2568 i_exp = i_exp_int->get_val();
2569 }
2570 }
2571 else err = true;
2572 }
2573 else err = true;
2574 /* clean up */
2575 delete nvs;
2576 if (err) {
2577 valuetype = V_ERROR;
2578 return;
2579 }
2580 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2581 static_cast<double>(i_exp));
2582 break; }
2583 case V_NOTUSED:
2584 clean_up();
2585 break;
2586 default:
2587 FATAL_ERROR("Value::set_valuetype()");
2588 } // switch
2589 break;
2590 case V_SEQOF:
2591 switch (p_valuetype) {
2592 case V_SEQ: {
2593 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2594 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2595 Type *t = my_governor->get_type_refd_last();
2596 switch (t->get_typetype()) {
2597 case Type::T_SEQ_T:
2598 case Type::T_SEQ_A:
2599 break;
2600 default:
2601 FATAL_ERROR("Value::set_valuetype()");
2602 }
2603 Values *vals = u.val_vs;
2604 size_t nof_vals = vals->get_nof_vs();
2605 size_t nof_comps = t->get_nof_comps();
2606 if (nof_vals > nof_comps) {
2607 error("Too many elements in value list notation for type `%s': "
2608 "%lu was expected instead of %lu",
2609 t->get_typename().c_str(),
2610 (unsigned long)nof_comps, (unsigned long)nof_vals);
2611 }
2612 size_t upper_limit;
2613 bool allnotused;
2614 if (nof_vals <= nof_comps) {
2615 upper_limit = nof_vals;
2616 allnotused = true;
2617 } else {
2618 upper_limit = nof_comps;
2619 allnotused = false;
2620 }
2621 u.val_nvs = new NamedValues;
2622 for (size_t i = 0; i < upper_limit; i++) {
2623 Value *v = vals->steal_v_byIndex(i);
2624 if (v->valuetype != V_NOTUSED) {
2625 allnotused = false;
2626 }
2627 NamedValue *nv =
2628 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2629 nv->set_location(*v);
2630 u.val_nvs->add_nv(nv);
2631 }
2632 u.val_nvs->set_my_scope(get_my_scope());
2633 u.val_nvs->set_fullname(get_fullname());
2634 delete vals;
2635 if (allnotused && nof_vals > 0)
2636 warning("All elements of value list notation for type `%s' are not "
2637 "used symbols (`-')", t->get_typename().c_str());
2638 break; }
2639 case V_SET:
2640 // { } -> empty set value
2641 if (u.val_vs->get_nof_vs() != 0)
2642 FATAL_ERROR("Value::set_valuetype()");
2643 delete u.val_vs;
2644 u.val_nvs = new NamedValues;
2645 break;
2646 case V_SETOF:
2647 case V_ARRAY:
2648 // SEQOF -> SETOF or ARRAY: trivial
2649 break;
2650 default:
2651 FATAL_ERROR("Value::set_valuetype()");
2652 }
2653 break;
2654 case V_SET:
2655 case V_CHOICE:
2656 if (p_valuetype == V_NOTUSED) {
2657 clean_up();
2658 }
2659 else {
2660 FATAL_ERROR("Value::set_valuetype()");
2661 }
2662 break;
2663 case V_TTCN3_NULL:
2664 switch (p_valuetype) {
2665 case V_DEFAULT_NULL:
2666 break;
2667 case V_FAT_NULL:
2668 break;
2669 default:
2670 FATAL_ERROR("Value::set_valuetype()");
2671 }
2672 break;
2673 case V_NOTUSED:
2674 if (V_OMIT != p_valuetype) { // in case of implicit omit
2675 FATAL_ERROR("Value::set_valuetype()");
2676 }
2677 break;
2678 default:
2679 FATAL_ERROR("Value::set_valuetype()");
2680 } // switch
2681 valuetype=p_valuetype;
2682 }
2683
2684 void Value::set_valuetype_COMP_NULL()
2685 {
2686 if(valuetype == V_ERROR) return;
2687 if(valuetype==V_TTCN3_NULL) {
2688 valuetype=V_EXPR;
2689 u.expr.v_optype=OPTYPE_COMP_NULL;
2690 // Nothing to check.
2691 u.expr.state=EXPR_CHECKED;
2692 }
2693 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2694 }
2695
2696 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2697 {
2698 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2699 delete u.val_id;
2700 u.val_Int = new int_val_t(p_val_int);
2701 valuetype = V_INT;
2702 } else FATAL_ERROR("Value::set_valuetype()");
2703 }
2704
2705 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2706 {
2707 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2708 clean_up();
2709 valuetype = V_BSTR;
2710 set_val_str(p_str);
2711 } else FATAL_ERROR("Value::set_valuetype()");
2712 }
2713
2714 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2715 {
2716 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2717 delete u.val_id;
2718 u.val_id = p_id;
2719 valuetype = V_ENUM;
2720 } else FATAL_ERROR("Value::set_valuetype()");
2721 }
2722
2723 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2724 {
2725 switch (p_valuetype) {
2726 case V_FUNCTION:
2727 case V_ALTSTEP:
2728 case V_TESTCASE:
2729 if (valuetype == V_REFER && p_ass) break;
2730 // no break
2731 default:
2732 FATAL_ERROR("Value::set_valuetype()");
2733 }
2734 delete u.refered;
2735 u.refd_fat = p_ass;
2736 valuetype = p_valuetype;
2737 }
2738
2739 bool Value::is_undef_lowerid()
2740 {
2741 switch (valuetype) {
2742 case V_UNDEF_LOWERID:
2743 return true;
2744 case V_EXPR:
2745 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2746 !u.expr.ti1->get_DerivedRef()) {
2747 return u.expr.ti1->get_Template()->is_undef_lowerid();
2748 }
2749 // no break
2750 default:
2751 return false;
2752 }
2753 }
2754
2755 const Identifier& Value::get_undef_lowerid()
2756 {
2757 switch (valuetype) {
2758 case V_UNDEF_LOWERID:
2759 return *u.val_id;
2760 case V_EXPR:
2761 if (u.expr.v_optype != OPTYPE_VALUEOF)
2762 FATAL_ERROR("Value::get_undef_lowerid()");
2763 return u.expr.ti1->get_Template()->get_specific_value()
2764 ->get_undef_lowerid();
2765 default:
2766 FATAL_ERROR("Value::get_undef_lowerid()");
2767 }
2768 const Identifier *dummy = 0;
2769 return *dummy;
2770 }
2771
2772 void Value::set_lowerid_to_ref()
2773 {
2774 switch (valuetype) {
2775 case V_UNDEF_LOWERID:
2776 set_valuetype(V_REFD);
2777 break;
2778 case V_EXPR:
2779 // if the governor of the expression is not known (in log(), etc...)
2780 // then the governor is taken from the reference (using
2781 // v1/ti1->get_expr_governor()), but that runs before the
2782 // params were checked, this smells like a workaround :)
2783 switch (u.expr.v_optype) {
2784 case OPTYPE_ROTL:
2785 case OPTYPE_ROTR:
2786 u.expr.v1->set_lowerid_to_ref();
2787 break;
2788 case OPTYPE_CONCAT:
2789 u.expr.v1->set_lowerid_to_ref();
2790 u.expr.v2->set_lowerid_to_ref();
2791 break;
2792 case OPTYPE_VALUEOF:
2793 case OPTYPE_ISVALUE:
2794 case OPTYPE_ISBOUND:
2795 case OPTYPE_ISPRESENT:
2796 case OPTYPE_SUBSTR:
2797 case OPTYPE_REGEXP:
2798 case OPTYPE_REPLACE:
2799 case OPTYPE_TTCN2STRING:
2800 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2801 Error_Context cntxt(u.expr.ti1->get_Template(),
2802 "In the operand of operation `%s'",
2803 get_opname());
2804 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2805 }
2806 if (u.expr.v_optype==OPTYPE_REGEXP) {
2807 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2808 Error_Context cntxt(u.expr.t2->get_Template(),
2809 "In the operand of operation `%s'",
2810 get_opname());
2811 u.expr.t2->get_Template()->set_lowerid_to_ref();
2812 }
2813 }
2814 if (u.expr.v_optype==OPTYPE_REPLACE) {
2815 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2816 Error_Context cntxt(u.expr.ti4->get_Template(),
2817 "In the operand of operation `%s'",
2818 get_opname());
2819 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2820 }
2821 }
2822 break;
2823 default:
2824 break;
2825 }
2826 break;
2827 default:
2828 break;
2829 }
2830 }
2831
2832 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2833 {
2834 switch (valuetype) {
2835 case V_CHARSYMS:
2836 case V_CHOICE:
2837 case V_SEQOF:
2838 case V_SETOF:
2839 case V_ARRAY:
2840 case V_SEQ:
2841 case V_SET:
2842 case V_UNDEF_LOWERID:
2843 case V_UNDEF_BLOCK:
2844 case V_OMIT:
2845 case V_TTCN3_NULL:
2846 case V_NOTUSED:
2847 case V_REFER:
2848 case V_FAT_NULL:
2849 return Type::T_UNDEF;
2850 case V_NAMEDINT:
2851 case V_NAMEDBITS:
2852 case V_OPENTYPE:
2853 FATAL_ERROR("Value::get_expr_returntype()");
2854 case V_ERROR:
2855 return Type::T_ERROR;
2856 case V_REFD:
2857 case V_INVOKE: {
2858 Type *t = get_expr_governor(exp_val);
2859 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2860 else return Type::T_ERROR; }
2861 case V_FUNCTION:
2862 return Type::T_FUNCTION;
2863 case V_ALTSTEP:
2864 return Type::T_ALTSTEP;
2865 case V_TESTCASE:
2866 return Type::T_TESTCASE;
2867 case V_EXPR:
2868 switch(u.expr.v_optype) {
2869 case OPTYPE_COMP_NULL:
2870 case OPTYPE_COMP_MTC:
2871 case OPTYPE_COMP_SYSTEM:
2872 case OPTYPE_COMP_SELF:
2873 case OPTYPE_COMP_CREATE:
2874 return Type::T_COMPONENT;
2875 case OPTYPE_UNDEF_RUNNING:
2876 case OPTYPE_COMP_RUNNING:
2877 case OPTYPE_COMP_RUNNING_ANY:
2878 case OPTYPE_COMP_RUNNING_ALL:
2879 case OPTYPE_COMP_ALIVE:
2880 case OPTYPE_COMP_ALIVE_ANY:
2881 case OPTYPE_COMP_ALIVE_ALL:
2882 case OPTYPE_TMR_RUNNING:
2883 case OPTYPE_TMR_RUNNING_ANY:
2884 case OPTYPE_MATCH:
2885 case OPTYPE_EQ:
2886 case OPTYPE_LT:
2887 case OPTYPE_GT:
2888 case OPTYPE_NE:
2889 case OPTYPE_GE:
2890 case OPTYPE_LE:
2891 case OPTYPE_NOT:
2892 case OPTYPE_AND:
2893 case OPTYPE_OR:
2894 case OPTYPE_XOR:
2895 case OPTYPE_ISPRESENT:
2896 case OPTYPE_ISCHOSEN:
2897 case OPTYPE_ISCHOSEN_V:
2898 case OPTYPE_ISCHOSEN_T:
2899 case OPTYPE_ISVALUE:
2900 case OPTYPE_ISBOUND:
2901 case OPTYPE_PROF_RUNNING:
2902 return Type::T_BOOL;
2903 case OPTYPE_GETVERDICT:
2904 return Type::T_VERDICT;
2905 case OPTYPE_VALUEOF: {
2906 Error_Context cntxt(this, "In the operand of operation `%s'",
2907 get_opname());
2908 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2909 case OPTYPE_TMR_READ:
2910 case OPTYPE_INT2FLOAT:
2911 case OPTYPE_STR2FLOAT:
2912 case OPTYPE_RND:
2913 case OPTYPE_RNDWITHVAL:
2914 return Type::T_REAL;
2915 case OPTYPE_ACTIVATE:
2916 return Type::T_DEFAULT;
2917 case OPTYPE_ACTIVATE_REFD:
2918 return Type::T_DEFAULT;
2919 case OPTYPE_EXECUTE:
2920 case OPTYPE_EXECUTE_REFD:
2921 return Type::T_VERDICT;
2922 case OPTYPE_UNARYPLUS: // v1
2923 case OPTYPE_UNARYMINUS: {
2924 Type::typetype_t tmp_tt;
2925 {
2926 Error_Context cntxt(this, "In the operand of operation `%s'",
2927 get_opname());
2928 u.expr.v1->set_lowerid_to_ref();
2929 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2930 }
2931 switch(tmp_tt) {
2932 case Type::T_INT:
2933 case Type::T_REAL:
2934 return tmp_tt;
2935 default:
2936 get_value_refd_last(); // to report the error
2937 return Type::T_ERROR;
2938 } // switch tmp_tt
2939 }
2940 case OPTYPE_ADD: // v1 v2
2941 case OPTYPE_SUBTRACT:
2942 case OPTYPE_MULTIPLY:
2943 case OPTYPE_DIVIDE: {
2944 Type::typetype_t tmp_tt;
2945 {
2946 Error_Context cntxt(this, "In the left operand of operation `%s'",
2947 get_opname());
2948 u.expr.v1->set_lowerid_to_ref();
2949 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2950 }
2951 switch(tmp_tt) {
2952 case Type::T_INT:
2953 case Type::T_REAL:
2954 return tmp_tt;
2955 default:
2956 if(u.expr.v_optype==OPTYPE_ADD) {
2957 Type::typetype_t tmp_tt2;
2958 {
2959 Error_Context cntxt(this, "In the right operand of operation `%s'",
2960 get_opname());
2961 u.expr.v2->set_lowerid_to_ref();
2962 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2963 }
2964 Type::typetype_t ret_val=Type::T_ERROR;
2965 bool maybeconcat=false;
2966 switch(tmp_tt) {
2967 case Type::T_BSTR:
2968 case Type::T_HSTR:
2969 case Type::T_OSTR:
2970 if(tmp_tt2==tmp_tt) {
2971 maybeconcat=true;
2972 ret_val=tmp_tt;
2973 }
2974 break;
2975 case Type::T_CSTR:
2976 case Type::T_USTR:
2977 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2978 maybeconcat=true;
2979 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2980 ret_val=Type::T_USTR;
2981 else ret_val=Type::T_CSTR;
2982 }
2983 break;
2984 default:
2985 break;
2986 }
2987 if(maybeconcat) {
2988 error("Did you mean the concat operation (`&') instead of"
2989 " addition operator (`+')?");
2990 u.expr.v_optype=OPTYPE_CONCAT;
2991 return ret_val;
2992 }
2993 }
2994 get_value_refd_last(); // to report the error
2995 return Type::T_ERROR;
2996 } // switch tmp_tt
2997 }
2998 case OPTYPE_NOT4B: // v1
2999 case OPTYPE_AND4B: // v1 v2
3000 case OPTYPE_OR4B:
3001 case OPTYPE_XOR4B:
3002 case OPTYPE_SHL:
3003 case OPTYPE_SHR: {
3004 Type::typetype_t tmp_tt;
3005 {
3006 Error_Context cntxt(this, "In the %soperand of operation `%s'",
3007 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
3008 get_opname());
3009 u.expr.v1->set_lowerid_to_ref();
3010 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3011 }
3012 switch(tmp_tt) {
3013 case Type::T_BSTR:
3014 case Type::T_HSTR:
3015 case Type::T_OSTR:
3016 return tmp_tt;
3017 default:
3018 get_value_refd_last(); // to report the error
3019 return Type::T_ERROR;
3020 } // switch tmp_tt
3021 }
3022 case OPTYPE_ROTL: // v1 v2
3023 case OPTYPE_ROTR: {
3024 Type::typetype_t tmp_tt;
3025 {
3026 Error_Context cntxt(this, "In the %s operand of operation `%s'",
3027 u.expr.v_optype==OPTYPE_ROTL
3028 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
3029 get_opname());
3030 u.expr.v1->set_lowerid_to_ref();
3031 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3032 }
3033 switch(tmp_tt) {
3034 case Type::T_BSTR:
3035 case Type::T_HSTR:
3036 case Type::T_OSTR:
3037 case Type::T_CSTR:
3038 case Type::T_USTR:
3039 case Type::T_SETOF:
3040 case Type::T_SEQOF:
3041 case Type::T_ARRAY:
3042 return tmp_tt;
3043 default:
3044 get_value_refd_last(); // to report the error
3045 return Type::T_ERROR;
3046 } // switch tmp_tt
3047 }
3048 case OPTYPE_SUBSTR:
3049 case OPTYPE_REPLACE: {
3050 Type::typetype_t tmp_tt;
3051 {
3052 Error_Context cntxt(this, "In the operand of operation `%s'",
3053 get_opname());
3054 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3055 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3056 }
3057 switch (tmp_tt) {
3058 case Type::T_BSTR:
3059 case Type::T_HSTR:
3060 case Type::T_OSTR:
3061 case Type::T_CSTR:
3062 case Type::T_USTR:
3063 case Type::T_SETOF:
3064 case Type::T_SEQOF:
3065 return tmp_tt;
3066 default:
3067 get_value_refd_last(); // to report the error
3068 return Type::T_ERROR;
3069 }
3070 }
3071 case OPTYPE_REGEXP: {
3072 Type::typetype_t tmp_tt;
3073 {
3074 Error_Context cntxt(this, "In the first operand of operation `%s'",
3075 get_opname());
3076 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3077 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3078 }
3079 switch(tmp_tt) {
3080 case Type::T_CSTR:
3081 case Type::T_USTR:
3082 return tmp_tt;
3083 default:
3084 get_value_refd_last(); // to report the error
3085 return Type::T_ERROR;
3086 } // switch tmp_tt
3087 }
3088 case OPTYPE_CONCAT: { // v1 v2
3089 Type::typetype_t tmp_tt;
3090 {
3091 Error_Context cntxt(this, "In the first operand of operation `%s'",
3092 get_opname());
3093 u.expr.v1->set_lowerid_to_ref();
3094 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3095 }
3096 switch(tmp_tt) {
3097 case Type::T_CSTR:
3098 case Type::T_USTR:
3099 case Type::T_BSTR:
3100 case Type::T_HSTR:
3101 case Type::T_OSTR:
3102 case Type::T_SETOF:
3103 case Type::T_SEQOF:
3104 return tmp_tt;
3105 default:
3106 get_value_refd_last(); // to report the error
3107 return Type::T_ERROR;
3108 } // switch tmp_tt
3109 }
3110 case OPTYPE_MOD:
3111 case OPTYPE_REM:
3112 case OPTYPE_CHAR2INT:
3113 case OPTYPE_UNICHAR2INT:
3114 case OPTYPE_BIT2INT:
3115 case OPTYPE_HEX2INT:
3116 case OPTYPE_OCT2INT:
3117 case OPTYPE_STR2INT:
3118 case OPTYPE_FLOAT2INT:
3119 case OPTYPE_LENGTHOF:
3120 case OPTYPE_SIZEOF:
3121 case OPTYPE_DECODE:
3122 case OPTYPE_ENUM2INT:
3123 case OPTYPE_DECVALUE_UNICHAR:
3124 return Type::T_INT;
3125 case OPTYPE_BIT2STR:
3126 case OPTYPE_FLOAT2STR:
3127 case OPTYPE_HEX2STR:
3128 case OPTYPE_INT2CHAR:
3129 case OPTYPE_INT2STR:
3130 case OPTYPE_OCT2CHAR:
3131 case OPTYPE_OCT2STR:
3132 case OPTYPE_UNICHAR2CHAR:
3133 case OPTYPE_LOG2STR:
3134 case OPTYPE_TESTCASENAME:
3135 case OPTYPE_TTCN2STRING:
3136 case OPTYPE_GET_STRINGENCODING:
3137 case OPTYPE_ENCODE_BASE64:
3138 return Type::T_CSTR;
3139 case OPTYPE_INT2UNICHAR:
3140 case OPTYPE_OCT2UNICHAR:
3141 case OPTYPE_ENCVALUE_UNICHAR:
3142 case OPTYPE_ANY2UNISTR:
3143 return Type::T_USTR;
3144 case OPTYPE_INT2BIT:
3145 case OPTYPE_HEX2BIT:
3146 case OPTYPE_OCT2BIT:
3147 case OPTYPE_STR2BIT:
3148 case OPTYPE_ENCODE:
3149 return Type::T_BSTR;
3150 case OPTYPE_INT2HEX:
3151 case OPTYPE_BIT2HEX:
3152 case OPTYPE_OCT2HEX:
3153 case OPTYPE_STR2HEX:
3154 return Type::T_HSTR;
3155 case OPTYPE_INT2OCT:
3156 case OPTYPE_CHAR2OCT:
3157 case OPTYPE_HEX2OCT:
3158 case OPTYPE_BIT2OCT:
3159 case OPTYPE_STR2OCT:
3160 case OPTYPE_UNICHAR2OCT:
3161 case OPTYPE_REMOVE_BOM:
3162 case OPTYPE_DECODE_BASE64:
3163 return Type::T_OSTR;
3164 case OPTYPE_DECOMP:
3165 return Type::T_OID;
3166 default:
3167 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3168 // to avoid warning
3169 return Type::T_ERROR;
3170 } // switch optype
3171 case V_MACRO:
3172 switch (u.macro) {
3173 case MACRO_MODULEID:
3174 case MACRO_FILENAME:
3175 case MACRO_BFILENAME:
3176 case MACRO_FILEPATH:
3177 case MACRO_LINENUMBER:
3178 case MACRO_DEFINITIONID:
3179 case MACRO_SCOPE:
3180 case MACRO_TESTCASEID:
3181 return Type::T_CSTR;
3182 case MACRO_LINENUMBER_C:
3183 return Type::T_INT;
3184 default:
3185 return Type::T_ERROR;
3186 }
3187 case V_NULL:
3188 return Type::T_NULL;
3189 case V_BOOL:
3190 return Type::T_BOOL;
3191 case V_INT:
3192 return Type::T_INT;
3193 case V_REAL:
3194 return Type::T_REAL;
3195 case V_ENUM:
3196 return Type::T_ENUM_T;
3197 case V_BSTR:
3198 return Type::T_BSTR;
3199 case V_HSTR:
3200 return Type::T_HSTR;
3201 case V_OSTR:
3202 return Type::T_OSTR;
3203 case V_CSTR:
3204 return Type::T_CSTR;
3205 case V_USTR:
3206 return Type::T_USTR;
3207 case V_ISO2022STR:
3208 return Type::T_GENERALSTRING;
3209 case V_OID:
3210 return Type::T_OID;
3211 case V_ROID:
3212 return Type::T_ROID;
3213 case V_VERDICT:
3214 return Type::T_VERDICT;
3215 case V_DEFAULT_NULL:
3216 return Type::T_DEFAULT;
3217 default:
3218 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3219 // to avoid warning
3220 return Type::T_ERROR;
3221 } // switch
3222 }
3223
3224 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3225 {
3226 if(my_governor) return my_governor;
3227 switch (valuetype) {
3228 case V_INVOKE: {
3229 Type *t = u.invoke.v->get_expr_governor(exp_val);
3230 if(!t) {
3231 if(u.invoke.v->get_valuetype() != V_ERROR)
3232 u.invoke.v->error("A value of type function expected");
3233 goto error;
3234 }
3235 t = t->get_type_refd_last();
3236 switch(t->get_typetype()) {
3237 case Type::T_FUNCTION: {
3238 Type *t_return_type = t->get_function_return_type();
3239 if (!t_return_type) {
3240 error("Reference to a %s was expected instead of invocation "
3241 "of behavior type `%s' with no return type",
3242 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3243 t->get_fullname().c_str());
3244 goto error;
3245 }
3246 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3247 error("Reference to a value was expected, but functions of type "
3248 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3249 t_return_type->get_typename().c_str());
3250 goto error;
3251 }
3252 return t_return_type; }
3253 case Type::T_ALTSTEP:
3254 goto error;
3255 default:
3256 u.invoke.v->error("A value of type function expected instead of `%s'",
3257 t->get_typename().c_str());
3258 goto error;
3259 }
3260 break; }
3261 case V_REFD: {
3262 Assignment *ass=u.ref.ref->get_refd_assignment();
3263 Type *tmp_type=0;
3264 if (!ass) goto error;
3265 switch (ass->get_asstype()) {
3266 case Assignment::A_CONST:
3267 case Assignment::A_EXT_CONST:
3268 case Assignment::A_MODULEPAR:
3269 case Assignment::A_MODULEPAR_TEMP:
3270 case Assignment::A_TEMPLATE:
3271 case Assignment::A_VAR:
3272 case Assignment::A_VAR_TEMPLATE:
3273 case Assignment::A_FUNCTION_RVAL:
3274 case Assignment::A_FUNCTION_RTEMP:
3275 case Assignment::A_EXT_FUNCTION_RVAL:
3276 case Assignment::A_EXT_FUNCTION_RTEMP:
3277 case Assignment::A_PAR_VAL_IN:
3278 case Assignment::A_PAR_VAL_OUT:
3279 case Assignment::A_PAR_VAL_INOUT:
3280 case Assignment::A_PAR_TEMPL_IN:
3281 case Assignment::A_PAR_TEMPL_OUT:
3282 case Assignment::A_PAR_TEMPL_INOUT:
3283 tmp_type=ass->get_Type();
3284 break;
3285 case Assignment::A_FUNCTION:
3286 case Assignment::A_EXT_FUNCTION:
3287 error("Reference to a %s was expected instead of a call of %s, which "
3288 "does not have return type",
3289 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3290 ass->get_description().c_str());
3291 goto error;
3292 default:
3293 error("Reference to a %s was expected instead of %s",
3294 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3295 ass->get_description().c_str());
3296 goto error;
3297 } // end switch
3298 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3299 if(!tmp_type) goto error;
3300 return tmp_type; }
3301 case V_EXPR:
3302 switch (u.expr.v_optype) {
3303 case OPTYPE_VALUEOF:
3304 case OPTYPE_SUBSTR:
3305 case OPTYPE_REGEXP:
3306 case OPTYPE_REPLACE:{
3307 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3308 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3309 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3310 return tmp_type;
3311 }
3312 case OPTYPE_ROTL:
3313 case OPTYPE_ROTR:
3314 return u.expr.v1->get_expr_governor(exp_val);
3315 case OPTYPE_CONCAT:
3316 return get_expr_governor_v1v2(exp_val);
3317 case OPTYPE_COMP_MTC:
3318 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3319 else return 0;
3320 case OPTYPE_COMP_SYSTEM:
3321 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3322 else return 0;
3323 case OPTYPE_COMP_SELF:
3324 if (my_scope) {
3325 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3326 if (t_ros) return t_ros->get_component_type();
3327 else return 0;
3328 } else return 0;
3329 case OPTYPE_COMP_CREATE:
3330 return chk_expr_operand_comptyperef_create();
3331 default:
3332 break;
3333 }
3334 // no break
3335 default:
3336 return Type::get_pooltype(get_expr_returntype(exp_val));
3337 }
3338 error:
3339 set_valuetype(V_ERROR);
3340 return 0;
3341 }
3342
3343 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3344 {
3345 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3346 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3347 if (v1_gov) {
3348 if (v2_gov) { // both have governors
3349 // return the type that is compatible with both (if there is no type mismatch)
3350 if (v1_gov->is_compatible(v2_gov, NULL))
3351 return v1_gov;
3352 else return v2_gov;
3353 } else return v1_gov;
3354 } else { // v1 has no governor
3355 if (v2_gov) return v2_gov;
3356 else return NULL; // neither has governor
3357 }
3358 }
3359
3360 Type *Value::get_expr_governor_last()
3361 {
3362 Value *v_last = get_value_refd_last();
3363 if (v_last->valuetype == V_ERROR) return 0;
3364 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3365 if(!t) return 0;
3366 return t->get_type_refd_last();
3367 }
3368
3369 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3370 {
3371 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3372 return u.invoke.v->get_expr_governor(exp_val);
3373 }
3374
3375 const char* Value::get_opname() const
3376 {
3377 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3378 switch(u.expr.v_optype) {
3379 case OPTYPE_RND: // -
3380 return "rnd()";
3381 case OPTYPE_COMP_NULL:
3382 return "(component) null";
3383 case OPTYPE_COMP_MTC:
3384 return "mtc";
3385 case OPTYPE_COMP_SYSTEM:
3386 return "system";
3387 case OPTYPE_COMP_SELF:
3388 return "self";
3389 case OPTYPE_COMP_RUNNING_ANY:
3390 return "any component.running";
3391 case OPTYPE_COMP_RUNNING_ALL:
3392 return "all component.running";
3393 case OPTYPE_COMP_ALIVE_ANY:
3394 return "any component.alive";
3395 case OPTYPE_COMP_ALIVE_ALL:
3396 return "all component.alive";
3397 case OPTYPE_TMR_RUNNING_ANY:
3398 return "any timer.running";
3399 case OPTYPE_GETVERDICT:
3400 return "getverdict()";
3401 case OPTYPE_TESTCASENAME:
3402 return "testcasename()";
3403 case OPTYPE_UNARYPLUS: // v1
3404 return "unary +";
3405 case OPTYPE_UNARYMINUS:
3406 return "unary -";
3407 case OPTYPE_NOT:
3408 return "not";
3409 case OPTYPE_NOT4B:
3410 return "not4b";
3411 case OPTYPE_BIT2HEX:
3412 return "bit2hex()";
3413 case OPTYPE_BIT2INT:
3414 return "bit2int()";
3415 case OPTYPE_BIT2OCT:
3416 return "bit2oct()";
3417 case OPTYPE_BIT2STR:
3418 return "bit2str()";
3419 case OPTYPE_CHAR2INT:
3420 return "char2int()";
3421 case OPTYPE_CHAR2OCT:
3422 return "char2oct()";
3423 case OPTYPE_FLOAT2INT:
3424 return "float2int()";
3425 case OPTYPE_FLOAT2STR:
3426 return "float2str()";
3427 case OPTYPE_HEX2BIT:
3428 return "hex2bit()";
3429 case OPTYPE_HEX2INT:
3430 return "hex2int()";
3431 case OPTYPE_HEX2OCT:
3432 return "hex2oct()";
3433 case OPTYPE_HEX2STR:
3434 return "hex2str()";
3435 case OPTYPE_INT2CHAR:
3436 return "int2char()";
3437 case OPTYPE_INT2FLOAT:
3438 return "int2float()";
3439 case OPTYPE_INT2STR:
3440 return "int2str()";
3441 case OPTYPE_INT2UNICHAR:
3442 return "int2unichar()";
3443 case OPTYPE_OCT2BIT:
3444 return "oct2bit()";
3445 case OPTYPE_OCT2CHAR:
3446 return "oct2char()";
3447 case OPTYPE_OCT2HEX:
3448 return "oct2hex()";
3449 case OPTYPE_OCT2INT:
3450 return "oct2int()";
3451 case OPTYPE_OCT2STR:
3452 return "oct2str()";
3453 case OPTYPE_STR2BIT:
3454 return "str2bit()";
3455 case OPTYPE_STR2FLOAT:
3456 return "str2float()";
3457 case OPTYPE_STR2HEX:
3458 return "str2hex()";
3459 case OPTYPE_STR2INT:
3460 return "str2int()";
3461 case OPTYPE_STR2OCT:
3462 return "str2oct()";
3463 case OPTYPE_UNICHAR2INT:
3464 return "unichar2int()";
3465 case OPTYPE_UNICHAR2CHAR:
3466 return "unichar2char()";
3467 case OPTYPE_UNICHAR2OCT:
3468 return "unichar2oct()";
3469 case OPTYPE_ENUM2INT:
3470 return "enum2int()";
3471 case OPTYPE_LENGTHOF:
3472 return "lengthof()";
3473 case OPTYPE_SIZEOF:
3474 return "sizeof()";
3475 case OPTYPE_RNDWITHVAL:
3476 return "rnd (seed)";
3477 case OPTYPE_ENCODE:
3478 return "encvalue()";
3479 case OPTYPE_DECODE:
3480 return "decvalue()";
3481 case OPTYPE_GET_STRINGENCODING:
3482 return "get_stringencoding()";
3483 case OPTYPE_REMOVE_BOM:
3484 return "remove_bom()";
3485 case OPTYPE_ENCODE_BASE64:
3486 return "encode_base64()";
3487 case OPTYPE_DECODE_BASE64:
3488 return "decode_base64()";
3489 case OPTYPE_ADD: // v1 v2
3490 return "+";
3491 case OPTYPE_SUBTRACT:
3492 return "-";
3493 case OPTYPE_MULTIPLY:
3494 return "*";
3495 case OPTYPE_DIVIDE:
3496 return "/";
3497 case OPTYPE_MOD:
3498 return "mod";
3499 case OPTYPE_REM:
3500 return "rem";
3501 case OPTYPE_CONCAT:
3502 return "&";
3503 case OPTYPE_EQ:
3504 return "==";
3505 case OPTYPE_LT:
3506 return "<";
3507 case OPTYPE_GT:
3508 return ">";
3509 case OPTYPE_NE:
3510 return "!=";
3511 case OPTYPE_GE:
3512 return ">=";
3513 case OPTYPE_LE:
3514 return "<=";
3515 case OPTYPE_AND:
3516 return "and";
3517 case OPTYPE_OR:
3518 return "or";
3519 case OPTYPE_XOR:
3520 return "xor";
3521 case OPTYPE_AND4B:
3522 return "and4b";
3523 case OPTYPE_OR4B:
3524 return "or4b";
3525 case OPTYPE_XOR4B:
3526 return "xor4b";
3527 case OPTYPE_SHL:
3528 return "<<";
3529 case OPTYPE_SHR:
3530 return ">>";
3531 case OPTYPE_ROTL:
3532 return "<@";
3533 case OPTYPE_ROTR:
3534 return "@>";
3535 case OPTYPE_INT2BIT:
3536 return "int2bit()";
3537 case OPTYPE_INT2HEX:
3538 return "int2hex()";
3539 case OPTYPE_INT2OCT:
3540 return "int2oct()";
3541 case OPTYPE_OCT2UNICHAR:
3542 return "oct2unichar()";
3543 case OPTYPE_ENCVALUE_UNICHAR:
3544 return "encvalue_unichar()";
3545 case OPTYPE_DECVALUE_UNICHAR:
3546 return "decvalue_unichar()";
3547 case OPTYPE_SUBSTR:
3548 return "substr()";
3549 case OPTYPE_REGEXP:
3550 return "regexp()";
3551 case OPTYPE_DECOMP:
3552 return "decomp()";
3553 case OPTYPE_REPLACE:
3554 return "replace()";
3555 case OPTYPE_VALUEOF: // t1
3556 return "valueof()";
3557 case OPTYPE_UNDEF_RUNNING:
3558 return "<timer or component> running";
3559 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3560 return "create()";
3561 case OPTYPE_COMP_RUNNING: // v1
3562 return "component running";
3563 case OPTYPE_COMP_ALIVE: // v1
3564 return "alive";
3565 case OPTYPE_TMR_READ:
3566 return "timer read";
3567 case OPTYPE_TMR_RUNNING:
3568 return "timer running";
3569 case OPTYPE_ACTIVATE:
3570 return "activate()";
3571 case OPTYPE_ACTIVATE_REFD:
3572 return "activate()";
3573 case OPTYPE_EXECUTE: // r1 [v2]
3574 case OPTYPE_EXECUTE_REFD:
3575 return "execute()";
3576 case OPTYPE_MATCH: // v1 t2
3577 return "match()";
3578 case OPTYPE_ISPRESENT:
3579 return "ispresent()";
3580 case OPTYPE_ISCHOSEN:
3581 case OPTYPE_ISCHOSEN_V:
3582 case OPTYPE_ISCHOSEN_T:
3583 return "ischosen()";
3584 case OPTYPE_ISVALUE:
3585 return "isvalue()";
3586 case OPTYPE_ISBOUND:
3587 return "isbound()";
3588 case OPTYPE_LOG2STR:
3589 return "log2str()";
3590 case OPTYPE_ANY2UNISTR:
3591 return "any2unistr()";
3592 case OPTYPE_TTCN2STRING:
3593 return "ttcn2string()";
3594 case OPTYPE_PROF_RUNNING:
3595 return "@profiler.running";
3596 default:
3597 FATAL_ERROR("Value::get_opname()");
3598 } // switch
3599 }
3600
3601 void Value::chk_expr_ref_ischosen()
3602 {
3603 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3604 Ttcn::Ref_base *tmpref=u.expr.r1;
3605 Assignment *ass=tmpref->get_refd_assignment();
3606 if (!ass) {
3607 set_valuetype(V_ERROR);
3608 return;
3609 }
3610 // Now we know whether the argument of ischosen() is a value or template.
3611 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3612 // or template (OPTYPE_ISCHOSEN_T).
3613 switch (ass->get_asstype()) {
3614 case Assignment::A_CONST:
3615 case Assignment::A_EXT_CONST:
3616 case Assignment::A_MODULEPAR:
3617 case Assignment::A_VAR:
3618 case Assignment::A_PAR_VAL_IN:
3619 case Assignment::A_PAR_VAL_OUT:
3620 case Assignment::A_PAR_VAL_INOUT:
3621 u.expr.v1=new Value(V_REFD, tmpref);
3622 u.expr.v1->set_location(*tmpref);
3623 u.expr.v1->set_my_scope(get_my_scope());
3624 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3625 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3626 break;
3627 case Assignment::A_MODULEPAR_TEMP:
3628 case Assignment::A_TEMPLATE:
3629 case Assignment::A_VAR_TEMPLATE:
3630 case Assignment::A_PAR_TEMPL_IN:
3631 case Assignment::A_PAR_TEMPL_OUT:
3632 case Assignment::A_PAR_TEMPL_INOUT:
3633 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3634 u.expr.t1->set_location(*tmpref);
3635 u.expr.t1->set_my_scope(get_my_scope());
3636 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3637 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3638 break;
3639 default:
3640 tmpref->error("Reference to a value or template was expected instead of "
3641 "%s", ass->get_description().c_str());
3642 set_valuetype(V_ERROR);
3643 break;
3644 } // switch
3645 }
3646
3647 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3648 Type::expected_value_t exp_val)
3649 {
3650 v->set_lowerid_to_ref(); // can only be reference to enum
3651 Type *t = v->get_expr_governor(exp_val);
3652 if (v->valuetype==V_ERROR) return;
3653 if (!t) {
3654 v->error("Please use reference to an enumerated value as the operand of "
3655 "operation `%s'", get_opname());
3656 set_valuetype(V_ERROR);
3657 return;
3658 }
3659 t = t->get_type_refd_last();
3660 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3661 v->error("The operand of operation `%s' should be enumerated value", opname);
3662 set_valuetype(V_ERROR);
3663 }
3664 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3665 v->error("The operand of operation `%s' cannot be omit", opname);
3666 set_valuetype(V_ERROR);
3667 }
3668 }
3669
3670 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3671 const char *opnum,
3672 const char *opname,
3673 const Location *loc)
3674 {
3675 if(tt==Type::T_BOOL) return;
3676 if(tt!=Type::T_ERROR)
3677 loc->error("%s operand of operation `%s' should be boolean value",
3678 opnum, opname);
3679 set_valuetype(V_ERROR);
3680 }
3681
3682 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3683 const char *opnum,
3684 const char *opname,
3685 const Location *loc)
3686 {
3687 if(tt==Type::T_INT) return;
3688 if(tt!=Type::T_ERROR)
3689 loc->error("%s operand of operation `%s' should be integer value",
3690 opnum, opname);
3691 set_valuetype(V_ERROR);
3692 }
3693
3694 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3695 const char *opnum,
3696 const char *opname,
3697 const Location *loc)
3698 {
3699 if(tt==Type::T_REAL) return;
3700 else if(tt==Type::T_INT)
3701 loc->error("%s operand of operation `%s' should be float value."
3702 " Perhaps you missed an int2float() conversion function"
3703 " or `.0' at the end of the number",
3704 opnum, opname);
3705 else if(tt!=Type::T_ERROR)
3706 loc->error("%s operand of operation `%s' should be float value",
3707 opnum, opname);
3708 set_valuetype(V_ERROR);
3709 }
3710
3711 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3712 const char *opnum,
3713 const char *opname,
3714 const Location *loc)
3715 {
3716 switch(tt) {
3717 case Type::T_INT:
3718 case Type::T_REAL:
3719 return;
3720 default:
3721 break;
3722 }
3723 if(tt!=Type::T_ERROR)
3724 loc->error("%s operand of operation `%s' should be integer"
3725 " or float value",
3726 opnum, opname);
3727 set_valuetype(V_ERROR);
3728 }
3729
3730 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3731 const char *opnum,
3732 const char *opname,
3733 const Location *loc)
3734 {
3735 switch(tt) {
3736 case Type::T_INT:
3737 case Type::T_REAL:
3738 case Type::T_ENUM_T:
3739 return;
3740 default:
3741 break;
3742 }
3743 if(tt!=Type::T_ERROR)
3744 loc->error("%s operand of operation `%s' should be integer, float"
3745 " or enumerated value", opnum, opname);
3746 set_valuetype(V_ERROR);
3747 }
3748
3749 void Value::chk_expr_operandtype_list(Type* t,
3750 const char *opnum,
3751 const char *opname,
3752 const Location *loc,
3753 bool allow_array)
3754 {
3755 if (valuetype == V_ERROR) return;
3756 if (t->get_typetype() == Type::T_ERROR) {
3757 set_valuetype(V_ERROR);
3758 return;
3759 }
3760 if (!t->is_list_type(allow_array)) {
3761 loc->error("%s operand of operation `%s' should be a string, "
3762 "`record of'%s `set of'%s value", opnum, opname,
3763 allow_array ? "," : " or", allow_array ? " or array" : "");
3764 set_valuetype(V_ERROR);
3765 return;
3766 }
3767 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3768 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3769 TypeChain l_chain;
3770 TypeChain r_chain;
3771 if (my_governor && my_governor->is_list_type(allow_array)
3772 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3773 if (info.is_subtype_error()) {
3774 // this is ok.
3775 if (info.needs_conversion()) set_needs_conversion();
3776 } else
3777 if (!info.is_erroneous()) {
3778 error("%s operand of operation `%s' is of type `%s', but a value of "
3779 "type `%s' was expected here", opnum, opname,
3780 t->get_typename().c_str(), my_governor->get_typename().c_str());
3781 } else {
3782 error("%s", info.get_error_str_str().c_str());
3783 }
3784 } else {
3785 if (info.needs_conversion())
3786 set_needs_conversion();
3787 }
3788 }
3789
3790 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3791 const char *opnum,
3792 const char *opname,
3793 const Location *loc)
3794 {
3795 switch(tt) {
3796 case Type::T_CSTR:
3797 case Type::T_USTR:
3798 case Type::T_BSTR:
3799 case Type::T_HSTR:
3800 case Type::T_OSTR:
3801 return;
3802 default:
3803 break;
3804 }
3805 if(tt!=Type::T_ERROR)
3806 loc->error("%s operand of operation `%s' should be string value",
3807 opnum, opname);
3808 set_valuetype(V_ERROR);
3809 }
3810
3811 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3812 const char *opnum,
3813 const char *opname,
3814 const Location *loc)
3815 {
3816 switch(tt) {
3817 case Type::T_CSTR:
3818 case Type::T_USTR:
3819 return;
3820 default:
3821 break;
3822 }
3823 if(tt!=Type::T_ERROR)
3824 loc->error("%s operand of operation `%s' should be (universal)"
3825 " charstring value",
3826 opnum, opname);
3827 set_valuetype(V_ERROR);
3828 }
3829
3830 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3831 const char *opnum,
3832 const char *opname,
3833 const Location *loc)
3834 {
3835 if(tt==Type::T_CSTR) return;
3836 if(tt!=Type::T_ERROR)
3837 loc->error("%s operand of operation `%s' should be charstring value",
3838 opnum, opname);
3839 set_valuetype(V_ERROR);
3840 }
3841
3842 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3843 const char *opnum,
3844 const char *opname,
3845 const Location *loc)
3846 {
3847 switch(tt) {
3848 case Type::T_BSTR:
3849 case Type::T_HSTR:
3850 case Type::T_OSTR:
3851 return;
3852 default:
3853 break;
3854 }
3855 if(tt!=Type::T_ERROR)
3856 loc->error("%s operand of operation `%s' should be binary string value",
3857 opnum, opname);
3858 set_valuetype(V_ERROR);
3859 }
3860
3861 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3862 const char *opnum,
3863 const char *opname,
3864 const Location *loc)
3865 {
3866 if(tt==Type::T_BSTR) return;
3867 if(tt!=Type::T_ERROR)
3868 loc->error("%s operand of operation `%s' should be bitstring value",
3869 opnum, opname);
3870 set_valuetype(V_ERROR);
3871 }
3872
3873 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3874 const char *opnum,
3875 const char *opname,
3876 const Location *loc)
3877 {
3878 if(tt==Type::T_HSTR) return;
3879 if(tt!=Type::T_ERROR)
3880 loc->error("%s operand of operation `%s' should be hexstring value",
3881 opnum, opname);
3882 set_valuetype(V_ERROR);
3883 }
3884
3885 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3886 const char *opnum,
3887 const char *opname,
3888 const Location *loc)
3889 {
3890 if(tt==Type::T_OSTR) return;
3891 if(tt!=Type::T_ERROR)
3892 loc->error("%s operand of operation `%s' should be octetstring value",
3893 opnum, opname);
3894 set_valuetype(V_ERROR);
3895 }
3896
3897 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3898 Type::typetype_t tt2,
3899 const char *opname)
3900 {
3901 if(valuetype==V_ERROR) return;
3902 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3903 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3904 set_valuetype(V_ERROR);
3905 return;
3906 }
3907 if(tt1==tt2) return;
3908 error("The operands of operation `%s' should be of same type", opname);
3909 set_valuetype(V_ERROR);
3910 }
3911
3912 /* For predefined functions. */
3913 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3914 Type::typetype_t tt2,
3915 const char *opnum1,
3916 const char *opnum2,
3917 const char *opname)
3918 {
3919 if(valuetype==V_ERROR) return;
3920 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3921 set_valuetype(V_ERROR);
3922 return;
3923 }
3924 if(tt1==tt2) return;
3925 error("The %s and %s operands of operation `%s' should be of same type",
3926 opnum1, opnum2, opname);
3927 set_valuetype(V_ERROR);
3928 }
3929
3930 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3931 Value *v1, Value *v2,
3932 const char *opnum1,
3933 const char *opnum2)
3934 {
3935 start:
3936 if (valuetype == V_ERROR) return;
3937 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3938 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3939 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3940
3941 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3942 set_valuetype(V_ERROR);
3943 return;
3944 }
3945 if (tt1 == Type::T_UNDEF) {
3946 if (tt2 == Type::T_UNDEF) {
3947 if (v1->is_undef_lowerid()) {
3948 if (v2->is_undef_lowerid()) {
3949 Scope *scope = get_my_scope();
3950 Module *my_mod = scope->get_scope_mod();
3951 const Identifier& id1 = v1->get_undef_lowerid();
3952 if (scope->has_ass_withId(id1)
3953 || my_mod->has_imported_ass_withId(id1)) {
3954 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3955 * should examine this situation better, but now I suppose
3956 * the first is ref, not enum. */
3957 v1->set_lowerid_to_ref();
3958 goto start;
3959 } else {
3960 const Identifier& id2 = v2->get_undef_lowerid();
3961 if (scope->has_ass_withId(id2)
3962 || my_mod->has_imported_ass_withId(id2)) {
3963 v2->set_lowerid_to_ref();
3964 goto start;
3965 }
3966 }
3967 /* This is perhaps enum-enum, but it has no real
3968 * significance, so this should be an error. */
3969 } else {
3970 v1->set_lowerid_to_ref();
3971 goto start;
3972 }
3973 } else if (v2->is_undef_lowerid()) {
3974 v2->set_lowerid_to_ref();
3975 goto start;
3976 }
3977 error("Cannot determine the type of the operands in operation `%s'",
3978 get_opname());
3979 set_valuetype(V_ERROR);
3980 return;
3981 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3982 v1->set_lowerid_to_ref();
3983 goto start;
3984 } else {
3985 /* v1 is something undefined, but not lowerid; v2 has
3986 * returntype (perhaps also governor) */
3987 }
3988 } else if (tt2 == Type::T_UNDEF) {
3989 /* but tt1 is not undef */
3990 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3991 v2->set_lowerid_to_ref();
3992 goto start;
3993 } else {
3994 /* v2 is something undefined, but not lowerid; v1 has
3995 * returntype (perhaps also governor) */
3996 }
3997 }
3998
3999 /* Now undef_lower_id's are converted to references, or the other
4000 * value has governor; let's see the governors, if they exist. */
4001 Type *t1 = v1->get_expr_governor(exp_val);
4002 Type *t2 = v2->get_expr_governor(exp_val);
4003 if (t1) {
4004 if (t2) {
4005 // Both value has governor. Are they compatible? According to 7.1.2
4006 // and C.34 it's required to have the same root types for
4007 // OPTYPE_{CONCAT,REPLACE}.
4008 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
4009 u.expr.v_optype == OPTYPE_REPLACE);
4010 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
4011 u.expr.v_optype == OPTYPE_REPLACE);
4012 TypeChain l_chain1, l_chain2;
4013 TypeChain r_chain1, r_chain2;
4014 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
4015 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
4016 if (!compat_t1 && !compat_t2) {
4017 if (!info1.is_erroneous() && !info2.is_erroneous()) {
4018 // the subtypes don't need to be compatible here
4019 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
4020 error("The operands of operation `%s' should be of compatible "
4021 "types", get_opname());
4022 set_valuetype(V_ERROR);
4023 } else {
4024 if (info1.needs_conversion() || info2.needs_conversion()) {
4025 set_needs_conversion(); // Avoid folding.
4026 return;
4027 }
4028 }
4029 } else {
4030 if (info1.is_erroneous())
4031 v1->error("%s", info1.get_error_str_str().c_str());
4032 else if (info2.is_erroneous())
4033 v2->error("%s", info2.get_error_str_str().c_str());
4034 set_valuetype(V_ERROR);
4035 }
4036 return;
4037 } else if (info1.needs_conversion() || info2.needs_conversion()) {
4038 set_needs_conversion(); // Avoid folding.
4039 return;
4040 }
4041 } else {
4042 // t1, no t2.
4043 v2->set_my_governor(t1);
4044 t1->chk_this_value_ref(v2);
4045 if (v2->valuetype == V_OMIT) {
4046 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4047 get_opname());
4048 v1->chk_expr_omit_comparison(exp_val);
4049 } else {
4050 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4051 get_opname());
4052 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4053 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4054 goto start;
4055 }
4056 }
4057 } else if (t2) {
4058 v1->set_my_governor(t2);
4059 t2->chk_this_value_ref(v1);
4060 if (v1->valuetype == V_OMIT) {
4061 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4062 get_opname());
4063 v2->chk_expr_omit_comparison(exp_val);
4064 } else {
4065 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4066 get_opname());
4067 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4068 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4069 goto start;
4070 }
4071 } else {
4072 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4073 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
4074 // Here, it cannot be that both are T_UNDEF.
4075 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4076 error("Please use reference as %s operand of operator `%s'",
4077 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
4078 set_valuetype(V_ERROR);
4079 return;
4080 }
4081 // Deny type compatibility if no governors found. The typetype_t must
4082 // be the same. TODO: How can this happen?
4083 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
4084 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
4085 error("The operands of operation `%s' should be of compatible types",
4086 get_opname());
4087 set_valuetype(V_ERROR);
4088 }
4089 }
4090 }
4091
4092 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
4093 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
4094 {
4095 if(valuetype==V_ERROR) return;
4096 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4097 Assignment *t_ass = ref->get_refd_assignment();
4098 if(!t_ass) goto error;
4099 switch(t_ass->get_asstype()) {
4100 case Assignment::A_TIMER:
4101 case Assignment::A_PAR_TIMER:
4102 u.expr.v_optype=OPTYPE_TMR_RUNNING;
4103 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
4104 chk_expr_dynamic_part(exp_val, true);
4105 break;
4106 case Assignment::A_CONST:
4107 case Assignment::A_EXT_CONST:
4108 case Assignment::A_MODULEPAR:
4109 case Assignment::A_VAR:
4110 case Assignment::A_FUNCTION_RVAL:
4111 case Assignment::A_EXT_FUNCTION_RVAL:
4112 case Assignment::A_PAR_VAL_IN:
4113 case Assignment::A_PAR_VAL_OUT:
4114 case Assignment::A_PAR_VAL_INOUT: {
4115 u.expr.v_optype = OPTYPE_COMP_RUNNING;
4116 Value* val = new Value(V_REFD, u.expr.r1);
4117 val->set_my_scope(my_scope);
4118 val->set_fullname(u.expr.r1->get_fullname());
4119 val->set_location(*u.expr.r1);
4120 u.expr.v1 = val;
4121 chk_expr_operand_compref(val, opnum, get_opname());
4122 chk_expr_dynamic_part(exp_val, false);
4123 break; }
4124 default:
4125 ref->error("%s operand of operation `%s' should be timer or"
4126 " component reference instead of %s",
4127 opnum, opname, t_ass->get_description().c_str());
4128 goto error;
4129 } // switch
4130 return;
4131 error:
4132 set_valuetype(V_ERROR);
4133 }
4134
4135 Type *Value::chk_expr_operand_comptyperef_create()
4136 {
4137 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4138 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4139 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4140 if (!t_ass) goto error;
4141 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4142 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4143 Type::EXPECTED_DYNAMIC_VALUE);
4144 if (!t_type) goto error;
4145 t_type = t_type->get_type_refd_last();
4146 if (t_type->get_typetype() == Type::T_COMPONENT) {
4147 if (my_governor) {
4148 Type *my_governor_last = my_governor->get_type_refd_last();
4149 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4150 !my_governor_last->is_compatible(t_type, NULL)) {
4151 u.expr.r1->error("Incompatible component types: operation "
4152 "`create' should refer to `%s' instead of "
4153 "`%s'",
4154 my_governor_last->get_typename().c_str(),
4155 t_type->get_typename().c_str());
4156 goto error;
4157 }
4158 }
4159 return t_type;
4160 } else {
4161 u.expr.r1->error("Type mismatch: reference to a component type was "
4162 "expected in operation `create' instead of `%s'",
4163 t_type->get_typename().c_str());
4164 }
4165 } else {
4166 u.expr.r1->error("Operation `create' should refer to a component type "
4167 "instead of %s", t_ass->get_description().c_str());
4168 }
4169 error:
4170 set_valuetype(V_ERROR);
4171 return NULL;
4172 }
4173
4174 void Value::chk_expr_comptype_compat()
4175 {
4176 if (valuetype != V_EXPR)
4177 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4178 if (!my_governor || !my_scope) return;
4179 Type *my_governor_last = my_governor->get_type_refd_last();
4180 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4181 Type *t_comptype;
4182 switch (u.expr.v_optype) {
4183 case OPTYPE_COMP_MTC:
4184 t_comptype = my_scope->get_mtc_system_comptype(false);
4185 break;
4186 case OPTYPE_COMP_SYSTEM:
4187 t_comptype = my_scope->get_mtc_system_comptype(true);
4188 break;
4189 case OPTYPE_COMP_SELF: {
4190 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4191 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4192 break; }
4193 default:
4194 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4195 t_comptype = 0;
4196 break;
4197 }
4198 if (t_comptype
4199 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4200 error("Incompatible component types: a component reference of "
4201 "type `%s' was expected, but `%s' has type `%s'",
4202 my_governor_last->get_typename().c_str(), get_opname(),
4203 t_comptype->get_typename().c_str());
4204 set_valuetype(V_ERROR);
4205 }
4206 }
4207
4208 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4209 const char *opname)
4210 {
4211 if(valuetype == V_ERROR) return;
4212 switch(val->get_valuetype()) {
4213 case V_INVOKE: {
4214 Error_Context cntxt(this, "In `%s' operation", opname);
4215 Value *v_last = val->get_value_refd_last();
4216 if(!v_last) goto error;
4217 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4218 if(!t) goto error;
4219 t = t->get_type_refd_last();
4220 if(t->get_typetype() != Type::T_COMPONENT) {
4221 v_last->error("%s operand of operation `%s': Type mismatch:"
4222 " component reference was expected instead of `%s'",
4223 opnum, opname, t->get_typename().c_str());
4224 goto error;
4225 }
4226 return; }
4227 case V_REFD: {
4228 Reference *ref = val->get_reference();
4229 Assignment *t_ass = ref->get_refd_assignment();
4230 Value *t_val = 0;
4231 if (!t_ass) goto error;
4232 switch(t_ass->get_asstype()) {
4233 case Assignment::A_CONST:
4234 t_val = t_ass->get_Value();
4235 // no break
4236 case Assignment::A_EXT_CONST:
4237 case Assignment::A_MODULEPAR:
4238 case Assignment::A_VAR:
4239 case Assignment::A_FUNCTION_RVAL:
4240 case Assignment::A_EXT_FUNCTION_RVAL:
4241 case Assignment::A_PAR_VAL_IN:
4242 case Assignment::A_PAR_VAL_OUT:
4243 case Assignment::A_PAR_VAL_INOUT: {
4244 Type *t_type=t_ass->get_Type()
4245 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4246 if(!t_type) goto error;
4247 t_type=t_type->get_type_refd_last();
4248 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4249 ref->error("%s operand of operation `%s': Type mismatch:"
4250 " component reference was expected instead of `%s'",
4251 opnum, opname, t_type->get_typename().c_str());
4252 goto error;
4253 }
4254 break;}
4255 default:
4256 ref->error("%s operand of operation `%s' should be"
4257 " component reference instead of %s",
4258 opnum, opname, t_ass->get_description().c_str());
4259 goto error;
4260 }
4261 if (t_val) {
4262 ReferenceChain refch(this, "While searching referenced value");
4263 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4264 if (!t_val) return;
4265 t_val = t_val->get_value_refd_last();
4266 if (t_val->valuetype != V_EXPR) return;
4267 switch (t_val->u.expr.v_optype) {
4268 case OPTYPE_COMP_NULL:
4269 ref->error("%s operand of operation `%s' refers to `null' component "
4270 "reference", opnum, opname);
4271 goto error;
4272 case OPTYPE_COMP_MTC:
4273 ref->error("%s operand of operation `%s' refers to the component "
4274 "reference of the `mtc'", opnum, opname);
4275 goto error;
4276 case OPTYPE_COMP_SYSTEM:
4277 ref->error("%s operand of operation `%s' refers to the component "
4278 "reference of the `system'", opnum, opname);
4279 goto error;
4280 default:
4281 break;
4282 }
4283 }
4284 return;}
4285 default:
4286 FATAL_ERROR("Value::chk_expr_operand_compref()");
4287 }
4288 error:
4289 set_valuetype(V_ERROR);
4290 }
4291
4292 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4293 const char *opnum,
4294 const char *opname)
4295 {
4296 if(valuetype==V_ERROR) return;
4297 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4298 Assignment *t_ass = ref->get_refd_assignment();
4299 if(!t_ass) goto error;
4300 switch(t_ass->get_asstype()) {
4301 case Assignment::A_TIMER: {
4302 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4303 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4304 Type::EXPECTED_DYNAMIC_VALUE);
4305 else if (ref->get_subrefs()) {
4306 ref->error("%s operand of operation `%s': "
4307 "Reference to single timer `%s' cannot have field or array "
4308 "sub-references", opnum, opname,
4309 t_ass->get_id().get_dispname().c_str());
4310 goto error;
4311 }
4312 break; }
4313 case Assignment::A_PAR_TIMER:
4314 if (ref->get_subrefs()) {
4315 ref->error("%s operand of operation `%s': "
4316 "Reference to %s cannot have field or array sub-references",
4317 opnum, opname, t_ass->get_description().c_str());
4318 goto error;
4319 }
4320 break;
4321 default:
4322 ref->error("%s operand of operation `%s' should be timer"
4323 " instead of %s",
4324 opnum, opname, t_ass->get_description().c_str());
4325 goto error;
4326 } // switch
4327 return;
4328 error:
4329 set_valuetype(V_ERROR);
4330 }
4331
4332 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4333 const char *,
4334 const char *opname)
4335 {
4336 if(valuetype==V_ERROR) return;
4337 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4338 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4339 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4340 Error_Context cntxt(this, "In `%s' operation", opname);
4341 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4342 }
4343
4344 void Value::chk_expr_operand_activate_refd(Value *val,
4345 Ttcn::TemplateInstances* t_list2,
4346 Ttcn::ActualParList *&parlist,
4347 const char *,
4348 const char *opname)
4349 {
4350 if(valuetype==V_ERROR) return;
4351 Error_Context cntxt(this, "In `%s' operation", opname);
4352 Type *t = val->get_expr_governor_last();
4353 if (t) {
4354 switch (t->get_typetype()) {
4355 case Type::T_ERROR:
4356 set_valuetype(V_ERROR);
4357 break;
4358 case Type::T_ALTSTEP: {
4359 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4360 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4361 if(is_erroneous) {
4362 delete parlist;
4363 parlist = 0;
4364 set_valuetype(V_ERROR);
4365 } else {
4366 parlist->set_fullname(get_fullname());
4367 parlist->set_my_scope(get_my_scope());
4368 if (!fp_list->chk_activate_argument(parlist,
4369 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4370 }
4371 break; }
4372 default:
4373 error("Reference to an altstep was expected in the argument of "
4374 "`derefers()' instead of `%s'", t->get_typename().c_str());
4375 set_valuetype(V_ERROR);
4376 break;
4377 }
4378 } else set_valuetype(V_ERROR);
4379 }
4380
4381 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4382 const char *,
4383 const char *opname)
4384 {
4385 if(valuetype==V_ERROR) return;
4386 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4387 Error_Context cntxt(this, "In `%s' operation", opname);
4388 Assignment *t_ass = ref->get_refd_assignment();
4389 bool error_flag = false;
4390 if (t_ass) {
4391 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4392 ref->error("Reference to a testcase was expected in the argument "
4393 "instead of %s", t_ass->get_description().c_str());
4394 error_flag = true;
4395 }
4396 } else error_flag = true;
4397 if (val) {
4398 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4399 Value *v_last = val->get_value_refd_last();
4400 switch (v_last->valuetype) {
4401 case V_REAL: {
4402 ttcn3float v_real = v_last->get_val_Real();
4403 if (v_real < 0.0) {
4404 val->error("The testcase guard timer has negative value: `%s'",
4405 Real2string(v_real).c_str());
4406 error_flag = true;
4407 }
4408 break; }
4409 case V_ERROR:
4410 error_flag = true;
4411 break;
4412 default:
4413 break;
4414 }
4415 }
4416 if (error_flag) set_valuetype(V_ERROR);
4417 }
4418
4419 void Value::chk_expr_operand_execute_refd(Value *v1,
4420 Ttcn::TemplateInstances* t_list2,
4421 Ttcn::ActualParList *&parlist,
4422 Value *v3,
4423 const char *,
4424 const char *opname)
4425 {
4426 if(valuetype==V_ERROR) return;
4427 Error_Context cntxt(this, "In `%s' operation", opname);
4428 Type *t = v1->get_expr_governor_last();
4429 if (t) {
4430 switch (t->get_typetype()) {
4431 case Type::T_ERROR:
4432 set_valuetype(V_ERROR);
4433 break;
4434 case Type::T_TESTCASE: {
4435 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4436 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4437 if(is_erroneous) {
4438 delete parlist;
4439 parlist = 0;
4440 set_valuetype(V_ERROR);
4441 } else {
4442 parlist->set_fullname(get_fullname());
4443 parlist->set_my_scope(get_my_scope());
4444 }
4445 break; }
4446 default:
4447 v1->error("Reference to a value of type testcase was expected in the "
4448 "argument of `derefers()' instead of `%s'",
4449 t->get_typename().c_str());
4450 set_valuetype(V_ERROR);
4451 break;
4452 }
4453 } else set_valuetype(V_ERROR);
4454 if (v3) {
4455 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4456 Value *v_last = v3->get_value_refd_last();
4457 switch (v_last->valuetype) {
4458 case V_REAL: {
4459 ttcn3float v_real = v_last->get_val_Real();
4460 if(v_real < 0.0) {
4461 v3->error("The testcase guard timer has negative value: `%s'",
4462 Real2string(v_real).c_str());
4463 set_valuetype(V_ERROR);
4464 }
4465 break; }
4466 case V_ERROR:
4467 set_valuetype(V_ERROR);
4468 break;
4469 default:
4470 break;
4471 }
4472 }
4473 }
4474
4475 void Value::chk_invoke(Type::expected_value_t exp_val)
4476 {
4477 if(valuetype == V_ERROR) return;
4478 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4479 if(!u.invoke.t_list) return; //already checked
4480 Error_Context cntxt(this, "In `apply()' operation");
4481 Type *t = u.invoke.v->get_expr_governor_last();
4482 if (!t) {
4483 set_valuetype(V_ERROR);
4484 return;
4485 }
4486 switch (t->get_typetype()) {
4487 case Type::T_ERROR:
4488 set_valuetype(V_ERROR);
4489 return;
4490 case Type::T_FUNCTION:
4491 break;
4492 default:
4493 u.invoke.v->error("A value of type function was expected in the "
4494 "argument instead of `%s'", t->get_typename().c_str());
4495 set_valuetype(V_ERROR);
4496 return;
4497 }
4498 my_scope->chk_runs_on_clause(t, *this, "call");
4499 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4500 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4501 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4502 delete u.invoke.t_list;
4503 u.invoke.t_list = 0;
4504 if(is_erroneous) {
4505 delete parlist;
4506 u.invoke.ap_list = 0;
4507 } else {
4508 parlist->set_fullname(get_fullname());
4509 parlist->set_my_scope(get_my_scope());
4510 u.invoke.ap_list = parlist;
4511 }
4512 switch (exp_val) {
4513 case Type::EXPECTED_CONSTANT:
4514 error("An evaluable constant value was expected instead of operation "
4515 "`apply()'");
4516 set_valuetype(V_ERROR);
4517 break;
4518 case Type::EXPECTED_STATIC_VALUE:
4519 error("A static value was expected instead of operation `apply()'");
4520 set_valuetype(V_ERROR);
4521 break;
4522 default:
4523 break;
4524 } // switch
4525 }
4526
4527 void Value::chk_expr_eval_value(Value *val, Type &t,
4528 ReferenceChain *refch,
4529 Type::expected_value_t exp_val)
4530 {
4531 bool self_ref = false;
4532 if(valuetype==V_ERROR) return;
4533 // Commented out to report more errors :)
4534 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4535 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4536 switch(val->get_valuetype()) {
4537 case V_REFD:
4538 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4539 break;
4540 case V_EXPR:
4541 case V_MACRO:
4542 case V_INVOKE:
4543 val->get_value_refd_last(refch, exp_val);
4544 break;
4545 default:
4546 break;
4547 } // switch
4548 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4549
4550 (void)self_ref;
4551 }
4552
4553 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4554 ReferenceChain *refch, Type::expected_value_t exp_val)
4555 {
4556 bool self_ref = false;
4557 ti->chk(type);
4558 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4559 ti->error("Reference to a %s value was expected instead of an in-line "
4560 "modified template",
4561 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4562 set_valuetype(V_ERROR);
4563 return;
4564 }
4565 Template *templ = ti->get_Template();
4566 switch (templ->get_templatetype()) {
4567 case Template::TEMPLATE_REFD:
4568 // not foldable
4569 if (exp_val == Type::EXPECTED_TEMPLATE) {
4570 templ = templ->get_template_refd_last(refch);
4571 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4572 set_valuetype(V_ERROR);
4573 } else {
4574 ti->error("Reference to a %s value was expected instead of %s",
4575 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4576 templ->get_reference()->get_refd_assignment()
4577 ->get_description().c_str());
4578 set_valuetype(V_ERROR);
4579 }
4580 break;
4581 case Template::SPECIFIC_VALUE: {
4582 Value *val = templ->get_specific_value();
4583 switch (val->get_valuetype()) {
4584 case V_REFD:
4585 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4586 break;
4587 case V_EXPR:
4588 val->get_value_refd_last(refch, exp_val);
4589 default:
4590 break;
4591 } // switch
4592 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4593 break; }
4594 case Template::TEMPLATE_ERROR:
4595 set_valuetype(V_ERROR);
4596 break;
4597 default:
4598 break;
4599 } // switch
4600
4601 (void)self_ref;
4602 }
4603
4604 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4605 const char *opname)
4606 {
4607 if(valuetype==V_ERROR) return;
4608 if(u.expr.state==EXPR_CHECKING_ERR) return;
4609 if(val->is_unfoldable()) return;
4610 if(*val->get_val_Int()<0) {
4611 val->error("%s operand of operation `%s' should not be negative",
4612 opnum, opname);
4613 set_valuetype(V_ERROR);
4614 }
4615 }
4616
4617 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4618 const char *opname)
4619 {
4620 if(valuetype==V_ERROR) return;
4621 if(u.expr.state==EXPR_CHECKING_ERR) return;
4622 if(val->is_unfoldable()) return;
4623 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4624 val->error("%s operand of operation `%s' should be in range 0..127",
4625 opnum, opname);
4626 set_valuetype(V_ERROR);
4627 }
4628 }
4629
4630 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4631 const char *opname)
4632 {
4633 if(valuetype==V_ERROR) return;
4634 if(u.expr.state==EXPR_CHECKING_ERR) return;
4635 if(val->is_unfoldable()) return;
4636 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4637 val->error("%s operand of operation `%s' should be in range"
4638 " 0..2147483647", opnum, opname);
4639 set_valuetype(V_ERROR);
4640 }
4641 }
4642
4643 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4644 const char *opname)
4645 {
4646 if(valuetype==V_ERROR) return;
4647 if(u.expr.state==EXPR_CHECKING_ERR) return;
4648 if(val->is_unfoldable()) return;
4649 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4650 ||
4651 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4652 {
4653 val->error("%s operand of operation `%s' should not be zero",
4654 opnum, opname);
4655 set_valuetype(V_ERROR);
4656 }
4657 }
4658
4659 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4660 const char *opname)
4661 {
4662 if (valuetype == V_ERROR) return;
4663 if (u.expr.state == EXPR_CHECKING_ERR) return;
4664 if (val->get_expr_returntype() != Type::T_INT) return;
4665 if (val->is_unfoldable()) return;
4666 const int_val_t *val_int = val->get_val_Int();
4667 if (*val_int > static_cast<Int>(INT_MAX)) {
4668 val->error("%s operand of operation `%s' should be less than `%d' "
4669 "instead of `%s'", opnum, opname, INT_MAX,
4670 (val_int->t_str()).c_str());
4671 set_valuetype(V_ERROR);
4672 }
4673 }
4674
4675 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4676 const char *opname)
4677 {
4678 if(valuetype==V_ERROR) return;
4679 if(u.expr.state==EXPR_CHECKING_ERR) return;
4680 if(val->is_unfoldable()) return;
4681 if(val->get_val_strlen()!=1) {
4682 val->error("%s operand of operation `%s' should be of length 1",
4683 opnum, opname);
4684 set_valuetype(V_ERROR);
4685 }
4686 }
4687
4688 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4689 const char *opname)
4690 {
4691 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4692 Value *v_last = val->get_value_refd_last();
4693 if (v_last->valuetype == V_CSTR) {
4694 size_t len = v_last->get_val_strlen();
4695 if (len % 2) {
4696 val->error("%s operand of operation `%s' should contain even number "
4697 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4698 set_valuetype(V_ERROR);
4699 }
4700 } else if (v_last->valuetype == V_REFD) {
4701 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4702 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4703 val->error("%s operand of operation `%s' should contain even number "
4704 "of characters, but a string element contains 1", opnum, opname);
4705 set_valuetype(V_ERROR);
4706 }
4707 }
4708 }
4709
4710 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4711 const char *opname)
4712 {
4713 if(valuetype==V_ERROR) return;
4714 if(u.expr.state==EXPR_CHECKING_ERR) return;
4715 if(val->is_unfoldable()) return;
4716 const string& s=val->get_val_str();
4717 for(size_t i=0; i<s.size(); i++) {
4718 char c=s[i];
4719 if(!(c=='0' || c=='1')) {
4720 val->error("%s operand of operation `%s' can contain only"
4721 " binary digits (position %lu is `%c')",
4722 opnum, opname, (unsigned long) i, c);
4723 set_valuetype(V_ERROR);
4724 return;
4725 }
4726 }
4727 }
4728
4729 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4730 const char *opname)
4731 {
4732 if(valuetype==V_ERROR) return;
4733 if(u.expr.state==EXPR_CHECKING_ERR) return;
4734 if(val->is_unfoldable()) return;
4735 const string& s=val->get_val_str();
4736 for(size_t i=0; i<s.size(); i++) {
4737 char c=s[i];
4738 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4739 val->error("%s operand of operation `%s' can contain only valid "
4740 "hexadecimal digits (position %lu is `%c')",
4741 opnum, opname, (unsigned long) i, c);
4742 set_valuetype(V_ERROR);
4743 return;
4744 }
4745 }
4746 }
4747
4748 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4749 const char *opname)
4750 {
4751 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4752 Value *v = val->get_value_refd_last();
4753 if (v->valuetype != V_OSTR) return;
4754 const string& s = val->get_val_str();
4755 size_t n_octets = s.size() / 2;
4756 for (size_t i = 0; i < n_octets; i++) {
4757 char c = s[2 * i];
4758 if (!(c >= '0' && c <= '7')) {
4759 val->error("%s operand of operation `%s' shall consist of octets "
4760 "within the range 00 .. 7F, but the string `%s'O contains octet "
4761 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4762 (unsigned long) i);
4763 set_valuetype(V_ERROR);
4764 return;
4765 }
4766 }
4767 }
4768
4769 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4770 const char *opname)
4771 {
4772 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4773 Value *v_last = val->get_value_refd_last();
4774 if (v_last->valuetype != V_CSTR) return;
4775 const string& s = v_last->get_val_str();
4776 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4777 state = S_INITIAL;
4778 // state: expected characters
4779 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4780 // S_FIRST: first digit
4781 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4782 // S_END: trailing whitespace
4783 // S_ERR: error was found, stop
4784 for (size_t i = 0; i < s.size(); i++) {
4785 char c = s[i];
4786 switch (state) {
4787 case S_INITIAL:
4788 case S_INITIAL_WS:
4789 if (c == '+' || c == '-') state = S_FIRST;
4790 else if (c == '0') state = S_ZERO;
4791 else if (c >= '1' && c <= '9') state = S_MORE;
4792 else if (string::is_whitespace(c)) {
4793 if (state == S_INITIAL) {
4794 val->warning("Leading whitespace was detected and ignored in the "
4795 "operand of operation `%s'", opname);
4796 state = S_INITIAL_WS;
4797 }
4798 } else state = S_ERR;
4799 break;
4800 case S_FIRST:
4801 if (c == '0') state = S_ZERO;
4802 else if (c >= '1' && c <= '9') state = S_MORE;
4803 else state = S_ERR;
4804 break;
4805 case S_ZERO:
4806 if (c >= '0' && c <= '9') {
4807 val->warning("Leading zero digit was detected and ignored in the "
4808 "operand of operation `%s'", opname);
4809 state = S_MORE;
4810 } else if (string::is_whitespace(c)) state = S_END;
4811 else state = S_ERR;
4812 break;
4813 case S_MORE:
4814 if (c >= '0' && c <= '9') {}
4815 else if (string::is_whitespace(c)) state = S_END;
4816 else state = S_ERR;
4817 break;
4818 case S_END:
4819 if (!string::is_whitespace(c)) state = S_ERR;
4820 break;
4821 default:
4822 break;
4823 }
4824 if (state == S_ERR) {
4825 if (string::is_printable(c)) {
4826 val->error("%s operand of operation `%s' should be a string "
4827 "containing a valid integer value, but invalid character `%c' "
4828 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4829 } else {
4830 val->error("%s operand of operation `%s' should be a string "
4831 "containing a valid integer value, but invalid character with "
4832 "character code %u was detected at index %lu", opnum, opname, c,
4833 (unsigned long) i);
4834 }
4835 set_valuetype(V_ERROR);
4836 break;
4837 }
4838 }
4839 switch (state) {
4840 case S_INITIAL:
4841 case S_INITIAL_WS:
4842 val->error("%s operand of operation `%s' should be a string containing a "
4843 "valid integer value instead of an empty string", opnum, opname);
4844 set_valuetype(V_ERROR);
4845 break;
4846 case S_FIRST:
4847 val->error("%s operand of operation `%s' should be a string containing a "
4848 "valid integer value, but only a sign character was detected", opnum,
4849 opname);
4850 set_valuetype(V_ERROR);
4851 break;
4852 case S_END:
4853 val->warning("Trailing whitespace was detected and ignored in the "
4854 "operand of operation `%s'", opname);
4855 break;
4856 default:
4857 break;
4858 }
4859 }
4860
4861 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4862 const char *opname)
4863 {
4864 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4865 Value *v_last = val->get_value_refd_last();
4866 if (v_last->valuetype == V_REFD) {
4867 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4868 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4869 val->error("%s operand of operation `%s' should be a string containing "
4870 "a valid float value instead of a string element, which cannot "
4871 "represent a floating point number", opnum, opname);
4872 set_valuetype(V_ERROR);
4873 }
4874 return;
4875 } else if (v_last->valuetype != V_CSTR) return;
4876 const string& s = v_last->get_val_str();
4877 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4878 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4879 state = S_INITIAL;
4880 // state: expected characters
4881 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4882 // leading whitespace
4883 // S_FIRST_M: first digit of integer part in mantissa
4884 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4885 // S_FIRST_F: first digit of fraction
4886 // S_MORE_F: more digits of fraction, E, trailing whitespace
4887 // S_INITIAL_E: +, -, first digit of exponent
4888 // S_FIRST_E: first digit of exponent
4889 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4890 // S_END: trailing whitespace
4891 // S_ERR: error was found, stop
4892 for (size_t i = 0; i < s.size(); i++) {
4893 char c = s[i];
4894 switch (state) {
4895 case S_INITIAL:
4896 case S_INITIAL_WS:
4897 if (c == '+' || c == '-') state = S_FIRST_M;
4898 else if (c == '0') state = S_ZERO_M;
4899 else if (c >= '1' && c <= '9') state = S_MORE_M;
4900 else if (string::is_whitespace(c)) {
4901 if (state == S_INITIAL) {
4902 val->warning("Leading whitespace was detected and ignored in the "
4903 "operand of operation `%s'", opname);
4904 state = S_INITIAL_WS;
4905 }
4906 } else state = S_ERR;
4907 break;
4908 case S_FIRST_M:
4909 if (c == '0') state = S_ZERO_M;
4910 else if (c >= '1' && c <= '9') state = S_MORE_M;
4911 else state = S_ERR;
4912 break;
4913 case S_ZERO_M:
4914 if (c == '.') state = S_FIRST_F;
4915 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4916 else if (c >= '0' && c <= '9') {
4917 val->warning("Leading zero digit was detected and ignored in the "
4918 "mantissa of the operand of operation `%s'", opname);
4919 state = S_MORE_M;
4920 } else state = S_ERR;
4921 break;
4922 case S_MORE_M:
4923 if (c == '.') state = S_FIRST_F;
4924 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4925 else if (c >= '0' && c <= '9') {}
4926 else state = S_ERR;
4927 break;
4928 case S_FIRST_F:
4929 if (c >= '0' && c <= '9') state = S_MORE_F;
4930 else state = S_ERR;
4931 break;
4932 case S_MORE_F:
4933 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4934 else if (c >= '0' && c <= '9') {}
4935 else if (string::is_whitespace(c)) state = S_END;
4936 else state = S_ERR;
4937 break;
4938 case S_INITIAL_E:
4939 if (c == '+' || c == '-') state = S_FIRST_E;
4940 else if (c == '0') state = S_ZERO_E;
4941 else if (c >= '1' && c <= '9') state = S_MORE_E;
4942 else state = S_ERR;
4943 break;
4944 case S_FIRST_E:
4945 if (c == '0') state = S_ZERO_E;
4946 else if (c >= '1' && c <= '9') state = S_MORE_E;
4947 else state = S_ERR;
4948 break;
4949 case S_ZERO_E:
4950 if (c >= '0' && c <= '9') {
4951 val->warning("Leading zero digit was detected and ignored in the "
4952 "exponent of the operand of operation `%s'", opname);
4953 state = S_MORE_E;
4954 } else if (string::is_whitespace(c)) state = S_END;
4955 else state = S_ERR;
4956 break;
4957 case S_MORE_E:
4958 if (c >= '0' && c <= '9') {}
4959 else if (string::is_whitespace(c)) state = S_END;
4960 else state = S_ERR;
4961 break;
4962 case S_END:
4963 if (!string::is_whitespace(c)) state = S_ERR;
4964 break;
4965 default:
4966 break;
4967 }
4968 if (state == S_ERR) {
4969 if (string::is_printable(c)) {
4970 val->error("%s operand of operation `%s' should be a string "
4971 "containing a valid float value, but invalid character `%c' "
4972 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4973 } else {
4974 val->error("%s operand of operation `%s' should be a string "
4975 "containing a valid float value, but invalid character with "
4976 "character code %u was detected at index %lu", opnum, opname, c,
4977 (unsigned long) i);
4978 }
4979 set_valuetype(V_ERROR);
4980 break;
4981 }
4982 }
4983 switch (state) {
4984 case S_INITIAL:
4985 case S_INITIAL_WS:
4986 val->error("%s operand of operation `%s' should be a string containing a "
4987 "valid float value instead of an empty string", opnum, opname);
4988 set_valuetype(V_ERROR);
4989 break;
4990 case S_FIRST_M:
4991 val->error("%s operand of operation `%s' should be a string containing a "
4992 "valid float value, but only a sign character was detected", opnum,
4993 opname);
4994 set_valuetype(V_ERROR);
4995 break;
4996 case S_ZERO_M:
4997 case S_MORE_M:
4998 // HL67862: Missing decimal dot allowed for str2float
4999 break;
5000 case S_FIRST_F:
5001 // HL67862: Missing fraction part is allowed for str2float
5002 break;
5003 case S_INITIAL_E:
5004 case S_FIRST_E:
5005 val->error("%s operand of operation `%s' should be a string containing a "
5006 "valid float value, but the exponent is missing after the `E' sign",
5007 opnum, opname);
5008 set_valuetype(V_ERROR);
5009 break;
5010 case S_END:
5011 val->warning("Trailing whitespace was detected and ignored in the "
5012 "operand of operation `%s'", opname);
5013 break;
5014 default:
5015 break;
5016 }
5017 }
5018
5019 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
5020 const char *opname)
5021 {
5022 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5023 Value *v = val->get_value_refd_last();
5024 if (v->valuetype != V_USTR) return;
5025 const ustring& us = v->get_val_ustr();
5026 for (size_t i = 0; i < us.size(); i++) {
5027 const ustring::universal_char& uchar = us[i];
5028 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
5029 uchar.cell > 127) {
5030 val->error("%s operand of operation `%s' shall consist of characters "
5031 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5032 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5033 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
5034 uchar.row, uchar.cell, (unsigned long) i);
5035 set_valuetype(V_ERROR);
5036 return;
5037 }
5038 }
5039 }
5040
5041 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
5042 const char *opname)
5043 {
5044 if(valuetype==V_ERROR) return;
5045 if(u.expr.state==EXPR_CHECKING_ERR) return;
5046 if(val->is_unfoldable()) return;
5047 const string& bstr=val->get_val_str();
5048 // see also PredefFunc.cc::bit2int()
5049 size_t nof_bits = bstr.size();
5050 // skip the leading zeros
5051 size_t start_index = 0;
5052 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
5053 // check whether the remaining bits fit in Int
5054 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
5055 val->error("%s operand of operation `%s' is too large (maximum number"
5056 " of bits in integer is %lu)",
5057 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5058 set_valuetype(V_ERROR);
5059 }
5060 }
5061
5062 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
5063 const char *opname)
5064 {
5065 if(valuetype==V_ERROR) return;
5066 if(u.expr.state==EXPR_CHECKING_ERR) return;
5067 if(val->is_unfoldable()) return;
5068 const string& hstr=val->get_val_str();
5069 // see also PredefFunc.cc::hex2int()
5070 size_t nof_digits = hstr.size();
5071 // skip the leading zeros
5072 size_t start_index = 0;
5073 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
5074 // check whether the remaining hex digits fit in Int
5075 if (nof_digits - start_index > 2 * sizeof(Int) ||
5076 (nof_digits - start_index == 2 * sizeof(Int) &&
5077 char_to_hexdigit(hstr[start_index]) > 7)) {
5078 val->error("%s operand of operation `%s' is too large (maximum number"
5079 " of bits in integer is %lu)",
5080 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5081 set_valuetype(V_ERROR);
5082 }
5083 }
5084
5085 void Value::chk_expr_operands_int2binstr()
5086 {
5087 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5088 if (u.expr.v1->is_unfoldable()) return;
5089 if (u.expr.v2->is_unfoldable()) return;
5090 // It is already checked that i1 and i2 are non-negative.
5091 Error_Context cntxt(this, "In operation `%s'", get_opname());
5092 const int_val_t *i1 = u.expr.v1->get_val_Int();
5093 const int_val_t *i2 = u.expr.v2->get_val_Int();
5094 if (!i2->is_native()) {
5095 u.expr.v2->error("The length of the resulting string is too large for "
5096 "being represented in memory");
5097 set_valuetype(V_ERROR);
5098 return;
5099 }
5100 Int nof_bits = i2->get_val();
5101 if (u.expr.v1->is_unfoldable()) return;
5102 switch (u.expr.v_optype) {
5103 case OPTYPE_INT2BIT:
5104 break;
5105 case OPTYPE_INT2HEX:
5106 nof_bits *= 4;
5107 break;
5108 case OPTYPE_INT2OCT:
5109 nof_bits *= 8;
5110 break;
5111 default:
5112 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5113 }
5114 if (*i1 >> nof_bits > 0) { // Expensive?
5115 u.expr.v1->error("Value %s does not fit in length %s",
5116 i1->t_str().c_str(), i2->t_str().c_str());
5117 set_valuetype(V_ERROR);
5118 }
5119 }
5120
5121 void Value::chk_expr_operands_str_samelen()
5122 {
5123 if(valuetype==V_ERROR) return;
5124 if(u.expr.state==EXPR_CHECKING_ERR) return;
5125 Value *v1=u.expr.v1;
5126 if(v1->is_unfoldable()) return;
5127 Value *v2=u.expr.v2;
5128 if(v2->is_unfoldable()) return;
5129 Error_Context cntxt(this, "In operation `%s'", get_opname());
5130 size_t i1=v1->get_val_strlen();
5131 size_t i2=v2->get_val_strlen();
5132 if(i1!=i2) {
5133 error("The operands should have the same length");
5134 set_valuetype(V_ERROR);
5135 }
5136 }
5137
5138 void Value::chk_expr_operands_replace()
5139 {
5140 // The fourth operand doesn't need to be checked at all here.
5141 if(valuetype==V_ERROR) return;
5142 if(u.expr.state==EXPR_CHECKING_ERR) return;
5143 Value* v1 = u.expr.ti1->get_specific_value();
5144 if (!v1) return;
5145
5146 Error_Context cntxt(this, "In operation `%s'", get_opname());
5147 size_t list_len = 0;
5148 bool list_len_known = false;
5149 if (v1->valuetype == V_REFD) {
5150 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5151 if (subrefs && subrefs->refers_to_string_element()) {
5152 warning("Replacing a string element does not make any sense");
5153 list_len = 1;
5154 list_len_known = true;
5155 }
5156 }
5157 if (!v1->is_unfoldable()) {
5158 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5159 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5160 list_len_known = true;
5161 }
5162 if (!list_len_known) return;
5163 if (u.expr.v2->is_unfoldable()) {
5164 if (!u.expr.v3->is_unfoldable()) {
5165 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5166 if (*len_int_3 > static_cast<Int>(list_len)) {
5167 error("Third operand `len' (%s) is greater than the length of "
5168 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5169 (unsigned long)list_len);
5170 set_valuetype(V_ERROR);
5171 }
5172 }
5173 } else {
5174 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5175 if (u.expr.v3->is_unfoldable()) {
5176 if (*index_int_2 > static_cast<Int>(list_len)) {
5177 error("Second operand `index' (%s) is greater than the length of "
5178 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5179 (unsigned long)list_len);
5180 set_valuetype(V_ERROR);
5181 }
5182 } else {
5183 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5184 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5185 error("The sum of second operand `index' (%s) and third operand "
5186 "`len' (%s) is greater than the length of the first operand (%lu)",
5187 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5188 (unsigned long)list_len);
5189 set_valuetype(V_ERROR);
5190 }
5191 }
5192 }
5193 }
5194
5195 void Value::chk_expr_operands_substr()
5196 {
5197 if(valuetype==V_ERROR) return;
5198 if(u.expr.state==EXPR_CHECKING_ERR) return;
5199 Value* v1 = u.expr.ti1->get_specific_value();
5200 if (!v1) return;
5201
5202 Error_Context cntxt(this, "In operation `%s'", get_opname());
5203 size_t list_len = 0;
5204 bool list_len_known = false;
5205 if (v1->valuetype == V_REFD) {
5206 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5207 if (subrefs && subrefs->refers_to_string_element()) {
5208 warning("Taking the substring of a string element does not make any "
5209 "sense");
5210 list_len = 1;
5211 list_len_known = true;
5212 }
5213 }
5214 if (!list_len_known && !v1->is_unfoldable()) {
5215 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5216 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5217 list_len_known = true;
5218 }
5219 // Do nothing if the length of the first operand is unknown.
5220 if (!list_len_known) return;
5221 if (u.expr.v2->is_unfoldable()) {
5222 if (!u.expr.v3->is_unfoldable()) {
5223 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5224 // Only the third operand is known.
5225 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5226 error("Third operand `returncount' (%s) is greater than the "
5227 "length of the first operand (%lu)",
5228 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5229 set_valuetype(V_ERROR);
5230 }
5231 }
5232 } else {
5233 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5234 if (u.expr.v3->is_unfoldable()) {
5235 // Only the second operand is known.
5236 if (*index_int_2 > static_cast<Int>(list_len)) {
5237 error("Second operand `index' (%s) is greater than the length "
5238 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5239 (unsigned long)list_len);
5240 set_valuetype(V_ERROR);
5241 }
5242 } else {
5243 // Both second and third operands are known.
5244 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5245 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5246 error("The sum of second operand `index' (%s) and third operand "
5247 "`returncount' (%s) is greater than the length of the first operand "
5248 "(%lu)", (index_int_2->t_str()).c_str(),
5249 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5250 set_valuetype(V_ERROR);
5251 }
5252 }
5253 }
5254 }
5255
5256 void Value::chk_expr_operands_regexp()
5257 {
5258 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5259 Value* v1 = u.expr.ti1->get_specific_value();
5260 Value* v2 = u.expr.t2->get_specific_value();
5261 if (!v1 || !v2) return;
5262
5263 Error_Context cntxt(this, "In operation `regexp()'");
5264 Value* v1_last = v1->get_value_refd_last();
5265 if (v1_last->valuetype == V_CSTR) {
5266 // the input string is available at compile time
5267 const string& instr = v1_last->get_val_str();
5268 const char *input_str = instr.c_str();
5269 size_t instr_len = strlen(input_str);
5270 if (instr_len < instr.size()) {
5271 v1->warning("The first operand of `regexp()' contains a "
5272 "character with character code zero at index %s. The rest of the "
5273 "string will be ignored during matching",
5274 Int2string(instr_len).c_str());
5275 }
5276 }
5277
5278 size_t nof_groups = 0;
5279 Value *v2_last = v2->get_value_refd_last();
5280
5281 if (v2_last->valuetype == V_CSTR) {
5282 // the pattern is available at compile time
5283 const string& expression = v2_last->get_val_str();
5284 const char *pattern_str = expression.c_str();
5285 size_t pattern_len = strlen(pattern_str);
5286 if (pattern_len < expression.size()) {
5287 v2->warning("The second operand of `regexp()' contains a "
5288 "character with character code zero at index %s. The rest of the "
5289 "string will be ignored during matching",
5290 Int2string(pattern_len).c_str());
5291 }
5292 char *posix_str;
5293 {
5294 Error_Context cntxt2(v2, "In character string pattern");
5295 posix_str = TTCN_pattern_to_regexp(pattern_str);
5296 }
5297 if (posix_str != NULL) {
5298 regex_t posix_regexp;
5299 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5300 if (ret_val != 0) {
5301 char msg[512];
5302 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5303 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5304 "regcomp() failed: %s", msg);
5305 }
5306 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5307 else {
5308 v2->error("The character pattern in the second operand of "
5309 "`regexp()' does not contain any groups");
5310 set_valuetype(V_ERROR);
5311 }
5312 regfree(&posix_regexp);
5313 Free(posix_str);
5314 } else {
5315 // the pattern is faulty
5316 // the error has been reported by TTCN_pattern_to_regexp
5317 set_valuetype(V_ERROR);
5318 }
5319 }
5320 if (nof_groups > 0) {
5321 Value *v3 = u.expr.v3->get_value_refd_last();
5322 if (v3->valuetype == V_INT) {
5323 // the group number is available at compile time
5324 const int_val_t *groupno_int = v3->get_val_Int();
5325 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5326 u.expr.v3->error("The the third operand of `regexp()' is too "
5327 "large: The requested group index is %s, but the pattern "
5328 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5329 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5330 set_valuetype(V_ERROR);
5331 }
5332 }
5333 }
5334 }
5335
5336 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5337 Type::expected_value_t exp_val)
5338 {
5339 const char *opname = get_opname();
5340 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5341 Type *t_governor;
5342 const Location *loc;
5343 bool error_flag = false;
5344 switch (u.expr.v_optype) {
5345 case OPTYPE_ISCHOSEN_V:
5346 // u.expr.v1 is always a referenced value
5347 t_governor = u.expr.v1->get_expr_governor(exp_val);
5348 if (t_governor) {
5349 u.expr.v1->set_my_governor(t_governor);
5350 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5351 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5352 } else error_flag = true;
5353 loc = u.expr.v1;
5354 break;
5355 case OPTYPE_ISCHOSEN_T:
5356 // u.expr.t1 is always a referenced template
5357 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5358 exp_val = Type::EXPECTED_TEMPLATE;
5359 t_governor = u.expr.t1->get_expr_governor(exp_val);
5360 if (t_governor) {
5361 u.expr.t1->set_my_governor(t_governor);
5362 //
5363 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5364 //
5365 u.expr.t1->get_template_refd_last(refch);
5366 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5367 error_flag = true;
5368 } else error_flag = true;
5369 if (exp_val != Type::EXPECTED_TEMPLATE) {
5370 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5371 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5372 u.expr.t1->get_reference()->get_refd_assignment()
5373 ->get_description().c_str());
5374 error_flag = true;
5375 }
5376 loc = u.expr.t1;
5377 break;
5378 default:
5379 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5380 t_governor = 0;
5381 loc = 0;
5382 }
5383 if (t_governor) {
5384 t_governor = t_governor->get_type_refd_last();
5385 switch (t_governor->get_typetype()) {
5386 case Type::T_ERROR:
5387 error_flag = true;
5388 break;
5389 case Type::T_CHOICE_A:
5390 case Type::T_CHOICE_T:
5391 case Type::T_ANYTYPE:
5392 case Type::T_OPENTYPE:
5393 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5394 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5395 "%s does not have a field named `%s'" :
5396 "Union type `%s' does not have a field named `%s'",
5397 t_governor->get_typename().c_str(),
5398 u.expr.i2->get_dispname().c_str());
5399 error_flag = true;
5400 }
5401 break;
5402 default:
5403 loc->error("The operand of operation `%s' should be a union value "
5404 "or template instead of `%s'", opname,
5405 t_governor->get_typename().c_str());
5406 error_flag = true;
5407 break;
5408 }
5409 }
5410 if (error_flag) set_valuetype(V_ERROR);
5411 }
5412
5413 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5414 Type::expected_value_t exp_val) {
5415
5416 Error_Context cntxt(this, "In the parameter of %s",
5417 u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR ? "encvalue_unichar()" : "encvalue()");
5418 Type t_chk(Type::T_ERROR);
5419 Type* t_type;
5420
5421 Type::expected_value_t ti_exp_val = exp_val;
5422 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5423 ti_exp_val = Type::EXPECTED_TEMPLATE;
5424
5425 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5426 if (t_type) {
5427 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5428 if (valuetype!=V_ERROR)
5429 u.expr.ti1->get_Template()->chk_specific_value(false);
5430 t_type = t_type->get_type_refd_last();
5431 } else {
5432 error("Cannot determine type of value");
5433 goto error;
5434 }
5435
5436 // todo: fix this
5437 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5438 error("Expecting a value of a type with coding attributes in first"
5439 "parameter of encvalue() which belongs to a generic type '%s'",
5440 t_type->get_typename().c_str());
5441 goto error;
5442 }*/
5443
5444 if(!disable_attribute_validation()) {
5445 t_type->chk_coding(true);
5446 }
5447
5448 switch (t_type->get_typetype()) {
5449 case Type::T_UNDEF:
5450 case Type::T_ERROR:
5451 case Type::T_NULL:
5452 case Type::T_REFD:
5453 case Type::T_REFDSPEC:
5454 case Type::T_SELTYPE:
5455 case Type::T_VERDICT:
5456 case Type::T_PORT:
5457 case Type::T_COMPONENT:
5458 case Type::T_DEFAULT:
5459 case Type::T_SIGNATURE:
5460 case Type::T_FUNCTION:
5461 case Type::T_ALTSTEP:
5462 case Type::T_TESTCASE:
5463 error("Type of parameter of encvalue() cannot be '%s'",
5464 t_type->get_typename().c_str());
5465 goto error;
5466 default:
5467 break;
5468 }
5469 return;
5470 error:
5471 set_valuetype(V_ERROR);
5472 }
5473
5474 void Value::chk_expr_operands_decode(operationtype_t p_optype)
5475 {
5476 Error_Context cntxt(this, "In the parameters of %s",
5477 p_optype == OPTYPE_DECVALUE_UNICHAR ? "encvalue_unichar()" : "decvalue()");
5478 Ttcn::Ref_base* ref = u.expr.r1;
5479 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5480 Type* t_type = 0;
5481 Assignment* t_ass = ref->get_refd_assignment();
5482
5483 if (!t_ass) {
5484 error("Could not determine the assignment for first parameter");
5485 goto error;
5486 }
5487 switch (t_ass->get_asstype()) {
5488 case Assignment::A_PAR_VAL_IN:
5489 t_ass->use_as_lvalue(*this);
5490 break;
5491 case Assignment::A_CONST:
5492 case Assignment::A_EXT_CONST:
5493 case Assignment::A_MODULEPAR:
5494 case Assignment::A_MODULEPAR_TEMP:
5495 case Assignment::A_TEMPLATE:
5496 ref->error("Reference to '%s' cannot be used as the first operand of "
5497 "the 'decvalue' operation", t_ass->get_assname());
5498 goto error;
5499 break;
5500 case Assignment::A_VAR:
5501 case Assignment::A_PAR_VAL_OUT:
5502 case Assignment::A_PAR_VAL_INOUT:
5503 break;
5504 case Assignment::A_VAR_TEMPLATE:
5505 case Assignment::A_PAR_TEMPL_IN:
5506 case Assignment::A_PAR_TEMPL_OUT:
5507 case Assignment::A_PAR_TEMPL_INOUT: {
5508 Template* t = new Template(ref->clone());
5509 t->set_location(*ref);
5510 t->set_my_scope(get_my_scope());
5511 t->set_fullname(get_fullname()+".<operand>");
5512 Template* t_last = t->get_template_refd_last();
5513 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5514 && t_last != t) {
5515 ref->error("Specific value template was expected instead of '%s'.",
5516 t->get_template_refd_last()->get_templatetype_str());
5517 delete t;
5518 goto error;
5519 }
5520 delete t;
5521 break; }
5522 default:
5523 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5524 goto error;
5525 }
5526 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5527 Type::EXPECTED_DYNAMIC_VALUE);
5528 if (!t_type) {
5529 goto error;
5530 }
5531 switch(p_optype) {
5532 case OPTYPE_DECODE:
5533 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5534 error("First parameter has to be a bitstring");
5535 goto error;
5536 }
5537 break;
5538 case OPTYPE_DECVALUE_UNICHAR:
5539 if (t_type->get_type_refd_last()->get_typetype() != Type::T_USTR){
5540 error("First parameter has to be a universal charstring");
5541 goto error;
5542 }
5543 break;
5544 default:
5545 FATAL_ERROR("Value::chk_expr_decode_operands()");
5546 break;
5547 }
5548
5549 ref = u.expr.r2;
5550 t_subrefs = ref->get_subrefs();
5551 t_ass = ref->get_refd_assignment();
5552
5553 if (!t_ass) {
5554 error("Could not determine the assignment for second parameter");
5555 goto error;
5556 }
5557 // Extra check for HM59355.
5558 switch (t_ass->get_asstype()) {
5559 case Assignment::A_VAR:
5560 case Assignment::A_PAR_VAL_IN:
5561 case Assignment::A_PAR_VAL_OUT:
5562 case Assignment::A_PAR_VAL_INOUT:
5563 break;
5564 default:
5565 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5566 goto error;
5567 }
5568 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5569 Type::EXPECTED_DYNAMIC_VALUE);
5570 if (!t_type) {
5571 goto error;
5572 }
5573 t_type = t_type->get_type_refd_last();
5574 switch (t_type->get_typetype()) {
5575 case Type::T_UNDEF:
5576 case Type::T_ERROR:
5577 case Type::T_NULL:
5578 case Type::T_REFD:
5579 case Type::T_REFDSPEC:
5580 case Type::T_SELTYPE:
5581 case Type::T_VERDICT:
5582 case Type::T_PORT:
5583 case Type::T_COMPONENT:
5584 case Type::T_DEFAULT:
5585 case Type::T_SIGNATURE:
5586 case Type::T_FUNCTION:
5587 case Type::T_ALTSTEP:
5588 case Type::T_TESTCASE:
5589 error("Type of second parameter cannot be %s",
5590 t_type->get_typename().c_str());
5591 goto error;
5592 default:
5593 break;
5594 }
5595
5596 if(!disable_attribute_validation()) {
5597 t_type->chk_coding(false);
5598 }
5599
5600 return;
5601 error:
5602 set_valuetype(V_ERROR);
5603 }
5604
5605 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5606 {
5607 Ttcn::FieldOrArrayRefs *subrefs;
5608 Identifier *field_id = 0;
5609 Assignment *t_ass;
5610 Type *t_type;
5611 if (valuetype == V_ERROR) return;
5612 else if (valuetype != V_REFD) {
5613 error("Only a referenced value can be compared with `omit'");
5614 goto error;
5615 }
5616 subrefs = u.ref.ref->get_subrefs();
5617 if (subrefs) field_id = subrefs->remove_last_field();
5618 if (!field_id) {
5619 error("Only a reference pointing to an optional record or set field "
5620 "can be compared with `omit'");
5621 goto error;
5622 }
5623 t_ass = u.ref.ref->get_refd_assignment();
5624 if (!t_ass) goto error;
5625 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5626 if (!t_type) goto error;
5627 t_type = t_type->get_type_refd_last();
5628 switch (t_type->get_typetype()) {
5629 case Type::T_ERROR:
5630 goto error;
5631 case Type::T_SEQ_A:
5632 case Type::T_SEQ_T:
5633 case Type::T_SET_A:
5634 case Type::T_SET_T:
5635 break;
5636 default:
5637 error("Only a reference pointing to an optional field of a record"
5638 " or set type can be compared with `omit'");
5639 goto error;
5640 }
5641 if (!t_type->has_comp_withName(*field_id)) {
5642 error("Type `%s' does not have field named `%s'",
5643 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5644 goto error;
5645 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5646 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5647 "`omit'", field_id->get_dispname().c_str(),
5648 t_type->get_typename().c_str());
5649 goto error;
5650 }
5651 // putting the last field_id back to subrefs
5652 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5653 return;
5654 error:
5655 set_valuetype(V_ERROR);
5656 delete field_id;
5657 }
5658
5659 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5660 Type::expected_value_t exp_val)
5661 {
5662 if(valuetype==V_ERROR) return -1;
5663 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5664 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5665 exp_val=Type::EXPECTED_TEMPLATE;
5666
5667 Error_Context cntxt(this, "In the operand of"
5668 " operation `%s'", get_opname());
5669
5670 Int result = -1;
5671 Template* t_templ = u.expr.ti1->get_Template();
5672
5673 if (!t_templ) {
5674 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5675 }
5676
5677 t_templ = t_templ->get_template_refd_last(refch);
5678
5679 // Timer and port arrays are handled separately
5680 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5681 Value* val = t_templ->get_specific_value();
5682 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5683 val->set_lowerid_to_ref();
5684 }
5685 if (val && val->get_valuetype() == V_REFD) {
5686 Reference* ref = val->get_reference();
5687 Assignment* t_ass = ref->get_refd_assignment();
5688 Common::Assignment::asstype_t asstype =
5689 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5690 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5691 if (t_ass->get_Dimensions()) {
5692 // here we have a timer or port array
5693 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5694 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5695 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5696 Type::EXPECTED_DYNAMIC_VALUE);
5697 size_t refd_dim;
5698 if (t_subrefs) {
5699 refd_dim = t_subrefs->get_nof_refs();
5700 size_t nof_dims = t_dims->get_nof_dims();
5701 if (refd_dim >= nof_dims) {
5702 u.expr.ti1->error("Operation is not applicable to a %s",
5703 t_ass->get_assname());
5704 set_valuetype(V_ERROR);
5705 return -1;
5706 }
5707 } else refd_dim = 0;
5708 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5709 } else {
5710 u.expr.ti1->error("Operation is not applicable to single `%s'",
5711 t_ass->get_description().c_str());
5712 set_valuetype(V_ERROR);
5713 return -1;
5714 }
5715 }
5716 }
5717 }
5718
5719 Value* t_val = 0;
5720 Type* t_type = 0;
5721 Assignment* t_ass = 0;
5722 Reference* ref = 0;
5723 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5724 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5725 if (t_type) {
5726 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5727 t_type = t_type->get_type_refd_last();
5728 } else {
5729 error("Cannot determine type of value");
5730 goto error;
5731 }
5732
5733 if(valuetype==V_ERROR) return -1;
5734
5735 t_templ = t_templ->get_template_refd_last(refch);
5736 switch(t_templ->get_templatetype()) {
5737 case Template::TEMPLATE_ERROR:
5738 goto error;
5739 case Template::INDEXED_TEMPLATE_LIST:
5740 return -1;
5741 case Template::TEMPLATE_REFD:
5742 case Template::TEMPLATE_LIST:
5743 case Template::NAMED_TEMPLATE_LIST:
5744 // computed later
5745 break;
5746 case Template::SPECIFIC_VALUE:
5747 {
5748 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5749 if(t_val) {
5750 switch(t_val->get_valuetype()) {
5751 case V_SEQOF:
5752 case V_SETOF:
5753 case V_ARRAY:
5754 case V_ROID:
5755 case V_OID:
5756 case V_SEQ:
5757 case V_SET:
5758 break;
5759 case V_REFD: {
5760 ref = t_val->get_reference();
5761 t_ass = ref->get_refd_assignment();
5762 t_subrefs = ref->get_subrefs();
5763 break;
5764 }
5765 default:
5766 u.expr.ti1->error("Operation is not applicable to `%s'",
5767 t_val->create_stringRepr().c_str());
5768 goto error;
5769 }
5770 }
5771 break;
5772 }
5773 default:
5774 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5775 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5776 goto error;
5777 } // switch
5778
5779 if (t_ass) {
5780 switch(t_ass->get_asstype()) {
5781 case Assignment::A_ERROR:
5782 goto error;
5783 case Assignment::A_CONST:
5784 t_val = t_ass->get_Value();
5785 break;
5786 case Assignment::A_EXT_CONST:
5787 case Assignment::A_MODULEPAR:
5788 case Assignment::A_MODULEPAR_TEMP:
5789 if(exp_val==Type::EXPECTED_CONSTANT) {
5790 u.expr.ti1->error("Reference to an (evaluable) constant value was "
5791 "expected instead of %s", t_ass->get_description().c_str());
5792 goto error;
5793 }
5794 break;
5795 case Assignment::A_VAR:
5796 case Assignment::A_PAR_VAL_IN:
5797 case Assignment::A_PAR_VAL_OUT:
5798 case Assignment::A_PAR_VAL_INOUT:
5799 switch(exp_val) {
5800 case Type::EXPECTED_CONSTANT:
5801 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5802 t_ass->get_description().c_str());
5803 goto error;
5804 break;
5805 case Type::EXPECTED_STATIC_VALUE:
5806 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5807 t_ass->get_description().c_str());
5808 goto error;
5809 break;
5810 default:
5811 break;
5812 }
5813 break;
5814 case Assignment::A_TEMPLATE:
5815 t_templ = t_ass->get_Template();
5816 // no break
5817 case Assignment::A_VAR_TEMPLATE:
5818 case Assignment::A_PAR_TEMPL_IN:
5819 case Assignment::A_PAR_TEMPL_OUT:
5820 case Assignment::A_PAR_TEMPL_INOUT:
5821 if (exp_val!=Type::EXPECTED_TEMPLATE)
5822 u.expr.ti1->error("Reference to a value was expected instead of %s",
5823 t_ass->get_description().c_str());
5824 goto error;
5825 break;
5826 case Assignment::A_FUNCTION_RVAL:
5827 case Assignment::A_EXT_FUNCTION_RVAL:
5828 switch(exp_val) {
5829 case Type::EXPECTED_CONSTANT:
5830 u.expr.ti1->error("Reference to a constant value was expected instead of "
5831 "the return value of %s", t_ass->get_description().c_str());
5832 goto error;
5833 break;
5834 case Type::EXPECTED_STATIC_VALUE:
5835 u.expr.ti1->error("Reference to a static value was expected instead of "
5836 "the return value of %s", t_ass->get_description().c_str());
5837 goto error;
5838 break;
5839 default:
5840 break;
5841 }
5842 break;
5843 case Assignment::A_FUNCTION_RTEMP:
5844 case Assignment::A_EXT_FUNCTION_RTEMP:
5845 if(exp_val!=Type::EXPECTED_TEMPLATE)
5846 u.expr.ti1->error("Reference to a value was expected instead of a call"
5847 " of %s, which returns a template",
5848 t_ass->get_description().c_str());
5849 goto error;
5850 break;
5851 case Assignment::A_TIMER:
5852 case Assignment::A_PORT:
5853 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5854 // sizeof is applicable to timer and port arrays
5855 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5856 if (!t_dims) {
5857 u.expr.ti1->error("Operation is not applicable to single %s",
5858 t_ass->get_description().c_str());
5859 goto error;
5860 }
5861 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5862 Type::EXPECTED_DYNAMIC_VALUE);
5863 size_t refd_dim;
5864 if (t_subrefs) {
5865 refd_dim = t_subrefs->get_nof_refs();
5866 size_t nof_dims = t_dims->get_nof_dims();
5867 if (refd_dim > nof_dims) goto error;
5868 else if (refd_dim == nof_dims) {
5869 u.expr.ti1->error("Operation is not applicable to a %s",
5870 t_ass->get_assname());
5871 goto error;
5872 }
5873 } else refd_dim = 0;
5874 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5875 }
5876 // no break
5877 default:
5878 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5879 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5880 t_ass->get_description().c_str());
5881 goto error;
5882 } // end switch
5883
5884 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5885 if (!t_type) goto error;
5886 t_type = t_type->get_type_refd_last();
5887
5888 switch(t_type->get_typetype()) {
5889 case Type::T_ERROR:
5890 goto error;
5891 case Type::T_SEQOF:
5892 case Type::T_SETOF:
5893 // no break
5894 case Type::T_SEQ_T:
5895 case Type::T_SET_T:
5896 case Type::T_SEQ_A:
5897 case Type::T_SET_A:
5898 case Type::T_ARRAY:
5899 // ok
5900 break;
5901 case Type::T_OID:
5902 case Type::T_ROID:
5903 break;
5904 default:
5905 u.expr.ti1->error("Reference to value or template of type record, record of,"
5906 " set, set of, objid or array was expected");
5907 goto error;
5908 } // switch
5909 }
5910
5911 // check for index overflows in subrefs if possible
5912 if (t_val) {
5913 switch (t_val->get_valuetype()) {
5914 case V_SEQOF:
5915 case V_SETOF:
5916 case V_ARRAY:
5917 if (t_val->is_indexed()) {
5918 return -1;
5919 }
5920 break;
5921 default:
5922 break;
5923 }
5924 /* The reference points to a constant. */
5925 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5926 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5927 if (!t_val) goto error;
5928 t_val=t_val->get_value_refd_last(refch);
5929 } else { t_val = 0; }
5930 } else if (t_templ) {
5931 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5932 time. Don't try to evaluate it at compile time. */
5933 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5934 return -1;
5935 /* The reference points to a static template. */
5936 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5937 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5938 if (!t_templ) goto error;
5939 t_templ = t_templ->get_template_refd_last(refch);
5940 } else { t_templ = 0; }
5941 }
5942
5943 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5944 if(t_templ) {
5945 switch(t_templ->get_templatetype()) {
5946 case Template::TEMPLATE_ERROR:
5947 goto error;
5948 case Template::TEMPLATE_REFD:
5949 // not foldable
5950 t_templ=0;
5951 break;
5952 case Template::SPECIFIC_VALUE:
5953 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5954 t_templ=0;
5955 break;
5956 case Template::TEMPLATE_LIST:
5957 case Template::NAMED_TEMPLATE_LIST:
5958 break;
5959 default:
5960 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5961 t_templ->get_templatetype_str(),
5962 t_templ->get_fullname().c_str());
5963 goto error;
5964 } // switch
5965 }
5966 if(t_val) {
5967 switch(t_val->get_valuetype()) {
5968 case V_SEQOF:
5969 case V_SETOF:
5970 case V_ARRAY:
5971 case V_SEQ:
5972 case V_SET:
5973 case V_OID:
5974 case V_ROID:
5975 // ok
5976 break;
5977 default:
5978 // error is already reported
5979 t_val=0;
5980 break;
5981 } // switch
5982 }
5983 }
5984
5985 /* evaluation */
5986
5987 if(t_type->get_typetype()==Type::T_ARRAY) {
5988 result = t_type->get_dimension()->get_size();
5989 }
5990 else if(t_templ) { // sizeof()
5991 switch(t_templ->get_templatetype()) {
5992 case Template::TEMPLATE_LIST:
5993 if(t_templ->temps_contains_anyornone_symbol()) {
5994 if(t_templ->is_length_restricted()) {
5995 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5996 if (lr->get_is_range()) {
5997 Value *v_upper = lr->get_upper_value();
5998 if (v_upper) {
5999 if (v_upper->valuetype == V_INT) {
6000 Int nof_comps =
6001 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
6002 if (v_upper->u.val_Int->get_val() == nof_comps)
6003 result = nof_comps;
6004 else {
6005 u.expr.ti1->error("`sizeof' operation is not applicable for "
6006 "templates without exact size");
6007 goto error;
6008 }
6009 }
6010 } else {
6011 u.expr.ti1->error("`sizeof' operation is not applicable for "
6012 "templates containing `*' without upper boundary in the "
6013 "length restriction");
6014 goto error;
6015 }
6016 } else {
6017 Value *v_single = lr->get_single_value();
6018 if (v_single->valuetype == V_INT)
6019 result = v_single->u.val_Int->get_val();
6020 }
6021 }
6022 else { // not length restricted
6023 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
6024 " containing `*' without length restriction");
6025 goto error;
6026 }
6027 }
6028 else result=t_templ->get_nof_listitems();
6029 break;
6030 case Template::NAMED_TEMPLATE_LIST:
6031 result=0;
6032 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
6033 if(t_templ->get_namedtemp_byIndex(i)->get_template()
6034 ->get_templatetype()!=Template::OMIT_VALUE) result++;
6035 return result;
6036 default:
6037 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6038 } // switch
6039 }
6040 else if(t_val) {
6041 switch(t_val->get_valuetype()) {
6042 case V_SEQOF:
6043 case V_SETOF:
6044 case V_ARRAY:
6045
6046 case V_OID:
6047 case V_ROID:
6048 result=t_val->get_nof_comps();
6049 break;
6050 case V_SEQ:
6051 case V_SET:
6052 result=0;
6053 for(size_t i=0; i<t_val->get_nof_comps(); i++)
6054 if(t_val->get_se_comp_byIndex(i)->get_value()
6055 ->get_valuetype()!=V_OMIT) result++;
6056 break;
6057
6058 default:
6059 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6060 } // switch
6061 }
6062
6063 return result;
6064 error:
6065 set_valuetype(V_ERROR);
6066 return -1;
6067 }
6068
6069 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
6070 {
6071 Type *governor = ti->get_expr_governor(exp_val);
6072 if (!governor) {
6073 ti->get_Template()->set_lowerid_to_ref();
6074 governor = ti->get_expr_governor(exp_val);
6075 }
6076 if (!governor) {
6077 string str;
6078 ti->append_stringRepr( str);
6079 ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6080 "If type is known, use valueof(<type>: %s) as argument.",
6081 str.c_str(), get_opname(), str.c_str());
6082 set_valuetype(V_ERROR);
6083 }
6084 return governor;
6085 }
6086
6087 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
6088 {
6089 start:
6090 Type *governor = u.expr.v1->get_expr_governor(exp_val);
6091 if (!governor) governor = u.expr.t2->get_expr_governor(
6092 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
6093 Type::EXPECTED_TEMPLATE : exp_val);
6094 if (!governor) {
6095 Template *t_temp = u.expr.t2->get_Template();
6096 if (t_temp->is_undef_lowerid()) {
6097 // We convert the template to reference first even if the value is also
6098 // an undef lowerid. The user can prevent this by explicit type
6099 // specification.
6100 t_temp->set_lowerid_to_ref();
6101 goto start;
6102 } else if (u.expr.v1->is_undef_lowerid()) {
6103 u.expr.v1->set_lowerid_to_ref();
6104 goto start;
6105 }
6106 }
6107 if (!governor) {
6108 error("Cannot determine the type of arguments in `match()' operation");
6109 set_valuetype(V_ERROR);
6110 return;
6111 }
6112 u.expr.v1->set_my_governor(governor);
6113 {
6114 Error_Context cntxt(this, "In the first argument of `match()'"
6115 " operation");
6116 governor->chk_this_value_ref(u.expr.v1);
6117 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
6118 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6119 }
6120 {
6121 Error_Context cntxt(this, "In the second argument of `match()' "
6122 "operation");
6123 u.expr.t2->chk(governor);
6124 }
6125 }
6126
6127 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
6128 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
6129 {
6130 Ttcn::StatementBlock *my_sb;
6131 switch (exp_val) {
6132 case Type::EXPECTED_CONSTANT:
6133 error("An evaluable constant value was expected instead of operation "
6134 "`%s'", get_opname());
6135 goto error;
6136 case Type::EXPECTED_STATIC_VALUE:
6137 error("A static value was expected instead of operation `%s'",
6138 get_opname());
6139 goto error;
6140 default:
6141 break;
6142 } // switch
6143 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6144 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
6145 if (!my_sb) {
6146 error("Operation `%s' is allowed only within statements",
6147 get_opname());
6148 goto error;
6149 }
6150 if (!allow_controlpart && !my_sb->get_my_def()) {
6151 error("Operation `%s' is not allowed in the control part",
6152 get_opname());
6153 goto error;
6154 }
6155 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6156 error("Operation `%s' cannot be used in a definition that has "
6157 "`runs on' clause", get_opname());
6158 goto error;
6159 }
6160 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6161 error("Operation `%s' can be used only in a definition that has "
6162 "`runs on' clause", get_opname());
6163 goto error;
6164 }
6165 return;
6166 error:
6167 set_valuetype(V_ERROR);
6168 }
6169
6170 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6171 {
6172 if(valuetype==V_ERROR) return;
6173 if(u.expr.state==EXPR_CHECKING_ERR) return;
6174 if(v->is_unfoldable()) return;
6175 if(v->get_expr_returntype()!=Type::T_REAL) return;
6176 ttcn3float r = v->get_val_Real();
6177 if (isSpecialFloatValue(r)) {
6178 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6179 opnum, opname, Real2string(r).c_str());
6180 set_valuetype(V_ERROR);
6181 }
6182 }
6183
6184 void Value::chk_expr_operands(ReferenceChain *refch,
6185 Type::expected_value_t exp_val)
6186 {
6187 const char *first="First", *second="Second", *third="Third",
6188 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6189 Value *v1, *v2, *v3;
6190 Type::typetype_t tt1, tt2, tt3;
6191 Type t_chk(Type::T_ERROR);
6192
6193 const char *opname=get_opname();
6194
6195 // first classify the unchecked ischosen() operation
6196 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6197
6198 switch (u.expr.v_optype) {
6199 case OPTYPE_COMP_NULL:
6200 case OPTYPE_TESTCASENAME:
6201 case OPTYPE_PROF_RUNNING:
6202 break;
6203 case OPTYPE_COMP_MTC:
6204 case OPTYPE_COMP_SYSTEM:
6205 chk_expr_comptype_compat();
6206 break;
6207 case OPTYPE_RND: // -
6208 case OPTYPE_TMR_RUNNING_ANY:
6209 chk_expr_dynamic_part(exp_val, true);
6210 break;
6211 case OPTYPE_COMP_RUNNING_ANY:
6212 case OPTYPE_COMP_RUNNING_ALL:
6213 case OPTYPE_COMP_ALIVE_ANY:
6214 case OPTYPE_COMP_ALIVE_ALL:
6215 case OPTYPE_GETVERDICT:
6216 chk_expr_dynamic_part(exp_val, false);
6217 break;
6218 case OPTYPE_COMP_SELF:
6219 chk_expr_comptype_compat();
6220 chk_expr_dynamic_part(exp_val, false, true, false);
6221 break;
6222 case OPTYPE_UNARYPLUS: // v1
6223 case OPTYPE_UNARYMINUS:
6224 v1=u.expr.v1;
6225 {
6226 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6227 v1->set_lowerid_to_ref();
6228 tt1=v1->get_expr_returntype(exp_val);
6229 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6230 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6231 }
6232 break;
6233 case OPTYPE_NOT:
6234 v1=u.expr.v1;
6235 {
6236 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6237 v1->set_lowerid_to_ref();
6238 tt1=v1->get_expr_returntype(exp_val);
6239 chk_expr_operandtype_bool(tt1, the, opname, v1);
6240 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6241 }
6242 break;
6243 case OPTYPE_NOT4B:
6244 v1=u.expr.v1;
6245 {
6246 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6247 v1->set_lowerid_to_ref();
6248 tt1=v1->get_expr_returntype(exp_val);
6249 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6250 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6251 }
6252 break;
6253 case OPTYPE_BIT2HEX:
6254 case OPTYPE_BIT2OCT:
6255 case OPTYPE_BIT2STR:
6256 v1=u.expr.v1;
6257 {
6258 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6259 v1->set_lowerid_to_ref();
6260 tt1=v1->get_expr_returntype(exp_val);
6261 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6262 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6263 }
6264 break;
6265 case OPTYPE_BIT2INT:
6266 v1=u.expr.v1;
6267 {
6268 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6269 v1->set_lowerid_to_ref();
6270 tt1=v1->get_expr_returntype(exp_val);
6271 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6272 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6273 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6274 }
6275 break;
6276 case OPTYPE_CHAR2INT:
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_cstr(tt1, the, opname, v1);
6283 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6284 chk_expr_val_len1(v1, the, opname);
6285 }
6286 break;
6287 case OPTYPE_CHAR2OCT:
6288 v1=u.expr.v1;
6289 {
6290 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6291 v1->set_lowerid_to_ref();
6292 tt1=v1->get_expr_returntype(exp_val);
6293 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6294 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6295 }
6296 break;
6297 case OPTYPE_STR2INT:
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_cstr(tt1, the, opname, v1);
6304 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6305 chk_expr_val_str_int(v1, the, opname);
6306 }
6307 break;
6308 case OPTYPE_STR2FLOAT:
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_cstr(tt1, the, opname, v1);
6315 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6316 chk_expr_val_str_float(v1, the, opname);
6317 }
6318 break;
6319 case OPTYPE_STR2BIT:
6320 v1=u.expr.v1;
6321 {
6322 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6323 v1->set_lowerid_to_ref();
6324 tt1=v1->get_expr_returntype(exp_val);
6325 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6326 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6327 chk_expr_val_str_bindigits(v1, the, opname);
6328 }
6329 break;
6330 case OPTYPE_STR2HEX:
6331 v1=u.expr.v1;
6332 {
6333 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6334 v1->set_lowerid_to_ref();
6335 tt1=v1->get_expr_returntype(exp_val);
6336 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6337 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6338 chk_expr_val_str_hexdigits(v1, the, opname);
6339 }
6340 break;
6341 case OPTYPE_STR2OCT:
6342 v1=u.expr.v1;
6343 {
6344 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6345 v1->set_lowerid_to_ref();
6346 tt1=v1->get_expr_returntype(exp_val);
6347 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6348 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6349 chk_expr_val_str_len_even(v1, the, opname);
6350 chk_expr_val_str_hexdigits(v1, the, opname);
6351 }
6352 break;
6353 case OPTYPE_ENUM2INT:
6354 v1=u.expr.v1;
6355 {
6356 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6357 chk_expr_operandtype_enum(opname, v1, exp_val);
6358 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6359 }
6360 break;
6361 case OPTYPE_ENCODE:
6362 chk_expr_operand_encode(refch, exp_val);
6363 break;
6364 case OPTYPE_FLOAT2INT:
6365 case OPTYPE_FLOAT2STR:
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_float(tt1, the, opname, v1);
6372 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6373 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6374 chk_expr_operand_valid_float(v1, the, opname);
6375 }
6376 break;
6377 case OPTYPE_RNDWITHVAL:
6378 v1=u.expr.v1;
6379 {
6380 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6381 v1->set_lowerid_to_ref();
6382 tt1=v1->get_expr_returntype(exp_val);
6383 chk_expr_operandtype_float(tt1, the, opname, v1);
6384 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6385 chk_expr_operand_valid_float(v1, the, opname);
6386 }
6387 chk_expr_dynamic_part(exp_val, true);
6388 break;
6389 case OPTYPE_HEX2BIT:
6390 case OPTYPE_HEX2OCT:
6391 case OPTYPE_HEX2STR:
6392 v1=u.expr.v1;
6393 {
6394 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6395 v1->set_lowerid_to_ref();
6396 tt1=v1->get_expr_returntype(exp_val);
6397 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6398 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6399 }
6400 break;
6401 case OPTYPE_HEX2INT:
6402 v1=u.expr.v1;
6403 {
6404 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6405 v1->set_lowerid_to_ref();
6406 tt1=v1->get_expr_returntype(exp_val);
6407 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6408 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6409 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6410 }
6411 break;
6412 case OPTYPE_INT2CHAR:
6413 v1=u.expr.v1;
6414 {
6415 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6416 v1->set_lowerid_to_ref();
6417 tt1=v1->get_expr_returntype(exp_val);
6418 chk_expr_operandtype_int(tt1, the, opname, v1);
6419 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6420 chk_expr_val_int_pos7bit(v1, the, opname);
6421 }
6422 break;
6423 case OPTYPE_INT2UNICHAR:
6424 v1=u.expr.v1;
6425 {
6426 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6427 v1->set_lowerid_to_ref();
6428 tt1=v1->get_expr_returntype(exp_val);
6429 chk_expr_operandtype_int(tt1, the, opname, v1);
6430 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6431 chk_expr_val_int_pos31bit(v1, first, opname);
6432 }
6433 break;
6434 case OPTYPE_INT2FLOAT:
6435 case OPTYPE_INT2STR:
6436 v1=u.expr.v1;
6437 {
6438 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6439 v1->set_lowerid_to_ref();
6440 tt1=v1->get_expr_returntype(exp_val);
6441 chk_expr_operandtype_int(tt1, the, opname, v1);
6442 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6443 }
6444 break;
6445 case OPTYPE_OCT2BIT:
6446 case OPTYPE_OCT2HEX:
6447 case OPTYPE_OCT2STR:
6448 v1=u.expr.v1;
6449 {
6450 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6451 v1->set_lowerid_to_ref();
6452 tt1=v1->get_expr_returntype(exp_val);
6453 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6454 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6455 }
6456 break;
6457 case OPTYPE_OCT2INT:
6458 v1=u.expr.v1;
6459 {
6460 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6461 v1->set_lowerid_to_ref();
6462 tt1=v1->get_expr_returntype(exp_val);
6463 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6464 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6465 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6466 // now.
6467 }
6468 break;
6469 case OPTYPE_OCT2CHAR:
6470 v1=u.expr.v1;
6471 {
6472 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6473 v1->set_lowerid_to_ref();
6474 tt1=v1->get_expr_returntype(exp_val);
6475 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6476 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6477 chk_expr_val_str_7bitoctets(v1, the, opname);
6478 }
6479 break;
6480 case OPTYPE_REMOVE_BOM:
6481 v1=u.expr.v1;
6482 {
6483 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6484 v1->set_lowerid_to_ref();
6485 tt1=v1->get_expr_returntype(exp_val);
6486 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6487 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6488 }
6489 break;
6490 case OPTYPE_GET_STRINGENCODING:
6491 v1=u.expr.v1;
6492 {
6493 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6494 v1->set_lowerid_to_ref();
6495 tt1=v1->get_expr_returntype(exp_val);
6496 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6497 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6498 }
6499 break;
6500 case OPTYPE_ENCODE_BASE64:
6501 v1=u.expr.v1;
6502 {
6503 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6504 v1->set_lowerid_to_ref();
6505 tt1=v1->get_expr_returntype(exp_val);
6506 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6507 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6508 }
6509 v2=u.expr.v2 ? u.expr.v2 : 0;
6510 if (v2)
6511 {
6512 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6513 v2->set_lowerid_to_ref();
6514 tt2=v2->get_expr_returntype(exp_val);
6515 chk_expr_operandtype_bool(tt2, second, opname, v2);
6516 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6517 }
6518 break;
6519 case OPTYPE_DECODE_BASE64:
6520 v1=u.expr.v1;
6521 {
6522 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6523 v1->set_lowerid_to_ref();
6524 tt1=v1->get_expr_returntype(exp_val);
6525 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6526 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6527 }
6528 break;
6529 case OPTYPE_UNICHAR2INT:
6530 v1=u.expr.v1;
6531 {
6532 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6533 v1->set_lowerid_to_ref();
6534 tt1=v1->get_expr_returntype(exp_val);
6535 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6536 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6537 chk_expr_val_len1(v1, the, opname);
6538 }
6539 break;
6540 case OPTYPE_UNICHAR2CHAR:
6541 v1=u.expr.v1;
6542 {
6543 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6544 v1->set_lowerid_to_ref();
6545 tt1=v1->get_expr_returntype(exp_val);
6546 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6547 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6548 chk_expr_val_ustr_7bitchars(v1, the, opname);
6549 }
6550 break;
6551 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6552 v1=u.expr.v1;
6553 {
6554 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6555 v1->set_lowerid_to_ref();
6556 tt1=v1->get_expr_returntype(exp_val);
6557 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6558 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6559 }
6560 v2=u.expr.v2 ? u.expr.v2 : 0;
6561 if (v2)
6562 {
6563 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6564 v2->set_lowerid_to_ref();
6565 tt2=v2->get_expr_returntype(exp_val);
6566 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6567 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6568 }
6569 break;
6570 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6571 v1=u.expr.v1;
6572 {
6573 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6574 v1->set_lowerid_to_ref();
6575 tt1=v1->get_expr_returntype(exp_val);
6576 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6577 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6578 }
6579 v2=u.expr.v2 ? u.expr.v2 : 0;
6580 if (v2)
6581 {
6582 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6583 v2->set_lowerid_to_ref();
6584 tt2=v2->get_expr_returntype(exp_val);
6585 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6586 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6587 }
6588 break;
6589 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
6590 chk_expr_operand_encode(refch, exp_val);
6591 v2=u.expr.v2 ? u.expr.v2 : 0;
6592 if (v2)
6593 {
6594 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6595 v2->set_lowerid_to_ref();
6596 tt2=v2->get_expr_returntype(exp_val);
6597 chk_expr_operandtype_charstr(tt2, second, opname, v2);
6598 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6599 }
6600 break;
6601 case OPTYPE_DECVALUE_UNICHAR:
6602 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR);
6603 v3=u.expr.v3 ? u.expr.v3 : 0;
6604 if (v3)
6605 {
6606 Error_Context cntxt(this, "In the thrid operand of operation `%s'", opname);
6607 v3->set_lowerid_to_ref();
6608 tt3=v3->get_expr_returntype(exp_val);
6609 chk_expr_operandtype_charstr(tt3, third, opname, v3);
6610 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6611 }
6612 break;
6613 case OPTYPE_ADD: // v1 v2
6614 case OPTYPE_SUBTRACT:
6615 case OPTYPE_MULTIPLY:
6616 case OPTYPE_DIVIDE:
6617 v1=u.expr.v1;
6618 {
6619 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6620 v1->set_lowerid_to_ref();
6621 tt1=v1->get_expr_returntype(exp_val);
6622 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6623 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6624 chk_expr_operand_valid_float(v1, first, opname);
6625 }
6626 v2=u.expr.v2;
6627 {
6628 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6629 v2->set_lowerid_to_ref();
6630 tt2=v2->get_expr_returntype(exp_val);
6631 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6632 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6633 chk_expr_operand_valid_float(v2, second, opname);
6634 if(u.expr.v_optype==OPTYPE_DIVIDE)
6635 chk_expr_val_int_float_not0(v2, second, opname);
6636 }
6637 chk_expr_operandtypes_same(tt1, tt2, opname);
6638 break;
6639 case OPTYPE_MOD:
6640 case OPTYPE_REM:
6641 v1=u.expr.v1;
6642 {
6643 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6644 v1->set_lowerid_to_ref();
6645 tt1=v1->get_expr_returntype(exp_val);
6646 chk_expr_operandtype_int(tt1, left, opname, v1);
6647 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6648 }
6649 v2=u.expr.v2;
6650 {
6651 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6652 v2->set_lowerid_to_ref();
6653 tt2=v2->get_expr_returntype(exp_val);
6654 chk_expr_operandtype_int(tt2, right, opname, v2);
6655 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6656 chk_expr_val_int_float_not0(v2, right, opname);
6657 }
6658 break;
6659 case OPTYPE_CONCAT: {
6660 v1=u.expr.v1;
6661 v2=u.expr.v2;
6662 v1->set_lowerid_to_ref();
6663 v2->set_lowerid_to_ref();
6664 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6665 {
6666 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6667 tt1=v1->get_expr_returntype(exp_val);
6668 chk_expr_operandtype_str(tt1, left, opname, v1);
6669 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6670 }
6671 {
6672 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6673 tt2=v2->get_expr_returntype(exp_val);
6674 chk_expr_operandtype_str(tt2, right, opname, v2);
6675 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6676 }
6677 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6678 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6679 chk_expr_operandtypes_same(tt1, tt2, opname);
6680 } else { // other list types
6681 Type* v1_gov = v1->get_expr_governor(exp_val);
6682 Type* v2_gov = v2->get_expr_governor(exp_val);
6683 if (!v1_gov) {
6684 error("Cannot determine the type of the left operand of `%s' operation", opname);
6685 set_valuetype(V_ERROR);
6686 return;
6687 } else {
6688 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6689 v1_gov->chk_this_value_ref(v1);
6690 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6691 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6692 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6693 }
6694 if (!v2_gov) {
6695 if (!v1_gov) {
6696 error("Cannot determine the type of the right operand of `%s' operation", opname);
6697 set_valuetype(V_ERROR);
6698 return;
6699 }
6700 // for recof/setof literals set the type from v1
6701 v2_gov = v1_gov;
6702 v2->set_my_governor(v1_gov);
6703 }
6704 {
6705 Error_Context cntxt(this, "In the right operand of operation `%s'",
6706 opname);
6707 v2_gov->chk_this_value_ref(v2);
6708 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6709 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6710 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6711 if (valuetype == V_ERROR) return;
6712 // 7.1.2 says that we shouldn't allow type compatibility.
6713 if (!v1_gov->is_compatible(v2_gov, NULL)
6714 && !v2_gov->is_compatible(v1_gov, NULL)) {
6715 error("The operands of operation `%s' should be of compatible "
6716 "types", get_opname());
6717 }
6718 }
6719 }
6720 break; }
6721 case OPTYPE_EQ:
6722 case OPTYPE_NE:
6723 v1 = u.expr.v1;
6724 v2 = u.expr.v2;
6725 chk_expr_operandtypes_compat(exp_val, v1, v2);
6726 {
6727 Error_Context cntxt(this, "In the left operand of operation `%s'",
6728 opname);
6729 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6730 }
6731 {
6732 Error_Context cntxt(this, "In the right operand of operation `%s'",
6733 opname);
6734 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6735 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6736 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6737 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6738 * "a == not b" is not allowed. (HL69107)
6739 * The various *Expressions implement operator precedence in the std.
6740 * Titan's parser has only one Expression and relies on Bison
6741 * for operator precedence. The check below brings Titan in line
6742 * with the standard by explicitly making "a == not b" an error */
6743 if (v2->get_valuetype() == V_EXPR
6744 && v2->u.expr.v_optype == OPTYPE_NOT) {
6745 error("The operation `%s' is not allowed to be "
6746 "the second operand of operation `%s'", v2->get_opname(), opname);
6747 set_valuetype(V_ERROR);
6748 }
6749 }
6750 break;
6751 case OPTYPE_LT:
6752 case OPTYPE_GT:
6753 case OPTYPE_GE:
6754 case OPTYPE_LE:
6755 v1=u.expr.v1;
6756 v2=u.expr.v2;
6757 chk_expr_operandtypes_compat(exp_val, v1, v2);
6758 {
6759 Error_Context cntxt(this, "In the left operand of operation `%s'",
6760 opname);
6761 tt1=v1->get_expr_returntype(exp_val);
6762 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6763 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6764 }
6765 {
6766 Error_Context cntxt(this, "In the right operand of operation `%s'",
6767 opname);
6768 tt2=v2->get_expr_returntype(exp_val);
6769 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6770 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6771 }
6772 break;
6773 case OPTYPE_AND:
6774 case OPTYPE_OR:
6775 case OPTYPE_XOR:
6776 v1=u.expr.v1;
6777 {
6778 Error_Context cntxt(this, "In the left operand of operation `%s'",
6779 opname);
6780 v1->set_lowerid_to_ref();
6781 tt1=v1->get_expr_returntype(exp_val);
6782 chk_expr_operandtype_bool(tt1, left, opname, v1);
6783 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6784 }
6785 v2=u.expr.v2;
6786 {
6787 Error_Context cntxt(this, "In the right operand of operation `%s'",
6788 opname);
6789 v2->set_lowerid_to_ref();
6790 tt2=v2->get_expr_returntype(exp_val);
6791 chk_expr_operandtype_bool(tt2, right, opname, v2);
6792 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6793 }
6794 break;
6795 case OPTYPE_AND4B:
6796 case OPTYPE_OR4B:
6797 case OPTYPE_XOR4B:
6798 v1=u.expr.v1;
6799 {
6800 Error_Context cntxt(this, "In the left operand of operation `%s'",
6801 opname);
6802 v1->set_lowerid_to_ref();
6803 tt1=v1->get_expr_returntype(exp_val);
6804 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6805 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6806 }
6807 v2=u.expr.v2;
6808 {
6809 Error_Context cntxt(this, "In the right operand of operation `%s'",
6810 opname);
6811 v2->set_lowerid_to_ref();
6812 tt2=v2->get_expr_returntype(exp_val);
6813 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6814 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6815 }
6816 chk_expr_operandtypes_same(tt1, tt2, opname);
6817 chk_expr_operands_str_samelen();
6818 break;
6819 case OPTYPE_SHL:
6820 case OPTYPE_SHR:
6821 v1=u.expr.v1;
6822 {
6823 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6824 v1->set_lowerid_to_ref();
6825 tt1=v1->get_expr_returntype(exp_val);
6826 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6827 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6828 }
6829 v2=u.expr.v2;
6830 {
6831 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6832 v2->set_lowerid_to_ref();
6833 tt2=v2->get_expr_returntype(exp_val);
6834 chk_expr_operandtype_int(tt2, right, opname, v2);
6835 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6836 chk_expr_val_large_int(v2, right, opname);
6837 }
6838 break;
6839 case OPTYPE_ROTL:
6840 case OPTYPE_ROTR:
6841 v1=u.expr.v1;
6842 v1->set_lowerid_to_ref();
6843 if (v1->is_string_type(exp_val)) {
6844 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6845 tt1=v1->get_expr_returntype(exp_val);
6846 chk_expr_operandtype_str(tt1, left, opname, v1);
6847 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6848 } else { // other list types
6849 Type* v1_gov = v1->get_expr_governor(exp_val);
6850 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6851 error("Cannot determine the type of the left operand of `%s' operation", opname);
6852 } else {
6853 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6854 v1_gov->chk_this_value_ref(v1);
6855 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6856 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6857 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6858 }
6859 }
6860 v2=u.expr.v2;
6861 {
6862 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6863 v2->set_lowerid_to_ref();
6864 tt2=v2->get_expr_returntype(exp_val);
6865 chk_expr_operandtype_int(tt2, right, opname, v2);
6866 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6867 chk_expr_val_large_int(v2, right, opname);
6868 }
6869 break;
6870 case OPTYPE_INT2BIT:
6871 case OPTYPE_INT2HEX:
6872 case OPTYPE_INT2OCT:
6873 v1=u.expr.v1;
6874 {
6875 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6876 v1->set_lowerid_to_ref();
6877 tt1=v1->get_expr_returntype(exp_val);
6878 chk_expr_operandtype_int(tt1, first, opname, v1);
6879 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6880 chk_expr_val_int_pos0(v1, first, opname);
6881 }
6882 v2=u.expr.v2;
6883 {
6884 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6885 v2->set_lowerid_to_ref();
6886 tt2=v2->get_expr_returntype(exp_val);
6887 chk_expr_operandtype_int(tt2, second, opname, v2);
6888 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6889 chk_expr_val_int_pos0(v2, second, opname);
6890 }
6891 chk_expr_operands_int2binstr();
6892 break;
6893 case OPTYPE_DECODE:
6894 chk_expr_operands_decode(OPTYPE_DECODE);
6895 break;
6896 case OPTYPE_SUBSTR:
6897 {
6898 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6899 Type::expected_value_t ti_exp_val = exp_val;
6900 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6901 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6902 if (!governor) return;
6903 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6904 if (valuetype!=V_ERROR)
6905 u.expr.ti1->get_Template()->chk_specific_value(false);
6906 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6907 }
6908 v2=u.expr.v2;
6909 {
6910 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6911 v2->set_lowerid_to_ref();
6912 tt2=v2->get_expr_returntype(exp_val);
6913 chk_expr_operandtype_int(tt2, second, opname, v2);
6914 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6915 chk_expr_val_int_pos0(v2, second, opname);
6916 }
6917 v3=u.expr.v3;
6918 {
6919 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6920 v3->set_lowerid_to_ref();
6921 tt3=v3->get_expr_returntype(exp_val);
6922 chk_expr_operandtype_int(tt3, third, opname, v3);
6923 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6924 chk_expr_val_int_pos0(v3, third, opname);
6925 }
6926 chk_expr_operands_substr();
6927 break;
6928 case OPTYPE_REGEXP: {
6929 Type::expected_value_t ti_exp_val = exp_val;
6930 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6931 {
6932 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6933 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6934 if (!governor) return;
6935 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6936 if (valuetype!=V_ERROR) {
6937 u.expr.ti1->get_Template()->chk_specific_value(false);
6938 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6939 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6940 }
6941 }
6942 {
6943 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6944 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6945 if (!governor) return;
6946 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6947 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6948 get_typetype_ttcn3(), second, opname, u.expr.t2);
6949 }
6950 v3=u.expr.v3;
6951 {
6952 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6953 v3->set_lowerid_to_ref();
6954 tt3=v3->get_expr_returntype(exp_val);
6955 chk_expr_operandtype_int(tt3, third, opname, v3);
6956 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6957 chk_expr_val_int_pos0(v3, third, opname);
6958 }
6959 chk_expr_operands_regexp();
6960 } break;
6961 case OPTYPE_ISCHOSEN:
6962 // do nothing: the operand is erroneous
6963 // the error was already reported in chk_expr_ref_ischosen()
6964 break;
6965 case OPTYPE_ISCHOSEN_V: // v1 i2
6966 case OPTYPE_ISCHOSEN_T: // t1 i2
6967 chk_expr_operands_ischosen(refch, exp_val);
6968 break;
6969 case OPTYPE_VALUEOF: { // ti1
6970 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6971 exp_val = Type::EXPECTED_TEMPLATE;
6972 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6973 Type *governor = my_governor;
6974 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6975 if (!governor) return;
6976 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6977 if (valuetype == V_ERROR) return;
6978 u.expr.ti1->get_Template()->chk_specific_value(false);
6979 break; }
6980 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6981 case OPTYPE_ISBOUND: {
6982 Template *templ = u.expr.ti1->get_Template();
6983 switch (templ->get_templatetype()) {
6984 case Template::TEMPLATE_REFD:
6985 templ->get_reference()->setUsedInIsbound();
6986 break;
6987 case Template::SPECIFIC_VALUE: {
6988 Value *value = templ->get_specific_value();
6989 if (Value::V_REFD == value->get_valuetype()) {
6990 value->get_reference()->setUsedInIsbound();
6991 }
6992 break; }
6993 default:
6994 break;
6995 }
6996 }
6997 // no break
6998 case OPTYPE_ISVALUE: {// ti1
6999 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
7000 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7001 exp_val = Type::EXPECTED_TEMPLATE;
7002 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7003 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7004 if (!governor) return;
7005 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
7006 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7007 break; }
7008 case OPTYPE_SIZEOF: // ti1
7009 /* this checking is too complex, do the checking during eval... */
7010 break;
7011 case OPTYPE_LENGTHOF: { // ti1
7012 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7013 exp_val = Type::EXPECTED_TEMPLATE;
7014 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7015 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7016 if (!governor) return;
7017 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
7018 if (valuetype == V_ERROR) return;
7019 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7020 break; }
7021 case OPTYPE_MATCH: // v1 t2
7022 chk_expr_operands_match(exp_val);
7023 break;
7024 case OPTYPE_UNDEF_RUNNING: // r1
7025 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
7026 break;
7027 case OPTYPE_COMP_ALIVE:
7028 case OPTYPE_COMP_RUNNING: //v1
7029 chk_expr_operand_compref(u.expr.v1, the, opname);
7030 chk_expr_dynamic_part(exp_val, false);
7031 break;
7032 case OPTYPE_TMR_READ: // r1
7033 case OPTYPE_TMR_RUNNING: // r1
7034 chk_expr_operand_tmrref(u.expr.r1, the, opname);
7035 chk_expr_dynamic_part(exp_val, true);
7036 break;
7037 case OPTYPE_EXECUTE: // r1 [v2] // testcase
7038 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
7039 chk_expr_dynamic_part(exp_val, true, false, false);
7040 break;
7041 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7042 chk_expr_operand_comptyperef_create();
7043 v2=u.expr.v2;
7044 if(v2) {
7045 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7046 v2->set_lowerid_to_ref();
7047 tt2=v2->get_expr_returntype(exp_val);
7048 chk_expr_operandtype_cstr(tt2, first, opname, v2);
7049 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7050 }
7051 v3=u.expr.v3;
7052 if(v3) {
7053 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
7054 v3->set_lowerid_to_ref();
7055 tt3=v3->get_expr_returntype(exp_val);
7056 chk_expr_operandtype_cstr(tt3, second, opname, v3);
7057 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7058 }
7059 chk_expr_dynamic_part(exp_val, false);
7060 break;
7061 case OPTYPE_ACTIVATE: // r1 // altstep
7062 chk_expr_operand_activate(u.expr.r1, the, opname);
7063 chk_expr_dynamic_part(exp_val, true);
7064 break;
7065 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
7066 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7067 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
7068 opname);
7069 delete u.expr.t_list2;
7070 u.expr.ap_list2 = parlist;
7071 chk_expr_dynamic_part(exp_val, true);
7072 break; }
7073 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
7074 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7075 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
7076 u.expr.v3, the, opname);
7077 delete u.expr.t_list2;
7078 u.expr.ap_list2 = parlist;
7079 chk_expr_dynamic_part(exp_val, true);
7080 break; }
7081 case OPTYPE_DECOMP:
7082 error("Built-in function `%s' is not yet supported", opname);
7083 set_valuetype(V_ERROR);
7084 break;
7085 case OPTYPE_REPLACE: {
7086 Type::expected_value_t ti_exp_val = exp_val;
7087 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7088 ti_exp_val = Type::EXPECTED_TEMPLATE;
7089 {
7090 Error_Context cntxt(this, "In the first operand of operation `%s'",
7091 opname);
7092 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7093 if (!governor) return;
7094 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7095 if (valuetype != V_ERROR)
7096 u.expr.ti1->get_Template()->chk_specific_value(false);
7097 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
7098 }
7099 v2 = u.expr.v2;
7100 {
7101 Error_Context cntxt(this, "In the second operand of operation `%s'",
7102 opname);
7103 v2->set_lowerid_to_ref();
7104 tt2 = v2->get_expr_returntype(exp_val);
7105 chk_expr_operandtype_int(tt2, second, opname, v2);
7106 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7107 chk_expr_val_int_pos0(v2, second, opname);
7108 }
7109 v3 = u.expr.v3;
7110 {
7111 Error_Context cntxt(this, "In the third operand of operation `%s'",
7112 opname);
7113 v3->set_lowerid_to_ref();
7114 tt3 = v3->get_expr_returntype(exp_val);
7115 chk_expr_operandtype_int(tt3, third, opname, v3);
7116 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7117 chk_expr_val_int_pos0(v3, third, opname);
7118 }
7119 {
7120 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
7121 opname);
7122 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
7123 if (!governor) return;
7124 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
7125 if (valuetype != V_ERROR)
7126 u.expr.ti4->get_Template()->chk_specific_value(false);
7127 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
7128 }
7129 chk_expr_operands_replace();
7130 break; }
7131 case OPTYPE_LOG2STR:
7132 case OPTYPE_ANY2UNISTR: {
7133 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7134 u.expr.logargs->chk();
7135 if (!semantic_check_only) u.expr.logargs->join_strings();
7136 break; }
7137 case OPTYPE_TTCN2STRING: {
7138 Error_Context cntxt(this, "In the parameter of ttcn2string()");
7139 Type::expected_value_t ti_exp_val = exp_val;
7140 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
7141 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7142 if (!governor) return;
7143 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7144 } break;
7145 default:
7146 FATAL_ERROR("chk_expr_operands()");
7147 } // switch optype
7148 }
7149
7150 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7151 // the result of evaluating the expression. E.g. V_BOOL for
7152 // OPTYPE_ISCHOSEN.
7153 void Value::evaluate_value(ReferenceChain *refch,
7154 Type::expected_value_t exp_val)
7155 {
7156 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
7157 if(u.expr.state!=EXPR_NOT_CHECKED) return;
7158
7159 u.expr.state=EXPR_CHECKING;
7160
7161 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
7162 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
7163 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
7164
7165 if(valuetype==V_ERROR) return;
7166 if(u.expr.state==EXPR_CHECKING_ERR) {
7167 u.expr.state=EXPR_CHECKED;
7168 set_valuetype(V_ERROR);
7169 return;
7170 }
7171
7172 u.expr.state=EXPR_CHECKED;
7173
7174 Value *v1, *v2, *v3, *v4;
7175 switch(u.expr.v_optype) {
7176 case OPTYPE_RND: // -
7177 case OPTYPE_COMP_NULL: // the only foldable in this group
7178 case OPTYPE_COMP_MTC:
7179 case OPTYPE_COMP_SYSTEM:
7180 case OPTYPE_COMP_SELF:
7181 case OPTYPE_COMP_RUNNING_ANY:
7182 case OPTYPE_COMP_RUNNING_ALL:
7183 case OPTYPE_COMP_ALIVE_ANY:
7184 case OPTYPE_COMP_ALIVE_ALL:
7185 case OPTYPE_TMR_RUNNING_ANY:
7186 case OPTYPE_GETVERDICT:
7187 case OPTYPE_PROF_RUNNING:
7188 case OPTYPE_RNDWITHVAL: // v1
7189 case OPTYPE_COMP_RUNNING: // v1
7190 case OPTYPE_COMP_ALIVE:
7191 case OPTYPE_TMR_READ:
7192 case OPTYPE_TMR_RUNNING:
7193 case OPTYPE_ACTIVATE:
7194 case OPTYPE_ACTIVATE_REFD:
7195 case OPTYPE_EXECUTE: // r1 [v2]
7196 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7197 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7198 case OPTYPE_MATCH: // v1 t2
7199 case OPTYPE_ISCHOSEN_T:
7200 case OPTYPE_LOG2STR:
7201 case OPTYPE_ANY2UNISTR:
7202 case OPTYPE_ENCODE:
7203 case OPTYPE_DECODE:
7204 case OPTYPE_ISBOUND:
7205 case OPTYPE_ISPRESENT:
7206 case OPTYPE_TTCN2STRING:
7207 case OPTYPE_UNICHAR2OCT:
7208 case OPTYPE_OCT2UNICHAR:
7209 case OPTYPE_ENCODE_BASE64:
7210 case OPTYPE_DECODE_BASE64:
7211 case OPTYPE_ENCVALUE_UNICHAR:
7212 case OPTYPE_DECVALUE_UNICHAR:
7213 break;
7214 case OPTYPE_TESTCASENAME: { // -
7215 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7216 Ttcn::StatementBlock *my_sb =
7217 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7218 if (!my_sb) break;
7219 Ttcn::Definition *my_def = my_sb->get_my_def();
7220 if (!my_def) { // In control part.
7221 set_val_str(new string(""));
7222 valuetype = V_CSTR;
7223 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7224 set_val_str(new string(my_def->get_id().get_dispname()));
7225 valuetype = V_CSTR;
7226 }
7227 break; }
7228 case OPTYPE_UNARYPLUS: // v1
7229 v1=u.expr.v1;
7230 u.expr.v1=0;
7231 copy_and_destroy(v1);
7232 break;
7233 case OPTYPE_UNARYMINUS:
7234 if (is_unfoldable()) break;
7235 v1 = u.expr.v1->get_value_refd_last();
7236 switch (v1->valuetype) {
7237 case V_INT: {
7238 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7239 if (!i) FATAL_ERROR("Value::evaluate_value()");
7240 clean_up();
7241 valuetype = V_INT;
7242 u.val_Int = i;
7243 break; }
7244 case V_REAL: {
7245 ttcn3float r = v1->get_val_Real();
7246 clean_up();
7247 valuetype = V_REAL;
7248 u.val_Real = -r;
7249 break; }
7250 default:
7251 FATAL_ERROR("Value::evaluate_value()");
7252 }
7253 break;
7254 case OPTYPE_NOT: {
7255 if(is_unfoldable()) break;
7256 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7257 clean_up();
7258 valuetype=V_BOOL;
7259 u.val_bool=!b;
7260 break;}
7261 case OPTYPE_NOT4B: {
7262 if(is_unfoldable()) break;
7263 v1=u.expr.v1->get_value_refd_last();
7264 const string& s = v1->get_val_str();
7265 valuetype_t vt=v1->valuetype;
7266 clean_up();
7267 valuetype=vt;
7268 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7269 break;}
7270 case OPTYPE_BIT2HEX: {
7271 if(is_unfoldable()) break;
7272 v1=u.expr.v1->get_value_refd_last();
7273 const string& s = v1->get_val_str();
7274 clean_up();
7275 valuetype=V_HSTR;
7276 set_val_str(bit2hex(s));
7277 break;}
7278 case OPTYPE_BIT2OCT: {
7279 if(is_unfoldable()) break;
7280 v1=u.expr.v1->get_value_refd_last();
7281 const string& s = v1->get_val_str();
7282 clean_up();
7283 valuetype=V_OSTR;
7284 set_val_str(bit2oct(s));
7285 break;}
7286 case OPTYPE_BIT2STR:
7287 case OPTYPE_HEX2STR:
7288 case OPTYPE_OCT2STR: {
7289 if(is_unfoldable()) break;
7290 v1=u.expr.v1->get_value_refd_last();
7291 const string& s = v1->get_val_str();
7292 clean_up();
7293 valuetype=V_CSTR;
7294 set_val_str(new string(s));
7295 break;}
7296 case OPTYPE_BIT2INT: {
7297 if (is_unfoldable()) break;
7298 v1 = u.expr.v1->get_value_refd_last();
7299 const string& s = v1->get_val_str();
7300 clean_up();
7301 valuetype = V_INT;
7302 u.val_Int = bit2int(s);
7303 break; }
7304 case OPTYPE_CHAR2INT: {
7305 if (is_unfoldable()) break;
7306 v1 = u.expr.v1->get_value_refd_last();
7307 char c = v1->get_val_str()[0];
7308 clean_up();
7309 valuetype = V_INT;
7310 u.val_Int = new int_val_t((Int)c);
7311 break; }
7312 case OPTYPE_CHAR2OCT: {
7313 if(is_unfoldable()) break;
7314 v1=u.expr.v1->get_value_refd_last();
7315 const string& s = v1->get_val_str();
7316 clean_up();
7317 valuetype=V_OSTR;
7318 set_val_str(char2oct(s));
7319 break;}
7320 case OPTYPE_STR2INT: {
7321 if (is_unfoldable()) break;
7322 v1 = u.expr.v1->get_value_refd_last();
7323 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7324 clean_up();
7325 valuetype = V_INT;
7326 u.val_Int = i;
7327 /** \todo hiba eseten lenyeli... */
7328 break; }
7329 case OPTYPE_STR2FLOAT: {
7330 if(is_unfoldable()) break;
7331 v1=u.expr.v1->get_value_refd_last();
7332 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7333 clean_up();
7334 valuetype=V_REAL;
7335 u.val_Real=r;
7336 /** \todo hiba eseten lenyeli... */
7337 break;}
7338 case OPTYPE_STR2BIT: {
7339 if(is_unfoldable()) break;
7340 v1=u.expr.v1->get_value_refd_last();
7341 const string& s = v1->get_val_str();
7342 clean_up();
7343 valuetype=V_BSTR;
7344 set_val_str(new string(s));
7345 break;}
7346 case OPTYPE_STR2HEX:
7347 case OPTYPE_OCT2HEX: {
7348 if(is_unfoldable()) break;
7349 v1=u.expr.v1->get_value_refd_last();
7350 const string& s = v1->get_val_str();
7351 clean_up();
7352 valuetype=V_HSTR;
7353 set_val_str(to_uppercase(s));
7354 break;}
7355 case OPTYPE_STR2OCT: {
7356 if(is_unfoldable()) break;
7357 v1=u.expr.v1->get_value_refd_last();
7358 const string& s = v1->get_val_str();
7359 clean_up();
7360 valuetype=V_OSTR;
7361 set_val_str(to_uppercase(s));
7362 break;}
7363 case OPTYPE_FLOAT2INT: {
7364 if (is_unfoldable()) break;
7365 v1 = u.expr.v1->get_value_refd_last();
7366 ttcn3float r = v1->get_val_Real();
7367 clean_up();
7368 valuetype = V_INT;
7369 u.val_Int = float2int(r, *u.expr.v1);
7370 break;}
7371 case OPTYPE_FLOAT2STR: {
7372 if(is_unfoldable()) break;
7373 v1=u.expr.v1->get_value_refd_last();
7374 ttcn3float r=v1->get_val_Real();
7375 clean_up();
7376 valuetype=V_CSTR;
7377 set_val_str(float2str(r));
7378 break;}
7379 case OPTYPE_HEX2BIT:
7380 case OPTYPE_OCT2BIT: {
7381 if(is_unfoldable()) break;
7382 v1=u.expr.v1->get_value_refd_last();
7383 const string& s = v1->get_val_str();
7384 clean_up();
7385 valuetype=V_BSTR;
7386 set_val_str(hex2bit(s));
7387 break;}
7388 case OPTYPE_HEX2INT:
7389 case OPTYPE_OCT2INT: {
7390 if(is_unfoldable()) break;
7391 v1=u.expr.v1->get_value_refd_last();
7392 const string& s = v1->get_val_str();
7393 clean_up();
7394 valuetype=V_INT;
7395 u.val_Int=hex2int(s);
7396 break;}
7397 case OPTYPE_HEX2OCT: {
7398 if(is_unfoldable()) break;
7399 v1=u.expr.v1->get_value_refd_last();
7400 const string& s = v1->get_val_str();
7401 clean_up();
7402 valuetype=V_OSTR;
7403 set_val_str(hex2oct(s));
7404 break;}
7405 case OPTYPE_INT2CHAR: {
7406 if (is_unfoldable()) break;
7407 v1 = u.expr.v1->get_value_refd_last();
7408 const int_val_t *c_int = v1->get_val_Int();
7409 char c = static_cast<char>(c_int->get_val());
7410 clean_up();
7411 valuetype = V_CSTR;
7412 set_val_str(new string(1, &c));
7413 break; }
7414 case OPTYPE_INT2UNICHAR: {
7415 if (is_unfoldable()) break;
7416 v1 = u.expr.v1->get_value_refd_last();
7417 const int_val_t *i_int = v1->get_val_Int();
7418 Int i = i_int->get_val();
7419 clean_up();
7420 valuetype = V_USTR;
7421 set_val_ustr(int2unichar(i));
7422 u.ustr.convert_str = false;
7423 break; }
7424 case OPTYPE_INT2FLOAT: {
7425 if (is_unfoldable()) break;
7426 v1 = u.expr.v1->get_value_refd_last();
7427 const int_val_t *i_int = v1->get_val_Int();
7428 Real i_int_real = i_int->to_real();
7429 clean_up();
7430 valuetype = V_REAL;
7431 u.val_Real = i_int_real;
7432 break; }
7433 case OPTYPE_INT2STR: {
7434 if (is_unfoldable()) break;
7435 v1 = u.expr.v1->get_value_refd_last();
7436 const int_val_t *i_int = v1->get_val_Int();
7437 string *i_int_str = new string(i_int->t_str());
7438 clean_up();
7439 valuetype = V_CSTR;
7440 set_val_str(i_int_str);
7441 break; }
7442 case OPTYPE_OCT2CHAR: {
7443 if(is_unfoldable()) break;
7444 v1=u.expr.v1->get_value_refd_last();
7445 const string& s = v1->get_val_str();
7446 clean_up();
7447 valuetype=V_CSTR;
7448 set_val_str(oct2char(s));
7449 break;}
7450 case OPTYPE_GET_STRINGENCODING: {
7451 if(is_unfoldable()) break;
7452 v1 = u.expr.v1->get_value_refd_last();
7453 const string& s1 = v1->get_val_str();
7454 clean_up();
7455 valuetype = V_CSTR;
7456 set_val_str(get_stringencoding(s1));
7457 break;}
7458 case OPTYPE_REMOVE_BOM: {
7459 if(is_unfoldable()) break;
7460 v1 = u.expr.v1->get_value_refd_last();
7461 const string& s1 = v1->get_val_str();
7462 clean_up();
7463 valuetype = V_OSTR;
7464 set_val_str(remove_bom(s1));
7465 break;}
7466 case OPTYPE_ENUM2INT: {
7467 if(is_unfoldable()) break;
7468 v1=u.expr.v1->get_value_refd_last();
7469 Type* enum_type = v1->get_my_governor();
7470 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7471 clean_up();
7472 valuetype = V_INT;
7473 u.val_Int = new int_val_t(enum_val);
7474 break;}
7475 case OPTYPE_UNICHAR2INT:
7476 if (is_unfoldable()) {
7477 // replace the operation with char2int() if the operand is a charstring
7478 // value to avoid its unnecessary conversion to universal charstring
7479 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7480 u.expr.v_optype = OPTYPE_CHAR2INT;
7481 } else {
7482 v1=u.expr.v1->get_value_refd_last();
7483 const ustring& s = v1->get_val_ustr();
7484 clean_up();
7485 valuetype=V_INT;
7486 u.val_Int=new int_val_t(unichar2int(s));
7487 }
7488 break;
7489 case OPTYPE_UNICHAR2CHAR:
7490 v1 = u.expr.v1;
7491 if (is_unfoldable()) {
7492 // replace the operation with its operand if it is a charstring
7493 // value to avoid its unnecessary conversion to universal charstring
7494 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7495 u.expr.v1 = 0;
7496 copy_and_destroy(v1);
7497 }
7498 } else {
7499 v1 = v1->get_value_refd_last();
7500 const ustring& s = v1->get_val_ustr();
7501 clean_up();
7502 valuetype = V_CSTR;
7503 set_val_str(new string(s));
7504 }
7505 break;
7506 case OPTYPE_MULTIPLY: { // v1 v2
7507 if (!is_unfoldable()) goto eval_arithmetic;
7508 v1 = u.expr.v1->get_value_refd_last();
7509 v2 = u.expr.v2->get_value_refd_last();
7510 if (v1->is_unfoldable()) v1 = v2;
7511 if (v1->is_unfoldable()) break;
7512 switch(v1->valuetype) {
7513 case V_INT: {
7514 if (*v1->get_val_Int() != 0) break;
7515 clean_up();
7516 valuetype = V_INT;
7517 u.val_Int = new int_val_t((Int)0);
7518 break; }
7519 case V_REAL: {
7520 if (v1->get_val_Real() != 0.0) break;
7521 clean_up();
7522 valuetype = V_REAL;
7523 u.val_Real = 0.0;
7524 break; }
7525 default:
7526 FATAL_ERROR("Value::evaluate_value()");
7527 }
7528 break; }
7529 case OPTYPE_ADD: // v1 v2
7530 case OPTYPE_SUBTRACT:
7531 case OPTYPE_DIVIDE:
7532 case OPTYPE_MOD:
7533 case OPTYPE_REM: {
7534 eval_arithmetic:
7535 if(is_unfoldable()) break;
7536 v1=u.expr.v1->get_value_refd_last();
7537 v2=u.expr.v2->get_value_refd_last();
7538 operationtype_t ot=u.expr.v_optype;
7539 switch (v1->valuetype) {
7540 case V_INT: {
7541 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7542 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7543 clean_up();
7544 valuetype = V_INT;
7545 switch (ot) {
7546 case OPTYPE_ADD:
7547 u.val_Int = new int_val_t(*i1 + *i2);
7548 break;
7549 case OPTYPE_SUBTRACT:
7550 u.val_Int = new int_val_t(*i1 - *i2);
7551 break;
7552 case OPTYPE_MULTIPLY:
7553 u.val_Int = new int_val_t(*i1 * *i2);
7554 break;
7555 case OPTYPE_DIVIDE:
7556 u.val_Int = new int_val_t(*i1 / *i2);
7557 break;
7558 case OPTYPE_MOD:
7559 u.val_Int = new int_val_t(mod(*i1, *i2));
7560 break;
7561 case OPTYPE_REM:
7562 u.val_Int = new int_val_t(rem(*i1, *i2));
7563 break;
7564 default:
7565 FATAL_ERROR("Value::evaluate_value()");
7566 }
7567 delete i1;
7568 delete i2;
7569 break; }
7570 case V_REAL: {
7571 ttcn3float r1=v1->get_val_Real();
7572 ttcn3float r2=v2->get_val_Real();
7573 clean_up();
7574 valuetype=V_REAL;
7575 switch(ot) {
7576 case OPTYPE_ADD:
7577 u.val_Real=r1+r2;
7578 break;
7579 case OPTYPE_SUBTRACT:
7580 u.val_Real=r1-r2;
7581 break;
7582 case OPTYPE_MULTIPLY:
7583 u.val_Real=r1*r2;
7584 break;
7585 case OPTYPE_DIVIDE:
7586 u.val_Real=r1/r2;
7587 break;
7588 default:
7589 FATAL_ERROR("Value::evaluate_value()");
7590 }
7591 break;}
7592 default:
7593 FATAL_ERROR("Value::evaluate_value()");
7594 }
7595 break;}
7596 case OPTYPE_CONCAT: {
7597 if(is_unfoldable()) break;
7598 v1=u.expr.v1->get_value_refd_last();
7599 v2=u.expr.v2->get_value_refd_last();
7600 valuetype_t vt = v1->valuetype;
7601 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7602 const ustring& s1 = v1->get_val_ustr();
7603 const ustring& s2 = v2->get_val_ustr();
7604 clean_up();
7605 valuetype = V_USTR;
7606 set_val_ustr(new ustring(s1 + s2));
7607 u.ustr.convert_str = false;
7608 } else {
7609 const string& s1 = v1->get_val_str();
7610 const string& s2 = v2->get_val_str();
7611 clean_up();
7612 valuetype = vt;
7613 set_val_str(new string(s1 + s2));
7614 }
7615 break;}
7616 case OPTYPE_EQ: {
7617 if(is_unfoldable()) break;
7618 v1=u.expr.v1->get_value_refd_last();
7619 v2=u.expr.v2->get_value_refd_last();
7620 bool b=*v1==*v2;
7621 clean_up();
7622 valuetype=V_BOOL;
7623 u.val_bool=b;
7624 break;}
7625 case OPTYPE_NE: {
7626 if(is_unfoldable()) break;
7627 v1=u.expr.v1->get_value_refd_last();
7628 v2=u.expr.v2->get_value_refd_last();
7629 bool b=*v1==*v2;
7630 clean_up();
7631 valuetype=V_BOOL;
7632 u.val_bool=!b;
7633 break;}
7634 case OPTYPE_LT: {
7635 if(is_unfoldable()) break;
7636 v1=u.expr.v1->get_value_refd_last();
7637 v2=u.expr.v2->get_value_refd_last();
7638 bool b=*v1<*v2;
7639 clean_up();
7640 valuetype=V_BOOL;
7641 u.val_bool=b;
7642 break;}
7643 case OPTYPE_GT: {
7644 if(is_unfoldable()) break;
7645 v1=u.expr.v1->get_value_refd_last();
7646 v2=u.expr.v2->get_value_refd_last();
7647 bool b=*v2<*v1;
7648 clean_up();
7649 valuetype=V_BOOL;
7650 u.val_bool=b;
7651 break;}
7652 case OPTYPE_GE: {
7653 if(is_unfoldable()) break;
7654 v1=u.expr.v1->get_value_refd_last();
7655 v2=u.expr.v2->get_value_refd_last();
7656 bool b=*v1<*v2;
7657 clean_up();
7658 valuetype=V_BOOL;
7659 u.val_bool=!b;
7660 break;}
7661 case OPTYPE_LE: {
7662 if(is_unfoldable()) break;
7663 v1=u.expr.v1->get_value_refd_last();
7664 v2=u.expr.v2->get_value_refd_last();
7665 bool b=*v2<*v1;
7666 clean_up();
7667 valuetype=V_BOOL;
7668 u.val_bool=!b;
7669 break;}
7670 case OPTYPE_AND:
7671 v1 = u.expr.v1->get_value_refd_last();
7672 if (v1->valuetype == V_BOOL) {
7673 if (v1->get_val_bool()) {
7674 // the left operand is a literal "true"
7675 // substitute the expression with the right operand
7676 v2 = u.expr.v2;
7677 u.expr.v2 = 0;
7678 copy_and_destroy(v2);
7679 } else {
7680 // the left operand is a literal "false"
7681 // the result must be false regardless the right operand
7682 // because of the short circuit evaluation rule
7683 clean_up();
7684 valuetype = V_BOOL;
7685 u.val_bool = false;
7686 }
7687 } else {
7688 // we must keep the left operand because of the potential side effects
7689 // the right operand can only be eliminated if it is a literal "true"
7690 v2 = u.expr.v2->get_value_refd_last();
7691 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7692 v1 = u.expr.v1;
7693 u.expr.v1 = 0;
7694 copy_and_destroy(v1);
7695 }
7696 }
7697 break;
7698 case OPTYPE_OR:
7699 v1 = u.expr.v1->get_value_refd_last();
7700 if (v1->valuetype == V_BOOL) {
7701 if (v1->get_val_bool()) {
7702 // the left operand is a literal "true"
7703 // the result must be true regardless the right operand
7704 // because of the short circuit evaluation rule
7705 clean_up();
7706 valuetype = V_BOOL;
7707 u.val_bool = true;
7708 } else {
7709 // the left operand is a literal "false"
7710 // substitute the expression with the right operand
7711 v2 = u.expr.v2;
7712 u.expr.v2 = 0;
7713 copy_and_destroy(v2);
7714 }
7715 } else {
7716 // we must keep the left operand because of the potential side effects
7717 // the right operand can only be eliminated if it is a literal "false"
7718 v2 = u.expr.v2->get_value_refd_last();
7719 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7720 v1 = u.expr.v1;
7721 u.expr.v1 = 0;
7722 copy_and_destroy(v1);
7723 }
7724 }
7725 break;
7726 case OPTYPE_XOR: {
7727 if(is_unfoldable()) break;
7728 v1=u.expr.v1->get_value_refd_last();
7729 v2=u.expr.v2->get_value_refd_last();
7730 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7731 clean_up();
7732 valuetype=V_BOOL;
7733 u.val_bool=b;
7734 break;}
7735 case OPTYPE_AND4B: {
7736 if(is_unfoldable()) break;
7737 v1=u.expr.v1->get_value_refd_last();
7738 v2=u.expr.v2->get_value_refd_last();
7739 valuetype_t vt=v1->valuetype;
7740 const string& s1 = v1->get_val_str();
7741 const string& s2 = v2->get_val_str();
7742 clean_up();
7743 valuetype=vt;
7744 set_val_str(and4b(s1, s2));
7745 break;}
7746 case OPTYPE_OR4B: {
7747 if(is_unfoldable()) break;
7748 v1=u.expr.v1->get_value_refd_last();
7749 v2=u.expr.v2->get_value_refd_last();
7750 valuetype_t vt=v1->valuetype;
7751 const string& s1 = v1->get_val_str();
7752 const string& s2 = v2->get_val_str();
7753 clean_up();
7754 valuetype=vt;
7755 set_val_str(or4b(s1, s2));
7756 break;}
7757 case OPTYPE_XOR4B: {
7758 if(is_unfoldable()) break;
7759 v1=u.expr.v1->get_value_refd_last();
7760 v2=u.expr.v2->get_value_refd_last();
7761 valuetype_t vt=v1->valuetype;
7762 const string& s1 = v1->get_val_str();
7763 const string& s2 = v2->get_val_str();
7764 clean_up();
7765 valuetype=vt;
7766 set_val_str(xor4b(s1, s2));
7767 break;}
7768 case OPTYPE_SHL: {
7769 if(is_unfoldable()) break;
7770 v1=u.expr.v1->get_value_refd_last();
7771 v2=u.expr.v2->get_value_refd_last();
7772 valuetype_t vt=v1->valuetype;
7773 const string& s = v1->get_val_str();
7774 const int_val_t *i_int = v2->get_val_Int();
7775 Int i=i_int->get_val();
7776 if(vt==V_OSTR) i*=2;
7777 clean_up();
7778 valuetype=vt;
7779 set_val_str(shift_left(s, i));
7780 break;}
7781 case OPTYPE_SHR: {
7782 if(is_unfoldable()) break;
7783 v1=u.expr.v1->get_value_refd_last();
7784 v2=u.expr.v2->get_value_refd_last();
7785 valuetype_t vt=v1->valuetype;
7786 const string& s = v1->get_val_str();
7787 const int_val_t *i_int = v2->get_val_Int();
7788 Int i=i_int->get_val();
7789 if(vt==V_OSTR) i*=2;
7790 clean_up();
7791 valuetype=vt;
7792 set_val_str(shift_right(s, i));
7793 break;}
7794 case OPTYPE_ROTL: {
7795 if(is_unfoldable()) break;
7796 v1=u.expr.v1->get_value_refd_last();
7797 v2=u.expr.v2->get_value_refd_last();
7798 valuetype_t vt=v1->valuetype;
7799 const int_val_t *i_int=v2->get_val_Int();
7800 Int i=i_int->get_val();
7801 if(vt==V_USTR) {
7802 const ustring& s = v1->get_val_ustr();
7803 clean_up();
7804 valuetype=vt;
7805 set_val_ustr(rotate_left(s, i));
7806 u.ustr.convert_str = false;
7807 }
7808 else {
7809 if(vt==V_OSTR) i*=2;
7810 const string& s = v1->get_val_str();
7811 clean_up();
7812 valuetype=vt;
7813 set_val_str(rotate_left(s, i));
7814 }
7815 break;}
7816 case OPTYPE_ROTR: {
7817 if(is_unfoldable()) break;
7818 v1=u.expr.v1->get_value_refd_last();
7819 v2=u.expr.v2->get_value_refd_last();
7820 valuetype_t vt=v1->valuetype;
7821 const int_val_t *i_int=v2->get_val_Int();
7822 Int i=i_int->get_val();
7823 if(vt==V_USTR) {
7824 const ustring& s = v1->get_val_ustr();
7825 clean_up();
7826 valuetype=vt;
7827 set_val_ustr(rotate_right(s, i));
7828 u.ustr.convert_str = false;
7829 }
7830 else {
7831 if(vt==V_OSTR) i*=2;
7832 const string& s = v1->get_val_str();
7833 clean_up();
7834 valuetype=vt;
7835 set_val_str(rotate_right(s, i));
7836 }
7837 break;}
7838 case OPTYPE_INT2BIT: {
7839 if (is_unfoldable()) break;
7840 v1 = u.expr.v1->get_value_refd_last();
7841 v2 = u.expr.v2->get_value_refd_last();
7842 const int_val_t *i1_int = v1->get_val_Int();
7843 const int_val_t *i2_int = v2->get_val_Int();
7844 string *val = int2bit(*i1_int, i2_int->get_val());
7845 clean_up();
7846 valuetype = V_BSTR;
7847 set_val_str(val);
7848 break; }
7849 case OPTYPE_INT2HEX: {
7850 if (is_unfoldable()) break;
7851 v1 = u.expr.v1->get_value_refd_last();
7852 v2 = u.expr.v2->get_value_refd_last();
7853 const int_val_t *i1_int = v1->get_val_Int();
7854 const int_val_t *i2_int = v2->get_val_Int();
7855 // Do it before the `clean_up'. i2_int is already checked.
7856 string *val = int2hex(*i1_int, i2_int->get_val());
7857 clean_up();
7858 valuetype = V_HSTR;
7859 set_val_str(val);
7860 break; }
7861 case OPTYPE_INT2OCT: {
7862 if (is_unfoldable()) break;
7863 v1 = u.expr.v1->get_value_refd_last();
7864 v2 = u.expr.v2->get_value_refd_last();
7865 const int_val_t i1_int(*v1->get_val_Int());
7866 // `v2' is a native integer.
7867 Int i2_int = v2->get_val_Int()->get_val() * 2;
7868 clean_up();
7869 valuetype = V_OSTR;
7870 set_val_str(int2hex(i1_int, i2_int));
7871 break; }
7872 case OPTYPE_SUBSTR: {
7873 if(is_unfoldable()) break;
7874 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7875 v2=u.expr.v2->get_value_refd_last();
7876 v3=u.expr.v3->get_value_refd_last();
7877 valuetype_t vt=v1->valuetype;
7878 const int_val_t *i2_int=v2->get_val_Int();
7879 const int_val_t *i3_int=v3->get_val_Int();
7880 Int i2=i2_int->get_val();
7881 Int i3=i3_int->get_val();
7882 if(vt==V_USTR) {
7883 const ustring& s = v1->get_val_ustr();
7884 clean_up();
7885 valuetype=vt;
7886 set_val_ustr(new ustring(s.substr(i2, i3)));
7887 u.ustr.convert_str = false;
7888 }
7889 else {
7890 if(vt==V_OSTR) {
7891 i2*=2;
7892 i3*=2;
7893 }
7894 const string& s = v1->get_val_str();
7895 clean_up();
7896 valuetype=vt;
7897 set_val_str(new string(s.substr(i2, i3)));
7898 }
7899 break;}
7900 case OPTYPE_REPLACE: {
7901 if(is_unfoldable()) break;
7902 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7903 v2=u.expr.v2->get_value_refd_last();
7904 v3=u.expr.v3->get_value_refd_last();
7905 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7906 valuetype_t vt=v1->valuetype;
7907 const int_val_t *i2_int=v2->get_val_Int();
7908 const int_val_t *i3_int=v3->get_val_Int();
7909 Int i2=i2_int->get_val();
7910 Int i3=i3_int->get_val();
7911 switch(vt) {
7912 case V_BSTR: {
7913 string *s1 = new string(v1->get_val_str());
7914 const string& s2 = v4->get_val_str();
7915 clean_up();
7916 valuetype=vt;
7917 s1->replace(i2, i3, s2);
7918 set_val_str(s1);
7919 break;}
7920 case V_HSTR: {
7921 string *s1 = new string(v1->get_val_str());
7922 const string& s2 = v4->get_val_str();
7923 clean_up();
7924 valuetype=vt;
7925 s1->replace(i2, i3, s2);
7926 set_val_str(s1);
7927 break;}
7928 case V_OSTR: {
7929 i2*=2;
7930 i3*=2;
7931 string *s1 = new string(v1->get_val_str());
7932 const string& s2 = v4->get_val_str();
7933 clean_up();
7934 valuetype=vt;
7935 s1->replace(i2, i3, s2);
7936 set_val_str(s1);
7937 break;}
7938 case V_CSTR: {
7939 string *s1 = new string(v1->get_val_str());
7940 const string& s2 = v4->get_val_str();
7941 clean_up();
7942 valuetype=vt;
7943 s1->replace(i2, i3, s2);
7944 set_val_str(s1);
7945 break;}
7946 case V_USTR: {
7947 ustring *s1 = new ustring(v1->get_val_ustr());
7948 const ustring& s2 = v4->get_val_ustr();
7949 clean_up();
7950 valuetype=vt;
7951 s1->replace(i2, i3, s2);
7952 set_val_ustr(s1);
7953 u.ustr.convert_str = false;
7954 break;}
7955 default:
7956 FATAL_ERROR("Value::evaluate_value()");
7957 }
7958 break; }
7959 case OPTYPE_REGEXP: {
7960 if (is_unfoldable()) break;
7961 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7962 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7963 v3=u.expr.v3->get_value_refd_last();
7964 const int_val_t *i3_int = v3->get_val_Int();
7965 Int i3 = i3_int->get_val();
7966 if (v1->valuetype == V_CSTR) {
7967 const string& s1 = v1->get_val_str();
7968 const string& s2 = v2->get_val_str();
7969 string *result = regexp(s1, s2, i3);
7970 clean_up();
7971 valuetype = V_CSTR;
7972 set_val_str(result);
7973 } if (v1->valuetype == V_USTR) {
7974 const ustring& s1 = v1->get_val_ustr();
7975 const ustring& s2 = v2->get_val_ustr();
7976 ustring *result = regexp(s1, s2, i3);
7977 clean_up();
7978 valuetype = V_USTR;
7979 set_val_ustr(result);
7980 u.ustr.convert_str = false;
7981 }
7982 break; }
7983 case OPTYPE_LENGTHOF:{
7984 if(is_unfoldable()) break;
7985 v1=u.expr.ti1->get_Template()->get_specific_value()
7986 ->get_value_refd_last();
7987 size_t i;
7988 if(v1->is_string_type(exp_val)) {
7989 i=v1->get_val_strlen();
7990 } else { // v1 is be seq/set of or array
7991 switch (v1->valuetype) {
7992 case V_SEQOF:
7993 case V_SETOF:
7994 case V_ARRAY: {
7995 if(v1->u.val_vs->is_indexed())
7996 { i = v1->u.val_vs->get_nof_ivs();}
7997 else { i = v1->u.val_vs->get_nof_vs();}
7998 break; }
7999 default:
8000 FATAL_ERROR("Value::evaluate_value()");
8001 }
8002 }
8003 clean_up();
8004 valuetype=V_INT;
8005 u.val_Int=new int_val_t(i);
8006 break;}
8007 case OPTYPE_SIZEOF: {
8008 Int i=chk_eval_expr_sizeof(refch, exp_val);
8009 if(i!=-1) {
8010 clean_up();
8011 valuetype=V_INT;
8012 u.val_Int=new int_val_t(i);
8013 }
8014 break;}
8015 case OPTYPE_ISVALUE: {
8016 if(is_unfoldable()) break;
8017 bool is_singleval = !u.expr.ti1->get_DerivedRef()
8018 && u.expr.ti1->get_Template()->is_Value();
8019 if (is_singleval) {
8020 Value * other_val = u.expr.ti1->get_Template()->get_Value();
8021 is_singleval = other_val->evaluate_isvalue(false);
8022 // is_singleval now contains the compile-time result of isvalue
8023 delete other_val;
8024 }
8025 clean_up();
8026 valuetype = V_BOOL;
8027 u.val_bool = is_singleval;
8028 break;}
8029 case OPTYPE_ISCHOSEN_V: {
8030 if (is_unfoldable()) break;
8031 v1 = u.expr.v1->get_value_refd_last();
8032 bool b = v1->field_is_chosen(*u.expr.i2);
8033 clean_up();
8034 valuetype = V_BOOL;
8035 u.val_bool = b;
8036 break; }
8037 case OPTYPE_VALUEOF: // ti1
8038 if (!u.expr.ti1->get_DerivedRef() &&
8039 u.expr.ti1->get_Template()->is_Value() &&
8040 !u.expr.ti1->get_Type()) {
8041 // FIXME actually if the template instance has a type
8042 // it might still be foldable.
8043 // the argument is a single specific value
8044 v1 = u.expr.ti1->get_Template()->get_Value();
8045 Type *governor = my_governor;
8046 if (governor == NULL) {
8047 governor = u.expr.ti1->get_expr_governor(exp_val);
8048 if (governor != NULL) governor = governor->get_type_refd_last();
8049 }
8050 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
8051 if (governor == NULL)
8052 FATAL_ERROR("Value::evaluate_value()");
8053 clean_up();
8054 valuetype = v1->valuetype;
8055 u = v1->u;
8056 set_my_governor(governor);
8057 if (valuetype == V_REFD && u.ref.refd_last == v1)
8058 u.ref.refd_last = this;
8059 v1->valuetype = V_ERROR;
8060 delete v1;
8061 }
8062 break;
8063 case OPTYPE_UNDEF_RUNNING:
8064 default:
8065 FATAL_ERROR("Value::evaluate_value()");
8066 } // switch optype
8067 }
8068
8069 bool Value::evaluate_isvalue(bool from_sequence)
8070 {
8071 switch (valuetype) {
8072 case V_OMIT:
8073 // Omit is not a value unless a member of a sequence or set
8074 return from_sequence;
8075 case V_NOTUSED:
8076 return false;
8077 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8078 case V_BOOL: /**< boolean */
8079 case V_NAMEDINT: /**< integer / named number */
8080 case V_NAMEDBITS: /**< named bits (identifiers) */
8081 case V_INT: /**< integer */
8082 case V_REAL: /**< real/float */
8083 case V_ENUM: /**< enumerated */
8084 case V_BSTR: /**< bitstring */
8085 case V_HSTR: /**< hexstring */
8086 case V_OSTR: /**< octetstring */
8087 case V_CSTR: /**< charstring */
8088 case V_USTR: /**< universal charstring */
8089 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
8090 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
8091 case V_OID: /**< object identifier */
8092 case V_ROID: /**< relative object identifier */
8093 case V_VERDICT: /**< all verdicts */
8094 return true; // values of built-in types return true
8095
8096 // Code below was adapted from is_unfoldable(), false returned early.
8097 case V_CHOICE:
8098 return u.choice.alt_value->evaluate_isvalue(false);
8099
8100 case V_SEQOF:
8101 case V_SETOF:
8102 case V_ARRAY:
8103 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8104 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
8105 return false;
8106 }
8107 }
8108 return true;
8109
8110 case V_SEQ:
8111 case V_SET:
8112 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8113 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
8114 ->evaluate_isvalue(true)) return false;
8115 }
8116 return true;
8117
8118 case V_REFD:
8119 // alas, get_value_refd_last prevents this function from const
8120 return get_value_refd_last()->evaluate_isvalue(false);
8121
8122 case V_EXPR:
8123 switch (u.expr.v_optype) {
8124 // A constant null component reference is a corner case: it is foldable
8125 // but escapes unmodified from evaluate_value.
8126 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8127 // or is transformed into some other valuetype in evaluate_value.
8128 case OPTYPE_COMP_NULL:
8129 return false;
8130 default:
8131 break; // and fall through to the FATAL_ERROR
8132 }
8133 // no break
8134 default:
8135 FATAL_ERROR("Value::evaluate_isvalue()");
8136 break;
8137 }
8138 return true;
8139 }
8140
8141 void Value::evaluate_macro(Type::expected_value_t exp_val)
8142 {
8143 switch (u.macro) {
8144 case MACRO_MODULEID:
8145 if (!my_scope)
8146 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8147 set_val_str(new string(my_scope->get_scope_mod()
8148 ->get_modid().get_dispname()));
8149 valuetype = V_CSTR;
8150 break;
8151 case MACRO_FILENAME:
8152 case MACRO_BFILENAME: {
8153 const char *t_filename = get_filename();
8154 if (!t_filename)
8155 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8156 set_val_str(new string(t_filename));
8157 valuetype = V_CSTR;
8158 break; }
8159 case MACRO_FILEPATH: {
8160 const char *t_filename = get_filename();
8161 if (!t_filename)
8162 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8163 char *t_filepath = canonize_input_file(t_filename);
8164 if (!t_filepath)
8165 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8166 set_val_str(new string(t_filepath));
8167 valuetype = V_CSTR;
8168 Free(t_filepath);
8169 break; }
8170 case MACRO_LINENUMBER: {
8171 int t_lineno = get_first_line();
8172 if (t_lineno <= 0)
8173 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8174 set_val_str(new string(Int2string(t_lineno)));
8175 valuetype = V_CSTR;
8176 break; }
8177 case MACRO_LINENUMBER_C: {
8178 int t_lineno = get_first_line();
8179 if (t_lineno <= 0)
8180 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8181 u.val_Int = new int_val_t(t_lineno);
8182 valuetype = V_INT;
8183 break; }
8184 case MACRO_DEFINITIONID: {
8185 // cut the second part from the fullname separated by dots
8186 const string& t_fullname = get_fullname();
8187 size_t first_char = t_fullname.find('.') + 1;
8188 if (first_char >= t_fullname.size())
8189 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8190 t_fullname.c_str());
8191 set_val_str(new string(t_fullname.substr(first_char,
8192 t_fullname.find('.', first_char) - first_char)));
8193 valuetype = V_CSTR;
8194 break; }
8195 case MACRO_SCOPE: {
8196 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8197 set_val_str(new string(my_scope->get_scopeMacro_name()));
8198 valuetype = V_CSTR;
8199 break;
8200 }
8201 case MACRO_TESTCASEID: {
8202 if (exp_val == Type::EXPECTED_CONSTANT ||
8203 exp_val == Type::EXPECTED_STATIC_VALUE) {
8204 error("A %s value was expected instead of macro `%%testcaseId', "
8205 "which is evaluated at runtime",
8206 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8207 goto error;
8208 }
8209 if (!my_scope)
8210 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8211 Ttcn::StatementBlock *my_sb =
8212 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8213 if (!my_sb) {
8214 error("Usage of macro %%testcaseId is allowed only within the "
8215 "statement blocks of functions, altsteps and testcases");
8216 goto error;
8217 }
8218 Ttcn::Definition *my_def = my_sb->get_my_def();
8219 if (!my_def) {
8220 error("Macro %%testcaseId cannot be used in the control part. "
8221 "It is allowed only within the statement blocks of functions, "
8222 "altsteps and testcases");
8223 goto error;
8224 }
8225 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8226 // folding is possible only within testcases
8227 set_val_str(new string(my_def->get_id().get_dispname()));
8228 valuetype = V_CSTR;
8229 }
8230 break; }
8231 default:
8232 FATAL_ERROR("Value::evaluate_macro()");
8233 }
8234 return;
8235 error:
8236 set_valuetype(V_ERROR);
8237 }
8238
8239 void Value::add_id(Identifier *p_id)
8240 {
8241 switch(valuetype) {
8242 case V_NAMEDBITS:
8243 if(u.ids->has_key(p_id->get_name())) {
8244 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8245 // The Value does not take ownership for the identifier,
8246 // so it must be deleted (add_is acts as a sink).
8247 delete p_id;
8248 }
8249 else u.ids->add(p_id->get_name(), p_id);
8250 break;
8251 default:
8252 FATAL_ERROR("Value::add_id()");
8253 } // switch
8254 }
8255
8256 Value* Value::get_value_refd_last(ReferenceChain *refch,
8257 Type::expected_value_t exp_val)
8258 {
8259 set_lowerid_to_ref();
8260 switch (valuetype) {
8261 case V_INVOKE:
8262 // there might be a better place for this
8263 chk_invoke(exp_val);
8264 return this;
8265 case V_REFD:
8266 // use the cache if available
8267 if (u.ref.refd_last) return u.ref.refd_last;
8268 else {
8269 Assignment *ass = u.ref.ref->get_refd_assignment();
8270 if (!ass) {
8271 // the referred definition is not found
8272 set_valuetype(V_ERROR);
8273 } else {
8274 switch (ass->get_asstype()) {
8275 case Assignment::A_OBJECT:
8276 case Assignment::A_OS: {
8277 // the referred definition is an ASN.1 object or object set
8278 Setting *setting = u.ref.ref->get_refd_setting();
8279 if (!setting || setting->get_st() == S_ERROR) {
8280 // remain silent, the error has been already reported
8281 set_valuetype(V_ERROR);
8282 break;
8283 } else if (setting->get_st() != S_V) {
8284 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8285 " refer to a value", u.ref.ref->get_dispname().c_str());
8286 set_valuetype(V_ERROR);
8287 break;
8288 }
8289 bool destroy_refch;
8290 if (refch) {
8291 refch->mark_state();
8292 destroy_refch = false;
8293 } else {
8294 refch = new ReferenceChain(this,
8295 "While searching referenced value");
8296 destroy_refch = true;
8297 }
8298 if (refch->add(get_fullname())) {
8299 Value *v_refd = dynamic_cast<Value*>(setting);
8300 Value *v_last = v_refd->get_value_refd_last(refch);
8301 // in case of circular recursion the valuetype is already set
8302 // to V_ERROR, so don't set the cache
8303 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8304 } else {
8305 // a circular recursion was detected
8306 set_valuetype(V_ERROR);
8307 }
8308 if (destroy_refch) delete refch;
8309 else refch->prev_state();
8310 break; }
8311 case Assignment::A_CONST: {
8312 // the referred definition is a constant
8313 bool destroy_refch;
8314 if (refch) {
8315 refch->mark_state();
8316 destroy_refch = false;
8317 } else {
8318 refch = new ReferenceChain(this,
8319 "While searching referenced value");
8320 destroy_refch = true;
8321 }
8322 if (refch->add(get_fullname())) {
8323 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8324 Value *v_refd = ass->get_Value()
8325 ->get_refd_sub_value(subrefs, 0,
8326 u.ref.ref->getUsedInIsbound(), refch);
8327 if (v_refd) {
8328 Value *v_last = v_refd->get_value_refd_last(refch);
8329 // in case of circular recursion the valuetype is already set
8330 // to V_ERROR, so don't set the cache
8331 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8332 } else if (subrefs && subrefs->has_unfoldable_index()) {
8333 u.ref.refd_last = this;
8334 } else if (u.ref.ref->getUsedInIsbound()) {
8335 u.ref.refd_last = this;
8336 } else {
8337 // the sub-reference points to a non-existent field
8338 set_valuetype(V_ERROR);
8339 }
8340 } else {
8341 // a circular recursion was detected
8342 set_valuetype(V_ERROR);
8343 }
8344 if (destroy_refch) delete refch;
8345 else refch->prev_state();
8346 break; }
8347 case Assignment::A_EXT_CONST:
8348 case Assignment::A_MODULEPAR:
8349 case Assignment::A_VAR:
8350 case Assignment::A_FUNCTION_RVAL:
8351 case Assignment::A_EXT_FUNCTION_RVAL:
8352 case Assignment::A_PAR_VAL_IN:
8353 case Assignment::A_PAR_VAL_OUT:
8354 case Assignment::A_PAR_VAL_INOUT:
8355 // the referred definition is not a constant
8356 u.ref.refd_last = this;
8357 break;
8358 case Assignment::A_FUNCTION:
8359 case Assignment::A_EXT_FUNCTION:
8360 u.ref.ref->error("Reference to a value was expected instead of a "
8361 "call of %s, which does not have return type",
8362 ass->get_description().c_str());
8363 set_valuetype(V_ERROR);
8364 break;
8365 case Assignment::A_FUNCTION_RTEMP:
8366 case Assignment::A_EXT_FUNCTION_RTEMP:
8367 u.ref.ref->error("Reference to a value was expected instead of a "
8368 "call of %s, which returns a template",
8369 ass->get_description().c_str());
8370 set_valuetype(V_ERROR);
8371 break;
8372 default:
8373 u.ref.ref->error("Reference to a value was expected instead of %s",
8374 ass->get_description().c_str());
8375 set_valuetype(V_ERROR);
8376 } // switch asstype
8377 }
8378 if (valuetype == V_REFD) return u.ref.refd_last;
8379 else return this;
8380 }
8381 case V_EXPR: {
8382 // try to evaluate the expression
8383 bool destroy_refch;
8384 if(refch) {
8385 refch->mark_state();
8386 destroy_refch=false;
8387 }
8388 else {
8389 refch=new ReferenceChain(this, "While evaluating expression");
8390 destroy_refch=true;
8391 }
8392 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8393 else set_valuetype(V_ERROR);
8394 if(destroy_refch) delete refch;
8395 else refch->prev_state();
8396 return this; }
8397 case V_MACRO:
8398 evaluate_macro(exp_val);
8399 // no break
8400 default:
8401 // return this for all other value types
8402 return this;
8403 } // switch
8404 }
8405
8406 map<Value*, void> Value::UnfoldabilityCheck::running;
8407
8408 /* Note that the logic here needs to be in sync with evaluate_value,
8409 * and possibly others, i.e. if evaluate_value is called for a Value
8410 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8411 bool Value::is_unfoldable(ReferenceChain *refch,
8412 Type::expected_value_t exp_val)
8413 {
8414 if (UnfoldabilityCheck::is_running(this)) {
8415 // This function is already running on this value => infinite recursion
8416 return true;
8417 }
8418
8419 UnfoldabilityCheck checker(this);
8420
8421 if (get_needs_conversion()) return true;
8422 switch (valuetype) {
8423 case V_NAMEDINT:
8424 case V_NAMEDBITS:
8425 case V_OPENTYPE:
8426 case V_UNDEF_LOWERID:
8427 case V_UNDEF_BLOCK:
8428 case V_TTCN3_NULL:
8429 case V_REFER:
8430 // these value types are eliminated during semantic analysis
8431 FATAL_ERROR("Value::is_unfoldable()");
8432 case V_ERROR:
8433 case V_INVOKE:
8434 return true;
8435 case V_CHOICE:
8436 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8437 case V_SEQOF:
8438 case V_SETOF:
8439 case V_ARRAY:
8440 if (!is_indexed()) {
8441 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8442 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8443 return true;
8444 }
8445 } else {
8446 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8447 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8448 return true;
8449 }
8450 }
8451 return false;
8452 case V_SEQ:
8453 case V_SET:
8454 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8455 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8456 ->is_unfoldable(refch, exp_val)) return true;
8457 }
8458 return false;
8459 case V_OID:
8460 case V_ROID:
8461 chk();
8462 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8463 if ((*u.oid_comps)[i]->is_variable()) return true;
8464 }
8465 return false;
8466 case V_REFD: {
8467 Value *v_last=get_value_refd_last(refch, exp_val);
8468 if(v_last==this) return true; // there weren't any references to chase
8469 else return v_last->is_unfoldable(refch, exp_val);
8470 }
8471 case V_EXPR:
8472 // classify the unchecked ischosen() operation, if it was not done so far
8473 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8474 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8475 switch (u.expr.v_optype) {
8476 case OPTYPE_RND: // -
8477 case OPTYPE_COMP_MTC:
8478 case OPTYPE_COMP_SYSTEM:
8479 case OPTYPE_COMP_SELF:
8480 case OPTYPE_COMP_RUNNING_ANY:
8481 case OPTYPE_COMP_RUNNING_ALL:
8482 case OPTYPE_COMP_ALIVE_ANY:
8483 case OPTYPE_COMP_ALIVE_ALL:
8484 case OPTYPE_TMR_RUNNING_ANY:
8485 case OPTYPE_GETVERDICT:
8486 case OPTYPE_TESTCASENAME:
8487 case OPTYPE_PROF_RUNNING:
8488 case OPTYPE_RNDWITHVAL: // v1
8489 case OPTYPE_MATCH: // v1 t2
8490 case OPTYPE_UNDEF_RUNNING: // v1
8491 case OPTYPE_COMP_RUNNING:
8492 case OPTYPE_COMP_ALIVE:
8493 case OPTYPE_TMR_READ:
8494 case OPTYPE_TMR_RUNNING:
8495 case OPTYPE_ACTIVATE:
8496 case OPTYPE_ACTIVATE_REFD:
8497 case OPTYPE_EXECUTE: // r1 [v2]
8498 case OPTYPE_EXECUTE_REFD:
8499 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8500 case OPTYPE_ISCHOSEN:
8501 case OPTYPE_ISCHOSEN_T:
8502 case OPTYPE_SIZEOF: // ti1
8503 case OPTYPE_DECODE:
8504 case OPTYPE_ENCODE:
8505 case OPTYPE_OCT2UNICHAR:
8506 case OPTYPE_UNICHAR2OCT:
8507 case OPTYPE_ENCODE_BASE64:
8508 case OPTYPE_DECODE_BASE64:
8509 case OPTYPE_ENCVALUE_UNICHAR:
8510 case OPTYPE_DECVALUE_UNICHAR:
8511 return true;
8512 case OPTYPE_COMP_NULL: // -
8513 return false;
8514 case OPTYPE_UNARYPLUS: // v1
8515 case OPTYPE_UNARYMINUS:
8516 case OPTYPE_NOT:
8517 case OPTYPE_NOT4B:
8518 case OPTYPE_BIT2HEX:
8519 case OPTYPE_BIT2INT:
8520 case OPTYPE_BIT2OCT:
8521 case OPTYPE_BIT2STR:
8522 case OPTYPE_CHAR2INT:
8523 case OPTYPE_CHAR2OCT:
8524 case OPTYPE_FLOAT2INT:
8525 case OPTYPE_FLOAT2STR:
8526 case OPTYPE_HEX2BIT:
8527 case OPTYPE_HEX2INT:
8528 case OPTYPE_HEX2OCT:
8529 case OPTYPE_HEX2STR:
8530 case OPTYPE_INT2CHAR:
8531 case OPTYPE_INT2FLOAT:
8532 case OPTYPE_INT2STR:
8533 case OPTYPE_INT2UNICHAR:
8534 case OPTYPE_OCT2BIT:
8535 case OPTYPE_OCT2CHAR:
8536 case OPTYPE_OCT2HEX:
8537 case OPTYPE_OCT2INT:
8538 case OPTYPE_OCT2STR:
8539 case OPTYPE_STR2BIT:
8540 case OPTYPE_STR2FLOAT:
8541 case OPTYPE_STR2HEX:
8542 case OPTYPE_STR2INT:
8543 case OPTYPE_STR2OCT:
8544 case OPTYPE_UNICHAR2INT:
8545 case OPTYPE_UNICHAR2CHAR:
8546 case OPTYPE_ENUM2INT:
8547 case OPTYPE_GET_STRINGENCODING:
8548 case OPTYPE_REMOVE_BOM:
8549 return u.expr.v1->is_unfoldable(refch, exp_val);
8550 case OPTYPE_ISBOUND: /*{
8551 //TODO once we have the time for it make isbound foldable.
8552 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8553 Template* temp = u.expr.ti1->get_Template();
8554 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8555 Value* specificValue = temp->get_specific_value();
8556 if (specificValue->get_valuetype() == Value::V_REFD) {
8557 //FIXME implement
8558 }
8559
8560 return specificValue->is_unfoldable(refch, exp_val);
8561 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8562 //FIXME implement
8563 }
8564 }*/
8565 return true;
8566 case OPTYPE_ISPRESENT:
8567 // TODO: "if you have motivation"
8568 return true;
8569 case OPTYPE_ISVALUE: // ti1
8570 // fallthrough
8571 case OPTYPE_LENGTHOF: // ti1
8572 return u.expr.ti1->get_DerivedRef() != 0
8573 || u.expr.ti1->get_Template()->get_templatetype()
8574 != Template::SPECIFIC_VALUE
8575 || u.expr.ti1->get_Template()->get_specific_value()
8576 ->is_unfoldable(refch, exp_val);
8577 case OPTYPE_ROTL:
8578 case OPTYPE_ROTR:
8579 case OPTYPE_CONCAT:
8580 if (!u.expr.v1->is_string_type(exp_val)) return true;
8581 // no break
8582 case OPTYPE_ADD: // v1 v2
8583 case OPTYPE_SUBTRACT:
8584 case OPTYPE_MULTIPLY:
8585 case OPTYPE_DIVIDE:
8586 case OPTYPE_MOD:
8587 case OPTYPE_REM:
8588 case OPTYPE_EQ:
8589 case OPTYPE_LT:
8590 case OPTYPE_GT:
8591 case OPTYPE_NE:
8592 case OPTYPE_GE:
8593 case OPTYPE_LE:
8594 case OPTYPE_XOR:
8595 case OPTYPE_AND4B:
8596 case OPTYPE_OR4B:
8597 case OPTYPE_XOR4B:
8598 case OPTYPE_SHL:
8599 case OPTYPE_SHR:
8600 case OPTYPE_INT2BIT:
8601 case OPTYPE_INT2HEX:
8602 case OPTYPE_INT2OCT:
8603 return u.expr.v1->is_unfoldable(refch, exp_val)
8604 || u.expr.v2->is_unfoldable(refch, exp_val);
8605 case OPTYPE_AND: // short-circuit evaluation
8606 return u.expr.v1->is_unfoldable(refch, exp_val)
8607 || (u.expr.v1->get_val_bool() &&
8608 u.expr.v2->is_unfoldable(refch, exp_val));
8609 case OPTYPE_OR: // short-circuit evaluation
8610 return u.expr.v1->is_unfoldable(refch, exp_val)
8611 || (!u.expr.v1->get_val_bool() &&
8612 u.expr.v2->is_unfoldable(refch, exp_val));
8613 case OPTYPE_SUBSTR:
8614 if (!u.expr.ti1->get_specific_value()) return true;
8615 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8616 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8617 || u.expr.v2->is_unfoldable(refch, exp_val)
8618 || u.expr.v3->is_unfoldable(refch, exp_val);
8619 case OPTYPE_REGEXP:
8620 if (!u.expr.ti1->get_specific_value() ||
8621 !u.expr.t2->get_specific_value()) return true;
8622 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8623 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8624 || u.expr.v3->is_unfoldable(refch, exp_val);
8625 case OPTYPE_DECOMP:
8626 return u.expr.v1->is_unfoldable(refch, exp_val)
8627 || u.expr.v2->is_unfoldable(refch, exp_val)
8628 || u.expr.v3->is_unfoldable(refch, exp_val);
8629 case OPTYPE_REPLACE: {
8630 if (!u.expr.ti1->get_specific_value() ||
8631 !u.expr.ti4->get_specific_value()) return true;
8632 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8633 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8634 || u.expr.v2->is_unfoldable(refch, exp_val)
8635 || u.expr.v3->is_unfoldable(refch, exp_val)
8636 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8637 }
8638 case OPTYPE_VALUEOF: // ti1
8639 /* \todo if you have motivation to implement the eval function
8640 for valueof()... */
8641 return true;
8642 case OPTYPE_ISCHOSEN_V:
8643 return u.expr.v1->is_unfoldable(refch, exp_val);
8644 case OPTYPE_LOG2STR:
8645 case OPTYPE_ANY2UNISTR:
8646 case OPTYPE_TTCN2STRING:
8647 return true;
8648 default:
8649 FATAL_ERROR("Value::is_unfoldable()");
8650 } // switch
8651 break; // should never get here
8652 case V_MACRO:
8653 switch (u.macro) {
8654 case MACRO_TESTCASEID:
8655 // this is known only at runtime
8656 return true;
8657 default:
8658 return false;
8659 }
8660 default:
8661 // all literal values are foldable
8662 return false;
8663 }
8664 }
8665
8666 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8667 size_t start_i, bool usedInIsbound,
8668 ReferenceChain *refch)
8669 {
8670 if (!subrefs) return this;
8671 Value *v = this;
8672 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8673 if (!v) break;
8674 v = v->get_value_refd_last(refch);
8675 switch(v->valuetype) {
8676 case V_ERROR:
8677 return v;
8678 case V_REFD:
8679 // unfoldable stuff
8680 return this;
8681 default:
8682 break;
8683 } // switch
8684 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8685 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8686 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8687 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8688 }
8689 return v;
8690 }
8691
8692 Value *Value::get_refd_field_value(const Identifier& field_id,
8693 bool usedInIsbound, const Location& loc)
8694 {
8695 if (valuetype == V_OMIT) {
8696 loc.error("Reference to field `%s' of omit value `%s'",
8697 field_id.get_dispname().c_str(), get_fullname().c_str());
8698 return 0;
8699 }
8700 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8701 Type *t = my_governor->get_type_refd_last();
8702 switch (t->get_typetype()) {
8703 case Type::T_ERROR:
8704 // remain silent
8705 return 0;
8706 case Type::T_CHOICE_A:
8707 case Type::T_CHOICE_T:
8708 case Type::T_OPENTYPE:
8709 case Type::T_ANYTYPE:
8710 if (!t->has_comp_withName(field_id)) {
8711 loc.error("Reference to non-existent union field `%s' in type `%s'",
8712 field_id.get_dispname().c_str(), t->get_typename().c_str());
8713 return 0;
8714 } else if (valuetype != V_CHOICE) {
8715 // remain silent, the error is already reported
8716 return 0;
8717 } else if (*u.choice.alt_name == field_id) {
8718 // everything is OK
8719 return u.choice.alt_value;
8720 }else {
8721 if (!usedInIsbound) {
8722 loc.error("Reference to inactive field `%s' in a value of union type "
8723 "`%s'. The active field is `%s'",
8724 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8725 u.choice.alt_name->get_dispname().c_str());
8726 }
8727 return 0;
8728 }
8729 case Type::T_SEQ_A:
8730 case Type::T_SEQ_T:
8731 if (!t->has_comp_withName(field_id)) {
8732 loc.error("Reference to non-existent record field `%s' in type `%s'",
8733 field_id.get_dispname().c_str(), t->get_typename().c_str());
8734 return 0;
8735 } else if (valuetype != V_SEQ) {
8736 // remain silent, the error has been already reported
8737 return 0;
8738 } else break;
8739 case Type::T_SET_A:
8740 case Type::T_SET_T:
8741 if (!t->has_comp_withName(field_id)) {
8742 loc.error("Reference to non-existent set field `%s' in type `%s'",
8743 field_id.get_dispname().c_str(), t->get_typename().c_str());
8744 return 0;
8745 } else if (valuetype != V_SET) {
8746 // remain silent, the error has been already reported
8747 return 0;
8748 } else break;
8749 default:
8750 loc.error("Invalid field reference `%s': type `%s' "
8751 "does not have fields", field_id.get_dispname().c_str(),
8752 t->get_typename().c_str());
8753 return 0;
8754 }
8755 // the common end for record & set types
8756 if (u.val_nvs->has_nv_withName(field_id)) {
8757 // everything is OK
8758 return u.val_nvs->get_nv_byName(field_id)->get_value();
8759 } else if (!is_asn1()) {
8760 if (!usedInIsbound) {
8761 loc.error("Reference to unbound field `%s'",
8762 field_id.get_dispname().c_str());
8763 // this is an error in TTCN-3, which has been already reported
8764 }
8765 return 0;
8766 } else {
8767 CompField *cf = t->get_comp_byName(field_id);
8768 if (cf->get_is_optional()) {
8769 // creating an explicit omit value
8770 Value *v = new Value(V_OMIT);
8771 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8772 v->set_my_scope(get_my_scope());
8773 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8774 return v;
8775 } else if (cf->has_default()) {
8776 // returning the component's default value
8777 return cf->get_defval();
8778 } else {
8779 // this is an error in ASN.1, which has been already reported
8780 return 0;
8781 }
8782 }
8783 }
8784
8785 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8786 ReferenceChain *refch)
8787 {
8788 Value *v_index = array_index->get_value_refd_last(refch);
8789 Int index = 0;
8790 bool index_available = false;
8791 if (!v_index->is_unfoldable()) {
8792 if (v_index->valuetype == V_INT) {
8793 index = v_index->get_val_Int()->get_val();
8794 index_available = true;
8795 } else {
8796 array_index->error("An integer value was expected as index");
8797 }
8798 }
8799 if (valuetype == V_OMIT) {
8800 array_index->error("Accessing an element with index of omit value `%s'",
8801 get_fullname().c_str());
8802 return 0;
8803 }
8804 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8805 Type *t = my_governor->get_type_refd_last();
8806 switch (t->get_typetype()) {
8807 case Type::T_ERROR:
8808 // remain silent
8809 return 0;
8810 case Type::T_SEQOF:
8811 if (index_available) {
8812 if (index < 0) {
8813 array_index->error("A non-negative integer value was expected "
8814 "instead of %s for indexing a value of `record "
8815 "of' type `%s'", Int2string(index).c_str(),
8816 t->get_typename().c_str());
8817 return 0;
8818 }
8819 switch (valuetype) {
8820 case V_SEQOF:
8821 if (!is_indexed()) {
8822 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8823 if (!usedInIsbound) {
8824 array_index->error("Index overflow in a value of `record of' "
8825 "type `%s': the index is %s, but the value "
8826 "has only %lu elements",
8827 t->get_typename().c_str(),
8828 Int2string(index).c_str(),
8829 (unsigned long)u.val_vs->get_nof_vs());
8830 }
8831 return 0;
8832 } else {
8833 Value* temp = u.val_vs->get_v_byIndex(index);
8834 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8835 temp->error("Not used symbol is not allowed in this context");
8836 return u.val_vs->get_v_byIndex(index);
8837 }
8838 } else {
8839 // Search the appropriate constant index.
8840 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8841 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8842 ->get_value_refd_last();
8843 if (iv_index->get_valuetype() != V_INT) continue;
8844 if (iv_index->get_val_Int()->get_val() == index)
8845 return u.val_vs->get_iv_byIndex(i)->get_value();
8846 }
8847 return 0;
8848 }
8849 break;
8850 default:
8851 // remain silent, the error has been already reported
8852 return 0;
8853 }
8854 } else {
8855 // the error has been reported above
8856 return 0;
8857 }
8858 case Type::T_SETOF:
8859 if (index_available) {
8860 if (index < 0) {
8861 array_index->error("A non-negative integer value was expected "
8862 "instead of %s for indexing a value of `set of' type `%s'",
8863 Int2string(index).c_str(), t->get_typename().c_str());
8864 return 0;
8865 }
8866 switch (valuetype) {
8867 case V_SETOF:
8868 if (!is_indexed()) {
8869 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8870 if (!usedInIsbound) {
8871 array_index->error("Index overflow in a value of `set of' type "
8872 "`%s': the index is %s, but the value has "
8873 "only %lu elements",
8874 t->get_typename().c_str(),
8875 Int2string(index).c_str(),
8876 (unsigned long)u.val_vs->get_nof_vs());
8877 }
8878 return 0;
8879 } else {
8880 Value* temp = u.val_vs->get_v_byIndex(index);
8881 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8882 temp->error("Not used symbol is not allowed in this context");
8883 return temp;
8884 }
8885 } else {
8886 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8887 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8888 ->get_value_refd_last();
8889 if (iv_index->get_valuetype() != V_INT) continue;
8890 if (iv_index->get_val_Int()->get_val() == index)
8891 return u.val_vs->get_iv_byIndex(i)->get_value();
8892 }
8893 return 0;
8894 }
8895 break;
8896 default:
8897 // remain silent, the error has been already reported
8898 return 0;
8899 }
8900 } else {
8901 // the error has been reported above
8902 return 0;
8903 }
8904 case Type::T_ARRAY:
8905 if (index_available) {
8906 Ttcn::ArrayDimension *dim = t->get_dimension();
8907 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8908 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8909 // perform the index transformation
8910 index -= dim->get_offset();
8911 if (!is_indexed()) {
8912 // check for index underflow/overflow or too few elements in the
8913 // value
8914 if (index < 0 ||
8915 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8916 return 0;
8917 else return u.val_vs->get_v_byIndex(index);
8918 } else {
8919 if (index < 0) return 0;
8920 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8921 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8922 ->get_value_refd_last();
8923 if (iv_index->get_valuetype() != V_INT) continue;
8924 if (iv_index->get_val_Int()->get_val() == index)
8925 return u.val_vs->get_iv_byIndex(index)->get_value();
8926 }
8927 return 0;
8928 }
8929 } else {
8930 // remain silent, the error has been already reported
8931 return 0;
8932 }
8933 } else {
8934 // the error has been reported above
8935 return 0;
8936 }
8937 case Type::T_BSTR:
8938 case Type::T_BSTR_A:
8939 case Type::T_HSTR:
8940 case Type::T_OSTR:
8941 case Type::T_CSTR:
8942 case Type::T_USTR:
8943 case Type::T_UTF8STRING:
8944 case Type::T_NUMERICSTRING:
8945 case Type::T_PRINTABLESTRING:
8946 case Type::T_TELETEXSTRING:
8947 case Type::T_VIDEOTEXSTRING:
8948 case Type::T_IA5STRING:
8949 case Type::T_GRAPHICSTRING:
8950 case Type::T_VISIBLESTRING:
8951 case Type::T_GENERALSTRING:
8952 case Type::T_UNIVERSALSTRING:
8953 case Type::T_BMPSTRING:
8954 case Type::T_UTCTIME:
8955 case Type::T_GENERALIZEDTIME:
8956 case Type::T_OBJECTDESCRIPTOR:
8957 if (index_available) return get_string_element(index, *array_index);
8958 else return 0;
8959 default:
8960 array_index->error("Invalid array element reference: type `%s' cannot "
8961 "be indexed", t->get_typename().c_str());
8962 return 0;
8963 }
8964 }
8965
8966 Value *Value::get_string_element(const Int& index, const Location& loc)
8967 {
8968 if (index < 0) {
8969 loc.error("A non-negative integer value was expected instead of %s "
8970 "for indexing a string element", Int2string(index).c_str());
8971 return 0;
8972 }
8973 size_t string_length;
8974 switch (valuetype) {
8975 case V_BSTR:
8976 case V_HSTR:
8977 case V_CSTR:
8978 case V_ISO2022STR:
8979 string_length = u.str.val_str->size();
8980 break;
8981 case V_OSTR:
8982 string_length = u.str.val_str->size() / 2;
8983 break;
8984 case V_USTR:
8985 string_length = u.ustr.val_ustr->size();
8986 break;
8987 default:
8988 // remain silent, the error has been already reported
8989 return 0;
8990 }
8991 if (index >= static_cast<Int>(string_length)) {
8992 loc.error("Index overflow when accessing a string element: "
8993 "the index is %s, but the string has only %lu elements",
8994 Int2string(index).c_str(), (unsigned long) string_length);
8995 return 0;
8996 }
8997 switch (valuetype) {
8998 case V_BSTR:
8999 case V_HSTR:
9000 case V_CSTR:
9001 case V_ISO2022STR:
9002 if (u.str.str_elements && u.str.str_elements->has_key(index))
9003 return (*u.str.str_elements)[index];
9004 else {
9005 Value *t_val = new Value(valuetype,
9006 new string(u.str.val_str->substr(index, 1)));
9007 add_string_element(index, t_val, u.str.str_elements);
9008 return t_val;
9009 }
9010 case V_OSTR:
9011 if (u.str.str_elements && u.str.str_elements->has_key(index))
9012 return (*u.str.str_elements)[index];
9013 else {
9014 Value *t_val = new Value(V_OSTR,
9015 new string(u.str.val_str->substr(2 * index, 2)));
9016 add_string_element(index, t_val, u.str.str_elements);
9017 return t_val;
9018 }
9019 case V_USTR:
9020 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
9021 return (*u.ustr.ustr_elements)[index];
9022 else {
9023 Value *t_val = new Value(V_USTR,
9024 new ustring(u.ustr.val_ustr->substr(index, 1)));
9025 add_string_element(index, t_val, u.ustr.ustr_elements);
9026 return t_val;
9027 }
9028 default:
9029 FATAL_ERROR("Value::get_string_element()");
9030 return 0;
9031 }
9032 }
9033
9034 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
9035 Type::expected_value_t exp_val)
9036 {
9037 set_lowerid_to_ref();
9038 Type::typetype_t r_tt = get_expr_returntype(exp_val);
9039 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
9040 if (error_flag)
9041 error("A value or expression of type %s was expected", type_name);
9042 if (valuetype == V_REFD) {
9043 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
9044 t_chk->chk_this_refd_value(this, 0, exp_val);
9045 }
9046 get_value_refd_last(0, exp_val);
9047 if (error_flag) set_valuetype(V_ERROR);
9048 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
9049 }
9050
9051 int Value::is_parsed_infinity()
9052 {
9053 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
9054 return 1;
9055 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
9056 (u.expr.v1->get_valuetype()==V_REAL) &&
9057 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
9058 return -1;
9059 return 0;
9060 }
9061
9062 bool Value::get_val_bool()
9063 {
9064 Value *v;
9065 if (valuetype == V_REFD) v = get_value_refd_last();
9066 else v = this;
9067 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
9068 return v->u.val_bool;
9069 }
9070
9071 int_val_t* Value::get_val_Int()
9072 {
9073 Value *v;
9074 if (valuetype == V_REFD) v = get_value_refd_last();
9075 else v = this;
9076 switch (v->valuetype) {
9077 case V_INT:
9078 break;
9079 case V_UNDEF_LOWERID:
9080 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9081 "`%s'", (*u.val_id).get_dispname().c_str());
9082 default:
9083 FATAL_ERROR("Value::get_val_Int()");
9084 } // switch
9085 return v->u.val_Int;
9086 }
9087
9088 const Identifier* Value::get_val_id()
9089 {
9090 switch(valuetype) {
9091 case V_NAMEDINT:
9092 case V_ENUM:
9093 case V_UNDEF_LOWERID:
9094 return u.val_id;
9095 default:
9096 FATAL_ERROR("Value::get_val_id()");
9097 return 0;
9098 } // switch
9099 }
9100
9101 const ttcn3float& Value::get_val_Real()
9102 {
9103 Value *v;
9104 if (valuetype == V_REFD) v = get_value_refd_last();
9105 else v = this;
9106 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
9107 return v->u.val_Real;
9108 }
9109
9110 string Value::get_val_str()
9111 {
9112 Value *v = get_value_refd_last();
9113 switch (v->valuetype) {
9114 case V_BSTR:
9115 case V_HSTR:
9116 case V_OSTR:
9117 case V_CSTR:
9118 return *v->u.str.val_str;
9119 case V_CHARSYMS:
9120 return v->u.char_syms->get_string();
9121 case V_USTR:
9122 error("Cannot use ISO-10646 string value in string context");
9123 return string();
9124 case V_ISO2022STR:
9125 error("Cannot use ISO-2022 string value in string context");
9126 // no break
9127 case V_ERROR:
9128 return string();
9129 default:
9130 error("Cannot use this value in charstring value context");
9131 return string();
9132 } // switch
9133 }
9134
9135 ustring Value::get_val_ustr()
9136 {
9137 Value *v = get_value_refd_last();
9138 switch (v->valuetype) {
9139 case V_CSTR:
9140 return ustring(*v->u.str.val_str);
9141 case V_USTR:
9142 return *v->u.ustr.val_ustr;
9143 case V_CHARSYMS:
9144 return v->u.char_syms->get_ustring();
9145 case V_ISO2022STR:
9146 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9147 // no break
9148 case V_ERROR:
9149 return ustring();
9150 default:
9151 error("Cannot use this value in ISO-10646 string context");
9152 return ustring();
9153 } // switch
9154 }
9155
9156 string Value::get_val_iso2022str()
9157 {
9158 Value *v = get_value_refd_last();
9159 switch (v->valuetype) {
9160 case V_CSTR:
9161 case V_ISO2022STR:
9162 return *v->u.str.val_str;
9163 case V_CHARSYMS:
9164 return v->u.char_syms->get_iso2022string();
9165 case V_USTR:
9166 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9167 // no break
9168 case V_ERROR:
9169 return string();
9170 default:
9171 error("Cannot use this value in ISO-2022 string context");
9172 return string();
9173 } // switch
9174 }
9175
9176 size_t Value::get_val_strlen()
9177 {
9178 Value *v = get_value_refd_last();
9179 switch (v->valuetype) {
9180 case V_BSTR:
9181 case V_HSTR:
9182 case V_CSTR:
9183 case V_ISO2022STR:
9184 return v->u.str.val_str->size();
9185 case V_OSTR:
9186 return v->u.str.val_str->size()/2;
9187 case V_CHARSYMS:
9188 return v->u.char_syms->get_len();
9189 case V_USTR:
9190 return v->u.ustr.val_ustr->size();
9191 case V_ERROR:
9192 return 0;
9193 default:
9194 error("Cannot use this value in string value context");
9195 return 0;
9196 } // switch
9197 }
9198
9199 Value::verdict_t Value::get_val_verdict()
9200 {
9201 switch(valuetype) {
9202 case V_VERDICT:
9203 return u.verdict;
9204 default:
9205 FATAL_ERROR("Value::get_val_verdict()");
9206 return u.verdict;
9207 } // switch
9208 }
9209
9210 size_t Value::get_nof_comps()
9211 {
9212 switch (valuetype) {
9213 case V_OID:
9214 case V_ROID:
9215 chk();
9216 return u.oid_comps->size();
9217 case V_SEQOF:
9218 case V_SETOF:
9219 case V_ARRAY:
9220 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9221 else return u.val_vs->get_nof_vs();
9222 case V_SEQ:
9223 case V_SET:
9224 return u.val_nvs->get_nof_nvs();
9225 case V_BSTR:
9226 case V_HSTR:
9227 case V_CSTR:
9228 case V_ISO2022STR:
9229 return u.str.val_str->size();
9230 case V_OSTR:
9231 return u.str.val_str->size()/2;
9232 case V_USTR:
9233 return u.ustr.val_ustr->size();
9234 default:
9235 FATAL_ERROR("Value::get_nof_comps()");
9236 return 0;
9237 } // switch
9238 }
9239
9240 bool Value::is_indexed() const
9241 {
9242 switch (valuetype) {
9243 case V_SEQOF:
9244 case V_SETOF:
9245 case V_ARRAY:
9246 // Applicable only for list-types. Assigning a record/SEQUENCE or
9247 // set/SET with indexed notation is not supported.
9248 return u.val_vs->is_indexed();
9249 default:
9250 FATAL_ERROR("Value::is_indexed()");
9251 break;
9252 }
9253 return false;
9254 }
9255
9256 const Identifier& Value::get_alt_name()
9257 {
9258 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9259 return *u.choice.alt_name;
9260 }
9261
9262 Value *Value::get_alt_value()
9263 {
9264 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9265 return u.choice.alt_value;
9266 }
9267
9268 void Value::set_alt_name_to_lowercase()
9269 {
9270 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9271 string new_name = u.choice.alt_name->get_name();
9272 if (isupper(new_name[0])) {
9273 new_name[0] = tolower(new_name[0]);
9274 if (new_name[new_name.size() - 1] == '_') {
9275 // an underscore is inserted at the end of the alternative name if it's
9276 // a basic type's name (since it would conflict with the class generated
9277 // for that type)
9278 // remove the underscore, it won't conflict with anything if its name
9279 // starts with a lowercase letter
9280 new_name.replace(new_name.size() - 1, 1, "");
9281 }
9282 delete u.choice.alt_name;
9283 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9284 }
9285 }
9286
9287 bool Value::has_oid_error()
9288 {
9289 Value *v;
9290 if (valuetype == V_REFD) v = get_value_refd_last();
9291 else v = this;
9292 switch (valuetype) {
9293 case V_OID:
9294 case V_ROID:
9295 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9296 if ((*v->u.oid_comps)[i]->has_error()) return true;
9297 return false;
9298 default:
9299 return true;
9300 }
9301 }
9302
9303 bool Value::get_oid_comps(vector<string>& comps)
9304 {
9305 bool ret_val = true;
9306 Value *v = this;
9307 switch (valuetype) {
9308 case V_REFD:
9309 v = get_value_refd_last();
9310 // no break
9311 case V_OID:
9312 case V_ROID:
9313 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9314 (*v->u.oid_comps)[i]->get_comps(comps);
9315 if ((*v->u.oid_comps)[i]->is_variable()) {
9316 // not all components can be calculated in compile-time
9317 ret_val = false;
9318 }
9319 }
9320 break;
9321 default:
9322 FATAL_ERROR("Value::get_oid_comps()");
9323 }
9324 return ret_val;
9325 }
9326
9327 void Value::add_se_comp(NamedValue* nv) {
9328 switch (valuetype) {
9329 case V_SEQ:
9330 case V_SET:
9331 if (!u.val_nvs)
9332 u.val_nvs = new NamedValues();
9333 u.val_nvs->add_nv(nv);
9334 break;
9335 default:
9336 FATAL_ERROR("Value::add_se_comp()");
9337 }
9338 }
9339
9340 NamedValue* Value::get_se_comp_byIndex(size_t n)
9341 {
9342 switch(valuetype) {
9343 case V_SEQ:
9344 case V_SET:
9345 return u.val_nvs->get_nv_byIndex(n);
9346 default:
9347 FATAL_ERROR("Value::get_se_comp_byIndex()");
9348 return 0;
9349 } // switch
9350 }
9351
9352 Value *Value::get_comp_byIndex(size_t n)
9353 {
9354 switch (valuetype) {
9355 case V_SEQOF:
9356 case V_SETOF:
9357 case V_ARRAY:
9358 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9359 return u.val_vs->get_iv_byIndex(n)->get_value();
9360 default:
9361 FATAL_ERROR("Value::get_comp_byIndex()");
9362 return 0;
9363 } // switch
9364 }
9365
9366 Value *Value::get_index_byIndex(size_t n)
9367 {
9368 switch (valuetype) {
9369 case V_SEQOF:
9370 case V_SETOF:
9371 case V_ARRAY:
9372 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9373 return u.val_vs->get_iv_byIndex(n)->get_index();
9374 default:
9375 FATAL_ERROR("Value::get_index_byIndex()");
9376 return 0;
9377 } // switch
9378 }
9379
9380 bool Value::has_comp_withName(const Identifier& p_name)
9381 {
9382 switch(valuetype) {
9383 case V_SEQ:
9384 case V_SET:
9385 return u.val_nvs->has_nv_withName(p_name);
9386 case V_CHOICE:
9387 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9388 default:
9389 FATAL_ERROR("Value::get_has_comp_withName()");
9390 return false;
9391 } // switch
9392 }
9393
9394 bool Value::field_is_chosen(const Identifier& p_name)
9395 {
9396 Value *v=get_value_refd_last();
9397 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9398 return *v->u.choice.alt_name==p_name;
9399 }
9400
9401 bool Value::field_is_present(const Identifier& p_name)
9402 {
9403 Value *v=get_value_refd_last();
9404 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9405 FATAL_ERROR("Value::field_is_present()");
9406 return v->u.val_nvs->has_nv_withName(p_name)
9407 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9408 ->get_value_refd_last()->valuetype != V_OMIT;
9409 }
9410
9411 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9412 {
9413 switch(valuetype) {
9414 case V_SEQ:
9415 case V_SET:
9416 return u.val_nvs->get_nv_byName(p_name);
9417 default:
9418 FATAL_ERROR("Value::get_se_comp_byName()");
9419 return 0;
9420 } // switch
9421 }
9422
9423 Value* Value::get_comp_value_byName(const Identifier& p_name)
9424 {
9425 switch(valuetype) {
9426 case V_SEQ:
9427 case V_SET:
9428 return u.val_nvs->get_nv_byName(p_name)->get_value();
9429 case V_CHOICE:
9430 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9431 return u.choice.alt_value;
9432 else
9433 return NULL;
9434 default:
9435 FATAL_ERROR("Value::get_se_comp_byName()");
9436 return 0;
9437 } // switch
9438 }
9439
9440 void Value::chk_dupl_id()
9441 {
9442 switch(valuetype) {
9443 case V_SEQ:
9444 case V_SET:
9445 u.val_nvs->chk_dupl_id();
9446 break;
9447 default:
9448 FATAL_ERROR("Value::chk_dupl_id()");
9449 } // switch
9450 }
9451
9452 size_t Value::get_nof_ids() const
9453 {
9454 switch(valuetype) {
9455 case V_NAMEDBITS:
9456 return u.ids->size();
9457 break;
9458 default:
9459 FATAL_ERROR("Value::get_nof_ids()");
9460 return 0;
9461 } // switch
9462 }
9463
9464 Identifier* Value::get_id_byIndex(size_t p_i)
9465 {
9466 switch(valuetype) {
9467 case V_NAMEDBITS:
9468 return u.ids->get_nth_elem(p_i);
9469 break;
9470 default:
9471 FATAL_ERROR("Value::get_id_byIndex()");
9472 return 0;
9473 } // switch
9474 }
9475
9476 bool Value::has_id(const Identifier& p_id)
9477 {
9478 switch(valuetype) {
9479 case V_NAMEDBITS:
9480 return u.ids->has_key(p_id.get_name());
9481 break;
9482 default:
9483 FATAL_ERROR("Value::has_id()");
9484 return false;
9485 } // switch
9486 }
9487
9488 Reference *Value::get_reference() const
9489 {
9490 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9491 return u.ref.ref;
9492 }
9493
9494 Reference *Value::get_refered() const
9495 {
9496 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9497 return u.refered;
9498 }
9499
9500 Common::Assignment *Value::get_refd_fat() const
9501 {
9502 switch(valuetype){
9503 case V_FUNCTION:
9504 case V_ALTSTEP:
9505 case V_TESTCASE:
9506 return u.refd_fat;
9507 default:
9508 FATAL_ERROR("Value::get_refd_fat()");
9509 }
9510 }
9511
9512 Ttcn::Reference* Value::steal_ttcn_ref()
9513 {
9514 Ttcn::Reference *ret_val =
9515 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9516 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9517 return ret_val;
9518 }
9519
9520 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9521 {
9522 Ttcn::Ref_base *t_ref;
9523 if(valuetype==V_REFD) {
9524 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9525 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9526 u.ref.ref=0;
9527 }
9528 else if(valuetype==V_UNDEF_LOWERID) {
9529 t_ref=new Ttcn::Reference(u.val_id);
9530 t_ref->set_location(*this);
9531 t_ref->set_fullname(get_fullname());
9532 t_ref->set_my_scope(get_my_scope());
9533 u.val_id=0;
9534 }
9535 else {
9536 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9537 t_ref = 0;
9538 }
9539 set_valuetype(V_ERROR);
9540 return t_ref;
9541 }
9542
9543 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9544 Ttcn::ActualParList*& p_ap)
9545 {
9546 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9547 p_v = u.invoke.v;
9548 u.invoke.v = 0;
9549 p_ti = u.invoke.t_list;
9550 u.invoke.t_list = 0;
9551 p_ap = u.invoke.ap_list;
9552 u.invoke.ap_list = 0;
9553 set_valuetype(V_ERROR);
9554 }
9555
9556 Common::Assignment* Value::get_refd_assignment()
9557 {
9558 switch(valuetype) {
9559 case V_FUNCTION:
9560 case V_ALTSTEP:
9561 case V_TESTCASE:
9562 return u.refd_fat;
9563 break;
9564 default:
9565 FATAL_ERROR("Value::get_refd_assignment()");
9566 return 0;
9567 }
9568 }
9569
9570 void Value::chk()
9571 {
9572 if(checked) return;
9573 switch(valuetype) {
9574 case V_OID: {
9575 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9576 " components");
9577 chk_OID(refch);
9578 break; }
9579 case V_ROID: {
9580 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9581 chk_ROID(refch);
9582 break; }
9583 default:
9584 break;
9585 } // switch
9586 checked=true;
9587 }
9588
9589 void Value::chk_OID(ReferenceChain& refch)
9590 {
9591 if (checked) return;
9592 if (valuetype != V_OID || u.oid_comps->size() < 1)
9593 FATAL_ERROR("Value::chk_OID()");
9594 if (!refch.add(get_fullname())) {
9595 checked = true;
9596 return;
9597 }
9598 OID_comp::oidstate_t state = OID_comp::START;
9599 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9600 refch.mark_state();
9601 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9602 refch.prev_state();
9603 }
9604 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9605 error("An OBJECT IDENTIFIER value must have at least "
9606 "two components"); // X.680 (07/2002) 31.10
9607 }
9608
9609 void Value::chk_ROID(ReferenceChain& refch)
9610 {
9611 if (checked) return;
9612 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9613 FATAL_ERROR("Value::chk_ROID()");
9614 if (!refch.add(get_fullname())) {
9615 checked = true;
9616 return;
9617 }
9618 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9619 refch.mark_state();
9620 (*u.oid_comps)[i]->chk_ROID(refch, i);
9621 refch.prev_state();
9622 }
9623 }
9624
9625 void Value::chk_recursions(ReferenceChain& refch)
9626 {
9627 if (recurs_checked) return;
9628 Value *v = get_value_refd_last();
9629 if (refch.add(v->get_fullname())) {
9630 switch (v->valuetype) {
9631 case V_CHOICE:
9632 v->u.choice.alt_value->chk_recursions(refch);
9633 break;
9634 case V_SEQOF:
9635 case V_SETOF:
9636 case V_ARRAY:
9637 if (!v->is_indexed()) {
9638 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9639 refch.mark_state();
9640 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9641 refch.prev_state();
9642 }
9643 } else {
9644 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9645 refch.mark_state();
9646 v->u.val_vs->get_iv_byIndex(i)->get_value()
9647 ->chk_recursions(refch);
9648 refch.prev_state();
9649 }
9650 }
9651 break;
9652 case V_SEQ:
9653 case V_SET:
9654 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9655 refch.mark_state();
9656 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9657 refch.prev_state();
9658 }
9659 break;
9660 case V_EXPR:
9661 chk_recursions_expr(refch);
9662 break;
9663 default:
9664 break;
9665 }
9666 if (v->err_descr) { // FIXME: make this work
9667 v->err_descr->chk_recursions(refch);
9668 }
9669 }
9670 recurs_checked = true;
9671 }
9672
9673 void Value::chk_recursions_expr(ReferenceChain& refch)
9674 {
9675 // first classify the unchecked ischosen() operation
9676 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9677 switch (u.expr.v_optype) {
9678 case OPTYPE_UNARYPLUS: // v1
9679 case OPTYPE_UNARYMINUS:
9680 case OPTYPE_NOT:
9681 case OPTYPE_NOT4B:
9682 case OPTYPE_BIT2HEX:
9683 case OPTYPE_BIT2INT:
9684 case OPTYPE_BIT2OCT:
9685 case OPTYPE_BIT2STR:
9686 case OPTYPE_CHAR2INT:
9687 case OPTYPE_CHAR2OCT:
9688 case OPTYPE_FLOAT2INT:
9689 case OPTYPE_FLOAT2STR:
9690 case OPTYPE_HEX2BIT:
9691 case OPTYPE_HEX2INT:
9692 case OPTYPE_HEX2OCT:
9693 case OPTYPE_HEX2STR:
9694 case OPTYPE_INT2CHAR:
9695 case OPTYPE_INT2FLOAT:
9696 case OPTYPE_INT2STR:
9697 case OPTYPE_INT2UNICHAR:
9698 case OPTYPE_OCT2BIT:
9699 case OPTYPE_OCT2CHAR:
9700 case OPTYPE_OCT2HEX:
9701 case OPTYPE_OCT2INT:
9702 case OPTYPE_OCT2STR:
9703 case OPTYPE_STR2BIT:
9704 case OPTYPE_STR2FLOAT:
9705 case OPTYPE_STR2HEX:
9706 case OPTYPE_STR2INT:
9707 case OPTYPE_STR2OCT:
9708 case OPTYPE_UNICHAR2INT:
9709 case OPTYPE_ENUM2INT:
9710 case OPTYPE_UNICHAR2CHAR:
9711 case OPTYPE_RNDWITHVAL:
9712 case OPTYPE_ISCHOSEN_V:
9713 case OPTYPE_GET_STRINGENCODING:
9714 case OPTYPE_REMOVE_BOM:
9715 case OPTYPE_DECODE_BASE64:
9716 refch.mark_state();
9717 u.expr.v1->chk_recursions(refch);
9718 refch.prev_state();
9719 break;
9720 case OPTYPE_ISCHOSEN_T:
9721 refch.mark_state();
9722 u.expr.t1->chk_recursions(refch);
9723 refch.prev_state();
9724 break;
9725 case OPTYPE_ADD: // v1 v2
9726 case OPTYPE_SUBTRACT:
9727 case OPTYPE_MULTIPLY:
9728 case OPTYPE_DIVIDE:
9729 case OPTYPE_MOD:
9730 case OPTYPE_REM:
9731 case OPTYPE_CONCAT:
9732 case OPTYPE_EQ:
9733 case OPTYPE_LT:
9734 case OPTYPE_GT:
9735 case OPTYPE_NE:
9736 case OPTYPE_GE:
9737 case OPTYPE_LE:
9738 case OPTYPE_AND:
9739 case OPTYPE_OR:
9740 case OPTYPE_XOR:
9741 case OPTYPE_AND4B:
9742 case OPTYPE_OR4B:
9743 case OPTYPE_XOR4B:
9744 case OPTYPE_SHL:
9745 case OPTYPE_SHR:
9746 case OPTYPE_ROTL:
9747 case OPTYPE_ROTR:
9748 case OPTYPE_INT2BIT:
9749 case OPTYPE_INT2HEX:
9750 case OPTYPE_INT2OCT:
9751 refch.mark_state();
9752 u.expr.v1->chk_recursions(refch);
9753 refch.prev_state();
9754 refch.mark_state();
9755 u.expr.v2->chk_recursions(refch);
9756 refch.prev_state();
9757 break;
9758 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9759 case OPTYPE_OCT2UNICHAR:
9760 case OPTYPE_ENCODE_BASE64:
9761 refch.mark_state();
9762 u.expr.v1->chk_recursions(refch);
9763 refch.prev_state();
9764 if (u.expr.v2) {
9765 refch.mark_state();
9766 u.expr.v2->chk_recursions(refch);
9767 refch.prev_state();
9768 }
9769 break;
9770 case OPTYPE_DECODE:
9771 chk_recursions_expr_decode(u.expr.r1, refch);
9772 chk_recursions_expr_decode(u.expr.r2, refch);
9773 break;
9774 case OPTYPE_SUBSTR:
9775 refch.mark_state();
9776 u.expr.ti1->chk_recursions(refch);
9777 refch.prev_state();
9778 refch.mark_state();
9779 u.expr.v2->chk_recursions(refch);
9780 refch.prev_state();
9781 refch.mark_state();
9782 u.expr.v3->chk_recursions(refch);
9783 refch.prev_state();
9784 break;
9785 case OPTYPE_REGEXP:
9786 refch.mark_state();
9787 u.expr.ti1->chk_recursions(refch);
9788 refch.prev_state();
9789 refch.mark_state();
9790 u.expr.t2->chk_recursions(refch);
9791 refch.prev_state();
9792 refch.mark_state();
9793 u.expr.v3->chk_recursions(refch);
9794 refch.prev_state();
9795 break;
9796 case OPTYPE_DECOMP: // v1 v2 v3
9797 refch.mark_state();
9798 u.expr.v1->chk_recursions(refch);
9799 refch.prev_state();
9800 refch.mark_state();
9801 u.expr.v2->chk_recursions(refch);
9802 refch.prev_state();
9803 refch.mark_state();
9804 u.expr.v3->chk_recursions(refch);
9805 refch.prev_state();
9806 break;
9807 case OPTYPE_REPLACE:
9808 refch.mark_state();
9809 u.expr.ti1->chk_recursions(refch);
9810 refch.prev_state();
9811 refch.mark_state();
9812 u.expr.v2->chk_recursions(refch);
9813 refch.prev_state();
9814 refch.mark_state();
9815 u.expr.v3->chk_recursions(refch);
9816 refch.prev_state();
9817 refch.mark_state();
9818 u.expr.ti4->chk_recursions(refch);
9819 refch.prev_state();
9820 break;
9821 case OPTYPE_LENGTHOF: // ti1
9822 case OPTYPE_SIZEOF: // ti1
9823 case OPTYPE_VALUEOF: // ti1
9824 case OPTYPE_ENCODE:
9825 case OPTYPE_ISPRESENT:
9826 case OPTYPE_TTCN2STRING:
9827 refch.mark_state();
9828 u.expr.ti1->chk_recursions(refch);
9829 refch.prev_state();
9830 break;
9831 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
9832 refch.mark_state();
9833 u.expr.ti1->chk_recursions(refch);
9834 refch.prev_state();
9835 if (u.expr.v2){
9836 refch.mark_state();
9837 u.expr.v2->chk_recursions(refch);
9838 refch.prev_state();
9839 }
9840 break;
9841 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
9842 chk_recursions_expr_decode(u.expr.r1, refch);
9843 chk_recursions_expr_decode(u.expr.r2, refch);
9844 if (u.expr.v3){
9845 refch.mark_state();
9846 u.expr.v3->chk_recursions(refch);
9847 refch.prev_state();
9848 }
9849 break;
9850 case OPTYPE_MATCH: // v1 t2
9851 refch.mark_state();
9852 u.expr.v1->chk_recursions(refch);
9853 refch.prev_state();
9854 refch.mark_state();
9855 u.expr.t2->chk_recursions(refch);
9856 refch.prev_state();
9857 break;
9858 case OPTYPE_LOG2STR:
9859 case OPTYPE_ANY2UNISTR:
9860 u.expr.logargs->chk_recursions(refch);
9861 break;
9862 default:
9863 break;
9864 } // switch
9865 }
9866
9867 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9868 ReferenceChain& refch) {
9869 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9870 Assignment *ass = ref->get_refd_assignment();
9871 if (!ass) {
9872 set_valuetype(V_ERROR);
9873 return;
9874 }
9875 switch (ass->get_asstype()) {
9876 case Assignment::A_CONST:
9877 case Assignment::A_EXT_CONST:
9878 case Assignment::A_MODULEPAR:
9879 case Assignment::A_VAR:
9880 case Assignment::A_PAR_VAL_IN:
9881 case Assignment::A_PAR_VAL_OUT:
9882 case Assignment::A_PAR_VAL_INOUT: {
9883 Value* v = new Value(V_REFD, ref);
9884 v->set_location(*ref);
9885 v->set_my_scope(get_my_scope());
9886 v->set_fullname(get_fullname()+".<operand>");
9887 refch.mark_state();
9888 v->chk_recursions(refch);
9889 refch.prev_state();
9890 delete v;
9891 break; }
9892 case Assignment::A_MODULEPAR_TEMP:
9893 case Assignment::A_TEMPLATE:
9894 case Assignment::A_VAR_TEMPLATE:
9895 case Assignment::A_PAR_TEMPL_IN:
9896 case Assignment::A_PAR_TEMPL_OUT:
9897 case Assignment::A_PAR_TEMPL_INOUT: {
9898 Template* t = new Template(ref->clone());
9899 t->set_location(*ref);
9900 t->set_my_scope(get_my_scope());
9901 t->set_fullname(get_fullname()+".<operand>");
9902 refch.mark_state();
9903 t->chk_recursions(refch);
9904 refch.prev_state();
9905 delete t;
9906 break; }
9907 default:
9908 // remain silent, the error has been already reported
9909 set_valuetype(V_ERROR);
9910 break;
9911 } // switch
9912 }
9913
9914 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9915 {
9916 bool self_ref = false;
9917 switch (t->get_templatetype()) {
9918 case Ttcn::Template::SPECIFIC_VALUE: {
9919 Value *v = t->get_specific_value();
9920 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9921 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9922 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9923 break; }
9924 case Ttcn::Template::TEMPLATE_REFD: {
9925 Ttcn::Ref_base *refb = t->get_reference();
9926 Common::Assignment *ass = refb->get_refd_assignment();
9927 self_ref |= (ass == lhs);
9928 break; }
9929 case Ttcn::Template::ALL_FROM:
9930 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9931 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9932 break;
9933 case Ttcn::Template::TEMPLATE_LIST:
9934 case Ttcn::Template::SUPERSET_MATCH:
9935 case Ttcn::Template::SUBSET_MATCH:
9936 case Ttcn::Template::PERMUTATION_MATCH:
9937 case Ttcn::Template::COMPLEMENTED_LIST:
9938 case Ttcn::Template::VALUE_LIST: {
9939 size_t num = t->get_nof_comps();
9940 for (size_t i = 0; i < num; ++i) {
9941 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9942 }
9943 break; }
9944 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9945 // case Ttcn::Template::TEMPLATE_LIST: {
9946 // size_t num = t->get_nof_listitems();
9947 // for (size_t i=0; i < num; ++i) {
9948 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9949 // }
9950 // break; }
9951 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9952 size_t nnt = t->get_nof_comps();
9953 for (size_t i=0; i < nnt; ++i) {
9954 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9955 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9956 }
9957 break; }
9958 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9959 size_t nnt = t->get_nof_comps();
9960 for (size_t i=0; i < nnt; ++i) {
9961 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9962 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9963 }
9964 break; }
9965 case Ttcn::Template::VALUE_RANGE: {
9966 Ttcn::ValueRange *vr = t->get_value_range();
9967 Common::Value *v = vr->get_min_v();
9968 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9969 v = vr->get_max_v();
9970 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9971 break; }
9972 case Ttcn::Template::CSTR_PATTERN:
9973 case Ttcn::Template::USTR_PATTERN: {
9974 Ttcn::PatternString *ps = t->get_cstr_pattern();
9975 self_ref |= ps->chk_self_ref(lhs);
9976 break; }
9977 case Ttcn::Template::BSTR_PATTERN:
9978 case Ttcn::Template::HSTR_PATTERN:
9979 case Ttcn::Template::OSTR_PATTERN: {
9980 // FIXME: cannot access u.pattern
9981 break; }
9982 case Ttcn::Template::ANY_VALUE:
9983 case Ttcn::Template::ANY_OR_OMIT:
9984 case Ttcn::Template::OMIT_VALUE:
9985 case Ttcn::Template::TEMPLATE_NOTUSED:
9986 break; // self-ref can't happen
9987 case Ttcn::Template::TEMPLATE_INVOKE:
9988 break; // assume self-ref can't happen
9989 case Ttcn::Template::TEMPLATE_ERROR:
9990 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9991 break;
9992 // default:
9993 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9994 // break; // and hope for the best
9995 }
9996 return self_ref;
9997 }
9998
9999 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
10000 {
10001 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
10002 namedbool is_str_elem = NOT_STR_ELEM;
10003 if (v->valuetype == V_REFD) {
10004 Reference *ref = v->get_reference();
10005 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
10006 if (subrefs && subrefs->refers_to_string_element()) {
10007 is_str_elem = IS_STR_ELEM;
10008 }
10009 }
10010 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
10011 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
10012 is_str_elem);
10013 }
10014
10015 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
10016 {
10017 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
10018 if (!lhs) FATAL_ERROR("no lhs!");
10019 bool self_ref = false;
10020 switch (u.expr.v_optype) {
10021 case OPTYPE_RND: // -
10022 case OPTYPE_TESTCASENAME: // -
10023 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
10024 case OPTYPE_COMP_MTC: // -
10025 case OPTYPE_COMP_SYSTEM: // -
10026 case OPTYPE_COMP_SELF: // -
10027 case OPTYPE_COMP_RUNNING_ANY: // -
10028 case OPTYPE_COMP_RUNNING_ALL: // -
10029 case OPTYPE_COMP_ALIVE_ANY: // -
10030 case OPTYPE_COMP_ALIVE_ALL: // -
10031 case OPTYPE_TMR_RUNNING_ANY: // -
10032 case OPTYPE_GETVERDICT: // -
10033 case OPTYPE_PROF_RUNNING: // -
10034 break; // nothing to do
10035
10036 case OPTYPE_MATCH: // v1 t2
10037 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
10038 // no break
10039 case OPTYPE_UNARYPLUS: // v1
10040 case OPTYPE_UNARYMINUS: // v1
10041 case OPTYPE_NOT: // v1
10042 case OPTYPE_NOT4B: // v1
10043 case OPTYPE_BIT2HEX: // v1
10044 case OPTYPE_BIT2INT: // v1
10045 case OPTYPE_BIT2OCT: // v1
10046 case OPTYPE_BIT2STR: // v1
10047 case OPTYPE_CHAR2INT: // v1
10048 case OPTYPE_CHAR2OCT: // v1
10049 case OPTYPE_FLOAT2INT: // v1
10050 case OPTYPE_FLOAT2STR: // v1
10051 case OPTYPE_HEX2BIT: // v1
10052 case OPTYPE_HEX2INT: // v1
10053 case OPTYPE_HEX2OCT: // v1
10054 case OPTYPE_HEX2STR: // v1
10055 case OPTYPE_INT2CHAR: // v1
10056 case OPTYPE_INT2FLOAT: // v1
10057 case OPTYPE_INT2STR: // v1
10058 case OPTYPE_INT2UNICHAR: // v1
10059 case OPTYPE_OCT2BIT: // v1
10060 case OPTYPE_OCT2CHAR: // v1
10061 case OPTYPE_OCT2HEX: // v1
10062 case OPTYPE_OCT2INT: // v1
10063 case OPTYPE_OCT2STR: // v1
10064 case OPTYPE_STR2BIT: // v1
10065 case OPTYPE_STR2FLOAT: // v1
10066 case OPTYPE_STR2HEX: // v1
10067 case OPTYPE_STR2INT: // v1
10068 case OPTYPE_STR2OCT: // v1
10069 case OPTYPE_UNICHAR2INT: // v1
10070 case OPTYPE_UNICHAR2CHAR: // v1
10071 case OPTYPE_ENUM2INT: // v1
10072 case OPTYPE_RNDWITHVAL: // v1
10073 case OPTYPE_COMP_RUNNING: // v1
10074 case OPTYPE_COMP_ALIVE: // v1
10075 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
10076 case OPTYPE_GET_STRINGENCODING:
10077 case OPTYPE_DECODE_BASE64:
10078 case OPTYPE_REMOVE_BOM:
10079 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10080 break;
10081 case OPTYPE_ADD: // v1 v2
10082 case OPTYPE_SUBTRACT: // v1 v2
10083 case OPTYPE_MULTIPLY: // v1 v2
10084 case OPTYPE_DIVIDE: // v1 v2
10085 case OPTYPE_MOD: // v1 v2
10086 case OPTYPE_REM: // v1 v2
10087 case OPTYPE_CONCAT: // v1 v2
10088 case OPTYPE_EQ: // v1 v2
10089 case OPTYPE_LT: // v1 v2
10090 case OPTYPE_GT: // v1 v2
10091 case OPTYPE_NE: // v1 v2
10092 case OPTYPE_GE: // v1 v2
10093 case OPTYPE_LE: // v1 v2
10094 case OPTYPE_AND: // v1 v2
10095 case OPTYPE_OR: // v1 v2
10096 case OPTYPE_XOR: // v1 v2
10097 case OPTYPE_AND4B: // v1 v2
10098 case OPTYPE_OR4B: // v1 v2
10099 case OPTYPE_XOR4B: // v1 v2
10100 case OPTYPE_SHL: // v1 v2
10101 case OPTYPE_SHR: // v1 v2
10102 case OPTYPE_ROTL: // v1 v2
10103 case OPTYPE_ROTR: // v1 v2
10104 case OPTYPE_INT2BIT: // v1 v2
10105 case OPTYPE_INT2HEX: // v1 v2
10106 case OPTYPE_INT2OCT: // v1 v2
10107 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10108 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10109 break;
10110 case OPTYPE_UNICHAR2OCT: // v1 [v2]
10111 case OPTYPE_OCT2UNICHAR:
10112 case OPTYPE_ENCODE_BASE64:
10113 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10114 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10115 break;
10116 case OPTYPE_DECOMP: // v1 v2 v3
10117 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10118 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10119 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10120 break;
10121
10122 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
10123 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
10124 // no break
10125 case OPTYPE_SUBSTR: // ti1 v2 v3
10126 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10127 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
10128 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
10129 break;
10130
10131 case OPTYPE_REGEXP: // ti1 t2 v3
10132 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10133 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
10134 // no break
10135 case OPTYPE_LENGTHOF: // ti1
10136 case OPTYPE_SIZEOF: // ti1
10137 case OPTYPE_VALUEOF: // ti1
10138 case OPTYPE_ENCODE: // ti1
10139 case OPTYPE_TTCN2STRING:
10140 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10141 break;
10142 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
10143 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10144 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10145 break;
10146 case OPTYPE_DECVALUE_UNICHAR: { // r1 r2 [v3]
10147 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10148 self_ref |= (ass == lhs);
10149 if (u.expr.v3) self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10150 goto label_r1;
10151 break; }
10152 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
10153 // component.create -- assume no self-ref
10154 case OPTYPE_ACTIVATE: // r1
10155 // defaultref := activate(altstep) -- assume no self-ref
10156 case OPTYPE_TMR_RUNNING: // r1
10157 // boolvar := a_timer.running -- assume no self-ref
10158 break;
10159 break;
10160
10161 case OPTYPE_ANY2UNISTR:
10162 case OPTYPE_LOG2STR: {// logargs
10163 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
10164 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
10165 switch (la->get_type()) {
10166 case Ttcn::LogArgument::L_UNDEF:
10167 case Ttcn::LogArgument::L_ERROR:
10168 FATAL_ERROR("%s argument type",
10169 u.expr.v_optype == OPTYPE_ANY2UNISTR ? "any2unistr" : "log2str");
10170 break; // not reached
10171
10172 case Ttcn::LogArgument::L_MACRO:
10173 case Ttcn::LogArgument::L_STR:
10174 break; // self reference not possible
10175
10176 case Ttcn::LogArgument::L_VAL:
10177 case Ttcn::LogArgument::L_MATCH:
10178 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
10179 break;
10180
10181 case Ttcn::LogArgument::L_REF: {
10182 Ttcn::Ref_base *ref = la->get_ref();
10183 Common::Assignment *ass = ref->get_refd_assignment();
10184 self_ref |= (ass == lhs);
10185 break; }
10186
10187 case Ttcn::LogArgument::L_TI: {
10188 Ttcn::TemplateInstance *ti = la->get_ti();
10189 Ttcn::Template *t = ti->get_Template();
10190 self_ref |= chk_expr_self_ref_templ(t, lhs);
10191 break; }
10192
10193 // no default please
10194 } // switch la->logargtype
10195 }
10196 break; }
10197
10198 case OPTYPE_DECODE: { // r1 r2
10199 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10200 self_ref |= (ass == lhs);
10201 goto label_r1; }
10202 case OPTYPE_EXECUTE: // r1 [v2]
10203 if (u.expr.v2) {
10204 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10205 }
10206 label_r1:
10207 // no break
10208 case OPTYPE_UNDEF_RUNNING: // r1
10209 case OPTYPE_TMR_READ: { // r1
10210 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
10211 self_ref |= (ass == lhs);
10212 break; }
10213
10214 case OPTYPE_ISCHOSEN_T: // t1 i2
10215 case OPTYPE_ISBOUND: // ti1
10216 case OPTYPE_ISVALUE: // ti1
10217 case OPTYPE_ISPRESENT: { // ti1
10218 Ttcn::Template *t;
10219 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10220 else t = u.expr.ti1->get_Template();
10221 self_ref |= chk_expr_self_ref_templ(t, lhs);
10222 break; }
10223
10224 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10225 if (u.expr.v3) {
10226 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10227 }
10228 // no break
10229 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10230 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10231 // TODO t_list2
10232 break;
10233
10234 case NUMBER_OF_OPTYPES: // can never happen
10235 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10236 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10237 break;
10238 } // switch u.expr.v_optype
10239 return self_ref;
10240 }
10241
10242
10243 string Value::create_stringRepr()
10244 {
10245 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10246 switch (valuetype) {
10247 case V_ERROR:
10248 return string("<erroneous>");
10249 case V_NULL:
10250 return string("NULL");
10251 case V_BOOL:
10252 if (!parse_only && is_asn1()) {
10253 if (u.val_bool) return string("TRUE");
10254 else return string("FALSE");
10255 }
10256 else {
10257 if (u.val_bool) return string("true");
10258 else return string("false");
10259 }
10260 case V_INT:
10261 return u.val_Int->t_str();
10262 case V_REAL:
10263 return Real2string(u.val_Real);
10264 case V_ENUM:
10265 case V_NAMEDINT:
10266 case V_UNDEF_LOWERID:
10267 return u.val_id->get_name();
10268 case V_NAMEDBITS: {
10269 string ret_val("{ ");
10270 for (size_t i = 0; i < u.ids->size(); i++) {
10271 if (i>0) ret_val += ' ';
10272 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10273 }
10274 ret_val += '}';
10275 return ret_val; }
10276 case V_BSTR: {
10277 string ret_val('\'');
10278 ret_val += *u.str.val_str;
10279 ret_val += "'B";
10280 return ret_val; }
10281 case V_HSTR: {
10282 string ret_val('\'');
10283 ret_val += *u.str.val_str;
10284 ret_val += "'H";
10285 return ret_val; }
10286 case V_OSTR: {
10287 string ret_val('\'');
10288 ret_val += *u.str.val_str;
10289 ret_val += "'O";
10290 return ret_val; }
10291 case V_CSTR:
10292 case V_ISO2022STR:
10293 return u.str.val_str->get_stringRepr();
10294 case V_USTR:
10295 return u.ustr.val_ustr->get_stringRepr();
10296 case V_CHARSYMS:
10297 /** \todo stringrepr of V_CHARSYMS */
10298 return string("<sorry, string representation of charsyms "
10299 "not implemented>");
10300 case V_OID:
10301 case V_ROID: {
10302 string ret_val;
10303 if (parse_only || !is_asn1()) ret_val += "objid ";
10304 ret_val += "{ ";
10305 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10306 if (i>0) ret_val += ' ';
10307 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10308 }
10309 ret_val += " }";
10310 return ret_val; }
10311 case V_CHOICE:
10312 if (!parse_only && is_asn1()) {
10313 string ret_val(u.choice.alt_name->get_dispname());
10314 ret_val += " : ";
10315 ret_val += u.choice.alt_value->get_stringRepr();
10316 return ret_val;
10317 }
10318 else {
10319 string ret_val("{ ");
10320 ret_val += u.choice.alt_name->get_dispname();
10321 ret_val += " := ";
10322 ret_val += u.choice.alt_value->get_stringRepr();
10323 ret_val += " }";
10324 return ret_val;
10325 }
10326 case V_SEQOF:
10327 case V_SETOF:
10328 case V_ARRAY: {
10329 string ret_val("{ ");
10330 if (!is_indexed()) {
10331 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10332 if (i > 0) ret_val += ", ";
10333 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10334 }
10335 } else {
10336 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10337 if (i > 0) ret_val += ", ";
10338 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10339 }
10340 }
10341 ret_val += " }";
10342 return ret_val; }
10343 case V_SEQ:
10344 case V_SET: {
10345 string ret_val("{ ");
10346 bool asn1_flag = !parse_only && is_asn1();
10347 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10348 if (i > 0) ret_val += ", ";
10349 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10350 ret_val += nv->get_name().get_dispname();
10351 if (asn1_flag) ret_val += ' ';
10352 else ret_val += " := ";
10353 ret_val += nv->get_value()->get_stringRepr();
10354 }
10355 ret_val += " }";
10356 return ret_val; }
10357 case V_REFD: {
10358 // do not evaluate the reference if it is not done so far
10359 // (e.g. in parse-only mode)
10360 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10361 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10362 else return t_val->get_stringRepr(); }
10363 case V_OMIT:
10364 return string("omit");
10365 case V_VERDICT:
10366 switch (u.verdict) {
10367 case Verdict_NONE:
10368 return string("none");
10369 case Verdict_PASS:
10370 return string("pass");
10371 case Verdict_INCONC:
10372 return string("inconc");
10373 case Verdict_FAIL:
10374 return string("fail");
10375 case Verdict_ERROR:
10376 return string("error");
10377 default:
10378 return string("<unknown verdict value>");
10379 }
10380 case V_DEFAULT_NULL:
10381 case V_FAT_NULL:
10382 return string("null");
10383 case V_EXPR:
10384 switch (u.expr.v_optype) {
10385 case OPTYPE_RND:
10386 return string("rnd()");
10387 case OPTYPE_TESTCASENAME:
10388 return string("testcasename()");
10389 case OPTYPE_UNARYPLUS:
10390 return create_stringRepr_unary("+");
10391 case OPTYPE_UNARYMINUS:
10392 return create_stringRepr_unary("-");
10393 case OPTYPE_NOT:
10394 return create_stringRepr_unary("not");
10395 case OPTYPE_NOT4B:
10396 return create_stringRepr_unary("not4b");
10397 case OPTYPE_BIT2HEX:
10398 return create_stringRepr_predef1("bit2hex");
10399 case OPTYPE_BIT2INT:
10400 return create_stringRepr_predef1("bit2int");
10401 case OPTYPE_BIT2OCT:
10402 return create_stringRepr_predef1("bit2oct");
10403 case OPTYPE_BIT2STR:
10404 return create_stringRepr_predef1("bit2str");
10405 case OPTYPE_CHAR2INT:
10406 return create_stringRepr_predef1("char2int");
10407 case OPTYPE_CHAR2OCT:
10408 return create_stringRepr_predef1("char2oct");
10409 case OPTYPE_FLOAT2INT:
10410 return create_stringRepr_predef1("float2int");
10411 case OPTYPE_FLOAT2STR:
10412 return create_stringRepr_predef1("float2str");
10413 case OPTYPE_HEX2BIT:
10414 return create_stringRepr_predef1("hex2bit");
10415 case OPTYPE_HEX2INT:
10416 return create_stringRepr_predef1("hex2int");
10417 case OPTYPE_HEX2OCT:
10418 return create_stringRepr_predef1("hex2oct");
10419 case OPTYPE_HEX2STR:
10420 return create_stringRepr_predef1("hex2str");
10421 case OPTYPE_INT2CHAR:
10422 return create_stringRepr_predef1("int2char");
10423 case OPTYPE_INT2FLOAT:
10424 return create_stringRepr_predef1("int2float");
10425 case OPTYPE_INT2STR:
10426 return create_stringRepr_predef1("int2str");
10427 case OPTYPE_INT2UNICHAR:
10428 return create_stringRepr_predef1("int2unichar");
10429 case OPTYPE_OCT2BIT:
10430 return create_stringRepr_predef1("oct2bit");
10431 case OPTYPE_OCT2CHAR:
10432 return create_stringRepr_predef1("oct2char");
10433 case OPTYPE_OCT2HEX:
10434 return create_stringRepr_predef1("oct2hex");
10435 case OPTYPE_OCT2INT:
10436 return create_stringRepr_predef1("oct2int");
10437 case OPTYPE_OCT2STR:
10438 return create_stringRepr_predef1("oct2str");
10439 case OPTYPE_GET_STRINGENCODING:
10440 return create_stringRepr_predef1("get_stringencoding");
10441 case OPTYPE_REMOVE_BOM:
10442 return create_stringRepr_predef1("remove_bom");
10443 case OPTYPE_ENCODE_BASE64: {
10444 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10445 else return create_stringRepr_predef1("encode_base64");
10446 }
10447 case OPTYPE_DECODE_BASE64:
10448 return create_stringRepr_predef1("decode_base64");
10449 case OPTYPE_OCT2UNICHAR:{
10450 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10451 else return create_stringRepr_predef1("oct2unichar");
10452 }
10453 case OPTYPE_UNICHAR2OCT: {
10454 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10455 else return create_stringRepr_predef1("unichar2oct");
10456 }
10457 case OPTYPE_ENCVALUE_UNICHAR: {
10458 if (u.expr.v2) return create_stringRepr_predef2("encvalue_unichar");
10459 else return create_stringRepr_predef1("encvalue_unichar");
10460 }
10461 case OPTYPE_DECVALUE_UNICHAR: {
10462 if (u.expr.v3) {
10463 string ret_val("decvalue_unichar");
10464 ret_val += '(';
10465 ret_val += u.expr.v1->get_stringRepr();
10466 ret_val += ", ";
10467 ret_val += u.expr.v2->get_stringRepr();
10468 ret_val += ", ";
10469 ret_val += u.expr.v3->get_stringRepr();
10470 ret_val += ')';
10471 return ret_val;
10472 }
10473 else return create_stringRepr_predef2("decvalue_unichar");
10474 }
10475 case OPTYPE_STR2BIT:
10476 return create_stringRepr_predef1("str2bit");
10477 case OPTYPE_STR2FLOAT:
10478 return create_stringRepr_predef1("str2float");
10479 case OPTYPE_STR2HEX:
10480 return create_stringRepr_predef1("str2hex");
10481 case OPTYPE_STR2INT:
10482 return create_stringRepr_predef1("str2int");
10483 case OPTYPE_STR2OCT:
10484 return create_stringRepr_predef1("str2oct");
10485 case OPTYPE_UNICHAR2INT:
10486 return create_stringRepr_predef1("unichar2int");
10487 case OPTYPE_UNICHAR2CHAR:
10488 return create_stringRepr_predef1("unichar2char");
10489 case OPTYPE_ENUM2INT:
10490 return create_stringRepr_predef1("enum2int");
10491 case OPTYPE_ENCODE:
10492 return create_stringRepr_predef1("encvalue");
10493 case OPTYPE_DECODE:
10494 return create_stringRepr_predef2("decvalue");
10495 case OPTYPE_RNDWITHVAL:
10496 return create_stringRepr_predef1("rnd");
10497 case OPTYPE_ADD:
10498 return create_stringRepr_infix("+");
10499 case OPTYPE_SUBTRACT:
10500 return create_stringRepr_infix("-");
10501 case OPTYPE_MULTIPLY:
10502 return create_stringRepr_infix("*");
10503 case OPTYPE_DIVIDE:
10504 return create_stringRepr_infix("/");
10505 case OPTYPE_MOD:
10506 return create_stringRepr_infix("mod");
10507 case OPTYPE_REM:
10508 return create_stringRepr_infix("rem");
10509 case OPTYPE_CONCAT:
10510 return create_stringRepr_infix("&");
10511 case OPTYPE_EQ:
10512 return create_stringRepr_infix("==");
10513 case OPTYPE_LT:
10514 return create_stringRepr_infix("<");
10515 case OPTYPE_GT:
10516 return create_stringRepr_infix(">");
10517 case OPTYPE_NE:
10518 return create_stringRepr_infix("!=");
10519 case OPTYPE_GE:
10520 return create_stringRepr_infix(">=");
10521 case OPTYPE_LE:
10522 return create_stringRepr_infix("<=");
10523 case OPTYPE_AND:
10524 return create_stringRepr_infix("and");
10525 case OPTYPE_OR:
10526 return create_stringRepr_infix("or");
10527 case OPTYPE_XOR:
10528 return create_stringRepr_infix("xor");
10529 case OPTYPE_AND4B:
10530 return create_stringRepr_infix("and4b");
10531 case OPTYPE_OR4B:
10532 return create_stringRepr_infix("or4b");
10533 case OPTYPE_XOR4B:
10534 return create_stringRepr_infix("xor4b");
10535 case OPTYPE_SHL:
10536 return create_stringRepr_infix("<<");
10537 case OPTYPE_SHR:
10538 return create_stringRepr_infix(">>");
10539 case OPTYPE_ROTL:
10540 return create_stringRepr_infix("<@");
10541 case OPTYPE_ROTR:
10542 return create_stringRepr_infix("@>");
10543 case OPTYPE_INT2BIT:
10544 return create_stringRepr_predef2("int2bit");
10545 case OPTYPE_INT2HEX:
10546 return create_stringRepr_predef2("int2hex");
10547 case OPTYPE_INT2OCT:
10548 return create_stringRepr_predef2("int2oct");
10549 case OPTYPE_SUBSTR: {
10550 string ret_val("substr(");
10551 u.expr.ti1->append_stringRepr(ret_val);
10552 ret_val += ", ";
10553 ret_val += u.expr.v2->get_stringRepr();
10554 ret_val += ", ";
10555 ret_val += u.expr.v3->get_stringRepr();
10556 ret_val += ')';
10557 return ret_val;
10558 }
10559 case OPTYPE_REGEXP: {
10560 string ret_val("regexp(");
10561 u.expr.ti1->append_stringRepr(ret_val);
10562 ret_val += ", ";
10563 u.expr.t2->append_stringRepr(ret_val);
10564 ret_val += ", ";
10565 ret_val += u.expr.v3->get_stringRepr();
10566 ret_val += ')';
10567 return ret_val;
10568 }
10569 case OPTYPE_DECOMP: {
10570 string ret_val("decomp(");
10571 ret_val += u.expr.v1->get_stringRepr();
10572 ret_val += ", ";
10573 ret_val += u.expr.v2->get_stringRepr();
10574 ret_val += ", ";
10575 ret_val += u.expr.v3->get_stringRepr();
10576 ret_val += ')';
10577 return ret_val;
10578 }
10579 case OPTYPE_REPLACE: {
10580 string ret_val("replace(");
10581 u.expr.ti1->append_stringRepr(ret_val);
10582 ret_val += ", ";
10583 ret_val += u.expr.v2->get_stringRepr();
10584 ret_val += ", ";
10585 ret_val += u.expr.v3->get_stringRepr();
10586 ret_val += ", ";
10587 u.expr.ti4->append_stringRepr(ret_val);
10588 ret_val += ')';
10589 return ret_val;
10590 }
10591 case OPTYPE_ISPRESENT: {
10592 string ret_val("ispresent(");
10593 u.expr.ti1->append_stringRepr(ret_val);
10594 ret_val += ')';
10595 return ret_val; }
10596 case OPTYPE_ISCHOSEN: {
10597 string ret_val("ischosen(");
10598 ret_val += u.expr.r1->get_dispname();
10599 ret_val += '.';
10600 ret_val += u.expr.i2->get_dispname();
10601 ret_val += ')';
10602 return ret_val; }
10603 case OPTYPE_ISCHOSEN_V: {
10604 string ret_val("ischosen(");
10605 ret_val += u.expr.v1->get_stringRepr();
10606 ret_val += '.';
10607 ret_val += u.expr.i2->get_dispname();
10608 ret_val += ')';
10609 return ret_val; }
10610 case OPTYPE_ISCHOSEN_T: {
10611 string ret_val("ischosen(");
10612 ret_val += u.expr.t1->get_stringRepr();
10613 ret_val += '.';
10614 ret_val += u.expr.i2->get_dispname();
10615 ret_val += ')';
10616 return ret_val; }
10617 case OPTYPE_LENGTHOF: {
10618 string ret_val("lengthof(");
10619 u.expr.ti1->append_stringRepr(ret_val);
10620 ret_val += ')';
10621 return ret_val; }
10622 case OPTYPE_SIZEOF: {
10623 string ret_val("sizeof(");
10624 u.expr.ti1->append_stringRepr(ret_val);
10625 ret_val += ')';
10626 return ret_val; }
10627 case OPTYPE_ISVALUE: {
10628 string ret_val("isvalue(");
10629 u.expr.ti1->append_stringRepr(ret_val);
10630 ret_val += ')';
10631 return ret_val; }
10632 case OPTYPE_VALUEOF: {
10633 string ret_val("valueof(");
10634 u.expr.ti1->append_stringRepr(ret_val);
10635 ret_val += ')';
10636 return ret_val; }
10637 case OPTYPE_LOG2STR:
10638 return string("log2str(...)");
10639 case OPTYPE_ANY2UNISTR:
10640 return string("any2unistr(...)");
10641 case OPTYPE_MATCH: {
10642 string ret_val("match(");
10643 ret_val += u.expr.v1->get_stringRepr();
10644 ret_val += ", ";
10645 u.expr.t2->append_stringRepr(ret_val);
10646 ret_val += ')';
10647 return ret_val; }
10648 case OPTYPE_TTCN2STRING: {
10649 string ret_val("ttcn2string(");
10650 u.expr.ti1->append_stringRepr(ret_val);
10651 ret_val += ')';
10652 return ret_val;
10653 }
10654 case OPTYPE_UNDEF_RUNNING:
10655 return u.expr.r1->get_dispname() + ".running";
10656 case OPTYPE_COMP_NULL:
10657 return string("null");
10658 case OPTYPE_COMP_MTC:
10659 return string("mtc");
10660 case OPTYPE_COMP_SYSTEM:
10661 return string("system");
10662 case OPTYPE_COMP_SELF:
10663 return string("self");
10664 case OPTYPE_COMP_CREATE: {
10665 string ret_val(u.expr.r1->get_dispname());
10666 ret_val += ".create";
10667 if (u.expr.v2 || u.expr.v3) {
10668 ret_val += '(';
10669 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10670 else ret_val += '-';
10671 if (u.expr.v3) {
10672 ret_val += ", ";
10673 ret_val += u.expr.v3->get_stringRepr();
10674 }
10675 ret_val += ')';
10676 }
10677 if (u.expr.b4) ret_val += " alive";
10678 return ret_val; }
10679 case OPTYPE_COMP_RUNNING:
10680 return u.expr.v1->get_stringRepr() + ".running";
10681 case OPTYPE_COMP_RUNNING_ANY:
10682 return string("any component.running");
10683 case OPTYPE_COMP_RUNNING_ALL:
10684 return string("all component.running");
10685 case OPTYPE_COMP_ALIVE:
10686 return u.expr.v1->get_stringRepr() + ".alive";
10687 case OPTYPE_COMP_ALIVE_ANY:
10688 return string("any component.alive");
10689 case OPTYPE_COMP_ALIVE_ALL:
10690 return string("all component.alive");
10691 case OPTYPE_TMR_READ:
10692 return u.expr.r1->get_dispname() + ".read";
10693 case OPTYPE_TMR_RUNNING:
10694 return u.expr.r1->get_dispname() + ".running";
10695 case OPTYPE_TMR_RUNNING_ANY:
10696 return string("any timer.running");
10697 case OPTYPE_GETVERDICT:
10698 return string("getverdict");
10699 case OPTYPE_ACTIVATE: {
10700 string ret_val("activate(");
10701 ret_val += u.expr.r1->get_dispname();
10702 ret_val += ')';
10703 return ret_val; }
10704 case OPTYPE_ACTIVATE_REFD: {
10705 string ret_val("activate(derefer(");
10706 ret_val += u.expr.v1->get_stringRepr();
10707 ret_val += ")(";
10708 if (u.expr.state == EXPR_CHECKED) {
10709 if (u.expr.ap_list2) {
10710 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10711 for (size_t i = 0; i < nof_pars; i++) {
10712 if (i > 0) ret_val += ", ";
10713 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10714 }
10715 }
10716 } else {
10717 if (u.expr.t_list2) {
10718 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10719 for (size_t i = 0; i < nof_pars; i++) {
10720 if (i > 0) ret_val += ", ";
10721 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10722 }
10723 }
10724 }
10725 ret_val += "))";
10726 return ret_val; }
10727 case OPTYPE_EXECUTE: {
10728 string ret_val("execute(");
10729 ret_val += u.expr.r1->get_dispname();
10730 if (u.expr.v2) {
10731 ret_val += ", ";
10732 ret_val += u.expr.v2->get_stringRepr();
10733 }
10734 ret_val += ')';
10735 return ret_val; }
10736 case OPTYPE_EXECUTE_REFD: {
10737 string ret_val("execute(derefers(");
10738 ret_val += u.expr.v1->get_stringRepr();
10739 ret_val += ")(";
10740 if (u.expr.state == EXPR_CHECKED) {
10741 if (u.expr.ap_list2) {
10742 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10743 for (size_t i = 0; i < nof_pars; i++) {
10744 if (i > 0) ret_val += ", ";
10745 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10746 }
10747 }
10748 } else {
10749 if (u.expr.t_list2) {
10750 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10751 for (size_t i = 0; i < nof_pars; i++) {
10752 if (i > 0) ret_val += ", ";
10753 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10754 }
10755 }
10756 }
10757 ret_val += ')';
10758 if(u.expr.v3) {
10759 ret_val += ", ";
10760 ret_val += u.expr.v3->get_stringRepr();
10761 }
10762 ret_val += ')';
10763 return ret_val; }
10764 case OPTYPE_PROF_RUNNING:
10765 return string("@profiler.running");
10766 default:
10767 return string("<unsupported optype>");
10768 } // switch u.expr.v_optype
10769 case V_MACRO:
10770 switch (u.macro) {
10771 case MACRO_MODULEID:
10772 return string("%moduleId");
10773 case MACRO_FILENAME:
10774 return string("%fileName");
10775 case MACRO_BFILENAME:
10776 return string("__BFILE__");
10777 case MACRO_FILEPATH:
10778 return string("__FILE__");
10779 case MACRO_LINENUMBER:
10780 return string("%lineNumber");
10781 case MACRO_LINENUMBER_C:
10782 return string("__LINE__");
10783 case MACRO_DEFINITIONID:
10784 return string("%definitionId");
10785 case MACRO_SCOPE:
10786 return string("__SCOPE__");
10787 case MACRO_TESTCASEID:
10788 return string("%testcaseId");
10789 default:
10790 return string("<unknown macro>");
10791 } // switch u.macro
10792 case V_NOTUSED:
10793 return string('-');
10794 case V_FUNCTION:
10795 case V_ALTSTEP:
10796 case V_TESTCASE: {
10797 string ret_val("refers(");
10798 ret_val += u.refd_fat->get_assname();
10799 ret_val += ')';
10800 return ret_val; }
10801 case V_INVOKE: {
10802 string ret_val;
10803 ret_val += u.invoke.v->get_stringRepr();
10804 ret_val += ".apply(";
10805 if (u.invoke.ap_list) {
10806 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10807 for (size_t i = 0; i < nof_pars; i++) {
10808 if (i > 0) ret_val += ", ";
10809 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10810 }
10811 } else if (u.invoke.t_list) {
10812 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10813 for (size_t i = 0; i < nof_pars; i++) {
10814 if (i > 0) ret_val += ", ";
10815 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10816 }
10817 }
10818 ret_val += ')';
10819 return ret_val; }
10820 case V_REFER: {
10821 string ret_val("refers(");
10822 ret_val += u.refered->get_dispname();
10823 ret_val += ')';
10824 return ret_val; }
10825 default:
10826 return string("<unsupported valuetype>");
10827 } // switch valuetype
10828 }
10829
10830 string Value::create_stringRepr_unary(const char *operator_str)
10831 {
10832 string ret_val(operator_str);
10833 ret_val += '(';
10834 ret_val += u.expr.v1->get_stringRepr();
10835 ret_val += ')';
10836 return ret_val;
10837 }
10838
10839 string Value::create_stringRepr_infix(const char *operator_str)
10840 {
10841 string ret_val('(');
10842 ret_val += u.expr.v1->get_stringRepr();
10843 ret_val += ' ';
10844 ret_val += operator_str;
10845 ret_val += ' ';
10846 ret_val += u.expr.v2->get_stringRepr();
10847 ret_val += ')';
10848 return ret_val;
10849 }
10850
10851 string Value::create_stringRepr_predef1(const char *function_name)
10852 {
10853 string ret_val(function_name);
10854 ret_val += '(';
10855 if (u.expr.v_optype == OPTYPE_ENCODE || u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR) { // ti1, not v1
10856 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10857 }
10858 else ret_val += u.expr.v1->get_stringRepr();
10859 ret_val += ')';
10860 return ret_val;
10861 }
10862
10863 string Value::create_stringRepr_predef2(const char *function_name)
10864 {
10865 string ret_val(function_name);
10866 ret_val += '(';
10867 ret_val += u.expr.v1->get_stringRepr();
10868 ret_val += ", ";
10869 ret_val += u.expr.v2->get_stringRepr();
10870 ret_val += ')';
10871 return ret_val;
10872 }
10873
10874 bool Value::operator==(Value& val)
10875 {
10876 Value *left = get_value_refd_last();
10877 Type *left_governor = left->get_my_governor();
10878 if (left_governor) left_governor = left_governor->get_type_refd_last();
10879 Value *right = val.get_value_refd_last();
10880 Type *right_governor = right->get_my_governor();
10881 if (right_governor) right_governor = right_governor->get_type_refd_last();
10882 if (left_governor && right_governor
10883 && !left_governor->is_compatible(right_governor, NULL)
10884 && !right_governor->is_compatible(left_governor, NULL))
10885 FATAL_ERROR("Value::operator==");
10886
10887 // Not-A-Value is not equal to anything (NaN analogy:)
10888 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10889 return false;
10890
10891 switch (left->valuetype) {
10892 case V_NULL:
10893 case V_OMIT:
10894 case V_DEFAULT_NULL:
10895 case V_FAT_NULL:
10896 case V_NOTUSED:
10897 return left->valuetype == right->valuetype;
10898 case V_BOOL:
10899 return right->valuetype == V_BOOL &&
10900 left->get_val_bool() == right->get_val_bool();
10901 case V_INT:
10902 return right->valuetype == V_INT && *left->get_val_Int()
10903 == *right->get_val_Int();
10904 case V_REAL:
10905 return right->valuetype == V_REAL &&
10906 left->get_val_Real() == right->get_val_Real();
10907 case V_CSTR:
10908 switch (right->valuetype) {
10909 case V_CSTR:
10910 return left->get_val_str() == right->get_val_str();
10911 case V_USTR:
10912 return right->get_val_ustr() == left->get_val_str();
10913 case V_ISO2022STR:
10914 return right->get_val_iso2022str() == left->get_val_str();
10915 default:
10916 return false;
10917 }
10918 case V_BSTR:
10919 case V_HSTR:
10920 case V_OSTR:
10921 return left->valuetype == right->valuetype &&
10922 left->get_val_str() == right->get_val_str();
10923 case V_USTR:
10924 switch (right->valuetype) {
10925 case V_CSTR:
10926 return left->get_val_ustr() == right->get_val_str();
10927 case V_USTR:
10928 return left->get_val_ustr() == right->get_val_ustr();
10929 case V_ISO2022STR:
10930 return left->get_val_ustr() == right->get_val_iso2022str();
10931 default:
10932 return false;
10933 }
10934 case V_ISO2022STR:
10935 switch (right->valuetype) {
10936 case V_CSTR:
10937 return left->get_val_iso2022str() == right->get_val_str();
10938 case V_USTR:
10939 // The appropriate operator==() is missing. The operands are swapped,
10940 // but it shouldn't be a problem.
10941 return right->get_val_ustr() == left->get_val_iso2022str();
10942 case V_ISO2022STR:
10943 return left->get_val_iso2022str() == right->get_val_iso2022str();
10944 default:
10945 return false;
10946 }
10947 case V_ENUM:
10948 return right->valuetype == V_ENUM &&
10949 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10950 case V_OID:
10951 case V_ROID:
10952 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10953 vector<string> act, other;
10954 get_oid_comps(act);
10955 val.get_oid_comps(other);
10956 size_t act_size = act.size(), other_size = other.size();
10957 bool ret_val;
10958 if (act_size == other_size) {
10959 ret_val = true;
10960 for (size_t i = 0; i < act_size; i++)
10961 if (*act[i] != *other[i]) {
10962 ret_val = false;
10963 break;
10964 }
10965 } else ret_val = false;
10966 for (size_t i = 0; i < act_size; i++) delete act[i];
10967 act.clear();
10968 for (size_t i = 0; i < other_size; i++) delete other[i];
10969 other.clear();
10970 return ret_val;
10971 } else return false;
10972 case V_CHOICE:
10973 return right->valuetype == V_CHOICE &&
10974 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10975 *(left->get_alt_value()) == *(right->get_alt_value());
10976 case V_SEQ:
10977 case V_SET: {
10978 if (!left_governor) FATAL_ERROR("Value::operator==");
10979 if (left->valuetype != right->valuetype) return false;
10980 size_t nof_comps = left_governor->get_nof_comps();
10981 for (size_t i = 0; i < nof_comps; i++) {
10982 Value *lval = NULL, *rval = NULL;
10983 CompField* cfl = left_governor->get_comp_byIndex(i);
10984 const Identifier& field_name = cfl->get_name();
10985 if (left->has_comp_withName(field_name)) {
10986 lval = left->get_comp_value_byName(field_name);
10987 if (right->has_comp_withName(field_name)) {
10988 rval = right->get_comp_value_byName(field_name);
10989 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10990 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10991 return false;
10992 else if (!(*lval == *rval))
10993 return false;
10994 } else {
10995 if (cfl->has_default()) {
10996 if (!(*lval == *cfl->get_defval()))
10997 return false;
10998 } else {
10999 if (lval->valuetype != V_OMIT)
11000 return false;
11001 }
11002 }
11003 } else {
11004 if(right->has_comp_withName(field_name)) {
11005 rval = right->get_comp_value_byName(field_name);
11006 if(cfl->has_default()) {
11007 if(rval->valuetype==V_OMIT) return false;
11008 else {
11009 lval = cfl->get_defval();
11010 if (!(*lval==*rval)) return false;
11011 }
11012 }
11013 }
11014 }
11015 }
11016 return true; }
11017 case V_SEQOF:
11018 case V_ARRAY: {
11019 if (left->valuetype != right->valuetype) return false;
11020 size_t ncomps = get_nof_comps();
11021 if (ncomps != right->get_nof_comps()) return false;
11022
11023 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
11024 bool found = false;
11025 map<IndexedValue*, void> uncovered;
11026 for (size_t i = 0; i < left->get_nof_comps(); ++i)
11027 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
11028
11029 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
11030 found = false;
11031 for (size_t j = 0; j < uncovered.size(); ++j) {
11032 if (*(uncovered.get_nth_key(j)->get_value()) ==
11033 *(right->get_comp_byIndex(i)) &&
11034 *(uncovered.get_nth_key(j)->get_index()) ==
11035 *(right->get_index_byIndex(i))) {
11036 found = true;
11037 uncovered.erase(uncovered.get_nth_key(j));
11038 break;
11039 }
11040 }
11041 if (!found) break;
11042 }
11043 uncovered.clear();
11044 return found;
11045 } else if (left->is_indexed() || right->is_indexed()) {
11046 Value* indexed_one = 0;
11047 Value* not_indexed_one = 0;
11048
11049 if(left->is_indexed()) { // left is indexed, right is not
11050 indexed_one = left;
11051 not_indexed_one = right;
11052 } else { // right indexed, left is not
11053 indexed_one = right;
11054 not_indexed_one = left;
11055 }
11056
11057 for(size_t i = 0; i < ncomps; ++i) {
11058 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
11059 if(!(ind->valuetype == V_INT &&
11060 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
11061 *(indexed_one->get_comp_byIndex(i))))
11062 { return false; }
11063 }
11064 return true;
11065 } else { // none of them is indexed
11066 for (size_t i = 0; i < ncomps; i++) {
11067 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
11068 return false;
11069 }
11070 return true;
11071 }
11072 }
11073 case V_SETOF: {
11074 if (right->valuetype != V_SETOF) return false;
11075 size_t ncomps = get_nof_comps();
11076 if (ncomps != right->get_nof_comps()) return false;
11077 if (ncomps == 0) return true;
11078 map<size_t, void> uncovered;
11079 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
11080 for (size_t i = 0; i < ncomps; i++) {
11081 Value *left_item = left->get_comp_byIndex(i);
11082 bool pair_found = false;
11083 for (size_t j = 0; j < ncomps - i; j++) {
11084 size_t right_index = uncovered.get_nth_key(j);
11085 if (*left_item == *right->get_comp_byIndex(right_index)) {
11086 uncovered.erase(right_index);
11087 pair_found = true;
11088 break;
11089 }
11090 }
11091 if (!pair_found) {
11092 uncovered.clear();
11093 return false;
11094 }
11095 }
11096 return true; }
11097 case V_VERDICT:
11098 return right->valuetype == V_VERDICT &&
11099 left->get_val_verdict() == right->get_val_verdict();
11100 case V_FUNCTION:
11101 case V_ALTSTEP:
11102 case V_TESTCASE:
11103 return left->valuetype == right->valuetype &&
11104 left->get_refd_assignment() == right->get_refd_assignment();
11105 default:
11106 FATAL_ERROR("Value::operator==");
11107 }
11108 return true;
11109 }
11110
11111 bool Value::operator<(Value& val)
11112 {
11113 Value *left = get_value_refd_last();
11114 Type *left_governor = left->get_my_governor();
11115 if(left_governor) left_governor=left_governor->get_type_refd_last();
11116 Value *right = val.get_value_refd_last();
11117 Type *right_governor = right->get_my_governor();
11118 if(right_governor) right_governor=right_governor->get_type_refd_last();
11119 if (left->get_valuetype() != right->get_valuetype())
11120 FATAL_ERROR("Value::operator<");
11121 switch(valuetype){
11122 case V_INT:
11123 return *left->get_val_Int() < *right->get_val_Int();
11124 case V_REAL:
11125 return (left->get_val_Real() < right->get_val_Real());
11126 case V_ENUM:
11127 if(!left_governor || !right_governor)
11128 FATAL_ERROR("Value::operator<");
11129 if(left_governor!=right_governor)
11130 FATAL_ERROR("Value::operator<");
11131 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
11132 right_governor->get_enum_val_byId(*right->get_val_id()));
11133 default:
11134 FATAL_ERROR("Value::operator<");
11135 }
11136 return true;
11137 }
11138
11139 bool Value::is_string_type(Type::expected_value_t exp_val)
11140 {
11141 switch (get_expr_returntype(exp_val)) {
11142 case Type::T_CSTR:
11143 case Type::T_USTR:
11144 case Type::T_BSTR:
11145 case Type::T_HSTR:
11146 case Type::T_OSTR:
11147 return true;
11148 default:
11149 return false;
11150 }
11151 }
11152
11153 void Value::generate_code_expr(expression_struct *expr)
11154 {
11155 if (has_single_expr()) {
11156 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
11157 } else {
11158 switch (valuetype) {
11159 case V_EXPR:
11160 generate_code_expr_expr(expr);
11161 break;
11162 case V_CHOICE:
11163 case V_SEQOF:
11164 case V_SETOF:
11165 case V_ARRAY:
11166 case V_SEQ:
11167 case V_SET: {
11168 const string& tmp_id = get_temporary_id();
11169 const char *tmp_id_str = tmp_id.c_str();
11170 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11171 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
11172 set_genname_recursive(tmp_id);
11173 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11174 expr->expr = mputstr(expr->expr, tmp_id_str);
11175 break; }
11176 case V_INT: {
11177 const string& tmp_id = get_temporary_id();
11178 const char *tmp_id_str = tmp_id.c_str();
11179 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
11180 tmp_id_str);
11181 set_genname_recursive(tmp_id);
11182 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11183 expr->expr = mputstr(expr->expr, tmp_id_str);
11184 break; }
11185 case V_REFD: {
11186 if (!get_needs_conversion()) {
11187 u.ref.ref->generate_code_const_ref(expr);
11188 } else {
11189 Type *my_gov = get_expr_governor_last();
11190 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
11191 ->get_field_type(u.ref.ref->get_subrefs(),
11192 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
11193 // Make sure that nothing goes wrong.
11194 if (!my_gov || !refd_gov || my_gov == refd_gov)
11195 FATAL_ERROR("Value::generate_code_expr()");
11196 expression_struct expr_tmp;
11197 Code::init_expr(&expr_tmp);
11198 const string& tmp_id1 = get_temporary_id();
11199 const char *tmp_id_str1 = tmp_id1.c_str();
11200 const string& tmp_id2 = get_temporary_id();
11201 const char *tmp_id_str2 = tmp_id2.c_str();
11202 expr->preamble = mputprintf(expr->preamble,
11203 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
11204 tmp_id_str1);
11205 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11206 u.ref.ref->generate_code_const_ref(&expr_tmp);
11207 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11208 expr->preamble = mputprintf(expr->preamble,
11209 "%s %s;\n"
11210 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11211 "and `%s' are not compatible at run-time\");\n",
11212 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11213 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
11214 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
11215 ->get_typename().c_str(), refd_gov->get_typename().c_str());
11216 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11217 }
11218 break; }
11219 case V_INVOKE:
11220 generate_code_expr_invoke(expr);
11221 break;
11222 default:
11223 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
11224 }
11225 }
11226 }
11227
11228 void Value::generate_code_expr_mandatory(expression_struct *expr)
11229 {
11230 generate_code_expr(expr);
11231 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11232 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11233 }
11234
11235 bool Value::can_use_increment(Reference *ref) const
11236 {
11237 if (valuetype != V_EXPR) {
11238 return false;
11239 }
11240 switch (u.expr.v_optype) {
11241 case OPTYPE_ADD:
11242 case OPTYPE_SUBTRACT:
11243 break;
11244 default:
11245 return false;
11246 }
11247 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11248 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11249 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11250 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11251 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11252 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11253 return true;
11254 }
11255 return false;
11256 }
11257
11258 char *Value::generate_code_init(char *str, const char *name)
11259 {
11260 if (get_code_generated()) return str;
11261 if (err_descr) {
11262 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11263 }
11264 switch (valuetype) {
11265 case V_NULL:
11266 case V_BOOL:
11267 case V_REAL:
11268 case V_ENUM:
11269 case V_BSTR:
11270 case V_HSTR:
11271 case V_OSTR:
11272 case V_CSTR:
11273 case V_USTR:
11274 case V_ISO2022STR:
11275 case V_OID:
11276 case V_ROID:
11277 case V_VERDICT:
11278 case V_DEFAULT_NULL:
11279 case V_FAT_NULL:
11280 case V_FUNCTION:
11281 case V_ALTSTEP:
11282 case V_TESTCASE:
11283 // These values have a single string equivalent.
11284 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11285 break;
11286 case V_INT:
11287 if (u.val_Int->is_native_fit())
11288 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11289 else
11290 // It's always an INTEGER.
11291 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11292 "}\n", get_single_expr().c_str(), name);
11293 break;
11294 case V_EXPR:
11295 case V_INVOKE: {
11296 expression_struct expr;
11297 Code::init_expr(&expr);
11298 expr.expr = mputprintf(expr.expr, "%s = ", name);
11299 generate_code_expr(&expr);
11300 str = Code::merge_free_expr(str, &expr);
11301 break; }
11302 case V_CHOICE:
11303 str = generate_code_init_choice(str, name);
11304 break;
11305 case V_SEQOF:
11306 case V_SETOF:
11307 if (!is_indexed()) str = generate_code_init_seof(str, name);
11308 else str = generate_code_init_indexed(str, name);
11309 break;
11310 case V_ARRAY:
11311 if (!is_indexed()) str = generate_code_init_array(str, name);
11312 else str = generate_code_init_indexed(str, name);
11313 break;
11314 case V_SEQ:
11315 case V_SET:
11316 str = generate_code_init_se(str, name);
11317 break;
11318 case V_REFD:
11319 str = generate_code_init_refd(str, name);
11320 break;
11321 case V_MACRO:
11322 switch (u.macro) {
11323 case MACRO_TESTCASEID:
11324 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11325 break;
11326 default:
11327 // all others must already be evaluated away
11328 FATAL_ERROR("Value::generate_code_init()");
11329 }
11330 break;
11331 case V_NOTUSED:
11332 // unbound value, don't generate anything
11333 break;
11334 default:
11335 FATAL_ERROR("Value::generate_code_init()");
11336 }
11337 if (err_descr) {
11338 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11339 }
11340 set_code_generated();
11341 return str;
11342 }
11343
11344 char *Value::rearrange_init_code(char *str, Common::Module* usage_mod)
11345 {
11346 switch (valuetype) {
11347 case V_REFD: {
11348 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11349 if (parlist) {
11350 str = parlist->rearrange_init_code(str, usage_mod);
11351 }
11352 break; }
11353 case V_INVOKE: {
11354 str = u.invoke.v->rearrange_init_code(str, usage_mod);
11355 str = u.invoke.ap_list->rearrange_init_code(str, usage_mod);
11356 break; }
11357 case V_EXPR:
11358 switch (u.expr.v_optype) {
11359 case OPTYPE_UNARYPLUS:
11360 case OPTYPE_UNARYMINUS:
11361 case OPTYPE_NOT:
11362 case OPTYPE_NOT4B:
11363 case OPTYPE_BIT2HEX:
11364 case OPTYPE_BIT2INT:
11365 case OPTYPE_BIT2OCT:
11366 case OPTYPE_BIT2STR:
11367 case OPTYPE_CHAR2INT:
11368 case OPTYPE_CHAR2OCT:
11369 case OPTYPE_FLOAT2INT:
11370 case OPTYPE_FLOAT2STR:
11371 case OPTYPE_HEX2BIT:
11372 case OPTYPE_HEX2INT:
11373 case OPTYPE_HEX2OCT:
11374 case OPTYPE_HEX2STR:
11375 case OPTYPE_INT2CHAR:
11376 case OPTYPE_INT2FLOAT:
11377 case OPTYPE_INT2STR:
11378 case OPTYPE_INT2UNICHAR:
11379 case OPTYPE_OCT2BIT:
11380 case OPTYPE_OCT2CHAR:
11381 case OPTYPE_OCT2HEX:
11382 case OPTYPE_OCT2INT:
11383 case OPTYPE_OCT2STR:
11384 case OPTYPE_STR2BIT:
11385 case OPTYPE_STR2FLOAT:
11386 case OPTYPE_STR2HEX:
11387 case OPTYPE_STR2INT:
11388 case OPTYPE_STR2OCT:
11389 case OPTYPE_UNICHAR2INT:
11390 case OPTYPE_UNICHAR2CHAR:
11391 case OPTYPE_ENUM2INT:
11392 case OPTYPE_ISCHOSEN_V:
11393 case OPTYPE_GET_STRINGENCODING:
11394 case OPTYPE_REMOVE_BOM:
11395 case OPTYPE_DECODE_BASE64:
11396 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11397 break;
11398 case OPTYPE_DECODE: {
11399 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11400 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11401 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11402
11403 parlist = u.expr.r2->get_parlist();
11404 ass = u.expr.r2->get_refd_assignment();
11405 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11406 break; }
11407 case OPTYPE_ADD:
11408 case OPTYPE_SUBTRACT:
11409 case OPTYPE_MULTIPLY:
11410 case OPTYPE_DIVIDE:
11411 case OPTYPE_MOD:
11412 case OPTYPE_REM:
11413 case OPTYPE_CONCAT:
11414 case OPTYPE_EQ:
11415 case OPTYPE_LT:
11416 case OPTYPE_GT:
11417 case OPTYPE_NE:
11418 case OPTYPE_GE:
11419 case OPTYPE_LE:
11420 case OPTYPE_AND:
11421 case OPTYPE_OR:
11422 case OPTYPE_XOR:
11423 case OPTYPE_AND4B:
11424 case OPTYPE_OR4B:
11425 case OPTYPE_XOR4B:
11426 case OPTYPE_SHL:
11427 case OPTYPE_SHR:
11428 case OPTYPE_ROTL:
11429 case OPTYPE_ROTR:
11430 case OPTYPE_INT2BIT:
11431 case OPTYPE_INT2HEX:
11432 case OPTYPE_INT2OCT:
11433 //case OPTYPE_DECODE:
11434 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11435 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11436 break;
11437 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11438 case OPTYPE_OCT2UNICHAR:
11439 case OPTYPE_ENCODE_BASE64:
11440 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11441 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11442 break;
11443 case OPTYPE_SUBSTR:
11444 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11445 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11446 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11447 break;
11448 case OPTYPE_REGEXP:
11449 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11450 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11451 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11452 break;
11453 case OPTYPE_DECOMP:
11454 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11455 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11456 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11457 break;
11458 case OPTYPE_REPLACE:
11459 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11460 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11461 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11462 str = u.expr.ti4->rearrange_init_code(str, usage_mod);
11463 break;
11464 case OPTYPE_LENGTHOF:
11465 case OPTYPE_SIZEOF:
11466 case OPTYPE_VALUEOF:
11467 case OPTYPE_ENCODE:
11468 case OPTYPE_ISPRESENT:
11469 case OPTYPE_TTCN2STRING:
11470 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11471 break;
11472 case OPTYPE_ENCVALUE_UNICHAR:
11473 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11474 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11475 break;
11476 case OPTYPE_DECVALUE_UNICHAR: {
11477 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11478 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11479 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11480
11481 parlist = u.expr.r2->get_parlist();
11482 ass = u.expr.r2->get_refd_assignment();
11483 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11484 if (u.expr.v3) str = u.expr.v3->rearrange_init_code(str, usage_mod);
11485 break; }
11486 case OPTYPE_ISCHOSEN_T:
11487 str = u.expr.t1->rearrange_init_code(str, usage_mod);
11488 break;
11489 case OPTYPE_MATCH:
11490 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11491 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11492 break;
11493 default:
11494 // other kinds of expressions cannot appear within templates
11495 break;
11496 }
11497 break;
11498 default:
11499 break;
11500 }
11501 return str;
11502 }
11503
11504 char* Value::generate_code_tmp(char *str, const char *prefix,
11505 size_t& blockcount)
11506 {
11507 char *s2 = memptystr();
11508 char *s1 = generate_code_tmp(NULL, s2);
11509 if (s2[0]) {
11510 if (blockcount == 0) {
11511 str = mputstr(str, "{\n");
11512 blockcount++;
11513 }
11514 str = mputstr(str, s2);
11515 }
11516 Free(s2);
11517 str=mputstr(str, prefix);
11518 str=mputstr(str, s1);
11519 Free(s1);
11520 return str;
11521 }
11522
11523 char *Value::generate_code_tmp(char *str, char*& init)
11524 {
11525 expression_struct expr;
11526 Code::init_expr(&expr);
11527 generate_code_expr_mandatory(&expr);
11528 if (expr.preamble || expr.postamble) {
11529 if (valuetype == V_EXPR &&
11530 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11531 // a temporary variable is already introduced
11532 if (expr.preamble) init = mputstr(init, expr.preamble);
11533 if (expr.postamble) init = mputstr(init, expr.postamble);
11534 str = mputstr(str, expr.expr);
11535 } else {
11536 const string& tmp_id = get_temporary_id();
11537 const char *tmp_id_str = tmp_id.c_str();
11538 init = mputprintf(init, "%s %s;\n"
11539 "{\n",
11540 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11541 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11542 tmp_id_str);
11543 if (expr.preamble) init = mputstr(init, expr.preamble);
11544 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11545 if (expr.postamble) init = mputstr(init, expr.postamble);
11546 init = mputstr(init, "}\n");
11547 str = mputstr(str, tmp_id_str);
11548 }
11549 } else str = mputstr(str, expr.expr);
11550 Code::free_expr(&expr);
11551 return str;
11552 }
11553
11554 void Value::generate_code_log(expression_struct *expr)
11555 {
11556 if (explicit_cast_needed()) {
11557 char *expr_backup = expr->expr;
11558 expr->expr = NULL;
11559 generate_code_expr(expr);
11560 const string& tmp_id = get_temporary_id();
11561 const char *tmp_id_str = tmp_id.c_str();
11562 // We have to create a temporary object, because the parser of GCC
11563 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11564 // constructor call that is, this does not work: type(...).log(); but
11565 // this works: type tmp(...); tmp.log();.
11566 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11567 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11568 expr->expr);
11569 Free(expr->expr);
11570 expr->expr = mputstr(expr_backup, tmp_id_str);
11571 } else {
11572 generate_code_expr(expr);
11573 }
11574 expr->expr = mputstr(expr->expr, ".log()");
11575 }
11576
11577 void Value::generate_code_log_match(expression_struct *expr)
11578 {
11579 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11580 FATAL_ERROR("Value::generate_code_log_match()");
11581 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11582 // compliance the whole code-generation should be checked. Standalone
11583 // constructs like: "A(a[0].f());" should be avoided. The current
11584 // solution for HK38721 uses an additional assignment to overcome the
11585 // issue. The generated code will be slower, but it's needed for old GCC
11586 // versions in specific circumstances.
11587 if (u.expr.t2->needs_temp_ref()) {
11588 char *expr_backup = expr->expr;
11589 expr->expr = NULL;
11590 u.expr.t2->generate_code(expr);
11591 const string& tmp_id = get_temporary_id();
11592 const char *tmp_id_str = tmp_id.c_str();
11593 expr->preamble = mputprintf(expr->preamble,
11594 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11595 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11596 Free(expr->expr);
11597 expr->expr = mputstr(expr_backup, tmp_id_str);
11598 } else {
11599 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11600 // some reason "(A(NS::B)).a(C);" compiles fine.
11601 expr->expr = mputc(expr->expr, '(');
11602 u.expr.t2->generate_code(expr);
11603 expr->expr = mputc(expr->expr, ')');
11604 }
11605 expr->expr = mputstr(expr->expr, ".log_match(");
11606 u.expr.v1->generate_code_expr(expr);
11607 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11608 }
11609
11610 void Value::generate_code_expr_expr(expression_struct *expr)
11611 {
11612 switch (u.expr.v_optype) {
11613 case OPTYPE_RND:
11614 generate_code_expr_rnd(expr, 0);
11615 break;
11616 case OPTYPE_UNARYPLUS:
11617 // same as without the '+' operator
11618 u.expr.v1->generate_code_expr(expr);
11619 break;
11620 case OPTYPE_UNARYMINUS:
11621 generate_code_expr_unary(expr, "-", u.expr.v1);
11622 break;
11623 case OPTYPE_NOT:
11624 generate_code_expr_unary(expr, "!", u.expr.v1);
11625 break;
11626 case OPTYPE_NOT4B:
11627 generate_code_expr_unary(expr, "~", u.expr.v1);
11628 break;
11629 case OPTYPE_BIT2HEX:
11630 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11631 break;
11632 case OPTYPE_BIT2INT:
11633 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11634 break;
11635 case OPTYPE_BIT2OCT:
11636 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11637 break;
11638 case OPTYPE_BIT2STR:
11639 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11640 break;
11641 case OPTYPE_CHAR2INT:
11642 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11643 break;
11644 case OPTYPE_CHAR2OCT:
11645 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11646 break;
11647 case OPTYPE_FLOAT2INT:
11648 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11649 break;
11650 case OPTYPE_FLOAT2STR:
11651 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11652 break;
11653 case OPTYPE_HEX2BIT:
11654 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11655 break;
11656 case OPTYPE_HEX2INT:
11657 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11658 break;
11659 case OPTYPE_HEX2OCT:
11660 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11661 break;
11662 case OPTYPE_HEX2STR:
11663 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11664 break;
11665 case OPTYPE_INT2CHAR:
11666 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11667 break;
11668 case OPTYPE_INT2FLOAT:
11669 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11670 break;
11671 case OPTYPE_INT2STR:
11672 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11673 break;
11674 case OPTYPE_INT2UNICHAR:
11675 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11676 break;
11677 case OPTYPE_OCT2BIT:
11678 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11679 break;
11680 case OPTYPE_OCT2CHAR:
11681 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11682 break;
11683 case OPTYPE_GET_STRINGENCODING:
11684 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11685 break;
11686 case OPTYPE_REMOVE_BOM:
11687 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11688 break;
11689 case OPTYPE_ENCODE_BASE64:
11690 if (u.expr.v2)
11691 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11692 else
11693 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11694 break;
11695 case OPTYPE_DECODE_BASE64:
11696 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11697 break;
11698 case OPTYPE_OCT2UNICHAR:
11699 if (u.expr.v2)
11700 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11701 else
11702 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11703 break;
11704 case OPTYPE_UNICHAR2OCT:
11705 if (u.expr.v2)
11706 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11707 else
11708 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11709 break;
11710 case OPTYPE_ENCVALUE_UNICHAR:
11711 generate_code_expr_encvalue_unichar(expr);
11712 break;
11713 case OPTYPE_DECVALUE_UNICHAR:
11714 generate_code_expr_decvalue_unichar(expr);
11715 break;
11716 case OPTYPE_OCT2HEX:
11717 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11718 break;
11719 case OPTYPE_OCT2INT:
11720 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11721 break;
11722 case OPTYPE_OCT2STR:
11723 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11724 break;
11725 case OPTYPE_STR2BIT:
11726 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11727 break;
11728 case OPTYPE_STR2FLOAT:
11729 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11730 break;
11731 case OPTYPE_STR2HEX:
11732 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11733 break;
11734 case OPTYPE_STR2INT:
11735 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11736 break;
11737 case OPTYPE_STR2OCT:
11738 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11739 break;
11740 case OPTYPE_UNICHAR2INT:
11741 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11742 break;
11743 case OPTYPE_UNICHAR2CHAR:
11744 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11745 break;
11746 case OPTYPE_ENUM2INT: {
11747 Type* enum_type = u.expr.v1->get_expr_governor_last();
11748 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11749 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11750 enum_type->get_genname_value(my_scope).c_str());
11751 u.expr.v1->generate_code_expr_mandatory(expr);
11752 expr->expr = mputc(expr->expr, ')');
11753 break;}
11754 case OPTYPE_ENCODE:
11755 generate_code_expr_encode(expr);
11756 break;
11757 case OPTYPE_DECODE:
11758 generate_code_expr_decode(expr);
11759 break;
11760 case OPTYPE_RNDWITHVAL:
11761 generate_code_expr_rnd(expr, u.expr.v1);
11762 break;
11763 case OPTYPE_ADD:
11764 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11765 break;
11766 case OPTYPE_SUBTRACT:
11767 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11768 break;
11769 case OPTYPE_MULTIPLY:
11770 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11771 break;
11772 case OPTYPE_DIVIDE:
11773 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11774 break;
11775 case OPTYPE_MOD:
11776 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11777 break;
11778 case OPTYPE_REM:
11779 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11780 break;
11781 case OPTYPE_CONCAT:
11782 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11783 break;
11784 case OPTYPE_EQ:
11785 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11786 break;
11787 case OPTYPE_LT:
11788 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11789 break;
11790 case OPTYPE_GT:
11791 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11792 break;
11793 case OPTYPE_NE:
11794 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11795 break;
11796 case OPTYPE_GE:
11797 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11798 break;
11799 case OPTYPE_LE:
11800 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11801 break;
11802 case OPTYPE_AND:
11803 case OPTYPE_OR:
11804 generate_code_expr_and_or(expr);
11805 break;
11806 case OPTYPE_XOR:
11807 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11808 break;
11809 case OPTYPE_AND4B:
11810 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11811 break;
11812 case OPTYPE_OR4B:
11813 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11814 break;
11815 case OPTYPE_XOR4B:
11816 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11817 break;
11818 case OPTYPE_SHL:
11819 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11820 break;
11821 case OPTYPE_SHR:
11822 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11823 break;
11824 case OPTYPE_ROTL:
11825 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11826 break;
11827 case OPTYPE_ROTR:
11828 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11829 break;
11830 case OPTYPE_INT2BIT:
11831 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11832 break;
11833 case OPTYPE_INT2HEX:
11834 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11835 break;
11836 case OPTYPE_INT2OCT:
11837 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11838 break;
11839 case OPTYPE_SUBSTR:
11840 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11841 else generate_code_expr_substr_replace_compat(expr);
11842 break;
11843 case OPTYPE_REGEXP:
11844 generate_code_expr_regexp(expr);
11845 break;
11846 case OPTYPE_DECOMP:
11847 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11848 break;
11849 case OPTYPE_REPLACE:
11850 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11851 else generate_code_expr_substr_replace_compat(expr);
11852 break;
11853 case OPTYPE_ISCHOSEN: // r1 i2
11854 FATAL_ERROR("Value::generate_code_expr_expr()");
11855 break;
11856 case OPTYPE_ISCHOSEN_V: // v1 i2
11857 u.expr.v1->generate_code_expr_mandatory(expr);
11858 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11859 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11860 u.expr.i2->get_name().c_str());
11861 break;
11862 case OPTYPE_ISCHOSEN_T: // t1 i2
11863 u.expr.t1->generate_code_expr(expr);
11864 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11865 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11866 u.expr.i2->get_name().c_str());
11867 break;
11868 case OPTYPE_ISPRESENT:
11869 case OPTYPE_ISBOUND: {
11870 Template::templatetype_t temp = u.expr.ti1->get_Template()
11871 ->get_templatetype();
11872 if (temp == Template::SPECIFIC_VALUE) {
11873 Value* specific_value = u.expr.ti1->get_Template()
11874 ->get_specific_value();
11875 if (specific_value->get_valuetype() == Value::V_REFD) {
11876 Ttcn::Reference* reference =
11877 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11878 if (reference) {
11879 reference->generate_code_ispresentbound(expr, false,
11880 u.expr.v_optype==OPTYPE_ISBOUND);
11881 break;
11882 }
11883 }
11884 } else if (temp == Template::TEMPLATE_REFD){
11885 Ttcn::Reference* reference =
11886 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11887 ->get_reference());
11888 if (reference) {
11889 reference->generate_code_ispresentbound(expr, true,
11890 u.expr.v_optype==OPTYPE_ISBOUND);
11891 break;
11892 }
11893 }
11894 }
11895 // no break
11896 case OPTYPE_LENGTHOF: // ti1
11897 // fall through, separated later
11898 case OPTYPE_SIZEOF: // ti1
11899 // fall through, separated later
11900 case OPTYPE_ISVALUE: { // ti1
11901 if (u.expr.ti1->is_only_specific_value()) {
11902 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11903 bool cast_needed = t_val->explicit_cast_needed(
11904 u.expr.v_optype != OPTYPE_LENGTHOF);
11905 if(cast_needed) {
11906 // the ambiguous C++ expression is converted to the value class
11907 expr->expr = mputprintf(expr->expr, "%s(",
11908 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11909 }
11910
11911 if (u.expr.v_optype != OPTYPE_LENGTHOF
11912 && u.expr.v_optype != OPTYPE_SIZEOF) {
11913 t_val->generate_code_expr(expr);
11914 } else {
11915 t_val->generate_code_expr_mandatory(expr);
11916 }
11917
11918 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11919 }
11920 else u.expr.ti1->generate_code(expr);
11921
11922 switch (u.expr.v_optype) {
11923 case OPTYPE_ISBOUND:
11924 expr->expr=mputstr(expr->expr, ".is_bound()");
11925 break;
11926 case OPTYPE_ISPRESENT:
11927 expr->expr=mputprintf(expr->expr, ".is_present()");
11928 break;
11929 case OPTYPE_SIZEOF:
11930 expr->expr=mputstr(expr->expr, ".size_of()");
11931 break;
11932 case OPTYPE_LENGTHOF:
11933 expr->expr=mputstr(expr->expr, ".lengthof()");
11934 break;
11935 case OPTYPE_ISVALUE:
11936 expr->expr=mputstr(expr->expr, ".is_value()");
11937 break;
11938 default:
11939 FATAL_ERROR("Value::generate_code_expr_expr()");
11940 }
11941 break; }
11942 case OPTYPE_VALUEOF: // ti1
11943 u.expr.ti1->generate_code(expr);
11944 expr->expr = mputstr(expr->expr, ".valueof()");
11945 break;
11946 case OPTYPE_MATCH: // v1 t2
11947 u.expr.t2->generate_code(expr);
11948 expr->expr = mputstr(expr->expr, ".match(");
11949 u.expr.v1->generate_code_expr(expr);
11950 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11951 break;
11952 case OPTYPE_UNDEF_RUNNING:
11953 // it is resolved during semantic check
11954 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11955 break;
11956 case OPTYPE_COMP_NULL: // -
11957 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11958 break;
11959 case OPTYPE_COMP_MTC: // -
11960 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11961 break;
11962 case OPTYPE_COMP_SYSTEM: // -
11963 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11964 break;
11965 case OPTYPE_COMP_SELF: // -
11966 expr->expr=mputstr(expr->expr, "self");
11967 break;
11968 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11969 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11970 u.expr.b4);
11971 break;
11972 case OPTYPE_COMP_RUNNING: // v1
11973 u.expr.v1->generate_code_expr(expr);
11974 if(u.expr.v1->get_valuetype() == V_REFD)
11975 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11976 expr->expr = mputstr(expr->expr, ".running()");
11977 break;
11978 case OPTYPE_COMP_RUNNING_ANY: // -
11979 expr->expr=mputstr(expr->expr,
11980 "TTCN_Runtime::component_running(ANY_COMPREF)");
11981 break;
11982 case OPTYPE_COMP_RUNNING_ALL: // -
11983 expr->expr=mputstr(expr->expr,
11984 "TTCN_Runtime::component_running(ALL_COMPREF)");
11985 break;
11986 case OPTYPE_COMP_ALIVE: // v1
11987 u.expr.v1->generate_code_expr(expr);
11988 if(u.expr.v1->get_valuetype() == V_REFD)
11989 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11990 expr->expr = mputstr(expr->expr, ".alive()");
11991 break;
11992 case OPTYPE_COMP_ALIVE_ANY: // -
11993 expr->expr = mputstr(expr->expr,
11994 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11995 break;
11996 case OPTYPE_COMP_ALIVE_ALL: // -
11997 expr->expr = mputstr(expr->expr,
11998 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11999 break;
12000 case OPTYPE_TMR_READ: // r1
12001 u.expr.r1->generate_code(expr);
12002 expr->expr = mputstr(expr->expr, ".read()");
12003 break;
12004 case OPTYPE_TMR_RUNNING: // r1
12005 u.expr.r1->generate_code(expr);
12006 expr->expr = mputstr(expr->expr, ".running()");
12007 break;
12008 case OPTYPE_TMR_RUNNING_ANY: // -
12009 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
12010 break;
12011 case OPTYPE_GETVERDICT: // -
12012 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
12013 break;
12014 case OPTYPE_TESTCASENAME: // -
12015 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
12016 break;
12017 case OPTYPE_ACTIVATE: // r1
12018 generate_code_expr_activate(expr);
12019 break;
12020 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
12021 generate_code_expr_activate_refd(expr);
12022 break;
12023 case OPTYPE_EXECUTE: // r1 [v2]
12024 generate_code_expr_execute(expr);
12025 break;
12026 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
12027 generate_code_expr_execute_refd(expr);
12028 break;
12029 case OPTYPE_LOG2STR:
12030 case OPTYPE_ANY2UNISTR:
12031 u.expr.logargs->generate_code_expr(expr);
12032 break;
12033 case OPTYPE_TTCN2STRING: {
12034 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
12035 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
12036 param_governor = param_governor->get_type_refd_last();
12037 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
12038 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
12039 u.expr.ti1->get_Template()->is_Value()) {
12040 Value* v = u.expr.ti1->get_Template()->get_Value();
12041 delete u.expr.ti1;
12042 u.expr.ti1 = NULL;
12043 bool cast_needed = v->explicit_cast_needed();
12044 if (cast_needed) {
12045 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
12046 }
12047 v->generate_code_expr(expr);
12048 if (cast_needed) {
12049 expr->expr = mputstr(expr->expr, ")");
12050 }
12051 delete v;
12052 } else {
12053 u.expr.ti1->generate_code(expr);
12054 }
12055 expr->expr = mputstr(expr->expr, ")");
12056 } break;
12057 case OPTYPE_PROF_RUNNING:
12058 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
12059 break;
12060 default:
12061 FATAL_ERROR("Value::generate_code_expr_expr()");
12062 }
12063 }
12064
12065 void Value::generate_code_expr_unary(expression_struct *expr,
12066 const char *operator_str, Value *v1)
12067 {
12068 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
12069 v1->generate_code_expr_mandatory(expr);
12070 expr->expr = mputstrn(expr->expr, "))", 2);
12071 }
12072
12073 void Value::generate_code_expr_infix(expression_struct *expr,
12074 const char *operator_str, Value *v1,
12075 Value *v2, bool optional_allowed)
12076 {
12077 if (!get_needs_conversion()) {
12078 expr->expr = mputc(expr->expr, '(');
12079 if (optional_allowed) v1->generate_code_expr(expr);
12080 else v1->generate_code_expr_mandatory(expr);
12081 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
12082 if (optional_allowed) v2->generate_code_expr(expr);
12083 else v2->generate_code_expr_mandatory(expr);
12084 expr->expr = mputc(expr->expr, ')');
12085 } else { // Temporary variable for the converted value.
12086 const string& tmp_id1 = get_temporary_id();
12087 const char *tmp_id_str1 = tmp_id1.c_str();
12088 expression_struct expr_tmp;
12089 Code::init_expr(&expr_tmp);
12090 switch (u.expr.v_optype) {
12091 case OPTYPE_EQ:
12092 case OPTYPE_NE: {
12093 // Always "v1 -> v2".
12094 Type *t1 = v1->get_expr_governor_last();
12095 Type *t2 = v2->get_expr_governor_last();
12096 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
12097 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12098 else v2->generate_code_expr_mandatory(&expr_tmp);
12099 if (expr_tmp.preamble)
12100 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12101 expr->preamble = mputprintf(expr->preamble,
12102 "%s %s;\n"
12103 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12104 "and `%s' are not compatible at run-time\");\n",
12105 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
12106 TypeConv::get_conv_func(t2, t1, get_my_scope()
12107 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
12108 t2->get_typename().c_str(), t1->get_typename().c_str());
12109 Code::free_expr(&expr_tmp);
12110 if (optional_allowed) v1->generate_code_expr(expr);
12111 else v1->generate_code_expr_mandatory(expr);
12112 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
12113 tmp_id_str1);
12114 break; }
12115 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12116 // functions. The governors of all operands must exist at this point.
12117 case OPTYPE_ROTL:
12118 case OPTYPE_ROTR:
12119 case OPTYPE_CONCAT: {
12120 const string& tmp_id2 = get_temporary_id();
12121 const char *tmp_id_str2 = tmp_id2.c_str();
12122 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
12123 Type *my_gov = my_governor->get_type_refd_last();
12124 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
12125 ->get_type_refd_last();
12126 if (!t1_gov || my_gov == t1_gov)
12127 FATAL_ERROR("Value::generate_code_expr_infix()");
12128 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
12129 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
12130 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
12131 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
12132 else v1->generate_code_expr_mandatory(&expr_tmp);
12133 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
12134 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12135 else v2->generate_code_expr_mandatory(&expr_tmp);
12136 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
12137 expr->preamble = mputprintf(expr->preamble,
12138 "%s %s;\n"
12139 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12140 "and `%s' are not compatible at run-time\");\n",
12141 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
12142 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
12143 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
12144 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
12145 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
12146 break; }
12147 default:
12148 FATAL_ERROR("Value::generate_code_expr_infix()");
12149 break;
12150 }
12151 }
12152 }
12153
12154 void Value::generate_code_expr_and_or(expression_struct *expr)
12155 {
12156 if (u.expr.v2->needs_short_circuit()) {
12157 // introduce a temporary variable to store the result of the operation
12158 const string& tmp_id = get_temporary_id();
12159 const char *tmp_id_str = tmp_id.c_str();
12160 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
12161 expression_struct expr2;
12162 // the left operand must be evaluated anyway
12163 Code::init_expr(&expr2);
12164 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12165 u.expr.v1->generate_code_expr_mandatory(&expr2);
12166 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12167 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
12168 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
12169 // evaluate the right operand only when necessary
12170 // in this case the final result will be the right operand
12171 Code::init_expr(&expr2);
12172 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12173 u.expr.v2->generate_code_expr_mandatory(&expr2);
12174 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12175 // the result is now in the temporary variable
12176 expr->expr = mputstr(expr->expr, tmp_id_str);
12177 } else {
12178 // use the overloaded operator to get better error messages
12179 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
12180 "&&" : "||", u.expr.v1, u.expr.v2, false);
12181 }
12182 }
12183
12184 void Value::generate_code_expr_predef1(expression_struct *expr,
12185 const char *function_name,
12186 Value *v1)
12187 {
12188 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12189 v1->generate_code_expr_mandatory(expr);
12190 expr->expr = mputc(expr->expr, ')');
12191 }
12192
12193 void Value::generate_code_expr_predef2(expression_struct *expr,
12194 const char *function_name,
12195 Value *v1, Value *v2)
12196 {
12197 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12198 v1->generate_code_expr_mandatory(expr);
12199 expr->expr = mputstr(expr->expr, ", ");
12200 v2->generate_code_expr_mandatory(expr);
12201 expr->expr = mputc(expr->expr, ')');
12202 }
12203
12204 void Value::generate_code_expr_predef3(expression_struct *expr,
12205 const char *function_name,
12206 Value *v1, Value *v2, Value *v3)
12207 {
12208 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12209 v1->generate_code_expr_mandatory(expr);
12210 expr->expr = mputstr(expr->expr, ", ");
12211 v2->generate_code_expr_mandatory(expr);
12212 expr->expr = mputstr(expr->expr, ", ");
12213 v3->generate_code_expr_mandatory(expr);
12214 expr->expr = mputc(expr->expr, ')');
12215 }
12216
12217 void Value::generate_code_expr_substr(expression_struct *expr)
12218 {
12219 bool par1_is_str;
12220 Value* v1 = u.expr.ti1->get_specific_value();
12221 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12222 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12223 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
12224 if (v1) v1->generate_code_expr_mandatory(expr);
12225 else u.expr.ti1->generate_code(expr);
12226 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12227 else expr->expr = mputstr(expr->expr, ".substr(");
12228 if (!par1_is_str && u.expr.v2->is_unfoldable())
12229 expr->expr = mputstr(expr->expr, "(int)");
12230 u.expr.v2->generate_code_expr_mandatory(expr);
12231 expr->expr = mputstr(expr->expr, ", ");
12232 if (!par1_is_str && u.expr.v3->is_unfoldable())
12233 expr->expr = mputstr(expr->expr, "(int)");
12234 u.expr.v3->generate_code_expr_mandatory(expr);
12235 expr->expr = mputc(expr->expr, ')');
12236 }
12237
12238 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
12239 {
12240 expression_struct expr_tmp;
12241 Code::init_expr(&expr_tmp);
12242 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
12243 ->get_type_refd_last();
12244 if (!t1 || t1 == my_governor->get_type_refd_last())
12245 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12246 if (u.expr.v_optype == OPTYPE_SUBSTR) {
12247 generate_code_expr_substr(&expr_tmp);
12248 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
12249 generate_code_expr_replace(&expr_tmp);
12250 } else {
12251 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12252 }
12253 // Two temporaries to store the result of substr() or replace() and to
12254 // store the converted value.
12255 const string& tmp_id1 = get_temporary_id();
12256 const char *tmp_id_str1 = tmp_id1.c_str();
12257 const string& tmp_id2 = get_temporary_id();
12258 const char *tmp_id_str2 = tmp_id2.c_str();
12259 if (expr_tmp.preamble)
12260 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12261 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12262 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12263 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12264 if (expr_tmp.postamble)
12265 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12266 Code::free_expr(&expr_tmp);
12267 expr->preamble = mputprintf(expr->preamble,
12268 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12269 "`%s' are not compatible at run-time\");\n",
12270 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12271 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12272 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12273 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12274 }
12275
12276 void Value::generate_code_expr_regexp(expression_struct *expr)
12277 {
12278 Value* v1 = u.expr.ti1->get_specific_value();
12279 Value* v2 = u.expr.t2->get_specific_value();
12280 expr->expr = mputstr(expr->expr, "regexp(");
12281 if (v1) v1->generate_code_expr_mandatory(expr);
12282 else u.expr.ti1->generate_code(expr);
12283 expr->expr = mputstr(expr->expr, ", ");
12284 if (v2) v2->generate_code_expr_mandatory(expr);
12285 else u.expr.t2->generate_code(expr);
12286 expr->expr = mputstr(expr->expr, ", ");
12287 u.expr.v3->generate_code_expr_mandatory(expr);
12288 expr->expr = mputc(expr->expr, ')');
12289 }
12290
12291 void Value::generate_code_expr_replace(expression_struct *expr)
12292 {
12293 Value* v1 = u.expr.ti1->get_specific_value();
12294 Value* v4 = u.expr.ti4->get_specific_value();
12295 bool par1_is_str;
12296 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12297 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12298 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12299 if (v1) v1->generate_code_expr_mandatory(expr);
12300 else u.expr.ti1->generate_code(expr);
12301 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12302 else expr->expr = mputstr(expr->expr, ".replace(");
12303 if (!par1_is_str && u.expr.v2->is_unfoldable())
12304 expr->expr = mputstr(expr->expr, "(int)");
12305 u.expr.v2->generate_code_expr_mandatory(expr);
12306 expr->expr = mputstr(expr->expr, ", ");
12307 if (!par1_is_str && u.expr.v3->is_unfoldable())
12308 expr->expr = mputstr(expr->expr, "(int)");
12309 u.expr.v3->generate_code_expr_mandatory(expr);
12310 expr->expr = mputstr(expr->expr, ", ");
12311 if (v4) {
12312 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12313 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12314 Value* v4_last = v4->get_value_refd_last();
12315 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12316 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12317 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
12318 }
12319 v4->generate_code_expr_mandatory(expr);
12320 }
12321 else u.expr.ti4->generate_code(expr);
12322 expr->expr = mputc(expr->expr, ')');
12323 }
12324
12325 void Value::generate_code_expr_rnd(expression_struct *expr,
12326 Value *v1)
12327 {
12328 if(!v1) // simple random generation
12329 expr->expr = mputstr(expr->expr, "rnd()");
12330 else { // random generation with seeding
12331 expr->expr = mputstr(expr->expr, "rnd(");
12332 v1->generate_code_expr_mandatory(expr);
12333 expr->expr = mputc(expr->expr, ')');
12334 }
12335 }
12336
12337 void Value::generate_code_expr_create(expression_struct *expr,
12338 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12339 {
12340 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12341 // first two arguments: component type
12342 Assignment *t_ass = type->get_refd_assignment();
12343 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12344 FATAL_ERROR("Value::generate_code_expr_create()");
12345 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12346 Type::EXPECTED_DYNAMIC_VALUE);
12347 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12348 comptype = comptype->get_type_refd_last();
12349 expr->expr = comptype->get_CompBody()
12350 ->generate_code_comptype_name(expr->expr);
12351 expr->expr = mputstr(expr->expr, ", ");
12352 // third argument: component name
12353 if (name) {
12354 Value *t_val = name->get_value_refd_last();
12355 if (t_val->valuetype == V_CSTR) {
12356 // the argument is foldable to a string literal
12357 size_t str_len = t_val->u.str.val_str->size();
12358 const char *str_ptr = t_val->u.str.val_str->c_str();
12359 expr->expr = mputc(expr->expr, '"');
12360 for (size_t i = 0; i < str_len; i++)
12361 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12362 expr->expr = mputc(expr->expr, '"');
12363 } else name->generate_code_expr_mandatory(expr);
12364 } else expr->expr = mputstr(expr->expr, "NULL");
12365 expr->expr = mputstr(expr->expr, ", ");
12366 // fourth argument: location
12367 if (location) {
12368 Value *t_val = location->get_value_refd_last();
12369 if (t_val->valuetype == V_CSTR) {
12370 // the argument is foldable to a string literal
12371 size_t str_len = t_val->u.str.val_str->size();
12372 const char *str_ptr = t_val->u.str.val_str->c_str();
12373 expr->expr = mputc(expr->expr, '"');
12374 for (size_t i = 0; i < str_len; i++)
12375 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12376 expr->expr = mputc(expr->expr, '"');
12377 } else location->generate_code_expr_mandatory(expr);
12378 } else expr->expr = mputstr(expr->expr, "NULL");
12379 // fifth argument: alive flag
12380 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12381 }
12382
12383 void Value::generate_code_expr_activate(expression_struct *expr)
12384 {
12385 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12386 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12387 FATAL_ERROR("Value::generate_code_expr_activate()");
12388 expr->expr = mputprintf(expr->expr, "%s(",
12389 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12390 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12391 expr->expr = mputc(expr->expr, ')');
12392 }
12393
12394 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12395 {
12396 Value *v_last = u.expr.v1->get_value_refd_last();
12397 if (v_last->valuetype == V_ALTSTEP) {
12398 // the referred altstep is known
12399 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12400 ->get_genname_from_scope(my_scope, "activate_").c_str());
12401 } else {
12402 // the referred altstep is unknown
12403 u.expr.v1->generate_code_expr_mandatory(expr);
12404 expr->expr = mputstr(expr->expr,".activate(");
12405 }
12406 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12407 expr->expr = mputc(expr->expr, ')');
12408 }
12409
12410 void Value::generate_code_expr_execute(expression_struct *expr)
12411 {
12412 Assignment *testcase = u.expr.r1->get_refd_assignment();
12413 expr->expr = mputprintf(expr->expr, "%s(",
12414 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12415 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12416 if (parlist->get_nof_pars() > 0) {
12417 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12418 0, false);
12419 expr->expr = mputstr(expr->expr, ", ");
12420 }
12421 if (u.expr.v2) {
12422 expr->expr = mputstr(expr->expr, "TRUE, ");
12423 u.expr.v2->generate_code_expr_mandatory(expr);
12424 expr->expr = mputc(expr->expr, ')');
12425 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12426 }
12427
12428 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12429 {
12430 Value *v_last = u.expr.v1->get_value_refd_last();
12431 if (v_last->valuetype == V_TESTCASE) {
12432 // the referred testcase is known
12433 Assignment *testcase = v_last->get_refd_fat();
12434 expr->expr = mputprintf(expr->expr, "%s(",
12435 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12436 u.expr.ap_list2->generate_code_alias(expr,
12437 testcase->get_FormalParList(), 0, false);
12438 } else {
12439 // the referred testcase is unknown
12440 u.expr.v1->generate_code_expr_mandatory(expr);
12441 expr->expr = mputstr(expr->expr,".execute(");
12442 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12443 }
12444 if (u.expr.ap_list2->get_nof_pars() > 0)
12445 expr->expr = mputstr(expr->expr, ", ");
12446 if (u.expr.v3) {
12447 expr->expr = mputstr(expr->expr, "TRUE, ");
12448 u.expr.v3->generate_code_expr_mandatory(expr);
12449 expr->expr = mputc(expr->expr, ')');
12450 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12451 }
12452
12453 void Value::generate_code_expr_invoke(expression_struct *expr)
12454 {
12455 Value *last_v = u.invoke.v->get_value_refd_last();
12456 if (last_v->get_valuetype() == V_FUNCTION) {
12457 // the referred function is known
12458 Assignment *function = last_v->get_refd_fat();
12459 expr->expr = mputprintf(expr->expr, "%s(",
12460 function->get_genname_from_scope(my_scope).c_str());
12461 u.invoke.ap_list->generate_code_alias(expr,
12462 function->get_FormalParList(), function->get_RunsOnType(), false);
12463 } else {
12464 // the referred function is unknown
12465 u.invoke.v->generate_code_expr_mandatory(expr);
12466 expr->expr = mputstr(expr->expr, ".invoke(");
12467 Type* gov_last = last_v->get_expr_governor_last();
12468 u.invoke.ap_list->generate_code_alias(expr, 0,
12469 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12470 }
12471 expr->expr = mputc(expr->expr, ')');
12472 }
12473
12474 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12475 Reference *ref)
12476 {
12477 // if the referenced value points to an optional value field the
12478 // generated code has to be corrected at the end:
12479 // `fieldid()' => `fieldid()()'
12480 Assignment *ass = ref->get_refd_assignment();
12481 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12482 switch (ass->get_asstype()) {
12483 case Assignment::A_CONST:
12484 case Assignment::A_EXT_CONST:
12485 case Assignment::A_MODULEPAR:
12486 case Assignment::A_VAR:
12487 case Assignment::A_FUNCTION_RVAL:
12488 case Assignment::A_EXT_FUNCTION_RVAL:
12489 case Assignment::A_PAR_VAL_IN:
12490 case Assignment::A_PAR_VAL_OUT:
12491 case Assignment::A_PAR_VAL_INOUT:
12492 // only these are mapped to value objects
12493 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12494 expr->expr = mputstr(expr->expr, "()");
12495 break;
12496 default:
12497 break;
12498 }
12499 }
12500
12501 void Value::generate_code_expr_encode(expression_struct *expr)
12502 {
12503 Value* v1 = 0;
12504
12505 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12506 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12507 v1 = templ->get_specific_value();
12508 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12509
12510 expression_struct expr2;
12511 Code::init_expr(&expr2);
12512
12513 bool is_templ = false;
12514 switch (templ->get_templatetype()) {
12515 case Template::SPECIFIC_VALUE:
12516 v1->generate_code_expr_mandatory(&expr2);
12517 break;
12518 default:
12519 u.expr.ti1->generate_code(&expr2);
12520 is_templ = true;
12521 break;
12522 }
12523
12524 if (!gov_last->is_coding_by_function()) {
12525 const string& tmp_id = get_temporary_id();
12526 const string& tmp_buf_id = get_temporary_id();
12527 const string& tmp_ref_id = get_temporary_id();
12528 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12529 tmp_id.c_str());
12530 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12531 tmp_buf_id.c_str());
12532 if (expr2.preamble) { // copy preamble setting up the argument, if any
12533 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12534 expr->preamble = mputc (expr->preamble, '\n');
12535 }
12536 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12537 gov_last->get_genname_typedescriptor(
12538 u.expr.ti1->get_Template()->get_my_scope()
12539 ).c_str(),
12540 tmp_ref_id.c_str(),
12541 expr2.expr);
12542 if (is_templ) // make a value out of the template, if needed
12543 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12544 expr->preamble = mputprintf(expr->preamble,
12545 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12546 tmp_ref_id.c_str(),
12547 gov_last->get_genname_typedescriptor(
12548 u.expr.ti1->get_Template()->get_my_scope()
12549 ).c_str(),
12550 tmp_buf_id.c_str(),
12551 gov_last->get_coding(true).c_str()
12552 );
12553 expr->preamble = mputstr(expr->preamble, ");\n");
12554 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12555 tmp_buf_id.c_str(),
12556 tmp_id.c_str()
12557 );
12558 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12559 if (expr2.postamble)
12560 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12561 } else
12562 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12563 gov_last->get_coding(true).c_str(), expr2.expr,
12564 is_templ ? ".valueof()" : "");
12565 Code::free_expr(&expr2);
12566 }
12567
12568 void Value::generate_code_expr_decode(expression_struct *expr)
12569 {
12570 expression_struct expr1, expr2;
12571 Code::init_expr(&expr1);
12572 Code::init_expr(&expr2);
12573 u.expr.r1->generate_code(&expr1);
12574 u.expr.r2->generate_code(&expr2);
12575
12576 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12577 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12578 get_type_refd_last();
12579
12580 if (expr1.preamble)
12581 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12582 if (expr2.preamble)
12583 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12584
12585 if (!_type->is_coding_by_function()) {
12586 const string& tmp_id = get_temporary_id();
12587 const string& buffer_id = get_temporary_id();
12588 const string& retval_id = get_temporary_id();
12589 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12590 field_is_optional(u.expr.r2->get_subrefs());
12591
12592 expr->preamble = mputprintf(expr->preamble,
12593 "TTCN_Buffer %s(bit2oct(%s));\n"
12594 "INTEGER %s;\n"
12595 "TTCN_EncDec::set_error_behavior("
12596 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12597 "TTCN_EncDec::clear_error();\n",
12598 buffer_id.c_str(),
12599 expr1.expr,
12600 retval_id.c_str()
12601 );
12602 expr->preamble = mputprintf(expr->preamble,
12603 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12604 expr2.expr,
12605 optional ? "()" : "",
12606 _type->get_genname_typedescriptor(
12607 u.expr.r2->get_my_scope()
12608 ).c_str(),
12609 buffer_id.c_str(),
12610 _type->get_coding(false).c_str()
12611 );
12612 expr->preamble = mputprintf(expr->preamble,
12613 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12614 "case TTCN_EncDec::ET_NONE: {\n"
12615 "%s.cut();\n"
12616 "OCTETSTRING %s;\n"
12617 "%s.get_string(%s);\n"
12618 "%s = oct2bit(%s);\n"
12619 "%s = 0;\n"
12620 "}break;\n"
12621 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12622 "case TTCN_EncDec::ET_LEN_ERR:\n"
12623 "%s = 2;\n"
12624 "break;\n"
12625 "default:\n"
12626 "%s = 1;\n"
12627 "}\n"
12628 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12629 "TTCN_EncDec::EB_DEFAULT);\n"
12630 "TTCN_EncDec::clear_error();\n",
12631 buffer_id.c_str(),
12632 tmp_id.c_str(),
12633 buffer_id.c_str(),
12634 tmp_id.c_str(),
12635 expr1.expr,
12636 tmp_id.c_str(),
12637 retval_id.c_str(),
12638 retval_id.c_str(),
12639 retval_id.c_str()
12640 );
12641 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12642 } else
12643 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12644 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12645 if (expr1.postamble)
12646 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12647 if (expr2.postamble)
12648 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12649 Code::free_expr(&expr1);
12650 Code::free_expr(&expr2);
12651 }
12652
12653 void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
12654 {
12655 Value* v1 = 0;
12656
12657 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12658 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12659 v1 = templ->get_specific_value();
12660 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12661
12662 expression_struct expr2;
12663 Code::init_expr(&expr2);
12664
12665 bool is_templ = false;
12666 switch (templ->get_templatetype()) {
12667 case Template::SPECIFIC_VALUE:
12668 v1->generate_code_expr_mandatory(&expr2);
12669 break;
12670 default:
12671 u.expr.ti1->generate_code(&expr2);
12672 is_templ = true;
12673 break;
12674 }
12675
12676 if (!gov_last->is_coding_by_function()) {
12677 const string& tmp_id = get_temporary_id();
12678 const string& tmp_buf_id = get_temporary_id();
12679 const string& tmp_ref_id = get_temporary_id();
12680 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12681 tmp_id.c_str());
12682 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12683 tmp_buf_id.c_str());
12684 if (expr2.preamble) { // copy preamble setting up the argument, if any
12685 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12686 expr->preamble = mputc (expr->preamble, '\n');
12687 }
12688 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12689 gov_last->get_genname_typedescriptor(
12690 u.expr.ti1->get_Template()->get_my_scope()
12691 ).c_str(),
12692 tmp_ref_id.c_str(),
12693 expr2.expr);
12694 if (is_templ) // make a value out of the template, if needed
12695 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12696 expr->preamble = mputprintf(expr->preamble,
12697 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12698 tmp_ref_id.c_str(),
12699 gov_last->get_genname_typedescriptor(
12700 u.expr.ti1->get_Template()->get_my_scope()
12701 ).c_str(),
12702 tmp_buf_id.c_str(),
12703 gov_last->get_coding(true).c_str()
12704 );
12705 expr->preamble = mputstr(expr->preamble, ");\n");
12706 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12707 tmp_buf_id.c_str(),
12708 tmp_id.c_str()
12709 );
12710 const char * v2_code = NULL;
12711 if(u.expr.v2) {
12712 v2_code = generate_code_char_coding_check(expr, u.expr.v2, "encvalue_unichar");
12713 }
12714 expr->expr = mputprintf(expr->expr, "oct2unichar(%s", tmp_id.c_str());
12715 if(u.expr.v2) {
12716 expr->expr = mputprintf(expr->expr, ", %s", v2_code);
12717 } else {
12718 expr->expr = mputprintf(expr->expr, ", \"UTF-8\""); //default
12719 }
12720 expr->expr = mputprintf(expr->expr, ")");
12721 if (expr2.postamble)
12722 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12723 } else
12724 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12725 gov_last->get_coding(true).c_str(), expr2.expr,
12726 is_templ ? ".valueof()" : "");
12727 Code::free_expr(&expr2);
12728 }
12729
12730 void Value::generate_code_expr_decvalue_unichar(expression_struct *expr)
12731 {
12732 expression_struct expr1, expr2;
12733 Code::init_expr(&expr1);
12734 Code::init_expr(&expr2);
12735 u.expr.r1->generate_code(&expr1);
12736 u.expr.r2->generate_code(&expr2);
12737
12738 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12739 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12740 get_type_refd_last();
12741
12742 if (expr1.preamble)
12743 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12744 if (expr2.preamble)
12745 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12746
12747 if (!_type->is_coding_by_function()) {
12748 const string& tmp_id = get_temporary_id();
12749 const string& buffer_id = get_temporary_id();
12750 const string& retval_id = get_temporary_id();
12751 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12752 field_is_optional(u.expr.r2->get_subrefs());
12753
12754 const char* v3_code = NULL;
12755 if(u.expr.v3) {
12756 v3_code = generate_code_char_coding_check(expr, u.expr.v3, "decvalue_unichar");
12757 }
12758 expr->preamble = mputprintf(expr->preamble,
12759 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12760 "INTEGER %s;\n"
12761 "TTCN_EncDec::set_error_behavior("
12762 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12763 "TTCN_EncDec::clear_error();\n",
12764 buffer_id.c_str(),
12765 expr1.expr,
12766 u.expr.v3 ? v3_code : "\"UTF-8\"",
12767 retval_id.c_str()
12768 );
12769 expr->preamble = mputprintf(expr->preamble,
12770 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12771 expr2.expr,
12772 optional ? "()" : "",
12773 _type->get_genname_typedescriptor(
12774 u.expr.r2->get_my_scope()
12775 ).c_str(),
12776 buffer_id.c_str(),
12777 _type->get_coding(false).c_str()
12778 );
12779 expr->preamble = mputprintf(expr->preamble,
12780 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12781 "case TTCN_EncDec::ET_NONE: {\n"
12782 "%s.cut();\n"
12783 "OCTETSTRING %s;\n"
12784 "%s.get_string(%s);\n"
12785 "%s = oct2unichar(%s, %s);\n"
12786 "%s = 0;\n"
12787 "}break;\n"
12788 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12789 "case TTCN_EncDec::ET_LEN_ERR:\n"
12790 "%s = 2;\n"
12791 "break;\n"
12792 "default:\n"
12793 "%s = 1;\n"
12794 "}\n"
12795 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12796 "TTCN_EncDec::EB_DEFAULT);\n"
12797 "TTCN_EncDec::clear_error();\n",
12798 buffer_id.c_str(),
12799 tmp_id.c_str(),
12800 buffer_id.c_str(),
12801 tmp_id.c_str(),
12802 expr1.expr,
12803 tmp_id.c_str(),
12804 u.expr.v3 ? v3_code : "\"UTF-8\"",
12805 retval_id.c_str(),
12806 retval_id.c_str(),
12807 retval_id.c_str()
12808 );
12809 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12810 } else
12811 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12812 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12813 if (expr1.postamble)
12814 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12815 if (expr2.postamble)
12816 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12817 Code::free_expr(&expr1);
12818 Code::free_expr(&expr2);
12819 }
12820
12821 char* Value::generate_code_char_coding_check(expression_struct *expr, Value *v, const char *name)
12822 {
12823 expression_struct expr2;
12824 Code::init_expr(&expr2);
12825 v->generate_code_expr_mandatory(&expr2);
12826 expr->preamble = mputprintf(expr->preamble,
12827 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12828 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12829 " \"UTF-32BE\" != %s) {\n"
12830 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12831 "}\n", //todo errorbehaviour?
12832 expr2.expr,
12833 expr2.expr,
12834 expr2.expr,
12835 expr2.expr,
12836 expr2.expr,
12837 expr2.expr,
12838 expr2.expr,
12839 name,
12840 expr2.expr);
12841 return expr2.expr;
12842 }
12843
12844 char *Value::generate_code_init_choice(char *str, const char *name)
12845 {
12846 const char *alt_name = u.choice.alt_name->get_name().c_str();
12847 // Safe as long as get_name() returns a const string&, not a temporary.
12848 const char *alt_prefix =
12849 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12850 ? "AT_" : "";
12851 if (u.choice.alt_value->needs_temp_ref()) {
12852 const string& tmp_id = get_temporary_id();
12853 const char *tmp_id_str = tmp_id.c_str();
12854 str = mputprintf(str, "{\n"
12855 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12856 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12857 alt_prefix, alt_name);
12858 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12859 str = mputstr(str, "}\n");
12860 } else {
12861 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12862 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12863 Free(embedded_name);
12864 }
12865 return str;
12866 }
12867
12868 char *Value::generate_code_init_seof(char *str, const char *name)
12869 {
12870 size_t nof_vs = u.val_vs->get_nof_vs();
12871 if (nof_vs > 0) {
12872 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12873 const string& embedded_type =
12874 my_governor->get_ofType()->get_genname_value(my_scope);
12875 const char *embedded_type_str = embedded_type.c_str();
12876 for (size_t i = 0; i < nof_vs; i++) {
12877 Value *comp_v = u.val_vs->get_v_byIndex(i);
12878
12879 if (comp_v->valuetype == V_NOTUSED) continue;
12880 else if (comp_v->needs_temp_ref()) {
12881 const string& tmp_id = get_temporary_id();
12882 const char *tmp_id_str = tmp_id.c_str();
12883 str = mputprintf(str, "{\n"
12884 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12885 (unsigned long) i);
12886 str = comp_v->generate_code_init(str, tmp_id_str);
12887 str = mputstr(str, "}\n");
12888 } else {
12889 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12890 str = comp_v->generate_code_init(str, embedded_name);
12891 Free(embedded_name);
12892 }
12893 }
12894 } else {
12895 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12896 }
12897 return str;
12898 }
12899
12900 char *Value::generate_code_init_indexed(char *str, const char *name)
12901 {
12902 size_t nof_ivs = u.val_vs->get_nof_ivs();
12903 if (nof_ivs > 0) {
12904 // Previous values can be truncated. The concept is similar to
12905 // templates.
12906 Type *t_last = my_governor->get_type_refd_last();
12907 const string& oftype_name =
12908 t_last->get_ofType()->get_genname_value(my_scope);
12909 const char *oftype_name_str = oftype_name.c_str();
12910 for (size_t i = 0; i < nof_ivs; i++) {
12911 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12912 const string& tmp_id_1 = get_temporary_id();
12913 str = mputstr(str, "{\n");
12914 Value *index = iv->get_index();
12915 if (index->get_valuetype() != V_INT) {
12916 const string& tmp_id_2 = get_temporary_id();
12917 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12918 str = index->generate_code_init(str, tmp_id_2.c_str());
12919 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12920 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12921 } else {
12922 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12923 tmp_id_1.c_str(), name,
12924 (index->get_val_Int()->t_str()).c_str());
12925 }
12926 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12927 str = mputstr(str, "}\n");
12928 }
12929 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12930 return str;
12931 }
12932
12933 char *Value::generate_code_init_array(char *str, const char *name)
12934 {
12935 size_t nof_vs = u.val_vs->get_nof_vs();
12936 Type *t_last = my_governor->get_type_refd_last();
12937 Int index_offset = t_last->get_dimension()->get_offset();
12938 const string& embedded_type =
12939 t_last->get_ofType()->get_genname_value(my_scope);
12940 const char *embedded_type_str = embedded_type.c_str();
12941 for (size_t i = 0; i < nof_vs; i++) {
12942 Value *comp_v = u.val_vs->get_v_byIndex(i);
12943 if (comp_v->valuetype == V_NOTUSED) continue;
12944 else if (comp_v->needs_temp_ref()) {
12945 const string& tmp_id = get_temporary_id();
12946 const char *tmp_id_str = tmp_id.c_str();
12947 str = mputprintf(str, "{\n"
12948 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12949 Int2string(index_offset + i).c_str());
12950 str = comp_v->generate_code_init(str, tmp_id_str);
12951 str = mputstr(str, "}\n");
12952 } else {
12953 char *embedded_name = mprintf("%s[%s]", name,
12954 Int2string(index_offset + i).c_str());
12955 str = comp_v->generate_code_init(str, embedded_name);
12956 Free(embedded_name);
12957 }
12958 }
12959 return str;
12960 }
12961
12962 char *Value::generate_code_init_se(char *str, const char *name)
12963 {
12964 Type *type = my_governor->get_type_refd_last();
12965 size_t nof_comps = type->get_nof_comps();
12966 if (nof_comps > 0) {
12967 for (size_t i = 0; i < nof_comps; i++) {
12968 CompField *cf = type->get_comp_byIndex(i);
12969 const Identifier& field_id = cf->get_name();
12970 const char *field_name = field_id.get_name().c_str();
12971 Value *field_v;
12972 if (u.val_nvs->has_nv_withName(field_id)) {
12973 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12974 if (field_v->valuetype == V_NOTUSED) continue;
12975 if (field_v->valuetype == V_OMIT) field_v = 0;
12976 } else if (is_asn1()) {
12977 if (cf->has_default()) {
12978 // handle like a referenced value
12979 Value *defval = cf->get_defval();
12980 if (needs_init_precede(defval)) {
12981 str = defval->generate_code_init(str,
12982 defval->get_lhs_name().c_str());
12983 }
12984 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12985 defval->get_genname_own(my_scope).c_str());
12986 continue;
12987 } else {
12988 if (!cf->get_is_optional())
12989 FATAL_ERROR("Value::generate_code_init()");
12990 field_v = 0;
12991 }
12992 } else {
12993 continue;
12994 }
12995 if (field_v) {
12996 // the value is not omit
12997 if (field_v->needs_temp_ref()) {
12998 const string& tmp_id = get_temporary_id();
12999 const char *tmp_id_str = tmp_id.c_str();
13000 str = mputprintf(str, "{\n"
13001 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
13002 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
13003 field_name);
13004 str = field_v->generate_code_init(str, tmp_id_str);
13005 str = mputstr(str, "}\n");
13006 } else {
13007 char *embedded_name = mprintf("%s.%s()", name,
13008 field_name);
13009 if (cf->get_is_optional() && field_v->is_compound())
13010 embedded_name = mputstr(embedded_name, "()");
13011 str = field_v->generate_code_init(str, embedded_name);
13012 Free(embedded_name);
13013 }
13014 } else {
13015 // the value is omit
13016 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
13017 name, field_name);
13018 }
13019 }
13020 } else {
13021 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
13022 }
13023 return str;
13024 }
13025
13026 char *Value::generate_code_init_refd(char *str, const char *name)
13027 {
13028 Value *v = get_value_refd_last();
13029 if (v == this) {
13030 // the referred value is not available at compile time
13031 // the code generation is based on the reference
13032 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
13033 str = TypeConv::gen_conv_code_refd(str, name, v);
13034 } else {
13035 expression_struct expr;
13036 Code::init_expr(&expr);
13037 expr.expr = mputprintf(expr.expr, "%s = ", name);
13038 u.ref.ref->generate_code_const_ref(&expr);
13039 str = Code::merge_free_expr(str, &expr);
13040 }
13041 } else {
13042 // the referred value is available at compile time
13043 // the code generation is based on the referred value
13044 if (v->has_single_expr() &&
13045 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
13046 // simple substitution for in-line values within the same module
13047 str = mputprintf(str, "%s = %s;\n", name,
13048 v->get_single_expr().c_str());
13049 } else {
13050 // use a simple reference to reduce code size
13051 if (needs_init_precede(v)) {
13052 // the referred value must be initialized first
13053 if (!v->is_toplevel() && v->needs_temp_ref()) {
13054 // temporary id should be introduced for the lhs
13055 const string& tmp_id = get_temporary_id();
13056 const char *tmp_id_str = tmp_id.c_str();
13057 str = mputprintf(str, "{\n"
13058 "%s& %s = %s;\n",
13059 v->get_my_governor()->get_genname_value(my_scope).c_str(),
13060 tmp_id_str, v->get_lhs_name().c_str());
13061 str = v->generate_code_init(str, tmp_id_str);
13062 str = mputstr(str, "}\n");
13063 } else {
13064 str = v->generate_code_init(str, v->get_lhs_name().c_str());
13065 }
13066 }
13067 str = mputprintf(str, "%s = %s;\n", name,
13068 v->get_genname_own(my_scope).c_str());
13069 }
13070 }
13071 return str;
13072 }
13073
13074 void Value::generate_json_value(JSON_Tokenizer& json,
13075 bool allow_special_float, /* = true */
13076 bool union_value_list, /* = false */
13077 Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
13078 {
13079 switch (valuetype) {
13080 case V_INT:
13081 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
13082 break;
13083 case V_REAL: {
13084 Real r = get_val_Real();
13085 if (r == REAL_INFINITY) {
13086 if (allow_special_float) {
13087 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
13088 }
13089 }
13090 else if (r == -REAL_INFINITY) {
13091 if (allow_special_float) {
13092 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
13093 }
13094 }
13095 else if (r != r) {
13096 if (allow_special_float) {
13097 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
13098 }
13099 }
13100 else {
13101 // true if decimal representation possible (use %f format)
13102 bool decimal_repr = (r == 0.0)
13103 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
13104 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
13105 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
13106 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
13107 Free(number_str);
13108 }
13109 break; }
13110 case V_BOOL:
13111 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
13112 break;
13113 case V_BSTR:
13114 case V_HSTR:
13115 case V_OSTR:
13116 case V_CSTR: {
13117 char* str = convert_to_json_string(get_val_str().c_str());
13118 json.put_next_token(JSON_TOKEN_STRING, str);
13119 Free(str);
13120 break; }
13121 case V_USTR: {
13122 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13123 json.put_next_token(JSON_TOKEN_STRING, str);
13124 Free(str);
13125 break; }
13126 case V_VERDICT:
13127 case V_ENUM:
13128 json.put_next_token(JSON_TOKEN_STRING,
13129 (string('\"') + create_stringRepr() + string('\"')).c_str());
13130 break;
13131 case V_SEQOF:
13132 case V_SETOF:
13133 json.put_next_token(JSON_TOKEN_ARRAY_START);
13134 if (!u.val_vs->is_indexed()) {
13135 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
13136 u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
13137 union_value_list, omit_combo);
13138 }
13139 }
13140 else {
13141 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
13142 // look for the entry with index equal to i
13143 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
13144 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
13145 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
13146 allow_special_float, union_value_list, omit_combo);
13147 break;
13148 }
13149 }
13150 }
13151 }
13152 json.put_next_token(JSON_TOKEN_ARRAY_END);
13153 break;
13154 case V_SEQ:
13155 case V_SET: {
13156 // omitted fields have 2 possible JSON values (the field is absent, or it's
13157 // present with value 'null'), each combination of omitted values must be
13158 // generated
13159 if (omit_combo == NULL) {
13160 FATAL_ERROR("Value::generate_json_value - no combo");
13161 }
13162 size_t len = get_nof_comps();
13163 // generate the JSON object from the present combination
13164 json.put_next_token(JSON_TOKEN_OBJECT_START);
13165 for (size_t i = 0; i < len; ++i) {
13166 Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
13167 if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
13168 // the field is absent, don't insert anything
13169 continue;
13170 }
13171 // use the field's alias, if it has one
13172 const char* alias = NULL;
13173 if (my_governor != NULL) {
13174 JsonAST* field_attrib = my_governor->get_comp_byName(
13175 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
13176 if (field_attrib != NULL) {
13177 alias = field_attrib->alias;
13178 }
13179 }
13180 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13181 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
13182 if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
13183 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
13184 }
13185 else {
13186 get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
13187 allow_special_float, union_value_list, omit_combo);
13188 }
13189 }
13190 json.put_next_token(JSON_TOKEN_OBJECT_END);
13191 break; }
13192 case V_CHOICE: {
13193 bool as_value = !union_value_list && my_governor != NULL &&
13194 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
13195 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
13196 if (!as_value) {
13197 // no 'as value' coding instruction, insert an object with one field
13198 json.put_next_token(JSON_TOKEN_OBJECT_START);
13199 // use the field's alias, if it has one
13200 const char* alias = NULL;
13201 if (my_governor != NULL) {
13202 JsonAST* field_attrib = my_governor->get_comp_byName(
13203 get_alt_name())->get_type()->get_json_attributes();
13204 if (field_attrib != NULL) {
13205 alias = field_attrib->alias;
13206 }
13207 }
13208 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13209 get_alt_name().get_ttcnname().c_str());
13210 }
13211 get_alt_value()->generate_json_value(json, allow_special_float,
13212 union_value_list, omit_combo);
13213 if (!as_value) {
13214 json.put_next_token(JSON_TOKEN_OBJECT_END);
13215 }
13216 break; }
13217 case V_REFD: {
13218 Value* v = get_value_refd_last();
13219 if (this != v) {
13220 v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
13221 return;
13222 }
13223 } // no break
13224 default:
13225 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
13226 }
13227 }
13228
13229 bool Value::explicit_cast_needed(bool forIsValue)
13230 {
13231 Value *v_last = get_value_refd_last();
13232 if (v_last != this) {
13233 // this is a foldable referenced value
13234 // if the reference points to an imported or compound value the code
13235 // generation will be based on the reference so cast is not needed
13236 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
13237 || !v_last->has_single_expr()) return false;
13238 } else if (v_last->valuetype == V_REFD) {
13239 // this is an unfoldable reference (v_last==this)
13240 // explicit cast is needed only for string element references
13241 if (forIsValue) return false;
13242 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
13243 return t_subrefs && t_subrefs->refers_to_string_element();
13244 }
13245 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
13246 Type *t_governor = v_last->my_governor->get_type_refd_last();
13247 switch (t_governor->get_typetype()) {
13248 case Type::T_NULL:
13249 case Type::T_BOOL:
13250 case Type::T_INT:
13251 case Type::T_INT_A:
13252 case Type::T_REAL:
13253 case Type::T_ENUM_A:
13254 case Type::T_ENUM_T:
13255 case Type::T_VERDICT:
13256 case Type::T_COMPONENT:
13257 // these are mapped to built-in C/C++ types
13258 return true;
13259 case Type::T_SEQ_A:
13260 case Type::T_SEQ_T:
13261 case Type::T_SET_A:
13262 case Type::T_SET_T:
13263 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13264 return t_governor->get_nof_comps() == 0;
13265 case Type::T_SEQOF:
13266 case Type::T_SETOF:
13267 // the C++ equivalent of value {} is ambiguous
13268 // tr926
13269 return true;
13270 case Type::T_FUNCTION:
13271 case Type::T_ALTSTEP:
13272 case Type::T_TESTCASE:
13273 return true;
13274 default:
13275 return false;
13276 }
13277 }
13278
13279 bool Value::has_single_expr()
13280 {
13281 if (get_needs_conversion()) return false;
13282 switch (valuetype) {
13283 case V_EXPR:
13284 return has_single_expr_expr();
13285 case V_CHOICE:
13286 case V_ARRAY:
13287 // a union or array value cannot be represented as an in-line expression
13288 return false;
13289 case V_SEQOF:
13290 case V_SETOF:
13291 // only an empty record/set of value can be represented as an in-line
13292 // expression
13293 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
13294 else return u.val_vs->get_nof_ivs() == 0;
13295 case V_SEQ:
13296 case V_SET: {
13297 // only a value for an empty record/set type can be represented as an
13298 // in-line expression
13299 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
13300 Type *type = my_governor->get_type_refd_last();
13301 return type->get_nof_comps() == 0; }
13302 case V_REFD: {
13303 Value *v_last = get_value_refd_last();
13304 // If the above call hit an error and set_valuetype(V_ERROR),
13305 // then u.ref.ref has been freed. Avoid the segfault.
13306 if (valuetype == V_ERROR)
13307 return false;
13308 if (v_last != this && v_last->has_single_expr() &&
13309 v_last->my_scope->get_scope_mod_gen() ==
13310 my_scope->get_scope_mod_gen()) return true;
13311 else return u.ref.ref->has_single_expr(); }
13312 case V_INVOKE:
13313 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
13314 case V_ERROR:
13315 case V_NAMEDINT:
13316 case V_NAMEDBITS:
13317 case V_UNDEF_LOWERID:
13318 case V_UNDEF_BLOCK:
13319 case V_REFER:
13320 // these values cannot occur during code generation
13321 FATAL_ERROR("Value::has_single_expr()");
13322 case V_INT:
13323 return u.val_Int->is_native_fit();
13324 case V_NOTUSED:
13325 // should only happen when generating code for an unbound record/set value
13326 return false;
13327 default:
13328 // other value types (literal values) do not need temporary reference
13329 return true;
13330 }
13331 }
13332
13333 string Value::get_single_expr()
13334 {
13335 switch (valuetype) {
13336 case V_NULL:
13337 return string("ASN_NULL_VALUE");
13338 case V_BOOL:
13339 return string(u.val_bool ? "TRUE" : "FALSE");
13340 case V_INT:
13341 if (u.val_Int->is_native_fit()) { // Be sure.
13342 return u.val_Int->t_str();
13343 } else {
13344 // get_single_expr may be called only if has_single_expr() is true.
13345 // The only exception is V_INT, where get_single_expr may be called
13346 // even if is_native_fit (which is used to implement has_single_expr)
13347 // returns false.
13348 string ret_val('"');
13349 ret_val += u.val_Int->t_str();
13350 ret_val += '"';
13351 return ret_val;
13352 }
13353 case V_REAL:
13354 return Real2code(u.val_Real);
13355 case V_ENUM:
13356 return get_single_expr_enum();
13357 case V_BSTR:
13358 return get_my_scope()->get_scope_mod_gen()
13359 ->add_bitstring_literal(*u.str.val_str);
13360 case V_HSTR:
13361 return get_my_scope()->get_scope_mod_gen()
13362 ->add_hexstring_literal(*u.str.val_str);
13363 case V_OSTR:
13364 return get_my_scope()->get_scope_mod_gen()
13365 ->add_octetstring_literal(*u.str.val_str);
13366 case V_CSTR:
13367 return get_my_scope()->get_scope_mod_gen()
13368 ->add_charstring_literal(*u.str.val_str);
13369 case V_USTR:
13370 if (u.ustr.convert_str) {
13371 set_valuetype(V_CSTR);
13372 return get_my_scope()->get_scope_mod_gen()
13373 ->add_charstring_literal(*u.str.val_str);
13374 } else
13375 return get_my_scope()->get_scope_mod_gen()
13376 ->add_ustring_literal(*u.ustr.val_ustr);
13377 case V_ISO2022STR:
13378 return get_single_expr_iso2022str();
13379 case V_OID:
13380 case V_ROID: {
13381 vector<string> comps;
13382 bool is_constant = get_oid_comps(comps);
13383 size_t nof_comps = comps.size();
13384 string oi_str;
13385 for (size_t i = 0; i < nof_comps; i++) {
13386 if (i > 0) oi_str += ", ";
13387 oi_str += *(comps[i]);
13388 }
13389 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
13390 comps.clear();
13391 if (is_constant) {
13392 // the objid only contains constants
13393 // => create a literal and return its name
13394 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
13395 }
13396 // the objid contains at least one variable
13397 // => append the number of components before the component values in the string and return it
13398 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
13399 case V_SEQOF:
13400 case V_SETOF:
13401 if (u.val_vs->get_nof_vs() > 0)
13402 FATAL_ERROR("Value::get_single_expr()");
13403 return string("NULL_VALUE");
13404 case V_SEQ:
13405 case V_SET:
13406 if (u.val_nvs->get_nof_nvs() > 0)
13407 FATAL_ERROR("Value::get_single_expr()");
13408 return string("NULL_VALUE");
13409 case V_REFD: {
13410 Value *v_last = get_value_refd_last();
13411 if (v_last != this && v_last->has_single_expr() &&
13412 v_last->my_scope->get_scope_mod_gen() ==
13413 my_scope->get_scope_mod_gen()) {
13414 // the reference points to another single value in the same module
13415 return v_last->get_single_expr();
13416 } else {
13417 // convert the reference to a single expression
13418 expression_struct expr;
13419 Code::init_expr(&expr);
13420 u.ref.ref->generate_code_const_ref(&expr);
13421 if (expr.preamble || expr.postamble)
13422 FATAL_ERROR("Value::get_single_expr()");
13423 string ret_val(expr.expr);
13424 Code::free_expr(&expr);
13425 return ret_val;
13426 } }
13427 case V_OMIT:
13428 return string("OMIT_VALUE");
13429 case V_VERDICT:
13430 switch (u.verdict) {
13431 case Verdict_NONE:
13432 return string("NONE");
13433 case Verdict_PASS:
13434 return string("PASS");
13435 case Verdict_INCONC:
13436 return string("INCONC");
13437 case Verdict_FAIL:
13438 return string("FAIL");
13439 case Verdict_ERROR:
13440 return string("ERROR");
13441 default:
13442 FATAL_ERROR("Value::get_single_expr()");
13443 return string();
13444 }
13445 case V_DEFAULT_NULL:
13446 return string("NULL_COMPREF");
13447 case V_FAT_NULL: {
13448 string ret_val('(');
13449 ret_val += my_governor->get_genname_value(my_scope);
13450 ret_val += "::function_pointer)Module_List::get_fat_null()";
13451 return ret_val; }
13452 case V_EXPR:
13453 case V_INVOKE: {
13454 expression_struct expr;
13455 Code::init_expr(&expr);
13456 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13457 else generate_code_expr_invoke(&expr);
13458 if (expr.preamble || expr.postamble)
13459 FATAL_ERROR("Value::get_single_expr()");
13460 string ret_val(expr.expr);
13461 Code::free_expr(&expr);
13462 return ret_val; }
13463 case V_MACRO:
13464 switch (u.macro) {
13465 case MACRO_TESTCASEID:
13466 return string("TTCN_Runtime::get_testcase_id_macro()");
13467 default:
13468 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13469 return string();
13470 }
13471 case V_FUNCTION:
13472 case V_ALTSTEP:
13473 case V_TESTCASE:
13474 return get_single_expr_fat();
13475 default:
13476 FATAL_ERROR("Value::get_single_expr()");
13477 return string();
13478 }
13479 }
13480
13481 bool Value::has_single_expr_expr()
13482 {
13483 switch (u.expr.v_optype) {
13484 case OPTYPE_RND: // -
13485 case OPTYPE_COMP_NULL:
13486 case OPTYPE_COMP_MTC:
13487 case OPTYPE_COMP_SYSTEM:
13488 case OPTYPE_COMP_SELF:
13489 case OPTYPE_COMP_RUNNING_ANY:
13490 case OPTYPE_COMP_RUNNING_ALL:
13491 case OPTYPE_COMP_ALIVE_ANY:
13492 case OPTYPE_COMP_ALIVE_ALL:
13493 case OPTYPE_TMR_RUNNING_ANY:
13494 case OPTYPE_GETVERDICT:
13495 case OPTYPE_TESTCASENAME:
13496 case OPTYPE_PROF_RUNNING:
13497 return true;
13498 case OPTYPE_ENCODE:
13499 case OPTYPE_DECODE:
13500 case OPTYPE_ISBOUND:
13501 case OPTYPE_ISPRESENT:
13502 case OPTYPE_TTCN2STRING:
13503 case OPTYPE_ENCVALUE_UNICHAR:
13504 case OPTYPE_DECVALUE_UNICHAR:
13505 return false;
13506 case OPTYPE_UNARYPLUS: // v1
13507 case OPTYPE_UNARYMINUS:
13508 case OPTYPE_NOT:
13509 case OPTYPE_NOT4B:
13510 case OPTYPE_BIT2HEX:
13511 case OPTYPE_BIT2INT:
13512 case OPTYPE_BIT2OCT:
13513 case OPTYPE_BIT2STR:
13514 case OPTYPE_CHAR2INT:
13515 case OPTYPE_CHAR2OCT:
13516 case OPTYPE_FLOAT2INT:
13517 case OPTYPE_FLOAT2STR:
13518 case OPTYPE_HEX2BIT:
13519 case OPTYPE_HEX2INT:
13520 case OPTYPE_HEX2OCT:
13521 case OPTYPE_HEX2STR:
13522 case OPTYPE_INT2CHAR:
13523 case OPTYPE_INT2FLOAT:
13524 case OPTYPE_INT2STR:
13525 case OPTYPE_INT2UNICHAR:
13526 case OPTYPE_OCT2BIT:
13527 case OPTYPE_OCT2CHAR:
13528 case OPTYPE_OCT2HEX:
13529 case OPTYPE_OCT2INT:
13530 case OPTYPE_OCT2STR:
13531 case OPTYPE_STR2BIT:
13532 case OPTYPE_STR2FLOAT:
13533 case OPTYPE_STR2HEX:
13534 case OPTYPE_STR2INT:
13535 case OPTYPE_STR2OCT:
13536 case OPTYPE_UNICHAR2INT:
13537 case OPTYPE_UNICHAR2CHAR:
13538 case OPTYPE_ENUM2INT:
13539 case OPTYPE_RNDWITHVAL:
13540 case OPTYPE_ISCHOSEN_V: // v1 i2
13541 case OPTYPE_COMP_RUNNING:
13542 case OPTYPE_COMP_ALIVE:
13543 case OPTYPE_GET_STRINGENCODING:
13544 case OPTYPE_REMOVE_BOM:
13545 case OPTYPE_DECODE_BASE64:
13546 return u.expr.v1->has_single_expr();
13547 case OPTYPE_ISCHOSEN_T: // t1 i2
13548 return u.expr.t1->has_single_expr();
13549 case OPTYPE_ADD: // v1 v2
13550 case OPTYPE_SUBTRACT:
13551 case OPTYPE_MULTIPLY:
13552 case OPTYPE_DIVIDE:
13553 case OPTYPE_MOD:
13554 case OPTYPE_REM:
13555 case OPTYPE_CONCAT:
13556 case OPTYPE_EQ:
13557 case OPTYPE_LT:
13558 case OPTYPE_GT:
13559 case OPTYPE_NE:
13560 case OPTYPE_GE:
13561 case OPTYPE_LE:
13562 case OPTYPE_XOR:
13563 case OPTYPE_AND4B:
13564 case OPTYPE_OR4B:
13565 case OPTYPE_XOR4B:
13566 case OPTYPE_SHL:
13567 case OPTYPE_SHR:
13568 case OPTYPE_ROTL:
13569 case OPTYPE_ROTR:
13570 case OPTYPE_INT2BIT:
13571 case OPTYPE_INT2HEX:
13572 case OPTYPE_INT2OCT:
13573 return u.expr.v1->has_single_expr() &&
13574 u.expr.v2->has_single_expr();
13575 case OPTYPE_UNICHAR2OCT:
13576 case OPTYPE_OCT2UNICHAR:
13577 case OPTYPE_ENCODE_BASE64:
13578 return u.expr.v1->has_single_expr() &&
13579 (!u.expr.v2 || u.expr.v2->has_single_expr());
13580 case OPTYPE_AND:
13581 case OPTYPE_OR:
13582 return u.expr.v1->has_single_expr() &&
13583 u.expr.v2->has_single_expr() &&
13584 !u.expr.v2->needs_short_circuit();
13585 case OPTYPE_SUBSTR:
13586 return u.expr.ti1->has_single_expr() &&
13587 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13588 case OPTYPE_REGEXP:
13589 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13590 u.expr.v3->has_single_expr();
13591 case OPTYPE_DECOMP: // v1 v2 v3
13592 return u.expr.v1->has_single_expr() &&
13593 u.expr.v2->has_single_expr() &&
13594 u.expr.v3->has_single_expr();
13595 case OPTYPE_REPLACE:
13596 return u.expr.ti1->has_single_expr() &&
13597 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13598 u.expr.ti4->has_single_expr();
13599 case OPTYPE_ISVALUE: // ti1
13600 case OPTYPE_LENGTHOF: // ti1
13601 case OPTYPE_SIZEOF: // ti1
13602 case OPTYPE_VALUEOF: // ti1
13603 return u.expr.ti1->has_single_expr();
13604 case OPTYPE_LOG2STR:
13605 case OPTYPE_ANY2UNISTR:
13606 return u.expr.logargs->has_single_expr();
13607 case OPTYPE_MATCH: // v1 t2
13608 return u.expr.v1->has_single_expr() &&
13609 u.expr.t2->has_single_expr();
13610 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13611 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13612 (!u.expr.v3 || u.expr.v3->has_single_expr());
13613 case OPTYPE_TMR_READ: // r1
13614 case OPTYPE_TMR_RUNNING:
13615 case OPTYPE_ACTIVATE:
13616 return u.expr.r1->has_single_expr();
13617 case OPTYPE_EXECUTE: // r1 [v2]
13618 return u.expr.r1->has_single_expr() &&
13619 (!u.expr.v2 || u.expr.v2->has_single_expr());
13620 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13621 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13622 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13623 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13624 (!u.expr.v3 || u.expr.v3->has_single_expr());
13625 default:
13626 FATAL_ERROR("Value::has_single_expr_expr()");
13627 } // switch
13628 }
13629
13630 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13631 {
13632 if (!v->has_single_expr()) return false;
13633 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13634 if (!ap_list->get_par(i)->has_single_expr()) return false;
13635 return true;
13636 }
13637
13638 string Value::get_single_expr_enum()
13639 {
13640 string ret_val(my_governor->get_genname_value(my_scope));
13641 ret_val += "::";
13642 ret_val += u.val_id->get_name();
13643 return ret_val;
13644 }
13645
13646 string Value::get_single_expr_iso2022str()
13647 {
13648 string ret_val;
13649 Type *type = get_my_governor()->get_type_refd_last();
13650 switch (type->get_typetype()) {
13651 case Type::T_TELETEXSTRING:
13652 ret_val += "TTCN_ISO2022_2_TeletexString";
13653 break;
13654 case Type::T_VIDEOTEXSTRING:
13655 ret_val += "TTCN_ISO2022_2_VideotexString";
13656 break;
13657 case Type::T_GRAPHICSTRING:
13658 case Type::T_OBJECTDESCRIPTOR:
13659 ret_val += "TTCN_ISO2022_2_GraphicString";
13660 break;
13661 case Type::T_GENERALSTRING:
13662 ret_val += "TTCN_ISO2022_2_GeneralString";
13663 break;
13664 default:
13665 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13666 } // switch
13667 ret_val += '(';
13668 string *ostr = char2oct(*u.str.val_str);
13669 ret_val += get_my_scope()->get_scope_mod_gen()
13670 ->add_octetstring_literal(*ostr);
13671 delete ostr;
13672 ret_val += ')';
13673 return ret_val;
13674 }
13675
13676 string Value::get_single_expr_fat()
13677 {
13678 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13679 // the ampersand operator is not really necessary to obtain the function
13680 // pointer, but some older versions of GCC cannot instantiate the
13681 // appropriate operator=() member of class OPTIONAL when necessary
13682 // if only the function name is given
13683 string ret_val('&');
13684 switch (valuetype) {
13685 case V_FUNCTION:
13686 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13687 break;
13688 case V_ALTSTEP:
13689 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13690 ret_val += "_instance";
13691 break;
13692 case V_TESTCASE:
13693 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13694 break;
13695 default:
13696 FATAL_ERROR("Value::get_single_expr_fat()");
13697 }
13698 return ret_val;
13699 }
13700
13701 bool Value::is_compound()
13702 {
13703 switch (valuetype) {
13704 case V_CHOICE:
13705 case V_SEQOF:
13706 case V_SETOF:
13707 case V_ARRAY:
13708 case V_SEQ:
13709 case V_SET:
13710 return true;
13711 default:
13712 return false;
13713 }
13714 }
13715
13716 bool Value::needs_temp_ref()
13717 {
13718 switch (valuetype) {
13719 case V_SEQOF:
13720 case V_SETOF:
13721 if (!is_indexed()) {
13722 // Temporary reference is needed if the value has at least one real
13723 // element (i.e. it is not empty or contains only not used symbols).
13724 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13725 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13726 }
13727 } else {
13728 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13729 if (u.val_vs->get_iv_byIndex(i)->get_value()
13730 ->valuetype != V_NOTUSED)
13731 return true;
13732 }
13733 }
13734 return false;
13735 case V_ARRAY: {
13736 size_t nof_real_vs = 0;
13737 if (!is_indexed()) {
13738 // Temporary reference is needed if the array value has at least two
13739 // real elements (excluding not used symbols).
13740 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13741 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13742 nof_real_vs++;
13743 if (nof_real_vs > 1) return true;
13744 }
13745 }
13746 } else {
13747 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13748 if (u.val_vs->get_iv_byIndex(i)->get_value()
13749 ->valuetype != V_NOTUSED) {
13750 nof_real_vs++;
13751 if (nof_real_vs > 1) return true;
13752 }
13753 }
13754 }
13755 return false; }
13756 case V_SEQ:
13757 case V_SET:
13758 if (is_asn1()) {
13759 // it depends on the type since fields with omit or default value
13760 // may not be present
13761 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13762 } else {
13763 // incomplete values are allowed in TTCN-3
13764 // we should check the number of value components
13765 return u.val_nvs->get_nof_nvs() > 1;
13766 }
13767 case V_ERROR:
13768 case V_NAMEDINT:
13769 case V_NAMEDBITS:
13770 case V_UNDEF_LOWERID:
13771 case V_UNDEF_BLOCK:
13772 case V_TTCN3_NULL:
13773 // these values cannot occur during code generation
13774 FATAL_ERROR("Value::needs_temp_ref()");
13775 case V_INT:
13776 return !u.val_Int->is_native();
13777 default:
13778 // other value types (literal values) do not need temporary reference
13779 return false;
13780 }
13781 }
13782
13783 bool Value::needs_short_circuit()
13784 {
13785 switch (valuetype) {
13786 case V_BOOL:
13787 return false;
13788 case V_REFD:
13789 // examined below
13790 break;
13791 case V_EXPR:
13792 case V_INVOKE:
13793 // sub-expressions should be evaluated only if necessary
13794 return true;
13795 default:
13796 FATAL_ERROR("Value::needs_short_circuit()");
13797 }
13798 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13799 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13800 switch (t_ass->get_asstype()) {
13801 case Assignment::A_FUNCTION_RVAL:
13802 case Assignment::A_EXT_FUNCTION_RVAL:
13803 // avoid unnecessary call of a function
13804 return true;
13805 case Assignment::A_CONST:
13806 case Assignment::A_EXT_CONST:
13807 case Assignment::A_MODULEPAR:
13808 case Assignment::A_VAR:
13809 case Assignment::A_PAR_VAL_IN:
13810 case Assignment::A_PAR_VAL_OUT:
13811 case Assignment::A_PAR_VAL_INOUT:
13812 // depends on field/array sub-references, which is examined below
13813 break;
13814 default:
13815 FATAL_ERROR("Value::needs_short_circuit()");
13816 }
13817 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13818 if (t_subrefs) {
13819 // the evaluation of the reference does not have side effects
13820 // (i.e. false shall be returned) only if all sub-references point to
13821 // mandatory fields of record/set types, and neither sub-reference points
13822 // to a field of a union type
13823 Type *t_type = t_ass->get_Type();
13824 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13825 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13826 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13827 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13828 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13829 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13830 t_cf->get_is_optional()) return true;
13831 t_type = t_cf->get_type();
13832 } else return true;
13833 }
13834 }
13835 return false;
13836 }
13837
13838 void Value::dump(unsigned level) const
13839 {
13840 switch (valuetype) {
13841 case V_ERROR:
13842 case V_NULL:
13843 case V_BOOL:
13844 case V_INT:
13845 case V_NAMEDINT:
13846 case V_NAMEDBITS:
13847 case V_REAL:
13848 case V_ENUM:
13849 case V_BSTR:
13850 case V_HSTR:
13851 case V_OSTR:
13852 case V_CSTR:
13853 case V_ISO2022STR:
13854 case V_OID:
13855 case V_ROID:
13856 case V_CHOICE:
13857 case V_SEQOF:
13858 case V_SETOF:
13859 case V_ARRAY:
13860 case V_SEQ:
13861 case V_SET:
13862 case V_OMIT:
13863 case V_VERDICT:
13864 case V_DEFAULT_NULL:
13865 case V_FAT_NULL:
13866 case V_EXPR:
13867 case V_MACRO:
13868 case V_NOTUSED:
13869 case V_FUNCTION:
13870 case V_ALTSTEP:
13871 case V_TESTCASE:
13872 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13873 break;
13874 case V_REFD:
13875 case V_REFER:
13876 DEBUG(level, "Value: reference");
13877 u.ref.ref->dump(level + 1);
13878 break;
13879 case V_UNDEF_LOWERID:
13880 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13881 break;
13882 case V_UNDEF_BLOCK:
13883 DEBUG(level, "Value: {block}");
13884 break;
13885 case V_TTCN3_NULL:
13886 DEBUG(level, "Value: null");
13887 break;
13888 case V_INVOKE:
13889 DEBUG(level, "Value: invoke");
13890 u.invoke.v->dump(level + 1);
13891 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13892 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13893 break;
13894 default:
13895 DEBUG(level, "Value: unknown type: %d", valuetype);
13896 } // switch
13897 }
13898
13899 void Value::add_string_element(size_t index, Value *v_element,
13900 map<size_t, Value>*& string_elements)
13901 {
13902 v_element->set_my_scope(get_my_scope());
13903 v_element->set_my_governor(get_my_governor());
13904 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13905 v_element->set_location(*this);
13906 if (!string_elements) string_elements = new map<size_t, Value>;
13907 string_elements->add(index, v_element);
13908 }
13909
13910 ///////////////////////////////////////////////////////////////////////////////
13911 // class LazyParamData
13912
13913 int LazyParamData::depth = 0;
13914 bool LazyParamData::used_as_lvalue = false;
13915 vector<string>* LazyParamData::type_vec = NULL;
13916 vector<string>* LazyParamData::refd_vec = NULL;
13917
13918 void LazyParamData::init(bool p_used_as_lvalue) {
13919 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13920 if (depth==0) {
13921 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13922 used_as_lvalue = p_used_as_lvalue;
13923 type_vec = new vector<string>;
13924 refd_vec = new vector<string>;
13925 }
13926 depth++;
13927 }
13928
13929 void LazyParamData::clean() {
13930 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13931 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13932 if (depth==1) {
13933 // type_vec
13934 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13935 type_vec->clear();
13936 delete type_vec;
13937 type_vec = NULL;
13938 // refd_vec
13939 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13940 refd_vec->clear();
13941 delete refd_vec;
13942 refd_vec = NULL;
13943 }
13944 depth--;
13945 }
13946
13947 bool LazyParamData::in_lazy() {
13948 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13949 return depth>0;
13950 }
13951
13952 // returns a temporary id instead of the C++ reference to a definition
13953 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13954 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13955 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13956 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13957 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13958 // store the type of the assignment
13959 string* type_str = new string;
13960 switch (ass->get_asstype()) {
13961 case Assignment::A_MODULEPAR_TEMP:
13962 case Assignment::A_TEMPLATE:
13963 case Assignment::A_VAR_TEMPLATE:
13964 case Assignment::A_PAR_TEMPL_IN:
13965 case Assignment::A_PAR_TEMPL_OUT:
13966 case Assignment::A_PAR_TEMPL_INOUT:
13967 *type_str = ass->get_Type()->get_genname_template(scope);
13968 break;
13969 default:
13970 *type_str = ass->get_Type()->get_genname_value(scope);
13971 }
13972 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13973 bool refd_ass_is_lazy_fpar = false;
13974 switch (ass->get_asstype()) {
13975 case Assignment::A_PAR_VAL:
13976 case Assignment::A_PAR_VAL_IN:
13977 case Assignment::A_PAR_TEMPL_IN:
13978 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13979 if (refd_ass_is_lazy_fpar) {
13980 *type_str = string("Lazy_Param<") + *type_str + string(">");
13981 }
13982 break;
13983 default:
13984 break;
13985 }
13986 // add the "const" part if the referenced assignment is a constant thing
13987 if (!refd_ass_is_lazy_fpar) {
13988 switch (ass->get_asstype()) {
13989 case Assignment::A_CONST:
13990 case Assignment::A_OC:
13991 case Assignment::A_OBJECT:
13992 case Assignment::A_OS:
13993 case Assignment::A_VS:
13994 case Assignment::A_EXT_CONST:
13995 case Assignment::A_MODULEPAR:
13996 case Assignment::A_MODULEPAR_TEMP:
13997 case Assignment::A_TEMPLATE:
13998 case Assignment::A_PAR_VAL:
13999 case Assignment::A_PAR_VAL_IN:
14000 case Assignment::A_PAR_TEMPL_IN:
14001 *type_str = string("const ") + *type_str;
14002 break;
14003 default:
14004 // nothing to do
14005 break;
14006 }
14007 }
14008 //
14009 type_vec->add(type_str);
14010 // store the C++ reference string
14011 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
14012 if (refd_ass_is_lazy_fpar) {
14013 Type* refd_ass_type = ass->get_Type();
14014 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);
14015 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
14016 } else {
14017 return get_member_name(refd_vec->size()-1);
14018 }
14019 }
14020
14021 string LazyParamData::get_member_name(size_t idx) {
14022 return string("lpm_") + Int2string(idx);
14023 }
14024
14025 string LazyParamData::get_constr_param_name(size_t idx) {
14026 return string("lpp_") + Int2string(idx);
14027 }
14028
14029 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
14030 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14031 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
14032 const string& tmp_id = val->get_temporary_id();
14033 const char *tmp_id_str = tmp_id.c_str();
14034 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14035 val->get_my_governor()->get_genname_value(my_scope).c_str(),
14036 tmp_id_str);
14037 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14038 tmp_id_str, val);
14039 expr->expr = mputstr(expr->expr, tmp_id_str);
14040 } else {
14041 val->generate_code_expr(expr);
14042 }
14043 }
14044
14045 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
14046 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14047 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
14048 const string& tmp_id = temp->get_Template()->get_temporary_id();
14049 const char *tmp_id_str = tmp_id.c_str();
14050 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14051 temp->get_Template()->get_my_governor()
14052 ->get_genname_template(my_scope).c_str(), tmp_id_str);
14053 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14054 tmp_id_str, temp->get_Template());
14055 // Not incorporated into gen_conv_code() yet.
14056 if (gen_restriction_check != TR_NONE)
14057 expr->preamble = Template::generate_restriction_check_code(
14058 expr->preamble, tmp_id_str, gen_restriction_check);
14059 expr->expr = mputstr(expr->expr, tmp_id_str);
14060 } else temp->generate_code(expr, gen_restriction_check);
14061 }
14062
14063 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
14064 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14065 if (depth>1) {
14066 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14067 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14068 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14069 expression_struct value_expr;
14070 Code::init_expr(&value_expr);
14071 generate_code_for_value(&value_expr, value, scope);
14072 // the id of the instance of Lazy_Param which will be used as the actual parameter
14073 const string& lazy_param_id = value->get_temporary_id();
14074 if (value_expr.preamble) {
14075 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
14076 }
14077 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14078 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14079 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
14080 Code::free_expr(&value_expr);
14081 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14082 return;
14083 }
14084 // only if the formal parameter is *not* used as lvalue
14085 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
14086 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
14087 if (refd_ass) {
14088 bool refd_ass_is_lazy_fpar = false;
14089 switch (refd_ass->get_asstype()) {
14090 case Assignment::A_PAR_VAL:
14091 case Assignment::A_PAR_VAL_IN:
14092 case Assignment::A_PAR_TEMPL_IN:
14093 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14094 break;
14095 default:
14096 break;
14097 }
14098 if (refd_ass_is_lazy_fpar) {
14099 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14100 return;
14101 }
14102 }
14103 }
14104 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14105 expression_struct value_expr;
14106 Code::init_expr(&value_expr);
14107 generate_code_for_value(&value_expr, value, scope);
14108 // the id of the instance of Lazy_Param which will be used as the actual parameter
14109 string lazy_param_id = value->get_temporary_id();
14110 string type_name = value->get_my_governor()->get_genname_value(scope);
14111 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
14112 }
14113
14114 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
14115 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14116 if (depth>1) {
14117 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14118 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14119 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14120 expression_struct tmpl_expr;
14121 Code::init_expr(&tmpl_expr);
14122 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14123 // the id of the instance of Lazy_Param which will be used as the actual parameter
14124 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
14125 if (tmpl_expr.preamble) {
14126 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
14127 }
14128 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14129 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14130 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
14131 Code::free_expr(&tmpl_expr);
14132 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14133 return;
14134 }
14135 // only if the formal parameter is *not* used as lvalue
14136 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
14137 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
14138 if (refd_ass) {
14139 bool refd_ass_is_lazy_fpar = false;
14140 switch (refd_ass->get_asstype()) {
14141 case Assignment::A_PAR_VAL:
14142 case Assignment::A_PAR_VAL_IN:
14143 case Assignment::A_PAR_TEMPL_IN:
14144 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14145 break;
14146 default:
14147 break;
14148 }
14149 if (refd_ass_is_lazy_fpar) {
14150 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14151 return;
14152 }
14153 }
14154 }
14155 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14156 expression_struct tmpl_expr;
14157 Code::init_expr(&tmpl_expr);
14158 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14159 // the id of the instance of Lazy_Param which will be used as the actual parameter
14160 string lazy_param_id = temp->get_Template()->get_temporary_id();
14161 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
14162 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
14163 }
14164
14165 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
14166 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
14167 if (type_vec->size()>0) {
14168 // private members of the local class will be const references to the objects referenced by the expression
14169 for (size_t i=0; i<type_vec->size(); i++) {
14170 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
14171 }
14172 expr->preamble = mputstr(expr->preamble, "public:\n");
14173 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
14174 for (size_t i=0; i<type_vec->size(); i++) {
14175 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14176 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
14177 }
14178 expr->preamble = mputstr(expr->preamble, "): ");
14179 for (size_t i=0; i<type_vec->size(); i++) {
14180 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14181 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
14182 }
14183 expr->preamble = mputstr(expr->preamble, " {}\n");
14184 expr->preamble = mputstr(expr->preamble, "private:\n");
14185 }
14186 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
14187 // use the temporary expr structure to fill the body of the eval_expr() function
14188 if (param_expr.preamble) {
14189 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
14190 }
14191 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
14192 if (param_expr.postamble) {
14193 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
14194 }
14195 Code::free_expr(&param_expr);
14196 expr->preamble = mputstr(expr->preamble, "}\n"
14197 "};\n" // end of local class definition
14198 );
14199 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
14200 if (type_vec->size()>0) {
14201 expr->preamble = mputc(expr->preamble, '(');
14202 // paramteres of the constructor are references to the objects used in the expression
14203 for (size_t i=0; i<refd_vec->size(); i++) {
14204 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14205 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
14206 }
14207 expr->preamble = mputc(expr->preamble, ')');
14208 }
14209 expr->preamble = mputstr(expr->preamble, ";\n");
14210 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14211 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
14212 }
14213
14214 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
14215 expression_struct ref_expr;
14216 Code::init_expr(&ref_expr);
14217 ref->generate_code(&ref_expr);
14218 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
14219 if (ref_expr.preamble) {
14220 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
14221 }
14222 Assignment* ass = ref->get_refd_assignment();
14223 // determine C++ type of the assignment
14224 string type_str;
14225 switch (ass->get_asstype()) {
14226 case Assignment::A_MODULEPAR_TEMP:
14227 case Assignment::A_TEMPLATE:
14228 case Assignment::A_VAR_TEMPLATE:
14229 case Assignment::A_PAR_TEMPL_IN:
14230 case Assignment::A_PAR_TEMPL_OUT:
14231 case Assignment::A_PAR_TEMPL_INOUT:
14232 type_str = ass->get_Type()->get_genname_template(scope);
14233 break;
14234 default:
14235 type_str = ass->get_Type()->get_genname_value(scope);
14236 }
14237 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14238 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
14239 if (ref_expr.postamble) {
14240 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
14241 }
14242 Code::free_expr(&ref_expr);
14243 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14244 }
14245
14246 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
14247 const string& lazy_param_id = value->get_temporary_id();
14248 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14249 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14250 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
14251 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14252 }
14253
14254 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
14255 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
14256 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14257 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14258 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
14259 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14260 }
14261
14262 } // namespace Common
This page took 0.396251 seconds and 6 git commands to generate.