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