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:
Robert Shearman 2005-12-08 12:52:13 +01:00 committed by Alexandre Julliard
parent ba39a874d4
commit 35d327bd0d
5 changed files with 271 additions and 143 deletions

View File

@ -15,6 +15,7 @@ C_SRCS = \
header.c \
proxy.c \
server.c \
typegen.c \
typelib.c \
utils.c \
widl.c \

View File

@ -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");

View File

@ -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
View 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
View 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);