1.1 --- a/dispatch.c Sat Dec 10 01:28:22 2022 +0100
1.2 +++ b/dispatch.c Tue Dec 13 17:04:42 2022 +0100
1.3 @@ -80,22 +80,34 @@
1.4 /* Write cases for each interface, using the protocol to select between the
1.5 cases. */
1.6
1.7 - if (by_protocol && (protocol != NULL))
1.8 + if (by_protocol)
1.9 {
1.10 - /* Convert to any base interface. */
1.11 + if (protocol != NULL)
1.12 + {
1.13 + /* Convert to any base interface. */
1.14
1.15 - ref = get_object_conversion(base->iface, 1);
1.16 - fprintf(fp, dispatch_function_interface_case, protocol, base->name, ref);
1.17 - free(ref);
1.18 + ref = get_object_conversion(base->iface, 1);
1.19 + fprintf(fp, dispatch_function_interface_case, protocol, base->name, ref);
1.20 + free(ref);
1.21 + }
1.22 +
1.23 + /* Look for any base interfaces employing protocols. */
1.24 +
1.25 + else
1.26 + write_dispatcher_interface_cases(fp, base->iface, 1);
1.27 }
1.28
1.29 /* Write cases for each operation provided by the interface so that they can
1.30 be selected. Note that this requires distinct opcodes to be used, so in
1.31 practice requiring explicit opcodes to be indicated. */
1.32
1.33 - else if (!by_protocol && (protocol == NULL))
1.34 - write_dispatcher_cases(fp, base->iface, 1);
1.35 + else if (protocol == NULL)
1.36 + write_dispatcher_interface_cases(fp, base->iface, 1);
1.37 }
1.38 +
1.39 + /* Dispatch to each operation defined at this level. */
1.40 +
1.41 + write_dispatcher_cases(fp, iface, is_compound_interface(iface));
1.42 }
1.43
1.44 /* Return whether any base interface specifies a protocol. */
1.45 @@ -141,34 +153,26 @@
1.46
1.47 /* Declare an error variable to support testing for already-sent messages. */
1.48
1.49 - fputs(" long err;\n\n", fp);
1.50 + fputs(dispatch_function_prologue, fp);
1.51
1.52 /* Without a protocol applying to the entire interface, dispatch using the
1.53 protocol from the message label. */
1.54
1.55 if (protocol == NULL)
1.56 - {
1.57 - fputs(" switch (l4_msgtag_label(msg->tag))\n {\n", fp);
1.58 + fputs(dispatch_function_label_dispatcher, fp);
1.59 +
1.60 + /* If a protocol applies to the entire interface, test for this protocol and
1.61 + dispatch using an operation indicator in the word data. */
1.62
1.63 - /* Dispatch using the protocol to base interfaces employing protocols. */
1.64 -
1.65 - if (have_interfaces_using_protocols(iface))
1.66 - write_dispatcher_interface_cases(fp, iface, 1);
1.67 + else
1.68 + {
1.69 + fprintf(fp, dispatch_function_test_protocol, protocol);
1.70 + fputs(dispatch_function_word_dispatcher, fp);
1.71 }
1.72
1.73 - /* If a protocol applies to the entire interface, dispatch using an operation
1.74 - indicator in the word data. */
1.75 -
1.76 - else
1.77 - fputs(" switch (ipc_message_get_word(msg, 0))\n {\n", fp);
1.78 + /* Dispatch to operations and any base interfaces. */
1.79
1.80 - /* Dispatch to operations provided by compound interfaces. */
1.81 -
1.82 - write_dispatcher_interface_cases(fp, iface, 0);
1.83 -
1.84 - /* Dispatch to each operation defined at this level. */
1.85 -
1.86 - write_dispatcher_cases(fp, iface, is_compound_interface(iface));
1.87 + write_dispatcher_interface_cases(fp, iface, (protocol == NULL));
1.88
1.89 /* Terminate the dispatcher. */
1.90
2.1 --- a/program.c Sat Dec 10 01:28:22 2022 +0100
2.2 +++ b/program.c Tue Dec 13 17:04:42 2022 +0100
2.3 @@ -198,10 +198,6 @@
2.4
2.5 if (server_fp != NULL)
2.6 {
2.7 - /* Write any includes for base interfaces. */
2.8 -
2.9 - write_server_includes(iface, server_fp);
2.10 -
2.11 /* Write the dispatcher and handler functions. */
2.12
2.13 write_functions(iface->signatures, server_fp, iface,
2.14 @@ -245,6 +241,10 @@
2.15 if (iface->tail == NULL)
2.16 write_include(iface->output_basename, "_interface.h", server_header_fp);
2.17
2.18 + /* Write any includes for base interfaces. */
2.19 +
2.20 + write_server_includes(iface, server_header_fp);
2.21 +
2.22 /* Emit signatures. */
2.23
2.24 write_signatures(iface->signatures, DECLARATION_ROLE, server_header_fp,
3.1 --- a/templates.h Sat Dec 10 01:28:22 2022 +0100
3.2 +++ b/templates.h Tue Dec 13 17:04:42 2022 +0100
3.3 @@ -87,16 +87,6 @@
3.4
3.5
3.6
3.7 -/* Compound interface dispatcher templates. */
3.8 -
3.9 -#define compound_dispatch_prologue \
3.10 -"#include \"%s_server.h\"\n"
3.11 -
3.12 -#define compound_dispatch_function_prologue \
3.13 -" long err;\n\n" \
3.14 -" switch (l4_msgtag_label(msg->tag))\n" \
3.15 -" {\n"
3.16 -
3.17 /* Compound interface definitions. */
3.18
3.19 #define compound_interface_include \
3.20 @@ -128,8 +118,32 @@
3.21 #define dispatch_function_signature \
3.22 "\nvoid dispatch_%s(ipc_message_t *msg, %s *_self)"
3.23
3.24 +#define dispatch_function_prologue \
3.25 +" long err;\n\n"
3.26 +
3.27 +#define dispatch_function_test_protocol \
3.28 +" if (l4_msgtag_label(msg->tag) != %s)\n" \
3.29 +" {\n" \
3.30 +" ipc_message_send_error(msg, -L4_EBADPROTO);\n" \
3.31 +" return;\n" \
3.32 +" }\n"
3.33 +
3.34 +#define dispatch_function_label_dispatcher \
3.35 +" switch (l4_msgtag_label(msg->tag))\n" \
3.36 +" {\n"
3.37 +
3.38 +#define dispatch_function_word_dispatcher \
3.39 +" switch (ipc_message_get_word(msg, 0))\n" \
3.40 +" {\n"
3.41 +
3.42 /* Dispatch templates. */
3.43
3.44 +#define dispatch_function_case_prologue \
3.45 +" case %s:\n"
3.46 +
3.47 +#define dispatch_function_case_epilogue \
3.48 +" break;\n\n"
3.49 +
3.50 #define dispatch_function_interface_case \
3.51 " case %s:\n" \
3.52 " dispatch_%s(msg, %s);\n" \