added hostid function (artf724006)
[deliverable/titan.core.git] / compiler2 / Value.cc
CommitLineData
d44e3c4f 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
1d0599f0 24 * Szabo, Bence Janos
d44e3c4f 25 * Szabo, Janos Zoltan – initial implementation
26 * Szalai, Gabor
27 * Tatarka, Gabor
28 * Zalanyi, Balazs Andor
29 *
30 ******************************************************************************/
970ed795
EL
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"
3abe9331 56#include "../common/JSON_Tokenizer.hh"
3f84031e 57#include "ttcn3/Ttcn2Json.hh"
970ed795
EL
58
59#include <math.h>
60#include <regex.h>
61#include <limits.h>
62
63namespace 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:
a38c6d4c 171 case OPTYPE_PROF_RUNNING:
970ed795
EL
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;
efbe586d 214 case OPTYPE_HOSTID: // [v1]
215 u.expr.v1=p.u.expr.v1?p.u.expr.v1->clone():0;
216 break;
970ed795
EL
217 case OPTYPE_ADD: // v1 v2
218 case OPTYPE_SUBTRACT:
219 case OPTYPE_MULTIPLY:
220 case OPTYPE_DIVIDE:
221 case OPTYPE_MOD:
222 case OPTYPE_REM:
223 case OPTYPE_CONCAT:
224 case OPTYPE_EQ:
225 case OPTYPE_LT:
226 case OPTYPE_GT:
227 case OPTYPE_NE:
228 case OPTYPE_GE:
229 case OPTYPE_LE:
230 case OPTYPE_AND:
231 case OPTYPE_OR:
232 case OPTYPE_XOR:
233 case OPTYPE_AND4B:
234 case OPTYPE_OR4B:
235 case OPTYPE_XOR4B:
236 case OPTYPE_SHL:
237 case OPTYPE_SHR:
238 case OPTYPE_ROTL:
239 case OPTYPE_ROTR:
240 case OPTYPE_INT2BIT:
241 case OPTYPE_INT2HEX:
242 case OPTYPE_INT2OCT:
243 u.expr.v1=p.u.expr.v1->clone();
244 u.expr.v2=p.u.expr.v2->clone();
245 break;
246 case OPTYPE_UNICHAR2OCT: // v1 [v2]
247 case OPTYPE_OCT2UNICHAR:
248 case OPTYPE_ENCODE_BASE64:
249 u.expr.v1=p.u.expr.v1->clone();
250 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
251 break;
252 case OPTYPE_DECODE:
253 u.expr.r1=p.u.expr.r1->clone();
254 u.expr.r2=p.u.expr.r2->clone();
255 break;
256 case OPTYPE_SUBSTR:
257 u.expr.ti1=p.u.expr.ti1->clone();
258 u.expr.v2=p.u.expr.v2->clone();
259 u.expr.v3=p.u.expr.v3->clone();
260 break;
261 case OPTYPE_REGEXP:
262 u.expr.ti1=p.u.expr.ti1->clone();
263 u.expr.t2=p.u.expr.t2->clone();
264 u.expr.v3=p.u.expr.v3->clone();
265 break;
266 case OPTYPE_DECOMP: // v1 v2 v3
267 u.expr.v1=p.u.expr.v1->clone();
268 u.expr.v2=p.u.expr.v2->clone();
269 u.expr.v3=p.u.expr.v3->clone();
270 break;
271 case OPTYPE_REPLACE:
272 u.expr.ti1 = p.u.expr.ti1->clone();
273 u.expr.v2 = p.u.expr.v2->clone();
274 u.expr.v3 = p.u.expr.v3->clone();
275 u.expr.ti4 = p.u.expr.ti4->clone();
276 break;
277 case OPTYPE_LENGTHOF: // ti1
278 case OPTYPE_SIZEOF: // ti1
279 case OPTYPE_VALUEOF: // ti1
280 case OPTYPE_ENCODE:
281 case OPTYPE_ISPRESENT:
282 case OPTYPE_TTCN2STRING:
283 u.expr.ti1=p.u.expr.ti1->clone();
284 break;
1d0599f0 285 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
286 u.expr.ti1=p.u.expr.ti1->clone();
287 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
288 break;
289 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
290 u.expr.r1 = p.u.expr.r1->clone();
291 u.expr.r2 = p.u.expr.r2->clone();
292 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
293 break;
970ed795
EL
294 case OPTYPE_UNDEF_RUNNING:
295 case OPTYPE_TMR_READ:
296 case OPTYPE_TMR_RUNNING:
297 case OPTYPE_ACTIVATE:
298 u.expr.r1=p.u.expr.r1->clone();
299 break;
300 case OPTYPE_EXECUTE: // r1 [v2]
301 u.expr.r1=p.u.expr.r1->clone();
302 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
303 break;
0a1610f4 304 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
305 case OPTYPE_CHECKSTATE_ALL:
306 u.expr.r1=p.u.expr.r1?p.u.expr.r1->clone():0;
307 u.expr.v2=p.u.expr.v2->clone();
308 break;
970ed795
EL
309 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
310 u.expr.r1=p.u.expr.r1->clone();
311 u.expr.v2=p.u.expr.v2?p.u.expr.v2->clone():0;
312 u.expr.v3=p.u.expr.v3?p.u.expr.v3->clone():0;
313 u.expr.b4 = p.u.expr.b4;
314 break;
315 case OPTYPE_MATCH: // v1 t2
316 u.expr.v1=p.u.expr.v1->clone();
317 u.expr.t2=p.u.expr.t2->clone();
318 break;
319 case OPTYPE_ISCHOSEN: // r1 i2
320 u.expr.r1=p.u.expr.r1->clone();
321 u.expr.i2=p.u.expr.i2->clone();
322 break;
323 case OPTYPE_ISCHOSEN_V: // v1 i2
324 u.expr.v1=p.u.expr.v1->clone();
325 u.expr.i2=p.u.expr.i2->clone();
326 break;
327 case OPTYPE_ISCHOSEN_T: // t1 i2
328 u.expr.t1=p.u.expr.t1->clone();
329 u.expr.i2=p.u.expr.i2->clone();
330 break;
331 case OPTYPE_ACTIVATE_REFD:
332 u.expr.v1 = p.u.expr.v1->clone();
333 if(p.u.expr.state!=EXPR_CHECKED)
334 u.expr.t_list2 = p.u.expr.t_list2->clone();
335 else {
336 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
337 u.expr.state = EXPR_CHECKED;
338 }
339 break;
340 case OPTYPE_EXECUTE_REFD:
341 u.expr.v1 = p.u.expr.v1->clone();
342 if(p.u.expr.state!=EXPR_CHECKED)
343 u.expr.t_list2 = p.u.expr.t_list2->clone();
344 else {
345 u.expr.ap_list2 = p.u.expr.ap_list2->clone();
346 u.expr.state = EXPR_CHECKED;
347 }
348 u.expr.v3 = p.u.expr.v3 ? p.u.expr.v3->clone() : 0;
349 break;
350 case OPTYPE_LOG2STR:
a50716c1 351 case OPTYPE_ANY2UNISTR:
970ed795
EL
352 u.expr.logargs = p.u.expr.logargs->clone();
353 break;
354 default:
355 FATAL_ERROR("Value::Value()");
356 } // switch
357 break;
358 case V_MACRO:
359 u.macro = p.u.macro;
360 break;
361 case V_FUNCTION:
362 case V_ALTSTEP:
363 case V_TESTCASE:
364 u.refd_fat = p.u.refd_fat;
365 break;
366 case V_INVOKE:
367 u.invoke.v = p.u.invoke.v->clone();
368 u.invoke.t_list = p.u.invoke.t_list?p.u.invoke.t_list->clone():0;
369 u.invoke.ap_list = p.u.invoke.ap_list?p.u.invoke.ap_list->clone():0;
370 break;
371 case V_REFER:
372 u.refered = p.u.refered->clone();
373 break;
374 default:
375 FATAL_ERROR("Value::Value()");
376 } // switch
377 }
378
379 void Value::clean_up()
380 {
381 switch (valuetype) {
382 case V_ERROR:
383 case V_NULL:
384 case V_BOOL:
385 case V_REAL:
386 case V_OMIT:
387 case V_VERDICT:
388 case V_TTCN3_NULL:
389 case V_DEFAULT_NULL:
390 case V_FAT_NULL:
391 case V_MACRO:
392 case V_NOTUSED:
393 case V_FUNCTION:
394 case V_ALTSTEP:
395 case V_TESTCASE:
396 break;
397 case V_INT:
398 delete u.val_Int;
399 break;
400 case V_NAMEDINT:
401 case V_ENUM:
402 case V_UNDEF_LOWERID:
403 delete u.val_id;
404 break;
405 case V_BSTR:
406 case V_HSTR:
407 case V_OSTR:
408 case V_CSTR:
409 case V_ISO2022STR:
410 delete u.str.val_str;
411 clean_up_string_elements(u.str.str_elements);
412 break;
413 case V_USTR:
414 delete u.ustr.val_ustr;
415 clean_up_string_elements(u.ustr.ustr_elements);
416 break;
417 case V_CHARSYMS:
418 delete u.char_syms;
419 break;
420 case V_OID:
421 case V_ROID:
422 if (u.oid_comps) {
423 for(size_t i=0; i<u.oid_comps->size(); i++)
424 delete (*u.oid_comps)[i];
425 u.oid_comps->clear();
426 delete u.oid_comps;
427 }
428 break;
429 case V_EXPR:
430 clean_up_expr();
431 break;
432 case V_CHOICE:
433 delete u.choice.alt_name;
434 delete u.choice.alt_value;
435 break;
436 case V_SEQOF:
437 case V_SETOF:
438 case V_ARRAY:
439 delete u.val_vs;
440 break;
441 case V_SEQ:
442 case V_SET:
443 delete u.val_nvs;
444 break;
445 case V_REFD:
446 delete u.ref.ref;
447 break;
448 case V_REFER:
449 delete u.refered;
450 break;
451 case V_INVOKE:
452 delete u.invoke.v;
453 delete u.invoke.t_list;
454 delete u.invoke.ap_list;
455 break;
456 case V_NAMEDBITS:
457 if(u.ids) {
458 for(size_t i=0; i<u.ids->size(); i++) delete u.ids->get_nth_elem(i);
459 u.ids->clear();
460 delete u.ids;
461 }
462 break;
463 case V_UNDEF_BLOCK:
464 delete u.block;
465 break;
466 default:
467 FATAL_ERROR("Value::clean_up()");
468 } // switch
469 }
470
471 void Value::clean_up_expr()
472 {
473 switch (u.expr.state) {
474 case EXPR_CHECKING:
475 case EXPR_CHECKING_ERR:
476 FATAL_ERROR("Value::clean_up_expr()");
477 default:
478 break;
479 }
480 switch (u.expr.v_optype) {
481 case OPTYPE_RND: // -
482 case OPTYPE_COMP_NULL:
483 case OPTYPE_COMP_MTC:
484 case OPTYPE_COMP_SYSTEM:
485 case OPTYPE_COMP_SELF:
486 case OPTYPE_COMP_RUNNING_ANY:
487 case OPTYPE_COMP_RUNNING_ALL:
488 case OPTYPE_COMP_ALIVE_ANY:
489 case OPTYPE_COMP_ALIVE_ALL:
490 case OPTYPE_TMR_RUNNING_ANY:
491 case OPTYPE_GETVERDICT:
492 case OPTYPE_TESTCASENAME:
a38c6d4c 493 case OPTYPE_PROF_RUNNING:
970ed795
EL
494 break;
495 case OPTYPE_UNARYPLUS: // v1
496 case OPTYPE_UNARYMINUS:
497 case OPTYPE_NOT:
498 case OPTYPE_NOT4B:
499 case OPTYPE_BIT2HEX:
500 case OPTYPE_BIT2INT:
501 case OPTYPE_BIT2OCT:
502 case OPTYPE_BIT2STR:
503 case OPTYPE_CHAR2INT:
504 case OPTYPE_CHAR2OCT:
505 case OPTYPE_COMP_RUNNING:
506 case OPTYPE_COMP_ALIVE:
507 case OPTYPE_FLOAT2INT:
508 case OPTYPE_FLOAT2STR:
509 case OPTYPE_HEX2BIT:
510 case OPTYPE_HEX2INT:
511 case OPTYPE_HEX2OCT:
512 case OPTYPE_HEX2STR:
513 case OPTYPE_INT2CHAR:
514 case OPTYPE_INT2FLOAT:
515 case OPTYPE_INT2STR:
516 case OPTYPE_INT2UNICHAR:
517 case OPTYPE_OCT2BIT:
518 case OPTYPE_OCT2CHAR:
519 case OPTYPE_OCT2HEX:
520 case OPTYPE_OCT2INT:
521 case OPTYPE_OCT2STR:
522 case OPTYPE_STR2BIT:
523 case OPTYPE_STR2FLOAT:
524 case OPTYPE_STR2HEX:
525 case OPTYPE_STR2INT:
526 case OPTYPE_STR2OCT:
527 case OPTYPE_UNICHAR2INT:
528 case OPTYPE_UNICHAR2CHAR:
529 case OPTYPE_ENUM2INT:
530 case OPTYPE_RNDWITHVAL:
531 case OPTYPE_REMOVE_BOM:
532 case OPTYPE_GET_STRINGENCODING:
533 case OPTYPE_DECODE_BASE64:
efbe586d 534 case OPTYPE_HOSTID:
970ed795
EL
535 delete u.expr.v1;
536 break;
537 case OPTYPE_ADD: // v1 v2
538 case OPTYPE_SUBTRACT:
539 case OPTYPE_MULTIPLY:
540 case OPTYPE_DIVIDE:
541 case OPTYPE_MOD:
542 case OPTYPE_REM:
543 case OPTYPE_CONCAT:
544 case OPTYPE_EQ:
545 case OPTYPE_LT:
546 case OPTYPE_GT:
547 case OPTYPE_NE:
548 case OPTYPE_GE:
549 case OPTYPE_LE:
550 case OPTYPE_AND:
551 case OPTYPE_OR:
552 case OPTYPE_XOR:
553 case OPTYPE_AND4B:
554 case OPTYPE_OR4B:
555 case OPTYPE_XOR4B:
556 case OPTYPE_SHL:
557 case OPTYPE_SHR:
558 case OPTYPE_ROTL:
559 case OPTYPE_ROTR:
560 case OPTYPE_INT2BIT:
561 case OPTYPE_INT2HEX:
562 case OPTYPE_INT2OCT:
563 case OPTYPE_UNICHAR2OCT:
564 case OPTYPE_OCT2UNICHAR:
565 case OPTYPE_ENCODE_BASE64:
566 delete u.expr.v1;
567 delete u.expr.v2;
568 break;
569 case OPTYPE_DECODE:
570 delete u.expr.r1;
571 delete u.expr.r2;
572 break;
573 case OPTYPE_SUBSTR:
574 delete u.expr.ti1;
575 delete u.expr.v2;
576 delete u.expr.v3;
577 break;
578 case OPTYPE_REGEXP:
579 delete u.expr.ti1;
580 delete u.expr.t2;
581 delete u.expr.v3;
582 break;
583 case OPTYPE_DECOMP: // v1 v2 v3
584 delete u.expr.v1;
585 delete u.expr.v2;
586 delete u.expr.v3;
587 break;
588 case OPTYPE_REPLACE:
589 delete u.expr.ti1;
590 delete u.expr.v2;
591 delete u.expr.v3;
592 delete u.expr.ti4;
593 break;
594 case OPTYPE_LENGTHOF: // ti1
595 case OPTYPE_SIZEOF: // ti1
596 case OPTYPE_VALUEOF: // ti1
597 case OPTYPE_ISVALUE:
598 case OPTYPE_ISBOUND:
599 case OPTYPE_ENCODE:
600 case OPTYPE_ISPRESENT:
601 case OPTYPE_TTCN2STRING:
602 delete u.expr.ti1;
603 break;
1d0599f0 604 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
605 delete u.expr.ti1;
606 delete u.expr.v2;
607 break;
608 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
609 delete u.expr.r1;
610 delete u.expr.r2;
611 delete u.expr.v3;
612 break;
970ed795
EL
613 case OPTYPE_UNDEF_RUNNING:
614 case OPTYPE_TMR_READ:
615 case OPTYPE_TMR_RUNNING:
616 case OPTYPE_ACTIVATE:
617 delete u.expr.r1;
618 break;
619 case OPTYPE_EXECUTE: // r1 [v2]
620 delete u.expr.r1;
621 delete u.expr.v2;
622 break;
0a1610f4 623 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
624 case OPTYPE_CHECKSTATE_ALL:
625 delete u.expr.r1;
626 delete u.expr.v2;
627 break;
970ed795
EL
628 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
629 delete u.expr.r1;
630 delete u.expr.v2;
631 delete u.expr.v3;
632 break;
633 case OPTYPE_MATCH: // v1 t2
634 delete u.expr.v1;
635 delete u.expr.t2;
636 break;
637 case OPTYPE_ISCHOSEN: // r1 i2
638 delete u.expr.r1;
639 delete u.expr.i2;
640 break;
641 case OPTYPE_ISCHOSEN_V: // v1 i2
642 delete u.expr.v1;
643 delete u.expr.i2;
644 break;
645 case OPTYPE_ISCHOSEN_T: // t1 i2
646 delete u.expr.t1;
647 delete u.expr.i2;
648 break;
649 case OPTYPE_ACTIVATE_REFD: //v1 t_list2
650 delete u.expr.v1;
651 if(u.expr.state!=EXPR_CHECKED)
652 delete u.expr.t_list2;
653 else
654 delete u.expr.ap_list2;
655 break;
656 case OPTYPE_EXECUTE_REFD: //v1 t_list2 [v3]
657 delete u.expr.v1;
658 if(u.expr.state!=EXPR_CHECKED)
659 delete u.expr.t_list2;
660 else
661 delete u.expr.ap_list2;
662 delete u.expr.v3;
663 break;
664 case OPTYPE_LOG2STR:
a50716c1 665 case OPTYPE_ANY2UNISTR:
970ed795
EL
666 delete u.expr.logargs;
667 break;
668 default:
669 FATAL_ERROR("Value::clean_up_expr()");
670 } // switch
671 }
672
673 void Value::copy_and_destroy(Value *src)
674 {
675 clean_up();
676 valuetype = src->valuetype;
677 u = src->u;
678 // update the pointer used for caching if it points to the value itself
679 if (valuetype == V_REFD && u.ref.refd_last == src) u.ref.refd_last = this;
680 src->valuetype = V_ERROR;
681 delete src;
682 }
683
684 Value::Value(valuetype_t p_vt)
685 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
686 {
687 switch(valuetype) {
688 case V_NULL:
689 case V_TTCN3_NULL:
690 case V_OMIT:
691 case V_NOTUSED:
692 case V_ERROR:
693 break;
694 case V_OID:
695 case V_ROID:
696 u.oid_comps=new vector<OID_comp>();
697 break;
698 case V_NAMEDBITS:
699 u.ids=new map<string, Identifier>();
700 break;
701 default:
702 FATAL_ERROR("Value::Value()");
703 } // switch
704 }
705
706 Value::Value(valuetype_t p_vt, bool p_val_bool)
707 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
708 {
709 switch(valuetype) {
710 case V_BOOL:
711 u.val_bool=p_val_bool;
712 break;
713 default:
714 FATAL_ERROR("Value::Value()");
715 } // switch
716 }
717
718 Value::Value(valuetype_t p_vt, const Int& p_val_Int)
719 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
720 {
721 switch(valuetype) {
722 case V_INT:
723 u.val_Int=new int_val_t(p_val_Int);
724 break;
725 default:
726 FATAL_ERROR("Value::Value()");
727 } // switch
728 }
729
730 Value::Value(valuetype_t p_vt, int_val_t *p_val_Int)
731 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
732 {
733 switch(valuetype){
734 case V_INT:
735 u.val_Int=p_val_Int;
736 break;
737 default:
738 FATAL_ERROR("Value::Value()");
739 }
740 }
741
742 Value::Value(valuetype_t p_vt, string *p_val_str)
743 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
744 {
745 if(!p_val_str) FATAL_ERROR("NULL parameter");
746 switch(valuetype) {
747 case V_BSTR:
748 case V_HSTR:
749 case V_OSTR:
750 case V_CSTR:
751 case V_ISO2022STR:
752 set_val_str(p_val_str);
753 break;
754 default:
755 FATAL_ERROR("Value::Value()");
756 } // switch
757 }
758
759 Value::Value(valuetype_t p_vt, ustring *p_val_ustr)
760 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
761 {
762 if (p_vt != V_USTR || !p_val_ustr) FATAL_ERROR("Value::Value()");
763 set_val_ustr(p_val_ustr);
764 u.ustr.convert_str = false;
765 }
766
767 Value::Value(valuetype_t p_vt, CharSyms *p_char_syms)
768 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
769 {
770 if (!p_char_syms) FATAL_ERROR("NULL parameter");
771 switch (valuetype) {
772 case V_CHARSYMS:
773 u.char_syms = p_char_syms;
774 break;
775 default:
776 FATAL_ERROR("Value::Value()");
777 } // switch
778 }
779
780 Value::Value(valuetype_t p_vt, Identifier *p_val_id)
781 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
782 {
783 if(!p_val_id)
784 FATAL_ERROR("NULL parameter");
785 switch(valuetype) {
786 case V_NAMEDINT:
787 case V_ENUM:
788 case V_UNDEF_LOWERID:
789 u.val_id=p_val_id;
790 break;
791 default:
792 FATAL_ERROR("Value::Value()");
793 } // switch
794 }
795
796 Value::Value(valuetype_t p_vt, Identifier *p_id, Value *p_val)
797 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
798 {
799 if(!p_id || !p_val)
800 FATAL_ERROR("NULL parameter");
801 switch(valuetype) {
802 case V_CHOICE:
803 u.choice.alt_name=p_id;
804 u.choice.alt_value=p_val;
805 break;
806 default:
807 FATAL_ERROR("Value::Value()");
808 } // switch
809 }
810
811 Value::Value(valuetype_t p_vt, const Real& p_val_Real)
812 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
813 {
814 switch(valuetype) {
815 case V_REAL:
816 u.val_Real=p_val_Real;
817 break;
818 default:
819 FATAL_ERROR("Value::Value()");
820 } // switch
821 }
822
823 Value::Value(valuetype_t p_vt, Values *p_vs)
824 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
825 {
826 if(!p_vs) FATAL_ERROR("NULL parameter");
827 switch(valuetype) {
828 case V_SEQOF:
829 case V_SETOF:
830 case V_ARRAY:
831 u.val_vs=p_vs;
832 break;
833 default:
834 FATAL_ERROR("Value::Value()");
835 } // switch
836 }
837
838 Value::Value(valuetype_t p_vt, Value *p_v,
839 Ttcn::ParsedActualParameters *p_t_list)
840 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
841 {
842 if(!p_v || !p_t_list) FATAL_ERROR("NULL parameter");
843 switch(valuetype) {
844 case V_INVOKE:
845 u.invoke.v = p_v;
846 u.invoke.t_list = p_t_list;
847 u.invoke.ap_list = 0;
848 break;
849 default:
850 FATAL_ERROR("Value::Value()");
851 }
852 }
853
854 // -
855 Value::Value(operationtype_t p_optype)
856 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
857 {
858 u.expr.v_optype = p_optype;
859 u.expr.state = EXPR_NOT_CHECKED;
860 switch(p_optype) {
861 case OPTYPE_RND:
862 case OPTYPE_COMP_NULL:
863 case OPTYPE_COMP_MTC:
864 case OPTYPE_COMP_SYSTEM:
865 case OPTYPE_COMP_SELF:
866 case OPTYPE_COMP_RUNNING_ANY:
867 case OPTYPE_COMP_RUNNING_ALL:
868 case OPTYPE_COMP_ALIVE_ANY:
869 case OPTYPE_COMP_ALIVE_ALL:
870 case OPTYPE_TMR_RUNNING_ANY:
871 case OPTYPE_GETVERDICT:
872 case OPTYPE_TESTCASENAME:
a38c6d4c 873 case OPTYPE_PROF_RUNNING:
970ed795
EL
874 break;
875 default:
876 FATAL_ERROR("Value::Value()");
877 } // switch
878 }
879
880 // v1
881 Value::Value(operationtype_t p_optype, Value *p_v1)
882 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
883 {
884 u.expr.v_optype = p_optype;
885 u.expr.state = EXPR_NOT_CHECKED;
886 switch(p_optype) {
887 case OPTYPE_UNARYPLUS:
888 case OPTYPE_UNARYMINUS:
889 case OPTYPE_NOT:
890 case OPTYPE_NOT4B:
891 case OPTYPE_BIT2HEX:
892 case OPTYPE_BIT2INT:
893 case OPTYPE_BIT2OCT:
894 case OPTYPE_BIT2STR:
895 case OPTYPE_CHAR2INT:
896 case OPTYPE_CHAR2OCT:
897 case OPTYPE_COMP_RUNNING:
898 case OPTYPE_COMP_ALIVE:
899 case OPTYPE_FLOAT2INT:
900 case OPTYPE_FLOAT2STR:
901 case OPTYPE_HEX2BIT:
902 case OPTYPE_HEX2INT:
903 case OPTYPE_HEX2OCT:
904 case OPTYPE_HEX2STR:
905 case OPTYPE_INT2CHAR:
906 case OPTYPE_INT2FLOAT:
907 case OPTYPE_INT2STR:
908 case OPTYPE_INT2UNICHAR:
909 case OPTYPE_OCT2BIT:
910 case OPTYPE_OCT2CHAR:
911 case OPTYPE_OCT2HEX:
912 case OPTYPE_OCT2INT:
913 case OPTYPE_OCT2STR:
914 case OPTYPE_STR2BIT:
915 case OPTYPE_STR2FLOAT:
916 case OPTYPE_STR2HEX:
917 case OPTYPE_STR2INT:
918 case OPTYPE_STR2OCT:
919 case OPTYPE_UNICHAR2INT:
920 case OPTYPE_UNICHAR2CHAR:
921 case OPTYPE_ENUM2INT:
922 case OPTYPE_RNDWITHVAL:
923 case OPTYPE_REMOVE_BOM:
924 case OPTYPE_GET_STRINGENCODING:
925 case OPTYPE_DECODE_BASE64:
926 if(!p_v1) FATAL_ERROR("Value::Value()");
927 u.expr.v1=p_v1;
928 break;
efbe586d 929 case OPTYPE_HOSTID:
930 u.expr.v1=p_v1;
931 break;
970ed795
EL
932 default:
933 FATAL_ERROR("Value::Value()");
934 } // switch
935 }
936
937 // ti1
938 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1)
939 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
940 {
941 u.expr.v_optype = p_optype;
942 u.expr.state = EXPR_NOT_CHECKED;
943 switch(p_optype) {
944 case OPTYPE_LENGTHOF:
945 case OPTYPE_SIZEOF:
946 case OPTYPE_VALUEOF:
947 case OPTYPE_ISVALUE:
948 case OPTYPE_ISBOUND:
949 case OPTYPE_ENCODE:
1d0599f0 950 case OPTYPE_ENCVALUE_UNICHAR:
970ed795
EL
951 case OPTYPE_ISPRESENT:
952 case OPTYPE_TTCN2STRING:
953 if(!p_ti1) FATAL_ERROR("Value::Value()");
954 u.expr.ti1=p_ti1;
955 break;
956 default:
957 FATAL_ERROR("Value::Value()");
958 } // switch
959 }
960
961 // r1
962 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1)
963 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
964 {
965 u.expr.v_optype = p_optype;
966 u.expr.state = EXPR_NOT_CHECKED;
967 switch(p_optype) {
968 case OPTYPE_UNDEF_RUNNING:
969 case OPTYPE_TMR_READ:
970 case OPTYPE_TMR_RUNNING:
971 case OPTYPE_ACTIVATE:
972 if(!p_r1) FATAL_ERROR("Value::Value()");
973 u.expr.r1=p_r1;
974 break;
975 default:
976 FATAL_ERROR("Value::Value()");
977 } // switch
978 }
979
980 // v1 t_list2
981 Value::Value(operationtype_t p_optype, Value *p_v1,
982 Ttcn::ParsedActualParameters *p_ap_list)
983 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
984 {
985 u.expr.v_optype = p_optype;
986 u.expr.state = EXPR_NOT_CHECKED;
987 switch(p_optype) {
988 case OPTYPE_ACTIVATE_REFD:
989 if(!p_v1 || !p_ap_list) FATAL_ERROR("Value::Value()");
990 u.expr.v1 = p_v1;
991 u.expr.t_list2 = p_ap_list;
992 break;
993 default:
994 FATAL_ERROR("Value::Value()");
995 }
996 }
997
998 //v1 t_list2 v3
999 Value::Value(operationtype_t p_optype, Value *p_v1,
1000 Ttcn::ParsedActualParameters *p_t_list2, Value *p_v3)
1001 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1002 {
1003 u.expr.v_optype = p_optype;
1004 u.expr.state = EXPR_NOT_CHECKED;
1005 switch(p_optype) {
1006 case OPTYPE_EXECUTE_REFD:
1007 if(!p_v1 || !p_t_list2) FATAL_ERROR("Value::Value()");
1008 u.expr.v1 = p_v1;
1009 u.expr.t_list2 = p_t_list2;
1010 u.expr.v3 = p_v3;
1011 break;
1012 default:
1013 FATAL_ERROR("Value::Value()");
1014 }
1015 }
1016
0a1610f4 1017 // r1 [v2] or [r1] v2
970ed795
EL
1018 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Value *p_v2)
1019 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1020 {
1021 u.expr.v_optype = p_optype;
1022 u.expr.state = EXPR_NOT_CHECKED;
1023 switch(p_optype) {
1024 case OPTYPE_EXECUTE:
1025 if(!p_r1) FATAL_ERROR("Value::Value()");
1026 u.expr.r1=p_r1;
1027 u.expr.v2=p_v2;
1028 break;
0a1610f4 1029 case OPTYPE_CHECKSTATE_ANY:
1030 case OPTYPE_CHECKSTATE_ALL:
1031 if(!p_v2) FATAL_ERROR("Value::Value()");
1032 u.expr.r1=p_r1; // may be null if any port or all port
1033 u.expr.v2=p_v2;
1034 break;
970ed795
EL
1035 default:
1036 FATAL_ERROR("Value::Value()");
1037 } // switch
1038 }
1039
1040 // r1 [v2] [v3] b4
1041 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1,
1042 Value *p_v2, Value *p_v3, bool p_b4)
1043 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1044 {
1045 u.expr.v_optype = p_optype;
1046 u.expr.state = EXPR_NOT_CHECKED;
1047 switch(p_optype) {
1048 case OPTYPE_COMP_CREATE:
1049 if(!p_r1) FATAL_ERROR("Value::Value()");
1050 u.expr.r1=p_r1;
1051 u.expr.v2=p_v2;
1052 u.expr.v3=p_v3;
1053 u.expr.b4=p_b4;
1054 break;
1055 default:
1056 FATAL_ERROR("Value::Value()");
1057 } // switch
1058 }
1059
1060 // v1 v2
1061 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2)
1062 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1063 {
1064 u.expr.v_optype = p_optype;
1065 u.expr.state = EXPR_NOT_CHECKED;
1066 switch(p_optype) {
1067 case OPTYPE_ADD:
1068 case OPTYPE_SUBTRACT:
1069 case OPTYPE_MULTIPLY:
1070 case OPTYPE_DIVIDE:
1071 case OPTYPE_MOD:
1072 case OPTYPE_REM:
1073 case OPTYPE_CONCAT:
1074 case OPTYPE_EQ:
1075 case OPTYPE_LT:
1076 case OPTYPE_GT:
1077 case OPTYPE_NE:
1078 case OPTYPE_GE:
1079 case OPTYPE_LE:
1080 case OPTYPE_AND:
1081 case OPTYPE_OR:
1082 case OPTYPE_XOR:
1083 case OPTYPE_AND4B:
1084 case OPTYPE_OR4B:
1085 case OPTYPE_XOR4B:
1086 case OPTYPE_SHL:
1087 case OPTYPE_SHR:
1088 case OPTYPE_ROTL:
1089 case OPTYPE_ROTR:
1090 case OPTYPE_INT2BIT:
1091 case OPTYPE_INT2HEX:
1092 case OPTYPE_INT2OCT:
1093 if(!p_v1 || !p_v2) FATAL_ERROR("Value::Value()");
1094 u.expr.v1=p_v1;
1095 u.expr.v2=p_v2;
1096 break;
1097 case OPTYPE_UNICHAR2OCT:
1098 case OPTYPE_OCT2UNICHAR:
1099 case OPTYPE_ENCODE_BASE64:
1100 if(!p_v1) FATAL_ERROR("Value::Value()");
1101 u.expr.v1=p_v1;
1102 // p_v2 may be NULL if there is no second param
1103 u.expr.v2=p_v2;
1104 break;
1105 default:
1106 FATAL_ERROR("Value::Value()");
1107 } // switch
1108 }
1109
1110 // ti1 v2 v3 ti4
1111 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2,
1112 Value *p_v3, TemplateInstance *p_ti4) :
1113 GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1114 {
1115 u.expr.v_optype = p_optype;
1116 u.expr.state = EXPR_NOT_CHECKED;
1117 switch (p_optype) {
1118 case OPTYPE_REPLACE:
1119 if (!p_ti1 || !p_v2 || !p_v3 || !p_ti4) FATAL_ERROR("Value::Value()");
1120 u.expr.ti1 = p_ti1;
1121 u.expr.v2 = p_v2;
1122 u.expr.v3 = p_v3;
1123 u.expr.ti4 = p_ti4;
1124 break;
1125 default:
1126 FATAL_ERROR("Value::Value()");
1127 } // switch
1128 }
1129
1130 // v1 v2 v3
1131 Value::Value(operationtype_t p_optype, Value *p_v1, Value *p_v2, Value *p_v3)
1132 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1133 {
1134 u.expr.v_optype = p_optype;
1135 u.expr.state = EXPR_NOT_CHECKED;
1136 switch(p_optype) {
1137 case OPTYPE_DECOMP:
1138 if(!p_v1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1139 u.expr.v1=p_v1;
1140 u.expr.v2=p_v2;
1141 u.expr.v3=p_v3;
1d0599f0 1142 break;
970ed795
EL
1143 default:
1144 FATAL_ERROR("Value::Value()");
1145 } // switch
1146 }
1147
1d0599f0 1148 // ti1 [v2]
1149 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2)
1150 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1151 {
1152 u.expr.v_optype = p_optype;
1153 u.expr.state = EXPR_NOT_CHECKED;
1154 switch(p_optype) {
1155 case OPTYPE_ENCVALUE_UNICHAR:
1156 if(!p_ti1 || !p_v2) FATAL_ERROR("Value::Value()");
1157 u.expr.ti1=p_ti1;
1158 u.expr.v2=p_v2;
1159 break;
1160 default:
1161 FATAL_ERROR("Value::Value()");
1162 } // switch
1163 }
1164
970ed795
EL
1165 // ti1 v2 v3
1166 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, Value *p_v2, Value *p_v3)
1167 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1168 {
1169 u.expr.v_optype=p_optype;
1170 u.expr.state=EXPR_NOT_CHECKED;
1171 switch(p_optype) {
1172 case OPTYPE_SUBSTR:
1173 if(!p_ti1 || !p_v2 || !p_v3) FATAL_ERROR("Value::Value()");
1174 u.expr.ti1 = p_ti1;
1175 u.expr.v2=p_v2;
1176 u.expr.v3=p_v3;
1177 break;
1178 default:
1179 FATAL_ERROR("Value::Value()");
1180 } // switch
1181 }
1182
1183 // ti1 t2 v3
1184 Value::Value(operationtype_t p_optype, TemplateInstance *p_ti1, TemplateInstance *p_t2, Value *p_v3)
1185 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1186 {
1187 u.expr.v_optype=p_optype;
1188 u.expr.state=EXPR_NOT_CHECKED;
1189 switch(p_optype) {
1190 case OPTYPE_REGEXP:
1191 if(!p_ti1 || !p_t2 || !p_v3) FATAL_ERROR("Value::Value()");
1192 u.expr.ti1 = p_ti1;
1193 u.expr.t2 = p_t2;
1194 u.expr.v3=p_v3;
1195 break;
1196 default:
1197 FATAL_ERROR("Value::Value()");
1198 } // switch
1199 }
1200
1201 // v1 t2
1202 Value::Value(operationtype_t p_optype, Value *p_v1, TemplateInstance *p_t2)
1203 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1204 {
1205 u.expr.v_optype = p_optype;
1206 u.expr.state = EXPR_NOT_CHECKED;
1207 switch(p_optype) {
1208 case OPTYPE_MATCH:
1209 if(!p_v1 || !p_t2) FATAL_ERROR("Value::Value()");
1210 u.expr.v1=p_v1;
1211 u.expr.t2=p_t2;
1212 break;
1213 default:
1214 FATAL_ERROR("Value::Value()");
1215 } // switch
1216 }
1217
1218 // r1 i2
1219 Value::Value(operationtype_t p_optype, Ttcn::Reference *p_r1,
1220 Identifier *p_i2)
1221 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1222 {
1223 u.expr.v_optype = p_optype;
1224 u.expr.state = EXPR_NOT_CHECKED;
1225 switch(p_optype) {
1226 case OPTYPE_ISCHOSEN:
1227 if(!p_r1 || !p_i2) FATAL_ERROR("Value::Value()");
1228 u.expr.r1=p_r1;
1229 u.expr.i2=p_i2;
1230 break;
1231 default:
1232 FATAL_ERROR("Value::Value()");
1233 } // switch
1234 }
1235
1236 Value::Value(operationtype_t p_optype, LogArguments *p_logargs)
1237 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1238 {
1239 u.expr.v_optype = p_optype;
1240 u.expr.state = EXPR_NOT_CHECKED;
1241 switch(p_optype) {
1242 case OPTYPE_LOG2STR:
a50716c1 1243 case OPTYPE_ANY2UNISTR:
970ed795
EL
1244 if (!p_logargs) FATAL_ERROR("Value::Value()");
1245 u.expr.logargs = p_logargs;
1246 break;
1247 default:
1248 FATAL_ERROR("Value::Value()");
1249 } // switch
1250 }
1251
1252 Value::Value(valuetype_t p_vt, macrotype_t p_macrotype)
1253 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1254 {
1255 if (p_vt != V_MACRO) FATAL_ERROR("Value::Value()");
1256 switch (p_macrotype) {
1257 case MACRO_MODULEID:
1258 case MACRO_FILENAME:
1259 case MACRO_BFILENAME:
1260 case MACRO_FILEPATH:
1261 case MACRO_LINENUMBER:
1262 case MACRO_LINENUMBER_C:
1263 case MACRO_DEFINITIONID:
1264 case MACRO_SCOPE:
1265 case MACRO_TESTCASEID:
1266 break;
1267 default:
1268 FATAL_ERROR("Value::Value()");
1269 }
1270 u.macro = p_macrotype;
1271 }
1272
1273 Value::Value(valuetype_t p_vt, NamedValues *p_nvs)
1274 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1275 {
1276 if(!p_nvs) FATAL_ERROR("NULL parameter");
1277 switch(valuetype) {
1278 case V_SEQ:
1279 case V_SET:
1280 u.val_nvs=p_nvs;
1281 break;
1282 default:
1283 FATAL_ERROR("Value::Value()");
1284 } // switch
1285 }
1286
1287 Value::Value(valuetype_t p_vt, Reference *p_ref)
1288 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1289 {
1290 if (!p_ref) FATAL_ERROR("NULL parameter: Value::Value()");
1291 switch(p_vt) {
1292 case V_REFD:
1293 u.ref.ref = p_ref;
1294 u.ref.refd_last = 0;
1295 break;
1296 case V_REFER:
1297 u.refered = p_ref;
1298 break;
1299 default:
1300 FATAL_ERROR("Value::Value()");
1301 }
1302 }
1303
1304 Value::Value(valuetype_t p_vt, Block *p_block)
1305 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1306 {
1307 if(!p_block) FATAL_ERROR("NULL parameter");
1308 switch(valuetype) {
1309 case V_UNDEF_BLOCK:
1310 u.block=p_block;
1311 break;
1312 default:
1313 FATAL_ERROR("Value::Value()");
1314 } // switch
1315 }
1316
1317 Value::Value(valuetype_t p_vt, verdict_t p_verdict)
1318 : GovernedSimple(S_V), valuetype(p_vt), my_governor(0)
1319 {
1320 if (valuetype != V_VERDICT) FATAL_ERROR("Value::Value()");
1321 switch (p_verdict) {
1322 case Verdict_NONE:
1323 case Verdict_PASS:
1324 case Verdict_INCONC:
1325 case Verdict_FAIL:
1326 case Verdict_ERROR:
1327 break;
1328 default:
1329 FATAL_ERROR("Value::Value()");
1330 } // switch
1331 u.verdict = p_verdict;
1332 }
1333
1334 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2)
1335 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1336 {
1337 u.expr.v_optype = p_optype;
1338 u.expr.state = EXPR_NOT_CHECKED;
1339 switch(p_optype) {
1340 case OPTYPE_DECODE:
1d0599f0 1341 case OPTYPE_DECVALUE_UNICHAR:
970ed795
EL
1342 if(!p_r1 || !p_r2) FATAL_ERROR("Value::Value()");
1343 u.expr.r1=p_r1;
1344 u.expr.r2=p_r2;
1345 break;
1346 default:
1347 FATAL_ERROR("Value::Value()");
1348 } // switch
1349 }
1d0599f0 1350
1351 // r1 r2 [v3]
1352 Value::Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1, Ttcn::Ref_base *p_r2,
1353 Value *p_v3)
1354 : GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0)
1355 {
1356 u.expr.v_optype = p_optype;
1357 u.expr.state = EXPR_NOT_CHECKED;
1358 switch(p_optype) {
1359 case OPTYPE_DECVALUE_UNICHAR:
1360 if(!p_r1 || !p_r2 || !p_v3) FATAL_ERROR("Value::Value()");
1361 u.expr.r1=p_r1;
1362 u.expr.r2=p_r2;
1363 u.expr.v3=p_v3;
1364 break;
1365 default:
1366 FATAL_ERROR("Value::Value()");
1367 } // switch
1368 }
970ed795
EL
1369
1370 Value::~Value()
1371 {
1372 clean_up();
1373 }
1374
1375 Value *Value::clone() const
1376 {
1377 return new Value(*this);
1378 }
1379
1380 Value::operationtype_t Value::get_optype() const
1381 {
1382 if(valuetype!=V_EXPR)
1383 FATAL_ERROR("Value::get_optype()");
1384 return u.expr.v_optype;
1385 }
1386
1387 void Value::set_my_governor(Type *p_gov)
1388 {
1389 if(!p_gov)
1390 FATAL_ERROR("Value::set_my_governor(): NULL parameter");
1391 my_governor=p_gov;
1392 }
1393
1394 Type *Value::get_my_governor() const
1395 {
1396 return my_governor;
1397 }
1398
1399 void Value::set_fullname(const string& p_fullname)
1400 {
1401 GovernedSimple::set_fullname(p_fullname);
1402 switch(valuetype) {
1403 case V_CHARSYMS:
1404 u.char_syms->set_fullname(p_fullname);
1405 break;
1406 case V_OID:
1407 case V_ROID:
1408 for(size_t i=0; i<u.oid_comps->size(); i++)
1409 (*u.oid_comps)[i]->set_fullname(p_fullname+"."+Int2string(i+1));
1410 break;
1411 case V_CHOICE:
1412 u.choice.alt_value->set_fullname(p_fullname + "." +
1413 u.choice.alt_name->get_dispname());
1414 break;
1415 case V_SEQOF:
1416 case V_SETOF:
1417 case V_ARRAY:
1418 u.val_vs->set_fullname(p_fullname);
1419 break;
1420 case V_SEQ:
1421 case V_SET:
1422 u.val_nvs->set_fullname(p_fullname);
1423 break;
1424 case V_REFD:
1425 u.ref.ref->set_fullname(p_fullname);
1426 break;
1427 case V_REFER:
1428 u.refered->set_fullname(p_fullname);
1429 break;
1430 case V_INVOKE:
1431 u.invoke.v->set_fullname(p_fullname);
1432 if(u.invoke.t_list) u.invoke.t_list->set_fullname(p_fullname);
1433 if(u.invoke.ap_list) u.invoke.ap_list->set_fullname(p_fullname);
1434 break;
1435 case V_EXPR:
1436 set_fullname_expr(p_fullname);
1437 break;
1438 default:
1439 break;
1440 } // switch
1441 }
1442
1443 void Value::set_my_scope(Scope *p_scope)
1444 {
1445 GovernedSimple::set_my_scope(p_scope);
1446 switch(valuetype) {
1447 case V_CHARSYMS:
1448 u.char_syms->set_my_scope(p_scope);
1449 break;
1450 case V_OID:
1451 case V_ROID:
1452 for(size_t i=0; i<u.oid_comps->size(); i++)
1453 (*u.oid_comps)[i]->set_my_scope(p_scope);
1454 break;
1455 case V_CHOICE:
1456 u.choice.alt_value->set_my_scope(p_scope);
1457 break;
1458 case V_SEQOF:
1459 case V_SETOF:
1460 case V_ARRAY:
1461 u.val_vs->set_my_scope(p_scope);
1462 break;
1463 case V_SEQ:
1464 case V_SET:
1465 u.val_nvs->set_my_scope(p_scope);
1466 break;
1467 case V_REFD:
1468 u.ref.ref->set_my_scope(p_scope);
1469 break;
1470 case V_REFER:
1471 u.refered->set_my_scope(p_scope);
1472 break;
1473 case V_INVOKE:
1474 u.invoke.v->set_my_scope(p_scope);
1475 if(u.invoke.t_list) u.invoke.t_list->set_my_scope(p_scope);
1476 if(u.invoke.ap_list) u.invoke.ap_list->set_my_scope(p_scope);
1477 break;
1478 case V_EXPR:
1479 set_my_scope_expr(p_scope);
1480 break;
1481 default:
1482 break;
1483 } // switch
1484 }
1485
1486 void Value::set_fullname_expr(const string& p_fullname)
1487 {
1488 switch (u.expr.v_optype) {
1489 case OPTYPE_RND: // -
1490 case OPTYPE_COMP_NULL:
1491 case OPTYPE_COMP_MTC:
1492 case OPTYPE_COMP_SYSTEM:
1493 case OPTYPE_COMP_SELF:
1494 case OPTYPE_COMP_RUNNING_ANY:
1495 case OPTYPE_COMP_RUNNING_ALL:
1496 case OPTYPE_COMP_ALIVE_ANY:
1497 case OPTYPE_COMP_ALIVE_ALL:
1498 case OPTYPE_TMR_RUNNING_ANY:
1499 case OPTYPE_GETVERDICT:
1500 case OPTYPE_TESTCASENAME:
a38c6d4c 1501 case OPTYPE_PROF_RUNNING:
970ed795
EL
1502 break;
1503 case OPTYPE_UNARYPLUS: // v1
1504 case OPTYPE_UNARYMINUS:
1505 case OPTYPE_NOT:
1506 case OPTYPE_NOT4B:
1507 case OPTYPE_BIT2HEX:
1508 case OPTYPE_BIT2INT:
1509 case OPTYPE_BIT2OCT:
1510 case OPTYPE_BIT2STR:
1511 case OPTYPE_CHAR2INT:
1512 case OPTYPE_CHAR2OCT:
1513 case OPTYPE_COMP_RUNNING:
1514 case OPTYPE_COMP_ALIVE:
1515 case OPTYPE_FLOAT2INT:
1516 case OPTYPE_FLOAT2STR:
1517 case OPTYPE_HEX2BIT:
1518 case OPTYPE_HEX2INT:
1519 case OPTYPE_HEX2OCT:
1520 case OPTYPE_HEX2STR:
1521 case OPTYPE_INT2CHAR:
1522 case OPTYPE_INT2FLOAT:
1523 case OPTYPE_INT2STR:
1524 case OPTYPE_INT2UNICHAR:
1525 case OPTYPE_OCT2BIT:
1526 case OPTYPE_OCT2CHAR:
1527 case OPTYPE_OCT2HEX:
1528 case OPTYPE_OCT2INT:
1529 case OPTYPE_OCT2STR:
1530 case OPTYPE_STR2BIT:
1531 case OPTYPE_STR2FLOAT:
1532 case OPTYPE_STR2HEX:
1533 case OPTYPE_STR2INT:
1534 case OPTYPE_STR2OCT:
1535 case OPTYPE_UNICHAR2INT:
1536 case OPTYPE_UNICHAR2CHAR:
1537 case OPTYPE_ENUM2INT:
1538 case OPTYPE_RNDWITHVAL:
1539 case OPTYPE_REMOVE_BOM:
1540 case OPTYPE_GET_STRINGENCODING:
1541 case OPTYPE_DECODE_BASE64:
1542 u.expr.v1->set_fullname(p_fullname+".<operand>");
1543 break;
efbe586d 1544 case OPTYPE_HOSTID: // [v1]
1545 if(u.expr.v1) u.expr.v1->set_fullname(p_fullname+".<operand>");
1546 break;
970ed795
EL
1547 case OPTYPE_ADD: // v1 v2
1548 case OPTYPE_SUBTRACT:
1549 case OPTYPE_MULTIPLY:
1550 case OPTYPE_DIVIDE:
1551 case OPTYPE_MOD:
1552 case OPTYPE_REM:
1553 case OPTYPE_CONCAT:
1554 case OPTYPE_EQ:
1555 case OPTYPE_LT:
1556 case OPTYPE_GT:
1557 case OPTYPE_NE:
1558 case OPTYPE_GE:
1559 case OPTYPE_LE:
1560 case OPTYPE_AND:
1561 case OPTYPE_OR:
1562 case OPTYPE_XOR:
1563 case OPTYPE_AND4B:
1564 case OPTYPE_OR4B:
1565 case OPTYPE_XOR4B:
1566 case OPTYPE_SHL:
1567 case OPTYPE_SHR:
1568 case OPTYPE_ROTL:
1569 case OPTYPE_ROTR:
1570 case OPTYPE_INT2BIT:
1571 case OPTYPE_INT2HEX:
1572 case OPTYPE_INT2OCT:
1573 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1574 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1575 break;
1576 case OPTYPE_UNICHAR2OCT:
1577 case OPTYPE_OCT2UNICHAR:
1578 case OPTYPE_ENCODE_BASE64:
1579 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1580 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1581 break;
1582 case OPTYPE_DECODE:
1583 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1584 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1585 break;
1586 case OPTYPE_SUBSTR:
1587 u.expr.ti1->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_REGEXP:
1592 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1593 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1594 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1595 break;
1596 case OPTYPE_DECOMP: // v1 v2 v3
1597 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1598 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1599 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1600 break;
1601 case OPTYPE_REPLACE:
1602 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1603 u.expr.v2->set_fullname(p_fullname+".<operand2>");
1604 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1605 u.expr.ti4->set_fullname(p_fullname+".<operand4>");
1606 break;
1607 case OPTYPE_LENGTHOF: // ti1
1608 case OPTYPE_SIZEOF: // ti1
1609 case OPTYPE_VALUEOF: // ti1
1610 case OPTYPE_ISVALUE:
1611 case OPTYPE_ISBOUND:
1612 case OPTYPE_ENCODE:
1613 case OPTYPE_ISPRESENT:
1614 case OPTYPE_TTCN2STRING:
1615 u.expr.ti1->set_fullname(p_fullname+".<operand>");
1616 break;
1d0599f0 1617 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
1618 u.expr.ti1->set_fullname(p_fullname+".<operand1>");
1619 if (u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1620 break;
1621 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1622 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1623 u.expr.r2->set_fullname(p_fullname+".<operand2>");
1624 if (u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
970ed795
EL
1625 case OPTYPE_UNDEF_RUNNING: // r1
1626 case OPTYPE_TMR_READ:
1627 case OPTYPE_TMR_RUNNING:
1628 case OPTYPE_ACTIVATE:
1629 u.expr.r1->set_fullname(p_fullname+".<operand>");
1630 break;
1631 case OPTYPE_EXECUTE: // r1 [v2]
1632 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1633 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1634 break;
1635 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
1636 u.expr.r1->set_fullname(p_fullname+".<operand1>");
1637 if(u.expr.v2) u.expr.v2->set_fullname(p_fullname+".<operand2>");
1638 if(u.expr.v3) u.expr.v3->set_fullname(p_fullname+".<operand3>");
1639 break;
1640 case OPTYPE_MATCH: // v1 t2
1641 u.expr.v1->set_fullname(p_fullname+".<operand1>");
1642 u.expr.t2->set_fullname(p_fullname+".<operand2>");
1643 break;
1644 case OPTYPE_ISCHOSEN: // r1 i2
1645 u.expr.r1->set_fullname(p_fullname+".<operand>");
1646 break;
1647 case OPTYPE_ISCHOSEN_V: // v1 i2
1648 u.expr.v1->set_fullname(p_fullname+".<operand>");
1649 break;
1650 case OPTYPE_ISCHOSEN_T: // t1 i2
1651 u.expr.t1->set_fullname(p_fullname+".<operand>");
1652 break;
1653 case OPTYPE_ACTIVATE_REFD:
1654 u.expr.v1->set_fullname(p_fullname+".<reference>");
1655 if(u.expr.state!=EXPR_CHECKED)
1656 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1657 else
1658 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1659 break;
1660 case OPTYPE_EXECUTE_REFD:
1661 u.expr.v1->set_fullname(p_fullname+".<reference>");
1662 if(u.expr.state!=EXPR_CHECKED)
1663 u.expr.t_list2->set_fullname(p_fullname+".<parameterlist>");
1664 else
1665 u.expr.ap_list2->set_fullname(p_fullname+".<parameterlist>");
1666 if(u.expr.v3)
1667 u.expr.v3->set_fullname(p_fullname+".<operand3>");
1668 break;
1669 case OPTYPE_LOG2STR:
1670 u.expr.logargs->set_fullname(p_fullname+".<logargs>");
1671 break;
a50716c1 1672 case OPTYPE_ANY2UNISTR:
1673 u.expr.logargs->set_fullname(p_fullname+".<logarg>");
1674 break;
0a1610f4 1675 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
1676 case OPTYPE_CHECKSTATE_ALL:
1677 u.expr.v2->set_fullname(p_fullname+".<operand1>");
1678 break;
970ed795
EL
1679 default:
1680 FATAL_ERROR("Value::set_fullname_expr()");
1681 } // switch
1682 }
1683
1684 void Value::set_my_scope_expr(Scope *p_scope)
1685 {
1686 switch (u.expr.v_optype) {
1687 case OPTYPE_RND: // -
1688 case OPTYPE_COMP_NULL:
1689 case OPTYPE_COMP_MTC:
1690 case OPTYPE_COMP_SYSTEM:
1691 case OPTYPE_COMP_SELF:
1692 case OPTYPE_COMP_RUNNING_ANY:
1693 case OPTYPE_COMP_RUNNING_ALL:
1694 case OPTYPE_COMP_ALIVE_ANY:
1695 case OPTYPE_COMP_ALIVE_ALL:
1696 case OPTYPE_TMR_RUNNING_ANY:
1697 case OPTYPE_GETVERDICT:
1698 case OPTYPE_TESTCASENAME:
a38c6d4c 1699 case OPTYPE_PROF_RUNNING:
970ed795
EL
1700 break;
1701 case OPTYPE_UNARYPLUS: // v1
1702 case OPTYPE_UNARYMINUS:
1703 case OPTYPE_NOT:
1704 case OPTYPE_NOT4B:
1705 case OPTYPE_BIT2HEX:
1706 case OPTYPE_BIT2INT:
1707 case OPTYPE_BIT2OCT:
1708 case OPTYPE_BIT2STR:
1709 case OPTYPE_CHAR2INT:
1710 case OPTYPE_CHAR2OCT:
1711 case OPTYPE_COMP_RUNNING:
1712 case OPTYPE_COMP_ALIVE:
1713 case OPTYPE_FLOAT2INT:
1714 case OPTYPE_FLOAT2STR:
1715 case OPTYPE_HEX2BIT:
1716 case OPTYPE_HEX2INT:
1717 case OPTYPE_HEX2OCT:
1718 case OPTYPE_HEX2STR:
1719 case OPTYPE_INT2CHAR:
1720 case OPTYPE_INT2FLOAT:
1721 case OPTYPE_INT2STR:
1722 case OPTYPE_INT2UNICHAR:
1723 case OPTYPE_OCT2BIT:
1724 case OPTYPE_OCT2CHAR:
1725 case OPTYPE_OCT2HEX:
1726 case OPTYPE_OCT2INT:
1727 case OPTYPE_OCT2STR:
1728 case OPTYPE_STR2BIT:
1729 case OPTYPE_STR2FLOAT:
1730 case OPTYPE_STR2HEX:
1731 case OPTYPE_STR2INT:
1732 case OPTYPE_STR2OCT:
1733 case OPTYPE_UNICHAR2INT:
1734 case OPTYPE_UNICHAR2CHAR:
1735 case OPTYPE_ENUM2INT:
1736 case OPTYPE_RNDWITHVAL:
1737 case OPTYPE_REMOVE_BOM:
1738 case OPTYPE_GET_STRINGENCODING:
1739 case OPTYPE_DECODE_BASE64:
1740 u.expr.v1->set_my_scope(p_scope);
1741 break;
efbe586d 1742 case OPTYPE_HOSTID: // [v1]
1743 if(u.expr.v1) u.expr.v1->set_my_scope(p_scope);
1744 break;
970ed795
EL
1745 case OPTYPE_ADD: // v1 v2
1746 case OPTYPE_SUBTRACT:
1747 case OPTYPE_MULTIPLY:
1748 case OPTYPE_DIVIDE:
1749 case OPTYPE_MOD:
1750 case OPTYPE_REM:
1751 case OPTYPE_CONCAT:
1752 case OPTYPE_EQ:
1753 case OPTYPE_LT:
1754 case OPTYPE_GT:
1755 case OPTYPE_NE:
1756 case OPTYPE_GE:
1757 case OPTYPE_LE:
1758 case OPTYPE_AND:
1759 case OPTYPE_OR:
1760 case OPTYPE_XOR:
1761 case OPTYPE_AND4B:
1762 case OPTYPE_OR4B:
1763 case OPTYPE_XOR4B:
1764 case OPTYPE_SHL:
1765 case OPTYPE_SHR:
1766 case OPTYPE_ROTL:
1767 case OPTYPE_ROTR:
1768 case OPTYPE_INT2BIT:
1769 case OPTYPE_INT2HEX:
1770 case OPTYPE_INT2OCT:
1771 u.expr.v1->set_my_scope(p_scope);
1772 u.expr.v2->set_my_scope(p_scope);
1773 break;
1774 case OPTYPE_UNICHAR2OCT:
1775 case OPTYPE_OCT2UNICHAR:
1776 case OPTYPE_ENCODE_BASE64:
1777 u.expr.v1->set_my_scope(p_scope);
1778 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1779 break;
1780 case OPTYPE_DECODE:
1781 u.expr.r1->set_my_scope(p_scope);
1782 u.expr.r2->set_my_scope(p_scope);
1783 break;
1784 case OPTYPE_SUBSTR:
1785 u.expr.ti1->set_my_scope(p_scope);
1786 u.expr.v2->set_my_scope(p_scope);
1787 u.expr.v3->set_my_scope(p_scope);
1788 break;
1789 case OPTYPE_REGEXP:
1790 u.expr.ti1->set_my_scope(p_scope);
1791 u.expr.t2->set_my_scope(p_scope);
1792 u.expr.v3->set_my_scope(p_scope);
1793 break;
1794 case OPTYPE_DECOMP: // v1 v2 v3
1795 u.expr.v1->set_my_scope(p_scope);
1796 u.expr.v2->set_my_scope(p_scope);
1797 u.expr.v3->set_my_scope(p_scope);
1798 break;
1799 case OPTYPE_REPLACE:
1800 u.expr.ti1->set_my_scope(p_scope);
1801 u.expr.v2->set_my_scope(p_scope);
1802 u.expr.v3->set_my_scope(p_scope);
1803 u.expr.ti4->set_my_scope(p_scope);
1804 break;
1805 case OPTYPE_LENGTHOF: // ti1
1806 case OPTYPE_SIZEOF: // ti1
1807 case OPTYPE_VALUEOF: // ti1
1808 case OPTYPE_ISVALUE:
1809 case OPTYPE_ISBOUND:
1810 case OPTYPE_ENCODE:
1811 case OPTYPE_ISPRESENT:
1812 case OPTYPE_TTCN2STRING:
1813 u.expr.ti1->set_my_scope(p_scope);
1814 break;
1d0599f0 1815 case OPTYPE_ENCVALUE_UNICHAR: //ti1 [v2]
1816 u.expr.ti1->set_my_scope(p_scope);
1817 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1818 break;
1819 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
1820 u.expr.r1->set_my_scope(p_scope);
1821 u.expr.r2->set_my_scope(p_scope);
1822 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1823 break;
970ed795
EL
1824 case OPTYPE_UNDEF_RUNNING: // r1
1825 case OPTYPE_TMR_READ:
1826 case OPTYPE_TMR_RUNNING:
1827 case OPTYPE_ACTIVATE:
1828 u.expr.r1->set_my_scope(p_scope);
1829 break;
1830 case OPTYPE_EXECUTE: // r1 [v2]
1831 u.expr.r1->set_my_scope(p_scope);
1832 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1833 break;
0a1610f4 1834 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
1835 case OPTYPE_CHECKSTATE_ALL:
1836 if(u.expr.r1) u.expr.r1->set_my_scope(p_scope);
1837 u.expr.v2->set_my_scope(p_scope);
1838 break;
970ed795
EL
1839 case OPTYPE_COMP_CREATE: // r1 [v2] [v3]
1840 u.expr.r1->set_my_scope(p_scope);
1841 if(u.expr.v2) u.expr.v2->set_my_scope(p_scope);
1842 if(u.expr.v3) u.expr.v3->set_my_scope(p_scope);
1843 break;
1844 case OPTYPE_MATCH: // v1 t2
1845 u.expr.v1->set_my_scope(p_scope);
1846 u.expr.t2->set_my_scope(p_scope);
1847 break;
1848 case OPTYPE_ISCHOSEN: // r1 i2
1849 u.expr.r1->set_my_scope(p_scope);
1850 break;
1851 case OPTYPE_ISCHOSEN_V: // v1 i2
1852 u.expr.v1->set_my_scope(p_scope);
1853 break;
1854 case OPTYPE_ISCHOSEN_T: // t1 i2
1855 u.expr.t1->set_my_scope(p_scope);
1856 break;
1857 case OPTYPE_ACTIVATE_REFD:
1858 u.expr.v1->set_my_scope(p_scope);
1859 if(u.expr.state!=EXPR_CHECKED) {
1860 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1861 else
1862 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1863 } break;
1864 case OPTYPE_EXECUTE_REFD:
1865 u.expr.v1->set_my_scope(p_scope);
1866 if(u.expr.state!=EXPR_CHECKED) {
1867 if(u.expr.t_list2) u.expr.t_list2->set_my_scope(p_scope);
1868 else
1869 if(u.expr.ap_list2) u.expr.ap_list2->set_my_scope(p_scope);
1870 }
1871 if(u.expr.v3)
1872 u.expr.v3->set_my_scope(p_scope);
1873 break;
1874 case OPTYPE_LOG2STR:
a50716c1 1875 case OPTYPE_ANY2UNISTR:
970ed795
EL
1876 u.expr.logargs->set_my_scope(p_scope);
1877 break;
1878 default:
1879 FATAL_ERROR("Value::set_my_scope_expr()");
1880 } // switch
1881 }
1882
1883 void Value::set_genname_recursive(const string& p_genname)
1884 {
1885 size_t genname_len = p_genname.size();
1886 if (genname_len >= 4 &&
1887 p_genname.find("()()", genname_len - 4) == genname_len - 4) {
1888 // if the genname ends with ()() (i.e. the value stands for an optional
1889 // field) then drop the last () from the own genname, but leave it for
1890 // the embedded values
1891 set_genname(p_genname.substr(0, genname_len - 2));
1892 } else set_genname(p_genname);
1893 switch(valuetype) {
1894 case V_CHOICE: {
1895 string embedded_genname(p_genname);
1896 embedded_genname += '.';
1897 // If this is a choice value for an anytype, prepend the AT_ prefix
1898 // to the name of the alternative. The genname is used later in
1899 // Common::Value::generate_code_init_se()
1900 if (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
1901 embedded_genname += "AT_";
1902 embedded_genname += u.choice.alt_name->get_name();
1903 embedded_genname += "()";
1904 u.choice.alt_value->set_genname_recursive(embedded_genname);
1905 break; }
1906 case V_SEQOF:
1907 case V_SETOF: {
1908 if (!is_indexed()) {
1909 size_t nof_vs = u.val_vs->get_nof_vs();
1910 for (size_t i = 0; i < nof_vs; i++) {
1911 string embedded_genname(p_genname);
1912 embedded_genname += '[';
1913 embedded_genname += Int2string(i);
1914 embedded_genname += ']';
1915 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1916 }
1917 } else {
1918 size_t nof_ivs = u.val_vs->get_nof_ivs();
1919 for (size_t i = 0; i < nof_ivs; i++) {
1920 string embedded_genname(p_genname);
1921 embedded_genname += '[';
1922 embedded_genname += Int2string(i);
1923 embedded_genname += ']';
1924 u.val_vs->get_iv_byIndex(i)->get_value()
1925 ->set_genname_recursive(embedded_genname);
1926 }
1927 }
1928 break; }
1929 case V_ARRAY: {
1930 if (!my_governor) return; // error recovery
1931 Type *type = my_governor->get_type_refd_last();
1932 if (type->get_typetype() != Type::T_ARRAY) return; // error recovery
1933 Int offset = type->get_dimension()->get_offset();
1934 if (!is_indexed()) {
1935 size_t nof_vs = u.val_vs->get_nof_vs();
1936 for (size_t i = 0; i < nof_vs; i++) {
1937 string embedded_genname(p_genname);
1938 embedded_genname += '[';
1939 embedded_genname += Int2string(offset + i);
1940 embedded_genname += ']';
1941 u.val_vs->get_v_byIndex(i)->set_genname_recursive(embedded_genname);
1942 }
1943 } else {
1944 size_t nof_ivs = u.val_vs->get_nof_ivs();
1945 for (size_t i = 0; i < nof_ivs; i++) {
1946 string embedded_genname(p_genname);
1947 embedded_genname += '[';
1948 embedded_genname += Int2string(offset + i);
1949 embedded_genname += ']';
1950 u.val_vs->get_iv_byIndex(i)->get_value()
1951 ->set_genname_recursive(embedded_genname);
1952 }
1953 }
1954 break; }
1955 case V_SEQ:
1956 case V_SET: {
1957 if (!my_governor) return; // error recovery
1958 Type *t = my_governor->get_type_refd_last();
1959 if (!t->is_secho()) return; // error recovery
1960 size_t nof_nvs = u.val_nvs->get_nof_nvs();
1961 for (size_t i = 0; i < nof_nvs; i++) {
1962 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
1963 const Identifier& id = nv->get_name();
1964 if (!t->has_comp_withName(id)) return; // error recovery
1965 string embedded_genname(p_genname);
1966 embedded_genname += '.';
1967 embedded_genname += id.get_name();
1968 embedded_genname += "()";
1969 if (t->get_comp_byName(id)->get_is_optional())
1970 embedded_genname += "()";
1971 nv->get_value()->set_genname_recursive(embedded_genname);
1972 }
1973 break; }
1974 default:
1975 break;
1976 } // switch
1977 }
1978
1979 void Value::set_genname_prefix(const char *p_genname_prefix)
1980 {
1981 GovernedSimple::set_genname_prefix(p_genname_prefix);
1982 switch(valuetype) {
1983 case V_CHOICE:
1984 u.choice.alt_value->set_genname_prefix(p_genname_prefix);
1985 break;
1986 case V_SEQOF:
1987 case V_SETOF:
1988 case V_ARRAY:
1989 if (!is_indexed()) {
1990 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
1991 u.val_vs->get_v_byIndex(i)->set_genname_prefix(p_genname_prefix);
1992 } else {
1993 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
1994 u.val_vs->get_iv_byIndex(i)->get_value()
1995 ->set_genname_prefix(p_genname_prefix);
1996 }
1997 break;
1998 case V_SEQ:
1999 case V_SET:
2000 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2001 u.val_nvs->get_nv_byIndex(i)->get_value()
2002 ->set_genname_prefix(p_genname_prefix);
2003 break;
2004 default:
2005 break;
2006 } // switch
2007 }
2008
2009 void Value::set_code_section(code_section_t p_code_section)
2010 {
2011 GovernedSimple::set_code_section(p_code_section);
2012 switch(valuetype) {
2013 case V_EXPR:
2014 switch (u.expr.v_optype) {
2015 case OPTYPE_RND: // -
2016 case OPTYPE_COMP_NULL:
2017 case OPTYPE_COMP_MTC:
2018 case OPTYPE_COMP_SYSTEM:
2019 case OPTYPE_COMP_SELF:
2020 case OPTYPE_COMP_RUNNING_ANY:
2021 case OPTYPE_COMP_RUNNING_ALL:
2022 case OPTYPE_COMP_ALIVE_ANY:
2023 case OPTYPE_COMP_ALIVE_ALL:
2024 case OPTYPE_TMR_RUNNING_ANY:
2025 case OPTYPE_GETVERDICT:
2026 case OPTYPE_TESTCASENAME:
a38c6d4c 2027 case OPTYPE_PROF_RUNNING:
970ed795
EL
2028 break;
2029 case OPTYPE_UNARYPLUS: // v1
2030 case OPTYPE_UNARYMINUS:
2031 case OPTYPE_NOT:
2032 case OPTYPE_NOT4B:
2033 case OPTYPE_BIT2HEX:
2034 case OPTYPE_BIT2INT:
2035 case OPTYPE_BIT2OCT:
2036 case OPTYPE_BIT2STR:
2037 case OPTYPE_CHAR2INT:
2038 case OPTYPE_CHAR2OCT:
2039 case OPTYPE_COMP_RUNNING:
2040 case OPTYPE_COMP_ALIVE:
2041 case OPTYPE_FLOAT2INT:
2042 case OPTYPE_FLOAT2STR:
2043 case OPTYPE_HEX2BIT:
2044 case OPTYPE_HEX2INT:
2045 case OPTYPE_HEX2OCT:
2046 case OPTYPE_HEX2STR:
2047 case OPTYPE_INT2CHAR:
2048 case OPTYPE_INT2FLOAT:
2049 case OPTYPE_INT2STR:
2050 case OPTYPE_INT2UNICHAR:
2051 case OPTYPE_OCT2BIT:
2052 case OPTYPE_OCT2CHAR:
2053 case OPTYPE_OCT2HEX:
2054 case OPTYPE_OCT2INT:
2055 case OPTYPE_OCT2STR:
2056 case OPTYPE_STR2BIT:
2057 case OPTYPE_STR2FLOAT:
2058 case OPTYPE_STR2HEX:
2059 case OPTYPE_STR2INT:
2060 case OPTYPE_STR2OCT:
2061 case OPTYPE_UNICHAR2INT:
2062 case OPTYPE_UNICHAR2CHAR:
2063 case OPTYPE_ENUM2INT:
2064 case OPTYPE_RNDWITHVAL:
2065 case OPTYPE_GET_STRINGENCODING:
2066 case OPTYPE_DECODE_BASE64:
2067 case OPTYPE_REMOVE_BOM:
2068 u.expr.v1->set_code_section(p_code_section);
2069 break;
efbe586d 2070 case OPTYPE_HOSTID: // [v1]
2071 if(u.expr.v1) u.expr.v1->set_code_section(p_code_section);
2072 break;
970ed795
EL
2073 case OPTYPE_ADD: // v1 v2
2074 case OPTYPE_SUBTRACT:
2075 case OPTYPE_MULTIPLY:
2076 case OPTYPE_DIVIDE:
2077 case OPTYPE_MOD:
2078 case OPTYPE_REM:
2079 case OPTYPE_CONCAT:
2080 case OPTYPE_EQ:
2081 case OPTYPE_LT:
2082 case OPTYPE_GT:
2083 case OPTYPE_NE:
2084 case OPTYPE_GE:
2085 case OPTYPE_LE:
2086 case OPTYPE_AND:
2087 case OPTYPE_OR:
2088 case OPTYPE_XOR:
2089 case OPTYPE_AND4B:
2090 case OPTYPE_OR4B:
2091 case OPTYPE_XOR4B:
2092 case OPTYPE_SHL:
2093 case OPTYPE_SHR:
2094 case OPTYPE_ROTL:
2095 case OPTYPE_ROTR:
2096 case OPTYPE_INT2BIT:
2097 case OPTYPE_INT2HEX:
2098 case OPTYPE_INT2OCT:
2099 u.expr.v1->set_code_section(p_code_section);
2100 u.expr.v2->set_code_section(p_code_section);
2101 break;
2102 case OPTYPE_UNICHAR2OCT:
2103 case OPTYPE_OCT2UNICHAR:
2104 case OPTYPE_ENCODE_BASE64:
2105 u.expr.v1->set_code_section(p_code_section);
2106 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2107 break;
2108 case OPTYPE_DECODE:
2109 u.expr.r1->set_code_section(p_code_section);
2110 u.expr.r2->set_code_section(p_code_section);
2111 break;
2112 case OPTYPE_SUBSTR:
2113 u.expr.ti1->set_code_section(p_code_section);
2114 u.expr.v2->set_code_section(p_code_section);
2115 u.expr.v3->set_code_section(p_code_section);
2116 break;
2117 case OPTYPE_REGEXP:
2118 u.expr.ti1->set_code_section(p_code_section);
2119 u.expr.t2->set_code_section(p_code_section);
2120 u.expr.v3->set_code_section(p_code_section);
2121 break;
2122 case OPTYPE_DECOMP: // v1 v2 v3
2123 u.expr.v1->set_code_section(p_code_section);
2124 u.expr.v2->set_code_section(p_code_section);
2125 u.expr.v3->set_code_section(p_code_section);
2126 break;
2127 case OPTYPE_REPLACE:
2128 u.expr.ti1->set_code_section(p_code_section);
2129 u.expr.v2->set_code_section(p_code_section);
2130 u.expr.v3->set_code_section(p_code_section);
2131 u.expr.ti4->set_code_section(p_code_section);
2132 break;
2133 case OPTYPE_LENGTHOF: // ti1
2134 case OPTYPE_SIZEOF: // ti1
2135 case OPTYPE_VALUEOF: // ti1
2136 case OPTYPE_ISVALUE:
2137 case OPTYPE_ISBOUND:
2138 case OPTYPE_ENCODE:
2139 case OPTYPE_ISPRESENT:
2140 case OPTYPE_TTCN2STRING:
2141 u.expr.ti1->set_code_section(p_code_section);
2142 break;
1d0599f0 2143 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
2144 u.expr.ti1->set_code_section(p_code_section);
2145 if (u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2146 break;
2147 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
2148 u.expr.r1->set_code_section(p_code_section);
2149 u.expr.r2->set_code_section(p_code_section);
2150 if (u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2151 break;
970ed795
EL
2152 case OPTYPE_UNDEF_RUNNING: // r1
2153 case OPTYPE_TMR_READ:
2154 case OPTYPE_TMR_RUNNING:
2155 case OPTYPE_ACTIVATE:
2156 u.expr.r1->set_code_section(p_code_section);
2157 break;
2158 case OPTYPE_EXECUTE: // r1 [v2]
2159 u.expr.r1->set_code_section(p_code_section);
2160 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2161 break;
0a1610f4 2162 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
2163 case OPTYPE_CHECKSTATE_ALL:
2164 if(u.expr.r1) u.expr.r1->set_code_section(p_code_section);
2165 u.expr.v2->set_code_section(p_code_section);
2166 break;
970ed795
EL
2167 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
2168 u.expr.r1->set_code_section(p_code_section);
2169 if(u.expr.v2) u.expr.v2->set_code_section(p_code_section);
2170 if(u.expr.v3) u.expr.v3->set_code_section(p_code_section);
2171 break;
2172 case OPTYPE_MATCH: // v1 t2
2173 u.expr.v1->set_code_section(p_code_section);
2174 u.expr.t2->set_code_section(p_code_section);
2175 break;
2176 case OPTYPE_ISCHOSEN: // r1 i2
2177 u.expr.r1->set_code_section(p_code_section);
2178 break;
2179 case OPTYPE_ISCHOSEN_V: // v1 i2
2180 u.expr.v1->set_code_section(p_code_section);
2181 break;
2182 case OPTYPE_ISCHOSEN_T: // t1 i2
2183 u.expr.t1->set_code_section(p_code_section);
2184 break;
2185 case OPTYPE_ACTIVATE_REFD:
2186 u.expr.v1->set_code_section(p_code_section);
2187 if(u.expr.state!=EXPR_CHECKED)
2188 u.expr.t_list2->set_code_section(p_code_section);
2189 else {
2190 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2191 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2192 u.expr.state = EXPR_CHECKED;
2193 }
2194 break;
2195 case OPTYPE_EXECUTE_REFD:
2196 u.expr.v1->set_code_section(p_code_section);
2197 if(u.expr.state!=EXPR_CHECKED)
2198 u.expr.t_list2->set_code_section(p_code_section);
2199 else {
2200 for(size_t i = 0; i < u.expr.ap_list2->get_nof_pars(); i++)
2201 u.expr.ap_list2->get_par(i)->set_code_section(p_code_section);
2202 u.expr.state = EXPR_CHECKED;
2203 }
2204 if(u.expr.v3)
2205 u.expr.v3->set_code_section(p_code_section);
2206 break;
2207 case OPTYPE_LOG2STR:
a50716c1 2208 case OPTYPE_ANY2UNISTR:
970ed795
EL
2209 u.expr.logargs->set_code_section(p_code_section);
2210 break;
2211 default:
2212 FATAL_ERROR("Value::set_code_section()");
2213 } // switch
2214 break;
2215 case V_CHOICE:
2216 u.choice.alt_value->set_code_section(p_code_section);
2217 break;
2218 case V_SEQOF:
2219 case V_SETOF:
2220 case V_ARRAY:
2221 if (!is_indexed()) {
2222 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++)
2223 u.val_vs->get_v_byIndex(i)->set_code_section(p_code_section);
2224 } else {
2225 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++)
2226 u.val_vs->get_iv_byIndex(i)->set_code_section(p_code_section);
2227 }
2228 break;
2229 case V_SEQ:
2230 case V_SET:
2231 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++)
2232 u.val_nvs->get_nv_byIndex(i)->get_value()
2233 ->set_code_section(p_code_section);
2234 break;
2235 case V_REFD:
2236 u.ref.ref->set_code_section(p_code_section);
2237 break;
2238 case V_REFER:
2239 u.refered->set_code_section(p_code_section);
2240 break;
2241 case V_INVOKE:
2242 u.invoke.v->set_code_section(p_code_section);
2243 if(u.invoke.t_list) u.invoke.t_list->set_code_section(p_code_section);
2244 if(u.invoke.ap_list)
2245 for(size_t i = 0; i < u.invoke.ap_list->get_nof_pars(); i++)
2246 u.invoke.ap_list->get_par(i)->set_code_section(p_code_section);
2247 break;
2248 default:
2249 break;
2250 } // switch
2251 }
2252
2253 void Value::change_sign()
2254 {
2255 switch(valuetype) {
2256 case V_INT:
2257 *u.val_Int=-*u.val_Int;
2258 break;
2259 case V_REAL:
2260 u.val_Real*=-1.0;
2261 break;
2262 case V_ERROR:
2263 break;
2264 default:
2265 FATAL_ERROR("Value::change_sign()");
2266 } // switch
2267 }
2268
2269 void Value::add_oid_comp(OID_comp* p_comp)
2270 {
2271 if(!p_comp)
2272 FATAL_ERROR("NULL parameter");
2273 u.oid_comps->add(p_comp);
2274 p_comp->set_fullname(get_fullname()+"."
2275 +Int2string(u.oid_comps->size()));
2276 p_comp->set_my_scope(my_scope);
2277 }
2278
2279 void Value::set_valuetype(valuetype_t p_valuetype)
2280 {
2281 if (valuetype == V_ERROR) return;
2282 else if (p_valuetype == V_ERROR) {
2283 if(valuetype==V_EXPR) {
2284 switch(u.expr.state) {
2285 case EXPR_CHECKING:
2286 u.expr.state=EXPR_CHECKING_ERR;
2287 // no break
2288 case EXPR_CHECKING_ERR:
2289 return;
2290 default:
2291 break;
2292 }
2293 }
2294 clean_up();
2295 valuetype = V_ERROR;
2296 return;
2297 }
2298 switch(valuetype) {
2299 case V_UNDEF_LOWERID:
2300 switch(p_valuetype) {
2301 case V_ENUM:
2302 case V_NAMEDINT:
2303 break;
2304 case V_REFD:
2305 if (is_asn1()) u.ref.ref = new Asn::Ref_defd_simple(0, u.val_id);
2306 else u.ref.ref = new Ttcn::Reference(0, u.val_id);
2307 u.ref.ref->set_my_scope(get_my_scope());
2308 u.ref.ref->set_fullname(get_fullname());
2309 u.ref.ref->set_location(*this);
2310 u.ref.refd_last = 0;
2311 break;
2312 default:
2313 FATAL_ERROR("Value::set_valuetype()");
2314 } // switch
2315 break;
2316 case V_UNDEF_BLOCK: {
2317 Block *t_block=u.block;
2318 Value *v=0;
2319 switch(p_valuetype) {
2320 case V_NAMEDBITS: {
2321 Node *node=t_block->parse(KW_Block_IdentifierList);
2322 v=dynamic_cast<Value*>(node);
2323 if(!v) {
2324 /* syntax error */
2325 u.ids=new map<string, Identifier>();
2326 }
2327 else {
2328 u.ids=v->u.ids; v->u.ids=0;
2329 }
2330 break;}
2331 case V_SEQOF: {
2332 Node *node=t_block->parse(KW_Block_SeqOfValue);
2333 v=dynamic_cast<Value*>(node);
2334 if(!v) {
2335 /* syntax error */
2336 u.val_vs=new Values();
2337 }
2338 else {
2339 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2340 }
2341 u.val_vs->set_my_scope(get_my_scope());
2342 u.val_vs->set_fullname(get_fullname());
2343 break;}
2344 case V_SETOF: {
2345 Node *node=t_block->parse(KW_Block_SetOfValue);
2346 v=dynamic_cast<Value*>(node);
2347 if(!v) {
2348 /* syntax error */
2349 u.val_vs=new Values();
2350 }
2351 else {
2352 u.val_vs=v->u.val_vs; v->u.val_vs=0;
2353 }
2354 u.val_vs->set_my_scope(get_my_scope());
2355 u.val_vs->set_fullname(get_fullname());
2356 break;}
2357 case V_SEQ: {
2358 Node *node=t_block->parse(KW_Block_SequenceValue);
2359 v=dynamic_cast<Value*>(node);
2360 if(!v) {
2361 /* syntax error */
2362 u.val_nvs=new NamedValues();
2363 }
2364 else {
2365 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2366 }
2367 u.val_nvs->set_my_scope(get_my_scope());
2368 u.val_nvs->set_fullname(get_fullname());
2369 break;}
2370 case V_SET: {
2371 Node *node=t_block->parse(KW_Block_SetValue);
2372 v=dynamic_cast<Value*>(node);
2373 if(!v) {
2374 /* syntax error */
2375 u.val_nvs=new NamedValues();
2376 }
2377 else {
2378 u.val_nvs=v->u.val_nvs; v->u.val_nvs=0;
2379 }
2380 u.val_nvs->set_my_scope(get_my_scope());
2381 u.val_nvs->set_fullname(get_fullname());
2382 break;}
2383 case V_OID: {
2384 Node *node=t_block->parse(KW_Block_OIDValue);
2385 v=dynamic_cast<Value*>(node);
2386 if(!v) {
2387 /* syntax error */
2388 u.oid_comps=new vector<OID_comp>();
2389 }
2390 else {
2391 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2392 }
2393 for (size_t i = 0; i < u.oid_comps->size(); i++)
2394 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2395 break;}
2396 case V_ROID: {
2397 Node *node=t_block->parse(KW_Block_ROIDValue);
2398 v=dynamic_cast<Value*>(node);
2399 if(!v) {
2400 /* syntax error */
2401 u.oid_comps=new vector<OID_comp>();
2402 }
2403 else {
2404 u.oid_comps=v->u.oid_comps; v->u.oid_comps=0;
2405 }
2406 for (size_t i = 0; i < u.oid_comps->size(); i++)
2407 (*u.oid_comps)[i]->set_my_scope(get_my_scope());
2408 break;}
2409 case V_CHARSYMS: {
2410 Node *node=t_block->parse(KW_Block_CharStringValue);
2411 u.char_syms=dynamic_cast<CharSyms*>(node);
2412 if(!u.char_syms) {
2413 /* syntax error */
2414 u.char_syms=new CharSyms();
2415 }
2416 u.char_syms->set_my_scope(get_my_scope());
2417 u.char_syms->set_fullname(get_fullname());
2418 break;}
2419 default:
2420 FATAL_ERROR("Value::set_valuetype()");
2421 } // switch
2422 delete v;
2423 delete t_block;
2424 break;}
2425 case V_REFD:
2426 if (p_valuetype == V_USTR) {
2427 Value *v_last = get_value_refd_last();
2428 if (v_last->valuetype != V_CSTR) FATAL_ERROR("Value::set_valuetype()");
2429 ustring *ustr = new ustring(*v_last->u.str.val_str);
2430 delete u.ref.ref;
2431 set_val_ustr(ustr);
2432 u.ustr.convert_str = true; // will be converted back to string
2433 } else FATAL_ERROR("Value::set_valuetype()");
2434 break;
2435 case V_CHARSYMS:
2436 switch(p_valuetype) {
2437 case V_CSTR: {
2438 const string& str = u.char_syms->get_string();
2439 delete u.char_syms;
2440 set_val_str(new string(str));
2441 break;}
2442 case V_USTR: {
2443 const ustring& ustr = u.char_syms->get_ustring();
2444 delete u.char_syms;
2445 set_val_ustr(new ustring(ustr));
2446 u.ustr.convert_str = false;
2447 break;}
2448 case V_ISO2022STR: {
2449 const string& str = u.char_syms->get_iso2022string();
2450 delete u.char_syms;
2451 set_val_str(new string(str));
2452 break;}
2453 default:
2454 FATAL_ERROR("Value::set_valuetype()");
2455 } // switch
2456 break;
2457 case V_INT: {
2458 Real val_Real;
2459 if (p_valuetype == V_REAL)
2460 val_Real = u.val_Int->to_real();
2461 else FATAL_ERROR("Value::set_valuetype()");
2462 clean_up();
2463 u.val_Real = val_Real;
2464 break; }
2465 case V_HSTR: {
2466 clean_up_string_elements(u.str.str_elements);
2467 string *old_str = u.str.val_str;
2468 switch(p_valuetype) {
2469 case V_BSTR:
2470 set_val_str(hex2bit(*old_str));
2471 break;
2472 case V_OSTR:
2473 set_val_str(asn_hex2oct(*old_str));
2474 break;
2475 default:
2476 FATAL_ERROR("Value::set_valuetype()");
2477 } // switch
2478 delete old_str;
2479 break;}
2480 case V_BSTR:
2481 clean_up_string_elements(u.str.str_elements);
2482 if (p_valuetype == V_OSTR) {
2483 string *old_str = u.str.val_str;
2484 set_val_str(asn_bit2oct(*old_str));
2485 delete old_str;
2486 } else FATAL_ERROR("Value::set_valuetype()");
2487 break;
2488 case V_CSTR:
2489 clean_up_string_elements(u.str.str_elements);
2490 switch(p_valuetype) {
2491 case V_USTR: {
2492 string *old_str = u.str.val_str;
2493 set_val_ustr(new ustring(*old_str));
2494 u.ustr.convert_str = true; // will be converted back to string
2495 delete old_str;
2496 break;}
2497 case V_ISO2022STR:
2498 // do nothing
2499 break;
2500 default:
2501 FATAL_ERROR("Value::set_valuetype()");
2502 } // switch p_valuetype
2503 break;
2504 case V_USTR:
2505 clean_up_string_elements(u.ustr.ustr_elements);
2506 switch(p_valuetype) {
2507 case V_CSTR: {
2508 ustring *old_str = u.ustr.val_ustr;
2509 size_t nof_chars = old_str->size();
2510 bool warning_flag = false;
2511 for (size_t i = 0; i < nof_chars; i++) {
2512 const ustring::universal_char& uchar = (*old_str)[i];
2513 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0) {
2514 error("This string value cannot contain multiple-byte characters, "
2515 "but it has quadruple char(%u, %u, %u, %u) at index %lu",
2516 uchar.group, uchar.plane, uchar.row, uchar.cell,
2517 (unsigned long) i);
2518 p_valuetype = V_ERROR;
2519 break;
2520 } else if (uchar.cell > 127 && !warning_flag) {
2521 warning("This string value may not contain characters with code "
2522 "higher than 127, but it has character with code %u (0x%02X) "
2523 "at index %lu", uchar.cell, uchar.cell, (unsigned long) i);
2524 warning_flag = true;
2525 }
2526 }
2527 if (p_valuetype != V_ERROR) set_val_str(new string(*old_str));
2528 delete old_str;
2529 break; }
2530 case V_ISO2022STR:
2531 error("ISO-10646 string value cannot be converted to "
2532 "ISO-2022 string");
2533 delete u.ustr.val_ustr;
2534 p_valuetype = V_ERROR;
2535 break;
2536 default:
2537 FATAL_ERROR("Value::set_valuetype()");
2538 } // switch p_valuetype
2539 break;
2540 case V_SEQ:
2541 switch (p_valuetype) {
2542 case V_CHOICE: {
2543 NamedValues *nvs = u.val_nvs;
2544 if (nvs->get_nof_nvs() < 1) {
2545 error("Union value must have one active field");
2546 delete nvs;
2547 valuetype = V_ERROR;
2548 return;
2549 } else if (nvs->get_nof_nvs() > 1) {
2550 error("Only one field was expected in union value instead of %lu",
2551 (unsigned long) nvs->get_nof_nvs());
2552 }
2553 NamedValue *nv = nvs->get_nv_byIndex(0);
2554 u.choice.alt_name = nv->get_name().clone();
2555 u.choice.alt_value = nv->steal_value();
2556 delete nvs;
2557 break;}
2558 case V_SET:
2559 // do nothing
2560 break;
2561 case V_REAL: {
2562 NamedValues *nvs = u.val_nvs;
2563 bool err = false;
2564 /* mantissa */
2565 Int i_mant = 0;
2566 Identifier id_mant(Identifier::ID_ASN, string("mantissa"));
2567 if (nvs->has_nv_withName(id_mant)) {
2568 Value *v_tmp = nvs->get_nv_byName(id_mant)->get_value()
2569 ->get_value_refd_last();
2570 if (v_tmp->get_valuetype() == V_INT) {
2571 const int_val_t *i_mant_int = v_tmp->get_val_Int();
2572 if (*i_mant_int > INT_MAX) {
2573 error("Mantissa `%s' should be less than `%d'",
2574 (i_mant_int->t_str()).c_str(), INT_MAX);
2575 err = true;
2576 } else {
2577 i_mant = i_mant_int->get_val();
2578 }
2579 }
2580 else err = true;
2581 }
2582 else err = true;
2583 /* base */
2584 Int i_base = 0;
2585 Identifier id_base(Identifier::ID_ASN, string("base"));
2586 if (!err && nvs->has_nv_withName(id_base)) {
2587 Value *v = nvs->get_nv_byName(id_base)->get_value();
2588 Value *v_tmp = v->get_value_refd_last();
2589 if (v_tmp->get_valuetype() == V_INT) {
2590 const int_val_t *i_base_int = v_tmp->get_val_Int();
2591 if (!err && *i_base_int != 10 && *i_base_int != 2) {
2592 v->error("Base of the REAL must be 2 or 10");
2593 err = true;
2594 } else {
2595 i_base = i_base_int->get_val();
2596 }
2597 }
2598 else err = true;
2599 }
2600 else err = true;
2601 /* exponent */
2602 Int i_exp = 0;
2603 Identifier id_exp(Identifier::ID_ASN, string("exponent"));
2604 if (!err && nvs->has_nv_withName(id_exp)) {
2605 Value *v_tmp = nvs->get_nv_byName(id_exp)->get_value()
2606 ->get_value_refd_last();
2607 if (v_tmp->get_valuetype() == V_INT) {
2608 const int_val_t *i_exp_int = v_tmp->get_val_Int();
2609 if (*i_exp_int > INT_MAX) {
2610 error("Exponent `%s' should be less than `%d'",
2611 (i_exp_int->t_str()).c_str(), INT_MAX);
2612 err = true;
2613 } else {
2614 i_exp = i_exp_int->get_val();
2615 }
2616 }
2617 else err = true;
2618 }
2619 else err = true;
2620 /* clean up */
2621 delete nvs;
2622 if (err) {
2623 valuetype = V_ERROR;
2624 return;
2625 }
2626 u.val_Real = i_mant * pow(static_cast<double>(i_base),
2627 static_cast<double>(i_exp));
2628 break; }
feade998 2629 case V_NOTUSED:
2630 clean_up();
2631 break;
970ed795
EL
2632 default:
2633 FATAL_ERROR("Value::set_valuetype()");
2634 } // switch
2635 break;
2636 case V_SEQOF:
2637 switch (p_valuetype) {
2638 case V_SEQ: {
2639 // SEQOF -> SEQ: value list notation (TTCN-3 only)
2640 if (!my_governor) FATAL_ERROR("Value::set_valuetype()");
2641 Type *t = my_governor->get_type_refd_last();
2642 switch (t->get_typetype()) {
2643 case Type::T_SEQ_T:
2644 case Type::T_SEQ_A:
2645 break;
2646 default:
2647 FATAL_ERROR("Value::set_valuetype()");
2648 }
2649 Values *vals = u.val_vs;
2650 size_t nof_vals = vals->get_nof_vs();
2651 size_t nof_comps = t->get_nof_comps();
2652 if (nof_vals > nof_comps) {
2653 error("Too many elements in value list notation for type `%s': "
2654 "%lu was expected instead of %lu",
2655 t->get_typename().c_str(),
2656 (unsigned long)nof_comps, (unsigned long)nof_vals);
2657 }
2658 size_t upper_limit;
2659 bool allnotused;
2660 if (nof_vals <= nof_comps) {
2661 upper_limit = nof_vals;
2662 allnotused = true;
2663 } else {
2664 upper_limit = nof_comps;
2665 allnotused = false;
2666 }
2667 u.val_nvs = new NamedValues;
2668 for (size_t i = 0; i < upper_limit; i++) {
2669 Value *v = vals->steal_v_byIndex(i);
2670 if (v->valuetype != V_NOTUSED) {
2671 allnotused = false;
2672 }
2673 NamedValue *nv =
2674 new NamedValue(t->get_comp_id_byIndex(i).clone(), v);
2675 nv->set_location(*v);
2676 u.val_nvs->add_nv(nv);
2677 }
2678 u.val_nvs->set_my_scope(get_my_scope());
2679 u.val_nvs->set_fullname(get_fullname());
2680 delete vals;
2681 if (allnotused && nof_vals > 0)
2682 warning("All elements of value list notation for type `%s' are not "
2683 "used symbols (`-')", t->get_typename().c_str());
2684 break; }
2685 case V_SET:
2686 // { } -> empty set value
2687 if (u.val_vs->get_nof_vs() != 0)
2688 FATAL_ERROR("Value::set_valuetype()");
2689 delete u.val_vs;
2690 u.val_nvs = new NamedValues;
2691 break;
2692 case V_SETOF:
2693 case V_ARRAY:
2694 // SEQOF -> SETOF or ARRAY: trivial
2695 break;
2696 default:
2697 FATAL_ERROR("Value::set_valuetype()");
2698 }
2699 break;
feade998 2700 case V_SET:
2701 case V_CHOICE:
2702 if (p_valuetype == V_NOTUSED) {
2703 clean_up();
2704 }
2705 else {
2706 FATAL_ERROR("Value::set_valuetype()");
2707 }
2708 break;
970ed795
EL
2709 case V_TTCN3_NULL:
2710 switch (p_valuetype) {
2711 case V_DEFAULT_NULL:
2712 break;
2713 case V_FAT_NULL:
2714 break;
2715 default:
2716 FATAL_ERROR("Value::set_valuetype()");
2717 }
2718 break;
2719 case V_NOTUSED:
2720 if (V_OMIT != p_valuetype) { // in case of implicit omit
2721 FATAL_ERROR("Value::set_valuetype()");
2722 }
2723 break;
2724 default:
2725 FATAL_ERROR("Value::set_valuetype()");
2726 } // switch
2727 valuetype=p_valuetype;
2728 }
2729
2730 void Value::set_valuetype_COMP_NULL()
2731 {
2732 if(valuetype == V_ERROR) return;
2733 if(valuetype==V_TTCN3_NULL) {
2734 valuetype=V_EXPR;
2735 u.expr.v_optype=OPTYPE_COMP_NULL;
2736 // Nothing to check.
2737 u.expr.state=EXPR_CHECKED;
2738 }
2739 else FATAL_ERROR("Value::set_valuetype_COMP_NULL()");
2740 }
2741
2742 void Value::set_valuetype(valuetype_t p_valuetype, const Int& p_val_int)
2743 {
2744 if (valuetype == V_NAMEDINT && p_valuetype == V_INT) {
2745 delete u.val_id;
2746 u.val_Int = new int_val_t(p_val_int);
2747 valuetype = V_INT;
2748 } else FATAL_ERROR("Value::set_valuetype()");
2749 }
2750
2751 void Value::set_valuetype(valuetype_t p_valuetype, string *p_str)
2752 {
2753 if (p_str && valuetype == V_NAMEDBITS && p_valuetype == V_BSTR) {
2754 clean_up();
2755 valuetype = V_BSTR;
2756 set_val_str(p_str);
2757 } else FATAL_ERROR("Value::set_valuetype()");
2758 }
2759
2760 void Value::set_valuetype(valuetype_t p_valuetype, Identifier *p_id)
2761 {
2762 if (p_id && valuetype == V_UNDEF_LOWERID && p_valuetype == V_ENUM) {
2763 delete u.val_id;
2764 u.val_id = p_id;
2765 valuetype = V_ENUM;
2766 } else FATAL_ERROR("Value::set_valuetype()");
2767 }
2768
2769 void Value::set_valuetype(valuetype_t p_valuetype, Assignment *p_ass)
2770 {
2771 switch (p_valuetype) {
2772 case V_FUNCTION:
2773 case V_ALTSTEP:
2774 case V_TESTCASE:
2775 if (valuetype == V_REFER && p_ass) break;
2776 // no break
2777 default:
2778 FATAL_ERROR("Value::set_valuetype()");
2779 }
2780 delete u.refered;
2781 u.refd_fat = p_ass;
2782 valuetype = p_valuetype;
2783 }
2784
2785 bool Value::is_undef_lowerid()
2786 {
2787 switch (valuetype) {
2788 case V_UNDEF_LOWERID:
2789 return true;
2790 case V_EXPR:
2791 if (u.expr.v_optype == OPTYPE_VALUEOF && !u.expr.ti1->get_Type() &&
2792 !u.expr.ti1->get_DerivedRef()) {
2793 return u.expr.ti1->get_Template()->is_undef_lowerid();
2794 }
2795 // no break
2796 default:
2797 return false;
2798 }
2799 }
2800
2801 const Identifier& Value::get_undef_lowerid()
2802 {
2803 switch (valuetype) {
2804 case V_UNDEF_LOWERID:
2805 return *u.val_id;
2806 case V_EXPR:
2807 if (u.expr.v_optype != OPTYPE_VALUEOF)
2808 FATAL_ERROR("Value::get_undef_lowerid()");
2809 return u.expr.ti1->get_Template()->get_specific_value()
2810 ->get_undef_lowerid();
2811 default:
2812 FATAL_ERROR("Value::get_undef_lowerid()");
2813 }
2814 const Identifier *dummy = 0;
2815 return *dummy;
2816 }
2817
2818 void Value::set_lowerid_to_ref()
2819 {
2820 switch (valuetype) {
2821 case V_UNDEF_LOWERID:
2822 set_valuetype(V_REFD);
2823 break;
2824 case V_EXPR:
2825 // if the governor of the expression is not known (in log(), etc...)
2826 // then the governor is taken from the reference (using
2827 // v1/ti1->get_expr_governor()), but that runs before the
2828 // params were checked, this smells like a workaround :)
2829 switch (u.expr.v_optype) {
2830 case OPTYPE_ROTL:
2831 case OPTYPE_ROTR:
2832 u.expr.v1->set_lowerid_to_ref();
2833 break;
2834 case OPTYPE_CONCAT:
2835 u.expr.v1->set_lowerid_to_ref();
2836 u.expr.v2->set_lowerid_to_ref();
2837 break;
2838 case OPTYPE_VALUEOF:
2839 case OPTYPE_ISVALUE:
2840 case OPTYPE_ISBOUND:
2841 case OPTYPE_ISPRESENT:
2842 case OPTYPE_SUBSTR:
2843 case OPTYPE_REGEXP:
2844 case OPTYPE_REPLACE:
2845 case OPTYPE_TTCN2STRING:
2846 if (!u.expr.ti1->get_Type() && !u.expr.ti1->get_DerivedRef()) {
2847 Error_Context cntxt(u.expr.ti1->get_Template(),
2848 "In the operand of operation `%s'",
2849 get_opname());
2850 u.expr.ti1->get_Template()->set_lowerid_to_ref();
2851 }
2852 if (u.expr.v_optype==OPTYPE_REGEXP) {
2853 if (!u.expr.t2->get_Type() && !u.expr.t2->get_DerivedRef()) {
2854 Error_Context cntxt(u.expr.t2->get_Template(),
2855 "In the operand of operation `%s'",
2856 get_opname());
2857 u.expr.t2->get_Template()->set_lowerid_to_ref();
2858 }
2859 }
2860 if (u.expr.v_optype==OPTYPE_REPLACE) {
2861 if (!u.expr.ti4->get_Type() && !u.expr.ti4->get_DerivedRef()) {
2862 Error_Context cntxt(u.expr.ti4->get_Template(),
2863 "In the operand of operation `%s'",
2864 get_opname());
2865 u.expr.ti4->get_Template()->set_lowerid_to_ref();
2866 }
2867 }
2868 break;
2869 default:
2870 break;
2871 }
2872 break;
2873 default:
2874 break;
2875 }
2876 }
2877
2878 Type::typetype_t Value::get_expr_returntype(Type::expected_value_t exp_val)
2879 {
2880 switch (valuetype) {
2881 case V_CHARSYMS:
2882 case V_CHOICE:
2883 case V_SEQOF:
2884 case V_SETOF:
2885 case V_ARRAY:
2886 case V_SEQ:
2887 case V_SET:
2888 case V_UNDEF_LOWERID:
2889 case V_UNDEF_BLOCK:
2890 case V_OMIT:
2891 case V_TTCN3_NULL:
2892 case V_NOTUSED:
2893 case V_REFER:
2894 case V_FAT_NULL:
2895 return Type::T_UNDEF;
2896 case V_NAMEDINT:
2897 case V_NAMEDBITS:
2898 case V_OPENTYPE:
2899 FATAL_ERROR("Value::get_expr_returntype()");
2900 case V_ERROR:
2901 return Type::T_ERROR;
2902 case V_REFD:
2903 case V_INVOKE: {
2904 Type *t = get_expr_governor(exp_val);
2905 if (t) return t->get_type_refd_last()->get_typetype_ttcn3();
2906 else return Type::T_ERROR; }
2907 case V_FUNCTION:
2908 return Type::T_FUNCTION;
2909 case V_ALTSTEP:
2910 return Type::T_ALTSTEP;
2911 case V_TESTCASE:
2912 return Type::T_TESTCASE;
2913 case V_EXPR:
2914 switch(u.expr.v_optype) {
2915 case OPTYPE_COMP_NULL:
2916 case OPTYPE_COMP_MTC:
2917 case OPTYPE_COMP_SYSTEM:
2918 case OPTYPE_COMP_SELF:
2919 case OPTYPE_COMP_CREATE:
2920 return Type::T_COMPONENT;
2921 case OPTYPE_UNDEF_RUNNING:
2922 case OPTYPE_COMP_RUNNING:
2923 case OPTYPE_COMP_RUNNING_ANY:
2924 case OPTYPE_COMP_RUNNING_ALL:
2925 case OPTYPE_COMP_ALIVE:
2926 case OPTYPE_COMP_ALIVE_ANY:
2927 case OPTYPE_COMP_ALIVE_ALL:
2928 case OPTYPE_TMR_RUNNING:
2929 case OPTYPE_TMR_RUNNING_ANY:
2930 case OPTYPE_MATCH:
2931 case OPTYPE_EQ:
2932 case OPTYPE_LT:
2933 case OPTYPE_GT:
2934 case OPTYPE_NE:
2935 case OPTYPE_GE:
2936 case OPTYPE_LE:
2937 case OPTYPE_NOT:
2938 case OPTYPE_AND:
2939 case OPTYPE_OR:
2940 case OPTYPE_XOR:
2941 case OPTYPE_ISPRESENT:
2942 case OPTYPE_ISCHOSEN:
2943 case OPTYPE_ISCHOSEN_V:
2944 case OPTYPE_ISCHOSEN_T:
2945 case OPTYPE_ISVALUE:
2946 case OPTYPE_ISBOUND:
a38c6d4c 2947 case OPTYPE_PROF_RUNNING:
0a1610f4 2948 case OPTYPE_CHECKSTATE_ANY:
2949 case OPTYPE_CHECKSTATE_ALL:
970ed795
EL
2950 return Type::T_BOOL;
2951 case OPTYPE_GETVERDICT:
2952 return Type::T_VERDICT;
2953 case OPTYPE_VALUEOF: {
2954 Error_Context cntxt(this, "In the operand of operation `%s'",
2955 get_opname());
2956 return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
2957 case OPTYPE_TMR_READ:
2958 case OPTYPE_INT2FLOAT:
2959 case OPTYPE_STR2FLOAT:
2960 case OPTYPE_RND:
2961 case OPTYPE_RNDWITHVAL:
2962 return Type::T_REAL;
2963 case OPTYPE_ACTIVATE:
2964 return Type::T_DEFAULT;
2965 case OPTYPE_ACTIVATE_REFD:
2966 return Type::T_DEFAULT;
2967 case OPTYPE_EXECUTE:
2968 case OPTYPE_EXECUTE_REFD:
2969 return Type::T_VERDICT;
2970 case OPTYPE_UNARYPLUS: // v1
2971 case OPTYPE_UNARYMINUS: {
2972 Type::typetype_t tmp_tt;
2973 {
2974 Error_Context cntxt(this, "In the operand of operation `%s'",
2975 get_opname());
2976 u.expr.v1->set_lowerid_to_ref();
2977 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2978 }
2979 switch(tmp_tt) {
2980 case Type::T_INT:
2981 case Type::T_REAL:
2982 return tmp_tt;
2983 default:
2984 get_value_refd_last(); // to report the error
2985 return Type::T_ERROR;
2986 } // switch tmp_tt
2987 }
2988 case OPTYPE_ADD: // v1 v2
2989 case OPTYPE_SUBTRACT:
2990 case OPTYPE_MULTIPLY:
2991 case OPTYPE_DIVIDE: {
2992 Type::typetype_t tmp_tt;
2993 {
2994 Error_Context cntxt(this, "In the left operand of operation `%s'",
2995 get_opname());
2996 u.expr.v1->set_lowerid_to_ref();
2997 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
2998 }
2999 switch(tmp_tt) {
3000 case Type::T_INT:
3001 case Type::T_REAL:
3002 return tmp_tt;
3003 default:
3004 if(u.expr.v_optype==OPTYPE_ADD) {
3005 Type::typetype_t tmp_tt2;
3006 {
3007 Error_Context cntxt(this, "In the right operand of operation `%s'",
3008 get_opname());
3009 u.expr.v2->set_lowerid_to_ref();
3010 tmp_tt2=u.expr.v2->get_expr_returntype(exp_val);
3011 }
3012 Type::typetype_t ret_val=Type::T_ERROR;
3013 bool maybeconcat=false;
3014 switch(tmp_tt) {
3015 case Type::T_BSTR:
3016 case Type::T_HSTR:
3017 case Type::T_OSTR:
3018 if(tmp_tt2==tmp_tt) {
3019 maybeconcat=true;
3020 ret_val=tmp_tt;
3021 }
3022 break;
3023 case Type::T_CSTR:
3024 case Type::T_USTR:
3025 if(tmp_tt2==Type::T_CSTR || tmp_tt2==Type::T_USTR) {
3026 maybeconcat=true;
3027 if(tmp_tt==Type::T_USTR || tmp_tt2==Type::T_USTR)
3028 ret_val=Type::T_USTR;
3029 else ret_val=Type::T_CSTR;
3030 }
3031 break;
3032 default:
3033 break;
3034 }
3035 if(maybeconcat) {
3036 error("Did you mean the concat operation (`&') instead of"
3037 " addition operator (`+')?");
3038 u.expr.v_optype=OPTYPE_CONCAT;
3039 return ret_val;
3040 }
3041 }
3042 get_value_refd_last(); // to report the error
3043 return Type::T_ERROR;
3044 } // switch tmp_tt
3045 }
3046 case OPTYPE_NOT4B: // v1
3047 case OPTYPE_AND4B: // v1 v2
3048 case OPTYPE_OR4B:
3049 case OPTYPE_XOR4B:
3050 case OPTYPE_SHL:
3051 case OPTYPE_SHR: {
3052 Type::typetype_t tmp_tt;
3053 {
3054 Error_Context cntxt(this, "In the %soperand of operation `%s'",
3055 u.expr.v_optype==OPTYPE_NOT4B?"":"left ",
3056 get_opname());
3057 u.expr.v1->set_lowerid_to_ref();
3058 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3059 }
3060 switch(tmp_tt) {
3061 case Type::T_BSTR:
3062 case Type::T_HSTR:
3063 case Type::T_OSTR:
3064 return tmp_tt;
3065 default:
3066 get_value_refd_last(); // to report the error
3067 return Type::T_ERROR;
3068 } // switch tmp_tt
3069 }
3070 case OPTYPE_ROTL: // v1 v2
3071 case OPTYPE_ROTR: {
3072 Type::typetype_t tmp_tt;
3073 {
3074 Error_Context cntxt(this, "In the %s operand of operation `%s'",
3075 u.expr.v_optype==OPTYPE_ROTL
3076 || u.expr.v_optype==OPTYPE_ROTR?"left":"first",
3077 get_opname());
3078 u.expr.v1->set_lowerid_to_ref();
3079 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3080 }
3081 switch(tmp_tt) {
3082 case Type::T_BSTR:
3083 case Type::T_HSTR:
3084 case Type::T_OSTR:
3085 case Type::T_CSTR:
3086 case Type::T_USTR:
3087 case Type::T_SETOF:
3088 case Type::T_SEQOF:
3089 case Type::T_ARRAY:
3090 return tmp_tt;
3091 default:
3092 get_value_refd_last(); // to report the error
3093 return Type::T_ERROR;
3094 } // switch tmp_tt
3095 }
3096 case OPTYPE_SUBSTR:
3097 case OPTYPE_REPLACE: {
3098 Type::typetype_t tmp_tt;
3099 {
3100 Error_Context cntxt(this, "In the operand of operation `%s'",
3101 get_opname());
3102 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3103 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3104 }
3105 switch (tmp_tt) {
3106 case Type::T_BSTR:
3107 case Type::T_HSTR:
3108 case Type::T_OSTR:
3109 case Type::T_CSTR:
3110 case Type::T_USTR:
3111 case Type::T_SETOF:
3112 case Type::T_SEQOF:
3113 return tmp_tt;
3114 default:
3115 get_value_refd_last(); // to report the error
3116 return Type::T_ERROR;
3117 }
3118 }
3119 case OPTYPE_REGEXP: {
3120 Type::typetype_t tmp_tt;
3121 {
3122 Error_Context cntxt(this, "In the first operand of operation `%s'",
3123 get_opname());
3124 u.expr.ti1->get_Template()->set_lowerid_to_ref();
3125 tmp_tt = u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
3126 }
3127 switch(tmp_tt) {
3128 case Type::T_CSTR:
3129 case Type::T_USTR:
3130 return tmp_tt;
3131 default:
3132 get_value_refd_last(); // to report the error
3133 return Type::T_ERROR;
3134 } // switch tmp_tt
3135 }
3136 case OPTYPE_CONCAT: { // v1 v2
3137 Type::typetype_t tmp_tt;
3138 {
3139 Error_Context cntxt(this, "In the first operand of operation `%s'",
3140 get_opname());
3141 u.expr.v1->set_lowerid_to_ref();
3142 tmp_tt=u.expr.v1->get_expr_returntype(exp_val);
3143 }
3144 switch(tmp_tt) {
3145 case Type::T_CSTR:
3146 case Type::T_USTR:
3147 case Type::T_BSTR:
3148 case Type::T_HSTR:
3149 case Type::T_OSTR:
3150 case Type::T_SETOF:
3151 case Type::T_SEQOF:
3152 return tmp_tt;
3153 default:
3154 get_value_refd_last(); // to report the error
3155 return Type::T_ERROR;
3156 } // switch tmp_tt
3157 }
3158 case OPTYPE_MOD:
3159 case OPTYPE_REM:
3160 case OPTYPE_CHAR2INT:
3161 case OPTYPE_UNICHAR2INT:
3162 case OPTYPE_BIT2INT:
3163 case OPTYPE_HEX2INT:
3164 case OPTYPE_OCT2INT:
3165 case OPTYPE_STR2INT:
3166 case OPTYPE_FLOAT2INT:
3167 case OPTYPE_LENGTHOF:
3168 case OPTYPE_SIZEOF:
3169 case OPTYPE_DECODE:
3170 case OPTYPE_ENUM2INT:
1d0599f0 3171 case OPTYPE_DECVALUE_UNICHAR:
970ed795
EL
3172 return Type::T_INT;
3173 case OPTYPE_BIT2STR:
3174 case OPTYPE_FLOAT2STR:
3175 case OPTYPE_HEX2STR:
3176 case OPTYPE_INT2CHAR:
3177 case OPTYPE_INT2STR:
3178 case OPTYPE_OCT2CHAR:
3179 case OPTYPE_OCT2STR:
3180 case OPTYPE_UNICHAR2CHAR:
3181 case OPTYPE_LOG2STR:
3182 case OPTYPE_TESTCASENAME:
3183 case OPTYPE_TTCN2STRING:
3184 case OPTYPE_GET_STRINGENCODING:
3185 case OPTYPE_ENCODE_BASE64:
efbe586d 3186 case OPTYPE_HOSTID:
970ed795
EL
3187 return Type::T_CSTR;
3188 case OPTYPE_INT2UNICHAR:
3189 case OPTYPE_OCT2UNICHAR:
1d0599f0 3190 case OPTYPE_ENCVALUE_UNICHAR:
a50716c1 3191 case OPTYPE_ANY2UNISTR:
970ed795
EL
3192 return Type::T_USTR;
3193 case OPTYPE_INT2BIT:
3194 case OPTYPE_HEX2BIT:
3195 case OPTYPE_OCT2BIT:
3196 case OPTYPE_STR2BIT:
3197 case OPTYPE_ENCODE:
3198 return Type::T_BSTR;
3199 case OPTYPE_INT2HEX:
3200 case OPTYPE_BIT2HEX:
3201 case OPTYPE_OCT2HEX:
3202 case OPTYPE_STR2HEX:
3203 return Type::T_HSTR;
3204 case OPTYPE_INT2OCT:
3205 case OPTYPE_CHAR2OCT:
3206 case OPTYPE_HEX2OCT:
3207 case OPTYPE_BIT2OCT:
3208 case OPTYPE_STR2OCT:
3209 case OPTYPE_UNICHAR2OCT:
3210 case OPTYPE_REMOVE_BOM:
3211 case OPTYPE_DECODE_BASE64:
3212 return Type::T_OSTR;
3213 case OPTYPE_DECOMP:
3214 return Type::T_OID;
3215 default:
3216 FATAL_ERROR("Value::get_expr_returntype(): invalid optype");
3217 // to avoid warning
3218 return Type::T_ERROR;
3219 } // switch optype
3220 case V_MACRO:
3221 switch (u.macro) {
3222 case MACRO_MODULEID:
3223 case MACRO_FILENAME:
3224 case MACRO_BFILENAME:
3225 case MACRO_FILEPATH:
3226 case MACRO_LINENUMBER:
3227 case MACRO_DEFINITIONID:
3228 case MACRO_SCOPE:
3229 case MACRO_TESTCASEID:
3230 return Type::T_CSTR;
3231 case MACRO_LINENUMBER_C:
3232 return Type::T_INT;
3233 default:
3234 return Type::T_ERROR;
3235 }
3236 case V_NULL:
3237 return Type::T_NULL;
3238 case V_BOOL:
3239 return Type::T_BOOL;
3240 case V_INT:
3241 return Type::T_INT;
3242 case V_REAL:
3243 return Type::T_REAL;
3244 case V_ENUM:
3245 return Type::T_ENUM_T;
3246 case V_BSTR:
3247 return Type::T_BSTR;
3248 case V_HSTR:
3249 return Type::T_HSTR;
3250 case V_OSTR:
3251 return Type::T_OSTR;
3252 case V_CSTR:
3253 return Type::T_CSTR;
3254 case V_USTR:
3255 return Type::T_USTR;
3256 case V_ISO2022STR:
3257 return Type::T_GENERALSTRING;
3258 case V_OID:
3259 return Type::T_OID;
3260 case V_ROID:
3261 return Type::T_ROID;
3262 case V_VERDICT:
3263 return Type::T_VERDICT;
3264 case V_DEFAULT_NULL:
3265 return Type::T_DEFAULT;
3266 default:
3267 FATAL_ERROR("Value::get_expr_returntype(): invalid valuetype");
3268 // to avoid warning
3269 return Type::T_ERROR;
3270 } // switch
3271 }
3272
3273 Type* Value::get_expr_governor(Type::expected_value_t exp_val)
3274 {
3275 if(my_governor) return my_governor;
3276 switch (valuetype) {
3277 case V_INVOKE: {
3278 Type *t = u.invoke.v->get_expr_governor(exp_val);
3279 if(!t) {
3280 if(u.invoke.v->get_valuetype() != V_ERROR)
3281 u.invoke.v->error("A value of type function expected");
3282 goto error;
3283 }
3284 t = t->get_type_refd_last();
3285 switch(t->get_typetype()) {
3286 case Type::T_FUNCTION: {
3287 Type *t_return_type = t->get_function_return_type();
3288 if (!t_return_type) {
3289 error("Reference to a %s was expected instead of invocation "
3290 "of behavior type `%s' with no return type",
3291 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3292 t->get_fullname().c_str());
3293 goto error;
3294 }
3295 if (exp_val != Type::EXPECTED_TEMPLATE && t->get_returns_template()) {
3296 error("Reference to a value was expected, but functions of type "
3297 "`%s' return a template of type `%s'", t->get_typename().c_str(),
3298 t_return_type->get_typename().c_str());
3299 goto error;
3300 }
3301 return t_return_type; }
3302 case Type::T_ALTSTEP:
3303 goto error;
3304 default:
3305 u.invoke.v->error("A value of type function expected instead of `%s'",
3306 t->get_typename().c_str());
3307 goto error;
3308 }
3309 break; }
3310 case V_REFD: {
3311 Assignment *ass=u.ref.ref->get_refd_assignment();
3312 Type *tmp_type=0;
3313 if (!ass) goto error;
3314 switch (ass->get_asstype()) {
3315 case Assignment::A_CONST:
3316 case Assignment::A_EXT_CONST:
3317 case Assignment::A_MODULEPAR:
3318 case Assignment::A_MODULEPAR_TEMP:
3319 case Assignment::A_TEMPLATE:
3320 case Assignment::A_VAR:
3321 case Assignment::A_VAR_TEMPLATE:
3322 case Assignment::A_FUNCTION_RVAL:
3323 case Assignment::A_FUNCTION_RTEMP:
3324 case Assignment::A_EXT_FUNCTION_RVAL:
3325 case Assignment::A_EXT_FUNCTION_RTEMP:
3326 case Assignment::A_PAR_VAL_IN:
3327 case Assignment::A_PAR_VAL_OUT:
3328 case Assignment::A_PAR_VAL_INOUT:
3329 case Assignment::A_PAR_TEMPL_IN:
3330 case Assignment::A_PAR_TEMPL_OUT:
3331 case Assignment::A_PAR_TEMPL_INOUT:
3332 tmp_type=ass->get_Type();
3333 break;
3334 case Assignment::A_FUNCTION:
3335 case Assignment::A_EXT_FUNCTION:
3336 error("Reference to a %s was expected instead of a call of %s, which "
3337 "does not have return type",
3338 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3339 ass->get_description().c_str());
3340 goto error;
3341 default:
3342 error("Reference to a %s was expected instead of %s",
3343 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
3344 ass->get_description().c_str());
3345 goto error;
3346 } // end switch
3347 tmp_type=tmp_type->get_field_type(u.ref.ref->get_subrefs(), exp_val);
3348 if(!tmp_type) goto error;
3349 return tmp_type; }
3350 case V_EXPR:
3351 switch (u.expr.v_optype) {
3352 case OPTYPE_VALUEOF:
3353 case OPTYPE_SUBSTR:
3354 case OPTYPE_REGEXP:
3355 case OPTYPE_REPLACE:{
3356 Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
3357 Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
3358 if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
3359 return tmp_type;
3360 }
3361 case OPTYPE_ROTL:
3362 case OPTYPE_ROTR:
3363 return u.expr.v1->get_expr_governor(exp_val);
3364 case OPTYPE_CONCAT:
3365 return get_expr_governor_v1v2(exp_val);
3366 case OPTYPE_COMP_MTC:
af710487 3367 if (my_scope) return my_scope->get_mtc_system_comptype(false);
970ed795
EL
3368 else return 0;
3369 case OPTYPE_COMP_SYSTEM:
af710487 3370 if (my_scope) return my_scope->get_mtc_system_comptype(true);
970ed795
EL
3371 else return 0;
3372 case OPTYPE_COMP_SELF:
3373 if (my_scope) {
3374 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
3375 if (t_ros) return t_ros->get_component_type();
3376 else return 0;
3377 } else return 0;
3378 case OPTYPE_COMP_CREATE:
3379 return chk_expr_operand_comptyperef_create();
3380 default:
3381 break;
3382 }
3383 // no break
3384 default:
3385 return Type::get_pooltype(get_expr_returntype(exp_val));
3386 }
3387 error:
3388 set_valuetype(V_ERROR);
3389 return 0;
3390 }
3391
3392 Type* Value::get_expr_governor_v1v2(Type::expected_value_t exp_val)
3393 {
3394 Type* v1_gov = u.expr.v1->get_expr_governor(exp_val);
3395 Type* v2_gov = u.expr.v2->get_expr_governor(exp_val);
3396 if (v1_gov) {
3397 if (v2_gov) { // both have governors
3398 // return the type that is compatible with both (if there is no type mismatch)
3399 if (v1_gov->is_compatible(v2_gov, NULL))
3400 return v1_gov;
3401 else return v2_gov;
3402 } else return v1_gov;
3403 } else { // v1 has no governor
3404 if (v2_gov) return v2_gov;
3405 else return NULL; // neither has governor
3406 }
3407 }
3408
3409 Type *Value::get_expr_governor_last()
3410 {
3411 Value *v_last = get_value_refd_last();
3412 if (v_last->valuetype == V_ERROR) return 0;
3413 Type *t = v_last->get_expr_governor(Type::EXPECTED_TEMPLATE);
3414 if(!t) return 0;
3415 return t->get_type_refd_last();
3416 }
3417
3418 Type *Value::get_invoked_type(Type::expected_value_t exp_val)
3419 {
3420 if(valuetype != V_INVOKE) FATAL_ERROR("Value::get_invoked_type()");
3421 return u.invoke.v->get_expr_governor(exp_val);
3422 }
970ed795
EL
3423
3424 const char* Value::get_opname() const
3425 {
3426 if(valuetype!=V_EXPR) FATAL_ERROR("Value::get_opname()");
3427 switch(u.expr.v_optype) {
3428 case OPTYPE_RND: // -
3429 return "rnd()";
3430 case OPTYPE_COMP_NULL:
3431 return "(component) null";
3432 case OPTYPE_COMP_MTC:
3433 return "mtc";
3434 case OPTYPE_COMP_SYSTEM:
3435 return "system";
3436 case OPTYPE_COMP_SELF:
3437 return "self";
3438 case OPTYPE_COMP_RUNNING_ANY:
3439 return "any component.running";
3440 case OPTYPE_COMP_RUNNING_ALL:
3441 return "all component.running";
3442 case OPTYPE_COMP_ALIVE_ANY:
3443 return "any component.alive";
3444 case OPTYPE_COMP_ALIVE_ALL:
3445 return "all component.alive";
3446 case OPTYPE_TMR_RUNNING_ANY:
3447 return "any timer.running";
3448 case OPTYPE_GETVERDICT:
3449 return "getverdict()";
3450 case OPTYPE_TESTCASENAME:
3451 return "testcasename()";
0a1610f4 3452 case OPTYPE_CHECKSTATE_ANY:
3453 if (u.expr.r1) {
3454 return "port.checkstate()";
3455 } else {
3456 return "any port.checkstate()";
3457 }
3458 case OPTYPE_CHECKSTATE_ALL:
3459 if (u.expr.r1) {
3460 return "port.checkstate()";
3461 } else {
3462 return "all port.checkstate()";
3463 }
970ed795
EL
3464 case OPTYPE_UNARYPLUS: // v1
3465 return "unary +";
3466 case OPTYPE_UNARYMINUS:
3467 return "unary -";
3468 case OPTYPE_NOT:
3469 return "not";
3470 case OPTYPE_NOT4B:
3471 return "not4b";
3472 case OPTYPE_BIT2HEX:
3473 return "bit2hex()";
3474 case OPTYPE_BIT2INT:
3475 return "bit2int()";
3476 case OPTYPE_BIT2OCT:
3477 return "bit2oct()";
3478 case OPTYPE_BIT2STR:
3479 return "bit2str()";
3480 case OPTYPE_CHAR2INT:
3481 return "char2int()";
3482 case OPTYPE_CHAR2OCT:
3483 return "char2oct()";
3484 case OPTYPE_FLOAT2INT:
3485 return "float2int()";
3486 case OPTYPE_FLOAT2STR:
3487 return "float2str()";
3488 case OPTYPE_HEX2BIT:
3489 return "hex2bit()";
3490 case OPTYPE_HEX2INT:
3491 return "hex2int()";
3492 case OPTYPE_HEX2OCT:
3493 return "hex2oct()";
3494 case OPTYPE_HEX2STR:
3495 return "hex2str()";
3496 case OPTYPE_INT2CHAR:
3497 return "int2char()";
3498 case OPTYPE_INT2FLOAT:
3499 return "int2float()";
3500 case OPTYPE_INT2STR:
3501 return "int2str()";
3502 case OPTYPE_INT2UNICHAR:
3503 return "int2unichar()";
3504 case OPTYPE_OCT2BIT:
3505 return "oct2bit()";
3506 case OPTYPE_OCT2CHAR:
3507 return "oct2char()";
3508 case OPTYPE_OCT2HEX:
3509 return "oct2hex()";
3510 case OPTYPE_OCT2INT:
3511 return "oct2int()";
3512 case OPTYPE_OCT2STR:
3513 return "oct2str()";
3514 case OPTYPE_STR2BIT:
3515 return "str2bit()";
3516 case OPTYPE_STR2FLOAT:
3517 return "str2float()";
3518 case OPTYPE_STR2HEX:
3519 return "str2hex()";
3520 case OPTYPE_STR2INT:
3521 return "str2int()";
3522 case OPTYPE_STR2OCT:
3523 return "str2oct()";
3524 case OPTYPE_UNICHAR2INT:
3525 return "unichar2int()";
3526 case OPTYPE_UNICHAR2CHAR:
3527 return "unichar2char()";
3528 case OPTYPE_UNICHAR2OCT:
3529 return "unichar2oct()";
3530 case OPTYPE_ENUM2INT:
3531 return "enum2int()";
3532 case OPTYPE_LENGTHOF:
3533 return "lengthof()";
3534 case OPTYPE_SIZEOF:
3535 return "sizeof()";
3536 case OPTYPE_RNDWITHVAL:
3537 return "rnd (seed)";
3538 case OPTYPE_ENCODE:
3539 return "encvalue()";
3540 case OPTYPE_DECODE:
3541 return "decvalue()";
3542 case OPTYPE_GET_STRINGENCODING:
3543 return "get_stringencoding()";
3544 case OPTYPE_REMOVE_BOM:
3545 return "remove_bom()";
3546 case OPTYPE_ENCODE_BASE64:
3547 return "encode_base64()";
3548 case OPTYPE_DECODE_BASE64:
3549 return "decode_base64()";
efbe586d 3550 case OPTYPE_HOSTID: // [v1]
3551 return "hostid()";
970ed795
EL
3552 case OPTYPE_ADD: // v1 v2
3553 return "+";
3554 case OPTYPE_SUBTRACT:
3555 return "-";
3556 case OPTYPE_MULTIPLY:
3557 return "*";
3558 case OPTYPE_DIVIDE:
3559 return "/";
3560 case OPTYPE_MOD:
3561 return "mod";
3562 case OPTYPE_REM:
3563 return "rem";
3564 case OPTYPE_CONCAT:
3565 return "&";
3566 case OPTYPE_EQ:
3567 return "==";
3568 case OPTYPE_LT:
3569 return "<";
3570 case OPTYPE_GT:
3571 return ">";
3572 case OPTYPE_NE:
3573 return "!=";
3574 case OPTYPE_GE:
3575 return ">=";
3576 case OPTYPE_LE:
3577 return "<=";
3578 case OPTYPE_AND:
3579 return "and";
3580 case OPTYPE_OR:
3581 return "or";
3582 case OPTYPE_XOR:
3583 return "xor";
3584 case OPTYPE_AND4B:
3585 return "and4b";
3586 case OPTYPE_OR4B:
3587 return "or4b";
3588 case OPTYPE_XOR4B:
3589 return "xor4b";
3590 case OPTYPE_SHL:
3591 return "<<";
3592 case OPTYPE_SHR:
3593 return ">>";
3594 case OPTYPE_ROTL:
3595 return "<@";
3596 case OPTYPE_ROTR:
3597 return "@>";
3598 case OPTYPE_INT2BIT:
3599 return "int2bit()";
3600 case OPTYPE_INT2HEX:
3601 return "int2hex()";
3602 case OPTYPE_INT2OCT:
3603 return "int2oct()";
3604 case OPTYPE_OCT2UNICHAR:
3605 return "oct2unichar()";
1d0599f0 3606 case OPTYPE_ENCVALUE_UNICHAR:
3607 return "encvalue_unichar()";
3608 case OPTYPE_DECVALUE_UNICHAR:
3609 return "decvalue_unichar()";
970ed795
EL
3610 case OPTYPE_SUBSTR:
3611 return "substr()";
3612 case OPTYPE_REGEXP:
3613 return "regexp()";
3614 case OPTYPE_DECOMP:
3615 return "decomp()";
3616 case OPTYPE_REPLACE:
3617 return "replace()";
3618 case OPTYPE_VALUEOF: // t1
3619 return "valueof()";
3620 case OPTYPE_UNDEF_RUNNING:
3621 return "<timer or component> running";
3622 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
3623 return "create()";
3624 case OPTYPE_COMP_RUNNING: // v1
3625 return "component running";
3626 case OPTYPE_COMP_ALIVE: // v1
3627 return "alive";
3628 case OPTYPE_TMR_READ:
3629 return "timer read";
3630 case OPTYPE_TMR_RUNNING:
3631 return "timer running";
3632 case OPTYPE_ACTIVATE:
3633 return "activate()";
3634 case OPTYPE_ACTIVATE_REFD:
3635 return "activate()";
3636 case OPTYPE_EXECUTE: // r1 [v2]
3637 case OPTYPE_EXECUTE_REFD:
3638 return "execute()";
3639 case OPTYPE_MATCH: // v1 t2
3640 return "match()";
3641 case OPTYPE_ISPRESENT:
3642 return "ispresent()";
3643 case OPTYPE_ISCHOSEN:
3644 case OPTYPE_ISCHOSEN_V:
3645 case OPTYPE_ISCHOSEN_T:
3646 return "ischosen()";
3647 case OPTYPE_ISVALUE:
3648 return "isvalue()";
3649 case OPTYPE_ISBOUND:
3650 return "isbound()";
3651 case OPTYPE_LOG2STR:
3652 return "log2str()";
a50716c1 3653 case OPTYPE_ANY2UNISTR:
3654 return "any2unistr()";
970ed795
EL
3655 case OPTYPE_TTCN2STRING:
3656 return "ttcn2string()";
a38c6d4c 3657 case OPTYPE_PROF_RUNNING:
3658 return "@profiler.running";
970ed795
EL
3659 default:
3660 FATAL_ERROR("Value::get_opname()");
3661 } // switch
3662 }
3663
3664 void Value::chk_expr_ref_ischosen()
3665 {
3666 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
3667 Ttcn::Ref_base *tmpref=u.expr.r1;
3668 Assignment *ass=tmpref->get_refd_assignment();
3669 if (!ass) {
3670 set_valuetype(V_ERROR);
3671 return;
3672 }
3673 // Now we know whether the argument of ischosen() is a value or template.
3674 // Wrap u.expr.r1 of OPTYPE_ISCHOSEN in a value (OPTYPE_ISCHOSEN_V)
3675 // or template (OPTYPE_ISCHOSEN_T).
3676 switch (ass->get_asstype()) {
3677 case Assignment::A_CONST:
3678 case Assignment::A_EXT_CONST:
3679 case Assignment::A_MODULEPAR:
3680 case Assignment::A_VAR:
3681 case Assignment::A_PAR_VAL_IN:
3682 case Assignment::A_PAR_VAL_OUT:
3683 case Assignment::A_PAR_VAL_INOUT:
3684 u.expr.v1=new Value(V_REFD, tmpref);
3685 u.expr.v1->set_location(*tmpref);
3686 u.expr.v1->set_my_scope(get_my_scope());
3687 u.expr.v1->set_fullname(get_fullname()+".<operand>");
3688 u.expr.v_optype=OPTYPE_ISCHOSEN_V;
3689 break;
3690 case Assignment::A_MODULEPAR_TEMP:
3691 case Assignment::A_TEMPLATE:
3692 case Assignment::A_VAR_TEMPLATE:
3693 case Assignment::A_PAR_TEMPL_IN:
3694 case Assignment::A_PAR_TEMPL_OUT:
3695 case Assignment::A_PAR_TEMPL_INOUT:
3696 u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
3697 u.expr.t1->set_location(*tmpref);
3698 u.expr.t1->set_my_scope(get_my_scope());
3699 u.expr.t1->set_fullname(get_fullname()+".<operand>");
3700 u.expr.v_optype=OPTYPE_ISCHOSEN_T;
3701 break;
3702 default:
3703 tmpref->error("Reference to a value or template was expected instead of "
3704 "%s", ass->get_description().c_str());
3705 set_valuetype(V_ERROR);
3706 break;
3707 } // switch
3708 }
3709
3710 void Value::chk_expr_operandtype_enum(const char *opname, Value *v,
3711 Type::expected_value_t exp_val)
3712 {
3713 v->set_lowerid_to_ref(); // can only be reference to enum
3714 Type *t = v->get_expr_governor(exp_val);
3715 if (v->valuetype==V_ERROR) return;
3716 if (!t) {
3717 v->error("Please use reference to an enumerated value as the operand of "
3718 "operation `%s'", get_opname());
3719 set_valuetype(V_ERROR);
3720 return;
3721 }
3722 t = t->get_type_refd_last();
3723 if (t->get_typetype()!=Type::T_ENUM_A && t->get_typetype()!=Type::T_ENUM_T) {
3724 v->error("The operand of operation `%s' should be enumerated value", opname);
3725 set_valuetype(V_ERROR);
3726 }
3727 if (v->get_value_refd_last()->valuetype==V_OMIT) {
3728 v->error("The operand of operation `%s' cannot be omit", opname);
3729 set_valuetype(V_ERROR);
3730 }
3731 }
3732
3733 void Value::chk_expr_operandtype_bool(Type::typetype_t tt,
3734 const char *opnum,
3735 const char *opname,
3736 const Location *loc)
3737 {
3738 if(tt==Type::T_BOOL) return;
3739 if(tt!=Type::T_ERROR)
3740 loc->error("%s operand of operation `%s' should be boolean value",
3741 opnum, opname);
3742 set_valuetype(V_ERROR);
3743 }
3744
3745 void Value::chk_expr_operandtype_int(Type::typetype_t tt,
3746 const char *opnum,
3747 const char *opname,
3748 const Location *loc)
3749 {
3750 if(tt==Type::T_INT) return;
3751 if(tt!=Type::T_ERROR)
3752 loc->error("%s operand of operation `%s' should be integer value",
3753 opnum, opname);
3754 set_valuetype(V_ERROR);
3755 }
3756
3757 void Value::chk_expr_operandtype_float(Type::typetype_t tt,
3758 const char *opnum,
3759 const char *opname,
3760 const Location *loc)
3761 {
3762 if(tt==Type::T_REAL) return;
3763 else if(tt==Type::T_INT)
3764 loc->error("%s operand of operation `%s' should be float value."
3765 " Perhaps you missed an int2float() conversion function"
3766 " or `.0' at the end of the number",
3767 opnum, opname);
3768 else if(tt!=Type::T_ERROR)
3769 loc->error("%s operand of operation `%s' should be float value",
3770 opnum, opname);
3771 set_valuetype(V_ERROR);
3772 }
3773
3774 void Value::chk_expr_operandtype_int_float(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 return;
3783 default:
3784 break;
3785 }
3786 if(tt!=Type::T_ERROR)
3787 loc->error("%s operand of operation `%s' should be integer"
3788 " or float value",
3789 opnum, opname);
3790 set_valuetype(V_ERROR);
3791 }
3792
3793 void Value::chk_expr_operandtype_int_float_enum(Type::typetype_t tt,
3794 const char *opnum,
3795 const char *opname,
3796 const Location *loc)
3797 {
3798 switch(tt) {
3799 case Type::T_INT:
3800 case Type::T_REAL:
3801 case Type::T_ENUM_T:
3802 return;
3803 default:
3804 break;
3805 }
3806 if(tt!=Type::T_ERROR)
3807 loc->error("%s operand of operation `%s' should be integer, float"
3808 " or enumerated value", opnum, opname);
3809 set_valuetype(V_ERROR);
3810 }
3811
3812 void Value::chk_expr_operandtype_list(Type* t,
3813 const char *opnum,
3814 const char *opname,
3815 const Location *loc,
3816 bool allow_array)
3817 {
3818 if (valuetype == V_ERROR) return;
3819 if (t->get_typetype() == Type::T_ERROR) {
3820 set_valuetype(V_ERROR);
3821 return;
3822 }
3823 if (!t->is_list_type(allow_array)) {
3824 loc->error("%s operand of operation `%s' should be a string, "
3825 "`record of'%s `set of'%s value", opnum, opname,
3826 allow_array ? "," : " or", allow_array ? " or array" : "");
3827 set_valuetype(V_ERROR);
3828 return;
3829 }
3830 TypeCompatInfo info(my_scope->get_scope_mod(), my_governor, t, true,
3831 u.expr.v_optype == OPTYPE_LENGTHOF); // The only outsider.
3832 TypeChain l_chain;
3833 TypeChain r_chain;
3834 if (my_governor && my_governor->is_list_type(allow_array)
3835 && !my_governor->is_compatible(t, &info, &l_chain, &r_chain)) {
3836 if (info.is_subtype_error()) {
3837 // this is ok.
3838 if (info.needs_conversion()) set_needs_conversion();
3839 } else
3840 if (!info.is_erroneous()) {
3841 error("%s operand of operation `%s' is of type `%s', but a value of "
3842 "type `%s' was expected here", opnum, opname,
3843 t->get_typename().c_str(), my_governor->get_typename().c_str());
3844 } else {
3845 error("%s", info.get_error_str_str().c_str());
3846 }
3847 } else {
3848 if (info.needs_conversion())
3849 set_needs_conversion();
3850 }
3851 }
3852
3853 void Value::chk_expr_operandtype_str(Type::typetype_t tt,
3854 const char *opnum,
3855 const char *opname,
3856 const Location *loc)
3857 {
3858 switch(tt) {
3859 case Type::T_CSTR:
3860 case Type::T_USTR:
3861 case Type::T_BSTR:
3862 case Type::T_HSTR:
3863 case Type::T_OSTR:
3864 return;
3865 default:
3866 break;
3867 }
3868 if(tt!=Type::T_ERROR)
3869 loc->error("%s operand of operation `%s' should be string value",
3870 opnum, opname);
3871 set_valuetype(V_ERROR);
3872 }
3873
3874 void Value::chk_expr_operandtype_charstr(Type::typetype_t tt,
3875 const char *opnum,
3876 const char *opname,
3877 const Location *loc)
3878 {
3879 switch(tt) {
3880 case Type::T_CSTR:
3881 case Type::T_USTR:
3882 return;
3883 default:
3884 break;
3885 }
3886 if(tt!=Type::T_ERROR)
3887 loc->error("%s operand of operation `%s' should be (universal)"
3888 " charstring value",
3889 opnum, opname);
3890 set_valuetype(V_ERROR);
3891 }
3892
3893 void Value::chk_expr_operandtype_cstr(Type::typetype_t tt,
3894 const char *opnum,
3895 const char *opname,
3896 const Location *loc)
3897 {
3898 if(tt==Type::T_CSTR) return;
3899 if(tt!=Type::T_ERROR)
3900 loc->error("%s operand of operation `%s' should be charstring value",
3901 opnum, opname);
3902 set_valuetype(V_ERROR);
3903 }
3904
3905 void Value::chk_expr_operandtype_binstr(Type::typetype_t tt,
3906 const char *opnum,
3907 const char *opname,
3908 const Location *loc)
3909 {
3910 switch(tt) {
3911 case Type::T_BSTR:
3912 case Type::T_HSTR:
3913 case Type::T_OSTR:
3914 return;
3915 default:
3916 break;
3917 }
3918 if(tt!=Type::T_ERROR)
3919 loc->error("%s operand of operation `%s' should be binary string value",
3920 opnum, opname);
3921 set_valuetype(V_ERROR);
3922 }
3923
3924 void Value::chk_expr_operandtype_bstr(Type::typetype_t tt,
3925 const char *opnum,
3926 const char *opname,
3927 const Location *loc)
3928 {
3929 if(tt==Type::T_BSTR) return;
3930 if(tt!=Type::T_ERROR)
3931 loc->error("%s operand of operation `%s' should be bitstring value",
3932 opnum, opname);
3933 set_valuetype(V_ERROR);
3934 }
3935
3936 void Value::chk_expr_operandtype_hstr(Type::typetype_t tt,
3937 const char *opnum,
3938 const char *opname,
3939 const Location *loc)
3940 {
3941 if(tt==Type::T_HSTR) return;
3942 if(tt!=Type::T_ERROR)
3943 loc->error("%s operand of operation `%s' should be hexstring value",
3944 opnum, opname);
3945 set_valuetype(V_ERROR);
3946 }
3947
3948 void Value::chk_expr_operandtype_ostr(Type::typetype_t tt,
3949 const char *opnum,
3950 const char *opname,
3951 const Location *loc)
3952 {
3953 if(tt==Type::T_OSTR) return;
3954 if(tt!=Type::T_ERROR)
3955 loc->error("%s operand of operation `%s' should be octetstring value",
3956 opnum, opname);
3957 set_valuetype(V_ERROR);
3958 }
3959
3960 void Value::chk_expr_operandtypes_same(Type::typetype_t tt1,
3961 Type::typetype_t tt2,
3962 const char *opname)
3963 {
3964 if(valuetype==V_ERROR) return;
3965 // if(u.expr.state==EXPR_CHECKING_ERR) return;
3966 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3967 set_valuetype(V_ERROR);
3968 return;
3969 }
3970 if(tt1==tt2) return;
3971 error("The operands of operation `%s' should be of same type", opname);
3972 set_valuetype(V_ERROR);
3973 }
3974
3975 /* For predefined functions. */
3976 void Value::chk_expr_operandtypes_same_with_opnum(Type::typetype_t tt1,
3977 Type::typetype_t tt2,
3978 const char *opnum1,
3979 const char *opnum2,
3980 const char *opname)
3981 {
3982 if(valuetype==V_ERROR) return;
3983 if(tt1==Type::T_ERROR || tt2==Type::T_ERROR) {
3984 set_valuetype(V_ERROR);
3985 return;
3986 }
3987 if(tt1==tt2) return;
3988 error("The %s and %s operands of operation `%s' should be of same type",
3989 opnum1, opnum2, opname);
3990 set_valuetype(V_ERROR);
3991 }
3992
3993 void Value::chk_expr_operandtypes_compat(Type::expected_value_t exp_val,
3994 Value *v1, Value *v2,
3995 const char *opnum1,
3996 const char *opnum2)
3997 {
3998 start:
3999 if (valuetype == V_ERROR) return;
4000 // if (u.expr.state == EXPR_CHECKING_ERR) return;
4001 Type::typetype_t tt1 = v1->get_expr_returntype(exp_val);
4002 Type::typetype_t tt2 = v2->get_expr_returntype(exp_val);
4003
4004 if (tt1 == Type::T_ERROR || tt2 == Type::T_ERROR) {
4005 set_valuetype(V_ERROR);
4006 return;
4007 }
4008 if (tt1 == Type::T_UNDEF) {
4009 if (tt2 == Type::T_UNDEF) {
4010 if (v1->is_undef_lowerid()) {
4011 if (v2->is_undef_lowerid()) {
4012 Scope *scope = get_my_scope();
4013 Module *my_mod = scope->get_scope_mod();
4014 const Identifier& id1 = v1->get_undef_lowerid();
4015 if (scope->has_ass_withId(id1)
4016 || my_mod->has_imported_ass_withId(id1)) {
4017 /* It can be ref-ref, ref-enum or enum-ref. Perhaps we
4018 * should examine this situation better, but now I suppose
4019 * the first is ref, not enum. */
4020 v1->set_lowerid_to_ref();
4021 goto start;
4022 } else {
4023 const Identifier& id2 = v2->get_undef_lowerid();
4024 if (scope->has_ass_withId(id2)
4025 || my_mod->has_imported_ass_withId(id2)) {
4026 v2->set_lowerid_to_ref();
4027 goto start;
4028 }
4029 }
4030 /* This is perhaps enum-enum, but it has no real
4031 * significance, so this should be an error. */
4032 } else {
4033 v1->set_lowerid_to_ref();
4034 goto start;
4035 }
4036 } else if (v2->is_undef_lowerid()) {
4037 v2->set_lowerid_to_ref();
4038 goto start;
4039 }
4040 error("Cannot determine the type of the operands in operation `%s'",
4041 get_opname());
4042 set_valuetype(V_ERROR);
4043 return;
4044 } else if (v1->is_undef_lowerid() && tt2 != Type::T_ENUM_T) {
4045 v1->set_lowerid_to_ref();
4046 goto start;
4047 } else {
4048 /* v1 is something undefined, but not lowerid; v2 has
4049 * returntype (perhaps also governor) */
4050 }
4051 } else if (tt2 == Type::T_UNDEF) {
4052 /* but tt1 is not undef */
4053 if (v2->is_undef_lowerid() && tt1 != Type::T_ENUM_T) {
4054 v2->set_lowerid_to_ref();
4055 goto start;
4056 } else {
4057 /* v2 is something undefined, but not lowerid; v1 has
4058 * returntype (perhaps also governor) */
4059 }
4060 }
4061
4062 /* Now undef_lower_id's are converted to references, or the other
4063 * value has governor; let's see the governors, if they exist. */
4064 Type *t1 = v1->get_expr_governor(exp_val);
4065 Type *t2 = v2->get_expr_governor(exp_val);
4066 if (t1) {
4067 if (t2) {
4068 // Both value has governor. Are they compatible? According to 7.1.2
4069 // and C.34 it's required to have the same root types for
4070 // OPTYPE_{CONCAT,REPLACE}.
4071 TypeCompatInfo info1(my_scope->get_scope_mod(), t1, t2, true,
4072 u.expr.v_optype == OPTYPE_REPLACE);
4073 TypeCompatInfo info2(my_scope->get_scope_mod(), t2, t1, true,
4074 u.expr.v_optype == OPTYPE_REPLACE);
4075 TypeChain l_chain1, l_chain2;
4076 TypeChain r_chain1, r_chain2;
4077 bool compat_t1 = t1->is_compatible(t2, &info1, &l_chain1, &r_chain1);
4078 bool compat_t2 = t2->is_compatible(t1, &info2, &l_chain2, &r_chain2);
4079 if (!compat_t1 && !compat_t2) {
4080 if (!info1.is_erroneous() && !info2.is_erroneous()) {
4081 // the subtypes don't need to be compatible here
4082 if (!info1.is_subtype_error() && !info2.is_subtype_error()) {
4083 error("The operands of operation `%s' should be of compatible "
4084 "types", get_opname());
4085 set_valuetype(V_ERROR);
4086 } else {
4087 if (info1.needs_conversion() || info2.needs_conversion()) {
4088 set_needs_conversion(); // Avoid folding.
4089 return;
4090 }
4091 }
4092 } else {
4093 if (info1.is_erroneous())
4094 v1->error("%s", info1.get_error_str_str().c_str());
4095 else if (info2.is_erroneous())
4096 v2->error("%s", info2.get_error_str_str().c_str());
4097 set_valuetype(V_ERROR);
4098 }
4099 return;
4100 } else if (info1.needs_conversion() || info2.needs_conversion()) {
4101 set_needs_conversion(); // Avoid folding.
4102 return;
4103 }
4104 } else {
4105 // t1, no t2.
4106 v2->set_my_governor(t1);
4107 t1->chk_this_value_ref(v2);
4108 if (v2->valuetype == V_OMIT) {
4109 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4110 get_opname());
4111 v1->chk_expr_omit_comparison(exp_val);
4112 } else {
4113 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4114 get_opname());
4115 (void)t1->chk_this_value(v2, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4116 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4117 goto start;
4118 }
4119 }
4120 } else if (t2) {
4121 v1->set_my_governor(t2);
4122 t2->chk_this_value_ref(v1);
4123 if (v1->valuetype == V_OMIT) {
4124 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum2,
4125 get_opname());
4126 v2->chk_expr_omit_comparison(exp_val);
4127 } else {
4128 Error_Context cntxt(this, "In %s operand of operation `%s'", opnum1,
4129 get_opname());
4130 (void)t2->chk_this_value(v1, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
4131 OMIT_NOT_ALLOWED, NO_SUB_CHK);
4132 goto start;
4133 }
4134 } else {
4135 // Neither v1 nor v2 has a governor. Let's see the returntypes.
4136 if (tt1 == Type::T_UNDEF || tt2 == Type::T_UNDEF) {
4137 // Here, it cannot be that both are T_UNDEF.
4138 // TODO: What if "a" == char(0, 0, 0, 65) or self == null etc.
4139 error("Please use reference as %s operand of operator `%s'",
4140 tt1 == Type::T_UNDEF ? opnum1 : opnum2, get_opname());
4141 set_valuetype(V_ERROR);
4142 return;
4143 }
4144 // Deny type compatibility if no governors found. The typetype_t must
4145 // be the same. TODO: How can this happen?
4146 if (!Type::is_compatible_tt_tt(tt1, tt2, false, false)
4147 && !Type::is_compatible_tt_tt(tt2, tt1, false, false)) {
4148 error("The operands of operation `%s' should be of compatible types",
4149 get_opname());
4150 set_valuetype(V_ERROR);
4151 }
4152 }
4153 }
4154
4155 void Value::chk_expr_operand_undef_running(Type::expected_value_t exp_val,
4156 Ttcn::Ref_base *ref, const char *opnum, const char *opname)
4157 {
4158 if(valuetype==V_ERROR) return;
4159 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4160 Assignment *t_ass = ref->get_refd_assignment();
4161 if(!t_ass) goto error;
4162 switch(t_ass->get_asstype()) {
4163 case Assignment::A_TIMER:
4164 case Assignment::A_PAR_TIMER:
4165 u.expr.v_optype=OPTYPE_TMR_RUNNING;
4166 chk_expr_operand_tmrref(u.expr.r1, opnum, get_opname());
4167 chk_expr_dynamic_part(exp_val, true);
4168 break;
4169 case Assignment::A_CONST:
4170 case Assignment::A_EXT_CONST:
4171 case Assignment::A_MODULEPAR:
4172 case Assignment::A_VAR:
4173 case Assignment::A_FUNCTION_RVAL:
4174 case Assignment::A_EXT_FUNCTION_RVAL:
4175 case Assignment::A_PAR_VAL_IN:
4176 case Assignment::A_PAR_VAL_OUT:
4177 case Assignment::A_PAR_VAL_INOUT: {
4178 u.expr.v_optype = OPTYPE_COMP_RUNNING;
4179 Value* val = new Value(V_REFD, u.expr.r1);
4180 val->set_my_scope(my_scope);
4181 val->set_fullname(u.expr.r1->get_fullname());
4182 val->set_location(*u.expr.r1);
4183 u.expr.v1 = val;
4184 chk_expr_operand_compref(val, opnum, get_opname());
4185 chk_expr_dynamic_part(exp_val, false);
4186 break; }
4187 default:
4188 ref->error("%s operand of operation `%s' should be timer or"
4189 " component reference instead of %s",
4190 opnum, opname, t_ass->get_description().c_str());
4191 goto error;
4192 } // switch
4193 return;
4194 error:
4195 set_valuetype(V_ERROR);
4196 }
4197
4198 Type *Value::chk_expr_operand_comptyperef_create()
4199 {
4200 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_COMP_CREATE)
4201 FATAL_ERROR("Value::chk_expr_operand_comptyperef_create()");
4202 Assignment *t_ass = u.expr.r1->get_refd_assignment();
4203 if (!t_ass) goto error;
4204 if (t_ass->get_asstype() == Assignment::A_TYPE) {
4205 Type *t_type = t_ass->get_Type()->get_field_type(u.expr.r1->get_subrefs(),
4206 Type::EXPECTED_DYNAMIC_VALUE);
4207 if (!t_type) goto error;
4208 t_type = t_type->get_type_refd_last();
4209 if (t_type->get_typetype() == Type::T_COMPONENT) {
4210 if (my_governor) {
4211 Type *my_governor_last = my_governor->get_type_refd_last();
4212 if (my_governor_last->get_typetype() == Type::T_COMPONENT &&
4213 !my_governor_last->is_compatible(t_type, NULL)) {
4214 u.expr.r1->error("Incompatible component types: operation "
4215 "`create' should refer to `%s' instead of "
4216 "`%s'",
4217 my_governor_last->get_typename().c_str(),
4218 t_type->get_typename().c_str());
4219 goto error;
4220 }
4221 }
4222 return t_type;
4223 } else {
4224 u.expr.r1->error("Type mismatch: reference to a component type was "
4225 "expected in operation `create' instead of `%s'",
4226 t_type->get_typename().c_str());
4227 }
4228 } else {
4229 u.expr.r1->error("Operation `create' should refer to a component type "
4230 "instead of %s", t_ass->get_description().c_str());
4231 }
4232 error:
4233 set_valuetype(V_ERROR);
4234 return NULL;
4235 }
4236
4237 void Value::chk_expr_comptype_compat()
4238 {
4239 if (valuetype != V_EXPR)
4240 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4241 if (!my_governor || !my_scope) return;
4242 Type *my_governor_last = my_governor->get_type_refd_last();
4243 if (my_governor_last->get_typetype() != Type::T_COMPONENT) return;
4244 Type *t_comptype;
4245 switch (u.expr.v_optype) {
4246 case OPTYPE_COMP_MTC:
af710487 4247 t_comptype = my_scope->get_mtc_system_comptype(false);
970ed795
EL
4248 break;
4249 case OPTYPE_COMP_SYSTEM:
af710487 4250 t_comptype = my_scope->get_mtc_system_comptype(true);
970ed795
EL
4251 break;
4252 case OPTYPE_COMP_SELF: {
4253 Ttcn::RunsOnScope *t_ros = my_scope->get_scope_runs_on();
4254 t_comptype = t_ros ? t_ros->get_component_type() : 0;
4255 break; }
4256 default:
4257 FATAL_ERROR("Value::chk_expr_comptype_compat()");
4258 t_comptype = 0;
4259 break;
4260 }
4261 if (t_comptype
4262 && !my_governor_last->is_compatible(t_comptype, NULL)) {
4263 error("Incompatible component types: a component reference of "
4264 "type `%s' was expected, but `%s' has type `%s'",
4265 my_governor_last->get_typename().c_str(), get_opname(),
4266 t_comptype->get_typename().c_str());
4267 set_valuetype(V_ERROR);
4268 }
4269 }
4270
4271 void Value::chk_expr_operand_compref(Value *val, const char *opnum,
4272 const char *opname)
4273 {
4274 if(valuetype == V_ERROR) return;
4275 switch(val->get_valuetype()) {
4276 case V_INVOKE: {
4277 Error_Context cntxt(this, "In `%s' operation", opname);
4278 Value *v_last = val->get_value_refd_last();
4279 if(!v_last) goto error;
4280 Type *t = v_last->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
4281 if(!t) goto error;
4282 t = t->get_type_refd_last();
4283 if(t->get_typetype() != Type::T_COMPONENT) {
4284 v_last->error("%s operand of operation `%s': Type mismatch:"
4285 " component reference was expected instead of `%s'",
4286 opnum, opname, t->get_typename().c_str());
4287 goto error;
4288 }
4289 return; }
4290 case V_REFD: {
4291 Reference *ref = val->get_reference();
4292 Assignment *t_ass = ref->get_refd_assignment();
4293 Value *t_val = 0;
4294 if (!t_ass) goto error;
4295 switch(t_ass->get_asstype()) {
4296 case Assignment::A_CONST:
4297 t_val = t_ass->get_Value();
4298 // no break
4299 case Assignment::A_EXT_CONST:
4300 case Assignment::A_MODULEPAR:
4301 case Assignment::A_VAR:
4302 case Assignment::A_FUNCTION_RVAL:
4303 case Assignment::A_EXT_FUNCTION_RVAL:
4304 case Assignment::A_PAR_VAL_IN:
4305 case Assignment::A_PAR_VAL_OUT:
4306 case Assignment::A_PAR_VAL_INOUT: {
4307 Type *t_type=t_ass->get_Type()
4308 ->get_field_type(ref->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE);
4309 if(!t_type) goto error;
4310 t_type=t_type->get_type_refd_last();
4311 if(t_type->get_typetype()!=Type::T_COMPONENT) {
4312 ref->error("%s operand of operation `%s': Type mismatch:"
4313 " component reference was expected instead of `%s'",
4314 opnum, opname, t_type->get_typename().c_str());
4315 goto error;
4316 }
4317 break;}
4318 default:
4319 ref->error("%s operand of operation `%s' should be"
4320 " component reference instead of %s",
4321 opnum, opname, t_ass->get_description().c_str());
4322 goto error;
4323 }
4324 if (t_val) {
4325 ReferenceChain refch(this, "While searching referenced value");
4326 t_val = t_val->get_refd_sub_value(ref->get_subrefs(), 0, false, &refch);
4327 if (!t_val) return;
4328 t_val = t_val->get_value_refd_last();
4329 if (t_val->valuetype != V_EXPR) return;
4330 switch (t_val->u.expr.v_optype) {
4331 case OPTYPE_COMP_NULL:
4332 ref->error("%s operand of operation `%s' refers to `null' component "
4333 "reference", opnum, opname);
4334 goto error;
4335 case OPTYPE_COMP_MTC:
4336 ref->error("%s operand of operation `%s' refers to the component "
4337 "reference of the `mtc'", opnum, opname);
4338 goto error;
4339 case OPTYPE_COMP_SYSTEM:
4340 ref->error("%s operand of operation `%s' refers to the component "
4341 "reference of the `system'", opnum, opname);
4342 goto error;
4343 default:
4344 break;
4345 }
4346 }
4347 return;}
4348 default:
4349 FATAL_ERROR("Value::chk_expr_operand_compref()");
4350 }
4351 error:
4352 set_valuetype(V_ERROR);
4353 }
4354
4355 void Value::chk_expr_operand_tmrref(Ttcn::Ref_base *ref,
4356 const char *opnum,
4357 const char *opname)
4358 {
4359 if(valuetype==V_ERROR) return;
4360 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4361 Assignment *t_ass = ref->get_refd_assignment();
4362 if(!t_ass) goto error;
4363 switch(t_ass->get_asstype()) {
4364 case Assignment::A_TIMER: {
4365 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
4366 if (t_dims) t_dims->chk_indices(ref, "timer", false,
4367 Type::EXPECTED_DYNAMIC_VALUE);
4368 else if (ref->get_subrefs()) {
4369 ref->error("%s operand of operation `%s': "
4370 "Reference to single timer `%s' cannot have field or array "
4371 "sub-references", opnum, opname,
4372 t_ass->get_id().get_dispname().c_str());
4373 goto error;
4374 }
4375 break; }
4376 case Assignment::A_PAR_TIMER:
4377 if (ref->get_subrefs()) {
4378 ref->error("%s operand of operation `%s': "
4379 "Reference to %s cannot have field or array sub-references",
4380 opnum, opname, t_ass->get_description().c_str());
4381 goto error;
4382 }
4383 break;
4384 default:
4385 ref->error("%s operand of operation `%s' should be timer"
4386 " instead of %s",
4387 opnum, opname, t_ass->get_description().c_str());
4388 goto error;
4389 } // switch
4390 return;
4391 error:
4392 set_valuetype(V_ERROR);
4393 }
4394
4395 void Value::chk_expr_operand_activate(Ttcn::Ref_base *ref,
4396 const char *,
4397 const char *opname)
4398 {
4399 if(valuetype==V_ERROR) return;
4400 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4401 Ttcn::Ref_pard *t_ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
4402 if (!t_ref_pard) FATAL_ERROR("Value::chk_expr_operand_activate()");
4403 Error_Context cntxt(this, "In `%s' operation", opname);
4404 if (!t_ref_pard->chk_activate_argument()) set_valuetype(V_ERROR);
4405 }
4406
4407 void Value::chk_expr_operand_activate_refd(Value *val,
4408 Ttcn::TemplateInstances* t_list2,
4409 Ttcn::ActualParList *&parlist,
4410 const char *,
4411 const char *opname)
4412 {
4413 if(valuetype==V_ERROR) return;
4414 Error_Context cntxt(this, "In `%s' operation", opname);
4415 Type *t = val->get_expr_governor_last();
4416 if (t) {
4417 switch (t->get_typetype()) {
4418 case Type::T_ERROR:
4419 set_valuetype(V_ERROR);
4420 break;
4421 case Type::T_ALTSTEP: {
4422 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4423 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4424 if(is_erroneous) {
4425 delete parlist;
4426 parlist = 0;
4427 set_valuetype(V_ERROR);
4428 } else {
4429 parlist->set_fullname(get_fullname());
4430 parlist->set_my_scope(get_my_scope());
4431 if (!fp_list->chk_activate_argument(parlist,
4432 get_stringRepr().c_str())) set_valuetype(V_ERROR);
4433 }
4434 break; }
4435 default:
4436 error("Reference to an altstep was expected in the argument of "
4437 "`derefers()' instead of `%s'", t->get_typename().c_str());
4438 set_valuetype(V_ERROR);
4439 break;
4440 }
4441 } else set_valuetype(V_ERROR);
4442 }
4443
4444 void Value::chk_expr_operand_execute(Ttcn::Ref_base *ref, Value *val,
4445 const char *,
4446 const char *opname)
4447 {
4448 if(valuetype==V_ERROR) return;
4449 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4450 Error_Context cntxt(this, "In `%s' operation", opname);
4451 Assignment *t_ass = ref->get_refd_assignment();
4452 bool error_flag = false;
4453 if (t_ass) {
4454 if (t_ass->get_asstype() != Common::Assignment::A_TESTCASE) {
4455 ref->error("Reference to a testcase was expected in the argument "
4456 "instead of %s", t_ass->get_description().c_str());
4457 error_flag = true;
4458 }
4459 } else error_flag = true;
4460 if (val) {
4461 val->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4462 Value *v_last = val->get_value_refd_last();
4463 switch (v_last->valuetype) {
4464 case V_REAL: {
4465 ttcn3float v_real = v_last->get_val_Real();
4466 if (v_real < 0.0) {
4467 val->error("The testcase guard timer has negative value: `%s'",
4468 Real2string(v_real).c_str());
4469 error_flag = true;
4470 }
4471 break; }
4472 case V_ERROR:
4473 error_flag = true;
4474 break;
4475 default:
4476 break;
4477 }
4478 }
4479 if (error_flag) set_valuetype(V_ERROR);
4480 }
4481
4482void Value::chk_expr_operand_execute_refd(Value *v1,
4483 Ttcn::TemplateInstances* t_list2,
4484 Ttcn::ActualParList *&parlist,
4485 Value *v3,
4486 const char *,
4487 const char *opname)
4488 {
4489 if(valuetype==V_ERROR) return;
4490 Error_Context cntxt(this, "In `%s' operation", opname);
4491 Type *t = v1->get_expr_governor_last();
4492 if (t) {
4493 switch (t->get_typetype()) {
4494 case Type::T_ERROR:
4495 set_valuetype(V_ERROR);
4496 break;
4497 case Type::T_TESTCASE: {
4498 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4499 bool is_erroneous = fp_list->chk_actual_parlist(t_list2, parlist);
4500 if(is_erroneous) {
4501 delete parlist;
4502 parlist = 0;
4503 set_valuetype(V_ERROR);
4504 } else {
4505 parlist->set_fullname(get_fullname());
4506 parlist->set_my_scope(get_my_scope());
4507 }
4508 break; }
4509 default:
4510 v1->error("Reference to a value of type testcase was expected in the "
4511 "argument of `derefers()' instead of `%s'",
4512 t->get_typename().c_str());
4513 set_valuetype(V_ERROR);
4514 break;
4515 }
4516 } else set_valuetype(V_ERROR);
4517 if (v3) {
4518 v3->chk_expr_float(Type::EXPECTED_DYNAMIC_VALUE);
4519 Value *v_last = v3->get_value_refd_last();
4520 switch (v_last->valuetype) {
4521 case V_REAL: {
4522 ttcn3float v_real = v_last->get_val_Real();
4523 if(v_real < 0.0) {
4524 v3->error("The testcase guard timer has negative value: `%s'",
4525 Real2string(v_real).c_str());
4526 set_valuetype(V_ERROR);
4527 }
4528 break; }
4529 case V_ERROR:
4530 set_valuetype(V_ERROR);
4531 break;
4532 default:
4533 break;
4534 }
4535 }
4536 }
4537
4538 void Value::chk_invoke(Type::expected_value_t exp_val)
4539 {
4540 if(valuetype == V_ERROR) return;
4541 if(valuetype != V_INVOKE) FATAL_ERROR("Value::chk_invoke()");
4542 if(!u.invoke.t_list) return; //already checked
4543 Error_Context cntxt(this, "In `apply()' operation");
4544 Type *t = u.invoke.v->get_expr_governor_last();
4545 if (!t) {
4546 set_valuetype(V_ERROR);
4547 return;
4548 }
4549 switch (t->get_typetype()) {
4550 case Type::T_ERROR:
4551 set_valuetype(V_ERROR);
4552 return;
4553 case Type::T_FUNCTION:
4554 break;
4555 default:
4556 u.invoke.v->error("A value of type function was expected in the "
4557 "argument instead of `%s'", t->get_typename().c_str());
4558 set_valuetype(V_ERROR);
4559 return;
4560 }
4561 my_scope->chk_runs_on_clause(t, *this, "call");
4562 Ttcn::FormalParList *fp_list = t->get_fat_parameters();
4563 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
4564 bool is_erroneous = fp_list->fold_named_and_chk(u.invoke.t_list, parlist);
4565 delete u.invoke.t_list;
4566 u.invoke.t_list = 0;
4567 if(is_erroneous) {
4568 delete parlist;
4569 u.invoke.ap_list = 0;
4570 } else {
4571 parlist->set_fullname(get_fullname());
4572 parlist->set_my_scope(get_my_scope());
4573 u.invoke.ap_list = parlist;
4574 }
4575 switch (exp_val) {
4576 case Type::EXPECTED_CONSTANT:
51fa56b9 4577 error("An evaluable constant value was expected instead of operation "
970ed795
EL
4578 "`apply()'");
4579 set_valuetype(V_ERROR);
4580 break;
4581 case Type::EXPECTED_STATIC_VALUE:
4582 error("A static value was expected instead of operation `apply()'");
4583 set_valuetype(V_ERROR);
4584 break;
4585 default:
4586 break;
4587 } // switch
4588 }
4589
4590 void Value::chk_expr_eval_value(Value *val, Type &t,
4591 ReferenceChain *refch,
4592 Type::expected_value_t exp_val)
4593 {
4594 bool self_ref = false;
4595 if(valuetype==V_ERROR) return;
4596 // Commented out to report more errors :)
4597 // e.g.: while ( 2 + Nonexi03 > 2 + Nonexi04 ) {}
4598 // if(u.expr.state==EXPR_CHECKING_ERR) return;
4599 switch(val->get_valuetype()) {
4600 case V_REFD:
4601 self_ref = t.chk_this_refd_value(val, 0, exp_val, refch);
4602 break;
4603 case V_EXPR:
4604 case V_MACRO:
4605 case V_INVOKE:
4606 val->get_value_refd_last(refch, exp_val);
4607 break;
4608 default:
4609 break;
4610 } // switch
4611 if(val->get_valuetype()==V_ERROR) set_valuetype(V_ERROR);
4612
4613 (void)self_ref;
4614 }
4615
4616 void Value::chk_expr_eval_ti(TemplateInstance *ti, Type *type,
4617 ReferenceChain *refch, Type::expected_value_t exp_val)
4618 {
4619 bool self_ref = false;
4620 ti->chk(type);
4621 if (exp_val != Type::EXPECTED_TEMPLATE && ti->get_DerivedRef()) {
4622 ti->error("Reference to a %s value was expected instead of an in-line "
4623 "modified template",
4624 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
4625 set_valuetype(V_ERROR);
4626 return;
4627 }
4628 Template *templ = ti->get_Template();
4629 switch (templ->get_templatetype()) {
4630 case Template::TEMPLATE_REFD:
4631 // not foldable
4632 if (exp_val == Type::EXPECTED_TEMPLATE) {
4633 templ = templ->get_template_refd_last(refch);
4634 if (templ->get_templatetype() == Template::TEMPLATE_ERROR)
4635 set_valuetype(V_ERROR);
4636 } else {
4637 ti->error("Reference to a %s value was expected instead of %s",
4638 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
4639 templ->get_reference()->get_refd_assignment()
4640 ->get_description().c_str());
4641 set_valuetype(V_ERROR);
4642 }
4643 break;
4644 case Template::SPECIFIC_VALUE: {
4645 Value *val = templ->get_specific_value();
4646 switch (val->get_valuetype()) {
4647 case V_REFD:
4648 self_ref = type->chk_this_refd_value(val, 0, exp_val, refch);
4649 break;
4650 case V_EXPR:
4651 val->get_value_refd_last(refch, exp_val);
4652 default:
4653 break;
4654 } // switch
4655 if (val->get_valuetype() == V_ERROR) set_valuetype(V_ERROR);
4656 break; }
4657 case Template::TEMPLATE_ERROR:
4658 set_valuetype(V_ERROR);
4659 break;
4660 default:
4661 break;
4662 } // switch
4663
4664 (void)self_ref;
4665 }
4666
4667 void Value::chk_expr_val_int_pos0(Value *val, const char *opnum,
4668 const char *opname)
4669 {
4670 if(valuetype==V_ERROR) return;
4671 if(u.expr.state==EXPR_CHECKING_ERR) return;
4672 if(val->is_unfoldable()) return;
4673 if(*val->get_val_Int()<0) {
4674 val->error("%s operand of operation `%s' should not be negative",
4675 opnum, opname);
4676 set_valuetype(V_ERROR);
4677 }
4678 }
4679
4680 void Value::chk_expr_val_int_pos7bit(Value *val, const char *opnum,
4681 const char *opname)
4682 {
4683 if(valuetype==V_ERROR) return;
4684 if(u.expr.state==EXPR_CHECKING_ERR) return;
4685 if(val->is_unfoldable()) return;
4686 if(*val->get_val_Int()<0 || *val->get_val_Int()>127) {
4687 val->error("%s operand of operation `%s' should be in range 0..127",
4688 opnum, opname);
4689 set_valuetype(V_ERROR);
4690 }
4691 }
4692
4693 void Value::chk_expr_val_int_pos31bit(Value *val, const char *opnum,
4694 const char *opname)
4695 {
4696 if(valuetype==V_ERROR) return;
4697 if(u.expr.state==EXPR_CHECKING_ERR) return;
4698 if(val->is_unfoldable()) return;
4699 if(*val->get_val_Int()<0 || *val->get_val_Int()>2147483647) {
4700 val->error("%s operand of operation `%s' should be in range"
4701 " 0..2147483647", opnum, opname);
4702 set_valuetype(V_ERROR);
4703 }
4704 }
4705
4706 void Value::chk_expr_val_int_float_not0(Value *val, const char *opnum,
4707 const char *opname)
4708 {
4709 if(valuetype==V_ERROR) return;
4710 if(u.expr.state==EXPR_CHECKING_ERR) return;
4711 if(val->is_unfoldable()) return;
4712 if((val->get_expr_returntype()==Type::T_INT && *val->get_val_Int()==0)
4713 ||
4714 (val->get_expr_returntype()==Type::T_REAL && val->get_val_Real()==0.0))
4715 {
4716 val->error("%s operand of operation `%s' should not be zero",
4717 opnum, opname);
4718 set_valuetype(V_ERROR);
4719 }
4720 }
4721
4722 void Value::chk_expr_val_large_int(Value *val, const char *opnum,
4723 const char *opname)
4724 {
4725 if (valuetype == V_ERROR) return;
4726 if (u.expr.state == EXPR_CHECKING_ERR) return;
4727 if (val->get_expr_returntype() != Type::T_INT) return;
4728 if (val->is_unfoldable()) return;
4729 const int_val_t *val_int = val->get_val_Int();
4730 if (*val_int > static_cast<Int>(INT_MAX)) {
4731 val->error("%s operand of operation `%s' should be less than `%d' "
4732 "instead of `%s'", opnum, opname, INT_MAX,
4733 (val_int->t_str()).c_str());
4734 set_valuetype(V_ERROR);
4735 }
4736 }
4737
4738 void Value::chk_expr_val_len1(Value *val, const char *opnum,
4739 const char *opname)
4740 {
4741 if(valuetype==V_ERROR) return;
4742 if(u.expr.state==EXPR_CHECKING_ERR) return;
4743 if(val->is_unfoldable()) return;
4744 if(val->get_val_strlen()!=1) {
4745 val->error("%s operand of operation `%s' should be of length 1",
4746 opnum, opname);
4747 set_valuetype(V_ERROR);
4748 }
4749 }
4750
4751 void Value::chk_expr_val_str_len_even(Value *val, const char *opnum,
4752 const char *opname)
4753 {
4754 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4755 Value *v_last = val->get_value_refd_last();
4756 if (v_last->valuetype == V_CSTR) {
4757 size_t len = v_last->get_val_strlen();
4758 if (len % 2) {
4759 val->error("%s operand of operation `%s' should contain even number "
4760 "of characters instead of %lu", opnum, opname, (unsigned long) len);
4761 set_valuetype(V_ERROR);
4762 }
4763 } else if (v_last->valuetype == V_REFD) {
4764 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4765 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4766 val->error("%s operand of operation `%s' should contain even number "
4767 "of characters, but a string element contains 1", opnum, opname);
4768 set_valuetype(V_ERROR);
4769 }
4770 }
4771 }
4772
4773 void Value::chk_expr_val_str_bindigits(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=='1')) {
4783 val->error("%s operand of operation `%s' can contain only"
4784 " binary 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_hexdigits(Value *val, const char *opnum,
4793 const char *opname)
4794 {
4795 if(valuetype==V_ERROR) return;
4796 if(u.expr.state==EXPR_CHECKING_ERR) return;
4797 if(val->is_unfoldable()) return;
4798 const string& s=val->get_val_str();
4799 for(size_t i=0; i<s.size(); i++) {
4800 char c=s[i];
4801 if(!((c>='0' && c<='9') || (c>='A' && c<='F') || (c>='a' && c<='f'))) {
4802 val->error("%s operand of operation `%s' can contain only valid "
4803 "hexadecimal digits (position %lu is `%c')",
4804 opnum, opname, (unsigned long) i, c);
4805 set_valuetype(V_ERROR);
4806 return;
4807 }
4808 }
4809 }
4810
4811 void Value::chk_expr_val_str_7bitoctets(Value *val, const char *opnum,
4812 const char *opname)
4813 {
4814 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4815 Value *v = val->get_value_refd_last();
4816 if (v->valuetype != V_OSTR) return;
4817 const string& s = val->get_val_str();
4818 size_t n_octets = s.size() / 2;
4819 for (size_t i = 0; i < n_octets; i++) {
4820 char c = s[2 * i];
4821 if (!(c >= '0' && c <= '7')) {
4822 val->error("%s operand of operation `%s' shall consist of octets "
4823 "within the range 00 .. 7F, but the string `%s'O contains octet "
4824 "%c%c at index %lu", opnum, opname, s.c_str(), c, s[2 * i + 1],
4825 (unsigned long) i);
4826 set_valuetype(V_ERROR);
4827 return;
4828 }
4829 }
4830 }
4831
4832 void Value::chk_expr_val_str_int(Value *val, const char *opnum,
4833 const char *opname)
4834 {
4835 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4836 Value *v_last = val->get_value_refd_last();
4837 if (v_last->valuetype != V_CSTR) return;
4838 const string& s = v_last->get_val_str();
4839 enum { S_INITIAL, S_INITIAL_WS, S_FIRST, S_ZERO, S_MORE, S_END, S_ERR }
4840 state = S_INITIAL;
4841 // state: expected characters
4842 // S_INITIAL, S_INITIAL_WS: +, -, first digit, leading whitespace
4843 // S_FIRST: first digit
4844 // S_ZERO, S_MORE: more digit(s), trailing whitespace
4845 // S_END: trailing whitespace
4846 // S_ERR: error was found, stop
4847 for (size_t i = 0; i < s.size(); i++) {
4848 char c = s[i];
4849 switch (state) {
4850 case S_INITIAL:
4851 case S_INITIAL_WS:
4852 if (c == '+' || c == '-') state = S_FIRST;
4853 else if (c == '0') state = S_ZERO;
4854 else if (c >= '1' && c <= '9') state = S_MORE;
4855 else if (string::is_whitespace(c)) {
4856 if (state == S_INITIAL) {
4857 val->warning("Leading whitespace was detected and ignored in the "
4858 "operand of operation `%s'", opname);
4859 state = S_INITIAL_WS;
4860 }
4861 } else state = S_ERR;
4862 break;
4863 case S_FIRST:
4864 if (c == '0') state = S_ZERO;
4865 else if (c >= '1' && c <= '9') state = S_MORE;
4866 else state = S_ERR;
4867 break;
4868 case S_ZERO:
4869 if (c >= '0' && c <= '9') {
4870 val->warning("Leading zero digit was detected and ignored in the "
4871 "operand of operation `%s'", opname);
4872 state = S_MORE;
4873 } else if (string::is_whitespace(c)) state = S_END;
4874 else state = S_ERR;
4875 break;
4876 case S_MORE:
4877 if (c >= '0' && c <= '9') {}
4878 else if (string::is_whitespace(c)) state = S_END;
4879 else state = S_ERR;
4880 break;
4881 case S_END:
4882 if (!string::is_whitespace(c)) state = S_ERR;
4883 break;
4884 default:
4885 break;
4886 }
4887 if (state == S_ERR) {
4888 if (string::is_printable(c)) {
4889 val->error("%s operand of operation `%s' should be a string "
4890 "containing a valid integer value, but invalid character `%c' "
4891 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
4892 } else {
4893 val->error("%s operand of operation `%s' should be a string "
4894 "containing a valid integer value, but invalid character with "
4895 "character code %u was detected at index %lu", opnum, opname, c,
4896 (unsigned long) i);
4897 }
4898 set_valuetype(V_ERROR);
4899 break;
4900 }
4901 }
4902 switch (state) {
4903 case S_INITIAL:
4904 case S_INITIAL_WS:
4905 val->error("%s operand of operation `%s' should be a string containing a "
4906 "valid integer value instead of an empty string", opnum, opname);
4907 set_valuetype(V_ERROR);
4908 break;
4909 case S_FIRST:
4910 val->error("%s operand of operation `%s' should be a string containing a "
4911 "valid integer value, but only a sign character was detected", opnum,
4912 opname);
4913 set_valuetype(V_ERROR);
4914 break;
4915 case S_END:
4916 val->warning("Trailing whitespace was detected and ignored in the "
4917 "operand of operation `%s'", opname);
4918 break;
4919 default:
4920 break;
4921 }
4922 }
4923
4924 void Value::chk_expr_val_str_float(Value *val, const char *opnum,
4925 const char *opname)
4926 {
4927 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
4928 Value *v_last = val->get_value_refd_last();
4929 if (v_last->valuetype == V_REFD) {
4930 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
4931 if (t_subrefs && t_subrefs->refers_to_string_element()) {
4932 val->error("%s operand of operation `%s' should be a string containing "
4933 "a valid float value instead of a string element, which cannot "
4934 "represent a floating point number", opnum, opname);
4935 set_valuetype(V_ERROR);
4936 }
4937 return;
4938 } else if (v_last->valuetype != V_CSTR) return;
4939 const string& s = v_last->get_val_str();
4940 enum { S_INITIAL, S_INITIAL_WS, S_FIRST_M, S_ZERO_M, S_MORE_M, S_FIRST_F,
4941 S_MORE_F, S_INITIAL_E, S_FIRST_E, S_ZERO_E, S_MORE_E, S_END, S_ERR }
4942 state = S_INITIAL;
4943 // state: expected characters
4944 // S_INITIAL, S_INITIAL_WS: +, -, first digit of integer part in mantissa,
4945 // leading whitespace
4946 // S_FIRST_M: first digit of integer part in mantissa
4947 // S_ZERO_M, S_MORE_M: more digits of mantissa, decimal dot, E
4948 // S_FIRST_F: first digit of fraction
4949 // S_MORE_F: more digits of fraction, E, trailing whitespace
4950 // S_INITIAL_E: +, -, first digit of exponent
4951 // S_FIRST_E: first digit of exponent
4952 // S_ZERO_E, S_MORE_E: more digits of exponent, trailing whitespace
4953 // S_END: trailing whitespace
4954 // S_ERR: error was found, stop
4955 for (size_t i = 0; i < s.size(); i++) {
4956 char c = s[i];
4957 switch (state) {
4958 case S_INITIAL:
4959 case S_INITIAL_WS:
4960 if (c == '+' || c == '-') state = S_FIRST_M;
4961 else if (c == '0') state = S_ZERO_M;
4962 else if (c >= '1' && c <= '9') state = S_MORE_M;
4963 else if (string::is_whitespace(c)) {
4964 if (state == S_INITIAL) {
4965 val->warning("Leading whitespace was detected and ignored in the "
4966 "operand of operation `%s'", opname);
4967 state = S_INITIAL_WS;
4968 }
4969 } else state = S_ERR;
4970 break;
4971 case S_FIRST_M:
4972 if (c == '0') state = S_ZERO_M;
4973 else if (c >= '1' && c <= '9') state = S_MORE_M;
4974 else state = S_ERR;
4975 break;
4976 case S_ZERO_M:
4977 if (c == '.') state = S_FIRST_F;
4978 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4979 else if (c >= '0' && c <= '9') {
4980 val->warning("Leading zero digit was detected and ignored in the "
4981 "mantissa of the operand of operation `%s'", opname);
4982 state = S_MORE_M;
4983 } else state = S_ERR;
4984 break;
4985 case S_MORE_M:
4986 if (c == '.') state = S_FIRST_F;
4987 else if (c == 'E' || c == 'e') state = S_INITIAL_E;
4988 else if (c >= '0' && c <= '9') {}
4989 else state = S_ERR;
4990 break;
4991 case S_FIRST_F:
4992 if (c >= '0' && c <= '9') state = S_MORE_F;
4993 else state = S_ERR;
4994 break;
4995 case S_MORE_F:
4996 if (c == 'E' || c == 'e') state = S_INITIAL_E;
4997 else if (c >= '0' && c <= '9') {}
4998 else if (string::is_whitespace(c)) state = S_END;
4999 else state = S_ERR;
5000 break;
5001 case S_INITIAL_E:
5002 if (c == '+' || c == '-') state = S_FIRST_E;
5003 else if (c == '0') state = S_ZERO_E;
5004 else if (c >= '1' && c <= '9') state = S_MORE_E;
5005 else state = S_ERR;
5006 break;
5007 case S_FIRST_E:
5008 if (c == '0') state = S_ZERO_E;
5009 else if (c >= '1' && c <= '9') state = S_MORE_E;
5010 else state = S_ERR;
5011 break;
5012 case S_ZERO_E:
5013 if (c >= '0' && c <= '9') {
5014 val->warning("Leading zero digit was detected and ignored in the "
5015 "exponent of the operand of operation `%s'", opname);
5016 state = S_MORE_E;
5017 } else if (string::is_whitespace(c)) state = S_END;
5018 else state = S_ERR;
5019 break;
5020 case S_MORE_E:
5021 if (c >= '0' && c <= '9') {}
5022 else if (string::is_whitespace(c)) state = S_END;
5023 else state = S_ERR;
5024 break;
5025 case S_END:
5026 if (!string::is_whitespace(c)) state = S_ERR;
5027 break;
5028 default:
5029 break;
5030 }
5031 if (state == S_ERR) {
5032 if (string::is_printable(c)) {
5033 val->error("%s operand of operation `%s' should be a string "
5034 "containing a valid float value, but invalid character `%c' "
5035 "was detected at index %lu", opnum, opname, c, (unsigned long) i);
5036 } else {
5037 val->error("%s operand of operation `%s' should be a string "
5038 "containing a valid float value, but invalid character with "
5039 "character code %u was detected at index %lu", opnum, opname, c,
5040 (unsigned long) i);
5041 }
5042 set_valuetype(V_ERROR);
5043 break;
5044 }
5045 }
5046 switch (state) {
5047 case S_INITIAL:
5048 case S_INITIAL_WS:
5049 val->error("%s operand of operation `%s' should be a string containing a "
5050 "valid float value instead of an empty string", opnum, opname);
5051 set_valuetype(V_ERROR);
5052 break;
5053 case S_FIRST_M:
5054 val->error("%s operand of operation `%s' should be a string containing a "
5055 "valid float value, but only a sign character was detected", opnum,
5056 opname);
5057 set_valuetype(V_ERROR);
5058 break;
5059 case S_ZERO_M:
5060 case S_MORE_M:
5061 // HL67862: Missing decimal dot allowed for str2float
5062 break;
5063 case S_FIRST_F:
5064 // HL67862: Missing fraction part is allowed for str2float
5065 break;
5066 case S_INITIAL_E:
5067 case S_FIRST_E:
5068 val->error("%s operand of operation `%s' should be a string containing a "
5069 "valid float value, but the exponent is missing after the `E' sign",
5070 opnum, opname);
5071 set_valuetype(V_ERROR);
5072 break;
5073 case S_END:
5074 val->warning("Trailing whitespace was detected and ignored in the "
5075 "operand of operation `%s'", opname);
5076 break;
5077 default:
5078 break;
5079 }
5080 }
5081
5082 void Value::chk_expr_val_ustr_7bitchars(Value *val, const char *opnum,
5083 const char *opname)
5084 {
5085 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5086 Value *v = val->get_value_refd_last();
5087 if (v->valuetype != V_USTR) return;
5088 const ustring& us = v->get_val_ustr();
5089 for (size_t i = 0; i < us.size(); i++) {
5090 const ustring::universal_char& uchar = us[i];
5091 if (uchar.group != 0 || uchar.plane != 0 || uchar.row != 0 ||
5092 uchar.cell > 127) {
5093 val->error("%s operand of operation `%s' shall consist of characters "
5094 "within the range char(0, 0, 0, 0) .. char(0, 0, 0, 127), but the "
5095 "string %s contains character char(%u, %u, %u, %u) at index %lu",
5096 opnum, opname, us.get_stringRepr().c_str(), uchar.group, uchar.plane,
5097 uchar.row, uchar.cell, (unsigned long) i);
5098 set_valuetype(V_ERROR);
5099 return;
5100 }
5101 }
5102 }
5103
5104 void Value::chk_expr_val_bitstr_intsize(Value *val, const char *opnum,
5105 const char *opname)
5106 {
5107 if(valuetype==V_ERROR) return;
5108 if(u.expr.state==EXPR_CHECKING_ERR) return;
5109 if(val->is_unfoldable()) return;
5110 const string& bstr=val->get_val_str();
5111 // see also PredefFunc.cc::bit2int()
5112 size_t nof_bits = bstr.size();
5113 // skip the leading zeros
5114 size_t start_index = 0;
5115 while (start_index < nof_bits && bstr[start_index] == '0') start_index++;
5116 // check whether the remaining bits fit in Int
5117 if (nof_bits - start_index > 8 * sizeof(Int) - 1) {
5118 val->error("%s operand of operation `%s' is too large (maximum number"
5119 " of bits in integer is %lu)",
5120 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5121 set_valuetype(V_ERROR);
5122 }
5123 }
5124
5125 void Value::chk_expr_val_hexstr_intsize(Value *val, const char *opnum,
5126 const char *opname)
5127 {
5128 if(valuetype==V_ERROR) return;
5129 if(u.expr.state==EXPR_CHECKING_ERR) return;
5130 if(val->is_unfoldable()) return;
5131 const string& hstr=val->get_val_str();
5132 // see also PredefFunc.cc::hex2int()
5133 size_t nof_digits = hstr.size();
5134 // skip the leading zeros
5135 size_t start_index = 0;
5136 while (start_index < nof_digits && hstr[start_index] == '0') start_index++;
5137 // check whether the remaining hex digits fit in Int
5138 if (nof_digits - start_index > 2 * sizeof(Int) ||
5139 (nof_digits - start_index == 2 * sizeof(Int) &&
5140 char_to_hexdigit(hstr[start_index]) > 7)) {
5141 val->error("%s operand of operation `%s' is too large (maximum number"
5142 " of bits in integer is %lu)",
5143 opnum, opname, (unsigned long) (8 * sizeof(Int) - 1));
5144 set_valuetype(V_ERROR);
5145 }
5146 }
5147
5148 void Value::chk_expr_operands_int2binstr()
5149 {
5150 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5151 if (u.expr.v1->is_unfoldable()) return;
5152 if (u.expr.v2->is_unfoldable()) return;
5153 // It is already checked that i1 and i2 are non-negative.
5154 Error_Context cntxt(this, "In operation `%s'", get_opname());
5155 const int_val_t *i1 = u.expr.v1->get_val_Int();
5156 const int_val_t *i2 = u.expr.v2->get_val_Int();
5157 if (!i2->is_native()) {
5158 u.expr.v2->error("The length of the resulting string is too large for "
5159 "being represented in memory");
5160 set_valuetype(V_ERROR);
5161 return;
5162 }
5163 Int nof_bits = i2->get_val();
5164 if (u.expr.v1->is_unfoldable()) return;
5165 switch (u.expr.v_optype) {
5166 case OPTYPE_INT2BIT:
5167 break;
5168 case OPTYPE_INT2HEX:
5169 nof_bits *= 4;
5170 break;
5171 case OPTYPE_INT2OCT:
5172 nof_bits *= 8;
5173 break;
5174 default:
5175 FATAL_ERROR("Value::chk_expr_operands_int2binstr()");
5176 }
5177 if (*i1 >> nof_bits > 0) { // Expensive?
5178 u.expr.v1->error("Value %s does not fit in length %s",
5179 i1->t_str().c_str(), i2->t_str().c_str());
5180 set_valuetype(V_ERROR);
5181 }
5182 }
5183
5184 void Value::chk_expr_operands_str_samelen()
5185 {
5186 if(valuetype==V_ERROR) return;
5187 if(u.expr.state==EXPR_CHECKING_ERR) return;
5188 Value *v1=u.expr.v1;
5189 if(v1->is_unfoldable()) return;
5190 Value *v2=u.expr.v2;
5191 if(v2->is_unfoldable()) return;
5192 Error_Context cntxt(this, "In operation `%s'", get_opname());
5193 size_t i1=v1->get_val_strlen();
5194 size_t i2=v2->get_val_strlen();
5195 if(i1!=i2) {
5196 error("The operands should have the same length");
5197 set_valuetype(V_ERROR);
5198 }
5199 }
5200
5201 void Value::chk_expr_operands_replace()
5202 {
5203 // The fourth operand doesn't need to be checked at all here.
5204 if(valuetype==V_ERROR) return;
5205 if(u.expr.state==EXPR_CHECKING_ERR) return;
5206 Value* v1 = u.expr.ti1->get_specific_value();
5207 if (!v1) return;
5208
5209 Error_Context cntxt(this, "In operation `%s'", get_opname());
5210 size_t list_len = 0;
5211 bool list_len_known = false;
5212 if (v1->valuetype == V_REFD) {
5213 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5214 if (subrefs && subrefs->refers_to_string_element()) {
5215 warning("Replacing a string element does not make any sense");
5216 list_len = 1;
5217 list_len_known = true;
5218 }
5219 }
5220 if (!v1->is_unfoldable()) {
5221 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5222 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5223 list_len_known = true;
5224 }
5225 if (!list_len_known) return;
5226 if (u.expr.v2->is_unfoldable()) {
5227 if (!u.expr.v3->is_unfoldable()) {
5228 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5229 if (*len_int_3 > static_cast<Int>(list_len)) {
5230 error("Third operand `len' (%s) is greater than the length of "
5231 "the first operand (%lu)", (len_int_3->t_str()).c_str(),
5232 (unsigned long)list_len);
5233 set_valuetype(V_ERROR);
5234 }
5235 }
5236 } else {
5237 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5238 if (u.expr.v3->is_unfoldable()) {
5239 if (*index_int_2 > static_cast<Int>(list_len)) {
5240 error("Second operand `index' (%s) is greater than the length of "
5241 "the first operand (%lu)", (index_int_2->t_str()).c_str(),
5242 (unsigned long)list_len);
5243 set_valuetype(V_ERROR);
5244 }
5245 } else {
5246 const int_val_t *len_int_3 = u.expr.v3->get_val_Int();
5247 if (*index_int_2 + *len_int_3 > static_cast<Int>(list_len)) {
5248 error("The sum of second operand `index' (%s) and third operand "
5249 "`len' (%s) is greater than the length of the first operand (%lu)",
5250 (index_int_2->t_str()).c_str(), (len_int_3->t_str()).c_str(),
5251 (unsigned long)list_len);
5252 set_valuetype(V_ERROR);
5253 }
5254 }
5255 }
5256 }
5257
5258 void Value::chk_expr_operands_substr()
5259 {
5260 if(valuetype==V_ERROR) return;
5261 if(u.expr.state==EXPR_CHECKING_ERR) return;
5262 Value* v1 = u.expr.ti1->get_specific_value();
5263 if (!v1) return;
5264
5265 Error_Context cntxt(this, "In operation `%s'", get_opname());
5266 size_t list_len = 0;
5267 bool list_len_known = false;
5268 if (v1->valuetype == V_REFD) {
5269 Ttcn::FieldOrArrayRefs *subrefs = v1->u.ref.ref->get_subrefs();
5270 if (subrefs && subrefs->refers_to_string_element()) {
5271 warning("Taking the substring of a string element does not make any "
5272 "sense");
5273 list_len = 1;
5274 list_len_known = true;
5275 }
5276 }
5277 if (!list_len_known && !v1->is_unfoldable()) {
5278 list_len = v1->is_string_type(Type::EXPECTED_TEMPLATE) ?
5279 v1->get_val_strlen() : v1->get_value_refd_last()->get_nof_comps();
5280 list_len_known = true;
5281 }
5282 // Do nothing if the length of the first operand is unknown.
5283 if (!list_len_known) return;
5284 if (u.expr.v2->is_unfoldable()) {
5285 if (!u.expr.v3->is_unfoldable()) {
5286 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5287 // Only the third operand is known.
5288 if (*returncount_int_3 > static_cast<Int>(list_len)) {
5289 error("Third operand `returncount' (%s) is greater than the "
5290 "length of the first operand (%lu)",
5291 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5292 set_valuetype(V_ERROR);
5293 }
5294 }
5295 } else {
5296 const int_val_t *index_int_2 = u.expr.v2->get_val_Int();
5297 if (u.expr.v3->is_unfoldable()) {
5298 // Only the second operand is known.
5299 if (*index_int_2 > static_cast<Int>(list_len)) {
5300 error("Second operand `index' (%s) is greater than the length "
5301 "of the first operand (%lu)", (index_int_2->t_str()).c_str(),
5302 (unsigned long)list_len);
5303 set_valuetype(V_ERROR);
5304 }
5305 } else {
5306 // Both second and third operands are known.
5307 const int_val_t *returncount_int_3 = u.expr.v3->get_val_Int();
5308 if (*index_int_2 + *returncount_int_3 > static_cast<Int>(list_len)) {
5309 error("The sum of second operand `index' (%s) and third operand "
5310 "`returncount' (%s) is greater than the length of the first operand "
5311 "(%lu)", (index_int_2->t_str()).c_str(),
5312 (returncount_int_3->t_str()).c_str(), (unsigned long)list_len);
5313 set_valuetype(V_ERROR);
5314 }
5315 }
5316 }
5317 }
5318
5319 void Value::chk_expr_operands_regexp()
5320 {
5321 if (valuetype == V_ERROR || u.expr.state == EXPR_CHECKING_ERR) return;
5322 Value* v1 = u.expr.ti1->get_specific_value();
5323 Value* v2 = u.expr.t2->get_specific_value();
5324 if (!v1 || !v2) return;
5325
5326 Error_Context cntxt(this, "In operation `regexp()'");
5327 Value* v1_last = v1->get_value_refd_last();
5328 if (v1_last->valuetype == V_CSTR) {
5329 // the input string is available at compile time
5330 const string& instr = v1_last->get_val_str();
5331 const char *input_str = instr.c_str();
5332 size_t instr_len = strlen(input_str);
5333 if (instr_len < instr.size()) {
5334 v1->warning("The first operand of `regexp()' contains a "
5335 "character with character code zero at index %s. The rest of the "
5336 "string will be ignored during matching",
5337 Int2string(instr_len).c_str());
5338 }
5339 }
5340
5341 size_t nof_groups = 0;
5342 Value *v2_last = v2->get_value_refd_last();
5343
5344 if (v2_last->valuetype == V_CSTR) {
5345 // the pattern is available at compile time
5346 const string& expression = v2_last->get_val_str();
5347 const char *pattern_str = expression.c_str();
5348 size_t pattern_len = strlen(pattern_str);
5349 if (pattern_len < expression.size()) {
5350 v2->warning("The second operand of `regexp()' contains a "
5351 "character with character code zero at index %s. The rest of the "
5352 "string will be ignored during matching",
5353 Int2string(pattern_len).c_str());
5354 }
5355 char *posix_str;
5356 {
5357 Error_Context cntxt2(v2, "In character string pattern");
5358 posix_str = TTCN_pattern_to_regexp(pattern_str);
5359 }
5360 if (posix_str != NULL) {
5361 regex_t posix_regexp;
5362 int ret_val = regcomp(&posix_regexp, posix_str, REG_EXTENDED);
5363 if (ret_val != 0) {
5364 char msg[512];
5365 regerror(ret_val, &posix_regexp, msg, sizeof(msg));
5366 FATAL_ERROR("Value::chk_expr_operands_regexp(): " \
5367 "regcomp() failed: %s", msg);
5368 }
5369 if (posix_regexp.re_nsub > 0) nof_groups = posix_regexp.re_nsub;
5370 else {
5371 v2->error("The character pattern in the second operand of "
5372 "`regexp()' does not contain any groups");
5373 set_valuetype(V_ERROR);
5374 }
5375 regfree(&posix_regexp);
5376 Free(posix_str);
5377 } else {
5378 // the pattern is faulty
5379 // the error has been reported by TTCN_pattern_to_regexp
5380 set_valuetype(V_ERROR);
5381 }
5382 }
5383 if (nof_groups > 0) {
5384 Value *v3 = u.expr.v3->get_value_refd_last();
5385 if (v3->valuetype == V_INT) {
5386 // the group number is available at compile time
5387 const int_val_t *groupno_int = v3->get_val_Int();
5388 if (*groupno_int >= static_cast<Int>(nof_groups)) {
5389 u.expr.v3->error("The the third operand of `regexp()' is too "
5390 "large: The requested group index is %s, but the pattern "
5391 "contains only %s group%s", (groupno_int->t_str()).c_str(),
5392 Int2string(nof_groups).c_str(), nof_groups > 1 ? "s" : "");
5393 set_valuetype(V_ERROR);
5394 }
5395 }
5396 }
5397 }
5398
5399 void Value::chk_expr_operands_ischosen(ReferenceChain *refch,
5400 Type::expected_value_t exp_val)
5401 {
5402 const char *opname = get_opname();
5403 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
5404 Type *t_governor;
5405 const Location *loc;
5406 bool error_flag = false;
5407 switch (u.expr.v_optype) {
5408 case OPTYPE_ISCHOSEN_V:
5409 // u.expr.v1 is always a referenced value
5410 t_governor = u.expr.v1->get_expr_governor(exp_val);
5411 if (t_governor) {
5412 u.expr.v1->set_my_governor(t_governor);
5413 t_governor->chk_this_refd_value(u.expr.v1, 0, exp_val, refch);
5414 if (u.expr.v1->valuetype == V_ERROR) error_flag = true;
5415 } else error_flag = true;
5416 loc = u.expr.v1;
5417 break;
5418 case OPTYPE_ISCHOSEN_T:
5419 // u.expr.t1 is always a referenced template
5420 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5421 exp_val = Type::EXPECTED_TEMPLATE;
5422 t_governor = u.expr.t1->get_expr_governor(exp_val);
5423 if (t_governor) {
5424 u.expr.t1->set_my_governor(t_governor);
5425 //
5426 // FIXME: commenting out the 2 lines below "fixes" the ischosen for HQ46602
5427 //
5428 u.expr.t1->get_template_refd_last(refch);
5429 if (u.expr.t1->get_templatetype() == Template::TEMPLATE_ERROR)
5430 error_flag = true;
5431 } else error_flag = true;
5432 if (exp_val != Type::EXPECTED_TEMPLATE) {
5433 u.expr.t1->error("Reference to a %s value was expected instead of %s",
5434 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static",
5435 u.expr.t1->get_reference()->get_refd_assignment()
5436 ->get_description().c_str());
5437 error_flag = true;
5438 }
5439 loc = u.expr.t1;
5440 break;
5441 default:
5442 FATAL_ERROR("Value::chk_expr_operands_ischosen()");
5443 t_governor = 0;
5444 loc = 0;
5445 }
5446 if (t_governor) {
5447 t_governor = t_governor->get_type_refd_last();
5448 switch (t_governor->get_typetype()) {
5449 case Type::T_ERROR:
5450 error_flag = true;
5451 break;
5452 case Type::T_CHOICE_A:
5453 case Type::T_CHOICE_T:
5454 case Type::T_ANYTYPE:
5455 case Type::T_OPENTYPE:
5456 if (!t_governor->has_comp_withName(*u.expr.i2)) {
5457 error(t_governor->get_typetype()==Type::T_ANYTYPE ?
5458 "%s does not have a field named `%s'" :
5459 "Union type `%s' does not have a field named `%s'",
5460 t_governor->get_typename().c_str(),
5461 u.expr.i2->get_dispname().c_str());
5462 error_flag = true;
5463 }
5464 break;
5465 default:
5466 loc->error("The operand of operation `%s' should be a union value "
5467 "or template instead of `%s'", opname,
5468 t_governor->get_typename().c_str());
5469 error_flag = true;
5470 break;
5471 }
5472 }
5473 if (error_flag) set_valuetype(V_ERROR);
5474 }
5475
5476 void Value::chk_expr_operand_encode(ReferenceChain *refch,
5477 Type::expected_value_t exp_val) {
5478
a50716c1 5479 Error_Context cntxt(this, "In the parameter of %s",
5480 u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR ? "encvalue_unichar()" : "encvalue()");
970ed795
EL
5481 Type t_chk(Type::T_ERROR);
5482 Type* t_type;
5483
5484 Type::expected_value_t ti_exp_val = exp_val;
5485 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
5486 ti_exp_val = Type::EXPECTED_TEMPLATE;
5487
5488 t_type = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
5489 if (t_type) {
5490 chk_expr_eval_ti(u.expr.ti1, t_type, refch, ti_exp_val);
5491 if (valuetype!=V_ERROR)
5492 u.expr.ti1->get_Template()->chk_specific_value(false);
5493 t_type = t_type->get_type_refd_last();
5494 } else {
5495 error("Cannot determine type of value");
5496 goto error;
5497 }
1d0599f0 5498
970ed795
EL
5499 // todo: fix this
5500 /*if (u.expr.par1_is_value && u.expr.v1->get_valuetype() != V_REFD) {
5501 error("Expecting a value of a type with coding attributes in first"
5502 "parameter of encvalue() which belongs to a generic type '%s'",
5503 t_type->get_typename().c_str());
5504 goto error;
5505 }*/
5506
5507 if(!disable_attribute_validation()) {
5508 t_type->chk_coding(true);
5509 }
1d0599f0 5510
970ed795
EL
5511 switch (t_type->get_typetype()) {
5512 case Type::T_UNDEF:
5513 case Type::T_ERROR:
5514 case Type::T_NULL:
5515 case Type::T_REFD:
5516 case Type::T_REFDSPEC:
5517 case Type::T_SELTYPE:
5518 case Type::T_VERDICT:
5519 case Type::T_PORT:
5520 case Type::T_COMPONENT:
5521 case Type::T_DEFAULT:
5522 case Type::T_SIGNATURE:
5523 case Type::T_FUNCTION:
5524 case Type::T_ALTSTEP:
5525 case Type::T_TESTCASE:
5526 error("Type of parameter of encvalue() cannot be '%s'",
5527 t_type->get_typename().c_str());
5528 goto error;
5529 default:
5530 break;
5531 }
5532 return;
5533error:
5534 set_valuetype(V_ERROR);
5535 }
5536
1d0599f0 5537 void Value::chk_expr_operands_decode(operationtype_t p_optype)
970ed795 5538 {
a50716c1 5539 Error_Context cntxt(this, "In the parameters of %s",
7be5e88c 5540 p_optype == OPTYPE_DECVALUE_UNICHAR ? "decvalue_unichar()" : "decvalue()");
970ed795
EL
5541 Ttcn::Ref_base* ref = u.expr.r1;
5542 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5543 Type* t_type = 0;
5544 Assignment* t_ass = ref->get_refd_assignment();
5545
5546 if (!t_ass) {
5547 error("Could not determine the assignment for first parameter");
5548 goto error;
5549 }
5550 switch (t_ass->get_asstype()) {
5551 case Assignment::A_PAR_VAL_IN:
5552 t_ass->use_as_lvalue(*this);
5553 break;
5554 case Assignment::A_CONST:
5555 case Assignment::A_EXT_CONST:
5556 case Assignment::A_MODULEPAR:
5557 case Assignment::A_MODULEPAR_TEMP:
5558 case Assignment::A_TEMPLATE:
5559 ref->error("Reference to '%s' cannot be used as the first operand of "
5560 "the 'decvalue' operation", t_ass->get_assname());
5561 goto error;
5562 break;
5563 case Assignment::A_VAR:
5564 case Assignment::A_PAR_VAL_OUT:
5565 case Assignment::A_PAR_VAL_INOUT:
5566 break;
5567 case Assignment::A_VAR_TEMPLATE:
5568 case Assignment::A_PAR_TEMPL_IN:
5569 case Assignment::A_PAR_TEMPL_OUT:
5570 case Assignment::A_PAR_TEMPL_INOUT: {
5571 Template* t = new Template(ref->clone());
5572 t->set_location(*ref);
5573 t->set_my_scope(get_my_scope());
5574 t->set_fullname(get_fullname()+".<operand>");
5575 Template* t_last = t->get_template_refd_last();
5576 if (t_last->get_templatetype() != Template::SPECIFIC_VALUE
5577 && t_last != t) {
5578 ref->error("Specific value template was expected instead of '%s'.",
5579 t->get_template_refd_last()->get_templatetype_str());
5580 delete t;
5581 goto error;
5582 }
5583 delete t;
5584 break; }
5585 default:
5586 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5587 goto error;
5588 }
5589 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5590 Type::EXPECTED_DYNAMIC_VALUE);
5591 if (!t_type) {
5592 goto error;
5593 }
1d0599f0 5594 switch(p_optype) {
5595 case OPTYPE_DECODE:
5596 if (t_type->get_type_refd_last()->get_typetype() != Type::T_BSTR){
5597 error("First parameter has to be a bitstring");
5598 goto error;
5599 }
5600 break;
5601 case OPTYPE_DECVALUE_UNICHAR:
5602 if (t_type->get_type_refd_last()->get_typetype() != Type::T_USTR){
5603 error("First parameter has to be a universal charstring");
5604 goto error;
5605 }
5606 break;
5607 default:
5608 FATAL_ERROR("Value::chk_expr_decode_operands()");
5609 break;
970ed795
EL
5610 }
5611
5612 ref = u.expr.r2;
5613 t_subrefs = ref->get_subrefs();
5614 t_ass = ref->get_refd_assignment();
5615
5616 if (!t_ass) {
5617 error("Could not determine the assignment for second parameter");
5618 goto error;
5619 }
5620 // Extra check for HM59355.
5621 switch (t_ass->get_asstype()) {
5622 case Assignment::A_VAR:
5623 case Assignment::A_PAR_VAL_IN:
5624 case Assignment::A_PAR_VAL_OUT:
5625 case Assignment::A_PAR_VAL_INOUT:
5626 break;
5627 default:
5628 ref->error("Reference to '%s' cannot be used.", t_ass->get_assname());
5629 goto error;
5630 }
5631 t_type = t_ass->get_Type()->get_field_type(t_subrefs,
5632 Type::EXPECTED_DYNAMIC_VALUE);
5633 if (!t_type) {
5634 goto error;
5635 }
5636 t_type = t_type->get_type_refd_last();
5637 switch (t_type->get_typetype()) {
5638 case Type::T_UNDEF:
5639 case Type::T_ERROR:
5640 case Type::T_NULL:
5641 case Type::T_REFD:
5642 case Type::T_REFDSPEC:
5643 case Type::T_SELTYPE:
5644 case Type::T_VERDICT:
5645 case Type::T_PORT:
5646 case Type::T_COMPONENT:
5647 case Type::T_DEFAULT:
5648 case Type::T_SIGNATURE:
5649 case Type::T_FUNCTION:
5650 case Type::T_ALTSTEP:
5651 case Type::T_TESTCASE:
5652 error("Type of second parameter cannot be %s",
5653 t_type->get_typename().c_str());
5654 goto error;
5655 default:
5656 break;
5657 }
5658
5659 if(!disable_attribute_validation()) {
5660 t_type->chk_coding(false);
5661 }
5662
5663 return;
5664 error:
5665 set_valuetype(V_ERROR);
5666 }
5667
5668 void Value::chk_expr_omit_comparison(Type::expected_value_t exp_val)
5669 {
5670 Ttcn::FieldOrArrayRefs *subrefs;
5671 Identifier *field_id = 0;
5672 Assignment *t_ass;
5673 Type *t_type;
5674 if (valuetype == V_ERROR) return;
5675 else if (valuetype != V_REFD) {
5676 error("Only a referenced value can be compared with `omit'");
5677 goto error;
5678 }
5679 subrefs = u.ref.ref->get_subrefs();
5680 if (subrefs) field_id = subrefs->remove_last_field();
5681 if (!field_id) {
5682 error("Only a reference pointing to an optional record or set field "
5683 "can be compared with `omit'");
5684 goto error;
5685 }
5686 t_ass = u.ref.ref->get_refd_assignment();
5687 if (!t_ass) goto error;
5688 t_type = t_ass->get_Type()->get_field_type(subrefs, exp_val);
5689 if (!t_type) goto error;
5690 t_type = t_type->get_type_refd_last();
5691 switch (t_type->get_typetype()) {
5692 case Type::T_ERROR:
5693 goto error;
5694 case Type::T_SEQ_A:
5695 case Type::T_SEQ_T:
5696 case Type::T_SET_A:
5697 case Type::T_SET_T:
5698 break;
5699 default:
5700 error("Only a reference pointing to an optional field of a record"
5701 " or set type can be compared with `omit'");
5702 goto error;
5703 }
5704 if (!t_type->has_comp_withName(*field_id)) {
5705 error("Type `%s' does not have field named `%s'",
5706 t_type->get_typename().c_str(), field_id->get_dispname().c_str());
5707 goto error;
5708 } else if (!t_type->get_comp_byName(*field_id)->get_is_optional()) {
5709 error("Field `%s' is mandatory in type `%s'. It cannot be compared with "
5710 "`omit'", field_id->get_dispname().c_str(),
5711 t_type->get_typename().c_str());
5712 goto error;
5713 }
5714 // putting the last field_id back to subrefs
5715 subrefs->add(new Ttcn::FieldOrArrayRef(field_id));
5716 return;
5717 error:
5718 set_valuetype(V_ERROR);
5719 delete field_id;
5720 }
5721
5722 Int Value::chk_eval_expr_sizeof(ReferenceChain *refch,
5723 Type::expected_value_t exp_val)
5724 {
5725 if(valuetype==V_ERROR) return -1;
5726 if(u.expr.state==EXPR_CHECKING_ERR) return -1;
5727 if(exp_val==Type::EXPECTED_DYNAMIC_VALUE)
5728 exp_val=Type::EXPECTED_TEMPLATE;
5729
5730 Error_Context cntxt(this, "In the operand of"
5731 " operation `%s'", get_opname());
5732
5733 Int result = -1;
5734 Template* t_templ = u.expr.ti1->get_Template();
5735
5736 if (!t_templ) {
5737 FATAL_ERROR("chk_eval_expr_sizeof()\n");
5738 }
5739
5740 t_templ = t_templ->get_template_refd_last(refch);
5741
5742 // Timer and port arrays are handled separately
5743 if (t_templ->get_templatetype() == Template::SPECIFIC_VALUE) {
5744 Value* val = t_templ->get_specific_value();
5745 if (val->get_valuetype() == V_UNDEF_LOWERID) {
5746 val->set_lowerid_to_ref();
5747 }
5748 if (val && val->get_valuetype() == V_REFD) {
5749 Reference* ref = val->get_reference();
5750 Assignment* t_ass = ref->get_refd_assignment();
5751 Common::Assignment::asstype_t asstype =
5752 t_ass ? t_ass->get_asstype() : Assignment::A_ERROR;
5753 if (asstype == Assignment::A_PORT || asstype == Assignment::A_TIMER) {
5754 if (t_ass->get_Dimensions()) {
5755 // here we have a timer or port array
5756 Ttcn::FieldOrArrayRefs* t_subrefs = ref->get_subrefs();
5757 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5758 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5759 Type::EXPECTED_DYNAMIC_VALUE);
5760 size_t refd_dim;
5761 if (t_subrefs) {
5762 refd_dim = t_subrefs->get_nof_refs();
5763 size_t nof_dims = t_dims->get_nof_dims();
5764 if (refd_dim >= nof_dims) {
5765 u.expr.ti1->error("Operation is not applicable to a %s",
5766 t_ass->get_assname());
5767 set_valuetype(V_ERROR);
5768 return -1;
5769 }
5770 } else refd_dim = 0;
5771 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5772 } else {
5773 u.expr.ti1->error("Operation is not applicable to single `%s'",
5774 t_ass->get_description().c_str());
5775 set_valuetype(V_ERROR);
5776 return -1;
5777 }
5778 }
5779 }
5780 }
5781
5782 Value* t_val = 0;
5783 Type* t_type = 0;
5784 Assignment* t_ass = 0;
5785 Reference* ref = 0;
5786 Ttcn::FieldOrArrayRefs* t_subrefs = 0;
5787 t_type = chk_expr_operands_ti(u.expr.ti1, exp_val);
5788 if (t_type) {
5789 chk_expr_eval_ti(u.expr.ti1, t_type, refch, exp_val);
5790 t_type = t_type->get_type_refd_last();
5791 } else {
5792 error("Cannot determine type of value");
5793 goto error;
5794 }
5795
5796 if(valuetype==V_ERROR) return -1;
5797
5798 t_templ = t_templ->get_template_refd_last(refch);
5799 switch(t_templ->get_templatetype()) {
5800 case Template::TEMPLATE_ERROR:
5801 goto error;
5802 case Template::INDEXED_TEMPLATE_LIST:
5803 return -1;
5804 case Template::TEMPLATE_REFD:
5805 case Template::TEMPLATE_LIST:
5806 case Template::NAMED_TEMPLATE_LIST:
5807 // computed later
5808 break;
5809 case Template::SPECIFIC_VALUE:
5810 {
5811 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
5812 if(t_val) {
5813 switch(t_val->get_valuetype()) {
5814 case V_SEQOF:
5815 case V_SETOF:
5816 case V_ARRAY:
5817 case V_ROID:
5818 case V_OID:
5819 case V_SEQ:
5820 case V_SET:
5821 break;
5822 case V_REFD: {
5823 ref = t_val->get_reference();
5824 t_ass = ref->get_refd_assignment();
5825 t_subrefs = ref->get_subrefs();
5826 break;
5827 }
5828 default:
5829 u.expr.ti1->error("Operation is not applicable to `%s'",
5830 t_val->create_stringRepr().c_str());
5831 goto error;
5832 }
5833 }
5834 break;
5835 }
5836 default:
5837 u.expr.ti1->error("Operation is not applicable to %s `%s'",
5838 t_templ->get_templatetype_str(), t_templ->get_fullname().c_str());
5839 goto error;
5840 } // switch
5841
5842 if (t_ass) {
5843 switch(t_ass->get_asstype()) {
5844 case Assignment::A_ERROR:
5845 goto error;
5846 case Assignment::A_CONST:
5847 t_val = t_ass->get_Value();
5848 break;
5849 case Assignment::A_EXT_CONST:
5850 case Assignment::A_MODULEPAR:
5851 case Assignment::A_MODULEPAR_TEMP:
5852 if(exp_val==Type::EXPECTED_CONSTANT) {
51fa56b9 5853 u.expr.ti1->error("Reference to an (evaluable) constant value was "
970ed795
EL
5854 "expected instead of %s", t_ass->get_description().c_str());
5855 goto error;
5856 }
5857 break;
5858 case Assignment::A_VAR:
5859 case Assignment::A_PAR_VAL_IN:
5860 case Assignment::A_PAR_VAL_OUT:
5861 case Assignment::A_PAR_VAL_INOUT:
5862 switch(exp_val) {
5863 case Type::EXPECTED_CONSTANT:
5864 u.expr.ti1->error("Reference to a constant value was expected instead of %s",
5865 t_ass->get_description().c_str());
5866 goto error;
5867 break;
5868 case Type::EXPECTED_STATIC_VALUE:
5869 u.expr.ti1->error("Reference to a static value was expected instead of %s",
5870 t_ass->get_description().c_str());
5871 goto error;
5872 break;
5873 default:
5874 break;
5875 }
5876 break;
5877 case Assignment::A_TEMPLATE:
5878 t_templ = t_ass->get_Template();
5879 // no break
5880 case Assignment::A_VAR_TEMPLATE:
5881 case Assignment::A_PAR_TEMPL_IN:
5882 case Assignment::A_PAR_TEMPL_OUT:
5883 case Assignment::A_PAR_TEMPL_INOUT:
5884 if (exp_val!=Type::EXPECTED_TEMPLATE)
5885 u.expr.ti1->error("Reference to a value was expected instead of %s",
5886 t_ass->get_description().c_str());
5887 goto error;
5888 break;
5889 case Assignment::A_FUNCTION_RVAL:
5890 case Assignment::A_EXT_FUNCTION_RVAL:
5891 switch(exp_val) {
5892 case Type::EXPECTED_CONSTANT:
5893 u.expr.ti1->error("Reference to a constant value was expected instead of "
5894 "the return value of %s", t_ass->get_description().c_str());
5895 goto error;
5896 break;
5897 case Type::EXPECTED_STATIC_VALUE:
5898 u.expr.ti1->error("Reference to a static value was expected instead of "
5899 "the return value of %s", t_ass->get_description().c_str());
5900 goto error;
5901 break;
5902 default:
5903 break;
5904 }
5905 break;
5906 case Assignment::A_FUNCTION_RTEMP:
5907 case Assignment::A_EXT_FUNCTION_RTEMP:
5908 if(exp_val!=Type::EXPECTED_TEMPLATE)
5909 u.expr.ti1->error("Reference to a value was expected instead of a call"
5910 " of %s, which returns a template",
5911 t_ass->get_description().c_str());
5912 goto error;
5913 break;
5914 case Assignment::A_TIMER:
5915 case Assignment::A_PORT:
5916 if (u.expr.v_optype == OPTYPE_SIZEOF) {
5917 // sizeof is applicable to timer and port arrays
5918 Ttcn::ArrayDimensions *t_dims = t_ass->get_Dimensions();
5919 if (!t_dims) {
5920 u.expr.ti1->error("Operation is not applicable to single %s",
5921 t_ass->get_description().c_str());
5922 goto error;
5923 }
5924 t_dims->chk_indices(ref, t_ass->get_assname(), true,
5925 Type::EXPECTED_DYNAMIC_VALUE);
5926 size_t refd_dim;
5927 if (t_subrefs) {
5928 refd_dim = t_subrefs->get_nof_refs();
5929 size_t nof_dims = t_dims->get_nof_dims();
5930 if (refd_dim > nof_dims) goto error;
5931 else if (refd_dim == nof_dims) {
5932 u.expr.ti1->error("Operation is not applicable to a %s",
5933 t_ass->get_assname());
5934 goto error;
5935 }
5936 } else refd_dim = 0;
5937 return t_dims->get_dim_byIndex(refd_dim)->get_size();
5938 }
5939 // no break
5940 default:
5941 u.expr.ti1->error("Reference to a %s was expected instead of %s",
5942 exp_val == Type::EXPECTED_TEMPLATE ? "value or template" : "value",
5943 t_ass->get_description().c_str());
5944 goto error;
5945 } // end switch
5946
5947 t_type = t_ass->get_Type()->get_field_type(t_subrefs, exp_val);
5948 if (!t_type) goto error;
5949 t_type = t_type->get_type_refd_last();
5950
5951 switch(t_type->get_typetype()) {
5952 case Type::T_ERROR:
5953 goto error;
5954 case Type::T_SEQOF:
5955 case Type::T_SETOF:
5956 // no break
5957 case Type::T_SEQ_T:
5958 case Type::T_SET_T:
5959 case Type::T_SEQ_A:
5960 case Type::T_SET_A:
5961 case Type::T_ARRAY:
5962 // ok
5963 break;
5964 case Type::T_OID:
5965 case Type::T_ROID:
5966 break;
5967 default:
5968 u.expr.ti1->error("Reference to value or template of type record, record of,"
5969 " set, set of, objid or array was expected");
5970 goto error;
5971 } // switch
5972 }
5973
5974 // check for index overflows in subrefs if possible
5975 if (t_val) {
5976 switch (t_val->get_valuetype()) {
5977 case V_SEQOF:
5978 case V_SETOF:
5979 case V_ARRAY:
5980 if (t_val->is_indexed()) {
5981 return -1;
5982 }
5983 break;
5984 default:
5985 break;
5986 }
5987 /* The reference points to a constant. */
5988 if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
5989 t_val = t_val->get_refd_sub_value(t_subrefs, 0, false, refch);
5990 if (!t_val) goto error;
5991 t_val=t_val->get_value_refd_last(refch);
5992 } else { t_val = 0; }
5993 } else if (t_templ) {
5994 /* The size of INDEXED_TEMPLATE_LIST nodes is unknown at compile
5995 time. Don't try to evaluate it at compile time. */
5996 if (t_templ->get_templatetype() == Template::INDEXED_TEMPLATE_LIST) {
5997 return -1;
5998 /* The reference points to a static template. */
5999 } else if (!t_subrefs || !t_subrefs->has_unfoldable_index()) {
6000 t_templ = t_templ->get_refd_sub_template(t_subrefs, ref && ref->getUsedInIsbound(), refch);
6001 if (!t_templ) goto error;
6002 t_templ = t_templ->get_template_refd_last(refch);
6003 } else { t_templ = 0; }
6004 }
6005
6006 if(u.expr.v_optype==OPTYPE_SIZEOF) {
6007 if(t_templ) {
6008 switch(t_templ->get_templatetype()) {
6009 case Template::TEMPLATE_ERROR:
6010 goto error;
6011 case Template::TEMPLATE_REFD:
6012 // not foldable
6013 t_templ=0;
6014 break;
6015 case Template::SPECIFIC_VALUE:
6016 t_val=t_templ->get_specific_value()->get_value_refd_last(refch);
6017 t_templ=0;
6018 break;
6019 case Template::TEMPLATE_LIST:
6020 case Template::NAMED_TEMPLATE_LIST:
6021 break;
6022 default:
6023 u.expr.ti1->error("Operation is not applicable to %s `%s'",
6024 t_templ->get_templatetype_str(),
6025 t_templ->get_fullname().c_str());
6026 goto error;
6027 } // switch
6028 }
6029 if(t_val) {
6030 switch(t_val->get_valuetype()) {
6031 case V_SEQOF:
6032 case V_SETOF:
6033 case V_ARRAY:
6034 case V_SEQ:
6035 case V_SET:
6036 case V_OID:
6037 case V_ROID:
6038 // ok
6039 break;
6040 default:
6041 // error is already reported
6042 t_val=0;
6043 break;
6044 } // switch
6045 }
6046 }
6047
6048 /* evaluation */
6049
6050 if(t_type->get_typetype()==Type::T_ARRAY) {
6051 result = t_type->get_dimension()->get_size();
6052 }
6053 else if(t_templ) { // sizeof()
6054 switch(t_templ->get_templatetype()) {
6055 case Template::TEMPLATE_LIST:
6056 if(t_templ->temps_contains_anyornone_symbol()) {
6057 if(t_templ->is_length_restricted()) {
6058 Ttcn::LengthRestriction *lr = t_templ->get_length_restriction();
6059 if (lr->get_is_range()) {
6060 Value *v_upper = lr->get_upper_value();
6061 if (v_upper) {
6062 if (v_upper->valuetype == V_INT) {
6063 Int nof_comps =
6064 static_cast<Int>(t_templ->get_nof_comps_not_anyornone());
6065 if (v_upper->u.val_Int->get_val() == nof_comps)
6066 result = nof_comps;
6067 else {
6068 u.expr.ti1->error("`sizeof' operation is not applicable for "
6069 "templates without exact size");
6070 goto error;
6071 }
6072 }
6073 } else {
6074 u.expr.ti1->error("`sizeof' operation is not applicable for "
6075 "templates containing `*' without upper boundary in the "
6076 "length restriction");
6077 goto error;
6078 }
6079 } else {
6080 Value *v_single = lr->get_single_value();
6081 if (v_single->valuetype == V_INT)
6082 result = v_single->u.val_Int->get_val();
6083 }
6084 }
6085 else { // not length restricted
6086 u.expr.ti1->error("`sizeof' operation is not applicable for templates"
6087 " containing `*' without length restriction");
6088 goto error;
6089 }
6090 }
6091 else result=t_templ->get_nof_listitems();
6092 break;
6093 case Template::NAMED_TEMPLATE_LIST:
6094 result=0;
6095 for(size_t i=0; i<t_templ->get_nof_comps(); i++)
6096 if(t_templ->get_namedtemp_byIndex(i)->get_template()
6097 ->get_templatetype()!=Template::OMIT_VALUE) result++;
6098 return result;
6099 default:
6100 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6101 } // switch
6102 }
6103 else if(t_val) {
6104 switch(t_val->get_valuetype()) {
6105 case V_SEQOF:
6106 case V_SETOF:
6107 case V_ARRAY:
6108
6109 case V_OID:
6110 case V_ROID:
6111 result=t_val->get_nof_comps();
6112 break;
6113 case V_SEQ:
6114 case V_SET:
6115 result=0;
6116 for(size_t i=0; i<t_val->get_nof_comps(); i++)
6117 if(t_val->get_se_comp_byIndex(i)->get_value()
6118 ->get_valuetype()!=V_OMIT) result++;
6119 break;
6120
6121 default:
6122 FATAL_ERROR("Value::chk_eval_expr_sizeof()");
6123 } // switch
6124 }
6125
6126 return result;
6127 error:
6128 set_valuetype(V_ERROR);
6129 return -1;
6130 }
6131
6132 Type *Value::chk_expr_operands_ti(TemplateInstance* ti, Type::expected_value_t exp_val)
6133 {
6134 Type *governor = ti->get_expr_governor(exp_val);
6135 if (!governor) {
6136 ti->get_Template()->set_lowerid_to_ref();
6137 governor = ti->get_expr_governor(exp_val);
6138 }
6139 if (!governor) {
6140 string str;
6141 ti->append_stringRepr( str);
feade998 6142 ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
6143 "If type is known, use valueof(<type>: %s) as argument.",
970ed795
EL
6144 str.c_str(), get_opname(), str.c_str());
6145 set_valuetype(V_ERROR);
6146 }
6147 return governor;
6148 }
6149
6150 void Value::chk_expr_operands_match(Type::expected_value_t exp_val)
6151 {
6152 start:
6153 Type *governor = u.expr.v1->get_expr_governor(exp_val);
6154 if (!governor) governor = u.expr.t2->get_expr_governor(
6155 exp_val == Type::EXPECTED_DYNAMIC_VALUE ?
6156 Type::EXPECTED_TEMPLATE : exp_val);
6157 if (!governor) {
6158 Template *t_temp = u.expr.t2->get_Template();
6159 if (t_temp->is_undef_lowerid()) {
6160 // We convert the template to reference first even if the value is also
6161 // an undef lowerid. The user can prevent this by explicit type
6162 // specification.
6163 t_temp->set_lowerid_to_ref();
6164 goto start;
6165 } else if (u.expr.v1->is_undef_lowerid()) {
6166 u.expr.v1->set_lowerid_to_ref();
6167 goto start;
6168 }
6169 }
6170 if (!governor) {
6171 error("Cannot determine the type of arguments in `match()' operation");
6172 set_valuetype(V_ERROR);
6173 return;
6174 }
6175 u.expr.v1->set_my_governor(governor);
6176 {
6177 Error_Context cntxt(this, "In the first argument of `match()'"
6178 " operation");
6179 governor->chk_this_value_ref(u.expr.v1);
6180 (void)governor->chk_this_value(u.expr.v1, 0, exp_val,
6181 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6182 }
6183 {
6184 Error_Context cntxt(this, "In the second argument of `match()' "
6185 "operation");
6186 u.expr.t2->chk(governor);
6187 }
6188 }
6189
6190 void Value::chk_expr_dynamic_part(Type::expected_value_t exp_val,
6191 bool allow_controlpart, bool allow_runs_on, bool require_runs_on)
6192 {
6193 Ttcn::StatementBlock *my_sb;
6194 switch (exp_val) {
6195 case Type::EXPECTED_CONSTANT:
51fa56b9 6196 error("An evaluable constant value was expected instead of operation "
970ed795
EL
6197 "`%s'", get_opname());
6198 goto error;
6199 case Type::EXPECTED_STATIC_VALUE:
6200 error("A static value was expected instead of operation `%s'",
6201 get_opname());
6202 goto error;
6203 default:
6204 break;
6205 } // switch
6206 if (!my_scope) FATAL_ERROR("Value::chk_expr_dynamic_part()");
6207 my_sb = dynamic_cast<Ttcn::StatementBlock*>(my_scope);
6208 if (!my_sb) {
6209 error("Operation `%s' is allowed only within statements",
6210 get_opname());
6211 goto error;
6212 }
6213 if (!allow_controlpart && !my_sb->get_my_def()) {
6214 error("Operation `%s' is not allowed in the control part",
6215 get_opname());
6216 goto error;
6217 }
6218 if (!allow_runs_on && my_scope->get_scope_runs_on()) {
6219 error("Operation `%s' cannot be used in a definition that has "
6220 "`runs on' clause", get_opname());
6221 goto error;
6222 }
6223 if (require_runs_on && !my_scope->get_scope_runs_on()) {
6224 error("Operation `%s' can be used only in a definition that has "
6225 "`runs on' clause", get_opname());
6226 goto error;
6227 }
6228 return;
6229 error:
6230 set_valuetype(V_ERROR);
6231 }
6232
6233 void Value::chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname)
6234 {
6235 if(valuetype==V_ERROR) return;
6236 if(u.expr.state==EXPR_CHECKING_ERR) return;
6237 if(v->is_unfoldable()) return;
6238 if(v->get_expr_returntype()!=Type::T_REAL) return;
6239 ttcn3float r = v->get_val_Real();
6240 if (isSpecialFloatValue(r)) {
6241 v->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
6242 opnum, opname, Real2string(r).c_str());
6243 set_valuetype(V_ERROR);
6244 }
6245 }
6246
6247 void Value::chk_expr_operands(ReferenceChain *refch,
6248 Type::expected_value_t exp_val)
6249 {
6250 const char *first="First", *second="Second", *third="Third",
6251 *fourth="Fourth", *the="The", *left="Left", *right="Right";
6252 Value *v1, *v2, *v3;
6253 Type::typetype_t tt1, tt2, tt3;
6254 Type t_chk(Type::T_ERROR);
6255
6256 const char *opname=get_opname();
6257
6258 // first classify the unchecked ischosen() operation
6259 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
6260
6261 switch (u.expr.v_optype) {
6262 case OPTYPE_COMP_NULL:
6263 case OPTYPE_TESTCASENAME:
a38c6d4c 6264 case OPTYPE_PROF_RUNNING:
970ed795
EL
6265 break;
6266 case OPTYPE_COMP_MTC:
6267 case OPTYPE_COMP_SYSTEM:
6268 chk_expr_comptype_compat();
6269 break;
6270 case OPTYPE_RND: // -
6271 case OPTYPE_TMR_RUNNING_ANY:
6272 chk_expr_dynamic_part(exp_val, true);
6273 break;
6274 case OPTYPE_COMP_RUNNING_ANY:
6275 case OPTYPE_COMP_RUNNING_ALL:
6276 case OPTYPE_COMP_ALIVE_ANY:
6277 case OPTYPE_COMP_ALIVE_ALL:
6278 case OPTYPE_GETVERDICT:
6279 chk_expr_dynamic_part(exp_val, false);
6280 break;
6281 case OPTYPE_COMP_SELF:
6282 chk_expr_comptype_compat();
6283 chk_expr_dynamic_part(exp_val, false, true, false);
6284 break;
6285 case OPTYPE_UNARYPLUS: // v1
6286 case OPTYPE_UNARYMINUS:
6287 v1=u.expr.v1;
6288 {
6289 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6290 v1->set_lowerid_to_ref();
6291 tt1=v1->get_expr_returntype(exp_val);
6292 chk_expr_operandtype_int_float(tt1, the, opname, v1);
6293 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6294 }
6295 break;
6296 case OPTYPE_NOT:
6297 v1=u.expr.v1;
6298 {
6299 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6300 v1->set_lowerid_to_ref();
6301 tt1=v1->get_expr_returntype(exp_val);
6302 chk_expr_operandtype_bool(tt1, the, opname, v1);
6303 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6304 }
6305 break;
6306 case OPTYPE_NOT4B:
6307 v1=u.expr.v1;
6308 {
6309 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6310 v1->set_lowerid_to_ref();
6311 tt1=v1->get_expr_returntype(exp_val);
6312 chk_expr_operandtype_binstr(tt1, the, opname, v1);
6313 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6314 }
6315 break;
6316 case OPTYPE_BIT2HEX:
6317 case OPTYPE_BIT2OCT:
6318 case OPTYPE_BIT2STR:
6319 v1=u.expr.v1;
6320 {
6321 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6322 v1->set_lowerid_to_ref();
6323 tt1=v1->get_expr_returntype(exp_val);
6324 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6325 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6326 }
6327 break;
6328 case OPTYPE_BIT2INT:
6329 v1=u.expr.v1;
6330 {
6331 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6332 v1->set_lowerid_to_ref();
6333 tt1=v1->get_expr_returntype(exp_val);
6334 chk_expr_operandtype_bstr(tt1, the, opname, v1);
6335 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6336 // Skip `chk_expr_val_bitstr_intsize(v1, the, opname);'.
6337 }
6338 break;
6339 case OPTYPE_CHAR2INT:
6340 v1=u.expr.v1;
6341 {
6342 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6343 v1->set_lowerid_to_ref();
6344 tt1=v1->get_expr_returntype(exp_val);
6345 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6346 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6347 chk_expr_val_len1(v1, the, opname);
6348 }
6349 break;
6350 case OPTYPE_CHAR2OCT:
6351 v1=u.expr.v1;
6352 {
6353 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6354 v1->set_lowerid_to_ref();
6355 tt1=v1->get_expr_returntype(exp_val);
6356 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6357 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6358 }
6359 break;
6360 case OPTYPE_STR2INT:
6361 v1=u.expr.v1;
6362 {
6363 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6364 v1->set_lowerid_to_ref();
6365 tt1=v1->get_expr_returntype(exp_val);
6366 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6367 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6368 chk_expr_val_str_int(v1, the, opname);
6369 }
6370 break;
6371 case OPTYPE_STR2FLOAT:
6372 v1=u.expr.v1;
6373 {
6374 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6375 v1->set_lowerid_to_ref();
6376 tt1=v1->get_expr_returntype(exp_val);
6377 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6378 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6379 chk_expr_val_str_float(v1, the, opname);
6380 }
6381 break;
6382 case OPTYPE_STR2BIT:
6383 v1=u.expr.v1;
6384 {
6385 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6386 v1->set_lowerid_to_ref();
6387 tt1=v1->get_expr_returntype(exp_val);
6388 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6389 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6390 chk_expr_val_str_bindigits(v1, the, opname);
6391 }
6392 break;
6393 case OPTYPE_STR2HEX:
6394 v1=u.expr.v1;
6395 {
6396 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6397 v1->set_lowerid_to_ref();
6398 tt1=v1->get_expr_returntype(exp_val);
6399 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6400 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6401 chk_expr_val_str_hexdigits(v1, the, opname);
6402 }
6403 break;
6404 case OPTYPE_STR2OCT:
6405 v1=u.expr.v1;
6406 {
6407 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6408 v1->set_lowerid_to_ref();
6409 tt1=v1->get_expr_returntype(exp_val);
6410 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6411 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6412 chk_expr_val_str_len_even(v1, the, opname);
6413 chk_expr_val_str_hexdigits(v1, the, opname);
6414 }
6415 break;
6416 case OPTYPE_ENUM2INT:
6417 v1=u.expr.v1;
6418 {
6419 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6420 chk_expr_operandtype_enum(opname, v1, exp_val);
6421 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6422 }
6423 break;
6424 case OPTYPE_ENCODE:
6425 chk_expr_operand_encode(refch, exp_val);
6426 break;
6427 case OPTYPE_FLOAT2INT:
6428 case OPTYPE_FLOAT2STR:
6429 v1=u.expr.v1;
6430 {
6431 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6432 v1->set_lowerid_to_ref();
6433 tt1=v1->get_expr_returntype(exp_val);
6434 chk_expr_operandtype_float(tt1, the, opname, v1);
6435 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6436 if (u.expr.v_optype==OPTYPE_FLOAT2INT)
6437 chk_expr_operand_valid_float(v1, the, opname);
6438 }
6439 break;
6440 case OPTYPE_RNDWITHVAL:
6441 v1=u.expr.v1;
6442 {
6443 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6444 v1->set_lowerid_to_ref();
6445 tt1=v1->get_expr_returntype(exp_val);
6446 chk_expr_operandtype_float(tt1, the, opname, v1);
6447 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6448 chk_expr_operand_valid_float(v1, the, opname);
6449 }
6450 chk_expr_dynamic_part(exp_val, true);
6451 break;
6452 case OPTYPE_HEX2BIT:
6453 case OPTYPE_HEX2OCT:
6454 case OPTYPE_HEX2STR:
6455 v1=u.expr.v1;
6456 {
6457 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6458 v1->set_lowerid_to_ref();
6459 tt1=v1->get_expr_returntype(exp_val);
6460 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6461 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6462 }
6463 break;
6464 case OPTYPE_HEX2INT:
6465 v1=u.expr.v1;
6466 {
6467 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6468 v1->set_lowerid_to_ref();
6469 tt1=v1->get_expr_returntype(exp_val);
6470 chk_expr_operandtype_hstr(tt1, the, opname, v1);
6471 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6472 // Skip `chk_expr_val_hexstr_intsize(v1, the, opname);'.
6473 }
6474 break;
6475 case OPTYPE_INT2CHAR:
6476 v1=u.expr.v1;
6477 {
6478 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6479 v1->set_lowerid_to_ref();
6480 tt1=v1->get_expr_returntype(exp_val);
6481 chk_expr_operandtype_int(tt1, the, opname, v1);
6482 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6483 chk_expr_val_int_pos7bit(v1, the, opname);
6484 }
6485 break;
6486 case OPTYPE_INT2UNICHAR:
6487 v1=u.expr.v1;
6488 {
6489 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6490 v1->set_lowerid_to_ref();
6491 tt1=v1->get_expr_returntype(exp_val);
6492 chk_expr_operandtype_int(tt1, the, opname, v1);
6493 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6494 chk_expr_val_int_pos31bit(v1, first, opname);
6495 }
6496 break;
6497 case OPTYPE_INT2FLOAT:
6498 case OPTYPE_INT2STR:
6499 v1=u.expr.v1;
6500 {
6501 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6502 v1->set_lowerid_to_ref();
6503 tt1=v1->get_expr_returntype(exp_val);
6504 chk_expr_operandtype_int(tt1, the, opname, v1);
6505 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6506 }
6507 break;
6508 case OPTYPE_OCT2BIT:
6509 case OPTYPE_OCT2HEX:
6510 case OPTYPE_OCT2STR:
6511 v1=u.expr.v1;
6512 {
6513 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6514 v1->set_lowerid_to_ref();
6515 tt1=v1->get_expr_returntype(exp_val);
6516 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6517 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6518 }
6519 break;
6520 case OPTYPE_OCT2INT:
6521 v1=u.expr.v1;
6522 {
6523 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6524 v1->set_lowerid_to_ref();
6525 tt1=v1->get_expr_returntype(exp_val);
6526 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6527 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6528 // Simply skip `chk_expr_val_hexstr_intsize(v1, the, opname);' for
6529 // now.
6530 }
6531 break;
6532 case OPTYPE_OCT2CHAR:
6533 v1=u.expr.v1;
6534 {
6535 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6536 v1->set_lowerid_to_ref();
6537 tt1=v1->get_expr_returntype(exp_val);
6538 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6539 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6540 chk_expr_val_str_7bitoctets(v1, the, opname);
6541 }
6542 break;
6543 case OPTYPE_REMOVE_BOM:
6544 v1=u.expr.v1;
6545 {
6546 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6547 v1->set_lowerid_to_ref();
6548 tt1=v1->get_expr_returntype(exp_val);
6549 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6550 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6551 }
6552 break;
6553 case OPTYPE_GET_STRINGENCODING:
6554 v1=u.expr.v1;
6555 {
6556 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6557 v1->set_lowerid_to_ref();
6558 tt1=v1->get_expr_returntype(exp_val);
6559 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6560 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6561 }
6562 break;
6563 case OPTYPE_ENCODE_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_ostr(tt1, the, opname, v1);
6570 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6571 }
6572 v2=u.expr.v2 ? u.expr.v2 : 0;
6573 if (v2)
6574 {
6575 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6576 v2->set_lowerid_to_ref();
6577 tt2=v2->get_expr_returntype(exp_val);
6578 chk_expr_operandtype_bool(tt2, second, opname, v2);
6579 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6580 }
6581 break;
6582 case OPTYPE_DECODE_BASE64:
6583 v1=u.expr.v1;
6584 {
6585 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6586 v1->set_lowerid_to_ref();
6587 tt1=v1->get_expr_returntype(exp_val);
6588 chk_expr_operandtype_cstr(tt1, the, opname, v1);
6589 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6590 }
6591 break;
6592 case OPTYPE_UNICHAR2INT:
6593 v1=u.expr.v1;
6594 {
6595 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6596 v1->set_lowerid_to_ref();
6597 tt1=v1->get_expr_returntype(exp_val);
6598 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6599 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6600 chk_expr_val_len1(v1, the, opname);
6601 }
6602 break;
6603 case OPTYPE_UNICHAR2CHAR:
6604 v1=u.expr.v1;
6605 {
6606 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6607 v1->set_lowerid_to_ref();
6608 tt1=v1->get_expr_returntype(exp_val);
6609 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6610 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6611 chk_expr_val_ustr_7bitchars(v1, the, opname);
6612 }
6613 break;
efbe586d 6614 case OPTYPE_HOSTID:
6615 v1=u.expr.v1 ? u.expr.v1 : 0;
6616 if (v1)
6617 {
6618 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6619 v1->set_lowerid_to_ref();
6620 tt1=v1->get_expr_returntype(exp_val);
6621 chk_expr_operandtype_cstr(tt1, second, opname, v1);
6622 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6623 }
6624 break;
970ed795
EL
6625 case OPTYPE_UNICHAR2OCT: // v1 [v2]
6626 v1=u.expr.v1;
6627 {
6628 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6629 v1->set_lowerid_to_ref();
6630 tt1=v1->get_expr_returntype(exp_val);
6631 chk_expr_operandtype_charstr(tt1, the, opname, v1);
6632 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6633 }
6634 v2=u.expr.v2 ? u.expr.v2 : 0;
6635 if (v2)
6636 {
6637 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6638 v2->set_lowerid_to_ref();
6639 tt2=v2->get_expr_returntype(exp_val);
6640 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6641 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6642 }
6643 break;
6644 case OPTYPE_OCT2UNICHAR: // v1 [v2]
6645 v1=u.expr.v1;
6646 {
6647 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
6648 v1->set_lowerid_to_ref();
6649 tt1=v1->get_expr_returntype(exp_val);
6650 chk_expr_operandtype_ostr(tt1, the, opname, v1);
6651 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6652 }
6653 v2=u.expr.v2 ? u.expr.v2 : 0;
6654 if (v2)
6655 {
6656 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6657 v2->set_lowerid_to_ref();
6658 tt2=v2->get_expr_returntype(exp_val);
6659 chk_expr_operandtype_cstr(tt2, second, opname, v2);
6660 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6661 }
6662 break;
1d0599f0 6663 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
6664 chk_expr_operand_encode(refch, exp_val);
6665 v2=u.expr.v2 ? u.expr.v2 : 0;
6666 if (v2)
6667 {
6668 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6669 v2->set_lowerid_to_ref();
6670 tt2=v2->get_expr_returntype(exp_val);
6671 chk_expr_operandtype_charstr(tt2, second, opname, v2);
6672 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6673 }
6674 break;
6675 case OPTYPE_DECVALUE_UNICHAR:
6676 chk_expr_operands_decode(OPTYPE_DECVALUE_UNICHAR);
6677 v3=u.expr.v3 ? u.expr.v3 : 0;
6678 if (v3)
6679 {
6680 Error_Context cntxt(this, "In the thrid operand of operation `%s'", opname);
6681 v3->set_lowerid_to_ref();
6682 tt3=v3->get_expr_returntype(exp_val);
6683 chk_expr_operandtype_charstr(tt3, third, opname, v3);
6684 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6685 }
6686 break;
970ed795
EL
6687 case OPTYPE_ADD: // v1 v2
6688 case OPTYPE_SUBTRACT:
6689 case OPTYPE_MULTIPLY:
6690 case OPTYPE_DIVIDE:
6691 v1=u.expr.v1;
6692 {
6693 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6694 v1->set_lowerid_to_ref();
6695 tt1=v1->get_expr_returntype(exp_val);
6696 chk_expr_operandtype_int_float(tt1, first, opname, v1);
6697 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6698 chk_expr_operand_valid_float(v1, first, opname);
6699 }
6700 v2=u.expr.v2;
6701 {
6702 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6703 v2->set_lowerid_to_ref();
6704 tt2=v2->get_expr_returntype(exp_val);
6705 chk_expr_operandtype_int_float(tt2, second, opname, v2);
6706 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6707 chk_expr_operand_valid_float(v2, second, opname);
6708 if(u.expr.v_optype==OPTYPE_DIVIDE)
6709 chk_expr_val_int_float_not0(v2, second, opname);
6710 }
6711 chk_expr_operandtypes_same(tt1, tt2, opname);
6712 break;
6713 case OPTYPE_MOD:
6714 case OPTYPE_REM:
6715 v1=u.expr.v1;
6716 {
6717 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6718 v1->set_lowerid_to_ref();
6719 tt1=v1->get_expr_returntype(exp_val);
6720 chk_expr_operandtype_int(tt1, left, opname, v1);
6721 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6722 }
6723 v2=u.expr.v2;
6724 {
6725 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6726 v2->set_lowerid_to_ref();
6727 tt2=v2->get_expr_returntype(exp_val);
6728 chk_expr_operandtype_int(tt2, right, opname, v2);
6729 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6730 chk_expr_val_int_float_not0(v2, right, opname);
6731 }
6732 break;
6733 case OPTYPE_CONCAT: {
6734 v1=u.expr.v1;
6735 v2=u.expr.v2;
6736 v1->set_lowerid_to_ref();
6737 v2->set_lowerid_to_ref();
6738 if (v1->is_string_type(exp_val) || v2->is_string_type(exp_val)) {
6739 {
6740 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6741 tt1=v1->get_expr_returntype(exp_val);
6742 chk_expr_operandtype_str(tt1, left, opname, v1);
6743 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6744 }
6745 {
6746 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6747 tt2=v2->get_expr_returntype(exp_val);
6748 chk_expr_operandtype_str(tt2, right, opname, v2);
6749 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6750 }
6751 if (!((tt1==Type::T_CSTR && tt2==Type::T_USTR)
6752 || (tt2==Type::T_CSTR && tt1==Type::T_USTR)))
6753 chk_expr_operandtypes_same(tt1, tt2, opname);
6754 } else { // other list types
6755 Type* v1_gov = v1->get_expr_governor(exp_val);
6756 Type* v2_gov = v2->get_expr_governor(exp_val);
6757 if (!v1_gov) {
6758 error("Cannot determine the type of the left operand of `%s' operation", opname);
6759 set_valuetype(V_ERROR);
6760 return;
6761 } else {
6762 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6763 v1_gov->chk_this_value_ref(v1);
6764 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6765 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6766 chk_expr_operandtype_list(v1_gov, left, opname, v1, false);
6767 }
6768 if (!v2_gov) {
6769 if (!v1_gov) {
6770 error("Cannot determine the type of the right operand of `%s' operation", opname);
6771 set_valuetype(V_ERROR);
6772 return;
6773 }
6774 // for recof/setof literals set the type from v1
6775 v2_gov = v1_gov;
6776 v2->set_my_governor(v1_gov);
6777 }
6778 {
6779 Error_Context cntxt(this, "In the right operand of operation `%s'",
6780 opname);
6781 v2_gov->chk_this_value_ref(v2);
6782 (void)v2_gov->chk_this_value(v2, 0, exp_val,
6783 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6784 chk_expr_operandtype_list(v2_gov, right, opname, v2, false);
6785 if (valuetype == V_ERROR) return;
6786 // 7.1.2 says that we shouldn't allow type compatibility.
6787 if (!v1_gov->is_compatible(v2_gov, NULL)
6788 && !v2_gov->is_compatible(v1_gov, NULL)) {
6789 error("The operands of operation `%s' should be of compatible "
6790 "types", get_opname());
6791 }
6792 }
6793 }
6794 break; }
6795 case OPTYPE_EQ:
6796 case OPTYPE_NE:
6797 v1 = u.expr.v1;
6798 v2 = u.expr.v2;
6799 chk_expr_operandtypes_compat(exp_val, v1, v2);
6800 {
6801 Error_Context cntxt(this, "In the left operand of operation `%s'",
6802 opname);
6803 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6804 }
6805 {
6806 Error_Context cntxt(this, "In the right operand of operation `%s'",
6807 opname);
6808 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6809 /* According to the BNF v4.1.1, the "arguments" around ==/!= in an
6810 * EqualExpression are RelExpression-s, not NotExpression-s. This means:
6811 * "not a == b" is supposed to be equivalent to "not (a == b)", and
6812 * "a == not b" is not allowed. (HL69107)
6813 * The various *Expressions implement operator precedence in the std.
6814 * Titan's parser has only one Expression and relies on Bison
6815 * for operator precedence. The check below brings Titan in line
6816 * with the standard by explicitly making "a == not b" an error */
6817 if (v2->get_valuetype() == V_EXPR
6818 && v2->u.expr.v_optype == OPTYPE_NOT) {
6819 error("The operation `%s' is not allowed to be "
6820 "the second operand of operation `%s'", v2->get_opname(), opname);
6821 set_valuetype(V_ERROR);
6822 }
6823 }
6824 break;
6825 case OPTYPE_LT:
6826 case OPTYPE_GT:
6827 case OPTYPE_GE:
6828 case OPTYPE_LE:
6829 v1=u.expr.v1;
6830 v2=u.expr.v2;
6831 chk_expr_operandtypes_compat(exp_val, v1, v2);
6832 {
6833 Error_Context cntxt(this, "In the left operand of operation `%s'",
6834 opname);
6835 tt1=v1->get_expr_returntype(exp_val);
6836 chk_expr_operandtype_int_float_enum(tt1, left, opname, v1);
6837 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6838 }
6839 {
6840 Error_Context cntxt(this, "In the right operand of operation `%s'",
6841 opname);
6842 tt2=v2->get_expr_returntype(exp_val);
6843 chk_expr_operandtype_int_float_enum(tt2, right, opname, v2);
6844 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6845 }
6846 break;
6847 case OPTYPE_AND:
6848 case OPTYPE_OR:
6849 case OPTYPE_XOR:
6850 v1=u.expr.v1;
6851 {
6852 Error_Context cntxt(this, "In the left operand of operation `%s'",
6853 opname);
6854 v1->set_lowerid_to_ref();
6855 tt1=v1->get_expr_returntype(exp_val);
6856 chk_expr_operandtype_bool(tt1, left, opname, v1);
6857 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6858 }
6859 v2=u.expr.v2;
6860 {
6861 Error_Context cntxt(this, "In the right operand of operation `%s'",
6862 opname);
6863 v2->set_lowerid_to_ref();
6864 tt2=v2->get_expr_returntype(exp_val);
6865 chk_expr_operandtype_bool(tt2, right, opname, v2);
6866 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6867 }
6868 break;
6869 case OPTYPE_AND4B:
6870 case OPTYPE_OR4B:
6871 case OPTYPE_XOR4B:
6872 v1=u.expr.v1;
6873 {
6874 Error_Context cntxt(this, "In the left operand of operation `%s'",
6875 opname);
6876 v1->set_lowerid_to_ref();
6877 tt1=v1->get_expr_returntype(exp_val);
6878 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6879 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6880 }
6881 v2=u.expr.v2;
6882 {
6883 Error_Context cntxt(this, "In the right operand of operation `%s'",
6884 opname);
6885 v2->set_lowerid_to_ref();
6886 tt2=v2->get_expr_returntype(exp_val);
6887 chk_expr_operandtype_binstr(tt2, right, opname, v2);
6888 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6889 }
6890 chk_expr_operandtypes_same(tt1, tt2, opname);
6891 chk_expr_operands_str_samelen();
6892 break;
6893 case OPTYPE_SHL:
6894 case OPTYPE_SHR:
6895 v1=u.expr.v1;
6896 {
6897 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6898 v1->set_lowerid_to_ref();
6899 tt1=v1->get_expr_returntype(exp_val);
6900 chk_expr_operandtype_binstr(tt1, left, opname, v1);
6901 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6902 }
6903 v2=u.expr.v2;
6904 {
6905 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6906 v2->set_lowerid_to_ref();
6907 tt2=v2->get_expr_returntype(exp_val);
6908 chk_expr_operandtype_int(tt2, right, opname, v2);
6909 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6910 chk_expr_val_large_int(v2, right, opname);
6911 }
6912 break;
6913 case OPTYPE_ROTL:
6914 case OPTYPE_ROTR:
6915 v1=u.expr.v1;
6916 v1->set_lowerid_to_ref();
6917 if (v1->is_string_type(exp_val)) {
6918 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6919 tt1=v1->get_expr_returntype(exp_val);
6920 chk_expr_operandtype_str(tt1, left, opname, v1);
6921 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6922 } else { // other list types
6923 Type* v1_gov = v1->get_expr_governor(exp_val);
6924 if (!v1_gov) { // a recof/setof literal would be a syntax error here
6925 error("Cannot determine the type of the left operand of `%s' operation", opname);
6926 } else {
6927 Error_Context cntxt(this, "In the left operand of operation `%s'", opname);
6928 v1_gov->chk_this_value_ref(v1);
6929 (void)v1_gov->chk_this_value(v1, 0, exp_val,
6930 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
6931 chk_expr_operandtype_list(v1_gov, left, opname, v1, true);
6932 }
6933 }
6934 v2=u.expr.v2;
6935 {
6936 Error_Context cntxt(this, "In the right operand of operation `%s'", opname);
6937 v2->set_lowerid_to_ref();
6938 tt2=v2->get_expr_returntype(exp_val);
6939 chk_expr_operandtype_int(tt2, right, opname, v2);
6940 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6941 chk_expr_val_large_int(v2, right, opname);
6942 }
6943 break;
6944 case OPTYPE_INT2BIT:
6945 case OPTYPE_INT2HEX:
6946 case OPTYPE_INT2OCT:
6947 v1=u.expr.v1;
6948 {
6949 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
6950 v1->set_lowerid_to_ref();
6951 tt1=v1->get_expr_returntype(exp_val);
6952 chk_expr_operandtype_int(tt1, first, opname, v1);
6953 chk_expr_eval_value(v1, t_chk, refch, exp_val);
6954 chk_expr_val_int_pos0(v1, first, opname);
6955 }
6956 v2=u.expr.v2;
6957 {
6958 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6959 v2->set_lowerid_to_ref();
6960 tt2=v2->get_expr_returntype(exp_val);
6961 chk_expr_operandtype_int(tt2, second, opname, v2);
6962 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6963 chk_expr_val_int_pos0(v2, second, opname);
6964 }
6965 chk_expr_operands_int2binstr();
6966 break;
6967 case OPTYPE_DECODE:
1d0599f0 6968 chk_expr_operands_decode(OPTYPE_DECODE);
970ed795
EL
6969 break;
6970 case OPTYPE_SUBSTR:
6971 {
6972 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
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 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
6976 if (!governor) return;
6977 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
6978 if (valuetype!=V_ERROR)
6979 u.expr.ti1->get_Template()->chk_specific_value(false);
6980 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
6981 }
6982 v2=u.expr.v2;
6983 {
6984 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
6985 v2->set_lowerid_to_ref();
6986 tt2=v2->get_expr_returntype(exp_val);
6987 chk_expr_operandtype_int(tt2, second, opname, v2);
6988 chk_expr_eval_value(v2, t_chk, refch, exp_val);
6989 chk_expr_val_int_pos0(v2, second, opname);
6990 }
6991 v3=u.expr.v3;
6992 {
6993 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
6994 v3->set_lowerid_to_ref();
6995 tt3=v3->get_expr_returntype(exp_val);
6996 chk_expr_operandtype_int(tt3, third, opname, v3);
6997 chk_expr_eval_value(v3, t_chk, refch, exp_val);
6998 chk_expr_val_int_pos0(v3, third, opname);
6999 }
7000 chk_expr_operands_substr();
7001 break;
7002 case OPTYPE_REGEXP: {
7003 Type::expected_value_t ti_exp_val = exp_val;
7004 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
7005 {
7006 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7007 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7008 if (!governor) return;
7009 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7010 if (valuetype!=V_ERROR) {
7011 u.expr.ti1->get_Template()->chk_specific_value(false);
7012 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
7013 get_typetype_ttcn3(), first, opname, u.expr.ti1);
7014 }
7015 }
7016 {
7017 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
7018 Type* governor = chk_expr_operands_ti(u.expr.t2, ti_exp_val);
7019 if (!governor) return;
7020 chk_expr_eval_ti(u.expr.t2, governor, refch, ti_exp_val);
7021 chk_expr_operandtype_charstr(governor->get_type_refd_last()->
7022 get_typetype_ttcn3(), second, opname, u.expr.t2);
7023 }
7024 v3=u.expr.v3;
7025 {
7026 Error_Context cntxt(this, "In the third operand of operation `%s'", opname);
7027 v3->set_lowerid_to_ref();
7028 tt3=v3->get_expr_returntype(exp_val);
7029 chk_expr_operandtype_int(tt3, third, opname, v3);
7030 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7031 chk_expr_val_int_pos0(v3, third, opname);
7032 }
7033 chk_expr_operands_regexp();
7034 } break;
7035 case OPTYPE_ISCHOSEN:
7036 // do nothing: the operand is erroneous
7037 // the error was already reported in chk_expr_ref_ischosen()
7038 break;
7039 case OPTYPE_ISCHOSEN_V: // v1 i2
7040 case OPTYPE_ISCHOSEN_T: // t1 i2
7041 chk_expr_operands_ischosen(refch, exp_val);
7042 break;
7043 case OPTYPE_VALUEOF: { // ti1
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 = my_governor;
7048 if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7049 if (!governor) return;
7050 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7051 if (valuetype == V_ERROR) return;
7052 u.expr.ti1->get_Template()->chk_specific_value(false);
7053 break; }
7054 case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
7055 case OPTYPE_ISBOUND: {
7056 Template *templ = u.expr.ti1->get_Template();
7057 switch (templ->get_templatetype()) {
7058 case Template::TEMPLATE_REFD:
7059 templ->get_reference()->setUsedInIsbound();
7060 break;
7061 case Template::SPECIFIC_VALUE: {
7062 Value *value = templ->get_specific_value();
7063 if (Value::V_REFD == value->get_valuetype()) {
7064 value->get_reference()->setUsedInIsbound();
7065 }
7066 break; }
7067 default:
7068 break;
7069 }
7070 }
7071 // no break
7072 case OPTYPE_ISVALUE: {// ti1
7073 // This code is almost, but not quite, the same as for OPTYPE_VALUEOF
7074 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7075 exp_val = Type::EXPECTED_TEMPLATE;
7076 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7077 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7078 if (!governor) return;
7079 tt1 = u.expr.ti1->get_expr_returntype(exp_val);
7080 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7081 break; }
7082 case OPTYPE_SIZEOF: // ti1
7083 /* this checking is too complex, do the checking during eval... */
7084 break;
7085 case OPTYPE_LENGTHOF: { // ti1
7086 if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7087 exp_val = Type::EXPECTED_TEMPLATE;
7088 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7089 Type *governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
7090 if (!governor) return;
7091 chk_expr_operandtype_list(governor, the, opname, u.expr.ti1, true);
7092 if (valuetype == V_ERROR) return;
7093 chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
7094 break; }
7095 case OPTYPE_MATCH: // v1 t2
7096 chk_expr_operands_match(exp_val);
7097 break;
7098 case OPTYPE_UNDEF_RUNNING: // r1
7099 chk_expr_operand_undef_running(exp_val, u.expr.r1, the, opname);
7100 break;
7101 case OPTYPE_COMP_ALIVE:
7102 case OPTYPE_COMP_RUNNING: //v1
7103 chk_expr_operand_compref(u.expr.v1, the, opname);
7104 chk_expr_dynamic_part(exp_val, false);
7105 break;
7106 case OPTYPE_TMR_READ: // r1
7107 case OPTYPE_TMR_RUNNING: // r1
7108 chk_expr_operand_tmrref(u.expr.r1, the, opname);
7109 chk_expr_dynamic_part(exp_val, true);
7110 break;
7111 case OPTYPE_EXECUTE: // r1 [v2] // testcase
7112 chk_expr_operand_execute(u.expr.r1, u.expr.v2, the, opname);
7113 chk_expr_dynamic_part(exp_val, true, false, false);
7114 break;
7115 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7116 chk_expr_operand_comptyperef_create();
7117 v2=u.expr.v2;
7118 if(v2) {
7119 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7120 v2->set_lowerid_to_ref();
7121 tt2=v2->get_expr_returntype(exp_val);
7122 chk_expr_operandtype_cstr(tt2, first, opname, v2);
7123 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7124 }
7125 v3=u.expr.v3;
7126 if(v3) {
7127 Error_Context cntxt(this, "In the second operand of operation `%s'", opname);
7128 v3->set_lowerid_to_ref();
7129 tt3=v3->get_expr_returntype(exp_val);
7130 chk_expr_operandtype_cstr(tt3, second, opname, v3);
7131 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7132 }
7133 chk_expr_dynamic_part(exp_val, false);
7134 break;
7135 case OPTYPE_ACTIVATE: // r1 // altstep
7136 chk_expr_operand_activate(u.expr.r1, the, opname);
7137 chk_expr_dynamic_part(exp_val, true);
7138 break;
0a1610f4 7139 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
7140 case OPTYPE_CHECKSTATE_ALL:
7141 chk_expr_dynamic_part(exp_val, false);
7142 v2=u.expr.v2;
7143 if(v2) {
7144 Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
7145 v2->set_lowerid_to_ref();
7146 tt2=v2->get_expr_returntype(exp_val);
7147 chk_expr_operandtype_cstr(tt2, first, opname, v2);
7148 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7149 }
7150 break;
970ed795
EL
7151 case OPTYPE_ACTIVATE_REFD:{ //v1 t_list2
7152 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7153 chk_expr_operand_activate_refd(u.expr.v1,u.expr.t_list2->get_tis(), parlist, the,
7154 opname);
7155 delete u.expr.t_list2;
7156 u.expr.ap_list2 = parlist;
7157 chk_expr_dynamic_part(exp_val, true);
7158 break; }
7159 case OPTYPE_EXECUTE_REFD: {// v1 t_list2 [v3]
7160 Ttcn::ActualParList *parlist = new Ttcn::ActualParList;
7161 chk_expr_operand_execute_refd(u.expr.v1, u.expr.t_list2->get_tis(), parlist,
7162 u.expr.v3, the, opname);
7163 delete u.expr.t_list2;
7164 u.expr.ap_list2 = parlist;
7165 chk_expr_dynamic_part(exp_val, true);
7166 break; }
7167 case OPTYPE_DECOMP:
7168 error("Built-in function `%s' is not yet supported", opname);
7169 set_valuetype(V_ERROR);
7170 break;
7171 case OPTYPE_REPLACE: {
7172 Type::expected_value_t ti_exp_val = exp_val;
7173 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE)
7174 ti_exp_val = Type::EXPECTED_TEMPLATE;
7175 {
7176 Error_Context cntxt(this, "In the first operand of operation `%s'",
7177 opname);
7178 Type* governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7179 if (!governor) return;
7180 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7181 if (valuetype != V_ERROR)
7182 u.expr.ti1->get_Template()->chk_specific_value(false);
7183 chk_expr_operandtype_list(governor, first, opname, u.expr.ti1, false);
7184 }
7185 v2 = u.expr.v2;
7186 {
7187 Error_Context cntxt(this, "In the second operand of operation `%s'",
7188 opname);
7189 v2->set_lowerid_to_ref();
7190 tt2 = v2->get_expr_returntype(exp_val);
7191 chk_expr_operandtype_int(tt2, second, opname, v2);
7192 chk_expr_eval_value(v2, t_chk, refch, exp_val);
7193 chk_expr_val_int_pos0(v2, second, opname);
7194 }
7195 v3 = u.expr.v3;
7196 {
7197 Error_Context cntxt(this, "In the third operand of operation `%s'",
7198 opname);
7199 v3->set_lowerid_to_ref();
7200 tt3 = v3->get_expr_returntype(exp_val);
7201 chk_expr_operandtype_int(tt3, third, opname, v3);
7202 chk_expr_eval_value(v3, t_chk, refch, exp_val);
7203 chk_expr_val_int_pos0(v3, third, opname);
7204 }
7205 {
7206 Error_Context cntxt(this, "In the fourth operand of operation `%s'",
7207 opname);
7208 Type* governor = chk_expr_operands_ti(u.expr.ti4, ti_exp_val);
7209 if (!governor) return;
7210 chk_expr_eval_ti(u.expr.ti4, governor, refch, ti_exp_val);
7211 if (valuetype != V_ERROR)
7212 u.expr.ti4->get_Template()->chk_specific_value(false);
7213 chk_expr_operandtype_list(governor, fourth, opname, u.expr.ti4, false);
7214 }
7215 chk_expr_operands_replace();
7216 break; }
a50716c1 7217 case OPTYPE_LOG2STR:
7218 case OPTYPE_ANY2UNISTR: {
970ed795
EL
7219 Error_Context cntxt(this, "In the operand of operation `%s'", opname);
7220 u.expr.logargs->chk();
7221 if (!semantic_check_only) u.expr.logargs->join_strings();
7222 break; }
7223 case OPTYPE_TTCN2STRING: {
7224 Error_Context cntxt(this, "In the parameter of ttcn2string()");
7225 Type::expected_value_t ti_exp_val = exp_val;
7226 if (ti_exp_val == Type::EXPECTED_DYNAMIC_VALUE) ti_exp_val = Type::EXPECTED_TEMPLATE;
7227 Type *governor = chk_expr_operands_ti(u.expr.ti1, ti_exp_val);
7228 if (!governor) return;
7229 chk_expr_eval_ti(u.expr.ti1, governor, refch, ti_exp_val);
7230 } break;
7231 default:
7232 FATAL_ERROR("chk_expr_operands()");
7233 } // switch optype
7234 }
7235
7236 // Compile-time evaluation. It may change the valuetype from V_EXPR to
7237 // the result of evaluating the expression. E.g. V_BOOL for
7238 // OPTYPE_ISCHOSEN.
7239 void Value::evaluate_value(ReferenceChain *refch,
7240 Type::expected_value_t exp_val)
7241 {
7242 if(valuetype!=V_EXPR) FATAL_ERROR("Value::evaluate_value()");
7243 if(u.expr.state!=EXPR_NOT_CHECKED) return;
7244
7245 u.expr.state=EXPR_CHECKING;
7246
7247 get_expr_returntype(exp_val); // to report 'didyamean'-errors etc
7248 chk_expr_operands(refch, exp_val == Type::EXPECTED_TEMPLATE ?
7249 Type::EXPECTED_DYNAMIC_VALUE : exp_val);
7250
7251 if(valuetype==V_ERROR) return;
7252 if(u.expr.state==EXPR_CHECKING_ERR) {
7253 u.expr.state=EXPR_CHECKED;
7254 set_valuetype(V_ERROR);
7255 return;
7256 }
7257
7258 u.expr.state=EXPR_CHECKED;
7259
7260 Value *v1, *v2, *v3, *v4;
7261 switch(u.expr.v_optype) {
7262 case OPTYPE_RND: // -
7263 case OPTYPE_COMP_NULL: // the only foldable in this group
7264 case OPTYPE_COMP_MTC:
7265 case OPTYPE_COMP_SYSTEM:
7266 case OPTYPE_COMP_SELF:
7267 case OPTYPE_COMP_RUNNING_ANY:
7268 case OPTYPE_COMP_RUNNING_ALL:
7269 case OPTYPE_COMP_ALIVE_ANY:
7270 case OPTYPE_COMP_ALIVE_ALL:
7271 case OPTYPE_TMR_RUNNING_ANY:
7272 case OPTYPE_GETVERDICT:
a38c6d4c 7273 case OPTYPE_PROF_RUNNING:
970ed795
EL
7274 case OPTYPE_RNDWITHVAL: // v1
7275 case OPTYPE_COMP_RUNNING: // v1
7276 case OPTYPE_COMP_ALIVE:
7277 case OPTYPE_TMR_READ:
7278 case OPTYPE_TMR_RUNNING:
7279 case OPTYPE_ACTIVATE:
7280 case OPTYPE_ACTIVATE_REFD:
7281 case OPTYPE_EXECUTE: // r1 [v2]
7282 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
7283 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
7284 case OPTYPE_MATCH: // v1 t2
7285 case OPTYPE_ISCHOSEN_T:
7286 case OPTYPE_LOG2STR:
a50716c1 7287 case OPTYPE_ANY2UNISTR:
970ed795
EL
7288 case OPTYPE_ENCODE:
7289 case OPTYPE_DECODE:
7290 case OPTYPE_ISBOUND:
7291 case OPTYPE_ISPRESENT:
7292 case OPTYPE_TTCN2STRING:
7293 case OPTYPE_UNICHAR2OCT:
7294 case OPTYPE_OCT2UNICHAR:
7295 case OPTYPE_ENCODE_BASE64:
7296 case OPTYPE_DECODE_BASE64:
1d0599f0 7297 case OPTYPE_ENCVALUE_UNICHAR:
7298 case OPTYPE_DECVALUE_UNICHAR:
0a1610f4 7299 case OPTYPE_CHECKSTATE_ANY:
7300 case OPTYPE_CHECKSTATE_ALL:
efbe586d 7301 case OPTYPE_HOSTID:
970ed795
EL
7302 break;
7303 case OPTYPE_TESTCASENAME: { // -
7304 if (!my_scope) FATAL_ERROR("Value::evaluate_value()");
7305 Ttcn::StatementBlock *my_sb =
7306 dynamic_cast<Ttcn::StatementBlock *>(my_scope);
7307 if (!my_sb) break;
7308 Ttcn::Definition *my_def = my_sb->get_my_def();
7309 if (!my_def) { // In control part.
7310 set_val_str(new string(""));
7311 valuetype = V_CSTR;
7312 } else if (my_def->get_asstype() == Assignment::A_TESTCASE) {
7313 set_val_str(new string(my_def->get_id().get_dispname()));
7314 valuetype = V_CSTR;
7315 }
7316 break; }
7317 case OPTYPE_UNARYPLUS: // v1
7318 v1=u.expr.v1;
7319 u.expr.v1=0;
7320 copy_and_destroy(v1);
7321 break;
7322 case OPTYPE_UNARYMINUS:
7323 if (is_unfoldable()) break;
7324 v1 = u.expr.v1->get_value_refd_last();
7325 switch (v1->valuetype) {
7326 case V_INT: {
7327 int_val_t *i = new int_val_t(-*(v1->get_val_Int()));
7328 if (!i) FATAL_ERROR("Value::evaluate_value()");
7329 clean_up();
7330 valuetype = V_INT;
7331 u.val_Int = i;
7332 break; }
7333 case V_REAL: {
7334 ttcn3float r = v1->get_val_Real();
7335 clean_up();
7336 valuetype = V_REAL;
7337 u.val_Real = -r;
7338 break; }
7339 default:
7340 FATAL_ERROR("Value::evaluate_value()");
7341 }
7342 break;
7343 case OPTYPE_NOT: {
7344 if(is_unfoldable()) break;
7345 bool b=u.expr.v1->get_value_refd_last()->get_val_bool();
7346 clean_up();
7347 valuetype=V_BOOL;
7348 u.val_bool=!b;
7349 break;}
7350 case OPTYPE_NOT4B: {
7351 if(is_unfoldable()) break;
7352 v1=u.expr.v1->get_value_refd_last();
7353 const string& s = v1->get_val_str();
7354 valuetype_t vt=v1->valuetype;
7355 clean_up();
7356 valuetype=vt;
7357 set_val_str(vt==V_BSTR?not4b_bit(s):not4b_hex(s));
7358 break;}
7359 case OPTYPE_BIT2HEX: {
7360 if(is_unfoldable()) break;
7361 v1=u.expr.v1->get_value_refd_last();
7362 const string& s = v1->get_val_str();
7363 clean_up();
7364 valuetype=V_HSTR;
7365 set_val_str(bit2hex(s));
7366 break;}
7367 case OPTYPE_BIT2OCT: {
7368 if(is_unfoldable()) break;
7369 v1=u.expr.v1->get_value_refd_last();
7370 const string& s = v1->get_val_str();
7371 clean_up();
7372 valuetype=V_OSTR;
7373 set_val_str(bit2oct(s));
7374 break;}
7375 case OPTYPE_BIT2STR:
7376 case OPTYPE_HEX2STR:
7377 case OPTYPE_OCT2STR: {
7378 if(is_unfoldable()) break;
7379 v1=u.expr.v1->get_value_refd_last();
7380 const string& s = v1->get_val_str();
7381 clean_up();
7382 valuetype=V_CSTR;
7383 set_val_str(new string(s));
7384 break;}
7385 case OPTYPE_BIT2INT: {
7386 if (is_unfoldable()) break;
7387 v1 = u.expr.v1->get_value_refd_last();
7388 const string& s = v1->get_val_str();
7389 clean_up();
7390 valuetype = V_INT;
7391 u.val_Int = bit2int(s);
7392 break; }
7393 case OPTYPE_CHAR2INT: {
7394 if (is_unfoldable()) break;
7395 v1 = u.expr.v1->get_value_refd_last();
7396 char c = v1->get_val_str()[0];
7397 clean_up();
7398 valuetype = V_INT;
7399 u.val_Int = new int_val_t((Int)c);
7400 break; }
7401 case OPTYPE_CHAR2OCT: {
7402 if(is_unfoldable()) break;
7403 v1=u.expr.v1->get_value_refd_last();
7404 const string& s = v1->get_val_str();
7405 clean_up();
7406 valuetype=V_OSTR;
7407 set_val_str(char2oct(s));
7408 break;}
7409 case OPTYPE_STR2INT: {
7410 if (is_unfoldable()) break;
7411 v1 = u.expr.v1->get_value_refd_last();
7412 int_val_t *i = new int_val_t((v1->get_val_str()).c_str(), *u.expr.v1);
7413 clean_up();
7414 valuetype = V_INT;
7415 u.val_Int = i;
7416 /** \todo hiba eseten lenyeli... */
7417 break; }
7418 case OPTYPE_STR2FLOAT: {
7419 if(is_unfoldable()) break;
7420 v1=u.expr.v1->get_value_refd_last();
7421 Real r=string2Real(v1->get_val_str(), *u.expr.v1);
7422 clean_up();
7423 valuetype=V_REAL;
7424 u.val_Real=r;
7425 /** \todo hiba eseten lenyeli... */
7426 break;}
7427 case OPTYPE_STR2BIT: {
7428 if(is_unfoldable()) break;
7429 v1=u.expr.v1->get_value_refd_last();
7430 const string& s = v1->get_val_str();
7431 clean_up();
7432 valuetype=V_BSTR;
7433 set_val_str(new string(s));
7434 break;}
7435 case OPTYPE_STR2HEX:
7436 case OPTYPE_OCT2HEX: {
7437 if(is_unfoldable()) break;
7438 v1=u.expr.v1->get_value_refd_last();
7439 const string& s = v1->get_val_str();
7440 clean_up();
7441 valuetype=V_HSTR;
7442 set_val_str(to_uppercase(s));
7443 break;}
7444 case OPTYPE_STR2OCT: {
7445 if(is_unfoldable()) break;
7446 v1=u.expr.v1->get_value_refd_last();
7447 const string& s = v1->get_val_str();
7448 clean_up();
7449 valuetype=V_OSTR;
7450 set_val_str(to_uppercase(s));
7451 break;}
7452 case OPTYPE_FLOAT2INT: {
7453 if (is_unfoldable()) break;
7454 v1 = u.expr.v1->get_value_refd_last();
7455 ttcn3float r = v1->get_val_Real();
7456 clean_up();
7457 valuetype = V_INT;
7458 u.val_Int = float2int(r, *u.expr.v1);
7459 break;}
7460 case OPTYPE_FLOAT2STR: {
7461 if(is_unfoldable()) break;
7462 v1=u.expr.v1->get_value_refd_last();
7463 ttcn3float r=v1->get_val_Real();
7464 clean_up();
7465 valuetype=V_CSTR;
7466 set_val_str(float2str(r));
7467 break;}
7468 case OPTYPE_HEX2BIT:
7469 case OPTYPE_OCT2BIT: {
7470 if(is_unfoldable()) break;
7471 v1=u.expr.v1->get_value_refd_last();
7472 const string& s = v1->get_val_str();
7473 clean_up();
7474 valuetype=V_BSTR;
7475 set_val_str(hex2bit(s));
7476 break;}
7477 case OPTYPE_HEX2INT:
7478 case OPTYPE_OCT2INT: {
7479 if(is_unfoldable()) break;
7480 v1=u.expr.v1->get_value_refd_last();
7481 const string& s = v1->get_val_str();
7482 clean_up();
7483 valuetype=V_INT;
7484 u.val_Int=hex2int(s);
7485 break;}
7486 case OPTYPE_HEX2OCT: {
7487 if(is_unfoldable()) break;
7488 v1=u.expr.v1->get_value_refd_last();
7489 const string& s = v1->get_val_str();
7490 clean_up();
7491 valuetype=V_OSTR;
7492 set_val_str(hex2oct(s));
7493 break;}
7494 case OPTYPE_INT2CHAR: {
7495 if (is_unfoldable()) break;
7496 v1 = u.expr.v1->get_value_refd_last();
7497 const int_val_t *c_int = v1->get_val_Int();
7498 char c = static_cast<char>(c_int->get_val());
7499 clean_up();
7500 valuetype = V_CSTR;
7501 set_val_str(new string(1, &c));
7502 break; }
7503 case OPTYPE_INT2UNICHAR: {
7504 if (is_unfoldable()) break;
7505 v1 = u.expr.v1->get_value_refd_last();
7506 const int_val_t *i_int = v1->get_val_Int();
7507 Int i = i_int->get_val();
7508 clean_up();
7509 valuetype = V_USTR;
7510 set_val_ustr(int2unichar(i));
7511 u.ustr.convert_str = false;
7512 break; }
7513 case OPTYPE_INT2FLOAT: {
7514 if (is_unfoldable()) break;
7515 v1 = u.expr.v1->get_value_refd_last();
7516 const int_val_t *i_int = v1->get_val_Int();
7517 Real i_int_real = i_int->to_real();
7518 clean_up();
7519 valuetype = V_REAL;
7520 u.val_Real = i_int_real;
7521 break; }
7522 case OPTYPE_INT2STR: {
7523 if (is_unfoldable()) break;
7524 v1 = u.expr.v1->get_value_refd_last();
7525 const int_val_t *i_int = v1->get_val_Int();
7526 string *i_int_str = new string(i_int->t_str());
7527 clean_up();
7528 valuetype = V_CSTR;
7529 set_val_str(i_int_str);
7530 break; }
7531 case OPTYPE_OCT2CHAR: {
7532 if(is_unfoldable()) break;
7533 v1=u.expr.v1->get_value_refd_last();
7534 const string& s = v1->get_val_str();
7535 clean_up();
7536 valuetype=V_CSTR;
7537 set_val_str(oct2char(s));
7538 break;}
7539 case OPTYPE_GET_STRINGENCODING: {
7540 if(is_unfoldable()) break;
7541 v1 = u.expr.v1->get_value_refd_last();
7542 const string& s1 = v1->get_val_str();
7543 clean_up();
7544 valuetype = V_CSTR;
7545 set_val_str(get_stringencoding(s1));
7546 break;}
7547 case OPTYPE_REMOVE_BOM: {
7548 if(is_unfoldable()) break;
7549 v1 = u.expr.v1->get_value_refd_last();
7550 const string& s1 = v1->get_val_str();
7551 clean_up();
7552 valuetype = V_OSTR;
7553 set_val_str(remove_bom(s1));
7554 break;}
7555 case OPTYPE_ENUM2INT: {
7556 if(is_unfoldable()) break;
7557 v1=u.expr.v1->get_value_refd_last();
7558 Type* enum_type = v1->get_my_governor();
7559 const Int& enum_val = enum_type->get_enum_val_byId(*(v1->u.val_id));
7560 clean_up();
7561 valuetype = V_INT;
7562 u.val_Int = new int_val_t(enum_val);
7563 break;}
7564 case OPTYPE_UNICHAR2INT:
7565 if (is_unfoldable()) {
7566 // replace the operation with char2int() if the operand is a charstring
7567 // value to avoid its unnecessary conversion to universal charstring
7568 if (u.expr.v1->get_expr_returntype(exp_val) == Type::T_CSTR)
7569 u.expr.v_optype = OPTYPE_CHAR2INT;
7570 } else {
7571 v1=u.expr.v1->get_value_refd_last();
7572 const ustring& s = v1->get_val_ustr();
7573 clean_up();
7574 valuetype=V_INT;
7575 u.val_Int=new int_val_t(unichar2int(s));
7576 }
7577 break;
7578 case OPTYPE_UNICHAR2CHAR:
7579 v1 = u.expr.v1;
7580 if (is_unfoldable()) {
7581 // replace the operation with its operand if it is a charstring
7582 // value to avoid its unnecessary conversion to universal charstring
7583 if (v1->get_expr_returntype(exp_val) == Type::T_CSTR) {
7584 u.expr.v1 = 0;
7585 copy_and_destroy(v1);
7586 }
7587 } else {
7588 v1 = v1->get_value_refd_last();
7589 const ustring& s = v1->get_val_ustr();
7590 clean_up();
7591 valuetype = V_CSTR;
7592 set_val_str(new string(s));
7593 }
7594 break;
7595 case OPTYPE_MULTIPLY: { // v1 v2
7596 if (!is_unfoldable()) goto eval_arithmetic;
7597 v1 = u.expr.v1->get_value_refd_last();
7598 v2 = u.expr.v2->get_value_refd_last();
7599 if (v1->is_unfoldable()) v1 = v2;
7600 if (v1->is_unfoldable()) break;
7601 switch(v1->valuetype) {
7602 case V_INT: {
7603 if (*v1->get_val_Int() != 0) break;
7604 clean_up();
7605 valuetype = V_INT;
7606 u.val_Int = new int_val_t((Int)0);
7607 break; }
7608 case V_REAL: {
7609 if (v1->get_val_Real() != 0.0) break;
7610 clean_up();
7611 valuetype = V_REAL;
7612 u.val_Real = 0.0;
7613 break; }
7614 default:
7615 FATAL_ERROR("Value::evaluate_value()");
7616 }
7617 break; }
7618 case OPTYPE_ADD: // v1 v2
7619 case OPTYPE_SUBTRACT:
7620 case OPTYPE_DIVIDE:
7621 case OPTYPE_MOD:
7622 case OPTYPE_REM: {
7623 eval_arithmetic:
7624 if(is_unfoldable()) break;
7625 v1=u.expr.v1->get_value_refd_last();
7626 v2=u.expr.v2->get_value_refd_last();
7627 operationtype_t ot=u.expr.v_optype;
7628 switch (v1->valuetype) {
7629 case V_INT: {
7630 const int_val_t *i1 = new int_val_t(*(v1->get_val_Int()));
7631 const int_val_t *i2 = new int_val_t(*(v2->get_val_Int()));
7632 clean_up();
7633 valuetype = V_INT;
7634 switch (ot) {
7635 case OPTYPE_ADD:
7636 u.val_Int = new int_val_t(*i1 + *i2);
7637 break;
7638 case OPTYPE_SUBTRACT:
7639 u.val_Int = new int_val_t(*i1 - *i2);
7640 break;
7641 case OPTYPE_MULTIPLY:
7642 u.val_Int = new int_val_t(*i1 * *i2);
7643 break;
7644 case OPTYPE_DIVIDE:
7645 u.val_Int = new int_val_t(*i1 / *i2);
7646 break;
7647 case OPTYPE_MOD:
7648 u.val_Int = new int_val_t(mod(*i1, *i2));
7649 break;
7650 case OPTYPE_REM:
7651 u.val_Int = new int_val_t(rem(*i1, *i2));
7652 break;
7653 default:
7654 FATAL_ERROR("Value::evaluate_value()");
7655 }
7656 delete i1;
7657 delete i2;
7658 break; }
7659 case V_REAL: {
7660 ttcn3float r1=v1->get_val_Real();
7661 ttcn3float r2=v2->get_val_Real();
7662 clean_up();
7663 valuetype=V_REAL;
7664 switch(ot) {
7665 case OPTYPE_ADD:
7666 u.val_Real=r1+r2;
7667 break;
7668 case OPTYPE_SUBTRACT:
7669 u.val_Real=r1-r2;
7670 break;
7671 case OPTYPE_MULTIPLY:
7672 u.val_Real=r1*r2;
7673 break;
7674 case OPTYPE_DIVIDE:
7675 u.val_Real=r1/r2;
7676 break;
7677 default:
7678 FATAL_ERROR("Value::evaluate_value()");
7679 }
7680 break;}
7681 default:
7682 FATAL_ERROR("Value::evaluate_value()");
7683 }
7684 break;}
7685 case OPTYPE_CONCAT: {
7686 if(is_unfoldable()) break;
7687 v1=u.expr.v1->get_value_refd_last();
7688 v2=u.expr.v2->get_value_refd_last();
7689 valuetype_t vt = v1->valuetype;
7690 if (vt == V_USTR || v2->valuetype == V_USTR) { // V_USTR wins
7691 const ustring& s1 = v1->get_val_ustr();
7692 const ustring& s2 = v2->get_val_ustr();
7693 clean_up();
7694 valuetype = V_USTR;
7695 set_val_ustr(new ustring(s1 + s2));
7696 u.ustr.convert_str = false;
7697 } else {
7698 const string& s1 = v1->get_val_str();
7699 const string& s2 = v2->get_val_str();
7700 clean_up();
7701 valuetype = vt;
7702 set_val_str(new string(s1 + s2));
7703 }
7704 break;}
7705 case OPTYPE_EQ: {
7706 if(is_unfoldable()) break;
7707 v1=u.expr.v1->get_value_refd_last();
7708 v2=u.expr.v2->get_value_refd_last();
7709 bool b=*v1==*v2;
7710 clean_up();
7711 valuetype=V_BOOL;
7712 u.val_bool=b;
7713 break;}
7714 case OPTYPE_NE: {
7715 if(is_unfoldable()) break;
7716 v1=u.expr.v1->get_value_refd_last();
7717 v2=u.expr.v2->get_value_refd_last();
7718 bool b=*v1==*v2;
7719 clean_up();
7720 valuetype=V_BOOL;
7721 u.val_bool=!b;
7722 break;}
7723 case OPTYPE_LT: {
7724 if(is_unfoldable()) break;
7725 v1=u.expr.v1->get_value_refd_last();
7726 v2=u.expr.v2->get_value_refd_last();
7727 bool b=*v1<*v2;
7728 clean_up();
7729 valuetype=V_BOOL;
7730 u.val_bool=b;
7731 break;}
7732 case OPTYPE_GT: {
7733 if(is_unfoldable()) break;
7734 v1=u.expr.v1->get_value_refd_last();
7735 v2=u.expr.v2->get_value_refd_last();
7736 bool b=*v2<*v1;
7737 clean_up();
7738 valuetype=V_BOOL;
7739 u.val_bool=b;
7740 break;}
7741 case OPTYPE_GE: {
7742 if(is_unfoldable()) break;
7743 v1=u.expr.v1->get_value_refd_last();
7744 v2=u.expr.v2->get_value_refd_last();
7745 bool b=*v1<*v2;
7746 clean_up();
7747 valuetype=V_BOOL;
7748 u.val_bool=!b;
7749 break;}
7750 case OPTYPE_LE: {
7751 if(is_unfoldable()) break;
7752 v1=u.expr.v1->get_value_refd_last();
7753 v2=u.expr.v2->get_value_refd_last();
7754 bool b=*v2<*v1;
7755 clean_up();
7756 valuetype=V_BOOL;
7757 u.val_bool=!b;
7758 break;}
7759 case OPTYPE_AND:
7760 v1 = u.expr.v1->get_value_refd_last();
7761 if (v1->valuetype == V_BOOL) {
7762 if (v1->get_val_bool()) {
7763 // the left operand is a literal "true"
7764 // substitute the expression with the right operand
7765 v2 = u.expr.v2;
7766 u.expr.v2 = 0;
7767 copy_and_destroy(v2);
7768 } else {
7769 // the left operand is a literal "false"
7770 // the result must be false regardless the right operand
7771 // because of the short circuit evaluation rule
7772 clean_up();
7773 valuetype = V_BOOL;
7774 u.val_bool = false;
7775 }
7776 } else {
7777 // we must keep the left operand because of the potential side effects
7778 // the right operand can only be eliminated if it is a literal "true"
7779 v2 = u.expr.v2->get_value_refd_last();
7780 if (v2->valuetype == V_BOOL && v2->get_val_bool()) {
7781 v1 = u.expr.v1;
7782 u.expr.v1 = 0;
7783 copy_and_destroy(v1);
7784 }
7785 }
7786 break;
7787 case OPTYPE_OR:
7788 v1 = u.expr.v1->get_value_refd_last();
7789 if (v1->valuetype == V_BOOL) {
7790 if (v1->get_val_bool()) {
7791 // the left operand is a literal "true"
7792 // the result must be true regardless the right operand
7793 // because of the short circuit evaluation rule
7794 clean_up();
7795 valuetype = V_BOOL;
7796 u.val_bool = true;
7797 } else {
7798 // the left operand is a literal "false"
7799 // substitute the expression with the right operand
7800 v2 = u.expr.v2;
7801 u.expr.v2 = 0;
7802 copy_and_destroy(v2);
7803 }
7804 } else {
7805 // we must keep the left operand because of the potential side effects
7806 // the right operand can only be eliminated if it is a literal "false"
7807 v2 = u.expr.v2->get_value_refd_last();
7808 if (v2->valuetype == V_BOOL && !v2->get_val_bool()) {
7809 v1 = u.expr.v1;
7810 u.expr.v1 = 0;
7811 copy_and_destroy(v1);
7812 }
7813 }
7814 break;
7815 case OPTYPE_XOR: {
7816 if(is_unfoldable()) break;
7817 v1=u.expr.v1->get_value_refd_last();
7818 v2=u.expr.v2->get_value_refd_last();
7819 bool b=v1->get_val_bool() ^ v2->get_val_bool();
7820 clean_up();
7821 valuetype=V_BOOL;
7822 u.val_bool=b;
7823 break;}
7824 case OPTYPE_AND4B: {
7825 if(is_unfoldable()) break;
7826 v1=u.expr.v1->get_value_refd_last();
7827 v2=u.expr.v2->get_value_refd_last();
7828 valuetype_t vt=v1->valuetype;
7829 const string& s1 = v1->get_val_str();
7830 const string& s2 = v2->get_val_str();
7831 clean_up();
7832 valuetype=vt;
7833 set_val_str(and4b(s1, s2));
7834 break;}
7835 case OPTYPE_OR4B: {
7836 if(is_unfoldable()) break;
7837 v1=u.expr.v1->get_value_refd_last();
7838 v2=u.expr.v2->get_value_refd_last();
7839 valuetype_t vt=v1->valuetype;
7840 const string& s1 = v1->get_val_str();
7841 const string& s2 = v2->get_val_str();
7842 clean_up();
7843 valuetype=vt;
7844 set_val_str(or4b(s1, s2));
7845 break;}
7846 case OPTYPE_XOR4B: {
7847 if(is_unfoldable()) break;
7848 v1=u.expr.v1->get_value_refd_last();
7849 v2=u.expr.v2->get_value_refd_last();
7850 valuetype_t vt=v1->valuetype;
7851 const string& s1 = v1->get_val_str();
7852 const string& s2 = v2->get_val_str();
7853 clean_up();
7854 valuetype=vt;
7855 set_val_str(xor4b(s1, s2));
7856 break;}
7857 case OPTYPE_SHL: {
7858 if(is_unfoldable()) break;
7859 v1=u.expr.v1->get_value_refd_last();
7860 v2=u.expr.v2->get_value_refd_last();
7861 valuetype_t vt=v1->valuetype;
7862 const string& s = v1->get_val_str();
7863 const int_val_t *i_int = v2->get_val_Int();
7864 Int i=i_int->get_val();
7865 if(vt==V_OSTR) i*=2;
7866 clean_up();
7867 valuetype=vt;
7868 set_val_str(shift_left(s, i));
7869 break;}
7870 case OPTYPE_SHR: {
7871 if(is_unfoldable()) break;
7872 v1=u.expr.v1->get_value_refd_last();
7873 v2=u.expr.v2->get_value_refd_last();
7874 valuetype_t vt=v1->valuetype;
7875 const string& s = v1->get_val_str();
7876 const int_val_t *i_int = v2->get_val_Int();
7877 Int i=i_int->get_val();
7878 if(vt==V_OSTR) i*=2;
7879 clean_up();
7880 valuetype=vt;
7881 set_val_str(shift_right(s, i));
7882 break;}
7883 case OPTYPE_ROTL: {
7884 if(is_unfoldable()) break;
7885 v1=u.expr.v1->get_value_refd_last();
7886 v2=u.expr.v2->get_value_refd_last();
7887 valuetype_t vt=v1->valuetype;
7888 const int_val_t *i_int=v2->get_val_Int();
7889 Int i=i_int->get_val();
7890 if(vt==V_USTR) {
7891 const ustring& s = v1->get_val_ustr();
7892 clean_up();
7893 valuetype=vt;
7894 set_val_ustr(rotate_left(s, i));
7895 u.ustr.convert_str = false;
7896 }
7897 else {
7898 if(vt==V_OSTR) i*=2;
7899 const string& s = v1->get_val_str();
7900 clean_up();
7901 valuetype=vt;
7902 set_val_str(rotate_left(s, i));
7903 }
7904 break;}
7905 case OPTYPE_ROTR: {
7906 if(is_unfoldable()) break;
7907 v1=u.expr.v1->get_value_refd_last();
7908 v2=u.expr.v2->get_value_refd_last();
7909 valuetype_t vt=v1->valuetype;
7910 const int_val_t *i_int=v2->get_val_Int();
7911 Int i=i_int->get_val();
7912 if(vt==V_USTR) {
7913 const ustring& s = v1->get_val_ustr();
7914 clean_up();
7915 valuetype=vt;
7916 set_val_ustr(rotate_right(s, i));
7917 u.ustr.convert_str = false;
7918 }
7919 else {
7920 if(vt==V_OSTR) i*=2;
7921 const string& s = v1->get_val_str();
7922 clean_up();
7923 valuetype=vt;
7924 set_val_str(rotate_right(s, i));
7925 }
7926 break;}
7927 case OPTYPE_INT2BIT: {
7928 if (is_unfoldable()) break;
7929 v1 = u.expr.v1->get_value_refd_last();
7930 v2 = u.expr.v2->get_value_refd_last();
7931 const int_val_t *i1_int = v1->get_val_Int();
7932 const int_val_t *i2_int = v2->get_val_Int();
7933 string *val = int2bit(*i1_int, i2_int->get_val());
7934 clean_up();
7935 valuetype = V_BSTR;
7936 set_val_str(val);
7937 break; }
7938 case OPTYPE_INT2HEX: {
7939 if (is_unfoldable()) break;
7940 v1 = u.expr.v1->get_value_refd_last();
7941 v2 = u.expr.v2->get_value_refd_last();
7942 const int_val_t *i1_int = v1->get_val_Int();
7943 const int_val_t *i2_int = v2->get_val_Int();
7944 // Do it before the `clean_up'. i2_int is already checked.
7945 string *val = int2hex(*i1_int, i2_int->get_val());
7946 clean_up();
7947 valuetype = V_HSTR;
7948 set_val_str(val);
7949 break; }
7950 case OPTYPE_INT2OCT: {
7951 if (is_unfoldable()) break;
7952 v1 = u.expr.v1->get_value_refd_last();
7953 v2 = u.expr.v2->get_value_refd_last();
7954 const int_val_t i1_int(*v1->get_val_Int());
7955 // `v2' is a native integer.
7956 Int i2_int = v2->get_val_Int()->get_val() * 2;
7957 clean_up();
7958 valuetype = V_OSTR;
7959 set_val_str(int2hex(i1_int, i2_int));
7960 break; }
7961 case OPTYPE_SUBSTR: {
7962 if(is_unfoldable()) break;
7963 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7964 v2=u.expr.v2->get_value_refd_last();
7965 v3=u.expr.v3->get_value_refd_last();
7966 valuetype_t vt=v1->valuetype;
7967 const int_val_t *i2_int=v2->get_val_Int();
7968 const int_val_t *i3_int=v3->get_val_Int();
7969 Int i2=i2_int->get_val();
7970 Int i3=i3_int->get_val();
7971 if(vt==V_USTR) {
7972 const ustring& s = v1->get_val_ustr();
7973 clean_up();
7974 valuetype=vt;
7975 set_val_ustr(new ustring(s.substr(i2, i3)));
7976 u.ustr.convert_str = false;
7977 }
7978 else {
7979 if(vt==V_OSTR) {
7980 i2*=2;
7981 i3*=2;
7982 }
7983 const string& s = v1->get_val_str();
7984 clean_up();
7985 valuetype=vt;
7986 set_val_str(new string(s.substr(i2, i3)));
7987 }
7988 break;}
7989 case OPTYPE_REPLACE: {
7990 if(is_unfoldable()) break;
7991 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
7992 v2=u.expr.v2->get_value_refd_last();
7993 v3=u.expr.v3->get_value_refd_last();
7994 v4=u.expr.ti4->get_specific_value()->get_value_refd_last();
7995 valuetype_t vt=v1->valuetype;
7996 const int_val_t *i2_int=v2->get_val_Int();
7997 const int_val_t *i3_int=v3->get_val_Int();
7998 Int i2=i2_int->get_val();
7999 Int i3=i3_int->get_val();
8000 switch(vt) {
8001 case V_BSTR: {
8002 string *s1 = new string(v1->get_val_str());
8003 const string& s2 = v4->get_val_str();
8004 clean_up();
8005 valuetype=vt;
8006 s1->replace(i2, i3, s2);
8007 set_val_str(s1);
8008 break;}
8009 case V_HSTR: {
8010 string *s1 = new string(v1->get_val_str());
8011 const string& s2 = v4->get_val_str();
8012 clean_up();
8013 valuetype=vt;
8014 s1->replace(i2, i3, s2);
8015 set_val_str(s1);
8016 break;}
8017 case V_OSTR: {
8018 i2*=2;
8019 i3*=2;
8020 string *s1 = new string(v1->get_val_str());
8021 const string& s2 = v4->get_val_str();
8022 clean_up();
8023 valuetype=vt;
8024 s1->replace(i2, i3, s2);
8025 set_val_str(s1);
8026 break;}
8027 case V_CSTR: {
8028 string *s1 = new string(v1->get_val_str());
8029 const string& s2 = v4->get_val_str();
8030 clean_up();
8031 valuetype=vt;
8032 s1->replace(i2, i3, s2);
8033 set_val_str(s1);
8034 break;}
8035 case V_USTR: {
8036 ustring *s1 = new ustring(v1->get_val_ustr());
8037 const ustring& s2 = v4->get_val_ustr();
8038 clean_up();
8039 valuetype=vt;
8040 s1->replace(i2, i3, s2);
8041 set_val_ustr(s1);
8042 u.ustr.convert_str = false;
8043 break;}
8044 default:
8045 FATAL_ERROR("Value::evaluate_value()");
8046 }
8047 break; }
8048 case OPTYPE_REGEXP: {
8049 if (is_unfoldable()) break;
8050 v1=u.expr.ti1->get_specific_value()->get_value_refd_last();
8051 v2=u.expr.t2->get_specific_value()->get_value_refd_last();
8052 v3=u.expr.v3->get_value_refd_last();
8053 const int_val_t *i3_int = v3->get_val_Int();
8054 Int i3 = i3_int->get_val();
8055 if (v1->valuetype == V_CSTR) {
8056 const string& s1 = v1->get_val_str();
8057 const string& s2 = v2->get_val_str();
8058 string *result = regexp(s1, s2, i3);
8059 clean_up();
8060 valuetype = V_CSTR;
8061 set_val_str(result);
8062 } if (v1->valuetype == V_USTR) {
8063 const ustring& s1 = v1->get_val_ustr();
8064 const ustring& s2 = v2->get_val_ustr();
8065 ustring *result = regexp(s1, s2, i3);
8066 clean_up();
8067 valuetype = V_USTR;
8068 set_val_ustr(result);
8069 u.ustr.convert_str = false;
8070 }
8071 break; }
8072 case OPTYPE_LENGTHOF:{
8073 if(is_unfoldable()) break;
8074 v1=u.expr.ti1->get_Template()->get_specific_value()
8075 ->get_value_refd_last();
8076 size_t i;
8077 if(v1->is_string_type(exp_val)) {
8078 i=v1->get_val_strlen();
8079 } else { // v1 is be seq/set of or array
8080 switch (v1->valuetype) {
8081 case V_SEQOF:
8082 case V_SETOF:
8083 case V_ARRAY: {
8084 if(v1->u.val_vs->is_indexed())
8085 { i = v1->u.val_vs->get_nof_ivs();}
8086 else { i = v1->u.val_vs->get_nof_vs();}
8087 break; }
8088 default:
8089 FATAL_ERROR("Value::evaluate_value()");
8090 }
8091 }
8092 clean_up();
8093 valuetype=V_INT;
8094 u.val_Int=new int_val_t(i);
8095 break;}
8096 case OPTYPE_SIZEOF: {
8097 Int i=chk_eval_expr_sizeof(refch, exp_val);
8098 if(i!=-1) {
8099 clean_up();
8100 valuetype=V_INT;
8101 u.val_Int=new int_val_t(i);
8102 }
8103 break;}
8104 case OPTYPE_ISVALUE: {
8105 if(is_unfoldable()) break;
8106 bool is_singleval = !u.expr.ti1->get_DerivedRef()
8107 && u.expr.ti1->get_Template()->is_Value();
8108 if (is_singleval) {
8109 Value * other_val = u.expr.ti1->get_Template()->get_Value();
8110 is_singleval = other_val->evaluate_isvalue(false);
8111 // is_singleval now contains the compile-time result of isvalue
8112 delete other_val;
8113 }
8114 clean_up();
8115 valuetype = V_BOOL;
8116 u.val_bool = is_singleval;
8117 break;}
8118 case OPTYPE_ISCHOSEN_V: {
8119 if (is_unfoldable()) break;
8120 v1 = u.expr.v1->get_value_refd_last();
8121 bool b = v1->field_is_chosen(*u.expr.i2);
8122 clean_up();
8123 valuetype = V_BOOL;
8124 u.val_bool = b;
8125 break; }
8126 case OPTYPE_VALUEOF: // ti1
8127 if (!u.expr.ti1->get_DerivedRef() &&
8128 u.expr.ti1->get_Template()->is_Value() &&
8129 !u.expr.ti1->get_Type()) {
8130 // FIXME actually if the template instance has a type
8131 // it might still be foldable.
8132 // the argument is a single specific value
8133 v1 = u.expr.ti1->get_Template()->get_Value();
8134 Type *governor = my_governor;
8135 if (governor == NULL) {
8136 governor = u.expr.ti1->get_expr_governor(exp_val);
8137 if (governor != NULL) governor = governor->get_type_refd_last();
8138 }
8139 if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
8140 if (governor == NULL)
8141 FATAL_ERROR("Value::evaluate_value()");
8142 clean_up();
8143 valuetype = v1->valuetype;
8144 u = v1->u;
8145 set_my_governor(governor);
8146 if (valuetype == V_REFD && u.ref.refd_last == v1)
8147 u.ref.refd_last = this;
8148 v1->valuetype = V_ERROR;
8149 delete v1;
8150 }
8151 break;
8152 case OPTYPE_UNDEF_RUNNING:
8153 default:
8154 FATAL_ERROR("Value::evaluate_value()");
8155 } // switch optype
8156 }
8157
8158 bool Value::evaluate_isvalue(bool from_sequence)
8159 {
8160 switch (valuetype) {
8161 case V_OMIT:
8162 // Omit is not a value unless a member of a sequence or set
8163 return from_sequence;
8164 case V_NOTUSED:
8165 return false;
8166 case V_NULL: /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
8167 case V_BOOL: /**< boolean */
8168 case V_NAMEDINT: /**< integer / named number */
8169 case V_NAMEDBITS: /**< named bits (identifiers) */
8170 case V_INT: /**< integer */
8171 case V_REAL: /**< real/float */
8172 case V_ENUM: /**< enumerated */
8173 case V_BSTR: /**< bitstring */
8174 case V_HSTR: /**< hexstring */
8175 case V_OSTR: /**< octetstring */
8176 case V_CSTR: /**< charstring */
8177 case V_USTR: /**< universal charstring */
8178 case V_ISO2022STR: /**< ISO-2022 string (treat as octetstring) */
8179 case V_CHARSYMS: /**< parsed ASN.1 universal string notation */
8180 case V_OID: /**< object identifier */
8181 case V_ROID: /**< relative object identifier */
8182 case V_VERDICT: /**< all verdicts */
8183 return true; // values of built-in types return true
8184
8185 // Code below was adapted from is_unfoldable(), false returned early.
8186 case V_CHOICE:
8187 return u.choice.alt_value->evaluate_isvalue(false);
8188
8189 case V_SEQOF:
8190 case V_SETOF:
8191 case V_ARRAY:
8192 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8193 if (!u.val_vs->get_v_byIndex(i)->evaluate_isvalue(false)) {
8194 return false;
8195 }
8196 }
8197 return true;
8198
8199 case V_SEQ:
8200 case V_SET:
8201 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8202 if (!u.val_nvs->get_nv_byIndex(i)->get_value()
8203 ->evaluate_isvalue(true)) return false;
8204 }
8205 return true;
8206
8207 case V_REFD:
8208 // alas, get_value_refd_last prevents this function from const
8209 return get_value_refd_last()->evaluate_isvalue(false);
8210
8211 case V_EXPR:
8212 switch (u.expr.v_optype) {
8213 // A constant null component reference is a corner case: it is foldable
8214 // but escapes unmodified from evaluate_value.
8215 // A V_EXPR with any other OPTYPE_ is either unfoldable,
8216 // or is transformed into some other valuetype in evaluate_value.
8217 case OPTYPE_COMP_NULL:
8218 return false;
8219 default:
8220 break; // and fall through to the FATAL_ERROR
8221 }
8222 // no break
8223 default:
8224 FATAL_ERROR("Value::evaluate_isvalue()");
8225 break;
8226 }
8227 return true;
8228 }
8229
8230 void Value::evaluate_macro(Type::expected_value_t exp_val)
8231 {
8232 switch (u.macro) {
8233 case MACRO_MODULEID:
8234 if (!my_scope)
8235 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8236 set_val_str(new string(my_scope->get_scope_mod()
8237 ->get_modid().get_dispname()));
8238 valuetype = V_CSTR;
8239 break;
8240 case MACRO_FILENAME:
8241 case MACRO_BFILENAME: {
8242 const char *t_filename = get_filename();
8243 if (!t_filename)
8244 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8245 set_val_str(new string(t_filename));
8246 valuetype = V_CSTR;
8247 break; }
8248 case MACRO_FILEPATH: {
8249 const char *t_filename = get_filename();
8250 if (!t_filename)
8251 FATAL_ERROR("Value::evaluate_macro(): file name is not set");
8252 char *t_filepath = canonize_input_file(t_filename);
8253 if (!t_filepath)
8254 FATAL_ERROR("Value::evaluate_macro(): file path cannot be determined");
8255 set_val_str(new string(t_filepath));
8256 valuetype = V_CSTR;
8257 Free(t_filepath);
8258 break; }
8259 case MACRO_LINENUMBER: {
8260 int t_lineno = get_first_line();
8261 if (t_lineno <= 0)
8262 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8263 set_val_str(new string(Int2string(t_lineno)));
8264 valuetype = V_CSTR;
8265 break; }
8266 case MACRO_LINENUMBER_C: {
8267 int t_lineno = get_first_line();
8268 if (t_lineno <= 0)
8269 FATAL_ERROR("Value::evaluate_macro(): line number is not set");
8270 u.val_Int = new int_val_t(t_lineno);
8271 valuetype = V_INT;
8272 break; }
8273 case MACRO_DEFINITIONID: {
8274 // cut the second part from the fullname separated by dots
8275 const string& t_fullname = get_fullname();
8276 size_t first_char = t_fullname.find('.') + 1;
8277 if (first_char >= t_fullname.size())
8278 FATAL_ERROR("Value::evaluate_macro(): malformed fullname: `%s'", \
8279 t_fullname.c_str());
8280 set_val_str(new string(t_fullname.substr(first_char,
8281 t_fullname.find('.', first_char) - first_char)));
8282 valuetype = V_CSTR;
8283 break; }
8284 case MACRO_SCOPE: {
8285 if (!my_scope) FATAL_ERROR("Value::evaluate_macro(): scope is not set");
8286 set_val_str(new string(my_scope->get_scopeMacro_name()));
8287 valuetype = V_CSTR;
8288 break;
8289 }
8290 case MACRO_TESTCASEID: {
8291 if (exp_val == Type::EXPECTED_CONSTANT ||
8292 exp_val == Type::EXPECTED_STATIC_VALUE) {
8293 error("A %s value was expected instead of macro `%%testcaseId', "
8294 "which is evaluated at runtime",
8295 exp_val == Type::EXPECTED_CONSTANT ? "constant" : "static");
8296 goto error;
8297 }
8298 if (!my_scope)
8299 FATAL_ERROR("Value::evaluate_macro(): my_scope is not set");
8300 Ttcn::StatementBlock *my_sb =
8301 dynamic_cast<Ttcn::StatementBlock*>(my_scope);
8302 if (!my_sb) {
8303 error("Usage of macro %%testcaseId is allowed only within the "
8304 "statement blocks of functions, altsteps and testcases");
8305 goto error;
8306 }
8307 Ttcn::Definition *my_def = my_sb->get_my_def();
8308 if (!my_def) {
8309 error("Macro %%testcaseId cannot be used in the control part. "
8310 "It is allowed only within the statement blocks of functions, "
8311 "altsteps and testcases");
8312 goto error;
8313 }
8314 if (my_def->get_asstype() == Assignment::A_TESTCASE) {
8315 // folding is possible only within testcases
8316 set_val_str(new string(my_def->get_id().get_dispname()));
8317 valuetype = V_CSTR;
8318 }
8319 break; }
8320 default:
8321 FATAL_ERROR("Value::evaluate_macro()");
8322 }
8323 return;
8324 error:
8325 set_valuetype(V_ERROR);
8326 }
8327
8328 void Value::add_id(Identifier *p_id)
8329 {
8330 switch(valuetype) {
8331 case V_NAMEDBITS:
8332 if(u.ids->has_key(p_id->get_name())) {
8333 error("Duplicate named bit `%s'", p_id->get_dispname().c_str());
8334 // The Value does not take ownership for the identifier,
8335 // so it must be deleted (add_is acts as a sink).
8336 delete p_id;
8337 }
8338 else u.ids->add(p_id->get_name(), p_id);
8339 break;
8340 default:
8341 FATAL_ERROR("Value::add_id()");
8342 } // switch
8343 }
8344
8345 Value* Value::get_value_refd_last(ReferenceChain *refch,
8346 Type::expected_value_t exp_val)
8347 {
8348 set_lowerid_to_ref();
8349 switch (valuetype) {
8350 case V_INVOKE:
8351 // there might be a better place for this
8352 chk_invoke(exp_val);
8353 return this;
8354 case V_REFD:
8355 // use the cache if available
8356 if (u.ref.refd_last) return u.ref.refd_last;
8357 else {
8358 Assignment *ass = u.ref.ref->get_refd_assignment();
8359 if (!ass) {
8360 // the referred definition is not found
8361 set_valuetype(V_ERROR);
8362 } else {
8363 switch (ass->get_asstype()) {
8364 case Assignment::A_OBJECT:
8365 case Assignment::A_OS: {
8366 // the referred definition is an ASN.1 object or object set
8367 Setting *setting = u.ref.ref->get_refd_setting();
8368 if (!setting || setting->get_st() == S_ERROR) {
8369 // remain silent, the error has been already reported
8370 set_valuetype(V_ERROR);
8371 break;
8372 } else if (setting->get_st() != S_V) {
8373 u.ref.ref->error("InformationFromObjects construct `%s' does not"
8374 " refer to a value", u.ref.ref->get_dispname().c_str());
8375 set_valuetype(V_ERROR);
8376 break;
8377 }
8378 bool destroy_refch;
8379 if (refch) {
8380 refch->mark_state();
8381 destroy_refch = false;
8382 } else {
8383 refch = new ReferenceChain(this,
8384 "While searching referenced value");
8385 destroy_refch = true;
8386 }
8387 if (refch->add(get_fullname())) {
8388 Value *v_refd = dynamic_cast<Value*>(setting);
8389 Value *v_last = v_refd->get_value_refd_last(refch);
8390 // in case of circular recursion the valuetype is already set
8391 // to V_ERROR, so don't set the cache
8392 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8393 } else {
8394 // a circular recursion was detected
8395 set_valuetype(V_ERROR);
8396 }
8397 if (destroy_refch) delete refch;
8398 else refch->prev_state();
8399 break; }
8400 case Assignment::A_CONST: {
8401 // the referred definition is a constant
8402 bool destroy_refch;
8403 if (refch) {
8404 refch->mark_state();
8405 destroy_refch = false;
8406 } else {
8407 refch = new ReferenceChain(this,
8408 "While searching referenced value");
8409 destroy_refch = true;
8410 }
8411 if (refch->add(get_fullname())) {
8412 Ttcn::FieldOrArrayRefs *subrefs = u.ref.ref->get_subrefs();
8413 Value *v_refd = ass->get_Value()
8414 ->get_refd_sub_value(subrefs, 0,
8415 u.ref.ref->getUsedInIsbound(), refch);
8416 if (v_refd) {
8417 Value *v_last = v_refd->get_value_refd_last(refch);
8418 // in case of circular recursion the valuetype is already set
8419 // to V_ERROR, so don't set the cache
8420 if (valuetype == V_REFD) u.ref.refd_last = v_last;
8421 } else if (subrefs && subrefs->has_unfoldable_index()) {
8422 u.ref.refd_last = this;
8423 } else if (u.ref.ref->getUsedInIsbound()) {
8424 u.ref.refd_last = this;
8425 } else {
8426 // the sub-reference points to a non-existent field
8427 set_valuetype(V_ERROR);
8428 }
8429 } else {
8430 // a circular recursion was detected
8431 set_valuetype(V_ERROR);
8432 }
8433 if (destroy_refch) delete refch;
8434 else refch->prev_state();
8435 break; }
8436 case Assignment::A_EXT_CONST:
8437 case Assignment::A_MODULEPAR:
8438 case Assignment::A_VAR:
8439 case Assignment::A_FUNCTION_RVAL:
8440 case Assignment::A_EXT_FUNCTION_RVAL:
8441 case Assignment::A_PAR_VAL_IN:
8442 case Assignment::A_PAR_VAL_OUT:
8443 case Assignment::A_PAR_VAL_INOUT:
8444 // the referred definition is not a constant
8445 u.ref.refd_last = this;
8446 break;
8447 case Assignment::A_FUNCTION:
8448 case Assignment::A_EXT_FUNCTION:
8449 u.ref.ref->error("Reference to a value was expected instead of a "
8450 "call of %s, which does not have return type",
8451 ass->get_description().c_str());
8452 set_valuetype(V_ERROR);
8453 break;
8454 case Assignment::A_FUNCTION_RTEMP:
8455 case Assignment::A_EXT_FUNCTION_RTEMP:
8456 u.ref.ref->error("Reference to a value was expected instead of a "
8457 "call of %s, which returns a template",
8458 ass->get_description().c_str());
8459 set_valuetype(V_ERROR);
8460 break;
8461 default:
8462 u.ref.ref->error("Reference to a value was expected instead of %s",
8463 ass->get_description().c_str());
8464 set_valuetype(V_ERROR);
8465 } // switch asstype
8466 }
8467 if (valuetype == V_REFD) return u.ref.refd_last;
8468 else return this;
8469 }
8470 case V_EXPR: {
8471 // try to evaluate the expression
8472 bool destroy_refch;
8473 if(refch) {
8474 refch->mark_state();
8475 destroy_refch=false;
8476 }
8477 else {
8478 refch=new ReferenceChain(this, "While evaluating expression");
8479 destroy_refch=true;
8480 }
8481 if(refch->add(get_fullname())) evaluate_value(refch, exp_val);
8482 else set_valuetype(V_ERROR);
8483 if(destroy_refch) delete refch;
8484 else refch->prev_state();
8485 return this; }
8486 case V_MACRO:
8487 evaluate_macro(exp_val);
8488 // no break
8489 default:
8490 // return this for all other value types
8491 return this;
8492 } // switch
8493 }
8494
8495 map<Value*, void> Value::UnfoldabilityCheck::running;
8496
8497 /* Note that the logic here needs to be in sync with evaluate_value,
8498 * and possibly others, i.e. if evaluate_value is called for a Value
8499 * for which is_unfoldable returns false, FATAL_ERROR might happen. */
8500 bool Value::is_unfoldable(ReferenceChain *refch,
8501 Type::expected_value_t exp_val)
8502 {
8503 if (UnfoldabilityCheck::is_running(this)) {
8504 // This function is already running on this value => infinite recursion
8505 return true;
8506 }
8507
8508 UnfoldabilityCheck checker(this);
8509
8510 if (get_needs_conversion()) return true;
8511 switch (valuetype) {
8512 case V_NAMEDINT:
8513 case V_NAMEDBITS:
8514 case V_OPENTYPE:
8515 case V_UNDEF_LOWERID:
8516 case V_UNDEF_BLOCK:
8517 case V_TTCN3_NULL:
8518 case V_REFER:
8519 // these value types are eliminated during semantic analysis
8520 FATAL_ERROR("Value::is_unfoldable()");
8521 case V_ERROR:
8522 case V_INVOKE:
8523 return true;
8524 case V_CHOICE:
8525 return u.choice.alt_value->is_unfoldable(refch, exp_val);
8526 case V_SEQOF:
8527 case V_SETOF:
8528 case V_ARRAY:
8529 if (!is_indexed()) {
8530 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
8531 if (u.val_vs->get_v_byIndex(i)->is_unfoldable(refch, exp_val))
8532 return true;
8533 }
8534 } else {
8535 for(size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
8536 if (u.val_vs->get_iv_byIndex(i)->is_unfoldable(refch, exp_val))
8537 return true;
8538 }
8539 }
8540 return false;
8541 case V_SEQ:
8542 case V_SET:
8543 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
8544 if (u.val_nvs->get_nv_byIndex(i)->get_value()
8545 ->is_unfoldable(refch, exp_val)) return true;
8546 }
8547 return false;
8548 case V_OID:
8549 case V_ROID:
8550 chk();
8551 for (size_t i = 0; i < u.oid_comps->size(); ++i) {
8552 if ((*u.oid_comps)[i]->is_variable()) return true;
8553 }
8554 return false;
8555 case V_REFD: {
8556 Value *v_last=get_value_refd_last(refch, exp_val);
8557 if(v_last==this) return true; // there weren't any references to chase
8558 else return v_last->is_unfoldable(refch, exp_val);
8559 }
8560 case V_EXPR:
8561 // classify the unchecked ischosen() operation, if it was not done so far
8562 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
8563 if(u.expr.state==EXPR_CHECKING_ERR) return true;
8564 switch (u.expr.v_optype) {
8565 case OPTYPE_RND: // -
8566 case OPTYPE_COMP_MTC:
8567 case OPTYPE_COMP_SYSTEM:
8568 case OPTYPE_COMP_SELF:
8569 case OPTYPE_COMP_RUNNING_ANY:
8570 case OPTYPE_COMP_RUNNING_ALL:
8571 case OPTYPE_COMP_ALIVE_ANY:
8572 case OPTYPE_COMP_ALIVE_ALL:
8573 case OPTYPE_TMR_RUNNING_ANY:
8574 case OPTYPE_GETVERDICT:
8575 case OPTYPE_TESTCASENAME:
a38c6d4c 8576 case OPTYPE_PROF_RUNNING:
970ed795
EL
8577 case OPTYPE_RNDWITHVAL: // v1
8578 case OPTYPE_MATCH: // v1 t2
8579 case OPTYPE_UNDEF_RUNNING: // v1
8580 case OPTYPE_COMP_RUNNING:
8581 case OPTYPE_COMP_ALIVE:
8582 case OPTYPE_TMR_READ:
8583 case OPTYPE_TMR_RUNNING:
8584 case OPTYPE_ACTIVATE:
8585 case OPTYPE_ACTIVATE_REFD:
8586 case OPTYPE_EXECUTE: // r1 [v2]
8587 case OPTYPE_EXECUTE_REFD:
8588 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
8589 case OPTYPE_ISCHOSEN:
8590 case OPTYPE_ISCHOSEN_T:
8591 case OPTYPE_SIZEOF: // ti1
8592 case OPTYPE_DECODE:
8593 case OPTYPE_ENCODE:
8594 case OPTYPE_OCT2UNICHAR:
8595 case OPTYPE_UNICHAR2OCT:
8596 case OPTYPE_ENCODE_BASE64:
8597 case OPTYPE_DECODE_BASE64:
1d0599f0 8598 case OPTYPE_ENCVALUE_UNICHAR:
8599 case OPTYPE_DECVALUE_UNICHAR:
0a1610f4 8600 case OPTYPE_CHECKSTATE_ANY:
8601 case OPTYPE_CHECKSTATE_ALL:
efbe586d 8602 case OPTYPE_HOSTID:
970ed795
EL
8603 return true;
8604 case OPTYPE_COMP_NULL: // -
8605 return false;
8606 case OPTYPE_UNARYPLUS: // v1
8607 case OPTYPE_UNARYMINUS:
8608 case OPTYPE_NOT:
8609 case OPTYPE_NOT4B:
8610 case OPTYPE_BIT2HEX:
8611 case OPTYPE_BIT2INT:
8612 case OPTYPE_BIT2OCT:
8613 case OPTYPE_BIT2STR:
8614 case OPTYPE_CHAR2INT:
8615 case OPTYPE_CHAR2OCT:
8616 case OPTYPE_FLOAT2INT:
8617 case OPTYPE_FLOAT2STR:
8618 case OPTYPE_HEX2BIT:
8619 case OPTYPE_HEX2INT:
8620 case OPTYPE_HEX2OCT:
8621 case OPTYPE_HEX2STR:
8622 case OPTYPE_INT2CHAR:
8623 case OPTYPE_INT2FLOAT:
8624 case OPTYPE_INT2STR:
8625 case OPTYPE_INT2UNICHAR:
8626 case OPTYPE_OCT2BIT:
8627 case OPTYPE_OCT2CHAR:
8628 case OPTYPE_OCT2HEX:
8629 case OPTYPE_OCT2INT:
8630 case OPTYPE_OCT2STR:
8631 case OPTYPE_STR2BIT:
8632 case OPTYPE_STR2FLOAT:
8633 case OPTYPE_STR2HEX:
8634 case OPTYPE_STR2INT:
8635 case OPTYPE_STR2OCT:
8636 case OPTYPE_UNICHAR2INT:
8637 case OPTYPE_UNICHAR2CHAR:
8638 case OPTYPE_ENUM2INT:
8639 case OPTYPE_GET_STRINGENCODING:
8640 case OPTYPE_REMOVE_BOM:
8641 return u.expr.v1->is_unfoldable(refch, exp_val);
8642 case OPTYPE_ISBOUND: /*{
8643 //TODO once we have the time for it make isbound foldable.
8644 if (u.expr.ti1->get_DerivedRef() != 0) return true;
8645 Template* temp = u.expr.ti1->get_Template();
8646 if (temp->get_templatetype() == Template::SPECIFIC_VALUE) {
8647 Value* specificValue = temp->get_specific_value();
8648 if (specificValue->get_valuetype() == Value::V_REFD) {
8649 //FIXME implement
8650 }
8651
8652 return specificValue->is_unfoldable(refch, exp_val);
8653 } else if (temp->get_templatetype() == Template::TEMPLATE_REFD) {
8654 //FIXME implement
8655 }
8656 }*/
8657 return true;
8658 case OPTYPE_ISPRESENT:
8659 // TODO: "if you have motivation"
8660 return true;
8661 case OPTYPE_ISVALUE: // ti1
8662 // fallthrough
8663 case OPTYPE_LENGTHOF: // ti1
8664 return u.expr.ti1->get_DerivedRef() != 0
8665 || u.expr.ti1->get_Template()->get_templatetype()
8666 != Template::SPECIFIC_VALUE
8667 || u.expr.ti1->get_Template()->get_specific_value()
8668 ->is_unfoldable(refch, exp_val);
8669 case OPTYPE_ROTL:
8670 case OPTYPE_ROTR:
8671 case OPTYPE_CONCAT:
8672 if (!u.expr.v1->is_string_type(exp_val)) return true;
8673 // no break
8674 case OPTYPE_ADD: // v1 v2
8675 case OPTYPE_SUBTRACT:
8676 case OPTYPE_MULTIPLY:
8677 case OPTYPE_DIVIDE:
8678 case OPTYPE_MOD:
8679 case OPTYPE_REM:
8680 case OPTYPE_EQ:
8681 case OPTYPE_LT:
8682 case OPTYPE_GT:
8683 case OPTYPE_NE:
8684 case OPTYPE_GE:
8685 case OPTYPE_LE:
8686 case OPTYPE_XOR:
8687 case OPTYPE_AND4B:
8688 case OPTYPE_OR4B:
8689 case OPTYPE_XOR4B:
8690 case OPTYPE_SHL:
8691 case OPTYPE_SHR:
8692 case OPTYPE_INT2BIT:
8693 case OPTYPE_INT2HEX:
8694 case OPTYPE_INT2OCT:
8695 return u.expr.v1->is_unfoldable(refch, exp_val)
8696 || u.expr.v2->is_unfoldable(refch, exp_val);
8697 case OPTYPE_AND: // short-circuit evaluation
8698 return u.expr.v1->is_unfoldable(refch, exp_val)
8699 || (u.expr.v1->get_val_bool() &&
8700 u.expr.v2->is_unfoldable(refch, exp_val));
8701 case OPTYPE_OR: // short-circuit evaluation
8702 return u.expr.v1->is_unfoldable(refch, exp_val)
8703 || (!u.expr.v1->get_val_bool() &&
8704 u.expr.v2->is_unfoldable(refch, exp_val));
8705 case OPTYPE_SUBSTR:
8706 if (!u.expr.ti1->get_specific_value()) return true;
8707 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8708 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8709 || u.expr.v2->is_unfoldable(refch, exp_val)
8710 || u.expr.v3->is_unfoldable(refch, exp_val);
8711 case OPTYPE_REGEXP:
8712 if (!u.expr.ti1->get_specific_value() ||
8713 !u.expr.t2->get_specific_value()) return true;
8714 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8715 || u.expr.t2->get_specific_value()->is_unfoldable(refch, exp_val)
8716 || u.expr.v3->is_unfoldable(refch, exp_val);
8717 case OPTYPE_DECOMP:
8718 return u.expr.v1->is_unfoldable(refch, exp_val)
8719 || u.expr.v2->is_unfoldable(refch, exp_val)
8720 || u.expr.v3->is_unfoldable(refch, exp_val);
8721 case OPTYPE_REPLACE: {
8722 if (!u.expr.ti1->get_specific_value() ||
8723 !u.expr.ti4->get_specific_value()) return true;
8724 if (!u.expr.ti1->is_string_type(exp_val)) return true;
8725 return u.expr.ti1->get_specific_value()->is_unfoldable(refch, exp_val)
8726 || u.expr.v2->is_unfoldable(refch, exp_val)
8727 || u.expr.v3->is_unfoldable(refch, exp_val)
8728 || u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
8729 }
8730 case OPTYPE_VALUEOF: // ti1
8731 /* \todo if you have motivation to implement the eval function
8732 for valueof()... */
8733 return true;
8734 case OPTYPE_ISCHOSEN_V:
8735 return u.expr.v1->is_unfoldable(refch, exp_val);
8736 case OPTYPE_LOG2STR:
a50716c1 8737 case OPTYPE_ANY2UNISTR:
970ed795
EL
8738 case OPTYPE_TTCN2STRING:
8739 return true;
8740 default:
8741 FATAL_ERROR("Value::is_unfoldable()");
8742 } // switch
8743 break; // should never get here
8744 case V_MACRO:
8745 switch (u.macro) {
8746 case MACRO_TESTCASEID:
8747 // this is known only at runtime
8748 return true;
8749 default:
8750 return false;
8751 }
8752 default:
8753 // all literal values are foldable
8754 return false;
8755 }
8756 }
8757
8758 Value* Value::get_refd_sub_value(Ttcn::FieldOrArrayRefs *subrefs,
8759 size_t start_i, bool usedInIsbound,
8760 ReferenceChain *refch)
8761 {
8762 if (!subrefs) return this;
8763 Value *v = this;
8764 for (size_t i = start_i; i < subrefs->get_nof_refs(); i++) {
8765 if (!v) break;
8766 v = v->get_value_refd_last(refch);
8767 switch(v->valuetype) {
8768 case V_ERROR:
8769 return v;
8770 case V_REFD:
8771 // unfoldable stuff
8772 return this;
8773 default:
8774 break;
8775 } // switch
8776 Ttcn::FieldOrArrayRef *ref = subrefs->get_ref(i);
8777 if (ref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF)
8778 v = v->get_refd_field_value(*ref->get_id(), usedInIsbound, *ref);
8779 else v = v->get_refd_array_value(ref->get_val(), usedInIsbound, refch);
8780 }
8781 return v;
8782 }
8783
8784 Value *Value::get_refd_field_value(const Identifier& field_id,
8785 bool usedInIsbound, const Location& loc)
8786 {
8787 if (valuetype == V_OMIT) {
8788 loc.error("Reference to field `%s' of omit value `%s'",
8789 field_id.get_dispname().c_str(), get_fullname().c_str());
8790 return 0;
8791 }
8792 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8793 Type *t = my_governor->get_type_refd_last();
8794 switch (t->get_typetype()) {
8795 case Type::T_ERROR:
8796 // remain silent
8797 return 0;
8798 case Type::T_CHOICE_A:
8799 case Type::T_CHOICE_T:
8800 case Type::T_OPENTYPE:
8801 case Type::T_ANYTYPE:
8802 if (!t->has_comp_withName(field_id)) {
8803 loc.error("Reference to non-existent union field `%s' in type `%s'",
8804 field_id.get_dispname().c_str(), t->get_typename().c_str());
8805 return 0;
8806 } else if (valuetype != V_CHOICE) {
8807 // remain silent, the error is already reported
8808 return 0;
8809 } else if (*u.choice.alt_name == field_id) {
8810 // everything is OK
8811 return u.choice.alt_value;
8812 }else {
8813 if (!usedInIsbound) {
8814 loc.error("Reference to inactive field `%s' in a value of union type "
8815 "`%s'. The active field is `%s'",
8816 field_id.get_dispname().c_str(), t->get_typename().c_str(),
8817 u.choice.alt_name->get_dispname().c_str());
8818 }
8819 return 0;
8820 }
8821 case Type::T_SEQ_A:
8822 case Type::T_SEQ_T:
8823 if (!t->has_comp_withName(field_id)) {
8824 loc.error("Reference to non-existent record field `%s' in type `%s'",
8825 field_id.get_dispname().c_str(), t->get_typename().c_str());
8826 return 0;
8827 } else if (valuetype != V_SEQ) {
8828 // remain silent, the error has been already reported
8829 return 0;
8830 } else break;
8831 case Type::T_SET_A:
8832 case Type::T_SET_T:
8833 if (!t->has_comp_withName(field_id)) {
8834 loc.error("Reference to non-existent set field `%s' in type `%s'",
8835 field_id.get_dispname().c_str(), t->get_typename().c_str());
8836 return 0;
8837 } else if (valuetype != V_SET) {
8838 // remain silent, the error has been already reported
8839 return 0;
8840 } else break;
8841 default:
8842 loc.error("Invalid field reference `%s': type `%s' "
8843 "does not have fields", field_id.get_dispname().c_str(),
8844 t->get_typename().c_str());
8845 return 0;
8846 }
8847 // the common end for record & set types
8848 if (u.val_nvs->has_nv_withName(field_id)) {
8849 // everything is OK
8850 return u.val_nvs->get_nv_byName(field_id)->get_value();
8851 } else if (!is_asn1()) {
8852 if (!usedInIsbound) {
8853 loc.error("Reference to unbound field `%s'",
8854 field_id.get_dispname().c_str());
8855 // this is an error in TTCN-3, which has been already reported
8856 }
8857 return 0;
8858 } else {
8859 CompField *cf = t->get_comp_byName(field_id);
8860 if (cf->get_is_optional()) {
8861 // creating an explicit omit value
8862 Value *v = new Value(V_OMIT);
8863 v->set_fullname(get_fullname() + "." + field_id.get_dispname());
8864 v->set_my_scope(get_my_scope());
8865 u.val_nvs->add_nv(new NamedValue(field_id.clone(), v));
8866 return v;
8867 } else if (cf->has_default()) {
8868 // returning the component's default value
8869 return cf->get_defval();
8870 } else {
8871 // this is an error in ASN.1, which has been already reported
8872 return 0;
8873 }
8874 }
8875 }
8876
8877 Value *Value::get_refd_array_value(Value *array_index, bool usedInIsbound,
8878 ReferenceChain *refch)
8879 {
8880 Value *v_index = array_index->get_value_refd_last(refch);
8881 Int index = 0;
8882 bool index_available = false;
8883 if (!v_index->is_unfoldable()) {
8884 if (v_index->valuetype == V_INT) {
8885 index = v_index->get_val_Int()->get_val();
8886 index_available = true;
8887 } else {
8888 array_index->error("An integer value was expected as index");
8889 }
8890 }
8891 if (valuetype == V_OMIT) {
8892 array_index->error("Accessing an element with index of omit value `%s'",
8893 get_fullname().c_str());
8894 return 0;
8895 }
8896 if (!my_governor) FATAL_ERROR("Value::get_refd_field_value()");
8897 Type *t = my_governor->get_type_refd_last();
8898 switch (t->get_typetype()) {
8899 case Type::T_ERROR:
8900 // remain silent
8901 return 0;
8902 case Type::T_SEQOF:
8903 if (index_available) {
8904 if (index < 0) {
8905 array_index->error("A non-negative integer value was expected "
8906 "instead of %s for indexing a value of `record "
8907 "of' type `%s'", Int2string(index).c_str(),
8908 t->get_typename().c_str());
8909 return 0;
8910 }
8911 switch (valuetype) {
8912 case V_SEQOF:
8913 if (!is_indexed()) {
8914 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8915 if (!usedInIsbound) {
8916 array_index->error("Index overflow in a value of `record of' "
8917 "type `%s': the index is %s, but the value "
8918 "has only %lu elements",
8919 t->get_typename().c_str(),
8920 Int2string(index).c_str(),
8921 (unsigned long)u.val_vs->get_nof_vs());
8922 }
8923 return 0;
8924 } else {
8925 Value* temp = u.val_vs->get_v_byIndex(index);
8926 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8927 temp->error("Not used symbol is not allowed in this context");
8928 return u.val_vs->get_v_byIndex(index);
8929 }
8930 } else {
8931 // Search the appropriate constant index.
8932 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8933 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8934 ->get_value_refd_last();
8935 if (iv_index->get_valuetype() != V_INT) continue;
8936 if (iv_index->get_val_Int()->get_val() == index)
8937 return u.val_vs->get_iv_byIndex(i)->get_value();
8938 }
8939 return 0;
8940 }
8941 break;
8942 default:
8943 // remain silent, the error has been already reported
8944 return 0;
8945 }
8946 } else {
8947 // the error has been reported above
8948 return 0;
8949 }
8950 case Type::T_SETOF:
8951 if (index_available) {
8952 if (index < 0) {
8953 array_index->error("A non-negative integer value was expected "
8954 "instead of %s for indexing a value of `set of' type `%s'",
8955 Int2string(index).c_str(), t->get_typename().c_str());
8956 return 0;
8957 }
8958 switch (valuetype) {
8959 case V_SETOF:
8960 if (!is_indexed()) {
8961 if (index >= static_cast<Int>(u.val_vs->get_nof_vs())) {
8962 if (!usedInIsbound) {
8963 array_index->error("Index overflow in a value of `set of' type "
8964 "`%s': the index is %s, but the value has "
8965 "only %lu elements",
8966 t->get_typename().c_str(),
8967 Int2string(index).c_str(),
8968 (unsigned long)u.val_vs->get_nof_vs());
8969 }
8970 return 0;
8971 } else {
8972 Value* temp = u.val_vs->get_v_byIndex(index);
8973 if(temp->get_value_refd_last()->get_valuetype() == V_NOTUSED)
8974 temp->error("Not used symbol is not allowed in this context");
8975 return temp;
8976 }
8977 } else {
8978 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
8979 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
8980 ->get_value_refd_last();
8981 if (iv_index->get_valuetype() != V_INT) continue;
8982 if (iv_index->get_val_Int()->get_val() == index)
8983 return u.val_vs->get_iv_byIndex(i)->get_value();
8984 }
8985 return 0;
8986 }
8987 break;
8988 default:
8989 // remain silent, the error has been already reported
8990 return 0;
8991 }
8992 } else {
8993 // the error has been reported above
8994 return 0;
8995 }
8996 case Type::T_ARRAY:
8997 if (index_available) {
8998 Ttcn::ArrayDimension *dim = t->get_dimension();
8999 dim->chk_index(v_index, Type::EXPECTED_CONSTANT);
9000 if (valuetype == V_ARRAY && !dim->get_has_error()) {
9001 // perform the index transformation
9002 index -= dim->get_offset();
9003 if (!is_indexed()) {
9004 // check for index underflow/overflow or too few elements in the
9005 // value
9006 if (index < 0 ||
9007 index >= static_cast<Int>(u.val_vs->get_nof_vs()))
9008 return 0;
9009 else return u.val_vs->get_v_byIndex(index);
9010 } else {
9011 if (index < 0) return 0;
9012 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
9013 Value *iv_index = u.val_vs->get_iv_byIndex(i)->get_index()
9014 ->get_value_refd_last();
9015 if (iv_index->get_valuetype() != V_INT) continue;
9016 if (iv_index->get_val_Int()->get_val() == index)
9017 return u.val_vs->get_iv_byIndex(index)->get_value();
9018 }
9019 return 0;
9020 }
9021 } else {
9022 // remain silent, the error has been already reported
9023 return 0;
9024 }
9025 } else {
9026 // the error has been reported above
9027 return 0;
9028 }
9029 case Type::T_BSTR:
9030 case Type::T_BSTR_A:
9031 case Type::T_HSTR:
9032 case Type::T_OSTR:
9033 case Type::T_CSTR:
9034 case Type::T_USTR:
9035 case Type::T_UTF8STRING:
9036 case Type::T_NUMERICSTRING:
9037 case Type::T_PRINTABLESTRING:
9038 case Type::T_TELETEXSTRING:
9039 case Type::T_VIDEOTEXSTRING:
9040 case Type::T_IA5STRING:
9041 case Type::T_GRAPHICSTRING:
9042 case Type::T_VISIBLESTRING:
9043 case Type::T_GENERALSTRING:
9044 case Type::T_UNIVERSALSTRING:
9045 case Type::T_BMPSTRING:
9046 case Type::T_UTCTIME:
9047 case Type::T_GENERALIZEDTIME:
9048 case Type::T_OBJECTDESCRIPTOR:
9049 if (index_available) return get_string_element(index, *array_index);
9050 else return 0;
9051 default:
9052 array_index->error("Invalid array element reference: type `%s' cannot "
9053 "be indexed", t->get_typename().c_str());
9054 return 0;
9055 }
9056 }
9057
9058 Value *Value::get_string_element(const Int& index, const Location& loc)
9059 {
9060 if (index < 0) {
9061 loc.error("A non-negative integer value was expected instead of %s "
9062 "for indexing a string element", Int2string(index).c_str());
9063 return 0;
9064 }
9065 size_t string_length;
9066 switch (valuetype) {
9067 case V_BSTR:
9068 case V_HSTR:
9069 case V_CSTR:
9070 case V_ISO2022STR:
9071 string_length = u.str.val_str->size();
9072 break;
9073 case V_OSTR:
9074 string_length = u.str.val_str->size() / 2;
9075 break;
9076 case V_USTR:
9077 string_length = u.ustr.val_ustr->size();
9078 break;
9079 default:
9080 // remain silent, the error has been already reported
9081 return 0;
9082 }
9083 if (index >= static_cast<Int>(string_length)) {
9084 loc.error("Index overflow when accessing a string element: "
9085 "the index is %s, but the string has only %lu elements",
9086 Int2string(index).c_str(), (unsigned long) string_length);
9087 return 0;
9088 }
9089 switch (valuetype) {
9090 case V_BSTR:
9091 case V_HSTR:
9092 case V_CSTR:
9093 case V_ISO2022STR:
9094 if (u.str.str_elements && u.str.str_elements->has_key(index))
9095 return (*u.str.str_elements)[index];
9096 else {
9097 Value *t_val = new Value(valuetype,
9098 new string(u.str.val_str->substr(index, 1)));
9099 add_string_element(index, t_val, u.str.str_elements);
9100 return t_val;
9101 }
9102 case V_OSTR:
9103 if (u.str.str_elements && u.str.str_elements->has_key(index))
9104 return (*u.str.str_elements)[index];
9105 else {
9106 Value *t_val = new Value(V_OSTR,
9107 new string(u.str.val_str->substr(2 * index, 2)));
9108 add_string_element(index, t_val, u.str.str_elements);
9109 return t_val;
9110 }
9111 case V_USTR:
9112 if (u.ustr.ustr_elements && u.ustr.ustr_elements->has_key(index))
9113 return (*u.ustr.ustr_elements)[index];
9114 else {
9115 Value *t_val = new Value(V_USTR,
9116 new ustring(u.ustr.val_ustr->substr(index, 1)));
9117 add_string_element(index, t_val, u.ustr.ustr_elements);
9118 return t_val;
9119 }
9120 default:
9121 FATAL_ERROR("Value::get_string_element()");
9122 return 0;
9123 }
9124 }
9125
9126 void Value::chk_expr_type(Type::typetype_t p_tt, const char *type_name,
9127 Type::expected_value_t exp_val)
9128 {
9129 set_lowerid_to_ref();
9130 Type::typetype_t r_tt = get_expr_returntype(exp_val);
9131 bool error_flag = r_tt != Type::T_ERROR && r_tt != p_tt;
9132 if (error_flag)
9133 error("A value or expression of type %s was expected", type_name);
9134 if (valuetype == V_REFD) {
9135 Type *t_chk = Type::get_pooltype(Type::T_ERROR);
9136 t_chk->chk_this_refd_value(this, 0, exp_val);
9137 }
9138 get_value_refd_last(0, exp_val);
9139 if (error_flag) set_valuetype(V_ERROR);
9140 else if (!my_governor) set_my_governor(Type::get_pooltype(p_tt));
9141 }
9142
9143 int Value::is_parsed_infinity()
9144 {
9145 if ( (get_valuetype()==V_REAL) && (get_val_Real()==REAL_INFINITY) )
9146 return 1;
9147 if ( (get_valuetype()==V_EXPR) && (get_optype()==OPTYPE_UNARYMINUS) &&
9148 (u.expr.v1->get_valuetype()==V_REAL) &&
9149 (u.expr.v1->get_val_Real()==REAL_INFINITY) )
9150 return -1;
9151 return 0;
9152 }
9153
9154 bool Value::get_val_bool()
9155 {
9156 Value *v;
9157 if (valuetype == V_REFD) v = get_value_refd_last();
9158 else v = this;
9159 if (v->valuetype != V_BOOL) FATAL_ERROR("Value::get_val_bool()");
9160 return v->u.val_bool;
9161 }
9162
9163 int_val_t* Value::get_val_Int()
9164 {
9165 Value *v;
9166 if (valuetype == V_REFD) v = get_value_refd_last();
9167 else v = this;
9168 switch (v->valuetype) {
9169 case V_INT:
9170 break;
9171 case V_UNDEF_LOWERID:
9172 FATAL_ERROR("Cannot use this value (here) as an integer: " \
9173 "`%s'", (*u.val_id).get_dispname().c_str());
9174 default:
9175 FATAL_ERROR("Value::get_val_Int()");
9176 } // switch
9177 return v->u.val_Int;
9178 }
9179
9180 const Identifier* Value::get_val_id()
9181 {
9182 switch(valuetype) {
9183 case V_NAMEDINT:
9184 case V_ENUM:
9185 case V_UNDEF_LOWERID:
9186 return u.val_id;
9187 default:
9188 FATAL_ERROR("Value::get_val_id()");
9189 return 0;
9190 } // switch
9191 }
9192
9193 const ttcn3float& Value::get_val_Real()
9194 {
9195 Value *v;
9196 if (valuetype == V_REFD) v = get_value_refd_last();
9197 else v = this;
9198 if (v->valuetype != V_REAL) FATAL_ERROR("Value::get_val_Real()");
9199 return v->u.val_Real;
9200 }
9201
9202 string Value::get_val_str()
9203 {
9204 Value *v = get_value_refd_last();
9205 switch (v->valuetype) {
9206 case V_BSTR:
9207 case V_HSTR:
9208 case V_OSTR:
9209 case V_CSTR:
9210 return *v->u.str.val_str;
9211 case V_CHARSYMS:
9212 return v->u.char_syms->get_string();
9213 case V_USTR:
9214 error("Cannot use ISO-10646 string value in string context");
9215 return string();
9216 case V_ISO2022STR:
9217 error("Cannot use ISO-2022 string value in string context");
9218 // no break
9219 case V_ERROR:
9220 return string();
9221 default:
9222 error("Cannot use this value in charstring value context");
9223 return string();
9224 } // switch
9225 }
9226
9227 ustring Value::get_val_ustr()
9228 {
9229 Value *v = get_value_refd_last();
9230 switch (v->valuetype) {
9231 case V_CSTR:
9232 return ustring(*v->u.str.val_str);
9233 case V_USTR:
9234 return *v->u.ustr.val_ustr;
9235 case V_CHARSYMS:
9236 return v->u.char_syms->get_ustring();
9237 case V_ISO2022STR:
9238 error("Cannot use ISO-2022 string value in ISO-10646 string context");
9239 // no break
9240 case V_ERROR:
9241 return ustring();
9242 default:
9243 error("Cannot use this value in ISO-10646 string context");
9244 return ustring();
9245 } // switch
9246 }
9247
9248 string Value::get_val_iso2022str()
9249 {
9250 Value *v = get_value_refd_last();
9251 switch (v->valuetype) {
9252 case V_CSTR:
9253 case V_ISO2022STR:
9254 return *v->u.str.val_str;
9255 case V_CHARSYMS:
9256 return v->u.char_syms->get_iso2022string();
9257 case V_USTR:
9258 error("Cannot use ISO-10646 string value in ISO-2022 string context");
9259 // no break
9260 case V_ERROR:
9261 return string();
9262 default:
9263 error("Cannot use this value in ISO-2022 string context");
9264 return string();
9265 } // switch
9266 }
9267
9268 size_t Value::get_val_strlen()
9269 {
9270 Value *v = get_value_refd_last();
9271 switch (v->valuetype) {
9272 case V_BSTR:
9273 case V_HSTR:
9274 case V_CSTR:
9275 case V_ISO2022STR:
9276 return v->u.str.val_str->size();
9277 case V_OSTR:
9278 return v->u.str.val_str->size()/2;
9279 case V_CHARSYMS:
9280 return v->u.char_syms->get_len();
9281 case V_USTR:
9282 return v->u.ustr.val_ustr->size();
9283 case V_ERROR:
9284 return 0;
9285 default:
9286 error("Cannot use this value in string value context");
9287 return 0;
9288 } // switch
9289 }
9290
9291 Value::verdict_t Value::get_val_verdict()
9292 {
9293 switch(valuetype) {
9294 case V_VERDICT:
9295 return u.verdict;
9296 default:
9297 FATAL_ERROR("Value::get_val_verdict()");
9298 return u.verdict;
9299 } // switch
9300 }
9301
9302 size_t Value::get_nof_comps()
9303 {
9304 switch (valuetype) {
9305 case V_OID:
9306 case V_ROID:
9307 chk();
9308 return u.oid_comps->size();
9309 case V_SEQOF:
9310 case V_SETOF:
9311 case V_ARRAY:
9312 if (u.val_vs->is_indexed()) return u.val_vs->get_nof_ivs();
9313 else return u.val_vs->get_nof_vs();
9314 case V_SEQ:
9315 case V_SET:
9316 return u.val_nvs->get_nof_nvs();
9317 case V_BSTR:
9318 case V_HSTR:
9319 case V_CSTR:
9320 case V_ISO2022STR:
9321 return u.str.val_str->size();
9322 case V_OSTR:
9323 return u.str.val_str->size()/2;
9324 case V_USTR:
9325 return u.ustr.val_ustr->size();
9326 default:
9327 FATAL_ERROR("Value::get_nof_comps()");
9328 return 0;
9329 } // switch
9330 }
9331
9332 bool Value::is_indexed() const
9333 {
9334 switch (valuetype) {
9335 case V_SEQOF:
9336 case V_SETOF:
9337 case V_ARRAY:
9338 // Applicable only for list-types. Assigning a record/SEQUENCE or
9339 // set/SET with indexed notation is not supported.
9340 return u.val_vs->is_indexed();
9341 default:
9342 FATAL_ERROR("Value::is_indexed()");
9343 break;
9344 }
9345 return false;
9346 }
9347
9348 const Identifier& Value::get_alt_name()
9349 {
9350 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_name()");
9351 return *u.choice.alt_name;
9352 }
9353
9354 Value *Value::get_alt_value()
9355 {
9356 if (valuetype != V_CHOICE) FATAL_ERROR("Value::get_alt_value()");
9357 return u.choice.alt_value;
9358 }
3abe9331 9359
9360 void Value::set_alt_name_to_lowercase()
9361 {
9362 if (valuetype != V_CHOICE) FATAL_ERROR("Value::set_alt_name_to_lowercase()");
9363 string new_name = u.choice.alt_name->get_name();
9364 if (isupper(new_name[0])) {
9365 new_name[0] = tolower(new_name[0]);
9366 if (new_name[new_name.size() - 1] == '_') {
9367 // an underscore is inserted at the end of the alternative name if it's
9368 // a basic type's name (since it would conflict with the class generated
9369 // for that type)
9370 // remove the underscore, it won't conflict with anything if its name
9371 // starts with a lowercase letter
9372 new_name.replace(new_name.size() - 1, 1, "");
9373 }
9374 delete u.choice.alt_name;
9375 u.choice.alt_name = new Identifier(Identifier::ID_NAME, new_name);
9376 }
9377 }
970ed795
EL
9378
9379 bool Value::has_oid_error()
9380 {
9381 Value *v;
9382 if (valuetype == V_REFD) v = get_value_refd_last();
9383 else v = this;
9384 switch (valuetype) {
9385 case V_OID:
9386 case V_ROID:
9387 for (size_t i = 0; i < v->u.oid_comps->size(); i++)
9388 if ((*v->u.oid_comps)[i]->has_error()) return true;
9389 return false;
9390 default:
9391 return true;
9392 }
9393 }
9394
9395 bool Value::get_oid_comps(vector<string>& comps)
9396 {
9397 bool ret_val = true;
9398 Value *v = this;
9399 switch (valuetype) {
9400 case V_REFD:
9401 v = get_value_refd_last();
9402 // no break
9403 case V_OID:
9404 case V_ROID:
9405 for (size_t i = 0; i < v->u.oid_comps->size(); i++) {
9406 (*v->u.oid_comps)[i]->get_comps(comps);
9407 if ((*v->u.oid_comps)[i]->is_variable()) {
9408 // not all components can be calculated in compile-time
9409 ret_val = false;
9410 }
9411 }
9412 break;
9413 default:
9414 FATAL_ERROR("Value::get_oid_comps()");
9415 }
9416 return ret_val;
9417 }
9418
9419 void Value::add_se_comp(NamedValue* nv) {
9420 switch (valuetype) {
9421 case V_SEQ:
9422 case V_SET:
9423 if (!u.val_nvs)
9424 u.val_nvs = new NamedValues();
9425 u.val_nvs->add_nv(nv);
9426 break;
9427 default:
9428 FATAL_ERROR("Value::add_se_comp()");
9429 }
9430 }
9431
9432 NamedValue* Value::get_se_comp_byIndex(size_t n)
9433 {
9434 switch(valuetype) {
9435 case V_SEQ:
9436 case V_SET:
9437 return u.val_nvs->get_nv_byIndex(n);
9438 default:
9439 FATAL_ERROR("Value::get_se_comp_byIndex()");
9440 return 0;
9441 } // switch
9442 }
9443
9444 Value *Value::get_comp_byIndex(size_t n)
9445 {
9446 switch (valuetype) {
9447 case V_SEQOF:
9448 case V_SETOF:
9449 case V_ARRAY:
9450 if (!is_indexed()) return u.val_vs->get_v_byIndex(n);
9451 return u.val_vs->get_iv_byIndex(n)->get_value();
9452 default:
9453 FATAL_ERROR("Value::get_comp_byIndex()");
9454 return 0;
9455 } // switch
9456 }
9457
9458 Value *Value::get_index_byIndex(size_t n)
9459 {
9460 switch (valuetype) {
9461 case V_SEQOF:
9462 case V_SETOF:
9463 case V_ARRAY:
9464 if (!is_indexed()) FATAL_ERROR("Value::get_index_byIndex()");
9465 return u.val_vs->get_iv_byIndex(n)->get_index();
9466 default:
9467 FATAL_ERROR("Value::get_index_byIndex()");
9468 return 0;
9469 } // switch
9470 }
9471
9472 bool Value::has_comp_withName(const Identifier& p_name)
9473 {
9474 switch(valuetype) {
9475 case V_SEQ:
9476 case V_SET:
9477 return u.val_nvs->has_nv_withName(p_name);
9478 case V_CHOICE:
9479 return u.choice.alt_name->get_dispname() == p_name.get_dispname();
9480 default:
9481 FATAL_ERROR("Value::get_has_comp_withName()");
9482 return false;
9483 } // switch
9484 }
9485
9486 bool Value::field_is_chosen(const Identifier& p_name)
9487 {
9488 Value *v=get_value_refd_last();
9489 if(v->valuetype!=V_CHOICE) FATAL_ERROR("Value::field_is_chosen()");
9490 return *v->u.choice.alt_name==p_name;
9491 }
9492
9493 bool Value::field_is_present(const Identifier& p_name)
9494 {
9495 Value *v=get_value_refd_last();
9496 if(!(v->valuetype==V_SEQ || v->valuetype==V_SET))
9497 FATAL_ERROR("Value::field_is_present()");
9498 return v->u.val_nvs->has_nv_withName(p_name)
9499 && v->u.val_nvs->get_nv_byName(p_name)->get_value()
9500 ->get_value_refd_last()->valuetype != V_OMIT;
9501 }
9502
9503 NamedValue* Value::get_se_comp_byName(const Identifier& p_name)
9504 {
9505 switch(valuetype) {
9506 case V_SEQ:
9507 case V_SET:
9508 return u.val_nvs->get_nv_byName(p_name);
9509 default:
9510 FATAL_ERROR("Value::get_se_comp_byName()");
9511 return 0;
9512 } // switch
9513 }
9514
9515 Value* Value::get_comp_value_byName(const Identifier& p_name)
9516 {
9517 switch(valuetype) {
9518 case V_SEQ:
9519 case V_SET:
9520 return u.val_nvs->get_nv_byName(p_name)->get_value();
9521 case V_CHOICE:
9522 if(u.choice.alt_name->get_dispname() == p_name.get_dispname())
9523 return u.choice.alt_value;
9524 else
9525 return NULL;
9526 default:
9527 FATAL_ERROR("Value::get_se_comp_byName()");
9528 return 0;
9529 } // switch
9530 }
9531
9532 void Value::chk_dupl_id()
9533 {
9534 switch(valuetype) {
9535 case V_SEQ:
9536 case V_SET:
9537 u.val_nvs->chk_dupl_id();
9538 break;
9539 default:
9540 FATAL_ERROR("Value::chk_dupl_id()");
9541 } // switch
9542 }
9543
9544 size_t Value::get_nof_ids() const
9545 {
9546 switch(valuetype) {
9547 case V_NAMEDBITS:
9548 return u.ids->size();
9549 break;
9550 default:
9551 FATAL_ERROR("Value::get_nof_ids()");
9552 return 0;
9553 } // switch
9554 }
9555
9556 Identifier* Value::get_id_byIndex(size_t p_i)
9557 {
9558 switch(valuetype) {
9559 case V_NAMEDBITS:
9560 return u.ids->get_nth_elem(p_i);
9561 break;
9562 default:
9563 FATAL_ERROR("Value::get_id_byIndex()");
9564 return 0;
9565 } // switch
9566 }
9567
9568 bool Value::has_id(const Identifier& p_id)
9569 {
9570 switch(valuetype) {
9571 case V_NAMEDBITS:
9572 return u.ids->has_key(p_id.get_name());
9573 break;
9574 default:
9575 FATAL_ERROR("Value::has_id()");
9576 return false;
9577 } // switch
9578 }
9579
9580 Reference *Value::get_reference() const
9581 {
9582 if (valuetype != V_REFD) FATAL_ERROR("Value::get_reference()");
9583 return u.ref.ref;
9584 }
9585
9586 Reference *Value::get_refered() const
9587 {
9588 if (valuetype != V_REFER) FATAL_ERROR("Value::get_referred()");
9589 return u.refered;
9590 }
9591
9592 Common::Assignment *Value::get_refd_fat() const
9593 {
9594 switch(valuetype){
9595 case V_FUNCTION:
9596 case V_ALTSTEP:
9597 case V_TESTCASE:
9598 return u.refd_fat;
9599 default:
9600 FATAL_ERROR("Value::get_refd_fat()");
9601 }
9602 }
9603
9604 Ttcn::Reference* Value::steal_ttcn_ref()
9605 {
9606 Ttcn::Reference *ret_val =
9607 dynamic_cast<Ttcn::Reference*>(steal_ttcn_ref_base());
9608 if(!ret_val) FATAL_ERROR("Value::steal_ttcn_ref()");
9609 return ret_val;
9610 }
9611
9612 Ttcn::Ref_base* Value::steal_ttcn_ref_base()
9613 {
9614 Ttcn::Ref_base *t_ref;
9615 if(valuetype==V_REFD) {
9616 t_ref=dynamic_cast<Ttcn::Ref_base*>(u.ref.ref);
9617 if(!t_ref) FATAL_ERROR("Value::steal_ttcn_ref_base()");
9618 u.ref.ref=0;
9619 }
9620 else if(valuetype==V_UNDEF_LOWERID) {
9621 t_ref=new Ttcn::Reference(u.val_id);
9622 t_ref->set_location(*this);
9623 t_ref->set_fullname(get_fullname());
9624 t_ref->set_my_scope(get_my_scope());
9625 u.val_id=0;
9626 }
9627 else {
9628 FATAL_ERROR("Value::steal_ttcn_ref_base()");
9629 t_ref = 0;
9630 }
9631 set_valuetype(V_ERROR);
9632 return t_ref;
9633 }
9634
9635 void Value::steal_invoke_data(Value*& p_v, Ttcn::ParsedActualParameters*& p_ti,
9636 Ttcn::ActualParList*& p_ap)
9637 {
9638 if(valuetype != V_INVOKE) FATAL_ERROR("Value::steal_invoke_data()");
9639 p_v = u.invoke.v;
9640 u.invoke.v = 0;
9641 p_ti = u.invoke.t_list;
9642 u.invoke.t_list = 0;
9643 p_ap = u.invoke.ap_list;
9644 u.invoke.ap_list = 0;
9645 set_valuetype(V_ERROR);
9646 }
9647
9648 Common::Assignment* Value::get_refd_assignment()
9649 {
9650 switch(valuetype) {
9651 case V_FUNCTION:
9652 case V_ALTSTEP:
9653 case V_TESTCASE:
9654 return u.refd_fat;
9655 break;
9656 default:
9657 FATAL_ERROR("Value::get_refd_assignment()");
9658 return 0;
9659 }
9660 }
9661
9662 void Value::chk()
9663 {
9664 if(checked) return;
9665 switch(valuetype) {
9666 case V_OID: {
9667 ReferenceChain refch(this, "While checking OBJECT IDENTIFIER"
9668 " components");
9669 chk_OID(refch);
9670 break; }
9671 case V_ROID: {
9672 ReferenceChain refch(this, "While checking RELATIVE-OID components");
9673 chk_ROID(refch);
9674 break; }
9675 default:
9676 break;
9677 } // switch
9678 checked=true;
9679 }
9680
9681 void Value::chk_OID(ReferenceChain& refch)
9682 {
9683 if (checked) return;
9684 if (valuetype != V_OID || u.oid_comps->size() < 1)
9685 FATAL_ERROR("Value::chk_OID()");
9686 if (!refch.add(get_fullname())) {
9687 checked = true;
9688 return;
9689 }
9690 OID_comp::oidstate_t state = OID_comp::START;
9691 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9692 refch.mark_state();
9693 (*u.oid_comps)[i]->chk_OID(refch, this, i, state);
9694 refch.prev_state();
9695 }
9696 if (state != OID_comp::LATER && state != OID_comp::ITU_REC)
9697 error("An OBJECT IDENTIFIER value must have at least "
9698 "two components"); // X.680 (07/2002) 31.10
9699 }
9700
9701 void Value::chk_ROID(ReferenceChain& refch)
9702 {
9703 if (checked) return;
9704 if (valuetype != V_ROID || u.oid_comps->size() < 1)
9705 FATAL_ERROR("Value::chk_ROID()");
9706 if (!refch.add(get_fullname())) {
9707 checked = true;
9708 return;
9709 }
9710 for (size_t i = 0; i < u.oid_comps->size(); i++) {
9711 refch.mark_state();
9712 (*u.oid_comps)[i]->chk_ROID(refch, i);
9713 refch.prev_state();
9714 }
9715 }
9716
9717 void Value::chk_recursions(ReferenceChain& refch)
9718 {
9719 if (recurs_checked) return;
9720 Value *v = get_value_refd_last();
9721 if (refch.add(v->get_fullname())) {
9722 switch (v->valuetype) {
9723 case V_CHOICE:
9724 v->u.choice.alt_value->chk_recursions(refch);
9725 break;
9726 case V_SEQOF:
9727 case V_SETOF:
9728 case V_ARRAY:
9729 if (!v->is_indexed()) {
9730 for (size_t i = 0; i < v->u.val_vs->get_nof_vs(); i++) {
9731 refch.mark_state();
9732 v->u.val_vs->get_v_byIndex(i)->chk_recursions(refch);
9733 refch.prev_state();
9734 }
9735 } else {
9736 for (size_t i = 0; i < v->u.val_vs->get_nof_ivs(); i++) {
9737 refch.mark_state();
9738 v->u.val_vs->get_iv_byIndex(i)->get_value()
9739 ->chk_recursions(refch);
9740 refch.prev_state();
9741 }
9742 }
9743 break;
9744 case V_SEQ:
9745 case V_SET:
9746 for (size_t i = 0; i < v->u.val_nvs->get_nof_nvs(); i++) {
9747 refch.mark_state();
9748 v->u.val_nvs->get_nv_byIndex(i)->get_value()->chk_recursions(refch);
9749 refch.prev_state();
9750 }
9751 break;
9752 case V_EXPR:
9753 chk_recursions_expr(refch);
9754 break;
9755 default:
9756 break;
9757 }
9758 if (v->err_descr) { // FIXME: make this work
9759 v->err_descr->chk_recursions(refch);
9760 }
9761 }
9762 recurs_checked = true;
9763 }
9764
9765 void Value::chk_recursions_expr(ReferenceChain& refch)
9766 {
9767 // first classify the unchecked ischosen() operation
9768 if (u.expr.v_optype==OPTYPE_ISCHOSEN) chk_expr_ref_ischosen();
9769 switch (u.expr.v_optype) {
9770 case OPTYPE_UNARYPLUS: // v1
9771 case OPTYPE_UNARYMINUS:
9772 case OPTYPE_NOT:
9773 case OPTYPE_NOT4B:
9774 case OPTYPE_BIT2HEX:
9775 case OPTYPE_BIT2INT:
9776 case OPTYPE_BIT2OCT:
9777 case OPTYPE_BIT2STR:
9778 case OPTYPE_CHAR2INT:
9779 case OPTYPE_CHAR2OCT:
9780 case OPTYPE_FLOAT2INT:
9781 case OPTYPE_FLOAT2STR:
9782 case OPTYPE_HEX2BIT:
9783 case OPTYPE_HEX2INT:
9784 case OPTYPE_HEX2OCT:
9785 case OPTYPE_HEX2STR:
9786 case OPTYPE_INT2CHAR:
9787 case OPTYPE_INT2FLOAT:
9788 case OPTYPE_INT2STR:
9789 case OPTYPE_INT2UNICHAR:
9790 case OPTYPE_OCT2BIT:
9791 case OPTYPE_OCT2CHAR:
9792 case OPTYPE_OCT2HEX:
9793 case OPTYPE_OCT2INT:
9794 case OPTYPE_OCT2STR:
9795 case OPTYPE_STR2BIT:
9796 case OPTYPE_STR2FLOAT:
9797 case OPTYPE_STR2HEX:
9798 case OPTYPE_STR2INT:
9799 case OPTYPE_STR2OCT:
9800 case OPTYPE_UNICHAR2INT:
9801 case OPTYPE_ENUM2INT:
9802 case OPTYPE_UNICHAR2CHAR:
9803 case OPTYPE_RNDWITHVAL:
9804 case OPTYPE_ISCHOSEN_V:
9805 case OPTYPE_GET_STRINGENCODING:
9806 case OPTYPE_REMOVE_BOM:
9807 case OPTYPE_DECODE_BASE64:
9808 refch.mark_state();
9809 u.expr.v1->chk_recursions(refch);
9810 refch.prev_state();
9811 break;
9812 case OPTYPE_ISCHOSEN_T:
9813 refch.mark_state();
9814 u.expr.t1->chk_recursions(refch);
9815 refch.prev_state();
9816 break;
efbe586d 9817 case OPTYPE_HOSTID: // [v1]
9818 if (u.expr.v1) {
9819 refch.mark_state();
9820 u.expr.v1->chk_recursions(refch);
9821 refch.prev_state();
9822 }
9823 break;
970ed795
EL
9824 case OPTYPE_ADD: // v1 v2
9825 case OPTYPE_SUBTRACT:
9826 case OPTYPE_MULTIPLY:
9827 case OPTYPE_DIVIDE:
9828 case OPTYPE_MOD:
9829 case OPTYPE_REM:
9830 case OPTYPE_CONCAT:
9831 case OPTYPE_EQ:
9832 case OPTYPE_LT:
9833 case OPTYPE_GT:
9834 case OPTYPE_NE:
9835 case OPTYPE_GE:
9836 case OPTYPE_LE:
9837 case OPTYPE_AND:
9838 case OPTYPE_OR:
9839 case OPTYPE_XOR:
9840 case OPTYPE_AND4B:
9841 case OPTYPE_OR4B:
9842 case OPTYPE_XOR4B:
9843 case OPTYPE_SHL:
9844 case OPTYPE_SHR:
9845 case OPTYPE_ROTL:
9846 case OPTYPE_ROTR:
9847 case OPTYPE_INT2BIT:
9848 case OPTYPE_INT2HEX:
9849 case OPTYPE_INT2OCT:
9850 refch.mark_state();
9851 u.expr.v1->chk_recursions(refch);
9852 refch.prev_state();
9853 refch.mark_state();
9854 u.expr.v2->chk_recursions(refch);
9855 refch.prev_state();
9856 break;
9857 case OPTYPE_UNICHAR2OCT: // v1 [v2]
9858 case OPTYPE_OCT2UNICHAR:
9859 case OPTYPE_ENCODE_BASE64:
9860 refch.mark_state();
9861 u.expr.v1->chk_recursions(refch);
9862 refch.prev_state();
9863 if (u.expr.v2) {
9864 refch.mark_state();
9865 u.expr.v2->chk_recursions(refch);
9866 refch.prev_state();
9867 }
9868 break;
9869 case OPTYPE_DECODE:
9870 chk_recursions_expr_decode(u.expr.r1, refch);
9871 chk_recursions_expr_decode(u.expr.r2, refch);
9872 break;
9873 case OPTYPE_SUBSTR:
9874 refch.mark_state();
9875 u.expr.ti1->chk_recursions(refch);
9876 refch.prev_state();
9877 refch.mark_state();
9878 u.expr.v2->chk_recursions(refch);
9879 refch.prev_state();
9880 refch.mark_state();
9881 u.expr.v3->chk_recursions(refch);
9882 refch.prev_state();
9883 break;
9884 case OPTYPE_REGEXP:
9885 refch.mark_state();
9886 u.expr.ti1->chk_recursions(refch);
9887 refch.prev_state();
9888 refch.mark_state();
9889 u.expr.t2->chk_recursions(refch);
9890 refch.prev_state();
9891 refch.mark_state();
9892 u.expr.v3->chk_recursions(refch);
9893 refch.prev_state();
9894 break;
9895 case OPTYPE_DECOMP: // v1 v2 v3
9896 refch.mark_state();
9897 u.expr.v1->chk_recursions(refch);
9898 refch.prev_state();
9899 refch.mark_state();
9900 u.expr.v2->chk_recursions(refch);
9901 refch.prev_state();
9902 refch.mark_state();
9903 u.expr.v3->chk_recursions(refch);
9904 refch.prev_state();
9905 break;
9906 case OPTYPE_REPLACE:
9907 refch.mark_state();
9908 u.expr.ti1->chk_recursions(refch);
9909 refch.prev_state();
9910 refch.mark_state();
9911 u.expr.v2->chk_recursions(refch);
9912 refch.prev_state();
9913 refch.mark_state();
9914 u.expr.v3->chk_recursions(refch);
9915 refch.prev_state();
9916 refch.mark_state();
9917 u.expr.ti4->chk_recursions(refch);
9918 refch.prev_state();
9919 break;
9920 case OPTYPE_LENGTHOF: // ti1
9921 case OPTYPE_SIZEOF: // ti1
9922 case OPTYPE_VALUEOF: // ti1
9923 case OPTYPE_ENCODE:
9924 case OPTYPE_ISPRESENT:
9925 case OPTYPE_TTCN2STRING:
9926 refch.mark_state();
9927 u.expr.ti1->chk_recursions(refch);
9928 refch.prev_state();
9929 break;
1d0599f0 9930 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
9931 refch.mark_state();
9932 u.expr.ti1->chk_recursions(refch);
9933 refch.prev_state();
9934 if (u.expr.v2){
9935 refch.mark_state();
9936 u.expr.v2->chk_recursions(refch);
9937 refch.prev_state();
9938 }
9939 break;
9940 case OPTYPE_DECVALUE_UNICHAR: // r1 r2 [v3]
9941 chk_recursions_expr_decode(u.expr.r1, refch);
9942 chk_recursions_expr_decode(u.expr.r2, refch);
9943 if (u.expr.v3){
9944 refch.mark_state();
9945 u.expr.v3->chk_recursions(refch);
9946 refch.prev_state();
9947 }
9948 break;
970ed795
EL
9949 case OPTYPE_MATCH: // v1 t2
9950 refch.mark_state();
9951 u.expr.v1->chk_recursions(refch);
9952 refch.prev_state();
9953 refch.mark_state();
9954 u.expr.t2->chk_recursions(refch);
9955 refch.prev_state();
9956 break;
9957 case OPTYPE_LOG2STR:
a50716c1 9958 case OPTYPE_ANY2UNISTR:
970ed795
EL
9959 u.expr.logargs->chk_recursions(refch);
9960 break;
9961 default:
9962 break;
9963 } // switch
9964 }
9965
9966 void Value::chk_recursions_expr_decode(Ttcn::Ref_base* ref,
9967 ReferenceChain& refch) {
9968 Error_Context cntxt(this, "In the operand of operation `%s'", get_opname());
9969 Assignment *ass = ref->get_refd_assignment();
9970 if (!ass) {
9971 set_valuetype(V_ERROR);
9972 return;
9973 }
9974 switch (ass->get_asstype()) {
9975 case Assignment::A_CONST:
9976 case Assignment::A_EXT_CONST:
9977 case Assignment::A_MODULEPAR:
9978 case Assignment::A_VAR:
9979 case Assignment::A_PAR_VAL_IN:
9980 case Assignment::A_PAR_VAL_OUT:
9981 case Assignment::A_PAR_VAL_INOUT: {
9982 Value* v = new Value(V_REFD, ref);
9983 v->set_location(*ref);
9984 v->set_my_scope(get_my_scope());
9985 v->set_fullname(get_fullname()+".<operand>");
9986 refch.mark_state();
9987 v->chk_recursions(refch);
9988 refch.prev_state();
9989 delete v;
9990 break; }
9991 case Assignment::A_MODULEPAR_TEMP:
9992 case Assignment::A_TEMPLATE:
9993 case Assignment::A_VAR_TEMPLATE:
9994 case Assignment::A_PAR_TEMPL_IN:
9995 case Assignment::A_PAR_TEMPL_OUT:
9996 case Assignment::A_PAR_TEMPL_INOUT: {
9997 Template* t = new Template(ref->clone());
9998 t->set_location(*ref);
9999 t->set_my_scope(get_my_scope());
10000 t->set_fullname(get_fullname()+".<operand>");
10001 refch.mark_state();
10002 t->chk_recursions(refch);
10003 refch.prev_state();
10004 delete t;
10005 break; }
10006 default:
10007 // remain silent, the error has been already reported
10008 set_valuetype(V_ERROR);
10009 break;
10010 } // switch
10011 }
10012
10013 bool Value::chk_expr_self_ref_templ(Ttcn::Template *t, Common::Assignment *lhs)
10014 {
10015 bool self_ref = false;
10016 switch (t->get_templatetype()) {
10017 case Ttcn::Template::SPECIFIC_VALUE: {
10018 Value *v = t->get_specific_value();
10019 self_ref |= v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
10020 ->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
10021 INCOMPLETE_NOT_ALLOWED, OMIT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT, NOT_STR_ELEM);
10022 break; }
10023 case Ttcn::Template::TEMPLATE_REFD: {
10024 Ttcn::Ref_base *refb = t->get_reference();
10025 Common::Assignment *ass = refb->get_refd_assignment();
10026 self_ref |= (ass == lhs);
10027 break; }
10028 case Ttcn::Template::ALL_FROM:
10029 case Ttcn::Template::VALUE_LIST_ALL_FROM:
10030 self_ref |= chk_expr_self_ref_templ(t->get_all_from(), lhs);
10031 break;
10032 case Ttcn::Template::TEMPLATE_LIST:
10033 case Ttcn::Template::SUPERSET_MATCH:
10034 case Ttcn::Template::SUBSET_MATCH:
10035 case Ttcn::Template::PERMUTATION_MATCH:
10036 case Ttcn::Template::COMPLEMENTED_LIST:
10037 case Ttcn::Template::VALUE_LIST: {
10038 size_t num = t->get_nof_comps();
10039 for (size_t i = 0; i < num; ++i) {
10040 self_ref |= chk_expr_self_ref_templ(t->get_temp_byIndex(i), lhs);
10041 }
10042 break; }
10043// not yet clear whether we should use this or the above for TEMPLATE_LIST
10044// case Ttcn::Template::TEMPLATE_LIST: {
10045// size_t num = t->get_nof_listitems();
10046// for (size_t i=0; i < num; ++i) {
10047// self_ref |= chk_expr_self_ref_templ(t->get_listitem_byIndex(i), lhs);
10048// }
10049// break; }
10050 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
10051 size_t nnt = t->get_nof_comps();
10052 for (size_t i=0; i < nnt; ++i) {
10053 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
10054 self_ref |= chk_expr_self_ref_templ(nt->get_template(), lhs);
10055 }
10056 break; }
10057 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
10058 size_t nnt = t->get_nof_comps();
10059 for (size_t i=0; i < nnt; ++i) {
10060 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
10061 self_ref |= chk_expr_self_ref_templ(it->get_template(), lhs);
10062 }
10063 break; }
10064 case Ttcn::Template::VALUE_RANGE: {
10065 Ttcn::ValueRange *vr = t->get_value_range();
10066 Common::Value *v = vr->get_min_v();
10067 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
10068 v = vr->get_max_v();
10069 if (v) self_ref |= chk_expr_self_ref_val(v, lhs);
10070 break; }
10071 case Ttcn::Template::CSTR_PATTERN:
10072 case Ttcn::Template::USTR_PATTERN: {
10073 Ttcn::PatternString *ps = t->get_cstr_pattern();
10074 self_ref |= ps->chk_self_ref(lhs);
10075 break; }
10076 case Ttcn::Template::BSTR_PATTERN:
10077 case Ttcn::Template::HSTR_PATTERN:
10078 case Ttcn::Template::OSTR_PATTERN: {
10079 // FIXME: cannot access u.pattern
10080 break; }
10081 case Ttcn::Template::ANY_VALUE:
10082 case Ttcn::Template::ANY_OR_OMIT:
10083 case Ttcn::Template::OMIT_VALUE:
10084 case Ttcn::Template::TEMPLATE_NOTUSED:
10085 break; // self-ref can't happen
10086 case Ttcn::Template::TEMPLATE_INVOKE:
10087 break; // assume self-ref can't happen
10088 case Ttcn::Template::TEMPLATE_ERROR:
3f84031e 10089 //FATAL_ERROR("Value::chk_expr_self_ref_templ()");
10090 break;
970ed795
EL
10091// default:
10092// FATAL_ERROR("todo ttype %d", t->get_templatetype());
10093// break; // and hope for the best
10094 }
10095 return self_ref;
10096 }
10097
10098 bool Value::chk_expr_self_ref_val(Common::Value *v, Common::Assignment *lhs)
10099 {
10100 Common::Type *gov = v->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE);
10101 namedbool is_str_elem = NOT_STR_ELEM;
10102 if (v->valuetype == V_REFD) {
10103 Reference *ref = v->get_reference();
10104 Ttcn::FieldOrArrayRefs *subrefs = ref->get_subrefs();
10105 if (subrefs && subrefs->refers_to_string_element()) {
10106 is_str_elem = IS_STR_ELEM;
10107 }
10108 }
10109 return gov->chk_this_value(v, lhs, Type::EXPECTED_DYNAMIC_VALUE,
10110 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, NO_SUB_CHK, NOT_IMPLICIT_OMIT,
10111 is_str_elem);
10112 }
10113
10114 bool Value::chk_expr_self_ref(Common::Assignment *lhs)
10115 {
10116 if (valuetype != V_EXPR) FATAL_ERROR("Value::chk_expr_self_ref");
10117 if (!lhs) FATAL_ERROR("no lhs!");
10118 bool self_ref = false;
10119 switch (u.expr.v_optype) {
10120 case OPTYPE_RND: // -
10121 case OPTYPE_TESTCASENAME: // -
10122 case OPTYPE_COMP_NULL: // - (from V_TTCN3_NULL)
10123 case OPTYPE_COMP_MTC: // -
10124 case OPTYPE_COMP_SYSTEM: // -
10125 case OPTYPE_COMP_SELF: // -
10126 case OPTYPE_COMP_RUNNING_ANY: // -
10127 case OPTYPE_COMP_RUNNING_ALL: // -
10128 case OPTYPE_COMP_ALIVE_ANY: // -
10129 case OPTYPE_COMP_ALIVE_ALL: // -
10130 case OPTYPE_TMR_RUNNING_ANY: // -
10131 case OPTYPE_GETVERDICT: // -
a38c6d4c 10132 case OPTYPE_PROF_RUNNING: // -
0a1610f4 10133 case OPTYPE_CHECKSTATE_ANY:
10134 case OPTYPE_CHECKSTATE_ALL:
970ed795
EL
10135 break; // nothing to do
10136
10137 case OPTYPE_MATCH: // v1 t2
10138 self_ref |= chk_expr_self_ref_templ(u.expr.t2->get_Template(), lhs);
10139 // no break
10140 case OPTYPE_UNARYPLUS: // v1
10141 case OPTYPE_UNARYMINUS: // v1
10142 case OPTYPE_NOT: // v1
10143 case OPTYPE_NOT4B: // v1
10144 case OPTYPE_BIT2HEX: // v1
10145 case OPTYPE_BIT2INT: // v1
10146 case OPTYPE_BIT2OCT: // v1
10147 case OPTYPE_BIT2STR: // v1
10148 case OPTYPE_CHAR2INT: // v1
10149 case OPTYPE_CHAR2OCT: // v1
10150 case OPTYPE_FLOAT2INT: // v1
10151 case OPTYPE_FLOAT2STR: // v1
10152 case OPTYPE_HEX2BIT: // v1
10153 case OPTYPE_HEX2INT: // v1
10154 case OPTYPE_HEX2OCT: // v1
10155 case OPTYPE_HEX2STR: // v1
10156 case OPTYPE_INT2CHAR: // v1
10157 case OPTYPE_INT2FLOAT: // v1
10158 case OPTYPE_INT2STR: // v1
10159 case OPTYPE_INT2UNICHAR: // v1
10160 case OPTYPE_OCT2BIT: // v1
10161 case OPTYPE_OCT2CHAR: // v1
10162 case OPTYPE_OCT2HEX: // v1
10163 case OPTYPE_OCT2INT: // v1
10164 case OPTYPE_OCT2STR: // v1
10165 case OPTYPE_STR2BIT: // v1
10166 case OPTYPE_STR2FLOAT: // v1
10167 case OPTYPE_STR2HEX: // v1
10168 case OPTYPE_STR2INT: // v1
10169 case OPTYPE_STR2OCT: // v1
10170 case OPTYPE_UNICHAR2INT: // v1
10171 case OPTYPE_UNICHAR2CHAR: // v1
10172 case OPTYPE_ENUM2INT: // v1
10173 case OPTYPE_RNDWITHVAL: // v1
10174 case OPTYPE_COMP_RUNNING: // v1
10175 case OPTYPE_COMP_ALIVE: // v1
10176 case OPTYPE_ISCHOSEN_V: // v1 i2; ignore the identifier
10177 case OPTYPE_GET_STRINGENCODING:
10178 case OPTYPE_DECODE_BASE64:
10179 case OPTYPE_REMOVE_BOM:
10180 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10181 break;
efbe586d 10182 case OPTYPE_HOSTID: // [v1]
10183 if (u.expr.v1) self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10184 break;
970ed795
EL
10185 case OPTYPE_ADD: // v1 v2
10186 case OPTYPE_SUBTRACT: // v1 v2
10187 case OPTYPE_MULTIPLY: // v1 v2
10188 case OPTYPE_DIVIDE: // v1 v2
10189 case OPTYPE_MOD: // v1 v2
10190 case OPTYPE_REM: // v1 v2
10191 case OPTYPE_CONCAT: // v1 v2
10192 case OPTYPE_EQ: // v1 v2
10193 case OPTYPE_LT: // v1 v2
10194 case OPTYPE_GT: // v1 v2
10195 case OPTYPE_NE: // v1 v2
10196 case OPTYPE_GE: // v1 v2
10197 case OPTYPE_LE: // v1 v2
10198 case OPTYPE_AND: // v1 v2
10199 case OPTYPE_OR: // v1 v2
10200 case OPTYPE_XOR: // v1 v2
10201 case OPTYPE_AND4B: // v1 v2
10202 case OPTYPE_OR4B: // v1 v2
10203 case OPTYPE_XOR4B: // v1 v2
10204 case OPTYPE_SHL: // v1 v2
10205 case OPTYPE_SHR: // v1 v2
10206 case OPTYPE_ROTL: // v1 v2
10207 case OPTYPE_ROTR: // v1 v2
10208 case OPTYPE_INT2BIT: // v1 v2
10209 case OPTYPE_INT2HEX: // v1 v2
10210 case OPTYPE_INT2OCT: // v1 v2
10211 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10212 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10213 break;
10214 case OPTYPE_UNICHAR2OCT: // v1 [v2]
10215 case OPTYPE_OCT2UNICHAR:
10216 case OPTYPE_ENCODE_BASE64:
10217 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10218 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10219 break;
10220 case OPTYPE_DECOMP: // v1 v2 v3
10221 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10222 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10223 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10224 break;
10225
10226 case OPTYPE_REPLACE: // ti1 v2 v3 ti4
10227 self_ref |= chk_expr_self_ref_templ(u.expr.ti4->get_Template(), lhs);
10228 // no break
10229 case OPTYPE_SUBSTR: // ti1 v2 v3
10230 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10231 self_ref |= chk_expr_self_ref_val (u.expr.v2, lhs);
10232 self_ref |= chk_expr_self_ref_val (u.expr.v3, lhs);
10233 break;
10234
10235 case OPTYPE_REGEXP: // ti1 t2 v3
10236 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10237 self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
10238 // no break
10239 case OPTYPE_LENGTHOF: // ti1
10240 case OPTYPE_SIZEOF: // ti1
10241 case OPTYPE_VALUEOF: // ti1
10242 case OPTYPE_ENCODE: // ti1
10243 case OPTYPE_TTCN2STRING:
10244 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10245 break;
1d0599f0 10246 case OPTYPE_ENCVALUE_UNICHAR: // ti1 [v2]
10247 self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
10248 if (u.expr.v2) self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10249 break;
10250 case OPTYPE_DECVALUE_UNICHAR: { // r1 r2 [v3]
10251 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10252 self_ref |= (ass == lhs);
10253 if (u.expr.v3) self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10254 goto label_r1;
10255 break; }
970ed795
EL
10256 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
10257 // component.create -- assume no self-ref
10258 case OPTYPE_ACTIVATE: // r1
10259 // defaultref := activate(altstep) -- assume no self-ref
10260 case OPTYPE_TMR_RUNNING: // r1
10261 // boolvar := a_timer.running -- assume no self-ref
10262 break;
10263 break;
a50716c1 10264
10265 case OPTYPE_ANY2UNISTR:
970ed795
EL
10266 case OPTYPE_LOG2STR: {// logargs
10267 for (size_t i = 0, e = u.expr.logargs->get_nof_logargs(); i < e; ++i) {
10268 const Ttcn::LogArgument *la = u.expr.logargs->get_logarg_byIndex(i);
10269 switch (la->get_type()) {
10270 case Ttcn::LogArgument::L_UNDEF:
10271 case Ttcn::LogArgument::L_ERROR:
a50716c1 10272 FATAL_ERROR("%s argument type",
10273 u.expr.v_optype == OPTYPE_ANY2UNISTR ? "any2unistr" : "log2str");
970ed795
EL
10274 break; // not reached
10275
10276 case Ttcn::LogArgument::L_MACRO:
10277 case Ttcn::LogArgument::L_STR:
10278 break; // self reference not possible
10279
10280 case Ttcn::LogArgument::L_VAL:
10281 case Ttcn::LogArgument::L_MATCH:
10282 self_ref |= chk_expr_self_ref_val(la->get_val(), lhs);
10283 break;
10284
10285 case Ttcn::LogArgument::L_REF: {
10286 Ttcn::Ref_base *ref = la->get_ref();
10287 Common::Assignment *ass = ref->get_refd_assignment();
10288 self_ref |= (ass == lhs);
10289 break; }
10290
10291 case Ttcn::LogArgument::L_TI: {
10292 Ttcn::TemplateInstance *ti = la->get_ti();
10293 Ttcn::Template *t = ti->get_Template();
10294 self_ref |= chk_expr_self_ref_templ(t, lhs);
10295 break; }
10296
10297 // no default please
10298 } // switch la->logargtype
10299 }
10300 break; }
10301
10302 case OPTYPE_DECODE: { // r1 r2
10303 Common::Assignment *ass = u.expr.r2->get_refd_assignment();
10304 self_ref |= (ass == lhs);
10305 goto label_r1; }
10306 case OPTYPE_EXECUTE: // r1 [v2]
10307 if (u.expr.v2) {
10308 self_ref |= chk_expr_self_ref_val(u.expr.v2, lhs);
10309 }
10310 label_r1:
10311 // no break
10312 case OPTYPE_UNDEF_RUNNING: // r1
10313 case OPTYPE_TMR_READ: { // r1
10314 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
10315 self_ref |= (ass == lhs);
10316 break; }
10317
10318 case OPTYPE_ISCHOSEN_T: // t1 i2
10319 case OPTYPE_ISBOUND: // ti1
10320 case OPTYPE_ISVALUE: // ti1
10321 case OPTYPE_ISPRESENT: { // ti1
10322 Ttcn::Template *t;
10323 if (u.expr.v_optype == OPTYPE_ISCHOSEN_T) t = u.expr.t1;
10324 else t = u.expr.ti1->get_Template();
10325 self_ref |= chk_expr_self_ref_templ(t, lhs);
10326 break; }
10327
10328 case OPTYPE_EXECUTE_REFD: // v1 t_list2 [v3]
10329 if (u.expr.v3) {
10330 self_ref |= chk_expr_self_ref_val(u.expr.v3, lhs);
10331 }
10332 // no break
10333 case OPTYPE_ACTIVATE_REFD: // v1 t_list2
10334 self_ref |= chk_expr_self_ref_val(u.expr.v1, lhs);
10335 // TODO t_list2
10336 break;
10337
10338 case NUMBER_OF_OPTYPES: // can never happen
10339 case OPTYPE_ISCHOSEN: // r1 i2, should have been classified as _T or _V
10340 FATAL_ERROR("Value::chk_expr_self_ref(%d)", u.expr.v_optype);
10341 break;
10342 } // switch u.expr.v_optype
10343 return self_ref;
10344 }
10345
10346
10347 string Value::create_stringRepr()
10348 {
af710487 10349 // note: cannot call is_asn1() when only parsing (scopes are not properly set)
970ed795
EL
10350 switch (valuetype) {
10351 case V_ERROR:
10352 return string("<erroneous>");
10353 case V_NULL:
10354 return string("NULL");
10355 case V_BOOL:
af710487 10356 if (!parse_only && is_asn1()) {
970ed795
EL
10357 if (u.val_bool) return string("TRUE");
10358 else return string("FALSE");
10359 }
10360 else {
10361 if (u.val_bool) return string("true");
10362 else return string("false");
10363 }
10364 case V_INT:
10365 return u.val_Int->t_str();
10366 case V_REAL:
10367 return Real2string(u.val_Real);
10368 case V_ENUM:
10369 case V_NAMEDINT:
10370 case V_UNDEF_LOWERID:
10371 return u.val_id->get_name();
10372 case V_NAMEDBITS: {
10373 string ret_val("{ ");
10374 for (size_t i = 0; i < u.ids->size(); i++) {
10375 if (i>0) ret_val += ' ';
10376 ret_val += u.ids->get_nth_elem(i)->get_dispname();
10377 }
10378 ret_val += '}';
10379 return ret_val; }
10380 case V_BSTR: {
10381 string ret_val('\'');
10382 ret_val += *u.str.val_str;
10383 ret_val += "'B";
10384 return ret_val; }
10385 case V_HSTR: {
10386 string ret_val('\'');
10387 ret_val += *u.str.val_str;
10388 ret_val += "'H";
10389 return ret_val; }
10390 case V_OSTR: {
10391 string ret_val('\'');
10392 ret_val += *u.str.val_str;
10393 ret_val += "'O";
10394 return ret_val; }
10395 case V_CSTR:
10396 case V_ISO2022STR:
10397 return u.str.val_str->get_stringRepr();
10398 case V_USTR:
10399 return u.ustr.val_ustr->get_stringRepr();
10400 case V_CHARSYMS:
10401 /** \todo stringrepr of V_CHARSYMS */
10402 return string("<sorry, string representation of charsyms "
10403 "not implemented>");
10404 case V_OID:
10405 case V_ROID: {
10406 string ret_val;
af710487 10407 if (parse_only || !is_asn1()) ret_val += "objid ";
970ed795
EL
10408 ret_val += "{ ";
10409 for (size_t i = 0; i < u.oid_comps->size(); i++) {
10410 if (i>0) ret_val += ' ';
10411 (*u.oid_comps)[i]->append_stringRepr(ret_val);
10412 }
10413 ret_val += " }";
10414 return ret_val; }
10415 case V_CHOICE:
af710487 10416 if (!parse_only && is_asn1()) {
970ed795
EL
10417 string ret_val(u.choice.alt_name->get_dispname());
10418 ret_val += " : ";
10419 ret_val += u.choice.alt_value->get_stringRepr();
10420 return ret_val;
10421 }
10422 else {
10423 string ret_val("{ ");
10424 ret_val += u.choice.alt_name->get_dispname();
10425 ret_val += " := ";
10426 ret_val += u.choice.alt_value->get_stringRepr();
10427 ret_val += " }";
10428 return ret_val;
10429 }
10430 case V_SEQOF:
10431 case V_SETOF:
10432 case V_ARRAY: {
10433 string ret_val("{ ");
10434 if (!is_indexed()) {
10435 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
10436 if (i > 0) ret_val += ", ";
10437 ret_val += u.val_vs->get_v_byIndex(i)->get_stringRepr();
10438 }
10439 } else {
10440 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
10441 if (i > 0) ret_val += ", ";
10442 ret_val += u.val_vs->get_iv_byIndex(i)->get_value()->get_stringRepr();
10443 }
10444 }
10445 ret_val += " }";
10446 return ret_val; }
10447 case V_SEQ:
10448 case V_SET: {
10449 string ret_val("{ ");
af710487 10450 bool asn1_flag = !parse_only && is_asn1();
970ed795
EL
10451 for (size_t i = 0; i < u.val_nvs->get_nof_nvs(); i++) {
10452 if (i > 0) ret_val += ", ";
10453 NamedValue *nv = u.val_nvs->get_nv_byIndex(i);
10454 ret_val += nv->get_name().get_dispname();
10455 if (asn1_flag) ret_val += ' ';
10456 else ret_val += " := ";
10457 ret_val += nv->get_value()->get_stringRepr();
10458 }
10459 ret_val += " }";
10460 return ret_val; }
10461 case V_REFD: {
10462 // do not evaluate the reference if it is not done so far
10463 // (e.g. in parse-only mode)
10464 Value *t_val = u.ref.refd_last ? u.ref.refd_last : this;
10465 if (t_val->valuetype == V_REFD) return t_val->u.ref.ref->get_dispname();
10466 else return t_val->get_stringRepr(); }
10467 case V_OMIT:
10468 return string("omit");
10469 case V_VERDICT:
10470 switch (u.verdict) {
10471 case Verdict_NONE:
10472 return string("none");
10473 case Verdict_PASS:
10474 return string("pass");
10475 case Verdict_INCONC:
10476 return string("inconc");
10477 case Verdict_FAIL:
10478 return string("fail");
10479 case Verdict_ERROR:
10480 return string("error");
10481 default:
10482 return string("<unknown verdict value>");
10483 }
10484 case V_DEFAULT_NULL:
10485 case V_FAT_NULL:
10486 return string("null");
10487 case V_EXPR:
10488 switch (u.expr.v_optype) {
10489 case OPTYPE_RND:
10490 return string("rnd()");
10491 case OPTYPE_TESTCASENAME:
10492 return string("testcasename()");
10493 case OPTYPE_UNARYPLUS:
10494 return create_stringRepr_unary("+");
10495 case OPTYPE_UNARYMINUS:
10496 return create_stringRepr_unary("-");
10497 case OPTYPE_NOT:
10498 return create_stringRepr_unary("not");
10499 case OPTYPE_NOT4B:
10500 return create_stringRepr_unary("not4b");
10501 case OPTYPE_BIT2HEX:
10502 return create_stringRepr_predef1("bit2hex");
10503 case OPTYPE_BIT2INT:
10504 return create_stringRepr_predef1("bit2int");
10505 case OPTYPE_BIT2OCT:
10506 return create_stringRepr_predef1("bit2oct");
10507 case OPTYPE_BIT2STR:
10508 return create_stringRepr_predef1("bit2str");
10509 case OPTYPE_CHAR2INT:
10510 return create_stringRepr_predef1("char2int");
10511 case OPTYPE_CHAR2OCT:
10512 return create_stringRepr_predef1("char2oct");
10513 case OPTYPE_FLOAT2INT:
10514 return create_stringRepr_predef1("float2int");
10515 case OPTYPE_FLOAT2STR:
10516 return create_stringRepr_predef1("float2str");
10517 case OPTYPE_HEX2BIT:
10518 return create_stringRepr_predef1("hex2bit");
10519 case OPTYPE_HEX2INT:
10520 return create_stringRepr_predef1("hex2int");
10521 case OPTYPE_HEX2OCT:
10522 return create_stringRepr_predef1("hex2oct");
10523 case OPTYPE_HEX2STR:
10524 return create_stringRepr_predef1("hex2str");
10525 case OPTYPE_INT2CHAR:
10526 return create_stringRepr_predef1("int2char");
10527 case OPTYPE_INT2FLOAT:
10528 return create_stringRepr_predef1("int2float");
10529 case OPTYPE_INT2STR:
10530 return create_stringRepr_predef1("int2str");
10531 case OPTYPE_INT2UNICHAR:
10532 return create_stringRepr_predef1("int2unichar");
10533 case OPTYPE_OCT2BIT:
10534 return create_stringRepr_predef1("oct2bit");
10535 case OPTYPE_OCT2CHAR:
10536 return create_stringRepr_predef1("oct2char");
10537 case OPTYPE_OCT2HEX:
10538 return create_stringRepr_predef1("oct2hex");
10539 case OPTYPE_OCT2INT:
10540 return create_stringRepr_predef1("oct2int");
10541 case OPTYPE_OCT2STR:
10542 return create_stringRepr_predef1("oct2str");
10543 case OPTYPE_GET_STRINGENCODING:
10544 return create_stringRepr_predef1("get_stringencoding");
10545 case OPTYPE_REMOVE_BOM:
10546 return create_stringRepr_predef1("remove_bom");
10547 case OPTYPE_ENCODE_BASE64: {
10548 if (u.expr.v2) return create_stringRepr_predef2("encode_base64");
10549 else return create_stringRepr_predef1("encode_base64");
10550 }
10551 case OPTYPE_DECODE_BASE64:
10552 return create_stringRepr_predef1("decode_base64");
10553 case OPTYPE_OCT2UNICHAR:{
10554 if (u.expr.v2) return create_stringRepr_predef2("oct2unichar");
10555 else return create_stringRepr_predef1("oct2unichar");
10556 }
10557 case OPTYPE_UNICHAR2OCT: {
10558 if (u.expr.v2) return create_stringRepr_predef2("unichar2oct");
10559 else return create_stringRepr_predef1("unichar2oct");
10560 }
1d0599f0 10561 case OPTYPE_ENCVALUE_UNICHAR: {
10562 if (u.expr.v2) return create_stringRepr_predef2("encvalue_unichar");
10563 else return create_stringRepr_predef1("encvalue_unichar");
10564 }
efbe586d 10565 case OPTYPE_HOSTID: {
10566 if (u.expr.v1) return create_stringRepr_predef1("hostid");
10567 else return string("hostid()");
10568 }
1d0599f0 10569 case OPTYPE_DECVALUE_UNICHAR: {
10570 if (u.expr.v3) {
10571 string ret_val("decvalue_unichar");
10572 ret_val += '(';
10573 ret_val += u.expr.v1->get_stringRepr();
10574 ret_val += ", ";
10575 ret_val += u.expr.v2->get_stringRepr();
10576 ret_val += ", ";
10577 ret_val += u.expr.v3->get_stringRepr();
10578 ret_val += ')';
10579 return ret_val;
10580 }
10581 else return create_stringRepr_predef2("decvalue_unichar");
10582 }
970ed795
EL
10583 case OPTYPE_STR2BIT:
10584 return create_stringRepr_predef1("str2bit");
10585 case OPTYPE_STR2FLOAT:
10586 return create_stringRepr_predef1("str2float");
10587 case OPTYPE_STR2HEX:
10588 return create_stringRepr_predef1("str2hex");
10589 case OPTYPE_STR2INT:
10590 return create_stringRepr_predef1("str2int");
10591 case OPTYPE_STR2OCT:
10592 return create_stringRepr_predef1("str2oct");
10593 case OPTYPE_UNICHAR2INT:
10594 return create_stringRepr_predef1("unichar2int");
10595 case OPTYPE_UNICHAR2CHAR:
10596 return create_stringRepr_predef1("unichar2char");
10597 case OPTYPE_ENUM2INT:
10598 return create_stringRepr_predef1("enum2int");
10599 case OPTYPE_ENCODE:
10600 return create_stringRepr_predef1("encvalue");
10601 case OPTYPE_DECODE:
10602 return create_stringRepr_predef2("decvalue");
10603 case OPTYPE_RNDWITHVAL:
10604 return create_stringRepr_predef1("rnd");
10605 case OPTYPE_ADD:
10606 return create_stringRepr_infix("+");
10607 case OPTYPE_SUBTRACT:
10608 return create_stringRepr_infix("-");
10609 case OPTYPE_MULTIPLY:
10610 return create_stringRepr_infix("*");
10611 case OPTYPE_DIVIDE:
10612 return create_stringRepr_infix("/");
10613 case OPTYPE_MOD:
10614 return create_stringRepr_infix("mod");
10615 case OPTYPE_REM:
10616 return create_stringRepr_infix("rem");
10617 case OPTYPE_CONCAT:
10618 return create_stringRepr_infix("&");
10619 case OPTYPE_EQ:
10620 return create_stringRepr_infix("==");
10621 case OPTYPE_LT:
10622 return create_stringRepr_infix("<");
10623 case OPTYPE_GT:
10624 return create_stringRepr_infix(">");
10625 case OPTYPE_NE:
10626 return create_stringRepr_infix("!=");
10627 case OPTYPE_GE:
10628 return create_stringRepr_infix(">=");
10629 case OPTYPE_LE:
10630 return create_stringRepr_infix("<=");
10631 case OPTYPE_AND:
10632 return create_stringRepr_infix("and");
10633 case OPTYPE_OR:
10634 return create_stringRepr_infix("or");
10635 case OPTYPE_XOR:
10636 return create_stringRepr_infix("xor");
10637 case OPTYPE_AND4B:
10638 return create_stringRepr_infix("and4b");
10639 case OPTYPE_OR4B:
10640 return create_stringRepr_infix("or4b");
10641 case OPTYPE_XOR4B:
10642 return create_stringRepr_infix("xor4b");
10643 case OPTYPE_SHL:
10644 return create_stringRepr_infix("<<");
10645 case OPTYPE_SHR:
10646 return create_stringRepr_infix(">>");
10647 case OPTYPE_ROTL:
10648 return create_stringRepr_infix("<@");
10649 case OPTYPE_ROTR:
10650 return create_stringRepr_infix("@>");
10651 case OPTYPE_INT2BIT:
10652 return create_stringRepr_predef2("int2bit");
10653 case OPTYPE_INT2HEX:
10654 return create_stringRepr_predef2("int2hex");
10655 case OPTYPE_INT2OCT:
10656 return create_stringRepr_predef2("int2oct");
10657 case OPTYPE_SUBSTR: {
10658 string ret_val("substr(");
10659 u.expr.ti1->append_stringRepr(ret_val);
10660 ret_val += ", ";
10661 ret_val += u.expr.v2->get_stringRepr();
10662 ret_val += ", ";
10663 ret_val += u.expr.v3->get_stringRepr();
10664 ret_val += ')';
10665 return ret_val;
10666 }
10667 case OPTYPE_REGEXP: {
10668 string ret_val("regexp(");
10669 u.expr.ti1->append_stringRepr(ret_val);
10670 ret_val += ", ";
10671 u.expr.t2->append_stringRepr(ret_val);
10672 ret_val += ", ";
10673 ret_val += u.expr.v3->get_stringRepr();
10674 ret_val += ')';
10675 return ret_val;
10676 }
10677 case OPTYPE_DECOMP: {
10678 string ret_val("decomp(");
10679 ret_val += u.expr.v1->get_stringRepr();
10680 ret_val += ", ";
10681 ret_val += u.expr.v2->get_stringRepr();
10682 ret_val += ", ";
10683 ret_val += u.expr.v3->get_stringRepr();
10684 ret_val += ')';
10685 return ret_val;
10686 }
10687 case OPTYPE_REPLACE: {
10688 string ret_val("replace(");
10689 u.expr.ti1->append_stringRepr(ret_val);
10690 ret_val += ", ";
10691 ret_val += u.expr.v2->get_stringRepr();
10692 ret_val += ", ";
10693 ret_val += u.expr.v3->get_stringRepr();
10694 ret_val += ", ";
10695 u.expr.ti4->append_stringRepr(ret_val);
10696 ret_val += ')';
10697 return ret_val;
10698 }
10699 case OPTYPE_ISPRESENT: {
10700 string ret_val("ispresent(");
10701 u.expr.ti1->append_stringRepr(ret_val);
10702 ret_val += ')';
10703 return ret_val; }
10704 case OPTYPE_ISCHOSEN: {
10705 string ret_val("ischosen(");
10706 ret_val += u.expr.r1->get_dispname();
10707 ret_val += '.';
10708 ret_val += u.expr.i2->get_dispname();
10709 ret_val += ')';
10710 return ret_val; }
10711 case OPTYPE_ISCHOSEN_V: {
10712 string ret_val("ischosen(");
10713 ret_val += u.expr.v1->get_stringRepr();
10714 ret_val += '.';
10715 ret_val += u.expr.i2->get_dispname();
10716 ret_val += ')';
10717 return ret_val; }
10718 case OPTYPE_ISCHOSEN_T: {
10719 string ret_val("ischosen(");
10720 ret_val += u.expr.t1->get_stringRepr();
10721 ret_val += '.';
10722 ret_val += u.expr.i2->get_dispname();
10723 ret_val += ')';
10724 return ret_val; }
10725 case OPTYPE_LENGTHOF: {
10726 string ret_val("lengthof(");
10727 u.expr.ti1->append_stringRepr(ret_val);
10728 ret_val += ')';
10729 return ret_val; }
10730 case OPTYPE_SIZEOF: {
10731 string ret_val("sizeof(");
10732 u.expr.ti1->append_stringRepr(ret_val);
10733 ret_val += ')';
10734 return ret_val; }
10735 case OPTYPE_ISVALUE: {
10736 string ret_val("isvalue(");
10737 u.expr.ti1->append_stringRepr(ret_val);
10738 ret_val += ')';
10739 return ret_val; }
10740 case OPTYPE_VALUEOF: {
10741 string ret_val("valueof(");
10742 u.expr.ti1->append_stringRepr(ret_val);
10743 ret_val += ')';
10744 return ret_val; }
10745 case OPTYPE_LOG2STR:
10746 return string("log2str(...)");
a50716c1 10747 case OPTYPE_ANY2UNISTR:
10748 return string("any2unistr(...)");
970ed795
EL
10749 case OPTYPE_MATCH: {
10750 string ret_val("match(");
10751 ret_val += u.expr.v1->get_stringRepr();
10752 ret_val += ", ";
10753 u.expr.t2->append_stringRepr(ret_val);
10754 ret_val += ')';
10755 return ret_val; }
10756 case OPTYPE_TTCN2STRING: {
10757 string ret_val("ttcn2string(");
10758 u.expr.ti1->append_stringRepr(ret_val);
10759 ret_val += ')';
10760 return ret_val;
10761 }
10762 case OPTYPE_UNDEF_RUNNING:
10763 return u.expr.r1->get_dispname() + ".running";
10764 case OPTYPE_COMP_NULL:
10765 return string("null");
10766 case OPTYPE_COMP_MTC:
10767 return string("mtc");
10768 case OPTYPE_COMP_SYSTEM:
10769 return string("system");
10770 case OPTYPE_COMP_SELF:
10771 return string("self");
10772 case OPTYPE_COMP_CREATE: {
10773 string ret_val(u.expr.r1->get_dispname());
10774 ret_val += ".create";
10775 if (u.expr.v2 || u.expr.v3) {
10776 ret_val += '(';
10777 if (u.expr.v2) ret_val += u.expr.v2->get_stringRepr();
10778 else ret_val += '-';
10779 if (u.expr.v3) {
10780 ret_val += ", ";
10781 ret_val += u.expr.v3->get_stringRepr();
10782 }
10783 ret_val += ')';
10784 }
10785 if (u.expr.b4) ret_val += " alive";
10786 return ret_val; }
10787 case OPTYPE_COMP_RUNNING:
10788 return u.expr.v1->get_stringRepr() + ".running";
10789 case OPTYPE_COMP_RUNNING_ANY:
10790 return string("any component.running");
10791 case OPTYPE_COMP_RUNNING_ALL:
10792 return string("all component.running");
10793 case OPTYPE_COMP_ALIVE:
10794 return u.expr.v1->get_stringRepr() + ".alive";
10795 case OPTYPE_COMP_ALIVE_ANY:
10796 return string("any component.alive");
10797 case OPTYPE_COMP_ALIVE_ALL:
10798 return string("all component.alive");
10799 case OPTYPE_TMR_READ:
10800 return u.expr.r1->get_dispname() + ".read";
10801 case OPTYPE_TMR_RUNNING:
10802 return u.expr.r1->get_dispname() + ".running";
10803 case OPTYPE_TMR_RUNNING_ANY:
10804 return string("any timer.running");
0a1610f4 10805 case OPTYPE_CHECKSTATE_ANY:
10806 case OPTYPE_CHECKSTATE_ALL: {
10807 string ret_val("");
10808 if (u.expr.r1) {
04077e43 10809 ret_val += u.expr.r1->get_dispname();
0a1610f4 10810 } else {
10811 if (u.expr.v_optype == OPTYPE_CHECKSTATE_ANY) {
10812 ret_val += "any port";
10813 } else if (u.expr.v_optype == OPTYPE_CHECKSTATE_ALL) {
10814 ret_val += "all port";
10815 }
10816 }
10817 ret_val += "checkstate(";
10818 ret_val += u.expr.v2->get_stringRepr();
10819 ret_val += ")";
10820 return ret_val; }
970ed795
EL
10821 case OPTYPE_GETVERDICT:
10822 return string("getverdict");
10823 case OPTYPE_ACTIVATE: {
10824 string ret_val("activate(");
10825 ret_val += u.expr.r1->get_dispname();
10826 ret_val += ')';
10827 return ret_val; }
10828 case OPTYPE_ACTIVATE_REFD: {
10829 string ret_val("activate(derefer(");
10830 ret_val += u.expr.v1->get_stringRepr();
10831 ret_val += ")(";
10832 if (u.expr.state == EXPR_CHECKED) {
10833 if (u.expr.ap_list2) {
10834 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10835 for (size_t i = 0; i < nof_pars; i++) {
10836 if (i > 0) ret_val += ", ";
10837 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10838 }
10839 }
10840 } else {
10841 if (u.expr.t_list2) {
10842 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10843 for (size_t i = 0; i < nof_pars; i++) {
10844 if (i > 0) ret_val += ", ";
10845 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10846 }
10847 }
10848 }
10849 ret_val += "))";
10850 return ret_val; }
10851 case OPTYPE_EXECUTE: {
10852 string ret_val("execute(");
10853 ret_val += u.expr.r1->get_dispname();
10854 if (u.expr.v2) {
10855 ret_val += ", ";
10856 ret_val += u.expr.v2->get_stringRepr();
10857 }
10858 ret_val += ')';
10859 return ret_val; }
10860 case OPTYPE_EXECUTE_REFD: {
10861 string ret_val("execute(derefers(");
10862 ret_val += u.expr.v1->get_stringRepr();
10863 ret_val += ")(";
10864 if (u.expr.state == EXPR_CHECKED) {
10865 if (u.expr.ap_list2) {
10866 size_t nof_pars = u.expr.ap_list2->get_nof_pars();
10867 for (size_t i = 0; i < nof_pars; i++) {
10868 if (i > 0) ret_val += ", ";
10869 u.expr.ap_list2->get_par(i)->append_stringRepr(ret_val);
10870 }
10871 }
10872 } else {
10873 if (u.expr.t_list2) {
10874 size_t nof_pars = u.expr.t_list2->get_nof_tis();
10875 for (size_t i = 0; i < nof_pars; i++) {
10876 if (i > 0) ret_val += ", ";
10877 u.expr.t_list2->get_ti_byIndex(i)->append_stringRepr(ret_val);
10878 }
10879 }
10880 }
10881 ret_val += ')';
10882 if(u.expr.v3) {
10883 ret_val += ", ";
10884 ret_val += u.expr.v3->get_stringRepr();
10885 }
10886 ret_val += ')';
10887 return ret_val; }
a38c6d4c 10888 case OPTYPE_PROF_RUNNING:
10889 return string("@profiler.running");
970ed795
EL
10890 default:
10891 return string("<unsupported optype>");
10892 } // switch u.expr.v_optype
10893 case V_MACRO:
10894 switch (u.macro) {
10895 case MACRO_MODULEID:
10896 return string("%moduleId");
10897 case MACRO_FILENAME:
10898 return string("%fileName");
10899 case MACRO_BFILENAME:
10900 return string("__BFILE__");
10901 case MACRO_FILEPATH:
10902 return string("__FILE__");
10903 case MACRO_LINENUMBER:
10904 return string("%lineNumber");
10905 case MACRO_LINENUMBER_C:
10906 return string("__LINE__");
10907 case MACRO_DEFINITIONID:
10908 return string("%definitionId");
10909 case MACRO_SCOPE:
10910 return string("__SCOPE__");
10911 case MACRO_TESTCASEID:
10912 return string("%testcaseId");
10913 default:
10914 return string("<unknown macro>");
10915 } // switch u.macro
10916 case V_NOTUSED:
10917 return string('-');
10918 case V_FUNCTION:
10919 case V_ALTSTEP:
10920 case V_TESTCASE: {
10921 string ret_val("refers(");
10922 ret_val += u.refd_fat->get_assname();
10923 ret_val += ')';
10924 return ret_val; }
10925 case V_INVOKE: {
10926 string ret_val;
10927 ret_val += u.invoke.v->get_stringRepr();
10928 ret_val += ".apply(";
10929 if (u.invoke.ap_list) {
10930 size_t nof_pars = u.invoke.ap_list->get_nof_pars();
10931 for (size_t i = 0; i < nof_pars; i++) {
10932 if (i > 0) ret_val += ", ";
10933 u.invoke.ap_list->get_par(i)->append_stringRepr(ret_val);
10934 }
10935 } else if (u.invoke.t_list) {
10936 size_t nof_pars = u.invoke.t_list->get_nof_tis();
10937 for (size_t i = 0; i < nof_pars; i++) {
10938 if (i > 0) ret_val += ", ";
10939 u.invoke.t_list->get_ti_byIndex(i)->append_stringRepr(ret_val);
10940 }
10941 }
10942 ret_val += ')';
10943 return ret_val; }
10944 case V_REFER: {
10945 string ret_val("refers(");
10946 ret_val += u.refered->get_dispname();
10947 ret_val += ')';
10948 return ret_val; }
10949 default:
10950 return string("<unsupported valuetype>");
10951 } // switch valuetype
10952 }
10953
10954 string Value::create_stringRepr_unary(const char *operator_str)
10955 {
10956 string ret_val(operator_str);
10957 ret_val += '(';
10958 ret_val += u.expr.v1->get_stringRepr();
10959 ret_val += ')';
10960 return ret_val;
10961 }
10962
10963 string Value::create_stringRepr_infix(const char *operator_str)
10964 {
10965 string ret_val('(');
10966 ret_val += u.expr.v1->get_stringRepr();
10967 ret_val += ' ';
10968 ret_val += operator_str;
10969 ret_val += ' ';
10970 ret_val += u.expr.v2->get_stringRepr();
10971 ret_val += ')';
10972 return ret_val;
10973 }
10974
10975 string Value::create_stringRepr_predef1(const char *function_name)
10976 {
10977 string ret_val(function_name);
10978 ret_val += '(';
1d0599f0 10979 if (u.expr.v_optype == OPTYPE_ENCODE || u.expr.v_optype == OPTYPE_ENCVALUE_UNICHAR) { // ti1, not v1
970ed795
EL
10980 ret_val += u.expr.ti1->get_specific_value()->get_stringRepr();
10981 }
10982 else ret_val += u.expr.v1->get_stringRepr();
10983 ret_val += ')';
10984 return ret_val;
10985 }
10986
10987 string Value::create_stringRepr_predef2(const char *function_name)
10988 {
10989 string ret_val(function_name);
10990 ret_val += '(';
10991 ret_val += u.expr.v1->get_stringRepr();
10992 ret_val += ", ";
10993 ret_val += u.expr.v2->get_stringRepr();
10994 ret_val += ')';
10995 return ret_val;
10996 }
10997
10998 bool Value::operator==(Value& val)
10999 {
11000 Value *left = get_value_refd_last();
11001 Type *left_governor = left->get_my_governor();
11002 if (left_governor) left_governor = left_governor->get_type_refd_last();
11003 Value *right = val.get_value_refd_last();
11004 Type *right_governor = right->get_my_governor();
11005 if (right_governor) right_governor = right_governor->get_type_refd_last();
11006 if (left_governor && right_governor
11007 && !left_governor->is_compatible(right_governor, NULL)
11008 && !right_governor->is_compatible(left_governor, NULL))
11009 FATAL_ERROR("Value::operator==");
11010
11011 // Not-A-Value is not equal to anything (NaN analogy:)
11012 if ( (left->valuetype==V_ERROR) || (right->valuetype==V_ERROR) )
11013 return false;
11014
11015 switch (left->valuetype) {
11016 case V_NULL:
11017 case V_OMIT:
11018 case V_DEFAULT_NULL:
11019 case V_FAT_NULL:
11020 case V_NOTUSED:
11021 return left->valuetype == right->valuetype;
11022 case V_BOOL:
11023 return right->valuetype == V_BOOL &&
11024 left->get_val_bool() == right->get_val_bool();
11025 case V_INT:
11026 return right->valuetype == V_INT && *left->get_val_Int()
11027 == *right->get_val_Int();
11028 case V_REAL:
11029 return right->valuetype == V_REAL &&
11030 left->get_val_Real() == right->get_val_Real();
11031 case V_CSTR:
11032 switch (right->valuetype) {
11033 case V_CSTR:
11034 return left->get_val_str() == right->get_val_str();
11035 case V_USTR:
11036 return right->get_val_ustr() == left->get_val_str();
11037 case V_ISO2022STR:
11038 return right->get_val_iso2022str() == left->get_val_str();
11039 default:
11040 return false;
11041 }
11042 case V_BSTR:
11043 case V_HSTR:
11044 case V_OSTR:
11045 return left->valuetype == right->valuetype &&
11046 left->get_val_str() == right->get_val_str();
11047 case V_USTR:
11048 switch (right->valuetype) {
11049 case V_CSTR:
11050 return left->get_val_ustr() == right->get_val_str();
11051 case V_USTR:
11052 return left->get_val_ustr() == right->get_val_ustr();
11053 case V_ISO2022STR:
11054 return left->get_val_ustr() == right->get_val_iso2022str();
11055 default:
11056 return false;
11057 }
11058 case V_ISO2022STR:
11059 switch (right->valuetype) {
11060 case V_CSTR:
11061 return left->get_val_iso2022str() == right->get_val_str();
11062 case V_USTR:
11063 // The appropriate operator==() is missing. The operands are swapped,
11064 // but it shouldn't be a problem.
11065 return right->get_val_ustr() == left->get_val_iso2022str();
11066 case V_ISO2022STR:
11067 return left->get_val_iso2022str() == right->get_val_iso2022str();
11068 default:
11069 return false;
11070 }
11071 case V_ENUM:
11072 return right->valuetype == V_ENUM &&
11073 left->get_val_id()->get_name() == right->get_val_id()->get_name();
11074 case V_OID:
11075 case V_ROID:
11076 if (right->valuetype == V_OID || right->valuetype == V_ROID) {
11077 vector<string> act, other;
11078 get_oid_comps(act);
11079 val.get_oid_comps(other);
11080 size_t act_size = act.size(), other_size = other.size();
11081 bool ret_val;
11082 if (act_size == other_size) {
11083 ret_val = true;
11084 for (size_t i = 0; i < act_size; i++)
11085 if (*act[i] != *other[i]) {
11086 ret_val = false;
11087 break;
11088 }
11089 } else ret_val = false;
11090 for (size_t i = 0; i < act_size; i++) delete act[i];
11091 act.clear();
11092 for (size_t i = 0; i < other_size; i++) delete other[i];
11093 other.clear();
11094 return ret_val;
11095 } else return false;
11096 case V_CHOICE:
11097 return right->valuetype == V_CHOICE &&
11098 left->get_alt_name().get_name() == right->get_alt_name().get_name() &&
11099 *(left->get_alt_value()) == *(right->get_alt_value());
11100 case V_SEQ:
11101 case V_SET: {
11102 if (!left_governor) FATAL_ERROR("Value::operator==");
11103 if (left->valuetype != right->valuetype) return false;
11104 size_t nof_comps = left_governor->get_nof_comps();
11105 for (size_t i = 0; i < nof_comps; i++) {
11106 Value *lval = NULL, *rval = NULL;
11107 CompField* cfl = left_governor->get_comp_byIndex(i);
11108 const Identifier& field_name = cfl->get_name();
11109 if (left->has_comp_withName(field_name)) {
11110 lval = left->get_comp_value_byName(field_name);
11111 if (right->has_comp_withName(field_name)) {
11112 rval = right->get_comp_value_byName(field_name);
11113 if ((lval->valuetype == V_OMIT && rval->valuetype != V_OMIT)
11114 || (rval->valuetype == V_OMIT && lval->valuetype!=V_OMIT))
11115 return false;
11116 else if (!(*lval == *rval))
11117 return false;
11118 } else {
11119 if (cfl->has_default()) {
11120 if (!(*lval == *cfl->get_defval()))
11121 return false;
11122 } else {
11123 if (lval->valuetype != V_OMIT)
11124 return false;
11125 }
11126 }
11127 } else {
11128 if(right->has_comp_withName(field_name)) {
11129 rval = right->get_comp_value_byName(field_name);
11130 if(cfl->has_default()) {
11131 if(rval->valuetype==V_OMIT) return false;
11132 else {
11133 lval = cfl->get_defval();
11134 if (!(*lval==*rval)) return false;
11135 }
11136 }
11137 }
11138 }
11139 }
11140 return true; }
11141 case V_SEQOF:
11142 case V_ARRAY: {
11143 if (left->valuetype != right->valuetype) return false;
11144 size_t ncomps = get_nof_comps();
11145 if (ncomps != right->get_nof_comps()) return false;
11146
11147 if (left->is_indexed() && right->is_indexed()) { //both of them are indexed
11148 bool found = false;
11149 map<IndexedValue*, void> uncovered;
11150 for (size_t i = 0; i < left->get_nof_comps(); ++i)
11151 uncovered.add(left->u.val_vs->get_iv_byIndex(i),0);
11152
11153 for (size_t i = 0; i < right->get_nof_comps(); ++i) {
11154 found = false;
11155 for (size_t j = 0; j < uncovered.size(); ++j) {
11156 if (*(uncovered.get_nth_key(j)->get_value()) ==
11157 *(right->get_comp_byIndex(i)) &&
11158 *(uncovered.get_nth_key(j)->get_index()) ==
11159 *(right->get_index_byIndex(i))) {
11160 found = true;
11161 uncovered.erase(uncovered.get_nth_key(j));
11162 break;
11163 }
11164 }
11165 if (!found) break;
11166 }
11167 uncovered.clear();
11168 return found;
11169 } else if (left->is_indexed() || right->is_indexed()) {
11170 Value* indexed_one = 0;
11171 Value* not_indexed_one = 0;
11172
11173 if(left->is_indexed()) { // left is indexed, right is not
11174 indexed_one = left;
11175 not_indexed_one = right;
11176 } else { // right indexed, left is not
11177 indexed_one = right;
11178 not_indexed_one = left;
11179 }
11180
11181 for(size_t i = 0; i < ncomps; ++i) {
11182 Value* ind = indexed_one->get_index_byIndex(i)->get_value_refd_last();
11183 if(!(ind->valuetype == V_INT &&
11184 *(not_indexed_one->get_comp_byIndex(ind->u.val_Int->get_val())) ==
11185 *(indexed_one->get_comp_byIndex(i))))
11186 { return false; }
11187 }
11188 return true;
11189 } else { // none of them is indexed
11190 for (size_t i = 0; i < ncomps; i++) {
11191 if (!(*(left->get_comp_byIndex(i)) == *(right->get_comp_byIndex(i))))
11192 return false;
11193 }
11194 return true;
11195 }
11196 }
11197 case V_SETOF: {
11198 if (right->valuetype != V_SETOF) return false;
11199 size_t ncomps = get_nof_comps();
11200 if (ncomps != right->get_nof_comps()) return false;
11201 if (ncomps == 0) return true;
11202 map<size_t, void> uncovered;
11203 for (size_t i = 0; i < ncomps; i++) uncovered.add(i, 0);
11204 for (size_t i = 0; i < ncomps; i++) {
11205 Value *left_item = left->get_comp_byIndex(i);
11206 bool pair_found = false;
11207 for (size_t j = 0; j < ncomps - i; j++) {
11208 size_t right_index = uncovered.get_nth_key(j);
11209 if (*left_item == *right->get_comp_byIndex(right_index)) {
11210 uncovered.erase(right_index);
11211 pair_found = true;
11212 break;
11213 }
11214 }
11215 if (!pair_found) {
11216 uncovered.clear();
11217 return false;
11218 }
11219 }
11220 return true; }
11221 case V_VERDICT:
11222 return right->valuetype == V_VERDICT &&
11223 left->get_val_verdict() == right->get_val_verdict();
11224 case V_FUNCTION:
11225 case V_ALTSTEP:
11226 case V_TESTCASE:
11227 return left->valuetype == right->valuetype &&
11228 left->get_refd_assignment() == right->get_refd_assignment();
11229 default:
11230 FATAL_ERROR("Value::operator==");
11231 }
11232 return true;
11233 }
11234
11235 bool Value::operator<(Value& val)
11236 {
11237 Value *left = get_value_refd_last();
11238 Type *left_governor = left->get_my_governor();
11239 if(left_governor) left_governor=left_governor->get_type_refd_last();
11240 Value *right = val.get_value_refd_last();
11241 Type *right_governor = right->get_my_governor();
11242 if(right_governor) right_governor=right_governor->get_type_refd_last();
11243 if (left->get_valuetype() != right->get_valuetype())
11244 FATAL_ERROR("Value::operator<");
11245 switch(valuetype){
11246 case V_INT:
11247 return *left->get_val_Int() < *right->get_val_Int();
11248 case V_REAL:
11249 return (left->get_val_Real() < right->get_val_Real());
11250 case V_ENUM:
11251 if(!left_governor || !right_governor)
11252 FATAL_ERROR("Value::operator<");
11253 if(left_governor!=right_governor)
11254 FATAL_ERROR("Value::operator<");
11255 return (left_governor->get_enum_val_byId(*left->get_val_id()) <
11256 right_governor->get_enum_val_byId(*right->get_val_id()));
11257 default:
11258 FATAL_ERROR("Value::operator<");
11259 }
11260 return true;
11261 }
11262
11263 bool Value::is_string_type(Type::expected_value_t exp_val)
11264 {
11265 switch (get_expr_returntype(exp_val)) {
11266 case Type::T_CSTR:
11267 case Type::T_USTR:
11268 case Type::T_BSTR:
11269 case Type::T_HSTR:
11270 case Type::T_OSTR:
11271 return true;
11272 default:
11273 return false;
11274 }
11275 }
11276
11277 void Value::generate_code_expr(expression_struct *expr)
11278 {
11279 if (has_single_expr()) {
11280 expr->expr = mputstr(expr->expr, get_single_expr().c_str());
11281 } else {
11282 switch (valuetype) {
11283 case V_EXPR:
11284 generate_code_expr_expr(expr);
11285 break;
11286 case V_CHOICE:
11287 case V_SEQOF:
11288 case V_SETOF:
11289 case V_ARRAY:
11290 case V_SEQ:
11291 case V_SET: {
11292 const string& tmp_id = get_temporary_id();
11293 const char *tmp_id_str = tmp_id.c_str();
11294 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
11295 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str);
11296 set_genname_recursive(tmp_id);
11297 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11298 expr->expr = mputstr(expr->expr, tmp_id_str);
11299 break; }
11300 case V_INT: {
11301 const string& tmp_id = get_temporary_id();
11302 const char *tmp_id_str = tmp_id.c_str();
11303 expr->preamble = mputprintf(expr->preamble, "INTEGER %s;\n",
11304 tmp_id_str);
11305 set_genname_recursive(tmp_id);
11306 expr->preamble = generate_code_init(expr->preamble, tmp_id_str);
11307 expr->expr = mputstr(expr->expr, tmp_id_str);
11308 break; }
11309 case V_REFD: {
11310 if (!get_needs_conversion()) {
11311 u.ref.ref->generate_code_const_ref(expr);
11312 } else {
11313 Type *my_gov = get_expr_governor_last();
11314 Type *refd_gov = u.ref.ref->get_refd_assignment()->get_Type()
11315 ->get_field_type(u.ref.ref->get_subrefs(),
11316 Type::EXPECTED_DYNAMIC_VALUE)->get_type_refd_last();
11317 // Make sure that nothing goes wrong.
11318 if (!my_gov || !refd_gov || my_gov == refd_gov)
11319 FATAL_ERROR("Value::generate_code_expr()");
11320 expression_struct expr_tmp;
11321 Code::init_expr(&expr_tmp);
11322 const string& tmp_id1 = get_temporary_id();
11323 const char *tmp_id_str1 = tmp_id1.c_str();
11324 const string& tmp_id2 = get_temporary_id();
11325 const char *tmp_id_str2 = tmp_id2.c_str();
11326 expr->preamble = mputprintf(expr->preamble,
11327 "%s %s;\n", refd_gov->get_genname_value(my_scope).c_str(),
11328 tmp_id_str1);
11329 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
11330 u.ref.ref->generate_code_const_ref(&expr_tmp);
11331 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
11332 expr->preamble = mputprintf(expr->preamble,
11333 "%s %s;\n"
11334 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
11335 "and `%s' are not compatible at run-time\");\n",
11336 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
11337 TypeConv::get_conv_func(refd_gov, my_gov, get_my_scope()
11338 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1, my_gov
11339 ->get_typename().c_str(), refd_gov->get_typename().c_str());
11340 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
11341 }
11342 break; }
11343 case V_INVOKE:
11344 generate_code_expr_invoke(expr);
11345 break;
11346 default:
11347 FATAL_ERROR("Value::generate_code_expr(%d)", valuetype);
11348 }
11349 }
11350 }
11351
11352 void Value::generate_code_expr_mandatory(expression_struct *expr)
11353 {
11354 generate_code_expr(expr);
11355 if (valuetype == V_REFD && get_value_refd_last()->valuetype == V_REFD)
11356 generate_code_expr_optional_field_ref(expr, u.ref.ref);
11357 }
11358
11359 bool Value::can_use_increment(Reference *ref) const
11360 {
11361 if (valuetype != V_EXPR) {
11362 return false;
11363 }
11364 switch (u.expr.v_optype) {
11365 case OPTYPE_ADD:
11366 case OPTYPE_SUBTRACT:
11367 break;
11368 default:
11369 return false;
11370 }
11371 bool v1_one = u.expr.v1->get_valuetype() == V_INT && *u.expr.v1->get_val_Int() == 1;
11372 bool v2_one = u.expr.v2->get_valuetype() == V_INT && *u.expr.v2->get_val_Int() == 1;
11373 if ((v1_one && u.expr.v2->get_valuetype() == V_REFD &&
11374 u.expr.v2->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id()) ||
11375 (v2_one && u.expr.v1->get_valuetype() == V_REFD &&
11376 u.expr.v1->get_reference()->get_refd_assignment()->get_id() == ref->get_refd_assignment()->get_id())) {
11377 return true;
11378 }
11379 return false;
11380 }
11381
11382 char *Value::generate_code_init(char *str, const char *name)
11383 {
11384 if (get_code_generated()) return str;
11385 if (err_descr) {
11386 str = err_descr->generate_code_init_str(str, string(name) + "_err_descr");
11387 }
11388 switch (valuetype) {
11389 case V_NULL:
11390 case V_BOOL:
11391 case V_REAL:
11392 case V_ENUM:
11393 case V_BSTR:
11394 case V_HSTR:
11395 case V_OSTR:
11396 case V_CSTR:
11397 case V_USTR:
11398 case V_ISO2022STR:
11399 case V_OID:
11400 case V_ROID:
11401 case V_VERDICT:
11402 case V_DEFAULT_NULL:
11403 case V_FAT_NULL:
11404 case V_FUNCTION:
11405 case V_ALTSTEP:
11406 case V_TESTCASE:
11407 // These values have a single string equivalent.
11408 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11409 break;
11410 case V_INT:
11411 if (u.val_Int->is_native_fit())
11412 str = mputprintf(str, "%s = %s;\n", name, get_single_expr().c_str());
11413 else
11414 // It's always an INTEGER.
11415 str = mputprintf(str, "{ INTEGER INTEGER_tmp(%s);\n%s = INTEGER_tmp; "
11416 "}\n", get_single_expr().c_str(), name);
11417 break;
11418 case V_EXPR:
11419 case V_INVOKE: {
11420 expression_struct expr;
11421 Code::init_expr(&expr);
11422 expr.expr = mputprintf(expr.expr, "%s = ", name);
11423 generate_code_expr(&expr);
11424 str = Code::merge_free_expr(str, &expr);
11425 break; }
11426 case V_CHOICE:
11427 str = generate_code_init_choice(str, name);
11428 break;
11429 case V_SEQOF:
11430 case V_SETOF:
11431 if (!is_indexed()) str = generate_code_init_seof(str, name);
11432 else str = generate_code_init_indexed(str, name);
11433 break;
11434 case V_ARRAY:
11435 if (!is_indexed()) str = generate_code_init_array(str, name);
11436 else str = generate_code_init_indexed(str, name);
11437 break;
11438 case V_SEQ:
11439 case V_SET:
11440 str = generate_code_init_se(str, name);
11441 break;
11442 case V_REFD:
11443 str = generate_code_init_refd(str, name);
11444 break;
11445 case V_MACRO:
11446 switch (u.macro) {
11447 case MACRO_TESTCASEID:
11448 str = mputprintf(str, "%s = TTCN_Runtime::get_testcase_id_macro();\n", name);
11449 break;
11450 default:
11451 // all others must already be evaluated away
11452 FATAL_ERROR("Value::generate_code_init()");
11453 }
11454 break;
feade998 11455 case V_NOTUSED:
11456 // unbound value, don't generate anything
11457 break;
970ed795
EL
11458 default:
11459 FATAL_ERROR("Value::generate_code_init()");
11460 }
11461 if (err_descr) {
11462 str = mputprintf(str, "%s.set_err_descr(&%s_err_descr);\n", name, name);
11463 }
11464 set_code_generated();
11465 return str;
11466 }
11467
2861f5cd 11468 char *Value::rearrange_init_code(char *str, Common::Module* usage_mod)
970ed795
EL
11469 {
11470 switch (valuetype) {
11471 case V_REFD: {
11472 Ttcn::ActualParList *parlist = u.ref.ref->get_parlist();
11473 if (parlist) {
2861f5cd 11474 str = parlist->rearrange_init_code(str, usage_mod);
970ed795
EL
11475 }
11476 break; }
11477 case V_INVOKE: {
2861f5cd
BB
11478 str = u.invoke.v->rearrange_init_code(str, usage_mod);
11479 str = u.invoke.ap_list->rearrange_init_code(str, usage_mod);
970ed795
EL
11480 break; }
11481 case V_EXPR:
11482 switch (u.expr.v_optype) {
11483 case OPTYPE_UNARYPLUS:
11484 case OPTYPE_UNARYMINUS:
11485 case OPTYPE_NOT:
11486 case OPTYPE_NOT4B:
11487 case OPTYPE_BIT2HEX:
11488 case OPTYPE_BIT2INT:
11489 case OPTYPE_BIT2OCT:
11490 case OPTYPE_BIT2STR:
11491 case OPTYPE_CHAR2INT:
11492 case OPTYPE_CHAR2OCT:
11493 case OPTYPE_FLOAT2INT:
11494 case OPTYPE_FLOAT2STR:
11495 case OPTYPE_HEX2BIT:
11496 case OPTYPE_HEX2INT:
11497 case OPTYPE_HEX2OCT:
11498 case OPTYPE_HEX2STR:
11499 case OPTYPE_INT2CHAR:
11500 case OPTYPE_INT2FLOAT:
11501 case OPTYPE_INT2STR:
11502 case OPTYPE_INT2UNICHAR:
11503 case OPTYPE_OCT2BIT:
11504 case OPTYPE_OCT2CHAR:
11505 case OPTYPE_OCT2HEX:
11506 case OPTYPE_OCT2INT:
11507 case OPTYPE_OCT2STR:
11508 case OPTYPE_STR2BIT:
11509 case OPTYPE_STR2FLOAT:
11510 case OPTYPE_STR2HEX:
11511 case OPTYPE_STR2INT:
11512 case OPTYPE_STR2OCT:
11513 case OPTYPE_UNICHAR2INT:
11514 case OPTYPE_UNICHAR2CHAR:
11515 case OPTYPE_ENUM2INT:
11516 case OPTYPE_ISCHOSEN_V:
11517 case OPTYPE_GET_STRINGENCODING:
11518 case OPTYPE_REMOVE_BOM:
11519 case OPTYPE_DECODE_BASE64:
2861f5cd 11520 str = u.expr.v1->rearrange_init_code(str, usage_mod);
970ed795
EL
11521 break;
11522 case OPTYPE_DECODE: {
11523 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11524 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
2861f5cd 11525 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
970ed795
EL
11526
11527 parlist = u.expr.r2->get_parlist();
11528 ass = u.expr.r2->get_refd_assignment();
2861f5cd 11529 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
970ed795 11530 break; }
efbe586d 11531 case OPTYPE_HOSTID:
11532 if (u.expr.v1) str = u.expr.v1->rearrange_init_code(str, usage_mod);
11533 break;
970ed795
EL
11534 case OPTYPE_ADD:
11535 case OPTYPE_SUBTRACT:
11536 case OPTYPE_MULTIPLY:
11537 case OPTYPE_DIVIDE:
11538 case OPTYPE_MOD:
11539 case OPTYPE_REM:
11540 case OPTYPE_CONCAT:
11541 case OPTYPE_EQ:
11542 case OPTYPE_LT:
11543 case OPTYPE_GT:
11544 case OPTYPE_NE:
11545 case OPTYPE_GE:
11546 case OPTYPE_LE:
11547 case OPTYPE_AND:
11548 case OPTYPE_OR:
11549 case OPTYPE_XOR:
11550 case OPTYPE_AND4B:
11551 case OPTYPE_OR4B:
11552 case OPTYPE_XOR4B:
11553 case OPTYPE_SHL:
11554 case OPTYPE_SHR:
11555 case OPTYPE_ROTL:
11556 case OPTYPE_ROTR:
11557 case OPTYPE_INT2BIT:
11558 case OPTYPE_INT2HEX:
11559 case OPTYPE_INT2OCT:
11560 //case OPTYPE_DECODE:
2861f5cd
BB
11561 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11562 str = u.expr.v2->rearrange_init_code(str, usage_mod);
970ed795
EL
11563 break;
11564 case OPTYPE_UNICHAR2OCT: // v1 [v2]
11565 case OPTYPE_OCT2UNICHAR:
11566 case OPTYPE_ENCODE_BASE64:
2861f5cd
BB
11567 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11568 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
970ed795
EL
11569 break;
11570 case OPTYPE_SUBSTR:
2861f5cd
BB
11571 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11572 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11573 str = u.expr.v3->rearrange_init_code(str, usage_mod);
970ed795
EL
11574 break;
11575 case OPTYPE_REGEXP:
2861f5cd
BB
11576 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11577 str = u.expr.t2->rearrange_init_code(str, usage_mod);
11578 str = u.expr.v3->rearrange_init_code(str, usage_mod);
970ed795
EL
11579 break;
11580 case OPTYPE_DECOMP:
2861f5cd
BB
11581 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11582 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11583 str = u.expr.v3->rearrange_init_code(str, usage_mod);
970ed795
EL
11584 break;
11585 case OPTYPE_REPLACE:
2861f5cd
BB
11586 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11587 str = u.expr.v2->rearrange_init_code(str, usage_mod);
11588 str = u.expr.v3->rearrange_init_code(str, usage_mod);
11589 str = u.expr.ti4->rearrange_init_code(str, usage_mod);
970ed795
EL
11590 break;
11591 case OPTYPE_LENGTHOF:
11592 case OPTYPE_SIZEOF:
11593 case OPTYPE_VALUEOF:
11594 case OPTYPE_ENCODE:
11595 case OPTYPE_ISPRESENT:
11596 case OPTYPE_TTCN2STRING:
2861f5cd 11597 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
970ed795 11598 break;
1d0599f0 11599 case OPTYPE_ENCVALUE_UNICHAR:
11600 str = u.expr.ti1->rearrange_init_code(str, usage_mod);
11601 if (u.expr.v2) str = u.expr.v2->rearrange_init_code(str, usage_mod);
11602 break;
11603 case OPTYPE_DECVALUE_UNICHAR: {
11604 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
11605 Common::Assignment *ass = u.expr.r1->get_refd_assignment();
11606 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11607
11608 parlist = u.expr.r2->get_parlist();
11609 ass = u.expr.r2->get_refd_assignment();
11610 if (parlist) str = parlist->rearrange_init_code(str, usage_mod);
11611 if (u.expr.v3) str = u.expr.v3->rearrange_init_code(str, usage_mod);
11612 break; }
970ed795 11613 case OPTYPE_ISCHOSEN_T:
2861f5cd 11614 str = u.expr.t1->rearrange_init_code(str, usage_mod);
970ed795
EL
11615 break;
11616 case OPTYPE_MATCH:
2861f5cd
BB
11617 str = u.expr.v1->rearrange_init_code(str, usage_mod);
11618 str = u.expr.t2->rearrange_init_code(str, usage_mod);
970ed795
EL
11619 break;
11620 default:
11621 // other kinds of expressions cannot appear within templates
11622 break;
11623 }
11624 break;
11625 default:
11626 break;
11627 }
11628 return str;
11629 }
11630
11631 char* Value::generate_code_tmp(char *str, const char *prefix,
11632 size_t& blockcount)
11633 {
11634 char *s2 = memptystr();
11635 char *s1 = generate_code_tmp(NULL, s2);
11636 if (s2[0]) {
11637 if (blockcount == 0) {
11638 str = mputstr(str, "{\n");
11639 blockcount++;
11640 }
11641 str = mputstr(str, s2);
11642 }
11643 Free(s2);
11644 str=mputstr(str, prefix);
11645 str=mputstr(str, s1);
11646 Free(s1);
11647 return str;
11648 }
11649
11650 char *Value::generate_code_tmp(char *str, char*& init)
11651 {
11652 expression_struct expr;
11653 Code::init_expr(&expr);
11654 generate_code_expr_mandatory(&expr);
11655 if (expr.preamble || expr.postamble) {
11656 if (valuetype == V_EXPR &&
11657 (u.expr.v_optype == OPTYPE_AND || u.expr.v_optype == OPTYPE_OR)) {
11658 // a temporary variable is already introduced
11659 if (expr.preamble) init = mputstr(init, expr.preamble);
11660 if (expr.postamble) init = mputstr(init, expr.postamble);
11661 str = mputstr(str, expr.expr);
11662 } else {
11663 const string& tmp_id = get_temporary_id();
11664 const char *tmp_id_str = tmp_id.c_str();
11665 init = mputprintf(init, "%s %s;\n"
11666 "{\n",
11667 my_governor->get_type_refd_last()->get_typetype() == Type::T_BOOL ?
11668 "boolean" : my_governor->get_genname_value(my_scope).c_str(),
11669 tmp_id_str);
11670 if (expr.preamble) init = mputstr(init, expr.preamble);
11671 init = mputprintf(init, "%s = %s;\n", tmp_id_str, expr.expr);
11672 if (expr.postamble) init = mputstr(init, expr.postamble);
11673 init = mputstr(init, "}\n");
11674 str = mputstr(str, tmp_id_str);
11675 }
11676 } else str = mputstr(str, expr.expr);
11677 Code::free_expr(&expr);
11678 return str;
11679 }
11680
11681 void Value::generate_code_log(expression_struct *expr)
11682 {
11683 if (explicit_cast_needed()) {
11684 char *expr_backup = expr->expr;
11685 expr->expr = NULL;
11686 generate_code_expr(expr);
11687 const string& tmp_id = get_temporary_id();
11688 const char *tmp_id_str = tmp_id.c_str();
11689 // We have to create a temporary object, because the parser of GCC
11690 // earlier than 3.4.x (e.g. 3.0.4) in some cases cannot recognize the
11691 // constructor call that is, this does not work: type(...).log(); but
11692 // this works: type tmp(...); tmp.log();.
11693 expr->preamble = mputprintf(expr->preamble, "%s %s(%s);\n",
11694 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str,
11695 expr->expr);
11696 Free(expr->expr);
11697 expr->expr = mputstr(expr_backup, tmp_id_str);
11698 } else {
11699 generate_code_expr(expr);
11700 }
11701 expr->expr = mputstr(expr->expr, ".log()");
11702 }
11703
11704 void Value::generate_code_log_match(expression_struct *expr)
11705 {
11706 if (valuetype != V_EXPR || u.expr.v_optype != OPTYPE_MATCH)
11707 FATAL_ERROR("Value::generate_code_log_match()");
11708 // Maybe, it's a more general problem, but for complete GCC 3.0.4
11709 // compliance the whole code-generation should be checked. Standalone
11710 // constructs like: "A(a[0].f());" should be avoided. The current
11711 // solution for HK38721 uses an additional assignment to overcome the
11712 // issue. The generated code will be slower, but it's needed for old GCC
11713 // versions in specific circumstances.
11714 if (u.expr.t2->needs_temp_ref()) {
11715 char *expr_backup = expr->expr;
11716 expr->expr = NULL;
11717 u.expr.t2->generate_code(expr);
11718 const string& tmp_id = get_temporary_id();
11719 const char *tmp_id_str = tmp_id.c_str();
11720 expr->preamble = mputprintf(expr->preamble,
11721 "%s %s = %s;\n", u.expr.t2->get_expr_governor(Type::EXPECTED_TEMPLATE)
11722 ->get_genname_template(my_scope).c_str(), tmp_id_str, expr->expr);
11723 Free(expr->expr);
11724 expr->expr = mputstr(expr_backup, tmp_id_str);
11725 } else {
11726 // Workaround for "A(NS::B).a(C);" like constructs for GCC 3.0.4. For
11727 // some reason "(A(NS::B)).a(C);" compiles fine.
11728 expr->expr = mputc(expr->expr, '(');
11729 u.expr.t2->generate_code(expr);
11730 expr->expr = mputc(expr->expr, ')');
11731 }
11732 expr->expr = mputstr(expr->expr, ".log_match(");
11733 u.expr.v1->generate_code_expr(expr);
3abe9331 11734 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
970ed795
EL
11735 }
11736
11737 void Value::generate_code_expr_expr(expression_struct *expr)
11738 {
11739 switch (u.expr.v_optype) {
11740 case OPTYPE_RND:
11741 generate_code_expr_rnd(expr, 0);
11742 break;
11743 case OPTYPE_UNARYPLUS:
11744 // same as without the '+' operator
11745 u.expr.v1->generate_code_expr(expr);
11746 break;
11747 case OPTYPE_UNARYMINUS:
11748 generate_code_expr_unary(expr, "-", u.expr.v1);
11749 break;
11750 case OPTYPE_NOT:
11751 generate_code_expr_unary(expr, "!", u.expr.v1);
11752 break;
11753 case OPTYPE_NOT4B:
11754 generate_code_expr_unary(expr, "~", u.expr.v1);
11755 break;
11756 case OPTYPE_BIT2HEX:
11757 generate_code_expr_predef1(expr, "bit2hex", u.expr.v1);
11758 break;
11759 case OPTYPE_BIT2INT:
11760 generate_code_expr_predef1(expr, "bit2int", u.expr.v1);
11761 break;
11762 case OPTYPE_BIT2OCT:
11763 generate_code_expr_predef1(expr, "bit2oct", u.expr.v1);
11764 break;
11765 case OPTYPE_BIT2STR:
11766 generate_code_expr_predef1(expr, "bit2str", u.expr.v1);
11767 break;
11768 case OPTYPE_CHAR2INT:
11769 generate_code_expr_predef1(expr, "char2int", u.expr.v1);
11770 break;
11771 case OPTYPE_CHAR2OCT:
11772 generate_code_expr_predef1(expr, "char2oct", u.expr.v1);
11773 break;
11774 case OPTYPE_FLOAT2INT:
11775 generate_code_expr_predef1(expr, "float2int", u.expr.v1);
11776 break;
11777 case OPTYPE_FLOAT2STR:
11778 generate_code_expr_predef1(expr, "float2str", u.expr.v1);
11779 break;
11780 case OPTYPE_HEX2BIT:
11781 generate_code_expr_predef1(expr, "hex2bit", u.expr.v1);
11782 break;
11783 case OPTYPE_HEX2INT:
11784 generate_code_expr_predef1(expr, "hex2int", u.expr.v1);
11785 break;
11786 case OPTYPE_HEX2OCT:
11787 generate_code_expr_predef1(expr, "hex2oct", u.expr.v1);
11788 break;
11789 case OPTYPE_HEX2STR:
11790 generate_code_expr_predef1(expr, "hex2str", u.expr.v1);
11791 break;
11792 case OPTYPE_INT2CHAR:
11793 generate_code_expr_predef1(expr, "int2char", u.expr.v1);
11794 break;
11795 case OPTYPE_INT2FLOAT:
11796 generate_code_expr_predef1(expr, "int2float", u.expr.v1);
11797 break;
11798 case OPTYPE_INT2STR:
11799 generate_code_expr_predef1(expr, "int2str", u.expr.v1);
11800 break;
11801 case OPTYPE_INT2UNICHAR:
11802 generate_code_expr_predef1(expr, "int2unichar", u.expr.v1);
11803 break;
11804 case OPTYPE_OCT2BIT:
11805 generate_code_expr_predef1(expr, "oct2bit", u.expr.v1);
11806 break;
11807 case OPTYPE_OCT2CHAR:
11808 generate_code_expr_predef1(expr, "oct2char", u.expr.v1);
11809 break;
11810 case OPTYPE_GET_STRINGENCODING:
11811 generate_code_expr_predef1(expr, "get_stringencoding", u.expr.v1);
11812 break;
11813 case OPTYPE_REMOVE_BOM:
11814 generate_code_expr_predef1(expr, "remove_bom", u.expr.v1);
11815 break;
11816 case OPTYPE_ENCODE_BASE64:
11817 if (u.expr.v2)
11818 generate_code_expr_predef2(expr, "encode_base64", u.expr.v1, u.expr.v2);
11819 else
11820 generate_code_expr_predef1(expr, "encode_base64", u.expr.v1);
11821 break;
11822 case OPTYPE_DECODE_BASE64:
11823 generate_code_expr_predef1(expr, "decode_base64", u.expr.v1);
11824 break;
11825 case OPTYPE_OCT2UNICHAR:
11826 if (u.expr.v2)
11827 generate_code_expr_predef2(expr, "oct2unichar", u.expr.v1, u.expr.v2);
11828 else
11829 generate_code_expr_predef1(expr, "oct2unichar", u.expr.v1);
11830 break;
11831 case OPTYPE_UNICHAR2OCT:
11832 if (u.expr.v2)
11833 generate_code_expr_predef2(expr, "unichar2oct", u.expr.v1, u.expr.v2);
11834 else
11835 generate_code_expr_predef1(expr, "unichar2oct", u.expr.v1);
11836 break;
1d0599f0 11837 case OPTYPE_ENCVALUE_UNICHAR:
11838 generate_code_expr_encvalue_unichar(expr);
11839 break;
11840 case OPTYPE_DECVALUE_UNICHAR:
11841 generate_code_expr_decvalue_unichar(expr);
11842 break;
efbe586d 11843 case OPTYPE_HOSTID:
11844 generate_code_expr_hostid(expr);
11845 break;
970ed795
EL
11846 case OPTYPE_OCT2HEX:
11847 generate_code_expr_predef1(expr, "oct2hex", u.expr.v1);
11848 break;
11849 case OPTYPE_OCT2INT:
11850 generate_code_expr_predef1(expr, "oct2int", u.expr.v1);
11851 break;
11852 case OPTYPE_OCT2STR:
11853 generate_code_expr_predef1(expr, "oct2str", u.expr.v1);
11854 break;
11855 case OPTYPE_STR2BIT:
11856 generate_code_expr_predef1(expr, "str2bit", u.expr.v1);
11857 break;
11858 case OPTYPE_STR2FLOAT:
11859 generate_code_expr_predef1(expr, "str2float", u.expr.v1);
11860 break;
11861 case OPTYPE_STR2HEX:
11862 generate_code_expr_predef1(expr, "str2hex", u.expr.v1);
11863 break;
11864 case OPTYPE_STR2INT:
11865 generate_code_expr_predef1(expr, "str2int", u.expr.v1);
11866 break;
11867 case OPTYPE_STR2OCT:
11868 generate_code_expr_predef1(expr, "str2oct", u.expr.v1);
11869 break;
11870 case OPTYPE_UNICHAR2INT:
11871 generate_code_expr_predef1(expr, "unichar2int", u.expr.v1);
11872 break;
11873 case OPTYPE_UNICHAR2CHAR:
11874 generate_code_expr_predef1(expr, "unichar2char", u.expr.v1);
11875 break;
11876 case OPTYPE_ENUM2INT: {
11877 Type* enum_type = u.expr.v1->get_expr_governor_last();
11878 if (!enum_type) FATAL_ERROR("Value::generate_code_expr_expr(): enum2int");
11879 expr->expr = mputprintf(expr->expr, "%s::enum2int(",
11880 enum_type->get_genname_value(my_scope).c_str());
11881 u.expr.v1->generate_code_expr_mandatory(expr);
11882 expr->expr = mputc(expr->expr, ')');
11883 break;}
11884 case OPTYPE_ENCODE:
11885 generate_code_expr_encode(expr);
11886 break;
11887 case OPTYPE_DECODE:
11888 generate_code_expr_decode(expr);
11889 break;
11890 case OPTYPE_RNDWITHVAL:
11891 generate_code_expr_rnd(expr, u.expr.v1);
11892 break;
11893 case OPTYPE_ADD:
11894 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11895 break;
11896 case OPTYPE_SUBTRACT:
11897 generate_code_expr_infix(expr, "-", u.expr.v1, u.expr.v2, false);
11898 break;
11899 case OPTYPE_MULTIPLY:
11900 generate_code_expr_infix(expr, "*", u.expr.v1, u.expr.v2, false);
11901 break;
11902 case OPTYPE_DIVIDE:
11903 generate_code_expr_infix(expr, "/", u.expr.v1, u.expr.v2, false);
11904 break;
11905 case OPTYPE_MOD:
11906 generate_code_expr_predef2(expr, "mod", u.expr.v1, u.expr.v2);
11907 break;
11908 case OPTYPE_REM:
11909 generate_code_expr_predef2(expr, "rem", u.expr.v1, u.expr.v2);
11910 break;
11911 case OPTYPE_CONCAT:
11912 generate_code_expr_infix(expr, "+", u.expr.v1, u.expr.v2, false);
11913 break;
11914 case OPTYPE_EQ:
11915 generate_code_expr_infix(expr, "==", u.expr.v1, u.expr.v2, true);
11916 break;
11917 case OPTYPE_LT:
11918 generate_code_expr_infix(expr, "<", u.expr.v1, u.expr.v2, false);
11919 break;
11920 case OPTYPE_GT:
11921 generate_code_expr_infix(expr, ">", u.expr.v1, u.expr.v2, false);
11922 break;
11923 case OPTYPE_NE:
11924 generate_code_expr_infix(expr, "!=", u.expr.v1, u.expr.v2, true);
11925 break;
11926 case OPTYPE_GE:
11927 generate_code_expr_infix(expr, ">=", u.expr.v1, u.expr.v2, false);
11928 break;
11929 case OPTYPE_LE:
11930 generate_code_expr_infix(expr, "<=", u.expr.v1, u.expr.v2, false);
11931 break;
11932 case OPTYPE_AND:
11933 case OPTYPE_OR:
11934 generate_code_expr_and_or(expr);
11935 break;
11936 case OPTYPE_XOR:
11937 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11938 break;
11939 case OPTYPE_AND4B:
11940 generate_code_expr_infix(expr, "&", u.expr.v1, u.expr.v2, false);
11941 break;
11942 case OPTYPE_OR4B:
11943 generate_code_expr_infix(expr, "|", u.expr.v1, u.expr.v2, false);
11944 break;
11945 case OPTYPE_XOR4B:
11946 generate_code_expr_infix(expr, "^", u.expr.v1, u.expr.v2, false);
11947 break;
11948 case OPTYPE_SHL:
11949 generate_code_expr_infix(expr, "<<", u.expr.v1, u.expr.v2, false);
11950 break;
11951 case OPTYPE_SHR:
11952 generate_code_expr_infix(expr, ">>", u.expr.v1, u.expr.v2, false);
11953 break;
11954 case OPTYPE_ROTL:
11955 generate_code_expr_infix(expr, "<<=", u.expr.v1, u.expr.v2, false);
11956 break;
11957 case OPTYPE_ROTR:
11958 generate_code_expr_infix(expr, ">>=", u.expr.v1, u.expr.v2, false);
11959 break;
11960 case OPTYPE_INT2BIT:
11961 generate_code_expr_predef2(expr, "int2bit", u.expr.v1, u.expr.v2);
11962 break;
11963 case OPTYPE_INT2HEX:
11964 generate_code_expr_predef2(expr, "int2hex", u.expr.v1, u.expr.v2);
11965 break;
11966 case OPTYPE_INT2OCT:
11967 generate_code_expr_predef2(expr, "int2oct", u.expr.v1, u.expr.v2);
11968 break;
11969 case OPTYPE_SUBSTR:
11970 if (!get_needs_conversion()) generate_code_expr_substr(expr);
11971 else generate_code_expr_substr_replace_compat(expr);
11972 break;
11973 case OPTYPE_REGEXP:
11974 generate_code_expr_regexp(expr);
11975 break;
11976 case OPTYPE_DECOMP:
11977 generate_code_expr_predef3(expr, "decomp", u.expr.v1, u.expr.v2, u.expr.v3);
11978 break;
11979 case OPTYPE_REPLACE:
11980 if (!get_needs_conversion()) generate_code_expr_replace(expr);
11981 else generate_code_expr_substr_replace_compat(expr);
11982 break;
11983 case OPTYPE_ISCHOSEN: // r1 i2
11984 FATAL_ERROR("Value::generate_code_expr_expr()");
11985 break;
11986 case OPTYPE_ISCHOSEN_V: // v1 i2
11987 u.expr.v1->generate_code_expr_mandatory(expr);
11988 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11989 u.expr.v1->get_my_governor()->get_genname_value(my_scope).c_str(),
11990 u.expr.i2->get_name().c_str());
11991 break;
11992 case OPTYPE_ISCHOSEN_T: // t1 i2
11993 u.expr.t1->generate_code_expr(expr);
11994 expr->expr = mputprintf(expr->expr, ".ischosen(%s::ALT_%s)",
11995 u.expr.t1->get_my_governor()->get_genname_value(my_scope).c_str(),
11996 u.expr.i2->get_name().c_str());
11997 break;
11998 case OPTYPE_ISPRESENT:
11999 case OPTYPE_ISBOUND: {
12000 Template::templatetype_t temp = u.expr.ti1->get_Template()
12001 ->get_templatetype();
12002 if (temp == Template::SPECIFIC_VALUE) {
12003 Value* specific_value = u.expr.ti1->get_Template()
12004 ->get_specific_value();
12005 if (specific_value->get_valuetype() == Value::V_REFD) {
12006 Ttcn::Reference* reference =
12007 dynamic_cast<Ttcn::Reference*>(specific_value->get_reference());
12008 if (reference) {
12009 reference->generate_code_ispresentbound(expr, false,
12010 u.expr.v_optype==OPTYPE_ISBOUND);
12011 break;
12012 }
12013 }
12014 } else if (temp == Template::TEMPLATE_REFD){
12015 Ttcn::Reference* reference =
12016 dynamic_cast<Ttcn::Reference*>(u.expr.ti1->get_Template()
12017 ->get_reference());
12018 if (reference) {
12019 reference->generate_code_ispresentbound(expr, true,
12020 u.expr.v_optype==OPTYPE_ISBOUND);
12021 break;
12022 }
12023 }
12024 }
12025 // no break
12026 case OPTYPE_LENGTHOF: // ti1
12027 // fall through, separated later
12028 case OPTYPE_SIZEOF: // ti1
12029 // fall through, separated later
12030 case OPTYPE_ISVALUE: { // ti1
12031 if (u.expr.ti1->is_only_specific_value()) {
12032 Value *t_val=u.expr.ti1->get_Template()->get_specific_value();
12033 bool cast_needed = t_val->explicit_cast_needed(
12034 u.expr.v_optype != OPTYPE_LENGTHOF);
12035 if(cast_needed) {
12036 // the ambiguous C++ expression is converted to the value class
12037 expr->expr = mputprintf(expr->expr, "%s(",
12038 t_val->get_my_governor()->get_genname_value(my_scope).c_str());
12039 }
12040
12041 if (u.expr.v_optype != OPTYPE_LENGTHOF
12042 && u.expr.v_optype != OPTYPE_SIZEOF) {
12043 t_val->generate_code_expr(expr);
12044 } else {
12045 t_val->generate_code_expr_mandatory(expr);
12046 }
12047
12048 if(cast_needed) expr->expr=mputc(expr->expr, ')');
12049 }
12050 else u.expr.ti1->generate_code(expr);
12051
12052 switch (u.expr.v_optype) {
12053 case OPTYPE_ISBOUND:
12054 expr->expr=mputstr(expr->expr, ".is_bound()");
12055 break;
12056 case OPTYPE_ISPRESENT:
feade998 12057 expr->expr=mputprintf(expr->expr, ".is_present()");
970ed795
EL
12058 break;
12059 case OPTYPE_SIZEOF:
12060 expr->expr=mputstr(expr->expr, ".size_of()");
12061 break;
12062 case OPTYPE_LENGTHOF:
12063 expr->expr=mputstr(expr->expr, ".lengthof()");
12064 break;
12065 case OPTYPE_ISVALUE:
12066 expr->expr=mputstr(expr->expr, ".is_value()");
12067 break;
12068 default:
12069 FATAL_ERROR("Value::generate_code_expr_expr()");
12070 }
12071 break; }
12072 case OPTYPE_VALUEOF: // ti1
12073 u.expr.ti1->generate_code(expr);
12074 expr->expr = mputstr(expr->expr, ".valueof()");
12075 break;
12076 case OPTYPE_MATCH: // v1 t2
12077 u.expr.t2->generate_code(expr);
12078 expr->expr = mputstr(expr->expr, ".match(");
12079 u.expr.v1->generate_code_expr(expr);
3abe9331 12080 expr->expr = mputprintf(expr->expr, "%s)", omit_in_value_list ? ", TRUE" : "");
970ed795
EL
12081 break;
12082 case OPTYPE_UNDEF_RUNNING:
12083 // it is resolved during semantic check
12084 FATAL_ERROR("Value::generate_code_expr_expr(): undef running");
12085 break;
12086 case OPTYPE_COMP_NULL: // -
12087 expr->expr=mputstr(expr->expr, "NULL_COMPREF");
12088 break;
12089 case OPTYPE_COMP_MTC: // -
12090 expr->expr=mputstr(expr->expr, "MTC_COMPREF");
12091 break;
12092 case OPTYPE_COMP_SYSTEM: // -
12093 expr->expr=mputstr(expr->expr, "SYSTEM_COMPREF");
12094 break;
12095 case OPTYPE_COMP_SELF: // -
12096 expr->expr=mputstr(expr->expr, "self");
12097 break;
12098 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
12099 generate_code_expr_create(expr, u.expr.r1, u.expr.v2, u.expr.v3,
12100 u.expr.b4);
12101 break;
12102 case OPTYPE_COMP_RUNNING: // v1
12103 u.expr.v1->generate_code_expr(expr);
12104 if(u.expr.v1->get_valuetype() == V_REFD)
12105 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
12106 expr->expr = mputstr(expr->expr, ".running()");
12107 break;
12108 case OPTYPE_COMP_RUNNING_ANY: // -
12109 expr->expr=mputstr(expr->expr,
12110 "TTCN_Runtime::component_running(ANY_COMPREF)");
12111 break;
12112 case OPTYPE_COMP_RUNNING_ALL: // -
12113 expr->expr=mputstr(expr->expr,
12114 "TTCN_Runtime::component_running(ALL_COMPREF)");
12115 break;
12116 case OPTYPE_COMP_ALIVE: // v1
12117 u.expr.v1->generate_code_expr(expr);
12118 if(u.expr.v1->get_valuetype() == V_REFD)
12119 generate_code_expr_optional_field_ref(expr, u.expr.v1->get_reference());
12120 expr->expr = mputstr(expr->expr, ".alive()");
12121 break;
12122 case OPTYPE_COMP_ALIVE_ANY: // -
12123 expr->expr = mputstr(expr->expr,
12124 "TTCN_Runtime::component_alive(ANY_COMPREF)");
12125 break;
12126 case OPTYPE_COMP_ALIVE_ALL: // -
12127 expr->expr = mputstr(expr->expr,
12128 "TTCN_Runtime::component_alive(ALL_COMPREF)");
12129 break;
12130 case OPTYPE_TMR_READ: // r1
12131 u.expr.r1->generate_code(expr);
12132 expr->expr = mputstr(expr->expr, ".read()");
12133 break;
12134 case OPTYPE_TMR_RUNNING: // r1
12135 u.expr.r1->generate_code(expr);
12136 expr->expr = mputstr(expr->expr, ".running()");
12137 break;
12138 case OPTYPE_TMR_RUNNING_ANY: // -
12139 expr->expr=mputstr(expr->expr, "TIMER::any_running()");
12140 break;
12141 case OPTYPE_GETVERDICT: // -
12142 expr->expr=mputstr(expr->expr, "TTCN_Runtime::getverdict()");
12143 break;
12144 case OPTYPE_TESTCASENAME: // -
12145 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_testcasename()");
12146 break;
12147 case OPTYPE_ACTIVATE: // r1
12148 generate_code_expr_activate(expr);
12149 break;
0a1610f4 12150 case OPTYPE_CHECKSTATE_ANY: // [r1] v2
12151 case OPTYPE_CHECKSTATE_ALL:
12152 generate_code_expr_checkstate(expr);
12153 break;
970ed795
EL
12154 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
12155 generate_code_expr_activate_refd(expr);
12156 break;
12157 case OPTYPE_EXECUTE: // r1 [v2]
12158 generate_code_expr_execute(expr);
12159 break;
12160 case OPTYPE_EXECUTE_REFD: //v1 ap_list2 [v3]
12161 generate_code_expr_execute_refd(expr);
12162 break;
12163 case OPTYPE_LOG2STR:
a50716c1 12164 case OPTYPE_ANY2UNISTR:
970ed795
EL
12165 u.expr.logargs->generate_code_expr(expr);
12166 break;
12167 case OPTYPE_TTCN2STRING: {
12168 Type* param_governor = u.expr.ti1->get_Template()->get_template_refd_last()->get_my_governor();
12169 if (param_governor==NULL) FATAL_ERROR("Value::generate_code_expr_expr()");
12170 param_governor = param_governor->get_type_refd_last();
12171 expr->expr = mputstr(expr->expr, "ttcn_to_string(");
12172 if (!u.expr.ti1->get_DerivedRef() && !u.expr.ti1->get_Type() &&
12173 u.expr.ti1->get_Template()->is_Value()) {
12174 Value* v = u.expr.ti1->get_Template()->get_Value();
12175 delete u.expr.ti1;
12176 u.expr.ti1 = NULL;
12177 bool cast_needed = v->explicit_cast_needed();
12178 if (cast_needed) {
12179 expr->expr = mputprintf(expr->expr, "%s(", param_governor->get_genname_value(my_scope).c_str());
12180 }
12181 v->generate_code_expr(expr);
12182 if (cast_needed) {
12183 expr->expr = mputstr(expr->expr, ")");
12184 }
12185 delete v;
12186 } else {
12187 u.expr.ti1->generate_code(expr);
12188 }
12189 expr->expr = mputstr(expr->expr, ")");
12190 } break;
a38c6d4c 12191 case OPTYPE_PROF_RUNNING:
12192 expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
12193 break;
970ed795
EL
12194 default:
12195 FATAL_ERROR("Value::generate_code_expr_expr()");
12196 }
12197 }
12198
12199 void Value::generate_code_expr_unary(expression_struct *expr,
12200 const char *operator_str, Value *v1)
12201 {
12202 expr->expr = mputprintf(expr->expr, "(%s(", operator_str);
12203 v1->generate_code_expr_mandatory(expr);
12204 expr->expr = mputstrn(expr->expr, "))", 2);
12205 }
12206
12207 void Value::generate_code_expr_infix(expression_struct *expr,
12208 const char *operator_str, Value *v1,
12209 Value *v2, bool optional_allowed)
12210 {
12211 if (!get_needs_conversion()) {
12212 expr->expr = mputc(expr->expr, '(');
12213 if (optional_allowed) v1->generate_code_expr(expr);
12214 else v1->generate_code_expr_mandatory(expr);
12215 expr->expr = mputprintf(expr->expr, " %s ", operator_str);
12216 if (optional_allowed) v2->generate_code_expr(expr);
12217 else v2->generate_code_expr_mandatory(expr);
12218 expr->expr = mputc(expr->expr, ')');
12219 } else { // Temporary variable for the converted value.
12220 const string& tmp_id1 = get_temporary_id();
12221 const char *tmp_id_str1 = tmp_id1.c_str();
12222 expression_struct expr_tmp;
12223 Code::init_expr(&expr_tmp);
12224 switch (u.expr.v_optype) {
12225 case OPTYPE_EQ:
12226 case OPTYPE_NE: {
12227 // Always "v1 -> v2".
12228 Type *t1 = v1->get_expr_governor_last();
12229 Type *t2 = v2->get_expr_governor_last();
12230 if (t1 == t2) FATAL_ERROR("Value::generate_code_expr_infix()");
12231 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12232 else v2->generate_code_expr_mandatory(&expr_tmp);
12233 if (expr_tmp.preamble)
12234 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12235 expr->preamble = mputprintf(expr->preamble,
12236 "%s %s;\n"
12237 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12238 "and `%s' are not compatible at run-time\");\n",
12239 t1->get_genname_value(v1->get_my_scope()).c_str(), tmp_id_str1,
12240 TypeConv::get_conv_func(t2, t1, get_my_scope()
12241 ->get_scope_mod()).c_str(), tmp_id_str1, expr_tmp.expr,
12242 t2->get_typename().c_str(), t1->get_typename().c_str());
12243 Code::free_expr(&expr_tmp);
12244 if (optional_allowed) v1->generate_code_expr(expr);
12245 else v1->generate_code_expr_mandatory(expr);
12246 expr->expr = mputprintf(expr->expr, " %s %s", operator_str,
12247 tmp_id_str1);
12248 break; }
12249 // OPTYPE_{REPLACE,SUBSTR} are handled in their own code generation
12250 // functions. The governors of all operands must exist at this point.
12251 case OPTYPE_ROTL:
12252 case OPTYPE_ROTR:
12253 case OPTYPE_CONCAT: {
12254 const string& tmp_id2 = get_temporary_id();
12255 const char *tmp_id_str2 = tmp_id2.c_str();
12256 if (!my_governor) FATAL_ERROR("Value::generate_code_expr_infix()");
12257 Type *my_gov = my_governor->get_type_refd_last();
12258 Type *t1_gov = v1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)
12259 ->get_type_refd_last();
12260 if (!t1_gov || my_gov == t1_gov)
12261 FATAL_ERROR("Value::generate_code_expr_infix()");
12262 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
12263 t1_gov->get_genname_value(my_scope).c_str(), tmp_id_str1);
12264 expr_tmp.expr = mputprintf(expr_tmp.expr, "%s = ", tmp_id_str1);
12265 if (optional_allowed) v1->generate_code_expr(&expr_tmp);
12266 else v1->generate_code_expr_mandatory(&expr_tmp);
12267 expr_tmp.expr = mputprintf(expr_tmp.expr, " %s ", operator_str);
12268 if (optional_allowed) v2->generate_code_expr(&expr_tmp);
12269 else v2->generate_code_expr_mandatory(&expr_tmp);
12270 expr->preamble = Code::merge_free_expr(expr->preamble, &expr_tmp);
12271 expr->preamble = mputprintf(expr->preamble,
12272 "%s %s;\n"
12273 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' "
12274 "and `%s' are not compatible at run-time\");\n",
12275 my_gov->get_genname_value(my_scope).c_str(), tmp_id_str2,
12276 TypeConv::get_conv_func(t1_gov, my_gov, get_my_scope()
12277 ->get_scope_mod()).c_str(), tmp_id_str2, tmp_id_str1,
12278 my_gov->get_typename().c_str(), t1_gov->get_typename().c_str());
12279 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str2);
12280 break; }
12281 default:
12282 FATAL_ERROR("Value::generate_code_expr_infix()");
12283 break;
12284 }
12285 }
12286 }
12287
12288 void Value::generate_code_expr_and_or(expression_struct *expr)
12289 {
12290 if (u.expr.v2->needs_short_circuit()) {
12291 // introduce a temporary variable to store the result of the operation
12292 const string& tmp_id = get_temporary_id();
12293 const char *tmp_id_str = tmp_id.c_str();
12294 expr->preamble = mputprintf(expr->preamble, "boolean %s;\n", tmp_id_str);
12295 expression_struct expr2;
12296 // the left operand must be evaluated anyway
12297 Code::init_expr(&expr2);
12298 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12299 u.expr.v1->generate_code_expr_mandatory(&expr2);
12300 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12301 expr->preamble = mputprintf(expr->preamble, "if (%s%s) ",
12302 u.expr.v_optype == OPTYPE_AND ? "" : "!", tmp_id_str);
12303 // evaluate the right operand only when necessary
12304 // in this case the final result will be the right operand
12305 Code::init_expr(&expr2);
12306 expr2.expr = mputprintf(expr2.expr, "%s = ", tmp_id_str);
12307 u.expr.v2->generate_code_expr_mandatory(&expr2);
12308 expr->preamble = Code::merge_free_expr(expr->preamble, &expr2);
12309 // the result is now in the temporary variable
12310 expr->expr = mputstr(expr->expr, tmp_id_str);
12311 } else {
12312 // use the overloaded operator to get better error messages
12313 generate_code_expr_infix(expr, u.expr.v_optype == OPTYPE_AND ?
12314 "&&" : "||", u.expr.v1, u.expr.v2, false);
12315 }
12316 }
12317
12318 void Value::generate_code_expr_predef1(expression_struct *expr,
12319 const char *function_name,
12320 Value *v1)
12321 {
12322 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12323 v1->generate_code_expr_mandatory(expr);
12324 expr->expr = mputc(expr->expr, ')');
12325 }
12326
12327 void Value::generate_code_expr_predef2(expression_struct *expr,
12328 const char *function_name,
12329 Value *v1, Value *v2)
12330 {
12331 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12332 v1->generate_code_expr_mandatory(expr);
12333 expr->expr = mputstr(expr->expr, ", ");
12334 v2->generate_code_expr_mandatory(expr);
12335 expr->expr = mputc(expr->expr, ')');
12336 }
12337
12338 void Value::generate_code_expr_predef3(expression_struct *expr,
12339 const char *function_name,
12340 Value *v1, Value *v2, Value *v3)
12341 {
12342 expr->expr = mputprintf(expr->expr, "%s(", function_name);
12343 v1->generate_code_expr_mandatory(expr);
12344 expr->expr = mputstr(expr->expr, ", ");
12345 v2->generate_code_expr_mandatory(expr);
12346 expr->expr = mputstr(expr->expr, ", ");
12347 v3->generate_code_expr_mandatory(expr);
12348 expr->expr = mputc(expr->expr, ')');
12349 }
12350
12351 void Value::generate_code_expr_substr(expression_struct *expr)
12352 {
12353 bool par1_is_str;
12354 Value* v1 = u.expr.ti1->get_specific_value();
12355 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12356 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12357 if (par1_is_str) expr->expr = mputstr(expr->expr, "substr(");
12358 if (v1) v1->generate_code_expr_mandatory(expr);
12359 else u.expr.ti1->generate_code(expr);
12360 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12361 else expr->expr = mputstr(expr->expr, ".substr(");
12362 if (!par1_is_str && u.expr.v2->is_unfoldable())
12363 expr->expr = mputstr(expr->expr, "(int)");
12364 u.expr.v2->generate_code_expr_mandatory(expr);
12365 expr->expr = mputstr(expr->expr, ", ");
12366 if (!par1_is_str && u.expr.v3->is_unfoldable())
12367 expr->expr = mputstr(expr->expr, "(int)");
12368 u.expr.v3->generate_code_expr_mandatory(expr);
12369 expr->expr = mputc(expr->expr, ')');
12370 }
12371
12372 void Value::generate_code_expr_substr_replace_compat(expression_struct *expr)
12373 {
12374 expression_struct expr_tmp;
12375 Code::init_expr(&expr_tmp);
12376 Type *t1 = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE)
12377 ->get_type_refd_last();
12378 if (!t1 || t1 == my_governor->get_type_refd_last())
12379 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12380 if (u.expr.v_optype == OPTYPE_SUBSTR) {
12381 generate_code_expr_substr(&expr_tmp);
12382 } else if (u.expr.v_optype == OPTYPE_REPLACE) {
12383 generate_code_expr_replace(&expr_tmp);
12384 } else {
12385 FATAL_ERROR("Value::generate_code_expr_substr_replace_compat()");
12386 }
12387 // Two temporaries to store the result of substr() or replace() and to
12388 // store the converted value.
12389 const string& tmp_id1 = get_temporary_id();
12390 const char *tmp_id_str1 = tmp_id1.c_str();
12391 const string& tmp_id2 = get_temporary_id();
12392 const char *tmp_id_str2 = tmp_id2.c_str();
12393 if (expr_tmp.preamble)
12394 expr->preamble = mputstr(expr->preamble, expr_tmp.preamble);
12395 expr->preamble = mputprintf(expr->preamble, "%s %s;\n%s %s = %s;\n",
12396 my_governor->get_genname_value(my_scope).c_str(), tmp_id_str1,
12397 t1->get_genname_value(my_scope).c_str(), tmp_id_str2, expr_tmp.expr);
12398 if (expr_tmp.postamble)
12399 expr->preamble = mputstr(expr->preamble, expr_tmp.postamble);
12400 Code::free_expr(&expr_tmp);
12401 expr->preamble = mputprintf(expr->preamble,
12402 "if (!%s(%s, %s)) TTCN_error(\"Values or templates of types `%s' and "
12403 "`%s' are not compatible at run-time\");\n",
12404 TypeConv::get_conv_func(t1, my_governor->get_type_refd_last(),
12405 my_scope->get_scope_mod()).c_str(), tmp_id_str1, tmp_id_str2,
12406 my_governor->get_typename().c_str(), t1->get_typename().c_str());
12407 expr->expr = mputprintf(expr->expr, "%s", tmp_id_str1);
12408 }
12409
12410 void Value::generate_code_expr_regexp(expression_struct *expr)
12411 {
12412 Value* v1 = u.expr.ti1->get_specific_value();
12413 Value* v2 = u.expr.t2->get_specific_value();
12414 expr->expr = mputstr(expr->expr, "regexp(");
12415 if (v1) v1->generate_code_expr_mandatory(expr);
12416 else u.expr.ti1->generate_code(expr);
12417 expr->expr = mputstr(expr->expr, ", ");
12418 if (v2) v2->generate_code_expr_mandatory(expr);
12419 else u.expr.t2->generate_code(expr);
12420 expr->expr = mputstr(expr->expr, ", ");
12421 u.expr.v3->generate_code_expr_mandatory(expr);
12422 expr->expr = mputc(expr->expr, ')');
12423 }
12424
12425 void Value::generate_code_expr_replace(expression_struct *expr)
12426 {
12427 Value* v1 = u.expr.ti1->get_specific_value();
12428 Value* v4 = u.expr.ti4->get_specific_value();
12429 bool par1_is_str;
12430 if (v1) par1_is_str = v1->is_string_type(Type::EXPECTED_TEMPLATE);
12431 else par1_is_str = u.expr.ti1->is_string_type(Type::EXPECTED_TEMPLATE);
12432 if (par1_is_str) expr->expr = mputstr(expr->expr, "replace(");
12433 if (v1) v1->generate_code_expr_mandatory(expr);
12434 else u.expr.ti1->generate_code(expr);
12435 if (par1_is_str) expr->expr = mputstr(expr->expr, ", ");
12436 else expr->expr = mputstr(expr->expr, ".replace(");
12437 if (!par1_is_str && u.expr.v2->is_unfoldable())
12438 expr->expr = mputstr(expr->expr, "(int)");
12439 u.expr.v2->generate_code_expr_mandatory(expr);
12440 expr->expr = mputstr(expr->expr, ", ");
12441 if (!par1_is_str && u.expr.v3->is_unfoldable())
12442 expr->expr = mputstr(expr->expr, "(int)");
12443 u.expr.v3->generate_code_expr_mandatory(expr);
12444 expr->expr = mputstr(expr->expr, ", ");
12445 if (v4) {
12446 // if v4 is an empty record of constant (NULL_VALUE), the C++ compiler won't know
12447 // which replace function to call (replace(int,int,X) or replace(int,int,X_template))
12448 Value* v4_last = v4->get_value_refd_last();
12449 if ((v4_last->valuetype == V_SEQOF || v4_last->valuetype == V_SETOF)
12450 && !v4_last->u.val_vs->is_indexed() && v4_last->u.val_vs->get_nof_vs() == 0) {
3abe9331 12451 expr->expr = mputprintf(expr->expr, "(%s)", v4->my_governor->get_genname_value(my_scope).c_str());
970ed795
EL
12452 }
12453 v4->generate_code_expr_mandatory(expr);
12454 }
12455 else u.expr.ti4->generate_code(expr);
12456 expr->expr = mputc(expr->expr, ')');
12457 }
12458
12459 void Value::generate_code_expr_rnd(expression_struct *expr,
12460 Value *v1)
12461 {
12462 if(!v1) // simple random generation
12463 expr->expr = mputstr(expr->expr, "rnd()");
12464 else { // random generation with seeding
12465 expr->expr = mputstr(expr->expr, "rnd(");
12466 v1->generate_code_expr_mandatory(expr);
12467 expr->expr = mputc(expr->expr, ')');
12468 }
12469 }
12470
12471 void Value::generate_code_expr_create(expression_struct *expr,
12472 Ttcn::Ref_base *type, Value *name, Value *location, bool alive)
12473 {
12474 expr->expr = mputstr(expr->expr, "TTCN_Runtime::create_component(");
12475 // first two arguments: component type
12476 Assignment *t_ass = type->get_refd_assignment();
12477 if (!t_ass || t_ass->get_asstype() != Assignment::A_TYPE)
12478 FATAL_ERROR("Value::generate_code_expr_create()");
12479 Type *comptype = t_ass->get_Type()->get_field_type(type->get_subrefs(),
12480 Type::EXPECTED_DYNAMIC_VALUE);
12481 if (!comptype) FATAL_ERROR("Value::generate_code_expr_create()");
12482 comptype = comptype->get_type_refd_last();
12483 expr->expr = comptype->get_CompBody()
12484 ->generate_code_comptype_name(expr->expr);
12485 expr->expr = mputstr(expr->expr, ", ");
12486 // third argument: component name
12487 if (name) {
12488 Value *t_val = name->get_value_refd_last();
12489 if (t_val->valuetype == V_CSTR) {
12490 // the argument is foldable to a string literal
12491 size_t str_len = t_val->u.str.val_str->size();
12492 const char *str_ptr = t_val->u.str.val_str->c_str();
12493 expr->expr = mputc(expr->expr, '"');
12494 for (size_t i = 0; i < str_len; i++)
12495 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12496 expr->expr = mputc(expr->expr, '"');
12497 } else name->generate_code_expr_mandatory(expr);
12498 } else expr->expr = mputstr(expr->expr, "NULL");
12499 expr->expr = mputstr(expr->expr, ", ");
12500 // fourth argument: location
12501 if (location) {
12502 Value *t_val = location->get_value_refd_last();
12503 if (t_val->valuetype == V_CSTR) {
12504 // the argument is foldable to a string literal
12505 size_t str_len = t_val->u.str.val_str->size();
12506 const char *str_ptr = t_val->u.str.val_str->c_str();
12507 expr->expr = mputc(expr->expr, '"');
12508 for (size_t i = 0; i < str_len; i++)
12509 expr->expr = Code::translate_character(expr->expr, str_ptr[i], true);
12510 expr->expr = mputc(expr->expr, '"');
12511 } else location->generate_code_expr_mandatory(expr);
12512 } else expr->expr = mputstr(expr->expr, "NULL");
12513 // fifth argument: alive flag
12514 expr->expr = mputprintf(expr->expr, ", %s)", alive ? "TRUE" : "FALSE");
12515 }
12516
12517 void Value::generate_code_expr_activate(expression_struct *expr)
12518 {
12519 Assignment *t_ass = u.expr.r1->get_refd_assignment();
12520 if (!t_ass || t_ass->get_asstype() != Assignment::A_ALTSTEP)
12521 FATAL_ERROR("Value::generate_code_expr_activate()");
12522 expr->expr = mputprintf(expr->expr, "%s(",
12523 t_ass->get_genname_from_scope(my_scope, "activate_").c_str());
12524 u.expr.r1->get_parlist()->generate_code_noalias(expr, t_ass->get_FormalParList());
12525 expr->expr = mputc(expr->expr, ')');
12526 }
12527
12528 void Value::generate_code_expr_activate_refd(expression_struct *expr)
12529 {
12530 Value *v_last = u.expr.v1->get_value_refd_last();
12531 if (v_last->valuetype == V_ALTSTEP) {
12532 // the referred altstep is known
12533 expr->expr = mputprintf(expr->expr, "%s(", v_last->get_refd_fat()
12534 ->get_genname_from_scope(my_scope, "activate_").c_str());
12535 } else {
12536 // the referred altstep is unknown
12537 u.expr.v1->generate_code_expr_mandatory(expr);
12538 expr->expr = mputstr(expr->expr,".activate(");
12539 }
12540 u.expr.ap_list2->generate_code_noalias(expr, NULL);
12541 expr->expr = mputc(expr->expr, ')');
12542 }
12543
12544 void Value::generate_code_expr_execute(expression_struct *expr)
12545 {
12546 Assignment *testcase = u.expr.r1->get_refd_assignment();
12547 expr->expr = mputprintf(expr->expr, "%s(",
12548 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12549 Ttcn::ActualParList *parlist = u.expr.r1->get_parlist();
12550 if (parlist->get_nof_pars() > 0) {
12551 parlist->generate_code_alias(expr, testcase->get_FormalParList(),
12552 0, false);
12553 expr->expr = mputstr(expr->expr, ", ");
12554 }
12555 if (u.expr.v2) {
12556 expr->expr = mputstr(expr->expr, "TRUE, ");
12557 u.expr.v2->generate_code_expr_mandatory(expr);
12558 expr->expr = mputc(expr->expr, ')');
12559 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12560 }
12561
12562 void Value::generate_code_expr_execute_refd(expression_struct *expr)
12563 {
12564 Value *v_last = u.expr.v1->get_value_refd_last();
12565 if (v_last->valuetype == V_TESTCASE) {
12566 // the referred testcase is known
12567 Assignment *testcase = v_last->get_refd_fat();
12568 expr->expr = mputprintf(expr->expr, "%s(",
12569 testcase->get_genname_from_scope(my_scope, "testcase_").c_str());
12570 u.expr.ap_list2->generate_code_alias(expr,
12571 testcase->get_FormalParList(), 0, false);
12572 } else {
12573 // the referred testcase is unknown
12574 u.expr.v1->generate_code_expr_mandatory(expr);
12575 expr->expr = mputstr(expr->expr,".execute(");
12576 u.expr.ap_list2->generate_code_alias(expr, 0, 0, false);
12577 }
12578 if (u.expr.ap_list2->get_nof_pars() > 0)
12579 expr->expr = mputstr(expr->expr, ", ");
12580 if (u.expr.v3) {
12581 expr->expr = mputstr(expr->expr, "TRUE, ");
12582 u.expr.v3->generate_code_expr_mandatory(expr);
12583 expr->expr = mputc(expr->expr, ')');
12584 } else expr->expr = mputstr(expr->expr, "FALSE, 0.0)");
12585 }
12586
12587 void Value::generate_code_expr_invoke(expression_struct *expr)
12588 {
12589 Value *last_v = u.invoke.v->get_value_refd_last();
12590 if (last_v->get_valuetype() == V_FUNCTION) {
12591 // the referred function is known
12592 Assignment *function = last_v->get_refd_fat();
12593 expr->expr = mputprintf(expr->expr, "%s(",
12594 function->get_genname_from_scope(my_scope).c_str());
12595 u.invoke.ap_list->generate_code_alias(expr,
12596 function->get_FormalParList(), function->get_RunsOnType(), false);
12597 } else {
12598 // the referred function is unknown
12599 u.invoke.v->generate_code_expr_mandatory(expr);
12600 expr->expr = mputstr(expr->expr, ".invoke(");
12601 Type* gov_last = last_v->get_expr_governor_last();
12602 u.invoke.ap_list->generate_code_alias(expr, 0,
12603 gov_last->get_fat_runs_on_type(), gov_last->get_fat_runs_on_self());
12604 }
12605 expr->expr = mputc(expr->expr, ')');
12606 }
12607
12608 void Value::generate_code_expr_optional_field_ref(expression_struct *expr,
12609 Reference *ref)
12610 {
12611 // if the referenced value points to an optional value field the
12612 // generated code has to be corrected at the end:
12613 // `fieldid()' => `fieldid()()'
12614 Assignment *ass = ref->get_refd_assignment();
12615 if (!ass) FATAL_ERROR("Value::generate_code_expr_optional_field_ref()");
12616 switch (ass->get_asstype()) {
12617 case Assignment::A_CONST:
12618 case Assignment::A_EXT_CONST:
12619 case Assignment::A_MODULEPAR:
12620 case Assignment::A_VAR:
12621 case Assignment::A_FUNCTION_RVAL:
12622 case Assignment::A_EXT_FUNCTION_RVAL:
12623 case Assignment::A_PAR_VAL_IN:
12624 case Assignment::A_PAR_VAL_OUT:
12625 case Assignment::A_PAR_VAL_INOUT:
12626 // only these are mapped to value objects
12627 if (ass->get_Type()->field_is_optional(ref->get_subrefs()))
12628 expr->expr = mputstr(expr->expr, "()");
12629 break;
12630 default:
12631 break;
12632 }
12633 }
12634
12635 void Value::generate_code_expr_encode(expression_struct *expr)
12636 {
12637 Value* v1 = 0;
12638
12639 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12640 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12641 v1 = templ->get_specific_value();
12642 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12643
12644 expression_struct expr2;
12645 Code::init_expr(&expr2);
12646
12647 bool is_templ = false;
12648 switch (templ->get_templatetype()) {
12649 case Template::SPECIFIC_VALUE:
12650 v1->generate_code_expr_mandatory(&expr2);
12651 break;
12652 default:
12653 u.expr.ti1->generate_code(&expr2);
12654 is_templ = true;
12655 break;
12656 }
12657
12658 if (!gov_last->is_coding_by_function()) {
12659 const string& tmp_id = get_temporary_id();
12660 const string& tmp_buf_id = get_temporary_id();
12661 const string& tmp_ref_id = get_temporary_id();
12662 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12663 tmp_id.c_str());
12664 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12665 tmp_buf_id.c_str());
12666 if (expr2.preamble) { // copy preamble setting up the argument, if any
12667 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12668 expr->preamble = mputc (expr->preamble, '\n');
12669 }
12670 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12671 gov_last->get_genname_typedescriptor(
12672 u.expr.ti1->get_Template()->get_my_scope()
12673 ).c_str(),
12674 tmp_ref_id.c_str(),
12675 expr2.expr);
12676 if (is_templ) // make a value out of the template, if needed
12677 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12678 expr->preamble = mputprintf(expr->preamble,
12679 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12680 tmp_ref_id.c_str(),
12681 gov_last->get_genname_typedescriptor(
12682 u.expr.ti1->get_Template()->get_my_scope()
12683 ).c_str(),
12684 tmp_buf_id.c_str(),
12685 gov_last->get_coding(true).c_str()
12686 );
12687 expr->preamble = mputstr(expr->preamble, ");\n");
12688 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12689 tmp_buf_id.c_str(),
12690 tmp_id.c_str()
12691 );
12692 expr->expr = mputprintf(expr->expr, "oct2bit(%s)", tmp_id.c_str());
12693 if (expr2.postamble)
12694 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12695 } else
3f84031e 12696 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12697 gov_last->get_coding(true).c_str(), expr2.expr,
12698 is_templ ? ".valueof()" : "");
970ed795
EL
12699 Code::free_expr(&expr2);
12700 }
1d0599f0 12701
970ed795
EL
12702 void Value::generate_code_expr_decode(expression_struct *expr)
12703 {
12704 expression_struct expr1, expr2;
12705 Code::init_expr(&expr1);
12706 Code::init_expr(&expr2);
12707 u.expr.r1->generate_code(&expr1);
12708 u.expr.r2->generate_code(&expr2);
12709
12710 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12711 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12712 get_type_refd_last();
12713
12714 if (expr1.preamble)
12715 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12716 if (expr2.preamble)
12717 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12718
12719 if (!_type->is_coding_by_function()) {
12720 const string& tmp_id = get_temporary_id();
12721 const string& buffer_id = get_temporary_id();
12722 const string& retval_id = get_temporary_id();
12723 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12724 field_is_optional(u.expr.r2->get_subrefs());
12725
12726 expr->preamble = mputprintf(expr->preamble,
12727 "TTCN_Buffer %s(bit2oct(%s));\n"
12728 "INTEGER %s;\n"
12729 "TTCN_EncDec::set_error_behavior("
12730 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12731 "TTCN_EncDec::clear_error();\n",
12732 buffer_id.c_str(),
12733 expr1.expr,
12734 retval_id.c_str()
12735 );
12736 expr->preamble = mputprintf(expr->preamble,
12737 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12738 expr2.expr,
12739 optional ? "()" : "",
12740 _type->get_genname_typedescriptor(
12741 u.expr.r2->get_my_scope()
12742 ).c_str(),
12743 buffer_id.c_str(),
12744 _type->get_coding(false).c_str()
12745 );
12746 expr->preamble = mputprintf(expr->preamble,
12747 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12748 "case TTCN_EncDec::ET_NONE: {\n"
12749 "%s.cut();\n"
12750 "OCTETSTRING %s;\n"
12751 "%s.get_string(%s);\n"
12752 "%s = oct2bit(%s);\n"
12753 "%s = 0;\n"
12754 "}break;\n"
12755 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12756 "case TTCN_EncDec::ET_LEN_ERR:\n"
12757 "%s = 2;\n"
12758 "break;\n"
12759 "default:\n"
12760 "%s = 1;\n"
12761 "}\n"
12762 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12763 "TTCN_EncDec::EB_DEFAULT);\n"
12764 "TTCN_EncDec::clear_error();\n",
12765 buffer_id.c_str(),
12766 tmp_id.c_str(),
12767 buffer_id.c_str(),
12768 tmp_id.c_str(),
12769 expr1.expr,
12770 tmp_id.c_str(),
12771 retval_id.c_str(),
12772 retval_id.c_str(),
12773 retval_id.c_str()
12774 );
12775 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12776 } else
12777 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12778 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12779 if (expr1.postamble)
12780 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12781 if (expr2.postamble)
12782 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12783 Code::free_expr(&expr1);
12784 Code::free_expr(&expr2);
12785 }
1d0599f0 12786
12787void Value::generate_code_expr_encvalue_unichar(expression_struct *expr)
12788 {
12789 Value* v1 = 0;
12790
12791 Template* templ = u.expr.ti1->get_Template()->get_template_refd_last();
12792 if (templ->get_templatetype() == Template::SPECIFIC_VALUE)
12793 v1 = templ->get_specific_value();
12794 Type* gov_last = templ->get_my_governor()->get_type_refd_last();
12795
12796 expression_struct expr2;
12797 Code::init_expr(&expr2);
12798
12799 bool is_templ = false;
12800 switch (templ->get_templatetype()) {
12801 case Template::SPECIFIC_VALUE:
12802 v1->generate_code_expr_mandatory(&expr2);
12803 break;
12804 default:
12805 u.expr.ti1->generate_code(&expr2);
12806 is_templ = true;
12807 break;
12808 }
12809
12810 if (!gov_last->is_coding_by_function()) {
12811 const string& tmp_id = get_temporary_id();
12812 const string& tmp_buf_id = get_temporary_id();
12813 const string& tmp_ref_id = get_temporary_id();
12814 expr->preamble = mputprintf(expr->preamble, "OCTETSTRING %s;\n",
12815 tmp_id.c_str());
12816 expr->preamble = mputprintf(expr->preamble, "TTCN_Buffer %s;\n",
12817 tmp_buf_id.c_str());
12818 if (expr2.preamble) { // copy preamble setting up the argument, if any
12819 expr->preamble = mputstr(expr->preamble, expr2.preamble);
12820 expr->preamble = mputc (expr->preamble, '\n');
12821 }
12822 expr->preamble = mputprintf(expr->preamble, "%s const& %s = %s",
12823 gov_last->get_genname_typedescriptor(
12824 u.expr.ti1->get_Template()->get_my_scope()
12825 ).c_str(),
12826 tmp_ref_id.c_str(),
12827 expr2.expr);
12828 if (is_templ) // make a value out of the template, if needed
12829 expr->preamble = mputprintf(expr->preamble, ".valueof()");
12830 expr->preamble = mputprintf(expr->preamble,
12831 ";\n%s.encode(%s_descr_, %s, TTCN_EncDec::CT_%s",
12832 tmp_ref_id.c_str(),
12833 gov_last->get_genname_typedescriptor(
12834 u.expr.ti1->get_Template()->get_my_scope()
12835 ).c_str(),
12836 tmp_buf_id.c_str(),
12837 gov_last->get_coding(true).c_str()
12838 );
12839 expr->preamble = mputstr(expr->preamble, ");\n");
12840 expr->preamble = mputprintf(expr->preamble, "%s.get_string(%s);\n",
12841 tmp_buf_id.c_str(),
12842 tmp_id.c_str()
12843 );
12844 const char * v2_code = NULL;
12845 if(u.expr.v2) {
12846 v2_code = generate_code_char_coding_check(expr, u.expr.v2, "encvalue_unichar");
12847 }
12848 expr->expr = mputprintf(expr->expr, "oct2unichar(%s", tmp_id.c_str());
12849 if(u.expr.v2) {
12850 expr->expr = mputprintf(expr->expr, ", %s", v2_code);
12851 } else {
12852 expr->expr = mputprintf(expr->expr, ", \"UTF-8\""); //default
12853 }
12854 expr->expr = mputprintf(expr->expr, ")");
12855 if (expr2.postamble)
12856 expr->postamble = mputstr(expr->postamble, expr2.postamble);
12857 } else
12858 expr->expr = mputprintf(expr->expr, "%s(%s%s)",
12859 gov_last->get_coding(true).c_str(), expr2.expr,
12860 is_templ ? ".valueof()" : "");
12861 Code::free_expr(&expr2);
12862 }
12863
12864 void Value::generate_code_expr_decvalue_unichar(expression_struct *expr)
12865 {
12866 expression_struct expr1, expr2;
12867 Code::init_expr(&expr1);
12868 Code::init_expr(&expr2);
12869 u.expr.r1->generate_code(&expr1);
12870 u.expr.r2->generate_code(&expr2);
12871
12872 Type* _type = u.expr.r2->get_refd_assignment()->get_Type()->
12873 get_field_type(u.expr.r2->get_subrefs(), Type::EXPECTED_DYNAMIC_VALUE)->
12874 get_type_refd_last();
12875
12876 if (expr1.preamble)
12877 expr->preamble = mputprintf(expr->preamble, "%s", expr1.preamble);
12878 if (expr2.preamble)
12879 expr->preamble = mputprintf(expr->preamble, "%s", expr2.preamble);
12880
12881 if (!_type->is_coding_by_function()) {
12882 const string& tmp_id = get_temporary_id();
12883 const string& buffer_id = get_temporary_id();
12884 const string& retval_id = get_temporary_id();
12885 const bool optional = u.expr.r2->get_refd_assignment()->get_Type()->
12886 field_is_optional(u.expr.r2->get_subrefs());
12887
12888 const char* v3_code = NULL;
12889 if(u.expr.v3) {
12890 v3_code = generate_code_char_coding_check(expr, u.expr.v3, "decvalue_unichar");
12891 }
12892 expr->preamble = mputprintf(expr->preamble,
12893 "TTCN_Buffer %s(unichar2oct(%s, %s));\n"
12894 "INTEGER %s;\n"
12895 "TTCN_EncDec::set_error_behavior("
12896 "TTCN_EncDec::ET_ALL, TTCN_EncDec::EB_WARNING);\n"
12897 "TTCN_EncDec::clear_error();\n",
12898 buffer_id.c_str(),
12899 expr1.expr,
12900 u.expr.v3 ? v3_code : "\"UTF-8\"",
12901 retval_id.c_str()
12902 );
12903 expr->preamble = mputprintf(expr->preamble,
12904 "%s%s.decode(%s_descr_, %s, TTCN_EncDec::CT_%s);\n",
12905 expr2.expr,
12906 optional ? "()" : "",
12907 _type->get_genname_typedescriptor(
12908 u.expr.r2->get_my_scope()
12909 ).c_str(),
12910 buffer_id.c_str(),
12911 _type->get_coding(false).c_str()
12912 );
12913 expr->preamble = mputprintf(expr->preamble,
12914 "switch (TTCN_EncDec::get_last_error_type()) {\n"
12915 "case TTCN_EncDec::ET_NONE: {\n"
12916 "%s.cut();\n"
12917 "OCTETSTRING %s;\n"
12918 "%s.get_string(%s);\n"
12919 "%s = oct2unichar(%s, %s);\n"
12920 "%s = 0;\n"
12921 "}break;\n"
12922 "case TTCN_EncDec::ET_INCOMPL_MSG:\n"
12923 "case TTCN_EncDec::ET_LEN_ERR:\n"
12924 "%s = 2;\n"
12925 "break;\n"
12926 "default:\n"
12927 "%s = 1;\n"
12928 "}\n"
12929 "TTCN_EncDec::set_error_behavior(TTCN_EncDec::ET_ALL,"
12930 "TTCN_EncDec::EB_DEFAULT);\n"
12931 "TTCN_EncDec::clear_error();\n",
12932 buffer_id.c_str(),
12933 tmp_id.c_str(),
12934 buffer_id.c_str(),
12935 tmp_id.c_str(),
12936 expr1.expr,
12937 tmp_id.c_str(),
12938 u.expr.v3 ? v3_code : "\"UTF-8\"",
12939 retval_id.c_str(),
12940 retval_id.c_str(),
12941 retval_id.c_str()
12942 );
12943 expr->expr = mputprintf(expr->expr, "%s", retval_id.c_str());
12944 } else
12945 expr->expr = mputprintf(expr->expr, "%s(%s, %s)",
12946 _type->get_coding(false).c_str(), expr1.expr, expr2.expr);
12947 if (expr1.postamble)
12948 expr->postamble = mputprintf(expr->postamble, "%s", expr1.postamble);
12949 if (expr2.postamble)
12950 expr->postamble = mputprintf(expr->postamble, "%s", expr2.postamble);
12951 Code::free_expr(&expr1);
12952 Code::free_expr(&expr2);
12953 }
12954
0a1610f4 12955 void Value::generate_code_expr_checkstate(expression_struct *expr)
12956 {
12957 if (u.expr.r1) {
12958 // It is a port if r1 is not null
12959 u.expr.r1->generate_code_const_ref(expr);
12960 expr->expr = mputstr(expr->expr, ".");
12961 } else {
12962 // it is an any or all port if r1 is null
12963 if (u.expr.v_optype == OPTYPE_CHECKSTATE_ANY) {
12964 expr->expr = mputstr(expr->expr, "PORT::any_");
12965 } else if (u.expr.v_optype == OPTYPE_CHECKSTATE_ALL) {
12966 expr->expr = mputstr(expr->expr, "PORT::all_");
12967 } else {
12968 FATAL_ERROR("Value::generate_code_expr_checkstate()");
12969 }
12970 }
12971 expr->expr = mputstr(expr->expr, "check_port_state(");
12972 u.expr.v2->generate_code_expr_mandatory(expr);
12973 expr->expr = mputstr(expr->expr, ")");
12974 }
12975
efbe586d 12976 void Value::generate_code_expr_hostid(expression_struct *expr)
12977 {
12978 expr->expr = mputstr(expr->expr, "TTCN_Runtime::get_host_address(");
12979 if (u.expr.v1) u.expr.v1->generate_code_expr_mandatory(expr);
12980 else expr->expr = mputstr(expr->expr, "CHARSTRING(\"Ipv4orIpv6\")");
12981 expr->expr = mputstr(expr->expr, ")");
12982 }
12983
1d0599f0 12984 char* Value::generate_code_char_coding_check(expression_struct *expr, Value *v, const char *name)
12985 {
12986 expression_struct expr2;
12987 Code::init_expr(&expr2);
12988 v->generate_code_expr_mandatory(&expr2);
12989 expr->preamble = mputprintf(expr->preamble,
12990 "if (\"UTF-8\" != %s && \"UTF-16\" != %s && \"UTF-16LE\" != %s && \n"
12991 " \"UTF-16BE\" != %s && \"UTF-32\" != %s && \"UTF-32LE\" != %s && \n"
12992 " \"UTF-32BE\" != %s) {\n"
12993 " TTCN_error(\"%s: Invalid encoding parameter: %%s\", (const char*)%s);\n"
12994 "}\n", //todo errorbehaviour?
12995 expr2.expr,
12996 expr2.expr,
12997 expr2.expr,
12998 expr2.expr,
12999 expr2.expr,
13000 expr2.expr,
13001 expr2.expr,
13002 name,
13003 expr2.expr);
13004 return expr2.expr;
13005 }
970ed795
EL
13006
13007 char *Value::generate_code_init_choice(char *str, const char *name)
13008 {
13009 const char *alt_name = u.choice.alt_name->get_name().c_str();
13010 // Safe as long as get_name() returns a const string&, not a temporary.
13011 const char *alt_prefix =
13012 (my_governor->get_type_refd_last()->get_typetype()==Type::T_ANYTYPE)
13013 ? "AT_" : "";
13014 if (u.choice.alt_value->needs_temp_ref()) {
13015 const string& tmp_id = get_temporary_id();
13016 const char *tmp_id_str = tmp_id.c_str();
13017 str = mputprintf(str, "{\n"
13018 "%s& %s = %s.%s%s();\n", my_governor->get_comp_byName(*u.choice.alt_name)
13019 ->get_type()->get_genname_value(my_scope).c_str(), tmp_id_str, name,
13020 alt_prefix, alt_name);
13021 str = u.choice.alt_value->generate_code_init(str, tmp_id_str);
13022 str = mputstr(str, "}\n");
13023 } else {
13024 char *embedded_name = mprintf("%s.%s%s()", name, alt_prefix, alt_name);
13025 str = u.choice.alt_value->generate_code_init(str, embedded_name);
13026 Free(embedded_name);
13027 }
13028 return str;
13029 }
13030
13031 char *Value::generate_code_init_seof(char *str, const char *name)
13032 {
13033 size_t nof_vs = u.val_vs->get_nof_vs();
13034 if (nof_vs > 0) {
13035 str = mputprintf(str, "%s.set_size(%lu);\n", name, (unsigned long)nof_vs);
13036 const string& embedded_type =
13037 my_governor->get_ofType()->get_genname_value(my_scope);
13038 const char *embedded_type_str = embedded_type.c_str();
13039 for (size_t i = 0; i < nof_vs; i++) {
13040 Value *comp_v = u.val_vs->get_v_byIndex(i);
13041
13042 if (comp_v->valuetype == V_NOTUSED) continue;
13043 else if (comp_v->needs_temp_ref()) {
13044 const string& tmp_id = get_temporary_id();
13045 const char *tmp_id_str = tmp_id.c_str();
13046 str = mputprintf(str, "{\n"
13047 "%s& %s = %s[%lu];\n", embedded_type_str, tmp_id_str, name,
13048 (unsigned long) i);
13049 str = comp_v->generate_code_init(str, tmp_id_str);
13050 str = mputstr(str, "}\n");
13051 } else {
13052 char *embedded_name = mprintf("%s[%lu]", name, (unsigned long) i);
13053 str = comp_v->generate_code_init(str, embedded_name);
13054 Free(embedded_name);
13055 }
13056 }
13057 } else {
13058 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
13059 }
13060 return str;
13061 }
13062
13063 char *Value::generate_code_init_indexed(char *str, const char *name)
13064 {
13065 size_t nof_ivs = u.val_vs->get_nof_ivs();
13066 if (nof_ivs > 0) {
13067 // Previous values can be truncated. The concept is similar to
13068 // templates.
13069 Type *t_last = my_governor->get_type_refd_last();
13070 const string& oftype_name =
13071 t_last->get_ofType()->get_genname_value(my_scope);
13072 const char *oftype_name_str = oftype_name.c_str();
13073 for (size_t i = 0; i < nof_ivs; i++) {
13074 IndexedValue *iv = u.val_vs->get_iv_byIndex(i);
13075 const string& tmp_id_1 = get_temporary_id();
13076 str = mputstr(str, "{\n");
13077 Value *index = iv->get_index();
13078 if (index->get_valuetype() != V_INT) {
13079 const string& tmp_id_2 = get_temporary_id();
13080 str = mputprintf(str, "int %s;\n", tmp_id_2.c_str());
13081 str = index->generate_code_init(str, tmp_id_2.c_str());
13082 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
13083 tmp_id_1.c_str(), name, tmp_id_2.c_str());
13084 } else {
13085 str = mputprintf(str, "%s& %s = %s[%s];\n", oftype_name_str,
13086 tmp_id_1.c_str(), name,
13087 (index->get_val_Int()->t_str()).c_str());
13088 }
13089 str = iv->get_value()->generate_code_init(str, tmp_id_1.c_str());
13090 str = mputstr(str, "}\n");
13091 }
13092 } else { str = mputprintf(str, "%s = NULL_VALUE;\n", name); }
13093 return str;
13094 }
13095
13096 char *Value::generate_code_init_array(char *str, const char *name)
13097 {
13098 size_t nof_vs = u.val_vs->get_nof_vs();
13099 Type *t_last = my_governor->get_type_refd_last();
13100 Int index_offset = t_last->get_dimension()->get_offset();
13101 const string& embedded_type =
13102 t_last->get_ofType()->get_genname_value(my_scope);
13103 const char *embedded_type_str = embedded_type.c_str();
13104 for (size_t i = 0; i < nof_vs; i++) {
13105 Value *comp_v = u.val_vs->get_v_byIndex(i);
13106 if (comp_v->valuetype == V_NOTUSED) continue;
13107 else if (comp_v->needs_temp_ref()) {
13108 const string& tmp_id = get_temporary_id();
13109 const char *tmp_id_str = tmp_id.c_str();
13110 str = mputprintf(str, "{\n"
13111 "%s& %s = %s[%s];\n", embedded_type_str, tmp_id_str, name,
13112 Int2string(index_offset + i).c_str());
13113 str = comp_v->generate_code_init(str, tmp_id_str);
13114 str = mputstr(str, "}\n");
13115 } else {
13116 char *embedded_name = mprintf("%s[%s]", name,
13117 Int2string(index_offset + i).c_str());
13118 str = comp_v->generate_code_init(str, embedded_name);
13119 Free(embedded_name);
13120 }
13121 }
13122 return str;
13123 }
13124
13125 char *Value::generate_code_init_se(char *str, const char *name)
13126 {
13127 Type *type = my_governor->get_type_refd_last();
13128 size_t nof_comps = type->get_nof_comps();
13129 if (nof_comps > 0) {
13130 for (size_t i = 0; i < nof_comps; i++) {
13131 CompField *cf = type->get_comp_byIndex(i);
13132 const Identifier& field_id = cf->get_name();
13133 const char *field_name = field_id.get_name().c_str();
13134 Value *field_v;
13135 if (u.val_nvs->has_nv_withName(field_id)) {
13136 field_v = u.val_nvs->get_nv_byName(field_id)->get_value();
13137 if (field_v->valuetype == V_NOTUSED) continue;
13138 if (field_v->valuetype == V_OMIT) field_v = 0;
13139 } else if (is_asn1()) {
13140 if (cf->has_default()) {
13141 // handle like a referenced value
13142 Value *defval = cf->get_defval();
13143 if (needs_init_precede(defval)) {
13144 str = defval->generate_code_init(str,
13145 defval->get_lhs_name().c_str());
13146 }
13147 str = mputprintf(str, "%s.%s() = %s;\n", name, field_name,
13148 defval->get_genname_own(my_scope).c_str());
13149 continue;
13150 } else {
13151 if (!cf->get_is_optional())
13152 FATAL_ERROR("Value::generate_code_init()");
13153 field_v = 0;
13154 }
13155 } else {
13156 continue;
13157 }
13158 if (field_v) {
13159 // the value is not omit
13160 if (field_v->needs_temp_ref()) {
13161 const string& tmp_id = get_temporary_id();
13162 const char *tmp_id_str = tmp_id.c_str();
13163 str = mputprintf(str, "{\n"
13164 "%s& %s = %s.%s();\n", type->get_comp_byName(field_id)->get_type()
13165 ->get_genname_value(my_scope).c_str(), tmp_id_str, name,
13166 field_name);
13167 str = field_v->generate_code_init(str, tmp_id_str);
13168 str = mputstr(str, "}\n");
13169 } else {
13170 char *embedded_name = mprintf("%s.%s()", name,
13171 field_name);
13172 if (cf->get_is_optional() && field_v->is_compound())
13173 embedded_name = mputstr(embedded_name, "()");
13174 str = field_v->generate_code_init(str, embedded_name);
13175 Free(embedded_name);
13176 }
13177 } else {
13178 // the value is omit
13179 str = mputprintf(str, "%s.%s() = OMIT_VALUE;\n",
13180 name, field_name);
13181 }
13182 }
13183 } else {
13184 str = mputprintf(str, "%s = NULL_VALUE;\n", name);
13185 }
13186 return str;
13187 }
13188
13189 char *Value::generate_code_init_refd(char *str, const char *name)
13190 {
13191 Value *v = get_value_refd_last();
13192 if (v == this) {
13193 // the referred value is not available at compile time
13194 // the code generation is based on the reference
13195 if (use_runtime_2 && TypeConv::needs_conv_refd(v)) {
13196 str = TypeConv::gen_conv_code_refd(str, name, v);
13197 } else {
13198 expression_struct expr;
13199 Code::init_expr(&expr);
13200 expr.expr = mputprintf(expr.expr, "%s = ", name);
13201 u.ref.ref->generate_code_const_ref(&expr);
13202 str = Code::merge_free_expr(str, &expr);
13203 }
13204 } else {
13205 // the referred value is available at compile time
13206 // the code generation is based on the referred value
13207 if (v->has_single_expr() &&
13208 my_scope->get_scope_mod_gen() == v->my_scope->get_scope_mod_gen()) {
13209 // simple substitution for in-line values within the same module
13210 str = mputprintf(str, "%s = %s;\n", name,
13211 v->get_single_expr().c_str());
13212 } else {
13213 // use a simple reference to reduce code size
13214 if (needs_init_precede(v)) {
13215 // the referred value must be initialized first
13216 if (!v->is_toplevel() && v->needs_temp_ref()) {
13217 // temporary id should be introduced for the lhs
13218 const string& tmp_id = get_temporary_id();
13219 const char *tmp_id_str = tmp_id.c_str();
13220 str = mputprintf(str, "{\n"
13221 "%s& %s = %s;\n",
13222 v->get_my_governor()->get_genname_value(my_scope).c_str(),
13223 tmp_id_str, v->get_lhs_name().c_str());
13224 str = v->generate_code_init(str, tmp_id_str);
13225 str = mputstr(str, "}\n");
13226 } else {
13227 str = v->generate_code_init(str, v->get_lhs_name().c_str());
13228 }
13229 }
13230 str = mputprintf(str, "%s = %s;\n", name,
13231 v->get_genname_own(my_scope).c_str());
13232 }
13233 }
13234 return str;
13235 }
3abe9331 13236
3f84031e 13237 void Value::generate_json_value(JSON_Tokenizer& json,
13238 bool allow_special_float, /* = true */
13239 bool union_value_list, /* = false */
13240 Ttcn::JsonOmitCombination* omit_combo /* = NULL */)
3abe9331 13241 {
13242 switch (valuetype) {
13243 case V_INT:
13244 json.put_next_token(JSON_TOKEN_NUMBER, get_val_Int()->t_str().c_str());
13245 break;
13246 case V_REAL: {
13247 Real r = get_val_Real();
13248 if (r == REAL_INFINITY) {
13249 if (allow_special_float) {
13250 json.put_next_token(JSON_TOKEN_STRING, "\"infinity\"");
13251 }
13252 }
13253 else if (r == -REAL_INFINITY) {
13254 if (allow_special_float) {
13255 json.put_next_token(JSON_TOKEN_STRING, "\"-infinity\"");
13256 }
13257 }
13258 else if (r != r) {
13259 if (allow_special_float) {
13260 json.put_next_token(JSON_TOKEN_STRING, "\"not_a_number\"");
13261 }
13262 }
13263 else {
13264 // true if decimal representation possible (use %f format)
13265 bool decimal_repr = (r == 0.0)
13266 || (r > -MAX_DECIMAL_FLOAT && r <= -MIN_DECIMAL_FLOAT)
13267 || (r >= MIN_DECIMAL_FLOAT && r < MAX_DECIMAL_FLOAT);
13268 char* number_str = mprintf(decimal_repr ? "%f" : "%e", r);
13269 json.put_next_token(JSON_TOKEN_NUMBER, number_str);
13270 Free(number_str);
13271 }
13272 break; }
13273 case V_BOOL:
13274 json.put_next_token(get_val_bool() ? JSON_TOKEN_LITERAL_TRUE : JSON_TOKEN_LITERAL_FALSE);
13275 break;
13276 case V_BSTR:
13277 case V_HSTR:
13278 case V_OSTR:
13279 case V_CSTR: {
13280 char* str = convert_to_json_string(get_val_str().c_str());
13281 json.put_next_token(JSON_TOKEN_STRING, str);
13282 Free(str);
13283 break; }
13284 case V_USTR: {
13285 char* str = convert_to_json_string(ustring_to_uft8(get_val_ustr()).c_str());
13286 json.put_next_token(JSON_TOKEN_STRING, str);
13287 Free(str);
13288 break; }
13289 case V_VERDICT:
13290 case V_ENUM:
13291 json.put_next_token(JSON_TOKEN_STRING,
13292 (string('\"') + create_stringRepr() + string('\"')).c_str());
13293 break;
13294 case V_SEQOF:
13295 case V_SETOF:
13296 json.put_next_token(JSON_TOKEN_ARRAY_START);
13297 if (!u.val_vs->is_indexed()) {
13298 for (size_t i = 0; i < u.val_vs->get_nof_vs(); ++i) {
3f84031e 13299 u.val_vs->get_v_byIndex(i)->generate_json_value(json, allow_special_float,
13300 union_value_list, omit_combo);
3abe9331 13301 }
13302 }
13303 else {
13304 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); ++i) {
13305 // look for the entry with index equal to i
13306 for (size_t j = 0; j < u.val_vs->get_nof_ivs(); ++j) {
13307 if (u.val_vs->get_iv_byIndex(j)->get_index()->get_val_Int()->get_val() == (Int)i) {
3f84031e 13308 u.val_vs->get_iv_byIndex(j)->get_value()->generate_json_value(json,
13309 allow_special_float, union_value_list, omit_combo);
3abe9331 13310 break;
13311 }
13312 }
13313 }
13314 }
13315 json.put_next_token(JSON_TOKEN_ARRAY_END);
13316 break;
13317 case V_SEQ:
13318 case V_SET: {
13319 // omitted fields have 2 possible JSON values (the field is absent, or it's
13320 // present with value 'null'), each combination of omitted values must be
13321 // generated
3f84031e 13322 if (omit_combo == NULL) {
13323 FATAL_ERROR("Value::generate_json_value - no combo");
13324 }
3abe9331 13325 size_t len = get_nof_comps();
3f84031e 13326 // generate the JSON object from the present combination
13327 json.put_next_token(JSON_TOKEN_OBJECT_START);
3abe9331 13328 for (size_t i = 0; i < len; ++i) {
3f84031e 13329 Ttcn::JsonOmitCombination::omit_state_t state = omit_combo->get_state(this, i);
13330 if (state == Ttcn::JsonOmitCombination::OMITTED_ABSENT) {
13331 // the field is absent, don't insert anything
13332 continue;
13333 }
13334 // use the field's alias, if it has one
13335 const char* alias = NULL;
13336 if (my_governor != NULL) {
13337 JsonAST* field_attrib = my_governor->get_comp_byName(
13338 get_se_comp_byIndex(i)->get_name())->get_type()->get_json_attributes();
13339 if (field_attrib != NULL) {
13340 alias = field_attrib->alias;
13341 }
13342 }
13343 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13344 get_se_comp_byIndex(i)->get_name().get_ttcnname().c_str());
13345 if (state == Ttcn::JsonOmitCombination::OMITTED_NULL) {
13346 json.put_next_token(JSON_TOKEN_LITERAL_NULL);
3abe9331 13347 }
13348 else {
3f84031e 13349 get_se_comp_byIndex(i)->get_value()->generate_json_value(json,
13350 allow_special_float, union_value_list, omit_combo);
3abe9331 13351 }
13352 }
3f84031e 13353 json.put_next_token(JSON_TOKEN_OBJECT_END);
3abe9331 13354 break; }
13355 case V_CHOICE: {
3f84031e 13356 bool as_value = !union_value_list && my_governor != NULL &&
3abe9331 13357 my_governor->get_type_refd_last()->get_json_attributes() != NULL &&
13358 my_governor->get_type_refd_last()->get_json_attributes()->as_value;
13359 if (!as_value) {
13360 // no 'as value' coding instruction, insert an object with one field
13361 json.put_next_token(JSON_TOKEN_OBJECT_START);
13362 // use the field's alias, if it has one
13363 const char* alias = NULL;
13364 if (my_governor != NULL) {
13365 JsonAST* field_attrib = my_governor->get_comp_byName(
13366 get_alt_name())->get_type()->get_json_attributes();
13367 if (field_attrib != NULL) {
13368 alias = field_attrib->alias;
13369 }
13370 }
13371 json.put_next_token(JSON_TOKEN_NAME, (alias != NULL) ? alias :
13372 get_alt_name().get_ttcnname().c_str());
13373 }
3f84031e 13374 get_alt_value()->generate_json_value(json, allow_special_float,
13375 union_value_list, omit_combo);
3abe9331 13376 if (!as_value) {
13377 json.put_next_token(JSON_TOKEN_OBJECT_END);
13378 }
13379 break; }
13380 case V_REFD: {
13381 Value* v = get_value_refd_last();
13382 if (this != v) {
3f84031e 13383 v->generate_json_value(json, allow_special_float, union_value_list, omit_combo);
3abe9331 13384 return;
13385 }
13386 } // no break
13387 default:
13388 FATAL_ERROR("Value::generate_json_value - %d", valuetype);
13389 }
13390 }
970ed795
EL
13391
13392 bool Value::explicit_cast_needed(bool forIsValue)
13393 {
13394 Value *v_last = get_value_refd_last();
13395 if (v_last != this) {
13396 // this is a foldable referenced value
13397 // if the reference points to an imported or compound value the code
13398 // generation will be based on the reference so cast is not needed
13399 if (v_last->my_scope->get_scope_mod_gen() != my_scope->get_scope_mod_gen()
13400 || !v_last->has_single_expr()) return false;
13401 } else if (v_last->valuetype == V_REFD) {
13402 // this is an unfoldable reference (v_last==this)
13403 // explicit cast is needed only for string element references
13404 if (forIsValue) return false;
13405 Ttcn::FieldOrArrayRefs *t_subrefs = v_last->u.ref.ref->get_subrefs();
13406 return t_subrefs && t_subrefs->refers_to_string_element();
13407 }
13408 if (!v_last->my_governor) FATAL_ERROR("Value::explicit_cast_needed()");
13409 Type *t_governor = v_last->my_governor->get_type_refd_last();
13410 switch (t_governor->get_typetype()) {
13411 case Type::T_NULL:
13412 case Type::T_BOOL:
13413 case Type::T_INT:
13414 case Type::T_INT_A:
13415 case Type::T_REAL:
13416 case Type::T_ENUM_A:
13417 case Type::T_ENUM_T:
13418 case Type::T_VERDICT:
13419 case Type::T_COMPONENT:
13420 // these are mapped to built-in C/C++ types
13421 return true;
13422 case Type::T_SEQ_A:
13423 case Type::T_SEQ_T:
13424 case Type::T_SET_A:
13425 case Type::T_SET_T:
13426 // the C++ equivalent of empty record/set value (i.e. {}) is ambiguous
13427 return t_governor->get_nof_comps() == 0;
13428 case Type::T_SEQOF:
13429 case Type::T_SETOF:
13430 // the C++ equivalent of value {} is ambiguous
13431 // tr926
13432 return true;
13433 case Type::T_FUNCTION:
13434 case Type::T_ALTSTEP:
13435 case Type::T_TESTCASE:
13436 return true;
13437 default:
13438 return false;
13439 }
13440 }
13441
13442 bool Value::has_single_expr()
13443 {
13444 if (get_needs_conversion()) return false;
13445 switch (valuetype) {
13446 case V_EXPR:
13447 return has_single_expr_expr();
13448 case V_CHOICE:
13449 case V_ARRAY:
13450 // a union or array value cannot be represented as an in-line expression
13451 return false;
13452 case V_SEQOF:
13453 case V_SETOF:
13454 // only an empty record/set of value can be represented as an in-line
13455 // expression
13456 if (!is_indexed()) return u.val_vs->get_nof_vs() == 0;
13457 else return u.val_vs->get_nof_ivs() == 0;
13458 case V_SEQ:
13459 case V_SET: {
13460 // only a value for an empty record/set type can be represented as an
13461 // in-line expression
13462 if (!my_governor) FATAL_ERROR("Value::has_single_expr()");
13463 Type *type = my_governor->get_type_refd_last();
13464 return type->get_nof_comps() == 0; }
13465 case V_REFD: {
13466 Value *v_last = get_value_refd_last();
13467 // If the above call hit an error and set_valuetype(V_ERROR),
13468 // then u.ref.ref has been freed. Avoid the segfault.
13469 if (valuetype == V_ERROR)
13470 return false;
13471 if (v_last != this && v_last->has_single_expr() &&
13472 v_last->my_scope->get_scope_mod_gen() ==
13473 my_scope->get_scope_mod_gen()) return true;
13474 else return u.ref.ref->has_single_expr(); }
13475 case V_INVOKE:
13476 return has_single_expr_invoke(u.invoke.v, u.invoke.ap_list);
13477 case V_ERROR:
13478 case V_NAMEDINT:
13479 case V_NAMEDBITS:
13480 case V_UNDEF_LOWERID:
13481 case V_UNDEF_BLOCK:
13482 case V_REFER:
13483 // these values cannot occur during code generation
13484 FATAL_ERROR("Value::has_single_expr()");
13485 case V_INT:
13486 return u.val_Int->is_native_fit();
feade998 13487 case V_NOTUSED:
13488 // should only happen when generating code for an unbound record/set value
13489 return false;
970ed795
EL
13490 default:
13491 // other value types (literal values) do not need temporary reference
13492 return true;
13493 }
13494 }
13495
13496 string Value::get_single_expr()
13497 {
13498 switch (valuetype) {
13499 case V_NULL:
13500 return string("ASN_NULL_VALUE");
13501 case V_BOOL:
13502 return string(u.val_bool ? "TRUE" : "FALSE");
13503 case V_INT:
13504 if (u.val_Int->is_native_fit()) { // Be sure.
13505 return u.val_Int->t_str();
13506 } else {
13507 // get_single_expr may be called only if has_single_expr() is true.
13508 // The only exception is V_INT, where get_single_expr may be called
13509 // even if is_native_fit (which is used to implement has_single_expr)
13510 // returns false.
13511 string ret_val('"');
13512 ret_val += u.val_Int->t_str();
13513 ret_val += '"';
13514 return ret_val;
13515 }
13516 case V_REAL:
13517 return Real2code(u.val_Real);
13518 case V_ENUM:
13519 return get_single_expr_enum();
13520 case V_BSTR:
13521 return get_my_scope()->get_scope_mod_gen()
13522 ->add_bitstring_literal(*u.str.val_str);
13523 case V_HSTR:
13524 return get_my_scope()->get_scope_mod_gen()
13525 ->add_hexstring_literal(*u.str.val_str);
13526 case V_OSTR:
13527 return get_my_scope()->get_scope_mod_gen()
13528 ->add_octetstring_literal(*u.str.val_str);
13529 case V_CSTR:
13530 return get_my_scope()->get_scope_mod_gen()
13531 ->add_charstring_literal(*u.str.val_str);
13532 case V_USTR:
13533 if (u.ustr.convert_str) {
13534 set_valuetype(V_CSTR);
13535 return get_my_scope()->get_scope_mod_gen()
13536 ->add_charstring_literal(*u.str.val_str);
13537 } else
13538 return get_my_scope()->get_scope_mod_gen()
13539 ->add_ustring_literal(*u.ustr.val_ustr);
13540 case V_ISO2022STR:
13541 return get_single_expr_iso2022str();
13542 case V_OID:
13543 case V_ROID: {
13544 vector<string> comps;
13545 bool is_constant = get_oid_comps(comps);
13546 size_t nof_comps = comps.size();
13547 string oi_str;
13548 for (size_t i = 0; i < nof_comps; i++) {
13549 if (i > 0) oi_str += ", ";
13550 oi_str += *(comps[i]);
13551 }
13552 for (size_t i = 0; i < nof_comps; i++) delete comps[i];
13553 comps.clear();
13554 if (is_constant) {
13555 // the objid only contains constants
13556 // => create a literal and return its name
13557 return get_my_scope()->get_scope_mod_gen()->add_objid_literal(oi_str, nof_comps);
13558 }
13559 // the objid contains at least one variable
13560 // => append the number of components before the component values in the string and return it
13561 return "OBJID(" + Int2string(nof_comps) + ", " + oi_str + ")"; }
13562 case V_SEQOF:
13563 case V_SETOF:
13564 if (u.val_vs->get_nof_vs() > 0)
13565 FATAL_ERROR("Value::get_single_expr()");
13566 return string("NULL_VALUE");
13567 case V_SEQ:
13568 case V_SET:
13569 if (u.val_nvs->get_nof_nvs() > 0)
13570 FATAL_ERROR("Value::get_single_expr()");
13571 return string("NULL_VALUE");
13572 case V_REFD: {
13573 Value *v_last = get_value_refd_last();
13574 if (v_last != this && v_last->has_single_expr() &&
13575 v_last->my_scope->get_scope_mod_gen() ==
13576 my_scope->get_scope_mod_gen()) {
13577 // the reference points to another single value in the same module
13578 return v_last->get_single_expr();
13579 } else {
13580 // convert the reference to a single expression
13581 expression_struct expr;
13582 Code::init_expr(&expr);
13583 u.ref.ref->generate_code_const_ref(&expr);
13584 if (expr.preamble || expr.postamble)
13585 FATAL_ERROR("Value::get_single_expr()");
13586 string ret_val(expr.expr);
13587 Code::free_expr(&expr);
13588 return ret_val;
13589 } }
13590 case V_OMIT:
13591 return string("OMIT_VALUE");
13592 case V_VERDICT:
13593 switch (u.verdict) {
13594 case Verdict_NONE:
13595 return string("NONE");
13596 case Verdict_PASS:
13597 return string("PASS");
13598 case Verdict_INCONC:
13599 return string("INCONC");
13600 case Verdict_FAIL:
13601 return string("FAIL");
13602 case Verdict_ERROR:
13603 return string("ERROR");
13604 default:
13605 FATAL_ERROR("Value::get_single_expr()");
13606 return string();
13607 }
13608 case V_DEFAULT_NULL:
13609 return string("NULL_COMPREF");
13610 case V_FAT_NULL: {
13611 string ret_val('(');
13612 ret_val += my_governor->get_genname_value(my_scope);
13613 ret_val += "::function_pointer)Module_List::get_fat_null()";
13614 return ret_val; }
13615 case V_EXPR:
13616 case V_INVOKE: {
13617 expression_struct expr;
13618 Code::init_expr(&expr);
13619 if (valuetype == V_EXPR) generate_code_expr_expr(&expr);
13620 else generate_code_expr_invoke(&expr);
13621 if (expr.preamble || expr.postamble)
13622 FATAL_ERROR("Value::get_single_expr()");
13623 string ret_val(expr.expr);
13624 Code::free_expr(&expr);
13625 return ret_val; }
13626 case V_MACRO:
13627 switch (u.macro) {
13628 case MACRO_TESTCASEID:
13629 return string("TTCN_Runtime::get_testcase_id_macro()");
13630 default:
13631 FATAL_ERROR("Value::get_single_expr(): invalid macrotype");
13632 return string();
13633 }
13634 case V_FUNCTION:
13635 case V_ALTSTEP:
13636 case V_TESTCASE:
13637 return get_single_expr_fat();
13638 default:
13639 FATAL_ERROR("Value::get_single_expr()");
13640 return string();
13641 }
13642 }
13643
13644 bool Value::has_single_expr_expr()
13645 {
13646 switch (u.expr.v_optype) {
13647 case OPTYPE_RND: // -
13648 case OPTYPE_COMP_NULL:
13649 case OPTYPE_COMP_MTC:
13650 case OPTYPE_COMP_SYSTEM:
13651 case OPTYPE_COMP_SELF:
13652 case OPTYPE_COMP_RUNNING_ANY:
13653 case OPTYPE_COMP_RUNNING_ALL:
13654 case OPTYPE_COMP_ALIVE_ANY:
13655 case OPTYPE_COMP_ALIVE_ALL:
13656 case OPTYPE_TMR_RUNNING_ANY:
13657 case OPTYPE_GETVERDICT:
13658 case OPTYPE_TESTCASENAME:
a38c6d4c 13659 case OPTYPE_PROF_RUNNING:
0a1610f4 13660 case OPTYPE_CHECKSTATE_ANY:
13661 case OPTYPE_CHECKSTATE_ALL:
efbe586d 13662 case OPTYPE_HOSTID:
970ed795
EL
13663 return true;
13664 case OPTYPE_ENCODE:
13665 case OPTYPE_DECODE:
13666 case OPTYPE_ISBOUND:
13667 case OPTYPE_ISPRESENT:
13668 case OPTYPE_TTCN2STRING:
1d0599f0 13669 case OPTYPE_ENCVALUE_UNICHAR:
13670 case OPTYPE_DECVALUE_UNICHAR:
970ed795
EL
13671 return false;
13672 case OPTYPE_UNARYPLUS: // v1
13673 case OPTYPE_UNARYMINUS:
13674 case OPTYPE_NOT:
13675 case OPTYPE_NOT4B:
13676 case OPTYPE_BIT2HEX:
13677 case OPTYPE_BIT2INT:
13678 case OPTYPE_BIT2OCT:
13679 case OPTYPE_BIT2STR:
13680 case OPTYPE_CHAR2INT:
13681 case OPTYPE_CHAR2OCT:
13682 case OPTYPE_FLOAT2INT:
13683 case OPTYPE_FLOAT2STR:
13684 case OPTYPE_HEX2BIT:
13685 case OPTYPE_HEX2INT:
13686 case OPTYPE_HEX2OCT:
13687 case OPTYPE_HEX2STR:
13688 case OPTYPE_INT2CHAR:
13689 case OPTYPE_INT2FLOAT:
13690 case OPTYPE_INT2STR:
13691 case OPTYPE_INT2UNICHAR:
13692 case OPTYPE_OCT2BIT:
13693 case OPTYPE_OCT2CHAR:
13694 case OPTYPE_OCT2HEX:
13695 case OPTYPE_OCT2INT:
13696 case OPTYPE_OCT2STR:
13697 case OPTYPE_STR2BIT:
13698 case OPTYPE_STR2FLOAT:
13699 case OPTYPE_STR2HEX:
13700 case OPTYPE_STR2INT:
13701 case OPTYPE_STR2OCT:
13702 case OPTYPE_UNICHAR2INT:
13703 case OPTYPE_UNICHAR2CHAR:
13704 case OPTYPE_ENUM2INT:
13705 case OPTYPE_RNDWITHVAL:
13706 case OPTYPE_ISCHOSEN_V: // v1 i2
13707 case OPTYPE_COMP_RUNNING:
13708 case OPTYPE_COMP_ALIVE:
13709 case OPTYPE_GET_STRINGENCODING:
13710 case OPTYPE_REMOVE_BOM:
13711 case OPTYPE_DECODE_BASE64:
13712 return u.expr.v1->has_single_expr();
13713 case OPTYPE_ISCHOSEN_T: // t1 i2
13714 return u.expr.t1->has_single_expr();
13715 case OPTYPE_ADD: // v1 v2
13716 case OPTYPE_SUBTRACT:
13717 case OPTYPE_MULTIPLY:
13718 case OPTYPE_DIVIDE:
13719 case OPTYPE_MOD:
13720 case OPTYPE_REM:
13721 case OPTYPE_CONCAT:
13722 case OPTYPE_EQ:
13723 case OPTYPE_LT:
13724 case OPTYPE_GT:
13725 case OPTYPE_NE:
13726 case OPTYPE_GE:
13727 case OPTYPE_LE:
13728 case OPTYPE_XOR:
13729 case OPTYPE_AND4B:
13730 case OPTYPE_OR4B:
13731 case OPTYPE_XOR4B:
13732 case OPTYPE_SHL:
13733 case OPTYPE_SHR:
13734 case OPTYPE_ROTL:
13735 case OPTYPE_ROTR:
13736 case OPTYPE_INT2BIT:
13737 case OPTYPE_INT2HEX:
13738 case OPTYPE_INT2OCT:
13739 return u.expr.v1->has_single_expr() &&
13740 u.expr.v2->has_single_expr();
13741 case OPTYPE_UNICHAR2OCT:
13742 case OPTYPE_OCT2UNICHAR:
13743 case OPTYPE_ENCODE_BASE64:
13744 return u.expr.v1->has_single_expr() &&
13745 (!u.expr.v2 || u.expr.v2->has_single_expr());
13746 case OPTYPE_AND:
13747 case OPTYPE_OR:
13748 return u.expr.v1->has_single_expr() &&
13749 u.expr.v2->has_single_expr() &&
13750 !u.expr.v2->needs_short_circuit();
13751 case OPTYPE_SUBSTR:
13752 return u.expr.ti1->has_single_expr() &&
13753 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr();
13754 case OPTYPE_REGEXP:
13755 return u.expr.ti1->has_single_expr() && u.expr.t2->has_single_expr() &&
13756 u.expr.v3->has_single_expr();
13757 case OPTYPE_DECOMP: // v1 v2 v3
13758 return u.expr.v1->has_single_expr() &&
13759 u.expr.v2->has_single_expr() &&
13760 u.expr.v3->has_single_expr();
13761 case OPTYPE_REPLACE:
13762 return u.expr.ti1->has_single_expr() &&
13763 u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
13764 u.expr.ti4->has_single_expr();
13765 case OPTYPE_ISVALUE: // ti1
13766 case OPTYPE_LENGTHOF: // ti1
13767 case OPTYPE_SIZEOF: // ti1
13768 case OPTYPE_VALUEOF: // ti1
13769 return u.expr.ti1->has_single_expr();
13770 case OPTYPE_LOG2STR:
a50716c1 13771 case OPTYPE_ANY2UNISTR:
970ed795
EL
13772 return u.expr.logargs->has_single_expr();
13773 case OPTYPE_MATCH: // v1 t2
13774 return u.expr.v1->has_single_expr() &&
13775 u.expr.t2->has_single_expr();
13776 case OPTYPE_COMP_CREATE: // r1 [v2] [v3] b4
13777 return (!u.expr.v2 || u.expr.v2->has_single_expr()) &&
13778 (!u.expr.v3 || u.expr.v3->has_single_expr());
13779 case OPTYPE_TMR_READ: // r1
13780 case OPTYPE_TMR_RUNNING:
13781 case OPTYPE_ACTIVATE:
13782 return u.expr.r1->has_single_expr();
13783 case OPTYPE_EXECUTE: // r1 [v2]
13784 return u.expr.r1->has_single_expr() &&
13785 (!u.expr.v2 || u.expr.v2->has_single_expr());
13786 case OPTYPE_ACTIVATE_REFD: // v1 ap_list2
13787 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2);
13788 case OPTYPE_EXECUTE_REFD: // v1 ap_list2 [v3]
13789 return has_single_expr_invoke(u.expr.v1, u.expr.ap_list2) &&
13790 (!u.expr.v3 || u.expr.v3->has_single_expr());
13791 default:
13792 FATAL_ERROR("Value::has_single_expr_expr()");
13793 } // switch
13794 }
13795
13796 bool Value::has_single_expr_invoke(Value *v, Ttcn::ActualParList *ap_list)
13797 {
13798 if (!v->has_single_expr()) return false;
13799 for (size_t i = 0; i < ap_list->get_nof_pars(); i++)
13800 if (!ap_list->get_par(i)->has_single_expr()) return false;
13801 return true;
13802 }
13803
13804 string Value::get_single_expr_enum()
13805 {
13806 string ret_val(my_governor->get_genname_value(my_scope));
13807 ret_val += "::";
13808 ret_val += u.val_id->get_name();
13809 return ret_val;
13810 }
13811
13812 string Value::get_single_expr_iso2022str()
13813 {
13814 string ret_val;
13815 Type *type = get_my_governor()->get_type_refd_last();
13816 switch (type->get_typetype()) {
13817 case Type::T_TELETEXSTRING:
13818 ret_val += "TTCN_ISO2022_2_TeletexString";
13819 break;
13820 case Type::T_VIDEOTEXSTRING:
13821 ret_val += "TTCN_ISO2022_2_VideotexString";
13822 break;
13823 case Type::T_GRAPHICSTRING:
13824 case Type::T_OBJECTDESCRIPTOR:
13825 ret_val += "TTCN_ISO2022_2_GraphicString";
13826 break;
13827 case Type::T_GENERALSTRING:
13828 ret_val += "TTCN_ISO2022_2_GeneralString";
13829 break;
13830 default:
13831 FATAL_ERROR("Value::get_single_expr_iso2022str()");
13832 } // switch
13833 ret_val += '(';
13834 string *ostr = char2oct(*u.str.val_str);
13835 ret_val += get_my_scope()->get_scope_mod_gen()
13836 ->add_octetstring_literal(*ostr);
13837 delete ostr;
13838 ret_val += ')';
13839 return ret_val;
13840 }
13841
13842 string Value::get_single_expr_fat()
13843 {
13844 if (!my_governor) FATAL_ERROR("Value::get_single_expr_fat()");
13845 // the ampersand operator is not really necessary to obtain the function
13846 // pointer, but some older versions of GCC cannot instantiate the
13847 // appropriate operator=() member of class OPTIONAL when necessary
13848 // if only the function name is given
13849 string ret_val('&');
13850 switch (valuetype) {
13851 case V_FUNCTION:
13852 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13853 break;
13854 case V_ALTSTEP:
13855 ret_val += u.refd_fat->get_genname_from_scope(my_scope);
13856 ret_val += "_instance";
13857 break;
13858 case V_TESTCASE:
13859 ret_val += u.refd_fat->get_genname_from_scope(my_scope, "testcase_");
13860 break;
13861 default:
13862 FATAL_ERROR("Value::get_single_expr_fat()");
13863 }
13864 return ret_val;
13865 }
13866
13867 bool Value::is_compound()
13868 {
13869 switch (valuetype) {
13870 case V_CHOICE:
13871 case V_SEQOF:
13872 case V_SETOF:
13873 case V_ARRAY:
13874 case V_SEQ:
13875 case V_SET:
13876 return true;
13877 default:
13878 return false;
13879 }
13880 }
13881
13882 bool Value::needs_temp_ref()
13883 {
13884 switch (valuetype) {
13885 case V_SEQOF:
13886 case V_SETOF:
13887 if (!is_indexed()) {
13888 // Temporary reference is needed if the value has at least one real
13889 // element (i.e. it is not empty or contains only not used symbols).
13890 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13891 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) return true;
13892 }
13893 } else {
13894 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13895 if (u.val_vs->get_iv_byIndex(i)->get_value()
13896 ->valuetype != V_NOTUSED)
13897 return true;
13898 }
13899 }
13900 return false;
13901 case V_ARRAY: {
13902 size_t nof_real_vs = 0;
13903 if (!is_indexed()) {
13904 // Temporary reference is needed if the array value has at least two
13905 // real elements (excluding not used symbols).
13906 for (size_t i = 0; i < u.val_vs->get_nof_vs(); i++) {
13907 if (u.val_vs->get_v_byIndex(i)->valuetype != V_NOTUSED) {
13908 nof_real_vs++;
13909 if (nof_real_vs > 1) return true;
13910 }
13911 }
13912 } else {
13913 for (size_t i = 0; i < u.val_vs->get_nof_ivs(); i++) {
13914 if (u.val_vs->get_iv_byIndex(i)->get_value()
13915 ->valuetype != V_NOTUSED) {
13916 nof_real_vs++;
13917 if (nof_real_vs > 1) return true;
13918 }
13919 }
13920 }
13921 return false; }
13922 case V_SEQ:
13923 case V_SET:
13924 if (is_asn1()) {
13925 // it depends on the type since fields with omit or default value
13926 // may not be present
13927 return my_governor->get_type_refd_last()->get_nof_comps() > 1;
13928 } else {
13929 // incomplete values are allowed in TTCN-3
13930 // we should check the number of value components
13931 return u.val_nvs->get_nof_nvs() > 1;
13932 }
13933 case V_ERROR:
13934 case V_NAMEDINT:
13935 case V_NAMEDBITS:
13936 case V_UNDEF_LOWERID:
13937 case V_UNDEF_BLOCK:
13938 case V_TTCN3_NULL:
13939 // these values cannot occur during code generation
13940 FATAL_ERROR("Value::needs_temp_ref()");
13941 case V_INT:
13942 return !u.val_Int->is_native();
13943 default:
13944 // other value types (literal values) do not need temporary reference
13945 return false;
13946 }
13947 }
13948
13949 bool Value::needs_short_circuit()
13950 {
13951 switch (valuetype) {
13952 case V_BOOL:
13953 return false;
13954 case V_REFD:
13955 // examined below
13956 break;
13957 case V_EXPR:
13958 case V_INVOKE:
13959 // sub-expressions should be evaluated only if necessary
13960 return true;
13961 default:
13962 FATAL_ERROR("Value::needs_short_circuit()");
13963 }
13964 Assignment *t_ass = u.ref.ref->get_refd_assignment();
13965 if (!t_ass) FATAL_ERROR("Value::needs_short_circuit()");
13966 switch (t_ass->get_asstype()) {
13967 case Assignment::A_FUNCTION_RVAL:
13968 case Assignment::A_EXT_FUNCTION_RVAL:
13969 // avoid unnecessary call of a function
13970 return true;
13971 case Assignment::A_CONST:
13972 case Assignment::A_EXT_CONST:
13973 case Assignment::A_MODULEPAR:
13974 case Assignment::A_VAR:
13975 case Assignment::A_PAR_VAL_IN:
13976 case Assignment::A_PAR_VAL_OUT:
13977 case Assignment::A_PAR_VAL_INOUT:
13978 // depends on field/array sub-references, which is examined below
13979 break;
13980 default:
13981 FATAL_ERROR("Value::needs_short_circuit()");
13982 }
13983 Ttcn::FieldOrArrayRefs *t_subrefs = u.ref.ref->get_subrefs();
13984 if (t_subrefs) {
13985 // the evaluation of the reference does not have side effects
13986 // (i.e. false shall be returned) only if all sub-references point to
a38c6d4c 13987 // mandatory fields of record/set types, and neither sub-reference points
13988 // to a field of a union type
970ed795
EL
13989 Type *t_type = t_ass->get_Type();
13990 for (size_t i = 0; i < t_subrefs->get_nof_refs(); i++) {
13991 Ttcn::FieldOrArrayRef *t_fieldref = t_subrefs->get_ref(i);
13992 if (t_fieldref->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF) {
13993 CompField *t_cf = t_type->get_comp_byName(*t_fieldref->get_id());
a38c6d4c 13994 if (Type::T_CHOICE_T == t_type->get_type_refd_last()->get_typetype() ||
13995 Type::T_CHOICE_A == t_type->get_type_refd_last()->get_typetype() ||
13996 t_cf->get_is_optional()) return true;
970ed795
EL
13997 t_type = t_cf->get_type();
13998 } else return true;
13999 }
14000 }
14001 return false;
14002 }
14003
14004 void Value::dump(unsigned level) const
14005 {
14006 switch (valuetype) {
14007 case V_ERROR:
14008 case V_NULL:
14009 case V_BOOL:
14010 case V_INT:
14011 case V_NAMEDINT:
14012 case V_NAMEDBITS:
14013 case V_REAL:
14014 case V_ENUM:
14015 case V_BSTR:
14016 case V_HSTR:
14017 case V_OSTR:
14018 case V_CSTR:
14019 case V_ISO2022STR:
14020 case V_OID:
14021 case V_ROID:
14022 case V_CHOICE:
14023 case V_SEQOF:
14024 case V_SETOF:
14025 case V_ARRAY:
14026 case V_SEQ:
14027 case V_SET:
14028 case V_OMIT:
14029 case V_VERDICT:
14030 case V_DEFAULT_NULL:
14031 case V_FAT_NULL:
14032 case V_EXPR:
14033 case V_MACRO:
14034 case V_NOTUSED:
14035 case V_FUNCTION:
14036 case V_ALTSTEP:
14037 case V_TESTCASE:
14038 DEBUG(level, "Value: %s", const_cast<Value*>(this)->get_stringRepr().c_str());
14039 break;
14040 case V_REFD:
14041 case V_REFER:
14042 DEBUG(level, "Value: reference");
14043 u.ref.ref->dump(level + 1);
14044 break;
14045 case V_UNDEF_LOWERID:
14046 DEBUG(level, "Value: identifier: %s", u.val_id->get_dispname().c_str());
14047 break;
14048 case V_UNDEF_BLOCK:
14049 DEBUG(level, "Value: {block}");
14050 break;
14051 case V_TTCN3_NULL:
14052 DEBUG(level, "Value: null");
14053 break;
14054 case V_INVOKE:
14055 DEBUG(level, "Value: invoke");
14056 u.invoke.v->dump(level + 1);
14057 if (u.invoke.ap_list) u.invoke.ap_list->dump(level + 1);
14058 else if (u.invoke.t_list) u.invoke.t_list->dump(level + 1);
14059 break;
14060 default:
14061 DEBUG(level, "Value: unknown type: %d", valuetype);
14062 } // switch
14063 }
14064
14065 void Value::add_string_element(size_t index, Value *v_element,
14066 map<size_t, Value>*& string_elements)
14067 {
14068 v_element->set_my_scope(get_my_scope());
14069 v_element->set_my_governor(get_my_governor());
14070 v_element->set_fullname(get_fullname() + "[" + Int2string(index) + "]");
14071 v_element->set_location(*this);
14072 if (!string_elements) string_elements = new map<size_t, Value>;
14073 string_elements->add(index, v_element);
14074 }
14075
14076///////////////////////////////////////////////////////////////////////////////
14077// class LazyParamData
14078
14079 int LazyParamData::depth = 0;
14080 bool LazyParamData::used_as_lvalue = false;
14081 vector<string>* LazyParamData::type_vec = NULL;
14082 vector<string>* LazyParamData::refd_vec = NULL;
14083
14084 void LazyParamData::init(bool p_used_as_lvalue) {
14085 if (depth<0) FATAL_ERROR("LazyParamData::init()");
14086 if (depth==0) {
14087 if (type_vec || refd_vec) FATAL_ERROR("LazyParamData::init()");
14088 used_as_lvalue = p_used_as_lvalue;
14089 type_vec = new vector<string>;
14090 refd_vec = new vector<string>;
14091 }
14092 depth++;
14093 }
14094
14095 void LazyParamData::clean() {
14096 if (depth<=0) FATAL_ERROR("LazyParamData::clean()");
14097 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::clean()");
14098 if (depth==1) {
14099 // type_vec
14100 for (size_t i=0; i<type_vec->size(); i++) delete (*type_vec)[i];
14101 type_vec->clear();
14102 delete type_vec;
14103 type_vec = NULL;
14104 // refd_vec
14105 for (size_t i=0; i<refd_vec->size(); i++) delete (*refd_vec)[i];
14106 refd_vec->clear();
14107 delete refd_vec;
14108 refd_vec = NULL;
14109 }
14110 depth--;
14111 }
14112
14113 bool LazyParamData::in_lazy() {
14114 if (depth<0) FATAL_ERROR("LazyParamData::in_lazy()");
14115 return depth>0;
14116 }
14117
14118 // returns a temporary id instead of the C++ reference to a definition
14119 // stores in vectors the C++ type of the definiton, the C++ reference to the definition and if it refers to a lazy formal parameter
14120 string LazyParamData::add_ref_genname(Assignment* ass, Scope* scope) {
14121 if (!ass || !scope) FATAL_ERROR("LazyParamData::add_ref_genname()");
14122 if (!type_vec || !refd_vec) FATAL_ERROR("LazyParamData::add_ref_genname()");
14123 if (type_vec->size()!=refd_vec->size()) FATAL_ERROR("LazyParamData::add_ref_genname()");
14124 // store the type of the assignment
14125 string* type_str = new string;
14126 switch (ass->get_asstype()) {
14127 case Assignment::A_MODULEPAR_TEMP:
14128 case Assignment::A_TEMPLATE:
14129 case Assignment::A_VAR_TEMPLATE:
14130 case Assignment::A_PAR_TEMPL_IN:
14131 case Assignment::A_PAR_TEMPL_OUT:
14132 case Assignment::A_PAR_TEMPL_INOUT:
14133 *type_str = ass->get_Type()->get_genname_template(scope);
14134 break;
14135 default:
14136 *type_str = ass->get_Type()->get_genname_value(scope);
14137 }
14138 // add the Lazy_Param<> part if the referenced assignment is a FormalPar with lazy_eval == true
14139 bool refd_ass_is_lazy_fpar = false;
14140 switch (ass->get_asstype()) {
14141 case Assignment::A_PAR_VAL:
14142 case Assignment::A_PAR_VAL_IN:
14143 case Assignment::A_PAR_TEMPL_IN:
14144 refd_ass_is_lazy_fpar = ass->get_lazy_eval();
14145 if (refd_ass_is_lazy_fpar) {
14146 *type_str = string("Lazy_Param<") + *type_str + string(">");
14147 }
14148 break;
14149 default:
14150 break;
14151 }
14152 // add the "const" part if the referenced assignment is a constant thing
14153 if (!refd_ass_is_lazy_fpar) {
14154 switch (ass->get_asstype()) {
14155 case Assignment::A_CONST:
14156 case Assignment::A_OC:
14157 case Assignment::A_OBJECT:
14158 case Assignment::A_OS:
14159 case Assignment::A_VS:
14160 case Assignment::A_EXT_CONST:
14161 case Assignment::A_MODULEPAR:
14162 case Assignment::A_MODULEPAR_TEMP:
14163 case Assignment::A_TEMPLATE:
14164 case Assignment::A_PAR_VAL:
14165 case Assignment::A_PAR_VAL_IN:
14166 case Assignment::A_PAR_TEMPL_IN:
14167 *type_str = string("const ") + *type_str;
14168 break;
14169 default:
14170 // nothing to do
14171 break;
14172 }
14173 }
14174 //
14175 type_vec->add(type_str);
14176 // store the C++ reference string
14177 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
14178 if (refd_ass_is_lazy_fpar) {
14179 Type* refd_ass_type = ass->get_Type();
14180 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);
14181 return string("((") + refd_ass_type_genname + string("&)") + get_member_name(refd_vec->size()-1) + string(")");
14182 } else {
14183 return get_member_name(refd_vec->size()-1);
14184 }
14185 }
14186
14187 string LazyParamData::get_member_name(size_t idx) {
14188 return string("lpm_") + Int2string(idx);
14189 }
14190
14191 string LazyParamData::get_constr_param_name(size_t idx) {
14192 return string("lpp_") + Int2string(idx);
14193 }
14194
14195 void LazyParamData::generate_code_for_value(expression_struct* expr, Value* val, Scope* my_scope) {
14196 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14197 if (use_runtime_2 && TypeConv::needs_conv_refd(val)) {
14198 const string& tmp_id = val->get_temporary_id();
14199 const char *tmp_id_str = tmp_id.c_str();
14200 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14201 val->get_my_governor()->get_genname_value(my_scope).c_str(),
14202 tmp_id_str);
14203 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14204 tmp_id_str, val);
14205 expr->expr = mputstr(expr->expr, tmp_id_str);
14206 } else {
14207 val->generate_code_expr(expr);
14208 }
14209 }
14210
14211 void LazyParamData::generate_code_for_template(expression_struct* expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* my_scope) {
14212 // copied from ActualPar::generate_code(), TODO: remove duplication by refactoring
14213 if (use_runtime_2 && TypeConv::needs_conv_refd(temp->get_Template())) {
14214 const string& tmp_id = temp->get_Template()->get_temporary_id();
14215 const char *tmp_id_str = tmp_id.c_str();
14216 expr->preamble = mputprintf(expr->preamble, "%s %s;\n",
14217 temp->get_Template()->get_my_governor()
14218 ->get_genname_template(my_scope).c_str(), tmp_id_str);
14219 expr->preamble = TypeConv::gen_conv_code_refd(expr->preamble,
14220 tmp_id_str, temp->get_Template());
14221 // Not incorporated into gen_conv_code() yet.
14222 if (gen_restriction_check != TR_NONE)
14223 expr->preamble = Template::generate_restriction_check_code(
14224 expr->preamble, tmp_id_str, gen_restriction_check);
14225 expr->expr = mputstr(expr->expr, tmp_id_str);
14226 } else temp->generate_code(expr, gen_restriction_check);
14227 }
14228
14229 void LazyParamData::generate_code(expression_struct *expr, Value* value, Scope* scope) {
14230 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14231 if (depth>1) {
14232 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14233 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14234 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14235 expression_struct value_expr;
14236 Code::init_expr(&value_expr);
14237 generate_code_for_value(&value_expr, value, scope);
14238 // the id of the instance of Lazy_Param which will be used as the actual parameter
14239 const string& lazy_param_id = value->get_temporary_id();
14240 if (value_expr.preamble) {
14241 expr->preamble = mputstr(expr->preamble, value_expr.preamble);
14242 }
14243 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14244 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14245 value->get_my_governor()->get_genname_value(scope).c_str(), value_expr.expr);
14246 Code::free_expr(&value_expr);
14247 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14248 return;
14249 }
14250 // only if the formal parameter is *not* used as lvalue
14251 if (!used_as_lvalue && value->get_valuetype()==Value::V_REFD && value->get_reference()->get_subrefs()==NULL) {
14252 Assignment* refd_ass = value->get_reference()->get_refd_assignment();
14253 if (refd_ass) {
14254 bool refd_ass_is_lazy_fpar = false;
14255 switch (refd_ass->get_asstype()) {
14256 case Assignment::A_PAR_VAL:
14257 case Assignment::A_PAR_VAL_IN:
14258 case Assignment::A_PAR_TEMPL_IN:
14259 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14260 break;
14261 default:
14262 break;
14263 }
14264 if (refd_ass_is_lazy_fpar) {
14265 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14266 return;
14267 }
14268 }
14269 }
14270 // generate the code for value in a temporary expr structure, this code is put inside the ::eval() member function
14271 expression_struct value_expr;
14272 Code::init_expr(&value_expr);
14273 generate_code_for_value(&value_expr, value, scope);
14274 // the id of the instance of Lazy_Param which will be used as the actual parameter
14275 string lazy_param_id = value->get_temporary_id();
14276 string type_name = value->get_my_governor()->get_genname_value(scope);
14277 generate_code_lazyparam_class(expr, value_expr, lazy_param_id, type_name);
14278 }
14279
14280 void LazyParamData::generate_code(expression_struct *expr, TemplateInstance* temp, template_restriction_t gen_restriction_check, Scope* scope) {
14281 if (depth<=0) FATAL_ERROR("LazyParamData::generate_code()");
14282 if (depth>1) {
14283 // if a function with lazy parameter(s) was called inside a lazy parameter then don't generate code for
14284 // lazy parameter inside a lazy parameter, call the funcion as a normal call
14285 // wrap the calculated parameter value inside a special constructor which calculates the value of it's cache immediately
14286 expression_struct tmpl_expr;
14287 Code::init_expr(&tmpl_expr);
14288 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14289 // the id of the instance of Lazy_Param which will be used as the actual parameter
14290 const string& lazy_param_id = temp->get_Template()->get_temporary_id();
14291 if (tmpl_expr.preamble) {
14292 expr->preamble = mputstr(expr->preamble, tmpl_expr.preamble);
14293 }
14294 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14295 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14296 temp->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), tmpl_expr.expr);
14297 Code::free_expr(&tmpl_expr);
14298 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14299 return;
14300 }
14301 // only if the formal parameter is *not* used as lvalue
14302 if (!used_as_lvalue && temp->get_Template()->get_templatetype()==Template::TEMPLATE_REFD && temp->get_Template()->get_reference()->get_subrefs()==NULL) {
14303 Assignment* refd_ass = temp->get_Template()->get_reference()->get_refd_assignment();
14304 if (refd_ass) {
14305 bool refd_ass_is_lazy_fpar = false;
14306 switch (refd_ass->get_asstype()) {
14307 case Assignment::A_PAR_VAL:
14308 case Assignment::A_PAR_VAL_IN:
14309 case Assignment::A_PAR_TEMPL_IN:
14310 refd_ass_is_lazy_fpar = refd_ass->get_lazy_eval();
14311 break;
14312 default:
14313 break;
14314 }
14315 if (refd_ass_is_lazy_fpar) {
14316 expr->expr = mputprintf(expr->expr, "%s", refd_ass->get_genname_from_scope(scope,"").c_str());
14317 return;
14318 }
14319 }
14320 }
14321 // generate the code for template in a temporary expr structure, this code is put inside the ::eval_expr() member function
14322 expression_struct tmpl_expr;
14323 Code::init_expr(&tmpl_expr);
14324 generate_code_for_template(&tmpl_expr, temp, gen_restriction_check, scope);
14325 // the id of the instance of Lazy_Param which will be used as the actual parameter
14326 string lazy_param_id = temp->get_Template()->get_temporary_id();
14327 string type_name = temp->get_Template()->get_my_governor()->get_genname_template(scope);
14328 generate_code_lazyparam_class(expr, tmpl_expr, lazy_param_id, type_name);
14329 }
14330
14331 void LazyParamData::generate_code_lazyparam_class(expression_struct *expr, expression_struct& param_expr, const string& lazy_param_id, const string& type_name) {
14332 expr->preamble = mputprintf(expr->preamble, "class Lazy_Param_%s : public Lazy_Param<%s> {\n", lazy_param_id.c_str(), type_name.c_str());
14333 if (type_vec->size()>0) {
14334 // private members of the local class will be const references to the objects referenced by the expression
14335 for (size_t i=0; i<type_vec->size(); i++) {
14336 expr->preamble = mputprintf(expr->preamble, "%s& %s;\n", (*type_vec)[i]->c_str(), get_member_name(i).c_str());
14337 }
14338 expr->preamble = mputstr(expr->preamble, "public:\n");
14339 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s(", lazy_param_id.c_str());
14340 for (size_t i=0; i<type_vec->size(); i++) {
14341 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14342 expr->preamble = mputprintf(expr->preamble, "%s& %s", (*type_vec)[i]->c_str(), get_constr_param_name(i).c_str());
14343 }
14344 expr->preamble = mputstr(expr->preamble, "): ");
14345 for (size_t i=0; i<type_vec->size(); i++) {
14346 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14347 expr->preamble = mputprintf(expr->preamble, "%s(%s)", get_member_name(i).c_str(), get_constr_param_name(i).c_str());
14348 }
14349 expr->preamble = mputstr(expr->preamble, " {}\n");
14350 expr->preamble = mputstr(expr->preamble, "private:\n");
14351 }
14352 expr->preamble = mputstr(expr->preamble, "virtual void eval_expr() {\n");
14353 // use the temporary expr structure to fill the body of the eval_expr() function
14354 if (param_expr.preamble) {
14355 expr->preamble = mputstr(expr->preamble, param_expr.preamble);
14356 }
14357 expr->preamble = mputprintf(expr->preamble, "expr_cache = %s;\n", param_expr.expr);
14358 if (param_expr.postamble) {
14359 expr->preamble = mputstr(expr->preamble, param_expr.postamble);
14360 }
14361 Code::free_expr(&param_expr);
14362 expr->preamble = mputstr(expr->preamble, "}\n"
14363 "};\n" // end of local class definition
14364 );
14365 expr->preamble = mputprintf(expr->preamble, "Lazy_Param_%s %s", lazy_param_id.c_str(), lazy_param_id.c_str());
14366 if (type_vec->size()>0) {
14367 expr->preamble = mputc(expr->preamble, '(');
14368 // paramteres of the constructor are references to the objects used in the expression
14369 for (size_t i=0; i<refd_vec->size(); i++) {
14370 if (i>0) expr->preamble = mputstr(expr->preamble, ", ");
14371 expr->preamble = mputprintf(expr->preamble, "%s", (*refd_vec)[i]->c_str());
14372 }
14373 expr->preamble = mputc(expr->preamble, ')');
14374 }
14375 expr->preamble = mputstr(expr->preamble, ";\n");
14376 // the instance of the local class Lazy_Param_tmp_xxx is used as the actual parameter
14377 expr->expr = mputprintf(expr->expr, "%s", lazy_param_id.c_str());
14378 }
14379
14380 void LazyParamData::generate_code_ap_default_ref(expression_struct *expr, Ttcn::Ref_base* ref, Scope* scope) {
14381 expression_struct ref_expr;
14382 Code::init_expr(&ref_expr);
14383 ref->generate_code(&ref_expr);
14384 const string& lazy_param_id = scope->get_scope_mod_gen()->get_temporary_id();
14385 if (ref_expr.preamble) {
14386 expr->preamble = mputstr(expr->preamble, ref_expr.preamble);
14387 }
14388 Assignment* ass = ref->get_refd_assignment();
14389 // determine C++ type of the assignment
14390 string type_str;
14391 switch (ass->get_asstype()) {
14392 case Assignment::A_MODULEPAR_TEMP:
14393 case Assignment::A_TEMPLATE:
14394 case Assignment::A_VAR_TEMPLATE:
14395 case Assignment::A_PAR_TEMPL_IN:
14396 case Assignment::A_PAR_TEMPL_OUT:
14397 case Assignment::A_PAR_TEMPL_INOUT:
14398 type_str = ass->get_Type()->get_genname_template(scope);
14399 break;
14400 default:
14401 type_str = ass->get_Type()->get_genname_value(scope);
14402 }
14403 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14404 type_str.c_str(), lazy_param_id.c_str(), type_str.c_str(), ref_expr.expr);
14405 if (ref_expr.postamble) {
14406 expr->postamble = mputstr(expr->postamble, ref_expr.postamble);
14407 }
14408 Code::free_expr(&ref_expr);
14409 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14410 }
14411
14412 void LazyParamData::generate_code_ap_default_value(expression_struct *expr, Value* value, Scope* scope) {
14413 const string& lazy_param_id = value->get_temporary_id();
14414 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14415 value->get_my_governor()->get_genname_value(scope).c_str(), lazy_param_id.c_str(),
14416 value->get_my_governor()->get_genname_value(scope).c_str(), value->get_genname_own(scope).c_str());
14417 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14418 }
14419
14420 void LazyParamData::generate_code_ap_default_ti(expression_struct *expr, TemplateInstance* ti, Scope* scope) {
14421 const string& lazy_param_id = ti->get_Template()->get_temporary_id();
14422 expr->preamble = mputprintf(expr->preamble, "Lazy_Param<%s> %s(Lazy_Param<%s>::EXPR_EVALED, %s);\n",
14423 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), lazy_param_id.c_str(),
14424 ti->get_Template()->get_my_governor()->get_genname_template(scope).c_str(), ti->get_Template()->get_genname_own(scope).c_str());
14425 expr->expr = mputstr(expr->expr, lazy_param_id.c_str());
14426 }
14427
14428} // namespace Common
This page took 0.570034 seconds and 5 git commands to generate.