added checkstate operation (artf724009)
[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_CHECKSTATE_ANY: // [r1] v2
302 case OPTYPE_CHECKSTATE_ALL:
303 u.expr.r1=p.u.expr.r1?p.u.expr.r1->clone():0;
304 u.expr.v2=p.u.expr.v2->clone();
305 break;
306 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
307 u.expr.r1=p.u.expr.r1->clone();
308 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
309 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
310 u.expr.b4 = p.u.expr.b4;
311 break;
312 case OPTYPE_MATCH: // v1 t2
313 u.expr.v1=p.u.expr.v1->clone();
314 u.expr.t2=p.u.expr.t2->clone();
315 break;
316 case OPTYPE_ISCHOSEN: // r1 i2
317 u.expr.r1=p.u.expr.r1->clone();
318 u.expr.i2=p.u.expr.i2->clone();
319 break;
320 case OPTYPE_ISCHOSEN_V: // v1 i2
321 u.expr.v1=p.u.expr.v1->clone();
322 u.expr.i2=p.u.expr.i2->clone();
323 break;
324 case OPTYPE_ISCHOSEN_T: // t1 i2
325 u.expr.t1=p.u.expr.t1->clone();
326 u.expr.i2=p.u.expr.i2->clone();
327 break;
328 case OPTYPE_ACTIVATE_REFD:
329 u.expr.v1 = p.u.expr.v1->clone();
330 if(p.u.expr.state!=EXPR_CHECKED)
331 u.expr.t_list2 = p.u.expr.t_list2->clone();
332 else {
333 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
334 u.expr.state = EXPR_CHECKED;
335 }
336 break;
337 case OPTYPE_EXECUTE_REFD:
338 u.expr.v1 = p.u.expr.v1->clone();
339 if(p.u.expr.state!=EXPR_CHECKED)
340 u.expr.t_list2 = p.u.expr.t_list2->clone();
341 else {
342 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
343 u.expr.state = EXPR_CHECKED;
344 }
345 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
346 break;
347 case OPTYPE_LOG2STR:
348 case OPTYPE_ANY2UNISTR:
349 u.expr.logargs = p.u.expr.logargs->clone();
350 break;
351 default:
352 FATAL_ERROR("Value::Value()");
353 } // switch
354 break;
355 case V_MACRO:
356 u.macro = p.u.macro;
357 break;
358 case V_FUNCTION:
359 case V_ALTSTEP:
360 case V_TESTCASE:
361 u.refd_fat = p.u.refd_fat;
362 break;
363 case V_INVOKE:
364 u.invoke.v = p.u.invoke.v->clone();
365 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
366 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
367 break;
368 case V_REFER:
369 u.refered = p.u.refered->clone();
370 break;
371 default:
372 FATAL_ERROR("Value::Value()");
373 } // switch
374 }
375
376 void Value::clean_up()
377 {
378 switch (valuetype) {
379 case V_ERROR:
380 case V_NULL:
381 case V_BOOL:
382 case V_REAL:
383 case V_OMIT:
384 case V_VERDICT:
385 case V_TTCN3_NULL:
386 case V_DEFAULT_NULL:
387 case V_FAT_NULL:
388 case V_MACRO:
389 case V_NOTUSED:
390 case V_FUNCTION:
391 case V_ALTSTEP:
392 case V_TESTCASE:
393 break;
394 case V_INT:
395 delete u.val_Int;
396 break;
397 case V_NAMEDINT:
398 case V_ENUM:
399 case V_UNDEF_LOWERID:
400 delete u.val_id;
401 break;
402 case V_BSTR:
403 case V_HSTR:
404 case V_OSTR:
405 case V_CSTR:
406 case V_ISO2022STR:
407 delete u.str.val_str;
408 clean_up_string_elements(u.str.str_elements);
409 break;
410 case V_USTR:
411 delete u.ustr.val_ustr;
412 clean_up_string_elements(u.ustr.ustr_elements);
413 break;
414 case V_CHARSYMS:
415 delete u.char_syms;
416 break;
417 case V_OID:
418 case V_ROID:
419 if (u.oid_comps) {
420 for(size_t i=0; i<u.oid_comps->size(); i++)
421 delete (*u.oid_comps)[i];
422 u.oid_comps->clear();
423 delete u.oid_comps;
424 }
425 break;
426 case V_EXPR:
427 clean_up_expr();
428 break;
429 case V_CHOICE:
430 delete u.choice.alt_name;
431 delete u.choice.alt_value;
432 break;
433 case V_SEQOF:
434 case V_SETOF:
435 case V_ARRAY:
436 delete u.val_vs;
437 break;
438 case V_SEQ:
439 case V_SET:
440 delete u.val_nvs;
441 break;
442 case V_REFD:
443 delete u.ref.ref;
444 break;
445 case V_REFER:
446 delete u.refered;
447 break;
448 case V_INVOKE:
449 delete u.invoke.v;
450 delete u.invoke.t_list;
451 delete u.invoke.ap_list;
452 break;
453 case V_NAMEDBITS:
454 if(u.ids) {
455 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
456 u.ids->clear();
457 delete u.ids;
458 }
459 break;
460 case V_UNDEF_BLOCK:
461 delete u.block;
462 break;
463 default:
464 FATAL_ERROR("Value::clean_up()");
465 } // switch
466 }
467
468 void Value::clean_up_expr()
469 {
470 switch (u.expr.state) {
471 case EXPR_CHECKING:
472 case EXPR_CHECKING_ERR:
473 FATAL_ERROR("Value::clean_up_expr()");
474 default:
475 break;
476 }
477 switch (u.expr.v_optype) {
478 case OPTYPE_RND: // -
479 case OPTYPE_COMP_NULL:
480 case OPTYPE_COMP_MTC:
481 case OPTYPE_COMP_SYSTEM:
482 case OPTYPE_COMP_SELF:
483 case OPTYPE_COMP_RUNNING_ANY:
484 case OPTYPE_COMP_RUNNING_ALL:
485 case OPTYPE_COMP_ALIVE_ANY:
486 case OPTYPE_COMP_ALIVE_ALL:
487 case OPTYPE_TMR_RUNNING_ANY:
488 case OPTYPE_GETVERDICT:
489 case OPTYPE_TESTCASENAME:
490 case OPTYPE_PROF_RUNNING:
491 break;
492 case OPTYPE_UNARYPLUS: // v1
493 case OPTYPE_UNARYMINUS:
494 case OPTYPE_NOT:
495 case OPTYPE_NOT4B:
496 case OPTYPE_BIT2HEX:
497 case OPTYPE_BIT2INT:
498 case OPTYPE_BIT2OCT:
499 case OPTYPE_BIT2STR:
500 case OPTYPE_CHAR2INT:
501 case OPTYPE_CHAR2OCT:
502 case OPTYPE_COMP_RUNNING:
503 case OPTYPE_COMP_ALIVE:
504 case OPTYPE_FLOAT2INT:
505 case OPTYPE_FLOAT2STR:
506 case OPTYPE_HEX2BIT:
507 case OPTYPE_HEX2INT:
508 case OPTYPE_HEX2OCT:
509 case OPTYPE_HEX2STR:
510 case OPTYPE_INT2CHAR:
511 case OPTYPE_INT2FLOAT:
512 case OPTYPE_INT2STR:
513 case OPTYPE_INT2UNICHAR:
514 case OPTYPE_OCT2BIT:
515 case OPTYPE_OCT2CHAR:
516 case OPTYPE_OCT2HEX:
517 case OPTYPE_OCT2INT:
518 case OPTYPE_OCT2STR:
519 case OPTYPE_STR2BIT:
520 case OPTYPE_STR2FLOAT:
521 case OPTYPE_STR2HEX:
522 case OPTYPE_STR2INT:
523 case OPTYPE_STR2OCT:
524 case OPTYPE_UNICHAR2INT:
525 case OPTYPE_UNICHAR2CHAR:
526 case OPTYPE_ENUM2INT:
527 case OPTYPE_RNDWITHVAL:
528 case OPTYPE_REMOVE_BOM:
529 case OPTYPE_GET_STRINGENCODING:
530 case OPTYPE_DECODE_BASE64:
531 delete u.expr.v1;
532 break;
533 case OPTYPE_ADD: // v1 v2
534 case OPTYPE_SUBTRACT:
535 case OPTYPE_MULTIPLY:
536 case OPTYPE_DIVIDE:
537 case OPTYPE_MOD:
538 case OPTYPE_REM:
539 case OPTYPE_CONCAT:
540 case OPTYPE_EQ:
541 case OPTYPE_LT:
542 case OPTYPE_GT:
543 case OPTYPE_NE:
544 case OPTYPE_GE:
545 case OPTYPE_LE:
546 case OPTYPE_AND:
547 case OPTYPE_OR:
548 case OPTYPE_XOR:
549 case OPTYPE_AND4B:
550 case OPTYPE_OR4B:
551 case OPTYPE_XOR4B:
552 case OPTYPE_SHL:
553 case OPTYPE_SHR:
554 case OPTYPE_ROTL:
555 case OPTYPE_ROTR:
556 case OPTYPE_INT2BIT:
557 case OPTYPE_INT2HEX:
558 case OPTYPE_INT2OCT:
559 case OPTYPE_UNICHAR2OCT:
560 case OPTYPE_OCT2UNICHAR:
561 case OPTYPE_ENCODE_BASE64:
562 delete u.expr.v1;
563 delete u.expr.v2;
564 break;
565 case OPTYPE_DECODE:
566 delete u.expr.r1;
567 delete u.expr.r2;
568 break;
569 case OPTYPE_SUBSTR:
570 delete u.expr.ti1;
571 delete u.expr.v2;
572 delete u.expr.v3;
573 break;
574 case OPTYPE_REGEXP:
575 delete u.expr.ti1;
576 delete u.expr.t2;
577 delete u.expr.v3;
578 break;
579 case OPTYPE_DECOMP: // v1 v2 v3
580 delete u.expr.v1;
581 delete u.expr.v2;
582 delete u.expr.v3;
583 break;
584 case OPTYPE_REPLACE:
585 delete u.expr.ti1;
586 delete u.expr.v2;
587 delete u.expr.v3;
588 delete u.expr.ti4;
589 break;
590 case OPTYPE_LENGTHOF: // ti1
591 case OPTYPE_SIZEOF: // ti1
592 case OPTYPE_VALUEOF: // ti1
593 case OPTYPE_ISVALUE:
594 case OPTYPE_ISBOUND:
595 case OPTYPE_ENCODE:
596 case OPTYPE_ISPRESENT:
597 case OPTYPE_TTCN2STRING:
598 delete u.expr.ti1;
599 break;
600 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
601 delete u.expr.ti1;
602 delete u.expr.v2;
603 break;
604 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
605 delete u.expr.r1;
606 delete u.expr.r2;
607 delete u.expr.v3;
608 break;
609 case OPTYPE_UNDEF_RUNNING:
610 case OPTYPE_TMR_READ:
611 case OPTYPE_TMR_RUNNING:
612 case OPTYPE_ACTIVATE:
613 delete u.expr.r1;
614 break;
615 case OPTYPE_EXECUTE: // r1 [v2]
616 delete u.expr.r1;
617 delete u.expr.v2;
618 break;
619 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
620 case OPTYPE_CHECKSTATE_ALL:
621 delete u.expr.r1;
622 delete u.expr.v2;
623 break;
624 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
625 delete u.expr.r1;
626 delete u.expr.v2;
627 delete u.expr.v3;
628 break;
629 case OPTYPE_MATCH: // v1 t2
630 delete u.expr.v1;
631 delete u.expr.t2;
632 break;
633 case OPTYPE_ISCHOSEN: // r1 i2
634 delete u.expr.r1;
635 delete u.expr.i2;
636 break;
637 case OPTYPE_ISCHOSEN_V: // v1 i2
638 delete u.expr.v1;
639 delete u.expr.i2;
640 break;
641 case OPTYPE_ISCHOSEN_T: // t1 i2
642 delete u.expr.t1;
643 delete u.expr.i2;
644 break;
645 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
646 delete u.expr.v1;
647 if(u.expr.state!=EXPR_CHECKED)
648 delete u.expr.t_list2;
649 else
650 delete u.expr.ap_list2;
651 break;
652 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
653 delete u.expr.v1;
654 if(u.expr.state!=EXPR_CHECKED)
655 delete u.expr.t_list2;
656 else
657 delete u.expr.ap_list2;
658 delete u.expr.v3;
659 break;
660 case OPTYPE_LOG2STR:
661 case OPTYPE_ANY2UNISTR:
662 delete u.expr.logargs;
663 break;
664 default:
665 FATAL_ERROR("Value::clean_up_expr()");
666 } // switch
667 }
668
669 void Value::copy_and_destroy(Value *src)
670 {
671 clean_up();
672 valuetype = src->valuetype;
673 u = src->u;
674 // update the pointer used for caching if it points to the value itself
675 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
676 src->valuetype = V_ERROR;
677 delete src;
678 }
679
680 Value::Value(valuetype_t p_vt)
681 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
682 {
683 switch(valuetype) {
684 case V_NULL:
685 case V_TTCN3_NULL:
686 case V_OMIT:
687 case V_NOTUSED:
688 case V_ERROR:
689 break;
690 case V_OID:
691 case V_ROID:
692 u.oid_comps=new vector<OID_comp>();
693 break;
694 case V_NAMEDBITS:
695 u.ids=new map<string, Identifier>();
696 break;
697 default:
698 FATAL_ERROR("Value::Value()");
699 } // switch
700 }
701
702 Value::Value(valuetype_t p_vt, bool p_val_bool)
703 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
704 {
705 switch(valuetype) {
706 case V_BOOL:
707 u.val_bool=p_val_bool;
708 break;
709 default:
710 FATAL_ERROR("Value::Value()");
711 } // switch
712 }
713
714 Value::Value(valuetype_t p_vt, const Int& 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=new int_val_t(p_val_Int);
720 break;
721 default:
722 FATAL_ERROR("Value::Value()");
723 } // switch
724 }
725
726 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
727 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
728 {
729 switch(valuetype){
730 case V_INT:
731 u.val_Int=p_val_Int;
732 break;
733 default:
734 FATAL_ERROR("Value::Value()");
735 }
736 }
737
738 Value::Value(valuetype_t p_vt, string *p_val_str)
739 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
740 {
741 if(!p_val_str) FATAL_ERROR("NULL parameter");
742 switch(valuetype) {
743 case V_BSTR:
744 case V_HSTR:
745 case V_OSTR:
746 case V_CSTR:
747 case V_ISO2022STR:
748 set_val_str(p_val_str);
749 break;
750 default:
751 FATAL_ERROR("Value::Value()");
752 } // switch
753 }
754
755 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
756 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
757 {
758 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
759 set_val_ustr(p_val_ustr);
760 u.ustr.convert_str = false;
761 }
762
763 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
764 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
765 {
766 if (!p_char_syms) FATAL_ERROR("NULL parameter");
767 switch (valuetype) {
768 case V_CHARSYMS:
769 u.char_syms = p_char_syms;
770 break;
771 default:
772 FATAL_ERROR("Value::Value()");
773 } // switch
774 }
775
776 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
777 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
778 {
779 if(!p_val_id)
780 FATAL_ERROR("NULL parameter");
781 switch(valuetype) {
782 case V_NAMEDINT:
783 case V_ENUM:
784 case V_UNDEF_LOWERID:
785 u.val_id=p_val_id;
786 break;
787 default:
788 FATAL_ERROR("Value::Value()");
789 } // switch
790 }
791
792 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
793 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
794 {
795 if(!p_id || !p_val)
796 FATAL_ERROR("NULL parameter");
797 switch(valuetype) {
798 case V_CHOICE:
799 u.choice.alt_name=p_id;
800 u.choice.alt_value=p_val;
801 break;
802 default:
803 FATAL_ERROR("Value::Value()");
804 } // switch
805 }
806
807 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
808 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
809 {
810 switch(valuetype) {
811 case V_REAL:
812 u.val_Real=p_val_Real;
813 break;
814 default:
815 FATAL_ERROR("Value::Value()");
816 } // switch
817 }
818
819 Value::Value(valuetype_t p_vt, Values *p_vs)
820 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
821 {
822 if(!p_vs) FATAL_ERROR("NULL parameter");
823 switch(valuetype) {
824 case V_SEQOF:
825 case V_SETOF:
826 case V_ARRAY:
827 u.val_vs=p_vs;
828 break;
829 default:
830 FATAL_ERROR("Value::Value()");
831 } // switch
832 }
833
834 Value::Value(valuetype_t p_vt, Value *p_v,
835 Ttcn::ParsedActualParameters *p_t_list)
836 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
837 {
838 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
839 switch(valuetype) {
840 case V_INVOKE:
841 u.invoke.v = p_v;
842 u.invoke.t_list = p_t_list;
843 u.invoke.ap_list = 0;
844 break;
845 default:
846 FATAL_ERROR("Value::Value()");
847 }
848 }
849
850 // -
851 Value::Value(operationtype_t p_optype)
852 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
853 {
854 u.expr.v_optype = p_optype;
855 u.expr.state = EXPR_NOT_CHECKED;
856 switch(p_optype) {
857 case OPTYPE_RND:
858 case OPTYPE_COMP_NULL:
859 case OPTYPE_COMP_MTC:
860 case OPTYPE_COMP_SYSTEM:
861 case OPTYPE_COMP_SELF:
862 case OPTYPE_COMP_RUNNING_ANY:
863 case OPTYPE_COMP_RUNNING_ALL:
864 case OPTYPE_COMP_ALIVE_ANY:
865 case OPTYPE_COMP_ALIVE_ALL:
866 case OPTYPE_TMR_RUNNING_ANY:
867 case OPTYPE_GETVERDICT:
868 case OPTYPE_TESTCASENAME:
869 case OPTYPE_PROF_RUNNING:
870 break;
871 default:
872 FATAL_ERROR("Value::Value()");
873 } // switch
874 }
875
876 // v1
877 Value::Value(operationtype_t p_optype, Value *p_v1)
878 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
879 {
880 u.expr.v_optype = p_optype;
881 u.expr.state = EXPR_NOT_CHECKED;
882 switch(p_optype) {
883 case OPTYPE_UNARYPLUS:
884 case OPTYPE_UNARYMINUS:
885 case OPTYPE_NOT:
886 case OPTYPE_NOT4B:
887 case OPTYPE_BIT2HEX:
888 case OPTYPE_BIT2INT:
889 case OPTYPE_BIT2OCT:
890 case OPTYPE_BIT2STR:
891 case OPTYPE_CHAR2INT:
892 case OPTYPE_CHAR2OCT:
893 case OPTYPE_COMP_RUNNING:
894 case OPTYPE_COMP_ALIVE:
895 case OPTYPE_FLOAT2INT:
896 case OPTYPE_FLOAT2STR:
897 case OPTYPE_HEX2BIT:
898 case OPTYPE_HEX2INT:
899 case OPTYPE_HEX2OCT:
900 case OPTYPE_HEX2STR:
901 case OPTYPE_INT2CHAR:
902 case OPTYPE_INT2FLOAT:
903 case OPTYPE_INT2STR:
904 case OPTYPE_INT2UNICHAR:
905 case OPTYPE_OCT2BIT:
906 case OPTYPE_OCT2CHAR:
907 case OPTYPE_OCT2HEX:
908 case OPTYPE_OCT2INT:
909 case OPTYPE_OCT2STR:
910 case OPTYPE_STR2BIT:
911 case OPTYPE_STR2FLOAT:
912 case OPTYPE_STR2HEX:
913 case OPTYPE_STR2INT:
914 case OPTYPE_STR2OCT:
915 case OPTYPE_UNICHAR2INT:
916 case OPTYPE_UNICHAR2CHAR:
917 case OPTYPE_ENUM2INT:
918 case OPTYPE_RNDWITHVAL:
919 case OPTYPE_REMOVE_BOM:
920 case OPTYPE_GET_STRINGENCODING:
921 case OPTYPE_DECODE_BASE64:
922 if(!p_v1) FATAL_ERROR("Value::Value()");
923 u.expr.v1=p_v1;
924 break;
925 default:
926 FATAL_ERROR("Value::Value()");
927 } // switch
928 }
929
930 // ti1
931 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
932 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
933 {
934 u.expr.v_optype = p_optype;
935 u.expr.state = EXPR_NOT_CHECKED;
936 switch(p_optype) {
937 case OPTYPE_LENGTHOF:
938 case OPTYPE_SIZEOF:
939 case OPTYPE_VALUEOF:
940 case OPTYPE_ISVALUE:
941 case OPTYPE_ISBOUND:
942 case OPTYPE_ENCODE:
943 case OPTYPE_ENCVALUE_UNICHAR:
944 case OPTYPE_ISPRESENT:
945 case OPTYPE_TTCN2STRING:
946 if(!p_ti1) FATAL_ERROR("Value::Value()");
947 u.expr.ti1=p_ti1;
948 break;
949 default:
950 FATAL_ERROR("Value::Value()");
951 } // switch
952 }
953
954 // r1
955 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
956 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
957 {
958 u.expr.v_optype = p_optype;
959 u.expr.state = EXPR_NOT_CHECKED;
960 switch(p_optype) {
961 case OPTYPE_UNDEF_RUNNING:
962 case OPTYPE_TMR_READ:
963 case OPTYPE_TMR_RUNNING:
964 case OPTYPE_ACTIVATE:
965 if(!p_r1) FATAL_ERROR("Value::Value()");
966 u.expr.r1=p_r1;
967 break;
968 default:
969 FATAL_ERROR("Value::Value()");
970 } // switch
971 }
972
973 // v1 t_list2
974 Value::Value(operationtype_t p_optype, Value *p_v1,
975 Ttcn::ParsedActualParameters *p_ap_list)
976 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
977 {
978 u.expr.v_optype = p_optype;
979 u.expr.state = EXPR_NOT_CHECKED;
980 switch(p_optype) {
981 case OPTYPE_ACTIVATE_REFD:
982 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
983 u.expr.v1 = p_v1;
984 u.expr.t_list2 = p_ap_list;
985 break;
986 default:
987 FATAL_ERROR("Value::Value()");
988 }
989 }
990
991 //v1 t_list2 v3
992 Value::Value(operationtype_t p_optype, Value *p_v1,
993 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
994 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
995 {
996 u.expr.v_optype = p_optype;
997 u.expr.state = EXPR_NOT_CHECKED;
998 switch(p_optype) {
999 case OPTYPE_EXECUTE_REFD:
1000 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
1001 u.expr.v1 = p_v1;
1002 u.expr.t_list2 = p_t_list2;
1003 u.expr.v3 = p_v3;
1004 break;
1005 default:
1006 FATAL_ERROR("Value::Value()");
1007 }
1008 }
1009
1010 // r1 [v2] or [r1] v2
1011 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
1012 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1013 {
1014 u.expr.v_optype = p_optype;
1015 u.expr.state = EXPR_NOT_CHECKED;
1016 switch(p_optype) {
1017 case OPTYPE_EXECUTE:
1018 if(!p_r1) FATAL_ERROR("Value::Value()");
1019 u.expr.r1=p_r1;
1020 u.expr.v2=p_v2;
1021 break;
1022 case OPTYPE_CHECKSTATE_ANY:
1023 case OPTYPE_CHECKSTATE_ALL:
1024 if(!p_v2) FATAL_ERROR("Value::Value()");
1025 u.expr.r1=p_r1; // may be null if any port or all port
1026 u.expr.v2=p_v2;
1027 break;
1028 default:
1029 FATAL_ERROR("Value::Value()");
1030 } // switch
1031 }
1032
1033 // r1 [v2] [v3] b4
1034 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
1035 Value *p_v2, Value *p_v3, bool p_b4)
1036 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1037 {
1038 u.expr.v_optype = p_optype;
1039 u.expr.state = EXPR_NOT_CHECKED;
1040 switch(p_optype) {
1041 case OPTYPE_COMP_CREATE:
1042 if(!p_r1) FATAL_ERROR("Value::Value()");
1043 u.expr.r1=p_r1;
1044 u.expr.v2=p_v2;
1045 u.expr.v3=p_v3;
1046 u.expr.b4=p_b4;
1047 break;
1048 default:
1049 FATAL_ERROR("Value::Value()");
1050 } // switch
1051 }
1052
1053 // v1 v2
1054 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
1055 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1056 {
1057 u.expr.v_optype = p_optype;
1058 u.expr.state = EXPR_NOT_CHECKED;
1059 switch(p_optype) {
1060 case OPTYPE_ADD:
1061 case OPTYPE_SUBTRACT:
1062 case OPTYPE_MULTIPLY:
1063 case OPTYPE_DIVIDE:
1064 case OPTYPE_MOD:
1065 case OPTYPE_REM:
1066 case OPTYPE_CONCAT:
1067 case OPTYPE_EQ:
1068 case OPTYPE_LT:
1069 case OPTYPE_GT:
1070 case OPTYPE_NE:
1071 case OPTYPE_GE:
1072 case OPTYPE_LE:
1073 case OPTYPE_AND:
1074 case OPTYPE_OR:
1075 case OPTYPE_XOR:
1076 case OPTYPE_AND4B:
1077 case OPTYPE_OR4B:
1078 case OPTYPE_XOR4B:
1079 case OPTYPE_SHL:
1080 case OPTYPE_SHR:
1081 case OPTYPE_ROTL:
1082 case OPTYPE_ROTR:
1083 case OPTYPE_INT2BIT:
1084 case OPTYPE_INT2HEX:
1085 case OPTYPE_INT2OCT:
1086 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1087 u.expr.v1=p_v1;
1088 u.expr.v2=p_v2;
1089 break;
1090 case OPTYPE_UNICHAR2OCT:
1091 case OPTYPE_OCT2UNICHAR:
1092 case OPTYPE_ENCODE_BASE64:
1093 if(!p_v1) FATAL_ERROR("Value::Value()");
1094 u.expr.v1=p_v1;
1095 // p_v2 may be NULL if there is no second param
1096 u.expr.v2=p_v2;
1097 break;
1098 default:
1099 FATAL_ERROR("Value::Value()");
1100 } // switch
1101 }
1102
1103 // ti1 v2 v3 ti4
1104 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1105 Value *p_v3, TemplateInstance *p_ti4) :
1106 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1107 {
1108 u.expr.v_optype = p_optype;
1109 u.expr.state = EXPR_NOT_CHECKED;
1110 switch (p_optype) {
1111 case OPTYPE_REPLACE:
1112 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1113 u.expr.ti1 = p_ti1;
1114 u.expr.v2 = p_v2;
1115 u.expr.v3 = p_v3;
1116 u.expr.ti4 = p_ti4;
1117 break;
1118 default:
1119 FATAL_ERROR("Value::Value()");
1120 } // switch
1121 }
1122
1123 // v1 v2 v3
1124 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
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_DECOMP:
1131 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1132 u.expr.v1=p_v1;
1133 u.expr.v2=p_v2;
1134 u.expr.v3=p_v3;
1135 break;
1136 default:
1137 FATAL_ERROR("Value::Value()");
1138 } // switch
1139 }
1140
1141 // ti1 [v2]
1142 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2)
1143 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1144 {
1145 u.expr.v_optype = p_optype;
1146 u.expr.state = EXPR_NOT_CHECKED;
1147 switch(p_optype) {
1148 case OPTYPE_ENCVALUE_UNICHAR:
1149 if(!p_ti1 || !p_v2) FATAL_ERROR("Value::Value()");
1150 u.expr.ti1=p_ti1;
1151 u.expr.v2=p_v2;
1152 break;
1153 default:
1154 FATAL_ERROR("Value::Value()");
1155 } // switch
1156 }
1157
1158 // ti1 v2 v3
1159 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, 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_SUBSTR:
1166 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1167 u.expr.ti1 = p_ti1;
1168 u.expr.v2=p_v2;
1169 u.expr.v3=p_v3;
1170 break;
1171 default:
1172 FATAL_ERROR("Value::Value()");
1173 } // switch
1174 }
1175
1176 // ti1 t2 v3
1177 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
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_REGEXP:
1184 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1185 u.expr.ti1 = p_ti1;
1186 u.expr.t2 = p_t2;
1187 u.expr.v3=p_v3;
1188 break;
1189 default:
1190 FATAL_ERROR("Value::Value()");
1191 } // switch
1192 }
1193
1194 // v1 t2
1195 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
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_MATCH:
1202 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1203 u.expr.v1=p_v1;
1204 u.expr.t2=p_t2;
1205 break;
1206 default:
1207 FATAL_ERROR("Value::Value()");
1208 } // switch
1209 }
1210
1211 // r1 i2
1212 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1213 Identifier *p_i2)
1214 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1215 {
1216 u.expr.v_optype = p_optype;
1217 u.expr.state = EXPR_NOT_CHECKED;
1218 switch(p_optype) {
1219 case OPTYPE_ISCHOSEN:
1220 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1221 u.expr.r1=p_r1;
1222 u.expr.i2=p_i2;
1223 break;
1224 default:
1225 FATAL_ERROR("Value::Value()");
1226 } // switch
1227 }
1228
1229 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1230 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1231 {
1232 u.expr.v_optype = p_optype;
1233 u.expr.state = EXPR_NOT_CHECKED;
1234 switch(p_optype) {
1235 case OPTYPE_LOG2STR:
1236 case OPTYPE_ANY2UNISTR:
1237 if (!p_logargs) FATAL_ERROR("Value::Value()");
1238 u.expr.logargs = p_logargs;
1239 break;
1240 default:
1241 FATAL_ERROR("Value::Value()");
1242 } // switch
1243 }
1244
1245 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1246 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1247 {
1248 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1249 switch (p_macrotype) {
1250 case MACRO_MODULEID:
1251 case MACRO_FILENAME:
1252 case MACRO_BFILENAME:
1253 case MACRO_FILEPATH:
1254 case MACRO_LINENUMBER:
1255 case MACRO_LINENUMBER_C:
1256 case MACRO_DEFINITIONID:
1257 case MACRO_SCOPE:
1258 case MACRO_TESTCASEID:
1259 break;
1260 default:
1261 FATAL_ERROR("Value::Value()");
1262 }
1263 u.macro = p_macrotype;
1264 }
1265
1266 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1267 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1268 {
1269 if(!p_nvs) FATAL_ERROR("NULL parameter");
1270 switch(valuetype) {
1271 case V_SEQ:
1272 case V_SET:
1273 u.val_nvs=p_nvs;
1274 break;
1275 default:
1276 FATAL_ERROR("Value::Value()");
1277 } // switch
1278 }
1279
1280 Value::Value(valuetype_t p_vt, Reference *p_ref)
1281 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1282 {
1283 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1284 switch(p_vt) {
1285 case V_REFD:
1286 u.ref.ref = p_ref;
1287 u.ref.refd_last = 0;
1288 break;
1289 case V_REFER:
1290 u.refered = p_ref;
1291 break;
1292 default:
1293 FATAL_ERROR("Value::Value()");
1294 }
1295 }
1296
1297 Value::Value(valuetype_t p_vt, Block *p_block)
1298 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1299 {
1300 if(!p_block) FATAL_ERROR("NULL parameter");
1301 switch(valuetype) {
1302 case V_UNDEF_BLOCK:
1303 u.block=p_block;
1304 break;
1305 default:
1306 FATAL_ERROR("Value::Value()");
1307 } // switch
1308 }
1309
1310 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1311 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1312 {
1313 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1314 switch (p_verdict) {
1315 case Verdict_NONE:
1316 case Verdict_PASS:
1317 case Verdict_INCONC:
1318 case Verdict_FAIL:
1319 case Verdict_ERROR:
1320 break;
1321 default:
1322 FATAL_ERROR("Value::Value()");
1323 } // switch
1324 u.verdict = p_verdict;
1325 }
1326
1327 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
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_DECODE:
1334 case OPTYPE_DECVALUE_UNICHAR:
1335 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1336 u.expr.r1=p_r1;
1337 u.expr.r2=p_r2;
1338 break;
1339 default:
1340 FATAL_ERROR("Value::Value()");
1341 } // switch
1342 }
1343
1344 // r1 r2 [v3]
1345 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2,
1346 Value *p_v3)
1347 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1348 {
1349 u.expr.v_optype = p_optype;
1350 u.expr.state = EXPR_NOT_CHECKED;
1351 switch(p_optype) {
1352 case OPTYPE_DECVALUE_UNICHAR:
1353 if(!p_r1 || !p_r2 || !p_v3) FATAL_ERROR("Value::Value()");
1354 u.expr.r1=p_r1;
1355 u.expr.r2=p_r2;
1356 u.expr.v3=p_v3;
1357 break;
1358 default:
1359 FATAL_ERROR("Value::Value()");
1360 } // switch
1361 }
1362
1363 Value::~Value()
1364 {
1365 clean_up();
1366 }
1367
1368 Value *Value::clone() const
1369 {
1370 return new Value(*this);
1371 }
1372
1373 Value::operationtype_t Value::get_optype() const
1374 {
1375 if(valuetype!=V_EXPR)
1376 FATAL_ERROR("Value::get_optype()");
1377 return u.expr.v_optype;
1378 }
1379
1380 void Value::set_my_governor(Type *p_gov)
1381 {
1382 if(!p_gov)
1383 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1384 my_governor=p_gov;
1385 }
1386
1387 Type *Value::get_my_governor() const
1388 {
1389 return my_governor;
1390 }
1391
1392 void Value::set_fullname(const string& p_fullname)
1393 {
1394 GovernedSimple::set_fullname(p_fullname);
1395 switch(valuetype) {
1396 case V_CHARSYMS:
1397 u.char_syms->set_fullname(p_fullname);
1398 break;
1399 case V_OID:
1400 case V_ROID:
1401 for(size_t i=0; i<u.oid_comps->size(); i++)
1402 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1403 break;
1404 case V_CHOICE:
1405 u.choice.alt_value->set_fullname(p_fullname + "." +
1406 u.choice.alt_name->get_dispname());
1407 break;
1408 case V_SEQOF:
1409 case V_SETOF:
1410 case V_ARRAY:
1411 u.val_vs->set_fullname(p_fullname);
1412 break;
1413 case V_SEQ:
1414 case V_SET:
1415 u.val_nvs->set_fullname(p_fullname);
1416 break;
1417 case V_REFD:
1418 u.ref.ref->set_fullname(p_fullname);
1419 break;
1420 case V_REFER:
1421 u.refered->set_fullname(p_fullname);
1422 break;
1423 case V_INVOKE:
1424 u.invoke.v->set_fullname(p_fullname);
1425 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1426 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1427 break;
1428 case V_EXPR:
1429 set_fullname_expr(p_fullname);
1430 break;
1431 default:
1432 break;
1433 } // switch
1434 }
1435
1436 void Value::set_my_scope(Scope *p_scope)
1437 {
1438 GovernedSimple::set_my_scope(p_scope);
1439 switch(valuetype) {
1440 case V_CHARSYMS:
1441 u.char_syms->set_my_scope(p_scope);
1442 break;
1443 case V_OID:
1444 case V_ROID:
1445 for(size_t i=0; i<u.oid_comps->size(); i++)
1446 (*u.oid_comps)[i]->set_my_scope(p_scope);
1447 break;
1448 case V_CHOICE:
1449 u.choice.alt_value->set_my_scope(p_scope);
1450 break;
1451 case V_SEQOF:
1452 case V_SETOF:
1453 case V_ARRAY:
1454 u.val_vs->set_my_scope(p_scope);
1455 break;
1456 case V_SEQ:
1457 case V_SET:
1458 u.val_nvs->set_my_scope(p_scope);
1459 break;
1460 case V_REFD:
1461 u.ref.ref->set_my_scope(p_scope);
1462 break;
1463 case V_REFER:
1464 u.refered->set_my_scope(p_scope);
1465 break;
1466 case V_INVOKE:
1467 u.invoke.v->set_my_scope(p_scope);
1468 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1469 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1470 break;
1471 case V_EXPR:
1472 set_my_scope_expr(p_scope);
1473 break;
1474 default:
1475 break;
1476 } // switch
1477 }
1478
1479 void Value::set_fullname_expr(const string& p_fullname)
1480 {
1481 switch (u.expr.v_optype) {
1482 case OPTYPE_RND: // -
1483 case OPTYPE_COMP_NULL:
1484 case OPTYPE_COMP_MTC:
1485 case OPTYPE_COMP_SYSTEM:
1486 case OPTYPE_COMP_SELF:
1487 case OPTYPE_COMP_RUNNING_ANY:
1488 case OPTYPE_COMP_RUNNING_ALL:
1489 case OPTYPE_COMP_ALIVE_ANY:
1490 case OPTYPE_COMP_ALIVE_ALL:
1491 case OPTYPE_TMR_RUNNING_ANY:
1492 case OPTYPE_GETVERDICT:
1493 case OPTYPE_TESTCASENAME:
1494 case OPTYPE_PROF_RUNNING:
1495 break;
1496 case OPTYPE_UNARYPLUS: // v1
1497 case OPTYPE_UNARYMINUS:
1498 case OPTYPE_NOT:
1499 case OPTYPE_NOT4B:
1500 case OPTYPE_BIT2HEX:
1501 case OPTYPE_BIT2INT:
1502 case OPTYPE_BIT2OCT:
1503 case OPTYPE_BIT2STR:
1504 case OPTYPE_CHAR2INT:
1505 case OPTYPE_CHAR2OCT:
1506 case OPTYPE_COMP_RUNNING:
1507 case OPTYPE_COMP_ALIVE:
1508 case OPTYPE_FLOAT2INT:
1509 case OPTYPE_FLOAT2STR:
1510 case OPTYPE_HEX2BIT:
1511 case OPTYPE_HEX2INT:
1512 case OPTYPE_HEX2OCT:
1513 case OPTYPE_HEX2STR:
1514 case OPTYPE_INT2CHAR:
1515 case OPTYPE_INT2FLOAT:
1516 case OPTYPE_INT2STR:
1517 case OPTYPE_INT2UNICHAR:
1518 case OPTYPE_OCT2BIT:
1519 case OPTYPE_OCT2CHAR:
1520 case OPTYPE_OCT2HEX:
1521 case OPTYPE_OCT2INT:
1522 case OPTYPE_OCT2STR:
1523 case OPTYPE_STR2BIT:
1524 case OPTYPE_STR2FLOAT:
1525 case OPTYPE_STR2HEX:
1526 case OPTYPE_STR2INT:
1527 case OPTYPE_STR2OCT:
1528 case OPTYPE_UNICHAR2INT:
1529 case OPTYPE_UNICHAR2CHAR:
1530 case OPTYPE_ENUM2INT:
1531 case OPTYPE_RNDWITHVAL:
1532 case OPTYPE_REMOVE_BOM:
1533 case OPTYPE_GET_STRINGENCODING:
1534 case OPTYPE_DECODE_BASE64:
1535 u.expr.v1->set_fullname(p_fullname+".<operand>");
1536 break;
1537 case OPTYPE_ADD: // v1 v2
1538 case OPTYPE_SUBTRACT:
1539 case OPTYPE_MULTIPLY:
1540 case OPTYPE_DIVIDE:
1541 case OPTYPE_MOD:
1542 case OPTYPE_REM:
1543 case OPTYPE_CONCAT:
1544 case OPTYPE_EQ:
1545 case OPTYPE_LT:
1546 case OPTYPE_GT:
1547 case OPTYPE_NE:
1548 case OPTYPE_GE:
1549 case OPTYPE_LE:
1550 case OPTYPE_AND:
1551 case OPTYPE_OR:
1552 case OPTYPE_XOR:
1553 case OPTYPE_AND4B:
1554 case OPTYPE_OR4B:
1555 case OPTYPE_XOR4B:
1556 case OPTYPE_SHL:
1557 case OPTYPE_SHR:
1558 case OPTYPE_ROTL:
1559 case OPTYPE_ROTR:
1560 case OPTYPE_INT2BIT:
1561 case OPTYPE_INT2HEX:
1562 case OPTYPE_INT2OCT:
1563 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1564 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1565 break;
1566 case OPTYPE_UNICHAR2OCT:
1567 case OPTYPE_OCT2UNICHAR:
1568 case OPTYPE_ENCODE_BASE64:
1569 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1570 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1571 break;
1572 case OPTYPE_DECODE:
1573 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1574 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1575 break;
1576 case OPTYPE_SUBSTR:
1577 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1578 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1579 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1580 break;
1581 case OPTYPE_REGEXP:
1582 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1583 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1584 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1585 break;
1586 case OPTYPE_DECOMP: // v1 v2 v3
1587 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1588 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1589 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1590 break;
1591 case OPTYPE_REPLACE:
1592 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1593 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1594 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1595 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1596 break;
1597 case OPTYPE_LENGTHOF: // ti1
1598 case OPTYPE_SIZEOF: // ti1
1599 case OPTYPE_VALUEOF: // ti1
1600 case OPTYPE_ISVALUE:
1601 case OPTYPE_ISBOUND:
1602 case OPTYPE_ENCODE:
1603 case OPTYPE_ISPRESENT:
1604 case OPTYPE_TTCN2STRING:
1605 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1606 break;
1607 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
1608 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1609 if (u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1610 break;
1611 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1612 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1613 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1614 if (u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1615 case OPTYPE_UNDEF_RUNNING: // r1
1616 case OPTYPE_TMR_READ:
1617 case OPTYPE_TMR_RUNNING:
1618 case OPTYPE_ACTIVATE:
1619 u.expr.r1->set_fullname(p_fullname+".<operand>");
1620 break;
1621 case OPTYPE_EXECUTE: // r1 [v2]
1622 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1623 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1624 break;
1625 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1626 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1627 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1628 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1629 break;
1630 case OPTYPE_MATCH: // v1 t2
1631 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1632 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1633 break;
1634 case OPTYPE_ISCHOSEN: // r1 i2
1635 u.expr.r1->set_fullname(p_fullname+".<operand>");
1636 break;
1637 case OPTYPE_ISCHOSEN_V: // v1 i2
1638 u.expr.v1->set_fullname(p_fullname+".<operand>");
1639 break;
1640 case OPTYPE_ISCHOSEN_T: // t1 i2
1641 u.expr.t1->set_fullname(p_fullname+".<operand>");
1642 break;
1643 case OPTYPE_ACTIVATE_REFD:
1644 u.expr.v1->set_fullname(p_fullname+".<reference>");
1645 if(u.expr.state!=EXPR_CHECKED)
1646 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1647 else
1648 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1649 break;
1650 case OPTYPE_EXECUTE_REFD:
1651 u.expr.v1->set_fullname(p_fullname+".<reference>");
1652 if(u.expr.state!=EXPR_CHECKED)
1653 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1654 else
1655 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1656 if(u.expr.v3)
1657 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1658 break;
1659 case OPTYPE_LOG2STR:
1660 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1661 break;
1662 case OPTYPE_ANY2UNISTR:
1663 u.expr.logargs->set_fullname(p_fullname+".<logarg>");
1664 break;
1665 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
1666 case OPTYPE_CHECKSTATE_ALL:
1667 u.expr.v2->set_fullname(p_fullname+".<operand1>");
1668 break;
1669 default:
1670 FATAL_ERROR("Value::set_fullname_expr()");
1671 } // switch
1672 }
1673
1674 void Value::set_my_scope_expr(Scope *p_scope)
1675 {
1676 switch (u.expr.v_optype) {
1677 case OPTYPE_RND: // -
1678 case OPTYPE_COMP_NULL:
1679 case OPTYPE_COMP_MTC:
1680 case OPTYPE_COMP_SYSTEM:
1681 case OPTYPE_COMP_SELF:
1682 case OPTYPE_COMP_RUNNING_ANY:
1683 case OPTYPE_COMP_RUNNING_ALL:
1684 case OPTYPE_COMP_ALIVE_ANY:
1685 case OPTYPE_COMP_ALIVE_ALL:
1686 case OPTYPE_TMR_RUNNING_ANY:
1687 case OPTYPE_GETVERDICT:
1688 case OPTYPE_TESTCASENAME:
1689 case OPTYPE_PROF_RUNNING:
1690 break;
1691 case OPTYPE_UNARYPLUS: // v1
1692 case OPTYPE_UNARYMINUS:
1693 case OPTYPE_NOT:
1694 case OPTYPE_NOT4B:
1695 case OPTYPE_BIT2HEX:
1696 case OPTYPE_BIT2INT:
1697 case OPTYPE_BIT2OCT:
1698 case OPTYPE_BIT2STR:
1699 case OPTYPE_CHAR2INT:
1700 case OPTYPE_CHAR2OCT:
1701 case OPTYPE_COMP_RUNNING:
1702 case OPTYPE_COMP_ALIVE:
1703 case OPTYPE_FLOAT2INT:
1704 case OPTYPE_FLOAT2STR:
1705 case OPTYPE_HEX2BIT:
1706 case OPTYPE_HEX2INT:
1707 case OPTYPE_HEX2OCT:
1708 case OPTYPE_HEX2STR:
1709 case OPTYPE_INT2CHAR:
1710 case OPTYPE_INT2FLOAT:
1711 case OPTYPE_INT2STR:
1712 case OPTYPE_INT2UNICHAR:
1713 case OPTYPE_OCT2BIT:
1714 case OPTYPE_OCT2CHAR:
1715 case OPTYPE_OCT2HEX:
1716 case OPTYPE_OCT2INT:
1717 case OPTYPE_OCT2STR:
1718 case OPTYPE_STR2BIT:
1719 case OPTYPE_STR2FLOAT:
1720 case OPTYPE_STR2HEX:
1721 case OPTYPE_STR2INT:
1722 case OPTYPE_STR2OCT:
1723 case OPTYPE_UNICHAR2INT:
1724 case OPTYPE_UNICHAR2CHAR:
1725 case OPTYPE_ENUM2INT:
1726 case OPTYPE_RNDWITHVAL:
1727 case OPTYPE_REMOVE_BOM:
1728 case OPTYPE_GET_STRINGENCODING:
1729 case OPTYPE_DECODE_BASE64:
1730 u.expr.v1->set_my_scope(p_scope);
1731 break;
1732 case OPTYPE_ADD: // v1 v2
1733 case OPTYPE_SUBTRACT:
1734 case OPTYPE_MULTIPLY:
1735 case OPTYPE_DIVIDE:
1736 case OPTYPE_MOD:
1737 case OPTYPE_REM:
1738 case OPTYPE_CONCAT:
1739 case OPTYPE_EQ:
1740 case OPTYPE_LT:
1741 case OPTYPE_GT:
1742 case OPTYPE_NE:
1743 case OPTYPE_GE:
1744 case OPTYPE_LE:
1745 case OPTYPE_AND:
1746 case OPTYPE_OR:
1747 case OPTYPE_XOR:
1748 case OPTYPE_AND4B:
1749 case OPTYPE_OR4B:
1750 case OPTYPE_XOR4B:
1751 case OPTYPE_SHL:
1752 case OPTYPE_SHR:
1753 case OPTYPE_ROTL:
1754 case OPTYPE_ROTR:
1755 case OPTYPE_INT2BIT:
1756 case OPTYPE_INT2HEX:
1757 case OPTYPE_INT2OCT:
1758 u.expr.v1->set_my_scope(p_scope);
1759 u.expr.v2->set_my_scope(p_scope);
1760 break;
1761 case OPTYPE_UNICHAR2OCT:
1762 case OPTYPE_OCT2UNICHAR:
1763 case OPTYPE_ENCODE_BASE64:
1764 u.expr.v1->set_my_scope(p_scope);
1765 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1766 break;
1767 case OPTYPE_DECODE:
1768 u.expr.r1->set_my_scope(p_scope);
1769 u.expr.r2->set_my_scope(p_scope);
1770 break;
1771 case OPTYPE_SUBSTR:
1772 u.expr.ti1->set_my_scope(p_scope);
1773 u.expr.v2->set_my_scope(p_scope);
1774 u.expr.v3->set_my_scope(p_scope);
1775 break;
1776 case OPTYPE_REGEXP:
1777 u.expr.ti1->set_my_scope(p_scope);
1778 u.expr.t2->set_my_scope(p_scope);
1779 u.expr.v3->set_my_scope(p_scope);
1780 break;
1781 case OPTYPE_DECOMP: // v1 v2 v3
1782 u.expr.v1->set_my_scope(p_scope);
1783 u.expr.v2->set_my_scope(p_scope);
1784 u.expr.v3->set_my_scope(p_scope);
1785 break;
1786 case OPTYPE_REPLACE:
1787 u.expr.ti1->set_my_scope(p_scope);
1788 u.expr.v2->set_my_scope(p_scope);
1789 u.expr.v3->set_my_scope(p_scope);
1790 u.expr.ti4->set_my_scope(p_scope);
1791 break;
1792 case OPTYPE_LENGTHOF: // ti1
1793 case OPTYPE_SIZEOF: // ti1
1794 case OPTYPE_VALUEOF: // ti1
1795 case OPTYPE_ISVALUE:
1796 case OPTYPE_ISBOUND:
1797 case OPTYPE_ENCODE:
1798 case OPTYPE_ISPRESENT:
1799 case OPTYPE_TTCN2STRING:
1800 u.expr.ti1->set_my_scope(p_scope);
1801 break;
1802 case OPTYPE_ENCVALUE_UNICHAR: //ti1 [v2]
1803 u.expr.ti1->set_my_scope(p_scope);
1804 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1805 break;
1806 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1807 u.expr.r1->set_my_scope(p_scope);
1808 u.expr.r2->set_my_scope(p_scope);
1809 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1810 break;
1811 case OPTYPE_UNDEF_RUNNING: // r1
1812 case OPTYPE_TMR_READ:
1813 case OPTYPE_TMR_RUNNING:
1814 case OPTYPE_ACTIVATE:
1815 u.expr.r1->set_my_scope(p_scope);
1816 break;
1817 case OPTYPE_EXECUTE: // r1 [v2]
1818 u.expr.r1->set_my_scope(p_scope);
1819 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1820 break;
1821 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
1822 case OPTYPE_CHECKSTATE_ALL:
1823 if(u.expr.r1) u.expr.r1->set_my_scope(p_scope);
1824 u.expr.v2->set_my_scope(p_scope);
1825 break;
1826 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1827 u.expr.r1->set_my_scope(p_scope);
1828 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1829 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1830 break;
1831 case OPTYPE_MATCH: // v1 t2
1832 u.expr.v1->set_my_scope(p_scope);
1833 u.expr.t2->set_my_scope(p_scope);
1834 break;
1835 case OPTYPE_ISCHOSEN: // r1 i2
1836 u.expr.r1->set_my_scope(p_scope);
1837 break;
1838 case OPTYPE_ISCHOSEN_V: // v1 i2
1839 u.expr.v1->set_my_scope(p_scope);
1840 break;
1841 case OPTYPE_ISCHOSEN_T: // t1 i2
1842 u.expr.t1->set_my_scope(p_scope);
1843 break;
1844 case OPTYPE_ACTIVATE_REFD:
1845 u.expr.v1->set_my_scope(p_scope);
1846 if(u.expr.state!=EXPR_CHECKED) {
1847 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1848 else
1849 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1850 } break;
1851 case OPTYPE_EXECUTE_REFD:
1852 u.expr.v1->set_my_scope(p_scope);
1853 if(u.expr.state!=EXPR_CHECKED) {
1854 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1855 else
1856 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1857 }
1858 if(u.expr.v3)
1859 u.expr.v3->set_my_scope(p_scope);
1860 break;
1861 case OPTYPE_LOG2STR:
1862 case OPTYPE_ANY2UNISTR:
1863 u.expr.logargs->set_my_scope(p_scope);
1864 break;
1865 default:
1866 FATAL_ERROR("Value::set_my_scope_expr()");
1867 } // switch
1868 }
1869
1870 void Value::set_genname_recursive(const string& p_genname)
1871 {
1872 size_t genname_len = p_genname.size();
1873 if (genname_len >= 4 &&
1874 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1875 // if the genname ends with ()() (i.e. the value stands for an optional
1876 // field) then drop the last () from the own genname, but leave it for
1877 // the embedded values
1878 set_genname(p_genname.substr(0, genname_len - 2));
1879 } else set_genname(p_genname);
1880 switch(valuetype) {
1881 case V_CHOICE: {
1882 string embedded_genname(p_genname);
1883 embedded_genname += '.';
1884 // If this is a choice value for an anytype, prepend the AT_ prefix
1885 // to the name of the alternative. The genname is used later in
1886 // Common::Value::generate_code_init_se()
1887 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1888 embedded_genname += "AT_";
1889 embedded_genname += u.choice.alt_name->get_name();
1890 embedded_genname += "()";
1891 u.choice.alt_value->set_genname_recursive(embedded_genname);
1892 break; }
1893 case V_SEQOF:
1894 case V_SETOF: {
1895 if (!is_indexed()) {
1896 size_t nof_vs = u.val_vs->get_nof_vs();
1897 for (size_t i = 0; i < nof_vs; i++) {
1898 string embedded_genname(p_genname);
1899 embedded_genname += '[';
1900 embedded_genname += Int2string(i);
1901 embedded_genname += ']';
1902 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1903 }
1904 } else {
1905 size_t nof_ivs = u.val_vs->get_nof_ivs();
1906 for (size_t i = 0; i < nof_ivs; i++) {
1907 string embedded_genname(p_genname);
1908 embedded_genname += '[';
1909 embedded_genname += Int2string(i);
1910 embedded_genname += ']';
1911 u.val_vs->get_iv_byIndex(i)->get_value()
1912 ->set_genname_recursive(embedded_genname);
1913 }
1914 }
1915 break; }
1916 case V_ARRAY: {
1917 if (!my_governor) return; // error recovery
1918 Type *type = my_governor->get_type_refd_last();
1919 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1920 Int offset = type->get_dimension()->get_offset();
1921 if (!is_indexed()) {
1922 size_t nof_vs = u.val_vs->get_nof_vs();
1923 for (size_t i = 0; i < nof_vs; i++) {
1924 string embedded_genname(p_genname);
1925 embedded_genname += '[';
1926 embedded_genname += Int2string(offset + i);
1927 embedded_genname += ']';
1928 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1929 }
1930 } else {
1931 size_t nof_ivs = u.val_vs->get_nof_ivs();
1932 for (size_t i = 0; i < nof_ivs; i++) {
1933 string embedded_genname(p_genname);
1934 embedded_genname += '[';
1935 embedded_genname += Int2string(offset + i);
1936 embedded_genname += ']';
1937 u.val_vs->get_iv_byIndex(i)->get_value()
1938 ->set_genname_recursive(embedded_genname);
1939 }
1940 }
1941 break; }
1942 case V_SEQ:
1943 case V_SET: {
1944 if (!my_governor) return; // error recovery
1945 Type *t = my_governor->get_type_refd_last();
1946 if (!t->is_secho()) return; // error recovery
1947 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1948 for (size_t i = 0; i < nof_nvs; i++) {
1949 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1950 const Identifier& id = nv->get_name();
1951 if (!t->has_comp_withName(id)) return; // error recovery
1952 string embedded_genname(p_genname);
1953 embedded_genname += '.';
1954 embedded_genname += id.get_name();
1955 embedded_genname += "()";
1956 if (t->get_comp_byName(id)->get_is_optional())
1957 embedded_genname += "()";
1958 nv->get_value()->set_genname_recursive(embedded_genname);
1959 }
1960 break; }
1961 default:
1962 break;
1963 } // switch
1964 }
1965
1966 void Value::set_genname_prefix(const char *p_genname_prefix)
1967 {
1968 GovernedSimple::set_genname_prefix(p_genname_prefix);
1969 switch(valuetype) {
1970 case V_CHOICE:
1971 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1972 break;
1973 case V_SEQOF:
1974 case V_SETOF:
1975 case V_ARRAY:
1976 if (!is_indexed()) {
1977 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1978 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1979 } else {
1980 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1981 u.val_vs->get_iv_byIndex(i)->get_value()
1982 ->set_genname_prefix(p_genname_prefix);
1983 }
1984 break;
1985 case V_SEQ:
1986 case V_SET:
1987 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
1988 u.val_nvs->get_nv_byIndex(i)->get_value()
1989 ->set_genname_prefix(p_genname_prefix);
1990 break;
1991 default:
1992 break;
1993 } // switch
1994 }
1995
1996 void Value::set_code_section(code_section_t p_code_section)
1997 {
1998 GovernedSimple::set_code_section(p_code_section);
1999 switch(valuetype) {
2000 case V_EXPR:
2001 switch (u.expr.v_optype) {
2002 case OPTYPE_RND: // -
2003 case OPTYPE_COMP_NULL:
2004 case OPTYPE_COMP_MTC:
2005 case OPTYPE_COMP_SYSTEM:
2006 case OPTYPE_COMP_SELF:
2007 case OPTYPE_COMP_RUNNING_ANY:
2008 case OPTYPE_COMP_RUNNING_ALL:
2009 case OPTYPE_COMP_ALIVE_ANY:
2010 case OPTYPE_COMP_ALIVE_ALL:
2011 case OPTYPE_TMR_RUNNING_ANY:
2012 case OPTYPE_GETVERDICT:
2013 case OPTYPE_TESTCASENAME:
2014 case OPTYPE_PROF_RUNNING:
2015 break;
2016 case OPTYPE_UNARYPLUS: // v1
2017 case OPTYPE_UNARYMINUS:
2018 case OPTYPE_NOT:
2019 case OPTYPE_NOT4B:
2020 case OPTYPE_BIT2HEX:
2021 case OPTYPE_BIT2INT:
2022 case OPTYPE_BIT2OCT:
2023 case OPTYPE_BIT2STR:
2024 case OPTYPE_CHAR2INT:
2025 case OPTYPE_CHAR2OCT:
2026 case OPTYPE_COMP_RUNNING:
2027 case OPTYPE_COMP_ALIVE:
2028 case OPTYPE_FLOAT2INT:
2029 case OPTYPE_FLOAT2STR:
2030 case OPTYPE_HEX2BIT:
2031 case OPTYPE_HEX2INT:
2032 case OPTYPE_HEX2OCT:
2033 case OPTYPE_HEX2STR:
2034 case OPTYPE_INT2CHAR:
2035 case OPTYPE_INT2FLOAT:
2036 case OPTYPE_INT2STR:
2037 case OPTYPE_INT2UNICHAR:
2038 case OPTYPE_OCT2BIT:
2039 case OPTYPE_OCT2CHAR:
2040 case OPTYPE_OCT2HEX:
2041 case OPTYPE_OCT2INT:
2042 case OPTYPE_OCT2STR:
2043 case OPTYPE_STR2BIT:
2044 case OPTYPE_STR2FLOAT:
2045 case OPTYPE_STR2HEX:
2046 case OPTYPE_STR2INT:
2047 case OPTYPE_STR2OCT:
2048 case OPTYPE_UNICHAR2INT:
2049 case OPTYPE_UNICHAR2CHAR:
2050 case OPTYPE_ENUM2INT:
2051 case OPTYPE_RNDWITHVAL:
2052 case OPTYPE_GET_STRINGENCODING:
2053 case OPTYPE_DECODE_BASE64:
2054 case OPTYPE_REMOVE_BOM:
2055 u.expr.v1->set_code_section(p_code_section);
2056 break;
2057 case OPTYPE_ADD: // v1 v2
2058 case OPTYPE_SUBTRACT:
2059 case OPTYPE_MULTIPLY:
2060 case OPTYPE_DIVIDE:
2061 case OPTYPE_MOD:
2062 case OPTYPE_REM:
2063 case OPTYPE_CONCAT:
2064 case OPTYPE_EQ:
2065 case OPTYPE_LT:
2066 case OPTYPE_GT:
2067 case OPTYPE_NE:
2068 case OPTYPE_GE:
2069 case OPTYPE_LE:
2070 case OPTYPE_AND:
2071 case OPTYPE_OR:
2072 case OPTYPE_XOR:
2073 case OPTYPE_AND4B:
2074 case OPTYPE_OR4B:
2075 case OPTYPE_XOR4B:
2076 case OPTYPE_SHL:
2077 case OPTYPE_SHR:
2078 case OPTYPE_ROTL:
2079 case OPTYPE_ROTR:
2080 case OPTYPE_INT2BIT:
2081 case OPTYPE_INT2HEX:
2082 case OPTYPE_INT2OCT:
2083 u.expr.v1->set_code_section(p_code_section);
2084 u.expr.v2->set_code_section(p_code_section);
2085 break;
2086 case OPTYPE_UNICHAR2OCT:
2087 case OPTYPE_OCT2UNICHAR:
2088 case OPTYPE_ENCODE_BASE64:
2089 u.expr.v1->set_code_section(p_code_section);
2090 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2091 break;
2092 case OPTYPE_DECODE:
2093 u.expr.r1->set_code_section(p_code_section);
2094 u.expr.r2->set_code_section(p_code_section);
2095 break;
2096 case OPTYPE_SUBSTR:
2097 u.expr.ti1->set_code_section(p_code_section);
2098 u.expr.v2->set_code_section(p_code_section);
2099 u.expr.v3->set_code_section(p_code_section);
2100 break;
2101 case OPTYPE_REGEXP:
2102 u.expr.ti1->set_code_section(p_code_section);
2103 u.expr.t2->set_code_section(p_code_section);
2104 u.expr.v3->set_code_section(p_code_section);
2105 break;
2106 case OPTYPE_DECOMP: // v1 v2 v3
2107 u.expr.v1->set_code_section(p_code_section);
2108 u.expr.v2->set_code_section(p_code_section);
2109 u.expr.v3->set_code_section(p_code_section);
2110 break;
2111 case OPTYPE_REPLACE:
2112 u.expr.ti1->set_code_section(p_code_section);
2113 u.expr.v2->set_code_section(p_code_section);
2114 u.expr.v3->set_code_section(p_code_section);
2115 u.expr.ti4->set_code_section(p_code_section);
2116 break;
2117 case OPTYPE_LENGTHOF: // ti1
2118 case OPTYPE_SIZEOF: // ti1
2119 case OPTYPE_VALUEOF: // ti1
2120 case OPTYPE_ISVALUE:
2121 case OPTYPE_ISBOUND:
2122 case OPTYPE_ENCODE:
2123 case OPTYPE_ISPRESENT:
2124 case OPTYPE_TTCN2STRING:
2125 u.expr.ti1->set_code_section(p_code_section);
2126 break;
2127 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
2128 u.expr.ti1->set_code_section(p_code_section);
2129 if (u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2130 break;
2131 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
2132 u.expr.r1->set_code_section(p_code_section);
2133 u.expr.r2->set_code_section(p_code_section);
2134 if (u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2135 break;
2136 case OPTYPE_UNDEF_RUNNING: // r1
2137 case OPTYPE_TMR_READ:
2138 case OPTYPE_TMR_RUNNING:
2139 case OPTYPE_ACTIVATE:
2140 u.expr.r1->set_code_section(p_code_section);
2141 break;
2142 case OPTYPE_EXECUTE: // r1 [v2]
2143 u.expr.r1->set_code_section(p_code_section);
2144 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2145 break;
2146 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
2147 case OPTYPE_CHECKSTATE_ALL:
2148 if(u.expr.r1) u.expr.r1->set_code_section(p_code_section);
2149 u.expr.v2->set_code_section(p_code_section);
2150 break;
2151 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2152 u.expr.r1->set_code_section(p_code_section);
2153 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2154 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2155 break;
2156 case OPTYPE_MATCH: // v1 t2
2157 u.expr.v1->set_code_section(p_code_section);
2158 u.expr.t2->set_code_section(p_code_section);
2159 break;
2160 case OPTYPE_ISCHOSEN: // r1 i2
2161 u.expr.r1->set_code_section(p_code_section);
2162 break;
2163 case OPTYPE_ISCHOSEN_V: // v1 i2
2164 u.expr.v1->set_code_section(p_code_section);
2165 break;
2166 case OPTYPE_ISCHOSEN_T: // t1 i2
2167 u.expr.t1->set_code_section(p_code_section);
2168 break;
2169 case OPTYPE_ACTIVATE_REFD:
2170 u.expr.v1->set_code_section(p_code_section);
2171 if(u.expr.state!=EXPR_CHECKED)
2172 u.expr.t_list2->set_code_section(p_code_section);
2173 else {
2174 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2175 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2176 u.expr.state = EXPR_CHECKED;
2177 }
2178 break;
2179 case OPTYPE_EXECUTE_REFD:
2180 u.expr.v1->set_code_section(p_code_section);
2181 if(u.expr.state!=EXPR_CHECKED)
2182 u.expr.t_list2->set_code_section(p_code_section);
2183 else {
2184 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2185 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2186 u.expr.state = EXPR_CHECKED;
2187 }
2188 if(u.expr.v3)
2189 u.expr.v3->set_code_section(p_code_section);
2190 break;
2191 case OPTYPE_LOG2STR:
2192 case OPTYPE_ANY2UNISTR:
2193 u.expr.logargs->set_code_section(p_code_section);
2194 break;
2195 default:
2196 FATAL_ERROR("Value::set_code_section()");
2197 } // switch
2198 break;
2199 case V_CHOICE:
2200 u.choice.alt_value->set_code_section(p_code_section);
2201 break;
2202 case V_SEQOF:
2203 case V_SETOF:
2204 case V_ARRAY:
2205 if (!is_indexed()) {
2206 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2207 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2208 } else {
2209 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2210 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2211 }
2212 break;
2213 case V_SEQ:
2214 case V_SET:
2215 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2216 u.val_nvs->get_nv_byIndex(i)->get_value()
2217 ->set_code_section(p_code_section);
2218 break;
2219 case V_REFD:
2220 u.ref.ref->set_code_section(p_code_section);
2221 break;
2222 case V_REFER:
2223 u.refered->set_code_section(p_code_section);
2224 break;
2225 case V_INVOKE:
2226 u.invoke.v->set_code_section(p_code_section);
2227 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2228 if(u.invoke.ap_list)
2229 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2230 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2231 break;
2232 default:
2233 break;
2234 } // switch
2235 }
2236
2237 void Value::change_sign()
2238 {
2239 switch(valuetype) {
2240 case V_INT:
2241 *u.val_Int=-*u.val_Int;
2242 break;
2243 case V_REAL:
2244 u.val_Real*=-1.0;
2245 break;
2246 case V_ERROR:
2247 break;
2248 default:
2249 FATAL_ERROR("Value::change_sign()");
2250 } // switch
2251 }
2252
2253 void Value::add_oid_comp(OID_comp* p_comp)
2254 {
2255 if(!p_comp)
2256 FATAL_ERROR("NULL parameter");
2257 u.oid_comps->add(p_comp);
2258 p_comp->set_fullname(get_fullname()+"."
2259 +Int2string(u.oid_comps->size()));
2260 p_comp->set_my_scope(my_scope);
2261 }
2262
2263 void Value::set_valuetype(valuetype_t p_valuetype)
2264 {
2265 if (valuetype == V_ERROR) return;
2266 else if (p_valuetype == V_ERROR) {
2267 if(valuetype==V_EXPR) {
2268 switch(u.expr.state) {
2269 case EXPR_CHECKING:
2270 u.expr.state=EXPR_CHECKING_ERR;
2271 // no break
2272 case EXPR_CHECKING_ERR:
2273 return;
2274 default:
2275 break;
2276 }
2277 }
2278 clean_up();
2279 valuetype = V_ERROR;
2280 return;
2281 }
2282 switch(valuetype) {
2283 case V_UNDEF_LOWERID:
2284 switch(p_valuetype) {
2285 case V_ENUM:
2286 case V_NAMEDINT:
2287 break;
2288 case V_REFD:
2289 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2290 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2291 u.ref.ref->set_my_scope(get_my_scope());
2292 u.ref.ref->set_fullname(get_fullname());
2293 u.ref.ref->set_location(*this);
2294 u.ref.refd_last = 0;
2295 break;
2296 default:
2297 FATAL_ERROR("Value::set_valuetype()");
2298 } // switch
2299 break;
2300 case V_UNDEF_BLOCK: {
2301 Block *t_block=u.block;
2302 Value *v=0;
2303 switch(p_valuetype) {
2304 case V_NAMEDBITS: {
2305 Node *node=t_block->parse(KW_Block_IdentifierList);
2306 v=dynamic_cast<Value*>(node);
2307 if(!v) {
2308 /* syntax error */
2309 u.ids=new map<string, Identifier>();
2310 }
2311 else {
2312 u.ids=v->u.ids; v->u.ids=0;
2313 }
2314 break;}
2315 case V_SEQOF: {
2316 Node *node=t_block->parse(KW_Block_SeqOfValue);
2317 v=dynamic_cast<Value*>(node);
2318 if(!v) {
2319 /* syntax error */
2320 u.val_vs=new Values();
2321 }
2322 else {
2323 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2324 }
2325 u.val_vs->set_my_scope(get_my_scope());
2326 u.val_vs->set_fullname(get_fullname());
2327 break;}
2328 case V_SETOF: {
2329 Node *node=t_block->parse(KW_Block_SetOfValue);
2330 v=dynamic_cast<Value*>(node);
2331 if(!v) {
2332 /* syntax error */
2333 u.val_vs=new Values();
2334 }
2335 else {
2336 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2337 }
2338 u.val_vs->set_my_scope(get_my_scope());
2339 u.val_vs->set_fullname(get_fullname());
2340 break;}
2341 case V_SEQ: {
2342 Node *node=t_block->parse(KW_Block_SequenceValue);
2343 v=dynamic_cast<Value*>(node);
2344 if(!v) {
2345 /* syntax error */
2346 u.val_nvs=new NamedValues();
2347 }
2348 else {
2349 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2350 }
2351 u.val_nvs->set_my_scope(get_my_scope());
2352 u.val_nvs->set_fullname(get_fullname());
2353 break;}
2354 case V_SET: {
2355 Node *node=t_block->parse(KW_Block_SetValue);
2356 v=dynamic_cast<Value*>(node);
2357 if(!v) {
2358 /* syntax error */
2359 u.val_nvs=new NamedValues();
2360 }
2361 else {
2362 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2363 }
2364 u.val_nvs->set_my_scope(get_my_scope());
2365 u.val_nvs->set_fullname(get_fullname());
2366 break;}
2367 case V_OID: {
2368 Node *node=t_block->parse(KW_Block_OIDValue);
2369 v=dynamic_cast<Value*>(node);
2370 if(!v) {
2371 /* syntax error */
2372 u.oid_comps=new vector<OID_comp>();
2373 }
2374 else {
2375 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2376 }
2377 for (size_t i = 0; i < u.oid_comps->size(); i++)
2378 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2379 break;}
2380 case V_ROID: {
2381 Node *node=t_block->parse(KW_Block_ROIDValue);
2382 v=dynamic_cast<Value*>(node);
2383 if(!v) {
2384 /* syntax error */
2385 u.oid_comps=new vector<OID_comp>();
2386 }
2387 else {
2388 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2389 }
2390 for (size_t i = 0; i < u.oid_comps->size(); i++)
2391 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2392 break;}
2393 case V_CHARSYMS: {
2394 Node *node=t_block->parse(KW_Block_CharStringValue);
2395 u.char_syms=dynamic_cast<CharSyms*>(node);
2396 if(!u.char_syms) {
2397 /* syntax error */
2398 u.char_syms=new CharSyms();
2399 }
2400 u.char_syms->set_my_scope(get_my_scope());
2401 u.char_syms->set_fullname(get_fullname());
2402 break;}
2403 default:
2404 FATAL_ERROR("Value::set_valuetype()");
2405 } // switch
2406 delete v;
2407 delete t_block;
2408 break;}
2409 case V_REFD:
2410 if (p_valuetype == V_USTR) {
2411 Value *v_last = get_value_refd_last();
2412 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2413 ustring *ustr = new ustring(*v_last->u.str.val_str);
2414 delete u.ref.ref;
2415 set_val_ustr(ustr);
2416 u.ustr.convert_str = true; // will be converted back to string
2417 } else FATAL_ERROR("Value::set_valuetype()");
2418 break;
2419 case V_CHARSYMS:
2420 switch(p_valuetype) {
2421 case V_CSTR: {
2422 const string& str = u.char_syms->get_string();
2423 delete u.char_syms;
2424 set_val_str(new string(str));
2425 break;}
2426 case V_USTR: {
2427 const ustring& ustr = u.char_syms->get_ustring();
2428 delete u.char_syms;
2429 set_val_ustr(new ustring(ustr));
2430 u.ustr.convert_str = false;
2431 break;}
2432 case V_ISO2022STR: {
2433 const string& str = u.char_syms->get_iso2022string();
2434 delete u.char_syms;
2435 set_val_str(new string(str));
2436 break;}
2437 default:
2438 FATAL_ERROR("Value::set_valuetype()");
2439 } // switch
2440 break;
2441 case V_INT: {
2442 Real val_Real;
2443 if (p_valuetype == V_REAL)
2444 val_Real = u.val_Int->to_real();
2445 else FATAL_ERROR("Value::set_valuetype()");
2446 clean_up();
2447 u.val_Real = val_Real;
2448 break; }
2449 case V_HSTR: {
2450 clean_up_string_elements(u.str.str_elements);
2451 string *old_str = u.str.val_str;
2452 switch(p_valuetype) {
2453 case V_BSTR:
2454 set_val_str(hex2bit(*old_str));
2455 break;
2456 case V_OSTR:
2457 set_val_str(asn_hex2oct(*old_str));
2458 break;
2459 default:
2460 FATAL_ERROR("Value::set_valuetype()");
2461 } // switch
2462 delete old_str;
2463 break;}
2464 case V_BSTR:
2465 clean_up_string_elements(u.str.str_elements);
2466 if (p_valuetype == V_OSTR) {
2467 string *old_str = u.str.val_str;
2468 set_val_str(asn_bit2oct(*old_str));
2469 delete old_str;
2470 } else FATAL_ERROR("Value::set_valuetype()");
2471 break;
2472 case V_CSTR:
2473 clean_up_string_elements(u.str.str_elements);
2474 switch(p_valuetype) {
2475 case V_USTR: {
2476 string *old_str = u.str.val_str;
2477 set_val_ustr(new ustring(*old_str));
2478 u.ustr.convert_str = true; // will be converted back to string
2479 delete old_str;
2480 break;}
2481 case V_ISO2022STR:
2482 // do nothing
2483 break;
2484 default:
2485 FATAL_ERROR("Value::set_valuetype()");
2486 } // switch p_valuetype
2487 break;
2488 case V_USTR:
2489 clean_up_string_elements(u.ustr.ustr_elements);
2490 switch(p_valuetype) {
2491 case V_CSTR: {
2492 ustring *old_str = u.ustr.val_ustr;
2493 size_t nof_chars = old_str->size();
2494 bool warning_flag = false;
2495 for (size_t i = 0; i < nof_chars; i++) {
2496 const ustring::universal_char& uchar = (*old_str)[i];
2497 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2498 error("This string value cannot contain multiple-byte characters, "
2499 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2500 uchar.group, uchar.plane, uchar.row, uchar.cell,
2501 (unsigned long) i);
2502 p_valuetype = V_ERROR;
2503 break;
2504 } else if (uchar.cell > 127 && !warning_flag) {
2505 warning("This string value may not contain characters with code "
2506 "higher than 127, but it has character with code %u (0x%02X) "
2507 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2508 warning_flag = true;
2509 }
2510 }
2511 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2512 delete old_str;
2513 break; }
2514 case V_ISO2022STR:
2515 error("ISO-10646 string value cannot be converted to "
2516 "ISO-2022 string");
2517 delete u.ustr.val_ustr;
2518 p_valuetype = V_ERROR;
2519 break;
2520 default:
2521 FATAL_ERROR("Value::set_valuetype()");
2522 } // switch p_valuetype
2523 break;
2524 case V_SEQ:
2525 switch (p_valuetype) {
2526 case V_CHOICE: {
2527 NamedValues *nvs = u.val_nvs;
2528 if (nvs->get_nof_nvs() < 1) {
2529 error("Union value must have one active field");
2530 delete nvs;
2531 valuetype = V_ERROR;
2532 return;
2533 } else if (nvs->get_nof_nvs() > 1) {
2534 error("Only one field was expected in union value instead of %lu",
2535 (unsigned long) nvs->get_nof_nvs());
2536 }
2537 NamedValue *nv = nvs->get_nv_byIndex(0);
2538 u.choice.alt_name = nv->get_name().clone();
2539 u.choice.alt_value = nv->steal_value();
2540 delete nvs;
2541 break;}
2542 case V_SET:
2543 // do nothing
2544 break;
2545 case V_REAL: {
2546 NamedValues *nvs = u.val_nvs;
2547 bool err = false;
2548 /* mantissa */
2549 Int i_mant = 0;
2550 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2551 if (nvs->has_nv_withName(id_mant)) {
2552 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2553 ->get_value_refd_last();
2554 if (v_tmp->get_valuetype() == V_INT) {
2555 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2556 if (*i_mant_int > INT_MAX) {
2557 error("Mantissa `%s' should be less than `%d'",
2558 (i_mant_int->t_str()).c_str(), INT_MAX);
2559 err = true;
2560 } else {
2561 i_mant = i_mant_int->get_val();
2562 }
2563 }
2564 else err = true;
2565 }
2566 else err = true;
2567 /* base */
2568 Int i_base = 0;
2569 Identifier id_base(Identifier::ID_ASN, string("base"));
2570 if (!err && nvs->has_nv_withName(id_base)) {
2571 Value *v = nvs->get_nv_byName(id_base)->get_value();
2572 Value *v_tmp = v->get_value_refd_last();
2573 if (v_tmp->get_valuetype() == V_INT) {
2574 const int_val_t *i_base_int = v_tmp->get_val_Int();
2575 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2576 v->error("Base of the REAL must be 2 or 10");
2577 err = true;
2578 } else {
2579 i_base = i_base_int->get_val();
2580 }
2581 }
2582 else err = true;
2583 }
2584 else err = true;
2585 /* exponent */
2586 Int i_exp = 0;
2587 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2588 if (!err && nvs->has_nv_withName(id_exp)) {
2589 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2590 ->get_value_refd_last();
2591 if (v_tmp->get_valuetype() == V_INT) {
2592 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2593 if (*i_exp_int > INT_MAX) {
2594 error("Exponent `%s' should be less than `%d'",
2595 (i_exp_int->t_str()).c_str(), INT_MAX);
2596 err = true;
2597 } else {
2598 i_exp = i_exp_int->get_val();
2599 }
2600 }
2601 else err = true;
2602 }
2603 else err = true;
2604 /* clean up */
2605 delete nvs;
2606 if (err) {
2607 valuetype = V_ERROR;
2608 return;
2609 }
2610 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2611 static_cast<double>(i_exp));
2612 break; }
2613 case V_NOTUSED:
2614 clean_up();
2615 break;
2616 default:
2617 FATAL_ERROR("Value::set_valuetype()");
2618 } // switch
2619 break;
2620 case V_SEQOF:
2621 switch (p_valuetype) {
2622 case V_SEQ: {
2623 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2624 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2625 Type *t = my_governor->get_type_refd_last();
2626 switch (t->get_typetype()) {
2627 case Type::T_SEQ_T:
2628 case Type::T_SEQ_A:
2629 break;
2630 default:
2631 FATAL_ERROR("Value::set_valuetype()");
2632 }
2633 Values *vals = u.val_vs;
2634 size_t nof_vals = vals->get_nof_vs();
2635 size_t nof_comps = t->get_nof_comps();
2636 if (nof_vals > nof_comps) {
2637 error("Too many elements in value list notation for type `%s': "
2638 "%lu was expected instead of %lu",
2639 t->get_typename().c_str(),
2640 (unsigned long)nof_comps, (unsigned long)nof_vals);
2641 }
2642 size_t upper_limit;
2643 bool allnotused;
2644 if (nof_vals <= nof_comps) {
2645 upper_limit = nof_vals;
2646 allnotused = true;
2647 } else {
2648 upper_limit = nof_comps;
2649 allnotused = false;
2650 }
2651 u.val_nvs = new NamedValues;
2652 for (size_t i = 0; i < upper_limit; i++) {
2653 Value *v = vals->steal_v_byIndex(i);
2654 if (v->valuetype != V_NOTUSED) {
2655 allnotused = false;
2656 }
2657 NamedValue *nv =
2658 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2659 nv->set_location(*v);
2660 u.val_nvs->add_nv(nv);
2661 }
2662 u.val_nvs->set_my_scope(get_my_scope());
2663 u.val_nvs->set_fullname(get_fullname());
2664 delete vals;
2665 if (allnotused && nof_vals > 0)
2666 warning("All elements of value list notation for type `%s' are not "
2667 "used symbols (`-')", t->get_typename().c_str());
2668 break; }
2669 case V_SET:
2670 // { } -> empty set value
2671 if (u.val_vs->get_nof_vs() != 0)
2672 FATAL_ERROR("Value::set_valuetype()");
2673 delete u.val_vs;
2674 u.val_nvs = new NamedValues;
2675 break;
2676 case V_SETOF:
2677 case V_ARRAY:
2678 // SEQOF -> SETOF or ARRAY: trivial
2679 break;
2680 default:
2681 FATAL_ERROR("Value::set_valuetype()");
2682 }
2683 break;
2684 case V_SET:
2685 case V_CHOICE:
2686 if (p_valuetype == V_NOTUSED) {
2687 clean_up();
2688 }
2689 else {
2690 FATAL_ERROR("Value::set_valuetype()");
2691 }
2692 break;
2693 case V_TTCN3_NULL:
2694 switch (p_valuetype) {
2695 case V_DEFAULT_NULL:
2696 break;
2697 case V_FAT_NULL:
2698 break;
2699 default:
2700 FATAL_ERROR("Value::set_valuetype()");
2701 }
2702 break;
2703 case V_NOTUSED:
2704 if (V_OMIT != p_valuetype) { // in case of implicit omit
2705 FATAL_ERROR("Value::set_valuetype()");
2706 }
2707 break;
2708 default:
2709 FATAL_ERROR("Value::set_valuetype()");
2710 } // switch
2711 valuetype=p_valuetype;
2712 }
2713
2714 void Value::set_valuetype_COMP_NULL()
2715 {
2716 if(valuetype == V_ERROR) return;
2717 if(valuetype==V_TTCN3_NULL) {
2718 valuetype=V_EXPR;
2719 u.expr.v_optype=OPTYPE_COMP_NULL;
2720 // Nothing to check.
2721 u.expr.state=EXPR_CHECKED;
2722 }
2723 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2724 }
2725
2726 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2727 {
2728 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2729 delete u.val_id;
2730 u.val_Int = new int_val_t(p_val_int);
2731 valuetype = V_INT;
2732 } else FATAL_ERROR("Value::set_valuetype()");
2733 }
2734
2735 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2736 {
2737 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2738 clean_up();
2739 valuetype = V_BSTR;
2740 set_val_str(p_str);
2741 } else FATAL_ERROR("Value::set_valuetype()");
2742 }
2743
2744 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2745 {
2746 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2747 delete u.val_id;
2748 u.val_id = p_id;
2749 valuetype = V_ENUM;
2750 } else FATAL_ERROR("Value::set_valuetype()");
2751 }
2752
2753 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2754 {
2755 switch (p_valuetype) {
2756 case V_FUNCTION:
2757 case V_ALTSTEP:
2758 case V_TESTCASE:
2759 if (valuetype == V_REFER && p_ass) break;
2760 // no break
2761 default:
2762 FATAL_ERROR("Value::set_valuetype()");
2763 }
2764 delete u.refered;
2765 u.refd_fat = p_ass;
2766 valuetype = p_valuetype;
2767 }
2768
2769 bool Value::is_undef_lowerid()
2770 {
2771 switch (valuetype) {
2772 case V_UNDEF_LOWERID:
2773 return true;
2774 case V_EXPR:
2775 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2776 !u.expr.ti1->get_DerivedRef()) {
2777 return u.expr.ti1->get_Template()->is_undef_lowerid();
2778 }
2779 // no break
2780 default:
2781 return false;
2782 }
2783 }
2784
2785 const Identifier& Value::get_undef_lowerid()
2786 {
2787 switch (valuetype) {
2788 case V_UNDEF_LOWERID:
2789 return *u.val_id;
2790 case V_EXPR:
2791 if (u.expr.v_optype != OPTYPE_VALUEOF)
2792 FATAL_ERROR("Value::get_undef_lowerid()");
2793 return u.expr.ti1->get_Template()->get_specific_value()
2794 ->get_undef_lowerid();
2795 default:
2796 FATAL_ERROR("Value::get_undef_lowerid()");
2797 }
2798 const Identifier *dummy = 0;
2799 return *dummy;
2800 }
2801
2802 void Value::set_lowerid_to_ref()
2803 {
2804 switch (valuetype) {
2805 case V_UNDEF_LOWERID:
2806 set_valuetype(V_REFD);
2807 break;
2808 case V_EXPR:
2809 // if the governor of the expression is not known (in log(), etc...)
2810 // then the governor is taken from the reference (using
2811 // v1/ti1->get_expr_governor()), but that runs before the
2812 // params were checked, this smells like a workaround :)
2813 switch (u.expr.v_optype) {
2814 case OPTYPE_ROTL:
2815 case OPTYPE_ROTR:
2816 u.expr.v1->set_lowerid_to_ref();
2817 break;
2818 case OPTYPE_CONCAT:
2819 u.expr.v1->set_lowerid_to_ref();
2820 u.expr.v2->set_lowerid_to_ref();
2821 break;
2822 case OPTYPE_VALUEOF:
2823 case OPTYPE_ISVALUE:
2824 case OPTYPE_ISBOUND:
2825 case OPTYPE_ISPRESENT:
2826 case OPTYPE_SUBSTR:
2827 case OPTYPE_REGEXP:
2828 case OPTYPE_REPLACE:
2829 case OPTYPE_TTCN2STRING:
2830 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2831 Error_Context cntxt(u.expr.ti1->get_Template(),
2832 "In the operand of operation `%s'",
2833 get_opname());
2834 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2835 }
2836 if (u.expr.v_optype==OPTYPE_REGEXP) {
2837 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2838 Error_Context cntxt(u.expr.t2->get_Template(),
2839 "In the operand of operation `%s'",
2840 get_opname());
2841 u.expr.t2->get_Template()->set_lowerid_to_ref();
2842 }
2843 }
2844 if (u.expr.v_optype==OPTYPE_REPLACE) {
2845 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2846 Error_Context cntxt(u.expr.ti4->get_Template(),
2847 "In the operand of operation `%s'",
2848 get_opname());
2849 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2850 }
2851 }
2852 break;
2853 default:
2854 break;
2855 }
2856 break;
2857 default:
2858 break;
2859 }
2860 }
2861
2862 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2863 {
2864 switch (valuetype) {
2865 case V_CHARSYMS:
2866 case V_CHOICE:
2867 case V_SEQOF:
2868 case V_SETOF:
2869 case V_ARRAY:
2870 case V_SEQ:
2871 case V_SET:
2872 case V_UNDEF_LOWERID:
2873 case V_UNDEF_BLOCK:
2874 case V_OMIT:
2875 case V_TTCN3_NULL:
2876 case V_NOTUSED:
2877 case V_REFER:
2878 case V_FAT_NULL:
2879 return Type::T_UNDEF;
2880 case V_NAMEDINT:
2881 case V_NAMEDBITS:
2882 case V_OPENTYPE:
2883 FATAL_ERROR("Value::get_expr_returntype()");
2884 case V_ERROR:
2885 return Type::T_ERROR;
2886 case V_REFD:
2887 case V_INVOKE: {
2888 Type *t = get_expr_governor(exp_val);
2889 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2890 else return Type::T_ERROR; }
2891 case V_FUNCTION:
2892 return Type::T_FUNCTION;
2893 case V_ALTSTEP:
2894 return Type::T_ALTSTEP;
2895 case V_TESTCASE:
2896 return Type::T_TESTCASE;
2897 case V_EXPR:
2898 switch(u.expr.v_optype) {
2899 case OPTYPE_COMP_NULL:
2900 case OPTYPE_COMP_MTC:
2901 case OPTYPE_COMP_SYSTEM:
2902 case OPTYPE_COMP_SELF:
2903 case OPTYPE_COMP_CREATE:
2904 return Type::T_COMPONENT;
2905 case OPTYPE_UNDEF_RUNNING:
2906 case OPTYPE_COMP_RUNNING:
2907 case OPTYPE_COMP_RUNNING_ANY:
2908 case OPTYPE_COMP_RUNNING_ALL:
2909 case OPTYPE_COMP_ALIVE:
2910 case OPTYPE_COMP_ALIVE_ANY:
2911 case OPTYPE_COMP_ALIVE_ALL:
2912 case OPTYPE_TMR_RUNNING:
2913 case OPTYPE_TMR_RUNNING_ANY:
2914 case OPTYPE_MATCH:
2915 case OPTYPE_EQ:
2916 case OPTYPE_LT:
2917 case OPTYPE_GT:
2918 case OPTYPE_NE:
2919 case OPTYPE_GE:
2920 case OPTYPE_LE:
2921 case OPTYPE_NOT:
2922 case OPTYPE_AND:
2923 case OPTYPE_OR:
2924 case OPTYPE_XOR:
2925 case OPTYPE_ISPRESENT:
2926 case OPTYPE_ISCHOSEN:
2927 case OPTYPE_ISCHOSEN_V:
2928 case OPTYPE_ISCHOSEN_T:
2929 case OPTYPE_ISVALUE:
2930 case OPTYPE_ISBOUND:
2931 case OPTYPE_PROF_RUNNING:
2932 case OPTYPE_CHECKSTATE_ANY:
2933 case OPTYPE_CHECKSTATE_ALL:
2934 return Type::T_BOOL;
2935 case OPTYPE_GETVERDICT:
2936 return Type::T_VERDICT;
2937 case OPTYPE_VALUEOF: {
2938 Error_Context cntxt(this, "In the operand of operation `%s'",
2939 get_opname());
2940 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2941 case OPTYPE_TMR_READ:
2942 case OPTYPE_INT2FLOAT:
2943 case OPTYPE_STR2FLOAT:
2944 case OPTYPE_RND:
2945 case OPTYPE_RNDWITHVAL:
2946 return Type::T_REAL;
2947 case OPTYPE_ACTIVATE:
2948 return Type::T_DEFAULT;
2949 case OPTYPE_ACTIVATE_REFD:
2950 return Type::T_DEFAULT;
2951 case OPTYPE_EXECUTE:
2952 case OPTYPE_EXECUTE_REFD:
2953 return Type::T_VERDICT;
2954 case OPTYPE_UNARYPLUS: // v1
2955 case OPTYPE_UNARYMINUS: {
2956 Type::typetype_t tmp_tt;
2957 {
2958 Error_Context cntxt(this, "In the operand of operation `%s'",
2959 get_opname());
2960 u.expr.v1->set_lowerid_to_ref();
2961 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2962 }
2963 switch(tmp_tt) {
2964 case Type::T_INT:
2965 case Type::T_REAL:
2966 return tmp_tt;
2967 default:
2968 get_value_refd_last(); // to report the error
2969 return Type::T_ERROR;
2970 } // switch tmp_tt
2971 }
2972 case OPTYPE_ADD: // v1 v2
2973 case OPTYPE_SUBTRACT:
2974 case OPTYPE_MULTIPLY:
2975 case OPTYPE_DIVIDE: {
2976 Type::typetype_t tmp_tt;
2977 {
2978 Error_Context cntxt(this, "In the left operand of operation `%s'",
2979 get_opname());
2980 u.expr.v1->set_lowerid_to_ref();
2981 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2982 }
2983 switch(tmp_tt) {
2984 case Type::T_INT:
2985 case Type::T_REAL:
2986 return tmp_tt;
2987 default:
2988 if(u.expr.v_optype==OPTYPE_ADD) {
2989 Type::typetype_t tmp_tt2;
2990 {
2991 Error_Context cntxt(this, "In the right operand of operation `%s'",
2992 get_opname());
2993 u.expr.v2->set_lowerid_to_ref();
2994 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
2995 }
2996 Type::typetype_t ret_val=Type::T_ERROR;
2997 bool maybeconcat=false;
2998 switch(tmp_tt) {
2999 case Type::T_BSTR:
3000 case Type::T_HSTR:
3001 case Type::T_OSTR:
3002 if(tmp_tt2==tmp_tt) {
3003 maybeconcat=true;
3004 ret_val=tmp_tt;
3005 }
3006 break;
3007 case Type::T_CSTR:
3008 case Type::T_USTR:
3009 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
3010 maybeconcat=true;
3011 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
3012 ret_val=Type::T_USTR;
3013 else ret_val=Type::T_CSTR;
3014 }
3015 break;
3016 default:
3017 break;
3018 }
3019 if(maybeconcat) {
3020 error("Did you mean the concat operation (`&') instead of"
3021 " addition operator (`+')?");
3022 u.expr.v_optype=OPTYPE_CONCAT;
3023 return ret_val;
3024 }
3025 }
3026 get_value_refd_last(); // to report the error
3027 return Type::T_ERROR;
3028 } // switch tmp_tt
3029 }
3030 case OPTYPE_NOT4B: // v1
3031 case OPTYPE_AND4B: // v1 v2
3032 case OPTYPE_OR4B:
3033 case OPTYPE_XOR4B:
3034 case OPTYPE_SHL:
3035 case OPTYPE_SHR: {
3036 Type::typetype_t tmp_tt;
3037 {
3038 Error_Context cntxt(this, "In the %soperand of operation `%s'",
3039 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
3040 get_opname());
3041 u.expr.v1->set_lowerid_to_ref();
3042 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3043 }
3044 switch(tmp_tt) {
3045 case Type::T_BSTR:
3046 case Type::T_HSTR:
3047 case Type::T_OSTR:
3048 return tmp_tt;
3049 default:
3050 get_value_refd_last(); // to report the error
3051 return Type::T_ERROR;
3052 } // switch tmp_tt
3053 }
3054 case OPTYPE_ROTL: // v1 v2
3055 case OPTYPE_ROTR: {
3056 Type::typetype_t tmp_tt;
3057 {
3058 Error_Context cntxt(this, "In the %s operand of operation `%s'",
3059 u.expr.v_optype==OPTYPE_ROTL
3060 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
3061 get_opname());
3062 u.expr.v1->set_lowerid_to_ref();
3063 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3064 }
3065 switch(tmp_tt) {
3066 case Type::T_BSTR:
3067 case Type::T_HSTR:
3068 case Type::T_OSTR:
3069 case Type::T_CSTR:
3070 case Type::T_USTR:
3071 case Type::T_SETOF:
3072 case Type::T_SEQOF:
3073 case Type::T_ARRAY:
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_SUBSTR:
3081 case OPTYPE_REPLACE: {
3082 Type::typetype_t tmp_tt;
3083 {
3084 Error_Context cntxt(this, "In the operand of operation `%s'",
3085 get_opname());
3086 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3087 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3088 }
3089 switch (tmp_tt) {
3090 case Type::T_BSTR:
3091 case Type::T_HSTR:
3092 case Type::T_OSTR:
3093 case Type::T_CSTR:
3094 case Type::T_USTR:
3095 case Type::T_SETOF:
3096 case Type::T_SEQOF:
3097 return tmp_tt;
3098 default:
3099 get_value_refd_last(); // to report the error
3100 return Type::T_ERROR;
3101 }
3102 }
3103 case OPTYPE_REGEXP: {
3104 Type::typetype_t tmp_tt;
3105 {
3106 Error_Context cntxt(this, "In the first operand of operation `%s'",
3107 get_opname());
3108 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3109 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3110 }
3111 switch(tmp_tt) {
3112 case Type::T_CSTR:
3113 case Type::T_USTR:
3114 return tmp_tt;
3115 default:
3116 get_value_refd_last(); // to report the error
3117 return Type::T_ERROR;
3118 } // switch tmp_tt
3119 }
3120 case OPTYPE_CONCAT: { // v1 v2
3121 Type::typetype_t tmp_tt;
3122 {
3123 Error_Context cntxt(this, "In the first operand of operation `%s'",
3124 get_opname());
3125 u.expr.v1->set_lowerid_to_ref();
3126 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3127 }
3128 switch(tmp_tt) {
3129 case Type::T_CSTR:
3130 case Type::T_USTR:
3131 case Type::T_BSTR:
3132 case Type::T_HSTR:
3133 case Type::T_OSTR:
3134 case Type::T_SETOF:
3135 case Type::T_SEQOF:
3136 return tmp_tt;
3137 default:
3138 get_value_refd_last(); // to report the error
3139 return Type::T_ERROR;
3140 } // switch tmp_tt
3141 }
3142 case OPTYPE_MOD:
3143 case OPTYPE_REM:
3144 case OPTYPE_CHAR2INT:
3145 case OPTYPE_UNICHAR2INT:
3146 case OPTYPE_BIT2INT:
3147 case OPTYPE_HEX2INT:
3148 case OPTYPE_OCT2INT:
3149 case OPTYPE_STR2INT:
3150 case OPTYPE_FLOAT2INT:
3151 case OPTYPE_LENGTHOF:
3152 case OPTYPE_SIZEOF:
3153 case OPTYPE_DECODE:
3154 case OPTYPE_ENUM2INT:
3155 case OPTYPE_DECVALUE_UNICHAR:
3156 return Type::T_INT;
3157 case OPTYPE_BIT2STR:
3158 case OPTYPE_FLOAT2STR:
3159 case OPTYPE_HEX2STR:
3160 case OPTYPE_INT2CHAR:
3161 case OPTYPE_INT2STR:
3162 case OPTYPE_OCT2CHAR:
3163 case OPTYPE_OCT2STR:
3164 case OPTYPE_UNICHAR2CHAR:
3165 case OPTYPE_LOG2STR:
3166 case OPTYPE_TESTCASENAME:
3167 case OPTYPE_TTCN2STRING:
3168 case OPTYPE_GET_STRINGENCODING:
3169 case OPTYPE_ENCODE_BASE64:
3170 return Type::T_CSTR;
3171 case OPTYPE_INT2UNICHAR:
3172 case OPTYPE_OCT2UNICHAR:
3173 case OPTYPE_ENCVALUE_UNICHAR:
3174 case OPTYPE_ANY2UNISTR:
3175 return Type::T_USTR;
3176 case OPTYPE_INT2BIT:
3177 case OPTYPE_HEX2BIT:
3178 case OPTYPE_OCT2BIT:
3179 case OPTYPE_STR2BIT:
3180 case OPTYPE_ENCODE:
3181 return Type::T_BSTR;
3182 case OPTYPE_INT2HEX:
3183 case OPTYPE_BIT2HEX:
3184 case OPTYPE_OCT2HEX:
3185 case OPTYPE_STR2HEX:
3186 return Type::T_HSTR;
3187 case OPTYPE_INT2OCT:
3188 case OPTYPE_CHAR2OCT:
3189 case OPTYPE_HEX2OCT:
3190 case OPTYPE_BIT2OCT:
3191 case OPTYPE_STR2OCT:
3192 case OPTYPE_UNICHAR2OCT:
3193 case OPTYPE_REMOVE_BOM:
3194 case OPTYPE_DECODE_BASE64:
3195 return Type::T_OSTR;
3196 case OPTYPE_DECOMP:
3197 return Type::T_OID;
3198 default:
3199 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3200 // to avoid warning
3201 return Type::T_ERROR;
3202 } // switch optype
3203 case V_MACRO:
3204 switch (u.macro) {
3205 case MACRO_MODULEID:
3206 case MACRO_FILENAME:
3207 case MACRO_BFILENAME:
3208 case MACRO_FILEPATH:
3209 case MACRO_LINENUMBER:
3210 case MACRO_DEFINITIONID:
3211 case MACRO_SCOPE:
3212 case MACRO_TESTCASEID:
3213 return Type::T_CSTR;
3214 case MACRO_LINENUMBER_C:
3215 return Type::T_INT;
3216 default:
3217 return Type::T_ERROR;
3218 }
3219 case V_NULL:
3220 return Type::T_NULL;
3221 case V_BOOL:
3222 return Type::T_BOOL;
3223 case V_INT:
3224 return Type::T_INT;
3225 case V_REAL:
3226 return Type::T_REAL;
3227 case V_ENUM:
3228 return Type::T_ENUM_T;
3229 case V_BSTR:
3230 return Type::T_BSTR;
3231 case V_HSTR:
3232 return Type::T_HSTR;
3233 case V_OSTR:
3234 return Type::T_OSTR;
3235 case V_CSTR:
3236 return Type::T_CSTR;
3237 case V_USTR:
3238 return Type::T_USTR;
3239 case V_ISO2022STR:
3240 return Type::T_GENERALSTRING;
3241 case V_OID:
3242 return Type::T_OID;
3243 case V_ROID:
3244 return Type::T_ROID;
3245 case V_VERDICT:
3246 return Type::T_VERDICT;
3247 case V_DEFAULT_NULL:
3248 return Type::T_DEFAULT;
3249 default:
3250 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3251 // to avoid warning
3252 return Type::T_ERROR;
3253 } // switch
3254 }
3255
3256 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3257 {
3258 if(my_governor) return my_governor;
3259 switch (valuetype) {
3260 case V_INVOKE: {
3261 Type *t = u.invoke.v->get_expr_governor(exp_val);
3262 if(!t) {
3263 if(u.invoke.v->get_valuetype() != V_ERROR)
3264 u.invoke.v->error("A value of type function expected");
3265 goto error;
3266 }
3267 t = t->get_type_refd_last();
3268 switch(t->get_typetype()) {
3269 case Type::T_FUNCTION: {
3270 Type *t_return_type = t->get_function_return_type();
3271 if (!t_return_type) {
3272 error("Reference to a %s was expected instead of invocation "
3273 "of behavior type `%s' with no return type",
3274 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3275 t->get_fullname().c_str());
3276 goto error;
3277 }
3278 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3279 error("Reference to a value was expected, but functions of type "
3280 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3281 t_return_type->get_typename().c_str());
3282 goto error;
3283 }
3284 return t_return_type; }
3285 case Type::T_ALTSTEP:
3286 goto error;
3287 default:
3288 u.invoke.v->error("A value of type function expected instead of `%s'",
3289 t->get_typename().c_str());
3290 goto error;
3291 }
3292 break; }
3293 case V_REFD: {
3294 Assignment *ass=u.ref.ref->get_refd_assignment();
3295 Type *tmp_type=0;
3296 if (!ass) goto error;
3297 switch (ass->get_asstype()) {
3298 case Assignment::A_CONST:
3299 case Assignment::A_EXT_CONST:
3300 case Assignment::A_MODULEPAR:
3301 case Assignment::A_MODULEPAR_TEMP:
3302 case Assignment::A_TEMPLATE:
3303 case Assignment::A_VAR:
3304 case Assignment::A_VAR_TEMPLATE:
3305 case Assignment::A_FUNCTION_RVAL:
3306 case Assignment::A_FUNCTION_RTEMP:
3307 case Assignment::A_EXT_FUNCTION_RVAL:
3308 case Assignment::A_EXT_FUNCTION_RTEMP:
3309 case Assignment::A_PAR_VAL_IN:
3310 case Assignment::A_PAR_VAL_OUT:
3311 case Assignment::A_PAR_VAL_INOUT:
3312 case Assignment::A_PAR_TEMPL_IN:
3313 case Assignment::A_PAR_TEMPL_OUT:
3314 case Assignment::A_PAR_TEMPL_INOUT:
3315 tmp_type=ass->get_Type();
3316 break;
3317 case Assignment::A_FUNCTION:
3318 case Assignment::A_EXT_FUNCTION:
3319 error("Reference to a %s was expected instead of a call of %s, which "
3320 "does not have return type",
3321 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3322 ass->get_description().c_str());
3323 goto error;
3324 default:
3325 error("Reference to a %s was expected instead of %s",
3326 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3327 ass->get_description().c_str());
3328 goto error;
3329 } // end switch
3330 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3331 if(!tmp_type) goto error;
3332 return tmp_type; }
3333 case V_EXPR:
3334 switch (u.expr.v_optype) {
3335 case OPTYPE_VALUEOF:
3336 case OPTYPE_SUBSTR:
3337 case OPTYPE_REGEXP:
3338 case OPTYPE_REPLACE:{
3339 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3340 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3341 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3342 return tmp_type;
3343 }
3344 case OPTYPE_ROTL:
3345 case OPTYPE_ROTR:
3346 return u.expr.v1->get_expr_governor(exp_val);
3347 case OPTYPE_CONCAT:
3348 return get_expr_governor_v1v2(exp_val);
3349 case OPTYPE_COMP_MTC:
3350 if (my_scope) return my_scope->get_mtc_system_comptype(false);
3351 else return 0;
3352 case OPTYPE_COMP_SYSTEM:
3353 if (my_scope) return my_scope->get_mtc_system_comptype(true);
3354 else return 0;
3355 case OPTYPE_COMP_SELF:
3356 if (my_scope) {
3357 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3358 if (t_ros) return t_ros->get_component_type();
3359 else return 0;
3360 } else return 0;
3361 case OPTYPE_COMP_CREATE:
3362 return chk_expr_operand_comptyperef_create();
3363 default:
3364 break;
3365 }
3366 // no break
3367 default:
3368 return Type::get_pooltype(get_expr_returntype(exp_val));
3369 }
3370 error:
3371 set_valuetype(V_ERROR);
3372 return 0;
3373 }
3374
3375 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3376 {
3377 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3378 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3379 if (v1_gov) {
3380 if (v2_gov) { // both have governors
3381 // return the type that is compatible with both (if there is no type mismatch)
3382 if (v1_gov->is_compatible(v2_gov, NULL))
3383 return v1_gov;
3384 else return v2_gov;
3385 } else return v1_gov;
3386 } else { // v1 has no governor
3387 if (v2_gov) return v2_gov;
3388 else return NULL; // neither has governor
3389 }
3390 }
3391
3392 Type *Value::get_expr_governor_last()
3393 {
3394 Value *v_last = get_value_refd_last();
3395 if (v_last->valuetype == V_ERROR) return 0;
3396 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3397 if(!t) return 0;
3398 return t->get_type_refd_last();
3399 }
3400
3401 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3402 {
3403 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3404 return u.invoke.v->get_expr_governor(exp_val);
3405 }
3406
3407 const char* Value::get_opname() const
3408 {
3409 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3410 switch(u.expr.v_optype) {
3411 case OPTYPE_RND: // -
3412 return "rnd()";
3413 case OPTYPE_COMP_NULL:
3414 return "(component) null";
3415 case OPTYPE_COMP_MTC:
3416 return "mtc";
3417 case OPTYPE_COMP_SYSTEM:
3418 return "system";
3419 case OPTYPE_COMP_SELF:
3420 return "self";
3421 case OPTYPE_COMP_RUNNING_ANY:
3422 return "any component.running";
3423 case OPTYPE_COMP_RUNNING_ALL:
3424 return "all component.running";
3425 case OPTYPE_COMP_ALIVE_ANY:
3426 return "any component.alive";
3427 case OPTYPE_COMP_ALIVE_ALL:
3428 return "all component.alive";
3429 case OPTYPE_TMR_RUNNING_ANY:
3430 return "any timer.running";
3431 case OPTYPE_GETVERDICT:
3432 return "getverdict()";
3433 case OPTYPE_TESTCASENAME:
3434 return "testcasename()";
3435 case OPTYPE_CHECKSTATE_ANY:
3436 if (u.expr.r1) {
3437 return "port.checkstate()";
3438 } else {
3439 return "any port.checkstate()";
3440 }
3441 case OPTYPE_CHECKSTATE_ALL:
3442 if (u.expr.r1) {
3443 return "port.checkstate()";
3444 } else {
3445 return "all port.checkstate()";
3446 }
3447 case OPTYPE_UNARYPLUS: // v1
3448 return "unary +";
3449 case OPTYPE_UNARYMINUS:
3450 return "unary -";
3451 case OPTYPE_NOT:
3452 return "not";
3453 case OPTYPE_NOT4B:
3454 return "not4b";
3455 case OPTYPE_BIT2HEX:
3456 return "bit2hex()";
3457 case OPTYPE_BIT2INT:
3458 return "bit2int()";
3459 case OPTYPE_BIT2OCT:
3460 return "bit2oct()";
3461 case OPTYPE_BIT2STR:
3462 return "bit2str()";
3463 case OPTYPE_CHAR2INT:
3464 return "char2int()";
3465 case OPTYPE_CHAR2OCT:
3466 return "char2oct()";
3467 case OPTYPE_FLOAT2INT:
3468 return "float2int()";
3469 case OPTYPE_FLOAT2STR:
3470 return "float2str()";
3471 case OPTYPE_HEX2BIT:
3472 return "hex2bit()";
3473 case OPTYPE_HEX2INT:
3474 return "hex2int()";
3475 case OPTYPE_HEX2OCT:
3476 return "hex2oct()";
3477 case OPTYPE_HEX2STR:
3478 return "hex2str()";
3479 case OPTYPE_INT2CHAR:
3480 return "int2char()";
3481 case OPTYPE_INT2FLOAT:
3482 return "int2float()";
3483 case OPTYPE_INT2STR:
3484 return "int2str()";
3485 case OPTYPE_INT2UNICHAR:
3486 return "int2unichar()";
3487 case OPTYPE_OCT2BIT:
3488 return "oct2bit()";
3489 case OPTYPE_OCT2CHAR:
3490 return "oct2char()";
3491 case OPTYPE_OCT2HEX:
3492 return "oct2hex()";
3493 case OPTYPE_OCT2INT:
3494 return "oct2int()";
3495 case OPTYPE_OCT2STR:
3496 return "oct2str()";
3497 case OPTYPE_STR2BIT:
3498 return "str2bit()";
3499 case OPTYPE_STR2FLOAT:
3500 return "str2float()";
3501 case OPTYPE_STR2HEX:
3502 return "str2hex()";
3503 case OPTYPE_STR2INT:
3504 return "str2int()";
3505 case OPTYPE_STR2OCT:
3506 return "str2oct()";
3507 case OPTYPE_UNICHAR2INT:
3508 return "unichar2int()";
3509 case OPTYPE_UNICHAR2CHAR:
3510 return "unichar2char()";
3511 case OPTYPE_UNICHAR2OCT:
3512 return "unichar2oct()";
3513 case OPTYPE_ENUM2INT:
3514 return "enum2int()";
3515 case OPTYPE_LENGTHOF:
3516 return "lengthof()";
3517 case OPTYPE_SIZEOF:
3518 return "sizeof()";
3519 case OPTYPE_RNDWITHVAL:
3520 return "rnd (seed)";
3521 case OPTYPE_ENCODE:
3522 return "encvalue()";
3523 case OPTYPE_DECODE:
3524 return "decvalue()";
3525 case OPTYPE_GET_STRINGENCODING:
3526 return "get_stringencoding()";
3527 case OPTYPE_REMOVE_BOM:
3528 return "remove_bom()";
3529 case OPTYPE_ENCODE_BASE64:
3530 return "encode_base64()";
3531 case OPTYPE_DECODE_BASE64:
3532 return "decode_base64()";
3533 case OPTYPE_ADD: // v1 v2
3534 return "+";
3535 case OPTYPE_SUBTRACT:
3536 return "-";
3537 case OPTYPE_MULTIPLY:
3538 return "*";
3539 case OPTYPE_DIVIDE:
3540 return "/";
3541 case OPTYPE_MOD:
3542 return "mod";
3543 case OPTYPE_REM:
3544 return "rem";
3545 case OPTYPE_CONCAT:
3546 return "&";
3547 case OPTYPE_EQ:
3548 return "==";
3549 case OPTYPE_LT:
3550 return "<";
3551 case OPTYPE_GT:
3552 return ">";
3553 case OPTYPE_NE:
3554 return "!=";
3555 case OPTYPE_GE:
3556 return ">=";
3557 case OPTYPE_LE:
3558 return "<=";
3559 case OPTYPE_AND:
3560 return "and";
3561 case OPTYPE_OR:
3562 return "or";
3563 case OPTYPE_XOR:
3564 return "xor";
3565 case OPTYPE_AND4B:
3566 return "and4b";
3567 case OPTYPE_OR4B:
3568 return "or4b";
3569 case OPTYPE_XOR4B:
3570 return "xor4b";
3571 case OPTYPE_SHL:
3572 return "<<";
3573 case OPTYPE_SHR:
3574 return ">>";
3575 case OPTYPE_ROTL:
3576 return "<@";
3577 case OPTYPE_ROTR:
3578 return "@>";
3579 case OPTYPE_INT2BIT:
3580 return "int2bit()";
3581 case OPTYPE_INT2HEX:
3582 return "int2hex()";
3583 case OPTYPE_INT2OCT:
3584 return "int2oct()";
3585 case OPTYPE_OCT2UNICHAR:
3586 return "oct2unichar()";
3587 case OPTYPE_ENCVALUE_UNICHAR:
3588 return "encvalue_unichar()";
3589 case OPTYPE_DECVALUE_UNICHAR:
3590 return "decvalue_unichar()";
3591 case OPTYPE_SUBSTR:
3592 return "substr()";
3593 case OPTYPE_REGEXP:
3594 return "regexp()";
3595 case OPTYPE_DECOMP:
3596 return "decomp()";
3597 case OPTYPE_REPLACE:
3598 return "replace()";
3599 case OPTYPE_VALUEOF: // t1
3600 return "valueof()";
3601 case OPTYPE_UNDEF_RUNNING:
3602 return "<timer or component> running";
3603 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3604 return "create()";
3605 case OPTYPE_COMP_RUNNING: // v1
3606 return "component running";
3607 case OPTYPE_COMP_ALIVE: // v1
3608 return "alive";
3609 case OPTYPE_TMR_READ:
3610 return "timer read";
3611 case OPTYPE_TMR_RUNNING:
3612 return "timer running";
3613 case OPTYPE_ACTIVATE:
3614 return "activate()";
3615 case OPTYPE_ACTIVATE_REFD:
3616 return "activate()";
3617 case OPTYPE_EXECUTE: // r1 [v2]
3618 case OPTYPE_EXECUTE_REFD:
3619 return "execute()";
3620 case OPTYPE_MATCH: // v1 t2
3621 return "match()";
3622 case OPTYPE_ISPRESENT:
3623 return "ispresent()";
3624 case OPTYPE_ISCHOSEN:
3625 case OPTYPE_ISCHOSEN_V:
3626 case OPTYPE_ISCHOSEN_T:
3627 return "ischosen()";
3628 case OPTYPE_ISVALUE:
3629 return "isvalue()";
3630 case OPTYPE_ISBOUND:
3631 return "isbound()";
3632 case OPTYPE_LOG2STR:
3633 return "log2str()";
3634 case OPTYPE_ANY2UNISTR:
3635 return "any2unistr()";
3636 case OPTYPE_TTCN2STRING:
3637 return "ttcn2string()";
3638 case OPTYPE_PROF_RUNNING:
3639 return "@profiler.running";
3640 default:
3641 FATAL_ERROR("Value::get_opname()");
3642 } // switch
3643 }
3644
3645 void Value::chk_expr_ref_ischosen()
3646 {
3647 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3648 Ttcn::Ref_base *tmpref=u.expr.r1;
3649 Assignment *ass=tmpref->get_refd_assignment();
3650 if (!ass) {
3651 set_valuetype(V_ERROR);
3652 return;
3653 }
3654 // Now we know whether the argument of ischosen() is a value or template.
3655 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3656 // or template (OPTYPE_ISCHOSEN_T).
3657 switch (ass->get_asstype()) {
3658 case Assignment::A_CONST:
3659 case Assignment::A_EXT_CONST:
3660 case Assignment::A_MODULEPAR:
3661 case Assignment::A_VAR:
3662 case Assignment::A_PAR_VAL_IN:
3663 case Assignment::A_PAR_VAL_OUT:
3664 case Assignment::A_PAR_VAL_INOUT:
3665 u.expr.v1=new Value(V_REFD, tmpref);
3666 u.expr.v1->set_location(*tmpref);
3667 u.expr.v1->set_my_scope(get_my_scope());
3668 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3669 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3670 break;
3671 case Assignment::A_MODULEPAR_TEMP:
3672 case Assignment::A_TEMPLATE:
3673 case Assignment::A_VAR_TEMPLATE:
3674 case Assignment::A_PAR_TEMPL_IN:
3675 case Assignment::A_PAR_TEMPL_OUT:
3676 case Assignment::A_PAR_TEMPL_INOUT:
3677 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3678 u.expr.t1->set_location(*tmpref);
3679 u.expr.t1->set_my_scope(get_my_scope());
3680 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3681 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3682 break;
3683 default:
3684 tmpref->error("Reference to a value or template was expected instead of "
3685 "%s", ass->get_description().c_str());
3686 set_valuetype(V_ERROR);
3687 break;
3688 } // switch
3689 }
3690
3691 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3692 Type::expected_value_t exp_val)
3693 {
3694 v->set_lowerid_to_ref(); // can only be reference to enum
3695 Type *t = v->get_expr_governor(exp_val);
3696 if (v->valuetype==V_ERROR) return;
3697 if (!t) {
3698 v->error("Please use reference to an enumerated value as the operand of "
3699 "operation `%s'", get_opname());
3700 set_valuetype(V_ERROR);
3701 return;
3702 }
3703 t = t->get_type_refd_last();
3704 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3705 v->error("The operand of operation `%s' should be enumerated value", opname);
3706 set_valuetype(V_ERROR);
3707 }
3708 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3709 v->error("The operand of operation `%s' cannot be omit", opname);
3710 set_valuetype(V_ERROR);
3711 }
3712 }
3713
3714 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3715 const char *opnum,
3716 const char *opname,
3717 const Location *loc)
3718 {
3719 if(tt==Type::T_BOOL) return;
3720 if(tt!=Type::T_ERROR)
3721 loc->error("%s operand of operation `%s' should be boolean value",
3722 opnum, opname);
3723 set_valuetype(V_ERROR);
3724 }
3725
3726 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3727 const char *opnum,
3728 const char *opname,
3729 const Location *loc)
3730 {
3731 if(tt==Type::T_INT) return;
3732 if(tt!=Type::T_ERROR)
3733 loc->error("%s operand of operation `%s' should be integer value",
3734 opnum, opname);
3735 set_valuetype(V_ERROR);
3736 }
3737
3738 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3739 const char *opnum,
3740 const char *opname,
3741 const Location *loc)
3742 {
3743 if(tt==Type::T_REAL) return;
3744 else if(tt==Type::T_INT)
3745 loc->error("%s operand of operation `%s' should be float value."
3746 " Perhaps you missed an int2float() conversion function"
3747 " or `.0' at the end of the number",
3748 opnum, opname);
3749 else if(tt!=Type::T_ERROR)
3750 loc->error("%s operand of operation `%s' should be float value",
3751 opnum, opname);
3752 set_valuetype(V_ERROR);
3753 }
3754
3755 void Value::chk_expr_operandtype_int_float(Type::typetype_t tt,
3756 const char *opnum,
3757 const char *opname,
3758 const Location *loc)
3759 {
3760 switch(tt) {
3761 case Type::T_INT:
3762 case Type::T_REAL:
3763 return;
3764 default:
3765 break;
3766 }
3767 if(tt!=Type::T_ERROR)
3768 loc->error("%s operand of operation `%s' should be integer"
3769 " or float value",
3770 opnum, opname);
3771 set_valuetype(V_ERROR);
3772 }
3773
3774 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3775 const char *opnum,
3776 const char *opname,
3777 const Location *loc)
3778 {
3779 switch(tt) {
3780 case Type::T_INT:
3781 case Type::T_REAL:
3782 case Type::T_ENUM_T:
3783 return;
3784 default:
3785 break;
3786 }
3787 if(tt!=Type::T_ERROR)
3788 loc->error("%s operand of operation `%s' should be integer, float"
3789 " or enumerated value", opnum, opname);
3790 set_valuetype(V_ERROR);
3791 }
3792
3793 void Value::chk_expr_operandtype_list(Type* t,
3794 const char *opnum,
3795 const char *opname,
3796 const Location *loc,
3797 bool allow_array)
3798 {
3799 if (valuetype == V_ERROR) return;
3800 if (t->get_typetype() == Type::T_ERROR) {
3801 set_valuetype(V_ERROR);
3802 return;
3803 }
3804 if (!t->is_list_type(allow_array)) {
3805 loc->error("%s operand of operation `%s' should be a string, "
3806 "`record of'%s `set of'%s value", opnum, opname,
3807 allow_array ? "," : " or", allow_array ? " or array" : "");
3808 set_valuetype(V_ERROR);
3809 return;
3810 }
3811 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3812 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3813 TypeChain l_chain;
3814 TypeChain r_chain;
3815 if (my_governor && my_governor->is_list_type(allow_array)
3816 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3817 if (info.is_subtype_error()) {
3818 // this is ok.
3819 if (info.needs_conversion()) set_needs_conversion();
3820 } else
3821 if (!info.is_erroneous()) {
3822 error("%s operand of operation `%s' is of type `%s', but a value of "
3823 "type `%s' was expected here", opnum, opname,
3824 t->get_typename().c_str(), my_governor->get_typename().c_str());
3825 } else {
3826 error("%s", info.get_error_str_str().c_str());
3827 }
3828 } else {
3829 if (info.needs_conversion())
3830 set_needs_conversion();
3831 }
3832 }
3833
3834 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3835 const char *opnum,
3836 const char *opname,
3837 const Location *loc)
3838 {
3839 switch(tt) {
3840 case Type::T_CSTR:
3841 case Type::T_USTR:
3842 case Type::T_BSTR:
3843 case Type::T_HSTR:
3844 case Type::T_OSTR:
3845 return;
3846 default:
3847 break;
3848 }
3849 if(tt!=Type::T_ERROR)
3850 loc->error("%s operand of operation `%s' should be string value",
3851 opnum, opname);
3852 set_valuetype(V_ERROR);
3853 }
3854
3855 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3856 const char *opnum,
3857 const char *opname,
3858 const Location *loc)
3859 {
3860 switch(tt) {
3861 case Type::T_CSTR:
3862 case Type::T_USTR:
3863 return;
3864 default:
3865 break;
3866 }
3867 if(tt!=Type::T_ERROR)
3868 loc->error("%s operand of operation `%s' should be (universal)"
3869 " charstring value",
3870 opnum, opname);
3871 set_valuetype(V_ERROR);
3872 }
3873
3874 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3875 const char *opnum,
3876 const char *opname,
3877 const Location *loc)
3878 {
3879 if(tt==Type::T_CSTR) return;
3880 if(tt!=Type::T_ERROR)
3881 loc->error("%s operand of operation `%s' should be charstring value",
3882 opnum, opname);
3883 set_valuetype(V_ERROR);
3884 }
3885
3886 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3887 const char *opnum,
3888 const char *opname,
3889 const Location *loc)
3890 {
3891 switch(tt) {
3892 case Type::T_BSTR:
3893 case Type::T_HSTR:
3894 case Type::T_OSTR:
3895 return;
3896 default:
3897 break;
3898 }
3899 if(tt!=Type::T_ERROR)
3900 loc->error("%s operand of operation `%s' should be binary string value",
3901 opnum, opname);
3902 set_valuetype(V_ERROR);
3903 }
3904
3905 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3906 const char *opnum,
3907 const char *opname,
3908 const Location *loc)
3909 {
3910 if(tt==Type::T_BSTR) return;
3911 if(tt!=Type::T_ERROR)
3912 loc->error("%s operand of operation `%s' should be bitstring value",
3913 opnum, opname);
3914 set_valuetype(V_ERROR);
3915 }
3916
3917 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3918 const char *opnum,
3919 const char *opname,
3920 const Location *loc)
3921 {
3922 if(tt==Type::T_HSTR) return;
3923 if(tt!=Type::T_ERROR)
3924 loc->error("%s operand of operation `%s' should be hexstring value",
3925 opnum, opname);
3926 set_valuetype(V_ERROR);
3927 }
3928
3929 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3930 const char *opnum,
3931 const char *opname,
3932 const Location *loc)
3933 {
3934 if(tt==Type::T_OSTR) return;
3935 if(tt!=Type::T_ERROR)
3936 loc->error("%s operand of operation `%s' should be octetstring value",
3937 opnum, opname);
3938 set_valuetype(V_ERROR);
3939 }
3940
3941 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3942 Type::typetype_t tt2,
3943 const char *opname)
3944 {
3945 if(valuetype==V_ERROR) return;
3946 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3947 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3948 set_valuetype(V_ERROR);
3949 return;
3950 }
3951 if(tt1==tt2) return;
3952 error("The operands of operation `%s' should be of same type", opname);
3953 set_valuetype(V_ERROR);
3954 }
3955
3956 /* For predefined functions. */
3957 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3958 Type::typetype_t tt2,
3959 const char *opnum1,
3960 const char *opnum2,
3961 const char *opname)
3962 {
3963 if(valuetype==V_ERROR) return;
3964 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3965 set_valuetype(V_ERROR);
3966 return;
3967 }
3968 if(tt1==tt2) return;
3969 error("The %s and %s operands of operation `%s' should be of same type",
3970 opnum1, opnum2, opname);
3971 set_valuetype(V_ERROR);
3972 }
3973
3974 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3975 Value *v1, Value *v2,
3976 const char *opnum1,
3977 const char *opnum2)
3978 {
3979 start:
3980 if (valuetype == V_ERROR) return;
3981 // if (u.expr.state == EXPR_CHECKING_ERR) return;
3982 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
3983 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
3984
3985 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
3986 set_valuetype(V_ERROR);
3987 return;
3988 }
3989 if (tt1 == Type::T_UNDEF) {
3990 if (tt2 == Type::T_UNDEF) {
3991 if (v1->is_undef_lowerid()) {
3992 if (v2->is_undef_lowerid()) {
3993 Scope *scope = get_my_scope();
3994 Module *my_mod = scope->get_scope_mod();
3995 const Identifier& id1 = v1->get_undef_lowerid();
3996 if (scope->has_ass_withId(id1)
3997 || my_mod->has_imported_ass_withId(id1)) {
3998 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
3999 * should examine this situation better, but now I suppose
4000 * the first is ref, not enum. */
4001 v1->set_lowerid_to_ref();
4002 goto start;
4003 } else {
4004 const Identifier& id2 = v2->get_undef_lowerid();
4005 if (scope->has_ass_withId(id2)
4006 || my_mod->has_imported_ass_withId(id2)) {
4007 v2->set_lowerid_to_ref();
4008 goto start;
4009 }
4010 }
4011 /* This is perhaps enum-enum, but it has no real
4012 * significance, so this should be an error. */
4013 } else {
4014 v1->set_lowerid_to_ref();
4015 goto start;
4016 }
4017 } else if (v2->is_undef_lowerid()) {
4018 v2->set_lowerid_to_ref();
4019 goto start;
4020 }
4021 error("Cannot determine the type of the operands in operation `%s'",
4022 get_opname());
4023 set_valuetype(V_ERROR);
4024 return;
4025 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
4026 v1->set_lowerid_to_ref();
4027 goto start;
4028 } else {
4029 /* v1 is something undefined, but not lowerid; v2 has
4030 * returntype (perhaps also governor) */
4031 }
4032 } else if (tt2 == Type::T_UNDEF) {
4033 /* but tt1 is not undef */
4034 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
4035 v2->set_lowerid_to_ref();
4036 goto start;
4037 } else {
4038 /* v2 is something undefined, but not lowerid; v1 has
4039 * returntype (perhaps also governor) */
4040 }
4041 }
4042
4043 /* Now undef_lower_id's are converted to references, or the other
4044 * value has governor; let's see the governors, if they exist. */
4045 Type *t1 = v1->get_expr_governor(exp_val);
4046 Type *t2 = v2->get_expr_governor(exp_val);
4047 if (t1) {
4048 if (t2) {
4049 // Both value has governor. Are they compatible? According to 7.1.2
4050 // and C.34 it's required to have the same root types for
4051 // OPTYPE_{CONCAT,REPLACE}.
4052 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
4053 u.expr.v_optype == OPTYPE_REPLACE);
4054 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
4055 u.expr.v_optype == OPTYPE_REPLACE);
4056 TypeChain l_chain1, l_chain2;
4057 TypeChain r_chain1, r_chain2;
4058 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
4059 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
4060 if (!compat_t1 && !compat_t2) {
4061 if (!info1.is_erroneous() && !info2.is_erroneous()) {
4062 // the subtypes don't need to be compatible here
4063 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
4064 error("The operands of operation `%s' should be of compatible "
4065 "types", get_opname());
4066 set_valuetype(V_ERROR);
4067 } else {
4068 if (info1.needs_conversion() || info2.needs_conversion()) {
4069 set_needs_conversion(); // Avoid folding.
4070 return;
4071 }
4072 }
4073 } else {
4074 if (info1.is_erroneous())
4075 v1->error("%s", info1.get_error_str_str().c_str());
4076 else if (info2.is_erroneous())
4077 v2->error("%s", info2.get_error_str_str().c_str());
4078 set_valuetype(V_ERROR);
4079 }
4080 return;
4081 } else if (info1.needs_conversion() || info2.needs_conversion()) {
4082 set_needs_conversion(); // Avoid folding.
4083 return;
4084 }
4085 } else {
4086 // t1, no t2.
4087 v2->set_my_governor(t1);
4088 t1->chk_this_value_ref(v2);
4089 if (v2->valuetype == V_OMIT) {
4090 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4091 get_opname());
4092 v1->chk_expr_omit_comparison(exp_val);
4093 } else {
4094 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4095 get_opname());
4096 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4097 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4098 goto start;
4099 }
4100 }
4101 } else if (t2) {
4102 v1->set_my_governor(t2);
4103 t2->chk_this_value_ref(v1);
4104 if (v1->valuetype == V_OMIT) {
4105 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4106 get_opname());
4107 v2->chk_expr_omit_comparison(exp_val);
4108 } else {
4109 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4110 get_opname());
4111 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4112 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4113 goto start;
4114 }
4115 } else {
4116 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4117 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
4118 // Here, it cannot be that both are T_UNDEF.
4119 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4120 error("Please use reference as %s operand of operator `%s'",
4121 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
4122 set_valuetype(V_ERROR);
4123 return;
4124 }
4125 // Deny type compatibility if no governors found. The typetype_t must
4126 // be the same. TODO: How can this happen?
4127 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
4128 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
4129 error("The operands of operation `%s' should be of compatible types",
4130 get_opname());
4131 set_valuetype(V_ERROR);
4132 }
4133 }
4134 }
4135
4136 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
4137 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
4138 {
4139 if(valuetype==V_ERROR) return;
4140 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4141 Assignment *t_ass = ref->get_refd_assignment();
4142 if(!t_ass) goto error;
4143 switch(t_ass->get_asstype()) {
4144 case Assignment::A_TIMER:
4145 case Assignment::A_PAR_TIMER:
4146 u.expr.v_optype=OPTYPE_TMR_RUNNING;
4147 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
4148 chk_expr_dynamic_part(exp_val, true);
4149 break;
4150 case Assignment::A_CONST:
4151 case Assignment::A_EXT_CONST:
4152 case Assignment::A_MODULEPAR:
4153 case Assignment::A_VAR:
4154 case Assignment::A_FUNCTION_RVAL:
4155 case Assignment::A_EXT_FUNCTION_RVAL:
4156 case Assignment::A_PAR_VAL_IN:
4157 case Assignment::A_PAR_VAL_OUT:
4158 case Assignment::A_PAR_VAL_INOUT: {
4159 u.expr.v_optype = OPTYPE_COMP_RUNNING;
4160 Value* val = new Value(V_REFD, u.expr.r1);
4161 val->set_my_scope(my_scope);
4162 val->set_fullname(u.expr.r1->get_fullname());
4163 val->set_location(*u.expr.r1);
4164 u.expr.v1 = val;
4165 chk_expr_operand_compref(val, opnum, get_opname());
4166 chk_expr_dynamic_part(exp_val, false);
4167 break; }
4168 default:
4169 ref->error("%s operand of operation `%s' should be timer or"
4170 " component reference instead of %s",
4171 opnum, opname, t_ass->get_description().c_str());
4172 goto error;
4173 } // switch
4174 return;
4175 error:
4176 set_valuetype(V_ERROR);
4177 }
4178
4179 Type *Value::chk_expr_operand_comptyperef_create()
4180 {
4181 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4182 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4183 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4184 if (!t_ass) goto error;
4185 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4186 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4187 Type::EXPECTED_DYNAMIC_VALUE);
4188 if (!t_type) goto error;
4189 t_type = t_type->get_type_refd_last();
4190 if (t_type->get_typetype() == Type::T_COMPONENT) {
4191 if (my_governor) {
4192 Type *my_governor_last = my_governor->get_type_refd_last();
4193 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4194 !my_governor_last->is_compatible(t_type, NULL)) {
4195 u.expr.r1->error("Incompatible component types: operation "
4196 "`create' should refer to `%s' instead of "
4197 "`%s'",
4198 my_governor_last->get_typename().c_str(),
4199 t_type->get_typename().c_str());
4200 goto error;
4201 }
4202 }
4203 return t_type;
4204 } else {
4205 u.expr.r1->error("Type mismatch: reference to a component type was "
4206 "expected in operation `create' instead of `%s'",
4207 t_type->get_typename().c_str());
4208 }
4209 } else {
4210 u.expr.r1->error("Operation `create' should refer to a component type "
4211 "instead of %s", t_ass->get_description().c_str());
4212 }
4213 error:
4214 set_valuetype(V_ERROR);
4215 return NULL;
4216 }
4217
4218 void Value::chk_expr_comptype_compat()
4219 {
4220 if (valuetype != V_EXPR)
4221 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4222 if (!my_governor || !my_scope) return;
4223 Type *my_governor_last = my_governor->get_type_refd_last();
4224 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4225 Type *t_comptype;
4226 switch (u.expr.v_optype) {
4227 case OPTYPE_COMP_MTC:
4228 t_comptype = my_scope->get_mtc_system_comptype(false);
4229 break;
4230 case OPTYPE_COMP_SYSTEM:
4231 t_comptype = my_scope->get_mtc_system_comptype(true);
4232 break;
4233 case OPTYPE_COMP_SELF: {
4234 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4235 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4236 break; }
4237 default:
4238 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4239 t_comptype = 0;
4240 break;
4241 }
4242 if (t_comptype
4243 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4244 error("Incompatible component types: a component reference of "
4245 "type `%s' was expected, but `%s' has type `%s'",
4246 my_governor_last->get_typename().c_str(), get_opname(),
4247 t_comptype->get_typename().c_str());
4248 set_valuetype(V_ERROR);
4249 }
4250 }
4251
4252 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4253 const char *opname)
4254 {
4255 if(valuetype == V_ERROR) return;
4256 switch(val->get_valuetype()) {
4257 case V_INVOKE: {
4258 Error_Context cntxt(this, "In `%s' operation", opname);
4259 Value *v_last = val->get_value_refd_last();
4260 if(!v_last) goto error;
4261 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4262 if(!t) goto error;
4263 t = t->get_type_refd_last();
4264 if(t->get_typetype() != Type::T_COMPONENT) {
4265 v_last->error("%s operand of operation `%s': Type mismatch:"
4266 " component reference was expected instead of `%s'",
4267 opnum, opname, t->get_typename().c_str());
4268 goto error;
4269 }
4270 return; }
4271 case V_REFD: {
4272 Reference *ref = val->get_reference();
4273 Assignment *t_ass = ref->get_refd_assignment();
4274 Value *t_val = 0;
4275 if (!t_ass) goto error;
4276 switch(t_ass->get_asstype()) {
4277 case Assignment::A_CONST:
4278 t_val = t_ass->get_Value();
4279 // no break
4280 case Assignment::A_EXT_CONST:
4281 case Assignment::A_MODULEPAR:
4282 case Assignment::A_VAR:
4283 case Assignment::A_FUNCTION_RVAL:
4284 case Assignment::A_EXT_FUNCTION_RVAL:
4285 case Assignment::A_PAR_VAL_IN:
4286 case Assignment::A_PAR_VAL_OUT:
4287 case Assignment::A_PAR_VAL_INOUT: {
4288 Type *t_type=t_ass->get_Type()
4289 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4290 if(!t_type) goto error;
4291 t_type=t_type->get_type_refd_last();
4292 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4293 ref->error("%s operand of operation `%s': Type mismatch:"
4294 " component reference was expected instead of `%s'",
4295 opnum, opname, t_type->get_typename().c_str());
4296 goto error;
4297 }
4298 break;}
4299 default:
4300 ref->error("%s operand of operation `%s' should be"
4301 " component reference instead of %s",
4302 opnum, opname, t_ass->get_description().c_str());
4303 goto error;
4304 }
4305 if (t_val) {
4306 ReferenceChain refch(this, "While searching referenced value");
4307 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4308 if (!t_val) return;
4309 t_val = t_val->get_value_refd_last();
4310 if (t_val->valuetype != V_EXPR) return;
4311 switch (t_val->u.expr.v_optype) {
4312 case OPTYPE_COMP_NULL:
4313 ref->error("%s operand of operation `%s' refers to `null' component "
4314 "reference", opnum, opname);
4315 goto error;
4316 case OPTYPE_COMP_MTC:
4317 ref->error("%s operand of operation `%s' refers to the component "
4318 "reference of the `mtc'", opnum, opname);
4319 goto error;
4320 case OPTYPE_COMP_SYSTEM:
4321 ref->error("%s operand of operation `%s' refers to the component "
4322 "reference of the `system'", opnum, opname);
4323 goto error;
4324 default:
4325 break;
4326 }
4327 }
4328 return;}
4329 default:
4330 FATAL_ERROR("Value::chk_expr_operand_compref()");
4331 }
4332 error:
4333 set_valuetype(V_ERROR);
4334 }
4335
4336 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4337 const char *opnum,
4338 const char *opname)
4339 {
4340 if(valuetype==V_ERROR) return;
4341 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4342 Assignment *t_ass = ref->get_refd_assignment();
4343 if(!t_ass) goto error;
4344 switch(t_ass->get_asstype()) {
4345 case Assignment::A_TIMER: {
4346 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4347 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4348 Type::EXPECTED_DYNAMIC_VALUE);
4349 else if (ref->get_subrefs()) {
4350 ref->error("%s operand of operation `%s': "
4351 "Reference to single timer `%s' cannot have field or array "
4352 "sub-references", opnum, opname,
4353 t_ass->get_id().get_dispname().c_str());
4354 goto error;
4355 }
4356 break; }
4357 case Assignment::A_PAR_TIMER:
4358 if (ref->get_subrefs()) {
4359 ref->error("%s operand of operation `%s': "
4360 "Reference to %s cannot have field or array sub-references",
4361 opnum, opname, t_ass->get_description().c_str());
4362 goto error;
4363 }
4364 break;
4365 default:
4366 ref->error("%s operand of operation `%s' should be timer"
4367 " instead of %s",
4368 opnum, opname, t_ass->get_description().c_str());
4369 goto error;
4370 } // switch
4371 return;
4372 error:
4373 set_valuetype(V_ERROR);
4374 }
4375
4376 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4377 const char *,
4378 const char *opname)
4379 {
4380 if(valuetype==V_ERROR) return;
4381 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4382 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4383 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4384 Error_Context cntxt(this, "In `%s' operation", opname);
4385 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4386 }
4387
4388 void Value::chk_expr_operand_activate_refd(Value *val,
4389 Ttcn::TemplateInstances* t_list2,
4390 Ttcn::ActualParList *&parlist,
4391 const char *,
4392 const char *opname)
4393 {
4394 if(valuetype==V_ERROR) return;
4395 Error_Context cntxt(this, "In `%s' operation", opname);
4396 Type *t = val->get_expr_governor_last();
4397 if (t) {
4398 switch (t->get_typetype()) {
4399 case Type::T_ERROR:
4400 set_valuetype(V_ERROR);
4401 break;
4402 case Type::T_ALTSTEP: {
4403 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4404 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4405 if(is_erroneous) {
4406 delete parlist;
4407 parlist = 0;
4408 set_valuetype(V_ERROR);
4409 } else {
4410 parlist->set_fullname(get_fullname());
4411 parlist->set_my_scope(get_my_scope());
4412 if (!fp_list->chk_activate_argument(parlist,
4413 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4414 }
4415 break; }
4416 default:
4417 error("Reference to an altstep was expected in the argument of "
4418 "`derefers()' instead of `%s'", t->get_typename().c_str());
4419 set_valuetype(V_ERROR);
4420 break;
4421 }
4422 } else set_valuetype(V_ERROR);
4423 }
4424
4425 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4426 const char *,
4427 const char *opname)
4428 {
4429 if(valuetype==V_ERROR) return;
4430 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4431 Error_Context cntxt(this, "In `%s' operation", opname);
4432 Assignment *t_ass = ref->get_refd_assignment();
4433 bool error_flag = false;
4434 if (t_ass) {
4435 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4436 ref->error("Reference to a testcase was expected in the argument "
4437 "instead of %s", t_ass->get_description().c_str());
4438 error_flag = true;
4439 }
4440 } else error_flag = true;
4441 if (val) {
4442 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4443 Value *v_last = val->get_value_refd_last();
4444 switch (v_last->valuetype) {
4445 case V_REAL: {
4446 ttcn3float v_real = v_last->get_val_Real();
4447 if (v_real < 0.0) {
4448 val->error("The testcase guard timer has negative value: `%s'",
4449 Real2string(v_real).c_str());
4450 error_flag = true;
4451 }
4452 break; }
4453 case V_ERROR:
4454 error_flag = true;
4455 break;
4456 default:
4457 break;
4458 }
4459 }
4460 if (error_flag) set_valuetype(V_ERROR);
4461 }
4462
4463 void Value::chk_expr_operand_execute_refd(Value *v1,
4464 Ttcn::TemplateInstances* t_list2,
4465 Ttcn::ActualParList *&parlist,
4466 Value *v3,
4467 const char *,
4468 const char *opname)
4469 {
4470 if(valuetype==V_ERROR) return;
4471 Error_Context cntxt(this, "In `%s' operation", opname);
4472 Type *t = v1->get_expr_governor_last();
4473 if (t) {
4474 switch (t->get_typetype()) {
4475 case Type::T_ERROR:
4476 set_valuetype(V_ERROR);
4477 break;
4478 case Type::T_TESTCASE: {
4479 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4480 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4481 if(is_erroneous) {
4482 delete parlist;
4483 parlist = 0;
4484 set_valuetype(V_ERROR);
4485 } else {
4486 parlist->set_fullname(get_fullname());
4487 parlist->set_my_scope(get_my_scope());
4488 }
4489 break; }
4490 default:
4491 v1->error("Reference to a value of type testcase was expected in the "
4492 "argument of `derefers()' instead of `%s'",
4493 t->get_typename().c_str());
4494 set_valuetype(V_ERROR);
4495 break;
4496 }
4497 } else set_valuetype(V_ERROR);
4498 if (v3) {
4499 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4500 Value *v_last = v3->get_value_refd_last();
4501 switch (v_last->valuetype) {
4502 case V_REAL: {
4503 ttcn3float v_real = v_last->get_val_Real();
4504 if(v_real < 0.0) {
4505 v3->error("The testcase guard timer has negative value: `%s'",
4506 Real2string(v_real).c_str());
4507 set_valuetype(V_ERROR);
4508 }
4509 break; }
4510 case V_ERROR:
4511 set_valuetype(V_ERROR);
4512 break;
4513 default:
4514 break;
4515 }
4516 }
4517 }
4518
4519 void Value::chk_invoke(Type::expected_value_t exp_val)
4520 {
4521 if(valuetype == V_ERROR) return;
4522 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4523 if(!u.invoke.t_list) return; //already checked
4524 Error_Context cntxt(this, "In `apply()' operation");
4525 Type *t = u.invoke.v->get_expr_governor_last();
4526 if (!t) {
4527 set_valuetype(V_ERROR);
4528 return;
4529 }
4530 switch (t->get_typetype()) {
4531 case Type::T_ERROR:
4532 set_valuetype(V_ERROR);
4533 return;
4534 case Type::T_FUNCTION:
4535 break;
4536 default:
4537 u.invoke.v->error("A value of type function was expected in the "
4538 "argument instead of `%s'", t->get_typename().c_str());
4539 set_valuetype(V_ERROR);
4540 return;
4541 }
4542 my_scope->chk_runs_on_clause(t, *this, "call");
4543 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4544 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4545 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4546 delete u.invoke.t_list;
4547 u.invoke.t_list = 0;
4548 if(is_erroneous) {
4549 delete parlist;
4550 u.invoke.ap_list = 0;
4551 } else {
4552 parlist->set_fullname(get_fullname());
4553 parlist->set_my_scope(get_my_scope());
4554 u.invoke.ap_list = parlist;
4555 }
4556 switch (exp_val) {
4557 case Type::EXPECTED_CONSTANT:
4558 error("An evaluable constant value was expected instead of operation "
4559 "`apply()'");
4560 set_valuetype(V_ERROR);
4561 break;
4562 case Type::EXPECTED_STATIC_VALUE:
4563 error("A static value was expected instead of operation `apply()'");
4564 set_valuetype(V_ERROR);
4565 break;
4566 default:
4567 break;
4568 } // switch
4569 }
4570
4571 void Value::chk_expr_eval_value(Value *val, Type &t,
4572 ReferenceChain *refch,
4573 Type::expected_value_t exp_val)
4574 {
4575 bool self_ref = false;
4576 if(valuetype==V_ERROR) return;
4577 // Commented out to report more errors :)
4578 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4579 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4580 switch(val->get_valuetype()) {
4581 case V_REFD:
4582 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4583 break;
4584 case V_EXPR:
4585 case V_MACRO:
4586 case V_INVOKE:
4587 val->get_value_refd_last(refch, exp_val);
4588 break;
4589 default:
4590 break;
4591 } // switch
4592 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4593
4594 (void)self_ref;
4595 }
4596
4597 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4598 ReferenceChain *refch, Type::expected_value_t exp_val)
4599 {
4600 bool self_ref = false;
4601 ti->chk(type);
4602 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4603 ti->error("Reference to a %s value was expected instead of an in-line "
4604 "modified template",
4605 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4606 set_valuetype(V_ERROR);
4607 return;
4608 }
4609 Template *templ = ti->get_Template();
4610 switch (templ->get_templatetype()) {
4611 case Template::TEMPLATE_REFD:
4612 // not foldable
4613 if (exp_val == Type::EXPECTED_TEMPLATE) {
4614 templ = templ->get_template_refd_last(refch);
4615 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4616 set_valuetype(V_ERROR);
4617 } else {
4618 ti->error("Reference to a %s value was expected instead of %s",
4619 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4620 templ->get_reference()->get_refd_assignment()
4621 ->get_description().c_str());
4622 set_valuetype(V_ERROR);
4623 }
4624 break;
4625 case Template::SPECIFIC_VALUE: {
4626 Value *val = templ->get_specific_value();
4627 switch (val->get_valuetype()) {
4628 case V_REFD:
4629 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4630 break;
4631 case V_EXPR:
4632 val->get_value_refd_last(refch, exp_val);
4633 default:
4634 break;
4635 } // switch
4636 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4637 break; }
4638 case Template::TEMPLATE_ERROR:
4639 set_valuetype(V_ERROR);
4640 break;
4641 default:
4642 break;
4643 } // switch
4644
4645 (void)self_ref;
4646 }
4647
4648 void Value::chk_expr_val_int_pos0(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->is_unfoldable()) return;
4654 if(*val->get_val_Int()<0) {
4655 val->error("%s operand of operation `%s' should not be negative",
4656 opnum, opname);
4657 set_valuetype(V_ERROR);
4658 }
4659 }
4660
4661 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4662 const char *opname)
4663 {
4664 if(valuetype==V_ERROR) return;
4665 if(u.expr.state==EXPR_CHECKING_ERR) return;
4666 if(val->is_unfoldable()) return;
4667 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4668 val->error("%s operand of operation `%s' should be in range 0..127",
4669 opnum, opname);
4670 set_valuetype(V_ERROR);
4671 }
4672 }
4673
4674 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4675 const char *opname)
4676 {
4677 if(valuetype==V_ERROR) return;
4678 if(u.expr.state==EXPR_CHECKING_ERR) return;
4679 if(val->is_unfoldable()) return;
4680 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4681 val->error("%s operand of operation `%s' should be in range"
4682 " 0..2147483647", opnum, opname);
4683 set_valuetype(V_ERROR);
4684 }
4685 }
4686
4687 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4688 const char *opname)
4689 {
4690 if(valuetype==V_ERROR) return;
4691 if(u.expr.state==EXPR_CHECKING_ERR) return;
4692 if(val->is_unfoldable()) return;
4693 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4694 ||
4695 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4696 {
4697 val->error("%s operand of operation `%s' should not be zero",
4698 opnum, opname);
4699 set_valuetype(V_ERROR);
4700 }
4701 }
4702
4703 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4704 const char *opname)
4705 {
4706 if (valuetype == V_ERROR) return;
4707 if (u.expr.state == EXPR_CHECKING_ERR) return;
4708 if (val->get_expr_returntype() != Type::T_INT) return;
4709 if (val->is_unfoldable()) return;
4710 const int_val_t *val_int = val->get_val_Int();
4711 if (*val_int > static_cast<Int>(INT_MAX)) {
4712 val->error("%s operand of operation `%s' should be less than `%d' "
4713 "instead of `%s'", opnum, opname, INT_MAX,
4714 (val_int->t_str()).c_str());
4715 set_valuetype(V_ERROR);
4716 }
4717 }
4718
4719 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4720 const char *opname)
4721 {
4722 if(valuetype==V_ERROR) return;
4723 if(u.expr.state==EXPR_CHECKING_ERR) return;
4724 if(val->is_unfoldable()) return;
4725 if(val->get_val_strlen()!=1) {
4726 val->error("%s operand of operation `%s' should be of length 1",
4727 opnum, opname);
4728 set_valuetype(V_ERROR);
4729 }
4730 }
4731
4732 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4733 const char *opname)
4734 {
4735 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4736 Value *v_last = val->get_value_refd_last();
4737 if (v_last->valuetype == V_CSTR) {
4738 size_t len = v_last->get_val_strlen();
4739 if (len % 2) {
4740 val->error("%s operand of operation `%s' should contain even number "
4741 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4742 set_valuetype(V_ERROR);
4743 }
4744 } else if (v_last->valuetype == V_REFD) {
4745 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4746 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4747 val->error("%s operand of operation `%s' should contain even number "
4748 "of characters, but a string element contains 1", opnum, opname);
4749 set_valuetype(V_ERROR);
4750 }
4751 }
4752 }
4753
4754 void Value::chk_expr_val_str_bindigits(Value *val, const char *opnum,
4755 const char *opname)
4756 {
4757 if(valuetype==V_ERROR) return;
4758 if(u.expr.state==EXPR_CHECKING_ERR) return;
4759 if(val->is_unfoldable()) return;
4760 const string& s=val->get_val_str();
4761 for(size_t i=0; i<s.size(); i++) {
4762 char c=s[i];
4763 if(!(c=='0' || c=='1')) {
4764 val->error("%s operand of operation `%s' can contain only"
4765 " binary digits (position %lu is `%c')",
4766 opnum, opname, (unsigned long) i, c);
4767 set_valuetype(V_ERROR);
4768 return;
4769 }
4770 }
4771 }
4772
4773 void Value::chk_expr_val_str_hexdigits(Value *val, const char *opnum,
4774 const char *opname)
4775 {
4776 if(valuetype==V_ERROR) return;
4777 if(u.expr.state==EXPR_CHECKING_ERR) return;
4778 if(val->is_unfoldable()) return;
4779 const string& s=val->get_val_str();
4780 for(size_t i=0; i<s.size(); i++) {
4781 char c=s[i];
4782 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4783 val->error("%s operand of operation `%s' can contain only valid "
4784 "hexadecimal digits (position %lu is `%c')",
4785 opnum, opname, (unsigned long) i, c);
4786 set_valuetype(V_ERROR);
4787 return;
4788 }
4789 }
4790 }
4791
4792 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4793 const char *opname)
4794 {
4795 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4796 Value *v = val->get_value_refd_last();
4797 if (v->valuetype != V_OSTR) return;
4798 const string& s = val->get_val_str();
4799 size_t n_octets = s.size() / 2;
4800 for (size_t i = 0; i < n_octets; i++) {
4801 char c = s[2 * i];
4802 if (!(c >= '0' && c <= '7')) {
4803 val->error("%s operand of operation `%s' shall consist of octets "
4804 "within the range 00 .. 7F, but the string `%s'O contains octet "
4805 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4806 (unsigned long) i);
4807 set_valuetype(V_ERROR);
4808 return;
4809 }
4810 }
4811 }
4812
4813 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4814 const char *opname)
4815 {
4816 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4817 Value *v_last = val->get_value_refd_last();
4818 if (v_last->valuetype != V_CSTR) return;
4819 const string& s = v_last->get_val_str();
4820 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4821 state = S_INITIAL;
4822 // state: expected characters
4823 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4824 // S_FIRST: first digit
4825 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4826 // S_END: trailing whitespace
4827 // S_ERR: error was found, stop
4828 for (size_t i = 0; i < s.size(); i++) {
4829 char c = s[i];
4830 switch (state) {
4831 case S_INITIAL:
4832 case S_INITIAL_WS:
4833 if (c == '+' || c == '-') state = S_FIRST;
4834 else if (c == '0') state = S_ZERO;
4835 else if (c >= '1' && c <= '9') state = S_MORE;
4836 else if (string::is_whitespace(c)) {
4837 if (state == S_INITIAL) {
4838 val->warning("Leading whitespace was detected and ignored in the "
4839 "operand of operation `%s'", opname);
4840 state = S_INITIAL_WS;
4841 }
4842 } else state = S_ERR;
4843 break;
4844 case S_FIRST:
4845 if (c == '0') state = S_ZERO;
4846 else if (c >= '1' && c <= '9') state = S_MORE;
4847 else state = S_ERR;
4848 break;
4849 case S_ZERO:
4850 if (c >= '0' && c <= '9') {
4851 val->warning("Leading zero digit was detected and ignored in the "
4852 "operand of operation `%s'", opname);
4853 state = S_MORE;
4854 } else if (string::is_whitespace(c)) state = S_END;
4855 else state = S_ERR;
4856 break;
4857 case S_MORE:
4858 if (c >= '0' && c <= '9') {}
4859 else if (string::is_whitespace(c)) state = S_END;
4860 else state = S_ERR;
4861 break;
4862 case S_END:
4863 if (!string::is_whitespace(c)) state = S_ERR;
4864 break;
4865 default:
4866 break;
4867 }
4868 if (state == S_ERR) {
4869 if (string::is_printable(c)) {
4870 val->error("%s operand of operation `%s' should be a string "
4871 "containing a valid integer value, but invalid character `%c' "
4872 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4873 } else {
4874 val->error("%s operand of operation `%s' should be a string "
4875 "containing a valid integer value, but invalid character with "
4876 "character code %u was detected at index %lu", opnum, opname, c,
4877 (unsigned long) i);
4878 }
4879 set_valuetype(V_ERROR);
4880 break;
4881 }
4882 }
4883 switch (state) {
4884 case S_INITIAL:
4885 case S_INITIAL_WS:
4886 val->error("%s operand of operation `%s' should be a string containing a "
4887 "valid integer value instead of an empty string", opnum, opname);
4888 set_valuetype(V_ERROR);
4889 break;
4890 case S_FIRST:
4891 val->error("%s operand of operation `%s' should be a string containing a "
4892 "valid integer value, but only a sign character was detected", opnum,
4893 opname);
4894 set_valuetype(V_ERROR);
4895 break;
4896 case S_END:
4897 val->warning("Trailing whitespace was detected and ignored in the "
4898 "operand of operation `%s'", opname);
4899 break;
4900 default:
4901 break;
4902 }
4903 }
4904
4905 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4906 const char *opname)
4907 {
4908 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4909 Value *v_last = val->get_value_refd_last();
4910 if (v_last->valuetype == V_REFD) {
4911 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4912 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4913 val->error("%s operand of operation `%s' should be a string containing "
4914 "a valid float value instead of a string element, which cannot "
4915 "represent a floating point number", opnum, opname);
4916 set_valuetype(V_ERROR);
4917 }
4918 return;
4919 } else if (v_last->valuetype != V_CSTR) return;
4920 const string& s = v_last->get_val_str();
4921 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4922 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4923 state = S_INITIAL;
4924 // state: expected characters
4925 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4926 // leading whitespace
4927 // S_FIRST_M: first digit of integer part in mantissa
4928 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4929 // S_FIRST_F: first digit of fraction
4930 // S_MORE_F: more digits of fraction, E, trailing whitespace
4931 // S_INITIAL_E: +, -, first digit of exponent
4932 // S_FIRST_E: first digit of exponent
4933 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4934 // S_END: trailing whitespace
4935 // S_ERR: error was found, stop
4936 for (size_t i = 0; i < s.size(); i++) {
4937 char c = s[i];
4938 switch (state) {
4939 case S_INITIAL:
4940 case S_INITIAL_WS:
4941 if (c == '+' || c == '-') state = S_FIRST_M;
4942 else if (c == '0') state = S_ZERO_M;
4943 else if (c >= '1' && c <= '9') state = S_MORE_M;
4944 else if (string::is_whitespace(c)) {
4945 if (state == S_INITIAL) {
4946 val->warning("Leading whitespace was detected and ignored in the "
4947 "operand of operation `%s'", opname);
4948 state = S_INITIAL_WS;
4949 }
4950 } else state = S_ERR;
4951 break;
4952 case S_FIRST_M:
4953 if (c == '0') state = S_ZERO_M;
4954 else if (c >= '1' && c <= '9') state = S_MORE_M;
4955 else state = S_ERR;
4956 break;
4957 case S_ZERO_M:
4958 if (c == '.') state = S_FIRST_F;
4959 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4960 else if (c >= '0' && c <= '9') {
4961 val->warning("Leading zero digit was detected and ignored in the "
4962 "mantissa of the operand of operation `%s'", opname);
4963 state = S_MORE_M;
4964 } else state = S_ERR;
4965 break;
4966 case S_MORE_M:
4967 if (c == '.') state = S_FIRST_F;
4968 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4969 else if (c >= '0' && c <= '9') {}
4970 else state = S_ERR;
4971 break;
4972 case S_FIRST_F:
4973 if (c >= '0' && c <= '9') state = S_MORE_F;
4974 else state = S_ERR;
4975 break;
4976 case S_MORE_F:
4977 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4978 else if (c >= '0' && c <= '9') {}
4979 else if (string::is_whitespace(c)) state = S_END;
4980 else state = S_ERR;
4981 break;
4982 case S_INITIAL_E:
4983 if (c == '+' || c == '-') state = S_FIRST_E;
4984 else if (c == '0') state = S_ZERO_E;
4985 else if (c >= '1' && c <= '9') state = S_MORE_E;
4986 else state = S_ERR;
4987 break;
4988 case S_FIRST_E:
4989 if (c == '0') state = S_ZERO_E;
4990 else if (c >= '1' && c <= '9') state = S_MORE_E;
4991 else state = S_ERR;
4992 break;
4993 case S_ZERO_E:
4994 if (c >= '0' && c <= '9') {
4995 val->warning("Leading zero digit was detected and ignored in the "
4996 "exponent of the operand of operation `%s'", opname);
4997 state = S_MORE_E;
4998 } else if (string::is_whitespace(c)) state = S_END;
4999 else state = S_ERR;
5000 break;
5001 case S_MORE_E:
5002 if (c >= '0' && c <= '9') {}
5003 else if (string::is_whitespace(c)) state = S_END;
5004 else state = S_ERR;
5005 break;
5006 case S_END:
5007 if (!string::is_whitespace(c)) state = S_ERR;
5008 break;
5009 default:
5010 break;
5011 }
5012 if (state == S_ERR) {
5013 if (string::is_printable(c)) {
5014 val->error("%s operand of operation `%s' should be a string "
5015 "containing a valid float value, but invalid character `%c' "
5016 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
5017 } else {
5018 val->error("%s operand of operation `%s' should be a string "
5019 "containing a valid float value, but invalid character with "
5020 "character code %u was detected at index %lu", opnum, opname, c,
5021 (unsigned long) i);
5022 }
5023 set_valuetype(V_ERROR);
5024 break;
5025 }
5026 }
5027 switch (state) {
5028 case S_INITIAL:
5029 case S_INITIAL_WS:
5030 val->error("%s operand of operation `%s' should be a string containing a "
5031 "valid float value instead of an empty string", opnum, opname);
5032 set_valuetype(V_ERROR);
5033 break;
5034 case S_FIRST_M:
5035 val->error("%s operand of operation `%s' should be a string containing a "
5036 "valid float value, but only a sign character was detected", opnum,
5037 opname);
5038 set_valuetype(V_ERROR);
5039 break;
5040 case S_ZERO_M:
5041 case S_MORE_M:
5042 // HL67862: Missing decimal dot allowed for str2float
5043 break;
5044 case S_FIRST_F:
5045 // HL67862: Missing fraction part is allowed for str2float
5046 break;
5047 case S_INITIAL_E:
5048 case S_FIRST_E:
5049 val->error("%s operand of operation `%s' should be a string containing a "
5050 "valid float value, but the exponent is missing after the `E' sign",
5051 opnum, opname);
5052 set_valuetype(V_ERROR);
5053 break;
5054 case S_END:
5055 val->warning("Trailing whitespace was detected and ignored in the "
5056 "operand of operation `%s'", opname);
5057 break;
5058 default:
5059 break;
5060 }
5061 }
5062
5063 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
5064 const char *opname)
5065 {
5066 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5067 Value *v = val->get_value_refd_last();
5068 if (v->valuetype != V_USTR) return;
5069 const ustring& us = v->get_val_ustr();
5070 for (size_t i = 0; i < us.size(); i++) {
5071 const ustring::universal_char& uchar = us[i];
5072 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
5073 uchar.cell > 127) {
5074 val->error("%s operand of operation `%s' shall consist of characters "
5075 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5076 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5077 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
5078 uchar.row, uchar.cell, (unsigned long) i);
5079 set_valuetype(V_ERROR);
5080 return;
5081 }
5082 }
5083 }
5084
5085 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
5086 const char *opname)
5087 {
5088 if(valuetype==V_ERROR) return;
5089 if(u.expr.state==EXPR_CHECKING_ERR) return;
5090 if(val->is_unfoldable()) return;
5091 const string& bstr=val->get_val_str();
5092 // see also PredefFunc.cc::bit2int()
5093 size_t nof_bits = bstr.size();
5094 // skip the leading zeros
5095 size_t start_index = 0;
5096 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
5097 // check whether the remaining bits fit in Int
5098 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
5099 val->error("%s operand of operation `%s' is too large (maximum number"
5100 " of bits in integer is %lu)",
5101 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5102 set_valuetype(V_ERROR);
5103 }
5104 }
5105
5106 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
5107 const char *opname)
5108 {
5109 if(valuetype==V_ERROR) return;
5110 if(u.expr.state==EXPR_CHECKING_ERR) return;
5111 if(val->is_unfoldable()) return;
5112 const string& hstr=val->get_val_str();
5113 // see also PredefFunc.cc::hex2int()
5114 size_t nof_digits = hstr.size();
5115 // skip the leading zeros
5116 size_t start_index = 0;
5117 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
5118 // check whether the remaining hex digits fit in Int
5119 if (nof_digits - start_index > 2 * sizeof(Int) ||
5120 (nof_digits - start_index == 2 * sizeof(Int) &&
5121 char_to_hexdigit(hstr[start_index]) > 7)) {
5122 val->error("%s operand of operation `%s' is too large (maximum number"
5123 " of bits in integer is %lu)",
5124 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5125 set_valuetype(V_ERROR);
5126 }
5127 }
5128
5129 void Value::chk_expr_operands_int2binstr()
5130 {
5131 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5132 if (u.expr.v1->is_unfoldable()) return;
5133 if (u.expr.v2->is_unfoldable()) return;
5134 // It is already checked that i1 and i2 are non-negative.
5135 Error_Context cntxt(this, "In operation `%s'", get_opname());
5136 const int_val_t *i1 = u.expr.v1->get_val_Int();
5137 const int_val_t *i2 = u.expr.v2->get_val_Int();
5138 if (!i2->is_native()) {
5139 u.expr.v2->error("The length of the resulting string is too large for "
5140 "being represented in memory");
5141 set_valuetype(V_ERROR);
5142 return;
5143 }
5144 Int nof_bits = i2->get_val();
5145 if (u.expr.v1->is_unfoldable()) return;
5146 switch (u.expr.v_optype) {
5147 case OPTYPE_INT2BIT:
5148 break;
5149 case OPTYPE_INT2HEX:
5150 nof_bits *= 4;
5151 break;
5152 case OPTYPE_INT2OCT:
5153 nof_bits *= 8;
5154 break;
5155 default:
5156 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5157 }
5158 if (*i1 >> nof_bits > 0) { // Expensive?
5159 u.expr.v1->error("Value %s does not fit in length %s",
5160 i1->t_str().c_str(), i2->t_str().c_str());
5161 set_valuetype(V_ERROR);
5162 }
5163 }
5164
5165 void Value::chk_expr_operands_str_samelen()
5166 {
5167 if(valuetype==V_ERROR) return;
5168 if(u.expr.state==EXPR_CHECKING_ERR) return;
5169 Value *v1=u.expr.v1;
5170 if(v1->is_unfoldable()) return;
5171 Value *v2=u.expr.v2;
5172 if(v2->is_unfoldable()) return;
5173 Error_Context cntxt(this, "In operation `%s'", get_opname());
5174 size_t i1=v1->get_val_strlen();
5175 size_t i2=v2->get_val_strlen();
5176 if(i1!=i2) {
5177 error("The operands should have the same length");
5178 set_valuetype(V_ERROR);
5179 }
5180 }
5181
5182 void Value::chk_expr_operands_replace()
5183 {
5184 // The fourth operand doesn't need to be checked at all here.
5185 if(valuetype==V_ERROR) return;
5186 if(u.expr.state==EXPR_CHECKING_ERR) return;
5187 Value* v1 = u.expr.ti1->get_specific_value();
5188 if (!v1) return;
5189
5190 Error_Context cntxt(this, "In operation `%s'", get_opname());
5191 size_t list_len = 0;
5192 bool list_len_known = false;
5193 if (v1->valuetype == V_REFD) {
5194 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5195 if (subrefs && subrefs->refers_to_string_element()) {
5196 warning("Replacing a string element does not make any sense");
5197 list_len = 1;
5198 list_len_known = true;
5199 }
5200 }
5201 if (!v1->is_unfoldable()) {
5202 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5203 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5204 list_len_known = true;
5205 }
5206 if (!list_len_known) return;
5207 if (u.expr.v2->is_unfoldable()) {
5208 if (!u.expr.v3->is_unfoldable()) {
5209 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5210 if (*len_int_3 > static_cast<Int>(list_len)) {
5211 error("Third operand `len' (%s) is greater than the length of "
5212 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5213 (unsigned long)list_len);
5214 set_valuetype(V_ERROR);
5215 }
5216 }
5217 } else {
5218 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5219 if (u.expr.v3->is_unfoldable()) {
5220 if (*index_int_2 > static_cast<Int>(list_len)) {
5221 error("Second operand `index' (%s) is greater than the length of "
5222 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5223 (unsigned long)list_len);
5224 set_valuetype(V_ERROR);
5225 }
5226 } else {
5227 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5228 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5229 error("The sum of second operand `index' (%s) and third operand "
5230 "`len' (%s) is greater than the length of the first operand (%lu)",
5231 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5232 (unsigned long)list_len);
5233 set_valuetype(V_ERROR);
5234 }
5235 }
5236 }
5237 }
5238
5239 void Value::chk_expr_operands_substr()
5240 {
5241 if(valuetype==V_ERROR) return;
5242 if(u.expr.state==EXPR_CHECKING_ERR) return;
5243 Value* v1 = u.expr.ti1->get_specific_value();
5244 if (!v1) return;
5245
5246 Error_Context cntxt(this, "In operation `%s'", get_opname());
5247 size_t list_len = 0;
5248 bool list_len_known = false;
5249 if (v1->valuetype == V_REFD) {
5250 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5251 if (subrefs && subrefs->refers_to_string_element()) {
5252 warning("Taking the substring of a string element does not make any "
5253 "sense");
5254 list_len = 1;
5255 list_len_known = true;
5256 }
5257 }
5258 if (!list_len_known && !v1->is_unfoldable()) {
5259 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5260 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5261 list_len_known = true;
5262 }
5263 // Do nothing if the length of the first operand is unknown.
5264 if (!list_len_known) return;
5265 if (u.expr.v2->is_unfoldable()) {
5266 if (!u.expr.v3->is_unfoldable()) {
5267 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5268 // Only the third operand is known.
5269 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5270 error("Third operand `returncount' (%s) is greater than the "
5271 "length of the first operand (%lu)",
5272 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5273 set_valuetype(V_ERROR);
5274 }
5275 }
5276 } else {
5277 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5278 if (u.expr.v3->is_unfoldable()) {
5279 // Only the second operand is known.
5280 if (*index_int_2 > static_cast<Int>(list_len)) {
5281 error("Second operand `index' (%s) is greater than the length "
5282 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5283 (unsigned long)list_len);
5284 set_valuetype(V_ERROR);
5285 }
5286 } else {
5287 // Both second and third operands are known.
5288 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5289 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5290 error("The sum of second operand `index' (%s) and third operand "
5291 "`returncount' (%s) is greater than the length of the first operand "
5292 "(%lu)", (index_int_2->t_str()).c_str(),
5293 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5294 set_valuetype(V_ERROR);
5295 }
5296 }
5297 }
5298 }
5299
5300 void Value::chk_expr_operands_regexp()
5301 {
5302 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5303 Value* v1 = u.expr.ti1->get_specific_value();
5304 Value* v2 = u.expr.t2->get_specific_value();
5305 if (!v1 || !v2) return;
5306
5307 Error_Context cntxt(this, "In operation `regexp()'");
5308 Value* v1_last = v1->get_value_refd_last();
5309 if (v1_last->valuetype == V_CSTR) {
5310 // the input string is available at compile time
5311 const string& instr = v1_last->get_val_str();
5312 const char *input_str = instr.c_str();
5313 size_t instr_len = strlen(input_str);
5314 if (instr_len < instr.size()) {
5315 v1->warning("The first operand of `regexp()' contains a "
5316 "character with character code zero at index %s. The rest of the "
5317 "string will be ignored during matching",
5318 Int2string(instr_len).c_str());
5319 }
5320 }
5321
5322 size_t nof_groups = 0;
5323 Value *v2_last = v2->get_value_refd_last();
5324
5325 if (v2_last->valuetype == V_CSTR) {
5326 // the pattern is available at compile time
5327 const string& expression = v2_last->get_val_str();
5328 const char *pattern_str = expression.c_str();
5329 size_t pattern_len = strlen(pattern_str);
5330 if (pattern_len < expression.size()) {
5331 v2->warning("The second operand of `regexp()' contains a "
5332 "character with character code zero at index %s. The rest of the "
5333 "string will be ignored during matching",
5334 Int2string(pattern_len).c_str());
5335 }
5336 char *posix_str;
5337 {
5338 Error_Context cntxt2(v2, "In character string pattern");
5339 posix_str = TTCN_pattern_to_regexp(pattern_str);
5340 }
5341 if (posix_str != NULL) {
5342 regex_t posix_regexp;
5343 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5344 if (ret_val != 0) {
5345 char msg[512];
5346 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5347 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5348 "regcomp() failed: %s", msg);
5349 }
5350 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5351 else {
5352 v2->error("The character pattern in the second operand of "
5353 "`regexp()' does not contain any groups");
5354 set_valuetype(V_ERROR);
5355 }
5356 regfree(&posix_regexp);
5357 Free(posix_str);
5358 } else {
5359 // the pattern is faulty
5360 // the error has been reported by TTCN_pattern_to_regexp
5361 set_valuetype(V_ERROR);
5362 }
5363 }
5364 if (nof_groups > 0) {
5365 Value *v3 = u.expr.v3->get_value_refd_last();
5366 if (v3->valuetype == V_INT) {
5367 // the group number is available at compile time
5368 const int_val_t *groupno_int = v3->get_val_Int();
5369 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5370 u.expr.v3->error("The the third operand of `regexp()' is too "
5371 "large: The requested group index is %s, but the pattern "
5372 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5373 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5374 set_valuetype(V_ERROR);
5375 }
5376 }
5377 }
5378 }
5379
5380 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5381 Type::expected_value_t exp_val)
5382 {
5383 const char *opname = get_opname();
5384 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5385 Type *t_governor;
5386 const Location *loc;
5387 bool error_flag = false;
5388 switch (u.expr.v_optype) {
5389 case OPTYPE_ISCHOSEN_V:
5390 // u.expr.v1 is always a referenced value
5391 t_governor = u.expr.v1->get_expr_governor(exp_val);
5392 if (t_governor) {
5393 u.expr.v1->set_my_governor(t_governor);
5394 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5395 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5396 } else error_flag = true;
5397 loc = u.expr.v1;
5398 break;
5399 case OPTYPE_ISCHOSEN_T:
5400 // u.expr.t1 is always a referenced template
5401 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5402 exp_val = Type::EXPECTED_TEMPLATE;
5403 t_governor = u.expr.t1->get_expr_governor(exp_val);
5404 if (t_governor) {
5405 u.expr.t1->set_my_governor(t_governor);
5406 //
5407 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5408 //
5409 u.expr.t1->get_template_refd_last(refch);
5410 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5411 error_flag = true;
5412 } else error_flag = true;
5413 if (exp_val != Type::EXPECTED_TEMPLATE) {
5414 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5415 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5416 u.expr.t1->get_reference()->get_refd_assignment()
5417 ->get_description().c_str());
5418 error_flag = true;
5419 }
5420 loc = u.expr.t1;
5421 break;
5422 default:
5423 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5424 t_governor = 0;
5425 loc = 0;
5426 }
5427 if (t_governor) {
5428 t_governor = t_governor->get_type_refd_last();
5429 switch (t_governor->get_typetype()) {
5430 case Type::T_ERROR:
5431 error_flag = true;
5432 break;
5433 case Type::T_CHOICE_A:
5434 case Type::T_CHOICE_T:
5435 case Type::T_ANYTYPE:
5436 case Type::T_OPENTYPE:
5437 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5438 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5439 "%s does not have a field named `%s'" :
5440 "Union type `%s' does not have a field named `%s'",
5441 t_governor->get_typename().c_str(),
5442 u.expr.i2->get_dispname().c_str());
5443 error_flag = true;
5444 }
5445 break;
5446 default:
5447 loc->error("The operand of operation `%s' should be a union value "
5448 "or template instead of `%s'", opname,
5449 t_governor->get_typename().c_str());
5450 error_flag = true;
5451 break;
5452 }
5453 }
5454 if (error_flag) set_valuetype(V_ERROR);
5455 }
5456
5457 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5458 Type::expected_value_t exp_val) {
5459
5460 Error_Context cntxt(this, "In the parameter of %s",
5461 u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR ? "encvalue_unichar()" : "encvalue()");
5462 Type t_chk(Type::T_ERROR);
5463 Type* t_type;
5464
5465 Type::expected_value_t ti_exp_val = exp_val;
5466 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5467 ti_exp_val = Type::EXPECTED_TEMPLATE;
5468
5469 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5470 if (t_type) {
5471 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5472 if (valuetype!=V_ERROR)
5473 u.expr.ti1->get_Template()->chk_specific_value(false);
5474 t_type = t_type->get_type_refd_last();
5475 } else {
5476 error("Cannot determine type of value");
5477 goto error;
5478 }
5479
5480 // todo: fix this
5481 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5482 error("Expecting a value of a type with coding attributes in first"
5483 "parameter of encvalue() which belongs to a generic type '%s'",
5484 t_type->get_typename().c_str());
5485 goto error;
5486 }*/
5487
5488 if(!disable_attribute_validation()) {
5489 t_type->chk_coding(true);
5490 }
5491
5492 switch (t_type->get_typetype()) {
5493 case Type::T_UNDEF:
5494 case Type::T_ERROR:
5495 case Type::T_NULL:
5496 case Type::T_REFD:
5497 case Type::T_REFDSPEC:
5498 case Type::T_SELTYPE:
5499 case Type::T_VERDICT:
5500 case Type::T_PORT:
5501 case Type::T_COMPONENT:
5502 case Type::T_DEFAULT:
5503 case Type::T_SIGNATURE:
5504 case Type::T_FUNCTION:
5505 case Type::T_ALTSTEP:
5506 case Type::T_TESTCASE:
5507 error("Type of parameter of encvalue() cannot be '%s'",
5508 t_type->get_typename().c_str());
5509 goto error;
5510 default:
5511 break;
5512 }
5513 return;
5514 error:
5515 set_valuetype(V_ERROR);
5516 }
5517
5518 void Value::chk_expr_operands_decode(operationtype_t p_optype)
5519 {
5520 Error_Context cntxt(this, "In the parameters of %s",
5521 p_optype == OPTYPE_DECVALUE_UNICHAR ? "decvalue_unichar()" : "decvalue()");
5522 Ttcn::Ref_base* ref = u.expr.r1;
5523 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5524 Type* t_type = 0;
5525 Assignment* t_ass = ref->get_refd_assignment();
5526
5527 if (!t_ass) {
5528 error("Could not determine the assignment for first parameter");
5529 goto error;
5530 }
5531 switch (t_ass->get_asstype()) {
5532 case Assignment::A_PAR_VAL_IN:
5533 t_ass->use_as_lvalue(*this);
5534 break;
5535 case Assignment::A_CONST:
5536 case Assignment::A_EXT_CONST:
5537 case Assignment::A_MODULEPAR:
5538 case Assignment::A_MODULEPAR_TEMP:
5539 case Assignment::A_TEMPLATE:
5540 ref->error("Reference to '%s' cannot be used as the first operand of "
5541 "the 'decvalue' operation", t_ass->get_assname());
5542 goto error;
5543 break;
5544 case Assignment::A_VAR:
5545 case Assignment::A_PAR_VAL_OUT:
5546 case Assignment::A_PAR_VAL_INOUT:
5547 break;
5548 case Assignment::A_VAR_TEMPLATE:
5549 case Assignment::A_PAR_TEMPL_IN:
5550 case Assignment::A_PAR_TEMPL_OUT:
5551 case Assignment::A_PAR_TEMPL_INOUT: {
5552 Template* t = new Template(ref->clone());
5553 t->set_location(*ref);
5554 t->set_my_scope(get_my_scope());
5555 t->set_fullname(get_fullname()+".<operand>");
5556 Template* t_last = t->get_template_refd_last();
5557 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5558 && t_last != t) {
5559 ref->error("Specific value template was expected instead of '%s'.",
5560 t->get_template_refd_last()->get_templatetype_str());
5561 delete t;
5562 goto error;
5563 }
5564 delete t;
5565 break; }
5566 default:
5567 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5568 goto error;
5569 }
5570 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5571 Type::EXPECTED_DYNAMIC_VALUE);
5572 if (!t_type) {
5573 goto error;
5574 }
5575 switch(p_optype) {
5576 case OPTYPE_DECODE:
5577 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5578 error("First parameter has to be a bitstring");
5579 goto error;
5580 }
5581 break;
5582 case OPTYPE_DECVALUE_UNICHAR:
5583 if (t_type->get_type_refd_last()->get_typetype() != Type::T_USTR){
5584 error("First parameter has to be a universal charstring");
5585 goto error;
5586 }
5587 break;
5588 default:
5589 FATAL_ERROR("Value::chk_expr_decode_operands()");
5590 break;
5591 }
5592
5593 ref = u.expr.r2;
5594 t_subrefs = ref->get_subrefs();
5595 t_ass = ref->get_refd_assignment();
5596
5597 if (!t_ass) {
5598 error("Could not determine the assignment for second parameter");
5599 goto error;
5600 }
5601 // Extra check for HM59355.
5602 switch (t_ass->get_asstype()) {
5603 case Assignment::A_VAR:
5604 case Assignment::A_PAR_VAL_IN:
5605 case Assignment::A_PAR_VAL_OUT:
5606 case Assignment::A_PAR_VAL_INOUT:
5607 break;
5608 default:
5609 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5610 goto error;
5611 }
5612 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5613 Type::EXPECTED_DYNAMIC_VALUE);
5614 if (!t_type) {
5615 goto error;
5616 }
5617 t_type = t_type->get_type_refd_last();
5618 switch (t_type->get_typetype()) {
5619 case Type::T_UNDEF:
5620 case Type::T_ERROR:
5621 case Type::T_NULL:
5622 case Type::T_REFD:
5623 case Type::T_REFDSPEC:
5624 case Type::T_SELTYPE:
5625 case Type::T_VERDICT:
5626 case Type::T_PORT:
5627 case Type::T_COMPONENT:
5628 case Type::T_DEFAULT:
5629 case Type::T_SIGNATURE:
5630 case Type::T_FUNCTION:
5631 case Type::T_ALTSTEP:
5632 case Type::T_TESTCASE:
5633 error("Type of second parameter cannot be %s",
5634 t_type->get_typename().c_str());
5635 goto error;
5636 default:
5637 break;
5638 }
5639
5640 if(!disable_attribute_validation()) {
5641 t_type->chk_coding(false);
5642 }
5643
5644 return;
5645 error:
5646 set_valuetype(V_ERROR);
5647 }
5648
5649 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5650 {
5651 Ttcn::FieldOrArrayRefs *subrefs;
5652 Identifier *field_id = 0;
5653 Assignment *t_ass;
5654 Type *t_type;
5655 if (valuetype == V_ERROR) return;
5656 else if (valuetype != V_REFD) {
5657 error("Only a referenced value can be compared with `omit'");
5658 goto error;
5659 }
5660 subrefs = u.ref.ref->get_subrefs();
5661 if (subrefs) field_id = subrefs->remove_last_field();
5662 if (!field_id) {
5663 error("Only a reference pointing to an optional record or set field "
5664 "can be compared with `omit'");
5665 goto error;
5666 }
5667 t_ass = u.ref.ref->get_refd_assignment();
5668 if (!t_ass) goto error;
5669 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5670 if (!t_type) goto error;
5671 t_type = t_type->get_type_refd_last();
5672 switch (t_type->get_typetype()) {
5673 case Type::T_ERROR:
5674 goto error;
5675 case Type::T_SEQ_A:
5676 case Type::T_SEQ_T:
5677 case Type::T_SET_A:
5678 case Type::T_SET_T:
5679 break;
5680 default:
5681 error("Only a reference pointing to an optional field of a record"
5682 " or set type can be compared with `omit'");
5683 goto error;
5684 }
5685 if (!t_type->has_comp_withName(*field_id)) {
5686 error("Type `%s' does not have field named `%s'",
5687 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5688 goto error;
5689 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5690 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5691 "`omit'", field_id->get_dispname().c_str(),
5692 t_type->get_typename().c_str());
5693 goto error;
5694 }
5695 // putting the last field_id back to subrefs
5696 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5697 return;
5698 error:
5699 set_valuetype(V_ERROR);
5700 delete field_id;
5701 }
5702
5703 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5704 Type::expected_value_t exp_val)
5705 {
5706 if(valuetype==V_ERROR) return -1;
5707 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5708 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5709 exp_val=Type::EXPECTED_TEMPLATE;
5710
5711 Error_Context cntxt(this, "In the operand of"
5712 " operation `%s'", get_opname());
5713
5714 Int result = -1;
5715 Template* t_templ = u.expr.ti1->get_Template();
5716
5717 if (!t_templ) {
5718 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5719 }
5720
5721 t_templ = t_templ->get_template_refd_last(refch);
5722
5723 // Timer and port arrays are handled separately
5724 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5725 Value* val = t_templ->get_specific_value();
5726 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5727 val->set_lowerid_to_ref();
5728 }
5729 if (val && val->get_valuetype() == V_REFD) {
5730 Reference* ref = val->get_reference();
5731 Assignment* t_ass = ref->get_refd_assignment();
5732 Common::Assignment::asstype_t asstype =
5733 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5734 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5735 if (t_ass->get_Dimensions()) {
5736 // here we have a timer or port array
5737 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5738 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5739 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5740 Type::EXPECTED_DYNAMIC_VALUE);
5741 size_t refd_dim;
5742 if (t_subrefs) {
5743 refd_dim = t_subrefs->get_nof_refs();
5744 size_t nof_dims = t_dims->get_nof_dims();
5745 if (refd_dim >= nof_dims) {
5746 u.expr.ti1->error("Operation is not applicable to a %s",
5747 t_ass->get_assname());
5748 set_valuetype(V_ERROR);
5749 return -1;
5750 }
5751 } else refd_dim = 0;
5752 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5753 } else {
5754 u.expr.ti1->error("Operation is not applicable to single `%s'",
5755 t_ass->get_description().c_str());
5756 set_valuetype(V_ERROR);
5757 return -1;
5758 }
5759 }
5760 }
5761 }
5762
5763 Value* t_val = 0;
5764 Type* t_type = 0;
5765 Assignment* t_ass = 0;
5766 Reference* ref = 0;
5767 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5768 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5769 if (t_type) {
5770 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5771 t_type = t_type->get_type_refd_last();
5772 } else {
5773 error("Cannot determine type of value");
5774 goto error;
5775 }
5776
5777 if(valuetype==V_ERROR) return -1;
5778
5779 t_templ = t_templ->get_template_refd_last(refch);
5780 switch(t_templ->get_templatetype()) {
5781 case Template::TEMPLATE_ERROR:
5782 goto error;
5783 case Template::INDEXED_TEMPLATE_LIST:
5784 return -1;
5785 case Template::TEMPLATE_REFD:
5786 case Template::TEMPLATE_LIST:
5787 case Template::NAMED_TEMPLATE_LIST:
5788 // computed later
5789 break;
5790 case Template::SPECIFIC_VALUE:
5791 {
5792 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5793 if(t_val) {
5794 switch(t_val->get_valuetype()) {
5795 case V_SEQOF:
5796 case V_SETOF:
5797 case V_ARRAY:
5798 case V_ROID:
5799 case V_OID:
5800 case V_SEQ:
5801 case V_SET:
5802 break;
5803 case V_REFD: {
5804 ref = t_val->get_reference();
5805 t_ass = ref->get_refd_assignment();
5806 t_subrefs = ref->get_subrefs();
5807 break;
5808 }
5809 default:
5810 u.expr.ti1->error("Operation is not applicable to `%s'",
5811 t_val->create_stringRepr().c_str());
5812 goto error;
5813 }
5814 }
5815 break;
5816 }
5817 default:
5818 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5819 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5820 goto error;
5821 } // switch
5822
5823 if (t_ass) {
5824 switch(t_ass->get_asstype()) {
5825 case Assignment::A_ERROR:
5826 goto error;
5827 case Assignment::A_CONST:
5828 t_val = t_ass->get_Value();
5829 break;
5830 case Assignment::A_EXT_CONST:
5831 case Assignment::A_MODULEPAR:
5832 case Assignment::A_MODULEPAR_TEMP:
5833 if(exp_val==Type::EXPECTED_CONSTANT) {
5834 u.expr.ti1->error("Reference to an (evaluable) constant value was "
5835 "expected instead of %s", t_ass->get_description().c_str());
5836 goto error;
5837 }
5838 break;
5839 case Assignment::A_VAR:
5840 case Assignment::A_PAR_VAL_IN:
5841 case Assignment::A_PAR_VAL_OUT:
5842 case Assignment::A_PAR_VAL_INOUT:
5843 switch(exp_val) {
5844 case Type::EXPECTED_CONSTANT:
5845 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5846 t_ass->get_description().c_str());
5847 goto error;
5848 break;
5849 case Type::EXPECTED_STATIC_VALUE:
5850 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5851 t_ass->get_description().c_str());
5852 goto error;
5853 break;
5854 default:
5855 break;
5856 }
5857 break;
5858 case Assignment::A_TEMPLATE:
5859 t_templ = t_ass->get_Template();
5860 // no break
5861 case Assignment::A_VAR_TEMPLATE:
5862 case Assignment::A_PAR_TEMPL_IN:
5863 case Assignment::A_PAR_TEMPL_OUT:
5864 case Assignment::A_PAR_TEMPL_INOUT:
5865 if (exp_val!=Type::EXPECTED_TEMPLATE)
5866 u.expr.ti1->error("Reference to a value was expected instead of %s",
5867 t_ass->get_description().c_str());
5868 goto error;
5869 break;
5870 case Assignment::A_FUNCTION_RVAL:
5871 case Assignment::A_EXT_FUNCTION_RVAL:
5872 switch(exp_val) {
5873 case Type::EXPECTED_CONSTANT:
5874 u.expr.ti1->error("Reference to a constant value was expected instead of "
5875 "the return value of %s", t_ass->get_description().c_str());
5876 goto error;
5877 break;
5878 case Type::EXPECTED_STATIC_VALUE:
5879 u.expr.ti1->error("Reference to a static value was expected instead of "
5880 "the return value of %s", t_ass->get_description().c_str());
5881 goto error;
5882 break;
5883 default:
5884 break;
5885 }
5886 break;
5887 case Assignment::A_FUNCTION_RTEMP:
5888 case Assignment::A_EXT_FUNCTION_RTEMP:
5889 if(exp_val!=Type::EXPECTED_TEMPLATE)
5890 u.expr.ti1->error("Reference to a value was expected instead of a call"
5891 " of %s, which returns a template",
5892 t_ass->get_description().c_str());
5893 goto error;
5894 break;
5895 case Assignment::A_TIMER:
5896 case Assignment::A_PORT:
5897 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5898 // sizeof is applicable to timer and port arrays
5899 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5900 if (!t_dims) {
5901 u.expr.ti1->error("Operation is not applicable to single %s",
5902 t_ass->get_description().c_str());
5903 goto error;
5904 }
5905 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5906 Type::EXPECTED_DYNAMIC_VALUE);
5907 size_t refd_dim;
5908 if (t_subrefs) {
5909 refd_dim = t_subrefs->get_nof_refs();
5910 size_t nof_dims = t_dims->get_nof_dims();
5911 if (refd_dim > nof_dims) goto error;
5912 else if (refd_dim == nof_dims) {
5913 u.expr.ti1->error("Operation is not applicable to a %s",
5914 t_ass->get_assname());
5915 goto error;
5916 }
5917 } else refd_dim = 0;
5918 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5919 }
5920 // no break
5921 default:
5922 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5923 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5924 t_ass->get_description().c_str());
5925 goto error;
5926 } // end switch
5927
5928 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5929 if (!t_type) goto error;
5930 t_type = t_type->get_type_refd_last();
5931
5932 switch(t_type->get_typetype()) {
5933 case Type::T_ERROR:
5934 goto error;
5935 case Type::T_SEQOF:
5936 case Type::T_SETOF:
5937 // no break
5938 case Type::T_SEQ_T:
5939 case Type::T_SET_T:
5940 case Type::T_SEQ_A:
5941 case Type::T_SET_A:
5942 case Type::T_ARRAY:
5943 // ok
5944 break;
5945 case Type::T_OID:
5946 case Type::T_ROID:
5947 break;
5948 default:
5949 u.expr.ti1->error("Reference to value or template of type record, record of,"
5950 " set, set of, objid or array was expected");
5951 goto error;
5952 } // switch
5953 }
5954
5955 // check for index overflows in subrefs if possible
5956 if (t_val) {
5957 switch (t_val->get_valuetype()) {
5958 case V_SEQOF:
5959 case V_SETOF:
5960 case V_ARRAY:
5961 if (t_val->is_indexed()) {
5962 return -1;
5963 }
5964 break;
5965 default:
5966 break;
5967 }
5968 /* The reference points to a constant. */
5969 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5970 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5971 if (!t_val) goto error;
5972 t_val=t_val->get_value_refd_last(refch);
5973 } else { t_val = 0; }
5974 } else if (t_templ) {
5975 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5976 time. Don't try to evaluate it at compile time. */
5977 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5978 return -1;
5979 /* The reference points to a static template. */
5980 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5981 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
5982 if (!t_templ) goto error;
5983 t_templ = t_templ->get_template_refd_last(refch);
5984 } else { t_templ = 0; }
5985 }
5986
5987 if(u.expr.v_optype==OPTYPE_SIZEOF) {
5988 if(t_templ) {
5989 switch(t_templ->get_templatetype()) {
5990 case Template::TEMPLATE_ERROR:
5991 goto error;
5992 case Template::TEMPLATE_REFD:
5993 // not foldable
5994 t_templ=0;
5995 break;
5996 case Template::SPECIFIC_VALUE:
5997 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5998 t_templ=0;
5999 break;
6000 case Template::TEMPLATE_LIST:
6001 case Template::NAMED_TEMPLATE_LIST:
6002 break;
6003 default:
6004 u.expr.ti1->error("Operation is not applicable to %s `%s'",
6005 t_templ->get_templatetype_str(),
6006 t_templ->get_fullname().c_str());
6007 goto error;
6008 } // switch
6009 }
6010 if(t_val) {
6011 switch(t_val->get_valuetype()) {
6012 case V_SEQOF:
6013 case V_SETOF:
6014 case V_ARRAY:
6015 case V_SEQ:
6016 case V_SET:
6017 case V_OID:
6018 case V_ROID:
6019 // ok
6020 break;
6021 default:
6022 // error is already reported
6023 t_val=0;
6024 break;
6025 } // switch
6026 }
6027 }
6028
6029 /* evaluation */
6030
6031 if(t_type->get_typetype()==Type::T_ARRAY) {
6032 result = t_type->get_dimension()->get_size();
6033 }
6034 else if(t_templ) { // sizeof()
6035 switch(t_templ->get_templatetype()) {
6036 case Template::TEMPLATE_LIST:
6037 if(t_templ->temps_contains_anyornone_symbol()) {
6038 if(t_templ->is_length_restricted()) {
6039 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
6040 if (lr->get_is_range()) {
6041 Value *v_upper = lr->get_upper_value();
6042 if (v_upper) {
6043 if (v_upper->valuetype == V_INT) {
6044 Int nof_comps =
6045 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
6046 if (v_upper->u.val_Int->get_val() == nof_comps)
6047 result = nof_comps;
6048 else {
6049 u.expr.ti1->error("`sizeof' operation is not applicable for "
6050 "templates without exact size");
6051 goto error;
6052 }
6053 }
6054 } else {
6055 u.expr.ti1->error("`sizeof' operation is not applicable for "
6056 "templates containing `*' without upper boundary in the "
6057 "length restriction");
6058 goto error;
6059 }
6060 } else {
6061 Value *v_single = lr->get_single_value();
6062 if (v_single->valuetype == V_INT)
6063 result = v_single->u.val_Int->get_val();
6064 }
6065 }
6066 else { // not length restricted
6067 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
6068 " containing `*' without length restriction");
6069 goto error;
6070 }
6071 }
6072 else result=t_templ->get_nof_listitems();
6073 break;
6074 case Template::NAMED_TEMPLATE_LIST:
6075 result=0;
6076 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
6077 if(t_templ->get_namedtemp_byIndex(i)->get_template()
6078 ->get_templatetype()!=Template::OMIT_VALUE) result++;
6079 return result;
6080 default:
6081 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6082 } // switch
6083 }
6084 else if(t_val) {
6085 switch(t_val->get_valuetype()) {
6086 case V_SEQOF:
6087 case V_SETOF:
6088 case V_ARRAY:
6089
6090 case V_OID:
6091 case V_ROID:
6092 result=t_val->get_nof_comps();
6093 break;
6094 case V_SEQ:
6095 case V_SET:
6096 result=0;
6097 for(size_t i=0; i<t_val->get_nof_comps(); i++)
6098 if(t_val->get_se_comp_byIndex(i)->get_value()
6099 ->get_valuetype()!=V_OMIT) result++;
6100 break;
6101
6102 default:
6103 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6104 } // switch
6105 }
6106
6107 return result;
6108 error:
6109 set_valuetype(V_ERROR);
6110 return -1;
6111 }
6112
6113 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
6114 {
6115 Type *governor = ti->get_expr_governor(exp_val);
6116 if (!governor) {
6117 ti->get_Template()->set_lowerid_to_ref();
6118 governor = ti->get_expr_governor(exp_val);
6119 }
6120 if (!governor) {
6121 string str;
6122 ti->append_stringRepr( str);
6123 ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6124 "If type is known, use valueof(<type>: %s) as argument.",
6125 str.c_str(), get_opname(), str.c_str());
6126 set_valuetype(V_ERROR);
6127 }
6128 return governor;
6129 }
6130
6131 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
6132 {
6133 start:
6134 Type *governor = u.expr.v1->get_expr_governor(exp_val);
6135 if (!governor) governor = u.expr.t2->get_expr_governor(
6136 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
6137 Type::EXPECTED_TEMPLATE : exp_val);
6138 if (!governor) {
6139 Template *t_temp = u.expr.t2->get_Template();
6140 if (t_temp->is_undef_lowerid()) {
6141 // We convert the template to reference first even if the value is also
6142 // an undef lowerid. The user can prevent this by explicit type
6143 // specification.
6144 t_temp->set_lowerid_to_ref();
6145 goto start;
6146 } else if (u.expr.v1->is_undef_lowerid()) {
6147 u.expr.v1->set_lowerid_to_ref();
6148 goto start;
6149 }
6150 }
6151 if (!governor) {
6152 error("Cannot determine the type of arguments in `match()' operation");
6153 set_valuetype(V_ERROR);
6154 return;
6155 }
6156 u.expr.v1->set_my_governor(governor);
6157 {
6158 Error_Context cntxt(this, "In the first argument of `match()'"
6159 " operation");
6160 governor->chk_this_value_ref(u.expr.v1);
6161 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
6162 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6163 }
6164 {
6165 Error_Context cntxt(this, "In the second argument of `match()' "
6166 "operation");
6167 u.expr.t2->chk(governor);
6168 }
6169 }
6170
6171 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
6172 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
6173 {
6174 Ttcn::StatementBlock *my_sb;
6175 switch (exp_val) {
6176 case Type::EXPECTED_CONSTANT:
6177 error("An evaluable constant value was expected instead of operation "
6178 "`%s'", get_opname());
6179 goto error;
6180 case Type::EXPECTED_STATIC_VALUE:
6181 error("A static value was expected instead of operation `%s'",
6182 get_opname());
6183 goto error;
6184 default:
6185 break;
6186 } // switch
6187 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6188 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
6189 if (!my_sb) {
6190 error("Operation `%s' is allowed only within statements",
6191 get_opname());
6192 goto error;
6193 }
6194 if (!allow_controlpart && !my_sb->get_my_def()) {
6195 error("Operation `%s' is not allowed in the control part",
6196 get_opname());
6197 goto error;
6198 }
6199 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6200 error("Operation `%s' cannot be used in a definition that has "
6201 "`runs on' clause", get_opname());
6202 goto error;
6203 }
6204 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6205 error("Operation `%s' can be used only in a definition that has "
6206 "`runs on' clause", get_opname());
6207 goto error;
6208 }
6209 return;
6210 error:
6211 set_valuetype(V_ERROR);
6212 }
6213
6214 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6215 {
6216 if(valuetype==V_ERROR) return;
6217 if(u.expr.state==EXPR_CHECKING_ERR) return;
6218 if(v->is_unfoldable()) return;
6219 if(v->get_expr_returntype()!=Type::T_REAL) return;
6220 ttcn3float r = v->get_val_Real();
6221 if (isSpecialFloatValue(r)) {
6222 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6223 opnum, opname, Real2string(r).c_str());
6224 set_valuetype(V_ERROR);
6225 }
6226 }
6227
6228 void Value::chk_expr_operands(ReferenceChain *refch,
6229 Type::expected_value_t exp_val)
6230 {
6231 const char *first="First", *second="Second", *third="Third",
6232 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6233 Value *v1, *v2, *v3;
6234 Type::typetype_t tt1, tt2, tt3;
6235 Type t_chk(Type::T_ERROR);
6236
6237 const char *opname=get_opname();
6238
6239 // first classify the unchecked ischosen() operation
6240 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6241
6242 switch (u.expr.v_optype) {
6243 case OPTYPE_COMP_NULL:
6244 case OPTYPE_TESTCASENAME:
6245 case OPTYPE_PROF_RUNNING:
6246 break;
6247 case OPTYPE_COMP_MTC:
6248 case OPTYPE_COMP_SYSTEM:
6249 chk_expr_comptype_compat();
6250 break;
6251 case OPTYPE_RND: // -
6252 case OPTYPE_TMR_RUNNING_ANY:
6253 chk_expr_dynamic_part(exp_val, true);
6254 break;
6255 case OPTYPE_COMP_RUNNING_ANY:
6256 case OPTYPE_COMP_RUNNING_ALL:
6257 case OPTYPE_COMP_ALIVE_ANY:
6258 case OPTYPE_COMP_ALIVE_ALL:
6259 case OPTYPE_GETVERDICT:
6260 chk_expr_dynamic_part(exp_val, false);
6261 break;
6262 case OPTYPE_COMP_SELF:
6263 chk_expr_comptype_compat();
6264 chk_expr_dynamic_part(exp_val, false, true, false);
6265 break;
6266 case OPTYPE_UNARYPLUS: // v1
6267 case OPTYPE_UNARYMINUS:
6268 v1=u.expr.v1;
6269 {
6270 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6271 v1->set_lowerid_to_ref();
6272 tt1=v1->get_expr_returntype(exp_val);
6273 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6274 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6275 }
6276 break;
6277 case OPTYPE_NOT:
6278 v1=u.expr.v1;
6279 {
6280 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6281 v1->set_lowerid_to_ref();
6282 tt1=v1->get_expr_returntype(exp_val);
6283 chk_expr_operandtype_bool(tt1, the, opname, v1);
6284 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6285 }
6286 break;
6287 case OPTYPE_NOT4B:
6288 v1=u.expr.v1;
6289 {
6290 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6291 v1->set_lowerid_to_ref();
6292 tt1=v1->get_expr_returntype(exp_val);
6293 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6294 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6295 }
6296 break;
6297 case OPTYPE_BIT2HEX:
6298 case OPTYPE_BIT2OCT:
6299 case OPTYPE_BIT2STR:
6300 v1=u.expr.v1;
6301 {
6302 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6303 v1->set_lowerid_to_ref();
6304 tt1=v1->get_expr_returntype(exp_val);
6305 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6306 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6307 }
6308 break;
6309 case OPTYPE_BIT2INT:
6310 v1=u.expr.v1;
6311 {
6312 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6313 v1->set_lowerid_to_ref();
6314 tt1=v1->get_expr_returntype(exp_val);
6315 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6316 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6317 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6318 }
6319 break;
6320 case OPTYPE_CHAR2INT:
6321 v1=u.expr.v1;
6322 {
6323 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6324 v1->set_lowerid_to_ref();
6325 tt1=v1->get_expr_returntype(exp_val);
6326 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6327 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6328 chk_expr_val_len1(v1, the, opname);
6329 }
6330 break;
6331 case OPTYPE_CHAR2OCT:
6332 v1=u.expr.v1;
6333 {
6334 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6335 v1->set_lowerid_to_ref();
6336 tt1=v1->get_expr_returntype(exp_val);
6337 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6338 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6339 }
6340 break;
6341 case OPTYPE_STR2INT:
6342 v1=u.expr.v1;
6343 {
6344 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6345 v1->set_lowerid_to_ref();
6346 tt1=v1->get_expr_returntype(exp_val);
6347 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6348 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6349 chk_expr_val_str_int(v1, the, opname);
6350 }
6351 break;
6352 case OPTYPE_STR2FLOAT:
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_cstr(tt1, the, opname, v1);
6359 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6360 chk_expr_val_str_float(v1, the, opname);
6361 }
6362 break;
6363 case OPTYPE_STR2BIT:
6364 v1=u.expr.v1;
6365 {
6366 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6367 v1->set_lowerid_to_ref();
6368 tt1=v1->get_expr_returntype(exp_val);
6369 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6370 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6371 chk_expr_val_str_bindigits(v1, the, opname);
6372 }
6373 break;
6374 case OPTYPE_STR2HEX:
6375 v1=u.expr.v1;
6376 {
6377 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6378 v1->set_lowerid_to_ref();
6379 tt1=v1->get_expr_returntype(exp_val);
6380 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6381 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6382 chk_expr_val_str_hexdigits(v1, the, opname);
6383 }
6384 break;
6385 case OPTYPE_STR2OCT:
6386 v1=u.expr.v1;
6387 {
6388 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6389 v1->set_lowerid_to_ref();
6390 tt1=v1->get_expr_returntype(exp_val);
6391 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6392 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6393 chk_expr_val_str_len_even(v1, the, opname);
6394 chk_expr_val_str_hexdigits(v1, the, opname);
6395 }
6396 break;
6397 case OPTYPE_ENUM2INT:
6398 v1=u.expr.v1;
6399 {
6400 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6401 chk_expr_operandtype_enum(opname, v1, exp_val);
6402 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6403 }
6404 break;
6405 case OPTYPE_ENCODE:
6406 chk_expr_operand_encode(refch, exp_val);
6407 break;
6408 case OPTYPE_FLOAT2INT:
6409 case OPTYPE_FLOAT2STR:
6410 v1=u.expr.v1;
6411 {
6412 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6413 v1->set_lowerid_to_ref();
6414 tt1=v1->get_expr_returntype(exp_val);
6415 chk_expr_operandtype_float(tt1, the, opname, v1);
6416 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6417 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6418 chk_expr_operand_valid_float(v1, the, opname);
6419 }
6420 break;
6421 case OPTYPE_RNDWITHVAL:
6422 v1=u.expr.v1;
6423 {
6424 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6425 v1->set_lowerid_to_ref();
6426 tt1=v1->get_expr_returntype(exp_val);
6427 chk_expr_operandtype_float(tt1, the, opname, v1);
6428 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6429 chk_expr_operand_valid_float(v1, the, opname);
6430 }
6431 chk_expr_dynamic_part(exp_val, true);
6432 break;
6433 case OPTYPE_HEX2BIT:
6434 case OPTYPE_HEX2OCT:
6435 case OPTYPE_HEX2STR:
6436 v1=u.expr.v1;
6437 {
6438 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6439 v1->set_lowerid_to_ref();
6440 tt1=v1->get_expr_returntype(exp_val);
6441 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6442 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6443 }
6444 break;
6445 case OPTYPE_HEX2INT:
6446 v1=u.expr.v1;
6447 {
6448 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6449 v1->set_lowerid_to_ref();
6450 tt1=v1->get_expr_returntype(exp_val);
6451 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6452 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6453 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6454 }
6455 break;
6456 case OPTYPE_INT2CHAR:
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_int(tt1, the, opname, v1);
6463 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6464 chk_expr_val_int_pos7bit(v1, the, opname);
6465 }
6466 break;
6467 case OPTYPE_INT2UNICHAR:
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_int(tt1, the, opname, v1);
6474 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6475 chk_expr_val_int_pos31bit(v1, first, opname);
6476 }
6477 break;
6478 case OPTYPE_INT2FLOAT:
6479 case OPTYPE_INT2STR:
6480 v1=u.expr.v1;
6481 {
6482 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6483 v1->set_lowerid_to_ref();
6484 tt1=v1->get_expr_returntype(exp_val);
6485 chk_expr_operandtype_int(tt1, the, opname, v1);
6486 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6487 }
6488 break;
6489 case OPTYPE_OCT2BIT:
6490 case OPTYPE_OCT2HEX:
6491 case OPTYPE_OCT2STR:
6492 v1=u.expr.v1;
6493 {
6494 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6495 v1->set_lowerid_to_ref();
6496 tt1=v1->get_expr_returntype(exp_val);
6497 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6498 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6499 }
6500 break;
6501 case OPTYPE_OCT2INT:
6502 v1=u.expr.v1;
6503 {
6504 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6505 v1->set_lowerid_to_ref();
6506 tt1=v1->get_expr_returntype(exp_val);
6507 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6508 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6509 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6510 // now.
6511 }
6512 break;
6513 case OPTYPE_OCT2CHAR:
6514 v1=u.expr.v1;
6515 {
6516 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6517 v1->set_lowerid_to_ref();
6518 tt1=v1->get_expr_returntype(exp_val);
6519 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6520 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6521 chk_expr_val_str_7bitoctets(v1, the, opname);
6522 }
6523 break;
6524 case OPTYPE_REMOVE_BOM:
6525 v1=u.expr.v1;
6526 {
6527 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6528 v1->set_lowerid_to_ref();
6529 tt1=v1->get_expr_returntype(exp_val);
6530 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6531 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6532 }
6533 break;
6534 case OPTYPE_GET_STRINGENCODING:
6535 v1=u.expr.v1;
6536 {
6537 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6538 v1->set_lowerid_to_ref();
6539 tt1=v1->get_expr_returntype(exp_val);
6540 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6541 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6542 }
6543 break;
6544 case OPTYPE_ENCODE_BASE64:
6545 v1=u.expr.v1;
6546 {
6547 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6548 v1->set_lowerid_to_ref();
6549 tt1=v1->get_expr_returntype(exp_val);
6550 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6551 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6552 }
6553 v2=u.expr.v2 ? u.expr.v2 : 0;
6554 if (v2)
6555 {
6556 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6557 v2->set_lowerid_to_ref();
6558 tt2=v2->get_expr_returntype(exp_val);
6559 chk_expr_operandtype_bool(tt2, second, opname, v2);
6560 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6561 }
6562 break;
6563 case OPTYPE_DECODE_BASE64:
6564 v1=u.expr.v1;
6565 {
6566 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6567 v1->set_lowerid_to_ref();
6568 tt1=v1->get_expr_returntype(exp_val);
6569 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6570 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6571 }
6572 break;
6573 case OPTYPE_UNICHAR2INT:
6574 v1=u.expr.v1;
6575 {
6576 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6577 v1->set_lowerid_to_ref();
6578 tt1=v1->get_expr_returntype(exp_val);
6579 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6580 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6581 chk_expr_val_len1(v1, the, opname);
6582 }
6583 break;
6584 case OPTYPE_UNICHAR2CHAR:
6585 v1=u.expr.v1;
6586 {
6587 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6588 v1->set_lowerid_to_ref();
6589 tt1=v1->get_expr_returntype(exp_val);
6590 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6591 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6592 chk_expr_val_ustr_7bitchars(v1, the, opname);
6593 }
6594 break;
6595 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6596 v1=u.expr.v1;
6597 {
6598 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6599 v1->set_lowerid_to_ref();
6600 tt1=v1->get_expr_returntype(exp_val);
6601 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6602 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6603 }
6604 v2=u.expr.v2 ? u.expr.v2 : 0;
6605 if (v2)
6606 {
6607 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6608 v2->set_lowerid_to_ref();
6609 tt2=v2->get_expr_returntype(exp_val);
6610 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6611 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6612 }
6613 break;
6614 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6615 v1=u.expr.v1;
6616 {
6617 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6618 v1->set_lowerid_to_ref();
6619 tt1=v1->get_expr_returntype(exp_val);
6620 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6621 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6622 }
6623 v2=u.expr.v2 ? u.expr.v2 : 0;
6624 if (v2)
6625 {
6626 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6627 v2->set_lowerid_to_ref();
6628 tt2=v2->get_expr_returntype(exp_val);
6629 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6630 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6631 }
6632 break;
6633 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
6634 chk_expr_operand_encode(refch, exp_val);
6635 v2=u.expr.v2 ? u.expr.v2 : 0;
6636 if (v2)
6637 {
6638 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6639 v2->set_lowerid_to_ref();
6640 tt2=v2->get_expr_returntype(exp_val);
6641 chk_expr_operandtype_charstr(tt2, second, opname, v2);
6642 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6643 }
6644 break;
6645 case OPTYPE_DECVALUE_UNICHAR:
6646 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR);
6647 v3=u.expr.v3 ? u.expr.v3 : 0;
6648 if (v3)
6649 {
6650 Error_Context cntxt(this, "In the thrid operand of operation `%s'", opname);
6651 v3->set_lowerid_to_ref();
6652 tt3=v3->get_expr_returntype(exp_val);
6653 chk_expr_operandtype_charstr(tt3, third, opname, v3);
6654 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6655 }
6656 break;
6657 case OPTYPE_ADD: // v1 v2
6658 case OPTYPE_SUBTRACT:
6659 case OPTYPE_MULTIPLY:
6660 case OPTYPE_DIVIDE:
6661 v1=u.expr.v1;
6662 {
6663 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6664 v1->set_lowerid_to_ref();
6665 tt1=v1->get_expr_returntype(exp_val);
6666 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6667 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6668 chk_expr_operand_valid_float(v1, first, opname);
6669 }
6670 v2=u.expr.v2;
6671 {
6672 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6673 v2->set_lowerid_to_ref();
6674 tt2=v2->get_expr_returntype(exp_val);
6675 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6676 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6677 chk_expr_operand_valid_float(v2, second, opname);
6678 if(u.expr.v_optype==OPTYPE_DIVIDE)
6679 chk_expr_val_int_float_not0(v2, second, opname);
6680 }
6681 chk_expr_operandtypes_same(tt1, tt2, opname);
6682 break;
6683 case OPTYPE_MOD:
6684 case OPTYPE_REM:
6685 v1=u.expr.v1;
6686 {
6687 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6688 v1->set_lowerid_to_ref();
6689 tt1=v1->get_expr_returntype(exp_val);
6690 chk_expr_operandtype_int(tt1, left, opname, v1);
6691 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6692 }
6693 v2=u.expr.v2;
6694 {
6695 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6696 v2->set_lowerid_to_ref();
6697 tt2=v2->get_expr_returntype(exp_val);
6698 chk_expr_operandtype_int(tt2, right, opname, v2);
6699 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6700 chk_expr_val_int_float_not0(v2, right, opname);
6701 }
6702 break;
6703 case OPTYPE_CONCAT: {
6704 v1=u.expr.v1;
6705 v2=u.expr.v2;
6706 v1->set_lowerid_to_ref();
6707 v2->set_lowerid_to_ref();
6708 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6709 {
6710 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6711 tt1=v1->get_expr_returntype(exp_val);
6712 chk_expr_operandtype_str(tt1, left, opname, v1);
6713 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6714 }
6715 {
6716 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6717 tt2=v2->get_expr_returntype(exp_val);
6718 chk_expr_operandtype_str(tt2, right, opname, v2);
6719 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6720 }
6721 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6722 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6723 chk_expr_operandtypes_same(tt1, tt2, opname);
6724 } else { // other list types
6725 Type* v1_gov = v1->get_expr_governor(exp_val);
6726 Type* v2_gov = v2->get_expr_governor(exp_val);
6727 if (!v1_gov) {
6728 error("Cannot determine the type of the left operand of `%s' operation", opname);
6729 set_valuetype(V_ERROR);
6730 return;
6731 } else {
6732 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6733 v1_gov->chk_this_value_ref(v1);
6734 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6735 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6736 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6737 }
6738 if (!v2_gov) {
6739 if (!v1_gov) {
6740 error("Cannot determine the type of the right operand of `%s' operation", opname);
6741 set_valuetype(V_ERROR);
6742 return;
6743 }
6744 // for recof/setof literals set the type from v1
6745 v2_gov = v1_gov;
6746 v2->set_my_governor(v1_gov);
6747 }
6748 {
6749 Error_Context cntxt(this, "In the right operand of operation `%s'",
6750 opname);
6751 v2_gov->chk_this_value_ref(v2);
6752 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6753 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6754 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6755 if (valuetype == V_ERROR) return;
6756 // 7.1.2 says that we shouldn't allow type compatibility.
6757 if (!v1_gov->is_compatible(v2_gov, NULL)
6758 && !v2_gov->is_compatible(v1_gov, NULL)) {
6759 error("The operands of operation `%s' should be of compatible "
6760 "types", get_opname());
6761 }
6762 }
6763 }
6764 break; }
6765 case OPTYPE_EQ:
6766 case OPTYPE_NE:
6767 v1 = u.expr.v1;
6768 v2 = u.expr.v2;
6769 chk_expr_operandtypes_compat(exp_val, v1, v2);
6770 {
6771 Error_Context cntxt(this, "In the left operand of operation `%s'",
6772 opname);
6773 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6774 }
6775 {
6776 Error_Context cntxt(this, "In the right operand of operation `%s'",
6777 opname);
6778 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6779 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6780 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6781 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6782 * "a == not b" is not allowed. (HL69107)
6783 * The various *Expressions implement operator precedence in the std.
6784 * Titan's parser has only one Expression and relies on Bison
6785 * for operator precedence. The check below brings Titan in line
6786 * with the standard by explicitly making "a == not b" an error */
6787 if (v2->get_valuetype() == V_EXPR
6788 && v2->u.expr.v_optype == OPTYPE_NOT) {
6789 error("The operation `%s' is not allowed to be "
6790 "the second operand of operation `%s'", v2->get_opname(), opname);
6791 set_valuetype(V_ERROR);
6792 }
6793 }
6794 break;
6795 case OPTYPE_LT:
6796 case OPTYPE_GT:
6797 case OPTYPE_GE:
6798 case OPTYPE_LE:
6799 v1=u.expr.v1;
6800 v2=u.expr.v2;
6801 chk_expr_operandtypes_compat(exp_val, v1, v2);
6802 {
6803 Error_Context cntxt(this, "In the left operand of operation `%s'",
6804 opname);
6805 tt1=v1->get_expr_returntype(exp_val);
6806 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6807 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6808 }
6809 {
6810 Error_Context cntxt(this, "In the right operand of operation `%s'",
6811 opname);
6812 tt2=v2->get_expr_returntype(exp_val);
6813 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6814 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6815 }
6816 break;
6817 case OPTYPE_AND:
6818 case OPTYPE_OR:
6819 case OPTYPE_XOR:
6820 v1=u.expr.v1;
6821 {
6822 Error_Context cntxt(this, "In the left operand of operation `%s'",
6823 opname);
6824 v1->set_lowerid_to_ref();
6825 tt1=v1->get_expr_returntype(exp_val);
6826 chk_expr_operandtype_bool(tt1, left, opname, v1);
6827 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6828 }
6829 v2=u.expr.v2;
6830 {
6831 Error_Context cntxt(this, "In the right operand of operation `%s'",
6832 opname);
6833 v2->set_lowerid_to_ref();
6834 tt2=v2->get_expr_returntype(exp_val);
6835 chk_expr_operandtype_bool(tt2, right, opname, v2);
6836 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6837 }
6838 break;
6839 case OPTYPE_AND4B:
6840 case OPTYPE_OR4B:
6841 case OPTYPE_XOR4B:
6842 v1=u.expr.v1;
6843 {
6844 Error_Context cntxt(this, "In the left operand of operation `%s'",
6845 opname);
6846 v1->set_lowerid_to_ref();
6847 tt1=v1->get_expr_returntype(exp_val);
6848 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6849 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6850 }
6851 v2=u.expr.v2;
6852 {
6853 Error_Context cntxt(this, "In the right operand of operation `%s'",
6854 opname);
6855 v2->set_lowerid_to_ref();
6856 tt2=v2->get_expr_returntype(exp_val);
6857 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6858 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6859 }
6860 chk_expr_operandtypes_same(tt1, tt2, opname);
6861 chk_expr_operands_str_samelen();
6862 break;
6863 case OPTYPE_SHL:
6864 case OPTYPE_SHR:
6865 v1=u.expr.v1;
6866 {
6867 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6868 v1->set_lowerid_to_ref();
6869 tt1=v1->get_expr_returntype(exp_val);
6870 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6871 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6872 }
6873 v2=u.expr.v2;
6874 {
6875 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6876 v2->set_lowerid_to_ref();
6877 tt2=v2->get_expr_returntype(exp_val);
6878 chk_expr_operandtype_int(tt2, right, opname, v2);
6879 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6880 chk_expr_val_large_int(v2, right, opname);
6881 }
6882 break;
6883 case OPTYPE_ROTL:
6884 case OPTYPE_ROTR:
6885 v1=u.expr.v1;
6886 v1->set_lowerid_to_ref();
6887 if (v1->is_string_type(exp_val)) {
6888 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6889 tt1=v1->get_expr_returntype(exp_val);
6890 chk_expr_operandtype_str(tt1, left, opname, v1);
6891 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6892 } else { // other list types
6893 Type* v1_gov = v1->get_expr_governor(exp_val);
6894 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6895 error("Cannot determine the type of the left operand of `%s' operation", opname);
6896 } else {
6897 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6898 v1_gov->chk_this_value_ref(v1);
6899 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6900 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6901 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6902 }
6903 }
6904 v2=u.expr.v2;
6905 {
6906 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6907 v2->set_lowerid_to_ref();
6908 tt2=v2->get_expr_returntype(exp_val);
6909 chk_expr_operandtype_int(tt2, right, opname, v2);
6910 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6911 chk_expr_val_large_int(v2, right, opname);
6912 }
6913 break;
6914 case OPTYPE_INT2BIT:
6915 case OPTYPE_INT2HEX:
6916 case OPTYPE_INT2OCT:
6917 v1=u.expr.v1;
6918 {
6919 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6920 v1->set_lowerid_to_ref();
6921 tt1=v1->get_expr_returntype(exp_val);
6922 chk_expr_operandtype_int(tt1, first, opname, v1);
6923 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6924 chk_expr_val_int_pos0(v1, first, opname);
6925 }
6926 v2=u.expr.v2;
6927 {
6928 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6929 v2->set_lowerid_to_ref();
6930 tt2=v2->get_expr_returntype(exp_val);
6931 chk_expr_operandtype_int(tt2, second, opname, v2);
6932 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6933 chk_expr_val_int_pos0(v2, second, opname);
6934 }
6935 chk_expr_operands_int2binstr();
6936 break;
6937 case OPTYPE_DECODE:
6938 chk_expr_operands_decode(OPTYPE_DECODE);
6939 break;
6940 case OPTYPE_SUBSTR:
6941 {
6942 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6943 Type::expected_value_t ti_exp_val = exp_val;
6944 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6945 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6946 if (!governor) return;
6947 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6948 if (valuetype!=V_ERROR)
6949 u.expr.ti1->get_Template()->chk_specific_value(false);
6950 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6951 }
6952 v2=u.expr.v2;
6953 {
6954 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6955 v2->set_lowerid_to_ref();
6956 tt2=v2->get_expr_returntype(exp_val);
6957 chk_expr_operandtype_int(tt2, second, opname, v2);
6958 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6959 chk_expr_val_int_pos0(v2, second, opname);
6960 }
6961 v3=u.expr.v3;
6962 {
6963 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6964 v3->set_lowerid_to_ref();
6965 tt3=v3->get_expr_returntype(exp_val);
6966 chk_expr_operandtype_int(tt3, third, opname, v3);
6967 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6968 chk_expr_val_int_pos0(v3, third, opname);
6969 }
6970 chk_expr_operands_substr();
6971 break;
6972 case OPTYPE_REGEXP: {
6973 Type::expected_value_t ti_exp_val = exp_val;
6974 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
6975 {
6976 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6977 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6978 if (!governor) return;
6979 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6980 if (valuetype!=V_ERROR) {
6981 u.expr.ti1->get_Template()->chk_specific_value(false);
6982 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6983 get_typetype_ttcn3(), first, opname, u.expr.ti1);
6984 }
6985 }
6986 {
6987 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6988 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
6989 if (!governor) return;
6990 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
6991 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
6992 get_typetype_ttcn3(), second, opname, u.expr.t2);
6993 }
6994 v3=u.expr.v3;
6995 {
6996 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6997 v3->set_lowerid_to_ref();
6998 tt3=v3->get_expr_returntype(exp_val);
6999 chk_expr_operandtype_int(tt3, third, opname, v3);
7000 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7001 chk_expr_val_int_pos0(v3, third, opname);
7002 }
7003 chk_expr_operands_regexp();
7004 } break;
7005 case OPTYPE_ISCHOSEN:
7006 // do nothing: the operand is erroneous
7007 // the error was already reported in chk_expr_ref_ischosen()
7008 break;
7009 case OPTYPE_ISCHOSEN_V: // v1 i2
7010 case OPTYPE_ISCHOSEN_T: // t1 i2
7011 chk_expr_operands_ischosen(refch, exp_val);
7012 break;
7013 case OPTYPE_VALUEOF: { // ti1
7014 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7015 exp_val = Type::EXPECTED_TEMPLATE;
7016 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7017 Type *governor = my_governor;
7018 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7019 if (!governor) return;
7020 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7021 if (valuetype == V_ERROR) return;
7022 u.expr.ti1->get_Template()->chk_specific_value(false);
7023 break; }
7024 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
7025 case OPTYPE_ISBOUND: {
7026 Template *templ = u.expr.ti1->get_Template();
7027 switch (templ->get_templatetype()) {
7028 case Template::TEMPLATE_REFD:
7029 templ->get_reference()->setUsedInIsbound();
7030 break;
7031 case Template::SPECIFIC_VALUE: {
7032 Value *value = templ->get_specific_value();
7033 if (Value::V_REFD == value->get_valuetype()) {
7034 value->get_reference()->setUsedInIsbound();
7035 }
7036 break; }
7037 default:
7038 break;
7039 }
7040 }
7041 // no break
7042 case OPTYPE_ISVALUE: {// ti1
7043 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
7044 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7045 exp_val = Type::EXPECTED_TEMPLATE;
7046 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7047 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7048 if (!governor) return;
7049 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
7050 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7051 break; }
7052 case OPTYPE_SIZEOF: // ti1
7053 /* this checking is too complex, do the checking during eval... */
7054 break;
7055 case OPTYPE_LENGTHOF: { // ti1
7056 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7057 exp_val = Type::EXPECTED_TEMPLATE;
7058 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7059 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7060 if (!governor) return;
7061 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
7062 if (valuetype == V_ERROR) return;
7063 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7064 break; }
7065 case OPTYPE_MATCH: // v1 t2
7066 chk_expr_operands_match(exp_val);
7067 break;
7068 case OPTYPE_UNDEF_RUNNING: // r1
7069 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
7070 break;
7071 case OPTYPE_COMP_ALIVE:
7072 case OPTYPE_COMP_RUNNING: //v1
7073 chk_expr_operand_compref(u.expr.v1, the, opname);
7074 chk_expr_dynamic_part(exp_val, false);
7075 break;
7076 case OPTYPE_TMR_READ: // r1
7077 case OPTYPE_TMR_RUNNING: // r1
7078 chk_expr_operand_tmrref(u.expr.r1, the, opname);
7079 chk_expr_dynamic_part(exp_val, true);
7080 break;
7081 case OPTYPE_EXECUTE: // r1 [v2] // testcase
7082 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
7083 chk_expr_dynamic_part(exp_val, true, false, false);
7084 break;
7085 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7086 chk_expr_operand_comptyperef_create();
7087 v2=u.expr.v2;
7088 if(v2) {
7089 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7090 v2->set_lowerid_to_ref();
7091 tt2=v2->get_expr_returntype(exp_val);
7092 chk_expr_operandtype_cstr(tt2, first, opname, v2);
7093 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7094 }
7095 v3=u.expr.v3;
7096 if(v3) {
7097 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
7098 v3->set_lowerid_to_ref();
7099 tt3=v3->get_expr_returntype(exp_val);
7100 chk_expr_operandtype_cstr(tt3, second, opname, v3);
7101 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7102 }
7103 chk_expr_dynamic_part(exp_val, false);
7104 break;
7105 case OPTYPE_ACTIVATE: // r1 // altstep
7106 chk_expr_operand_activate(u.expr.r1, the, opname);
7107 chk_expr_dynamic_part(exp_val, true);
7108 break;
7109 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
7110 case OPTYPE_CHECKSTATE_ALL:
7111 chk_expr_dynamic_part(exp_val, false);
7112 v2=u.expr.v2;
7113 if(v2) {
7114 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7115 v2->set_lowerid_to_ref();
7116 tt2=v2->get_expr_returntype(exp_val);
7117 chk_expr_operandtype_cstr(tt2, first, opname, v2);
7118 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7119 }
7120 break;
7121 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
7122 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7123 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
7124 opname);
7125 delete u.expr.t_list2;
7126 u.expr.ap_list2 = parlist;
7127 chk_expr_dynamic_part(exp_val, true);
7128 break; }
7129 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
7130 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7131 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
7132 u.expr.v3, the, opname);
7133 delete u.expr.t_list2;
7134 u.expr.ap_list2 = parlist;
7135 chk_expr_dynamic_part(exp_val, true);
7136 break; }
7137 case OPTYPE_DECOMP:
7138 error("Built-in function `%s' is not yet supported", opname);
7139 set_valuetype(V_ERROR);
7140 break;
7141 case OPTYPE_REPLACE: {
7142 Type::expected_value_t ti_exp_val = exp_val;
7143 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7144 ti_exp_val = Type::EXPECTED_TEMPLATE;
7145 {
7146 Error_Context cntxt(this, "In the first operand of operation `%s'",
7147 opname);
7148 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7149 if (!governor) return;
7150 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7151 if (valuetype != V_ERROR)
7152 u.expr.ti1->get_Template()->chk_specific_value(false);
7153 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
7154 }
7155 v2 = u.expr.v2;
7156 {
7157 Error_Context cntxt(this, "In the second operand of operation `%s'",
7158 opname);
7159 v2->set_lowerid_to_ref();
7160 tt2 = v2->get_expr_returntype(exp_val);
7161 chk_expr_operandtype_int(tt2, second, opname, v2);
7162 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7163 chk_expr_val_int_pos0(v2, second, opname);
7164 }
7165 v3 = u.expr.v3;
7166 {
7167 Error_Context cntxt(this, "In the third operand of operation `%s'",
7168 opname);
7169 v3->set_lowerid_to_ref();
7170 tt3 = v3->get_expr_returntype(exp_val);
7171 chk_expr_operandtype_int(tt3, third, opname, v3);
7172 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7173 chk_expr_val_int_pos0(v3, third, opname);
7174 }
7175 {
7176 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
7177 opname);
7178 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
7179 if (!governor) return;
7180 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
7181 if (valuetype != V_ERROR)
7182 u.expr.ti4->get_Template()->chk_specific_value(false);
7183 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
7184 }
7185 chk_expr_operands_replace();
7186 break; }
7187 case OPTYPE_LOG2STR:
7188 case OPTYPE_ANY2UNISTR: {
7189 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7190 u.expr.logargs->chk();
7191 if (!semantic_check_only) u.expr.logargs->join_strings();
7192 break; }
7193 case OPTYPE_TTCN2STRING: {
7194 Error_Context cntxt(this, "In the parameter of ttcn2string()");
7195 Type::expected_value_t ti_exp_val = exp_val;
7196 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
7197 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7198 if (!governor) return;
7199 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7200 } break;
7201 default:
7202 FATAL_ERROR("chk_expr_operands()");
7203 } // switch optype
7204 }
7205
7206 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7207 // the result of evaluating the expression. E.g. V_BOOL for
7208 // OPTYPE_ISCHOSEN.
7209 void Value::evaluate_value(ReferenceChain *refch,
7210 Type::expected_value_t exp_val)
7211 {
7212 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
7213 if(u.expr.state!=EXPR_NOT_CHECKED) return;
7214
7215 u.expr.state=EXPR_CHECKING;
7216
7217 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
7218 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
7219 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
7220
7221 if(valuetype==V_ERROR) return;
7222 if(u.expr.state==EXPR_CHECKING_ERR) {
7223 u.expr.state=EXPR_CHECKED;
7224 set_valuetype(V_ERROR);
7225 return;
7226 }
7227
7228 u.expr.state=EXPR_CHECKED;
7229
7230 Value *v1, *v2, *v3, *v4;
7231 switch(u.expr.v_optype) {
7232 case OPTYPE_RND: // -
7233 case OPTYPE_COMP_NULL: // the only foldable in this group
7234 case OPTYPE_COMP_MTC:
7235 case OPTYPE_COMP_SYSTEM:
7236 case OPTYPE_COMP_SELF:
7237 case OPTYPE_COMP_RUNNING_ANY:
7238 case OPTYPE_COMP_RUNNING_ALL:
7239 case OPTYPE_COMP_ALIVE_ANY:
7240 case OPTYPE_COMP_ALIVE_ALL:
7241 case OPTYPE_TMR_RUNNING_ANY:
7242 case OPTYPE_GETVERDICT:
7243 case OPTYPE_PROF_RUNNING:
7244 case OPTYPE_RNDWITHVAL: // v1
7245 case OPTYPE_COMP_RUNNING: // v1
7246 case OPTYPE_COMP_ALIVE:
7247 case OPTYPE_TMR_READ:
7248 case OPTYPE_TMR_RUNNING:
7249 case OPTYPE_ACTIVATE:
7250 case OPTYPE_ACTIVATE_REFD:
7251 case OPTYPE_EXECUTE: // r1 [v2]
7252 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7253 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7254 case OPTYPE_MATCH: // v1 t2
7255 case OPTYPE_ISCHOSEN_T:
7256 case OPTYPE_LOG2STR:
7257 case OPTYPE_ANY2UNISTR:
7258 case OPTYPE_ENCODE:
7259 case OPTYPE_DECODE:
7260 case OPTYPE_ISBOUND:
7261 case OPTYPE_ISPRESENT:
7262 case OPTYPE_TTCN2STRING:
7263 case OPTYPE_UNICHAR2OCT:
7264 case OPTYPE_OCT2UNICHAR:
7265 case OPTYPE_ENCODE_BASE64:
7266 case OPTYPE_DECODE_BASE64:
7267 case OPTYPE_ENCVALUE_UNICHAR:
7268 case OPTYPE_DECVALUE_UNICHAR:
7269 case OPTYPE_CHECKSTATE_ANY:
7270 case OPTYPE_CHECKSTATE_ALL:
7271 break;
7272 case OPTYPE_TESTCASENAME: { // -
7273 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7274 Ttcn::StatementBlock *my_sb =
7275 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7276 if (!my_sb) break;
7277 Ttcn::Definition *my_def = my_sb->get_my_def();
7278 if (!my_def) { // In control part.
7279 set_val_str(new string(""));
7280 valuetype = V_CSTR;
7281 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7282 set_val_str(new string(my_def->get_id().get_dispname()));
7283 valuetype = V_CSTR;
7284 }
7285 break; }
7286 case OPTYPE_UNARYPLUS: // v1
7287 v1=u.expr.v1;
7288 u.expr.v1=0;
7289 copy_and_destroy(v1);
7290 break;
7291 case OPTYPE_UNARYMINUS:
7292 if (is_unfoldable()) break;
7293 v1 = u.expr.v1->get_value_refd_last();
7294 switch (v1->valuetype) {
7295 case V_INT: {
7296 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7297 if (!i) FATAL_ERROR("Value::evaluate_value()");
7298 clean_up();
7299 valuetype = V_INT;
7300 u.val_Int = i;
7301 break; }
7302 case V_REAL: {
7303 ttcn3float r = v1->get_val_Real();
7304 clean_up();
7305 valuetype = V_REAL;
7306 u.val_Real = -r;
7307 break; }
7308 default:
7309 FATAL_ERROR("Value::evaluate_value()");
7310 }
7311 break;
7312 case OPTYPE_NOT: {
7313 if(is_unfoldable()) break;
7314 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7315 clean_up();
7316 valuetype=V_BOOL;
7317 u.val_bool=!b;
7318 break;}
7319 case OPTYPE_NOT4B: {
7320 if(is_unfoldable()) break;
7321 v1=u.expr.v1->get_value_refd_last();
7322 const string& s = v1->get_val_str();
7323 valuetype_t vt=v1->valuetype;
7324 clean_up();
7325 valuetype=vt;
7326 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7327 break;}
7328 case OPTYPE_BIT2HEX: {
7329 if(is_unfoldable()) break;
7330 v1=u.expr.v1->get_value_refd_last();
7331 const string& s = v1->get_val_str();
7332 clean_up();
7333 valuetype=V_HSTR;
7334 set_val_str(bit2hex(s));
7335 break;}
7336 case OPTYPE_BIT2OCT: {
7337 if(is_unfoldable()) break;
7338 v1=u.expr.v1->get_value_refd_last();
7339 const string& s = v1->get_val_str();
7340 clean_up();
7341 valuetype=V_OSTR;
7342 set_val_str(bit2oct(s));
7343 break;}
7344 case OPTYPE_BIT2STR:
7345 case OPTYPE_HEX2STR:
7346 case OPTYPE_OCT2STR: {
7347 if(is_unfoldable()) break;
7348 v1=u.expr.v1->get_value_refd_last();
7349 const string& s = v1->get_val_str();
7350 clean_up();
7351 valuetype=V_CSTR;
7352 set_val_str(new string(s));
7353 break;}
7354 case OPTYPE_BIT2INT: {
7355 if (is_unfoldable()) break;
7356 v1 = u.expr.v1->get_value_refd_last();
7357 const string& s = v1->get_val_str();
7358 clean_up();
7359 valuetype = V_INT;
7360 u.val_Int = bit2int(s);
7361 break; }
7362 case OPTYPE_CHAR2INT: {
7363 if (is_unfoldable()) break;
7364 v1 = u.expr.v1->get_value_refd_last();
7365 char c = v1->get_val_str()[0];
7366 clean_up();
7367 valuetype = V_INT;
7368 u.val_Int = new int_val_t((Int)c);
7369 break; }
7370 case OPTYPE_CHAR2OCT: {
7371 if(is_unfoldable()) break;
7372 v1=u.expr.v1->get_value_refd_last();
7373 const string& s = v1->get_val_str();
7374 clean_up();
7375 valuetype=V_OSTR;
7376 set_val_str(char2oct(s));
7377 break;}
7378 case OPTYPE_STR2INT: {
7379 if (is_unfoldable()) break;
7380 v1 = u.expr.v1->get_value_refd_last();
7381 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7382 clean_up();
7383 valuetype = V_INT;
7384 u.val_Int = i;
7385 /** \todo hiba eseten lenyeli... */
7386 break; }
7387 case OPTYPE_STR2FLOAT: {
7388 if(is_unfoldable()) break;
7389 v1=u.expr.v1->get_value_refd_last();
7390 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7391 clean_up();
7392 valuetype=V_REAL;
7393 u.val_Real=r;
7394 /** \todo hiba eseten lenyeli... */
7395 break;}
7396 case OPTYPE_STR2BIT: {
7397 if(is_unfoldable()) break;
7398 v1=u.expr.v1->get_value_refd_last();
7399 const string& s = v1->get_val_str();
7400 clean_up();
7401 valuetype=V_BSTR;
7402 set_val_str(new string(s));
7403 break;}
7404 case OPTYPE_STR2HEX:
7405 case OPTYPE_OCT2HEX: {
7406 if(is_unfoldable()) break;
7407 v1=u.expr.v1->get_value_refd_last();
7408 const string& s = v1->get_val_str();
7409 clean_up();
7410 valuetype=V_HSTR;
7411 set_val_str(to_uppercase(s));
7412 break;}
7413 case OPTYPE_STR2OCT: {
7414 if(is_unfoldable()) break;
7415 v1=u.expr.v1->get_value_refd_last();
7416 const string& s = v1->get_val_str();
7417 clean_up();
7418 valuetype=V_OSTR;
7419 set_val_str(to_uppercase(s));
7420 break;}
7421 case OPTYPE_FLOAT2INT: {
7422 if (is_unfoldable()) break;
7423 v1 = u.expr.v1->get_value_refd_last();
7424 ttcn3float r = v1->get_val_Real();
7425 clean_up();
7426 valuetype = V_INT;
7427 u.val_Int = float2int(r, *u.expr.v1);
7428 break;}
7429 case OPTYPE_FLOAT2STR: {
7430 if(is_unfoldable()) break;
7431 v1=u.expr.v1->get_value_refd_last();
7432 ttcn3float r=v1->get_val_Real();
7433 clean_up();
7434 valuetype=V_CSTR;
7435 set_val_str(float2str(r));
7436 break;}
7437 case OPTYPE_HEX2BIT:
7438 case OPTYPE_OCT2BIT: {
7439 if(is_unfoldable()) break;
7440 v1=u.expr.v1->get_value_refd_last();
7441 const string& s = v1->get_val_str();
7442 clean_up();
7443 valuetype=V_BSTR;
7444 set_val_str(hex2bit(s));
7445 break;}
7446 case OPTYPE_HEX2INT:
7447 case OPTYPE_OCT2INT: {
7448 if(is_unfoldable()) break;
7449 v1=u.expr.v1->get_value_refd_last();
7450 const string& s = v1->get_val_str();
7451 clean_up();
7452 valuetype=V_INT;
7453 u.val_Int=hex2int(s);
7454 break;}
7455 case OPTYPE_HEX2OCT: {
7456 if(is_unfoldable()) break;
7457 v1=u.expr.v1->get_value_refd_last();
7458 const string& s = v1->get_val_str();
7459 clean_up();
7460 valuetype=V_OSTR;
7461 set_val_str(hex2oct(s));
7462 break;}
7463 case OPTYPE_INT2CHAR: {
7464 if (is_unfoldable()) break;
7465 v1 = u.expr.v1->get_value_refd_last();
7466 const int_val_t *c_int = v1->get_val_Int();
7467 char c = static_cast<char>(c_int->get_val());
7468 clean_up();
7469 valuetype = V_CSTR;
7470 set_val_str(new string(1, &c));
7471 break; }
7472 case OPTYPE_INT2UNICHAR: {
7473 if (is_unfoldable()) break;
7474 v1 = u.expr.v1->get_value_refd_last();
7475 const int_val_t *i_int = v1->get_val_Int();
7476 Int i = i_int->get_val();
7477 clean_up();
7478 valuetype = V_USTR;
7479 set_val_ustr(int2unichar(i));
7480 u.ustr.convert_str = false;
7481 break; }
7482 case OPTYPE_INT2FLOAT: {
7483 if (is_unfoldable()) break;
7484 v1 = u.expr.v1->get_value_refd_last();
7485 const int_val_t *i_int = v1->get_val_Int();
7486 Real i_int_real = i_int->to_real();
7487 clean_up();
7488 valuetype = V_REAL;
7489 u.val_Real = i_int_real;
7490 break; }
7491 case OPTYPE_INT2STR: {
7492 if (is_unfoldable()) break;
7493 v1 = u.expr.v1->get_value_refd_last();
7494 const int_val_t *i_int = v1->get_val_Int();
7495 string *i_int_str = new string(i_int->t_str());
7496 clean_up();
7497 valuetype = V_CSTR;
7498 set_val_str(i_int_str);
7499 break; }
7500 case OPTYPE_OCT2CHAR: {
7501 if(is_unfoldable()) break;
7502 v1=u.expr.v1->get_value_refd_last();
7503 const string& s = v1->get_val_str();
7504 clean_up();
7505 valuetype=V_CSTR;
7506 set_val_str(oct2char(s));
7507 break;}
7508 case OPTYPE_GET_STRINGENCODING: {
7509 if(is_unfoldable()) break;
7510 v1 = u.expr.v1->get_value_refd_last();
7511 const string& s1 = v1->get_val_str();
7512 clean_up();
7513 valuetype = V_CSTR;
7514 set_val_str(get_stringencoding(s1));
7515 break;}
7516 case OPTYPE_REMOVE_BOM: {
7517 if(is_unfoldable()) break;
7518 v1 = u.expr.v1->get_value_refd_last();
7519 const string& s1 = v1->get_val_str();
7520 clean_up();
7521 valuetype = V_OSTR;
7522 set_val_str(remove_bom(s1));
7523 break;}
7524 case OPTYPE_ENUM2INT: {
7525 if(is_unfoldable()) break;
7526 v1=u.expr.v1->get_value_refd_last();
7527 Type* enum_type = v1->get_my_governor();
7528 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7529 clean_up();
7530 valuetype = V_INT;
7531 u.val_Int = new int_val_t(enum_val);
7532 break;}
7533 case OPTYPE_UNICHAR2INT:
7534 if (is_unfoldable()) {
7535 // replace the operation with char2int() if the operand is a charstring
7536 // value to avoid its unnecessary conversion to universal charstring
7537 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7538 u.expr.v_optype = OPTYPE_CHAR2INT;
7539 } else {
7540 v1=u.expr.v1->get_value_refd_last();
7541 const ustring& s = v1->get_val_ustr();
7542 clean_up();
7543 valuetype=V_INT;
7544 u.val_Int=new int_val_t(unichar2int(s));
7545 }
7546 break;
7547 case OPTYPE_UNICHAR2CHAR:
7548 v1 = u.expr.v1;
7549 if (is_unfoldable()) {
7550 // replace the operation with its operand if it is a charstring
7551 // value to avoid its unnecessary conversion to universal charstring
7552 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7553 u.expr.v1 = 0;
7554 copy_and_destroy(v1);
7555 }
7556 } else {
7557 v1 = v1->get_value_refd_last();
7558 const ustring& s = v1->get_val_ustr();
7559 clean_up();
7560 valuetype = V_CSTR;
7561 set_val_str(new string(s));
7562 }
7563 break;
7564 case OPTYPE_MULTIPLY: { // v1 v2
7565 if (!is_unfoldable()) goto eval_arithmetic;
7566 v1 = u.expr.v1->get_value_refd_last();
7567 v2 = u.expr.v2->get_value_refd_last();
7568 if (v1->is_unfoldable()) v1 = v2;
7569 if (v1->is_unfoldable()) break;
7570 switch(v1->valuetype) {
7571 case V_INT: {
7572 if (*v1->get_val_Int() != 0) break;
7573 clean_up();
7574 valuetype = V_INT;
7575 u.val_Int = new int_val_t((Int)0);
7576 break; }
7577 case V_REAL: {
7578 if (v1->get_val_Real() != 0.0) break;
7579 clean_up();
7580 valuetype = V_REAL;
7581 u.val_Real = 0.0;
7582 break; }
7583 default:
7584 FATAL_ERROR("Value::evaluate_value()");
7585 }
7586 break; }
7587 case OPTYPE_ADD: // v1 v2
7588 case OPTYPE_SUBTRACT:
7589 case OPTYPE_DIVIDE:
7590 case OPTYPE_MOD:
7591 case OPTYPE_REM: {
7592 eval_arithmetic:
7593 if(is_unfoldable()) break;
7594 v1=u.expr.v1->get_value_refd_last();
7595 v2=u.expr.v2->get_value_refd_last();
7596 operationtype_t ot=u.expr.v_optype;
7597 switch (v1->valuetype) {
7598 case V_INT: {
7599 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7600 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7601 clean_up();
7602 valuetype = V_INT;
7603 switch (ot) {
7604 case OPTYPE_ADD:
7605 u.val_Int = new int_val_t(*i1 + *i2);
7606 break;
7607 case OPTYPE_SUBTRACT:
7608 u.val_Int = new int_val_t(*i1 - *i2);
7609 break;
7610 case OPTYPE_MULTIPLY:
7611 u.val_Int = new int_val_t(*i1 * *i2);
7612 break;
7613 case OPTYPE_DIVIDE:
7614 u.val_Int = new int_val_t(*i1 / *i2);
7615 break;
7616 case OPTYPE_MOD:
7617 u.val_Int = new int_val_t(mod(*i1, *i2));
7618 break;
7619 case OPTYPE_REM:
7620 u.val_Int = new int_val_t(rem(*i1, *i2));
7621 break;
7622 default:
7623 FATAL_ERROR("Value::evaluate_value()");
7624 }
7625 delete i1;
7626 delete i2;
7627 break; }
7628 case V_REAL: {
7629 ttcn3float r1=v1->get_val_Real();
7630 ttcn3float r2=v2->get_val_Real();
7631 clean_up();
7632 valuetype=V_REAL;
7633 switch(ot) {
7634 case OPTYPE_ADD:
7635 u.val_Real=r1+r2;
7636 break;
7637 case OPTYPE_SUBTRACT:
7638 u.val_Real=r1-r2;
7639 break;
7640 case OPTYPE_MULTIPLY:
7641 u.val_Real=r1*r2;
7642 break;
7643 case OPTYPE_DIVIDE:
7644 u.val_Real=r1/r2;
7645 break;
7646 default:
7647 FATAL_ERROR("Value::evaluate_value()");
7648 }
7649 break;}
7650 default:
7651 FATAL_ERROR("Value::evaluate_value()");
7652 }
7653 break;}
7654 case OPTYPE_CONCAT: {
7655 if(is_unfoldable()) break;
7656 v1=u.expr.v1->get_value_refd_last();
7657 v2=u.expr.v2->get_value_refd_last();
7658 valuetype_t vt = v1->valuetype;
7659 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7660 const ustring& s1 = v1->get_val_ustr();
7661 const ustring& s2 = v2->get_val_ustr();
7662 clean_up();
7663 valuetype = V_USTR;
7664 set_val_ustr(new ustring(s1 + s2));
7665 u.ustr.convert_str = false;
7666 } else {
7667 const string& s1 = v1->get_val_str();
7668 const string& s2 = v2->get_val_str();
7669 clean_up();
7670 valuetype = vt;
7671 set_val_str(new string(s1 + s2));
7672 }
7673 break;}
7674 case OPTYPE_EQ: {
7675 if(is_unfoldable()) break;
7676 v1=u.expr.v1->get_value_refd_last();
7677 v2=u.expr.v2->get_value_refd_last();
7678 bool b=*v1==*v2;
7679 clean_up();
7680 valuetype=V_BOOL;
7681 u.val_bool=b;
7682 break;}
7683 case OPTYPE_NE: {
7684 if(is_unfoldable()) break;
7685 v1=u.expr.v1->get_value_refd_last();
7686 v2=u.expr.v2->get_value_refd_last();
7687 bool b=*v1==*v2;
7688 clean_up();
7689 valuetype=V_BOOL;
7690 u.val_bool=!b;
7691 break;}
7692 case OPTYPE_LT: {
7693 if(is_unfoldable()) break;
7694 v1=u.expr.v1->get_value_refd_last();
7695 v2=u.expr.v2->get_value_refd_last();
7696 bool b=*v1<*v2;
7697 clean_up();
7698 valuetype=V_BOOL;
7699 u.val_bool=b;
7700 break;}
7701 case OPTYPE_GT: {
7702 if(is_unfoldable()) break;
7703 v1=u.expr.v1->get_value_refd_last();
7704 v2=u.expr.v2->get_value_refd_last();
7705 bool b=*v2<*v1;
7706 clean_up();
7707 valuetype=V_BOOL;
7708 u.val_bool=b;
7709 break;}
7710 case OPTYPE_GE: {
7711 if(is_unfoldable()) break;
7712 v1=u.expr.v1->get_value_refd_last();
7713 v2=u.expr.v2->get_value_refd_last();
7714 bool b=*v1<*v2;
7715 clean_up();
7716 valuetype=V_BOOL;
7717 u.val_bool=!b;
7718 break;}
7719 case OPTYPE_LE: {
7720 if(is_unfoldable()) break;
7721 v1=u.expr.v1->get_value_refd_last();
7722 v2=u.expr.v2->get_value_refd_last();
7723 bool b=*v2<*v1;
7724 clean_up();
7725 valuetype=V_BOOL;
7726 u.val_bool=!b;
7727 break;}
7728 case OPTYPE_AND:
7729 v1 = u.expr.v1->get_value_refd_last();
7730 if (v1->valuetype == V_BOOL) {
7731 if (v1->get_val_bool()) {
7732 // the left operand is a literal "true"
7733 // substitute the expression with the right operand
7734 v2 = u.expr.v2;
7735 u.expr.v2 = 0;
7736 copy_and_destroy(v2);
7737 } else {
7738 // the left operand is a literal "false"
7739 // the result must be false regardless the right operand
7740 // because of the short circuit evaluation rule
7741 clean_up();
7742 valuetype = V_BOOL;
7743 u.val_bool = false;
7744 }
7745 } else {
7746 // we must keep the left operand because of the potential side effects
7747 // the right operand can only be eliminated if it is a literal "true"
7748 v2 = u.expr.v2->get_value_refd_last();
7749 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7750 v1 = u.expr.v1;
7751 u.expr.v1 = 0;
7752 copy_and_destroy(v1);
7753 }
7754 }
7755 break;
7756 case OPTYPE_OR:
7757 v1 = u.expr.v1->get_value_refd_last();
7758 if (v1->valuetype == V_BOOL) {
7759 if (v1->get_val_bool()) {
7760 // the left operand is a literal "true"
7761 // the result must be true regardless the right operand
7762 // because of the short circuit evaluation rule
7763 clean_up();
7764 valuetype = V_BOOL;
7765 u.val_bool = true;
7766 } else {
7767 // the left operand is a literal "false"
7768 // substitute the expression with the right operand
7769 v2 = u.expr.v2;
7770 u.expr.v2 = 0;
7771 copy_and_destroy(v2);
7772 }
7773 } else {
7774 // we must keep the left operand because of the potential side effects
7775 // the right operand can only be eliminated if it is a literal "false"
7776 v2 = u.expr.v2->get_value_refd_last();
7777 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7778 v1 = u.expr.v1;
7779 u.expr.v1 = 0;
7780 copy_and_destroy(v1);
7781 }
7782 }
7783 break;
7784 case OPTYPE_XOR: {
7785 if(is_unfoldable()) break;
7786 v1=u.expr.v1->get_value_refd_last();
7787 v2=u.expr.v2->get_value_refd_last();
7788 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7789 clean_up();
7790 valuetype=V_BOOL;
7791 u.val_bool=b;
7792 break;}
7793 case OPTYPE_AND4B: {
7794 if(is_unfoldable()) break;
7795 v1=u.expr.v1->get_value_refd_last();
7796 v2=u.expr.v2->get_value_refd_last();
7797 valuetype_t vt=v1->valuetype;
7798 const string& s1 = v1->get_val_str();
7799 const string& s2 = v2->get_val_str();
7800 clean_up();
7801 valuetype=vt;
7802 set_val_str(and4b(s1, s2));
7803 break;}
7804 case OPTYPE_OR4B: {
7805 if(is_unfoldable()) break;
7806 v1=u.expr.v1->get_value_refd_last();
7807 v2=u.expr.v2->get_value_refd_last();
7808 valuetype_t vt=v1->valuetype;
7809 const string& s1 = v1->get_val_str();
7810 const string& s2 = v2->get_val_str();
7811 clean_up();
7812 valuetype=vt;
7813 set_val_str(or4b(s1, s2));
7814 break;}
7815 case OPTYPE_XOR4B: {
7816 if(is_unfoldable()) break;
7817 v1=u.expr.v1->get_value_refd_last();
7818 v2=u.expr.v2->get_value_refd_last();
7819 valuetype_t vt=v1->valuetype;
7820 const string& s1 = v1->get_val_str();
7821 const string& s2 = v2->get_val_str();
7822 clean_up();
7823 valuetype=vt;
7824 set_val_str(xor4b(s1, s2));
7825 break;}
7826 case OPTYPE_SHL: {
7827 if(is_unfoldable()) break;
7828 v1=u.expr.v1->get_value_refd_last();
7829 v2=u.expr.v2->get_value_refd_last();
7830 valuetype_t vt=v1->valuetype;
7831 const string& s = v1->get_val_str();
7832 const int_val_t *i_int = v2->get_val_Int();
7833 Int i=i_int->get_val();
7834 if(vt==V_OSTR) i*=2;
7835 clean_up();
7836 valuetype=vt;
7837 set_val_str(shift_left(s, i));
7838 break;}
7839 case OPTYPE_SHR: {
7840 if(is_unfoldable()) break;
7841 v1=u.expr.v1->get_value_refd_last();
7842 v2=u.expr.v2->get_value_refd_last();
7843 valuetype_t vt=v1->valuetype;
7844 const string& s = v1->get_val_str();
7845 const int_val_t *i_int = v2->get_val_Int();
7846 Int i=i_int->get_val();
7847 if(vt==V_OSTR) i*=2;
7848 clean_up();
7849 valuetype=vt;
7850 set_val_str(shift_right(s, i));
7851 break;}
7852 case OPTYPE_ROTL: {
7853 if(is_unfoldable()) break;
7854 v1=u.expr.v1->get_value_refd_last();
7855 v2=u.expr.v2->get_value_refd_last();
7856 valuetype_t vt=v1->valuetype;
7857 const int_val_t *i_int=v2->get_val_Int();
7858 Int i=i_int->get_val();
7859 if(vt==V_USTR) {
7860 const ustring& s = v1->get_val_ustr();
7861 clean_up();
7862 valuetype=vt;
7863 set_val_ustr(rotate_left(s, i));
7864 u.ustr.convert_str = false;
7865 }
7866 else {
7867 if(vt==V_OSTR) i*=2;
7868 const string& s = v1->get_val_str();
7869 clean_up();
7870 valuetype=vt;
7871 set_val_str(rotate_left(s, i));
7872 }
7873 break;}
7874 case OPTYPE_ROTR: {
7875 if(is_unfoldable()) break;
7876 v1=u.expr.v1->get_value_refd_last();
7877 v2=u.expr.v2->get_value_refd_last();
7878 valuetype_t vt=v1->valuetype;
7879 const int_val_t *i_int=v2->get_val_Int();
7880 Int i=i_int->get_val();
7881 if(vt==V_USTR) {
7882 const ustring& s = v1->get_val_ustr();
7883 clean_up();
7884 valuetype=vt;
7885 set_val_ustr(rotate_right(s, i));
7886 u.ustr.convert_str = false;
7887 }
7888 else {
7889 if(vt==V_OSTR) i*=2;
7890 const string& s = v1->get_val_str();
7891 clean_up();
7892 valuetype=vt;
7893 set_val_str(rotate_right(s, i));
7894 }
7895 break;}
7896 case OPTYPE_INT2BIT: {
7897 if (is_unfoldable()) break;
7898 v1 = u.expr.v1->get_value_refd_last();
7899 v2 = u.expr.v2->get_value_refd_last();
7900 const int_val_t *i1_int = v1->get_val_Int();
7901 const int_val_t *i2_int = v2->get_val_Int();
7902 string *val = int2bit(*i1_int, i2_int->get_val());
7903 clean_up();
7904 valuetype = V_BSTR;
7905 set_val_str(val);
7906 break; }
7907 case OPTYPE_INT2HEX: {
7908 if (is_unfoldable()) break;
7909 v1 = u.expr.v1->get_value_refd_last();
7910 v2 = u.expr.v2->get_value_refd_last();
7911 const int_val_t *i1_int = v1->get_val_Int();
7912 const int_val_t *i2_int = v2->get_val_Int();
7913 // Do it before the `clean_up'. i2_int is already checked.
7914 string *val = int2hex(*i1_int, i2_int->get_val());
7915 clean_up();
7916 valuetype = V_HSTR;
7917 set_val_str(val);
7918 break; }
7919 case OPTYPE_INT2OCT: {
7920 if (is_unfoldable()) break;
7921 v1 = u.expr.v1->get_value_refd_last();
7922 v2 = u.expr.v2->get_value_refd_last();
7923 const int_val_t i1_int(*v1->get_val_Int());
7924 // `v2' is a native integer.
7925 Int i2_int = v2->get_val_Int()->get_val() * 2;
7926 clean_up();
7927 valuetype = V_OSTR;
7928 set_val_str(int2hex(i1_int, i2_int));
7929 break; }
7930 case OPTYPE_SUBSTR: {
7931 if(is_unfoldable()) break;
7932 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7933 v2=u.expr.v2->get_value_refd_last();
7934 v3=u.expr.v3->get_value_refd_last();
7935 valuetype_t vt=v1->valuetype;
7936 const int_val_t *i2_int=v2->get_val_Int();
7937 const int_val_t *i3_int=v3->get_val_Int();
7938 Int i2=i2_int->get_val();
7939 Int i3=i3_int->get_val();
7940 if(vt==V_USTR) {
7941 const ustring& s = v1->get_val_ustr();
7942 clean_up();
7943 valuetype=vt;
7944 set_val_ustr(new ustring(s.substr(i2, i3)));
7945 u.ustr.convert_str = false;
7946 }
7947 else {
7948 if(vt==V_OSTR) {
7949 i2*=2;
7950 i3*=2;
7951 }
7952 const string& s = v1->get_val_str();
7953 clean_up();
7954 valuetype=vt;
7955 set_val_str(new string(s.substr(i2, i3)));
7956 }
7957 break;}
7958 case OPTYPE_REPLACE: {
7959 if(is_unfoldable()) break;
7960 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7961 v2=u.expr.v2->get_value_refd_last();
7962 v3=u.expr.v3->get_value_refd_last();
7963 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7964 valuetype_t vt=v1->valuetype;
7965 const int_val_t *i2_int=v2->get_val_Int();
7966 const int_val_t *i3_int=v3->get_val_Int();
7967 Int i2=i2_int->get_val();
7968 Int i3=i3_int->get_val();
7969 switch(vt) {
7970 case V_BSTR: {
7971 string *s1 = new string(v1->get_val_str());
7972 const string& s2 = v4->get_val_str();
7973 clean_up();
7974 valuetype=vt;
7975 s1->replace(i2, i3, s2);
7976 set_val_str(s1);
7977 break;}
7978 case V_HSTR: {
7979 string *s1 = new string(v1->get_val_str());
7980 const string& s2 = v4->get_val_str();
7981 clean_up();
7982 valuetype=vt;
7983 s1->replace(i2, i3, s2);
7984 set_val_str(s1);
7985 break;}
7986 case V_OSTR: {
7987 i2*=2;
7988 i3*=2;
7989 string *s1 = new string(v1->get_val_str());
7990 const string& s2 = v4->get_val_str();
7991 clean_up();
7992 valuetype=vt;
7993 s1->replace(i2, i3, s2);
7994 set_val_str(s1);
7995 break;}
7996 case V_CSTR: {
7997 string *s1 = new string(v1->get_val_str());
7998 const string& s2 = v4->get_val_str();
7999 clean_up();
8000 valuetype=vt;
8001 s1->replace(i2, i3, s2);
8002 set_val_str(s1);
8003 break;}
8004 case V_USTR: {
8005 ustring *s1 = new ustring(v1->get_val_ustr());
8006 const ustring& s2 = v4->get_val_ustr();
8007 clean_up();
8008 valuetype=vt;
8009 s1->replace(i2, i3, s2);
8010 set_val_ustr(s1);
8011 u.ustr.convert_str = false;
8012 break;}
8013 default:
8014 FATAL_ERROR("Value::evaluate_value()");
8015 }
8016 break; }
8017 case OPTYPE_REGEXP: {
8018 if (is_unfoldable()) break;
8019 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
8020 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
8021 v3=u.expr.v3->get_value_refd_last();
8022 const int_val_t *i3_int = v3->get_val_Int();
8023 Int i3 = i3_int->get_val();
8024 if (v1->valuetype == V_CSTR) {
8025 const string& s1 = v1->get_val_str();
8026 const string& s2 = v2->get_val_str();
8027 string *result = regexp(s1, s2, i3);
8028 clean_up();
8029 valuetype = V_CSTR;
8030 set_val_str(result);
8031 } if (v1->valuetype == V_USTR) {
8032 const ustring& s1 = v1->get_val_ustr();
8033 const ustring& s2 = v2->get_val_ustr();
8034 ustring *result = regexp(s1, s2, i3);
8035 clean_up();
8036 valuetype = V_USTR;
8037 set_val_ustr(result);
8038 u.ustr.convert_str = false;
8039 }
8040 break; }
8041 case OPTYPE_LENGTHOF:{
8042 if(is_unfoldable()) break;
8043 v1=u.expr.ti1->get_Template()->get_specific_value()
8044 ->get_value_refd_last();
8045 size_t i;
8046 if(v1->is_string_type(exp_val)) {
8047 i=v1->get_val_strlen();
8048 } else { // v1 is be seq/set of or array
8049 switch (v1->valuetype) {
8050 case V_SEQOF:
8051 case V_SETOF:
8052 case V_ARRAY: {
8053 if(v1->u.val_vs->is_indexed())
8054 { i = v1->u.val_vs->get_nof_ivs();}
8055 else { i = v1->u.val_vs->get_nof_vs();}
8056 break; }
8057 default:
8058 FATAL_ERROR("Value::evaluate_value()");
8059 }
8060 }
8061 clean_up();
8062 valuetype=V_INT;
8063 u.val_Int=new int_val_t(i);
8064 break;}
8065 case OPTYPE_SIZEOF: {
8066 Int i=chk_eval_expr_sizeof(refch, exp_val);
8067 if(i!=-1) {
8068 clean_up();
8069 valuetype=V_INT;
8070 u.val_Int=new int_val_t(i);
8071 }
8072 break;}
8073 case OPTYPE_ISVALUE: {
8074 if(is_unfoldable()) break;
8075 bool is_singleval = !u.expr.ti1->get_DerivedRef()
8076 && u.expr.ti1->get_Template()->is_Value();
8077 if (is_singleval) {
8078 Value * other_val = u.expr.ti1->get_Template()->get_Value();
8079 is_singleval = other_val->evaluate_isvalue(false);
8080 // is_singleval now contains the compile-time result of isvalue
8081 delete other_val;
8082 }
8083 clean_up();
8084 valuetype = V_BOOL;
8085 u.val_bool = is_singleval;
8086 break;}
8087 case OPTYPE_ISCHOSEN_V: {
8088 if (is_unfoldable()) break;
8089 v1 = u.expr.v1->get_value_refd_last();
8090 bool b = v1->field_is_chosen(*u.expr.i2);
8091 clean_up();
8092 valuetype = V_BOOL;
8093 u.val_bool = b;
8094 break; }
8095 case OPTYPE_VALUEOF: // ti1
8096 if (!u.expr.ti1->get_DerivedRef() &&
8097 u.expr.ti1->get_Template()->is_Value() &&
8098 !u.expr.ti1->get_Type()) {
8099 // FIXME actually if the template instance has a type
8100 // it might still be foldable.
8101 // the argument is a single specific value
8102 v1 = u.expr.ti1->get_Template()->get_Value();
8103 Type *governor = my_governor;
8104 if (governor == NULL) {
8105 governor = u.expr.ti1->get_expr_governor(exp_val);
8106 if (governor != NULL) governor = governor->get_type_refd_last();
8107 }
8108 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
8109 if (governor == NULL)
8110 FATAL_ERROR("Value::evaluate_value()");
8111 clean_up();
8112 valuetype = v1->valuetype;
8113 u = v1->u;
8114 set_my_governor(governor);
8115 if (valuetype == V_REFD && u.ref.refd_last == v1)
8116 u.ref.refd_last = this;
8117 v1->valuetype = V_ERROR;
8118 delete v1;
8119 }
8120 break;
8121 case OPTYPE_UNDEF_RUNNING:
8122 default:
8123 FATAL_ERROR("Value::evaluate_value()");
8124 } // switch optype
8125 }
8126
8127 bool Value::evaluate_isvalue(bool from_sequence)
8128 {
8129 switch (valuetype) {
8130 case V_OMIT:
8131 // Omit is not a value unless a member of a sequence or set
8132 return from_sequence;
8133 case V_NOTUSED:
8134 return false;
8135 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8136 case V_BOOL: /**< boolean */
8137 case V_NAMEDINT: /**< integer / named number */
8138 case V_NAMEDBITS: /**< named bits (identifiers) */
8139 case V_INT: /**< integer */
8140 case V_REAL: /**< real/float */
8141 case V_ENUM: /**< enumerated */
8142 case V_BSTR: /**< bitstring */
8143 case V_HSTR: /**< hexstring */
8144 case V_OSTR: /**< octetstring */
8145 case V_CSTR: /**< charstring */
8146 case V_USTR: /**< universal charstring */
8147 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
8148 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
8149 case V_OID: /**< object identifier */
8150 case V_ROID: /**< relative object identifier */
8151 case V_VERDICT: /**< all verdicts */
8152 return true; // values of built-in types return true
8153
8154 // Code below was adapted from is_unfoldable(), false returned early.
8155 case V_CHOICE:
8156 return u.choice.alt_value->evaluate_isvalue(false);
8157
8158 case V_SEQOF:
8159 case V_SETOF:
8160 case V_ARRAY:
8161 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8162 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
8163 return false;
8164 }
8165 }
8166 return true;
8167
8168 case V_SEQ:
8169 case V_SET:
8170 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8171 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
8172 ->evaluate_isvalue(true)) return false;
8173 }
8174 return true;
8175
8176 case V_REFD:
8177 // alas, get_value_refd_last prevents this function from const
8178 return get_value_refd_last()->evaluate_isvalue(false);
8179
8180 case V_EXPR:
8181 switch (u.expr.v_optype) {
8182 // A constant null component reference is a corner case: it is foldable
8183 // but escapes unmodified from evaluate_value.
8184 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8185 // or is transformed into some other valuetype in evaluate_value.
8186 case OPTYPE_COMP_NULL:
8187 return false;
8188 default:
8189 break; // and fall through to the FATAL_ERROR
8190 }
8191 // no break
8192 default:
8193 FATAL_ERROR("Value::evaluate_isvalue()");
8194 break;
8195 }
8196 return true;
8197 }
8198
8199 void Value::evaluate_macro(Type::expected_value_t exp_val)
8200 {
8201 switch (u.macro) {
8202 case MACRO_MODULEID:
8203 if (!my_scope)
8204 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8205 set_val_str(new string(my_scope->get_scope_mod()
8206 ->get_modid().get_dispname()));
8207 valuetype = V_CSTR;
8208 break;
8209 case MACRO_FILENAME:
8210 case MACRO_BFILENAME: {
8211 const char *t_filename = get_filename();
8212 if (!t_filename)
8213 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8214 set_val_str(new string(t_filename));
8215 valuetype = V_CSTR;
8216 break; }
8217 case MACRO_FILEPATH: {
8218 const char *t_filename = get_filename();
8219 if (!t_filename)
8220 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8221 char *t_filepath = canonize_input_file(t_filename);
8222 if (!t_filepath)
8223 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8224 set_val_str(new string(t_filepath));
8225 valuetype = V_CSTR;
8226 Free(t_filepath);
8227 break; }
8228 case MACRO_LINENUMBER: {
8229 int t_lineno = get_first_line();
8230 if (t_lineno <= 0)
8231 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8232 set_val_str(new string(Int2string(t_lineno)));
8233 valuetype = V_CSTR;
8234 break; }
8235 case MACRO_LINENUMBER_C: {
8236 int t_lineno = get_first_line();
8237 if (t_lineno <= 0)
8238 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8239 u.val_Int = new int_val_t(t_lineno);
8240 valuetype = V_INT;
8241 break; }
8242 case MACRO_DEFINITIONID: {
8243 // cut the second part from the fullname separated by dots
8244 const string& t_fullname = get_fullname();
8245 size_t first_char = t_fullname.find('.') + 1;
8246 if (first_char >= t_fullname.size())
8247 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8248 t_fullname.c_str());
8249 set_val_str(new string(t_fullname.substr(first_char,
8250 t_fullname.find('.', first_char) - first_char)));
8251 valuetype = V_CSTR;
8252 break; }
8253 case MACRO_SCOPE: {
8254 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8255 set_val_str(new string(my_scope->get_scopeMacro_name()));
8256 valuetype = V_CSTR;
8257 break;
8258 }
8259 case MACRO_TESTCASEID: {
8260 if (exp_val == Type::EXPECTED_CONSTANT ||
8261 exp_val == Type::EXPECTED_STATIC_VALUE) {
8262 error("A %s value was expected instead of macro `%%testcaseId', "
8263 "which is evaluated at runtime",
8264 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8265 goto error;
8266 }
8267 if (!my_scope)
8268 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8269 Ttcn::StatementBlock *my_sb =
8270 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8271 if (!my_sb) {
8272 error("Usage of macro %%testcaseId is allowed only within the "
8273 "statement blocks of functions, altsteps and testcases");
8274 goto error;
8275 }
8276 Ttcn::Definition *my_def = my_sb->get_my_def();
8277 if (!my_def) {
8278 error("Macro %%testcaseId cannot be used in the control part. "
8279 "It is allowed only within the statement blocks of functions, "
8280 "altsteps and testcases");
8281 goto error;
8282 }
8283 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8284 // folding is possible only within testcases
8285 set_val_str(new string(my_def->get_id().get_dispname()));
8286 valuetype = V_CSTR;
8287 }
8288 break; }
8289 default:
8290 FATAL_ERROR("Value::evaluate_macro()");
8291 }
8292 return;
8293 error:
8294 set_valuetype(V_ERROR);
8295 }
8296
8297 void Value::add_id(Identifier *p_id)
8298 {
8299 switch(valuetype) {
8300 case V_NAMEDBITS:
8301 if(u.ids->has_key(p_id->get_name())) {
8302 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8303 // The Value does not take ownership for the identifier,
8304 // so it must be deleted (add_is acts as a sink).
8305 delete p_id;
8306 }
8307 else u.ids->add(p_id->get_name(), p_id);
8308 break;
8309 default:
8310 FATAL_ERROR("Value::add_id()");
8311 } // switch
8312 }
8313
8314 Value* Value::get_value_refd_last(ReferenceChain *refch,
8315 Type::expected_value_t exp_val)
8316 {
8317 set_lowerid_to_ref();
8318 switch (valuetype) {
8319 case V_INVOKE:
8320 // there might be a better place for this
8321 chk_invoke(exp_val);
8322 return this;
8323 case V_REFD:
8324 // use the cache if available
8325 if (u.ref.refd_last) return u.ref.refd_last;
8326 else {
8327 Assignment *ass = u.ref.ref->get_refd_assignment();
8328 if (!ass) {
8329 // the referred definition is not found
8330 set_valuetype(V_ERROR);
8331 } else {
8332 switch (ass->get_asstype()) {
8333 case Assignment::A_OBJECT:
8334 case Assignment::A_OS: {
8335 // the referred definition is an ASN.1 object or object set
8336 Setting *setting = u.ref.ref->get_refd_setting();
8337 if (!setting || setting->get_st() == S_ERROR) {
8338 // remain silent, the error has been already reported
8339 set_valuetype(V_ERROR);
8340 break;
8341 } else if (setting->get_st() != S_V) {
8342 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8343 " refer to a value", u.ref.ref->get_dispname().c_str());
8344 set_valuetype(V_ERROR);
8345 break;
8346 }
8347 bool destroy_refch;
8348 if (refch) {
8349 refch->mark_state();
8350 destroy_refch = false;
8351 } else {
8352 refch = new ReferenceChain(this,
8353 "While searching referenced value");
8354 destroy_refch = true;
8355 }
8356 if (refch->add(get_fullname())) {
8357 Value *v_refd = dynamic_cast<Value*>(setting);
8358 Value *v_last = v_refd->get_value_refd_last(refch);
8359 // in case of circular recursion the valuetype is already set
8360 // to V_ERROR, so don't set the cache
8361 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8362 } else {
8363 // a circular recursion was detected
8364 set_valuetype(V_ERROR);
8365 }
8366 if (destroy_refch) delete refch;
8367 else refch->prev_state();
8368 break; }
8369 case Assignment::A_CONST: {
8370 // the referred definition is a constant
8371 bool destroy_refch;
8372 if (refch) {
8373 refch->mark_state();
8374 destroy_refch = false;
8375 } else {
8376 refch = new ReferenceChain(this,
8377 "While searching referenced value");
8378 destroy_refch = true;
8379 }
8380 if (refch->add(get_fullname())) {
8381 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8382 Value *v_refd = ass->get_Value()
8383 ->get_refd_sub_value(subrefs, 0,
8384 u.ref.ref->getUsedInIsbound(), refch);
8385 if (v_refd) {
8386 Value *v_last = v_refd->get_value_refd_last(refch);
8387 // in case of circular recursion the valuetype is already set
8388 // to V_ERROR, so don't set the cache
8389 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8390 } else if (subrefs && subrefs->has_unfoldable_index()) {
8391 u.ref.refd_last = this;
8392 } else if (u.ref.ref->getUsedInIsbound()) {
8393 u.ref.refd_last = this;
8394 } else {
8395 // the sub-reference points to a non-existent field
8396 set_valuetype(V_ERROR);
8397 }
8398 } else {
8399 // a circular recursion was detected
8400 set_valuetype(V_ERROR);
8401 }
8402 if (destroy_refch) delete refch;
8403 else refch->prev_state();
8404 break; }
8405 case Assignment::A_EXT_CONST:
8406 case Assignment::A_MODULEPAR:
8407 case Assignment::A_VAR:
8408 case Assignment::A_FUNCTION_RVAL:
8409 case Assignment::A_EXT_FUNCTION_RVAL:
8410 case Assignment::A_PAR_VAL_IN:
8411 case Assignment::A_PAR_VAL_OUT:
8412 case Assignment::A_PAR_VAL_INOUT:
8413 // the referred definition is not a constant
8414 u.ref.refd_last = this;
8415 break;
8416 case Assignment::A_FUNCTION:
8417 case Assignment::A_EXT_FUNCTION:
8418 u.ref.ref->error("Reference to a value was expected instead of a "
8419 "call of %s, which does not have return type",
8420 ass->get_description().c_str());
8421 set_valuetype(V_ERROR);
8422 break;
8423 case Assignment::A_FUNCTION_RTEMP:
8424 case Assignment::A_EXT_FUNCTION_RTEMP:
8425 u.ref.ref->error("Reference to a value was expected instead of a "
8426 "call of %s, which returns a template",
8427 ass->get_description().c_str());
8428 set_valuetype(V_ERROR);
8429 break;
8430 default:
8431 u.ref.ref->error("Reference to a value was expected instead of %s",
8432 ass->get_description().c_str());
8433 set_valuetype(V_ERROR);
8434 } // switch asstype
8435 }
8436 if (valuetype == V_REFD) return u.ref.refd_last;
8437 else return this;
8438 }
8439 case V_EXPR: {
8440 // try to evaluate the expression
8441 bool destroy_refch;
8442 if(refch) {
8443 refch->mark_state();
8444 destroy_refch=false;
8445 }
8446 else {
8447 refch=new ReferenceChain(this, "While evaluating expression");
8448 destroy_refch=true;
8449 }
8450 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8451 else set_valuetype(V_ERROR);
8452 if(destroy_refch) delete refch;
8453 else refch->prev_state();
8454 return this; }
8455 case V_MACRO:
8456 evaluate_macro(exp_val);
8457 // no break
8458 default:
8459 // return this for all other value types
8460 return this;
8461 } // switch
8462 }
8463
8464 map<Value*, void> Value::UnfoldabilityCheck::running;
8465
8466 /* Note that the logic here needs to be in sync with evaluate_value,
8467 * and possibly others, i.e. if evaluate_value is called for a Value
8468 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8469 bool Value::is_unfoldable(ReferenceChain *refch,
8470 Type::expected_value_t exp_val)
8471 {
8472 if (UnfoldabilityCheck::is_running(this)) {
8473 // This function is already running on this value => infinite recursion
8474 return true;
8475 }
8476
8477 UnfoldabilityCheck checker(this);
8478
8479 if (get_needs_conversion()) return true;
8480 switch (valuetype) {
8481 case V_NAMEDINT:
8482 case V_NAMEDBITS:
8483 case V_OPENTYPE:
8484 case V_UNDEF_LOWERID:
8485 case V_UNDEF_BLOCK:
8486 case V_TTCN3_NULL:
8487 case V_REFER:
8488 // these value types are eliminated during semantic analysis
8489 FATAL_ERROR("Value::is_unfoldable()");
8490 case V_ERROR:
8491 case V_INVOKE:
8492 return true;
8493 case V_CHOICE:
8494 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8495 case V_SEQOF:
8496 case V_SETOF:
8497 case V_ARRAY:
8498 if (!is_indexed()) {
8499 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8500 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8501 return true;
8502 }
8503 } else {
8504 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8505 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8506 return true;
8507 }
8508 }
8509 return false;
8510 case V_SEQ:
8511 case V_SET:
8512 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8513 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8514 ->is_unfoldable(refch, exp_val)) return true;
8515 }
8516 return false;
8517 case V_OID:
8518 case V_ROID:
8519 chk();
8520 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8521 if ((*u.oid_comps)[i]->is_variable()) return true;
8522 }
8523 return false;
8524 case V_REFD: {
8525 Value *v_last=get_value_refd_last(refch, exp_val);
8526 if(v_last==this) return true; // there weren't any references to chase
8527 else return v_last->is_unfoldable(refch, exp_val);
8528 }
8529 case V_EXPR:
8530 // classify the unchecked ischosen() operation, if it was not done so far
8531 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8532 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8533 switch (u.expr.v_optype) {
8534 case OPTYPE_RND: // -
8535 case OPTYPE_COMP_MTC:
8536 case OPTYPE_COMP_SYSTEM:
8537 case OPTYPE_COMP_SELF:
8538 case OPTYPE_COMP_RUNNING_ANY:
8539 case OPTYPE_COMP_RUNNING_ALL:
8540 case OPTYPE_COMP_ALIVE_ANY:
8541 case OPTYPE_COMP_ALIVE_ALL:
8542 case OPTYPE_TMR_RUNNING_ANY:
8543 case OPTYPE_GETVERDICT:
8544 case OPTYPE_TESTCASENAME:
8545 case OPTYPE_PROF_RUNNING:
8546 case OPTYPE_RNDWITHVAL: // v1
8547 case OPTYPE_MATCH: // v1 t2
8548 case OPTYPE_UNDEF_RUNNING: // v1
8549 case OPTYPE_COMP_RUNNING:
8550 case OPTYPE_COMP_ALIVE:
8551 case OPTYPE_TMR_READ:
8552 case OPTYPE_TMR_RUNNING:
8553 case OPTYPE_ACTIVATE:
8554 case OPTYPE_ACTIVATE_REFD:
8555 case OPTYPE_EXECUTE: // r1 [v2]
8556 case OPTYPE_EXECUTE_REFD:
8557 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8558 case OPTYPE_ISCHOSEN:
8559 case OPTYPE_ISCHOSEN_T:
8560 case OPTYPE_SIZEOF: // ti1
8561 case OPTYPE_DECODE:
8562 case OPTYPE_ENCODE:
8563 case OPTYPE_OCT2UNICHAR:
8564 case OPTYPE_UNICHAR2OCT:
8565 case OPTYPE_ENCODE_BASE64:
8566 case OPTYPE_DECODE_BASE64:
8567 case OPTYPE_ENCVALUE_UNICHAR:
8568 case OPTYPE_DECVALUE_UNICHAR:
8569 case OPTYPE_CHECKSTATE_ANY:
8570 case OPTYPE_CHECKSTATE_ALL:
8571 return true;
8572 case OPTYPE_COMP_NULL: // -
8573 return false;
8574 case OPTYPE_UNARYPLUS: // v1
8575 case OPTYPE_UNARYMINUS:
8576 case OPTYPE_NOT:
8577 case OPTYPE_NOT4B:
8578 case OPTYPE_BIT2HEX:
8579 case OPTYPE_BIT2INT:
8580 case OPTYPE_BIT2OCT:
8581 case OPTYPE_BIT2STR:
8582 case OPTYPE_CHAR2INT:
8583 case OPTYPE_CHAR2OCT:
8584 case OPTYPE_FLOAT2INT:
8585 case OPTYPE_FLOAT2STR:
8586 case OPTYPE_HEX2BIT:
8587 case OPTYPE_HEX2INT:
8588 case OPTYPE_HEX2OCT:
8589 case OPTYPE_HEX2STR:
8590 case OPTYPE_INT2CHAR:
8591 case OPTYPE_INT2FLOAT:
8592 case OPTYPE_INT2STR:
8593 case OPTYPE_INT2UNICHAR:
8594 case OPTYPE_OCT2BIT:
8595 case OPTYPE_OCT2CHAR:
8596 case OPTYPE_OCT2HEX:
8597 case OPTYPE_OCT2INT:
8598 case OPTYPE_OCT2STR:
8599 case OPTYPE_STR2BIT:
8600 case OPTYPE_STR2FLOAT:
8601 case OPTYPE_STR2HEX:
8602 case OPTYPE_STR2INT:
8603 case OPTYPE_STR2OCT:
8604 case OPTYPE_UNICHAR2INT:
8605 case OPTYPE_UNICHAR2CHAR:
8606 case OPTYPE_ENUM2INT:
8607 case OPTYPE_GET_STRINGENCODING:
8608 case OPTYPE_REMOVE_BOM:
8609 return u.expr.v1->is_unfoldable(refch, exp_val);
8610 case OPTYPE_ISBOUND: /*{
8611 //TODO once we have the time for it make isbound foldable.
8612 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8613 Template* temp = u.expr.ti1->get_Template();
8614 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8615 Value* specificValue = temp->get_specific_value();
8616 if (specificValue->get_valuetype() == Value::V_REFD) {
8617 //FIXME implement
8618 }
8619
8620 return specificValue->is_unfoldable(refch, exp_val);
8621 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8622 //FIXME implement
8623 }
8624 }*/
8625 return true;
8626 case OPTYPE_ISPRESENT:
8627 // TODO: "if you have motivation"
8628 return true;
8629 case OPTYPE_ISVALUE: // ti1
8630 // fallthrough
8631 case OPTYPE_LENGTHOF: // ti1
8632 return u.expr.ti1->get_DerivedRef() != 0
8633 || u.expr.ti1->get_Template()->get_templatetype()
8634 != Template::SPECIFIC_VALUE
8635 || u.expr.ti1->get_Template()->get_specific_value()
8636 ->is_unfoldable(refch, exp_val);
8637 case OPTYPE_ROTL:
8638 case OPTYPE_ROTR:
8639 case OPTYPE_CONCAT:
8640 if (!u.expr.v1->is_string_type(exp_val)) return true;
8641 // no break
8642 case OPTYPE_ADD: // v1 v2
8643 case OPTYPE_SUBTRACT:
8644 case OPTYPE_MULTIPLY:
8645 case OPTYPE_DIVIDE:
8646 case OPTYPE_MOD:
8647 case OPTYPE_REM:
8648 case OPTYPE_EQ:
8649 case OPTYPE_LT:
8650 case OPTYPE_GT:
8651 case OPTYPE_NE:
8652 case OPTYPE_GE:
8653 case OPTYPE_LE:
8654 case OPTYPE_XOR:
8655 case OPTYPE_AND4B:
8656 case OPTYPE_OR4B:
8657 case OPTYPE_XOR4B:
8658 case OPTYPE_SHL:
8659 case OPTYPE_SHR:
8660 case OPTYPE_INT2BIT:
8661 case OPTYPE_INT2HEX:
8662 case OPTYPE_INT2OCT:
8663 return u.expr.v1->is_unfoldable(refch, exp_val)
8664 || u.expr.v2->is_unfoldable(refch, exp_val);
8665 case OPTYPE_AND: // short-circuit evaluation
8666 return u.expr.v1->is_unfoldable(refch, exp_val)
8667 || (u.expr.v1->get_val_bool() &&
8668 u.expr.v2->is_unfoldable(refch, exp_val));
8669 case OPTYPE_OR: // short-circuit evaluation
8670 return u.expr.v1->is_unfoldable(refch, exp_val)
8671 || (!u.expr.v1->get_val_bool() &&
8672 u.expr.v2->is_unfoldable(refch, exp_val));
8673 case OPTYPE_SUBSTR:
8674 if (!u.expr.ti1->get_specific_value()) return true;
8675 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8676 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8677 || u.expr.v2->is_unfoldable(refch, exp_val)
8678 || u.expr.v3->is_unfoldable(refch, exp_val);
8679 case OPTYPE_REGEXP:
8680 if (!u.expr.ti1->get_specific_value() ||
8681 !u.expr.t2->get_specific_value()) return true;
8682 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8683 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8684 || u.expr.v3->is_unfoldable(refch, exp_val);
8685 case OPTYPE_DECOMP:
8686 return u.expr.v1->is_unfoldable(refch, exp_val)
8687 || u.expr.v2->is_unfoldable(refch, exp_val)
8688 || u.expr.v3->is_unfoldable(refch, exp_val);
8689 case OPTYPE_REPLACE: {
8690 if (!u.expr.ti1->get_specific_value() ||
8691 !u.expr.ti4->get_specific_value()) return true;
8692 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8693 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8694 || u.expr.v2->is_unfoldable(refch, exp_val)
8695 || u.expr.v3->is_unfoldable(refch, exp_val)
8696 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8697 }
8698 case OPTYPE_VALUEOF: // ti1
8699 /* \todo if you have motivation to implement the eval function
8700 for valueof()... */
8701 return true;
8702 case OPTYPE_ISCHOSEN_V:
8703 return u.expr.v1->is_unfoldable(refch, exp_val);
8704 case OPTYPE_LOG2STR:
8705 case OPTYPE_ANY2UNISTR:
8706 case OPTYPE_TTCN2STRING:
8707 return true;
8708 default:
8709 FATAL_ERROR("Value::is_unfoldable()");
8710 } // switch
8711 break; // should never get here
8712 case V_MACRO:
8713 switch (u.macro) {
8714 case MACRO_TESTCASEID:
8715 // this is known only at runtime
8716 return true;
8717 default:
8718 return false;
8719 }
8720 default:
8721 // all literal values are foldable
8722 return false;
8723 }
8724 }
8725
8726 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8727 size_t start_i, bool usedInIsbound,
8728 ReferenceChain *refch)
8729 {
8730 if (!subrefs) return this;
8731 Value *v = this;
8732 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8733 if (!v) break;
8734 v = v->get_value_refd_last(refch);
8735 switch(v->valuetype) {
8736 case V_ERROR:
8737 return v;
8738 case V_REFD:
8739 // unfoldable stuff
8740 return this;
8741 default:
8742 break;
8743 } // switch
8744 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8745 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8746 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8747 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8748 }
8749 return v;
8750 }
8751
8752 Value *Value::get_refd_field_value(const Identifier& field_id,
8753 bool usedInIsbound, const Location& loc)
8754 {
8755 if (valuetype == V_OMIT) {
8756 loc.error("Reference to field `%s' of omit value `%s'",
8757 field_id.get_dispname().c_str(), get_fullname().c_str());
8758 return 0;
8759 }
8760 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8761 Type *t = my_governor->get_type_refd_last();
8762 switch (t->get_typetype()) {
8763 case Type::T_ERROR:
8764 // remain silent
8765 return 0;
8766 case Type::T_CHOICE_A:
8767 case Type::T_CHOICE_T:
8768 case Type::T_OPENTYPE:
8769 case Type::T_ANYTYPE:
8770 if (!t->has_comp_withName(field_id)) {
8771 loc.error("Reference to non-existent union field `%s' in type `%s'",
8772 field_id.get_dispname().c_str(), t->get_typename().c_str());
8773 return 0;
8774 } else if (valuetype != V_CHOICE) {
8775 // remain silent, the error is already reported
8776 return 0;
8777 } else if (*u.choice.alt_name == field_id) {
8778 // everything is OK
8779 return u.choice.alt_value;
8780 }else {
8781 if (!usedInIsbound) {
8782 loc.error("Reference to inactive field `%s' in a value of union type "
8783 "`%s'. The active field is `%s'",
8784 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8785 u.choice.alt_name->get_dispname().c_str());
8786 }
8787 return 0;
8788 }
8789 case Type::T_SEQ_A:
8790 case Type::T_SEQ_T:
8791 if (!t->has_comp_withName(field_id)) {
8792 loc.error("Reference to non-existent record field `%s' in type `%s'",
8793 field_id.get_dispname().c_str(), t->get_typename().c_str());
8794 return 0;
8795 } else if (valuetype != V_SEQ) {
8796 // remain silent, the error has been already reported
8797 return 0;
8798 } else break;
8799 case Type::T_SET_A:
8800 case Type::T_SET_T:
8801 if (!t->has_comp_withName(field_id)) {
8802 loc.error("Reference to non-existent set field `%s' in type `%s'",
8803 field_id.get_dispname().c_str(), t->get_typename().c_str());
8804 return 0;
8805 } else if (valuetype != V_SET) {
8806 // remain silent, the error has been already reported
8807 return 0;
8808 } else break;
8809 default:
8810 loc.error("Invalid field reference `%s': type `%s' "
8811 "does not have fields", field_id.get_dispname().c_str(),
8812 t->get_typename().c_str());
8813 return 0;
8814 }
8815 // the common end for record & set types
8816 if (u.val_nvs->has_nv_withName(field_id)) {
8817 // everything is OK
8818 return u.val_nvs->get_nv_byName(field_id)->get_value();
8819 } else if (!is_asn1()) {
8820 if (!usedInIsbound) {
8821 loc.error("Reference to unbound field `%s'",
8822 field_id.get_dispname().c_str());
8823 // this is an error in TTCN-3, which has been already reported
8824 }
8825 return 0;
8826 } else {
8827 CompField *cf = t->get_comp_byName(field_id);
8828 if (cf->get_is_optional()) {
8829 // creating an explicit omit value
8830 Value *v = new Value(V_OMIT);
8831 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8832 v->set_my_scope(get_my_scope());
8833 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8834 return v;
8835 } else if (cf->has_default()) {
8836 // returning the component's default value
8837 return cf->get_defval();
8838 } else {
8839 // this is an error in ASN.1, which has been already reported
8840 return 0;
8841 }
8842 }
8843 }
8844
8845 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8846 ReferenceChain *refch)
8847 {
8848 Value *v_index = array_index->get_value_refd_last(refch);
8849 Int index = 0;
8850 bool index_available = false;
8851 if (!v_index->is_unfoldable()) {
8852 if (v_index->valuetype == V_INT) {
8853 index = v_index->get_val_Int()->get_val();
8854 index_available = true;
8855 } else {
8856 array_index->error("An integer value was expected as index");
8857 }
8858 }
8859 if (valuetype == V_OMIT) {
8860 array_index->error("Accessing an element with index of omit value `%s'",
8861 get_fullname().c_str());
8862 return 0;
8863 }
8864 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8865 Type *t = my_governor->get_type_refd_last();
8866 switch (t->get_typetype()) {
8867 case Type::T_ERROR:
8868 // remain silent
8869 return 0;
8870 case Type::T_SEQOF:
8871 if (index_available) {
8872 if (index < 0) {
8873 array_index->error("A non-negative integer value was expected "
8874 "instead of %s for indexing a value of `record "
8875 "of' type `%s'", Int2string(index).c_str(),
8876 t->get_typename().c_str());
8877 return 0;
8878 }
8879 switch (valuetype) {
8880 case V_SEQOF:
8881 if (!is_indexed()) {
8882 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8883 if (!usedInIsbound) {
8884 array_index->error("Index overflow in a value of `record of' "
8885 "type `%s': the index is %s, but the value "
8886 "has only %lu elements",
8887 t->get_typename().c_str(),
8888 Int2string(index).c_str(),
8889 (unsigned long)u.val_vs->get_nof_vs());
8890 }
8891 return 0;
8892 } else {
8893 Value* temp = u.val_vs->get_v_byIndex(index);
8894 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8895 temp->error("Not used symbol is not allowed in this context");
8896 return u.val_vs->get_v_byIndex(index);
8897 }
8898 } else {
8899 // Search the appropriate constant index.
8900 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8901 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8902 ->get_value_refd_last();
8903 if (iv_index->get_valuetype() != V_INT) continue;
8904 if (iv_index->get_val_Int()->get_val() == index)
8905 return u.val_vs->get_iv_byIndex(i)->get_value();
8906 }
8907 return 0;
8908 }
8909 break;
8910 default:
8911 // remain silent, the error has been already reported
8912 return 0;
8913 }
8914 } else {
8915 // the error has been reported above
8916 return 0;
8917 }
8918 case Type::T_SETOF:
8919 if (index_available) {
8920 if (index < 0) {
8921 array_index->error("A non-negative integer value was expected "
8922 "instead of %s for indexing a value of `set of' type `%s'",
8923 Int2string(index).c_str(), t->get_typename().c_str());
8924 return 0;
8925 }
8926 switch (valuetype) {
8927 case V_SETOF:
8928 if (!is_indexed()) {
8929 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8930 if (!usedInIsbound) {
8931 array_index->error("Index overflow in a value of `set of' type "
8932 "`%s': the index is %s, but the value has "
8933 "only %lu elements",
8934 t->get_typename().c_str(),
8935 Int2string(index).c_str(),
8936 (unsigned long)u.val_vs->get_nof_vs());
8937 }
8938 return 0;
8939 } else {
8940 Value* temp = u.val_vs->get_v_byIndex(index);
8941 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8942 temp->error("Not used symbol is not allowed in this context");
8943 return temp;
8944 }
8945 } else {
8946 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8947 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8948 ->get_value_refd_last();
8949 if (iv_index->get_valuetype() != V_INT) continue;
8950 if (iv_index->get_val_Int()->get_val() == index)
8951 return u.val_vs->get_iv_byIndex(i)->get_value();
8952 }
8953 return 0;
8954 }
8955 break;
8956 default:
8957 // remain silent, the error has been already reported
8958 return 0;
8959 }
8960 } else {
8961 // the error has been reported above
8962 return 0;
8963 }
8964 case Type::T_ARRAY:
8965 if (index_available) {
8966 Ttcn::ArrayDimension *dim = t->get_dimension();
8967 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
8968 if (valuetype == V_ARRAY && !dim->get_has_error()) {
8969 // perform the index transformation
8970 index -= dim->get_offset();
8971 if (!is_indexed()) {
8972 // check for index underflow/overflow or too few elements in the
8973 // value
8974 if (index < 0 ||
8975 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
8976 return 0;
8977 else return u.val_vs->get_v_byIndex(index);
8978 } else {
8979 if (index < 0) return 0;
8980 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8981 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8982 ->get_value_refd_last();
8983 if (iv_index->get_valuetype() != V_INT) continue;
8984 if (iv_index->get_val_Int()->get_val() == index)
8985 return u.val_vs->get_iv_byIndex(index)->get_value();
8986 }
8987 return 0;
8988 }
8989 } else {
8990 // remain silent, the error has been already reported
8991 return 0;
8992 }
8993 } else {
8994 // the error has been reported above
8995 return 0;
8996 }
8997 case Type::T_BSTR:
8998 case Type::T_BSTR_A:
8999 case Type::T_HSTR:
9000 case Type::T_OSTR:
9001 case Type::T_CSTR:
9002 case Type::T_USTR:
9003 case Type::T_UTF8STRING:
9004 case Type::T_NUMERICSTRING:
9005 case Type::T_PRINTABLESTRING:
9006 case Type::T_TELETEXSTRING:
9007 case Type::T_VIDEOTEXSTRING:
9008 case Type::T_IA5STRING:
9009 case Type::T_GRAPHICSTRING:
9010 case Type::T_VISIBLESTRING:
9011 case Type::T_GENERALSTRING:
9012 case Type::T_UNIVERSALSTRING:
9013 case Type::T_BMPSTRING:
9014 case Type::T_UTCTIME:
9015 case Type::T_GENERALIZEDTIME:
9016 case Type::T_OBJECTDESCRIPTOR:
9017 if (index_available) return get_string_element(index, *array_index);
9018 else return 0;
9019 default:
9020 array_index->error("Invalid array element reference: type `%s' cannot "
9021 "be indexed", t->get_typename().c_str());
9022 return 0;
9023 }
9024 }
9025
9026 Value *Value::get_string_element(const Int& index, const Location& loc)
9027 {
9028 if (index < 0) {
9029 loc.error("A non-negative integer value was expected instead of %s "
9030 "for indexing a string element", Int2string(index).c_str());
9031 return 0;
9032 }
9033 size_t string_length;
9034 switch (valuetype) {
9035 case V_BSTR:
9036 case V_HSTR:
9037 case V_CSTR:
9038 case V_ISO2022STR:
9039 string_length = u.str.val_str->size();
9040 break;
9041 case V_OSTR:
9042 string_length = u.str.val_str->size() / 2;
9043 break;
9044 case V_USTR:
9045 string_length = u.ustr.val_ustr->size();
9046 break;
9047 default:
9048 // remain silent, the error has been already reported
9049 return 0;
9050 }
9051 if (index >= static_cast<Int>(string_length)) {
9052 loc.error("Index overflow when accessing a string element: "
9053 "the index is %s, but the string has only %lu elements",
9054 Int2string(index).c_str(), (unsigned long) string_length);
9055 return 0;
9056 }
9057 switch (valuetype) {
9058 case V_BSTR:
9059 case V_HSTR:
9060 case V_CSTR:
9061 case V_ISO2022STR:
9062 if (u.str.str_elements && u.str.str_elements->has_key(index))
9063 return (*u.str.str_elements)[index];
9064 else {
9065 Value *t_val = new Value(valuetype,
9066 new string(u.str.val_str->substr(index, 1)));
9067 add_string_element(index, t_val, u.str.str_elements);
9068 return t_val;
9069 }
9070 case V_OSTR:
9071 if (u.str.str_elements && u.str.str_elements->has_key(index))
9072 return (*u.str.str_elements)[index];
9073 else {
9074 Value *t_val = new Value(V_OSTR,
9075 new string(u.str.val_str->substr(2 * index, 2)));
9076 add_string_element(index, t_val, u.str.str_elements);
9077 return t_val;
9078 }
9079 case V_USTR:
9080 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
9081 return (*u.ustr.ustr_elements)[index];
9082 else {
9083 Value *t_val = new Value(V_USTR,
9084 new ustring(u.ustr.val_ustr->substr(index, 1)));
9085 add_string_element(index, t_val, u.ustr.ustr_elements);
9086 return t_val;
9087 }
9088 default:
9089 FATAL_ERROR("Value::get_string_element()");
9090 return 0;
9091 }
9092 }
9093
9094 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
9095 Type::expected_value_t exp_val)
9096 {
9097 set_lowerid_to_ref();
9098 Type::typetype_t r_tt = get_expr_returntype(exp_val);
9099 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
9100 if (error_flag)
9101 error("A value or expression of type %s was expected", type_name);
9102 if (valuetype == V_REFD) {
9103 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
9104 t_chk->chk_this_refd_value(this, 0, exp_val);
9105 }
9106 get_value_refd_last(0, exp_val);
9107 if (error_flag) set_valuetype(V_ERROR);
9108 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
9109 }
9110
9111 int Value::is_parsed_infinity()
9112 {
9113 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
9114 return 1;
9115 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
9116 (u.expr.v1->get_valuetype()==V_REAL) &&
9117 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
9118 return -1;
9119 return 0;
9120 }
9121
9122 bool Value::get_val_bool()
9123 {
9124 Value *v;
9125 if (valuetype == V_REFD) v = get_value_refd_last();
9126 else v = this;
9127 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
9128 return v->u.val_bool;
9129 }
9130
9131 int_val_t* Value::get_val_Int()
9132 {
9133 Value *v;
9134 if (valuetype == V_REFD) v = get_value_refd_last();
9135 else v = this;
9136 switch (v->valuetype) {
9137 case V_INT:
9138 break;
9139 case V_UNDEF_LOWERID:
9140 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9141 "`%s'", (*u.val_id).get_dispname().c_str());
9142 default:
9143 FATAL_ERROR("Value::get_val_Int()");
9144 } // switch
9145 return v->u.val_Int;
9146 }
9147
9148 const Identifier* Value::get_val_id()
9149 {
9150 switch(valuetype) {
9151 case V_NAMEDINT:
9152 case V_ENUM:
9153 case V_UNDEF_LOWERID:
9154 return u.val_id;
9155 default:
9156 FATAL_ERROR("Value::get_val_id()");
9157 return 0;
9158 } // switch
9159 }
9160
9161 const ttcn3float& Value::get_val_Real()
9162 {
9163 Value *v;
9164 if (valuetype == V_REFD) v = get_value_refd_last();
9165 else v = this;
9166 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
9167 return v->u.val_Real;
9168 }
9169
9170 string Value::get_val_str()
9171 {
9172 Value *v = get_value_refd_last();
9173 switch (v->valuetype) {
9174 case V_BSTR:
9175 case V_HSTR:
9176 case V_OSTR:
9177 case V_CSTR:
9178 return *v->u.str.val_str;
9179 case V_CHARSYMS:
9180 return v->u.char_syms->get_string();
9181 case V_USTR:
9182 error("Cannot use ISO-10646 string value in string context");
9183 return string();
9184 case V_ISO2022STR:
9185 error("Cannot use ISO-2022 string value in string context");
9186 // no break
9187 case V_ERROR:
9188 return string();
9189 default:
9190 error("Cannot use this value in charstring value context");
9191 return string();
9192 } // switch
9193 }
9194
9195 ustring Value::get_val_ustr()
9196 {
9197 Value *v = get_value_refd_last();
9198 switch (v->valuetype) {
9199 case V_CSTR:
9200 return ustring(*v->u.str.val_str);
9201 case V_USTR:
9202 return *v->u.ustr.val_ustr;
9203 case V_CHARSYMS:
9204 return v->u.char_syms->get_ustring();
9205 case V_ISO2022STR:
9206 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9207 // no break
9208 case V_ERROR:
9209 return ustring();
9210 default:
9211 error("Cannot use this value in ISO-10646 string context");
9212 return ustring();
9213 } // switch
9214 }
9215
9216 string Value::get_val_iso2022str()
9217 {
9218 Value *v = get_value_refd_last();
9219 switch (v->valuetype) {
9220 case V_CSTR:
9221 case V_ISO2022STR:
9222 return *v->u.str.val_str;
9223 case V_CHARSYMS:
9224 return v->u.char_syms->get_iso2022string();
9225 case V_USTR:
9226 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9227 // no break
9228 case V_ERROR:
9229 return string();
9230 default:
9231 error("Cannot use this value in ISO-2022 string context");
9232 return string();
9233 } // switch
9234 }
9235
9236 size_t Value::get_val_strlen()
9237 {
9238 Value *v = get_value_refd_last();
9239 switch (v->valuetype) {
9240 case V_BSTR:
9241 case V_HSTR:
9242 case V_CSTR:
9243 case V_ISO2022STR:
9244 return v->u.str.val_str->size();
9245 case V_OSTR:
9246 return v->u.str.val_str->size()/2;
9247 case V_CHARSYMS:
9248 return v->u.char_syms->get_len();
9249 case V_USTR:
9250 return v->u.ustr.val_ustr->size();
9251 case V_ERROR:
9252 return 0;
9253 default:
9254 error("Cannot use this value in string value context");
9255 return 0;
9256 } // switch
9257 }
9258
9259 Value::verdict_t Value::get_val_verdict()
9260 {
9261 switch(valuetype) {
9262 case V_VERDICT:
9263 return u.verdict;
9264 default:
9265 FATAL_ERROR("Value::get_val_verdict()");
9266 return u.verdict;
9267 } // switch
9268 }
9269
9270 size_t Value::get_nof_comps()
9271 {
9272 switch (valuetype) {
9273 case V_OID:
9274 case V_ROID:
9275 chk();
9276 return u.oid_comps->size();
9277 case V_SEQOF:
9278 case V_SETOF:
9279 case V_ARRAY:
9280 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9281 else return u.val_vs->get_nof_vs();
9282 case V_SEQ:
9283 case V_SET:
9284 return u.val_nvs->get_nof_nvs();
9285 case V_BSTR:
9286 case V_HSTR:
9287 case V_CSTR:
9288 case V_ISO2022STR:
9289 return u.str.val_str->size();
9290 case V_OSTR:
9291 return u.str.val_str->size()/2;
9292 case V_USTR:
9293 return u.ustr.val_ustr->size();
9294 default:
9295 FATAL_ERROR("Value::get_nof_comps()");
9296 return 0;
9297 } // switch
9298 }
9299
9300 bool Value::is_indexed() const
9301 {
9302 switch (valuetype) {
9303 case V_SEQOF:
9304 case V_SETOF:
9305 case V_ARRAY:
9306 // Applicable only for list-types. Assigning a record/SEQUENCE or
9307 // set/SET with indexed notation is not supported.
9308 return u.val_vs->is_indexed();
9309 default:
9310 FATAL_ERROR("Value::is_indexed()");
9311 break;
9312 }
9313 return false;
9314 }
9315
9316 const Identifier& Value::get_alt_name()
9317 {
9318 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9319 return *u.choice.alt_name;
9320 }
9321
9322 Value *Value::get_alt_value()
9323 {
9324 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9325 return u.choice.alt_value;
9326 }
9327
9328 void Value::set_alt_name_to_lowercase()
9329 {
9330 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9331 string new_name = u.choice.alt_name->get_name();
9332 if (isupper(new_name[0])) {
9333 new_name[0] = tolower(new_name[0]);
9334 if (new_name[new_name.size() - 1] == '_') {
9335 // an underscore is inserted at the end of the alternative name if it's
9336 // a basic type's name (since it would conflict with the class generated
9337 // for that type)
9338 // remove the underscore, it won't conflict with anything if its name
9339 // starts with a lowercase letter
9340 new_name.replace(new_name.size() - 1, 1, "");
9341 }
9342 delete u.choice.alt_name;
9343 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9344 }
9345 }
9346
9347 bool Value::has_oid_error()
9348 {
9349 Value *v;
9350 if (valuetype == V_REFD) v = get_value_refd_last();
9351 else v = this;
9352 switch (valuetype) {
9353 case V_OID:
9354 case V_ROID:
9355 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9356 if ((*v->u.oid_comps)[i]->has_error()) return true;
9357 return false;
9358 default:
9359 return true;
9360 }
9361 }
9362
9363 bool Value::get_oid_comps(vector<string>& comps)
9364 {
9365 bool ret_val = true;
9366 Value *v = this;
9367 switch (valuetype) {
9368 case V_REFD:
9369 v = get_value_refd_last();
9370 // no break
9371 case V_OID:
9372 case V_ROID:
9373 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9374 (*v->u.oid_comps)[i]->get_comps(comps);
9375 if ((*v->u.oid_comps)[i]->is_variable()) {
9376 // not all components can be calculated in compile-time
9377 ret_val = false;
9378 }
9379 }
9380 break;
9381 default:
9382 FATAL_ERROR("Value::get_oid_comps()");
9383 }
9384 return ret_val;
9385 }
9386
9387 void Value::add_se_comp(NamedValue* nv) {
9388 switch (valuetype) {
9389 case V_SEQ:
9390 case V_SET:
9391 if (!u.val_nvs)
9392 u.val_nvs = new NamedValues();
9393 u.val_nvs->add_nv(nv);
9394 break;
9395 default:
9396 FATAL_ERROR("Value::add_se_comp()");
9397 }
9398 }
9399
9400 NamedValue* Value::get_se_comp_byIndex(size_t n)
9401 {
9402 switch(valuetype) {
9403 case V_SEQ:
9404 case V_SET:
9405 return u.val_nvs->get_nv_byIndex(n);
9406 default:
9407 FATAL_ERROR("Value::get_se_comp_byIndex()");
9408 return 0;
9409 } // switch
9410 }
9411
9412 Value *Value::get_comp_byIndex(size_t n)
9413 {
9414 switch (valuetype) {
9415 case V_SEQOF:
9416 case V_SETOF:
9417 case V_ARRAY:
9418 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9419 return u.val_vs->get_iv_byIndex(n)->get_value();
9420 default:
9421 FATAL_ERROR("Value::get_comp_byIndex()");
9422 return 0;
9423 } // switch
9424 }
9425
9426 Value *Value::get_index_byIndex(size_t n)
9427 {
9428 switch (valuetype) {
9429 case V_SEQOF:
9430 case V_SETOF:
9431 case V_ARRAY:
9432 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9433 return u.val_vs->get_iv_byIndex(n)->get_index();
9434 default:
9435 FATAL_ERROR("Value::get_index_byIndex()");
9436 return 0;
9437 } // switch
9438 }
9439
9440 bool Value::has_comp_withName(const Identifier& p_name)
9441 {
9442 switch(valuetype) {
9443 case V_SEQ:
9444 case V_SET:
9445 return u.val_nvs->has_nv_withName(p_name);
9446 case V_CHOICE:
9447 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9448 default:
9449 FATAL_ERROR("Value::get_has_comp_withName()");
9450 return false;
9451 } // switch
9452 }
9453
9454 bool Value::field_is_chosen(const Identifier& p_name)
9455 {
9456 Value *v=get_value_refd_last();
9457 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9458 return *v->u.choice.alt_name==p_name;
9459 }
9460
9461 bool Value::field_is_present(const Identifier& p_name)
9462 {
9463 Value *v=get_value_refd_last();
9464 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9465 FATAL_ERROR("Value::field_is_present()");
9466 return v->u.val_nvs->has_nv_withName(p_name)
9467 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9468 ->get_value_refd_last()->valuetype != V_OMIT;
9469 }
9470
9471 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9472 {
9473 switch(valuetype) {
9474 case V_SEQ:
9475 case V_SET:
9476 return u.val_nvs->get_nv_byName(p_name);
9477 default:
9478 FATAL_ERROR("Value::get_se_comp_byName()");
9479 return 0;
9480 } // switch
9481 }
9482
9483 Value* Value::get_comp_value_byName(const Identifier& p_name)
9484 {
9485 switch(valuetype) {
9486 case V_SEQ:
9487 case V_SET:
9488 return u.val_nvs->get_nv_byName(p_name)->get_value();
9489 case V_CHOICE:
9490 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9491 return u.choice.alt_value;
9492 else
9493 return NULL;
9494 default:
9495 FATAL_ERROR("Value::get_se_comp_byName()");
9496 return 0;
9497 } // switch
9498 }
9499
9500 void Value::chk_dupl_id()
9501 {
9502 switch(valuetype) {
9503 case V_SEQ:
9504 case V_SET:
9505 u.val_nvs->chk_dupl_id();
9506 break;
9507 default:
9508 FATAL_ERROR("Value::chk_dupl_id()");
9509 } // switch
9510 }
9511
9512 size_t Value::get_nof_ids() const
9513 {
9514 switch(valuetype) {
9515 case V_NAMEDBITS:
9516 return u.ids->size();
9517 break;
9518 default:
9519 FATAL_ERROR("Value::get_nof_ids()");
9520 return 0;
9521 } // switch
9522 }
9523
9524 Identifier* Value::get_id_byIndex(size_t p_i)
9525 {
9526 switch(valuetype) {
9527 case V_NAMEDBITS:
9528 return u.ids->get_nth_elem(p_i);
9529 break;
9530 default:
9531 FATAL_ERROR("Value::get_id_byIndex()");
9532 return 0;
9533 } // switch
9534 }
9535
9536 bool Value::has_id(const Identifier& p_id)
9537 {
9538 switch(valuetype) {
9539 case V_NAMEDBITS:
9540 return u.ids->has_key(p_id.get_name());
9541 break;
9542 default:
9543 FATAL_ERROR("Value::has_id()");
9544 return false;
9545 } // switch
9546 }
9547
9548 Reference *Value::get_reference() const
9549 {
9550 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9551 return u.ref.ref;
9552 }
9553
9554 Reference *Value::get_refered() const
9555 {
9556 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9557 return u.refered;
9558 }
9559
9560 Common::Assignment *Value::get_refd_fat() const
9561 {
9562 switch(valuetype){
9563 case V_FUNCTION:
9564 case V_ALTSTEP:
9565 case V_TESTCASE:
9566 return u.refd_fat;
9567 default:
9568 FATAL_ERROR("Value::get_refd_fat()");
9569 }
9570 }
9571
9572 Ttcn::Reference* Value::steal_ttcn_ref()
9573 {
9574 Ttcn::Reference *ret_val =
9575 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9576 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9577 return ret_val;
9578 }
9579
9580 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9581 {
9582 Ttcn::Ref_base *t_ref;
9583 if(valuetype==V_REFD) {
9584 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9585 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9586 u.ref.ref=0;
9587 }
9588 else if(valuetype==V_UNDEF_LOWERID) {
9589 t_ref=new Ttcn::Reference(u.val_id);
9590 t_ref->set_location(*this);
9591 t_ref->set_fullname(get_fullname());
9592 t_ref->set_my_scope(get_my_scope());
9593 u.val_id=0;
9594 }
9595 else {
9596 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9597 t_ref = 0;
9598 }
9599 set_valuetype(V_ERROR);
9600 return t_ref;
9601 }
9602
9603 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9604 Ttcn::ActualParList*& p_ap)
9605 {
9606 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9607 p_v = u.invoke.v;
9608 u.invoke.v = 0;
9609 p_ti = u.invoke.t_list;
9610 u.invoke.t_list = 0;
9611 p_ap = u.invoke.ap_list;
9612 u.invoke.ap_list = 0;
9613 set_valuetype(V_ERROR);
9614 }
9615
9616 Common::Assignment* Value::get_refd_assignment()
9617 {
9618 switch(valuetype) {
9619 case V_FUNCTION:
9620 case V_ALTSTEP:
9621 case V_TESTCASE:
9622 return u.refd_fat;
9623 break;
9624 default:
9625 FATAL_ERROR("Value::get_refd_assignment()");
9626 return 0;
9627 }
9628 }
9629
9630 void Value::chk()
9631 {
9632 if(checked) return;
9633 switch(valuetype) {
9634 case V_OID: {
9635 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9636 " components");
9637 chk_OID(refch);
9638 break; }
9639 case V_ROID: {
9640 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9641 chk_ROID(refch);
9642 break; }
9643 default:
9644 break;
9645 } // switch
9646 checked=true;
9647 }
9648
9649 void Value::chk_OID(ReferenceChain& refch)
9650 {
9651 if (checked) return;
9652 if (valuetype != V_OID || u.oid_comps->size() < 1)
9653 FATAL_ERROR("Value::chk_OID()");
9654 if (!refch.add(get_fullname())) {
9655 checked = true;
9656 return;
9657 }
9658 OID_comp::oidstate_t state = OID_comp::START;
9659 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9660 refch.mark_state();
9661 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9662 refch.prev_state();
9663 }
9664 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9665 error("An OBJECT IDENTIFIER value must have at least "
9666 "two components"); // X.680 (07/2002) 31.10
9667 }
9668
9669 void Value::chk_ROID(ReferenceChain& refch)
9670 {
9671 if (checked) return;
9672 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9673 FATAL_ERROR("Value::chk_ROID()");
9674 if (!refch.add(get_fullname())) {
9675 checked = true;
9676 return;
9677 }
9678 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9679 refch.mark_state();
9680 (*u.oid_comps)[i]->chk_ROID(refch, i);
9681 refch.prev_state();
9682 }
9683 }
9684
9685 void Value::chk_recursions(ReferenceChain& refch)
9686 {
9687 if (recurs_checked) return;
9688 Value *v = get_value_refd_last();
9689 if (refch.add(v->get_fullname())) {
9690 switch (v->valuetype) {
9691 case V_CHOICE:
9692 v->u.choice.alt_value->chk_recursions(refch);
9693 break;
9694 case V_SEQOF:
9695 case V_SETOF:
9696 case V_ARRAY:
9697 if (!v->is_indexed()) {
9698 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9699 refch.mark_state();
9700 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9701 refch.prev_state();
9702 }
9703 } else {
9704 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9705 refch.mark_state();
9706 v->u.val_vs->get_iv_byIndex(i)->get_value()
9707 ->chk_recursions(refch);
9708 refch.prev_state();
9709 }
9710 }
9711 break;
9712 case V_SEQ:
9713 case V_SET:
9714 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9715 refch.mark_state();
9716 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9717 refch.prev_state();
9718 }
9719 break;
9720 case V_EXPR:
9721 chk_recursions_expr(refch);
9722 break;
9723 default:
9724 break;
9725 }
9726 if (v->err_descr) { // FIXME: make this work
9727 v->err_descr->chk_recursions(refch);
9728 }
9729 }
9730 recurs_checked = true;
9731 }
9732
9733 void Value::chk_recursions_expr(ReferenceChain& refch)
9734 {
9735 // first classify the unchecked ischosen() operation
9736 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9737 switch (u.expr.v_optype) {
9738 case OPTYPE_UNARYPLUS: // v1
9739 case OPTYPE_UNARYMINUS:
9740 case OPTYPE_NOT:
9741 case OPTYPE_NOT4B:
9742 case OPTYPE_BIT2HEX:
9743 case OPTYPE_BIT2INT:
9744 case OPTYPE_BIT2OCT:
9745 case OPTYPE_BIT2STR:
9746 case OPTYPE_CHAR2INT:
9747 case OPTYPE_CHAR2OCT:
9748 case OPTYPE_FLOAT2INT:
9749 case OPTYPE_FLOAT2STR:
9750 case OPTYPE_HEX2BIT:
9751 case OPTYPE_HEX2INT:
9752 case OPTYPE_HEX2OCT:
9753 case OPTYPE_HEX2STR:
9754 case OPTYPE_INT2CHAR:
9755 case OPTYPE_INT2FLOAT:
9756 case OPTYPE_INT2STR:
9757 case OPTYPE_INT2UNICHAR:
9758 case OPTYPE_OCT2BIT:
9759 case OPTYPE_OCT2CHAR:
9760 case OPTYPE_OCT2HEX:
9761 case OPTYPE_OCT2INT:
9762 case OPTYPE_OCT2STR:
9763 case OPTYPE_STR2BIT:
9764 case OPTYPE_STR2FLOAT:
9765 case OPTYPE_STR2HEX:
9766 case OPTYPE_STR2INT:
9767 case OPTYPE_STR2OCT:
9768 case OPTYPE_UNICHAR2INT:
9769 case OPTYPE_ENUM2INT:
9770 case OPTYPE_UNICHAR2CHAR:
9771 case OPTYPE_RNDWITHVAL:
9772 case OPTYPE_ISCHOSEN_V:
9773 case OPTYPE_GET_STRINGENCODING:
9774 case OPTYPE_REMOVE_BOM:
9775 case OPTYPE_DECODE_BASE64:
9776 refch.mark_state();
9777 u.expr.v1->chk_recursions(refch);
9778 refch.prev_state();
9779 break;
9780 case OPTYPE_ISCHOSEN_T:
9781 refch.mark_state();
9782 u.expr.t1->chk_recursions(refch);
9783 refch.prev_state();
9784 break;
9785 case OPTYPE_ADD: // v1 v2
9786 case OPTYPE_SUBTRACT:
9787 case OPTYPE_MULTIPLY:
9788 case OPTYPE_DIVIDE:
9789 case OPTYPE_MOD:
9790 case OPTYPE_REM:
9791 case OPTYPE_CONCAT:
9792 case OPTYPE_EQ:
9793 case OPTYPE_LT:
9794 case OPTYPE_GT:
9795 case OPTYPE_NE:
9796 case OPTYPE_GE:
9797 case OPTYPE_LE:
9798 case OPTYPE_AND:
9799 case OPTYPE_OR:
9800 case OPTYPE_XOR:
9801 case OPTYPE_AND4B:
9802 case OPTYPE_OR4B:
9803 case OPTYPE_XOR4B:
9804 case OPTYPE_SHL:
9805 case OPTYPE_SHR:
9806 case OPTYPE_ROTL:
9807 case OPTYPE_ROTR:
9808 case OPTYPE_INT2BIT:
9809 case OPTYPE_INT2HEX:
9810 case OPTYPE_INT2OCT:
9811 refch.mark_state();
9812 u.expr.v1->chk_recursions(refch);
9813 refch.prev_state();
9814 refch.mark_state();
9815 u.expr.v2->chk_recursions(refch);
9816 refch.prev_state();
9817 break;
9818 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9819 case OPTYPE_OCT2UNICHAR:
9820 case OPTYPE_ENCODE_BASE64:
9821 refch.mark_state();
9822 u.expr.v1->chk_recursions(refch);
9823 refch.prev_state();
9824 if (u.expr.v2) {
9825 refch.mark_state();
9826 u.expr.v2->chk_recursions(refch);
9827 refch.prev_state();
9828 }
9829 break;
9830 case OPTYPE_DECODE:
9831 chk_recursions_expr_decode(u.expr.r1, refch);
9832 chk_recursions_expr_decode(u.expr.r2, refch);
9833 break;
9834 case OPTYPE_SUBSTR:
9835 refch.mark_state();
9836 u.expr.ti1->chk_recursions(refch);
9837 refch.prev_state();
9838 refch.mark_state();
9839 u.expr.v2->chk_recursions(refch);
9840 refch.prev_state();
9841 refch.mark_state();
9842 u.expr.v3->chk_recursions(refch);
9843 refch.prev_state();
9844 break;
9845 case OPTYPE_REGEXP:
9846 refch.mark_state();
9847 u.expr.ti1->chk_recursions(refch);
9848 refch.prev_state();
9849 refch.mark_state();
9850 u.expr.t2->chk_recursions(refch);
9851 refch.prev_state();
9852 refch.mark_state();
9853 u.expr.v3->chk_recursions(refch);
9854 refch.prev_state();
9855 break;
9856 case OPTYPE_DECOMP: // v1 v2 v3
9857 refch.mark_state();
9858 u.expr.v1->chk_recursions(refch);
9859 refch.prev_state();
9860 refch.mark_state();
9861 u.expr.v2->chk_recursions(refch);
9862 refch.prev_state();
9863 refch.mark_state();
9864 u.expr.v3->chk_recursions(refch);
9865 refch.prev_state();
9866 break;
9867 case OPTYPE_REPLACE:
9868 refch.mark_state();
9869 u.expr.ti1->chk_recursions(refch);
9870 refch.prev_state();
9871 refch.mark_state();
9872 u.expr.v2->chk_recursions(refch);
9873 refch.prev_state();
9874 refch.mark_state();
9875 u.expr.v3->chk_recursions(refch);
9876 refch.prev_state();
9877 refch.mark_state();
9878 u.expr.ti4->chk_recursions(refch);
9879 refch.prev_state();
9880 break;
9881 case OPTYPE_LENGTHOF: // ti1
9882 case OPTYPE_SIZEOF: // ti1
9883 case OPTYPE_VALUEOF: // ti1
9884 case OPTYPE_ENCODE:
9885 case OPTYPE_ISPRESENT:
9886 case OPTYPE_TTCN2STRING:
9887 refch.mark_state();
9888 u.expr.ti1->chk_recursions(refch);
9889 refch.prev_state();
9890 break;
9891 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
9892 refch.mark_state();
9893 u.expr.ti1->chk_recursions(refch);
9894 refch.prev_state();
9895 if (u.expr.v2){
9896 refch.mark_state();
9897 u.expr.v2->chk_recursions(refch);
9898 refch.prev_state();
9899 }
9900 break;
9901 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
9902 chk_recursions_expr_decode(u.expr.r1, refch);
9903 chk_recursions_expr_decode(u.expr.r2, refch);
9904 if (u.expr.v3){
9905 refch.mark_state();
9906 u.expr.v3->chk_recursions(refch);
9907 refch.prev_state();
9908 }
9909 break;
9910 case OPTYPE_MATCH: // v1 t2
9911 refch.mark_state();
9912 u.expr.v1->chk_recursions(refch);
9913 refch.prev_state();
9914 refch.mark_state();
9915 u.expr.t2->chk_recursions(refch);
9916 refch.prev_state();
9917 break;
9918 case OPTYPE_LOG2STR:
9919 case OPTYPE_ANY2UNISTR:
9920 u.expr.logargs->chk_recursions(refch);
9921 break;
9922 default:
9923 break;
9924 } // switch
9925 }
9926
9927 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9928 ReferenceChain& refch) {
9929 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9930 Assignment *ass = ref->get_refd_assignment();
9931 if (!ass) {
9932 set_valuetype(V_ERROR);
9933 return;
9934 }
9935 switch (ass->get_asstype()) {
9936 case Assignment::A_CONST:
9937 case Assignment::A_EXT_CONST:
9938 case Assignment::A_MODULEPAR:
9939 case Assignment::A_VAR:
9940 case Assignment::A_PAR_VAL_IN:
9941 case Assignment::A_PAR_VAL_OUT:
9942 case Assignment::A_PAR_VAL_INOUT: {
9943 Value* v = new Value(V_REFD, ref);
9944 v->set_location(*ref);
9945 v->set_my_scope(get_my_scope());
9946 v->set_fullname(get_fullname()+".<operand>");
9947 refch.mark_state();
9948 v->chk_recursions(refch);
9949 refch.prev_state();
9950 delete v;
9951 break; }
9952 case Assignment::A_MODULEPAR_TEMP:
9953 case Assignment::A_TEMPLATE:
9954 case Assignment::A_VAR_TEMPLATE:
9955 case Assignment::A_PAR_TEMPL_IN:
9956 case Assignment::A_PAR_TEMPL_OUT:
9957 case Assignment::A_PAR_TEMPL_INOUT: {
9958 Template* t = new Template(ref->clone());
9959 t->set_location(*ref);
9960 t->set_my_scope(get_my_scope());
9961 t->set_fullname(get_fullname()+".<operand>");
9962 refch.mark_state();
9963 t->chk_recursions(refch);
9964 refch.prev_state();
9965 delete t;
9966 break; }
9967 default:
9968 // remain silent, the error has been already reported
9969 set_valuetype(V_ERROR);
9970 break;
9971 } // switch
9972 }
9973
9974 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
9975 {
9976 bool self_ref = false;
9977 switch (t->get_templatetype()) {
9978 case Ttcn::Template::SPECIFIC_VALUE: {
9979 Value *v = t->get_specific_value();
9980 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
9981 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
9982 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
9983 break; }
9984 case Ttcn::Template::TEMPLATE_REFD: {
9985 Ttcn::Ref_base *refb = t->get_reference();
9986 Common::Assignment *ass = refb->get_refd_assignment();
9987 self_ref |= (ass == lhs);
9988 break; }
9989 case Ttcn::Template::ALL_FROM:
9990 case Ttcn::Template::VALUE_LIST_ALL_FROM:
9991 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
9992 break;
9993 case Ttcn::Template::TEMPLATE_LIST:
9994 case Ttcn::Template::SUPERSET_MATCH:
9995 case Ttcn::Template::SUBSET_MATCH:
9996 case Ttcn::Template::PERMUTATION_MATCH:
9997 case Ttcn::Template::COMPLEMENTED_LIST:
9998 case Ttcn::Template::VALUE_LIST: {
9999 size_t num = t->get_nof_comps();
10000 for (size_t i = 0; i < num; ++i) {
10001 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
10002 }
10003 break; }
10004 // not yet clear whether we should use this or the above for TEMPLATE_LIST
10005 // case Ttcn::Template::TEMPLATE_LIST: {
10006 // size_t num = t->get_nof_listitems();
10007 // for (size_t i=0; i < num; ++i) {
10008 // self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
10009 // }
10010 // break; }
10011 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
10012 size_t nnt = t->get_nof_comps();
10013 for (size_t i=0; i < nnt; ++i) {
10014 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
10015 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
10016 }
10017 break; }
10018 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
10019 size_t nnt = t->get_nof_comps();
10020 for (size_t i=0; i < nnt; ++i) {
10021 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
10022 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
10023 }
10024 break; }
10025 case Ttcn::Template::VALUE_RANGE: {
10026 Ttcn::ValueRange *vr = t->get_value_range();
10027 Common::Value *v = vr->get_min_v();
10028 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
10029 v = vr->get_max_v();
10030 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
10031 break; }
10032 case Ttcn::Template::CSTR_PATTERN:
10033 case Ttcn::Template::USTR_PATTERN: {
10034 Ttcn::PatternString *ps = t->get_cstr_pattern();
10035 self_ref |= ps->chk_self_ref(lhs);
10036 break; }
10037 case Ttcn::Template::BSTR_PATTERN:
10038 case Ttcn::Template::HSTR_PATTERN:
10039 case Ttcn::Template::OSTR_PATTERN: {
10040 // FIXME: cannot access u.pattern
10041 break; }
10042 case Ttcn::Template::ANY_VALUE:
10043 case Ttcn::Template::ANY_OR_OMIT:
10044 case Ttcn::Template::OMIT_VALUE:
10045 case Ttcn::Template::TEMPLATE_NOTUSED:
10046 break; // self-ref can't happen
10047 case Ttcn::Template::TEMPLATE_INVOKE:
10048 break; // assume self-ref can't happen
10049 case Ttcn::Template::TEMPLATE_ERROR:
10050 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
10051 break;
10052 // default:
10053 // FATAL_ERROR("todo ttype %d", t->get_templatetype());
10054 // break; // and hope for the best
10055 }
10056 return self_ref;
10057 }
10058
10059 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
10060 {
10061 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
10062 namedbool is_str_elem = NOT_STR_ELEM;
10063 if (v->valuetype == V_REFD) {
10064 Reference *ref = v->get_reference();
10065 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
10066 if (subrefs && subrefs->refers_to_string_element()) {
10067 is_str_elem = IS_STR_ELEM;
10068 }
10069 }
10070 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
10071 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
10072 is_str_elem);
10073 }
10074
10075 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
10076 {
10077 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
10078 if (!lhs) FATAL_ERROR("no lhs!");
10079 bool self_ref = false;
10080 switch (u.expr.v_optype) {
10081 case OPTYPE_RND: // -
10082 case OPTYPE_TESTCASENAME: // -
10083 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
10084 case OPTYPE_COMP_MTC: // -
10085 case OPTYPE_COMP_SYSTEM: // -
10086 case OPTYPE_COMP_SELF: // -
10087 case OPTYPE_COMP_RUNNING_ANY: // -
10088 case OPTYPE_COMP_RUNNING_ALL: // -
10089 case OPTYPE_COMP_ALIVE_ANY: // -
10090 case OPTYPE_COMP_ALIVE_ALL: // -
10091 case OPTYPE_TMR_RUNNING_ANY: // -
10092 case OPTYPE_GETVERDICT: // -
10093 case OPTYPE_PROF_RUNNING: // -
10094 case OPTYPE_CHECKSTATE_ANY:
10095 case OPTYPE_CHECKSTATE_ALL:
10096 break; // nothing to do
10097
10098 case OPTYPE_MATCH: // v1 t2
10099 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
10100 // no break
10101 case OPTYPE_UNARYPLUS: // v1
10102 case OPTYPE_UNARYMINUS: // v1
10103 case OPTYPE_NOT: // v1
10104 case OPTYPE_NOT4B: // v1
10105 case OPTYPE_BIT2HEX: // v1
10106 case OPTYPE_BIT2INT: // v1
10107 case OPTYPE_BIT2OCT: // v1
10108 case OPTYPE_BIT2STR: // v1
10109 case OPTYPE_CHAR2INT: // v1
10110 case OPTYPE_CHAR2OCT: // v1
10111 case OPTYPE_FLOAT2INT: // v1
10112 case OPTYPE_FLOAT2STR: // v1
10113 case OPTYPE_HEX2BIT: // v1
10114 case OPTYPE_HEX2INT: // v1
10115 case OPTYPE_HEX2OCT: // v1
10116 case OPTYPE_HEX2STR: // v1
10117 case OPTYPE_INT2CHAR: // v1
10118 case OPTYPE_INT2FLOAT: // v1
10119 case OPTYPE_INT2STR: // v1
10120 case OPTYPE_INT2UNICHAR: // v1
10121 case OPTYPE_OCT2BIT: // v1
10122 case OPTYPE_OCT2CHAR: // v1
10123 case OPTYPE_OCT2HEX: // v1
10124 case OPTYPE_OCT2INT: // v1
10125 case OPTYPE_OCT2STR: // v1
10126 case OPTYPE_STR2BIT: // v1
10127 case OPTYPE_STR2FLOAT: // v1
10128 case OPTYPE_STR2HEX: // v1
10129 case OPTYPE_STR2INT: // v1
10130 case OPTYPE_STR2OCT: // v1
10131 case OPTYPE_UNICHAR2INT: // v1
10132 case OPTYPE_UNICHAR2CHAR: // v1
10133 case OPTYPE_ENUM2INT: // v1
10134 case OPTYPE_RNDWITHVAL: // v1
10135 case OPTYPE_COMP_RUNNING: // v1
10136 case OPTYPE_COMP_ALIVE: // v1
10137 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
10138 case OPTYPE_GET_STRINGENCODING:
10139 case OPTYPE_DECODE_BASE64:
10140 case OPTYPE_REMOVE_BOM:
10141 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10142 break;
10143 case OPTYPE_ADD: // v1 v2
10144 case OPTYPE_SUBTRACT: // v1 v2
10145 case OPTYPE_MULTIPLY: // v1 v2
10146 case OPTYPE_DIVIDE: // v1 v2
10147 case OPTYPE_MOD: // v1 v2
10148 case OPTYPE_REM: // v1 v2
10149 case OPTYPE_CONCAT: // v1 v2
10150 case OPTYPE_EQ: // v1 v2
10151 case OPTYPE_LT: // v1 v2
10152 case OPTYPE_GT: // v1 v2
10153 case OPTYPE_NE: // v1 v2
10154 case OPTYPE_GE: // v1 v2
10155 case OPTYPE_LE: // v1 v2
10156 case OPTYPE_AND: // v1 v2
10157 case OPTYPE_OR: // v1 v2
10158 case OPTYPE_XOR: // v1 v2
10159 case OPTYPE_AND4B: // v1 v2
10160 case OPTYPE_OR4B: // v1 v2
10161 case OPTYPE_XOR4B: // v1 v2
10162 case OPTYPE_SHL: // v1 v2
10163 case OPTYPE_SHR: // v1 v2
10164 case OPTYPE_ROTL: // v1 v2
10165 case OPTYPE_ROTR: // v1 v2
10166 case OPTYPE_INT2BIT: // v1 v2
10167 case OPTYPE_INT2HEX: // v1 v2
10168 case OPTYPE_INT2OCT: // v1 v2
10169 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10170 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10171 break;
10172 case OPTYPE_UNICHAR2OCT: // v1 [v2]
10173 case OPTYPE_OCT2UNICHAR:
10174 case OPTYPE_ENCODE_BASE64:
10175 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10176 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10177 break;
10178 case OPTYPE_DECOMP: // v1 v2 v3
10179 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10180 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10181 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10182 break;
10183
10184 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
10185 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
10186 // no break
10187 case OPTYPE_SUBSTR: // ti1 v2 v3
10188 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10189 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
10190 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
10191 break;
10192
10193 case OPTYPE_REGEXP: // ti1 t2 v3
10194 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10195 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
10196 // no break
10197 case OPTYPE_LENGTHOF: // ti1
10198 case OPTYPE_SIZEOF: // ti1
10199 case OPTYPE_VALUEOF: // ti1
10200 case OPTYPE_ENCODE: // ti1
10201 case OPTYPE_TTCN2STRING:
10202 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10203 break;
10204 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
10205 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10206 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10207 break;
10208 case OPTYPE_DECVALUE_UNICHAR: { // r1 r2 [v3]
10209 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10210 self_ref |= (ass == lhs);
10211 if (u.expr.v3) self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10212 goto label_r1;
10213 break; }
10214 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
10215 // component.create -- assume no self-ref
10216 case OPTYPE_ACTIVATE: // r1
10217 // defaultref := activate(altstep) -- assume no self-ref
10218 case OPTYPE_TMR_RUNNING: // r1
10219 // boolvar := a_timer.running -- assume no self-ref
10220 break;
10221 break;
10222
10223 case OPTYPE_ANY2UNISTR:
10224 case OPTYPE_LOG2STR: {// logargs
10225 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
10226 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
10227 switch (la->get_type()) {
10228 case Ttcn::LogArgument::L_UNDEF:
10229 case Ttcn::LogArgument::L_ERROR:
10230 FATAL_ERROR("%s argument type",
10231 u.expr.v_optype == OPTYPE_ANY2UNISTR ? "any2unistr" : "log2str");
10232 break; // not reached
10233
10234 case Ttcn::LogArgument::L_MACRO:
10235 case Ttcn::LogArgument::L_STR:
10236 break; // self reference not possible
10237
10238 case Ttcn::LogArgument::L_VAL:
10239 case Ttcn::LogArgument::L_MATCH:
10240 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
10241 break;
10242
10243 case Ttcn::LogArgument::L_REF: {
10244 Ttcn::Ref_base *ref = la->get_ref();
10245 Common::Assignment *ass = ref->get_refd_assignment();
10246 self_ref |= (ass == lhs);
10247 break; }
10248
10249 case Ttcn::LogArgument::L_TI: {
10250 Ttcn::TemplateInstance *ti = la->get_ti();
10251 Ttcn::Template *t = ti->get_Template();
10252 self_ref |= chk_expr_self_ref_templ(t, lhs);
10253 break; }
10254
10255 // no default please
10256 } // switch la->logargtype
10257 }
10258 break; }
10259
10260 case OPTYPE_DECODE: { // r1 r2
10261 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10262 self_ref |= (ass == lhs);
10263 goto label_r1; }
10264 case OPTYPE_EXECUTE: // r1 [v2]
10265 if (u.expr.v2) {
10266 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10267 }
10268 label_r1:
10269 // no break
10270 case OPTYPE_UNDEF_RUNNING: // r1
10271 case OPTYPE_TMR_READ: { // r1
10272 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
10273 self_ref |= (ass == lhs);
10274 break; }
10275
10276 case OPTYPE_ISCHOSEN_T: // t1 i2
10277 case OPTYPE_ISBOUND: // ti1
10278 case OPTYPE_ISVALUE: // ti1
10279 case OPTYPE_ISPRESENT: { // ti1
10280 Ttcn::Template *t;
10281 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10282 else t = u.expr.ti1->get_Template();
10283 self_ref |= chk_expr_self_ref_templ(t, lhs);
10284 break; }
10285
10286 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10287 if (u.expr.v3) {
10288 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10289 }
10290 // no break
10291 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10292 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10293 // TODO t_list2
10294 break;
10295
10296 case NUMBER_OF_OPTYPES: // can never happen
10297 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10298 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10299 break;
10300 } // switch u.expr.v_optype
10301 return self_ref;
10302 }
10303
10304
10305 string Value::create_stringRepr()
10306 {
10307 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
10308 switch (valuetype) {
10309 case V_ERROR:
10310 return string("<erroneous>");
10311 case V_NULL:
10312 return string("NULL");
10313 case V_BOOL:
10314 if (!parse_only && is_asn1()) {
10315 if (u.val_bool) return string("TRUE");
10316 else return string("FALSE");
10317 }
10318 else {
10319 if (u.val_bool) return string("true");
10320 else return string("false");
10321 }
10322 case V_INT:
10323 return u.val_Int->t_str();
10324 case V_REAL:
10325 return Real2string(u.val_Real);
10326 case V_ENUM:
10327 case V_NAMEDINT:
10328 case V_UNDEF_LOWERID:
10329 return u.val_id->get_name();
10330 case V_NAMEDBITS: {
10331 string ret_val("{ ");
10332 for (size_t i = 0; i < u.ids->size(); i++) {
10333 if (i>0) ret_val += ' ';
10334 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10335 }
10336 ret_val += '}';
10337 return ret_val; }
10338 case V_BSTR: {
10339 string ret_val('\'');
10340 ret_val += *u.str.val_str;
10341 ret_val += "'B";
10342 return ret_val; }
10343 case V_HSTR: {
10344 string ret_val('\'');
10345 ret_val += *u.str.val_str;
10346 ret_val += "'H";
10347 return ret_val; }
10348 case V_OSTR: {
10349 string ret_val('\'');
10350 ret_val += *u.str.val_str;
10351 ret_val += "'O";
10352 return ret_val; }
10353 case V_CSTR:
10354 case V_ISO2022STR:
10355 return u.str.val_str->get_stringRepr();
10356 case V_USTR:
10357 return u.ustr.val_ustr->get_stringRepr();
10358 case V_CHARSYMS:
10359 /** \todo stringrepr of V_CHARSYMS */
10360 return string("<sorry, string representation of charsyms "
10361 "not implemented>");
10362 case V_OID:
10363 case V_ROID: {
10364 string ret_val;
10365 if (parse_only || !is_asn1()) ret_val += "objid ";
10366 ret_val += "{ ";
10367 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10368 if (i>0) ret_val += ' ';
10369 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10370 }
10371 ret_val += " }";
10372 return ret_val; }
10373 case V_CHOICE:
10374 if (!parse_only && is_asn1()) {
10375 string ret_val(u.choice.alt_name->get_dispname());
10376 ret_val += " : ";
10377 ret_val += u.choice.alt_value->get_stringRepr();
10378 return ret_val;
10379 }
10380 else {
10381 string ret_val("{ ");
10382 ret_val += u.choice.alt_name->get_dispname();
10383 ret_val += " := ";
10384 ret_val += u.choice.alt_value->get_stringRepr();
10385 ret_val += " }";
10386 return ret_val;
10387 }
10388 case V_SEQOF:
10389 case V_SETOF:
10390 case V_ARRAY: {
10391 string ret_val("{ ");
10392 if (!is_indexed()) {
10393 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10394 if (i > 0) ret_val += ", ";
10395 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10396 }
10397 } else {
10398 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10399 if (i > 0) ret_val += ", ";
10400 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10401 }
10402 }
10403 ret_val += " }";
10404 return ret_val; }
10405 case V_SEQ:
10406 case V_SET: {
10407 string ret_val("{ ");
10408 bool asn1_flag = !parse_only && is_asn1();
10409 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10410 if (i > 0) ret_val += ", ";
10411 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10412 ret_val += nv->get_name().get_dispname();
10413 if (asn1_flag) ret_val += ' ';
10414 else ret_val += " := ";
10415 ret_val += nv->get_value()->get_stringRepr();
10416 }
10417 ret_val += " }";
10418 return ret_val; }
10419 case V_REFD: {
10420 // do not evaluate the reference if it is not done so far
10421 // (e.g. in parse-only mode)
10422 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10423 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10424 else return t_val->get_stringRepr(); }
10425 case V_OMIT:
10426 return string("omit");
10427 case V_VERDICT:
10428 switch (u.verdict) {
10429 case Verdict_NONE:
10430 return string("none");
10431 case Verdict_PASS:
10432 return string("pass");
10433 case Verdict_INCONC:
10434 return string("inconc");
10435 case Verdict_FAIL:
10436 return string("fail");
10437 case Verdict_ERROR:
10438 return string("error");
10439 default:
10440 return string("<unknown verdict value>");
10441 }
10442 case V_DEFAULT_NULL:
10443 case V_FAT_NULL:
10444 return string("null");
10445 case V_EXPR:
10446 switch (u.expr.v_optype) {
10447 case OPTYPE_RND:
10448 return string("rnd()");
10449 case OPTYPE_TESTCASENAME:
10450 return string("testcasename()");
10451 case OPTYPE_UNARYPLUS:
10452 return create_stringRepr_unary("+");
10453 case OPTYPE_UNARYMINUS:
10454 return create_stringRepr_unary("-");
10455 case OPTYPE_NOT:
10456 return create_stringRepr_unary("not");
10457 case OPTYPE_NOT4B:
10458 return create_stringRepr_unary("not4b");
10459 case OPTYPE_BIT2HEX:
10460 return create_stringRepr_predef1("bit2hex");
10461 case OPTYPE_BIT2INT:
10462 return create_stringRepr_predef1("bit2int");
10463 case OPTYPE_BIT2OCT:
10464 return create_stringRepr_predef1("bit2oct");
10465 case OPTYPE_BIT2STR:
10466 return create_stringRepr_predef1("bit2str");
10467 case OPTYPE_CHAR2INT:
10468 return create_stringRepr_predef1("char2int");
10469 case OPTYPE_CHAR2OCT:
10470 return create_stringRepr_predef1("char2oct");
10471 case OPTYPE_FLOAT2INT:
10472 return create_stringRepr_predef1("float2int");
10473 case OPTYPE_FLOAT2STR:
10474 return create_stringRepr_predef1("float2str");
10475 case OPTYPE_HEX2BIT:
10476 return create_stringRepr_predef1("hex2bit");
10477 case OPTYPE_HEX2INT:
10478 return create_stringRepr_predef1("hex2int");
10479 case OPTYPE_HEX2OCT:
10480 return create_stringRepr_predef1("hex2oct");
10481 case OPTYPE_HEX2STR:
10482 return create_stringRepr_predef1("hex2str");
10483 case OPTYPE_INT2CHAR:
10484 return create_stringRepr_predef1("int2char");
10485 case OPTYPE_INT2FLOAT:
10486 return create_stringRepr_predef1("int2float");
10487 case OPTYPE_INT2STR:
10488 return create_stringRepr_predef1("int2str");
10489 case OPTYPE_INT2UNICHAR:
10490 return create_stringRepr_predef1("int2unichar");
10491 case OPTYPE_OCT2BIT:
10492 return create_stringRepr_predef1("oct2bit");
10493 case OPTYPE_OCT2CHAR:
10494 return create_stringRepr_predef1("oct2char");
10495 case OPTYPE_OCT2HEX:
10496 return create_stringRepr_predef1("oct2hex");
10497 case OPTYPE_OCT2INT:
10498 return create_stringRepr_predef1("oct2int");
10499 case OPTYPE_OCT2STR:
10500 return create_stringRepr_predef1("oct2str");
10501 case OPTYPE_GET_STRINGENCODING:
10502 return create_stringRepr_predef1("get_stringencoding");
10503 case OPTYPE_REMOVE_BOM:
10504 return create_stringRepr_predef1("remove_bom");
10505 case OPTYPE_ENCODE_BASE64: {
10506 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10507 else return create_stringRepr_predef1("encode_base64");
10508 }
10509 case OPTYPE_DECODE_BASE64:
10510 return create_stringRepr_predef1("decode_base64");
10511 case OPTYPE_OCT2UNICHAR:{
10512 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10513 else return create_stringRepr_predef1("oct2unichar");
10514 }
10515 case OPTYPE_UNICHAR2OCT: {
10516 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10517 else return create_stringRepr_predef1("unichar2oct");
10518 }
10519 case OPTYPE_ENCVALUE_UNICHAR: {
10520 if (u.expr.v2) return create_stringRepr_predef2("encvalue_unichar");
10521 else return create_stringRepr_predef1("encvalue_unichar");
10522 }
10523 case OPTYPE_DECVALUE_UNICHAR: {
10524 if (u.expr.v3) {
10525 string ret_val("decvalue_unichar");
10526 ret_val += '(';
10527 ret_val += u.expr.v1->get_stringRepr();
10528 ret_val += ", ";
10529 ret_val += u.expr.v2->get_stringRepr();
10530 ret_val += ", ";
10531 ret_val += u.expr.v3->get_stringRepr();
10532 ret_val += ')';
10533 return ret_val;
10534 }
10535 else return create_stringRepr_predef2("decvalue_unichar");
10536 }
10537 case OPTYPE_STR2BIT:
10538 return create_stringRepr_predef1("str2bit");
10539 case OPTYPE_STR2FLOAT:
10540 return create_stringRepr_predef1("str2float");
10541 case OPTYPE_STR2HEX:
10542 return create_stringRepr_predef1("str2hex");
10543 case OPTYPE_STR2INT:
10544 return create_stringRepr_predef1("str2int");
10545 case OPTYPE_STR2OCT:
10546 return create_stringRepr_predef1("str2oct");
10547 case OPTYPE_UNICHAR2INT:
10548 return create_stringRepr_predef1("unichar2int");
10549 case OPTYPE_UNICHAR2CHAR:
10550 return create_stringRepr_predef1("unichar2char");
10551 case OPTYPE_ENUM2INT:
10552 return create_stringRepr_predef1("enum2int");
10553 case OPTYPE_ENCODE:
10554 return create_stringRepr_predef1("encvalue");
10555 case OPTYPE_DECODE:
10556 return create_stringRepr_predef2("decvalue");
10557 case OPTYPE_RNDWITHVAL:
10558 return create_stringRepr_predef1("rnd");
10559 case OPTYPE_ADD:
10560 return create_stringRepr_infix("+");
10561 case OPTYPE_SUBTRACT:
10562 return create_stringRepr_infix("-");
10563 case OPTYPE_MULTIPLY:
10564 return create_stringRepr_infix("*");
10565 case OPTYPE_DIVIDE:
10566 return create_stringRepr_infix("/");
10567 case OPTYPE_MOD:
10568 return create_stringRepr_infix("mod");
10569 case OPTYPE_REM:
10570 return create_stringRepr_infix("rem");
10571 case OPTYPE_CONCAT:
10572 return create_stringRepr_infix("&");
10573 case OPTYPE_EQ:
10574 return create_stringRepr_infix("==");
10575 case OPTYPE_LT:
10576 return create_stringRepr_infix("<");
10577 case OPTYPE_GT:
10578 return create_stringRepr_infix(">");
10579 case OPTYPE_NE:
10580 return create_stringRepr_infix("!=");
10581 case OPTYPE_GE:
10582 return create_stringRepr_infix(">=");
10583 case OPTYPE_LE:
10584 return create_stringRepr_infix("<=");
10585 case OPTYPE_AND:
10586 return create_stringRepr_infix("and");
10587 case OPTYPE_OR:
10588 return create_stringRepr_infix("or");
10589 case OPTYPE_XOR:
10590 return create_stringRepr_infix("xor");
10591 case OPTYPE_AND4B:
10592 return create_stringRepr_infix("and4b");
10593 case OPTYPE_OR4B:
10594 return create_stringRepr_infix("or4b");
10595 case OPTYPE_XOR4B:
10596 return create_stringRepr_infix("xor4b");
10597 case OPTYPE_SHL:
10598 return create_stringRepr_infix("<<");
10599 case OPTYPE_SHR:
10600 return create_stringRepr_infix(">>");
10601 case OPTYPE_ROTL:
10602 return create_stringRepr_infix("<@");
10603 case OPTYPE_ROTR:
10604 return create_stringRepr_infix("@>");
10605 case OPTYPE_INT2BIT:
10606 return create_stringRepr_predef2("int2bit");
10607 case OPTYPE_INT2HEX:
10608 return create_stringRepr_predef2("int2hex");
10609 case OPTYPE_INT2OCT:
10610 return create_stringRepr_predef2("int2oct");
10611 case OPTYPE_SUBSTR: {
10612 string ret_val("substr(");
10613 u.expr.ti1->append_stringRepr(ret_val);
10614 ret_val += ", ";
10615 ret_val += u.expr.v2->get_stringRepr();
10616 ret_val += ", ";
10617 ret_val += u.expr.v3->get_stringRepr();
10618 ret_val += ')';
10619 return ret_val;
10620 }
10621 case OPTYPE_REGEXP: {
10622 string ret_val("regexp(");
10623 u.expr.ti1->append_stringRepr(ret_val);
10624 ret_val += ", ";
10625 u.expr.t2->append_stringRepr(ret_val);
10626 ret_val += ", ";
10627 ret_val += u.expr.v3->get_stringRepr();
10628 ret_val += ')';
10629 return ret_val;
10630 }
10631 case OPTYPE_DECOMP: {
10632 string ret_val("decomp(");
10633 ret_val += u.expr.v1->get_stringRepr();
10634 ret_val += ", ";
10635 ret_val += u.expr.v2->get_stringRepr();
10636 ret_val += ", ";
10637 ret_val += u.expr.v3->get_stringRepr();
10638 ret_val += ')';
10639 return ret_val;
10640 }
10641 case OPTYPE_REPLACE: {
10642 string ret_val("replace(");
10643 u.expr.ti1->append_stringRepr(ret_val);
10644 ret_val += ", ";
10645 ret_val += u.expr.v2->get_stringRepr();
10646 ret_val += ", ";
10647 ret_val += u.expr.v3->get_stringRepr();
10648 ret_val += ", ";
10649 u.expr.ti4->append_stringRepr(ret_val);
10650 ret_val += ')';
10651 return ret_val;
10652 }
10653 case OPTYPE_ISPRESENT: {
10654 string ret_val("ispresent(");
10655 u.expr.ti1->append_stringRepr(ret_val);
10656 ret_val += ')';
10657 return ret_val; }
10658 case OPTYPE_ISCHOSEN: {
10659 string ret_val("ischosen(");
10660 ret_val += u.expr.r1->get_dispname();
10661 ret_val += '.';
10662 ret_val += u.expr.i2->get_dispname();
10663 ret_val += ')';
10664 return ret_val; }
10665 case OPTYPE_ISCHOSEN_V: {
10666 string ret_val("ischosen(");
10667 ret_val += u.expr.v1->get_stringRepr();
10668 ret_val += '.';
10669 ret_val += u.expr.i2->get_dispname();
10670 ret_val += ')';
10671 return ret_val; }
10672 case OPTYPE_ISCHOSEN_T: {
10673 string ret_val("ischosen(");
10674 ret_val += u.expr.t1->get_stringRepr();
10675 ret_val += '.';
10676 ret_val += u.expr.i2->get_dispname();
10677 ret_val += ')';
10678 return ret_val; }
10679 case OPTYPE_LENGTHOF: {
10680 string ret_val("lengthof(");
10681 u.expr.ti1->append_stringRepr(ret_val);
10682 ret_val += ')';
10683 return ret_val; }
10684 case OPTYPE_SIZEOF: {
10685 string ret_val("sizeof(");
10686 u.expr.ti1->append_stringRepr(ret_val);
10687 ret_val += ')';
10688 return ret_val; }
10689 case OPTYPE_ISVALUE: {
10690 string ret_val("isvalue(");
10691 u.expr.ti1->append_stringRepr(ret_val);
10692 ret_val += ')';
10693 return ret_val; }
10694 case OPTYPE_VALUEOF: {
10695 string ret_val("valueof(");
10696 u.expr.ti1->append_stringRepr(ret_val);
10697 ret_val += ')';
10698 return ret_val; }
10699 case OPTYPE_LOG2STR:
10700 return string("log2str(...)");
10701 case OPTYPE_ANY2UNISTR:
10702 return string("any2unistr(...)");
10703 case OPTYPE_MATCH: {
10704 string ret_val("match(");
10705 ret_val += u.expr.v1->get_stringRepr();
10706 ret_val += ", ";
10707 u.expr.t2->append_stringRepr(ret_val);
10708 ret_val += ')';
10709 return ret_val; }
10710 case OPTYPE_TTCN2STRING: {
10711 string ret_val("ttcn2string(");
10712 u.expr.ti1->append_stringRepr(ret_val);
10713 ret_val += ')';
10714 return ret_val;
10715 }
10716 case OPTYPE_UNDEF_RUNNING:
10717 return u.expr.r1->get_dispname() + ".running";
10718 case OPTYPE_COMP_NULL:
10719 return string("null");
10720 case OPTYPE_COMP_MTC:
10721 return string("mtc");
10722 case OPTYPE_COMP_SYSTEM:
10723 return string("system");
10724 case OPTYPE_COMP_SELF:
10725 return string("self");
10726 case OPTYPE_COMP_CREATE: {
10727 string ret_val(u.expr.r1->get_dispname());
10728 ret_val += ".create";
10729 if (u.expr.v2 || u.expr.v3) {
10730 ret_val += '(';
10731 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10732 else ret_val += '-';
10733 if (u.expr.v3) {
10734 ret_val += ", ";
10735 ret_val += u.expr.v3->get_stringRepr();
10736 }
10737 ret_val += ')';
10738 }
10739 if (u.expr.b4) ret_val += " alive";
10740 return ret_val; }
10741 case OPTYPE_COMP_RUNNING:
10742 return u.expr.v1->get_stringRepr() + ".running";
10743 case OPTYPE_COMP_RUNNING_ANY:
10744 return string("any component.running");
10745 case OPTYPE_COMP_RUNNING_ALL:
10746 return string("all component.running");
10747 case OPTYPE_COMP_ALIVE:
10748 return u.expr.v1->get_stringRepr() + ".alive";
10749 case OPTYPE_COMP_ALIVE_ANY:
10750 return string("any component.alive");
10751 case OPTYPE_COMP_ALIVE_ALL:
10752 return string("all component.alive");
10753 case OPTYPE_TMR_READ:
10754 return u.expr.r1->get_dispname() + ".read";
10755 case OPTYPE_TMR_RUNNING:
10756 return u.expr.r1->get_dispname() + ".running";
10757 case OPTYPE_TMR_RUNNING_ANY:
10758 return string("any timer.running");
10759 case OPTYPE_CHECKSTATE_ANY:
10760 case OPTYPE_CHECKSTATE_ALL: {
10761 string ret_val("");
10762 if (u.expr.r1) {
10763 ret_val += "port";
10764 } else {
10765 if (u.expr.v_optype == OPTYPE_CHECKSTATE_ANY) {
10766 ret_val += "any port";
10767 } else if (u.expr.v_optype == OPTYPE_CHECKSTATE_ALL) {
10768 ret_val += "all port";
10769 }
10770 }
10771 ret_val += "checkstate(";
10772 ret_val += u.expr.v2->get_stringRepr();
10773 ret_val += ")";
10774 return ret_val; }
10775 case OPTYPE_GETVERDICT:
10776 return string("getverdict");
10777 case OPTYPE_ACTIVATE: {
10778 string ret_val("activate(");
10779 ret_val += u.expr.r1->get_dispname();
10780 ret_val += ')';
10781 return ret_val; }
10782 case OPTYPE_ACTIVATE_REFD: {
10783 string ret_val("activate(derefer(");
10784 ret_val += u.expr.v1->get_stringRepr();
10785 ret_val += ")(";
10786 if (u.expr.state == EXPR_CHECKED) {
10787 if (u.expr.ap_list2) {
10788 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10789 for (size_t i = 0; i < nof_pars; i++) {
10790 if (i > 0) ret_val += ", ";
10791 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10792 }
10793 }
10794 } else {
10795 if (u.expr.t_list2) {
10796 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10797 for (size_t i = 0; i < nof_pars; i++) {
10798 if (i > 0) ret_val += ", ";
10799 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10800 }
10801 }
10802 }
10803 ret_val += "))";
10804 return ret_val; }
10805 case OPTYPE_EXECUTE: {
10806 string ret_val("execute(");
10807 ret_val += u.expr.r1->get_dispname();
10808 if (u.expr.v2) {
10809 ret_val += ", ";
10810 ret_val += u.expr.v2->get_stringRepr();
10811 }
10812 ret_val += ')';
10813 return ret_val; }
10814 case OPTYPE_EXECUTE_REFD: {
10815 string ret_val("execute(derefers(");
10816 ret_val += u.expr.v1->get_stringRepr();
10817 ret_val += ")(";
10818 if (u.expr.state == EXPR_CHECKED) {
10819 if (u.expr.ap_list2) {
10820 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10821 for (size_t i = 0; i < nof_pars; i++) {
10822 if (i > 0) ret_val += ", ";
10823 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10824 }
10825 }
10826 } else {
10827 if (u.expr.t_list2) {
10828 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10829 for (size_t i = 0; i < nof_pars; i++) {
10830 if (i > 0) ret_val += ", ";
10831 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10832 }
10833 }
10834 }
10835 ret_val += ')';
10836 if(u.expr.v3) {
10837 ret_val += ", ";
10838 ret_val += u.expr.v3->get_stringRepr();
10839 }
10840 ret_val += ')';
10841 return ret_val; }
10842 case OPTYPE_PROF_RUNNING:
10843 return string("@profiler.running");
10844 default:
10845 return string("<unsupported optype>");
10846 } // switch u.expr.v_optype
10847 case V_MACRO:
10848 switch (u.macro) {
10849 case MACRO_MODULEID:
10850 return string("%moduleId");
10851 case MACRO_FILENAME:
10852 return string("%fileName");
10853 case MACRO_BFILENAME:
10854 return string("__BFILE__");
10855 case MACRO_FILEPATH:
10856 return string("__FILE__");
10857 case MACRO_LINENUMBER:
10858 return string("%lineNumber");
10859 case MACRO_LINENUMBER_C:
10860 return string("__LINE__");
10861 case MACRO_DEFINITIONID:
10862 return string("%definitionId");
10863 case MACRO_SCOPE:
10864 return string("__SCOPE__");
10865 case MACRO_TESTCASEID:
10866 return string("%testcaseId");
10867 default:
10868 return string("<unknown macro>");
10869 } // switch u.macro
10870 case V_NOTUSED:
10871 return string('-');
10872 case V_FUNCTION:
10873 case V_ALTSTEP:
10874 case V_TESTCASE: {
10875 string ret_val("refers(");
10876 ret_val += u.refd_fat->get_assname();
10877 ret_val += ')';
10878 return ret_val; }
10879 case V_INVOKE: {
10880 string ret_val;
10881 ret_val += u.invoke.v->get_stringRepr();
10882 ret_val += ".apply(";
10883 if (u.invoke.ap_list) {
10884 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10885 for (size_t i = 0; i < nof_pars; i++) {
10886 if (i > 0) ret_val += ", ";
10887 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10888 }
10889 } else if (u.invoke.t_list) {
10890 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10891 for (size_t i = 0; i < nof_pars; i++) {
10892 if (i > 0) ret_val += ", ";
10893 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10894 }
10895 }
10896 ret_val += ')';
10897 return ret_val; }
10898 case V_REFER: {
10899 string ret_val("refers(");
10900 ret_val += u.refered->get_dispname();
10901 ret_val += ')';
10902 return ret_val; }
10903 default:
10904 return string("<unsupported valuetype>");
10905 } // switch valuetype
10906 }
10907
10908 string Value::create_stringRepr_unary(const char *operator_str)
10909 {
10910 string ret_val(operator_str);
10911 ret_val += '(';
10912 ret_val += u.expr.v1->get_stringRepr();
10913 ret_val += ')';
10914 return ret_val;
10915 }
10916
10917 string Value::create_stringRepr_infix(const char *operator_str)
10918 {
10919 string ret_val('(');
10920 ret_val += u.expr.v1->get_stringRepr();
10921 ret_val += ' ';
10922 ret_val += operator_str;
10923 ret_val += ' ';
10924 ret_val += u.expr.v2->get_stringRepr();
10925 ret_val += ')';
10926 return ret_val;
10927 }
10928
10929 string Value::create_stringRepr_predef1(const char *function_name)
10930 {
10931 string ret_val(function_name);
10932 ret_val += '(';
10933 if (u.expr.v_optype == OPTYPE_ENCODE || u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR) { // ti1, not v1
10934 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10935 }
10936 else ret_val += u.expr.v1->get_stringRepr();
10937 ret_val += ')';
10938 return ret_val;
10939 }
10940
10941 string Value::create_stringRepr_predef2(const char *function_name)
10942 {
10943 string ret_val(function_name);
10944 ret_val += '(';
10945 ret_val += u.expr.v1->get_stringRepr();
10946 ret_val += ", ";
10947 ret_val += u.expr.v2->get_stringRepr();
10948 ret_val += ')';
10949 return ret_val;
10950 }
10951
10952 bool Value::operator==(Value& val)
10953 {
10954 Value *left = get_value_refd_last();
10955 Type *left_governor = left->get_my_governor();
10956 if (left_governor) left_governor = left_governor->get_type_refd_last();
10957 Value *right = val.get_value_refd_last();
10958 Type *right_governor = right->get_my_governor();
10959 if (right_governor) right_governor = right_governor->get_type_refd_last();
10960 if (left_governor && right_governor
10961 && !left_governor->is_compatible(right_governor, NULL)
10962 && !right_governor->is_compatible(left_governor, NULL))
10963 FATAL_ERROR("Value::operator==");
10964
10965 // Not-A-Value is not equal to anything (NaN analogy:)
10966 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
10967 return false;
10968
10969 switch (left->valuetype) {
10970 case V_NULL:
10971 case V_OMIT:
10972 case V_DEFAULT_NULL:
10973 case V_FAT_NULL:
10974 case V_NOTUSED:
10975 return left->valuetype == right->valuetype;
10976 case V_BOOL:
10977 return right->valuetype == V_BOOL &&
10978 left->get_val_bool() == right->get_val_bool();
10979 case V_INT:
10980 return right->valuetype == V_INT && *left->get_val_Int()
10981 == *right->get_val_Int();
10982 case V_REAL:
10983 return right->valuetype == V_REAL &&
10984 left->get_val_Real() == right->get_val_Real();
10985 case V_CSTR:
10986 switch (right->valuetype) {
10987 case V_CSTR:
10988 return left->get_val_str() == right->get_val_str();
10989 case V_USTR:
10990 return right->get_val_ustr() == left->get_val_str();
10991 case V_ISO2022STR:
10992 return right->get_val_iso2022str() == left->get_val_str();
10993 default:
10994 return false;
10995 }
10996 case V_BSTR:
10997 case V_HSTR:
10998 case V_OSTR:
10999 return left->valuetype == right->valuetype &&
11000 left->get_val_str() == right->get_val_str();
11001 case V_USTR:
11002 switch (right->valuetype) {
11003 case V_CSTR:
11004 return left->get_val_ustr() == right->get_val_str();
11005 case V_USTR:
11006 return left->get_val_ustr() == right->get_val_ustr();
11007 case V_ISO2022STR:
11008 return left->get_val_ustr() == right->get_val_iso2022str();
11009 default:
11010 return false;
11011 }
11012 case V_ISO2022STR:
11013 switch (right->valuetype) {
11014 case V_CSTR:
11015 return left->get_val_iso2022str() == right->get_val_str();
11016 case V_USTR:
11017 // The appropriate operator==() is missing. The operands are swapped,
11018 // but it shouldn't be a problem.
11019 return right->get_val_ustr() == left->get_val_iso2022str();
11020 case V_ISO2022STR:
11021 return left->get_val_iso2022str() == right->get_val_iso2022str();
11022 default:
11023 return false;
11024 }
11025 case V_ENUM:
11026 return right->valuetype == V_ENUM &&
11027 left->get_val_id()->get_name() == right->get_val_id()->get_name();
11028 case V_OID:
11029 case V_ROID:
11030 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
11031 vector<string> act, other;
11032 get_oid_comps(act);
11033 val.get_oid_comps(other);
11034 size_t act_size = act.size(), other_size = other.size();
11035 bool ret_val;
11036 if (act_size == other_size) {
11037 ret_val = true;
11038 for (size_t i = 0; i < act_size; i++)
11039 if (*act[i] != *other[i]) {
11040 ret_val = false;
11041 break;
11042 }
11043 } else ret_val = false;
11044 for (size_t i = 0; i < act_size; i++) delete act[i];
11045 act.clear();
11046 for (size_t i = 0; i < other_size; i++) delete other[i];
11047 other.clear();
11048 return ret_val;
11049 } else return false;
11050 case V_CHOICE:
11051 return right->valuetype == V_CHOICE &&
11052 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
11053 *(left->get_alt_value()) == *(right->get_alt_value());
11054 case V_SEQ:
11055 case V_SET: {
11056 if (!left_governor) FATAL_ERROR("Value::operator==");
11057 if (left->valuetype != right->valuetype) return false;
11058 size_t nof_comps = left_governor->get_nof_comps();
11059 for (size_t i = 0; i < nof_comps; i++) {
11060 Value *lval = NULL, *rval = NULL;
11061 CompField* cfl = left_governor->get_comp_byIndex(i);
11062 const Identifier& field_name = cfl->get_name();
11063 if (left->has_comp_withName(field_name)) {
11064 lval = left->get_comp_value_byName(field_name);
11065 if (right->has_comp_withName(field_name)) {
11066 rval = right->get_comp_value_byName(field_name);
11067 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
11068 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
11069 return false;
11070 else if (!(*lval == *rval))
11071 return false;
11072 } else {
11073 if (cfl->has_default()) {
11074 if (!(*lval == *cfl->get_defval()))
11075 return false;
11076 } else {
11077 if (lval->valuetype != V_OMIT)
11078 return false;
11079 }
11080 }
11081 } else {
11082 if(right->has_comp_withName(field_name)) {
11083 rval = right->get_comp_value_byName(field_name);
11084 if(cfl->has_default()) {
11085 if(rval->valuetype==V_OMIT) return false;
11086 else {
11087 lval = cfl->get_defval();
11088 if (!(*lval==*rval)) return false;
11089 }
11090 }
11091 }
11092 }
11093 }
11094 return true; }
11095 case V_SEQOF:
11096 case V_ARRAY: {
11097 if (left->valuetype != right->valuetype) return false;
11098 size_t ncomps = get_nof_comps();
11099 if (ncomps != right->get_nof_comps()) return false;
11100
11101 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
11102 bool found = false;
11103 map<IndexedValue*, void> uncovered;
11104 for (size_t i = 0; i < left->get_nof_comps(); ++i)
11105 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
11106
11107 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
11108 found = false;
11109 for (size_t j = 0; j < uncovered.size(); ++j) {
11110 if (*(uncovered.get_nth_key(j)->get_value()) ==
11111 *(right->get_comp_byIndex(i)) &&
11112 *(uncovered.get_nth_key(j)->get_index()) ==
11113 *(right->get_index_byIndex(i))) {
11114 found = true;
11115 uncovered.erase(uncovered.get_nth_key(j));
11116 break;
11117 }
11118 }
11119 if (!found) break;
11120 }
11121 uncovered.clear();
11122 return found;
11123 } else if (left->is_indexed() || right->is_indexed()) {
11124 Value* indexed_one = 0;
11125 Value* not_indexed_one = 0;
11126
11127 if(left->is_indexed()) { // left is indexed, right is not
11128 indexed_one = left;
11129 not_indexed_one = right;
11130 } else { // right indexed, left is not
11131 indexed_one = right;
11132 not_indexed_one = left;
11133 }
11134
11135 for(size_t i = 0; i < ncomps; ++i) {
11136 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
11137 if(!(ind->valuetype == V_INT &&
11138 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
11139 *(indexed_one->get_comp_byIndex(i))))
11140 { return false; }
11141 }
11142 return true;
11143 } else { // none of them is indexed
11144 for (size_t i = 0; i < ncomps; i++) {
11145 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
11146 return false;
11147 }
11148 return true;
11149 }
11150 }
11151 case V_SETOF: {
11152 if (right->valuetype != V_SETOF) return false;
11153 size_t ncomps = get_nof_comps();
11154 if (ncomps != right->get_nof_comps()) return false;
11155 if (ncomps == 0) return true;
11156 map<size_t, void> uncovered;
11157 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
11158 for (size_t i = 0; i < ncomps; i++) {
11159 Value *left_item = left->get_comp_byIndex(i);
11160 bool pair_found = false;
11161 for (size_t j = 0; j < ncomps - i; j++) {
11162 size_t right_index = uncovered.get_nth_key(j);
11163 if (*left_item == *right->get_comp_byIndex(right_index)) {
11164 uncovered.erase(right_index);
11165 pair_found = true;
11166 break;
11167 }
11168 }
11169 if (!pair_found) {
11170 uncovered.clear();
11171 return false;
11172 }
11173 }
11174 return true; }
11175 case V_VERDICT:
11176 return right->valuetype == V_VERDICT &&
11177 left->get_val_verdict() == right->get_val_verdict();
11178 case V_FUNCTION:
11179 case V_ALTSTEP:
11180 case V_TESTCASE:
11181 return left->valuetype == right->valuetype &&
11182 left->get_refd_assignment() == right->get_refd_assignment();
11183 default:
11184 FATAL_ERROR("Value::operator==");
11185 }
11186 return true;
11187 }
11188
11189 bool Value::operator<(Value& val)
11190 {
11191 Value *left = get_value_refd_last();
11192 Type *left_governor = left->get_my_governor();
11193 if(left_governor) left_governor=left_governor->get_type_refd_last();
11194 Value *right = val.get_value_refd_last();
11195 Type *right_governor = right->get_my_governor();
11196 if(right_governor) right_governor=right_governor->get_type_refd_last();
11197 if (left->get_valuetype() != right->get_valuetype())
11198 FATAL_ERROR("Value::operator<");
11199 switch(valuetype){
11200 case V_INT:
11201 return *left->get_val_Int() < *right->get_val_Int();
11202 case V_REAL:
11203 return (left->get_val_Real() < right->get_val_Real());
11204 case V_ENUM:
11205 if(!left_governor || !right_governor)
11206 FATAL_ERROR("Value::operator<");
11207 if(left_governor!=right_governor)
11208 FATAL_ERROR("Value::operator<");
11209 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
11210 right_governor->get_enum_val_byId(*right->get_val_id()));
11211 default:
11212 FATAL_ERROR("Value::operator<");
11213 }
11214 return true;
11215 }
11216
11217 bool Value::is_string_type(Type::expected_value_t exp_val)
11218 {
11219 switch (get_expr_returntype(exp_val)) {
11220 case Type::T_CSTR:
11221 case Type::T_USTR:
11222 case Type::T_BSTR:
11223 case Type::T_HSTR:
11224 case Type::T_OSTR:
11225 return true;
11226 default:
11227 return false;
11228 }
11229 }
11230
11231 void Value::generate_code_expr(expression_struct *expr)
11232 {
11233 if (has_single_expr()) {
11234 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
11235 } else {
11236 switch (valuetype) {
11237 case V_EXPR:
11238 generate_code_expr_expr(expr);
11239 break;
11240 case V_CHOICE:
11241 case V_SEQOF:
11242 case V_SETOF:
11243 case V_ARRAY:
11244 case V_SEQ:
11245 case V_SET: {
11246 const string& tmp_id = get_temporary_id();
11247 const char *tmp_id_str = tmp_id.c_str();
11248 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11249 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
11250 set_genname_recursive(tmp_id);
11251 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11252 expr->expr = mputstr(expr->expr, tmp_id_str);
11253 break; }
11254 case V_INT: {
11255 const string& tmp_id = get_temporary_id();
11256 const char *tmp_id_str = tmp_id.c_str();
11257 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
11258 tmp_id_str);
11259 set_genname_recursive(tmp_id);
11260 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11261 expr->expr = mputstr(expr->expr, tmp_id_str);
11262 break; }
11263 case V_REFD: {
11264 if (!get_needs_conversion()) {
11265 u.ref.ref->generate_code_const_ref(expr);
11266 } else {
11267 Type *my_gov = get_expr_governor_last();
11268 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
11269 ->get_field_type(u.ref.ref->get_subrefs(),
11270 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
11271 // Make sure that nothing goes wrong.
11272 if (!my_gov || !refd_gov || my_gov == refd_gov)
11273 FATAL_ERROR("Value::generate_code_expr()");
11274 expression_struct expr_tmp;
11275 Code::init_expr(&expr_tmp);
11276 const string& tmp_id1 = get_temporary_id();
11277 const char *tmp_id_str1 = tmp_id1.c_str();
11278 const string& tmp_id2 = get_temporary_id();
11279 const char *tmp_id_str2 = tmp_id2.c_str();
11280 expr->preamble = mputprintf(expr->preamble,
11281 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
11282 tmp_id_str1);
11283 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11284 u.ref.ref->generate_code_const_ref(&expr_tmp);
11285 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11286 expr->preamble = mputprintf(expr->preamble,
11287 "%s %s;\n"
11288 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11289 "and `%s' are not compatible at run-time\");\n",
11290 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11291 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
11292 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
11293 ->get_typename().c_str(), refd_gov->get_typename().c_str());
11294 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11295 }
11296 break; }
11297 case V_INVOKE:
11298 generate_code_expr_invoke(expr);
11299 break;
11300 default:
11301 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
11302 }
11303 }
11304 }
11305
11306 void Value::generate_code_expr_mandatory(expression_struct *expr)
11307 {
11308 generate_code_expr(expr);
11309 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11310 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11311 }
11312
11313 bool Value::can_use_increment(Reference *ref) const
11314 {
11315 if (valuetype != V_EXPR) {
11316 return false;
11317 }
11318 switch (u.expr.v_optype) {
11319 case OPTYPE_ADD:
11320 case OPTYPE_SUBTRACT:
11321 break;
11322 default:
11323 return false;
11324 }
11325 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11326 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11327 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11328 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11329 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11330 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11331 return true;
11332 }
11333 return false;
11334 }
11335
11336 char *Value::generate_code_init(char *str, const char *name)
11337 {
11338 if (get_code_generated()) return str;
11339 if (err_descr) {
11340 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11341 }
11342 switch (valuetype) {
11343 case V_NULL:
11344 case V_BOOL:
11345 case V_REAL:
11346 case V_ENUM:
11347 case V_BSTR:
11348 case V_HSTR:
11349 case V_OSTR:
11350 case V_CSTR:
11351 case V_USTR:
11352 case V_ISO2022STR:
11353 case V_OID:
11354 case V_ROID:
11355 case V_VERDICT:
11356 case V_DEFAULT_NULL:
11357 case V_FAT_NULL:
11358 case V_FUNCTION:
11359 case V_ALTSTEP:
11360 case V_TESTCASE:
11361 // These values have a single string equivalent.
11362 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11363 break;
11364 case V_INT:
11365 if (u.val_Int->is_native_fit())
11366 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11367 else
11368 // It's always an INTEGER.
11369 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11370 "}\n", get_single_expr().c_str(), name);
11371 break;
11372 case V_EXPR:
11373 case V_INVOKE: {
11374 expression_struct expr;
11375 Code::init_expr(&expr);
11376 expr.expr = mputprintf(expr.expr, "%s = ", name);
11377 generate_code_expr(&expr);
11378 str = Code::merge_free_expr(str, &expr);
11379 break; }
11380 case V_CHOICE:
11381 str = generate_code_init_choice(str, name);
11382 break;
11383 case V_SEQOF:
11384 case V_SETOF:
11385 if (!is_indexed()) str = generate_code_init_seof(str, name);
11386 else str = generate_code_init_indexed(str, name);
11387 break;
11388 case V_ARRAY:
11389 if (!is_indexed()) str = generate_code_init_array(str, name);
11390 else str = generate_code_init_indexed(str, name);
11391 break;
11392 case V_SEQ:
11393 case V_SET:
11394 str = generate_code_init_se(str, name);
11395 break;
11396 case V_REFD:
11397 str = generate_code_init_refd(str, name);
11398 break;
11399 case V_MACRO:
11400 switch (u.macro) {
11401 case MACRO_TESTCASEID:
11402 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11403 break;
11404 default:
11405 // all others must already be evaluated away
11406 FATAL_ERROR("Value::generate_code_init()");
11407 }
11408 break;
11409 case V_NOTUSED:
11410 // unbound value, don't generate anything
11411 break;
11412 default:
11413 FATAL_ERROR("Value::generate_code_init()");
11414 }
11415 if (err_descr) {
11416 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11417 }
11418 set_code_generated();
11419 return str;
11420 }
11421
11422 char *Value::rearrange_init_code(char *str, Common::Module* usage_mod)
11423 {
11424 switch (valuetype) {
11425 case V_REFD: {
11426 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11427 if (parlist) {
11428 str = parlist->rearrange_init_code(str, usage_mod);
11429 }
11430 break; }
11431 case V_INVOKE: {
11432 str = u.invoke.v->rearrange_init_code(str, usage_mod);
11433 str = u.invoke.ap_list->rearrange_init_code(str, usage_mod);
11434 break; }
11435 case V_EXPR:
11436 switch (u.expr.v_optype) {
11437 case OPTYPE_UNARYPLUS:
11438 case OPTYPE_UNARYMINUS:
11439 case OPTYPE_NOT:
11440 case OPTYPE_NOT4B:
11441 case OPTYPE_BIT2HEX:
11442 case OPTYPE_BIT2INT:
11443 case OPTYPE_BIT2OCT:
11444 case OPTYPE_BIT2STR:
11445 case OPTYPE_CHAR2INT:
11446 case OPTYPE_CHAR2OCT:
11447 case OPTYPE_FLOAT2INT:
11448 case OPTYPE_FLOAT2STR:
11449 case OPTYPE_HEX2BIT:
11450 case OPTYPE_HEX2INT:
11451 case OPTYPE_HEX2OCT:
11452 case OPTYPE_HEX2STR:
11453 case OPTYPE_INT2CHAR:
11454 case OPTYPE_INT2FLOAT:
11455 case OPTYPE_INT2STR:
11456 case OPTYPE_INT2UNICHAR:
11457 case OPTYPE_OCT2BIT:
11458 case OPTYPE_OCT2CHAR:
11459 case OPTYPE_OCT2HEX:
11460 case OPTYPE_OCT2INT:
11461 case OPTYPE_OCT2STR:
11462 case OPTYPE_STR2BIT:
11463 case OPTYPE_STR2FLOAT:
11464 case OPTYPE_STR2HEX:
11465 case OPTYPE_STR2INT:
11466 case OPTYPE_STR2OCT:
11467 case OPTYPE_UNICHAR2INT:
11468 case OPTYPE_UNICHAR2CHAR:
11469 case OPTYPE_ENUM2INT:
11470 case OPTYPE_ISCHOSEN_V:
11471 case OPTYPE_GET_STRINGENCODING:
11472 case OPTYPE_REMOVE_BOM:
11473 case OPTYPE_DECODE_BASE64:
11474 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11475 break;
11476 case OPTYPE_DECODE: {
11477 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11478 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11479 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11480
11481 parlist = u.expr.r2->get_parlist();
11482 ass = u.expr.r2->get_refd_assignment();
11483 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11484 break; }
11485 case OPTYPE_ADD:
11486 case OPTYPE_SUBTRACT:
11487 case OPTYPE_MULTIPLY:
11488 case OPTYPE_DIVIDE:
11489 case OPTYPE_MOD:
11490 case OPTYPE_REM:
11491 case OPTYPE_CONCAT:
11492 case OPTYPE_EQ:
11493 case OPTYPE_LT:
11494 case OPTYPE_GT:
11495 case OPTYPE_NE:
11496 case OPTYPE_GE:
11497 case OPTYPE_LE:
11498 case OPTYPE_AND:
11499 case OPTYPE_OR:
11500 case OPTYPE_XOR:
11501 case OPTYPE_AND4B:
11502 case OPTYPE_OR4B:
11503 case OPTYPE_XOR4B:
11504 case OPTYPE_SHL:
11505 case OPTYPE_SHR:
11506 case OPTYPE_ROTL:
11507 case OPTYPE_ROTR:
11508 case OPTYPE_INT2BIT:
11509 case OPTYPE_INT2HEX:
11510 case OPTYPE_INT2OCT:
11511 //case OPTYPE_DECODE:
11512 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11513 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11514 break;
11515 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11516 case OPTYPE_OCT2UNICHAR:
11517 case OPTYPE_ENCODE_BASE64:
11518 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11519 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11520 break;
11521 case OPTYPE_SUBSTR:
11522 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11523 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11524 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11525 break;
11526 case OPTYPE_REGEXP:
11527 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11528 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11529 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11530 break;
11531 case OPTYPE_DECOMP:
11532 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11533 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11534 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11535 break;
11536 case OPTYPE_REPLACE:
11537 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11538 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11539 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11540 str = u.expr.ti4->rearrange_init_code(str, usage_mod);
11541 break;
11542 case OPTYPE_LENGTHOF:
11543 case OPTYPE_SIZEOF:
11544 case OPTYPE_VALUEOF:
11545 case OPTYPE_ENCODE:
11546 case OPTYPE_ISPRESENT:
11547 case OPTYPE_TTCN2STRING:
11548 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11549 break;
11550 case OPTYPE_ENCVALUE_UNICHAR:
11551 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11552 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11553 break;
11554 case OPTYPE_DECVALUE_UNICHAR: {
11555 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11556 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11557 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11558
11559 parlist = u.expr.r2->get_parlist();
11560 ass = u.expr.r2->get_refd_assignment();
11561 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11562 if (u.expr.v3) str = u.expr.v3->rearrange_init_code(str, usage_mod);
11563 break; }
11564 case OPTYPE_ISCHOSEN_T:
11565 str = u.expr.t1->rearrange_init_code(str, usage_mod);
11566 break;
11567 case OPTYPE_MATCH:
11568 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11569 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11570 break;
11571 default:
11572 // other kinds of expressions cannot appear within templates
11573 break;
11574 }
11575 break;
11576 default:
11577 break;
11578 }
11579 return str;
11580 }
11581
11582 char* Value::generate_code_tmp(char *str, const char *prefix,
11583 size_t& blockcount)
11584 {
11585 char *s2 = memptystr();
11586 char *s1 = generate_code_tmp(NULL, s2);
11587 if (s2[0]) {
11588 if (blockcount == 0) {
11589 str = mputstr(str, "{\n");
11590 blockcount++;
11591 }
11592 str = mputstr(str, s2);
11593 }
11594 Free(s2);
11595 str=mputstr(str, prefix);
11596 str=mputstr(str, s1);
11597 Free(s1);
11598 return str;
11599 }
11600
11601 char *Value::generate_code_tmp(char *str, char*& init)
11602 {
11603 expression_struct expr;
11604 Code::init_expr(&expr);
11605 generate_code_expr_mandatory(&expr);
11606 if (expr.preamble || expr.postamble) {
11607 if (valuetype == V_EXPR &&
11608 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11609 // a temporary variable is already introduced
11610 if (expr.preamble) init = mputstr(init, expr.preamble);
11611 if (expr.postamble) init = mputstr(init, expr.postamble);
11612 str = mputstr(str, expr.expr);
11613 } else {
11614 const string& tmp_id = get_temporary_id();
11615 const char *tmp_id_str = tmp_id.c_str();
11616 init = mputprintf(init, "%s %s;\n"
11617 "{\n",
11618 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11619 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11620 tmp_id_str);
11621 if (expr.preamble) init = mputstr(init, expr.preamble);
11622 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11623 if (expr.postamble) init = mputstr(init, expr.postamble);
11624 init = mputstr(init, "}\n");
11625 str = mputstr(str, tmp_id_str);
11626 }
11627 } else str = mputstr(str, expr.expr);
11628 Code::free_expr(&expr);
11629 return str;
11630 }
11631
11632 void Value::generate_code_log(expression_struct *expr)
11633 {
11634 if (explicit_cast_needed()) {
11635 char *expr_backup = expr->expr;
11636 expr->expr = NULL;
11637 generate_code_expr(expr);
11638 const string& tmp_id = get_temporary_id();
11639 const char *tmp_id_str = tmp_id.c_str();
11640 // We have to create a temporary object, because the parser of GCC
11641 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11642 // constructor call that is, this does not work: type(...).log(); but
11643 // this works: type tmp(...); tmp.log();.
11644 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11645 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11646 expr->expr);
11647 Free(expr->expr);
11648 expr->expr = mputstr(expr_backup, tmp_id_str);
11649 } else {
11650 generate_code_expr(expr);
11651 }
11652 expr->expr = mputstr(expr->expr, ".log()");
11653 }
11654
11655 void Value::generate_code_log_match(expression_struct *expr)
11656 {
11657 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11658 FATAL_ERROR("Value::generate_code_log_match()");
11659 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11660 // compliance the whole code-generation should be checked. Standalone
11661 // constructs like: "A(a[0].f());" should be avoided. The current
11662 // solution for HK38721 uses an additional assignment to overcome the
11663 // issue. The generated code will be slower, but it's needed for old GCC
11664 // versions in specific circumstances.
11665 if (u.expr.t2->needs_temp_ref()) {
11666 char *expr_backup = expr->expr;
11667 expr->expr = NULL;
11668 u.expr.t2->generate_code(expr);
11669 const string& tmp_id = get_temporary_id();
11670 const char *tmp_id_str = tmp_id.c_str();
11671 expr->preamble = mputprintf(expr->preamble,
11672 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11673 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11674 Free(expr->expr);
11675 expr->expr = mputstr(expr_backup, tmp_id_str);
11676 } else {
11677 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11678 // some reason "(A(NS::B)).a(C);" compiles fine.
11679 expr->expr = mputc(expr->expr, '(');
11680 u.expr.t2->generate_code(expr);
11681 expr->expr = mputc(expr->expr, ')');
11682 }
11683 expr->expr = mputstr(expr->expr, ".log_match(");
11684 u.expr.v1->generate_code_expr(expr);
11685 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
11686 }
11687
11688 void Value::generate_code_expr_expr(expression_struct *expr)
11689 {
11690 switch (u.expr.v_optype) {
11691 case OPTYPE_RND:
11692 generate_code_expr_rnd(expr, 0);
11693 break;
11694 case OPTYPE_UNARYPLUS:
11695 // same as without the '+' operator
11696 u.expr.v1->generate_code_expr(expr);
11697 break;
11698 case OPTYPE_UNARYMINUS:
11699 generate_code_expr_unary(expr, "-", u.expr.v1);
11700 break;
11701 case OPTYPE_NOT:
11702 generate_code_expr_unary(expr, "!", u.expr.v1);
11703 break;
11704 case OPTYPE_NOT4B:
11705 generate_code_expr_unary(expr, "~", u.expr.v1);
11706 break;
11707 case OPTYPE_BIT2HEX:
11708 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11709 break;
11710 case OPTYPE_BIT2INT:
11711 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11712 break;
11713 case OPTYPE_BIT2OCT:
11714 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11715 break;
11716 case OPTYPE_BIT2STR:
11717 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11718 break;
11719 case OPTYPE_CHAR2INT:
11720 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11721 break;
11722 case OPTYPE_CHAR2OCT:
11723 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11724 break;
11725 case OPTYPE_FLOAT2INT:
11726 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11727 break;
11728 case OPTYPE_FLOAT2STR:
11729 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11730 break;
11731 case OPTYPE_HEX2BIT:
11732 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11733 break;
11734 case OPTYPE_HEX2INT:
11735 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11736 break;
11737 case OPTYPE_HEX2OCT:
11738 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11739 break;
11740 case OPTYPE_HEX2STR:
11741 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11742 break;
11743 case OPTYPE_INT2CHAR:
11744 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11745 break;
11746 case OPTYPE_INT2FLOAT:
11747 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11748 break;
11749 case OPTYPE_INT2STR:
11750 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11751 break;
11752 case OPTYPE_INT2UNICHAR:
11753 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11754 break;
11755 case OPTYPE_OCT2BIT:
11756 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11757 break;
11758 case OPTYPE_OCT2CHAR:
11759 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11760 break;
11761 case OPTYPE_GET_STRINGENCODING:
11762 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11763 break;
11764 case OPTYPE_REMOVE_BOM:
11765 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11766 break;
11767 case OPTYPE_ENCODE_BASE64:
11768 if (u.expr.v2)
11769 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11770 else
11771 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11772 break;
11773 case OPTYPE_DECODE_BASE64:
11774 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11775 break;
11776 case OPTYPE_OCT2UNICHAR:
11777 if (u.expr.v2)
11778 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11779 else
11780 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11781 break;
11782 case OPTYPE_UNICHAR2OCT:
11783 if (u.expr.v2)
11784 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11785 else
11786 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11787 break;
11788 case OPTYPE_ENCVALUE_UNICHAR:
11789 generate_code_expr_encvalue_unichar(expr);
11790 break;
11791 case OPTYPE_DECVALUE_UNICHAR:
11792 generate_code_expr_decvalue_unichar(expr);
11793 break;
11794 case OPTYPE_OCT2HEX:
11795 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11796 break;
11797 case OPTYPE_OCT2INT:
11798 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11799 break;
11800 case OPTYPE_OCT2STR:
11801 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11802 break;
11803 case OPTYPE_STR2BIT:
11804 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11805 break;
11806 case OPTYPE_STR2FLOAT:
11807 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11808 break;
11809 case OPTYPE_STR2HEX:
11810 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11811 break;
11812 case OPTYPE_STR2INT:
11813 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11814 break;
11815 case OPTYPE_STR2OCT:
11816 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11817 break;
11818 case OPTYPE_UNICHAR2INT:
11819 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11820 break;
11821 case OPTYPE_UNICHAR2CHAR:
11822 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11823 break;
11824 case OPTYPE_ENUM2INT: {
11825 Type* enum_type = u.expr.v1->get_expr_governor_last();
11826 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11827 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11828 enum_type->get_genname_value(my_scope).c_str());
11829 u.expr.v1->generate_code_expr_mandatory(expr);
11830 expr->expr = mputc(expr->expr, ')');
11831 break;}
11832 case OPTYPE_ENCODE:
11833 generate_code_expr_encode(expr);
11834 break;
11835 case OPTYPE_DECODE:
11836 generate_code_expr_decode(expr);
11837 break;
11838 case OPTYPE_RNDWITHVAL:
11839 generate_code_expr_rnd(expr, u.expr.v1);
11840 break;
11841 case OPTYPE_ADD:
11842 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11843 break;
11844 case OPTYPE_SUBTRACT:
11845 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11846 break;
11847 case OPTYPE_MULTIPLY:
11848 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11849 break;
11850 case OPTYPE_DIVIDE:
11851 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11852 break;
11853 case OPTYPE_MOD:
11854 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11855 break;
11856 case OPTYPE_REM:
11857 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11858 break;
11859 case OPTYPE_CONCAT:
11860 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11861 break;
11862 case OPTYPE_EQ:
11863 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11864 break;
11865 case OPTYPE_LT:
11866 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11867 break;
11868 case OPTYPE_GT:
11869 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11870 break;
11871 case OPTYPE_NE:
11872 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11873 break;
11874 case OPTYPE_GE:
11875 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11876 break;
11877 case OPTYPE_LE:
11878 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11879 break;
11880 case OPTYPE_AND:
11881 case OPTYPE_OR:
11882 generate_code_expr_and_or(expr);
11883 break;
11884 case OPTYPE_XOR:
11885 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11886 break;
11887 case OPTYPE_AND4B:
11888 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11889 break;
11890 case OPTYPE_OR4B:
11891 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11892 break;
11893 case OPTYPE_XOR4B:
11894 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11895 break;
11896 case OPTYPE_SHL:
11897 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11898 break;
11899 case OPTYPE_SHR:
11900 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11901 break;
11902 case OPTYPE_ROTL:
11903 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11904 break;
11905 case OPTYPE_ROTR:
11906 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11907 break;
11908 case OPTYPE_INT2BIT:
11909 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11910 break;
11911 case OPTYPE_INT2HEX:
11912 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11913 break;
11914 case OPTYPE_INT2OCT:
11915 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11916 break;
11917 case OPTYPE_SUBSTR:
11918 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11919 else generate_code_expr_substr_replace_compat(expr);
11920 break;
11921 case OPTYPE_REGEXP:
11922 generate_code_expr_regexp(expr);
11923 break;
11924 case OPTYPE_DECOMP:
11925 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11926 break;
11927 case OPTYPE_REPLACE:
11928 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11929 else generate_code_expr_substr_replace_compat(expr);
11930 break;
11931 case OPTYPE_ISCHOSEN: // r1 i2
11932 FATAL_ERROR("Value::generate_code_expr_expr()");
11933 break;
11934 case OPTYPE_ISCHOSEN_V: // v1 i2
11935 u.expr.v1->generate_code_expr_mandatory(expr);
11936 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11937 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11938 u.expr.i2->get_name().c_str());
11939 break;
11940 case OPTYPE_ISCHOSEN_T: // t1 i2
11941 u.expr.t1->generate_code_expr(expr);
11942 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11943 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11944 u.expr.i2->get_name().c_str());
11945 break;
11946 case OPTYPE_ISPRESENT:
11947 case OPTYPE_ISBOUND: {
11948 Template::templatetype_t temp = u.expr.ti1->get_Template()
11949 ->get_templatetype();
11950 if (temp == Template::SPECIFIC_VALUE) {
11951 Value* specific_value = u.expr.ti1->get_Template()
11952 ->get_specific_value();
11953 if (specific_value->get_valuetype() == Value::V_REFD) {
11954 Ttcn::Reference* reference =
11955 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
11956 if (reference) {
11957 reference->generate_code_ispresentbound(expr, false,
11958 u.expr.v_optype==OPTYPE_ISBOUND);
11959 break;
11960 }
11961 }
11962 } else if (temp == Template::TEMPLATE_REFD){
11963 Ttcn::Reference* reference =
11964 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
11965 ->get_reference());
11966 if (reference) {
11967 reference->generate_code_ispresentbound(expr, true,
11968 u.expr.v_optype==OPTYPE_ISBOUND);
11969 break;
11970 }
11971 }
11972 }
11973 // no break
11974 case OPTYPE_LENGTHOF: // ti1
11975 // fall through, separated later
11976 case OPTYPE_SIZEOF: // ti1
11977 // fall through, separated later
11978 case OPTYPE_ISVALUE: { // ti1
11979 if (u.expr.ti1->is_only_specific_value()) {
11980 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
11981 bool cast_needed = t_val->explicit_cast_needed(
11982 u.expr.v_optype != OPTYPE_LENGTHOF);
11983 if(cast_needed) {
11984 // the ambiguous C++ expression is converted to the value class
11985 expr->expr = mputprintf(expr->expr, "%s(",
11986 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
11987 }
11988
11989 if (u.expr.v_optype != OPTYPE_LENGTHOF
11990 && u.expr.v_optype != OPTYPE_SIZEOF) {
11991 t_val->generate_code_expr(expr);
11992 } else {
11993 t_val->generate_code_expr_mandatory(expr);
11994 }
11995
11996 if(cast_needed) expr->expr=mputc(expr->expr, ')');
11997 }
11998 else u.expr.ti1->generate_code(expr);
11999
12000 switch (u.expr.v_optype) {
12001 case OPTYPE_ISBOUND:
12002 expr->expr=mputstr(expr->expr, ".is_bound()");
12003 break;
12004 case OPTYPE_ISPRESENT:
12005 expr->expr=mputprintf(expr->expr, ".is_present()");
12006 break;
12007 case OPTYPE_SIZEOF:
12008 expr->expr=mputstr(expr->expr, ".size_of()");
12009 break;
12010 case OPTYPE_LENGTHOF:
12011 expr->expr=mputstr(expr->expr, ".lengthof()");
12012 break;
12013 case OPTYPE_ISVALUE:
12014 expr->expr=mputstr(expr->expr, ".is_value()");
12015 break;
12016 default:
12017 FATAL_ERROR("Value::generate_code_expr_expr()");
12018 }
12019 break; }
12020 case OPTYPE_VALUEOF: // ti1
12021 u.expr.ti1->generate_code(expr);
12022 expr->expr = mputstr(expr->expr, ".valueof()");
12023 break;
12024 case OPTYPE_MATCH: // v1 t2
12025 u.expr.t2->generate_code(expr);
12026 expr->expr = mputstr(expr->expr, ".match(");
12027 u.expr.v1->generate_code_expr(expr);
12028 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
12029 break;
12030 case OPTYPE_UNDEF_RUNNING:
12031 // it is resolved during semantic check
12032 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
12033 break;
12034 case OPTYPE_COMP_NULL: // -
12035 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
12036 break;
12037 case OPTYPE_COMP_MTC: // -
12038 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
12039 break;
12040 case OPTYPE_COMP_SYSTEM: // -
12041 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
12042 break;
12043 case OPTYPE_COMP_SELF: // -
12044 expr->expr=mputstr(expr->expr, "self");
12045 break;
12046 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
12047 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
12048 u.expr.b4);
12049 break;
12050 case OPTYPE_COMP_RUNNING: // v1
12051 u.expr.v1->generate_code_expr(expr);
12052 if(u.expr.v1->get_valuetype() == V_REFD)
12053 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
12054 expr->expr = mputstr(expr->expr, ".running()");
12055 break;
12056 case OPTYPE_COMP_RUNNING_ANY: // -
12057 expr->expr=mputstr(expr->expr,
12058 "TTCN_Runtime::component_running(ANY_COMPREF)");
12059 break;
12060 case OPTYPE_COMP_RUNNING_ALL: // -
12061 expr->expr=mputstr(expr->expr,
12062 "TTCN_Runtime::component_running(ALL_COMPREF)");
12063 break;
12064 case OPTYPE_COMP_ALIVE: // v1
12065 u.expr.v1->generate_code_expr(expr);
12066 if(u.expr.v1->get_valuetype() == V_REFD)
12067 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
12068 expr->expr = mputstr(expr->expr, ".alive()");
12069 break;
12070 case OPTYPE_COMP_ALIVE_ANY: // -
12071 expr->expr = mputstr(expr->expr,
12072 "TTCN_Runtime::component_alive(ANY_COMPREF)");
12073 break;
12074 case OPTYPE_COMP_ALIVE_ALL: // -
12075 expr->expr = mputstr(expr->expr,
12076 "TTCN_Runtime::component_alive(ALL_COMPREF)");
12077 break;
12078 case OPTYPE_TMR_READ: // r1
12079 u.expr.r1->generate_code(expr);
12080 expr->expr = mputstr(expr->expr, ".read()");
12081 break;
12082 case OPTYPE_TMR_RUNNING: // r1
12083 u.expr.r1->generate_code(expr);
12084 expr->expr = mputstr(expr->expr, ".running()");
12085 break;
12086 case OPTYPE_TMR_RUNNING_ANY: // -
12087 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
12088 break;
12089 case OPTYPE_GETVERDICT: // -
12090 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
12091 break;
12092 case OPTYPE_TESTCASENAME: // -
12093 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
12094 break;
12095 case OPTYPE_ACTIVATE: // r1
12096 generate_code_expr_activate(expr);
12097 break;
12098 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
12099 case OPTYPE_CHECKSTATE_ALL:
12100 generate_code_expr_checkstate(expr);
12101 break;
12102 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
12103 generate_code_expr_activate_refd(expr);
12104 break;
12105 case OPTYPE_EXECUTE: // r1 [v2]
12106 generate_code_expr_execute(expr);
12107 break;
12108 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
12109 generate_code_expr_execute_refd(expr);
12110 break;
12111 case OPTYPE_LOG2STR:
12112 case OPTYPE_ANY2UNISTR:
12113 u.expr.logargs->generate_code_expr(expr);
12114 break;
12115 case OPTYPE_TTCN2STRING: {
12116 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
12117 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
12118 param_governor = param_governor->get_type_refd_last();
12119 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
12120 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
12121 u.expr.ti1->get_Template()->is_Value()) {
12122 Value* v = u.expr.ti1->get_Template()->get_Value();
12123 delete u.expr.ti1;
12124 u.expr.ti1 = NULL;
12125 bool cast_needed = v->explicit_cast_needed();
12126 if (cast_needed) {
12127 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
12128 }
12129 v->generate_code_expr(expr);
12130 if (cast_needed) {
12131 expr->expr = mputstr(expr->expr, ")");
12132 }
12133 delete v;
12134 } else {
12135 u.expr.ti1->generate_code(expr);
12136 }
12137 expr->expr = mputstr(expr->expr, ")");
12138 } break;
12139 case OPTYPE_PROF_RUNNING:
12140 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
12141 break;
12142 default:
12143 FATAL_ERROR("Value::generate_code_expr_expr()");
12144 }
12145 }
12146
12147 void Value::generate_code_expr_unary(expression_struct *expr,
12148 const char *operator_str, Value *v1)
12149 {
12150 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
12151 v1->generate_code_expr_mandatory(expr);
12152 expr->expr = mputstrn(expr->expr, "))", 2);
12153 }
12154
12155 void Value::generate_code_expr_infix(expression_struct *expr,
12156 const char *operator_str, Value *v1,
12157 Value *v2, bool optional_allowed)
12158 {
12159 if (!get_needs_conversion()) {
12160 expr->expr = mputc(expr->expr, '(');
12161 if (optional_allowed) v1->generate_code_expr(expr);
12162 else v1->generate_code_expr_mandatory(expr);
12163 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
12164 if (optional_allowed) v2->generate_code_expr(expr);
12165 else v2->generate_code_expr_mandatory(expr);
12166 expr->expr = mputc(expr->expr, ')');
12167 } else { // Temporary variable for the converted value.
12168 const string& tmp_id1 = get_temporary_id();
12169 const char *tmp_id_str1 = tmp_id1.c_str();
12170 expression_struct expr_tmp;
12171 Code::init_expr(&expr_tmp);
12172 switch (u.expr.v_optype) {
12173 case OPTYPE_EQ:
12174 case OPTYPE_NE: {
12175 // Always "v1 -> v2".
12176 Type *t1 = v1->get_expr_governor_last();
12177 Type *t2 = v2->get_expr_governor_last();
12178 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
12179 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12180 else v2->generate_code_expr_mandatory(&expr_tmp);
12181 if (expr_tmp.preamble)
12182 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12183 expr->preamble = mputprintf(expr->preamble,
12184 "%s %s;\n"
12185 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12186 "and `%s' are not compatible at run-time\");\n",
12187 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
12188 TypeConv::get_conv_func(t2, t1, get_my_scope()
12189 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
12190 t2->get_typename().c_str(), t1->get_typename().c_str());
12191 Code::free_expr(&expr_tmp);
12192 if (optional_allowed) v1->generate_code_expr(expr);
12193 else v1->generate_code_expr_mandatory(expr);
12194 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
12195 tmp_id_str1);
12196 break; }
12197 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12198 // functions. The governors of all operands must exist at this point.
12199 case OPTYPE_ROTL:
12200 case OPTYPE_ROTR:
12201 case OPTYPE_CONCAT: {
12202 const string& tmp_id2 = get_temporary_id();
12203 const char *tmp_id_str2 = tmp_id2.c_str();
12204 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
12205 Type *my_gov = my_governor->get_type_refd_last();
12206 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
12207 ->get_type_refd_last();
12208 if (!t1_gov || my_gov == t1_gov)
12209 FATAL_ERROR("Value::generate_code_expr_infix()");
12210 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
12211 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
12212 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
12213 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
12214 else v1->generate_code_expr_mandatory(&expr_tmp);
12215 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
12216 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12217 else v2->generate_code_expr_mandatory(&expr_tmp);
12218 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
12219 expr->preamble = mputprintf(expr->preamble,
12220 "%s %s;\n"
12221 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12222 "and `%s' are not compatible at run-time\");\n",
12223 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
12224 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
12225 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
12226 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
12227 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
12228 break; }
12229 default:
12230 FATAL_ERROR("Value::generate_code_expr_infix()");
12231 break;
12232 }
12233 }
12234 }
12235
12236 void Value::generate_code_expr_and_or(expression_struct *expr)
12237 {
12238 if (u.expr.v2->needs_short_circuit()) {
12239 // introduce a temporary variable to store the result of the operation
12240 const string& tmp_id = get_temporary_id();
12241 const char *tmp_id_str = tmp_id.c_str();
12242 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
12243 expression_struct expr2;
12244 // the left operand must be evaluated anyway
12245 Code::init_expr(&expr2);
12246 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12247 u.expr.v1->generate_code_expr_mandatory(&expr2);
12248 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12249 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
12250 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
12251 // evaluate the right operand only when necessary
12252 // in this case the final result will be the right operand
12253 Code::init_expr(&expr2);
12254 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12255 u.expr.v2->generate_code_expr_mandatory(&expr2);
12256 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12257 // the result is now in the temporary variable
12258 expr->expr = mputstr(expr->expr, tmp_id_str);
12259 } else {
12260 // use the overloaded operator to get better error messages
12261 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
12262 "&&" : "||", u.expr.v1, u.expr.v2, false);
12263 }
12264 }
12265
12266 void Value::generate_code_expr_predef1(expression_struct *expr,
12267 const char *function_name,
12268 Value *v1)
12269 {
12270 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12271 v1->generate_code_expr_mandatory(expr);
12272 expr->expr = mputc(expr->expr, ')');
12273 }
12274
12275 void Value::generate_code_expr_predef2(expression_struct *expr,
12276 const char *function_name,
12277 Value *v1, Value *v2)
12278 {
12279 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12280 v1->generate_code_expr_mandatory(expr);
12281 expr->expr = mputstr(expr->expr, ", ");
12282 v2->generate_code_expr_mandatory(expr);
12283 expr->expr = mputc(expr->expr, ')');
12284 }
12285
12286 void Value::generate_code_expr_predef3(expression_struct *expr,
12287 const char *function_name,
12288 Value *v1, Value *v2, Value *v3)
12289 {
12290 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12291 v1->generate_code_expr_mandatory(expr);
12292 expr->expr = mputstr(expr->expr, ", ");
12293 v2->generate_code_expr_mandatory(expr);
12294 expr->expr = mputstr(expr->expr, ", ");
12295 v3->generate_code_expr_mandatory(expr);
12296 expr->expr = mputc(expr->expr, ')');
12297 }
12298
12299 void Value::generate_code_expr_substr(expression_struct *expr)
12300 {
12301 bool par1_is_str;
12302 Value* v1 = u.expr.ti1->get_specific_value();
12303 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12304 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12305 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
12306 if (v1) v1->generate_code_expr_mandatory(expr);
12307 else u.expr.ti1->generate_code(expr);
12308 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12309 else expr->expr = mputstr(expr->expr, ".substr(");
12310 if (!par1_is_str && u.expr.v2->is_unfoldable())
12311 expr->expr = mputstr(expr->expr, "(int)");
12312 u.expr.v2->generate_code_expr_mandatory(expr);
12313 expr->expr = mputstr(expr->expr, ", ");
12314 if (!par1_is_str && u.expr.v3->is_unfoldable())
12315 expr->expr = mputstr(expr->expr, "(int)");
12316 u.expr.v3->generate_code_expr_mandatory(expr);
12317 expr->expr = mputc(expr->expr, ')');
12318 }
12319
12320 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
12321 {
12322 expression_struct expr_tmp;
12323 Code::init_expr(&expr_tmp);
12324 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
12325 ->get_type_refd_last();
12326 if (!t1 || t1 == my_governor->get_type_refd_last())
12327 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12328 if (u.expr.v_optype == OPTYPE_SUBSTR) {
12329 generate_code_expr_substr(&expr_tmp);
12330 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
12331 generate_code_expr_replace(&expr_tmp);
12332 } else {
12333 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12334 }
12335 // Two temporaries to store the result of substr() or replace() and to
12336 // store the converted value.
12337 const string& tmp_id1 = get_temporary_id();
12338 const char *tmp_id_str1 = tmp_id1.c_str();
12339 const string& tmp_id2 = get_temporary_id();
12340 const char *tmp_id_str2 = tmp_id2.c_str();
12341 if (expr_tmp.preamble)
12342 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12343 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12344 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12345 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12346 if (expr_tmp.postamble)
12347 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12348 Code::free_expr(&expr_tmp);
12349 expr->preamble = mputprintf(expr->preamble,
12350 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12351 "`%s' are not compatible at run-time\");\n",
12352 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12353 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12354 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12355 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12356 }
12357
12358 void Value::generate_code_expr_regexp(expression_struct *expr)
12359 {
12360 Value* v1 = u.expr.ti1->get_specific_value();
12361 Value* v2 = u.expr.t2->get_specific_value();
12362 expr->expr = mputstr(expr->expr, "regexp(");
12363 if (v1) v1->generate_code_expr_mandatory(expr);
12364 else u.expr.ti1->generate_code(expr);
12365 expr->expr = mputstr(expr->expr, ", ");
12366 if (v2) v2->generate_code_expr_mandatory(expr);
12367 else u.expr.t2->generate_code(expr);
12368 expr->expr = mputstr(expr->expr, ", ");
12369 u.expr.v3->generate_code_expr_mandatory(expr);
12370 expr->expr = mputc(expr->expr, ')');
12371 }
12372
12373 void Value::generate_code_expr_replace(expression_struct *expr)
12374 {
12375 Value* v1 = u.expr.ti1->get_specific_value();
12376 Value* v4 = u.expr.ti4->get_specific_value();
12377 bool par1_is_str;
12378 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12379 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12380 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12381 if (v1) v1->generate_code_expr_mandatory(expr);
12382 else u.expr.ti1->generate_code(expr);
12383 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12384 else expr->expr = mputstr(expr->expr, ".replace(");
12385 if (!par1_is_str && u.expr.v2->is_unfoldable())
12386 expr->expr = mputstr(expr->expr, "(int)");
12387 u.expr.v2->generate_code_expr_mandatory(expr);
12388 expr->expr = mputstr(expr->expr, ", ");
12389 if (!par1_is_str && u.expr.v3->is_unfoldable())
12390 expr->expr = mputstr(expr->expr, "(int)");
12391 u.expr.v3->generate_code_expr_mandatory(expr);
12392 expr->expr = mputstr(expr->expr, ", ");
12393 if (v4) {
12394 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12395 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12396 Value* v4_last = v4->get_value_refd_last();
12397 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12398 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
12399 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
12400 }
12401 v4->generate_code_expr_mandatory(expr);
12402 }
12403 else u.expr.ti4->generate_code(expr);
12404 expr->expr = mputc(expr->expr, ')');
12405 }
12406
12407 void Value::generate_code_expr_rnd(expression_struct *expr,
12408 Value *v1)
12409 {
12410 if(!v1) // simple random generation
12411 expr->expr = mputstr(expr->expr, "rnd()");
12412 else { // random generation with seeding
12413 expr->expr = mputstr(expr->expr, "rnd(");
12414 v1->generate_code_expr_mandatory(expr);
12415 expr->expr = mputc(expr->expr, ')');
12416 }
12417 }
12418
12419 void Value::generate_code_expr_create(expression_struct *expr,
12420 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12421 {
12422 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12423 // first two arguments: component type
12424 Assignment *t_ass = type->get_refd_assignment();
12425 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12426 FATAL_ERROR("Value::generate_code_expr_create()");
12427 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12428 Type::EXPECTED_DYNAMIC_VALUE);
12429 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12430 comptype = comptype->get_type_refd_last();
12431 expr->expr = comptype->get_CompBody()
12432 ->generate_code_comptype_name(expr->expr);
12433 expr->expr = mputstr(expr->expr, ", ");
12434 // third argument: component name
12435 if (name) {
12436 Value *t_val = name->get_value_refd_last();
12437 if (t_val->valuetype == V_CSTR) {
12438 // the argument is foldable to a string literal
12439 size_t str_len = t_val->u.str.val_str->size();
12440 const char *str_ptr = t_val->u.str.val_str->c_str();
12441 expr->expr = mputc(expr->expr, '"');
12442 for (size_t i = 0; i < str_len; i++)
12443 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12444 expr->expr = mputc(expr->expr, '"');
12445 } else name->generate_code_expr_mandatory(expr);
12446 } else expr->expr = mputstr(expr->expr, "NULL");
12447 expr->expr = mputstr(expr->expr, ", ");
12448 // fourth argument: location
12449 if (location) {
12450 Value *t_val = location->get_value_refd_last();
12451 if (t_val->valuetype == V_CSTR) {
12452 // the argument is foldable to a string literal
12453 size_t str_len = t_val->u.str.val_str->size();
12454 const char *str_ptr = t_val->u.str.val_str->c_str();
12455 expr->expr = mputc(expr->expr, '"');
12456 for (size_t i = 0; i < str_len; i++)
12457 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12458 expr->expr = mputc(expr->expr, '"');
12459 } else location->generate_code_expr_mandatory(expr);
12460 } else expr->expr = mputstr(expr->expr, "NULL");
12461 // fifth argument: alive flag
12462 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12463 }
12464
12465 void Value::generate_code_expr_activate(expression_struct *expr)
12466 {
12467 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12468 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12469 FATAL_ERROR("Value::generate_code_expr_activate()");
12470 expr->expr = mputprintf(expr->expr, "%s(",
12471 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12472 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12473 expr->expr = mputc(expr->expr, ')');
12474 }
12475
12476 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12477 {
12478 Value *v_last = u.expr.v1->get_value_refd_last();
12479 if (v_last->valuetype == V_ALTSTEP) {
12480 // the referred altstep is known
12481 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12482 ->get_genname_from_scope(my_scope, "activate_").c_str());
12483 } else {
12484 // the referred altstep is unknown
12485 u.expr.v1->generate_code_expr_mandatory(expr);
12486 expr->expr = mputstr(expr->expr,".activate(");
12487 }
12488 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12489 expr->expr = mputc(expr->expr, ')');
12490 }
12491
12492 void Value::generate_code_expr_execute(expression_struct *expr)
12493 {
12494 Assignment *testcase = u.expr.r1->get_refd_assignment();
12495 expr->expr = mputprintf(expr->expr, "%s(",
12496 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12497 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12498 if (parlist->get_nof_pars() > 0) {
12499 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12500 0, false);
12501 expr->expr = mputstr(expr->expr, ", ");
12502 }
12503 if (u.expr.v2) {
12504 expr->expr = mputstr(expr->expr, "TRUE, ");
12505 u.expr.v2->generate_code_expr_mandatory(expr);
12506 expr->expr = mputc(expr->expr, ')');
12507 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12508 }
12509
12510 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12511 {
12512 Value *v_last = u.expr.v1->get_value_refd_last();
12513 if (v_last->valuetype == V_TESTCASE) {
12514 // the referred testcase is known
12515 Assignment *testcase = v_last->get_refd_fat();
12516 expr->expr = mputprintf(expr->expr, "%s(",
12517 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12518 u.expr.ap_list2->generate_code_alias(expr,
12519 testcase->get_FormalParList(), 0, false);
12520 } else {
12521 // the referred testcase is unknown
12522 u.expr.v1->generate_code_expr_mandatory(expr);
12523 expr->expr = mputstr(expr->expr,".execute(");
12524 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12525 }
12526 if (u.expr.ap_list2->get_nof_pars() > 0)
12527 expr->expr = mputstr(expr->expr, ", ");
12528 if (u.expr.v3) {
12529 expr->expr = mputstr(expr->expr, "TRUE, ");
12530 u.expr.v3->generate_code_expr_mandatory(expr);
12531 expr->expr = mputc(expr->expr, ')');
12532 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12533 }
12534
12535 void Value::generate_code_expr_invoke(expression_struct *expr)
12536 {
12537 Value *last_v = u.invoke.v->get_value_refd_last();
12538 if (last_v->get_valuetype() == V_FUNCTION) {
12539 // the referred function is known
12540 Assignment *function = last_v->get_refd_fat();
12541 expr->expr = mputprintf(expr->expr, "%s(",
12542 function->get_genname_from_scope(my_scope).c_str());
12543 u.invoke.ap_list->generate_code_alias(expr,
12544 function->get_FormalParList(), function->get_RunsOnType(), false);
12545 } else {
12546 // the referred function is unknown
12547 u.invoke.v->generate_code_expr_mandatory(expr);
12548 expr->expr = mputstr(expr->expr, ".invoke(");
12549 Type* gov_last = last_v->get_expr_governor_last();
12550 u.invoke.ap_list->generate_code_alias(expr, 0,
12551 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12552 }
12553 expr->expr = mputc(expr->expr, ')');
12554 }
12555
12556 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12557 Reference *ref)
12558 {
12559 // if the referenced value points to an optional value field the
12560 // generated code has to be corrected at the end:
12561 // `fieldid()' => `fieldid()()'
12562 Assignment *ass = ref->get_refd_assignment();
12563 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12564 switch (ass->get_asstype()) {
12565 case Assignment::A_CONST:
12566 case Assignment::A_EXT_CONST:
12567 case Assignment::A_MODULEPAR:
12568 case Assignment::A_VAR:
12569 case Assignment::A_FUNCTION_RVAL:
12570 case Assignment::A_EXT_FUNCTION_RVAL:
12571 case Assignment::A_PAR_VAL_IN:
12572 case Assignment::A_PAR_VAL_OUT:
12573 case Assignment::A_PAR_VAL_INOUT:
12574 // only these are mapped to value objects
12575 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12576 expr->expr = mputstr(expr->expr, "()");
12577 break;
12578 default:
12579 break;
12580 }
12581 }
12582
12583 void Value::generate_code_expr_encode(expression_struct *expr)
12584 {
12585 Value* v1 = 0;
12586
12587 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12588 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12589 v1 = templ->get_specific_value();
12590 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12591
12592 expression_struct expr2;
12593 Code::init_expr(&expr2);
12594
12595 bool is_templ = false;
12596 switch (templ->get_templatetype()) {
12597 case Template::SPECIFIC_VALUE:
12598 v1->generate_code_expr_mandatory(&expr2);
12599 break;
12600 default:
12601 u.expr.ti1->generate_code(&expr2);
12602 is_templ = true;
12603 break;
12604 }
12605
12606 if (!gov_last->is_coding_by_function()) {
12607 const string& tmp_id = get_temporary_id();
12608 const string& tmp_buf_id = get_temporary_id();
12609 const string& tmp_ref_id = get_temporary_id();
12610 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12611 tmp_id.c_str());
12612 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12613 tmp_buf_id.c_str());
12614 if (expr2.preamble) { // copy preamble setting up the argument, if any
12615 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12616 expr->preamble = mputc (expr->preamble, '\n');
12617 }
12618 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12619 gov_last->get_genname_typedescriptor(
12620 u.expr.ti1->get_Template()->get_my_scope()
12621 ).c_str(),
12622 tmp_ref_id.c_str(),
12623 expr2.expr);
12624 if (is_templ) // make a value out of the template, if needed
12625 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12626 expr->preamble = mputprintf(expr->preamble,
12627 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12628 tmp_ref_id.c_str(),
12629 gov_last->get_genname_typedescriptor(
12630 u.expr.ti1->get_Template()->get_my_scope()
12631 ).c_str(),
12632 tmp_buf_id.c_str(),
12633 gov_last->get_coding(true).c_str()
12634 );
12635 expr->preamble = mputstr(expr->preamble, ");\n");
12636 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12637 tmp_buf_id.c_str(),
12638 tmp_id.c_str()
12639 );
12640 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12641 if (expr2.postamble)
12642 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12643 } else
12644 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12645 gov_last->get_coding(true).c_str(), expr2.expr,
12646 is_templ ? ".valueof()" : "");
12647 Code::free_expr(&expr2);
12648 }
12649
12650 void Value::generate_code_expr_decode(expression_struct *expr)
12651 {
12652 expression_struct expr1, expr2;
12653 Code::init_expr(&expr1);
12654 Code::init_expr(&expr2);
12655 u.expr.r1->generate_code(&expr1);
12656 u.expr.r2->generate_code(&expr2);
12657
12658 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12659 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12660 get_type_refd_last();
12661
12662 if (expr1.preamble)
12663 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12664 if (expr2.preamble)
12665 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12666
12667 if (!_type->is_coding_by_function()) {
12668 const string& tmp_id = get_temporary_id();
12669 const string& buffer_id = get_temporary_id();
12670 const string& retval_id = get_temporary_id();
12671 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12672 field_is_optional(u.expr.r2->get_subrefs());
12673
12674 expr->preamble = mputprintf(expr->preamble,
12675 "TTCN_Buffer %s(bit2oct(%s));\n"
12676 "INTEGER %s;\n"
12677 "TTCN_EncDec::set_error_behavior("
12678 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12679 "TTCN_EncDec::clear_error();\n",
12680 buffer_id.c_str(),
12681 expr1.expr,
12682 retval_id.c_str()
12683 );
12684 expr->preamble = mputprintf(expr->preamble,
12685 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12686 expr2.expr,
12687 optional ? "()" : "",
12688 _type->get_genname_typedescriptor(
12689 u.expr.r2->get_my_scope()
12690 ).c_str(),
12691 buffer_id.c_str(),
12692 _type->get_coding(false).c_str()
12693 );
12694 expr->preamble = mputprintf(expr->preamble,
12695 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12696 "case TTCN_EncDec::ET_NONE: {\n"
12697 "%s.cut();\n"
12698 "OCTETSTRING %s;\n"
12699 "%s.get_string(%s);\n"
12700 "%s = oct2bit(%s);\n"
12701 "%s = 0;\n"
12702 "}break;\n"
12703 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12704 "case TTCN_EncDec::ET_LEN_ERR:\n"
12705 "%s = 2;\n"
12706 "break;\n"
12707 "default:\n"
12708 "%s = 1;\n"
12709 "}\n"
12710 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12711 "TTCN_EncDec::EB_DEFAULT);\n"
12712 "TTCN_EncDec::clear_error();\n",
12713 buffer_id.c_str(),
12714 tmp_id.c_str(),
12715 buffer_id.c_str(),
12716 tmp_id.c_str(),
12717 expr1.expr,
12718 tmp_id.c_str(),
12719 retval_id.c_str(),
12720 retval_id.c_str(),
12721 retval_id.c_str()
12722 );
12723 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12724 } else
12725 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12726 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12727 if (expr1.postamble)
12728 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12729 if (expr2.postamble)
12730 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12731 Code::free_expr(&expr1);
12732 Code::free_expr(&expr2);
12733 }
12734
12735 void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
12736 {
12737 Value* v1 = 0;
12738
12739 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12740 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12741 v1 = templ->get_specific_value();
12742 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12743
12744 expression_struct expr2;
12745 Code::init_expr(&expr2);
12746
12747 bool is_templ = false;
12748 switch (templ->get_templatetype()) {
12749 case Template::SPECIFIC_VALUE:
12750 v1->generate_code_expr_mandatory(&expr2);
12751 break;
12752 default:
12753 u.expr.ti1->generate_code(&expr2);
12754 is_templ = true;
12755 break;
12756 }
12757
12758 if (!gov_last->is_coding_by_function()) {
12759 const string& tmp_id = get_temporary_id();
12760 const string& tmp_buf_id = get_temporary_id();
12761 const string& tmp_ref_id = get_temporary_id();
12762 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12763 tmp_id.c_str());
12764 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12765 tmp_buf_id.c_str());
12766 if (expr2.preamble) { // copy preamble setting up the argument, if any
12767 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12768 expr->preamble = mputc (expr->preamble, '\n');
12769 }
12770 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12771 gov_last->get_genname_typedescriptor(
12772 u.expr.ti1->get_Template()->get_my_scope()
12773 ).c_str(),
12774 tmp_ref_id.c_str(),
12775 expr2.expr);
12776 if (is_templ) // make a value out of the template, if needed
12777 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12778 expr->preamble = mputprintf(expr->preamble,
12779 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12780 tmp_ref_id.c_str(),
12781 gov_last->get_genname_typedescriptor(
12782 u.expr.ti1->get_Template()->get_my_scope()
12783 ).c_str(),
12784 tmp_buf_id.c_str(),
12785 gov_last->get_coding(true).c_str()
12786 );
12787 expr->preamble = mputstr(expr->preamble, ");\n");
12788 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12789 tmp_buf_id.c_str(),
12790 tmp_id.c_str()
12791 );
12792 const char * v2_code = NULL;
12793 if(u.expr.v2) {
12794 v2_code = generate_code_char_coding_check(expr, u.expr.v2, "encvalue_unichar");
12795 }
12796 expr->expr = mputprintf(expr->expr, "oct2unichar(%s", tmp_id.c_str());
12797 if(u.expr.v2) {
12798 expr->expr = mputprintf(expr->expr, ", %s", v2_code);
12799 } else {
12800 expr->expr = mputprintf(expr->expr, ", \"UTF-8\""); //default
12801 }
12802 expr->expr = mputprintf(expr->expr, ")");
12803 if (expr2.postamble)
12804 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12805 } else
12806 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12807 gov_last->get_coding(true).c_str(), expr2.expr,
12808 is_templ ? ".valueof()" : "");
12809 Code::free_expr(&expr2);
12810 }
12811
12812 void Value::generate_code_expr_decvalue_unichar(expression_struct *expr)
12813 {
12814 expression_struct expr1, expr2;
12815 Code::init_expr(&expr1);
12816 Code::init_expr(&expr2);
12817 u.expr.r1->generate_code(&expr1);
12818 u.expr.r2->generate_code(&expr2);
12819
12820 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12821 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12822 get_type_refd_last();
12823
12824 if (expr1.preamble)
12825 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12826 if (expr2.preamble)
12827 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12828
12829 if (!_type->is_coding_by_function()) {
12830 const string& tmp_id = get_temporary_id();
12831 const string& buffer_id = get_temporary_id();
12832 const string& retval_id = get_temporary_id();
12833 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12834 field_is_optional(u.expr.r2->get_subrefs());
12835
12836 const char* v3_code = NULL;
12837 if(u.expr.v3) {
12838 v3_code = generate_code_char_coding_check(expr, u.expr.v3, "decvalue_unichar");
12839 }
12840 expr->preamble = mputprintf(expr->preamble,
12841 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12842 "INTEGER %s;\n"
12843 "TTCN_EncDec::set_error_behavior("
12844 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12845 "TTCN_EncDec::clear_error();\n",
12846 buffer_id.c_str(),
12847 expr1.expr,
12848 u.expr.v3 ? v3_code : "\"UTF-8\"",
12849 retval_id.c_str()
12850 );
12851 expr->preamble = mputprintf(expr->preamble,
12852 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12853 expr2.expr,
12854 optional ? "()" : "",
12855 _type->get_genname_typedescriptor(
12856 u.expr.r2->get_my_scope()
12857 ).c_str(),
12858 buffer_id.c_str(),
12859 _type->get_coding(false).c_str()
12860 );
12861 expr->preamble = mputprintf(expr->preamble,
12862 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12863 "case TTCN_EncDec::ET_NONE: {\n"
12864 "%s.cut();\n"
12865 "OCTETSTRING %s;\n"
12866 "%s.get_string(%s);\n"
12867 "%s = oct2unichar(%s, %s);\n"
12868 "%s = 0;\n"
12869 "}break;\n"
12870 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12871 "case TTCN_EncDec::ET_LEN_ERR:\n"
12872 "%s = 2;\n"
12873 "break;\n"
12874 "default:\n"
12875 "%s = 1;\n"
12876 "}\n"
12877 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12878 "TTCN_EncDec::EB_DEFAULT);\n"
12879 "TTCN_EncDec::clear_error();\n",
12880 buffer_id.c_str(),
12881 tmp_id.c_str(),
12882 buffer_id.c_str(),
12883 tmp_id.c_str(),
12884 expr1.expr,
12885 tmp_id.c_str(),
12886 u.expr.v3 ? v3_code : "\"UTF-8\"",
12887 retval_id.c_str(),
12888 retval_id.c_str(),
12889 retval_id.c_str()
12890 );
12891 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12892 } else
12893 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12894 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12895 if (expr1.postamble)
12896 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12897 if (expr2.postamble)
12898 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12899 Code::free_expr(&expr1);
12900 Code::free_expr(&expr2);
12901 }
12902
12903 void Value::generate_code_expr_checkstate(expression_struct *expr)
12904 {
12905 if (u.expr.r1) {
12906 // It is a port if r1 is not null
12907 u.expr.r1->generate_code_const_ref(expr);
12908 expr->expr = mputstr(expr->expr, ".");
12909 } else {
12910 // it is an any or all port if r1 is null
12911 if (u.expr.v_optype == OPTYPE_CHECKSTATE_ANY) {
12912 expr->expr = mputstr(expr->expr, "PORT::any_");
12913 } else if (u.expr.v_optype == OPTYPE_CHECKSTATE_ALL) {
12914 expr->expr = mputstr(expr->expr, "PORT::all_");
12915 } else {
12916 FATAL_ERROR("Value::generate_code_expr_checkstate()");
12917 }
12918 }
12919 expr->expr = mputstr(expr->expr, "check_port_state(");
12920 u.expr.v2->generate_code_expr_mandatory(expr);
12921 expr->expr = mputstr(expr->expr, ")");
12922 }
12923
12924 char* Value::generate_code_char_coding_check(expression_struct *expr, Value *v, const char *name)
12925 {
12926 expression_struct expr2;
12927 Code::init_expr(&expr2);
12928 v->generate_code_expr_mandatory(&expr2);
12929 expr->preamble = mputprintf(expr->preamble,
12930 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12931 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12932 " \"UTF-32BE\" != %s) {\n"
12933 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12934 "}\n", //todo errorbehaviour?
12935 expr2.expr,
12936 expr2.expr,
12937 expr2.expr,
12938 expr2.expr,
12939 expr2.expr,
12940 expr2.expr,
12941 expr2.expr,
12942 name,
12943 expr2.expr);
12944 return expr2.expr;
12945 }
12946
12947 char *Value::generate_code_init_choice(char *str, const char *name)
12948 {
12949 const char *alt_name = u.choice.alt_name->get_name().c_str();
12950 // Safe as long as get_name() returns a const string&, not a temporary.
12951 const char *alt_prefix =
12952 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
12953 ? "AT_" : "";
12954 if (u.choice.alt_value->needs_temp_ref()) {
12955 const string& tmp_id = get_temporary_id();
12956 const char *tmp_id_str = tmp_id.c_str();
12957 str = mputprintf(str, "{\n"
12958 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
12959 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
12960 alt_prefix, alt_name);
12961 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
12962 str = mputstr(str, "}\n");
12963 } else {
12964 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
12965 str = u.choice.alt_value->generate_code_init(str, embedded_name);
12966 Free(embedded_name);
12967 }
12968 return str;
12969 }
12970
12971 char *Value::generate_code_init_seof(char *str, const char *name)
12972 {
12973 size_t nof_vs = u.val_vs->get_nof_vs();
12974 if (nof_vs > 0) {
12975 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
12976 const string& embedded_type =
12977 my_governor->get_ofType()->get_genname_value(my_scope);
12978 const char *embedded_type_str = embedded_type.c_str();
12979 for (size_t i = 0; i < nof_vs; i++) {
12980 Value *comp_v = u.val_vs->get_v_byIndex(i);
12981
12982 if (comp_v->valuetype == V_NOTUSED) continue;
12983 else if (comp_v->needs_temp_ref()) {
12984 const string& tmp_id = get_temporary_id();
12985 const char *tmp_id_str = tmp_id.c_str();
12986 str = mputprintf(str, "{\n"
12987 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
12988 (unsigned long) i);
12989 str = comp_v->generate_code_init(str, tmp_id_str);
12990 str = mputstr(str, "}\n");
12991 } else {
12992 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
12993 str = comp_v->generate_code_init(str, embedded_name);
12994 Free(embedded_name);
12995 }
12996 }
12997 } else {
12998 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
12999 }
13000 return str;
13001 }
13002
13003 char *Value::generate_code_init_indexed(char *str, const char *name)
13004 {
13005 size_t nof_ivs = u.val_vs->get_nof_ivs();
13006 if (nof_ivs > 0) {
13007 // Previous values can be truncated. The concept is similar to
13008 // templates.
13009 Type *t_last = my_governor->get_type_refd_last();
13010 const string& oftype_name =
13011 t_last->get_ofType()->get_genname_value(my_scope);
13012 const char *oftype_name_str = oftype_name.c_str();
13013 for (size_t i = 0; i < nof_ivs; i++) {
13014 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
13015 const string& tmp_id_1 = get_temporary_id();
13016 str = mputstr(str, "{\n");
13017 Value *index = iv->get_index();
13018 if (index->get_valuetype() != V_INT) {
13019 const string& tmp_id_2 = get_temporary_id();
13020 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
13021 str = index->generate_code_init(str, tmp_id_2.c_str());
13022 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
13023 tmp_id_1.c_str(), name, tmp_id_2.c_str());
13024 } else {
13025 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
13026 tmp_id_1.c_str(), name,
13027 (index->get_val_Int()->t_str()).c_str());
13028 }
13029 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
13030 str = mputstr(str, "}\n");
13031 }
13032 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
13033 return str;
13034 }
13035
13036 char *Value::generate_code_init_array(char *str, const char *name)
13037 {
13038 size_t nof_vs = u.val_vs->get_nof_vs();
13039 Type *t_last = my_governor->get_type_refd_last();
13040 Int index_offset = t_last->get_dimension()->get_offset();
13041 const string& embedded_type =
13042 t_last->get_ofType()->get_genname_value(my_scope);
13043 const char *embedded_type_str = embedded_type.c_str();
13044 for (size_t i = 0; i < nof_vs; i++) {
13045 Value *comp_v = u.val_vs->get_v_byIndex(i);
13046 if (comp_v->valuetype == V_NOTUSED) continue;
13047 else if (comp_v->needs_temp_ref()) {
13048 const string& tmp_id = get_temporary_id();
13049 const char *tmp_id_str = tmp_id.c_str();
13050 str = mputprintf(str, "{\n"
13051 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
13052 Int2string(index_offset + i).c_str());
13053 str = comp_v->generate_code_init(str, tmp_id_str);
13054 str = mputstr(str, "}\n");
13055 } else {
13056 char *embedded_name = mprintf("%s[%s]", name,
13057 Int2string(index_offset + i).c_str());
13058 str = comp_v->generate_code_init(str, embedded_name);
13059 Free(embedded_name);
13060 }
13061 }
13062 return str;
13063 }
13064
13065 char *Value::generate_code_init_se(char *str, const char *name)
13066 {
13067 Type *type = my_governor->get_type_refd_last();
13068 size_t nof_comps = type->get_nof_comps();
13069 if (nof_comps > 0) {
13070 for (size_t i = 0; i < nof_comps; i++) {
13071 CompField *cf = type->get_comp_byIndex(i);
13072 const Identifier& field_id = cf->get_name();
13073 const char *field_name = field_id.get_name().c_str();
13074 Value *field_v;
13075 if (u.val_nvs->has_nv_withName(field_id)) {
13076 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
13077 if (field_v->valuetype == V_NOTUSED) continue;
13078 if (field_v->valuetype == V_OMIT) field_v = 0;
13079 } else if (is_asn1()) {
13080 if (cf->has_default()) {
13081 // handle like a referenced value
13082 Value *defval = cf->get_defval();
13083 if (needs_init_precede(defval)) {
13084 str = defval->generate_code_init(str,
13085 defval->get_lhs_name().c_str());
13086 }
13087 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
13088 defval->get_genname_own(my_scope).c_str());
13089 continue;
13090 } else {
13091 if (!cf->get_is_optional())
13092 FATAL_ERROR("Value::generate_code_init()");
13093 field_v = 0;
13094 }
13095 } else {
13096 continue;
13097 }
13098 if (field_v) {
13099 // the value is not omit
13100 if (field_v->needs_temp_ref()) {
13101 const string& tmp_id = get_temporary_id();
13102 const char *tmp_id_str = tmp_id.c_str();
13103 str = mputprintf(str, "{\n"
13104 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
13105 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
13106 field_name);
13107 str = field_v->generate_code_init(str, tmp_id_str);
13108 str = mputstr(str, "}\n");
13109 } else {
13110 char *embedded_name = mprintf("%s.%s()", name,
13111 field_name);
13112 if (cf->get_is_optional() && field_v->is_compound())
13113 embedded_name = mputstr(embedded_name, "()");
13114 str = field_v->generate_code_init(str, embedded_name);
13115 Free(embedded_name);
13116 }
13117 } else {
13118 // the value is omit
13119 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
13120 name, field_name);
13121 }
13122 }
13123 } else {
13124 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
13125 }
13126 return str;
13127 }
13128
13129 char *Value::generate_code_init_refd(char *str, const char *name)
13130 {
13131 Value *v = get_value_refd_last();
13132 if (v == this) {
13133 // the referred value is not available at compile time
13134 // the code generation is based on the reference
13135 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
13136 str = TypeConv::gen_conv_code_refd(str, name, v);
13137 } else {
13138 expression_struct expr;
13139 Code::init_expr(&expr);
13140 expr.expr = mputprintf(expr.expr, "%s = ", name);
13141 u.ref.ref->generate_code_const_ref(&expr);
13142 str = Code::merge_free_expr(str, &expr);
13143 }
13144 } else {
13145 // the referred value is available at compile time
13146 // the code generation is based on the referred value
13147 if (v->has_single_expr() &&
13148 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
13149 // simple substitution for in-line values within the same module
13150 str = mputprintf(str, "%s = %s;\n", name,
13151 v->get_single_expr().c_str());
13152 } else {
13153 // use a simple reference to reduce code size
13154 if (needs_init_precede(v)) {
13155 // the referred value must be initialized first
13156 if (!v->is_toplevel() && v->needs_temp_ref()) {
13157 // temporary id should be introduced for the lhs
13158 const string& tmp_id = get_temporary_id();
13159 const char *tmp_id_str = tmp_id.c_str();
13160 str = mputprintf(str, "{\n"
13161 "%s& %s = %s;\n",
13162 v->get_my_governor()->get_genname_value(my_scope).c_str(),
13163 tmp_id_str, v->get_lhs_name().c_str());
13164 str = v->generate_code_init(str, tmp_id_str);
13165 str = mputstr(str, "}\n");
13166 } else {
13167 str = v->generate_code_init(str, v->get_lhs_name().c_str());
13168 }
13169 }
13170 str = mputprintf(str, "%s = %s;\n", name,
13171 v->get_genname_own(my_scope).c_str());
13172 }
13173 }
13174 return str;
13175 }
13176
13177 void Value::generate_json_value(JSON_Tokenizer& json,
13178 bool allow_special_float, /* = true */
13179 bool union_value_list, /* = false */
13180 Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
13181 {
13182 switch (valuetype) {
13183 case V_INT:
13184 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
13185 break;
13186 case V_REAL: {
13187 Real r = get_val_Real();
13188 if (r == REAL_INFINITY) {
13189 if (allow_special_float) {
13190 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
13191 }
13192 }
13193 else if (r == -REAL_INFINITY) {
13194 if (allow_special_float) {
13195 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
13196 }
13197 }
13198 else if (r != r) {
13199 if (allow_special_float) {
13200 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
13201 }
13202 }
13203 else {
13204 // true if decimal representation possible (use %f format)
13205 bool decimal_repr = (r == 0.0)
13206 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
13207 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
13208 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
13209 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
13210 Free(number_str);
13211 }
13212 break; }
13213 case V_BOOL:
13214 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
13215 break;
13216 case V_BSTR:
13217 case V_HSTR:
13218 case V_OSTR:
13219 case V_CSTR: {
13220 char* str = convert_to_json_string(get_val_str().c_str());
13221 json.put_next_token(JSON_TOKEN_STRING, str);
13222 Free(str);
13223 break; }
13224 case V_USTR: {
13225 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13226 json.put_next_token(JSON_TOKEN_STRING, str);
13227 Free(str);
13228 break; }
13229 case V_VERDICT:
13230 case V_ENUM:
13231 json.put_next_token(JSON_TOKEN_STRING,
13232 (string('\"') + create_stringRepr() + string('\"')).c_str());
13233 break;
13234 case V_SEQOF:
13235 case V_SETOF:
13236 json.put_next_token(JSON_TOKEN_ARRAY_START);
13237 if (!u.val_vs->is_indexed()) {
13238 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
13239 u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
13240 union_value_list, omit_combo);
13241 }
13242 }
13243 else {
13244 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
13245 // look for the entry with index equal to i
13246 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
13247 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
13248 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
13249 allow_special_float, union_value_list, omit_combo);
13250 break;
13251 }
13252 }
13253 }
13254 }
13255 json.put_next_token(JSON_TOKEN_ARRAY_END);
13256 break;
13257 case V_SEQ:
13258 case V_SET: {
13259 // omitted fields have 2 possible JSON values (the field is absent, or it's
13260 // present with value 'null'), each combination of omitted values must be
13261 // generated
13262 if (omit_combo == NULL) {
13263 FATAL_ERROR("Value::generate_json_value - no combo");
13264 }
13265 size_t len = get_nof_comps();
13266 // generate the JSON object from the present combination
13267 json.put_next_token(JSON_TOKEN_OBJECT_START);
13268 for (size_t i = 0; i < len; ++i) {
13269 Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
13270 if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
13271 // the field is absent, don't insert anything
13272 continue;
13273 }
13274 // use the field's alias, if it has one
13275 const char* alias = NULL;
13276 if (my_governor != NULL) {
13277 JsonAST* field_attrib = my_governor->get_comp_byName(
13278 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
13279 if (field_attrib != NULL) {
13280 alias = field_attrib->alias;
13281 }
13282 }
13283 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13284 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
13285 if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
13286 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
13287 }
13288 else {
13289 get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
13290 allow_special_float, union_value_list, omit_combo);
13291 }
13292 }
13293 json.put_next_token(JSON_TOKEN_OBJECT_END);
13294 break; }
13295 case V_CHOICE: {
13296 bool as_value = !union_value_list && my_governor != NULL &&
13297 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
13298 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
13299 if (!as_value) {
13300 // no 'as value' coding instruction, insert an object with one field
13301 json.put_next_token(JSON_TOKEN_OBJECT_START);
13302 // use the field's alias, if it has one
13303 const char* alias = NULL;
13304 if (my_governor != NULL) {
13305 JsonAST* field_attrib = my_governor->get_comp_byName(
13306 get_alt_name())->get_type()->get_json_attributes();
13307 if (field_attrib != NULL) {
13308 alias = field_attrib->alias;
13309 }
13310 }
13311 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13312 get_alt_name().get_ttcnname().c_str());
13313 }
13314 get_alt_value()->generate_json_value(json, allow_special_float,
13315 union_value_list, omit_combo);
13316 if (!as_value) {
13317 json.put_next_token(JSON_TOKEN_OBJECT_END);
13318 }
13319 break; }
13320 case V_REFD: {
13321 Value* v = get_value_refd_last();
13322 if (this != v) {
13323 v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
13324 return;
13325 }
13326 } // no break
13327 default:
13328 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
13329 }
13330 }
13331
13332 bool Value::explicit_cast_needed(bool forIsValue)
13333 {
13334 Value *v_last = get_value_refd_last();
13335 if (v_last != this) {
13336 // this is a foldable referenced value
13337 // if the reference points to an imported or compound value the code
13338 // generation will be based on the reference so cast is not needed
13339 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
13340 || !v_last->has_single_expr()) return false;
13341 } else if (v_last->valuetype == V_REFD) {
13342 // this is an unfoldable reference (v_last==this)
13343 // explicit cast is needed only for string element references
13344 if (forIsValue) return false;
13345 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
13346 return t_subrefs && t_subrefs->refers_to_string_element();
13347 }
13348 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
13349 Type *t_governor = v_last->my_governor->get_type_refd_last();
13350 switch (t_governor->get_typetype()) {
13351 case Type::T_NULL:
13352 case Type::T_BOOL:
13353 case Type::T_INT:
13354 case Type::T_INT_A:
13355 case Type::T_REAL:
13356 case Type::T_ENUM_A:
13357 case Type::T_ENUM_T:
13358 case Type::T_VERDICT:
13359 case Type::T_COMPONENT:
13360 // these are mapped to built-in C/C++ types
13361 return true;
13362 case Type::T_SEQ_A:
13363 case Type::T_SEQ_T:
13364 case Type::T_SET_A:
13365 case Type::T_SET_T:
13366 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13367 return t_governor->get_nof_comps() == 0;
13368 case Type::T_SEQOF:
13369 case Type::T_SETOF:
13370 // the C++ equivalent of value {} is ambiguous
13371 // tr926
13372 return true;
13373 case Type::T_FUNCTION:
13374 case Type::T_ALTSTEP:
13375 case Type::T_TESTCASE:
13376 return true;
13377 default:
13378 return false;
13379 }
13380 }
13381
13382 bool Value::has_single_expr()
13383 {
13384 if (get_needs_conversion()) return false;
13385 switch (valuetype) {
13386 case V_EXPR:
13387 return has_single_expr_expr();
13388 case V_CHOICE:
13389 case V_ARRAY:
13390 // a union or array value cannot be represented as an in-line expression
13391 return false;
13392 case V_SEQOF:
13393 case V_SETOF:
13394 // only an empty record/set of value can be represented as an in-line
13395 // expression
13396 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
13397 else return u.val_vs->get_nof_ivs() == 0;
13398 case V_SEQ:
13399 case V_SET: {
13400 // only a value for an empty record/set type can be represented as an
13401 // in-line expression
13402 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
13403 Type *type = my_governor->get_type_refd_last();
13404 return type->get_nof_comps() == 0; }
13405 case V_REFD: {
13406 Value *v_last = get_value_refd_last();
13407 // If the above call hit an error and set_valuetype(V_ERROR),
13408 // then u.ref.ref has been freed. Avoid the segfault.
13409 if (valuetype == V_ERROR)
13410 return false;
13411 if (v_last != this && v_last->has_single_expr() &&
13412 v_last->my_scope->get_scope_mod_gen() ==
13413 my_scope->get_scope_mod_gen()) return true;
13414 else return u.ref.ref->has_single_expr(); }
13415 case V_INVOKE:
13416 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
13417 case V_ERROR:
13418 case V_NAMEDINT:
13419 case V_NAMEDBITS:
13420 case V_UNDEF_LOWERID:
13421 case V_UNDEF_BLOCK:
13422 case V_REFER:
13423 // these values cannot occur during code generation
13424 FATAL_ERROR("Value::has_single_expr()");
13425 case V_INT:
13426 return u.val_Int->is_native_fit();
13427 case V_NOTUSED:
13428 // should only happen when generating code for an unbound record/set value
13429 return false;
13430 default:
13431 // other value types (literal values) do not need temporary reference
13432 return true;
13433 }
13434 }
13435
13436 string Value::get_single_expr()
13437 {
13438 switch (valuetype) {
13439 case V_NULL:
13440 return string("ASN_NULL_VALUE");
13441 case V_BOOL:
13442 return string(u.val_bool ? "TRUE" : "FALSE");
13443 case V_INT:
13444 if (u.val_Int->is_native_fit()) { // Be sure.
13445 return u.val_Int->t_str();
13446 } else {
13447 // get_single_expr may be called only if has_single_expr() is true.
13448 // The only exception is V_INT, where get_single_expr may be called
13449 // even if is_native_fit (which is used to implement has_single_expr)
13450 // returns false.
13451 string ret_val('"');
13452 ret_val += u.val_Int->t_str();
13453 ret_val += '"';
13454 return ret_val;
13455 }
13456 case V_REAL:
13457 return Real2code(u.val_Real);
13458 case V_ENUM:
13459 return get_single_expr_enum();
13460 case V_BSTR:
13461 return get_my_scope()->get_scope_mod_gen()
13462 ->add_bitstring_literal(*u.str.val_str);
13463 case V_HSTR:
13464 return get_my_scope()->get_scope_mod_gen()
13465 ->add_hexstring_literal(*u.str.val_str);
13466 case V_OSTR:
13467 return get_my_scope()->get_scope_mod_gen()
13468 ->add_octetstring_literal(*u.str.val_str);
13469 case V_CSTR:
13470 return get_my_scope()->get_scope_mod_gen()
13471 ->add_charstring_literal(*u.str.val_str);
13472 case V_USTR:
13473 if (u.ustr.convert_str) {
13474 set_valuetype(V_CSTR);
13475 return get_my_scope()->get_scope_mod_gen()
13476 ->add_charstring_literal(*u.str.val_str);
13477 } else
13478 return get_my_scope()->get_scope_mod_gen()
13479 ->add_ustring_literal(*u.ustr.val_ustr);
13480 case V_ISO2022STR:
13481 return get_single_expr_iso2022str();
13482 case V_OID:
13483 case V_ROID: {
13484 vector<string> comps;
13485 bool is_constant = get_oid_comps(comps);
13486 size_t nof_comps = comps.size();
13487 string oi_str;
13488 for (size_t i = 0; i < nof_comps; i++) {
13489 if (i > 0) oi_str += ", ";
13490 oi_str += *(comps[i]);
13491 }
13492 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
13493 comps.clear();
13494 if (is_constant) {
13495 // the objid only contains constants
13496 // => create a literal and return its name
13497 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
13498 }
13499 // the objid contains at least one variable
13500 // => append the number of components before the component values in the string and return it
13501 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
13502 case V_SEQOF:
13503 case V_SETOF:
13504 if (u.val_vs->get_nof_vs() > 0)
13505 FATAL_ERROR("Value::get_single_expr()");
13506 return string("NULL_VALUE");
13507 case V_SEQ:
13508 case V_SET:
13509 if (u.val_nvs->get_nof_nvs() > 0)
13510 FATAL_ERROR("Value::get_single_expr()");
13511 return string("NULL_VALUE");
13512 case V_REFD: {
13513 Value *v_last = get_value_refd_last();
13514 if (v_last != this && v_last->has_single_expr() &&
13515 v_last->my_scope->get_scope_mod_gen() ==
13516 my_scope->get_scope_mod_gen()) {
13517 // the reference points to another single value in the same module
13518 return v_last->get_single_expr();
13519 } else {
13520 // convert the reference to a single expression
13521 expression_struct expr;
13522 Code::init_expr(&expr);
13523 u.ref.ref->generate_code_const_ref(&expr);
13524 if (expr.preamble || expr.postamble)
13525 FATAL_ERROR("Value::get_single_expr()");
13526 string ret_val(expr.expr);
13527 Code::free_expr(&expr);
13528 return ret_val;
13529 } }
13530 case V_OMIT:
13531 return string("OMIT_VALUE");
13532 case V_VERDICT:
13533 switch (u.verdict) {
13534 case Verdict_NONE:
13535 return string("NONE");
13536 case Verdict_PASS:
13537 return string("PASS");
13538 case Verdict_INCONC:
13539 return string("INCONC");
13540 case Verdict_FAIL:
13541 return string("FAIL");
13542 case Verdict_ERROR:
13543 return string("ERROR");
13544 default:
13545 FATAL_ERROR("Value::get_single_expr()");
13546 return string();
13547 }
13548 case V_DEFAULT_NULL:
13549 return string("NULL_COMPREF");
13550 case V_FAT_NULL: {
13551 string ret_val('(');
13552 ret_val += my_governor->get_genname_value(my_scope);
13553 ret_val += "::function_pointer)Module_List::get_fat_null()";
13554 return ret_val; }
13555 case V_EXPR:
13556 case V_INVOKE: {
13557 expression_struct expr;
13558 Code::init_expr(&expr);
13559 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13560 else generate_code_expr_invoke(&expr);
13561 if (expr.preamble || expr.postamble)
13562 FATAL_ERROR("Value::get_single_expr()");
13563 string ret_val(expr.expr);
13564 Code::free_expr(&expr);
13565 return ret_val; }
13566 case V_MACRO:
13567 switch (u.macro) {
13568 case MACRO_TESTCASEID:
13569 return string("TTCN_Runtime::get_testcase_id_macro()");
13570 default:
13571 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13572 return string();
13573 }
13574 case V_FUNCTION:
13575 case V_ALTSTEP:
13576 case V_TESTCASE:
13577 return get_single_expr_fat();
13578 default:
13579 FATAL_ERROR("Value::get_single_expr()");
13580 return string();
13581 }
13582 }
13583
13584 bool Value::has_single_expr_expr()
13585 {
13586 switch (u.expr.v_optype) {
13587 case OPTYPE_RND: // -
13588 case OPTYPE_COMP_NULL:
13589 case OPTYPE_COMP_MTC:
13590 case OPTYPE_COMP_SYSTEM:
13591 case OPTYPE_COMP_SELF:
13592 case OPTYPE_COMP_RUNNING_ANY:
13593 case OPTYPE_COMP_RUNNING_ALL:
13594 case OPTYPE_COMP_ALIVE_ANY:
13595 case OPTYPE_COMP_ALIVE_ALL:
13596 case OPTYPE_TMR_RUNNING_ANY:
13597 case OPTYPE_GETVERDICT:
13598 case OPTYPE_TESTCASENAME:
13599 case OPTYPE_PROF_RUNNING:
13600 case OPTYPE_CHECKSTATE_ANY:
13601 case OPTYPE_CHECKSTATE_ALL:
13602 return true;
13603 case OPTYPE_ENCODE:
13604 case OPTYPE_DECODE:
13605 case OPTYPE_ISBOUND:
13606 case OPTYPE_ISPRESENT:
13607 case OPTYPE_TTCN2STRING:
13608 case OPTYPE_ENCVALUE_UNICHAR:
13609 case OPTYPE_DECVALUE_UNICHAR:
13610 return false;
13611 case OPTYPE_UNARYPLUS: // v1
13612 case OPTYPE_UNARYMINUS:
13613 case OPTYPE_NOT:
13614 case OPTYPE_NOT4B:
13615 case OPTYPE_BIT2HEX:
13616 case OPTYPE_BIT2INT:
13617 case OPTYPE_BIT2OCT:
13618 case OPTYPE_BIT2STR:
13619 case OPTYPE_CHAR2INT:
13620 case OPTYPE_CHAR2OCT:
13621 case OPTYPE_FLOAT2INT:
13622 case OPTYPE_FLOAT2STR:
13623 case OPTYPE_HEX2BIT:
13624 case OPTYPE_HEX2INT:
13625 case OPTYPE_HEX2OCT:
13626 case OPTYPE_HEX2STR:
13627 case OPTYPE_INT2CHAR:
13628 case OPTYPE_INT2FLOAT:
13629 case OPTYPE_INT2STR:
13630 case OPTYPE_INT2UNICHAR:
13631 case OPTYPE_OCT2BIT:
13632 case OPTYPE_OCT2CHAR:
13633 case OPTYPE_OCT2HEX:
13634 case OPTYPE_OCT2INT:
13635 case OPTYPE_OCT2STR:
13636 case OPTYPE_STR2BIT:
13637 case OPTYPE_STR2FLOAT:
13638 case OPTYPE_STR2HEX:
13639 case OPTYPE_STR2INT:
13640 case OPTYPE_STR2OCT:
13641 case OPTYPE_UNICHAR2INT:
13642 case OPTYPE_UNICHAR2CHAR:
13643 case OPTYPE_ENUM2INT:
13644 case OPTYPE_RNDWITHVAL:
13645 case OPTYPE_ISCHOSEN_V: // v1 i2
13646 case OPTYPE_COMP_RUNNING:
13647 case OPTYPE_COMP_ALIVE:
13648 case OPTYPE_GET_STRINGENCODING:
13649 case OPTYPE_REMOVE_BOM:
13650 case OPTYPE_DECODE_BASE64:
13651 return u.expr.v1->has_single_expr();
13652 case OPTYPE_ISCHOSEN_T: // t1 i2
13653 return u.expr.t1->has_single_expr();
13654 case OPTYPE_ADD: // v1 v2
13655 case OPTYPE_SUBTRACT:
13656 case OPTYPE_MULTIPLY:
13657 case OPTYPE_DIVIDE:
13658 case OPTYPE_MOD:
13659 case OPTYPE_REM:
13660 case OPTYPE_CONCAT:
13661 case OPTYPE_EQ:
13662 case OPTYPE_LT:
13663 case OPTYPE_GT:
13664 case OPTYPE_NE:
13665 case OPTYPE_GE:
13666 case OPTYPE_LE:
13667 case OPTYPE_XOR:
13668 case OPTYPE_AND4B:
13669 case OPTYPE_OR4B:
13670 case OPTYPE_XOR4B:
13671 case OPTYPE_SHL:
13672 case OPTYPE_SHR:
13673 case OPTYPE_ROTL:
13674 case OPTYPE_ROTR:
13675 case OPTYPE_INT2BIT:
13676 case OPTYPE_INT2HEX:
13677 case OPTYPE_INT2OCT:
13678 return u.expr.v1->has_single_expr() &&
13679 u.expr.v2->has_single_expr();
13680 case OPTYPE_UNICHAR2OCT:
13681 case OPTYPE_OCT2UNICHAR:
13682 case OPTYPE_ENCODE_BASE64:
13683 return u.expr.v1->has_single_expr() &&
13684 (!u.expr.v2 || u.expr.v2->has_single_expr());
13685 case OPTYPE_AND:
13686 case OPTYPE_OR:
13687 return u.expr.v1->has_single_expr() &&
13688 u.expr.v2->has_single_expr() &&
13689 !u.expr.v2->needs_short_circuit();
13690 case OPTYPE_SUBSTR:
13691 return u.expr.ti1->has_single_expr() &&
13692 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13693 case OPTYPE_REGEXP:
13694 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13695 u.expr.v3->has_single_expr();
13696 case OPTYPE_DECOMP: // v1 v2 v3
13697 return u.expr.v1->has_single_expr() &&
13698 u.expr.v2->has_single_expr() &&
13699 u.expr.v3->has_single_expr();
13700 case OPTYPE_REPLACE:
13701 return u.expr.ti1->has_single_expr() &&
13702 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13703 u.expr.ti4->has_single_expr();
13704 case OPTYPE_ISVALUE: // ti1
13705 case OPTYPE_LENGTHOF: // ti1
13706 case OPTYPE_SIZEOF: // ti1
13707 case OPTYPE_VALUEOF: // ti1
13708 return u.expr.ti1->has_single_expr();
13709 case OPTYPE_LOG2STR:
13710 case OPTYPE_ANY2UNISTR:
13711 return u.expr.logargs->has_single_expr();
13712 case OPTYPE_MATCH: // v1 t2
13713 return u.expr.v1->has_single_expr() &&
13714 u.expr.t2->has_single_expr();
13715 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13716 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13717 (!u.expr.v3 || u.expr.v3->has_single_expr());
13718 case OPTYPE_TMR_READ: // r1
13719 case OPTYPE_TMR_RUNNING:
13720 case OPTYPE_ACTIVATE:
13721 return u.expr.r1->has_single_expr();
13722 case OPTYPE_EXECUTE: // r1 [v2]
13723 return u.expr.r1->has_single_expr() &&
13724 (!u.expr.v2 || u.expr.v2->has_single_expr());
13725 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13726 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13727 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13728 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13729 (!u.expr.v3 || u.expr.v3->has_single_expr());
13730 default:
13731 FATAL_ERROR("Value::has_single_expr_expr()");
13732 } // switch
13733 }
13734
13735 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13736 {
13737 if (!v->has_single_expr()) return false;
13738 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13739 if (!ap_list->get_par(i)->has_single_expr()) return false;
13740 return true;
13741 }
13742
13743 string Value::get_single_expr_enum()
13744 {
13745 string ret_val(my_governor->get_genname_value(my_scope));
13746 ret_val += "::";
13747 ret_val += u.val_id->get_name();
13748 return ret_val;
13749 }
13750
13751 string Value::get_single_expr_iso2022str()
13752 {
13753 string ret_val;
13754 Type *type = get_my_governor()->get_type_refd_last();
13755 switch (type->get_typetype()) {
13756 case Type::T_TELETEXSTRING:
13757 ret_val += "TTCN_ISO2022_2_TeletexString";
13758 break;
13759 case Type::T_VIDEOTEXSTRING:
13760 ret_val += "TTCN_ISO2022_2_VideotexString";
13761 break;
13762 case Type::T_GRAPHICSTRING:
13763 case Type::T_OBJECTDESCRIPTOR:
13764 ret_val += "TTCN_ISO2022_2_GraphicString";
13765 break;
13766 case Type::T_GENERALSTRING:
13767 ret_val += "TTCN_ISO2022_2_GeneralString";
13768 break;
13769 default:
13770 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13771 } // switch
13772 ret_val += '(';
13773 string *ostr = char2oct(*u.str.val_str);
13774 ret_val += get_my_scope()->get_scope_mod_gen()
13775 ->add_octetstring_literal(*ostr);
13776 delete ostr;
13777 ret_val += ')';
13778 return ret_val;
13779 }
13780
13781 string Value::get_single_expr_fat()
13782 {
13783 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13784 // the ampersand operator is not really necessary to obtain the function
13785 // pointer, but some older versions of GCC cannot instantiate the
13786 // appropriate operator=() member of class OPTIONAL when necessary
13787 // if only the function name is given
13788 string ret_val('&');
13789 switch (valuetype) {
13790 case V_FUNCTION:
13791 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13792 break;
13793 case V_ALTSTEP:
13794 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13795 ret_val += "_instance";
13796 break;
13797 case V_TESTCASE:
13798 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13799 break;
13800 default:
13801 FATAL_ERROR("Value::get_single_expr_fat()");
13802 }
13803 return ret_val;
13804 }
13805
13806 bool Value::is_compound()
13807 {
13808 switch (valuetype) {
13809 case V_CHOICE:
13810 case V_SEQOF:
13811 case V_SETOF:
13812 case V_ARRAY:
13813 case V_SEQ:
13814 case V_SET:
13815 return true;
13816 default:
13817 return false;
13818 }
13819 }
13820
13821 bool Value::needs_temp_ref()
13822 {
13823 switch (valuetype) {
13824 case V_SEQOF:
13825 case V_SETOF:
13826 if (!is_indexed()) {
13827 // Temporary reference is needed if the value has at least one real
13828 // element (i.e. it is not empty or contains only not used symbols).
13829 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13830 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13831 }
13832 } else {
13833 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13834 if (u.val_vs->get_iv_byIndex(i)->get_value()
13835 ->valuetype != V_NOTUSED)
13836 return true;
13837 }
13838 }
13839 return false;
13840 case V_ARRAY: {
13841 size_t nof_real_vs = 0;
13842 if (!is_indexed()) {
13843 // Temporary reference is needed if the array value has at least two
13844 // real elements (excluding not used symbols).
13845 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13846 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13847 nof_real_vs++;
13848 if (nof_real_vs > 1) return true;
13849 }
13850 }
13851 } else {
13852 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13853 if (u.val_vs->get_iv_byIndex(i)->get_value()
13854 ->valuetype != V_NOTUSED) {
13855 nof_real_vs++;
13856 if (nof_real_vs > 1) return true;
13857 }
13858 }
13859 }
13860 return false; }
13861 case V_SEQ:
13862 case V_SET:
13863 if (is_asn1()) {
13864 // it depends on the type since fields with omit or default value
13865 // may not be present
13866 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13867 } else {
13868 // incomplete values are allowed in TTCN-3
13869 // we should check the number of value components
13870 return u.val_nvs->get_nof_nvs() > 1;
13871 }
13872 case V_ERROR:
13873 case V_NAMEDINT:
13874 case V_NAMEDBITS:
13875 case V_UNDEF_LOWERID:
13876 case V_UNDEF_BLOCK:
13877 case V_TTCN3_NULL:
13878 // these values cannot occur during code generation
13879 FATAL_ERROR("Value::needs_temp_ref()");
13880 case V_INT:
13881 return !u.val_Int->is_native();
13882 default:
13883 // other value types (literal values) do not need temporary reference
13884 return false;
13885 }
13886 }
13887
13888 bool Value::needs_short_circuit()
13889 {
13890 switch (valuetype) {
13891 case V_BOOL:
13892 return false;
13893 case V_REFD:
13894 // examined below
13895 break;
13896 case V_EXPR:
13897 case V_INVOKE:
13898 // sub-expressions should be evaluated only if necessary
13899 return true;
13900 default:
13901 FATAL_ERROR("Value::needs_short_circuit()");
13902 }
13903 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13904 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13905 switch (t_ass->get_asstype()) {
13906 case Assignment::A_FUNCTION_RVAL:
13907 case Assignment::A_EXT_FUNCTION_RVAL:
13908 // avoid unnecessary call of a function
13909 return true;
13910 case Assignment::A_CONST:
13911 case Assignment::A_EXT_CONST:
13912 case Assignment::A_MODULEPAR:
13913 case Assignment::A_VAR:
13914 case Assignment::A_PAR_VAL_IN:
13915 case Assignment::A_PAR_VAL_OUT:
13916 case Assignment::A_PAR_VAL_INOUT:
13917 // depends on field/array sub-references, which is examined below
13918 break;
13919 default:
13920 FATAL_ERROR("Value::needs_short_circuit()");
13921 }
13922 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13923 if (t_subrefs) {
13924 // the evaluation of the reference does not have side effects
13925 // (i.e. false shall be returned) only if all sub-references point to
13926 // mandatory fields of record/set types, and neither sub-reference points
13927 // to a field of a union type
13928 Type *t_type = t_ass->get_Type();
13929 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13930 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13931 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13932 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
13933 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13934 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13935 t_cf->get_is_optional()) return true;
13936 t_type = t_cf->get_type();
13937 } else return true;
13938 }
13939 }
13940 return false;
13941 }
13942
13943 void Value::dump(unsigned level) const
13944 {
13945 switch (valuetype) {
13946 case V_ERROR:
13947 case V_NULL:
13948 case V_BOOL:
13949 case V_INT:
13950 case V_NAMEDINT:
13951 case V_NAMEDBITS:
13952 case V_REAL:
13953 case V_ENUM:
13954 case V_BSTR:
13955 case V_HSTR:
13956 case V_OSTR:
13957 case V_CSTR:
13958 case V_ISO2022STR:
13959 case V_OID:
13960 case V_ROID:
13961 case V_CHOICE:
13962 case V_SEQOF:
13963 case V_SETOF:
13964 case V_ARRAY:
13965 case V_SEQ:
13966 case V_SET:
13967 case V_OMIT:
13968 case V_VERDICT:
13969 case V_DEFAULT_NULL:
13970 case V_FAT_NULL:
13971 case V_EXPR:
13972 case V_MACRO:
13973 case V_NOTUSED:
13974 case V_FUNCTION:
13975 case V_ALTSTEP:
13976 case V_TESTCASE:
13977 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
13978 break;
13979 case V_REFD:
13980 case V_REFER:
13981 DEBUG(level, "Value: reference");
13982 u.ref.ref->dump(level + 1);
13983 break;
13984 case V_UNDEF_LOWERID:
13985 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
13986 break;
13987 case V_UNDEF_BLOCK:
13988 DEBUG(level, "Value: {block}");
13989 break;
13990 case V_TTCN3_NULL:
13991 DEBUG(level, "Value: null");
13992 break;
13993 case V_INVOKE:
13994 DEBUG(level, "Value: invoke");
13995 u.invoke.v->dump(level + 1);
13996 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
13997 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
13998 break;
13999 default:
14000 DEBUG(level, "Value: unknown type: %d", valuetype);
14001 } // switch
14002 }
14003
14004 void Value::add_string_element(size_t index, Value *v_element,
14005 map<size_t, Value>*& string_elements)
14006 {
14007 v_element->set_my_scope(get_my_scope());
14008 v_element->set_my_governor(get_my_governor());
14009 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
14010 v_element->set_location(*this);
14011 if (!string_elements) string_elements = new map<size_t, Value>;
14012 string_elements->add(index, v_element);
14013 }
14014
14015 ///////////////////////////////////////////////////////////////////////////////
14016 // class LazyParamData
14017
14018 int LazyParamData::depth = 0;
14019 bool LazyParamData::used_as_lvalue = false;
14020 vector<string>* LazyParamData::type_vec = NULL;
14021 vector<string>* LazyParamData::refd_vec = NULL;
14022
14023 void LazyParamData::init(bool p_used_as_lvalue) {
14024 if (depth<0) FATAL_ERROR("LazyParamData::init()");
14025 if (depth==0) {
14026 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
14027 used_as_lvalue = p_used_as_lvalue;
14028 type_vec = new vector<string>;
14029 refd_vec = new vector<string>;
14030 }
14031 depth++;
14032 }
14033
14034 void LazyParamData::clean() {
14035 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
14036 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
14037 if (depth==1) {
14038 // type_vec
14039 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
14040 type_vec->clear();
14041 delete type_vec;
14042 type_vec = NULL;
14043 // refd_vec
14044 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
14045 refd_vec->clear();
14046 delete refd_vec;
14047 refd_vec = NULL;
14048 }
14049 depth--;
14050 }
14051
14052 bool LazyParamData::in_lazy() {
14053 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
14054 return depth>0;
14055 }
14056
14057 // returns a temporary id instead of the C++ reference to a definition
14058 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
14059 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
14060 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
14061 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
14062 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
14063 // store the type of the assignment
14064 string* type_str = new string;
14065 switch (ass->get_asstype()) {
14066 case Assignment::A_MODULEPAR_TEMP:
14067 case Assignment::A_TEMPLATE:
14068 case Assignment::A_VAR_TEMPLATE:
14069 case Assignment::A_PAR_TEMPL_IN:
14070 case Assignment::A_PAR_TEMPL_OUT:
14071 case Assignment::A_PAR_TEMPL_INOUT:
14072 *type_str = ass->get_Type()->get_genname_template(scope);
14073 break;
14074 default:
14075 *type_str = ass->get_Type()->get_genname_value(scope);
14076 }
14077 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
14078 bool refd_ass_is_lazy_fpar = false;
14079 switch (ass->get_asstype()) {
14080 case Assignment::A_PAR_VAL:
14081 case Assignment::A_PAR_VAL_IN:
14082 case Assignment::A_PAR_TEMPL_IN:
14083 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
14084 if (refd_ass_is_lazy_fpar) {
14085 *type_str = string("Lazy_Param<") + *type_str + string(">");
14086 }
14087 break;
14088 default:
14089 break;
14090 }
14091 // add the "const" part if the referenced assignment is a constant thing
14092 if (!refd_ass_is_lazy_fpar) {
14093 switch (ass->get_asstype()) {
14094 case Assignment::A_CONST:
14095 case Assignment::A_OC:
14096 case Assignment::A_OBJECT:
14097 case Assignment::A_OS:
14098 case Assignment::A_VS:
14099 case Assignment::A_EXT_CONST:
14100 case Assignment::A_MODULEPAR:
14101 case Assignment::A_MODULEPAR_TEMP:
14102 case Assignment::A_TEMPLATE:
14103 case Assignment::A_PAR_VAL:
14104 case Assignment::A_PAR_VAL_IN:
14105 case Assignment::A_PAR_TEMPL_IN:
14106 *type_str = string("const ") + *type_str;
14107 break;
14108 default:
14109 // nothing to do
14110 break;
14111 }
14112 }
14113 //
14114 type_vec->add(type_str);
14115 // store the C++ reference string
14116 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
14117 if (refd_ass_is_lazy_fpar) {
14118 Type* refd_ass_type = ass->get_Type();
14119 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);
14120 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
14121 } else {
14122 return get_member_name(refd_vec->size()-1);
14123 }
14124 }
14125
14126 string LazyParamData::get_member_name(size_t idx) {
14127 return string("lpm_") + Int2string(idx);
14128 }
14129
14130 string LazyParamData::get_constr_param_name(size_t idx) {
14131 return string("lpp_") + Int2string(idx);
14132 }
14133
14134 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
14135 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14136 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
14137 const string& tmp_id = val->get_temporary_id();
14138 const char *tmp_id_str = tmp_id.c_str();
14139 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14140 val->get_my_governor()->get_genname_value(my_scope).c_str(),
14141 tmp_id_str);
14142 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14143 tmp_id_str, val);
14144 expr->expr = mputstr(expr->expr, tmp_id_str);
14145 } else {
14146 val->generate_code_expr(expr);
14147 }
14148 }
14149
14150 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
14151 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14152 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
14153 const string& tmp_id = temp->get_Template()->get_temporary_id();
14154 const char *tmp_id_str = tmp_id.c_str();
14155 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14156 temp->get_Template()->get_my_governor()
14157 ->get_genname_template(my_scope).c_str(), tmp_id_str);
14158 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14159 tmp_id_str, temp->get_Template());
14160 // Not incorporated into gen_conv_code() yet.
14161 if (gen_restriction_check != TR_NONE)
14162 expr->preamble = Template::generate_restriction_check_code(
14163 expr->preamble, tmp_id_str, gen_restriction_check);
14164 expr->expr = mputstr(expr->expr, tmp_id_str);
14165 } else temp->generate_code(expr, gen_restriction_check);
14166 }
14167
14168 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
14169 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14170 if (depth>1) {
14171 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14172 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14173 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14174 expression_struct value_expr;
14175 Code::init_expr(&value_expr);
14176 generate_code_for_value(&value_expr, value, scope);
14177 // the id of the instance of Lazy_Param which will be used as the actual parameter
14178 const string& lazy_param_id = value->get_temporary_id();
14179 if (value_expr.preamble) {
14180 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
14181 }
14182 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14183 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14184 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
14185 Code::free_expr(&value_expr);
14186 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14187 return;
14188 }
14189 // only if the formal parameter is *not* used as lvalue
14190 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
14191 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
14192 if (refd_ass) {
14193 bool refd_ass_is_lazy_fpar = false;
14194 switch (refd_ass->get_asstype()) {
14195 case Assignment::A_PAR_VAL:
14196 case Assignment::A_PAR_VAL_IN:
14197 case Assignment::A_PAR_TEMPL_IN:
14198 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14199 break;
14200 default:
14201 break;
14202 }
14203 if (refd_ass_is_lazy_fpar) {
14204 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14205 return;
14206 }
14207 }
14208 }
14209 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14210 expression_struct value_expr;
14211 Code::init_expr(&value_expr);
14212 generate_code_for_value(&value_expr, value, scope);
14213 // the id of the instance of Lazy_Param which will be used as the actual parameter
14214 string lazy_param_id = value->get_temporary_id();
14215 string type_name = value->get_my_governor()->get_genname_value(scope);
14216 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
14217 }
14218
14219 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
14220 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14221 if (depth>1) {
14222 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14223 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14224 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14225 expression_struct tmpl_expr;
14226 Code::init_expr(&tmpl_expr);
14227 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14228 // the id of the instance of Lazy_Param which will be used as the actual parameter
14229 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
14230 if (tmpl_expr.preamble) {
14231 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
14232 }
14233 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14234 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14235 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
14236 Code::free_expr(&tmpl_expr);
14237 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14238 return;
14239 }
14240 // only if the formal parameter is *not* used as lvalue
14241 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
14242 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
14243 if (refd_ass) {
14244 bool refd_ass_is_lazy_fpar = false;
14245 switch (refd_ass->get_asstype()) {
14246 case Assignment::A_PAR_VAL:
14247 case Assignment::A_PAR_VAL_IN:
14248 case Assignment::A_PAR_TEMPL_IN:
14249 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14250 break;
14251 default:
14252 break;
14253 }
14254 if (refd_ass_is_lazy_fpar) {
14255 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14256 return;
14257 }
14258 }
14259 }
14260 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14261 expression_struct tmpl_expr;
14262 Code::init_expr(&tmpl_expr);
14263 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14264 // the id of the instance of Lazy_Param which will be used as the actual parameter
14265 string lazy_param_id = temp->get_Template()->get_temporary_id();
14266 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
14267 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
14268 }
14269
14270 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
14271 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
14272 if (type_vec->size()>0) {
14273 // private members of the local class will be const references to the objects referenced by the expression
14274 for (size_t i=0; i<type_vec->size(); i++) {
14275 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
14276 }
14277 expr->preamble = mputstr(expr->preamble, "public:\n");
14278 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
14279 for (size_t i=0; i<type_vec->size(); i++) {
14280 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14281 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
14282 }
14283 expr->preamble = mputstr(expr->preamble, "): ");
14284 for (size_t i=0; i<type_vec->size(); i++) {
14285 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14286 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
14287 }
14288 expr->preamble = mputstr(expr->preamble, " {}\n");
14289 expr->preamble = mputstr(expr->preamble, "private:\n");
14290 }
14291 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
14292 // use the temporary expr structure to fill the body of the eval_expr() function
14293 if (param_expr.preamble) {
14294 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
14295 }
14296 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
14297 if (param_expr.postamble) {
14298 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
14299 }
14300 Code::free_expr(&param_expr);
14301 expr->preamble = mputstr(expr->preamble, "}\n"
14302 "};\n" // end of local class definition
14303 );
14304 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
14305 if (type_vec->size()>0) {
14306 expr->preamble = mputc(expr->preamble, '(');
14307 // paramteres of the constructor are references to the objects used in the expression
14308 for (size_t i=0; i<refd_vec->size(); i++) {
14309 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14310 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
14311 }
14312 expr->preamble = mputc(expr->preamble, ')');
14313 }
14314 expr->preamble = mputstr(expr->preamble, ";\n");
14315 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14316 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
14317 }
14318
14319 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
14320 expression_struct ref_expr;
14321 Code::init_expr(&ref_expr);
14322 ref->generate_code(&ref_expr);
14323 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
14324 if (ref_expr.preamble) {
14325 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
14326 }
14327 Assignment* ass = ref->get_refd_assignment();
14328 // determine C++ type of the assignment
14329 string type_str;
14330 switch (ass->get_asstype()) {
14331 case Assignment::A_MODULEPAR_TEMP:
14332 case Assignment::A_TEMPLATE:
14333 case Assignment::A_VAR_TEMPLATE:
14334 case Assignment::A_PAR_TEMPL_IN:
14335 case Assignment::A_PAR_TEMPL_OUT:
14336 case Assignment::A_PAR_TEMPL_INOUT:
14337 type_str = ass->get_Type()->get_genname_template(scope);
14338 break;
14339 default:
14340 type_str = ass->get_Type()->get_genname_value(scope);
14341 }
14342 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14343 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
14344 if (ref_expr.postamble) {
14345 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
14346 }
14347 Code::free_expr(&ref_expr);
14348 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14349 }
14350
14351 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
14352 const string& lazy_param_id = value->get_temporary_id();
14353 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14354 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14355 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
14356 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14357 }
14358
14359 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
14360 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
14361 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14362 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14363 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
14364 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14365 }
14366
14367 } // namespace Common
This page took 0.553891 seconds and 6 git commands to generate.