Commit 8abd72b8 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

disallowed the usage of '*' in receive, getreply, catch and done (artf433757)



Change-Id: I9583325c6b0778313b9e90bcb0dd90d9cb4ceb27
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 9e26131c
...@@ -2254,6 +2254,8 @@ void Type::generate_code_done(output_struct *target) ...@@ -2254,6 +2254,8 @@ void Type::generate_code_done(output_struct *target)
"if (!component_reference.is_bound()) " "if (!component_reference.is_bound()) "
"TTCN_error(\"Performing a done operation on an unbound component " "TTCN_error(\"Performing a done operation on an unbound component "
"reference.\");\n" "reference.\");\n"
"if (value_template.get_selection() == ANY_OR_OMIT) "
"TTCN_error(\"Done operation using '*' as matching template\");\n"
"Text_Buf *text_buf;\n" "Text_Buf *text_buf;\n"
"alt_status ret_val = TTCN_Runtime::component_done(" "alt_status ret_val = TTCN_Runtime::component_done("
"(component)component_reference, \"%s\", text_buf);\n" "(component)component_reference, \"%s\", text_buf);\n"
......
...@@ -3318,7 +3318,7 @@ error: ...@@ -3318,7 +3318,7 @@ error:
msg_type = out_msgs->get_type_byIndex(0); msg_type = out_msgs->get_type_byIndex(0);
} else { } else {
// there are more than one outgoing message types // there are more than one outgoing message types
msg_type = get_outgoing_type(port_op.s.sendpar); msg_type = get_msg_sig_type(port_op.s.sendpar);
if (msg_type) { if (msg_type) {
size_t nof_comp_types = size_t nof_comp_types =
out_msgs->get_nof_compatible_types(msg_type); out_msgs->get_nof_compatible_types(msg_type);
...@@ -3351,7 +3351,7 @@ error: ...@@ -3351,7 +3351,7 @@ error:
} }
// determining the message type if it is not done so far // determining the message type if it is not done so far
if (!msg_type_determined) { if (!msg_type_determined) {
msg_type = get_outgoing_type(port_op.s.sendpar); msg_type = get_msg_sig_type(port_op.s.sendpar);
} }
if (!msg_type) msg_type = Type::get_pooltype(Type::T_ERROR); if (!msg_type) msg_type = Type::get_pooltype(Type::T_ERROR);
// checking the parameter (template instance) // checking the parameter (template instance)
...@@ -3396,7 +3396,7 @@ error: ...@@ -3396,7 +3396,7 @@ error:
signature = out_sigs->get_type_byIndex(0); signature = out_sigs->get_type_byIndex(0);
} else { } else {
// there are more than one outgoing signatures // there are more than one outgoing signatures
signature = get_outgoing_type(port_op.s.sendpar); signature = get_msg_sig_type(port_op.s.sendpar);
if (signature) { if (signature) {
if (!out_sigs->has_type(signature)) { if (!out_sigs->has_type(signature)) {
port_op.s.sendpar->error("Signature `%s' is not present on the " port_op.s.sendpar->error("Signature `%s' is not present on the "
...@@ -3421,7 +3421,7 @@ error: ...@@ -3421,7 +3421,7 @@ error:
} }
} }
if (!signature_determined) if (!signature_determined)
signature = get_outgoing_type(port_op.s.sendpar); signature = get_msg_sig_type(port_op.s.sendpar);
if (!signature) signature = Type::get_pooltype(Type::T_ERROR); if (!signature) signature = Type::get_pooltype(Type::T_ERROR);
// checking the parameter (template instance) // checking the parameter (template instance)
port_op.s.sendpar->chk(signature); port_op.s.sendpar->chk(signature);
...@@ -3504,7 +3504,7 @@ error: ...@@ -3504,7 +3504,7 @@ error:
signature = in_sigs->get_type_byIndex(0); signature = in_sigs->get_type_byIndex(0);
} else { } else {
// there are more than one incoming signatures // there are more than one incoming signatures
signature = get_outgoing_type(port_op.s.sendpar); signature = get_msg_sig_type(port_op.s.sendpar);
if (signature) { if (signature) {
if (!in_sigs->has_type(signature)) { if (!in_sigs->has_type(signature)) {
port_op.s.sendpar->error("Signature `%s' is not present on the " port_op.s.sendpar->error("Signature `%s' is not present on the "
...@@ -3529,7 +3529,7 @@ error: ...@@ -3529,7 +3529,7 @@ error:
} }
} }
if (!signature_determined) if (!signature_determined)
signature = get_outgoing_type(port_op.s.sendpar); signature = get_msg_sig_type(port_op.s.sendpar);
if (!signature) signature = Type::get_pooltype(Type::T_ERROR); if (!signature) signature = Type::get_pooltype(Type::T_ERROR);
// checking the parameter (template instance) // checking the parameter (template instance)
port_op.s.sendpar->chk(signature); port_op.s.sendpar->chk(signature);
...@@ -3625,7 +3625,7 @@ error: ...@@ -3625,7 +3625,7 @@ error:
exc_type = exceptions->get_type_byIndex(0); exc_type = exceptions->get_type_byIndex(0);
} else { } else {
// the signature has more than one exception types // the signature has more than one exception types
exc_type = get_outgoing_type(port_op.s.sendpar); exc_type = get_msg_sig_type(port_op.s.sendpar);
if (exc_type) { if (exc_type) {
size_t nof_comp_types = size_t nof_comp_types =
exceptions->get_nof_compatible_types(exc_type); exceptions->get_nof_compatible_types(exc_type);
...@@ -3653,7 +3653,7 @@ error: ...@@ -3653,7 +3653,7 @@ error:
} }
// determining the type of exception if it is not done so far // determining the type of exception if it is not done so far
if (!exc_type_determined) { if (!exc_type_determined) {
exc_type = get_outgoing_type(port_op.s.sendpar); exc_type = get_msg_sig_type(port_op.s.sendpar);
} }
if (!exc_type) exc_type = Type::get_pooltype(Type::T_ERROR); if (!exc_type) exc_type = Type::get_pooltype(Type::T_ERROR);
// checking the exception template // checking the exception template
...@@ -3707,7 +3707,7 @@ error: ...@@ -3707,7 +3707,7 @@ error:
msg_type = in_msgs->get_type_byIndex(0); msg_type = in_msgs->get_type_byIndex(0);
} else { } else {
// there are more than one incoming message types // there are more than one incoming message types
msg_type = get_incoming_type(port_op.r.rcvpar, port_op.r.redirect.value); msg_type = get_msg_sig_type(port_op.r.rcvpar);
if (msg_type) { if (msg_type) {
size_t nof_comp_types = size_t nof_comp_types =
in_msgs->get_nof_compatible_types(msg_type); in_msgs->get_nof_compatible_types(msg_type);
...@@ -3747,11 +3747,16 @@ error: ...@@ -3747,11 +3747,16 @@ error:
} }
} }
if (!msg_type_determined) { if (!msg_type_determined) {
msg_type = get_incoming_type(port_op.r.rcvpar, port_op.r.redirect.value); msg_type = get_msg_sig_type(port_op.r.rcvpar);
} }
if (!msg_type) msg_type = Type::get_pooltype(Type::T_ERROR); if (!msg_type) msg_type = Type::get_pooltype(Type::T_ERROR);
// check the template instance using the message type // check the template instance using the message type
port_op.r.rcvpar->chk(msg_type); port_op.r.rcvpar->chk(msg_type);
if (port_op.r.rcvpar->get_Template()->get_template_refd_last()->
get_templatetype() == Template::ANY_OR_OMIT) {
port_op.r.rcvpar->error("'*' cannot be used as a matching template "
"for a '%s' operation", stmt_name);
}
// check the value redirect if it exists // check the value redirect if it exists
if (port_op.r.redirect.value != NULL) { if (port_op.r.redirect.value != NULL) {
port_op.r.redirect.value->chk(msg_type); port_op.r.redirect.value->chk(msg_type);
...@@ -3805,7 +3810,7 @@ error: ...@@ -3805,7 +3810,7 @@ error:
signature = in_sigs->get_type_byIndex(0); signature = in_sigs->get_type_byIndex(0);
} else { } else {
// there are more than one incoming signatures // there are more than one incoming signatures
signature = get_outgoing_type(port_op.r.rcvpar); signature = get_msg_sig_type(port_op.r.rcvpar);
if (signature) { if (signature) {
if (!in_sigs->has_type(signature)) { if (!in_sigs->has_type(signature)) {
port_op.r.rcvpar->error("Signature `%s' is not present on the " port_op.r.rcvpar->error("Signature `%s' is not present on the "
...@@ -3838,7 +3843,7 @@ error: ...@@ -3838,7 +3843,7 @@ error:
} }
} }
if (!signature_determined) if (!signature_determined)
signature = get_outgoing_type(port_op.r.rcvpar); signature = get_msg_sig_type(port_op.r.rcvpar);
if (!signature) signature = Type::get_pooltype(Type::T_ERROR); if (!signature) signature = Type::get_pooltype(Type::T_ERROR);
// checking the parameter (template instance) // checking the parameter (template instance)
port_op.r.rcvpar->chk(signature); port_op.r.rcvpar->chk(signature);
...@@ -3909,7 +3914,7 @@ error: ...@@ -3909,7 +3914,7 @@ error:
signature = out_sigs->get_type_byIndex(0); signature = out_sigs->get_type_byIndex(0);
} else { } else {
// there are more than one outgoing signatures // there are more than one outgoing signatures
signature = get_outgoing_type(port_op.r.rcvpar); signature = get_msg_sig_type(port_op.r.rcvpar);
if (signature) { if (signature) {
if (!out_sigs->has_type(signature)) { if (!out_sigs->has_type(signature)) {
port_op.r.rcvpar->error("Signature `%s' is not present on the " port_op.r.rcvpar->error("Signature `%s' is not present on the "
...@@ -3950,7 +3955,7 @@ error: ...@@ -3950,7 +3955,7 @@ error:
} }
} }
if (!signature_determined) if (!signature_determined)
signature = get_outgoing_type(port_op.r.rcvpar); signature = get_msg_sig_type(port_op.r.rcvpar);
if (!signature) signature = Type::get_pooltype(Type::T_ERROR); if (!signature) signature = Type::get_pooltype(Type::T_ERROR);
// checking the parameter (template instance) // checking the parameter (template instance)
port_op.r.rcvpar->chk(signature); port_op.r.rcvpar->chk(signature);
...@@ -3992,9 +3997,14 @@ error: ...@@ -3992,9 +3997,14 @@ error:
} }
// checking the value match if present // checking the value match if present
if (port_op.r.getreply_valuematch) { if (port_op.r.getreply_valuematch) {
Error_Context cntxt2(port_op.s.replyval, "In value match"); Error_Context cntxt2(port_op.s.replyval, "In value match");
if (!return_type) return_type = Type::get_pooltype(Type::T_ERROR); if (!return_type) return_type = Type::get_pooltype(Type::T_ERROR);
port_op.r.getreply_valuematch->chk(return_type); port_op.r.getreply_valuematch->chk(return_type);
if (port_op.r.getreply_valuematch->get_Template()->get_template_refd_last()->
get_templatetype() == Template::ANY_OR_OMIT) {
port_op.r.getreply_valuematch->error("'*' cannot be used as a return "
"value matching template for a '%s' operation", stmt_name);
}
} }
// checking the value redirect if present // checking the value redirect if present
if (port_op.r.redirect.value != NULL) { if (port_op.r.redirect.value != NULL) {
...@@ -4098,7 +4108,7 @@ error: ...@@ -4098,7 +4108,7 @@ error:
exc_type = exceptions->get_type_byIndex(0); exc_type = exceptions->get_type_byIndex(0);
} else { } else {
// the signature has more than one exception types // the signature has more than one exception types
exc_type = get_incoming_type(port_op.r.rcvpar, port_op.r.redirect.value); exc_type = get_msg_sig_type(port_op.r.rcvpar);
if (exc_type) { if (exc_type) {
size_t nof_comp_types = size_t nof_comp_types =
exceptions->get_nof_compatible_types(exc_type); exceptions->get_nof_compatible_types(exc_type);
...@@ -4125,11 +4135,16 @@ error: ...@@ -4125,11 +4135,16 @@ error:
} }
} }
if (!exc_type_determined) { if (!exc_type_determined) {
exc_type = get_incoming_type(port_op.r.rcvpar, port_op.r.redirect.value); exc_type = get_msg_sig_type(port_op.r.rcvpar);
} }
if (!exc_type) exc_type = Type::get_pooltype(Type::T_ERROR); if (!exc_type) exc_type = Type::get_pooltype(Type::T_ERROR);
// check the template instance using the exception type // check the template instance using the exception type
port_op.r.rcvpar->chk(exc_type); port_op.r.rcvpar->chk(exc_type);
if (port_op.r.rcvpar->get_Template()->get_template_refd_last()->
get_templatetype() == Template::ANY_OR_OMIT) {
port_op.r.rcvpar->error("'*' cannot be used as a matching template for "
"a '%s' operation", stmt_name);
}
// check the value redirect if it exists // check the value redirect if it exists
if (port_op.r.redirect.value != NULL) { if (port_op.r.redirect.value != NULL) {
port_op.r.redirect.value->chk(exc_type); port_op.r.redirect.value->chk(exc_type);
...@@ -4405,8 +4420,7 @@ error: ...@@ -4405,8 +4420,7 @@ error:
// specific component reference // specific component reference
if (comp_op.donereturn.donematch) { if (comp_op.donereturn.donematch) {
// try to determine the type of the return value // try to determine the type of the return value
Type *return_type = get_incoming_type(comp_op.donereturn.donematch, Type *return_type = get_msg_sig_type(comp_op.donereturn.donematch);
comp_op.donereturn.redirect);
if (return_type) { if (return_type) {
bool return_type_correct = false; bool return_type_correct = false;
for (Type *t = return_type; ; t = t->get_type_refd()) { for (Type *t = return_type; ; t = t->get_type_refd()) {
...@@ -4426,6 +4440,11 @@ error: ...@@ -4426,6 +4440,11 @@ error:
return_type = Type::get_pooltype(Type::T_ERROR); return_type = Type::get_pooltype(Type::T_ERROR);
} }
comp_op.donereturn.donematch->chk(return_type); comp_op.donereturn.donematch->chk(return_type);
if (comp_op.donereturn.donematch->get_Template()->get_template_refd_last()->
get_templatetype() == Template::ANY_OR_OMIT) {
comp_op.donereturn.donematch->error("'*' cannot be used as a matching "
"template for a 'done' operation");
}
if (comp_op.donereturn.redirect != NULL) { if (comp_op.donereturn.redirect != NULL) {
comp_op.donereturn.redirect->chk(return_type); comp_op.donereturn.redirect->chk(return_type);
} }
...@@ -4977,7 +4996,7 @@ error: ...@@ -4977,7 +4996,7 @@ error:
"not caught"); "not caught");
} }
Type *Statement::get_outgoing_type(TemplateInstance *p_ti) Type *Statement::get_msg_sig_type(TemplateInstance *p_ti)
{ {
// first analyze the template instance as is // first analyze the template instance as is
Type *ret_val = p_ti->get_expr_governor(Type::EXPECTED_TEMPLATE); Type *ret_val = p_ti->get_expr_governor(Type::EXPECTED_TEMPLATE);
...@@ -4990,27 +5009,6 @@ error: ...@@ -4990,27 +5009,6 @@ error:
return t_templ->get_expr_governor(Type::EXPECTED_TEMPLATE); return t_templ->get_expr_governor(Type::EXPECTED_TEMPLATE);
} }
Type *Statement::get_incoming_type(TemplateInstance *p_ti,
ValueRedirect *p_val_redir)
{
// first analyze the template instance
Type *ret_val = p_ti->get_expr_governor(Type::EXPECTED_TEMPLATE);
// return if this step was successful
if (ret_val) return ret_val;
// try to convert the undef identifier in the template instance to
// a reference because it cannot be an enum value anymore
Template *t_templ = p_ti->get_Template();
t_templ->set_lowerid_to_ref();
ret_val = t_templ->get_expr_governor(Type::EXPECTED_TEMPLATE);
// return if this step was successful
if (ret_val) return ret_val;
// finally try to determine the type from the value redirect
if (p_val_redir != NULL) {
ret_val = p_val_redir->get_type();
}
return ret_val;
}
Type *Statement::chk_sender_redirect(Type *address_type) Type *Statement::chk_sender_redirect(Type *address_type)
{ {
if (!port_op.r.redirect.sender) return 0; if (!port_op.r.redirect.sender) return 0;
......
...@@ -700,13 +700,9 @@ namespace Ttcn { ...@@ -700,13 +700,9 @@ namespace Ttcn {
* operation. Arguments \a port_type \a signature point to the * operation. Arguments \a port_type \a signature point to the
* port type and signature used in the call operation. */ * port type and signature used in the call operation. */
void chk_call_body(Type *port_type, Type *signature); void chk_call_body(Type *port_type, Type *signature);
/** Determines and returns the type of the outgoing message or /** Determines and returns the type of the incoming or outgoing message or
* signature based on a template instance \a p_ti. */ * signature based on a template instance \a p_ti. */
static Type *get_outgoing_type(TemplateInstance *p_ti); static Type *get_msg_sig_type(TemplateInstance *p_ti);
/** Determines and returns the type of the incoming message or
* signature based on a template instance \a p_ti and an optional
* value redirect \a p_val_redir. */
Type *get_incoming_type(TemplateInstance *p_ti, ValueRedirect *p_val_redir);
/** Checks the variable reference of a sender redirect. The type /** Checks the variable reference of a sender redirect. The type
* of the variable (or NULL in case of non-existent sender clause * of the variable (or NULL in case of non-existent sender clause
* or error) is returned. The type of the variable is also * or error) is returned. The type of the variable is also
......
...@@ -1867,6 +1867,7 @@ namespace Ttcn { ...@@ -1867,6 +1867,7 @@ namespace Ttcn {
signature->is_nonblocking_signature(); signature->is_nonblocking_signature();
pdef.proc_in.elements[i].has_exceptions = pdef.proc_in.elements[i].has_exceptions =
signature->get_signature_exceptions() ? TRUE : FALSE; signature->get_signature_exceptions() ? TRUE : FALSE;
pdef.proc_in.elements[i].has_return_value = FALSE;
} }
} else { } else {
pdef.proc_in.nElements = 0; pdef.proc_in.nElements = 0;
...@@ -1886,6 +1887,8 @@ namespace Ttcn { ...@@ -1886,6 +1887,8 @@ namespace Ttcn {
signature->is_nonblocking_signature(); signature->is_nonblocking_signature();
pdef.proc_out.elements[i].has_exceptions = pdef.proc_out.elements[i].has_exceptions =
signature->get_signature_exceptions() ? TRUE : FALSE; signature->get_signature_exceptions() ? TRUE : FALSE;
pdef.proc_out.elements[i].has_return_value =
signature->get_signature_return_type() != NULL ? TRUE : FALSE;
} }
} else { } else {
pdef.proc_out.nElements = 0; pdef.proc_out.nElements = 0;
......
...@@ -573,6 +573,8 @@ static void generate_receive(char **def_ptr, char **src_ptr, ...@@ -573,6 +573,8 @@ static void generate_receive(char **def_ptr, char **src_ptr,
"value_template, %s_Redirect_Interface *value_redirect, const %s_template& " "value_template, %s_Redirect_Interface *value_redirect, const %s_template& "
"sender_template, %s *sender_ptr)\n" "sender_template, %s *sender_ptr)\n"
"{\n" "{\n"
"if (value_template.get_selection() == ANY_OR_OMIT) "
"TTCN_error(\"%s operation using '*' as matching template\");\n"
"msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;\n" "msg_queue_item *my_head = (msg_queue_item*)msg_queue_head;\n"
"if (msg_queue_head == NULL) {\n" "if (msg_queue_head == NULL) {\n"
"if (is_started) return ALT_MAYBE;\n" "if (is_started) return ALT_MAYBE;\n"
...@@ -583,7 +585,7 @@ static void generate_receive(char **def_ptr, char **src_ptr, ...@@ -583,7 +585,7 @@ static void generate_receive(char **def_ptr, char **src_ptr,
"return ALT_NO;\n" "return ALT_NO;\n"
"}\n" "}\n"
"} else ", class_name, function_name, message_type->name, "} else ", class_name, function_name, message_type->name,
message_type->name_w_no_prefix, sender_type, sender_type); message_type->name_w_no_prefix, sender_type, sender_type, operation_name);
if (is_address) { if (is_address) {
src = mputprintf(src, "if (my_head->sender_component != " src = mputprintf(src, "if (my_head->sender_component != "
"SYSTEM_COMPREF) {\n" "SYSTEM_COMPREF) {\n"
...@@ -1099,16 +1101,23 @@ static void generate_getreply(char **def_ptr, char **src_ptr, ...@@ -1099,16 +1101,23 @@ static void generate_getreply(char **def_ptr, char **src_ptr,
src = mputprintf(src, "alt_status %s::%s(const %s_template& " src = mputprintf(src, "alt_status %s::%s(const %s_template& "
"getreply_template, const %s_template& sender_template, " "getreply_template, const %s_template& sender_template, "
"const %s_reply_redirect& param_ref, %s *sender_ptr)\n" "const %s_reply_redirect& param_ref, %s *sender_ptr)\n"
"{\n" "{\n", class_name, function_name, signature->name, sender_type,
signature->name, sender_type);
if (signature->has_return_value) {
src = mputprintf(src,
"if (getreply_template.return_value().get_selection() == ANY_OR_OMIT) "
"TTCN_error(\"%s operation using '*' as return value matching template\");\n",
operation_name);
}
src = mputstr(src,
"if (proc_queue_head == NULL) {\n" "if (proc_queue_head == NULL) {\n"
"if (is_started) return ALT_MAYBE;\n" "if (is_started) return ALT_MAYBE;\n"
"else {\n" "else {\n"
"TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on " "TTCN_Logger::log(TTCN_Logger::MATCHING_PROBLEM, \"Matching on "
"port %%s failed: Port is not started and the queue is empty.\", " "port %s failed: Port is not started and the queue is empty.\", "
"port_name);\n" "port_name);\n"
"return ALT_NO;\n" "return ALT_NO;\n"
"}\n", class_name, function_name, signature->name, sender_type, "}\n");
signature->name, sender_type);
if (is_address) { if (is_address) {
src = mputprintf(src, src = mputprintf(src,
"} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) " "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
...@@ -1221,6 +1230,8 @@ static void generate_catch(char **def_ptr, char **src_ptr, ...@@ -1221,6 +1230,8 @@ static void generate_catch(char **def_ptr, char **src_ptr,
"catch_template, const %s_template& sender_template, " "catch_template, const %s_template& sender_template, "
"%s *sender_ptr)\n" "%s *sender_ptr)\n"
"{\n" "{\n"
"if (catch_template.is_any_or_omit()) TTCN_error(\"%s operation using '*' "
"as matching template\");\n"
"if (proc_queue_head == NULL) {\n" "if (proc_queue_head == NULL) {\n"
"if (is_started) return ALT_MAYBE;\n" "if (is_started) return ALT_MAYBE;\n"
"else {\n" "else {\n"
...@@ -1229,7 +1240,7 @@ static void generate_catch(char **def_ptr, char **src_ptr, ...@@ -1229,7 +1240,7 @@ static void generate_catch(char **def_ptr, char **src_ptr,
"port_name);\n" "port_name);\n"
"return ALT_NO;\n" "return ALT_NO;\n"
"}\n", class_name, function_name, signature->name, sender_type, "}\n", class_name, function_name, signature->name, sender_type,
sender_type); sender_type, operation_name);
if (is_address) { if (is_address) {
src = mputprintf(src, src = mputprintf(src,
"} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) " "} else if (proc_queue_head->sender_component != SYSTEM_COMPREF) "
......
...@@ -76,6 +76,7 @@ typedef struct port_proc_signature_tag { ...@@ -76,6 +76,7 @@ typedef struct port_proc_signature_tag {
const char *dispname; const char *dispname;
boolean is_noblock; boolean is_noblock;
boolean has_exceptions; boolean has_exceptions;
boolean has_return_value;
} port_proc_signature; } port_proc_signature;
typedef struct port_proc_signature_list_tag { typedef struct port_proc_signature_list_tag {
......
...@@ -689,7 +689,6 @@ void defSignatureClasses(const signature_def *sdef, output_struct *output) ...@@ -689,7 +689,6 @@ void defSignatureClasses(const signature_def *sdef, output_struct *output)
/* value redirect base classes (interfaces) */ /* value redirect base classes (interfaces) */
for (i = 0; i < sdef->exceptions.nElements; i++) { for (i = 0; i < sdef->exceptions.nElements; i++) {
def = mputprintf(def, def = mputprintf(def,
"public:\n"
"class %s_Redirect_Interface {\n" "class %s_Redirect_Interface {\n"
"public:\n" "public:\n"
"virtual void set_values(const %s&) = 0;\n" "virtual void set_values(const %s&) = 0;\n"
...@@ -852,6 +851,27 @@ void defSignatureClasses(const signature_def *sdef, output_struct *output) ...@@ -852,6 +851,27 @@ void defSignatureClasses(const signature_def *sdef, output_struct *output)
"TTCN_error(\"Internal error: Invalid selector when performing " "TTCN_error(\"Internal error: Invalid selector when performing "
"value redirect on an exception of signature %s.\");\n" "value redirect on an exception of signature %s.\");\n"
"}\n\n", dispname); "}\n\n", dispname);
/* is_any_or_omit function */
def = mputprintf(def, "boolean is_any_or_omit() const;\n");
src = mputprintf(src,
"boolean %s_exception_template::is_any_or_omit() const\n"
"{\n"
"switch (exception_selection) {\n", name);
for (i = 0; i < sdef->exceptions.nElements; i++) {
src = mputprintf(src,
"case %s_%s:\n"
"return field_%s->get_selection() == ANY_OR_OMIT;\n",
selection_prefix, sdef->exceptions.elements[i].altname,
sdef->exceptions.elements[i].altname);
}
src = mputprintf(src,
"default:\n"
"break;\n"
"}\n"
"TTCN_error(\"Internal error: Invalid selector when checking for '*' in "
"an exception template of signature %s.\");\n"
"}\n\n", dispname);
def = mputstr(def, "};\n\n"); def = mputstr(def, "};\n\n");
/* end of class xxx_exception_template */ /* end of class xxx_exception_template */
......
...@@ -6863,7 +6863,7 @@ module ModuleA { ...@@ -6863,7 +6863,7 @@ module ModuleA {
var MyCompType MyVar2; var MyCompType MyVar2;
} }
// others should be covered in 'VariableRef' // others should be covered in 'VariableRef'
altstep MyAltstep41() runs on MyCompType {[] MyPort2.catch(MyProc2, ?) -> value MyVar1 sender Nonexi41 {}} altstep MyAltstep41() runs on MyCompType {[] MyPort2.catch(MyProc2, MyType1: ?) -> value MyVar1 sender Nonexi41 {}}
} }
<END_MODULE> <END_MODULE>
<RESULT IF_PASS COUNT 1> <RESULT IF_PASS COUNT 1>
......
...@@ -565,14 +565,14 @@ testcase TC() runs on MyComponent { ...@@ -565,14 +565,14 @@ testcase TC() runs on MyComponent {
var float F; var float F;
alt { alt {
[]any port.receive(integer:?) -> value I { } []any port.receive(integer:?) -> value I { }
[]any port.check(receive(integer:*) -> value I) { } []any port.check(receive(integer:?) -> value I) { }
[]any port.getcall(Sig:{0}) -> param(I) { } []any port.getcall(Sig:{0}) -> param(I) { }
[]any port.getreply(Sig:{0}) -> value J param(I) { } []any port.getreply(Sig:{0}) -> value J param(I) { }
[]any port.catch(Sig, float:*) -> value F { } []any port.catch(Sig, float:?) -> value F { }
[]any port.check(getcall(Sig:{0}) -> param(I)) { } []any port.check(getcall(Sig:{0}) -> param(I)) { }
[]any port.check(getreply(Sig:{0}) -> value J param(I)) { } []any port.check(getreply(Sig:{0}) -> value J param(I)) { }
[]any port.check(catch(Sig, float:*) -> value F) { } []any port.check(catch(Sig, float:?) -> value F) { }
} }
} }
...@@ -1374,6 +1374,80 @@ testcase TC() runs on MyComponent { ...@@ -1374,6 +1374,80 @@ testcase TC() runs on MyComponent {
:exmp. :exmp.
.*---------------------------------------------------------------------*
:h3.Adhoc - port operation: '*' in matching template