From 35d327bd0dff4646a9cf3b45c0717926cbc7b8a4 Mon Sep 17 00:00:00 2001 From: Robert Shearman Date: Thu, 8 Dec 2005 12:52:13 +0100 Subject: [PATCH] widl: Add a type generator framework. Add a framework for writing the strings for marshaling and unmarshaling parameters and make the client and server use it. --- tools/widl/Makefile.in | 1 + tools/widl/client.c | 65 ++------------ tools/widl/server.c | 89 ++----------------- tools/widl/typegen.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++ tools/widl/typegen.h | 27 ++++++ 5 files changed, 271 insertions(+), 143 deletions(-) create mode 100644 tools/widl/typegen.c create mode 100644 tools/widl/typegen.h diff --git a/tools/widl/Makefile.in b/tools/widl/Makefile.in index aaa2825f3b7..6d52a59cb68 100644 --- a/tools/widl/Makefile.in +++ b/tools/widl/Makefile.in @@ -15,6 +15,7 @@ C_SRCS = \ header.c \ proxy.c \ server.c \ + typegen.c \ typelib.c \ utils.c \ widl.c \ diff --git a/tools/widl/client.c b/tools/widl/client.c index 25231254d60..a371be62d24 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -39,6 +39,7 @@ #include "widltypes.h" #include "typelib.h" #include "typelib_struct.h" +#include "typegen.h" #define END_OF_LIST(list) \ do { \ @@ -65,63 +66,6 @@ static int print_client( const char *format, ... ) } -static void write_procformatstring(type_t *iface) -{ - func_t *func = iface->funcs; - - print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); - print_client("{\n"); - indent++; - print_client("0,\n"); - print_client("{\n"); - indent++; - - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) - { - var_t *def = func->def; - - if (is_void(def->type, NULL)) - { - print_client("0x5b, /* FC_END */\n"); - print_client("0x5c, /* FC_PAD */\n"); - } - else - { - print_client("0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); - print_client("0x%02x, /* */\n", def->type->type); - } - - func = PREV_LINK(func); - } - - print_client("0x0\n"); - indent--; - print_client("}\n"); - indent--; - print_client("};\n"); - print_client("\n"); -} - - -static void write_typeformatstring(void) -{ - print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); - print_client("{\n"); - indent++; - print_client("0,\n"); - print_client("{\n"); - indent++; - print_client("NdrFcShort(0x0),\n"); - print_client("0x0\n"); - indent--; - print_client("}\n"); - indent--; - print_client("};\n"); - print_client("\n"); -} - - static void write_function_stubs(type_t *iface) { func_t *func = iface->funcs; @@ -201,6 +145,9 @@ static void write_function_stubs(type_t *iface) fprintf(client, "\n"); + /* marshal arguments */ + marshall_arguments(client, indent, func); + /* send/receive message */ /* print_client("NdrNsSendReceive(\n"); */ print_client("NdrSendReceive(\n"); @@ -466,8 +413,8 @@ void write_client(ifref_t *ifaces) print_client("#endif\n"); fprintf(client, "\n"); - write_procformatstring(lcur->iface); - write_typeformatstring(); + write_procformatstring(client, lcur->iface); + write_typeformatstring(client); fprintf(client, "\n"); diff --git a/tools/widl/server.c b/tools/widl/server.c index ee2a1c277a0..4009bb255bf 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -40,6 +40,7 @@ #include "widl.h" #include "typelib.h" #include "typelib_struct.h" +#include "typegen.h" #define END_OF_LIST(list) \ do { \ @@ -67,86 +68,6 @@ static int print_server(const char *format, ...) } -static void write_procformatstring(type_t *iface) -{ - func_t *func = iface->funcs; - - print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); - print_server("{\n"); - indent++; - print_server("0,\n"); - print_server("{\n"); - indent++; - - while (NEXT_LINK(func)) func = NEXT_LINK(func); - while (func) - { - var_t *def = func->def; - - if (is_void(def->type, NULL)) - { - print_server("0x5b, /* FC_END */\n"); - print_server("0x5c, /* FC_PAD */\n"); - } - else - { - print_server("0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); - print_server("0x%02x, /* */\n", def->type->type); - } - - func = PREV_LINK(func); - } - - print_server("0x0\n"); - indent--; - print_server("}\n"); - indent--; - print_server("};\n"); - print_server("\n"); -} - - -static void write_typeformatstring(void) -{ - print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); - print_server("{\n"); - indent++; - print_server("0,\n"); - print_server("{\n"); - indent++; - print_server("NdrFcShort(0x0),\n"); - print_server("0x0\n"); - indent--; - print_server("}\n"); - indent--; - print_server("};\n"); - print_server("\n"); -} - - -static unsigned int get_required_stack_size(type_t *type) -{ - switch(type->type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - case RPC_FC_ULONG: - case RPC_FC_LONG: - return 4; - - case RPC_FC_HYPER: - return 8; - - default: - error("Unknown/unsupported type: %s\n", type->name); - return 0; - } -} - - static void write_function_stubs(type_t *iface) { func_t *func = iface->funcs; @@ -228,7 +149,7 @@ static void write_function_stubs(type_t *iface) indent -= 2; fprintf(server, "\n"); - /* FIXME: unmarshall arguments */ + unmarshall_arguments(server, indent, func); } print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); @@ -286,7 +207,7 @@ static void write_function_stubs(type_t *iface) if (!is_void(def->type, NULL)) { fprintf(server, "\n"); - print_server("_StubMsg.BufferLength = %uU;\n", get_required_stack_size(def->type)); + print_server("_StubMsg.BufferLength = %uU;\n", get_required_buffer_size(def->type)); print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); fprintf(server, "\n"); print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n"); @@ -537,8 +458,8 @@ void write_server(ifref_t *ifaces) print_server("#endif\n"); fprintf(server, "\n"); - write_procformatstring(lcur->iface); - write_typeformatstring(); + write_procformatstring(server, lcur->iface); + write_typeformatstring(server); fprintf(server, "\n"); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c new file mode 100644 index 00000000000..01992b029d9 --- /dev/null +++ b/tools/widl/typegen.c @@ -0,0 +1,232 @@ +/* + * Format String Generator for IDL Compiler + * + * Copyright 2005 Eric Kohl + * Copyright 2005 Robert Shearman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" +#include "wine/port.h" + +#include +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#include +#include +#include +#include + +#include "widl.h" +#include "utils.h" +#include "parser.h" +#include "header.h" +#include "windef.h" + +#include "widl.h" + +static int print_file(FILE *file, int indent, const char *format, ...) +{ + va_list va; + int i, r; + + va_start(va, format); + for (i = 0; i < indent; i++) + fprintf(file, " "); + r = vfprintf(file, format, va); + va_end(va); + return r; +} + +void write_procformatstring(FILE *file, type_t *iface) +{ + int indent = 0; + func_t *func = iface->funcs; + var_t *var; + + print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "0,\n"); + print_file(file, indent, "{\n"); + indent++; + + while (NEXT_LINK(func)) func = NEXT_LINK(func); + while (func) + { + /* emit argument data */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + switch(var->type->type) + { + default: + error("Unknown/unsupported type\n"); + } + + var = PREV_LINK(var); + } + } + + /* emit return value data */ + var = func->def; + if (is_void(var->type, NULL)) + { + print_file(file, indent, "0x5b, /* FC_END */\n"); + print_file(file, indent, "0x5c, /* FC_PAD */\n"); + } + else + { + switch(var->type->type) + { + default: + error("Unknown/unsupported type\n"); + } + } + + func = PREV_LINK(func); + } + + print_file(file, indent, "0x0\n"); + indent--; + print_file(file, indent, "}\n"); + indent--; + print_file(file, indent, "};\n"); + print_file(file, indent, "\n"); +} + + +void write_typeformatstring(FILE *file) +{ + int indent = 0; + print_file(file, indent, "static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "0,\n"); + print_file(file, indent, "{\n"); + indent++; + print_file(file, indent, "NdrFcShort(0x0),\n"); + print_file(file, indent, "0x0\n"); + indent--; + print_file(file, indent, "}\n"); + indent--; + print_file(file, indent, "};\n"); + print_file(file, indent, "\n"); +} + + +unsigned int get_required_buffer_size(type_t *type) +{ + switch(type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + case RPC_FC_ULONG: + case RPC_FC_LONG: + return 4; + + case RPC_FC_HYPER: + return 8; + + default: + error("Unknown/unsupported type: %s\n", type->name); + return 0; + } +} + +void marshall_arguments(FILE *file, int indent, func_t *func) +{ + unsigned int alignment; + unsigned int size; + unsigned int last_size = 0; + var_t *var; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + alignment = 0; + switch (var->type->type) + { + default: + size = 0; + error("Unknown/unsupported type!"); + } + + if (alignment != 0) + print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment); + + print_file(file, indent, "*(("); + write_type(file, var->type, var, var->tname); + fprintf(file, " __RPC_FAR*)_StubMsg.Buffer)++ = "); + write_name(file, var); + fprintf(file, ";\n"); + fprintf(file, "\n"); + + last_size = size; + + var = PREV_LINK(var); + } +} + +void unmarshall_arguments(FILE *file, int indent, func_t *func) +{ + unsigned int alignment; + unsigned int size; + unsigned int last_size = 0; + var_t *var; + + if (!func->args) + return; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + alignment = 0; + switch (var->type->type) + { + default: + size = 0; + error("Unknown/unsupported type!"); + } + + if (alignment != 0) + print_file(file, indent, "_StubMsg.Buffer += %u;\n", alignment); + + print_file(file, indent, ""); + write_name(file, var); + fprintf(file, " = *(("); + write_type(file, var->type, var, var->tname); + fprintf(file, " __RPC_FAR*)_StubMsg.Buffer)++;\n"); + fprintf(file, "\n"); + + last_size = size; + + var = PREV_LINK(var); + } +} diff --git a/tools/widl/typegen.h b/tools/widl/typegen.h new file mode 100644 index 00000000000..5517c62116c --- /dev/null +++ b/tools/widl/typegen.h @@ -0,0 +1,27 @@ +/* + * Format String Generator for IDL Compiler + * + * Copyright 2005 Eric Kohl + * Copyright 2005 Robert Shearman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +void write_procformatstring(FILE *file, type_t *iface); +void write_typeformatstring(FILE *file); +unsigned int get_required_buffer_size(type_t *type); +void marshall_arguments(FILE *file, int indent, func_t *func); +void unmarshall_arguments(FILE *file, int indent, func_t *func); -- 2.11.4.GIT