Sync with 5.1.0
[deliverable/titan.core.git] / compiler2 / ttcn3 / signature.c
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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 ((sdef->parameters.nElements - num_in) > 0
374 || sdef->return_type != NULL) {
375 /* if there are "out" or "inout" parameters or a "return" ... */
376 def = mputprintf(def, "void set_parameters(const %s_reply& reply_par) "
377 "const;\n", name);
378 src = mputprintf(src, "void %s_reply_redirect::set_parameters(const "
379 "%s_reply& reply_par) const\n"
380 "{\n", name, name);
381 for (i = 0; i < sdef->parameters.nElements; i++) {
382 if (sdef->parameters.elements[i].direction != PAR_IN) {
383 src = mputprintf(src, "if (ptr_%s != NULL) "
384 "*ptr_%s = reply_par.%s();\n",
385 sdef->parameters.elements[i].name,
386 sdef->parameters.elements[i].name,
387 sdef->parameters.elements[i].name);
388 }
389 }
390 if (sdef->return_type!=NULL) {
391 src = mputstr(src, "if (ret_val_ptr != NULL) "
392 "*ret_val_ptr = reply_par.return_value();\n");
393 }
394 src = mputstr(src, "}\n\n");
395 }
396 else {
397 def = mputprintf(def, "inline void set_parameters(const %s_reply&) "
398 "const {}\n", name);
399 }
400
401 def = mputstr(def, "};\n\n");
402 /* end of class xxx_reply_redirect */
403 } /* if (!sdeff->is_noblock) */
404
405
406 if (sdef->exceptions.nElements > 0) {
407 char *selection_type, *unbound_value, *selection_prefix;
408
409 selection_type = mcopystr("exception_selection_type");
410 unbound_value = mcopystr("UNBOUND_VALUE");
411 selection_prefix = mcopystr("ALT");
412
413 /*
414 *
415 * xxx_exception class
416 *
417 */
418 decl = mputprintf(decl, "class %s_exception;\n", name);
419 /* class definition */
420 def = mputprintf(def, "class %s_exception {\n", name);
421
422 /* enum type */
423 def = mputstr(def, "public:\n"
424 "enum exception_selection_type { ");
425 for (i = 0; i < sdef->exceptions.nElements; i++) {
426 def = mputprintf(def, "ALT_%s = %lu, ",
427 sdef->exceptions.elements[i].altname, (unsigned long) i);
428 }
429 def = mputprintf(def, " UNBOUND_VALUE = %lu };\n"
430 "private:\n", (unsigned long) sdef->exceptions.nElements);
431
432 /* data members */
433 def = mputprintf(def, "%s exception_selection;\n"
434 "union {\n", selection_type);
435 for (i = 0; i < sdef->exceptions.nElements; i++) {
436 def = mputprintf(def, "%s *field_%s;\n",
437 sdef->exceptions.elements[i].name,
438 sdef->exceptions.elements[i].altname);
439 }
440 def = mputstr(def, "};\n");
441
442 /* clean_up function */
443 def = mputstr(def, "void clean_up();\n");
444 src = mputprintf(src, "void %s_exception::clean_up()\n"
445 "{\n"
446 "switch (exception_selection) {\n", name);
447 for (i = 0; i < sdef->exceptions.nElements; i++) {
448 src = mputprintf(src, "case %s_%s:\n"
449 "delete field_%s;\n", selection_prefix,
450 sdef->exceptions.elements[i].altname,
451 sdef->exceptions.elements[i].altname);
452 if (i < sdef->exceptions.nElements - 1)
453 src = mputstr(src, "break;\n");
454 }
455 src = mputprintf(src, "default:\n"
456 "break;\n"
457 "}\n"
458 "exception_selection = %s;\n"
459 "}\n\n", unbound_value);
460
461 /* copy_value function */
462 def = mputprintf(def, "void copy_value(const %s_exception& "
463 "other_value);\n", name);
464 src = mputprintf(src, "void %s_exception::copy_value(const "
465 "%s_exception& other_value)\n"
466 "{\n"
467 "switch (other_value.exception_selection) {\n", name, name);
468 for (i = 0; i < sdef->exceptions.nElements; i++) {
469 src = mputprintf(src, "case %s_%s:\n"
470 "field_%s = new %s(*other_value.field_%s);\n"
471 "break;\n", selection_prefix,
472 sdef->exceptions.elements[i].altname,
473 sdef->exceptions.elements[i].altname,
474 sdef->exceptions.elements[i].name,
475 sdef->exceptions.elements[i].altname);
476 }
477 src = mputprintf(src, "default:\n"
478 "TTCN_error(\"Copying an uninitialized exception of signature "
479 "%s.\");\n"
480 "}\n"
481 "exception_selection = other_value.exception_selection;\n"
482 "}\n\n", name);
483
484 /* default constructor */
485 def = mputprintf(def, "public:\n"
486 "%s_exception() : exception_selection(%s) { }\n", name,
487 unbound_value);
488
489 /* copy constructor */
490 def = mputprintf(def, "%s_exception(const %s_exception& "
491 "other_value) { copy_value(other_value); }\n", name, name);
492
493 /* constructors (from exception types) */
494 for (i = 0; i < sdef->exceptions.nElements; i++) {
495 def = mputprintf(def, "%s_exception(const %s& other_value);\n",
496 name, sdef->exceptions.elements[i].name);
497 src = mputprintf(src, "%s_exception::%s_exception(const "
498 "%s& other_value)\n"
499 "{\n"
500 "field_%s = new %s(other_value);\n"
501 "exception_selection = %s_%s;\n"
502 "}\n\n", name, name, sdef->exceptions.elements[i].name,
503 sdef->exceptions.elements[i].altname,
504 sdef->exceptions.elements[i].name, selection_prefix,
505 sdef->exceptions.elements[i].altname);
506 def = mputprintf(def, "%s_exception(const %s_template& "
507 "other_value);\n", name, sdef->exceptions.elements[i].name);
508 src = mputprintf(src, "%s_exception::%s_exception(const "
509 "%s_template& other_value)\n"
510 "{\n"
511 "field_%s = new %s(other_value.valueof());\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 }
518
519 /* destructor */
520 def = mputprintf(def, "~%s_exception() { clean_up(); }\n", name);
521
522 /* assignment operator */
523 def = mputprintf(def, "%s_exception& operator=(const %s_exception& "
524 "other_value);\n", name, name);
525 src = mputprintf(src, "%s_exception& %s_exception::operator=(const "
526 "%s_exception& other_value)\n"
527 "{\n"
528 "if (this != &other_value) {\n"
529 "clean_up();\n"
530 "copy_value(other_value);\n"
531 "}\n"
532 "return *this;\n"
533 "}\n\n", name, name, name);
534
535 /* field (type) access functions */
536 for (i = 0; i < sdef->exceptions.nElements; i++) {
537 def = mputprintf(def, "%s& %s_field();\n",
538 sdef->exceptions.elements[i].name,
539 sdef->exceptions.elements[i].altname);
540 src = mputprintf(src, "%s& %s_exception::%s_field()\n"
541 "{\n"
542 "if (exception_selection != %s_%s) {\n"
543 "clean_up();\n"
544 "field_%s = new %s;\n"
545 "exception_selection = %s_%s;\n"
546 "}\n"
547 "return *field_%s;\n"
548 "}\n\n", sdef->exceptions.elements[i].name, name,
549 sdef->exceptions.elements[i].altname, selection_prefix,
550 sdef->exceptions.elements[i].altname,
551 sdef->exceptions.elements[i].altname,
552 sdef->exceptions.elements[i].name,
553 selection_prefix, sdef->exceptions.elements[i].altname,
554 sdef->exceptions.elements[i].altname);
555 def = mputprintf(def, "const %s& %s_field() const;\n",
556 sdef->exceptions.elements[i].name,
557 sdef->exceptions.elements[i].altname);
558 src = mputprintf(src, "const %s& %s_exception::%s_field() const\n"
559 "{\n"
560 "if (exception_selection != %s_%s) "
561 "TTCN_error(\"Referencing to non-selected type %s in an "
562 "exception of signature %s.\");\n"
563 "return *field_%s;\n"
564 "}\n\n", sdef->exceptions.elements[i].name, name,
565 sdef->exceptions.elements[i].altname, selection_prefix,
566 sdef->exceptions.elements[i].altname,
567 sdef->exceptions.elements[i].dispname, dispname,
568 sdef->exceptions.elements[i].altname);
569 }
570
571 /* get_selection function */
572 def = mputprintf(def, "inline %s get_selection() const "
573 "{ return exception_selection; }\n", selection_type);
574
575 /* encode_text function */
576 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
577 src = mputprintf(src, "void %s_exception::encode_text(Text_Buf& "
578 "text_buf) const\n"
579 "{\n"
580 "text_buf.push_int(exception_selection);\n"
581 "switch (exception_selection) {\n", name);
582 for (i = 0; i < sdef->exceptions.nElements; i++) {
583 src = mputprintf(src, "case %s_%s:\n"
584 "field_%s->encode_text(text_buf);\n"
585 "break;\n", selection_prefix,
586 sdef->exceptions.elements[i].altname,
587 sdef->exceptions.elements[i].altname);
588 }
589 src = mputprintf(src, "default:\n"
590 "TTCN_error(\"Text encoder: Encoding an uninitialized exception "
591 "of signature %s.\");\n"
592 "}\n"
593 "}\n\n", dispname);
594
595 /* decode_text function */
596 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
597 src = mputprintf(src, "void %s_exception::decode_text(Text_Buf& "
598 "text_buf)\n"
599 "{\n"
600 "switch ((%s)text_buf.pull_int().get_val()) {\n", name, selection_type);
601 for (i = 0; i < sdef->exceptions.nElements; i++) {
602 src = mputprintf(src, "case %s_%s:\n"
603 "%s_field().decode_text(text_buf);\n"
604 "break;\n", selection_prefix,
605 sdef->exceptions.elements[i].altname,
606 sdef->exceptions.elements[i].altname);
607 }
608 src = mputprintf(src, "default:\n"
609 "TTCN_error(\"Text decoder: Unrecognized selector was received "
610 "for an exception of signature %s.\");\n"
611 "}\n"
612 "}\n\n", dispname);
613
614 /* log function */
615 def = mputstr(def, "void log() const;\n");
616 src = mputprintf(src, "void %s_exception::log() const\n"
617 "{\n"
618 "TTCN_Logger::log_event_str(\"%s, \");\n"
619 "switch (exception_selection) {\n",
620 name, dispname);
621 for (i = 0; i < sdef->exceptions.nElements; i++) {
622 src = mputprintf(src, "case %s_%s:\n"
623 "TTCN_Logger::log_event_str(\"%s : \");\n"
624 "field_%s->log();\n"
625 "break;\n", selection_prefix,
626 sdef->exceptions.elements[i].altname,
627 sdef->exceptions.elements[i].dispname,
628 sdef->exceptions.elements[i].altname);
629 }
630 src = mputstr(src, "default:\n"
631 "TTCN_Logger::log_event_str(\"<uninitialized exception>\");\n"
632 "}\n"
633 "}\n\n");
634
635 def = mputstr(def, "};\n\n");
636 /* end of xxx_exception class*/
637
638 Free(selection_type);
639 selection_type = mprintf("%s_exception::exception_selection_type", name);
640 Free(unbound_value);
641 unbound_value = mprintf("%s_exception::UNBOUND_VALUE", name);
642 Free(selection_prefix);
643 selection_prefix = mprintf("%s_exception::ALT", name);
644
645 /*
646 *
647 * simple xxx_exception_template for the catch port-operator
648 * only with constructors, a log/match function and value redirect
649 *
650 */
651 decl = mputprintf(decl, "class %s_exception_template;\n", name);
652
653 def = mputprintf(def, "class %s_exception_template {\n", name);
654
655 /* data members */
656 /* exception-selection enum */
657 def = mputprintf(def, "%s exception_selection;\n", selection_type);
658 /* union of all possible exceptions (templates) */
659 def = mputstr(def, "union {\n");
660 for (i = 0; i < sdef->exceptions.nElements; i++) {
661 def = mputprintf(def, "const %s_template *field_%s;\n",
662 sdef->exceptions.elements[i].name,
663 sdef->exceptions.elements[i].altname);
664 }
665 def = mputstr(def, "};\n");
666 /* union of all possible value redirect pointers */
667 def = mputstr(def, "union {\n");
668 for (i = 0; i < sdef->exceptions.nElements; i++) {
669 def = mputprintf(def, "%s *ptr_%s;\n",
670 sdef->exceptions.elements[i].name,
671 sdef->exceptions.elements[i].altname);
672 }
673 def = mputstr(def, "};\n"
674 "public:\n");
675 /* constructors (for all possible template + redirect pointer pairs) */
676 for (i = 0; i < sdef->exceptions.nElements; i++) {
677 def = mputprintf(def, "%s_exception_template(const %s_template& "
678 "init_template, %s *value_ptr = NULL);\n", name,
679 sdef->exceptions.elements[i].name,
680 sdef->exceptions.elements[i].name);
681 src = mputprintf(src, "%s_exception_template::%s_exception_template"
682 "(const %s_template& init_template, %s *value_ptr)\n"
683 "{\n"
684 "exception_selection = %s_%s;\n"
685 "field_%s = &init_template;\n"
686 "ptr_%s = value_ptr;\n"
687 "}\n\n", name, name, sdef->exceptions.elements[i].name,
688 sdef->exceptions.elements[i].name, selection_prefix,
689 sdef->exceptions.elements[i].altname,
690 sdef->exceptions.elements[i].altname,
691 sdef->exceptions.elements[i].altname);
692 }
693
694 /* match function */
695 def = mputprintf(def, "boolean match(const %s_exception& other_value) "
696 "const;\n", name);
697 src = mputprintf(src, "boolean %s_exception_template::match(const "
698 "%s_exception& other_value) const\n"
699 "{\n"
700 "if (exception_selection != other_value.get_selection()) "
701 "return FALSE;\n"
702 "switch (exception_selection) {\n", name, name);
703 for (i = 0; i < sdef->exceptions.nElements; i++) {
704 src = mputprintf(src, "case %s_%s:\n"
705 "return field_%s->match(other_value.%s_field());\n",
706 selection_prefix, sdef->exceptions.elements[i].altname,
707 sdef->exceptions.elements[i].altname,
708 sdef->exceptions.elements[i].altname);
709 }
710 src = mputprintf(src, "default:\n"
711 "TTCN_error(\"Internal error: Invalid selector when matching an "
712 "exception of signature %s.\");\n"
713 "return FALSE;\n"
714 "}\n"
715 "}\n\n", dispname);
716
717 /* log_match function */
718 def = mputprintf(def, "void log_match(const %s_exception& other_value) "
719 "const;\n", name);
720 src = mputprintf(src, "void %s_exception_template::log_match(const "
721 "%s_exception& other_value) const\n"
722 "{\n"
723 "TTCN_Logger::log_event_str(\"%s, \");\n"
724 "if (exception_selection == other_value.get_selection()) {\n"
725 "switch (exception_selection) {\n", name, name, dispname);
726 for (i = 0; i < sdef->exceptions.nElements; i++) {
727 src = mputprintf(src, "case %s_%s:\n"
728 "TTCN_Logger::log_event_str(\"%s : \");\n"
729 "field_%s->log_match(other_value.%s_field());\n"
730 "break;\n", selection_prefix,
731 sdef->exceptions.elements[i].altname,
732 sdef->exceptions.elements[i].dispname,
733 sdef->exceptions.elements[i].altname,
734 sdef->exceptions.elements[i].altname);
735 }
736 src = mputstr(src, "default:\n"
737 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
738 "}\n"
739 "} else {\n"
740 "other_value.log();\n"
741 "TTCN_Logger::log_event_str(\" with \");\n"
742 "switch (exception_selection) {\n");
743 for (i = 0; i < sdef->exceptions.nElements; i++) {
744 src = mputprintf(src, "case %s_%s:\n"
745 "TTCN_Logger::log_event_str(\"%s : \");\n"
746 "field_%s->log();\n"
747 "break;\n", selection_prefix,
748 sdef->exceptions.elements[i].altname,
749 sdef->exceptions.elements[i].dispname,
750 sdef->exceptions.elements[i].altname);
751 }
752 src = mputstr(src, "default:\n"
753 "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
754 "}\n"
755 "if (match(other_value)) "
756 "TTCN_Logger::log_event_str(\" matched\");\n"
757 "else TTCN_Logger::log_event_str(\" unmatched\");\n"
758 "}\n"
759 "}\n\n");
760
761 /* set_value function */
762 def = mputprintf(def, "void set_value(const %s_exception& "
763 "source_value) const;\n", name);
764 src = mputprintf(src, "void %s_exception_template::set_value(const "
765 "%s_exception& source_value) const\n"
766 "{\n"
767 "if (exception_selection == source_value.get_selection()) {\n"
768 "switch (exception_selection) {\n", name, name);
769 for (i = 0; i < sdef->exceptions.nElements; i++) {
770 src = mputprintf(src, "case %s_%s:\n"
771 "if (ptr_%s != NULL) *ptr_%s = source_value.%s_field();\n"
772 "return;\n", selection_prefix,
773 sdef->exceptions.elements[i].altname,
774 sdef->exceptions.elements[i].altname,
775 sdef->exceptions.elements[i].altname,
776 sdef->exceptions.elements[i].altname);
777 }
778 src = mputprintf(src, "default:\n"
779 "break;\n"
780 "}\n"
781 "}\n"
782 "TTCN_error(\"Internal error: Invalid selector when performing "
783 "value redirect on an exception of signature %s.\");\n"
784 "}\n\n", dispname);
785
786 def = mputstr(def, "};\n\n");
787 /* end of class xxx_exception_template */
788
789 Free(selection_type);
790 Free(unbound_value);
791 Free(selection_prefix);
792 } /* if (sdef->exceptions.nElements > 0) */
793
794 /*
795 * template class
796 */
797
798 decl = mputprintf(decl, "class %s_template;\n", name);
799
800 def = mputprintf(def, "class %s_template {\n", name);
801
802 /* parameters */
803 for (i = 0; i < sdef->parameters.nElements; i++) {
804 def = mputprintf(def, "%s_template param_%s;\n",
805 sdef->parameters.elements[i].type,
806 sdef->parameters.elements[i].name);
807 }
808 if (sdef->return_type != NULL) {
809 def = mputprintf(def, "mutable %s_template reply_value;\n",
810 sdef->return_type);
811 }
812
813 def = mputstr(def, "public:\n");
814 /* constructor */
815 if (sdef->parameters.nElements > 0 || sdef->return_type != NULL) {
816 boolean first_param = TRUE;
817 def = mputprintf(def, "%s_template();\n", name);
818 src = mputprintf(src, "%s_template::%s_template()\n"
819 " : ", name, name);
820 for (i = 0; i < sdef->parameters.nElements; i++) {
821 if (first_param) first_param = FALSE;
822 else src = mputstr(src, ", ");
823 src = mputprintf(src, "param_%s(ANY_VALUE)",
824 sdef->parameters.elements[i].name);
825 }
826 if (sdef->return_type != NULL) {
827 if (first_param) /*first_param = FALSE*/;
828 else src = mputstr(src, ", ");
829 src = mputstr(src, "reply_value(ANY_VALUE)");
830 }
831 src = mputstr(src, "\n"
832 "{\n"
833 "}\n\n");
834 } else {
835 def = mputprintf(def, "%s_template() { }\n", name);
836 }
837
838 if (sdef->parameters.nElements == 0) {
839 /* constructor and assignment operator for parameter-less signatures */
840 if (sdef->return_type != NULL) {
841 def = mputprintf(def, "%s_template(null_type null_value);\n",
842 name);
843 src = mputprintf(src,
844 "%s_template::%s_template(null_type)\n"
845 " : reply_value(ANY_VALUE)\n"
846 "{\n"
847 "}\n\n", name, name);
848 } else {
849 def = mputprintf(def, "%s_template(null_type) { }\n",
850 name);
851 }
852 def = mputprintf(def, "inline %s_template& operator=(null_type)"
853 " { return *this; }\n", name);
854 }
855
856 /* parameter access functions */
857 for (i = 0; i < sdef->parameters.nElements; i++) {
858 def = mputprintf(def, "inline %s_template& %s() { return param_%s; }\n"
859 "inline const %s_template& %s() const { return param_%s; }\n",
860 sdef->parameters.elements[i].type,
861 sdef->parameters.elements[i].name,
862 sdef->parameters.elements[i].name,
863 sdef->parameters.elements[i].type,
864 sdef->parameters.elements[i].name,
865 sdef->parameters.elements[i].name);
866 }
867 if (sdef->return_type != NULL) {
868 def = mputprintf(def, "inline %s_template& return_value() const "
869 "{ return reply_value; }\n", sdef->return_type);
870 }
871
872 /* create_call function for creating xxx_call signature-value */
873 if (num_in > 0) {
874 def = mputprintf(def, "%s_call create_call() const;\n", name);
875 src = mputprintf(src, "%s_call %s_template::create_call() const\n"
876 "{\n"
877 "%s_call ret_val;\n", name, name, name);
878 for (i = 0; i < sdef->parameters.nElements; i++) {
879 if (sdef->parameters.elements[i].direction != PAR_OUT) {
880 src = mputprintf(src, "ret_val.%s() = param_%s.valueof();\n",
881 sdef->parameters.elements[i].name,
882 sdef->parameters.elements[i].name);
883 }
884 }
885 src = mputstr(src, "return ret_val;\n"
886 "}\n\n");
887 } else {
888 def = mputprintf(def, "inline %s_call create_call() const "
889 "{ return %s_call(); }\n", name, name);
890 }
891
892 if (!sdef->is_noblock) {
893 /* create_reply function for creating xxx_reply signature-value */
894 if (num_out > 0 || sdef->return_type != NULL) {
895 def = mputprintf(def, "%s_reply create_reply() const;\n", name);
896 src = mputprintf(src, "%s_reply %s_template::create_reply() const\n"
897 "{\n"
898 "%s_reply ret_val;\n", name, name, name);
899 for (i = 0; i < sdef->parameters.nElements; i++) {
900 if (sdef->parameters.elements[i].direction != PAR_IN) {
901 src = mputprintf(src, "ret_val.%s() = "
902 "param_%s.valueof();\n",
903 sdef->parameters.elements[i].name,
904 sdef->parameters.elements[i].name);
905 }
906 }
907 if (sdef->return_type != NULL) {
908 src = mputstr(src, "ret_val.return_value() = "
909 "reply_value.valueof();\n");
910 }
911 src = mputstr(src, "return ret_val;\n"
912 "}\n\n");
913 } else {
914 def = mputprintf(def, "inline %s_reply create_reply() const "
915 "{ return %s_reply(); }\n", name, name);
916 }
917 }
918
919 /* match_call function for matching with xxx_call signature-value */
920 if (num_in > 0) {
921 boolean first_param = TRUE;
922 def = mputprintf(def, "boolean match_call(const %s_call& match_value) "
923 "const;\n", name);
924 src = mputprintf(src, "boolean %s_template::match_call(const %s_call& "
925 "match_value) const\n"
926 "{\n"
927 "return ", name, name);
928 for (i = 0; i < sdef->parameters.nElements; i++) {
929 if (sdef->parameters.elements[i].direction != PAR_OUT) {
930 if (first_param) first_param = FALSE;
931 else src = mputstr(src, " &&\n");
932 src = mputprintf(src, "param_%s.match(match_value.%s())",
933 sdef->parameters.elements[i].name,
934 sdef->parameters.elements[i].name);
935 }
936 }
937 src = mputstr(src, ";\n"
938 "}\n\n");
939 } else {
940 def = mputprintf(def, "inline boolean match_call(const %s_call&"
941 ") const { return TRUE; }\n", name);
942 }
943
944 if (!sdef->is_noblock) {
945 if (num_out > 0 || sdef->return_type != NULL) {
946 boolean first_param = TRUE;
947 /* match_reply function for matching with xxx_reply value */
948 def = mputprintf(def, "boolean match_reply(const %s_reply& "
949 "match_value) const;\n", name);
950 src = mputprintf(src, "boolean %s_template::match_reply(const "
951 "%s_reply& match_value) const\n"
952 "{\n"
953 "return ", name, name);
954 for (i = 0; i < sdef->parameters.nElements; i++) {
955 if(sdef->parameters.elements[i].direction != PAR_IN) {
956 if (first_param) first_param = FALSE;
957 else src = mputstr(src, " &&\n");
958 src = mputprintf(src, "param_%s.match(match_value.%s())",
959 sdef->parameters.elements[i].name,
960 sdef->parameters.elements[i].name);
961 }
962 }
963 if (sdef->return_type != NULL) {
964 if (first_param) /*first_param = FALSE*/;
965 else src = mputstr(src, " &&\n");
966 src = mputstr(src,
967 "reply_value.match(match_value.return_value())");
968 }
969 src = mputstr(src, ";\n"
970 "}\n\n");
971 } else {
972 def = mputprintf(def, "inline boolean match_reply(const %s_reply&"
973 ") const { return TRUE; }\n", name);
974 }
975 }
976
977 /* set_value_template function */
978 if (sdef->return_type != NULL) {
979 def = mputprintf(def, "const %s_template& set_value_template(const "
980 "%s_template& new_template) const;\n", name, sdef->return_type);
981 src = mputprintf(src,
982 "const %s_template& %s_template::set_value_template"
983 "(const %s_template& new_template) const\n"
984 "{\n"
985 "reply_value = new_template;\n"
986 "return *this;\n"
987 "}\n\n", name, name, sdef->return_type);
988 }
989
990 /* log function */
991 def = mputstr(def, "void log() const;\n");
992 src = mputprintf(src, "void %s_template::log() const\n"
993 "{\n", name);
994 if (sdef->parameters.nElements >= 1) {
995 for (i = 0; i < sdef->parameters.nElements; i++) {
996 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
997 if (i == 0) src = mputc(src, '{');
998 else src = mputc(src, ',');
999 src = mputprintf(src, " %s := \");\n"
1000 "param_%s.log();\n", sdef->parameters.elements[i].dispname,
1001 sdef->parameters.elements[i].name);
1002 }
1003 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
1004 } else {
1005 src = mputstr(src, "TTCN_Logger::log_event_str(\"{ }\");\n");
1006 }
1007 src = mputstr(src, "}\n\n");
1008
1009 /* log_match_call function */
1010 def = mputprintf(def, "void log_match_call(const %s_call& match_value) "
1011 "const;\n", name);
1012 src = mputprintf(src, "void %s_template::log_match_call(const %s_call& "
1013 , name, name);
1014 if (num_in > 0) {
1015 boolean first_param = TRUE;
1016 src = mputstr(src, "match_value) const\n{\n");
1017 for (i = 0; i < sdef->parameters.nElements; i++) {
1018 if (sdef->parameters.elements[i].direction != PAR_OUT) {
1019 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
1020 if (first_param) {
1021 src = mputc(src, '{');
1022 first_param = FALSE;
1023 } else src = mputc(src, ',');
1024 src = mputprintf(src, " %s := \");\n"
1025 "param_%s.log_match(match_value.%s());\n",
1026 sdef->parameters.elements[i].dispname,
1027 sdef->parameters.elements[i].name,
1028 sdef->parameters.elements[i].name);
1029 }
1030 }
1031 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
1032 } else {
1033 src = mputstr(src, ") const\n{\n"
1034 "TTCN_Logger::log_event_str(\"{ } with { } matched\");\n");
1035 }
1036 src = mputstr(src, "}\n\n");
1037
1038 if (!sdef->is_noblock) {
1039 /* log_match_reply function */
1040 def = mputprintf(def, "void log_match_reply(const %s_reply& match_value) "
1041 "const;\n", name);
1042 src = mputprintf(src, "void %s_template::log_match_reply(const %s_reply& "
1043 , name, name);
1044 if (num_out > 0) {
1045 boolean first_param = TRUE;
1046 src = mputstr(src, "match_value) const\n{\n");
1047 for (i = 0; i < sdef->parameters.nElements; i++) {
1048 if (sdef->parameters.elements[i].direction != PAR_IN) {
1049 src = mputstr(src, "TTCN_Logger::log_event_str(\"");
1050 if (first_param) {
1051 src = mputc(src, '{');
1052 first_param = FALSE;
1053 } else src = mputc(src, ',');
1054 src = mputprintf(src, " %s := \");\n"
1055 "param_%s.log_match(match_value.%s());\n",
1056 sdef->parameters.elements[i].dispname,
1057 sdef->parameters.elements[i].name,
1058 sdef->parameters.elements[i].name);
1059 }
1060 }
1061 if (sdef->return_type != NULL) {
1062 src = mputstr(src, "TTCN_Logger::log_event_str(\" } value "
1063 "\");\n"
1064 "reply_value.log_match(match_value.return_value());\n");
1065 } else {
1066 src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
1067 }
1068 } else {
1069 if (sdef->return_type != NULL) {
1070 src = mputstr(src, "match_value) const\n{\n"
1071 "TTCN_Logger::log_event_str(\"{ } with { } "
1072 "matched value \");\n"
1073 "reply_value.log_match(match_value.return_value());\n");
1074 } else {
1075 src = mputstr(src, ") const\n{\n"
1076 "TTCN_Logger::log_event_str(\"{ } with { } "
1077 "matched\");\n");
1078 }
1079 }
1080 src = mputstr(src, "}\n\n");
1081 }
1082
1083 if (sdef->parameters.nElements > 0) {
1084 /* encode_text function */
1085 def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
1086 src = mputprintf(src, "void %s_template::encode_text(Text_Buf& "
1087 "text_buf) const\n"
1088 "{\n", name);
1089 for (i = 0; i < sdef->parameters.nElements; i++) {
1090 src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
1091 sdef->parameters.elements[i].name);
1092 }
1093 src = mputstr(src, "}\n\n");
1094 /* decode_text function */
1095 def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
1096 src = mputprintf(src, "void %s_template::decode_text(Text_Buf& "
1097 "text_buf)\n"
1098 "{\n", name);
1099 for (i = 0; i < sdef->parameters.nElements; i++) {
1100 src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
1101 sdef->parameters.elements[i].name);
1102 }
1103 src = mputstr(src, "}\n\n");
1104 } else {
1105 def = mputstr(def, "inline void encode_text(Text_Buf&) const "
1106 "{ }\n"
1107 "inline void decode_text(Text_Buf&) { }\n");
1108 }
1109
1110 /* end of template definition */
1111 def = mputstr(def, "};\n\n");
1112
1113 output->header.class_decls = mputstr(output->header.class_decls, decl);
1114 Free(decl);
1115
1116 output->header.class_defs = mputstr(output->header.class_defs, def);
1117 Free(def);
1118
1119 output->source.methods = mputstr(output->source.methods, src);
1120 Free(src);
1121 }
This page took 0.059137 seconds and 5 git commands to generate.