added encvalue_unichar and decvalue_unichar built in functions (artf725502)
[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 u.expr.logargs = p.u.expr.logargs->clone();
344 break;
345 default:
346 FATAL_ERROR("Value::Value()");
347 } // switch
348 break;
349 case V_MACRO:
350 u.macro = p.u.macro;
351 break;
352 case V_FUNCTION:
353 case V_ALTSTEP:
354 case V_TESTCASE:
355 u.refd_fat = p.u.refd_fat;
356 break;
357 case V_INVOKE:
358 u.invoke.v = p.u.invoke.v->clone();
359 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
360 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
361 break;
362 case V_REFER:
363 u.refered = p.u.refered->clone();
364 break;
365 default:
366 FATAL_ERROR("Value::Value()");
367 } // switch
368 }
369
370 void Value::clean_up()
371 {
372 switch (valuetype) {
373 case V_ERROR:
374 case V_NULL:
375 case V_BOOL:
376 case V_REAL:
377 case V_OMIT:
378 case V_VERDICT:
379 case V_TTCN3_NULL:
380 case V_DEFAULT_NULL:
381 case V_FAT_NULL:
382 case V_MACRO:
383 case V_NOTUSED:
384 case V_FUNCTION:
385 case V_ALTSTEP:
386 case V_TESTCASE:
387 break;
388 case V_INT:
389 delete u.val_Int;
390 break;
391 case V_NAMEDINT:
392 case V_ENUM:
393 case V_UNDEF_LOWERID:
394 delete u.val_id;
395 break;
396 case V_BSTR:
397 case V_HSTR:
398 case V_OSTR:
399 case V_CSTR:
400 case V_ISO2022STR:
401 delete u.str.val_str;
402 clean_up_string_elements(u.str.str_elements);
403 break;
404 case V_USTR:
405 delete u.ustr.val_ustr;
406 clean_up_string_elements(u.ustr.ustr_elements);
407 break;
408 case V_CHARSYMS:
409 delete u.char_syms;
410 break;
411 case V_OID:
412 case V_ROID:
413 if (u.oid_comps) {
414 for(size_t i=0; i<u.oid_comps->size(); i++)
415 delete (*u.oid_comps)[i];
416 u.oid_comps->clear();
417 delete u.oid_comps;
418 }
419 break;
420 case V_EXPR:
421 clean_up_expr();
422 break;
423 case V_CHOICE:
424 delete u.choice.alt_name;
425 delete u.choice.alt_value;
426 break;
427 case V_SEQOF:
428 case V_SETOF:
429 case V_ARRAY:
430 delete u.val_vs;
431 break;
432 case V_SEQ:
433 case V_SET:
434 delete u.val_nvs;
435 break;
436 case V_REFD:
437 delete u.ref.ref;
438 break;
439 case V_REFER:
440 delete u.refered;
441 break;
442 case V_INVOKE:
443 delete u.invoke.v;
444 delete u.invoke.t_list;
445 delete u.invoke.ap_list;
446 break;
447 case V_NAMEDBITS:
448 if(u.ids) {
449 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
450 u.ids->clear();
451 delete u.ids;
452 }
453 break;
454 case V_UNDEF_BLOCK:
455 delete u.block;
456 break;
457 default:
458 FATAL_ERROR("Value::clean_up()");
459 } // switch
460 }
461
462 void Value::clean_up_expr()
463 {
464 switch (u.expr.state) {
465 case EXPR_CHECKING:
466 case EXPR_CHECKING_ERR:
467 FATAL_ERROR("Value::clean_up_expr()");
468 default:
469 break;
470 }
471 switch (u.expr.v_optype) {
472 case OPTYPE_RND: // -
473 case OPTYPE_COMP_NULL:
474 case OPTYPE_COMP_MTC:
475 case OPTYPE_COMP_SYSTEM:
476 case OPTYPE_COMP_SELF:
477 case OPTYPE_COMP_RUNNING_ANY:
478 case OPTYPE_COMP_RUNNING_ALL:
479 case OPTYPE_COMP_ALIVE_ANY:
480 case OPTYPE_COMP_ALIVE_ALL:
481 case OPTYPE_TMR_RUNNING_ANY:
482 case OPTYPE_GETVERDICT:
483 case OPTYPE_TESTCASENAME:
484 case OPTYPE_PROF_RUNNING:
485 break;
486 case OPTYPE_UNARYPLUS: // v1
487 case OPTYPE_UNARYMINUS:
488 case OPTYPE_NOT:
489 case OPTYPE_NOT4B:
490 case OPTYPE_BIT2HEX:
491 case OPTYPE_BIT2INT:
492 case OPTYPE_BIT2OCT:
493 case OPTYPE_BIT2STR:
494 case OPTYPE_CHAR2INT:
495 case OPTYPE_CHAR2OCT:
496 case OPTYPE_COMP_RUNNING:
497 case OPTYPE_COMP_ALIVE:
498 case OPTYPE_FLOAT2INT:
499 case OPTYPE_FLOAT2STR:
500 case OPTYPE_HEX2BIT:
501 case OPTYPE_HEX2INT:
502 case OPTYPE_HEX2OCT:
503 case OPTYPE_HEX2STR:
504 case OPTYPE_INT2CHAR:
505 case OPTYPE_INT2FLOAT:
506 case OPTYPE_INT2STR:
507 case OPTYPE_INT2UNICHAR:
508 case OPTYPE_OCT2BIT:
509 case OPTYPE_OCT2CHAR:
510 case OPTYPE_OCT2HEX:
511 case OPTYPE_OCT2INT:
512 case OPTYPE_OCT2STR:
513 case OPTYPE_STR2BIT:
514 case OPTYPE_STR2FLOAT:
515 case OPTYPE_STR2HEX:
516 case OPTYPE_STR2INT:
517 case OPTYPE_STR2OCT:
518 case OPTYPE_UNICHAR2INT:
519 case OPTYPE_UNICHAR2CHAR:
520 case OPTYPE_ENUM2INT:
521 case OPTYPE_RNDWITHVAL:
522 case OPTYPE_REMOVE_BOM:
523 case OPTYPE_GET_STRINGENCODING:
524 case OPTYPE_DECODE_BASE64:
525 delete u.expr.v1;
526 break;
527 case OPTYPE_ADD: // v1 v2
528 case OPTYPE_SUBTRACT:
529 case OPTYPE_MULTIPLY:
530 case OPTYPE_DIVIDE:
531 case OPTYPE_MOD:
532 case OPTYPE_REM:
533 case OPTYPE_CONCAT:
534 case OPTYPE_EQ:
535 case OPTYPE_LT:
536 case OPTYPE_GT:
537 case OPTYPE_NE:
538 case OPTYPE_GE:
539 case OPTYPE_LE:
540 case OPTYPE_AND:
541 case OPTYPE_OR:
542 case OPTYPE_XOR:
543 case OPTYPE_AND4B:
544 case OPTYPE_OR4B:
545 case OPTYPE_XOR4B:
546 case OPTYPE_SHL:
547 case OPTYPE_SHR:
548 case OPTYPE_ROTL:
549 case OPTYPE_ROTR:
550 case OPTYPE_INT2BIT:
551 case OPTYPE_INT2HEX:
552 case OPTYPE_INT2OCT:
553 case OPTYPE_UNICHAR2OCT:
554 case OPTYPE_OCT2UNICHAR:
555 case OPTYPE_ENCODE_BASE64:
556 delete u.expr.v1;
557 delete u.expr.v2;
558 break;
559 case OPTYPE_DECODE:
560 delete u.expr.r1;
561 delete u.expr.r2;
562 break;
563 case OPTYPE_SUBSTR:
564 delete u.expr.ti1;
565 delete u.expr.v2;
566 delete u.expr.v3;
567 break;
568 case OPTYPE_REGEXP:
569 delete u.expr.ti1;
570 delete u.expr.t2;
571 delete u.expr.v3;
572 break;
573 case OPTYPE_DECOMP: // v1 v2 v3
574 delete u.expr.v1;
575 delete u.expr.v2;
576 delete u.expr.v3;
577 break;
578 case OPTYPE_REPLACE:
579 delete u.expr.ti1;
580 delete u.expr.v2;
581 delete u.expr.v3;
582 delete u.expr.ti4;
583 break;
584 case OPTYPE_LENGTHOF: // ti1
585 case OPTYPE_SIZEOF: // ti1
586 case OPTYPE_VALUEOF: // ti1
587 case OPTYPE_ISVALUE:
588 case OPTYPE_ISBOUND:
589 case OPTYPE_ENCODE:
590 case OPTYPE_ISPRESENT:
591 case OPTYPE_TTCN2STRING:
592 delete u.expr.ti1;
593 break;
594 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
595 delete u.expr.ti1;
596 delete u.expr.v2;
597 break;
598 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
599 delete u.expr.r1;
600 delete u.expr.r2;
601 delete u.expr.v3;
602 break;
603 case OPTYPE_UNDEF_RUNNING:
604 case OPTYPE_TMR_READ:
605 case OPTYPE_TMR_RUNNING:
606 case OPTYPE_ACTIVATE:
607 delete u.expr.r1;
608 break;
609 case OPTYPE_EXECUTE: // r1 [v2]
610 delete u.expr.r1;
611 delete u.expr.v2;
612 break;
613 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
614 delete u.expr.r1;
615 delete u.expr.v2;
616 delete u.expr.v3;
617 break;
618 case OPTYPE_MATCH: // v1 t2
619 delete u.expr.v1;
620 delete u.expr.t2;
621 break;
622 case OPTYPE_ISCHOSEN: // r1 i2
623 delete u.expr.r1;
624 delete u.expr.i2;
625 break;
626 case OPTYPE_ISCHOSEN_V: // v1 i2
627 delete u.expr.v1;
628 delete u.expr.i2;
629 break;
630 case OPTYPE_ISCHOSEN_T: // t1 i2
631 delete u.expr.t1;
632 delete u.expr.i2;
633 break;
634 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
635 delete u.expr.v1;
636 if(u.expr.state!=EXPR_CHECKED)
637 delete u.expr.t_list2;
638 else
639 delete u.expr.ap_list2;
640 break;
641 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
642 delete u.expr.v1;
643 if(u.expr.state!=EXPR_CHECKED)
644 delete u.expr.t_list2;
645 else
646 delete u.expr.ap_list2;
647 delete u.expr.v3;
648 break;
649 case OPTYPE_LOG2STR:
650 delete u.expr.logargs;
651 break;
652 default:
653 FATAL_ERROR("Value::clean_up_expr()");
654 } // switch
655 }
656
657 void Value::copy_and_destroy(Value *src)
658 {
659 clean_up();
660 valuetype = src->valuetype;
661 u = src->u;
662 // update the pointer used for caching if it points to the value itself
663 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
664 src->valuetype = V_ERROR;
665 delete src;
666 }
667
668 Value::Value(valuetype_t p_vt)
669 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
670 {
671 switch(valuetype) {
672 case V_NULL:
673 case V_TTCN3_NULL:
674 case V_OMIT:
675 case V_NOTUSED:
676 case V_ERROR:
677 break;
678 case V_OID:
679 case V_ROID:
680 u.oid_comps=new vector<OID_comp>();
681 break;
682 case V_NAMEDBITS:
683 u.ids=new map<string, Identifier>();
684 break;
685 default:
686 FATAL_ERROR("Value::Value()");
687 } // switch
688 }
689
690 Value::Value(valuetype_t p_vt, bool p_val_bool)
691 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
692 {
693 switch(valuetype) {
694 case V_BOOL:
695 u.val_bool=p_val_bool;
696 break;
697 default:
698 FATAL_ERROR("Value::Value()");
699 } // switch
700 }
701
702 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
703 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
704 {
705 switch(valuetype) {
706 case V_INT:
707 u.val_Int=new int_val_t(p_val_Int);
708 break;
709 default:
710 FATAL_ERROR("Value::Value()");
711 } // switch
712 }
713
714 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
715 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
716 {
717 switch(valuetype){
718 case V_INT:
719 u.val_Int=p_val_Int;
720 break;
721 default:
722 FATAL_ERROR("Value::Value()");
723 }
724 }
725
726 Value::Value(valuetype_t p_vt, string *p_val_str)
727 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
728 {
729 if(!p_val_str) FATAL_ERROR("NULL parameter");
730 switch(valuetype) {
731 case V_BSTR:
732 case V_HSTR:
733 case V_OSTR:
734 case V_CSTR:
735 case V_ISO2022STR:
736 set_val_str(p_val_str);
737 break;
738 default:
739 FATAL_ERROR("Value::Value()");
740 } // switch
741 }
742
743 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
744 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
745 {
746 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
747 set_val_ustr(p_val_ustr);
748 u.ustr.convert_str = false;
749 }
750
751 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
752 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
753 {
754 if (!p_char_syms) FATAL_ERROR("NULL parameter");
755 switch (valuetype) {
756 case V_CHARSYMS:
757 u.char_syms = p_char_syms;
758 break;
759 default:
760 FATAL_ERROR("Value::Value()");
761 } // switch
762 }
763
764 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
765 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
766 {
767 if(!p_val_id)
768 FATAL_ERROR("NULL parameter");
769 switch(valuetype) {
770 case V_NAMEDINT:
771 case V_ENUM:
772 case V_UNDEF_LOWERID:
773 u.val_id=p_val_id;
774 break;
775 default:
776 FATAL_ERROR("Value::Value()");
777 } // switch
778 }
779
780 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
781 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
782 {
783 if(!p_id || !p_val)
784 FATAL_ERROR("NULL parameter");
785 switch(valuetype) {
786 case V_CHOICE:
787 u.choice.alt_name=p_id;
788 u.choice.alt_value=p_val;
789 break;
790 default:
791 FATAL_ERROR("Value::Value()");
792 } // switch
793 }
794
795 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
796 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
797 {
798 switch(valuetype) {
799 case V_REAL:
800 u.val_Real=p_val_Real;
801 break;
802 default:
803 FATAL_ERROR("Value::Value()");
804 } // switch
805 }
806
807 Value::Value(valuetype_t p_vt, Values *p_vs)
808 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
809 {
810 if(!p_vs) FATAL_ERROR("NULL parameter");
811 switch(valuetype) {
812 case V_SEQOF:
813 case V_SETOF:
814 case V_ARRAY:
815 u.val_vs=p_vs;
816 break;
817 default:
818 FATAL_ERROR("Value::Value()");
819 } // switch
820 }
821
822 Value::Value(valuetype_t p_vt, Value *p_v,
823 Ttcn::ParsedActualParameters *p_t_list)
824 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
825 {
826 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
827 switch(valuetype) {
828 case V_INVOKE:
829 u.invoke.v = p_v;
830 u.invoke.t_list = p_t_list;
831 u.invoke.ap_list = 0;
832 break;
833 default:
834 FATAL_ERROR("Value::Value()");
835 }
836 }
837
838 // -
839 Value::Value(operationtype_t p_optype)
840 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
841 {
842 u.expr.v_optype = p_optype;
843 u.expr.state = EXPR_NOT_CHECKED;
844 switch(p_optype) {
845 case OPTYPE_RND:
846 case OPTYPE_COMP_NULL:
847 case OPTYPE_COMP_MTC:
848 case OPTYPE_COMP_SYSTEM:
849 case OPTYPE_COMP_SELF:
850 case OPTYPE_COMP_RUNNING_ANY:
851 case OPTYPE_COMP_RUNNING_ALL:
852 case OPTYPE_COMP_ALIVE_ANY:
853 case OPTYPE_COMP_ALIVE_ALL:
854 case OPTYPE_TMR_RUNNING_ANY:
855 case OPTYPE_GETVERDICT:
856 case OPTYPE_TESTCASENAME:
857 case OPTYPE_PROF_RUNNING:
858 break;
859 default:
860 FATAL_ERROR("Value::Value()");
861 } // switch
862 }
863
864 // v1
865 Value::Value(operationtype_t p_optype, Value *p_v1)
866 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
867 {
868 u.expr.v_optype = p_optype;
869 u.expr.state = EXPR_NOT_CHECKED;
870 switch(p_optype) {
871 case OPTYPE_UNARYPLUS:
872 case OPTYPE_UNARYMINUS:
873 case OPTYPE_NOT:
874 case OPTYPE_NOT4B:
875 case OPTYPE_BIT2HEX:
876 case OPTYPE_BIT2INT:
877 case OPTYPE_BIT2OCT:
878 case OPTYPE_BIT2STR:
879 case OPTYPE_CHAR2INT:
880 case OPTYPE_CHAR2OCT:
881 case OPTYPE_COMP_RUNNING:
882 case OPTYPE_COMP_ALIVE:
883 case OPTYPE_FLOAT2INT:
884 case OPTYPE_FLOAT2STR:
885 case OPTYPE_HEX2BIT:
886 case OPTYPE_HEX2INT:
887 case OPTYPE_HEX2OCT:
888 case OPTYPE_HEX2STR:
889 case OPTYPE_INT2CHAR:
890 case OPTYPE_INT2FLOAT:
891 case OPTYPE_INT2STR:
892 case OPTYPE_INT2UNICHAR:
893 case OPTYPE_OCT2BIT:
894 case OPTYPE_OCT2CHAR:
895 case OPTYPE_OCT2HEX:
896 case OPTYPE_OCT2INT:
897 case OPTYPE_OCT2STR:
898 case OPTYPE_STR2BIT:
899 case OPTYPE_STR2FLOAT:
900 case OPTYPE_STR2HEX:
901 case OPTYPE_STR2INT:
902 case OPTYPE_STR2OCT:
903 case OPTYPE_UNICHAR2INT:
904 case OPTYPE_UNICHAR2CHAR:
905 case OPTYPE_ENUM2INT:
906 case OPTYPE_RNDWITHVAL:
907 case OPTYPE_REMOVE_BOM:
908 case OPTYPE_GET_STRINGENCODING:
909 case OPTYPE_DECODE_BASE64:
910 if(!p_v1) FATAL_ERROR("Value::Value()");
911 u.expr.v1=p_v1;
912 break;
913 default:
914 FATAL_ERROR("Value::Value()");
915 } // switch
916 }
917
918 // ti1
919 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
920 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
921 {
922 u.expr.v_optype = p_optype;
923 u.expr.state = EXPR_NOT_CHECKED;
924 switch(p_optype) {
925 case OPTYPE_LENGTHOF:
926 case OPTYPE_SIZEOF:
927 case OPTYPE_VALUEOF:
928 case OPTYPE_ISVALUE:
929 case OPTYPE_ISBOUND:
930 case OPTYPE_ENCODE:
931 case OPTYPE_ENCVALUE_UNICHAR:
932 case OPTYPE_ISPRESENT:
933 case OPTYPE_TTCN2STRING:
934 if(!p_ti1) FATAL_ERROR("Value::Value()");
935 u.expr.ti1=p_ti1;
936 break;
937 default:
938 FATAL_ERROR("Value::Value()");
939 } // switch
940 }
941
942 // r1
943 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
944 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
945 {
946 u.expr.v_optype = p_optype;
947 u.expr.state = EXPR_NOT_CHECKED;
948 switch(p_optype) {
949 case OPTYPE_UNDEF_RUNNING:
950 case OPTYPE_TMR_READ:
951 case OPTYPE_TMR_RUNNING:
952 case OPTYPE_ACTIVATE:
953 if(!p_r1) FATAL_ERROR("Value::Value()");
954 u.expr.r1=p_r1;
955 break;
956 default:
957 FATAL_ERROR("Value::Value()");
958 } // switch
959 }
960
961 // v1 t_list2
962 Value::Value(operationtype_t p_optype, Value *p_v1,
963 Ttcn::ParsedActualParameters *p_ap_list)
964 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
965 {
966 u.expr.v_optype = p_optype;
967 u.expr.state = EXPR_NOT_CHECKED;
968 switch(p_optype) {
969 case OPTYPE_ACTIVATE_REFD:
970 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
971 u.expr.v1 = p_v1;
972 u.expr.t_list2 = p_ap_list;
973 break;
974 default:
975 FATAL_ERROR("Value::Value()");
976 }
977 }
978
979 //v1 t_list2 v3
980 Value::Value(operationtype_t p_optype, Value *p_v1,
981 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
982 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
983 {
984 u.expr.v_optype = p_optype;
985 u.expr.state = EXPR_NOT_CHECKED;
986 switch(p_optype) {
987 case OPTYPE_EXECUTE_REFD:
988 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
989 u.expr.v1 = p_v1;
990 u.expr.t_list2 = p_t_list2;
991 u.expr.v3 = p_v3;
992 break;
993 default:
994 FATAL_ERROR("Value::Value()");
995 }
996 }
997
998 // r1 [v2]
999 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
1000 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1001 {
1002 u.expr.v_optype = p_optype;
1003 u.expr.state = EXPR_NOT_CHECKED;
1004 switch(p_optype) {
1005 case OPTYPE_EXECUTE:
1006 if(!p_r1) FATAL_ERROR("Value::Value()");
1007 u.expr.r1=p_r1;
1008 u.expr.v2=p_v2;
1009 break;
1010 default:
1011 FATAL_ERROR("Value::Value()");
1012 } // switch
1013 }
1014
1015 // r1 [v2] [v3] b4
1016 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
1017 Value *p_v2, Value *p_v3, bool p_b4)
1018 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1019 {
1020 u.expr.v_optype = p_optype;
1021 u.expr.state = EXPR_NOT_CHECKED;
1022 switch(p_optype) {
1023 case OPTYPE_COMP_CREATE:
1024 if(!p_r1) FATAL_ERROR("Value::Value()");
1025 u.expr.r1=p_r1;
1026 u.expr.v2=p_v2;
1027 u.expr.v3=p_v3;
1028 u.expr.b4=p_b4;
1029 break;
1030 default:
1031 FATAL_ERROR("Value::Value()");
1032 } // switch
1033 }
1034
1035 // v1 v2
1036 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
1037 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1038 {
1039 u.expr.v_optype = p_optype;
1040 u.expr.state = EXPR_NOT_CHECKED;
1041 switch(p_optype) {
1042 case OPTYPE_ADD:
1043 case OPTYPE_SUBTRACT:
1044 case OPTYPE_MULTIPLY:
1045 case OPTYPE_DIVIDE:
1046 case OPTYPE_MOD:
1047 case OPTYPE_REM:
1048 case OPTYPE_CONCAT:
1049 case OPTYPE_EQ:
1050 case OPTYPE_LT:
1051 case OPTYPE_GT:
1052 case OPTYPE_NE:
1053 case OPTYPE_GE:
1054 case OPTYPE_LE:
1055 case OPTYPE_AND:
1056 case OPTYPE_OR:
1057 case OPTYPE_XOR:
1058 case OPTYPE_AND4B:
1059 case OPTYPE_OR4B:
1060 case OPTYPE_XOR4B:
1061 case OPTYPE_SHL:
1062 case OPTYPE_SHR:
1063 case OPTYPE_ROTL:
1064 case OPTYPE_ROTR:
1065 case OPTYPE_INT2BIT:
1066 case OPTYPE_INT2HEX:
1067 case OPTYPE_INT2OCT:
1068 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1069 u.expr.v1=p_v1;
1070 u.expr.v2=p_v2;
1071 break;
1072 case OPTYPE_UNICHAR2OCT:
1073 case OPTYPE_OCT2UNICHAR:
1074 case OPTYPE_ENCODE_BASE64:
1075 if(!p_v1) FATAL_ERROR("Value::Value()");
1076 u.expr.v1=p_v1;
1077 // p_v2 may be NULL if there is no second param
1078 u.expr.v2=p_v2;
1079 break;
1080 default:
1081 FATAL_ERROR("Value::Value()");
1082 } // switch
1083 }
1084
1085 // ti1 v2 v3 ti4
1086 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1087 Value *p_v3, TemplateInstance *p_ti4) :
1088 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1089 {
1090 u.expr.v_optype = p_optype;
1091 u.expr.state = EXPR_NOT_CHECKED;
1092 switch (p_optype) {
1093 case OPTYPE_REPLACE:
1094 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1095 u.expr.ti1 = p_ti1;
1096 u.expr.v2 = p_v2;
1097 u.expr.v3 = p_v3;
1098 u.expr.ti4 = p_ti4;
1099 break;
1100 default:
1101 FATAL_ERROR("Value::Value()");
1102 } // switch
1103 }
1104
1105 // v1 v2 v3
1106 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1107 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1108 {
1109 u.expr.v_optype = p_optype;
1110 u.expr.state = EXPR_NOT_CHECKED;
1111 switch(p_optype) {
1112 case OPTYPE_DECOMP:
1113 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1114 u.expr.v1=p_v1;
1115 u.expr.v2=p_v2;
1116 u.expr.v3=p_v3;
1117 break;
1118 default:
1119 FATAL_ERROR("Value::Value()");
1120 } // switch
1121 }
1122
1123 // ti1 [v2]
1124 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2)
1125 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1126 {
1127 u.expr.v_optype = p_optype;
1128 u.expr.state = EXPR_NOT_CHECKED;
1129 switch(p_optype) {
1130 case OPTYPE_ENCVALUE_UNICHAR:
1131 if(!p_ti1 || !p_v2) FATAL_ERROR("Value::Value()");
1132 u.expr.ti1=p_ti1;
1133 u.expr.v2=p_v2;
1134 break;
1135 default:
1136 FATAL_ERROR("Value::Value()");
1137 } // switch
1138 }
1139
1140 // ti1 v2 v3
1141 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1142 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1143 {
1144 u.expr.v_optype=p_optype;
1145 u.expr.state=EXPR_NOT_CHECKED;
1146 switch(p_optype) {
1147 case OPTYPE_SUBSTR:
1148 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1149 u.expr.ti1 = p_ti1;
1150 u.expr.v2=p_v2;
1151 u.expr.v3=p_v3;
1152 break;
1153 default:
1154 FATAL_ERROR("Value::Value()");
1155 } // switch
1156 }
1157
1158 // ti1 t2 v3
1159 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1160 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1161 {
1162 u.expr.v_optype=p_optype;
1163 u.expr.state=EXPR_NOT_CHECKED;
1164 switch(p_optype) {
1165 case OPTYPE_REGEXP:
1166 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1167 u.expr.ti1 = p_ti1;
1168 u.expr.t2 = p_t2;
1169 u.expr.v3=p_v3;
1170 break;
1171 default:
1172 FATAL_ERROR("Value::Value()");
1173 } // switch
1174 }
1175
1176 // v1 t2
1177 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1178 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1179 {
1180 u.expr.v_optype = p_optype;
1181 u.expr.state = EXPR_NOT_CHECKED;
1182 switch(p_optype) {
1183 case OPTYPE_MATCH:
1184 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1185 u.expr.v1=p_v1;
1186 u.expr.t2=p_t2;
1187 break;
1188 default:
1189 FATAL_ERROR("Value::Value()");
1190 } // switch
1191 }
1192
1193 // r1 i2
1194 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1195 Identifier *p_i2)
1196 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1197 {
1198 u.expr.v_optype = p_optype;
1199 u.expr.state = EXPR_NOT_CHECKED;
1200 switch(p_optype) {
1201 case OPTYPE_ISCHOSEN:
1202 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1203 u.expr.r1=p_r1;
1204 u.expr.i2=p_i2;
1205 break;
1206 default:
1207 FATAL_ERROR("Value::Value()");
1208 } // switch
1209 }
1210
1211 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1212 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1213 {
1214 u.expr.v_optype = p_optype;
1215 u.expr.state = EXPR_NOT_CHECKED;
1216 switch(p_optype) {
1217 case OPTYPE_LOG2STR:
1218 if (!p_logargs) FATAL_ERROR("Value::Value()");
1219 u.expr.logargs = p_logargs;
1220 break;
1221 default:
1222 FATAL_ERROR("Value::Value()");
1223 } // switch
1224 }
1225
1226 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1227 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1228 {
1229 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1230 switch (p_macrotype) {
1231 case MACRO_MODULEID:
1232 case MACRO_FILENAME:
1233 case MACRO_BFILENAME:
1234 case MACRO_FILEPATH:
1235 case MACRO_LINENUMBER:
1236 case MACRO_LINENUMBER_C:
1237 case MACRO_DEFINITIONID:
1238 case MACRO_SCOPE:
1239 case MACRO_TESTCASEID:
1240 break;
1241 default:
1242 FATAL_ERROR("Value::Value()");
1243 }
1244 u.macro = p_macrotype;
1245 }
1246
1247 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1248 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1249 {
1250 if(!p_nvs) FATAL_ERROR("NULL parameter");
1251 switch(valuetype) {
1252 case V_SEQ:
1253 case V_SET:
1254 u.val_nvs=p_nvs;
1255 break;
1256 default:
1257 FATAL_ERROR("Value::Value()");
1258 } // switch
1259 }
1260
1261 Value::Value(valuetype_t p_vt, Reference *p_ref)
1262 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1263 {
1264 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1265 switch(p_vt) {
1266 case V_REFD:
1267 u.ref.ref = p_ref;
1268 u.ref.refd_last = 0;
1269 break;
1270 case V_REFER:
1271 u.refered = p_ref;
1272 break;
1273 default:
1274 FATAL_ERROR("Value::Value()");
1275 }
1276 }
1277
1278 Value::Value(valuetype_t p_vt, Block *p_block)
1279 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1280 {
1281 if(!p_block) FATAL_ERROR("NULL parameter");
1282 switch(valuetype) {
1283 case V_UNDEF_BLOCK:
1284 u.block=p_block;
1285 break;
1286 default:
1287 FATAL_ERROR("Value::Value()");
1288 } // switch
1289 }
1290
1291 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1292 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1293 {
1294 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1295 switch (p_verdict) {
1296 case Verdict_NONE:
1297 case Verdict_PASS:
1298 case Verdict_INCONC:
1299 case Verdict_FAIL:
1300 case Verdict_ERROR:
1301 break;
1302 default:
1303 FATAL_ERROR("Value::Value()");
1304 } // switch
1305 u.verdict = p_verdict;
1306 }
1307
1308 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1309 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1310 {
1311 u.expr.v_optype = p_optype;
1312 u.expr.state = EXPR_NOT_CHECKED;
1313 switch(p_optype) {
1314 case OPTYPE_DECODE:
1315 case OPTYPE_DECVALUE_UNICHAR:
1316 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1317 u.expr.r1=p_r1;
1318 u.expr.r2=p_r2;
1319 break;
1320 default:
1321 FATAL_ERROR("Value::Value()");
1322 } // switch
1323 }
1324
1325 // r1 r2 [v3]
1326 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2,
1327 Value *p_v3)
1328 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1329 {
1330 u.expr.v_optype = p_optype;
1331 u.expr.state = EXPR_NOT_CHECKED;
1332 switch(p_optype) {
1333 case OPTYPE_DECVALUE_UNICHAR:
1334 if(!p_r1 || !p_r2 || !p_v3) FATAL_ERROR("Value::Value()");
1335 u.expr.r1=p_r1;
1336 u.expr.r2=p_r2;
1337 u.expr.v3=p_v3;
1338 break;
1339 default:
1340 FATAL_ERROR("Value::Value()");
1341 } // switch
1342 }
1343
1344 Value::~Value()
1345 {
1346 clean_up();
1347 }
1348
1349 Value *Value::clone() const
1350 {
1351 return new Value(*this);
1352 }
1353
1354 Value::operationtype_t Value::get_optype() const
1355 {
1356 if(valuetype!=V_EXPR)
1357 FATAL_ERROR("Value::get_optype()");
1358 return u.expr.v_optype;
1359 }
1360
1361 void Value::set_my_governor(Type *p_gov)
1362 {
1363 if(!p_gov)
1364 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1365 my_governor=p_gov;
1366 }
1367
1368 Type *Value::get_my_governor() const
1369 {
1370 return my_governor;
1371 }
1372
1373 void Value::set_fullname(const string& p_fullname)
1374 {
1375 GovernedSimple::set_fullname(p_fullname);
1376 switch(valuetype) {
1377 case V_CHARSYMS:
1378 u.char_syms->set_fullname(p_fullname);
1379 break;
1380 case V_OID:
1381 case V_ROID:
1382 for(size_t i=0; i<u.oid_comps->size(); i++)
1383 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1384 break;
1385 case V_CHOICE:
1386 u.choice.alt_value->set_fullname(p_fullname + "." +
1387 u.choice.alt_name->get_dispname());
1388 break;
1389 case V_SEQOF:
1390 case V_SETOF:
1391 case V_ARRAY:
1392 u.val_vs->set_fullname(p_fullname);
1393 break;
1394 case V_SEQ:
1395 case V_SET:
1396 u.val_nvs->set_fullname(p_fullname);
1397 break;
1398 case V_REFD:
1399 u.ref.ref->set_fullname(p_fullname);
1400 break;
1401 case V_REFER:
1402 u.refered->set_fullname(p_fullname);
1403 break;
1404 case V_INVOKE:
1405 u.invoke.v->set_fullname(p_fullname);
1406 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1407 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1408 break;
1409 case V_EXPR:
1410 set_fullname_expr(p_fullname);
1411 break;
1412 default:
1413 break;
1414 } // switch
1415 }
1416
1417 void Value::set_my_scope(Scope *p_scope)
1418 {
1419 GovernedSimple::set_my_scope(p_scope);
1420 switch(valuetype) {
1421 case V_CHARSYMS:
1422 u.char_syms->set_my_scope(p_scope);
1423 break;
1424 case V_OID:
1425 case V_ROID:
1426 for(size_t i=0; i<u.oid_comps->size(); i++)
1427 (*u.oid_comps)[i]->set_my_scope(p_scope);
1428 break;
1429 case V_CHOICE:
1430 u.choice.alt_value->set_my_scope(p_scope);
1431 break;
1432 case V_SEQOF:
1433 case V_SETOF:
1434 case V_ARRAY:
1435 u.val_vs->set_my_scope(p_scope);
1436 break;
1437 case V_SEQ:
1438 case V_SET:
1439 u.val_nvs->set_my_scope(p_scope);
1440 break;
1441 case V_REFD:
1442 u.ref.ref->set_my_scope(p_scope);
1443 break;
1444 case V_REFER:
1445 u.refered->set_my_scope(p_scope);
1446 break;
1447 case V_INVOKE:
1448 u.invoke.v->set_my_scope(p_scope);
1449 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1450 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1451 break;
1452 case V_EXPR:
1453 set_my_scope_expr(p_scope);
1454 break;
1455 default:
1456 break;
1457 } // switch
1458 }
1459
1460 void Value::set_fullname_expr(const string& p_fullname)
1461 {
1462 switch (u.expr.v_optype) {
1463 case OPTYPE_RND: // -
1464 case OPTYPE_COMP_NULL:
1465 case OPTYPE_COMP_MTC:
1466 case OPTYPE_COMP_SYSTEM:
1467 case OPTYPE_COMP_SELF:
1468 case OPTYPE_COMP_RUNNING_ANY:
1469 case OPTYPE_COMP_RUNNING_ALL:
1470 case OPTYPE_COMP_ALIVE_ANY:
1471 case OPTYPE_COMP_ALIVE_ALL:
1472 case OPTYPE_TMR_RUNNING_ANY:
1473 case OPTYPE_GETVERDICT:
1474 case OPTYPE_TESTCASENAME:
1475 case OPTYPE_PROF_RUNNING:
1476 break;
1477 case OPTYPE_UNARYPLUS: // v1
1478 case OPTYPE_UNARYMINUS:
1479 case OPTYPE_NOT:
1480 case OPTYPE_NOT4B:
1481 case OPTYPE_BIT2HEX:
1482 case OPTYPE_BIT2INT:
1483 case OPTYPE_BIT2OCT:
1484 case OPTYPE_BIT2STR:
1485 case OPTYPE_CHAR2INT:
1486 case OPTYPE_CHAR2OCT:
1487 case OPTYPE_COMP_RUNNING:
1488 case OPTYPE_COMP_ALIVE:
1489 case OPTYPE_FLOAT2INT:
1490 case OPTYPE_FLOAT2STR:
1491 case OPTYPE_HEX2BIT:
1492 case OPTYPE_HEX2INT:
1493 case OPTYPE_HEX2OCT:
1494 case OPTYPE_HEX2STR:
1495 case OPTYPE_INT2CHAR:
1496 case OPTYPE_INT2FLOAT:
1497 case OPTYPE_INT2STR:
1498 case OPTYPE_INT2UNICHAR:
1499 case OPTYPE_OCT2BIT:
1500 case OPTYPE_OCT2CHAR:
1501 case OPTYPE_OCT2HEX:
1502 case OPTYPE_OCT2INT:
1503 case OPTYPE_OCT2STR:
1504 case OPTYPE_STR2BIT:
1505 case OPTYPE_STR2FLOAT:
1506 case OPTYPE_STR2HEX:
1507 case OPTYPE_STR2INT:
1508 case OPTYPE_STR2OCT:
1509 case OPTYPE_UNICHAR2INT:
1510 case OPTYPE_UNICHAR2CHAR:
1511 case OPTYPE_ENUM2INT:
1512 case OPTYPE_RNDWITHVAL:
1513 case OPTYPE_REMOVE_BOM:
1514 case OPTYPE_GET_STRINGENCODING:
1515 case OPTYPE_DECODE_BASE64:
1516 u.expr.v1->set_fullname(p_fullname+".<operand>");
1517 break;
1518 case OPTYPE_ADD: // v1 v2
1519 case OPTYPE_SUBTRACT:
1520 case OPTYPE_MULTIPLY:
1521 case OPTYPE_DIVIDE:
1522 case OPTYPE_MOD:
1523 case OPTYPE_REM:
1524 case OPTYPE_CONCAT:
1525 case OPTYPE_EQ:
1526 case OPTYPE_LT:
1527 case OPTYPE_GT:
1528 case OPTYPE_NE:
1529 case OPTYPE_GE:
1530 case OPTYPE_LE:
1531 case OPTYPE_AND:
1532 case OPTYPE_OR:
1533 case OPTYPE_XOR:
1534 case OPTYPE_AND4B:
1535 case OPTYPE_OR4B:
1536 case OPTYPE_XOR4B:
1537 case OPTYPE_SHL:
1538 case OPTYPE_SHR:
1539 case OPTYPE_ROTL:
1540 case OPTYPE_ROTR:
1541 case OPTYPE_INT2BIT:
1542 case OPTYPE_INT2HEX:
1543 case OPTYPE_INT2OCT:
1544 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1545 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1546 break;
1547 case OPTYPE_UNICHAR2OCT:
1548 case OPTYPE_OCT2UNICHAR:
1549 case OPTYPE_ENCODE_BASE64:
1550 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1551 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1552 break;
1553 case OPTYPE_DECODE:
1554 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1555 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1556 break;
1557 case OPTYPE_SUBSTR:
1558 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1559 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1560 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1561 break;
1562 case OPTYPE_REGEXP:
1563 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1564 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1565 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1566 break;
1567 case OPTYPE_DECOMP: // v1 v2 v3
1568 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1569 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1570 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1571 break;
1572 case OPTYPE_REPLACE:
1573 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1574 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1575 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1576 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1577 break;
1578 case OPTYPE_LENGTHOF: // ti1
1579 case OPTYPE_SIZEOF: // ti1
1580 case OPTYPE_VALUEOF: // ti1
1581 case OPTYPE_ISVALUE:
1582 case OPTYPE_ISBOUND:
1583 case OPTYPE_ENCODE:
1584 case OPTYPE_ISPRESENT:
1585 case OPTYPE_TTCN2STRING:
1586 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1587 break;
1588 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
1589 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1590 if (u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1591 break;
1592 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1593 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1594 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1595 if (u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1596 case OPTYPE_UNDEF_RUNNING: // r1
1597 case OPTYPE_TMR_READ:
1598 case OPTYPE_TMR_RUNNING:
1599 case OPTYPE_ACTIVATE:
1600 u.expr.r1->set_fullname(p_fullname+".<operand>");
1601 break;
1602 case OPTYPE_EXECUTE: // r1 [v2]
1603 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1604 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1605 break;
1606 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1607 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1608 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1609 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1610 break;
1611 case OPTYPE_MATCH: // v1 t2
1612 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1613 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1614 break;
1615 case OPTYPE_ISCHOSEN: // r1 i2
1616 u.expr.r1->set_fullname(p_fullname+".<operand>");
1617 break;
1618 case OPTYPE_ISCHOSEN_V: // v1 i2
1619 u.expr.v1->set_fullname(p_fullname+".<operand>");
1620 break;
1621 case OPTYPE_ISCHOSEN_T: // t1 i2
1622 u.expr.t1->set_fullname(p_fullname+".<operand>");
1623 break;
1624 case OPTYPE_ACTIVATE_REFD:
1625 u.expr.v1->set_fullname(p_fullname+".<reference>");
1626 if(u.expr.state!=EXPR_CHECKED)
1627 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1628 else
1629 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1630 break;
1631 case OPTYPE_EXECUTE_REFD:
1632 u.expr.v1->set_fullname(p_fullname+".<reference>");
1633 if(u.expr.state!=EXPR_CHECKED)
1634 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1635 else
1636 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1637 if(u.expr.v3)
1638 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1639 break;
1640 case OPTYPE_LOG2STR:
1641 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1642 break;
1643 default:
1644 FATAL_ERROR("Value::set_fullname_expr()");
1645 } // switch
1646 }
1647
1648 void Value::set_my_scope_expr(Scope *p_scope)
1649 {
1650 switch (u.expr.v_optype) {
1651 case OPTYPE_RND: // -
1652 case OPTYPE_COMP_NULL:
1653 case OPTYPE_COMP_MTC:
1654 case OPTYPE_COMP_SYSTEM:
1655 case OPTYPE_COMP_SELF:
1656 case OPTYPE_COMP_RUNNING_ANY:
1657 case OPTYPE_COMP_RUNNING_ALL:
1658 case OPTYPE_COMP_ALIVE_ANY:
1659 case OPTYPE_COMP_ALIVE_ALL:
1660 case OPTYPE_TMR_RUNNING_ANY:
1661 case OPTYPE_GETVERDICT:
1662 case OPTYPE_TESTCASENAME:
1663 case OPTYPE_PROF_RUNNING:
1664 break;
1665 case OPTYPE_UNARYPLUS: // v1
1666 case OPTYPE_UNARYMINUS:
1667 case OPTYPE_NOT:
1668 case OPTYPE_NOT4B:
1669 case OPTYPE_BIT2HEX:
1670 case OPTYPE_BIT2INT:
1671 case OPTYPE_BIT2OCT:
1672 case OPTYPE_BIT2STR:
1673 case OPTYPE_CHAR2INT:
1674 case OPTYPE_CHAR2OCT:
1675 case OPTYPE_COMP_RUNNING:
1676 case OPTYPE_COMP_ALIVE:
1677 case OPTYPE_FLOAT2INT:
1678 case OPTYPE_FLOAT2STR:
1679 case OPTYPE_HEX2BIT:
1680 case OPTYPE_HEX2INT:
1681 case OPTYPE_HEX2OCT:
1682 case OPTYPE_HEX2STR:
1683 case OPTYPE_INT2CHAR:
1684 case OPTYPE_INT2FLOAT:
1685 case OPTYPE_INT2STR:
1686 case OPTYPE_INT2UNICHAR:
1687 case OPTYPE_OCT2BIT:
1688 case OPTYPE_OCT2CHAR:
1689 case OPTYPE_OCT2HEX:
1690 case OPTYPE_OCT2INT:
1691 case OPTYPE_OCT2STR:
1692 case OPTYPE_STR2BIT:
1693 case OPTYPE_STR2FLOAT:
1694 case OPTYPE_STR2HEX:
1695 case OPTYPE_STR2INT:
1696 case OPTYPE_STR2OCT:
1697 case OPTYPE_UNICHAR2INT:
1698 case OPTYPE_UNICHAR2CHAR:
1699 case OPTYPE_ENUM2INT:
1700 case OPTYPE_RNDWITHVAL:
1701 case OPTYPE_REMOVE_BOM:
1702 case OPTYPE_GET_STRINGENCODING:
1703 case OPTYPE_DECODE_BASE64:
1704 u.expr.v1->set_my_scope(p_scope);
1705 break;
1706 case OPTYPE_ADD: // v1 v2
1707 case OPTYPE_SUBTRACT:
1708 case OPTYPE_MULTIPLY:
1709 case OPTYPE_DIVIDE:
1710 case OPTYPE_MOD:
1711 case OPTYPE_REM:
1712 case OPTYPE_CONCAT:
1713 case OPTYPE_EQ:
1714 case OPTYPE_LT:
1715 case OPTYPE_GT:
1716 case OPTYPE_NE:
1717 case OPTYPE_GE:
1718 case OPTYPE_LE:
1719 case OPTYPE_AND:
1720 case OPTYPE_OR:
1721 case OPTYPE_XOR:
1722 case OPTYPE_AND4B:
1723 case OPTYPE_OR4B:
1724 case OPTYPE_XOR4B:
1725 case OPTYPE_SHL:
1726 case OPTYPE_SHR:
1727 case OPTYPE_ROTL:
1728 case OPTYPE_ROTR:
1729 case OPTYPE_INT2BIT:
1730 case OPTYPE_INT2HEX:
1731 case OPTYPE_INT2OCT:
1732 u.expr.v1->set_my_scope(p_scope);
1733 u.expr.v2->set_my_scope(p_scope);
1734 break;
1735 case OPTYPE_UNICHAR2OCT:
1736 case OPTYPE_OCT2UNICHAR:
1737 case OPTYPE_ENCODE_BASE64:
1738 u.expr.v1->set_my_scope(p_scope);
1739 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1740 break;
1741 case OPTYPE_DECODE:
1742 u.expr.r1->set_my_scope(p_scope);
1743 u.expr.r2->set_my_scope(p_scope);
1744 break;
1745 case OPTYPE_SUBSTR:
1746 u.expr.ti1->set_my_scope(p_scope);
1747 u.expr.v2->set_my_scope(p_scope);
1748 u.expr.v3->set_my_scope(p_scope);
1749 break;
1750 case OPTYPE_REGEXP:
1751 u.expr.ti1->set_my_scope(p_scope);
1752 u.expr.t2->set_my_scope(p_scope);
1753 u.expr.v3->set_my_scope(p_scope);
1754 break;
1755 case OPTYPE_DECOMP: // v1 v2 v3
1756 u.expr.v1->set_my_scope(p_scope);
1757 u.expr.v2->set_my_scope(p_scope);
1758 u.expr.v3->set_my_scope(p_scope);
1759 break;
1760 case OPTYPE_REPLACE:
1761 u.expr.ti1->set_my_scope(p_scope);
1762 u.expr.v2->set_my_scope(p_scope);
1763 u.expr.v3->set_my_scope(p_scope);
1764 u.expr.ti4->set_my_scope(p_scope);
1765 break;
1766 case OPTYPE_LENGTHOF: // ti1
1767 case OPTYPE_SIZEOF: // ti1
1768 case OPTYPE_VALUEOF: // ti1
1769 case OPTYPE_ISVALUE:
1770 case OPTYPE_ISBOUND:
1771 case OPTYPE_ENCODE:
1772 case OPTYPE_ISPRESENT:
1773 case OPTYPE_TTCN2STRING:
1774 u.expr.ti1->set_my_scope(p_scope);
1775 break;
1776 case OPTYPE_ENCVALUE_UNICHAR: //ti1 [v2]
1777 u.expr.ti1->set_my_scope(p_scope);
1778 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1779 break;
1780 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1781 u.expr.r1->set_my_scope(p_scope);
1782 u.expr.r2->set_my_scope(p_scope);
1783 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1784 break;
1785 case OPTYPE_UNDEF_RUNNING: // r1
1786 case OPTYPE_TMR_READ:
1787 case OPTYPE_TMR_RUNNING:
1788 case OPTYPE_ACTIVATE:
1789 u.expr.r1->set_my_scope(p_scope);
1790 break;
1791 case OPTYPE_EXECUTE: // r1 [v2]
1792 u.expr.r1->set_my_scope(p_scope);
1793 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1794 break;
1795 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1796 u.expr.r1->set_my_scope(p_scope);
1797 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1798 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1799 break;
1800 case OPTYPE_MATCH: // v1 t2
1801 u.expr.v1->set_my_scope(p_scope);
1802 u.expr.t2->set_my_scope(p_scope);
1803 break;
1804 case OPTYPE_ISCHOSEN: // r1 i2
1805 u.expr.r1->set_my_scope(p_scope);
1806 break;
1807 case OPTYPE_ISCHOSEN_V: // v1 i2
1808 u.expr.v1->set_my_scope(p_scope);
1809 break;
1810 case OPTYPE_ISCHOSEN_T: // t1 i2
1811 u.expr.t1->set_my_scope(p_scope);
1812 break;
1813 case OPTYPE_ACTIVATE_REFD:
1814 u.expr.v1->set_my_scope(p_scope);
1815 if(u.expr.state!=EXPR_CHECKED) {
1816 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1817 else
1818 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1819 } break;
1820 case OPTYPE_EXECUTE_REFD:
1821 u.expr.v1->set_my_scope(p_scope);
1822 if(u.expr.state!=EXPR_CHECKED) {
1823 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1824 else
1825 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1826 }
1827 if(u.expr.v3)
1828 u.expr.v3->set_my_scope(p_scope);
1829 break;
1830 case OPTYPE_LOG2STR:
1831 u.expr.logargs->set_my_scope(p_scope);
1832 break;
1833 default:
1834 FATAL_ERROR("Value::set_my_scope_expr()");
1835 } // switch
1836 }
1837
1838 void Value::set_genname_recursive(const string& p_genname)
1839 {
1840 size_t genname_len = p_genname.size();
1841 if (genname_len >= 4 &&
1842 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1843 // if the genname ends with ()() (i.e. the value stands for an optional
1844 // field) then drop the last () from the own genname, but leave it for
1845 // the embedded values
1846 set_genname(p_genname.substr(0, genname_len - 2));
1847 } else set_genname(p_genname);
1848 switch(valuetype) {
1849 case V_CHOICE: {
1850 string embedded_genname(p_genname);
1851 embedded_genname += '.';
1852 // If this is a choice value for an anytype, prepend the AT_ prefix
1853 // to the name of the alternative. The genname is used later in
1854 // Common::Value::generate_code_init_se()
1855 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1856 embedded_genname += "AT_";
1857 embedded_genname += u.choice.alt_name->get_name();
1858 embedded_genname += "()";
1859 u.choice.alt_value->set_genname_recursive(embedded_genname);
1860 break; }
1861 case V_SEQOF:
1862 case V_SETOF: {
1863 if (!is_indexed()) {
1864 size_t nof_vs = u.val_vs->get_nof_vs();
1865 for (size_t i = 0; i < nof_vs; i++) {
1866 string embedded_genname(p_genname);
1867 embedded_genname += '[';
1868 embedded_genname += Int2string(i);
1869 embedded_genname += ']';
1870 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1871 }
1872 } else {
1873 size_t nof_ivs = u.val_vs->get_nof_ivs();
1874 for (size_t i = 0; i < nof_ivs; i++) {
1875 string embedded_genname(p_genname);
1876 embedded_genname += '[';
1877 embedded_genname += Int2string(i);
1878 embedded_genname += ']';
1879 u.val_vs->get_iv_byIndex(i)->get_value()
1880 ->set_genname_recursive(embedded_genname);
1881 }
1882 }
1883 break; }
1884 case V_ARRAY: {
1885 if (!my_governor) return; // error recovery
1886 Type *type = my_governor->get_type_refd_last();
1887 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1888 Int offset = type->get_dimension()->get_offset();
1889 if (!is_indexed()) {
1890 size_t nof_vs = u.val_vs->get_nof_vs();
1891 for (size_t i = 0; i < nof_vs; i++) {
1892 string embedded_genname(p_genname);
1893 embedded_genname += '[';
1894 embedded_genname += Int2string(offset + i);
1895 embedded_genname += ']';
1896 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1897 }
1898 } else {
1899 size_t nof_ivs = u.val_vs->get_nof_ivs();
1900 for (size_t i = 0; i < nof_ivs; i++) {
1901 string embedded_genname(p_genname);
1902 embedded_genname += '[';
1903 embedded_genname += Int2string(offset + i);
1904 embedded_genname += ']';
1905 u.val_vs->get_iv_byIndex(i)->get_value()
1906 ->set_genname_recursive(embedded_genname);
1907 }
1908 }
1909 break; }
1910 case V_SEQ:
1911 case V_SET: {
1912 if (!my_governor) return; // error recovery
1913 Type *t = my_governor->get_type_refd_last();
1914 if (!t->is_secho()) return; // error recovery
1915 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1916 for (size_t i = 0; i < nof_nvs; i++) {
1917 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1918 const Identifier& id = nv->get_name();
1919 if (!t->has_comp_withName(id)) return; // error recovery
1920 string embedded_genname(p_genname);
1921 embedded_genname += '.';
1922 embedded_genname += id.get_name();
1923 embedded_genname += "()";
1924 if (t->get_comp_byName(id)->get_is_optional())
1925 embedded_genname += "()";
1926 nv->get_value()->set_genname_recursive(embedded_genname);
1927 }
1928 break; }
1929 default:
1930 break;
1931 } // switch
1932 }
1933
1934 void Value::set_genname_prefix(const char *p_genname_prefix)
1935 {
1936 GovernedSimple::set_genname_prefix(p_genname_prefix);
1937 switch(valuetype) {
1938 case V_CHOICE:
1939 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1940 break;
1941 case V_SEQOF:
1942 case V_SETOF:
1943 case V_ARRAY:
1944 if (!is_indexed()) {
1945 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1946 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1947 } else {
1948 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1949 u.val_vs->get_iv_byIndex(i)->get_value()
1950 ->set_genname_prefix(p_genname_prefix);
1951 }
1952 break;
1953 case V_SEQ:
1954 case V_SET:
1955 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1956 u.val_nvs->get_nv_byIndex(i)->get_value()
1957 ->set_genname_prefix(p_genname_prefix);
1958 break;
1959 default:
1960 break;
1961 } // switch
1962 }
1963
1964 void Value::set_code_section(code_section_t p_code_section)
1965 {
1966 GovernedSimple::set_code_section(p_code_section);
1967 switch(valuetype) {
1968 case V_EXPR:
1969 switch (u.expr.v_optype) {
1970 case OPTYPE_RND: // -
1971 case OPTYPE_COMP_NULL:
1972 case OPTYPE_COMP_MTC:
1973 case OPTYPE_COMP_SYSTEM:
1974 case OPTYPE_COMP_SELF:
1975 case OPTYPE_COMP_RUNNING_ANY:
1976 case OPTYPE_COMP_RUNNING_ALL:
1977 case OPTYPE_COMP_ALIVE_ANY:
1978 case OPTYPE_COMP_ALIVE_ALL:
1979 case OPTYPE_TMR_RUNNING_ANY:
1980 case OPTYPE_GETVERDICT:
1981 case OPTYPE_TESTCASENAME:
1982 case OPTYPE_PROF_RUNNING:
1983 break;
1984 case OPTYPE_UNARYPLUS: // v1
1985 case OPTYPE_UNARYMINUS:
1986 case OPTYPE_NOT:
1987 case OPTYPE_NOT4B:
1988 case OPTYPE_BIT2HEX:
1989 case OPTYPE_BIT2INT:
1990 case OPTYPE_BIT2OCT:
1991 case OPTYPE_BIT2STR:
1992 case OPTYPE_CHAR2INT:
1993 case OPTYPE_CHAR2OCT:
1994 case OPTYPE_COMP_RUNNING:
1995 case OPTYPE_COMP_ALIVE:
1996 case OPTYPE_FLOAT2INT:
1997 case OPTYPE_FLOAT2STR:
1998 case OPTYPE_HEX2BIT:
1999 case OPTYPE_HEX2INT:
2000 case OPTYPE_HEX2OCT:
2001 case OPTYPE_HEX2STR:
2002 case OPTYPE_INT2CHAR:
2003 case OPTYPE_INT2FLOAT:
2004 case OPTYPE_INT2STR:
2005 case OPTYPE_INT2UNICHAR:
2006 case OPTYPE_OCT2BIT:
2007 case OPTYPE_OCT2CHAR:
2008 case OPTYPE_OCT2HEX:
2009 case OPTYPE_OCT2INT:
2010 case OPTYPE_OCT2STR:
2011 case OPTYPE_STR2BIT:
2012 case OPTYPE_STR2FLOAT:
2013 case OPTYPE_STR2HEX:
2014 case OPTYPE_STR2INT:
2015 case OPTYPE_STR2OCT:
2016 case OPTYPE_UNICHAR2INT:
2017 case OPTYPE_UNICHAR2CHAR:
2018 case OPTYPE_ENUM2INT:
2019 case OPTYPE_RNDWITHVAL:
2020 case OPTYPE_GET_STRINGENCODING:
2021 case OPTYPE_DECODE_BASE64:
2022 case OPTYPE_REMOVE_BOM:
2023 u.expr.v1->set_code_section(p_code_section);
2024 break;
2025 case OPTYPE_ADD: // v1 v2
2026 case OPTYPE_SUBTRACT:
2027 case OPTYPE_MULTIPLY:
2028 case OPTYPE_DIVIDE:
2029 case OPTYPE_MOD:
2030 case OPTYPE_REM:
2031 case OPTYPE_CONCAT:
2032 case OPTYPE_EQ:
2033 case OPTYPE_LT:
2034 case OPTYPE_GT:
2035 case OPTYPE_NE:
2036 case OPTYPE_GE:
2037 case OPTYPE_LE:
2038 case OPTYPE_AND:
2039 case OPTYPE_OR:
2040 case OPTYPE_XOR:
2041 case OPTYPE_AND4B:
2042 case OPTYPE_OR4B:
2043 case OPTYPE_XOR4B:
2044 case OPTYPE_SHL:
2045 case OPTYPE_SHR:
2046 case OPTYPE_ROTL:
2047 case OPTYPE_ROTR:
2048 case OPTYPE_INT2BIT:
2049 case OPTYPE_INT2HEX:
2050 case OPTYPE_INT2OCT:
2051 u.expr.v1->set_code_section(p_code_section);
2052 u.expr.v2->set_code_section(p_code_section);
2053 break;
2054 case OPTYPE_UNICHAR2OCT:
2055 case OPTYPE_OCT2UNICHAR:
2056 case OPTYPE_ENCODE_BASE64:
2057 u.expr.v1->set_code_section(p_code_section);
2058 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2059 break;
2060 case OPTYPE_DECODE:
2061 u.expr.r1->set_code_section(p_code_section);
2062 u.expr.r2->set_code_section(p_code_section);
2063 break;
2064 case OPTYPE_SUBSTR:
2065 u.expr.ti1->set_code_section(p_code_section);
2066 u.expr.v2->set_code_section(p_code_section);
2067 u.expr.v3->set_code_section(p_code_section);
2068 break;
2069 case OPTYPE_REGEXP:
2070 u.expr.ti1->set_code_section(p_code_section);
2071 u.expr.t2->set_code_section(p_code_section);
2072 u.expr.v3->set_code_section(p_code_section);
2073 break;
2074 case OPTYPE_DECOMP: // v1 v2 v3
2075 u.expr.v1->set_code_section(p_code_section);
2076 u.expr.v2->set_code_section(p_code_section);
2077 u.expr.v3->set_code_section(p_code_section);
2078 break;
2079 case OPTYPE_REPLACE:
2080 u.expr.ti1->set_code_section(p_code_section);
2081 u.expr.v2->set_code_section(p_code_section);
2082 u.expr.v3->set_code_section(p_code_section);
2083 u.expr.ti4->set_code_section(p_code_section);
2084 break;
2085 case OPTYPE_LENGTHOF: // ti1
2086 case OPTYPE_SIZEOF: // ti1
2087 case OPTYPE_VALUEOF: // ti1
2088 case OPTYPE_ISVALUE:
2089 case OPTYPE_ISBOUND:
2090 case OPTYPE_ENCODE:
2091 case OPTYPE_ISPRESENT:
2092 case OPTYPE_TTCN2STRING:
2093 u.expr.ti1->set_code_section(p_code_section);
2094 break;
2095 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
2096 u.expr.ti1->set_code_section(p_code_section);
2097 if (u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2098 break;
2099 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
2100 u.expr.r1->set_code_section(p_code_section);
2101 u.expr.r2->set_code_section(p_code_section);
2102 if (u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2103 break;
2104 case OPTYPE_UNDEF_RUNNING: // r1
2105 case OPTYPE_TMR_READ:
2106 case OPTYPE_TMR_RUNNING:
2107 case OPTYPE_ACTIVATE:
2108 u.expr.r1->set_code_section(p_code_section);
2109 break;
2110 case OPTYPE_EXECUTE: // r1 [v2]
2111 u.expr.r1->set_code_section(p_code_section);
2112 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2113 break;
2114 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2115 u.expr.r1->set_code_section(p_code_section);
2116 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2117 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2118 break;
2119 case OPTYPE_MATCH: // v1 t2
2120 u.expr.v1->set_code_section(p_code_section);
2121 u.expr.t2->set_code_section(p_code_section);
2122 break;
2123 case OPTYPE_ISCHOSEN: // r1 i2
2124 u.expr.r1->set_code_section(p_code_section);
2125 break;
2126 case OPTYPE_ISCHOSEN_V: // v1 i2
2127 u.expr.v1->set_code_section(p_code_section);
2128 break;
2129 case OPTYPE_ISCHOSEN_T: // t1 i2
2130 u.expr.t1->set_code_section(p_code_section);
2131 break;
2132 case OPTYPE_ACTIVATE_REFD:
2133 u.expr.v1->set_code_section(p_code_section);
2134 if(u.expr.state!=EXPR_CHECKED)
2135 u.expr.t_list2->set_code_section(p_code_section);
2136 else {
2137 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2138 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2139 u.expr.state = EXPR_CHECKED;
2140 }
2141 break;
2142 case OPTYPE_EXECUTE_REFD:
2143 u.expr.v1->set_code_section(p_code_section);
2144 if(u.expr.state!=EXPR_CHECKED)
2145 u.expr.t_list2->set_code_section(p_code_section);
2146 else {
2147 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2148 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2149 u.expr.state = EXPR_CHECKED;
2150 }
2151 if(u.expr.v3)
2152 u.expr.v3->set_code_section(p_code_section);
2153 break;
2154 case OPTYPE_LOG2STR:
2155 u.expr.logargs->set_code_section(p_code_section);
2156 break;
2157 default:
2158 FATAL_ERROR("Value::set_code_section()");
2159 } // switch
2160 break;
2161 case V_CHOICE:
2162 u.choice.alt_value->set_code_section(p_code_section);
2163 break;
2164 case V_SEQOF:
2165 case V_SETOF:
2166 case V_ARRAY:
2167 if (!is_indexed()) {
2168 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2169 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2170 } else {
2171 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2172 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2173 }
2174 break;
2175 case V_SEQ:
2176 case V_SET:
2177 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2178 u.val_nvs->get_nv_byIndex(i)->get_value()
2179 ->set_code_section(p_code_section);
2180 break;
2181 case V_REFD:
2182 u.ref.ref->set_code_section(p_code_section);
2183 break;
2184 case V_REFER:
2185 u.refered->set_code_section(p_code_section);
2186 break;
2187 case V_INVOKE:
2188 u.invoke.v->set_code_section(p_code_section);
2189 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2190 if(u.invoke.ap_list)
2191 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2192 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2193 break;
2194 default:
2195 break;
2196 } // switch
2197 }
2198
2199 void Value::change_sign()
2200 {
2201 switch(valuetype) {
2202 case V_INT:
2203 *u.val_Int=-*u.val_Int;
2204 break;
2205 case V_REAL:
2206 u.val_Real*=-1.0;
2207 break;
2208 case V_ERROR:
2209 break;
2210 default:
2211 FATAL_ERROR("Value::change_sign()");
2212 } // switch
2213 }
2214
2215 void Value::add_oid_comp(OID_comp* p_comp)
2216 {
2217 if(!p_comp)
2218 FATAL_ERROR("NULL parameter");
2219 u.oid_comps->add(p_comp);
2220 p_comp->set_fullname(get_fullname()+"."
2221 +Int2string(u.oid_comps->size()));
2222 p_comp->set_my_scope(my_scope);
2223 }
2224
2225 void Value::set_valuetype(valuetype_t p_valuetype)
2226 {
2227 if (valuetype == V_ERROR) return;
2228 else if (p_valuetype == V_ERROR) {
2229 if(valuetype==V_EXPR) {
2230 switch(u.expr.state) {
2231 case EXPR_CHECKING:
2232 u.expr.state=EXPR_CHECKING_ERR;
2233 // no break
2234 case EXPR_CHECKING_ERR:
2235 return;
2236 default:
2237 break;
2238 }
2239 }
2240 clean_up();
2241 valuetype = V_ERROR;
2242 return;
2243 }
2244 switch(valuetype) {
2245 case V_UNDEF_LOWERID:
2246 switch(p_valuetype) {
2247 case V_ENUM:
2248 case V_NAMEDINT:
2249 break;
2250 case V_REFD:
2251 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2252 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2253 u.ref.ref->set_my_scope(get_my_scope());
2254 u.ref.ref->set_fullname(get_fullname());
2255 u.ref.ref->set_location(*this);
2256 u.ref.refd_last = 0;
2257 break;
2258 default:
2259 FATAL_ERROR("Value::set_valuetype()");
2260 } // switch
2261 break;
2262 case V_UNDEF_BLOCK: {
2263 Block *t_block=u.block;
2264 Value *v=0;
2265 switch(p_valuetype) {
2266 case V_NAMEDBITS: {
2267 Node *node=t_block->parse(KW_Block_IdentifierList);
2268 v=dynamic_cast<Value*>(node);
2269 if(!v) {
2270 /* syntax error */
2271 u.ids=new map<string, Identifier>();
2272 }
2273 else {
2274 u.ids=v->u.ids; v->u.ids=0;
2275 }
2276 break;}
2277 case V_SEQOF: {
2278 Node *node=t_block->parse(KW_Block_SeqOfValue);
2279 v=dynamic_cast<Value*>(node);
2280 if(!v) {
2281 /* syntax error */
2282 u.val_vs=new Values();
2283 }
2284 else {
2285 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2286 }
2287 u.val_vs->set_my_scope(get_my_scope());
2288 u.val_vs->set_fullname(get_fullname());
2289 break;}
2290 case V_SETOF: {
2291 Node *node=t_block->parse(KW_Block_SetOfValue);
2292 v=dynamic_cast<Value*>(node);
2293 if(!v) {
2294 /* syntax error */
2295 u.val_vs=new Values();
2296 }
2297 else {
2298 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2299 }
2300 u.val_vs->set_my_scope(get_my_scope());
2301 u.val_vs->set_fullname(get_fullname());
2302 break;}
2303 case V_SEQ: {
2304 Node *node=t_block->parse(KW_Block_SequenceValue);
2305 v=dynamic_cast<Value*>(node);
2306 if(!v) {
2307 /* syntax error */
2308 u.val_nvs=new NamedValues();
2309 }
2310 else {
2311 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2312 }
2313 u.val_nvs->set_my_scope(get_my_scope());
2314 u.val_nvs->set_fullname(get_fullname());
2315 break;}
2316 case V_SET: {
2317 Node *node=t_block->parse(KW_Block_SetValue);
2318 v=dynamic_cast<Value*>(node);
2319 if(!v) {
2320 /* syntax error */
2321 u.val_nvs=new NamedValues();
2322 }
2323 else {
2324 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2325 }
2326 u.val_nvs->set_my_scope(get_my_scope());
2327 u.val_nvs->set_fullname(get_fullname());
2328 break;}
2329 case V_OID: {
2330 Node *node=t_block->parse(KW_Block_OIDValue);
2331 v=dynamic_cast<Value*>(node);
2332 if(!v) {
2333 /* syntax error */
2334 u.oid_comps=new vector<OID_comp>();
2335 }
2336 else {
2337 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2338 }
2339 for (size_t i = 0; i < u.oid_comps->size(); i++)
2340 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2341 break;}
2342 case V_ROID: {
2343 Node *node=t_block->parse(KW_Block_ROIDValue);
2344 v=dynamic_cast<Value*>(node);
2345 if(!v) {
2346 /* syntax error */
2347 u.oid_comps=new vector<OID_comp>();
2348 }
2349 else {
2350 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2351 }
2352 for (size_t i = 0; i < u.oid_comps->size(); i++)
2353 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2354 break;}
2355 case V_CHARSYMS: {
2356 Node *node=t_block->parse(KW_Block_CharStringValue);
2357 u.char_syms=dynamic_cast<CharSyms*>(node);
2358 if(!u.char_syms) {
2359 /* syntax error */
2360 u.char_syms=new CharSyms();
2361 }
2362 u.char_syms->set_my_scope(get_my_scope());
2363 u.char_syms->set_fullname(get_fullname());
2364 break;}
2365 default:
2366 FATAL_ERROR("Value::set_valuetype()");
2367 } // switch
2368 delete v;
2369 delete t_block;
2370 break;}
2371 case V_REFD:
2372 if (p_valuetype == V_USTR) {
2373 Value *v_last = get_value_refd_last();
2374 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2375 ustring *ustr = new ustring(*v_last->u.str.val_str);
2376 delete u.ref.ref;
2377 set_val_ustr(ustr);
2378 u.ustr.convert_str = true; // will be converted back to string
2379 } else FATAL_ERROR("Value::set_valuetype()");
2380 break;
2381 case V_CHARSYMS:
2382 switch(p_valuetype) {
2383 case V_CSTR: {
2384 const string& str = u.char_syms->get_string();
2385 delete u.char_syms;
2386 set_val_str(new string(str));
2387 break;}
2388 case V_USTR: {
2389 const ustring& ustr = u.char_syms->get_ustring();
2390 delete u.char_syms;
2391 set_val_ustr(new ustring(ustr));
2392 u.ustr.convert_str = false;
2393 break;}
2394 case V_ISO2022STR: {
2395 const string& str = u.char_syms->get_iso2022string();
2396 delete u.char_syms;
2397 set_val_str(new string(str));
2398 break;}
2399 default:
2400 FATAL_ERROR("Value::set_valuetype()");
2401 } // switch
2402 break;
2403 case V_INT: {
2404 Real val_Real;
2405 if (p_valuetype == V_REAL)
2406 val_Real = u.val_Int->to_real();
2407 else FATAL_ERROR("Value::set_valuetype()");
2408 clean_up();
2409 u.val_Real = val_Real;
2410 break; }
2411 case V_HSTR: {
2412 clean_up_string_elements(u.str.str_elements);
2413 string *old_str = u.str.val_str;
2414 switch(p_valuetype) {
2415 case V_BSTR:
2416 set_val_str(hex2bit(*old_str));
2417 break;
2418 case V_OSTR:
2419 set_val_str(asn_hex2oct(*old_str));
2420 break;
2421 default:
2422 FATAL_ERROR("Value::set_valuetype()");
2423 } // switch
2424 delete old_str;
2425 break;}
2426 case V_BSTR:
2427 clean_up_string_elements(u.str.str_elements);
2428 if (p_valuetype == V_OSTR) {
2429 string *old_str = u.str.val_str;
2430 set_val_str(asn_bit2oct(*old_str));
2431 delete old_str;
2432 } else FATAL_ERROR("Value::set_valuetype()");
2433 break;
2434 case V_CSTR:
2435 clean_up_string_elements(u.str.str_elements);
2436 switch(p_valuetype) {
2437 case V_USTR: {
2438 string *old_str = u.str.val_str;
2439 set_val_ustr(new ustring(*old_str));
2440 u.ustr.convert_str = true; // will be converted back to string
2441 delete old_str;
2442 break;}
2443 case V_ISO2022STR:
2444 // do nothing
2445 break;
2446 default:
2447 FATAL_ERROR("Value::set_valuetype()");
2448 } // switch p_valuetype
2449 break;
2450 case V_USTR:
2451 clean_up_string_elements(u.ustr.ustr_elements);
2452 switch(p_valuetype) {
2453 case V_CSTR: {
2454 ustring *old_str = u.ustr.val_ustr;
2455 size_t nof_chars = old_str->size();
2456 bool warning_flag = false;
2457 for (size_t i = 0; i < nof_chars; i++) {
2458 const ustring::universal_char& uchar = (*old_str)[i];
2459 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2460 error("This string value cannot contain multiple-byte characters, "
2461 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2462 uchar.group, uchar.plane, uchar.row, uchar.cell,
2463 (unsigned long) i);
2464 p_valuetype = V_ERROR;
2465 break;
2466 } else if (uchar.cell > 127 && !warning_flag) {
2467 warning("This string value may not contain characters with code "
2468 "higher than 127, but it has character with code %u (0x%02X) "
2469 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2470 warning_flag = true;
2471 }
2472 }
2473 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2474 delete old_str;
2475 break; }
2476 case V_ISO2022STR:
2477 error("ISO-10646 string value cannot be converted to "
2478 "ISO-2022 string");
2479 delete u.ustr.val_ustr;
2480 p_valuetype = V_ERROR;
2481 break;
2482 default:
2483 FATAL_ERROR("Value::set_valuetype()");
2484 } // switch p_valuetype
2485 break;
2486 case V_SEQ:
2487 switch (p_valuetype) {
2488 case V_CHOICE: {
2489 NamedValues *nvs = u.val_nvs;
2490 if (nvs->get_nof_nvs() < 1) {
2491 error("Union value must have one active field");
2492 delete nvs;
2493 valuetype = V_ERROR;
2494 return;
2495 } else if (nvs->get_nof_nvs() > 1) {
2496 error("Only one field was expected in union value instead of %lu",
2497 (unsigned long) nvs->get_nof_nvs());
2498 }
2499 NamedValue *nv = nvs->get_nv_byIndex(0);
2500 u.choice.alt_name = nv->get_name().clone();
2501 u.choice.alt_value = nv->steal_value();
2502 delete nvs;
2503 break;}
2504 case V_SET:
2505 // do nothing
2506 break;
2507 case V_REAL: {
2508 NamedValues *nvs = u.val_nvs;
2509 bool err = false;
2510 /* mantissa */
2511 Int i_mant = 0;
2512 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2513 if (nvs->has_nv_withName(id_mant)) {
2514 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2515 ->get_value_refd_last();
2516 if (v_tmp->get_valuetype() == V_INT) {
2517 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2518 if (*i_mant_int > INT_MAX) {
2519 error("Mantissa `%s' should be less than `%d'",
2520 (i_mant_int->t_str()).c_str(), INT_MAX);
2521 err = true;
2522 } else {
2523 i_mant = i_mant_int->get_val();
2524 }
2525 }
2526 else err = true;
2527 }
2528 else err = true;
2529 /* base */
2530 Int i_base = 0;
2531 Identifier id_base(Identifier::ID_ASN, string("base"));
2532 if (!err && nvs->has_nv_withName(id_base)) {
2533 Value *v = nvs->get_nv_byName(id_base)->get_value();
2534 Value *v_tmp = v->get_value_refd_last();
2535 if (v_tmp->get_valuetype() == V_INT) {
2536 const int_val_t *i_base_int = v_tmp->get_val_Int();
2537 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2538 v->error("Base of the REAL must be 2 or 10");
2539 err = true;
2540 } else {
2541 i_base = i_base_int->get_val();
2542 }
2543 }
2544 else err = true;
2545 }
2546 else err = true;
2547 /* exponent */
2548 Int i_exp = 0;
2549 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2550 if (!err && nvs->has_nv_withName(id_exp)) {
2551 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2552 ->get_value_refd_last();
2553 if (v_tmp->get_valuetype() == V_INT) {
2554 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2555 if (*i_exp_int > INT_MAX) {
2556 error("Exponent `%s' should be less than `%d'",
2557 (i_exp_int->t_str()).c_str(), INT_MAX);
2558 err = true;
2559 } else {
2560 i_exp = i_exp_int->get_val();
2561 }
2562 }
2563 else err = true;
2564 }
2565 else err = true;
2566 /* clean up */
2567 delete nvs;
2568 if (err) {
2569 valuetype = V_ERROR;
2570 return;
2571 }
2572 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2573 static_cast<double>(i_exp));
2574 break; }
2575 case V_NOTUSED:
2576 clean_up();
2577 break;
2578 default:
2579 FATAL_ERROR("Value::set_valuetype()");
2580 } // switch
2581 break;
2582 case V_SEQOF:
2583 switch (p_valuetype) {
2584 case V_SEQ: {
2585 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2586 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2587 Type *t = my_governor->get_type_refd_last();
2588 switch (t->get_typetype()) {
2589 case Type::T_SEQ_T:
2590 case Type::T_SEQ_A:
2591 break;
2592 default:
2593 FATAL_ERROR("Value::set_valuetype()");
2594 }
2595 Values *vals = u.val_vs;
2596 size_t nof_vals = vals->get_nof_vs();
2597 size_t nof_comps = t->get_nof_comps();
2598 if (nof_vals > nof_comps) {
2599 error("Too many elements in value list notation for type `%s': "
2600 "%lu was expected instead of %lu",
2601 t->get_typename().c_str(),
2602 (unsigned long)nof_comps, (unsigned long)nof_vals);
2603 }
2604 size_t upper_limit;
2605 bool allnotused;
2606 if (nof_vals <= nof_comps) {
2607 upper_limit = nof_vals;
2608 allnotused = true;
2609 } else {
2610 upper_limit = nof_comps;
2611 allnotused = false;
2612 }
2613 u.val_nvs = new NamedValues;
2614 for (size_t i = 0; i < upper_limit; i++) {
2615 Value *v = vals->steal_v_byIndex(i);
2616 if (v->valuetype != V_NOTUSED) {
2617 allnotused = false;
2618 }
2619 NamedValue *nv =
2620 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2621 nv->set_location(*v);
2622 u.val_nvs->add_nv(nv);
2623 }
2624 u.val_nvs->set_my_scope(get_my_scope());
2625 u.val_nvs->set_fullname(get_fullname());
2626 delete vals;
2627 if (allnotused && nof_vals > 0)
2628 warning("All elements of value list notation for type `%s' are not "
2629 "used symbols (`-')", t->get_typename().c_str());
2630 break; }
2631 case V_SET:
2632 // { } -> empty set value
2633 if (u.val_vs->get_nof_vs() != 0)
2634 FATAL_ERROR("Value::set_valuetype()");
2635 delete u.val_vs;
2636 u.val_nvs = new NamedValues;
2637 break;
2638 case V_SETOF:
2639 case V_ARRAY:
2640 // SEQOF -> SETOF or ARRAY: trivial
2641 break;
2642 default:
2643 FATAL_ERROR("Value::set_valuetype()");
2644 }
2645 break;
2646 case V_SET:
2647 case V_CHOICE:
2648 if (p_valuetype == V_NOTUSED) {
2649 clean_up();
2650 }
2651 else {
2652 FATAL_ERROR("Value::set_valuetype()");
2653 }
2654 break;
2655 case V_TTCN3_NULL:
2656 switch (p_valuetype) {
2657 case V_DEFAULT_NULL:
2658 break;
2659 case V_FAT_NULL:
2660 break;
2661 default:
2662 FATAL_ERROR("Value::set_valuetype()");
2663 }
2664 break;
2665 case V_NOTUSED:
2666 if (V_OMIT != p_valuetype) { // in case of implicit omit
2667 FATAL_ERROR("Value::set_valuetype()");
2668 }
2669 break;
2670 default:
2671 FATAL_ERROR("Value::set_valuetype()");
2672 } // switch
2673 valuetype=p_valuetype;
2674 }
2675
2676 void Value::set_valuetype_COMP_NULL()
2677 {
2678 if(valuetype == V_ERROR) return;
2679 if(valuetype==V_TTCN3_NULL) {
2680 valuetype=V_EXPR;
2681 u.expr.v_optype=OPTYPE_COMP_NULL;
2682 // Nothing to check.
2683 u.expr.state=EXPR_CHECKED;
2684 }
2685 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2686 }
2687
2688 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2689 {
2690 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2691 delete u.val_id;
2692 u.val_Int = new int_val_t(p_val_int);
2693 valuetype = V_INT;
2694 } else FATAL_ERROR("Value::set_valuetype()");
2695 }
2696
2697 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2698 {
2699 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2700 clean_up();
2701 valuetype = V_BSTR;
2702 set_val_str(p_str);
2703 } else FATAL_ERROR("Value::set_valuetype()");
2704 }
2705
2706 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2707 {
2708 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2709 delete u.val_id;
2710 u.val_id = p_id;
2711 valuetype = V_ENUM;
2712 } else FATAL_ERROR("Value::set_valuetype()");
2713 }
2714
2715 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2716 {
2717 switch (p_valuetype) {
2718 case V_FUNCTION:
2719 case V_ALTSTEP:
2720 case V_TESTCASE:
2721 if (valuetype == V_REFER && p_ass) break;
2722 // no break
2723 default:
2724 FATAL_ERROR("Value::set_valuetype()");
2725 }
2726 delete u.refered;
2727 u.refd_fat = p_ass;
2728 valuetype = p_valuetype;
2729 }
2730
2731 bool Value::is_undef_lowerid()
2732 {
2733 switch (valuetype) {
2734 case V_UNDEF_LOWERID:
2735 return true;
2736 case V_EXPR:
2737 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2738 !u.expr.ti1->get_DerivedRef()) {
2739 return u.expr.ti1->get_Template()->is_undef_lowerid();
2740 }
2741 // no break
2742 default:
2743 return false;
2744 }
2745 }
2746
2747 const Identifier& Value::get_undef_lowerid()
2748 {
2749 switch (valuetype) {
2750 case V_UNDEF_LOWERID:
2751 return *u.val_id;
2752 case V_EXPR:
2753 if (u.expr.v_optype != OPTYPE_VALUEOF)
2754 FATAL_ERROR("Value::get_undef_lowerid()");
2755 return u.expr.ti1->get_Template()->get_specific_value()
2756 ->get_undef_lowerid();
2757 default:
2758 FATAL_ERROR("Value::get_undef_lowerid()");
2759 }
2760 const Identifier *dummy = 0;
2761 return *dummy;
2762 }
2763
2764 void Value::set_lowerid_to_ref()
2765 {
2766 switch (valuetype) {
2767 case V_UNDEF_LOWERID:
2768 set_valuetype(V_REFD);
2769 break;
2770 case V_EXPR:
2771 // if the governor of the expression is not known (in log(), etc...)
2772 // then the governor is taken from the reference (using
2773 // v1/ti1->get_expr_governor()), but that runs before the
2774 // params were checked, this smells like a workaround :)
2775 switch (u.expr.v_optype) {
2776 case OPTYPE_ROTL:
2777 case OPTYPE_ROTR:
2778 u.expr.v1->set_lowerid_to_ref();
2779 break;
2780 case OPTYPE_CONCAT:
2781 u.expr.v1->set_lowerid_to_ref();
2782 u.expr.v2->set_lowerid_to_ref();
2783 break;
2784 case OPTYPE_VALUEOF:
2785 case OPTYPE_ISVALUE:
2786 case OPTYPE_ISBOUND:
2787 case OPTYPE_ISPRESENT:
2788 case OPTYPE_SUBSTR:
2789 case OPTYPE_REGEXP:
2790 case OPTYPE_REPLACE:
2791 case OPTYPE_TTCN2STRING:
2792 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2793 Error_Context cntxt(u.expr.ti1->get_Template(),
2794 "In the operand of operation `%s'",
2795 get_opname());
2796 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2797 }
2798 if (u.expr.v_optype==OPTYPE_REGEXP) {
2799 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2800 Error_Context cntxt(u.expr.t2->get_Template(),
2801 "In the operand of operation `%s'",
2802 get_opname());
2803 u.expr.t2->get_Template()->set_lowerid_to_ref();
2804 }
2805 }
2806 if (u.expr.v_optype==OPTYPE_REPLACE) {
2807 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2808 Error_Context cntxt(u.expr.ti4->get_Template(),
2809 "In the operand of operation `%s'",
2810 get_opname());
2811 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2812 }
2813 }
2814 break;
2815 default:
2816 break;
2817 }
2818 break;
2819 default:
2820 break;
2821 }
2822 }
2823
2824 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2825 {
2826 switch (valuetype) {
2827 case V_CHARSYMS:
2828 case V_CHOICE:
2829 case V_SEQOF:
2830 case V_SETOF:
2831 case V_ARRAY:
2832 case V_SEQ:
2833 case V_SET:
2834 case V_UNDEF_LOWERID:
2835 case V_UNDEF_BLOCK:
2836 case V_OMIT:
2837 case V_TTCN3_NULL:
2838 case V_NOTUSED:
2839 case V_REFER:
2840 case V_FAT_NULL:
2841 return Type::T_UNDEF;
2842 case V_NAMEDINT:
2843 case V_NAMEDBITS:
2844 case V_OPENTYPE:
2845 FATAL_ERROR("Value::get_expr_returntype()");
2846 case V_ERROR:
2847 return Type::T_ERROR;
2848 case V_REFD:
2849 case V_INVOKE: {
2850 Type *t = get_expr_governor(exp_val);
2851 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2852 else return Type::T_ERROR; }
2853 case V_FUNCTION:
2854 return Type::T_FUNCTION;
2855 case V_ALTSTEP:
2856 return Type::T_ALTSTEP;
2857 case V_TESTCASE:
2858 return Type::T_TESTCASE;
2859 case V_EXPR:
2860 switch(u.expr.v_optype) {
2861 case OPTYPE_COMP_NULL:
2862 case OPTYPE_COMP_MTC:
2863 case OPTYPE_COMP_SYSTEM:
2864 case OPTYPE_COMP_SELF:
2865 case OPTYPE_COMP_CREATE:
2866 return Type::T_COMPONENT;
2867 case OPTYPE_UNDEF_RUNNING:
2868 case OPTYPE_COMP_RUNNING:
2869 case OPTYPE_COMP_RUNNING_ANY:
2870 case OPTYPE_COMP_RUNNING_ALL:
2871 case OPTYPE_COMP_ALIVE:
2872 case OPTYPE_COMP_ALIVE_ANY:
2873 case OPTYPE_COMP_ALIVE_ALL:
2874 case OPTYPE_TMR_RUNNING:
2875 case OPTYPE_TMR_RUNNING_ANY:
2876 case OPTYPE_MATCH:
2877 case OPTYPE_EQ:
2878 case OPTYPE_LT:
2879 case OPTYPE_GT:
2880 case OPTYPE_NE:
2881 case OPTYPE_GE:
2882 case OPTYPE_LE:
2883 case OPTYPE_NOT:
2884 case OPTYPE_AND:
2885 case OPTYPE_OR:
2886 case OPTYPE_XOR:
2887 case OPTYPE_ISPRESENT:
2888 case OPTYPE_ISCHOSEN:
2889 case OPTYPE_ISCHOSEN_V:
2890 case OPTYPE_ISCHOSEN_T:
2891 case OPTYPE_ISVALUE:
2892 case OPTYPE_ISBOUND:
2893 case OPTYPE_PROF_RUNNING:
2894 return Type::T_BOOL;
2895 case OPTYPE_GETVERDICT:
2896 return Type::T_VERDICT;
2897 case OPTYPE_VALUEOF: {
2898 Error_Context cntxt(this, "In the operand of operation `%s'",
2899 get_opname());
2900 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2901 case OPTYPE_TMR_READ:
2902 case OPTYPE_INT2FLOAT:
2903 case OPTYPE_STR2FLOAT:
2904 case OPTYPE_RND:
2905 case OPTYPE_RNDWITHVAL:
2906 return Type::T_REAL;
2907 case OPTYPE_ACTIVATE:
2908 return Type::T_DEFAULT;
2909 case OPTYPE_ACTIVATE_REFD:
2910 return Type::T_DEFAULT;
2911 case OPTYPE_EXECUTE:
2912 case OPTYPE_EXECUTE_REFD:
2913 return Type::T_VERDICT;
2914 case OPTYPE_UNARYPLUS: // v1
2915 case OPTYPE_UNARYMINUS: {
2916 Type::typetype_t tmp_tt;
2917 {
2918 Error_Context cntxt(this, "In the operand of operation `%s'",
2919 get_opname());
2920 u.expr.v1->set_lowerid_to_ref();
2921 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2922 }
2923 switch(tmp_tt) {
2924 case Type::T_INT:
2925 case Type::T_REAL:
2926 return tmp_tt;
2927 default:
2928 get_value_refd_last(); // to report the error
2929 return Type::T_ERROR;
2930 } // switch tmp_tt
2931 }
2932 case OPTYPE_ADD: // v1 v2
2933 case OPTYPE_SUBTRACT:
2934 case OPTYPE_MULTIPLY:
2935 case OPTYPE_DIVIDE: {
2936 Type::typetype_t tmp_tt;
2937 {
2938 Error_Context cntxt(this, "In the left operand of operation `%s'",
2939 get_opname());
2940 u.expr.v1->set_lowerid_to_ref();
2941 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2942 }
2943 switch(tmp_tt) {
2944 case Type::T_INT:
2945 case Type::T_REAL:
2946 return tmp_tt;
2947 default:
2948 if(u.expr.v_optype==OPTYPE_ADD) {
2949 Type::typetype_t tmp_tt2;
2950 {
2951 Error_Context cntxt(this, "In the right operand of operation `%s'",
2952 get_opname());
2953 u.expr.v2->set_lowerid_to_ref();
2954 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2955 }
2956 Type::typetype_t ret_val=Type::T_ERROR;
2957 bool maybeconcat=false;
2958 switch(tmp_tt) {
2959 case Type::T_BSTR:
2960 case Type::T_HSTR:
2961 case Type::T_OSTR:
2962 if(tmp_tt2==tmp_tt) {
2963 maybeconcat=true;
2964 ret_val=tmp_tt;
2965 }
2966 break;
2967 case Type::T_CSTR:
2968 case Type::T_USTR:
2969 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
2970 maybeconcat=true;
2971 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
2972 ret_val=Type::T_USTR;
2973 else ret_val=Type::T_CSTR;
2974 }
2975 break;
2976 default:
2977 break;
2978 }
2979 if(maybeconcat) {
2980 error("Did you mean the concat operation (`&') instead of"
2981 " addition operator (`+')?");
2982 u.expr.v_optype=OPTYPE_CONCAT;
2983 return ret_val;
2984 }
2985 }
2986 get_value_refd_last(); // to report the error
2987 return Type::T_ERROR;
2988 } // switch tmp_tt
2989 }
2990 case OPTYPE_NOT4B: // v1
2991 case OPTYPE_AND4B: // v1 v2
2992 case OPTYPE_OR4B:
2993 case OPTYPE_XOR4B:
2994 case OPTYPE_SHL:
2995 case OPTYPE_SHR: {
2996 Type::typetype_t tmp_tt;
2997 {
2998 Error_Context cntxt(this, "In the %soperand of operation `%s'",
2999 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
3000 get_opname());
3001 u.expr.v1->set_lowerid_to_ref();
3002 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3003 }
3004 switch(tmp_tt) {
3005 case Type::T_BSTR:
3006 case Type::T_HSTR:
3007 case Type::T_OSTR:
3008 return tmp_tt;
3009 default:
3010 get_value_refd_last(); // to report the error
3011 return Type::T_ERROR;
3012 } // switch tmp_tt
3013 }
3014 case OPTYPE_ROTL: // v1 v2
3015 case OPTYPE_ROTR: {
3016 Type::typetype_t tmp_tt;
3017 {
3018 Error_Context cntxt(this, "In the %s operand of operation `%s'",
3019 u.expr.v_optype==OPTYPE_ROTL
3020 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
3021 get_opname());
3022 u.expr.v1->set_lowerid_to_ref();
3023 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3024 }
3025 switch(tmp_tt) {
3026 case Type::T_BSTR:
3027 case Type::T_HSTR:
3028 case Type::T_OSTR:
3029 case Type::T_CSTR:
3030 case Type::T_USTR:
3031 case Type::T_SETOF:
3032 case Type::T_SEQOF:
3033 case Type::T_ARRAY:
3034 return tmp_tt;
3035 default:
3036 get_value_refd_last(); // to report the error
3037 return Type::T_ERROR;
3038 } // switch tmp_tt
3039 }
3040 case OPTYPE_SUBSTR:
3041 case OPTYPE_REPLACE: {
3042 Type::typetype_t tmp_tt;
3043 {
3044 Error_Context cntxt(this, "In the operand of operation `%s'",
3045 get_opname());
3046 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3047 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3048 }
3049 switch (tmp_tt) {
3050 case Type::T_BSTR:
3051 case Type::T_HSTR:
3052 case Type::T_OSTR:
3053 case Type::T_CSTR:
3054 case Type::T_USTR:
3055 case Type::T_SETOF:
3056 case Type::T_SEQOF:
3057 return tmp_tt;
3058 default:
3059 get_value_refd_last(); // to report the error
3060 return Type::T_ERROR;
3061 }
3062 }
3063 case OPTYPE_REGEXP: {
3064 Type::typetype_t tmp_tt;
3065 {
3066 Error_Context cntxt(this, "In the first operand of operation `%s'",
3067 get_opname());
3068 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3069 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3070 }
3071 switch(tmp_tt) {
3072 case Type::T_CSTR:
3073 case Type::T_USTR:
3074 return tmp_tt;
3075 default:
3076 get_value_refd_last(); // to report the error
3077 return Type::T_ERROR;
3078 } // switch tmp_tt
3079 }
3080 case OPTYPE_CONCAT: { // v1 v2
3081 Type::typetype_t tmp_tt;
3082 {
3083 Error_Context cntxt(this, "In the first operand of operation `%s'",
3084 get_opname());
3085 u.expr.v1->set_lowerid_to_ref();
3086 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3087 }
3088 switch(tmp_tt) {
3089 case Type::T_CSTR:
3090 case Type::T_USTR:
3091 case Type::T_BSTR:
3092 case Type::T_HSTR:
3093 case Type::T_OSTR:
3094 case Type::T_SETOF:
3095 case Type::T_SEQOF:
3096 return tmp_tt;
3097 default:
3098 get_value_refd_last(); // to report the error
3099 return Type::T_ERROR;
3100 } // switch tmp_tt
3101 }
3102 case OPTYPE_MOD:
3103 case OPTYPE_REM:
3104 case OPTYPE_CHAR2INT:
3105 case OPTYPE_UNICHAR2INT:
3106 case OPTYPE_BIT2INT:
3107 case OPTYPE_HEX2INT:
3108 case OPTYPE_OCT2INT:
3109 case OPTYPE_STR2INT:
3110 case OPTYPE_FLOAT2INT:
3111 case OPTYPE_LENGTHOF:
3112 case OPTYPE_SIZEOF:
3113 case OPTYPE_DECODE:
3114 case OPTYPE_ENUM2INT:
3115 case OPTYPE_DECVALUE_UNICHAR:
3116 return Type::T_INT;
3117 case OPTYPE_BIT2STR:
3118 case OPTYPE_FLOAT2STR:
3119 case OPTYPE_HEX2STR:
3120 case OPTYPE_INT2CHAR:
3121 case OPTYPE_INT2STR:
3122 case OPTYPE_OCT2CHAR:
3123 case OPTYPE_OCT2STR:
3124 case OPTYPE_UNICHAR2CHAR:
3125 case OPTYPE_LOG2STR:
3126 case OPTYPE_TESTCASENAME:
3127 case OPTYPE_TTCN2STRING:
3128 case OPTYPE_GET_STRINGENCODING:
3129 case OPTYPE_ENCODE_BASE64:
3130 return Type::T_CSTR;
3131 case OPTYPE_INT2UNICHAR:
3132 case OPTYPE_OCT2UNICHAR:
3133 case OPTYPE_ENCVALUE_UNICHAR:
3134 return Type::T_USTR;
3135 case OPTYPE_INT2BIT:
3136 case OPTYPE_HEX2BIT:
3137 case OPTYPE_OCT2BIT:
3138 case OPTYPE_STR2BIT:
3139 case OPTYPE_ENCODE:
3140 return Type::T_BSTR;
3141 case OPTYPE_INT2HEX:
3142 case OPTYPE_BIT2HEX:
3143 case OPTYPE_OCT2HEX:
3144 case OPTYPE_STR2HEX:
3145 return Type::T_HSTR;
3146 case OPTYPE_INT2OCT:
3147 case OPTYPE_CHAR2OCT:
3148 case OPTYPE_HEX2OCT:
3149 case OPTYPE_BIT2OCT:
3150 case OPTYPE_STR2OCT:
3151 case OPTYPE_UNICHAR2OCT:
3152 case OPTYPE_REMOVE_BOM:
3153 case OPTYPE_DECODE_BASE64:
3154 return Type::T_OSTR;
3155 case OPTYPE_DECOMP:
3156 return Type::T_OID;
3157 default:
3158 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3159 // to avoid warning
3160 return Type::T_ERROR;
3161 } // switch optype
3162 case V_MACRO:
3163 switch (u.macro) {
3164 case MACRO_MODULEID:
3165 case MACRO_FILENAME:
3166 case MACRO_BFILENAME:
3167 case MACRO_FILEPATH:
3168 case MACRO_LINENUMBER:
3169 case MACRO_DEFINITIONID:
3170 case MACRO_SCOPE:
3171 case MACRO_TESTCASEID:
3172 return Type::T_CSTR;
3173 case MACRO_LINENUMBER_C:
3174 return Type::T_INT;
3175 default:
3176 return Type::T_ERROR;
3177 }
3178 case V_NULL:
3179 return Type::T_NULL;
3180 case V_BOOL:
3181 return Type::T_BOOL;
3182 case V_INT:
3183 return Type::T_INT;
3184 case V_REAL:
3185 return Type::T_REAL;
3186 case V_ENUM:
3187 return Type::T_ENUM_T;
3188 case V_BSTR:
3189 return Type::T_BSTR;
3190 case V_HSTR:
3191 return Type::T_HSTR;
3192 case V_OSTR:
3193 return Type::T_OSTR;
3194 case V_CSTR:
3195 return Type::T_CSTR;
3196 case V_USTR:
3197 return Type::T_USTR;
3198 case V_ISO2022STR:
3199 return Type::T_GENERALSTRING;
3200 case V_OID:
3201 return Type::T_OID;
3202 case V_ROID:
3203 return Type::T_ROID;
3204 case V_VERDICT:
3205 return Type::T_VERDICT;
3206 case V_DEFAULT_NULL:
3207 return Type::T_DEFAULT;
3208 default:
3209 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3210 // to avoid warning
3211 return Type::T_ERROR;
3212 } // switch
3213 }
3214
3215 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3216 {
3217 if(my_governor) return my_governor;
3218 switch (valuetype) {
3219 case V_INVOKE: {
3220 Type *t = u.invoke.v->get_expr_governor(exp_val);
3221 if(!t) {
3222 if(u.invoke.v->get_valuetype() != V_ERROR)
3223 u.invoke.v->error("A value of type function expected");
3224 goto error;
3225 }
3226 t = t->get_type_refd_last();
3227 switch(t->get_typetype()) {
3228 case Type::T_FUNCTION: {
3229 Type *t_return_type = t->get_function_return_type();
3230 if (!t_return_type) {
3231 error("Reference to a %s was expected instead of invocation "
3232 "of behavior type `%s' with no return type",
3233 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3234 t->get_fullname().c_str());
3235 goto error;
3236 }
3237 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3238 error("Reference to a value was expected, but functions of type "
3239 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3240 t_return_type->get_typename().c_str());
3241 goto error;
3242 }
3243 return t_return_type; }
3244 case Type::T_ALTSTEP:
3245 goto error;
3246 default:
3247 u.invoke.v->error("A value of type function expected instead of `%s'",
3248 t->get_typename().c_str());
3249 goto error;
3250 }
3251 break; }
3252 case V_REFD: {
3253 Assignment *ass=u.ref.ref->get_refd_assignment();
3254 Type *tmp_type=0;
3255 if (!ass) goto error;
3256 switch (ass->get_asstype()) {
3257 case Assignment::A_CONST:
3258 case Assignment::A_EXT_CONST:
3259 case Assignment::A_MODULEPAR:
3260 case Assignment::A_MODULEPAR_TEMP:
3261 case Assignment::A_TEMPLATE:
3262 case Assignment::A_VAR:
3263 case Assignment::A_VAR_TEMPLATE:
3264 case Assignment::A_FUNCTION_RVAL:
3265 case Assignment::A_FUNCTION_RTEMP:
3266 case Assignment::A_EXT_FUNCTION_RVAL:
3267 case Assignment::A_EXT_FUNCTION_RTEMP:
3268 case Assignment::A_PAR_VAL_IN:
3269 case Assignment::A_PAR_VAL_OUT:
3270 case Assignment::A_PAR_VAL_INOUT:
3271 case Assignment::A_PAR_TEMPL_IN:
3272 case Assignment::A_PAR_TEMPL_OUT:
3273 case Assignment::A_PAR_TEMPL_INOUT:
3274 tmp_type=ass->get_Type();
3275 break;
3276 case Assignment::A_FUNCTION:
3277 case Assignment::A_EXT_FUNCTION:
3278 error("Reference to a %s was expected instead of a call of %s, which "
3279 "does not have return type",
3280 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3281 ass->get_description().c_str());
3282 goto error;
3283 default:
3284 error("Reference to a %s was expected instead of %s",
3285 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3286 ass->get_description().c_str());
3287 goto error;
3288 } // end switch
3289 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3290 if(!tmp_type) goto error;
3291 return tmp_type; }
3292 case V_EXPR:
3293 switch (u.expr.v_optype) {
3294 case OPTYPE_VALUEOF:
3295 case OPTYPE_SUBSTR:
3296 case OPTYPE_REGEXP:
3297 case OPTYPE_REPLACE:{
3298 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3299 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3300 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3301 return tmp_type;
3302 }
3303 case OPTYPE_ROTL:
3304 case OPTYPE_ROTR:
3305 return u.expr.v1->get_expr_governor(exp_val);
3306 case OPTYPE_CONCAT:
3307 return get_expr_governor_v1v2(exp_val);
3308 case OPTYPE_COMP_MTC:
3309 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3310 else return 0;
3311 case OPTYPE_COMP_SYSTEM:
3312 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3313 else return 0;
3314 case OPTYPE_COMP_SELF:
3315 if (my_scope) {
3316 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3317 if (t_ros) return t_ros->get_component_type();
3318 else return 0;
3319 } else return 0;
3320 case OPTYPE_COMP_CREATE:
3321 return chk_expr_operand_comptyperef_create();
3322 default:
3323 break;
3324 }
3325 // no break
3326 default:
3327 return Type::get_pooltype(get_expr_returntype(exp_val));
3328 }
3329 error:
3330 set_valuetype(V_ERROR);
3331 return 0;
3332 }
3333
3334 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3335 {
3336 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3337 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3338 if (v1_gov) {
3339 if (v2_gov) { // both have governors
3340 // return the type that is compatible with both (if there is no type mismatch)
3341 if (v1_gov->is_compatible(v2_gov, NULL))
3342 return v1_gov;
3343 else return v2_gov;
3344 } else return v1_gov;
3345 } else { // v1 has no governor
3346 if (v2_gov) return v2_gov;
3347 else return NULL; // neither has governor
3348 }
3349 }
3350
3351 Type *Value::get_expr_governor_last()
3352 {
3353 Value *v_last = get_value_refd_last();
3354 if (v_last->valuetype == V_ERROR) return 0;
3355 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3356 if(!t) return 0;
3357 return t->get_type_refd_last();
3358 }
3359
3360 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3361 {
3362 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3363 return u.invoke.v->get_expr_governor(exp_val);
3364 }
3365
3366 const char* Value::get_opname() const
3367 {
3368 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3369 switch(u.expr.v_optype) {
3370 case OPTYPE_RND: // -
3371 return "rnd()";
3372 case OPTYPE_COMP_NULL:
3373 return "(component) null";
3374 case OPTYPE_COMP_MTC:
3375 return "mtc";
3376 case OPTYPE_COMP_SYSTEM:
3377 return "system";
3378 case OPTYPE_COMP_SELF:
3379 return "self";
3380 case OPTYPE_COMP_RUNNING_ANY:
3381 return "any component.running";
3382 case OPTYPE_COMP_RUNNING_ALL:
3383 return "all component.running";
3384 case OPTYPE_COMP_ALIVE_ANY:
3385 return "any component.alive";
3386 case OPTYPE_COMP_ALIVE_ALL:
3387 return "all component.alive";
3388 case OPTYPE_TMR_RUNNING_ANY:
3389 return "any timer.running";
3390 case OPTYPE_GETVERDICT:
3391 return "getverdict()";
3392 case OPTYPE_TESTCASENAME:
3393 return "testcasename()";
3394 case OPTYPE_UNARYPLUS: // v1
3395 return "unary +";
3396 case OPTYPE_UNARYMINUS:
3397 return "unary -";
3398 case OPTYPE_NOT:
3399 return "not";
3400 case OPTYPE_NOT4B:
3401 return "not4b";
3402 case OPTYPE_BIT2HEX:
3403 return "bit2hex()";
3404 case OPTYPE_BIT2INT:
3405 return "bit2int()";
3406 case OPTYPE_BIT2OCT:
3407 return "bit2oct()";
3408 case OPTYPE_BIT2STR:
3409 return "bit2str()";
3410 case OPTYPE_CHAR2INT:
3411 return "char2int()";
3412 case OPTYPE_CHAR2OCT:
3413 return "char2oct()";
3414 case OPTYPE_FLOAT2INT:
3415 return "float2int()";
3416 case OPTYPE_FLOAT2STR:
3417 return "float2str()";
3418 case OPTYPE_HEX2BIT:
3419 return "hex2bit()";
3420 case OPTYPE_HEX2INT:
3421 return "hex2int()";
3422 case OPTYPE_HEX2OCT:
3423 return "hex2oct()";
3424 case OPTYPE_HEX2STR:
3425 return "hex2str()";
3426 case OPTYPE_INT2CHAR:
3427 return "int2char()";
3428 case OPTYPE_INT2FLOAT:
3429 return "int2float()";
3430 case OPTYPE_INT2STR:
3431 return "int2str()";
3432 case OPTYPE_INT2UNICHAR:
3433 return "int2unichar()";
3434 case OPTYPE_OCT2BIT:
3435 return "oct2bit()";
3436 case OPTYPE_OCT2CHAR:
3437 return "oct2char()";
3438 case OPTYPE_OCT2HEX:
3439 return "oct2hex()";
3440 case OPTYPE_OCT2INT:
3441 return "oct2int()";
3442 case OPTYPE_OCT2STR:
3443 return "oct2str()";
3444 case OPTYPE_STR2BIT:
3445 return "str2bit()";
3446 case OPTYPE_STR2FLOAT:
3447 return "str2float()";
3448 case OPTYPE_STR2HEX:
3449 return "str2hex()";
3450 case OPTYPE_STR2INT:
3451 return "str2int()";
3452 case OPTYPE_STR2OCT:
3453 return "str2oct()";
3454 case OPTYPE_UNICHAR2INT:
3455 return "unichar2int()";
3456 case OPTYPE_UNICHAR2CHAR:
3457 return "unichar2char()";
3458 case OPTYPE_UNICHAR2OCT:
3459 return "unichar2oct()";
3460 case OPTYPE_ENUM2INT:
3461 return "enum2int()";
3462 case OPTYPE_LENGTHOF:
3463 return "lengthof()";
3464 case OPTYPE_SIZEOF:
3465 return "sizeof()";
3466 case OPTYPE_RNDWITHVAL:
3467 return "rnd (seed)";
3468 case OPTYPE_ENCODE:
3469 return "encvalue()";
3470 case OPTYPE_DECODE:
3471 return "decvalue()";
3472 case OPTYPE_GET_STRINGENCODING:
3473 return "get_stringencoding()";
3474 case OPTYPE_REMOVE_BOM:
3475 return "remove_bom()";
3476 case OPTYPE_ENCODE_BASE64:
3477 return "encode_base64()";
3478 case OPTYPE_DECODE_BASE64:
3479 return "decode_base64()";
3480 case OPTYPE_ADD: // v1 v2
3481 return "+";
3482 case OPTYPE_SUBTRACT:
3483 return "-";
3484 case OPTYPE_MULTIPLY:
3485 return "*";
3486 case OPTYPE_DIVIDE:
3487 return "/";
3488 case OPTYPE_MOD:
3489 return "mod";
3490 case OPTYPE_REM:
3491 return "rem";
3492 case OPTYPE_CONCAT:
3493 return "&";
3494 case OPTYPE_EQ:
3495 return "==";
3496 case OPTYPE_LT:
3497 return "<";
3498 case OPTYPE_GT:
3499 return ">";
3500 case OPTYPE_NE:
3501 return "!=";
3502 case OPTYPE_GE:
3503 return ">=";
3504 case OPTYPE_LE:
3505 return "<=";
3506 case OPTYPE_AND:
3507 return "and";
3508 case OPTYPE_OR:
3509 return "or";
3510 case OPTYPE_XOR:
3511 return "xor";
3512 case OPTYPE_AND4B:
3513 return "and4b";
3514 case OPTYPE_OR4B:
3515 return "or4b";
3516 case OPTYPE_XOR4B:
3517 return "xor4b";
3518 case OPTYPE_SHL:
3519 return "<<";
3520 case OPTYPE_SHR:
3521 return ">>";
3522 case OPTYPE_ROTL:
3523 return "<@";
3524 case OPTYPE_ROTR:
3525 return "@>";
3526 case OPTYPE_INT2BIT:
3527 return "int2bit()";
3528 case OPTYPE_INT2HEX:
3529 return "int2hex()";
3530 case OPTYPE_INT2OCT:
3531 return "int2oct()";
3532 case OPTYPE_OCT2UNICHAR:
3533 return "oct2unichar()";
3534 case OPTYPE_ENCVALUE_UNICHAR:
3535 return "encvalue_unichar()";
3536 case OPTYPE_DECVALUE_UNICHAR:
3537 return "decvalue_unichar()";
3538 case OPTYPE_SUBSTR:
3539 return "substr()";
3540 case OPTYPE_REGEXP:
3541 return "regexp()";
3542 case OPTYPE_DECOMP:
3543 return "decomp()";
3544 case OPTYPE_REPLACE:
3545 return "replace()";
3546 case OPTYPE_VALUEOF: // t1
3547 return "valueof()";
3548 case OPTYPE_UNDEF_RUNNING:
3549 return "<timer or component> running";
3550 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3551 return "create()";
3552 case OPTYPE_COMP_RUNNING: // v1
3553 return "component running";
3554 case OPTYPE_COMP_ALIVE: // v1
3555 return "alive";
3556 case OPTYPE_TMR_READ:
3557 return "timer read";
3558 case OPTYPE_TMR_RUNNING:
3559 return "timer running";
3560 case OPTYPE_ACTIVATE:
3561 return "activate()";
3562 case OPTYPE_ACTIVATE_REFD:
3563 return "activate()";
3564 case OPTYPE_EXECUTE: // r1 [v2]
3565 case OPTYPE_EXECUTE_REFD:
3566 return "execute()";
3567 case OPTYPE_MATCH: // v1 t2
3568 return "match()";
3569 case OPTYPE_ISPRESENT:
3570 return "ispresent()";
3571 case OPTYPE_ISCHOSEN:
3572 case OPTYPE_ISCHOSEN_V:
3573 case OPTYPE_ISCHOSEN_T:
3574 return "ischosen()";
3575 case OPTYPE_ISVALUE:
3576 return "isvalue()";
3577 case OPTYPE_ISBOUND:
3578 return "isbound()";
3579 case OPTYPE_LOG2STR:
3580 return "log2str()";
3581 case OPTYPE_TTCN2STRING:
3582 return "ttcn2string()";
3583 case OPTYPE_PROF_RUNNING:
3584 return "@profiler.running";
3585 default:
3586 FATAL_ERROR("Value::get_opname()");
3587 } // switch
3588 }
3589
3590 void Value::chk_expr_ref_ischosen()
3591 {
3592 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3593 Ttcn::Ref_base *tmpref=u.expr.r1;
3594 Assignment *ass=tmpref->get_refd_assignment();
3595 if (!ass) {
3596 set_valuetype(V_ERROR);
3597 return;
3598 }
3599 // Now we know whether the argument of ischosen() is a value or template.
3600 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3601 // or template (OPTYPE_ISCHOSEN_T).
3602 switch (ass->get_asstype()) {
3603 case Assignment::A_CONST:
3604 case Assignment::A_EXT_CONST:
3605 case Assignment::A_MODULEPAR:
3606 case Assignment::A_VAR:
3607 case Assignment::A_PAR_VAL_IN:
3608 case Assignment::A_PAR_VAL_OUT:
3609 case Assignment::A_PAR_VAL_INOUT:
3610 u.expr.v1=new Value(V_REFD, tmpref);
3611 u.expr.v1->set_location(*tmpref);
3612 u.expr.v1->set_my_scope(get_my_scope());
3613 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3614 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3615 break;
3616 case Assignment::A_MODULEPAR_TEMP:
3617 case Assignment::A_TEMPLATE:
3618 case Assignment::A_VAR_TEMPLATE:
3619 case Assignment::A_PAR_TEMPL_IN:
3620 case Assignment::A_PAR_TEMPL_OUT:
3621 case Assignment::A_PAR_TEMPL_INOUT:
3622 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3623 u.expr.t1->set_location(*tmpref);
3624 u.expr.t1->set_my_scope(get_my_scope());
3625 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3626 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3627 break;
3628 default:
3629 tmpref->error("Reference to a value or template was expected instead of "
3630 "%s", ass->get_description().c_str());
3631 set_valuetype(V_ERROR);
3632 break;
3633 } // switch
3634 }
3635
3636 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3637 Type::expected_value_t exp_val)
3638 {
3639 v->set_lowerid_to_ref(); // can only be reference to enum
3640 Type *t = v->get_expr_governor(exp_val);
3641 if (v->valuetype==V_ERROR) return;
3642 if (!t) {
3643 v->error("Please use reference to an enumerated value as the operand of "
3644 "operation `%s'", get_opname());
3645 set_valuetype(V_ERROR);
3646 return;
3647 }
3648 t = t->get_type_refd_last();
3649 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3650 v->error("The operand of operation `%s' should be enumerated value", opname);
3651 set_valuetype(V_ERROR);
3652 }
3653 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3654 v->error("The operand of operation `%s' cannot be omit", opname);
3655 set_valuetype(V_ERROR);
3656 }
3657 }
3658
3659 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3660 const char *opnum,
3661 const char *opname,
3662 const Location *loc)
3663 {
3664 if(tt==Type::T_BOOL) return;
3665 if(tt!=Type::T_ERROR)
3666 loc->error("%s operand of operation `%s' should be boolean value",
3667 opnum, opname);
3668 set_valuetype(V_ERROR);
3669 }
3670
3671 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3672 const char *opnum,
3673 const char *opname,
3674 const Location *loc)
3675 {
3676 if(tt==Type::T_INT) return;
3677 if(tt!=Type::T_ERROR)
3678 loc->error("%s operand of operation `%s' should be integer value",
3679 opnum, opname);
3680 set_valuetype(V_ERROR);
3681 }
3682
3683 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3684 const char *opnum,
3685 const char *opname,
3686 const Location *loc)
3687 {
3688 if(tt==Type::T_REAL) return;
3689 else if(tt==Type::T_INT)
3690 loc->error("%s operand of operation `%s' should be float value."
3691 " Perhaps you missed an int2float() conversion function"
3692 " or `.0' at the end of the number",
3693 opnum, opname);
3694 else if(tt!=Type::T_ERROR)
3695 loc->error("%s operand of operation `%s' should be float value",
3696 opnum, opname);
3697 set_valuetype(V_ERROR);
3698 }
3699
3700 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3701 const char *opnum,
3702 const char *opname,
3703 const Location *loc)
3704 {
3705 switch(tt) {
3706 case Type::T_INT:
3707 case Type::T_REAL:
3708 return;
3709 default:
3710 break;
3711 }
3712 if(tt!=Type::T_ERROR)
3713 loc->error("%s operand of operation `%s' should be integer"
3714 " or float value",
3715 opnum, opname);
3716 set_valuetype(V_ERROR);
3717 }
3718
3719 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3720 const char *opnum,
3721 const char *opname,
3722 const Location *loc)
3723 {
3724 switch(tt) {
3725 case Type::T_INT:
3726 case Type::T_REAL:
3727 case Type::T_ENUM_T:
3728 return;
3729 default:
3730 break;
3731 }
3732 if(tt!=Type::T_ERROR)
3733 loc->error("%s operand of operation `%s' should be integer, float"
3734 " or enumerated value", opnum, opname);
3735 set_valuetype(V_ERROR);
3736 }
3737
3738 void Value::chk_expr_operandtype_list(Type* t,
3739 const char *opnum,
3740 const char *opname,
3741 const Location *loc,
3742 bool allow_array)
3743 {
3744 if (valuetype == V_ERROR) return;
3745 if (t->get_typetype() == Type::T_ERROR) {
3746 set_valuetype(V_ERROR);
3747 return;
3748 }
3749 if (!t->is_list_type(allow_array)) {
3750 loc->error("%s operand of operation `%s' should be a string, "
3751 "`record of'%s `set of'%s value", opnum, opname,
3752 allow_array ? "," : " or", allow_array ? " or array" : "");
3753 set_valuetype(V_ERROR);
3754 return;
3755 }
3756 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3757 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3758 TypeChain l_chain;
3759 TypeChain r_chain;
3760 if (my_governor && my_governor->is_list_type(allow_array)
3761 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3762 if (info.is_subtype_error()) {
3763 // this is ok.
3764 if (info.needs_conversion()) set_needs_conversion();
3765 } else
3766 if (!info.is_erroneous()) {
3767 error("%s operand of operation `%s' is of type `%s', but a value of "
3768 "type `%s' was expected here", opnum, opname,
3769 t->get_typename().c_str(), my_governor->get_typename().c_str());
3770 } else {
3771 error("%s", info.get_error_str_str().c_str());
3772 }
3773 } else {
3774 if (info.needs_conversion())
3775 set_needs_conversion();
3776 }
3777 }
3778
3779 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3780 const char *opnum,
3781 const char *opname,
3782 const Location *loc)
3783 {
3784 switch(tt) {
3785 case Type::T_CSTR:
3786 case Type::T_USTR:
3787 case Type::T_BSTR:
3788 case Type::T_HSTR:
3789 case Type::T_OSTR:
3790 return;
3791 default:
3792 break;
3793 }
3794 if(tt!=Type::T_ERROR)
3795 loc->error("%s operand of operation `%s' should be string value",
3796 opnum, opname);
3797 set_valuetype(V_ERROR);
3798 }
3799
3800 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3801 const char *opnum,
3802 const char *opname,
3803 const Location *loc)
3804 {
3805 switch(tt) {
3806 case Type::T_CSTR:
3807 case Type::T_USTR:
3808 return;
3809 default:
3810 break;
3811 }
3812 if(tt!=Type::T_ERROR)
3813 loc->error("%s operand of operation `%s' should be (universal)"
3814 " charstring value",
3815 opnum, opname);
3816 set_valuetype(V_ERROR);
3817 }
3818
3819 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3820 const char *opnum,
3821 const char *opname,
3822 const Location *loc)
3823 {
3824 if(tt==Type::T_CSTR) return;
3825 if(tt!=Type::T_ERROR)
3826 loc->error("%s operand of operation `%s' should be charstring value",
3827 opnum, opname);
3828 set_valuetype(V_ERROR);
3829 }
3830
3831 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3832 const char *opnum,
3833 const char *opname,
3834 const Location *loc)
3835 {
3836 switch(tt) {
3837 case Type::T_BSTR:
3838 case Type::T_HSTR:
3839 case Type::T_OSTR:
3840 return;
3841 default:
3842 break;
3843 }
3844 if(tt!=Type::T_ERROR)
3845 loc->error("%s operand of operation `%s' should be binary string value",
3846 opnum, opname);
3847 set_valuetype(V_ERROR);
3848 }
3849
3850 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3851 const char *opnum,
3852 const char *opname,
3853 const Location *loc)
3854 {
3855 if(tt==Type::T_BSTR) return;
3856 if(tt!=Type::T_ERROR)
3857 loc->error("%s operand of operation `%s' should be bitstring value",
3858 opnum, opname);
3859 set_valuetype(V_ERROR);
3860 }
3861
3862 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3863 const char *opnum,
3864 const char *opname,
3865 const Location *loc)
3866 {
3867 if(tt==Type::T_HSTR) return;
3868 if(tt!=Type::T_ERROR)
3869 loc->error("%s operand of operation `%s' should be hexstring value",
3870 opnum, opname);
3871 set_valuetype(V_ERROR);
3872 }
3873
3874 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3875 const char *opnum,
3876 const char *opname,
3877 const Location *loc)
3878 {
3879 if(tt==Type::T_OSTR) return;
3880 if(tt!=Type::T_ERROR)
3881 loc->error("%s operand of operation `%s' should be octetstring value",
3882 opnum, opname);
3883 set_valuetype(V_ERROR);
3884 }
3885
3886 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3887 Type::typetype_t tt2,
3888 const char *opname)
3889 {
3890 if(valuetype==V_ERROR) return;
3891 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3892 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3893 set_valuetype(V_ERROR);
3894 return;
3895 }
3896 if(tt1==tt2) return;
3897 error("The operands of operation `%s' should be of same type", opname);
3898 set_valuetype(V_ERROR);
3899 }
3900
3901 /* For predefined functions. */
3902 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3903 Type::typetype_t tt2,
3904 const char *opnum1,
3905 const char *opnum2,
3906 const char *opname)
3907 {
3908 if(valuetype==V_ERROR) return;
3909 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3910 set_valuetype(V_ERROR);
3911 return;
3912 }
3913 if(tt1==tt2) return;
3914 error("The %s and %s operands of operation `%s' should be of same type",
3915 opnum1, opnum2, opname);
3916 set_valuetype(V_ERROR);
3917 }
3918
3919 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3920 Value *v1, Value *v2,
3921 const char *opnum1,
3922 const char *opnum2)
3923 {
3924 start:
3925 if (valuetype == V_ERROR) return;
3926 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3927 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3928 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3929
3930 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3931 set_valuetype(V_ERROR);
3932 return;
3933 }
3934 if (tt1 == Type::T_UNDEF) {
3935 if (tt2 == Type::T_UNDEF) {
3936 if (v1->is_undef_lowerid()) {
3937 if (v2->is_undef_lowerid()) {
3938 Scope *scope = get_my_scope();
3939 Module *my_mod = scope->get_scope_mod();
3940 const Identifier& id1 = v1->get_undef_lowerid();
3941 if (scope->has_ass_withId(id1)
3942 || my_mod->has_imported_ass_withId(id1)) {
3943 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3944 * should examine this situation better, but now I suppose
3945 * the first is ref, not enum. */
3946 v1->set_lowerid_to_ref();
3947 goto start;
3948 } else {
3949 const Identifier& id2 = v2->get_undef_lowerid();
3950 if (scope->has_ass_withId(id2)
3951 || my_mod->has_imported_ass_withId(id2)) {
3952 v2->set_lowerid_to_ref();
3953 goto start;
3954 }
3955 }
3956 /* This is perhaps enum-enum, but it has no real
3957 * significance, so this should be an error. */
3958 } else {
3959 v1->set_lowerid_to_ref();
3960 goto start;
3961 }
3962 } else if (v2->is_undef_lowerid()) {
3963 v2->set_lowerid_to_ref();
3964 goto start;
3965 }
3966 error("Cannot determine the type of the operands in operation `%s'",
3967 get_opname());
3968 set_valuetype(V_ERROR);
3969 return;
3970 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
3971 v1->set_lowerid_to_ref();
3972 goto start;
3973 } else {
3974 /* v1 is something undefined, but not lowerid; v2 has
3975 * returntype (perhaps also governor) */
3976 }
3977 } else if (tt2 == Type::T_UNDEF) {
3978 /* but tt1 is not undef */
3979 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
3980 v2->set_lowerid_to_ref();
3981 goto start;
3982 } else {
3983 /* v2 is something undefined, but not lowerid; v1 has
3984 * returntype (perhaps also governor) */
3985 }
3986 }
3987
3988 /* Now undef_lower_id's are converted to references, or the other
3989 * value has governor; let's see the governors, if they exist. */
3990 Type *t1 = v1->get_expr_governor(exp_val);
3991 Type *t2 = v2->get_expr_governor(exp_val);
3992 if (t1) {
3993 if (t2) {
3994 // Both value has governor. Are they compatible? According to 7.1.2
3995 // and C.34 it's required to have the same root types for
3996 // OPTYPE_{CONCAT,REPLACE}.
3997 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
3998 u.expr.v_optype == OPTYPE_REPLACE);
3999 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
4000 u.expr.v_optype == OPTYPE_REPLACE);
4001 TypeChain l_chain1, l_chain2;
4002 TypeChain r_chain1, r_chain2;
4003 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
4004 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
4005 if (!compat_t1 && !compat_t2) {
4006 if (!info1.is_erroneous() && !info2.is_erroneous()) {
4007 // the subtypes don't need to be compatible here
4008 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
4009 error("The operands of operation `%s' should be of compatible "
4010 "types", get_opname());
4011 set_valuetype(V_ERROR);
4012 } else {
4013 if (info1.needs_conversion() || info2.needs_conversion()) {
4014 set_needs_conversion(); // Avoid folding.
4015 return;
4016 }
4017 }
4018 } else {
4019 if (info1.is_erroneous())
4020 v1->error("%s", info1.get_error_str_str().c_str());
4021 else if (info2.is_erroneous())
4022 v2->error("%s", info2.get_error_str_str().c_str());
4023 set_valuetype(V_ERROR);
4024 }
4025 return;
4026 } else if (info1.needs_conversion() || info2.needs_conversion()) {
4027 set_needs_conversion(); // Avoid folding.
4028 return;
4029 }
4030 } else {
4031 // t1, no t2.
4032 v2->set_my_governor(t1);
4033 t1->chk_this_value_ref(v2);
4034 if (v2->valuetype == V_OMIT) {
4035 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4036 get_opname());
4037 v1->chk_expr_omit_comparison(exp_val);
4038 } else {
4039 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4040 get_opname());
4041 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4042 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4043 goto start;
4044 }
4045 }
4046 } else if (t2) {
4047 v1->set_my_governor(t2);
4048 t2->chk_this_value_ref(v1);
4049 if (v1->valuetype == V_OMIT) {
4050 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4051 get_opname());
4052 v2->chk_expr_omit_comparison(exp_val);
4053 } else {
4054 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4055 get_opname());
4056 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4057 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4058 goto start;
4059 }
4060 } else {
4061 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4062 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
4063 // Here, it cannot be that both are T_UNDEF.
4064 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4065 error("Please use reference as %s operand of operator `%s'",
4066 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
4067 set_valuetype(V_ERROR);
4068 return;
4069 }
4070 // Deny type compatibility if no governors found. The typetype_t must
4071 // be the same. TODO: How can this happen?
4072 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
4073 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
4074 error("The operands of operation `%s' should be of compatible types",
4075 get_opname());
4076 set_valuetype(V_ERROR);
4077 }
4078 }
4079 }
4080
4081 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
4082 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
4083 {
4084 if(valuetype==V_ERROR) return;
4085 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4086 Assignment *t_ass = ref->get_refd_assignment();
4087 if(!t_ass) goto error;
4088 switch(t_ass->get_asstype()) {
4089 case Assignment::A_TIMER:
4090 case Assignment::A_PAR_TIMER:
4091 u.expr.v_optype=OPTYPE_TMR_RUNNING;
4092 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
4093 chk_expr_dynamic_part(exp_val, true);
4094 break;
4095 case Assignment::A_CONST:
4096 case Assignment::A_EXT_CONST:
4097 case Assignment::A_MODULEPAR:
4098 case Assignment::A_VAR:
4099 case Assignment::A_FUNCTION_RVAL:
4100 case Assignment::A_EXT_FUNCTION_RVAL:
4101 case Assignment::A_PAR_VAL_IN:
4102 case Assignment::A_PAR_VAL_OUT:
4103 case Assignment::A_PAR_VAL_INOUT: {
4104 u.expr.v_optype = OPTYPE_COMP_RUNNING;
4105 Value* val = new Value(V_REFD, u.expr.r1);
4106 val->set_my_scope(my_scope);
4107 val->set_fullname(u.expr.r1->get_fullname());
4108 val->set_location(*u.expr.r1);
4109 u.expr.v1 = val;
4110 chk_expr_operand_compref(val, opnum, get_opname());
4111 chk_expr_dynamic_part(exp_val, false);
4112 break; }
4113 default:
4114 ref->error("%s operand of operation `%s' should be timer or"
4115 " component reference instead of %s",
4116 opnum, opname, t_ass->get_description().c_str());
4117 goto error;
4118 } // switch
4119 return;
4120 error:
4121 set_valuetype(V_ERROR);
4122 }
4123
4124 Type *Value::chk_expr_operand_comptyperef_create()
4125 {
4126 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4127 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4128 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4129 if (!t_ass) goto error;
4130 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4131 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4132 Type::EXPECTED_DYNAMIC_VALUE);
4133 if (!t_type) goto error;
4134 t_type = t_type->get_type_refd_last();
4135 if (t_type->get_typetype() == Type::T_COMPONENT) {
4136 if (my_governor) {
4137 Type *my_governor_last = my_governor->get_type_refd_last();
4138 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4139 !my_governor_last->is_compatible(t_type, NULL)) {
4140 u.expr.r1->error("Incompatible component types: operation "
4141 "`create' should refer to `%s' instead of "
4142 "`%s'",
4143 my_governor_last->get_typename().c_str(),
4144 t_type->get_typename().c_str());
4145 goto error;
4146 }
4147 }
4148 return t_type;
4149 } else {
4150 u.expr.r1->error("Type mismatch: reference to a component type was "
4151 "expected in operation `create' instead of `%s'",
4152 t_type->get_typename().c_str());
4153 }
4154 } else {
4155 u.expr.r1->error("Operation `create' should refer to a component type "
4156 "instead of %s", t_ass->get_description().c_str());
4157 }
4158 error:
4159 set_valuetype(V_ERROR);
4160 return NULL;
4161 }
4162
4163 void Value::chk_expr_comptype_compat()
4164 {
4165 if (valuetype != V_EXPR)
4166 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4167 if (!my_governor || !my_scope) return;
4168 Type *my_governor_last = my_governor->get_type_refd_last();
4169 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4170 Type *t_comptype;
4171 switch (u.expr.v_optype) {
4172 case OPTYPE_COMP_MTC:
4173 t_comptype = my_scope->get_mtc_system_comptype(false);
4174 break;
4175 case OPTYPE_COMP_SYSTEM:
4176 t_comptype = my_scope->get_mtc_system_comptype(true);
4177 break;
4178 case OPTYPE_COMP_SELF: {
4179 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4180 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4181 break; }
4182 default:
4183 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4184 t_comptype = 0;
4185 break;
4186 }
4187 if (t_comptype
4188 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4189 error("Incompatible component types: a component reference of "
4190 "type `%s' was expected, but `%s' has type `%s'",
4191 my_governor_last->get_typename().c_str(), get_opname(),
4192 t_comptype->get_typename().c_str());
4193 set_valuetype(V_ERROR);
4194 }
4195 }
4196
4197 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4198 const char *opname)
4199 {
4200 if(valuetype == V_ERROR) return;
4201 switch(val->get_valuetype()) {
4202 case V_INVOKE: {
4203 Error_Context cntxt(this, "In `%s' operation", opname);
4204 Value *v_last = val->get_value_refd_last();
4205 if(!v_last) goto error;
4206 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4207 if(!t) goto error;
4208 t = t->get_type_refd_last();
4209 if(t->get_typetype() != Type::T_COMPONENT) {
4210 v_last->error("%s operand of operation `%s': Type mismatch:"
4211 " component reference was expected instead of `%s'",
4212 opnum, opname, t->get_typename().c_str());
4213 goto error;
4214 }
4215 return; }
4216 case V_REFD: {
4217 Reference *ref = val->get_reference();
4218 Assignment *t_ass = ref->get_refd_assignment();
4219 Value *t_val = 0;
4220 if (!t_ass) goto error;
4221 switch(t_ass->get_asstype()) {
4222 case Assignment::A_CONST:
4223 t_val = t_ass->get_Value();
4224 // no break
4225 case Assignment::A_EXT_CONST:
4226 case Assignment::A_MODULEPAR:
4227 case Assignment::A_VAR:
4228 case Assignment::A_FUNCTION_RVAL:
4229 case Assignment::A_EXT_FUNCTION_RVAL:
4230 case Assignment::A_PAR_VAL_IN:
4231 case Assignment::A_PAR_VAL_OUT:
4232 case Assignment::A_PAR_VAL_INOUT: {
4233 Type *t_type=t_ass->get_Type()
4234 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4235 if(!t_type) goto error;
4236 t_type=t_type->get_type_refd_last();
4237 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4238 ref->error("%s operand of operation `%s': Type mismatch:"
4239 " component reference was expected instead of `%s'",
4240 opnum, opname, t_type->get_typename().c_str());
4241 goto error;
4242 }
4243 break;}
4244 default:
4245 ref->error("%s operand of operation `%s' should be"
4246 " component reference instead of %s",
4247 opnum, opname, t_ass->get_description().c_str());
4248 goto error;
4249 }
4250 if (t_val) {
4251 ReferenceChain refch(this, "While searching referenced value");
4252 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4253 if (!t_val) return;
4254 t_val = t_val->get_value_refd_last();
4255 if (t_val->valuetype != V_EXPR) return;
4256 switch (t_val->u.expr.v_optype) {
4257 case OPTYPE_COMP_NULL:
4258 ref->error("%s operand of operation `%s' refers to `null' component "
4259 "reference", opnum, opname);
4260 goto error;
4261 case OPTYPE_COMP_MTC:
4262 ref->error("%s operand of operation `%s' refers to the component "
4263 "reference of the `mtc'", opnum, opname);
4264 goto error;
4265 case OPTYPE_COMP_SYSTEM:
4266 ref->error("%s operand of operation `%s' refers to the component "
4267 "reference of the `system'", opnum, opname);
4268 goto error;
4269 default:
4270 break;
4271 }
4272 }
4273 return;}
4274 default:
4275 FATAL_ERROR("Value::chk_expr_operand_compref()");
4276 }
4277 error:
4278 set_valuetype(V_ERROR);
4279 }
4280
4281 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4282 const char *opnum,
4283 const char *opname)
4284 {
4285 if(valuetype==V_ERROR) return;
4286 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4287 Assignment *t_ass = ref->get_refd_assignment();
4288 if(!t_ass) goto error;
4289 switch(t_ass->get_asstype()) {
4290 case Assignment::A_TIMER: {
4291 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4292 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4293 Type::EXPECTED_DYNAMIC_VALUE);
4294 else if (ref->get_subrefs()) {
4295 ref->error("%s operand of operation `%s': "
4296 "Reference to single timer `%s' cannot have field or array "
4297 "sub-references", opnum, opname,
4298 t_ass->get_id().get_dispname().c_str());
4299 goto error;
4300 }
4301 break; }
4302 case Assignment::A_PAR_TIMER:
4303 if (ref->get_subrefs()) {
4304 ref->error("%s operand of operation `%s': "
4305 "Reference to %s cannot have field or array sub-references",
4306 opnum, opname, t_ass->get_description().c_str());
4307 goto error;
4308 }
4309 break;
4310 default:
4311 ref->error("%s operand of operation `%s' should be timer"
4312 " instead of %s",
4313 opnum, opname, t_ass->get_description().c_str());
4314 goto error;
4315 } // switch
4316 return;
4317 error:
4318 set_valuetype(V_ERROR);
4319 }
4320
4321 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4322 const char *,
4323 const char *opname)
4324 {
4325 if(valuetype==V_ERROR) return;
4326 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4327 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4328 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4329 Error_Context cntxt(this, "In `%s' operation", opname);
4330 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4331 }
4332
4333 void Value::chk_expr_operand_activate_refd(Value *val,
4334 Ttcn::TemplateInstances* t_list2,
4335 Ttcn::ActualParList *&parlist,
4336 const char *,
4337 const char *opname)
4338 {
4339 if(valuetype==V_ERROR) return;
4340 Error_Context cntxt(this, "In `%s' operation", opname);
4341 Type *t = val->get_expr_governor_last();
4342 if (t) {
4343 switch (t->get_typetype()) {
4344 case Type::T_ERROR:
4345 set_valuetype(V_ERROR);
4346 break;
4347 case Type::T_ALTSTEP: {
4348 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4349 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4350 if(is_erroneous) {
4351 delete parlist;
4352 parlist = 0;
4353 set_valuetype(V_ERROR);
4354 } else {
4355 parlist->set_fullname(get_fullname());
4356 parlist->set_my_scope(get_my_scope());
4357 if (!fp_list->chk_activate_argument(parlist,
4358 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4359 }
4360 break; }
4361 default:
4362 error("Reference to an altstep was expected in the argument of "
4363 "`derefers()' instead of `%s'", t->get_typename().c_str());
4364 set_valuetype(V_ERROR);
4365 break;
4366 }
4367 } else set_valuetype(V_ERROR);
4368 }
4369
4370 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4371 const char *,
4372 const char *opname)
4373 {
4374 if(valuetype==V_ERROR) return;
4375 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4376 Error_Context cntxt(this, "In `%s' operation", opname);
4377 Assignment *t_ass = ref->get_refd_assignment();
4378 bool error_flag = false;
4379 if (t_ass) {
4380 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4381 ref->error("Reference to a testcase was expected in the argument "
4382 "instead of %s", t_ass->get_description().c_str());
4383 error_flag = true;
4384 }
4385 } else error_flag = true;
4386 if (val) {
4387 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4388 Value *v_last = val->get_value_refd_last();
4389 switch (v_last->valuetype) {
4390 case V_REAL: {
4391 ttcn3float v_real = v_last->get_val_Real();
4392 if (v_real < 0.0) {
4393 val->error("The testcase guard timer has negative value: `%s'",
4394 Real2string(v_real).c_str());
4395 error_flag = true;
4396 }
4397 break; }
4398 case V_ERROR:
4399 error_flag = true;
4400 break;
4401 default:
4402 break;
4403 }
4404 }
4405 if (error_flag) set_valuetype(V_ERROR);
4406 }
4407
4408 void Value::chk_expr_operand_execute_refd(Value *v1,
4409 Ttcn::TemplateInstances* t_list2,
4410 Ttcn::ActualParList *&parlist,
4411 Value *v3,
4412 const char *,
4413 const char *opname)
4414 {
4415 if(valuetype==V_ERROR) return;
4416 Error_Context cntxt(this, "In `%s' operation", opname);
4417 Type *t = v1->get_expr_governor_last();
4418 if (t) {
4419 switch (t->get_typetype()) {
4420 case Type::T_ERROR:
4421 set_valuetype(V_ERROR);
4422 break;
4423 case Type::T_TESTCASE: {
4424 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4425 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4426 if(is_erroneous) {
4427 delete parlist;
4428 parlist = 0;
4429 set_valuetype(V_ERROR);
4430 } else {
4431 parlist->set_fullname(get_fullname());
4432 parlist->set_my_scope(get_my_scope());
4433 }
4434 break; }
4435 default:
4436 v1->error("Reference to a value of type testcase was expected in the "
4437 "argument of `derefers()' instead of `%s'",
4438 t->get_typename().c_str());
4439 set_valuetype(V_ERROR);
4440 break;
4441 }
4442 } else set_valuetype(V_ERROR);
4443 if (v3) {
4444 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4445 Value *v_last = v3->get_value_refd_last();
4446 switch (v_last->valuetype) {
4447 case V_REAL: {
4448 ttcn3float v_real = v_last->get_val_Real();
4449 if(v_real < 0.0) {
4450 v3->error("The testcase guard timer has negative value: `%s'",
4451 Real2string(v_real).c_str());
4452 set_valuetype(V_ERROR);
4453 }
4454 break; }
4455 case V_ERROR:
4456 set_valuetype(V_ERROR);
4457 break;
4458 default:
4459 break;
4460 }
4461 }
4462 }
4463
4464 void Value::chk_invoke(Type::expected_value_t exp_val)
4465 {
4466 if(valuetype == V_ERROR) return;
4467 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4468 if(!u.invoke.t_list) return; //already checked
4469 Error_Context cntxt(this, "In `apply()' operation");
4470 Type *t = u.invoke.v->get_expr_governor_last();
4471 if (!t) {
4472 set_valuetype(V_ERROR);
4473 return;
4474 }
4475 switch (t->get_typetype()) {
4476 case Type::T_ERROR:
4477 set_valuetype(V_ERROR);
4478 return;
4479 case Type::T_FUNCTION:
4480 break;
4481 default:
4482 u.invoke.v->error("A value of type function was expected in the "
4483 "argument instead of `%s'", t->get_typename().c_str());
4484 set_valuetype(V_ERROR);
4485 return;
4486 }
4487 my_scope->chk_runs_on_clause(t, *this, "call");
4488 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4489 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4490 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4491 delete u.invoke.t_list;
4492 u.invoke.t_list = 0;
4493 if(is_erroneous) {
4494 delete parlist;
4495 u.invoke.ap_list = 0;
4496 } else {
4497 parlist->set_fullname(get_fullname());
4498 parlist->set_my_scope(get_my_scope());
4499 u.invoke.ap_list = parlist;
4500 }
4501 switch (exp_val) {
4502 case Type::EXPECTED_CONSTANT:
4503 error("An evaluable constant value was expected instead of operation "
4504 "`apply()'");
4505 set_valuetype(V_ERROR);
4506 break;
4507 case Type::EXPECTED_STATIC_VALUE:
4508 error("A static value was expected instead of operation `apply()'");
4509 set_valuetype(V_ERROR);
4510 break;
4511 default:
4512 break;
4513 } // switch
4514 }
4515
4516 void Value::chk_expr_eval_value(Value *val, Type &t,
4517 ReferenceChain *refch,
4518 Type::expected_value_t exp_val)
4519 {
4520 bool self_ref = false;
4521 if(valuetype==V_ERROR) return;
4522 // Commented out to report more errors :)
4523 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4524 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4525 switch(val->get_valuetype()) {
4526 case V_REFD:
4527 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4528 break;
4529 case V_EXPR:
4530 case V_MACRO:
4531 case V_INVOKE:
4532 val->get_value_refd_last(refch, exp_val);
4533 break;
4534 default:
4535 break;
4536 } // switch
4537 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4538
4539 (void)self_ref;
4540 }
4541
4542 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4543 ReferenceChain *refch, Type::expected_value_t exp_val)
4544 {
4545 bool self_ref = false;
4546 ti->chk(type);
4547 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4548 ti->error("Reference to a %s value was expected instead of an in-line "
4549 "modified template",
4550 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4551 set_valuetype(V_ERROR);
4552 return;
4553 }
4554 Template *templ = ti->get_Template();
4555 switch (templ->get_templatetype()) {
4556 case Template::TEMPLATE_REFD:
4557 // not foldable
4558 if (exp_val == Type::EXPECTED_TEMPLATE) {
4559 templ = templ->get_template_refd_last(refch);
4560 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4561 set_valuetype(V_ERROR);
4562 } else {
4563 ti->error("Reference to a %s value was expected instead of %s",
4564 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4565 templ->get_reference()->get_refd_assignment()
4566 ->get_description().c_str());
4567 set_valuetype(V_ERROR);
4568 }
4569 break;
4570 case Template::SPECIFIC_VALUE: {
4571 Value *val = templ->get_specific_value();
4572 switch (val->get_valuetype()) {
4573 case V_REFD:
4574 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4575 break;
4576 case V_EXPR:
4577 val->get_value_refd_last(refch, exp_val);
4578 default:
4579 break;
4580 } // switch
4581 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4582 break; }
4583 case Template::TEMPLATE_ERROR:
4584 set_valuetype(V_ERROR);
4585 break;
4586 default:
4587 break;
4588 } // switch
4589
4590 (void)self_ref;
4591 }
4592
4593 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4594 const char *opname)
4595 {
4596 if(valuetype==V_ERROR) return;
4597 if(u.expr.state==EXPR_CHECKING_ERR) return;
4598 if(val->is_unfoldable()) return;
4599 if(*val->get_val_Int()<0) {
4600 val->error("%s operand of operation `%s' should not be negative",
4601 opnum, opname);
4602 set_valuetype(V_ERROR);
4603 }
4604 }
4605
4606 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4607 const char *opname)
4608 {
4609 if(valuetype==V_ERROR) return;
4610 if(u.expr.state==EXPR_CHECKING_ERR) return;
4611 if(val->is_unfoldable()) return;
4612 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4613 val->error("%s operand of operation `%s' should be in range 0..127",
4614 opnum, opname);
4615 set_valuetype(V_ERROR);
4616 }
4617 }
4618
4619 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4620 const char *opname)
4621 {
4622 if(valuetype==V_ERROR) return;
4623 if(u.expr.state==EXPR_CHECKING_ERR) return;
4624 if(val->is_unfoldable()) return;
4625 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4626 val->error("%s operand of operation `%s' should be in range"
4627 " 0..2147483647", opnum, opname);
4628 set_valuetype(V_ERROR);
4629 }
4630 }
4631
4632 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4633 const char *opname)
4634 {
4635 if(valuetype==V_ERROR) return;
4636 if(u.expr.state==EXPR_CHECKING_ERR) return;
4637 if(val->is_unfoldable()) return;
4638 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4639 ||
4640 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4641 {
4642 val->error("%s operand of operation `%s' should not be zero",
4643 opnum, opname);
4644 set_valuetype(V_ERROR);
4645 }
4646 }
4647
4648 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4649 const char *opname)
4650 {
4651 if (valuetype == V_ERROR) return;
4652 if (u.expr.state == EXPR_CHECKING_ERR) return;
4653 if (val->get_expr_returntype() != Type::T_INT) return;
4654 if (val->is_unfoldable()) return;
4655 const int_val_t *val_int = val->get_val_Int();
4656 if (*val_int > static_cast<Int>(INT_MAX)) {
4657 val->error("%s operand of operation `%s' should be less than `%d' "
4658 "instead of `%s'", opnum, opname, INT_MAX,
4659 (val_int->t_str()).c_str());
4660 set_valuetype(V_ERROR);
4661 }
4662 }
4663
4664 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4665 const char *opname)
4666 {
4667 if(valuetype==V_ERROR) return;
4668 if(u.expr.state==EXPR_CHECKING_ERR) return;
4669 if(val->is_unfoldable()) return;
4670 if(val->get_val_strlen()!=1) {
4671 val->error("%s operand of operation `%s' should be of length 1",
4672 opnum, opname);
4673 set_valuetype(V_ERROR);
4674 }
4675 }
4676
4677 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4678 const char *opname)
4679 {
4680 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4681 Value *v_last = val->get_value_refd_last();
4682 if (v_last->valuetype == V_CSTR) {
4683 size_t len = v_last->get_val_strlen();
4684 if (len % 2) {
4685 val->error("%s operand of operation `%s' should contain even number "
4686 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4687 set_valuetype(V_ERROR);
4688 }
4689 } else if (v_last->valuetype == V_REFD) {
4690 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4691 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4692 val->error("%s operand of operation `%s' should contain even number "
4693 "of characters, but a string element contains 1", opnum, opname);
4694 set_valuetype(V_ERROR);
4695 }
4696 }
4697 }
4698
4699 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4700 const char *opname)
4701 {
4702 if(valuetype==V_ERROR) return;
4703 if(u.expr.state==EXPR_CHECKING_ERR) return;
4704 if(val->is_unfoldable()) return;
4705 const string& s=val->get_val_str();
4706 for(size_t i=0; i<s.size(); i++) {
4707 char c=s[i];
4708 if(!(c=='0' || c=='1')) {
4709 val->error("%s operand of operation `%s' can contain only"
4710 " binary digits (position %lu is `%c')",
4711 opnum, opname, (unsigned long) i, c);
4712 set_valuetype(V_ERROR);
4713 return;
4714 }
4715 }
4716 }
4717
4718 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4719 const char *opname)
4720 {
4721 if(valuetype==V_ERROR) return;
4722 if(u.expr.state==EXPR_CHECKING_ERR) return;
4723 if(val->is_unfoldable()) return;
4724 const string& s=val->get_val_str();
4725 for(size_t i=0; i<s.size(); i++) {
4726 char c=s[i];
4727 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4728 val->error("%s operand of operation `%s' can contain only valid "
4729 "hexadecimal digits (position %lu is `%c')",
4730 opnum, opname, (unsigned long) i, c);
4731 set_valuetype(V_ERROR);
4732 return;
4733 }
4734 }
4735 }
4736
4737 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4738 const char *opname)
4739 {
4740 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4741 Value *v = val->get_value_refd_last();
4742 if (v->valuetype != V_OSTR) return;
4743 const string& s = val->get_val_str();
4744 size_t n_octets = s.size() / 2;
4745 for (size_t i = 0; i < n_octets; i++) {
4746 char c = s[2 * i];
4747 if (!(c >= '0' && c <= '7')) {
4748 val->error("%s operand of operation `%s' shall consist of octets "
4749 "within the range 00 .. 7F, but the string `%s'O contains octet "
4750 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4751 (unsigned long) i);
4752 set_valuetype(V_ERROR);
4753 return;
4754 }
4755 }
4756 }
4757
4758 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4759 const char *opname)
4760 {
4761 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4762 Value *v_last = val->get_value_refd_last();
4763 if (v_last->valuetype != V_CSTR) return;
4764 const string& s = v_last->get_val_str();
4765 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4766 state = S_INITIAL;
4767 // state: expected characters
4768 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4769 // S_FIRST: first digit
4770 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4771 // S_END: trailing whitespace
4772 // S_ERR: error was found, stop
4773 for (size_t i = 0; i < s.size(); i++) {
4774 char c = s[i];
4775 switch (state) {
4776 case S_INITIAL:
4777 case S_INITIAL_WS:
4778 if (c == '+' || c == '-') state = S_FIRST;
4779 else if (c == '0') state = S_ZERO;
4780 else if (c >= '1' && c <= '9') state = S_MORE;
4781 else if (string::is_whitespace(c)) {
4782 if (state == S_INITIAL) {
4783 val->warning("Leading whitespace was detected and ignored in the "
4784 "operand of operation `%s'", opname);
4785 state = S_INITIAL_WS;
4786 }
4787 } else state = S_ERR;
4788 break;
4789 case S_FIRST:
4790 if (c == '0') state = S_ZERO;
4791 else if (c >= '1' && c <= '9') state = S_MORE;
4792 else state = S_ERR;
4793 break;
4794 case S_ZERO:
4795 if (c >= '0' && c <= '9') {
4796 val->warning("Leading zero digit was detected and ignored in the "
4797 "operand of operation `%s'", opname);
4798 state = S_MORE;
4799 } else if (string::is_whitespace(c)) state = S_END;
4800 else state = S_ERR;
4801 break;
4802 case S_MORE:
4803 if (c >= '0' && c <= '9') {}
4804 else if (string::is_whitespace(c)) state = S_END;
4805 else state = S_ERR;
4806 break;
4807 case S_END:
4808 if (!string::is_whitespace(c)) state = S_ERR;
4809 break;
4810 default:
4811 break;
4812 }
4813 if (state == S_ERR) {
4814 if (string::is_printable(c)) {
4815 val->error("%s operand of operation `%s' should be a string "
4816 "containing a valid integer value, but invalid character `%c' "
4817 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4818 } else {
4819 val->error("%s operand of operation `%s' should be a string "
4820 "containing a valid integer value, but invalid character with "
4821 "character code %u was detected at index %lu", opnum, opname, c,
4822 (unsigned long) i);
4823 }
4824 set_valuetype(V_ERROR);
4825 break;
4826 }
4827 }
4828 switch (state) {
4829 case S_INITIAL:
4830 case S_INITIAL_WS:
4831 val->error("%s operand of operation `%s' should be a string containing a "
4832 "valid integer value instead of an empty string", opnum, opname);
4833 set_valuetype(V_ERROR);
4834 break;
4835 case S_FIRST:
4836 val->error("%s operand of operation `%s' should be a string containing a "
4837 "valid integer value, but only a sign character was detected", opnum,
4838 opname);
4839 set_valuetype(V_ERROR);
4840 break;
4841 case S_END:
4842 val->warning("Trailing whitespace was detected and ignored in the "
4843 "operand of operation `%s'", opname);
4844 break;
4845 default:
4846 break;
4847 }
4848 }
4849
4850 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4851 const char *opname)
4852 {
4853 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4854 Value *v_last = val->get_value_refd_last();
4855 if (v_last->valuetype == V_REFD) {
4856 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4857 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4858 val->error("%s operand of operation `%s' should be a string containing "
4859 "a valid float value instead of a string element, which cannot "
4860 "represent a floating point number", opnum, opname);
4861 set_valuetype(V_ERROR);
4862 }
4863 return;
4864 } else if (v_last->valuetype != V_CSTR) return;
4865 const string& s = v_last->get_val_str();
4866 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4867 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4868 state = S_INITIAL;
4869 // state: expected characters
4870 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4871 // leading whitespace
4872 // S_FIRST_M: first digit of integer part in mantissa
4873 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4874 // S_FIRST_F: first digit of fraction
4875 // S_MORE_F: more digits of fraction, E, trailing whitespace
4876 // S_INITIAL_E: +, -, first digit of exponent
4877 // S_FIRST_E: first digit of exponent
4878 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4879 // S_END: trailing whitespace
4880 // S_ERR: error was found, stop
4881 for (size_t i = 0; i < s.size(); i++) {
4882 char c = s[i];
4883 switch (state) {
4884 case S_INITIAL:
4885 case S_INITIAL_WS:
4886 if (c == '+' || c == '-') state = S_FIRST_M;
4887 else if (c == '0') state = S_ZERO_M;
4888 else if (c >= '1' && c <= '9') state = S_MORE_M;
4889 else if (string::is_whitespace(c)) {
4890 if (state == S_INITIAL) {
4891 val->warning("Leading whitespace was detected and ignored in the "
4892 "operand of operation `%s'", opname);
4893 state = S_INITIAL_WS;
4894 }
4895 } else state = S_ERR;
4896 break;
4897 case S_FIRST_M:
4898 if (c == '0') state = S_ZERO_M;
4899 else if (c >= '1' && c <= '9') state = S_MORE_M;
4900 else state = S_ERR;
4901 break;
4902 case S_ZERO_M:
4903 if (c == '.') state = S_FIRST_F;
4904 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4905 else if (c >= '0' && c <= '9') {
4906 val->warning("Leading zero digit was detected and ignored in the "
4907 "mantissa of the operand of operation `%s'", opname);
4908 state = S_MORE_M;
4909 } else state = S_ERR;
4910 break;
4911 case S_MORE_M:
4912 if (c == '.') state = S_FIRST_F;
4913 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4914 else if (c >= '0' && c <= '9') {}
4915 else state = S_ERR;
4916 break;
4917 case S_FIRST_F:
4918 if (c >= '0' && c <= '9') state = S_MORE_F;
4919 else state = S_ERR;
4920 break;
4921 case S_MORE_F:
4922 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4923 else if (c >= '0' && c <= '9') {}
4924 else if (string::is_whitespace(c)) state = S_END;
4925 else state = S_ERR;
4926 break;
4927 case S_INITIAL_E:
4928 if (c == '+' || c == '-') state = S_FIRST_E;
4929 else if (c == '0') state = S_ZERO_E;
4930 else if (c >= '1' && c <= '9') state = S_MORE_E;
4931 else state = S_ERR;
4932 break;
4933 case S_FIRST_E:
4934 if (c == '0') state = S_ZERO_E;
4935 else if (c >= '1' && c <= '9') state = S_MORE_E;
4936 else state = S_ERR;
4937 break;
4938 case S_ZERO_E:
4939 if (c >= '0' && c <= '9') {
4940 val->warning("Leading zero digit was detected and ignored in the "
4941 "exponent of the operand of operation `%s'", opname);
4942 state = S_MORE_E;
4943 } else if (string::is_whitespace(c)) state = S_END;
4944 else state = S_ERR;
4945 break;
4946 case S_MORE_E:
4947 if (c >= '0' && c <= '9') {}
4948 else if (string::is_whitespace(c)) state = S_END;
4949 else state = S_ERR;
4950 break;
4951 case S_END:
4952 if (!string::is_whitespace(c)) state = S_ERR;
4953 break;
4954 default:
4955 break;
4956 }
4957 if (state == S_ERR) {
4958 if (string::is_printable(c)) {
4959 val->error("%s operand of operation `%s' should be a string "
4960 "containing a valid float value, but invalid character `%c' "
4961 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4962 } else {
4963 val->error("%s operand of operation `%s' should be a string "
4964 "containing a valid float value, but invalid character with "
4965 "character code %u was detected at index %lu", opnum, opname, c,
4966 (unsigned long) i);
4967 }
4968 set_valuetype(V_ERROR);
4969 break;
4970 }
4971 }
4972 switch (state) {
4973 case S_INITIAL:
4974 case S_INITIAL_WS:
4975 val->error("%s operand of operation `%s' should be a string containing a "
4976 "valid float value instead of an empty string", opnum, opname);
4977 set_valuetype(V_ERROR);
4978 break;
4979 case S_FIRST_M:
4980 val->error("%s operand of operation `%s' should be a string containing a "
4981 "valid float value, but only a sign character was detected", opnum,
4982 opname);
4983 set_valuetype(V_ERROR);
4984 break;
4985 case S_ZERO_M:
4986 case S_MORE_M:
4987 // HL67862: Missing decimal dot allowed for str2float
4988 break;
4989 case S_FIRST_F:
4990 // HL67862: Missing fraction part is allowed for str2float
4991 break;
4992 case S_INITIAL_E:
4993 case S_FIRST_E:
4994 val->error("%s operand of operation `%s' should be a string containing a "
4995 "valid float value, but the exponent is missing after the `E' sign",
4996 opnum, opname);
4997 set_valuetype(V_ERROR);
4998 break;
4999 case S_END:
5000 val->warning("Trailing whitespace was detected and ignored in the "
5001 "operand of operation `%s'", opname);
5002 break;
5003 default:
5004 break;
5005 }
5006 }
5007
5008 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
5009 const char *opname)
5010 {
5011 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5012 Value *v = val->get_value_refd_last();
5013 if (v->valuetype != V_USTR) return;
5014 const ustring& us = v->get_val_ustr();
5015 for (size_t i = 0; i < us.size(); i++) {
5016 const ustring::universal_char& uchar = us[i];
5017 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
5018 uchar.cell > 127) {
5019 val->error("%s operand of operation `%s' shall consist of characters "
5020 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5021 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5022 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
5023 uchar.row, uchar.cell, (unsigned long) i);
5024 set_valuetype(V_ERROR);
5025 return;
5026 }
5027 }
5028 }
5029
5030 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
5031 const char *opname)
5032 {
5033 if(valuetype==V_ERROR) return;
5034 if(u.expr.state==EXPR_CHECKING_ERR) return;
5035 if(val->is_unfoldable()) return;
5036 const string& bstr=val->get_val_str();
5037 // see also PredefFunc.cc::bit2int()
5038 size_t nof_bits = bstr.size();
5039 // skip the leading zeros
5040 size_t start_index = 0;
5041 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
5042 // check whether the remaining bits fit in Int
5043 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
5044 val->error("%s operand of operation `%s' is too large (maximum number"
5045 " of bits in integer is %lu)",
5046 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5047 set_valuetype(V_ERROR);
5048 }
5049 }
5050
5051 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
5052 const char *opname)
5053 {
5054 if(valuetype==V_ERROR) return;
5055 if(u.expr.state==EXPR_CHECKING_ERR) return;
5056 if(val->is_unfoldable()) return;
5057 const string& hstr=val->get_val_str();
5058 // see also PredefFunc.cc::hex2int()
5059 size_t nof_digits = hstr.size();
5060 // skip the leading zeros
5061 size_t start_index = 0;
5062 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
5063 // check whether the remaining hex digits fit in Int
5064 if (nof_digits - start_index > 2 * sizeof(Int) ||
5065 (nof_digits - start_index == 2 * sizeof(Int) &&
5066 char_to_hexdigit(hstr[start_index]) > 7)) {
5067 val->error("%s operand of operation `%s' is too large (maximum number"
5068 " of bits in integer is %lu)",
5069 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5070 set_valuetype(V_ERROR);
5071 }
5072 }
5073
5074 void Value::chk_expr_operands_int2binstr()
5075 {
5076 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5077 if (u.expr.v1->is_unfoldable()) return;
5078 if (u.expr.v2->is_unfoldable()) return;
5079 // It is already checked that i1 and i2 are non-negative.
5080 Error_Context cntxt(this, "In operation `%s'", get_opname());
5081 const int_val_t *i1 = u.expr.v1->get_val_Int();
5082 const int_val_t *i2 = u.expr.v2->get_val_Int();
5083 if (!i2->is_native()) {
5084 u.expr.v2->error("The length of the resulting string is too large for "
5085 "being represented in memory");
5086 set_valuetype(V_ERROR);
5087 return;
5088 }
5089 Int nof_bits = i2->get_val();
5090 if (u.expr.v1->is_unfoldable()) return;
5091 switch (u.expr.v_optype) {
5092 case OPTYPE_INT2BIT:
5093 break;
5094 case OPTYPE_INT2HEX:
5095 nof_bits *= 4;
5096 break;
5097 case OPTYPE_INT2OCT:
5098 nof_bits *= 8;
5099 break;
5100 default:
5101 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5102 }
5103 if (*i1 >> nof_bits > 0) { // Expensive?
5104 u.expr.v1->error("Value %s does not fit in length %s",
5105 i1->t_str().c_str(), i2->t_str().c_str());
5106 set_valuetype(V_ERROR);
5107 }
5108 }
5109
5110 void Value::chk_expr_operands_str_samelen()
5111 {
5112 if(valuetype==V_ERROR) return;
5113 if(u.expr.state==EXPR_CHECKING_ERR) return;
5114 Value *v1=u.expr.v1;
5115 if(v1->is_unfoldable()) return;
5116 Value *v2=u.expr.v2;
5117 if(v2->is_unfoldable()) return;
5118 Error_Context cntxt(this, "In operation `%s'", get_opname());
5119 size_t i1=v1->get_val_strlen();
5120 size_t i2=v2->get_val_strlen();
5121 if(i1!=i2) {
5122 error("The operands should have the same length");
5123 set_valuetype(V_ERROR);
5124 }
5125 }
5126
5127 void Value::chk_expr_operands_replace()
5128 {
5129 // The fourth operand doesn't need to be checked at all here.
5130 if(valuetype==V_ERROR) return;
5131 if(u.expr.state==EXPR_CHECKING_ERR) return;
5132 Value* v1 = u.expr.ti1->get_specific_value();
5133 if (!v1) return;
5134
5135 Error_Context cntxt(this, "In operation `%s'", get_opname());
5136 size_t list_len = 0;
5137 bool list_len_known = false;
5138 if (v1->valuetype == V_REFD) {
5139 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5140 if (subrefs && subrefs->refers_to_string_element()) {
5141 warning("Replacing a string element does not make any sense");
5142 list_len = 1;
5143 list_len_known = true;
5144 }
5145 }
5146 if (!v1->is_unfoldable()) {
5147 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5148 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5149 list_len_known = true;
5150 }
5151 if (!list_len_known) return;
5152 if (u.expr.v2->is_unfoldable()) {
5153 if (!u.expr.v3->is_unfoldable()) {
5154 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5155 if (*len_int_3 > static_cast<Int>(list_len)) {
5156 error("Third operand `len' (%s) is greater than the length of "
5157 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5158 (unsigned long)list_len);
5159 set_valuetype(V_ERROR);
5160 }
5161 }
5162 } else {
5163 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5164 if (u.expr.v3->is_unfoldable()) {
5165 if (*index_int_2 > static_cast<Int>(list_len)) {
5166 error("Second operand `index' (%s) is greater than the length of "
5167 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5168 (unsigned long)list_len);
5169 set_valuetype(V_ERROR);
5170 }
5171 } else {
5172 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5173 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5174 error("The sum of second operand `index' (%s) and third operand "
5175 "`len' (%s) is greater than the length of the first operand (%lu)",
5176 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5177 (unsigned long)list_len);
5178 set_valuetype(V_ERROR);
5179 }
5180 }
5181 }
5182 }
5183
5184 void Value::chk_expr_operands_substr()
5185 {
5186 if(valuetype==V_ERROR) return;
5187 if(u.expr.state==EXPR_CHECKING_ERR) return;
5188 Value* v1 = u.expr.ti1->get_specific_value();
5189 if (!v1) return;
5190
5191 Error_Context cntxt(this, "In operation `%s'", get_opname());
5192 size_t list_len = 0;
5193 bool list_len_known = false;
5194 if (v1->valuetype == V_REFD) {
5195 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5196 if (subrefs && subrefs->refers_to_string_element()) {
5197 warning("Taking the substring of a string element does not make any "
5198 "sense");
5199 list_len = 1;
5200 list_len_known = true;
5201 }
5202 }
5203 if (!list_len_known && !v1->is_unfoldable()) {
5204 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5205 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5206 list_len_known = true;
5207 }
5208 // Do nothing if the length of the first operand is unknown.
5209 if (!list_len_known) return;
5210 if (u.expr.v2->is_unfoldable()) {
5211 if (!u.expr.v3->is_unfoldable()) {
5212 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5213 // Only the third operand is known.
5214 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5215 error("Third operand `returncount' (%s) is greater than the "
5216 "length of the first operand (%lu)",
5217 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5218 set_valuetype(V_ERROR);
5219 }
5220 }
5221 } else {
5222 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5223 if (u.expr.v3->is_unfoldable()) {
5224 // Only the second operand is known.
5225 if (*index_int_2 > static_cast<Int>(list_len)) {
5226 error("Second operand `index' (%s) is greater than the length "
5227 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5228 (unsigned long)list_len);
5229 set_valuetype(V_ERROR);
5230 }
5231 } else {
5232 // Both second and third operands are known.
5233 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5234 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5235 error("The sum of second operand `index' (%s) and third operand "
5236 "`returncount' (%s) is greater than the length of the first operand "
5237 "(%lu)", (index_int_2->t_str()).c_str(),
5238 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5239 set_valuetype(V_ERROR);
5240 }
5241 }
5242 }
5243 }
5244
5245 void Value::chk_expr_operands_regexp()
5246 {
5247 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5248 Value* v1 = u.expr.ti1->get_specific_value();
5249 Value* v2 = u.expr.t2->get_specific_value();
5250 if (!v1 || !v2) return;
5251
5252 Error_Context cntxt(this, "In operation `regexp()'");
5253 Value* v1_last = v1->get_value_refd_last();
5254 if (v1_last->valuetype == V_CSTR) {
5255 // the input string is available at compile time
5256 const string& instr = v1_last->get_val_str();
5257 const char *input_str = instr.c_str();
5258 size_t instr_len = strlen(input_str);
5259 if (instr_len < instr.size()) {
5260 v1->warning("The first operand of `regexp()' contains a "
5261 "character with character code zero at index %s. The rest of the "
5262 "string will be ignored during matching",
5263 Int2string(instr_len).c_str());
5264 }
5265 }
5266
5267 size_t nof_groups = 0;
5268 Value *v2_last = v2->get_value_refd_last();
5269
5270 if (v2_last->valuetype == V_CSTR) {
5271 // the pattern is available at compile time
5272 const string& expression = v2_last->get_val_str();
5273 const char *pattern_str = expression.c_str();
5274 size_t pattern_len = strlen(pattern_str);
5275 if (pattern_len < expression.size()) {
5276 v2->warning("The second operand of `regexp()' contains a "
5277 "character with character code zero at index %s. The rest of the "
5278 "string will be ignored during matching",
5279 Int2string(pattern_len).c_str());
5280 }
5281 char *posix_str;
5282 {
5283 Error_Context cntxt2(v2, "In character string pattern");
5284 posix_str = TTCN_pattern_to_regexp(pattern_str);
5285 }
5286 if (posix_str != NULL) {
5287 regex_t posix_regexp;
5288 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5289 if (ret_val != 0) {
5290 char msg[512];
5291 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5292 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5293 "regcomp() failed: %s", msg);
5294 }
5295 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5296 else {
5297 v2->error("The character pattern in the second operand of "
5298 "`regexp()' does not contain any groups");
5299 set_valuetype(V_ERROR);
5300 }
5301 regfree(&posix_regexp);
5302 Free(posix_str);
5303 } else {
5304 // the pattern is faulty
5305 // the error has been reported by TTCN_pattern_to_regexp
5306 set_valuetype(V_ERROR);
5307 }
5308 }
5309 if (nof_groups > 0) {
5310 Value *v3 = u.expr.v3->get_value_refd_last();
5311 if (v3->valuetype == V_INT) {
5312 // the group number is available at compile time
5313 const int_val_t *groupno_int = v3->get_val_Int();
5314 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5315 u.expr.v3->error("The the third operand of `regexp()' is too "
5316 "large: The requested group index is %s, but the pattern "
5317 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5318 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5319 set_valuetype(V_ERROR);
5320 }
5321 }
5322 }
5323 }
5324
5325 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5326 Type::expected_value_t exp_val)
5327 {
5328 const char *opname = get_opname();
5329 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5330 Type *t_governor;
5331 const Location *loc;
5332 bool error_flag = false;
5333 switch (u.expr.v_optype) {
5334 case OPTYPE_ISCHOSEN_V:
5335 // u.expr.v1 is always a referenced value
5336 t_governor = u.expr.v1->get_expr_governor(exp_val);
5337 if (t_governor) {
5338 u.expr.v1->set_my_governor(t_governor);
5339 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5340 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5341 } else error_flag = true;
5342 loc = u.expr.v1;
5343 break;
5344 case OPTYPE_ISCHOSEN_T:
5345 // u.expr.t1 is always a referenced template
5346 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5347 exp_val = Type::EXPECTED_TEMPLATE;
5348 t_governor = u.expr.t1->get_expr_governor(exp_val);
5349 if (t_governor) {
5350 u.expr.t1->set_my_governor(t_governor);
5351 //
5352 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5353 //
5354 u.expr.t1->get_template_refd_last(refch);
5355 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5356 error_flag = true;
5357 } else error_flag = true;
5358 if (exp_val != Type::EXPECTED_TEMPLATE) {
5359 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5360 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5361 u.expr.t1->get_reference()->get_refd_assignment()
5362 ->get_description().c_str());
5363 error_flag = true;
5364 }
5365 loc = u.expr.t1;
5366 break;
5367 default:
5368 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5369 t_governor = 0;
5370 loc = 0;
5371 }
5372 if (t_governor) {
5373 t_governor = t_governor->get_type_refd_last();
5374 switch (t_governor->get_typetype()) {
5375 case Type::T_ERROR:
5376 error_flag = true;
5377 break;
5378 case Type::T_CHOICE_A:
5379 case Type::T_CHOICE_T:
5380 case Type::T_ANYTYPE:
5381 case Type::T_OPENTYPE:
5382 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5383 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5384 "%s does not have a field named `%s'" :
5385 "Union type `%s' does not have a field named `%s'",
5386 t_governor->get_typename().c_str(),
5387 u.expr.i2->get_dispname().c_str());
5388 error_flag = true;
5389 }
5390 break;
5391 default:
5392 loc->error("The operand of operation `%s' should be a union value "
5393 "or template instead of `%s'", opname,
5394 t_governor->get_typename().c_str());
5395 error_flag = true;
5396 break;
5397 }
5398 }
5399 if (error_flag) set_valuetype(V_ERROR);
5400 }
5401
5402 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5403 Type::expected_value_t exp_val) {
5404
5405 Error_Context cntxt(this, "In the parameter of encvalue()");
5406 Type t_chk(Type::T_ERROR);
5407 Type* t_type;
5408
5409 Type::expected_value_t ti_exp_val = exp_val;
5410 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5411 ti_exp_val = Type::EXPECTED_TEMPLATE;
5412
5413 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5414 if (t_type) {
5415 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5416 if (valuetype!=V_ERROR)
5417 u.expr.ti1->get_Template()->chk_specific_value(false);
5418 t_type = t_type->get_type_refd_last();
5419 } else {
5420 error("Cannot determine type of value");
5421 goto error;
5422 }
5423
5424 // todo: fix this
5425 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5426 error("Expecting a value of a type with coding attributes in first"
5427 "parameter of encvalue() which belongs to a generic type '%s'",
5428 t_type->get_typename().c_str());
5429 goto error;
5430 }*/
5431
5432 if(!disable_attribute_validation()) {
5433 t_type->chk_coding(true);
5434 }
5435
5436 switch (t_type->get_typetype()) {
5437 case Type::T_UNDEF:
5438 case Type::T_ERROR:
5439 case Type::T_NULL:
5440 case Type::T_REFD:
5441 case Type::T_REFDSPEC:
5442 case Type::T_SELTYPE:
5443 case Type::T_VERDICT:
5444 case Type::T_PORT:
5445 case Type::T_COMPONENT:
5446 case Type::T_DEFAULT:
5447 case Type::T_SIGNATURE:
5448 case Type::T_FUNCTION:
5449 case Type::T_ALTSTEP:
5450 case Type::T_TESTCASE:
5451 error("Type of parameter of encvalue() cannot be '%s'",
5452 t_type->get_typename().c_str());
5453 goto error;
5454 default:
5455 break;
5456 }
5457 return;
5458 error:
5459 set_valuetype(V_ERROR);
5460 }
5461
5462 void Value::chk_expr_operands_decode(operationtype_t p_optype)
5463 {
5464 Error_Context cntxt(this, "In the parameters of decvalue()"); //todo
5465 Ttcn::Ref_base* ref = u.expr.r1;
5466 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5467 Type* t_type = 0;
5468 Assignment* t_ass = ref->get_refd_assignment();
5469
5470 if (!t_ass) {
5471 error("Could not determine the assignment for first parameter");
5472 goto error;
5473 }
5474 switch (t_ass->get_asstype()) {
5475 case Assignment::A_PAR_VAL_IN:
5476 t_ass->use_as_lvalue(*this);
5477 break;
5478 case Assignment::A_CONST:
5479 case Assignment::A_EXT_CONST:
5480 case Assignment::A_MODULEPAR:
5481 case Assignment::A_MODULEPAR_TEMP:
5482 case Assignment::A_TEMPLATE:
5483 ref->error("Reference to '%s' cannot be used as the first operand of "
5484 "the 'decvalue' operation", t_ass->get_assname());
5485 goto error;
5486 break;
5487 case Assignment::A_VAR:
5488 case Assignment::A_PAR_VAL_OUT:
5489 case Assignment::A_PAR_VAL_INOUT:
5490 break;
5491 case Assignment::A_VAR_TEMPLATE:
5492 case Assignment::A_PAR_TEMPL_IN:
5493 case Assignment::A_PAR_TEMPL_OUT:
5494 case Assignment::A_PAR_TEMPL_INOUT: {
5495 Template* t = new Template(ref->clone());
5496 t->set_location(*ref);
5497 t->set_my_scope(get_my_scope());
5498 t->set_fullname(get_fullname()+".<operand>");
5499 Template* t_last = t->get_template_refd_last();
5500 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5501 && t_last != t) {
5502 ref->error("Specific value template was expected instead of '%s'.",
5503 t->get_template_refd_last()->get_templatetype_str());
5504 delete t;
5505 goto error;
5506 }
5507 delete t;
5508 break; }
5509 default:
5510 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5511 goto error;
5512 }
5513 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5514 Type::EXPECTED_DYNAMIC_VALUE);
5515 if (!t_type) {
5516 goto error;
5517 }
5518 switch(p_optype) {
5519 case OPTYPE_DECODE:
5520 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5521 error("First parameter has to be a bitstring");
5522 goto error;
5523 }
5524 break;
5525 case OPTYPE_DECVALUE_UNICHAR:
5526 if (t_type->get_type_refd_last()->get_typetype() != Type::T_USTR){
5527 error("First parameter has to be a universal charstring");
5528 goto error;
5529 }
5530 break;
5531 default:
5532 FATAL_ERROR("Value::chk_expr_decode_operands()");
5533 break;
5534 }
5535
5536 ref = u.expr.r2;
5537 t_subrefs = ref->get_subrefs();
5538 t_ass = ref->get_refd_assignment();
5539
5540 if (!t_ass) {
5541 error("Could not determine the assignment for second parameter");
5542 goto error;
5543 }
5544 // Extra check for HM59355.
5545 switch (t_ass->get_asstype()) {
5546 case Assignment::A_VAR:
5547 case Assignment::A_PAR_VAL_IN:
5548 case Assignment::A_PAR_VAL_OUT:
5549 case Assignment::A_PAR_VAL_INOUT:
5550 break;
5551 default:
5552 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5553 goto error;
5554 }
5555 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5556 Type::EXPECTED_DYNAMIC_VALUE);
5557 if (!t_type) {
5558 goto error;
5559 }
5560 t_type = t_type->get_type_refd_last();
5561 switch (t_type->get_typetype()) {
5562 case Type::T_UNDEF:
5563 case Type::T_ERROR:
5564 case Type::T_NULL:
5565 case Type::T_REFD:
5566 case Type::T_REFDSPEC:
5567 case Type::T_SELTYPE:
5568 case Type::T_VERDICT:
5569 case Type::T_PORT:
5570 case Type::T_COMPONENT:
5571 case Type::T_DEFAULT:
5572 case Type::T_SIGNATURE:
5573 case Type::T_FUNCTION:
5574 case Type::T_ALTSTEP:
5575 case Type::T_TESTCASE:
5576 error("Type of second parameter cannot be %s",
5577 t_type->get_typename().c_str());
5578 goto error;
5579 default:
5580 break;
5581 }
5582
5583 if(!disable_attribute_validation()) {
5584 t_type->chk_coding(false);
5585 }
5586
5587 return;
5588 error:
5589 set_valuetype(V_ERROR);
5590 }
5591
5592 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5593 {
5594 Ttcn::FieldOrArrayRefs *subrefs;
5595 Identifier *field_id = 0;
5596 Assignment *t_ass;
5597 Type *t_type;
5598 if (valuetype == V_ERROR) return;
5599 else if (valuetype != V_REFD) {
5600 error("Only a referenced value can be compared with `omit'");
5601 goto error;
5602 }
5603 subrefs = u.ref.ref->get_subrefs();
5604 if (subrefs) field_id = subrefs->remove_last_field();
5605 if (!field_id) {
5606 error("Only a reference pointing to an optional record or set field "
5607 "can be compared with `omit'");
5608 goto error;
5609 }
5610 t_ass = u.ref.ref->get_refd_assignment();
5611 if (!t_ass) goto error;
5612 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5613 if (!t_type) goto error;
5614 t_type = t_type->get_type_refd_last();
5615 switch (t_type->get_typetype()) {
5616 case Type::T_ERROR:
5617 goto error;
5618 case Type::T_SEQ_A:
5619 case Type::T_SEQ_T:
5620 case Type::T_SET_A:
5621 case Type::T_SET_T:
5622 break;
5623 default:
5624 error("Only a reference pointing to an optional field of a record"
5625 " or set type can be compared with `omit'");
5626 goto error;
5627 }
5628 if (!t_type->has_comp_withName(*field_id)) {
5629 error("Type `%s' does not have field named `%s'",
5630 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5631 goto error;
5632 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5633 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5634 "`omit'", field_id->get_dispname().c_str(),
5635 t_type->get_typename().c_str());
5636 goto error;
5637 }
5638 // putting the last field_id back to subrefs
5639 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5640 return;
5641 error:
5642 set_valuetype(V_ERROR);
5643 delete field_id;
5644 }
5645
5646 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5647 Type::expected_value_t exp_val)
5648 {
5649 if(valuetype==V_ERROR) return -1;
5650 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5651 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5652 exp_val=Type::EXPECTED_TEMPLATE;
5653
5654 Error_Context cntxt(this, "In the operand of"
5655 " operation `%s'", get_opname());
5656
5657 Int result = -1;
5658 Template* t_templ = u.expr.ti1->get_Template();
5659
5660 if (!t_templ) {
5661 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5662 }
5663
5664 t_templ = t_templ->get_template_refd_last(refch);
5665
5666 // Timer and port arrays are handled separately
5667 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5668 Value* val = t_templ->get_specific_value();
5669 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5670 val->set_lowerid_to_ref();
5671 }
5672 if (val && val->get_valuetype() == V_REFD) {
5673 Reference* ref = val->get_reference();
5674 Assignment* t_ass = ref->get_refd_assignment();
5675 Common::Assignment::asstype_t asstype =
5676 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5677 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5678 if (t_ass->get_Dimensions()) {
5679 // here we have a timer or port array
5680 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5681 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5682 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5683 Type::EXPECTED_DYNAMIC_VALUE);
5684 size_t refd_dim;
5685 if (t_subrefs) {
5686 refd_dim = t_subrefs->get_nof_refs();
5687 size_t nof_dims = t_dims->get_nof_dims();
5688 if (refd_dim >= nof_dims) {
5689 u.expr.ti1->error("Operation is not applicable to a %s",
5690 t_ass->get_assname());
5691 set_valuetype(V_ERROR);
5692 return -1;
5693 }
5694 } else refd_dim = 0;
5695 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5696 } else {
5697 u.expr.ti1->error("Operation is not applicable to single `%s'",
5698 t_ass->get_description().c_str());
5699 set_valuetype(V_ERROR);
5700 return -1;
5701 }
5702 }
5703 }
5704 }
5705
5706 Value* t_val = 0;
5707 Type* t_type = 0;
5708 Assignment* t_ass = 0;
5709 Reference* ref = 0;
5710 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5711 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5712 if (t_type) {
5713 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5714 t_type = t_type->get_type_refd_last();
5715 } else {
5716 error("Cannot determine type of value");
5717 goto error;
5718 }
5719
5720 if(valuetype==V_ERROR) return -1;
5721
5722 t_templ = t_templ->get_template_refd_last(refch);
5723 switch(t_templ->get_templatetype()) {
5724 case Template::TEMPLATE_ERROR:
5725 goto error;
5726 case Template::INDEXED_TEMPLATE_LIST:
5727 return -1;
5728 case Template::TEMPLATE_REFD:
5729 case Template::TEMPLATE_LIST:
5730 case Template::NAMED_TEMPLATE_LIST:
5731 // computed later
5732 break;
5733 case Template::SPECIFIC_VALUE:
5734 {
5735 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5736 if(t_val) {
5737 switch(t_val->get_valuetype()) {
5738 case V_SEQOF:
5739 case V_SETOF:
5740 case V_ARRAY:
5741 case V_ROID:
5742 case V_OID:
5743 case V_SEQ:
5744 case V_SET:
5745 break;
5746 case V_REFD: {
5747 ref = t_val->get_reference();
5748 t_ass = ref->get_refd_assignment();
5749 t_subrefs = ref->get_subrefs();
5750 break;
5751 }
5752 default:
5753 u.expr.ti1->error("Operation is not applicable to `%s'",
5754 t_val->create_stringRepr().c_str());
5755 goto error;
5756 }
5757 }
5758 break;
5759 }
5760 default:
5761 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5762 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5763 goto error;
5764 } // switch
5765
5766 if (t_ass) {
5767 switch(t_ass->get_asstype()) {
5768 case Assignment::A_ERROR:
5769 goto error;
5770 case Assignment::A_CONST:
5771 t_val = t_ass->get_Value();
5772 break;
5773 case Assignment::A_EXT_CONST:
5774 case Assignment::A_MODULEPAR:
5775 case Assignment::A_MODULEPAR_TEMP:
5776 if(exp_val==Type::EXPECTED_CONSTANT) {
5777 u.expr.ti1->error("Reference to an (evaluable) constant value was "
5778 "expected instead of %s", t_ass->get_description().c_str());
5779 goto error;
5780 }
5781 break;
5782 case Assignment::A_VAR:
5783 case Assignment::A_PAR_VAL_IN:
5784 case Assignment::A_PAR_VAL_OUT:
5785 case Assignment::A_PAR_VAL_INOUT:
5786 switch(exp_val) {
5787 case Type::EXPECTED_CONSTANT:
5788 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5789 t_ass->get_description().c_str());
5790 goto error;
5791 break;
5792 case Type::EXPECTED_STATIC_VALUE:
5793 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5794 t_ass->get_description().c_str());
5795 goto error;
5796 break;
5797 default:
5798 break;
5799 }
5800 break;
5801 case Assignment::A_TEMPLATE:
5802 t_templ = t_ass->get_Template();
5803 // no break
5804 case Assignment::A_VAR_TEMPLATE:
5805 case Assignment::A_PAR_TEMPL_IN:
5806 case Assignment::A_PAR_TEMPL_OUT:
5807 case Assignment::A_PAR_TEMPL_INOUT:
5808 if (exp_val!=Type::EXPECTED_TEMPLATE)
5809 u.expr.ti1->error("Reference to a value was expected instead of %s",
5810 t_ass->get_description().c_str());
5811 goto error;
5812 break;
5813 case Assignment::A_FUNCTION_RVAL:
5814 case Assignment::A_EXT_FUNCTION_RVAL:
5815 switch(exp_val) {
5816 case Type::EXPECTED_CONSTANT:
5817 u.expr.ti1->error("Reference to a constant value was expected instead of "
5818 "the return value of %s", t_ass->get_description().c_str());
5819 goto error;
5820 break;
5821 case Type::EXPECTED_STATIC_VALUE:
5822 u.expr.ti1->error("Reference to a static value was expected instead of "
5823 "the return value of %s", t_ass->get_description().c_str());
5824 goto error;
5825 break;
5826 default:
5827 break;
5828 }
5829 break;
5830 case Assignment::A_FUNCTION_RTEMP:
5831 case Assignment::A_EXT_FUNCTION_RTEMP:
5832 if(exp_val!=Type::EXPECTED_TEMPLATE)
5833 u.expr.ti1->error("Reference to a value was expected instead of a call"
5834 " of %s, which returns a template",
5835 t_ass->get_description().c_str());
5836 goto error;
5837 break;
5838 case Assignment::A_TIMER:
5839 case Assignment::A_PORT:
5840 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5841 // sizeof is applicable to timer and port arrays
5842 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5843 if (!t_dims) {
5844 u.expr.ti1->error("Operation is not applicable to single %s",
5845 t_ass->get_description().c_str());
5846 goto error;
5847 }
5848 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5849 Type::EXPECTED_DYNAMIC_VALUE);
5850 size_t refd_dim;
5851 if (t_subrefs) {
5852 refd_dim = t_subrefs->get_nof_refs();
5853 size_t nof_dims = t_dims->get_nof_dims();
5854 if (refd_dim > nof_dims) goto error;
5855 else if (refd_dim == nof_dims) {
5856 u.expr.ti1->error("Operation is not applicable to a %s",
5857 t_ass->get_assname());
5858 goto error;
5859 }
5860 } else refd_dim = 0;
5861 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5862 }
5863 // no break
5864 default:
5865 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5866 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5867 t_ass->get_description().c_str());
5868 goto error;
5869 } // end switch
5870
5871 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5872 if (!t_type) goto error;
5873 t_type = t_type->get_type_refd_last();
5874
5875 switch(t_type->get_typetype()) {
5876 case Type::T_ERROR:
5877 goto error;
5878 case Type::T_SEQOF:
5879 case Type::T_SETOF:
5880 // no break
5881 case Type::T_SEQ_T:
5882 case Type::T_SET_T:
5883 case Type::T_SEQ_A:
5884 case Type::T_SET_A:
5885 case Type::T_ARRAY:
5886 // ok
5887 break;
5888 case Type::T_OID:
5889 case Type::T_ROID:
5890 break;
5891 default:
5892 u.expr.ti1->error("Reference to value or template of type record, record of,"
5893 " set, set of, objid or array was expected");
5894 goto error;
5895 } // switch
5896 }
5897
5898 // check for index overflows in subrefs if possible
5899 if (t_val) {
5900 switch (t_val->get_valuetype()) {
5901 case V_SEQOF:
5902 case V_SETOF:
5903 case V_ARRAY:
5904 if (t_val->is_indexed()) {
5905 return -1;
5906 }
5907 break;
5908 default:
5909 break;
5910 }
5911 /* The reference points to a constant. */
5912 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5913 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5914 if (!t_val) goto error;
5915 t_val=t_val->get_value_refd_last(refch);
5916 } else { t_val = 0; }
5917 } else if (t_templ) {
5918 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5919 time. Don't try to evaluate it at compile time. */
5920 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5921 return -1;
5922 /* The reference points to a static template. */
5923 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5924 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5925 if (!t_templ) goto error;
5926 t_templ = t_templ->get_template_refd_last(refch);
5927 } else { t_templ = 0; }
5928 }
5929
5930 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5931 if(t_templ) {
5932 switch(t_templ->get_templatetype()) {
5933 case Template::TEMPLATE_ERROR:
5934 goto error;
5935 case Template::TEMPLATE_REFD:
5936 // not foldable
5937 t_templ=0;
5938 break;
5939 case Template::SPECIFIC_VALUE:
5940 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5941 t_templ=0;
5942 break;
5943 case Template::TEMPLATE_LIST:
5944 case Template::NAMED_TEMPLATE_LIST:
5945 break;
5946 default:
5947 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5948 t_templ->get_templatetype_str(),
5949 t_templ->get_fullname().c_str());
5950 goto error;
5951 } // switch
5952 }
5953 if(t_val) {
5954 switch(t_val->get_valuetype()) {
5955 case V_SEQOF:
5956 case V_SETOF:
5957 case V_ARRAY:
5958 case V_SEQ:
5959 case V_SET:
5960 case V_OID:
5961 case V_ROID:
5962 // ok
5963 break;
5964 default:
5965 // error is already reported
5966 t_val=0;
5967 break;
5968 } // switch
5969 }
5970 }
5971
5972 /* evaluation */
5973
5974 if(t_type->get_typetype()==Type::T_ARRAY) {
5975 result = t_type->get_dimension()->get_size();
5976 }
5977 else if(t_templ) { // sizeof()
5978 switch(t_templ->get_templatetype()) {
5979 case Template::TEMPLATE_LIST:
5980 if(t_templ->temps_contains_anyornone_symbol()) {
5981 if(t_templ->is_length_restricted()) {
5982 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
5983 if (lr->get_is_range()) {
5984 Value *v_upper = lr->get_upper_value();
5985 if (v_upper) {
5986 if (v_upper->valuetype == V_INT) {
5987 Int nof_comps =
5988 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
5989 if (v_upper->u.val_Int->get_val() == nof_comps)
5990 result = nof_comps;
5991 else {
5992 u.expr.ti1->error("`sizeof' operation is not applicable for "
5993 "templates without exact size");
5994 goto error;
5995 }
5996 }
5997 } else {
5998 u.expr.ti1->error("`sizeof' operation is not applicable for "
5999 "templates containing `*' without upper boundary in the "
6000 "length restriction");
6001 goto error;
6002 }
6003 } else {
6004 Value *v_single = lr->get_single_value();
6005 if (v_single->valuetype == V_INT)
6006 result = v_single->u.val_Int->get_val();
6007 }
6008 }
6009 else { // not length restricted
6010 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
6011 " containing `*' without length restriction");
6012 goto error;
6013 }
6014 }
6015 else result=t_templ->get_nof_listitems();
6016 break;
6017 case Template::NAMED_TEMPLATE_LIST:
6018 result=0;
6019 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
6020 if(t_templ->get_namedtemp_byIndex(i)->get_template()
6021 ->get_templatetype()!=Template::OMIT_VALUE) result++;
6022 return result;
6023 default:
6024 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6025 } // switch
6026 }
6027 else if(t_val) {
6028 switch(t_val->get_valuetype()) {
6029 case V_SEQOF:
6030 case V_SETOF:
6031 case V_ARRAY:
6032
6033 case V_OID:
6034 case V_ROID:
6035 result=t_val->get_nof_comps();
6036 break;
6037 case V_SEQ:
6038 case V_SET:
6039 result=0;
6040 for(size_t i=0; i<t_val->get_nof_comps(); i++)
6041 if(t_val->get_se_comp_byIndex(i)->get_value()
6042 ->get_valuetype()!=V_OMIT) result++;
6043 break;
6044
6045 default:
6046 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6047 } // switch
6048 }
6049
6050 return result;
6051 error:
6052 set_valuetype(V_ERROR);
6053 return -1;
6054 }
6055
6056 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
6057 {
6058 Type *governor = ti->get_expr_governor(exp_val);
6059 if (!governor) {
6060 ti->get_Template()->set_lowerid_to_ref();
6061 governor = ti->get_expr_governor(exp_val);
6062 }
6063 if (!governor) {
6064 string str;
6065 ti->append_stringRepr( str);
6066 ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6067 "If type is known, use valueof(<type>: %s) as argument.",
6068 str.c_str(), get_opname(), str.c_str());
6069 set_valuetype(V_ERROR);
6070 }
6071 return governor;
6072 }
6073
6074 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
6075 {
6076 start:
6077 Type *governor = u.expr.v1->get_expr_governor(exp_val);
6078 if (!governor) governor = u.expr.t2->get_expr_governor(
6079 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
6080 Type::EXPECTED_TEMPLATE : exp_val);
6081 if (!governor) {
6082 Template *t_temp = u.expr.t2->get_Template();
6083 if (t_temp->is_undef_lowerid()) {
6084 // We convert the template to reference first even if the value is also
6085 // an undef lowerid. The user can prevent this by explicit type
6086 // specification.
6087 t_temp->set_lowerid_to_ref();
6088 goto start;
6089 } else if (u.expr.v1->is_undef_lowerid()) {
6090 u.expr.v1->set_lowerid_to_ref();
6091 goto start;
6092 }
6093 }
6094 if (!governor) {
6095 error("Cannot determine the type of arguments in `match()' operation");
6096 set_valuetype(V_ERROR);
6097 return;
6098 }
6099 u.expr.v1->set_my_governor(governor);
6100 {
6101 Error_Context cntxt(this, "In the first argument of `match()'"
6102 " operation");
6103 governor->chk_this_value_ref(u.expr.v1);
6104 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
6105 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6106 }
6107 {
6108 Error_Context cntxt(this, "In the second argument of `match()' "
6109 "operation");
6110 u.expr.t2->chk(governor);
6111 }
6112 }
6113
6114 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
6115 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
6116 {
6117 Ttcn::StatementBlock *my_sb;
6118 switch (exp_val) {
6119 case Type::EXPECTED_CONSTANT:
6120 error("An evaluable constant value was expected instead of operation "
6121 "`%s'", get_opname());
6122 goto error;
6123 case Type::EXPECTED_STATIC_VALUE:
6124 error("A static value was expected instead of operation `%s'",
6125 get_opname());
6126 goto error;
6127 default:
6128 break;
6129 } // switch
6130 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6131 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
6132 if (!my_sb) {
6133 error("Operation `%s' is allowed only within statements",
6134 get_opname());
6135 goto error;
6136 }
6137 if (!allow_controlpart && !my_sb->get_my_def()) {
6138 error("Operation `%s' is not allowed in the control part",
6139 get_opname());
6140 goto error;
6141 }
6142 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6143 error("Operation `%s' cannot be used in a definition that has "
6144 "`runs on' clause", get_opname());
6145 goto error;
6146 }
6147 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6148 error("Operation `%s' can be used only in a definition that has "
6149 "`runs on' clause", get_opname());
6150 goto error;
6151 }
6152 return;
6153 error:
6154 set_valuetype(V_ERROR);
6155 }
6156
6157 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6158 {
6159 if(valuetype==V_ERROR) return;
6160 if(u.expr.state==EXPR_CHECKING_ERR) return;
6161 if(v->is_unfoldable()) return;
6162 if(v->get_expr_returntype()!=Type::T_REAL) return;
6163 ttcn3float r = v->get_val_Real();
6164 if (isSpecialFloatValue(r)) {
6165 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6166 opnum, opname, Real2string(r).c_str());
6167 set_valuetype(V_ERROR);
6168 }
6169 }
6170
6171 void Value::chk_expr_operands(ReferenceChain *refch,
6172 Type::expected_value_t exp_val)
6173 {
6174 const char *first="First", *second="Second", *third="Third",
6175 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6176 Value *v1, *v2, *v3;
6177 Type::typetype_t tt1, tt2, tt3;
6178 Type t_chk(Type::T_ERROR);
6179
6180 const char *opname=get_opname();
6181
6182 // first classify the unchecked ischosen() operation
6183 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6184
6185 switch (u.expr.v_optype) {
6186 case OPTYPE_COMP_NULL:
6187 case OPTYPE_TESTCASENAME:
6188 case OPTYPE_PROF_RUNNING:
6189 break;
6190 case OPTYPE_COMP_MTC:
6191 case OPTYPE_COMP_SYSTEM:
6192 chk_expr_comptype_compat();
6193 break;
6194 case OPTYPE_RND: // -
6195 case OPTYPE_TMR_RUNNING_ANY:
6196 chk_expr_dynamic_part(exp_val, true);
6197 break;
6198 case OPTYPE_COMP_RUNNING_ANY:
6199 case OPTYPE_COMP_RUNNING_ALL:
6200 case OPTYPE_COMP_ALIVE_ANY:
6201 case OPTYPE_COMP_ALIVE_ALL:
6202 case OPTYPE_GETVERDICT:
6203 chk_expr_dynamic_part(exp_val, false);
6204 break;
6205 case OPTYPE_COMP_SELF:
6206 chk_expr_comptype_compat();
6207 chk_expr_dynamic_part(exp_val, false, true, false);
6208 break;
6209 case OPTYPE_UNARYPLUS: // v1
6210 case OPTYPE_UNARYMINUS:
6211 v1=u.expr.v1;
6212 {
6213 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6214 v1->set_lowerid_to_ref();
6215 tt1=v1->get_expr_returntype(exp_val);
6216 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6217 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6218 }
6219 break;
6220 case OPTYPE_NOT:
6221 v1=u.expr.v1;
6222 {
6223 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6224 v1->set_lowerid_to_ref();
6225 tt1=v1->get_expr_returntype(exp_val);
6226 chk_expr_operandtype_bool(tt1, the, opname, v1);
6227 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6228 }
6229 break;
6230 case OPTYPE_NOT4B:
6231 v1=u.expr.v1;
6232 {
6233 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6234 v1->set_lowerid_to_ref();
6235 tt1=v1->get_expr_returntype(exp_val);
6236 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6237 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6238 }
6239 break;
6240 case OPTYPE_BIT2HEX:
6241 case OPTYPE_BIT2OCT:
6242 case OPTYPE_BIT2STR:
6243 v1=u.expr.v1;
6244 {
6245 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6246 v1->set_lowerid_to_ref();
6247 tt1=v1->get_expr_returntype(exp_val);
6248 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6249 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6250 }
6251 break;
6252 case OPTYPE_BIT2INT:
6253 v1=u.expr.v1;
6254 {
6255 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6256 v1->set_lowerid_to_ref();
6257 tt1=v1->get_expr_returntype(exp_val);
6258 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6259 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6260 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6261 }
6262 break;
6263 case OPTYPE_CHAR2INT:
6264 v1=u.expr.v1;
6265 {
6266 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6267 v1->set_lowerid_to_ref();
6268 tt1=v1->get_expr_returntype(exp_val);
6269 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6270 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6271 chk_expr_val_len1(v1, the, opname);
6272 }
6273 break;
6274 case OPTYPE_CHAR2OCT:
6275 v1=u.expr.v1;
6276 {
6277 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6278 v1->set_lowerid_to_ref();
6279 tt1=v1->get_expr_returntype(exp_val);
6280 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6281 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6282 }
6283 break;
6284 case OPTYPE_STR2INT:
6285 v1=u.expr.v1;
6286 {
6287 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6288 v1->set_lowerid_to_ref();
6289 tt1=v1->get_expr_returntype(exp_val);
6290 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6291 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6292 chk_expr_val_str_int(v1, the, opname);
6293 }
6294 break;
6295 case OPTYPE_STR2FLOAT:
6296 v1=u.expr.v1;
6297 {
6298 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6299 v1->set_lowerid_to_ref();
6300 tt1=v1->get_expr_returntype(exp_val);
6301 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6302 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6303 chk_expr_val_str_float(v1, the, opname);
6304 }
6305 break;
6306 case OPTYPE_STR2BIT:
6307 v1=u.expr.v1;
6308 {
6309 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6310 v1->set_lowerid_to_ref();
6311 tt1=v1->get_expr_returntype(exp_val);
6312 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6313 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6314 chk_expr_val_str_bindigits(v1, the, opname);
6315 }
6316 break;
6317 case OPTYPE_STR2HEX:
6318 v1=u.expr.v1;
6319 {
6320 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6321 v1->set_lowerid_to_ref();
6322 tt1=v1->get_expr_returntype(exp_val);
6323 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6324 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6325 chk_expr_val_str_hexdigits(v1, the, opname);
6326 }
6327 break;
6328 case OPTYPE_STR2OCT:
6329 v1=u.expr.v1;
6330 {
6331 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6332 v1->set_lowerid_to_ref();
6333 tt1=v1->get_expr_returntype(exp_val);
6334 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6335 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6336 chk_expr_val_str_len_even(v1, the, opname);
6337 chk_expr_val_str_hexdigits(v1, the, opname);
6338 }
6339 break;
6340 case OPTYPE_ENUM2INT:
6341 v1=u.expr.v1;
6342 {
6343 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6344 chk_expr_operandtype_enum(opname, v1, exp_val);
6345 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6346 }
6347 break;
6348 case OPTYPE_ENCODE:
6349 chk_expr_operand_encode(refch, exp_val);
6350 break;
6351 case OPTYPE_FLOAT2INT:
6352 case OPTYPE_FLOAT2STR:
6353 v1=u.expr.v1;
6354 {
6355 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6356 v1->set_lowerid_to_ref();
6357 tt1=v1->get_expr_returntype(exp_val);
6358 chk_expr_operandtype_float(tt1, the, opname, v1);
6359 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6360 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6361 chk_expr_operand_valid_float(v1, the, opname);
6362 }
6363 break;
6364 case OPTYPE_RNDWITHVAL:
6365 v1=u.expr.v1;
6366 {
6367 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6368 v1->set_lowerid_to_ref();
6369 tt1=v1->get_expr_returntype(exp_val);
6370 chk_expr_operandtype_float(tt1, the, opname, v1);
6371 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6372 chk_expr_operand_valid_float(v1, the, opname);
6373 }
6374 chk_expr_dynamic_part(exp_val, true);
6375 break;
6376 case OPTYPE_HEX2BIT:
6377 case OPTYPE_HEX2OCT:
6378 case OPTYPE_HEX2STR:
6379 v1=u.expr.v1;
6380 {
6381 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6382 v1->set_lowerid_to_ref();
6383 tt1=v1->get_expr_returntype(exp_val);
6384 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6385 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6386 }
6387 break;
6388 case OPTYPE_HEX2INT:
6389 v1=u.expr.v1;
6390 {
6391 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6392 v1->set_lowerid_to_ref();
6393 tt1=v1->get_expr_returntype(exp_val);
6394 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6395 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6396 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6397 }
6398 break;
6399 case OPTYPE_INT2CHAR:
6400 v1=u.expr.v1;
6401 {
6402 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6403 v1->set_lowerid_to_ref();
6404 tt1=v1->get_expr_returntype(exp_val);
6405 chk_expr_operandtype_int(tt1, the, opname, v1);
6406 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6407 chk_expr_val_int_pos7bit(v1, the, opname);
6408 }
6409 break;
6410 case OPTYPE_INT2UNICHAR:
6411 v1=u.expr.v1;
6412 {
6413 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6414 v1->set_lowerid_to_ref();
6415 tt1=v1->get_expr_returntype(exp_val);
6416 chk_expr_operandtype_int(tt1, the, opname, v1);
6417 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6418 chk_expr_val_int_pos31bit(v1, first, opname);
6419 }
6420 break;
6421 case OPTYPE_INT2FLOAT:
6422 case OPTYPE_INT2STR:
6423 v1=u.expr.v1;
6424 {
6425 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6426 v1->set_lowerid_to_ref();
6427 tt1=v1->get_expr_returntype(exp_val);
6428 chk_expr_operandtype_int(tt1, the, opname, v1);
6429 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6430 }
6431 break;
6432 case OPTYPE_OCT2BIT:
6433 case OPTYPE_OCT2HEX:
6434 case OPTYPE_OCT2STR:
6435 v1=u.expr.v1;
6436 {
6437 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6438 v1->set_lowerid_to_ref();
6439 tt1=v1->get_expr_returntype(exp_val);
6440 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6441 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6442 }
6443 break;
6444 case OPTYPE_OCT2INT:
6445 v1=u.expr.v1;
6446 {
6447 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6448 v1->set_lowerid_to_ref();
6449 tt1=v1->get_expr_returntype(exp_val);
6450 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6451 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6452 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6453 // now.
6454 }
6455 break;
6456 case OPTYPE_OCT2CHAR:
6457 v1=u.expr.v1;
6458 {
6459 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6460 v1->set_lowerid_to_ref();
6461 tt1=v1->get_expr_returntype(exp_val);
6462 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6463 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6464 chk_expr_val_str_7bitoctets(v1, the, opname);
6465 }
6466 break;
6467 case OPTYPE_REMOVE_BOM:
6468 v1=u.expr.v1;
6469 {
6470 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6471 v1->set_lowerid_to_ref();
6472 tt1=v1->get_expr_returntype(exp_val);
6473 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6474 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6475 }
6476 break;
6477 case OPTYPE_GET_STRINGENCODING:
6478 v1=u.expr.v1;
6479 {
6480 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6481 v1->set_lowerid_to_ref();
6482 tt1=v1->get_expr_returntype(exp_val);
6483 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6484 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6485 }
6486 break;
6487 case OPTYPE_ENCODE_BASE64:
6488 v1=u.expr.v1;
6489 {
6490 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6491 v1->set_lowerid_to_ref();
6492 tt1=v1->get_expr_returntype(exp_val);
6493 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6494 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6495 }
6496 v2=u.expr.v2 ? u.expr.v2 : 0;
6497 if (v2)
6498 {
6499 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6500 v2->set_lowerid_to_ref();
6501 tt2=v2->get_expr_returntype(exp_val);
6502 chk_expr_operandtype_bool(tt2, second, opname, v2);
6503 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6504 }
6505 break;
6506 case OPTYPE_DECODE_BASE64:
6507 v1=u.expr.v1;
6508 {
6509 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6510 v1->set_lowerid_to_ref();
6511 tt1=v1->get_expr_returntype(exp_val);
6512 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6513 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6514 }
6515 break;
6516 case OPTYPE_UNICHAR2INT:
6517 v1=u.expr.v1;
6518 {
6519 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6520 v1->set_lowerid_to_ref();
6521 tt1=v1->get_expr_returntype(exp_val);
6522 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6523 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6524 chk_expr_val_len1(v1, the, opname);
6525 }
6526 break;
6527 case OPTYPE_UNICHAR2CHAR:
6528 v1=u.expr.v1;
6529 {
6530 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6531 v1->set_lowerid_to_ref();
6532 tt1=v1->get_expr_returntype(exp_val);
6533 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6534 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6535 chk_expr_val_ustr_7bitchars(v1, the, opname);
6536 }
6537 break;
6538 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6539 v1=u.expr.v1;
6540 {
6541 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6542 v1->set_lowerid_to_ref();
6543 tt1=v1->get_expr_returntype(exp_val);
6544 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6545 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6546 }
6547 v2=u.expr.v2 ? u.expr.v2 : 0;
6548 if (v2)
6549 {
6550 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6551 v2->set_lowerid_to_ref();
6552 tt2=v2->get_expr_returntype(exp_val);
6553 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6554 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6555 }
6556 break;
6557 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6558 v1=u.expr.v1;
6559 {
6560 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6561 v1->set_lowerid_to_ref();
6562 tt1=v1->get_expr_returntype(exp_val);
6563 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6564 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6565 }
6566 v2=u.expr.v2 ? u.expr.v2 : 0;
6567 if (v2)
6568 {
6569 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6570 v2->set_lowerid_to_ref();
6571 tt2=v2->get_expr_returntype(exp_val);
6572 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6573 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6574 }
6575 break;
6576 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
6577 chk_expr_operand_encode(refch, exp_val);
6578 v2=u.expr.v2 ? u.expr.v2 : 0;
6579 if (v2)
6580 {
6581 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6582 v2->set_lowerid_to_ref();
6583 tt2=v2->get_expr_returntype(exp_val);
6584 chk_expr_operandtype_charstr(tt2, second, opname, v2);
6585 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6586 }
6587 break;
6588 case OPTYPE_DECVALUE_UNICHAR:
6589 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR);
6590 v3=u.expr.v3 ? u.expr.v3 : 0;
6591 if (v3)
6592 {
6593 Error_Context cntxt(this, "In the thrid operand of operation `%s'", opname);
6594 v3->set_lowerid_to_ref();
6595 tt3=v3->get_expr_returntype(exp_val);
6596 chk_expr_operandtype_charstr(tt3, third, opname, v3);
6597 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6598 }
6599 break;
6600 case OPTYPE_ADD: // v1 v2
6601 case OPTYPE_SUBTRACT:
6602 case OPTYPE_MULTIPLY:
6603 case OPTYPE_DIVIDE:
6604 v1=u.expr.v1;
6605 {
6606 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6607 v1->set_lowerid_to_ref();
6608 tt1=v1->get_expr_returntype(exp_val);
6609 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6610 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6611 chk_expr_operand_valid_float(v1, first, opname);
6612 }
6613 v2=u.expr.v2;
6614 {
6615 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6616 v2->set_lowerid_to_ref();
6617 tt2=v2->get_expr_returntype(exp_val);
6618 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6619 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6620 chk_expr_operand_valid_float(v2, second, opname);
6621 if(u.expr.v_optype==OPTYPE_DIVIDE)
6622 chk_expr_val_int_float_not0(v2, second, opname);
6623 }
6624 chk_expr_operandtypes_same(tt1, tt2, opname);
6625 break;
6626 case OPTYPE_MOD:
6627 case OPTYPE_REM:
6628 v1=u.expr.v1;
6629 {
6630 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6631 v1->set_lowerid_to_ref();
6632 tt1=v1->get_expr_returntype(exp_val);
6633 chk_expr_operandtype_int(tt1, left, opname, v1);
6634 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6635 }
6636 v2=u.expr.v2;
6637 {
6638 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6639 v2->set_lowerid_to_ref();
6640 tt2=v2->get_expr_returntype(exp_val);
6641 chk_expr_operandtype_int(tt2, right, opname, v2);
6642 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6643 chk_expr_val_int_float_not0(v2, right, opname);
6644 }
6645 break;
6646 case OPTYPE_CONCAT: {
6647 v1=u.expr.v1;
6648 v2=u.expr.v2;
6649 v1->set_lowerid_to_ref();
6650 v2->set_lowerid_to_ref();
6651 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6652 {
6653 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6654 tt1=v1->get_expr_returntype(exp_val);
6655 chk_expr_operandtype_str(tt1, left, opname, v1);
6656 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6657 }
6658 {
6659 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6660 tt2=v2->get_expr_returntype(exp_val);
6661 chk_expr_operandtype_str(tt2, right, opname, v2);
6662 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6663 }
6664 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6665 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6666 chk_expr_operandtypes_same(tt1, tt2, opname);
6667 } else { // other list types
6668 Type* v1_gov = v1->get_expr_governor(exp_val);
6669 Type* v2_gov = v2->get_expr_governor(exp_val);
6670 if (!v1_gov) {
6671 error("Cannot determine the type of the left operand of `%s' operation", opname);
6672 set_valuetype(V_ERROR);
6673 return;
6674 } else {
6675 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6676 v1_gov->chk_this_value_ref(v1);
6677 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6678 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6679 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6680 }
6681 if (!v2_gov) {
6682 if (!v1_gov) {
6683 error("Cannot determine the type of the right operand of `%s' operation", opname);
6684 set_valuetype(V_ERROR);
6685 return;
6686 }
6687 // for recof/setof literals set the type from v1
6688 v2_gov = v1_gov;
6689 v2->set_my_governor(v1_gov);
6690 }
6691 {
6692 Error_Context cntxt(this, "In the right operand of operation `%s'",
6693 opname);
6694 v2_gov->chk_this_value_ref(v2);
6695 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6696 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6697 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6698 if (valuetype == V_ERROR) return;
6699 // 7.1.2 says that we shouldn't allow type compatibility.
6700 if (!v1_gov->is_compatible(v2_gov, NULL)
6701 && !v2_gov->is_compatible(v1_gov, NULL)) {
6702 error("The operands of operation `%s' should be of compatible "
6703 "types", get_opname());
6704 }
6705 }
6706 }
6707 break; }
6708 case OPTYPE_EQ:
6709 case OPTYPE_NE:
6710 v1 = u.expr.v1;
6711 v2 = u.expr.v2;
6712 chk_expr_operandtypes_compat(exp_val, v1, v2);
6713 {
6714 Error_Context cntxt(this, "In the left operand of operation `%s'",
6715 opname);
6716 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6717 }
6718 {
6719 Error_Context cntxt(this, "In the right operand of operation `%s'",
6720 opname);
6721 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6722 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6723 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6724 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6725 * "a == not b" is not allowed. (HL69107)
6726 * The various *Expressions implement operator precedence in the std.
6727 * Titan's parser has only one Expression and relies on Bison
6728 * for operator precedence. The check below brings Titan in line
6729 * with the standard by explicitly making "a == not b" an error */
6730 if (v2->get_valuetype() == V_EXPR
6731 && v2->u.expr.v_optype == OPTYPE_NOT) {
6732 error("The operation `%s' is not allowed to be "
6733 "the second operand of operation `%s'", v2->get_opname(), opname);
6734 set_valuetype(V_ERROR);
6735 }
6736 }
6737 break;
6738 case OPTYPE_LT:
6739 case OPTYPE_GT:
6740 case OPTYPE_GE:
6741 case OPTYPE_LE:
6742 v1=u.expr.v1;
6743 v2=u.expr.v2;
6744 chk_expr_operandtypes_compat(exp_val, v1, v2);
6745 {
6746 Error_Context cntxt(this, "In the left operand of operation `%s'",
6747 opname);
6748 tt1=v1->get_expr_returntype(exp_val);
6749 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6750 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6751 }
6752 {
6753 Error_Context cntxt(this, "In the right operand of operation `%s'",
6754 opname);
6755 tt2=v2->get_expr_returntype(exp_val);
6756 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6757 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6758 }
6759 break;
6760 case OPTYPE_AND:
6761 case OPTYPE_OR:
6762 case OPTYPE_XOR:
6763 v1=u.expr.v1;
6764 {
6765 Error_Context cntxt(this, "In the left operand of operation `%s'",
6766 opname);
6767 v1->set_lowerid_to_ref();
6768 tt1=v1->get_expr_returntype(exp_val);
6769 chk_expr_operandtype_bool(tt1, left, opname, v1);
6770 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6771 }
6772 v2=u.expr.v2;
6773 {
6774 Error_Context cntxt(this, "In the right operand of operation `%s'",
6775 opname);
6776 v2->set_lowerid_to_ref();
6777 tt2=v2->get_expr_returntype(exp_val);
6778 chk_expr_operandtype_bool(tt2, right, opname, v2);
6779 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6780 }
6781 break;
6782 case OPTYPE_AND4B:
6783 case OPTYPE_OR4B:
6784 case OPTYPE_XOR4B:
6785 v1=u.expr.v1;
6786 {
6787 Error_Context cntxt(this, "In the left operand of operation `%s'",
6788 opname);
6789 v1->set_lowerid_to_ref();
6790 tt1=v1->get_expr_returntype(exp_val);
6791 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6792 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6793 }
6794 v2=u.expr.v2;
6795 {
6796 Error_Context cntxt(this, "In the right operand of operation `%s'",
6797 opname);
6798 v2->set_lowerid_to_ref();
6799 tt2=v2->get_expr_returntype(exp_val);
6800 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6801 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6802 }
6803 chk_expr_operandtypes_same(tt1, tt2, opname);
6804 chk_expr_operands_str_samelen();
6805 break;
6806 case OPTYPE_SHL:
6807 case OPTYPE_SHR:
6808 v1=u.expr.v1;
6809 {
6810 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6811 v1->set_lowerid_to_ref();
6812 tt1=v1->get_expr_returntype(exp_val);
6813 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6814 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6815 }
6816 v2=u.expr.v2;
6817 {
6818 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6819 v2->set_lowerid_to_ref();
6820 tt2=v2->get_expr_returntype(exp_val);
6821 chk_expr_operandtype_int(tt2, right, opname, v2);
6822 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6823 chk_expr_val_large_int(v2, right, opname);
6824 }
6825 break;
6826 case OPTYPE_ROTL:
6827 case OPTYPE_ROTR:
6828 v1=u.expr.v1;
6829 v1->set_lowerid_to_ref();
6830 if (v1->is_string_type(exp_val)) {
6831 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6832 tt1=v1->get_expr_returntype(exp_val);
6833 chk_expr_operandtype_str(tt1, left, opname, v1);
6834 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6835 } else { // other list types
6836 Type* v1_gov = v1->get_expr_governor(exp_val);
6837 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6838 error("Cannot determine the type of the left operand of `%s' operation", opname);
6839 } else {
6840 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6841 v1_gov->chk_this_value_ref(v1);
6842 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6843 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6844 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6845 }
6846 }
6847 v2=u.expr.v2;
6848 {
6849 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6850 v2->set_lowerid_to_ref();
6851 tt2=v2->get_expr_returntype(exp_val);
6852 chk_expr_operandtype_int(tt2, right, opname, v2);
6853 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6854 chk_expr_val_large_int(v2, right, opname);
6855 }
6856 break;
6857 case OPTYPE_INT2BIT:
6858 case OPTYPE_INT2HEX:
6859 case OPTYPE_INT2OCT:
6860 v1=u.expr.v1;
6861 {
6862 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6863 v1->set_lowerid_to_ref();
6864 tt1=v1->get_expr_returntype(exp_val);
6865 chk_expr_operandtype_int(tt1, first, opname, v1);
6866 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6867 chk_expr_val_int_pos0(v1, first, opname);
6868 }
6869 v2=u.expr.v2;
6870 {
6871 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6872 v2->set_lowerid_to_ref();
6873 tt2=v2->get_expr_returntype(exp_val);
6874 chk_expr_operandtype_int(tt2, second, opname, v2);
6875 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6876 chk_expr_val_int_pos0(v2, second, opname);
6877 }
6878 chk_expr_operands_int2binstr();
6879 break;
6880 case OPTYPE_DECODE:
6881 chk_expr_operands_decode(OPTYPE_DECODE);
6882 break;
6883 case OPTYPE_SUBSTR:
6884 {
6885 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6886 Type::expected_value_t ti_exp_val = exp_val;
6887 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6888 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6889 if (!governor) return;
6890 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6891 if (valuetype!=V_ERROR)
6892 u.expr.ti1->get_Template()->chk_specific_value(false);
6893 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6894 }
6895 v2=u.expr.v2;
6896 {
6897 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6898 v2->set_lowerid_to_ref();
6899 tt2=v2->get_expr_returntype(exp_val);
6900 chk_expr_operandtype_int(tt2, second, opname, v2);
6901 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6902 chk_expr_val_int_pos0(v2, second, opname);
6903 }
6904 v3=u.expr.v3;
6905 {
6906 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6907 v3->set_lowerid_to_ref();
6908 tt3=v3->get_expr_returntype(exp_val);
6909 chk_expr_operandtype_int(tt3, third, opname, v3);
6910 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6911 chk_expr_val_int_pos0(v3, third, opname);
6912 }
6913 chk_expr_operands_substr();
6914 break;
6915 case OPTYPE_REGEXP: {
6916 Type::expected_value_t ti_exp_val = exp_val;
6917 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6918 {
6919 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6920 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6921 if (!governor) return;
6922 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6923 if (valuetype!=V_ERROR) {
6924 u.expr.ti1->get_Template()->chk_specific_value(false);
6925 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6926 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6927 }
6928 }
6929 {
6930 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6931 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6932 if (!governor) return;
6933 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6934 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6935 get_typetype_ttcn3(), second, opname, u.expr.t2);
6936 }
6937 v3=u.expr.v3;
6938 {
6939 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6940 v3->set_lowerid_to_ref();
6941 tt3=v3->get_expr_returntype(exp_val);
6942 chk_expr_operandtype_int(tt3, third, opname, v3);
6943 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6944 chk_expr_val_int_pos0(v3, third, opname);
6945 }
6946 chk_expr_operands_regexp();
6947 } break;
6948 case OPTYPE_ISCHOSEN:
6949 // do nothing: the operand is erroneous
6950 // the error was already reported in chk_expr_ref_ischosen()
6951 break;
6952 case OPTYPE_ISCHOSEN_V: // v1 i2
6953 case OPTYPE_ISCHOSEN_T: // t1 i2
6954 chk_expr_operands_ischosen(refch, exp_val);
6955 break;
6956 case OPTYPE_VALUEOF: { // ti1
6957 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6958 exp_val = Type::EXPECTED_TEMPLATE;
6959 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6960 Type *governor = my_governor;
6961 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6962 if (!governor) return;
6963 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6964 if (valuetype == V_ERROR) return;
6965 u.expr.ti1->get_Template()->chk_specific_value(false);
6966 break; }
6967 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
6968 case OPTYPE_ISBOUND: {
6969 Template *templ = u.expr.ti1->get_Template();
6970 switch (templ->get_templatetype()) {
6971 case Template::TEMPLATE_REFD:
6972 templ->get_reference()->setUsedInIsbound();
6973 break;
6974 case Template::SPECIFIC_VALUE: {
6975 Value *value = templ->get_specific_value();
6976 if (Value::V_REFD == value->get_valuetype()) {
6977 value->get_reference()->setUsedInIsbound();
6978 }
6979 break; }
6980 default:
6981 break;
6982 }
6983 }
6984 // no break
6985 case OPTYPE_ISVALUE: {// ti1
6986 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
6987 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
6988 exp_val = Type::EXPECTED_TEMPLATE;
6989 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6990 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
6991 if (!governor) return;
6992 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
6993 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
6994 break; }
6995 case OPTYPE_SIZEOF: // ti1
6996 /* this checking is too complex, do the checking during eval... */
6997 break;
6998 case OPTYPE_LENGTHOF: { // ti1
6999 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7000 exp_val = Type::EXPECTED_TEMPLATE;
7001 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7002 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7003 if (!governor) return;
7004 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
7005 if (valuetype == V_ERROR) return;
7006 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7007 break; }
7008 case OPTYPE_MATCH: // v1 t2
7009 chk_expr_operands_match(exp_val);
7010 break;
7011 case OPTYPE_UNDEF_RUNNING: // r1
7012 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
7013 break;
7014 case OPTYPE_COMP_ALIVE:
7015 case OPTYPE_COMP_RUNNING: //v1
7016 chk_expr_operand_compref(u.expr.v1, the, opname);
7017 chk_expr_dynamic_part(exp_val, false);
7018 break;
7019 case OPTYPE_TMR_READ: // r1
7020 case OPTYPE_TMR_RUNNING: // r1
7021 chk_expr_operand_tmrref(u.expr.r1, the, opname);
7022 chk_expr_dynamic_part(exp_val, true);
7023 break;
7024 case OPTYPE_EXECUTE: // r1 [v2] // testcase
7025 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
7026 chk_expr_dynamic_part(exp_val, true, false, false);
7027 break;
7028 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7029 chk_expr_operand_comptyperef_create();
7030 v2=u.expr.v2;
7031 if(v2) {
7032 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7033 v2->set_lowerid_to_ref();
7034 tt2=v2->get_expr_returntype(exp_val);
7035 chk_expr_operandtype_cstr(tt2, first, opname, v2);
7036 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7037 }
7038 v3=u.expr.v3;
7039 if(v3) {
7040 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
7041 v3->set_lowerid_to_ref();
7042 tt3=v3->get_expr_returntype(exp_val);
7043 chk_expr_operandtype_cstr(tt3, second, opname, v3);
7044 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7045 }
7046 chk_expr_dynamic_part(exp_val, false);
7047 break;
7048 case OPTYPE_ACTIVATE: // r1 // altstep
7049 chk_expr_operand_activate(u.expr.r1, the, opname);
7050 chk_expr_dynamic_part(exp_val, true);
7051 break;
7052 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
7053 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7054 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
7055 opname);
7056 delete u.expr.t_list2;
7057 u.expr.ap_list2 = parlist;
7058 chk_expr_dynamic_part(exp_val, true);
7059 break; }
7060 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
7061 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7062 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
7063 u.expr.v3, the, opname);
7064 delete u.expr.t_list2;
7065 u.expr.ap_list2 = parlist;
7066 chk_expr_dynamic_part(exp_val, true);
7067 break; }
7068 case OPTYPE_DECOMP:
7069 error("Built-in function `%s' is not yet supported", opname);
7070 set_valuetype(V_ERROR);
7071 break;
7072 case OPTYPE_REPLACE: {
7073 Type::expected_value_t ti_exp_val = exp_val;
7074 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7075 ti_exp_val = Type::EXPECTED_TEMPLATE;
7076 {
7077 Error_Context cntxt(this, "In the first operand of operation `%s'",
7078 opname);
7079 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7080 if (!governor) return;
7081 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7082 if (valuetype != V_ERROR)
7083 u.expr.ti1->get_Template()->chk_specific_value(false);
7084 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
7085 }
7086 v2 = u.expr.v2;
7087 {
7088 Error_Context cntxt(this, "In the second operand of operation `%s'",
7089 opname);
7090 v2->set_lowerid_to_ref();
7091 tt2 = v2->get_expr_returntype(exp_val);
7092 chk_expr_operandtype_int(tt2, second, opname, v2);
7093 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7094 chk_expr_val_int_pos0(v2, second, opname);
7095 }
7096 v3 = u.expr.v3;
7097 {
7098 Error_Context cntxt(this, "In the third operand of operation `%s'",
7099 opname);
7100 v3->set_lowerid_to_ref();
7101 tt3 = v3->get_expr_returntype(exp_val);
7102 chk_expr_operandtype_int(tt3, third, opname, v3);
7103 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7104 chk_expr_val_int_pos0(v3, third, opname);
7105 }
7106 {
7107 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
7108 opname);
7109 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
7110 if (!governor) return;
7111 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
7112 if (valuetype != V_ERROR)
7113 u.expr.ti4->get_Template()->chk_specific_value(false);
7114 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
7115 }
7116 chk_expr_operands_replace();
7117 break; }
7118 case OPTYPE_LOG2STR: {
7119 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7120 u.expr.logargs->chk();
7121 if (!semantic_check_only) u.expr.logargs->join_strings();
7122 break; }
7123 case OPTYPE_TTCN2STRING: {
7124 Error_Context cntxt(this, "In the parameter of ttcn2string()");
7125 Type::expected_value_t ti_exp_val = exp_val;
7126 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
7127 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7128 if (!governor) return;
7129 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7130 } break;
7131 default:
7132 FATAL_ERROR("chk_expr_operands()");
7133 } // switch optype
7134 }
7135
7136 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7137 // the result of evaluating the expression. E.g. V_BOOL for
7138 // OPTYPE_ISCHOSEN.
7139 void Value::evaluate_value(ReferenceChain *refch,
7140 Type::expected_value_t exp_val)
7141 {
7142 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
7143 if(u.expr.state!=EXPR_NOT_CHECKED) return;
7144
7145 u.expr.state=EXPR_CHECKING;
7146
7147 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
7148 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
7149 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
7150
7151 if(valuetype==V_ERROR) return;
7152 if(u.expr.state==EXPR_CHECKING_ERR) {
7153 u.expr.state=EXPR_CHECKED;
7154 set_valuetype(V_ERROR);
7155 return;
7156 }
7157
7158 u.expr.state=EXPR_CHECKED;
7159
7160 Value *v1, *v2, *v3, *v4;
7161 switch(u.expr.v_optype) {
7162 case OPTYPE_RND: // -
7163 case OPTYPE_COMP_NULL: // the only foldable in this group
7164 case OPTYPE_COMP_MTC:
7165 case OPTYPE_COMP_SYSTEM:
7166 case OPTYPE_COMP_SELF:
7167 case OPTYPE_COMP_RUNNING_ANY:
7168 case OPTYPE_COMP_RUNNING_ALL:
7169 case OPTYPE_COMP_ALIVE_ANY:
7170 case OPTYPE_COMP_ALIVE_ALL:
7171 case OPTYPE_TMR_RUNNING_ANY:
7172 case OPTYPE_GETVERDICT:
7173 case OPTYPE_PROF_RUNNING:
7174 case OPTYPE_RNDWITHVAL: // v1
7175 case OPTYPE_COMP_RUNNING: // v1
7176 case OPTYPE_COMP_ALIVE:
7177 case OPTYPE_TMR_READ:
7178 case OPTYPE_TMR_RUNNING:
7179 case OPTYPE_ACTIVATE:
7180 case OPTYPE_ACTIVATE_REFD:
7181 case OPTYPE_EXECUTE: // r1 [v2]
7182 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7183 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7184 case OPTYPE_MATCH: // v1 t2
7185 case OPTYPE_ISCHOSEN_T:
7186 case OPTYPE_LOG2STR:
7187 case OPTYPE_ENCODE:
7188 case OPTYPE_DECODE:
7189 case OPTYPE_ISBOUND:
7190 case OPTYPE_ISPRESENT:
7191 case OPTYPE_TTCN2STRING:
7192 case OPTYPE_UNICHAR2OCT:
7193 case OPTYPE_OCT2UNICHAR:
7194 case OPTYPE_ENCODE_BASE64:
7195 case OPTYPE_DECODE_BASE64:
7196 case OPTYPE_ENCVALUE_UNICHAR:
7197 case OPTYPE_DECVALUE_UNICHAR:
7198 break;
7199 case OPTYPE_TESTCASENAME: { // -
7200 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7201 Ttcn::StatementBlock *my_sb =
7202 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7203 if (!my_sb) break;
7204 Ttcn::Definition *my_def = my_sb->get_my_def();
7205 if (!my_def) { // In control part.
7206 set_val_str(new string(""));
7207 valuetype = V_CSTR;
7208 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7209 set_val_str(new string(my_def->get_id().get_dispname()));
7210 valuetype = V_CSTR;
7211 }
7212 break; }
7213 case OPTYPE_UNARYPLUS: // v1
7214 v1=u.expr.v1;
7215 u.expr.v1=0;
7216 copy_and_destroy(v1);
7217 break;
7218 case OPTYPE_UNARYMINUS:
7219 if (is_unfoldable()) break;
7220 v1 = u.expr.v1->get_value_refd_last();
7221 switch (v1->valuetype) {
7222 case V_INT: {
7223 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7224 if (!i) FATAL_ERROR("Value::evaluate_value()");
7225 clean_up();
7226 valuetype = V_INT;
7227 u.val_Int = i;
7228 break; }
7229 case V_REAL: {
7230 ttcn3float r = v1->get_val_Real();
7231 clean_up();
7232 valuetype = V_REAL;
7233 u.val_Real = -r;
7234 break; }
7235 default:
7236 FATAL_ERROR("Value::evaluate_value()");
7237 }
7238 break;
7239 case OPTYPE_NOT: {
7240 if(is_unfoldable()) break;
7241 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7242 clean_up();
7243 valuetype=V_BOOL;
7244 u.val_bool=!b;
7245 break;}
7246 case OPTYPE_NOT4B: {
7247 if(is_unfoldable()) break;
7248 v1=u.expr.v1->get_value_refd_last();
7249 const string& s = v1->get_val_str();
7250 valuetype_t vt=v1->valuetype;
7251 clean_up();
7252 valuetype=vt;
7253 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7254 break;}
7255 case OPTYPE_BIT2HEX: {
7256 if(is_unfoldable()) break;
7257 v1=u.expr.v1->get_value_refd_last();
7258 const string& s = v1->get_val_str();
7259 clean_up();
7260 valuetype=V_HSTR;
7261 set_val_str(bit2hex(s));
7262 break;}
7263 case OPTYPE_BIT2OCT: {
7264 if(is_unfoldable()) break;
7265 v1=u.expr.v1->get_value_refd_last();
7266 const string& s = v1->get_val_str();
7267 clean_up();
7268 valuetype=V_OSTR;
7269 set_val_str(bit2oct(s));
7270 break;}
7271 case OPTYPE_BIT2STR:
7272 case OPTYPE_HEX2STR:
7273 case OPTYPE_OCT2STR: {
7274 if(is_unfoldable()) break;
7275 v1=u.expr.v1->get_value_refd_last();
7276 const string& s = v1->get_val_str();
7277 clean_up();
7278 valuetype=V_CSTR;
7279 set_val_str(new string(s));
7280 break;}
7281 case OPTYPE_BIT2INT: {
7282 if (is_unfoldable()) break;
7283 v1 = u.expr.v1->get_value_refd_last();
7284 const string& s = v1->get_val_str();
7285 clean_up();
7286 valuetype = V_INT;
7287 u.val_Int = bit2int(s);
7288 break; }
7289 case OPTYPE_CHAR2INT: {
7290 if (is_unfoldable()) break;
7291 v1 = u.expr.v1->get_value_refd_last();
7292 char c = v1->get_val_str()[0];
7293 clean_up();
7294 valuetype = V_INT;
7295 u.val_Int = new int_val_t((Int)c);
7296 break; }
7297 case OPTYPE_CHAR2OCT: {
7298 if(is_unfoldable()) break;
7299 v1=u.expr.v1->get_value_refd_last();
7300 const string& s = v1->get_val_str();
7301 clean_up();
7302 valuetype=V_OSTR;
7303 set_val_str(char2oct(s));
7304 break;}
7305 case OPTYPE_STR2INT: {
7306 if (is_unfoldable()) break;
7307 v1 = u.expr.v1->get_value_refd_last();
7308 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7309 clean_up();
7310 valuetype = V_INT;
7311 u.val_Int = i;
7312 /** \todo hiba eseten lenyeli... */
7313 break; }
7314 case OPTYPE_STR2FLOAT: {
7315 if(is_unfoldable()) break;
7316 v1=u.expr.v1->get_value_refd_last();
7317 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7318 clean_up();
7319 valuetype=V_REAL;
7320 u.val_Real=r;
7321 /** \todo hiba eseten lenyeli... */
7322 break;}
7323 case OPTYPE_STR2BIT: {
7324 if(is_unfoldable()) break;
7325 v1=u.expr.v1->get_value_refd_last();
7326 const string& s = v1->get_val_str();
7327 clean_up();
7328 valuetype=V_BSTR;
7329 set_val_str(new string(s));
7330 break;}
7331 case OPTYPE_STR2HEX:
7332 case OPTYPE_OCT2HEX: {
7333 if(is_unfoldable()) break;
7334 v1=u.expr.v1->get_value_refd_last();
7335 const string& s = v1->get_val_str();
7336 clean_up();
7337 valuetype=V_HSTR;
7338 set_val_str(to_uppercase(s));
7339 break;}
7340 case OPTYPE_STR2OCT: {
7341 if(is_unfoldable()) break;
7342 v1=u.expr.v1->get_value_refd_last();
7343 const string& s = v1->get_val_str();
7344 clean_up();
7345 valuetype=V_OSTR;
7346 set_val_str(to_uppercase(s));
7347 break;}
7348 case OPTYPE_FLOAT2INT: {
7349 if (is_unfoldable()) break;
7350 v1 = u.expr.v1->get_value_refd_last();
7351 ttcn3float r = v1->get_val_Real();
7352 clean_up();
7353 valuetype = V_INT;
7354 u.val_Int = float2int(r, *u.expr.v1);
7355 break;}
7356 case OPTYPE_FLOAT2STR: {
7357 if(is_unfoldable()) break;
7358 v1=u.expr.v1->get_value_refd_last();
7359 ttcn3float r=v1->get_val_Real();
7360 clean_up();
7361 valuetype=V_CSTR;
7362 set_val_str(float2str(r));
7363 break;}
7364 case OPTYPE_HEX2BIT:
7365 case OPTYPE_OCT2BIT: {
7366 if(is_unfoldable()) break;
7367 v1=u.expr.v1->get_value_refd_last();
7368 const string& s = v1->get_val_str();
7369 clean_up();
7370 valuetype=V_BSTR;
7371 set_val_str(hex2bit(s));
7372 break;}
7373 case OPTYPE_HEX2INT:
7374 case OPTYPE_OCT2INT: {
7375 if(is_unfoldable()) break;
7376 v1=u.expr.v1->get_value_refd_last();
7377 const string& s = v1->get_val_str();
7378 clean_up();
7379 valuetype=V_INT;
7380 u.val_Int=hex2int(s);
7381 break;}
7382 case OPTYPE_HEX2OCT: {
7383 if(is_unfoldable()) break;
7384 v1=u.expr.v1->get_value_refd_last();
7385 const string& s = v1->get_val_str();
7386 clean_up();
7387 valuetype=V_OSTR;
7388 set_val_str(hex2oct(s));
7389 break;}
7390 case OPTYPE_INT2CHAR: {
7391 if (is_unfoldable()) break;
7392 v1 = u.expr.v1->get_value_refd_last();
7393 const int_val_t *c_int = v1->get_val_Int();
7394 char c = static_cast<char>(c_int->get_val());
7395 clean_up();
7396 valuetype = V_CSTR;
7397 set_val_str(new string(1, &c));
7398 break; }
7399 case OPTYPE_INT2UNICHAR: {
7400 if (is_unfoldable()) break;
7401 v1 = u.expr.v1->get_value_refd_last();
7402 const int_val_t *i_int = v1->get_val_Int();
7403 Int i = i_int->get_val();
7404 clean_up();
7405 valuetype = V_USTR;
7406 set_val_ustr(int2unichar(i));
7407 u.ustr.convert_str = false;
7408 break; }
7409 case OPTYPE_INT2FLOAT: {
7410 if (is_unfoldable()) break;
7411 v1 = u.expr.v1->get_value_refd_last();
7412 const int_val_t *i_int = v1->get_val_Int();
7413 Real i_int_real = i_int->to_real();
7414 clean_up();
7415 valuetype = V_REAL;
7416 u.val_Real = i_int_real;
7417 break; }
7418 case OPTYPE_INT2STR: {
7419 if (is_unfoldable()) break;
7420 v1 = u.expr.v1->get_value_refd_last();
7421 const int_val_t *i_int = v1->get_val_Int();
7422 string *i_int_str = new string(i_int->t_str());
7423 clean_up();
7424 valuetype = V_CSTR;
7425 set_val_str(i_int_str);
7426 break; }
7427 case OPTYPE_OCT2CHAR: {
7428 if(is_unfoldable()) break;
7429 v1=u.expr.v1->get_value_refd_last();
7430 const string& s = v1->get_val_str();
7431 clean_up();
7432 valuetype=V_CSTR;
7433 set_val_str(oct2char(s));
7434 break;}
7435 case OPTYPE_GET_STRINGENCODING: {
7436 if(is_unfoldable()) break;
7437 v1 = u.expr.v1->get_value_refd_last();
7438 const string& s1 = v1->get_val_str();
7439 clean_up();
7440 valuetype = V_CSTR;
7441 set_val_str(get_stringencoding(s1));
7442 break;}
7443 case OPTYPE_REMOVE_BOM: {
7444 if(is_unfoldable()) break;
7445 v1 = u.expr.v1->get_value_refd_last();
7446 const string& s1 = v1->get_val_str();
7447 clean_up();
7448 valuetype = V_OSTR;
7449 set_val_str(remove_bom(s1));
7450 break;}
7451 case OPTYPE_ENUM2INT: {
7452 if(is_unfoldable()) break;
7453 v1=u.expr.v1->get_value_refd_last();
7454 Type* enum_type = v1->get_my_governor();
7455 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7456 clean_up();
7457 valuetype = V_INT;
7458 u.val_Int = new int_val_t(enum_val);
7459 break;}
7460 case OPTYPE_UNICHAR2INT:
7461 if (is_unfoldable()) {
7462 // replace the operation with char2int() if the operand is a charstring
7463 // value to avoid its unnecessary conversion to universal charstring
7464 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7465 u.expr.v_optype = OPTYPE_CHAR2INT;
7466 } else {
7467 v1=u.expr.v1->get_value_refd_last();
7468 const ustring& s = v1->get_val_ustr();
7469 clean_up();
7470 valuetype=V_INT;
7471 u.val_Int=new int_val_t(unichar2int(s));
7472 }
7473 break;
7474 case OPTYPE_UNICHAR2CHAR:
7475 v1 = u.expr.v1;
7476 if (is_unfoldable()) {
7477 // replace the operation with its operand if it is a charstring
7478 // value to avoid its unnecessary conversion to universal charstring
7479 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7480 u.expr.v1 = 0;
7481 copy_and_destroy(v1);
7482 }
7483 } else {
7484 v1 = v1->get_value_refd_last();
7485 const ustring& s = v1->get_val_ustr();
7486 clean_up();
7487 valuetype = V_CSTR;
7488 set_val_str(new string(s));
7489 }
7490 break;
7491 case OPTYPE_MULTIPLY: { // v1 v2
7492 if (!is_unfoldable()) goto eval_arithmetic;
7493 v1 = u.expr.v1->get_value_refd_last();
7494 v2 = u.expr.v2->get_value_refd_last();
7495 if (v1->is_unfoldable()) v1 = v2;
7496 if (v1->is_unfoldable()) break;
7497 switch(v1->valuetype) {
7498 case V_INT: {
7499 if (*v1->get_val_Int() != 0) break;
7500 clean_up();
7501 valuetype = V_INT;
7502 u.val_Int = new int_val_t((Int)0);
7503 break; }
7504 case V_REAL: {
7505 if (v1->get_val_Real() != 0.0) break;
7506 clean_up();
7507 valuetype = V_REAL;
7508 u.val_Real = 0.0;
7509 break; }
7510 default:
7511 FATAL_ERROR("Value::evaluate_value()");
7512 }
7513 break; }
7514 case OPTYPE_ADD: // v1 v2
7515 case OPTYPE_SUBTRACT:
7516 case OPTYPE_DIVIDE:
7517 case OPTYPE_MOD:
7518 case OPTYPE_REM: {
7519 eval_arithmetic:
7520 if(is_unfoldable()) break;
7521 v1=u.expr.v1->get_value_refd_last();
7522 v2=u.expr.v2->get_value_refd_last();
7523 operationtype_t ot=u.expr.v_optype;
7524 switch (v1->valuetype) {
7525 case V_INT: {
7526 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7527 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7528 clean_up();
7529 valuetype = V_INT;
7530 switch (ot) {
7531 case OPTYPE_ADD:
7532 u.val_Int = new int_val_t(*i1 + *i2);
7533 break;
7534 case OPTYPE_SUBTRACT:
7535 u.val_Int = new int_val_t(*i1 - *i2);
7536 break;
7537 case OPTYPE_MULTIPLY:
7538 u.val_Int = new int_val_t(*i1 * *i2);
7539 break;
7540 case OPTYPE_DIVIDE:
7541 u.val_Int = new int_val_t(*i1 / *i2);
7542 break;
7543 case OPTYPE_MOD:
7544 u.val_Int = new int_val_t(mod(*i1, *i2));
7545 break;
7546 case OPTYPE_REM:
7547 u.val_Int = new int_val_t(rem(*i1, *i2));
7548 break;
7549 default:
7550 FATAL_ERROR("Value::evaluate_value()");
7551 }
7552 delete i1;
7553 delete i2;
7554 break; }
7555 case V_REAL: {
7556 ttcn3float r1=v1->get_val_Real();
7557 ttcn3float r2=v2->get_val_Real();
7558 clean_up();
7559 valuetype=V_REAL;
7560 switch(ot) {
7561 case OPTYPE_ADD:
7562 u.val_Real=r1+r2;
7563 break;
7564 case OPTYPE_SUBTRACT:
7565 u.val_Real=r1-r2;
7566 break;
7567 case OPTYPE_MULTIPLY:
7568 u.val_Real=r1*r2;
7569 break;
7570 case OPTYPE_DIVIDE:
7571 u.val_Real=r1/r2;
7572 break;
7573 default:
7574 FATAL_ERROR("Value::evaluate_value()");
7575 }
7576 break;}
7577 default:
7578 FATAL_ERROR("Value::evaluate_value()");
7579 }
7580 break;}
7581 case OPTYPE_CONCAT: {
7582 if(is_unfoldable()) break;
7583 v1=u.expr.v1->get_value_refd_last();
7584 v2=u.expr.v2->get_value_refd_last();
7585 valuetype_t vt = v1->valuetype;
7586 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7587 const ustring& s1 = v1->get_val_ustr();
7588 const ustring& s2 = v2->get_val_ustr();
7589 clean_up();
7590 valuetype = V_USTR;
7591 set_val_ustr(new ustring(s1 + s2));
7592 u.ustr.convert_str = false;
7593 } else {
7594 const string& s1 = v1->get_val_str();
7595 const string& s2 = v2->get_val_str();
7596 clean_up();
7597 valuetype = vt;
7598 set_val_str(new string(s1 + s2));
7599 }
7600 break;}
7601 case OPTYPE_EQ: {
7602 if(is_unfoldable()) break;
7603 v1=u.expr.v1->get_value_refd_last();
7604 v2=u.expr.v2->get_value_refd_last();
7605 bool b=*v1==*v2;
7606 clean_up();
7607 valuetype=V_BOOL;
7608 u.val_bool=b;
7609 break;}
7610 case OPTYPE_NE: {
7611 if(is_unfoldable()) break;
7612 v1=u.expr.v1->get_value_refd_last();
7613 v2=u.expr.v2->get_value_refd_last();
7614 bool b=*v1==*v2;
7615 clean_up();
7616 valuetype=V_BOOL;
7617 u.val_bool=!b;
7618 break;}
7619 case OPTYPE_LT: {
7620 if(is_unfoldable()) break;
7621 v1=u.expr.v1->get_value_refd_last();
7622 v2=u.expr.v2->get_value_refd_last();
7623 bool b=*v1<*v2;
7624 clean_up();
7625 valuetype=V_BOOL;
7626 u.val_bool=b;
7627 break;}
7628 case OPTYPE_GT: {
7629 if(is_unfoldable()) break;
7630 v1=u.expr.v1->get_value_refd_last();
7631 v2=u.expr.v2->get_value_refd_last();
7632 bool b=*v2<*v1;
7633 clean_up();
7634 valuetype=V_BOOL;
7635 u.val_bool=b;
7636 break;}
7637 case OPTYPE_GE: {
7638 if(is_unfoldable()) break;
7639 v1=u.expr.v1->get_value_refd_last();
7640 v2=u.expr.v2->get_value_refd_last();
7641 bool b=*v1<*v2;
7642 clean_up();
7643 valuetype=V_BOOL;
7644 u.val_bool=!b;
7645 break;}
7646 case OPTYPE_LE: {
7647 if(is_unfoldable()) break;
7648 v1=u.expr.v1->get_value_refd_last();
7649 v2=u.expr.v2->get_value_refd_last();
7650 bool b=*v2<*v1;
7651 clean_up();
7652 valuetype=V_BOOL;
7653 u.val_bool=!b;
7654 break;}
7655 case OPTYPE_AND:
7656 v1 = u.expr.v1->get_value_refd_last();
7657 if (v1->valuetype == V_BOOL) {
7658 if (v1->get_val_bool()) {
7659 // the left operand is a literal "true"
7660 // substitute the expression with the right operand
7661 v2 = u.expr.v2;
7662 u.expr.v2 = 0;
7663 copy_and_destroy(v2);
7664 } else {
7665 // the left operand is a literal "false"
7666 // the result must be false regardless the right operand
7667 // because of the short circuit evaluation rule
7668 clean_up();
7669 valuetype = V_BOOL;
7670 u.val_bool = false;
7671 }
7672 } else {
7673 // we must keep the left operand because of the potential side effects
7674 // the right operand can only be eliminated if it is a literal "true"
7675 v2 = u.expr.v2->get_value_refd_last();
7676 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7677 v1 = u.expr.v1;
7678 u.expr.v1 = 0;
7679 copy_and_destroy(v1);
7680 }
7681 }
7682 break;
7683 case OPTYPE_OR:
7684 v1 = u.expr.v1->get_value_refd_last();
7685 if (v1->valuetype == V_BOOL) {
7686 if (v1->get_val_bool()) {
7687 // the left operand is a literal "true"
7688 // the result must be true regardless the right operand
7689 // because of the short circuit evaluation rule
7690 clean_up();
7691 valuetype = V_BOOL;
7692 u.val_bool = true;
7693 } else {
7694 // the left operand is a literal "false"
7695 // substitute the expression with the right operand
7696 v2 = u.expr.v2;
7697 u.expr.v2 = 0;
7698 copy_and_destroy(v2);
7699 }
7700 } else {
7701 // we must keep the left operand because of the potential side effects
7702 // the right operand can only be eliminated if it is a literal "false"
7703 v2 = u.expr.v2->get_value_refd_last();
7704 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7705 v1 = u.expr.v1;
7706 u.expr.v1 = 0;
7707 copy_and_destroy(v1);
7708 }
7709 }
7710 break;
7711 case OPTYPE_XOR: {
7712 if(is_unfoldable()) break;
7713 v1=u.expr.v1->get_value_refd_last();
7714 v2=u.expr.v2->get_value_refd_last();
7715 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7716 clean_up();
7717 valuetype=V_BOOL;
7718 u.val_bool=b;
7719 break;}
7720 case OPTYPE_AND4B: {
7721 if(is_unfoldable()) break;
7722 v1=u.expr.v1->get_value_refd_last();
7723 v2=u.expr.v2->get_value_refd_last();
7724 valuetype_t vt=v1->valuetype;
7725 const string& s1 = v1->get_val_str();
7726 const string& s2 = v2->get_val_str();
7727 clean_up();
7728 valuetype=vt;
7729 set_val_str(and4b(s1, s2));
7730 break;}
7731 case OPTYPE_OR4B: {
7732 if(is_unfoldable()) break;
7733 v1=u.expr.v1->get_value_refd_last();
7734 v2=u.expr.v2->get_value_refd_last();
7735 valuetype_t vt=v1->valuetype;
7736 const string& s1 = v1->get_val_str();
7737 const string& s2 = v2->get_val_str();
7738 clean_up();
7739 valuetype=vt;
7740 set_val_str(or4b(s1, s2));
7741 break;}
7742 case OPTYPE_XOR4B: {
7743 if(is_unfoldable()) break;
7744 v1=u.expr.v1->get_value_refd_last();
7745 v2=u.expr.v2->get_value_refd_last();
7746 valuetype_t vt=v1->valuetype;
7747 const string& s1 = v1->get_val_str();
7748 const string& s2 = v2->get_val_str();
7749 clean_up();
7750 valuetype=vt;
7751 set_val_str(xor4b(s1, s2));
7752 break;}
7753 case OPTYPE_SHL: {
7754 if(is_unfoldable()) break;
7755 v1=u.expr.v1->get_value_refd_last();
7756 v2=u.expr.v2->get_value_refd_last();
7757 valuetype_t vt=v1->valuetype;
7758 const string& s = v1->get_val_str();
7759 const int_val_t *i_int = v2->get_val_Int();
7760 Int i=i_int->get_val();
7761 if(vt==V_OSTR) i*=2;
7762 clean_up();
7763 valuetype=vt;
7764 set_val_str(shift_left(s, i));
7765 break;}
7766 case OPTYPE_SHR: {
7767 if(is_unfoldable()) break;
7768 v1=u.expr.v1->get_value_refd_last();
7769 v2=u.expr.v2->get_value_refd_last();
7770 valuetype_t vt=v1->valuetype;
7771 const string& s = v1->get_val_str();
7772 const int_val_t *i_int = v2->get_val_Int();
7773 Int i=i_int->get_val();
7774 if(vt==V_OSTR) i*=2;
7775 clean_up();
7776 valuetype=vt;
7777 set_val_str(shift_right(s, i));
7778 break;}
7779 case OPTYPE_ROTL: {
7780 if(is_unfoldable()) break;
7781 v1=u.expr.v1->get_value_refd_last();
7782 v2=u.expr.v2->get_value_refd_last();
7783 valuetype_t vt=v1->valuetype;
7784 const int_val_t *i_int=v2->get_val_Int();
7785 Int i=i_int->get_val();
7786 if(vt==V_USTR) {
7787 const ustring& s = v1->get_val_ustr();
7788 clean_up();
7789 valuetype=vt;
7790 set_val_ustr(rotate_left(s, i));
7791 u.ustr.convert_str = false;
7792 }
7793 else {
7794 if(vt==V_OSTR) i*=2;
7795 const string& s = v1->get_val_str();
7796 clean_up();
7797 valuetype=vt;
7798 set_val_str(rotate_left(s, i));
7799 }
7800 break;}
7801 case OPTYPE_ROTR: {
7802 if(is_unfoldable()) break;
7803 v1=u.expr.v1->get_value_refd_last();
7804 v2=u.expr.v2->get_value_refd_last();
7805 valuetype_t vt=v1->valuetype;
7806 const int_val_t *i_int=v2->get_val_Int();
7807 Int i=i_int->get_val();
7808 if(vt==V_USTR) {
7809 const ustring& s = v1->get_val_ustr();
7810 clean_up();
7811 valuetype=vt;
7812 set_val_ustr(rotate_right(s, i));
7813 u.ustr.convert_str = false;
7814 }
7815 else {
7816 if(vt==V_OSTR) i*=2;
7817 const string& s = v1->get_val_str();
7818 clean_up();
7819 valuetype=vt;
7820 set_val_str(rotate_right(s, i));
7821 }
7822 break;}
7823 case OPTYPE_INT2BIT: {
7824 if (is_unfoldable()) break;
7825 v1 = u.expr.v1->get_value_refd_last();
7826 v2 = u.expr.v2->get_value_refd_last();
7827 const int_val_t *i1_int = v1->get_val_Int();
7828 const int_val_t *i2_int = v2->get_val_Int();
7829 string *val = int2bit(*i1_int, i2_int->get_val());
7830 clean_up();
7831 valuetype = V_BSTR;
7832 set_val_str(val);
7833 break; }
7834 case OPTYPE_INT2HEX: {
7835 if (is_unfoldable()) break;
7836 v1 = u.expr.v1->get_value_refd_last();
7837 v2 = u.expr.v2->get_value_refd_last();
7838 const int_val_t *i1_int = v1->get_val_Int();
7839 const int_val_t *i2_int = v2->get_val_Int();
7840 // Do it before the `clean_up'. i2_int is already checked.
7841 string *val = int2hex(*i1_int, i2_int->get_val());
7842 clean_up();
7843 valuetype = V_HSTR;
7844 set_val_str(val);
7845 break; }
7846 case OPTYPE_INT2OCT: {
7847 if (is_unfoldable()) break;
7848 v1 = u.expr.v1->get_value_refd_last();
7849 v2 = u.expr.v2->get_value_refd_last();
7850 const int_val_t i1_int(*v1->get_val_Int());
7851 // `v2' is a native integer.
7852 Int i2_int = v2->get_val_Int()->get_val() * 2;
7853 clean_up();
7854 valuetype = V_OSTR;
7855 set_val_str(int2hex(i1_int, i2_int));
7856 break; }
7857 case OPTYPE_SUBSTR: {
7858 if(is_unfoldable()) break;
7859 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7860 v2=u.expr.v2->get_value_refd_last();
7861 v3=u.expr.v3->get_value_refd_last();
7862 valuetype_t vt=v1->valuetype;
7863 const int_val_t *i2_int=v2->get_val_Int();
7864 const int_val_t *i3_int=v3->get_val_Int();
7865 Int i2=i2_int->get_val();
7866 Int i3=i3_int->get_val();
7867 if(vt==V_USTR) {
7868 const ustring& s = v1->get_val_ustr();
7869 clean_up();
7870 valuetype=vt;
7871 set_val_ustr(new ustring(s.substr(i2, i3)));
7872 u.ustr.convert_str = false;
7873 }
7874 else {
7875 if(vt==V_OSTR) {
7876 i2*=2;
7877 i3*=2;
7878 }
7879 const string& s = v1->get_val_str();
7880 clean_up();
7881 valuetype=vt;
7882 set_val_str(new string(s.substr(i2, i3)));
7883 }
7884 break;}
7885 case OPTYPE_REPLACE: {
7886 if(is_unfoldable()) break;
7887 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7888 v2=u.expr.v2->get_value_refd_last();
7889 v3=u.expr.v3->get_value_refd_last();
7890 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7891 valuetype_t vt=v1->valuetype;
7892 const int_val_t *i2_int=v2->get_val_Int();
7893 const int_val_t *i3_int=v3->get_val_Int();
7894 Int i2=i2_int->get_val();
7895 Int i3=i3_int->get_val();
7896 switch(vt) {
7897 case V_BSTR: {
7898 string *s1 = new string(v1->get_val_str());
7899 const string& s2 = v4->get_val_str();
7900 clean_up();
7901 valuetype=vt;
7902 s1->replace(i2, i3, s2);
7903 set_val_str(s1);
7904 break;}
7905 case V_HSTR: {
7906 string *s1 = new string(v1->get_val_str());
7907 const string& s2 = v4->get_val_str();
7908 clean_up();
7909 valuetype=vt;
7910 s1->replace(i2, i3, s2);
7911 set_val_str(s1);
7912 break;}
7913 case V_OSTR: {
7914 i2*=2;
7915 i3*=2;
7916 string *s1 = new string(v1->get_val_str());
7917 const string& s2 = v4->get_val_str();
7918 clean_up();
7919 valuetype=vt;
7920 s1->replace(i2, i3, s2);
7921 set_val_str(s1);
7922 break;}
7923 case V_CSTR: {
7924 string *s1 = new string(v1->get_val_str());
7925 const string& s2 = v4->get_val_str();
7926 clean_up();
7927 valuetype=vt;
7928 s1->replace(i2, i3, s2);
7929 set_val_str(s1);
7930 break;}
7931 case V_USTR: {
7932 ustring *s1 = new ustring(v1->get_val_ustr());
7933 const ustring& s2 = v4->get_val_ustr();
7934 clean_up();
7935 valuetype=vt;
7936 s1->replace(i2, i3, s2);
7937 set_val_ustr(s1);
7938 u.ustr.convert_str = false;
7939 break;}
7940 default:
7941 FATAL_ERROR("Value::evaluate_value()");
7942 }
7943 break; }
7944 case OPTYPE_REGEXP: {
7945 if (is_unfoldable()) break;
7946 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7947 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
7948 v3=u.expr.v3->get_value_refd_last();
7949 const int_val_t *i3_int = v3->get_val_Int();
7950 Int i3 = i3_int->get_val();
7951 if (v1->valuetype == V_CSTR) {
7952 const string& s1 = v1->get_val_str();
7953 const string& s2 = v2->get_val_str();
7954 string *result = regexp(s1, s2, i3);
7955 clean_up();
7956 valuetype = V_CSTR;
7957 set_val_str(result);
7958 } if (v1->valuetype == V_USTR) {
7959 const ustring& s1 = v1->get_val_ustr();
7960 const ustring& s2 = v2->get_val_ustr();
7961 ustring *result = regexp(s1, s2, i3);
7962 clean_up();
7963 valuetype = V_USTR;
7964 set_val_ustr(result);
7965 u.ustr.convert_str = false;
7966 }
7967 break; }
7968 case OPTYPE_LENGTHOF:{
7969 if(is_unfoldable()) break;
7970 v1=u.expr.ti1->get_Template()->get_specific_value()
7971 ->get_value_refd_last();
7972 size_t i;
7973 if(v1->is_string_type(exp_val)) {
7974 i=v1->get_val_strlen();
7975 } else { // v1 is be seq/set of or array
7976 switch (v1->valuetype) {
7977 case V_SEQOF:
7978 case V_SETOF:
7979 case V_ARRAY: {
7980 if(v1->u.val_vs->is_indexed())
7981 { i = v1->u.val_vs->get_nof_ivs();}
7982 else { i = v1->u.val_vs->get_nof_vs();}
7983 break; }
7984 default:
7985 FATAL_ERROR("Value::evaluate_value()");
7986 }
7987 }
7988 clean_up();
7989 valuetype=V_INT;
7990 u.val_Int=new int_val_t(i);
7991 break;}
7992 case OPTYPE_SIZEOF: {
7993 Int i=chk_eval_expr_sizeof(refch, exp_val);
7994 if(i!=-1) {
7995 clean_up();
7996 valuetype=V_INT;
7997 u.val_Int=new int_val_t(i);
7998 }
7999 break;}
8000 case OPTYPE_ISVALUE: {
8001 if(is_unfoldable()) break;
8002 bool is_singleval = !u.expr.ti1->get_DerivedRef()
8003 && u.expr.ti1->get_Template()->is_Value();
8004 if (is_singleval) {
8005 Value * other_val = u.expr.ti1->get_Template()->get_Value();
8006 is_singleval = other_val->evaluate_isvalue(false);
8007 // is_singleval now contains the compile-time result of isvalue
8008 delete other_val;
8009 }
8010 clean_up();
8011 valuetype = V_BOOL;
8012 u.val_bool = is_singleval;
8013 break;}
8014 case OPTYPE_ISCHOSEN_V: {
8015 if (is_unfoldable()) break;
8016 v1 = u.expr.v1->get_value_refd_last();
8017 bool b = v1->field_is_chosen(*u.expr.i2);
8018 clean_up();
8019 valuetype = V_BOOL;
8020 u.val_bool = b;
8021 break; }
8022 case OPTYPE_VALUEOF: // ti1
8023 if (!u.expr.ti1->get_DerivedRef() &&
8024 u.expr.ti1->get_Template()->is_Value() &&
8025 !u.expr.ti1->get_Type()) {
8026 // FIXME actually if the template instance has a type
8027 // it might still be foldable.
8028 // the argument is a single specific value
8029 v1 = u.expr.ti1->get_Template()->get_Value();
8030 Type *governor = my_governor;
8031 if (governor == NULL) {
8032 governor = u.expr.ti1->get_expr_governor(exp_val);
8033 if (governor != NULL) governor = governor->get_type_refd_last();
8034 }
8035 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
8036 if (governor == NULL)
8037 FATAL_ERROR("Value::evaluate_value()");
8038 clean_up();
8039 valuetype = v1->valuetype;
8040 u = v1->u;
8041 set_my_governor(governor);
8042 if (valuetype == V_REFD && u.ref.refd_last == v1)
8043 u.ref.refd_last = this;
8044 v1->valuetype = V_ERROR;
8045 delete v1;
8046 }
8047 break;
8048 case OPTYPE_UNDEF_RUNNING:
8049 default:
8050 FATAL_ERROR("Value::evaluate_value()");
8051 } // switch optype
8052 }
8053
8054 bool Value::evaluate_isvalue(bool from_sequence)
8055 {
8056 switch (valuetype) {
8057 case V_OMIT:
8058 // Omit is not a value unless a member of a sequence or set
8059 return from_sequence;
8060 case V_NOTUSED:
8061 return false;
8062 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8063 case V_BOOL: /**< boolean */
8064 case V_NAMEDINT: /**< integer / named number */
8065 case V_NAMEDBITS: /**< named bits (identifiers) */
8066 case V_INT: /**< integer */
8067 case V_REAL: /**< real/float */
8068 case V_ENUM: /**< enumerated */
8069 case V_BSTR: /**< bitstring */
8070 case V_HSTR: /**< hexstring */
8071 case V_OSTR: /**< octetstring */
8072 case V_CSTR: /**< charstring */
8073 case V_USTR: /**< universal charstring */
8074 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
8075 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
8076 case V_OID: /**< object identifier */
8077 case V_ROID: /**< relative object identifier */
8078 case V_VERDICT: /**< all verdicts */
8079 return true; // values of built-in types return true
8080
8081 // Code below was adapted from is_unfoldable(), false returned early.
8082 case V_CHOICE:
8083 return u.choice.alt_value->evaluate_isvalue(false);
8084
8085 case V_SEQOF:
8086 case V_SETOF:
8087 case V_ARRAY:
8088 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8089 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
8090 return false;
8091 }
8092 }
8093 return true;
8094
8095 case V_SEQ:
8096 case V_SET:
8097 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8098 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
8099 ->evaluate_isvalue(true)) return false;
8100 }
8101 return true;
8102
8103 case V_REFD:
8104 // alas, get_value_refd_last prevents this function from const
8105 return get_value_refd_last()->evaluate_isvalue(false);
8106
8107 case V_EXPR:
8108 switch (u.expr.v_optype) {
8109 // A constant null component reference is a corner case: it is foldable
8110 // but escapes unmodified from evaluate_value.
8111 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8112 // or is transformed into some other valuetype in evaluate_value.
8113 case OPTYPE_COMP_NULL:
8114 return false;
8115 default:
8116 break; // and fall through to the FATAL_ERROR
8117 }
8118 // no break
8119 default:
8120 FATAL_ERROR("Value::evaluate_isvalue()");
8121 break;
8122 }
8123 return true;
8124 }
8125
8126 void Value::evaluate_macro(Type::expected_value_t exp_val)
8127 {
8128 switch (u.macro) {
8129 case MACRO_MODULEID:
8130 if (!my_scope)
8131 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8132 set_val_str(new string(my_scope->get_scope_mod()
8133 ->get_modid().get_dispname()));
8134 valuetype = V_CSTR;
8135 break;
8136 case MACRO_FILENAME:
8137 case MACRO_BFILENAME: {
8138 const char *t_filename = get_filename();
8139 if (!t_filename)
8140 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8141 set_val_str(new string(t_filename));
8142 valuetype = V_CSTR;
8143 break; }
8144 case MACRO_FILEPATH: {
8145 const char *t_filename = get_filename();
8146 if (!t_filename)
8147 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8148 char *t_filepath = canonize_input_file(t_filename);
8149 if (!t_filepath)
8150 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8151 set_val_str(new string(t_filepath));
8152 valuetype = V_CSTR;
8153 Free(t_filepath);
8154 break; }
8155 case MACRO_LINENUMBER: {
8156 int t_lineno = get_first_line();
8157 if (t_lineno <= 0)
8158 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8159 set_val_str(new string(Int2string(t_lineno)));
8160 valuetype = V_CSTR;
8161 break; }
8162 case MACRO_LINENUMBER_C: {
8163 int t_lineno = get_first_line();
8164 if (t_lineno <= 0)
8165 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8166 u.val_Int = new int_val_t(t_lineno);
8167 valuetype = V_INT;
8168 break; }
8169 case MACRO_DEFINITIONID: {
8170 // cut the second part from the fullname separated by dots
8171 const string& t_fullname = get_fullname();
8172 size_t first_char = t_fullname.find('.') + 1;
8173 if (first_char >= t_fullname.size())
8174 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8175 t_fullname.c_str());
8176 set_val_str(new string(t_fullname.substr(first_char,
8177 t_fullname.find('.', first_char) - first_char)));
8178 valuetype = V_CSTR;
8179 break; }
8180 case MACRO_SCOPE: {
8181 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8182 set_val_str(new string(my_scope->get_scopeMacro_name()));
8183 valuetype = V_CSTR;
8184 break;
8185 }
8186 case MACRO_TESTCASEID: {
8187 if (exp_val == Type::EXPECTED_CONSTANT ||
8188 exp_val == Type::EXPECTED_STATIC_VALUE) {
8189 error("A %s value was expected instead of macro `%%testcaseId', "
8190 "which is evaluated at runtime",
8191 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8192 goto error;
8193 }
8194 if (!my_scope)
8195 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8196 Ttcn::StatementBlock *my_sb =
8197 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8198 if (!my_sb) {
8199 error("Usage of macro %%testcaseId is allowed only within the "
8200 "statement blocks of functions, altsteps and testcases");
8201 goto error;
8202 }
8203 Ttcn::Definition *my_def = my_sb->get_my_def();
8204 if (!my_def) {
8205 error("Macro %%testcaseId cannot be used in the control part. "
8206 "It is allowed only within the statement blocks of functions, "
8207 "altsteps and testcases");
8208 goto error;
8209 }
8210 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8211 // folding is possible only within testcases
8212 set_val_str(new string(my_def->get_id().get_dispname()));
8213 valuetype = V_CSTR;
8214 }
8215 break; }
8216 default:
8217 FATAL_ERROR("Value::evaluate_macro()");
8218 }
8219 return;
8220 error:
8221 set_valuetype(V_ERROR);
8222 }
8223
8224 void Value::add_id(Identifier *p_id)
8225 {
8226 switch(valuetype) {
8227 case V_NAMEDBITS:
8228 if(u.ids->has_key(p_id->get_name())) {
8229 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8230 // The Value does not take ownership for the identifier,
8231 // so it must be deleted (add_is acts as a sink).
8232 delete p_id;
8233 }
8234 else u.ids->add(p_id->get_name(), p_id);
8235 break;
8236 default:
8237 FATAL_ERROR("Value::add_id()");
8238 } // switch
8239 }
8240
8241 Value* Value::get_value_refd_last(ReferenceChain *refch,
8242 Type::expected_value_t exp_val)
8243 {
8244 set_lowerid_to_ref();
8245 switch (valuetype) {
8246 case V_INVOKE:
8247 // there might be a better place for this
8248 chk_invoke(exp_val);
8249 return this;
8250 case V_REFD:
8251 // use the cache if available
8252 if (u.ref.refd_last) return u.ref.refd_last;
8253 else {
8254 Assignment *ass = u.ref.ref->get_refd_assignment();
8255 if (!ass) {
8256 // the referred definition is not found
8257 set_valuetype(V_ERROR);
8258 } else {
8259 switch (ass->get_asstype()) {
8260 case Assignment::A_OBJECT:
8261 case Assignment::A_OS: {
8262 // the referred definition is an ASN.1 object or object set
8263 Setting *setting = u.ref.ref->get_refd_setting();
8264 if (!setting || setting->get_st() == S_ERROR) {
8265 // remain silent, the error has been already reported
8266 set_valuetype(V_ERROR);
8267 break;
8268 } else if (setting->get_st() != S_V) {
8269 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8270 " refer to a value", u.ref.ref->get_dispname().c_str());
8271 set_valuetype(V_ERROR);
8272 break;
8273 }
8274 bool destroy_refch;
8275 if (refch) {
8276 refch->mark_state();
8277 destroy_refch = false;
8278 } else {
8279 refch = new ReferenceChain(this,
8280 "While searching referenced value");
8281 destroy_refch = true;
8282 }
8283 if (refch->add(get_fullname())) {
8284 Value *v_refd = dynamic_cast<Value*>(setting);
8285 Value *v_last = v_refd->get_value_refd_last(refch);
8286 // in case of circular recursion the valuetype is already set
8287 // to V_ERROR, so don't set the cache
8288 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8289 } else {
8290 // a circular recursion was detected
8291 set_valuetype(V_ERROR);
8292 }
8293 if (destroy_refch) delete refch;
8294 else refch->prev_state();
8295 break; }
8296 case Assignment::A_CONST: {
8297 // the referred definition is a constant
8298 bool destroy_refch;
8299 if (refch) {
8300 refch->mark_state();
8301 destroy_refch = false;
8302 } else {
8303 refch = new ReferenceChain(this,
8304 "While searching referenced value");
8305 destroy_refch = true;
8306 }
8307 if (refch->add(get_fullname())) {
8308 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8309 Value *v_refd = ass->get_Value()
8310 ->get_refd_sub_value(subrefs, 0,
8311 u.ref.ref->getUsedInIsbound(), refch);
8312 if (v_refd) {
8313 Value *v_last = v_refd->get_value_refd_last(refch);
8314 // in case of circular recursion the valuetype is already set
8315 // to V_ERROR, so don't set the cache
8316 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8317 } else if (subrefs && subrefs->has_unfoldable_index()) {
8318 u.ref.refd_last = this;
8319 } else if (u.ref.ref->getUsedInIsbound()) {
8320 u.ref.refd_last = this;
8321 } else {
8322 // the sub-reference points to a non-existent field
8323 set_valuetype(V_ERROR);
8324 }
8325 } else {
8326 // a circular recursion was detected
8327 set_valuetype(V_ERROR);
8328 }
8329 if (destroy_refch) delete refch;
8330 else refch->prev_state();
8331 break; }
8332 case Assignment::A_EXT_CONST:
8333 case Assignment::A_MODULEPAR:
8334 case Assignment::A_VAR:
8335 case Assignment::A_FUNCTION_RVAL:
8336 case Assignment::A_EXT_FUNCTION_RVAL:
8337 case Assignment::A_PAR_VAL_IN:
8338 case Assignment::A_PAR_VAL_OUT:
8339 case Assignment::A_PAR_VAL_INOUT:
8340 // the referred definition is not a constant
8341 u.ref.refd_last = this;
8342 break;
8343 case Assignment::A_FUNCTION:
8344 case Assignment::A_EXT_FUNCTION:
8345 u.ref.ref->error("Reference to a value was expected instead of a "
8346 "call of %s, which does not have return type",
8347 ass->get_description().c_str());
8348 set_valuetype(V_ERROR);
8349 break;
8350 case Assignment::A_FUNCTION_RTEMP:
8351 case Assignment::A_EXT_FUNCTION_RTEMP:
8352 u.ref.ref->error("Reference to a value was expected instead of a "
8353 "call of %s, which returns a template",
8354 ass->get_description().c_str());
8355 set_valuetype(V_ERROR);
8356 break;
8357 default:
8358 u.ref.ref->error("Reference to a value was expected instead of %s",
8359 ass->get_description().c_str());
8360 set_valuetype(V_ERROR);
8361 } // switch asstype
8362 }
8363 if (valuetype == V_REFD) return u.ref.refd_last;
8364 else return this;
8365 }
8366 case V_EXPR: {
8367 // try to evaluate the expression
8368 bool destroy_refch;
8369 if(refch) {
8370 refch->mark_state();
8371 destroy_refch=false;
8372 }
8373 else {
8374 refch=new ReferenceChain(this, "While evaluating expression");
8375 destroy_refch=true;
8376 }
8377 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8378 else set_valuetype(V_ERROR);
8379 if(destroy_refch) delete refch;
8380 else refch->prev_state();
8381 return this; }
8382 case V_MACRO:
8383 evaluate_macro(exp_val);
8384 // no break
8385 default:
8386 // return this for all other value types
8387 return this;
8388 } // switch
8389 }
8390
8391 map<Value*, void> Value::UnfoldabilityCheck::running;
8392
8393 /* Note that the logic here needs to be in sync with evaluate_value,
8394 * and possibly others, i.e. if evaluate_value is called for a Value
8395 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8396 bool Value::is_unfoldable(ReferenceChain *refch,
8397 Type::expected_value_t exp_val)
8398 {
8399 if (UnfoldabilityCheck::is_running(this)) {
8400 // This function is already running on this value => infinite recursion
8401 return true;
8402 }
8403
8404 UnfoldabilityCheck checker(this);
8405
8406 if (get_needs_conversion()) return true;
8407 switch (valuetype) {
8408 case V_NAMEDINT:
8409 case V_NAMEDBITS:
8410 case V_OPENTYPE:
8411 case V_UNDEF_LOWERID:
8412 case V_UNDEF_BLOCK:
8413 case V_TTCN3_NULL:
8414 case V_REFER:
8415 // these value types are eliminated during semantic analysis
8416 FATAL_ERROR("Value::is_unfoldable()");
8417 case V_ERROR:
8418 case V_INVOKE:
8419 return true;
8420 case V_CHOICE:
8421 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8422 case V_SEQOF:
8423 case V_SETOF:
8424 case V_ARRAY:
8425 if (!is_indexed()) {
8426 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8427 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8428 return true;
8429 }
8430 } else {
8431 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8432 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8433 return true;
8434 }
8435 }
8436 return false;
8437 case V_SEQ:
8438 case V_SET:
8439 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8440 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8441 ->is_unfoldable(refch, exp_val)) return true;
8442 }
8443 return false;
8444 case V_OID:
8445 case V_ROID:
8446 chk();
8447 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8448 if ((*u.oid_comps)[i]->is_variable()) return true;
8449 }
8450 return false;
8451 case V_REFD: {
8452 Value *v_last=get_value_refd_last(refch, exp_val);
8453 if(v_last==this) return true; // there weren't any references to chase
8454 else return v_last->is_unfoldable(refch, exp_val);
8455 }
8456 case V_EXPR:
8457 // classify the unchecked ischosen() operation, if it was not done so far
8458 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8459 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8460 switch (u.expr.v_optype) {
8461 case OPTYPE_RND: // -
8462 case OPTYPE_COMP_MTC:
8463 case OPTYPE_COMP_SYSTEM:
8464 case OPTYPE_COMP_SELF:
8465 case OPTYPE_COMP_RUNNING_ANY:
8466 case OPTYPE_COMP_RUNNING_ALL:
8467 case OPTYPE_COMP_ALIVE_ANY:
8468 case OPTYPE_COMP_ALIVE_ALL:
8469 case OPTYPE_TMR_RUNNING_ANY:
8470 case OPTYPE_GETVERDICT:
8471 case OPTYPE_TESTCASENAME:
8472 case OPTYPE_PROF_RUNNING:
8473 case OPTYPE_RNDWITHVAL: // v1
8474 case OPTYPE_MATCH: // v1 t2
8475 case OPTYPE_UNDEF_RUNNING: // v1
8476 case OPTYPE_COMP_RUNNING:
8477 case OPTYPE_COMP_ALIVE:
8478 case OPTYPE_TMR_READ:
8479 case OPTYPE_TMR_RUNNING:
8480 case OPTYPE_ACTIVATE:
8481 case OPTYPE_ACTIVATE_REFD:
8482 case OPTYPE_EXECUTE: // r1 [v2]
8483 case OPTYPE_EXECUTE_REFD:
8484 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8485 case OPTYPE_ISCHOSEN:
8486 case OPTYPE_ISCHOSEN_T:
8487 case OPTYPE_SIZEOF: // ti1
8488 case OPTYPE_DECODE:
8489 case OPTYPE_ENCODE:
8490 case OPTYPE_OCT2UNICHAR:
8491 case OPTYPE_UNICHAR2OCT:
8492 case OPTYPE_ENCODE_BASE64:
8493 case OPTYPE_DECODE_BASE64:
8494 case OPTYPE_ENCVALUE_UNICHAR:
8495 case OPTYPE_DECVALUE_UNICHAR:
8496 return true;
8497 case OPTYPE_COMP_NULL: // -
8498 return false;
8499 case OPTYPE_UNARYPLUS: // v1
8500 case OPTYPE_UNARYMINUS:
8501 case OPTYPE_NOT:
8502 case OPTYPE_NOT4B:
8503 case OPTYPE_BIT2HEX:
8504 case OPTYPE_BIT2INT:
8505 case OPTYPE_BIT2OCT:
8506 case OPTYPE_BIT2STR:
8507 case OPTYPE_CHAR2INT:
8508 case OPTYPE_CHAR2OCT:
8509 case OPTYPE_FLOAT2INT:
8510 case OPTYPE_FLOAT2STR:
8511 case OPTYPE_HEX2BIT:
8512 case OPTYPE_HEX2INT:
8513 case OPTYPE_HEX2OCT:
8514 case OPTYPE_HEX2STR:
8515 case OPTYPE_INT2CHAR:
8516 case OPTYPE_INT2FLOAT:
8517 case OPTYPE_INT2STR:
8518 case OPTYPE_INT2UNICHAR:
8519 case OPTYPE_OCT2BIT:
8520 case OPTYPE_OCT2CHAR:
8521 case OPTYPE_OCT2HEX:
8522 case OPTYPE_OCT2INT:
8523 case OPTYPE_OCT2STR:
8524 case OPTYPE_STR2BIT:
8525 case OPTYPE_STR2FLOAT:
8526 case OPTYPE_STR2HEX:
8527 case OPTYPE_STR2INT:
8528 case OPTYPE_STR2OCT:
8529 case OPTYPE_UNICHAR2INT:
8530 case OPTYPE_UNICHAR2CHAR:
8531 case OPTYPE_ENUM2INT:
8532 case OPTYPE_GET_STRINGENCODING:
8533 case OPTYPE_REMOVE_BOM:
8534 return u.expr.v1->is_unfoldable(refch, exp_val);
8535 case OPTYPE_ISBOUND: /*{
8536 //TODO once we have the time for it make isbound foldable.
8537 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8538 Template* temp = u.expr.ti1->get_Template();
8539 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8540 Value* specificValue = temp->get_specific_value();
8541 if (specificValue->get_valuetype() == Value::V_REFD) {
8542 //FIXME implement
8543 }
8544
8545 return specificValue->is_unfoldable(refch, exp_val);
8546 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8547 //FIXME implement
8548 }
8549 }*/
8550 return true;
8551 case OPTYPE_ISPRESENT:
8552 // TODO: "if you have motivation"
8553 return true;
8554 case OPTYPE_ISVALUE: // ti1
8555 // fallthrough
8556 case OPTYPE_LENGTHOF: // ti1
8557 return u.expr.ti1->get_DerivedRef() != 0
8558 || u.expr.ti1->get_Template()->get_templatetype()
8559 != Template::SPECIFIC_VALUE
8560 || u.expr.ti1->get_Template()->get_specific_value()
8561 ->is_unfoldable(refch, exp_val);
8562 case OPTYPE_ROTL:
8563 case OPTYPE_ROTR:
8564 case OPTYPE_CONCAT:
8565 if (!u.expr.v1->is_string_type(exp_val)) return true;
8566 // no break
8567 case OPTYPE_ADD: // v1 v2
8568 case OPTYPE_SUBTRACT:
8569 case OPTYPE_MULTIPLY:
8570 case OPTYPE_DIVIDE:
8571 case OPTYPE_MOD:
8572 case OPTYPE_REM:
8573 case OPTYPE_EQ:
8574 case OPTYPE_LT:
8575 case OPTYPE_GT:
8576 case OPTYPE_NE:
8577 case OPTYPE_GE:
8578 case OPTYPE_LE:
8579 case OPTYPE_XOR:
8580 case OPTYPE_AND4B:
8581 case OPTYPE_OR4B:
8582 case OPTYPE_XOR4B:
8583 case OPTYPE_SHL:
8584 case OPTYPE_SHR:
8585 case OPTYPE_INT2BIT:
8586 case OPTYPE_INT2HEX:
8587 case OPTYPE_INT2OCT:
8588 return u.expr.v1->is_unfoldable(refch, exp_val)
8589 || u.expr.v2->is_unfoldable(refch, exp_val);
8590 case OPTYPE_AND: // short-circuit evaluation
8591 return u.expr.v1->is_unfoldable(refch, exp_val)
8592 || (u.expr.v1->get_val_bool() &&
8593 u.expr.v2->is_unfoldable(refch, exp_val));
8594 case OPTYPE_OR: // short-circuit evaluation
8595 return u.expr.v1->is_unfoldable(refch, exp_val)
8596 || (!u.expr.v1->get_val_bool() &&
8597 u.expr.v2->is_unfoldable(refch, exp_val));
8598 case OPTYPE_SUBSTR:
8599 if (!u.expr.ti1->get_specific_value()) return true;
8600 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8601 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8602 || u.expr.v2->is_unfoldable(refch, exp_val)
8603 || u.expr.v3->is_unfoldable(refch, exp_val);
8604 case OPTYPE_REGEXP:
8605 if (!u.expr.ti1->get_specific_value() ||
8606 !u.expr.t2->get_specific_value()) return true;
8607 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8608 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8609 || u.expr.v3->is_unfoldable(refch, exp_val);
8610 case OPTYPE_DECOMP:
8611 return u.expr.v1->is_unfoldable(refch, exp_val)
8612 || u.expr.v2->is_unfoldable(refch, exp_val)
8613 || u.expr.v3->is_unfoldable(refch, exp_val);
8614 case OPTYPE_REPLACE: {
8615 if (!u.expr.ti1->get_specific_value() ||
8616 !u.expr.ti4->get_specific_value()) return true;
8617 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8618 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8619 || u.expr.v2->is_unfoldable(refch, exp_val)
8620 || u.expr.v3->is_unfoldable(refch, exp_val)
8621 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8622 }
8623 case OPTYPE_VALUEOF: // ti1
8624 /* \todo if you have motivation to implement the eval function
8625 for valueof()... */
8626 return true;
8627 case OPTYPE_ISCHOSEN_V:
8628 return u.expr.v1->is_unfoldable(refch, exp_val);
8629 case OPTYPE_LOG2STR:
8630 case OPTYPE_TTCN2STRING:
8631 return true;
8632 default:
8633 FATAL_ERROR("Value::is_unfoldable()");
8634 } // switch
8635 break; // should never get here
8636 case V_MACRO:
8637 switch (u.macro) {
8638 case MACRO_TESTCASEID:
8639 // this is known only at runtime
8640 return true;
8641 default:
8642 return false;
8643 }
8644 default:
8645 // all literal values are foldable
8646 return false;
8647 }
8648 }
8649
8650 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8651 size_t start_i, bool usedInIsbound,
8652 ReferenceChain *refch)
8653 {
8654 if (!subrefs) return this;
8655 Value *v = this;
8656 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8657 if (!v) break;
8658 v = v->get_value_refd_last(refch);
8659 switch(v->valuetype) {
8660 case V_ERROR:
8661 return v;
8662 case V_REFD:
8663 // unfoldable stuff
8664 return this;
8665 default:
8666 break;
8667 } // switch
8668 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8669 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8670 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8671 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8672 }
8673 return v;
8674 }
8675
8676 Value *Value::get_refd_field_value(const Identifier& field_id,
8677 bool usedInIsbound, const Location& loc)
8678 {
8679 if (valuetype == V_OMIT) {
8680 loc.error("Reference to field `%s' of omit value `%s'",
8681 field_id.get_dispname().c_str(), get_fullname().c_str());
8682 return 0;
8683 }
8684 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8685 Type *t = my_governor->get_type_refd_last();
8686 switch (t->get_typetype()) {
8687 case Type::T_ERROR:
8688 // remain silent
8689 return 0;
8690 case Type::T_CHOICE_A:
8691 case Type::T_CHOICE_T:
8692 case Type::T_OPENTYPE:
8693 case Type::T_ANYTYPE:
8694 if (!t->has_comp_withName(field_id)) {
8695 loc.error("Reference to non-existent union field `%s' in type `%s'",
8696 field_id.get_dispname().c_str(), t->get_typename().c_str());
8697 return 0;
8698 } else if (valuetype != V_CHOICE) {
8699 // remain silent, the error is already reported
8700 return 0;
8701 } else if (*u.choice.alt_name == field_id) {
8702 // everything is OK
8703 return u.choice.alt_value;
8704 }else {
8705 if (!usedInIsbound) {
8706 loc.error("Reference to inactive field `%s' in a value of union type "
8707 "`%s'. The active field is `%s'",
8708 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8709 u.choice.alt_name->get_dispname().c_str());
8710 }
8711 return 0;
8712 }
8713 case Type::T_SEQ_A:
8714 case Type::T_SEQ_T:
8715 if (!t->has_comp_withName(field_id)) {
8716 loc.error("Reference to non-existent record field `%s' in type `%s'",
8717 field_id.get_dispname().c_str(), t->get_typename().c_str());
8718 return 0;
8719 } else if (valuetype != V_SEQ) {
8720 // remain silent, the error has been already reported
8721 return 0;
8722 } else break;
8723 case Type::T_SET_A:
8724 case Type::T_SET_T:
8725 if (!t->has_comp_withName(field_id)) {
8726 loc.error("Reference to non-existent set field `%s' in type `%s'",
8727 field_id.get_dispname().c_str(), t->get_typename().c_str());
8728 return 0;
8729 } else if (valuetype != V_SET) {
8730 // remain silent, the error has been already reported
8731 return 0;
8732 } else break;
8733 default:
8734 loc.error("Invalid field reference `%s': type `%s' "
8735 "does not have fields", field_id.get_dispname().c_str(),
8736 t->get_typename().c_str());
8737 return 0;
8738 }
8739 // the common end for record & set types
8740 if (u.val_nvs->has_nv_withName(field_id)) {
8741 // everything is OK
8742 return u.val_nvs->get_nv_byName(field_id)->get_value();
8743 } else if (!is_asn1()) {
8744 if (!usedInIsbound) {
8745 loc.error("Reference to unbound field `%s'",
8746 field_id.get_dispname().c_str());
8747 // this is an error in TTCN-3, which has been already reported
8748 }
8749 return 0;
8750 } else {
8751 CompField *cf = t->get_comp_byName(field_id);
8752 if (cf->get_is_optional()) {
8753 // creating an explicit omit value
8754 Value *v = new Value(V_OMIT);
8755 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8756 v->set_my_scope(get_my_scope());
8757 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8758 return v;
8759 } else if (cf->has_default()) {
8760 // returning the component's default value
8761 return cf->get_defval();
8762 } else {
8763 // this is an error in ASN.1, which has been already reported
8764 return 0;
8765 }
8766 }
8767 }
8768
8769 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8770 ReferenceChain *refch)
8771 {
8772 Value *v_index = array_index->get_value_refd_last(refch);
8773 Int index = 0;
8774 bool index_available = false;
8775 if (!v_index->is_unfoldable()) {
8776 if (v_index->valuetype == V_INT) {
8777 index = v_index->get_val_Int()->get_val();
8778 index_available = true;
8779 } else {
8780 array_index->error("An integer value was expected as index");
8781 }
8782 }
8783 if (valuetype == V_OMIT) {
8784 array_index->error("Accessing an element with index of omit value `%s'",
8785 get_fullname().c_str());
8786 return 0;
8787 }
8788 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8789 Type *t = my_governor->get_type_refd_last();
8790 switch (t->get_typetype()) {
8791 case Type::T_ERROR:
8792 // remain silent
8793 return 0;
8794 case Type::T_SEQOF:
8795 if (index_available) {
8796 if (index < 0) {
8797 array_index->error("A non-negative integer value was expected "
8798 "instead of %s for indexing a value of `record "
8799 "of' type `%s'", Int2string(index).c_str(),
8800 t->get_typename().c_str());
8801 return 0;
8802 }
8803 switch (valuetype) {
8804 case V_SEQOF:
8805 if (!is_indexed()) {
8806 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8807 if (!usedInIsbound) {
8808 array_index->error("Index overflow in a value of `record of' "
8809 "type `%s': the index is %s, but the value "
8810 "has only %lu elements",
8811 t->get_typename().c_str(),
8812 Int2string(index).c_str(),
8813 (unsigned long)u.val_vs->get_nof_vs());
8814 }
8815 return 0;
8816 } else {
8817 Value* temp = u.val_vs->get_v_byIndex(index);
8818 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8819 temp->error("Not used symbol is not allowed in this context");
8820 return u.val_vs->get_v_byIndex(index);
8821 }
8822 } else {
8823 // Search the appropriate constant index.
8824 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8825 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8826 ->get_value_refd_last();
8827 if (iv_index->get_valuetype() != V_INT) continue;
8828 if (iv_index->get_val_Int()->get_val() == index)
8829 return u.val_vs->get_iv_byIndex(i)->get_value();
8830 }
8831 return 0;
8832 }
8833 break;
8834 default:
8835 // remain silent, the error has been already reported
8836 return 0;
8837 }
8838 } else {
8839 // the error has been reported above
8840 return 0;
8841 }
8842 case Type::T_SETOF:
8843 if (index_available) {
8844 if (index < 0) {
8845 array_index->error("A non-negative integer value was expected "
8846 "instead of %s for indexing a value of `set of' type `%s'",
8847 Int2string(index).c_str(), t->get_typename().c_str());
8848 return 0;
8849 }
8850 switch (valuetype) {
8851 case V_SETOF:
8852 if (!is_indexed()) {
8853 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8854 if (!usedInIsbound) {
8855 array_index->error("Index overflow in a value of `set of' type "
8856 "`%s': the index is %s, but the value has "
8857 "only %lu elements",
8858 t->get_typename().c_str(),
8859 Int2string(index).c_str(),
8860 (unsigned long)u.val_vs->get_nof_vs());
8861 }
8862 return 0;
8863 } else {
8864 Value* temp = u.val_vs->get_v_byIndex(index);
8865 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8866 temp->error("Not used symbol is not allowed in this context");
8867 return temp;
8868 }
8869 } else {
8870 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8871 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8872 ->get_value_refd_last();
8873 if (iv_index->get_valuetype() != V_INT) continue;
8874 if (iv_index->get_val_Int()->get_val() == index)
8875 return u.val_vs->get_iv_byIndex(i)->get_value();
8876 }
8877 return 0;
8878 }
8879 break;
8880 default:
8881 // remain silent, the error has been already reported
8882 return 0;
8883 }
8884 } else {
8885 // the error has been reported above
8886 return 0;
8887 }
8888 case Type::T_ARRAY:
8889 if (index_available) {
8890 Ttcn::ArrayDimension *dim = t->get_dimension();
8891 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8892 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8893 // perform the index transformation
8894 index -= dim->get_offset();
8895 if (!is_indexed()) {
8896 // check for index underflow/overflow or too few elements in the
8897 // value
8898 if (index < 0 ||
8899 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8900 return 0;
8901 else return u.val_vs->get_v_byIndex(index);
8902 } else {
8903 if (index < 0) return 0;
8904 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8905 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8906 ->get_value_refd_last();
8907 if (iv_index->get_valuetype() != V_INT) continue;
8908 if (iv_index->get_val_Int()->get_val() == index)
8909 return u.val_vs->get_iv_byIndex(index)->get_value();
8910 }
8911 return 0;
8912 }
8913 } else {
8914 // remain silent, the error has been already reported
8915 return 0;
8916 }
8917 } else {
8918 // the error has been reported above
8919 return 0;
8920 }
8921 case Type::T_BSTR:
8922 case Type::T_BSTR_A:
8923 case Type::T_HSTR:
8924 case Type::T_OSTR:
8925 case Type::T_CSTR:
8926 case Type::T_USTR:
8927 case Type::T_UTF8STRING:
8928 case Type::T_NUMERICSTRING:
8929 case Type::T_PRINTABLESTRING:
8930 case Type::T_TELETEXSTRING:
8931 case Type::T_VIDEOTEXSTRING:
8932 case Type::T_IA5STRING:
8933 case Type::T_GRAPHICSTRING:
8934 case Type::T_VISIBLESTRING:
8935 case Type::T_GENERALSTRING:
8936 case Type::T_UNIVERSALSTRING:
8937 case Type::T_BMPSTRING:
8938 case Type::T_UTCTIME:
8939 case Type::T_GENERALIZEDTIME:
8940 case Type::T_OBJECTDESCRIPTOR:
8941 if (index_available) return get_string_element(index, *array_index);
8942 else return 0;
8943 default:
8944 array_index->error("Invalid array element reference: type `%s' cannot "
8945 "be indexed", t->get_typename().c_str());
8946 return 0;
8947 }
8948 }
8949
8950 Value *Value::get_string_element(const Int& index, const Location& loc)
8951 {
8952 if (index < 0) {
8953 loc.error("A non-negative integer value was expected instead of %s "
8954 "for indexing a string element", Int2string(index).c_str());
8955 return 0;
8956 }
8957 size_t string_length;
8958 switch (valuetype) {
8959 case V_BSTR:
8960 case V_HSTR:
8961 case V_CSTR:
8962 case V_ISO2022STR:
8963 string_length = u.str.val_str->size();
8964 break;
8965 case V_OSTR:
8966 string_length = u.str.val_str->size() / 2;
8967 break;
8968 case V_USTR:
8969 string_length = u.ustr.val_ustr->size();
8970 break;
8971 default:
8972 // remain silent, the error has been already reported
8973 return 0;
8974 }
8975 if (index >= static_cast<Int>(string_length)) {
8976 loc.error("Index overflow when accessing a string element: "
8977 "the index is %s, but the string has only %lu elements",
8978 Int2string(index).c_str(), (unsigned long) string_length);
8979 return 0;
8980 }
8981 switch (valuetype) {
8982 case V_BSTR:
8983 case V_HSTR:
8984 case V_CSTR:
8985 case V_ISO2022STR:
8986 if (u.str.str_elements && u.str.str_elements->has_key(index))
8987 return (*u.str.str_elements)[index];
8988 else {
8989 Value *t_val = new Value(valuetype,
8990 new string(u.str.val_str->substr(index, 1)));
8991 add_string_element(index, t_val, u.str.str_elements);
8992 return t_val;
8993 }
8994 case V_OSTR:
8995 if (u.str.str_elements && u.str.str_elements->has_key(index))
8996 return (*u.str.str_elements)[index];
8997 else {
8998 Value *t_val = new Value(V_OSTR,
8999 new string(u.str.val_str->substr(2 * index, 2)));
9000 add_string_element(index, t_val, u.str.str_elements);
9001 return t_val;
9002 }
9003 case V_USTR:
9004 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
9005 return (*u.ustr.ustr_elements)[index];
9006 else {
9007 Value *t_val = new Value(V_USTR,
9008 new ustring(u.ustr.val_ustr->substr(index, 1)));
9009 add_string_element(index, t_val, u.ustr.ustr_elements);
9010 return t_val;
9011 }
9012 default:
9013 FATAL_ERROR("Value::get_string_element()");
9014 return 0;
9015 }
9016 }
9017
9018 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
9019 Type::expected_value_t exp_val)
9020 {
9021 set_lowerid_to_ref();
9022 Type::typetype_t r_tt = get_expr_returntype(exp_val);
9023 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
9024 if (error_flag)
9025 error("A value or expression of type %s was expected", type_name);
9026 if (valuetype == V_REFD) {
9027 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
9028 t_chk->chk_this_refd_value(this, 0, exp_val);
9029 }
9030 get_value_refd_last(0, exp_val);
9031 if (error_flag) set_valuetype(V_ERROR);
9032 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
9033 }
9034
9035 int Value::is_parsed_infinity()
9036 {
9037 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
9038 return 1;
9039 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
9040 (u.expr.v1->get_valuetype()==V_REAL) &&
9041 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
9042 return -1;
9043 return 0;
9044 }
9045
9046 bool Value::get_val_bool()
9047 {
9048 Value *v;
9049 if (valuetype == V_REFD) v = get_value_refd_last();
9050 else v = this;
9051 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
9052 return v->u.val_bool;
9053 }
9054
9055 int_val_t* Value::get_val_Int()
9056 {
9057 Value *v;
9058 if (valuetype == V_REFD) v = get_value_refd_last();
9059 else v = this;
9060 switch (v->valuetype) {
9061 case V_INT:
9062 break;
9063 case V_UNDEF_LOWERID:
9064 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9065 "`%s'", (*u.val_id).get_dispname().c_str());
9066 default:
9067 FATAL_ERROR("Value::get_val_Int()");
9068 } // switch
9069 return v->u.val_Int;
9070 }
9071
9072 const Identifier* Value::get_val_id()
9073 {
9074 switch(valuetype) {
9075 case V_NAMEDINT:
9076 case V_ENUM:
9077 case V_UNDEF_LOWERID:
9078 return u.val_id;
9079 default:
9080 FATAL_ERROR("Value::get_val_id()");
9081 return 0;
9082 } // switch
9083 }
9084
9085 const ttcn3float& Value::get_val_Real()
9086 {
9087 Value *v;
9088 if (valuetype == V_REFD) v = get_value_refd_last();
9089 else v = this;
9090 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
9091 return v->u.val_Real;
9092 }
9093
9094 string Value::get_val_str()
9095 {
9096 Value *v = get_value_refd_last();
9097 switch (v->valuetype) {
9098 case V_BSTR:
9099 case V_HSTR:
9100 case V_OSTR:
9101 case V_CSTR:
9102 return *v->u.str.val_str;
9103 case V_CHARSYMS:
9104 return v->u.char_syms->get_string();
9105 case V_USTR:
9106 error("Cannot use ISO-10646 string value in string context");
9107 return string();
9108 case V_ISO2022STR:
9109 error("Cannot use ISO-2022 string value in string context");
9110 // no break
9111 case V_ERROR:
9112 return string();
9113 default:
9114 error("Cannot use this value in charstring value context");
9115 return string();
9116 } // switch
9117 }
9118
9119 ustring Value::get_val_ustr()
9120 {
9121 Value *v = get_value_refd_last();
9122 switch (v->valuetype) {
9123 case V_CSTR:
9124 return ustring(*v->u.str.val_str);
9125 case V_USTR:
9126 return *v->u.ustr.val_ustr;
9127 case V_CHARSYMS:
9128 return v->u.char_syms->get_ustring();
9129 case V_ISO2022STR:
9130 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9131 // no break
9132 case V_ERROR:
9133 return ustring();
9134 default:
9135 error("Cannot use this value in ISO-10646 string context");
9136 return ustring();
9137 } // switch
9138 }
9139
9140 string Value::get_val_iso2022str()
9141 {
9142 Value *v = get_value_refd_last();
9143 switch (v->valuetype) {
9144 case V_CSTR:
9145 case V_ISO2022STR:
9146 return *v->u.str.val_str;
9147 case V_CHARSYMS:
9148 return v->u.char_syms->get_iso2022string();
9149 case V_USTR:
9150 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9151 // no break
9152 case V_ERROR:
9153 return string();
9154 default:
9155 error("Cannot use this value in ISO-2022 string context");
9156 return string();
9157 } // switch
9158 }
9159
9160 size_t Value::get_val_strlen()
9161 {
9162 Value *v = get_value_refd_last();
9163 switch (v->valuetype) {
9164 case V_BSTR:
9165 case V_HSTR:
9166 case V_CSTR:
9167 case V_ISO2022STR:
9168 return v->u.str.val_str->size();
9169 case V_OSTR:
9170 return v->u.str.val_str->size()/2;
9171 case V_CHARSYMS:
9172 return v->u.char_syms->get_len();
9173 case V_USTR:
9174 return v->u.ustr.val_ustr->size();
9175 case V_ERROR:
9176 return 0;
9177 default:
9178 error("Cannot use this value in string value context");
9179 return 0;
9180 } // switch
9181 }
9182
9183 Value::verdict_t Value::get_val_verdict()
9184 {
9185 switch(valuetype) {
9186 case V_VERDICT:
9187 return u.verdict;
9188 default:
9189 FATAL_ERROR("Value::get_val_verdict()");
9190 return u.verdict;
9191 } // switch
9192 }
9193
9194 size_t Value::get_nof_comps()
9195 {
9196 switch (valuetype) {
9197 case V_OID:
9198 case V_ROID:
9199 chk();
9200 return u.oid_comps->size();
9201 case V_SEQOF:
9202 case V_SETOF:
9203 case V_ARRAY:
9204 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9205 else return u.val_vs->get_nof_vs();
9206 case V_SEQ:
9207 case V_SET:
9208 return u.val_nvs->get_nof_nvs();
9209 case V_BSTR:
9210 case V_HSTR:
9211 case V_CSTR:
9212 case V_ISO2022STR:
9213 return u.str.val_str->size();
9214 case V_OSTR:
9215 return u.str.val_str->size()/2;
9216 case V_USTR:
9217 return u.ustr.val_ustr->size();
9218 default:
9219 FATAL_ERROR("Value::get_nof_comps()");
9220 return 0;
9221 } // switch
9222 }
9223
9224 bool Value::is_indexed() const
9225 {
9226 switch (valuetype) {
9227 case V_SEQOF:
9228 case V_SETOF:
9229 case V_ARRAY:
9230 // Applicable only for list-types. Assigning a record/SEQUENCE or
9231 // set/SET with indexed notation is not supported.
9232 return u.val_vs->is_indexed();
9233 default:
9234 FATAL_ERROR("Value::is_indexed()");
9235 break;
9236 }
9237 return false;
9238 }
9239
9240 const Identifier& Value::get_alt_name()
9241 {
9242 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9243 return *u.choice.alt_name;
9244 }
9245
9246 Value *Value::get_alt_value()
9247 {
9248 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9249 return u.choice.alt_value;
9250 }
9251
9252 void Value::set_alt_name_to_lowercase()
9253 {
9254 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9255 string new_name = u.choice.alt_name->get_name();
9256 if (isupper(new_name[0])) {
9257 new_name[0] = tolower(new_name[0]);
9258 if (new_name[new_name.size() - 1] == '_') {
9259 // an underscore is inserted at the end of the alternative name if it's
9260 // a basic type's name (since it would conflict with the class generated
9261 // for that type)
9262 // remove the underscore, it won't conflict with anything if its name
9263 // starts with a lowercase letter
9264 new_name.replace(new_name.size() - 1, 1, "");
9265 }
9266 delete u.choice.alt_name;
9267 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9268 }
9269 }
9270
9271 bool Value::has_oid_error()
9272 {
9273 Value *v;
9274 if (valuetype == V_REFD) v = get_value_refd_last();
9275 else v = this;
9276 switch (valuetype) {
9277 case V_OID:
9278 case V_ROID:
9279 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9280 if ((*v->u.oid_comps)[i]->has_error()) return true;
9281 return false;
9282 default:
9283 return true;
9284 }
9285 }
9286
9287 bool Value::get_oid_comps(vector<string>& comps)
9288 {
9289 bool ret_val = true;
9290 Value *v = this;
9291 switch (valuetype) {
9292 case V_REFD:
9293 v = get_value_refd_last();
9294 // no break
9295 case V_OID:
9296 case V_ROID:
9297 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9298 (*v->u.oid_comps)[i]->get_comps(comps);
9299 if ((*v->u.oid_comps)[i]->is_variable()) {
9300 // not all components can be calculated in compile-time
9301 ret_val = false;
9302 }
9303 }
9304 break;
9305 default:
9306 FATAL_ERROR("Value::get_oid_comps()");
9307 }
9308 return ret_val;
9309 }
9310
9311 void Value::add_se_comp(NamedValue* nv) {
9312 switch (valuetype) {
9313 case V_SEQ:
9314 case V_SET:
9315 if (!u.val_nvs)
9316 u.val_nvs = new NamedValues();
9317 u.val_nvs->add_nv(nv);
9318 break;
9319 default:
9320 FATAL_ERROR("Value::add_se_comp()");
9321 }
9322 }
9323
9324 NamedValue* Value::get_se_comp_byIndex(size_t n)
9325 {
9326 switch(valuetype) {
9327 case V_SEQ:
9328 case V_SET:
9329 return u.val_nvs->get_nv_byIndex(n);
9330 default:
9331 FATAL_ERROR("Value::get_se_comp_byIndex()");
9332 return 0;
9333 } // switch
9334 }
9335
9336 Value *Value::get_comp_byIndex(size_t n)
9337 {
9338 switch (valuetype) {
9339 case V_SEQOF:
9340 case V_SETOF:
9341 case V_ARRAY:
9342 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9343 return u.val_vs->get_iv_byIndex(n)->get_value();
9344 default:
9345 FATAL_ERROR("Value::get_comp_byIndex()");
9346 return 0;
9347 } // switch
9348 }
9349
9350 Value *Value::get_index_byIndex(size_t n)
9351 {
9352 switch (valuetype) {
9353 case V_SEQOF:
9354 case V_SETOF:
9355 case V_ARRAY:
9356 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9357 return u.val_vs->get_iv_byIndex(n)->get_index();
9358 default:
9359 FATAL_ERROR("Value::get_index_byIndex()");
9360 return 0;
9361 } // switch
9362 }
9363
9364 bool Value::has_comp_withName(const Identifier& p_name)
9365 {
9366 switch(valuetype) {
9367 case V_SEQ:
9368 case V_SET:
9369 return u.val_nvs->has_nv_withName(p_name);
9370 case V_CHOICE:
9371 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9372 default:
9373 FATAL_ERROR("Value::get_has_comp_withName()");
9374 return false;
9375 } // switch
9376 }
9377
9378 bool Value::field_is_chosen(const Identifier& p_name)
9379 {
9380 Value *v=get_value_refd_last();
9381 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9382 return *v->u.choice.alt_name==p_name;
9383 }
9384
9385 bool Value::field_is_present(const Identifier& p_name)
9386 {
9387 Value *v=get_value_refd_last();
9388 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9389 FATAL_ERROR("Value::field_is_present()");
9390 return v->u.val_nvs->has_nv_withName(p_name)
9391 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9392 ->get_value_refd_last()->valuetype != V_OMIT;
9393 }
9394
9395 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9396 {
9397 switch(valuetype) {
9398 case V_SEQ:
9399 case V_SET:
9400 return u.val_nvs->get_nv_byName(p_name);
9401 default:
9402 FATAL_ERROR("Value::get_se_comp_byName()");
9403 return 0;
9404 } // switch
9405 }
9406
9407 Value* Value::get_comp_value_byName(const Identifier& p_name)
9408 {
9409 switch(valuetype) {
9410 case V_SEQ:
9411 case V_SET:
9412 return u.val_nvs->get_nv_byName(p_name)->get_value();
9413 case V_CHOICE:
9414 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9415 return u.choice.alt_value;
9416 else
9417 return NULL;
9418 default:
9419 FATAL_ERROR("Value::get_se_comp_byName()");
9420 return 0;
9421 } // switch
9422 }
9423
9424 void Value::chk_dupl_id()
9425 {
9426 switch(valuetype) {
9427 case V_SEQ:
9428 case V_SET:
9429 u.val_nvs->chk_dupl_id();
9430 break;
9431 default:
9432 FATAL_ERROR("Value::chk_dupl_id()");
9433 } // switch
9434 }
9435
9436 size_t Value::get_nof_ids() const
9437 {
9438 switch(valuetype) {
9439 case V_NAMEDBITS:
9440 return u.ids->size();
9441 break;
9442 default:
9443 FATAL_ERROR("Value::get_nof_ids()");
9444 return 0;
9445 } // switch
9446 }
9447
9448 Identifier* Value::get_id_byIndex(size_t p_i)
9449 {
9450 switch(valuetype) {
9451 case V_NAMEDBITS:
9452 return u.ids->get_nth_elem(p_i);
9453 break;
9454 default:
9455 FATAL_ERROR("Value::get_id_byIndex()");
9456 return 0;
9457 } // switch
9458 }
9459
9460 bool Value::has_id(const Identifier& p_id)
9461 {
9462 switch(valuetype) {
9463 case V_NAMEDBITS:
9464 return u.ids->has_key(p_id.get_name());
9465 break;
9466 default:
9467 FATAL_ERROR("Value::has_id()");
9468 return false;
9469 } // switch
9470 }
9471
9472 Reference *Value::get_reference() const
9473 {
9474 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9475 return u.ref.ref;
9476 }
9477
9478 Reference *Value::get_refered() const
9479 {
9480 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9481 return u.refered;
9482 }
9483
9484 Common::Assignment *Value::get_refd_fat() const
9485 {
9486 switch(valuetype){
9487 case V_FUNCTION:
9488 case V_ALTSTEP:
9489 case V_TESTCASE:
9490 return u.refd_fat;
9491 default:
9492 FATAL_ERROR("Value::get_refd_fat()");
9493 }
9494 }
9495
9496 Ttcn::Reference* Value::steal_ttcn_ref()
9497 {
9498 Ttcn::Reference *ret_val =
9499 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9500 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9501 return ret_val;
9502 }
9503
9504 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9505 {
9506 Ttcn::Ref_base *t_ref;
9507 if(valuetype==V_REFD) {
9508 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9509 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9510 u.ref.ref=0;
9511 }
9512 else if(valuetype==V_UNDEF_LOWERID) {
9513 t_ref=new Ttcn::Reference(u.val_id);
9514 t_ref->set_location(*this);
9515 t_ref->set_fullname(get_fullname());
9516 t_ref->set_my_scope(get_my_scope());
9517 u.val_id=0;
9518 }
9519 else {
9520 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9521 t_ref = 0;
9522 }
9523 set_valuetype(V_ERROR);
9524 return t_ref;
9525 }
9526
9527 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9528 Ttcn::ActualParList*& p_ap)
9529 {
9530 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9531 p_v = u.invoke.v;
9532 u.invoke.v = 0;
9533 p_ti = u.invoke.t_list;
9534 u.invoke.t_list = 0;
9535 p_ap = u.invoke.ap_list;
9536 u.invoke.ap_list = 0;
9537 set_valuetype(V_ERROR);
9538 }
9539
9540 Common::Assignment* Value::get_refd_assignment()
9541 {
9542 switch(valuetype) {
9543 case V_FUNCTION:
9544 case V_ALTSTEP:
9545 case V_TESTCASE:
9546 return u.refd_fat;
9547 break;
9548 default:
9549 FATAL_ERROR("Value::get_refd_assignment()");
9550 return 0;
9551 }
9552 }
9553
9554 void Value::chk()
9555 {
9556 if(checked) return;
9557 switch(valuetype) {
9558 case V_OID: {
9559 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9560 " components");
9561 chk_OID(refch);
9562 break; }
9563 case V_ROID: {
9564 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9565 chk_ROID(refch);
9566 break; }
9567 default:
9568 break;
9569 } // switch
9570 checked=true;
9571 }
9572
9573 void Value::chk_OID(ReferenceChain& refch)
9574 {
9575 if (checked) return;
9576 if (valuetype != V_OID || u.oid_comps->size() < 1)
9577 FATAL_ERROR("Value::chk_OID()");
9578 if (!refch.add(get_fullname())) {
9579 checked = true;
9580 return;
9581 }
9582 OID_comp::oidstate_t state = OID_comp::START;
9583 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9584 refch.mark_state();
9585 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9586 refch.prev_state();
9587 }
9588 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9589 error("An OBJECT IDENTIFIER value must have at least "
9590 "two components"); // X.680 (07/2002) 31.10
9591 }
9592
9593 void Value::chk_ROID(ReferenceChain& refch)
9594 {
9595 if (checked) return;
9596 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9597 FATAL_ERROR("Value::chk_ROID()");
9598 if (!refch.add(get_fullname())) {
9599 checked = true;
9600 return;
9601 }
9602 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9603 refch.mark_state();
9604 (*u.oid_comps)[i]->chk_ROID(refch, i);
9605 refch.prev_state();
9606 }
9607 }
9608
9609 void Value::chk_recursions(ReferenceChain& refch)
9610 {
9611 if (recurs_checked) return;
9612 Value *v = get_value_refd_last();
9613 if (refch.add(v->get_fullname())) {
9614 switch (v->valuetype) {
9615 case V_CHOICE:
9616 v->u.choice.alt_value->chk_recursions(refch);
9617 break;
9618 case V_SEQOF:
9619 case V_SETOF:
9620 case V_ARRAY:
9621 if (!v->is_indexed()) {
9622 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9623 refch.mark_state();
9624 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9625 refch.prev_state();
9626 }
9627 } else {
9628 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9629 refch.mark_state();
9630 v->u.val_vs->get_iv_byIndex(i)->get_value()
9631 ->chk_recursions(refch);
9632 refch.prev_state();
9633 }
9634 }
9635 break;
9636 case V_SEQ:
9637 case V_SET:
9638 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9639 refch.mark_state();
9640 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9641 refch.prev_state();
9642 }
9643 break;
9644 case V_EXPR:
9645 chk_recursions_expr(refch);
9646 break;
9647 default:
9648 break;
9649 }
9650 if (v->err_descr) { // FIXME: make this work
9651 v->err_descr->chk_recursions(refch);
9652 }
9653 }
9654 recurs_checked = true;
9655 }
9656
9657 void Value::chk_recursions_expr(ReferenceChain& refch)
9658 {
9659 // first classify the unchecked ischosen() operation
9660 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9661 switch (u.expr.v_optype) {
9662 case OPTYPE_UNARYPLUS: // v1
9663 case OPTYPE_UNARYMINUS:
9664 case OPTYPE_NOT:
9665 case OPTYPE_NOT4B:
9666 case OPTYPE_BIT2HEX:
9667 case OPTYPE_BIT2INT:
9668 case OPTYPE_BIT2OCT:
9669 case OPTYPE_BIT2STR:
9670 case OPTYPE_CHAR2INT:
9671 case OPTYPE_CHAR2OCT:
9672 case OPTYPE_FLOAT2INT:
9673 case OPTYPE_FLOAT2STR:
9674 case OPTYPE_HEX2BIT:
9675 case OPTYPE_HEX2INT:
9676 case OPTYPE_HEX2OCT:
9677 case OPTYPE_HEX2STR:
9678 case OPTYPE_INT2CHAR:
9679 case OPTYPE_INT2FLOAT:
9680 case OPTYPE_INT2STR:
9681 case OPTYPE_INT2UNICHAR:
9682 case OPTYPE_OCT2BIT:
9683 case OPTYPE_OCT2CHAR:
9684 case OPTYPE_OCT2HEX:
9685 case OPTYPE_OCT2INT:
9686 case OPTYPE_OCT2STR:
9687 case OPTYPE_STR2BIT:
9688 case OPTYPE_STR2FLOAT:
9689 case OPTYPE_STR2HEX:
9690 case OPTYPE_STR2INT:
9691 case OPTYPE_STR2OCT:
9692 case OPTYPE_UNICHAR2INT:
9693 case OPTYPE_ENUM2INT:
9694 case OPTYPE_UNICHAR2CHAR:
9695 case OPTYPE_RNDWITHVAL:
9696 case OPTYPE_ISCHOSEN_V:
9697 case OPTYPE_GET_STRINGENCODING:
9698 case OPTYPE_REMOVE_BOM:
9699 case OPTYPE_DECODE_BASE64:
9700 refch.mark_state();
9701 u.expr.v1->chk_recursions(refch);
9702 refch.prev_state();
9703 break;
9704 case OPTYPE_ISCHOSEN_T:
9705 refch.mark_state();
9706 u.expr.t1->chk_recursions(refch);
9707 refch.prev_state();
9708 break;
9709 case OPTYPE_ADD: // v1 v2
9710 case OPTYPE_SUBTRACT:
9711 case OPTYPE_MULTIPLY:
9712 case OPTYPE_DIVIDE:
9713 case OPTYPE_MOD:
9714 case OPTYPE_REM:
9715 case OPTYPE_CONCAT:
9716 case OPTYPE_EQ:
9717 case OPTYPE_LT:
9718 case OPTYPE_GT:
9719 case OPTYPE_NE:
9720 case OPTYPE_GE:
9721 case OPTYPE_LE:
9722 case OPTYPE_AND:
9723 case OPTYPE_OR:
9724 case OPTYPE_XOR:
9725 case OPTYPE_AND4B:
9726 case OPTYPE_OR4B:
9727 case OPTYPE_XOR4B:
9728 case OPTYPE_SHL:
9729 case OPTYPE_SHR:
9730 case OPTYPE_ROTL:
9731 case OPTYPE_ROTR:
9732 case OPTYPE_INT2BIT:
9733 case OPTYPE_INT2HEX:
9734 case OPTYPE_INT2OCT:
9735 refch.mark_state();
9736 u.expr.v1->chk_recursions(refch);
9737 refch.prev_state();
9738 refch.mark_state();
9739 u.expr.v2->chk_recursions(refch);
9740 refch.prev_state();
9741 break;
9742 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9743 case OPTYPE_OCT2UNICHAR:
9744 case OPTYPE_ENCODE_BASE64:
9745 refch.mark_state();
9746 u.expr.v1->chk_recursions(refch);
9747 refch.prev_state();
9748 if (u.expr.v2) {
9749 refch.mark_state();
9750 u.expr.v2->chk_recursions(refch);
9751 refch.prev_state();
9752 }
9753 break;
9754 case OPTYPE_DECODE:
9755 chk_recursions_expr_decode(u.expr.r1, refch);
9756 chk_recursions_expr_decode(u.expr.r2, refch);
9757 break;
9758 case OPTYPE_SUBSTR:
9759 refch.mark_state();
9760 u.expr.ti1->chk_recursions(refch);
9761 refch.prev_state();
9762 refch.mark_state();
9763 u.expr.v2->chk_recursions(refch);
9764 refch.prev_state();
9765 refch.mark_state();
9766 u.expr.v3->chk_recursions(refch);
9767 refch.prev_state();
9768 break;
9769 case OPTYPE_REGEXP:
9770 refch.mark_state();
9771 u.expr.ti1->chk_recursions(refch);
9772 refch.prev_state();
9773 refch.mark_state();
9774 u.expr.t2->chk_recursions(refch);
9775 refch.prev_state();
9776 refch.mark_state();
9777 u.expr.v3->chk_recursions(refch);
9778 refch.prev_state();
9779 break;
9780 case OPTYPE_DECOMP: // v1 v2 v3
9781 refch.mark_state();
9782 u.expr.v1->chk_recursions(refch);
9783 refch.prev_state();
9784 refch.mark_state();
9785 u.expr.v2->chk_recursions(refch);
9786 refch.prev_state();
9787 refch.mark_state();
9788 u.expr.v3->chk_recursions(refch);
9789 refch.prev_state();
9790 break;
9791 case OPTYPE_REPLACE:
9792 refch.mark_state();
9793 u.expr.ti1->chk_recursions(refch);
9794 refch.prev_state();
9795 refch.mark_state();
9796 u.expr.v2->chk_recursions(refch);
9797 refch.prev_state();
9798 refch.mark_state();
9799 u.expr.v3->chk_recursions(refch);
9800 refch.prev_state();
9801 refch.mark_state();
9802 u.expr.ti4->chk_recursions(refch);
9803 refch.prev_state();
9804 break;
9805 case OPTYPE_LENGTHOF: // ti1
9806 case OPTYPE_SIZEOF: // ti1
9807 case OPTYPE_VALUEOF: // ti1
9808 case OPTYPE_ENCODE:
9809 case OPTYPE_ISPRESENT:
9810 case OPTYPE_TTCN2STRING:
9811 refch.mark_state();
9812 u.expr.ti1->chk_recursions(refch);
9813 refch.prev_state();
9814 break;
9815 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
9816 refch.mark_state();
9817 u.expr.ti1->chk_recursions(refch);
9818 refch.prev_state();
9819 if (u.expr.v2){
9820 refch.mark_state();
9821 u.expr.v2->chk_recursions(refch);
9822 refch.prev_state();
9823 }
9824 break;
9825 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
9826 chk_recursions_expr_decode(u.expr.r1, refch);
9827 chk_recursions_expr_decode(u.expr.r2, refch);
9828 if (u.expr.v3){
9829 refch.mark_state();
9830 u.expr.v3->chk_recursions(refch);
9831 refch.prev_state();
9832 }
9833 break;
9834 case OPTYPE_MATCH: // v1 t2
9835 refch.mark_state();
9836 u.expr.v1->chk_recursions(refch);
9837 refch.prev_state();
9838 refch.mark_state();
9839 u.expr.t2->chk_recursions(refch);
9840 refch.prev_state();
9841 break;
9842 case OPTYPE_LOG2STR:
9843 u.expr.logargs->chk_recursions(refch);
9844 break;
9845 default:
9846 break;
9847 } // switch
9848 }
9849
9850 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9851 ReferenceChain& refch) {
9852 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9853 Assignment *ass = ref->get_refd_assignment();
9854 if (!ass) {
9855 set_valuetype(V_ERROR);
9856 return;
9857 }
9858 switch (ass->get_asstype()) {
9859 case Assignment::A_CONST:
9860 case Assignment::A_EXT_CONST:
9861 case Assignment::A_MODULEPAR:
9862 case Assignment::A_VAR:
9863 case Assignment::A_PAR_VAL_IN:
9864 case Assignment::A_PAR_VAL_OUT:
9865 case Assignment::A_PAR_VAL_INOUT: {
9866 Value* v = new Value(V_REFD, ref);
9867 v->set_location(*ref);
9868 v->set_my_scope(get_my_scope());
9869 v->set_fullname(get_fullname()+".<operand>");
9870 refch.mark_state();
9871 v->chk_recursions(refch);
9872 refch.prev_state();
9873 delete v;
9874 break; }
9875 case Assignment::A_MODULEPAR_TEMP:
9876 case Assignment::A_TEMPLATE:
9877 case Assignment::A_VAR_TEMPLATE:
9878 case Assignment::A_PAR_TEMPL_IN:
9879 case Assignment::A_PAR_TEMPL_OUT:
9880 case Assignment::A_PAR_TEMPL_INOUT: {
9881 Template* t = new Template(ref->clone());
9882 t->set_location(*ref);
9883 t->set_my_scope(get_my_scope());
9884 t->set_fullname(get_fullname()+".<operand>");
9885 refch.mark_state();
9886 t->chk_recursions(refch);
9887 refch.prev_state();
9888 delete t;
9889 break; }
9890 default:
9891 // remain silent, the error has been already reported
9892 set_valuetype(V_ERROR);
9893 break;
9894 } // switch
9895 }
9896
9897 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9898 {
9899 bool self_ref = false;
9900 switch (t->get_templatetype()) {
9901 case Ttcn::Template::SPECIFIC_VALUE: {
9902 Value *v = t->get_specific_value();
9903 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9904 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9905 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9906 break; }
9907 case Ttcn::Template::TEMPLATE_REFD: {
9908 Ttcn::Ref_base *refb = t->get_reference();
9909 Common::Assignment *ass = refb->get_refd_assignment();
9910 self_ref |= (ass == lhs);
9911 break; }
9912 case Ttcn::Template::ALL_FROM:
9913 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9914 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9915 break;
9916 case Ttcn::Template::TEMPLATE_LIST:
9917 case Ttcn::Template::SUPERSET_MATCH:
9918 case Ttcn::Template::SUBSET_MATCH:
9919 case Ttcn::Template::PERMUTATION_MATCH:
9920 case Ttcn::Template::COMPLEMENTED_LIST:
9921 case Ttcn::Template::VALUE_LIST: {
9922 size_t num = t->get_nof_comps();
9923 for (size_t i = 0; i < num; ++i) {
9924 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
9925 }
9926 break; }
9927 // not yet clear whether we should use this or the above for TEMPLATE_LIST
9928 // case Ttcn::Template::TEMPLATE_LIST: {
9929 // size_t num = t->get_nof_listitems();
9930 // for (size_t i=0; i < num; ++i) {
9931 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
9932 // }
9933 // break; }
9934 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
9935 size_t nnt = t->get_nof_comps();
9936 for (size_t i=0; i < nnt; ++i) {
9937 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
9938 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
9939 }
9940 break; }
9941 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
9942 size_t nnt = t->get_nof_comps();
9943 for (size_t i=0; i < nnt; ++i) {
9944 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
9945 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
9946 }
9947 break; }
9948 case Ttcn::Template::VALUE_RANGE: {
9949 Ttcn::ValueRange *vr = t->get_value_range();
9950 Common::Value *v = vr->get_min_v();
9951 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9952 v = vr->get_max_v();
9953 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
9954 break; }
9955 case Ttcn::Template::CSTR_PATTERN:
9956 case Ttcn::Template::USTR_PATTERN: {
9957 Ttcn::PatternString *ps = t->get_cstr_pattern();
9958 self_ref |= ps->chk_self_ref(lhs);
9959 break; }
9960 case Ttcn::Template::BSTR_PATTERN:
9961 case Ttcn::Template::HSTR_PATTERN:
9962 case Ttcn::Template::OSTR_PATTERN: {
9963 // FIXME: cannot access u.pattern
9964 break; }
9965 case Ttcn::Template::ANY_VALUE:
9966 case Ttcn::Template::ANY_OR_OMIT:
9967 case Ttcn::Template::OMIT_VALUE:
9968 case Ttcn::Template::TEMPLATE_NOTUSED:
9969 break; // self-ref can't happen
9970 case Ttcn::Template::TEMPLATE_INVOKE:
9971 break; // assume self-ref can't happen
9972 case Ttcn::Template::TEMPLATE_ERROR:
9973 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
9974 break;
9975 // default:
9976 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
9977 // break; // and hope for the best
9978 }
9979 return self_ref;
9980 }
9981
9982 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
9983 {
9984 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
9985 namedbool is_str_elem = NOT_STR_ELEM;
9986 if (v->valuetype == V_REFD) {
9987 Reference *ref = v->get_reference();
9988 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
9989 if (subrefs && subrefs->refers_to_string_element()) {
9990 is_str_elem = IS_STR_ELEM;
9991 }
9992 }
9993 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9994 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
9995 is_str_elem);
9996 }
9997
9998 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
9999 {
10000 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
10001 if (!lhs) FATAL_ERROR("no lhs!");
10002 bool self_ref = false;
10003 switch (u.expr.v_optype) {
10004 case OPTYPE_RND: // -
10005 case OPTYPE_TESTCASENAME: // -
10006 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
10007 case OPTYPE_COMP_MTC: // -
10008 case OPTYPE_COMP_SYSTEM: // -
10009 case OPTYPE_COMP_SELF: // -
10010 case OPTYPE_COMP_RUNNING_ANY: // -
10011 case OPTYPE_COMP_RUNNING_ALL: // -
10012 case OPTYPE_COMP_ALIVE_ANY: // -
10013 case OPTYPE_COMP_ALIVE_ALL: // -
10014 case OPTYPE_TMR_RUNNING_ANY: // -
10015 case OPTYPE_GETVERDICT: // -
10016 case OPTYPE_PROF_RUNNING: // -
10017 break; // nothing to do
10018
10019 case OPTYPE_MATCH: // v1 t2
10020 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
10021 // no break
10022 case OPTYPE_UNARYPLUS: // v1
10023 case OPTYPE_UNARYMINUS: // v1
10024 case OPTYPE_NOT: // v1
10025 case OPTYPE_NOT4B: // v1
10026 case OPTYPE_BIT2HEX: // v1
10027 case OPTYPE_BIT2INT: // v1
10028 case OPTYPE_BIT2OCT: // v1
10029 case OPTYPE_BIT2STR: // v1
10030 case OPTYPE_CHAR2INT: // v1
10031 case OPTYPE_CHAR2OCT: // v1
10032 case OPTYPE_FLOAT2INT: // v1
10033 case OPTYPE_FLOAT2STR: // v1
10034 case OPTYPE_HEX2BIT: // v1
10035 case OPTYPE_HEX2INT: // v1
10036 case OPTYPE_HEX2OCT: // v1
10037 case OPTYPE_HEX2STR: // v1
10038 case OPTYPE_INT2CHAR: // v1
10039 case OPTYPE_INT2FLOAT: // v1
10040 case OPTYPE_INT2STR: // v1
10041 case OPTYPE_INT2UNICHAR: // v1
10042 case OPTYPE_OCT2BIT: // v1
10043 case OPTYPE_OCT2CHAR: // v1
10044 case OPTYPE_OCT2HEX: // v1
10045 case OPTYPE_OCT2INT: // v1
10046 case OPTYPE_OCT2STR: // v1
10047 case OPTYPE_STR2BIT: // v1
10048 case OPTYPE_STR2FLOAT: // v1
10049 case OPTYPE_STR2HEX: // v1
10050 case OPTYPE_STR2INT: // v1
10051 case OPTYPE_STR2OCT: // v1
10052 case OPTYPE_UNICHAR2INT: // v1
10053 case OPTYPE_UNICHAR2CHAR: // v1
10054 case OPTYPE_ENUM2INT: // v1
10055 case OPTYPE_RNDWITHVAL: // v1
10056 case OPTYPE_COMP_RUNNING: // v1
10057 case OPTYPE_COMP_ALIVE: // v1
10058 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
10059 case OPTYPE_GET_STRINGENCODING:
10060 case OPTYPE_DECODE_BASE64:
10061 case OPTYPE_REMOVE_BOM:
10062 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10063 break;
10064 case OPTYPE_ADD: // v1 v2
10065 case OPTYPE_SUBTRACT: // v1 v2
10066 case OPTYPE_MULTIPLY: // v1 v2
10067 case OPTYPE_DIVIDE: // v1 v2
10068 case OPTYPE_MOD: // v1 v2
10069 case OPTYPE_REM: // v1 v2
10070 case OPTYPE_CONCAT: // v1 v2
10071 case OPTYPE_EQ: // v1 v2
10072 case OPTYPE_LT: // v1 v2
10073 case OPTYPE_GT: // v1 v2
10074 case OPTYPE_NE: // v1 v2
10075 case OPTYPE_GE: // v1 v2
10076 case OPTYPE_LE: // v1 v2
10077 case OPTYPE_AND: // v1 v2
10078 case OPTYPE_OR: // v1 v2
10079 case OPTYPE_XOR: // v1 v2
10080 case OPTYPE_AND4B: // v1 v2
10081 case OPTYPE_OR4B: // v1 v2
10082 case OPTYPE_XOR4B: // v1 v2
10083 case OPTYPE_SHL: // v1 v2
10084 case OPTYPE_SHR: // v1 v2
10085 case OPTYPE_ROTL: // v1 v2
10086 case OPTYPE_ROTR: // v1 v2
10087 case OPTYPE_INT2BIT: // v1 v2
10088 case OPTYPE_INT2HEX: // v1 v2
10089 case OPTYPE_INT2OCT: // v1 v2
10090 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10091 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10092 break;
10093 case OPTYPE_UNICHAR2OCT: // v1 [v2]
10094 case OPTYPE_OCT2UNICHAR:
10095 case OPTYPE_ENCODE_BASE64:
10096 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10097 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10098 break;
10099 case OPTYPE_DECOMP: // v1 v2 v3
10100 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10101 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10102 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10103 break;
10104
10105 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
10106 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
10107 // no break
10108 case OPTYPE_SUBSTR: // ti1 v2 v3
10109 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10110 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
10111 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
10112 break;
10113
10114 case OPTYPE_REGEXP: // ti1 t2 v3
10115 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10116 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
10117 // no break
10118 case OPTYPE_LENGTHOF: // ti1
10119 case OPTYPE_SIZEOF: // ti1
10120 case OPTYPE_VALUEOF: // ti1
10121 case OPTYPE_ENCODE: // ti1
10122 case OPTYPE_TTCN2STRING:
10123 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10124 break;
10125 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
10126 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10127 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10128 break;
10129 case OPTYPE_DECVALUE_UNICHAR: { // r1 r2 [v3]
10130 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10131 self_ref |= (ass == lhs);
10132 if (u.expr.v3) self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10133 goto label_r1;
10134 break; }
10135 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
10136 // component.create -- assume no self-ref
10137 case OPTYPE_ACTIVATE: // r1
10138 // defaultref := activate(altstep) -- assume no self-ref
10139 case OPTYPE_TMR_RUNNING: // r1
10140 // boolvar := a_timer.running -- assume no self-ref
10141 break;
10142 break;
10143
10144 case OPTYPE_LOG2STR: {// logargs
10145 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
10146 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
10147 switch (la->get_type()) {
10148 case Ttcn::LogArgument::L_UNDEF:
10149 case Ttcn::LogArgument::L_ERROR:
10150 FATAL_ERROR("log2str argument type");
10151 break; // not reached
10152
10153 case Ttcn::LogArgument::L_MACRO:
10154 case Ttcn::LogArgument::L_STR:
10155 break; // self reference not possible
10156
10157 case Ttcn::LogArgument::L_VAL:
10158 case Ttcn::LogArgument::L_MATCH:
10159 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
10160 break;
10161
10162 case Ttcn::LogArgument::L_REF: {
10163 Ttcn::Ref_base *ref = la->get_ref();
10164 Common::Assignment *ass = ref->get_refd_assignment();
10165 self_ref |= (ass == lhs);
10166 break; }
10167
10168 case Ttcn::LogArgument::L_TI: {
10169 Ttcn::TemplateInstance *ti = la->get_ti();
10170 Ttcn::Template *t = ti->get_Template();
10171 self_ref |= chk_expr_self_ref_templ(t, lhs);
10172 break; }
10173
10174 // no default please
10175 } // switch la->logargtype
10176 }
10177 break; }
10178
10179 case OPTYPE_DECODE: { // r1 r2
10180 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10181 self_ref |= (ass == lhs);
10182 goto label_r1; }
10183 case OPTYPE_EXECUTE: // r1 [v2]
10184 if (u.expr.v2) {
10185 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10186 }
10187 label_r1:
10188 // no break
10189 case OPTYPE_UNDEF_RUNNING: // r1
10190 case OPTYPE_TMR_READ: { // r1
10191 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
10192 self_ref |= (ass == lhs);
10193 break; }
10194
10195 case OPTYPE_ISCHOSEN_T: // t1 i2
10196 case OPTYPE_ISBOUND: // ti1
10197 case OPTYPE_ISVALUE: // ti1
10198 case OPTYPE_ISPRESENT: { // ti1
10199 Ttcn::Template *t;
10200 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10201 else t = u.expr.ti1->get_Template();
10202 self_ref |= chk_expr_self_ref_templ(t, lhs);
10203 break; }
10204
10205 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10206 if (u.expr.v3) {
10207 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10208 }
10209 // no break
10210 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10211 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10212 // TODO t_list2
10213 break;
10214
10215 case NUMBER_OF_OPTYPES: // can never happen
10216 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10217 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10218 break;
10219 } // switch u.expr.v_optype
10220 return self_ref;
10221 }
10222
10223
10224 string Value::create_stringRepr()
10225 {
10226 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10227 switch (valuetype) {
10228 case V_ERROR:
10229 return string("<erroneous>");
10230 case V_NULL:
10231 return string("NULL");
10232 case V_BOOL:
10233 if (!parse_only && is_asn1()) {
10234 if (u.val_bool) return string("TRUE");
10235 else return string("FALSE");
10236 }
10237 else {
10238 if (u.val_bool) return string("true");
10239 else return string("false");
10240 }
10241 case V_INT:
10242 return u.val_Int->t_str();
10243 case V_REAL:
10244 return Real2string(u.val_Real);
10245 case V_ENUM:
10246 case V_NAMEDINT:
10247 case V_UNDEF_LOWERID:
10248 return u.val_id->get_name();
10249 case V_NAMEDBITS: {
10250 string ret_val("{ ");
10251 for (size_t i = 0; i < u.ids->size(); i++) {
10252 if (i>0) ret_val += ' ';
10253 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10254 }
10255 ret_val += '}';
10256 return ret_val; }
10257 case V_BSTR: {
10258 string ret_val('\'');
10259 ret_val += *u.str.val_str;
10260 ret_val += "'B";
10261 return ret_val; }
10262 case V_HSTR: {
10263 string ret_val('\'');
10264 ret_val += *u.str.val_str;
10265 ret_val += "'H";
10266 return ret_val; }
10267 case V_OSTR: {
10268 string ret_val('\'');
10269 ret_val += *u.str.val_str;
10270 ret_val += "'O";
10271 return ret_val; }
10272 case V_CSTR:
10273 case V_ISO2022STR:
10274 return u.str.val_str->get_stringRepr();
10275 case V_USTR:
10276 return u.ustr.val_ustr->get_stringRepr();
10277 case V_CHARSYMS:
10278 /** \todo stringrepr of V_CHARSYMS */
10279 return string("<sorry, string representation of charsyms "
10280 "not implemented>");
10281 case V_OID:
10282 case V_ROID: {
10283 string ret_val;
10284 if (parse_only || !is_asn1()) ret_val += "objid ";
10285 ret_val += "{ ";
10286 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10287 if (i>0) ret_val += ' ';
10288 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10289 }
10290 ret_val += " }";
10291 return ret_val; }
10292 case V_CHOICE:
10293 if (!parse_only && is_asn1()) {
10294 string ret_val(u.choice.alt_name->get_dispname());
10295 ret_val += " : ";
10296 ret_val += u.choice.alt_value->get_stringRepr();
10297 return ret_val;
10298 }
10299 else {
10300 string ret_val("{ ");
10301 ret_val += u.choice.alt_name->get_dispname();
10302 ret_val += " := ";
10303 ret_val += u.choice.alt_value->get_stringRepr();
10304 ret_val += " }";
10305 return ret_val;
10306 }
10307 case V_SEQOF:
10308 case V_SETOF:
10309 case V_ARRAY: {
10310 string ret_val("{ ");
10311 if (!is_indexed()) {
10312 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10313 if (i > 0) ret_val += ", ";
10314 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10315 }
10316 } else {
10317 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10318 if (i > 0) ret_val += ", ";
10319 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10320 }
10321 }
10322 ret_val += " }";
10323 return ret_val; }
10324 case V_SEQ:
10325 case V_SET: {
10326 string ret_val("{ ");
10327 bool asn1_flag = !parse_only && is_asn1();
10328 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10329 if (i > 0) ret_val += ", ";
10330 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10331 ret_val += nv->get_name().get_dispname();
10332 if (asn1_flag) ret_val += ' ';
10333 else ret_val += " := ";
10334 ret_val += nv->get_value()->get_stringRepr();
10335 }
10336 ret_val += " }";
10337 return ret_val; }
10338 case V_REFD: {
10339 // do not evaluate the reference if it is not done so far
10340 // (e.g. in parse-only mode)
10341 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10342 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10343 else return t_val->get_stringRepr(); }
10344 case V_OMIT:
10345 return string("omit");
10346 case V_VERDICT:
10347 switch (u.verdict) {
10348 case Verdict_NONE:
10349 return string("none");
10350 case Verdict_PASS:
10351 return string("pass");
10352 case Verdict_INCONC:
10353 return string("inconc");
10354 case Verdict_FAIL:
10355 return string("fail");
10356 case Verdict_ERROR:
10357 return string("error");
10358 default:
10359 return string("<unknown verdict value>");
10360 }
10361 case V_DEFAULT_NULL:
10362 case V_FAT_NULL:
10363 return string("null");
10364 case V_EXPR:
10365 switch (u.expr.v_optype) {
10366 case OPTYPE_RND:
10367 return string("rnd()");
10368 case OPTYPE_TESTCASENAME:
10369 return string("testcasename()");
10370 case OPTYPE_UNARYPLUS:
10371 return create_stringRepr_unary("+");
10372 case OPTYPE_UNARYMINUS:
10373 return create_stringRepr_unary("-");
10374 case OPTYPE_NOT:
10375 return create_stringRepr_unary("not");
10376 case OPTYPE_NOT4B:
10377 return create_stringRepr_unary("not4b");
10378 case OPTYPE_BIT2HEX:
10379 return create_stringRepr_predef1("bit2hex");
10380 case OPTYPE_BIT2INT:
10381 return create_stringRepr_predef1("bit2int");
10382 case OPTYPE_BIT2OCT:
10383 return create_stringRepr_predef1("bit2oct");
10384 case OPTYPE_BIT2STR:
10385 return create_stringRepr_predef1("bit2str");
10386 case OPTYPE_CHAR2INT:
10387 return create_stringRepr_predef1("char2int");
10388 case OPTYPE_CHAR2OCT:
10389 return create_stringRepr_predef1("char2oct");
10390 case OPTYPE_FLOAT2INT:
10391 return create_stringRepr_predef1("float2int");
10392 case OPTYPE_FLOAT2STR:
10393 return create_stringRepr_predef1("float2str");
10394 case OPTYPE_HEX2BIT:
10395 return create_stringRepr_predef1("hex2bit");
10396 case OPTYPE_HEX2INT:
10397 return create_stringRepr_predef1("hex2int");
10398 case OPTYPE_HEX2OCT:
10399 return create_stringRepr_predef1("hex2oct");
10400 case OPTYPE_HEX2STR:
10401 return create_stringRepr_predef1("hex2str");
10402 case OPTYPE_INT2CHAR:
10403 return create_stringRepr_predef1("int2char");
10404 case OPTYPE_INT2FLOAT:
10405 return create_stringRepr_predef1("int2float");
10406 case OPTYPE_INT2STR:
10407 return create_stringRepr_predef1("int2str");
10408 case OPTYPE_INT2UNICHAR:
10409 return create_stringRepr_predef1("int2unichar");
10410 case OPTYPE_OCT2BIT:
10411 return create_stringRepr_predef1("oct2bit");
10412 case OPTYPE_OCT2CHAR:
10413 return create_stringRepr_predef1("oct2char");
10414 case OPTYPE_OCT2HEX:
10415 return create_stringRepr_predef1("oct2hex");
10416 case OPTYPE_OCT2INT:
10417 return create_stringRepr_predef1("oct2int");
10418 case OPTYPE_OCT2STR:
10419 return create_stringRepr_predef1("oct2str");
10420 case OPTYPE_GET_STRINGENCODING:
10421 return create_stringRepr_predef1("get_stringencoding");
10422 case OPTYPE_REMOVE_BOM:
10423 return create_stringRepr_predef1("remove_bom");
10424 case OPTYPE_ENCODE_BASE64: {
10425 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10426 else return create_stringRepr_predef1("encode_base64");
10427 }
10428 case OPTYPE_DECODE_BASE64:
10429 return create_stringRepr_predef1("decode_base64");
10430 case OPTYPE_OCT2UNICHAR:{
10431 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10432 else return create_stringRepr_predef1("oct2unichar");
10433 }
10434 case OPTYPE_UNICHAR2OCT: {
10435 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10436 else return create_stringRepr_predef1("unichar2oct");
10437 }
10438 case OPTYPE_ENCVALUE_UNICHAR: {
10439 if (u.expr.v2) return create_stringRepr_predef2("encvalue_unichar");
10440 else return create_stringRepr_predef1("encvalue_unichar");
10441 }
10442 case OPTYPE_DECVALUE_UNICHAR: {
10443 if (u.expr.v3) {
10444 string ret_val("decvalue_unichar");
10445 ret_val += '(';
10446 ret_val += u.expr.v1->get_stringRepr();
10447 ret_val += ", ";
10448 ret_val += u.expr.v2->get_stringRepr();
10449 ret_val += ", ";
10450 ret_val += u.expr.v3->get_stringRepr();
10451 ret_val += ')';
10452 return ret_val;
10453 }
10454 else return create_stringRepr_predef2("decvalue_unichar");
10455 }
10456 case OPTYPE_STR2BIT:
10457 return create_stringRepr_predef1("str2bit");
10458 case OPTYPE_STR2FLOAT:
10459 return create_stringRepr_predef1("str2float");
10460 case OPTYPE_STR2HEX:
10461 return create_stringRepr_predef1("str2hex");
10462 case OPTYPE_STR2INT:
10463 return create_stringRepr_predef1("str2int");
10464 case OPTYPE_STR2OCT:
10465 return create_stringRepr_predef1("str2oct");
10466 case OPTYPE_UNICHAR2INT:
10467 return create_stringRepr_predef1("unichar2int");
10468 case OPTYPE_UNICHAR2CHAR:
10469 return create_stringRepr_predef1("unichar2char");
10470 case OPTYPE_ENUM2INT:
10471 return create_stringRepr_predef1("enum2int");
10472 case OPTYPE_ENCODE:
10473 return create_stringRepr_predef1("encvalue");
10474 case OPTYPE_DECODE:
10475 return create_stringRepr_predef2("decvalue");
10476 case OPTYPE_RNDWITHVAL:
10477 return create_stringRepr_predef1("rnd");
10478 case OPTYPE_ADD:
10479 return create_stringRepr_infix("+");
10480 case OPTYPE_SUBTRACT:
10481 return create_stringRepr_infix("-");
10482 case OPTYPE_MULTIPLY:
10483 return create_stringRepr_infix("*");
10484 case OPTYPE_DIVIDE:
10485 return create_stringRepr_infix("/");
10486 case OPTYPE_MOD:
10487 return create_stringRepr_infix("mod");
10488 case OPTYPE_REM:
10489 return create_stringRepr_infix("rem");
10490 case OPTYPE_CONCAT:
10491 return create_stringRepr_infix("&");
10492 case OPTYPE_EQ:
10493 return create_stringRepr_infix("==");
10494 case OPTYPE_LT:
10495 return create_stringRepr_infix("<");
10496 case OPTYPE_GT:
10497 return create_stringRepr_infix(">");
10498 case OPTYPE_NE:
10499 return create_stringRepr_infix("!=");
10500 case OPTYPE_GE:
10501 return create_stringRepr_infix(">=");
10502 case OPTYPE_LE:
10503 return create_stringRepr_infix("<=");
10504 case OPTYPE_AND:
10505 return create_stringRepr_infix("and");
10506 case OPTYPE_OR:
10507 return create_stringRepr_infix("or");
10508 case OPTYPE_XOR:
10509 return create_stringRepr_infix("xor");
10510 case OPTYPE_AND4B:
10511 return create_stringRepr_infix("and4b");
10512 case OPTYPE_OR4B:
10513 return create_stringRepr_infix("or4b");
10514 case OPTYPE_XOR4B:
10515 return create_stringRepr_infix("xor4b");
10516 case OPTYPE_SHL:
10517 return create_stringRepr_infix("<<");
10518 case OPTYPE_SHR:
10519 return create_stringRepr_infix(">>");
10520 case OPTYPE_ROTL:
10521 return create_stringRepr_infix("<@");
10522 case OPTYPE_ROTR:
10523 return create_stringRepr_infix("@>");
10524 case OPTYPE_INT2BIT:
10525 return create_stringRepr_predef2("int2bit");
10526 case OPTYPE_INT2HEX:
10527 return create_stringRepr_predef2("int2hex");
10528 case OPTYPE_INT2OCT:
10529 return create_stringRepr_predef2("int2oct");
10530 case OPTYPE_SUBSTR: {
10531 string ret_val("substr(");
10532 u.expr.ti1->append_stringRepr(ret_val);
10533 ret_val += ", ";
10534 ret_val += u.expr.v2->get_stringRepr();
10535 ret_val += ", ";
10536 ret_val += u.expr.v3->get_stringRepr();
10537 ret_val += ')';
10538 return ret_val;
10539 }
10540 case OPTYPE_REGEXP: {
10541 string ret_val("regexp(");
10542 u.expr.ti1->append_stringRepr(ret_val);
10543 ret_val += ", ";
10544 u.expr.t2->append_stringRepr(ret_val);
10545 ret_val += ", ";
10546 ret_val += u.expr.v3->get_stringRepr();
10547 ret_val += ')';
10548 return ret_val;
10549 }
10550 case OPTYPE_DECOMP: {
10551 string ret_val("decomp(");
10552 ret_val += u.expr.v1->get_stringRepr();
10553 ret_val += ", ";
10554 ret_val += u.expr.v2->get_stringRepr();
10555 ret_val += ", ";
10556 ret_val += u.expr.v3->get_stringRepr();
10557 ret_val += ')';
10558 return ret_val;
10559 }
10560 case OPTYPE_REPLACE: {
10561 string ret_val("replace(");
10562 u.expr.ti1->append_stringRepr(ret_val);
10563 ret_val += ", ";
10564 ret_val += u.expr.v2->get_stringRepr();
10565 ret_val += ", ";
10566 ret_val += u.expr.v3->get_stringRepr();
10567 ret_val += ", ";
10568 u.expr.ti4->append_stringRepr(ret_val);
10569 ret_val += ')';
10570 return ret_val;
10571 }
10572 case OPTYPE_ISPRESENT: {
10573 string ret_val("ispresent(");
10574 u.expr.ti1->append_stringRepr(ret_val);
10575 ret_val += ')';
10576 return ret_val; }
10577 case OPTYPE_ISCHOSEN: {
10578 string ret_val("ischosen(");
10579 ret_val += u.expr.r1->get_dispname();
10580 ret_val += '.';
10581 ret_val += u.expr.i2->get_dispname();
10582 ret_val += ')';
10583 return ret_val; }
10584 case OPTYPE_ISCHOSEN_V: {
10585 string ret_val("ischosen(");
10586 ret_val += u.expr.v1->get_stringRepr();
10587 ret_val += '.';
10588 ret_val += u.expr.i2->get_dispname();
10589 ret_val += ')';
10590 return ret_val; }
10591 case OPTYPE_ISCHOSEN_T: {
10592 string ret_val("ischosen(");
10593 ret_val += u.expr.t1->get_stringRepr();
10594 ret_val += '.';
10595 ret_val += u.expr.i2->get_dispname();
10596 ret_val += ')';
10597 return ret_val; }
10598 case OPTYPE_LENGTHOF: {
10599 string ret_val("lengthof(");
10600 u.expr.ti1->append_stringRepr(ret_val);
10601 ret_val += ')';
10602 return ret_val; }
10603 case OPTYPE_SIZEOF: {
10604 string ret_val("sizeof(");
10605 u.expr.ti1->append_stringRepr(ret_val);
10606 ret_val += ')';
10607 return ret_val; }
10608 case OPTYPE_ISVALUE: {
10609 string ret_val("isvalue(");
10610 u.expr.ti1->append_stringRepr(ret_val);
10611 ret_val += ')';
10612 return ret_val; }
10613 case OPTYPE_VALUEOF: {
10614 string ret_val("valueof(");
10615 u.expr.ti1->append_stringRepr(ret_val);
10616 ret_val += ')';
10617 return ret_val; }
10618 case OPTYPE_LOG2STR:
10619 return string("log2str(...)");
10620 case OPTYPE_MATCH: {
10621 string ret_val("match(");
10622 ret_val += u.expr.v1->get_stringRepr();
10623 ret_val += ", ";
10624 u.expr.t2->append_stringRepr(ret_val);
10625 ret_val += ')';
10626 return ret_val; }
10627 case OPTYPE_TTCN2STRING: {
10628 string ret_val("ttcn2string(");
10629 u.expr.ti1->append_stringRepr(ret_val);
10630 ret_val += ')';
10631 return ret_val;
10632 }
10633 case OPTYPE_UNDEF_RUNNING:
10634 return u.expr.r1->get_dispname() + ".running";
10635 case OPTYPE_COMP_NULL:
10636 return string("null");
10637 case OPTYPE_COMP_MTC:
10638 return string("mtc");
10639 case OPTYPE_COMP_SYSTEM:
10640 return string("system");
10641 case OPTYPE_COMP_SELF:
10642 return string("self");
10643 case OPTYPE_COMP_CREATE: {
10644 string ret_val(u.expr.r1->get_dispname());
10645 ret_val += ".create";
10646 if (u.expr.v2 || u.expr.v3) {
10647 ret_val += '(';
10648 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10649 else ret_val += '-';
10650 if (u.expr.v3) {
10651 ret_val += ", ";
10652 ret_val += u.expr.v3->get_stringRepr();
10653 }
10654 ret_val += ')';
10655 }
10656 if (u.expr.b4) ret_val += " alive";
10657 return ret_val; }
10658 case OPTYPE_COMP_RUNNING:
10659 return u.expr.v1->get_stringRepr() + ".running";
10660 case OPTYPE_COMP_RUNNING_ANY:
10661 return string("any component.running");
10662 case OPTYPE_COMP_RUNNING_ALL:
10663 return string("all component.running");
10664 case OPTYPE_COMP_ALIVE:
10665 return u.expr.v1->get_stringRepr() + ".alive";
10666 case OPTYPE_COMP_ALIVE_ANY:
10667 return string("any component.alive");
10668 case OPTYPE_COMP_ALIVE_ALL:
10669 return string("all component.alive");
10670 case OPTYPE_TMR_READ:
10671 return u.expr.r1->get_dispname() + ".read";
10672 case OPTYPE_TMR_RUNNING:
10673 return u.expr.r1->get_dispname() + ".running";
10674 case OPTYPE_TMR_RUNNING_ANY:
10675 return string("any timer.running");
10676 case OPTYPE_GETVERDICT:
10677 return string("getverdict");
10678 case OPTYPE_ACTIVATE: {
10679 string ret_val("activate(");
10680 ret_val += u.expr.r1->get_dispname();
10681 ret_val += ')';
10682 return ret_val; }
10683 case OPTYPE_ACTIVATE_REFD: {
10684 string ret_val("activate(derefer(");
10685 ret_val += u.expr.v1->get_stringRepr();
10686 ret_val += ")(";
10687 if (u.expr.state == EXPR_CHECKED) {
10688 if (u.expr.ap_list2) {
10689 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10690 for (size_t i = 0; i < nof_pars; i++) {
10691 if (i > 0) ret_val += ", ";
10692 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10693 }
10694 }
10695 } else {
10696 if (u.expr.t_list2) {
10697 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10698 for (size_t i = 0; i < nof_pars; i++) {
10699 if (i > 0) ret_val += ", ";
10700 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10701 }
10702 }
10703 }
10704 ret_val += "))";
10705 return ret_val; }
10706 case OPTYPE_EXECUTE: {
10707 string ret_val("execute(");
10708 ret_val += u.expr.r1->get_dispname();
10709 if (u.expr.v2) {
10710 ret_val += ", ";
10711 ret_val += u.expr.v2->get_stringRepr();
10712 }
10713 ret_val += ')';
10714 return ret_val; }
10715 case OPTYPE_EXECUTE_REFD: {
10716 string ret_val("execute(derefers(");
10717 ret_val += u.expr.v1->get_stringRepr();
10718 ret_val += ")(";
10719 if (u.expr.state == EXPR_CHECKED) {
10720 if (u.expr.ap_list2) {
10721 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10722 for (size_t i = 0; i < nof_pars; i++) {
10723 if (i > 0) ret_val += ", ";
10724 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10725 }
10726 }
10727 } else {
10728 if (u.expr.t_list2) {
10729 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10730 for (size_t i = 0; i < nof_pars; i++) {
10731 if (i > 0) ret_val += ", ";
10732 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10733 }
10734 }
10735 }
10736 ret_val += ')';
10737 if(u.expr.v3) {
10738 ret_val += ", ";
10739 ret_val += u.expr.v3->get_stringRepr();
10740 }
10741 ret_val += ')';
10742 return ret_val; }
10743 case OPTYPE_PROF_RUNNING:
10744 return string("@profiler.running");
10745 default:
10746 return string("<unsupported optype>");
10747 } // switch u.expr.v_optype
10748 case V_MACRO:
10749 switch (u.macro) {
10750 case MACRO_MODULEID:
10751 return string("%moduleId");
10752 case MACRO_FILENAME:
10753 return string("%fileName");
10754 case MACRO_BFILENAME:
10755 return string("__BFILE__");
10756 case MACRO_FILEPATH:
10757 return string("__FILE__");
10758 case MACRO_LINENUMBER:
10759 return string("%lineNumber");
10760 case MACRO_LINENUMBER_C:
10761 return string("__LINE__");
10762 case MACRO_DEFINITIONID:
10763 return string("%definitionId");
10764 case MACRO_SCOPE:
10765 return string("__SCOPE__");
10766 case MACRO_TESTCASEID:
10767 return string("%testcaseId");
10768 default:
10769 return string("<unknown macro>");
10770 } // switch u.macro
10771 case V_NOTUSED:
10772 return string('-');
10773 case V_FUNCTION:
10774 case V_ALTSTEP:
10775 case V_TESTCASE: {
10776 string ret_val("refers(");
10777 ret_val += u.refd_fat->get_assname();
10778 ret_val += ')';
10779 return ret_val; }
10780 case V_INVOKE: {
10781 string ret_val;
10782 ret_val += u.invoke.v->get_stringRepr();
10783 ret_val += ".apply(";
10784 if (u.invoke.ap_list) {
10785 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10786 for (size_t i = 0; i < nof_pars; i++) {
10787 if (i > 0) ret_val += ", ";
10788 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10789 }
10790 } else if (u.invoke.t_list) {
10791 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10792 for (size_t i = 0; i < nof_pars; i++) {
10793 if (i > 0) ret_val += ", ";
10794 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10795 }
10796 }
10797 ret_val += ')';
10798 return ret_val; }
10799 case V_REFER: {
10800 string ret_val("refers(");
10801 ret_val += u.refered->get_dispname();
10802 ret_val += ')';
10803 return ret_val; }
10804 default:
10805 return string("<unsupported valuetype>");
10806 } // switch valuetype
10807 }
10808
10809 string Value::create_stringRepr_unary(const char *operator_str)
10810 {
10811 string ret_val(operator_str);
10812 ret_val += '(';
10813 ret_val += u.expr.v1->get_stringRepr();
10814 ret_val += ')';
10815 return ret_val;
10816 }
10817
10818 string Value::create_stringRepr_infix(const char *operator_str)
10819 {
10820 string ret_val('(');
10821 ret_val += u.expr.v1->get_stringRepr();
10822 ret_val += ' ';
10823 ret_val += operator_str;
10824 ret_val += ' ';
10825 ret_val += u.expr.v2->get_stringRepr();
10826 ret_val += ')';
10827 return ret_val;
10828 }
10829
10830 string Value::create_stringRepr_predef1(const char *function_name)
10831 {
10832 string ret_val(function_name);
10833 ret_val += '(';
10834 if (u.expr.v_optype == OPTYPE_ENCODE || u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR) { // ti1, not v1
10835 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10836 }
10837 else ret_val += u.expr.v1->get_stringRepr();
10838 ret_val += ')';
10839 return ret_val;
10840 }
10841
10842 string Value::create_stringRepr_predef2(const char *function_name)
10843 {
10844 string ret_val(function_name);
10845 ret_val += '(';
10846 ret_val += u.expr.v1->get_stringRepr();
10847 ret_val += ", ";
10848 ret_val += u.expr.v2->get_stringRepr();
10849 ret_val += ')';
10850 return ret_val;
10851 }
10852
10853 bool Value::operator==(Value& val)
10854 {
10855 Value *left = get_value_refd_last();
10856 Type *left_governor = left->get_my_governor();
10857 if (left_governor) left_governor = left_governor->get_type_refd_last();
10858 Value *right = val.get_value_refd_last();
10859 Type *right_governor = right->get_my_governor();
10860 if (right_governor) right_governor = right_governor->get_type_refd_last();
10861 if (left_governor && right_governor
10862 && !left_governor->is_compatible(right_governor, NULL)
10863 && !right_governor->is_compatible(left_governor, NULL))
10864 FATAL_ERROR("Value::operator==");
10865
10866 // Not-A-Value is not equal to anything (NaN analogy:)
10867 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10868 return false;
10869
10870 switch (left->valuetype) {
10871 case V_NULL:
10872 case V_OMIT:
10873 case V_DEFAULT_NULL:
10874 case V_FAT_NULL:
10875 case V_NOTUSED:
10876 return left->valuetype == right->valuetype;
10877 case V_BOOL:
10878 return right->valuetype == V_BOOL &&
10879 left->get_val_bool() == right->get_val_bool();
10880 case V_INT:
10881 return right->valuetype == V_INT && *left->get_val_Int()
10882 == *right->get_val_Int();
10883 case V_REAL:
10884 return right->valuetype == V_REAL &&
10885 left->get_val_Real() == right->get_val_Real();
10886 case V_CSTR:
10887 switch (right->valuetype) {
10888 case V_CSTR:
10889 return left->get_val_str() == right->get_val_str();
10890 case V_USTR:
10891 return right->get_val_ustr() == left->get_val_str();
10892 case V_ISO2022STR:
10893 return right->get_val_iso2022str() == left->get_val_str();
10894 default:
10895 return false;
10896 }
10897 case V_BSTR:
10898 case V_HSTR:
10899 case V_OSTR:
10900 return left->valuetype == right->valuetype &&
10901 left->get_val_str() == right->get_val_str();
10902 case V_USTR:
10903 switch (right->valuetype) {
10904 case V_CSTR:
10905 return left->get_val_ustr() == right->get_val_str();
10906 case V_USTR:
10907 return left->get_val_ustr() == right->get_val_ustr();
10908 case V_ISO2022STR:
10909 return left->get_val_ustr() == right->get_val_iso2022str();
10910 default:
10911 return false;
10912 }
10913 case V_ISO2022STR:
10914 switch (right->valuetype) {
10915 case V_CSTR:
10916 return left->get_val_iso2022str() == right->get_val_str();
10917 case V_USTR:
10918 // The appropriate operator==() is missing. The operands are swapped,
10919 // but it shouldn't be a problem.
10920 return right->get_val_ustr() == left->get_val_iso2022str();
10921 case V_ISO2022STR:
10922 return left->get_val_iso2022str() == right->get_val_iso2022str();
10923 default:
10924 return false;
10925 }
10926 case V_ENUM:
10927 return right->valuetype == V_ENUM &&
10928 left->get_val_id()->get_name() == right->get_val_id()->get_name();
10929 case V_OID:
10930 case V_ROID:
10931 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
10932 vector<string> act, other;
10933 get_oid_comps(act);
10934 val.get_oid_comps(other);
10935 size_t act_size = act.size(), other_size = other.size();
10936 bool ret_val;
10937 if (act_size == other_size) {
10938 ret_val = true;
10939 for (size_t i = 0; i < act_size; i++)
10940 if (*act[i] != *other[i]) {
10941 ret_val = false;
10942 break;
10943 }
10944 } else ret_val = false;
10945 for (size_t i = 0; i < act_size; i++) delete act[i];
10946 act.clear();
10947 for (size_t i = 0; i < other_size; i++) delete other[i];
10948 other.clear();
10949 return ret_val;
10950 } else return false;
10951 case V_CHOICE:
10952 return right->valuetype == V_CHOICE &&
10953 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
10954 *(left->get_alt_value()) == *(right->get_alt_value());
10955 case V_SEQ:
10956 case V_SET: {
10957 if (!left_governor) FATAL_ERROR("Value::operator==");
10958 if (left->valuetype != right->valuetype) return false;
10959 size_t nof_comps = left_governor->get_nof_comps();
10960 for (size_t i = 0; i < nof_comps; i++) {
10961 Value *lval = NULL, *rval = NULL;
10962 CompField* cfl = left_governor->get_comp_byIndex(i);
10963 const Identifier& field_name = cfl->get_name();
10964 if (left->has_comp_withName(field_name)) {
10965 lval = left->get_comp_value_byName(field_name);
10966 if (right->has_comp_withName(field_name)) {
10967 rval = right->get_comp_value_byName(field_name);
10968 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
10969 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
10970 return false;
10971 else if (!(*lval == *rval))
10972 return false;
10973 } else {
10974 if (cfl->has_default()) {
10975 if (!(*lval == *cfl->get_defval()))
10976 return false;
10977 } else {
10978 if (lval->valuetype != V_OMIT)
10979 return false;
10980 }
10981 }
10982 } else {
10983 if(right->has_comp_withName(field_name)) {
10984 rval = right->get_comp_value_byName(field_name);
10985 if(cfl->has_default()) {
10986 if(rval->valuetype==V_OMIT) return false;
10987 else {
10988 lval = cfl->get_defval();
10989 if (!(*lval==*rval)) return false;
10990 }
10991 }
10992 }
10993 }
10994 }
10995 return true; }
10996 case V_SEQOF:
10997 case V_ARRAY: {
10998 if (left->valuetype != right->valuetype) return false;
10999 size_t ncomps = get_nof_comps();
11000 if (ncomps != right->get_nof_comps()) return false;
11001
11002 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
11003 bool found = false;
11004 map<IndexedValue*, void> uncovered;
11005 for (size_t i = 0; i < left->get_nof_comps(); ++i)
11006 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
11007
11008 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
11009 found = false;
11010 for (size_t j = 0; j < uncovered.size(); ++j) {
11011 if (*(uncovered.get_nth_key(j)->get_value()) ==
11012 *(right->get_comp_byIndex(i)) &&
11013 *(uncovered.get_nth_key(j)->get_index()) ==
11014 *(right->get_index_byIndex(i))) {
11015 found = true;
11016 uncovered.erase(uncovered.get_nth_key(j));
11017 break;
11018 }
11019 }
11020 if (!found) break;
11021 }
11022 uncovered.clear();
11023 return found;
11024 } else if (left->is_indexed() || right->is_indexed()) {
11025 Value* indexed_one = 0;
11026 Value* not_indexed_one = 0;
11027
11028 if(left->is_indexed()) { // left is indexed, right is not
11029 indexed_one = left;
11030 not_indexed_one = right;
11031 } else { // right indexed, left is not
11032 indexed_one = right;
11033 not_indexed_one = left;
11034 }
11035
11036 for(size_t i = 0; i < ncomps; ++i) {
11037 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
11038 if(!(ind->valuetype == V_INT &&
11039 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
11040 *(indexed_one->get_comp_byIndex(i))))
11041 { return false; }
11042 }
11043 return true;
11044 } else { // none of them is indexed
11045 for (size_t i = 0; i < ncomps; i++) {
11046 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
11047 return false;
11048 }
11049 return true;
11050 }
11051 }
11052 case V_SETOF: {
11053 if (right->valuetype != V_SETOF) return false;
11054 size_t ncomps = get_nof_comps();
11055 if (ncomps != right->get_nof_comps()) return false;
11056 if (ncomps == 0) return true;
11057 map<size_t, void> uncovered;
11058 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
11059 for (size_t i = 0; i < ncomps; i++) {
11060 Value *left_item = left->get_comp_byIndex(i);
11061 bool pair_found = false;
11062 for (size_t j = 0; j < ncomps - i; j++) {
11063 size_t right_index = uncovered.get_nth_key(j);
11064 if (*left_item == *right->get_comp_byIndex(right_index)) {
11065 uncovered.erase(right_index);
11066 pair_found = true;
11067 break;
11068 }
11069 }
11070 if (!pair_found) {
11071 uncovered.clear();
11072 return false;
11073 }
11074 }
11075 return true; }
11076 case V_VERDICT:
11077 return right->valuetype == V_VERDICT &&
11078 left->get_val_verdict() == right->get_val_verdict();
11079 case V_FUNCTION:
11080 case V_ALTSTEP:
11081 case V_TESTCASE:
11082 return left->valuetype == right->valuetype &&
11083 left->get_refd_assignment() == right->get_refd_assignment();
11084 default:
11085 FATAL_ERROR("Value::operator==");
11086 }
11087 return true;
11088 }
11089
11090 bool Value::operator<(Value& val)
11091 {
11092 Value *left = get_value_refd_last();
11093 Type *left_governor = left->get_my_governor();
11094 if(left_governor) left_governor=left_governor->get_type_refd_last();
11095 Value *right = val.get_value_refd_last();
11096 Type *right_governor = right->get_my_governor();
11097 if(right_governor) right_governor=right_governor->get_type_refd_last();
11098 if (left->get_valuetype() != right->get_valuetype())
11099 FATAL_ERROR("Value::operator<");
11100 switch(valuetype){
11101 case V_INT:
11102 return *left->get_val_Int() < *right->get_val_Int();
11103 case V_REAL:
11104 return (left->get_val_Real() < right->get_val_Real());
11105 case V_ENUM:
11106 if(!left_governor || !right_governor)
11107 FATAL_ERROR("Value::operator<");
11108 if(left_governor!=right_governor)
11109 FATAL_ERROR("Value::operator<");
11110 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
11111 right_governor->get_enum_val_byId(*right->get_val_id()));
11112 default:
11113 FATAL_ERROR("Value::operator<");
11114 }
11115 return true;
11116 }
11117
11118 bool Value::is_string_type(Type::expected_value_t exp_val)
11119 {
11120 switch (get_expr_returntype(exp_val)) {
11121 case Type::T_CSTR:
11122 case Type::T_USTR:
11123 case Type::T_BSTR:
11124 case Type::T_HSTR:
11125 case Type::T_OSTR:
11126 return true;
11127 default:
11128 return false;
11129 }
11130 }
11131
11132 void Value::generate_code_expr(expression_struct *expr)
11133 {
11134 if (has_single_expr()) {
11135 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
11136 } else {
11137 switch (valuetype) {
11138 case V_EXPR:
11139 generate_code_expr_expr(expr);
11140 break;
11141 case V_CHOICE:
11142 case V_SEQOF:
11143 case V_SETOF:
11144 case V_ARRAY:
11145 case V_SEQ:
11146 case V_SET: {
11147 const string& tmp_id = get_temporary_id();
11148 const char *tmp_id_str = tmp_id.c_str();
11149 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11150 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
11151 set_genname_recursive(tmp_id);
11152 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11153 expr->expr = mputstr(expr->expr, tmp_id_str);
11154 break; }
11155 case V_INT: {
11156 const string& tmp_id = get_temporary_id();
11157 const char *tmp_id_str = tmp_id.c_str();
11158 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
11159 tmp_id_str);
11160 set_genname_recursive(tmp_id);
11161 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11162 expr->expr = mputstr(expr->expr, tmp_id_str);
11163 break; }
11164 case V_REFD: {
11165 if (!get_needs_conversion()) {
11166 u.ref.ref->generate_code_const_ref(expr);
11167 } else {
11168 Type *my_gov = get_expr_governor_last();
11169 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
11170 ->get_field_type(u.ref.ref->get_subrefs(),
11171 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
11172 // Make sure that nothing goes wrong.
11173 if (!my_gov || !refd_gov || my_gov == refd_gov)
11174 FATAL_ERROR("Value::generate_code_expr()");
11175 expression_struct expr_tmp;
11176 Code::init_expr(&expr_tmp);
11177 const string& tmp_id1 = get_temporary_id();
11178 const char *tmp_id_str1 = tmp_id1.c_str();
11179 const string& tmp_id2 = get_temporary_id();
11180 const char *tmp_id_str2 = tmp_id2.c_str();
11181 expr->preamble = mputprintf(expr->preamble,
11182 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
11183 tmp_id_str1);
11184 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11185 u.ref.ref->generate_code_const_ref(&expr_tmp);
11186 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11187 expr->preamble = mputprintf(expr->preamble,
11188 "%s %s;\n"
11189 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11190 "and `%s' are not compatible at run-time\");\n",
11191 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11192 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
11193 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
11194 ->get_typename().c_str(), refd_gov->get_typename().c_str());
11195 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11196 }
11197 break; }
11198 case V_INVOKE:
11199 generate_code_expr_invoke(expr);
11200 break;
11201 default:
11202 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
11203 }
11204 }
11205 }
11206
11207 void Value::generate_code_expr_mandatory(expression_struct *expr)
11208 {
11209 generate_code_expr(expr);
11210 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11211 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11212 }
11213
11214 bool Value::can_use_increment(Reference *ref) const
11215 {
11216 if (valuetype != V_EXPR) {
11217 return false;
11218 }
11219 switch (u.expr.v_optype) {
11220 case OPTYPE_ADD:
11221 case OPTYPE_SUBTRACT:
11222 break;
11223 default:
11224 return false;
11225 }
11226 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11227 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11228 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11229 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11230 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11231 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11232 return true;
11233 }
11234 return false;
11235 }
11236
11237 char *Value::generate_code_init(char *str, const char *name)
11238 {
11239 if (get_code_generated()) return str;
11240 if (err_descr) {
11241 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11242 }
11243 switch (valuetype) {
11244 case V_NULL:
11245 case V_BOOL:
11246 case V_REAL:
11247 case V_ENUM:
11248 case V_BSTR:
11249 case V_HSTR:
11250 case V_OSTR:
11251 case V_CSTR:
11252 case V_USTR:
11253 case V_ISO2022STR:
11254 case V_OID:
11255 case V_ROID:
11256 case V_VERDICT:
11257 case V_DEFAULT_NULL:
11258 case V_FAT_NULL:
11259 case V_FUNCTION:
11260 case V_ALTSTEP:
11261 case V_TESTCASE:
11262 // These values have a single string equivalent.
11263 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11264 break;
11265 case V_INT:
11266 if (u.val_Int->is_native_fit())
11267 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11268 else
11269 // It's always an INTEGER.
11270 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11271 "}\n", get_single_expr().c_str(), name);
11272 break;
11273 case V_EXPR:
11274 case V_INVOKE: {
11275 expression_struct expr;
11276 Code::init_expr(&expr);
11277 expr.expr = mputprintf(expr.expr, "%s = ", name);
11278 generate_code_expr(&expr);
11279 str = Code::merge_free_expr(str, &expr);
11280 break; }
11281 case V_CHOICE:
11282 str = generate_code_init_choice(str, name);
11283 break;
11284 case V_SEQOF:
11285 case V_SETOF:
11286 if (!is_indexed()) str = generate_code_init_seof(str, name);
11287 else str = generate_code_init_indexed(str, name);
11288 break;
11289 case V_ARRAY:
11290 if (!is_indexed()) str = generate_code_init_array(str, name);
11291 else str = generate_code_init_indexed(str, name);
11292 break;
11293 case V_SEQ:
11294 case V_SET:
11295 str = generate_code_init_se(str, name);
11296 break;
11297 case V_REFD:
11298 str = generate_code_init_refd(str, name);
11299 break;
11300 case V_MACRO:
11301 switch (u.macro) {
11302 case MACRO_TESTCASEID:
11303 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11304 break;
11305 default:
11306 // all others must already be evaluated away
11307 FATAL_ERROR("Value::generate_code_init()");
11308 }
11309 break;
11310 case V_NOTUSED:
11311 // unbound value, don't generate anything
11312 break;
11313 default:
11314 FATAL_ERROR("Value::generate_code_init()");
11315 }
11316 if (err_descr) {
11317 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11318 }
11319 set_code_generated();
11320 return str;
11321 }
11322
11323 char *Value::rearrange_init_code(char *str, Common::Module* usage_mod)
11324 {
11325 switch (valuetype) {
11326 case V_REFD: {
11327 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11328 if (parlist) {
11329 str = parlist->rearrange_init_code(str, usage_mod);
11330 }
11331 break; }
11332 case V_INVOKE: {
11333 str = u.invoke.v->rearrange_init_code(str, usage_mod);
11334 str = u.invoke.ap_list->rearrange_init_code(str, usage_mod);
11335 break; }
11336 case V_EXPR:
11337 switch (u.expr.v_optype) {
11338 case OPTYPE_UNARYPLUS:
11339 case OPTYPE_UNARYMINUS:
11340 case OPTYPE_NOT:
11341 case OPTYPE_NOT4B:
11342 case OPTYPE_BIT2HEX:
11343 case OPTYPE_BIT2INT:
11344 case OPTYPE_BIT2OCT:
11345 case OPTYPE_BIT2STR:
11346 case OPTYPE_CHAR2INT:
11347 case OPTYPE_CHAR2OCT:
11348 case OPTYPE_FLOAT2INT:
11349 case OPTYPE_FLOAT2STR:
11350 case OPTYPE_HEX2BIT:
11351 case OPTYPE_HEX2INT:
11352 case OPTYPE_HEX2OCT:
11353 case OPTYPE_HEX2STR:
11354 case OPTYPE_INT2CHAR:
11355 case OPTYPE_INT2FLOAT:
11356 case OPTYPE_INT2STR:
11357 case OPTYPE_INT2UNICHAR:
11358 case OPTYPE_OCT2BIT:
11359 case OPTYPE_OCT2CHAR:
11360 case OPTYPE_OCT2HEX:
11361 case OPTYPE_OCT2INT:
11362 case OPTYPE_OCT2STR:
11363 case OPTYPE_STR2BIT:
11364 case OPTYPE_STR2FLOAT:
11365 case OPTYPE_STR2HEX:
11366 case OPTYPE_STR2INT:
11367 case OPTYPE_STR2OCT:
11368 case OPTYPE_UNICHAR2INT:
11369 case OPTYPE_UNICHAR2CHAR:
11370 case OPTYPE_ENUM2INT:
11371 case OPTYPE_ISCHOSEN_V:
11372 case OPTYPE_GET_STRINGENCODING:
11373 case OPTYPE_REMOVE_BOM:
11374 case OPTYPE_DECODE_BASE64:
11375 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11376 break;
11377 case OPTYPE_DECODE: {
11378 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11379 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11380 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11381
11382 parlist = u.expr.r2->get_parlist();
11383 ass = u.expr.r2->get_refd_assignment();
11384 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11385 break; }
11386 case OPTYPE_ADD:
11387 case OPTYPE_SUBTRACT:
11388 case OPTYPE_MULTIPLY:
11389 case OPTYPE_DIVIDE:
11390 case OPTYPE_MOD:
11391 case OPTYPE_REM:
11392 case OPTYPE_CONCAT:
11393 case OPTYPE_EQ:
11394 case OPTYPE_LT:
11395 case OPTYPE_GT:
11396 case OPTYPE_NE:
11397 case OPTYPE_GE:
11398 case OPTYPE_LE:
11399 case OPTYPE_AND:
11400 case OPTYPE_OR:
11401 case OPTYPE_XOR:
11402 case OPTYPE_AND4B:
11403 case OPTYPE_OR4B:
11404 case OPTYPE_XOR4B:
11405 case OPTYPE_SHL:
11406 case OPTYPE_SHR:
11407 case OPTYPE_ROTL:
11408 case OPTYPE_ROTR:
11409 case OPTYPE_INT2BIT:
11410 case OPTYPE_INT2HEX:
11411 case OPTYPE_INT2OCT:
11412 //case OPTYPE_DECODE:
11413 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11414 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11415 break;
11416 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11417 case OPTYPE_OCT2UNICHAR:
11418 case OPTYPE_ENCODE_BASE64:
11419 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11420 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11421 break;
11422 case OPTYPE_SUBSTR:
11423 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11424 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11425 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11426 break;
11427 case OPTYPE_REGEXP:
11428 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11429 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11430 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11431 break;
11432 case OPTYPE_DECOMP:
11433 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11434 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11435 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11436 break;
11437 case OPTYPE_REPLACE:
11438 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11439 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11440 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11441 str = u.expr.ti4->rearrange_init_code(str, usage_mod);
11442 break;
11443 case OPTYPE_LENGTHOF:
11444 case OPTYPE_SIZEOF:
11445 case OPTYPE_VALUEOF:
11446 case OPTYPE_ENCODE:
11447 case OPTYPE_ISPRESENT:
11448 case OPTYPE_TTCN2STRING:
11449 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11450 break;
11451 case OPTYPE_ENCVALUE_UNICHAR:
11452 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11453 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11454 break;
11455 case OPTYPE_DECVALUE_UNICHAR: {
11456 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11457 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11458 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11459
11460 parlist = u.expr.r2->get_parlist();
11461 ass = u.expr.r2->get_refd_assignment();
11462 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11463 if (u.expr.v3) str = u.expr.v3->rearrange_init_code(str, usage_mod);
11464 break; }
11465 case OPTYPE_ISCHOSEN_T:
11466 str = u.expr.t1->rearrange_init_code(str, usage_mod);
11467 break;
11468 case OPTYPE_MATCH:
11469 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11470 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11471 break;
11472 default:
11473 // other kinds of expressions cannot appear within templates
11474 break;
11475 }
11476 break;
11477 default:
11478 break;
11479 }
11480 return str;
11481 }
11482
11483 char* Value::generate_code_tmp(char *str, const char *prefix,
11484 size_t& blockcount)
11485 {
11486 char *s2 = memptystr();
11487 char *s1 = generate_code_tmp(NULL, s2);
11488 if (s2[0]) {
11489 if (blockcount == 0) {
11490 str = mputstr(str, "{\n");
11491 blockcount++;
11492 }
11493 str = mputstr(str, s2);
11494 }
11495 Free(s2);
11496 str=mputstr(str, prefix);
11497 str=mputstr(str, s1);
11498 Free(s1);
11499 return str;
11500 }
11501
11502 char *Value::generate_code_tmp(char *str, char*& init)
11503 {
11504 expression_struct expr;
11505 Code::init_expr(&expr);
11506 generate_code_expr_mandatory(&expr);
11507 if (expr.preamble || expr.postamble) {
11508 if (valuetype == V_EXPR &&
11509 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11510 // a temporary variable is already introduced
11511 if (expr.preamble) init = mputstr(init, expr.preamble);
11512 if (expr.postamble) init = mputstr(init, expr.postamble);
11513 str = mputstr(str, expr.expr);
11514 } else {
11515 const string& tmp_id = get_temporary_id();
11516 const char *tmp_id_str = tmp_id.c_str();
11517 init = mputprintf(init, "%s %s;\n"
11518 "{\n",
11519 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11520 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11521 tmp_id_str);
11522 if (expr.preamble) init = mputstr(init, expr.preamble);
11523 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11524 if (expr.postamble) init = mputstr(init, expr.postamble);
11525 init = mputstr(init, "}\n");
11526 str = mputstr(str, tmp_id_str);
11527 }
11528 } else str = mputstr(str, expr.expr);
11529 Code::free_expr(&expr);
11530 return str;
11531 }
11532
11533 void Value::generate_code_log(expression_struct *expr)
11534 {
11535 if (explicit_cast_needed()) {
11536 char *expr_backup = expr->expr;
11537 expr->expr = NULL;
11538 generate_code_expr(expr);
11539 const string& tmp_id = get_temporary_id();
11540 const char *tmp_id_str = tmp_id.c_str();
11541 // We have to create a temporary object, because the parser of GCC
11542 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11543 // constructor call that is, this does not work: type(...).log(); but
11544 // this works: type tmp(...); tmp.log();.
11545 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11546 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11547 expr->expr);
11548 Free(expr->expr);
11549 expr->expr = mputstr(expr_backup, tmp_id_str);
11550 } else {
11551 generate_code_expr(expr);
11552 }
11553 expr->expr = mputstr(expr->expr, ".log()");
11554 }
11555
11556 void Value::generate_code_log_match(expression_struct *expr)
11557 {
11558 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11559 FATAL_ERROR("Value::generate_code_log_match()");
11560 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11561 // compliance the whole code-generation should be checked. Standalone
11562 // constructs like: "A(a[0].f());" should be avoided. The current
11563 // solution for HK38721 uses an additional assignment to overcome the
11564 // issue. The generated code will be slower, but it's needed for old GCC
11565 // versions in specific circumstances.
11566 if (u.expr.t2->needs_temp_ref()) {
11567 char *expr_backup = expr->expr;
11568 expr->expr = NULL;
11569 u.expr.t2->generate_code(expr);
11570 const string& tmp_id = get_temporary_id();
11571 const char *tmp_id_str = tmp_id.c_str();
11572 expr->preamble = mputprintf(expr->preamble,
11573 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11574 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11575 Free(expr->expr);
11576 expr->expr = mputstr(expr_backup, tmp_id_str);
11577 } else {
11578 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11579 // some reason "(A(NS::B)).a(C);" compiles fine.
11580 expr->expr = mputc(expr->expr, '(');
11581 u.expr.t2->generate_code(expr);
11582 expr->expr = mputc(expr->expr, ')');
11583 }
11584 expr->expr = mputstr(expr->expr, ".log_match(");
11585 u.expr.v1->generate_code_expr(expr);
11586 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11587 }
11588
11589 void Value::generate_code_expr_expr(expression_struct *expr)
11590 {
11591 switch (u.expr.v_optype) {
11592 case OPTYPE_RND:
11593 generate_code_expr_rnd(expr, 0);
11594 break;
11595 case OPTYPE_UNARYPLUS:
11596 // same as without the '+' operator
11597 u.expr.v1->generate_code_expr(expr);
11598 break;
11599 case OPTYPE_UNARYMINUS:
11600 generate_code_expr_unary(expr, "-", u.expr.v1);
11601 break;
11602 case OPTYPE_NOT:
11603 generate_code_expr_unary(expr, "!", u.expr.v1);
11604 break;
11605 case OPTYPE_NOT4B:
11606 generate_code_expr_unary(expr, "~", u.expr.v1);
11607 break;
11608 case OPTYPE_BIT2HEX:
11609 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11610 break;
11611 case OPTYPE_BIT2INT:
11612 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11613 break;
11614 case OPTYPE_BIT2OCT:
11615 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11616 break;
11617 case OPTYPE_BIT2STR:
11618 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11619 break;
11620 case OPTYPE_CHAR2INT:
11621 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11622 break;
11623 case OPTYPE_CHAR2OCT:
11624 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11625 break;
11626 case OPTYPE_FLOAT2INT:
11627 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11628 break;
11629 case OPTYPE_FLOAT2STR:
11630 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11631 break;
11632 case OPTYPE_HEX2BIT:
11633 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11634 break;
11635 case OPTYPE_HEX2INT:
11636 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11637 break;
11638 case OPTYPE_HEX2OCT:
11639 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11640 break;
11641 case OPTYPE_HEX2STR:
11642 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11643 break;
11644 case OPTYPE_INT2CHAR:
11645 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11646 break;
11647 case OPTYPE_INT2FLOAT:
11648 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11649 break;
11650 case OPTYPE_INT2STR:
11651 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11652 break;
11653 case OPTYPE_INT2UNICHAR:
11654 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11655 break;
11656 case OPTYPE_OCT2BIT:
11657 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11658 break;
11659 case OPTYPE_OCT2CHAR:
11660 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11661 break;
11662 case OPTYPE_GET_STRINGENCODING:
11663 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11664 break;
11665 case OPTYPE_REMOVE_BOM:
11666 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11667 break;
11668 case OPTYPE_ENCODE_BASE64:
11669 if (u.expr.v2)
11670 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11671 else
11672 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11673 break;
11674 case OPTYPE_DECODE_BASE64:
11675 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11676 break;
11677 case OPTYPE_OCT2UNICHAR:
11678 if (u.expr.v2)
11679 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11680 else
11681 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11682 break;
11683 case OPTYPE_UNICHAR2OCT:
11684 if (u.expr.v2)
11685 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11686 else
11687 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11688 break;
11689 case OPTYPE_ENCVALUE_UNICHAR:
11690 generate_code_expr_encvalue_unichar(expr);
11691 break;
11692 case OPTYPE_DECVALUE_UNICHAR:
11693 generate_code_expr_decvalue_unichar(expr);
11694 break;
11695 case OPTYPE_OCT2HEX:
11696 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11697 break;
11698 case OPTYPE_OCT2INT:
11699 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11700 break;
11701 case OPTYPE_OCT2STR:
11702 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11703 break;
11704 case OPTYPE_STR2BIT:
11705 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11706 break;
11707 case OPTYPE_STR2FLOAT:
11708 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11709 break;
11710 case OPTYPE_STR2HEX:
11711 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11712 break;
11713 case OPTYPE_STR2INT:
11714 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11715 break;
11716 case OPTYPE_STR2OCT:
11717 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11718 break;
11719 case OPTYPE_UNICHAR2INT:
11720 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11721 break;
11722 case OPTYPE_UNICHAR2CHAR:
11723 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11724 break;
11725 case OPTYPE_ENUM2INT: {
11726 Type* enum_type = u.expr.v1->get_expr_governor_last();
11727 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11728 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11729 enum_type->get_genname_value(my_scope).c_str());
11730 u.expr.v1->generate_code_expr_mandatory(expr);
11731 expr->expr = mputc(expr->expr, ')');
11732 break;}
11733 case OPTYPE_ENCODE:
11734 generate_code_expr_encode(expr);
11735 break;
11736 case OPTYPE_DECODE:
11737 generate_code_expr_decode(expr);
11738 break;
11739 case OPTYPE_RNDWITHVAL:
11740 generate_code_expr_rnd(expr, u.expr.v1);
11741 break;
11742 case OPTYPE_ADD:
11743 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11744 break;
11745 case OPTYPE_SUBTRACT:
11746 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11747 break;
11748 case OPTYPE_MULTIPLY:
11749 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11750 break;
11751 case OPTYPE_DIVIDE:
11752 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11753 break;
11754 case OPTYPE_MOD:
11755 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11756 break;
11757 case OPTYPE_REM:
11758 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11759 break;
11760 case OPTYPE_CONCAT:
11761 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11762 break;
11763 case OPTYPE_EQ:
11764 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11765 break;
11766 case OPTYPE_LT:
11767 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11768 break;
11769 case OPTYPE_GT:
11770 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11771 break;
11772 case OPTYPE_NE:
11773 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11774 break;
11775 case OPTYPE_GE:
11776 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11777 break;
11778 case OPTYPE_LE:
11779 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11780 break;
11781 case OPTYPE_AND:
11782 case OPTYPE_OR:
11783 generate_code_expr_and_or(expr);
11784 break;
11785 case OPTYPE_XOR:
11786 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11787 break;
11788 case OPTYPE_AND4B:
11789 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11790 break;
11791 case OPTYPE_OR4B:
11792 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11793 break;
11794 case OPTYPE_XOR4B:
11795 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11796 break;
11797 case OPTYPE_SHL:
11798 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11799 break;
11800 case OPTYPE_SHR:
11801 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11802 break;
11803 case OPTYPE_ROTL:
11804 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11805 break;
11806 case OPTYPE_ROTR:
11807 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11808 break;
11809 case OPTYPE_INT2BIT:
11810 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11811 break;
11812 case OPTYPE_INT2HEX:
11813 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11814 break;
11815 case OPTYPE_INT2OCT:
11816 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11817 break;
11818 case OPTYPE_SUBSTR:
11819 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11820 else generate_code_expr_substr_replace_compat(expr);
11821 break;
11822 case OPTYPE_REGEXP:
11823 generate_code_expr_regexp(expr);
11824 break;
11825 case OPTYPE_DECOMP:
11826 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11827 break;
11828 case OPTYPE_REPLACE:
11829 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11830 else generate_code_expr_substr_replace_compat(expr);
11831 break;
11832 case OPTYPE_ISCHOSEN: // r1 i2
11833 FATAL_ERROR("Value::generate_code_expr_expr()");
11834 break;
11835 case OPTYPE_ISCHOSEN_V: // v1 i2
11836 u.expr.v1->generate_code_expr_mandatory(expr);
11837 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11838 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11839 u.expr.i2->get_name().c_str());
11840 break;
11841 case OPTYPE_ISCHOSEN_T: // t1 i2
11842 u.expr.t1->generate_code_expr(expr);
11843 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11844 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11845 u.expr.i2->get_name().c_str());
11846 break;
11847 case OPTYPE_ISPRESENT:
11848 case OPTYPE_ISBOUND: {
11849 Template::templatetype_t temp = u.expr.ti1->get_Template()
11850 ->get_templatetype();
11851 if (temp == Template::SPECIFIC_VALUE) {
11852 Value* specific_value = u.expr.ti1->get_Template()
11853 ->get_specific_value();
11854 if (specific_value->get_valuetype() == Value::V_REFD) {
11855 Ttcn::Reference* reference =
11856 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11857 if (reference) {
11858 reference->generate_code_ispresentbound(expr, false,
11859 u.expr.v_optype==OPTYPE_ISBOUND);
11860 break;
11861 }
11862 }
11863 } else if (temp == Template::TEMPLATE_REFD){
11864 Ttcn::Reference* reference =
11865 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11866 ->get_reference());
11867 if (reference) {
11868 reference->generate_code_ispresentbound(expr, true,
11869 u.expr.v_optype==OPTYPE_ISBOUND);
11870 break;
11871 }
11872 }
11873 }
11874 // no break
11875 case OPTYPE_LENGTHOF: // ti1
11876 // fall through, separated later
11877 case OPTYPE_SIZEOF: // ti1
11878 // fall through, separated later
11879 case OPTYPE_ISVALUE: { // ti1
11880 if (u.expr.ti1->is_only_specific_value()) {
11881 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11882 bool cast_needed = t_val->explicit_cast_needed(
11883 u.expr.v_optype != OPTYPE_LENGTHOF);
11884 if(cast_needed) {
11885 // the ambiguous C++ expression is converted to the value class
11886 expr->expr = mputprintf(expr->expr, "%s(",
11887 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11888 }
11889
11890 if (u.expr.v_optype != OPTYPE_LENGTHOF
11891 && u.expr.v_optype != OPTYPE_SIZEOF) {
11892 t_val->generate_code_expr(expr);
11893 } else {
11894 t_val->generate_code_expr_mandatory(expr);
11895 }
11896
11897 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11898 }
11899 else u.expr.ti1->generate_code(expr);
11900
11901 switch (u.expr.v_optype) {
11902 case OPTYPE_ISBOUND:
11903 expr->expr=mputstr(expr->expr, ".is_bound()");
11904 break;
11905 case OPTYPE_ISPRESENT:
11906 expr->expr=mputprintf(expr->expr, ".is_present()");
11907 break;
11908 case OPTYPE_SIZEOF:
11909 expr->expr=mputstr(expr->expr, ".size_of()");
11910 break;
11911 case OPTYPE_LENGTHOF:
11912 expr->expr=mputstr(expr->expr, ".lengthof()");
11913 break;
11914 case OPTYPE_ISVALUE:
11915 expr->expr=mputstr(expr->expr, ".is_value()");
11916 break;
11917 default:
11918 FATAL_ERROR("Value::generate_code_expr_expr()");
11919 }
11920 break; }
11921 case OPTYPE_VALUEOF: // ti1
11922 u.expr.ti1->generate_code(expr);
11923 expr->expr = mputstr(expr->expr, ".valueof()");
11924 break;
11925 case OPTYPE_MATCH: // v1 t2
11926 u.expr.t2->generate_code(expr);
11927 expr->expr = mputstr(expr->expr, ".match(");
11928 u.expr.v1->generate_code_expr(expr);
11929 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11930 break;
11931 case OPTYPE_UNDEF_RUNNING:
11932 // it is resolved during semantic check
11933 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
11934 break;
11935 case OPTYPE_COMP_NULL: // -
11936 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
11937 break;
11938 case OPTYPE_COMP_MTC: // -
11939 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
11940 break;
11941 case OPTYPE_COMP_SYSTEM: // -
11942 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
11943 break;
11944 case OPTYPE_COMP_SELF: // -
11945 expr->expr=mputstr(expr->expr, "self");
11946 break;
11947 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
11948 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
11949 u.expr.b4);
11950 break;
11951 case OPTYPE_COMP_RUNNING: // v1
11952 u.expr.v1->generate_code_expr(expr);
11953 if(u.expr.v1->get_valuetype() == V_REFD)
11954 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11955 expr->expr = mputstr(expr->expr, ".running()");
11956 break;
11957 case OPTYPE_COMP_RUNNING_ANY: // -
11958 expr->expr=mputstr(expr->expr,
11959 "TTCN_Runtime::component_running(ANY_COMPREF)");
11960 break;
11961 case OPTYPE_COMP_RUNNING_ALL: // -
11962 expr->expr=mputstr(expr->expr,
11963 "TTCN_Runtime::component_running(ALL_COMPREF)");
11964 break;
11965 case OPTYPE_COMP_ALIVE: // v1
11966 u.expr.v1->generate_code_expr(expr);
11967 if(u.expr.v1->get_valuetype() == V_REFD)
11968 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
11969 expr->expr = mputstr(expr->expr, ".alive()");
11970 break;
11971 case OPTYPE_COMP_ALIVE_ANY: // -
11972 expr->expr = mputstr(expr->expr,
11973 "TTCN_Runtime::component_alive(ANY_COMPREF)");
11974 break;
11975 case OPTYPE_COMP_ALIVE_ALL: // -
11976 expr->expr = mputstr(expr->expr,
11977 "TTCN_Runtime::component_alive(ALL_COMPREF)");
11978 break;
11979 case OPTYPE_TMR_READ: // r1
11980 u.expr.r1->generate_code(expr);
11981 expr->expr = mputstr(expr->expr, ".read()");
11982 break;
11983 case OPTYPE_TMR_RUNNING: // r1
11984 u.expr.r1->generate_code(expr);
11985 expr->expr = mputstr(expr->expr, ".running()");
11986 break;
11987 case OPTYPE_TMR_RUNNING_ANY: // -
11988 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
11989 break;
11990 case OPTYPE_GETVERDICT: // -
11991 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
11992 break;
11993 case OPTYPE_TESTCASENAME: // -
11994 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
11995 break;
11996 case OPTYPE_ACTIVATE: // r1
11997 generate_code_expr_activate(expr);
11998 break;
11999 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
12000 generate_code_expr_activate_refd(expr);
12001 break;
12002 case OPTYPE_EXECUTE: // r1 [v2]
12003 generate_code_expr_execute(expr);
12004 break;
12005 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
12006 generate_code_expr_execute_refd(expr);
12007 break;
12008 case OPTYPE_LOG2STR:
12009 u.expr.logargs->generate_code_expr(expr);
12010 break;
12011 case OPTYPE_TTCN2STRING: {
12012 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
12013 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
12014 param_governor = param_governor->get_type_refd_last();
12015 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
12016 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
12017 u.expr.ti1->get_Template()->is_Value()) {
12018 Value* v = u.expr.ti1->get_Template()->get_Value();
12019 delete u.expr.ti1;
12020 u.expr.ti1 = NULL;
12021 bool cast_needed = v->explicit_cast_needed();
12022 if (cast_needed) {
12023 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
12024 }
12025 v->generate_code_expr(expr);
12026 if (cast_needed) {
12027 expr->expr = mputstr(expr->expr, ")");
12028 }
12029 delete v;
12030 } else {
12031 u.expr.ti1->generate_code(expr);
12032 }
12033 expr->expr = mputstr(expr->expr, ")");
12034 } break;
12035 case OPTYPE_PROF_RUNNING:
12036 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
12037 break;
12038 default:
12039 FATAL_ERROR("Value::generate_code_expr_expr()");
12040 }
12041 }
12042
12043 void Value::generate_code_expr_unary(expression_struct *expr,
12044 const char *operator_str, Value *v1)
12045 {
12046 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
12047 v1->generate_code_expr_mandatory(expr);
12048 expr->expr = mputstrn(expr->expr, "))", 2);
12049 }
12050
12051 void Value::generate_code_expr_infix(expression_struct *expr,
12052 const char *operator_str, Value *v1,
12053 Value *v2, bool optional_allowed)
12054 {
12055 if (!get_needs_conversion()) {
12056 expr->expr = mputc(expr->expr, '(');
12057 if (optional_allowed) v1->generate_code_expr(expr);
12058 else v1->generate_code_expr_mandatory(expr);
12059 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
12060 if (optional_allowed) v2->generate_code_expr(expr);
12061 else v2->generate_code_expr_mandatory(expr);
12062 expr->expr = mputc(expr->expr, ')');
12063 } else { // Temporary variable for the converted value.
12064 const string& tmp_id1 = get_temporary_id();
12065 const char *tmp_id_str1 = tmp_id1.c_str();
12066 expression_struct expr_tmp;
12067 Code::init_expr(&expr_tmp);
12068 switch (u.expr.v_optype) {
12069 case OPTYPE_EQ:
12070 case OPTYPE_NE: {
12071 // Always "v1 -> v2".
12072 Type *t1 = v1->get_expr_governor_last();
12073 Type *t2 = v2->get_expr_governor_last();
12074 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
12075 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12076 else v2->generate_code_expr_mandatory(&expr_tmp);
12077 if (expr_tmp.preamble)
12078 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12079 expr->preamble = mputprintf(expr->preamble,
12080 "%s %s;\n"
12081 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12082 "and `%s' are not compatible at run-time\");\n",
12083 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
12084 TypeConv::get_conv_func(t2, t1, get_my_scope()
12085 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
12086 t2->get_typename().c_str(), t1->get_typename().c_str());
12087 Code::free_expr(&expr_tmp);
12088 if (optional_allowed) v1->generate_code_expr(expr);
12089 else v1->generate_code_expr_mandatory(expr);
12090 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
12091 tmp_id_str1);
12092 break; }
12093 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12094 // functions. The governors of all operands must exist at this point.
12095 case OPTYPE_ROTL:
12096 case OPTYPE_ROTR:
12097 case OPTYPE_CONCAT: {
12098 const string& tmp_id2 = get_temporary_id();
12099 const char *tmp_id_str2 = tmp_id2.c_str();
12100 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
12101 Type *my_gov = my_governor->get_type_refd_last();
12102 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
12103 ->get_type_refd_last();
12104 if (!t1_gov || my_gov == t1_gov)
12105 FATAL_ERROR("Value::generate_code_expr_infix()");
12106 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
12107 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
12108 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
12109 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
12110 else v1->generate_code_expr_mandatory(&expr_tmp);
12111 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
12112 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12113 else v2->generate_code_expr_mandatory(&expr_tmp);
12114 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
12115 expr->preamble = mputprintf(expr->preamble,
12116 "%s %s;\n"
12117 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12118 "and `%s' are not compatible at run-time\");\n",
12119 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
12120 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
12121 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
12122 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
12123 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
12124 break; }
12125 default:
12126 FATAL_ERROR("Value::generate_code_expr_infix()");
12127 break;
12128 }
12129 }
12130 }
12131
12132 void Value::generate_code_expr_and_or(expression_struct *expr)
12133 {
12134 if (u.expr.v2->needs_short_circuit()) {
12135 // introduce a temporary variable to store the result of the operation
12136 const string& tmp_id = get_temporary_id();
12137 const char *tmp_id_str = tmp_id.c_str();
12138 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
12139 expression_struct expr2;
12140 // the left operand must be evaluated anyway
12141 Code::init_expr(&expr2);
12142 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12143 u.expr.v1->generate_code_expr_mandatory(&expr2);
12144 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12145 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
12146 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
12147 // evaluate the right operand only when necessary
12148 // in this case the final result will be the right operand
12149 Code::init_expr(&expr2);
12150 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12151 u.expr.v2->generate_code_expr_mandatory(&expr2);
12152 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12153 // the result is now in the temporary variable
12154 expr->expr = mputstr(expr->expr, tmp_id_str);
12155 } else {
12156 // use the overloaded operator to get better error messages
12157 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
12158 "&&" : "||", u.expr.v1, u.expr.v2, false);
12159 }
12160 }
12161
12162 void Value::generate_code_expr_predef1(expression_struct *expr,
12163 const char *function_name,
12164 Value *v1)
12165 {
12166 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12167 v1->generate_code_expr_mandatory(expr);
12168 expr->expr = mputc(expr->expr, ')');
12169 }
12170
12171 void Value::generate_code_expr_predef2(expression_struct *expr,
12172 const char *function_name,
12173 Value *v1, Value *v2)
12174 {
12175 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12176 v1->generate_code_expr_mandatory(expr);
12177 expr->expr = mputstr(expr->expr, ", ");
12178 v2->generate_code_expr_mandatory(expr);
12179 expr->expr = mputc(expr->expr, ')');
12180 }
12181
12182 void Value::generate_code_expr_predef3(expression_struct *expr,
12183 const char *function_name,
12184 Value *v1, Value *v2, Value *v3)
12185 {
12186 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12187 v1->generate_code_expr_mandatory(expr);
12188 expr->expr = mputstr(expr->expr, ", ");
12189 v2->generate_code_expr_mandatory(expr);
12190 expr->expr = mputstr(expr->expr, ", ");
12191 v3->generate_code_expr_mandatory(expr);
12192 expr->expr = mputc(expr->expr, ')');
12193 }
12194
12195 void Value::generate_code_expr_substr(expression_struct *expr)
12196 {
12197 bool par1_is_str;
12198 Value* v1 = u.expr.ti1->get_specific_value();
12199 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12200 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12201 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
12202 if (v1) v1->generate_code_expr_mandatory(expr);
12203 else u.expr.ti1->generate_code(expr);
12204 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12205 else expr->expr = mputstr(expr->expr, ".substr(");
12206 if (!par1_is_str && u.expr.v2->is_unfoldable())
12207 expr->expr = mputstr(expr->expr, "(int)");
12208 u.expr.v2->generate_code_expr_mandatory(expr);
12209 expr->expr = mputstr(expr->expr, ", ");
12210 if (!par1_is_str && u.expr.v3->is_unfoldable())
12211 expr->expr = mputstr(expr->expr, "(int)");
12212 u.expr.v3->generate_code_expr_mandatory(expr);
12213 expr->expr = mputc(expr->expr, ')');
12214 }
12215
12216 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
12217 {
12218 expression_struct expr_tmp;
12219 Code::init_expr(&expr_tmp);
12220 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
12221 ->get_type_refd_last();
12222 if (!t1 || t1 == my_governor->get_type_refd_last())
12223 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12224 if (u.expr.v_optype == OPTYPE_SUBSTR) {
12225 generate_code_expr_substr(&expr_tmp);
12226 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
12227 generate_code_expr_replace(&expr_tmp);
12228 } else {
12229 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12230 }
12231 // Two temporaries to store the result of substr() or replace() and to
12232 // store the converted value.
12233 const string& tmp_id1 = get_temporary_id();
12234 const char *tmp_id_str1 = tmp_id1.c_str();
12235 const string& tmp_id2 = get_temporary_id();
12236 const char *tmp_id_str2 = tmp_id2.c_str();
12237 if (expr_tmp.preamble)
12238 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12239 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12240 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12241 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12242 if (expr_tmp.postamble)
12243 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12244 Code::free_expr(&expr_tmp);
12245 expr->preamble = mputprintf(expr->preamble,
12246 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12247 "`%s' are not compatible at run-time\");\n",
12248 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12249 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12250 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12251 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12252 }
12253
12254 void Value::generate_code_expr_regexp(expression_struct *expr)
12255 {
12256 Value* v1 = u.expr.ti1->get_specific_value();
12257 Value* v2 = u.expr.t2->get_specific_value();
12258 expr->expr = mputstr(expr->expr, "regexp(");
12259 if (v1) v1->generate_code_expr_mandatory(expr);
12260 else u.expr.ti1->generate_code(expr);
12261 expr->expr = mputstr(expr->expr, ", ");
12262 if (v2) v2->generate_code_expr_mandatory(expr);
12263 else u.expr.t2->generate_code(expr);
12264 expr->expr = mputstr(expr->expr, ", ");
12265 u.expr.v3->generate_code_expr_mandatory(expr);
12266 expr->expr = mputc(expr->expr, ')');
12267 }
12268
12269 void Value::generate_code_expr_replace(expression_struct *expr)
12270 {
12271 Value* v1 = u.expr.ti1->get_specific_value();
12272 Value* v4 = u.expr.ti4->get_specific_value();
12273 bool par1_is_str;
12274 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12275 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12276 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12277 if (v1) v1->generate_code_expr_mandatory(expr);
12278 else u.expr.ti1->generate_code(expr);
12279 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12280 else expr->expr = mputstr(expr->expr, ".replace(");
12281 if (!par1_is_str && u.expr.v2->is_unfoldable())
12282 expr->expr = mputstr(expr->expr, "(int)");
12283 u.expr.v2->generate_code_expr_mandatory(expr);
12284 expr->expr = mputstr(expr->expr, ", ");
12285 if (!par1_is_str && u.expr.v3->is_unfoldable())
12286 expr->expr = mputstr(expr->expr, "(int)");
12287 u.expr.v3->generate_code_expr_mandatory(expr);
12288 expr->expr = mputstr(expr->expr, ", ");
12289 if (v4) {
12290 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12291 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12292 Value* v4_last = v4->get_value_refd_last();
12293 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12294 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12295 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
12296 }
12297 v4->generate_code_expr_mandatory(expr);
12298 }
12299 else u.expr.ti4->generate_code(expr);
12300 expr->expr = mputc(expr->expr, ')');
12301 }
12302
12303 void Value::generate_code_expr_rnd(expression_struct *expr,
12304 Value *v1)
12305 {
12306 if(!v1) // simple random generation
12307 expr->expr = mputstr(expr->expr, "rnd()");
12308 else { // random generation with seeding
12309 expr->expr = mputstr(expr->expr, "rnd(");
12310 v1->generate_code_expr_mandatory(expr);
12311 expr->expr = mputc(expr->expr, ')');
12312 }
12313 }
12314
12315 void Value::generate_code_expr_create(expression_struct *expr,
12316 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12317 {
12318 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12319 // first two arguments: component type
12320 Assignment *t_ass = type->get_refd_assignment();
12321 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12322 FATAL_ERROR("Value::generate_code_expr_create()");
12323 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12324 Type::EXPECTED_DYNAMIC_VALUE);
12325 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12326 comptype = comptype->get_type_refd_last();
12327 expr->expr = comptype->get_CompBody()
12328 ->generate_code_comptype_name(expr->expr);
12329 expr->expr = mputstr(expr->expr, ", ");
12330 // third argument: component name
12331 if (name) {
12332 Value *t_val = name->get_value_refd_last();
12333 if (t_val->valuetype == V_CSTR) {
12334 // the argument is foldable to a string literal
12335 size_t str_len = t_val->u.str.val_str->size();
12336 const char *str_ptr = t_val->u.str.val_str->c_str();
12337 expr->expr = mputc(expr->expr, '"');
12338 for (size_t i = 0; i < str_len; i++)
12339 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12340 expr->expr = mputc(expr->expr, '"');
12341 } else name->generate_code_expr_mandatory(expr);
12342 } else expr->expr = mputstr(expr->expr, "NULL");
12343 expr->expr = mputstr(expr->expr, ", ");
12344 // fourth argument: location
12345 if (location) {
12346 Value *t_val = location->get_value_refd_last();
12347 if (t_val->valuetype == V_CSTR) {
12348 // the argument is foldable to a string literal
12349 size_t str_len = t_val->u.str.val_str->size();
12350 const char *str_ptr = t_val->u.str.val_str->c_str();
12351 expr->expr = mputc(expr->expr, '"');
12352 for (size_t i = 0; i < str_len; i++)
12353 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12354 expr->expr = mputc(expr->expr, '"');
12355 } else location->generate_code_expr_mandatory(expr);
12356 } else expr->expr = mputstr(expr->expr, "NULL");
12357 // fifth argument: alive flag
12358 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12359 }
12360
12361 void Value::generate_code_expr_activate(expression_struct *expr)
12362 {
12363 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12364 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12365 FATAL_ERROR("Value::generate_code_expr_activate()");
12366 expr->expr = mputprintf(expr->expr, "%s(",
12367 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12368 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12369 expr->expr = mputc(expr->expr, ')');
12370 }
12371
12372 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12373 {
12374 Value *v_last = u.expr.v1->get_value_refd_last();
12375 if (v_last->valuetype == V_ALTSTEP) {
12376 // the referred altstep is known
12377 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12378 ->get_genname_from_scope(my_scope, "activate_").c_str());
12379 } else {
12380 // the referred altstep is unknown
12381 u.expr.v1->generate_code_expr_mandatory(expr);
12382 expr->expr = mputstr(expr->expr,".activate(");
12383 }
12384 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12385 expr->expr = mputc(expr->expr, ')');
12386 }
12387
12388 void Value::generate_code_expr_execute(expression_struct *expr)
12389 {
12390 Assignment *testcase = u.expr.r1->get_refd_assignment();
12391 expr->expr = mputprintf(expr->expr, "%s(",
12392 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12393 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12394 if (parlist->get_nof_pars() > 0) {
12395 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12396 0, false);
12397 expr->expr = mputstr(expr->expr, ", ");
12398 }
12399 if (u.expr.v2) {
12400 expr->expr = mputstr(expr->expr, "TRUE, ");
12401 u.expr.v2->generate_code_expr_mandatory(expr);
12402 expr->expr = mputc(expr->expr, ')');
12403 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12404 }
12405
12406 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12407 {
12408 Value *v_last = u.expr.v1->get_value_refd_last();
12409 if (v_last->valuetype == V_TESTCASE) {
12410 // the referred testcase is known
12411 Assignment *testcase = v_last->get_refd_fat();
12412 expr->expr = mputprintf(expr->expr, "%s(",
12413 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12414 u.expr.ap_list2->generate_code_alias(expr,
12415 testcase->get_FormalParList(), 0, false);
12416 } else {
12417 // the referred testcase is unknown
12418 u.expr.v1->generate_code_expr_mandatory(expr);
12419 expr->expr = mputstr(expr->expr,".execute(");
12420 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12421 }
12422 if (u.expr.ap_list2->get_nof_pars() > 0)
12423 expr->expr = mputstr(expr->expr, ", ");
12424 if (u.expr.v3) {
12425 expr->expr = mputstr(expr->expr, "TRUE, ");
12426 u.expr.v3->generate_code_expr_mandatory(expr);
12427 expr->expr = mputc(expr->expr, ')');
12428 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12429 }
12430
12431 void Value::generate_code_expr_invoke(expression_struct *expr)
12432 {
12433 Value *last_v = u.invoke.v->get_value_refd_last();
12434 if (last_v->get_valuetype() == V_FUNCTION) {
12435 // the referred function is known
12436 Assignment *function = last_v->get_refd_fat();
12437 expr->expr = mputprintf(expr->expr, "%s(",
12438 function->get_genname_from_scope(my_scope).c_str());
12439 u.invoke.ap_list->generate_code_alias(expr,
12440 function->get_FormalParList(), function->get_RunsOnType(), false);
12441 } else {
12442 // the referred function is unknown
12443 u.invoke.v->generate_code_expr_mandatory(expr);
12444 expr->expr = mputstr(expr->expr, ".invoke(");
12445 Type* gov_last = last_v->get_expr_governor_last();
12446 u.invoke.ap_list->generate_code_alias(expr, 0,
12447 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12448 }
12449 expr->expr = mputc(expr->expr, ')');
12450 }
12451
12452 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12453 Reference *ref)
12454 {
12455 // if the referenced value points to an optional value field the
12456 // generated code has to be corrected at the end:
12457 // `fieldid()' => `fieldid()()'
12458 Assignment *ass = ref->get_refd_assignment();
12459 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12460 switch (ass->get_asstype()) {
12461 case Assignment::A_CONST:
12462 case Assignment::A_EXT_CONST:
12463 case Assignment::A_MODULEPAR:
12464 case Assignment::A_VAR:
12465 case Assignment::A_FUNCTION_RVAL:
12466 case Assignment::A_EXT_FUNCTION_RVAL:
12467 case Assignment::A_PAR_VAL_IN:
12468 case Assignment::A_PAR_VAL_OUT:
12469 case Assignment::A_PAR_VAL_INOUT:
12470 // only these are mapped to value objects
12471 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12472 expr->expr = mputstr(expr->expr, "()");
12473 break;
12474 default:
12475 break;
12476 }
12477 }
12478
12479 void Value::generate_code_expr_encode(expression_struct *expr)
12480 {
12481 Value* v1 = 0;
12482
12483 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12484 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12485 v1 = templ->get_specific_value();
12486 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12487
12488 expression_struct expr2;
12489 Code::init_expr(&expr2);
12490
12491 bool is_templ = false;
12492 switch (templ->get_templatetype()) {
12493 case Template::SPECIFIC_VALUE:
12494 v1->generate_code_expr_mandatory(&expr2);
12495 break;
12496 default:
12497 u.expr.ti1->generate_code(&expr2);
12498 is_templ = true;
12499 break;
12500 }
12501
12502 if (!gov_last->is_coding_by_function()) {
12503 const string& tmp_id = get_temporary_id();
12504 const string& tmp_buf_id = get_temporary_id();
12505 const string& tmp_ref_id = get_temporary_id();
12506 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12507 tmp_id.c_str());
12508 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12509 tmp_buf_id.c_str());
12510 if (expr2.preamble) { // copy preamble setting up the argument, if any
12511 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12512 expr->preamble = mputc (expr->preamble, '\n');
12513 }
12514 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12515 gov_last->get_genname_typedescriptor(
12516 u.expr.ti1->get_Template()->get_my_scope()
12517 ).c_str(),
12518 tmp_ref_id.c_str(),
12519 expr2.expr);
12520 if (is_templ) // make a value out of the template, if needed
12521 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12522 expr->preamble = mputprintf(expr->preamble,
12523 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12524 tmp_ref_id.c_str(),
12525 gov_last->get_genname_typedescriptor(
12526 u.expr.ti1->get_Template()->get_my_scope()
12527 ).c_str(),
12528 tmp_buf_id.c_str(),
12529 gov_last->get_coding(true).c_str()
12530 );
12531 expr->preamble = mputstr(expr->preamble, ");\n");
12532 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12533 tmp_buf_id.c_str(),
12534 tmp_id.c_str()
12535 );
12536 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12537 if (expr2.postamble)
12538 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12539 } else
12540 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12541 gov_last->get_coding(true).c_str(), expr2.expr,
12542 is_templ ? ".valueof()" : "");
12543 Code::free_expr(&expr2);
12544 }
12545
12546 void Value::generate_code_expr_decode(expression_struct *expr)
12547 {
12548 expression_struct expr1, expr2;
12549 Code::init_expr(&expr1);
12550 Code::init_expr(&expr2);
12551 u.expr.r1->generate_code(&expr1);
12552 u.expr.r2->generate_code(&expr2);
12553
12554 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12555 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12556 get_type_refd_last();
12557
12558 if (expr1.preamble)
12559 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12560 if (expr2.preamble)
12561 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12562
12563 if (!_type->is_coding_by_function()) {
12564 const string& tmp_id = get_temporary_id();
12565 const string& buffer_id = get_temporary_id();
12566 const string& retval_id = get_temporary_id();
12567 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12568 field_is_optional(u.expr.r2->get_subrefs());
12569
12570 expr->preamble = mputprintf(expr->preamble,
12571 "TTCN_Buffer %s(bit2oct(%s));\n"
12572 "INTEGER %s;\n"
12573 "TTCN_EncDec::set_error_behavior("
12574 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12575 "TTCN_EncDec::clear_error();\n",
12576 buffer_id.c_str(),
12577 expr1.expr,
12578 retval_id.c_str()
12579 );
12580 expr->preamble = mputprintf(expr->preamble,
12581 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12582 expr2.expr,
12583 optional ? "()" : "",
12584 _type->get_genname_typedescriptor(
12585 u.expr.r2->get_my_scope()
12586 ).c_str(),
12587 buffer_id.c_str(),
12588 _type->get_coding(false).c_str()
12589 );
12590 expr->preamble = mputprintf(expr->preamble,
12591 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12592 "case TTCN_EncDec::ET_NONE: {\n"
12593 "%s.cut();\n"
12594 "OCTETSTRING %s;\n"
12595 "%s.get_string(%s);\n"
12596 "%s = oct2bit(%s);\n"
12597 "%s = 0;\n"
12598 "}break;\n"
12599 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12600 "case TTCN_EncDec::ET_LEN_ERR:\n"
12601 "%s = 2;\n"
12602 "break;\n"
12603 "default:\n"
12604 "%s = 1;\n"
12605 "}\n"
12606 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12607 "TTCN_EncDec::EB_DEFAULT);\n"
12608 "TTCN_EncDec::clear_error();\n",
12609 buffer_id.c_str(),
12610 tmp_id.c_str(),
12611 buffer_id.c_str(),
12612 tmp_id.c_str(),
12613 expr1.expr,
12614 tmp_id.c_str(),
12615 retval_id.c_str(),
12616 retval_id.c_str(),
12617 retval_id.c_str()
12618 );
12619 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12620 } else
12621 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12622 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12623 if (expr1.postamble)
12624 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12625 if (expr2.postamble)
12626 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12627 Code::free_expr(&expr1);
12628 Code::free_expr(&expr2);
12629 }
12630
12631 void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
12632 {
12633 Value* v1 = 0;
12634
12635 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12636 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12637 v1 = templ->get_specific_value();
12638 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12639
12640 expression_struct expr2;
12641 Code::init_expr(&expr2);
12642
12643 bool is_templ = false;
12644 switch (templ->get_templatetype()) {
12645 case Template::SPECIFIC_VALUE:
12646 v1->generate_code_expr_mandatory(&expr2);
12647 break;
12648 default:
12649 u.expr.ti1->generate_code(&expr2);
12650 is_templ = true;
12651 break;
12652 }
12653
12654 if (!gov_last->is_coding_by_function()) {
12655 const string& tmp_id = get_temporary_id();
12656 const string& tmp_buf_id = get_temporary_id();
12657 const string& tmp_ref_id = get_temporary_id();
12658 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12659 tmp_id.c_str());
12660 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12661 tmp_buf_id.c_str());
12662 if (expr2.preamble) { // copy preamble setting up the argument, if any
12663 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12664 expr->preamble = mputc (expr->preamble, '\n');
12665 }
12666 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12667 gov_last->get_genname_typedescriptor(
12668 u.expr.ti1->get_Template()->get_my_scope()
12669 ).c_str(),
12670 tmp_ref_id.c_str(),
12671 expr2.expr);
12672 if (is_templ) // make a value out of the template, if needed
12673 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12674 expr->preamble = mputprintf(expr->preamble,
12675 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12676 tmp_ref_id.c_str(),
12677 gov_last->get_genname_typedescriptor(
12678 u.expr.ti1->get_Template()->get_my_scope()
12679 ).c_str(),
12680 tmp_buf_id.c_str(),
12681 gov_last->get_coding(true).c_str()
12682 );
12683 expr->preamble = mputstr(expr->preamble, ");\n");
12684 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12685 tmp_buf_id.c_str(),
12686 tmp_id.c_str()
12687 );
12688 const char * v2_code = NULL;
12689 if(u.expr.v2) {
12690 v2_code = generate_code_char_coding_check(expr, u.expr.v2, "encvalue_unichar");
12691 }
12692 expr->expr = mputprintf(expr->expr, "oct2unichar(%s", tmp_id.c_str());
12693 if(u.expr.v2) {
12694 expr->expr = mputprintf(expr->expr, ", %s", v2_code);
12695 } else {
12696 expr->expr = mputprintf(expr->expr, ", \"UTF-8\""); //default
12697 }
12698 expr->expr = mputprintf(expr->expr, ")");
12699 if (expr2.postamble)
12700 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12701 } else
12702 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12703 gov_last->get_coding(true).c_str(), expr2.expr,
12704 is_templ ? ".valueof()" : "");
12705 Code::free_expr(&expr2);
12706 }
12707
12708 void Value::generate_code_expr_decvalue_unichar(expression_struct *expr)
12709 {
12710 expression_struct expr1, expr2;
12711 Code::init_expr(&expr1);
12712 Code::init_expr(&expr2);
12713 u.expr.r1->generate_code(&expr1);
12714 u.expr.r2->generate_code(&expr2);
12715
12716 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12717 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12718 get_type_refd_last();
12719
12720 if (expr1.preamble)
12721 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12722 if (expr2.preamble)
12723 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12724
12725 if (!_type->is_coding_by_function()) {
12726 const string& tmp_id = get_temporary_id();
12727 const string& buffer_id = get_temporary_id();
12728 const string& retval_id = get_temporary_id();
12729 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12730 field_is_optional(u.expr.r2->get_subrefs());
12731
12732 const char* v3_code = NULL;
12733 if(u.expr.v3) {
12734 v3_code = generate_code_char_coding_check(expr, u.expr.v3, "decvalue_unichar");
12735 }
12736 expr->preamble = mputprintf(expr->preamble,
12737 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12738 "INTEGER %s;\n"
12739 "TTCN_EncDec::set_error_behavior("
12740 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12741 "TTCN_EncDec::clear_error();\n",
12742 buffer_id.c_str(),
12743 expr1.expr,
12744 u.expr.v3 ? v3_code : "\"UTF-8\"",
12745 retval_id.c_str()
12746 );
12747 expr->preamble = mputprintf(expr->preamble,
12748 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12749 expr2.expr,
12750 optional ? "()" : "",
12751 _type->get_genname_typedescriptor(
12752 u.expr.r2->get_my_scope()
12753 ).c_str(),
12754 buffer_id.c_str(),
12755 _type->get_coding(false).c_str()
12756 );
12757 expr->preamble = mputprintf(expr->preamble,
12758 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12759 "case TTCN_EncDec::ET_NONE: {\n"
12760 "%s.cut();\n"
12761 "OCTETSTRING %s;\n"
12762 "%s.get_string(%s);\n"
12763 "%s = oct2unichar(%s, %s);\n"
12764 "%s = 0;\n"
12765 "}break;\n"
12766 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12767 "case TTCN_EncDec::ET_LEN_ERR:\n"
12768 "%s = 2;\n"
12769 "break;\n"
12770 "default:\n"
12771 "%s = 1;\n"
12772 "}\n"
12773 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12774 "TTCN_EncDec::EB_DEFAULT);\n"
12775 "TTCN_EncDec::clear_error();\n",
12776 buffer_id.c_str(),
12777 tmp_id.c_str(),
12778 buffer_id.c_str(),
12779 tmp_id.c_str(),
12780 expr1.expr,
12781 tmp_id.c_str(),
12782 u.expr.v3 ? v3_code : "\"UTF-8\"",
12783 retval_id.c_str(),
12784 retval_id.c_str(),
12785 retval_id.c_str()
12786 );
12787 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12788 } else
12789 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12790 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12791 if (expr1.postamble)
12792 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12793 if (expr2.postamble)
12794 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12795 Code::free_expr(&expr1);
12796 Code::free_expr(&expr2);
12797 }
12798
12799 char* Value::generate_code_char_coding_check(expression_struct *expr, Value *v, const char *name)
12800 {
12801 expression_struct expr2;
12802 Code::init_expr(&expr2);
12803 v->generate_code_expr_mandatory(&expr2);
12804 expr->preamble = mputprintf(expr->preamble,
12805 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12806 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12807 " \"UTF-32BE\" != %s) {\n"
12808 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12809 "}\n", //todo errorbehaviour?
12810 expr2.expr,
12811 expr2.expr,
12812 expr2.expr,
12813 expr2.expr,
12814 expr2.expr,
12815 expr2.expr,
12816 expr2.expr,
12817 name,
12818 expr2.expr);
12819 return expr2.expr;
12820 }
12821
12822 char *Value::generate_code_init_choice(char *str, const char *name)
12823 {
12824 const char *alt_name = u.choice.alt_name->get_name().c_str();
12825 // Safe as long as get_name() returns a const string&, not a temporary.
12826 const char *alt_prefix =
12827 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12828 ? "AT_" : "";
12829 if (u.choice.alt_value->needs_temp_ref()) {
12830 const string& tmp_id = get_temporary_id();
12831 const char *tmp_id_str = tmp_id.c_str();
12832 str = mputprintf(str, "{\n"
12833 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12834 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12835 alt_prefix, alt_name);
12836 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12837 str = mputstr(str, "}\n");
12838 } else {
12839 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12840 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12841 Free(embedded_name);
12842 }
12843 return str;
12844 }
12845
12846 char *Value::generate_code_init_seof(char *str, const char *name)
12847 {
12848 size_t nof_vs = u.val_vs->get_nof_vs();
12849 if (nof_vs > 0) {
12850 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12851 const string& embedded_type =
12852 my_governor->get_ofType()->get_genname_value(my_scope);
12853 const char *embedded_type_str = embedded_type.c_str();
12854 for (size_t i = 0; i < nof_vs; i++) {
12855 Value *comp_v = u.val_vs->get_v_byIndex(i);
12856
12857 if (comp_v->valuetype == V_NOTUSED) continue;
12858 else if (comp_v->needs_temp_ref()) {
12859 const string& tmp_id = get_temporary_id();
12860 const char *tmp_id_str = tmp_id.c_str();
12861 str = mputprintf(str, "{\n"
12862 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12863 (unsigned long) i);
12864 str = comp_v->generate_code_init(str, tmp_id_str);
12865 str = mputstr(str, "}\n");
12866 } else {
12867 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12868 str = comp_v->generate_code_init(str, embedded_name);
12869 Free(embedded_name);
12870 }
12871 }
12872 } else {
12873 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12874 }
12875 return str;
12876 }
12877
12878 char *Value::generate_code_init_indexed(char *str, const char *name)
12879 {
12880 size_t nof_ivs = u.val_vs->get_nof_ivs();
12881 if (nof_ivs > 0) {
12882 // Previous values can be truncated. The concept is similar to
12883 // templates.
12884 Type *t_last = my_governor->get_type_refd_last();
12885 const string& oftype_name =
12886 t_last->get_ofType()->get_genname_value(my_scope);
12887 const char *oftype_name_str = oftype_name.c_str();
12888 for (size_t i = 0; i < nof_ivs; i++) {
12889 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
12890 const string& tmp_id_1 = get_temporary_id();
12891 str = mputstr(str, "{\n");
12892 Value *index = iv->get_index();
12893 if (index->get_valuetype() != V_INT) {
12894 const string& tmp_id_2 = get_temporary_id();
12895 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
12896 str = index->generate_code_init(str, tmp_id_2.c_str());
12897 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12898 tmp_id_1.c_str(), name, tmp_id_2.c_str());
12899 } else {
12900 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
12901 tmp_id_1.c_str(), name,
12902 (index->get_val_Int()->t_str()).c_str());
12903 }
12904 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
12905 str = mputstr(str, "}\n");
12906 }
12907 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
12908 return str;
12909 }
12910
12911 char *Value::generate_code_init_array(char *str, const char *name)
12912 {
12913 size_t nof_vs = u.val_vs->get_nof_vs();
12914 Type *t_last = my_governor->get_type_refd_last();
12915 Int index_offset = t_last->get_dimension()->get_offset();
12916 const string& embedded_type =
12917 t_last->get_ofType()->get_genname_value(my_scope);
12918 const char *embedded_type_str = embedded_type.c_str();
12919 for (size_t i = 0; i < nof_vs; i++) {
12920 Value *comp_v = u.val_vs->get_v_byIndex(i);
12921 if (comp_v->valuetype == V_NOTUSED) continue;
12922 else if (comp_v->needs_temp_ref()) {
12923 const string& tmp_id = get_temporary_id();
12924 const char *tmp_id_str = tmp_id.c_str();
12925 str = mputprintf(str, "{\n"
12926 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
12927 Int2string(index_offset + i).c_str());
12928 str = comp_v->generate_code_init(str, tmp_id_str);
12929 str = mputstr(str, "}\n");
12930 } else {
12931 char *embedded_name = mprintf("%s[%s]", name,
12932 Int2string(index_offset + i).c_str());
12933 str = comp_v->generate_code_init(str, embedded_name);
12934 Free(embedded_name);
12935 }
12936 }
12937 return str;
12938 }
12939
12940 char *Value::generate_code_init_se(char *str, const char *name)
12941 {
12942 Type *type = my_governor->get_type_refd_last();
12943 size_t nof_comps = type->get_nof_comps();
12944 if (nof_comps > 0) {
12945 for (size_t i = 0; i < nof_comps; i++) {
12946 CompField *cf = type->get_comp_byIndex(i);
12947 const Identifier& field_id = cf->get_name();
12948 const char *field_name = field_id.get_name().c_str();
12949 Value *field_v;
12950 if (u.val_nvs->has_nv_withName(field_id)) {
12951 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
12952 if (field_v->valuetype == V_NOTUSED) continue;
12953 if (field_v->valuetype == V_OMIT) field_v = 0;
12954 } else if (is_asn1()) {
12955 if (cf->has_default()) {
12956 // handle like a referenced value
12957 Value *defval = cf->get_defval();
12958 if (needs_init_precede(defval)) {
12959 str = defval->generate_code_init(str,
12960 defval->get_lhs_name().c_str());
12961 }
12962 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
12963 defval->get_genname_own(my_scope).c_str());
12964 continue;
12965 } else {
12966 if (!cf->get_is_optional())
12967 FATAL_ERROR("Value::generate_code_init()");
12968 field_v = 0;
12969 }
12970 } else {
12971 continue;
12972 }
12973 if (field_v) {
12974 // the value is not omit
12975 if (field_v->needs_temp_ref()) {
12976 const string& tmp_id = get_temporary_id();
12977 const char *tmp_id_str = tmp_id.c_str();
12978 str = mputprintf(str, "{\n"
12979 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
12980 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12981 field_name);
12982 str = field_v->generate_code_init(str, tmp_id_str);
12983 str = mputstr(str, "}\n");
12984 } else {
12985 char *embedded_name = mprintf("%s.%s()", name,
12986 field_name);
12987 if (cf->get_is_optional() && field_v->is_compound())
12988 embedded_name = mputstr(embedded_name, "()");
12989 str = field_v->generate_code_init(str, embedded_name);
12990 Free(embedded_name);
12991 }
12992 } else {
12993 // the value is omit
12994 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
12995 name, field_name);
12996 }
12997 }
12998 } else {
12999 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
13000 }
13001 return str;
13002 }
13003
13004 char *Value::generate_code_init_refd(char *str, const char *name)
13005 {
13006 Value *v = get_value_refd_last();
13007 if (v == this) {
13008 // the referred value is not available at compile time
13009 // the code generation is based on the reference
13010 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
13011 str = TypeConv::gen_conv_code_refd(str, name, v);
13012 } else {
13013 expression_struct expr;
13014 Code::init_expr(&expr);
13015 expr.expr = mputprintf(expr.expr, "%s = ", name);
13016 u.ref.ref->generate_code_const_ref(&expr);
13017 str = Code::merge_free_expr(str, &expr);
13018 }
13019 } else {
13020 // the referred value is available at compile time
13021 // the code generation is based on the referred value
13022 if (v->has_single_expr() &&
13023 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
13024 // simple substitution for in-line values within the same module
13025 str = mputprintf(str, "%s = %s;\n", name,
13026 v->get_single_expr().c_str());
13027 } else {
13028 // use a simple reference to reduce code size
13029 if (needs_init_precede(v)) {
13030 // the referred value must be initialized first
13031 if (!v->is_toplevel() && v->needs_temp_ref()) {
13032 // temporary id should be introduced for the lhs
13033 const string& tmp_id = get_temporary_id();
13034 const char *tmp_id_str = tmp_id.c_str();
13035 str = mputprintf(str, "{\n"
13036 "%s& %s = %s;\n",
13037 v->get_my_governor()->get_genname_value(my_scope).c_str(),
13038 tmp_id_str, v->get_lhs_name().c_str());
13039 str = v->generate_code_init(str, tmp_id_str);
13040 str = mputstr(str, "}\n");
13041 } else {
13042 str = v->generate_code_init(str, v->get_lhs_name().c_str());
13043 }
13044 }
13045 str = mputprintf(str, "%s = %s;\n", name,
13046 v->get_genname_own(my_scope).c_str());
13047 }
13048 }
13049 return str;
13050 }
13051
13052 void Value::generate_json_value(JSON_Tokenizer& json,
13053 bool allow_special_float, /* = true */
13054 bool union_value_list, /* = false */
13055 Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
13056 {
13057 switch (valuetype) {
13058 case V_INT:
13059 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
13060 break;
13061 case V_REAL: {
13062 Real r = get_val_Real();
13063 if (r == REAL_INFINITY) {
13064 if (allow_special_float) {
13065 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
13066 }
13067 }
13068 else if (r == -REAL_INFINITY) {
13069 if (allow_special_float) {
13070 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
13071 }
13072 }
13073 else if (r != r) {
13074 if (allow_special_float) {
13075 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
13076 }
13077 }
13078 else {
13079 // true if decimal representation possible (use %f format)
13080 bool decimal_repr = (r == 0.0)
13081 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
13082 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
13083 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
13084 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
13085 Free(number_str);
13086 }
13087 break; }
13088 case V_BOOL:
13089 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
13090 break;
13091 case V_BSTR:
13092 case V_HSTR:
13093 case V_OSTR:
13094 case V_CSTR: {
13095 char* str = convert_to_json_string(get_val_str().c_str());
13096 json.put_next_token(JSON_TOKEN_STRING, str);
13097 Free(str);
13098 break; }
13099 case V_USTR: {
13100 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13101 json.put_next_token(JSON_TOKEN_STRING, str);
13102 Free(str);
13103 break; }
13104 case V_VERDICT:
13105 case V_ENUM:
13106 json.put_next_token(JSON_TOKEN_STRING,
13107 (string('\"') + create_stringRepr() + string('\"')).c_str());
13108 break;
13109 case V_SEQOF:
13110 case V_SETOF:
13111 json.put_next_token(JSON_TOKEN_ARRAY_START);
13112 if (!u.val_vs->is_indexed()) {
13113 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
13114 u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
13115 union_value_list, omit_combo);
13116 }
13117 }
13118 else {
13119 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
13120 // look for the entry with index equal to i
13121 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
13122 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
13123 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
13124 allow_special_float, union_value_list, omit_combo);
13125 break;
13126 }
13127 }
13128 }
13129 }
13130 json.put_next_token(JSON_TOKEN_ARRAY_END);
13131 break;
13132 case V_SEQ:
13133 case V_SET: {
13134 // omitted fields have 2 possible JSON values (the field is absent, or it's
13135 // present with value 'null'), each combination of omitted values must be
13136 // generated
13137 if (omit_combo == NULL) {
13138 FATAL_ERROR("Value::generate_json_value - no combo");
13139 }
13140 size_t len = get_nof_comps();
13141 // generate the JSON object from the present combination
13142 json.put_next_token(JSON_TOKEN_OBJECT_START);
13143 for (size_t i = 0; i < len; ++i) {
13144 Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
13145 if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
13146 // the field is absent, don't insert anything
13147 continue;
13148 }
13149 // use the field's alias, if it has one
13150 const char* alias = NULL;
13151 if (my_governor != NULL) {
13152 JsonAST* field_attrib = my_governor->get_comp_byName(
13153 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
13154 if (field_attrib != NULL) {
13155 alias = field_attrib->alias;
13156 }
13157 }
13158 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13159 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
13160 if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
13161 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
13162 }
13163 else {
13164 get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
13165 allow_special_float, union_value_list, omit_combo);
13166 }
13167 }
13168 json.put_next_token(JSON_TOKEN_OBJECT_END);
13169 break; }
13170 case V_CHOICE: {
13171 bool as_value = !union_value_list && my_governor != NULL &&
13172 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
13173 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
13174 if (!as_value) {
13175 // no 'as value' coding instruction, insert an object with one field
13176 json.put_next_token(JSON_TOKEN_OBJECT_START);
13177 // use the field's alias, if it has one
13178 const char* alias = NULL;
13179 if (my_governor != NULL) {
13180 JsonAST* field_attrib = my_governor->get_comp_byName(
13181 get_alt_name())->get_type()->get_json_attributes();
13182 if (field_attrib != NULL) {
13183 alias = field_attrib->alias;
13184 }
13185 }
13186 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13187 get_alt_name().get_ttcnname().c_str());
13188 }
13189 get_alt_value()->generate_json_value(json, allow_special_float,
13190 union_value_list, omit_combo);
13191 if (!as_value) {
13192 json.put_next_token(JSON_TOKEN_OBJECT_END);
13193 }
13194 break; }
13195 case V_REFD: {
13196 Value* v = get_value_refd_last();
13197 if (this != v) {
13198 v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
13199 return;
13200 }
13201 } // no break
13202 default:
13203 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
13204 }
13205 }
13206
13207 bool Value::explicit_cast_needed(bool forIsValue)
13208 {
13209 Value *v_last = get_value_refd_last();
13210 if (v_last != this) {
13211 // this is a foldable referenced value
13212 // if the reference points to an imported or compound value the code
13213 // generation will be based on the reference so cast is not needed
13214 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
13215 || !v_last->has_single_expr()) return false;
13216 } else if (v_last->valuetype == V_REFD) {
13217 // this is an unfoldable reference (v_last==this)
13218 // explicit cast is needed only for string element references
13219 if (forIsValue) return false;
13220 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
13221 return t_subrefs && t_subrefs->refers_to_string_element();
13222 }
13223 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
13224 Type *t_governor = v_last->my_governor->get_type_refd_last();
13225 switch (t_governor->get_typetype()) {
13226 case Type::T_NULL:
13227 case Type::T_BOOL:
13228 case Type::T_INT:
13229 case Type::T_INT_A:
13230 case Type::T_REAL:
13231 case Type::T_ENUM_A:
13232 case Type::T_ENUM_T:
13233 case Type::T_VERDICT:
13234 case Type::T_COMPONENT:
13235 // these are mapped to built-in C/C++ types
13236 return true;
13237 case Type::T_SEQ_A:
13238 case Type::T_SEQ_T:
13239 case Type::T_SET_A:
13240 case Type::T_SET_T:
13241 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13242 return t_governor->get_nof_comps() == 0;
13243 case Type::T_SEQOF:
13244 case Type::T_SETOF:
13245 // the C++ equivalent of value {} is ambiguous
13246 // tr926
13247 return true;
13248 case Type::T_FUNCTION:
13249 case Type::T_ALTSTEP:
13250 case Type::T_TESTCASE:
13251 return true;
13252 default:
13253 return false;
13254 }
13255 }
13256
13257 bool Value::has_single_expr()
13258 {
13259 if (get_needs_conversion()) return false;
13260 switch (valuetype) {
13261 case V_EXPR:
13262 return has_single_expr_expr();
13263 case V_CHOICE:
13264 case V_ARRAY:
13265 // a union or array value cannot be represented as an in-line expression
13266 return false;
13267 case V_SEQOF:
13268 case V_SETOF:
13269 // only an empty record/set of value can be represented as an in-line
13270 // expression
13271 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
13272 else return u.val_vs->get_nof_ivs() == 0;
13273 case V_SEQ:
13274 case V_SET: {
13275 // only a value for an empty record/set type can be represented as an
13276 // in-line expression
13277 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
13278 Type *type = my_governor->get_type_refd_last();
13279 return type->get_nof_comps() == 0; }
13280 case V_REFD: {
13281 Value *v_last = get_value_refd_last();
13282 // If the above call hit an error and set_valuetype(V_ERROR),
13283 // then u.ref.ref has been freed. Avoid the segfault.
13284 if (valuetype == V_ERROR)
13285 return false;
13286 if (v_last != this && v_last->has_single_expr() &&
13287 v_last->my_scope->get_scope_mod_gen() ==
13288 my_scope->get_scope_mod_gen()) return true;
13289 else return u.ref.ref->has_single_expr(); }
13290 case V_INVOKE:
13291 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
13292 case V_ERROR:
13293 case V_NAMEDINT:
13294 case V_NAMEDBITS:
13295 case V_UNDEF_LOWERID:
13296 case V_UNDEF_BLOCK:
13297 case V_REFER:
13298 // these values cannot occur during code generation
13299 FATAL_ERROR("Value::has_single_expr()");
13300 case V_INT:
13301 return u.val_Int->is_native_fit();
13302 case V_NOTUSED:
13303 // should only happen when generating code for an unbound record/set value
13304 return false;
13305 default:
13306 // other value types (literal values) do not need temporary reference
13307 return true;
13308 }
13309 }
13310
13311 string Value::get_single_expr()
13312 {
13313 switch (valuetype) {
13314 case V_NULL:
13315 return string("ASN_NULL_VALUE");
13316 case V_BOOL:
13317 return string(u.val_bool ? "TRUE" : "FALSE");
13318 case V_INT:
13319 if (u.val_Int->is_native_fit()) { // Be sure.
13320 return u.val_Int->t_str();
13321 } else {
13322 // get_single_expr may be called only if has_single_expr() is true.
13323 // The only exception is V_INT, where get_single_expr may be called
13324 // even if is_native_fit (which is used to implement has_single_expr)
13325 // returns false.
13326 string ret_val('"');
13327 ret_val += u.val_Int->t_str();
13328 ret_val += '"';
13329 return ret_val;
13330 }
13331 case V_REAL:
13332 return Real2code(u.val_Real);
13333 case V_ENUM:
13334 return get_single_expr_enum();
13335 case V_BSTR:
13336 return get_my_scope()->get_scope_mod_gen()
13337 ->add_bitstring_literal(*u.str.val_str);
13338 case V_HSTR:
13339 return get_my_scope()->get_scope_mod_gen()
13340 ->add_hexstring_literal(*u.str.val_str);
13341 case V_OSTR:
13342 return get_my_scope()->get_scope_mod_gen()
13343 ->add_octetstring_literal(*u.str.val_str);
13344 case V_CSTR:
13345 return get_my_scope()->get_scope_mod_gen()
13346 ->add_charstring_literal(*u.str.val_str);
13347 case V_USTR:
13348 if (u.ustr.convert_str) {
13349 set_valuetype(V_CSTR);
13350 return get_my_scope()->get_scope_mod_gen()
13351 ->add_charstring_literal(*u.str.val_str);
13352 } else
13353 return get_my_scope()->get_scope_mod_gen()
13354 ->add_ustring_literal(*u.ustr.val_ustr);
13355 case V_ISO2022STR:
13356 return get_single_expr_iso2022str();
13357 case V_OID:
13358 case V_ROID: {
13359 vector<string> comps;
13360 bool is_constant = get_oid_comps(comps);
13361 size_t nof_comps = comps.size();
13362 string oi_str;
13363 for (size_t i = 0; i < nof_comps; i++) {
13364 if (i > 0) oi_str += ", ";
13365 oi_str += *(comps[i]);
13366 }
13367 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
13368 comps.clear();
13369 if (is_constant) {
13370 // the objid only contains constants
13371 // => create a literal and return its name
13372 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
13373 }
13374 // the objid contains at least one variable
13375 // => append the number of components before the component values in the string and return it
13376 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
13377 case V_SEQOF:
13378 case V_SETOF:
13379 if (u.val_vs->get_nof_vs() > 0)
13380 FATAL_ERROR("Value::get_single_expr()");
13381 return string("NULL_VALUE");
13382 case V_SEQ:
13383 case V_SET:
13384 if (u.val_nvs->get_nof_nvs() > 0)
13385 FATAL_ERROR("Value::get_single_expr()");
13386 return string("NULL_VALUE");
13387 case V_REFD: {
13388 Value *v_last = get_value_refd_last();
13389 if (v_last != this && v_last->has_single_expr() &&
13390 v_last->my_scope->get_scope_mod_gen() ==
13391 my_scope->get_scope_mod_gen()) {
13392 // the reference points to another single value in the same module
13393 return v_last->get_single_expr();
13394 } else {
13395 // convert the reference to a single expression
13396 expression_struct expr;
13397 Code::init_expr(&expr);
13398 u.ref.ref->generate_code_const_ref(&expr);
13399 if (expr.preamble || expr.postamble)
13400 FATAL_ERROR("Value::get_single_expr()");
13401 string ret_val(expr.expr);
13402 Code::free_expr(&expr);
13403 return ret_val;
13404 } }
13405 case V_OMIT:
13406 return string("OMIT_VALUE");
13407 case V_VERDICT:
13408 switch (u.verdict) {
13409 case Verdict_NONE:
13410 return string("NONE");
13411 case Verdict_PASS:
13412 return string("PASS");
13413 case Verdict_INCONC:
13414 return string("INCONC");
13415 case Verdict_FAIL:
13416 return string("FAIL");
13417 case Verdict_ERROR:
13418 return string("ERROR");
13419 default:
13420 FATAL_ERROR("Value::get_single_expr()");
13421 return string();
13422 }
13423 case V_DEFAULT_NULL:
13424 return string("NULL_COMPREF");
13425 case V_FAT_NULL: {
13426 string ret_val('(');
13427 ret_val += my_governor->get_genname_value(my_scope);
13428 ret_val += "::function_pointer)Module_List::get_fat_null()";
13429 return ret_val; }
13430 case V_EXPR:
13431 case V_INVOKE: {
13432 expression_struct expr;
13433 Code::init_expr(&expr);
13434 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13435 else generate_code_expr_invoke(&expr);
13436 if (expr.preamble || expr.postamble)
13437 FATAL_ERROR("Value::get_single_expr()");
13438 string ret_val(expr.expr);
13439 Code::free_expr(&expr);
13440 return ret_val; }
13441 case V_MACRO:
13442 switch (u.macro) {
13443 case MACRO_TESTCASEID:
13444 return string("TTCN_Runtime::get_testcase_id_macro()");
13445 default:
13446 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13447 return string();
13448 }
13449 case V_FUNCTION:
13450 case V_ALTSTEP:
13451 case V_TESTCASE:
13452 return get_single_expr_fat();
13453 default:
13454 FATAL_ERROR("Value::get_single_expr()");
13455 return string();
13456 }
13457 }
13458
13459 bool Value::has_single_expr_expr()
13460 {
13461 switch (u.expr.v_optype) {
13462 case OPTYPE_RND: // -
13463 case OPTYPE_COMP_NULL:
13464 case OPTYPE_COMP_MTC:
13465 case OPTYPE_COMP_SYSTEM:
13466 case OPTYPE_COMP_SELF:
13467 case OPTYPE_COMP_RUNNING_ANY:
13468 case OPTYPE_COMP_RUNNING_ALL:
13469 case OPTYPE_COMP_ALIVE_ANY:
13470 case OPTYPE_COMP_ALIVE_ALL:
13471 case OPTYPE_TMR_RUNNING_ANY:
13472 case OPTYPE_GETVERDICT:
13473 case OPTYPE_TESTCASENAME:
13474 case OPTYPE_PROF_RUNNING:
13475 return true;
13476 case OPTYPE_ENCODE:
13477 case OPTYPE_DECODE:
13478 case OPTYPE_ISBOUND:
13479 case OPTYPE_ISPRESENT:
13480 case OPTYPE_TTCN2STRING:
13481 case OPTYPE_ENCVALUE_UNICHAR:
13482 case OPTYPE_DECVALUE_UNICHAR:
13483 return false;
13484 case OPTYPE_UNARYPLUS: // v1
13485 case OPTYPE_UNARYMINUS:
13486 case OPTYPE_NOT:
13487 case OPTYPE_NOT4B:
13488 case OPTYPE_BIT2HEX:
13489 case OPTYPE_BIT2INT:
13490 case OPTYPE_BIT2OCT:
13491 case OPTYPE_BIT2STR:
13492 case OPTYPE_CHAR2INT:
13493 case OPTYPE_CHAR2OCT:
13494 case OPTYPE_FLOAT2INT:
13495 case OPTYPE_FLOAT2STR:
13496 case OPTYPE_HEX2BIT:
13497 case OPTYPE_HEX2INT:
13498 case OPTYPE_HEX2OCT:
13499 case OPTYPE_HEX2STR:
13500 case OPTYPE_INT2CHAR:
13501 case OPTYPE_INT2FLOAT:
13502 case OPTYPE_INT2STR:
13503 case OPTYPE_INT2UNICHAR:
13504 case OPTYPE_OCT2BIT:
13505 case OPTYPE_OCT2CHAR:
13506 case OPTYPE_OCT2HEX:
13507 case OPTYPE_OCT2INT:
13508 case OPTYPE_OCT2STR:
13509 case OPTYPE_STR2BIT:
13510 case OPTYPE_STR2FLOAT:
13511 case OPTYPE_STR2HEX:
13512 case OPTYPE_STR2INT:
13513 case OPTYPE_STR2OCT:
13514 case OPTYPE_UNICHAR2INT:
13515 case OPTYPE_UNICHAR2CHAR:
13516 case OPTYPE_ENUM2INT:
13517 case OPTYPE_RNDWITHVAL:
13518 case OPTYPE_ISCHOSEN_V: // v1 i2
13519 case OPTYPE_COMP_RUNNING:
13520 case OPTYPE_COMP_ALIVE:
13521 case OPTYPE_GET_STRINGENCODING:
13522 case OPTYPE_REMOVE_BOM:
13523 case OPTYPE_DECODE_BASE64:
13524 return u.expr.v1->has_single_expr();
13525 case OPTYPE_ISCHOSEN_T: // t1 i2
13526 return u.expr.t1->has_single_expr();
13527 case OPTYPE_ADD: // v1 v2
13528 case OPTYPE_SUBTRACT:
13529 case OPTYPE_MULTIPLY:
13530 case OPTYPE_DIVIDE:
13531 case OPTYPE_MOD:
13532 case OPTYPE_REM:
13533 case OPTYPE_CONCAT:
13534 case OPTYPE_EQ:
13535 case OPTYPE_LT:
13536 case OPTYPE_GT:
13537 case OPTYPE_NE:
13538 case OPTYPE_GE:
13539 case OPTYPE_LE:
13540 case OPTYPE_XOR:
13541 case OPTYPE_AND4B:
13542 case OPTYPE_OR4B:
13543 case OPTYPE_XOR4B:
13544 case OPTYPE_SHL:
13545 case OPTYPE_SHR:
13546 case OPTYPE_ROTL:
13547 case OPTYPE_ROTR:
13548 case OPTYPE_INT2BIT:
13549 case OPTYPE_INT2HEX:
13550 case OPTYPE_INT2OCT:
13551 return u.expr.v1->has_single_expr() &&
13552 u.expr.v2->has_single_expr();
13553 case OPTYPE_UNICHAR2OCT:
13554 case OPTYPE_OCT2UNICHAR:
13555 case OPTYPE_ENCODE_BASE64:
13556 return u.expr.v1->has_single_expr() &&
13557 (!u.expr.v2 || u.expr.v2->has_single_expr());
13558 case OPTYPE_AND:
13559 case OPTYPE_OR:
13560 return u.expr.v1->has_single_expr() &&
13561 u.expr.v2->has_single_expr() &&
13562 !u.expr.v2->needs_short_circuit();
13563 case OPTYPE_SUBSTR:
13564 return u.expr.ti1->has_single_expr() &&
13565 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13566 case OPTYPE_REGEXP:
13567 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13568 u.expr.v3->has_single_expr();
13569 case OPTYPE_DECOMP: // v1 v2 v3
13570 return u.expr.v1->has_single_expr() &&
13571 u.expr.v2->has_single_expr() &&
13572 u.expr.v3->has_single_expr();
13573 case OPTYPE_REPLACE:
13574 return u.expr.ti1->has_single_expr() &&
13575 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13576 u.expr.ti4->has_single_expr();
13577 case OPTYPE_ISVALUE: // ti1
13578 case OPTYPE_LENGTHOF: // ti1
13579 case OPTYPE_SIZEOF: // ti1
13580 case OPTYPE_VALUEOF: // ti1
13581 return u.expr.ti1->has_single_expr();
13582 case OPTYPE_LOG2STR:
13583 return u.expr.logargs->has_single_expr();
13584 case OPTYPE_MATCH: // v1 t2
13585 return u.expr.v1->has_single_expr() &&
13586 u.expr.t2->has_single_expr();
13587 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13588 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13589 (!u.expr.v3 || u.expr.v3->has_single_expr());
13590 case OPTYPE_TMR_READ: // r1
13591 case OPTYPE_TMR_RUNNING:
13592 case OPTYPE_ACTIVATE:
13593 return u.expr.r1->has_single_expr();
13594 case OPTYPE_EXECUTE: // r1 [v2]
13595 return u.expr.r1->has_single_expr() &&
13596 (!u.expr.v2 || u.expr.v2->has_single_expr());
13597 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13598 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13599 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13600 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13601 (!u.expr.v3 || u.expr.v3->has_single_expr());
13602 default:
13603 FATAL_ERROR("Value::has_single_expr_expr()");
13604 } // switch
13605 }
13606
13607 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13608 {
13609 if (!v->has_single_expr()) return false;
13610 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13611 if (!ap_list->get_par(i)->has_single_expr()) return false;
13612 return true;
13613 }
13614
13615 string Value::get_single_expr_enum()
13616 {
13617 string ret_val(my_governor->get_genname_value(my_scope));
13618 ret_val += "::";
13619 ret_val += u.val_id->get_name();
13620 return ret_val;
13621 }
13622
13623 string Value::get_single_expr_iso2022str()
13624 {
13625 string ret_val;
13626 Type *type = get_my_governor()->get_type_refd_last();
13627 switch (type->get_typetype()) {
13628 case Type::T_TELETEXSTRING:
13629 ret_val += "TTCN_ISO2022_2_TeletexString";
13630 break;
13631 case Type::T_VIDEOTEXSTRING:
13632 ret_val += "TTCN_ISO2022_2_VideotexString";
13633 break;
13634 case Type::T_GRAPHICSTRING:
13635 case Type::T_OBJECTDESCRIPTOR:
13636 ret_val += "TTCN_ISO2022_2_GraphicString";
13637 break;
13638 case Type::T_GENERALSTRING:
13639 ret_val += "TTCN_ISO2022_2_GeneralString";
13640 break;
13641 default:
13642 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13643 } // switch
13644 ret_val += '(';
13645 string *ostr = char2oct(*u.str.val_str);
13646 ret_val += get_my_scope()->get_scope_mod_gen()
13647 ->add_octetstring_literal(*ostr);
13648 delete ostr;
13649 ret_val += ')';
13650 return ret_val;
13651 }
13652
13653 string Value::get_single_expr_fat()
13654 {
13655 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13656 // the ampersand operator is not really necessary to obtain the function
13657 // pointer, but some older versions of GCC cannot instantiate the
13658 // appropriate operator=() member of class OPTIONAL when necessary
13659 // if only the function name is given
13660 string ret_val('&');
13661 switch (valuetype) {
13662 case V_FUNCTION:
13663 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13664 break;
13665 case V_ALTSTEP:
13666 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13667 ret_val += "_instance";
13668 break;
13669 case V_TESTCASE:
13670 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13671 break;
13672 default:
13673 FATAL_ERROR("Value::get_single_expr_fat()");
13674 }
13675 return ret_val;
13676 }
13677
13678 bool Value::is_compound()
13679 {
13680 switch (valuetype) {
13681 case V_CHOICE:
13682 case V_SEQOF:
13683 case V_SETOF:
13684 case V_ARRAY:
13685 case V_SEQ:
13686 case V_SET:
13687 return true;
13688 default:
13689 return false;
13690 }
13691 }
13692
13693 bool Value::needs_temp_ref()
13694 {
13695 switch (valuetype) {
13696 case V_SEQOF:
13697 case V_SETOF:
13698 if (!is_indexed()) {
13699 // Temporary reference is needed if the value has at least one real
13700 // element (i.e. it is not empty or contains only not used symbols).
13701 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13702 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13703 }
13704 } else {
13705 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13706 if (u.val_vs->get_iv_byIndex(i)->get_value()
13707 ->valuetype != V_NOTUSED)
13708 return true;
13709 }
13710 }
13711 return false;
13712 case V_ARRAY: {
13713 size_t nof_real_vs = 0;
13714 if (!is_indexed()) {
13715 // Temporary reference is needed if the array value has at least two
13716 // real elements (excluding not used symbols).
13717 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13718 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13719 nof_real_vs++;
13720 if (nof_real_vs > 1) return true;
13721 }
13722 }
13723 } else {
13724 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13725 if (u.val_vs->get_iv_byIndex(i)->get_value()
13726 ->valuetype != V_NOTUSED) {
13727 nof_real_vs++;
13728 if (nof_real_vs > 1) return true;
13729 }
13730 }
13731 }
13732 return false; }
13733 case V_SEQ:
13734 case V_SET:
13735 if (is_asn1()) {
13736 // it depends on the type since fields with omit or default value
13737 // may not be present
13738 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13739 } else {
13740 // incomplete values are allowed in TTCN-3
13741 // we should check the number of value components
13742 return u.val_nvs->get_nof_nvs() > 1;
13743 }
13744 case V_ERROR:
13745 case V_NAMEDINT:
13746 case V_NAMEDBITS:
13747 case V_UNDEF_LOWERID:
13748 case V_UNDEF_BLOCK:
13749 case V_TTCN3_NULL:
13750 // these values cannot occur during code generation
13751 FATAL_ERROR("Value::needs_temp_ref()");
13752 case V_INT:
13753 return !u.val_Int->is_native();
13754 default:
13755 // other value types (literal values) do not need temporary reference
13756 return false;
13757 }
13758 }
13759
13760 bool Value::needs_short_circuit()
13761 {
13762 switch (valuetype) {
13763 case V_BOOL:
13764 return false;
13765 case V_REFD:
13766 // examined below
13767 break;
13768 case V_EXPR:
13769 case V_INVOKE:
13770 // sub-expressions should be evaluated only if necessary
13771 return true;
13772 default:
13773 FATAL_ERROR("Value::needs_short_circuit()");
13774 }
13775 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13776 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13777 switch (t_ass->get_asstype()) {
13778 case Assignment::A_FUNCTION_RVAL:
13779 case Assignment::A_EXT_FUNCTION_RVAL:
13780 // avoid unnecessary call of a function
13781 return true;
13782 case Assignment::A_CONST:
13783 case Assignment::A_EXT_CONST:
13784 case Assignment::A_MODULEPAR:
13785 case Assignment::A_VAR:
13786 case Assignment::A_PAR_VAL_IN:
13787 case Assignment::A_PAR_VAL_OUT:
13788 case Assignment::A_PAR_VAL_INOUT:
13789 // depends on field/array sub-references, which is examined below
13790 break;
13791 default:
13792 FATAL_ERROR("Value::needs_short_circuit()");
13793 }
13794 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13795 if (t_subrefs) {
13796 // the evaluation of the reference does not have side effects
13797 // (i.e. false shall be returned) only if all sub-references point to
13798 // mandatory fields of record/set types, and neither sub-reference points
13799 // to a field of a union type
13800 Type *t_type = t_ass->get_Type();
13801 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13802 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13803 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13804 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13805 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13806 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13807 t_cf->get_is_optional()) return true;
13808 t_type = t_cf->get_type();
13809 } else return true;
13810 }
13811 }
13812 return false;
13813 }
13814
13815 void Value::dump(unsigned level) const
13816 {
13817 switch (valuetype) {
13818 case V_ERROR:
13819 case V_NULL:
13820 case V_BOOL:
13821 case V_INT:
13822 case V_NAMEDINT:
13823 case V_NAMEDBITS:
13824 case V_REAL:
13825 case V_ENUM:
13826 case V_BSTR:
13827 case V_HSTR:
13828 case V_OSTR:
13829 case V_CSTR:
13830 case V_ISO2022STR:
13831 case V_OID:
13832 case V_ROID:
13833 case V_CHOICE:
13834 case V_SEQOF:
13835 case V_SETOF:
13836 case V_ARRAY:
13837 case V_SEQ:
13838 case V_SET:
13839 case V_OMIT:
13840 case V_VERDICT:
13841 case V_DEFAULT_NULL:
13842 case V_FAT_NULL:
13843 case V_EXPR:
13844 case V_MACRO:
13845 case V_NOTUSED:
13846 case V_FUNCTION:
13847 case V_ALTSTEP:
13848 case V_TESTCASE:
13849 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13850 break;
13851 case V_REFD:
13852 case V_REFER:
13853 DEBUG(level, "Value: reference");
13854 u.ref.ref->dump(level + 1);
13855 break;
13856 case V_UNDEF_LOWERID:
13857 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13858 break;
13859 case V_UNDEF_BLOCK:
13860 DEBUG(level, "Value: {block}");
13861 break;
13862 case V_TTCN3_NULL:
13863 DEBUG(level, "Value: null");
13864 break;
13865 case V_INVOKE:
13866 DEBUG(level, "Value: invoke");
13867 u.invoke.v->dump(level + 1);
13868 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13869 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13870 break;
13871 default:
13872 DEBUG(level, "Value: unknown type: %d", valuetype);
13873 } // switch
13874 }
13875
13876 void Value::add_string_element(size_t index, Value *v_element,
13877 map<size_t, Value>*& string_elements)
13878 {
13879 v_element->set_my_scope(get_my_scope());
13880 v_element->set_my_governor(get_my_governor());
13881 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
13882 v_element->set_location(*this);
13883 if (!string_elements) string_elements = new map<size_t, Value>;
13884 string_elements->add(index, v_element);
13885 }
13886
13887 ///////////////////////////////////////////////////////////////////////////////
13888 // class LazyParamData
13889
13890 int LazyParamData::depth = 0;
13891 bool LazyParamData::used_as_lvalue = false;
13892 vector<string>* LazyParamData::type_vec = NULL;
13893 vector<string>* LazyParamData::refd_vec = NULL;
13894
13895 void LazyParamData::init(bool p_used_as_lvalue) {
13896 if (depth<0) FATAL_ERROR("LazyParamData::init()");
13897 if (depth==0) {
13898 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
13899 used_as_lvalue = p_used_as_lvalue;
13900 type_vec = new vector<string>;
13901 refd_vec = new vector<string>;
13902 }
13903 depth++;
13904 }
13905
13906 void LazyParamData::clean() {
13907 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
13908 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
13909 if (depth==1) {
13910 // type_vec
13911 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
13912 type_vec->clear();
13913 delete type_vec;
13914 type_vec = NULL;
13915 // refd_vec
13916 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
13917 refd_vec->clear();
13918 delete refd_vec;
13919 refd_vec = NULL;
13920 }
13921 depth--;
13922 }
13923
13924 bool LazyParamData::in_lazy() {
13925 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
13926 return depth>0;
13927 }
13928
13929 // returns a temporary id instead of the C++ reference to a definition
13930 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
13931 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
13932 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
13933 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
13934 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
13935 // store the type of the assignment
13936 string* type_str = new string;
13937 switch (ass->get_asstype()) {
13938 case Assignment::A_MODULEPAR_TEMP:
13939 case Assignment::A_TEMPLATE:
13940 case Assignment::A_VAR_TEMPLATE:
13941 case Assignment::A_PAR_TEMPL_IN:
13942 case Assignment::A_PAR_TEMPL_OUT:
13943 case Assignment::A_PAR_TEMPL_INOUT:
13944 *type_str = ass->get_Type()->get_genname_template(scope);
13945 break;
13946 default:
13947 *type_str = ass->get_Type()->get_genname_value(scope);
13948 }
13949 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
13950 bool refd_ass_is_lazy_fpar = false;
13951 switch (ass->get_asstype()) {
13952 case Assignment::A_PAR_VAL:
13953 case Assignment::A_PAR_VAL_IN:
13954 case Assignment::A_PAR_TEMPL_IN:
13955 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
13956 if (refd_ass_is_lazy_fpar) {
13957 *type_str = string("Lazy_Param<") + *type_str + string(">");
13958 }
13959 break;
13960 default:
13961 break;
13962 }
13963 // add the "const" part if the referenced assignment is a constant thing
13964 if (!refd_ass_is_lazy_fpar) {
13965 switch (ass->get_asstype()) {
13966 case Assignment::A_CONST:
13967 case Assignment::A_OC:
13968 case Assignment::A_OBJECT:
13969 case Assignment::A_OS:
13970 case Assignment::A_VS:
13971 case Assignment::A_EXT_CONST:
13972 case Assignment::A_MODULEPAR:
13973 case Assignment::A_MODULEPAR_TEMP:
13974 case Assignment::A_TEMPLATE:
13975 case Assignment::A_PAR_VAL:
13976 case Assignment::A_PAR_VAL_IN:
13977 case Assignment::A_PAR_TEMPL_IN:
13978 *type_str = string("const ") + *type_str;
13979 break;
13980 default:
13981 // nothing to do
13982 break;
13983 }
13984 }
13985 //
13986 type_vec->add(type_str);
13987 // store the C++ reference string
13988 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
13989 if (refd_ass_is_lazy_fpar) {
13990 Type* refd_ass_type = ass->get_Type();
13991 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);
13992 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
13993 } else {
13994 return get_member_name(refd_vec->size()-1);
13995 }
13996 }
13997
13998 string LazyParamData::get_member_name(size_t idx) {
13999 return string("lpm_") + Int2string(idx);
14000 }
14001
14002 string LazyParamData::get_constr_param_name(size_t idx) {
14003 return string("lpp_") + Int2string(idx);
14004 }
14005
14006 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
14007 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14008 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
14009 const string& tmp_id = val->get_temporary_id();
14010 const char *tmp_id_str = tmp_id.c_str();
14011 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14012 val->get_my_governor()->get_genname_value(my_scope).c_str(),
14013 tmp_id_str);
14014 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14015 tmp_id_str, val);
14016 expr->expr = mputstr(expr->expr, tmp_id_str);
14017 } else {
14018 val->generate_code_expr(expr);
14019 }
14020 }
14021
14022 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
14023 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14024 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
14025 const string& tmp_id = temp->get_Template()->get_temporary_id();
14026 const char *tmp_id_str = tmp_id.c_str();
14027 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14028 temp->get_Template()->get_my_governor()
14029 ->get_genname_template(my_scope).c_str(), tmp_id_str);
14030 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14031 tmp_id_str, temp->get_Template());
14032 // Not incorporated into gen_conv_code() yet.
14033 if (gen_restriction_check != TR_NONE)
14034 expr->preamble = Template::generate_restriction_check_code(
14035 expr->preamble, tmp_id_str, gen_restriction_check);
14036 expr->expr = mputstr(expr->expr, tmp_id_str);
14037 } else temp->generate_code(expr, gen_restriction_check);
14038 }
14039
14040 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
14041 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14042 if (depth>1) {
14043 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14044 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14045 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14046 expression_struct value_expr;
14047 Code::init_expr(&value_expr);
14048 generate_code_for_value(&value_expr, value, scope);
14049 // the id of the instance of Lazy_Param which will be used as the actual parameter
14050 const string& lazy_param_id = value->get_temporary_id();
14051 if (value_expr.preamble) {
14052 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
14053 }
14054 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14055 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14056 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
14057 Code::free_expr(&value_expr);
14058 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14059 return;
14060 }
14061 // only if the formal parameter is *not* used as lvalue
14062 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
14063 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
14064 if (refd_ass) {
14065 bool refd_ass_is_lazy_fpar = false;
14066 switch (refd_ass->get_asstype()) {
14067 case Assignment::A_PAR_VAL:
14068 case Assignment::A_PAR_VAL_IN:
14069 case Assignment::A_PAR_TEMPL_IN:
14070 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14071 break;
14072 default:
14073 break;
14074 }
14075 if (refd_ass_is_lazy_fpar) {
14076 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14077 return;
14078 }
14079 }
14080 }
14081 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14082 expression_struct value_expr;
14083 Code::init_expr(&value_expr);
14084 generate_code_for_value(&value_expr, value, scope);
14085 // the id of the instance of Lazy_Param which will be used as the actual parameter
14086 string lazy_param_id = value->get_temporary_id();
14087 string type_name = value->get_my_governor()->get_genname_value(scope);
14088 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
14089 }
14090
14091 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
14092 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14093 if (depth>1) {
14094 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14095 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14096 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14097 expression_struct tmpl_expr;
14098 Code::init_expr(&tmpl_expr);
14099 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14100 // the id of the instance of Lazy_Param which will be used as the actual parameter
14101 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
14102 if (tmpl_expr.preamble) {
14103 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
14104 }
14105 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14106 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14107 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
14108 Code::free_expr(&tmpl_expr);
14109 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14110 return;
14111 }
14112 // only if the formal parameter is *not* used as lvalue
14113 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
14114 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
14115 if (refd_ass) {
14116 bool refd_ass_is_lazy_fpar = false;
14117 switch (refd_ass->get_asstype()) {
14118 case Assignment::A_PAR_VAL:
14119 case Assignment::A_PAR_VAL_IN:
14120 case Assignment::A_PAR_TEMPL_IN:
14121 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14122 break;
14123 default:
14124 break;
14125 }
14126 if (refd_ass_is_lazy_fpar) {
14127 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14128 return;
14129 }
14130 }
14131 }
14132 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14133 expression_struct tmpl_expr;
14134 Code::init_expr(&tmpl_expr);
14135 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14136 // the id of the instance of Lazy_Param which will be used as the actual parameter
14137 string lazy_param_id = temp->get_Template()->get_temporary_id();
14138 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
14139 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
14140 }
14141
14142 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
14143 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
14144 if (type_vec->size()>0) {
14145 // private members of the local class will be const references to the objects referenced by the expression
14146 for (size_t i=0; i<type_vec->size(); i++) {
14147 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
14148 }
14149 expr->preamble = mputstr(expr->preamble, "public:\n");
14150 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
14151 for (size_t i=0; i<type_vec->size(); i++) {
14152 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14153 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
14154 }
14155 expr->preamble = mputstr(expr->preamble, "): ");
14156 for (size_t i=0; i<type_vec->size(); i++) {
14157 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14158 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
14159 }
14160 expr->preamble = mputstr(expr->preamble, " {}\n");
14161 expr->preamble = mputstr(expr->preamble, "private:\n");
14162 }
14163 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
14164 // use the temporary expr structure to fill the body of the eval_expr() function
14165 if (param_expr.preamble) {
14166 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
14167 }
14168 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
14169 if (param_expr.postamble) {
14170 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
14171 }
14172 Code::free_expr(&param_expr);
14173 expr->preamble = mputstr(expr->preamble, "}\n"
14174 "};\n" // end of local class definition
14175 );
14176 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
14177 if (type_vec->size()>0) {
14178 expr->preamble = mputc(expr->preamble, '(');
14179 // paramteres of the constructor are references to the objects used in the expression
14180 for (size_t i=0; i<refd_vec->size(); i++) {
14181 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14182 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
14183 }
14184 expr->preamble = mputc(expr->preamble, ')');
14185 }
14186 expr->preamble = mputstr(expr->preamble, ";\n");
14187 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14188 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
14189 }
14190
14191 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
14192 expression_struct ref_expr;
14193 Code::init_expr(&ref_expr);
14194 ref->generate_code(&ref_expr);
14195 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
14196 if (ref_expr.preamble) {
14197 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
14198 }
14199 Assignment* ass = ref->get_refd_assignment();
14200 // determine C++ type of the assignment
14201 string type_str;
14202 switch (ass->get_asstype()) {
14203 case Assignment::A_MODULEPAR_TEMP:
14204 case Assignment::A_TEMPLATE:
14205 case Assignment::A_VAR_TEMPLATE:
14206 case Assignment::A_PAR_TEMPL_IN:
14207 case Assignment::A_PAR_TEMPL_OUT:
14208 case Assignment::A_PAR_TEMPL_INOUT:
14209 type_str = ass->get_Type()->get_genname_template(scope);
14210 break;
14211 default:
14212 type_str = ass->get_Type()->get_genname_value(scope);
14213 }
14214 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14215 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
14216 if (ref_expr.postamble) {
14217 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
14218 }
14219 Code::free_expr(&ref_expr);
14220 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14221 }
14222
14223 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
14224 const string& lazy_param_id = value->get_temporary_id();
14225 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14226 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14227 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
14228 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14229 }
14230
14231 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
14232 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
14233 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14234 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14235 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
14236 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14237 }
14238
14239 } // namespace Common
This page took 0.354672 seconds and 6 git commands to generate.