1.1 --- a/common.c Thu Apr 23 00:02:49 2020 +0200
1.2 +++ b/common.c Thu Apr 23 00:03:30 2020 +0200
1.3 @@ -90,6 +90,21 @@
1.4 return get_attribute_value(attr->tail, name);
1.5 }
1.6
1.7 +/* Return any conversion to a different object type in a dispatcher. */
1.8 +
1.9 +char *get_object_conversion(struct interface *iface, int compound)
1.10 +{
1.11 + char *conversion;
1.12 +
1.13 + if (!compound)
1.14 + return strdup("_self");
1.15 +
1.16 + if (asprintf(&conversion, "convert_to_%s(_self)", iface->name) == -1)
1.17 + conversion = NULL;
1.18 +
1.19 + return conversion;
1.20 +}
1.21 +
1.22 /* Return any opcode attribute value. */
1.23
1.24 char *get_opcode(struct attribute *attr)
2.1 --- a/common.h Thu Apr 23 00:02:49 2020 +0200
2.2 +++ b/common.h Thu Apr 23 00:03:30 2020 +0200
2.3 @@ -1,7 +1,7 @@
2.4 /*
2.5 * Common routines.
2.6 *
2.7 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
2.8 + * Copyright (C) 2019, 2020 Paul Boddie <paul@boddie.org.uk>
2.9 *
2.10 * This program is free software; you can redistribute it and/or
2.11 * modify it under the terms of the GNU General Public License as
2.12 @@ -47,6 +47,10 @@
2.13 int have_attribute_value(struct attribute *attr, const char *name, const char *value);
2.14 int have_identifier(struct identifier *ident, const char *value);
2.15
2.16 +/* Dispatcher object conversion (from compound to individual interfaces). */
2.17 +
2.18 +char *get_object_conversion(struct interface *iface, int compound);
2.19 +
2.20 /* Interface and operation naming. */
2.21
2.22 char *get_interface_class_name(struct interface *iface,
3.1 --- a/dispatch.c Thu Apr 23 00:02:49 2020 +0200
3.2 +++ b/dispatch.c Thu Apr 23 00:03:30 2020 +0200
3.3 @@ -58,7 +58,7 @@
3.4 else
3.5 fputs(" switch (l4_msgtag_label(msg->tag))\n {\n", fp);
3.6
3.7 - write_dispatcher_cases(sig, fp, iface);
3.8 + write_dispatcher_cases(sig, fp, iface, 0);
3.9 fputs(server_function_dispatcher_body_epilogue, fp);
3.10
3.11 fputs("}\n", fp);
3.12 @@ -66,9 +66,10 @@
3.13
3.14 /* Generate each dispatch possibility within an interface. */
3.15
3.16 -void write_dispatcher_cases(struct signature *sig, FILE *fp, struct interface *iface)
3.17 +void write_dispatcher_cases(struct signature *sig, FILE *fp,
3.18 + struct interface *iface, int compound)
3.19 {
3.20 - char *opcode, *opname, *protocol, *prefix, *s;
3.21 + char *opcode, *opname, *protocol, *prefix, *ref, *s;
3.22
3.23 if (sig == NULL)
3.24 return;
3.25 @@ -76,6 +77,7 @@
3.26 opname = get_operation_name(iface, sig);
3.27 opcode = get_opcode_identifier(NULL, opname);
3.28 prefix = get_operation_wrapper_prefix(sig->attributes);
3.29 + ref = get_object_conversion(iface, compound);
3.30
3.31 /* Generate a reply if appropriate. */
3.32
3.33 @@ -86,14 +88,15 @@
3.34
3.35 /* Generate the case and invocation. */
3.36
3.37 - fprintf(fp, s, opcode, prefix, opname);
3.38 + fprintf(fp, s, opcode, prefix, opname, ref);
3.39
3.40 /* Generate the other cases. */
3.41
3.42 - write_dispatcher_cases(sig->tail, fp, iface);
3.43 + write_dispatcher_cases(sig->tail, fp, iface, compound);
3.44
3.45 /* Free allocated strings. */
3.46
3.47 free(opcode);
3.48 free(opname);
3.49 + free(ref);
3.50 }
4.1 --- a/dispatch.h Thu Apr 23 00:02:49 2020 +0200
4.2 +++ b/dispatch.h Thu Apr 23 00:03:30 2020 +0200
4.3 @@ -1,7 +1,7 @@
4.4 /*
4.5 * Generation of server dispatch and handle functions.
4.6 *
4.7 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
4.8 + * Copyright (C) 2019, 2020 Paul Boddie <paul@boddie.org.uk>
4.9 *
4.10 * This program is free software; you can redistribute it and/or
4.11 * modify it under the terms of the GNU General Public License as
4.12 @@ -25,6 +25,7 @@
4.13 #include "types.h"
4.14
4.15 void write_dispatcher(struct signature *sig, FILE *fp, struct interface *iface);
4.16 -void write_dispatcher_cases(struct signature *sig, FILE *fp, struct interface *iface);
4.17 +void write_dispatcher_cases(struct signature *sig, FILE *fp,
4.18 + struct interface *iface, int compound);
4.19 void write_dispatcher_signature(const char *name, enum signature_role role, FILE *fp);
4.20 void write_handler_signature(const char *name, enum signature_role role, FILE *fp);
5.1 --- a/interface.c Thu Apr 23 00:02:49 2020 +0200
5.2 +++ b/interface.c Thu Apr 23 00:03:30 2020 +0200
5.3 @@ -143,5 +143,10 @@
5.4 write_structures(iface->signatures, fp, iface);
5.5 }
5.6
5.7 + /* Emit a conversion macro for compound interface dispatch. */
5.8 +
5.9 + if (!cpp && !client)
5.10 + fprintf(fp, compound_interface_conversion, name, name, name, name);
5.11 +
5.12 free(class_name);
5.13 }
6.1 --- a/program.c Thu Apr 23 00:02:49 2020 +0200
6.2 +++ b/program.c Thu Apr 23 00:03:30 2020 +0200
6.3 @@ -186,7 +186,9 @@
6.4 }
6.5
6.6 if (compound_interface_fp != NULL)
6.7 - fprintf(compound_interface_fp, compound_interface_prologue,
6.8 + fprintf(compound_interface_fp,
6.9 + (conf.language == CPP_LANGUAGE) ? compound_interface_prologue_cpp
6.10 + : compound_interface_prologue_c,
6.11 conf.compound, conf.compound_name);
6.12
6.13 if (compound_interfaces_fp != NULL)
6.14 @@ -214,7 +216,7 @@
6.15 /* Or dispatch to each operation defined at this level. */
6.16
6.17 else
6.18 - write_dispatcher_cases(iface->signatures, compound_dispatch_fp, iface);
6.19 + write_dispatcher_cases(iface->signatures, compound_dispatch_fp, iface, 1);
6.20 }
6.21
6.22 if (compound_dispatch_header_fp != NULL)
6.23 @@ -253,8 +255,15 @@
6.24
6.25 void write_compound_interface(struct interface *iface)
6.26 {
6.27 - char *sep = processed_interfaces ? ", " : " ";
6.28 - fprintf(compound_interface_fp, "%spublic %s", sep, iface->name);
6.29 + char *sep;
6.30 +
6.31 + if (conf.language == CPP_LANGUAGE)
6.32 + {
6.33 + sep = processed_interfaces ? ", " : " ";
6.34 + fprintf(compound_interface_fp, "%spublic %s", sep, iface->name);
6.35 + }
6.36 + else
6.37 + fprintf(compound_interface_fp, " iface_%s *to_%s;\n", iface->name, iface->name);
6.38 }
6.39
6.40 void end_compound_output(void)
6.41 @@ -277,7 +286,12 @@
6.42
6.43 if (compound_interface_fp != NULL)
6.44 {
6.45 - fputs(compound_interface_epilogue, compound_interface_fp);
6.46 + if (conf.language == CPP_LANGUAGE)
6.47 + fputs(compound_interface_epilogue_cpp, compound_interface_fp);
6.48 + else
6.49 + fprintf(compound_interface_fp, compound_interface_epilogue_c,
6.50 + conf.compound_name);
6.51 +
6.52 fclose(compound_interface_fp);
6.53 }
6.54
7.1 --- a/templates.h Thu Apr 23 00:02:49 2020 +0200
7.2 +++ b/templates.h Thu Apr 23 00:03:30 2020 +0200
7.3 @@ -1,7 +1,7 @@
7.4 /*
7.5 * Template output.
7.6 *
7.7 - * Copyright (C) 2019 Paul Boddie <paul@boddie.org.uk>
7.8 + * Copyright (C) 2019, 2020 Paul Boddie <paul@boddie.org.uk>
7.9 *
7.10 * This program is free software; you can redistribute it and/or
7.11 * modify it under the terms of the GNU General Public License as
7.12 @@ -100,19 +100,31 @@
7.13
7.14 /* Compound interface class definitions. */
7.15
7.16 -#define compound_interface_prologue \
7.17 +#define compound_interface_prologue_cpp \
7.18 "#pragma once\n\n" \
7.19 "#include \"%s_interfaces.h\"\n\n" \
7.20 "#ifdef __cplusplus\n\n" \
7.21 "class %s :"
7.22
7.23 -#define compound_interface_epilogue \
7.24 +#define compound_interface_prologue_c \
7.25 +"#pragma once\n\n" \
7.26 +"#include \"%s_interfaces.h\"\n\n" \
7.27 +"typedef struct\n" \
7.28 +"{\n"
7.29 +
7.30 +#define compound_interface_epilogue_cpp \
7.31 "\n{\n};\n\n" \
7.32 "#endif /* __cplusplus */\n"
7.33
7.34 +#define compound_interface_epilogue_c \
7.35 +"\n} iface_%s;\n"
7.36 +
7.37 #define compound_interfaces_prologue \
7.38 "#pragma once\n\n"
7.39
7.40 +#define compound_interface_conversion \
7.41 +"\n#define convert_to_%s(_self) (&((%s) {.ref=(ref_%s) *_self, .iface=_self->iface->to_%s}))\n"
7.42 +
7.43 /* Dispatch functions. */
7.44
7.45 #define dispatch_function_signature \
7.46 @@ -282,12 +294,12 @@
7.47
7.48 #define dispatch_function_wrapper_case \
7.49 " case %s:\n" \
7.50 -" ipc_message_send_error(msg, %s_%s(msg, _self));\n" \
7.51 +" ipc_message_send_error(msg, %s_%s(msg, %s));\n" \
7.52 " break;\n\n"
7.53
7.54 #define dispatch_function_reply_wrapper_case \
7.55 " case %s:\n" \
7.56 -" ipc_message_send_error(msg, %s_%s(msg, _self));\n" \
7.57 +" ipc_message_send_error(msg, %s_%s(msg, %s));\n" \
7.58 " ipc_message_reply(msg);\n" \
7.59 " break;\n\n"
7.60