Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / ttcn3 / port.c
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
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"
3abe9331 623 "} else if (!value_template.match(*my_head->message_%lu%s)) {\n",
624 failed_status, (unsigned long) message_index,
625 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
626 src = mputprintf(src,
627 "const TTCN_Logger::Severity log_sev = %s;\n"
628 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
629 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::message__,\n"
630 "port_name, my_head->sender_component,\n"
631 "TitanLoggerApiSimple::MatchingFailureType_reason::message__does__not__match__template,\n"
632 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 633 " value_template.log_match(*my_head->message_%lu%s),\n"
970ed795
EL
634 " TTCN_Logger::end_event_log2str())"
635 ");\n"
636 "}\n",
637 (is_address ?
638 "TTCN_Logger::MATCHING_MMUNSUCC" :
639 "my_head->sender_component==SYSTEM_COMPREF ? "
640 "TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC"),
3abe9331 641 (unsigned long) message_index,
642 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
643 if (is_trigger) src = mputstr(src, "remove_msg_queue_head();\n");
644 src = mputprintf(src, "return %s;\n"
645 "} else {\n"
646 "if (value_ptr != NULL) *value_ptr = *my_head->message_%lu;\n"
647 "if (sender_ptr != NULL) *sender_ptr = %smy_head->%s;\n",
648 failed_status, (unsigned long) message_index, is_address ? "*" : "",
649 is_address ? "sender_address" : "sender_component");
650
651 if (is_address) {
652 src = mputprintf(src,
653 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMSUCCESS)) "
654 "{\n"
655 "TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,\n"
656 "port_name, SYSTEM_COMPREF,\n"
657 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_MMSUCCESS, TRUE),"
3abe9331 658 " value_template.log_match(*my_head->message_%lu%s),\n"
970ed795
EL
659 " TTCN_Logger::end_event_log2str()));\n"
660 "}\n"
661 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MMRECV)) "
662 "{\n"
663 "TTCN_Logger::log_msgport_recv(port_name, "
664 "TitanLoggerApiSimple::Msg__port__recv_operation::%s__op, my_head->sender_component,\n"
665 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMRECV,TRUE),"
666 "my_head->sender_address->log(), TTCN_Logger::end_event_log2str()),\n"
667 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMRECV,TRUE),"
668 " TTCN_Logger::log_event_str(\": %s : \"),\n"
669 "my_head->message_%lu->log(), TTCN_Logger::end_event_log2str()),\n"
670 "msg_head_count+1);\n"
3abe9331 671 "}\n", (unsigned long) message_index,
672 (omit_in_value_list ? ", TRUE" : ""), logger_operation,
970ed795
EL
673 message_type->dispname, (unsigned long) message_index);
674 } else {
675 src = mputprintf(src,
676 "TTCN_Logger::Severity log_sev = "
677 "my_head->sender_component==SYSTEM_COMPREF?"
678 "TTCN_Logger::MATCHING_MMSUCCESS:TTCN_Logger::MATCHING_MCSUCCESS;\n"
679 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
680 "TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::message__,\n"
681 "port_name, my_head->sender_component,\n"
682 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 683 " value_template.log_match(*my_head->message_%lu%s),\n"
970ed795
EL
684 " TTCN_Logger::end_event_log2str()));\n"
685 "}\n"
686 "log_sev = my_head->sender_component==SYSTEM_COMPREF?"
687 "TTCN_Logger::PORTEVENT_MMRECV:TTCN_Logger::PORTEVENT_MCRECV;\n"
688 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
689 "TTCN_Logger::log_msgport_recv(port_name, "
690 "TitanLoggerApiSimple::Msg__port__recv_operation::%s__op,\n"
691 "my_head->sender_component, CHARSTRING(0, NULL),\n"
692 "(TTCN_Logger::begin_event(log_sev,TRUE), TTCN_Logger::log_event_str(\": %s : \"),\n"
693 "my_head->message_%lu->log(), TTCN_Logger::end_event_log2str()),\n"
694 "msg_head_count+1);\n"
3abe9331 695 "}\n", (unsigned long) message_index,
696 (omit_in_value_list ? ", TRUE" : ""), logger_operation,
970ed795
EL
697 message_type->dispname, (unsigned long) message_index);
698 }
699
700 if (!is_check) src = mputstr(src, "remove_msg_queue_head();\n");
701 src = mputstr(src, "return ALT_YES;\n"
702 "}\n"
703 "}\n\n");
704
705 *def_ptr = def;
706 *src_ptr = src;
707}
708
709typedef enum { GETCALL, GETREPLY, CATCH } getop_t;
710enum { NOT_ADDRESS = 0, IS_ADDRESS };
711enum { NOT_CHECK = 0, IS_CHECK };
712
713/** Writes (check_)?getcall, (check_)?getreply, get_exception and check_catch methods.
714 * These are called from PORT::any(_check)?_(getcall|getreply|catch) and
715 * PORT::check; they are the implementation of "any port.getcall" etc.
716 *
717 * @param getop the operation (call, reply or catch)
718 * @param def_ptr pointer to a string which will be written to the header
719 * @param src_ptr pointer to a string which will be written as the source file
720 * @param pdef
721 * @param class_name
722 * @param is_check
723 * @param is_address
724 */
725static void generate_generic_getop(getop_t getop,
726 char **def_ptr, char **src_ptr, const port_def *pdef,
727 const char *class_name, boolean is_check, boolean is_address)
728{
729 char *def = *def_ptr, *src = *src_ptr;
730 const char *function_name = NULL, *operation_name = NULL,
731 *entity_name_prefix = NULL, *entity_name = NULL;
732 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
733 size_t i;
734
735 switch (getop) {
736 case GETCALL:
737 function_name = is_check ? "check_getcall" : "getcall";
738 operation_name = is_check ? "Check-getcall" : "Getcall";
739 entity_name_prefix = "a";
740 entity_name = "call";
741 break;
742 case GETREPLY:
743 function_name = is_check ? "check_getreply" : "getreply";
744 operation_name = is_check ? "Check-getreply" : "Getreply";
745 entity_name_prefix = "a";
746 entity_name = "reply";
747 break;
748 case CATCH:
749 function_name = is_check ? "check_catch" : "get_exception";
750 operation_name = is_check ? "Check-catch" : "Catch";
751 entity_name_prefix = "an";
752 entity_name = "exception";
753 }
754
755 def = mputprintf(def, "alt_status %s(const %s_template& "
756 "sender_template, %s *sender_ptr);\n", function_name, sender_type,
757 sender_type);
758 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
759 "sender_template, %s *sender_ptr)\n"
760 "{\n"
761 "if (proc_queue_head == NULL) {\n"
762 "if (is_started) return ALT_MAYBE;\n"
763 "else {\n"
764 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
765 "port %%s failed: Port is not started and the queue is empty.\", "
766 "port_name);\n"
767 "return ALT_NO;\n"
768 "}\n", class_name, function_name, sender_type, sender_type);
769 if (is_address) {
770 src = mputprintf(src, "} else if (proc_queue_head->sender_component "
771 "!= SYSTEM_COMPREF) {\n"
772 "TTCN_Logger::log(TTCN_Logger::MATCHING_PMUNSUCC, \"Matching "
773 "on port %%s failed: Sender of the first entity in the queue is"
774 " not the system.\", port_name);\n"
775 "return ALT_NO;\n"
776 "} else if (proc_queue_head->sender_address == NULL) {\n"
777 "TTCN_error(\"%s operation on port %%s requires the address "
778 "of the sender, which was not given by the test port.\", "
779 "port_name);\n"
780 "return ALT_NO;\n"
781 "} else if (!sender_template.match("
782 "*proc_queue_head->sender_address)) {\n"
783 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
784 "{\n"
785 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
786 "port_name, SYSTEM_COMPREF,\n"
787 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
788 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),"
789 " sender_template.log_match(*proc_queue_head->sender_address), "
790 " TTCN_Logger::end_event_log2str()));\n"
791 "}\n"
792 "return ALT_NO;\n", operation_name);
793 } else {
794 src = mputstr(src, "} else if (!sender_template.match("
795 "proc_queue_head->sender_component)) {\n"
796 "const TTCN_Logger::Severity log_sev = "
797 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
798 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
799 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
800 "TTCN_Logger::begin_event(log_sev);\n"
801 "TTCN_Logger::log_event(\"Matching on port %s failed: "
802 "Sender of the first entity in the queue does not match the "
803 "from clause: \", port_name);\n"
804 "sender_template.log_match(proc_queue_head->sender_component);\n"
805 "TTCN_Logger::end_event();\n"
806 "}\n"
807 "return ALT_NO;\n");
808 }
809 src = mputstr(src, "} else switch (proc_queue_head->item_selection) {\n");
810 switch (getop) {
811 case GETCALL:
812 for (i = 0; i < pdef->proc_in.nElements; i++) {
813 src = mputprintf(src, "case CALL_%lu:\n", (unsigned long) i);
814 }
815 break;
816 case GETREPLY:
817 for (i = 0; i < pdef->proc_out.nElements; i++) {
818 if (!pdef->proc_out.elements[i].is_noblock)
819 src = mputprintf(src, "case REPLY_%lu:\n", (unsigned long) i);
820 }
821 break;
822 case CATCH:
823 for (i = 0; i < pdef->proc_out.nElements; i++) {
824 if (pdef->proc_out.elements[i].has_exceptions)
825 src = mputprintf(src, "case EXCEPTION_%lu:\n",
826 (unsigned long) i);
827 }
828 }
829 src = mputstr(src, "{\n"
830 "if (sender_ptr != NULL) *sender_ptr = ");
831 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
832 else src = mputstr(src, "proc_queue_head->sender_component;\n");
833
834 if (is_address) {
835 src = mputprintf(src, "TTCN_Logger::log("
836 "TTCN_Logger::MATCHING_PMSUCCESS, \"Matching on port %%s "
837 "succeeded.\", port_name);\n"
838 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMIN)) {\n"
839 "TTCN_Logger::log_procport_recv(port_name, "
840 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component,\n"
841 "%s, CHARSTRING(0, NULL), msg_head_count+1);\n"
842 "}\n", entity_name, (is_check ? "TRUE" : "FALSE"));
843 } else {
844 src = mputprintf(src, "TTCN_Logger::log("
845 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
846 "TTCN_Logger::MATCHING_PMSUCCESS:TTCN_Logger::MATCHING_PCSUCCESS"
847 ", \"Matching on port %%s succeeded.\", port_name);\n"
848 "const TTCN_Logger::Severity log_sev = "
849 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
850 "TTCN_Logger::PORTEVENT_PMIN:TTCN_Logger::PORTEVENT_PCIN;\n"
851 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
852 "TTCN_Logger::log_procport_recv(port_name, "
853 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component,\n"
854 "%s, CHARSTRING(0, NULL), msg_head_count+1);\n"
855 "}\n", entity_name, (is_check ? "TRUE" : "FALSE"));
856 }
857
858 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
859 src = mputprintf(src, "return ALT_YES;\n"
860 "}\n"
861 "default:\n"
862 "TTCN_Logger::log(%s, \"Matching on port %%s "
863 "failed: First entity in the queue is not %s %s.\", port_name);\n"
864 "return ALT_NO;\n"
865 "}\n"
866 "}\n\n",
867 is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" :
868 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
869 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
870 entity_name_prefix, entity_name);
871
872 *def_ptr = def;
873 *src_ptr = src;
874}
875
876
877/** Generate code for logging
878 *
879 * Called from generate_getcall, generate_getreply, generate_catch
880 *
881 * @param src_ptr
882 * @param op_str "call", "reply" or "exception"
883 * @param match_str "catch_template.log_match", "getcall_template.log_match_call"
884 * or "getreply_template.log_match_reply"
885 * @param is_address
886 * @param is_check
887 * @param signature_index
888 */
889static void generate_proc_incoming_data_logging(char **src_ptr,
890 const char *op_str, const char *match_str, boolean is_address,
891 boolean is_check, size_t signature_index)
892{
893 if (is_address) {
894 *src_ptr = mputprintf(*src_ptr,
895 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMSUCCESS)) "
896 "{\n"
897 "TTCN_Logger::log_matching_success(TitanLoggerApiSimple::PortType::procedure__,\n"
898 "port_name, SYSTEM_COMPREF,\n"
899 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMSUCCESS, TRUE),"
3abe9331 900 " %s(*proc_queue_head->%s_%lu%s),\n"
970ed795
EL
901 " TTCN_Logger::end_event_log2str()));\n"
902 "}\n"
903 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMIN)) "
904 "{\n"
905 "TTCN_Logger::log_procport_recv(port_name, "
906 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component, %s,\n"
907 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMIN, TRUE),"
908 " proc_queue_head->%s_%lu->log(),"
909 " TTCN_Logger::end_event_log2str()),\n"
910 "msg_head_count+1);\n"
911 "}\n", match_str, op_str, (unsigned long) signature_index,
3abe9331 912 (omit_in_value_list ? ", TRUE" : ""),
970ed795
EL
913 op_str, (is_check ? "TRUE" : "FALSE"), op_str, (unsigned long) signature_index);
914 } else {
915 *src_ptr = mputprintf(*src_ptr, "TTCN_Logger::Severity log_sev = "
916 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
917 "TTCN_Logger::MATCHING_PMSUCCESS:TTCN_Logger::MATCHING_PCSUCCESS;\n"
918 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
919 "TTCN_Logger::begin_event(log_sev);\n"
920 "TTCN_Logger::log_event(\"Matching on port %%s "
921 "succeeded: \", port_name);\n"
922 "%s(*proc_queue_head->%s_%lu);\n"
923 "TTCN_Logger::end_event();\n"
924 "}\n"
925 "log_sev = proc_queue_head->sender_component==SYSTEM_COMPREF?"
926 "TTCN_Logger::PORTEVENT_PMIN:TTCN_Logger::PORTEVENT_PCIN;\n"
927 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
928 "TTCN_Logger::log_procport_recv(port_name, "
929 "TitanLoggerApiSimple::Port__oper::%s__op, proc_queue_head->sender_component, %s,\n"
930 "(TTCN_Logger::begin_event(log_sev, TRUE),"
931 " proc_queue_head->%s_%lu->log(),"
932 " TTCN_Logger::end_event_log2str()),\n"
933 "msg_head_count+1"
934 ");\n"
935 "}\n", match_str, op_str, (unsigned long) signature_index,
936 op_str, (is_check ? "TRUE" : "FALSE"),
937 op_str, (unsigned long) signature_index);
938 }
939}
940
941static void generate_getcall(char **def_ptr, char **src_ptr,
942 const port_def *pdef, const char *class_name, size_t signature_index,
943 boolean is_check, boolean is_address)
944{
945 char *def = *def_ptr, *src = *src_ptr;
946 const port_proc_signature *signature =
947 pdef->proc_in.elements + signature_index;
948 const char *function_name = is_check ? "check_getcall" : "getcall";
949 const char *operation_name = is_check ? "Check-getcall" : "Getcall";
950 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
951
952 def = mputprintf(def, "alt_status %s(const %s_template& "
953 "getcall_template, const %s_template& sender_template, "
954 "const %s_call_redirect& param_ref, %s *sender_ptr);\n",
955 function_name, signature->name, sender_type, signature->name,
956 sender_type);
957
958 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
959 "getcall_template, const %s_template& sender_template, "
960 "const %s_call_redirect& param_ref, %s *sender_ptr)\n"
961 "{\n"
962 "if (proc_queue_head == NULL) {\n"
963 "if (is_started) return ALT_MAYBE;\n"
964 "else {\n"
965 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
966 "port %%s failed: Port is not started and the queue is empty.\", "
967 "port_name);\n"
968 "return ALT_NO;\n"
969 "}\n", class_name, function_name, signature->name, sender_type,
970 signature->name, sender_type);
971 if (is_address) {
972 src = mputprintf(src,
973 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
974 "{\n"
975 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
976 "port_name, proc_queue_head->sender_component,\n"
977 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__is__not__system ,\n"
978 "CHARSTRING(0,NULL));\n"
979 "return ALT_NO;\n"
980 "} else if (proc_queue_head->sender_address == NULL) {\n"
981 "TTCN_error(\"%s operation on port %%s requires the address "
982 "of the sender, which was not given by the test port.\", "
983 "port_name);\n"
984 "return ALT_NO;\n"
985 "} else if (!sender_template.match("
986 "*proc_queue_head->sender_address)) {\n"
987 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
988 "{\n"
989 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
990 "port_name, SYSTEM_COMPREF,\n"
991 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
992 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),"
993 " sender_template.log_match(*proc_queue_head->sender_address), "
994 " TTCN_Logger::end_event_log2str()));\n"
995 "}\n"
996 "return ALT_NO;\n", operation_name);
997 } else {
998 src = mputstr(src, "} else if (!sender_template.match("
999 "proc_queue_head->sender_component)) {\n"
1000 "const TTCN_Logger::Severity log_sev = "
1001 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1002 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC;\n"
1003 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1004 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1005 "port_name, proc_queue_head->sender_component,\n"
1006 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1007 "(TTCN_Logger::begin_event(log_sev, TRUE),"
1008 " sender_template.log_match(proc_queue_head->sender_component), "
1009 " TTCN_Logger::end_event_log2str()));\n"
1010 "}\n"
1011 "return ALT_NO;\n");
1012 }
1013 src = mputprintf(src,
1014 "} else if (proc_queue_head->item_selection != CALL_%lu) {\n"
1015 "TTCN_Logger::log(%s, \"Matching on port %%s "
1016 "failed: The first entity in the queue is not a call for "
1017 "signature %s.\", port_name);\n"
1018 "return ALT_NO;\n"
1019 "} else if (!getcall_template.match_call"
3abe9331 1020 "(*proc_queue_head->call_%lu%s)) {\n",
970ed795
EL
1021 (unsigned long) signature_index,
1022 is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" :
1023 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1024 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
3abe9331 1025 signature->dispname, (unsigned long) signature_index,
1026 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
1027 src = mputprintf(src,
1028 "const TTCN_Logger::Severity log_sev = %s;\n"
1029 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1030 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1031 "port_name, proc_queue_head->sender_component,\n"
1032 "TitanLoggerApiSimple::MatchingFailureType_reason::parameters__of__call__do__not__match__template,\n"
1033 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 1034 " getcall_template.log_match_call(*proc_queue_head->call_%lu%s),"
970ed795
EL
1035 " TTCN_Logger::end_event_log2str()));\n"
1036 "}\n"
1037 "return ALT_NO;\n"
1038 "} else {\n"
1039 "param_ref.set_parameters(*proc_queue_head->call_%lu);\n"
1040 "if (sender_ptr != NULL) *sender_ptr = ",
1041 (is_address ?
1042 "TTCN_Logger::MATCHING_PMUNSUCC" :
1043 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1044 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC"),
3abe9331 1045 (unsigned long) signature_index,
1046 (omit_in_value_list ? ", TRUE" : ""),
1047 (unsigned long) signature_index);
970ed795
EL
1048 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
1049 else src = mputstr(src, "proc_queue_head->sender_component;\n");
1050
1051 generate_proc_incoming_data_logging(&src, "call",
1052 "getcall_template.log_match_call", is_address, is_check, signature_index);
1053
1054 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
1055 src = mputstr(src,
1056 "return ALT_YES;\n"
1057 "}\n"
1058 "}\n\n");
1059
1060 *def_ptr = def;
1061 *src_ptr = src;
1062}
1063
1064static void generate_getreply(char **def_ptr, char **src_ptr,
1065 const port_def *pdef, const char *class_name, size_t signature_index,
1066 boolean is_check, boolean is_address)
1067{
1068 char *def = *def_ptr, *src = *src_ptr;
1069 const port_proc_signature *signature =
1070 pdef->proc_out.elements + signature_index;
1071 const char *function_name = is_check ? "check_getreply" : "getreply";
1072 const char *operation_name = is_check ? "Check-getreply" : "Getreply";
1073 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
1074
1075 def = mputprintf(def, "alt_status %s(const %s_template& "
1076 "getreply_template, const %s_template& sender_template, "
1077 "const %s_reply_redirect& param_ref, %s *sender_ptr);\n",
1078 function_name, signature->name, sender_type, signature->name,
1079 sender_type);
1080
1081 src = mputprintf(src, "alt_status %s::%s(const %s_template& "
1082 "getreply_template, const %s_template& sender_template, "
1083 "const %s_reply_redirect& param_ref, %s *sender_ptr)\n"
1084 "{\n"
1085 "if (proc_queue_head == NULL) {\n"
1086 "if (is_started) return ALT_MAYBE;\n"
1087 "else {\n"
1088 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
1089 "port %%s failed: Port is not started and the queue is empty.\", "
1090 "port_name);\n"
1091 "return ALT_NO;\n"
1092 "}\n", class_name, function_name, signature->name, sender_type,
1093 signature->name, sender_type);
1094 if (is_address) {
1095 src = mputprintf(src,
1096 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
1097 "{\n"
1098 "TTCN_Logger::log(TTCN_Logger::MATCHING_PMUNSUCC, \"Matching "
1099 "on port %%s failed: Sender of the first entity in the queue "
1100 "is not the system.\", port_name);\n"
1101 "return ALT_NO;\n"
1102 "} else if (proc_queue_head->sender_address == NULL) {\n"
1103 "TTCN_error(\"%s operation on port %%s requires the address "
1104 "of the sender, which was not given by the test port.\", "
1105 "port_name);\n"
1106 "return ALT_NO;\n"
1107 "} else if (!sender_template.match("
1108 "*proc_queue_head->sender_address)) {\n"
1109 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
1110 "{\n"
1111 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1112 "port_name, SYSTEM_COMPREF,\n"
1113 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1114 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),"
1115 " sender_template.log_match(*proc_queue_head->sender_address), "
1116 " TTCN_Logger::end_event_log2str()));\n"
1117 "}\n"
1118 "return ALT_NO;\n", operation_name);
1119 } else {
1120 src = mputstr(src, "} else if (!sender_template.match("
1121 "proc_queue_head->sender_component)) {\n"
1122 "const TTCN_Logger::Severity log_sev = "
1123 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1124 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
1125 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1126 "TTCN_Logger::begin_event(log_sev);\n"
1127 "TTCN_Logger::log_event(\"Matching on port %s failed: "
1128 "Sender of the first entity in the queue does not match the "
1129 "from clause: \", port_name);\n"
1130 "sender_template.log_match(proc_queue_head->sender_component);\n"
1131 "TTCN_Logger::end_event();\n"
1132 "}\n"
1133 "return ALT_NO;\n");
1134 }
1135 src = mputprintf(src,
1136 "} else if (proc_queue_head->item_selection != REPLY_%lu) {\n"
1137 "TTCN_Logger::log(%s, \"Matching on port %%s "
1138 "failed: The first entity in the queue is not a reply for "
1139 "signature %s.\", port_name);\n"
1140 "return ALT_NO;\n"
1141 "} else if (!getreply_template.match_reply"
3abe9331 1142 "(*proc_queue_head->reply_%lu%s)) {\n", (unsigned long) signature_index,
970ed795
EL
1143 is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" :
1144 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1145 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
3abe9331 1146 signature->dispname, (unsigned long) signature_index,
1147 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
1148
1149 src = mputprintf(src,
1150 "const TTCN_Logger::Severity log_sev = %s;\n"
1151 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1152 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1153 "port_name, proc_queue_head->sender_component,\n"
1154 "TitanLoggerApiSimple::MatchingFailureType_reason::parameters__of__reply__do__not__match__template,\n"
1155 "(TTCN_Logger::begin_event(log_sev, TRUE),"
3abe9331 1156 " getreply_template.log_match_reply(*proc_queue_head->reply_%lu%s), "
970ed795
EL
1157 " TTCN_Logger::end_event_log2str()));\n"
1158 "}\n"
1159 "return ALT_NO;\n"
1160 "} else {\n"
1161 "param_ref.set_parameters(*proc_queue_head->reply_%lu);\n"
1162 "if (sender_ptr != NULL) *sender_ptr = ",
1163 (is_address ?
1164 "TTCN_Logger::MATCHING_PMUNSUCC" :
1165 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1166 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC"),
3abe9331 1167 (unsigned long) signature_index,
1168 (omit_in_value_list ? ", TRUE" : ""),
1169 (unsigned long) signature_index);
970ed795
EL
1170 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
1171 else src = mputstr(src, "proc_queue_head->sender_component;\n");
1172
1173 generate_proc_incoming_data_logging(&src, "reply",
1174 "getreply_template.log_match_reply", is_address, is_check, signature_index);
1175
1176 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
1177 src = mputstr(src,
1178 "return ALT_YES;\n"
1179 "}\n"
1180 "}\n\n");
1181
1182 *def_ptr = def;
1183 *src_ptr = src;
1184}
1185
1186static void generate_catch(char **def_ptr, char **src_ptr,
1187 const port_def *pdef, const char *class_name, size_t signature_index,
1188 boolean is_check, boolean is_address)
1189{
1190 char *def = *def_ptr, *src = *src_ptr;
1191 const port_proc_signature *signature =
1192 pdef->proc_out.elements + signature_index;
1193 const char *function_name = is_check ? "check_catch" : "get_exception";
1194 const char *operation_name = is_check ? "Check-catch" : "Catch";
1195 const char *sender_type = is_address ? pdef->address_name : "COMPONENT";
1196
1197 def = mputprintf(def, "alt_status %s(const %s_exception_template& "
1198 "catch_template, const %s_template& sender_template, "
1199 "%s *sender_ptr);\n",
1200 function_name, signature->name, sender_type, sender_type);
1201
1202 src = mputprintf(src, "alt_status %s::%s(const %s_exception_template& "
1203 "catch_template, const %s_template& sender_template, "
1204 "%s *sender_ptr)\n"
1205 "{\n"
1206 "if (proc_queue_head == NULL) {\n"
1207 "if (is_started) return ALT_MAYBE;\n"
1208 "else {\n"
1209 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
1210 "port %%s failed: Port is not started and the queue is empty.\", "
1211 "port_name);\n"
1212 "return ALT_NO;\n"
1213 "}\n", class_name, function_name, signature->name, sender_type,
1214 sender_type);
1215 if (is_address) {
1216 src = mputprintf(src,
1217 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
1218 "{\n"
1219 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1220 "port_name, proc_queue_head->sender_component,\n"
1221 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__is__not__system,\n"
1222 "CHARSTRING(0, NULL));\n"
1223
1224 "return ALT_NO;\n"
1225 "} else if (proc_queue_head->sender_address == NULL) {\n"
1226 "TTCN_error(\"%s operation on port %%s requires the address "
1227 "of the sender, which was not given by the test port.\", "
1228 "port_name);\n"
1229 "return ALT_NO;\n"
1230 "} else if (!sender_template.match("
1231 "*proc_queue_head->sender_address)) {\n"
1232 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
1233 "{\n"
1234 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1235 "port_name, proc_queue_head->sender_component,\n"
1236 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1237 "(TTCN_Logger::begin_event(TTCN_Logger::MATCHING_PMUNSUCC, TRUE),\n"
1238 " sender_template.log_match(*proc_queue_head->sender_address),\n"
1239 " TTCN_Logger::end_event_log2str()));\n"
1240 "}\n"
1241 "return ALT_NO;\n", operation_name);
1242 } else {
1243 src = mputstr(src, "} else if (!sender_template.match("
1244 "proc_queue_head->sender_component)) {\n"
1245 "const TTCN_Logger::Severity log_sev = "
1246 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1247 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
1248 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1249 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1250 "port_name, proc_queue_head->sender_component,\n"
1251 "TitanLoggerApiSimple::MatchingFailureType_reason::sender__does__not__match__from__clause,\n"
1252 "(TTCN_Logger::begin_event(log_sev, TRUE),\n"
1253 " sender_template.log_match(proc_queue_head->sender_component),\n"
1254 " TTCN_Logger::end_event_log2str()));\n"
1255 "}\n"
1256 "return ALT_NO;\n");
1257 }
1258 src = mputprintf(src,
1259 "} else if (proc_queue_head->item_selection != EXCEPTION_%lu) {\n"
1260 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1261 "port_name, %s,\n"
1262 "TitanLoggerApiSimple::MatchingFailureType_reason::not__an__exception__for__signature,\n"
1263 "CHARSTRING(\"%s\"));\n"
1264 "return ALT_NO;\n"
1265 "} else if (!catch_template.match"
3abe9331 1266 "(*proc_queue_head->exception_%lu%s)) {\n",
970ed795
EL
1267 (unsigned long) signature_index,
1268 (is_address ? "SYSTEM_COMPREF": "proc_queue_head->sender_component"),
3abe9331 1269 signature->dispname, (unsigned long) signature_index,
1270 (omit_in_value_list ? ", TRUE" : ""));
970ed795
EL
1271 if (is_address) {
1272 src = mputstr(src, "if (TTCN_Logger::log_this_event("
1273 "TTCN_Logger::MATCHING_PMUNSUCC)) {\n");
1274 } else {
1275 src = mputstr(src, "const TTCN_Logger::Severity log_sev = "
1276 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1277 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC;\n"
1278 "if (TTCN_Logger::log_this_event(log_sev)) {\n");
1279 }
1280 src = mputprintf(src,
1281 "TTCN_Logger::log_matching_failure(TitanLoggerApiSimple::PortType::procedure__,\n"
1282 "port_name, proc_queue_head->sender_component,\n"
1283 "TitanLoggerApiSimple::MatchingFailureType_reason::exception__does__not__match__template,\n"
1284 "(TTCN_Logger::begin_event(%s, TRUE),\n"
3abe9331 1285 " catch_template.log_match(*proc_queue_head->exception_%lu%s),\n"
970ed795
EL
1286 " TTCN_Logger::end_event_log2str()));\n"
1287 "}\n"
1288 "return ALT_NO;\n"
1289 "} else {\n"
1290 "catch_template.set_value(*proc_queue_head->exception_%lu);\n"
1291 "if (sender_ptr != NULL) *sender_ptr = ",
1292 (is_address ? "TTCN_Logger::MATCHING_PMUNSUCC" : "log_sev"),
3abe9331 1293 (unsigned long) signature_index,
1294 (omit_in_value_list ? ", TRUE" : ""),
1295 (unsigned long) signature_index);
970ed795
EL
1296 if (is_address) src = mputstr(src, "*proc_queue_head->sender_address;\n");
1297 else src = mputstr(src, "proc_queue_head->sender_component;\n");
1298
1299 generate_proc_incoming_data_logging(&src, "exception",
1300 "catch_template.log_match", is_address, is_check, signature_index);
1301
1302 if (!is_check) src = mputstr(src, "remove_proc_queue_head();\n");
1303 src = mputstr(src,
1304 "return ALT_YES;\n"
1305 "}\n"
1306 "}\n\n");
1307
1308 *def_ptr = def;
1309 *src_ptr = src;
1310}
1311
1312#ifdef __SUNPRO_C
1313#define SUNPRO_PUBLIC "public:\n"
1314#define SUNPRO_PRIVATE "private:\n"
1315#else
1316#define SUNPRO_PUBLIC
1317#define SUNPRO_PRIVATE
1318#endif
1319
1320
1321void defPortClass(const port_def* pdef, output_struct* output)
1322{
1323 char *def = NULL, *src = NULL;
1324 char *class_name, *base_class_name;
1325 size_t i;
1326 boolean has_incoming_call, has_incoming_reply, has_incoming_exception;
1327 boolean has_msg_queue, has_proc_queue;
1328
1329 if (pdef->testport_type == INTERNAL) {
1330 class_name = mcopystr(pdef->name);
1331 base_class_name = mcopystr("PORT");
1332 } else {
1333 switch (pdef->port_type) {
1334 case REGULAR:
1335 class_name = mprintf("%s_BASE", pdef->name);
1336 base_class_name = mcopystr("PORT");
1337 break;
1338 case PROVIDER:
1339 class_name = mcopystr(pdef->name);
1340 base_class_name = mprintf("%s_PROVIDER", pdef->name);
1341 break;
1342 case USER:
1343 class_name = mcopystr(pdef->name);
1344 base_class_name = mprintf("%s_PROVIDER", pdef->provider_name);
1345 break;
1346 default:
1347 FATAL_ERROR("defPortClass(): invalid port type");
1348 }
1349 }
1350
1351 has_incoming_call = pdef->proc_in.nElements > 0;
1352
1353 has_incoming_reply = FALSE;
1354 for (i = 0; i < pdef->proc_out.nElements; i++) {
1355 if (!pdef->proc_out.elements[i].is_noblock) {
1356 has_incoming_reply = TRUE;
1357 break;
1358 }
1359 }
1360
1361 has_incoming_exception = FALSE;
1362 for (i = 0; i < pdef->proc_out.nElements; i++) {
1363 if (pdef->proc_out.elements[i].has_exceptions) {
1364 has_incoming_exception = TRUE;
1365 break;
1366 }
1367 }
1368
1369 has_msg_queue = pdef->msg_in.nElements > 0;
1370 has_proc_queue = has_incoming_call || has_incoming_reply ||
1371 has_incoming_exception;
1372
1373 def = mprintf("class %s : public %s {\n", class_name, base_class_name);
1374
1375 /* private data types and member functions for queue management */
1376 if (has_msg_queue) {
1377 /* data structures for the message queue */
1378 def = mputstr(def,
1379 SUNPRO_PUBLIC
1380 "enum msg_selection { ");
1381 for (i = 0; i < pdef->msg_in.nElements; i++) {
1382 if (i > 0) def = mputstr(def, ", ");
1383 def = mputprintf(def, "MESSAGE_%lu", (unsigned long) i);
1384 }
1385 def = mputstr(def, " };\n"
1386 SUNPRO_PRIVATE
1387 "struct msg_queue_item : public msg_queue_item_base {\n"
1388 "msg_selection item_selection;\n"
1389 "union {\n");
1390 for (i = 0; i < pdef->msg_in.nElements; i++)
1391 def = mputprintf(def, "%s *message_%lu;\n",
1392 pdef->msg_in.elements[i].name, (unsigned long) i);
1393
1394 def = mputstr(def, "};\n"
1395 "component sender_component;\n");
1396 if (pdef->testport_type == ADDRESS) {
1397 def = mputprintf(def, "%s *sender_address;\n", pdef->address_name);
1398 }
1399 def = mputstr(def, "};\n\n");
1400 if (pdef->has_sliding) {
1401 def = mputprintf(def, "OCTETSTRING sliding_buffer;\n");
1402 }
1403 def = mputstr(def, "void remove_msg_queue_head();\n");
1404 src = mputprintf(src,
1405 "void %s::remove_msg_queue_head()\n"
1406 "{\n"
1407 "msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;\n"
1408 "switch (my_head->item_selection) {\n", class_name);
1409 for (i = 0; i < pdef->msg_in.nElements; i++)
1410 src = mputprintf(src, "case MESSAGE_%lu:\n"
1411 "delete (my_head)->message_%lu;\n"
1412 "break;\n", (unsigned long) i, (unsigned long) i);
1413 src = mputstr(src, "default:\n"
1414 "TTCN_error(\"Internal error: Invalid message selector in the "
1415 "queue of port %s.\", port_name);\n"
1416 "}\n");
1417 if (pdef->testport_type == ADDRESS) {
1418 src = mputstr(src, "delete ((msg_queue_item*)msg_queue_head)->sender_address;\n");
1419 }
1420 src = mputstr(src,
1421 "msg_queue_item_base *next_item = msg_queue_head->next_item;\n"
1422 /* Make sure to delete the derived class; no virtual destructor. */
1423 "delete (msg_queue_item*)msg_queue_head;\n"
1424 "msg_queue_head = next_item;\n"
1425 "if (next_item == NULL) msg_queue_tail = NULL;\n"
1426 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::extract__msg, "
1427 "port_name, 0, ++msg_head_count, CHARSTRING(0,NULL), CHARSTRING(0,NULL));"
1428 "}\n\n");
1429 } /* if has_msg_queue */
1430
1431 if (has_proc_queue) {
1432 /* data structures for the procedure queue */
1433 boolean is_first = TRUE;
1434 def = mputstr(def,
1435 SUNPRO_PUBLIC
1436 "enum proc_selection { ");
1437 for (i = 0; i < pdef->proc_in.nElements; i++) {
1438 if (is_first) is_first = FALSE;
1439 else def = mputstr(def, ", ");
1440 def = mputprintf(def, "CALL_%lu", (unsigned long) i);
1441 }
1442 for (i = 0; i < pdef->proc_out.nElements; i++) {
1443 if (pdef->proc_out.elements[i].is_noblock) continue;
1444 if (is_first) is_first = FALSE;
1445 else def = mputstr(def, ", ");
1446 def = mputprintf(def, "REPLY_%lu", (unsigned long) i);
1447 }
1448 for (i = 0; i < pdef->proc_out.nElements; i++) {
1449 if (!pdef->proc_out.elements[i].has_exceptions) continue;
1450 if (is_first) is_first = FALSE;
1451 else def = mputstr(def, ", ");
1452 def = mputprintf(def, "EXCEPTION_%lu", (unsigned long) i);
1453 }
1454 def = mputstr(def, " };\n"
1455 SUNPRO_PRIVATE
1456 "struct proc_queue_item {\n"
1457 "proc_selection item_selection;\n"
1458 "union {\n");
1459 for (i = 0; i < pdef->proc_in.nElements; i++) {
1460 def = mputprintf(def, "%s_call *call_%lu;\n",
1461 pdef->proc_in.elements[i].name, (unsigned long) i);
1462 }
1463 for (i = 0; i < pdef->proc_out.nElements; i++) {
1464 if (pdef->proc_out.elements[i].is_noblock) continue;
1465 def = mputprintf(def, "%s_reply *reply_%lu;\n",
1466 pdef->proc_out.elements[i].name, (unsigned long) i);
1467 }
1468 for (i = 0; i < pdef->proc_out.nElements; i++) {
1469 if (!pdef->proc_out.elements[i].has_exceptions) continue;
1470 def = mputprintf(def, "%s_exception *exception_%lu;\n",
1471 pdef->proc_out.elements[i].name, (unsigned long) i);
1472 }
1473 def = mputstr(def, "};\n"
1474 "component sender_component;\n");
1475 if (pdef->testport_type == ADDRESS) {
1476 def = mputprintf(def, "%s *sender_address;\n", pdef->address_name);
1477 }
1478 def = mputstr(def, "proc_queue_item *next_item;\n"
1479 "} *proc_queue_head, *proc_queue_tail;\n");
1480
1481 def = mputstr(def, "void append_to_proc_queue("
1482 "proc_queue_item *new_item);\n");
1483 src = mputprintf(src, "void %s::append_to_proc_queue("
1484 "proc_queue_item *new_item)\n"
1485 "{\n"
1486 "new_item->next_item = NULL;\n"
1487 "if (proc_queue_tail != NULL) "
1488 "proc_queue_tail->next_item = new_item;\n"
1489 "else proc_queue_head = new_item;\n"
1490 "proc_queue_tail = new_item;\n"
1491 "}\n\n", class_name);
1492
1493 def = mputstr(def, "void remove_proc_queue_head();\n");
1494 src = mputprintf(src,
1495 "void %s::remove_proc_queue_head()\n"
1496 "{\n"
1497 "switch (proc_queue_head->item_selection) {\n", class_name);
1498 for (i = 0; i < pdef->proc_in.nElements; i++) {
1499 src = mputprintf(src, "case CALL_%lu:\n"
1500 "delete proc_queue_head->call_%lu;\n"
1501 "break;\n", (unsigned long) i, (unsigned long) i);
1502 }
1503 for (i = 0; i < pdef->proc_out.nElements; i++) {
1504 if (pdef->proc_out.elements[i].is_noblock) continue;
1505 src = mputprintf(src, "case REPLY_%lu:\n"
1506 "delete proc_queue_head->reply_%lu;\n"
1507 "break;\n", (unsigned long) i, (unsigned long) i);
1508 }
1509 for (i = 0; i < pdef->proc_out.nElements; i++) {
1510 if (!pdef->proc_out.elements[i].has_exceptions) continue;
1511 src = mputprintf(src, "case EXCEPTION_%lu:\n"
1512 "delete proc_queue_head->exception_%lu;\n"
1513 "break;\n", (unsigned long) i, (unsigned long) i);
1514 }
1515 src = mputstr(src, "default:\n"
1516 "TTCN_error(\"Internal error: Invalid signature selector in "
1517 "the queue of port %s.\", port_name);\n"
1518 "}\n");
1519 if (pdef->testport_type == ADDRESS) {
1520 src = mputstr(src, "delete proc_queue_head->sender_address;\n");
1521 }
1522 src = mputstr(src,
1523 "proc_queue_item *next_item = proc_queue_head->next_item;\n"
1524 "delete proc_queue_head;\n"
1525 "proc_queue_head = next_item;\n"
1526 "if (next_item == NULL) proc_queue_tail = NULL;\n"
1527 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::extract__op, "
1528 "port_name, 0, ++proc_head_count, CHARSTRING(0,NULL), CHARSTRING(0,NULL));"
1529 "}\n\n");
1530 }
1531
1532 /* clear_queue */
1533 if (has_msg_queue || has_proc_queue) {
1534 def = mputstr(def, "protected:\n"
1535 "void clear_queue();\n");
1536 src = mputprintf(src, "void %s::clear_queue()\n"
1537 "{\n", class_name);
1538 if (has_msg_queue) src = mputstr(src,
1539 "while (msg_queue_head != NULL) remove_msg_queue_head();\n");
1540 if (has_proc_queue) src = mputstr(src,
1541 "while (proc_queue_head != NULL) remove_proc_queue_head();\n");
1542 if (pdef->has_sliding) src = mputstr(src,
1543 "sliding_buffer = OCTETSTRING(0, 0);\n");
1544 src = mputstr(src, "}\n\n");
1545 }
1546
1547
1548 def = mputstr(def, "public:\n");
1549
1550 /* constructor */
1551 def = mputprintf(def, "%s(const char *par_port_name", class_name);
1552 if (pdef->testport_type == INTERNAL || pdef->port_type != REGULAR) {
1553 /* the default argument is needed if the generated class implements
1554 * the port type (i.e. it is not a base class) */
1555 def = mputstr(def, " = NULL");
1556 }
1557 def = mputstr(def, ");\n");
1558 src = mputprintf(src, "%s::%s(const char *par_port_name)\n"
1559 " : %s(par_port_name)\n"
1560 "%s"
1561 "{\n", class_name, class_name, base_class_name,
1562 (pdef->has_sliding ? " , sliding_buffer(0, 0)" : ""));
1563 if (has_msg_queue) src = mputstr(src, "msg_queue_head = NULL;\n"
1564 "msg_queue_tail = NULL;\n");
1565 if (has_proc_queue) src = mputstr(src, "proc_queue_head = NULL;\n"
1566 "proc_queue_tail = NULL;\n");
1567 src = mputstr(src, "}\n\n");
1568
1569 /* destructor */
1570 if (has_msg_queue || has_proc_queue) {
1571 def = mputprintf(def, "~%s();\n", class_name);
1572 src = mputprintf(src, "%s::~%s()\n"
1573 "{\n"
1574 "clear_queue();\n"
1575 "}\n\n", class_name, class_name);
1576 }
1577
1578 /* send functions */
1579 for (i = 0; i < pdef->msg_out.nElements; i++) {
1580 const port_msg_mapped_type *msg = pdef->msg_out.elements + i;
1581
1582 def = mputprintf(def, "void send(const %s& send_par, "
1583 "const COMPONENT& destination_component);\n", msg->name);
1584
1585 src = mputprintf(src, "void %s::send(const %s& send_par, "
1586 "const COMPONENT& destination_component)\n"
1587 "{\n"
1588 "if (!is_started) TTCN_error(\"Sending a message on port %%s, which "
1589 "is not started.\", port_name);\n"
1590 "if (!destination_component.is_bound()) "
1591 "TTCN_error(\"Unbound component reference in the to clause of send "
1592 "operation.\");\n"
1593 "const TTCN_Logger::Severity log_sev = "
1594 "destination_component==SYSTEM_COMPREF?"
1595 "TTCN_Logger::PORTEVENT_MMSEND:TTCN_Logger::PORTEVENT_MCSEND;\n"
1596 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1597 "TTCN_Logger::log_msgport_send(port_name, destination_component,\n"
1598 "(TTCN_Logger::begin_event(log_sev, TRUE), TTCN_Logger::log_event_str(\" %s : \"),\n"
1599 "send_par.log(), TTCN_Logger::end_event_log2str()));\n"
1600 "}\n", class_name, msg->name, msg->dispname);
1601 if (pdef->port_type != USER || (msg->nTargets == 1 &&
1602 msg->targets[0].mapping_type == M_SIMPLE)) {
1603 /* the same message type goes through the external interface */
1604 src = mputstr(src, "if (destination_component == SYSTEM_COMPREF) ");
1605 if (pdef->testport_type == INTERNAL) {
1606 src = mputstr(src, "TTCN_error(\"Message cannot be sent to system "
1607 "on internal port %s.\", port_name);\n");
1608 } else {
1609 src = mputprintf(src, "outgoing_send(send_par%s);\n",
1610 pdef->testport_type == ADDRESS ? ", NULL" : "");
1611 }
1612 src = mputprintf(src, "else {\n"
1613 "Text_Buf text_buf;\n"
1614 "prepare_message(text_buf, \"%s\");\n"
1615 "send_par.encode_text(text_buf);\n"
1616 "send_data(text_buf, destination_component);\n"
1617 "}\n", msg->dispname);
1618 } else {
1619 /* the message type is mapped to another outgoing type of the
1620 * external interface */
1621 src = generate_send_mapping(src, pdef, msg, FALSE);
1622 }
1623 src = mputstr(src, "}\n\n");
1624
1625 if (pdef->testport_type == ADDRESS) {
1626 def = mputprintf(def, "void send(const %s& send_par, "
1627 "const %s& destination_address);\n", msg->name,
1628 pdef->address_name);
1629
1630 src = mputprintf(src, "void %s::send(const %s& send_par, "
1631 "const %s& destination_address)\n"
1632 "{\n"
1633 "if (!is_started) TTCN_error(\"Sending a message on port %%s, "
1634 "which is not started.\", port_name);\n"
1635 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MMSEND))"
1636 "{\n"
1637 "TTCN_Logger::log_msgport_send(port_name, SYSTEM_COMPREF,\n"
1638 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MMSEND, TRUE),"
1639 " TTCN_Logger::log_event_str(\"(\"),"
1640 " destination_address.log(),"
1641 " TTCN_Logger::log_event_str(\") %s : \"),"
1642 " send_par.log(),"
1643 " TTCN_Logger::end_event_log2str()));\n"
1644 "}\n", class_name, msg->name, pdef->address_name, msg->dispname);
1645 if (pdef->port_type != USER || (msg->nTargets == 1 &&
1646 msg->targets[0].mapping_type == M_SIMPLE)) {
1647 src = mputstr(src, "outgoing_send(send_par, "
1648 "&destination_address);\n");
1649 } else src = generate_send_mapping(src, pdef, msg, TRUE);
1650 src = mputstr(src, "}\n\n");
1651 }
1652
1653 def = mputprintf(def, "void send(const %s& send_par);\n", msg->name);
1654 src = mputprintf(src, "void %s::send(const %s& send_par)\n"
1655 "{\n"
1656 "send(send_par, COMPONENT(get_default_destination()));\n"
1657 "}\n\n", class_name, msg->name);
1658
1659 def = mputprintf(def, "void send(const %s_template& send_par, "
1660 "const COMPONENT& destination_component);\n", msg->name);
1661 src = mputprintf(src, "void %s::send(const %s_template& send_par, "
1662 "const COMPONENT& destination_component)\n"
1663 "{\n"
1664 "const %s& send_par_value = %s(send_par.valueof());\n"
1665 "send(send_par_value, destination_component);\n"
1666 "}\n\n", class_name, msg->name, msg->name, msg->name);
1667
1668 if (pdef->testport_type == ADDRESS) {
1669 def = mputprintf(def, "void send(const %s_template& send_par, "
1670 "const %s& destination_address);\n", msg->name,
1671 pdef->address_name);
1672 src = mputprintf(src, "void %s::send(const %s_template& send_par, "
1673 "const %s& destination_address)\n"
1674 "{\n"
1675 "const %s& send_par_value = %s(send_par.valueof());\n"
1676 "send(send_par_value, destination_address);\n"
1677 "}\n\n", class_name, msg->name, pdef->address_name, msg->name, msg->name);
1678 }
1679
1680 def = mputprintf(def, "void send(const %s_template& send_par);\n",
1681 msg->name);
1682 src = mputprintf(src, "void %s::send(const %s_template& send_par)\n"
1683 "{\n"
1684 "const %s& send_par_value = %s(send_par.valueof());\n"
1685 "send(send_par_value, COMPONENT(get_default_destination()));\n"
1686 "}\n\n", class_name, msg->name, msg->name, msg->name);
1687 }
1688
1689 /* call functions */
1690 for (i = 0; i < pdef->proc_out.nElements; i++) {
1691 const port_proc_signature *sig = pdef->proc_out.elements + i;
1692 def = mputprintf(def, "void call(const %s_template& call_template, "
1693 "const COMPONENT& destination_component);\n", sig->name);
1694 src = mputprintf(src, "void %s::call(const %s_template& "
1695 "call_template, const COMPONENT& destination_component)\n"
1696 "{\n"
1697 "if (!is_started) TTCN_error(\"Calling a signature on port %%s, "
1698 "which is not started.\", port_name);\n"
1699 "if (!destination_component.is_bound()) TTCN_error(\"Unbound "
1700 "component reference in the to clause of call operation.\");\n"
1701 "const %s_call& call_tmp = call_template.create_call();\n"
1702 "const TTCN_Logger::Severity log_sev = "
1703 "destination_component==SYSTEM_COMPREF?"
1704 "TTCN_Logger::PORTEVENT_PMOUT:TTCN_Logger::PORTEVENT_PCOUT;\n"
1705 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1706
1707 "TTCN_Logger::log_procport_send(port_name,"
1708 "TitanLoggerApiSimple::Port__oper::call__op, destination_component,\n"
1709 "CHARSTRING(0,NULL),"
1710 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1711 " call_tmp.log(),"
1712 " TTCN_Logger::end_event_log2str()));\n"
1713 "}\n"
1714 "if (destination_component == SYSTEM_COMPREF) ",
1715 class_name, sig->name, sig->name);
1716 if (pdef->testport_type == INTERNAL) {
1717 src = mputstr(src, "TTCN_error(\"Internal port %s cannot send "
1718 "call to system.\", port_name);\n");
1719 } else {
1720 src = mputprintf(src, "outgoing_call(call_tmp%s);\n",
1721 pdef->testport_type == ADDRESS ? ", NULL" : "");
1722 }
1723 src = mputprintf(src, "else {\n"
1724 "Text_Buf text_buf;\n"
1725 "prepare_call(text_buf, \"%s\");\n"
1726 "call_tmp.encode_text(text_buf);\n"
1727 "send_data(text_buf, destination_component);\n"
1728 "}\n"
1729 "}\n\n", sig->dispname);
1730
1731 if (pdef->testport_type == ADDRESS) {
1732 def = mputprintf(def, "void call(const %s_template& "
1733 "call_template, const %s& destination_address);\n",
1734 sig->name, pdef->address_name);
1735 src = mputprintf(src, "void %s::call(const %s_template& "
1736 "call_template, const %s& destination_address)\n"
1737 "{\n"
1738 "if (!is_started) TTCN_error(\"Calling a signature on port "
1739 "%%s, which is not started.\", port_name);\n"
1740 "const %s_call& call_tmp = call_template.create_call();\n"
1741 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMOUT))"
1742 " {\n"
1743 "TTCN_Logger::log_procport_send(port_name, "
1744 "TitanLoggerApiSimple::Port__oper::call__op, SYSTEM_COMPREF,\n"
1745 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1746 " destination_address.log(),"
1747 " TTCN_Logger::end_event_log2str()),\n"
1748 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1749 " call_tmp.log(),"
1750 " TTCN_Logger::end_event_log2str()));\n"
1751 "}\n"
1752 "outgoing_call(call_tmp, &destination_address);\n"
1753 "}\n\n",
1754 class_name, sig->name, pdef->address_name, sig->name);
1755 }
1756
1757 def = mputprintf(def, "void call(const %s_template& "
1758 "call_template);\n", sig->name);
1759 src = mputprintf(src, "void %s::call(const %s_template& "
1760 "call_template)\n"
1761 "{\n"
1762 "call(call_template, COMPONENT(get_default_destination()));\n"
1763 "}\n\n", class_name, sig->name);
1764 }
1765
1766 /* reply functions */
1767 for (i = 0; i < pdef->proc_in.nElements; i++) {
1768 const port_proc_signature *sig = pdef->proc_in.elements + i;
1769 if (sig->is_noblock) continue;
1770 def = mputprintf(def,"void reply(const %s_template& "
1771 "reply_template, const COMPONENT& destination_component);\n",
1772 sig->name);
1773 src = mputprintf(src, "void %s::reply(const %s_template& "
1774 "reply_template, const COMPONENT& destination_component)\n"
1775 "{\n"
1776 "if (!is_started) TTCN_error(\"Replying to a signature on port "
1777 "%%s, which is not started.\", port_name);\n"
1778 "if (!destination_component.is_bound()) TTCN_error(\"Unbound "
1779 "component reference in the to clause of reply operation.\");\n"
1780 "const %s_reply& reply_tmp = reply_template.create_reply();\n"
1781 "const TTCN_Logger::Severity log_sev = "
1782 "destination_component==SYSTEM_COMPREF?"
1783 "TTCN_Logger::PORTEVENT_PMOUT:TTCN_Logger::PORTEVENT_PCOUT;\n"
1784 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1785 "TTCN_Logger::log_procport_send(port_name, "
1786 "TitanLoggerApiSimple::Port__oper::reply__op, destination_component,\n"
1787 " CHARSTRING(0, NULL),\n"
1788 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1789 " reply_tmp.log(),"
1790 " TTCN_Logger::end_event_log2str()));\n"
1791 "}\n"
1792 "if (destination_component == SYSTEM_COMPREF) ",
1793 class_name, sig->name, sig->name);
1794 if (pdef->testport_type == INTERNAL) {
1795 src = mputstr(src, "TTCN_error(\"Internal port %s cannot send "
1796 "reply to system.\", port_name);\n");
1797 } else {
1798 src = mputprintf(src, "outgoing_reply(reply_tmp%s);\n",
1799 pdef->testport_type == ADDRESS ? ", NULL" : "");
1800 }
1801 src = mputprintf(src, "else {\n"
1802 "Text_Buf text_buf;\n"
1803 "prepare_reply(text_buf, \"%s\");\n"
1804 "reply_tmp.encode_text(text_buf);\n"
1805 "send_data(text_buf, destination_component);\n"
1806 "}\n"
1807 "}\n\n", sig->dispname);
1808
1809 if (pdef->testport_type == ADDRESS) {
1810 def = mputprintf(def, "void reply(const %s_template& "
1811 "reply_template, const %s& destination_address);\n",
1812 sig->name, pdef->address_name);
1813 src = mputprintf(src, "void %s::reply(const %s_template& "
1814 "reply_template, const %s& destination_address)\n"
1815 "{\n"
1816 "if (!is_started) TTCN_error(\"Replying to a call on port "
1817 "%%s, which is not started.\", port_name);\n"
1818 "const %s_reply& reply_tmp = reply_template.create_reply();\n"
1819 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMOUT))"
1820 " {\n"
1821 "TTCN_Logger::log_procport_send(port_name, "
1822 "TitanLoggerApiSimple::Port__oper::reply__op, SYSTEM_COMPREF,\n"
1823 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1824 " destination_address.log(),"
1825 " TTCN_Logger::end_event_log2str()),\n"
1826 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1827 " reply_tmp.log(),"
1828 " TTCN_Logger::end_event_log2str()));\n"
1829 "}\n"
1830 "outgoing_reply(reply_tmp, &destination_address);\n"
1831 "}\n\n",
1832 class_name, sig->name, pdef->address_name, sig->name);
1833 }
1834
1835 def = mputprintf(def, "void reply(const %s_template& "
1836 "reply_template);\n", sig->name);
1837 src = mputprintf(src, "void %s::reply(const %s_template& "
1838 "reply_template)\n"
1839 "{\n"
1840 "reply(reply_template, COMPONENT(get_default_destination()));\n"
1841 "}\n\n", class_name, sig->name);
1842 }
1843
1844 /* raise functions */
1845 for(i = 0; i < pdef->proc_in.nElements; i++) {
1846 const port_proc_signature *sig = pdef->proc_in.elements + i;
1847 if (!sig->has_exceptions) continue;
1848 def = mputprintf(def, "void raise(const %s_exception& "
1849 "raise_exception, const COMPONENT& destination_component);\n",
1850 sig->name);
1851 src = mputprintf(src, "void %s::raise(const %s_exception& "
1852 "raise_exception, const COMPONENT& destination_component)\n"
1853 "{\n"
1854 "if (!is_started) TTCN_error(\"Raising an exception on port %%s, "
1855 "which is not started.\", port_name);\n"
1856 "if (!destination_component.is_bound()) TTCN_error(\"Unbound "
1857 "component reference in the to clause of raise operation.\");\n"
1858 "const TTCN_Logger::Severity log_sev = "
1859 "destination_component==SYSTEM_COMPREF?"
1860 "TTCN_Logger::PORTEVENT_PMOUT:TTCN_Logger::PORTEVENT_PCOUT;\n"
1861 "if (TTCN_Logger::log_this_event(log_sev)) {\n"
1862 "TTCN_Logger::log_procport_send(port_name, "
1863 "TitanLoggerApiSimple::Port__oper::exception__op, destination_component,\n"
1864 " CHARSTRING(0, NULL),\n"
1865 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1866 " raise_exception.log(),"
1867 " TTCN_Logger::end_event_log2str()));\n"
1868 "}\n"
1869 "if (destination_component == SYSTEM_COMPREF) ",
1870 class_name, sig->name);
1871 if (pdef->testport_type == INTERNAL) {
1872 src = mputstr(src, "TTCN_error(\"Internal port %s cannot raise an "
1873 "exception to system.\", port_name);\n");
1874 } else {
1875 src = mputprintf(src, "outgoing_raise(raise_exception%s);\n",
1876 pdef->testport_type == ADDRESS ? ", NULL" : "");
1877 }
1878 src = mputprintf(src, "else {\n"
1879 "Text_Buf text_buf;\n"
1880 "prepare_exception(text_buf, \"%s\");\n"
1881 "raise_exception.encode_text(text_buf);\n"
1882 "send_data(text_buf, destination_component);\n"
1883 "}\n"
1884 "}\n\n", sig->dispname);
1885
1886 if (pdef->testport_type == ADDRESS) {
1887 def = mputprintf(def, "void raise(const %s_exception& "
1888 "raise_exception, const %s& destination_address);\n",
1889 sig->name, pdef->address_name);
1890 src = mputprintf(src, "void %s::raise(const %s_exception& "
1891 "raise_exception, const %s& destination_address)\n"
1892 "{\n"
1893 "if (!is_started) TTCN_error(\"Raising an exception on port "
1894 "%%s, which is not started.\", port_name);\n"
1895 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMOUT))"
1896 " {\n"
1897 "TTCN_Logger::log_procport_send(port_name, "
1898 "TitanLoggerApiSimple::Port__oper::exception__op, SYSTEM_COMPREF,\n"
1899 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1900 " destination_address.log(),"
1901 " TTCN_Logger::end_event_log2str()),\n"
1902 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PMOUT, TRUE),"
1903 " raise_exception.log(),"
1904 " TTCN_Logger::end_event_log2str()));\n"
1905 "}\n"
1906 "outgoing_raise(raise_exception, &destination_address);\n"
1907 "}\n\n",
1908 class_name, sig->name, pdef->address_name);
1909 }
1910
1911 def = mputprintf(def, "void raise(const %s_exception& "
1912 "raise_exception);\n", sig->name);
1913 src = mputprintf(src, "void %s::raise(const %s_exception& "
1914 "raise_exception)\n"
1915 "{\n"
1916 "raise(raise_exception, COMPONENT(get_default_destination()));\n"
1917 "}\n\n", class_name, sig->name);
1918 }
1919
1920 if (pdef->testport_type != INTERNAL && pdef->port_type == REGULAR) {
1921 /* virtual functions for transmission (implemented by the test port) */
1922 def = mputstr(def, "protected:\n");
1923 /* outgoing_send functions */
1924 for (i = 0; i < pdef->msg_out.nElements; i++) {
1925 def = mputprintf(def, "virtual void outgoing_send("
1926 "const %s& send_par", pdef->msg_out.elements[i].name);
1927 if (pdef->testport_type == ADDRESS) {
1928 def = mputprintf(def, ", const %s *destination_address",
1929 pdef->address_name);
1930 }
1931 def = mputstr(def, ") = 0;\n");
1932 }
1933 /* outgoing_call functions */
1934 for (i = 0; i < pdef->proc_out.nElements; i++) {
1935 def = mputprintf(def, "virtual void outgoing_call("
1936 "const %s_call& call_par", pdef->proc_out.elements[i].name);
1937 if (pdef->testport_type == ADDRESS) {
1938 def = mputprintf(def, ", const %s *destination_address",
1939 pdef->address_name);
1940 }
1941 def = mputstr(def, ") = 0;\n");
1942 }
1943 /* outgoing_reply functions */
1944 for (i = 0; i < pdef->proc_in.nElements; i++) {
1945 if (pdef->proc_in.elements[i].is_noblock) continue;
1946 def = mputprintf(def, "virtual void outgoing_reply("
1947 "const %s_reply& reply_par", pdef->proc_in.elements[i].name);
1948 if (pdef->testport_type == ADDRESS) {
1949 def = mputprintf(def, ", const %s *destination_address",
1950 pdef->address_name);
1951 }
1952 def = mputstr(def, ") = 0;\n");
1953 }
1954 /* outgoing_raise functions */
1955 for(i = 0; i < pdef->proc_in.nElements; i++) {
1956 if (!pdef->proc_in.elements[i].has_exceptions) continue;
1957 def = mputprintf(def, "virtual void outgoing_raise("
1958 "const %s_exception& raise_exception",
1959 pdef->proc_in.elements[i].name);
1960 if (pdef->testport_type == ADDRESS) {
1961 def = mputprintf(def, ", const %s *destination_address",
1962 pdef->address_name);
1963 }
1964 def = mputstr(def, ") = 0;\n");
1965 }
1966 def = mputstr(def, "public:\n");
1967 }
1968
1969 /* Generic receive routines (without message type) */
1970 if (has_msg_queue) {
1971 /* generic receive function */
1972 generate_generic_receive(&def, &src, pdef, class_name, FALSE, FALSE,
1973 FALSE);
1974 /* generic check_receive function */
1975 generate_generic_receive(&def, &src, pdef, class_name, TRUE, FALSE,
1976 FALSE);
1977 /* generic trigger function */
1978 generate_generic_receive(&def, &src, pdef, class_name, FALSE, TRUE,
1979 FALSE);
1980 if (pdef->testport_type == ADDRESS) {
1981 /* generic receive with address */
1982 generate_generic_receive(&def, &src, pdef, class_name, FALSE,
1983 FALSE, TRUE);
1984 /* generic check_receive with address */
1985 generate_generic_receive(&def, &src, pdef, class_name, TRUE,
1986 FALSE, TRUE);
1987 /* generic trigger with address */
1988 generate_generic_receive(&def, &src, pdef, class_name, FALSE,
1989 TRUE, TRUE);
1990 }
1991 }
1992
1993 /* Receive routines with message type */
1994 for (i = 0; i < pdef->msg_in.nElements; i++) {
1995 /* receive */
1996 generate_receive(&def, &src, pdef, class_name, i, FALSE, FALSE, FALSE);
1997 /* check_receive */
1998 generate_receive(&def, &src, pdef, class_name, i, TRUE, FALSE, FALSE);
1999 /* trigger */
2000 generate_receive(&def, &src, pdef, class_name, i, FALSE, TRUE, FALSE);
2001 if (pdef->testport_type == ADDRESS) {
2002 /* receive with address */
2003 generate_receive(&def, &src, pdef, class_name, i, FALSE, FALSE,
2004 TRUE);
2005 /* check_receive with address */
2006 generate_receive(&def, &src, pdef, class_name, i, TRUE, FALSE,
2007 TRUE);
2008 /* trigger with address */
2009 generate_receive(&def, &src, pdef, class_name, i, FALSE, TRUE,
2010 TRUE);
2011 }
2012 }
2013
2014 if (has_incoming_call) {
2015 /* generic getcall function */
2016 generate_generic_getop(GETCALL, &def, &src, pdef, class_name, FALSE,
2017 FALSE);
2018 /* generic check_getcall function */
2019 generate_generic_getop(GETCALL, &def, &src, pdef, class_name, TRUE,
2020 FALSE);
2021 if (pdef->testport_type == ADDRESS) {
2022 /* generic getcall with address */
2023 generate_generic_getop(GETCALL, &def, &src, pdef, class_name,
2024 FALSE, TRUE);
2025 /* generic check_getcall with address */
2026 generate_generic_getop(GETCALL, &def, &src, pdef, class_name,
2027 TRUE, TRUE);
2028 }
2029 }
2030
2031 /* getcall functions */
2032 for (i = 0; i < pdef->proc_in.nElements; i++) {
2033 /* getcall */
2034 generate_getcall(&def, &src, pdef, class_name, i, FALSE, FALSE);
2035 /* check_getcall */
2036 generate_getcall(&def, &src, pdef, class_name, i, TRUE, FALSE);
2037 if (pdef->testport_type == ADDRESS) {
2038 /* getcall with address */
2039 generate_getcall(&def, &src, pdef, class_name, i, FALSE, TRUE);
2040 /* check_getcall with address */
2041 generate_getcall(&def, &src, pdef, class_name, i, TRUE, TRUE);
2042 }
2043 }
2044
2045 if (has_incoming_reply) {
2046 /* generic getreply function */
2047 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name, FALSE,
2048 FALSE);
2049 /* generic check_getreply function */
2050 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name, TRUE,
2051 FALSE);
2052 if (pdef->testport_type == ADDRESS) {
2053 /* generic getreply with address */
2054 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name,
2055 FALSE, TRUE);
2056 /* generic check_getreply with address */
2057 generate_generic_getop(GETREPLY, &def, &src, pdef, class_name,
2058 TRUE, TRUE);
2059 }
2060 }
2061
2062 /* getreply functions */
2063 for (i = 0; i < pdef->proc_out.nElements; i++) {
2064 if (pdef->proc_out.elements[i].is_noblock) continue;
2065 /* getreply */
2066 generate_getreply(&def, &src, pdef, class_name, i, FALSE, FALSE);
2067 /* check_getreply */
2068 generate_getreply(&def, &src, pdef, class_name, i, TRUE, FALSE);
2069 if (pdef->testport_type == ADDRESS) {
2070 /* getreply with address */
2071 generate_getreply(&def, &src, pdef, class_name, i, FALSE, TRUE);
2072 /* check_getreply with address */
2073 generate_getreply(&def, &src, pdef, class_name, i, TRUE, TRUE);
2074 }
2075 }
2076
2077 if (has_incoming_exception) {
2078 /* generic catch (get_exception) function */
2079 generate_generic_getop(CATCH, &def, &src, pdef, class_name, FALSE,
2080 FALSE);
2081 /* generic check_catch function */
2082 generate_generic_getop(CATCH, &def, &src, pdef, class_name, TRUE,
2083 FALSE);
2084 if (pdef->testport_type == ADDRESS) {
2085 /* generic catch (get_exception) with address */
2086 generate_generic_getop(CATCH, &def, &src, pdef, class_name, FALSE,
2087 TRUE);
2088 /* generic check_catch with address */
2089 generate_generic_getop(CATCH, &def, &src, pdef, class_name, TRUE,
2090 TRUE);
2091 }
2092 }
2093
2094 /* catch functions */
2095 for (i = 0; i < pdef->proc_out.nElements; i++) {
2096 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2097 /* catch (get_exception) */
2098 generate_catch(&def, &src, pdef, class_name, i, FALSE, FALSE);
2099 /* check_catch */
2100 generate_catch(&def, &src, pdef, class_name, i, TRUE, FALSE);
2101 if (pdef->testport_type == ADDRESS) {
2102 /* catch (get_exception) with address */
2103 generate_catch(&def, &src, pdef, class_name, i, FALSE, TRUE);
2104 /* check_catch with address */
2105 generate_catch(&def, &src, pdef, class_name, i, TRUE, TRUE);
2106 }
2107 }
2108
2109 def = mputstr(def, "private:\n");
2110
2111 if (pdef->port_type == USER) {
2112 /* incoming_message() functions for the incoming types of the provider
2113 * port type */
2114 for (i = 0; i < pdef->provider_msg_in.nElements; i++) {
2115 const port_msg_mapped_type *mapped_type =
2116 pdef->provider_msg_in.elements + i;
2117 boolean is_simple = mapped_type->nTargets == 1 &&
2118 mapped_type->targets[0].mapping_type == M_SIMPLE;
2119 def = mputprintf(def, "void incoming_message(const %s& "
2120 "incoming_par, component sender_component%s",
2121 mapped_type->name,
2122 (pdef->has_sliding ? ", OCTETSTRING& slider" : ""));
2123 if (pdef->testport_type == ADDRESS) {
2124 def = mputprintf(def, ", const %s *sender_address",
2125 pdef->address_name);
2126 }
2127 def = mputstr(def, ");\n");
2128
2129 src = mputprintf(src, "void %s::incoming_message(const %s& "
2130 "incoming_par, component sender_component%s", class_name,
2131 mapped_type->name,
2132 (pdef->has_sliding ? ", OCTETSTRING& slider" : ""));
2133 if (pdef->testport_type == ADDRESS) {
2134 src = mputprintf(src, ", const %s *sender_address",
2135 pdef->address_name);
2136 }
2137 src = mputstr(src, ")\n"
2138 "{\n"
2139 "if (!is_started) TTCN_error(\"Port %s is not started but a "
2140 "message has arrived on it.\", port_name);\n");
2141 if (pdef->has_sliding) src = mputstr(src, "(void)slider;\n");
2142 if (is_simple) src = mputstr(src, "msg_tail_count++;\n");
2143 src = mputprintf(src, "if (TTCN_Logger::log_this_event("
2144 "TTCN_Logger::PORTEVENT_MQUEUE)) {\n"
2145 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg,"
2146 " port_name, sender_component, msg_tail_count%s,\n",
2147 /* if is_simple==FALSE then this log message is a LIE! */
2148 is_simple?"":"+1"
2149 );
2150 if (pdef->testport_type == ADDRESS) {
2151 src = mputstr(src,
2152 "sender_address ?"
2153 /* Use the comma operator to get an expression of type CHARSTRING */
2154 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2155 " TTCN_Logger::log_char('('), sender_address->log(),"
2156 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2157 );
2158 }
2159 src = mputprintf(src,
2160 /* This empty string may be an operand to a conditional operator from above */
2161 "CHARSTRING(0, NULL),\n"
2162 /* Protect the comma operators from being interpreted as
2163 * function argument separators. */
2164 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2165 " TTCN_Logger::log_event_str(\" %s : \"),"
2166 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2167 "}\n", mapped_type->dispname);
2168 if (is_simple) {
2169 src = mputprintf(src,
2170#ifndef NDEBUG
2171 "// simple mapping\n"
2172#endif
2173 "msg_queue_item *new_item = new msg_queue_item;\n"
2174 "new_item->item_selection = MESSAGE_%lu;\n"
2175 "new_item->message_%lu = new %s(incoming_par);\n"
2176 "new_item->sender_component = sender_component;\n",
2177 (unsigned long) mapped_type->targets[0].target_index,
2178 (unsigned long) mapped_type->targets[0].target_index,
2179 mapped_type->name);
2180 if (pdef->testport_type == ADDRESS) {
2181 src = mputprintf(src, "if (sender_address != NULL) "
2182 "new_item->sender_address = new %s(*sender_address);\n"
2183 "else new_item->sender_address = NULL;\n",
2184 pdef->address_name);
2185 }
2186 src = mputstr(src, "append_to_msg_queue(new_item);\n");
2187 } else src = generate_incoming_mapping(src, pdef, mapped_type);
2188 src = mputstr(src, "}\n\n");
2189 }
2190 } else { /* not user */
2191 /* incoming_message functions */
2192 for (i = 0; i < pdef->msg_in.nElements; i++) {
2193 def = mputprintf(def, "void incoming_message(const %s& "
2194 "incoming_par, component sender_component",
2195 pdef->msg_in.elements[i].name);
2196 if (pdef->testport_type == ADDRESS) {
2197 def = mputprintf(def, ", const %s *sender_address",
2198 pdef->address_name);
2199 }
2200 def = mputstr(def, ");\n");
2201
2202 src = mputprintf(src, "void %s::incoming_message(const %s& "
2203 "incoming_par, component sender_component", class_name,
2204 pdef->msg_in.elements[i].name);
2205 if (pdef->testport_type == ADDRESS) {
2206 src = mputprintf(src, ", const %s *sender_address",
2207 pdef->address_name);
2208 }
2209 src = mputstr(src, ")\n"
2210 "{\n"
2211 "if (!is_started) TTCN_error(\"Port %s is not started but a "
2212 "message has arrived on it.\", port_name);\n"
2213 "msg_tail_count++;\n"
2214 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MQUEUE)) "
2215 "{\n"
2216 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg,"
2217 " port_name, sender_component, msg_tail_count,\n"
2218 );
2219 if (pdef->testport_type == ADDRESS) {
2220 src = mputstr(src,
2221 "sender_address ?"
2222 /* Use the comma operator to get an expression of type CHARSTRING */
2223 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2224 " TTCN_Logger::log_char('('), sender_address->log(),"
2225 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2226 );
2227 }
2228 src = mputprintf(src,
2229 /* This empty string may be an operand to a conditional operator from above */
2230 "CHARSTRING(0, NULL),\n"
2231 /* Protect the comma operators from being interpreted as
2232 * function argument separators. */
2233 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_MQUEUE, TRUE),"
2234 " TTCN_Logger::log_event_str(\" %s : \"),"
2235 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2236 "}\n"
2237 "msg_queue_item *new_item = new msg_queue_item;\n"
2238 "new_item->item_selection = MESSAGE_%lu;\n"
2239 "new_item->message_%lu = new %s(incoming_par);\n"
2240 "new_item->sender_component = sender_component;\n",
2241 pdef->msg_in.elements[i].dispname,
2242 (unsigned long) i, (unsigned long) i,
2243 pdef->msg_in.elements[i].name);
2244 if (pdef->testport_type == ADDRESS) {
2245 src = mputprintf(src, "if (sender_address != NULL) "
2246 "new_item->sender_address = new %s(*sender_address);\n"
2247 "else new_item->sender_address = NULL;\n",
2248 pdef->address_name);
2249 }
2250 src = mputstr(src, "append_to_msg_queue(new_item);\n"
2251 "}\n\n");
2252 }
2253 }
2254
2255 /* incoming_call functions */
2256 for (i = 0; i < pdef->proc_in.nElements; i++) {
2257 const port_proc_signature *sig = pdef->proc_in.elements + i;
2258 def = mputprintf(def, "void incoming_call(const %s_call& incoming_par, "
2259 "component sender_component", sig->name);
2260 if (pdef->testport_type == ADDRESS) {
2261 def = mputprintf(def, ", const %s *sender_address",
2262 pdef->address_name);
2263 }
2264 def = mputstr(def, ");\n");
2265 src = mputprintf(src, "void %s::incoming_call(const %s_call& "
2266 "incoming_par, component sender_component", class_name, sig->name);
2267 if (pdef->testport_type == ADDRESS) {
2268 src = mputprintf(src, ", const %s *sender_address",
2269 pdef->address_name);
2270 }
2271 src = mputstr(src, ")\n"
2272 "{\n"
2273 "if (!is_started) TTCN_error(\"Port %s is not started but a call "
2274 "has arrived on it.\", port_name);\n"
2275 "proc_tail_count++;\n"
2276 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PQUEUE)) "
2277 "{\n"
2278 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__call,"
2279 " port_name, sender_component, proc_tail_count,\n"
2280 );
2281 if (pdef->testport_type == ADDRESS) {
2282 src = mputstr(src,
2283 "sender_address ?"
2284 /* Use the comma operator to get an expression of type CHARSTRING */
2285 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2286 " TTCN_Logger::log_char('('), sender_address->log(),"
2287 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2288 );
2289 }
2290 src = mputprintf(src,
2291 /* This empty string may be an operand to a conditional operator from above */
2292 "CHARSTRING(0, NULL),\n"
2293 /* Protect the comma operators from being interpreted as
2294 * function argument separators. */
2295 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2296 " TTCN_Logger::log_char(' '),"
2297 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2298 "}\n"
2299 "proc_queue_item *new_item = new proc_queue_item;\n"
2300 "new_item->item_selection = CALL_%lu;\n"
2301 "new_item->call_%lu = new %s_call(incoming_par);\n"
2302 "new_item->sender_component = sender_component;\n",
2303 (unsigned long) i, (unsigned long) i, sig->name);
2304 if (pdef->testport_type == ADDRESS) {
2305 src = mputprintf(src, "if (sender_address != NULL) "
2306 "new_item->sender_address = new %s(*sender_address);\n"
2307 "else new_item->sender_address = NULL;\n", pdef->address_name);
2308 }
2309 src = mputstr(src, "append_to_proc_queue(new_item);\n"
2310 "}\n\n");
2311 }
2312
2313 /* incoming_reply functions */
2314 for (i = 0; i < pdef->proc_out.nElements; i++) {
2315 const port_proc_signature *sig = pdef->proc_out.elements + i;
2316 if (sig->is_noblock) continue;
2317 def = mputprintf(def, "void incoming_reply(const %s_reply& "
2318 "incoming_par, component sender_component", sig->name);
2319 if (pdef->testport_type == ADDRESS) {
2320 def = mputprintf(def, ", const %s *sender_address",
2321 pdef->address_name);
2322 }
2323 def = mputstr(def, ");\n");
2324 src = mputprintf(src, "void %s::incoming_reply(const %s_reply& "
2325 "incoming_par, component sender_component", class_name,
2326 sig->name);
2327 if (pdef->testport_type == ADDRESS) {
2328 src = mputprintf(src, ", const %s *sender_address",
2329 pdef->address_name);
2330 }
2331 src = mputstr(src, ")\n"
2332 "{\n"
2333 "if (!is_started) TTCN_error(\"Port %s is not started but a reply "
2334 "has arrived on it.\", port_name);\n"
2335 "proc_tail_count++;\n"
2336 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PQUEUE)) "
2337 "{\n"
2338 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__reply,"
2339 " port_name, sender_component, proc_tail_count,\n");
2340 if (pdef->testport_type == ADDRESS) {
2341 src = mputstr(src,
2342 "sender_address ?"
2343 /* Use the comma operator to get an expression of type CHARSTRING */
2344 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2345 " TTCN_Logger::log_char('('), sender_address->log(),"
2346 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : ");
2347 }
2348 src = mputprintf(src,
2349 /* This empty string may be an operand to a conditional operator from above */
2350 "CHARSTRING(0, NULL),\n"
2351 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2352 " TTCN_Logger::log_char(' '),"
2353 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2354 "}\n"
2355 "proc_queue_item *new_item = new proc_queue_item;\n"
2356 "new_item->item_selection = REPLY_%lu;\n"
2357 "new_item->reply_%lu = new %s_reply(incoming_par);\n"
2358 "new_item->sender_component = sender_component;\n",
2359 (unsigned long) i, (unsigned long) i, sig->name);
2360 if (pdef->testport_type == ADDRESS) {
2361 src = mputprintf(src, "if (sender_address != NULL) "
2362 "new_item->sender_address = new %s(*sender_address);\n"
2363 "else new_item->sender_address = NULL;\n",
2364 pdef->address_name);
2365 }
2366 src = mputstr(src, "append_to_proc_queue(new_item);\n"
2367 "}\n\n");
2368 }
2369
2370 /* incoming_exception functions */
2371 for (i = 0; i < pdef->proc_out.nElements; i++) {
2372 const port_proc_signature *sig = pdef->proc_out.elements + i;
2373 if (!sig->has_exceptions) continue;
2374 def = mputprintf(def, "void incoming_exception(const %s_exception& "
2375 "incoming_par, component sender_component", sig->name);
2376 if (pdef->testport_type == ADDRESS) {
2377 def = mputprintf(def, ", const %s *sender_address",
2378 pdef->address_name);
2379 }
2380 def = mputstr(def, ");\n");
2381 src = mputprintf(src,
2382 "void %s::incoming_exception(const %s_exception& incoming_par, "
2383 "component sender_component", class_name, sig->name);
2384 if (pdef->testport_type == ADDRESS) {
2385 src = mputprintf(src, ", const %s *sender_address",
2386 pdef->address_name);
2387 }
2388 src = mputstr(src, ")\n"
2389 "{\n"
2390 "if (!is_started) TTCN_error(\"Port %s is not started but an "
2391 "exception has arrived on it.\", port_name);\n"
2392 "proc_tail_count++;\n"
2393 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PQUEUE)) "
2394 "{\n"
2395 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__exception,"
2396 " port_name, sender_component, proc_tail_count,\n"
2397 );
2398 if (pdef->testport_type == ADDRESS) {
2399 src = mputstr(src,
2400 "sender_address ?"
2401 /* Use the comma operator to get an expression of type CHARSTRING */
2402 " (TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2403 " TTCN_Logger::log_char('('), sender_address->log(),"
2404 " TTCN_Logger::log_char(')'), TTCN_Logger::end_event_log2str()) : "
2405 );
2406 }
2407 src = mputprintf(src,
2408 /* This empty string may be an operand to a conditional operator from above */
2409 "CHARSTRING(0, NULL),\n"
2410 "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_PQUEUE, TRUE),"
2411 " TTCN_Logger::log_char(' '),"
2412 " incoming_par.log(), TTCN_Logger::end_event_log2str()));\n"
2413 "}\n"
2414 "proc_queue_item *new_item = new proc_queue_item;\n"
2415 "new_item->item_selection = EXCEPTION_%lu;\n"
2416 "new_item->exception_%lu = new %s_exception(incoming_par);\n"
2417 "new_item->sender_component = sender_component;\n",
2418 (unsigned long) i, (unsigned long) i, sig->name);
2419 if (pdef->testport_type == ADDRESS) {
2420 src = mputprintf(src, "if (sender_address != NULL) "
2421 "new_item->sender_address = new %s(*sender_address);\n"
2422 "else new_item->sender_address = NULL;\n", pdef->address_name);
2423 }
2424 src = mputstr(src, "append_to_proc_queue(new_item);\n"
2425 "}\n\n");
2426 }
2427
2428 def = mputstr(def, "protected:\n");
2429
2430 if (pdef->testport_type != INTERNAL) {
2431 /** functions provided for the test port to pass incoming messages or
2432 * procedure operations into the queue */
2433 if (pdef->port_type == REGULAR) {
2434 /* inline functions that are used through simple inheritance */
2435 for (i = 0; i < pdef->msg_in.nElements; i++) {
2436 /* wrapper for incoming_message */
2437 def = mputprintf(def, "inline void incoming_message("
2438 "const %s& incoming_par", pdef->msg_in.elements[i].name);
2439 if (pdef->testport_type == ADDRESS) {
2440 def = mputprintf(def, ", const %s *sender_address = NULL",
2441 pdef->address_name);
2442 }
2443 def = mputprintf(def, ") { incoming_message(incoming_par, "
2444 "SYSTEM_COMPREF%s); }\n",
2445 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2446 }
2447 for (i = 0; i < pdef->proc_in.nElements; i++) {
2448 /* wrapper for incoming_call */
2449 def = mputprintf(def, "inline void incoming_call("
2450 "const %s_call& incoming_par",
2451 pdef->proc_in.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_call(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_reply */
2462 if (pdef->proc_out.elements[i].is_noblock) continue;
2463 def = mputprintf(def, "inline void incoming_reply("
2464 "const %s_reply& 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_reply(incoming_par, "
2471 "SYSTEM_COMPREF%s); }\n",
2472 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2473 }
2474 for (i = 0; i < pdef->proc_out.nElements; i++) {
2475 /* wrapper for incoming_exception */
2476 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2477 def = mputprintf(def, "inline void incoming_exception("
2478 "const %s_exception& incoming_par",
2479 pdef->proc_out.elements[i].name);
2480 if (pdef->testport_type == ADDRESS) {
2481 def = mputprintf(def, ", const %s *sender_address = NULL",
2482 pdef->address_name);
2483 }
2484 def = mputprintf(def, ") { incoming_exception(incoming_par, "
2485 "SYSTEM_COMPREF%s); }\n",
2486 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2487 }
2488 } else {
2489 /** implementation of pure virtual functions that are defined in
2490 * the test port class */
2491 /* in case of PROVIDER port types the functions must handle the own
2492 * incoming messages, but in case of USER port types the incoming
2493 * messages of the provider port type must be handled */
2494 size_t nof_messages = pdef->port_type == USER ?
2495 pdef->provider_msg_in.nElements : pdef->msg_in.nElements;
2496 for (i = 0; i < nof_messages; i++) {
2497 /* incoming_message */
2498 const char *message_type = pdef->port_type == USER ?
2499 pdef->provider_msg_in.elements[i].name :
2500 pdef->msg_in.elements[i].name;
2501 def = mputprintf(def, "void incoming_message(const %s& "
2502 "incoming_par", message_type);
2503 if (pdef->testport_type == ADDRESS) {
2504 def = mputprintf(def, ", const %s *sender_address",
2505 pdef->address_name);
2506 }
2507 def = mputstr(def, ");\n");
2508 src = mputprintf(src, "void %s::incoming_message("
2509 "const %s& incoming_par", class_name, message_type);
2510 if (pdef->testport_type == ADDRESS) {
2511 src = mputprintf(src, ", const %s *sender_address",
2512 pdef->address_name);
2513 }
2514 src = mputprintf(src, ")\n"
2515 "{\n"
2516 "incoming_message(incoming_par, SYSTEM_COMPREF%s%s);\n"
2517 "}\n\n",
2518 (pdef->has_sliding ? ", sliding_buffer": ""),
2519 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2520 }
2521 for (i = 0; i < pdef->proc_in.nElements; i++) {
2522 /* incoming_call */
2523 def = mputprintf(def, "void incoming_call(const %s_call& "
2524 "incoming_par", pdef->proc_in.elements[i].name);
2525 if (pdef->testport_type == ADDRESS) {
2526 def = mputprintf(def, ", const %s *sender_address",
2527 pdef->address_name);
2528 }
2529 def = mputstr(def, ");\n");
2530 src = mputprintf(src, "void %s::incoming_call(const %s_call& "
2531 "incoming_par", class_name, pdef->proc_in.elements[i].name);
2532 if (pdef->testport_type == ADDRESS) {
2533 src = mputprintf(src, ", const %s *sender_address",
2534 pdef->address_name);
2535 }
2536 src = mputprintf(src, ")\n"
2537 "{\n"
2538 "incoming_call(incoming_par, SYSTEM_COMPREF%s);\n"
2539 "}\n\n",
2540 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2541 }
2542 for (i = 0; i < pdef->proc_out.nElements; i++) {
2543 /* incoming_reply */
2544 if (pdef->proc_out.elements[i].is_noblock) continue;
2545 def = mputprintf(def, "void incoming_reply(const %s_reply& "
2546 "incoming_par", pdef->proc_out.elements[i].name);
2547 if (pdef->testport_type == ADDRESS) {
2548 def = mputprintf(def, ", const %s *sender_address",
2549 pdef->address_name);
2550 }
2551 def = mputstr(def, ");\n");
2552 src = mputprintf(src, "void %s::incoming_reply(const %s_reply& "
2553 "incoming_par", class_name,
2554 pdef->proc_out.elements[i].name);
2555 if (pdef->testport_type == ADDRESS) {
2556 src = mputprintf(src, ", const %s *sender_address",
2557 pdef->address_name);
2558 }
2559 src = mputprintf(src, ")\n"
2560 "{\n"
2561 "incoming_reply(incoming_par, SYSTEM_COMPREF%s);\n"
2562 "}\n\n",
2563 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2564 }
2565 for (i = 0; i < pdef->proc_out.nElements; i++) {
2566 /* incoming_exception */
2567 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2568 def = mputprintf(def, "void incoming_exception("
2569 "const %s_exception& incoming_par",
2570 pdef->proc_out.elements[i].name);
2571 if (pdef->testport_type == ADDRESS) {
2572 def = mputprintf(def, ", const %s *sender_address",
2573 pdef->address_name);
2574 }
2575 def = mputstr(def, ");\n");
2576 src = mputprintf(src, "void %s::incoming_exception("
2577 "const %s_exception& incoming_par", class_name,
2578 pdef->proc_out.elements[i].name);
2579 if (pdef->testport_type == ADDRESS) {
2580 src = mputprintf(src, ", const %s *sender_address",
2581 pdef->address_name);
2582 }
2583 src = mputprintf(src, ")\n"
2584 "{\n"
2585 "incoming_exception(incoming_par, SYSTEM_COMPREF%s);\n"
2586 "}\n\n",
2587 pdef->testport_type == ADDRESS ? ", sender_address" : "");
2588 }
2589 }
2590 }
2591
2592 if (has_msg_queue) {
2593 size_t nof_messages = pdef->port_type == USER ?
2594 pdef->provider_msg_in.nElements : pdef->msg_in.nElements;
2595 def = mputstr(def, "boolean process_message(const char *message_type, "
2596 "Text_Buf& incoming_buf, component sender_component, OCTETSTRING& slider);\n");
2597 src = mputprintf(src, "boolean %s::process_message("
2598 "const char *message_type, Text_Buf& incoming_buf, "
2599 "component sender_component, OCTETSTRING&%s)\n"
2600 "{\n", class_name,
2601 pdef->has_sliding ? " slider" : "");
2602 for (i = 0; i < nof_messages; i++) {
2603 const char *msg_name, *msg_dispname;
2604 if (pdef->port_type == USER) {
2605 msg_name = pdef->provider_msg_in.elements[i].name;
2606 msg_dispname = pdef->provider_msg_in.elements[i].dispname;
2607 } else {
2608 msg_name = pdef->msg_in.elements[i].name;
2609 msg_dispname = pdef->msg_in.elements[i].dispname;
2610 }
2611 src = mputprintf(src, "if (!strcmp(message_type, \"%s\")) {\n"
2612 "%s incoming_par;\n"
2613 "incoming_par.decode_text(incoming_buf);\n"
2614 "incoming_message(incoming_par, sender_component%s%s);\n"
2615 "return TRUE;\n"
2616 "} else ", msg_dispname, msg_name,
2617 (pdef->has_sliding ? ", slider" : ""),
2618 pdef->testport_type == ADDRESS ? ", NULL" : "");
2619 }
2620 src = mputstr(src, "return FALSE;\n"
2621 "}\n\n");
2622 }
2623
2624 if (has_incoming_call) {
2625 def = mputstr(def, "boolean process_call(const char *signature_name, "
2626 "Text_Buf& incoming_buf, component sender_component);\n");
2627 src = mputprintf(src, "boolean %s::process_call("
2628 "const char *signature_name, Text_Buf& incoming_buf, "
2629 "component sender_component)\n"
2630 "{\n", class_name);
2631 for (i = 0; i < pdef->proc_in.nElements; i++) {
2632 src = mputprintf(src, "if (!strcmp(signature_name, \"%s\")) {\n"
2633 "%s_call incoming_par;\n"
2634 "incoming_par.decode_text(incoming_buf);\n"
2635 "incoming_call(incoming_par, sender_component%s);\n"
2636 "return TRUE;\n"
2637 "} else ", pdef->proc_in.elements[i].dispname,
2638 pdef->proc_in.elements[i].name,
2639 pdef->testport_type == ADDRESS ? ", NULL" : "");
2640 }
2641 src = mputstr(src, "return FALSE;\n"
2642 "}\n\n");
2643 }
2644
2645 if (has_incoming_reply) {
2646 def = mputstr(def, "boolean process_reply(const char *signature_name, "
2647 "Text_Buf& incoming_buf, component sender_component);\n");
2648 src = mputprintf(src, "boolean %s::process_reply("
2649 "const char *signature_name, Text_Buf& incoming_buf, "
2650 "component sender_component)\n"
2651 "{\n", class_name);
2652 for (i = 0; i < pdef->proc_out.nElements; i++) {
2653 if (pdef->proc_out.elements[i].is_noblock) continue;
2654 src = mputprintf(src, "if (!strcmp(signature_name, \"%s\")) {\n"
2655 "%s_reply incoming_par;\n"
2656 "incoming_par.decode_text(incoming_buf);\n"
2657 "incoming_reply(incoming_par, sender_component%s);\n"
2658 "return TRUE;\n"
2659 "} else ", pdef->proc_out.elements[i].dispname,
2660 pdef->proc_out.elements[i].name,
2661 pdef->testport_type == ADDRESS ? ", NULL" : "");
2662 }
2663 src = mputstr(src, "return FALSE;\n"
2664 "}\n\n");
2665 }
2666
2667 if (has_incoming_exception) {
2668 def = mputstr(def, "boolean process_exception("
2669 "const char *signature_name, Text_Buf& incoming_buf, "
2670 "component sender_component);\n");
2671 src = mputprintf(src, "boolean %s::process_exception("
2672 "const char *signature_name, Text_Buf& incoming_buf, "
2673 "component sender_component)\n"
2674 "{\n", class_name);
2675 for (i = 0; i < pdef->proc_out.nElements; i++) {
2676 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2677 src = mputprintf(src, "if (!strcmp(signature_name, \"%s\")) {\n"
2678 "%s_exception incoming_par;\n"
2679 "incoming_par.decode_text(incoming_buf);\n"
2680 "incoming_exception(incoming_par, sender_component%s);\n"
2681 "return TRUE;\n"
2682 "} else ", pdef->proc_out.elements[i].dispname,
2683 pdef->proc_out.elements[i].name,
2684 pdef->testport_type == ADDRESS ? ", NULL" : "");
2685 }
2686 src = mputstr(src, "return FALSE;\n"
2687 "}\n\n");
2688 }
2689
2690 /* Event handler prototype and empty implementation is not generated.
2691 When a port does not wait any events it is correct.
2692 (Call to the event handler will cause a dynamic test case error.) */
2693
2694 def = mputstr(def, "};\n\n");
2695 /* end of base class */
2696
2697 /* Putting everything to the output */
2698
2699 output->header.class_decls = mputprintf(output->header.class_decls,
2700 "class %s;\n", class_name);
2701 if (pdef->testport_type != INTERNAL && pdef->port_type == REGULAR)
2702 output->header.class_decls = mputprintf(output->header.class_decls,
2703 "class %s;\n", pdef->name);
2704
2705 output->header.class_defs = mputstr(output->header.class_defs, def);
2706 Free(def);
2707
2708 if (pdef->testport_type != INTERNAL) {
2709 switch (pdef->port_type) {
2710 case REGULAR:
2711 output->header.testport_includes = mputprintf(
2712 output->header.testport_includes, "#include \"%s.hh\"\n",
2713 duplicate_underscores ? pdef->name : pdef->filename);
2714 break;
2715 case PROVIDER:
2716 output->header.includes = mputprintf(output->header.includes,
2717 "#include \"%s.hh\"\n",
2718 duplicate_underscores ? pdef->name : pdef->filename);
2719 default:
2720 break;
2721 }
2722 }
2723
2724 output->source.methods = mputstr(output->source.methods, src);
2725 Free(src);
2726
2727 Free(class_name);
2728 Free(base_class_name);
2729}
2730
2731void generateTestPortSkeleton(const port_def *pdef)
2732{
2733 char *class_name, *base_class_name;
2734 const char *file_prefix =
2735 duplicate_underscores ? pdef->name : pdef->filename;
2736 size_t i;
2737 char *header_name, *source_name;
2738 char *user_info = NULL;
2739
2740 DEBUG(1, "Generating test port skeleton for port type `%s' ...",
2741 pdef->dispname);
2742
2743 if (pdef->port_type == PROVIDER) {
2744 class_name = mprintf("%s_PROVIDER", pdef->name);
2745 base_class_name = mcopystr("PORT");
2746 } else {
2747 class_name = mcopystr(pdef->name);
2748 base_class_name = mprintf("%s_BASE", pdef->name);
2749 }
2750
2751 if (output_dir != NULL) {
2752 header_name = mprintf("%s/%s.hh", output_dir, file_prefix);
2753 source_name = mprintf("%s/%s.cc", output_dir, file_prefix);
2754 } else {
2755 header_name = mprintf("%s.hh", file_prefix);
2756 source_name = mprintf("%s.cc", file_prefix);
2757 }
2758
2759 if (force_overwrite || get_path_status(header_name) == PS_NONEXISTENT) {
2760 FILE *fp = fopen(header_name, "w");
2761 if (fp == NULL) {
2762 ERROR("Cannot open output test port skeleton header file `%s' for "
2763 "writing: %s", header_name, strerror(errno));
2764 exit(EXIT_FAILURE);
2765 }
2766 if (user_info == NULL) user_info = get_user_info();
2767 fprintf(fp,
2768 "// This Test Port skeleton header file was generated by the\n"
2769 "// TTCN-3 Compiler of the TTCN-3 Test Executor version "
2770 PRODUCT_NUMBER "\n"
2771 "// for %s\n"
2772 COPYRIGHT_STRING "\n\n"
2773 "// You may modify this file. Add your attributes and "
2774 "prototypes of your\n"
2775 "// member functions here.\n\n"
2776 "#ifndef %s_HH\n"
2777 "#define %s_HH\n\n", user_info, pdef->name, pdef->name);
2778 if (pdef->port_type == PROVIDER) {
2779 fprintf(fp, "#include <TTCN3.hh>\n\n"
2780 "// Note: Header file %s.hh must not be included into this "
2781 "file!\n"
2782 "// (because it includes this file)\n"
2783 "// Please add the declarations of message types manually.\n\n",
2784 duplicate_underscores ? pdef->module_name :
2785 pdef->module_dispname);
2786 } else {
2787 fprintf(fp, "#include \"%s.hh\"\n\n",
2788 duplicate_underscores ? pdef->module_name :
2789 pdef->module_dispname);
2790 }
2791 fprintf(fp, "namespace %s {\n\n", pdef->module_name);
2792 fprintf(fp,
2793 "class %s : public %s {\n"
2794 "public:\n"
2795 "\t%s(const char *par_port_name%s);\n"
2796 "\t~%s();\n\n"
2797 "\tvoid set_parameter(const char *parameter_name,\n"
2798 "\t\tconst char *parameter_value);\n\n"
2799 "private:\n"
2800 "\t/* void Handle_Fd_Event(int fd, boolean is_readable,\n"
2801 "\t\tboolean is_writable, boolean is_error); */\n"
2802 "\tvoid Handle_Fd_Event_Error(int fd);\n"
2803 "\tvoid Handle_Fd_Event_Writable(int fd);\n"
2804 "\tvoid Handle_Fd_Event_Readable(int fd);\n"
2805 "\t/* void Handle_Timeout(double time_since_last_call); */\n"
2806 "protected:\n"
2807 "\tvoid user_map(const char *system_port);\n"
2808 "\tvoid user_unmap(const char *system_port);\n\n"
2809 "\tvoid user_start();\n"
2810 "\tvoid user_stop();\n\n",
2811 class_name, base_class_name, class_name,
2812 pdef->port_type == REGULAR ? " = NULL" : "", class_name);
2813
2814 for (i = 0; i < pdef->msg_out.nElements; i++) {
2815 fprintf(fp, "\tvoid outgoing_send(const %s& send_par",
2816 pdef->msg_out.elements[i].name);
2817 if (pdef->testport_type == ADDRESS) {
2818 fprintf(fp, ",\n"
2819 "\t\tconst %s *destination_address", pdef->address_name);
2820 }
2821 fputs(");\n", fp);
2822 }
2823 for (i = 0; i < pdef->proc_out.nElements; i++) {
2824 fprintf(fp, "\tvoid outgoing_call(const %s_call& call_par",
2825 pdef->proc_out.elements[i].name);
2826 if (pdef->testport_type == ADDRESS) {
2827 fprintf(fp, ",\n"
2828 "\t\tconst %s *destination_address", pdef->address_name);
2829 }
2830 fputs(");\n" , fp);
2831 }
2832 for (i = 0; i < pdef->proc_in.nElements; i++) {
2833 if (pdef->proc_in.elements[i].is_noblock) continue;
2834 fprintf(fp, "\tvoid outgoing_reply(const %s_reply& reply_par",
2835 pdef->proc_in.elements[i].name);
2836 if (pdef->testport_type == ADDRESS) {
2837 fprintf(fp, ",\n"
2838 "\t\tconst %s *destination_address", pdef->address_name);
2839 }
2840 fputs(");\n", fp);
2841 }
2842 for (i = 0; i < pdef->proc_in.nElements; i++) {
2843 if (!pdef->proc_in.elements[i].has_exceptions) continue;
2844 fprintf(fp, "\tvoid outgoing_raise(const %s_exception& "
2845 "raise_exception", pdef->proc_in.elements[i].name);
2846 if (pdef->testport_type == ADDRESS) {
2847 fprintf(fp, ",\n"
2848 "\t\tconst %s *destination_address", pdef->address_name);
2849 }
2850 fputs(");\n", fp);
2851 }
2852 if (pdef->port_type == PROVIDER) {
2853 /* pure virtual functions for incoming operations */
2854 for (i = 0; i < pdef->msg_in.nElements; i++) {
2855 fprintf(fp, "\tvirtual void incoming_message(const %s& "
2856 "incoming_par", pdef->msg_in.elements[i].name);
2857 if (pdef->testport_type == ADDRESS) {
2858 fprintf(fp, ",\n"
2859 "\t\tconst %s *sender_address = NULL",
2860 pdef->address_name);
2861 }
2862 fputs(") = 0;\n", fp);
2863 }
2864 for (i = 0; i < pdef->proc_in.nElements; i++) {
2865 fprintf(fp, "\tvirtual void incoming_call(const %s_call& "
2866 "incoming_par", pdef->proc_in.elements[i].name);
2867 if (pdef->testport_type == ADDRESS) {
2868 fprintf(fp, ",\n"
2869 "\t\tconst %s *sender_address = NULL",
2870 pdef->address_name);
2871 }
2872 fputs(") = 0;\n", fp);
2873 }
2874 for (i = 0; i < pdef->proc_out.nElements; i++) {
2875 if (pdef->proc_out.elements[i].is_noblock) continue;
2876 fprintf(fp, "\tvirtual void incoming_reply(const %s_reply& "
2877 "incoming_par", pdef->proc_out.elements[i].name);
2878 if (pdef->testport_type == ADDRESS) {
2879 fprintf(fp, ",\n"
2880 "\t\tconst %s *sender_address = NULL",
2881 pdef->address_name);
2882 }
2883 fputs(") = 0;\n", fp);
2884 }
2885 for (i = 0; i < pdef->proc_out.nElements; i++) {
2886 if (!pdef->proc_out.elements[i].has_exceptions) continue;
2887 fprintf(fp, "\tvirtual void incoming_exception("
2888 "const %s_exception& incoming_par",
2889 pdef->proc_out.elements[i].name);
2890 if (pdef->testport_type == ADDRESS) {
2891 fprintf(fp, ",\n"
2892 "\t\tconst %s *sender_address = NULL",
2893 pdef->address_name);
2894 }
2895 fputs(") = 0;\n", fp);
2896 }
2897 }
2898 fputs("};\n\n", fp);
2899 fputs("} /* end of namespace */\n\n", fp);
2900 fputs("#endif\n", fp);
2901 fclose(fp);
2902 NOTIFY("Test port skeleton header file `%s' was generated for port "
2903 "type `%s'.", header_name, pdef->dispname);
2904 } else {
2905 DEBUG(1, "Test port header file `%s' already exists. It was not "
2906 "overwritten.", header_name);
2907 }
2908
2909 if (force_overwrite || get_path_status(source_name) == PS_NONEXISTENT) {
2910 FILE *fp = fopen(source_name, "w");
2911 if (fp == NULL) {
2912 ERROR("Cannot open output test port skeleton source file `%s' for "
2913 "writing: %s", source_name, strerror(errno));
2914 exit(EXIT_FAILURE);
2915 }
2916 if (user_info == NULL) user_info = get_user_info();
2917 fprintf(fp,
2918 "// This Test Port skeleton source file was generated by the\n"
2919 "// TTCN-3 Compiler of the TTCN-3 Test Executor version "
2920 PRODUCT_NUMBER "\n"
2921 "// for %s\n"
2922 COPYRIGHT_STRING "\n\n"
2923 "// You may modify this file. Complete the body of empty functions and\n"
2924 "// add your member functions here.\n\n"
2925 "#include \"%s.hh\"\n", user_info, file_prefix);
2926 if (pdef->port_type == PROVIDER) {
2927 fprintf(fp, "#include \"%s.hh\"\n",
2928 duplicate_underscores ? pdef->module_name :
2929 pdef->module_dispname);
2930 }
2931 putc('\n', fp);
2932 fprintf(fp, "namespace %s {\n\n", pdef->module_name);
2933 fprintf(fp, "%s::%s(const char *par_port_name)\n"
2934 "\t: %s(par_port_name)\n"
2935 "{\n\n"
2936 "}\n\n"
2937 "%s::~%s()\n"
2938 "{\n\n"
2939 "}\n\n"
2940 "void %s::set_parameter(const char * /*parameter_name*/,\n"
2941 "\tconst char * /*parameter_value*/)\n"
2942 "{\n\n"
2943 "}\n\n"
2944 "/*void %s::Handle_Fd_Event(int fd, boolean is_readable,\n"
2945 "\tboolean is_writable, boolean is_error) {}*/\n\n"
2946 "void %s::Handle_Fd_Event_Error(int /*fd*/)\n"
2947 "{\n\n"
2948 "}\n\n"
2949 "void %s::Handle_Fd_Event_Writable(int /*fd*/)\n"
2950 "{\n\n"
2951 "}\n\n"
2952 "void %s::Handle_Fd_Event_Readable(int /*fd*/)\n"
2953 "{\n\n"
2954 "}\n\n"
2955 "/*void %s::Handle_Timeout(double time_since_last_call) {}*/\n\n"
2956 "void %s::user_map(const char * /*system_port*/)\n"
2957 "{\n\n"
2958 "}\n\n"
2959 "void %s::user_unmap(const char * /*system_port*/)\n"
2960 "{\n\n"
2961 "}\n\n"
2962 "void %s::user_start()\n"
2963 "{\n\n"
2964 "}\n\n"
2965 "void %s::user_stop()\n"
2966 "{\n\n"
2967 "}\n\n", class_name, class_name, base_class_name, class_name,
2968 class_name, class_name, class_name, class_name, class_name,
2969 class_name, class_name, class_name, class_name, class_name,
2970 class_name);
2971
2972 for (i = 0; i < pdef->msg_out.nElements; i++) {
2973 fprintf(fp, "void %s::outgoing_send(const %s& /*send_par*/",
2974 class_name, pdef->msg_out.elements[i].name);
2975 if (pdef->testport_type == ADDRESS) {
2976 fprintf(fp, ",\n"
2977 "\tconst %s * /*destination_address*/", pdef->address_name);
2978 }
2979 fputs(")\n"
2980 "{\n\n"
2981 "}\n\n", fp);
2982 }
2983 for (i = 0; i < pdef->proc_out.nElements; i++) {
2984 fprintf(fp, "void %s::outgoing_call(const %s_call& /*call_par*/",
2985 class_name, pdef->proc_out.elements[i].name);
2986 if (pdef->testport_type == ADDRESS) {
2987 fprintf(fp, ",\n"
2988 "\tconst %s * /*destination_address*/", pdef->address_name);
2989 }
2990 fputs(")\n"
2991 "{\n\n"
2992 "}\n\n", fp);
2993 }
2994 for (i = 0; i < pdef->proc_in.nElements; i++) {
2995 if (pdef->proc_in.elements[i].is_noblock) continue;
2996 fprintf(fp, "void %s::outgoing_reply(const %s_reply& /*reply_par*/",
2997 class_name, pdef->proc_in.elements[i].name);
2998 if (pdef->testport_type == ADDRESS) {
2999 fprintf(fp, ",\n"
3000 "\tconst %s * /*destination_address*/", pdef->address_name);
3001 }
3002 fputs(")\n"
3003 "{\n\n"
3004 "}\n\n", fp);
3005 }
3006 for (i = 0; i < pdef->proc_in.nElements; i++) {
3007 if (!pdef->proc_in.elements[i].has_exceptions) continue;
3008 fprintf(fp, "void %s::outgoing_raise"
3009 "(const %s_exception& /*raise_exception*/",
3010 class_name, pdef->proc_in.elements[i].name);
3011 if (pdef->testport_type == ADDRESS) {
3012 fprintf(fp, ",\n"
3013 "\tconst %s * /*destination_address*/", pdef->address_name);
3014 }
3015 fputs(")\n"
3016 "{\n\n"
3017 "}\n\n", fp);
3018 }
3019 fputs("} /* end of namespace */\n\n", fp);
3020 fclose(fp);
3021 NOTIFY("Test port skeleton source file `%s' was generated for port "
3022 "type `%s'.", source_name, pdef->dispname);
3023 } else {
3024 DEBUG(1, "Test port source file `%s' already exists. It was not "
3025 "overwritten.", source_name);
3026 }
3027
3028 Free(class_name);
3029 Free(base_class_name);
3030 Free(header_name);
3031 Free(source_name);
3032 Free(user_info);
3033}
This page took 0.135539 seconds and 5 git commands to generate.