Last sync 2016.04.01
[deliverable/titan.core.git] / compiler2 / ttcn3 / signature.c
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 * Feher, Csaba
13 * Kovacs, Ferenc
14 * Raduly, Csaba
15 * Szabo, Janos Zoltan – initial implementation
16 * Szalai, Gabor
17 * Tatarka, Gabor
18 *
19 ******************************************************************************/
970ed795
EL
20#include "../../common/memory.h"
21#include "signature.h"
22#include "../datatypes.h"
23#include "../main.hh"
24#include "compiler.h"
25
26void defSignatureClasses(const signature_def *sdef, output_struct *output)
27{
28 char *decl = NULL, *def = NULL, *src = NULL;
29 const char *name = sdef->name, *dispname = sdef->dispname;
30 size_t i, num_in = 0, num_out = 0;
31
32 for (i = 0; i < sdef->parameters.nElements; i++) {
33 if (sdef->parameters.elements[i].direction != PAR_OUT) num_in++;
34 if (sdef->parameters.elements[i].direction != PAR_IN) num_out++;
35 }
36
37 /*
38 *
39 * xxx_call class
40 *
41 */
42
43 decl = mputprintf(decl, "class %s_call;\n", name);
44
45 /* class definition */
46 def = mputprintf(def, "class %s_call {\n", name);
47
48 /* signature's in and inout parameters */
49 for (i = 0; i < sdef->parameters.nElements; i++) {
50 if (sdef->parameters.elements[i].direction != PAR_OUT)
51 def = mputprintf(def, "%s param_%s;\n",
52 sdef->parameters.elements[i].type,
53 sdef->parameters.elements[i].name);
54 }
55
56 def = mputstr(def, "public:\n");
57
58 /* parameters' access functions */
59 for (i = 0; i < sdef->parameters.nElements; i++) {
60 if (sdef->parameters.elements[i].direction != PAR_OUT) {
61 def = mputprintf(def, "inline %s& %s() { return param_%s; }\n"
62 "inline const %s& %s() const { return param_%s; }\n",
63 sdef->parameters.elements[i].type,
64 sdef->parameters.elements[i].name,
65 sdef->parameters.elements[i].name,
66 sdef->parameters.elements[i].type,
67 sdef->parameters.elements[i].name,
68 sdef->parameters.elements[i].name);
69 }
70 }
71
72 if (num_in > 0) {
73 /* encode_text function */
74 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
75 src = mputprintf(src, "void %s_call::encode_text(Text_Buf& text_buf) "
76 "const\n"
77 "{\n", name);
78 for(i = 0; i < sdef->parameters.nElements; i++) {
79 if(sdef->parameters.elements[i].direction != PAR_OUT)
80 src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
81 sdef->parameters.elements[i].name);
82 }
83 src = mputstr(src, "}\n\n");
84 /* decode_text function */
85 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
86 src = mputprintf(src, "void %s_call::decode_text(Text_Buf& text_buf)\n"
87 "{\n", name);
88 for (i = 0; i < sdef->parameters.nElements; i++) {
89 if (sdef->parameters.elements[i].direction!= PAR_OUT)
90 src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
91 sdef->parameters.elements[i].name);
92 }
93 src = mputstr(src, "}\n\n");
94 } else {
95 def = mputstr(def, "inline void encode_text(Text_Buf&) const "
96 "{ }\n"
97 "inline void decode_text(Text_Buf&) { }\n");
98 }
99
100 /* log function */
101 def = mputstr(def, "void log() const;\n");
102 src = mputprintf(src, "void %s_call::log() const\n"
103 "{\n", name);
104 if (num_in > 0) {
105 boolean first_param = TRUE;
106 src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { \");\n",
107 dispname);
108 for (i = 0; i < sdef->parameters.nElements; i++) {
109 if (sdef->parameters.elements[i].direction != PAR_OUT) {
110 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
111 if (first_param) first_param = FALSE;
112 else src = mputstr(src, ", ");
113 src = mputprintf(src, "%s := \");\n"
114 "param_%s.log();\n",
115 sdef->parameters.elements[i].dispname,
116 sdef->parameters.elements[i].name);
117 }
118 }
119 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
120 } else {
121 src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { }\");\n",
122 dispname);
123 }
124 src = mputstr(src, "}\n\n");
125
126 def = mputstr(def, "};\n\n");
127 /* end of xxx_call class*/
128
129 /*
130 *
131 * xxx_call_redirect class (for getcall port-operation)
132 *
133 */
134 decl = mputprintf(decl, "class %s_call_redirect;\n", name);
135
136 /* class definition */
137 def = mputprintf(def, "class %s_call_redirect {\n", name);
138
139 /* parameter pointers */
140 for (i = 0; i < sdef->parameters.nElements; i++) {
141 if (sdef->parameters.elements[i].direction != PAR_OUT) {
142 def = mputprintf(def, "%s *ptr_%s;\n",
143 sdef->parameters.elements[i].type,
144 sdef->parameters.elements[i].name);
145 }
146 }
147
148 def = mputstr(def, "public:\n");
149
150 if (num_in > 0) {
151 /* constructor */
152 boolean first_param = TRUE;
153 def = mputprintf(def, "%s_call_redirect(", name);
154 for (i = 0;i<sdef->parameters.nElements;i++) {
155 if (sdef->parameters.elements[i].direction != PAR_OUT) {
156 if (first_param) first_param = FALSE;
157 else def = mputstr(def, ", ");
158 def = mputprintf(def, "%s *par_%s = NULL",
159 sdef->parameters.elements[i].type,
160 sdef->parameters.elements[i].name);
161 }
162 }
163 def = mputstr(def, ")\n"
164 " : ");
165 first_param = TRUE;
166 for (i = 0; i < sdef->parameters.nElements; i++) {
167 if (sdef->parameters.elements[i].direction != PAR_OUT) {
168 if (first_param) first_param = FALSE;
169 else def = mputstr(def, ", ");
170 def = mputprintf(def, "ptr_%s(par_%s)",
171 sdef->parameters.elements[i].name,
172 sdef->parameters.elements[i].name);
173 }
174 }
175 def = mputstr(def, " { }\n");
176 }
177 /* otherwise constructor is not needed */
178
179 /* set_parameters function (used for param redirect in getcall) */
180 if (num_in > 0) {
181 def = mputprintf(def, "void set_parameters(const %s_call& call_par) "
182 "const;\n", name);
183 src = mputprintf(src, "void %s_call_redirect::set_parameters(const "
184 "%s_call& call_par) const\n"
185 "{\n", name, name);
186 for (i = 0; i < sdef->parameters.nElements; i++) {
187 if (sdef->parameters.elements[i].direction != PAR_OUT) {
188 src = mputprintf(src, "if (ptr_%s != NULL) "
189 "*ptr_%s = call_par.%s();\n",
190 sdef->parameters.elements[i].name,
191 sdef->parameters.elements[i].name,
192 sdef->parameters.elements[i].name);
193 }
194 }
195 src = mputstr(src, "}\n\n");
196 } else {
197 def = mputprintf(def, "inline void set_parameters(const %s_call&"
198 ") const { }\n", name);
199 }
200
201 def = mputstr(def, "};\n\n");
202 /* end of class xxx_call_redirect */
203
204
205 if (!sdef->is_noblock) {
206 /*
207 *
208 * xxx_reply class
209 *
210 */
211 decl = mputprintf(decl, "class %s_reply;\n", name);
212
213 /* class definition */
214 def = mputprintf(def, "class %s_reply {\n", name);
215
216 /* signature's out and inout parameters */
217 for (i = 0; i < sdef->parameters.nElements; i++) {
218 if (sdef->parameters.elements[i].direction != PAR_IN) {
219 def = mputprintf(def, "%s param_%s;\n",
220 sdef->parameters.elements[i].type,
221 sdef->parameters.elements[i].name);
222 }
223 }
224 if (sdef->return_type != NULL) {
225 def = mputprintf(def, "%s reply_value;\n", sdef->return_type);
226 }
227
228 def = mputstr(def, "public:\n");
229
230 /* parameters' access functions */
231 for (i = 0; i < sdef->parameters.nElements; i++) {
232 if (sdef->parameters.elements[i].direction != PAR_IN) {
233 def = mputprintf(def, "inline %s& %s() { return param_%s; }\n"
234 "inline const %s& %s() const { return param_%s; }\n",
235 sdef->parameters.elements[i].type,
236 sdef->parameters.elements[i].name,
237 sdef->parameters.elements[i].name,
238 sdef->parameters.elements[i].type,
239 sdef->parameters.elements[i].name,
240 sdef->parameters.elements[i].name);
241 }
242 }
243 if (sdef->return_type != NULL) {
244 def = mputprintf(def, "inline %s& return_value() "
245 "{ return reply_value; }\n"
246 "inline const %s& return_value() const "
247 "{ return reply_value; }\n",
248 sdef->return_type, sdef->return_type);
249 }
250
251 if (num_out > 0 || sdef->return_type != NULL) {
252 /* encode_text function */
253 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
254 src = mputprintf(src, "void %s_reply::encode_text(Text_Buf& "
255 "text_buf) const\n"
256 "{\n", name);
257 for (i = 0; i < sdef->parameters.nElements; i++) {
258 if (sdef->parameters.elements[i].direction != PAR_IN)
259 src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
260 sdef->parameters.elements[i].name);
261 }
262 if (sdef->return_type != NULL)
263 src = mputstr(src, "reply_value.encode_text(text_buf);\n");
264 src = mputstr(src, "}\n\n");
265 /* decode_text function */
266 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
267 src = mputprintf(src, "void %s_reply::decode_text(Text_Buf& "
268 "text_buf)\n"
269 "{\n", name);
270 for (i = 0; i < sdef->parameters.nElements; i++) {
271 if (sdef->parameters.elements[i].direction != PAR_IN)
272 src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
273 sdef->parameters.elements[i].name);
274 }
275 if (sdef->return_type != NULL)
276 src = mputstr(src, "reply_value.decode_text(text_buf);\n");
277 src = mputstr(src, "}\n\n");
278 } else {
279 def = mputstr(def, "inline void encode_text(Text_Buf&) "
280 "const { }\n"
281 "inline void decode_text(Text_Buf&) { }\n");
282 }
283
284 /* log function */
285 def = mputstr(def, "void log() const;\n");
286 src = mputprintf(src, "void %s_reply::log() const\n"
287 "{\n", name);
288 if (num_out > 0) {
289 boolean first_param = TRUE;
290 src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { \");\n",
291 dispname);
292 for (i = 0; i < sdef->parameters.nElements; i++) {
293 if (sdef->parameters.elements[i].direction != PAR_IN) {
294 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
295 if (first_param) first_param = FALSE;
296 else src = mputstr(src, ", ");
297 src = mputprintf(src, "%s := \");\n"
298 "param_%s.log();\n",
299 sdef->parameters.elements[i].dispname,
300 sdef->parameters.elements[i].name);
301 }
302 }
303 if (sdef->return_type != NULL) {
304 src = mputstr(src, "TTCN_Logger::log_event_str(\" } "
305 "value \");\n"
306 "reply_value.log();\n");
307 } else {
308 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
309 }
310 } else if (sdef->return_type != NULL) {
311 src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { } "
312 "value \");\n"
313 "reply_value.log();\n", dispname);
314 } else {
315 src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : "
316 "{ }\");\n", dispname);
317 }
318 src = mputstr(src, "}\n\n");
319
320 def = mputstr(def, "};\n\n");
321 /* end of xxx_reply class*/
322
323 /*
324 *
325 * xxx_reply_redirect class (for getreply port-operation)
326 *
327 */
328 decl = mputprintf(decl, "class %s_reply_redirect;\n", name);
329
330 /* class definition */
331 def = mputprintf(def, "class %s_reply_redirect {\n", name);
332
333 /* parameter pointers */
334 if (sdef->return_type != NULL) {
335 def = mputprintf(def, "%s *ret_val_ptr;\n", sdef->return_type);
336 }
337 for (i = 0; i < sdef->parameters.nElements; i++) {
338 if (sdef->parameters.elements[i].direction != PAR_IN) {
339 def = mputprintf(def, "%s *ptr_%s;\n",
340 sdef->parameters.elements[i].type,
341 sdef->parameters.elements[i].name);
342 }
343 }
344
345 def = mputstr(def, "public:\n");
346
347 if (num_out > 0 || sdef->return_type != NULL) {
348 boolean first_param = TRUE;
349 /* constructor */
350 def = mputprintf(def, "%s_reply_redirect(", name);
351 if (sdef->return_type != NULL) {
352 def = mputprintf(def, "%s *return_ptr", sdef->return_type);
353 first_param = FALSE;
354 }
355 for (i = 0; i < sdef->parameters.nElements; i++) {
356 if(sdef->parameters.elements[i].direction != PAR_IN) {
357 if (first_param) first_param = FALSE;
358 else def = mputstr(def, ", ");
359 def = mputprintf(def, "%s *par_%s = NULL",
360 sdef->parameters.elements[i].type,
361 sdef->parameters.elements[i].name);
362 }
363 }
364 def = mputstr(def, ")\n"
365 " : ");
366 first_param = TRUE;
367 if (sdef->return_type != NULL) {
368 def = mputstr(def, "ret_val_ptr(return_ptr)");
369 first_param = FALSE;
370 }
371 for (i = 0; i < sdef->parameters.nElements; i++) {
372 if(sdef->parameters.elements[i].direction != PAR_IN) {
373 if (first_param) first_param = FALSE;
374 else def = mputstr(def, ", ");
375 def = mputprintf(def, "ptr_%s(par_%s)",
376 sdef->parameters.elements[i].name,
377 sdef->parameters.elements[i].name);
378 }
379 }
380 def = mputstr(def, " { }\n");
381 }
382 /* otherwise constructor is not needed */
383
384 /* set_parameters function (used for param redirect in getreply) */
3abe9331 385 if (num_out > 0 || sdef->return_type != NULL) {
970ed795
EL
386 /* if there are "out" or "inout" parameters or a "return" ... */
387 def = mputprintf(def, "void set_parameters(const %s_reply& reply_par) "
388 "const;\n", name);
389 src = mputprintf(src, "void %s_reply_redirect::set_parameters(const "
390 "%s_reply& reply_par) const\n"
391 "{\n", name, name);
392 for (i = 0; i < sdef->parameters.nElements; i++) {
393 if (sdef->parameters.elements[i].direction != PAR_IN) {
394 src = mputprintf(src, "if (ptr_%s != NULL) "
395 "*ptr_%s = reply_par.%s();\n",
396 sdef->parameters.elements[i].name,
397 sdef->parameters.elements[i].name,
398 sdef->parameters.elements[i].name);
399 }
400 }
401 if (sdef->return_type!=NULL) {
402 src = mputstr(src, "if (ret_val_ptr != NULL) "
403 "*ret_val_ptr = reply_par.return_value();\n");
404 }
405 src = mputstr(src, "}\n\n");
406 }
407 else {
408 def = mputprintf(def, "inline void set_parameters(const %s_reply&) "
409 "const {}\n", name);
410 }
411
412 def = mputstr(def, "};\n\n");
413 /* end of class xxx_reply_redirect */
414 } /* if (!sdeff->is_noblock) */
415
416
417 if (sdef->exceptions.nElements > 0) {
418 char *selection_type, *unbound_value, *selection_prefix;
419
420 selection_type = mcopystr("exception_selection_type");
421 unbound_value = mcopystr("UNBOUND_VALUE");
422 selection_prefix = mcopystr("ALT");
423
424 /*
425 *
426 * xxx_exception class
427 *
428 */
429 decl = mputprintf(decl, "class %s_exception;\n", name);
430 /* class definition */
431 def = mputprintf(def, "class %s_exception {\n", name);
432
433 /* enum type */
434 def = mputstr(def, "public:\n"
435 "enum exception_selection_type { ");
436 for (i = 0; i < sdef->exceptions.nElements; i++) {
437 def = mputprintf(def, "ALT_%s = %lu, ",
438 sdef->exceptions.elements[i].altname, (unsigned long) i);
439 }
440 def = mputprintf(def, " UNBOUND_VALUE = %lu };\n"
441 "private:\n", (unsigned long) sdef->exceptions.nElements);
442
443 /* data members */
444 def = mputprintf(def, "%s exception_selection;\n"
445 "union {\n", selection_type);
446 for (i = 0; i < sdef->exceptions.nElements; i++) {
447 def = mputprintf(def, "%s *field_%s;\n",
448 sdef->exceptions.elements[i].name,
449 sdef->exceptions.elements[i].altname);
450 }
451 def = mputstr(def, "};\n");
452
453 /* clean_up function */
454 def = mputstr(def, "void clean_up();\n");
455 src = mputprintf(src, "void %s_exception::clean_up()\n"
456 "{\n"
457 "switch (exception_selection) {\n", name);
458 for (i = 0; i < sdef->exceptions.nElements; i++) {
459 src = mputprintf(src, "case %s_%s:\n"
460 "delete field_%s;\n", selection_prefix,
461 sdef->exceptions.elements[i].altname,
462 sdef->exceptions.elements[i].altname);
463 if (i < sdef->exceptions.nElements - 1)
464 src = mputstr(src, "break;\n");
465 }
466 src = mputprintf(src, "default:\n"
467 "break;\n"
468 "}\n"
469 "exception_selection = %s;\n"
470 "}\n\n", unbound_value);
471
472 /* copy_value function */
473 def = mputprintf(def, "void copy_value(const %s_exception& "
474 "other_value);\n", name);
475 src = mputprintf(src, "void %s_exception::copy_value(const "
476 "%s_exception& other_value)\n"
477 "{\n"
478 "switch (other_value.exception_selection) {\n", name, name);
479 for (i = 0; i < sdef->exceptions.nElements; i++) {
480 src = mputprintf(src, "case %s_%s:\n"
481 "field_%s = new %s(*other_value.field_%s);\n"
482 "break;\n", selection_prefix,
483 sdef->exceptions.elements[i].altname,
484 sdef->exceptions.elements[i].altname,
485 sdef->exceptions.elements[i].name,
486 sdef->exceptions.elements[i].altname);
487 }
488 src = mputprintf(src, "default:\n"
489 "TTCN_error(\"Copying an uninitialized exception of signature "
490 "%s.\");\n"
491 "}\n"
492 "exception_selection = other_value.exception_selection;\n"
493 "}\n\n", name);
494
495 /* default constructor */
496 def = mputprintf(def, "public:\n"
497 "%s_exception() : exception_selection(%s) { }\n", name,
498 unbound_value);
499
500 /* copy constructor */
501 def = mputprintf(def, "%s_exception(const %s_exception& "
502 "other_value) { copy_value(other_value); }\n", name, name);
503
504 /* constructors (from exception types) */
505 for (i = 0; i < sdef->exceptions.nElements; i++) {
506 def = mputprintf(def, "%s_exception(const %s& other_value);\n",
507 name, sdef->exceptions.elements[i].name);
508 src = mputprintf(src, "%s_exception::%s_exception(const "
509 "%s& other_value)\n"
510 "{\n"
511 "field_%s = new %s(other_value);\n"
512 "exception_selection = %s_%s;\n"
513 "}\n\n", name, name, sdef->exceptions.elements[i].name,
514 sdef->exceptions.elements[i].altname,
515 sdef->exceptions.elements[i].name, selection_prefix,
516 sdef->exceptions.elements[i].altname);
517 def = mputprintf(def, "%s_exception(const %s_template& "
518 "other_value);\n", name, sdef->exceptions.elements[i].name);
519 src = mputprintf(src, "%s_exception::%s_exception(const "
520 "%s_template& other_value)\n"
521 "{\n"
522 "field_%s = new %s(other_value.valueof());\n"
523 "exception_selection = %s_%s;\n"
524 "}\n\n", name, name, sdef->exceptions.elements[i].name,
525 sdef->exceptions.elements[i].altname,
526 sdef->exceptions.elements[i].name, selection_prefix,
527 sdef->exceptions.elements[i].altname);
528 }
529
530 /* destructor */
531 def = mputprintf(def, "~%s_exception() { clean_up(); }\n", name);
532
533 /* assignment operator */
534 def = mputprintf(def, "%s_exception& operator=(const %s_exception& "
535 "other_value);\n", name, name);
536 src = mputprintf(src, "%s_exception& %s_exception::operator=(const "
537 "%s_exception& other_value)\n"
538 "{\n"
539 "if (this != &other_value) {\n"
540 "clean_up();\n"
541 "copy_value(other_value);\n"
542 "}\n"
543 "return *this;\n"
544 "}\n\n", name, name, name);
545
546 /* field (type) access functions */
547 for (i = 0; i < sdef->exceptions.nElements; i++) {
548 def = mputprintf(def, "%s& %s_field();\n",
549 sdef->exceptions.elements[i].name,
550 sdef->exceptions.elements[i].altname);
551 src = mputprintf(src, "%s& %s_exception::%s_field()\n"
552 "{\n"
553 "if (exception_selection != %s_%s) {\n"
554 "clean_up();\n"
555 "field_%s = new %s;\n"
556 "exception_selection = %s_%s;\n"
557 "}\n"
558 "return *field_%s;\n"
559 "}\n\n", sdef->exceptions.elements[i].name, name,
560 sdef->exceptions.elements[i].altname, selection_prefix,
561 sdef->exceptions.elements[i].altname,
562 sdef->exceptions.elements[i].altname,
563 sdef->exceptions.elements[i].name,
564 selection_prefix, sdef->exceptions.elements[i].altname,
565 sdef->exceptions.elements[i].altname);
566 def = mputprintf(def, "const %s& %s_field() const;\n",
567 sdef->exceptions.elements[i].name,
568 sdef->exceptions.elements[i].altname);
569 src = mputprintf(src, "const %s& %s_exception::%s_field() const\n"
570 "{\n"
571 "if (exception_selection != %s_%s) "
572 "TTCN_error(\"Referencing to non-selected type %s in an "
573 "exception of signature %s.\");\n"
574 "return *field_%s;\n"
575 "}\n\n", sdef->exceptions.elements[i].name, name,
576 sdef->exceptions.elements[i].altname, selection_prefix,
577 sdef->exceptions.elements[i].altname,
578 sdef->exceptions.elements[i].dispname, dispname,
579 sdef->exceptions.elements[i].altname);
580 }
581
582 /* get_selection function */
583 def = mputprintf(def, "inline %s get_selection() const "
584 "{ return exception_selection; }\n", selection_type);
585
586 /* encode_text function */
587 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
588 src = mputprintf(src, "void %s_exception::encode_text(Text_Buf& "
589 "text_buf) const\n"
590 "{\n"
591 "text_buf.push_int(exception_selection);\n"
592 "switch (exception_selection) {\n", name);
593 for (i = 0; i < sdef->exceptions.nElements; i++) {
594 src = mputprintf(src, "case %s_%s:\n"
595 "field_%s->encode_text(text_buf);\n"
596 "break;\n", selection_prefix,
597 sdef->exceptions.elements[i].altname,
598 sdef->exceptions.elements[i].altname);
599 }
600 src = mputprintf(src, "default:\n"
601 "TTCN_error(\"Text encoder: Encoding an uninitialized exception "
602 "of signature %s.\");\n"
603 "}\n"
604 "}\n\n", dispname);
605
606 /* decode_text function */
607 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
608 src = mputprintf(src, "void %s_exception::decode_text(Text_Buf& "
609 "text_buf)\n"
610 "{\n"
611 "switch ((%s)text_buf.pull_int().get_val()) {\n", name, selection_type);
612 for (i = 0; i < sdef->exceptions.nElements; i++) {
613 src = mputprintf(src, "case %s_%s:\n"
614 "%s_field().decode_text(text_buf);\n"
615 "break;\n", selection_prefix,
616 sdef->exceptions.elements[i].altname,
617 sdef->exceptions.elements[i].altname);
618 }
619 src = mputprintf(src, "default:\n"
620 "TTCN_error(\"Text decoder: Unrecognized selector was received "
621 "for an exception of signature %s.\");\n"
622 "}\n"
623 "}\n\n", dispname);
624
625 /* log function */
626 def = mputstr(def, "void log() const;\n");
627 src = mputprintf(src, "void %s_exception::log() const\n"
628 "{\n"
629 "TTCN_Logger::log_event_str(\"%s, \");\n"
630 "switch (exception_selection) {\n",
631 name, dispname);
632 for (i = 0; i < sdef->exceptions.nElements; i++) {
633 src = mputprintf(src, "case %s_%s:\n"
634 "TTCN_Logger::log_event_str(\"%s : \");\n"
635 "field_%s->log();\n"
636 "break;\n", selection_prefix,
637 sdef->exceptions.elements[i].altname,
638 sdef->exceptions.elements[i].dispname,
639 sdef->exceptions.elements[i].altname);
640 }
641 src = mputstr(src, "default:\n"
642 "TTCN_Logger::log_event_str(\"<uninitialized exception>\");\n"
643 "}\n"
644 "}\n\n");
645
646 def = mputstr(def, "};\n\n");
647 /* end of xxx_exception class*/
648
649 Free(selection_type);
650 selection_type = mprintf("%s_exception::exception_selection_type", name);
651 Free(unbound_value);
652 unbound_value = mprintf("%s_exception::UNBOUND_VALUE", name);
653 Free(selection_prefix);
654 selection_prefix = mprintf("%s_exception::ALT", name);
655
656 /*
657 *
658 * simple xxx_exception_template for the catch port-operator
659 * only with constructors, a log/match function and value redirect
660 *
661 */
662 decl = mputprintf(decl, "class %s_exception_template;\n", name);
663
664 def = mputprintf(def, "class %s_exception_template {\n", name);
665
666 /* data members */
667 /* exception-selection enum */
668 def = mputprintf(def, "%s exception_selection;\n", selection_type);
669 /* union of all possible exceptions (templates) */
670 def = mputstr(def, "union {\n");
671 for (i = 0; i < sdef->exceptions.nElements; i++) {
672 def = mputprintf(def, "const %s_template *field_%s;\n",
673 sdef->exceptions.elements[i].name,
674 sdef->exceptions.elements[i].altname);
675 }
676 def = mputstr(def, "};\n");
677 /* union of all possible value redirect pointers */
678 def = mputstr(def, "union {\n");
679 for (i = 0; i < sdef->exceptions.nElements; i++) {
680 def = mputprintf(def, "%s *ptr_%s;\n",
681 sdef->exceptions.elements[i].name,
682 sdef->exceptions.elements[i].altname);
683 }
684 def = mputstr(def, "};\n"
685 "public:\n");
686 /* constructors (for all possible template + redirect pointer pairs) */
687 for (i = 0; i < sdef->exceptions.nElements; i++) {
688 def = mputprintf(def, "%s_exception_template(const %s_template& "
689 "init_template, %s *value_ptr = NULL);\n", name,
690 sdef->exceptions.elements[i].name,
691 sdef->exceptions.elements[i].name);
692 src = mputprintf(src, "%s_exception_template::%s_exception_template"
693 "(const %s_template& init_template, %s *value_ptr)\n"
694 "{\n"
695 "exception_selection = %s_%s;\n"
696 "field_%s = &init_template;\n"
697 "ptr_%s = value_ptr;\n"
698 "}\n\n", name, name, sdef->exceptions.elements[i].name,
699 sdef->exceptions.elements[i].name, selection_prefix,
700 sdef->exceptions.elements[i].altname,
701 sdef->exceptions.elements[i].altname,
702 sdef->exceptions.elements[i].altname);
703 }
704
705 /* match function */
3abe9331 706 def = mputprintf(def, "boolean match(const %s_exception& other_value,"
707 "boolean legacy = FALSE) const;\n", name);
970ed795 708 src = mputprintf(src, "boolean %s_exception_template::match(const "
3abe9331 709 "%s_exception& other_value, boolean legacy) const\n"
970ed795
EL
710 "{\n"
711 "if (exception_selection != other_value.get_selection()) "
712 "return FALSE;\n"
713 "switch (exception_selection) {\n", name, name);
714 for (i = 0; i < sdef->exceptions.nElements; i++) {
715 src = mputprintf(src, "case %s_%s:\n"
3abe9331 716 "return field_%s->match(other_value.%s_field(), legacy);\n",
970ed795
EL
717 selection_prefix, sdef->exceptions.elements[i].altname,
718 sdef->exceptions.elements[i].altname,
719 sdef->exceptions.elements[i].altname);
720 }
721 src = mputprintf(src, "default:\n"
722 "TTCN_error(\"Internal error: Invalid selector when matching an "
723 "exception of signature %s.\");\n"
724 "return FALSE;\n"
725 "}\n"
726 "}\n\n", dispname);
727
728 /* log_match function */
3abe9331 729 def = mputprintf(def, "void log_match(const %s_exception& other_value, "
730 "boolean legacy = FALSE) const;\n", name);
970ed795 731 src = mputprintf(src, "void %s_exception_template::log_match(const "
3abe9331 732 "%s_exception& other_value, boolean legacy) const\n"
970ed795
EL
733 "{\n"
734 "TTCN_Logger::log_event_str(\"%s, \");\n"
735 "if (exception_selection == other_value.get_selection()) {\n"
736 "switch (exception_selection) {\n", name, name, dispname);
737 for (i = 0; i < sdef->exceptions.nElements; i++) {
738 src = mputprintf(src, "case %s_%s:\n"
739 "TTCN_Logger::log_event_str(\"%s : \");\n"
3abe9331 740 "field_%s->log_match(other_value.%s_field(), legacy);\n"
970ed795
EL
741 "break;\n", selection_prefix,
742 sdef->exceptions.elements[i].altname,
743 sdef->exceptions.elements[i].dispname,
744 sdef->exceptions.elements[i].altname,
745 sdef->exceptions.elements[i].altname);
746 }
747 src = mputstr(src, "default:\n"
748 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
749 "}\n"
750 "} else {\n"
751 "other_value.log();\n"
752 "TTCN_Logger::log_event_str(\" with \");\n"
753 "switch (exception_selection) {\n");
754 for (i = 0; i < sdef->exceptions.nElements; i++) {
755 src = mputprintf(src, "case %s_%s:\n"
756 "TTCN_Logger::log_event_str(\"%s : \");\n"
757 "field_%s->log();\n"
758 "break;\n", selection_prefix,
759 sdef->exceptions.elements[i].altname,
760 sdef->exceptions.elements[i].dispname,
761 sdef->exceptions.elements[i].altname);
762 }
763 src = mputstr(src, "default:\n"
764 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
765 "}\n"
3abe9331 766 "if (match(other_value, legacy)) "
970ed795
EL
767 "TTCN_Logger::log_event_str(\" matched\");\n"
768 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
769 "}\n"
770 "}\n\n");
771
772 /* set_value function */
773 def = mputprintf(def, "void set_value(const %s_exception& "
774 "source_value) const;\n", name);
775 src = mputprintf(src, "void %s_exception_template::set_value(const "
776 "%s_exception& source_value) const\n"
777 "{\n"
778 "if (exception_selection == source_value.get_selection()) {\n"
779 "switch (exception_selection) {\n", name, name);
780 for (i = 0; i < sdef->exceptions.nElements; i++) {
781 src = mputprintf(src, "case %s_%s:\n"
782 "if (ptr_%s != NULL) *ptr_%s = source_value.%s_field();\n"
783 "return;\n", selection_prefix,
784 sdef->exceptions.elements[i].altname,
785 sdef->exceptions.elements[i].altname,
786 sdef->exceptions.elements[i].altname,
787 sdef->exceptions.elements[i].altname);
788 }
789 src = mputprintf(src, "default:\n"
790 "break;\n"
791 "}\n"
792 "}\n"
793 "TTCN_error(\"Internal error: Invalid selector when performing "
794 "value redirect on an exception of signature %s.\");\n"
795 "}\n\n", dispname);
796
797 def = mputstr(def, "};\n\n");
798 /* end of class xxx_exception_template */
799
800 Free(selection_type);
801 Free(unbound_value);
802 Free(selection_prefix);
803 } /* if (sdef->exceptions.nElements > 0) */
804
805 /*
806 * template class
807 */
808
809 decl = mputprintf(decl, "class %s_template;\n", name);
810
811 def = mputprintf(def, "class %s_template {\n", name);
812
813 /* parameters */
814 for (i = 0; i < sdef->parameters.nElements; i++) {
815 def = mputprintf(def, "%s_template param_%s;\n",
816 sdef->parameters.elements[i].type,
817 sdef->parameters.elements[i].name);
818 }
819 if (sdef->return_type != NULL) {
820 def = mputprintf(def, "mutable %s_template reply_value;\n",
821 sdef->return_type);
822 }
823
824 def = mputstr(def, "public:\n");
825 /* constructor */
826 if (sdef->parameters.nElements > 0 || sdef->return_type != NULL) {
827 boolean first_param = TRUE;
828 def = mputprintf(def, "%s_template();\n", name);
829 src = mputprintf(src, "%s_template::%s_template()\n"
830 " : ", name, name);
831 for (i = 0; i < sdef->parameters.nElements; i++) {
832 if (first_param) first_param = FALSE;
833 else src = mputstr(src, ", ");
834 src = mputprintf(src, "param_%s(ANY_VALUE)",
835 sdef->parameters.elements[i].name);
836 }
837 if (sdef->return_type != NULL) {
838 if (first_param) /*first_param = FALSE*/;
839 else src = mputstr(src, ", ");
840 src = mputstr(src, "reply_value(ANY_VALUE)");
841 }
842 src = mputstr(src, "\n"
843 "{\n"
844 "}\n\n");
845 } else {
846 def = mputprintf(def, "%s_template() { }\n", name);
847 }
848
849 if (sdef->parameters.nElements == 0) {
850 /* constructor and assignment operator for parameter-less signatures */
851 if (sdef->return_type != NULL) {
852 def = mputprintf(def, "%s_template(null_type null_value);\n",
853 name);
854 src = mputprintf(src,
855 "%s_template::%s_template(null_type)\n"
856 " : reply_value(ANY_VALUE)\n"
857 "{\n"
858 "}\n\n", name, name);
859 } else {
860 def = mputprintf(def, "%s_template(null_type) { }\n",
861 name);
862 }
863 def = mputprintf(def, "inline %s_template& operator=(null_type)"
864 " { return *this; }\n", name);
865 }
866
867 /* parameter access functions */
868 for (i = 0; i < sdef->parameters.nElements; i++) {
869 def = mputprintf(def, "inline %s_template& %s() { return param_%s; }\n"
870 "inline const %s_template& %s() const { return param_%s; }\n",
871 sdef->parameters.elements[i].type,
872 sdef->parameters.elements[i].name,
873 sdef->parameters.elements[i].name,
874 sdef->parameters.elements[i].type,
875 sdef->parameters.elements[i].name,
876 sdef->parameters.elements[i].name);
877 }
878 if (sdef->return_type != NULL) {
879 def = mputprintf(def, "inline %s_template& return_value() const "
880 "{ return reply_value; }\n", sdef->return_type);
881 }
882
883 /* create_call function for creating xxx_call signature-value */
884 if (num_in > 0) {
885 def = mputprintf(def, "%s_call create_call() const;\n", name);
886 src = mputprintf(src, "%s_call %s_template::create_call() const\n"
887 "{\n"
888 "%s_call ret_val;\n", name, name, name);
889 for (i = 0; i < sdef->parameters.nElements; i++) {
890 if (sdef->parameters.elements[i].direction != PAR_OUT) {
891 src = mputprintf(src, "ret_val.%s() = param_%s.valueof();\n",
892 sdef->parameters.elements[i].name,
893 sdef->parameters.elements[i].name);
894 }
895 }
896 src = mputstr(src, "return ret_val;\n"
897 "}\n\n");
898 } else {
899 def = mputprintf(def, "inline %s_call create_call() const "
900 "{ return %s_call(); }\n", name, name);
901 }
902
903 if (!sdef->is_noblock) {
904 /* create_reply function for creating xxx_reply signature-value */
905 if (num_out > 0 || sdef->return_type != NULL) {
906 def = mputprintf(def, "%s_reply create_reply() const;\n", name);
907 src = mputprintf(src, "%s_reply %s_template::create_reply() const\n"
908 "{\n"
909 "%s_reply ret_val;\n", name, name, name);
910 for (i = 0; i < sdef->parameters.nElements; i++) {
911 if (sdef->parameters.elements[i].direction != PAR_IN) {
912 src = mputprintf(src, "ret_val.%s() = "
913 "param_%s.valueof();\n",
914 sdef->parameters.elements[i].name,
915 sdef->parameters.elements[i].name);
916 }
917 }
918 if (sdef->return_type != NULL) {
919 src = mputstr(src, "ret_val.return_value() = "
920 "reply_value.valueof();\n");
921 }
922 src = mputstr(src, "return ret_val;\n"
923 "}\n\n");
924 } else {
925 def = mputprintf(def, "inline %s_reply create_reply() const "
926 "{ return %s_reply(); }\n", name, name);
927 }
928 }
929
930 /* match_call function for matching with xxx_call signature-value */
931 if (num_in > 0) {
932 boolean first_param = TRUE;
3abe9331 933 def = mputprintf(def, "boolean match_call(const %s_call& match_value, "
934 "boolean legacy = FALSE) const;\n", name);
970ed795 935 src = mputprintf(src, "boolean %s_template::match_call(const %s_call& "
3abe9331 936 "match_value, boolean legacy) const\n"
970ed795
EL
937 "{\n"
938 "return ", name, name);
939 for (i = 0; i < sdef->parameters.nElements; i++) {
940 if (sdef->parameters.elements[i].direction != PAR_OUT) {
941 if (first_param) first_param = FALSE;
942 else src = mputstr(src, " &&\n");
3abe9331 943 src = mputprintf(src, "param_%s.match(match_value.%s(), legacy)",
970ed795
EL
944 sdef->parameters.elements[i].name,
945 sdef->parameters.elements[i].name);
946 }
947 }
948 src = mputstr(src, ";\n"
949 "}\n\n");
950 } else {
951 def = mputprintf(def, "inline boolean match_call(const %s_call&"
3abe9331 952 ", boolean legacy = FALSE) const { return TRUE; }\n", name);
970ed795
EL
953 }
954
955 if (!sdef->is_noblock) {
956 if (num_out > 0 || sdef->return_type != NULL) {
957 boolean first_param = TRUE;
958 /* match_reply function for matching with xxx_reply value */
959 def = mputprintf(def, "boolean match_reply(const %s_reply& "
3abe9331 960 "match_value, boolean legacy = FALSE) const;\n", name);
970ed795 961 src = mputprintf(src, "boolean %s_template::match_reply(const "
3abe9331 962 "%s_reply& match_value, boolean legacy) const\n"
970ed795
EL
963 "{\n"
964 "return ", name, name);
965 for (i = 0; i < sdef->parameters.nElements; i++) {
966 if(sdef->parameters.elements[i].direction != PAR_IN) {
967 if (first_param) first_param = FALSE;
968 else src = mputstr(src, " &&\n");
3abe9331 969 src = mputprintf(src, "param_%s.match(match_value.%s(), legacy)",
970ed795
EL
970 sdef->parameters.elements[i].name,
971 sdef->parameters.elements[i].name);
972 }
973 }
974 if (sdef->return_type != NULL) {
975 if (first_param) /*first_param = FALSE*/;
976 else src = mputstr(src, " &&\n");
977 src = mputstr(src,
3abe9331 978 "reply_value.match(match_value.return_value(), legacy)");
970ed795
EL
979 }
980 src = mputstr(src, ";\n"
981 "}\n\n");
982 } else {
983 def = mputprintf(def, "inline boolean match_reply(const %s_reply&"
3abe9331 984 ", boolean legacy = FALSE) const { return TRUE; }\n", name);
970ed795
EL
985 }
986 }
987
988 /* set_value_template function */
989 if (sdef->return_type != NULL) {
990 def = mputprintf(def, "const %s_template& set_value_template(const "
991 "%s_template& new_template) const;\n", name, sdef->return_type);
992 src = mputprintf(src,
993 "const %s_template& %s_template::set_value_template"
994 "(const %s_template& new_template) const\n"
995 "{\n"
996 "reply_value = new_template;\n"
997 "return *this;\n"
998 "}\n\n", name, name, sdef->return_type);
999 }
1000
1001 /* log function */
1002 def = mputstr(def, "void log() const;\n");
1003 src = mputprintf(src, "void %s_template::log() const\n"
1004 "{\n", name);
1005 if (sdef->parameters.nElements >= 1) {
1006 for (i = 0; i < sdef->parameters.nElements; i++) {
1007 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
1008 if (i == 0) src = mputc(src, '{');
1009 else src = mputc(src, ',');
1010 src = mputprintf(src, " %s := \");\n"
1011 "param_%s.log();\n", sdef->parameters.elements[i].dispname,
1012 sdef->parameters.elements[i].name);
1013 }
1014 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
1015 } else {
1016 src = mputstr(src, "TTCN_Logger::log_event_str(\"{ }\");\n");
1017 }
1018 src = mputstr(src, "}\n\n");
1019
1020 /* log_match_call function */
3abe9331 1021 def = mputprintf(def, "void log_match_call(const %s_call& match_value, "
1022 "boolean legacy = FALSE) const;\n", name);
970ed795
EL
1023 src = mputprintf(src, "void %s_template::log_match_call(const %s_call& "
1024 , name, name);
1025 if (num_in > 0) {
1026 boolean first_param = TRUE;
3abe9331 1027 src = mputstr(src, "match_value, boolean legacy) const\n{\n");
970ed795
EL
1028 for (i = 0; i < sdef->parameters.nElements; i++) {
1029 if (sdef->parameters.elements[i].direction != PAR_OUT) {
1030 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
1031 if (first_param) {
1032 src = mputc(src, '{');
1033 first_param = FALSE;
1034 } else src = mputc(src, ',');
1035 src = mputprintf(src, " %s := \");\n"
3abe9331 1036 "param_%s.log_match(match_value.%s(), legacy);\n",
970ed795
EL
1037 sdef->parameters.elements[i].dispname,
1038 sdef->parameters.elements[i].name,
1039 sdef->parameters.elements[i].name);
1040 }
1041 }
1042 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
1043 } else {
3abe9331 1044 src = mputstr(src, ", boolean) const\n{\n"
970ed795
EL
1045 "TTCN_Logger::log_event_str(\"{ } with { } matched\");\n");
1046 }
1047 src = mputstr(src, "}\n\n");
1048
1049 if (!sdef->is_noblock) {
1050 /* log_match_reply function */
3abe9331 1051 def = mputprintf(def, "void log_match_reply(const %s_reply& match_value, "
1052 "boolean legacy = FALSE) const;\n", name);
970ed795
EL
1053 src = mputprintf(src, "void %s_template::log_match_reply(const %s_reply& "
1054 , name, name);
1055 if (num_out > 0) {
1056 boolean first_param = TRUE;
3abe9331 1057 src = mputstr(src, "match_value, boolean legacy) const\n{\n");
970ed795
EL
1058 for (i = 0; i < sdef->parameters.nElements; i++) {
1059 if (sdef->parameters.elements[i].direction != PAR_IN) {
1060 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
1061 if (first_param) {
1062 src = mputc(src, '{');
1063 first_param = FALSE;
1064 } else src = mputc(src, ',');
1065 src = mputprintf(src, " %s := \");\n"
3abe9331 1066 "param_%s.log_match(match_value.%s(), legacy);\n",
970ed795
EL
1067 sdef->parameters.elements[i].dispname,
1068 sdef->parameters.elements[i].name,
1069 sdef->parameters.elements[i].name);
1070 }
1071 }
1072 if (sdef->return_type != NULL) {
1073 src = mputstr(src, "TTCN_Logger::log_event_str(\" } value "
1074 "\");\n"
3abe9331 1075 "reply_value.log_match(match_value.return_value(), legacy);\n");
970ed795
EL
1076 } else {
1077 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
1078 }
1079 } else {
1080 if (sdef->return_type != NULL) {
3abe9331 1081 src = mputstr(src, "match_value, boolean legacy) const\n{\n"
970ed795
EL
1082 "TTCN_Logger::log_event_str(\"{ } with { } "
1083 "matched value \");\n"
3abe9331 1084 "reply_value.log_match(match_value.return_value(), legacy);\n");
970ed795 1085 } else {
3abe9331 1086 src = mputstr(src, ", boolean) const\n{\n"
970ed795
EL
1087 "TTCN_Logger::log_event_str(\"{ } with { } "
1088 "matched\");\n");
1089 }
1090 }
1091 src = mputstr(src, "}\n\n");
1092 }
1093
1094 if (sdef->parameters.nElements > 0) {
1095 /* encode_text function */
1096 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
1097 src = mputprintf(src, "void %s_template::encode_text(Text_Buf& "
1098 "text_buf) const\n"
1099 "{\n", name);
1100 for (i = 0; i < sdef->parameters.nElements; i++) {
1101 src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
1102 sdef->parameters.elements[i].name);
1103 }
1104 src = mputstr(src, "}\n\n");
1105 /* decode_text function */
1106 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
1107 src = mputprintf(src, "void %s_template::decode_text(Text_Buf& "
1108 "text_buf)\n"
1109 "{\n", name);
1110 for (i = 0; i < sdef->parameters.nElements; i++) {
1111 src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
1112 sdef->parameters.elements[i].name);
1113 }
1114 src = mputstr(src, "}\n\n");
1115 } else {
1116 def = mputstr(def, "inline void encode_text(Text_Buf&) const "
1117 "{ }\n"
1118 "inline void decode_text(Text_Buf&) { }\n");
1119 }
1120
1121 /* end of template definition */
1122 def = mputstr(def, "};\n\n");
1123
1124 output->header.class_decls = mputstr(output->header.class_decls, decl);
1125 Free(decl);
1126
1127 output->header.class_defs = mputstr(output->header.class_defs, def);
1128 Free(def);
1129
1130 output->source.methods = mputstr(output->source.methods, src);
1131 Free(src);
1132}
This page took 0.087335 seconds and 5 git commands to generate.