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