1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
12 #include "../../common/memory.h"
13 #include "../../common/path.h"
14 #include "../../common/version_internal.h"
15 #include "../../common/userinfo.h"
18 #include "../datatypes.h"
23 /* macro used in version_internal.h */
25 #define COMMENT_PREFIX "// "
28 static const char *functypes
[] = {"convert", "fast", "backtrack", "sliding"};
31 static char *generate_send_mapping(char *src
, const port_def
*pdef
,
32 const port_msg_mapped_type
*mapped_type
, boolean has_address
)
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");
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");
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 */
56 if (mapped_type
->nTargets
> 1) src
= mputstr(src
, "{\n");
57 switch (target
->mapping_type
) {
60 src
= mputprintf(src
, "// out mapping with a prototype(%s) function\n",
61 functypes
[target
->mapping
.function
.prototype
]);
63 switch (target
->mapping
.function
.prototype
) {
65 src
= mputprintf(src
, "%s mapped_par(%s(send_par));\n",
66 target
->target_name
, target
->mapping
.function
.name
);
69 src
= mputprintf(src
, "%s mapped_par;\n"
70 "%s(send_par, mapped_par);\n",
71 target
->target_name
, target
->mapping
.function
.name
);
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
);
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
);
91 FATAL_ERROR("generate_send_mapping(): invalid function type");
96 src
= mputstr(src
, "// out mapping with a built-in encoder\n");
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"
108 "ttcn_buffer.get_string(mapped_par);\n", target
->target_name
);
112 src
= mputstr(src
, "// out mapping with a built-in decoder\n");
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"
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
;
131 FATAL_ERROR("generate_send_mapping(): invalid mapping type");
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
);
141 "outgoing_send(mapped_par, &destination_address);\n");
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" : "");
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");
156 src
= mputstr(src
, "return;\n"
160 if (mapped_type
->nTargets
> 1) src
= mputstr(src
, "}\n");
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
);
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
);
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
);
182 static char *generate_incoming_mapping(char *src
, const port_def
*pdef
,
183 const port_msg_mapped_type
*mapped_type
)
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");
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 */
201 if (mapped_type
->nTargets
> 1) src
= mputstr(src
, "{\n");
202 switch (target
->mapping_type
) {
205 src
= mputprintf(src
, "// in mapping with a prototype(%s) function\n",
206 functypes
[target
->mapping
.function
.prototype
]);
208 switch (target
->mapping
.function
.prototype
) {
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
);
216 src
= mputprintf(src
, "%s *mapped_par = new %s;\n"
218 "%s(incoming_par, *mapped_par);\n"
220 "delete mapped_par;\n"
222 "}\n", target
->target_name
, target
->target_name
,
223 target
->mapping
.function
.name
);
226 src
= mputprintf(src
,
227 "slider += incoming_par;\n" /* hack */
229 "%s *mapped_par = new %s;\n"
230 "int decoding_result;\n"
232 "decoding_result = %s(slider, *mapped_par);\n"
234 "delete mapped_par;\n"
237 "if (decoding_result==0) {\n", target
->target_name
,
238 target
->target_name
, target
->mapping
.function
.name
);
239 has_condition
= TRUE
;
242 src
= mputprintf(src
, "%s *mapped_par = new %s;\n"
243 "boolean success_flag;\n"
245 "success_flag = %s(incoming_par, *mapped_par) == 0;\n"
247 "delete mapped_par;\n"
250 "if (success_flag) {\n", target
->target_name
,
251 target
->target_name
, target
->mapping
.function
.name
);
252 has_condition
= TRUE
;
255 FATAL_ERROR("generate_incoming_mapping(): " \
256 "invalid function type");
261 src
= mputstr(src
, "// in mapping with a built-in encoder\n");
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
);
278 src
= mputstr(src
, "// in mapping with a built-in decoder\n");
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"
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"
295 "delete mapped_par;\n"
298 "if (TTCN_EncDec::get_last_error_type() == "
299 "TTCN_EncDec::ET_NONE) {\n");
300 has_condition
= TRUE
;
303 FATAL_ERROR("generate_incoming_mapping(): invalid mapping type");
305 src
= mputprintf(src
, "msg_tail_count++;\n"
306 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_DUALRECV)) "
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"
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",
325 src
= mputstr(src
, "append_to_msg_queue(new_item);\n");
327 if (pdef
->has_sliding
328 && target
->mapping_type
== M_FUNCTION
329 && target
->mapping
.function
.prototype
== PT_SLIDING
) {
332 "} else delete mapped_par;\n"
333 "if (decoding_result==2) return; }\n");
336 src
= mputstr(src
, "return;\n"
337 "} else delete mapped_par;\n");
341 if (mapped_type
->nTargets
> 1) src
= mputstr(src
, "}\n");
342 } /* next mapping target */
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
);
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
);
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
);
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"
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
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
375 static 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
)
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
;
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";
392 function_name
= "check_receive";
393 logger_operation
= "check__receive";
394 operation_name
= "Check-receive";
396 function_name
= "receive";
397 logger_operation
= function_name
;
398 operation_name
= "Receive";
400 failed_str
= "failed";
401 failed_status
= "ALT_NO";
404 def
= mputprintf(def
, "alt_status %s(const %s_template& "
405 "sender_template, %s *sender_ptr);\n", function_name
, sender_type
,
407 src
= mputprintf(src
, "alt_status %s::%s(const %s_template& "
408 "sender_template, %s *sender_ptr)\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"
414 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
415 "port %%s failed: Port is not started and the queue is empty.\","
419 "} else ", class_name
, function_name
, sender_type
, sender_type
);
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.\", "
433 "} else if (!sender_template.match("
434 "*my_head->sender_address)) {\n"
435 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMUNSUCC)) "
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())"
450 "}\n", failed_status
, operation_name
, failed_str
);
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"
466 if (is_trigger
) src
= mputstr(src
, "remove_msg_queue_head();\n");
467 src
= mputprintf(src
, "return %s;\n"
469 "if (sender_ptr != NULL) *sender_ptr = %smy_head->%s;\n",
470 failed_status
, is_address
? "*" : "",
471 is_address
? "sender_address" : "sender_component");
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)) "
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
);
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"
504 (unsigned long)msg_idx
, logger_operation
, message_type
->dispname
, (unsigned long)msg_idx
);
508 "TTCN_error(\"Internal error: unknown message\");\n"
513 if (!is_check
) src
= mputstr(src
, "remove_msg_queue_head();\n");
514 src
= mputstr(src
, "return ALT_YES;\n"
522 static 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
)
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
;
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";
540 function_name
= "check_receive";
541 logger_operation
= "check__receive";
542 operation_name
= "Check-receive";
544 function_name
= "receive";
545 logger_operation
= function_name
;
546 operation_name
= "Receive";
548 failed_str
= "failed";
549 failed_status
= "ALT_NO";
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
);
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"
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"
565 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
566 "port %%s failed: Port is not started and the queue is empty.\", "
570 "} else ", class_name
, function_name
, message_type
->name
,
571 message_type
->name
, sender_type
, sender_type
);
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.\", "
585 "} else if (!sender_template.match("
586 "*my_head->sender_address)) {\n"
587 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMUNSUCC)) "
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
);
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"
611 if (is_trigger
) src
= mputstr(src
, "remove_msg_queue_head();\n");
612 src
= mputprintf(src
, "return %s;\n"
613 "} else if (my_head->item_selection != MESSAGE_%lu) {\n"
614 "TTCN_Logger::log(%s, \"Matching on port %%s %s: "
615 "Type of the first message in the queue is not %s.\", "
616 "port_name);\n", failed_status
, (unsigned long) message_index
,
617 is_address
? "TTCN_Logger::MATCHING_MMUNSUCC" :
618 "my_head->sender_component==SYSTEM_COMPREF?"
619 "TTCN_Logger::MATCHING_MMUNSUCC:TTCN_Logger::MATCHING_MCUNSUCC",
620 failed_str
, message_type
->dispname
);
621 if (is_trigger
) src
= mputstr(src
, "remove_msg_queue_head();\n");
622 src
= mputprintf(src
, "return %s;\n"
623 "} else if (!value_template.match(*my_head->message_%lu%s)) {\n",
624 failed_status
, (unsigned long) message_index
,
625 (omit_in_value_list
? ", TRUE" : ""));
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),"
633 " value_template.log_match(*my_head->message_%lu%s),\n"
634 " TTCN_Logger::end_event_log2str())"
638 "TTCN_Logger::MATCHING_MMUNSUCC" :
639 "my_head->sender_component==SYSTEM_COMPREF ? "
640 "TTCN_Logger::MATCHING_MMUNSUCC : TTCN_Logger::MATCHING_MCUNSUCC"),
641 (unsigned long) message_index
,
642 (omit_in_value_list
? ", TRUE" : ""));
643 if (is_trigger
) src
= mputstr(src
, "remove_msg_queue_head();\n");
644 src
= mputprintf(src
, "return %s;\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");
652 src
= mputprintf(src
,
653 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_MMSUCCESS)) "
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),"
658 " value_template.log_match(*my_head->message_%lu%s),\n"
659 " TTCN_Logger::end_event_log2str()));\n"
661 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_MMRECV)) "
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"
671 "}\n", (unsigned long) message_index
,
672 (omit_in_value_list
? ", TRUE" : ""), logger_operation
,
673 message_type
->dispname
, (unsigned long) message_index
);
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),"
683 " value_template.log_match(*my_head->message_%lu%s),\n"
684 " TTCN_Logger::end_event_log2str()));\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"
695 "}\n", (unsigned long) message_index
,
696 (omit_in_value_list
? ", TRUE" : ""), logger_operation
,
697 message_type
->dispname
, (unsigned long) message_index
);
700 if (!is_check
) src
= mputstr(src
, "remove_msg_queue_head();\n");
701 src
= mputstr(src
, "return ALT_YES;\n"
709 typedef enum { GETCALL
, GETREPLY
, CATCH
} getop_t
;
710 enum { NOT_ADDRESS
= 0, IS_ADDRESS
};
711 enum { NOT_CHECK
= 0, IS_CHECK
};
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.
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
725 static 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
)
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";
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";
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";
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";
755 def
= mputprintf(def
, "alt_status %s(const %s_template& "
756 "sender_template, %s *sender_ptr);\n", function_name
, sender_type
,
758 src
= mputprintf(src
, "alt_status %s::%s(const %s_template& "
759 "sender_template, %s *sender_ptr)\n"
761 "if (proc_queue_head == NULL) {\n"
762 "if (is_started) return ALT_MAYBE;\n"
764 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
765 "port %%s failed: Port is not started and the queue is empty.\", "
768 "}\n", class_name
, function_name
, sender_type
, sender_type
);
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"
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.\", "
781 "} else if (!sender_template.match("
782 "*proc_queue_head->sender_address)) {\n"
783 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
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"
792 "return ALT_NO;\n", operation_name
);
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"
809 src
= mputstr(src
, "} else switch (proc_queue_head->item_selection) {\n");
812 for (i
= 0; i
< pdef
->proc_in
.nElements
; i
++) {
813 src
= mputprintf(src
, "case CALL_%lu:\n", (unsigned long) i
);
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
);
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",
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");
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"));
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"));
858 if (!is_check
) src
= mputstr(src
, "remove_proc_queue_head();\n");
859 src
= mputprintf(src
, "return ALT_YES;\n"
862 "TTCN_Logger::log(%s, \"Matching on port %%s "
863 "failed: First entity in the queue is not %s %s.\", port_name);\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
);
877 /** Generate code for logging
879 * Called from generate_getcall, generate_getreply, generate_catch
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"
887 * @param signature_index
889 static 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
)
894 *src_ptr
= mputprintf(*src_ptr
,
895 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMSUCCESS)) "
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),"
900 " %s(*proc_queue_head->%s_%lu%s),\n"
901 " TTCN_Logger::end_event_log2str()));\n"
903 "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_PMIN)) "
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
,
912 (omit_in_value_list
? ", TRUE" : ""),
913 op_str
, (is_check
? "TRUE" : "FALSE"), op_str
, (unsigned long) signature_index
);
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"
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"
935 "}\n", match_str
, op_str
, (unsigned long) signature_index
,
936 op_str
, (is_check
? "TRUE" : "FALSE"),
937 op_str
, (unsigned long) signature_index
);
941 static 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
)
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";
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
,
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"
962 "if (proc_queue_head == NULL) {\n"
963 "if (is_started) return ALT_MAYBE;\n"
965 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
966 "port %%s failed: Port is not started and the queue is empty.\", "
969 "}\n", class_name
, function_name
, signature
->name
, sender_type
,
970 signature
->name
, sender_type
);
972 src
= mputprintf(src
,
973 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
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"
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.\", "
985 "} else if (!sender_template.match("
986 "*proc_queue_head->sender_address)) {\n"
987 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
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"
996 "return ALT_NO;\n", operation_name
);
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"
1011 "return ALT_NO;\n");
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"
1019 "} else if (!getcall_template.match_call"
1020 "(*proc_queue_head->call_%lu%s)) {\n",
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",
1025 signature
->dispname
, (unsigned long) signature_index
,
1026 (omit_in_value_list
? ", TRUE" : ""));
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),"
1034 " getcall_template.log_match_call(*proc_queue_head->call_%lu%s),"
1035 " TTCN_Logger::end_event_log2str()));\n"
1039 "param_ref.set_parameters(*proc_queue_head->call_%lu);\n"
1040 "if (sender_ptr != NULL) *sender_ptr = ",
1042 "TTCN_Logger::MATCHING_PMUNSUCC" :
1043 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1044 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC"),
1045 (unsigned long) signature_index
,
1046 (omit_in_value_list
? ", TRUE" : ""),
1047 (unsigned long) signature_index
);
1048 if (is_address
) src
= mputstr(src
, "*proc_queue_head->sender_address;\n");
1049 else src
= mputstr(src
, "proc_queue_head->sender_component;\n");
1051 generate_proc_incoming_data_logging(&src
, "call",
1052 "getcall_template.log_match_call", is_address
, is_check
, signature_index
);
1054 if (!is_check
) src
= mputstr(src
, "remove_proc_queue_head();\n");
1064 static 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
)
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";
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
,
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"
1085 "if (proc_queue_head == NULL) {\n"
1086 "if (is_started) return ALT_MAYBE;\n"
1088 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
1089 "port %%s failed: Port is not started and the queue is empty.\", "
1092 "}\n", class_name
, function_name
, signature
->name
, sender_type
,
1093 signature
->name
, sender_type
);
1095 src
= mputprintf(src
,
1096 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
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"
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.\", "
1107 "} else if (!sender_template.match("
1108 "*proc_queue_head->sender_address)) {\n"
1109 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
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"
1118 "return ALT_NO;\n", operation_name
);
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"
1133 "return ALT_NO;\n");
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"
1141 "} else if (!getreply_template.match_reply"
1142 "(*proc_queue_head->reply_%lu%s)) {\n", (unsigned long) signature_index
,
1143 is_address
? "TTCN_Logger::MATCHING_PMUNSUCC" :
1144 "proc_queue_head->sender_component==SYSTEM_COMPREF?"
1145 "TTCN_Logger::MATCHING_PMUNSUCC:TTCN_Logger::MATCHING_PCUNSUCC",
1146 signature
->dispname
, (unsigned long) signature_index
,
1147 (omit_in_value_list
? ", TRUE" : ""));
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),"
1156 " getreply_template.log_match_reply(*proc_queue_head->reply_%lu%s), "
1157 " TTCN_Logger::end_event_log2str()));\n"
1161 "param_ref.set_parameters(*proc_queue_head->reply_%lu);\n"
1162 "if (sender_ptr != NULL) *sender_ptr = ",
1164 "TTCN_Logger::MATCHING_PMUNSUCC" :
1165 "proc_queue_head->sender_component==SYSTEM_COMPREF ? "
1166 "TTCN_Logger::MATCHING_PMUNSUCC : TTCN_Logger::MATCHING_PCUNSUCC"),
1167 (unsigned long) signature_index
,
1168 (omit_in_value_list
? ", TRUE" : ""),
1169 (unsigned long) signature_index
);
1170 if (is_address
) src
= mputstr(src
, "*proc_queue_head->sender_address;\n");
1171 else src
= mputstr(src
, "proc_queue_head->sender_component;\n");
1173 generate_proc_incoming_data_logging(&src
, "reply",
1174 "getreply_template.log_match_reply", is_address
, is_check
, signature_index
);
1176 if (!is_check
) src
= mputstr(src
, "remove_proc_queue_head();\n");
1186 static 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
)
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";
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
);
1202 src
= mputprintf(src
, "alt_status %s::%s(const %s_exception_template& "
1203 "catch_template, const %s_template& sender_template, "
1206 "if (proc_queue_head == NULL) {\n"
1207 "if (is_started) return ALT_MAYBE;\n"
1209 "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
1210 "port %%s failed: Port is not started and the queue is empty.\", "
1213 "}\n", class_name
, function_name
, signature
->name
, sender_type
,
1216 src
= mputprintf(src
,
1217 "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
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"
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.\", "
1230 "} else if (!sender_template.match("
1231 "*proc_queue_head->sender_address)) {\n"
1232 "if (TTCN_Logger::log_this_event(TTCN_Logger::MATCHING_PMUNSUCC)) "
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"
1241 "return ALT_NO;\n", operation_name
);
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"
1256 "return ALT_NO;\n");
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"
1262 "TitanLoggerApiSimple::MatchingFailureType_reason::not__an__exception__for__signature,\n"
1263 "CHARSTRING(\"%s\"));\n"
1265 "} else if (!catch_template.match"
1266 "(*proc_queue_head->exception_%lu%s)) {\n",
1267 (unsigned long) signature_index
,
1268 (is_address
? "SYSTEM_COMPREF": "proc_queue_head->sender_component"),
1269 signature
->dispname
, (unsigned long) signature_index
,
1270 (omit_in_value_list
? ", TRUE" : ""));
1272 src
= mputstr(src
, "if (TTCN_Logger::log_this_event("
1273 "TTCN_Logger::MATCHING_PMUNSUCC)) {\n");
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");
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"
1285 " catch_template.log_match(*proc_queue_head->exception_%lu%s),\n"
1286 " TTCN_Logger::end_event_log2str()));\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"),
1293 (unsigned long) signature_index
,
1294 (omit_in_value_list
? ", TRUE" : ""),
1295 (unsigned long) signature_index
);
1296 if (is_address
) src
= mputstr(src
, "*proc_queue_head->sender_address;\n");
1297 else src
= mputstr(src
, "proc_queue_head->sender_component;\n");
1299 generate_proc_incoming_data_logging(&src
, "exception",
1300 "catch_template.log_match", is_address
, is_check
, signature_index
);
1302 if (!is_check
) src
= mputstr(src
, "remove_proc_queue_head();\n");
1313 #define SUNPRO_PUBLIC "public:\n"
1314 #define SUNPRO_PRIVATE "private:\n"
1316 #define SUNPRO_PUBLIC
1317 #define SUNPRO_PRIVATE
1321 void defPortClass(const port_def
* pdef
, output_struct
* output
)
1323 char *def
= NULL
, *src
= NULL
;
1324 char *class_name
, *base_class_name
;
1326 boolean has_incoming_call
, has_incoming_reply
, has_incoming_exception
;
1327 boolean has_msg_queue
, has_proc_queue
;
1329 if (pdef
->testport_type
== INTERNAL
) {
1330 class_name
= mcopystr(pdef
->name
);
1331 base_class_name
= mcopystr("PORT");
1333 switch (pdef
->port_type
) {
1335 class_name
= mprintf("%s_BASE", pdef
->name
);
1336 base_class_name
= mcopystr("PORT");
1339 class_name
= mcopystr(pdef
->name
);
1340 base_class_name
= mprintf("%s_PROVIDER", pdef
->name
);
1343 class_name
= mcopystr(pdef
->name
);
1344 base_class_name
= mprintf("%s_PROVIDER", pdef
->provider_name
);
1347 FATAL_ERROR("defPortClass(): invalid port type");
1351 has_incoming_call
= pdef
->proc_in
.nElements
> 0;
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
;
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
;
1369 has_msg_queue
= pdef
->msg_in
.nElements
> 0;
1370 has_proc_queue
= has_incoming_call
|| has_incoming_reply
||
1371 has_incoming_exception
;
1373 def
= mprintf("class %s : public %s {\n", class_name
, base_class_name
);
1375 /* private data types and member functions for queue management */
1376 if (has_msg_queue
) {
1377 /* data structures for the message queue */
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
);
1385 def
= mputstr(def
, " };\n"
1387 "struct msg_queue_item : public msg_queue_item_base {\n"
1388 "msg_selection item_selection;\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
);
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
);
1399 def
= mputstr(def
, "};\n\n");
1400 if (pdef
->has_sliding
) {
1401 def
= mputprintf(def
, "OCTETSTRING sliding_buffer;\n");
1403 def
= mputstr(def
, "void remove_msg_queue_head();\n");
1404 src
= mputprintf(src
,
1405 "void %s::remove_msg_queue_head()\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"
1417 if (pdef
->testport_type
== ADDRESS
) {
1418 src
= mputstr(src
, "delete ((msg_queue_item*)msg_queue_head)->sender_address;\n");
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));"
1429 } /* if has_msg_queue */
1431 if (has_proc_queue
) {
1432 /* data structures for the procedure queue */
1433 boolean is_first
= TRUE
;
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
);
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
);
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
);
1454 def
= mputstr(def
, " };\n"
1456 "struct proc_queue_item {\n"
1457 "proc_selection item_selection;\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
);
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
);
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
);
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
);
1478 def
= mputstr(def
, "proc_queue_item *next_item;\n"
1479 "} *proc_queue_head, *proc_queue_tail;\n");
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"
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
);
1493 def
= mputstr(def
, "void remove_proc_queue_head();\n");
1494 src
= mputprintf(src
,
1495 "void %s::remove_proc_queue_head()\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
);
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
);
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
);
1515 src
= mputstr(src
, "default:\n"
1516 "TTCN_error(\"Internal error: Invalid signature selector in "
1517 "the queue of port %s.\", port_name);\n"
1519 if (pdef
->testport_type
== ADDRESS
) {
1520 src
= mputstr(src
, "delete proc_queue_head->sender_address;\n");
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));"
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"
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");
1548 def
= mputstr(def
, "public:\n");
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");
1557 def
= mputstr(def
, ");\n");
1558 src
= mputprintf(src
, "%s::%s(const char *par_port_name)\n"
1559 " : %s(par_port_name)\n"
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");
1570 if (has_msg_queue
|| has_proc_queue
) {
1571 def
= mputprintf(def
, "~%s();\n", class_name
);
1572 src
= mputprintf(src
, "%s::~%s()\n"
1575 "}\n\n", class_name
, class_name
);
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
;
1582 def
= mputprintf(def
, "void send(const %s& send_par, "
1583 "const COMPONENT& destination_component);\n", msg
->name
);
1585 src
= mputprintf(src
, "void %s::send(const %s& send_par, "
1586 "const COMPONENT& destination_component)\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 "
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");
1609 src
= mputprintf(src
, "outgoing_send(send_par%s);\n",
1610 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
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
);
1619 /* the message type is mapped to another outgoing type of the
1620 * external interface */
1621 src
= generate_send_mapping(src
, pdef
, msg
, FALSE
);
1623 src
= mputstr(src
, "}\n\n");
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
);
1630 src
= mputprintf(src
, "void %s::send(const %s& send_par, "
1631 "const %s& destination_address)\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))"
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 : \"),"
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");
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"
1656 "send(send_par, COMPONENT(get_default_destination()));\n"
1657 "}\n\n", class_name
, msg
->name
);
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"
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
);
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"
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
);
1680 def
= mputprintf(def
, "void send(const %s_template& send_par);\n",
1682 src
= mputprintf(src
, "void %s::send(const %s_template& send_par)\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
);
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"
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"
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),"
1712 " TTCN_Logger::end_event_log2str()));\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");
1720 src
= mputprintf(src
, "outgoing_call(call_tmp%s);\n",
1721 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
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"
1729 "}\n\n", sig
->dispname
);
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"
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))"
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),"
1750 " TTCN_Logger::end_event_log2str()));\n"
1752 "outgoing_call(call_tmp, &destination_address);\n"
1754 class_name
, sig
->name
, pdef
->address_name
, sig
->name
);
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& "
1762 "call(call_template, COMPONENT(get_default_destination()));\n"
1763 "}\n\n", class_name
, sig
->name
);
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",
1773 src
= mputprintf(src
, "void %s::reply(const %s_template& "
1774 "reply_template, const COMPONENT& destination_component)\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),"
1790 " TTCN_Logger::end_event_log2str()));\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");
1798 src
= mputprintf(src
, "outgoing_reply(reply_tmp%s);\n",
1799 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
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"
1807 "}\n\n", sig
->dispname
);
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"
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))"
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),"
1828 " TTCN_Logger::end_event_log2str()));\n"
1830 "outgoing_reply(reply_tmp, &destination_address);\n"
1832 class_name
, sig
->name
, pdef
->address_name
, sig
->name
);
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& "
1840 "reply(reply_template, COMPONENT(get_default_destination()));\n"
1841 "}\n\n", class_name
, sig
->name
);
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",
1851 src
= mputprintf(src
, "void %s::raise(const %s_exception& "
1852 "raise_exception, const COMPONENT& destination_component)\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"
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");
1875 src
= mputprintf(src
, "outgoing_raise(raise_exception%s);\n",
1876 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
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"
1884 "}\n\n", sig
->dispname
);
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"
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))"
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"
1906 "outgoing_raise(raise_exception, &destination_address);\n"
1908 class_name
, sig
->name
, pdef
->address_name
);
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"
1916 "raise(raise_exception, COMPONENT(get_default_destination()));\n"
1917 "}\n\n", class_name
, sig
->name
);
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
);
1931 def
= mputstr(def
, ") = 0;\n");
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
);
1941 def
= mputstr(def
, ") = 0;\n");
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
);
1952 def
= mputstr(def
, ") = 0;\n");
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
);
1964 def
= mputstr(def
, ") = 0;\n");
1966 def
= mputstr(def
, "public:\n");
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
,
1974 /* generic check_receive function */
1975 generate_generic_receive(&def
, &src
, pdef
, class_name
, TRUE
, FALSE
,
1977 /* generic trigger function */
1978 generate_generic_receive(&def
, &src
, pdef
, class_name
, FALSE
, TRUE
,
1980 if (pdef
->testport_type
== ADDRESS
) {
1981 /* generic receive with address */
1982 generate_generic_receive(&def
, &src
, pdef
, class_name
, FALSE
,
1984 /* generic check_receive with address */
1985 generate_generic_receive(&def
, &src
, pdef
, class_name
, TRUE
,
1987 /* generic trigger with address */
1988 generate_generic_receive(&def
, &src
, pdef
, class_name
, FALSE
,
1993 /* Receive routines with message type */
1994 for (i
= 0; i
< pdef
->msg_in
.nElements
; i
++) {
1996 generate_receive(&def
, &src
, pdef
, class_name
, i
, FALSE
, FALSE
, FALSE
);
1998 generate_receive(&def
, &src
, pdef
, class_name
, i
, TRUE
, FALSE
, FALSE
);
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
,
2005 /* check_receive with address */
2006 generate_receive(&def
, &src
, pdef
, class_name
, i
, TRUE
, FALSE
,
2008 /* trigger with address */
2009 generate_receive(&def
, &src
, pdef
, class_name
, i
, FALSE
, TRUE
,
2014 if (has_incoming_call
) {
2015 /* generic getcall function */
2016 generate_generic_getop(GETCALL
, &def
, &src
, pdef
, class_name
, FALSE
,
2018 /* generic check_getcall function */
2019 generate_generic_getop(GETCALL
, &def
, &src
, pdef
, class_name
, TRUE
,
2021 if (pdef
->testport_type
== ADDRESS
) {
2022 /* generic getcall with address */
2023 generate_generic_getop(GETCALL
, &def
, &src
, pdef
, class_name
,
2025 /* generic check_getcall with address */
2026 generate_generic_getop(GETCALL
, &def
, &src
, pdef
, class_name
,
2031 /* getcall functions */
2032 for (i
= 0; i
< pdef
->proc_in
.nElements
; i
++) {
2034 generate_getcall(&def
, &src
, pdef
, class_name
, i
, FALSE
, FALSE
);
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
);
2045 if (has_incoming_reply
) {
2046 /* generic getreply function */
2047 generate_generic_getop(GETREPLY
, &def
, &src
, pdef
, class_name
, FALSE
,
2049 /* generic check_getreply function */
2050 generate_generic_getop(GETREPLY
, &def
, &src
, pdef
, class_name
, TRUE
,
2052 if (pdef
->testport_type
== ADDRESS
) {
2053 /* generic getreply with address */
2054 generate_generic_getop(GETREPLY
, &def
, &src
, pdef
, class_name
,
2056 /* generic check_getreply with address */
2057 generate_generic_getop(GETREPLY
, &def
, &src
, pdef
, class_name
,
2062 /* getreply functions */
2063 for (i
= 0; i
< pdef
->proc_out
.nElements
; i
++) {
2064 if (pdef
->proc_out
.elements
[i
].is_noblock
) continue;
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
);
2077 if (has_incoming_exception
) {
2078 /* generic catch (get_exception) function */
2079 generate_generic_getop(CATCH
, &def
, &src
, pdef
, class_name
, FALSE
,
2081 /* generic check_catch function */
2082 generate_generic_getop(CATCH
, &def
, &src
, pdef
, class_name
, TRUE
,
2084 if (pdef
->testport_type
== ADDRESS
) {
2085 /* generic catch (get_exception) with address */
2086 generate_generic_getop(CATCH
, &def
, &src
, pdef
, class_name
, FALSE
,
2088 /* generic check_catch with address */
2089 generate_generic_getop(CATCH
, &def
, &src
, pdef
, class_name
, TRUE
,
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
);
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
);
2109 def
= mputstr(def
, "private:\n");
2111 if (pdef
->port_type
== USER
) {
2112 /* incoming_message() functions for the incoming types of the provider
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",
2122 (pdef
->has_sliding
? ", OCTETSTRING& slider" : ""));
2123 if (pdef
->testport_type
== ADDRESS
) {
2124 def
= mputprintf(def
, ", const %s *sender_address",
2125 pdef
->address_name
);
2127 def
= mputstr(def
, ");\n");
2129 src
= mputprintf(src
, "void %s::incoming_message(const %s& "
2130 "incoming_par, component sender_component%s", class_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
);
2137 src
= mputstr(src
, ")\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! */
2150 if (pdef
->testport_type
== 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()) : "
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
);
2169 src
= mputprintf(src
,
2171 "// simple mapping\n"
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
,
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
);
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");
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
);
2200 def
= mputstr(def
, ");\n");
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
);
2209 src
= mputstr(src
, ")\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)) "
2216 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__msg,"
2217 " port_name, sender_component, msg_tail_count,\n"
2219 if (pdef
->testport_type
== 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()) : "
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"
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
);
2250 src
= mputstr(src
, "append_to_msg_queue(new_item);\n"
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
);
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
);
2271 src
= mputstr(src
, ")\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)) "
2278 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__call,"
2279 " port_name, sender_component, proc_tail_count,\n"
2281 if (pdef
->testport_type
== 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()) : "
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"
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
);
2309 src
= mputstr(src
, "append_to_proc_queue(new_item);\n"
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
);
2323 def
= mputstr(def
, ");\n");
2324 src
= mputprintf(src
, "void %s::incoming_reply(const %s_reply& "
2325 "incoming_par, component sender_component", class_name
,
2327 if (pdef
->testport_type
== ADDRESS
) {
2328 src
= mputprintf(src
, ", const %s *sender_address",
2329 pdef
->address_name
);
2331 src
= mputstr(src
, ")\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)) "
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
) {
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()) : ");
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"
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
);
2366 src
= mputstr(src
, "append_to_proc_queue(new_item);\n"
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
);
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
);
2388 src
= mputstr(src
, ")\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)) "
2395 "TTCN_Logger::log_port_queue(TitanLoggerApiSimple::Port__Queue_operation::enqueue__exception,"
2396 " port_name, sender_component, proc_tail_count,\n"
2398 if (pdef
->testport_type
== 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()) : "
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"
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
);
2424 src
= mputstr(src
, "append_to_proc_queue(new_item);\n"
2428 def
= mputstr(def
, "protected:\n");
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
);
2443 def
= mputprintf(def
, ") { incoming_message(incoming_par, "
2444 "SYSTEM_COMPREF%s); }\n",
2445 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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
);
2456 def
= mputprintf(def
, ") { incoming_call(incoming_par, "
2457 "SYSTEM_COMPREF%s); }\n",
2458 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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
);
2470 def
= mputprintf(def
, ") { incoming_reply(incoming_par, "
2471 "SYSTEM_COMPREF%s); }\n",
2472 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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
);
2484 def
= mputprintf(def
, ") { incoming_exception(incoming_par, "
2485 "SYSTEM_COMPREF%s); }\n",
2486 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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
);
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
);
2514 src
= mputprintf(src
, ")\n"
2516 "incoming_message(incoming_par, SYSTEM_COMPREF%s%s);\n"
2518 (pdef
->has_sliding
? ", sliding_buffer": ""),
2519 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
2521 for (i
= 0; i
< pdef
->proc_in
.nElements
; i
++) {
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
);
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
);
2536 src
= mputprintf(src
, ")\n"
2538 "incoming_call(incoming_par, SYSTEM_COMPREF%s);\n"
2540 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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
);
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
);
2559 src
= mputprintf(src
, ")\n"
2561 "incoming_reply(incoming_par, SYSTEM_COMPREF%s);\n"
2563 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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
);
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
);
2583 src
= mputprintf(src
, ")\n"
2585 "incoming_exception(incoming_par, SYSTEM_COMPREF%s);\n"
2587 pdef
->testport_type
== ADDRESS
? ", sender_address" : "");
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"
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
;
2608 msg_name
= pdef
->msg_in
.elements
[i
].name
;
2609 msg_dispname
= pdef
->msg_in
.elements
[i
].dispname
;
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"
2616 "} else ", msg_dispname
, msg_name
,
2617 (pdef
->has_sliding
? ", slider" : ""),
2618 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
2620 src
= mputstr(src
, "return FALSE;\n"
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"
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"
2637 "} else ", pdef
->proc_in
.elements
[i
].dispname
,
2638 pdef
->proc_in
.elements
[i
].name
,
2639 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
2641 src
= mputstr(src
, "return FALSE;\n"
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"
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"
2659 "} else ", pdef
->proc_out
.elements
[i
].dispname
,
2660 pdef
->proc_out
.elements
[i
].name
,
2661 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
2663 src
= mputstr(src
, "return FALSE;\n"
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"
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"
2682 "} else ", pdef
->proc_out
.elements
[i
].dispname
,
2683 pdef
->proc_out
.elements
[i
].name
,
2684 pdef
->testport_type
== ADDRESS
? ", NULL" : "");
2686 src
= mputstr(src
, "return FALSE;\n"
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.) */
2694 def
= mputstr(def
, "};\n\n");
2695 /* end of base class */
2697 /* Putting everything to the output */
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
);
2705 output
->header
.class_defs
= mputstr(output
->header
.class_defs
, def
);
2708 if (pdef
->testport_type
!= INTERNAL
) {
2709 switch (pdef
->port_type
) {
2711 output
->header
.testport_includes
= mputprintf(
2712 output
->header
.testport_includes
, "#include \"%s.hh\"\n",
2713 duplicate_underscores
? pdef
->name
: pdef
->filename
);
2716 output
->header
.includes
= mputprintf(output
->header
.includes
,
2717 "#include \"%s.hh\"\n",
2718 duplicate_underscores
? pdef
->name
: pdef
->filename
);
2724 output
->source
.methods
= mputstr(output
->source
.methods
, src
);
2728 Free(base_class_name
);
2731 void generateTestPortSkeleton(const port_def
*pdef
)
2733 char *class_name
, *base_class_name
;
2734 const char *file_prefix
=
2735 duplicate_underscores
? pdef
->name
: pdef
->filename
;
2737 char *header_name
, *source_name
;
2738 char *user_info
= NULL
;
2740 DEBUG(1, "Generating test port skeleton for port type `%s' ...",
2743 if (pdef
->port_type
== PROVIDER
) {
2744 class_name
= mprintf("%s_PROVIDER", pdef
->name
);
2745 base_class_name
= mcopystr("PORT");
2747 class_name
= mcopystr(pdef
->name
);
2748 base_class_name
= mprintf("%s_BASE", pdef
->name
);
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
);
2755 header_name
= mprintf("%s.hh", file_prefix
);
2756 source_name
= mprintf("%s.cc", file_prefix
);
2759 if (force_overwrite
|| get_path_status(header_name
) == PS_NONEXISTENT
) {
2760 FILE *fp
= fopen(header_name
, "w");
2762 ERROR("Cannot open output test port skeleton header file `%s' for "
2763 "writing: %s", header_name
, strerror(errno
));
2766 if (user_info
== NULL
) user_info
= get_user_info();
2768 "// This Test Port skeleton header file was generated by the\n"
2769 "// TTCN-3 Compiler of the TTCN-3 Test Executor version "
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"
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 "
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
);
2787 fprintf(fp
, "#include \"%s.hh\"\n\n",
2788 duplicate_underscores
? pdef
->module_name
:
2789 pdef
->module_dispname
);
2791 fprintf(fp
, "namespace %s {\n\n", pdef
->module_name
);
2793 "class %s : public %s {\n"
2795 "\t%s(const char *par_port_name%s);\n"
2797 "\tvoid set_parameter(const char *parameter_name,\n"
2798 "\t\tconst char *parameter_value);\n\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"
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
);
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
) {
2819 "\t\tconst %s *destination_address", pdef
->address_name
);
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
) {
2828 "\t\tconst %s *destination_address", pdef
->address_name
);
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
) {
2838 "\t\tconst %s *destination_address", pdef
->address_name
);
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
) {
2848 "\t\tconst %s *destination_address", pdef
->address_name
);
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
) {
2859 "\t\tconst %s *sender_address = NULL",
2860 pdef
->address_name
);
2862 fputs(") = 0;\n", fp
);
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
) {
2869 "\t\tconst %s *sender_address = NULL",
2870 pdef
->address_name
);
2872 fputs(") = 0;\n", fp
);
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
) {
2880 "\t\tconst %s *sender_address = NULL",
2881 pdef
->address_name
);
2883 fputs(") = 0;\n", fp
);
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
) {
2892 "\t\tconst %s *sender_address = NULL",
2893 pdef
->address_name
);
2895 fputs(") = 0;\n", fp
);
2898 fputs("};\n\n", fp
);
2899 fputs("} /* end of namespace */\n\n", fp
);
2900 fputs("#endif\n", fp
);
2902 NOTIFY("Test port skeleton header file `%s' was generated for port "
2903 "type `%s'.", header_name
, pdef
->dispname
);
2905 DEBUG(1, "Test port header file `%s' already exists. It was not "
2906 "overwritten.", header_name
);
2909 if (force_overwrite
|| get_path_status(source_name
) == PS_NONEXISTENT
) {
2910 FILE *fp
= fopen(source_name
, "w");
2912 ERROR("Cannot open output test port skeleton source file `%s' for "
2913 "writing: %s", source_name
, strerror(errno
));
2916 if (user_info
== NULL
) user_info
= get_user_info();
2918 "// This Test Port skeleton source file was generated by the\n"
2919 "// TTCN-3 Compiler of the TTCN-3 Test Executor version "
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
);
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"
2940 "void %s::set_parameter(const char * /*parameter_name*/,\n"
2941 "\tconst char * /*parameter_value*/)\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"
2949 "void %s::Handle_Fd_Event_Writable(int /*fd*/)\n"
2952 "void %s::Handle_Fd_Event_Readable(int /*fd*/)\n"
2955 "/*void %s::Handle_Timeout(double time_since_last_call) {}*/\n\n"
2956 "void %s::user_map(const char * /*system_port*/)\n"
2959 "void %s::user_unmap(const char * /*system_port*/)\n"
2962 "void %s::user_start()\n"
2965 "void %s::user_stop()\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
,
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
) {
2977 "\tconst %s * /*destination_address*/", pdef
->address_name
);
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
) {
2988 "\tconst %s * /*destination_address*/", pdef
->address_name
);
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
) {
3000 "\tconst %s * /*destination_address*/", pdef
->address_name
);
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
) {
3013 "\tconst %s * /*destination_address*/", pdef
->address_name
);
3019 fputs("} /* end of namespace */\n\n", fp
);
3021 NOTIFY("Test port skeleton source file `%s' was generated for port "
3022 "type `%s'.", source_name
, pdef
->dispname
);
3024 DEBUG(1, "Test port source file `%s' already exists. It was not "
3025 "overwritten.", source_name
);
3029 Free(base_class_name
);