added any2unistr predefined function (artf724008)
[deliverable/titan.core.git] / compiler2 / ttcn3 / port.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 * Cserveni, Akos
13 * Delic, Adam
14 * Feher, Csaba
15 * Forstner, Matyas
16 * Kovacs, Ferenc
17 * Kremer, Peter
18 * Raduly, Csaba
19 * Szabados, Kristof
20 * Szabo, Janos Zoltan – initial implementation
21 *
22 ******************************************************************************/
970ed795
EL
23#include <stdlib.h>
24#include <string.h>
25#include <errno.h>
26
27#include "../../common/memory.h"
28#include "../../common/path.h"
29#include "../../common/version_internal.h"
30#include "../../common/userinfo.h"
31
32#include "port.h"
33#include "../datatypes.h"
34#include "compiler.h"
35#include "../main.hh"
36#include "../error.h"
37
38/* macro used in version_internal.h */
39#undef COMMENT_PREFIX
40#define COMMENT_PREFIX "// "
41
42#ifndef NDEBUG
43static const char *functypes[] = {"convert", "fast", "backtrack", "sliding"};
44#endif
45
46static char *generate_send_mapping(char *src, const port_def *pdef,
47 const port_msg_mapped_type *mapped_type, boolean has_address)
48{
49 size_t i;
50 boolean has_buffer = FALSE, has_discard = FALSE, report_error = FALSE;
51 if (pdef->testport_type == INTERNAL) {
52 src = mputstr(src, "if (destination_component == SYSTEM_COMPREF) "
53 "TTCN_error(\"Message cannot be sent to system on internal port "
54 "%s.\", port_name);\n");
55 }
56 for (i = 0; i < mapped_type->nTargets; i++) {
57 const port_msg_type_mapping_target *target =
58 mapped_type->targets + i;
59 boolean has_condition = FALSE; /* TRUE when an if statement has been
60 generated around the call of the encoder function */
61 if (target->mapping_type == M_DISCARD) {
62 /* "discard" should always be the last mapping */
63 if (i != mapped_type->nTargets - 1)
64 FATAL_ERROR("generate_send_mapping(): invalid discard mapping");
65 has_discard = TRUE;
66 break;
67 } else if (target->mapping_type == M_DECODE && !has_buffer) {
68 src = mputstr(src, "TTCN_Buffer ttcn_buffer(send_par);\n");
69 /* has_buffer will be set to TRUE later */
70 }
71 if (mapped_type->nTargets > 1) src = mputstr(src, "{\n");
72 switch (target->mapping_type) {
73 case M_FUNCTION:
74#ifndef NDEBUG
75 src = mputprintf(src, "// out mapping with a prototype(%s) function\n",
76 functypes[target->mapping.function.prototype]);
77#endif
78 switch (target->mapping.function.prototype) {
79 case PT_CONVERT:
80 src = mputprintf(src, "%s mapped_par(%s(send_par));\n",
81 target->target_name, target->mapping.function.name);
82 break;
83 case PT_FAST:
84 src = mputprintf(src, "%s mapped_par;\n"
85 "%s(send_par, mapped_par);\n",
86 target->target_name, target->mapping.function.name);
87 break;
88 case PT_SLIDING:
89 /* Yes, it is possible to use a "prototype(sliding)" decoder
90 * for out mapping, even a compiler-generated one.
91 * The source must be octetstring for the first parameter
92 * of a sliding decoder. */
93 src = mputprintf(src, "%s mapped_par;\n"
94 "OCTETSTRING send_copy(send_par);\n"
95 "if (%s(send_copy, mapped_par) != 1) {\n",
96 target->target_name, target->mapping.function.name);
97 has_condition = TRUE;
98 break;
99 case PT_BACKTRACK:
100 src = mputprintf(src, "%s mapped_par;\n"
101 "if (%s(send_par, mapped_par) == 0) {\n",
102 target->target_name, target->mapping.function.name);
103 has_condition = TRUE;
104 break;
105 default:
106 FATAL_ERROR("generate_send_mapping(): invalid function type");
107 }
108 break;
109 case M_ENCODE:
110#ifndef NDEBUG
111 src = mputstr(src, "// out mapping with a built-in encoder\n");
112#endif
113 src = mputstr(src, target->mapping.encdec.errorbehavior);
114 src = mputprintf(src, "TTCN_Buffer ttcn_buffer;\n"
115 "send_par.encode(%s_descr_, ttcn_buffer, TTCN_EncDec::CT_%s",
116 target->mapping.encdec.typedescr_name,
117 target->mapping.encdec.encoding_type);
118 if (target->mapping.encdec.encoding_options != NULL)
119 src = mputprintf(src, ", %s",
120 target->mapping.encdec.encoding_options);
121 src = mputprintf(src, ");\n"
122 "%s mapped_par;\n"
123 "ttcn_buffer.get_string(mapped_par);\n", target->target_name);
124 break;
125 case M_DECODE:
126#ifndef NDEBUG
127 src = mputstr(src, "// out mapping with a built-in decoder\n");
128#endif
129 if (has_buffer) src = mputstr(src, "ttcn_buffer.rewind();\n");
130 else has_buffer = TRUE;
131 src = mputstr(src, target->mapping.encdec.errorbehavior);
132 src = mputprintf(src, "TTCN_EncDec::clear_error();\n"
133 "%s mapped_par;\n"
134 "mapped_par.decode(%s_descr_, ttcn_buffer, TTCN_EncDec::CT_%s",
135 target->target_name, target->mapping.encdec.typedescr_name,
136 target->mapping.encdec.encoding_type);
137 if (target->mapping.encdec.encoding_options != NULL)
138 src = mputprintf(src, ", %s",
139 target->mapping.encdec.encoding_options);
140 src = mputstr(src, ");\n"
141 "if (TTCN_EncDec::get_last_error_type() == "
142 "TTCN_EncDec::ET_NONE) {\n");
143 has_condition = TRUE;
144 break;
145 default:
146 FATAL_ERROR("generate_send_mapping(): invalid mapping type");
147 }
148 src = mputprintf(src, "if (TTCN_Logger::log_this_event("
149 "TTCN_Logger::PORTEVENT_DUALSEND)) {\n"
150 "TTCN_Logger::log_dualport_map(0, \"%s\",\n"
151 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_DUALSEND, TRUE),"
152 " mapped_par.log(), TTCN_Logger::end_event_log2str()), 0);\n"
153 "}\n", target->target_dispname);
154 if (has_address) {
155 src = mputstr(src,
156 "outgoing_send(mapped_par, &destination_address);\n");
157 } else {
158 if (pdef->testport_type != INTERNAL) {
159 src = mputprintf(src, "if (destination_component == "
160 "SYSTEM_COMPREF) outgoing_send(mapped_par%s);\n"
161 "else {\n", pdef->testport_type == ADDRESS ? ", NULL" : "");
162 }
163 src = mputprintf(src, "Text_Buf text_buf;\n"
164 "prepare_message(text_buf, \"%s\");\n"
165 "mapped_par.encode_text(text_buf);\n"
166 "send_data(text_buf, destination_component);\n",
167 target->target_dispname);
168 if (pdef->testport_type != INTERNAL) src = mputstr(src, "}\n");
169 }
170 if (has_condition) {
171 src = mputstr(src, "return;\n"
172 "}\n");
173 report_error = TRUE;
174 }
175 if (mapped_type->nTargets > 1) src = mputstr(src, "}\n");
176 }
177 if (has_discard) {
178 if (mapped_type->nTargets > 1) {
179 /* there are other mappings, which failed */
180 src = mputprintf(src,
181 "TTCN_Logger::log_dualport_discard(0, \"%s\", port_name, TRUE);\n"
182 , mapped_type->dispname);
183 } else {
184 /* this is the only mapping */
185 src = mputprintf(src,
186 "TTCN_Logger::log_dualport_discard(0, \"%s\", port_name, FALSE);\n"
187 , mapped_type->dispname);
188 }
189 } else if (report_error) {
190 src = mputprintf(src, "TTCN_error(\"Outgoing message of type %s could "
191 "not be handled by the type mapping rules on port %%s.\", "
192 "port_name);\n", mapped_type->dispname);
193 }
194 return src;
195}
196
197static char *generate_incoming_mapping(char *src, const port_def *pdef,
198 const port_msg_mapped_type *mapped_type)
199{
200 size_t i;
201 boolean has_buffer = FALSE, has_discard = FALSE, report_error = FALSE;
202 for (i = 0; i < mapped_type->nTargets; i++) {
203 const port_msg_type_mapping_target *target =
204 mapped_type->targets + i;
205 boolean has_condition = FALSE;
206 if (target->mapping_type == M_DISCARD) {
207 /* "discard" should always be the last mapping */
208 if (i != mapped_type->nTargets - 1) FATAL_ERROR( \
209 "generate_incoming_mapping(): invalid discard mapping");
210 has_discard = TRUE;
211 break;
212 } else if (target->mapping_type == M_DECODE && !has_buffer) {
213 src = mputstr(src, "TTCN_Buffer ttcn_buffer(incoming_par);\n");
214 /* has_buffer will be set to TRUE later */
215 }
216 if (mapped_type->nTargets > 1) src = mputstr(src, "{\n");
217 switch (target->mapping_type) {
218 case M_FUNCTION:
219#ifndef NDEBUG
220 src = mputprintf(src, "// in mapping with a prototype(%s) function\n",
221 functypes[target->mapping.function.prototype]);
222#endif
223 switch (target->mapping.function.prototype) {
224 case PT_CONVERT:
225 src = mputprintf(src, "%s *mapped_par = "
226 "new %s(%s(incoming_par));\n",
227 target->target_name, target->target_name,
228 target->mapping.function.name);
229 break;
230 case PT_FAST:
231 src = mputprintf(src, "%s *mapped_par = new %s;\n"
232 "try {\n"
233 "%s(incoming_par, *mapped_par);\n"
234 "} catch (...) {\n"
235 "delete mapped_par;\n"
236 "throw;\n"
237 "}\n", target->target_name, target->target_name,
238 target->mapping.function.name);
239 break;
240 case PT_SLIDING:
241 src = mputprintf(src,
242 "slider += incoming_par;\n" /* hack */
243 "for(;;){\n"
244 "%s *mapped_par = new %s;\n"
245 "int decoding_result;\n"
246 "try {\n"
247 "decoding_result = %s(slider, *mapped_par);\n"
248 "} catch (...) {\n"
249 "delete mapped_par;\n"
250 "throw;\n"
251 "}\n"
252 "if (decoding_result==0) {\n", target->target_name,
253 target->target_name, target->mapping.function.name);
254 has_condition = TRUE;
255 break;
256 case PT_BACKTRACK:
257 src = mputprintf(src, "%s *mapped_par = new %s;\n"
258 "boolean success_flag;\n"
259 "try {\n"
260 "success_flag = %s(incoming_par, *mapped_par) == 0;\n"
261 "} catch (...) {\n"
262 "delete mapped_par;\n"
263 "throw;\n"
264 "}\n"
265 "if (success_flag) {\n", target->target_name,
266 target->target_name, target->mapping.function.name);
267 has_condition = TRUE;
268 break;
269 default:
270 FATAL_ERROR("generate_incoming_mapping(): " \
271 "invalid function type");
272 }
273 break;
274 case M_ENCODE:
275#ifndef NDEBUG
276 src = mputstr(src, "// in mapping with a built-in encoder\n");
277#endif
278 src = mputstr(src, target->mapping.encdec.errorbehavior);
279 src = mputprintf(src, "TTCN_Buffer ttcn_buffer;\n"
280 "send_par.encode(%s_descr_, ttcn_buffer, TTCN_EncDec::CT_%s",
281 target->mapping.encdec.typedescr_name,
282 target->mapping.encdec.encoding_type);
283 if (target->mapping.encdec.encoding_options != NULL)
284 src = mputprintf(src, ", %s",
285 target->mapping.encdec.encoding_options);
286 src = mputprintf(src, ");\n"
287 "%s *mapped_par = new %s;\n"
288 "ttcn_buffer.get_string(*mapped_par);\n", target->target_name,
289 target->target_name);
290 break;
291 case M_DECODE:
292#ifndef NDEBUG
293 src = mputstr(src, "// in mapping with a built-in decoder\n");
294#endif
295 if (has_buffer) src = mputstr(src, "ttcn_buffer.rewind();\n");
296 else has_buffer = TRUE;
297 src = mputstr(src, target->mapping.encdec.errorbehavior);
298 src = mputprintf(src, "TTCN_EncDec::clear_error();\n"
299 "%s *mapped_par = new %s;\n"
300 "try {\n"
301 "mapped_par->decode(%s_descr_, ttcn_buffer, "
302 "TTCN_EncDec::CT_%s", target->target_name,
303 target->target_name, target->mapping.encdec.typedescr_name,
304 target->mapping.encdec.encoding_type);
305 if (target->mapping.encdec.encoding_options != NULL)
306 src = mputprintf(src, ", %s",
307 target->mapping.encdec.encoding_options);
308 src = mputstr(src, ");\n"
309 "} catch (...) {\n"
310 "delete mapped_par;\n"
311 "throw;\n"
312 "}\n"
313 "if (TTCN_EncDec::get_last_error_type() == "
314 "TTCN_EncDec::ET_NONE) {\n");
315 has_condition = TRUE;
316 break;
317 default:
318 FATAL_ERROR("generate_incoming_mapping(): invalid mapping type");
319 }
320 src = mputprintf(src, "msg_tail_count++;\n"
321 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_DUALRECV)) "
322 "{\n"
323 "TTCN_Logger::log_dualport_map(1, \"%s\",\n"
324 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_DUALRECV, TRUE),"
325 " mapped_par->log(), TTCN_Logger::end_event_log2str()),\n"
326 "msg_tail_count);\n"
327 "}\n"
328 "msg_queue_item *new_item = new msg_queue_item;\n"
329 "new_item->item_selection = MESSAGE_%lu;\n"
330 "new_item->message_%lu = mapped_par;\n"
331 "new_item->sender_component = sender_component;\n",
332 target->target_dispname, (unsigned long) target->target_index,
333 (unsigned long) target->target_index);
334 if (pdef->testport_type == ADDRESS) {
335 src = mputprintf(src, "if (sender_address != NULL) "
336 "new_item->sender_address = new %s(*sender_address);\n"
337 "else new_item->sender_address = NULL;\n",
338 pdef->address_name);
339 }
340 src = mputstr(src, "append_to_msg_queue(new_item);\n");
341 if (has_condition) {
342 if (pdef->has_sliding
343 && target->mapping_type == M_FUNCTION
344 && target->mapping.function.prototype == PT_SLIDING) {
345 src = mputstr(src,
346 "continue;\n"
347 "} else delete mapped_par;\n"
348 "if (decoding_result==2) return; }\n");
349 }
350 else {
351 src = mputstr(src, "return;\n"
352 "} else delete mapped_par;\n");
353 }
354 report_error = TRUE;
355 }
356 if (mapped_type->nTargets > 1) src = mputstr(src, "}\n");
357 } /* next mapping target */
358 if (has_discard) {
359 if (mapped_type->nTargets > 1) {
360 /* there are other mappings, which failed */
361 src = mputprintf(src,
362 "TTCN_Logger::log_dualport_discard(1, \"%s\", port_name, TRUE);\n"
363 , mapped_type->dispname);
364 } else {
365 /* this is the only mapping */
366 src = mputprintf(src,
367 "TTCN_Logger::log_dualport_discard(1, \"%s\", port_name, FALSE);\n"
368 , mapped_type->dispname);
369 }
370 } else if (report_error) {
371 src = mputprintf(src, "TTCN_error(\"Incoming message of type %s could "
372 "not be handled by the type mapping rules on port %%s.\", "
373 "port_name);\n", mapped_type->dispname);
374 }
375 return src;
376}
377
378/** Generates "receive(const COMPONENT_template&, COMPONENT *)" or
379 * "receive(const ADDRESS_template&, ADDRESS *)".
380 * These are called from PORT::any_receive for "any port.receive"
381 *
382 * @param def_ptr pointer to a string which will be written to the header
383 * @param src_ptr pointer to a string which will be written as the source file
384 * @param pdef pointer to a structure with information about the port
385 * @param class_name
386 * @param is_check true if writing the check-receive member
387 * @param is_trigger true if writing the trigger member
388 * @param is_address true if the port has the "address" extension
389 */
390static void generate_generic_receive(char **def_ptr, char **src_ptr,
391 const port_def *pdef, const char *class_name, boolean is_check,
392 boolean is_trigger, boolean is_address)
393{
394 char *def = *def_ptr, *src = *src_ptr;
395 const char *function_name, *operation_name, *failed_str, *failed_status;
396 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
397 const char *logger_operation;
398
399 if (is_trigger) {
400 function_name = "trigger";
401 logger_operation = function_name;
402 operation_name = "Trigger";
403 failed_str = "will drop a message";
404 failed_status = "ALT_REPEAT";
405 } else {
406 if (is_check) {
407 function_name = "check_receive";
408 logger_operation = "check__receive";
409 operation_name = "Check-receive";
410 } else {
411 function_name = "receive";
412 logger_operation = function_name;
413 operation_name = "Receive";
414 }
415 failed_str = "failed";
416 failed_status = "ALT_NO";
417 }
418
419 def = mputprintf(def, "alt_status %s(const %s_template& "
420 "sender_template, %s *sender_ptr);\n", function_name, sender_type,
421 sender_type);
422 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
423 "sender_template, %s *sender_ptr)\n"
424 "{\n"
425 "msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;\n"
426 "if (msg_queue_head == NULL) {\n"
427 "if (is_started) return ALT_MAYBE;\n"
428 "else {\n"
429 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
430 "port %%s failed: Port is not started and the queue is empty.\","
431 " port_name);\n"
432 "return ALT_NO;\n"
433 "}\n"
434 "} else ", class_name, function_name, sender_type, sender_type);
435 if (is_address) {
436 src = mputprintf(src, "if (my_head->sender_component != "
437 "SYSTEM_COMPREF) {\n"
438 "TTCN_Logger::log(TTCN_Logger::MATCHING_MMUNSUCC, \"Matching "
439 "on port %%s %s: Sender of the first message in the queue is "
440 "not the system.\", port_name);\n", failed_str);
441 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
442 src = mputprintf(src, "return %s;\n"
443 "} else if (my_head->sender_address == NULL) {\n"
444 "TTCN_error(\"%s operation on port %%s requires the address "
445 "of the sender, which was not given by the test port.\", "
446 "port_name);\n"
447 "return ALT_NO;\n"
448 "} else if (!sender_template.match("
449 "*my_head->sender_address)) {\n"
450 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMUNSUCC)) "
451 "{\n"
452 "TTCN_Logger::begin_event(TTCN_Logger::MATCHING_MMUNSUCC);\n"
453 "TTCN_Logger::log_event(\"Matching on port %%s %s: "
454 "Sender address of the first message in the queue does not "
455 "match the from clause: \", port_name);\n"
456 "sender_template.log_match(*my_head->sender_address);\n"
457 "TTCN_Logger::end_event();\n"
458 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,\n"
459 "port_name, my_head->sender_component,\n"
460 "TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,\n"
461 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_MMUNSUCC, TRUE),"
462 " sender_template.log_match(*my_head->sender_address),\n"
463 " TTCN_Logger::end_event_log2str())"
464 ");\n"
465 "}\n", failed_status, operation_name, failed_str);
466 } else {
467 src = mputprintf(src, "if (!sender_template.match("
468 "my_head->sender_component)) {\n"
469 "const TTCN_Logger::Severity log_sev = "
470 "my_head->sender_component==SYSTEM_COMPREF?"
471 "TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;\n"
472 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
473 "TTCN_Logger::begin_event(log_sev);\n"
474 "TTCN_Logger::log_event(\"Matching on port %%s %s: "
475 "Sender of the first message in the queue does not match the "
476 "from clause: \", port_name);\n"
477 "sender_template.log_match(my_head->sender_component);\n"
478 "TTCN_Logger::end_event();\n"
479 "}\n", failed_str);
480 }
481 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
482 src = mputprintf(src, "return %s;\n"
483 "} else {\n"
484 "if (sender_ptr != NULL) *sender_ptr = %smy_head->%s;\n",
485 failed_status, is_address ? "*" : "",
486 is_address ? "sender_address" : "sender_component");
487
488 if (is_address) {
489 src = mputprintf(src, "TTCN_Logger::log(TTCN_Logger::MATCHING_MMSUCCESS"
490 ", \"Matching on port %%s succeeded.\", port_name);\n"
491 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MMRECV)) "
492 "{\n"
493 "TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::%s__op,\n"
494 "SYSTEM_COMPREF, CHARSTRING(0, NULL),\n"
495 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMRECV, TRUE), "
496 "my_head->sender_address->log(), TTCN_Logger::end_event_log2str()),\n"
497 "msg_head_count+1);\n"
498 "}\n", logger_operation);
499 } else {
500 size_t msg_idx;
501 src = mputstr(src, "TTCN_Logger::log("
502 "my_head->sender_component==SYSTEM_COMPREF?"
503 "TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS"
504 ", \"Matching on port %s succeeded.\", port_name);\n"
505 "const TTCN_Logger::Severity log_sev = "
506 "my_head->sender_component==SYSTEM_COMPREF?"
507 "TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;\n"
508 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
509 "switch (my_head->item_selection) {\n");
510 for (msg_idx = 0; msg_idx < pdef->msg_in.nElements; msg_idx++) {
511 const port_msg_type *message_type = pdef->msg_in.elements + msg_idx;
512 src = mputprintf(src,
513 "case MESSAGE_%lu:\n"
514 "TTCN_Logger::log_msgport_recv(port_name, TitanLoggerApiSimple::Msg__port__recv_operation::%s__op,\n"
515 "my_head->sender_component, CHARSTRING(0, NULL),\n"
516 "(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(\": %s: \"),\n"
517 "my_head->message_%lu->log(), TTCN_Logger::end_event_log2str()), msg_head_count+1);\n"
518 "break;\n",
519 (unsigned long)msg_idx, logger_operation, message_type->dispname, (unsigned long)msg_idx);
520 }
521 src = mputstr(src,
522 "default:\n"
523 "TTCN_error(\"Internal error: unknown message\");\n"
524 "}\n"
525 "}\n");
526 }
527
528 if (!is_check) src = mputstr(src, "remove_msg_queue_head();\n");
529 src = mputstr(src, "return ALT_YES;\n"
530 "}\n"
531 "}\n\n");
532
533 *def_ptr = def;
534 *src_ptr = src;
535}
536
537static void generate_receive(char **def_ptr, char **src_ptr,
538 const port_def *pdef, const char *class_name, size_t message_index,
539 boolean is_check, boolean is_trigger, boolean is_address)
540{
541 char *def = *def_ptr, *src = *src_ptr;
542 const port_msg_type *message_type = pdef->msg_in.elements + message_index;
543 const char *function_name, *operation_name, *failed_str, *failed_status;
544 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
545 const char *logger_operation;
546
547 if (is_trigger) {
548 function_name = "trigger";
549 logger_operation = function_name;
550 operation_name = "Trigger";
551 failed_str = "will drop a message";
552 failed_status = "ALT_REPEAT";
553 } else {
554 if (is_check) {
555 function_name = "check_receive";
556 logger_operation = "check__receive";
557 operation_name = "Check-receive";
558 } else {
559 function_name = "receive";
560 logger_operation = function_name;
561 operation_name = "Receive";
562 }
563 failed_str = "failed";
564 failed_status = "ALT_NO";
565 }
566
567 def = mputprintf(def, "alt_status %s(const %s_template& value_template, "
568 "%s *value_ptr, const %s_template& sender_template, %s "
569 "*sender_ptr);\n", function_name, message_type->name,
570 message_type->name, sender_type, sender_type);
571
572 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
573 "value_template, %s *value_ptr, const %s_template& "
574 "sender_template, %s *sender_ptr)\n"
575 "{\n"
576 "msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;\n"
577 "if (msg_queue_head == NULL) {\n"
578 "if (is_started) return ALT_MAYBE;\n"
579 "else {\n"
580 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
581 "port %%s failed: Port is not started and the queue is empty.\", "
582 "port_name);\n"
583 "return ALT_NO;\n"
584 "}\n"
585 "} else ", class_name, function_name, message_type->name,
586 message_type->name, sender_type, sender_type);
587 if (is_address) {
588 src = mputprintf(src, "if (my_head->sender_component != "
589 "SYSTEM_COMPREF) {\n"
590 "TTCN_Logger::log(TTCN_Logger::MATCHING_MMUNSUCC, \"Matching "
591 "on port %%s %s: Sender of the first message in the queue is "
592 "not the system.\", port_name);\n", failed_str);
593 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
594 src = mputprintf(src, "return %s;\n"
595 "} else if (my_head->sender_address == NULL) {\n"
596 "TTCN_error(\"%s operation on port %%s requires the address "
597 "of the sender, which was not given by the test port.\", "
598 "port_name);\n"
599 "return ALT_NO;\n"
600 "} else if (!sender_template.match("
601 "*my_head->sender_address)) {\n"
602 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMUNSUCC)) "
603 "{\n"
604 "TTCN_Logger::begin_event(TTCN_Logger::MATCHING_MMUNSUCC);\n"
605 "TTCN_Logger::log_event(\"Matching on port %%s %s: "
606 "Sender address of the first message in the queue does not "
607 "match the from clause: \", port_name);\n"
608 "sender_template.log_match(*my_head->sender_address);\n"
609 "TTCN_Logger::end_event();\n"
610 "}\n", failed_status, operation_name, failed_str);
611 } else {
612 src = mputprintf(src, "if (!sender_template.match("
613 "my_head->sender_component)) {\n"
614 "const TTCN_Logger::Severity log_sev = "
615 "my_head->sender_component==SYSTEM_COMPREF?"
616 "TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC;\n"
617 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
618 "TTCN_Logger::begin_event(log_sev);\n"
619 "TTCN_Logger::log_event(\"Matching on port %%s %s: "
620 "Sender of the first message in the queue does not match the "
621 "from clause: \", port_name);\n"
622 "sender_template.log_match(my_head->sender_component);\n"
623 "TTCN_Logger::end_event();\n"
624 "}\n", failed_str);
625 }
626 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
627 src = mputprintf(src, "return %s;\n"
628 "} else if (my_head->item_selection != MESSAGE_%lu) {\n"
629 "TTCN_Logger::log(%s, \"Matching on port %%s %s: "
630 "Type of the first message in the queue is not %s.\", "
631 "port_name);\n", failed_status, (unsigned long) message_index,
632 is_address ? "TTCN_Logger::MATCHING_MMUNSUCC" :
633 "my_head->sender_component==SYSTEM_COMPREF?"
634 "TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC",
635 failed_str, message_type->dispname);
636 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
637 src = mputprintf(src, "return %s;\n"
3abe9331 638 "} else if (!value_template.match(*my_head->message_%lu%s)) {\n",
639 failed_status, (unsigned long) message_index,
640 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
641 src = mputprintf(src,
642 "const TTCN_Logger::Severity log_sev = %s;\n"
643 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
644 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,\n"
645 "port_name, my_head->sender_component,\n"
646 "TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,\n"
647 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 648 " value_template.log_match(*my_head->message_%lu%s),\n"
970ed795
EL
649 " TTCN_Logger::end_event_log2str())"
650 ");\n"
651 "}\n",
652 (is_address ?
653 "TTCN_Logger::MATCHING_MMUNSUCC" :
654 "my_head->sender_component==SYSTEM_COMPREF ? "
655 "TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC"),
3abe9331 656 (unsigned long) message_index,
657 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
658 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
659 src = mputprintf(src, "return %s;\n"
660 "} else {\n"
661 "if (value_ptr != NULL) *value_ptr = *my_head->message_%lu;\n"
662 "if (sender_ptr != NULL) *sender_ptr = %smy_head->%s;\n",
663 failed_status, (unsigned long) message_index, is_address ? "*" : "",
664 is_address ? "sender_address" : "sender_component");
665
666 if (is_address) {
667 src = mputprintf(src,
668 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMSUCCESS)) "
669 "{\n"
670 "TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,\n"
671 "port_name, SYSTEM_COMPREF,\n"
672 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_MMSUCCESS, TRUE),"
3abe9331 673 " value_template.log_match(*my_head->message_%lu%s),\n"
970ed795
EL
674 " TTCN_Logger::end_event_log2str()));\n"
675 "}\n"
676 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MMRECV)) "
677 "{\n"
678 "TTCN_Logger::log_msgport_recv(port_name, "
679 "TitanLoggerApiSimple::Msg__port__recv_operation::%s__op, my_head->sender_component,\n"
680 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMRECV,TRUE),"
681 "my_head->sender_address->log(), TTCN_Logger::end_event_log2str()),\n"
682 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMRECV,TRUE),"
683 " TTCN_Logger::log_event_str(\": %s : \"),\n"
684 "my_head->message_%lu->log(), TTCN_Logger::end_event_log2str()),\n"
685 "msg_head_count+1);\n"
3abe9331 686 "}\n", (unsigned long) message_index,
687 (omit_in_value_list ? ", TRUE" : ""), logger_operation,
970ed795
EL
688 message_type->dispname, (unsigned long) message_index);
689 } else {
690 src = mputprintf(src,
691 "TTCN_Logger::Severity log_sev = "
692 "my_head->sender_component==SYSTEM_COMPREF?"
693 "TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;\n"
694 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
695 "TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,\n"
696 "port_name, my_head->sender_component,\n"
697 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 698 " value_template.log_match(*my_head->message_%lu%s),\n"
970ed795
EL
699 " TTCN_Logger::end_event_log2str()));\n"
700 "}\n"
701 "log_sev = my_head->sender_component==SYSTEM_COMPREF?"
702 "TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;\n"
703 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
704 "TTCN_Logger::log_msgport_recv(port_name, "
705 "TitanLoggerApiSimple::Msg__port__recv_operation::%s__op,\n"
706 "my_head->sender_component, CHARSTRING(0, NULL),\n"
707 "(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(\": %s : \"),\n"
708 "my_head->message_%lu->log(), TTCN_Logger::end_event_log2str()),\n"
709 "msg_head_count+1);\n"
3abe9331 710 "}\n", (unsigned long) message_index,
711 (omit_in_value_list ? ", TRUE" : ""), logger_operation,
970ed795
EL
712 message_type->dispname, (unsigned long) message_index);
713 }
714
715 if (!is_check) src = mputstr(src, "remove_msg_queue_head();\n");
716 src = mputstr(src, "return ALT_YES;\n"
717 "}\n"
718 "}\n\n");
719
720 *def_ptr = def;
721 *src_ptr = src;
722}
723
724typedef enum { GETCALL, GETREPLY, CATCH } getop_t;
725enum { NOT_ADDRESS = 0, IS_ADDRESS };
726enum { NOT_CHECK = 0, IS_CHECK };
727
728/** Writes (check_)?getcall, (check_)?getreply, get_exception and check_catch methods.
729 * These are called from PORT::any(_check)?_(getcall|getreply|catch) and
730 * PORT::check; they are the implementation of "any port.getcall" etc.
731 *
732 * @param getop the operation (call, reply or catch)
733 * @param def_ptr pointer to a string which will be written to the header
734 * @param src_ptr pointer to a string which will be written as the source file
735 * @param pdef
736 * @param class_name
737 * @param is_check
738 * @param is_address
739 */
740static void generate_generic_getop(getop_t getop,
741 char **def_ptr, char **src_ptr, const port_def *pdef,
742 const char *class_name, boolean is_check, boolean is_address)
743{
744 char *def = *def_ptr, *src = *src_ptr;
745 const char *function_name = NULL, *operation_name = NULL,
746 *entity_name_prefix = NULL, *entity_name = NULL;
747 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
748 size_t i;
749
750 switch (getop) {
751 case GETCALL:
752 function_name = is_check ? "check_getcall" : "getcall";
753 operation_name = is_check ? "Check-getcall" : "Getcall";
754 entity_name_prefix = "a";
755 entity_name = "call";
756 break;
757 case GETREPLY:
758 function_name = is_check ? "check_getreply" : "getreply";
759 operation_name = is_check ? "Check-getreply" : "Getreply";
760 entity_name_prefix = "a";
761 entity_name = "reply";
762 break;
763 case CATCH:
764 function_name = is_check ? "check_catch" : "get_exception";
765 operation_name = is_check ? "Check-catch" : "Catch";
766 entity_name_prefix = "an";
767 entity_name = "exception";
768 }
769
770 def = mputprintf(def, "alt_status %s(const %s_template& "
771 "sender_template, %s *sender_ptr);\n", function_name, sender_type,
772 sender_type);
773 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
774 "sender_template, %s *sender_ptr)\n"
775 "{\n"
776 "if (proc_queue_head == NULL) {\n"
777 "if (is_started) return ALT_MAYBE;\n"
778 "else {\n"
779 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
780 "port %%s failed: Port is not started and the queue is empty.\", "
781 "port_name);\n"
782 "return ALT_NO;\n"
783 "}\n", class_name, function_name, sender_type, sender_type);
784 if (is_address) {
785 src = mputprintf(src, "} else if (proc_queue_head->sender_component "
786 "!= SYSTEM_COMPREF) {\n"
787 "TTCN_Logger::log(TTCN_Logger::MATCHING_PMUNSUCC, \"Matching "
788 "on port %%s failed: Sender of the first entity in the queue is"
789 " not the system.\", port_name);\n"
790 "return ALT_NO;\n"
791 "} else if (proc_queue_head->sender_address == NULL) {\n"
792 "TTCN_error(\"%s operation on port %%s requires the address "
793 "of the sender, which was not given by the test port.\", "
794 "port_name);\n"
795 "return ALT_NO;\n"
796 "} else if (!sender_template.match("
797 "*proc_queue_head->sender_address)) {\n"
798 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
799 "{\n"
800 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
801 "port_name, SYSTEM_COMPREF,\n"
802 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
803 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),"
804 " sender_template.log_match(*proc_queue_head->sender_address), "
805 " TTCN_Logger::end_event_log2str()));\n"
806 "}\n"
807 "return ALT_NO;\n", operation_name);
808 } else {
809 src = mputstr(src, "} else if (!sender_template.match("
810 "proc_queue_head->sender_component)) {\n"
811 "const TTCN_Logger::Severity log_sev = "
812 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
813 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
814 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
815 "TTCN_Logger::begin_event(log_sev);\n"
816 "TTCN_Logger::log_event(\"Matching on port %s failed: "
817 "Sender of the first entity in the queue does not match the "
818 "from clause: \", port_name);\n"
819 "sender_template.log_match(proc_queue_head->sender_component);\n"
820 "TTCN_Logger::end_event();\n"
821 "}\n"
822 "return ALT_NO;\n");
823 }
824 src = mputstr(src, "} else switch (proc_queue_head->item_selection) {\n");
825 switch (getop) {
826 case GETCALL:
827 for (i = 0; i < pdef->proc_in.nElements; i++) {
828 src = mputprintf(src, "case CALL_%lu:\n", (unsigned long) i);
829 }
830 break;
831 case GETREPLY:
832 for (i = 0; i < pdef->proc_out.nElements; i++) {
833 if (!pdef->proc_out.elements[i].is_noblock)
834 src = mputprintf(src, "case REPLY_%lu:\n", (unsigned long) i);
835 }
836 break;
837 case CATCH:
838 for (i = 0; i < pdef->proc_out.nElements; i++) {
839 if (pdef->proc_out.elements[i].has_exceptions)
840 src = mputprintf(src, "case EXCEPTION_%lu:\n",
841 (unsigned long) i);
842 }
843 }
844 src = mputstr(src, "{\n"
845 "if (sender_ptr != NULL) *sender_ptr = ");
846 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
847 else src = mputstr(src, "proc_queue_head->sender_component;\n");
848
849 if (is_address) {
850 src = mputprintf(src, "TTCN_Logger::log("
851 "TTCN_Logger::MATCHING_PMSUCCESS, \"Matching on port %%s "
852 "succeeded.\", port_name);\n"
853 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMIN)) {\n"
854 "TTCN_Logger::log_procport_recv(port_name, "
855 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component,\n"
856 "%s, CHARSTRING(0, NULL), msg_head_count+1);\n"
857 "}\n", entity_name, (is_check ? "TRUE" : "FALSE"));
858 } else {
859 src = mputprintf(src, "TTCN_Logger::log("
860 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
861 "TTCN_Logger::MATCHING_PMSUCCESS:TTCN_Logger::MATCHING_PCSUCCESS"
862 ", \"Matching on port %%s succeeded.\", port_name);\n"
863 "const TTCN_Logger::Severity log_sev = "
864 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
865 "TTCN_Logger::PORTEVENT_PMIN:TTCN_Logger::PORTEVENT_PCIN;\n"
866 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
867 "TTCN_Logger::log_procport_recv(port_name, "
868 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component,\n"
869 "%s, CHARSTRING(0, NULL), msg_head_count+1);\n"
870 "}\n", entity_name, (is_check ? "TRUE" : "FALSE"));
871 }
872
873 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
874 src = mputprintf(src, "return ALT_YES;\n"
875 "}\n"
876 "default:\n"
877 "TTCN_Logger::log(%s, \"Matching on port %%s "
878 "failed: First entity in the queue is not %s %s.\", port_name);\n"
879 "return ALT_NO;\n"
880 "}\n"
881 "}\n\n",
882 is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" :
883 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
884 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
885 entity_name_prefix, entity_name);
886
887 *def_ptr = def;
888 *src_ptr = src;
889}
890
891
892/** Generate code for logging
893 *
894 * Called from generate_getcall, generate_getreply, generate_catch
895 *
896 * @param src_ptr
897 * @param op_str "call", "reply" or "exception"
898 * @param match_str "catch_template.log_match", "getcall_template.log_match_call"
899 * or "getreply_template.log_match_reply"
900 * @param is_address
901 * @param is_check
902 * @param signature_index
903 */
904static void generate_proc_incoming_data_logging(char **src_ptr,
905 const char *op_str, const char *match_str, boolean is_address,
906 boolean is_check, size_t signature_index)
907{
908 if (is_address) {
909 *src_ptr = mputprintf(*src_ptr,
910 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMSUCCESS)) "
911 "{\n"
912 "TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::procedure__,\n"
913 "port_name, SYSTEM_COMPREF,\n"
914 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMSUCCESS, TRUE),"
3abe9331 915 " %s(*proc_queue_head->%s_%lu%s),\n"
970ed795
EL
916 " TTCN_Logger::end_event_log2str()));\n"
917 "}\n"
918 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMIN)) "
919 "{\n"
920 "TTCN_Logger::log_procport_recv(port_name, "
921 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component, %s,\n"
922 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMIN, TRUE),"
923 " proc_queue_head->%s_%lu->log(),"
924 " TTCN_Logger::end_event_log2str()),\n"
925 "msg_head_count+1);\n"
926 "}\n", match_str, op_str, (unsigned long) signature_index,
3abe9331 927 (omit_in_value_list ? ", TRUE" : ""),
970ed795
EL
928 op_str, (is_check ? "TRUE" : "FALSE"), op_str, (unsigned long) signature_index);
929 } else {
930 *src_ptr = mputprintf(*src_ptr, "TTCN_Logger::Severity log_sev = "
931 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
932 "TTCN_Logger::MATCHING_PMSUCCESS:TTCN_Logger::MATCHING_PCSUCCESS;\n"
933 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
934 "TTCN_Logger::begin_event(log_sev);\n"
935 "TTCN_Logger::log_event(\"Matching on port %%s "
936 "succeeded: \", port_name);\n"
937 "%s(*proc_queue_head->%s_%lu);\n"
938 "TTCN_Logger::end_event();\n"
939 "}\n"
940 "log_sev = proc_queue_head->sender_component==SYSTEM_COMPREF?"
941 "TTCN_Logger::PORTEVENT_PMIN:TTCN_Logger::PORTEVENT_PCIN;\n"
942 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
943 "TTCN_Logger::log_procport_recv(port_name, "
944 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component, %s,\n"
945 "(TTCN_Logger::begin_event(log_sev, TRUE),"
946 " proc_queue_head->%s_%lu->log(),"
947 " TTCN_Logger::end_event_log2str()),\n"
948 "msg_head_count+1"
949 ");\n"
950 "}\n", match_str, op_str, (unsigned long) signature_index,
951 op_str, (is_check ? "TRUE" : "FALSE"),
952 op_str, (unsigned long) signature_index);
953 }
954}
955
956static void generate_getcall(char **def_ptr, char **src_ptr,
957 const port_def *pdef, const char *class_name, size_t signature_index,
958 boolean is_check, boolean is_address)
959{
960 char *def = *def_ptr, *src = *src_ptr;
961 const port_proc_signature *signature =
962 pdef->proc_in.elements + signature_index;
963 const char *function_name = is_check ? "check_getcall" : "getcall";
964 const char *operation_name = is_check ? "Check-getcall" : "Getcall";
965 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
966
967 def = mputprintf(def, "alt_status %s(const %s_template& "
968 "getcall_template, const %s_template& sender_template, "
969 "const %s_call_redirect& param_ref, %s *sender_ptr);\n",
970 function_name, signature->name, sender_type, signature->name,
971 sender_type);
972
973 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
974 "getcall_template, const %s_template& sender_template, "
975 "const %s_call_redirect& param_ref, %s *sender_ptr)\n"
976 "{\n"
977 "if (proc_queue_head == NULL) {\n"
978 "if (is_started) return ALT_MAYBE;\n"
979 "else {\n"
980 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
981 "port %%s failed: Port is not started and the queue is empty.\", "
982 "port_name);\n"
983 "return ALT_NO;\n"
984 "}\n", class_name, function_name, signature->name, sender_type,
985 signature->name, sender_type);
986 if (is_address) {
987 src = mputprintf(src,
988 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
989 "{\n"
990 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
991 "port_name, proc_queue_head->sender_component,\n"
992 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__is__not__system ,\n"
993 "CHARSTRING(0,NULL));\n"
994 "return ALT_NO;\n"
995 "} else if (proc_queue_head->sender_address == NULL) {\n"
996 "TTCN_error(\"%s operation on port %%s requires the address "
997 "of the sender, which was not given by the test port.\", "
998 "port_name);\n"
999 "return ALT_NO;\n"
1000 "} else if (!sender_template.match("
1001 "*proc_queue_head->sender_address)) {\n"
1002 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
1003 "{\n"
1004 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1005 "port_name, SYSTEM_COMPREF,\n"
1006 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1007 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),"
1008 " sender_template.log_match(*proc_queue_head->sender_address), "
1009 " TTCN_Logger::end_event_log2str()));\n"
1010 "}\n"
1011 "return ALT_NO;\n", operation_name);
1012 } else {
1013 src = mputstr(src, "} else if (!sender_template.match("
1014 "proc_queue_head->sender_component)) {\n"
1015 "const TTCN_Logger::Severity log_sev = "
1016 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1017 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC;\n"
1018 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1019 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1020 "port_name, proc_queue_head->sender_component,\n"
1021 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1022 "(TTCN_Logger::begin_event(log_sev, TRUE),"
1023 " sender_template.log_match(proc_queue_head->sender_component), "
1024 " TTCN_Logger::end_event_log2str()));\n"
1025 "}\n"
1026 "return ALT_NO;\n");
1027 }
1028 src = mputprintf(src,
1029 "} else if (proc_queue_head->item_selection != CALL_%lu) {\n"
1030 "TTCN_Logger::log(%s, \"Matching on port %%s "
1031 "failed: The first entity in the queue is not a call for "
1032 "signature %s.\", port_name);\n"
1033 "return ALT_NO;\n"
1034 "} else if (!getcall_template.match_call"
3abe9331 1035 "(*proc_queue_head->call_%lu%s)) {\n",
970ed795
EL
1036 (unsigned long) signature_index,
1037 is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" :
1038 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1039 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
3abe9331 1040 signature->dispname, (unsigned long) signature_index,
1041 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
1042 src = mputprintf(src,
1043 "const TTCN_Logger::Severity log_sev = %s;\n"
1044 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1045 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1046 "port_name, proc_queue_head->sender_component,\n"
1047 "TitanLoggerApiSimple::MatchingFailureType_reason::parameters__of__call__do__not__match__template,\n"
1048 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 1049 " getcall_template.log_match_call(*proc_queue_head->call_%lu%s),"
970ed795
EL
1050 " TTCN_Logger::end_event_log2str()));\n"
1051 "}\n"
1052 "return ALT_NO;\n"
1053 "} else {\n"
1054 "param_ref.set_parameters(*proc_queue_head->call_%lu);\n"
1055 "if (sender_ptr != NULL) *sender_ptr = ",
1056 (is_address ?
1057 "TTCN_Logger::MATCHING_PMUNSUCC" :
1058 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1059 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC"),
3abe9331 1060 (unsigned long) signature_index,
1061 (omit_in_value_list ? ", TRUE" : ""),
1062 (unsigned long) signature_index);
970ed795
EL
1063 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
1064 else src = mputstr(src, "proc_queue_head->sender_component;\n");
1065
1066 generate_proc_incoming_data_logging(&src, "call",
1067 "getcall_template.log_match_call", is_address, is_check, signature_index);
1068
1069 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
1070 src = mputstr(src,
1071 "return ALT_YES;\n"
1072 "}\n"
1073 "}\n\n");
1074
1075 *def_ptr = def;
1076 *src_ptr = src;
1077}
1078
1079static void generate_getreply(char **def_ptr, char **src_ptr,
1080 const port_def *pdef, const char *class_name, size_t signature_index,
1081 boolean is_check, boolean is_address)
1082{
1083 char *def = *def_ptr, *src = *src_ptr;
1084 const port_proc_signature *signature =
1085 pdef->proc_out.elements + signature_index;
1086 const char *function_name = is_check ? "check_getreply" : "getreply";
1087 const char *operation_name = is_check ? "Check-getreply" : "Getreply";
1088 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
1089
1090 def = mputprintf(def, "alt_status %s(const %s_template& "
1091 "getreply_template, const %s_template& sender_template, "
1092 "const %s_reply_redirect& param_ref, %s *sender_ptr);\n",
1093 function_name, signature->name, sender_type, signature->name,
1094 sender_type);
1095
1096 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
1097 "getreply_template, const %s_template& sender_template, "
1098 "const %s_reply_redirect& param_ref, %s *sender_ptr)\n"
1099 "{\n"
1100 "if (proc_queue_head == NULL) {\n"
1101 "if (is_started) return ALT_MAYBE;\n"
1102 "else {\n"
1103 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
1104 "port %%s failed: Port is not started and the queue is empty.\", "
1105 "port_name);\n"
1106 "return ALT_NO;\n"
1107 "}\n", class_name, function_name, signature->name, sender_type,
1108 signature->name, sender_type);
1109 if (is_address) {
1110 src = mputprintf(src,
1111 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
1112 "{\n"
1113 "TTCN_Logger::log(TTCN_Logger::MATCHING_PMUNSUCC, \"Matching "
1114 "on port %%s failed: Sender of the first entity in the queue "
1115 "is not the system.\", port_name);\n"
1116 "return ALT_NO;\n"
1117 "} else if (proc_queue_head->sender_address == NULL) {\n"
1118 "TTCN_error(\"%s operation on port %%s requires the address "
1119 "of the sender, which was not given by the test port.\", "
1120 "port_name);\n"
1121 "return ALT_NO;\n"
1122 "} else if (!sender_template.match("
1123 "*proc_queue_head->sender_address)) {\n"
1124 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
1125 "{\n"
1126 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1127 "port_name, SYSTEM_COMPREF,\n"
1128 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1129 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),"
1130 " sender_template.log_match(*proc_queue_head->sender_address), "
1131 " TTCN_Logger::end_event_log2str()));\n"
1132 "}\n"
1133 "return ALT_NO;\n", operation_name);
1134 } else {
1135 src = mputstr(src, "} else if (!sender_template.match("
1136 "proc_queue_head->sender_component)) {\n"
1137 "const TTCN_Logger::Severity log_sev = "
1138 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1139 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
1140 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1141 "TTCN_Logger::begin_event(log_sev);\n"
1142 "TTCN_Logger::log_event(\"Matching on port %s failed: "
1143 "Sender of the first entity in the queue does not match the "
1144 "from clause: \", port_name);\n"
1145 "sender_template.log_match(proc_queue_head->sender_component);\n"
1146 "TTCN_Logger::end_event();\n"
1147 "}\n"
1148 "return ALT_NO;\n");
1149 }
1150 src = mputprintf(src,
1151 "} else if (proc_queue_head->item_selection != REPLY_%lu) {\n"
1152 "TTCN_Logger::log(%s, \"Matching on port %%s "
1153 "failed: The first entity in the queue is not a reply for "
1154 "signature %s.\", port_name);\n"
1155 "return ALT_NO;\n"
1156 "} else if (!getreply_template.match_reply"
3abe9331 1157 "(*proc_queue_head->reply_%lu%s)) {\n", (unsigned long) signature_index,
970ed795
EL
1158 is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" :
1159 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1160 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
3abe9331 1161 signature->dispname, (unsigned long) signature_index,
1162 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
1163
1164 src = mputprintf(src,
1165 "const TTCN_Logger::Severity log_sev = %s;\n"
1166 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1167 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1168 "port_name, proc_queue_head->sender_component,\n"
1169 "TitanLoggerApiSimple::MatchingFailureType_reason::parameters__of__reply__do__not__match__template,\n"
1170 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 1171 " getreply_template.log_match_reply(*proc_queue_head->reply_%lu%s), "
970ed795
EL
1172 " TTCN_Logger::end_event_log2str()));\n"
1173 "}\n"
1174 "return ALT_NO;\n"
1175 "} else {\n"
1176 "param_ref.set_parameters(*proc_queue_head->reply_%lu);\n"
1177 "if (sender_ptr != NULL) *sender_ptr = ",
1178 (is_address ?
1179 "TTCN_Logger::MATCHING_PMUNSUCC" :
1180 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1181 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC"),
3abe9331 1182 (unsigned long) signature_index,
1183 (omit_in_value_list ? ", TRUE" : ""),
1184 (unsigned long) signature_index);
970ed795
EL
1185 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
1186 else src = mputstr(src, "proc_queue_head->sender_component;\n");
1187
1188 generate_proc_incoming_data_logging(&src, "reply",
1189 "getreply_template.log_match_reply", is_address, is_check, signature_index);
1190
1191 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
1192 src = mputstr(src,
1193 "return ALT_YES;\n"
1194 "}\n"
1195 "}\n\n");
1196
1197 *def_ptr = def;
1198 *src_ptr = src;
1199}
1200
1201static void generate_catch(char **def_ptr, char **src_ptr,
1202 const port_def *pdef, const char *class_name, size_t signature_index,
1203 boolean is_check, boolean is_address)
1204{
1205 char *def = *def_ptr, *src = *src_ptr;
1206 const port_proc_signature *signature =
1207 pdef->proc_out.elements + signature_index;
1208 const char *function_name = is_check ? "check_catch" : "get_exception";
1209 const char *operation_name = is_check ? "Check-catch" : "Catch";
1210 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
1211
1212 def = mputprintf(def, "alt_status %s(const %s_exception_template& "
1213 "catch_template, const %s_template& sender_template, "
1214 "%s *sender_ptr);\n",
1215 function_name, signature->name, sender_type, sender_type);
1216
1217 src = mputprintf(src, "alt_status %s::%s(const %s_exception_template& "
1218 "catch_template, const %s_template& sender_template, "
1219 "%s *sender_ptr)\n"
1220 "{\n"
1221 "if (proc_queue_head == NULL) {\n"
1222 "if (is_started) return ALT_MAYBE;\n"
1223 "else {\n"
1224 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
1225 "port %%s failed: Port is not started and the queue is empty.\", "
1226 "port_name);\n"
1227 "return ALT_NO;\n"
1228 "}\n", class_name, function_name, signature->name, sender_type,
1229 sender_type);
1230 if (is_address) {
1231 src = mputprintf(src,
1232 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
1233 "{\n"
1234 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1235 "port_name, proc_queue_head->sender_component,\n"
1236 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__is__not__system,\n"
1237 "CHARSTRING(0, NULL));\n"
1238
1239 "return ALT_NO;\n"
1240 "} else if (proc_queue_head->sender_address == NULL) {\n"
1241 "TTCN_error(\"%s operation on port %%s requires the address "
1242 "of the sender, which was not given by the test port.\", "
1243 "port_name);\n"
1244 "return ALT_NO;\n"
1245 "} else if (!sender_template.match("
1246 "*proc_queue_head->sender_address)) {\n"
1247 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
1248 "{\n"
1249 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1250 "port_name, proc_queue_head->sender_component,\n"
1251 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1252 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),\n"
1253 " sender_template.log_match(*proc_queue_head->sender_address),\n"
1254 " TTCN_Logger::end_event_log2str()));\n"
1255 "}\n"
1256 "return ALT_NO;\n", operation_name);
1257 } else {
1258 src = mputstr(src, "} else if (!sender_template.match("
1259 "proc_queue_head->sender_component)) {\n"
1260 "const TTCN_Logger::Severity log_sev = "
1261 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1262 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
1263 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1264 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1265 "port_name, proc_queue_head->sender_component,\n"
1266 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1267 "(TTCN_Logger::begin_event(log_sev, TRUE),\n"
1268 " sender_template.log_match(proc_queue_head->sender_component),\n"
1269 " TTCN_Logger::end_event_log2str()));\n"
1270 "}\n"
1271 "return ALT_NO;\n");
1272 }
1273 src = mputprintf(src,
1274 "} else if (proc_queue_head->item_selection != EXCEPTION_%lu) {\n"
1275 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1276 "port_name, %s,\n"
1277 "TitanLoggerApiSimple::MatchingFailureType_reason::not__an__exception__for__signature,\n"
1278 "CHARSTRING(\"%s\"));\n"
1279 "return ALT_NO;\n"
1280 "} else if (!catch_template.match"
3abe9331 1281 "(*proc_queue_head->exception_%lu%s)) {\n",
970ed795
EL
1282 (unsigned long) signature_index,
1283 (is_address ? "SYSTEM_COMPREF": "proc_queue_head->sender_component"),
3abe9331 1284 signature->dispname, (unsigned long) signature_index,
1285 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
1286 if (is_address) {
1287 src = mputstr(src, "if (TTCN_Logger::log_this_event("
1288 "TTCN_Logger::MATCHING_PMUNSUCC)) {\n");
1289 } else {
1290 src = mputstr(src, "const TTCN_Logger::Severity log_sev = "
1291 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1292 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
1293 "if (TTCN_Logger::log_this_event(log_sev)) {\n");
1294 }
1295 src = mputprintf(src,
1296 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1297 "port_name, proc_queue_head->sender_component,\n"
1298 "TitanLoggerApiSimple::MatchingFailureType_reason::exception__does__not__match__template,\n"
1299 "(TTCN_Logger::begin_event(%s, TRUE),\n"
3abe9331 1300 " catch_template.log_match(*proc_queue_head->exception_%lu%s),\n"
970ed795
EL
1301 " TTCN_Logger::end_event_log2str()));\n"
1302 "}\n"
1303 "return ALT_NO;\n"
1304 "} else {\n"
1305 "catch_template.set_value(*proc_queue_head->exception_%lu);\n"
1306 "if (sender_ptr != NULL) *sender_ptr = ",
1307 (is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" : "log_sev"),
3abe9331 1308 (unsigned long) signature_index,
1309 (omit_in_value_list ? ", TRUE" : ""),
1310 (unsigned long) signature_index);
970ed795
EL
1311 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
1312 else src = mputstr(src, "proc_queue_head->sender_component;\n");
1313
1314 generate_proc_incoming_data_logging(&src, "exception",
1315 "catch_template.log_match", is_address, is_check, signature_index);
1316
1317 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
1318 src = mputstr(src,
1319 "return ALT_YES;\n"
1320 "}\n"
1321 "}\n\n");
1322
1323 *def_ptr = def;
1324 *src_ptr = src;
1325}
1326
1327#ifdef __SUNPRO_C
1328#define SUNPRO_PUBLIC "public:\n"
1329#define SUNPRO_PRIVATE "private:\n"
1330#else
1331#define SUNPRO_PUBLIC
1332#define SUNPRO_PRIVATE
1333#endif
1334
1335
1336void defPortClass(const port_def* pdef, output_struct* output)
1337{
1338 char *def = NULL, *src = NULL;
1339 char *class_name, *base_class_name;
1340 size_t i;
1341 boolean has_incoming_call, has_incoming_reply, has_incoming_exception;
1342 boolean has_msg_queue, has_proc_queue;
1343
1344 if (pdef->testport_type == INTERNAL) {
1345 class_name = mcopystr(pdef->name);
1346 base_class_name = mcopystr("PORT");
1347 } else {
1348 switch (pdef->port_type) {
1349 case REGULAR:
1350 class_name = mprintf("%s_BASE", pdef->name);
1351 base_class_name = mcopystr("PORT");
1352 break;
1353 case PROVIDER:
1354 class_name = mcopystr(pdef->name);
1355 base_class_name = mprintf("%s_PROVIDER", pdef->name);
1356 break;
1357 case USER:
1358 class_name = mcopystr(pdef->name);
1359 base_class_name = mprintf("%s_PROVIDER", pdef->provider_name);
1360 break;
1361 default:
1362 FATAL_ERROR("defPortClass(): invalid port type");
1363 }
1364 }
1365
1366 has_incoming_call = pdef->proc_in.nElements > 0;
1367
1368 has_incoming_reply = FALSE;
1369 for (i = 0; i < pdef->proc_out.nElements; i++) {
1370 if (!pdef->proc_out.elements[i].is_noblock) {
1371 has_incoming_reply = TRUE;
1372 break;
1373 }
1374 }
1375
1376 has_incoming_exception = FALSE;
1377 for (i = 0; i < pdef->proc_out.nElements; i++) {
1378 if (pdef->proc_out.elements[i].has_exceptions) {
1379 has_incoming_exception = TRUE;
1380 break;
1381 }
1382 }
1383
1384 has_msg_queue = pdef->msg_in.nElements > 0;
1385 has_proc_queue = has_incoming_call || has_incoming_reply ||
1386 has_incoming_exception;
1387
1388 def = mprintf("class %s : public %s {\n", class_name, base_class_name);
1389
1390 /* private data types and member functions for queue management */
1391 if (has_msg_queue) {
1392 /* data structures for the message queue */
1393 def = mputstr(def,
1394 SUNPRO_PUBLIC
1395 "enum msg_selection { ");
1396 for (i = 0; i < pdef->msg_in.nElements; i++) {
1397 if (i > 0) def = mputstr(def, ", ");
1398 def = mputprintf(def, "MESSAGE_%lu", (unsigned long) i);
1399 }
1400 def = mputstr(def, " };\n"
1401 SUNPRO_PRIVATE
1402 "struct msg_queue_item : public msg_queue_item_base {\n"
1403 "msg_selection item_selection;\n"
1404 "union {\n");
1405 for (i = 0; i < pdef->msg_in.nElements; i++)
1406 def = mputprintf(def, "%s *message_%lu;\n",
1407 pdef->msg_in.elements[i].name, (unsigned long) i);
1408
1409 def = mputstr(def, "};\n"
1410 "component sender_component;\n");
1411 if (pdef->testport_type == ADDRESS) {
1412 def = mputprintf(def, "%s *sender_address;\n", pdef->address_name);
1413 }
1414 def = mputstr(def, "};\n\n");
1415 if (pdef->has_sliding) {
1416 def = mputprintf(def, "OCTETSTRING sliding_buffer;\n");
1417 }
1418 def = mputstr(def, "void remove_msg_queue_head();\n");
1419 src = mputprintf(src,
1420 "void %s::remove_msg_queue_head()\n"
1421 "{\n"
1422 "msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;\n"
1423 "switch (my_head->item_selection) {\n", class_name);
1424 for (i = 0; i < pdef->msg_in.nElements; i++)
1425 src = mputprintf(src, "case MESSAGE_%lu:\n"
1426 "delete (my_head)->message_%lu;\n"
1427 "break;\n", (unsigned long) i, (unsigned long) i);
1428 src = mputstr(src, "default:\n"
1429 "TTCN_error(\"Internal error: Invalid message selector in the "
1430 "queue of port %s.\", port_name);\n"
1431 "}\n");
1432 if (pdef->testport_type == ADDRESS) {
1433 src = mputstr(src, "delete ((msg_queue_item*)msg_queue_head)->sender_address;\n");
1434 }
1435 src = mputstr(src,
1436 "msg_queue_item_base *next_item = msg_queue_head->next_item;\n"
1437 /* Make sure to delete the derived class; no virtual destructor. */
1438 "delete (msg_queue_item*)msg_queue_head;\n"
1439 "msg_queue_head = next_item;\n"
1440 "if (next_item == NULL) msg_queue_tail = NULL;\n"
1441 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::extract__msg, "
1442 "port_name, 0, ++msg_head_count, CHARSTRING(0,NULL), CHARSTRING(0,NULL));"
1443 "}\n\n");
1444 } /* if has_msg_queue */
1445
1446 if (has_proc_queue) {
1447 /* data structures for the procedure queue */
1448 boolean is_first = TRUE;
1449 def = mputstr(def,
1450 SUNPRO_PUBLIC
1451 "enum proc_selection { ");
1452 for (i = 0; i < pdef->proc_in.nElements; i++) {
1453 if (is_first) is_first = FALSE;
1454 else def = mputstr(def, ", ");
1455 def = mputprintf(def, "CALL_%lu", (unsigned long) i);
1456 }
1457 for (i = 0; i < pdef->proc_out.nElements; i++) {
1458 if (pdef->proc_out.elements[i].is_noblock) continue;
1459 if (is_first) is_first = FALSE;
1460 else def = mputstr(def, ", ");
1461 def = mputprintf(def, "REPLY_%lu", (unsigned long) i);
1462 }
1463 for (i = 0; i < pdef->proc_out.nElements; i++) {
1464 if (!pdef->proc_out.elements[i].has_exceptions) continue;
1465 if (is_first) is_first = FALSE;
1466 else def = mputstr(def, ", ");
1467 def = mputprintf(def, "EXCEPTION_%lu", (unsigned long) i);
1468 }
1469 def = mputstr(def, " };\n"
1470 SUNPRO_PRIVATE
1471 "struct proc_queue_item {\n"
1472 "proc_selection item_selection;\n"
1473 "union {\n");
1474 for (i = 0; i < pdef->proc_in.nElements; i++) {
1475 def = mputprintf(def, "%s_call *call_%lu;\n",
1476 pdef->proc_in.elements[i].name, (unsigned long) i);
1477 }
1478 for (i = 0; i < pdef->proc_out.nElements; i++) {
1479 if (pdef->proc_out.elements[i].is_noblock) continue;
1480 def = mputprintf(def, "%s_reply *reply_%lu;\n",
1481 pdef->proc_out.elements[i].name, (unsigned long) i);
1482 }
1483 for (i = 0; i < pdef->proc_out.nElements; i++) {
1484 if (!pdef->proc_out.elements[i].has_exceptions) continue;
1485 def = mputprintf(def, "%s_exception *exception_%lu;\n",
1486 pdef->proc_out.elements[i].name, (unsigned long) i);
1487 }
1488 def = mputstr(def, "};\n"
1489 "component sender_component;\n");
1490 if (pdef->testport_type == ADDRESS) {
1491 def = mputprintf(def, "%s *sender_address;\n", pdef->address_name);
1492 }
1493 def = mputstr(def, "proc_queue_item *next_item;\n"
1494 "} *proc_queue_head, *proc_queue_tail;\n");
1495
1496 def = mputstr(def, "void append_to_proc_queue("
1497 "proc_queue_item *new_item);\n");
1498 src = mputprintf(src, "void %s::append_to_proc_queue("
1499 "proc_queue_item *new_item)\n"
1500 "{\n"
1501 "new_item->next_item = NULL;\n"
1502 "if (proc_queue_tail != NULL) "
1503 "proc_queue_tail->next_item = new_item;\n"
1504 "else proc_queue_head = new_item;\n"
1505 "proc_queue_tail = new_item;\n"
1506 "}\n\n", class_name);
1507
1508 def = mputstr(def, "void remove_proc_queue_head();\n");
1509 src = mputprintf(src,
1510 "void %s::remove_proc_queue_head()\n"
1511 "{\n"
1512 "switch (proc_queue_head->item_selection) {\n", class_name);
1513 for (i = 0; i < pdef->proc_in.nElements; i++) {
1514 src = mputprintf(src, "case CALL_%lu:\n"
1515 "delete proc_queue_head->call_%lu;\n"
1516 "break;\n", (unsigned long) i, (unsigned long) i);
1517 }
1518 for (i = 0; i < pdef->proc_out.nElements; i++) {
1519 if (pdef->proc_out.elements[i].is_noblock) continue;
1520 src = mputprintf(src, "case REPLY_%lu:\n"
1521 "delete proc_queue_head->reply_%lu;\n"
1522 "break;\n", (unsigned long) i, (unsigned long) i);
1523 }
1524 for (i = 0; i < pdef->proc_out.nElements; i++) {
1525 if (!pdef->proc_out.elements[i].has_exceptions) continue;
1526 src = mputprintf(src, "case EXCEPTION_%lu:\n"
1527 "delete proc_queue_head->exception_%lu;\n"
1528 "break;\n", (unsigned long) i, (unsigned long) i);
1529 }
1530 src = mputstr(src, "default:\n"
1531 "TTCN_error(\"Internal error: Invalid signature selector in "
1532 "the queue of port %s.\", port_name);\n"
1533 "}\n");
1534 if (pdef->testport_type == ADDRESS) {
1535 src = mputstr(src, "delete proc_queue_head->sender_address;\n");
1536 }
1537 src = mputstr(src,
1538 "proc_queue_item *next_item = proc_queue_head->next_item;\n"
1539 "delete proc_queue_head;\n"
1540 "proc_queue_head = next_item;\n"
1541 "if (next_item == NULL) proc_queue_tail = NULL;\n"
1542 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::extract__op, "
1543 "port_name, 0, ++proc_head_count, CHARSTRING(0,NULL), CHARSTRING(0,NULL));"
1544 "}\n\n");
1545 }
1546
1547 /* clear_queue */
1548 if (has_msg_queue || has_proc_queue) {
1549 def = mputstr(def, "protected:\n"
1550 "void clear_queue();\n");
1551 src = mputprintf(src, "void %s::clear_queue()\n"
1552 "{\n", class_name);
1553 if (has_msg_queue) src = mputstr(src,
1554 "while (msg_queue_head != NULL) remove_msg_queue_head();\n");
1555 if (has_proc_queue) src = mputstr(src,
1556 "while (proc_queue_head != NULL) remove_proc_queue_head();\n");
1557 if (pdef->has_sliding) src = mputstr(src,
1558 "sliding_buffer = OCTETSTRING(0, 0);\n");
1559 src = mputstr(src, "}\n\n");
1560 }
1561
1562
1563 def = mputstr(def, "public:\n");
1564
1565 /* constructor */
1566 def = mputprintf(def, "%s(const char *par_port_name", class_name);
1567 if (pdef->testport_type == INTERNAL || pdef->port_type != REGULAR) {
1568 /* the default argument is needed if the generated class implements
1569 * the port type (i.e. it is not a base class) */
1570 def = mputstr(def, " = NULL");
1571 }
1572 def = mputstr(def, ");\n");
1573 src = mputprintf(src, "%s::%s(const char *par_port_name)\n"
1574 " : %s(par_port_name)\n"
1575 "%s"
1576 "{\n", class_name, class_name, base_class_name,
1577 (pdef->has_sliding ? " , sliding_buffer(0, 0)" : ""));
1578 if (has_msg_queue) src = mputstr(src, "msg_queue_head = NULL;\n"
1579 "msg_queue_tail = NULL;\n");
1580 if (has_proc_queue) src = mputstr(src, "proc_queue_head = NULL;\n"
1581 "proc_queue_tail = NULL;\n");
1582 src = mputstr(src, "}\n\n");
1583
1584 /* destructor */
1585 if (has_msg_queue || has_proc_queue) {
1586 def = mputprintf(def, "~%s();\n", class_name);
1587 src = mputprintf(src, "%s::~%s()\n"
1588 "{\n"
1589 "clear_queue();\n"
1590 "}\n\n", class_name, class_name);
1591 }
1592
1593 /* send functions */
1594 for (i = 0; i < pdef->msg_out.nElements; i++) {
1595 const port_msg_mapped_type *msg = pdef->msg_out.elements + i;
1596
1597 def = mputprintf(def, "void send(const %s& send_par, "
1598 "const COMPONENT& destination_component);\n", msg->name);
1599
1600 src = mputprintf(src, "void %s::send(const %s& send_par, "
1601 "const COMPONENT& destination_component)\n"
1602 "{\n"
1603 "if (!is_started) TTCN_error(\"Sending a message on port %%s, which "
1604 "is not started.\", port_name);\n"
1605 "if (!destination_component.is_bound()) "
1606 "TTCN_error(\"Unbound component reference in the to clause of send "
1607 "operation.\");\n"
1608 "const TTCN_Logger::Severity log_sev = "
1609 "destination_component==SYSTEM_COMPREF?"
1610 "TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;\n"
1611 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1612 "TTCN_Logger::log_msgport_send(port_name, destination_component,\n"
1613 "(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(\" %s : \"),\n"
1614 "send_par.log(), TTCN_Logger::end_event_log2str()));\n"
1615 "}\n", class_name, msg->name, msg->dispname);
1616 if (pdef->port_type != USER || (msg->nTargets == 1 &&
1617 msg->targets[0].mapping_type == M_SIMPLE)) {
1618 /* the same message type goes through the external interface */
1619 src = mputstr(src, "if (destination_component == SYSTEM_COMPREF) ");
1620 if (pdef->testport_type == INTERNAL) {
1621 src = mputstr(src, "TTCN_error(\"Message cannot be sent to system "
1622 "on internal port %s.\", port_name);\n");
1623 } else {
1624 src = mputprintf(src, "outgoing_send(send_par%s);\n",
1625 pdef->testport_type == ADDRESS ? ", NULL" : "");
1626 }
1627 src = mputprintf(src, "else {\n"
1628 "Text_Buf text_buf;\n"
1629 "prepare_message(text_buf, \"%s\");\n"
1630 "send_par.encode_text(text_buf);\n"
1631 "send_data(text_buf, destination_component);\n"
1632 "}\n", msg->dispname);
1633 } else {
1634 /* the message type is mapped to another outgoing type of the
1635 * external interface */
1636 src = generate_send_mapping(src, pdef, msg, FALSE);
1637 }
1638 src = mputstr(src, "}\n\n");
1639
1640 if (pdef->testport_type == ADDRESS) {
1641 def = mputprintf(def, "void send(const %s& send_par, "
1642 "const %s& destination_address);\n", msg->name,
1643 pdef->address_name);
1644
1645 src = mputprintf(src, "void %s::send(const %s& send_par, "
1646 "const %s& destination_address)\n"
1647 "{\n"
1648 "if (!is_started) TTCN_error(\"Sending a message on port %%s, "
1649 "which is not started.\", port_name);\n"
1650 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MMSEND))"
1651 "{\n"
1652 "TTCN_Logger::log_msgport_send(port_name, SYSTEM_COMPREF,\n"
1653 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMSEND, TRUE),"
1654 " TTCN_Logger::log_event_str(\"(\"),"
1655 " destination_address.log(),"
1656 " TTCN_Logger::log_event_str(\") %s : \"),"
1657 " send_par.log(),"
1658 " TTCN_Logger::end_event_log2str()));\n"
1659 "}\n", class_name, msg->name, pdef->address_name, msg->dispname);
1660 if (pdef->port_type != USER || (msg->nTargets == 1 &&
1661 msg->targets[0].mapping_type == M_SIMPLE)) {
1662 src = mputstr(src, "outgoing_send(send_par, "
1663 "&destination_address);\n");
1664 } else src = generate_send_mapping(src, pdef, msg, TRUE);
1665 src = mputstr(src, "}\n\n");
1666 }
1667
1668 def = mputprintf(def, "void send(const %s& send_par);\n", msg->name);
1669 src = mputprintf(src, "void %s::send(const %s& send_par)\n"
1670 "{\n"
1671 "send(send_par, COMPONENT(get_default_destination()));\n"
1672 "}\n\n", class_name, msg->name);
1673
1674 def = mputprintf(def, "void send(const %s_template& send_par, "
1675 "const COMPONENT& destination_component);\n", msg->name);
1676 src = mputprintf(src, "void %s::send(const %s_template& send_par, "
1677 "const COMPONENT& destination_component)\n"
1678 "{\n"
1679 "const %s& send_par_value = %s(send_par.valueof());\n"
1680 "send(send_par_value, destination_component);\n"
1681 "}\n\n", class_name, msg->name, msg->name, msg->name);
1682
1683 if (pdef->testport_type == ADDRESS) {
1684 def = mputprintf(def, "void send(const %s_template& send_par, "
1685 "const %s& destination_address);\n", msg->name,
1686 pdef->address_name);
1687 src = mputprintf(src, "void %s::send(const %s_template& send_par, "
1688 "const %s& destination_address)\n"
1689 "{\n"
1690 "const %s& send_par_value = %s(send_par.valueof());\n"
1691 "send(send_par_value, destination_address);\n"
1692 "}\n\n", class_name, msg->name, pdef->address_name, msg->name, msg->name);
1693 }
1694
1695 def = mputprintf(def, "void send(const %s_template& send_par);\n",
1696 msg->name);
1697 src = mputprintf(src, "void %s::send(const %s_template& send_par)\n"
1698 "{\n"
1699 "const %s& send_par_value = %s(send_par.valueof());\n"
1700 "send(send_par_value, COMPONENT(get_default_destination()));\n"
1701 "}\n\n", class_name, msg->name, msg->name, msg->name);
1702 }
1703
1704 /* call functions */
1705 for (i = 0; i < pdef->proc_out.nElements; i++) {
1706 const port_proc_signature *sig = pdef->proc_out.elements + i;
1707 def = mputprintf(def, "void call(const %s_template& call_template, "
1708 "const COMPONENT& destination_component);\n", sig->name);
1709 src = mputprintf(src, "void %s::call(const %s_template& "
1710 "call_template, const COMPONENT& destination_component)\n"
1711 "{\n"
1712 "if (!is_started) TTCN_error(\"Calling a signature on port %%s, "
1713 "which is not started.\", port_name);\n"
1714 "if (!destination_component.is_bound()) TTCN_error(\"Unbound "
1715 "component reference in the to clause of call operation.\");\n"
1716 "const %s_call& call_tmp = call_template.create_call();\n"
1717 "const TTCN_Logger::Severity log_sev = "
1718 "destination_component==SYSTEM_COMPREF?"
1719 "TTCN_Logger::PORTEVENT_PMOUT:TTCN_Logger::PORTEVENT_PCOUT;\n"
1720 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1721
1722 "TTCN_Logger::log_procport_send(port_name,"
1723 "TitanLoggerApiSimple::Port__oper::call__op, destination_component,\n"
1724 "CHARSTRING(0,NULL),"
1725 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1726 " call_tmp.log(),"
1727 " TTCN_Logger::end_event_log2str()));\n"
1728 "}\n"
1729 "if (destination_component == SYSTEM_COMPREF) ",
1730 class_name, sig->name, sig->name);
1731 if (pdef->testport_type == INTERNAL) {
1732 src = mputstr(src, "TTCN_error(\"Internal port %s cannot send "
1733 "call to system.\", port_name);\n");
1734 } else {
1735 src = mputprintf(src, "outgoing_call(call_tmp%s);\n",
1736 pdef->testport_type == ADDRESS ? ", NULL" : "");
1737 }
1738 src = mputprintf(src, "else {\n"
1739 "Text_Buf text_buf;\n"
1740 "prepare_call(text_buf, \"%s\");\n"
1741 "call_tmp.encode_text(text_buf);\n"
1742 "send_data(text_buf, destination_component);\n"
1743 "}\n"
1744 "}\n\n", sig->dispname);
1745
1746 if (pdef->testport_type == ADDRESS) {
1747 def = mputprintf(def, "void call(const %s_template& "
1748 "call_template, const %s& destination_address);\n",
1749 sig->name, pdef->address_name);
1750 src = mputprintf(src, "void %s::call(const %s_template& "
1751 "call_template, const %s& destination_address)\n"
1752 "{\n"
1753 "if (!is_started) TTCN_error(\"Calling a signature on port "
1754 "%%s, which is not started.\", port_name);\n"
1755 "const %s_call& call_tmp = call_template.create_call();\n"
1756 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMOUT))"
1757 " {\n"
1758 "TTCN_Logger::log_procport_send(port_name, "
1759 "TitanLoggerApiSimple::Port__oper::call__op, SYSTEM_COMPREF,\n"
1760 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1761 " destination_address.log(),"
1762 " TTCN_Logger::end_event_log2str()),\n"
1763 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1764 " call_tmp.log(),"
1765 " TTCN_Logger::end_event_log2str()));\n"
1766 "}\n"
1767 "outgoing_call(call_tmp, &destination_address);\n"
1768 "}\n\n",
1769 class_name, sig->name, pdef->address_name, sig->name);
1770 }
1771
1772 def = mputprintf(def, "void call(const %s_template& "
1773 "call_template);\n", sig->name);
1774 src = mputprintf(src, "void %s::call(const %s_template& "
1775 "call_template)\n"
1776 "{\n"
1777 "call(call_template, COMPONENT(get_default_destination()));\n"
1778 "}\n\n", class_name, sig->name);
1779 }
1780
1781 /* reply functions */
1782 for (i = 0; i < pdef->proc_in.nElements; i++) {
1783 const port_proc_signature *sig = pdef->proc_in.elements + i;
1784 if (sig->is_noblock) continue;
1785 def = mputprintf(def,"void reply(const %s_template& "
1786 "reply_template, const COMPONENT& destination_component);\n",
1787 sig->name);
1788 src = mputprintf(src, "void %s::reply(const %s_template& "
1789 "reply_template, const COMPONENT& destination_component)\n"
1790 "{\n"
1791 "if (!is_started) TTCN_error(\"Replying to a signature on port "
1792 "%%s, which is not started.\", port_name);\n"
1793 "if (!destination_component.is_bound()) TTCN_error(\"Unbound "
1794 "component reference in the to clause of reply operation.\");\n"
1795 "const %s_reply& reply_tmp = reply_template.create_reply();\n"
1796 "const TTCN_Logger::Severity log_sev = "
1797 "destination_component==SYSTEM_COMPREF?"
1798 "TTCN_Logger::PORTEVENT_PMOUT:TTCN_Logger::PORTEVENT_PCOUT;\n"
1799 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1800 "TTCN_Logger::log_procport_send(port_name, "
1801 "TitanLoggerApiSimple::Port__oper::reply__op, destination_component,\n"
1802 " CHARSTRING(0, NULL),\n"
1803 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1804 " reply_tmp.log(),"
1805 " TTCN_Logger::end_event_log2str()));\n"
1806 "}\n"
1807 "if (destination_component == SYSTEM_COMPREF) ",
1808 class_name, sig->name, sig->name);
1809 if (pdef->testport_type == INTERNAL) {
1810 src = mputstr(src, "TTCN_error(\"Internal port %s cannot send "
1811 "reply to system.\", port_name);\n");
1812 } else {
1813 src = mputprintf(src, "outgoing_reply(reply_tmp%s);\n",
1814 pdef->testport_type == ADDRESS ? ", NULL" : "");
1815 }
1816 src = mputprintf(src, "else {\n"
1817 "Text_Buf text_buf;\n"
1818 "prepare_reply(text_buf, \"%s\");\n"
1819 "reply_tmp.encode_text(text_buf);\n"
1820 "send_data(text_buf, destination_component);\n"
1821 "}\n"
1822 "}\n\n", sig->dispname);
1823
1824 if (pdef->testport_type == ADDRESS) {
1825 def = mputprintf(def, "void reply(const %s_template& "
1826 "reply_template, const %s& destination_address);\n",
1827 sig->name, pdef->address_name);
1828 src = mputprintf(src, "void %s::reply(const %s_template& "
1829 "reply_template, const %s& destination_address)\n"
1830 "{\n"
1831 "if (!is_started) TTCN_error(\"Replying to a call on port "
1832 "%%s, which is not started.\", port_name);\n"
1833 "const %s_reply& reply_tmp = reply_template.create_reply();\n"
1834 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMOUT))"
1835 " {\n"
1836 "TTCN_Logger::log_procport_send(port_name, "
1837 "TitanLoggerApiSimple::Port__oper::reply__op, SYSTEM_COMPREF,\n"
1838 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1839 " destination_address.log(),"
1840 " TTCN_Logger::end_event_log2str()),\n"
1841 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1842 " reply_tmp.log(),"
1843 " TTCN_Logger::end_event_log2str()));\n"
1844 "}\n"
1845 "outgoing_reply(reply_tmp, &destination_address);\n"
1846 "}\n\n",
1847 class_name, sig->name, pdef->address_name, sig->name);
1848 }
1849
1850 def = mputprintf(def, "void reply(const %s_template& "
1851 "reply_template);\n", sig->name);
1852 src = mputprintf(src, "void %s::reply(const %s_template& "
1853 "reply_template)\n"
1854 "{\n"
1855 "reply(reply_template, COMPONENT(get_default_destination()));\n"
1856 "}\n\n", class_name, sig->name);
1857 }
1858
1859 /* raise functions */
1860 for(i = 0; i < pdef->proc_in.nElements; i++) {
1861 const port_proc_signature *sig = pdef->proc_in.elements + i;
1862 if (!sig->has_exceptions) continue;
1863 def = mputprintf(def, "void raise(const %s_exception& "
1864 "raise_exception, const COMPONENT& destination_component);\n",
1865 sig->name);
1866 src = mputprintf(src, "void %s::raise(const %s_exception& "
1867 "raise_exception, const COMPONENT& destination_component)\n"
1868 "{\n"
1869 "if (!is_started) TTCN_error(\"Raising an exception on port %%s, "
1870 "which is not started.\", port_name);\n"
1871 "if (!destination_component.is_bound()) TTCN_error(\"Unbound "
1872 "component reference in the to clause of raise operation.\");\n"
1873 "const TTCN_Logger::Severity log_sev = "
1874 "destination_component==SYSTEM_COMPREF?"
1875 "TTCN_Logger::PORTEVENT_PMOUT:TTCN_Logger::PORTEVENT_PCOUT;\n"
1876 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1877 "TTCN_Logger::log_procport_send(port_name, "
1878 "TitanLoggerApiSimple::Port__oper::exception__op, destination_component,\n"
1879 " CHARSTRING(0, NULL),\n"
1880 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1881 " raise_exception.log(),"
1882 " TTCN_Logger::end_event_log2str()));\n"
1883 "}\n"
1884 "if (destination_component == SYSTEM_COMPREF) ",
1885 class_name, sig->name);
1886 if (pdef->testport_type == INTERNAL) {
1887 src = mputstr(src, "TTCN_error(\"Internal port %s cannot raise an "
1888 "exception to system.\", port_name);\n");
1889 } else {
1890 src = mputprintf(src, "outgoing_raise(raise_exception%s);\n",
1891 pdef->testport_type == ADDRESS ? ", NULL" : "");
1892 }
1893 src = mputprintf(src, "else {\n"
1894 "Text_Buf text_buf;\n"
1895 "prepare_exception(text_buf, \"%s\");\n"
1896 "raise_exception.encode_text(text_buf);\n"
1897 "send_data(text_buf, destination_component);\n"
1898 "}\n"
1899 "}\n\n", sig->dispname);
1900
1901 if (pdef->testport_type == ADDRESS) {
1902 def = mputprintf(def, "void raise(const %s_exception& "
1903 "raise_exception, const %s& destination_address);\n",
1904 sig->name, pdef->address_name);
1905 src = mputprintf(src, "void %s::raise(const %s_exception& "
1906 "raise_exception, const %s& destination_address)\n"
1907 "{\n"
1908 "if (!is_started) TTCN_error(\"Raising an exception on port "
1909 "%%s, which is not started.\", port_name);\n"
1910 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMOUT))"
1911 " {\n"
1912 "TTCN_Logger::log_procport_send(port_name, "
1913 "TitanLoggerApiSimple::Port__oper::exception__op, SYSTEM_COMPREF,\n"
1914 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1915 " destination_address.log(),"
1916 " TTCN_Logger::end_event_log2str()),\n"
1917 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1918 " raise_exception.log(),"
1919 " TTCN_Logger::end_event_log2str()));\n"
1920 "}\n"
1921 "outgoing_raise(raise_exception, &destination_address);\n"
1922 "}\n\n",
1923 class_name, sig->name, pdef->address_name);
1924 }
1925
1926 def = mputprintf(def, "void raise(const %s_exception& "
1927 "raise_exception);\n", sig->name);
1928 src = mputprintf(src, "void %s::raise(const %s_exception& "
1929 "raise_exception)\n"
1930 "{\n"
1931 "raise(raise_exception, COMPONENT(get_default_destination()));\n"
1932 "}\n\n", class_name, sig->name);
1933 }
1934
1935 if (pdef->testport_type != INTERNAL && pdef->port_type == REGULAR) {
1936 /* virtual functions for transmission (implemented by the test port) */
1937 def = mputstr(def, "protected:\n");
1938 /* outgoing_send functions */
1939 for (i = 0; i < pdef->msg_out.nElements; i++) {
1940 def = mputprintf(def, "virtual void outgoing_send("
1941 "const %s& send_par", pdef->msg_out.elements[i].name);
1942 if (pdef->testport_type == ADDRESS) {
1943 def = mputprintf(def, ", const %s *destination_address",
1944 pdef->address_name);
1945 }
1946 def = mputstr(def, ") = 0;\n");
1947 }
1948 /* outgoing_call functions */
1949 for (i = 0; i < pdef->proc_out.nElements; i++) {
1950 def = mputprintf(def, "virtual void outgoing_call("
1951 "const %s_call& call_par", pdef->proc_out.elements[i].name);
1952 if (pdef->testport_type == ADDRESS) {
1953 def = mputprintf(def, ", const %s *destination_address",
1954 pdef->address_name);
1955 }
1956 def = mputstr(def, ") = 0;\n");
1957 }
1958 /* outgoing_reply functions */
1959 for (i = 0; i < pdef->proc_in.nElements; i++) {
1960 if (pdef->proc_in.elements[i].is_noblock) continue;
1961 def = mputprintf(def, "virtual void outgoing_reply("
1962 "const %s_reply& reply_par", pdef->proc_in.elements[i].name);
1963 if (pdef->testport_type == ADDRESS) {
1964 def = mputprintf(def, ", const %s *destination_address",
1965 pdef->address_name);
1966 }
1967 def = mputstr(def, ") = 0;\n");
1968 }
1969 /* outgoing_raise functions */
1970 for(i = 0; i < pdef->proc_in.nElements; i++) {
1971 if (!pdef->proc_in.elements[i].has_exceptions) continue;
1972 def = mputprintf(def, "virtual void outgoing_raise("
1973 "const %s_exception& raise_exception",
1974 pdef->proc_in.elements[i].name);
1975 if (pdef->testport_type == ADDRESS) {
1976 def = mputprintf(def, ", const %s *destination_address",
1977 pdef->address_name);
1978 }
1979 def = mputstr(def, ") = 0;\n");
1980 }
1981 def = mputstr(def, "public:\n");
1982 }
1983
1984 /* Generic receive routines (without message type) */
1985 if (has_msg_queue) {
1986 /* generic receive function */
1987 generate_generic_receive(&def, &src, pdef, class_name, FALSE, FALSE,
1988 FALSE);
1989 /* generic check_receive function */
1990 generate_generic_receive(&def, &src, pdef, class_name, TRUE, FALSE,
1991 FALSE);
1992 /* generic trigger function */
1993 generate_generic_receive(&def, &src, pdef, class_name, FALSE, TRUE,
1994 FALSE);
1995 if (pdef->testport_type == ADDRESS) {
1996 /* generic receive with address */
1997 generate_generic_receive(&def, &src, pdef, class_name, FALSE,
1998 FALSE, TRUE);
1999 /* generic check_receive with address */
2000 generate_generic_receive(&def, &src, pdef, class_name, TRUE,
2001 FALSE, TRUE);
2002 /* generic trigger with address */
2003 generate_generic_receive(&def, &src, pdef, class_name, FALSE,
2004 TRUE, TRUE);
2005 }
2006 }
2007
2008 /* Receive routines with message type */
2009 for (i = 0; i < pdef->msg_in.nElements; i++) {
2010 /* receive */
2011 generate_receive(&def, &src, pdef, class_name, i, FALSE, FALSE, FALSE);
2012 /* check_receive */
2013 generate_receive(&def, &src, pdef, class_name, i, TRUE, FALSE, FALSE);
2014 /* trigger */
2015 generate_receive(&def, &src, pdef, class_name, i, FALSE, TRUE, FALSE);
2016 if (pdef->testport_type == ADDRESS) {
2017 /* receive with address */
2018 generate_receive(&def, &src, pdef, class_name, i, FALSE, FALSE,
2019 TRUE);
2020 /* check_receive with address */
2021 generate_receive(&def, &src, pdef, class_name, i, TRUE, FALSE,
2022 TRUE);
2023 /* trigger with address */
2024 generate_receive(&def, &src, pdef, class_name, i, FALSE, TRUE,
2025 TRUE);
2026 }
2027 }
2028
2029 if (has_incoming_call) {
2030 /* generic getcall function */
2031 generate_generic_getop(GETCALL, &def, &src, pdef, class_name, FALSE,
2032 FALSE);
2033 /* generic check_getcall function */
2034 generate_generic_getop(GETCALL, &def, &src, pdef, class_name, TRUE,
2035 FALSE);
2036 if (pdef->testport_type == ADDRESS) {
2037 /* generic getcall with address */
2038 generate_generic_getop(GETCALL, &def, &src, pdef, class_name,
2039 FALSE, TRUE);
2040 /* generic check_getcall with address */
2041 generate_generic_getop(GETCALL, &def, &src, pdef, class_name,
2042 TRUE, TRUE);
2043 }
2044 }
2045
2046 /* getcall functions */
2047 for (i = 0; i < pdef->proc_in.nElements; i++) {
2048 /* getcall */
2049 generate_getcall(&def, &src, pdef, class_name, i, FALSE, FALSE);
2050 /* check_getcall */
2051 generate_getcall(&def, &src, pdef, class_name, i, TRUE, FALSE);
2052 if (pdef->testport_type == ADDRESS) {
2053 /* getcall with address */
2054 generate_getcall(&def, &src, pdef, class_name, i, FALSE, TRUE);
2055 /* check_getcall with address */
2056 generate_getcall(&def, &src, pdef, class_name, i, TRUE, TRUE);
2057 }
2058 }
2059
2060 if (has_incoming_reply) {
2061 /* generic getreply function */
2062 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name, FALSE,
2063 FALSE);
2064 /* generic check_getreply function */
2065 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name, TRUE,
2066 FALSE);
2067 if (pdef->testport_type == ADDRESS) {
2068 /* generic getreply with address */
2069 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name,
2070 FALSE, TRUE);
2071 /* generic check_getreply with address */
2072 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name,
2073 TRUE, TRUE);
2074 }
2075 }
2076
2077 /* getreply functions */
2078 for (i = 0; i < pdef->proc_out.nElements; i++) {
2079 if (pdef->proc_out.elements[i].is_noblock) continue;
2080 /* getreply */
2081 generate_getreply(&def, &src, pdef, class_name, i, FALSE, FALSE);
2082 /* check_getreply */
2083 generate_getreply(&def, &src, pdef, class_name, i, TRUE, FALSE);
2084 if (pdef->testport_type == ADDRESS) {
2085 /* getreply with address */
2086 generate_getreply(&def, &src, pdef, class_name, i, FALSE, TRUE);
2087 /* check_getreply with address */
2088 generate_getreply(&def, &src, pdef, class_name, i, TRUE, TRUE);
2089 }
2090 }
2091
2092 if (has_incoming_exception) {
2093 /* generic catch (get_exception) function */
2094 generate_generic_getop(CATCH, &def, &src, pdef, class_name, FALSE,
2095 FALSE);
2096 /* generic check_catch function */
2097 generate_generic_getop(CATCH, &def, &src, pdef, class_name, TRUE,
2098 FALSE);
2099 if (pdef->testport_type == ADDRESS) {
2100 /* generic catch (get_exception) with address */
2101 generate_generic_getop(CATCH, &def, &src, pdef, class_name, FALSE,
2102 TRUE);
2103 /* generic check_catch with address */
2104 generate_generic_getop(CATCH, &def, &src, pdef, class_name, TRUE,
2105 TRUE);
2106 }
2107 }
2108
2109 /* catch functions */
2110 for (i = 0; i < pdef->proc_out.nElements; i++) {
2111 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2112 /* catch (get_exception) */
2113 generate_catch(&def, &src, pdef, class_name, i, FALSE, FALSE);
2114 /* check_catch */
2115 generate_catch(&def, &src, pdef, class_name, i, TRUE, FALSE);
2116 if (pdef->testport_type == ADDRESS) {
2117 /* catch (get_exception) with address */
2118 generate_catch(&def, &src, pdef, class_name, i, FALSE, TRUE);
2119 /* check_catch with address */
2120 generate_catch(&def, &src, pdef, class_name, i, TRUE, TRUE);
2121 }
2122 }
2123
2124 def = mputstr(def, "private:\n");
2125
2126 if (pdef->port_type == USER) {
2127 /* incoming_message() functions for the incoming types of the provider
2128 * port type */
2129 for (i = 0; i < pdef->provider_msg_in.nElements; i++) {
2130 const port_msg_mapped_type *mapped_type =
2131 pdef->provider_msg_in.elements + i;
2132 boolean is_simple = mapped_type->nTargets == 1 &&
2133 mapped_type->targets[0].mapping_type == M_SIMPLE;
2134 def = mputprintf(def, "void incoming_message(const %s& "
2135 "incoming_par, component sender_component%s",
2136 mapped_type->name,
2137 (pdef->has_sliding ? ", OCTETSTRING& slider" : ""));
2138 if (pdef->testport_type == ADDRESS) {
2139 def = mputprintf(def, ", const %s *sender_address",
2140 pdef->address_name);
2141 }
2142 def = mputstr(def, ");\n");
2143
2144 src = mputprintf(src, "void %s::incoming_message(const %s& "
2145 "incoming_par, component sender_component%s", class_name,
2146 mapped_type->name,
2147 (pdef->has_sliding ? ", OCTETSTRING& slider" : ""));
2148 if (pdef->testport_type == ADDRESS) {
2149 src = mputprintf(src, ", const %s *sender_address",
2150 pdef->address_name);
2151 }
2152 src = mputstr(src, ")\n"
2153 "{\n"
2154 "if (!is_started) TTCN_error(\"Port %s is not started but a "
2155 "message has arrived on it.\", port_name);\n");
2156 if (pdef->has_sliding) src = mputstr(src, "(void)slider;\n");
2157 if (is_simple) src = mputstr(src, "msg_tail_count++;\n");
2158 src = mputprintf(src, "if (TTCN_Logger::log_this_event("
2159 "TTCN_Logger::PORTEVENT_MQUEUE)) {\n"
2160 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg,"
2161 " port_name, sender_component, msg_tail_count%s,\n",
2162 /* if is_simple==FALSE then this log message is a LIE! */
2163 is_simple?"":"+1"
2164 );
2165 if (pdef->testport_type == ADDRESS) {
2166 src = mputstr(src,
2167 "sender_address ?"
2168 /* Use the comma operator to get an expression of type CHARSTRING */
2169 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2170 " TTCN_Logger::log_char('('), sender_address->log(),"
2171 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2172 );
2173 }
2174 src = mputprintf(src,
2175 /* This empty string may be an operand to a conditional operator from above */
2176 "CHARSTRING(0, NULL),\n"
2177 /* Protect the comma operators from being interpreted as
2178 * function argument separators. */
2179 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2180 " TTCN_Logger::log_event_str(\" %s : \"),"
2181 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2182 "}\n", mapped_type->dispname);
2183 if (is_simple) {
2184 src = mputprintf(src,
2185#ifndef NDEBUG
2186 "// simple mapping\n"
2187#endif
2188 "msg_queue_item *new_item = new msg_queue_item;\n"
2189 "new_item->item_selection = MESSAGE_%lu;\n"
2190 "new_item->message_%lu = new %s(incoming_par);\n"
2191 "new_item->sender_component = sender_component;\n",
2192 (unsigned long) mapped_type->targets[0].target_index,
2193 (unsigned long) mapped_type->targets[0].target_index,
2194 mapped_type->name);
2195 if (pdef->testport_type == ADDRESS) {
2196 src = mputprintf(src, "if (sender_address != NULL) "
2197 "new_item->sender_address = new %s(*sender_address);\n"
2198 "else new_item->sender_address = NULL;\n",
2199 pdef->address_name);
2200 }
2201 src = mputstr(src, "append_to_msg_queue(new_item);\n");
2202 } else src = generate_incoming_mapping(src, pdef, mapped_type);
2203 src = mputstr(src, "}\n\n");
2204 }
2205 } else { /* not user */
2206 /* incoming_message functions */
2207 for (i = 0; i < pdef->msg_in.nElements; i++) {
2208 def = mputprintf(def, "void incoming_message(const %s& "
2209 "incoming_par, component sender_component",
2210 pdef->msg_in.elements[i].name);
2211 if (pdef->testport_type == ADDRESS) {
2212 def = mputprintf(def, ", const %s *sender_address",
2213 pdef->address_name);
2214 }
2215 def = mputstr(def, ");\n");
2216
2217 src = mputprintf(src, "void %s::incoming_message(const %s& "
2218 "incoming_par, component sender_component", class_name,
2219 pdef->msg_in.elements[i].name);
2220 if (pdef->testport_type == ADDRESS) {
2221 src = mputprintf(src, ", const %s *sender_address",
2222 pdef->address_name);
2223 }
2224 src = mputstr(src, ")\n"
2225 "{\n"
2226 "if (!is_started) TTCN_error(\"Port %s is not started but a "
2227 "message has arrived on it.\", port_name);\n"
2228 "msg_tail_count++;\n"
2229 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) "
2230 "{\n"
2231 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg,"
2232 " port_name, sender_component, msg_tail_count,\n"
2233 );
2234 if (pdef->testport_type == ADDRESS) {
2235 src = mputstr(src,
2236 "sender_address ?"
2237 /* Use the comma operator to get an expression of type CHARSTRING */
2238 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2239 " TTCN_Logger::log_char('('), sender_address->log(),"
2240 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2241 );
2242 }
2243 src = mputprintf(src,
2244 /* This empty string may be an operand to a conditional operator from above */
2245 "CHARSTRING(0, NULL),\n"
2246 /* Protect the comma operators from being interpreted as
2247 * function argument separators. */
2248 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2249 " TTCN_Logger::log_event_str(\" %s : \"),"
2250 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2251 "}\n"
2252 "msg_queue_item *new_item = new msg_queue_item;\n"
2253 "new_item->item_selection = MESSAGE_%lu;\n"
2254 "new_item->message_%lu = new %s(incoming_par);\n"
2255 "new_item->sender_component = sender_component;\n",
2256 pdef->msg_in.elements[i].dispname,
2257 (unsigned long) i, (unsigned long) i,
2258 pdef->msg_in.elements[i].name);
2259 if (pdef->testport_type == ADDRESS) {
2260 src = mputprintf(src, "if (sender_address != NULL) "
2261 "new_item->sender_address = new %s(*sender_address);\n"
2262 "else new_item->sender_address = NULL;\n",
2263 pdef->address_name);
2264 }
2265 src = mputstr(src, "append_to_msg_queue(new_item);\n"
2266 "}\n\n");
2267 }
2268 }
2269
2270 /* incoming_call functions */
2271 for (i = 0; i < pdef->proc_in.nElements; i++) {
2272 const port_proc_signature *sig = pdef->proc_in.elements + i;
2273 def = mputprintf(def, "void incoming_call(const %s_call& incoming_par, "
2274 "component sender_component", sig->name);
2275 if (pdef->testport_type == ADDRESS) {
2276 def = mputprintf(def, ", const %s *sender_address",
2277 pdef->address_name);
2278 }
2279 def = mputstr(def, ");\n");
2280 src = mputprintf(src, "void %s::incoming_call(const %s_call& "
2281 "incoming_par, component sender_component", class_name, sig->name);
2282 if (pdef->testport_type == ADDRESS) {
2283 src = mputprintf(src, ", const %s *sender_address",
2284 pdef->address_name);
2285 }
2286 src = mputstr(src, ")\n"
2287 "{\n"
2288 "if (!is_started) TTCN_error(\"Port %s is not started but a call "
2289 "has arrived on it.\", port_name);\n"
2290 "proc_tail_count++;\n"
2291 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PQUEUE)) "
2292 "{\n"
2293 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__call,"
2294 " port_name, sender_component, proc_tail_count,\n"
2295 );
2296 if (pdef->testport_type == ADDRESS) {
2297 src = mputstr(src,
2298 "sender_address ?"
2299 /* Use the comma operator to get an expression of type CHARSTRING */
2300 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2301 " TTCN_Logger::log_char('('), sender_address->log(),"
2302 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2303 );
2304 }
2305 src = mputprintf(src,
2306 /* This empty string may be an operand to a conditional operator from above */
2307 "CHARSTRING(0, NULL),\n"
2308 /* Protect the comma operators from being interpreted as
2309 * function argument separators. */
2310 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2311 " TTCN_Logger::log_char(' '),"
2312 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2313 "}\n"
2314 "proc_queue_item *new_item = new proc_queue_item;\n"
2315 "new_item->item_selection = CALL_%lu;\n"
2316 "new_item->call_%lu = new %s_call(incoming_par);\n"
2317 "new_item->sender_component = sender_component;\n",
2318 (unsigned long) i, (unsigned long) i, sig->name);
2319 if (pdef->testport_type == ADDRESS) {
2320 src = mputprintf(src, "if (sender_address != NULL) "
2321 "new_item->sender_address = new %s(*sender_address);\n"
2322 "else new_item->sender_address = NULL;\n", pdef->address_name);
2323 }
2324 src = mputstr(src, "append_to_proc_queue(new_item);\n"
2325 "}\n\n");
2326 }
2327
2328 /* incoming_reply functions */
2329 for (i = 0; i < pdef->proc_out.nElements; i++) {
2330 const port_proc_signature *sig = pdef->proc_out.elements + i;
2331 if (sig->is_noblock) continue;
2332 def = mputprintf(def, "void incoming_reply(const %s_reply& "
2333 "incoming_par, component sender_component", sig->name);
2334 if (pdef->testport_type == ADDRESS) {
2335 def = mputprintf(def, ", const %s *sender_address",
2336 pdef->address_name);
2337 }
2338 def = mputstr(def, ");\n");
2339 src = mputprintf(src, "void %s::incoming_reply(const %s_reply& "
2340 "incoming_par, component sender_component", class_name,
2341 sig->name);
2342 if (pdef->testport_type == ADDRESS) {
2343 src = mputprintf(src, ", const %s *sender_address",
2344 pdef->address_name);
2345 }
2346 src = mputstr(src, ")\n"
2347 "{\n"
2348 "if (!is_started) TTCN_error(\"Port %s is not started but a reply "
2349 "has arrived on it.\", port_name);\n"
2350 "proc_tail_count++;\n"
2351 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PQUEUE)) "
2352 "{\n"
2353 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__reply,"
2354 " port_name, sender_component, proc_tail_count,\n");
2355 if (pdef->testport_type == ADDRESS) {
2356 src = mputstr(src,
2357 "sender_address ?"
2358 /* Use the comma operator to get an expression of type CHARSTRING */
2359 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2360 " TTCN_Logger::log_char('('), sender_address->log(),"
2361 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : ");
2362 }
2363 src = mputprintf(src,
2364 /* This empty string may be an operand to a conditional operator from above */
2365 "CHARSTRING(0, NULL),\n"
2366 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2367 " TTCN_Logger::log_char(' '),"
2368 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2369 "}\n"
2370 "proc_queue_item *new_item = new proc_queue_item;\n"
2371 "new_item->item_selection = REPLY_%lu;\n"
2372 "new_item->reply_%lu = new %s_reply(incoming_par);\n"
2373 "new_item->sender_component = sender_component;\n",
2374 (unsigned long) i, (unsigned long) i, sig->name);
2375 if (pdef->testport_type == ADDRESS) {
2376 src = mputprintf(src, "if (sender_address != NULL) "
2377 "new_item->sender_address = new %s(*sender_address);\n"
2378 "else new_item->sender_address = NULL;\n",
2379 pdef->address_name);
2380 }
2381 src = mputstr(src, "append_to_proc_queue(new_item);\n"
2382 "}\n\n");
2383 }
2384
2385 /* incoming_exception functions */
2386 for (i = 0; i < pdef->proc_out.nElements; i++) {
2387 const port_proc_signature *sig = pdef->proc_out.elements + i;
2388 if (!sig->has_exceptions) continue;
2389 def = mputprintf(def, "void incoming_exception(const %s_exception& "
2390 "incoming_par, component sender_component", sig->name);
2391 if (pdef->testport_type == ADDRESS) {
2392 def = mputprintf(def, ", const %s *sender_address",
2393 pdef->address_name);
2394 }
2395 def = mputstr(def, ");\n");
2396 src = mputprintf(src,
2397 "void %s::incoming_exception(const %s_exception& incoming_par, "
2398 "component sender_component", class_name, sig->name);
2399 if (pdef->testport_type == ADDRESS) {
2400 src = mputprintf(src, ", const %s *sender_address",
2401 pdef->address_name);
2402 }
2403 src = mputstr(src, ")\n"
2404 "{\n"
2405 "if (!is_started) TTCN_error(\"Port %s is not started but an "
2406 "exception has arrived on it.\", port_name);\n"
2407 "proc_tail_count++;\n"
2408 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PQUEUE)) "
2409 "{\n"
2410 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__exception,"
2411 " port_name, sender_component, proc_tail_count,\n"
2412 );
2413 if (pdef->testport_type == ADDRESS) {
2414 src = mputstr(src,
2415 "sender_address ?"
2416 /* Use the comma operator to get an expression of type CHARSTRING */
2417 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2418 " TTCN_Logger::log_char('('), sender_address->log(),"
2419 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2420 );
2421 }
2422 src = mputprintf(src,
2423 /* This empty string may be an operand to a conditional operator from above */
2424 "CHARSTRING(0, NULL),\n"
2425 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2426 " TTCN_Logger::log_char(' '),"
2427 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2428 "}\n"
2429 "proc_queue_item *new_item = new proc_queue_item;\n"
2430 "new_item->item_selection = EXCEPTION_%lu;\n"
2431 "new_item->exception_%lu = new %s_exception(incoming_par);\n"
2432 "new_item->sender_component = sender_component;\n",
2433 (unsigned long) i, (unsigned long) i, sig->name);
2434 if (pdef->testport_type == ADDRESS) {
2435 src = mputprintf(src, "if (sender_address != NULL) "
2436 "new_item->sender_address = new %s(*sender_address);\n"
2437 "else new_item->sender_address = NULL;\n", pdef->address_name);
2438 }
2439 src = mputstr(src, "append_to_proc_queue(new_item);\n"
2440 "}\n\n");
2441 }
2442
2443 def = mputstr(def, "protected:\n");
2444
2445 if (pdef->testport_type != INTERNAL) {
2446 /** functions provided for the test port to pass incoming messages or
2447 * procedure operations into the queue */
2448 if (pdef->port_type == REGULAR) {
2449 /* inline functions that are used through simple inheritance */
2450 for (i = 0; i < pdef->msg_in.nElements; i++) {
2451 /* wrapper for incoming_message */
2452 def = mputprintf(def, "inline void incoming_message("
2453 "const %s& incoming_par", pdef->msg_in.elements[i].name);
2454 if (pdef->testport_type == ADDRESS) {
2455 def = mputprintf(def, ", const %s *sender_address = NULL",
2456 pdef->address_name);
2457 }
2458 def = mputprintf(def, ") { incoming_message(incoming_par, "
2459 "SYSTEM_COMPREF%s); }\n",
2460 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2461 }
2462 for (i = 0; i < pdef->proc_in.nElements; i++) {
2463 /* wrapper for incoming_call */
2464 def = mputprintf(def, "inline void incoming_call("
2465 "const %s_call& incoming_par",
2466 pdef->proc_in.elements[i].name);
2467 if (pdef->testport_type == ADDRESS) {
2468 def = mputprintf(def, ", const %s *sender_address = NULL",
2469 pdef->address_name);
2470 }
2471 def = mputprintf(def, ") { incoming_call(incoming_par, "
2472 "SYSTEM_COMPREF%s); }\n",
2473 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2474 }
2475 for (i = 0; i < pdef->proc_out.nElements; i++) {
2476 /* wrapper for incoming_reply */
2477 if (pdef->proc_out.elements[i].is_noblock) continue;
2478 def = mputprintf(def, "inline void incoming_reply("
2479 "const %s_reply& incoming_par",
2480 pdef->proc_out.elements[i].name);
2481 if (pdef->testport_type == ADDRESS) {
2482 def = mputprintf(def, ", const %s *sender_address = NULL",
2483 pdef->address_name);
2484 }
2485 def = mputprintf(def, ") { incoming_reply(incoming_par, "
2486 "SYSTEM_COMPREF%s); }\n",
2487 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2488 }
2489 for (i = 0; i < pdef->proc_out.nElements; i++) {
2490 /* wrapper for incoming_exception */
2491 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2492 def = mputprintf(def, "inline void incoming_exception("
2493 "const %s_exception& incoming_par",
2494 pdef->proc_out.elements[i].name);
2495 if (pdef->testport_type == ADDRESS) {
2496 def = mputprintf(def, ", const %s *sender_address = NULL",
2497 pdef->address_name);
2498 }
2499 def = mputprintf(def, ") { incoming_exception(incoming_par, "
2500 "SYSTEM_COMPREF%s); }\n",
2501 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2502 }
2503 } else {
2504 /** implementation of pure virtual functions that are defined in
2505 * the test port class */
2506 /* in case of PROVIDER port types the functions must handle the own
2507 * incoming messages, but in case of USER port types the incoming
2508 * messages of the provider port type must be handled */
2509 size_t nof_messages = pdef->port_type == USER ?
2510 pdef->provider_msg_in.nElements : pdef->msg_in.nElements;
2511 for (i = 0; i < nof_messages; i++) {
2512 /* incoming_message */
2513 const char *message_type = pdef->port_type == USER ?
2514 pdef->provider_msg_in.elements[i].name :
2515 pdef->msg_in.elements[i].name;
2516 def = mputprintf(def, "void incoming_message(const %s& "
2517 "incoming_par", message_type);
2518 if (pdef->testport_type == ADDRESS) {
2519 def = mputprintf(def, ", const %s *sender_address",
2520 pdef->address_name);
2521 }
2522 def = mputstr(def, ");\n");
2523 src = mputprintf(src, "void %s::incoming_message("
2524 "const %s& incoming_par", class_name, message_type);
2525 if (pdef->testport_type == ADDRESS) {
2526 src = mputprintf(src, ", const %s *sender_address",
2527 pdef->address_name);
2528 }
2529 src = mputprintf(src, ")\n"
2530 "{\n"
2531 "incoming_message(incoming_par, SYSTEM_COMPREF%s%s);\n"
2532 "}\n\n",
2533 (pdef->has_sliding ? ", sliding_buffer": ""),
2534 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2535 }
2536 for (i = 0; i < pdef->proc_in.nElements; i++) {
2537 /* incoming_call */
2538 def = mputprintf(def, "void incoming_call(const %s_call& "
2539 "incoming_par", pdef->proc_in.elements[i].name);
2540 if (pdef->testport_type == ADDRESS) {
2541 def = mputprintf(def, ", const %s *sender_address",
2542 pdef->address_name);
2543 }
2544 def = mputstr(def, ");\n");
2545 src = mputprintf(src, "void %s::incoming_call(const %s_call& "
2546 "incoming_par", class_name, pdef->proc_in.elements[i].name);
2547 if (pdef->testport_type == ADDRESS) {
2548 src = mputprintf(src, ", const %s *sender_address",
2549 pdef->address_name);
2550 }
2551 src = mputprintf(src, ")\n"
2552 "{\n"
2553 "incoming_call(incoming_par, SYSTEM_COMPREF%s);\n"
2554 "}\n\n",
2555 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2556 }
2557 for (i = 0; i < pdef->proc_out.nElements; i++) {
2558 /* incoming_reply */
2559 if (pdef->proc_out.elements[i].is_noblock) continue;
2560 def = mputprintf(def, "void incoming_reply(const %s_reply& "
2561 "incoming_par", pdef->proc_out.elements[i].name);
2562 if (pdef->testport_type == ADDRESS) {
2563 def = mputprintf(def, ", const %s *sender_address",
2564 pdef->address_name);
2565 }
2566 def = mputstr(def, ");\n");
2567 src = mputprintf(src, "void %s::incoming_reply(const %s_reply& "
2568 "incoming_par", class_name,
2569 pdef->proc_out.elements[i].name);
2570 if (pdef->testport_type == ADDRESS) {
2571 src = mputprintf(src, ", const %s *sender_address",
2572 pdef->address_name);
2573 }
2574 src = mputprintf(src, ")\n"
2575 "{\n"
2576 "incoming_reply(incoming_par, SYSTEM_COMPREF%s);\n"
2577 "}\n\n",
2578 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2579 }
2580 for (i = 0; i < pdef->proc_out.nElements; i++) {
2581 /* incoming_exception */
2582 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2583 def = mputprintf(def, "void incoming_exception("
2584 "const %s_exception& incoming_par",
2585 pdef->proc_out.elements[i].name);
2586 if (pdef->testport_type == ADDRESS) {
2587 def = mputprintf(def, ", const %s *sender_address",
2588 pdef->address_name);
2589 }
2590 def = mputstr(def, ");\n");
2591 src = mputprintf(src, "void %s::incoming_exception("
2592 "const %s_exception& incoming_par", class_name,
2593 pdef->proc_out.elements[i].name);
2594 if (pdef->testport_type == ADDRESS) {
2595 src = mputprintf(src, ", const %s *sender_address",
2596 pdef->address_name);
2597 }
2598 src = mputprintf(src, ")\n"
2599 "{\n"
2600 "incoming_exception(incoming_par, SYSTEM_COMPREF%s);\n"
2601 "}\n\n",
2602 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2603 }
2604 }
2605 }
2606
2607 if (has_msg_queue) {
2608 size_t nof_messages = pdef->port_type == USER ?
2609 pdef->provider_msg_in.nElements : pdef->msg_in.nElements;
2610 def = mputstr(def, "boolean process_message(const char *message_type, "
2611 "Text_Buf& incoming_buf, component sender_component, OCTETSTRING& slider);\n");
2612 src = mputprintf(src, "boolean %s::process_message("
2613 "const char *message_type, Text_Buf& incoming_buf, "
2614 "component sender_component, OCTETSTRING&%s)\n"
2615 "{\n", class_name,
2616 pdef->has_sliding ? " slider" : "");
2617 for (i = 0; i < nof_messages; i++) {
2618 const char *msg_name, *msg_dispname;
2619 if (pdef->port_type == USER) {
2620 msg_name = pdef->provider_msg_in.elements[i].name;
2621 msg_dispname = pdef->provider_msg_in.elements[i].dispname;
2622 } else {
2623 msg_name = pdef->msg_in.elements[i].name;
2624 msg_dispname = pdef->msg_in.elements[i].dispname;
2625 }
2626 src = mputprintf(src, "if (!strcmp(message_type, \"%s\")) {\n"
2627 "%s incoming_par;\n"
2628 "incoming_par.decode_text(incoming_buf);\n"
2629 "incoming_message(incoming_par, sender_component%s%s);\n"
2630 "return TRUE;\n"
2631 "} else ", msg_dispname, msg_name,
2632 (pdef->has_sliding ? ", slider" : ""),
2633 pdef->testport_type == ADDRESS ? ", NULL" : "");
2634 }
2635 src = mputstr(src, "return FALSE;\n"
2636 "}\n\n");
2637 }
2638
2639 if (has_incoming_call) {
2640 def = mputstr(def, "boolean process_call(const char *signature_name, "
2641 "Text_Buf& incoming_buf, component sender_component);\n");
2642 src = mputprintf(src, "boolean %s::process_call("
2643 "const char *signature_name, Text_Buf& incoming_buf, "
2644 "component sender_component)\n"
2645 "{\n", class_name);
2646 for (i = 0; i < pdef->proc_in.nElements; i++) {
2647 src = mputprintf(src, "if (!strcmp(signature_name, \"%s\")) {\n"
2648 "%s_call incoming_par;\n"
2649 "incoming_par.decode_text(incoming_buf);\n"
2650 "incoming_call(incoming_par, sender_component%s);\n"
2651 "return TRUE;\n"
2652 "} else ", pdef->proc_in.elements[i].dispname,
2653 pdef->proc_in.elements[i].name,
2654 pdef->testport_type == ADDRESS ? ", NULL" : "");
2655 }
2656 src = mputstr(src, "return FALSE;\n"
2657 "}\n\n");
2658 }
2659
2660 if (has_incoming_reply) {
2661 def = mputstr(def, "boolean process_reply(const char *signature_name, "
2662 "Text_Buf& incoming_buf, component sender_component);\n");
2663 src = mputprintf(src, "boolean %s::process_reply("
2664 "const char *signature_name, Text_Buf& incoming_buf, "
2665 "component sender_component)\n"
2666 "{\n", class_name);
2667 for (i = 0; i < pdef->proc_out.nElements; i++) {
2668 if (pdef->proc_out.elements[i].is_noblock) continue;
2669 src = mputprintf(src, "if (!strcmp(signature_name, \"%s\")) {\n"
2670 "%s_reply incoming_par;\n"
2671 "incoming_par.decode_text(incoming_buf);\n"
2672 "incoming_reply(incoming_par, sender_component%s);\n"
2673 "return TRUE;\n"
2674 "} else ", pdef->proc_out.elements[i].dispname,
2675 pdef->proc_out.elements[i].name,
2676 pdef->testport_type == ADDRESS ? ", NULL" : "");
2677 }
2678 src = mputstr(src, "return FALSE;\n"
2679 "}\n\n");
2680 }
2681
2682 if (has_incoming_exception) {
2683 def = mputstr(def, "boolean process_exception("
2684 "const char *signature_name, Text_Buf& incoming_buf, "
2685 "component sender_component);\n");
2686 src = mputprintf(src, "boolean %s::process_exception("
2687 "const char *signature_name, Text_Buf& incoming_buf, "
2688 "component sender_component)\n"
2689 "{\n", class_name);
2690 for (i = 0; i < pdef->proc_out.nElements; i++) {
2691 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2692 src = mputprintf(src, "if (!strcmp(signature_name, \"%s\")) {\n"
2693 "%s_exception incoming_par;\n"
2694 "incoming_par.decode_text(incoming_buf);\n"
2695 "incoming_exception(incoming_par, sender_component%s);\n"
2696 "return TRUE;\n"
2697 "} else ", pdef->proc_out.elements[i].dispname,
2698 pdef->proc_out.elements[i].name,
2699 pdef->testport_type == ADDRESS ? ", NULL" : "");
2700 }
2701 src = mputstr(src, "return FALSE;\n"
2702 "}\n\n");
2703 }
2704
2705 /* Event handler prototype and empty implementation is not generated.
2706 When a port does not wait any events it is correct.
2707 (Call to the event handler will cause a dynamic test case error.) */
2708
2709 def = mputstr(def, "};\n\n");
2710 /* end of base class */
2711
2712 /* Putting everything to the output */
2713
2714 output->header.class_decls = mputprintf(output->header.class_decls,
2715 "class %s;\n", class_name);
2716 if (pdef->testport_type != INTERNAL && pdef->port_type == REGULAR)
2717 output->header.class_decls = mputprintf(output->header.class_decls,
2718 "class %s;\n", pdef->name);
2719
2720 output->header.class_defs = mputstr(output->header.class_defs, def);
2721 Free(def);
2722
2723 if (pdef->testport_type != INTERNAL) {
2724 switch (pdef->port_type) {
2725 case REGULAR:
2726 output->header.testport_includes = mputprintf(
2727 output->header.testport_includes, "#include \"%s.hh\"\n",
2728 duplicate_underscores ? pdef->name : pdef->filename);
2729 break;
2730 case PROVIDER:
2731 output->header.includes = mputprintf(output->header.includes,
2732 "#include \"%s.hh\"\n",
2733 duplicate_underscores ? pdef->name : pdef->filename);
2734 default:
2735 break;
2736 }
2737 }
2738
2739 output->source.methods = mputstr(output->source.methods, src);
2740 Free(src);
2741
2742 Free(class_name);
2743 Free(base_class_name);
2744}
2745
2746void generateTestPortSkeleton(const port_def *pdef)
2747{
2748 char *class_name, *base_class_name;
2749 const char *file_prefix =
2750 duplicate_underscores ? pdef->name : pdef->filename;
2751 size_t i;
2752 char *header_name, *source_name;
2753 char *user_info = NULL;
2754
2755 DEBUG(1, "Generating test port skeleton for port type `%s' ...",
2756 pdef->dispname);
2757
2758 if (pdef->port_type == PROVIDER) {
2759 class_name = mprintf("%s_PROVIDER", pdef->name);
2760 base_class_name = mcopystr("PORT");
2761 } else {
2762 class_name = mcopystr(pdef->name);
2763 base_class_name = mprintf("%s_BASE", pdef->name);
2764 }
2765
2766 if (output_dir != NULL) {
2767 header_name = mprintf("%s/%s.hh", output_dir, file_prefix);
2768 source_name = mprintf("%s/%s.cc", output_dir, file_prefix);
2769 } else {
2770 header_name = mprintf("%s.hh", file_prefix);
2771 source_name = mprintf("%s.cc", file_prefix);
2772 }
2773
2774 if (force_overwrite || get_path_status(header_name) == PS_NONEXISTENT) {
2775 FILE *fp = fopen(header_name, "w");
2776 if (fp == NULL) {
2777 ERROR("Cannot open output test port skeleton header file `%s' for "
2778 "writing: %s", header_name, strerror(errno));
2779 exit(EXIT_FAILURE);
2780 }
2781 if (user_info == NULL) user_info = get_user_info();
2782 fprintf(fp,
2783 "// This Test Port skeleton header file was generated by the\n"
2784 "// TTCN-3 Compiler of the TTCN-3 Test Executor version "
2785 PRODUCT_NUMBER "\n"
2786 "// for %s\n"
2787 COPYRIGHT_STRING "\n\n"
2788 "// You may modify this file. Add your attributes and "
2789 "prototypes of your\n"
2790 "// member functions here.\n\n"
2791 "#ifndef %s_HH\n"
2792 "#define %s_HH\n\n", user_info, pdef->name, pdef->name);
2793 if (pdef->port_type == PROVIDER) {
2794 fprintf(fp, "#include <TTCN3.hh>\n\n"
2795 "// Note: Header file %s.hh must not be included into this "
2796 "file!\n"
2797 "// (because it includes this file)\n"
2798 "// Please add the declarations of message types manually.\n\n",
2799 duplicate_underscores ? pdef->module_name :
2800 pdef->module_dispname);
2801 } else {
2802 fprintf(fp, "#include \"%s.hh\"\n\n",
2803 duplicate_underscores ? pdef->module_name :
2804 pdef->module_dispname);
2805 }
2806 fprintf(fp, "namespace %s {\n\n", pdef->module_name);
2807 fprintf(fp,
2808 "class %s : public %s {\n"
2809 "public:\n"
2810 "\t%s(const char *par_port_name%s);\n"
2811 "\t~%s();\n\n"
2812 "\tvoid set_parameter(const char *parameter_name,\n"
2813 "\t\tconst char *parameter_value);\n\n"
2814 "private:\n"
2815 "\t/* void Handle_Fd_Event(int fd, boolean is_readable,\n"
2816 "\t\tboolean is_writable, boolean is_error); */\n"
2817 "\tvoid Handle_Fd_Event_Error(int fd);\n"
2818 "\tvoid Handle_Fd_Event_Writable(int fd);\n"
2819 "\tvoid Handle_Fd_Event_Readable(int fd);\n"
2820 "\t/* void Handle_Timeout(double time_since_last_call); */\n"
2821 "protected:\n"
2822 "\tvoid user_map(const char *system_port);\n"
2823 "\tvoid user_unmap(const char *system_port);\n\n"
2824 "\tvoid user_start();\n"
2825 "\tvoid user_stop();\n\n",
2826 class_name, base_class_name, class_name,
2827 pdef->port_type == REGULAR ? " = NULL" : "", class_name);
2828
2829 for (i = 0; i < pdef->msg_out.nElements; i++) {
2830 fprintf(fp, "\tvoid outgoing_send(const %s& send_par",
2831 pdef->msg_out.elements[i].name);
2832 if (pdef->testport_type == ADDRESS) {
2833 fprintf(fp, ",\n"
2834 "\t\tconst %s *destination_address", pdef->address_name);
2835 }
2836 fputs(");\n", fp);
2837 }
2838 for (i = 0; i < pdef->proc_out.nElements; i++) {
2839 fprintf(fp, "\tvoid outgoing_call(const %s_call& call_par",
2840 pdef->proc_out.elements[i].name);
2841 if (pdef->testport_type == ADDRESS) {
2842 fprintf(fp, ",\n"
2843 "\t\tconst %s *destination_address", pdef->address_name);
2844 }
2845 fputs(");\n" , fp);
2846 }
2847 for (i = 0; i < pdef->proc_in.nElements; i++) {
2848 if (pdef->proc_in.elements[i].is_noblock) continue;
2849 fprintf(fp, "\tvoid outgoing_reply(const %s_reply& reply_par",
2850 pdef->proc_in.elements[i].name);
2851 if (pdef->testport_type == ADDRESS) {
2852 fprintf(fp, ",\n"
2853 "\t\tconst %s *destination_address", pdef->address_name);
2854 }
2855 fputs(");\n", fp);
2856 }
2857 for (i = 0; i < pdef->proc_in.nElements; i++) {
2858 if (!pdef->proc_in.elements[i].has_exceptions) continue;
2859 fprintf(fp, "\tvoid outgoing_raise(const %s_exception& "
2860 "raise_exception", pdef->proc_in.elements[i].name);
2861 if (pdef->testport_type == ADDRESS) {
2862 fprintf(fp, ",\n"
2863 "\t\tconst %s *destination_address", pdef->address_name);
2864 }
2865 fputs(");\n", fp);
2866 }
2867 if (pdef->port_type == PROVIDER) {
2868 /* pure virtual functions for incoming operations */
2869 for (i = 0; i < pdef->msg_in.nElements; i++) {
2870 fprintf(fp, "\tvirtual void incoming_message(const %s& "
2871 "incoming_par", pdef->msg_in.elements[i].name);
2872 if (pdef->testport_type == ADDRESS) {
2873 fprintf(fp, ",\n"
2874 "\t\tconst %s *sender_address = NULL",
2875 pdef->address_name);
2876 }
2877 fputs(") = 0;\n", fp);
2878 }
2879 for (i = 0; i < pdef->proc_in.nElements; i++) {
2880 fprintf(fp, "\tvirtual void incoming_call(const %s_call& "
2881 "incoming_par", pdef->proc_in.elements[i].name);
2882 if (pdef->testport_type == ADDRESS) {
2883 fprintf(fp, ",\n"
2884 "\t\tconst %s *sender_address = NULL",
2885 pdef->address_name);
2886 }
2887 fputs(") = 0;\n", fp);
2888 }
2889 for (i = 0; i < pdef->proc_out.nElements; i++) {
2890 if (pdef->proc_out.elements[i].is_noblock) continue;
2891 fprintf(fp, "\tvirtual void incoming_reply(const %s_reply& "
2892 "incoming_par", pdef->proc_out.elements[i].name);
2893 if (pdef->testport_type == ADDRESS) {
2894 fprintf(fp, ",\n"
2895 "\t\tconst %s *sender_address = NULL",
2896 pdef->address_name);
2897 }
2898 fputs(") = 0;\n", fp);
2899 }
2900 for (i = 0; i < pdef->proc_out.nElements; i++) {
2901 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2902 fprintf(fp, "\tvirtual void incoming_exception("
2903 "const %s_exception& incoming_par",
2904 pdef->proc_out.elements[i].name);
2905 if (pdef->testport_type == ADDRESS) {
2906 fprintf(fp, ",\n"
2907 "\t\tconst %s *sender_address = NULL",
2908 pdef->address_name);
2909 }
2910 fputs(") = 0;\n", fp);
2911 }
2912 }
2913 fputs("};\n\n", fp);
2914 fputs("} /* end of namespace */\n\n", fp);
2915 fputs("#endif\n", fp);
2916 fclose(fp);
2917 NOTIFY("Test port skeleton header file `%s' was generated for port "
2918 "type `%s'.", header_name, pdef->dispname);
2919 } else {
2920 DEBUG(1, "Test port header file `%s' already exists. It was not "
2921 "overwritten.", header_name);
2922 }
2923
2924 if (force_overwrite || get_path_status(source_name) == PS_NONEXISTENT) {
2925 FILE *fp = fopen(source_name, "w");
2926 if (fp == NULL) {
2927 ERROR("Cannot open output test port skeleton source file `%s' for "
2928 "writing: %s", source_name, strerror(errno));
2929 exit(EXIT_FAILURE);
2930 }
2931 if (user_info == NULL) user_info = get_user_info();
2932 fprintf(fp,
2933 "// This Test Port skeleton source file was generated by the\n"
2934 "// TTCN-3 Compiler of the TTCN-3 Test Executor version "
2935 PRODUCT_NUMBER "\n"
2936 "// for %s\n"
2937 COPYRIGHT_STRING "\n\n"
2938 "// You may modify this file. Complete the body of empty functions and\n"
2939 "// add your member functions here.\n\n"
2940 "#include \"%s.hh\"\n", user_info, file_prefix);
2941 if (pdef->port_type == PROVIDER) {
2942 fprintf(fp, "#include \"%s.hh\"\n",
2943 duplicate_underscores ? pdef->module_name :
2944 pdef->module_dispname);
2945 }
2946 putc('\n', fp);
2947 fprintf(fp, "namespace %s {\n\n", pdef->module_name);
2948 fprintf(fp, "%s::%s(const char *par_port_name)\n"
2949 "\t: %s(par_port_name)\n"
2950 "{\n\n"
2951 "}\n\n"
2952 "%s::~%s()\n"
2953 "{\n\n"
2954 "}\n\n"
2955 "void %s::set_parameter(const char * /*parameter_name*/,\n"
2956 "\tconst char * /*parameter_value*/)\n"
2957 "{\n\n"
2958 "}\n\n"
2959 "/*void %s::Handle_Fd_Event(int fd, boolean is_readable,\n"
2960 "\tboolean is_writable, boolean is_error) {}*/\n\n"
2961 "void %s::Handle_Fd_Event_Error(int /*fd*/)\n"
2962 "{\n\n"
2963 "}\n\n"
2964 "void %s::Handle_Fd_Event_Writable(int /*fd*/)\n"
2965 "{\n\n"
2966 "}\n\n"
2967 "void %s::Handle_Fd_Event_Readable(int /*fd*/)\n"
2968 "{\n\n"
2969 "}\n\n"
2970 "/*void %s::Handle_Timeout(double time_since_last_call) {}*/\n\n"
2971 "void %s::user_map(const char * /*system_port*/)\n"
2972 "{\n\n"
2973 "}\n\n"
2974 "void %s::user_unmap(const char * /*system_port*/)\n"
2975 "{\n\n"
2976 "}\n\n"
2977 "void %s::user_start()\n"
2978 "{\n\n"
2979 "}\n\n"
2980 "void %s::user_stop()\n"
2981 "{\n\n"
2982 "}\n\n", class_name, class_name, base_class_name, class_name,
2983 class_name, class_name, class_name, class_name, class_name,
2984 class_name, class_name, class_name, class_name, class_name,
2985 class_name);
2986
2987 for (i = 0; i < pdef->msg_out.nElements; i++) {
2988 fprintf(fp, "void %s::outgoing_send(const %s& /*send_par*/",
2989 class_name, pdef->msg_out.elements[i].name);
2990 if (pdef->testport_type == ADDRESS) {
2991 fprintf(fp, ",\n"
2992 "\tconst %s * /*destination_address*/", pdef->address_name);
2993 }
2994 fputs(")\n"
2995 "{\n\n"
2996 "}\n\n", fp);
2997 }
2998 for (i = 0; i < pdef->proc_out.nElements; i++) {
2999 fprintf(fp, "void %s::outgoing_call(const %s_call& /*call_par*/",
3000 class_name, pdef->proc_out.elements[i].name);
3001 if (pdef->testport_type == ADDRESS) {
3002 fprintf(fp, ",\n"
3003 "\tconst %s * /*destination_address*/", pdef->address_name);
3004 }
3005 fputs(")\n"
3006 "{\n\n"
3007 "}\n\n", fp);
3008 }
3009 for (i = 0; i < pdef->proc_in.nElements; i++) {
3010 if (pdef->proc_in.elements[i].is_noblock) continue;
3011 fprintf(fp, "void %s::outgoing_reply(const %s_reply& /*reply_par*/",
3012 class_name, pdef->proc_in.elements[i].name);
3013 if (pdef->testport_type == ADDRESS) {
3014 fprintf(fp, ",\n"
3015 "\tconst %s * /*destination_address*/", pdef->address_name);
3016 }
3017 fputs(")\n"
3018 "{\n\n"
3019 "}\n\n", fp);
3020 }
3021 for (i = 0; i < pdef->proc_in.nElements; i++) {
3022 if (!pdef->proc_in.elements[i].has_exceptions) continue;
3023 fprintf(fp, "void %s::outgoing_raise"
3024 "(const %s_exception& /*raise_exception*/",
3025 class_name, pdef->proc_in.elements[i].name);
3026 if (pdef->testport_type == ADDRESS) {
3027 fprintf(fp, ",\n"
3028 "\tconst %s * /*destination_address*/", pdef->address_name);
3029 }
3030 fputs(")\n"
3031 "{\n\n"
3032 "}\n\n", fp);
3033 }
3034 fputs("} /* end of namespace */\n\n", fp);
3035 fclose(fp);
3036 NOTIFY("Test port skeleton source file `%s' was generated for port "
3037 "type `%s'.", source_name, pdef->dispname);
3038 } else {
3039 DEBUG(1, "Test port source file `%s' already exists. It was not "
3040 "overwritten.", source_name);
3041 }
3042
3043 Free(class_name);
3044 Free(base_class_name);
3045 Free(header_name);
3046 Free(source_name);
3047 Free(user_info);
3048}
This page took 0.134329 seconds and 5 git commands to generate.