mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 12:49:45 +00:00
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.
This commit is contained in:
parent
ba39a874d4
commit
35d327bd0d
@ -15,6 +15,7 @@ C_SRCS = \
|
||||
header.c \
|
||||
proxy.c \
|
||||
server.c \
|
||||
typegen.c \
|
||||
typelib.c \
|
||||
utils.c \
|
||||
widl.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, /* <type> */\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");
|
||||
|
||||
|
@ -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, /* <type> */\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");
|
||||
|
||||
|
232
tools/widl/typegen.c
Normal file
232
tools/widl/typegen.c
Normal file
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
27
tools/widl/typegen.h
Normal file
27
tools/widl/typegen.h
Normal file
@ -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);
|
Loading…
Reference in New Issue
Block a user